Giter Club home page Giter Club logo

Comments (15)

vincentsarago avatar vincentsarago commented on September 9, 2024 1

FYI I started a PR in #131
I'll need to add some tests and also so if all the morecantile methods are working with VariableWidth TMS

from morecantile.

jerstlouis avatar jerstlouis commented on September 9, 2024 1

I don't think there is a formal requirement, but the following is included in normative Section 6.1.5:

Even if tiles can coalesce, this does not change the indexing or the tile matrix set that will be the same as if no coalescence has been applied. For example, if the c coefficient is 4, the tileCol of the first tile will be 0, the tileCol of the second tile will be 4, the tileCol of the third tile will be 8 and so on. In other words, and for the same example, tileCol 0, 1, 2 and 3 points to the same tile.

from morecantile.

jerstlouis avatar jerstlouis commented on September 9, 2024 1

@vincentsarago The spec says they are the same tile. It might be good to clarify that the first one (((int)(col / c)) * c) should be the one that clients look for, and that servers SHOULD redirect to the first one, but MAY return a 4xx for the non-canonical tile.

from morecantile.

AndrewAnnex avatar AndrewAnnex commented on September 9, 2024

@vincentsarago this would actually be neat to see implemented. By looking at that section I basically see that depending on the row you just lower the matrixWidth by dividing it by the coalescence coefficient, eg if in top row and c =4 you would have width/4 martixWidth. I'm looking at figure 8 to understand this, but no idea if it really is as easy as dividing the matrixWidth within morecantile. It also looks like Figure E.1 has a figure about how to scale the coefficients to be closer to equal area, and figure E.3 has a good visual for how the tiles look in equirectangular projection and example confs

from morecantile.

vincentsarago avatar vincentsarago commented on September 9, 2024

@AndrewAnnex 🙏

There is a OGC sprint coming in June https://developer.ogc.org/sprints/21/ where the variable matrix width will be the topic of one specific codesprint: https://portal.ogc.org/public_ogc/register/230612tiling_codesprint.php

I'm not sure if I can make it right now, but you seem pretty interested in the subject and having a POV from someone not only interested in the Earth would be super valuable 🙏

from morecantile.

jerstlouis avatar jerstlouis commented on September 9, 2024

@AndrewAnnex

It's actually very simple.

For rows where a coalescing factor is set, that many tiles will be coalesced into a single tile, with the same number of pixels as usual, but covering the horizontal extent of all of these tiles.

As an example, for a row with c=2, two 256x256 tiles covering 45 degrees x 45 degrees become a single 256x256 tile covering 45 degrees of latitude by 90 degrees of longitude.

I will be participating in the code sprint and happy to help clarify and answer any questions.

We also have an example tileset here:

https://maps.gnosis.earth/ogcapi/collections/blueMarble/map/tiles/GNOSISGlobalGrid

And an example variable width TMS definition here:

https://maps.gnosis.earth/ogcapi/tileMatrixSets/GNOSISGlobalGrid

(as defined in section E.1)

You can also use the following to get a particular level for the GNOSIS Global Grid in GeoJSON:

Level 0:

https://maps.gnosis.earth/ogcapi/dggs/GNOSISGlobalGrid/zones.geojson?zone-level=2&compact-zones=false

http://geojson.io/#data=data:text/x-url,https://maps.gnosis.earth/ogcapi/dggs/GNOSISGlobalGrid/zones.geojson%3Fzone-level%3D0%26compact-zones%3Dfalse

Level 1:

https://maps.gnosis.earth/ogcapi/dggs/GNOSISGlobalGrid/zones.geojson?zone-level=1&compact-zones=false

http://geojson.io/#data=data:text/x-url,https://maps.gnosis.earth/ogcapi/dggs/GNOSISGlobalGrid/zones.geojson%3Fzone-level%3D1%26compact-zones%3Dfalse

Level 2:

https://maps.gnosis.earth/ogcapi/dggs/GNOSISGlobalGrid/zones.geojson?zone-level=2&compact-zones=false

http://geojson.io/#data=data:text/x-url,https://maps.gnosis.earth/ogcapi/dggs/GNOSISGlobalGrid/zones.geojson%3Fzone-level%3D2%26compact-zones%3Dfalse

from morecantile.

vincentsarago avatar vincentsarago commented on September 9, 2024

I've added some test and put the PR as ready to review.

if someone want to tests that will be awesome, else I'll just assume that I understood the spec correctly 😅

import morecantile
tms = morecantile.tms.get("GNOSISGlobalGrid")

tms.xy_bounds(0, 0, 0)
>> BoundingBox(left=-180.0, bottom=0.0, right=-90.0, top=90.0)

tms.xy_bounds(0, 0, 1)
>> BoundingBox(left=-180.0, bottom=45.0, right=-90.0, top=90.0)

tms.xy_bounds(1, 0, 1)
>> BoundingBox(left=-180.0, bottom=45.0, right=-90.0, top=90.0)
morecantile tms --identifier GNOSISGlobalGrid | morecantile tms-to-geojson --level 2 --collect | gist

https://gist.github.com/vincentsarago/36d1dafc34be6b2ba9fd926bae8f07fa

Screenshot 2023-07-21 at 6 27 03 PM

from morecantile.

jerstlouis avatar jerstlouis commented on September 9, 2024

@vincentsarago The level 2 grid looks right! Those 3 set of values look OK.

