The code:
import arcpy
import os
def Merge (mergeFcs, outFc):
"""
Merge feature classes with field type discrepancies
emilharold@gmail.com
"""
print "iterating fields to determine field types"
stringFlds = []
lIntFlds = []
floatFlds = []
doubleFlds = []
dateFlds = []
numFcs = len (mergeFcs)
digits = len (str (numFcs))
lenDi = {}
placeDi = {}
fObDi = {}
place = 0
for i, fc in enumerate (mergeFcs, 1):
if i != 1 and not (i - 1) % 10:
print
print str (i).zfill (digits) + "/" + str (numFcs),
for fld in arcpy.ListFields (fc):
fType = fld.type
fName = fld.name
if fType in ("Geometry",
"Guid",
"GlobalID",
"OID") or fld.required:
continue
fObDi [fName] = fld
if not fName in placeDi.values ():
place += 1
placeDi [place] = fName
if fType == "String":
stringFlds += [fName]
fLength = fld.length
if not fName in lenDi:
lenDi [fName] = fLength
elif fLength > lenDi [fName]:
lenDi [fName] = fLength
elif fType == "Integer":
if fName in dateFlds:
stringFlds += [fName]
fLength = 50
if not fName in lenDi:
lenDi [fName] = fLength
elif fLength > lenDi [fName]:
lenDi [fName] = fLength
else:
lIntFlds += [fName]
elif fType == "Single":
if fName in dateFlds:
stringFlds += [fName]
fLength = 50
if not fName in lenDi:
lenDi [fName] = fLength
elif fLength > lenDi [fName]:
lenDi [fName] = fLength
else:
floatFlds += [fName]
elif fType == "Double":
if fName in dateFlds:
stringFlds += [fName]
fLength = 50
if not fName in lenDi:
lenDi [fName] = fLength
elif fLength > lenDi [fName]:
lenDi [fName] = fLength
else:
doubleFlds += [fName]
elif fType in ("Date", "Blob", "Raster"):
if fName in lIntFlds + floatFlds + doubleFlds:
stringFlds += [fName]
fLength = 50
if not fName in lenDi:
lenDi [fName] = fLength
elif fLength > lenDi [fName]:
lenDi [fName] = fLength
else:
dateFlds += [fName]
print
stringFlds = set (stringFlds)
lIntFlds = set (lIntFlds)
floatFlds = set (floatFlds)
doubleFlds = set (doubleFlds)
print "creating feature class"
outLoc, outName = os.path.split (outFc)
checkFc = mergeFcs [0]
sr = arcpy.Describe (checkFc).spatialReference
shapeType = arcpy.Describe (checkFc).shapeType.upper ()
arcpy.CreateFeatureclass_management (outLoc, outName,
shapeType,
spatial_reference = sr)
lenFlds = str (len (placeDi.keys ()))
digits = len (lenFlds)
print "adding fields"
for i, place in enumerate ((placeDi.keys ()), 1):
if i != 1 and not (i - 1) % 5:
print
print str (i).zfill (digits) + " of " + lenFlds, "",
fName = placeDi [place]
fld = fObDi [fName]
if fName in stringFlds:
arcpy.AddField_management (outFc, fName, "TEXT",
field_length =
lenDi [fName])
elif fName in floatFlds:
arcpy.AddField_management (outFc, fName, "FLOAT")
elif fName in doubleFlds:
arcpy.AddField_management (outFc, fName, "DOUBLE")
elif fName in lIntFlds:
arcpy.AddField_management (outFc, fName, "LONG")
else:
arcpy.AddField_management (outFc, fName, fld.type)
print
print "iterating feature classes"
outFlds = ["SHAPE@"] + [f.name for f in
arcpy.ListFields (outFc)
if f.type not in
("Geometry", "Guid", "OID")]
inputRows = [None] * len (outFlds)
with arcpy.da.InsertCursor (outFc, outFlds) as iCurs:
for i, fc in enumerate (mergeFcs, 1):
print i, numFcs, "copying rows from", os.path.basename (fc)
inFlds = ["SHAPE@"] + [f.name for f
in arcpy.ListFields (fc)
if f.name in outFlds]
with arcpy.da.SearchCursor (fc, inFlds) as sCurs:
for inRow in sCurs:
row = list (inputRows)
for n, fld in enumerate (inFlds):
if inRow [n]:
if fld in stringFlds:
try: row [outFlds.index
(fld)] = str (inRow [n])
except: row [outFlds.index
(fld)] = inRow [n]
else:
row [outFlds.index
(fld)] = inRow [n]
row [0] = inRow [0]
iCurs.insertRow (row)
return outFc
No comments:
Post a Comment