[GIS] Help with PostGIS polygon geometry – non-closed rings

ogrpostgispythonwell-known-text

I've picked up a copy of the super-wicked book 'Python Geospatial Development' by Erik Westra (Amazon link), and I'm working through it. Currently, it's teaching me to load GSHHS coastline data from a shapefile into a PostGIS database, in preparation for building a geospatial web app.

My problem is this: when I try to import the GSHHS data into PostGIS, it is rejected due to the coastline polygons not being considered 'valid'. Specifically, I am given an error message described some (but not all) of the coastline polygons as being 'non-closed rings'.

I understand that this error is trying to tell me that the first and last points of the polygon are not the same. However, this is simply not true. I have examined the WKT representation of many of the polygons, and they are correct. They definitely begin and end with the same co-ordinate.

The polygons are extracted from the shapefiles using the OGR library, and exporting each polygon feature to WKT. I've tried reconstituting the polygon via Shapely, and experimented with WKB, but to no avail. I have been able to load the same data into PostGIS as a MULTIPOLYGON table, using the shp2pgsql loader.

I was wondering if anybody out there had:
(a) perhaps used the same book, got stuck at the same problem, and has the answer for me?
(b) has encountered a similar problem, and found a solution?
(c) failing that, has some 'best practice' advice for ensuring valid geometry before loading into PostGIS?

UPDATE: a colleague has suggested that the 'non-closed rings' problem may just be a symptom of another problem. It is possible that my PostGIS/PostgreSQL configuration has size limits (on insert transactions, packets received, text strings, etc).

As I'm using very long WKT polygons as input, PostGIS may be cutting them too early to allow each polygon to complete. I will test it out tomorrow, but it does sound likely. My insert of country borders was only accepting some records and not others. From memory, the accepted geometries were for small island nations like Antigua (and so probably had short WKT representations).

So this could end up being more of a PostGIS database admin thread, rather than an invalid geometry thread.

Best Answer

I have looked at your data and the book example, the problem is that there are three invalid polygons in data that are processed in the book:

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

Because this is an example it would be easiest to delete those polygons from the dataset or just add one if statement in you code

if geometry.IsValid():
       cursor.execute("INSERT INTO gshhs (level, geom) VALUES (%s, ST_GeomFromText(%s, 4326))", (level, wkt))
Related Question