From 7b561ce4943b5976da590c839584d83c186aabf0 Mon Sep 17 00:00:00 2001 From: Sidney Gijzen Date: Sat, 15 Feb 2025 16:11:31 +0100 Subject: [PATCH 1/3] enforce WMS layer limit --- CHANGES.md | 1 + .../Catalog/Ows/WebMapServiceCapabilities.ts | 2 + .../Ows/WebMapServiceCapabilitiesStratum.ts | 7 + .../Catalog/Ows/WebMapServiceCatalogItem.ts | 26 +- .../Ows/WebMapServiceCatalogItemSpec.ts | 16 + wwwroot/test/WMS/colorscalerange.xml | 1 - wwwroot/test/WMS/ncwms2_service.xml | 1 - wwwroot/test/WMS/styles_and_dimensions.xml | 1 - wwwroot/test/WMS/wms_crs.xml | 1 - wwwroot/test/WMS/wms_nested_groups.xml | 1 - .../WMS/wms_nested_groups_layer_limited.xml | 652 ++++++++++++++++++ 11 files changed, 699 insertions(+), 10 deletions(-) create mode 100644 wwwroot/test/WMS/wms_nested_groups_layer_limited.xml diff --git a/CHANGES.md b/CHANGES.md index 5b432954508..673411c485f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ - Upgraded `sass` to version 1.80+ - Migrated SASS files to use `modern` API (by running the `sass-migrator` script) - Replaced webpack aliases `~terriajs-variables` and `~terriajs-mixins` with respective relative path. This was necessary to run the migrator. It also results in simpler webpack configuration. +- enforce the WMS layer limit - Remove `MapboxImageryProvider`, `createRegionMappedImageryProvider` now uses `ProtomapsImageryProvider`. - Update `protomaps` to `protomaps-leaflet`. This fixes the 5400 vertex limit in a single tile. - The very basic support of mvt style spec is now handled by Terria in [`lib/Map/Vector/mapboxStyleJsonToProtomaps.ts`](lib/Map/Vector/mapboxStyleJsonToProtomaps.ts) diff --git a/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts b/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts index 8b4e10ada75..8d2e292ad9c 100644 --- a/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts +++ b/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts @@ -97,6 +97,8 @@ export interface CapabilitiesService { readonly AccessConstraints?: string; /** List of keywords or keyword phrases to help catalog searching. */ readonly KeywordList?: OwsKeywordList; + /** The maximum amount of layers that can be requested. */ + readonly LayerLimit?: string; } /** diff --git a/lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts b/lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts index 3a828f9797d..ffcd3e664e7 100644 --- a/lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts +++ b/lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts @@ -110,6 +110,13 @@ export default class WebMapServiceCapabilitiesStratum extends LoadableStratum( ); } + @computed + get layerLimit() { + if (isDefined(this.capabilities?.Service?.LayerLimit)) { + return parseInt(this.capabilities?.Service?.LayerLimit); + } + } + @computed get layers(): string | undefined { let layers: string | undefined; diff --git a/lib/Models/Catalog/Ows/WebMapServiceCatalogItem.ts b/lib/Models/Catalog/Ows/WebMapServiceCatalogItem.ts index d832f7cb28b..8f3f13aa0da 100644 --- a/lib/Models/Catalog/Ows/WebMapServiceCatalogItem.ts +++ b/lib/Models/Catalog/Ows/WebMapServiceCatalogItem.ts @@ -245,15 +245,31 @@ class WebMapServiceCatalogItem return "0d"; } + @computed + get layerLimit() { + const gcStratum: WebMapServiceCapabilitiesStratum | undefined = + this.strata.get( + GetCapabilitiesMixin.getCapabilitiesStratumName + ) as WebMapServiceCapabilitiesStratum; + + return gcStratum?.layerLimit; + } + @computed get layersArray(): ReadonlyArray { - if (Array.isArray(this.layers)) { - return this.layers; - } else if (this.layers) { - return this.layers.split(","); + if (!this.layers) return []; + + let layers: string[]; + + if (!Array.isArray(this.layers)) { + layers = this.layers.split(","); } else { - return []; + layers = this.layers; } + + if (this.layerLimit) layers = layers.slice(0, this.layerLimit); + + return layers; } /** LAYERS which are valid (i.e. exist in GetCapabilities). diff --git a/test/Models/Catalog/Ows/WebMapServiceCatalogItemSpec.ts b/test/Models/Catalog/Ows/WebMapServiceCatalogItemSpec.ts index 7c5d7d68077..9539f8b8f43 100644 --- a/test/Models/Catalog/Ows/WebMapServiceCatalogItemSpec.ts +++ b/test/Models/Catalog/Ows/WebMapServiceCatalogItemSpec.ts @@ -617,6 +617,22 @@ describe("WebMapServiceCatalogItem", function () { expect(wms.validLayers).toEqual(["single_period"]); }); + it("enforces the layer limit", async function () { + const terria = new Terria(); + const wms = new WebMapServiceCatalogItem("test", terria); + runInAction(() => { + wms.setTrait( + "definition", + "url", + "test/WMS/wms_nested_groups_layer_limited.xml" + ); + }); + + await wms.loadMetadata(); + + expect(wms.validLayers).toEqual(["ls8_nbart_geomedian_annual"]); + }); + it("uses GetFeatureInfo from GetCapabilities", async function () { expect().nothing(); const terria = new Terria(); diff --git a/wwwroot/test/WMS/colorscalerange.xml b/wwwroot/test/WMS/colorscalerange.xml index 98a78150961..933ac4b1c6f 100644 --- a/wwwroot/test/WMS/colorscalerange.xml +++ b/wwwroot/test/WMS/colorscalerange.xml @@ -22,7 +22,6 @@ none none - 1 1024 1024 diff --git a/wwwroot/test/WMS/ncwms2_service.xml b/wwwroot/test/WMS/ncwms2_service.xml index 8b2c225cae5..db0466919f7 100644 --- a/wwwroot/test/WMS/ncwms2_service.xml +++ b/wwwroot/test/WMS/ncwms2_service.xml @@ -18,7 +18,6 @@ none none - 1 1024 1024 diff --git a/wwwroot/test/WMS/styles_and_dimensions.xml b/wwwroot/test/WMS/styles_and_dimensions.xml index 3d7fec90c1a..13a37e1d58a 100644 --- a/wwwroot/test/WMS/styles_and_dimensions.xml +++ b/wwwroot/test/WMS/styles_and_dimensions.xml @@ -25,7 +25,6 @@ none none - 1 2048 2048 diff --git a/wwwroot/test/WMS/wms_crs.xml b/wwwroot/test/WMS/wms_crs.xml index 804b8eedf92..409e6df6942 100644 --- a/wwwroot/test/WMS/wms_crs.xml +++ b/wwwroot/test/WMS/wms_crs.xml @@ -42,7 +42,6 @@ http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd"> none © Commonwealth of Australia (Geoscience Australia) 2018. This product is released under the Creative Commons Attribution 4.0 International Licence. http://creativecommons.org/licenses/by/4.0/legalcode - 1 512 512 diff --git a/wwwroot/test/WMS/wms_nested_groups.xml b/wwwroot/test/WMS/wms_nested_groups.xml index fc5852e1f94..ef1608064a9 100644 --- a/wwwroot/test/WMS/wms_nested_groups.xml +++ b/wwwroot/test/WMS/wms_nested_groups.xml @@ -42,7 +42,6 @@ http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd"> none © Commonwealth of Australia (Geoscience Australia) 2018. This product is released under the Creative Commons Attribution 4.0 International Licence. http://creativecommons.org/licenses/by/4.0/legalcode - 1 512 512 diff --git a/wwwroot/test/WMS/wms_nested_groups_layer_limited.xml b/wwwroot/test/WMS/wms_nested_groups_layer_limited.xml new file mode 100644 index 00000000000..fc5852e1f94 --- /dev/null +++ b/wwwroot/test/WMS/wms_nested_groups_layer_limited.xml @@ -0,0 +1,652 @@ + + + + + WMS + Digital Earth Australia - OGC Web Services + + Digital Earth Australia OGC Web Services + + + geomedian + WOfS + mangrove + bare-earth + NIDEM + HLTC + landsat + australia + time-series + fractional-cover + + + + + Digital Earth Australia + Geoscience Australia + + + postal +
GPO Box 378
+ Canberra + ACT + 2609 + Australia +
+ +61 2 6249 9111 + earth.observation@ga.gov.au +
+ none + © Commonwealth of Australia (Geoscience Australia) 2018. This product is released under the Creative Commons Attribution 4.0 International Licence. http://creativecommons.org/licenses/by/4.0/legalcode + 1 + 512 + 512 +
+ + + + text/xml + + + + + + + + + + image/png + + + + + + + + + + application/json + + + + + + + + + + + XML + + + Digital Earth Australia - OGC Web Services + + Digital Earth Australia OGC Web Services + + EPSG:3857 + EPSG:4326 + EPSG:3577 + EPSG:3111 + + 100 + 160 + -50 + -10 + + + Surface Reflectance + + + ls8_nbart_geomedian_annual + Surface Reflectance 25m Annual Geomedian (Landsat 8) + +Data is only visible at higher resolutions; when zoomed-out the available area will be displayed +as a shaded region. The surface reflectance geometric median (geomedian) is a pixel composite +mosaic of a time series of earth observations. The value of a pixel in a an annual geomedian +image is the statistical median of all observations for that pixel from a calendar year. +Annual mosaics are available for the following years:Landsat 8: 2013 to 2017;For more information, see http://pid.geoscience.gov.au/dataset/ga/120374For service status information, see https://status.dea.ga.gov.au + + + WOfS + HLTC + landsat + time-series + mangrove + bare-earth + australia + geomedian + NIDEM + fractional-cover + + + 109.989859933428 + 156.101505058599 + -45.2413329418709 + -9.02727104242042 + + + + + + + 2013-01-01,2014-01-01,2015-01-01,2016-01-01,2017-01-01,2018-01-01 + + + + + + + + + + + + + + + ls7_nbart_geomedian_annual + Surface Reflectance 25m Annual Geomedian (Landsat 7) + +Data is only visible at higher resolutions; when zoomed-out the available area will be displayed +as a shaded region. The surface reflectance geometric median (geomedian) is a pixel composite +mosaic of a time series of earth observations. The value of a pixel in a an annual geomedian +image is the statistical median of all observations for that pixel from a calendar year. +Annual mosaics are available for the following years:Landsat 7: 2000 to 2017;For more information, see http://pid.geoscience.gov.au/dataset/ga/120374For service status information, see https://status.dea.ga.gov.au + + + WOfS + HLTC + landsat + time-series + mangrove + bare-earth + australia + geomedian + NIDEM + fractional-cover + + + 109.989859933428 + 156.101505058599 + -45.2413329418709 + -9.02727104242042 + + + + + + + 2000-01-01,2001-01-01,2002-01-01,2003-01-01,2004-01-01,2005-01-01,2006-01-01,2007-01-01,2008-01-01,2009-01-01,2010-01-01,2011-01-01,2012-01-01,2013-01-01,2014-01-01,2015-01-01,2016-01-01,2017-01-01,2018-01-01 + + + + + + + + + + + + + + + ls5_nbart_geomedian_annual + Surface Reflectance 25m Annual Geomedian (Landsat 5) + +Data is only visible at higher resolutions; when zoomed-out the available area will be displayed +as a shaded region. The surface reflectance geometric median (geomedian) is a pixel composite +mosaic of a time series of earth observations. The value of a pixel in a an annual geomedian +image is the statistical median of all observations for that pixel from a calendar year. +Annual mosaics are available for the following years:Landsat 5: 1988 to 1999, 2004 to 2007, 2009 to 2011;For more information, see http://pid.geoscience.gov.au/dataset/ga/120374For service status information, see https://status.dea.ga.gov.au + + + WOfS + HLTC + landsat + time-series + mangrove + bare-earth + australia + geomedian + NIDEM + fractional-cover + + + 109.989859933428 + 156.101505058599 + -45.2413329418709 + -9.02727104242042 + + + + + + + 1988-01-01,1989-01-01,1990-01-01,1991-01-01,1992-01-01,1993-01-01,1994-01-01,1995-01-01,1996-01-01,1997-01-01,1998-01-01,1999-01-01,2004-01-01,2005-01-01,2006-01-01,2007-01-01,2009-01-01,2010-01-01,2011-01-01 + + + + + + + + + + + + + + + + Landsat-8 Barest Earth + + +A `weighted geometric median’ approach has been used to estimate the median surface reflectance of the barest state (i.e., least vegetation) observed through Landsat-8 OLI observations from 2013 to September 2018 to generate a six-band Landsat-8 Barest Earth pixel composite mosaic over the Australian continent.The bands include BLUE (0.452 - 0.512), GREEN (0.533 - 0.590), RED, (0.636 - 0.673) NIR (0.851 - 0.879), SWIR1 (1.566 - 1.651) and SWIR2 (2.107 - 2.294) wavelength regions. The weighted median approach is robust to outliers (such as cloud, shadows, saturation, corrupted pixels) and also maintains the relationship between all the spectral wavelengths in the spectra observed through time. The product reduces the influence of vegetation and allows for more direct mapping of soil and rock mineralogy.Reference: Dale Roberts, John Wilford, and Omar Ghattas (2018). Revealing the Australian Continent at its Barest, submitted.Mosaics are available for the following years: + Landsat 8: 2013 to 2017; + + + + ls8_barest_earth_mosaic + Landsat-8 Barest Earth 25m albers (Landsat-8) + +A `weighted geometric median’ approach has been used to estimate the median surface reflectance of the barest state (i.e., least vegetation) observed through Landsat-8 OLI observations from 2013 to September 2018 to generate a six-band Landsat-8 Barest Earth pixel composite mosaic over the Australian continent.The bands include BLUE (0.452 - 0.512), GREEN (0.533 - 0.590), RED, (0.636 - 0.673) NIR (0.851 - 0.879), SWIR1 (1.566 - 1.651) and SWIR2 (2.107 - 2.294) wavelength regions. The weighted median approach is robust to outliers (such as cloud, shadows, saturation, corrupted pixels) and also maintains the relationship between all the spectral wavelengths in the spectra observed through time. The product reduces the influence of vegetation and allows for more direct mapping of soil and rock mineralogy.Reference: Dale Roberts, John Wilford, and Omar Ghattas (2018). Revealing the Australian Continent at its Barest, submitted.Mosaics are available for the following years: + Landsat 8: 2013 to 2017;For service status information, see https://status.dea.ga.gov.au + + + WOfS + HLTC + landsat + time-series + mangrove + bare-earth + australia + geomedian + NIDEM + fractional-cover + + + 109.989859933428 + 156.101505058599 + -45.2413329418709 + -9.02727104242042 + + + + + + + + + + + + + + + + + + Landsat 30+ Barest Earth + + +An estimate of the spectra of the barest state (i.e., least vegetation) observed from imagery of the Australian continent collected by the Landsat 5, 7, and 8 satellites over a period of more than 30 years (1983 - 2018). The bands include BLUE (0.452 - 0.512), GREEN (0.533 - 0.590), RED, (0.636 - 0.673) NIR (0.851 - 0.879), SWIR1 (1.566 - 1.651) and SWIR2 (2.107 - 2.294) wavelength regions. The approach is robust to outliers (such as cloud, shadows, saturation, corrupted pixels) and also maintains the relationship between all the spectral wavelengths in the spectra observed through time. The product reduces the influence of vegetation and allows for more direct mapping of soil and rock mineralogy. This product complements the Landsat-8 Barest Earth which is based on the same algorithm but just uses Landsat8 satellite imagery from 2013-2108. Landsat-8's OLI sensor provides improved signal-to-noise radiometric (SNR) performance quantised over a 12-bit dynamic range compared to the 8-bit dynamic range of Landsat-5 and Landsat-7 data. However the Landsat 30+ Barest Earth has a greater capacity to find the barest ground due to the greater temporal depth. Reference: Roberts, D., Wilford, J., Ghattas, O. (2019). Exposed Soil and Mineral Map of the Australian Continent Revealing the Land at its Barest. Nature Communications. Mosaics are available for the following years: Landsat 5 / Landsat 7 / Landsat 8 - 1983 to 2018; + + + landsat_barest_earth + Landsat 30+ Barest Earth 25m albers (Combined Landsat) + +NOTE this layer has no EX_GeographicBoundingBox + + + WOfS + HLTC + landsat + time-series + mangrove + bare-earth + australia + geomedian + NIDEM + fractional-cover + + + + + + + + + + + + + + + + + + Some other catalog + + Some other catalog + + EPSG:3857 + EPSG:4326 + EPSG:3577 + EPSG:3111 + + 100 + 160 + -50 + -10 + + + Surface Reflectance + This is another layer called Surface Reflectance + + some_layer + Some layer + Some layer + + + WOfS + + + 109.989859933428 + 156.101505058599 + -45.2413329418709 + -9.02727104242042 + + + + + + + 2013-01-01,2014-01-01,2015-01-01,2016-01-01,2017-01-01,2018-01-01 + + + + + + +
From c22bf3f09c9f0d190c02599598856e13d2e3d43e Mon Sep 17 00:00:00 2001 From: Sidney Gijzen Date: Tue, 18 Feb 2025 16:33:51 +0100 Subject: [PATCH 2/3] PR 7466: process feedback code review --- lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts | 2 +- lib/Models/Catalog/Ows/WebMapServiceCatalogItem.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts b/lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts index ffcd3e664e7..6aec2135335 100644 --- a/lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts +++ b/lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts @@ -113,7 +113,7 @@ export default class WebMapServiceCapabilitiesStratum extends LoadableStratum( @computed get layerLimit() { if (isDefined(this.capabilities?.Service?.LayerLimit)) { - return parseInt(this.capabilities?.Service?.LayerLimit); + return parseInt(this.capabilities.Service.LayerLimit, 10); } } diff --git a/lib/Models/Catalog/Ows/WebMapServiceCatalogItem.ts b/lib/Models/Catalog/Ows/WebMapServiceCatalogItem.ts index 8f3f13aa0da..4f0cba74910 100644 --- a/lib/Models/Catalog/Ows/WebMapServiceCatalogItem.ts +++ b/lib/Models/Catalog/Ows/WebMapServiceCatalogItem.ts @@ -261,10 +261,10 @@ class WebMapServiceCatalogItem let layers: string[]; - if (!Array.isArray(this.layers)) { - layers = this.layers.split(","); - } else { + if (Array.isArray(this.layers)) { layers = this.layers; + } else { + layers = this.layers.split(","); } if (this.layerLimit) layers = layers.slice(0, this.layerLimit); From df7e04cc70e87b2eda71e8fd4c35f28b4b6eb52d Mon Sep 17 00:00:00 2001 From: Sidney Gijzen Date: Tue, 18 Feb 2025 17:22:12 +0100 Subject: [PATCH 3/3] update changes --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 080b4ca53aa..e1cd968aa37 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ #### next release (8.8.1) +- enforce the WMS layer limit - [The next improvement] #### 8.8.0 - 2025-02-18 @@ -16,7 +17,6 @@ - Upgraded `sass` to version 1.80+ - Migrated SASS files to use `modern` API (by running the `sass-migrator` script) - Replaced webpack aliases `~terriajs-variables` and `~terriajs-mixins` with respective relative path. This was necessary to run the migrator. It also results in simpler webpack configuration. -- enforce the WMS layer limit - Remove `MapboxImageryProvider`, `createRegionMappedImageryProvider` now uses `ProtomapsImageryProvider`. - Update `protomaps` to `protomaps-leaflet`. This fixes the 5400 vertex limit in a single tile. - The very basic support of mvt style spec is now handled by Terria in [`lib/Map/Vector/mapboxStyleJsonToProtomaps.ts`](lib/Map/Vector/mapboxStyleJsonToProtomaps.ts)