[OpenLayers-Commits] r4180 - in sandbox/ahocevar/sldRenderer: examples examples/xml lib lib/OpenLayers/Format lib/OpenLayers/Format/SLD

commits at openlayers.org commits at openlayers.org
Mon Sep 3 08:59:31 EDT 2007


Author: ahocevar
Date: 2007-09-03 08:59:30 -0400 (Mon, 03 Sep 2007)
New Revision: 4180

Added:
   sandbox/ahocevar/sldRenderer/examples/SLDParser.html
   sandbox/ahocevar/sldRenderer/examples/xml/sld.xml
   sandbox/ahocevar/sldRenderer/lib/OpenLayers/Format/SLD.js
   sandbox/ahocevar/sldRenderer/lib/OpenLayers/Format/SLD/
   sandbox/ahocevar/sldRenderer/lib/OpenLayers/Format/SLD/Rule.js
Modified:
   sandbox/ahocevar/sldRenderer/lib/OpenLayers.js
Log:
some sld parsing ideas

Added: sandbox/ahocevar/sldRenderer/examples/SLDParser.html
===================================================================
--- sandbox/ahocevar/sldRenderer/examples/SLDParser.html	                        (rev 0)
+++ sandbox/ahocevar/sldRenderer/examples/SLDParser.html	2007-09-03 12:59:30 UTC (rev 4180)
@@ -0,0 +1,33 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <style type="text/css">
+        #map {
+            width: 800px;
+            height: 475px;
+            border: 1px solid black;
+        }
+    </style>
+    <script src="../lib/OpenLayers.js"></script>
+    <script type="text/javascript">
+        function parseData(req) {
+          g =  new OpenLayers.Format.SLD();
+          html = ""
+          features = g.read(req.responseText);
+          for(var feat in features) {
+            html += "Feature: Geometry: "+ features[feat].geometry+",";
+                html += "<ul>";
+            for (var j in features[feat].attributes) {
+                html += "<li>"+j+":"+features[feat].attributes[j]+"</li>";
+            }
+                html += "</ul>"
+          }
+          document.body.innerHTML = html;
+        }
+        function load() {
+            OpenLayers.loadURL("xml/sld.xml", "", null, parseData);
+        }   
+    </script>
+  </head>
+  <body onload="load()">
+  </body>
+</html>  


Property changes on: sandbox/ahocevar/sldRenderer/examples/SLDParser.html
___________________________________________________________________
Name: svn:keywords
   + Id Author Date Revision
Name: svn:eol-style
   + native

Added: sandbox/ahocevar/sldRenderer/examples/xml/sld.xml
===================================================================
--- sandbox/ahocevar/sldRenderer/examples/xml/sld.xml	                        (rev 0)
+++ sandbox/ahocevar/sldRenderer/examples/xml/sld.xml	2007-09-03 12:59:30 UTC (rev 4180)
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sld:StyledLayerDescriptor xmlns:sld="http://www.opengis.net/sld"
+  xmlns:ogc="http://www.opengis.net/ogc"
+  xmlns:gml="http://www.opengis.net/gml">
+  <sld:NamedLayer>
+    <sld:UserStyle>
+      <sld:Name>Default Styler</sld:Name>
+      <sld:Title>Default Styler</sld:Title>
+      <sld:Abstract></sld:Abstract>
+      <sld:FeatureTypeStyle>
+        <sld:Name>testStyleName</sld:Name>
+        <sld:Title>title</sld:Title>
+        <sld:Abstract>abstract</sld:Abstract>
+        <sld:FeatureTypeName>Feature</sld:FeatureTypeName>
+        <sld:SemanticTypeIdentifier>generic:geometry</sld:SemanticTypeIdentifier>
+        <sld:Rule>
+          <sld:Name>testRuleName</sld:Name>
+          <sld:Title>title</sld:Title>
+          <sld:Abstract>Abstract</sld:Abstract>
+          <ogc:Filter>
+            <ogc:FeatureId fid="parcell.2" />
+            <ogc:FeatureId fid="parcell.0" />
+            <ogc:FeatureId fid="parcell.3" />
+            <ogc:FeatureId fid="parcell.1" />
+            <ogc:FeatureId fid="parcell.4" />
+          </ogc:Filter>
+          <sld:MaxScaleDenominator>1000000</sld:MaxScaleDenominator>
+          <sld:PolygonSymbolizer>
+            <sld:Fill>
+              <sld:CssParameter name="fill">
+                <ogc:Literal>#808080</ogc:Literal>
+              </sld:CssParameter>
+              <sld:CssParameter name="fill-opacity">
+                <ogc:Literal>1.0</ogc:Literal>
+              </sld:CssParameter>
+            </sld:Fill>
+            <sld:Stroke>
+              <sld:CssParameter name="stroke">
+                <ogc:Literal>#000000</ogc:Literal>
+              </sld:CssParameter>
+              <sld:CssParameter name="stroke-linecap">
+                <ogc:Literal>butt</ogc:Literal>
+              </sld:CssParameter>
+              <sld:CssParameter name="stroke-linejoin">
+                <ogc:Literal>miter</ogc:Literal>
+              </sld:CssParameter>
+              <sld:CssParameter name="stroke-opacity">
+                <ogc:Literal>1</ogc:Literal>
+              </sld:CssParameter>
+              <sld:CssParameter name="stroke-width">
+                <ogc:Literal>1</ogc:Literal>
+              </sld:CssParameter>
+              <sld:CssParameter name="stroke-dashoffset">
+                <ogc:Literal>0</ogc:Literal>
+              </sld:CssParameter>
+            </sld:Stroke>
+          </sld:PolygonSymbolizer>
+        </sld:Rule>
+      </sld:FeatureTypeStyle>
+    </sld:UserStyle>
+  </sld:NamedLayer>
+</sld:StyledLayerDescriptor>
\ No newline at end of file


