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

dataset/crop/feature/crop-all-within-polygon #71

Merged
merged 8 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor files
  • Loading branch information
MAfarrag committed Dec 28, 2023
commit 3168671c118e20b0f5ae3f6e6f61fb8126bc7b42
49 changes: 27 additions & 22 deletions docs/dataset.rst
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,19 @@ Band statistics (stats)
>>> Band_3 273.641479 274.168823 273.953979 0.198447
>>> Band_4 273.991516 274.540344 274.310669 0.205754

- The method can also take a mask (polygon/dataset) to calculate the statistics of the masked area only.

.. code:: py
era5_image = "tests/data/geotiff/era5_land_monthly_averaged.tif"
dataset = Dataset.read_file(era5_image)
mask = gpd.read_file("tests/data/geotiff/era5-mask.geojson")
stats = dataset.stats(mask=mask)
print(stats)
>>> min max mean std
>>> Band_1 270.369720 270.399017 270.384369 0.014648
>>> Band_2 269.651001 269.744751 269.697876 0.046875
>>> Band_3 273.889526 273.901245 273.895386 0.005859
>>> Band_4 274.235657 274.255188 274.245422 0.009766

Write raster to disk
====================
Expand Down Expand Up @@ -772,9 +785,7 @@ crop

Crop array using a raster
^^^^^^^^^^^^^^^^^^^^^^^^^
- `crop` clip/crop (matches the location of nodata value from src raster to dst raster), Both raster's have to
have the same dimensions (no of rows & columns) so MatchRasterAlignment should be used prior to this function to
align both raster's.
- The `crop` method clips/crops (matches the location of nodata value from source raster to destination raster).

Parameters
""""""""""
Expand All @@ -790,15 +801,14 @@ Parameters
Returns
"""""""
dst: [gdal.dataset]
the second raster with NoDataValue stored in its cells
exactly the same like src raster
the second raster with NoDataValue stored in its cells exactly the same like src raster


.. code:: py

aligned_raster = "examples/data/Evaporation_ECMWF_ERA-Interim_mm_daily_2009.01.01.tif"
band = 1
dst = Raster.Open(aligned_raster)
dst = Dataset.Open(aligned_raster)
dst_arr = dst.read_array()
dst_nodataval = dst.no_data_value[band - 1]

Expand Down Expand Up @@ -857,27 +867,22 @@ Crop raster using array

crop
^^^^
- `crop` method crops a raster using another raster (both rasters does not have to be aligned).
- `crop` method crops a raster using another raster/polygon.

Parameters
""""""""""
src: [string/gdal.Dataset]
the raster you want to crop as a path or a gdal object
mask : [string/gdal.Dataset]
the raster you want to use as a mask to crop other raster,
the mask can be also a path or a gdal object.
output_path : [string]
if you want to save the cropped raster directly to disk
enter the value of the OutputPath as the path.
save : [boolen]
True if you want to save the cropped raster directly to disk.
mask: [Polygon GeoDataFrame/Dataset]
GeodataFrame with a polygon geometry, or a Dataset object.
touch: [bool]
To include the cells that touch the polygon not only those that lie entirely inside the polygon mask.
Default is True.
inplace: [bool]
True to make the changes in place.

Returns
"""""""
dst : [gdal.Dataset]
the cropped raster will be returned, if the save parameter was True,
the cropped raster will also be saved to disk in the OutputPath
directory.
Dataset:
Dataset object.


.. code:: py
Expand Down Expand Up @@ -1234,7 +1239,7 @@ color_table


- When saving the raster to disk, the following file will be created along side the raster file.
<RASTER-FILE-NAME.aux.xml>
<RASTER-FILE-NAME.aux.xml>

.. code:: xml

Expand Down
140 changes: 100 additions & 40 deletions examples/notebooks/01dataset.ipynb

Large diffs are not rendered by default.

996 changes: 536 additions & 460 deletions examples/notebooks/02spatial-operation-methods.ipynb

Large diffs are not rendered by default.

544 changes: 288 additions & 256 deletions examples/notebooks/03convert-longitude.ipynb

Large diffs are not rendered by default.

52 changes: 23 additions & 29 deletions pyramids/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@
dtype=np.float32,
)
if mask is not None:
df.iloc[0, :] = dst._get_stats(band)

Check warning on line 584 in pyramids/dataset.py

View check run for this annotation

Codecov / codecov/patch

pyramids/dataset.py#L584

Added line #L584 was not covered by tests
else:
df.iloc[0, :] = self._get_stats(band)

Expand Down Expand Up @@ -2309,20 +2309,18 @@
) -> gdal.Dataset:
"""crop.

crop method crops a raster using another raster (both rasters does not have to be aligned).
crop method crops a raster using another raster.

Parameters
-----------
mask : [string/Dataset]
the raster you want to use as a mask to crop other raster,
string/Dataset:
The raster you want to use as a mask to crop another raster,
the mask can be also a path or a gdal object.

Returns
-------
dst : [Dataset]
the cropped raster will be returned, if the save parameter was True,
the cropped raster will also be saved to disk in the OutputPath
directory.
Dataset:
The cropped raster.
"""
# get information from the mask raster
if isinstance(mask, str):
Expand All @@ -2344,12 +2342,13 @@
def _crop_with_polygon_by_rasterizing(self, poly: GeoDataFrame):
"""cropWithPolygon.

clip the Raster object using a polygon vector.
Clip the Raster object using a polygon vector.

Parameters
----------
poly: [Polygon GeoDataFrame]
GeodataFrame with a geometry of polygon type.

Returns
-------
Dataset
Expand Down Expand Up @@ -2385,7 +2384,7 @@
feature: [FeatureCollection]
vector mask.
touch: [bool]
to include the cells that touches the polygon not only those that lies entirely inside the polygon mask.
To include the cells that touch the polygon not only those that lie entirely inside the polygon mask.
Default is True.

Returns
Expand Down Expand Up @@ -2421,14 +2420,14 @@
):
"""crop.

