jncc / web-mapper-core

Common web-mapper components for the JNCC websites
6 stars 1 forks source link

Permalinks #38

Closed andyb-esdm closed 5 years ago

andyb-esdm commented 5 years ago

A way for the user to create a link to the map with the current settings e.g. layers visible, filters applied.

Need client-side object to represent state of map and also need to finalise strategy. Currently two main options: Querystring strategy - manipulate querystring to reflect the state of the map (but how does this work with map in an iframe?) Save strategy: user can save a map to the database via the api. But then need to think about spamming etc.

This specification needs finalisation before Sprint 3, when it will be implemented.

andyb-esdm commented 5 years ago

Quite a bit more to do on this but permalinks somewhat working. Change layers, baselayer, move around and click the permalink icon. This updates the url, which you can copy and paste into another window/browser and see that it recreates the map. e.g. https://jnccdev-map.esdm.co.uk/?zoom=5&center=-3.508,52.305&layerIds=159,160&baseLayerId=1 TODO: • Get this working in the iframe context. Simon will write the JS that is hosted in the CMS to copy the querystring and set it as the src of the iframe. It will also provide the base url for the CMS. The mapper will consume this when applying/creating the permalink. • Decide what should be stored in the permalink – I expect filters will be included. • Decide what to do with the permalink – should it update the address as it currently does or offer the link to be copied from a popup? I expect we will need something copyable. Better still we could create a bitly link (as global forest watch does), which is more terse and easier to handle.

JordanPinder commented 5 years ago

@andyb-esdm I agree with creating something that's simple to handle, so a bitly approach and popup would be good.

Storing wise, it should store the parameters used to display a specific map view - filters, lat/lon, zoom scale, basemap, layers etc.

HelenwoodsJNCC commented 5 years ago

@andyb-esdm feedback from the UAT - could the permalink appear in a pop-up box rather than just change the url at the top, otherwise it isn't clear what has actually happened. Also could the tool tip be made more descriptive/user friendly as people might not be clear what permalink means. e.g. share map link

andyb-esdm commented 5 years ago

updated permalink tooltip to 'share map link'

andyb-esdm commented 5 years ago

need to finalise permalink behaviour

HelenwoodsJNCC commented 5 years ago

@andyb-esdm Quick Q. The current MPA mapper is used to create dynamic map images on some of our MPA pages e.g. map at the top of http://jncc.defra.gov.uk/page-6535, will is be possible do to something similar with the new mapper?

andyb-esdm commented 5 years ago

@HelenwoodsJNCC I wasn't aware you could do that with the previous version. That's using a proxy to return just the image from the wms - it isn't the mapper as such if that makes sense. It might be possible to query geoserver directly to do that. Will discuss how that works with @JamesPe and get back to you.

JamesPe commented 5 years ago

Hi @HelenwoodsJNCC this isn't really a mapper issue as the image is served from geoserver. It is on your current system possible to create a link that will generate an image (see below - quick attempt to roughly replicate your example). It does take a little bit of editing a URL to get the desired result - but perfectly possible. If this is something you need a lot - we could in the next version consider producing something a bit like the permalinks option - which would generate you the WMS request fro the currently displayed mapper.

https://staging.ows.emodnet-seabedhabitats.eu/mpa_mapper/wms?mapInstance=MPSMap_&LAYERS=prot_annexi_reef_full,sac_mc_full&FORMAT=image%2Fpng&TRANSPARENT=true&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A900913&BBOX=-2241056.9666509,7776566.9347497,-1605100,8366661&WIDTH=624&HEIGHT=579

HelenwoodsJNCC commented 5 years ago

@JamesPe that's great, thanks.

andyb-esdm commented 5 years ago

Permalink is now in a copy-able pop-up. @SimonAnnetts has also written some js so that it will work from within a hosted iframe.

andyb-esdm commented 5 years ago

So we'll need to deploy that somewhere in your CMS to test.

HelenwoodsJNCC commented 5 years ago

@andyb-esdm The new pop-up seems to be working. Will the finalised permalink take you to the page containing the iframe? At the moment it takes you to the standalone page. i.e. Permalink created here http://jncc.defra.gov.uk/default.aspx?page=7718 takes you to http://jnccdev-map.esdm.co.uk/

andyb-esdm commented 5 years ago

@HelenwoodsJNCC yes - but simon has written some javascript so that it will take you to jncc.defra.gov.uk. and apply the permalink to the map. We'll get that set up for you.

HelenwoodsJNCC commented 5 years ago

@andyb-esdm fab thanks!

GMDuncan commented 5 years ago

Not sure if this is a new issue, let me know if so and I'll separate it off.

@andyb-esdm Just looking into cross-functionality of the permalinks with the current EMODnet "Metadata search" page.

Currently the metadata search page itself fills in a link template with a GUI, that is passed to the old mapper's proxhandler, which uses a custom getfeatureinfo to get zoom extent, and then creates the equivalent of the old permalink zoomed to the right area, with the habitat maps from survey turned on and filtered to the right GUI.

