我正在使用带有 Spatialite 扩展的 sqlite 来查询地理包文件。
考虑以下测试表,其中每行具有 LineString 或 MultiLineString 几何类型。
sqlite>load_extension('mod_spatialite');
sqlite>select EnableGpkgMode(); -- I'm testing on GeoPackage
sqlite>SELECT id,geom FROM mix AS ft;
1|LINESTRING(10 0,10 60)
2|MULTILINESTRING( (40 0,40 60), (50 0,50 60) )
我需要一个结果,其中每个 MultiLineString 都“分解”为多个 LineString,如下所示:
1|1|LINESTRING(10 0,10 60)
2|2.1|LINESTRING( 40 0,40 60 )
2|2.2|LINESTRING( 50 0,50 60 )
如果可能的话,我希望两者都保留原来的
id
并创建一个新的newid
,如上所示。
以下解决方案适用于PostGIS,但我仍然没有找到Spatialite的解决方案。
postgis=> SELECT
id,
array_to_string(
id || (ST_Dump(geom)).path,
'.'
) AS newid,
ST_AsText((ST_Dump(geom)).geom) AS geom
FROM cubetown.MixLS_1
;
id | newid | geom
----+-------+------------------------
1 | 1 | LINESTRING(10 0,10 60)
2 | 2.1 | LINESTRING(40 0,40 60)
2 | 2.2 | LINESTRING(50 0,50 60)
Sqlite 本质上不支持设置返回函数,例如 ST_Dump。您需要使用一种解决方法,通常是通过递归 CTE。下面的 sqlite/spatialite SQL 语句应该可以解决问题:
WITH RECURSIVE mix (id, geom) AS (VALUES
(1, ST_GeomFromText('LINESTRING(10 0,10 60)')),
(2, ST_GeomFromText('MULTILINESTRING( (40 0,40 60), (50 0,50 60) )'))
), n_max AS (
SELECT max(ST_NumGeometries(geom)) as m
FROM mix
), nlist AS (
SELECT 1 AS n
UNION ALL
SELECT n + 1
FROM nlist, n_max
WHERE n < m
)
SELECT id, n,
CASE
WHEN ST_NumGeometries(geom) = 1 THEN 1
ELSE id || '.' || n
END AS newid,
ST_GeometryN(geom, n) AS geom
FROM mix, nlist
WHERE ST_GeometryN(geom, n) IS NOT NULL;
简短说明: