论如何获取 2 个多边形相交关系

栏目: 编程工具 · 发布时间: 6年前

内容简介:2 个多边形的关系无非:

2 个多边形的关系无非:

  • 相交(一处交集)

论如何获取 2 个多边形相交关系

  • 相交(多处交集)

论如何获取 2 个多边形相交关系

  • 相切(相交的一种,交集为线)

论如何获取 2 个多边形相交关系

  • 包含(相交的一种,交集为面积较小多边形)

论如何获取 2 个多边形相交关系

  • 相等(相交的一种,交集为 2 多边形本身)

论如何获取 2 个多边形相交关系

  • 相离(无交集)

论如何获取 2 个多边形相交关系

先向大家阐述我的应用场景:需求方欲通过在地图上绘制蜂窝以分配员工所负责区域。纯手工绘制易将道路、楼、园林、水系等切割引发划分纠纷,故我们接入一叫 block 的服务,根据绘制点返回周围的 N 个 block 即真正的地理分区(不切割道路、楼、园林、水系等),我们将这 N 个 block 合并形成一整个蜂窝。但绘制点跨度较大时将遗漏其间细小 block 产生缝隙,更糟糕的情况是产生零散块儿使合并结果不为一整体。此刻需获知每一零散块儿与蜂窝的关系,丢弃相离及被完全包含的,并入相交的。

论如何获取 2 个多边形相交关系

业务场景不再赘述,直接上代码:

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 'MultiLineString':
                callback && callback({
                    relation: 'tangent',
                    desc: '相切的',
                    intersection: intersection,
                    polygonA: opts.polygonA,
                    polygonB: opts.polygonB
                })
                return
            // 交集为多个多边形
            case 'MultiPolygon':
                callback && callback({
                    relation: 'multiIntersectant',
                    desc: '相交的(多处交集)',
                    intersection: intersection,
                    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
                        })
                    } else {
                        callback && callback({
                            relation: 'intersectant',
                            desc: '相交(一处交集)',
                            intersection: intersection,
                            polygonA: opts.polygonA,
                            polygonB: opts.polygonB
                        })
                    }
                }, {
                    polygons: [opts.polygonA, opts.polygonB],
                    order: 'ascend'
                })
                return
        }
    } else {
        callback && callback({
            relation: 'separated',
            desc: '相离的',
            intersection: intersection,
            polygonA: opts.polygonA,
            polygonB: opts.polygonB
        })
    }
}

机智的你发现我利用了第三方库 turf ,未自行研究大量几何算法。此分享内容不多,代码量较小,望勿嫌弃。俗话说“君子善假于物也”,俗话又说“天下代码一大抄,看你会抄不会抄”…

作者:呆恋小喵

我的后花园: https://sunmengyuan.github.io/garden/

我的 github: https://github.com/sunmengyuan

原文链接: https://sunmengyuan.github.io/garden/2018/08/31/polygon-relation.html


以上所述就是小编给大家介绍的《论如何获取 2 个多边形相交关系》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Code

Code

Charles Petzold / Microsoft Press / 2000-10-21 / USD 29.99

Paperback Edition What do flashlights, the British invasion, black cats, and seesaws have to do with computers? In CODE, they show us the ingenious ways we manipulate language and invent new means of ......一起来看看 《Code》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器