Использование D3-Geo для построения фигуры - PullRequest
1 голос
/ 13 июля 2020

Я использую пакет d3-geo для построения точек и форм в пространстве широты и долготы. Я хотел бы построить простой многоугольник, треугольник, квадрат, звезду и т. Д. c с центром в точке. Я бы также, если возможно, хотел бы построить текст в заданном [lat, lon].

В настоящее время у меня работает приведенный ниже код и рисует кольцо по заданным координатам [-40.5, 65.5]. Однако я хотел бы иметь возможность определять различные формы в этом месте, есть ли простой способ сделать это, не определяя форму вручную? Есть пустое поле «Свойства», и я не могу найти документацию, по которой можно было бы использовать? Документация по D3-geo и поиск в Google пока не дали результатов.

let geoGenerator = geoPath()
  .projection(projection)
  .pointRadius(4)
  .context(context); //2d Canvas contect

context.beginPath();
geoGenerator({
  type: "Feature",
  geometry: {
    type: "Point",
    coordinates: [-40.5, 65.5]
  },
  properties: {}
});
context.stroke();

1 Ответ

1 голос
/ 14 июля 2020

Geo json не имеет в своей спецификации какого-либо свойства, определяющего тип символа (форма символа, цвет, размер и т. Д. c), который должен быть нарисован. Geo json указывает только геометрию (точка, линия, многоугольник и т. Д. c) нарисованного объекта в координатах geographi c.

Конечно, вы можете использовать свойство свойства geo json функция для хранения данных символов, она просто не влияет на визуализацию функции, если вы сами не создадите эту функцию.

Хотя geo json не имеет никаких спецификаций для символов, генератор geoPath в D3 позволяет вы указываете одну часть нарисованного символа: радиус точки (в противном случае точки безразмерны). Однако, кроме этого, d3-geo не предлагает никакой поддержки для рисования определенных c символов, он может проецировать только геометрию.

Чтобы нарисовать символ с указанной c географической c координатой , вам нужно спроецировать координату (projection([longitude,latitude])). Теперь у вас есть координата в пикселях, вы можете использовать эту координату для рисования вашего символа. Вы не хотите пытаться нарисовать символ в географических c координатах, поскольку это не масштабируется и зависит от проекции.

Вот простая реализация с d3-символом (я не рисовал остальной мир, всего две точки, но они проецируются правильно):

var context = d3.select("canvas").node().getContext("2d");

var points = [[-136,63],[-123,50]];

var projection = d3.geoMercator();

var shape = d3.symbol()
     .type(d3.symbolWye)
     .context(context)
     .size(200);

var shapey = function(lonlat) {
   // Get xy Data
   var xy = projection(lonlat);
   // save without translation.
   context.save(); 
   // position symbol:
   context.translate(...xy);
   // Draw symbol:
   context.beginPath();   
   shape();
   context.fill();
   // Remove translation:
   context.restore();
}


points.forEach(shapey);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<canvas width="500" height="300"></canvas>

Конечно, вы также можете указать свои собственные формы, вот простая реализация квадрата:

var context = d3.select("canvas").node().getContext("2d");

var points = [[-136,63],[-123,50]];

var projection = d3.geoMercator();

var shape = function(xy) {
  var offset = 10;
  var x = xy[0];
  var y = xy[1];
  context.beginPath();
  // draw a sqaure:
  context.moveTo(x-offset,y-offset);
  context.lineTo(x-offset,y+offset);
  context.lineTo(x+offset,y+offset);
  context.lineTo(x+offset,y-offset);
  context.lineTo(x-offset,y-offset);
  context.fill();
  context.strokeStyle = "steelblue";
  context.lineWidth = 5;
  context.lineCap = "square"
  context.stroke();
}

var shapey = function(lonlat) {
   // Get xy Data
   var xy = projection(lonlat);
   // save without translation.
   shape(xy);

}


points.forEach(shapey);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<canvas width="500" height="300"></canvas>

Конечно, эти базовые c функции могут быть намного интереснее, но для демонстрации их должно быть достаточно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...