Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
fbunt committed Jan 4, 2023
2 parents 28d5731 + 513813f commit f0f327b
Show file tree
Hide file tree
Showing 51 changed files with 2,880 additions and 1,960 deletions.
63 changes: 48 additions & 15 deletions docs/reference/raster.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,36 @@ Constructing Rasters

Raster

Attributes
Properties
==========

.. autosummary::
:toctree: generated/

Raster.affine
Raster.bounds
Raster.crs
Raster.dtype
Raster.shape
Raster.nbands
Raster.null_value
Raster.pxrs
Raster.values
Raster.data
Raster.xdata
Raster.mask
Raster.xmask
Raster.x
Raster.y
Raster.crs
Raster.affine
Raster.resolution
Raster.shape
Raster.bounds
Raster.bandwise

Deprecated Properties
---------------------

.. autosummary::
:toctree: generated/

Raster.pxrs
Raster.xrs

Operations
Expand All @@ -36,9 +52,9 @@ Arithmetic and Comparison Operations

Raster objects support all arithmetic (``+``, ``-``, ``*``,
``/``, ``//``, ``%``, ``divmod()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,
``|``, ``~``) and comparison operations (``==``, ``<``, ``>``, ``<=``,
``>=``, ``!=``). Because of this, they can be used like regular scalar
variables. Some examples:
``|``, ``~``), bitwise/logical operators (``&``, ``|``, ``^``, ``~``), and
comparison operations (``==``, ``<``, ``>``, ``<=``, ``>=``, ``!=``). Because
of this, they can be used like regular scalar variables. Some examples:

* Addition and subtraction: ``rs4 = rs1 + rs2 - rs3``
* Floor division: ``rs3 = rs1 // rs2``
Expand All @@ -49,11 +65,6 @@ variables. Some examples:
* Bitwise complement: ``rs2 = ~rs1``
* Comparison: ``rs_bool = rs1 >= rs2``

The bitwise/logical operators (``&``, ``|``, ``^``, ``~``) have been overloaded
so that they behave differently from python's (or numpy's). Non-boolean
operands are coerced to the boolean type such that values greater than zero
become ``True`` and values less than or equal to zero become ``False``.

General
-------

Expand All @@ -78,12 +89,17 @@ Reductions
Raster.sum
Raster.var


Methods
=======

Reshaping and Reorganizing
--------------------------

.. autosummary::
:toctree: generated/

Raster.chunk
Raster.get_bands

Null Data and Remapping
Expand All @@ -93,6 +109,7 @@ Null Data and Remapping
:toctree: generated/

Raster.burn_mask
Raster.reclassify
Raster.replace_null
Raster.remap_range
Raster.set_null_value
Expand All @@ -107,7 +124,7 @@ Contents / Conversion

Raster.astype
Raster.copy
Raster.to_dask
Raster.to_dataset
Raster.to_vector

Georeferencing
Expand All @@ -129,3 +146,19 @@ Raster IO
Raster.close
Raster.eval
Raster.save

Plotting
========

.. autosummary::
:toctree: generated/

Raster.plot

Miscellaneous
=============

.. autosummary::
:toctree: generated/

Raster.get_chunked_coords
21 changes: 14 additions & 7 deletions raster_tools/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from raster_tools import clipping, distance, focal, line_stats, surface
from raster_tools import clipping, distance, focal, line_stats, surface, zonal
from raster_tools._version import __version__ # noqa
from raster_tools.creation import (
constant_raster,
Expand All @@ -8,28 +8,35 @@
random_raster,
zeros_like,
)
from raster_tools.general import band_concat, remap_range
from raster_tools.raster import Raster
from raster_tools.vector import Vector, open_vectors
from raster_tools.zonal import ZONAL_STAT_FUNCS, zonal_stats
from raster_tools.general import band_concat, reclassify, remap_range
from raster_tools.raster import Raster, get_raster
from raster_tools.vector import (
Vector,
count_layer_features,
list_layers,
open_vectors,
)

