Add KML importer as a vector source.
authorTom Hughes <tom@compton.nu>
Tue, 23 Nov 2010 11:40:10 +0000 (11:40 +0000)
committerTom Hughes <tom@compton.nu>
Tue, 23 Nov 2010 11:40:10 +0000 (11:40 +0000)
net/systemeD/potlatch2/VectorSourceDialog.mxml
net/systemeD/potlatch2/utils/KmlImporter.as [new file with mode: 0644]

index ef00a4e..1e8b244 100644 (file)
@@ -41,6 +41,7 @@
                <mx:HBox>
                        <mx:RadioButtonGroup id="filetype" />
                        <mx:RadioButton width="100%" groupName="filetype" value="gpx" id="gpx" label="GPX" selected="true" />
+                       <mx:RadioButton width="100%" groupName="filetype" value="kml" id="kml" label="KML" />
                        <mx:RadioButton width="100%" groupName="filetype" value="osm" id="osm" label="OSM" />
                        <mx:RadioButton width="100%" groupName="filetype" value="shp" id="shp" label="Shapefile" />
                        <mx:CheckBox width="100%" label="Simplify paths" selected="true" id="simplify" />
@@ -59,6 +60,7 @@
        import net.systemeD.halcyon.VectorLayer;
        import net.systemeD.potlatch2.utils.Importer;
        import net.systemeD.potlatch2.utils.GpxImporter;
+       import net.systemeD.potlatch2.utils.KmlImporter;
        import net.systemeD.potlatch2.utils.ShpImporter;
        import net.systemeD.potlatch2.utils.OsmImporter;
     import mx.managers.PopUpManager;
 
                if (type=='gpx') {
                        var gpx:GpxImporter=new GpxImporter(vectorlayer, vectorlayer.paint, [url], filesLoaded, simplify);
+               } else if (type=='kml') {
+                       var kml:KmlImporter=new KmlImporter(vectorlayer, vectorlayer.paint, [url], filesLoaded, simplify);
                } else if (type=='osm') {
                        var osm:OsmImporter=new OsmImporter(vectorlayer, vectorlayer.paint, [url], filesLoaded, simplify);
                } else {
diff --git a/net/systemeD/potlatch2/utils/KmlImporter.as b/net/systemeD/potlatch2/utils/KmlImporter.as
new file mode 100644 (file)
index 0000000..ab4b2a5
--- /dev/null
@@ -0,0 +1,111 @@
+package net.systemeD.potlatch2.utils {
+
+    import net.systemeD.halcyon.MapPaint;
+    import net.systemeD.halcyon.Globals;
+    import net.systemeD.halcyon.connection.Node;
+    import net.systemeD.halcyon.connection.Way;
+    import net.systemeD.halcyon.connection.Relation;
+    import net.systemeD.halcyon.connection.RelationMember;
+    import net.systemeD.potlatch2.tools.Simplify;
+
+    /**
+     * Implements parsing and loading of KML files.
+     */
+    public class KmlImporter extends Importer {
+
+        public function KmlImporter(container:*, paint:MapPaint, filenames:Array, callback:Function=null, simplify:Boolean=false) {
+            super(container, paint, filenames, callback, simplify);
+        }
+
+        override protected function doImport(): void {
+            var kml:XML = new XML(files[0]);
+
+            for each (var ns:Namespace in kml.namespaceDeclarations()) {
+                if
+                (ns.uri.match(/^http:\/\/earth\.google\.com\/kml\/[0-9]+\.[0-9]+$/) ||
+                 ns.uri.match(/^http:\/\/www\.opengis\.net\/kml\/[0-9]+\.[0-9]+$/)) {
+                    default xml namespace = ns;
+                }
+            }
+
+            for each (var placemark:XML in kml..Placemark) {
+                var tags:Object = {};
+
+                if (placemark.name.length() > 0) {
+                    tags["name"] = placemark.name;
+                }
+
+                if (placemark.description.length() > 0) {
+                    tags["description"] = placemark.description;
+                }
+
+                for each (var point:XML in placemark.Point) {
+                    importNode(point.coordinates, tags);
+                }
+
+                for each (var linestring:XML in placemark.LineString) {
+                    importWay(linestring.coordinates, tags);
+                }
+
+                for each (var linearring:XML in placemark.LinearRing) {
+                    importWay(linearring.coordinates, tags);
+                }
+
+                for each (var polygon:XML in placemark.Polygon) {
+                    if (polygon.innerBoundaryIs.length() > 0) {
+                        var members:Array = [];
+                        var way:Way;
+
+                        way = importWay(polygon.outerBoundaryIs.LinearRing.coordinates, {});
+                        members.push(new RelationMember(way, "outer"));
+
+                        for each (var inner:XML in polygon.innerBoundaryIs) {
+                            way = importWay(inner.LinearRing.coordinates, {});
+                            members.push(new RelationMember(way, "inner"));
+                        }
+
+                        tags["type"] = "multipolygon";
+
+                        container.createRelation(tags, members);
+                    } else {
+                        importWay(polygon.outerBoundaryIs.LinearRing.coordinates, tags);
+                    }
+                }
+            }
+        }
+
+        private function importNode(coordinates:String, tags:Object): Node {
+            var coords:Array = coordinates.split(",");
+            var lon:Number = coords[0];
+            var lat:Number = coords[1];
+            //var ele:Number = coords[2];
+
+            var node:Node = container.createNode(tags, lat, lon);
+
+            container.registerPOI(node);
+
+            return node;
+        }
+
+        private function importWay(coordinates:String, tags:Object): Way {
+            var way:Way;
+            var nodestring:Array = [];
+
+            for each (var tuple:String in coordinates.split(" ")) {
+                var coords:Array = tuple.split(",");
+                var lon:Number = coords[0];
+                var lat:Number = coords[1];
+                //var ele:Number = coords[2];
+
+                nodestring.push(container.createNode({}, lat, lon));
+            }
+
+            if (nodestring.length > 0) {
+                way = container.createWay(tags, nodestring);
+                if (simplify) { Simplify.simplify(way, paint.map, false); }
+            }
+
+            return way;
+        }
+    }
+}