javascript - d3.js - D3 map 未与中国城市数据集一起显示

标签 javascript json d3.js

我正在为中国一个叫深圳的城市制定路线图。我从 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]);
    

    我得到了这张图片:

    enter image description here

    这是一个gist/block (我没有使用queue.js,而是使用了d3.json),使用你的数据集。对于 d3 来说,该数据集非常大 - 可能值得研究一下矢量切片(或栅格切片)。

    关于javascript - d3.js - D3 map 未与中国城市数据集一起显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44534862/

    相关文章:

    javascript - 有人可以解释一下这个删除数组中重复值的函数是如何工作的吗?

    javascript - 使用 jQuery 删除列表项

    javascript - D3 树布局 - 具有子节点的子节点之间的距离

    javascript - d3.js 热图图例

    javascript - 如何通过按散点图中的更新按钮来更改(过渡)每个圆的半径?

    javascript - 如何将 datetimepicker js 包装到 AngularJS 指令中

    python 3, window 7 :ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host

    java - 当JsonArray嵌套到另一个JsonArray时如何使用Retrofit2进行反序列化

    javascript - 在 React Native 中将 JSON 数据传递到下一页

    javascript - 如何获取正在触摸特定 Sprite 的目标