Отрисовка уже спроектированной карты geoJSON в d3.js

С v3 d3.js у меня возникают проблемы с рисованием карты с использованием данных geoJSON. Код и полученная карта показаны по адресу: http://bl.ocks.org/73833ec90a8a77b0e29f. Используя v2 из d3.js, этот пример генерирует правильную карту.

  1. Мои данные уже спроектированы (это координаты Голландской национальной сети / Рейксдрихэкстелсель). Чтобы компенсировать это, я написал свою собственную функцию проекции, которая просто переводит систему координат карты в пиксели (например, масштабирование и перевод).
  2. d3.geo.path () в v3 d3.js выполняет повторную выборку данных. Однако точки, сгенерированные при повторной выборке, похоже, не находятся в той же системе координат, что и моя карта (я предполагаю, что это координаты lon, lat).

Я бы предпочел не переводить координаты моей карты в координаты долготы, широты, поскольку карта уже спроецирована так, как я хотел бы, и, насколько я могу судить, это нетривиальная проекция.

Если проблемы действительно вызваны повторной выборкой, я бы хотел отключить повторную выборку. Однако в документации я не нашел толком, как это сделать. Вместо передачи функции проекции в d3.geo.path.projection () я мог бы передать объект потоковой передачи. Я думал, что сработает следующее:

var projection = d3.geo.projection(function(x, y) {
    return [ scale*(x-xmin), height-scale*(y-ymin) ];
  }).precision(0);

но это не так. Вероятно, также связано с тем, что у меня нет координат широты и долготы. Как отключить повторную выборку с помощью настраиваемой функции проекции?

Или когда что-то еще вызывает проблемы, я бы хотел это услышать.

Спасибо.


person Jan van der Laan    schedule 01.02.2013    source источник


Ответы (2)


Недавно я столкнулся с той же проблемой.

Для этого нужно явно сказать d3, что вам не нужна проекция. Ответ находится в этой ссылке.

"If projection is null, the path uses the identity transformation, where the input 
geometry is not projected and is instead rendered directly in raw coordinates. This can be 
useful for fast rendering of already-projected geometry, or for fast rendering of the 
equirectangular projection."

Итак, вы хотите иметь

var path = d3.geo.path().projection(null);

А потом что-то вроде этого

g.selectAll("path")
            .data(json.features)
            .enter().append("path")
            .attr("d", path)
person Laurent Sigal    schedule 04.04.2013
comment
Спасибо. Я видел это, но проблема, с которой я столкнулся, заключалась в том, что мне нужно масштабировать и переводить мою карту (исходные координаты даны в метрах от какой-то точки где-то в Северном море). Возможно, будет работать проекция NULL и методы scale и translate. Я дам вам знать, если это сработает. - person Jan van der Laan; 05.04.2013
comment
Я не мог заставить ваше решение работать. Однако я нашел другое решение. - person Jan van der Laan; 08.04.2013

В ответ на ответ user603124 я еще раз посмотрел на проблему (до сих пор я придерживался v2 d3.js). Моя первоначальная идея создания объекта работает. Однако в моей первоначальной реализации у меня было неправильное масштабирование и масштабирование. Используя ответ на другой вопрос, чтобы получить масштабирование и масштабирование вправо:

<script>
  var height = 400;
  var width  = 400;

  var vis = d3.select("#vis").append("svg")
      .attr("width", width).attr("height", height)

  d3.json("po_2012_simplified.json", function(json) {

      var projection = d3.geo.projection(function(x, y) { return [x, y];})
        .precision(0).scale(1).translate([0, 0]);

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

      var bounds = path.bounds(json),
          scale  = .95 / Math.max((bounds[1][0] - bounds[0][0]) / width, 
                  (bounds[1][1] - bounds[0][1]) / height),
          transl = [(width - scale * (bounds[1][0] + bounds[0][0])) / 2, 
                  (height - scale * (bounds[1][1] + bounds[0][1])) / 2];

      projection.scale(scale).translate(transl);

      vis.selectAll("path").data(json.features).enter().append("path")
        .attr("d", path)
        .style("fill", "#D0D0D0")
        .style("stroke-width", "0.5px")
        .style("stroke", "black")
    });

</script>

См. http://bl.ocks.org/djvanderlaan/5336035 для получения полного рабочего решения.

person Jan van der Laan    schedule 08.04.2013
comment
Это действительно здорово! Мне нравится ваше решение с d3.geo.projection(function(x, y) { return [x, y];}). Мне непонятно, почему все хотят, чтобы все их конечные пользователи (зрители) воспроизводили данные на лету. Я вижу, что на 99% карт перепроектирование на лету совершенно бесполезно и является пустой тратой вычислительной мощности. - person Rutger Kassies; 31.05.2013
comment
Проекция d3.geo.projection предназначена для преобразования сферических координат в декартовы координаты. Если вы хотите масштабировать и переводить только в декартовых координатах, я рекомендую использовать d3.geo .transform, как в bl.ocks.org/5663666. - person mbostock; 10.05.2014