OpenLayers.Format.KML.write()

16 messages Options
Embed this post
Permalink
Damien Corpataux

OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
Some javascript/style in this post has been disabled (why?)
Hello,

I'd like to implement a bit of OpenLayers.Format.KML.write() method, and enhance OpenLayers.Format.KML.read() to enabl.e Polygon node parsing...

Questions:
1/ Did you have any reason not to have implemented Polygon parsing at once with Point and LineString? I thought it could be because of the outerBoudaryIs node, which cannot be translated into OpenLayers.Geometry object...? Or was it just laziness? :-)

2/ How do you see the namespaces for KML? My view is that one can parse any KML as a 2.0, fetching Placemark nodes and digging into their geometries, since this seems not to change over versions. Do you think it's a good way of doing it?

Cheers,
Damien


--
Camptocamp SA
Damien Corpataux
PSE A
CH-1015 Lausanne
+41 21 619 10 22 (Direct)
+41 21 619 10 10 (Centrale)
+41 21 619 10 00 (Fax)
P Please consider the environment
Do you really need to print this email?

_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
Christopher Schmidt-2

Re: OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
On Tue, Aug 14, 2007 at 04:16:32PM +0200, Damien Corpataux wrote:

> Hello,
>
> I'd like to implement a bit of OpenLayers.Format.KML.write() method, and
> enhance OpenLayers.Format.KML.read() to enabl.e Polygon node parsing...
>
> Questions:
> 1/ Did you have any reason not to have implemented Polygon parsing at
> once with Point and LineString? I thought it could be because of the
> outerBoudaryIs node, which cannot be translated into OpenLayers.Geometry
> object...? Or was it just laziness? :-)

Just laziness.

> 2/ How do you see the namespaces for KML? My view is that one can parse
> any KML as a 2.0, fetching Placemark nodes and digging into their
> geometries, since this seems not to change over versions. Do you think
> it's a good way of doing it?

I didn't know enough about KML at the time I wrote it to know if this
was true or not. I'd be happy to be better informed either way.

Regards,
--
Christopher Schmidt
MetaCarta
_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
Damien Corpataux

Re: OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
Some javascript/style in this post has been disabled (why?)
Hello,

Here's what I did so far... Reading KML only work for KML 2.0 namespaces for write() uses OpenLayers.Ajax.getElementsByTagNameNS(), but I'm pretty sure it will work on future versions (2.1 parsing successful). Also, GML and KML write() returns a Dom Document rather than a string. Should one change the result type, breaking OpenLayers.Format interface, or parse it into a string using OpenLayers.XML.....?

Cheers,
Damien


--8<-------------------------------------------------------------------------------------

Index: /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js
===================================================================
--- /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js    (revision 3900)
+++ /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js    (working copy)
@@ -8,8 +8,8 @@
  * @requires OpenLayers/Ajax.js
  *
  * Class: OpenLayers.Format.KML
- * Read only KML. Largely Proof of Concept: does not support advanced Features,
- *     including Polygons.  Create a new instance with the
+ * Read/write KML 2.0. Does not support advanced Features.
+ *     Create a new instance with the
  *     <OpenLayers.Format.KML> constructor.
  *
  * Inherits from:
@@ -100,6 +100,19 @@
                 // TBD Bounds only set for one of multiple geometries
                 geom.extendBounds(p.bounds);
             }
+
+        // match Polygon
+        } else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
+            this.kmlns, "", "Polygon").length != 0) {
+            var polygon = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
+                this.kmlns, "", "Polygon")[0];
+            p = this.parseCoords(polygon);
+            if (p.points) {
+                var linearRing = new OpenLayers.Geometry.LinearRing(p.points);
+                geom = new OpenLayers.Geometry.Polygon(linearRing);
+                // TBD Bounds only set for one of multiple geometries
+                geom.extendBounds(p.bounds);
+            }
         }
        
         feature.geometry = geom;
@@ -190,6 +203,136 @@
         }
         return p;
     },
+   
+    /**
+     * Accept Feature Collection, and return a string.
+     *
+     * @param {Array} List of features to serialize into a string.
+     */
+     write: function(features) {
+        var kml = document.createElementNS("http://earth.google.com/kml/2.0", "kml:kml"); // 'kml:' NS to be removed?
+        for (var i=0; i < features.length; i++) {
+            kml.appendChild(this.createPlacemarkXML(features[i]));
+        }
+        return kml;
+     },
+
+    /**
+     * Accept an OpenLayers.Feature.Vector, and build a geometry for it.
+     *
+     * @param OpenLayers.Feature.Vector feature
+     * @return DOMElement
+     */
+    createPlacemarkXML: function(feature) {
+        // Placemark name
+        var placemarkName = document.createElementNS(this.kmlns, "kml:" + "name");
+        var placemarkNameText = document.createTextNode(feature.id);
+        placemarkName.appendChild(placemarkNameText);
+
+        // Placemark description
+        var placemarkDesc = document.createElementNS(this.kmlns, "kml:" + "description");
+        var placemarkDescText = document.createTextNode("Not available");
+        placemarkDesc.appendChild(placemarkDescText);
+       
+        // Placemark
+        var placemarkNode = document.createElementNS(this.kmlns, "kml:" + "Placemark");
+        placemarkNode.appendChild(placemarkName);
+        placemarkNode.appendChild(placemarkDesc);
+
+        // Geometry node (Point, LineString, etc. nodes)
+        var geometryNode = this.buildGeometryNode(feature.geometry);
+        placemarkNode.appendChild(geometryNode);       
+       
+        return placemarkNode;
+    },   
+
+    /**
+     * builds a KML geometry node with a given geometry
+     *
+     * @param {OpenLayers.Geometry} 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 kml = "";
+        // match MultiPolygon or Polygon
+        if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon"
+            || geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
+                kml = document.createElementNS(this.kmlns, 'kml:Polygon');
+               
+                var polygon = document.createElementNS(this.kmlns, 'kml:Polygon');
+                var outerRing = document.createElementNS(this.kmlns, 'kml:outerBoundaryIs');
+                var linearRing = document.createElementNS(this.kmlns, 'kml:LinearRing');
+               
+                // TBD manage polygons with holes
+                linearRing.appendChild(this.buildCoordinatesNode(geometry.components[0]));
+                outerRing.appendChild(linearRing);
+                polygon.appendChild(outerRing);
+               
+                kml.appendChild(polygon);
+            }
+        // match MultiLineString or LineString
+        else if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiLineString"
+                 || geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") {
+                     kml = document.createElementNS(this.kmlns, 'kml:LineString');
+                    
+                     var lineString = document.createElementNS(this.kmlns, 'kml:LineString');
+                    
+                     lineString.appendChild(this.buildCoordinatesNode(geometry));
+                    
+                     kml.appendChild(lineString);
+                 }
+        // match MultiPoint or Point
+        else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point" ||
+                  geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") {                    
+                kml = document.createElementNS(this.kmlns, 'kml:Point');
+
+                // FIXME: There should be only one Point node per Placemark node
+                var parts = "";
+                if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") {
+                    parts = geometry.components;
+                } else {
+                    parts = [geometry];
+                }   
+               
+                for (var i = 0; i < parts.length; i++) {
+                    var point = document.createElementNS(this.kmlns, 'kml:Point');
+                    point.appendChild(this.buildCoordinatesNode(parts[i]));
+                    kml.appendChild(point);
+               }    
+        }
+        return kml;        
+    },
+    
+    /**
+     * builds the coordinates XmlNode
+     * <kml:coordinates>...</kml:coordinates>
+     *
+     * @param {OpenLayers.Geometry} geometry
+     * @return {XmlNode} created xmlNode
+     */
+    buildCoordinatesNode: function(geometry) {
+        var coordinatesNode = document.createElementNS(this.kmlns, "kml:coordinates");
+       
+        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.KML"
 });    




Christopher Schmidt wrote:
On Tue, Aug 14, 2007 at 04:16:32PM +0200, Damien Corpataux wrote:
  
Hello,

I'd like to implement a bit of OpenLayers.Format.KML.write() method, and
enhance OpenLayers.Format.KML.read() to enabl.e Polygon node parsing...

Questions:
1/ Did you have any reason not to have implemented Polygon parsing at
once with Point and LineString? I thought it could be because of the
outerBoudaryIs node, which cannot be translated into OpenLayers.Geometry
object...? Or was it just laziness? :-)
    

Just laziness.

  
2/ How do you see the namespaces for KML? My view is that one can parse
any KML as a 2.0, fetching Placemark nodes and digging into their
geometries, since this seems not to change over versions. Do you think
it's a good way of doing it?
    

I didn't know enough about KML at the time I wrote it to know if this
was true or not. I'd be happy to be better informed either way. 

Regards,
  


--
Camptocamp SA
Damien Corpataux
PSE A
CH-1015 Lausanne
+41 21 619 10 22 (Direct)
+41 21 619 10 10 (Centrale)
+41 21 619 10 00 (Fax)
P Please consider the environment
Do you really need to print this email?

_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
Tim Schaub-3

Re: OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
Hi-

So, we're mid-way through changing how XML flavors are read/written in
OpenLayers.

I've checked a new XML format in to the trunk.  This format has most of
the methods we need for reading/writing XML cross-browser.

To parse other XML flavors, format classes should be created that
inherit from the XML format.

For an (incomplete) example, see:
http://dev.openlayers.org/sandbox/tschaub/xml/lib/OpenLayers/Format/GML.js

(The important part to notice in the above example is that the GML
format inherits from the XML format.)

Instead of using OpenLayers.Ajax methods or document methods, DOM
creation and traversal should be done with OpenLayers.Format.XML
methods.  I've created methods to reflect the W3C standard XML DOM
methods - wrapping the standard ones and accommodating for non-compliant
browsers.

If you (or anyone) needs additional XML DOM methods, they should be
added to the XML format.  The next addition (in my mind) is
setAttributeNS.  Aside from that, you should be able to do efficient
parsing and dom creation with the XML format methods.

Please make modifications to the KML format in the trunk.  Create a
ticket and attach patches in Trac.  I can offer review or other help as
needed.

I don't have time to keep these sandboxes entirely clean right now - so
please forgive anything you find that is in a half-developed state.

Tim

PS - Eventually, I'll move the following example into the trunk.  It
would be nice if we could demonstrate read/write capability for all
vector formats in this way:
http://dev.openlayers.org/sandbox/tschaub/xml/examples/vector-formats.html

(note again that this reflects partially complete work - and you should
not be surprised to encounter errors or see changes at any time)


Damien Corpataux wrote:

