Search code examples
javascriptleafletproj4js

trying to use EPSG:3857 in Leaflet


I am trying to make leaflet use EPSG:3857 as an input coordinate system. I use porj4leaflet to achieve this. I have defined my map instance like this:

var map = L.map('map', {
center: [8378860.13, 1481133.311008498],
zoom: 7,
crs: new L.Proj.CRS(
  'EPSG:3857',
  '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs',
    {
      resolutions: [
        8192, 4096, 2048, 1024, 512, 256, 128
      ],
      origin: [0, 0]
    }
  )
});

When I try to run this, i get TypeError: coordinates must be finite numbers. You can see the entire fiddle here: https://jsfiddle.net/asdpinspdai/fckbpq0a/

Of what I understand from the docs, setting the crs like this should allow me to pass coordinates to leaflet in the EPSG:3857 format. Am I missing something?

Any help here is very, very appriciated. Thank you


Solution

  • The "finite numbers" error is because L.Map expects the center coordinates to be in the range -90 to 90 and -180 to 180 degrees.

    In your jsfiddle, you also have the problem that you are selecting zoom:11, but only have 7 zoom levels available in your CRS definition.

    The Leaflet API always uses WGS84 latitude/longitude coordinates in degrees, so using Proj4leaflet this way won't do what you want. See this explanation from the Proj4Leaflet project.

    However, EPSG:3857 is already the default CRS in Leaflet, and you can use its built-in methods to convert between meters and WGS84 degrees, without needing either Proj4Leaflet or Proj4js. See the Leaflet CRS documentation.

    const proj = L.CRS.EPSG3857;
    
    // Degrees to metres
    proj.project(new L.LatLng(51,-2));             // {x: -222638.98158654, y: 6621293.722740}
    
    // Metres to degrees
    proj.unproject(new L.Point(-222600, 6621000)); // {lat: 50.998339473, lng: -1.99964982245}
    

    It's probably easiest to unproject your metre coordinates to WGS whenever you need to pass them to Leaflet, but alternatively you could write overridden versions of some of Leaflet's functions. These would take metre coordinates, convert them to degrees, then pass them on the original function.