如何在聚类活动的多边形内获取 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 方法,对此深表歉意。
解决方法的简短描述:
- 获取多边形的边界框
- 向提供商请求您对此边界框感兴趣的所有类型的对象
(requestOverlays、requestSpatials、requestMarkers 等)- 在您的情况下是 requestMarkers
- 过滤掉所有不与多边形相交的对象
代码:
/**
* 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/
我们正在寻找一种方法来使用 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 方法,对此深表歉意。
解决方法的简短描述:
- 获取多边形的边界框
- 向提供商请求您对此边界框感兴趣的所有类型的对象 (requestOverlays、requestSpatials、requestMarkers 等)- 在您的情况下是 requestMarkers
- 过滤掉所有不与多边形相交的对象
代码:
/**
* 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/