Skip to content

Commit

Permalink
Add Level-3 and Level-4 bands for Land Cover product. (#161)
Browse files Browse the repository at this point in the history
* Added Level4 classes

* Added unit tests for cultivated terrestrial vegetation

* Added unit tests for natural terrestrial vegetation and cultivated terrestrial vegetation

* Added unit tests for natural terrestrial vegetation and cultivated terrestrial vegetation

* Added level-4 water classes

* Cleaned up inconsistencies between the land cover modules

* Improved class names and applied some other clean-ups.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Added more improvement on level3 and level4

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Applied formatting and code improvements

* Further modularised the level4

* Added an integration test for level 4. Also changed data types in unit tests to dask arrays

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Applied linting and formatting

* Applied fixes and improvements based on review comments

* Removed commented code

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Applied formatting changes

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fixed a unit test

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
tebadi and pre-commit-ci[bot] authored Oct 29, 2024
1 parent d799a99 commit 182de0d
Show file tree
Hide file tree
Showing 25 changed files with 3,489 additions and 89 deletions.
3 changes: 2 additions & 1 deletion odc/stats/plugins/_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ def import_all():

# TODO: make that more automatic
modules = [
"odc.stats.plugins.lc_treelite_cultivated.py",
"odc.stats.plugins.lc_treelite_cultivated",
"odc.stats.plugins.lc_level3",
"odc.stats.plugins.lc_treelite_woody",
"odc.stats.plugins.lc_tf_urban",
"odc.stats.plugins.lc_level34",
"odc.stats.plugins.lc_veg_class_a1",
"odc.stats.plugins.lc_fc_wo_a0",
"odc.stats.plugins.mangroves",
Expand Down
Empty file.
46 changes: 46 additions & 0 deletions odc/stats/plugins/l34_utils/l4_bare_gradation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import xarray as xr
from odc.stats._algebra import expr_eval


NODATA = 255


def bare_gradation(xx: xr.Dataset, bare_threshold, veg_cover):

# Map any data > 100 ---> 100
bs_pc_50 = expr_eval(
"where((a>100)&(a!=nodata), 100, a)",
{"a": xx.bs_pc_50.data},
name="mark_veg",
dtype="uint8",
**{"nodata": NODATA},
)

# 60% <= data --> 15
bs_mask = expr_eval(
"where((a>=m)&(a!=nodata), 15, a)",
{"a": bs_pc_50},
name="mark_veg",
dtype="uint8",
**{"m": bare_threshold[1], "nodata": NODATA},
)

# 20% <= data < 60% --> 12
bs_mask = expr_eval(
"where((a>=m)&(a<n), 12, b)",
{"a": bs_pc_50, "b": bs_mask},
name="mark_veg",
dtype="uint8",
**{"m": bare_threshold[0], "n": bare_threshold[1]},
)

# data < 20% --> 10
bs_mask = expr_eval(
"where(a<m, 10, b)",
{"a": bs_pc_50, "b": bs_mask},
name="mark_veg",
dtype="uint8",
**{"m": bare_threshold[0]},
)

return bs_mask
97 changes: 97 additions & 0 deletions odc/stats/plugins/l34_utils/l4_cultivated.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
from odc.stats._algebra import expr_eval

NODATA = 255


def lc_l4_cultivated(l34, level3, lifeform, veg_cover):

l4 = expr_eval(
"where((d==110)&(a==111)&(b==10)&(c==1), 9, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l34},
name="mark_cultivated",
dtype="uint8",
)

l4 = expr_eval(
"where((d==110)&(a==111)&(b==12)&(c==1), 10, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
name="mark_cultivated",
dtype="uint8",
)
l4 = expr_eval(
"where((d==110)&(a==111)&(b==13)&(c==1), 11, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
name="mark_cultivated",
dtype="uint8",
)
l4 = expr_eval(
"where((d==110)&(a==111)&(b==15)&(c==1), 12, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

l4 = expr_eval(
"where((d==110)&(a==111)&(b==16)&(c==1), 13, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

l4 = expr_eval(
"where((d==110)&(a==111)&(b==10)&(c==2), 14, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
name="mark_cultivated",
dtype="uint8",
)
l4 = expr_eval(
"where((d==110)&(a==111)&(b==12)&(c==2), 15, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
name="mark_cultivated",
dtype="uint8",
)
l4 = expr_eval(
"where((d==110)&(a==111)&(b==13)&(c==2), 16, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
name="mark_cultivated",
dtype="uint8",
)
l4 = expr_eval(
"where((d==110)&(a==111)&(b==15)&(c==2), 17, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

l4 = expr_eval(
"where((d==110)&(a==111)&(b==16)&(c==2), 18, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

l4 = expr_eval(
"where((d==110)&(a==111)&(b==1), 2, d)",
{"a": level3, "b": lifeform, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

l4 = expr_eval(
"where((d==110)&(a==111)&(b==2), 3, d)",
{"a": level3, "b": lifeform, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

# the 4-8 classes can't happen in LC since cultivated class will not be classified if vegetation doesn't exist.
# skip these classes in level4

l4 = expr_eval(
"where((d==110)&(a==111), 1, d)",
{"a": level3, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

return l4
Loading

0 comments on commit 182de0d

Please sign in to comment.