Snap a tile_source to the native pixel resolution

Hello,

Is it possible to use a tile_source and having the zoom/extent snap to certain steps so that the original tiles aren’t re-sampled in anyway? For example when using the tile_source example at:
https://github.com/bokeh/bokeh/blob/master/examples/glyphs/tile_source.py

The example works great, and performance is really good. But when you zoom, you can set it at arbitrary levels, causing the tiles to be re-sampled to a something different than their native resolution. I realize this is often convenient, but being a bit of a pixel-peeper myself I’d rather avoid ‘uncontrolled’ re-sampling unless i specify it myself. I’m not always using online TMS sources, but sometimes also locally created tiles with something like ‘gdal2tiles.py’ to break up really large rasters, like satellite images or stitched photo’s (panoramas etc). But i think the source of the tiles is irrelevant in this case.

I’m not sure where to implement this. I imagine the zoom-related tools trigger some callback which sets the figure extent, this might be the place to round the extent to a multiple of 256 (in pixel units) when using 256px tiles. But when looking at the models, i can see the classes defining the tools, but there is hardly any code. So whats the location where i should be looking to achieve something like this? I’m currently working on 0.11.0dev5.

Any help is appreciated.

Regards,
Rutger

Hey Rutger,

Yes, makes complete sense. I myself have a use case for maintain the true resolutions of tiles. Shouldn’t be a problem but will probably need to wait for next release for something formal. I think it would be nice to have smooth zoom with the wheel_zoom, and fixed resolution zoom with a double click or some other gesture.

One thing you can do for now is create a User Defined Model which extends TileRenderer. This would be a runtime extension of bokeh to include this functionality you desire. In this gist below, I demonstrate how to extend TileRenderer to do a fixed resolution zoom on double-click of the map. If you hold shift, then it will zoom out. This is NOT how it should be done long term, but may help for now. Note this is quick and dirty, but should work with the 0.11 release:

https://gist.github.com/brendancol/520ae46b6fa1b9279bd3

-Brendan

···

On Wednesday, December 23, 2015 at 9:21:11 AM UTC-6, Rutger Kassies wrote:

Hello,

Is it possible to use a tile_source and having the zoom/extent snap to certain steps so that the original tiles aren’t re-sampled in anyway? For example when using the tile_source example at:
https://github.com/bokeh/bokeh/blob/master/examples/glyphs/tile_source.py

The example works great, and performance is really good. But when you zoom, you can set it at arbitrary levels, causing the tiles to be re-sampled to a something different than their native resolution. I realize this is often convenient, but being a bit of a pixel-peeper myself I’d rather avoid ‘uncontrolled’ re-sampling unless i specify it myself. I’m not always using online TMS sources, but sometimes also locally created tiles with something like ‘gdal2tiles.py’ to break up really large rasters, like satellite images or stitched photo’s (panoramas etc). But i think the source of the tiles is irrelevant in this case.

I’m not sure where to implement this. I imagine the zoom-related tools trigger some callback which sets the figure extent, this might be the place to round the extent to a multiple of 256 (in pixel units) when using 256px tiles. But when looking at the models, i can see the classes defining the tools, but there is hardly any code. So whats the location where i should be looking to achieve something like this? I’m currently working on 0.11.0dev5.

Any help is appreciated.

Regards,
Rutger

Hi Brendan,

Thanks you very much for the example, that’s very useful. Having near-zero experience with Javascript (I’m trying Bokeh for a reason ;)), i would never be able to come up with this myself. With the Bokeh 0.11.0dev8 release i got an import error, i think on importing ‘figure’. I ignored that, and downgrading to dev7 made your gist work. I’m not sure how you intended to zooming to work, but for me it calculates the center and new extent not entirely as i would expect.

I cloned your gist and made a few simple edits, for me this zooms to the center of the ‘current’ extent, whereas yours drifted a bit (1/4th?) towards the edge. Here is my gist:

This a great step towards what i had in mind. Zooming with ‘double click’ works, but dragging afterwards again introduces resampling because it changes to zoom a little. This could probably fixed also adding a similar callback for that case. I haven’t looked into it yet.

