地理空间数据处理指南 | 实战案例+代码TableGIS

本文介绍一个强大的Python GIS工具库,涵盖10+个高频使用场景,从距离计算到空间分析,开箱即用,上手简单!

📌 前言

做地理空间数据处理时,经常要处理经纬度、距离计算、缓冲区分析、图层匹配 等繁琐工作。TableGIS 就是为了简化这些操作而生,它基于 GeoPandasShapely,提供了一套开箱即用的高效工具

本文通过10个真实场景的代码案例,让你快速掌握这个库的精髓。


🚀 5分钟快速安装

bash 复制代码
pip install tablegis

导入使用:

python 复制代码
import pandas as pd
import tablegis as tg

📊 核心功能速览

功能模块 主要方法 应用场景
📍 距离计算 min_distance_twotable(), distancea_str() 找最近的门店、配送路由
🗺️ 空间分析 add_buffer(), add_sectors(), add_polygon() 服务范围、风险评估
📐 几何操作 polygon_centroid(), add_area(), add_length() 面积统计、距离测量
🔗 数据转换 df_to_gdf(), points_coverage_merge() 格式互转、属性关联

💡 10个实战案例

案例1:找最近的配送点

场景:有100个待送达的订单位置和50个配送站,需要为每个订单找最近的3个配送站。

python 复制代码
import pandas as pd
import tablegis as tg

# 订单数据
orders = pd.DataFrame({
    'order_id': ['O001', 'O002', 'O003'],
    'lon': [116.404, 116.405, 116.406],
    'lat': [39.915, 39.916, 39.917]
})

# 配送站数据
stations = pd.DataFrame({
    'station_id': ['S001', 'S002', 'S003', 'S004'],
    'lon': [116.403, 116.407, 116.404, 116.408],
    'lat': [39.914, 39.918, 39.916, 39.919]
})

# 找最近的3个配送站,返回id、坐标、距离
result = tg.min_distance_twotable(
    orders, stations,
    lon1='lon', lat1='lat',
    lon2='lon', lat2='lat',
    df2_id='station_id',
    n=3  # 找3个最近的
)

print(result[['order_id', 'nearest1_station_id', 'nearest1_distance', 
              'nearest2_station_id', 'nearest2_distance',
              'nearest3_station_id', 'nearest3_distance']])

# 输出示例:
# order_id nearest1_station_id  nearest1_distance nearest2_station_id  nearest2_distance
# O001       S001              1200.5            S003               3400.2

✨ 优势

  • 自动处理坐标转换,精度到米
  • 返回所有信息,无需二次查询
  • 支持任意数量的邻近点查询

案例2:计算两点间直线距离

场景:快递员要去某个地址取货,需要知道当前位置到目的地有多远。

python 复制代码
import tablegis as tg

# 快递员当前位置
current_lon, current_lat = 116.404, 39.915

# 目的地位置
dest_lon, dest_lat = 116.407, 39.920

# 计算距离(单位:米)
distance = tg.distancea_str(current_lon, current_lat, dest_lon, dest_lat)

print(f"距离:{distance:.0f} 米,约 {distance/1000:.2f} 公里")
# 输出:距离:625 米,约 0.62 公里

✨ 特点

  • 使用Haversine公式,精确到米
  • 自动处理角度转弧度
  • 参数验证,防止坐标输入错误

案例3:批量计算DataFrame内任意两列坐标的距离

场景:有用户当前位置和店铺位置两组坐标,需要计算每个用户到对应店铺的距离。

python 复制代码
import pandas as pd
import tablegis as tg

# 用户数据(当前位置 vs 目标店铺)
df = pd.DataFrame({
    'user_id': ['U001', 'U002', 'U003'],
    'user_lon': [116.404, 116.405, 116.406],
    'user_lat': [39.915, 39.916, 39.917],
    'shop_lon': [116.407, 116.408, 116.409],
    'shop_lat': [39.918, 39.919, 39.920]
})

# 一行代码计算距离
result = tg.distancea_df(
    df,
    lon_1='user_lon', lat_1='user_lat',
    lon_2='shop_lon', lat_2='shop_lat',
    columns_name='到店距离'
)

print(result[['user_id', '到店距离']])
# user_id    到店距离
# U001       3335.5
# U002       3335.5

✨ 优点

  • 向量化计算,处理百万级数据无压力
  • 自动添加列,无需手动赋值

