黄山市网站建设_网站建设公司_网站制作_seo优化
2026/1/10 2:36:19 网站建设 项目流程

Python GIS神器:一行代码搞定空间数据匹配(Point in Polygon)——tablegis库match_layer详解

前言

在数据分析、城市规划、物流配送、网格管理等领域,我们经常遇到这样的需求:

  • 城市规划/地产:手头有一堆POI兴趣点(经纬度),想知道它们分别属于哪个行政区、哪个商圈?
  • 物流/外卖:成千上万个订单地址,如何快速划分到不同的配送站或责任网格?
  • 环保/气象:监测站点数据,如何对应到具体的流域或气象分区?

在GIS(地理信息系统)中,这叫做**空间连接(Spatial Join)点在多边形内(Point in Polygon)**的问题。通常我们需要安装庞大的ArcGIS/QGIS软件,或者编写复杂的Geopandas/Shapely代码来处理。

今天介绍一个Python库tablegis,它封装了这些复杂操作,让你一行代码就能完成空间匹配,并且支持处理一对多(一个点在多个区域重叠)的复杂情况。

1. 安装与准备

首先,确保你的Python环境已经安装了tablegis

pipinstalltablegis

准备工作:
你需要两份数据:

  1. 点数据(DataFrame):包含经纬度的表格(如Excel、CSV),比如店铺列表、订单记录。
  2. 面数据(GeoDataFrame/Shapefile):包含区域边界的矢量数据,比如行政区划、网格围栏。

2. 核心方法:match_layer

match_layertablegis的核心功能之一,用于将“面数据”的属性“挂”到“点数据”上。

函数签名

importtablegisastg result=tg.match_layer(df,# 你的点数据(DataFrame)layer,# 你的面数据(GeoDataFrame 或 shp文件路径)lon='lon',# 点数据中经度列名lat='lat',# 点数据中纬度列名columns=None,# 你想获取面数据里的哪些列(比如 'district_name', 'zone_id')default_value=None,# 如果点不在任何区域内,填什么值(比如 '未知区域')match_method='one',# 匹配模式:'one' (取第一个), 'multi_cell' (合并), 'multi_row' (炸裂)sep=';',# 当 match_method='multi_cell' 时的分隔符predicate='intersects'# 空间关系,通常用默认的即可)

3. 实战案例

场景一:城市规划/商业分析 - 确定店铺所属行政区

假设你有一个店铺列表shops.csv,和北京市行政区划beijing_districts.shp

需求:给每个店铺加上“所属区县”字段。

importpandasaspdimportgeopandasasgpdimporttablegisastg# 1. 读取数据df_shops=pd.read_csv('shops.csv')# 假设数据长这样:# | shop_name | longitude | latitude |# |-----------|-----------|----------|# | 肯德基A店 | 116.40 | 39.90 |gdf_districts=gpd.read_file('beijing_districts.shp')# 假设数据长这样(带有geometry):# | district_name | district_code | geometry |# |---------------|---------------|----------|# | 朝阳区 | 110105 | POLYGON...|# 2. 一行代码匹配# 我们想要 'district_name' 这一列result=tg.match_layer(df_shops,gdf_districts,lon='longitude',lat='latitude',columns=['district_name'])print(result)# 结果会自动添加 district_name 列:# | shop_name | longitude | latitude | district_name |# |-----------|-----------|----------|---------------|# | 肯德基A店 | 116.40 | 39.90 | 东城区 |

场景二:物流配送 - 处理重叠区域(一对多匹配)

有时候区域是重叠的。比如一个快递点可能同时属于“朝阳区”和“CBD商圈”两个图层要素(如果它们在同一个图层里),或者在网格管理中,边界处的点可能算作两个网格的重叠区。

需求:如果一个点落在两个区域里,我要把两个区域的名字都记下来,用分号隔开。

# 使用 match_method='multi_cell'result=tg.match_layer(df_shops,gdf_zones,columns=['zone_name'],match_method='multi_cell',# 关键参数:合并单元格sep=';'# 分隔符)# 结果:# | shop_name | zone_name |# |-----------|-----------------|# | 某某店铺 | 责任区A;责任区B |

场景三:数据清洗 - 找出不在服务区的数据

需求:找出所有不在任何服务范围内的订单,标记为“超区”。

# 使用 default_valueresult=tg.match_layer(df_orders,gdf_service_areas,columns=['station_name'],default_value='超区'# 关键参数:缺失填充)# 结果:# | order_id | station_name |# |----------|--------------|# | 1001 | 望京站 |# | 1002 | 超区 |

场景四:精细化分析 - 一行拆多行(Explode)

需求:如果一个点属于多个区域,我希望它变成多行数据,每一行对应一个区域,方便后续透视表统计。

# 使用 match_method='multi_row'result=tg.match_layer(df_points,gdf_layers,columns=['type'],match_method='multi_row'# 关键参数:多行炸裂)# 原始数据1行 -> 结果可能变2行

4. 参数详解速查表

参数类型默认值说明
dfDataFrame必填你的左表(点数据)。
layerGeoDataFrame/str必填你的右表(面数据),可以是变量也可以是文件路径。
lon/latstr‘lon’/‘lat’指定df中经纬度的列名。
columnslist/strNone最重要:指定要从layer中获取哪些属性列。不填则获取除geometry外的所有列。
default_valueanyNone当点不在任何面上时,新列填充的值(默认是NaN)。
match_methodstr‘one’‘one’: 随便取一个匹配到的(默认);
‘multi_cell’: 匹配到多个时,将值合并成字符串(如 “A,B”);
‘multi_row’: 匹配到多个时,复制该行数据,产生多行。
sepstr‘;’当模式为 ‘multi_cell’ 时的连接符。

总结

tablegis.match_layer是一个非常适合非GIS专业背景开发者使用的工具。它屏蔽了坐标系转换(自动处理EPSG:4326)、空间索引构建等底层细节,让你能像用Excel的VLOOKUP一样,轻松实现“空间VLOOKUP”。

无论你是做数据清洗特征工程还是地理分析,这个函数都能极大地提高效率。


本文基于 tablegis 库编写,欢迎在 PyPI 下载使用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询