Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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 definately 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?

Thanks folks,

Tim

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.

share|improve this question
    
can you provide a sample shp file? –  Mario Miler Jun 21 '11 at 7:36
    
no worries.The GSHHS shorelines data I'm using is a 96mb download from here. The world border data I'm using is the World Borders Dataset from thematicmapping.org –  timmy Jun 21 '11 at 9:02
add comment

1 Answer

up vote 6 down vote accepted

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))
share|improve this answer
    
Thanks Mario, it seems I was getting way ahead of myself, instead of properly validating ALL of my input polygons. Your answer was correct - these polygons showed up as invalid when tested with OGR. Interestingly, the looked fine in QGis, but ArcMap showed them as lacking a complete ring. These three polygons all fell on the dateline, and I guess the shapefile geometry didn't count the polygon edge along the dateline. Your solution is a nice and easy way to detect invalid polygons. I'll mark the post as answered. –  timmy Jun 22 '11 at 7:31
    
If you're feeling charitable, do you have any good solutions for the next step in the process, which is correcting the invalid polygons? I tried using OGR's .CloseRing() function, but to no avail. It simply ignored the function call, I think. –  timmy Jun 22 '11 at 7:35
    
I tried to use "buffer trick" (workshops.opengeo.org/postgis-intro/validity.html) with shapely and ogr but with no success. Shapely wont read invalid polygon and ogr wont do buffer operation, currently I don't know why. If I stumble on the answer, I'll let you know. Maybe somebody else has more success with this problem. Sorry. –  Mario Miler Jun 22 '11 at 8:47
    
no worries, thanks for the tips anyways. –  timmy Jun 23 '11 at 0:24
    
I think I've got my polygon validation working now. I think I was using OGR's .CloseRings() function in the wrong way. I was called it as a method of the polygon (i.e. poly.CloseRings() ). Instead, I had to extract the Linear Ring from the polygon, and then run it on that (i.e. lr = poly.GetGeometryRef(0); lr.CloseRings() ). The results are being successfully inserted into PostGIS, and I can use the 3 problem polygons in QGis witj no worries. There is just a bit of a computational cost in checking validity for EVERY polygon. –  timmy Jun 23 '11 at 0:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.