I have an OpenLayers map (version 9.1) that consumes GeoServer layers in EPSG:900913 projection (OpenLayers uses the compatible EPSG:3857 as it's default map projection).
There are two gridsets on GeoServer for 900913, there's EPSG 900913 and EPSG 900913x2. My understanding is that the regular 900913 gridset returns [256, 256] tile sizes, while 900913x2 returns [512, 512] tile sizes, making it more well suited for high resolution screens.
I saw this example on OpenLayers about how to setup your layers for high DPI screens and it manipulates the tilePixelRatio value of a WMTS source to serve 512x512 tiles on a 256x256 grid.
My thought is that when setting up a tile grid for a WMTS source, couldn't you just swap between the 900913 and 900913x2 gridsets depending on what the user's DEVICE_PIXEL_RATIO is? If it's 2+, you'd create the tile grid using 900913x2 and if it's 1 you'd create the tile grid with 900913, but I'm not sure I understand this correctly. This is my current code to create a WMTSTileGrid.
export const createTileGrid = (extent: Extent) => { //Setup basic layer parameters for web map tile services const projection = getProjection('EPSG:900913'); const projectionExtent = projection?.getExtent(); let tileSize: Array<number>; let size: number; let matrixSet: string; //Determine if using high resolution screen, then create tile grid if (DEVICE_PIXEL_RATIO > 1) { matrixSet = 'EPSG:900913x2'; size = getWidth(projectionExtent ? projectionExtent : []) / 512; tileSize = [512, 512]; } else { matrixSet = 'EPSG:900913'; size = getWidth(projectionExtent ? projectionExtent : []) / 256; tileSize = [256, 256]; } let resolutions = new Array(31); let matrixIds = new Array(31); for (let z = 0; z < 31; ++z) { resolutions[z] = size / Math.pow(2, z); matrixIds[z] = `${matrixSet}:` + z; } const tile_grid = new WMTSTileGrid({ origin: getTopLeft(projectionExtent ? projectionExtent : []), extent: extent, tileSize: tileSize, resolutions: resolutions, matrixIds: matrixIds, }); return tile_grid; }; I'm not really seeing any problems display-wise with my code above, but I'm more interested to know that what I'm doing is actually valid for handling low and high DPI displays or if there is a better way to go about this.