2 个多边形的关系无非:html
先向你们阐述个人应用场景:需求方欲经过在地图上绘制蜂窝以分配员工所负责区域。纯手工绘制易将道路、楼、园林、水系等切割引起划分纠纷,故咱们接入一叫 block 的服务,根据绘制点返回周围的 N 个 block 即真正的地理分区(不切割道路、楼、园林、水系等),咱们将这 N 个 block 合并造成一整个蜂窝。但绘制点跨度较大时将遗漏其间细小 block 产生缝隙,更糟糕的状况是产生零散块儿使合并结果不为一总体。此刻需获知每一零散块儿与蜂窝的关系,丢弃相离及被彻底包含的,并入相交的。git
业务场景再也不赘述,直接上代码:github
import MD5 from 'md5' import TURF from 'turf' /** * 获取 N 个多边形面积 * @param callback * @param opts * polygons(List{ polygonOpts })(必传): 多边形对象 List * order(String)(默认不排序): ascend(升序) 或 descend(降序) * @param polygonOpts * path(Path)(必传): 路径 [[lng(Number), lat(Number)], ...] */ export function getPolygonsArea (callback, opts = {}) { var polygons = opts.polygons var response = { polygons: [] } for (let i = 0; i < polygons.length; i++) { // 获取多边形面积 let area = TURF.area(TURF.polygon([polygons[i].path])) response.polygons.push({ ...polygons[i], area: area }) } switch (opts.order) { // 升序排列 case 'ascend': response.polygons.sort((a, b) => a.area - b.area) break // 降序排列 case 'descend': response.polygons.sort((a, b) => b.area - a.area) break default: break } callback && callback(response) } /** * 获取 2 个多边形相交关系 * @param callback * @param opts * polygonA(Polygon{ polygonOpts })(必传): 多边形对象 A * polygonB(Polygon{ polygonOpts })(必传): 多边形对象 B * @param polygonOpts * path(Path)(必传): 路径 [[lng(Number), lat(Number)], ...] */ export function getPolygonsRelation (callback, opts = {}) { var polygonA = TURF.polygon([opts.polygonA.path]) var polygonB = TURF.polygon([opts.polygonB.path]) // 获取 polygonA 与 polygonB 交集 var intersection = TURF.intersect(polygonA, polygonB) if (intersection) { let geometry = intersection.geometry switch (geometry.type) { case 'Point': callback && callback({ relation: 'pointIntersectant', desc: '相交的(交集为单点)', intersection: geometry, polygonA: opts.polygonA, polygonB: opts.polygonB }) return case 'MultiPoint': callback && callback({ relation: 'multiPointIntersectant', desc: '相交的(交集为多点)', intersection: geometry, polygonA: opts.polygonA, polygonB: opts.polygonB }) return case 'LineString': callback && callback({ relation: 'tangent', desc: '相切的(交集为单线)', intersection: geometry, polygonA: opts.polygonA, polygonB: opts.polygonB }) return case 'MultiLineString': callback && callback({ relation: 'multiTangent', desc: '相切的(交集为多线)', intersection: geometry, polygonA: opts.polygonA, polygonB: opts.polygonB }) return // 交集为多个多边形 case 'MultiPolygon': callback && callback({ relation: 'multiIntersectant', desc: '相交的(多处交集)', intersection: geometry, polygonA: opts.polygonA, polygonB: opts.polygonB }) return // 交集为单个多边形 case 'Polygon': getPolygonsArea((res) => { // 面积较小多边形 let minPolygon = res.polygons[0] // 面积较大多边形 let maxPolygon = res.polygons[1] // 判断 2 个多边形 path 是否如出一辙 if (MD5(minPolygon.path) === MD5(maxPolygon.path)) { callback && callback({ relation: 'equal', desc: '相等的', intersection: intersection, polygonA: opts.polygonA, polygonB: opts.polygonB }) return } // 判断较小多边形 path 与交集多边形 path 是否如出一辙 if (MD5(minPolygon.path) === MD5(geometry.coordinates[0])) { callback && callback({ relation: 'included', desc: '包含的', intersection: intersection, polygonA: opts.polygonA, polygonB: opts.polygonB, minPolygon: minPolygon, maxPolygon: maxPolygon }) return } callback && callback({ relation: 'intersectant', desc: '相交(一处交集)', intersection: intersection, polygonA: opts.polygonA, polygonB: opts.polygonB }) }, { polygons: [opts.polygonA, opts.polygonB], order: 'ascend' }) return default: callback && callback({ relation: 'fixedIntersectant', desc: '相交的(多种类型交集)', intersection: geometry, polygonA: opts.polygonA, polygonB: opts.polygonB }) return } } else { callback && callback({ relation: 'separated', desc: '相离的', intersection: intersection, polygonA: opts.polygonA, polygonB: opts.polygonB }) } }
机智的你发现我利用了第三方库 turf,未自行研究大量几何算法。此分享内容很少,代码量较小,望勿嫌弃。俗话说“君子善假于物也”,俗话又说“天下代码一大抄,看你会抄不会抄”...算法
做者:呆恋小喵spa
个人后花园:https://sunmengyuan.github.io...code
个人 github:https://github.com/sunmengyuanhtm