在容器中拟合地图的问题

时间:2018-03-31 22:01:58

标签: javascript d3.js

在上一个问题中,用户告诉我一个很好的功能,可以使地图居中并使其大小适应容器。

" nrabinowitz有一个很好的gist,它提供了一个缩放和平移投影以适合给定方框的功能。 它遍历每个地理数据点(数据参数),投影它(投影参数),并逐步更新必要的比例和平移以适应容器中的所有点(框参数),同时最大化比例:

function fitProjection(projection, data, box, center) {
     ...
     return projection.scale(scale).translate([transX, transY])
}

我喜欢这个功能但是现在我不介意使用能解决我问题的东西。这适用于任何地图,但专门针对哥伦比亚的地图,它对我不起作用。

我试图将地图居中放置到容器中,使其适合中心,尺寸是容器的正确尺寸。但我不能让它适应。我也尝试过.translate,它对我不起作用。有什么不对吗?

enter image description here

这是我的代码:

  function fitProjection(projection, data, box, center) {
      // get the bounding box for the data - might be more efficient approaches
      var left = Infinity,
          bottom = -Infinity,
          right = -Infinity,
          top = Infinity;
      // reset projection
      projection
          .scale(1)
          .translate([0, 0]);
      data.features.forEach(function(feature) {
          d3.geo.bounds(feature).forEach(function(coords) {
              coords = projection(coords);
              var x = coords[0],
                  y = coords[1];
              if (x < left) left = x;
              if (x > right) right = x;
              if (y > bottom) bottom = y;
              if (y < top) top = y;
          });
      });
      // project the bounding box, find aspect ratio
      function width(bb) {
          return (bb[1][0] - bb[0][0])
      }
      function height(bb) {
          return (bb[1][1] - bb[0][1]);
      }
      function aspect(bb) {
          return width(bb) / height(bb);
      }
      var startbox = [[left, top],  [right, bottom]],
          a1 = aspect(startbox),
          a2 = aspect(box),
          widthDetermined = a1 > a2,
          scale = widthDetermined ?
              // scale determined by width
              width(box) / width(startbox) :
              // scale determined by height
              height(box) / height(startbox),
          // set x translation
          transX = box[0][0] - startbox[0][0] * scale,
          // set y translation
          transY = box[0][1] - startbox[0][1] * scale;
      // center if requested
      if (center) {
          if (widthDetermined) {
              transY = transY - (transY + startbox[1][1] * scale - box[1][1])/2;
          } else {
              transX = transX - (transX + startbox[1][0] * scale - box[1][0])/2;
          }
      }
      return projection.scale(scale).translate([transX, transY])
  }

  var width = document.getElementById('statesvg').offsetWidth;
  var height =document.getElementById('statesvg').offsetHeight;     

  /*// Define path generator
  var path = d3.geo.path()               // path generator that will convert GeoJSON to SVG paths
             .projection(projection);  // tell path generator to use albersUsa projection
        */
  //remove svg
   d3.select("#statesvg svg").remove();
  var svg = d3.select("#statesvg")
            .append("svg")
            .attr("width", width+"px")
            .attr("height", height+"px");

   d3.json("https://rawgit.com/john-guerra/43c7656821069d00dcbc/raw/be6a6e239cd5b5b803c6e7c2ec405b793a9064dd/Colombia.geo.json", function(data) {
   var features = data.features;
   var projection=fitProjection(d3.geo.mercator(), data, [[0, 0],  [width, height]], true)
   var path = d3.geo.path()
    .projection(projection);        
        svg.selectAll('path')
        .data(features)
        .enter().append('path')
        .classed('map-layer', true)
        .attr('d', path)
        .attr('vector-effect', 'non-scaling-stroke')


  });

http://plnkr.co/edit/JWL6L7NnhOpwkJeTfO6h?p=preview

1 个答案:

答案 0 :(得分:2)

你说的功能......

  

适用于任何地图,但专门针对哥伦比亚的地图,它对我不起作用。

这没有任何意义:是什么让你觉得这个功能与哥伦比亚有个人问题?

问题在于左上角的那些岛屿Archipelago of San Andrés, Providencia and Santa Catalina。让我们删除它们:

data.features = data.features.filter(function(d){
    return d.properties.DPTO !== "88"
});

以下是我的浏览器中的结果:

enter image description here

以下是您更新的Plunker:http://plnkr.co/edit/1G0xY7CCCoJv070pdcx4?p=preview