mor*_*t32 5 sqlite subquery spatial
我目前正在学习使用空间访问方法进行查询优化。我正在阅读空间食谱中的示例并被困在这里 http://www.gaia-gis.it/gaia-sins/spatialite-cookbook/html/pp-adjacent.html
根据教程,为了找到距离小于 1 公里的人口对,我们必须执行此查询
SELECT pp1.name AS "PopulatedPlace #1",
GeodesicLength(MakeLine(pp1.geometry, pp2.geometry)) AS "Distance (meters)",
pp2.name AS "PopulatedPlace #2"
FROM populated_places AS pp1,
populated_places AS pp2
WHERE GeodesicLength(
MakeLine(pp1.geometry, pp2.geometry)) < 1000.0
AND pp1.id <> pp2.id
AND pp2.ROWID IN (
SELECT pkid
FROM idx_populated_places_geometry
WHERE pkid MATCH RTreeDistWithin(
ST_X(pp1.geometry),
ST_Y(pp1.geometry), 0.02))
ORDER BY 2;
Run Code Online (Sandbox Code Playgroud)
由于不再使用地理回调函数 RTree*** 而引发错误。我检查了这个更新,这已被虚拟空间索引的使用所取代。我们必须使用表单的子查询
SELECT ROWID
FROM SpatialIndex
WHERE
f_table_name = <table_name>
AND search_frame = <some_geometry>
Run Code Online (Sandbox Code Playgroud)
所以我测试了这个
SELECT pp1.name AS "PopulatedPlace #1",
GeodesicLength(MakeLine(pp1.geometry, pp2.geometry)) AS "Distance (meters)",
pp2.name AS "PopulatedPlace #2"
FROM populated_places AS pp1,
populated_places AS pp2
WHERE GeodesicLength(
MakeLine(pp1.geometry, pp2.geometry)) < 1000.0
AND pp1.id <> pp2.id
AND pp2.ROWID IN (
SELECT ROWID
FROM SpatialIndex
WHERE
f_table_name ='populated_places'
AND search_frame = pp1.geometry)
ORDER BY 2;
Run Code Online (Sandbox Code Playgroud)
结果集大错特错
PopulatedPlace #1 Distance (meters) PopulatedPlace #2
Ariano 0.000000 Ariano
Campolongo Maggiore 0.000000 Campolongo Maggiore
Campolongo Maggiore 0.000000 Campolongo Maggiore
Campolongo Maggiore 0.000000 Campolongo Maggiore
Campolongo Maggiore 0.000000 Campolongo Maggiore
Campolongo Maggiore 0.000000 Campolongo Maggiore
Campolongo Maggiore 0.000000 Campolongo Maggiore
Ariano 0.000000 Ariano
Run Code Online (Sandbox Code Playgroud)
有人可以解释这种行为和/或给出一个正确使用虚拟空间索引以获得距离查询的例子吗?
小智 0
我知道已经晚了,但我最近偶然发现了同样的问题。它在您的示例中不起作用,因为 search_frame 参数充当过滤器并且相当于函数 RTreeIntersect。
在这里,由于您使用一个点,它只会寻找相交的点(当使用它们的边界框时)。这个想法是使用以 pp1 点为中心的边界框,其边长为所需距离。
SELECT pp1.name AS "PopulatedPlace #1",
GeodesicLength(MakeLine(pp1.geometry, pp2.geometry)) AS "Distance (meters)",
pp2.name AS "PopulatedPlace #2"
FROM populated_places AS pp1,
populated_places AS pp2
WHERE GeodesicLength(
MakeLine(pp1.geometry, pp2.geometry)) < 1000.0
AND pp1.id <> pp2.id
AND pp2.ROWID IN (
SELECT ROWID
FROM SpatialIndex
WHERE
f_table_name ='populated_places'
AND search_frame = ST_Expand(pp1.geometry, 500.0)
ORDER BY 2;
Run Code Online (Sandbox Code Playgroud)
为此,我们只需使用函数 ST_Expand,它返回包围几何图形的边界框(这里是点)并将其均匀扩展。
因此,我们按如下方式过滤搜索:仅考虑以 pp1 为中心、边长为 1000 米的正方形内的 pp2 点。
归档时间: |
|
查看次数: |
354 次 |
最近记录: |