如何在Spatialite中分解几何图形,例如将每个MultiLineString特征转换为多个LineString特征

问题描述 投票:0回答:1

我正在使用带有 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 spatialite
1个回答
0
投票

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;

简短说明:

  • 关键字 RECURSIVE 必须直接放在WITH之后,即使实际的递归 CTE“nlist”要晚得多
  • CTE“n_max”获取任何(多)线串中线串的最大数量,存储在“m”列中
  • 递归 CTE“nlist”生成一个记录集,其中包含从 1 到 n_max.m 的连续记录(其功能相当于集合返回函数)
  • 最后的主 SELECT 使用 ST_GeometryN 通过使用表“mix”和“nlist”之间的交叉连接从 MultiLinestring 中提取第 n 个线串
  • 在许多情况下,原始几何图形中的实际 LineString 数量少于请求的第 n 个,从而导致 NULL 几何图形。这些通过 WHERE 子句从最终结果集中排除。
© www.soinside.com 2019 - 2024. All rights reserved.