Continued from yesterday’s post: Bizarre GeoServer WMS Rendering
Both the NJ Landscape Project habitat data and the Municipalities data are complex. It is hard to pinpoint a rendering issue when the data is very complex. I prepared a reference data set composed of a few multipart features. You can download the reference shapefile here.
I created the polygon features in ArcGIS Desktop as a shapefile. I then imported the shapefile into my PostGIS database twice, once using PG_GEOMETRY & ArcSDE, the other using OGR. I then prepared two WMS layers in GeoServer, one based off of the SDE import and one from the OGR import. The SDE import causes GeoServer to improperly render the data. GeoServer can render the OGR import without issue.
I exported the geometries of each table as WKT: hexagons imported using SDE; hexagons imported using OGR. Note that the coordinates are essentially the same, but the “wrappers” around the coordinates are different. You can also tell that it is a rendering issue; in GeoServer’s layer preview mode, you can click on the OpenLayers map to identify a feature. Clicking on one of the erroneous polygons yields no results.
It appears that GeoServer is improperly handling MULTIPOLYGON features. POLYGON features (with multiple parts) are properly rendered. This is also what is being suggested in the support forum.
One other issue I encountered was that OGR would not import the shapefile without the -nlt flag set.
$ ogr2ogr -f "PostgreSQL" PG:"pg connection string" ./testing.shp -nln test_hexagons_ogr Warning 1: Geometry to be inserted is of type Multi Polygon, whereas the layer geometry type is Polygon. Insertion is likely to fail ERROR 1: INSERT command for new feature failed. ERROR:Â new row for relation "test_hexagons_ogr" violates check constraint "enforce_geotype_wkb_geometry" Command: INSERT INTO "test_hexagons_ogr" ("wkb_geometry" , "id") VALUES ('snip'::GEOMETRY, 3) RETURNING "ogc_fid" ERROR 1: Terminating translation prematurely after failed translation of layer testing (use -skipfailures to skip errors) $ ogr2ogr -f "PostgreSQL" PG:"pg connection string" ./testing.shp -nln test_hexagons_ogr -nlt POLYGON $
John, as I suggested in the support forum, one cause of this issue appears to be that the PostGIS GEOMETRY_COLUMNS.TYPE metadata is not set correctly for the (SDE?) layer. If the loading method is loading MultiPolygon geometries into the table, but setting the TYPE to POLYGON, this is creating an invalid PostGIS configuration. In turn this is confusing GeoServer a bit, causing it to read the MultiPolygon as a Polygon. This is definitely not optimal behaviour, but at least is perhaps excusable. Really the loader tool needs to be fixed to create the table configuration correctly.
Note that PostGIS ver. 2.0 is a lot stricter about keeping the GEOMETRY_COLUMNS in synch with the actual contents of the table, so this issue probably could not occur.
Another thing you should be aware of is that although the OGR import looks fine in GeoServer, it has actually created invalid geometries in the table. I think this is because the -nlt flag looks like it has crushed the MultiPolygons into single (invalid) Polygons. GeoServer is happy enough to render these invalid shapes (yay!), and they happen to look reasonable, but this is deceptive.
The original shapefile looks fine, however – it contains a mix of valid Polygons and MultiPolygons, as expected. Not sure why OGR throws an error when loading it. Did you perhaps define the target table beforehand, with a TYPE of Polygon (leaving OGR no choice but to complain when trying to import MultiPolygon data)?
Another way of looking at this is that both OGR and GeoServer try hard to respect the PostGIS TYPE metadata, to the extent of reporting errors and forcing geometry conversion (even if invalid). SDE is not quite as concerned about this.
I’m not an OGR expert, but it seems like you should use the -nlt FORCE_TO_MULTI option in a case like this (loading a shapefile to PostGIS).
I plan on writing up some more detailed thoughts on the issues I encountered with loading the data. I don’t know why OGR fails if the -nlt flag is not set – I’m creating the table on load and nothing is predefined. I’ll have to try the FORCE_TO_MULTI flag on a new dataset. It also doesn’t surprise me that ArcSDE mishandles PostGIS data, though it is funny that SDE makes valid geometries but bungles the geometry_columns definition, while OGR can make invalid geometries through -nlt coercion, and that “works” for GeoServer. It’s like a perfect storm of GIS quirks.
Thanks again for your help getting this issue sorted.
“Perfect storm of GIS quirks” was my thought as well! And it is amusing (as well as annoying) that every system involved manages to bungle a different aspect of the data handling! Guess that’s why we get paid the big $$$…
Good luck with sorting out a workflow that works.