集合-覆盖操作#

使用多个空间数据集时--尤其是多个 多边形line 数据集--用户通常希望根据这些数据集重叠(或不重叠)的位置创建新形状。这些操作通常使用集合的语言--交集、并集和差集。这些类型的操作在 地貌熊猫 库通过 overlay() 方法。

基本思想如下图所示,但请记住,覆盖是在DataFrame级别上操作的,而不是在单个几何图形上操作,并且两者的属性都会被保留。实际上,对于左侧的每个形状 GeoDataFrame ,则对右侧的每一个其他形状执行此操作 GeoDataFrame

../../_images/overlay_operations.png

资料来源:QGIS文档

备注

熟悉的用户请注意 整齐地 库: overlay() 可以被认为是提供标准的版本 整齐地 集合运算处理将集合运算应用于 GeoSeries 。标准 整齐地 集合运算还可以通过以下方式使用 GeoSeries 方法。

不同的叠加操作#

首先,我们创建一些示例数据:

In [1]: from shapely.geometry import Polygon

In [2]: polys1 = geopandas.GeoSeries([Polygon([(0,0), (2,0), (2,2), (0,2)]),
   ...:                               Polygon([(2,2), (4,2), (4,4), (2,4)])])
   ...: 

In [3]: polys2 = geopandas.GeoSeries([Polygon([(1,1), (3,1), (3,3), (1,3)]),
   ...:                               Polygon([(3,3), (5,3), (5,5), (3,5)])])
   ...: 

In [4]: df1 = geopandas.GeoDataFrame({'geometry': polys1, 'df1':[1,2]})

In [5]: df2 = geopandas.GeoDataFrame({'geometry': polys2, 'df2':[1,2]})

这两个GeoDataFrame有一些重叠的区域:

In [6]: ax = df1.plot(color='red');

In [7]: df2.plot(ax=ax, color='green', alpha=0.5);
../../_images/overlay_example.png

我们用上面的例子说明了不同的覆盖模式。这个 overlay() 方法将通过叠加两个输入GeoDataFrame来确定所有单独几何图形的集合。该结果覆盖了两个输入GeoDataFrame所覆盖的区域,并且还保留了由两个GeoDataFrame的组合边界定义的所有唯一区域。

备注

由于历史原因,Overlay方法也可以作为顶级函数使用 overlay() 。建议使用该方法,因为该函数在将来可能会被弃用。

在使用时 how='union' ,则返回所有可能的几何图形:

In [8]: res_union = df1.overlay(df2, how='union')
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Input In [8], in <cell line: 1>()
----> 1 res_union = df1.overlay(df2, how='union')

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/geodataframe.py:2245, in GeoDataFrame.overlay(self, right, how, keep_geom_type, make_valid)
   2157 def overlay(self, right, how="intersection", keep_geom_type=None, make_valid=True):
   2158     """Perform spatial overlay between GeoDataFrames.
   2159 
   2160     Currently only supports data GeoDataFrames with uniform geometry types,
   (...)
   2243     dimension is not taken into account.
   2244     """
-> 2245     return geopandas.overlay(
   2246         self, right, how=how, keep_geom_type=keep_geom_type, make_valid=make_valid
   2247     )

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:321, in overlay(df1, df2, how, keep_geom_type, make_valid)
    319     result = _overlay_symmetric_diff(df1, df2)
    320 elif how == "union":
--> 321     result = _overlay_union(df1, df2)
    322 elif how == "identity":
    323     dfunion = _overlay_union(df1, df2)

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:136, in _overlay_union(df1, df2)
    132 def _overlay_union(df1, df2):
    133     """
    134     Overlay Union operation used in overlay function
    135     """
--> 136     dfinter = _overlay_intersection(df1, df2)
    137     dfsym = _overlay_symmetric_diff(df1, df2)
    138     dfunion = pd.concat([dfinter, dfsym], ignore_index=True, sort=False)

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:30, in _overlay_intersection(df1, df2)
     26 """
     27 Overlay Intersection operation used in overlay function
     28 """
     29 # Spatial Index to create intersections