Additionally the zooming might be a bit more intuitive by zooming to the mouse x/y instead of the window center. I made a first attempt, the modified gist is here:

I’m not sure about the last gist, so be careful. It makes some assumptions about the origin of the projection for example, so i wouldn’t be surprised if it fails for projections with a different origin then PseudoMercator. Unless the “.get_resolution()” call includes a sign with respect to the origin. Also, after a few times zooming in, it seems to skip increasing the zoom level at one step, zooming in further works again but it stays one level ‘behind’.

Thanks again, and a bokehlicious 2016 to everyone!

Regards,
Rutger

···

On Thursday, December 31, 2015 at 4:27:05 AM UTC+1, [email protected] wrote:

Hey Rutger,

Yes, makes complete sense. I myself have a use case for maintain the true resolutions of tiles. Shouldn’t be a problem but will probably need to wait for next release for something formal. I think it would be nice to have smooth zoom with the wheel_zoom, and fixed resolution zoom with a double click or some other gesture.

One thing you can do for now is create a User Defined Model which extends TileRenderer. This would be a runtime extension of bokeh to include this functionality you desire. In this gist below, I demonstrate how to extend TileRenderer to do a fixed resolution zoom on double-click of the map. If you hold shift, then it will zoom out. This is NOT how it should be done long term, but may help for now. Note this is quick and dirty, but should work with the 0.11 release:

https://gist.github.com/brendancol/520ae46b6fa1b9279bd3

-Brendan

On Wednesday, December 23, 2015 at 9:21:11 AM UTC-6, Rutger Kassies wrote:

Hello,

Is it possible to use a tile_source and having the zoom/extent snap to certain steps so that the original tiles aren’t re-sampled in anyway? For example when using the tile_source example at:
https://github.com/bokeh/bokeh/blob/master/examples/glyphs/tile_source.py

The example works great, and performance is really good. But when you zoom, you can set it at arbitrary levels, causing the tiles to be re-sampled to a something different than their native resolution. I realize this is often convenient, but being a bit of a pixel-peeper myself I’d rather avoid ‘uncontrolled’ re-sampling unless i specify it myself. I’m not always using online TMS sources, but sometimes also locally created tiles with something like ‘gdal2tiles.py’ to break up really large rasters, like satellite images or stitched photo’s (panoramas etc). But i think the source of the tiles is irrelevant in this case.

I’m not sure where to implement this. I imagine the zoom-related tools trigger some callback which sets the figure extent, this might be the place to round the extent to a multiple of 256 (in pixel units) when using 256px tiles. But when looking at the models, i can see the classes defining the tools, but there is hardly any code. So whats the location where i should be looking to achieve something like this? I’m currently working on 0.11.0dev5.

Any help is appreciated.

Regards,
Rutger

Rutger,

I think the issue with dev8 was that a new JS component was not yet being uploaded to CDN by our build machinery. It is now, and I just made a dev9 build. Can you try again with dev9? Brendan's gist code is working for me with dev9, but I would like confirmation from you as well, in case there is an issue that still needs to be resolved before the release.

Thanks,

Bryan

···

On Jan 1, 2016, at 3:22 AM, Rutger Kassies <[email protected]> wrote:

Hi Brendan,

Thanks you very much for the example, that's very useful. Having near-zero experience with Javascript (I'm trying Bokeh for a reason ;)), i would never be able to come up with this myself. With the Bokeh 0.11.0dev8 release i got an import error, i think on importing 'figure'. I ignored that, and downgrading to dev7 made your gist work. I'm not sure how you intended to zooming to work, but for me it calculates the center and new extent not entirely as i would expect.

I cloned your gist and made a few simple edits, for me this zooms to the center of the 'current' extent, whereas yours drifted a bit (1/4th?) towards the edge. Here is my gist:
https://gist.github.com/RutgerK/7e6801767aa9ad50b212/397891f8ea2318ef3d65614be3c71d50012cc34d

