我有一组java.awt.Shape
个物体,覆盖了一个没有重叠的二维平面。这些来自美国郡的数据集,分辨率相当低。对于(x,y)纬度/经度点,我想要一种快速的方法来识别哪个县包含该点的形状。什么是对此进行索引的最佳方式?
蛮力看起来像:
for (Shape eachShape : countyShapes) {
if (eachShape.contains(x, y)) {
return eachShape;
}
}
为了优化这一点,我可以存储(可能是复杂的)形状的最小/最大边界,并且只对其矩形边界包含给定x,y坐标的形状调用contains(x, y)
。构建此索引的最佳方法是什么? SortedMultiset可用于对x
最小值和最大值进行索引,但如何在索引中包含y
坐标?
对于这个特定的实现,做几秒钟的前期工作来索引形状不是问题。
答案 0 :(得分:1)
如果可能,您可以尝试使用不同颜色的每个形状的位图。然后只需查询点和颜色并查找形状。
答案 1 :(得分:1)
这个问题超出了Stackoverflow的范围,但答案可能是Binary Space Partitioning。
大致是:
传统算法实际上划分了横跨边界的形状,但这里可能没有必要。
智能实现可能会寻找最有效的划分线,其中两个列表中最长的一个是最小的。 这涉及更多的前期计算,但是更有效且始终如一地执行分区。
答案 2 :(得分:0)
您可以使用现有的GIS库,例如GeoTools,然后所有的努力工作都已完成。
只需加载shapefile of counties并执行
等查询即可CREATE EXTERNAL TABLE weather(WBAN STRING, `Date` STRING, Time STRING, StationType INT, SkyCondition STRING, SkyConditionFlag STRING, Visibility INT, VisibilityFlag STRING, WeatherType STRING, WeatherTypeFlag STRING, DryBulbFarenheit INT, DryBulbFarenheitFlag STRING, DryBulbCelsius DECIMAL, DryBulbCelsiusFlag INT, WetBulbFarenheit INT, WetBulbFarenheitFlag INT, WetBulbCelsius DECIMAL, WetBulbCelsiusFlag INT, DewPointFarenheit INT, DewPointFarenheitFlag INT, DewPointCelsius DECIMAL, DewPointCelsiusFlag INT, RelativeHumidity INT, RelativeHumidityFlag INT, WindSpeed INT, WindSpeedFlag INT, WindDirection INT, WindDirectionFlag INT, ValueForWindCharacter INT, ValueForWindCharacterFlag INT, StationPressure DECIMAL, StationPressureFlag INT, PressureTendency INT, PressureTendencyFlag INT, PressureChange INT, PressureChangeFlag INT, SeaLevelPressure DECIMAL, SeaLevelPressureFlag INT, RecordType STRING, RecordTypeFlag STRING, HourlyPrecip DECIMAL, HourlyPrecipFlag INT, Altimeter DECIMAL, AltimeterFlag INT)
COMMENT 'Our weather table in HIVE!'
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
LOCATION '/data/Weather';
quickstart tutorial将向您展示如何加载形状,query tutorial将向您展示如何查询它们。
答案 3 :(得分:0)
最小化边界坐标的最大值并不能保证您可以确定在任何情况下是否有一个点进入或退出。如果你想自己实现这个,你应该实现一些算法。有一个很好的被称为“径向算法”,我建议使用它,并且实现起来并不复杂,有足够的参考书目和例子。 希望这有帮助。