乐于分享
好东西不私藏

OpenClaw生成标准分幅,并生成工具pyt,普通的我可以洗洗睡了

OpenClaw生成标准分幅,并生成工具pyt,普通的我可以洗洗睡了

# -*- coding: utf-8 -*-"""GBT 13989-1992 地形图分幅生成工具支持多种比例尺:1:100万、1:50万、1:25万、1:10万、1:5万、1:2.5万、1:1万、1:5000"""import arcpyimport mathimport osclass Toolbox(object):def __init__(self):self.label "地形图分幅工具"self.alias "MapSheet"self.tools [GenerateMapSheets]class GenerateMapSheets(object):def __init__(self):self.label "GenerateMapSheets"self.description "根据 GBT 13989-1992 标准生成各种比例尺地形图分幅图框"self.canRunInBackground Falsedef getParameterInfo(self):参数 1:输入范围要素param0 arcpy.Parameter(displayName="输入范围要素",name="input_features",datatype="GPFeatureLayer",parameterType="Required",direction="Input")参数 2:比例尺param1 arcpy.Parameter(displayName="比例尺",name="scale",datatype="GPString",parameterType="Required",direction="Input")        param1.filter.list ["1:100 ","1:50 ","1:25 ","1:10 ","1:5 ","1:2.5 ","1:1 ","1:5000"]        param1.value "1:1 "参数 3:输出要素类param2 arcpy.Parameter(displayName="输出要素类",name="output_features",datatype="DEFeatureClass",parameterType="Required",direction="Output")参数 4:添加图幅编号字段param3 arcpy.Parameter(displayName="添加图幅编号字段",name="add_tbbh_field",datatype="GPBoolean",parameterType="Optional",direction="Input")        param3.value True参数 5:添加经纬度字段param4 arcpy.Parameter(displayName="添加经纬度字段",name="add_latlon_fields",datatype="GPBoolean",parameterType="Optional",direction="Input")        param4.value Truereturn [param0, param1, param2, param3, param4]def isLicensed(self):return Truedef updateParameters(selfparameters):return    def updateMessages(selfparameters):return    def execute(selfparametersmessages):        input_fc parameters[0].valueAsText        scale_str parameters[1].valueAsText        output_fc parameters[2].valueAsText        add_tbbh parameters[3].value        add_latlon parameters[4].value比例尺参数映射scale_params {"1:100 ": {"code""A","lat_delta"4.0,"lon_delta"6.0,"rows_in_1m"1,"cols_in_1m"1,"unit"""},"1:50 ": {"code""B","lat_delta"2.0,"lon_delta"3.0,"rows_in_1m"2,"cols_in_1m"2,"unit"""},"1:25 ": {"code""C","lat_delta"1.0,"lon_delta"1.5,"rows_in_1m"4,"cols_in_1m"4,"unit"""},"1:10 ": {"code""D","lat_delta"20.0 60,"lon_delta"30.0 60,"rows_in_1m"12,"cols_in_1m"12,"unit"""},"1:5 ": {"code""E","lat_delta"10.0 60,"lon_delta"15.0 60,"rows_in_1m"24,"cols_in_1m"24,"unit"""},"1:2.5 ": {"code""F","lat_delta"5.0 60,"lon_delta"7.5 60,"rows_in_1m"48,"cols_in_1m"48,"unit"""},"1:1 ": {"code""G","lat_delta"2.5 60,"lon_delta"3.75 60,"rows_in_1m"96,"cols_in_1m"144,"unit"""},"1:5000": {"code""H","lat_delta"1.25 60,"lon_delta"1.875 60,"rows_in_1m"192,"cols_in_1m"288,"unit"""}        }        params scale_params[scale_str]        code params["code"]        lat_delta params["lat_delta"]        lon_delta params["lon_delta"]        rows_in_1m params["rows_in_1m"]        cols_in_1m params["cols_in_1m"]self.messages messagesself.log(f"开始生成 {scale_str地形图分幅...")self.log("=" 60)获取输入要素范围self.log("获取输入要素范围...")        extent arcpy.Describe(input_fc).extent        spatial_ref arcpy.Describe(input_fc).spatialReferenceself.log(f"  坐标系:{spatial_ref.name}")self.log(f"  XMin: {extent.XMin:.2f}")self.log(f"  YMin: {extent.YMin:.2f}")self.log(f"  XMax: {extent.XMax:.2f}")self.log(f"  YMax: {extent.YMax:.2f}")转换为地理坐标if spatial_ref.type == 'Projected':self.log("\n转换为地理坐标...")            geo_sr arcpy.SpatialReference("GCS_China_Geodetic_Coordinate_System_2000")else:            geo_sr spatial_refdef project_to_geo(xy):            pt arcpy.PointGeometry(arcpy.Point(x, y), spatial_ref)            pt_geo pt.projectAs(geo_sr)return pt_geo.centroid.X, pt_geo.centroid.Y        xmin_geo, ymin_geo project_to_geo(extent.XMin, extent.YMin)        xmax_geo, ymax_geo project_to_geo(extent.XMax, extent.YMax)self.log(f"  经度:{xmin_geo:.6f}° - {xmax_geo:.6f}°")self.log(f"  纬度:{ymin_geo:.6f}° - {ymax_geo:.6f}°")计算 1:100 万图幅编号def get_1m_code(lonlat):            row_idx int(abs(lat) 4)if lat >= 0:                row_char chr(ord('A'row_idx)else:                row_char chr(ord('V'row_idx)            col_num int((lon 18061return f"{row_char}{col_num:02d}", row_idx, col_num        center_lon (xmin_geo xmax_geo) 2center_lat (ymin_geo ymax_geo) 2code_1m, row_1m, col_1m get_1m_code(center_lon, center_lat)self.log(f"\n1:100 万图幅编号:{code_1m}")# 1:100 万图幅范围lon_1m_start (col_1m 1180lat_1m_start row_1m 4self.log(f"1:100 万图幅范围:经度 {lon_1m_start:.2f}°-{lon_1m_start+6:.2f}°, 纬度 {lat_1m_start:.2f}°-{lat_1m_start+4:.2f}°")分幅规格self.log(f"\n{scale_str分幅规格:")self.log(f"  纬差:{lat_delta*60:.4f}′ ({lat_delta:.6f}°)")self.log(f"  经差:{lon_delta*60:.4f}′ ({lon_delta:.6f}°)")self.log(f"  1:100 万内分行数:{rows_in_1m}")self.log(f"  1:100 万内分列数:{cols_in_1m}")计算覆盖范围self.log("\n计算分幅图框...")        start_row int((ymin_geo lat_1m_start) lat_delta) 1start_col int((xmin_geo lon_1m_start) lon_delta) 1end_row int((ymax_geo lat_1m_start) lat_delta) 1end_col int((xmax_geo lon_1m_start) lon_delta) 1限制在有效范围内start_row max(0, start_row)        start_col max(0, start_col)        end_row min(rows_in_1m, end_row)        end_col min(cols_in_1m, end_col)        total_count (end_row start_row) (end_col start_col)self.log(f"  行范围:{start_row+1}-{end_row}")self.log(f"  列范围:{start_col+1}-{end_col}")self.log(f"  预计生成:{total_count幅图")if total_count 1000:self.log(f"警告:图幅数量过多 ({total_count}),可能耗时较长")创建输出要素类output_gdb os.path.dirname(output_fc)        output_name os.path.basename(output_fc)if arcpy.Exists(output_fc):self.log(f"\n删除已存在的要素类:{output_fc}")            arcpy.Delete_management(output_fc)self.log(f"\n创建要素类:{output_fc}")        arcpy.CreateFeatureclass_management(out_path=output_gdb,out_name=output_name,geometry_type='POLYGON',spatial_reference=spatial_ref        )添加字段if add_tbbh:            arcpy.AddField_management(output_fc, 'TBBH''TEXT'field_length=50)self.log("添加图幅编号字段")        arcpy.AddField_management(output_fc, 'Row''LONG')        arcpy.AddField_management(output_fc, 'Col''LONG')if add_latlon:            arcpy.AddField_management(output_fc, 'LonMin''DOUBLE')            arcpy.AddField_management(output_fc, 'LonMax''DOUBLE')            arcpy.AddField_management(output_fc, 'LatMin''DOUBLE')            arcpy.AddField_management(output_fc, 'LatMax''DOUBLE')生成图框self.log("\n生成图框...")        count 0field_list ['SHAPE@']if add_tbbh:            field_list.append('TBBH')        field_list.extend(['Row''Col'])if add_latlon:            field_list.extend(['LonMin''LonMax''LatMin''LatMax'])with arcpy.da.InsertCursor(output_fc, field_list) as cursor:for row in range(start_row, end_row):for col in range(start_col, end_col):地理坐标范围lat_min lat_1m_start row lat_delta                    lat_max lat_min lat_delta                    lon_min lon_1m_start col lon_delta                    lon_max lon_min lon_delta图幅编号if scale_str == "1:100 ":                        tbbh code_1melse:                        tbbh = f"{code_1m}{code}{row+1:03d}{col+1:03d}"创建矩形坐标coords [                        (lon_min, lat_min),                        (lon_max, lat_min),                        (lon_max, lat_max),                        (lon_min, lat_max),                        (lon_min, lat_min)                    ]转换为投影坐标proj_coords []for lon, lat in coords:                        pt arcpy.PointGeometry(arcpy.Point(lon, lat), geo_sr)                        pt_proj pt.projectAs(spatial_ref)                        proj_coords.append((pt_proj.centroid.X, pt_proj.centroid.Y))创建多边形array arcpy.Array([arcpy.Point(x, y) for x, y in proj_coords])                    polygon arcpy.Polygon(array, spatial_ref)构建记录record [polygon]if add_tbbh:                        record.append(tbbh)                    record.extend([row+1, col+1])if add_latlon:                        record.extend([lon_min, lon_max, lat_min, lat_max])                    cursor.insertRow(record)                    count += 1if count 100 == 0:self.log(f"  已生成 {count...")self.log(f"\n完成!共生成 {count幅 {scale_str图框")self.log(f"输出路径:{output_fc}")统计result arcpy.GetCount_management(output_fc)self.log(f"实际要素数:{result[0]}")return    def log(selfmsg):        arcpy.AddMessage(msg)
工具下载:

通过网盘分享的文件:生成标准分幅.rar

链接: https://pan.baidu.com/s/1AxvYbN9DrphLUPi9JgKUBw?pwd=ylok 提取码: ylok