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 方法花费更多时间。
如果你的多边形很大(从某种意义上说它们覆盖了很大的区域)或者形状很奇怪。然后,细分它们可能会提高索引性能,请记住索引首先在多边形的边界框上工作,以节省在多边形测试中进行昂贵的点。如果一个点落入许多边界框但只有一个多边形,则索引不会有太大帮助。
Paul Ramsey 的这篇博客文章在 PostGIS 上下文中讨论了这一点,但这里的底层实现是相同的。这个answer将帮助您划分多边形(因为我认为JTS没有细分方法)。
您还可以从 JTS 代码周围使用GeoTools 中受益,因为这将允许您切换到使用具有内置索引的 PostGIS 或 GeoPackage 数据库,或更简单的 在内存存储中建立索引。