首页 > 解决方案 > 去重多边形州/国家共享边界

问题描述

我正在使用 GEOJSON 绘制带有传单的世界地图,并用虚线绘制边界,如下图所示。

在此处输入图像描述

我遇到的问题是,如果两个州共享边界,则两条线不会被两个州共享,而是为不同的状态分别绘制两条线。因此,当缩放足够多的线时,它们看起来很奇怪,因为它们相互重叠。如下图所示。 在此处输入图像描述

var GeoJsonLayer = L.geoJson();
var myStyle = {
                "color": "#fff",
                "weight": 0.8,
                "opacity": 1,
                "fillOpacity": "1",
                "fillColor": "#243E54"
            };
// here data.world contains GEOJson to draw whole map
            if (data.world) {
                GeoJsonLayer.options.className = "geojsonlayerpolygon";
                GeoJsonLayer.on("dblclick", function (ev) {
                    map.fireEvent("dblclick", ev);
                });
                GeoJsonLayer.addData(data.world);
                GeoJsonLayer.setStyle(myStyle);
            }

为了使它成为虚线,我在 CSS 下面使用

.geojsonlayerpolygon{
   stroke-dasharray: 6 4;
 }

我使用的 GEOJson 是 https://jsonblob.com/826f1a94-c1a3-11e9-a004-354d7c27cab2

我如何确保边界在共享时只有一条线?

标签: leafletgeojson

解决方案


听起来像是TopoJSON的工作。从它的自述文件中:

TopoJSON 是对拓扑进行编码的 GeoJSON 的扩展。TopoJSON 文件中的几何不是离散地表示几何,而是从称为弧的共享线段缝合在一起。该技术类似于 Matt Bloch 的 MapShaper 和 Arc/Info 导出格式 .e00。

TopoJSON 消除了冗余,允许相关的几何图形有效地存储在同一个文件中。例如,加利福尼亚州和内华达州之间的共享边界仅表示一次,而不是为两个州重复。单个 TopoJSON 文件可以包含多个不重复的要素集合,例如州和县。或者,TopoJSON 文件可以有效地将多边形(用于填充)和边界(用于笔划)表示为共享相同弧形网格的两个特征集合。

因此,首先加载 topojson 库...

<script src="https://unpkg.com/topojson@3"></script>

...然后为您的 GeoJSON 数据创建一个拓扑对象;请注意,TopoJSON 需要一组 GeoJSON 特征,例如,我将通过以下方式加载包含自然地球国家边界的 GeoJSON FeatureCollectionfetch并创建拓扑:

fetch("ne_110m_admin_0_countries.geojson")
.then(res=>res.json())
.then(json=>{

      var topo = topojson.topology([json]);

      /* ...more stuff here soon */

});

...然后添加一个L.GeoJSON仅填充多边形的图层,设置stroke选项以避免在多边形的轮廓上绘制任何线(请记住,路径样式选项可以传递给 GeoJSON 构造函数)...

var layerFill = L.geoJson(json, { stroke: false }).addTo(map);

...计算拓扑的网格,这将是一个 GeoJSON MultiLineString...

topojson.mesh(topo);

...并创建另一个L.GeoJSON实例来绘制所述 MultiLineString。随心所欲地设置线条样式(包括dashArray),例如...

var layerLines = L.geoJson(topojson.mesh(topo), { 
  fill: false, dashArray:[3, 6], weight: 2 
}).addTo(map);

最终结果(您可以在此处作为工作示例看到)不包含重叠的虚线,正如预期的那样:

国家边界拓扑截图


使用 TopoJSON 是一种可能的方法。还有其他可能的方法(例如,使用不同的工具等预先生成仅具有边界的 MultiLineString GeoJSON 文件);但是在数据集上使用拓扑规则的想法是一样的。


推荐阅读