D3.js 如何在分层地形图中缩放和居中所有项目以适应D3版本4?

D3.js 如何在分层地形图中缩放和居中所有项目以适应D3版本4?,d3.js,topojson,D3.js,Topojson,我已经阅读并使用了Mike Bostock的,这是一种根据D3版本3中geojson文件的边界进行缩放以适应其中一项的通用方法。我也有。该算法的关键部分是: // Calculate bounding box transforms for entire collection var b = path.bounds( geojson ), s = .95 / Math.max((b[1][0] - b[0][0]) / w, (b[1][1] - b[0][1]) / h), t = [(w -

我已经阅读并使用了Mike Bostock的,这是一种根据D3版本3中geojson文件的边界进行缩放以适应其中一项的通用方法。我也有。该算法的关键部分是:

// Calculate bounding box transforms for entire collection
var b = path.bounds( geojson ),
s = .95 / Math.max((b[1][0] - b[0][0]) / w, (b[1][1] - b[0][1]) / h),
t = [(w - s * (b[1][0] + b[0][0])) / 2, (h - s * (b[1][1] + b[0][1])) / 2];

// Update the projection, which initially had .translate([0, 0]) .scale(1); 
projection
  .scale(s)
  .translate(t);
我已经对其进行了粗略的调整,使其能够与d3版本4.0中的新/ammend
d3.geoPath()
function/object一起工作。它似乎在下面的演示中起作用(我正在使用
d3.geoPath().bounds()
,还没有尝试V4看似新的
d3.geobunds()
)。然而,我随后不得不调整它,以便在使用topojson.js(即多个GeoJSON要素集合的边界框)转换的多层topojson文件中跨所有层获得边界框
d3.geoPath().bounds()
似乎只接受一个“层”,而
d3.geobunds()
似乎更受限制;只有一个特点

我也有点担心性能——所有这些似乎都涉及到在可能的许多层中循环使用可能非常多的形状,我觉得在D3 V4中可能有更有效的方法


这里是一个粗略的演示,以一个非常小的简单TopoJSON文件作为起点,该文件应该显示两个岛屿,每个岛屿都有几个子区域(对于一个简单的演示,威尔士和北爱尔兰的非常简化的版本,每个都在不同的层上)。经过一番尝试和错误,我成功地将其缩放并将地图转换为“威尔士式”岛屿的中心,但我不知道如何使其在地形的所有图层上居中并缩放

分层TopoJSON的标准方法似乎是将每一层转换为本质上独立的GeoJSON,那么如何在仍然能够将多个GeoJSON作为独立层处理的情况下获得它们的边界呢

//宽度和高度
var w=300;
var h=200;
//定义地图投影
var projection=d3.GeoEquirectangle()
.translate([0,0])
.比额表(1);
//定义路径生成器
var path=d3.geoPath()
.投影(投影);
//创建SVG元素
var svg=d3.选择(“主体”)
.append(“svg”)
.attr(“宽度”,w)
.attr(“高度”,h);
//加载GeoJSON数据
var json=someUKJSON();
for(json.objects中的var键){
if(json.objects.hasOwnProperty(键)){
//Topojson一次解压一层
var layer=json.objects[key];
var geojson=topojson.feature(json,层);
//计算整个集合的边界框变换
var b=path.bounds(geojson),
s=.95/Math.max((b[1][0]-b[0][0])/w,(b[1][1]-b[0][1])/h),
t=[(w-s*(b[1][0]+b[0][0])/2,(h-s*(b[1][1]+b[0][1])/2];
//更新投影
投影
.比例尺
.翻译(t);
//绑定数据并为每个GeoJSON功能创建一个路径
svg.selectAll(“路径”)
.data(geojson.features)
.输入()
.append(“路径”)
.attr(“d”,路径)
.样式(“填充”、“钢蓝”);
};
//…但每次迭代只会放大/集中在最新的
//如何在每一层中展开边界框?
}
函数someUKJSON(){
返回{“type”:“Topology”,“transform”:{“scale”:[0.0034431267161520807,0.002017902170346754],“translate”:[-7.85085441596444345,51.47680014500252],
“弧”:[[1366700]、-216、-155]、[1150545]、[121275]、[292101]、[45、-221]、[1366700]、[23、-449]、[1389251]、[1312155]、[75、-18]、[1237137]、[1175154]、[35383]、[1140537]、[10,8]、[117515454]、[1105144]、[71、-96]、[1104117]、[317]、[317]、[317]、[317]、[317]、[317]、[317]、[317]、[317]、[317]、[317]、[317]、[317]、[317]、[11],
[[1264,18],[-35,-18]],[[1229,0],[-125,117]],[[1312,155],[28,-118]],[[1340,37],[-76,-19]],[[1385,12],[-45,25]],[[1389,251],[-4,-239]],[[1385,12],[-156,-12]],[[563,1572],[16,-7]],[[579,1565],[-55,-14]],[[524,1551],[39,21]],[[397,1870],[166,-298]],[[524,1551],[-63,-5]],[[461,1546],[-96,-18]],
[[365,1528],[-109,10]],[[256,1538],[35,290]],[[291,1828],[106,42]],[[574,1342],[-124,192]],[[450,1534],[6,4],[5,8]],[[579,1565],[-5,-223]],[[365,1528],[85,6]],[[574,1342],[-219,-72],[-162,148]],[[193,1418],[63,120]],[[0,1515],[291,313]],[[193,1418],[-193,97]]],
“对象”:{“威尔士”:{“类型”:“几何集合”,“几何体”:[{“弧”:[[0,1],“类型”:“多边形”,“id”:“Bedr”},{“弧”:[[2,3,4,5,6,7,-1],“类型”:“多边形”,“id”:“Pong”},{“弧”:[8,9,-7],“类型”:“多边形”,“id”:“Hyda”},{“弧”:[-6,10,11,12,-9],“类型”:“多边形”,“id”:“Abwg”,
{“弧”:[[13,14,-11,-5]],“类型”:“多边形”,“id”:“Cwaf”},{“弧”:[[15,-14,-4,16]],“类型”:“多边形”,“id”:“Anan”},{“弧”:[[17,-12,-15,-16]],“类型”:“多边形”,“id”:“洞穴”},{“类型”:“几何图形”[{“弧”:[18,19,20],“类型”:“多边形”,“id”:“Blft”},
{“弧”:[[21,-21,22,23,24,25,26],“类型”:“多边形”,“id”:“nern”},{“弧”:[[27,28,-23,-20,29],“类型”:“多边形”,“id”:“hern”},{“弧”:[[30,-28,31,32,-25],“类型”:“多边形”,“id”:“sorn”},{“弧”:[33,-26,-33,34],“类型”:“多边形”,“id”:“wern”};
};

这里有一个非常简单的方法。这是我最近的一次尝试。把它留在这里,希望有人能想出更好的办法

  • 创建一个一次性的伪geojson对象,纯粹用于计算边界
  • 将每个要素的要素阵列合并到其中
  • 使用它计算边界并调整投影一次
虽然这感觉很笨重,但我找不到一次绘制一层的方法,我只能使用一次性的展平集合来绘制路径

另外,奇怪的是,
d3.merge()
似乎不适用于
geojson.features
,这就是为什么我使用
Array.concat()
。我不明白这个,但这确实可以做到

//宽度和高度
var w=300;
var h=200;
//定义地图投影
var projection=d3.GeoEquirectangle()
.translate([0,0])
.比额表(1);
//定义路径生成器
var path=d3.geoPath()
.投影(投影);
//创造