情况:

在做WebGIS项目的过程中,遇到一个需求是按省份统计省份内点位的数量,最开始我用双循环暴力统计,当点位达到三千左右时,统计耗时达到了2500ms左右,于是有了效率优化的需求。

优化前代码:

1
2
3
4
5
6
provinces.forEach(province=>{
province.count = 0
points.forEach(point=>{
if(turf.booleanPointInPolygonO(point,province)) province.count++
})
})

优化思路:

1.循环逻辑优化:每个点位在判断属于一个省份后,它就不会再属于第二个省份,就可以将该点移除数组,从而减少剩下省份统计时遍历的点位数量;

2.多边形简化:每个省份的多边形其实也是由很多个点组成,多边形越复杂,判断一个点是否在多边形内时消耗的时间也越多,因此可以简化多边形来提高空间计算的效率;

优化后代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
provinces.forEach(province=>{
province.count = 0

//1.简化多边形
province = turf.simplify(complexPolygon, {
tolerance: 0.05 //简化参数,数值越大,简化程度越高
});

//2.过滤已判断的点
points = points.filter(point=>{
if(turf.booleanPointInPolygonO(point,province)){
province.count++
return false
}else{
return true
}
})
})

优化结果:

💡tips: 使用console.time 和console.timeEnd 函数可以测试某段代码执行耗费的时间

1
2
3
console.time('统计时间')
pointNumStatic(); //执行统计函数
console.timeEnd('统计时间')

1.实践循环优化后,耗时从2500ms降低到1000ms左右;

2.实践多边形简化后,耗时从1000ms左右降低到50ms左右;