This a great step towards what i had in mind. Zooming with 'double click' works, but dragging afterwards again introduces resampling because it changes to zoom a little. This could probably fixed also adding a similar callback for that case. I haven't looked into it yet.

Additionally the zooming might be a bit more intuitive by zooming to the mouse x/y instead of the window center. I made a first attempt, the modified gist is here:
Snapping Tile Renderer User Defined Model · GitHub

I'm not sure about the last gist, so be careful. It makes some assumptions about the origin of the projection for example, so i wouldn't be surprised if it fails for projections with a different origin then PseudoMercator. Unless the ".get_resolution()" call includes a sign with respect to the origin. Also, after a few times zooming in, it seems to skip increasing the zoom level at one step, zooming in further works again but it stays one level 'behind'.

Thanks again, and a bokehlicious 2016 to everyone!

Regards,
Rutger

On Thursday, December 31, 2015 at 4:27:05 AM UTC+1, bcol...@continuum.io wrote:
Hey Rutger,

Yes, makes complete sense. I myself have a use case for maintain the true resolutions of tiles. Shouldn't be a problem but will probably need to wait for next release for something formal. I think it would be nice to have smooth zoom with the wheel_zoom, and fixed resolution zoom with a double click or some other gesture.

One thing you can do for now is create a User Defined Model which extends TileRenderer. This would be a runtime extension of bokeh to include this functionality you desire. In this gist below, I demonstrate how to extend TileRenderer to do a fixed resolution zoom on double-click of the map. If you hold shift, then it will zoom out. This is NOT how it should be done long term, but may help for now. Note this is quick and dirty, but should work with the 0.11 release:

https://gist.github.com/brendancol/520ae46b6fa1b9279bd3

-Brendan

On Wednesday, December 23, 2015 at 9:21:11 AM UTC-6, Rutger Kassies wrote:
Hello,

Is it possible to use a tile_source and having the zoom/extent snap to certain steps so that the original tiles aren't re-sampled in anyway? For example when using the tile_source example at:
https://github.com/bokeh/bokeh/blob/master/examples/glyphs/tile_source.py

The example works great, and performance is really good. But when you zoom, you can set it at arbitrary levels, causing the tiles to be re-sampled to a something different than their native resolution. I realize this is often convenient, but being a bit of a pixel-peeper myself I'd rather avoid 'uncontrolled' re-sampling unless i specify it myself. I'm not always using online TMS sources, but sometimes also locally created tiles with something like 'gdal2tiles.py' to break up really large rasters, like satellite images or stitched photo's (panoramas etc). But i think the source of the tiles is irrelevant in this case.

I'm not sure where to implement this. I imagine the zoom-related tools trigger some callback which sets the figure extent, this might be the place to round the extent to a multiple of 256 (in pixel units) when using 256px tiles. But when looking at the models, i can see the classes defining the tools, but there is hardly any code. So whats the location where i should be looking to achieve something like this? I'm currently working on 0.11.0dev5.

Any help is appreciated.

Regards,
Rutger

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/411ed69f-37f5-48a6-a530-67f08dbf7708%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Hi Bryan,

I’ve tested a few different dev versions, i cant replicate the initial error at import which i described previously, but perhaps that makes sense if its something ‘online’ at the CDN. A different error occurs however both with dev8 and dev9, with dev7 everything is working as i would expect. I have attached a screenshot of how the error looks in my notebook. I wanted to use nbviewer to show the error, but a bit to my surprise the notebook renders it correct, the same as it is for me with dev7, here is the notebook:

Let me know if there is anything i can test or do to clear it up.

Regards,
Rutger

···

On Friday, January 1, 2016 at 7:40:09 PM UTC+1, Bryan Van de ven wrote:

Rutger,

I think the issue with dev8 was that a new JS component was not yet being uploaded to CDN by our build machinery. It is now, and I just made a dev9 build. Can you try again with dev9? Brendan’s gist code is working for me with dev9, but I would like confirmation from you as well, in case there is an issue that still needs to be resolved before the release.

Thanks,

Bryan

