romero61 commited on
Commit
314e544
·
1 Parent(s): 37488bd

added salinity

Browse files
pages/01-main.py CHANGED
@@ -7,10 +7,10 @@ import sys
7
 
8
 
9
 
10
- print('entering project_root')
11
  # Get the project root directory
12
  project_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
13
- print(f'exiting project root', {project_root})
14
  module_path = os.path.join(project_root, 'public')
15
  print(module_path)
16
  # Add the module path to the Python path
@@ -18,7 +18,7 @@ sys.path.append(module_path)
18
 
19
  # Define the path to the shapefile
20
  shapefile_path = os.path.join(project_root,'WaterQuality_SMB', 'public', 'study_boundary.gpkg')
21
- print(f'shapefile path:', {shapefile_path})
22
 
23
 
24
 
@@ -49,6 +49,8 @@ class Map(geemap.Map):
49
  self.functions.load_and_process_spm(self, STUDY_BOUNDARY_PATH)
50
  elif self.selected_image_type == 'SST':
51
  self.functions.load_and_process_sst(self, STUDY_BOUNDARY_PATH)
 
 
52
 
53
  def set_selected_image_type(self, new_image_type):
54
  self.selected_image_type = new_image_type
@@ -100,7 +102,7 @@ Monitoring water quality is crucial for the preservation of marine ecosystems. C
100
 
101
  with solara.Column(style={'min-width': "500px"}):
102
  with solara.Card(title = 'Select Map Type', subtitle = 'Choose between True Color, Chlorophyll-a, Suspended Particle Matter, Sea Surface Temperature'):
103
- solara.ToggleButtonsSingle(value=selected_image_type, values=["True Color", "Chl-a", "SPM", "SST"], on_value=on_change_callback)
104
  solara.Markdown('''Currently bugged between switching: Return to TRUE COLOR then switch to CHL-A, SPM, or SST''')
