I'm trying to figure out how can I use Planetary computer as a provider of tiles.
I found how can I get links for a particular region, but unfortunately, Planetary Computer has a different format of URLs that supported by WebTileLayer.
examples of URLs -
https://planetarycomputer.microsoft.com/api/data/v1/item/tiles/WebMercatorQuad/{z}/{x}/{y}@1x?collec...
https://planetarycomputer.microsoft.com/api/data/v1/item/tiles/WebMercatorQuad/{z}/{x}/{y}@1x?collec...
As you can see the only difference is "item", but seems that WebTileLayer works with subdomains only.
Can anyone recommend which layer to use or how I can tweak WebTileLayer to work not with subdomains.
I already tried:
let customTileLayer = WebTileLayer.createSubclass({
properties: {
urlTemplate: "https://planetarycomputer.microsoft.com/api/data/v1/item/tiles/WebMercatorQuad/undefined/undefined/undefined@1x?collection=3dep-lidar-returns&item={subDomain}&assets=data&colormap_name=lidar-returns&nodata=-9999",
subDomains: ['VA_UpperMiddleNeckQL2_B2_2018-dsm-2m-1-1', 'VA_UpperMiddleNeckQL2_B2_2018-dsm-2m-1-2']
},
getTileUrl: function (level: any, row: any, col: any) {
return this.urlTemplate.replace("{z}", level).replace("{x}", col).replace("{y}", row);
}
});
but it is not working
The WebTileLayer supports the zxy format so something like this should work:
let customTileLayer = new WebTileLayer({
urlTemplate: "https://planetarycomputer.microsoft.com/api/data/v1/item/tiles/WebMercatorQuad/{z}/{x}/{y}@1x?collection=3dep-lidar-returns&item=VA_UpperMiddleNeckQL2_B2_2018-dsm-2m-1-2&assets=data&colormap_name=lidar-returns&nodata=-9999"
});
However, the service is returning this error:
No item 'VA_UpperMiddleNeckQL2_B2_2018-dsm-2m-1-2' found in '3dep-lidar-returns' collection
...so the URL parameters are not correct.
strange, I copied these names...
anyway, seems that I got a conception of WebTileLayer incorrectly, the intention of this layer is to load tiles from different subdomains in parallel, right?
But my intention was - to load tiles from different URLs for some particular boundary box and seems that I "found" a way how to do this, but this solution is working pretty bad so far
// tileObjects - array of objects with fields { bbox: number[]; link: string }
let customTileLayer = BaseTileLayer.createSubclass({
properties: {
urlTemplate: null
},
getTileUrl: function (level: any, row: any, col: any) {
let tileUrl = '';
const bounds = this.getTileBounds(level, row, col);
// probably I missed something but getTileBounds() returns not lat/lon coordinates but a diffrent projection, like [-13227886.366918996, 4011415.244407987, -13208318.487677995, 4030983.123648987]
let outSpatialReference = new SpatialReference({
wkid: 3857
});
tileObjects.forEach(tileObject => {
// change coordinates projection
const objBbox = self.extentToBbox(projection.project(self.bboxToExtent(tileObject.bbox), outSpatialReference));
// if tile boundary box belongs to boundary box of particular "item" in planetary computer collection
if (self.rectanglesIntersect(objBbox, bounds) || self.rectanglesIntersect(bounds, objBbox)) {
tileUrl = tileObject.link;
}
});
return tileUrl.replace("{z}", level).replace("{x}", col).replace("{y}", row);
}
});
Two more URLs to load items:
https://planetarycomputer.microsoft.com/api/data/v1/item/tiles/WebMercatorQuad/{z}/{x}/{y}@1x?collec...
https://planetarycomputer.microsoft.com/api/data/v1/item/tiles/WebMercatorQuad/{z}/{x}/{y}@1x?collec...
with tiles -
https://planetarycomputer.microsoft.com/api/data/v1/item/tiles/WebMercatorQuad/11/348/818@1x?collect...
https://planetarycomputer.microsoft.com/api/data/v1/item/tiles/WebMercatorQuad/11/348/817@1x?collect...
so, item names would be ['USGS_LPC_CA_LosAngeles_2016_LAS_2018-dtm_native-2m-1-9', 'USGS_LPC_CA_LosAngeles_2016_LAS_2018-dtm_native-2m-1-10']
I guess I need to work on math with fitting different "items" to each other(boundaries intersection).
If I'm wrong and you know a better way - let me know, please
Correct, the data you're trying to load seems to represent two distinct datasets and the way to configure each one is via the URL parameters and not as part of the base URL, so you will need two different layers. It always helps is you have a simple CodePen or similar showing us what you're trying, that way we can better understand your issues.
Not sure if this helps as I'm not familiar enough with this service, but here's an example of how you can extend the BaseTileLayer to access the service and use custom parameters:
https://codepen.io/john-grayson/pen/VwXWbjK