Java 查找包含X,Y坐标的形状

Java 查找包含X,Y坐标的形状,java,algorithm,geospatial,Java,Algorithm,Geospatial,我有一组java.awt.Shape对象,它们覆盖了一个没有重叠的二维平面。这些数据来自美国各州的数据集,分辨率相当低。对于x,y纬度/经度点,我需要一种快速方法来识别包含该点的县的形状。什么是索引的最佳方法 蛮力看起来像: for (Shape eachShape : countyShapes) { if (eachShape.contains(x, y)) { return eachShape; } } 为了优化这一点

我有一组java.awt.Shape对象,它们覆盖了一个没有重叠的二维平面。这些数据来自美国各州的数据集,分辨率相当低。对于x,y纬度/经度点,我需要一种快速方法来识别包含该点的县的形状。什么是索引的最佳方法

蛮力看起来像:

    for (Shape eachShape : countyShapes) {
        if (eachShape.contains(x, y)) {
            return eachShape;
        }
    }
为了优化这一点,我可以存储可能复杂形状的最小/最大边界,并且只在矩形边界包含给定x,y坐标的形状上调用containsx,y。建立此索引的最佳方法是什么?A可以在x极小值和极大值上建立索引,但是如何在索引中也包含y坐标呢


对于这个特定的实现,只需几秒钟的前期工作就可以为形状编制索引。

如果可能,您可以尝试使用不同颜色的每个形状的位图。然后简单地查询点和颜色并查找形状。

您可以使用现有的GIS库,如,然后所有的艰苦工作已经完成

只需加载并执行如下查询

"the_geom" contains 'POINT(x y)

将向您展示如何加载形状,并向您展示如何查询形状。

具有边界坐标的最小值和最大值并不能保证您可以确定在任何情况下一个点是处于内部还是外部。如果你想自己实现这一点,你应该实现一些算法。有一个很好的算法叫做径向算法,我建议使用它,实现起来并不复杂,有足够的参考文献和例子。
希望能有所帮助。

这个问题不在Stackoverflow的范围之内,但答案可能是

大致:

使用范围的中点在x坐标或y坐标上将空间一分为二。 在该线两侧创建一个县列表,并按该线划分。 在该行的每一侧,将集合再次除以另一个维度。 继续递归地构建一棵树,用x和y交替划分,直到得到一组令人满意的对象,以便使用蛮力进行检查。 传统的算法实际上是分割跨越边界的形状,但这在这里可能不是必需的

一个智能的实现可能会寻找最有效的划分行,其中两个列表中最长的是最小的。
这需要更多的前期计算,但需要更高效、一致地执行分区。

问题非常广泛,而且可能过于广泛。有几十种空间数据结构,从著名的四叉树、kD树和BSP等。在大多数情况下,在内存消耗、精度、查询时间与构建时间等方面存在一些权衡。或者问题是关于如何使用SortedMultiSet解决这个问题?谢谢@Marco13,这是关于美国县的数据,启动时间不是问题。我在一个请求中获取了数千个地址,需要尽快按县对它们进行分组,这样最终用户体验会很快。这增加了一些可能是问题的一部分的重要信息,以缩小问题的范围:因此形状的数量将约为3000个。它们将有相似的尺寸。它们将是简单的,并且大部分是凸面的。也许其他人可以据此给出提示。我不能在这里给出具体的建议。我的方法是将其隐藏在一个非常简单、单一的接口后面:Collection getPoint p,并尝试/基准测试一些实现。它们中的许多可能在现有的库中开箱即用。@Marco13我不确定它们的大小是否“相似”或“大部分”是凸的@DanAllen引用了类似的话:尺寸的变化不超过1000倍,这至少是一个粗略的暗示。它们的形状大多是凸面的,因为如果一个边界框包含一个点,那么实际形状包含该点的几率通常大于50%,通常大于90%。但我对简单的问题再也不确定了:看看,似乎有些县是其他县的飞地——如果这是真的,这可能会使事情变得复杂很多,可能……这当然是我在评论中提到的非常有效但可能不精确的权衡。这可能是一个非常有效且非常简单的解决方案。但它总是受到图像分辨率的限制。即使是在美国,一些县也会塌陷成几个像素的模糊斑点。对于一个大于几千像素的大图像,分辨率可以,但是内存消耗会很高…但是仍然考虑像素化,它确实提供了一种非常简单的分区方法。只需定义一个NxM数组,并将县存储在地图顶部NxM网格对应单元中的每个单元中。这将为您提供N和M作为调优参数。对于大约3000个对象,一个相对较小的网格将为您提供一个相当精简的列表以进行详细检查。学士学位
空间分区总是会更好,但这可能会提供一个适合用途的简单解决方案。@DanAllen空间哈希大致就是这样做的:它定义一个网格,并在每个单元格中存储一个与此单元格重叠的县列表。根据网格大小,在大多数情况下,这将是1个县。对于给定的点,通过O1查找找到单元格,并且只有少数几个县真正需要检查。是的,很少——又有诡辩了-