提取GeoJSON中所有交汇节点(被多个几何要素共享的坐标点)

/**
 * 提取GeoJSON中所有交汇节点(被多个几何要素共享的坐标点)
 * @param {Object} geojson - GeoJSON对象(支持FeatureCollection/Feature/Geometry)
 * @param {number} [precision=6] - 坐标精度(小数位数,解决浮点误差)
 * @returns {Array} 交汇坐标数组,格式为[[lng, lat], ...]
 */
export function findIntersections(geojson, precision = 6) {
    const coordsMap = new Map(); // 存储坐标出现次数 { '["x","y"]': { count, original } }

    // 递归提取所有坐标点
    const extractCoordinates = (geometry) => {
        if (!geometry) return;
        const { type, coordinates } = geometry;

        // 坐标处理函数
        const process = (coord) => {            
            const rounded = coord.map(c => Number(c.toFixed(precision))); // 精度处理
            const key = JSON.stringify(rounded);

            if (!coordsMap.has(key)) {
                coordsMap.set(key, { count: 0, original: rounded }); // 保留原始坐标
            }
            coordsMap.get(key).count++;
        };

        // 根据几何类型处理坐标
        switch (type) {
            case 'Point':
                process(coordinates);
                break;
            case 'LineString':
            case 'MultiPoint':
                for (const coord of coordinates) process(coord);
                break;
            case 'Polygon':
            case 'MultiLineString':
                for (const ring of coordinates) for (const coord of ring) process(coord);
                break;
            case 'MultiPolygon':
                for (const polygon of coordinates) for (const ring of polygon) for (const coord of ring) process(coord);
                break;
            case 'GeometryCollection':
                for (const g of geometry.geometries) extractCoordinates(g);
                break;
            default:
                console.warn(`未支持的几何类型: ${type}`);
        }
    };

    // 处理输入对象
    if (geojson.type === 'FeatureCollection') {
        for (const feature of geojson.features) extractCoordinates(feature.geometry);
    } else if (geojson.type === 'Feature') {
        extractCoordinates(geojson.geometry);
    } else {
        extractCoordinates(geojson);
    }

    // 筛选交汇节点(出现次数>1)
    return Array.from(coordsMap.values())
        .filter(({ count }) => count > 1)
        .map(({ original }) => original); // 返回原始坐标
}

/**
 * 通过交汇点获取 与交互点连续的线段集合
 * @param {Object} geojson - GeoJSON对象(支持FeatureCollection/Feature/Geometry)
 * @param {number} [precision=6] - 坐标精度(小数位数,解决浮点误差)
 * @returns {Array} 连续线段数组,格式为[[[lng, lat], [lng, lat]], ...]
 */
export function extractTriplets(geojson, precision = 6) {
    const intersections = findIntersections(geojson, precision); // 获取所有交汇点

    // 遍历 geojson 修改小数点精度
    const { features } = geojson;

    const arr  = features.map(feature => {
        const { geometry } = feature;
        const { coordinates } = geometry;
        return coordinates.map(coordinate => {
            coordinate = coordinate.map(coord => {
                return Number(coord.toFixed(precision))
            })
            return JSON.stringify(coordinate);
        })
    })

    const arr2 = intersections.map(coordinate => {
        return JSON.stringify(coordinate);
    })

    const arr3 = [];

    for (let i = 0; i < arr2.length; i++) {
        for(let j = 0; j < arr.length; j++) {
            if(arr[j].includes(arr2[i])) {
                arr3.push([...arr[j], arr2[i]])
            }
        }
    }

    const arr4 = arr3.map( item => {
        return item.map(item1 => {
            return JSON.parse(item1);
        })
    })

    // 对arr4 的每个经纬度元素进行排序,以便后续处理



    return arr4;

}

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容