Perbarui baris basis data dengan titik yang termasuk dalam poligon

10

Saya memiliki DB PostGIS / Postgresql yang memiliki dua tabel di dalamnya. Satu dengan geometri titik dan lainnya yang mewakili batas negara sebagai poligon. Saya ingin menambahkan nama negara yang saling bersinggungan dengan setiap baris di tabel titik saya. Mungkin sebagai salah satu permintaan pembaruan besar. Saya pikir ini mungkin dilakukan dengan menggunakan SQL langsung tapi saya tidak tahu harus mulai dari mana. Setiap saran tentang ini akan sangat dihargai ...

AdamEstrada
sumber

Jawaban:

9

Pilihan lain, tanpa perlu fungsi

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

Saya menduga (walaupun saya belum menguji) bahwa ini akan lebih cepat daripada menggunakan fungsi bersarang seperti pada contoh Anda.

Keluaran saya dari menjalankan jelaskan (semoga penampilan Anda mirip). Jika Anda mendapat lebih banyak hasil Pemindaian Seq, maka itu adalah sesuatu untuk dilihat, mungkin indeks tidak cukup diatur dengan benar.

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
sumber
Luar biasa! Ini tampaknya jauh lebih cepat juga. Terima kasih!
AdamEstrada
4

OK ... Saya melakukan sedikit peretasan dan menemukan bahwa FUNGSI SQL membuat saya hampir sampai di sana. Adakah yang memiliki pemikiran untuk membawa ini ke jembatan?

 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
sumber