在postgis中插入查询中的表单

时间:2016-08-29 08:09:54

标签: postgresql postgis

我尝试从查询中在表geofield中插入多边形。表geofield的定义如下:

CREATE TABLE geofield(id SERIAL PRIMARY KEY, field GEOMETRY);

insert into geofield(field) values (myfield)
SELECT
    'POLYGON(('||cast((select lat from coordinates where id=1)as varchar)||' '||
      cast((select lon from coordinates where id=1)as varchar)||','||
      cast((select lat from coordinates where id=2)as varchar)||' '||
      cast((select lon from coordinates where id=2)as varchar)||','||
      cast((select lat from coordinates where id=3)as varchar)||' '||
      cast((select lon from coordinates where id=3)as varchar)||','||
      cast((select lat from coordinates where id=4)as varchar)||' '||
      cast((select lon from coordinates where id=4)as varchar)||','||
      cast((select lat from coordinates where id=1)as varchar)||' '||
      cast((select lon from coordinates where id=1)as varchar)||'))') AS myfield;

SELECT单独返回我:

POLYGON((46.744628268759314 6.569952920654968,46.74441692818192 6.570487107359068,46.74426116111054 6.570355867853787,46.74447250168793 6.569821681149689,46.744628268759314 6.569952920654968))

但它不起作用,我也尝试使用ST_GeomFromText但结果相同。

2 个答案:

答案 0 :(得分:2)

字符串采用正确的WKT格式,因此不是问题。问题是您的经度和纬度值是否相反,INSERT的语法是错误的。您还应该首先将字符串转换为geometry

INSERT INTO geofield(field)
    SELECT ST_GeomFromText(
        'POLYGON(('||cast((select lat from coordinates where id=1)as varchar)||' '||
          cast((select lon from coordinates where id=1)as varchar)||','||
          cast((select lat from coordinates where id=2)as varchar)||' '||
          cast((select lon from coordinates where id=2)as varchar)||','||
          cast((select lat from coordinates where id=3)as varchar)||' '||
          cast((select lon from coordinates where id=3)as varchar)||','||
          cast((select lat from coordinates where id=4)as varchar)||' '||
          cast((select lon from coordinates where id=4)as varchar)||','||
          cast((select lat from coordinates where id=1)as varchar)||' '||
          cast((select lon from coordinates where id=1)as varchar)||'))');

但这非常浪费,不适合较大的多边形。只要您的多边形由单个环组成,您就可以做到这一点,这将更快,更不容易出错:

INSERT INTO geofield(field)
    SELECT ST_GeomFromText('POLYGON((' || coords.c || ',' || coord1.c || '))', 4326)
    FROM
        ( SELECT string_agg(lon::text || ' ' || lat::text, ',' ORDER BY id) AS c
          FROM coordinates ) coords,
        ( SELECT lon::text || ' ' || lat::text AS c
          FROM coordinates
          WHERE id = 1 ) coord1;

第一个子查询将所有坐标串在一起,而第二个只获取第一个坐标以关闭多边形。使用尽可能多的积分。

答案 1 :(得分:2)

我会避免使用文本连接,而是使用普通PostGIS functions代替:

SELECT
    /* Make a polygon from the linestring */
    ST_MakePolygon(
        /* Close the polygon */
        ST_AddPoint(
            t.linestring,
            ST_StartPoint(t.linestring)
        )
    )
FROM (
    SELECT
        /* Aggregate into a linestring */
        ST_MakeLine(ST_MakePoint(c.lon, c.lat) ORDER BY c.id) AS linestring
    FROM coordinates AS c
) t
;

关注prior question后,如果您愿意,可以直接从json取回:

SELECT
    /* Make a polygon from the linestring */
    ST_MakePolygon(
        /* Close the polygon */
        ST_AddPoint(
            t.linestring,
            ST_StartPoint(t.linestring)
        )
    )
FROM (
    SELECT
        /* Aggregate into a linestring */
        ST_MakeLine(ST_MakePoint(c.lon, c.lat) ORDER BY c.id) AS linestring
    FROM
    (
        SELECT
            e.id,
            (e.element->>'lat')::numeric AS lat,
            (e.element->>'lon')::numeric AS lon
        FROM
            field AS f,
            json_array_elements(f.data->'vertices') WITH ORDINALITY AS e(element, id)
    ) AS c
) t
;