Merge branch 'master' of github.com:systemed/potlatch2
[potlatch2.git] / net / systemeD / potlatch2 / utils / ShpImporter.as
1 package net.systemeD.potlatch2.utils {
2
3         import org.vanrijkom.shp.*;
4         import org.vanrijkom.dbf.*;
5         import com.gradoservice.proj4as.*;
6         import net.systemeD.halcyon.Map;
7         import net.systemeD.halcyon.connection.*;
8         import net.systemeD.potlatch2.tools.Simplify;
9         import flash.utils.*;
10
11         public class ShpImporter extends Importer {
12
13                 private var projection:String;
14                 
15                 private var timeout:uint;
16                 private var position:uint=0;
17
18                 private var polyArray:Array;
19                 private var shpFile:ByteArray;
20                 private var dbfFile:ByteArray;
21                 private var shp:ShpHeader;
22                 private var dbf:DbfHeader;
23                 private var proj:Proj4as;
24                 private var toProj:ProjProjection;
25                 private var fromProj:ProjProjection;
26
27                 private static var MAX_ITEMS:uint=10000;                // maximum number of shapes to process in each pass
28
29                 public function ShpImporter(connection:Connection, map:Map, callback:Function=null, simplify:Boolean=false, options:Object=null) {
30                         if (options['projection']) this.projection=options['projection'];
31                         super(connection,map,callback,simplify,options);
32                 }
33
34                 override protected function doImport():void {
35                         // we load .shp as files[0], .shx as files[1], .dbf as files[2]
36                         shpFile=getFileByName(/.shp$/); shp=new ShpHeader(shpFile);
37                         dbfFile=getFileByName(/.dbf$/); dbf=new DbfHeader(dbfFile);
38                         if (shp.shapeType!=ShpType.SHAPE_POLYGON && shp.shapeType!=ShpType.SHAPE_POLYLINE) { return; }
39
40                         if (projection) {
41                                 proj=new Proj4as();
42                                 toProj=new ProjProjection('EPSG:4326');
43                                 fromProj=new ProjProjection('EPSG:27700');
44                         }
45
46                         polyArray = ShpTools.readRecords(shpFile);
47                         timeout=setTimeout(runProcess,50);
48                         trace("Begin processing");
49                 }
50                 
51                 private function runProcess():void {
52                         var nodemap:Object={};
53                         var key:String, v:String;
54                         clearTimeout(timeout);
55                         var action:CompositeUndoableAction = new CompositeUndoableAction("Import layer "+connection.name);
56
57                         trace("Starting at position "+position);
58                         for (var i:uint=position; i<Math.min(position+MAX_ITEMS,polyArray.length); i++) {
59                                 // Get attributes and create a tags hash
60                                 // (note that dr.values is a Dictionary)
61                                 var dr:DbfRecord = DbfTools.getRecord(dbfFile, dbf, i);
62                                 var tags:Object={};
63                                 for (key in dr.values) {
64                                         v=dr.values[key];
65                                         while (v.substr(v.length-1,1)==" ") v=v.substr(0,v.length-1);
66                                         while (v.substr(0,1)==" ") v=v.substr(1);
67                                         if (v!='') tags[key.toLowerCase()]=v;
68                                 }
69
70                                 // Do each ring in turn, then each point in the ring
71                                 var way:Way;
72                                 var node:Node;
73                                 var x:Number, y:Number;
74                                 for (var j:int=0; j < polyArray[i].shape.rings.length; j++) {
75                                         var nodestring:Array=[];
76                                         var points:Array = polyArray[i].shape.rings[j];
77                                         if (points!=null) {
78                                                 for (var k:int=0; k < points.length; k++) {
79                                                         var p:ShpPoint = ShpPoint(points[k]);
80                                                         
81                                                         if (projection) {
82                                                                 var r:ProjPoint = new ProjPoint(p.x,p.y,0);
83                                                                 r=proj.transform(fromProj,toProj,r);
84                                                                 x=r.x; y=r.y;
85                                                         } else {
86                                                                 x=p.x; y=p.y;
87                                                         }
88
89                                                         key=x+","+y;
90                                                         if (nodemap[key]) { node=nodemap[key]; }
91                                                         else { node=connection.createNode({}, y, x, action.push); nodemap[key]=node; }
92                                                         nodestring.push(node);
93                                                 }
94                                         }
95                                         if (nodestring.length>0) {
96                                                 way=connection.createWay(tags, nodestring, action.push);
97                                                 if (simplify) { Simplify.simplify(way, map, false); }
98                                         }
99                                 }
100                         }
101
102                         // Set next iteration to run after a short delay
103                         action.doAction();
104                         if (i<polyArray.length) {
105                                 position=i;
106                                 timeout=setTimeout(runProcess,50);
107                         } else {
108                                 trace("Finished");
109                                 finish();
110                         }
111                 }
112         }
113 }