案例4:创建服务覆盖区域(缓冲区)

场景:医院周边1000米是其服务范围,需要为每个医院创建缓冲区。

python 复制代码
import pandas as pd
import tablegis as tg

# 医院数据
hospitals = pd.DataFrame({
    'hospital_id': ['H001', 'H002'],
    'lon': [116.404, 116.407],
    'lat': [39.915, 39.918],
    'coverage_meter': [1000, 1500]  # 覆盖范围(米)
})

# 创建缓冲区,自动处理坐标系转换
result_gdf = tg.add_buffer(
    hospitals,
    lon='lon', lat='lat',
    dis='coverage_meter',  # 指定距离列
    geometry='buffer_zone'
)

print(result_gdf)
print(f"缓冲区面积:{result_gdf['buffer_zone'].area.values[0]:.0f} 平方米")

✨ 精妙之处

  • 自动检测坐标,选择最优UTM投影
  • 输入单位为米,计算精准
  • 返回GeoDataFrame,可直接导出为Shapefile或GeoJSON

案例5:计算多边形的质心

场景:有若干个社区的边界多边形,需要找到每个社区的中心点(用于地图展示)。

python 复制代码
import geopandas as gpd
import pandas as pd
import tablegis as tg
from shapely.geometry import Polygon

# 创建社区多边形数据
gdf = gpd.GeoDataFrame({
    'community_id': ['C001', 'C002'],
    'geometry': [
        Polygon([(116.404, 39.915), (116.407, 39.915), (116.407, 39.918), (116.404, 39.918)]),
        Polygon([(116.410, 39.920), (116.413, 39.920), (116.413, 39.923), (116.410, 39.923)])
    ]
})

# 计算质心
centroids = tg.polygon_centroid(gdf)

# 添加质心坐标到原数据
gdf['center_lon'] = centroids[0]
gdf['center_lat'] = centroids[1]

print(gdf[['community_id', 'center_lon', 'center_lat']])
# community_id  center_lon  center_lat
# C001          116.4055    39.9165
# C002          116.4115    39.9215

✨ 应用

  • 用于地图聚类展示
  • 计算分布密度
  • 快速定位感兴趣区域

案例6:计算多边形面积

场景:地产公司有100个地块的边界,需要计算每个地块的面积用于定价。

python 复制代码
import geopandas as gpd
import tablegis as tg
from shapely.geometry import Polygon

# 地块数据
gdf = gpd.GeoDataFrame({
    'plot_id': ['P001', 'P002'],
    'geometry': [
        Polygon([(116.400, 39.910), (116.410, 39.910), (116.410, 39.920), (116.400, 39.920)]),
        Polygon([(116.420, 39.930), (116.430, 39.930), (116.430, 39.940), (116.420, 39.940)])
    ]
}, crs='EPSG:4326')

# 计算面积(自动进行投影转换)
result = tg.add_area(gdf, column='面积_平方米')

print(result[['plot_id', '面积_平方米']])
# plot_id  面积_平方米
# P001     11123400
# P002     11123400

✨ 技术细节

  • 自动选择最优UTM投影
  • 避免地理坐标系下的面积误差
  • 支持Polygon和MultiPolygon

案例7:计算线条长度(道路、河流等)

场景:城市规划部门有多条道路的线条数据,需要计算每条道路的长度。

python 复制代码
import geopandas as gpd
import tablegis as tg
from shapely.geometry import LineString

# 道路数据
gdf = gpd.GeoDataFrame({
    'road_id': ['R001', 'R002'],
    'geometry': [
        LineString([(116.400, 39.910), (116.410, 39.920), (116.420, 39.915)]),
        LineString([(116.420, 39.930), (116.440, 39.950)])
    ]
}, crs='EPSG:4326')

# 计算长度(单位:米)
result = tg.add_length(gdf, column='道路长度_米')

print(result[['road_id', '道路长度_米']])
# road_id  道路长度_米
# R001     2156.5
# R002     3142.3

✨ 应用场景

  • 道路养护预算计划
  • 供水管网设计
  • 电力网络规划

案例8:创建扇形区域

场景:无人机从某个位置出发,覆盖特定方向和距离的扇形区域,用于巡检规划。

python 复制代码
import pandas as pd
import tablegis as tg

