Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support loading COG layers from query params #9527

Closed
landryb opened this issue Oct 2, 2023 · 7 comments · Fixed by #9531 or #10187
Closed

support loading COG layers from query params #9527

landryb opened this issue Oct 2, 2023 · 7 comments · Fixed by #9531 or #10187

Comments

@landryb
Copy link
Collaborator

landryb commented Oct 2, 2023

Description

now that we have COG support since #9320 im looking at how to implement support for loading such data type from the url params eg http://localhost:8081/#/viewer/new?actions=[{%22type%22:%22CATALOG:ADD_LAYERS_FROM_CATALOGS%22,%22layers%22:[%22title%22],%22sources%22:[{%22type%22:%22cog%22,%22url%22:%22https%3A%2F%2Fcogeo.craig.fr%2Fopendata%2Fortho%2Forthocraig3_vichy_2021.cog.tif%22}]}]

for now i only changed one thing so that the layer title is not looked for in the catalog records like its done for 3dtiles (#9021) & geojson (#9276):

--- a/web/client/epics/catalog.js
+++ b/web/client/epics/catalog.js
@@ -163,7 +163,7 @@ export default (API) => ({
                         const layerOptionsParam = get(options, i, searchOptionsSelector(state));
                         // use the selected layer text as title for 3d tiles
                         // because currently we get only a single record for this service type
-                        const layerOptions = format === '3dtiles' || format === 'geojson'
+                        const layerOptions = format === '3dtiles' || format === 'geojson' || format === 'cog'
                             ? {
                                 ...layerOptionsParam,
                                 title: isObject(layerOptionsParam?.title)

but no layer is loaded. From my digging in the browser debugger, i understand that's because service.records is empty in https://github.com/geosolutions-it/MapStore2/blob/master/web/client/api/catalog/COG.js#L65, probably because searchAndPaginate hasnt been called yet, and that method will return no records anyway since layers is an empty array ? so ... does it make sense to have a searchAndPaginate method in a COG catalog type ? afaict this method isnt present for geojson and 3dtiles formats... @dsuren1, any idea ?

@landryb landryb added the New Feature used for new functionalities label Oct 2, 2023
@landryb
Copy link
Collaborator Author

landryb commented Oct 2, 2023

after more digging.. service.records is populated in GetRecords when coming from the regular 'add layers' widget, but i can't figure out yet what populates it. That's definitely puzzling.

@dsuren1
Copy link
Contributor

dsuren1 commented Oct 2, 2023

@landryb
Try passing this url.

URL http://localhost:8081/#/viewer/new?actions=[{%22type%22:%22CATALOG:ADD_LAYERS_FROM_CATALOGS%22,%22layers%22:[%22%22],%22sources%22:[{%22type%22:%22cog%22,%20%22records%22:[{%22title%22:%20%22orthocraig3_vichy_2021.cog%22,%20%22url%22:%22https://cogeo.craig.fr/opendata/ortho/orthocraig3_vichy_2021.cog.tif%22}]}]}]

It needs some update on catalog epic too. But if you like to try it locally, you can modify this line to something like this
const record = head(records.filter(rec => rec.identifier || rec.name === text || (rec.type === 'cog' && text ? rec.title.inludes(text) : true)))

@landryb
Copy link
Collaborator Author

landryb commented Oct 2, 2023

thanks, with that tweak and that url it 'works' (but wont zoom on the layer nor allow zoom to layer)

i see where this is going, but it feels wrong to have to construct a specific url for cog format while we should be able to use the same pattern as for other catalog types.. ofc, the goal is to have a generic API to be able to build the URL from client code (in my case, from geonetwork) without specific cases.

wouldn't it be possible to rework COG.js catalog type to be 'like' the others and have records array directly populated with the single entry that is available, constructed from url & title ? Unless there are plans to support multiple layers in a tiff but i doubt that's a usecase...

and loading a COG directly from queryparams, to me we want to directly zoom on it so fetchMetadata should default to true in that case.

@landryb
Copy link
Collaborator Author

landryb commented Oct 2, 2023

tried with this to have a default layer entry created on the fly (because _layers is empty in the 'add from query param' case)

--- a/web/client/api/catalog/COG.js
+++ b/web/client/api/catalog/COG.js
@@ -110,6 +110,13 @@ export const getRecords = (_url, startPosition, maxRecords, text, info = {}) =>
         });
     }
     return Promise.all([...layers]).then((_layers) => {
+        if (!_layers.length) {
+             _layers = [{
+                title: text,
+                type: COG_LAYER_TYPE,
+                url: _url
+             }];
+        }
         return searchAndPaginate(_layers, startPosition, maxRecords, text);
     });
 };

but that crashes when geotiff tries to load it:

