使用D3.js仅渲染topojson地图的一部分

时间:2013-09-16 19:02:21

标签: javascript windows d3.js geojson topojson

我使用D3.js库从US Census shapefile创建地图。我希望创建一个完整的美国地图,这是没有问题的,还有每个州的地图。

我的工作流程使用人口普查数据,ogr2ogr在命令行根据需要进行了更改,然后由shpescape.com转换为topojson或geojson,因为topojson模块的node.js下载错误(请参阅下面的编辑解决方案)对这个特殊的问题)。

我的问题更多的是一个实用的问题而不是其他任何问题 - 当提交此代码时(以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状态"中引发错误。说"不能读取未定义属性类型的行" - 但我也不知道我应该传递给匿名函数,或者mt_topo.objects.states应该引用什么。关于这种GIS的事情没有很好的文档。所有人口普查地图都有"州"特征?将.shp压缩到topojson时会丢失该信息吗?

简单地说,如果d3.json采用(对象,函数(错误,json)),那么实际上看起来像的例子是什么?

编辑: 解决方法和窗口7 IDIOSYNCRASIES -----

大多数教程都告诉你使用node.js中的模块,但是我在Windows7上使用规范的命令行" npm install -g topojson"失败" at contextify"。创作者给我发了一个很好的link来解决这个问题。

这很重要,因为在topojson的命令行中有一个标志,您可以在其中将geojson中的现有要素打包到topojson中的可访问对象中。例如,上面的代码使用"状态"在topojson中 - 除非您使用以下命令,否则这些内容毫无意义且无法访问:

topojson -o us.topojson -- states=us_states.json

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

2 个答案:

答案 0 :(得分: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文件,查看您的功能的名称。希望有所帮助!

答案 1 :(得分:0)

表示地图的GeoJSON文件通常具有一个或多个功能。每个要素可能具有零个或多个属性。通常,属性用于存储场所的元数据(州名,县等)。您可以阅读GeoJSON文件并查看它具有的属性,并使用此属性显示或隐藏功能。

将文件从GeoJSON转换为TopoJSON时,you can preserve or remove the original properties。例如,教程uk.jsonLet's Make a Map文件中的要素和要点具有属性name