dea-tools 0.3.3.dev21__tar.gz → 0.3.4.dev41__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. {dea_tools-0.3.3.dev21/dea_tools.egg-info → dea_tools-0.3.4.dev41}/PKG-INFO +1 -1
  2. dea_tools-0.3.4.dev41/dea_tools/app/geomedian.py +126 -0
  3. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/app/widgetconstructors.py +1 -1
  4. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/spatial.py +75 -5
  5. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/wetlands.py +1 -1
  6. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41/dea_tools.egg-info}/PKG-INFO +1 -1
  7. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools.egg-info/SOURCES.txt +1 -0
  8. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/.gitignore +0 -0
  9. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/LICENSE +0 -0
  10. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/MANIFEST.in +0 -0
  11. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/README.rst +0 -0
  12. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/__init__.py +0 -0
  13. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/__main__.py +0 -0
  14. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/app/__init__.py +0 -0
  15. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/app/animations.py +0 -0
  16. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/app/changefilmstrips.py +0 -0
  17. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/app/crophealth.py +0 -0
  18. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/app/deacoastlines.py +0 -0
  19. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/app/imageexport.py +0 -0
  20. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/app/miningrehab.py +0 -0
  21. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/bandindices.py +0 -0
  22. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/bom.py +0 -0
  23. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/classification.py +0 -0
  24. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/climate.py +0 -0
  25. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/coastal.py +0 -0
  26. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/dask.py +0 -0
  27. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/datahandling.py +0 -0
  28. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/landcover.py +0 -0
  29. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/maps.py +0 -0
  30. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/plotting.py +0 -0
  31. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/pyfes_model.py +0 -0
  32. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/temporal.py +0 -0
  33. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/validation.py +0 -0
  34. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools/waterbodies.py +0 -0
  35. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools.egg-info/dependency_links.txt +0 -0
  36. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools.egg-info/requires.txt +0 -0
  37. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/dea_tools.egg-info/top_level.txt +0 -0
  38. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/index.rst +0 -0
  39. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/mock_imports.txt +0 -0
  40. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/pyproject.toml +0 -0
  41. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/setup.cfg +0 -0
  42. {dea_tools-0.3.3.dev21 → dea_tools-0.3.4.dev41}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dea-tools
3
- Version: 0.3.3.dev21
3
+ Version: 0.3.4.dev41
4
4
  Summary: Functions and algorithms for analysing Digital Earth Australia data.
5
5
  Home-page: https://github.com/GeoscienceAustralia/dea-notebooks
6
6
  Author: Geoscience Australia
