【问题标题】:PostGIS: Transform Linestring to LineString ZMPostGIS:将线串转换为线串 ZM
【发布时间】:2021-05-09 14:47:49
【问题描述】:

问题:

我在 Postgres 数据库中保存了一系列几何图形 (LineString),并在几何图形旁边保存了其他信息(速度和时间列)。我想将这三列组合成一个LineString ZM 类型,这样几何图形就从一个二维向量变为一个四维向量。

id geometry speed time
1 LineString_A Int[] Float[]
2 LineString_B Int[] Float[]

问题:

如何最轻松地将geometry (x, y)、speedtime 组合成LineString ZM

【问题讨论】:

    标签: sql postgresql postgis


    【解决方案1】:

    您正在寻找ST_Force4D

    您需要做的就是使用speedtime 列中已有的值来ALTER TABLE,例如

    ALTER TABLE your_table ALTER COLUMN geom TYPE geometry (linestringzm, 4326) 
    USING ST_Force4D(geom,speed,time);
    

    演示(PostGIS 3.1)

    CREATE TABLE t (geom geometry(linestring,4326), speed int, time numeric);
    INSERT INTO t VALUES ('SRID=4326;LINESTRING(30 10,10 30,40 40)'::geometry,42,1230);
    
    ALTER TABLE t ALTER COLUMN geom type geometry (linestringzm, 4326) 
    USING ST_Force4D(geom,speed,time);
    
    SELECT ST_AsText(geom) FROM t;
    
                             st_astext                         
    -----------------------------------------------------------
     LINESTRING ZM (30 10 42 1230,10 30 42 1230,40 40 42 1230)
    

    不同场景(参见 cmets):speedtime 是与 LineString 中的点 1:1 重叠的数组。

    CREATE TABLE t
    (id int, geom geometry(linestring,4326), speed int[], time numeric[]);
    INSERT INTO t VALUES
    (1,'SRID=4326;LINESTRING(30 10, 10 30, 40 40)'::geometry,ARRAY[1,2,3],ARRAY[1230,1231,1232]),
    (2,'SRID=4326;LINESTRING(50 60, 70 80, 90 95)'::geometry,ARRAY[4,5,6],ARRAY[1458,1459,1500]);
    

    由于您不能在ALTER TABLE 语句中使用unnest 数组,因此您只需将数据类型从 LineString 更改为 LineStringZM 并将额外维度临时设置为 0

    ALTER TABLE t ALTER COLUMN geom TYPE geometry (linestringzm, 4326) 
    USING ST_Force4D(geom,0,0);
    

    以下CTE 转储 LineStrings 中的所有点,创建具有 ZM 维度的新点,最后为 UPDATE 查询创建 LineStringZM。

    WITH j AS (
      SELECT id, ST_MakeLine(j.pointzm) AS linestringzm
      FROM (SELECT id, geom AS linestring,
              (ST_DumpPoints(geom)).path AS path,
               ST_MakePoint(ST_X((ST_DumpPoints(geom)).geom),
                           ST_Y((ST_DumpPoints(geom)).geom),
                           unnest(speed),unnest(time)) AS pointzm
      FROM t ORDER BY id,path) j
      GROUP BY id 
    )
    UPDATE t SET geom = j.linestringzm
    FROM j WHERE t.id = j.id;
    
    SELECT id, ST_AsText(geom) FROM t;
    
     id |                       st_astext                        
    ----+--------------------------------------------------------
      1 | LINESTRING ZM (30 10 1 1230,10 30 2 1231,40 40 3 1232)
      2 | LINESTRING ZM (50 60 4 1458,70 80 5 1459,90 95 6 1500)
    (2 rows)
    

    进一步阅读:

    【讨论】:

    • 啊,太好了!不知道ST_Force4D 功能。有一点曲折。 speedtime 列是一个数组(参见上面的示例),它将一对一映射到 LineString 中的每个点。 ST_Force4D 是否仍可用于“压缩”几何图形以及 timespeed 列?
    • @SOK 几何图形是否有 pk 或唯一 ID?恐怕查询会长一点,但我相信这是可能的
    • 不是这样;我在几何旁边有一个 id 列,可能可以使用?
    • @SOK 一个 id 会让事情变得更加安全。如果行不重复,您可以像上面的示例一样使用它(请参阅我的编辑)
    • 谢谢! :) id 列是 PK - 不能用来安全更新它还是我误解了你?
    猜你喜欢
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多