Reputation: 2720
I'm using GeoServer MVT layers in OpenLayers and to add them to the map I just do:
const source = new VectorTileSource({
url:`${geoserverUrl}/gwc/service/tms/1.0.0/myworkspace:mylayer@EPSG%3A900913@pbf/{z}/{x}/{-y}.pbf`,
format: new MVT(),
wrapX: true,
tileGrid: createXYZ({ maxZoom: 19 })
});
const layer = new VectorTileLayer({
className: "myLayer",
source: source,
minResolution: 0,
maxResolution: 2,
style: myStyle(),
visible: true
});
So far so good. Now I would like to use the tileUrlFunction instead of defining the url attribute as I would like to define a different layer in the url based on the zoom level, and for that I used the following function that I called in the attribute tileUrlFunction of the new VectorTileSource
instantiation:
const tileUrlFunction = (tileCoord) => {
if (tileCoord[0] > 18) {
return `${geoserverUrl}/gwc/service/tms/1.0.0/myworkspace:layer1@EPSG%3A900913@pbf/${tileCoord[0]}/${tileCoord[1]}/${tileCoord[2]}.pbf`;
} else {
return `${geoserverUrl}/gwc/service/tms/1.0.0/myworkspace:layer2@EPSG%3A900913@pbf/${tileCoord[0]}/${tileCoord[1]}/${tileCoord[2]}.pbf`;
}
};
};
The problem is that when using tileUrlFunction, on render, I get a wrong y value (corresponding to tileCoord[2]).
When using ${geoserverUrl}/gwc/service/tms/1.0.0/myworkspace:mylayer@EPSG%3A900913@pbf/{z}/{x}/{-y}.pbf
I get for instance the coordinates /18/258309/98012.pbf and the tile renders correctly on the map, when I use the tileUrlFunction I get the wrong y 18/2258309/164130.pbf, and the tile fails to render.
I noticed that if I don't put the dash in the y when defining the url "...@EPSG%3A900913@pbf/{z}/{x}/{-y}.pbf", I also get the same wrong value.
Reading the docs I can see that
Grids like TMS where x 0 and y 0 are in the bottom left can be used by using the {-y} placeholder in the URL template, so long as the source does not have a custom tile grid
I'm quite sure this issue is related to the definition of the tileGrid, but I don't know how to make the function tileUrlFunction to work.
Upvotes: 1
Views: 910
Reputation: 17907
OpenLayers will be passing the tile coordinates for an XYZ source. To convert to TMS use
const z = tileCoord[0];
const x = tileCoord[1];
const y = Math.pow(2, z) - tileCoord[2] - 1;
Upvotes: 1