__all__ = [
"Raster",
"Vector",
"ZONAL_STAT_FUNCS",
"band_concat",
"clipping",
"constant_raster",
"count_layer_features",
"distance",
"empty_like",
"focal",
"full_like",
"get_raster",
"line_stats",
"list_layers",
"ones_like",
"open_vectors",
"random_raster",
"reclassify",
"remap_range",
"surface",
"zeros_like",
"zonal_stats",
"zonal",
]
33 changes: 0 additions & 33 deletions raster_tools/_utils.py

This file was deleted.

2 changes: 1 addition & 1 deletion raster_tools/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.1.0a9"
__version__ = "0.1.0b1"
2 changes: 1 addition & 1 deletion raster_tools/batch.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import os
import re

from raster_tools._utils import validate_file
from raster_tools.dtypes import is_int, is_scalar
from raster_tools.general import band_concat
from raster_tools.masking import get_default_null_value
from raster_tools.raster import Raster
from raster_tools.utils import validate_file


class BatchScriptParseError(BaseException):
Expand Down
45 changes: 26 additions & 19 deletions raster_tools/clipping.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import dask
import dask.array as da
import numpy as np
import rioxarray as rxr
import xarray as xr

from raster_tools.creation import ones_like, zeros_like
from raster_tools.masking import get_default_null_value
from raster_tools.raster import RasterNoDataError, get_raster
from raster_tools.raster import Raster, RasterNoDataError, get_raster
from raster_tools.utils import make_raster_ds
from raster_tools.vector import get_vector


Expand Down Expand Up @@ -43,26 +44,31 @@ def _clip(

feat_rs = feat.to_raster(rs)
if not envelope:
clip_mask = feat_rs > 0
if invert:
clip_mask = feat_rs.to_null_mask()
else:
clip_mask = ~feat_rs.to_null_mask()
else:
clip_mask = feat_rs >= 0
clip_mask._mask[:] = False
if invert:
clip_mask = zeros_like(feat_rs, dtype=bool)
else:
clip_mask = ones_like(feat_rs, dtype=bool)

if rs._masked:
nv = rs.null_value
else:
nv = get_default_null_value(rs.dtype)

if invert:
clip_mask = ~clip_mask
clip_mask._mask = ~clip_mask._mask
xrs_out = xr.where(clip_mask.xrs, rs.xrs, nv)
xrs_out = xrs_out.rio.write_crs(rs.crs)
mask_out = clip_mask._mask
xdata_out = xr.where(clip_mask.xdata, rs.xdata, nv)
xmask_out = ~clip_mask.xdata

if rs._masked:
mask_out |= rs._mask
return rs._replace(xrs_out, mask=mask_out, null_value=nv)
xmask_out |= rs.xmask
xdata_out = xdata_out.rio.write_nodata(nv)
ds_out = make_raster_ds(xdata_out, xmask_out)
if rs.crs is not None:
ds_out = ds_out.rio.write_crs(rs.crs)
return Raster(ds_out, _fast_path=True)


def clip(feature, data_raster, bounds=None):
Expand Down Expand Up @@ -209,13 +215,14 @@ def clip_box(raster, bounds):
if len(bounds) != 4:
raise ValueError("Invalid bounds. Must be a size 4 array or tuple.")
try:
xrs = rs.xrs.rio.clip_box(*bounds, auto_expand=True)
xrs = rs.xdata.rio.clip_box(*bounds, auto_expand=True)
except rxr.exceptions.NoDataInBounds:
raise RasterNoDataError("No data found within provided bounds")
if rs._masked:
mask = rs.xmask.rio.clip_box(*bounds, auto_expand=True).data
xmask = rs.xmask.rio.clip_box(*bounds, auto_expand=True)
else:
mask = da.zeros_like(xrs.data, dtype=bool)
# TODO: This will throw a rioxarray.exceptions.MissingCRS exception if
# no crs is set. Add code to fall back on
return rs._replace(xrs, mask=mask)
xmask = xr.zeros_like(xrs, dtype=bool)
ds = make_raster_ds(xrs, xmask)
if rs.crs is not None:
ds = ds.rio.write_crs(rs.crs)
return Raster(ds, _fast_path=True)
Loading

0 comments on commit f0f327b

Please sign in to comment.