Как я могу обрезать гео-проекцию, используя несколько полигонов (для нескольких результирующих окон просмотра) в D3?

TL;DR: Попытка визуализировать несмежную более полную проекцию, но полигоны объектов охватывают несколько "областей просмотра". Как мне избежать этого (вырезать полигоны по краям области просмотра)?

Полная версия: я хотел бы сделать несмежную более полную проекцию (фрагменты, разделенные "пробелом" и не выровненные по традиции) геоданных. Как мне заставить это работать в D3? Пример грубого макета, который я ищу, можно найти здесь.

Я думаю, что я выяснил, как написать саму проекцию, основываясь на чрезвычайно полезной работе Джейсона Дэвиса на http://jasondavies.com/maps/airocean. Поскольку я не хочу непрерывного представления карты, я просто жестко кодирую преобразование гномоники в относительную позицию для каждой грани, а не делаю матричные умножения для общих краев плитки. Тем не менее, объекты, которые пересекают границы листов в настоящее время, визуализируются как один путь SVG, таким образом заставляя их размазываться по всему холсту (соединяя плитки там, где они присутствуют), как в этом простом примере компоновки.

Я заметил, что Джейсон уже разветвил D3 для более полной проекции, добавив d3.geo.projection.clipPolygon для рендеринга непрямоугольной области просмотра. Но даже эта логика, кажется, ограничена одним окном просмотра, охватывающим всю карту. Глядя на реализацию clipPolygon, я не уверен, смогу ли я адаптировать ее для обработки нескольких полигонов за любое разумное время.

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

Любая помощь приветствуется!:)

Проекция "многогранник", которую я использую:

d3.geo.woodcut = function(nodes, face) {
  var r = π / 1.5;

  var baseTransform = [
    Math.cos(r), Math.sin(r), 0,
    -Math.sin(r), Math.cos(r), 0
  ];

  var mesh = [], outline = [];

  for (var i = 0; i < nodes.length; ++i) {
    var node = nodes[i];   
    var ring = node.face.slice();
    ring.push(ring[0]);
    var centroid = d3.geo.centroid({type: "Polygon", coordinates: [ring]});

    // add mesh
    var edges = faceEdges(node.face);
    for (var j = 0; j < edges.length; ++j) {
      // todo: skip some sides for indented triangle
      mesh.push(edges[j].map(function(d) { return d3.geo.interpolate(d, centroid)(ε); }));
    }

    // add to outline
    if (i == 4/*true*/) {
      var tmp = node.face.slice();
      tmp.push(tmp[0]);
      for (var j = 0; j < tmp.length; ++j) {
        outline.push(tmp.map(function(d) { return d3.geo.interpolate(d, centroid)(ε); }));
      }
    }

    node.transform = baseTransform.slice();
    node.transform[2] = i * 1.5;
  }

  function forward(λ, φ) {
    var node = face(λ, φ),
        point = node.project([λ * degrees, φ * degrees]),
        t;
    if (t = node.transform) {
      return [
        t[0] * point[0] + t[1] * point[1] + t[2],
        -(t[3] * point[0] + t[4] * point[1] + t[5])
      ];
    }
    point[1] = -point[1];
    return point;
  }

  var projection = d3.geo.projection(forward)/*.clipPolygon(outline)*/;
  projection.mesh = mesh;

  return projection;
}

0 ответов

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