a
    İaz<                     @   s   d dl Z d dlZd dlZddlmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZ dd	lmZ e Zd
ZG dd deZdd ZdddZdS )    N   )indexing)	DataArray)	is_scalar   )BackendArray)CachingFileManager)SerializableLockz~The kind of indexing operation you are trying to do is not valid on rasterio files. Try to load your data with ds.load()first.c                   @   sJ   e Zd ZdZdddZedd Zedd Zd	d
 Zdd Z	dd Z
dS )RasterioArrayWrapperz)A wrapper around rasterio dataset objectsNc                 C   s   ddl m} || _|| _| }|d ur8||fi |}|| _|j|j|jf| _	|j
}tt||d ksvtdt|d | _d S )Nr   	WarpedVRTz$All bands should have the same dtype)rasterio.vrtr   managerlockacquire
vrt_paramscountheightwidth_shapedtypesnpallasarray
ValueErrordtype_dtype)selfr   r   r   r   riodsr    r   8lib/python3.9/site-packages/xarray/backends/rasterio_.py__init__   s    zRasterioArrayWrapper.__init__c                 C   s   | j S N)r   r   r   r   r    r   ,   s    zRasterioArrayWrapper.dtypec                 C   s   | j S r"   )r   r#   r   r   r    shape0   s    zRasterioArrayWrapper.shapec                 C   s  t |dksJ d|d }g }t|trN|| jd \}}}t|||}t|d  }t|t	rx|
td g }g }tt|dd | jdd D ]\}	\}
}t|
tr|
|\}}}|
tdd| nPt|
r|
d|	   |
}|
d }n(t|
t|
d  }}|
|
|  |
||f qt|d tjrxt|d tjrxtj|dd  |dd< |t|t|t|fS )a  Get indexer for rasterio array.

        Parameters
        ----------
        key : tuple of int

        Returns
        -------
        band_key: an indexer for the 1st dimension
        window: two tuples. Each consists of (start, stop).
        squeeze_axis: axes to be squeezed
        np_ind: indexer for loaded numpy array

        See Also
        --------
        indexing.decompose_indexer
           z%rasterio datasets should always be 3Dr   r   Nr   )len
isinstancesliceindicesr$   r   aranger   tolistlistappend	enumeratezipr   minmaxndarrayZix_tuple)r   keyband_keynp_indsstartstopstepwindowsqueeze_axisiknr   r   r    _get_indexer4   s2    

,


$z!RasterioArrayWrapper._get_indexerc           
      C   s   ddl m} | |\}}}}|r4tdd |D rbt|ftdd |D  }tj|| jd}n^| j	H | j
jdd}	| jd ur||	fi | j}	|	j||d	}W d    n1 s0    Y  |rtj||d
}|| S )Nr   r   c                 s   s   | ]\}}||kV  qd S r"   r   .0r8   r9   r   r   r    	<genexpr>r       z0RasterioArrayWrapper._getitem.<locals>.<genexpr>c                 s   s   | ]\}}|| V  qd S r"   r   rA   r   r   r    rC   t   rD   )r   F)Z
needs_lock)r;   )Zaxis)r   r   r@   anyr'   r4   r   zerosr   r   r   r   r   readZsqueeze)
r   r5   r   r6   r;   r<   r7   r$   outr   r   r   r    _getitemm   s    
,zRasterioArrayWrapper._getitemc                 C   s   t || jt jj| jS r"   )r   Zexplicit_indexing_adapterr$   ZIndexingSupportZOUTERrI   )r   r5   r   r   r    __getitem__   s    z RasterioArrayWrapper.__getitem__)N)__name__
__module____qualname____doc__r!   propertyr   r$   r@   rI   rJ   r   r   r   r    r
      s   


9r
   c                    s6   dd }dd  ||d fdd|   D }|S )a  Parse ENVI metadata into Python data structures.

    See the link for information on the ENVI header file format:
    http://www.harrisgeospatial.com/docs/enviheaderfiles.html

    Parameters
    ----------
    meta : dict
        Dictionary of keys and str values to parse, as returned by the rasterio
        tags(ns='ENVI') call.

    Returns
    -------
    parsed_meta : dict
        Dictionary containing the original keys and the parsed values

    c                 S   s   t j| ddddS )N{}float,)r   sep)r   Z
