使用 Python 和 GeoJSON 计算多边形的边界框(Bounding Box)

在地理信息系统 (GIS) 中,边界框 (Bounding Box) 是用来描述一个几何图形的最小矩形区域的。它可以简单地表示为两个坐标:左下角和右上角的点。在这篇文章中,我们将介绍如何使用 Python 的 geojson 库计算一个多边形的边界框。

代码实现

下面是一段简单的 Python 代码,它接受一个坐标列表,计算出包含这些坐标的边界框,并返回一个表示这个边界框的字符串:

import os

def count_lines_in_files(directory):
    total_lines = 0
    for root, dirs, files in os.walk(directory):
        for file in files:
            if file.endswith('.py'):
                file_path = os.path.join(root, file)
                with open(file_path, 'r', encoding='utf-8') as f:
                    try:
                        lines = len(f.readlines())
                        total_lines += lines
                    except UnicodeDecodeError:
                        print(f"无法读取文件 {file_path},可能是编码问题")
    return total_lines


if __name__ == '__main__':
    # 使用方法
    directory = r'D:\code\rs-tool'  # 替换成你需要统计的目录路径
    total_lines = count_lines_in_files(directory)
    print(f"总行数: {total_lines}")

代码解析

  1. 导入 geojson 模块:我们使用了 geojson 库来处理 GeoJSON 格式的多边形。这是一个非常常见的格式,广泛用于地理数据的表示。

    import geojson
  2. 定义 bbox 函数:该函数接受一个包含坐标的列表(即一个二维点的集合),然后通过按 X 和 Y 坐标分别排序来计算边界框。边界框的 X 维度和 Y 维度分别取最小和最大的值。

    • 我们分别对 X 坐标和 Y 坐标进行排序。
    • box 存储的是最小 X 坐标到最大 X 坐标,以及最小 Y 坐标到最大 Y 坐标。
    • 最后返回一个表示边界框的数据,格式为 (min_x, min_y, max_x, max_y)
    def bbox(coord_list):
        # 获取所有的x坐标和y坐标
        xs, ys = zip(*coord_list)
        # 计算最小最大值
        min_x, max_x = min(xs), max(xs)
        min_y, max_y = min(ys), max(ys)
        # 返回边界框
        return (min_x, min_y, max_x, max_y)
  3. 创建一个多边形:我们使用了 geojson.Polygon() 来定义一个 GeoJSON 格式的多边形,该多边形由一组坐标组成。这里的坐标定义了一个简单的闭合多边形,最后一个点与第一个点相同。

    poly = geojson.Polygon([[
        (2.38, 57.322),
        (23.194, -20.28),
        (-120.43, 19.15),
        (2.38, 57.322)
    ]])
  4. 计算边界框:我们使用 geojson.utils.coords() 来提取多边形的坐标,并将它们传递给 bbox() 函数进行计算。最后,打印出计算结果。

    # 提取坐标
    coords = list(geojson.utils.coords(poly))
    
    # 计算边界框
    boundary_box = bbox(coords)
    
    print("边界框:", boundary_box)

输出结果

当运行这段代码时,输出如下:


(-120.43 -20.28, 23.194 57.322)

这个输出表示的是该多边形的边界框,左下角的坐标为 (-120.43, -20.28),右上角的坐标为 (23.194, 57.322)

使用 Folium 进行可视化

部分代码如下:

import folium

# 创建一个地图,中心点设置为多边形的大致中心位置
center_lat = sum([coord[1] for coord in coords]) / len(coords)
center_lon = sum([coord[0] for coord in coords]) / len(coords)
m = folium.Map(location=[center_lat, center_lon], zoom_start=4)

# 将GeoJSON数据添加到地图上
folium.GeoJson(poly).add_to(m)

# 显示地图(如果你在Jupyter环境中)
m

完整代码

import geojson
import folium

def bbox(coord_list):
    # 获取所有的x坐标和y坐标
    xs, ys = zip(*coord_list)
    # 计算最小最大值
    min_x, max_x = min(xs), max(xs)
    min_y, max_y = min(ys), max(ys)
    # 返回边界框
    return (min_x, min_y, max_x, max_y)

# 测试数据:一个简单的 GeoJSON 多边形
poly = geojson.Polygon([[
    (2.38, 57.322),
    (23.194, -20.28),
    (-120.43, 19.15),
    (2.38, 57.322)
]])

# 提取坐标
coords = list(geojson.utils.coords(poly))

# 计算边界框
boundary_box = bbox(coords)

print("边界框:", boundary_box)

# 创建一个地图,中心点设置为多边形的大致中心位置
center_lat = sum([coord[1] for coord in coords]) / len(coords)
center_lon = sum([coord[0] for coord in coords]) / len(coords)
m = folium.Map(location=[center_lat, center_lon], zoom_start=4)

# 将GeoJSON数据添加到地图上
folium.GeoJson(poly).add_to(m)

# 添加边界框到地图
folium.Rectangle(
    bounds=((boundary_box[1], boundary_box[0]), (boundary_box[3], boundary_box[2])),
    color="red",
    fill=False,
    popup="Boundary Box"
).add_to(m)

# 显示地图(如果你在Jupyter环境中)
m

# 保存地图为HTML文件(可选)
m.save("polygon_with_bbox_map.html")

image-20241016161145344

总结

通过这段简短的代码,我们展示了如何使用 Python 计算 GeoJSON 多边形的边界框。

曾经我使用这段代码将矢量文件转为yolo样本,所以把部分的过程记录下来。

至于folium的可视化的内容,是为了写这篇博客而增加的部分。