105
  Map(selected_image_type).element(
106
  selected_image_type= selected_image_type,
 
7
 
8
 
9
 
10
+
11
  # Get the project root directory
12
  project_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
13
+
14
  module_path = os.path.join(project_root, 'public')
15
  print(module_path)
16
  # Add the module path to the Python path
 
18
 
19
  # Define the path to the shapefile
20
  shapefile_path = os.path.join(project_root,'WaterQuality_SMB', 'public', 'study_boundary.gpkg')
21
+
22
 
23
 
24
 
 
49
  self.functions.load_and_process_spm(self, STUDY_BOUNDARY_PATH)
50
  elif self.selected_image_type == 'SST':
51
  self.functions.load_and_process_sst(self, STUDY_BOUNDARY_PATH)
52
+ elif self.selected_image_type == 'Salinity':
53
+ self.functions.load_and_process_salinity(self, STUDY_BOUNDARY_PATH)
54
 
55
  def set_selected_image_type(self, new_image_type):
56
  self.selected_image_type = new_image_type
 
102
 
103
  with solara.Column(style={'min-width': "500px"}):
104
  with solara.Card(title = 'Select Map Type', subtitle = 'Choose between True Color, Chlorophyll-a, Suspended Particle Matter, Sea Surface Temperature'):
105
+ solara.ToggleButtonsSingle(value=selected_image_type, values=["True Color", "Chl-a", "SPM", "SST", 'Salinity'], on_value=on_change_callback)
106
  solara.Markdown('''Currently bugged between switching: Return to TRUE COLOR then switch to CHL-A, SPM, or SST''')
107
  Map(selected_image_type).element(
108
  selected_image_type= selected_image_type,
pages/05_background.py CHANGED
@@ -4,71 +4,77 @@ import solara
4
  @solara.component
5
  def Page():
6
  with solara.Column(align="center"):
7
- markdown = """
8
- ## Earth Engine Web Apps
9
-
10
- **A collection of Earth Engine web apps developed using [Solara](https://github.com/widgetti/solara) and geemap**
11
 
12
-
13
- # WaterQualityMonitoring_SMB
14
- Monitoring water quality in the Santa Monica Bay using Landsat 8 OLI satellite data
15
 
16
- # Reproducing Chlorophyll-a Analysis in Santa Monica Bay Using Landsat 8
17
- This notebook aims to reproduce and extend the analysis conducted in the ocean remote sensing project titled "Remote Sensing of Chlorophyll-a using Landsat 8". The original project, available [here](https://romero61.github.io/posts/SMB/), focused on the analysis of Chlorophyll-a concentrations in the Santa Monica Bay.
 
18
 
19
- We utilize Landsat 8 satellite imagery to estimate Chlorophyll-a concentrations & Suspended Particle Matter and analyze changes over time, particularly focusing on the impact of the Hyperion Treatment Plant failure.
 
20
 
21
- The Earth Engine Web app include the following steps:
22
 
23
- 1. Importing necessary Python libraries for data manipulation, mathematical operations, data visualization, handling date and time data, interacting with Google Earth Engine, and handling geospatial data.
24
 
25
- 2. Initializing the Earth Engine API and creating an interactive map using the geemap library.
26
 
27
- 3. Defining the collection of satellite images to be used (Landsat 8 OLI images) and the study area.
28
 
29
- 4. Processing the satellite images, including applying scale factors and estimating Chlorophyll-a & Suspended Particle Matter concentrations.
30
 
31
- 5. Visualizing the processed images on an interactive map.
32
 
33
- The next steps of this project will include retrieving the most recent image from the collection, calculating basic statistics for Chlorophyll-a concentrations & Suspended Particle Matter, allowing user-defined regions for analysis, and creating an interactive data exploration.
34
 
35
- # Santa Monica Bay
36
 
37
- Santa Monica Bay Watershed Management Area (WMA): The Santa Monica Bay WMA encompasses an area of 414 square miles and is quite diverse. Its borders reach from the crest of the Santa Monica Mountains on the north and from the Ventura-Los Angeles County line to downtown Los Angeles. The WMA includes several watersheds, the two largest being Malibu Creek to the north (west) and Ballona Creek to the south. The Malibu Creek area contains mostly undeveloped mountain areas, large acreage residential properties, and many natural stream reaches. At the same time, Ballona Creek is predominantly channelized and highly developed with both residential and commercial properties. The Santa Monica Bay was included in the National Estuary Program in 1989 and has been extensively studied by the Santa Monica Bay Restoration Project. The Santa Monica Bay Watershed Commission was established in 2002 to oversee the implementation of the Plan.
38
 
39
- Water Quality Problems and Issues: The Santa Monica Bay WMA embraces a high diversity of geological and hydrological characteristics, habitat features, and human activities. Existing and potential beneficial use impairment problems in the watershed fall into two major categories: human health risk and natural habitat degradation. The former are issues primarily associated with recreational uses of the Santa Monica Bay. The latter are issues associated with terrestrial, aquatic, and marine environments. Pollutant loadings that originate from human activities are common causes of both human health risks and habitat degradation.
40
 
41
- # Suspended Particulate Matter
42
 
43
- The Santa Monica Bay, California, and the Gironde Estuary and Bourgneuf Bay in France have some similarities but also significant differences. Here are some key points to consider:
44
 
45
- Size and Geography: The Santa Monica Bay is a bight of the Pacific Ocean, while the Gironde Estuary and Bourgneuf Bay are estuaries, which are partially enclosed coastal bodies of water where freshwater from rivers and streams meets and mixes with saltwater from the ocean. The Gironde Estuary is formed by the confluence of the Garonne and Dordogne Rivers, and the Loire River feeds into Bourgneuf Bay. The Santa Monica Bay, on the other hand, is fed by several smaller watersheds, including Malibu Creek and Ballona Creek.
46
 
47
- Turbidity and SPM Concentration: The Gironde Estuary and Bourgneuf Bay are characterized by high Suspended Particulate Matter (SPM) concentrations, ranging from 1 to 3000 g·m−3 in the Gironde and 50 to over 1000 g·m−3 in Bourgneuf Bay. The Santa Monica Bay, according to the information found, has a lower SPM concentration, with a median value of 1.3 mg/L (or approximately 0.0013 g·m−3), which is significantly lower than the French sites.
48
 
49
- Tidal Range: Both the Gironde Estuary and Bourgneuf Bay have a macro-tidal regime, with tidal ranges from 2 to 5 m and 2 to 6 m, respectively. The tidal range in the Santa Monica Bay is not explicitly stated in the sources found, but the Pacific coast of Southern California typically experiences a smaller tidal range, usually less than 2 meters.
50
 
51
- Freshwater Inputs: The Gironde Estuary and Bourgneuf Bay have significant freshwater inputs from large rivers, with flow rates ranging from less than 100 m3·s−1 to more than 4000 m3·s−1. The Santa Monica Bay receives freshwater inputs from several smaller watersheds, but the flow rates are likely much lower than those of the French sites.
52
 
 
53
 
54
- The Santa Monica Bay, California, and the Gironde Estuary and Bourgneuf Bay in France have some similarities but also significant differences. Here are some key points to consider:
55
 
56
- Size and Geography: The Santa Monica Bay is a bight of the Pacific Ocean, while the Gironde Estuary and Bourgneuf Bay are estuaries, which are partially enclosed coastal bodies of water where freshwater from rivers and streams meets and mixes with saltwater from the ocean. The Gironde Estuary is formed by the confluence of the Garonne and Dordogne rivers, and the Loire River feeds into Bourgneuf Bay. The Santa Monica Bay, on the other hand, is fed by several smaller watersheds, including Malibu Creek and Ballona Creek.
57
 
58
- Turbidity and SPM Concentration: The Gironde Estuary and Bourgneuf Bay are characterized by high Suspended Particulate Matter (SPM) concentrations, ranging from 1 to 3000 g·m−3 in the Gironde and 50 to over 1000 g·m−3 in Bourgneuf Bay. The Santa Monica Bay, according to the information found, has a lower SPM concentration, with a median value of 1.3 mg/L (or approximately 0.0013 g·m−3), which is significantly lower than the French sites.
59
 
60
- Tidal Range: Both the Gironde Estuary and Bourgneuf Bay have a macro-tidal regime, with tidal ranges from 2 to 5 m and 2 to 6 m, respectively. The tidal range in the Santa Monica Bay is not explicitly stated in the sources found, but the Pacific coast of Southern California typically experiences a smaller tidal range, usually less than 2 meters.
61
 
62
- In conclusion, while there are some similarities in terms of being coastal water bodies with freshwater inputs, the Gironde Estuary and Bourgneuf Bay in France appear to be significantly more turbid and have higher SPM concentrations than the Santa Monica Bay.
63
 
64
- Freshwater Inputs: The Gironde Estuary and Bourgneuf Bay have significant freshwater inputs from large rivers, with flow rates ranging from less than 100 m3·s−1 to more than 4000 m3·s−1. The Santa Monica Bay receives freshwater inputs from several smaller watersheds, but the flow rates are likely much lower than those of the French sites.
65
 
66
- In conclusion, while there are some similarities in terms of being coastal water bodies with freshwater inputs, the Gironde Estuary and Bourgneuf Bay in France appear to be significantly more turbid and have higher SPM concentrations than the Santa Monica Bay. Therefore, the models developed for the French sites may not be directly applicable to the Santa Monica Bay without some adjustments or recalibrations.
67
 
68
- # References
69
- Trinh, R. C., Fichot, C. G., Gierach, M. M., Holt, B., Malakar, N. K., Hulley, G., & Smith, J. (2017). Application of Landsat 8 for Monitoring Impacts of Wastewater Discharge on Coastal Water Quality. Frontiers in Marine Science, 4. https://doi.org/10.3389/fmars.2017.00329
70
 
71
- Novoa S, Doxaran D, Ody A, Vanhellemont Q, Lafon V, Lubac B, Gernez P. Atmospheric Corrections and Multi-Conditional Algorithm for Multi-Sensor Remote Sensing of Suspended Particulate Matter in Low-to-High Turbidity Levels Coastal Waters. Remote Sensing. 2017; 9(1):61. https://doi.org/10.3390/rs9010061
72
- """
 
 
 
 
 
 
 
 
 
73
 
74
  solara.Markdown(markdown)
 
4
  @solara.component
5
  def Page():
6
  with solara.Column(align="center"):
7
+ markdown ="""
8
+ ## Earth Engine Web Apps
 
 
9
 
10
+ **A collection of Earth Engine web apps developed using [Solara](https://github.com/widgetti/solara) and geemap**
 
 
11
 
12
+
13
+ # WaterQualityMonitoring_SMB
14
+ Monitoring water quality in the Santa Monica Bay using Landsat 8 OLI satellite data
15
 
16
+ # Reproducing Chlorophyll-a Analysis in Santa Monica Bay Using Landsat 8
17
+ This notebook aims to reproduce and extend the analysis conducted in the ocean remote sensing project titled "Remote Sensing of Chlorophyll-a using Landsat 8". The original project, available [here](https://romero61.github.io/posts/SMB/), focused on the analysis of Chlorophyll-a concentrations in the Santa Monica Bay.
18
 
19
+ We utilize Landsat 8 satellite imagery to estimate Chlorophyll-a concentrations & Suspended Particle Matter and analyze changes over time, particularly focusing on the impact of the Hyperion Treatment Plant failure.
20
 
21
+ The Earth Engine Web app include the following steps:
22
 
23
+ 1. Importing necessary Python libraries for data manipulation, mathematical operations, data visualization, handling date and time data, interacting with Google Earth Engine, and handling geospatial data.
24
 
25
+ 2. Initializing the Earth Engine API and creating an interactive map using the geemap library.
26
 
27
+ 3. Defining the collection of satellite images to be used (Landsat 8 OLI images) and the study area.
28
 
29
+ 4. Processing the satellite images, including applying scale factors and estimating Chlorophyll-a & Suspended Particle Matter concentrations.
30
 
31
+ 5. Visualizing the processed images on an interactive map.
32
 
33
+ The next steps of this project will include retrieving the most recent image from the collection, calculating basic statistics for Chlorophyll-a concentrations & Suspended Particle Matter, allowing user-defined regions for analysis, and creating an interactive data exploration.
34
 
35
+ # Santa Monica Bay
36
 
37
+ Santa Monica Bay Watershed Management Area (WMA): The Santa Monica Bay WMA encompasses an area of 414 square miles and is quite diverse. Its borders reach from the crest of the Santa Monica Mountains on the north and from the Ventura-Los Angeles County line to downtown Los Angeles. The WMA includes several watersheds, the two largest being Malibu Creek to the north (west) and Ballona Creek to the south. The Malibu Creek area contains mostly undeveloped mountain areas, large acreage residential properties, and many natural stream reaches. At the same time, Ballona Creek is predominantly channelized and highly developed with both residential and commercial properties. The Santa Monica Bay was included in the National Estuary Program in 1989 and has been extensively studied by the Santa Monica Bay Restoration Project. The Santa Monica Bay Watershed Commission was established in 2002 to oversee the implementation of the Plan.
38
 
39
+ Water Quality Problems and Issues: The Santa Monica Bay WMA embraces a high diversity of geological and hydrological characteristics, habitat features, and human activities. Existing and potential beneficial use impairment problems in the watershed fall into two major categories: human health risk and natural habitat degradation. The former are issues primarily associated with recreational uses of the Santa Monica Bay. The latter are issues associated with terrestrial, aquatic, and marine environments. Pollutant loadings that originate from human activities are common causes of both human health risks and habitat degradation.
40
 
41
+ # Suspended Particulate Matter
42
 
43
+ The Santa Monica Bay, California, and the Gironde Estuary and Bourgneuf Bay in France have some similarities but also significant differences. Here are some key points to consider:
44
 
45
+ Size and Geography: The Santa Monica Bay is a bight of the Pacific Ocean, while the Gironde Estuary and Bourgneuf Bay are estuaries, which are partially enclosed coastal bodies of water where freshwater from rivers and streams meets and mixes with saltwater from the ocean. The Gironde Estuary is formed by the confluence of the Garonne and Dordogne Rivers, and the Loire River feeds into Bourgneuf Bay. The Santa Monica Bay, on the other hand, is fed by several smaller watersheds, including Malibu Creek and Ballona Creek.
46
 
47
+ Turbidity and SPM Concentration: The Gironde Estuary and Bourgneuf Bay are characterized by high Suspended Particulate Matter (SPM) concentrations, ranging from 1 to 3000 m−3 in the Gironde and 50 to over 1000 g·m−3 in Bourgneuf Bay. The Santa Monica Bay, according to the information found, has a lower SPM concentration, with a median value of 1.3 mg/L (or approximately 0.0013 g·m−3), which is significantly lower than the French sites.
48
 
49
+ Tidal Range: Both the Gironde Estuary and Bourgneuf Bay have a macro-tidal regime, with tidal ranges from 2 to 5 m and 2 to 6 m, respectively. The tidal range in the Santa Monica Bay is not explicitly stated in the sources found, but the Pacific coast of Southern California typically experiences a smaller tidal range, usually less than 2 meters.
50
 
51
+ Freshwater Inputs: The Gironde Estuary and Bourgneuf Bay have significant freshwater inputs from large rivers, with flow rates ranging from less than 100 m3·s−1 to more than 4000 m3·s−1. The Santa Monica Bay receives freshwater inputs from several smaller watersheds, but the flow rates are likely much lower than those of the French sites.
52
 
 
53
 
54
+ The Santa Monica Bay, California, and the Gironde Estuary and Bourgneuf Bay in France have some similarities but also significant differences. Here are some key points to consider:
55
 
56
+ Size and Geography: The Santa Monica Bay is a bight of the Pacific Ocean, while the Gironde Estuary and Bourgneuf Bay are estuaries, which are partially enclosed coastal bodies of water where freshwater from rivers and streams meets and mixes with saltwater from the ocean. The Gironde Estuary is formed by the confluence of the Garonne and Dordogne rivers, and the Loire River feeds into Bourgneuf Bay. The Santa Monica Bay, on the other hand, is fed by several smaller watersheds, including Malibu Creek and Ballona Creek.
57
 
58
+ Turbidity and SPM Concentration: The Gironde Estuary and Bourgneuf Bay are characterized by high Suspended Particulate Matter (SPM) concentrations, ranging from 1 to 3000 m−3 in the Gironde and 50 to over 1000 g·m−3 in Bourgneuf Bay. The Santa Monica Bay, according to the information found, has a lower SPM concentration, with a median value of 1.3 mg/L (or approximately 0.0013 g·m−3), which is significantly lower than the French sites.
59
 
60
+ Tidal Range: Both the Gironde Estuary and Bourgneuf Bay have a macro-tidal regime, with tidal ranges from 2 to 5 m and 2 to 6 m, respectively. The tidal range in the Santa Monica Bay is not explicitly stated in the sources found, but the Pacific coast of Southern California typically experiences a smaller tidal range, usually less than 2 meters.
61
 
62
+ In conclusion, while there are some similarities in terms of being coastal water bodies with freshwater inputs, the Gironde Estuary and Bourgneuf Bay in France appear to be significantly more turbid and have higher SPM concentrations than the Santa Monica Bay.
63
 
64
+ Freshwater Inputs: The Gironde Estuary and Bourgneuf Bay have significant freshwater inputs from large rivers, with flow rates ranging from less than 100 m3·s−1 to more than 4000 m3·s−1. The Santa Monica Bay receives freshwater inputs from several smaller watersheds, but the flow rates are likely much lower than those of the French sites.
65
 
66
+ In conclusion, while there are some similarities in terms of being coastal water bodies with freshwater inputs, the Gironde Estuary and Bourgneuf Bay in France appear to be significantly more turbid and have higher SPM concentrations than the Santa Monica Bay. Therefore, the models developed for the French sites may not be directly applicable to the Santa Monica Bay without some adjustments or recalibrations.
 
67
 
68
+ # References
69
+ Trinh, R. C., Fichot, C. G., Gierach, M. M., Holt, B., Malakar, N. K., Hulley, G., & Smith, J. (2017). Application of Landsat 8 for Monitoring Impacts of Wastewater Discharge on Coastal Water Quality. Frontiers in Marine Science, 4. https://doi.org/10.3389/fmars.2017.00329
70
+
71
+ Novoa S, Doxaran D, Ody A, Vanhellemont Q, Lafon V, Lubac B, Gernez P. Atmospheric Corrections and Multi-Conditional Algorithm for Multi-Sensor Remote Sensing of Suspended Particulate Matter in Low-to-High Turbidity Levels Coastal Waters. Remote Sensing. 2017; 9(1):61. https://doi.org/10.3390/rs9010061
72
+
73
+ Quinten Vanhellemont. Automated Water Surface Temperature Retrieval from Landsat 8/TIRS. Feb. 2020, pp. 111518–18, https://doi.org/10.1016/j.rse.2019.111518. Accessed 17 July 2023.
74
+
75
+ Ansari, Mohsen, and M. Akhoondzadeh. Mapping Water Salinity Using Landsat-8 OLI Satellite Images (Case Study: Karun Basin Located in Iran). no. 5, Mar. 2020, pp. 1490–502, https://doi.org/10.1016/j.asr.2019.12.007. Accessed 17 July 2023.
76
+
77
+ ‌Landsat-8 imagery courtesy of the U.S. Geological Survey
78
+ """
79
 
80
  solara.Markdown(markdown)
public/functions.py CHANGED
@@ -158,17 +158,8 @@ class ImageFunctions:
158
  image = image.addBands(SST_B10_Celsius.rename('SST_B10_Celsius'))
159
 
160
  return image
161
-
162
-
163
- '''def calculate_sst(self, image):
164
- # Constants from Table 1
165
- K1_B10 = 774.8853
166
- K2_B10 = 1321.0789
167
- epsilon_B10 = 0.9926
168
- K1_B11 = 480.8883
169
- K2_B11 = 1201.1442
170
- epsilon_B11 = 0.9877
171
-
172
  # extract the cloud and water masks
173
  qa_band = ee.Image(image).select('QA_PIXEL')
174
  cloudMask = self.extract_qa_bits(qa_band, 8, 9, "cloud").neq(3) # different than 3 to remove clouds
@@ -176,67 +167,32 @@ class ImageFunctions:
176
 
177
  # apply the masks to the image
178
  image = image.updateMask(cloudMask).updateMask(waterMask)
179
- image = image.multiply(10) # Scale factor for Landsat 8 TOA Reflectance
180
 
181
- # Extract the bands
182
- B10 = image.select('B10')
183
- B11 = image.select('B11')
 
184
 
 
 
 
 
 
 
 
 
 
 
 
 
185
 
186
- # Calculate the surface emitted radiance (Ls) for Bands 10 and 11
187
- Ls_B10 = image.expression(
188
- "B10 / (1 + (B10 / K2_B10) * log(epsilon_B10))",
189
- {
190
- 'B10': B10,
191
- 'K2_B10': K2_B10,
192
- 'epsilon_B10': epsilon_B10
193
- }
194
- )
195
- Ls_B11 = image.expression(
196
- "B11 / (1 + (B11 / K2_B11) * log(epsilon_B11))",
197
- { 'B11': B11,
198
- 'K2_B11': K2_B11,
199
- 'epsilon_B11': epsilon_B11}
200
- )
201
-
202
- # Calculate the atmospheric transmittance (tau)
203
- tau = image.expression(
204
- "(B10 - B11) / (Ls_B10 - Ls_B11)",
205
- {'B10': B10, 'B11': B11, 'Ls_B10': Ls_B10, 'Ls_B11': Ls_B11}
206
- )
207
-
208
- # Calculate the upwelled radiance (Lu) for Band 10
209
- Lu_B10 = image.expression(
210
- "B10 - tau * Ls_B10",
211
- {'B10': B10, 'tau': tau, 'Ls_B10': Ls_B10}
212
- )
213
-
214
- # Calculate the downwelled radiance (Ld) for Band 10
215
- Ld_B10 = image.expression(
216
- "(B10 - Lu_B10) / (tau * (1 - epsilon_B10))",
217
- {'B10': B10, 'Lu_B10': Lu_B10, 'tau': tau,'epsilon_B10': epsilon_B10}
218
- )
219
-
220
-
221
- # Define the expression for calculating SST
222
- expression = (
223
- )
224
 
225
- # Calculate SST using the expression
226
- SST_B10_Celsius = image.expression("K2_B10 / log(K1_B10 / ((B10 - Lu_B10 - tau * Ld_B10) / (tau * epsilon_B10)) + 1) - 273.15",
227
- {'K2_B10': K2_B10,
228
- 'K1_B10': K1_B10,
229
- 'B10': B10,
230
- 'Lu_B10': Lu_B10,
231
- 'tau': tau,
232
- 'Ld_B10': Ld_B10,
233
- 'epsilon_B10': epsilon_B10
234
- }
235
- )
236
 
237
- # Add the SST_B10_Celsius band to the image
238
- image = image.addBands(SST_B10_Celsius.select([0], ['SST_B10_Celsius']))
239
- return image'''
240
 
241
 
242
 
 
158
  image = image.addBands(SST_B10_Celsius.rename('SST_B10_Celsius'))
159
 
160
  return image
161
+
162
+ def ansari_akhoondzadeh_salinity(self, image):
 
 
 
 
 
 
 
 
 
163
  # extract the cloud and water masks
164
  qa_band = ee.Image(image).select('QA_PIXEL')
165
  cloudMask = self.extract_qa_bits(qa_band, 8, 9, "cloud").neq(3) # different than 3 to remove clouds
 
167
 
168
  # apply the masks to the image
169
  image = image.updateMask(cloudMask).updateMask(waterMask)
170
+ image = self.apply_scale_factors(image)
171
 
172
+ a_0 = 570.80
173
+ a_1 = 26535.17
174
+ a_2 = -62141.71
175
+ a_3 = 34952.89
176
 
177
+ coastal_aerosol = image.select('SR_B1')
178
+ blue_bands = image.select('SR_B2')
179
+ green_bands = image.select('SR_B3')
180
+ salinity = image.expression("a_0 + (a_1 *coastal_aerosol) + (a_2 * blue_bands) + (a_3 * green_bands)", {
181
+ 'a_0': a_0,
182
+ 'a_1': a_1,
183
+ 'a_2': a_2,
184
+ 'a_3': a_3,
185
+ 'coastal_aerosol': coastal_aerosol,
186
+ 'blue_bands': blue_bands,
187
+ 'green_bands': green_bands
188
+ })
189
 
190
+ image = image.addBands(salinity.select([0], ['salinity']))
191
+
192
+
193
+ return image
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
 
 
 
 
 
 
 
 
 
 
 
 
195
 
 
 
 
196
 
197
 
198
 
public/load_process.py CHANGED
@@ -39,7 +39,7 @@ class ImageProcess:
39
 
40
  # Loop through the dates and get the imagery
41
  for date in dates:
42
- print(f'Processing image for date {date}')
43
  start_date = ee.Date(date)
44
  end_date = start_date.advance(1, 'day')
45
 
@@ -50,7 +50,7 @@ class ImageProcess:
50
  .first() # get the first image that matches the filters
51
 
52
  if image: # check if image exists
53
- print(f'Image found for true color {date}')
54
  optical_bands = image.select('SR_B.*').multiply(0.0000275).add(-0.2)
55
  clipped_image = optical_bands.clip(aoi) # Clip the image to the study boundary
56
  map_instance.addLayer(clipped_image, vis_params, date, shown = True) # add the image to the map
@@ -62,7 +62,7 @@ class ImageProcess:
62
 
63
  def load_and_process_chla(self, map_instance, shapefile_path):
64
  # Load the study area
65
- print('Loading study boundary')
66
  study_boundary = gpd.read_file(shapefile_path)
67
  ee_boundary = geemap.geopandas_to_ee(study_boundary)
68
  aoi = ee_boundary.geometry()
@@ -112,7 +112,7 @@ class ImageProcess:
112
 
113
  # Loop through the dates and get the imagery
114
  for date in dates:
115
- print(f'Processing image for date {date}')
116
  start_date = ee.Date(date)
117
  end_date = start_date.advance(1, 'day')
118
 
@@ -123,7 +123,7 @@ class ImageProcess:
123
  .first() # get the first image that matches the filters
124
 
125
  if image: # check if image exists
126
- print(f'Image found for Chla {date}')
127
  clipped_image = image.clip(aoi) # Clip the image to the study boundary
128
  processed_image = map_instance.image_functions.trinh_et_al_chl_a(clipped_image) # process the image
129
  map_instance.addLayer(processed_image, chloro_params, date, shown = True) # add the image to the map
@@ -132,7 +132,7 @@ class ImageProcess:
132
  print(f"No image found for date {date}")
133
 
134
  # Set the map to focus on the study area
135
- print('Setting focus on study area')
136
  map_instance.add_colorbar_branca(vis_params= chloro_params, colors = TURBO_PALETTE,vmin = 0, vmax = 3, label = 'mg/m³')
137
 
138
 
@@ -189,7 +189,7 @@ class ImageProcess:
189
  .first() # get the first image that matches the filters
190
 
191
  if image: # check if image exists
192
- print(f'Image found for SPM {date}')
193
  clipped_image = image.clip(aoi) # Clip the image to the study boundary
194
  processed_image = map_instance.image_functions.novoa_et_al_spm(clipped_image) # process the image
195
  map_instance.addLayer(processed_image, spm_params, date, shown = True) # add the image to the map
@@ -203,7 +203,7 @@ class ImageProcess:
203
 
204
  def load_and_process_sst(self, map_instance, shapefile_path):
205
  # Load the study area
206
- print('Loading study boundary')
207
  study_boundary = gpd.read_file(shapefile_path)
208
  ee_boundary = geemap.geopandas_to_ee(study_boundary)
209
  aoi = ee_boundary.geometry()
@@ -253,7 +253,7 @@ class ImageProcess:
253
 
254
  # Loop through the dates and get the imagery
255
  for date in dates:
256
- print(f'Processing image for date {date}')
257
  start_date = ee.Date(date)
258
  end_date = start_date.advance(1, 'day')
259
 
@@ -264,7 +264,6 @@ class ImageProcess:
264
  .first() # get the first image that matches the filters
265
 
266
  if image: # check if image exists
267
- print(f'Image found for sst {date}')
268
  clipped_image = image.clip(aoi) # Clip the image to the study boundary
269
  processed_image = map_instance.image_functions.calculate_sst(clipped_image) # process the image
270
  map_instance.addLayer(processed_image, sst_params, date, shown = True) # add the image to the map
@@ -273,5 +272,69 @@ class ImageProcess:
273
  print(f"No image found for date {date}")
274
 
275
  # Set the map to focus on the study area
276
- print('Setting focus on study area')
277
  map_instance.add_colorbar_branca(vis_params= sst_params, colors = TURBO_PALETTE,vmin = 13.5, vmax = 20, label = 'C')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  # Loop through the dates and get the imagery
41
  for date in dates:
42
+
43
  start_date = ee.Date(date)
44
  end_date = start_date.advance(1, 'day')
45
 
 
50
  .first() # get the first image that matches the filters
51
 
52
  if image: # check if image exists
53
+
54
  optical_bands = image.select('SR_B.*').multiply(0.0000275).add(-0.2)
55
  clipped_image = optical_bands.clip(aoi) # Clip the image to the study boundary
56
  map_instance.addLayer(clipped_image, vis_params, date, shown = True) # add the image to the map
 
62
 
63
  def load_and_process_chla(self, map_instance, shapefile_path):
64
  # Load the study area
65
+
66
  study_boundary = gpd.read_file(shapefile_path)
67
  ee_boundary = geemap.geopandas_to_ee(study_boundary)
68
  aoi = ee_boundary.geometry()
 
112
 
113
  # Loop through the dates and get the imagery
114
  for date in dates:
115
+
116
  start_date = ee.Date(date)
117
  end_date = start_date.advance(1, 'day')
118
 
 
123
  .first() # get the first image that matches the filters
124
 
125
  if image: # check if image exists
126
+
127
  clipped_image = image.clip(aoi) # Clip the image to the study boundary
128
  processed_image = map_instance.image_functions.trinh_et_al_chl_a(clipped_image) # process the image
129
  map_instance.addLayer(processed_image, chloro_params, date, shown = True) # add the image to the map
 
132
  print(f"No image found for date {date}")
133
 
134
  # Set the map to focus on the study area
135
+
136
  map_instance.add_colorbar_branca(vis_params= chloro_params, colors = TURBO_PALETTE,vmin = 0, vmax = 3, label = 'mg/m³')
137
 
138
 
 
189
  .first() # get the first image that matches the filters
190
 
191
  if image: # check if image exists
192
+
193
  clipped_image = image.clip(aoi) # Clip the image to the study boundary
194
  processed_image = map_instance.image_functions.novoa_et_al_spm(clipped_image) # process the image
195
  map_instance.addLayer(processed_image, spm_params, date, shown = True) # add the image to the map
 
203
 
204
  def load_and_process_sst(self, map_instance, shapefile_path):
205
  # Load the study area
206
+
207
  study_boundary = gpd.read_file(shapefile_path)
208
  ee_boundary = geemap.geopandas_to_ee(study_boundary)
209
  aoi = ee_boundary.geometry()
 
253
 
254
  # Loop through the dates and get the imagery
255
  for date in dates:
256
+
257
  start_date = ee.Date(date)
258
  end_date = start_date.advance(1, 'day')
259
 
 
264
  .first() # get the first image that matches the filters
265
 
266
  if image: # check if image exists
 
267
  clipped_image = image.clip(aoi) # Clip the image to the study boundary
268
  processed_image = map_instance.image_functions.calculate_sst(clipped_image) # process the image
269
  map_instance.addLayer(processed_image, sst_params, date, shown = True) # add the image to the map
 
272
  print(f"No image found for date {date}")
273
 
274
  # Set the map to focus on the study area
275
+
276
  map_instance.add_colorbar_branca(vis_params= sst_params, colors = TURBO_PALETTE,vmin = 13.5, vmax = 20, label = 'C')
277
+
278
+
279
+ def load_and_process_salinity(self, map_instance, shapefile_path):
280
+ # Load the study area
281
+
282
+ study_boundary = gpd.read_file(shapefile_path)
283
+ ee_boundary = geemap.geopandas_to_ee(study_boundary)
284
+ aoi = ee_boundary.geometry()
285
+ VIRIDIS_PALETTE = [
286
+ '440154', '440256', '450457', '450559', '46075a', '46085c', '460a5d', '460b5e', '470d60',
287
+ '470e61', '471063', '471164', '471365', '481467', '481668', '481769', '48186a', '481a6c',
288
+ '481b6d', '481c6e', '481d6f', '481f70', '482071', '482173', '482374', '482475', '482576',
289
+ '482677', '482878', '482979', '472a7a', '472c7a', '472d7b', '472e7c', '472f7d', '46307e',
290
+ '46327e', '46337f', '463480', '453581', '453781', '453882', '443983', '443a83', '443b84',
291
+ '433d84', '433e85', '423f85', '424086', '424186', '414287', '414487', '404588', '404688',
292
+ '3f4788', '3f4889', '3e4989', '3e4a89', '3e4c8a', '3d4d8a', '3d4e8a', '3c4f8a', '3c508b',
293
+ '3b518b', '3b528b', '3a538b', '3a548c', '39558c', '39568c', '38588c', '38598c', '375a8c',
294
+ '375b8d', '365c8d', '365d8d', '355e8d', '355f8d', '34608d', '34618d', '33628d', '33638d',
295
+ '32648e', '32658e', '31668e', '31678e', '30688e', '30698e', '2f6a8e', '2f6b8e', '2e6c8e',
296
+ '2e6d8e', '2d6e8e', '2d6f8e', '2c708e', '2c718e', '2b728e', '2b738e', '2a748e', '2a758e',
297
+ '29768e', '29778e', '28788e', '28798e', '277a8e', '277b8e', '267c8e', '267d8e', '257e8e',
298
+ '257f8e', '24808e', '24818e', '23828e', '23828e', '22838e', '22848e', '21858e', '21868e',
299
+ '20878e', '20888e', '1f898e', '1f8a8d', '1e8b8d', '1e8c8d', '1d8d8d', '1d8e8d', '1c8f8d',
300
+ '1c8f8d', '1b908c', '1b918c', '1a928c', '1a938b', '19948b', '19958b', '18968a', '18978a',
301
+ '17988a', '179989', '169a89', '169b88', '159c88', '159d87', '149e87', '149f86', '13a086',
302
+ '13a185', '12a285', '12a384', '11a483', '11a583', '10a682', '10a781', '0fa881', '0fa980',
303
+ '0eaa7f', '0eab7e', '0dac7e', '0dad7d', '0cae7c', '0caf7b', '0bb07a', '0bb179', '0ab278',
304
+ '0ab377', '09b476', '09b575', '08b674', '08b773', '07b872', '07b971', '06ba70', '06bb6f',
305
+ '05bc6e', '05bd6d', '04be6c', '04bf6b', '03c06a', '03c169', '02c268', '02c367', '01c466',
306
+ '01c565', '00c664']
307
+
308
+ salinity_params= {
309
+ 'bands': ['salinity'],
310
+ 'min': 0,
311
+ 'max': 1000,
312
+ 'palette': VIRIDIS_PALETTE
313
+ }
314
+ dates = ['2021-11-11', '2021-10-26','2021-10-10', '2021-08-07','2021-07-22', '2021-07-06' ]
315
+
316
+ processed_collection = ee.ImageCollection([])
317
+
318
+ # Loop through the dates and get the imagery
319
+ for date in dates:
320
+
321
+ start_date = ee.Date(date)
322
+ end_date = start_date.advance(1, 'day')
323
+
324
+ # Filter the image collection by date and area
325
+ image = ee.ImageCollection("LANDSAT/LC08/C02/T1_L2") \
326
+ .filterDate(start_date, end_date) \
327
+ .filterBounds(ee_boundary) \
328
+ .first() # get the first image that matches the filters
329
+
330
+ if image: # check if image exists
331
+
332
+ clipped_image = image.clip(aoi) # Clip the image to the study boundary
333
+ processed_image = map_instance.image_functions.ansari_akhoondzadeh_salinity(clipped_image) # process the image
334
+ map_instance.addLayer(processed_image, salinity_params, date, shown = True) # add the image to the map
335
+ processed_collection = processed_collection.merge(processed_image) # add the image to the processed collection
336
+ else:
337
+ print(f"No image found for date {date}")
338
+
339
+ # Set the map to focus on the study area
340
+ map_instance.add_colorbar_branca(vis_params= salinity_params, colors = VIRIDIS_PALETTE,vmin = 0, vmax = 1000, label = 'EC')