【发布时间】:2014-04-05 03:06:00
【问题描述】:
我正在寻找一些指导,了解如何根据来自 (geo/topo)JSON 的等高线数据创建由路径组成的 SVG 图像,并使用 d3.js 进行渲染。
这是我想要创建的图像:
最终,我希望图像能够响应式缩放、动画(绘制线条、交互式更改颜色)路径,并能够交换不同的数据文件以呈现其他图像。
我已经浏览了几个指南、教程等,但到目前为止我似乎遗漏了一些步骤或实施了错误的程序,所以我想我会在这里问。感谢您的帮助。
我正在尝试澄清执行此操作的最佳方法,并找出我在 d3.js 中的功能/程序方面的误解。
我通过在 QGIS 中提取等高线来从 DEM(数字高程模型)数据创建等高线。为了从中获取 JSON,我尝试在 QGIS 中保存为 GeoJSON,并在 OGR2OGR 中将 Shapefile (ESRI .shp) 转换为 GeoJSON。我也尝试过使用 Node 的 Topojson (https://www.npmjs.org/package/topojson)。在大多数情况下,我已经能够获取 JSON 文件,尽管我转换它们的方式可能有问题,或者来自 QGIS 的原始轮廓数据使其与我在 d3 中尝试过的不兼容.
当 JSON 被渲染时,我得到的结果基本上看起来像黑盒子(看起来像渲染不正确的多边形在 svg 容器内变得狂野)。如果我将填充颜色更改为无,我会看到到处都是疯狂的线条。我在某处读到,TopoJSON 必须是多边形而不是线或折线,因为它使用弧线,但我使用 GeoJSON 得到了相同的结果。
我想知道这是否与我从 QGIS 导出轮廓线并转换为 JSON 的方式有关,也许投影没有对齐?转换时自动创建的行中也可能存在一些错误,但我不确定如何修复这些错误。正如您在示例图像中看到的那样,我的一些轮廓不是闭环,因为它们超出了我有数据用于/想要显示的区域的边界。这些应该被渲染为折线或路径是否有意义?
另外请注意,我对这些线路的“地理空间性”并不特别感兴趣,因为它们在这个项目中的经纬度或地理位置。基本上只是使用来自真实地理数据的等高线来显示线型。
这是我的代码:
<script type="text/javascript">
var width = 500,
height = 500;
var svg = d3.select("#section-1-svg").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("contour.json", function(error, contour) {
console.log(contour);
});
var path = d3.geo.path()
.projection(d3.geo.mercator());
d3.json("contour.json", function(error, json) {
svg.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", path);
});
</script>
所以除了让这个在基本层面上呈现之外,其他问题是: 我可以选择单独的线条来制作动画,例如 stroke-dashoffset 吗? 此源 JSON 是否仍包含高程数据,以便我可以根据高程为线条着色?
感谢您帮助我走上正轨!我会很感激有人为我澄清这一点并告知我呈现它的最佳方式。
编辑:使用 user1614080 示例中的代码,我正在渲染这些行:
svg.selectAll("path")
.data(topo).enter()
.append("path")
.style("fill", "none")
.style("stroke", function(d, i) {
return interp(cScale(d.properties.ELEV));
})
.attr("d", path)
.each(function(d) {
d.totalLength = this.getTotalLength();
console.log(d.totalLength);
})
.attr("stroke-dasharray", function(d) { return d.totalLength + " " + d.totalLength;})
.attr("stroke-dashoffset", function(d) { return d.totalLength; })
.transition()
.delay(function(d, i) { return i * 200; })
.duration(4000)
.ease("linear")
.attr("stroke-dashoffset", "0");
});
但我无法获得我需要的效果(画线)。它们似乎从小破折号淡入,而不是绘制整个破折号。我可以在浏览器中看到 stroke-dasharray 和 offset 被正确分配,只是无法弄清楚为什么不尊重过渡。
【问题讨论】:
-
如果没有看到完整的示例,我真的不知道发生了什么,但this vis I made a while ago 可能会对您有所帮助。我使用了基本相同的工作流程——DEM 通过 QGIS 到 GeoJSON,然后使用 D3 加载和处理。
标签: json svg d3.js geojson topojson