How can I use SVG translate to center a d3.js projection to given latitude and longitude values?

六月ゝ 毕业季﹏ 提交于 2019-11-29 23:56:02

问题


I am using d3 to render a Mercator projection of a GeoJSON world map.

I would like to be able to use d3 to scale, and translate the map to known latitude and longitude values as the user steps through my application.

projection.center (https://github.com/mbostock/d3/wiki/Geo-Projections#wiki-center) does what I'd like, combined with transition().duration(), but this requires redrawing the map and therefore seems expensive to keep repeating. I would like to use the native translate() and scale() methods that come with SVG (https://developer.mozilla.org/en-US/docs/SVG/Attribute/transform).

I've found a few helpful examples, like Mike Bostock's (http://bl.ocks.org/mbostock/4699541), and useful questions, like the following about centering a map to a given GeoJSON object (Center a map in d3 given a geoJSON object), but I am struggling to wrap my head around them.

Please could someone help me center my projection to given latitude and longitude values using SVG's transform="translate(x, y)"?

Many thanks in advance.


Edit @Lars: First of all, thank you. I have tried your suggestion, and movement occurs, but the projection appears to move too far. I have included a screenshot and my projection code, below:

var SFMap = {
    initialise: function() {
        var width = "752";
        var height = "420";
        SFMap.projection = d3.geo.mercator()
            .scale(100)
            .translate([width/2, height/2])
            .center([0, 0]);

        SFMap.path = d3.geo.path()
            .projection(SFMap.projection);

        SFMap.svg = d3.select("#sf__map")
            .append("svg")
            .attr("width", width)
            .attr("height", height);

        SFMap.g = SFMap.svg.append("g");

        d3.json("world-110m.topo.json", SFMap.draw);
    },

    draw: function(error, topology) {
        SFMap.g
            .selectAll("path")
            .data(topojson.feature(topology, topology.objects.countries)
                .features)
            .enter()
            .append("path")
            .attr("d", SFMap.path)
            .attr("class", "feature");
    },

(View full size)

The above occurs when translateing to London - 51.5171° N, 0.1062° W - using the following code:

var coordinates = SFMap.projection([0.1062, 51.5171]);
SFMap.g.attr("transform", "translate(" + (-coordinates[0]) + "," + (-coordinates[1]) + ")");

I have also tried inverting the values a second time.


回答1:


Assuming that the center of your projection is (0,0), all you need to do is to give the coordinates of the point you want to center to your projection function (to translate into user coordinates) and give the inverse of that to translate. Something like

var coordinates = projection(point);
svg.attr("transform", "translate(" + (-coordinates[0]) + "," + (-coordinates[1]) + ")");

If you translated the projection as well, you need to take that into account, e.g.

svg.attr("transform", "translate(" + (-coordinates[0]+width/2) +
         "," + (-coordinates[1]+height/2) + ")");


来源:https://stackoverflow.com/questions/16785881/how-can-i-use-svg-translate-to-center-a-d3-js-projection-to-given-latitude-and-l

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!