---> 30 idx1, idx2 = df2.sindex.query_bulk(df1.geometry, predicate="intersects", sort=True)
     31 # Create pairs of geometries in both dataframes to be intersected
     32 if idx1.size > 0 and idx2.size > 0:

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/base.py:2706, in GeoPandasBase.sindex(self)
   2655 @property
   2656 def sindex(self):
   2657     """Generate the spatial index
   2658 
   2659     Creates R-tree spatial index based on ``pygeos.STRtree`` or
   (...)
   2704            [2]])
   2705     """
-> 2706     return self.geometry.values.sindex

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/array.py:291, in GeometryArray.sindex(self)
    288 @property
    289 def sindex(self):
    290     if self._sindex is None:
--> 291         self._sindex = _get_sindex_class()(self.data)
    292     return self._sindex

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/sindex.py:21, in _get_sindex_class()
     19 if compat.HAS_RTREE:
     20     return RTreeIndex
---> 21 raise ImportError(
     22     "Spatial indexes require either `rtree` or `pygeos`. "
     23     "See installation instructions at https://geopandas.org/install.html"
     24 )

ImportError: Spatial indexes require either `rtree` or `pygeos`. See installation instructions at https://geopandas.org/install.html

In [9]: res_union
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Input In [9], in <cell line: 1>()
----> 1 res_union

NameError: name 'res_union' is not defined

In [10]: ax = res_union.plot(alpha=0.5, cmap='tab10')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Input In [10], in <cell line: 1>()
----> 1 ax = res_union.plot(alpha=0.5, cmap='tab10')

NameError: name 'res_union' is not defined

In [11]: df1.plot(ax=ax, facecolor='none', edgecolor='k');

In [12]: df2.plot(ax=ax, facecolor='none', edgecolor='k');
../../_images/overlay_example_union.png

另一个 how 操作将返回这些几何图形的不同子集。使用 how='intersection' ,它只返回这两个GeoDataFrame包含的几何图形:

In [13]: res_intersection = df1.overlay(df2, how='intersection')
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Input In [13], in <cell line: 1>()
----> 1 res_intersection = df1.overlay(df2, how='intersection')

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/geodataframe.py:2245, in GeoDataFrame.overlay(self, right, how, keep_geom_type, make_valid)
   2157 def overlay(self, right, how="intersection", keep_geom_type=None, make_valid=True):
   2158     """Perform spatial overlay between GeoDataFrames.
   2159 
   2160     Currently only supports data GeoDataFrames with uniform geometry types,
   (...)
   2243     dimension is not taken into account.
   2244     """
-> 2245     return geopandas.overlay(
   2246         self, right, how=how, keep_geom_type=keep_geom_type, make_valid=make_valid
   2247     )

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:317, in overlay(df1, df2, how, keep_geom_type, make_valid)
    315     result = _overlay_difference(df1, df2)
    316 elif how == "intersection":
--> 317     result = _overlay_intersection(df1, df2)
    318 elif how == "symmetric_difference":
    319     result = _overlay_symmetric_diff(df1, df2)

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:30, in _overlay_intersection(df1, df2)
     26 """
     27 Overlay Intersection operation used in overlay function
     28 """
     29 # Spatial Index to create intersections
---> 30 idx1, idx2 = df2.sindex.query_bulk(df1.geometry, predicate="intersects", sort=True)
     31 # Create pairs of geometries in both dataframes to be intersected
     32 if idx1.size > 0 and idx2.size > 0:

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/base.py:2706, in GeoPandasBase.sindex(self)
   2655 @property
   2656 def sindex(self):
   2657     """Generate the spatial index
   2658 
   2659     Creates R-tree spatial index based on ``pygeos.STRtree`` or
   (...)
   2704            [2]])
   2705     """
