I'm currently working on a webmapping application dedicated to warehouse management. Where data is based on indoor geolocation and Cartesian coordinates system.

More precisely, the map background is built from a LiDAR survey. I have a dedicated backend that creates a raster file then generate tiles with the gdal2tiles-leaflet script.

My web client consume these tiles with Leaflet TileLayer. But since my GeoJSON objects are stored with Cartesian coordinates I needed to set up a conversion mechanism based on raster-coords.

My current architecture could be sum up with this diagram: enter image description here

But I don't think this implementation is either efficient or robust (here I think about the conversion work).

So I would like to know if something else different is possible. I am wondering myself if an other solution wouldn't be to convert coordinates in WGS84 and use GeoServer to directly serve the tiles as a WMS service.


One possibility would be to use Leaflet's L.CRS.Simple flat (Cartesian) CRS. Here one pixel corresponds to one map unit.

Let's say we want map units that correspond to original rasters map pixels (before it was cut to tiles): one map unit is one pixel on original raster. With tile layer at zoom level 0 whole map is within 256 x 256 pixels, so factor for desired map units is factor = 256 / maxWidthHeight, where maxWidthHeight is the bigger of raster width and height.

Leaflet will use this factor in all coordinate calculation if we change L.CRS.Simple definition by extending it and changing transformation method:

L.CRS.myCRS = L.extend({}, L.CRS.Simple, {
  transformation: new L.Transformation(factor, 0, factor, 0)

Origin of our coordinate system wil be in top left corner, x going to the right and y down (because third parameter in transformation has positive value) and coordinates will be in the form [y, x] (that's how L.CRS.Simple is defined).

Let's see how this works on leaflet-rastercoords plugin example https://commenthol.github.io/leaflet-rastercoords/example/index.html. Here original raster is 3831 x 3101 pixels, so factor would be 0.06682 = 256 / 3831. Since actual map at zoom 0 is narrower that tile width (see below), if we want to have lower right corner at [3101, 3831], the correct factor is 0.062495.

enter image description here

This is the whole code:

var width = 3831;
var height = 3101;
var factor = 0.062495;

L.CRS.myCRS = L.extend({}, L.CRS.Simple, {
  transformation: new L.Transformation(factor, 0, factor, 0)
var map = L.map('map', {
  crs: L.CRS.myCRS
}).setView([height/2, width/2], 2);

L.tileLayer('https://commenthol.github.io/leaflet-rastercoords/example/tiles/{z}/{x}/{y}.png', {
  minZoom: 0,
  maxZoom: 5,
  noWrap: true

map.on('click', function (event) {
  var coords = event.latlng;
  var marker = L.marker(coords).addTo(map);
  marker.bindPopup('[' + Math.floor(coords.lat) + ',' + Math.floor(coords.lng) + ']').openPopup();

On map click marker is created and popup displayed with marker coordinates.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.