# 无人机基地位置
bases = pd.DataFrame({
    'base_id': ['B001', 'B002'],
    'lon': [116.404, 116.407],
    'lat': [39.915, 39.918],
    'azimuth': [45, 90],        # 方向角(度数)
    'distance': [2000, 2500],   # 巡检距离(米)
    'angle': [60, 45]           # 扇形角度(度数)
})

# 创建扇形覆盖区域
result_gdf = tg.add_sectors(
    bases,
    lon='lon', lat='lat',
    azimuth='azimuth',
    distance='distance',
    angle='angle'
)

print(result_gdf)
# 可用于地图可视化或与其他图层做空间关系分析

✨ 特殊用途

  • 无人机/卫星覆盖范围规划
  • 信号塔覆盖分析
  • 防护区域划定

案例9:创建规则多边形(正方形、正六边形等)

场景:需要为每个配送中心创建一个1000米的服务区(以正方形表示),用于区域划分。

python 复制代码
import pandas as pd
import tablegis as tg

# 配送中心
centers = pd.DataFrame({
    'center_id': ['C001', 'C002'],
    'lon': [116.404, 116.407],
    'lat': [39.915, 39.918],
    'side_length': [2000, 2500]  # 正方形边长(米)
})

# 创建正方形覆盖区域
result_gdf = tg.add_polygon(
    centers,
    lon='lon', lat='lat',
    num_sides=4,              # 4边形 = 正方形
    side_length='side_length',
    rotation=45               # 旋转45度让边平行于坐标轴
)

# 也可以创建正六边形
result_hex = tg.add_polygon(
    centers,
    lon='lon', lat='lat',
    num_sides=6,              # 6边形 = 正六边形
    side_length=2000
)

print(result_gdf)
print(f"正方形面积:{result_gdf['geometry'].area.values[0]:.0f} 平方米")

✨ 应用场景

  • 蜂窝网格划分
  • 网格化数据汇总
  • 规划区域划分

案例10:将坐标匹配到行政区或其他图层属性

场景:有1000个客户的经纬度位置,需要批量查询他们分别在哪个社区、哪个行政区。

python 复制代码
import pandas as pd
import tablegis as tg
import geopandas as gpd

# 客户数据
customers = pd.DataFrame({
    'customer_id': ['CUST001', 'CUST002', 'CUST003'],
    'lon': [116.404, 116.405, 116.406],
    'lat': [39.915, 39.916, 39.917]
})

# 行政区图层(可从本地加载或使用现成的shp文件)
district_gdf = gpd.read_file('district.shp', encoding='gbk')

# 或者直接传入GeoDataFrame
result = tg.points_coverage_merge(
    customers,
    lon='lon', lat='lat',
    coverage=district_gdf,  # 可以是shp路径,也可以是GeoDataFrame
    df_merge_coverage_columns=['district_name', 'district_code'],
    merge_only_right_mark='未知'  # 匹配不到时的默认值
)

print(result[['customer_id', 'district_name', 'district_code']])
# customer_id  district_name  district_code
# CUST001      朝阳区          110105
# CUST002      朝阳区          110105
# CUST003      东城区          110101

✨ 强大之处

  • 支持大规模批量匹配(秒级)
  • 自动处理坐标系转换
  • 支持多个属性列同时返回
  • 支持多边形和点的所有空间关系查询

案例11:从WKT或16进制格式转换为GeoDataFrame

场景:从数据库中导出的几何数据是WKT或十六进制格式,需要转换为GeoDataFrame进行分析。

python 复制代码
import pandas as pd
import tablegis as tg

# 数据库导出的数据(WKT格式)
df_wkt = pd.DataFrame({
    'id': [1, 2],
    'geometry': [
        'POINT (116.404 39.915)',
        'POLYGON ((116.400 39.910, 116.410 39.910, 116.410 39.920, 116.400 39.920, 116.400 39.910))'
    ]
})

# 转换为GeoDataFrame
gdf = tg.df_to_gdf(df_wkt, geometry='geometry')
print(gdf)
print(f"坐标系:{gdf.crs}")  # EPSG:4326

# 如果是十六进制格式
df_hex = pd.DataFrame({
    'id': [1, 2],
    'geometry_hex': ['0101000000...', '010300000...']
})

gdf_hex = tg.df_to_gdf_16_10(df_hex, geometry_16='geometry_hex')
print(gdf_hex)

✨ 适用场景

  • 与数据库系统集成
  • 处理旧系统导出的数据
  • 数据迁移和格式转换

