Search code examples
leafletarcgisproj4js

How to figure out resolution array from user inputted ArcGIS projection data


I have a Leaflet based mapping solution that uses ArcGIS map configuration supplied by a user (I have no idea what it will be, they will customize it with their own ArcGIS services). The issue is that the projection can be pretty much anything, and I will need to use Proj4Leaflet to configure the CRS of the map accordingly. The problem I'm running into is I'm not sure how to calculate the scale/resolution array. The user is inputting these values: projection key, Proj4 string, origin, bounds, zoom levels.

So, for example (yes I know EPSG:3857 is standard and I could just use L.CRS.EPSG3857 but it serves as a good example of how to set the same thing up using Proj4Leaflet):

Projection key = EPSG:3857
Proj4 string = +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
Origin = [0,0]
Bounds = [[-20026376.39, -20048966.10], [20026376.39, 20048966.10]]
Zoom levels = 18

With that I think I have enough to set up a L.Proj.CRS for it:

var 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 : [?????],
    origin : [0,0],
    bounds : [[-20026376.39, -20048966.10], [20026376.39, 20048966.10]]
});

I have everything I need apart from the resolutions array, I am not sure exactly how to go about setting that up based on the data given and having a hard time finding answers to get me pointed in the right direction.


Solution

  • So bottom line, the only way I found to calculate resolutions is if it is a mercator projection and we know the longitude extents of it and the tile size. Otherwise the resolutions will need to be looked up at the ArcGIS Server tile server REST endpoint. Thus for my project I will need the user to supply the array themselves and cannot calculate it for them.

    In the case of the mercator projection, I came up with this function that does the trick:

    function parseResolutionsFromZoomLevels(zoomLevels, tileSize, mapWGS84Extent)
    {
        var metersPerExtent = 40075008/360;     
        var mapWGS84Meters = mapWGS84Extent*metersPerExtent;
        var resolutionArray = [];
    
        for (var i=0; i<zoomLevels; i++)
        {
            var tilesAtZoom = Math.pow(2,i);
            var pixelsAtZoom = tilesAtZoom*tileSize;
    
            resolutionArray.push(mapWGS84Meters/pixelsAtZoom);
        }
    
        return resolutionArray;
    }
    

    Hope this helps anyone else that happens to encounter this same situation.