I think that we can forgoe the zooming for the new map, but it would be good to be able to arrive at the map with the habitat maps from survey layer turned on with a filter for a specific GUI. I've just been informed that the active filters is held as a token, however (sensible due to URL length), which means that it would be hard to programmatically filter to the correct GUI. Is there a way to pass through a "decoded" active filters value in any way? So that the URL query string could define layer x's filter y has value z. Even if specific to GUI (I can't see any other need for this for other layers currently).

andyb-esdm commented 5 years ago

@GMDuncan I think I understand but I'm not positive! I didn't know about this functionality. Can you provide a walk through with a real example starting from the Metadata Search? For example, 'type mytilus edulis beds in the metadata search', 'click the second link' etc. Thanks

GMDuncan commented 5 years ago

I'll try and come up with something, this afternoon, yup!

GMDuncan commented 5 years ago
  1. Go to the Metadata Search page.
  2. Type "Greater Haig Fras" into the search box and click search.
  3. Note the URL of the "View map GB001518" hyperlink. This is a standard template url: https://www.emodnet-seabedhabitats.eu/access-data/launch-map-viewer/?mapInstance=MESHAtlanticMap&mapZoomToId=GB001518&mapZoomToField=GUI&mapZoomToLayer=AllMappingAreas,MESHSurveysPoly,UnprocessedImageAreas and the page simply changes the GUI as necessary which it gets from the geonetwork metadata.
  4. Clicking the url, the mapper proxyhandler takes the GUI and, from it, generates a URL with a querystring with a zoom to centre, zoom level, the maps from survey layer turned on, and a (Mapserver) variable which filters the data by the map GUI (unique identifier for the dataset). Something like: https://mapper.emodnet-seabedhabitats.eu/default.aspx?mapInstance=MESHAtlanticMap_&page=1974&LAYERS=EUNISmedium&GUICode=GB001518&zoom=10&Y=50.29361628725189&X=-7.9428710921528936

To mimic this on the new mapper, I think that the zoom is nice but not absolutely necessary, and working out the zoom for a map would require significant development effort on both the geoserver and mapper side of things.

The main things will be

  1. Turning on the correct layer Which is possible with the way that the new mapper recognises permalinks Through the layerIds parameter e.g https://prelive.mapper.emodnet-seabedhabitats.eu/?zoom=6&center=-3.508,52.305&layerIds=1&baseLayerId=1&activeFilters=
  2. Filtering the "All habitat maps from survey" layer (identified by the layerId) with the complex filter "gui" value of 'GB001518' (value depending on the map). I'm not sure if this is possible as the activeFilters parameter currently looks like a token system (but I'm not sure how this token system works, whether it accesses a serverside file/value or something else?)

Let me know if i've not explained it very well! Might be easier to demonstrate on skype or something else?

andyb-esdm commented 5 years ago

Thanks for explaining this @GMDuncan

You're right that the activeFilters parameter is encoded to preserve querystring length. Filters can now be more freely defined than in past versions and now we're encoding a JSON object representing the filter state.

We could have another parameter in the permalink that the mapper can interpret as a different kind of filter and send to geoserver for a layer. However, that hasn't been something I've been asked to do to date.

GMDuncan commented 5 years ago

Thanks @andyb-esdm - didn't realise that it was an encoded JSON object.

Looks as though you're using LZstring with the compressToEncodedURIComponent method? It actually handily looks like someone's translated this package into Python. I'll have a go and see if they're directly comparable. If so, might be able to prebake the ICES geonetwork metadata records with correct download links and solve everything from our side and with a minor change to the metadata search page code rather than adding extra fluff to the mapper.

andyb-esdm commented 5 years ago

@GMDuncan I am 👍

There were a few gotchas reading this because the base64 encoded string was being uri encoded (e.g. = turning into %3D), which broke lzstring (a bug?) but this is all now handled by the mapper so not something you need to worry about when creating the compressed activefilter.

The code is here: https://github.com/jncc/web-mapper-core/blob/master/web-map/src/app/permalink.service.ts but I think you already know that!

andyb-esdm commented 5 years ago

The other class of interest, if you're going to try this, is here: https://github.com/jncc/web-mapper-core/blob/master/web-map/src/app/models/active-filter.model.ts This is an object representing a filter for a single layer.

layerId and filterId are pretty self explanatory from the config database filterLookupIds: number[] are the ids of the lookup values you want to filter by used by both cql and sql views. The mapper translates these ids into the lookup values to create a filter of the form: 'where hab_type in (A:1, A:2)' etc. On reflection, I'm not sure that extra bit of indirection was necessary (lookupIds to values) but we thought it would save a little space! filterText: string is the alternate way of filtering with a string for sql views (e.g. like %mud%)

GMDuncan commented 5 years ago

Thanks @andyb-esdm

Looks like the python library works nicely well. Seems to encode and decode the filterstrings very nciely, so I think that we can sort this out on our end, and scrub the sub-issue!

>>> import lzstring as LZ
>>> x = LZ.LZString()
>>> compressed = 'NobwRANghgngpgJwJIBMwC4CMAaMAzASwgBdFUMAmAVl0JMQBkB7JgawFcAHVAZw2EwAOTAE4AurSKkEAFTgAPYhjBgAvmKA'
>>> x.decompressFromEncodedURIComponent(compressed)
'[{"layerId":1,"filterId":25,"filterLookupIds":[1819],"filterText":""}]'

The GUI Filter will be a text-based filter, so it should be fairly simple to implement automatically per dataset.

Thanks for all the info!

andyb-esdm commented 5 years ago

@GMDuncan that's great.