如何修改Mike Bostock的Zoom to bounding box示例以适配GeoJSON
适配GeoJSON:修改Mike Bostock的「Zoom to bounding box」示例指南
其实把这个示例改成兼容GeoJSON非常简单,核心就是去掉TopoJSON的解析步骤,直接用原生GeoJSON数据来处理,具体改法如下:
1. 移除TopoJSON依赖
首先,你可以删掉原示例中引入的topojson.min.js脚本,因为现在不需要处理TopoJSON格式了。
2. 修改数据加载与要素绑定
原示例里用topojson.feature把TopoJSON转换为GeoJSON格式的代码:
.data(topojson.feature(us, us.objects.states).features)
直接替换成你提到的GeoJSON集合的features数组:
.data(collection.features)
当然,加载数据的时候也要对应改成加载你的GeoJSON文件,比如:
d3.json("your-geojson-data.geojson").then(function(collection) { // 这里写绑定数据、绘制要素的逻辑 });
(如果是d3v4及之前版本,用d3.json("url", function(error, collection) { ... })的回调写法)
3. 保留缩放逻辑(无需修改)
原示例中基于要素边界计算缩放的代码完全可以复用!因为d3.geoBounds()函数本身就支持GeoJSON要素,不管你传的是TopoJSON转换来的要素还是原生GeoJSON要素,它都能正确计算出地理边界。比如这段代码:
var bounds = d3.geoBounds(d), dx = bounds[1][0] - bounds[0][0], dy = bounds[1][1] - bounds[0][1], x = (bounds[0][0] + bounds[1][0]) / 2, y = (bounds[0][1] + bounds[1][1]) / 2, scale = Math.min(1000, Math.min(width / dx, height / dy));
直接保留就行,不需要做任何改动。
4. (可选)处理边界线(如果原示例有)
如果原示例用了topojson.mesh来生成州/区域的共享边界,你可以换成d3.geoMesh()(d3v5及以上版本支持),它可以直接从GeoJSON集合中提取共享边界:
var mesh = d3.geoMesh(collection);
然后用这个mesh来绘制边界线就可以了。
这样改完之后,整个脚本就能完美兼容GeoJSON数据啦,核心就是跳过TopoJSON到GeoJSON的转换步骤,直接使用原生GeoJSON的结构。
内容的提问来源于stack exchange,提问作者Noobster
相关产品推荐
相关产品推荐

