【问题标题】:Create a curved border around a d3 map projection围绕 d3 地图投影创建弯曲边框
【发布时间】:2019-02-24 21:16:00
【问题描述】:

我使用here 所示的 geoNaturalEarth1() 在 d3 中创建了一张世界地图。我使用带有此投影的 geojson 世界地图来获取地图,如下面的代码所示。然而,这表明这些国家漂浮在没有边界的太空中。我想在地图投影周围画一个边框,让它看起来更像一张地图。边界将是平坦的顶部/底部、弯曲的侧面,如投影图像中所示。这可能吗?我该怎么做?

var projection = d3.geoNaturalEarth1()
    .translate([w/2, h/2])
    .scale(247)
    .center([0,0]);

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

d3.json('map.geojson').then(function(world) {

    svg.selectAll(".emissions_path")
        .data(world.features)
        .enter().append("path")
        .attr('fill', '#fff')
        .attr("d", path)
        .style('stroke', 'black')
        .style('stroke-width', '0.5px');

【问题讨论】:

    标签: javascript d3.js maps


    【解决方案1】:

    您可以将Sphere 类型的geojson 提供给路径生成器:

    还支持 Sphere 类型,这对于渲染 地球的轮廓;球体没有坐标。 (docs)

    这看起来像:

    var outline = {type:"Sphere"}
    

    并且可以直接传递给路径生成器:

    var context = d3.select("canvas").node().getContext("2d"),
        projection = d3.geoNaturalEarth1()
          .scale(70)
          .translate([200,100])
        path = d3.geoPath()
          .context(context)
          .projection(projection);
    
    d3.json("https://unpkg.com/world-atlas@1/world/110m.json", function(error, world) {
      if (error) throw error;
    
      context.beginPath();
      context.fillStyle = "lightgreen";
      path(topojson.feature(world, world.objects.land));
      context.fill();
      
      context.beginPath();
      context.strokeStyle = "#ccc";
      path({type: "Sphere"})
      context.stroke();
      
    });
    <canvas width="500" height="300"></canvas>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script src="https://unpkg.com/topojson-client@3"></script>

    顺便说一句,还有d3.geoGraticule,它允许定期绘制经线和纬线:

    var context = d3.select("canvas").node().getContext("2d"),
            projection = d3.geoNaturalEarth1()
              .scale(70)
              .translate([200,100])
            path = d3.geoPath()
              .context(context)
              .projection(projection);
    
        d3.json("https://unpkg.com/world-atlas@1/world/110m.json", function(error, world) {
          if (error) throw error;
    
          context.beginPath();
          context.fillStyle = "lightgreen";
          path(topojson.feature(world, world.objects.land));
          context.fill();
      
          context.beginPath();
          context.strokeStyle = "#eee";
          path(d3.geoGraticule10())
          context.stroke();
          
          context.beginPath();
          context.strokeStyle = "#000";
          path({type:"Sphere"})
          context.stroke();        
          
        });
    <canvas width="500" height="300"></canvas>
        <script src="https://d3js.org/d3.v4.min.js"></script>
        <script src="https://unpkg.com/topojson-client@3"></script>

    【讨论】:

      【解决方案2】:

      Andrew Reid的代码翻译成SVG而不是canvas,代码如下

      var projection = d3.geoNaturalEarth1()
        .translate([w / 2, h / 2])
        .scale(247);
      
      var path = d3.geoPath().projection(projection);
      
      svg.enter("path")
        .datum({type: "Sphere"})
        .attr("d", path)
        .style("fill", "none")
        .style("stroke", "black")
        .style("stroke-width", 3);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-03-19
        • 2012-08-14
        • 2017-08-11
        • 1970-01-01
        • 2015-12-07
        • 1970-01-01
        • 2013-05-23
        • 2018-10-28
        相关资源
        最近更新 更多