javascript - 如何使用 geoPath 居中和缩放
问题描述
我正在使用 D3 和 topojson 过滤掉一部分美国县。我可以成功过滤出县并将它们绘制到 SVG 元素,但是如何更改地图边界以适应新选择的县?它将地图渲染为好像边界都是美国县,而只有过滤的县。
var width=960,
height=600,
centered;
const svgElement = d3.select(ref.current)
.append("svg")
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", [0,0,width,height]);
var path = d3.geoPath();
d3.json("https://d3js.org/us-10m.v2.json").then((d) => {
d.objects.counties.geometries = d.objects.counties.geometries.filter(function(item) {
return props.data.indexOf(item.id) > -1
})
var counties = topojson.feature(d, d.objects.counties).features;
svgElement.append("g")
.attr("class", "filled-territory")
.selectAll("path")
.data(counties)
.enter()
.append("path")
.attr("d", path)
});
props.data
县 ID 数组在哪里,例如 -
[
"45001",
"45003",
"45007",
"45083",
"45087",
"45091"
]
解决方案
此特定文件使用像素坐标系(它是投影的地理数据),它填充 [0,0] 和 [960,600] 之间的范围。因为它使用这个坐标系,所以我们通常可以使用 d3.geoPath 的默认投影,这是一个将 json 中的坐标视为像素的空投影。然而,geoPath 本身并不能提供一种方法来集中或缩放你的特征。
D3 地理投影带有一个名为 fitSize(也称为 fitExtent 或其他)的方法,该方法采用 geojson对象并设置投影比例并转换属性以使 geojson 对象在指定范围内居中。由于我们已经有了投影数据,我们可以使用 d3.geoIdentity() ,它提供了一些方便的投影方法,例如 fitSize 但不会投影我们的数据,因为它已经被投影了。
为了使用 fitSize 我们可以使用以下内容:
// get a geojson feature collection object:
var geojson = topojson.feature(d, d.objects.counties)
// create a geoidentity "projection" and center the geojson:
var projection = d3.geoIdentity()
.fitSize([width,height],geojson)
// set the path's projection:
path.projection(projection);
// Now access the array of features in the collection for use with .data():
var counties = geojson.features;
看起来像:
var data = [
"45001",
"45003",
"45007",
"45083",
"45087",
"45091"
]
var width=500,
height=500;
const svgElement = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var path = d3.geoPath();
d3.json("https://d3js.org/us-10m.v2.json").then((d) => {
d.objects.counties.geometries = d.objects.counties.geometries.filter(function(item) {
return data.indexOf(item.id) > -1
})
var geojson = topojson.feature(d, d.objects.counties)
var projection = d3.geoIdentity()
.fitSize([width,height],geojson)
path.projection(projection);
var counties = geojson.features;
svgElement.append("g")
.attr("class", "filled-territory")
.selectAll("path")
.data(counties)
.enter()
.append("path")
.attr("d", path)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.2/topojson.min.js
"></script>
推荐阅读
- workflow - activiti 模型图在哪里以及如何存储在 activiti 数据库表中
- python - 根据不同列子集的组合删除具有 NaN 的行
- apache-nifi - 恰好生成 1 个流文件
- vba - VBA - 从 2 张表中比较 2 张表,并在另一张表中获得结果,创建比较表
- php - 在 Imagick 中计算图像方差
- c# - 'where 子句'中的未知列'extent3.id'
- c# - 为 DynamicInput 动态注册 On selected index change 事件
- docker - 如何在 Docker 中的 oozie 中实现 ssh 操作
- ios - IOS TLS 证书对 api 请求无效
- sql - 如何在 BigQuery SQL 中计算完全/重复保留