2017-06-27 71 views
5

Próbuję wykonać operację przestrzenną za pomocą sqlalchemy i geoalchemy2 w Pythonie 3.5. Mam tabelę z punktami jako atrybut geom. Przeczytałem już tabelę i postępuję zgodnie z instrukcjami dotyczącymi dokumentacji:Błąd podzbioru przestrzennego i bazy danych PostGIS

metadata = MetaData() 
table = Table('table', 
       metadata, autoload=True, 
       schema = "schema", 
       autoload_with=engine) 
print(table.columns) 

To poprawnie zwraca nazwę kolumn w mojej tabeli. Teraz chcę utworzyć przestrzenny podzbiór danych, wybierając tylko punkty znajdujące się w obiekcie POLYGON. Próbowałem z ST_Contains i ST_Intersection:

# Create session for queries 
Session = sessionmaker(bind=engine) 
session = Session() 

#SELECT * FROM table: 
q = session.query(table).filter(table.c.geom.ST_Intersects(func.GeomFromEWKT(<POLYGON>))) 

wielokąt jest geometria WKT z określonym SRID=4326. Próbowałem już z różnymi formami tego samego wielokąta, ale żaden z nich nie zadziałał. Podczas wykonywania zapytania pojawia się następujący komunikat o błędzie:

(psycopg2.InternalError) geometry contains non-closed rings 
HINT: "...140.965576171875 -11.11288507032144))" <-- parse error at position 166 within geometry 

Gdzie zawodzę?

+0

umieścić swój wielokąta WKT. Jak wskazuje błąd, pierścień prawdopodobnie nie jest zamknięty (na przykład pierwszy i ostatni punkt każdego pierścienia musi być taki sam) – JGH

+0

'wkt_string =" POLYGON ((141.0205078125 -9.166331387642987, 143.602294921875 -9.155485188844034, 143.67919921875 -11.112885070321443, 140.965576171875 -11.11288507032144)) "' Jest obiektem POLYGON. Jak pan powiedział, POLYGON rzeczywiście nie jest ważny. Mimo to próbowałem użyć 'sqlalchemy.sql.func.ST_MakeValid', a problem nadal występuje. Jakieś pomysły? –

Odpowiedz

2

Wielokąt, którego używasz, nie jest zamknięty. Pierwsza i ostatnia współrzędna muszą być takie same. Zmień go na adres:

wkt_string = "POLYGON((141.0205078125 -9.166331387642987, 
         143.602294921875 -9.155485188844034, 
         143.67919921875 -11.112885070321443, 
         140.965576171875 -11.11288507032144, 
         141.0205078125 -9.166331387642987))" 

Alternatywnie, można construct the polygon z linii i automatycznie dodać brakujący punkt

SELECT ST_MakePolygon(
     ST_AddPoint(foo.open_line, ST_StartPoint(foo.open_line))) 
FROM (
    SELECT ST_GeomFromText(
      'LINESTRING(141.0205078125 -9.166331387642987, 
         143.602294921875 -9.155485188844034, 
         143.67919921875 -11.112885070321443, 
         140.965576171875 -11.11288507032144)') 
       As open_line) 
    As foo;