Merge branch 'master' of github.com:systemed/potlatch2
[potlatch2.git] / net / systemeD / potlatch2 / utils / KmlImporter.as
1 package net.systemeD.potlatch2.utils {
2
3     import net.systemeD.halcyon.Map;
4     import net.systemeD.halcyon.connection.*;
5     import net.systemeD.potlatch2.tools.Simplify;
6
7     /**
8      * Implements parsing and loading of KML files.
9      */
10     public class KmlImporter extends Importer {
11
12         public function KmlImporter(connection:Connection, map:Map, callback:Function=null, simplify:Boolean=false, options:Object=null) {
13             super(connection, map, callback, simplify, options);
14         }
15
16         override protected function doImport(): void {
17             var action:CompositeUndoableAction = new CompositeUndoableAction("Import KML "+connection.name);
18             var kml:XML = new XML(files[0]);
19
20             for each (var ns:Namespace in kml.namespaceDeclarations()) {
21                 if
22                 (ns.uri.match(/^http:\/\/earth\.google\.com\/kml\/[0-9]+\.[0-9]+$/) ||
23                  ns.uri.match(/^http:\/\/www\.opengis\.net\/kml\/[0-9]+\.[0-9]+$/)) {
24                     default xml namespace = ns;
25                 }
26             }
27
28             for each (var placemark:XML in kml..Placemark) {
29                 var tags:Object = {};
30
31                 if (placemark.name.length() > 0) {
32                     tags["name"] = placemark.name.substr(0,255);
33                 }
34
35                 if (placemark.description.length() > 0) {
36                     tags["description"] = placemark.description.substr(0,255);
37                 }
38
39                 for each (var point:XML in placemark.Point) {
40                     importNode(point.coordinates, tags, action.push);
41                 }
42
43                 for each (var linestring:XML in placemark.LineString) {
44                     importWay(linestring.coordinates, tags, false, action.push);
45                 }
46
47                 for each (var linearring:XML in placemark.LinearRing) {
48                     importWay(linearring.coordinates, tags, true, action.push);
49                 }
50
51                 for each (var polygon:XML in placemark.Polygon) {
52                     if (polygon.innerBoundaryIs.length() > 0) {
53                         var members:Array = [];
54                         var way:Way;
55
56                         way = importWay(polygon.outerBoundaryIs.LinearRing.coordinates, {}, true, action.push);
57                         members.push(new RelationMember(way, "outer"));
58
59                         for each (var inner:XML in polygon.innerBoundaryIs) {
60                             way = importWay(inner.LinearRing.coordinates, {}, true, action.push);
61                             members.push(new RelationMember(way, "inner"));
62                         }
63
64                         tags["type"] = "multipolygon";
65
66                         connection.createRelation(tags, members, action.push);
67                     } else {
68                         importWay(polygon.outerBoundaryIs.LinearRing.coordinates, tags, true, action.push);
69                     }
70                 }
71             }
72             default xml namespace = new Namespace("");
73             action.doAction();
74             finish();
75         }
76
77         private function importNode(coordinates:String, tags:Object, push:Function): Node {
78             var coords:Array = coordinates.split(",");
79             var lon:Number = coords[0];
80             var lat:Number = coords[1];
81             //var ele:Number = coords[2];
82
83             var node:Node = connection.createNode(tags, lat, lon, push);
84
85             connection.registerPOI(node);
86
87             return node;
88         }
89
90         private function importWay(coordinates:String, tags:Object, polygon:Boolean, push:Function): Way {
91             var way:Way;
92             var nodestring:Array = [];
93             var nodemap:Object = [];
94
95             var tuples:Array=coordinates.split(" ");
96             if (tuples[0]==tuples[tuples.length-1]) { polygon=true; }
97             if (polygon) { tuples.splice(-1,1); }
98
99             for each (var tuple:String in tuples) {
100                 var coords:Array = tuple.split(",");
101                 var lon:Number = coords[0];
102                 var lat:Number = coords[1];
103                 //var ele:Number = coords[2];
104
105                 nodestring.push(connection.createNode({}, lat, lon, push));
106             }
107
108             if (polygon) {
109                 nodestring.push(nodestring[0]);
110             }
111
112             if (nodestring.length > 0) {
113                 way = connection.createWay(tags, nodestring, push);
114                 if (simplify) { Simplify.simplify(way, map, false); }
115             }
116
117             return way;
118         }
119     }
120 }