使用 IndexedPointInAreaLocator 和 STRTree(JTS 拓扑套件)无法实现多边形中的点性能

问题描述 投票:0回答:1
private List<ZoneDefinitionCacheMemory> findZonesForShipPosition(Point point) {
    List<Object> zoneDefinitionCacheHits = new ArrayList<>();
    strTree.query(point.getEnvelopeInternal(), zoneDefinitionCacheHits::add);
    return zoneDefinitionCacheHits.stream()
        .filter(ZoneDefinitionCacheMemory.class::isInstance)
        .map(ZoneDefinitionCacheMemory.class::cast)
        .filter(zoneDefinition -> isPointInsideGeometry(point, zoneDefinition.getGeometry()))
        .toList();
}

private boolean isPointInsideGeometry(Point point, Geometry geometry) {
    PointOnGeometryLocator pointOnGeometryLocator = new IndexedPointInAreaLocator(geometry);
    int location = pointOnGeometryLocator.locate(point.getCoordinate());
    boolean isInside = location == Location.INTERIOR;
    return isInside;
}

我使用上面的代码来搜索多边形中的点,在查询之前将所有多边形和多边形插入到 strTree 中,并且我还使用 IndexedPointInAreaLocator 在 STR Tree 的顶部添加一个附加过滤器来验证是否给定点是否确实位于几何中。

此外,我的多边形非常大,这意味着某些多边形中有近 160 万个点。

因此,通过此实现,我面临着性能问题,这种方法至少需要 100 毫秒才能完成,这对于我的用例来说是不期望的。

这里可能出现什么问题?或任何以某种方式加快速度的建议。

我的用例:我将获得很多点来检测它们是否位于给定几何形状(多边形和多多边形)的内部或外部

我尝试使用 Polygon.contains(point) 谓词,但它比 IndexedPointInAreaLocator 方法花费更多时间。

geospatial point-in-polygon jts
1个回答
0
投票

如果你的多边形很大(从某种意义上说它们覆盖了很大的区域)或者形状很奇怪。然后,细分它们可能会提高索引性能,请记住索引首先在多边形的边界框上工作,以节省在多边形测试中进行昂贵的点。如果一个点落入许多边界框但只有一个多边形,则索引不会有太大帮助。

Paul Ramsey 的这篇

博客文章在 PostGIS 上下文中讨论了这一点,但这里的底层实现是相同的。这个answer将帮助您划分多边形(因为我认为JTS没有细分方法)。

您还可以从 JTS 代码周围使用

GeoTools 中受益,因为这将允许您切换到使用具有内置索引的 PostGIS 或 GeoPackage 数据库,或更简单的 在内存存储中建立索引

© www.soinside.com 2019 - 2024. All rights reserved.