fromstringstripsr   r   r    parsevec   s    z_parse_envi.<locals>.parsevecc                 S   s
   |  dS )NrP   )rT   rU   r   r   r    default   s    z_parse_envi.<locals>.default)Z
wavelengthZfwhmc                    s"   i | ]\}}| | |qS r   )get)rB   r>   vrX   parser   r    
<dictcomp>   rD   z_parse_envi.<locals>.<dictcomp>)items)metarW   Zparsed_metar   r[   r    _parse_envi   s
    
r`   c                 K   sJ  t jdtdd ddl}ddlm} d}t| |jjr>| j	} nZt| |j
jr| }	|	jj	} t|	j |	j |	j|	j|	j|	j|	j|	j|	j|	j|	j|	jd}|du rt}t|j| |d|d	}
|
 }|dur||fi |}|du r|du }i }|jd
k rtdt !|j"|d< |jj#r|du r&dn|}|r|j|j }}|jt $|d t %|d f \}}|jt %|d t $|d f \}}||d< ||d< n(|du rdn|}|rt jdt&dd i }t'|jdd |d< t(|dr(|jr(z|j) |d< W n" t*y&   |j |d< Y n0 t(|dr>|j+|d< t(|drZt ,|j-|d< t(|dr~t'dd |j.D |d< t(|dr|j/|d< t(|dr|j0|d< t(|drt1|j2r|j2|d< t(|drt1|j3r|j3|d< t4d d! d"}|j5}||v r|d#kr(|| |6 }n|| |j6|d$}|7 D ]H\}}t|t8t j9frt:||jkrdt !|f||< n|||< qDt;<t=|
||}t;>|}|r|du rt;?|}t@|d%||d&}|dur:dd'lAmB} ztCjDE| }W n tFy   d}Y n0 || ||}d(| }|jG|||d)}|H|
jI |S )*a  Open a file with rasterio.

    .. deprecated:: 0.20.0

        Deprecated in favor of rioxarray.
        For information about transitioning, see:
        https://corteva.github.io/rioxarray/stable/getting_started/getting_started.html

    This should work with any file that rasterio can open (most often:
    geoTIFF). The x and y coordinates are generated automatically from the
    file's geoinformation, shifted to the center of each pixel (see
    `"PixelIsArea" Raster Space
    <http://web.archive.org/web/20160326194152/http://remotesensing.org/geotiff/spec/geotiff2.5.html#2.5.2>`_
    for more information).

    You can generate 2D coordinates from the file's attributes with::

        >>> from affine import Affine
        >>> da = xr.open_rasterio(
        ...     "https://github.com/mapbox/rasterio/raw/1.2.1/tests/data/RGB.byte.tif"
        ... )
        >>> da
        <xarray.DataArray (band: 3, y: 718, x: 791)>
        [1703814 values with dtype=uint8]
        Coordinates:
          * band     (band) int64 1 2 3
          * y        (y) float64 2.827e+06 2.826e+06 2.826e+06 ... 2.612e+06 2.612e+06
          * x        (x) float64 1.021e+05 1.024e+05 1.027e+05 ... 3.389e+05 3.392e+05
        Attributes:
            transform:      (300.0379266750948, 0.0, 101985.0, 0.0, -300.041782729805...
            crs:            +init=epsg:32618
            res:            (300.0379266750948, 300.041782729805)
            is_tiled:       0
            nodatavals:     (0.0, 0.0, 0.0)
            scales:         (1.0, 1.0, 1.0)
            offsets:        (0.0, 0.0, 0.0)
            AREA_OR_POINT:  Area
        >>> transform = Affine(*da.attrs["transform"])
        >>> transform
        Affine(300.0379266750948, 0.0, 101985.0,
               0.0, -300.041782729805, 2826915.0)
        >>> nx, ny = da.sizes["x"], da.sizes["y"]
        >>> x, y = transform * np.meshgrid(np.arange(nx) + 0.5, np.arange(ny) + 0.5)
        >>> x
        array([[102135.01896334, 102435.05689001, 102735.09481669, ...,
                338564.90518331, 338864.94310999, 339164.98103666],
               [102135.01896334, 102435.05689001, 102735.09481669, ...,
                338564.90518331, 338864.94310999, 339164.98103666],
               [102135.01896334, 102435.05689001, 102735.09481669, ...,
                338564.90518331, 338864.94310999, 339164.98103666],
               ...,
               [102135.01896334, 102435.05689001, 102735.09481669, ...,
                338564.90518331, 338864.94310999, 339164.98103666],
               [102135.01896334, 102435.05689001, 102735.09481669, ...,
                338564.90518331, 338864.94310999, 339164.98103666],
               [102135.01896334, 102435.05689001, 102735.09481669, ...,
                338564.90518331, 338864.94310999, 339164.98103666]])

    Parameters
    ----------
    filename : str, rasterio.DatasetReader, or rasterio.WarpedVRT
        Path to the file to open. Or already open rasterio dataset.
    parse_coordinates : bool, optional
        Whether to parse the x and y coordinates out of the file's
        ``transform`` attribute or not. The default is to automatically
        parse the coordinates only if they are rectilinear (1D).
        It can be useful to set ``parse_coordinates=False``
        if your files are very large or if you don't need the coordinates.
    chunks : int, tuple or dict, optional
        Chunk sizes along each dimension, e.g., ``5``, ``(5, 5)`` or
        ``{'x': 5, 'y': 5}``. If chunks is provided, it used to load the new
        DataArray into a dask array.
    cache : bool, optional
        If True, cache data loaded from the underlying datastore in memory as
        NumPy arrays when accessed to avoid reading from the underlying data-
        store multiple times. Defaults to True unless you specify the `chunks`
        argument to use dask, in which case it defaults to False.
    lock : False, True or threading.Lock, optional
        If chunks is provided, this argument is passed on to
        :py:func:`dask.array.from_array`. By default, a global lock is
        used to avoid issues with concurrent access to the same file when using
        dask's multithreaded backend.

    Returns
    -------
    data : DataArray
        The newly created DataArray.
    zopen_rasterio is Deprecated in favor of rioxarray. For information about transitioning, see: https://corteva.github.io/rioxarray/stable/getting_started/getting_started.htmlr   )
stacklevelr   Nr   )src_crscrs
resampling	tolerance
src_nodatanodatar   r   src_transform	transformr   warp_extrasr)r   modekwargsr   zUnknown dimsbandTg      ?yxFzThe file coordinates' transformation isn't rectilinear: xarray won't parse the coordinates in this case. Set `parse_coordinates=False` to suppress this warning.r%      ri   rc   resis_tiled
nodatavalsc                 s   s    | ]}|d u rt jn|V  qd S r"   )r   nan)rB   Z	nodatavalr   r   r    rC   m  s   z open_rasterio.<locals>.<genexpr>scalesoffsetsdescriptionsunitsc                 S   s   | S r"   r   )mr   r   r    <lambda>~  rD   zopen_rasterio.<locals>.<lambda>)ZENVIGTiffr|   )ns)rn   ro   rp   )dataZdimscoordsattrs)tokenizezopen_rasterio-)name_prefixtoken)JwarningswarnDeprecationWarningrasterior   r   r(   ioZDatasetReadernamevrtZsrc_datasetdictrb   Z	to_stringrc   rd   re   rf   rg   r   r   rh   ri   Zworking_dtyperj   RASTERIO_LOCKr   openr   r   r   r   r   ZindexesZis_rectilinearr+   rF   RuntimeWarningr4   hasattrZto_proj4AttributeErrorrr   Zuint8rs   rt   rv   rw   rE   rx   ry   r`   drivertagsr^   r-   r3   r'   r   ZLazilyIndexedArrayr
   ZCopyOnWriteArrayZMemoryCachedArrayr   Z	dask.baser   ospathgetmtimeOSErrorchunkZ	set_closeclose)filenameZparse_coordinateschunkscacher   rm   r   r   r   r   r   r   r   r\   Znxnyrp   _ro   r   parsersr   r_   r>   rZ   r~   resultr   mtimer   r   r   r   r    open_rasterio   s    `

&&








"




r   )NNNN)r   r   Znumpyr   corer   Zcore.dataarrayr   Z
core.utilsr   commonr   Zfile_managerr   locksr	   r   Z
_ERROR_MSGr
   r`   r   r   r   r   r    <module>   s$   p     