ЗДЕСЬ карты для JavaScript API: рассчитать расстояние от полигона до маркера - PullRequest
5 голосов
/ 20 апреля 2020

Я нанес на карту несколько маркеров и многоугольников.

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

Здесь карта имеет функцию расстояния, но она работает только для вычисления расстояния между 2 маркерами.

Вот функция, которую я использовал для вычисления расстояния PaohaIsland.getGeometry().distance(yosmitePark.getGeometry()) Где PaohaIsland равно маркер Объект и yosmitePark - полигон объект

enter image description here

var map; 
function loadMap(){

    platform = new H.service.Platform({
      'apikey': HEREMAP_KEY
    });
    // Obtain the default map types from the platform object:
    var defaultLayers = platform.createDefaultLayers();

    // Instantiate (and display) a map object:
    map = new H.Map(
      document.getElementById('mapContainer'),
      defaultLayers.vector.normal.map,
      {
        center: { lat: 37.278419, lng: -119.674072,
        pixelRatio: window.devicePixelRatio || 1 },
        zoom: 8
      }
    );
    // Enable the event system on the map instance:
    var mapEvents = new H.mapevents.MapEvents(map);

    var behavior = new H.mapevents.Behavior(mapEvents);

    behavior.enable(H.mapevents.Behavior.WHEELZOOM);
}

function addPolygonToMap() {

  var lineString2 = new H.geo.LineString();
  lineString2.pushPoint({lat:37.278419,lng:-119.674072});
  lineString2.pushPoint({lat:37.335224,lng:-119.30603});
  lineString2.pushPoint({lat:37.529331,lng:-119.198914});
  lineString2.pushPoint({lat:37.522789,lng:-118.99292});
  lineString2.pushPoint({lat:37.627281,lng:-118.87207});
  lineString2.pushPoint({lat:37.80978,lng:-119.053337});
  lineString2.pushPoint({lat:38.01347,lng:-119.143982});
  lineString2.pushPoint({lat:37.965851,lng:-119.770203});
  lineString2.pushPoint({lat:37.898689,lng:-120.18219});
  lineString2.pushPoint({lat:37.867802,lng:-120.341492});
  lineString2.pushPoint({lat:37.746819,lng:-120.239861});
  lineString2.pushPoint({lat:37.51844,lng:-120.07782});
  lineString2.pushPoint({lat:37.278419,lng:-119.674072});

  var yosmitePark = new H.map.Polygon(lineString2, {
      style: {
        strokeColor: '#829',
        lineWidth: 8
      }
    });
  map.addObject(yosmitePark);

  var lakeMcClure = new H.map.Marker({
      lat: 37.6373862,
      lng: -120.3448606
  });
  lakeMcClure.setData("lakeMcClure");

  var Stockton = new H.map.Marker({
      lat: 37.9729404,
      lng: -121.4419639
  });
  Stockton.setData("Stockton");

  var Monolake = new H.map.Marker({
      lat: 38.0067483,
      lng: -119.1013779
  });
  Monolake.setData("Monolake");

  var PaohaIsland = new H.map.Marker({
      lat: 38.000514,
      lng: -119.0416587
  });
  PaohaIsland.setData("PaohaIsland");

  var WalkerLake = new H.map.Marker({
      lat: 38.7010578,
      lng: -118.878652
  });
  WalkerLake.setData("WalkerLake");

  var Bakersfield = new H.map.Marker({
      lat: 35.3208963,
      lng: -119.1587737
  });
  Bakersfield.setData("Bakersfield");
  var SanFrancisco = new H.map.Marker({
      lat: 37.7576793,
      lng: -122.5076405
  });
  SanFrancisco.setData("SanFrancisco");
  map.addObjects([lakeMcClure,Stockton,Monolake,PaohaIsland,WalkerLake,Bakersfield,SanFrancisco]);


  var mapObj =  map.getObjects();
  console.log(yosmitePark.getGeometry());
  console.log(PaohaIsland.getGeometry().distance(yosmitePark.getGeometry()));
}

1 Ответ

0 голосов
/ 30 апреля 2020

В API нет метода для расчета расстояния от точки до полигона.

Чтобы добиться этого, вы можете рассчитать расстояние от точки до каждого сегмента внешней строки LineString многоугольника, а затем выбрать наименьшее вычисленное значение:

function distanceToGeoPolygon(geoPoint, geoPolygon) {  
  let lineString = geoPolygon.getExterior(),
      minDistance = Infinity;

  // check distance for each LineString segment of the polygon
  for (let i = 0; i < lineString.getPointCount() - 1; i++) {
    let segmentStart = lineString.extractPoint(i),
        segmentEnd = lineString.extractPoint(i + 1),
        distance = distanceToSegment(geoPoint, segmentStart, segmentEnd);

    // set new min distance
    if (distance <= minDistance) {
      minDistance = distance;
    }
  }

  return minDistance;
}

. Здесь приведен метод расчета расстояния от точки к сегменту:

function distanceToSegment(point, segmentStart, segmentEnd) {
  // first we find the intersecting point of line which 
  // crosses the given point and is vertical to segment (start - end)
  let y0 = point.lat,
      x0 = point.lng,
      y1 = segmentStart.lat,
      x1 = segmentStart.lng,
      y2 = segmentEnd.lat,
      x2 = segmentEnd.lng,
      a = (y2 - y1) / (x2 - x1),
      b = y1 - a * x1,
      b0 = y0 + 1/a * x0,
      xi = a * (b0 - b) / ((a * a) + 1),
      yi = a * xi + b,
      intersectingPoint = new H.geo.Point(yi, xi); 


  // if calculated intersecting point is within the segment,
  // calculate distance between intersecting point and given point 
  if ( (xi > x1 && xi < x2 || xi > x2 && xi < x1) && 
    (yi > y1 && yi < y2 || yi > y2 && yi < y1) ) {
      return point.distance(intersectingPoint)
    } else {
      // else calculate distance between segment edges and given point
      // and return the smaller one
      return Math.min(point.distance(segmentStart), point.distance(segmentEnd));
    }
}

тест:

// test: (result is 14359)
console.log(distanceToGeoPolygon(lakeMcClure.getGeometry(), yosmitePark.getGeometry()));

Примечание : вышеуказанный скрипт возвращает положительные числа для точек внутри многоугольника. Если вы не хотите этого, вы можете использовать H.Map # getObjectsWithin , чтобы проверить, находится ли данный объект Маркер (должен быть размещен на карте) внутри гео-полигона (в вашем случае я предполагаю, что вам не нужно это).

Вот работает jsfiddle пример. Он регистрирует расстояние в консоли после нажатия на маркерный объект.

...