Center a map in d3 given a geoJSON object

后端 未结 11 2228
慢半拍i
慢半拍i 2020-11-21 22:55

Currently in d3 if you have a geoJSON object that you are going to draw you have to scale it and translate it in order to get it to the size that one wants and translate it

11条回答
  •  旧时难觅i
    2020-11-21 23:16

    For people who want to adjust verticaly et horizontaly, here is the solution :

      var width  = 300;
      var height = 400;
    
      var vis = d3.select("#vis").append("svg")
          .attr("width", width).attr("height", height)
    
      d3.json("nld.json", function(json) {
          // create a first guess for the projection
          var center = d3.geo.centroid(json)
          var scale  = 150;
          var offset = [width/2, height/2];
          var projection = d3.geo.mercator().scale(scale).center(center)
              .translate(offset);
    
          // create the path
          var path = d3.geo.path().projection(projection);
    
          // using the path determine the bounds of the current map and use 
          // these to determine better values for the scale and translation
          var bounds  = path.bounds(json);
          var hscale  = scale*width  / (bounds[1][0] - bounds[0][0]);
          var vscale  = scale*height / (bounds[1][1] - bounds[0][1]);
          var scale   = (hscale < vscale) ? hscale : vscale;
          var offset  = [width - (bounds[0][0] + bounds[1][0])/2,
                            height - (bounds[0][1] + bounds[1][1])/2];
    
          // new projection
          projection = d3.geo.mercator().center(center)
            .scale(scale).translate(offset);
          path = path.projection(projection);
    
          // adjust projection
          var bounds  = path.bounds(json);
          offset[0] = offset[0] + (width - bounds[1][0] - bounds[0][0]) / 2;
          offset[1] = offset[1] + (height - bounds[1][1] - bounds[0][1]) / 2;
    
          projection = d3.geo.mercator().center(center)
            .scale(scale).translate(offset);
          path = path.projection(projection);
    
          // add a rectangle to see the bound of the svg
          vis.append("rect").attr('width', width).attr('height', height)
            .style('stroke', 'black').style('fill', 'none');
    
          vis.selectAll("path").data(json.features).enter().append("path")
            .attr("d", path)
            .style("fill", "red")
            .style("stroke-width", "1")
            .style("stroke", "black")
        });
    

提交回复
热议问题