> Hello,
>
> Here's what I did so far... Reading KML only work for KML 2.0 namespaces
> for write() uses OpenLayers.Ajax.getElementsByTagNameNS(), but I'm
> pretty sure it will work on future versions (2.1 parsing successful).
> Also, GML and KML write() returns a Dom Document rather than a string.
> Should one change the result type, breaking OpenLayers.Format interface,
> or parse it into a string using OpenLayers.XML.....?
>
> Cheers,
> Damien
>
>
> --8<-------------------------------------------------------------------------------------
>
> Index: /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js
> ===================================================================
> ---
> /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js    
> (revision 3900)
> +++
> /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js    
> (working copy)
> @@ -8,8 +8,8 @@
>   * @requires OpenLayers/Ajax.js
>   *
>   * Class: OpenLayers.Format.KML
> - * Read only KML. Largely Proof of Concept: does not support advanced
> Features,
> - *     including Polygons.  Create a new instance with the
> + * Read/write KML 2.0. Does not support advanced Features.
> + *     Create a new instance with the
>   *     <OpenLayers.Format.KML> constructor.
>   *
>   * Inherits from:
> @@ -100,6 +100,19 @@
>                  // TBD Bounds only set for one of multiple geometries
>                  geom.extendBounds(p.bounds);
>              }
> +
> +        // match Polygon
> +        } else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
> +            this.kmlns, "", "Polygon").length != 0) {
> +            var polygon = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
> +                this.kmlns, "", "Polygon")[0];
> +            p = this.parseCoords(polygon);
> +            if (p.points) {
> +                var linearRing = new
> OpenLayers.Geometry.LinearRing(p.points);
> +                geom = new OpenLayers.Geometry.Polygon(linearRing);
> +                // TBD Bounds only set for one of multiple geometries
> +                geom.extendBounds(p.bounds);
> +            }
>          }
>        
>          feature.geometry = geom;
> @@ -190,6 +203,136 @@
>          }
>          return p;
>      },
> +  
> +    /**
> +     * Accept Feature Collection, and return a string.
> +     *
> +     * @param {Array} List of features to serialize into a string.
> +     */
> +     write: function(features) {
> +        var kml =
> document.createElementNS("http://earth.google.com/kml/2.0", "kml:kml");
> // 'kml:' NS to be removed?
> +        for (var i=0; i < features.length; i++) {
> +            kml.appendChild(this.createPlacemarkXML(features[i]));
> +        }
> +        return kml;
> +     },
> +
> +    /**
> +     * Accept an OpenLayers.Feature.Vector, and build a geometry for it.
> +     *
> +     * @param OpenLayers.Feature.Vector feature
> +     * @return DOMElement
> +     */
> +    createPlacemarkXML: function(feature) {
> +        // Placemark name
> +        var placemarkName = document.createElementNS(this.kmlns, "kml:"
> + "name");
> +        var placemarkNameText = document.createTextNode(feature.id);
> +        placemarkName.appendChild(placemarkNameText);
> +
> +        // Placemark description
> +        var placemarkDesc = document.createElementNS(this.kmlns, "kml:"
> + "description");
> +        var placemarkDescText = document.createTextNode("Not available");
> +        placemarkDesc.appendChild(placemarkDescText);
> +      
> +        // Placemark
> +        var placemarkNode = document.createElementNS(this.kmlns, "kml:"
> + "Placemark");
> +        placemarkNode.appendChild(placemarkName);
> +        placemarkNode.appendChild(placemarkDesc);
> +
> +        // Geometry node (Point, LineString, etc. nodes)
> +        var geometryNode = this.buildGeometryNode(feature.geometry);
> +        placemarkNode.appendChild(geometryNode);      
> +      
> +        return placemarkNode;
> +    },  
> +
> +    /**
> +     * builds a KML geometry node with a given geometry
> +     *
> +     * @param {OpenLayers.Geometry} 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 kml = "";
> +        // match MultiPolygon or Polygon
> +        if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon"
> +            || geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
> +                kml = document.createElementNS(this.kmlns, 'kml:Polygon');
> +              
> +                var polygon = document.createElementNS(this.kmlns,
> 'kml:Polygon');
> +                var outerRing = document.createElementNS(this.kmlns,
> 'kml:outerBoundaryIs');
> +                var linearRing = document.createElementNS(this.kmlns,
> 'kml:LinearRing');
> +              
> +                // TBD manage polygons with holes
> +                
> linearRing.appendChild(this.buildCoordinatesNode(geometry.components[0]));
> +                outerRing.appendChild(linearRing);
> +                polygon.appendChild(outerRing);
> +              
> +                kml.appendChild(polygon);
> +            }
> +        // match MultiLineString or LineString
> +        else if (geometry.CLASS_NAME ==
> "OpenLayers.Geometry.MultiLineString"
> +                 || geometry.CLASS_NAME ==
> "OpenLayers.Geometry.LineString") {
> +                     kml = document.createElementNS(this.kmlns,
> 'kml:LineString');
> +                    
> +                     var lineString =
> document.createElementNS(this.kmlns, 'kml:LineString');
> +                    
> +                    
> lineString.appendChild(this.buildCoordinatesNode(geometry));
> +                    
> +                     kml.appendChild(lineString);
> +                 }
> +        // match MultiPoint or Point
> +        else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point" ||
> +                  geometry.CLASS_NAME ==
> "OpenLayers.Geometry.MultiPoint") {                    
> +                kml = document.createElementNS(this.kmlns, 'kml:Point');
> +
> +                // FIXME: There should be only one Point node per
> Placemark node
> +                var parts = "";
> +                if (geometry.CLASS_NAME ==
> "OpenLayers.Geometry.MultiPoint") {
> +                    parts = geometry.components;
> +                } else {
> +                    parts = [geometry];
> +                }  
> +              
> +                for (var i = 0; i < parts.length; i++) {
> +                    var point = document.createElementNS(this.kmlns,
> 'kml:Point');
> +                    point.appendChild(this.buildCoordinatesNode(parts[i]));
> +                    kml.appendChild(point);
> +               }    
> +        }
> +        return kml;        
> +    },
> +    
> +    /**
> +     * builds the coordinates XmlNode
> +     * <kml:coordinates>...</kml:coordinates>
> +     *
> +     * @param {OpenLayers.Geometry} geometry
> +     * @return {XmlNode} created xmlNode
> +     */
> +    buildCoordinatesNode: function(geometry) {
> +        var coordinatesNode = document.createElementNS(this.kmlns,
> "kml:coordinates");
> +      
> +        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.KML"
>  });    
>
>
>
>
> Christopher Schmidt wrote:
>> On Tue, Aug 14, 2007 at 04:16:32PM +0200, Damien Corpataux wrote:
>>  
>>> Hello,
>>>
>>> I'd like to implement a bit of OpenLayers.Format.KML.write() method, and
>>> enhance OpenLayers.Format.KML.read() to enabl.e Polygon node parsing...
>>>
>>> Questions:
>>> 1/ Did you have any reason not to have implemented Polygon parsing at
>>> once with Point and LineString? I thought it could be because of the
>>> outerBoudaryIs node, which cannot be translated into OpenLayers.Geometry
>>> object...? Or was it just laziness? :-)
>>>    
>>
>> Just laziness.
>>
>>  
>>> 2/ How do you see the namespaces for KML? My view is that one can parse
>>> any KML as a 2.0, fetching Placemark nodes and digging into their
>>> geometries, since this seems not to change over versions. Do you think
>>> it's a good way of doing it?
>>>    
>>
>> I didn't know enough about KML at the time I wrote it to know if this
>> was true or not. I'd be happy to be better informed either way.
>>
>> Regards,
>>  
>
>
> --
> Camptocamp SA
> Damien Corpataux
> PSE A
> CH-1015 Lausanne
> +41 21 619 10 22 (Direct)
> +41 21 619 10 10 (Centrale)
> +41 21 619 10 00 (Fax)
> P Please consider the environment
> Do you really need to print this email?
> !DSPAM:4033,46c30f78118678362916074!
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Dev mailing list
> [hidden email]
> http://openlayers.org/mailman/listinfo/dev
>
>
> !DSPAM:4033,46c30f78118678362916074!

_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
Damien Corpataux

Re: OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
Some javascript/style in this post has been disabled (why?)
Hello,

As far as I can see, the advantages of doing so are obvious. Althought I didn't have time to apply these, here is a new version of the patch:
- puts placemarks in a folder tag (for google earth import)
- bugfix with geometry tags

Is the question about write() return type (string or DOMDocuemt/DOMNode) still open?

Cheers,
Damien


Patch:
Index: /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js
===================================================================
--- /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js    (revision 3900)
+++ /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js    (working copy)
@@ -8,8 +8,8 @@
  * @requires OpenLayers/Ajax.js
  *
  * Class: OpenLayers.Format.KML
- * Read only KML. Largely Proof of Concept: does not support advanced Features,
- *     including Polygons.  Create a new instance with the
+ * Read/write KML 2.0. Does not support advanced Features.
+ *     Create a new instance with the
  *     <OpenLayers.Format.KML> constructor.
  *
  * Inherits from:
@@ -24,6 +24,24 @@
     kmlns: "http://earth.google.com/kml/2.0",
    
     /**
+     * APIProperty: placemarksDesc
+     * Default description for a placemark
+     */
+    placemarksDesc: "No description available",
+
+    /**
+     * APIProperty: foldersName
+     * Default name for a folder
+     */
+    foldersName: "OpenLayers export",
+
+    /**
+     * APIProperty: foldersDesc
+     * Default description for a folder
+     */
+    foldersDesc: "Exported on " + new Date(),
+
+    /**
      * Constructor: OpenLayers.Format.KML
      * Create a new parser for KML
      *
@@ -46,7 +64,7 @@
         if (typeof data == "string") {
             data = OpenLayers.parseXMLString(data);
         }   
-        var featureNodes = OpenLayers.Ajax.getElementsByTagNameNS(data, this.kmlns, "", "Placemark");
+        var featureNodes = OpenLayers.Ajax.getElementsByTagNameNS(data, this.kmlns, "kml", "Placemark");
        
         var features = [];
        
@@ -100,6 +118,19 @@
                 // TBD Bounds only set for one of multiple geometries
                 geom.extendBounds(p.bounds);
             }
+
+        // match Polygon
+        } else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
+            this.kmlns, "", "Polygon").length != 0) {
+            var polygon = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
+                this.kmlns, "", "Polygon")[0];
+            p = this.parseCoords(polygon);
+            if (p.points) {
+                var linearRing = new OpenLayers.Geometry.LinearRing(p.points);
+                geom = new OpenLayers.Geometry.Polygon(linearRing);
+                // TBD Bounds only set for one of multiple geometries
+                geom.extendBounds(p.bounds);
+            }
         }
        
         feature.geometry = geom;
@@ -191,5 +222,171 @@
         return p;
     },
 
+    /**
+     * Method: write
+     * Accept Feature Collection, and return an XML Document.
+     *
+     * Parameters:
+     * features - An array of <OpenLayers.Feature.Vector> features.
+     *
+     * Returns:
+     * <DOMDocument>
+     */
+     write: function(features) {
+        var kml = document.createElementNS(this.kmlns, "kml");
+        var folder = this.createFolderXML();
+        for (var i=0; i < features.length; i++) {
+            folder.appendChild(this.createPlacemarkXML(features[i]));
+        }
+        kml.appendChild(folder);
+        return kml;
+     },
+
+    /**
+     * Method: createFolderXML
+     * Creates and returns a KML Folder node with default name and description
+     *
+     * Returns:
+     * xmlNode - {<XMLNode>}
+     */
+    createFolderXML: function() {
+        // Folder name
+        var folderName = document.createElementNS(this.kmlns, "name");
+        var folderNameText = document.createTextNode(this.foldersName);
+        folderName.appendChild(folderNameText);
+
+        // Folder description
+        var folderDesc = document.createElementNS(this.kmlns, "description");       
+        var folderDescText = document.createTextNode(this.foldersDesc);
+        folderDesc.appendChild(folderDescText);
+
+        // Folder
+        var folder = document.createElementNS(this.kmlns, "Folder");
+        folder.appendChild(folderName);
+        folder.appendChild(folderDesc);
+       
+        return folder;
+    },
+
+    /**
+     * Method: createPlacemarkXML
+     * Accept an OpenLayers.Feature.Vector, and create a KML Placemark node
+     *
+     * Parameters:
+     * feature - {<OpenLayers.Feature.Vector>}
+     *
+     * Returns:
+     * xmlNode - {<XMLNode>}
+     */
+    createPlacemarkXML: function(feature) {
+        // Placemark name
+        var placemarkName = document.createElementNS(this.kmlns, "name");
+        var placemarkNameText = document.createTextNode(feature.id);
+        placemarkName.appendChild(placemarkNameText);
+
+        // Placemark description
+        var placemarkDesc = document.createElementNS(this.kmlns, "description");
+        var placemarkDescText = document.createTextNode(this.placemarksDesc);
+        placemarkDesc.appendChild(placemarkDescText);
+       
+        // Placemark
+        var placemarkNode = document.createElementNS(this.kmlns, "Placemark");
+        placemarkNode.appendChild(placemarkName);
+        placemarkNode.appendChild(placemarkDesc);
+
+        // Geometry node (Point, LineString, etc. nodes)
+        var geometryNode = this.buildGeometryNode(feature.geometry);
+        placemarkNode.appendChild(geometryNode);       
+       
+        return placemarkNode;
+    },   
+
+    /**
+     * Method: buildGeometryNode
+     * Builds a KML geometry node with a given geometry
+     *
+     * Parameters:
+     * geometry - {<OpenLayers.Geometry>}
+     *
+     * Returns:
+     * xmlNode - {<XMLNode>}
+     */
+    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 kml = "";
+        // match MultiPolygon or Polygon
+        if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon"
+            || geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
+                kml = document.createElementNS(this.kmlns, 'Polygon');
+               
+                var outerRing = document.createElementNS(this.kmlns, 'outerBoundaryIs');
+                var linearRing = document.createElementNS(this.kmlns, 'LinearRing');
+               
+                // TBD manage polygons with holes
+                linearRing.appendChild(this.buildCoordinatesNode(geometry.components[0]));
+                outerRing.appendChild(linearRing);
+               
+                kml.appendChild(outerRing);
+            }
+        // match MultiLineString or LineString
+        else if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiLineString"
+                 || geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") {
+                     kml = document.createElementNS(this.kmlns, 'LineString');
+                                         
+                     kml.appendChild(this.buildCoordinatesNode(geometry));
+                 }
+        // match MultiPoint or Point
+        else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point" ||
+                  geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") {                    
+                kml = document.createElementNS(this.kmlns, 'Point');
+
+                // FIXME: There should be only one Point node per Placemark node
+                var parts = "";
+                if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") {
+                    parts = geometry.components;
+                } else {
+                    parts = [geometry];
+                }   
+               
+                for (var i = 0; i < parts.length; i++) {
+                    kml.appendChild(this.buildCoordinatesNode(parts[i]));
+               }    
+        }
+        return kml;        
+    },
+    /**
+     * Method: buildCoordinatesNode
+     * builds the KML coordinates node
+     *
+     * Parameters:
+     * geometry - {<OpenLayers.Geometry>}
+     *
+     * Returns:
+     * xmlNode - {<XMLNode>}
+     */
+    buildCoordinatesNode: function(geometry) {
+        var coordinatesNode = document.createElementNS(this.kmlns, "coordinates");
+       
+        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.KML"
 });    


