Query SQL per il poligono point-in utilizzando PostgreSQL
-
06-07-2019 - |
Domanda
Ho la seguente tabella semplice:
CREATE TABLE tbl_test
(
id serial NOT NULL,
poly polygon NOT NULL
)
WITH (OIDS=FALSE);
Provo quindi ad inserire una riga con un poligono:
insert into tbl_test values(1, PolyFromText('POLYGON((0 0, 10 10, 10 0, 0 0))'))
Ed imbattersi in questo errore:
colonna " poli " è di tipo poligono ma espressione è di tipo geometria
Che è zoppo. Quindi le mie prime domande sono:
- Devo davvero lanciare?
Comunque, dopo il casting funziona. E ora sto provando a fare una semplice query ST_Contains:
select id, poly from tbl_test where ST_Contains(poly, Point(GeomFromText('POINT(9 2)')))
Che dà l'errore:
ERROR: function st_contains(polygon, point) does not exist
LINE 1: select id, poly from tbl_test where ST_Contains(poly, Point(...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
Cosa dovrei fare?
Le seguenti opere:
select st_contains(st_geomfromtext('POLYGON((0 0, 10 10, 10 0, 0 0))'), st_geomfromtext('POINT(0 0)'))
Ma probabilmente è perché entrambi gli argomenti sono di tipo Geometria. La query effettiva con i dati della tabella non funziona.
Risposta:
Doi! Il problema era che il DB che avevo creato non si basava sul DB del modello Postgis (e quindi non aveva le relative funzioni e tabelle delle colonne della geometria, ecc.). Posso solo sottolineare, in conclusione, che il modo in cui PostGIS richiede di aggiungere centinaia di funzioni, righe e alcune tabelle al proprio DB in modo da avere il supporto GIS è completamente scadente. Rende il backup dello schema molto più complesso ed è molto soggetto a errori (il cielo proibirebbe se si trascura di chiamare AddGeometryColumn e si aggiunge semplicemente una colonna geometrica).
Soluzione
Il poligono è un tipo Postgres fondamentale che PostGIS costruisce sopra. Abilitare le colonne geometriche con la funzione PostGIS selezionare AddGeometryColumn (...)
. Altrimenti stai lavorando con poligoni dritti:
=> create table gt (id int, space polygon);
=> insert into gt values (1, '((2,2),(3,4),(3,6),(1,1))');
INSERT 0 1
=> select point(space) from gt where id = 1;
point
-------------
(2.25,3.25)
(1 row)
Questo è il punto centrale del poligono
=> select circle(space) from gt where id = 1;
circle
--------------------------------
<(2.25,3.25),1.93994028704315>
(1 row)
Questo è il cerchio limite minimo del poligono, espresso come un tipo Postgres circle
. Tutti gli operatori geometrici sono documentati qui: http://www.postgresql.org /docs/8.3/interactive/functions-geometry.html Il poligono di base non ha dati di proiezione, SRID, ecc., quindi, se funziona con PostGIS, è probabilmente solo l'impostazione predefinita dei preset e la fortuna. Ma ovviamente ci sono tonnellate di casi in cui hai semplicemente bisogno di geometria su scala sub-geospaziale.
Altri suggerimenti
Ok, strano, ho scoperto i seguenti lavori di sintassi molto più semplici:
insert into tbl_test (poly) values ('(0,0),(0,10),(10, 10), (0, 0)')
select * from tbl_test where poly @> '(2, 8)'
Ma faccio fatica a capire la differenza tra questi insiemi di funzioni e operatori. Questa sintassi più breve (che non è realmente conforme a OpenGIS) sfrutta gli stessi indici spaziali, ecc.?