-
-
Notifications
You must be signed in to change notification settings - Fork 23
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
Add snapshot control to download and print map #202
Conversation
First, click the "Capture image" button. Then the "Download" and "Print" buttons will appear. The download is a link like: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good start! Thanks for working on this @paul121
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be a great option! Thanks for working on it @paul121!
Great feedback @symbioquine. I don't have anything to add at this point.
Yes - thanks for the great feedback @symbioquine ! I renamed to "Snapshot" and have implemented the code changes you requested. Still remaining is to simplify the SVG, I'll need to download the program and go through the steps but agree we should do this. |
Hey @symbioquine how do these SVGs look now? I was able to transform/optimize to 24x24 with https://www.svgviewer.dev/ before optimizing again in SVGOMG (maybe not necessary) and it seemed to work well. |
Use number precision 2 in svgomg
d85954b
to
1f88295
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I was able to get the print SVG down to 1.6KB!
Also ebased on 2.x and force-pushed with another commit to get tests working.
But I found one issue with Mapbox and cross-origin image requests with the map canvas. Especially curious your thoughts @mstenta @symbioquine !
src/instance/methods/layer.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I commented on this file, click the file path above to see the relevant changes)
After testing again locally I discovered a console error when trying to use the Snapshot behavior with Mapbox layers. Notably, there was no issue with Open Street Map layers. The error was basically:
"Tainted canvases may not be exported."
TIL that cross-origin requests have some implications on how images are used in canvas elements... https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image
If the foreign content comes from an image obtained from either as HTMLCanvasElement or ImageBitMap, and the image source doesn't meet the same origin rules, attempts to read the canvas's contents are blocked.
We attempt to read the canvas's contents using the toDataUrl('image/jpeg')
.
HTML provides a crossorigin attribute for images that, in combination with an appropriate CORS header, allows images defined by the
element that are loaded from foreign origins to be used in a as if they had been loaded from the current origin.
So, ultimately, we can solve this by requesting "anonymous" crrss-origin access:
The image is then configured to allow cross-origin downloading by setting its crossOrigin attribute to "anonymous" (that is, allow non-authenticated downloading of the image cross-origin).
Thankfully OpenLayers includes a crossOrigin
option in their API for what appears like all raster layer sources. I didn't see the option on VectorSource
, which makes sense. Adding this solves the problem and Snapshots can be made of both Mapbox and Open Street Map layers!
https://openlayers.org/en/latest/apidoc/module-ol_source_XYZ-XYZ.html
The crossOrigin attribute for loaded images. Note that you must provide a crossOrigin value if you want to access pixel data with the Canvas renderer. See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.
I'm not quite sure why this wasn't happening previously. I suppose it is possible Mapbox changed the default CORS response headers to something less friendly? Even though it still works once we request anonymous
?
Anyways... this makes me wonder: Should we always set this value for raster layer sources? In theory I think a map server could reject anonymous
CORS requests. In which case this change would break those layers.
So... perhaps we could add crossOrigin
as an option to the farmOS-map addLayer()
API? Then we could set this crossOrigin
value as needed? I think the downside is that unless users explicitly set this flag, it's possible their map layers will be incompatible with the Snapshot behavior - which currently does not have any error handling for this issue (how should we tell the user one of the current map layers is unsupported for snapshotting?)
I assume we could avoid this issue the vast majority of the time by setting crossOrigin
to anonymous
by default, but allow it to be overridden via the API. Ultimately I think this might be our best option?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm reading the crossorigin
MDN page correctly, it seems like there's no way to make the proposed solution a non-breaking change.
One example would be uploading some XYZ layer tiles to farmOS directly and relying on the user already being signed-in to have access to those uploads. It sounds like setting the crossorigin: anonymous
would cause farmOS-map to make the tile layer requests as CORS requests even under the same domain.
I'd argue for not including the crossorigin
change in this PR and instead adding some error handling to let users know the nature of the problem for failures. (This could also help for other failure scenarios so users don't need to look in the JS console to see why the button didn't do anything.)
A follow-up PR could attempt to fix that problem for Mapbox and perhaps make it possible for other layer types to optionally specify crossorigin: anonymous
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh interesting. So this only happens with MapBox when you want to create a snapshot?
Do you have a MapBox API key locally (does that make any difference, I wonder)?
I'm not quite sure why this wasn't happening previously.
Do you mean in your local testing of the snapshot button this wasn't happening previously?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point @symbioquine, I hadn't thought of tile layers hosted on the same domain. I agree we should make the crossOrigin
change separately and add some error handling. Any ideas on how to implement some error handling? Have we done anything similar for other map behaviors? 🤔
@mstenta correct, this only happens with Mapbox. What do you mean by a Mapbox API key locally? I believe I am using a Mapbox API key that is not restricted to any particular domain (it is one from my personal acct). Not the one included in farmOS-map source code here which indeed did not work, as expected!
farmOS-map/examples/simple-html-consumer/static/mapbox.js
Lines 6 to 7 in 683423c
// Test MapBox API key (only works with farmos.github.io). | |
var key = 'pk.eyJ1IjoiZmFybWllciIsImEiOiJjazB6ajZjODkwMWIzM2ptcDBvNjl4eGViIn0.oYDl6csdVuVzlB0hf2ju2Q'; |
I tested this from both the simple-html-consumer
example hosted on 127.0.0.1
as well as a local farmOS dev server w/ HTTPS and a local SSL cert via ddev. Just in case this was a weird localhost issue. But experience the same on both.
Do you mean in your local testing of the snapshot button this wasn't happening previously?
Correct. I don't remember what exactly I tested, but I assume I tried both Mapbox and Open Street Map layers
Chatting today: we're going to move the |
1f88295
to
856b153
Compare
Okay, I removed the commit that made |
Adds an
image
control (naming?) that allows the user to download an image of the current map view or, using printjs, opens a print dialog with the map.I implemented this as a OL Control and wrapped it with a behavior (similar to snapping grid). It won't be added to maps by default unless the behavior is explicitly added.