-
Notifications
You must be signed in to change notification settings - Fork 6
Tiling #29
Comments
Mapbox Vector Tiles seem to be gaining traction as a standard format for vector tiles: https://www.mapbox.com/developers/vector-tiles/. |
With #49 it becomes easy to define a tileset matrix, meaning a collection of "zoom" levels: {
"type" : "CoverageCollection",
"domainType": "Grid",
"referencing": [{
"components": ["x","y"],
"system": {
"type": "GeodeticCRS",
"id": "http://www.opengis.net/def/crs/OGC/1.3/CRS84"
}
}, {
"components": ["t"],
"system": {
"type": "TemporalRS",
"calendar": "Gregorian"
}
}],
"parameters" : {
"air_temp": {
"type" : "Parameter",
"description" : {
"en": "The air temperature measured in degrees Celsius."
},
"unit" : {
"label": {
"en": "Degree Celsius"
},
"symbol": {
"value": "Cel",
"type": "http://www.opengis.net/def/uom/UCUM/"
}
},
"observedProperty" : {
"id" : "http://vocab.nerc.ac.uk/standard_name/air_temperature/",
"label" : {
"en": "Air temperature",
"de": "Lufttemperatur"
}
}
}
},
"coverages": [{
"type" : "Coverage",
"domain" : {
"type": "Domain",
"axes": {
"x": { "start": -179.5, "stop": 179.5, "num": 360 },
"y": { "start": -89.5, "stop": 89.5, "num": 180 },
"t": { "values": ["2016-01-01T00:00:00Z", "2016-01-01T06:00:00Z"] }
}
},
"ranges" : {
"air_temp" : {
"type": "TiledNdArray",
"axisNames": ["t","y","x"],
"shape": [2, 180, 360],
"tileSets": [{
"tileShape": [1, 60, 60],
"urlTemplate": "http://example.com/weather/temperature/0/{t}/{x}/{y}.covjson"
}]
}
}
}, {
"type" : "Coverage",
"domain" : {
"type": "Domain",
"axes": {
"x": { "start": -179.5, "stop": 179.5, "num": 720 },
"y": { "start": -89.5, "stop": 89.5, "num": 360 },
"t": { "values": ["2016-01-01T00:00:00Z", "2016-01-01T06:00:00Z"] }
}
},
"ranges" : {
"air_temp" : {
"type": "TiledNdArray",
"axisNames": ["t","y","x"],
"shape": [2, 360, 720],
"tileSets": [{
"tileShape": [1, 60, 60],
"urlTemplate": "http://example.com/weather/temperature/1/{t}/{x}/{y}.covjson"
}]
}
}
}, {
"type" : "Coverage",
"domain" : {
"type": "Domain",
"axes": {
"x": { "start": -179.5, "stop": 179.5, "num": 1440 },
"y": { "start": -89.5, "stop": 89.5, "num": 720 },
"t": { "values": ["2016-01-01T00:00:00Z", "2016-01-01T06:00:00Z"] }
}
},
"ranges" : {
"air_temp" : {
"type": "TiledNdArray",
"axisNames": ["t","y","x"],
"shape": [2, 720, 1440],
"tileSets": [{
"tileShape": [1, 60, 60],
"urlTemplate": "http://example.com/weather/temperature/2/{t}/{x}/{y}.covjson"
}]
}
}
}]
} |
And I think this would be a good candidate for a "profile", e.g. "HorizontalTileMatrixSet" or whatever, which would say that this is such a tile matrix set and that all coverages must have the same axis names and parameters, that they have TiledNdArray as range type with always the same axis order, and that all "tileShape"s are identical. Also, that the zoom happens on the horizontal spatial axes and the others stay identical. And I included only a single tile set in the example above, but there could be more, and these would have to be consistent between the coverages. So, lots of constraints. Of course, you could be pragmatic and just include at the root |
Given that Google Maps etc use a single tileset specification to cover tiling in x, y and zoom, I'm wondering if we can just extend the syntax in #49? For example a tileset could also contain a "zoomLevel" property, where zoom level 0 means sample every pixel in a particular dimension, zoom level 1 means sample every alternate pixel, etc. "shape": [2, 720, 1440],
"tileSets": [{
"tileShape": [1, 60, 60],
"urlTemplate": "http://example.com/weather/temperature/2/{t}/{x}/{y}.covjson",
"zoom": [0,2,2] // means not zoomed in t, but zoomed to level 2 in x and y
}] Of course, if I haven't thought this through properly, so there may be a big problem here! |
I'm not sure how that "zoom" thing would translate to a single URL template, since you have zoom per axis and not a single spatial zoom as in google maps. |
The idea was that you could have multiple tilesets for a range, each at a different zoom level. So a zoom of [0,1,1] means "all tiles in this set sample every point in t, but every alternate point in x and y". Then you could have another tileset with zoom=[0,2,2], etc, but the same tileShape. The default zoom level (if not specified) would be [0,0,0]. But I'd need to write this out in full to be sure that it works. |
I think having something like "zoom" in a tileset is not a good idea as it would mean that you can define tilesets which don't give you all range data. It kind of violates the contract that the range has to match the domain. |
Good point that the domain and range won't match in a zoomed tileset. Maybe the CoverageCollection is the way to go. And yes, a profile could be useful here. |
Closing this since the goal was simply to explore whether zoom-style tiling can be expressed in some way, and coverage collections were identified as one way to do it. |
The goal of this issue is not to create a tiling specification for CoverageJSON but to make sure that it is possible to do so by exploring several scenarios.
TorqueMaps / TorqueTiles
As a first example, we look at CartoDB's TorqueTiles and see how this maps to CoverageJSON concepts.
TorqueTiles is based conceptually on TileMaps of TMS:
Conceptually, a tile layer of a TorqueMap corresponds to a CoverageJSON X-Y-T grid with a specific spatial resolution. Each tile is then a spatial subset of that grid, and is again a CoverageJSON X-Y-T grid.
For efficiency reasons, a physical CoverageJSON tile would not correspond to a full subsetted CoverageJSON coverage document, but rather a tile would only be the range of that grid coverage. This makes sense, since the domains of the layers would have been established in the TileMap document, equal to TorqueMaps.
It seems that conceptually this kind of spatial X-Y tiling with an additional T dimension is not problematic and would be compatible to how CoverageJSON is defined.
Vector-like tiling
Tiling could also be specific in terms of individual coverages which are located in a certain X-Y spatial tile. This is similar to vector-based tiling (see GeoJSON-VT, or Google Maps) where features are cut off at tile boundaries.
This is definitely more tricky to realize than TorqueTiles. It means that you need to have algorithms to cut off any coverage types that are defined in CoverageJSON, for a generic implementation. Supposing that a tile is simply a Coverage collection, the challenge is also whether and how to logically match up the individual parts of one coverage, like a trajectory, and what happens when you click on parts of a coverage. You still want to get a full plot for a trajectory etc.
One way to do it would be to simply use standard index-based subsetting on the coverage domains. While this is simple for grids, it may be a bit trickier for domains with a composite axis like trajectories. It could happen that point 1 and 3 of a trajectory are in a given tile, but point 2 are in the neighbor tile. Would the subsetted trajectory then contain points 1 and 3? Merging this together again may be tricky.
TBD
The text was updated successfully, but these errors were encountered: