Aggiorna la riga del database con i punti che rientrano nei poligoni


10

Ho un DB PostGIS / Postgresql che contiene due tabelle. Uno con geometrie puntuali e l'altro che rappresenta i confini del paese come poligoni. Vorrei aggiungere il nome del paese con cui ogni punto si interseca con ciascuna riga della mia tabella dei punti. Forse come una grande query di aggiornamento. Penso che sia possibile farlo usando l'SQL diretto ma non so da dove cominciare. Qualsiasi consiglio su questo sarebbe molto apprezzato ...

Risposte:


9

Un'altra opzione, senza la necessità della funzione

update points set country = t1.country from 
(
    select points.oid, countries.name as country from
    countries INNER JOIN points on st_contains(countries.wkb_geometry,points.wkb_geometry)
) t1 
where t1.oid = points.oid

Sospetto (anche se non ho testato) che questo sarà più veloce rispetto all'utilizzo di una funzione nidificata come nel tuo esempio.

Il mio output da corsa spiega (spero che il tuo aspetto sia simile). Se hai ottenuto più risultati Seq Scan, allora è qualcosa da guardare, forse gli indici non sono abbastanza impostati correttamente.

Update on points  (cost=1.18..29.40 rows=121 width=129)"
  ->  Nested Loop  (cost=1.18..29.40 rows=121 width=129)"
        Join Filter: _st_contains(countries.geometry, public.points.geometry)"
        ->  Hash Join  (cost=1.18..2.37 rows=28 width=220)"
              Hash Cond: (public.points.oid = public.points.oid)"
              ->  Seq Scan on points  (cost=0.00..1.08 rows=28 width=114)"
              ->  Hash  (cost=1.08..1.08 rows=28 width=110)"
                    ->  Seq Scan on points  (cost=0.00..1.08 rows=28 width=110)"
        ->  Index Scan using "countries_Idx" on countries  (cost=0.00..0.91 rows=1 width=414)"
              Index Cond: (geometry && public.points.geometry)"

Eccezionale! Anche questo sembra essere molto più veloce. Grazie!
AdamEstrada,

4

OK ... Ho fatto un po 'di hacking e ho scoperto che una FUNZIONE SQL mi ha portato quasi ovunque. Qualcuno ha qualche idea su come portarlo sul ponte?

 CREATE OR REPLACE FUNCTION getcountry (
       country_geom geometry
    ) RETURNS TABLE(country text) AS $$
        SELECT b.name as country FROM  
                    geonames d, world_borders b WHERE
                    $1 && b.wkb_geometry 
                    AND intersects($1, b.wkb_geometry) ;
  $$ LANGUAGE SQL;

UPDATE geonames 
    SET country = val
    FROM (SELECT getcountry(point_geom) FROM geonames) AS val
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.