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

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

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


服务geojson文件gzip压缩,然后在客户端上解压缩。
将客户端上的shapefile解析为geojson
从shapefile生成我自己的图块并提供这些图块。 ),我将不胜感激!

评论

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

确保GeoJSON的打印效果不是很好,删除所有不必要的空白将有助于使文件更小-不一定要大很多,但这都有帮助!

#1 楼

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

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

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

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



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



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



评论


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

–迈克·弗兰德(Mike Furlender)
16-10-4在14:50

你是救星!

–Khizar
19年4月29日在10:12

优秀的工具。谢谢!

–DaniM
20年4月11日在8:01

#2 楼

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

如果减少了geojson文件的大小,多少钱了?

如果您确信已完成上述所有操作,则选择的最低目标是



提供geojson文件gzip压缩后,在客户端上解压缩。



所有现代浏览器都自动对gzip压缩数据进行解压缩,因此,设置您的Web服务器以在发送之前打包数据的情况。这通常是相对简单的方法,其中包含许多有关Apache,IIS或Nginx的资料。

我的技巧是先尝试一下,然后进行测试,然后确定延迟/响应/数据大小是否可接受,然后移至其他选项。我也将警惕尝试过早优化,我将寻找确定为什么需要减少数据大小,一旦有困难的理由(和数字)这样做,然后迭代地执行更改并重新测试以查看结果。获得的收获。

#3 楼

我想知道您是否可以利用在此答案中找到的有关谈论如何使用topojson压缩GeoJSON的压缩方法。 =)

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

评论


Leaflet.GeoJSON不会解析弧数据,因此这种方法不起作用

–smcphill
13年2月7日,0:28

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

–加尔文
13年2月16日在19:28

我有一个27mb的geoJson文件。进入mapshaper.org,经过简化(1.0%)和topojson导出后,它变为122kb。之后,将github.com/shramov/leaflet-plugins/blob/master/layer/vector/…中的topoJson Leaflet代码添加到我的应用程序中,然后执行以下操作:new L.TOPOJSON(“ myExported.topojson”)。toGeoJson()。

– StackUnder
18年8月22日在13:34

#4 楼

我同意上面的@Kelso简化几何结构。

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

评论


MessagePack与BSON无关(根据stackoverflow.com/questions/6355497/…,在许多情况下,它实际上要好得多。有关messagepack的详细信息,尤其是geojson,请参见nelsonslog.wordpress.com/2012/06/22/checking -out-msgpack。

–凯尔索(Kelso)
2013年1月14日23:27



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

–om_henners
13年1月15日在4:25

#5 楼

我建议仅创建您自己的传单多边形对象的过程数组。我同意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。向您的JS添加很多字节。就像我说的那样,键名很漂亮且具有描述性...但是它们很长,并且会给您的JS添加很多不必要的标记。

#6 楼

尽管这个问题年代久远,但这可能会对其他人有所帮助。使用GeoJSON在Web项目上进行了大量工作,我经常遇到这个问题。我的解决方案:与GeoJSON相关的文件类型BrokJSON(brokjson.dev)。取决于您的GeoJSON,它可以显着减小大小而不会丢失任何数据。

通过两点和一些数据来查看此GeoJSON:

 {
  "type": "FeatureCollection",
  "features": [
  {
    "type": "Feature",
    "properties": {
      "id": 1,
      "title": "Datapoint 1",
      "value": 343
    },
    "geometry": {
      "type": "Point",
      "coordinates": [8.5402,47.3782]
    }
  },
  {
    "type": "Feature",
    "properties": {
      "id": 1,
      "title": "Datapoint 2",
      "value": 14
    },
    "geometry": {
      "type": "Point",
      "coordinates": [8.5637,47.4504]
    }
  }]
}
 


转换成BrokJSON后看起来像这样:

 {
  "properties": ["id", "title", "value"],
  "geometries": [{
    "type": "Point",
    "features": [
      [[8.5402, 47.3782], [1, "Datapoint 1", 343]],
      [[8.5637, 47.4504], [1, "Datapoint 2", 14]]
    ]
  }
]}
 


我将我的地理数据存储为BrokJSON,并在运行时将其用于MapBox或传单转换为GeoJSON。

更多详细信息:https://www.brokjson.dev

评论


我喜欢避免重复属性键的想法。您还可以查看github.com/mapbox/geobuf,因为它可以使它成为GeoJSON(二进制压缩格式)大小的6到8倍,并且它是无损的。

– ThomasG77
20 Mar 2 '20 at 14:32