Aktualisieren Sie die Datenbankzeile mit Punkten, die in Polygone fallen


10

Ich habe eine PostGIS / Postgresql-Datenbank mit zwei Tabellen. Eine mit Punktgeometrien und die andere, die Ländergrenzen als Polygone darstellt. Ich möchte den Ländernamen, mit dem sich jeder Punkt schneidet, zu jeder Zeile in meiner Punktetabelle hinzufügen. Vielleicht als eine große Update-Abfrage. Ich denke, dass dies mit Straight SQL möglich ist, aber ich weiß nicht, wo ich anfangen soll. Jeder Rat hierzu wäre sehr dankbar ...

Antworten:


9

Eine weitere Option, ohne die Funktion zu benötigen

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

Ich vermute (obwohl ich nicht getestet habe), dass dies schneller ist als die Verwendung einer verschachtelten Funktion wie in Ihrem Beispiel.

Meine Ausgabe vom Laufen erklären (hoffentlich sieht es ähnlich aus). Wenn Sie mehr Seq Scan-Ergebnisse haben, sollten Sie sich das ansehen. Vielleicht sind die Indizes nicht richtig eingerichtet.

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)"

Genial! Dies scheint auch viel schneller zu sein. Vielen Dank!
AdamEstrada

4

OK ... Ich habe ein bisschen gehackt und festgestellt, dass eine SQL-Funktion mich den größten Teil des Weges dorthin bringt. Hat jemand irgendwelche Gedanken darüber, dies auf die Brücke zu bringen?

 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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.