MySQL - 选择矩形内的所有几何图形

标签 mysql sql geospatial

我有一个具有以下结构的表 AREAGEOMETRY:

+-----------------+----------+------+-----+---------+-------+
| Field           | Type     | Null | Key | Default | Extra |
+-----------------+----------+------+-----+---------+-------+
| AREAGEOMETRY_ID | int(11)  | NO   | PRI | NULL    |       |
| AreaManagerId   | int(11)  | YES  |     | NULL    |       |
| AreaId          | text     | YES  |     | NULL    |       |
| EndDateArea     | datetime | YES  |     | NULL    |       |
| StartDateArea   | datetime | YES  |     | NULL    |       |
| AreaGeometryTxt | text     | YES  |     | NULL    |       |
+-----------------+----------+------+-----+---------+-------+

它包含来自 parking 区的数据。现在我要做的是选择边界框内的所有行。

边界框可能是这样的:

LatLngBounds{southwest=lat/lng: (52.35631327204287,4.881156384944916), northeast=lat/lng: (52.38006384519922,4.913054890930653)}

我为此提出了以下查询:

SELECT * FROM AREAGEOMETRY WHERE ST_OVERLAPS(GeomFromText(AreaGeometryTxt), GeomFromText('LINESTRING(52.35631327204287 4.881156384944916, 52.38006384519922 4.881156384944916, 52.38006384519922 4.913054890930653, 52.35631327204287 4.913054890930653, 52.35631327204287 4.881156384944916)'))

但是它似乎返回了表中的所有行,我不知道这里出了什么问题。 也许有人可以为我指出正确的方向。

编辑:

例如它返回这一行:

# AREAGEOMETRY_ID, AreaManagerId, AreaId, EndDateArea, StartDateArea, AreaGeometryTxt
493, 299, 8721, 0000-00-00 00:00:00, 0000-00-00 00:00:00, POLYGON ((6.071624141 51.927465383, 6.071167939 51.927755315, 6.073816653 51.928513734, 6.07434586 51.928376592, 6.072239751 51.927748706, 6.072269225 51.927414931, 6.071624141 51.927465383))

这不应该。

编辑2: 一些可能的视口(viewport)及其结果:

视口(viewport) 1:

LatLngBounds{southwest=lat/lng: (52.367693923958065,6.981273405253887), northeast=lat/lng: (52.3812037840295,6.99942022562027)}

查询:

SELECT * FROM AREAGEOMETRY WHERE ST_CONTAINS(GeomFromText('LINESTRING(52.367693923958065 6.981273405253887, 52.3812037840295 6.981273405253887, 52.3812037840295 6.99942022562027, 52.367693923958065 6.99942022562027, 52.367693923958065 6.981273405253887)'), GeomFromText(AreaGeometryTxt));

预期结果:返回 0 行

实际结果:返回 0 行

视口(viewport) 2:

LatLngBounds{southwest=lat/lng: (52.20765248996001,6.881230026483536), northeast=lat/lng: (52.23028692988024,6.911527253687382)}

查询:

SELECT * FROM AREAGEOMETRY WHERE ST_CONTAINS(GeomFromText('LINESTRING(52.20765248996001 6.881230026483536, 52.23028692988024 6.881230026483536, 52.23028692988024 6.911527253687382, 52.20765248996001 6.911527253687382, 52.20765248996001 6.881230026483536)'), GeomFromText(AreaGeometryTxt));

预期结果:返回大约 25 行

实际结果:返回 0 行

另一个查询相同的视口(viewport):

SELECT * FROM AREAGEOMETRY WHERE ST_Overlaps(GeomFromText('LINESTRING(52.20765248996001 6.881230026483536, 52.23028692988024 6.881230026483536, 52.23028692988024 6.911527253687382, 52.20765248996001 6.911527253687382, 52.20765248996001 6.881230026483536)'), GeomFromText(AreaGeometryTxt));

预期结果:返回大约 25 行

实际结果:返回 1000 行(受 MySQL Workbench 限制)

编辑 3: 以下查询返回我想要的内容:

SELECT * FROM AREAGEOMETRY WHERE ST_Intersects(GeomFromText('Polygon((6.881230026483536 52.20765248996001, 6.881230026483536 52.23028692988024, 6.911527253687382 52.20765248996001, 6.881230026483536 52.20765248996001))'), GeomFromText(AreaGeometryTxt));

似乎我混淆了 Lat/Lng 并且参数顺序错误。

最佳答案

您应该使用 Contains 或 Intersects,这取决于您是要包含边界上的对象,还是要完全包含。 但是,您的主要问题是,如果您查看 Contains documentation,您的几何形状是错误的。如果 g1 包含 g2,您会看到 Contains(g1, g2) 返回 1,因此您需要先放置边界框。

SELECT * FROM AREAGEOMETRY WHERE ST_CONTAINS(ST_GeomFromText('LINESTRING(52.35631327204287 4.881156384944916, 52.38006384519922 4.881156384944916, 52.38006384519922 4.913054890930653, 52.35631327204287 4.913054890930653, 52.35631327204287 4.881156384944916)'), ST_GeomFromText(AreaGeometryTxt));

您可能还想考虑将 AreaGeometryTxt 存储为几何而不是文本,因为这会给您带来两个优势:

  1. 然后你可以输入 spatial index在它上面,随着表大小的增长,这将导致更快的查询时间。

  2. 您将避免每次查询时 GeomFromText 转换的开销,这与第 1 点一起将阻止每次进行全表扫描。

编辑: 我运行了以下查询,使用您说不应返回的行,以及您的原始纬度/经度边界框:

select ST_Overlaps(ST_GeomFromText('POLYGON ((6.071624141 51.927465383, 6.071167939 51.927755315, 6.073816653 51.928513734, 6.07434586 51.928376592, 6.072239751 51.927748706, 6.072269225 51.927414931, 6.071624141 51.927465383))'),
                ST_GeomFromText('POLYGON ((4.881156384944916 52.35631327204287, 4.881156384944916 52.38006384519922, 4.913054890930653 52.38006384519922, 4.913054890930653 52.35631327204287, 4.881156384944916 52.35631327204287))'));

此查询为 overlapsintersectscontains 返回了 0(假)。

关于MySQL - 选择矩形内的所有几何图形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25460938/

相关文章:

php - bind_result() 不绑定(bind)变量

c# - 连接到 Always On 可用性组的只读实例

elasticsearch - 大半径的Elasticsearch地理距离查询优先级

mysql - 结合这两个查询的最佳方法是什么

mysql - DECIMAL(M),允许实现决定 M 的值

php - 嵌套查询未运行,始终返回 null。

mysql - 从两行中,返回包含数字/字符串字符的行

SQL Server - 来自不同表的 CTE 递归 SUM 值

mongodb - MongoMapper 接近 maxDistance - Mongo::OperationFailure:地理值必须是数字:

grid - 如何将地球划分为小网格,以便我可以将每个纬度/经度位置分配给网格?