0

在我们的应用程序中,ES 保存具有区域字段的对象,其中区域字段为 MultiPyligon 类型。(基本上,它是一个多边形数组)。

现在,我们需要搜索其中一个多边形至少部分落在给定多边形内的所有对象(在我们的例子中,它是地图的当前视口)。

我们正在试验的当前查询如下:

$params = [
            'index' => self::CrimeIndex,
            'body' => [
                'size' => 10000,
                'query' => [
                    'bool' => [
                        'filter' => [
                            'geo_bounding_box' => [
                                'areas' => [
                                    "top_left" => [
                                        "lat" => $neLat,
                                        "lon" => $neLng
                                    ],
                                    "bottom_right" => [
                                        "lat" => $swLat,
                                        "lon" => $swLng
                                    ]
                                ],
                            ]
                        ]
                    ]
                ]
            ],
];

问题是这个查询获取了所有接触边界框边缘的多边形。(见图)。我们如何才能获得至少部分位于边界框内的所有多边形?

在此处输入图像描述

映射如下:

$params = [
    'index' => CrimeService::CrimeIndex,
    'body' => [
        "mappings" => [
            'properties' => [
                'areas' => [
                    'type' => 'geo_shape'
                ]
            ],
        ],
    ],
];
$client->indices()->create($params);

根据文档,geo_shape可以是MultiPolygon. https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-shape.html

这是它看起来如何填充的示例:

在此处输入图像描述

GET crimes/_mapping/field/areas提供以下内容: 在此处输入图像描述


更新 - 更详细的重现步骤

附上集合/索引的转储:https ://www.dropbox.com/s/8inavsvcrnuozw1/dump-2021-12-29t21_54_04.639z.json.zip?dl=0

使用 elasticsearch-php 执行的查询是:

$params = [
            'index' => 'crime',
            'body' => [
                'size' => 10000,
                'query' => [
                    'bool' => [
                        'filter' => [
                            'geo_bounding_box' => [
                                'areas' => [
                                    "top_left" => [
                                        "lat" => $neLat,
                                        "lon" => $neLng
                                    ],
                                    "bottom_right" => [
                                        "lat" => $swLat,
                                        "lon" => $swLng
                                    ]
                                ],
                            ]
                        ],
                    ]
                ]
            ],
        ];

如果我们使用参数执行它: 49.29366604017385,-123.00491857934166,49.19709977562233,-123.26617317321401

我们得到以下信息: 在此处输入图像描述

如果视口发生了一些变化,所以多边形接触到视口的边界:49.28031011582358,-122.92300503734472,49.18371770837152,-123.18425963121705,我们得到其余的多边形: 在此处输入图像描述

4

1 回答 1

1

您的查询坐标错误,而不是 top_left + bottom_right,您有 bottom_left + top_right(见下图)

在此处输入图像描述

我认为这几乎可以解释为什么你会看到你所看到的。

于 2021-12-30T05:42:45.823 回答