Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Earthpy docs improvement - crop_image #483

Closed
lwasser opened this issue Jan 30, 2020 · 4 comments
Closed

Earthpy docs improvement - crop_image #483

lwasser opened this issue Jan 30, 2020 · 4 comments
Labels
documentation documentation added or edited in earthpy enhancement New feature or request help wanted Extra attention is needed

Comments

@lwasser
Copy link

lwasser commented Jan 30, 2020

the docstring of crop_image

Help on function crop_image in module earthpy.spatial needs soem work

  1. the vignette in the docs both reads and crops the data which is not necessary.
  2. the parameters should more explicetly say "rasterio rasterReader object" the precise name of the object so it's more clear to users what it expects
crop_image(raster, geoms, all_touched=True)
    Crop a single file using geometry objects.
    
    Parameters
    ----------
    raster : rasterio object **# this should say the full proper name rasterio rasterREader object**
        The rasterio object to be cropped.
    geoms : geopandas geodataframe or list of polygons
        The spatial polygon boundaries in GeoJSON-like dict format
        to be used to crop the image. All data outside of the polygon
        boundaries will be set to nodata and/or removed from the image.
    all_touched : bool (default=True)
        Include a pixel in the mask if it touches any of the
        shapes. If False, include a pixel only if its center is within one of
        the shapes, or if it is selected by Bresenham's line algorithm.
        (from rasterio)
    
    Returns
    ----------
    tuple
    
        out_image: cropped numpy array
            A numpy array that is cropped to the geoms object
            extent with shape (bands, rows, columns)
        out_meta:  dict
            A dictionary containing updated metadata for the cropped raster,
            including extent (shape elements) and transform properties.
    
    Example
    -------
        >>> import geopandas as gpd
        >>> import rasterio as rio
        >>> import earthpy.spatial as es
        >>> from earthpy.io import path_to_example
        >>> # Clip an RGB image to the extent of Rocky Mountain National Park
        >>> rmnp = gpd.read_file(path_to_example("rmnp.shp"))
        >>> with rio.open(path_to_example("rmnp-rgb.tif")) as raster:
        ...     **src_image = raster.read()** # this should be removed
        ...     out_image, out_meta = es.crop_image(raster, rmnp)
        >>> out_image.shape
        (3, 265, 281)
        >>> src_image.shape
        (3, 373, 485)
@lwasser lwasser added documentation documentation added or edited in earthpy enhancement New feature or request help wanted Extra attention is needed labels Jan 30, 2020
@lwasser lwasser changed the title Earthpy docs improvement Earthpy docs improvement - crop_image Jan 30, 2020
@bmcandr
Copy link
Contributor

bmcandr commented Apr 24, 2020

Hey there, I took a crack at making the suggested changes. Two quick questions:

  1. Is "a [rasterio] dataset object opened in 'r' mode" specific enough (follows rasterio naming conventions -- see line 36)? Or would you prefer rasterio.io.DatasetReader which is the object type returned by a call to rasterio.open()?

  2. Removing the src_image = raster.read() line results in an error when making the docs because src_image is referenced at the end of the vignette in a call to src_image.shape as part of a comparison of the input/output array shapes. If the line 373 is removed, lines 375-376 should be removed. And with those lines removed, the call to out_image.shape on lines 377-378 should also be removed. Is the preference to keep the comparison of shapes OR remove lines 373 and 375-378 altogether?

Here's a draft version of the updated docstring:


    Parameters
    ----------
    raster : a rasterio dataset object opened in 'r' mode
        Raster that will be cropped.
    geoms : geopandas geodataframe or list of polygons
        The spatial polygon boundaries in GeoJSON-like dict format
        to be used to crop the image. All data outside of the polygon
        boundaries will be set to nodata and/or removed from the image.
    all_touched : bool (default=True)
        Include a pixel in the mask if it touches any of the
        shapes. If False, include a pixel only if its center is within one of
        the shapes, or if it is selected by Bresenham's line algorithm.
        (from rasterio)

    Returns
    ----------
    tuple

        out_image: cropped numpy array
            A numpy array that is cropped to the geoms object
            extent with shape (bands, rows, columns)
        out_meta:  dict
            A dictionary containing updated metadata for the cropped raster,
            including extent (shape elements) and transform properties.

    Example
    -------
        >>> import geopandas as gpd
        >>> import rasterio as rio
        >>> import earthpy.spatial as es
        >>> from earthpy.io import path_to_example
        >>> # Clip an RGB image to the extent of Rocky Mountain National Park
        >>> rmnp = gpd.read_file(path_to_example("rmnp.shp"))
        >>> with rio.open(path_to_example("rmnp-rgb.tif")) as raster:
        ...     out_image, out_meta = es.crop_image(raster, rmnp)

Let me know what you think. Happy to make the change and submit a PR!

@lwasser
Copy link
Author

lwasser commented Apr 24, 2020

hey @bmcandr 👋 👋 !! welcome to earthpy. And thank you for responding to this issue.

to answer your questions.

  1. lets use rasterio.io.DatasetReader so it's very clear what object is required for the crop function!
  2. i think you can get the shape of the original raster by using raster.shape
with rio.open(path_to_example("rmnp-rgb.tif")) as raster:

raster.shape # this should work

i just tested this and it seemed ok. So... whaht about we change raster to src_raster

with rio.open(path_to_example("rmnp-rgb.tif")) as src_raster:
        ...     out_image, out_meta = es.crop_image(raster, rmnp)

you can then skip the read step and call

src_raster.shape

to show the difference in object dimensions. If that sounds good to you, we welcome a PR!!
If you have any questions, please let me know!
thank you AGAIN!!

@bmcandr
Copy link
Contributor

bmcandr commented Apr 25, 2020

You're welcome! Glad to contribute.

I tested your suggestion and it seems the shape attribute of a rasterio.io.DatasetReader doesn't include the band count:

>>> with rio.open(path_to_example("rmnp-rgb.tif")) as src_raster:
...     out_image, out_meta = es.crop_image(src_raster, rmnp)
>>> out_image.shape
(3, 265, 281)
>>> src_raster.shape
(373, 485)           # Expected: (3, 373, 485)

It might be necessary to read src_raster into a numpy array for the shape comparison. Feel free to double check though!

@lwasser
Copy link
Author

lwasser commented May 7, 2020

closing this by way of #536 thank you again @bmcandr !!!

@lwasser lwasser closed this as completed May 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation documentation added or edited in earthpy enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants