Pomoc w geometrii wielokąta PostGIS - niezamknięte pierścienie

10

Wziąłem kopię super-nikczemnej książki „Python Geospatial Development” Erika Westry ( link do Amazon ) i pracuję nad tym. Obecnie uczy mnie, jak ładować dane wybrzeża GSHHS z pliku kształtu do bazy danych PostGIS, przygotowując się do budowy geoprzestrzennej aplikacji internetowej.

Mój problem jest następujący: kiedy próbuję zaimportować dane GSHHS do PostGIS, jest on odrzucany, ponieważ wielokąty linii brzegowej nie są uważane za „prawidłowe”. W szczególności pojawia się komunikat o błędzie opisujący niektóre (ale nie wszystkie) wielokąty linii brzegowej jako „niezamknięte pierścienie”.

Rozumiem, że ten błąd próbuje mi powiedzieć, że pierwszy i ostatni punkt wielokąta nie są takie same. Jednak to po prostu nieprawda. Zbadałem reprezentację WKT wielu wielokątów i są one poprawne. Oni na pewno się zaczynać i kończyć w tym samym współrzędnej.

Wieloboki są wyodrębniane z plików kształtów za pomocą biblioteki OGR i eksportowane do każdego elementu wielokąta do WKT. Próbowałem odtworzyć wielokąt za pomocą Shapely i eksperymentowałem z WKB, ale bezskutecznie. I nie udało się załadować te same dane w PostGIS jak stół MULTIPOLYGON za pomocą ładowacza shp2pgsql.

Zastanawiałem się, czy ktoś tam:
(a) być może użył tej samej książki, utknął przy tym samym problemie i czy ma dla mnie odpowiedź?
(b) napotkał podobny problem i znalazł rozwiązanie?
(c) w przeciwnym razie, czy istnieją jakieś porady dotyczące najlepszych praktyk w celu zapewnienia prawidłowej geometrii przed załadowaniem do PostGIS?

AKTUALIZACJA: kolega zasugerował, że problem „niezamkniętych pierścieni” może być tylko objawem innego problemu. Możliwe, że moja konfiguracja PostGIS / PostgreSQL ma ograniczenia wielkości (przy transakcjach wstawiania, otrzymanych pakietach, ciągach tekstowych itp.).

Ponieważ używam bardzo długich wielokątów WKT jako danych wejściowych, PostGIS może wycinać je zbyt wcześnie, aby umożliwić ukończenie każdego wielokąta. Przetestuję to jutro, ale wydaje się prawdopodobne. Moje wstawienie granic kraju akceptowało tylko niektóre rekordy, a nie inne. Z pamięci zaakceptowano geometrie dla małych narodów wyspiarskich, takich jak Antigua (a więc prawdopodobnie miały krótkie reprezentacje WKT).

Może to być bardziej wątek administracyjny bazy danych PostGIS niż nieprawidłowy wątek geometrii.

Timmy
źródło
czy możesz podać przykładowy plik shp?
Mario Miler
nie martw się. Dane linii brzegowej GSHHS, z których korzystam, to 96 MB pobierania stąd . Dane na temat granic światowych, których używam, to zestaw danych World Borders z thematicmapping.org
timmy

Odpowiedzi:

6

Sprawdziłem twoje dane i przykład książki, problem polega na tym, że w danych przetwarzanych w książce są trzy nieprawidłowe wielokąty:

GSHHS_l_L1.shp

ID = 92-W

POLYGON ((-180.0 71.514793999999995,-179.69008299999999 71.577888999999999,-178.648889 71.577416999999997,-178.40644399999999 71.549916999999994,-177.406306 71.244167000000004,-177.877444 71.022889000000006,-179.500111 70.863749999999996,-179.93011100000001 70.979583000000005,-180.0 70.962072000000006))

ID = 486-W

POLYGON ((-180.0 -16.799126,-179.84419399999999 -16.691278,-179.80041700000001 -16.789193999999998,-179.850472 -16.878361000000002,-180.0 -16.959561))

GSHHS_l_L2.shp

ID = 7333-W

POLYGON ((-180.0 65.393473,-179.76583299999999 65.428332999999995,-179.95416700000001 65.385555999999994,-179.90972199999999 65.316389,-180.0 65.321635))

Ponieważ jest to przykład, najłatwiej byłoby usunąć te wielokąty ze zbioru danych lub po prostu dodać instrukcję if w kodzie

if geometry.IsValid():
       cursor.execute("INSERT INTO gshhs (level, geom) VALUES (%s, ST_GeomFromText(%s, 4326))", (level, wkt))
Mario Miler
źródło
Dzięki Mario, wydaje mi się, że wyprzedzałem siebie, zamiast poprawnie sprawdzać WSZYSTKIE moje wielokąty wejściowe. Twoja odpowiedź była prawidłowa - te wielokąty okazały się nieprawidłowe podczas badania OGR. Co ciekawe, QGis wyglądał dobrze, ale ArcMap pokazał, że brakuje pełnego pierścienia. Te wszystkie wielokąty spadły na linię danych i wydaje mi się, że geometria pliku kształtu nie policzyła krawędzi wielokąta wzdłuż linii danych. Twoje rozwiązanie to przyjemny i łatwy sposób na wykrycie nieprawidłowych wielokątów. Oznaczę post jako odpowiedź.
timmy
Jeśli czujesz się charytatywny, czy masz jakieś dobre rozwiązania na następny etap procesu, jakim jest poprawianie nieprawidłowych wielokątów? Próbowałem użyć funkcji OGR .CloseRing (), ale bezskutecznie. Myślę, że po prostu zignorował wywołanie funkcji.
timmy
Próbowałem użyć „trick trick” ( workshop.opengeo.org/postgis-intro/validity.html ) ze zgrabnym i ogrodowym, ale bezskutecznie. Foremnie nie będę czytał nieprawidłowego wielokąta i ogr nie zrobię operacji buforowania, obecnie nie wiem dlaczego. Jeśli natknę się na odpowiedź, dam ci znać. Być może ktoś inny odnosi większe sukcesy w tym problemie. Przepraszam.
Mario Miler
Myślę, że moja walidacja wielokąta działa teraz. Myślę, że niewłaściwie użyłem funkcji OGR .CloseRings (). Zostałem nazwany jako metoda wielokąta (tj. Poly.CloseRings ()). Zamiast tego musiałem wyodrębnić pierścień liniowy z wielokąta, a następnie uruchomić go na tym (tj. Lr = poly.GetGeometryRef (0); lr.CloseRings ()). Wyniki są pomyślnie wstawiane do PostGIS i mogę używać 3 problematycznych wielokątów w QGis bez obaw. Sprawdzanie poprawności KAŻDEGO wielokąta wiąże się tylko z niewielkimi kosztami obliczeniowymi.
timmy