이 경우에 해결해야 할 세 가지 문제가 있습니다.
구멍
구멍 내의 선이 유지되므로 다각형에서 구멍을 제거하십시오. 아래 스크립트에서 커서와 도형을 사용하여 수행합니다.
다각형 사이의 선
두 개의 다각형에 닿는 선을 제거해야합니다. 아래 스크립트에서 나는 one to many
입력 피쳐 클래스로 내 선 을 , 결합 피쳐 클래스로 다각형을 사용 하여의 공간 결합을 수행하여 그렇게합니다 . 두 번 생성 된 선은 두 다각형에 닿아 제거됩니다.
엔드 라인
한쪽 끝의 다각형에만 닿는 선을 제거하기 위해 선을 끝점으로 변환합니다. 그런 다음 피처 레이어와 선택 영역을 사용하여 플로터가되는 엔드 포인트를 결정합니다. 다각형과 교차하는 끝점을 선택합니다. 그런 다음 선택을 전환합니다. 다각형과 교차하지 않는 끝점을 선택합니다. 선택한 점과 교차하는 선을 선택하고 삭제합니다.
결과
가정
- 입력은 파일 지오 데이터베이스 피처 클래스입니다.
- ArcGIS 고급 라이센스를 사용할 수 있습니다 (
erase
및 로 인해 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)