Tim Schaub wrote:
Hi-

So, we're mid-way through changing how XML flavors are read/written in 
OpenLayers.

I've checked a new XML format in to the trunk.  This format has most of 
the methods we need for reading/writing XML cross-browser.

To parse other XML flavors, format classes should be created that 
inherit from the XML format.

For an (incomplete) example, see:
http://dev.openlayers.org/sandbox/tschaub/xml/lib/OpenLayers/Format/GML.js

(The important part to notice in the above example is that the GML 
format inherits from the XML format.)

Instead of using OpenLayers.Ajax methods or document methods, DOM 
creation and traversal should be done with OpenLayers.Format.XML 
methods.  I've created methods to reflect the W3C standard XML DOM 
methods - wrapping the standard ones and accommodating for non-compliant 
browsers.

If you (or anyone) needs additional XML DOM methods, they should be 
added to the XML format.  The next addition (in my mind) is 
setAttributeNS.  Aside from that, you should be able to do efficient 
parsing and dom creation with the XML format methods.

Please make modifications to the KML format in the trunk.  Create a 
ticket and attach patches in Trac.  I can offer review or other help as 
needed.

I don't have time to keep these sandboxes entirely clean right now - so 
please forgive anything you find that is in a half-developed state.

Tim

PS - Eventually, I'll move the following example into the trunk.  It 
would be nice if we could demonstrate read/write capability for all 
vector formats in this way:
http://dev.openlayers.org/sandbox/tschaub/xml/examples/vector-formats.html

(note again that this reflects partially complete work - and you should 
not be surprised to encounter errors or see changes at any time)


Damien Corpataux wrote:
  
Hello,

Here's what I did so far... Reading KML only work for KML 2.0 namespaces 
for write() uses OpenLayers.Ajax.getElementsByTagNameNS(), but I'm 
pretty sure it will work on future versions (2.1 parsing successful). 
Also, GML and KML write() returns a Dom Document rather than a string. 
Should one change the result type, breaking OpenLayers.Format interface, 
or parse it into a string using OpenLayers.XML.....?

Cheers,
Damien

    
[patch stripped]

--
Camptocamp SA
Damien Corpataux
PSE A
CH-1015 Lausanne
+41 21 619 10 22 (Direct)
+41 21 619 10 10 (Centrale)
+41 21 619 10 00 (Fax)
P Please consider the environment
Do you really need to print this email?

_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
Tim Schaub-3

Re: OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
I've opened ticket #927 to track this.

If anybody has a patch for KML, please attach it to that ticket.
Damien, I've referenced your email on the ticket.

Since XML flavors should now all inherit from the XML format class, I'd
say that write will always return a string.

Thanks for any contributions.
Tim


Damien Corpataux wrote:

> Hello,
>
> As far as I can see, the advantages of doing so are obvious. Althought I
> didn't have time to apply these, here is a new version of the patch:
> - puts placemarks in a folder tag (for google earth import)
> - bugfix with geometry tags
>
> Is the question about write() return type (string or DOMDocuemt/DOMNode)
> still open?
>
> Cheers,
> Damien
>
>
> Patch:
> Index: /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js
> ===================================================================
> ---
> /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js    
> (revision 3900)
> +++
> /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js    
> (working copy)
> @@ -8,8 +8,8 @@
>   * @requires OpenLayers/Ajax.js
>   *
>   * Class: OpenLayers.Format.KML
> - * Read only KML. Largely Proof of Concept: does not support advanced
> Features,
> - *     including Polygons.  Create a new instance with the
> + * Read/write KML 2.0. Does not support advanced Features.
> + *     Create a new instance with the
>   *     <OpenLayers.Format.KML> constructor.
>   *
>   * Inherits from:
> @@ -24,6 +24,24 @@
>      kmlns: "http://earth.google.com/kml/2.0",
>    
>      /**
> +     * APIProperty: placemarksDesc
> +     * Default description for a placemark
> +     */
> +    placemarksDesc: "No description available",
> +
> +    /**
> +     * APIProperty: foldersName
> +     * Default name for a folder
> +     */
> +    foldersName: "OpenLayers export",
> +
> +    /**
> +     * APIProperty: foldersDesc
> +     * Default description for a folder
> +     */
> +    foldersDesc: "Exported on " + new Date(),
> +
> +    /**
>       * Constructor: OpenLayers.Format.KML
>       * Create a new parser for KML
>       *
> @@ -46,7 +64,7 @@
>          if (typeof data == "string") {
>              data = OpenLayers.parseXMLString(data);
>          }  
> -        var featureNodes = OpenLayers.Ajax.getElementsByTagNameNS(data,
> this.kmlns, "", "Placemark");
> +        var featureNodes = OpenLayers.Ajax.getElementsByTagNameNS(data,
> this.kmlns, "kml", "Placemark");
>        
>          var features = [];
>        
> @@ -100,6 +118,19 @@
>                  // TBD Bounds only set for one of multiple geometries
>                  geom.extendBounds(p.bounds);
>              }
> +
> +        // match Polygon
> +        } else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
> +            this.kmlns, "", "Polygon").length != 0) {
> +            var polygon = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
> +                this.kmlns, "", "Polygon")[0];
> +            p = this.parseCoords(polygon);
> +            if (p.points) {
> +                var linearRing = new
> OpenLayers.Geometry.LinearRing(p.points);
> +                geom = new OpenLayers.Geometry.Polygon(linearRing);
> +                // TBD Bounds only set for one of multiple geometries
> +                geom.extendBounds(p.bounds);
> +            }
>          }
>        
>          feature.geometry = geom;
> @@ -191,5 +222,171 @@
>          return p;
>      },
>  
> +    /**
> +     * Method: write
> +     * Accept Feature Collection, and return an XML Document.
> +     *
> +     * Parameters:
> +     * features - An array of <OpenLayers.Feature.Vector> features.
> +     *
> +     * Returns:
> +     * <DOMDocument>
> +     */
> +     write: function(features) {
> +        var kml = document.createElementNS(this.kmlns, "kml");
> +        var folder = this.createFolderXML();
> +        for (var i=0; i < features.length; i++) {
> +            folder.appendChild(this.createPlacemarkXML(features[i]));
> +        }
> +        kml.appendChild(folder);
> +        return kml;
> +     },
> +
> +    /**
> +     * Method: createFolderXML
> +     * Creates and returns a KML Folder node with default name and
> description
> +     *
> +     * Returns:
> +     * xmlNode - {<XMLNode>}
> +     */
> +    createFolderXML: function() {
> +        // Folder name
> +        var folderName = document.createElementNS(this.kmlns, "name");
> +        var folderNameText = document.createTextNode(this.foldersName);
> +        folderName.appendChild(folderNameText);
> +
> +        // Folder description
> +        var folderDesc = document.createElementNS(this.kmlns,
> "description");      
> +        var folderDescText = document.createTextNode(this.foldersDesc);
> +        folderDesc.appendChild(folderDescText);
> +
> +        // Folder
> +        var folder = document.createElementNS(this.kmlns, "Folder");
> +        folder.appendChild(folderName);
> +        folder.appendChild(folderDesc);
> +      
> +        return folder;
> +    },
> +
> +    /**
> +     * Method: createPlacemarkXML
> +     * Accept an OpenLayers.Feature.Vector, and create a KML Placemark node
> +     *
> +     * Parameters:
> +     * feature - {<OpenLayers.Feature.Vector>}
> +     *
> +     * Returns:
> +     * xmlNode - {<XMLNode>}
> +     */
> +    createPlacemarkXML: function(feature) {
> +        // Placemark name
> +        var placemarkName = document.createElementNS(this.kmlns, "name");
> +        var placemarkNameText = document.createTextNode(feature.id);
> +        placemarkName.appendChild(placemarkNameText);
> +
> +        // Placemark description
> +        var placemarkDesc = document.createElementNS(this.kmlns,
> "description");
> +        var placemarkDescText =
> document.createTextNode(this.placemarksDesc);
> +        placemarkDesc.appendChild(placemarkDescText);
> +      
> +        // Placemark
> +        var placemarkNode = document.createElementNS(this.kmlns,
> "Placemark");
> +        placemarkNode.appendChild(placemarkName);
> +        placemarkNode.appendChild(placemarkDesc);
> +
> +        // Geometry node (Point, LineString, etc. nodes)
> +        var geometryNode = this.buildGeometryNode(feature.geometry);
> +        placemarkNode.appendChild(geometryNode);      
> +      
> +        return placemarkNode;
> +    },  
> +
> +    /**
> +     * Method: buildGeometryNode
> +     * Builds a KML geometry node with a given geometry
> +     *
> +     * Parameters:
> +     * geometry - {<OpenLayers.Geometry>}
> +     *
> +     * Returns:
> +     * xmlNode - {<XMLNode>}
> +     */
> +    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 kml = "";
> +        // match MultiPolygon or Polygon
> +        if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon"
> +            || geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
> +                kml = document.createElementNS(this.kmlns, 'Polygon');
> +              
> +                var outerRing = document.createElementNS(this.kmlns,
> 'outerBoundaryIs');
> +                var linearRing = document.createElementNS(this.kmlns,
> 'LinearRing');
> +              
> +                // TBD manage polygons with holes
> +                
> linearRing.appendChild(this.buildCoordinatesNode(geometry.components[0]));
> +                outerRing.appendChild(linearRing);
> +              
> +                kml.appendChild(outerRing);
> +            }
> +        // match MultiLineString or LineString
> +        else if (geometry.CLASS_NAME ==
> "OpenLayers.Geometry.MultiLineString"
> +                 || geometry.CLASS_NAME ==
> "OpenLayers.Geometry.LineString") {
> +                     kml = document.createElementNS(this.kmlns,
> 'LineString');
> +                                        
> +                     kml.appendChild(this.buildCoordinatesNode(geometry));
> +                 }
> +        // match MultiPoint or Point
> +        else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point" ||
> +                  geometry.CLASS_NAME ==
> "OpenLayers.Geometry.MultiPoint") {                    
> +                kml = document.createElementNS(this.kmlns, 'Point');
> +
> +                // FIXME: There should be only one Point node per
> Placemark node
> +                var parts = "";
> +                if (geometry.CLASS_NAME ==
> "OpenLayers.Geometry.MultiPoint") {
> +                    parts = geometry.components;
> +                } else {
> +                    parts = [geometry];
> +                }  
> +              
> +                for (var i = 0; i < parts.length; i++) {
> +                    kml.appendChild(this.buildCoordinatesNode(parts[i]));
> +               }    
> +        }
> +        return kml;        
> +    },
> +    /**
> +     * Method: buildCoordinatesNode
> +     * builds the KML coordinates node
> +     *
> +     * Parameters:
> +     * geometry - {<OpenLayers.Geometry>}
> +     *
> +     * Returns:
> +     * xmlNode - {<XMLNode>}
> +     */
> +    buildCoordinatesNode: function(geometry) {
> +        var coordinatesNode = document.createElementNS(this.kmlns,
> "coordinates");
> +      
> +        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.KML"
>  });    
>
>
> Tim Schaub wrote:
>> Hi-
>>
>> So, we're mid-way through changing how XML flavors are read/written in
>> OpenLayers.
>>
>> I've checked a new XML format in to the trunk.  This format has most of
>> the methods we need for reading/writing XML cross-browser.
>>
>> To parse other XML flavors, format classes should be created that
>> inherit from the XML format.
>>
>> For an (incomplete) example, see:
>> http://dev.openlayers.org/sandbox/tschaub/xml/lib/OpenLayers/Format/GML.js
>>
>> (The important part to notice in the above example is that the GML
>> format inherits from the XML format.)
>>
>> Instead of using OpenLayers.Ajax methods or document methods, DOM
>> creation and traversal should be done with OpenLayers.Format.XML
>> methods.  I've created methods to reflect the W3C standard XML DOM
>> methods - wrapping the standard ones and accommodating for non-compliant
>> browsers.
>>
>> If you (or anyone) needs additional XML DOM methods, they should be
>> added to the XML format.  The next addition (in my mind) is
>> setAttributeNS.  Aside from that, you should be able to do efficient
>> parsing and dom creation with the XML format methods.
>>
>> Please make modifications to the KML format in the trunk.  Create a
>> ticket and attach patches in Trac.  I can offer review or other help as
>> needed.
>>
>> I don't have time to keep these sandboxes entirely clean right now - so
>> please forgive anything you find that is in a half-developed state.
>>
>> Tim
>>
>> PS - Eventually, I'll move the following example into the trunk.  It
>> would be nice if we could demonstrate read/write capability for all
>> vector formats in this way:
>> http://dev.openlayers.org/sandbox/tschaub/xml/examples/vector-formats.html
>>
>> (note again that this reflects partially complete work - and you should
>> not be surprised to encounter errors or see changes at any time)
>>
>>
>> Damien Corpataux wrote:
>>  
>>> Hello,
>>>
>>> Here's what I did so far... Reading KML only work for KML 2.0 namespaces
>>> for write() uses OpenLayers.Ajax.getElementsByTagNameNS(), but I'm
>>> pretty sure it will work on future versions (2.1 parsing successful).
>>> Also, GML and KML write() returns a Dom Document rather than a string.
>>> Should one change the result type, breaking OpenLayers.Format interface,
>>> or parse it into a string using OpenLayers.XML.....?
>>>
>>> Cheers,
>>> Damien
>>>
>>>    
> [patch stripped]
>
> --
> Camptocamp SA
> Damien Corpataux
> PSE A
> CH-1015 Lausanne
> +41 21 619 10 22 (Direct)
> +41 21 619 10 10 (Centrale)
> +41 21 619 10 00 (Fax)
> P Please consider the environment
> Do you really need to print this email?
> !DSPAM:4033,46cd662e41812090977483!
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Dev mailing list
> [hidden email]
> http://openlayers.org/mailman/listinfo/dev
>
>
> !DSPAM:4033,46cd662e41812090977483!

