如何在聚类活动的多边形内获取 MapMarker

How to get MapMarker inside a polygon with clustering active

我们正在寻找一种方法来使用 JavaScript HereMaps API

获取多边形内的数据点

我们正在向 ClusterLayer / ClusterProvider 添加 4 个数据点,并向地图添加一个多边形。 4 个点中的 3 个在绘制的多边形内(点的数据:a、b、d)。数据 = c 的点不在多边形内(参见 jsfiddle)

我们尝试使用 map.getObjectsWithin 但这仅对 returns 多边形起作用。我们假设这是由不同层引起的。

获取位于多边形边界内的数据点的最佳方法是什么? 我们尽量避免额外的依赖来解决这个问题。

快速演示: http://jsfiddle.net/4dno0gu2/59/

我们找到了这个问题,但是没有例子,activity很久了,没有解决方案。 HereMap getObjectsWithin does not show objects in LocalObjectProvider

是的,方法 getObjectsWithin 对 ObjectProvider 不起作用,尽管它是在 JS 中实现的 API,但很简单,此功能不是 public 方法,对此深表歉意。

解决方法的简短描述:

  1. 获取多边形的边界框
  2. 向提供商请求您对此边界框感兴趣的所有类型的对象 (requestOverlays、requestSpatials、requestMarkers 等)- 在您的情况下是 requestMarkers
  3. 过滤掉所有不与多边形相交的对象

代码:

/**
 * Adds a polygon to the map
 *
 * @param  {H.Map} map      A HERE Map instance within the application
 */
function addPolygonToMap(map) {
  var geoStrip = new H.geo.LineString(
    [48.8, 13.5, 100, 48.4, 13.0, 100, 48.4, 13.5, 100]
  );
  
  var polygon = new H.map.Polygon(geoStrip, {
      style: {
        strokeColor: '#829',
        lineWidth: 8
      },
      data: 'polygon'
    });
  //map.addObject(polygon);
  return polygon;
}

function logObjectsInPolygon(map, polygon){
 var geoPolygon = polygon.getGeometry();
 map.getObjectsWithin(geoPolygon, (o) => {
                console.log('found mapObjects: '+ o.length);
        o.forEach(x=>{
            if(typeof x.getData === 'function'){
            console.log(x.getData());
            }
        });
  });
}

function isPointInPolygon(testPoint, polygPoints) {
    let result = false;
    let j = polygPoints.length - 1;
    for(i=0,len=j+1; i<len; i++){
            let p = polygPoints[i];
        let lP = polygPoints[j];
        if(p.y < testPoint.y && lP.y >= testPoint.y || lP.y < testPoint.y && p.y >= testPoint.y){
            if((p.x + (testPoint.y - p.y) / (lP.y - p.y) * (lP.x - p.x)) < testPoint.x){
                result = !result;
            }
        }
        j = i;
     }
   return result;
}


/**
 * Boilerplate map initialization code starts below:
 */

//Step 1: initialize communication with the platform
var platform = new H.service.Platform({
  apikey: 'H6XyiCT0w1t9GgTjqhRXxDMrVj9h78ya3NuxlwM7XUs',
  useCIT: true,
  useHTTPS: true
});
var defaultLayers = platform.createDefaultLayers();

//Step 2: initialize a map - this map is centered over Europe
var map = new H.Map(document.getElementById('map'),
  defaultLayers.raster.normal.map,{
  center: {lat:48.5, lng:13.45},
  zoom: 10
});

//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));

// Create the default UI components
var ui = H.ui.UI.createDefault(map, defaultLayers);

//this marker should go to clusters if there is more data points
var dataPoints = [];
dataPoints.push(new H.clustering.DataPoint(48.5, 13.45,{}, 'a'));
dataPoints.push(new H.clustering.DataPoint(48.5001, 13.45,{}, 'b'));
dataPoints.push(new H.clustering.DataPoint(48.5002, 13.51,{}, 'c')); // not in Polygon
dataPoints.push(new H.clustering.DataPoint(48.53, 13.45,{}, 'd'));
var clusteredDataProvider = new H.clustering.Provider(dataPoints);
var layer = new H.map.layer.ObjectLayer(clusteredDataProvider);
map.addLayer(layer);

// createPolygon to select clustered (noise) points 
var polygon = addPolygonToMap(map);
let extPoly = polygon.getGeometry().getExterior();
let seqPointsPoly = [];
extPoly.eachLatLngAlt((lat, lng, alt, idy) => {
    seqPointsPoly.push( {y: lat, x: lng});
});

console.log("seqPointsPoly:", seqPointsPoly);

map.addEventListener("tap", (e) => {
    let pBbox = polygon.getBoundingBox();
  let arrPnts = clusteredDataProvider.requestMarkers(pBbox);
  for(let i=0,len=arrPnts.length; i<len; i++){
    let m = arrPnts[i];
    let p = {y: m.getGeometry().lat, x: m.getGeometry().lng};
    let clustData = m.getData();
    if(!clustData.getData){
        console.log("cluster: is in polygon:", isPointInPolygon(p, seqPointsPoly));
    } else if(clustData.getData){
        console.log("nois: is in polygon:", clustData.getData(), m.getGeometry(), isPointInPolygon(p, seqPointsPoly));
    }else{
        console.log("unknown type");
    }
    
  }
    console.log("clusteredDataProvider:", pBbox, clusteredDataProvider.requestMarkers(pBbox));
    // Our expected logging is: points a, b, d
    //logObjectsInPolygon(map, polygon);
});

工作示例(点击地图开始处理):http://jsfiddle.net/m1ey7p2h/1/