# How to detect/select/identify island polygons

I am generalizing geological maps and as a part of the process I am dealing with "Island Polygons". For that, I first need to identify them or select them.

I already tried Select by Location, by creating another layer from the same layer and used intersect the source layer, which select not only island polygons but polygons which touch the polygon also.

How do I select only Island polygons which are surrounded only by one polygon?

• Very interesting, like a detective story. What do we know about the case? At least 1) Inner polygon A must have exactly one intersecting neighbor 2) Outer polygon B must have at least one hole 3) Difference A-B must be A 4) Difference B-A must be B 5) Symmetric difference about A and B must contain one hole less than B (means that there are no gaps between the boundaries of A and B - is that even important?). I am not sure if this leads to a solution, dear Watson. – user30184 Jan 18 '17 at 21:23
• Another idea: explode polygons into linear rings and add polygon ID as an attribute, as well another attribute to tell if the ring is inner or outer. Find all linear rings which are equal. Of those rings select those who were outer rings in the beginning. Idea does not work if the topology of the polygon layer is not perfect - rings must share all vertices. – user30184 Jan 18 '17 at 21:30
• Or how about this: hole polygon must be covered by the convex hull of the outer polygon. Well, it can be covered even if it is not inside the other polygon, but perhaps not so often. – user30184 Jan 18 '17 at 21:38
• Do the blue polygon overlap the green or do they only share borders? – BERA Jan 20 '17 at 9:21
• Theoretically, they should not overlap and have no gap.. – peter Jan 20 '17 at 13:41

If you have an advanced licence, you can use "polygon to line" and the "IDENTIFY_NEIGHBORS" option. Each contour will then be split in as many lines as you have neighbours. This will also store the left and right ID's (-1 if no neighbour) for each line. You can then summarize the resulting table and find which polyon have only one neighbour (select by attribute on the "count" field)

• I had a similar train of thought using Polygon Neighbors tool and performing a count analysis but found that some polygons at the edge of the data only had one neighbour and if the dataset is not entirely continuous there are times were two polygons sit side by side in isolation (like Haiti and Dominican Republic for example). Although these have one neighbour they are not within another polygon. – Clubdebambos Jan 20 '17 at 10:00
• with polygon to line, the line exists all around. So you will have 2 different ID in the case that you mention. E.g, Haiti will have one set of lines with the FID of -1 (the sea) and one with the FID of Dominican republic. – radouxju Jan 20 '17 at 12:32

This script will interrogate the WKT makeup of the geometry and if the geometry has a hole will fill it in. The output is a feature class with filled-in polygons only, only those that had holes in the first place are copied to the new feature class. You can then use Select By Location to find polygons in your original dataset that are completely within the new filled feature class. This has worked for me but I knew my data had no multipolygons, each feature was a single polygon (you could remove multiparts or explode to achieve this), also if a polygon was within another polygon it was an island and it didn't just sit on top of another polygon.

``````import arcpy

# this is where your dataset resides, change path between ""
arcpy.env.workspace = r"C:\Users\******\Documents\ArcGIS\Default.gdb"

# this is the name of your feature class from the above path
fc = "your_fc"

# grab the WKT values for each feature
# this is a Python dictionary
shape_dict = {}

# for each unique feature we will get the WKT and store in the dictionary
# OBJECTID is a unique id but you can replace this with any unique id field name
with arcpy.da.SearchCursor(fc, ["OBJECTID", "SHAPE@WKT"]) as cursor:
for row in cursor:
shape_dict[row[0]] = row[1]

# this is an empty Python list, we will populate it witt WKT to make new features
feature_list = []

# for each unique feature in the dictionary
for key, value in shape_dict.iteritems():

# get an index list of all open parentheses
po_index = [pos for pos, char in enumerate(value) if char == "("]

# get an index list of all closing parentheses index list
pc_index = [pos for pos, char in enumerate(value) if char == ")"]

# I have found that WKT for polygons seems to always print as
# MULTIPOLYGON (((
# even if a simple polygon. This rebuilds the WKT to remove holes
if len(po_index) > 3:
new_wkt = value[0:pc_index[0]+1] + "))"
new_geom = arcpy.FromWKT(new_wkt)
# and appends the new geom to a list
feature_list.append(new_geom)

# creates a feature class based on the list and call it filled
# this will be put in the same path at the top of the script
arcpy.CopyFeatures_management(feature_list, "filled")

# set this to match the EPSG of the original polygons
# 27700 is for British National Grid, change to suit your projection
arcpy.DefineProjection_management("filled", "27700")
``````
• Thanks for you reply. I am not good at coding, so I am running into error in the line 9. Traceback (most recent call last): File "C:/Users/******hole_finder.py", line 9, in <module> for row in cursor: RuntimeError: A column was specified that does not exist. – peter Jan 31 '17 at 15:33
• Can you please a bit further elaborate your code? – peter Jan 31 '17 at 15:33
• The error you are getting is with the ["OBJECTID", "SHAPE@WKT"] does your data have a field called OBJECTID? you could change this part of the code to match the field name of a unique id. It is important that this field is a unique id field --> ["UNIQUEID", "SHAPE@WKT"] – Clubdebambos Jan 31 '17 at 16:04

Without any test data I'm just thinking out aloud here, so may be a red herring. Assuming you have an Advance licence level I can't but help think the solution using existing tools is some sort of fusion of the ideas posted so far. I was wondering if it was worth the effort to explore the following idea: