Drawing already projected geoJSON map in d3.js

隐身守侯 提交于 2019-12-05 01:32:27

问题


With the v3 of d3.js I am having problems drawing a map using geoJSON data. The code and the resulting map is shown at: http://bl.ocks.org/73833ec90a8a77b0e29f. Using v2 of d3.js this example generates a correct map.

  1. My data is already projected (they are Dutch National Grid/Rijksdriehoekstelsel coordinates). In order to compensate for this I wrote my own projection function that just translates the coordinate system of the map to pixels (e.g. scaling and translation).
  2. d3.geo.path() in v3 of d3.js resamples the data. However, the points generated in the resampling do not seem to be in the same coordinate system as my map (I assume they are lon, lat coordinates).

I would prefer not to translate the coordinates of my map to lon,lat coordinates, since the map is already projected the way I would like, and as far as I can tell this is not a trivial projection.

If the problems are indeed caused by the resampling, I would like to disable the resampling. However, in the documentation I could not really find how to do this. Instead of passing a projection function to d3.geo.path.projection(), I could pass an streaming object. I thought the following would work:

var projection = d3.geo.projection(function(x, y) {
    return [ scale*(x-xmin), height-scale*(y-ymin) ];
  }).precision(0);

but it doesn't. Probably also to do with the fact that I don't have lat,lon coordinates. How can I disable the resampling using a custom projection function?

Or when something else is causing the problems, I would like to hear that to.

Thanks.


回答1:


I ran into the same problem recently.

The way to do that is to explicitly tell d3 that you do not want a projection. The answer is in this link.

"If projection is null, the path uses the identity transformation, where the input 
geometry is not projected and is instead rendered directly in raw coordinates. This can be 
useful for fast rendering of already-projected geometry, or for fast rendering of the 
equirectangular projection."

So you want to have

var path = d3.geo.path().projection(null);

And then, something like this

g.selectAll("path")
            .data(json.features)
            .enter().append("path")
            .attr("d", path)



回答2:


In response to user603124 answer I had another look at the problem (up until now I sticked with v2 of d3.js). My original idea of creating an object works. However, in my original implementation I had the scaling and zooming wrong. Using the answer to another question to get the scaling and zooming right:

<script>
  var height = 400;
  var width  = 400;

  var vis = d3.select("#vis").append("svg")
      .attr("width", width).attr("height", height)

  d3.json("po_2012_simplified.json", function(json) {

      var projection = d3.geo.projection(function(x, y) { return [x, y];})
        .precision(0).scale(1).translate([0, 0]);

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

      var bounds = path.bounds(json),
          scale  = .95 / Math.max((bounds[1][0] - bounds[0][0]) / width, 
                  (bounds[1][1] - bounds[0][1]) / height),
          transl = [(width - scale * (bounds[1][0] + bounds[0][0])) / 2, 
                  (height - scale * (bounds[1][1] + bounds[0][1])) / 2];

      projection.scale(scale).translate(transl);

      vis.selectAll("path").data(json.features).enter().append("path")
        .attr("d", path)
        .style("fill", "#D0D0D0")
        .style("stroke-width", "0.5px")
        .style("stroke", "black")
    });

</script>

See http://bl.ocks.org/djvanderlaan/5336035 for a complete working solution.



来源:https://stackoverflow.com/questions/14646656/drawing-already-projected-geojson-map-in-d3-js

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