Another code sample. This one saves attributes from input polygon layer.
The main idea stills the same - convert single polygon to lines, create temporary layer of this polygon's boundary and intersecting it lines, then convert it back to polygons, clip by initial polygon and write it back.
Also there is an option to include SQL-query for the line layer.
# coding: utf-8
import arcpy
import os
import sys
import time
def splitPolygonsWithLines(Poly, Lines, LinesQuery="", outPoly=""):
inputPoly=Poly
inputLines=Lines
query=LinesQuery
inputPolyName=os.path.basename(inputPoly)
inputLinesName=os.path.basename(inputLines)
parDir=os.path.abspath(inputPoly+"\..")
if outPoly=="":
outputPolyName=os.path.splitext(inputPolyName)[0]+u"_Split"+os.path.splitext(inputPolyName)[1]
outputPoly=os.path.join(parDir,outputPolyName)
else:
outputPolyName=os.path.basename(outPoly)
outputPoly=outPoly
sr=arcpy.Describe(inputPoly).spatialReference
fieldNameIgnore=["SHAPE_Area", "SHAPE_Length"]
fieldTypeIgnore=["OID", "Geometry"]
#############################################################################################################################
arcpy.CreateFeatureclass_management (parDir, outputPolyName, "POLYGON", "", "", "", sr)
arcpy.AddField_management(outputPoly, "OLD_OID", "LONG")
for field in arcpy.ListFields(inputPoly):
if (field.type not in fieldTypeIgnore and field.name not in fieldNameIgnore):
arcpy.AddField_management (outputPoly, field.name, field.type)
arcpy.MakeFeatureLayer_management(inputLines,inputLinesName+"Layer",query)
arcpy.MakeFeatureLayer_management(inputPoly,inputPolyName+"Layer")
arcpy.SelectLayerByLocation_management(inputPolyName+"Layer","INTERSECT",inputLinesName+"Layer","","NEW_SELECTION")
arcpy.SelectLayerByAttribute_management(inputPolyName+"Layer", "SWITCH_SELECTION")
fieldmappings = arcpy.FieldMappings()
for field in arcpy.ListFields(inputPoly):
if (field.type not in fieldTypeIgnore and field.name not in fieldNameIgnore):
fm=arcpy.FieldMap()
fm.addInputField(outputPoly, field.name)
fm.addInputField(inputPolyName+"Layer", field.name)
fm_name = fm.outputField
fm_name.name = field.name
fm.outputField = fm_name
fieldmappings.addFieldMap (fm)
fm=arcpy.FieldMap()
fm.addInputField(outputPoly, "OLD_OID")
fm.addInputField(inputPolyName+"Layer", "OBJECTID")
fm_name = fm.outputField
fm_name.name = "OLD_OID"
fm.outputField = fm_name
fieldmappings.addFieldMap (fm)
arcpy.Append_management(inputPolyName+"Layer", outputPoly, "NO_TEST", fieldmappings)
polySelect=arcpy.SelectLayerByLocation_management(inputPolyName+"Layer","INTERSECT",inputLinesName+"Layer","","NEW_SELECTION")
lineSelect=arcpy.SelectLayerByLocation_management(inputLinesName+"Layer","INTERSECT",inputPolyName+"Layer","","NEW_SELECTION")
#############################################################################################################################
fields=[f.name for f in arcpy.ListFields(inputPoly) if (f.type not in fieldTypeIgnore and f.name not in fieldNameIgnore)]
fields.append("SHAPE@")
totalFeatures=int(arcpy.GetCount_management(polySelect).getOutput(0))
count=0
timePrev=time.time()
with arcpy.da.SearchCursor(polySelect,["OID@"]+fields) as curInput:
for rowInput in curInput:
linesTemp=arcpy.SelectLayerByLocation_management(lineSelect,"INTERSECT",rowInput[-1],"","NEW_SELECTION")
geometry=arcpy.CopyFeatures_management(linesTemp,arcpy.Geometry())
geometry.append(rowInput[-1].boundary())
arcpy.FeatureToPolygon_management (geometry, "in_memory\polygons_init")
arcpy.Clip_analysis ("in_memory\polygons_init", rowInput[-1], "in_memory\polygons_clip")
with arcpy.da.SearchCursor("in_memory\polygons_clip","SHAPE@") as curPoly:
newGeom=[]
for rowP in curPoly:
if not rowP[0].disjoint(rowInput[-1]):
newGeom.append(rowP[0])
arcpy.Delete_management("in_memory")
with arcpy.da.InsertCursor(outputPoly, ["OLD_OID"]+fields) as insCur:
for geom in newGeom:
insertFeature=[r for r in rowInput[:-1]]
insertFeature.append(geom)
insCur.insertRow(insertFeature)
count+=1
if int(time.time()-timePrev)%5==0 and int(time.time()-timePrev)>0:
timePrev=time.time()
arcpy.AddMessage("\r{0}% done, {1} features processed".format(int(count*100/totalFeatures),int(count)))
def main():
arcpy.env.overwriteOutput = True
arcpy.env.XYTolerance = "0.1 Meters"
inputPoly = arcpy.GetParameterAsText(0) # required
inputLines = arcpy.GetParameterAsText(1) # required
linesQuery = arcpy.GetParameterAsText(2) # optional
outPoly = arcpy.GetParameterAsText(3) # optional
if inputPoly=="":
inputPoly="D:/Projects/MOVE/MOVE.gdb/poly"
if arcpy.Exists(inputPoly):
arcpy.AddMessage("Input polygons: "+inputPoly)
else:
arcpy.AddError("Input polygons layer %s is invalid" % (inputPoly))
if inputLines=="":
inputLines="D:/Projects/MOVE/MOVE.gdb/line"
if arcpy.Exists(inputLines):
arcpy.AddMessage("Input lines: "+inputPoly)
else:
arcpy.AddError("Input lines layer %s is invalid" % (inputLines))
if linesQuery=="":
arcpy.AddMessage("Performing without query")
if outPoly == "":
arcpy.AddMessage("Output will be created at the same location as input polygons layer is.")
splitPolygonsWithLines(inputPoly, inputLines, linesQuery, outPoly)
if __name__ == "__main__":
main()