🎯 核心优势对比

操作 原生方案 TableGIS
距离计算 需要自己写Haversine公式 一行代码 distancea_str()
缓冲区 需要手动处理投影转换 自动选择UTM add_buffer()
两表关联距离 需要KDTree + 复杂循环 直接 min_distance_twotable()
坐标匹配图层 需要sjoin + 复杂处理 一行 points_coverage_merge()

🔧 高级技巧

技巧1:处理大规模数据

python 复制代码
# 当处理100万+条记录时,分批处理
import pandas as pd
import tablegis as tg

# 分块加载
for chunk in pd.read_csv('orders.csv', chunksize=10000):
    result = tg.min_distance_twotable(chunk, stations, n=3)
    # 逐块处理,减少内存占用
    result.to_csv('output.csv', mode='a')

技巧2:验证输入数据

python 复制代码
# 检查坐标范围
import numpy as np

def validate_coords(df, lon, lat):
    if not (df[lon].between(-180, 180).all() and df[lat].between(-90, 90).all()):
        print("⚠️ 发现异常坐标!")
        return False
    return True

# 使用前验证
if validate_coords(orders, 'lon', 'lat'):
    result = tg.min_distance_twotable(orders, stations, n=3)

技巧3:导出为不同格式

python 复制代码
import geopandas as gpd
import tablegis as tg

result_gdf = tg.add_buffer(hospitals, dis=1000)

# 导出为Shapefile
result_gdf.to_file('hospitals_coverage.shp', encoding='gbk')

# 导出为GeoJSON(可直接在网页地图上显示)
result_gdf.to_file('hospitals_coverage.geojson', driver='GeoJSON')

# 导出为KML(Google Earth)
result_gdf.to_file('hospitals_coverage.kml', driver='KML')

📚 常见问题速答

Q1:为什么距离计算结果与GPS不一致?

A:TableGIS使用Haversine公式,基于大圆距离,精度为±0.5%。GPS导航使用的是实际道路,结果会不同。

Q2:处理错误坐标系怎么办?

A:使用 to_lonlat() 函数进行坐标系转换,自动检测并转换为WGS84。

Q3:支持离线使用吗?

A:完全支持!所有计算都在本地进行,无需网络连接。

Q4:能处理多边形与多边形的关系吗?

A:可以,使用 gpd.sjoin() 结合TableGIS的预处理功能。


🌟 总结

TableGIS让复杂的地理空间计算变得简单直接,特别适合:

✅ 电商配送系统(找最近门店、分配运力)

✅ 地产开发(地块面积、容积率计算)

✅ 城市规划(区域划分、覆盖分析)

✅ 社交应用(找周边用户、推荐)

✅ 公共服务(医院学校覆盖分析)

立即开始使用

bash 复制代码
pip install tablegis
python 复制代码
import tablegis as tg
xxx

📖 更多资源


如果这篇文章对你有帮助,👍收藏!

有任何问题欢迎在评论区讨论,我会持续更新更多实战案例!

相关推荐
叫我:松哥2 小时前
基于YOLO深度学习算法的人群密集监测与统计分析预警系统,实现人群密集度的实时监测、智能分析和预警功能,支持图片和视频流两种输入方式
人工智能·深度学习·算法·yolo·机器学习·数据分析·flask
Dingdangcat862 小时前
驾驶行为识别▸方向盘握持与吸烟检测_YOLOv10n_LSCD_LQE模型详解
人工智能·yolo·目标跟踪
Lips6112 小时前
第七章 贝叶斯分类器
人工智能·算法·机器学习
xj7573065332 小时前
python中的序列化
服务器·数据库·python
郝学胜-神的一滴2 小时前
机器学习特征选择:深入理解移除低方差特征与sklearn的VarianceThreshold
开发语言·人工智能·python·机器学习·概率论·sklearn
HySpark2 小时前
智能语音识别基于模型优化与部署技术的轻量化方案
人工智能·语音识别
却道天凉_好个秋2 小时前
Tensorflow数据增强(一):图片的导入与显示
人工智能·python·tensorflow
一行注释也不写2 小时前
【循环神经网络(RNN)】隐藏状态在序列任务中的应用
人工智能·rnn·深度学习
屹立芯创ELEADTECH2 小时前
CoWoS封装技术全面解析:架构、演进与AI时代的基石作用
人工智能·架构