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(self, parameters):return def updateMessages(self, parameters):return def execute(self, parameters, messages): 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(x, y): 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(lon, lat): 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 + 180) / 6) + 1return 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 - 1) * 6 - 180lat_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(self, msg): arcpy.AddMessage(msg)

通过网盘分享的文件:生成标准分幅.rar
链接: https://pan.baidu.com/s/1AxvYbN9DrphLUPi9JgKUBw?pwd=ylok 提取码: ylok
夜雨聆风