topojson / D3 / 经度+纬度地图

topojson / D3 / Map with longitude + latitude

本文关键字:纬度 地图 经度 D3 topojson      更新时间:2023-09-26

Im 使用下面的英国地理 JSON 来渲染英国 SVG 地图http://martinjc.github.io/UK-GeoJSON/json/eng/topo_eer.json

在这张地图上,我希望能够将经度+纬度点绘制在地图上。

我通过以下方式将几何集合地点添加到地图:

 data.objects.places = {
        type: "GeometryCollection",
        geometries: [
            {
                type: "Point",
                coordinates: [-0.127758, 51.507351], // London
                properties: {
                    name: "London - Testing"
                }
            }
        ]
    };

但是,坐标不在正确的位置。

下面是完整的JavaScript。

var width = 960;
var height = 1000;
var projection = d3.geo.albers()
        .center([0, 55.4])
        .rotate([4.4, 0])
        .parallels([50, 60])
        .scale(4000)
        .translate([width / 2, height / 2]);
var path = d3.geo.path().projection(projection);
var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);
d3.json("topo_eer.json", function(error, data) {
    // Create path for the UK
    svg.selectAll(".subunit")
            .data(topojson.feature(data, data.objects.eer).features)
            .enter().append("path")
            .attr("class", function(d) { return "subunit " + d.id; })
            .attr("d", path);
    // Path around regions
    svg.append("path")
            .datum(topojson.mesh(data, data.objects.eer, function(a, b) { return a !== b; }))
            .attr("d", path)
            .attr("class", "subunit-boundary");
    // Add places to our data
    data.objects.places = {
        type: "GeometryCollection",
        geometries: [
            {
                type: "Point",
                coordinates: [-0.127758, 51.507351], // London
                properties: {
                    name: "London - Testing"
                }
            }
        ]
    };
    // try plotting a point
    svg.append("path")
            .datum(topojson.feature(data, data.objects.places))
            .attr("d", path)
            .attr("class", "place-online");
    console.log(data);
});

在 TopoJSON 中,coordinates中的那些数字不是实际的纬度/经度值。他们必须被改造。此函数将量化拓扑转换为绝对坐标:

function transformPoint(topology, position) {
    position = position.slice();
    position[0] = position[0] * topology.transform.scale[0] 
    + topology.transform.translate[0],
    position[1] = position[1] * topology.transform.scale[1] 
    + topology.transform.translate[1]
    return position;
};

您将在链接的 TopoJSON 末尾找到scaletranslate

"transform":
    {"scale":
        [0.000818229038834542,0.0005946917122888551],
    "translate":[-6.418556211736409,49.8647494628352]
    }

基于该函数,我相信很容易编写一个执行相反操作的函数:

function transformPointReversed(topology, position) {
    position = position.slice();
    position[0] = (position[0] - topology.transform.translate[0])
    /(topology.transform.scale[0]),
    position[1] = (position[1] - topology.transform.translate[1])
    /(topology.transform.scale[1]) 
    return position;
};
我尝试了我

刚刚制作的这个函数,你的伦敦坐标向我返回了这个数组:

[7688.309645789168, 2762.1059840278253]

请在您的coordinates中测试它,看看它是否有效。

另一种方法是用GeoJSON覆盖您的TopoJSON,它确实使用绝对坐标系。

以下是 API 参考:https://github.com/mbostock/topojson-specification/blob/master/README.md#22-geometry-objects