[Github]shapefile转json——对Github上shp2json项目的修改

一. 前言

大二开始正式学编程,这条路走得磕磕绊绊,基本上想写点东西时,都会先在Github上看有没有现成的......

在一开始还不会配环境的时候,最痛苦的就是Github上拉下来能直接就用的代码寥寥无几。

后面又渐渐尝试,接触了maven,pip以及npm,开始在Github上搬运代码了。

又因为专业和GIS相关,GIS又是个冷门的方向,往往搜索结果惨淡。

有时候想做个功能,这时候就只能找到别人类似的代码,在他人基础上修改了,这里的坑也是数不胜数......

下面介绍一个冷门的Github项目,该项目的地址

https://github.com/substack/shp2json

二. 修改

当初是想实现一个将shapefile文件转为json的功能,

其实在Github上类似功能的代码还算多。

但是,在那么多的代码里,限于能力窘迫,当时我能运行的也就那么一两个,再从中间挑一个评分高的,那就选中shp2json了。

在运行完shp2json,发现json数据能正确显示在控制台里。

那么呵呵呵,怎么把控制台的所谓的“流”变成json字符串呢?

当时各种搜索,各种关键词都一无所获,

最后走投无路时只能打开源码。

其实我连源码怎么看都不知道,

但还好,所以就挑了个最长最大的index.js开始瞎几把改。

最后,就莫名其妙的成功了。

呵呵呵~算是新手第一关通过了。

下面是代码修改:

原来的index.js

 1 function fromShpFile (file, outStream) {
 2     outStream = outStream || duplex.obj();
 3     var shp = gdal.open(file);
 4     var layerCount = shp.layers.count();
 5 
 6     var before = '{"type": "FeatureCollection","features": [\n';
 7     var after = '\n]}\n';
 8     var started = false;
 9     var currentLayer, currentFeature, currentTransformation;
10     var nextLayer = 0;
11 
12     var to = gdal.SpatialReference.fromEPSG(4326);
13 
14     function getNextLayer() {
15       currentLayer = shp.layers.get(nextLayer++);
16       var srs = currentLayer.srs || gdal.SpatialReference.fromEPSG(4326);
17       currentTransformation = new gdal.CoordinateTransformation(srs, to);
18     }
19 
20     getNextLayer();
21 
22     var layerStream = from(function(size, next) {
23       var out = '';
24       writeNextFeature();
25 
26       function writeNextFeature() {
27           var feature = currentLayer.features.next();
28           if (!feature) {
29               // end stream
30               if (nextLayer === layerCount) {
31                   // push remaining output and end
32                   layerStream.push(out);
33                   layerStream.push(after);
34                   return layerStream.push(null);
35               }
36               getNextLayer();
37               feature = currentLayer.features.next();
38           }
39 
40           try {
41               var geom = feature.getGeometry();
42           } catch (e) {
43               return writeNextFeature();
44           }
45 
46           geom.transform(currentTransformation);
47           var geojson = geom.toJSON();
48           var fields = feature.fields.toJSON();
49           var featStr = '{"type": "Feature", "properties": ' + fields + ',"geometry": ' + geojson + '}';
50 
51           if (started) {
52               featStr = ',\n' + featStr;
53           } else {
54               featStr = before + featStr;
55           }
56 
57           started = true;
58           out += featStr;
59 
60           if (out.length >= size) {
61               next(null, out);
62           } else {
63               writeNextFeature();
64           }
65       }
66 
67     })
68 
69     outStream.setReadable(layerStream);
70     outStream.end(after);
71 
72     return outStream;
73 }
View Code

 

修改之后的代码:

 1 function fromShpFile (file, outStream) {
 2     var out = '';
 3     outStream = outStream || duplex.obj();
 4     var shp = gdal.open(file);
 5     var layerCount = shp.layers.count();
 6     
 7     var countLimit = 0;//要素读取数量限制
 8     
 9     var before = '{"type": "FeatureCollection","features": [\n';
10     var after = '\n]}\n';
11     var started = false;
12     var currentLayer, currentFeature, currentTransformation;
13     var nextLayer = 0;
14 
15     var to = gdal.SpatialReference.fromEPSG(4326);
16 
17     function getNextLayer() {
18       currentLayer = shp.layers.get(nextLayer++);
19       var srs = currentLayer.srs || gdal.SpatialReference.fromEPSG(4326);
20       currentTransformation = new gdal.CoordinateTransformation(srs, to);
21     }
22 
23     getNextLayer();
24 
25     var layerStream = from(function(size, next) {
26       writeNextFeature();
27 
28       function writeNextFeature() {
29           var feature = currentLayer.features.next();
30           if (!feature) {
31               // end stream
32               if (nextLayer === layerCount) {
33                   // push remaining output and end
34                   layerStream.push(out);
35                   layerStream.push(after);
36                   return layerStream.push(null);
37               }
38               getNextLayer();
39               feature = currentLayer.features.next();
40           }
41 
42           try {
43               var geom = feature.getGeometry();
44           } catch (e) {
45               return writeNextFeature();
46           }
47 
48           geom.transform(currentTransformation);
49           var geojson = geom.toJSON();
50           var fields = feature.fields.toJSON();
51           var featStr = '{"type": "Feature", "properties": ' + fields + ',"geometry": ' + geojson + '}';
52 
53           if (started) {
54               featStr = ',\n' + featStr;
55           } else {
56               featStr = before + featStr;
57           }
58 
59           started = true;
60           out += featStr;
61 
62          countLimit++;  //要素读取数量
63                   
64          if(countLimit < 8000)
65             writeNextFeature();  //这个方法报错,栈溢出
66 
67       }
68 
69     })
70 
71     outStream.setReadable(layerStream);
72     outStream.end(after);
73 
74     return (out += after) ;  
75 }
View Code

三. 问题

这个包转化的速率并不理想,甚至很慢......

而且当要素数量过大时,会报栈溢出,这应该和机器的内存有关......

......

 [作者: 阿泫] https://www.cnblogs.com/KissXuan/

posted @ 2018-10-23 21:11  阿泫  阅读(962)  评论(0)    收藏  举报