ในกรณีนี้มีสามประเด็นที่ต้องแข่งขันกัน:
- หลุม
- เส้นแบ่งระหว่างรูปหลายเหลี่ยม
- สิ้นสุดบรรทัด
หลุม
เนื่องจากเส้นใด ๆ ที่อยู่ภายในรูจะถูกดูแลรักษาเอาหลุมออกจากรูปหลายเหลี่ยม ในสคริปต์ด้านล่างฉันทำได้โดยใช้เคอร์เซอร์และรูปทรงเรขาคณิต
เส้นแบ่งระหว่างรูปหลายเหลี่ยม
ต้องลบเส้นที่สัมผัสสองรูปหลายเหลี่ยม ในสคริปต์ด้านล่างฉันทำได้โดยดำเนินการเข้าร่วมเชิงพื้นที่one to many
โดยมีบรรทัดของฉันเป็นชั้นเรียนคุณลักษณะการป้อนข้อมูลของฉันและรูปหลายเหลี่ยมของฉันเป็นชั้นเรียนคุณลักษณะการเข้าร่วมของฉัน บรรทัดใด ๆ ที่สร้างขึ้นสองครั้งจะสัมผัสกับรูปหลายเหลี่ยมสองอันและถูกลบออก
สิ้นสุดบรรทัด
หากต้องการลบเส้นที่แตะรูปหลายเหลี่ยมที่ด้านเดียวฉันจะแปลงบรรทัดเป็นจุดสิ้นสุด ฉันใช้ประโยชน์จากเลเยอร์คุณลักษณะและการเลือกเพื่อกำหนดว่าจุดสิ้นสุดใดที่เป็นจุดลอยตัว ฉันเลือกจุดสิ้นสุดที่ตัดกันรูปหลายเหลี่ยม จากนั้นฉันสลับการเลือกของฉัน นี่เป็นการเลือกจุดสิ้นสุดที่ไม่ตัดกันรูปหลายเหลี่ยม ฉันเลือกบรรทัดใดก็ได้ที่ตัดกันจุดที่เลือกเหล่านี้และลบออก
ผลลัพธ์
สมมติฐาน
- อินพุตเป็นคลาสของคุณลักษณะทางภูมิศาสตร์ฐานข้อมูลไฟล์
- มีใบอนุญาตขั้นสูงของ ArcGIS (เนื่องจาก
erase
และ a feature vertices to points
)
- เส้นต่อเนื่องที่เชื่อมต่อกันเป็นคุณสมบัติเดียว
- รูปหลายเหลี่ยมไม่ทับซ้อนกัน
- ไม่มีรูปหลายเหลี่ยมหลายส่วน
ต้นฉบับ
สคริปต์ด้านล่างแสดงคลาสคุณลักษณะที่มีชื่อคลาสคุณลักษณะบรรทัดของคุณบวก_GreedyClip
ในฐานข้อมูลภูมิศาสตร์เดียวกันกับคลาสคุณลักษณะบรรทัดของคุณ ต้องการพื้นที่ทำงานด้วย
#input polygon feature class
polyFc = r"C:\Users\e1b8\Desktop\E1B8\Workspace\Workspace.gdb\testPolygon2"
#input line feature class
lineFc = r"C:\Users\e1b8\Desktop\E1B8\Workspace\Workspace.gdb\testLine"
#workspace
workspace = r"in_memory"
print "importing"
import arcpy
import os
#generate a unique ArcGIS file name
def UniqueFileName(location = "in_memory", name = "file", extension = ""):
if extension:
outName = os.path.join (location, name + "." + extension)
else:
outName = os.path.join (location, name)
i = 0
while arcpy.Exists (outName):
i += 1
if extension:
outName = os.path.join (location, "{0}_{1}.{2}".format (name, i, extension))
else:
outName = os.path.join (location, "{0}_{1}".format (name, i))
return outName
#remove holes from polygons
def RemoveHoles (inFc, workspace):
outFc = UniqueFileName (workspace)
array = arcpy.Array ()
sr = arcpy.Describe (inFc).spatialReference
outPath, outName = os.path.split (outFc)
arcpy.CreateFeatureclass_management (outPath, outName, "POLYGON", spatial_reference = sr)
with arcpy.da.InsertCursor (outFc, "SHAPE@") as iCurs:
with arcpy.da.SearchCursor (inFc, "SHAPE@") as sCurs:
for geom, in sCurs:
try:
part = geom.getPart (0)
except:
continue
for pnt in part:
if not pnt:
break
array.add (pnt)
polygon = arcpy.Polygon (array)
array.removeAll ()
row = (polygon,)
iCurs.insertRow (row)
del iCurs
del sCurs
return outFc
#split line fc by polygon fc
def SplitLinesByPolygon (lineFc, polygonFc, workspace):
#clip
clipFc = UniqueFileName(workspace)
arcpy.Clip_analysis (lineFc, polygonFc, clipFc)
#erase
eraseFc = UniqueFileName(workspace)
arcpy.Erase_analysis (lineFc, polygonFc, eraseFc)
#merge
mergeFc = UniqueFileName(workspace)
arcpy.Merge_management ([clipFc, eraseFc], mergeFc)
#multipart to singlepart
outFc = UniqueFileName(workspace)
arcpy.MultipartToSinglepart_management (mergeFc, outFc)
#delete intermediate data
for trash in [clipFc, eraseFc, mergeFc]:
arcpy.Delete_management (trash)
return outFc
#remove lines between two polygons and end lines
def RemoveLines (inFc, polygonFc, workspace):
#check if "TARGET_FID" is in fields
flds = [f.name for f in arcpy.ListFields (inFc)]
if "TARGET_FID" in flds:
#delete "TARGET_FID" field
arcpy.DeleteField_management (inFc, "TARGET_FID")
#spatial join
sjFc = UniqueFileName(workspace)
arcpy.SpatialJoin_analysis (inFc, polygonFc, sjFc, "JOIN_ONE_TO_MANY")
#list of TARGET_FIDs
targetFids = [fid for fid, in arcpy.da.SearchCursor (sjFc, "TARGET_FID")]
#target FIDs with multiple occurances
deleteFids = [dFid for dFid in targetFids if targetFids.count (dFid) > 1]
if deleteFids:
#delete rows with update cursor
with arcpy.da.UpdateCursor (inFc, "OID@") as cursor:
for oid, in cursor:
if oid in deleteFids:
cursor.deleteRow ()
del cursor
#feature vertices to points
vertFc = UniqueFileName(workspace)
arcpy.FeatureVerticesToPoints_management (inFc, vertFc, "BOTH_ENDS")
#select points intersecting polygons
arcpy.MakeFeatureLayer_management (vertFc, "vertLyr")
arcpy.SelectLayerByLocation_management ("vertLyr", "", polygonFc, "1 FEET")
#switch selection
arcpy.SelectLayerByAttribute_management ("vertLyr", "SWITCH_SELECTION")
arcpy.MakeFeatureLayer_management (inFc, "lineLyr")
#check for selection
if arcpy.Describe ("vertLyr").FIDSet:
#select lines by selected points
arcpy.SelectLayerByLocation_management ("lineLyr", "", "vertLyr", "1 FEET")
#double check selection (should always have selection)
if arcpy.Describe ("lineLyr").FIDSet:
#delete selected rows
arcpy.DeleteFeatures_management ("lineLyr")
#delete intermediate data
for trash in [sjFc, "vertLyr", "lineLyr"]:
arcpy.Delete_management (trash)
#main script
def main (polyFc, lineFc, workspace):
#remove holes
print "removing holes"
holelessPolyFc = RemoveHoles (polyFc, workspace)
#split line at polygons
print "splitting lines at polygons"
splitFc = SplitLinesByPolygon (lineFc, holelessPolyFc, workspace)
#delete unwanted lines
print "removing unwanted lines"
RemoveLines (splitFc, polyFc, workspace)
#create output feature class
outFc = lineFc + "_GreedyClip"
outFcPath, outFcName = os.path.split (outFc)
outFc = UniqueFileName (outFcPath, outFcName)
arcpy.CopyFeatures_management (splitFc, outFc)
print "created:"
print outFc
print
print "cleaning up"
#delete intermediate data
for trash in [holelessPolyFc, splitFc]:
arcpy.Delete_management (trash)
print "done"
if __name__ == "__main__":
main (polyFc, lineFc, workspace)