leaflet - 去重多边形州/国家共享边界
问题描述
我正在使用 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
我如何确保边界在共享时只有一条线?
解决方案
听起来像是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 文件);但是在数据集上使用拓扑规则的想法是一样的。
推荐阅读
- javascript - Highcharts - 如何在仪表图的两个刻度盘之间显示箭头?
- python - 下拉列表外键 Django
- c++ - 如何在参数模板其他类中使用某些类?
- php - 如何在没有 cron 的情况下每天只运行 10 次 php 文件?
- android - 截屏时未捕获视频部分
- javascript - 我需要一个边框长度可变的圆圈
- javascript - 使用 jquery从 html 元素中获取数据集项
- angular - 在同一个角度项目中使用角度元素
- android - 当焦点在android TV中从一个行移动到另一个行时,有没有办法停止RowsSupportFragment中行的垂直移动?
- bash - 让 git 的 "! [rejected] develop -> develop (non-fast-forward)" 脱颖而出