GeoJSON太庞大-怎么办?


19

我正在使用leaflet.js允许网络用户选择区域。有效区域是美国各州,加拿大的天意和世界国家(美国和加拿大除外)。我自己使用Qgis构造了一个shapefile,并将其保存为geojson。我尽可能地简化了几何形状。

生成的shapefile为400kb,但geojson超过一兆字节。这比我想要的要大。我需要减少传输此信息所涉及的网络开销。

什么是正确的方法?我可以想象的选项是:

  1. 将geojson文件压缩后,在客户端上解压缩。
  2. 将客户端上的shapefile解析为geojson
  3. 从shapefile生成我自己的图块并为这些图块服务

如果有人能告诉我哪个选项是最好的(或以上都不是),我将不胜感激!


我注意到您说过您试图简化几何图形,但是您是否尝试过使用GIS简化算法并检查结果?查看JSON的哪个部分占用最多的空间也可能会有所帮助。
BradHards

1
确保GeoJSON的打印效果不佳,去掉所有不必要的空白将有助于使文件变小-不一定要大很多,但这都可以!
亨德森

Answers:


13

在走更费劲的道路之前,最简单的选择是减小几何形状。您的源数据集是什么?您如何简化它们?这多少减少了geojson文件的大小?

如果您有信心在上述工作上已尽力而为,那么您选择的方案中最低的收获是

  1. 将geojson文件压缩后,在客户端上解压缩。

所有现代的浏览器都会自动解压缩压缩数据,因此这只是将您的Web服务器设置为在发送之前打包数据的一种情况。通常这是一个相对简单的方法,有关ApacheIISNginx的材料很多

我的提示是先尝试进行此测试,然后再进行测试,如果延迟/响应/数据大小不可接受,则转到其他选项。我也会对尝试过早优化保持警惕,希望能确定为什么需要减少数据大小,一旦有困难的理由(和数字),然后迭代实施更改并重新测试以查看结果。获得的收获。


13

Mapshaper.org是一款便捷的免费在线工具,可让您上载geojson文件,将其显示为地图,然后选择三个简化的逻辑符号之一,您可以使用滑块调整其强度。

它会更新地图,并在所有完整性缺失(例如两个区域之间的重叠)的地方以红色突出显示。有一个“修复”按钮通常(但并非总是)修复此类问题。

您可以找到可接受的简化程度,然后导出新简化的geojson文件。

显然,这取决于您需要的详细程度,但是结果可能会令人印象深刻。例如,这是一个40mb geojson文件中的苏格兰地图:

在此处输入图片说明

99%的应用程序将其缩减为441 kb的文件,没有重叠,并且在此缩放级别上看不到细节的丢失:

在此处输入图片说明

99.95%的应用程序(低至29kb)显示了正在简化的路径类型(并且仍然设法避免重叠,并且非常适合于国家级绿皮书使用):

在此处输入图片说明


我一直在使用这个工具。太好了!
Mike Furlender

1
你是救星!
Khizar

6

我想知道您是否可以利用此答案中提到的压缩方法,该方法讨论了使用topojson压缩GeoJSON

我不知道Leaflet是否仍然能够读取GeoJSON-可以尝试=)

有关topojson的更多信息: https : //github.com/mbostock/topojson/


Leaflet.GeoJSON无法解析弧数据,因此该方法将不起作用
smcphill

Leaflet并不是本机的,但是您可以在客户端使用topojson来实现它,例如leaflet上的topojson的示例,尽管该示例碰巧使用d3来呈现它。
加尔文

1
我有一个27mb的geoJson文件。进入mapshaper.org,经过简化(1.0%)和topojson导出后,它变为122kb。所添加topoJson传单代码后从github.com/shramov/leaflet-plugins/blob/master/layer/vector/...到我的应用程序,并做了以下内容:新L.TOPOJSON(“myExported.topojson”)toGeoJson()。
StackUnder

3

我同意上面的@Kelso简化几何形状。

如果您无权使用gzip轻松访问服务器来压缩数据,则可以看一下MessagePack库,将您的geoJSON序列化为二进制数据(我相信这是BSON规范的实现,MongoDB等用于存储数据,但我可能错了)。您可以使用Pythonjavascript(以及其他)库对数据进行序列化/反序列化。


2
MessagePack与BSON无关(根据stackoverflow.com/questions/6355497/…,它在许多情况下实际上要好得多。有关messagepack特别是geojson的更多有趣信息,请参见nelsonslog.wordpress.com/2012/06/22/checking退房手续,msgpack
凯尔索

感谢@Kelso-更新了答案。还有好文章!
om_henners 2013年

1

我建议只创建自己的传单多边形对象的过程数组。我同意GeoJSON太大。对象键名非常具有描述性,但也可能不必要地长。我做这种事情:

objects = [];
objects.push( new L.polygon([[1,1],[1,2],[3,4]],options );
objects.push( new L.polygon([[4,7],[8,27],[35,66]],options );
objects.push( new L.polygon([[3,5],[56,24],[13,49]],options );
objects.push( new L.polygon([[13,7],[7,68],[23,9]],options );
layerGroup = L.layerGroup(objects).addTo(map);

很简单。这样比GeoJSON轻巧得多:

{ "type": "FeatureCollection",
  "features": [
    { "type": "Feature",
      "geometry": {"type": "Polygon",
      "coordinates": [1,1],[1,2],[3,4]},
      },

    //etc...

并对每个多边形重复...呃... imo太way肿了。向您的JS添加很多字节。就像我说的那样,键名很漂亮且具有描述性……但是它们很长,会给您的JS添加很多不必要的标记。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.