Property changes on: sandbox/ahocevar/sldRenderer/examples/xml/sld.xml
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + Id Author Date Revision
Name: svn:eol-style
   + native

Added: sandbox/ahocevar/sldRenderer/lib/OpenLayers/Format/SLD/Rule.js
===================================================================
--- sandbox/ahocevar/sldRenderer/lib/OpenLayers/Format/SLD/Rule.js	                        (rev 0)
+++ sandbox/ahocevar/sldRenderer/lib/OpenLayers/Format/SLD/Rule.js	2007-09-03 12:59:30 UTC (rev 4180)
@@ -0,0 +1,190 @@
+/* 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.Format.SLD.Rule
+ * Features are combinations of geography and attributes. The OpenLayers.Feature
+ * class specifically combines a marker and a lonlat.
+ */
+OpenLayers.Format.SLD.Rule = OpenLayers.Class({
+
+    /** 
+     * Property: minScaleDenominator 
+     * {Float} 
+     */
+    minScaleDenominator: null,
+
+    /** 
+     * Property: maxScaleDenominator 
+     * {Float} 
+     */
+    maxScaleDenominator: null,
+
+    /** 
+     * Property: fid 
+     * {String} 
+     */
+    fid: null,
+    
+    /**
+     * Property: ifFilter
+     * {String}
+     */
+    ifFilter: null,
+
+    /**
+     * Property: elseFilter
+     * {String}
+     */
+    elseFilter: null,
+    
+
+    /** 
+     * Constructor: OpenLayers.Rule
+     * Constructor for features.
+     *
+     * Parameters:
+     * layer - {<OpenLayers.Layer>} 
+     * lonlat - {<OpenLayers.LonLat>} 
+     * data - {Object} 
+     * 
+     * Return:
+     * {<OpenLayers.Rule>}
+     */
+    initialize: function(layer, lonlat, data) {
+        this.layer = layer;
+        this.lonlat = lonlat;
+        this.data = (data != null) ? data : {};
+        this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_"); 
+    },
+
+    /** 
+     * Method: destroy
+     * nullify references to prevent circular references and memory leaks
+     */
+    destroy: function() {
+
+        //remove the popup from the map
+        if ((this.layer != null) && (this.layer.map != null)) {
+            if (this.popup != null) {
+                this.layer.map.removePopup(this.popup);
+            }
+        }
+
+        if (this.events) {
+            this.events.destroy();
+        }
+        this.events = null;
+        
+        this.layer = null;
+        this.id = null;
+        this.lonlat = null;
+        this.data = null;
+        if (this.marker != null) {
+            this.destroyMarker(this.marker);
+            this.marker = null;
+        }
+        if (this.popup != null) {
+            this.destroyPopup(this.popup);
+            this.popup = null;
+        }
+    },
+    
+    /**
+     * Method: onScreen
+     * 
+     * Returns:
+     * {Boolean} Whether or not the feature is currently visible on screen
+     *           (based on its 'lonlat' property)
+     */
+    onScreen:function() {
+        
+        var onScreen = false;
+        if ((this.layer != null) && (this.layer.map != null)) {
+            var screenBounds = this.layer.map.getExtent();
+            onScreen = screenBounds.containsLonLat(this.lonlat);
+        }    
+        return onScreen;
+    },
+    
+
+    /**
+     * Method: createMarker
+     * Based on the data associated with the Feature, create and return a marker object.
+     *
+     * Return: 
+     * {<OpenLayers.Marker>} A Marker Object created from the 'lonlat' and 'icon' properties
+     *          set in this.data. If no 'lonlat' is set, returns null. If no
+     *          'icon' is set, OpenLayers.Marker() will load the default image.
+     *          
+     *          Note - this.marker is set to return value
+     * 
+     */
+    createMarker: function() {
+
+        if (this.lonlat != null) {
+            this.marker = new OpenLayers.Marker(this.lonlat, this.data.icon);
+        }
+        return this.marker;
+    },
+
+    /**
+     * Method: destroyMarker
+     * Destroys marker.
+     * If user overrides the createMarker() function, s/he should be able
+     *   to also specify an alternative function for destroying it
+     */
+    destroyMarker: function() {
+        this.marker.destroy();  
+    },
+
+    /**
+     * Method: createPopup
+     *  Creates a popup object created from the 'lonlat', 'popupSize',
+     *  and 'popupContentHTML' properties set in this.data. It uses
+     *  this.marker.icon as default anchor. 
+     *  
+     *  If no 'lonlat' is set, returns null. 
+     *  If no this.marker has been created, no anchor is sent.
+     * 
+     *  Note - this.popup is set to return value
+     * 
+     * Parameters: 
+     * closeBox - {Boolean} create popup with closebox or not
+     * 
+     * Returns:
+     * {<OpenLayers.Popup.AnchoredBubble>} 
+     * 
+     */
+    createPopup: function(closeBox) {
+
+        if (this.lonlat != null) {
+            
+            var id = this.id + "_popup";
+            var anchor = (this.marker) ? this.marker.icon : null;
+
+            this.popup = new OpenLayers.Popup.AnchoredBubble(id, 
+                                                    this.lonlat,
+                                                    this.data.popupSize,
+                                                    this.data.popupContentHTML,
+                                                    anchor, closeBox); 
+        }        
+        return this.popup;
+    },
+
+    
+    /**
+     * Method: destroyPopup
+     * Destroys the popup created via createPopup.
+     *
+     * As with the marker, if user overrides the createPopup() function, s/he 
+     *   should also be able to override the destruction
+     */
+    destroyPopup: function() {
+        this.popup.destroy() 
+    },
+
+    CLASS_NAME: "OpenLayers.Format.SLD.Rule"
+});


