D3 добавляет пути GeoJSON в SVG, но ничего не отображается

Я пытаюсь использовать 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(...).

Я немного смущен терминологией документации. Когда он говорит, что значение должно быть объектом GeoJSON, я не уверен, означает ли это, что это должен быть весь JSON (то, что я назвал "топологией" в моем коде), функции (topology.features) или отдельный путь (топология)..features[0]). Тем не менее, я пытался использовать все три, и ни один из них не работал или отображал ошибку в консоли.

Файл GeoJSON был создан кем-то другим, поэтому я уверен, что он правильный.

Есть ли у вас какие-либо предложения по поводу того, что я могу делать неправильно или какие пути я должен использовать для устранения этого?

1 ответ

Два вопроса:

  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], который помещает координату центрирования в середину SVG, которая составляет 960 пикселей на 500 пикселей. Ваш svg 500 х 500, поэтому вы должны использовать:

projection.translate([250,250])  

Что касается вашего вопроса об объектах геойсон. Объект Geojson может быть либо коллекцией объектов (topology переменная в вашем коде) или конкретный объект / форма в наборе функций набора объектов: topology.features[0], но это не может быть массив, как topology.features, Это просто должен быть действительный одиночный объект geojson, см. Больше, чем вы когда-либо хотели знать о geojson для получения дополнительной информации о действительных объектах geojson.

При передаче объекта geojson, такого как коллекция объектов, в fitSize, ваш код может выглядеть следующим образом:

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

Обратите внимание, что это не меняет координату центрирования, но переводит и масштабирует элемент карты, чтобы соответствовать указанным размерам. Если вы используете этот метод, вам не нужно указывать перевод, так как этот метод определяет сам перевод.

Если указать координату центра с .center([long,lat]) (и не используя fitSize), тогда вам нужно будет указать перевод, как в пункте 2 выше.


Последнее замечание:

Geojson не кодирует топологию, формат topojson записывает топологию объектов. При обработке с помощью topojson.js топойсон преобразуется в геойсон. В качестве имени переменной использование топологии подразумевает использование топойсона, а не геойсона.

Другие вопросы по тегам