2016-08-29 39 views
1

我嘗試從查詢中插入表格geofield中的多邊形。該表geofield的定義是這樣的:從postgis中的查詢插入表格

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但同樣的結果也tryed。

+2

合適「INSERT INTO ... SELECT」的語法不包含「VALUES」部分。所以:'INSERT INTO geofield(field)SELECT什麼「。 – jcaron

+0

此外,指定實際的錯誤或行爲,你得到的肯定是一個要求。 「它不工作」只是沒用。 – jcaron

+0

非常感謝你!這是VALUES誰鎖定了我,我花了這麼多時間來試圖找出它:/ –

回答

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 
; 
+0

謝謝!最後,我使用你最後的解決方案。這是更高效的:)現在我處理另一個json文件,並將其放置在多邊形中,並感謝您的幫助,我認爲我可以自己管理它。 –

+0

@gabrielchauviere:不客氣。而且,你可以將答案標記爲接受(在兩個問題中)......) – MatheusOl

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; 

第一個子查詢字符串所有座標一起,而第二隻獲取第一個座標來關閉多邊形。與儘可能多的點共同工作。

+0

謝謝,我永遠不會想到這一點(我不是SQL專家),它工作得很好! –

+0

唯一的錯誤是ORDER BY誰返回一個錯誤:列「coordinates.id」必須出現在GROUP BY子句中或用於聚合函數中。我刪除它,它的工作原理 –

+1

首先,你使用'ORDER BY'的方式也不能保證順序,你應該在*'string_agg'函數調用中使用'ORDER BY' *,而不是在查詢中使用它(這是無用的在查詢上)。其次,你正在聚合並獲得「id」未聚合,但是你沒有使用「GROUP BY」(第一個的修復也應該解決這個問題,只要將'ORDER BY'從查詢移到聚合函數調用,就像我做的那樣在我的答案) – MatheusOl