a
    'f:?                     @   sz   d dl Z d dlmZ d dlZd dlZd dlmZm	Z	 d dl
mZmZ dd Zdd Zd	d
 Zdd Zdd ZdddZdS )    N)reduce)GeoDataFrame	GeoSeries)
_check_crs_crs_mismatch_warnc                 C   sL   | j dksHd| jv r$| jdddd | j| j diddd | jddd dS )	z
    Helper function to ensure the geometry column is called 'geometry'.
    If another column with that name exists, it will be dropped.
    geometry   TaxisinplaceF)columnscopyr   )r   N)_geometry_column_namer   droprenameZset_geometry)df r   e/var/www/staging/api/virtual_environments/venv/lib/python3.9/site-packages/geopandas/tools/overlay.py_ensure_geometry_column   s    

r   c                 C   sv  |j j| jddd\}}|jdkr|jdkr| j|}|jddd |j|}|jddd ||}|jddg}|| 	d|j
|< t||d}|}	| jdd	} |jdd	}|j| j| jd
dddd}
|
j|j|jd
ddddd}
t|
|	| jdS | jdd j|jdd j|jjd
ddddd}tj|d< tj|d< ||j| jj | jjg  S dS )zA
    Overlay Intersection operation used in overlay function
    
intersectsT	predicatesortr   r   r   PolygonMultiPolygon)__idx1__idx2r   r   r
   r   )left_onright_indexr   Z_1Z_2)r    r!   suffixesr   crsNZ
left_indexr!   r#   )sindexqueryr   sizeZtakereset_indexintersection	geom_typeisinbufferlocpdZ	DataFramemerger   r   r   r%   ilocnamenpnanr   tolist)df1df2idx1idx2leftrightZintersectionspoly_ixZpairs_intersectZgeom_intersectdfinterresultr   r   r   _overlay_intersection   sH    


r@   c                    s   |j j| jddd\}}tj|dd\ }t||dd  fddt| jjD }g }t| j|D ]2\}}t	d	d
 |gt
|jj|  }	||	 qjt|| j| jd}
|
jddg}|
|  |
j|< |
|
j   }| |
j   }|||j< |S )z?
    Overlay Difference operation used in overlay function
    r   Tr   )Zreturn_indexr   Nc                    s"   g | ]}| v r d ng qS )r   )pop).0idxZidx1_uniqueZ
idx2_splitr   r   
<listcomp>S   s   z'_overlay_difference.<locals>.<listcomp>c                 S   s
   |  |S )N)
difference)xyr   r   r   <lambda>[       z%_overlay_difference.<locals>.<lambda>)indexr%   r   r   )r'   r(   r   r4   uniquesplitranger)   zipr   listr2   appendr   rK   r%   r,   r-   
make_validr/   Zis_emptyr   r   )r7   r8   r9   r:   Zidx1_unique_indicesZsidxZnew_gZgeomZ
neighboursnewZdifferencesr=   Z	geom_diffZdfdiffr   rD   r   _overlay_differenceK   s&    

rT   c                 C   s   t | |}t || }tt||d< tt||d< tj|d< tj|d< t| t| |j|ddgddd}|j }d|_	|j
|j df |j
|j < |jddgd	d
d |jd
d
d t||| jd}|S )zI
    Overlay Symmetric Difference operation used in overlay function
    r   r   outerr"   )onhowr#   r   Z
geometry_2
geometry_1r   Tr	   r   r$   )rT   rN   lenr4   r5   r   r1   rX   r   r3   r/   Zisnullr   r*   r   r%   )r7   r8   Zdfdiff1Zdfdiff2dfsymr   r   r   r   _overlay_symmetric_diffh   s(    




r[   c                 C   sR   t | |}t| |}tj||gddd}t|j}|d |d |j|dS )z:
    Overlay Union operation used in overlay function
    TF)Zignore_indexr   r   )r   )	r@   r[   r0   concatrP   r   removerQ   Zreindex)r7   r8   r>   rZ   dfunionr   r   r   r   _overlay_union   s    




