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