-> 2706     return self.geometry.values.sindex

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/array.py:291, in GeometryArray.sindex(self)
    288 @property
    289 def sindex(self):
    290     if self._sindex is None:
--> 291         self._sindex = _get_sindex_class()(self.data)
    292     return self._sindex

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/sindex.py:21, in _get_sindex_class()
     19 if compat.HAS_RTREE:
     20     return RTreeIndex
---> 21 raise ImportError(
     22     "Spatial indexes require either `rtree` or `pygeos`. "
     23     "See installation instructions at https://geopandas.org/install.html"
     24 )

ImportError: Spatial indexes require either `rtree` or `pygeos`. See installation instructions at https://geopandas.org/install.html

In [14]: res_intersection
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Input In [14], in <cell line: 1>()
----> 1 res_intersection

NameError: name 'res_intersection' is not defined

In [15]: ax = res_intersection.plot(cmap='tab10')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Input In [15], in <cell line: 1>()
----> 1 ax = res_intersection.plot(cmap='tab10')

NameError: name 'res_intersection' is not defined

In [16]: df1.plot(ax=ax, facecolor='none', edgecolor='k');

In [17]: df2.plot(ax=ax, facecolor='none', edgecolor='k');
../../_images/overlay_example_intersection.png

how='symmetric_difference' 是与 'intersection' 并返回只属于其中一个GeoDataFrame而不属于两个GeoDataFrame的几何图形:

In [18]: res_symdiff = df1.overlay(df2, how='symmetric_difference')
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Input In [18], in <cell line: 1>()
----> 1 res_symdiff = df1.overlay(df2, how='symmetric_difference')

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/geodataframe.py:2245, in GeoDataFrame.overlay(self, right, how, keep_geom_type, make_valid)
   2157 def overlay(self, right, how="intersection", keep_geom_type=None, make_valid=True):
   2158     """Perform spatial overlay between GeoDataFrames.
   2159 
   2160     Currently only supports data GeoDataFrames with uniform geometry types,
   (...)
   2243     dimension is not taken into account.
   2244     """
-> 2245     return geopandas.overlay(
   2246         self, right, how=how, keep_geom_type=keep_geom_type, make_valid=make_valid
   2247     )

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:319, in overlay(df1, df2, how, keep_geom_type, make_valid)
    317     result = _overlay_intersection(df1, df2)
    318 elif how == "symmetric_difference":
--> 319     result = _overlay_symmetric_diff(df1, df2)
    320 elif how == "union":
    321     result = _overlay_union(df1, df2)

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:107, in _overlay_symmetric_diff(df1, df2)
    103 def _overlay_symmetric_diff(df1, df2):
    104     """
    105     Overlay Symmetric Difference operation used in overlay function
    106     """
--> 107     dfdiff1 = _overlay_difference(df1, df2)
    108     dfdiff2 = _overlay_difference(df2, df1)
    109     dfdiff1["__idx1"] = range(len(dfdiff1))

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:80, in _overlay_difference(df1, df2)
     76 """
     77 Overlay Difference operation used in overlay function
     78 """
     79 # spatial index query to find intersections
---> 80 idx1, idx2 = df2.sindex.query_bulk(df1.geometry, predicate="intersects", sort=True)
     81 idx1_unique, idx1_unique_indices = np.unique(idx1, return_index=True)
     82 idx2_split = np.split(idx2, idx1_unique_indices[1:])

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/base.py:2706, in GeoPandasBase.sindex(self)
   2655 @property
   2656 def sindex(self):
   2657     """Generate the spatial index
   2658 
   2659     Creates R-tree spatial index based on ``pygeos.STRtree`` or
   (...)
   2704            [2]])
   2705     """
-> 2706     return self.geometry.values.sindex

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/array.py:291, in GeometryArray.sindex(self)
    288 @property
    289 def sindex(self):
    290     if self._sindex is None:
