使用 D3.js 渲染部分 TopoJSON 地图

7
我正在使用D3.js库从美国人口普查的shapefile创建地图。我想要创建整个美国地图,这不是问题,以及每个州的地图。
我的工作流程使用人口普查数据,在命令行中通过ogr2ogr进行必要的更改,然后通过shpescape.com将其转换为topojson或geojson,由于node.js下载topojson模块时出现错误(请参见下面编辑的解决方案)。
我的问题更多是一个实际问题,而不是其他任何问题——当提供此代码时(基于http://bl.ocks.org/mbostock/4707858模型):
            var width = 640,
                height = 500;

            var projection = d3.geo.albers();

            var path = d3.geo.path()
                .projection(projection);

            var svg = d3.select("body").append("svg")
                .attr("width", width)
                .attr("height", height);

            d3.json("mt_geo.json", function(error, mt_topo) {
                var states = topojson.feature(mt_topo, mt_topo.objects.states),
                    state = states.features.filter(function(d) { return d.id === 34; })[0];
                projection
                    .scale(1)
                    .translate([0,0]);
                var b = path.bounds(state),
                    s = .95 / Math.max ((b[1][0]-b[0][0])/width, (b[1][1]-b[0][1])/height),
                    t = [(width-s*(b[1][0]+b[0][0]))/2, (height-s*(b[1][1]+b[0][1]))/2];
                projection
                    .scale(s)
                    .translate(t);
                svg.append("path")
                    .datum(states)
                    .attr("class", "feature")
                    .attr("d", path);
                svg.append("path")
                    .datum(topojson.mesh(us, us.objects.states,function(a, b) {return a !== b;}))
                    .attr("d", path);
                svg.append("path")
                    .datum(state)
                    .attr("class", "outline")
                    .attr("d", path);

不仅在"var states"行抛出了一个错误,说"无法读取未定义的属性类型",而且我也不知道我应该传递什么给匿名函数,或者mt_topo.objects.states应该指什么。这种GIS方面没有好的文档。所有普查地图都有“州”特征吗?当您将.shp压缩为topojson时,是否会丢失该信息?
简单来说,如果d3.json需要(object, function(error, json)),那么实际上有效的示例是什么样子的?
编辑: 解决方法和Windows 7特异性 -----
大多数教程告诉你使用一个来自node.js的模块,但我在Windows7上,规范的命令行"npm install -g topojson"失败了"在contextify处"。创建者向我发送了一个不错的link 来解决这个问题。
这很重要,因为命令行中有一个标志可以将现有特征打包到geojson中,并将其转换为topojson中可访问的对象。例如,上面的代码在topojson中使用“states”,这是毫无意义且不可访问的,除非您使用以下命令:
topojson -o us.topojson -- states=us_states.json

双连字符和状态之间的空格很重要。然后,您可以通过us.objects.states访问状态,如上面的原始代码所示。

你看过这个教程了吗?属性取决于数据中的内容,也就是完全由用户定义。 - Lars Kotthoff
@LarsKotthoff -- 是的,我已经非常仔细地阅读了教程。我想我已经解决了作用域问题;就像你说的那样,它只是一个占位符。我的原始问题正在变得更加清晰。感谢你的帮助。 - kgilvi3
@kgilvi3:如果你找到了解决方法,请分享答案,我们将很高兴给它点赞。 - Hugolpz
2个回答

1
你非常接近了。在测试代码之前,我发现一个主要问题。你的JSON回调函数的第二个参数是mt_topo,当你定义如下时使用它:

var states = topojson.feature(mt_topo, mt_topo.objects.states)

然而,后来你使用us作为回调对象,可能是因为这是Mike Bostock在你引用的示例中使用的。相反,应该是这样的:
svg.append("path")
 .datum(topojson.mesh(mt_topo, mt_topo.objects.states,function(a, b) {return a !== b;}))
 .attr("d", path);

说到这里,你的问题实际上是关于人口普查地图是否有“州”功能。我猜想,你使用的任何几何图形都没有“州”功能,这就是你出现错误的原因。在使用topojson命令行工具时,要素名称(即data.objects.x)通常是输入文件的名称,所以如果你的文件名为US_Census_2010.shp,你需要将州定义为

var states = topojson.feature(mt_topo, mt_topo.objects.US_Census_2010)

打开你的mt_geo.json文件,查看你的要素名称。希望这可以帮到你!


因为我花了一些时间在这上面,所以我认为把它全部记录下来是值得的: @jczaplew,你绝对是正确的。我将原本在这里的内容添加到答案中作为解决方法。 - kgilvi3

0
一个表示地图的GeoJSON文件通常有一个或多个要素。每个要素可能有零个或多个属性。通常,这些属性用于存储地点的元数据(州名、县等)。您可以读取您的GeoJSON文件并查看它具有哪些属性,并使用这些属性来显示或隐藏要素。
将文件从GeoJSON转换为TopoJSON时,您可以保留或删除原始属性。例如,教程Let's Make a Map中的uk.json文件中的要素和点具有属性name

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接