WKT has a hole in it
I’ve been working with WKT parsing lately and have been having some issues with multipart polygons vs multipolygons.
In section 6.1.11.1 of the OGC’s Simple Feature Access spec, it states:
The exterior boundary LinearRing defines the “top” of the surface which is the side of the surface from which the exterior boundary appears to traverse the boundary in a counter clockwise direction. The interior LinearRings will have the opposite orientation, and appear as clockwise when viewed from the “top”,
So, does this hold true? Let’s test
from osgeo import ogr
# Create outer ring
outRing = ogr.Geometry(ogr.wkbLinearRing)
outRing.AddPoint(0, 9)
outRing.AddPoint(0, 0)
outRing.AddPoint(9, 0)
outRing.AddPoint(9, 9)
outRing.AddPoint(0, 9)
# Create inner ring
innerRing = ogr.Geometry(ogr.wkbLinearRing)
innerRing.AddPoint(2, 7)
innerRing.AddPoint(2, 2)
innerRing.AddPoint(7, 2)
innerRing.AddPoint(7, 7)
innerRing.AddPoint(2, 7)
# Create polygon
poly = ogr.Geometry(ogr.wkbPolygon)
poly.AddGeometry(outRing)
poly.AddGeometry(innerRing)
print poly.ExportToWkt()This is adapted from the Python GDAL/OGR Cookbook, but with unrealistic fake numbers to better see what’s going on.
In this example, both the outer and inner rings are constructed in a counter-clockwise order.
The result?

So it doesn’t look like we care about the order, but rather just about overlap.
Let’s throw out section 6.1.11.1.c (no overlaps), and see what we and come up with:
from osgeo import ogr
# Ring 1
r1 = ogr.Geometry(ogr.wkbLinearRing)
r1.AddPoint(0, 9)
r1.AddPoint(0, 0)
r1.AddPoint(9, 0)
r1.AddPoint(9, 9)
r1.AddPoint(0, 9)
# Ring 2
r2 = ogr.Geometry(ogr.wkbLinearRing)
r2.AddPoint(-2, 7)
r2.AddPoint(-2, 2)
r2.AddPoint(7, 2)
r2.AddPoint(7, 7)
r2.AddPoint(-2, 7)
# Ring 2
r3 = ogr.Geometry(ogr.wkbLinearRing)
r3.AddPoint(-4, 6)
r3.AddPoint(-4, 3)
r3.AddPoint(11, 3)
r3.AddPoint(11, 6)
r3.AddPoint(-4, 6)
# Create polygon
poly = ogr.Geometry(ogr.wkbPolygon)
poly.AddGeometry(r1)
poly.AddGeometry(r2)
poly.AddGeometry(r3)
print poly.ExportToWkt()
If we actually want overlapping polygons, we’d need to define it as a MULTIPOLYGON:
from osgeo import ogr
# Ring 1
r1 = ogr.Geometry(ogr.wkbLinearRing)
r1.AddPoint(0, 9)
r1.AddPoint(0, 0)
r1.AddPoint(9, 0)
r1.AddPoint(9, 9)
r1.AddPoint(0, 9)
p1 = ogr.Geometry(ogr.wkbPolygon)
p1.AddGeometry(r1)
# Ring 2
r2 = ogr.Geometry(ogr.wkbLinearRing)
r2.AddPoint(-2, 7)
r2.AddPoint(-2, 2)
r2.AddPoint(7, 2)
r2.AddPoint(7, 7)
r2.AddPoint(-2, 7)
p2 = ogr.Geometry(ogr.wkbPolygon)
p2.AddGeometry(r2)
# Ring 2
r3 = ogr.Geometry(ogr.wkbLinearRing)
r3.AddPoint(-4, 6)
r3.AddPoint(-4, 3)
r3.AddPoint(11, 3)
r3.AddPoint(11, 6)
r3.AddPoint(-4, 6)
p3 = ogr.Geometry(ogr.wkbPolygon)
p3.AddGeometry(r3)
# Create multipolygon
multipoly = ogr.Geometry(ogr.wkbMultiPolygon)
multipoly.AddGeometry(p1)
multipoly.AddGeometry(p2)
multipoly.AddGeometry(p3)
print multipoly.ExportToWkt()