@@ -0,0 +1,126 @@
1
+ """
2
+ Geomedian widget: generates an interactive visualisation of
3
+ the geomedian summary statistic.
4
+ """
5
+
6
+ # Load modules
7
+ import ipywidgets as widgets
8
+ import matplotlib.pyplot as plt
9
+ from mpl_toolkits.mplot3d import Axes3D
10
+ import numpy as np
11
+ import xarray as xr
12
+ from odc.algo import xr_geomedian
13
+
14
+ def run_app():
15
+
16
+ """
17
+ An interactive app that allows users to visualise the difference between the median and geomedian time-series summary statistics. By modifying the red-green-blue values of three timesteps for a given pixel, the user changes the output summary statistics.
18
+
19
+ This allows a visual representation of the difference through the output values, RGB colour, as well as showing values plotted as a vector on a 3-dimensional space.
20
+
21
+ Last modified: December 2021
22
+ """
23
+
24
+ # Define the red-green-blue sliders for timestep 1
25
+ p1r = widgets.IntSlider(description='Red', max=255, value=58)
26
+ p1g = widgets.IntSlider(description='Green', max=255, value=153)
27
+ p1b = widgets.IntSlider(description='Blue', max=255, value=68)
28
+
29
+ # Define the red-green-blue sliders for timestep 2
30
+ p2r = widgets.IntSlider(description='Red', max=255, value=208)
31
+ p2g = widgets.IntSlider(description='Green', max=255, value=221)
32
+ p2b = widgets.IntSlider(description='Blue', max=255, value=203)
33
+
34
+ # Define the red-green-blue sliders for timestep 3
35
+ p3r = widgets.IntSlider(description='Red', max=255, value=202)
36
+ p3g = widgets.IntSlider(description='Green', max=255, value=82)
37
+ p3b = widgets.IntSlider(description='Blue', max=255, value=33)
38
+
39
+ # Define the median calculation for the timesteps
40
+ def f(p1r, p1g, p1b, p2r, p2g, p2b, p3r, p3g, p3b):
41
+ print('Red Median = {}'.format(np.median([p1r, p2r, p3r])))
42
+ print('Green Median = {}'.format(np.median([p1g, p2g, p3g])))
43
+ print('Blue Median = {}'.format(np.median([p1b, p2b, p3b])))
44
+
45
+ # Define the geomedian calculation for the timesteps
46
+ def g(p1r, p1g, p1b, p2r, p2g, p2b, p3r, p3g, p3b):
47
+ print('Red Geomedian = {:.2f}'.format(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).red.values.ravel()[0]))
48
+ print('Green Geomedian = {:.2f}'.format(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).green.values.ravel()[0]))
49
+ print('Blue Geomedian = {:.2f}'.format(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).blue.values.ravel()[0]))
50
+
51
+ # Define the Timestep 1 box colour
52
+ def h(p1r, p1g, p1b):
53
+ fig1, axes1 = plt.subplots(figsize=(2,2))
54
+ fig1 = plt.imshow([[(p1r, p1g, p1b)]])
55
+ axes1.set_title('Timestep 1')
56
+ axes1.axis('off')
57
+ plt.show(fig1)
58
+
59
+ # Define the Timestep 2 box colour
60
+ def hh(p2r, p2g, p2b):
61
+ fig2, axes2 = plt.subplots(figsize=(2,2))
62
+ fig2 = plt.imshow([[(p2r, p2g, p2b)]])
63
+ axes2.set_title('Timestep 2')
64
+ axes2.axis('off')
65
+ plt.show(fig2)
66
+
67
+ # Define the Timestep 3 box colour
68
+ def hhh(p3r, p3g, p3b):
69
+ fig3, axes3 = plt.subplots(figsize=(2,2))
70
+ fig3 = plt.imshow([[(p3r, p3g, p3b)]])
71
+ axes3.set_title('Timestep 3')
72
+ axes3.axis('off')
73
+ plt.show(fig3)
74
+
75
+ # Define the Median RGB colour box
76
+ def i(p1r, p1g, p1b, p2r, p2g, p2b, p3r, p3g, p3b):
77
+ fig4, axes4 = plt.subplots(figsize=(3,3))
78
+ fig4 = plt.imshow([[(int(np.median([p1r, p2r, p3r])), int(np.median([p1g, p2g, p3g])), int(np.median([p1b, p2b, p3b])))]])
79
+ axes4.set_title('Median RGB - All timesteps')
80
+ axes4.axis('off')
81
+ plt.show(fig4)
82
+
83
+ # Define the Geomedian RGB colour box
84
+ def ii(p1r, p1g, p1b, p2r, p2g, p2b, p3r, p3g, p3b):
85
+ fig5, axes5 = plt.subplots(figsize=(3,3))
86
+ fig5 = plt.imshow([[(int(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).red.values.ravel()[0]), int(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).green.values.ravel()[0]), int(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).blue.values.ravel()[0]))]])
87
+ axes5.set_title('Geomedian RGB - All timesteps')
88
+ axes5.axis('off')
89
+ plt.show(fig5)
90
+
91
+ # Define 3-D axis to display vectors on
92
+ def j(p1r, p1g, p1b, p2r, p2g, p2b, p3r, p3g, p3b):
93
+ fig6 = plt.figure()
94
+ axes6 = fig6.add_subplot(111, projection='3d')
95
+ x = [p1r, p2r, p3r, int(np.median([p1r, p2r, p3r])), int(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).red.values.ravel()[0])]
96
+ y = [p1g, p2g, p3g, int(np.median([p1g, p2g, p3g])), int(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).green.values.ravel()[0])]
97
+ z = [p1b, p2b, p3b, int(np.median([p1b, p2b, p3b])), int(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).blue.values.ravel()[0])]
98
+ labels = [' 1', ' 2', ' 3', ' median', ' geomedian']
99
+ axes6.scatter(x, y, z, c=['black','black','black','r', 'blue'], marker='o')
100
+ axes6.set_xlabel('Red')
101
+ axes6.set_ylabel('Green')
102
+ axes6.set_zlabel('Blue')
103
+ axes6.set_xlim3d(0, 255)
104
+ axes6.set_ylim3d(0, 255)
105
+ axes6.set_zlim3d(0, 255)
106
+ for ax, ay, az, label in zip(x, y, z, labels):
107
+ axes6.text(ax, ay, az, label)
108
+ plt.title('Each band represents a dimension.')
109
+ plt.show()
110
+
111
+ # Define outputs
112
+ outf = widgets.interactive_output(f, {'p1r': p1r, 'p2r': p2r,'p3r': p3r, 'p1g': p1g, 'p2g': p2g,'p3g': p3g, 'p1b': p1b, 'p2b': p2b,'p3b': p3b})
113
+ outg = widgets.interactive_output(g, {'p1r': p1r, 'p2r': p2r,'p3r': p3r, 'p1g': p1g, 'p2g': p2g,'p3g': p3g, 'p1b': p1b, 'p2b': p2b,'p3b': p3b})
114
+
115
+ outh = widgets.interactive_output(h, {'p1r': p1r, 'p1g': p1g, 'p1b': p1b})
116
+ outhh = widgets.interactive_output(hh, {'p2r': p2r, 'p2g': p2g, 'p2b': p2b})
117
+ outhhh = widgets.interactive_output(hhh, {'p3r': p3r, 'p3g': p3g, 'p3b': p3b})
118
+
119
+ outi = widgets.interactive_output(i, {'p1r': p1r, 'p2r': p2r,'p3r': p3r, 'p1g': p1g, 'p2g': p2g,'p3g': p3g, 'p1b': p1b, 'p2b': p2b,'p3b': p3b})
120
+ outii = widgets.interactive_output(ii, {'p1r': p1r, 'p2r': p2r,'p3r': p3r, 'p1g': p1g, 'p2g': p2g,'p3g': p3g, 'p1b': p1b, 'p2b': p2b,'p3b': p3b})
121
+
122
+ outj = widgets.interactive_output(j, {'p1r': p1r, 'p2r': p2r,'p3r': p3r, 'p1g': p1g, 'p2g': p2g,'p3g': p3g, 'p1b': p1b, 'p2b': p2b,'p3b': p3b})
123
+
124
+ app_output = widgets.HBox([widgets.VBox([widgets.HBox([outh, widgets.VBox([ p1r, p1g, p1b])]), widgets.HBox([outhh, widgets.VBox([p2r, p2g, p2b])]), widgets.HBox([outhhh, widgets.VBox([ p3r, p3g, p3b])])]), widgets.VBox([widgets.HBox([widgets.VBox([outf, outi]), widgets.VBox([outg, outii])]), outj])])
125
+
126
+ return app_output
@@ -274,7 +274,7 @@ def create_dea_wms_layer(product, date, **params):
274
274
  ----------
