Jak korzystać z ST_Intersection?

15

Oto krótkie podsumowanie tego, co próbuję zrobić: mam 3 tabele w Postgresie, „a” i „b”, każda ma kolumnę Wielokąt, a „c” ma kolumnę Punkt. Usiłuję uzyskać przecięcia geometrii między „a”, „b” i „c” oraz wyświetlić takie geometrie na warstwie wektorowej OpenLayers.

Wiem już, jak wyświetlać dowolną geometrię z łańcucha w OpenLayers, ale mam problemy z funkcją ST_Intersection PostGIS, robię to:

SELECT ST_Intersection(a.geom, b.geom) as inter from a, b;

gdzie a.geom i b.geom są kolumnami geometrii i pojawia się następujący komunikat o błędzie:

NOTICE:  TopologyException: found non-noded intersection between 515172 2.14408e+06, 497067 2.13373e+06 and 501321 2.13546e+06, 471202 2.14843e+06 500621 2.13576e+06 
ERROR:  GEOS Intersection() threw an error!

Próbowałem także wyrazić wynikową geometrię jako tekst za pomocą ST_AsText w następujący sposób:

SELECT ST_AsText(ST_Intersection(a.geom, b.geom)) as inter from a, b;

ale wysyła mi ten komunikat o błędzie:

HINT: No function matches the given name and argument types. You might need to add explicit type casts.

Nie wiem, co robię źle, chcę tylko, aby WKT wielokątów wyświetlał je na OpenLayers, oto jak wyświetlam geometrię z WKT:

                    var in_options = {
                        'internalProjection': new OpenLayers.Projection("EPSG:4326"),
                        'externalProjection': new OpenLayers.Projection("EPSG:4326")
                    }; 

                    var fea= new OpenLayers.Format.WKT(in_options).read(data); //data is the string with the WKT
                    vectorLayer.addFeatures([fea]); //this piece of code works great
                    map.zoomToExtent(bounds);

AKTUALIZACJA: Próbowałem następnego:

SELECT ST_Intersection(a.geom, b.geom) as intersect_ab FROM a INNER JOIN b ON 
ST_Intersection(a,b) WHERE ST_Overlaps(a.geom, b.geom) 
AND ST_isvalid(a.geom)='t' AND ST_isvalid(b.geom)='t';

ale pojawia się następny komunikat o błędzie:

ERROR: Function st_intersection(a,b) does not exist.
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

Dodałem isvalid, aby sprawdzić, czy sprawdzane są tylko poprawne wielokąty, ale to mówi, że błąd znajduje się w ST_Intersection (a, b), oba a, b i c mają ten sam SRID, więc jestem naprawdę zdezorientowany, przepraszam, jeśli jestem pytam za dużo, ale jestem całkiem nowy w PostGIS, więc mam nadzieję, że nie przeszkadzam zbytnio. Dzięki.

Uriel
źródło
1
Co SELECT PostGIS_Full_Version();zwraca
Mike T
POSTGIS = "1.4.0" GEOS = "3.1.0-CAPI-1.5.0" PROJ = "Rel. 4.7.1, 23 września 2009 r." USE_STATS
Uriel

Odpowiedzi:

8

Domyślam się, że nie powiedzie się, jeśli skrzyżowanie zwróci NULL. Powinieneś więc dodać klauzulę where sprawdzającą, czy rzeczywiście istnieje skrzyżowanie, zanim spróbujesz utworzyć WKT.

podmrok
źródło
Próbowałem: SELECT ST_Intersection (a.geom, b.geom) jako intersect_ab OD INNER JOIN b ON ST_Intersection (a, b) WHERE ST_Overlaps (a.geom, b.geom) AND ST_isvalid (a.geom) = 't „AND ST_isvalid (b.geom) =„ t ”; ale zwrócił ten sam błąd: ** BŁĄD: Funkcja przekrój st (a, b) nie istnieje. WSKAZÓWKA: Żadna funkcja nie pasuje do podanych nazw i typów argumentów. Może być konieczne dodanie rzutowania typu jawnego. ** Naprawdę utknąłem w tym, jeśli możesz mi pomóc, naprawdę to docenię.
Uriel
Wypróbuj podsumowanie (a.geom) i streszczenie (b.geom), aby sprawdzić wartości.
podmroku
podsumowanie -------------------------- Wielokąt [BS] z 1 pierścieniem pierścień 0 ma 4 punkty Wielokąt [BS] z 1 pierścieniem pierścień 0 ma 5 punkty Polygon [BS] z 1 pierścieniem pierścień 0 ma 10 punktów
Uriel
Tak, powinno to być ST_Intersection (a.geom, b.geom), a nie ST_Intersection (a, b)
podmrok
6