Tile (col: 1, row: 0, level: 1) does not exists (it is an alias to the tile to its left just above (col: 0, row: 0, level: 1) as you did correctly.

Will this also work automatically with the CDB1GlobalGrid? (the other variable width TMS: https://maps.gnosis.earth/ogcapi/tileMatrixSets/CDB1GlobalGrid)

Thank you very much for working on this!
It would be interesting to have feedback on how difficult it proved to be, and if something in particular would be helpful to include in a user guide to be easier to understand.

cc @jeffharrison @ayoumans @joanma747

from morecantile.

vincentsarago avatar vincentsarago commented on September 9, 2024

Will this also work automatically with the CDB1GlobalGrid? (the other variable width TMS: https://maps.gnosis.earth/ogcapi/tileMatrixSets/CDB1GlobalGrid)

Yes, it's added to the default TMS in morecantile https://github.com/developmentseed/morecantile/blob/main/morecantile/data/CDB1GlobalGrid.json

It would be interesting to have feedback on how difficult it proved to be, and if something in particular would be helpful to include in a user guide to be easier to understand.

This is how I did it https://github.com/developmentseed/morecantile/blob/38b35d159d5d0ea167f4171fe4f87a6d92a39f1d/morecantile/models.py#L924-L931C10

To me it might be easier to understand how it work by providing some pseudo code.

Another pain point for me was testing, to make sure I was doing the right thing 😅

Tile (col: 1, row: 0, level: 1) does not exists (it is an alias to the tile to its left just above (col: 0, row: 0, level: 1) as you did correctly.

I think the spec says it exist but it has the same bounds as the tile 0,0,1. I think it might be just different wording.

from morecantile.

jerstlouis avatar jerstlouis commented on September 9, 2024

I think the spec says it exist but it has the same bounds as the tile 0,0,1. I think it might be just different wording.

Right. The important thing is that when generating a tileset (or when a client request tiless), you do not generate the alias tile as well as the "real" tile.
Otherwise that will completely defeat the purpose of variable width, since you are re-duplicating the same data :D

from morecantile.

vincentsarago avatar vincentsarago commented on September 9, 2024

Right. The important thing is that when generating a tileset (or when a client request tiless), you do not generate the alias tile as well as the "real" tile.
Otherwise that will completely defeat the purpose of variable width, since you are re-duplicating the same data :D

ah, I was more under the impression that it's up to the client to not call the tile 😬

Not sure about the tileset, if I remember well the tileset specification says you need provide min/max row/col so it's the same issue it's up to the client to know the tilematrixset and not ask for alias tiles.

from morecantile.

jerstlouis avatar jerstlouis commented on September 9, 2024

@vincentsarago

I was mainly mentioning this for the case of a an offline tileset batch producer (not sure whether morecantile is used for this or not), where you definitely don't want to produce those extra tiles as it will make the resulting tileset larger than it needs to be, which is a key thing that the VW TMS try to avoid.

For a server, ideally it would return a 3xx redirect to the correct tile. For an on-demand server / block storage, you ideally want to avoid extra cache usage or processing overhead from generating duplicate tiles. Our own implementation doesn't quite do that yet :)

from morecantile.

vincentsarago avatar vincentsarago commented on September 9, 2024

I was mainly mentioning this for the case of a an offline tileset batch producer (not sure whether morecantile is used for this or not), where you definitely don't want to produce those extra tiles as it will make the resulting tileset larger than it needs to be, which is a key thing that the VW TMS try to avoid.

Maybe it is, I guess I will have to fix the TileMatrixSet.tiles() methods

for z in zooms:
nw_tile = self.tile(
w + LL_EPSILON, n - LL_EPSILON, z
) # Not in mercantile
se_tile = self.tile(e - LL_EPSILON, s + LL_EPSILON, z)
minx = min(nw_tile.x, se_tile.x)
maxx = max(nw_tile.x, se_tile.x)
miny = min(nw_tile.y, se_tile.y)
maxy = max(nw_tile.y, se_tile.y)
for i in range(minx, maxx + 1):
for j in range(miny, maxy + 1):
yield Tile(i, j, z)

which for now will return all the tiles.

Q: @jerstlouis, how do you decide which tile is an alias and which is not? is this defined in the spec? (like 1,0,1 is an alias of 0,01 but what about 3,0,1, is it the alias of 2,0,1 or the contrary?

For a server, ideally it would return a 3xx redirect to the correct tile. For an on-demand server / block storage, you ideally want to avoid extra cache usage or processing overhead from generating duplicate tiles. Our own implementation doesn't quite do that yet :)

🙏

from morecantile.

jerstlouis avatar jerstlouis commented on September 9, 2024

@vincentsarago

is this defined in the spec?

I am not 100% clear whether it is well stated in the spec, but my understanding is that the left-most tile is the one that exists i.e., integer division by the calescence factor, then multiplying again by the coalescence factor.
e.g., for GNOSIS Global Grid, the northernmost tiles are always power of two (2 ^ level) multiplied by 0, 1, 2 or 3.

3,0,1, is it the alias of 2,0,1 or the contrary?

col: 3, row: 0, level: 1, is an alias for col: 2, row: 0, level: 1 for the GGG.

from morecantile.

vincentsarago avatar vincentsarago commented on September 9, 2024

To me it feel kinda weird still because the TileMatrix spec says there are matrixWidth*matrixHeight tiles for a particular level but then with the idea of alias we add a discrimination between real and alias tiles. I guess going back to your original question

t would be interesting to have feedback on how difficult it proved to be, and if something in particular would be helpful to include in a user guide to be easier to understand.

It would be helpful to clarify the real vs alias tiles and if it's up to the client or the application to handle the generation of such a tile.

from morecantile.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.