需求:在Mapbox地图上绘制一个多边形,需要计算与多边形相交的村有哪些。
现状:地图上的村界市线图层
计算相交,在postgresql数据库里很简单,但是数据量大的时候就有点效率低了。使用Mapbox在前端直接计算屏幕内要素的相交,计算量就比较小了。
这里采用的是先把屏幕内的目标要素全查出来,然后使用turf进行相交的判断
具体实现
1.添加村界面图层
//村界转polygon
map.addLayer(
{
"id": "村域面",
"source": "dt_cy",
"type": "fill",
"minzoom": 12,
"maxzoom": 18,
"layout": {},
"paint": {
"fill-outline-color": "#08cc53",
"fill-opacity":0,
"fill-color": "#08cc53"
},
"source-layer": "dt_cy",
"metadata": {
"mapbox:group": "b9f7ce9068f6a"
}
},
"种植结构"
);
2.计算相交与去重
/**
* 更新落图村信息
*/
setLtQhdm(feature){
console.log("计算外接矩形");
//查出屏幕类所有村界
let result=this.map.queryRenderedFeatures(null,{layers: ['村域面']});
let intersectFeatures=[];
//turf相交判断
if(result&& result.length>0){
for (let i = 0; i <result.length ; i++) {
if (! (undefined === turf.intersect(result[i].geometry, feature.geometry))) {
console.log(turf.area(turf.intersect(result[i].geometry, feature.geometry)));
intersectFeatures.push(result[i]);
}
}
//根据id去重
if(intersectFeatures){
intersectFeatures=this.unique(intersectFeatures);
//大于1,按照相交面积降序
if(intersectFeatures.length>1){
intersectFeatures.sort(function(a, b){return turf.area(turf.intersect(b.geometry, feature.geometry)) - turf.area(turf.intersect(a.geometry, feature.geometry))});
}
}
}
//相交结果
return feature;
}
//根据要素属性去重
unique(features){
let newArr = [];
let newFeature = [];
for(let i = 0; i < features.length; i++){
if(newArr.indexOf(features[i].properties.qhdm) == -1){
newFeature.push(features[i])
newArr.push(features[i].properties.qhdm)
}
}
return newFeature;
}
map.queryRenderedFeatures这里第一个参数传的是空,会把当前屏幕内所有符合条件的图层查出来。本来想的是将绘制的多边形的bbox查出来,当作第一个参数,结果发现查询的结果根本不对。最后直接改成null了。
注意事项
- 目标图层的type一定是fill
- queryRenderedFeatures的第一个参数要设置成空,相交关系用turf去判断