_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
Damien Corpataux

Re: OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
Some javascript/style in this post has been disabled (why?)
Hi Tim,

I just posted a patch on ticket #927. The patch suits the requirements:
- KML extends XML
- XML class methods are used for XML manipulation
- tested on FF2/Linux and IE7
- KML.write() returns a string (using XML.write())
- GGE import of OL exported KML is working, and vice-versa

My 2 cents

Cheers,
Damien


Tim Schaub wrote:
I've opened ticket #927 to track this.

If anybody has a patch for KML, please attach it to that ticket. 
Damien, I've referenced your email on the ticket.

Since XML flavors should now all inherit from the XML format class, I'd 
say that write will always return a string.

Thanks for any contributions.
Tim


Damien Corpataux wrote:
  
Hello,

As far as I can see, the advantages of doing so are obvious. Althought I 
didn't have time to apply these, here is a new version of the patch:
- puts placemarks in a folder tag (for google earth import)
- bugfix with geometry tags

Is the question about write() return type (string or DOMDocuemt/DOMNode) 
still open?

Cheers,
Damien


Patch:
Index: /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js
===================================================================
--- 
/home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js    
(revision 3900)
+++ 
/home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js    
(working copy)
@@ -8,8 +8,8 @@
  * @requires OpenLayers/Ajax.js
  *
  * Class: OpenLayers.Format.KML
- * Read only KML. Largely Proof of Concept: does not support advanced 
Features,
- *     including Polygons.  Create a new instance with the
+ * Read/write KML 2.0. Does not support advanced Features.
+ *     Create a new instance with the
  *     <OpenLayers.Format.KML> constructor.
  *
  * Inherits from:
@@ -24,6 +24,24 @@
     kmlns: "http://earth.google.com/kml/2.0",
    
     /**
+     * APIProperty: placemarksDesc
+     * Default description for a placemark
+     */
+    placemarksDesc: "No description available",
+
+    /**
+     * APIProperty: foldersName
+     * Default name for a folder
+     */
+    foldersName: "OpenLayers export",
+
+    /**
+     * APIProperty: foldersDesc
+     * Default description for a folder
+     */
+    foldersDesc: "Exported on " + new Date(),
+
+    /**
      * Constructor: OpenLayers.Format.KML
      * Create a new parser for KML
      *
@@ -46,7 +64,7 @@
         if (typeof data == "string") {
             data = OpenLayers.parseXMLString(data);
         }   
-        var featureNodes = OpenLayers.Ajax.getElementsByTagNameNS(data, 
this.kmlns, "", "Placemark");
+        var featureNodes = OpenLayers.Ajax.getElementsByTagNameNS(data, 
this.kmlns, "kml", "Placemark");
        
         var features = [];
        
@@ -100,6 +118,19 @@
                 // TBD Bounds only set for one of multiple geometries
                 geom.extendBounds(p.bounds);
             }
+
+        // match Polygon
+        } else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
+            this.kmlns, "", "Polygon").length != 0) {
+            var polygon = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
+                this.kmlns, "", "Polygon")[0];
+            p = this.parseCoords(polygon);
+            if (p.points) {
+                var linearRing = new 
OpenLayers.Geometry.LinearRing(p.points);
+                geom = new OpenLayers.Geometry.Polygon(linearRing);
+                // TBD Bounds only set for one of multiple geometries
+                geom.extendBounds(p.bounds);
+            }
         }
        
         feature.geometry = geom;
@@ -191,5 +222,171 @@
         return p;
     },
 
+    /**
+     * Method: write
+     * Accept Feature Collection, and return an XML Document.
+     *
+     * Parameters:
+     * features - An array of <OpenLayers.Feature.Vector> features.
+     *
+     * Returns:
+     * <DOMDocument>
+     */
+     write: function(features) {
+        var kml = document.createElementNS(this.kmlns, "kml");
+        var folder = this.createFolderXML();
+        for (var i=0; i < features.length; i++) {
+            folder.appendChild(this.createPlacemarkXML(features[i]));
+        }
+        kml.appendChild(folder);
+        return kml;
+     },
+
+    /**
+     * Method: createFolderXML
+     * Creates and returns a KML Folder node with default name and 
description
+     *
+     * Returns:
+     * xmlNode - {<XMLNode>}
+     */
+    createFolderXML: function() {
+        // Folder name
+        var folderName = document.createElementNS(this.kmlns, "name");
+        var folderNameText = document.createTextNode(this.foldersName);
+        folderName.appendChild(folderNameText);
+
+        // Folder description
+        var folderDesc = document.createElementNS(this.kmlns, 
"description");       
+        var folderDescText = document.createTextNode(this.foldersDesc);
+        folderDesc.appendChild(folderDescText);
+
+        // Folder
+        var folder = document.createElementNS(this.kmlns, "Folder");
+        folder.appendChild(folderName);
+        folder.appendChild(folderDesc);
+       
+        return folder;
+    },
+
+    /**
+     * Method: createPlacemarkXML
+     * Accept an OpenLayers.Feature.Vector, and create a KML Placemark node
+     *
+     * Parameters:
+     * feature - {<OpenLayers.Feature.Vector>}
+     *
+     * Returns:
+     * xmlNode - {<XMLNode>}
+     */
+    createPlacemarkXML: function(feature) {
+        // Placemark name
+        var placemarkName = document.createElementNS(this.kmlns, "name");
+        var placemarkNameText = document.createTextNode(feature.id);
+        placemarkName.appendChild(placemarkNameText);
+
+        // Placemark description
+        var placemarkDesc = document.createElementNS(this.kmlns, 
"description");
+        var placemarkDescText = 
document.createTextNode(this.placemarksDesc);
+        placemarkDesc.appendChild(placemarkDescText);
+       
+        // Placemark
+        var placemarkNode = document.createElementNS(this.kmlns, 
"Placemark");
+        placemarkNode.appendChild(placemarkName);
+        placemarkNode.appendChild(placemarkDesc);
+
+        // Geometry node (Point, LineString, etc. nodes)
+        var geometryNode = this.buildGeometryNode(feature.geometry);
+        placemarkNode.appendChild(geometryNode);       
+       
+        return placemarkNode;
+    },   
+
+    /**
+     * Method: buildGeometryNode
+     * Builds a KML geometry node with a given geometry
+     *
+     * Parameters:
+     * geometry - {<OpenLayers.Geometry>}
+     *
+     * Returns:
+     * xmlNode - {<XMLNode>}
+     */
+    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 kml = "";
+        // match MultiPolygon or Polygon
+        if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon"
+            || geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
+                kml = document.createElementNS(this.kmlns, 'Polygon');
+               
+                var outerRing = document.createElementNS(this.kmlns, 
'outerBoundaryIs');
+                var linearRing = document.createElementNS(this.kmlns, 
'LinearRing');
+               
+                // TBD manage polygons with holes
+                
linearRing.appendChild(this.buildCoordinatesNode(geometry.components[0]));
+                outerRing.appendChild(linearRing);
+               
+                kml.appendChild(outerRing);
+            }
+        // match MultiLineString or LineString
+        else if (geometry.CLASS_NAME == 
"OpenLayers.Geometry.MultiLineString"
+                 || geometry.CLASS_NAME == 
"OpenLayers.Geometry.LineString") {
+                     kml = document.createElementNS(this.kmlns, 
'LineString');
+                                         
+                     kml.appendChild(this.buildCoordinatesNode(geometry));
+                 }
+        // match MultiPoint or Point
+        else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point" ||
+                  geometry.CLASS_NAME == 
"OpenLayers.Geometry.MultiPoint") {                    
+                kml = document.createElementNS(this.kmlns, 'Point');
+
+                // FIXME: There should be only one Point node per 
Placemark node
+                var parts = "";
+                if (geometry.CLASS_NAME == 
"OpenLayers.Geometry.MultiPoint") {
+                    parts = geometry.components;
+                } else {
+                    parts = [geometry];
+                }   
+               
+                for (var i = 0; i < parts.length; i++) {
+                    kml.appendChild(this.buildCoordinatesNode(parts[i]));
+               }    
+        }
+        return kml;        
+    },
+    /**
+     * Method: buildCoordinatesNode
+     * builds the KML coordinates node
+     *
+     * Parameters:
+     * geometry - {<OpenLayers.Geometry>}
+     *
+     * Returns:
+     * xmlNode - {<XMLNode>}
+     */
+    buildCoordinatesNode: function(geometry) {
+        var coordinatesNode = document.createElementNS(this.kmlns, 
"coordinates");
+       
+        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.KML"
 });    


