now... if we would hash it like this and compare both featureclasses...
import arcpy
def main():
fc1 = r"C:\GeoNet\FeatureCompare\test.gdb\polygons1"
fc2 = r"C:\GeoNet\FeatureCompare\test.gdb\polygons2"
# create dictionary for each featureclass
flds1 = getFields(fc1)
dct_fc1 = {getHashFeature(r, r[1], flds1):r[0] for r in arcpy.da.SearchCursor(fc1, flds1)}
flds2 = getFields(fc2)
dct_fc2 = {getHashFeature(r, r[1], flds2):r[0] for r in arcpy.da.SearchCursor(fc2, flds2)}
for h2, oid2 in dct_fc2.items():
if h2 in dct_fc1:
print "OID {0} from fc2 corresponds to OID {1} in fc1".format(oid2, dct_fc1[h2])
else:
print "OID {0} from fc2 has no match with features in fc1".format(oid2)
for h1, oid1 in dct_fc1.items():
if h1 in dct_fc2:
print "OID {0} from fc1 corresponds to OID {1} in fc2".format(oid1, dct_fc2[h1])
else:
print "OID {0} from fc1 has no match with features in fc2".format(oid1)
def getFields(fc):
"""Get all fields without fields to exclude like OID, Geometry, """
flds_exclude = getFieldsExclude(fc)
flds = [fld.name for fld in arcpy.ListFields(fc) if fld.name not in flds_exclude]
flds.insert(0,"SHAPE@")
flds.insert(0,"OID@")
return flds
def getFieldsExclude(fc):
"""List of fields to exclude"""
lst = []
props = ["OIDFieldName", "shapeFieldName", "areaFieldName", "lengthFieldName"]
desc = arcpy.Describe(fc)
for prop in props:
if hasattr(desc, prop):
lst.append(eval("desc.{0}".format(prop)))
return lst
def getHashFeature(row, geom, flds):
"""Hash feature (without OID, length and area fields)"""
# row: OBJECTID, SHAPE, other flds
# md5, sha1, sha224, sha256, sha384, sha512
import hashlib
dct = {}
for fld in flds[2:]:
dct[fld] = row[flds.index(fld)]
dct[flds[1]] = geom.JSON
h = hashlib.sha512(str(dct))
return h.hexdigest()
if __name__ == '__main__':
main()
It returns this:
OID 3 from fc2 corresponds to OID 3 in fc1
OID 5 from fc2 corresponds to OID 5 in fc1
OID 4 from fc2 corresponds to OID 4 in fc1
OID 1 from fc2 corresponds to OID 1 in fc1
OID 3 from fc1 corresponds to OID 3 in fc2
OID 5 from fc1 corresponds to OID 5 in fc2
OID 4 from fc1 corresponds to OID 4 in fc2
OID 2 from fc1 has no match with features in fc2
OID 1 from fc1 corresponds to OID 1 in fc2
...it matches the features based on the hash (sha512) generated.
However, don't get your hopes up to high since the code is terribly slow...