2016-08-10 72 views
0

我在ES中有两个geo_shapes。我需要弄清楚的是了解其中一个形状(绿色)是否包含或与另一个(红色)相交的最佳方式。 请参考下面的三种不同情况的直观表示:Elasticsearch Geoshape查询虚假结果

案例一:容易检测 - 利用绿色形状坐标进行Geoshape查询与“关系” =‘内’

案例二:还没有要做的事情 - 使用绿色形状坐标做一个Geoshape查询与“关系”=“INTERSECTS”

案例三:是一个真正的问题 - 使用绿色形状坐标我试图做一个Geoshape查询“relation”=“INTERSECTS “并且红色的形状返回结果...这是错误的 - 这种形状不会相互交叉(我认为是这样),即使其中一个边接触每个其他......

有什么办法可以避免这里的误报结果?任何其他建议如何解决这个任务?

P.S.坐标精确(例如:13.335594692338)。有没有像tree_levels或精度没有额外的映射......

enter image description here

+0

我不明白为什么情况1使用范围内,当红色/绿色多边形彼此相邻(并触摸边界的一侧)。 另外,案例3,根据定义,相交。他们触摸 – coffeeaddict

+0

案例1 - 对不起,我应该使红色有点transperant ...但它是在绿色的矩形(绿色的矩形是相同的case2-3。 ..) 关于交叉点 - 约定,但也不同意 - 交叉点是“交叉”...是n的边界,并不意味着交叉它)无论如何,一些解决方案将是很好的定义交叉和触摸)) ) –

+0

不幸的是,ES不支持通过'touch'进行匹配。它只提供相交(根据定义,它意味着共享一个共同点,不管它是否跨越,您可能会不同意这一点,但这是官方定义。) 如果您想要解决方法,可以从弹性搜索,并使用提供触摸方法的JTS库 – coffeeaddict

回答

2

这是使用geoshape存储在Elasticsearch每个多边形越来越转化为一个字符串列表。 为了缩小这个解释的范围,我会假设你在Elasticsearch中存储的多边形是使用geohash存储(这是geoshape类型的默认值)。

我不想陷入巨大的细节,但看看这个图片

geohash

,这说明从Elasticsearch文档拍摄(细节不相符,但你需要得到大的图片):

地球哈哈把世界划分成32格-4行和8列 列 - 每一列用一个字母或数字表示。 g格覆盖格陵兰岛的所有冰岛和大部分英国大陆的半壁江山。每个小区可以进一步划分为另外32个小区,其中可以划分为 另外32个小区,依此类推。 gc小区覆盖爱尔兰和英格兰, gcp覆盖伦敦的大部分地区和英格兰南部的一部分,而gcpuuz94k 是白金汉宫的入口,精确到5米左右。

您的多边形正在投影到矩形列表中,每个矩形都用一个字符串(geohash)表示。此投影的精确度取决于树级别。我不知道Elasticsearch的默认树层级别是什么,但如果您发现误报,它似乎对您而言太低。

树级别为8 splits the world in rectangles of size38.2m x 19.1m。如果多边形的边缘穿过此矩形的中间,它可能会或可能不会(取决于实现)将矩形的geohash表示分配给您的多边形。

要解决您的问题,您需要增加树水平以符合您的需求(更多关于地图here)。请注意,尽管索引的大小会大大增加(也取决于形状的大小和复杂性)。作为一个存储1000个区域大小多边形(有些具有100个点)的例子,树级别为8 - 索引大小约为600-700MB。

请记住,无论您选择哪种树木级别,您都会冒险得到一些误报,因为geohash永远不会100%准确地表示您的形状。这是一个精准度与性能之间的平衡,geohash是性能明智的选择

+0

非常感谢您提供这样的详细解释!纠正我,如果我错了 - 基本上我可以尝试玩“tree_levels”或“精度”,并将其设置为“1m”,例如...(PS ES文件建议设置'“树”:“quadtree”, “精度”:“1m”在我的情况下听起来合理 - 也许你可以对此发表一些评论?) –

+0

是的。你应该尝试这些值。请记住,每次更改映射时都需要重新编制索引。 – mbudnik

+0

非常感谢您的帮助!将尝试玩参数,并希望能够得到更精确的结果)) –