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

Я пытаюсь использовать 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) или отдельный путь (топология .features[0]). Однако я пробовал использовать все три, и ни один из них не работал и не отображал ошибку в консоли.

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

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


person David Moneysmith    schedule 10.11.2017    source источник


Ответы (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 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)

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

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


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

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

person Andrew Reid    schedule 10.11.2017