首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >d3.js svg从(geo/topo)json绘制等高线

d3.js svg从(geo/topo)json绘制等高线
EN

Stack Overflow用户
提问于 2014-04-05 03:06:00
回答 1查看 3.7K关注 0票数 2

我正在寻找一些关于如何创建SVG图像的指导,该图像由来自(geo/topo)JSON的轮廓线数据组成,并使用d3.js呈现。

这是我想要创建的本质上的图像:

最终,我希望该图像能够响应地缩放、动画(绘制线条、交互更改颜色)路径,并能够交换不同的数据文件来呈现其他图像。

我已经看过几个指南、教程等,但我似乎错过了一些步骤或实现了错误的过程,所以我想我会问这里。谢谢你的帮助。

我试图澄清做这件事的最佳方法,并找出我对d3.js中的功能/过程的错误解释。

我正在创建等高线从DEM (数字高程模型)数据通过提取等值线在QGIS。为了从这些中获取JSON,我尝试在QGIS中保存为GeoJSON,并将Shapefiles (ESRI .shp)转换为OGR2OGR中的GeoJSON。我也尝试过使用Node的Topojson (https://www.npmjs.org/package/topojson)。在大多数情况下,我能够获得JSON文件,尽管我转换它们的方式可能有问题,或者来自QGIS的原始轮廓数据使其与我在d3中尝试过的内容不兼容。

我在呈现JSON时得到的结果基本上类似于黑匣子(看起来像在svg容器中疯狂呈现的多边形)。如果我将填充颜色更改为none,我会看到到处都是疯狂的线条。我在某个地方读到,TopoJSON必须是多边形,而不是线条或多边形,因为它使用了弧线,但是我在GeoJSON中得到了同样的结果。

我想知道这是否与我从QGIS导出等高线并转换为JSON的方式有问题,也许投影没有排列好吗?在转换时自动创建的行中也可能有一些错误,但我不知道如何修复这些错误。正如您在示例图像中所看到的,我的一些等高线不是封闭的循环,因为它们超出了我为/想要显示的数据的边界。这些应该以多行或路径的形式呈现,这是否有意义?

另外,我并不特别感兴趣的是,在这个项目中,这些线路的“地理位置”是长的或地理位置的。基本上,只需使用真实地理数据中的等高线来显示线条图案。

这是我的代码:

代码语言:javascript
运行
复制
<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>

因此,除了让这个渲染在一个基本的层次上,其他的问题是:我是否能够选择单独的线条来动画,例如,笔画?这个源JSON是否仍然包含高程数据,这样我就可以根据海拔对线条进行着色了吗?

谢谢你的帮助,让我走上正轨!我希望任何人能为我澄清这一点,并告知我如何才能做到这一点。

编辑:使用Using 1614080的示例中的代码,我呈现的行如下:

代码语言:javascript
运行
复制
    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");
    });

但我无法得到我所需要的效果(线画进去)。他们似乎从小破折号中消失,而不是画出整个破折号。我可以在浏览器中看到笔画和偏移量被正确分配,只是不知道为什么转换不受尊重。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-04-06 01:49:57

根据Lar提到的内容,我看不出您拥有的东西有什么问题(只是您是两个相同的d3.json调用,但这不会给您带来问题)。

您所描述的工作流与我以前所做的大致相同。我能想到的唯一一件事可能会给您带来麻烦(尽管在您介绍的代码中没有),即topojson的默认设置不保留特性属性,您必须使用-p开关。

无论如何,我已经有一段时间不想做一个轮廓例子了,这似乎是一个很好的机会,所以我创建了一个可以看到这里的例子。代码和自述文件中有相当多的解释,所以我希望这能帮助您完成这一过程。

一旦您开始工作,您将能够创建各种交互等等。例如,在我的示例中,您可以使用以下内容突出显示mouseover事件的轮廓:

代码语言:javascript
运行
复制
.on("mouseover", highlight)
.on("mouseout", unhighlight(this, d)

function highlight(x) {
    var s = d3.select(this);
    s.style("stroke", "red");
}

function unhighlight(x,y) {
    var old = y.properties.ELEV;
    var u = d3.select(x);
    u.style("stroke", function(d, i) {
            return interp(cScale(old));
        })
}

希望这能让你

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22876086

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档