ArcPy – Solving Incorrect Geometry Returns from getPart() Method in Buffers

arcpybuffer

I created 4 basic polygons:

Sample data

And ran this script:

import arcpy
infc = r'D:\Scratch\POLYGONS.shp'
d=arcpy.Describe(infc)
SR=d.spatialReference
with arcpy.da.SearchCursor(infc, ("SHAPE@","LABEL")) as rows:
    for shp,label in rows:
        buf=shp.buffer(5)
        n=buf.partCount
        for i in xrange (n):
            prt=buf.getPart(i)
            pgon=arcpy.Polygon(prt,SR)
            arcpy.AddMessage((int(buf.area),int(pgon.area),label))

OUTPUT:

[68735, 68707, u'RECTANGLE']
[29892, 29846, u'TRIANGLE']
[47832, 47832, u'CIRCLE']
[55126, 55060, u"'COMPLEX'"]

Can anybody
help me to understand the result?


I modified the code:

import arcpy
infc = r'....POLYGONS.shp'
outBuffer=r'...OUT_BUFFER.shp'
outPart=r'...SCRARCH\OUT_PART.shp'
d=arcpy.Describe(infc)
SR=d.spatialReference
with arcpy.da.SearchCursor(infc, ("SHAPE@","LABEL")) as rows:
    for shp,label in rows:
        buf=shp.buffer(5)
        arcpy.CopyFeatures_management(buf, outBuffer)
        n=buf.partCount
        for i in xrange (n):
            prt=buf.getPart(i)
            pgon=arcpy.Polygon(prt,SR)
            arcpy.CopyFeatures_management(pgon, outPart)
            break

to check actual shapes. When working with geometries it would be expected that the first part of a single part polygon would be identical to the polygon itself.

This is an overlay of input and outputs and you can see where mismatch happened – at the corners:

enter image description here

Something sinister is happening inside arcpy.Polygon, it simplifies the shape using some sort of 'logic' handling true curves.

NOTE:

  • same result obtained with exporting to geodatabase
  • both outputs came up with input's spatial reference

This buffer issue is a part of a bigger job, where I have to deal with potentially multi-part polygons. The workaround I am using is explosion of buffer to single parts, using arcgis tool. It works, but ridiculously slow due to number of iterations. Why on earth the abc of geometry handling is not working?

Well, as it happens, after posting I realised I shouldn't be bothered with parts of the buffer, because label point of polygon is placed inside larger part of multipart polygon.

Best Answer

The sinister behaviour is not occurring at arcpy.Polygon as suggested by @FelixIP, it is occuring at the getPart() bit of code. I tweaked your code and ran it on a dataset with just a triangle. I had set the coordinate system to be British National Grid when I had created it.

import arcpy
arcpy.env.addOutputsToMap = True
infc = "tri"
outBuffer=r'c:\scratch\OUT_BUFFER.shp'
outPart=r'c:\scratch\OUT_PART.shp'
d=arcpy.Describe(infc)
SR=d.spatialReference
with arcpy.da.SearchCursor(infc, ("SHAPE@","LABEL")) as rows:
    for shp,label in rows:
        buf=shp.buffer(5)
        arcpy.CopyFeatures_management(buf, outBuffer)
        n=buf.partCount
        for i in xrange (n):
            prt=buf.getPart(i)
            # Print out sequence of XY points
            print(prt)
            for p in prt:
                print str(p.X ) + "," + str(p.Y)
            pgon=arcpy.Polygon(prt,SR)
            arcpy.CopyFeatures_management(pgon, outPart)
            break

Zooming into one corner of the buffer of the triangle in edit mode we can see many vertices:

Vertices of buffer

Infact there are 42 vertices for the whole geometry. My adjusted code reading the output of the getPart() returns only 11.

Clipped part

So the bug is occuring when the getPart() is called to return the Array of Points.

Related Question