openclaw把GIS的直线边弧段# -*- coding: utf-8 -*-"""线段转曲线工具将 2 点直线转换为曲线(圆弧)"""import arcpyimport mathimport os# 输入输出input_fc = r"C:\Users\yl\Documents\ArcGIS\Projects\MyProject17\MyProject17.gdb\line"output_fc = r"C:\Users\yl\Documents\ArcGIS\Projects\MyProject17\MyProject17.gdb\k"# 曲线参数CURVE_HEIGHT = 200 # 曲线拱高(米),正值向上拱,负值向下拱print("=" * 60)print("线段转曲线工具")print("=" * 60)print("输入:%s" % input_fc)print("输出:%s" % output_fc)print("曲线拱高:%.1f 米" % CURVE_HEIGHT)print()# 设置环境arcpy.env.overwriteOutput = True# 获取输入要素类信息desc = arcpy.Describe(input_fc)spatial_ref = desc.spatialReferenceprint("坐标系:%s" % spatial_ref.name)# 创建输出要素类print("\n创建输出要素类...")arcpy.management.CreateFeatureclass( os.path.dirname(output_fc), os.path.basename(output_fc),"POLYLINE", spatial_reference=spatial_ref, has_m="DISABLED", has_z="DISABLED")print("[OK] 输出要素类已创建")# 复制字段print("\n复制字段结构...")input_fields = [f for f in arcpy.ListFields(input_fc) if f.name not in ['Shape', 'OID', 'FID']]for field in input_fields:if field.type not in ['OID', 'Geometry']: arcpy.management.AddField(output_fc, field.name, field.type, field.precision, field.scale, field.length)print("[OK] 字段已复制")# 转换线段到曲线def line_to_curve(start_pt, end_pt, height=CURVE_HEIGHT):"""将直线转换为圆弧曲线 参数: start_pt: 起点 (arcpy.Point) end_pt: 终点 (arcpy.Point) height: 拱高(米) 返回: arcpy.Polyline: 曲线几何 """ # 计算中点mid_x = (start_pt.X + end_pt.X) / 2mid_y = (start_pt.Y + end_pt.Y) / 2# 计算线段长度和方向dx = end_pt.X - start_pt.X dy = end_pt.Y - start_pt.Y length = math.sqrt(dx * dx + dy * dy)if length == 0:return None# 计算垂直方向的单位向量perp_x = -dy / length perp_y = dx / length# 计算控制点(中点垂直偏移)control_x = mid_x + perp_x * height control_y = mid_y + perp_y * height# 创建圆弧(使用三个点:起点、控制点、终点)# ArcGIS 中使用 densify 或 true curve # 这里使用多段线近似圆弧# 生成圆弧上的点(使用二次贝塞尔曲线公式)num_points = 20 # 圆弧分段数points = arcpy.Array()for i in range(num_points + 1): t = i / num_points# 二次贝塞尔曲线公式# B(t) = (1-t)²*P0 + 2(1-t)*t*P1 + t²*P2x = (1-t)**2 * start_pt.X + 2*(1-t)*t * control_x + t**2 * end_pt.X y = (1-t)**2 * start_pt.Y + 2*(1-t)*t * control_y + t**2 * end_pt.Y pt = arcpy.Point(x, y) points.add(pt)# 创建折线polyline = arcpy.Polyline(points, spatial_ref)return polyline# 处理要素print("\n开始转换...")insert_cursor = arcpy.da.InsertCursor(output_fc, ["SHAPE@"] + [f.name for f in input_fields])count_total = 0count_success = 0with arcpy.da.SearchCursor(input_fc, ["SHAPE@", "OID@"] + [f.name for f in input_fields]) as search_cursor:for row in search_cursor: count_total += 1geometry = row[0] oid = row[1] attributes = row[2:]try:# 处理每个部分new_parts = []for part in geometry: points = [pt for pt in part if pt]if len(points) < 2:continue# 将每对相邻点转换为曲线curve_points = arcpy.Array()for i in range(len(points) - 1): start_pt = points[i] end_pt = points[i + 1]# 转换为曲线curve = line_to_curve(start_pt, end_pt)if curve:# 添加曲线上的点(排除第一个点,避免重复)for j, pt in enumerate(curve.getPart(0)):if j > 0 or i == 0: # 第一段包含起点curve_points.add(pt)if curve_points.count > 1: new_parts.append(curve_points)if new_parts:# 创建新的折线if len(new_parts) == 1: new_geometry = arcpy.Polyline(new_parts[0], spatial_ref)else: new_geometry = arcpy.Polyline(arcpy.Array(new_parts), spatial_ref)# 插入新要素insert_cursor.insertRow([new_geometry] + list(attributes)) count_success += 1if count_success % 10 == 0: print(" 已处理 %d 个要素..." % count_success)except Exception as e: print("[警告] 要素 %d 处理失败:%s" % (oid, str(e)))del insert_cursorprint()print("=" * 60)print("处理完成!")print("共处理 %d 个要素,成功 %d 个" % (count_total, count_success))print("输出:%s" % output_fc)print("=" * 60)