--> 291         self._sindex = _get_sindex_class()(self.data)
    292     return self._sindex

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/sindex.py:21, in _get_sindex_class()
     19 if compat.HAS_RTREE:
     20     return RTreeIndex
---> 21 raise ImportError(
     22     "Spatial indexes require either `rtree` or `pygeos`. "
     23     "See installation instructions at https://geopandas.org/install.html"
     24 )

ImportError: Spatial indexes require either `rtree` or `pygeos`. See installation instructions at https://geopandas.org/install.html

In [19]: res_symdiff
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Input In [19], in <cell line: 1>()
----> 1 res_symdiff

NameError: name 'res_symdiff' is not defined

In [20]: ax = res_symdiff.plot(cmap='tab10')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Input In [20], in <cell line: 1>()
----> 1 ax = res_symdiff.plot(cmap='tab10')

NameError: name 'res_symdiff' is not defined

In [21]: df1.plot(ax=ax, facecolor='none', edgecolor='k');

In [22]: df2.plot(ax=ax, facecolor='none', edgecolor='k');
../../_images/overlay_example_symdiff.png

获取属于的几何图形的步骤 df1 但不包含在 df2 ,您可以使用 how='difference'

In [23]: res_difference = df1.overlay(df2, how='difference')
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Input In [23], in <cell line: 1>()
----> 1 res_difference = df1.overlay(df2, how='difference')

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/geodataframe.py:2245, in GeoDataFrame.overlay(self, right, how, keep_geom_type, make_valid)
   2157 def overlay(self, right, how="intersection", keep_geom_type=None, make_valid=True):
   2158     """Perform spatial overlay between GeoDataFrames.
   2159 
   2160     Currently only supports data GeoDataFrames with uniform geometry types,
   (...)
   2243     dimension is not taken into account.
   2244     """
-> 2245     return geopandas.overlay(
   2246         self, right, how=how, keep_geom_type=keep_geom_type, make_valid=make_valid
   2247     )

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:315, in overlay(df1, df2, how, keep_geom_type, make_valid)
    313 warnings.filterwarnings("ignore", message="CRS mismatch between the CRS")
    314 if how == "difference":
--> 315     result = _overlay_difference(df1, df2)
    316 elif how == "intersection":
    317     result = _overlay_intersection(df1, df2)

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:80, in _overlay_difference(df1, df2)
     76 """
     77 Overlay Difference operation used in overlay function
     78 """
     79 # spatial index query to find intersections
---> 80 idx1, idx2 = df2.sindex.query_bulk(df1.geometry, predicate="intersects", sort=True)
     81 idx1_unique, idx1_unique_indices = np.unique(idx1, return_index=True)
     82 idx2_split = np.split(idx2, idx1_unique_indices[1:])

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/base.py:2706, in GeoPandasBase.sindex(self)
   2655 @property
   2656 def sindex(self):
   2657     """Generate the spatial index
   2658 
   2659     Creates R-tree spatial index based on ``pygeos.STRtree`` or
   (...)
   2704            [2]])
   2705     """
-> 2706     return self.geometry.values.sindex

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/array.py:291, in GeometryArray.sindex(self)
    288 @property
    289 def sindex(self):
    290     if self._sindex is None:
--> 291         self._sindex = _get_sindex_class()(self.data)
    292     return self._sindex

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/sindex.py:21, in _get_sindex_class()
     19 if compat.HAS_RTREE:
     20     return RTreeIndex
---> 21 raise ImportError(
     22     "Spatial indexes require either `rtree` or `pygeos`. "
     23     "See installation instructions at https://geopandas.org/install.html"
     24 )

ImportError: Spatial indexes require either `rtree` or `pygeos`. See installation instructions at https://geopandas.org/install.html

In [24]: res_difference
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Input In [24], in <cell line: 1>()
----> 1 res_difference

NameError: name 'res_difference' is not defined

In [25]: ax = res_difference.plot(cmap='tab10')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Input In [25], in <cell line: 1>()
----> 1 ax = res_difference.plot(cmap='tab10')

