diff --git a/CHANGELOG.md b/CHANGELOG.md index 0253fe6d..7dd907ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ * Add new "Geology/Mineral occurrences" layer from GEUS. * Update `layer_list.csv` to include new column indicating if each layer is stored on disk. Internet-required layers take the value `False`. +* Add new "Glaciology/Ice sheet velocity" layers: + * "GrIMP/Annual ice sheet velocity vectors 2021" + * "GrIMP/Annual ice sheet velocity magnitude 2021 (200m)" + * "GrIMP/Annual ice sheet velocity x component 2021 (200m)" + * "GrIMP/Annual ice sheet velocity y component 2021 (200m)" # v3.0.0alpha4 (2023-07-21) diff --git a/qgreenland/ancillary/styles/grimp_vectors.qml b/qgreenland/ancillary/styles/grimp_vectors.qml new file mode 100644 index 00000000..e064bc83 --- /dev/null +++ b/qgreenland/ancillary/styles/grimp_vectors.qml @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 1 + 0 + diff --git a/qgreenland/ancillary/styles/grimp_velocity_component.qml b/qgreenland/ancillary/styles/grimp_velocity_component.qml new file mode 100644 index 00000000..76cd0f75 --- /dev/null +++ b/qgreenland/ancillary/styles/grimp_velocity_component.qml @@ -0,0 +1,177 @@ + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MinMax + WholeRaster + Exact + 0.02 + 0.98 + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + resamplingFilter + + 0 + diff --git a/qgreenland/ancillary/styles/grimp_velocity_magnitude.qml b/qgreenland/ancillary/styles/grimp_velocity_magnitude.qml new file mode 100644 index 00000000..a30e25da --- /dev/null +++ b/qgreenland/ancillary/styles/grimp_velocity_magnitude.qml @@ -0,0 +1,175 @@ + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MinMax + WholeRaster + Exact + 0.02 + 0.98 + 2 + + + + + + + + + + + + + + + + + + + + + + + resamplingFilter + + 0 + diff --git a/qgreenland/config/cfg-lock.json b/qgreenland/config/cfg-lock.json index 19207929..af8358dd 100644 --- a/qgreenland/config/cfg-lock.json +++ b/qgreenland/config/cfg-lock.json @@ -816,6 +816,24 @@ "title": "Greenland Territorial Waters" } }, + "grimp_annual_ice_velocity": { + "assets": { + "only": { + "collection_concept_id": "C2386646586-NSIDC_ECS", + "granule_ur": "SC:NSIDC-0725.004:243900064", + "id": "only" + } + }, + "id": "grimp_annual_ice_velocity", + "metadata": { + "abstract": "This data set, part of the NASA Making Earth System Data Records for Use in\nResearch Environments (MEaSUREs) program, contains annual ice velocity mosaics\nfor the Greenland Ice Sheet derived from Synthetic Aperture Radar (SAR) data\nobtained by the German Space Agency's TerraSAR-X/TanDEM-X (TSX/TDX) and the\nEuropean Space Agency's Copernicus Sentinel-1A and -1B satellites, and from the\nUS Geological Survey's Landsat 8 optical imagery for years 2015 to 2021. See\nGreenland Ice Mapping Project (GrIMP) website for related data:\nhttp://nsidc.org/data/measures/gimp.", + "citation": { + "text": "Joughin, I. (2022). MEaSUREs Greenland Annual Ice Sheet Velocity Mosaics from\nSAR and Landsat, Version 4 [Data Set]. Boulder, Colorado USA. NASA National Snow\nand Ice Data Center Distributed Active Archive\nCenter. https://doi.org/10.5067/RS8GFZ848ZU9. {{date_accessed}}", + "url": "https://doi.org/10.5067/RS8GFZ848ZU9" + }, + "title": "MEaSUREs Greenland Annual Ice Sheet Velocity Mosaics from SAR and Landsat, Version 4" + } + }, "gshhg_coastlines": { "assets": { "only": { @@ -12045,6 +12063,350 @@ }, { "children": [ + { + "children": [ + { + "layer_cfg": { + "description": "Vector representation of ice sheet velocity in meters per year for 2021.", + "id": "grimp_annual_vectors_2021", + "in_package": true, + "input": { + "asset": { + "id": "only" + }, + "dataset": { + "id": "grimp_annual_ice_velocity" + } + }, + "show": false, + "steps": [ + { + "args": [ + "gdal_merge.py", + "-a_nodata", + "-2e+09", + "-separate", + "-o", + "{output_dir}/merged.tif", + "{input_dir}/*vx*.tif", + "{input_dir}/*vy*.tif" + ], + "type": "command" + }, + { + "args": [ + "gdalwarp", + "-tr", + "1500 1500", + "{input_dir}/merged.tif", + "{output_dir}/downsampled.tif" + ], + "type": "command" + }, + { + "args": [ + "gdal2xyz.py", + "-skipnodata", + "-csv", + "-allbands", + "{input_dir}/downsampled.tif", + "{output_dir}/data_with_header.csv", + "&&", + "sed -i '1s/^/x,y,vx,vy\n/' {output_dir}/data_with_header.csv" + ], + "type": "command" + }, + { + "args": [ + "ogr2ogr", + "-lco", + "ENCODING=UTF-8", + "-t_srs", + "EPSG:3413", + "-clipdst", + "{assets_dir}/latitude_shape_40_degrees.geojson", + "-makevalid", + "-oo", + "X_POSSIBLE_NAMES=x", + "-oo", + "Y_POSSIBLE_NAMES=y", + "-s_srs", + "EPSG:3413", + "-oo", + "KEEP_GEOM_COLUMNS=NO", + "-oo", + "AUTODETECT_TYPE=YES", + "{output_dir}/vectors.gpkg", + "CSV:{input_dir}/data_with_header.csv" + ], + "type": "command" + } + ], + "style": "grimp_vectors", + "tags": [], + "title": "Annual ice sheet velocity vectors 2021 (1.5km)" + }, + "name": "grimp_annual_vectors_2021" + }, + { + "layer_cfg": { + "description": "Ice sheet velocity magnitude (vv) in meters per year for 2021.\nAnnual mosaics are produced from data with resolutions varying from a few\nhundred meters to 1.5km. The 2021 annual mosaic includes data collected between\n2020-12-01 and 2021-11-30.\n\nNote that these data have been rounded to the nearest centimeter for QGreenland\nto save disk space. Please see the original data source for the un-modified and\nadditional data:\n\n* x and y component velocity error estimates (ex, ey).\n* A temporal offset parameter (dT) that reports the difference in days between\n the date of each velocity estimate and the midpoint date of the corresponding\n measurement period.\n* Shapefile that indicates the source of the image pairs (SAR or Landsat 8) used\n to produce the mosaic.", + "id": "grimp_annual_vv_2021", + "in_package": true, + "input": { + "asset": { + "id": "only" + }, + "dataset": { + "id": "grimp_annual_ice_velocity" + } + }, + "show": false, + "steps": [ + { + "args": [ + "gdal_calc.py", + "--calc", + "\"round(A * 100.0)\"", + "--NoDataValue", + "-9999", + "--type", + "Int32", + "-A", + "{input_dir}/*vv*.tif", + "--outfile", + "{output_dir}/scaled.tif" + ], + "type": "command" + }, + { + "args": [ + "cp", + "{input_dir}/scaled.tif", + "{output_dir}/edited.tif", + "&&", + "gdal_edit.py", + "-scale", + "0.01", + "{output_dir}/edited.tif" + ], + "type": "command" + }, + { + "args": [ + "gdal_translate", + "-co", + "TILED=YES", + "-co", + "COMPRESS=DEFLATE", + "-co", + "PREDICTOR=2", + "{input_dir}/edited.tif", + "{output_dir}/compressed.tif" + ], + "type": "command" + }, + { + "args": [ + "cp", + "{input_dir}/compressed.tif", + "{output_dir}/compressed_with_overviews.tif", + "&&", + "gdaladdo", + "-r", + "average", + "{output_dir}/compressed_with_overviews.tif", + "2", + "4", + "8", + "16" + ], + "type": "command" + } + ], + "style": "grimp_velocity_magnitude", + "tags": [], + "title": "Annual ice sheet velocity magnitude 2021 (200m)" + }, + "name": "grimp_annual_vv_2021" + }, + { + "layer_cfg": { + "description": "Ice sheet velocity x component (vy) in meters per year for 2021.\nAnnual mosaics are produced from data with resolutions varying from a few\nhundred meters to 1.5km. The 2021 annual mosaic includes data collected between\n2020-12-01 and 2021-11-30.\n\nNote that these data have been rounded to the nearest centimeter for QGreenland\nto save disk space. Please see the original data source for the un-modified and\nadditional data:\n\n* x and y component velocity error estimates (ex, ey).\n* A temporal offset parameter (dT) that reports the difference in days between\n the date of each velocity estimate and the midpoint date of the corresponding\n measurement period.\n* Shapefile that indicates the source of the image pairs (SAR or Landsat 8) used\n to produce the mosaic.", + "id": "grimp_annual_vx_2021", + "in_package": true, + "input": { + "asset": { + "id": "only" + }, + "dataset": { + "id": "grimp_annual_ice_velocity" + } + }, + "show": false, + "steps": [ + { + "args": [ + "gdal_calc.py", + "--calc", + "\"round(A * 100.0)\"", + "--NoDataValue", + "-9999", + "--type", + "Int32", + "-A", + "{input_dir}/*vx*.tif", + "--outfile", + "{output_dir}/scaled.tif" + ], + "type": "command" + }, + { + "args": [ + "cp", + "{input_dir}/scaled.tif", + "{output_dir}/edited.tif", + "&&", + "gdal_edit.py", + "-scale", + "0.01", + "{output_dir}/edited.tif" + ], + "type": "command" + }, + { + "args": [ + "gdal_translate", + "-co", + "TILED=YES", + "-co", + "COMPRESS=DEFLATE", + "-co", + "PREDICTOR=2", + "{input_dir}/edited.tif", + "{output_dir}/compressed.tif" + ], + "type": "command" + }, + { + "args": [ + "cp", + "{input_dir}/compressed.tif", + "{output_dir}/compressed_with_overviews.tif", + "&&", + "gdaladdo", + "-r", + "average", + "{output_dir}/compressed_with_overviews.tif", + "2", + "4", + "8", + "16" + ], + "type": "command" + } + ], + "style": "grimp_velocity_component", + "tags": [], + "title": "Annual ice sheet velocity x component 2021 (200m)" + }, + "name": "grimp_annual_vx_2021" + }, + { + "layer_cfg": { + "description": "Ice sheet velocity y component (vy) in meters per year for 2021.\nAnnual mosaics are produced from data with resolutions varying from a few\nhundred meters to 1.5km. The 2021 annual mosaic includes data collected between\n2020-12-01 and 2021-11-30.\n\nNote that these data have been rounded to the nearest centimeter for QGreenland\nto save disk space. Please see the original data source for the un-modified and\nadditional data:\n\n* x and y component velocity error estimates (ex, ey).\n* A temporal offset parameter (dT) that reports the difference in days between\n the date of each velocity estimate and the midpoint date of the corresponding\n measurement period.\n* Shapefile that indicates the source of the image pairs (SAR or Landsat 8) used\n to produce the mosaic.", + "id": "grimp_annual_vy_2021", + "in_package": true, + "input": { + "asset": { + "id": "only" + }, + "dataset": { + "id": "grimp_annual_ice_velocity" + } + }, + "show": false, + "steps": [ + { + "args": [ + "gdal_calc.py", + "--calc", + "\"round(A * 100.0)\"", + "--NoDataValue", + "-9999", + "--type", + "Int32", + "-A", + "{input_dir}/*vy*.tif", + "--outfile", + "{output_dir}/scaled.tif" + ], + "type": "command" + }, + { + "args": [ + "cp", + "{input_dir}/scaled.tif", + "{output_dir}/edited.tif", + "&&", + "gdal_edit.py", + "-scale", + "0.01", + "{output_dir}/edited.tif" + ], + "type": "command" + }, + { + "args": [ + "gdal_translate", + "-co", + "TILED=YES", + "-co", + "COMPRESS=DEFLATE", + "-co", + "PREDICTOR=2", + "{input_dir}/edited.tif", + "{output_dir}/compressed.tif" + ], + "type": "command" + }, + { + "args": [ + "cp", + "{input_dir}/compressed.tif", + "{output_dir}/compressed_with_overviews.tif", + "&&", + "gdaladdo", + "-r", + "average", + "{output_dir}/compressed_with_overviews.tif", + "2", + "4", + "8", + "16" + ], + "type": "command" + } + ], + "style": "grimp_velocity_component", + "tags": [], + "title": "Annual ice sheet velocity y component 2021 (200m)" + }, + "name": "grimp_annual_vy_2021" + } + ], + "name": "GrIMP", + "settings": { + "expand": false, + "order": [ + ":grimp_annual_vectors_2021", + ":grimp_annual_vv_2021", + ":grimp_annual_vx_2021", + ":grimp_annual_vy_2021" + ], + "show": false + } + }, { "children": [ { @@ -12508,6 +12870,7 @@ "settings": { "expand": false, "order": [ + "GrIMP", "ITS_LIVE", "ESA Climate Change Initiative" ], diff --git a/qgreenland/config/datasets/grimp.py b/qgreenland/config/datasets/grimp.py new file mode 100644 index 00000000..7e03883c --- /dev/null +++ b/qgreenland/config/datasets/grimp.py @@ -0,0 +1,36 @@ +from qgreenland.models.config.asset import CmrAsset +from qgreenland.models.config.dataset import Dataset + +grimp_annual_ice_velocity = Dataset( + id="grimp_annual_ice_velocity", + assets=[ + # GL_vel_mosaic_Annual_01Dec20_30Nov21_{variable}_v04.0.tif + CmrAsset( + id="only", + granule_ur="SC:NSIDC-0725.004:243900064", + collection_concept_id="C2386646586-NSIDC_ECS", + ), + ], + metadata={ + "title": "MEaSUREs Greenland Annual Ice Sheet Velocity Mosaics from SAR and Landsat, Version 4", + "abstract": """ +This data set, part of the NASA Making Earth System Data Records for Use in +Research Environments (MEaSUREs) program, contains annual ice velocity mosaics +for the Greenland Ice Sheet derived from Synthetic Aperture Radar (SAR) data +obtained by the German Space Agency's TerraSAR-X/TanDEM-X (TSX/TDX) and the +European Space Agency's Copernicus Sentinel-1A and -1B satellites, and from the +US Geological Survey's Landsat 8 optical imagery for years 2015 to 2021. See +Greenland Ice Mapping Project (GrIMP) website for related data: +http://nsidc.org/data/measures/gimp. +""", + "citation": { + "text": """ +Joughin, I. (2022). MEaSUREs Greenland Annual Ice Sheet Velocity Mosaics from +SAR and Landsat, Version 4 [Data Set]. Boulder, Colorado USA. NASA National Snow +and Ice Data Center Distributed Active Archive +Center. https://doi.org/10.5067/RS8GFZ848ZU9. {{date_accessed}} +""", + "url": "https://doi.org/10.5067/RS8GFZ848ZU9", + }, + }, +) diff --git a/qgreenland/config/layers/Glaciology/Ice sheet velocity/GrIMP/__settings__.py b/qgreenland/config/layers/Glaciology/Ice sheet velocity/GrIMP/__settings__.py new file mode 100644 index 00000000..2ed7f6bc --- /dev/null +++ b/qgreenland/config/layers/Glaciology/Ice sheet velocity/GrIMP/__settings__.py @@ -0,0 +1,13 @@ +from qgreenland.models.config.layer_group import ( + LayerGroupSettings, + LayerIdentifier, +) + +settings = LayerGroupSettings( + order=[ + LayerIdentifier("grimp_annual_vectors_2021"), + LayerIdentifier("grimp_annual_vv_2021"), + LayerIdentifier("grimp_annual_vx_2021"), + LayerIdentifier("grimp_annual_vy_2021"), + ], +) diff --git a/qgreenland/config/layers/Glaciology/Ice sheet velocity/GrIMP/grimp.py b/qgreenland/config/layers/Glaciology/Ice sheet velocity/GrIMP/grimp.py new file mode 100644 index 00000000..a98906ea --- /dev/null +++ b/qgreenland/config/layers/Glaciology/Ice sheet velocity/GrIMP/grimp.py @@ -0,0 +1,178 @@ +from qgreenland.config.datasets.grimp import grimp_annual_ice_velocity as annual_dataset +from qgreenland.config.helpers.steps.compress_and_add_overviews import ( + compress_and_add_overviews, +) +from qgreenland.config.helpers.steps.gdal_edit import gdal_edit +from qgreenland.config.helpers.steps.ogr2ogr import ogr2ogr +from qgreenland.models.config.layer import Layer, LayerInput +from qgreenland.models.config.step import CommandStep + + +def make_layer( + *, variable: str, layer_id: str, style: str, title: str, description: str +) -> Layer: + return Layer( + id=layer_id, + title=title, + description=description, + style=style, + input=LayerInput( + dataset=annual_dataset, + asset=annual_dataset.assets["only"], + ), + steps=[ + # Round data to the nearest cm and convert to integer to save disk + # space. + CommandStep( + args=[ + "gdal_calc.py", + "--calc", + '"round(A * 100.0)"', + "--NoDataValue", + "-9999", + "--type", + "Int32", + "-A", + "{input_dir}/" + f"*{variable}*.tif", + "--outfile", + "{output_dir}/scaled.tif", + ], + ), + # The `scale` metadata lets tools like QGIS know that the integers + # should be interpreted as floating point data (e.g,. a value of + # `12345` is displayed as 123.45) + *gdal_edit( + input_file="{input_dir}/scaled.tif", + output_file="{output_dir}/edited.tif", + gdal_edit_args=[ + "-scale", + "0.01", + ], + ), + *compress_and_add_overviews( + input_file="{input_dir}/edited.tif", + output_file="{output_dir}/compressed_with_overviews.tif", + dtype_is_float=False, + ), + ], + ) + + +_description_common = """ +Annual mosaics are produced from data with resolutions varying from a few +hundred meters to 1.5km. The 2021 annual mosaic includes data collected between +2020-12-01 and 2021-11-30. + +Note that these data have been rounded to the nearest centimeter for QGreenland +to save disk space. Please see the original data source for the un-modified and +additional data: + +* x and y component velocity error estimates (ex, ey). +* A temporal offset parameter (dT) that reports the difference in days between + the date of each velocity estimate and the midpoint date of the corresponding + measurement period. +* Shapefile that indicates the source of the image pairs (SAR or Landsat 8) used + to produce the mosaic. +""" + + +_layer_params = { + "vv": { + "description": "Ice sheet velocity magnitude (vv) in meters per year for 2021." + + _description_common, + "style": "grimp_velocity_magnitude", + "title": "Annual ice sheet velocity magnitude 2021 (200m)", + }, + "vx": { + "description": "Ice sheet velocity x component (vy) in meters per year for 2021." + + _description_common, + "style": "grimp_velocity_component", + "title": "Annual ice sheet velocity x component 2021 (200m)", + }, + "vy": { + "description": "Ice sheet velocity y component (vy) in meters per year for 2021." + + _description_common, + "style": "grimp_velocity_component", + "title": "Annual ice sheet velocity y component 2021 (200m)", + }, +} + +annual_grimp_layers = [ + make_layer( + variable=variable, + layer_id=f"grimp_annual_{variable}_2021", + style=layer_params["style"], + description=layer_params["description"], + title=layer_params["title"], + ) + for variable, layer_params in _layer_params.items() +] + +grimp_vector_layer = Layer( + id="grimp_annual_vectors_2021", + title="Annual ice sheet velocity vectors 2021 (1.5km)", + description=( + """Vector representation of ice sheet velocity in meters per year for 2021.""" + ), + style="grimp_vectors", + input=LayerInput( + dataset=annual_dataset, + asset=annual_dataset.assets["only"], + ), + steps=[ + # Now merge the variables into a 3-band .tif file. + CommandStep( + args=[ + "gdal_merge.py", + "-a_nodata", + "-2e+09", + "-separate", + "-o", + "{output_dir}/merged.tif", + "{input_dir}/*vx*.tif", + "{input_dir}/*vy*.tif", + ], + ), + # Downsample to 1.5km + CommandStep( + args=[ + "gdalwarp", + "-tr", + "1500 1500", + "{input_dir}/merged.tif", + "{output_dir}/downsampled.tif", + ], + ), + # Next, convert the .tif into a csv file. This converts the raster into + # a format readable by `ogr2ogr`, used in the next step. + CommandStep( + args=[ + "gdal2xyz.py", + "-skipnodata", + "-csv", + "-allbands", + "{input_dir}/downsampled.tif", + "{output_dir}/data_with_header.csv", + "&&", + "sed -i '1s/^/x,y,vx,vy\n/' {output_dir}/data_with_header.csv", + ], + ), + # Finally, convert to gpkg. + *ogr2ogr( + input_file="CSV:{input_dir}/data_with_header.csv", + output_file="{output_dir}/vectors.gpkg", + ogr2ogr_args=( + "-oo", + "X_POSSIBLE_NAMES=x", + "-oo", + "Y_POSSIBLE_NAMES=y", + "-s_srs", + "EPSG:3413", + "-oo", + "KEEP_GEOM_COLUMNS=NO", + "-oo", + "AUTODETECT_TYPE=YES", + ), + ), + ], +) diff --git a/qgreenland/config/layers/Glaciology/Ice sheet velocity/__settings__.py b/qgreenland/config/layers/Glaciology/Ice sheet velocity/__settings__.py index 567509b6..9b969af5 100644 --- a/qgreenland/config/layers/Glaciology/Ice sheet velocity/__settings__.py +++ b/qgreenland/config/layers/Glaciology/Ice sheet velocity/__settings__.py @@ -5,6 +5,7 @@ settings = LayerGroupSettings( order=[ + LayerGroupIdentifier("GrIMP"), LayerGroupIdentifier("ITS_LIVE"), LayerGroupIdentifier("ESA Climate Change Initiative"), ],