Come usare ST_Intersection?


15

Ecco un breve riassunto di ciò che sto cercando di fare: ho 3 tabelle in Postgres, 'a' e 'b', ognuna ha una colonna Poligono e 'c' ha una colonna Punto. Quello che sto cercando di fare qui è di ottenere le intersezioni delle geometrie tra 'a', 'b' e 'c' e di visualizzare tali geometrie su un livello vettoriale OpenLayers.

So già come visualizzare qualsiasi tipo di geometria da una stringa in OpenLayers, ma ho problemi con la funzione ST_Intersection di PostGIS, sto facendo questo:

SELECT ST_Intersection(a.geom, b.geom) as inter from a, b;

dove a.geom e b.geom sono entrambe le colonne della geometria e viene visualizzato questo messaggio di errore:

NOTICE:  TopologyException: found non-noded intersection between 515172 2.14408e+06, 497067 2.13373e+06 and 501321 2.13546e+06, 471202 2.14843e+06 500621 2.13576e+06 
ERROR:  GEOS Intersection() threw an error!

Inoltre ho provato ad esprimere la geometria risultante come testo usando ST_AsText in questo modo:

SELECT ST_AsText(ST_Intersection(a.geom, b.geom)) as inter from a, b;

ma mi invia questo messaggio di errore:

HINT: No function matches the given name and argument types. You might need to add explicit type casts.

Non so cosa sto facendo di sbagliato, voglio solo far visualizzare il WKT dei poligoni su OpenLayers, ecco come visualizzo una geometria da un WKT:

                    var in_options = {
                        'internalProjection': new OpenLayers.Projection("EPSG:4326"),
                        'externalProjection': new OpenLayers.Projection("EPSG:4326")
                    }; 

                    var fea= new OpenLayers.Format.WKT(in_options).read(data); //data is the string with the WKT
                    vectorLayer.addFeatures([fea]); //this piece of code works great
                    map.zoomToExtent(bounds);

AGGIORNAMENTO: ho provato il prossimo:

SELECT ST_Intersection(a.geom, b.geom) as intersect_ab FROM a INNER JOIN b ON 
ST_Intersection(a,b) WHERE ST_Overlaps(a.geom, b.geom) 
AND ST_isvalid(a.geom)='t' AND ST_isvalid(b.geom)='t';

ma ricevo il messaggio di errore successivo:

ERROR: Function st_intersection(a,b) does not exist.
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

Ho aggiunto l'isvalido per verificare che vengano valutati solo i poligoni validi, ma sta dicendo che l'errore si trova nella ST_Intersection (a, b), sia a, b che c hanno lo stesso SRID, quindi sono davvero confuso, mi dispiace se lo sono chiedendo troppo, ma sono abbastanza nuovo con PostGIS, quindi spero di non disturbarti molto. Grazie.


1
Cosa SELECT PostGIS_Full_Version();ritorna?
Mike T,

POSTGIS = "1.4.0" GEOS = "3.1.0-CAPI-1.5.0" PROJ = "Rel. 4.7.1, 23 settembre 2009" USE_STATS
Uriel

Risposte:


8

La mia ipotesi sarebbe che fallisce se l'intersezione restituisce NULL. Quindi dovresti aggiungere una clausola where controllando se esiste effettivamente un'intersezione prima di provare a creare il WKT.


Ho provato questo: SELECT ST_Intersection (a.geom, b.geom) come intersect_ab FROM a INNER JOIN b ON ST_Intersection (a, b) WHERE ST_Overlaps (a.geom, b.geom) AND ST_isvalid (a.geom) = 't 'AND ST_isvalid (b.geom) =' t '; ma ha restituito lo stesso errore: ** ERRORE: la funzione st_intersection (a, b) non esiste. SUGGERIMENTO: nessuna funzione corrisponde al nome e ai tipi di argomento indicati. Potrebbe essere necessario aggiungere cast di tipo esplicito. ** Sono davvero bloccato in questo, se mi puoi aiutare lo apprezzerò davvero.
Uriel,

Prova il sommario (a.geom) e il sommario (b.geom) per esaminare i valori.
underdark

sommario -------------------------- Poligono [BS] con 1 anello anello 0 ha 4 punti Poligono [BS] con 1 anello anello 0 ha 5 punti punti Poligono [BS] con 1 anello L'anello 0 ha 10 punti
Uriel

