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

Default to OSM z/x/y.png format, provide TMS (with y flipped) as an option #15

Closed
dracos opened this issue Feb 4, 2021 · 11 comments
Closed
Labels
enhancement New feature or request

Comments

@dracos
Copy link
Contributor

dracos commented Feb 4, 2021

As I understand it, mbtiles stores the y co-ordinate in the reverse of the standard OSM z/x/y notation. OSM has y=0 at the top counting down, whereas mbtiles have y=0 at the bottom counting up. For example, currently you have https://datasette-tiles-demo.datasette.io/-/tiles/basemap/4/8/9.png equal to https://tile.openstreetmap.org/4/8/6.png (so Y(osm) = 2^Z - Y(mbtile) - 1 and vice-versa). For ease of translating from one to the other (and perhaps with your proxy suggestion) it would be good if it could use the standard z/x/y co-ordinates for tile URLs, I think.

@simonw
Copy link
Owner

simonw commented Feb 4, 2021

Well that's confusing! Explains why I need the "tms": true property for the tile layer (I got there through much frustration and trial-and-error):

window.DATASETTE_CLUSTER_MAP_TILE_LAYER_OPTIONS = {
"minZoom": {{ min_zoom }},
"maxZoom": {{ max_zoom }},
"tms": true{% if attribution %},
"attribution": {{ attribution|safe }}{% endif %}
};

Maybe I could also support the OSM format directly at a different path - have /-/tiles/... for one format and /-/tiles-tms/... for the other format.

I want to make this change ASAP because it's a breaking change for anything consuming tiles served by this plugin. Need to make sure I fully understand the options first. Anything I should read about this?

@simonw
Copy link
Owner

simonw commented Feb 4, 2021

I want to match what the other MBTiles implementations are doing: https://github.com/mapbox/mbtiles-spec/wiki/Implementations

https://github.com/infostreams/mbtiles-php/blob/a7258d140788156bf3ad8eff7585ad65fac379c7/tileserver.php#L31-L39 is interesting:

$r->map("1.0.0/:layer/:z/:x/:y:is_retina.:ext",
	array("controller" => "maptile", "action" => "serveTmsTile"),
	array("layer"     => $_identifier, "x" => $_number, "y" => $_number, "z" => $_number,
	      "is_retina" => $_retina, "ext" => "(png|jpg|jpeg|json)"));

$r->map(":layer/:z/:x/:y:is_retina.:ext",
	array("controller" => "maptile", "action" => "serveTile"),
	array("layer"     => $_identifier, "x" => $_number, "y" => $_number, "z" => $_number,
	      "is_retina" => $_retina, "ext" => "(png|jpg|jpeg|json)"));

Note that the 1.0.0/ one callsserveTmsTile while the other one calls serveTile - which has this effect: https://github.com/infostreams/mbtiles-php/blob/a7258d140788156bf3ad8eff7585ad65fac379c7/tileserver.php#L182-L187

		if (!$this->is_tms) {
			$this->y = pow(2, $this->z) - 1 - $this->y;
		}

@simonw
Copy link
Owner

simonw commented Feb 4, 2021

This one lets you pass an ?origin= option: https://github.com/perrygeo/python-mbtiles/blob/1cc63047be0254139e1079ba4bb036a6c6904337/serve_mbtiles.py#L17-L33

        origin = self.get_arguments('origin')
        try:
            origin = origin[0]
        except IndexError:
            origin = 'bottom' 

        if origin == 'top':
            # invert y axis to top origin
            ymax = 1 << int(z);
            y = ymax - int(y) - 1;

@simonw
Copy link
Owner

simonw commented Feb 4, 2021

I feel like I've stumbled into some kind of weird multi-decade battle between geographers here that I don't understand the implications of!

@simonw
Copy link
Owner

simonw commented Feb 4, 2021

Useful background information from @tmcw: https://gist.github.com/tmcw/4954720

There are no advantages of XYZ over TMS or vice-versa for most maps*, but XYZ is more popular.

@simonw simonw changed the title Reverse y co-ordinate in tile URLs Take documented stand on OSM v.s. TMS default, support both Feb 4, 2021
@simonw
Copy link
Owner

simonw commented Feb 4, 2021

I think I'll go with XYZ by default and offer TMS as an option - maybe at /-/tiles-tms.

@simonw
Copy link
Owner

simonw commented Feb 4, 2021

I need to check that I understand how this issue affects the MBTiles files I'm creating with https://github.com/simonw/download-tiles

@simonw
Copy link
Owner

simonw commented Feb 9, 2021

Made myself a diagram showing how the OpenStreetMap tiles work:

Map_tile_coordinate_systems_–_Figma

@simonw simonw changed the title Take documented stand on OSM v.s. TMS default, support both Default to OSM z/x/y.png format, provide TMS z/y/x.png as an option Feb 9, 2021
@simonw
Copy link
Owner

simonw commented Feb 9, 2021

Zoom level 2 is more useful for understanding how these work:

Map_tile_coordinate_systems_–_Figma

@simonw
Copy link
Owner

simonw commented Feb 9, 2021

Same diagram for OpenStreetMap:

Map_tile_coordinate_systems_–_Figma

@simonw simonw changed the title Default to OSM z/x/y.png format, provide TMS z/y/x.png as an option Default to OSM z/x/y.png format, provide TMS (with y flipped) as an option Feb 10, 2021
@simonw
Copy link
Owner

simonw commented Feb 10, 2021

I'll use this to calculate the y value for non-TMS tiles:

y = int(math.pow(2, z) - 1 - y)

@simonw simonw closed this as completed in adf3495 Feb 11, 2021
@simonw simonw added the enhancement New feature or request label Feb 11, 2021
simonw added a commit that referenced this issue Feb 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants