【ArcMap】复制选中的线并将其上移一段距离

首先选中需要复制的线

image

 在python2窗口中输入以下代码:此处为上移10米

  • 对于地理坐标系,使用0.00009度(约10米)

  • 对于投影坐标系,使用10米

# -*- coding: utf-8 -*-
import arcpy
import os
import sys

# 重新加载sys并设置默认编码
reload(sys)
sys.setdefaultencoding('utf-8')

# 设置环境
arcpy.env.overwriteOutput = True

try:
    # 获取当前地图文档
    mxd = arcpy.mapping.MapDocument("CURRENT")
    df = arcpy.mapping.ListDataFrames(mxd)[0]
    
    arcpy.AddMessage("脚本开始执行...")
    
    # 查找线图层
    target_layer = None
    for layer in arcpy.mapping.ListLayers(mxd):
        if layer.isFeatureLayer:
            desc = arcpy.Describe(layer)
            if desc.shapeType == "Polyline":
                target_layer = layer
                break
    
    if target_layer is None:
        arcpy.AddError("未找到线图层")
        sys.exit()
    
    arcpy.AddMessage("找到图层: " + target_layer.name)
    
    # 检查是否有选中的要素
    desc = arcpy.Describe(target_layer)
    if not desc.FIDSet:
        arcpy.AddError("没有选中的要素")
        sys.exit()
    
    # 获取选中要素的数量
    result = arcpy.GetCount_management(target_layer)
    selected_count = int(result.getOutput(0))
    arcpy.AddMessage("选中的要素数量: " + str(selected_count))
    
    # 获取数据源路径
    data_source = desc.catalogPath
    arcpy.AddMessage("数据源: " + data_source)
    
    # 获取空间参考
    spatial_ref = desc.spatialReference
    arcpy.AddMessage("坐标系: " + spatial_ref.name)
    
    # 获取选中要素的OID
    selected_oids = []
    with arcpy.da.SearchCursor(target_layer, ["OID@"]) as cursor:
        for row in cursor:
            selected_oids.append(row[0])
    
    arcpy.AddMessage("选中的要素OID: " + str(selected_oids))
    
    # 创建查询条件
    oid_field = arcpy.Describe(target_layer).OIDFieldName
    where_clause = "{} IN ({})".format(arcpy.AddFieldDelimiters(data_source, oid_field), 
                                      ",".join(str(oid) for oid in selected_oids))
    
    # 获取字段列表
    field_names = []
    for field in arcpy.ListFields(target_layer):
        if field.type not in ["OID", "Geometry"]:
            field_names.append(field.name)
    
    arcpy.AddMessage("将复制的字段: " + str(field_names))
    
    # 确定移动距离 - 缩短为10米
    if spatial_ref.type == "Geographic":
        y_offset = 0.00009  # 大约10米 (1度≈111公里,10米≈0.00009度)
    else:
        y_offset = 10.0  # 10米
    
    arcpy.AddMessage("向上移动距离: " + str(y_offset) + ("" if spatial_ref.type == "Geographic" else ""))
    
    # 开始编辑会话
    edit = arcpy.da.Editor(os.path.dirname(data_source))
    edit.startEditing(False, True)
    edit.startOperation()
    
    try:
        # 使用插入游标将移动后的要素添加到同一图层
        with arcpy.da.InsertCursor(data_source, ["SHAPE@"] + field_names) as insert_cursor:
            # 使用搜索游标读取选中的要素
            with arcpy.da.SearchCursor(data_source, ["SHAPE@"] + field_names, where_clause) as search_cursor:
                moved_count = 0
                for row in search_cursor:
                    shape = row[0]
                    attributes = row[1:]
                    
                    if shape:
                        # 创建一个新的数组来存储移动后的点
                        new_parts = arcpy.Array()
                        
                        # 遍历原始几何的每个部分
                        for part in shape:
                            new_part = arcpy.Array()
                            
                            # 遍历每个点
                            for point in part:
                                if point:
                                    # 创建新点,Y坐标增加偏移量
                                    new_point = arcpy.Point(point.X, point.Y + y_offset)
                                    new_part.add(new_point)
                            
                            new_parts.add(new_part)
                        
                        # 创建新的Polyline几何
                        moved_shape = arcpy.Polyline(new_parts, spatial_ref)
                        
                        # 插入移动后的要素到同一图层
                        insert_cursor.insertRow([moved_shape] + list(attributes))
                        moved_count += 1
                        arcpy.AddMessage("已复制并移动要素 " + str(moved_count))
        
        # 提交编辑
        edit.stopOperation()
        edit.stopEditing(True)
        
        arcpy.AddMessage("成功复制并移动 " + str(moved_count) + " 个要素到原始图层")
        
        # 刷新视图
        arcpy.RefreshActiveView()
        arcpy.RefreshTOC()
        
        # 清除选择集,显示所有要素
        target_layer.setSelectionSet("NEW", [])
        
        arcpy.AddMessage("操作完成! 所有移动后的要素都已添加到原始图层中")
        arcpy.AddMessage("原始要素保持不变,新要素已向上移动10米")
        arcpy.AddMessage("现在图层中有 " + str(selected_count + moved_count) + " 个要素")
        arcpy.AddMessage("请使用测量工具验证两条线之间的距离是否为10米")
        arcpy.AddMessage("注意:由于10米距离很小,可能需要放大查看")
        
    except Exception as e:
        # 中止编辑
        edit.stopOperation()
        edit.stopEditing(False)
        raise e

except Exception as e:
    arcpy.AddError("错误: " + str(e))
    import traceback
    error_msg = traceback.format_exc()
    arcpy.AddError(error_msg)

运行后如下:

image

 

posted @ 2025-10-25 23:30  山鬼谣`  阅读(2)  评论(0)    收藏  举报