275
275
  product : string
276
276
  The Digital Earth Australia product to load
277
- (e.g. 'ga_ls8c_nbart_gm_cyear_3')
277
+ (e.g. 'ga_ls8cls9c_gm_cyear_3')
278
278
  date : string (yyyy-mm-dd format)
279
279
  The date to load the product for
280
280
 
@@ -16,7 +16,7 @@ here: https://gis.stackexchange.com/questions/tagged/open-data-cube).
16
16
  If you would like to report an issue with this script, file one on
17
17
  GitHub: https://github.com/GeoscienceAustralia/dea-notebooks/issues/new
18
18
 
19
- Last modified: June 2024
19
+ Last modified: July 2024
20
20
 
21
21
  """
22
22
 
@@ -33,8 +33,6 @@ import geopandas as gpd
33
33
  import rasterio.features
34
34
  import scipy.interpolate
35
35
  import multiprocessing as mp
36
- from odc.geo.geom import Geometry
37
- from odc.geo.crs import CRS
38
36
  from scipy import ndimage as nd
39
37
  from scipy.spatial import cKDTree as KDTree
40
38
  from skimage.measure import label
@@ -42,9 +40,74 @@ from rasterstats import zonal_stats
42
40
  from skimage.measure import find_contours
43
41
  from geopy.geocoders import Nominatim
44
42
  from geopy.exc import GeocoderUnavailable, GeocoderServiceError
43
+ from shapely.geometry import (
44
+ MultiPoint,
45
+ MultiLineString,
46
+ LineString,
47
+ Polygon,
48
+ MultiPolygon,
49
+ Point,
50
+ shape,
51
+ mapping,
52
+ )
45
53
 
46
54
  from datacube.utils.cog import write_cog
47
- from shapely.geometry import LineString, MultiLineString, shape, mapping
55
+ from odc.geo.geom import Geometry
56
+ from odc.geo.crs import CRS
57
+
58
+
59
+ def _geom_to_multipoint(geom):
60
+ """
61
+ Convert a LineString, MultiLineString, Polygon, MultiPolygon or
62
+ Point to a MultiPoint geometry.
63
+ """
64
+ if isinstance(geom, LineString):
65
+ points = list(geom.coords)
66
+ elif isinstance(geom, MultiLineString):
67
+ points = [point for line in geom.geoms for point in line.coords]
68
+ elif isinstance(geom, Polygon):
69
+ points = list(geom.boundary.coords)
70
+ elif isinstance(geom, MultiPolygon):
71
+ points = [point for poly in geom.boundary.geoms for point in poly.coords]
72
+ elif isinstance(geom, Point):
73
+ points = [geom]
74
+ elif isinstance(geom, MultiPoint):
75
+ points = [point for point in geom.geoms]
76
+
77
+ return MultiPoint(points)
78
+
79
+
80
+ def extract_vertices(gdf, explode=True, ignore_index=True):
81
+ """
82
+ Extract vertices from any GeoDataFrame features, returning Point or
83
+ MultiPoint geometries.
84
+
85
+ Parameters
86
+ ----------
87
+ gdf : geopandas.GeoDataFrame
88
+ Input GeoDataFrame containing geometries to be converted.
89
+ explode : bool, optional
90
+ By default, MultiPoint geometries will be exploded into individual
91
+ Points. If False, geometries will be returned as MultiPoints.
92
+ ignore_index : bool, optional
93
+ If True and explode=True, the resulting GeoDataFrame will have a
94
+ new index.
95
+
96
+ Returns
97
+ -------
98
+ geopandas.GeoDataFrame
99
+ Updated GeoDataFrame with geometries converted to Points or
100
+ MultiPoints.
101
+ """
102
+
103
+ # Convert all input features to MultiPoints
104
+ gdf["geometry"] = gdf["geometry"].apply(_geom_to_multipoint)
105
+
106
+ # Optionally break MultiPoints into individual Points
107
+ if explode:
108
+ gdf = gdf.explode(ignore_index=ignore_index)
109
+
110
+ return gdf
48
111
 
49
112
 
50
113
  def points_on_line(gdf, index, distance=30):
@@ -850,7 +913,7 @@ def xr_interpolate(
850
913
 
851
914
  # Run interpolation on values from each numeric column,
852
915
  for col, z_values in numeric_gdf.items():
853
-
916
+
854
917
  # Apply scipy.interpolate.griddata interpolation methods
855
918
  if method in ("linear", "nearest", "cubic"):
856
919
  # Interpolate x, y and z values
@@ -1047,6 +1110,13 @@ def contours_to_arrays(gdf, col):
1047
1110
  of each vertex in the input GeoDataFrame.
1048
1111
 
1049
1112
  """