Uncaught TypeError: this.sourceInfo_ is undefined
    GeoTIFFSource webpack://mapstore2/./node_modules/ol/source/GeoTIFF.js?:401
    create webpack://mapstore2/./web/client/components/map/openlayers/plugins/COGLayer.js?:23
    createLayer webpack://mapstore2/./web/client/utils/openlayers/Layers.js?:28
    OpenlayersLayer webpack://mapstore2/./web/client/components/map/openlayers/Layer.jsx?:96
    componentDidMount webpack://mapstore2/./web/client/components/map/openlayers/Layer.jsx?:271
    React 5
vendors-node_modules_eventlistener_eventlistener_js-node_modules_lrucache_index_js-node_modul-2ce0e3.js line 333 > eval:401:24
    GeoTIFFSource webpack://mapstore2/./node_modules/ol/source/GeoTIFF.js?:401
    create webpack://mapstore2/./web/client/components/map/openlayers/plugins/COGLayer.js?:23
    createLayer webpack://mapstore2/./web/client/utils/openlayers/Layers.js?:28
    OpenlayersLayer webpack://mapstore2/./web/client/components/map/openlayers/Layer.jsx?:96
    componentDidMount webpack://mapstore2/./web/client/components/map/openlayers/Layer.jsx?:271
    React 6
    unstable_runWithPriority webpack://mapstore2/./node_modules/scheduler/cjs/scheduler.development.js?:815
    React 5
    unstable_runWithPriority webpack://mapstore2/./node_modules/scheduler/cjs/scheduler.development.js?:815
    React 6
    Redux 3
    routerMiddleware webpack://mapstore2/./node_modules/connected-react-router/esm/middleware.js?:27
    Redux 4
    RxJS 37
    Redux 4
    RxJS 56

@dsuren1
Copy link
Contributor

dsuren1 commented Oct 2, 2023

@landryb Try setting sources instead of directly url

if (!_layers.length) {
       _layers = [{
       title: text,
       type: COG_LAYER_TYPE,
       sources: [{url: _url}]
      }];
 }

@landryb
Copy link
Collaborator Author

landryb commented Oct 2, 2023

so it works with that suggestion, but isnt satisfying since it wont allow to zoom to layer.

my idea then is to move the metadata/crs/bbox fetching to a separate function, and reuse that... but sadly my wip branch doesnt work yet. I'm probably doing something wrong with promises since sometimes _layers is defined and sometimes it's pending

@landryb
Copy link
Collaborator Author

landryb commented Oct 2, 2023

@landryb Try setting sources instead of directly url

if (!_layers.length) {
       _layers = [{
       title: text,
       type: COG_LAYER_TYPE,
       sources: [{url: _url}]
      }];
 }

on this, eslint will complain (rightfully?) that one isnt supposed to assign to a function parameter, per https://github.com/geosolutions-it/MapStore2/actions/runs/6379936002/job/17313379000

@tdipisa tdipisa added enhancement and removed New Feature used for new functionalities labels Jan 15, 2024
@tdipisa tdipisa added this to the 2024.01.00 milestone Jan 15, 2024
@tdipisa tdipisa modified the milestones: 2024.01.00, 2024.01.01 Mar 4, 2024
dsuren1 added a commit that referenced this issue Apr 10, 2024
* COG services only have a single layer, use provided layer text as title (#9527)

* create COG layer on the fly if none is provided (#9527)

* use properly named parameters for getLayerConfig call

* return layer in case getLayerConfig failed

* add documentation about loading COG layer via viewer parameters (#9531)

* Update docs/developer-guide/map-query-parameters.md

---------

Co-authored-by: Suren <[email protected]>
@tdipisa tdipisa added BackportNeeded Commits provided for an issue need to be backported to the milestone's stable branch External Contribution labels Apr 10, 2024
dsuren1 pushed a commit to dsuren1/MapStore2 that referenced this issue Apr 11, 2024
* COG services only have a single layer, use provided layer text as title (geosolutions-it#9527)

* create COG layer on the fly if none is provided (geosolutions-it#9527)

* use properly named parameters for getLayerConfig call

* return layer in case getLayerConfig failed

* add documentation about loading COG layer via viewer parameters (geosolutions-it#9531)

* Update docs/developer-guide/map-query-parameters.md

---------

Co-authored-by: Suren <[email protected]>
(cherry picked from commit 6b4d662)
tdipisa pushed a commit that referenced this issue May 14, 2024
* COG services only have a single layer, use provided layer text as title (#9527)

* create COG layer on the fly if none is provided (#9527)

* use properly named parameters for getLayerConfig call

* return layer in case getLayerConfig failed

* add documentation about loading COG layer via viewer parameters (#9531)

* Update docs/developer-guide/map-query-parameters.md

---------

Co-authored-by: Suren <[email protected]>
(cherry picked from commit 6b4d662)

Co-authored-by: Landry Breuil <[email protected]>
@tdipisa tdipisa removed the BackportNeeded Commits provided for an issue need to be backported to the milestone's stable branch label May 14, 2024
@ElenaGallo ElenaGallo self-assigned this May 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment