2

我在 Here Map 上绘制了几个标记和一个多边形对象。

我想知道多边形和标记之间的距离。非常接近多边形的标记是我想要弄清楚的。

这里的地图有一个距离函数,但它只能计算两个标记之间的距离。

这是我用来计算距离的函数PaohaIslandPaohaIsland.getGeometry().distance(yosmitePark.getGeometry())是标记对象yosmitePark多边形对象

在此处输入图像描述

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()));
}
4

1 回答 1

0

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来验证给定的 Marker 对象(必须放在地图上)是否在地理多边形内(在您的情况下,我假设您不需要它)。

这是工作jsfiddle示例。单击标记对象后,它会在控制台中记录距离。

于 2020-04-29T21:01:52.513 回答