I’m working on using leaflet to render a large rectangular game map, so using a TileLayer is the only reasonable option. Unfortunately I’m having a devil of a time getting the 3 different coordinate systems (game, image, and leaflet) aligned in a reasonable way. There’s… something about this all that I’m not understanding despite having read many, many SO posts and various other sources of information about CRS.Simple
, L.TileLayer
, L.transformation
, and etc.
Here’s roughly the code I’m working with:
// These values correspond to the bounds of the in-game map
const GAME_MIN_X = -2438281.4186383262;
const GAME_MIN_Y = -1129394.0806274635;
const GAME_MAX_X = 201600;
const GAME_MAX_Y = 504000;
// The size of the source image for the tiles
const IMG_MAX_X = 16384;
const IMG_MAX_Y = 5223;
// Maximum x/y values assuming a range starting at 0
const MAX_X = GAME_MAX_X - GAME_MIN_X;
const MAX_Y = GAME_MAX_Y - GAME_MIN_Y;
// Scale factor for the transformation, see https://gis.stackexchange.com/a/201037
const scaleX = 1 / (MAX_X / IMG_MAX_X);
const scaleY = 1 / (MAX_Y / IMG_MAX_Y);
const crs = L.extend(L.CRS.Simple, {
transformation: L.transformation(
scaleX,
0,
scaleY,
0
),
});
var map = L.map('map', {
crs,
maxZoom: 6,
});
const tiles = L.tileLayer("https://patcavit.com/tiles/{z}/{y}/{x}.png", {
errorTileUrl: "https://patcavit.com/tiles/blank.png",
minNativeZoom: 0,
maxNativeZoom: 6,
noWrap: true,
bounds: [
// Using MAX_* shows a lot of blank tiles
[MAX_Y, 0],
[0, MAX_X],
// Using GAME_MAX_* shows a lot of blank tiles
// [ GAME_MAX_Y, 0 ],
// [ 0, GAME_MAX_X ],
// Using IMG_MAX_* leads to only one tile being shown
// [ IMG_MAX_Y, 0 ],
// [ 0, IMG_MAX_X ]
],
});
tiles.addTo(map);
map.setView([0, 0], 0);
Here’s a live, editable version
I suspect that there’s a small part of the transformation
on the CRS
or how I’m defining bounds
on the TileLayer
that is tripping up literally everything else, but I’m kind of at my wit’s ends here.
For context, the MAX_Y
and MAX_X
values are me trying to scope the range of my points to start from 0 because that seems to play better with the TileLayer
bits, but that could just be me misunderstanding things. I’d love to not need it, as it makes turning game coordinates into map coordinates a tiny bit inconvenient.