NameError: name 'res_difference' is not defined

In [26]: df1.plot(ax=ax, facecolor='none', edgecolor='k');

In [27]: df2.plot(ax=ax, facecolor='none', edgecolor='k');
../../_images/overlay_example_difference.png

最后,通过 how='identity' ,结果由的曲面组成 df1 ,但具有通过叠加获得的几何图形 df1 使用 df2

In [28]: res_identity = df1.overlay(df2, how='identity')
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Input In [28], in <cell line: 1>()
----> 1 res_identity = df1.overlay(df2, how='identity')

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/geodataframe.py:2245, in GeoDataFrame.overlay(self, right, how, keep_geom_type, make_valid)
   2157 def overlay(self, right, how="intersection", keep_geom_type=None, make_valid=True):
   2158     """Perform spatial overlay between GeoDataFrames.
   2159 
   2160     Currently only supports data GeoDataFrames with uniform geometry types,
   (...)
   2243     dimension is not taken into account.
   2244     """
-> 2245     return geopandas.overlay(
   2246         self, right, how=how, keep_geom_type=keep_geom_type, make_valid=make_valid
   2247     )

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:323, in overlay(df1, df2, how, keep_geom_type, make_valid)
    321     result = _overlay_union(df1, df2)
    322 elif how == "identity":
--> 323     dfunion = _overlay_union(df1, df2)
    324     result = dfunion[dfunion["__idx1"].notnull()].copy()
    326 if how in ["intersection", "symmetric_difference", "union", "identity"]:

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:136, in _overlay_union(df1, df2)
    132 def _overlay_union(df1, df2):
    133     """
    134     Overlay Union operation used in overlay function
    135     """
--> 136     dfinter = _overlay_intersection(df1, df2)
    137     dfsym = _overlay_symmetric_diff(df1, df2)
    138     dfunion = pd.concat([dfinter, dfsym], ignore_index=True, sort=False)

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:30, in _overlay_intersection(df1, df2)
     26 """
     27 Overlay Intersection operation used in overlay function
     28 """
     29 # Spatial Index to create intersections
---> 30 idx1, idx2 = df2.sindex.query_bulk(df1.geometry, predicate="intersects", sort=True)
     31 # Create pairs of geometries in both dataframes to be intersected
     32 if idx1.size > 0 and idx2.size > 0:

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/base.py:2706, in GeoPandasBase.sindex(self)
   2655 @property
   2656 def sindex(self):
   2657     """Generate the spatial index
   2658 
   2659     Creates R-tree spatial index based on ``pygeos.STRtree`` or
   (...)
   2704            [2]])
   2705     """
-> 2706     return self.geometry.values.sindex

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/array.py:291, in GeometryArray.sindex(self)
    288 @property
    289 def sindex(self):
    290     if self._sindex is None:
--> 291         self._sindex = _get_sindex_class()(self.data)
    292     return self._sindex

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/sindex.py:21, in _get_sindex_class()
     19 if compat.HAS_RTREE:
     20     return RTreeIndex
---> 21 raise ImportError(
     22     "Spatial indexes require either `rtree` or `pygeos`. "
     23     "See installation instructions at https://geopandas.org/install.html"
     24 )

ImportError: Spatial indexes require either `rtree` or `pygeos`. See installation instructions at https://geopandas.org/install.html

In [29]: res_identity
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Input In [29], in <cell line: 1>()
----> 1 res_identity

NameError: name 'res_identity' is not defined

In [30]: ax = res_identity.plot(cmap='tab10')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Input In [30], in <cell line: 1>()
----> 1 ax = res_identity.plot(cmap='tab10')

NameError: name 'res_identity' is not defined

In [31]: df1.plot(ax=ax, facecolor='none', edgecolor='k');

In [32]: df2.plot(ax=ax, facecolor='none', edgecolor='k');
../../_images/overlay_example_identity.png

覆盖国家/地区示例#