Wskazówką jest

ERROR: Function st_intersection(a,b) does not exist.
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

Jak pokazuje komunikat o błędzie, nie można w ten sposób używać st_intersection. Podsumowując inne odpowiedzi, powinieneś użyć czegoś takiego:

SELECT ST_Intersection(a.geom, b.geom) as intersect_ab 
FROM a INNER JOIN b ON ST_Intersects(a.geom,b.geom)
WHERE ST_isvalid(a.geom)='t' AND ST_isvalid(b.geom)='t';

AFAIK nie ma sensu używać st_overlaps i st_intersects w tym samym zdaniu, ponieważ są one dość podobne .

Francisco Puga
źródło
4

Testuję między różnymi warstwami wielokątów i nie powiodło się, jeśli przynajmniej jedna z nich ma nieprawidłową geometrię. Czy sprawdziłeś ważność swoich wielokątów za pomocą ST_isvalid (the_geom)? To może być klucz.

Fabien Ancelin
źródło
Próbowałem: SELECT ST_Intersection (a.geom, b.geom) jako intersect_ab OD INNER JOIN b ON ST_Intersection (a, b) WHERE ST_Overlaps (a.geom, b.geom) AND ST_isvalid (a.geom) = 't „AND ST_isvalid (b.geom) =„ t ”; ale zwrócił ten sam błąd: ** BŁĄD: Funkcja przekrój st (a, b) nie istnieje. WSKAZÓWKA: Żadna funkcja nie pasuje do podanych nazw i typów argumentów. Może być konieczne dodanie rzutowania typu jawnego. ** Naprawdę jestem zagubiony, dlaczego to nie działa
Uriel
2

Wypróbuj coś takiego:

SELECT  ST_Intersection(a.geom, b.geom) As intersect_ab
    FROM a INNER JOIN b ON ST_Intersection(a,b)
    WHERE ST_Overlaps(a.geom, b.geom)
    ;

Źródło

CaptDragon
źródło
Próbowałem też, ale zwraca ten sam komunikat o błędzie: WSKAZÓWKA: Żadna funkcja nie pasuje do podanej nazwy ani typów argumentów. Może być konieczne dodanie rzutowania typu jawnego.
Uriel
Co powiesz na użycie „INNER JOIN b ON ST_Intersection (a.geom, b.geom)”?
CaptDragon
Mówi: BŁĄD: argument JOIN / ON musi być typu logicznego, a nie typu geometrii.
Uriel
shizer ... coś musi być nie tak z danymi lub coś, ponieważ ten typ zapytania działa dla mnie.
CaptDragon
Dodałem AND ST_isvalid (a.geom) = 't' AND ST_isvalid (b.geom) = 't'; na końcu, aby ocenić tylko poprawne geometrie, ale to mówi mi, że błąd jest w tym st_intersection (a, b)
Uriel
1

Próbowałem wykluczyć nieprawidłowe geometrie, ale to nie działało, więc ostatecznie musiałem usunąć każdą nieprawidłową geometrię, a następnie użyć tego:

SELECT ST_AsText(ST_Intersection(a.geom, b.geom)) as intersect_ab FROM a,b 
WHERE ST_Overlaps(a.geom, b.geom) AND ST_isvalid(a.geom)='t' AND ST_isvalid(b.geom)='t';

Jak widać, pominąłem część ST_Intersection (a, b), a to zadziałało świetnie, jestem trochę smutny, ponieważ nie mogłem znaleźć sposobu na wykluczenie nieprawidłowej geometrii z mojej selekcji, w każdym razie dzięki wszystkim za pomoc tu.

Uriel
źródło
0

Raz miałem ten problem.

<pre>NOTICE:  TopologyException: found non-noded intersection between xxx, xxxx and xxx, xxx  ERROR:  GEOS Intersection() threw an error!</pre>

Za pomocą tej metody udało mi się rozwiązać ten błąd.
- Użyj QGIS
- Dodaj warstwę wektorową z bazy danych
- Weź punkt z komunikatu o błędzie i wyszukaj go w QGIS
   Można użyć „QuickWKT” (wtyczki) do znalezienia go
- Następnie zobaczysz problem z oznaczaniem linii
- Włącz tryb edycji
- Wybierz „narzędzie węzła”, aby wyświetlić zielony węzeł (problem z węzłem)
- Odsuń węzeł od nakładającego się węzła
- Zapisz zmiany

Ruthe
źródło