1

我正在尝试使用 D3 显示旧金山的 GeoJSON 地图。我使用“http-server -c-1”提供以下文件:

索引.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(...)。

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

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

你对我可能做错了什么或我应该寻求什么途径来调试这个有什么建议吗?

4

1 回答 1

0

两个问题:

  1. 应用投影

你设置一个投影

  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. 翻译你的投影

d3 投影的默认平移通常为 [480,250],它将中心坐标放置在 960 x 500 像素的 svg 中间。你的 svg 是 500 x 500,所以你应该使用:

projection.translate([250,250])  

关于您对 geojson 对象的问题。geojson 对象可以是特征集合(topology代码中的变量)或特征集合的特征集合中的特定特征/形状:topology.features[0],但它不能是数组,例如topology.features. 它必须是一个有效的单个 geojson 对象,有关有效 geojson 对象的更多信息,请参阅关于 geojson的更多信息。

如果将 geojson 对象(例如特征集合)传递给 fitSize,您的代码可能如下所示:

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

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

如果使用(而不是使用 fitSize)指定中心坐标.center([long,lat]),那么您需要按照上面的数字 2 指定平移。


最后一点:

Geojson 不编码拓扑,topojson 格式记录了特征的拓扑。当被 topojson.js 处理时,topojson 被转换为 geojson。作为变量名,topology 的使用意味着使用 topojson 而不是 geojson。

于 2017-11-10T18:33:32.637 回答