Tim Schaub wrote:
    
Hi-

So, we're mid-way through changing how XML flavors are read/written in 
OpenLayers.

I've checked a new XML format in to the trunk.  This format has most of 
the methods we need for reading/writing XML cross-browser.

To parse other XML flavors, format classes should be created that 
inherit from the XML format.

For an (incomplete) example, see:
http://dev.openlayers.org/sandbox/tschaub/xml/lib/OpenLayers/Format/GML.js

(The important part to notice in the above example is that the GML 
format inherits from the XML format.)

Instead of using OpenLayers.Ajax methods or document methods, DOM 
creation and traversal should be done with OpenLayers.Format.XML 
methods.  I've created methods to reflect the W3C standard XML DOM 
methods - wrapping the standard ones and accommodating for non-compliant 
browsers.

If you (or anyone) needs additional XML DOM methods, they should be 
added to the XML format.  The next addition (in my mind) is 
setAttributeNS.  Aside from that, you should be able to do efficient 
parsing and dom creation with the XML format methods.

Please make modifications to the KML format in the trunk.  Create a 
ticket and attach patches in Trac.  I can offer review or other help as 
needed.

I don't have time to keep these sandboxes entirely clean right now - so 
please forgive anything you find that is in a half-developed state.

Tim

PS - Eventually, I'll move the following example into the trunk.  It 
would be nice if we could demonstrate read/write capability for all 
vector formats in this way:
http://dev.openlayers.org/sandbox/tschaub/xml/examples/vector-formats.html

(note again that this reflects partially complete work - and you should 
not be surprised to encounter errors or see changes at any time)


Damien Corpataux wrote:
  
      
Hello,

Here's what I did so far... Reading KML only work for KML 2.0 namespaces 
for write() uses OpenLayers.Ajax.getElementsByTagNameNS(), but I'm 
pretty sure it will work on future versions (2.1 parsing successful). 
Also, GML and KML write() returns a Dom Document rather than a string. 
Should one change the result type, breaking OpenLayers.Format interface, 
or parse it into a string using OpenLayers.XML.....?

Cheers,
Damien

    
        
[patch stripped]

-- 
Camptocamp SA
Damien Corpataux
PSE A
CH-1015 Lausanne
+41 21 619 10 22 (Direct)
+41 21 619 10 10 (Centrale)
+41 21 619 10 00 (Fax)
P Please consider the environment
Do you really need to print this email?
!DSPAM:4033,46cd662e41812090977483!


------------------------------------------------------------------------

_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev


!DSPAM:4033,46cd662e41812090977483!
    

_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
  


--
Camptocamp SA
Damien Corpataux
PSE A
CH-1015 Lausanne
+41 21 619 10 22 (Direct)
+41 21 619 10 10 (Centrale)
+41 21 619 10 00 (Fax)
P Please consider the environment
Do you really need to print this email?

_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
Christopher Schmidt-2

Re: OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
On Tue, Sep 04, 2007 at 04:28:52PM +0200, Damien Corpataux wrote:
> Hi Tim,
>
> I just posted a patch on ticket #927. The patch suits the requirements:
> - KML extends XML
> - XML class methods are used for XML manipulation
> - tested on FF2/Linux and IE7
> - KML.write() returns a string (using XML.write())
> - GGE import of OL exported KML is working, and vice-versa
>

Looks pretty good. Any chance you could write some tests for KML.write()
-- just a few simple ones, to confirm it works?

Regards,
--
Christopher Schmidt
MetaCarta
_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
Damien Corpataux

Re: OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
Some javascript/style in this post has been disabled (why?)
Thanks!

I think you mean unit tests... Glurp, I never played around with testanotherway. Although I'm interested in doing it when I get to have a little time, here is the test code I ran in firebug, using the openlayers/examples/vector-features.html example:

---8<-------------------------------------------------------------------
var kml = new OpenLayers.Format.KML();
var kmlOut = kml.write(map.layers[1].features);

kmlOut;

map.layers[1].eraseFeatures(map.layers[1].features);
map.layers[1].features = [];

var features = kml.read(kmlOut);

features;

map.layers[1].addFeatures(features);
---8<-------------------------------------------------------------------

Cheers,
Damien

Christopher Schmidt wrote:
On Tue, Sep 04, 2007 at 04:28:52PM +0200, Damien Corpataux wrote:
  
Hi Tim,

I just posted a patch on ticket #927. The patch suits the requirements:
- KML extends XML
- XML class methods are used for XML manipulation
- tested on FF2/Linux and IE7
- KML.write() returns a string (using XML.write())
- GGE import of OL exported KML is working, and vice-versa

    

Looks pretty good. Any chance you could write some tests for KML.write()
-- just a few simple ones, to confirm it works?

Regards,
  


--
Camptocamp SA
Damien Corpataux
PSE A
CH-1015 Lausanne
+41 21 619 10 22 (Direct)
+41 21 619 10 10 (Centrale)
+41 21 619 10 00 (Fax)
P Please consider the environment
Do you really need to print this email?

_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
Christopher Schmidt-2

Re: OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
On Tue, Sep 04, 2007 at 05:21:53PM +0200, Damien Corpataux wrote:
> Thanks!
>
> I think you mean unit tests... Glurp, I never played around with
> testanotherway. Although I'm interested in doing it when I get to have a
> little time, here is the test code I ran in firebug, using the
> openlayers/examples/vector-features.html example:

