js根据坐标判断构成单个多边形是否合法

代码

/**
 * 几何工具库
 * @author maybe
 * @license https://gitee.com/null_639_5368
 */
const turf = require('@turf/helpers');
const lineIntersect = require('@turf/line-intersect').default;

/**
 * 坐标转线段
 * @param {*} path 
 * @returns {arr}
 */
function pathToLines(path) {
    const lines = [];
    path.forEach((p, pi) => {
        let line;
        if (pi == path.length - 1) {
            line = turf.lineString([path[pi], path[0]]);
            lines.push(line)
            return;
        }
        line = turf.lineString([path[pi], path[pi + 1]]);
        lines.push(line)
    })
    // console.log(JSON.stringify(lines))
    return lines;
}
/**
 * 判断坐标组成的单个多边形是否合法
 * @param {*} path 
 * @description 请传入[[1,2],[2,2],[3,3]] 类似的二维数组 
 * @returns {boolean}
 */
function isTruePolygon(path) {
    if (!Array.isArray(path) || path.length < 3) return false;
    if (!path.every(item => Array.isArray(item) && item.length == 2)) return false;

    const lines = pathToLines(path);
    let isTrue = true;
    function check() {
        // 倒序循环
        for (let i = lines.length - 1; i >= 0; i--) {
            // 基准线段
            const line1 = lines[i];
            // 依次判断
            for (let j = i - 1; j >= 0; j--) {
                const line2 = lines[j];
                // 判断是否相交
                const lt = lineIntersect(line1, line2)
                // console.log(JSON.stringify(lt.features.length > 0 ? '相交' : '不相交'))
                // 如果是相邻的一根线段,判断是否有交点且交点是否在端点上,如果是最后一根线段为基准线段那么和第一根线段也将相邻在端点才合法
                if (j == i - 1 || (i == lines.length - 1 && j == 0)) {
                    // 判断交点是否在端点上
                    const coordinates = line1.geometry.coordinates;
                    const ltCoordinates = lt.features.length > 0 && lt.features[0].geometry.coordinates
                    const isEndpoint = coordinates.find(p => p[0] == ltCoordinates[0] && p[1] == ltCoordinates[1]);
                    // console.log(lt.features[0].geometry.coordinates);
                    if (!isEndpoint) {
                        isTrue = false;
                        // console.log('相邻线段非端点不合法')
                        return;
                    } else {
                        // console.log('相邻线段合法')
                    }
                } else {
                    if (lt.features.length > 0) {
                        isTrue = false;
                        // console.log('非相邻线段相交不合法')
                        return;
                    } else {
                        // console.log('非相邻线段合法')
                    }
                }
            }
        }
    }
    check();
    return isTrue;

}
module.exports = {
    pathToLines,
    isTruePolygon,
}
复制代码

测试

const path_false = [
    [116.403322, 39.920255],
    [116.385726, 39.909893],
    [116.410703, 39.897555],
    [116.402292, 39.892353],
    [116.389846, 39.891365]
]
const path_true = [
    [116.403322, 39.920255],
    [116.410703, 39.897555],
    [116.402292, 39.892353],
    [116.389846, 39.891365]
]
console.log(isTruePolygon(path_true)); // true
console.log(isTruePolygon(path_false)); // false

复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享