如何用Python为网格系统内方块分配地理坐标与行列编号
实现自定义网格划分与方块坐标、编号生成方案
核心步骤
- 提取边界框的坐标范围,确定x轴和y轴的极值
- 用
np.linspace对x、y轴进行等分分割,得到网格节点 - 遍历每个网格单元,计算四个角的坐标并生成自定义编号
- 可视化网格(可选)
- 实现点坐标到网格编号的快速映射
具体代码实现
import numpy as np import matplotlib.pyplot as plt # 1. 定义设施边界框坐标 bottomLeft = (5728532.582535409, -103910.03553330127) bottomRight = (5728616.315470162, -103910.03553330127) topLeft = (5728532.582535409, -103774.97966179297) topRight = (5728616.315470162, -103774.97966179297) # 提取x、y轴极值 x_min, y_min = bottomLeft x_max, y_max = topRight # 2. 自定义网格行列数(可根据需求调整) rows = 2 # 垂直方向(y轴)的网格行数 cols = 3 # 水平方向(x轴)的网格列数 # 生成x、y轴的分割点(cols+1个点分割成cols列,rows+1个点分割成rows行) x_points = np.linspace(x_min, x_max, cols + 1) y_points = np.linspace(y_min, y_max, rows + 1) # 3. 遍历生成每个网格方块的属性 grid_blocks = [] for row_idx in range(rows): for col_idx in range(cols): # 计算当前方块的四个角坐标 bl = (x_points[col_idx], y_points[row_idx]) br = (x_points[col_idx+1], y_points[row_idx]) tl = (x_points[col_idx], y_points[row_idx+1]) tr = (x_points[col_idx+1], y_points[row_idx+1]) # 生成编号:行号从顶部开始(1为最上方),列号从左侧开始(1为最左) row_num = rows - row_idx col_num = col_idx + 1 block_id = f"{row_num}{col_num}" grid_blocks.append({ "id": block_id, "bottomLeft": bl, "bottomRight": br, "topLeft": tl, "topRight": tr }) # 打印所有网格方块信息 for block in grid_blocks: print(f"方块编号: {block['id']}") print(f"bottomLeft: {block['bottomLeft']}") print(f"bottomRight: {block['bottomRight']}") print(f"topLeft: {block['topLeft']}") print(f"topRight: {block['topRight']}\n") # 4. 可视化网格 plt.figure(figsize=(10, 8)) # 画网格线 for x in x_points: plt.plot([x, x], [y_min, y_max], 'gray', linewidth=1) for y in y_points: plt.plot([x_min, x_max], [y, y], 'gray', linewidth=1) # 标注每个方块的编号和中心点坐标 for block in grid_blocks: # 计算中心点坐标用于标注 cx = (block['bottomLeft'][0] + block['topRight'][0]) / 2 cy = (block['bottomLeft'][1] + block['topRight'][1]) / 2 plt.text(cx, cy, block['id'], fontsize=12, ha='center', va='center') # 设置坐标轴标签和标题 plt.xlabel('X坐标 (米)') plt.ylabel('Y坐标 (米)') plt.title('设施网格划分可视化') plt.grid(False) # 关闭默认网格,避免和自定义网格重复 plt.show() # 5. 实现点坐标到网格编号的映射 def get_block_id(point, x_points, y_points, rows): x, y = point # 找到x所在的列索引(从0开始) col_idx = np.digitize(x, x_points) - 1 # 找到y所在的行索引(从0开始,y_min对应索引0) row_idx = np.digitize(y, y_points) - 1 # 转换为自定义编号规则的行号和列号 row_num = rows - row_idx col_num = col_idx + 1 # 处理边界情况:点刚好在x_max或y_max时,索引会超出范围 if col_idx >= cols: col_num = cols col_idx = cols - 1 if row_idx >= rows: row_num = 1 row_idx = rows - 1 return f"{row_num}{col_num}" # 测试映射功能 test_point = (5728550, -103850) print(f"测试点 {test_point} 所在方块编号: {get_block_id(test_point, x_points, y_points, rows)}")
关键细节说明
- 编号规则:行号从顶部开始计数(最上方为1),列号从左侧开始计数(最左侧为1),比如
11对应左上角第一个方块,符合需求。 - 坐标计算:利用分割点的索引直接推导每个方块的四个角坐标,确保每个方块的边界和设施边界完全对齐。
- 可视化:用matplotlib绘制网格线并标注编号,直观验证网格划分是否符合预期。
- 点映射:通过
np.digitize快速定位点所在的区间,转换为对应的网格编号,处理了点刚好落在边界上的特殊情况。
内容的提问来源于stack exchange,提问作者Zihan Liu
相关产品推荐
相关产品推荐