Property changes on: sandbox/ahocevar/sldRenderer/lib/OpenLayers/Format/SLD/Rule.js
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + Id Author Date Revision
Name: svn:eol-style
   + native

Added: sandbox/ahocevar/sldRenderer/lib/OpenLayers/Format/SLD.js
===================================================================
--- sandbox/ahocevar/sldRenderer/lib/OpenLayers/Format/SLD.js	                        (rev 0)
+++ sandbox/ahocevar/sldRenderer/lib/OpenLayers/Format/SLD.js	2007-09-03 12:59:30 UTC (rev 4180)
@@ -0,0 +1,270 @@
+/* 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/Format.js
+ * @requires OpenLayers/Feature/Vector.js
+ * @requires OpenLayers/Ajax.js
+ *
+ * Class: OpenLayers.Format.SLD
+ * Read/Wite SLD. Create a new instance with the <OpenLayers.Format.SLD>
+ *     constructor.
+ * 
+ * Inherits from:
+ *  - <OpenLayers.Format>
+ */
+OpenLayers.Format.SLD = OpenLayers.Class(OpenLayers.Format, {
+    
+    /*
+     * APIProperty: sldns
+     * Namespace used for sld.
+     */
+    sldns: "http://www.opengis.net/sld",
+    
+    /*
+     * APIProperty: ogcns
+     * Namespace used for ogc.
+     */
+    ogcns: "http://www.opengis.net/ogc",
+    
+    /*
+     * APIProperty: gmlns
+     * Namespace used for gml.
+     */
+    gmlns: "http://www.opengis.net/gml",
+    
+
+    /**
+     * Constructor: OpenLayers.Format.SLD
+     * Create a new parser for SLD
+     *
+     * Parameters:
+     * options - {Object} An optional object whose properties will be set on
+     *                    this instance.
+     */
+    initialize: function(options) {
+        OpenLayers.Format.prototype.initialize.apply(this, [options]);
+    },
+
+    /**
+     * APIMethod: read
+     * Read data from a string, and return a list of features. 
+     * 
+     * Parameters:
+     * data - {String} or {XMLNode} data to read/parse.
+     */
+     read: function(data) {
+        if (typeof data == "string") { 
+            data = OpenLayers.parseXMLString(data);
+        }
+        
+        var userStyles = OpenLayers.Ajax.getElementsByTagNameNS(data, this.sldns, "sld", "UserStyle");
+        if (userStyles.length == 0) {
+            return {};
+        }
+        var styles = {};
+        for (var i=0; i<userStyles.length; i++) {
+            var name = OpenLayers.Ajax.getElementsByTagNameNS(userStyles[i], this.sldns, "sld", "Name")[0].textContent;
+            styles[name] = this.parseStyle(userStyles[i]);
+        }
+        
+        return styles;
+     },
+
+     /**
+      * Method: parseStyle
+      * This function is the core of the SLD parsing code in OpenLayers.
+      * It creates the rules that are then attached to the returned
+      * feature.
+     
+      * Parameters:
+      * xmlNode - {<DOMElement>} 
+      */
+     parseStyle: function(xmlNode) {
+        var ruleNodes = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, this.sldns, "sld", "Rule");
+        if (ruleNodes.length == 0) { return []; }
+
+        var rules = {};
+        for (var i=0; i<ruleNodes.length; i++) {
+            var name = OpenLayers.Ajax.getElementsByTagNameNS(ruleNodes[i], this.sldns, "sld", "Name")[0].textContent;
+            rules[name] = this.parseRule(ruleNodes[i]);
+        }
+
+        return rules;
+    },        
+    
+    /**
+     * Method: parseRule
+     * parse an sld rule.
+     *
+     * Parameters:
+     * xmlNode - {<DOMElement>} 
+     */
+    parseRule: function(xmlNode) {
+    },
+        
+    /**
+     * APIMethod: write
+     * Accept Feature Array, and return a string. 
+     * 
+     * Parameters:
+     * features - Array({<OpenLayers.Feature.Vector>}> List of features to
+     * serialize into a string.
+     */
+     write: function(features) {
+        var featureCollection = document.createElementNS("http://www.opengis.net/wfs", "wfs:" + this.collectionName);
+        for (var i=0; i < features.length; i++) {
+            featureCollection.appendChild(this.createFeatureXML(features[i]));
+        }
+        return featureCollection;
+     },
+    
+    /** 
+     * Method: createFeatureXML
+     * Accept an OpenLayers.Feature.Vector, and build a geometry for it.
+     *
+     * Parameters:
+     * feature - {<OpenLayers.Feature.Vector>} 
+     *
+     * Returns:
+     * {DOMElement}
+     */
+    createFeatureXML: function(feature) {
+        var geometryNode = this.buildGeometryNode(feature.geometry);
+        var geomContainer = document.createElementNS(this.featureNS, "feature:"+this.geometryName);
+        geomContainer.appendChild(geometryNode);
+        var featureNode = document.createElementNS(this.gmlns, "gml:" + this.featureName);
+        var featureContainer = document.createElementNS(this.featureNS, "feature:"+this.layerName);
+        featureContainer.appendChild(geomContainer);
+        for(var attr in feature.attributes) {
+            var attrText = document.createTextNode(feature.attributes[attr]); 
+            var nodename = attr;
+            if (attr.search(":") != -1) {
+                nodename = attr.split(":")[1];
+            }    
+            var attrContainer = document.createElementNS(this.featureNS, "feature:"+nodename);
+            attrContainer.appendChild(attrText);
+            featureContainer.appendChild(attrContainer);
+        }    
+        featureNode.appendChild(featureContainer);
+        return featureNode;
+    },    
+    
+    /**
+     * Method: buildGeometryNode 
+     * builds a GML file with a given geometry
+     *
+     * Parameters:
+     * geometry - {<OpenLayers.Geometry>} 
+     */
+    buildGeometryNode: function(geometry) {
+    // TBD test if geoserver can be given a Multi-geometry for a simple-geometry data store
+    // ie if multipolygon can be sent for a polygon feature type
+        var gml = "";
+        // match MultiPolygon or Polygon
+        if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon"
+            || geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
+                gml = document.createElementNS(this.gmlns, 'gml:MultiPolygon');
+                
+                // TBD retrieve the srs from layer
+                // srsName is non-standard, so not including it until it's right.
+                //gml.setAttribute("srsName", "http://www.opengis.net/gml/srs/epsg.xml#4326");
+                
+                var polygonMember = document.createElementNS(this.gmlns, 'gml:polygonMember');
+                
+                var polygon = document.createElementNS(this.gmlns, 'gml:Polygon');
+                var outerRing = document.createElementNS(this.gmlns, 'gml:outerBoundaryIs');
+                var linearRing = document.createElementNS(this.gmlns, 'gml:LinearRing');
+                
+                // TBD manage polygons with holes
+                linearRing.appendChild(this.buildCoordinatesNode(geometry.components[0]));
+                outerRing.appendChild(linearRing);
+                polygon.appendChild(outerRing);
+                polygonMember.appendChild(polygon);
+                
+                gml.appendChild(polygonMember);
+            }
+        // match MultiLineString or LineString
+        else if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiLineString"
+                 || geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") {
+                     gml = document.createElementNS(this.gmlns, 'gml:MultiLineString');
+                     
+                     // TBD retrieve the srs from layer
+                     // srsName is non-standard, so not including it until it's right.
+                     //gml.setAttribute("srsName", "http://www.opengis.net/gml/srs/epsg.xml#4326");
+                     
+                     var lineStringMember = document.createElementNS(this.gmlns, 'gml:lineStringMember');
+                     
+                     var lineString = document.createElementNS(this.gmlns, 'gml:LineString');
+                     
+                     lineString.appendChild(this.buildCoordinatesNode(geometry));
+                     lineStringMember.appendChild(lineString);
+                     
+                     gml.appendChild(lineStringMember);
+                 }
+        // match MultiPoint or Point
+        else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point" || 
+                  geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") {
+                // TBD retrieve the srs from layer
+                // srsName is non-standard, so not including it until it's right.
+                //gml.setAttribute("srsName", "http://www.opengis.net/gml/srs/epsg.xml#4326");
+                     
+                gml = document.createElementNS(this.gmlns, 'gml:MultiPoint');
+                var parts = "";
+                if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") {
+                    parts = geometry.components;
+                } else {
+                    parts = [geometry];
+                }    
+                
+                for (var i = 0; i < parts.length; i++) { 
+                    var pointMember = document.createElementNS(this.gmlns, 'gml:pointMember');
+                    var point = document.createElementNS(this.gmlns, 'gml:Point');
+                    point.appendChild(this.buildCoordinatesNode(parts[i]));
+                    pointMember.appendChild(point);
+                    gml.appendChild(pointMember);
+               }     
+        }
+        return gml;         
+    },
+     
+    /**
+     * Method: buildCoordinates
+     * builds the coordinates XmlNode
+     * <gml:coordinates decimal="." cs="," ts=" ">...</gml:coordinates>
+     *
+     * Parameters: 
+     * geometry - {<OpenLayers.Geometry>} 
+     *
+     * Returns:
+     * {XmlNode} created xmlNode
+     */
+    buildCoordinatesNode: function(geometry) {
+        var coordinatesNode = document.createElementNS(this.gmlns, "gml:coordinates");
+        coordinatesNode.setAttribute("decimal", ".");
+        coordinatesNode.setAttribute("cs", ",");
+        coordinatesNode.setAttribute("ts", " ");
+        
+        var points = null;
+        if (geometry.components) {
+            points = geometry.components;
+        }
+
+        var path = "";
+        if (points) {
+            for (var i = 0; i < points.length; i++) {
+                path += points[i].x + "," + points[i].y + " ";
+            }
+        } else {
+           path += geometry.x + "," + geometry.y + " ";
+        }    
+        
+        var txtNode = document.createTextNode(path);
+        coordinatesNode.appendChild(txtNode);
+        
+        return coordinatesNode;
+    },
+
+    CLASS_NAME: "OpenLayers.Format.GML" 
+});     


Property changes on: sandbox/ahocevar/sldRenderer/lib/OpenLayers/Format/SLD.js
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + Id Author Date Revision
Name: svn:eol-style
   + native

Modified: sandbox/ahocevar/sldRenderer/lib/OpenLayers.js
===================================================================
--- sandbox/ahocevar/sldRenderer/lib/OpenLayers.js	2007-09-03 12:54:19 UTC (rev 4179)
+++ sandbox/ahocevar/sldRenderer/lib/OpenLayers.js	2007-09-03 12:59:30 UTC (rev 4180)
@@ -165,6 +165,7 @@
             "OpenLayers/Format/GeoRSS.js",
             "OpenLayers/Format/WFS.js",
             "OpenLayers/Format/WKT.js",
+            "OpenLayers/Format/SLD.js",
             "OpenLayers/Layer/WFS.js",
             "OpenLayers/Control/MouseToolbar.js",
             "OpenLayers/Control/NavToolbar.js",



More information about the Commits mailing list