[OpenLayers-Commits] r4746 - in sandbox/ahocevar/sldRenderer/lib: . OpenLayers OpenLayers/Format OpenLayers/Rule
commits at openlayers.org
commits at openlayers.org
Mon Oct 1 23:06:18 EDT 2007
Author: ahocevar
Date: 2007-10-01 23:06:16 -0400 (Mon, 01 Oct 2007)
New Revision: 4746
Added:
sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule.js
sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule/
sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule/Comparison.js
sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule/FeatureId.js
sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule/Logical.js
Modified:
sandbox/ahocevar/sldRenderer/lib/OpenLayers.js
sandbox/ahocevar/sldRenderer/lib/OpenLayers/Format/SLD.js
sandbox/ahocevar/sldRenderer/lib/OpenLayers/Style.js
Log:
got rid of using eval for evaluating the rules! Now there is a new class OpenLayers.Rule, with subclasses for three basic types of rules (similar to the ogc rules xsd schema). Also: code style fixes (< 80 chars/line) and improved NaturalDocs comments.
Modified: sandbox/ahocevar/sldRenderer/lib/OpenLayers/Format/SLD.js
===================================================================
--- sandbox/ahocevar/sldRenderer/lib/OpenLayers/Format/SLD.js 2007-10-02 02:55:22 UTC (rev 4745)
+++ sandbox/ahocevar/sldRenderer/lib/OpenLayers/Format/SLD.js 2007-10-02 03:06:16 UTC (rev 4746)
@@ -3,9 +3,12 @@
* for the full text of the license. */
/**
- * @requires OpenLayers/UserStyle.js
- * @requires OpenLayers/Format.js
* @requires OpenLayers/Format/XML.js
+ * @requires OpenLayers/Style.js
+ * @requires OpenLayers/Rule.js
+ * @requires OpenLayers/Rule/FeatureId.js
+ * @requires OpenLayers/Rule/Logical.js
+ * @requires OpenLayers/Rule/Comparison.js
*
* Class: OpenLayers.Format.SLD
* Read/Wite SLD. Create a new instance with the <OpenLayers.Format.SLD>
@@ -62,14 +65,16 @@
data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
}
- var userStyles = this.getElementsByTagNameNS(data, this.sldns, "UserStyle");
+ var userStyles = this.getElementsByTagNameNS(data, this.sldns,
+ "UserStyle");
if (userStyles.length == 0) {
return {};
}
var styles = {};
for (var i=0; i<userStyles.length; i++) {
- var name = OpenLayers.Util.getXmlNodeValue(
- this.getElementsByTagNameNS(userStyles[i], this.sldns, "Name")[0]);
+ var nameNode = this.getElementsByTagNameNS(userStyles[i],
+ this.sldns, "Name")
+ var name = OpenLayers.Util.getXmlNodeValue(nameNode[0]);
styles[name] = this.parseUserStyle(userStyles[i]);
}
@@ -89,13 +94,15 @@
parseUserStyle: function(xmlNode) {
var userStyle = new OpenLayers.Style();
- var ruleNodes = this.getElementsByTagNameNS(xmlNode, this.sldns, "Rule");
+ var ruleNodes = this.getElementsByTagNameNS(xmlNode, this.sldns,
+ "Rule");
if (ruleNodes.length == 0) { return []; }
var rules = userStyle.rules;
for (var i=0; i<ruleNodes.length; i++) {
- var name = OpenLayers.Util.getXmlNodeValue(
- this.getElementsByTagNameNS(ruleNodes[i], this.sldns, "Name")[0]);
+ var nameNode = this.getElementsByTagNameNS(ruleNodes[i], this.sldns,
+ "Name");
+ var name = OpenLayers.Util.getXmlNodeValue(nameNode[0]);
rules.push(this.parseRule(ruleNodes[i], name));
}
@@ -114,20 +121,17 @@
* {Object} Hash of rule properties
*/
parseRule: function(xmlNode, name) {
- var rule = {};
- OpenLayers.Util.extend(rule, OpenLayers.Style.RULE);
- rule.name = name;
- rule.symbolizer = {};
-
+
// FILTERS
var filter = this.getElementsByTagNameNS(xmlNode, this.ogcns, "Filter");
if (filter && filter.length > 0) {
- rule.appliesIf += this.parseFilter(filter[0]);
+ var rule = this.parseFilter(filter[0], null);
} else {
- // style applies to all features
- rule.appliesIf = "true";
+ // rule applies to all features
+ var rule = new OpenLayers.Rule()
}
+ rule.name = name;
// SCALE DENOMINATORS
@@ -162,68 +166,43 @@
var style = {};
// externalGraphic
- var externalGraphic = this.getElementsByTagNameNS(symbolizer[0],
- this.sldns, "ExternalGraphic");
- if (externalGraphic && externalGraphic.length > 0) {
- style.externalGraphic = this.getElementsByTagNameNS(
- externalGraphic[0], this.sldns, "OnlineResource").getAttribute("xlink:href");
+ var graphic = this.getElementsByTagNameNS(symbolizer[0],
+ this.sldns, "Graphic");
+ if (graphic && graphic.length > 0) {
+ style.externalGraphic = this.parseProperty(graphic[0],
+ "ExternalGraphic", this.sldns, "OnlineResource",
+ "xlink:href");
+ style.pointRadius = this.parseProperty(graphic[0], "Size",
+ this.sldns);
+ style.graphicOpacity = this.parseProperty(graphic[0],
+ "Opacity", this.sldns);
}
- var size = this.getElementsByTagNameNS(symbolizer[0], this.sldns, "Size");
- if (size && size.length > 0) {
- style.pointRadius = parseFloat(OpenLayers.Util.getXmlNodeValue(size[0]));
- }
- var opacity = this.getElementsByTagNameNS(symbolizer[0], this.sldns, "Opacity");
- if (opacity && opacity.length > 0) {
- style.graphicOpacity = parseFloat(OpenLayers.Util.getXmlNodeValue(opacity[0]));
- }
// fill
- var fill = this.getElementsByTagNameNS(symbolizer[0], this.sldns, "Fill");
+ var fill = this.getElementsByTagNameNS(symbolizer[0],
+ this.sldns, "Fill");
if (fill && fill.length > 0) {
- var cssParameter = this.getElementsByTagNameNS(fill[0], this.sldns, "CssParameter");
- var literal, attribute;
- for (var i=0; i<cssParameter.length; i++) {
- literal = this.getElementsByTagNameNS(cssParameter[i], this.ogcns, "Literal");
- attribute = cssParameter[i].getAttribute("name");
- // fillColor
- if (attribute == "fill") {
- style.fillColor = OpenLayers.String.trim(
- OpenLayers.Util.getXmlNodeValue(cssParameter[i]));
- } else
- // fillOpacity
- if (attribute == "fill-opacity") {
- style.fillOpacity = parseFloat(OpenLayers.Util.getXmlNodeValue(cssParameter[i]));
- }
- }
+ style.fillColor = this.parseProperty(fill[0], this.sldns,
+ "CssParameter", "name", "fill");
+ style.fillOpacity = this.parseProperty(fill[0],
+ this.sldns, "CssParameter", "name", "fill-opacity");
}
// stroke
- var stroke = this.getElementsByTagNameNS(symbolizer[0], this.sldns, "Stroke");
+ var stroke = this.getElementsByTagNameNS(symbolizer[0],
+ this.sldns, "Stroke");
if (stroke && stroke.length > 0) {
- var cssParameter = this.getElementsByTagNameNS(stroke[0], this.sldns, "CssParameter");
- var literal, attribute;
- for (var i=0; i<cssParameter.length; i++) {
- literal = this.getElementsByTagNameNS(cssParameter[i], this.ogcns, "Literal");
- attribute = cssParameter[i].getAttribute("name");
- // strokeColor
- if (attribute == "stroke") {
- style.strokeColor = OpenLayers.String.trim(
- OpenLayers.Util.getXmlNodeValue(cssParameter[i]));
- } else
- // strokeOpacity
- if (attribute == "stroke-opacity") {
- style.strokeOpacity = parseFloat(OpenLayers.Util.getXmlNodeValue(cssParameter[i]));
- } else
- // strokeWidth
- if (attribute == "stroke-width") {
- style.strokeWidth = parseFloat(OpenLayers.Util.getXmlNodeValue(cssParameter[i]));
- } else
- // strokeLinecap
- if (attribute == "stroke-linecap") {
- style.strokeLinecap = OpenLayers.String.trim(
- OpenLayers.Util.getXmlNodeValue(cssParameter[i]));
- }
- }
+ style.strokeColor = this.parseProperty(stroke[0],
+ this.sldns, "CssParameter", "name", "stroke");
+ style.strokeOpacity = this.parseProperty(stroke[0],
+ this.sldns, "CssParameter", "name",
+ "stroke-opacity");
+ style.strokeWidth = this.parseProperty(stroke[0],
+ this.sldns, "CssParameter", "name",
+ "stroke-width");
+ style.strokeLinecap = this.parseProperty(stroke[0],
+ this.sldns, "CssParameter", "name",
+ "stroke-linecap");
}
// set the [point|line|polygon]Symbolizer property of the rule
@@ -249,21 +228,16 @@
xmlNode.nodeName.split(":")[1] :
xmlNode.nodeName;
- var appliesIf = "(";
-
// ogc:FeatureId filter
var fidFilter = (nodeName == "FeatureId") ?
xmlNode :
this.getElementsByTagNameNS(xmlNode, this.ogcns, "FeatureId");
if (fidFilter && fidFilter.length > 0) {
+ var rule = new OpenLayers.Rule.FeatureId();
for (var i=0; i<fidFilter.length; i++) {
- var fid = fidFilter[i].getAttribute("fid");
- if (appliesIf != "(") {
- appliesIf += " || ";
- }
- appliesIf += "feature.fid == '" + fid + "'";
+ rule.fids.push(fidFilter[i].getAttribute("fid"));
}
- return appliesIf+")";
+ return rule;
}
// ogc:And filter
@@ -274,16 +248,15 @@
andFilter = andFilter[0];
}
if (andFilter.childNodes && andFilter.parentNode == xmlNode) {
+ var rule = new OpenLayers.Rule.Logical(
+ {type: OpenLayers.Rule.Logical.Type.AND});
var filters = andFilter.childNodes;
for (var i=0; i<filters.length; i++) {
if (filters[i].nodeType == 1) {
- if (appliesIf != "(") {
- appliesIf += " && ";
- }
- appliesIf += this.parseFilter(filters[i]);
+ rule.children.push(this.parseFilter(filters[i], rule));
}
}
- return appliesIf+")";
+ return rule;
}
// ogc:Or filter
@@ -294,16 +267,15 @@
orFilter = orFilter[0];
}
if (orFilter.childNodes && orFilter.parentNode == xmlNode) {
+ var rule = new OpenLayers.Rule.Logical(
+ {type: OpenLayers.Rule.Logical.Type.OR})
var filters = orFilter.childNodes;
for (var i=0; i<filters.length; i++) {
if (filters[i].nodeType == 1) {
- if (appliesIf != "(") {
- appliesIf += " || ";
- }
- appliesIf += this.parseFilter(filters[i]);
+ rule.children.push(this.parseFilter(filters[i], rule));
}
}
- return appliesIf+")";
+ return rule;
}
// ogc:Not filter
@@ -314,91 +286,147 @@
notFilter = notFilter[0];
}
if (notFilter.childNodes && notFilter.parentNode == xmlNode) {
- appliesIf += "!" + this.parseFilter(notFilter);
- return appliesIf+")";
+ var rule = new OpenLayers.Rule.Logical(
+ {type: OpenLayers.Rule.Logical.Type.NOT});
+ rule.children.push(this.parseFilter(notFilter, rule));
+ return rule;
}
- // ogc BinaryComparison filters
- var binaryComparisonOps = {
- 'PropertyIsEqualTo': "==",
- 'PropertyIsNotEqualTo': "!=",
- 'PropertyIsLessThan': "<",
- 'PropertyIsGreaterThan': ">",
- 'PropertyIsLessThanOrEqualTo': "<=",
- 'PropertyIsGreaterThanOrEqualTo': ">="
- };
- for (var i in binaryComparisonOps) {
- var binaryComparisonFilter = (nodeName == i) ?
+ // Comparison filters
+ for (var i in OpenLayers.Rule.Comparison.Type) {
+ // calculate the rule node name
+ var type = OpenLayers.String.camelize("-property-is-"+
+ i.replace("_", "-").toLowerCase());
+ var comparisonFilter = (nodeName == type) ?
xmlNode :
- this.getElementsByTagNameNS(xmlNode, this.ogcns, i);
- if (binaryComparisonFilter.length > 0) {
- binaryComparisonFilter = binaryComparisonFilter[0];
+ this.getElementsByTagNameNS(xmlNode, this.ogcns, type);
+ if (comparisonFilter.length > 0) {
+ comparisonFilter = comparisonFilter[0];
}
- if (binaryComparisonFilter.childNodes) {
- appliesIf += this.parseComparison(binaryComparisonFilter, binaryComparisonOps[i]);
- return appliesIf+")";
+ if (comparisonFilter.childNodes) {
+ var property = this.parseProperty(
+ xmlNode, this.ogcns, "PropertyName");
+ var lowerBoundary = this.parseProperty(
+ xmlNode, this.ogcns, "LowerBoundary");
+ if (lowerBoundary) {
+ var upperBoundary = this.parseProperty(
+ xmlNode, this.ogcns, "UpperBoundary");
+ var rule = new OpenLayers.Rule.Comparison({
+ type: OpenLayers.Rule.Comparison.Type.BETWEEN,
+ lowerBoundary: lowerBoundary,
+ upperBoundary: upperBoundary});
+ } else {
+ var value = this.parseProperty(
+ xmlNode, this.ogcns, "Literal");
+ var rule = new OpenLayers.Rule.Comparison({
+ type: OpenLayers.Rule.Comparison.Type[i],
+ value: value});
+ }
+ rule.property = property;
+ return rule;
}
}
-
- // ogc:PropertyIsBetween
- var propertyIsBetweenFilter = (nodeName == "PropertyIsBetween") ?
- xmlNode :
- this.getElementsByTagNameNS(xmlNode, this.ogcns, "PropertyIsBetween");
- if (propertyIsBetweenFilter.length > 0) {
- propertyIsBetweenFilter = propertyIsBetweenFilter[0];
- }
- if (propertyIsBetweenFilter.childNodes) {
- var propertyName = OpenLayers.String.trim(OpenLayers.Util.getXmlNodeValue(
- this.getElementsByTagNameNS(propertyNameIsBetweenFilter, this.ogcns, "PropertyName")[0]));
- var lowerBoundaryNode = this.getElementsByTagNameNS(
- propertyIsBetweenFilter, this.ogcns, "LowerBoundary");
- var lowerBoundary = OpenLayers.String.trim(OpenLayers.Util.getXmlNodeValue(
- this.getElementsByTagNameNS(lowerBoundaryNode, this.ogcns, "Literal")[0]));
- if (isNaN(lowerBoundary)) {
- lowerBoundary = "'"+lowerBoundary+"'";
- }
- var upperBoundaryNode = this.getElementsByTagNameNS(
- propertyIsBetweenFilter, this.ogcns, "UpperBoundary");
- var upperBoundary = OpenLayers.String.trim(OpenLayers.Util.getXmlNodeValue(
- this.getElementsByTagNameNS(upperBoundaryNode[0], this.ogcns, "Literal")[0]));
- if (isNaN(upperBoundary)) {
- upperBoundary = "'"+upperBoundary+"'";
- }
- appliesIf += "feature.attributes['"+propertyName+"']"+
- ">"+lowerBoundary+" && "+
- "feature.attributes['"+propertyName+"']"+
- "<"+upperBoundary;
-
- return appliesIf+")";
- }
-
- return "";
},
/**
- * Method: parseComparison
- * Parses ogc comparisons and builds a JS boolean expression.
+ * Method: parseProperty
+ * Convenience method to parse the different kinds of properties
+ * found in the sld and ogc namespace.
+ * Parses an ogc node that can either contain a value directly,
+ * or inside a <Literal> property. The parsing can also be limited
+ * to nodes with certain attribute names and/or values
*
* Parameters:
- * xmlNode - {<DOMElement>}
- * insertBetween - {<String>} string to insert between property and literal
+ * xmlNode - {<DOMElement>}
+ * namespace - {String} namespace of the node to find
+ * propertyName - {String} name of the property to parse
+ * attributeName - {String} optional name of the property to match
+ * attributeValue - {String} optional value of the specified attribute
*
* Returns:
- * {String} JavaScript eval'able boolean snippet
+ * {String} The value for the requested property
*/
- parseComparison: function(xmlNode, insertBetween) {
- var property = OpenLayers.String.trim(OpenLayers.Util.getXmlNodeValue(
- this.getElementsByTagNameNS(xmlNode, this.ogcns, "PropertyName")[0]));
- var literal = OpenLayers.String.trim(OpenLayers.Util.getXmlNodeValue(
- this.getElementsByTagNameNS(xmlNode, this.ogcns, "Literal")[0]));
- if (isNaN(literal)) {
- literal = "'"+literal+"'";
+ parseProperty: function(xmlNode, namespace, propertyName, attributeName,
+ attributeValue) {
+ var result = null;
+ var propertyNodeList = this.getElementsByTagNameNS(
+ xmlNode, namespace, propertyName);
+
+ if (propertyNodeList && propertyNodeList.length > 0) {
+ var propertyNode = attributeName ?
+ this.getNodeWithAttribute(propertyNodeList,
+ attributeName) :
+ propertyNodeList[0];
+
+ // get the property value from the node matching attributeName
+ // and attributeValue
+ if (attributeName && attributeValue) {
+ propertyNode = this.getNodeWithAttribute(propertyNodeList,
+ attributeName, attributeValue);
+ result = OpenLayers.Util.getXmlNodeValue(propertyNode);
+ }
+
+ // get the attribute value and use it as result
+ if (attributeName && !attributeValue) {
+ var propertyNode = this.getNodeWithAttribute(propertyNodeList,
+ attributeName);
+ result = propertyNode.getAttribute(attributeName);
+ }
+
+ // get the property value from the textContent of the first node
+ if (!result) {
+ propertyNode = propertyNodeList[0];
+ result = OpenLayers.Util.getXmlNodeValue(propertyNode);
+ }
+
+ // get the property value from an ogc:Literal at the level of
+ // the property node.
+ if (!result) {
+ var result = this.parseProperty(
+ propertyNode, this.ogcns, "Literal");
+ }
+
+ // finally, get the property value from an ogc:Literal at the same
+ // level as the xmlNode
+ if (!result) {
+ var result = this.parseProperty(xmlNode, this.ogcns, "Literal");
+ }
}
- return "feature.attributes['"+property+"']"+
- insertBetween+
- literal;
+ // adjust the result to be a trimmed string or a number
+ if (result) {
+ result = OpenLayers.String.trim(result);
+ if (!isNaN(result)) {
+ result = parseFloat(result);
+ }
+ }
+
+ return result;
},
+ /**
+ * Method: getNodeWithAttribute
+ * Walks through a list of xml nodes and returns the fist node that has an
+ * attribute with the name and optional value specified.
+ *
+ * Parameters:
+ * xmlNodeList - {Array(<DOMElement>)} list to search
+ * attributeName - {String} name of the attribute to match
+ * attributeValue - {String} optional value of the attribute
+ */
+ getNodeWithAttribute: function(xmlNodeList, attributeName, attributeValue) {
+ for (var i=0; i<xmlNodeList.length; i++) {
+ var currentAttributeValue =
+ xmlNodeList[i].getAttribute(attributeName);
+ if (currentAttributeValue) {
+ if (!attributeValue) {
+ return xmlNodeList[i];
+ } else if (currentAttributeValue == attributeValue) {
+ return xmlNodeList[i];
+ }
+ }
+ }
+ },
+
CLASS_NAME: "OpenLayers.Format.SLD"
});
\ No newline at end of file
Added: sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule/Comparison.js
===================================================================
--- sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule/Comparison.js (rev 0)
+++ sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule/Comparison.js 2007-10-02 03:06:16 UTC (rev 4746)
@@ -0,0 +1,145 @@
+/* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
+ * for the full text of the license. */
+
+
+/**
+ * @requires: OpenLayers/Rule.js
+ *
+ * Class: OpenLayers.Rule.Comparison
+ *
+ * This class represents the comparison rules, as being used for rule-based
+ * SLD styling
+ *
+ * Inherits from
+ * - <OpenLayers.Rule>
+ */
+OpenLayers.Rule.Comparison = OpenLayers.Class({
+
+ /**
+ * APIProperty: type
+ * {<OpenLayers.Rule.Logical.Type>} type: type of the comparison.
+ */
+ type: null,
+
+ /**
+ * APIProperty: property
+ * {String}
+ * name of the feature attribute to compare
+ */
+ property: null,
+
+ /**
+ * APIProperty: value
+ * {Number} or {String}
+ * comparison value for binary comparisons
+ */
+ value: null,
+
+ /**
+ * APIProperty: lowerBoundary
+ * {Number} or {String}
+ * lower boundary for between comparisons
+ */
+ lowerBoundary: null,
+
+ /**
+ * APIProperty: upperBoundary
+ * {Number} or {String}
+ * upper boundary for between comparisons
+ */
+ upperBoundary: null,
+
+ /**
+ * Constructor: OpenLayers.Rule.Logical
+ * Creates a logical rule (And, Or, Not).
+ *
+ * Parameters:
+ * params - {Object} Hash of parameters for this rule:
+ * -
+ * - value:
+ * options - {Object} An optional object with properties to set on the
+ * rule
+ *
+ * Returns:
+ * {<OpenLayers.Rule>}
+ */
+ initialize: function(options) {
+ OpenLayers.Rule.prototype.initialize.apply(
+ this, [options]);
+ },
+
+ /**
+ * APIMethod: evaluate
+ * evaluates this rule for a specific feature
+ *
+ * Parameters:
+ * feature - {<OpenLayers.Feature.Vector>} feature to apply the rule to.
+ *
+ * Returns:
+ * {boolean} true if the rule applies, false if it does not
+ */
+ evaluate: function(feature) {
+ switch(this.type) {
+ case OpenLayers.Rule.Comparison.Type.EQUAL_TO:
+ case OpenLayers.Rule.Comparison.Type.LESS_THAN:
+ case OpenLayers.Rule.Comparison.Type.GREATER_THAN:
+ case OpenLayers.Rule.Comparison.Type.LESS_THAN_OR_EQUAL_TO:
+ case OpenLayers.Rule.Comparison.Type.GREATER_THAN_OR_EQUAL_TO:
+ return this.binaryCompare(feature, this.property, this.value);
+
+ case OpenLayers.Rule.Comparison.Type.BETWEEN:
+ var result = false;
+ result = result &&
+ feature.attributes[this.property] > this.lowerBoundary;
+ result = result &&
+ feature.attributes[this.property] < this.upperBoundary;
+ return result;
+ }
+ },
+
+ /**
+ * Function: binaryCompare
+ * Compares a feature property to a rule value
+ *
+ * Parameters:
+ * feature - {<OpenLayers.Feature.Vector>}
+ * property - {String} or {Number}
+ * value - {String} or {Number}, same as property
+ *
+ * Returns:
+ * {boolean}
+ */
+ binaryCompare: function(feature, property, value) {
+ switch (this.type) {
+ case OpenLayers.Rule.Comparison.Type.EQUAL_TO:
+ return feature.attributes[property] == value;
+ case OpenLayers.Rule.Comparison.Type.NOT_EQUAL_TO:
+ return feature.attributes[property] != value;
+ case OpenLayers.Rule.Comparison.Type.LESS_THAN:
+ return feature.attributes[property] < value;
+ case OpenLayers.Rule.Comparison.Type.GREATER_THAN:
+ return feature.attributes[property] > value;
+ case OpenLayers.Rule.Comparison.Type.LESS_THAN_OR_EQUAL_TO:
+ return feature.attributes[property] <= value;
+ case OpenLayers.Rule.Comparison.Type.GREATER_THAN_OR_EQUAL_TO:
+ return feature.attributes[property] >= value;
+ }
+ },
+
+ CLASS_NAME: "OpenLayers.Rule.Comparison"
+});
+
+
+/**
+ * Constant:
+ * {Object} OpenLayers.Rule.Comparison.Type
+ */
+OpenLayers.Rule.Comparison.Type = {
+ 'EQUAL_TO': 0,
+ 'NOT_EQUAL_TO': 1,
+ 'LESS_THAN': 2,
+ 'GREATER_THAN': 3,
+ 'LESS_THAN_OR_EQUAL_TO': 4,
+ 'GREATER_THAN_OR_EQUAL_TO': 5,
+ 'BETWEEN': 6};
\ No newline at end of file
Added: sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule/FeatureId.js
===================================================================
--- sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule/FeatureId.js (rev 0)
+++ sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule/FeatureId.js 2007-10-02 03:06:16 UTC (rev 4746)
@@ -0,0 +1,63 @@
+/* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
+ * for the full text of the license. */
+
+
+/**
+ * @requires: OpenLayers/Rule.js
+ *
+ * Class: OpenLayers.Rule
+ *
+ * This class represents a ogc:FeatureId Rule, as being used for rule-based SLD
+ * styling
+ *
+ * Inherits from
+ * - <OpenLayers.Rule>
+ */
+OpenLayers.Rule.FeatureId = OpenLayers.Class({
+
+ /**
+ * APIProperty: fid
+ * {Array(<String>)} Feature Ids to evaluate this rule against. To be passed
+ * To be passed inside the params object.
+ */
+ fids: null,
+
+ /**
+ * Constructor: OpenLayers.Rule.FeatureId
+ * Creates an ogc:FeatureId rule.
+ *
+ * Parameters:
+ * options - {Object} An optional object with properties to set on the
+ * rule
+ *
+ * Returns:
+ * {<OpenLayers.Rule>}
+ *
+ * Inherits from:
+ * - <OpenLayers.Rule>
+ */
+ initialize: function(options) {
+ this.fids = [];
+ OpenLayers.Rule.prototype.initialize.apply(
+ this, [options]);
+ },
+
+ /**
+ * APIMethod: evaluate
+ * evaluates this rule for a specific feature
+ *
+ * Parameters:
+ * feature - {<OpenLayers.Feature.Vector>} feature to apply the rule to.
+ */
+ evaluate: function(feature) {
+ for (var i=0; i<this.fids.length; i++) {
+ if (feature.fid == this.fids[i]) {
+ return true;
+ }
+ }
+ return false;
+ },
+
+ CLASS_NAME: "OpenLayers.Rule.FeatureId"
+});
\ No newline at end of file
Added: sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule/Logical.js
===================================================================
--- sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule/Logical.js (rev 0)
+++ sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule/Logical.js 2007-10-02 03:06:16 UTC (rev 4746)
@@ -0,0 +1,91 @@
+/* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
+ * for the full text of the license. */
+
+
+/**
+ * @requires: OpenLayers/Rule.js
+ *
+ * Class: OpenLayers.Rule.Logical
+ *
+ * This class represents ogc:And, ogc:Or and ogc:Not rules.
+ *
+ * Inherits from
+ * - <OpenLayers.Rule>
+ */
+OpenLayers.Rule.Logical = OpenLayers.Class({
+
+ /**
+ * APIProperty: children
+ * {Array(<OpenLayers.Rule.Logical>)} child rules for this rule
+ */
+ children: null,
+
+ /**
+ * APIProperty: type
+ * {<OpenLayers.Rule.Logical.Type>} type of logical operator.
+ */
+ type: null,
+
+ /**
+ * Constructor: OpenLayers.Rule.Logical
+ * Creates a logical rule (And, Or, Not).
+ *
+ * Parameters:
+ * options - {Object} An optional object with properties to set on the
+ * rule
+ *
+ * Returns:
+ * {<OpenLayers.Rule>}
+ */
+ initialize: function(options) {
+ this.children = [];
+ OpenLayers.Rule.prototype.initialize.apply(
+ this, [options]);
+ },
+
+ /**
+ * APIMethod: evaluate
+ * evaluates this rule for a specific feature
+ *
+ * Parameters:
+ * feature - {<OpenLayers.Feature.Vector>} feature to apply the rule to.
+ *
+ * Returns:
+ * {boolean} true if the rule applies, false if it does not
+ */
+ evaluate: function(feature) {
+ switch(this.type) {
+ case OpenLayers.Rule.Logical.Type.AND:
+ for (var i=0; i<this.children.length; i++) {
+ if (this.children[i].evaluate(feature) == false) {
+ return false;
+ }
+ }
+ return true;
+
+ case OpenLayers.Rule.Logical.Type.OR:
+ for (var i=0; i<this.children.length; i++) {
+ if (this.children[i].evaluate(feature) == true) {
+ return true;
+ }
+ }
+ return false;
+
+ case OpenLayers.Rule.Logical.Type.NOT:
+ return (!this.children[0].evaluate(feature));
+ }
+ },
+
+ CLASS_NAME: "OpenLayers.Rule.Logical"
+});
+
+
+/**
+ * Constant:
+ * {Object} OpenLayers.Rule.Logical.Type
+ */
+OpenLayers.Rule.Logical.Type = {
+ 'AND': 0,
+ 'OR': 1,
+ 'NOT': 2};
\ No newline at end of file
Added: sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule.js
===================================================================
--- sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule.js (rev 0)
+++ sandbox/ahocevar/sldRenderer/lib/OpenLayers/Rule.js 2007-10-02 03:06:16 UTC (rev 4746)
@@ -0,0 +1,83 @@
+/* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
+ * for the full text of the license. */
+
+
+/**
+ * Class: OpenLayers.Rule
+ *
+ * This class represents a OGC Rule, as being used for rule-based SLD styling
+ */
+OpenLayers.Rule = OpenLayers.Class({
+
+ /**
+ * APIProperty: name
+ * {String} name of this rule
+ */
+ name: 'default',
+
+ /**
+ * Property: symbolizer
+ * {Object} Hash of styles for this rule. Contains hashes of feature
+ * styles. Keys are one or more of ["Point", "Line", "Polygon"]
+ */
+ symbolizer: null,
+
+ /**
+ * APIProperty: minScaleDenominator
+ * {Number} minimum scale at which to draw the feature.
+ */
+ minScaleDenominator: null,
+
+ /**
+ * APIProperty: maxScaleDenominator
+ * {Number} maximum scale at which to draw the feature.
+ */
+ maxScaleDenominator: null,
+
+ /**
+ * Constructor: OpenLayers.Rule
+ * Creates a Rule.
+ *
+ * Parameters:
+ * options - {Object} An optional object with properties to set on the
+ * rule
+ *
+ * Returns:
+ * {<OpenLayers.Rule>}
+ */
+ initialize: function(options) {
+ OpenLayers.Util.extend(this, options);
+
+ this.symbolizer = {};
+ },
+
+ /**
+ * APIMethod: destroy
+ * nullify references to prevent circular references and memory leaks
+ */
+ destroy: function() {
+ for (var i=0; i<children.length; i++) {
+ this.children[i].destroy();
+ }
+ this.children = null;
+ },
+
+ /**
+ * APIMethod: evaluate
+ * evaluates this rule for a specific feature
+ *
+ * Parameters:
+ * feature - {<OpenLayers.Feature.Vector>} feature to apply the rule to.
+ *
+ * Returns:
+ * {boolean} true if the rule applies, false if it does not.
+ * This rule is the default rule and always returns true.
+ */
+ evaluate: function(feature) {
+ // Default rule always applies. Subclasses will want to override this.
+ return true;
+ },
+
+ CLASS_NAME: "OpenLayers.Rule"
+});
\ No newline at end of file
Modified: sandbox/ahocevar/sldRenderer/lib/OpenLayers/Style.js
===================================================================
--- sandbox/ahocevar/sldRenderer/lib/OpenLayers/Style.js 2007-10-02 02:55:22 UTC (rev 4745)
+++ sandbox/ahocevar/sldRenderer/lib/OpenLayers/Style.js 2007-10-02 03:06:16 UTC (rev 4746)
@@ -15,7 +15,7 @@
/**
* APIProperty: rules
- * {Array(<OpenLayers.Format.SLD.Rule>}
+ * {Array(<OpenLayers.Rule>}
*/
rules: null,
@@ -64,7 +64,7 @@
},
/**
- * Method: destroy
+ * APIMethod: destroy
* nullify references to prevent circular references and memory leaks
*/
destroy: function() {
@@ -75,6 +75,18 @@
this.rules = null;
},
+ /**
+ * APIMethod: createStyle
+ * creates a style by applying all feature-dependent rules to the base
+ * style.
+ *
+ * Parameters:
+ * feature - {<OpenLayers.Feature.Vector>} feature to evaluate rules for
+ * baseStyle - {Object} hash of styles feature styles to extend
+ *
+ * Returns:
+ * {<OpenLayers.Feature.Vector.Style>} hash of feature styles
+ */
createStyle: function(feature, baseStyle) {
if (!baseStyle) {
baseStyle = this.defaultStyle;
@@ -84,7 +96,7 @@
for (var i=0; i<this.rules.length; i++) {
// does the rule apply?
- var applies = eval(this.rules[i].appliesIf);
+ var applies = this.rules[i].evaluate(feature);
if (applies) {
// check if within minScale/maxScale bounds
var scale = feature.layer.map.getScale();
Modified: sandbox/ahocevar/sldRenderer/lib/OpenLayers.js
===================================================================
--- sandbox/ahocevar/sldRenderer/lib/OpenLayers.js 2007-10-02 02:55:22 UTC (rev 4745)
+++ sandbox/ahocevar/sldRenderer/lib/OpenLayers.js 2007-10-02 03:06:16 UTC (rev 4746)
@@ -167,6 +167,10 @@
"OpenLayers/Layer/Vector.js",
"OpenLayers/Layer/GML.js",
"OpenLayers/Style.js",
+ "OpenLayers/Rule.js",
+ "OpenLayers/Rule/FeatureId.js",
+ "OpenLayers/Rule/Logical.js",
+ "OpenLayers/Rule/Comparison.js",
"OpenLayers/Format.js",
"OpenLayers/Format/XML.js",
"OpenLayers/Format/GML.js",
More information about the Commits
mailing list