D3.js无法显示GeoJSON数据的问题排查
问题诊断与修复方案
嘿,我帮你找出问题所在啦!你的代码没法渲染出地图,主要是两个核心问题:
- 数据源格式搞错啦:你加载的
Ukraine.json其实是TopoJSON格式,但你直接把它当成GeoJSON来用了!TopoJSON结构里没有features这个属性,必须先转换成GeoJSON格式,才能被d3.geoPath正确处理。 - 投影参数不太合适:原有的投影缩放比例太小,而且中心位置没对准乌克兰的区域,可能导致地图跑到SVG可视范围外面去了。
具体怎么改?看这两步:
- 把TopoJSON转成GeoJSON
你已经引入了topojson.v1.min.js,但没用到关键的转换方法。TopoJSON里的地理数据存在objects属性下,你需要用topojson.feature()把它转成GeoJSON:
// 转换TopoJSON为GeoJSON格式 var geojson = topojson.feature(json, json.objects.Ukraine);
之后用转换好的geojson.features来绑定数据就对了。
- 调整投影参数让地图显示正常
原来的scale(400)太小,地图会缩得看不见,我把缩放比例调到了2500,同时把投影中心对准乌克兰的大致经纬度(31,49),这样地图就能正好显示在你的SVG容器里了。
修复后的完整代码:
<!DOCTYPE html> <meta charset="utf-8"> <head> <title>geoPath measures</title> </head> <body> <div align="center"> <svg id="my_dataviz" width="400" height="560"></svg> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.1/d3.min.js"></script> <script src="//d3js.org/topojson.v1.min.js"></script> <script> var svg = d3.select('#my_dataviz'); // 调整投影参数适配乌克兰地图 var projection = d3.geoMercator() .scale(2500) // 放大缩放比例,让地图填满容器 .center([31, 49]) // 对准乌克兰的中心经纬度 .translate([200, 280]); // 对应SVG的中心位置 var geoGenerator = d3.geoPath().projection(projection); // 请求数据并渲染 d3.json( 'https://raw.githubusercontent.com/EugeneBorshch/ukraine_geojson/master/Ukraine.json', function(err, json) { // 关键步骤:转换TopoJSON为GeoJSON var geojson = topojson.feature(json, json.objects.Ukraine); svg.append("g") .selectAll("path") .data(geojson.features) .enter() .append('path') .attr('d', geoGenerator) .attr('fill', 'steelblue') .attr('stroke', '#fff') // 添加白色描边,让区域边界更清晰 .attr('stroke-width', 0.5); } ); </script> </body> </html>
为啥控制台没报错?
因为TopoJSON文件加载成功了,但你用json.features会得到undefined,D3处理空数据的时候不会创建任何元素,所以页面是空的,但不会抛出错误,这才让问题有点隐蔽~
内容的提问来源于stack exchange,提问作者evgenyorlov1
相关产品推荐
相关产品推荐