r_   r+   Tc                    sp  g d}||vr t d||t| ts4t|tr<tdt| |sTt| |dd |du rfd}d}nd}d	d
gg d}ddg}t| |gD ]\\}	}
|
j	
 }|
j	|
 }|
j	|
 }t|||gdkrtd|	d q|dkr| j}|j}|d |d krJ|d |d krJ|d |d krJ|d |d ks| jdd j|jdd j|jjdddddd}||j| jj | jjg  S  fdd}|| } ||}t  tjddd |dkrt| |}nj|dkrt| |}nT|dkrt| |}n>|dkr.t| |}n(|dkrVt| |}||d    }|d v rt|jdd!gddd" W d   n1 s0    Y  |r^| jjd }|jd#k}|
 r|j}||g | }|jdd$jdd%}|jdd&}|j d }|v rd|j!|j	 |f< nV||v r@d|j!|j	| |f< n2||v rdd|j!|j	| |f< nt"d'|||j#   }|j$d(d)}|| j%|j!||f< nd}|j d }|v r|j!|j	 }nJ||v r|j!|j	| }n,||v r|j!|j	| }nt"d'|||j d  }|dks>|dkr^|r^tj&d*|| t'dd |jddd+ |S ),a  Perform spatial overlay between two GeoDataFrames.

    Currently only supports data GeoDataFrames with uniform geometry types,
    i.e. containing only (Multi)Polygons, or only (Multi)Points, or a
    combination of (Multi)LineString and LinearRing shapes.
    Implements several methods that are all effectively subsets of the union.

    See the User Guide page :doc:`../../user_guide/set_operations` for details.

    Parameters
    ----------
    df1 : GeoDataFrame
    df2 : GeoDataFrame
    how : string
        Method of spatial overlay: 'intersection', 'union',
        'identity', 'symmetric_difference' or 'difference'.
    keep_geom_type : bool
        If True, return only geometries of the same geometry type as df1 has,
        if False, return all resulting geometries. Default is None,
        which will set keep_geom_type to True but warn upon dropping
        geometries.
    make_valid : bool, default True
        If True, any invalid input geometries are corrected with a call to `buffer(0)`,
        if False, a `ValueError` is raised if any input geometries are invalid.

    Returns
    -------
    df : GeoDataFrame
        GeoDataFrame with new set of polygons and attributes
        resulting from the overlay

    Examples
    --------
    >>> from shapely.geometry import Polygon
    >>> polys1 = geopandas.GeoSeries([Polygon([(0,0), (2,0), (2,2), (0,2)]),
    ...                               Polygon([(2,2), (4,2), (4,4), (2,4)])])
    >>> polys2 = geopandas.GeoSeries([Polygon([(1,1), (3,1), (3,3), (1,3)]),
    ...                               Polygon([(3,3), (5,3), (5,5), (3,5)])])
    >>> df1 = geopandas.GeoDataFrame({'geometry': polys1, 'df1_data':[1,2]})
    >>> df2 = geopandas.GeoDataFrame({'geometry': polys2, 'df2_data':[1,2]})

    >>> geopandas.overlay(df1, df2, how='union')
       df1_data  df2_data                                           geometry
    0       1.0       1.0  POLYGON ((2.00000 2.00000, 2.00000 1.00000, 1....
    1       2.0       1.0  POLYGON ((2.00000 2.00000, 2.00000 3.00000, 3....
    2       2.0       2.0  POLYGON ((4.00000 4.00000, 4.00000 3.00000, 3....
    3       1.0       NaN  POLYGON ((2.00000 0.00000, 0.00000 0.00000, 0....
    4       2.0       NaN  MULTIPOLYGON (((3.00000 4.00000, 3.00000 3.000...
    5       NaN       1.0  MULTIPOLYGON (((2.00000 3.00000, 2.00000 2.000...
    6       NaN       2.0  POLYGON ((3.00000 5.00000, 5.00000 5.00000, 5....

    >>> geopandas.overlay(df1, df2, how='intersection')
       df1_data  df2_data                                           geometry
    0         1         1  POLYGON ((2.00000 2.00000, 2.00000 1.00000, 1....
    1         2         1  POLYGON ((2.00000 2.00000, 2.00000 3.00000, 3....
    2         2         2  POLYGON ((4.00000 4.00000, 4.00000 3.00000, 3....

    >>> geopandas.overlay(df1, df2, how='symmetric_difference')
       df1_data  df2_data                                           geometry
    0       1.0       NaN  POLYGON ((2.00000 0.00000, 0.00000 0.00000, 0....
    1       2.0       NaN  MULTIPOLYGON (((3.00000 4.00000, 3.00000 3.000...
    2       NaN       1.0  MULTIPOLYGON (((2.00000 3.00000, 2.00000 2.000...
    3       NaN       2.0  POLYGON ((3.00000 5.00000, 5.00000 5.00000, 5....

    >>> geopandas.overlay(df1, df2, how='difference')
                                            geometry  df1_data
    0  POLYGON ((2.00000 0.00000, 0.00000 0.00000, 0....         1
    1  MULTIPOLYGON (((3.00000 4.00000, 3.00000 3.000...         2

    >>> geopandas.overlay(df1, df2, how='identity')
       df1_data  df2_data                                           geometry
    0       1.0       1.0  POLYGON ((2.00000 2.00000, 2.00000 1.00000, 1....
    1       2.0       1.0  POLYGON ((2.00000 2.00000, 2.00000 3.00000, 3....
    2       2.0       2.0  POLYGON ((4.00000 4.00000, 4.00000 3.00000, 3....
    3       1.0       NaN  POLYGON ((2.00000 0.00000, 0.00000 0.00000, 0....
    4       2.0       NaN  MULTIPOLYGON (((3.00000 4.00000, 3.00000 3.000...

    See also
    --------
    sjoin : spatial join
    GeoDataFrame.overlay : equivalent method

    Notes
    -----
    Every operation in GeoPandas is planar, i.e. the potential third
    dimension is not taken into account.
    )r+   unionidentitysymmetric_differencerF   z,`how` was '{0}' but is expected to be in {1}z4overlay currently only implemented for GeoDataFrames   )
stacklevelNTFr   r   )Z
LineStringZMultiLineStringZ
LinearRingZPointZ
MultiPointr   z#df{} contains mixed geometry types.r+   r      r   r"   r&   c                    sl   |   } | j rh| jj }| j} rL| j||f d| j||f< n|	 rht
d|  d| S )Nr   z,You have passed make_valid=False along with zo invalid input geometries. Use make_valid=True or make sure that all geometries are valid before using overlay.)r   r,   r-   allr   Zis_validr   r/   r.   any
ValueErrorsum)r   maskcolrR   Zpolysr   r   _make_valid&  s    
 zoverlay.<locals>._make_validignorezCRS mismatch between the CRS)messagerF   rb   r`   ra   r   )r+   rb   r`   ra   r   r	   ZGeometryCollectionr   )Zindex_parts)levelz%`keep_geom_type` does not support {}.Zlevel_0)Zbyz`keep_geom_type=True` in overlay resulted in {} dropped geometries of different geometry types than df1 has. Set `keep_geom_type=False` to retain all geometriesr   )(rh   format
isinstancer   NotImplementedErrorr   r   	enumerater,   r-   rg   ri   Ztotal_boundsr2   r1   r   r   r3   r   r6   warningscatch_warningsfilterwarningsrT   r@   r[   r_   Znotnullr   r   r*   Zexplodeshaper/   	TypeErrorZisnaZdissolvevalueswarnUserWarning)r7   r8   rW   Zkeep_geom_typerR   Zallowed_howsZkeep_geom_type_warninglinesZpointsir   Z
poly_checkZlines_checkZpoints_checkZbox_gdf1Zbox_gdf2r?   rm   r^   r,   Zis_collectionZgeom_colcollectionsexplodedZorig_num_geoms_explodedZnum_dropped_collectionZ	dissolvedZorig_num_geomsZnum_droppedr   rl   r   overlay   s    Y










4





	



	r   )r+   NT)ru   	functoolsr   numpyr4   Zpandasr0   Z	geopandasr   r   Zgeopandas.arrayr   r   r   r@   rT   r[   r_   r   r   r   r   r   <module>   s   2