You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Delaunay三角剖分处理地图经纬度点?JTS使用问题求助

用JTS库进行Delaunay三角剖分仅生成一个三角形的解决方案

问题根源分析

  1. 代码逻辑错误:重复创建DelaunayTriangulationBuilder实例后,错误地继续使用原始点集dal而非带噪声的dalWithNoise,且误用builder.toVertices(dalWithNoise)方法——该方法是用来提取三角剖分结果的顶点,而非设置输入点集。
  2. 点集共线问题:若原始4个点共线或近似共线,Delaunay三角剖分只会生成单个三角形(或退化的三角网),过小的噪声无法打破这种共线性。

修正后的代码

import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.triangulate.DelaunayTriangulationBuilder;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Arrays;

public class DelaunayExample {
    public static void main(String[] args) {
        GeometryFactory gf = new GeometryFactory();
        List<Coordinate> dal = new ArrayList<>();
        // 替换为实际的位置坐标
        dal.add(new Coordinate(1.0, 1.0));
        dal.add(new Coordinate(2.0, 2.0));
        dal.add(new Coordinate(3.0, 1.0));
        dal.add(new Coordinate(2.0, 0.0));

        // 原始点集的三角剖分
        DelaunayTriangulationBuilder builder1 = new DelaunayTriangulationBuilder();
        builder1.setSites(dal);
        builder1.setTolerance(0.00001);
        Geometry tri1 = builder1.getTriangles(gf);
        System.out.println("原始点集三角剖分输出: " + tri1);
        System.out.println("原始点集生成的三角形数量: " + tri1.getNumGeometries());

        // 添加噪声后的点集三角剖分
        Random random = new Random();
        List<Coordinate> dalWithNoise = new ArrayList<>();
        for (Coordinate c : dal) {
            // 增大正负噪声幅度,确保打破共线性
            double noiseX = random.nextDouble() * 0.01 - 0.005;
            double noiseY = random.nextDouble() * 0.01 - 0.005;
            dalWithNoise.add(new Coordinate(c.x + noiseX, c.y + noiseY));
        }

        DelaunayTriangulationBuilder builder2 = new DelaunayTriangulationBuilder();
        builder2.setSites(dalWithNoise); // 正确传入带噪声的点集
        builder2.setTolerance(0.000000001);
        Geometry tri2 = builder2.getTriangles(gf);

        if (tri2 == null) {
            System.out.println("错误: 三角剖分生成失败");
            return;
        }

        System.out.println("带噪声点集生成的三角形数量: " + tri2.getNumGeometries());
        for (int i = 0; i < tri2.getNumGeometries(); i++) {
            Geometry subGeometry = tri2.getGeometryN(i);
            System.out.println("三角形 " + (i + 1) + " 顶点: " + Arrays.toString(subGeometry.getCoordinates()));
        }

        // 遍历输出每个三角形的顶点
        for (int i = 0; i < tri2.getNumGeometries(); i++) {
            Geometry g = tri2.getGeometryN(i);
            Coordinate[] coords = g.getCoordinates();
            for (int j = 0; j < coords.length - 1; j++) {
                System.out.println("x: " + coords[j].x + ", y: " + coords[j].y);
            }
        }

        // 检查原始点集是否共线
        LineString line = gf.createLineString(dal.toArray(new Coordinate[0]));
        double totalDistance = dal.get(0).distance(dal.get(1)) 
                             + dal.get(1).distance(dal.get(2)) 
                             + dal.get(2).distance(dal.get(3));
        System.out.println("点集是否共线: " + Math.abs(line.getLength() - totalDistance) < 1e-6);
    }
}

关键修正说明

  • 修复点集传入逻辑:第二次三角剖分必须调用setSites(dalWithNoise)来使用带噪声的点,摒弃错误的toVertices调用。
  • 优化噪声策略:将噪声改为正负范围(-0.005到0.005),确保足够打破点的共线性。
  • 避免变量重复定义:将重复的builder、tri变量改为不同命名,避免编译错误。
  • 新增共线检测:通过计算点集的直线长度与逐点距离和的差值,判断是否存在共线问题。

内容的提问来源于stack exchange,提问作者user447551

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 16:00:59