注意
空间连接#
一个 空间连接 使用 二元谓词 ,例如 intersects 和 crosses ,根据它们几何形状之间的空间关系来组合两个 GeoDataFrames 。
一个常见的用例可能是点层与多边形层之间的空间连接,在这种情况下,您希望保留点几何形状并获取相交多边形的属性。

空间连接的类型#
我们目前支持以下空间连接方法。我们指的是left_df和right_df,它们对应于作为参数传入的两个数据框。
左外连接#
在左外连接 (how='left') 中,我们保留 所有 来自左侧的行,并在必要时复制它们以表示两个数据框之间的多个匹配。如果右侧的属性相交,我们会保留这些属性,而丢失没有相交的右侧行。左外连接意味着我们对保留左侧的几何体感兴趣。
这相当于PostGIS查询:
SELECT pts.geom, pts.id as ptid, polys.id as polyid
FROM pts
LEFT OUTER JOIN polys
ON ST_Intersects(pts.geom, polys.geom);
geom | ptid | polyid
--------------------------------------------+------+--------
010100000040A9FBF2D88AD03F349CD47D796CE9BF | 4 | 10
010100000048EABE3CB622D8BFA8FBF2D88AA0E9BF | 3 | 10
010100000048EABE3CB622D8BFA8FBF2D88AA0E9BF | 3 | 20
0101000000F0D88AA0E1A4EEBF7052F7E5B115E9BF | 2 | 20
0101000000818693BA2F8FF7BF4ADD97C75604E9BF | 1 |
(5 rows)
右外连接#
在 RIGHT OUTER JOIN (how='right') 中,我们保留 所有 右侧的行,并在必要时重复它们以表示两个数据框之间的多个匹配。如果左侧的行相交,我们保留其属性,并丢弃那些没有相交的左侧行。右外连接意味着我们对保留右侧的几何图形感兴趣。
这相当于PostGIS查询:
SELECT polys.geom, pts.id as ptid, polys.id as polyid
FROM pts
RIGHT OUTER JOIN polys
ON ST_Intersects(pts.geom, polys.geom);
geom | ptid | polyid
----------+------+--------
01...9BF | 4 | 10
01...9BF | 3 | 10
02...7BF | 3 | 20
02...7BF | 2 | 20
00...5BF | | 30
(5 rows)
内连接#
在内连接 (how='inner') 中,我们仅保留左右两侧其二元谓词为 True 的行。如果有必要,我们会复制它们以表示两个数据框之间的多个匹配。我们仅保留左右两侧的属性,如果它们相交,并失去所有不相交的行。内连接意味着我们有兴趣保留左侧的几何形状。
这相当于 PostGIS 查询:
SELECT pts.geom, pts.id as ptid, polys.id as polyid
FROM pts
INNER JOIN polys
ON ST_Intersects(pts.geom, polys.geom);
geom | ptid | polyid
--------------------------------------------+------+--------
010100000040A9FBF2D88AD03F349CD47D796CE9BF | 4 | 10
010100000048EABE3CB622D8BFA8FBF2D88AA0E9BF | 3 | 10
010100000048EABE3CB622D8BFA8FBF2D88AA0E9BF | 3 | 20
0101000000F0D88AA0E1A4EEBF7052F7E5B115E9BF | 2 | 20
(4 rows)
两个GeoDataFrames之间的空间连接#
让我们看看如何使用 GeoPandas 来实现这些。首先,将纽约市测试数据加载到 GeoDataFrames 中:
[1]:
%matplotlib inline
from shapely.geometry import Point
from geopandas import GeoDataFrame, read_file
import geodatasets
# NYC Boros
zippath = geodatasets.get_path("nybb")
polydf = read_file(zippath)
# Generate some points
b = [int(x) for x in polydf.total_bounds]
N = 8
pointdf = GeoDataFrame(
[
{"geometry": Point(x, y), "value1": x + y, "value2": x - y}
for x, y in zip(
range(b[0], b[2], int((b[2] - b[0]) / N)),
range(b[1], b[3], int((b[3] - b[1]) / N)),
)
]
)
# Make sure they're using the same projection reference
pointdf.crs = polydf.crs
[2]:
pointdf
[2]:
| 几何 | 值1 | 值2 | |
|---|---|---|---|
| 0 | 点 (913175 120121) | 1033296 | 793054 |
| 1 | 点 (932450 139211) | 1071661 | 793239 |
| 2 | 点 (951725 158301) | 1110026 | 793424 |
| 3 | 点 (971000 177391) | 1148391 | 793609 |
| 4 | POINT (990275 196481) | 1186756 | 793794 |
| 5 | POINT (1009550 215571) | 1225121 | 793979 |
| 6 | 点 (1028825 234661) | 1263486 | 794164 |
| 7 | 点 (1048100 253751) | 1301851 | 794349 |
| 8 | POINT (1067375 272841) | 1340216 | 794534 |
[3]:
polydf
[3]:
| 行政区代码 | 行政区名称 | 形状长度 | 形状面积 | 几何 | |
|---|---|---|---|---|---|
| 0 | 5 | 史坦顿岛 | 330470.010332 | 1.623820e+09 | MULTIPOLYGON (((970217.022 145643.332, 970227.... |
| 1 | 4 | 皇后区 | 896344.047763 | 3.045213e+09 | MULTIPOLYGON (((1029606.077 156073.814, 102957... |
| 2 | 3 | 布鲁克林 | 741080.523166 | 1.937479e+09 | MULTIPOLYGON (((1021176.479 151374.797, 102100... |
| 3 | 1 | 曼哈顿 | 359299.096471 | 6.364715e+08 | 多边形 (((981219.056 188655.316, 980940.... |
| 4 | 2 | 布朗克斯 | 464392.991824 | 1.186925e+09 | MULTIPOLYGON (((1012821.806 229228.265, 101278... |
[4]:
pointdf.plot()
[4]:
<Axes: >
[5]:
polydf.plot()
[5]:
<Axes: >
连接#
[6]:
join_left_df = pointdf.sjoin(polydf, how="left")
join_left_df
# Note the NaNs where the point did not intersect a boro
[6]:
| 几何 | 值1 | 值2 | 右索引 | 区代码 | 区名称 | 形状长度 | 形状面积 | |
|---|---|---|---|---|---|---|---|---|
| 0 | 点 (913175 120121) | 1033296 | 793054 | 无 | 无 | 无 | 无 | 无 |
| 1 | POINT (932450 139211) | 1071661 | 793239 | 0.0 | 5.0 | 斯塔滕岛 | 330470.010332 | 1.623820e+09 |
| 2 | POINT (951725 158301) | 1110026 | 793424 | 0.0 | 5.0 | 斯坦顿岛 | 330470.010332 | 1.623820e+09 |
| 3 | POINT (971000 177391) | 1148391 | 793609 | 无效值 | 无效值 | 无效值 | 无效值 | 无效值 |
| 4 | POINT (990275 196481) | 1186756 | 793794 | 无效值 | 无效值 | 无效值 | 无效值 | 无效值 |
| 5 | POINT (1009550 215571) | 1225121 | 793979 | 1.0 | 4.0 | 皇后区 | 896344.047763 | 3.045213e+09 |
| 6 | POINT (1028825 234661) | 1263486 | 794164 | 4.0 | 2.0 | 布朗克斯 | 464392.991824 | 1.186925e+09 |
| 7 | POINT (1048100 253751) | 1301851 | 794349 | 无 | 无 | 无 | 无 | 无 |
| 8 | POINT (1067375 272841) | 1340216 | 794534 | 缺失值 | 缺失值 | 缺失值 | 缺失值 | 缺失值 |
[7]:
join_right_df = pointdf.sjoin(polydf, how="right")
join_right_df
# Note Staten Island is repeated
[7]:
| 左索引 | 值1 | 值2 | 区代码 | 区名称 | 形状长度 | 形状面积 | 几何形状 | |
|---|---|---|---|---|---|---|---|---|
| 0 | 1.0 | 1071661.0 | 793239.0 | 5 | 斯塔滕岛 | 330470.010332 | 1.623820e+09 | MULTIPOLYGON (((970217.022 145643.332, 970227.... |
| 0 | 2.0 | 1110026.0 | 793424.0 | 5 | 史泰登岛 | 330470.010332 | 1.623820e+09 | MULTIPOLYGON (((970217.022 145643.332, 970227.... |
| 1 | 5.0 | 1225121.0 | 793979.0 | 4 | 皇后区 | 896344.047763 | 3.045213e+09 | MULTIPOLYGON (((1029606.077 156073.814, 102957... |
| 2 | NaN | NaN | NaN | 3 | 布鲁克林 | 741080.523166 | 1.937479e+09 | MULTIPOLYGON (((1021176.479 151374.797, 102100... |
| 3 | NaN | NaN | NaN | 1 | 曼哈顿 | 359299.096471 | 6.364715e+08 | MULTIPOLYGON (((981219.056 188655.316, 980940.... |
| 4 | 6.0 | 1263486.0 | 794164.0 | 2 | 布朗克斯 | 464392.991824 | 1.186925e+09 | MULTIPOLYGON (((1012821.806 229228.265, 101278... |
[8]:
join_inner_df = pointdf.sjoin(polydf, how="inner")
join_inner_df
# Note the lack of NaNs; dropped anything that didn't intersect
[8]:
| 几何 | 值1 | 值2 | 右索引 | 区代码 | 区名称 | 形状长度 | 形状面积 | |
|---|---|---|---|---|---|---|---|---|
| 1 | POINT (932450 139211) | 1071661 | 793239 | 0 | 5 | 史泰登岛 | 330470.010332 | 1.623820e+09 |
| 2 | POINT (951725 158301) | 1110026 | 793424 | 0 | 5 | 斯塔滕岛 | 330470.010332 | 1.623820e+09 |
| 5 | POINT (1009550 215571) | 1225121 | 793979 | 1 | 4 | 皇后区 | 896344.047763 | 3.045213e+09 |
| 6 | POINT (1028825 234661) | 1263486 | 794164 | 4 | 2 | 布朗克斯 | 464392.991824 | 1.186925e+09 |
我们不仅限于使用 intersection 二元谓词。可以通过指定 predicate 关键字参数使用任何返回布尔值的 Shapely 几何方法。
[9]:
pointdf.sjoin(polydf, how="left", predicate="within")
[9]:
| 几何 | 值1 | 值2 | 右索引 | 区代码 | 区名称 | 形状长度 | 形状面积 | |
|---|---|---|---|---|---|---|---|---|
| 0 | 点 (913175 120121) | 1033296 | 793054 | 无 | 无 | 无 | 无 | 无 |
| 1 | POINT (932450 139211) | 1071661 | 793239 | 0.0 | 5.0 | 斯塔滕岛 | 330470.010332 | 1.623820e+09 |
| 2 | POINT (951725 158301) | 1110026 | 793424 | 0.0 | 5.0 | 斯坦顿岛 | 330470.010332 | 1.623820e+09 |
| 3 | POINT (971000 177391) | 1148391 | 793609 | 无效值 | 无效值 | 无效值 | 无效值 | 无效值 |
| 4 | POINT (990275 196481) | 1186756 | 793794 | 无效值 | 无效值 | 无效值 | 无效值 | 无效值 |
| 5 | POINT (1009550 215571) | 1225121 | 793979 | 1.0 | 4.0 | 皇后区 | 896344.047763 | 3.045213e+09 |
| 6 | POINT (1028825 234661) | 1263486 | 794164 | 4.0 | 2.0 | 布朗克斯 | 464392.991824 | 1.186925e+09 |
| 7 | POINT (1048100 253751) | 1301851 | 794349 | 无 | 无 | 无 | 无 | 无 |
| 8 | POINT (1067375 272841) | 1340216 | 794534 | 缺失值 | 缺失值 | 缺失值 | 缺失值 | 缺失值 |
我们还可以使用 sjoin_nearest 进行最近邻连接。
[10]:
pointdf.sjoin_nearest(polydf, how="left", distance_col="Distances")
# Note the optional Distances column with computed distances between each point
# and the nearest polydf geometry.
[10]:
| 几何 | 值1 | 值2 | 右索引 | 区代码 | 区名称 | 形状长度 | 形状面积 | 距离 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | POINT (913175 120121) | 1033296 | 793054 | 0 | 5 | 斯塔滕岛 | 330470.010332 | 1.623820e+09 | 1479.291092 |
| 1 | POINT (932450 139211) | 1071661 | 793239 | 0 | 5 | 斯塔滕岛 | 330470.010332 | 1.623820e+09 | 0.000000 |
| 2 | POINT (951725 158301) | 1110026 | 793424 | 0 | 5 | 斯塔滕岛 | 330470.010332 | 1.623820e+09 | 0.000000 |
| 3 | POINT (971000 177391) | 1148391 | 793609 | 2 | 3 | 布鲁克林 | 741080.523166 | 1.937479e+09 | 5075.979291 |
| 4 | POINT (990275 196481) | 1186756 | 793794 | 2 | 3 | 布鲁克林 | 741080.523166 | 1.937479e+09 | 22.361467 |
| 5 | POINT (1009550 215571) | 1225121 | 793979 | 1 | 4 | 皇后区 | 896344.047763 | 3.045213e+09 | 0.000000 |
| 6 | POINT (1028825 234661) | 1263486 | 794164 | 4 | 2 | 布朗克斯 | 464392.991824 | 1.186925e+09 | 0.000000 |
| 7 | POINT (1048100 253751) | 1301851 | 794349 | 4 | 2 | 布朗克斯 | 464392.991824 | 1.186925e+09 | 818.940377 |
| 8 | POINT (1067375 272841) | 1340216 | 794534 | 4 | 2 | 布朗克斯 | 464392.991824 | 1.186925e+09 | 25368.109000 |