2

I have a number of features which I would like to individually Union with itself to remove internal gaps. The best way I've thought of so far is to use cursors and iterate through, essentially performing the Union as many times as I have rows in my feature class.

Is there a tool or other approach that might be more efficient?

Note I do not want to Union everything in the feature class together - the individual results should stay separate and should have as many rows output as I originally input.

I'd like to perform this in one of Esri's products/ArcPy (ArcGIS Pro preferred over ArcMap).

Per @Keagan Allan I tried the dissolve tool but wound up with the same polygon - the interior gap was not removed. A polygon example is below. (Note the view is filtered to only show this polygon - see second image.)

Feature: buffered line output with a gap

The second image shows that the polygon is overlapping several other polygons which need to be kept separate (and if they have gaps, those gaps should be removed as well.)

many overlapping polygons, one of them with a gap

UPDATE: The "Eliminate Polygon Part" (Advanced license) tool worked. I don't know whether something similar to this tool is available in other license levels or open source GIS, as replicability is a concern. (It may be better to use the repeated union for that reason.)

arcpy.management.EliminatePolygonPart("input_layer", "output_layer_eliminate", "PERCENT", "0 SquareMeters", 99, "CONTAINED_ONLY")

UPDATE2: I tried @FelixIP's method in arcpy (Python 2.7) and see a change in the outer border but it's no longer following the line. In the below screenshot, the greenish line is the resulting polygon from the code below, and the cyan is the original polygon.

I did the "check for gaps" and "remove gaps" separately because I wanted to examine the results of the first operation before proceeding, but theoretically could combine the two.

# Identify whether a polygon has an interior gap
with arcpy.da.UpdateCursor("infc", ["uniqueid", "SHAPE@", "HasInnerRing"]) as cur:
    for row in cur:
        print(row[0])
        for part in row[1]:
            partlist = [pnt for pnt in part]
            #print(partlist)
            if None in partlist:
                print("{} has inner ring".format(row[0]))
                row[2] = 1
            else:
                row[2] = 0
        cur.updateRow(row)


# Remove gaps, if they have been identified in previous step
with arcpy.da.UpdateCursor("infc", ["uniqueid", "SHAPE@", "HasInnerRing"]) as cur:
    for row in cur:
        if row[2] == 1:
            part = row[1].getPart(0)
            pgon = arcpy.Polygon(part)
            row[1] = pgon
        cur.updateRow(row)

enter image description here

12
  • 1
    Have you considered the dissolve tool? Assigning common field values to rows you want combined and then dissolving? Commented May 18, 2018 at 15:35
  • Thanks @Keagan Allen. I tried the dissolve tool but wound up with the same polygon - the interior gap was not removed.
    – SMiller
    Commented May 18, 2018 at 16:41
  • Ok. That gap is no data. You just need to delete the vertices to close the polygon. Commented May 18, 2018 at 16:42
  • I can type up a proper work flow if you want a more robust technique? Commented May 18, 2018 at 16:43
  • That would be appreciated; I will need to do this for several thousand locations so I'm looking for a method I can automate easily (not via a manual edit session.)
    – SMiller
    Commented May 18, 2018 at 16:48

2 Answers 2

4

This field calculator expression (to run on field Shape) works on single part polygons. Use add geometry attributes (parts count) to find out if this is a case. If not, use multipart to single part tool. In any case first test on backup version of your set.

def outRing(shp):
 part=shp.getPart(0)
 pgon=arcpy.Polygon(part)
 return pgon
#-------------
outRing( !Shape!)

Keep this in mind when dealing with arcs getPart() method returns incorrect geometry from buffer in ArcGIS

7
  • Great! I'll give this a try and accept / update once tested.
    – SMiller
    Commented May 19, 2018 at 3:13
  • I received the following series of errors: ERROR 999999: Error executing function. Unable to update area or length field in response to shape update Failed to execute (CalculateField). I tried on both the original unprojected dataset (WGS84) and projected (USA Contiguous Albers Equal Area)
    – SMiller
    Commented May 21, 2018 at 13:16
  • FelixIP's solution works on shapefiles but not GDB layers. Still testing.
    – SMiller
    Commented May 21, 2018 at 14:30
  • With fgdb start editing first.
    – FelixIP
    Commented May 21, 2018 at 18:31
  • Do I need to swap to Desktop for this stage? For Pro: "ArcGIS Pro automatically starts an edit session when you modify existing data or create new data. Saving or discarding your edits automatically stops the edit session. Any subsequent edits you make resumes the edit session until you save or discard your edits. There are no buttons to start or stop an edit session"
    – SMiller
    Commented May 21, 2018 at 18:48
1

Create an envelope around your study area, ensuring the main polygon extent is covered.

Run an erase between the polygon you want to fill and the envelope.

The erased layer should have a mix of big and small polygons. The small polygons are the gaps.

With the erased layer, create a field called area and calculate the area of the polygon.

Decide the area threshold (the maximum area you decide is a gap in the polygon).

Run the select by attributes and select all polygons smaller than the threshold.

With the selected polygons, run a merge with the original polygon.

Select these gap polygons again from the merged polygon you just created.

With these gaps selected run the Aggregate tool.

The gaps should be gone.

NOTE: I think the erase tool is Advanced only. Oh can maybe try ET Geowizards in Arc or try find the erase tool in QGIS.

9
  • I don't think this will work for my situation, but I appreciate the response. (There are thousands of polygons to do this on, so it sounds more efficient to select each polygon one-by-one and Union disallowing gaps.)
    – SMiller
    Commented May 18, 2018 at 17:44
  • Give it a go. Or maybe post a pic of your dataset. Commented May 18, 2018 at 17:55
  • Erase is easily implemented using Union and Select when only a Basic license is available.
    – PolyGeo
    Commented May 18, 2018 at 19:50
  • @PolyGeo thank you. I will look into t. I always wondered how ET Geo was able to get the same result. Commented May 18, 2018 at 20:05
  • gis.stackexchange.com/a/133268/115
    – PolyGeo
    Commented May 18, 2018 at 20:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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