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

如何使用Java GeoTools库实现多边形范围的点位查询

Java GeoTools实现多边形范围点位查询方案

前置依赖

首先确保项目中引入GeoTools核心模块,需要用到gt-main(包含JTS几何工具核心能力)、gt-referencing(涉及坐标系转换时需要用到)。

实现步骤

1. 构造查询多边形

首先将地图上绘制的多边形边界坐标,按顺序组装为GeoTools(底层依赖JTS)识别的Polygon对象,注意多边形坐标必须首尾闭合,且和存储的点位使用完全一致的空间坐标系。
示例代码:

import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Polygon;

// 初始化几何构造工厂,SRID要和点位数据保持一致,WGS84经纬度一般填4326
GeometryFactory geoFactory = new GeometryFactory();
// 按绘制顺序填入多边形边界点,最后一个点坐标和第一个点完全相同,实现多边形闭合
Coordinate[] polygonCoordinates = new Coordinate[]{
    new Coordinate(-124.71, 49.38),
    new Coordinate(-66.95, 49.38),
    new Coordinate(-66.95, 24.52),
    new Coordinate(-124.71, 24.52),
    new Coordinate(-124.71, 49.38)
};
Polygon queryArea = geoFactory.createPolygon(polygonCoordinates);
// 校验多边形是否合法,避免自交、不闭合等问题导致判断错误
if (!queryArea.isValid()) {
    throw new IllegalArgumentException("输入的多边形几何不合法");
}

2. 点位范围判断

如果你的List<Point>里存储的是JTS的Point类型,直接调用JTS内置的空间关系方法即可判断点位是否落在多边形内:

  • 用point.within(queryArea):判断点严格在多边形内部,不包含落在多边形边界上的点
  • 用point.coveredBy(queryArea):判断点在多边形内部或边界上,大部分业务场景用这个更符合预期
    基础遍历实现代码:
import org.locationtech.jts.geom.Point;
import java.util.ArrayList;
import java.util.List;

public List<Point> filterPointsInArea(List<Point> allPoints, Polygon queryArea) {
    List<Point> matchPoints = new ArrayList<>();
    for (Point point : allPoints) {
        if (point.coveredBy(queryArea)) {
            matchPoints.add(point);
        }
    }
    return matchPoints;
}

如果你存储的Point是自定义的经纬度实体类,先把经纬度值取出转成JTS Point对象再判断即可:

// 假设自定义点位类是MyPoint,有getLng()、getLat()方法获取经纬度
Point jtsPoint = geoFactory.createPoint(new Coordinate(myPoint.getLng(), myPoint.getLat()));

3. 大数据量性能优化

如果点位量级在十万级以上,直接全量遍历性能较差,可以用JTS自带的STRtree空间索引做预过滤,查询效率可以提升1~2个数量级:

import org.locationtech.jts.index.strtree.STRtree;
import java.util.List;

// 索引只需要在程序初始化/点位数据加载完成后构建一次,不需要每次查询重建
STRtree pointSpatialIndex = new STRtree();
for (Point point : points) {
    pointSpatialIndex.insert(point.getEnvelopeInternal(), point);
}
pointSpatialIndex.build();

// 查询时先通过索引快速拿到外接矩形和多边形重叠的候选点位,再做精确判断
List<Point> candidatePoints = pointSpatialIndex.query(queryArea.getEnvelopeInternal());
List<Point> finalResult = new ArrayList<>();
for (Point candidate : candidatePoints) {
    if (candidate.coveredBy(queryArea)) {
        finalResult.add(candidate);
    }
}

效果参考

多边形范围查询点位示例

注意事项

  • 多边形和点位的空间参考(SRID)必须完全一致,比如不能一个用WGS84经纬度、一个用Web墨卡托投影坐标,否则判断结果完全错误,涉及坐标系不一致时要先做坐标转换
  • 构造多边形时不要出现坐标顺序混乱、自交、不闭合的问题,一定要调用isValid()方法校验合法性
  • 不要用contains方法做判断,该方法在点恰好落在多边形边界时会返回false,边界场景容易出问题

内容的提问来源于stack exchange,提问作者杨振宁

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:33:22