首先,我们加载国家和城市示例数据集并选择:

In [33]: world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))

In [34]: capitals = geopandas.read_file(geopandas.datasets.get_path('naturalearth_cities'))

# Select South America and some columns
In [35]: countries = world[world['continent'] == "South America"]

In [36]: countries = countries[['geometry', 'name']]

# Project to crs that uses meters as distance measure
In [37]: countries = countries.to_crs('epsg:3395')

In [38]: capitals = capitals.to_crs('epsg:3395')

为了说明 overlay() 方法,考虑以下情况,在这种情况下,希望使用 GeoDataFrame 国家和地区的 GeoDataFrame 大写字母。

# Look at countries:
In [39]: countries.plot();

# Now buffer cities to find area within 500km.
# Check CRS -- World Mercator, units of meters.
In [40]: capitals.crs
Out[40]: 
<Derived Projected CRS: EPSG:3395>
Name: WGS 84 / World Mercator
Axis Info [cartesian]:
- E[east]: Easting (metre)
- N[north]: Northing (metre)
Area of Use:
- name: World between 80°S and 84°N.
- bounds: (-180.0, -80.0, 180.0, 84.0)
Coordinate Operation:
- name: World Mercator
- method: Mercator (variant A)
Datum: World Geodetic System 1984 ensemble
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich

# make 500km buffer
In [41]: capitals['geometry']= capitals.buffer(500000)

In [42]: capitals.plot();
../../_images/world_basic.png ../../_images/capital_buffers.png

为了只选择首都500公里范围内的国家,我们指定 how 选项为“INTERSECT”,这将在这两个层重叠的位置创建一组新的多边形集:

In [43]: country_cores = countries.overlay(capitals, how='intersection')
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Input In [43], in <cell line: 1>()
----> 1 country_cores = countries.overlay(capitals, how='intersection')

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/geodataframe.py:2245, in GeoDataFrame.overlay(self, right, how, keep_geom_type, make_valid)
   2157 def overlay(self, right, how="intersection", keep_geom_type=None, make_valid=True):
   2158     """Perform spatial overlay between GeoDataFrames.
   2159 
   2160     Currently only supports data GeoDataFrames with uniform geometry types,
   (...)
   2243     dimension is not taken into account.
   2244     """
-> 2245     return geopandas.overlay(
   2246         self, right, how=how, keep_geom_type=keep_geom_type, make_valid=make_valid
   2247     )

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:317, in overlay(df1, df2, how, keep_geom_type, make_valid)
    315     result = _overlay_difference(df1, df2)
    316 elif how == "intersection":
--> 317     result = _overlay_intersection(df1, df2)
    318 elif how == "symmetric_difference":
    319     result = _overlay_symmetric_diff(df1, df2)

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:30, in _overlay_intersection(df1, df2)
     26 """
     27 Overlay Intersection operation used in overlay function
     28 """
     29 # Spatial Index to create intersections
---> 30 idx1, idx2 = df2.sindex.query_bulk(df1.geometry, predicate="intersects", sort=True)
     31 # Create pairs of geometries in both dataframes to be intersected
     32 if idx1.size > 0 and idx2.size > 0:

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/base.py:2706, in GeoPandasBase.sindex(self)
   2655 @property
   2656 def sindex(self):
   2657     """Generate the spatial index
   2658 
   2659     Creates R-tree spatial index based on ``pygeos.STRtree`` or
   (...)
   2704            [2]])
   2705     """
-> 2706     return self.geometry.values.sindex

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/array.py:291, in GeometryArray.sindex(self)
    288 @property
    289 def sindex(self):
    290     if self._sindex is None:
--> 291         self._sindex = _get_sindex_class()(self.data)
    292     return self._sindex

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/sindex.py:21, in _get_sindex_class()
     19 if compat.HAS_RTREE:
     20     return RTreeIndex