clip the Dataset object using a polygon/another raster (both rasters does not have to be aligned).
Clip the Dataset object using a polygon/raster.

Parameters
----------
mask: [Polygon GeoDataFrame/Dataset object]
GeodataFrame with a geometry of polygon type
mask: [Polygon GeoDataFrame/Dataset]
GeodataFrame with a polygon geometry, or a Dataset object.
touch: [bool]
to include the cells that touches the polygon not only those that lies entirely inside the polygon mask.
To include the cells that touch the polygon not only those that lie entirely inside the polygon mask.
Default is True.
inplace: [bool]
True to make the changes in place.
Expand Down Expand Up @@ -2458,29 +2457,27 @@
) -> np.ndarray:
"""_nearest_neighbour.

-The _nearest_neighbour method fills the cells with a given indices in rows and cols with the value of the
- The _nearest_neighbour method fills the cells with a given indices in rows and cols with the value of the
nearest neighbour.
- Ss the raster grid is square so the 4 perpendicular direction are of the same proximity so the function
- Ss the raster grid is square, so the 4 perpendicular directions are of the same proximity, so the function
gives priority to the right, left, bottom, and then top and the same for 45 degree inclined direction
right bottom then left bottom then left Top then right Top.

Parameters
----------
array: [numpy.array]
Array to fill some of its cells with Nearest value.
Array to fill some of its cells with the Nearest value.
nodatavalue: [float32]
value stored in cells that is out of the domain
rows: [List]
list of the rows index of the cells you want to fill it with
nearest neighbour.
list of the rows' index of the cells you want to fill it with the nearest neighbour.
cols: [List]
list of the column index of the cells you want to fill it with
nearest neighbour.
list of the column index of the cells you want to fill it with the nearest neighbour.

Returns
-------
array: [numpy array]
Cells of given indices will be filled with value of the Nearest neighbour
Cells of given indices will be filled with the value of the Nearest neighbour

Examples
--------
Expand Down Expand Up @@ -4084,20 +4081,17 @@
gdal_merge.main(parameters)

def apply(self, ufunc: Callable):
"""folderCalculator.
"""apply.

this function matches the location of nodata value from src raster to dst
raster
Dataset A is where the NoDatavalue will be taken and the location of this value
B_input_path is path to the folder where Dataset B exist where we need to put
the NoDataValue of RasterA in RasterB at the same locations
apply a function on each raster in the datacube.

Parameters
----------
ufunc: [function]
callable universal function ufunc (builtin or user defined)
https://numpy.org/doc/stable/reference/ufuncs.html
- to create a ufunc from a normal function (https://numpy.org/doc/stable/reference/generated/numpy.frompyfunc.html)
- To create an ufunc from a normal function
(https://numpy.org/doc/stable/reference/generated/numpy.frompyfunc.html)

Returns
-------
Expand All @@ -4111,7 +4105,7 @@
>>> dataset.apply(ufunc)
"""
if not callable(ufunc):
raise TypeError("second argument should be a function")
raise TypeError("The Second argument should be a function")

Check warning on line 4108 in pyramids/dataset.py

View check run for this annotation

Codecov / codecov/patch

pyramids/dataset.py#L4108

Added line #L4108 was not covered by tests
arr = self.values
no_data_value = self.base.no_data_value[0]
# execute the function on each raster
Expand Down
10 changes: 5 additions & 5 deletions tests/dataset/test_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -714,8 +714,8 @@ def test_crop_dataset_with_another_dataset_single_band(
src_no_data_value: float,
):
mask_obj = Dataset(src)
aligned_raster = Dataset(aligned_raster)
cropped = aligned_raster._crop_alligned(mask_obj)
aligned_raster: Dataset = Dataset(aligned_raster)
cropped: Dataset = aligned_raster._crop_alligned(mask_obj)
dst_arr_cropped = cropped.raster.ReadAsArray()
# check that all the places of the nodatavalue are the same in both arrays
src_arr[~np.isclose(src_arr, src_no_data_value, rtol=0.001)] = 5
Expand All @@ -731,7 +731,7 @@ def test_crop_dataset_with_another_dataset_multi_band(
mask_obj = Dataset(sentinel_crop)
aligned_raster = Dataset(sentinel_raster)

cropped = aligned_raster._crop_alligned(mask_obj)
cropped: Dataset = aligned_raster._crop_alligned(mask_obj)
dst_arr_cropped = cropped.raster.ReadAsArray()
# filter the no_data_value out of the array
arr = dst_arr_cropped[
Expand Down Expand Up @@ -787,7 +787,7 @@ def test_inplace(
crop_by_wrap_touch_true_result: gdal.Dataset,
):
"""
just check that the inplace option is working
Check that the inplace option is working
"""
dataset = Dataset(rhine_raster)
cells = dataset.count_domain_cells()
Expand Down Expand Up @@ -1319,7 +1319,7 @@ def test_all_bands_with_mask(
era5_mask: GeoDataFrame,
):
"""
test the stats function with a mask.
Test the stats function with a mask.
The mask covers only the second row of the array, the test checks if the mean of the second row is equal to the
mean calculated by the stats function.
"""
Expand Down
Loading