Sì, dovrebbe essere ST_Intersection (a.geom, b.geom) non ST_Intersection (a, b)
underdark

6

L'indizio è

ERROR: Function st_intersection(a,b) does not exist.
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

Come dice il messaggio di errore, non puoi usare st_intersection in quel modo. Riassumendo le altre risposte dovresti usare qualcosa del genere:

SELECT ST_Intersection(a.geom, b.geom) as intersect_ab 
FROM a INNER JOIN b ON ST_Intersects(a.geom,b.geom)
WHERE ST_isvalid(a.geom)='t' AND ST_isvalid(b.geom)='t';

AFAIK non ha senso usare st_overlaps e st_intersects nella stessa frase in quanto sono abbastanza simili .


4

Ho testato tra diversi strati di poligoni e non è riuscito se c'è almeno una geometria non valida in uno dei livelli. Hai verificato la validità dei tuoi poligoni usando ST_isvalid (the_geom)? Potrebbe essere la chiave.


Ho provato questo: SELECT ST_Intersection (a.geom, b.geom) come intersect_ab FROM a INNER JOIN b ON ST_Intersection (a, b) WHERE ST_Overlaps (a.geom, b.geom) AND ST_isvalid (a.geom) = 't 'AND ST_isvalid (b.geom) =' t '; ma ha restituito lo stesso errore: ** ERRORE: la funzione st_intersection (a, b) non esiste. SUGGERIMENTO: nessuna funzione corrisponde al nome e ai tipi di argomento indicati. Potrebbe essere necessario aggiungere cast di tipo esplicito. ** Sono davvero perso sul perché non funziona
Uriel

2

Prova qualcosa del genere:

SELECT  ST_Intersection(a.geom, b.geom) As intersect_ab
    FROM a INNER JOIN b ON ST_Intersection(a,b)
    WHERE ST_Overlaps(a.geom, b.geom)
    ;

fonte


Ho provato anche quello, ma restituisce lo stesso messaggio di errore: SUGGERIMENTO: nessuna funzione corrisponde al nome e ai tipi di argomenti indicati. Potrebbe essere necessario aggiungere cast di tipo esplicito.
Uriel,

Che ne dici se usi "INNER JOIN b ON ST_Intersection (a.geom, b.geom)"?
CaptDragon,

Indica: ERRORE: l'argomento di JOIN / ON deve essere di tipo booleano, non di tipo geometrico.
Uriel,

shizer ... ci deve essere qualcosa di sbagliato nei dati o qualcosa del genere perché questo tipo di query funziona per me.
CaptDragon,

Ho aggiunto AND ST_isvalid (a.geom) = 't' AND ST_isvalid (b.geom) = 't'; alla fine per valutare solo le geometrie valide ma mi sta dicendo che l'errore è in quella st_intersection (a, b)
Uriel

1

Ho provato ad escludere le geometrie non valide ma non ha funzionato, quindi alla fine ho dovuto eliminare tutte le geometrie non valide e quindi utilizzare questo:

SELECT ST_AsText(ST_Intersection(a.geom, b.geom)) as intersect_ab FROM a,b 
WHERE ST_Overlaps(a.geom, b.geom) AND ST_isvalid(a.geom)='t' AND ST_isvalid(b.geom)='t';

Come puoi vedere ho omesso la parte ST_Intersection (a, b) e questo ha funzionato benissimo, sono un po 'triste perché non sono riuscito a trovare un modo per escludere qualsiasi geometria non valida dalla mia selezione, comunque grazie a tutti per l'aiuto qui fuori.


0

Ho avuto questo problema una volta.

<pre>NOTICE:  TopologyException: found non-noded intersection between xxx, xxxx and xxx, xxx  ERROR:  GEOS Intersection() threw an error!</pre>

Sono stato in grado di risolvere questo errore utilizzando questo metodo.
- Usa QGIS
- Aggiungi layer vettoriale dal tuo database
- Prendi il punto dal messaggio di errore e
   cercalo in QGIS "QuickWKT" (plug-in) può essere usato per trovarlo
- Quindi vedrai il problema del linestring
- Attiva la modalità di modifica
- Seleziona "Strumento nodo" per mostrare il nodo verde (problema nodo)
- Allontana il nodo dal nodo sovrapposto
- Salva le modifiche

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.