最近接到一个地理围栏采集工具的任务。之前自己只写过简单的单一多边形绘制,输出结果。现在需要我写一个多个多边形采集的任务。对于多边形之间的关系还需要通过业务逻辑进行处理,也需要对不同位置关系的多边形的result进行不同的数据格式处理。我有点慌!!!感觉此事必有蹊跷,需要老夫好好研究研究。
first:canvas实现绘图功能。
这个很简单,通过鼠标点击,获取当前位置的坐标(x,y),然后push到数组中,让数组的第一项为起始点,然后ctx.moveTo,之后遍历出剩下的点位,依次lineTo。要注意,当数组的length>=3时,需要比较当前坐标和起始点位是否相同(或者在合适的误差之内),如果满足要求,就可以完成绘制,形成闭合多边形。
second:判断其他多边形第一个点位的坐标与初始多边形的位置关系
通过几何算法来确定点和第一个多边形之间的位置关系。如果在多边形外,则绘制相离的多边形,如果在多边形内,绘制环状多边形。
通过使用turf.js第三方库来实现,点与多边形的位置关系。代码如下:
boolPointInPolygon() { //判断点和多边形位置关系(内部,外部) if (this.beforeShape.length >= 3 && this.firstClickArray.length >= 1) { let pt = turf.point( this.firstClickArray[this.firstClickArray.length - 1] ); let poly = turf.polygon([this.beforeShape]); this.bools = turf.booleanPointInPolygon(pt, poly); } },如果结果是true则点在多边形内。是false点在多边形外。
界面效果如下:
当确定第一个点位和多边形的关系后,需要接着判断其余点位和多边形的位置关系。如果第一个点在多边形外,第二个点在多边形内,这样的多边形不合法。接着通过上面的算法得出结果。
然后将画布和输出结果置为初始值。
next:判断两个多边形之间的关系。(相离,包含)
为什么需要判断两个多边形之间的位置关系,因为在geojson中,不同的多边形,输出的点位结果不同,我们需要不同的算法,来得出不同的结果。相离的结果是:
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "MultiPolygon",
"coordinates":
[
[
[
[109.2041015625,30.088107753367257],
[115.02685546875,30.088107753367257],
[115.02685546875,32.7872745269555],
[109.2041015625,32.7872745269555],
[109.2041015625,30.088107753367257]
]
],
[
[
[112.9833984375,26.82407078047018],
[116.69677734375,26.82407078047018],
[116.69677734375,29.036960648558267],
[112.9833984375,29.036960648558267],
[112.9833984375,26.82407078047018]
]
]
]
}
}环状的结果是:
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "MultiPolygon",
"coordinates":
[
[
[
[101.6455078125,27.68352808378776],
[114.78515624999999,27.68352808378776],
[114.78515624999999,35.209721645221386],
[101.6455078125,35.209721645221386],
[101.6455078125,27.68352808378776]
]
],
[
[
[104.2822265625,30.107117887092357],
[108.896484375,30.107117887092357],
[108.896484375,33.76088200086917],
[104.2822265625,33.76088200086917],
[104.2822265625,30.107117887092357]
]
]
]
}
}可以明显的看出来,二者的区别。通过turf.js来判断多边形之间的位置关系。
boolPolygonInPolygon() { //判断多边形和多边形的关系(是否出现相交) if ( this.threeArrs.length >= 1 && this.makers === 2 && this.nextVal.length != 0 ) { let polygon1 = turf.polygon([this.beforeShape]); let polygon2 = turf.polygon([this.nextVal]); this.intersection = turf.intersect(this.polygon1, this.polygon2); } },如果this.intersection的结果为null,则不相交,相离。
基本的绘制思路完成。接下来需要对结果进行处理,还有环状多边形的样式调整和回退,以及清空功能的实现。篇幅太多,放在下一篇中。。