我正在为中国一个叫深圳的城市制定路线图。我从 mapzen.com 获取数据集,并使用 topojson 命令行 (topojson -o -p) 将形状文件转换为 JSON 文件。
这是我的 json 文件:https://raw.githubusercontent.com/MandyZou/Mandy-Web/gh-pages/ShenzhenMap/shenzhenroads.json
这是我的代码:
<!DOCTYPE html>
<head>
<title>Shenzhen Map</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script>
<script src="https://unpkg.com/topojson@3.0.0"></script>
</head>
<body>
<svg id="map" width ="500" height = "960"></svg>
<script>
var margin = {top: 20, left: 20, right: 20, bottom: 20},
width = 500 - margin.left - margin.right,
height = 960 - margin.top - margin.bottom;
var svg = d3.select("#map")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.queue()
.defer(d3.json, "shenzhenroads.json")
.await(ready);
function ready(error, data){
if (error) throw error;
console.log(data)
var ShenzhenRoads = topojson.feature(data, {
type: "GeometryCollection",
geometries: data.objects.shenzhen_china_osm_roads.geometries
});
var projection = d3.geoMercator().center([23, 114]).scale(100).translate([width/2, height/2]);
var path = d3.geoPath()
.projection(projection);
svg.select("g")
.selectAll("path")
.data(ShenzhenRoads.features)
.enter().append("path")
.attr("class", "roads")
.attr("d", path)
.attr("fill", "#C5C5C5");
};
</script>
</body>
</html>
我认为这可能是由于我在这里使用的投影...我尝试了 d3.geoMercator、d3.geoTransverseMercator 和 d3.geoEquirectangular,但它们都不起作用...
谁能告诉我我的 map 有什么问题以及我应该如何修复它?提前致谢!!
最佳答案
您需要解决两个问题才能看到您的功能。
<强>1。 svg.select("g")
未选择任何元素。
定义变量 svg 时使用:
var svg = d3.select("#map")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
这将返回带有 g
元素的选择,而不是 svg
元素。例如尝试:
console.log(svg.node()); // <g transform="translate(20,20)">
相反,只需使用:
svg.selectAll("路径").data(....
<强>2。 .center、.rotate 的坐标以及一般在 d3 中的坐标为 [x,y]。
您需要在此处交换坐标:
var projection = d3.geoMercator().center([23, 114])...
致:
var projection = d3.geoMercator().center([114, 23])...
- topojson.feature 返回 geojson,
您可以简化此语句:
var ShenzhenRoads = topojson.feature(data, {
type: "GeometryCollection",
geometries: data.objects.shenzhen_china_osm_roads.geometries
});
至:
var ShenzhenRoads = topojson.feature(data, data.objects.shenzhen_china_osm_roads);
改进
您的缩放系数太小,您的数据可能仍然不可见(尽管它应该在 DOM 中),200 000 的缩放系数可能更合适。
其次,您正在使用 .attr("fill","color")
作为路径,您可能不想填充路径,因为这会使它们看起来像带有一个多边形的多边形连接第一个点和最后一个点的长直线部分。相反,请尝试:
.attr("fill", "none")
.attr("stroke","steelblue");
使用您的数据和以下投影(诚然放大得太远):
var projection = d3.geoMercator()
.center([114, 22.5])
.scale(500000)
.translate([width/2, height/2]);
我得到了这张图片:
这是一个gist/block (我没有使用queue.js,而是使用了d3.json),使用你的数据集。对于 d3 来说,该数据集非常大 - 可能值得研究一下矢量切片(或栅格切片)。
关于javascript - d3.js - D3 map 未与中国城市数据集一起显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44534862/