On Jan 1, 2016, at 3:22 AM, Rutger Kassies [email protected] wrote:

Hi Brendan,

Thanks you very much for the example, that’s very useful. Having near-zero experience with Javascript (I’m trying Bokeh for a reason ;)), i would never be able to come up with this myself. With the Bokeh 0.11.0dev8 release i got an import error, i think on importing ‘figure’. I ignored that, and downgrading to dev7 made your gist work. I’m not sure how you intended to zooming to work, but for me it calculates the center and new extent not entirely as i would expect.

I cloned your gist and made a few simple edits, for me this zooms to the center of the ‘current’ extent, whereas yours drifted a bit (1/4th?) towards the edge. Here is my gist:

https://gist.github.com/RutgerK/7e6801767aa9ad50b212/397891f8ea2318ef3d65614be3c71d50012cc34d

This a great step towards what i had in mind. Zooming with ‘double click’ works, but dragging afterwards again introduces resampling because it changes to zoom a little. This could probably fixed also adding a similar callback for that case. I haven’t looked into it yet.

Additionally the zooming might be a bit more intuitive by zooming to the mouse x/y instead of the window center. I made a first attempt, the modified gist is here:

https://gist.github.com/RutgerK/7e6801767aa9ad50b212/3ac311cd0651fc8794f297a34e1ebc03589366cd

I’m not sure about the last gist, so be careful. It makes some assumptions about the origin of the projection for example, so i wouldn’t be surprised if it fails for projections with a different origin then PseudoMercator. Unless the “.get_resolution()” call includes a sign with respect to the origin. Also, after a few times zooming in, it seems to skip increasing the zoom level at one step, zooming in further works again but it stays one level ‘behind’.

Thanks again, and a bokehlicious 2016 to everyone!

Regards,

Rutger

On Thursday, December 31, 2015 at 4:27:05 AM UTC+1, [email protected] wrote:

Hey Rutger,

Yes, makes complete sense. I myself have a use case for maintain the true resolutions of tiles. Shouldn’t be a problem but will probably need to wait for next release for something formal. I think it would be nice to have smooth zoom with the wheel_zoom, and fixed resolution zoom with a double click or some other gesture.

One thing you can do for now is create a User Defined Model which extends TileRenderer. This would be a runtime extension of bokeh to include this functionality you desire. In this gist below, I demonstrate how to extend TileRenderer to do a fixed resolution zoom on double-click of the map. If you hold shift, then it will zoom out. This is NOT how it should be done long term, but may help for now. Note this is quick and dirty, but should work with the 0.11 release:

https://gist.github.com/brendancol/520ae46b6fa1b9279bd3

-Brendan

On Wednesday, December 23, 2015 at 9:21:11 AM UTC-6, Rutger Kassies wrote:

Hello,

Is it possible to use a tile_source and having the zoom/extent snap to certain steps so that the original tiles aren’t re-sampled in anyway? For example when using the tile_source example at:

https://github.com/bokeh/bokeh/blob/master/examples/glyphs/tile_source.py

The example works great, and performance is really good. But when you zoom, you can set it at arbitrary levels, causing the tiles to be re-sampled to a something different than their native resolution. I realize this is often convenient, but being a bit of a pixel-peeper myself I’d rather avoid ‘uncontrolled’ re-sampling unless i specify it myself. I’m not always using online TMS sources, but sometimes also locally created tiles with something like ‘gdal2tiles.py’ to break up really large rasters, like satellite images or stitched photo’s (panoramas etc). But i think the source of the tiles is irrelevant in this case.

I’m not sure where to implement this. I imagine the zoom-related tools trigger some callback which sets the figure extent, this might be the place to round the extent to a multiple of 256 (in pixel units) when using 256px tiles. But when looking at the models, i can see the classes defining the tools, but there is hardly any code. So whats the location where i should be looking to achieve something like this? I’m currently working on 0.11.0dev5.

Any help is appreciated.

Regards,

Rutger


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/411ed69f-37f5-48a6-a530-67f08dbf7708%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.