D3为SVG添加了GeoJSON路径但没有任何显示

时间:2017-11-10 13:53:45

标签: d3.js svg geojson d3.geo

我正在尝试使用D3来显示旧金山的GeoJSON地图。我有以下文件,我正在使用" http-server -c-1":

的index.html:

<!DOCTYPE html>
<html>
  <head>
    <script src="http://d3js.org/d3.v4.min.js"></script>
  </head>
  <body>
    <script src="./d3Map.js"></script>
  </body>
</html>

d3Map.js:

const d3 = window.d3;

// Append a svg to the HTML body and set its height and width:
const svg = d3.select('body')
  .append('svg')
    .attr('height', 500)
    .attr('width', 500)
// Append the <g> element which is used for grouping SVGs:
const g = svg.append('g');

// Get the GeoJSON data and use it to setup the paths:
d3.json('./sfmaps/neighborhoods.json', (error, topology) => {
  // Setup the projection:
  const bounds = d3.geoBounds(topology);
  const centerX = d3.sum(bounds, (d) => d[0]) / 2;
  const centerY = d3.sum(bounds, (d) => d[1]) / 2;
  const projection = d3.geoMercator()
    .center([centerX, centerY]);

  // Create a geographic path generator and set its projection:
  const path = d3.geoPath()
    .projection(d3.geoMercator());

  g.selectAll('path')
    .data(topology.features)
    .enter()
      .append('path')
      .attr('d', path);
});

当我检查生成的页面时,我有:

<body>
  <svg>
    <g>
      <path d="..."></path>
      <path d="..."></path>
      ...
    </g>
  </svg>
</body

但是,显示的SVG为空白。

我怀疑投影没有正确缩放或居中,因此我尝试省略.center(...),硬编码中心与旧金山的纬度和经度,并使用.fitSize(...)。< / p>

我对文档的术语感到有些困惑。当它说一个值应该是一个GeoJSON对象时,我不确定这是否意味着它应该是整个JSON(我命名为&#34;拓扑&#34;在我的代码中),功能(topology.features) ,或单个路径(topology.features [0])。但是,我尝试使用所有三个,但没有一个在控制台中工作或显示错误。

GeoJSON文件是由其他人制作的,所以我很确定它是正确的。

您对我可能做错了什么或者我应该采取哪些措施进行调试有任何建议吗?

1 个答案:

答案 0 :(得分:0)

两个问题:

  1. 应用投影
  2. 您设置了投影

      const projection = d3.geoMercator()
        .center([centerX, centerY]);
    

    但是你不要使用它:

      const path = d3.geoPath()
        .projection(d3.geoMercator()); // applies default mercator
    

    尝试:

      const path = d3.geoPath()
        .projection(projection);  // applies mercator with modified parameters
    
    1. 翻译您的预测
    2. d3投影的默认平移通常为[480,250],它将居中坐标放在svg的中间,即960像素乘500像素。你的svg是500 x 500,所以你应该使用:

      projection.translate([250,250])  
      

      关于geojson对象的问题。 geojson对象可以是要素集合(代码中的topology变量),也可以是要素集合中的特定要素/形状:topology.features[0],但它不能是数组,比如topology.features。它必须是一个有效的单个geojson对象,有关有效geojson对象的更多信息,请参阅More than you ever wanted to know about geojson

      如果将geojson对象(例如要素集合)传递给fitSize,则代码可能如下所示:

      projection = d3.geoMercator()
          .fitSize([width,height],topology)
      

      请注意,这不会更改居中坐标,但会平移和缩放地图要素以适合指定的尺寸。如果使用此方法,则无需指定translate,因为此方法定义了translate本身。

      如果使用.center([long,lat])(而不是使用fitSize)指定中心坐标,则需要指定上面第2个转换。

      最后一点:

      Geojson不对拓扑进行编码,topojson格式记录了要素的拓扑。当由topojson.js处理时,topojson将转换为geojson。作为变量名,拓扑的使用推断使用topojson而不是geojson。