Okay, I've put together a stub for you in the tests/Format/test_KML.html
file. What I would do here is very similar to what you have below:
 * Create a KML parser.
 * Create a feature -- point, line, polygon, whatever.
 * In Firebug or elsewhere, create a text string which you can copy
   paste with the expected output KML: set that as the expectedOut
   variable.
 * Create kmlOut against that feature:
   kmlOut = kml.write([myFeature]);
 * Test that expectedOut matches KML Out:
    t.eq(expectedOut, kmlOut, "KML output matches given point feature");
 * If you feel up to it, add a test to write, which reads the output
   KML (as below) and test things like:
    t.eq(outputFeatures.length, 1, "Got correct number of features
                                    back");
    t.eq(outputFeatures[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Point",
                      "Correct geom type returned.");                                

etc.

If you don't get a chance, I'll bang something out soon, since we're
trying not to shove things in without at least some tests -- but thanks
for the patch regardless!

> ---8<-------------------------------------------------------------------
> var kml = new OpenLayers.Format.KML();
> var kmlOut = kml.write(map.layers[1].features);
>
> map.layers[1].eraseFeatures(map.layers[1].features);
> map.layers[1].features = [];
>
> var features = kml.read(kmlOut);
>
> features;
>
> map.layers[1].addFeatures(features);
> ---8<-------------------------------------------------------------------



--
Christopher Schmidt
MetaCarta
_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
Damien Corpataux

Re: OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
Some javascript/style in this post has been disabled (why?)
Hi Christopher,

Thanks for the stub! It got me into writing the tests (very quick). Everything's fine on ff2, but a problem occurs on IE7 (only when running the tests, not on using the component within OL).

I put all the information and patch into the ticket, which I now wonder whether it's a good idea, http://trac.openlayers.org/ticket/927#comment:5

Anybody might have ran into a similar problem with test.anotherway?


Cheers,
Damien


Christopher Schmidt wrote:
On Tue, Sep 04, 2007 at 05:21:53PM +0200, Damien Corpataux wrote:
  
Thanks!

I think you mean unit tests... Glurp, I never played around with
testanotherway. Although I'm interested in doing it when I get to have a
little time, here is the test code I ran in firebug, using the
openlayers/examples/vector-features.html example:
    

Okay, I've put together a stub for you in the tests/Format/test_KML.html
file. What I would do here is very similar to what you have below: 
 * Create a KML parser.
 * Create a feature -- point, line, polygon, whatever.
 * In Firebug or elsewhere, create a text string which you can copy
   paste with the expected output KML: set that as the expectedOut
   variable. 
 * Create kmlOut against that feature: 
   kmlOut = kml.write([myFeature]);
 * Test that expectedOut matches KML Out:
    t.eq(expectedOut, kmlOut, "KML output matches given point feature");
 * If you feel up to it, add a test to write, which reads the output
   KML (as below) and test things like:
    t.eq(outputFeatures.length, 1, "Got correct number of features
                                    back");
    t.eq(outputFeatures[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Point", 
                      "Correct geom type returned.");                                

etc.

If you don't get a chance, I'll bang something out soon, since we're
trying not to shove things in without at least some tests -- but thanks
for the patch regardless!

  
---8<-------------------------------------------------------------------
var kml = new OpenLayers.Format.KML();
var kmlOut = kml.write(map.layers[1].features);

map.layers[1].eraseFeatures(map.layers[1].features);
map.layers[1].features = [];

var features = kml.read(kmlOut);

features;

map.layers[1].addFeatures(features);
---8<-------------------------------------------------------------------
    



  


--
Camptocamp SA
Damien Corpataux
PSE A
CH-1015 Lausanne
+41 21 619 10 22 (Direct)
+41 21 619 10 10 (Centrale)
+41 21 619 10 00 (Fax)
P Please consider the environment
Do you really need to print this email?

_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
Christopher Schmidt-2

Re: OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
On Wed, Sep 05, 2007 at 12:27:09PM +0200, Damien Corpataux wrote:

> Hi Christopher,
>
> Thanks for the stub! It got me into writing the tests (very quick).
> Everything's fine on ff2, but a problem occurs on IE7 (only when running
> the tests, not on using the component within OL).
>
> I put all the information and patch into the ticket, which I now wonder
> whether it's a good idea, http://trac.openlayers.org/ticket/927#comment:5
>
> Anybody might have ran into a similar problem with test.anotherway?

Interesting. I'll see if I can figure out why: The GML tests should be
using something similar, and they don't have any problems I'm aware of.

Regards,
--
Christopher Schmidt
MetaCarta
_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
Damien Corpataux

Re: OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
Some javascript/style in this post has been disabled (why?)
Christopher Schmidt wrote:
On Wed, Sep 05, 2007 at 12:27:09PM +0200, Damien Corpataux wrote:
  
Hi Christopher,

Thanks for the stub! It got me into writing the tests (very quick).
Everything's fine on ff2, but a problem occurs on IE7 (only when running
the tests, not on using the component within OL).

I put all the information and patch into the ticket, which I now wonder
whether it's a good idea, http://trac.openlayers.org/ticket/927#comment:5

Anybody might have ran into a similar problem with test.anotherway?
    

Interesting. I'll see if I can figure out why: The GML tests should be
using something similar, and they don't have any problems I'm aware of.

Regards,
  
Unfortunately, test_GML.html doesn't test GML.write() and GML and is not yet using XML class methods for Doc manipulation... I wish I could help a little further, but I think my knowledge of Test.AnotherWay is too limited to rapidly make out what's going on... :\

http://trac.openlayers.org/browser/trunk/openlayers/tests/Format/test_GML.html
http://trac.openlayers.org/browser/trunk/openlayers/lib/OpenLayers/Format/GML.js

Regards,
Damien

--
Camptocamp SA
Damien Corpataux
PSE A
CH-1015 Lausanne
+41 21 619 10 22 (Direct)
+41 21 619 10 10 (Centrale)
+41 21 619 10 00 (Fax)
P Please consider the environment
Do you really need to print this email?

_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
Christopher Schmidt-2

Re: OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
On Wed, Sep 05, 2007 at 02:40:12PM +0200, Damien Corpataux wrote:

> Christopher Schmidt wrote:
> > On Wed, Sep 05, 2007 at 12:27:09PM +0200, Damien Corpataux wrote:
> >  
> >> Hi Christopher,
> >>
> >> Thanks for the stub! It got me into writing the tests (very quick).
> >> Everything's fine on ff2, but a problem occurs on IE7 (only when running
> >> the tests, not on using the component within OL).
> >>
> >> I put all the information and patch into the ticket, which I now wonder
> >> whether it's a good idea, http://trac.openlayers.org/ticket/927#comment:5
> >>
> >> Anybody might have ran into a similar problem with test.anotherway?
> >>    
> >
> > Interesting. I'll see if I can figure out why: The GML tests should be
> > using something similar, and they don't have any problems I'm aware of.
> >
> > Regards,
> >  
> Unfortunately, test_GML.html doesn't test GML.write() and GML and is not
> yet using XML class methods for Doc manipulation... I wish I could help
> a little further, but I think my knowledge of Test.AnotherWay is too
> limited to rapidly make out what's going on... :\
>
> http://trac.openlayers.org/browser/trunk/openlayers/tests/Format/test_GML.html
> http://trac.openlayers.org/browser/trunk/openlayers/lib/OpenLayers/Format/GML.js

Right, sorry: the GML tests I was talking about haven't made it back to
trunk yet, they're still at:
http://svn.openlayers.org/sandbox/tschaub/xml/tests/Format/test_GML.html

It's possible we're still missing something in the XML format though, so
I'll take a look at it: thanks for the tests you've got so far! :) Sorry
something seems to be more complex than it otherwise should be.

Regards,
--
Christopher Schmidt
MetaCarta
_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
Tim Schaub-3

Re: OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
In reply to this post by Damien Corpataux
Damien Corpataux wrote:

> Hi Tim,
>
> I just posted a patch on ticket #927. The patch suits the requirements:
> - KML extends XML
> - XML class methods are used for XML manipulation
> - tested on FF2/Linux and IE7
> - KML.write() returns a string (using XML.write())
> - GGE import of OL exported KML is working, and vice-versa
>
> My 2 cents
>
> Cheers,
> Damien
>

Thanks for the patch Damien.  I rewrote things a bit and put this in
with r4219 [1].  I added support for KML MultiGeometry and improved the
read/write stuff so all OL geometries are supported.  Also,
name/description attributes and feature id survive a round trip through
read/write.

There are likely still issues with the parser.  In particular, we don't
write out feature attributes (beyond name/description).

You can play with the vector formats example to see OL KML output [2].
Paste in any KML you can find and report back any trouble with the parser.

Tim

[1] http://trac.openlayers.org/changeset/4219

[2] http://openlayers.org/dev/examples/vector-formats.html



