动态投影单个县

时间:2017-01-22 17:09:23

标签: javascript d3.js topojson

这是一个简单但鼓舞人心的单一状态的topojson:

https://bl.ocks.org/mbostock/7061976

它由来自仅包含该状态的json的数据绘制,如下所示:

d3.json("va-counties.json", function(error, topo) {
  if (error) throw error;

我想做的是动态投影一个县。假设存在键盘事件或运行函数的事情:读入解析的数据,找到县id,并返回仅该县的topojson功能。上面的块与我的情况之间的区别在于我的json文件将拥有美国的所有县,但我一次只需要一个县。有没有办法在D3中实现这一目标?

就像一个简单的试金石,对于县id = 1000,我试过:

  var current_county = topojson.feature(topo, topo.objects.counties).filter(function(d) { return d.id=1000;})),
      bounds = path.bounds(county);

然而,无论我多么努力,我都会遇到持续的错误。或者它会停止抛出错误,但仍然没有工作'。也许.filter()不是这项工作的最佳工具?还有什么其他意见?

感谢您阅读

1 个答案:

答案 0 :(得分:4)

首先,您的filter语法错误,我认为您的意思是比较而不是作业:

d.id === 1000

其次,topojson.feature返回一个对象中的GeoJSON,它不会像那样过滤。你最好的选择是在途中过滤它:

// filter the geometries of the topojson the structure you want
var geoCounty = topo.objects.counties.geometries.filter(function(d){
  return d.id === "51750";
});

// assign it back to the topojson object
topo.objects.counties.geometries = geoCounty;

// and off you go...
var county = topojson.feature(topo, topo.objects.counties),
    bounds = path.bounds(county);

完整运行代码:

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.county {
  fill: #ccc;
}

</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>

var width = 500,
    height = 300;

var projection = d3.geo.conicConformal()
    .parallels([38 + 02 / 60, 39 + 12 / 60])
    .rotate([78 + 30 / 60, 0])
    .scale(200000)
    .translate([0, 0]);

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

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

d3.json("https://jsonblob.com/api/ce96ca06-e1ce-11e6-90ab-03e5986c4e20", function(error, topo) {
  if (error) throw error;

  var geoCounty = topo.objects.counties.geometries.filter(function(d){
    return d.id === "51750";
  });

  topo.objects.counties.geometries = geoCounty;

  var county = topojson.feature(topo, topo.objects.counties),
      bounds = path.bounds(county);

  projection
      .translate([width / 2 - (bounds[0][0] + bounds[1][0]) / 2, height / 2 - (bounds[0][1] + bounds[1][1]) / 2]);

  svg.append("path")
      .datum(county)
      .attr("class", "county")
      .attr("d", path);

});

</script>