Попытка создать "ромб" с API Google Maps - PullRequest
0 голосов
/ 13 ноября 2018

В настоящее время я использую API Google Maps для построения точек на карте.Я ищу лучший способ достижения эффекта типа «ромба» между точками (см. Изображение).По сути, толщина ромба будет определяться динамически.

Единственный способ увидеть это - нарисовать 2 круга на концах моих точек и создать прямоугольник между ними без границ.,Мне не нравится эта идея, так как она по существу добавляет 3 полигона на мою карту для каждой линии, которая у меня есть, и означает, что мне нужно будет добавить 3 события клика для каждой линии (по одному на каждый полигон), чтобы отобразить данные, которые я хочупоказывать при нажатии на строку.

Есть ли лучший способ добиться этого?

enter image description here

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Я обнаружил, что с помощью API Google Maps гораздо проще достичь этого. Есть встроенные функции для определения направления на основе начальной точки ... Поэтому я создал функцию, которая берет начальную и конечную точки линии, а затем создает точки вокруг них на основе заголовка, а затем создает многоугольник, используя эти точки.

var pointCount = 12;
function setLozengePath(startPoint, endPoint) {
  var sp = google.maps.geometry.spherical;
  var heading = sp.computeHeading(startPoint, endPoint);

  var points = [];

  for (var i = 0; i <= pointCount; ++i) {
    points.push(sp.computeOffset(endPoint, radius, heading + 90 - i * 15));
  }

  for (var i = 0; i <= pointCount; ++i) {
    points.push(sp.computeOffset(startPoint, radius, heading - 90 - i * 15));
  }

  return points;
}
0 голосов
/ 13 ноября 2018

Просто создайте 2 полилинии ...

function initialize() {

  var map = new google.maps.Map(document.getElementById('map-canvas'), {
    zoom: 3,
    center: {lat: 20, lng: 0},
    mapTypeId: 'terrain'
  });

  var flightPlanCoordinates = [
    {lat: 20, lng: -20},
    {lat: 20, lng: 20}
  ];
  
  new google.maps.Polyline({
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: .3,
    strokeWeight: 20,
    map: map
  });
  
  new google.maps.Polyline({
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 1,
    map: map
  });
}

initialize();
#map-canvas {
  height: 200px;
}
<div id="map-canvas"></div>

<script src="https://maps.googleapis.com/maps/api/js"></script>

Edit:

Вы упомянули в своем комментарии, что необходимо зафиксировать обводку на заданном расстоянии от центральной линии.

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

Это должно работать, если различные точки полилинии находятся более или менее на одной широте, поскольку разрешение карты с проекцией Меркатора зависит от широты. Так, например, если у вас большое пересечение Полилинии от -70 до +70 широты, оно не будет полностью точным.

Это формула, которую вы можете использовать для вычисления размера 1 пикселя карты. Вам нужно будет заменить map.getCenter().lat() центральной точкой Polyline.

// Calculate the width of 1 map pixel in meters
let scale = 156543.03392 * Math.cos(map.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());

К сожалению, есть проблема с этим подходом. Несмотря на то, что он не имеет документов, ширина обводки полилинии не может превышать 32px .

var map;
var polyBounds;
var polyStroke;
var polyWidth = 50; // Width in meters

function initialize() {

  map = new google.maps.Map(document.getElementById('map-canvas'), {
    zoom: 12,
    center: {
      lat: 20,
      lng: 0
    },
    mapTypeId: 'terrain'
  });

  var flightPlanCoordinates = [{
      lat: 20,
      lng: -0.5
    },
    {
      lat: 20,
      lng: 0.5
    }
  ];

  polyStroke = new google.maps.Polyline({
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: .3,
    strokeWeight: 0,
    map: map
  });

  new google.maps.Polyline({
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 1,
    map: map
  });

  polyBounds = new google.maps.LatLngBounds();

  for (var i = 0; i < flightPlanCoordinates.length; i++) {

    polyBounds.extend(flightPlanCoordinates[i]);
  }

  google.maps.event.addListenerOnce(map, 'idle', setStroke);
  google.maps.event.addListener(map, 'zoom_changed', setStroke);
}

function setStroke() {

  // Calculate the width of 1 map pixel in meters
  let scale = 156543.03392 * Math.cos(polyBounds.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());

  polyStroke.setOptions({
    strokeWeight: Math.ceil(polyWidth / scale)
  });
}

initialize();
#map-canvas {
  height: 200px;
}
<div id="map-canvas"></div>

<script src="https://maps.googleapis.com/maps/api/js"></script>

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

Решение, на которое вы указали в комментариях ( Как нарисовать многоугольник вокруг ломаной линии в JavaScript? ), по-прежнему, вероятно, ваш лучший вариант.

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