>
> Tim Schaub wrote:
>> I've opened ticket #927 to track this.
>>
>> If anybody has a patch for KML, please attach it to that ticket.
>> Damien, I've referenced your email on the ticket.
>>
>> Since XML flavors should now all inherit from the XML format class, I'd
>> say that write will always return a string.
>>
>> Thanks for any contributions.
>> Tim
>>
>>
>> Damien Corpataux wrote:
>>  
>>> Hello,
>>>
>>> As far as I can see, the advantages of doing so are obvious. Althought I
>>> didn't have time to apply these, here is a new version of the patch:
>>> - puts placemarks in a folder tag (for google earth import)
>>> - bugfix with geometry tags
>>>
>>> Is the question about write() return type (string or DOMDocuemt/DOMNode)
>>> still open?
>>>
>>> Cheers,
>>> Damien
>>>
>>>
>>> Patch:
>>> Index: /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js
>>> ===================================================================
>>> ---
>>> /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js    
>>> (revision 3900)
>>> +++
>>> /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js    
>>> (working copy)
>>> @@ -8,8 +8,8 @@
>>>   * @requires OpenLayers/Ajax.js
>>>   *
>>>   * Class: OpenLayers.Format.KML
>>> - * Read only KML. Largely Proof of Concept: does not support advanced
>>> Features,
>>> - *     including Polygons.  Create a new instance with the
>>> + * Read/write KML 2.0. Does not support advanced Features.
>>> + *     Create a new instance with the
>>>   *     <OpenLayers.Format.KML> constructor.
>>>   *
>>>   * Inherits from:
>>> @@ -24,6 +24,24 @@
>>>      kmlns: "http://earth.google.com/kml/2.0",
>>>    
>>>      /**
>>> +     * APIProperty: placemarksDesc
>>> +     * Default description for a placemark
>>> +     */
>>> +    placemarksDesc: "No description available",
>>> +
>>> +    /**
>>> +     * APIProperty: foldersName
>>> +     * Default name for a folder
>>> +     */
>>> +    foldersName: "OpenLayers export",
>>> +
>>> +    /**
>>> +     * APIProperty: foldersDesc
>>> +     * Default description for a folder
>>> +     */
>>> +    foldersDesc: "Exported on " + new Date(),
>>> +
>>> +    /**
>>>       * Constructor: OpenLayers.Format.KML
>>>       * Create a new parser for KML
>>>       *
>>> @@ -46,7 +64,7 @@
>>>          if (typeof data == "string") {
>>>              data = OpenLayers.parseXMLString(data);
>>>          }  
>>> -        var featureNodes = OpenLayers.Ajax.getElementsByTagNameNS(data,
>>> this.kmlns, "", "Placemark");
>>> +        var featureNodes = OpenLayers.Ajax.getElementsByTagNameNS(data,
>>> this.kmlns, "kml", "Placemark");
>>>        
>>>          var features = [];
>>>        
>>> @@ -100,6 +118,19 @@
>>>                  // TBD Bounds only set for one of multiple geometries
>>>                  geom.extendBounds(p.bounds);
>>>              }
>>> +
>>> +        // match Polygon
>>> +        } else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
>>> +            this.kmlns, "", "Polygon").length != 0) {
>>> +            var polygon = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
>>> +                this.kmlns, "", "Polygon")[0];
>>> +            p = this.parseCoords(polygon);
>>> +            if (p.points) {
>>> +                var linearRing = new
>>> OpenLayers.Geometry.LinearRing(p.points);
>>> +                geom = new OpenLayers.Geometry.Polygon(linearRing);
>>> +                // TBD Bounds only set for one of multiple geometries
>>> +                geom.extendBounds(p.bounds);
>>> +            }
>>>          }
>>>        
>>>          feature.geometry = geom;
>>> @@ -191,5 +222,171 @@
>>>          return p;
>>>      },
>>>  
>>> +    /**
>>> +     * Method: write
>>> +     * Accept Feature Collection, and return an XML Document.
>>> +     *
>>> +     * Parameters:
>>> +     * features - An array of <OpenLayers.Feature.Vector> features.
>>> +     *
>>> +     * Returns:
>>> +     * <DOMDocument>
>>> +     */
>>> +     write: function(features) {
>>> +        var kml = document.createElementNS(this.kmlns, "kml");
>>> +        var folder = this.createFolderXML();
>>> +        for (var i=0; i < features.length; i++) {
>>> +            folder.appendChild(this.createPlacemarkXML(features[i]));
>>> +        }
>>> +        kml.appendChild(folder);
>>> +        return kml;
>>> +     },
>>> +
>>> +    /**
>>> +     * Method: createFolderXML
>>> +     * Creates and returns a KML Folder node with default name and
>>> description
>>> +     *
>>> +     * Returns:
>>> +     * xmlNode - {<XMLNode>}
>>> +     */
>>> +    createFolderXML: function() {
>>> +        // Folder name
>>> +        var folderName = document.createElementNS(this.kmlns, "name");
>>> +        var folderNameText = document.createTextNode(this.foldersName);
>>> +        folderName.appendChild(folderNameText);
>>> +
>>> +        // Folder description
>>> +        var folderDesc = document.createElementNS(this.kmlns,
>>> "description");      
>>> +        var folderDescText = document.createTextNode(this.foldersDesc);
>>> +        folderDesc.appendChild(folderDescText);
>>> +
>>> +        // Folder
>>> +        var folder = document.createElementNS(this.kmlns, "Folder");
>>> +        folder.appendChild(folderName);
>>> +        folder.appendChild(folderDesc);
>>> +      
>>> +        return folder;
>>> +    },
>>> +
>>> +    /**
>>> +     * Method: createPlacemarkXML
>>> +     * Accept an OpenLayers.Feature.Vector, and create a KML Placemark node
>>> +     *
>>> +     * Parameters:
>>> +     * feature - {<OpenLayers.Feature.Vector>}
>>> +     *
>>> +     * Returns:
>>> +     * xmlNode - {<XMLNode>}
>>> +     */
>>> +    createPlacemarkXML: function(feature) {
>>> +        // Placemark name
>>> +        var placemarkName = document.createElementNS(this.kmlns, "name");
>>> +        var placemarkNameText = document.createTextNode(feature.id);
>>> +        placemarkName.appendChild(placemarkNameText);
>>> +
>>> +        // Placemark description
>>> +        var placemarkDesc = document.createElementNS(this.kmlns,
>>> "description");
>>> +        var placemarkDescText =
>>> document.createTextNode(this.placemarksDesc);
>>> +        placemarkDesc.appendChild(placemarkDescText);
>>> +      
>>> +        // Placemark
>>> +        var placemarkNode = document.createElementNS(this.kmlns,
>>> "Placemark");
>>> +        placemarkNode.appendChild(placemarkName);
>>> +        placemarkNode.appendChild(placemarkDesc);
>>> +
>>> +        // Geometry node (Point, LineString, etc. nodes)
>>> +        var geometryNode = this.buildGeometryNode(feature.geometry);
>>> +        placemarkNode.appendChild(geometryNode);      
>>> +      
>>> +        return placemarkNode;
>>> +    },  
>>> +
>>> +    /**
>>> +     * Method: buildGeometryNode
>>> +     * Builds a KML geometry node with a given geometry
>>> +     *
>>> +     * Parameters:
>>> +     * geometry - {<OpenLayers.Geometry>}
>>> +     *
>>> +     * Returns:
>>> +     * xmlNode - {<XMLNode>}
>>> +     */
>>> +    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 kml = "";
>>> +        // match MultiPolygon or Polygon
>>> +        if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon"
>>> +            || geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
>>> +                kml = document.createElementNS(this.kmlns, 'Polygon');
>>> +              
>>> +                var outerRing = document.createElementNS(this.kmlns,
>>> 'outerBoundaryIs');
>>> +                var linearRing = document.createElementNS(this.kmlns,
>>> 'LinearRing');
>>> +              
>>> +                // TBD manage polygons with holes
>>> +                
>>> linearRing.appendChild(this.buildCoordinatesNode(geometry.components[0]));
>>> +                outerRing.appendChild(linearRing);
>>> +              
>>> +                kml.appendChild(outerRing);
>>> +            }
>>> +        // match MultiLineString or LineString
>>> +        else if (geometry.CLASS_NAME ==
>>> "OpenLayers.Geometry.MultiLineString"
>>> +                 || geometry.CLASS_NAME ==
>>> "OpenLayers.Geometry.LineString") {
>>> +                     kml = document.createElementNS(this.kmlns,
>>> 'LineString');
>>> +                                        
>>> +                     kml.appendChild(this.buildCoordinatesNode(geometry));
>>> +                 }
>>> +        // match MultiPoint or Point
>>> +        else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point" ||
>>> +                  geometry.CLASS_NAME ==
>>> "OpenLayers.Geometry.MultiPoint") {                    
>>> +                kml = document.createElementNS(this.kmlns, 'Point');
>>> +
>>> +                // FIXME: There should be only one Point node per
>>> Placemark node
>>> +                var parts = "";
>>> +                if (geometry.CLASS_NAME ==
>>> "OpenLayers.Geometry.MultiPoint") {
>>> +                    parts = geometry.components;
>>> +                } else {
>>> +                    parts = [geometry];
>>> +                }  
>>> +              
>>> +                for (var i = 0; i < parts.length; i++) {
>>> +                    kml.appendChild(this.buildCoordinatesNode(parts[i]));
>>> +               }    
>>> +        }
>>> +        return kml;        
>>> +    },
>>> +    /**
>>> +     * Method: buildCoordinatesNode
>>> +     * builds the KML coordinates node
>>> +     *
>>> +     * Parameters:
>>> +     * geometry - {<OpenLayers.Geometry>}
>>> +     *
>>> +     * Returns:
>>> +     * xmlNode - {<XMLNode>}
>>> +     */
>>> +    buildCoordinatesNode: function(geometry) {
>>> +        var coordinatesNode = document.createElementNS(this.kmlns,
>>> "coordinates");
>>> +      
>>> +        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.KML"
>>>  });    
>>>
>>>
>>> Tim Schaub wrote:
>>>    
>>>> Hi-
>>>>
>>>> So, we're mid-way through changing how XML flavors are read/written in
>>>> OpenLayers.
>>>>
>>>> I've checked a new XML format in to the trunk.  This format has most of
>>>> the methods we need for reading/writing XML cross-browser.
>>>>
>>>> To parse other XML flavors, format classes should be created that
>>>> inherit from the XML format.
>>>>
>>>> For an (incomplete) example, see:
>>>> http://dev.openlayers.org/sandbox/tschaub/xml/lib/OpenLayers/Format/GML.js
>>>>
>>>> (The important part to notice in the above example is that the GML
>>>> format inherits from the XML format.)
>>>>
>>>> Instead of using OpenLayers.Ajax methods or document methods, DOM
>>>> creation and traversal should be done with OpenLayers.Format.XML
>>>> methods.  I've created methods to reflect the W3C standard XML DOM
>>>> methods - wrapping the standard ones and accommodating for non-compliant
>>>> browsers.
>>>>
>>>> If you (or anyone) needs additional XML DOM methods, they should be
>>>> added to the XML format.  The next addition (in my mind) is
>>>> setAttributeNS.  Aside from that, you should be able to do efficient
>>>> parsing and dom creation with the XML format methods.
>>>>
>>>> Please make modifications to the KML format in the trunk.  Create a
>>>> ticket and attach patches in Trac.  I can offer review or other help as
>>>> needed.
>>>>
>>>> I don't have time to keep these sandboxes entirely clean right now - so
>>>> please forgive anything you find that is in a half-developed state.
>>>>
>>>> Tim
>>>>
>>>> PS - Eventually, I'll move the following example into the trunk.  It
>>>> would be nice if we could demonstrate read/write capability for all
>>>> vector formats in this way:
>>>> http://dev.openlayers.org/sandbox/tschaub/xml/examples/vector-formats.html
>>>>
>>>> (note again that this reflects partially complete work - and you should
>>>> not be surprised to encounter errors or see changes at any time)
>>>>
>>>>
>>>> Damien Corpataux wrote:
>>>>  
>>>>      
>>>>> Hello,
>>>>>
>>>>> Here's what I did so far... Reading KML only work for KML 2.0 namespaces
>>>>> for write() uses OpenLayers.Ajax.getElementsByTagNameNS(), but I'm
>>>>> pretty sure it will work on future versions (2.1 parsing successful).
>>>>> Also, GML and KML write() returns a Dom Document rather than a string.
>>>>> Should one change the result type, breaking OpenLayers.Format interface,
>>>>> or parse it into a string using OpenLayers.XML.....?
>>>>>
>>>>> Cheers,
>>>>> Damien
>>>>>
>>>>>    
>>>>>        
>>> [patch stripped]
>>>
>>> --
>>> Camptocamp SA
>>> Damien Corpataux
>>> PSE A
>>> CH-1015 Lausanne
>>> +41 21 619 10 22 (Direct)
>>> +41 21 619 10 10 (Centrale)
>>> +41 21 619 10 00 (Fax)
>>> P Please consider the environment
>>> Do you really need to print this email?
>>>
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>> _______________________________________________
>>> Dev mailing list
>>> [hidden email]
>>> http://openlayers.org/mailman/listinfo/dev
>>>
>>>
>>> !DSPAM:4033,46cd662e41812090977483!
>>>    
>>
>> _______________________________________________
>> Dev mailing list
>> [hidden email]
>> http://openlayers.org/mailman/listinfo/dev
>>  
>
>
> --
> Camptocamp SA
> Damien Corpataux
> PSE A
> CH-1015 Lausanne
> +41 21 619 10 22 (Direct)
> +41 21 619 10 10 (Centrale)
> +41 21 619 10 00 (Fax)
> P Please consider the environment
> Do you really need to print this email?
> !DSPAM:4033,46dd6bc8182553362379201!

_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev
fporc7ji

Re: OpenLayers.Format.KML.write()

Reply Threaded More More options
Print post
Permalink
Hi Tim --

The only thing I noticed is when using IE6 the KML features do not overlay
with the same map when using IE7 or Firefox. It seems the features in IE6
are not displaying at the correct locations. Is this a known bug?

Regards,

Frank

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On
Behalf Of Tim Schaub
Sent: Tuesday, September 11, 2007 1:12 PM
To: [hidden email]
Subject: Re: [OpenLayers-Dev] OpenLayers.Format.KML.write()

Damien Corpataux wrote:

> Hi Tim,
>
> I just posted a patch on ticket #927. The patch suits the requirements:
> - KML extends XML
> - XML class methods are used for XML manipulation
> - tested on FF2/Linux and IE7
> - KML.write() returns a string (using XML.write())
> - GGE import of OL exported KML is working, and vice-versa
>
> My 2 cents
>
> Cheers,
> Damien
>

Thanks for the patch Damien.  I rewrote things a bit and put this in
with r4219 [1].  I added support for KML MultiGeometry and improved the
read/write stuff so all OL geometries are supported.  Also,
name/description attributes and feature id survive a round trip through
read/write.

There are likely still issues with the parser.  In particular, we don't
write out feature attributes (beyond name/description).

You can play with the vector formats example to see OL KML output [2].
Paste in any KML you can find and report back any trouble with the parser.

Tim

[1] http://trac.openlayers.org/changeset/4219

[2] http://openlayers.org/dev/examples/vector-formats.html



>
> Tim Schaub wrote:
>> I've opened ticket #927 to track this.
>>
>> If anybody has a patch for KML, please attach it to that ticket.
>> Damien, I've referenced your email on the ticket.
>>
>> Since XML flavors should now all inherit from the XML format class, I'd
>> say that write will always return a string.
>>
>> Thanks for any contributions.
>> Tim
>>
>>
>> Damien Corpataux wrote:
>>  
>>> Hello,
>>>
>>> As far as I can see, the advantages of doing so are obvious. Althought I

>>> didn't have time to apply these, here is a new version of the patch:
>>> - puts placemarks in a folder tag (for google earth import)
>>> - bugfix with geometry tags
>>>
>>> Is the question about write() return type (string or DOMDocuemt/DOMNode)

>>> still open?
>>>
>>> Cheers,
>>> Damien
>>>
>>>
>>> Patch:
>>> Index:
/home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js