1113
+
1114
+ warnings.warn(
1115
+ "This function is deprecated and will be retired in a future "
1116
+ "release. Please use `extract_vertices` instead.",
1117
+ DeprecationWarning,
1118
+ stacklevel=2,
1119
+ )
1050
1120
 
1051
1121
  coords_zvals = []
1052
1122
 
@@ -274,7 +274,7 @@ def display_wit_stack_with_df(
274
274
  ["open water", "wet", "green veg", "dry veg", "bare soil"][::-1],
275
275
  loc="lower left",
276
276
  )
277
- handles = legend.legendHandles
277
+ handles = legend.legend_handles
278
278
 
279
279
  for i, handle in enumerate(handles):
280
280
  handle.set_facecolor(pal[::-1][i])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dea-tools
3
- Version: 0.3.3.dev21
3
+ Version: 0.3.4.dev41
4
4
  Summary: Functions and algorithms for analysing Digital Earth Australia data.
5
5
  Home-page: https://github.com/GeoscienceAustralia/dea-notebooks
6
6
  Author: Geoscience Australia
@@ -34,6 +34,7 @@ dea_tools/app/animations.py
34
34
  dea_tools/app/changefilmstrips.py
35
35
  dea_tools/app/crophealth.py
36
36
  dea_tools/app/deacoastlines.py
37
+ dea_tools/app/geomedian.py
37
38
  dea_tools/app/imageexport.py
38
39
  dea_tools/app/miningrehab.py
39
40
  dea_tools/app/widgetconstructors.py
File without changes