Actualizar la fila de la base de datos con puntos que caen dentro de polígonos

10

Tengo un DB PostGIS / Postgresql que tiene dos tablas. Uno con geometrías de puntos y el otro que representa los límites de los países como polígonos. Me gustaría agregar el nombre del país con el que cada punto se cruza con cada fila en mi tabla de puntos. Tal vez como una gran consulta de actualización. Creo que esto es posible utilizando SQL directo, pero no sé por dónde empezar. Cualquier consejo sobre esto sería muy apreciado ...

AdamEstrada
fuente

Respuestas:

9

Otra opción, sin necesidad de la función.

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

Sospecho (aunque no lo he probado) que esto será más rápido que usar una función anidada como en su ejemplo.

Mi salida de la ejecución se explica (espero que se vea similar). Si tiene más resultados de Seq Scan, entonces eso es algo a tener en cuenta, tal vez los índices no estén configurados correctamente.

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)"
Kelso
fuente
¡Increíble! Esto parece ser mucho más rápido también. ¡Gracias!
AdamEstrada
4

OK ... Hice un poco de pirateo y descubrí que una FUNCIÓN SQL me llevó casi todo el camino. ¿Alguien tiene alguna idea sobre llevar esto al puente?

 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
AdamEstrada
fuente