<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Hello,<br>
<br>
Here's what I did so far... Reading KML only work for KML 2.0
namespaces for write() uses <tt><small>OpenLayers.Ajax.getElementsByTagNameNS()</small></tt>,
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.....?<br>
<br>
Cheers,<br>
Damien<br>
<br>
<br>
<tt><small>--8<-------------------------------------</small></tt><tt><small>---------------------------</small></tt><tt><small>---------------------<br>
<br>
</small></tt><tt><small>Index:
/home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js<br>
===================================================================<br>
---
/home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js
(revision 3900)<br>
+++
/home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js
(working copy)<br>
@@ -8,8 +8,8 @@<br>
* @requires OpenLayers/Ajax.js<br>
* <br>
* Class: OpenLayers.Format.KML<br>
- * Read only KML. Largely Proof of Concept: does not support advanced
Features,<br>
- * including Polygons. Create a new instance with the <br>
+ * Read/write KML 2.0. Does not support advanced Features.<br>
+ * Create a new instance with the <br>
* <OpenLayers.Format.KML> constructor.<br>
*<br>
* Inherits from:<br>
@@ -100,6 +100,19 @@<br>
// TBD Bounds only set for one of multiple geometries<br>
geom.extendBounds(p.bounds);<br>
}<br>
+<br>
+ // match Polygon <br>
+ } else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,<br>
+ this.kmlns, "", "Polygon").length != 0) {<br>
+ var polygon =
OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,<br>
+ this.kmlns, "", "Polygon")[0];<br>
+ p = this.parseCoords(polygon);<br>
+ if (p.points) {<br>
+ var linearRing = new
OpenLayers.Geometry.LinearRing(p.points);<br>
+ geom = new OpenLayers.Geometry.Polygon(linearRing);<br>
+ // TBD Bounds only set for one of multiple geometries<br>
+ geom.extendBounds(p.bounds);<br>
+ }<br>
}<br>
<br>
feature.geometry = geom;<br>
@@ -190,6 +203,136 @@<br>
}<br>
return p;<br>
},<br>
+ <br>
+ /**<br>
+ * Accept Feature Collection, and return a string. <br>
+ * <br>
+ * @param {Array} List of features to serialize into a string.<br>
+ */<br>
+ write: function(features) {<br>
+ var kml =
document.createElementNS(<a class="moz-txt-link-rfc2396E"
href="http://earth.google.com/kml/2.0">"http://earth.google.com/kml/2.0"</a>,
"kml:kml");
// 'kml:' NS to be removed?<br>
+ for (var i=0; i < features.length; i++) {<br>
+ kml.appendChild(this.createPlacemarkXML(features[i]));<br>
+ }<br>
+ return kml;<br>
+ },<br>
+<br>
+ /** <br>
+ * Accept an OpenLayers.Feature.Vector, and build a geometry for
it.<br>
+ * <br>
+ * @param OpenLayers.Feature.Vector feature<br>
+ * @return DOMElement<br>
+ */<br>
+ createPlacemarkXML: function(feature) {<br>
+ // Placemark name<br>
+ var placemarkName = document.createElementNS(this.kmlns,
"kml:" + "name");<br>
+ var placemarkNameText = document.createTextNode(feature.id); <br>
+ placemarkName.appendChild(placemarkNameText);<br>
+<br>
+ // Placemark description<br>
+ var placemarkDesc = document.createElementNS(this.kmlns,
"kml:" + "description");<br>
+ var placemarkDescText = document.createTextNode("Not
available"); <br>
+ placemarkDesc.appendChild(placemarkDescText);<br>
+ <br>
+ // Placemark<br>
+ var placemarkNode = document.createElementNS(this.kmlns,
"kml:" + "Placemark");<br>
+ placemarkNode.appendChild(placemarkName);<br>
+ placemarkNode.appendChild(placemarkDesc);<br>
+<br>
+ // Geometry node (Point, LineString, etc. nodes)<br>
+ var geometryNode = this.buildGeometryNode(feature.geometry);<br>
+ placemarkNode.appendChild(geometryNode); <br>
+ <br>
+ return placemarkNode;<br>
+ }, <br>
+<br>
+ /** <br>
+ * builds a KML geometry node with a given geometry<br>
+ * <br>
+ * @param {OpenLayers.Geometry} geometry<br>
+ */<br>
+ buildGeometryNode: function(geometry) {<br>
+ // TBD test if geoserver can be given a Multi-geometry for a
simple-geometry data store<br>
+ // ie if multipolygon can be sent for a polygon feature type<br>
+ var kml = "";<br>
+ // match MultiPolygon or Polygon<br>
+ if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon"<br>
+ || geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {<br>
+ kml = document.createElementNS(this.kmlns,
'kml:Polygon');<br>
+ <br>
+ var polygon = document.createElementNS(this.kmlns,
'kml:Polygon');<br>
+ var outerRing = document.createElementNS(this.kmlns,
'kml:outerBoundaryIs');<br>
+ var linearRing = document.createElementNS(this.kmlns,
'kml:LinearRing');<br>
+ <br>
+ // TBD manage polygons with holes<br>
+
linearRing.appendChild(this.buildCoordinatesNode(geometry.components[0]));<br>
+ outerRing.appendChild(linearRing);<br>
+ polygon.appendChild(outerRing);<br>
+ <br>
+ kml.appendChild(polygon);<br>
+ }<br>
+ // match MultiLineString or LineString<br>
+ else if (geometry.CLASS_NAME ==
"OpenLayers.Geometry.MultiLineString"<br>
+ || geometry.CLASS_NAME ==
"OpenLayers.Geometry.LineString") {<br>
+ kml = document.createElementNS(this.kmlns,
'kml:LineString');<br>
+ <br>
+ var lineString =
document.createElementNS(this.kmlns, 'kml:LineString');<br>
+ <br>
+
lineString.appendChild(this.buildCoordinatesNode(geometry));<br>
+ <br>
+ kml.appendChild(lineString);<br>
+ }<br>
+ // match MultiPoint or Point<br>
+ else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point" ||
<br>
+ geometry.CLASS_NAME ==
"OpenLayers.Geometry.MultiPoint") { <br>
+ kml = document.createElementNS(this.kmlns,
'kml:Point');<br>
+<br>
+ // FIXME: There should be only one Point node per
Placemark node<br>
+ var parts = "";<br>
+ if (geometry.CLASS_NAME ==
"OpenLayers.Geometry.MultiPoint") {<br>
+ parts = geometry.components;<br>
+ } else {<br>
+ parts = [geometry];<br>
+ } <br>
+ <br>
+ for (var i = 0; i < parts.length; i++) {<br>
+ var point = document.createElementNS(this.kmlns,
'kml:Point');<br>
+
point.appendChild(this.buildCoordinatesNode(parts[i]));<br>
+ kml.appendChild(point);<br>
+ } <br>
+ }<br>
+ return kml; <br>
+ },<br>
+ <br>
+ /**<br>
+ * builds the coordinates XmlNode<br>
+ * <kml:coordinates>...</kml:coordinates><br>
+ *<br>
+ * @param {OpenLayers.Geometry} geometry<br>
+ * @return {XmlNode} created xmlNode<br>
+ */<br>
+ buildCoordinatesNode: function(geometry) {<br>
+ var coordinatesNode = document.createElementNS(this.kmlns,
"kml:coordinates");<br>
+ <br>
+ var points = null;<br>
+ if (geometry.components) {<br>
+ points = geometry.components;<br>
+ }<br>
+<br>
+ var path = "";<br>
+ if (points) {<br>
+ for (var i = 0; i < points.length; i++) {<br>
+ path += points[i].x + "," + points[i].y + " ";<br>
+ }<br>
+ } else {<br>
+ path += geometry.x + "," + geometry.y + " ";<br>
+ } <br>
+ <br>
+ var txtNode = document.createTextNode(path);<br>
+ coordinatesNode.appendChild(txtNode);<br>
+ <br>
+ return coordinatesNode;<br>
+ }, <br>
<br>
CLASS_NAME: "OpenLayers.Format.KML" <br>
}); <br>
</small></tt><br>
<br>
<br>
<br>
Christopher Schmidt wrote:
<blockquote cite="mid20070814152052.GA22295@metacarta.com" type="cite">
<pre wrap="">On Tue, Aug 14, 2007 at 04:16:32PM +0200, Damien Corpataux wrote:
</pre>
<blockquote type="cite">
<pre wrap="">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? :-)
</pre>
</blockquote>
<pre wrap=""><!---->
Just laziness.
</pre>
<blockquote type="cite">
<pre wrap="">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?
</pre>
</blockquote>
<pre wrap=""><!---->
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,
</pre>
</blockquote>
<br>
<br>
<div class="moz-signature">-- <br>
<style>
<!--
.signature {
font-family:verdana,helvetica,sans-serif;
font-size:0.8em;
line-height: 1.25em;
color: #9999BB;
width: 27em;
}
.signature div {
padding: 0.22em;
margin-bottom: 0.5em;
margin-top: 0.5em;
border-bottom: 1px dotted lightgray;
background-color: #FCFCFF;
}
.signature .attention {
background-color: #FFFAFA;
color: #FFBBBB;
font-size: 0.8em;
font-weight: bold;
}
.header {
}
-->
</style>
<div class="signature">
<div> <span style="font-weight: bold;">Camptocamp SA</span><br>
Damien Corpataux<br>
PSE A<br>
CH-1015 Lausanne<br>
</div>
<div> +41 21 619 10 22 <span class="header">(Direct)</span><br>
+41 21 619 10 10 <span class="header">(Centrale)</span><br>
+41 21 619 10 00 <span class="header">(Fax)</span><br>
</div>
<div style="color: rgb(102, 204, 102);"> <span
style="position: relative; top: -3px; font-family: Webdings; font-size: 24pt;">P</span>
<span style="">Please consider the environment <br>
Do you really need to print this email?</span>
</div>
</div>
</div>
</body>
</html>