dustfurn

polygon with holes + arcpy.AsShape is broken?

Discussion created by dustfurn on Oct 6, 2011
Latest reply on Oct 7, 2011 by dustfurn
Hi,

I was searching for a way to programmatically create a polygon with a hole, as there isn't any obvious way of doing this in the documentation, I started fumbling around on my own.  I came up with this test script:

gjPolygonWithHole  = {
    "type": "Polygon",
    "coordinates": [
                    [[-88.684979400000032, 38.154361399999985], [-88.666690199999962, 38.154329800000042], [-88.67131005539963, 38.154337782166039], [-88.675899944207302, 38.154345712555887], [-88.675899944207302, 38.150691003182175], [-88.67131005539963, 38.150691003182175], [-88.67131005539963, 38.147037172952786], [-88.675899944207302, 38.147037172952786], [-88.685066075460313, 38.147037172952786], [-88.684979400000032, 38.154361399999985]],
                    [[-88.680463013034853, 38.152519617763254], [-88.680463013034853, 38.15068957953018], [-88.678182297717754, 38.15068957953018], [-88.678182297717754, 38.152519617763254], [-88.680463013034853, 38.152519617763254]]]
    }

def main():

    outputShapeDir = r"c:\temp"
    outputShapeFile = r"test.shp"
    spatialRef = r'X:\Nadel&Gussman\McLeansboro\Sections.prj'
    newFC = arcpy.CreateFeatureclass_management( outputShapeDir, outputShapeFile, "POLYGON", "", "", "", spatialRef )
    cur = arcpy.InsertCursor(newFC)
    
    array = arcpy.Array()
    point = arcpy.Point()
    # Create a list to store the features
    features = []
    # Read the coordinates
    for part in gjPolygonWithHole["coordinates"]:
        for coordPair in part:
            point.X = coordPair[0]
            point.Y = coordPair[1]
            array.add(point)
        
    feat = cur.newRow()
    feat.shape = array
    cur.insertRow( feat )

if __name__ == '__main__':
    import arcpy
    arcpy.env.overwriteOutput = True
    main()


Amazingly, it works (I'm not really sure how, since I don't do anything to separate the interior from the exterior, other than suddenly switch winding order):


Unfortunately, this doesn't work in all polygon-with-a-hole cases that I am working with. 

So...I noticed the seemingly useful "AsShape" functionality here.  Specifically, (notice the AsShape example on doing just this at the bottom of the page i linked).

I put together a little sample script to test this:
gjPolygonWithHole  = {
    "type": "Polygon",
    "coordinates": [
                    [[-88.684979400000032, 38.154361399999985], [-88.666690199999962, 38.154329800000042], [-88.67131005539963, 38.154337782166039], [-88.675899944207302, 38.154345712555887], [-88.675899944207302, 38.150691003182175], [-88.67131005539963, 38.150691003182175], [-88.67131005539963, 38.147037172952786], [-88.675899944207302, 38.147037172952786], [-88.685066075460313, 38.147037172952786], [-88.684979400000032, 38.154361399999985]],
                    [[-88.680463013034853, 38.152519617763254], [-88.680463013034853, 38.15068957953018], [-88.678182297717754, 38.15068957953018], [-88.678182297717754, 38.152519617763254], [-88.680463013034853, 38.152519617763254]]]
    }

def main():

    outputShapeDir = r"c:\temp"
    outputShapeFile = r"test.shp"
    spatialRef = r'X:\Nadel&Gussman\McLeansboro\Sections.prj'
    newFC = arcpy.CreateFeatureclass_management( outputShapeDir, outputShapeFile, "POLYGON", "", "", "", spatialRef )
    cur = arcpy.InsertCursor(newFC)
    
    feat = cur.newRow()
    feat.shape = arcpy.AsShape( gjPolygonWithHole )
    cur.insertRow( feat )

if __name__ == '__main__':
    import arcpy
    arcpy.env.overwriteOutput = True
    main()


FAILURE:


The hole is completely ignored.  Any clue as to why?

Regarding holes, I found this thread, and adapted their method to my test script + data.  It almost works:


Here's my example code:
gjPolygonWithHole  = {
    "type": "Polygon",
    "coordinates": [
                    [[-88.684979400000032, 38.154361399999985], [-88.666690199999962, 38.154329800000042], [-88.67131005539963, 38.154337782166039], [-88.675899944207302, 38.154345712555887], [-88.675899944207302, 38.150691003182175], [-88.67131005539963, 38.150691003182175], [-88.67131005539963, 38.147037172952786], [-88.675899944207302, 38.147037172952786], [-88.685066075460313, 38.147037172952786], [-88.684979400000032, 38.154361399999985]],
                    [[-88.680463013034853, 38.152519617763254], [-88.680463013034853, 38.15068957953018], [-88.678182297717754, 38.15068957953018], [-88.678182297717754, 38.152519617763254], [-88.680463013034853, 38.152519617763254]]]
    }

def main():

    outputShapeDir = r"c:\temp"
    outputShapeFile = r"test.shp"
    spatialRef = r'X:\Nadel&Gussman\McLeansboro\Sections.prj'
    newFC = arcpy.CreateFeatureclass_management( outputShapeDir, outputShapeFile, "POLYGON", "", "", "", spatialRef )
    cur = arcpy.InsertCursor(newFC)
    
    array = arcpy.Array()
    point = arcpy.Point()
    # Create a list to store the features
    features = []
    # Read the coordinates
    for part in gjPolygonWithHole["coordinates"]:
        for coordPair in part:
            point.X = coordPair[0]
            point.Y = coordPair[1]
            array.add(point)
        null_point = arcpy.Point()
        array.add(null_point)
    feat = cur.newRow()
    feat.shape = arcpy.Polygon( array )
    cur.insertRow( feat )

if __name__ == '__main__':
    import arcpy
    arcpy.env.overwriteOutput = True
    main()


Any ideas why this doesn't work?  Why is creating geometry such a hassle with arcpy?  Why do some methods work and some do not?

Most likely I'm missing something obvious...
Thanks,
Dustin

Outcomes