>>> ===================================================================
>>> ---
>>> /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js    
>>> (revision 3900)
>>> +++
>>> /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js    
>>> (working copy)
>>> @@ -8,8 +8,8 @@
>>>   * @requires OpenLayers/Ajax.js
>>>   *
>>>   * Class: OpenLayers.Format.KML
>>> - * Read only KML. Largely Proof of Concept: does not support advanced
>>> Features,
>>> - *     including Polygons.  Create a new instance with the
>>> + * Read/write KML 2.0. Does not support advanced Features.
>>> + *     Create a new instance with the
>>>   *     <OpenLayers.Format.KML> constructor.
>>>   *
>>>   * Inherits from:
>>> @@ -24,6 +24,24 @@
>>>      kmlns: "http://earth.google.com/kml/2.0",
>>>    
>>>      /**
>>> +     * APIProperty: placemarksDesc
>>> +     * Default description for a placemark
>>> +     */
>>> +    placemarksDesc: "No description available",
>>> +
>>> +    /**
>>> +     * APIProperty: foldersName
>>> +     * Default name for a folder
>>> +     */
>>> +    foldersName: "OpenLayers export",
>>> +
>>> +    /**
>>> +     * APIProperty: foldersDesc
>>> +     * Default description for a folder
>>> +     */
>>> +    foldersDesc: "Exported on " + new Date(),
>>> +
>>> +    /**
>>>       * Constructor: OpenLayers.Format.KML
>>>       * Create a new parser for KML
>>>       *
>>> @@ -46,7 +64,7 @@
>>>          if (typeof data == "string") {
>>>              data = OpenLayers.parseXMLString(data);
>>>          }  
>>> -        var featureNodes = OpenLayers.Ajax.getElementsByTagNameNS(data,

>>> this.kmlns, "", "Placemark");
>>> +        var featureNodes = OpenLayers.Ajax.getElementsByTagNameNS(data,

>>> this.kmlns, "kml", "Placemark");
>>>        
>>>          var features = [];
>>>        
>>> @@ -100,6 +118,19 @@
>>>                  // TBD Bounds only set for one of multiple geometries
>>>                  geom.extendBounds(p.bounds);
>>>              }
>>> +
>>> +        // match Polygon
>>> +        } else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
>>> +            this.kmlns, "", "Polygon").length != 0) {
>>> +            var polygon =
OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,

>>> +                this.kmlns, "", "Polygon")[0];
>>> +            p = this.parseCoords(polygon);
>>> +            if (p.points) {
>>> +                var linearRing = new
>>> OpenLayers.Geometry.LinearRing(p.points);
>>> +                geom = new OpenLayers.Geometry.Polygon(linearRing);
>>> +                // TBD Bounds only set for one of multiple geometries
>>> +                geom.extendBounds(p.bounds);
>>> +            }
>>>          }
>>>        
>>>          feature.geometry = geom;
>>> @@ -191,5 +222,171 @@
>>>          return p;
>>>      },
>>>  
>>> +    /**
>>> +     * Method: write
>>> +     * Accept Feature Collection, and return an XML Document.
>>> +     *
>>> +     * Parameters:
>>> +     * features - An array of <OpenLayers.Feature.Vector> features.
>>> +     *
>>> +     * Returns:
>>> +     * <DOMDocument>
>>> +     */
>>> +     write: function(features) {
>>> +        var kml = document.createElementNS(this.kmlns, "kml");
>>> +        var folder = this.createFolderXML();
>>> +        for (var i=0; i < features.length; i++) {
>>> +            folder.appendChild(this.createPlacemarkXML(features[i]));
>>> +        }
>>> +        kml.appendChild(folder);
>>> +        return kml;
>>> +     },
>>> +
>>> +    /**
>>> +     * Method: createFolderXML
>>> +     * Creates and returns a KML Folder node with default name and
>>> description
>>> +     *
>>> +     * Returns:
>>> +     * xmlNode - {<XMLNode>}
>>> +     */
>>> +    createFolderXML: function() {
>>> +        // Folder name
>>> +        var folderName = document.createElementNS(this.kmlns, "name");
>>> +        var folderNameText = document.createTextNode(this.foldersName);
>>> +        folderName.appendChild(folderNameText);
>>> +
>>> +        // Folder description
>>> +        var folderDesc = document.createElementNS(this.kmlns,
>>> "description");      
>>> +        var folderDescText = document.createTextNode(this.foldersDesc);
>>> +        folderDesc.appendChild(folderDescText);
>>> +
>>> +        // Folder
>>> +        var folder = document.createElementNS(this.kmlns, "Folder");
>>> +        folder.appendChild(folderName);
>>> +        folder.appendChild(folderDesc);
>>> +      
>>> +        return folder;
>>> +    },
>>> +
>>> +    /**
>>> +     * Method: createPlacemarkXML
>>> +     * Accept an OpenLayers.Feature.Vector, and create a KML Placemark
node

>>> +     *
>>> +     * Parameters:
>>> +     * feature - {<OpenLayers.Feature.Vector>}
>>> +     *
>>> +     * Returns:
>>> +     * xmlNode - {<XMLNode>}
>>> +     */
>>> +    createPlacemarkXML: function(feature) {
>>> +        // Placemark name
>>> +        var placemarkName = document.createElementNS(this.kmlns,
"name");

>>> +        var placemarkNameText = document.createTextNode(feature.id);
>>> +        placemarkName.appendChild(placemarkNameText);
>>> +
>>> +        // Placemark description
>>> +        var placemarkDesc = document.createElementNS(this.kmlns,
>>> "description");
>>> +        var placemarkDescText =
>>> document.createTextNode(this.placemarksDesc);
>>> +        placemarkDesc.appendChild(placemarkDescText);
>>> +      
>>> +        // Placemark
>>> +        var placemarkNode = document.createElementNS(this.kmlns,
>>> "Placemark");
>>> +        placemarkNode.appendChild(placemarkName);
>>> +        placemarkNode.appendChild(placemarkDesc);
>>> +
>>> +        // Geometry node (Point, LineString, etc. nodes)
>>> +        var geometryNode = this.buildGeometryNode(feature.geometry);
>>> +        placemarkNode.appendChild(geometryNode);      
>>> +      
>>> +        return placemarkNode;
>>> +    },  
>>> +
>>> +    /**
>>> +     * Method: buildGeometryNode
>>> +     * Builds a KML geometry node with a given geometry
>>> +     *
>>> +     * Parameters:
>>> +     * geometry - {<OpenLayers.Geometry>}
>>> +     *
>>> +     * Returns:
>>> +     * xmlNode - {<XMLNode>}
>>> +     */
>>> +    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 kml = "";
>>> +        // match MultiPolygon or Polygon
>>> +        if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon"
>>> +            || geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
>>> +                kml = document.createElementNS(this.kmlns, 'Polygon');
>>> +              
>>> +                var outerRing = document.createElementNS(this.kmlns,
>>> 'outerBoundaryIs');
>>> +                var linearRing = document.createElementNS(this.kmlns,
>>> 'LinearRing');
>>> +              
>>> +                // TBD manage polygons with holes
>>> +                
>>>
linearRing.appendChild(this.buildCoordinatesNode(geometry.components[0]));

>>> +                outerRing.appendChild(linearRing);
>>> +              
>>> +                kml.appendChild(outerRing);
>>> +            }
>>> +        // match MultiLineString or LineString
>>> +        else if (geometry.CLASS_NAME ==
>>> "OpenLayers.Geometry.MultiLineString"
>>> +                 || geometry.CLASS_NAME ==
>>> "OpenLayers.Geometry.LineString") {
>>> +                     kml = document.createElementNS(this.kmlns,
>>> 'LineString');
>>> +                                        
>>> +
kml.appendChild(this.buildCoordinatesNode(geometry));

>>> +                 }
>>> +        // match MultiPoint or Point
>>> +        else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point" ||
>>> +                  geometry.CLASS_NAME ==
>>> "OpenLayers.Geometry.MultiPoint") {                    
>>> +                kml = document.createElementNS(this.kmlns, 'Point');
>>> +
>>> +                // FIXME: There should be only one Point node per
>>> Placemark node
>>> +                var parts = "";
>>> +                if (geometry.CLASS_NAME ==
>>> "OpenLayers.Geometry.MultiPoint") {
>>> +                    parts = geometry.components;
>>> +                } else {
>>> +                    parts = [geometry];
>>> +                }  
>>> +              
>>> +                for (var i = 0; i < parts.length; i++) {
>>> +
kml.appendChild(this.buildCoordinatesNode(parts[i]));

>>> +               }    
>>> +        }
>>> +        return kml;        
>>> +    },
>>> +    /**
>>> +     * Method: buildCoordinatesNode
>>> +     * builds the KML coordinates node
>>> +     *
>>> +     * Parameters:
>>> +     * geometry - {<OpenLayers.Geometry>}
>>> +     *
>>> +     * Returns:
>>> +     * xmlNode - {<XMLNode>}
>>> +     */
>>> +    buildCoordinatesNode: function(geometry) {
>>> +        var coordinatesNode = document.createElementNS(this.kmlns,
>>> "coordinates");
>>> +      
>>> +        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.KML"
>>>  });    
>>>
>>>
>>> Tim Schaub wrote:
>>>    
>>>> Hi-
>>>>
>>>> So, we're mid-way through changing how XML flavors are read/written in
>>>> OpenLayers.
>>>>
>>>> I've checked a new XML format in to the trunk.  This format has most of

>>>> the methods we need for reading/writing XML cross-browser.
>>>>
>>>> To parse other XML flavors, format classes should be created that
>>>> inherit from the XML format.
>>>>
>>>> For an (incomplete) example, see:
>>>>
http://dev.openlayers.org/sandbox/tschaub/xml/lib/OpenLayers/Format/GML.js
>>>>
>>>> (The important part to notice in the above example is that the GML
>>>> format inherits from the XML format.)
>>>>
>>>> Instead of using OpenLayers.Ajax methods or document methods, DOM
>>>> creation and traversal should be done with OpenLayers.Format.XML
>>>> methods.  I've created methods to reflect the W3C standard XML DOM
>>>> methods - wrapping the standard ones and accommodating for
non-compliant
>>>> browsers.
>>>>
>>>> If you (or anyone) needs additional XML DOM methods, they should be
>>>> added to the XML format.  The next addition (in my mind) is
>>>> setAttributeNS.  Aside from that, you should be able to do efficient
>>>> parsing and dom creation with the XML format methods.
>>>>
>>>> Please make modifications to the KML format in the trunk.  Create a
>>>> ticket and attach patches in Trac.  I can offer review or other help as

>>>> needed.
>>>>
>>>> I don't have time to keep these sandboxes entirely clean right now - so

>>>> please forgive anything you find that is in a half-developed state.
>>>>
>>>> Tim
>>>>
>>>> PS - Eventually, I'll move the following example into the trunk.  It
>>>> would be nice if we could demonstrate read/write capability for all
>>>> vector formats in this way:
>>>>
http://dev.openlayers.org/sandbox/tschaub/xml/examples/vector-formats.html
>>>>
>>>> (note again that this reflects partially complete work - and you should

>>>> not be surprised to encounter errors or see changes at any time)
>>>>
>>>>
>>>> Damien Corpataux wrote:
>>>>  
>>>>      
>>>>> Hello,
>>>>>
>>>>> Here's what I did so far... Reading KML only work for KML 2.0
namespaces
>>>>> for write() uses OpenLayers.Ajax.getElementsByTagNameNS(), but I'm
>>>>> pretty sure it will work on future versions (2.1 parsing successful).
>>>>> Also, GML and KML write() returns a Dom Document rather than a string.

>>>>> Should one change the result type, breaking OpenLayers.Format
interface,

>>>>> or parse it into a string using OpenLayers.XML.....?
>>>>>
>>>>> Cheers,
>>>>> Damien
>>>>>
>>>>>    
>>>>>        
>>> [patch stripped]
>>>
>>> --
>>> Camptocamp SA
>>> Damien Corpataux
>>> PSE A
>>> CH-1015 Lausanne
>>> +41 21 619 10 22 (Direct)
>>> +41 21 619 10 10 (Centrale)
>>> +41 21 619 10 00 (Fax)
>>> P Please consider the environment
>>> Do you really need to print this email?
>>>
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>> _______________________________________________
>>> Dev mailing list
>>> [hidden email]
>>> http://openlayers.org/mailman/listinfo/dev
>>>
>>>
>>> !DSPAM:4033,46cd662e41812090977483!
>>>    
>>
>> _______________________________________________
>> Dev mailing list
>> [hidden email]
>> http://openlayers.org/mailman/listinfo/dev
>>  
>
>
> --
> Camptocamp SA
> Damien Corpataux
> PSE A
> CH-1015 Lausanne
> +41 21 619 10 22 (Direct)
> +41 21 619 10 10 (Centrale)
> +41 21 619 10 00 (Fax)
> P Please consider the environment
> Do you really need to print this email?
> !DSPAM:4033,46dd6bc8182553362379201!

_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev

_______________________________________________
Dev mailing list
[hidden email]
http://openlayers.org/mailman/listinfo/dev