---> 21 raise ImportError(
     22     "Spatial indexes require either `rtree` or `pygeos`. "
     23     "See installation instructions at https://geopandas.org/install.html"
     24 )

ImportError: Spatial indexes require either `rtree` or `pygeos`. See installation instructions at https://geopandas.org/install.html

In [44]: country_cores.plot(alpha=0.5, edgecolor='k', cmap='tab10');
../../_images/country_cores.png

更改“How”选项允许不同类型的覆盖操作。例如,如果我们对国家的部分感兴趣 far 从首都(外围)出发,我们可以计算出两者的差额。

In [45]: country_peripheries = countries.overlay(capitals, how='difference')
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Input In [45], in <cell line: 1>()
----> 1 country_peripheries = countries.overlay(capitals, how='difference')

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/geodataframe.py:2245, in GeoDataFrame.overlay(self, right, how, keep_geom_type, make_valid)
   2157 def overlay(self, right, how="intersection", keep_geom_type=None, make_valid=True):
   2158     """Perform spatial overlay between GeoDataFrames.
   2159 
   2160     Currently only supports data GeoDataFrames with uniform geometry types,
   (...)
   2243     dimension is not taken into account.
   2244     """
-> 2245     return geopandas.overlay(
   2246         self, right, how=how, keep_geom_type=keep_geom_type, make_valid=make_valid
   2247     )

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:315, in overlay(df1, df2, how, keep_geom_type, make_valid)
    313 warnings.filterwarnings("ignore", message="CRS mismatch between the CRS")
    314 if how == "difference":
--> 315     result = _overlay_difference(df1, df2)
    316 elif how == "intersection":
    317     result = _overlay_intersection(df1, df2)

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/tools/overlay.py:80, in _overlay_difference(df1, df2)
     76 """
     77 Overlay Difference operation used in overlay function
     78 """
     79 # spatial index query to find intersections
---> 80 idx1, idx2 = df2.sindex.query_bulk(df1.geometry, predicate="intersects", sort=True)
     81 idx1_unique, idx1_unique_indices = np.unique(idx1, return_index=True)
     82 idx2_split = np.split(idx2, idx1_unique_indices[1:])

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/base.py:2706, in GeoPandasBase.sindex(self)
   2655 @property
   2656 def sindex(self):
   2657     """Generate the spatial index
   2658 
   2659     Creates R-tree spatial index based on ``pygeos.STRtree`` or
   (...)
   2704            [2]])
   2705     """
-> 2706     return self.geometry.values.sindex

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/array.py:291, in GeometryArray.sindex(self)
    288 @property
    289 def sindex(self):
    290     if self._sindex is None:
--> 291         self._sindex = _get_sindex_class()(self.data)
    292     return self._sindex

File /usr/local/lib/python3.10/dist-packages/geopandas-0.10.2+79.g3abc6a7-py3.10.egg/geopandas/sindex.py:21, in _get_sindex_class()
     19 if compat.HAS_RTREE:
     20     return RTreeIndex
---> 21 raise ImportError(
     22     "Spatial indexes require either `rtree` or `pygeos`. "
     23     "See installation instructions at https://geopandas.org/install.html"
     24 )

ImportError: Spatial indexes require either `rtree` or `pygeos`. See installation instructions at https://geopandas.org/install.html

In [46]: country_peripheries.plot(alpha=0.5, edgecolor='k', cmap='tab10');
../../_images/country_peripheries.png

Keep_geom_type关键字#

在默认设置中, overlay() 仅返回与GeoDataFrame(左图)具有相同几何图形类型的几何图形,其中,多边形和多重多边形被视为同一类型(其他类型相同)。您可以使用以下命令控制此行为 keep_geom_type 选项,默认情况下设置为True。一旦设置为FALSE, overlay 将返回由选定的集合操作产生的所有几何图形类型。例如,两个多边形在一条直线或一点上相交的相交几何图形可能会产生不同的类型。

更多例子#

一组更大的用法示例 overlay() 可以找到 here