1

I am trying to change the coordinate system in Leaflet using proj4 and proj4leaflet.

If I execute this code

proj4.defs("EPSG:20538","+proj=utm +zone=38 +ellps=krass +towgs84=-43,-163,45,0,0,0,0 +units=m +no_defs +type=crs");

var crs = new L.Proj.CRS('EPSG:20538',
proj4.defs('EPSG:20538'),
{
    origin: [0, 0],
    resolutions: [
        4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 0.5
    ],
    bounds: L.bounds([52393.99, -190270.05], [1221571.98, 1338148.68])
});

let map = L.map('map', {
    zoom: 6,
    crs: crs,
    minZoom: 2,
    maxZoom: 20,
    maxBoundsViscosity: 1.0,
    // worldCopyJump: true,
    attributionControl:false,
    zoomControl: false,
    almostSamplingPeriod: 10,
    almostDistance: 25
});

then everything works, the coordinate system is changed.

You can see it in the screenshots below. Image from https://epsg.io/ and my map

epsg.io

my_map

But if I try to load data from JSON file on the server like this

let map = L.map('map', {
    zoom: 6,
    minZoom: 2,
    maxZoom: 20,
    maxBoundsViscosity: 1.0,
    // worldCopyJump: true,
    attributionControl:false,
    zoomControl: false,
    almostSamplingPeriod: 10,
    almostDistance: 25
});

async function applyCrsToMap(data) {
    if (data.name === "EPSG:3857") {
        map.options.crs = L.CRS.EPSG3857;
    } else {
        proj4.defs(data.name, data.proj4);
        
        let newCrs = new L.Proj.CRS(data.name, proj4.defs(data.name), {
            origin: [0, 0],
            resolutions: [
                2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 0.5
            ],
            bounds: L.bounds(data.bounds[0], data.bounds[1])
        });

        map.options.crs = newCrs;
    }

I get the wrong image on the map. A rectangle of solid color in the middle of an empty map.

enter image description here

It disappears if I zoom out of the map. Nothing works and the map is gone. My wms server is working and configured correctly, it outputs the correct tiles as in the first case. In the second case I am just loading data from a json file and I don't understand why it doesn't work. The data comes in JSON format for proj:

"EPSG:2001": {
      "name": "EPSG:2001",
      "proj4": "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995 +x_0=400000 +y_0=0 +a=6378249.145 +rf=293.465 +towgs84=-255,-15,71,0,0,0,0 +units=m +no_defs +type=crs",
      "center": [423637.34, 1888160.65],
      "bounds": [[405547.46, 1872662.17], [441754.25, 1903675.41]]
    }

I have a WMS server: L.tileLayer.wms.

function setWMSLayer(theme) {
    if (!theme.includes("SeaChart_")) theme = "SeaChart_" + theme;
    const url = `http://${FLASK_HOST}/cgi-bin/mapserv?map=/var/www/s57demo/data/map/${theme}.map`;
    wmsLocal.setUrl(url);
    wmsLocal.setParams({
        layers: theme
    });
}

const wmsLocal = L.tileLayer.wms('', {
    noWrap: false
});

It uploads .map files with the configuration of my map layers. Each .map file looks something like this:


MAP
    NAME SeaChart_DAY_BLACKBACK
    SIZE 1000 1000
    UNITS dd
    EXTENT -180 -90 180 90
    MAXSIZE 32768
    # CONFIG "MS_OPENLAYERS_JS_URL" "http://localhost/LocalOpenLayers/OpenLayers-ms60.js"
    CONFIG "MS_ERRORFILE" "/tmp/SeaChart_DAY_BLACKBACK.log"
    DEBUG 5
    CONFIG "ON_MISSING_DATA" "LOG"
    #RESOLUTION 96
    #DEFRESOLUTION 96

    PROJECTION
         'init=epsg:4326'
    END

    IMAGETYPE png
    FONTSET './fonts/fontset.lst'
    SYMBOLSET "./symbols/symbols-day.map"
    OUTPUTFORMAT
        NAME 'AGG'
        DRIVER AGG/PNG
        IMAGEMODE RGB
    END

    SHAPEPATH "../chart"

    WEB
        IMAGEPATH '/tmp/'
        IMAGEURL '/tmp/'

        METADATA
          "ows_enable_request"   "*"
          'ows_title'           'SeaChart_DAY_BLACKBACK'
          # 'ows_onlineresource'  'http://localhost/cgi-bin/mapserv.fcgi?map=/app/output/map/SeaChart_DAY_BLACKBACK.map&'
          "wms_srs" "EPSG:4326 EPSG:3857 EPSG:2950 EPSG:2949 EPSG:32188 EPSG:32187 EPSG:42403 EPSG:3857 EPSG:3979"
          "wfs_srs" "EPSG:4326 EPSG:3857 EPSG:2950 EPSG:2949 EPSG:32188 EPSG:32187 EPSG:42403 EPSG:3857 EPSG:3979"
          "labelcache_map_edge_buffer" "10"
          "wms_bbox_extended" "true"
        END
    END

    #
    #   Dummy layer to create a layer group for the color mode
    #
    LAYER
        NAME "DAY_BLACKBACK"
        GROUP "default"
        TYPE POINT
        TRANSFORM FALSE
        STATUS ON
        FEATURE
            POINTS 1 1 END
        END
    END

    #INCLUDE_GSHHS_HERE

END # Map

I use MapServer to load map tiles at this path - http://${FLASK_HOST}/cgi-bin/mapserv?map=/var/www/s57demo/data/map/${theme}.map.

I think the problem in Leaflet but I don't understand what exactly the problem is.

7
  • 1
    Please edit your code with how, where and when you create you layer.
    – TomazicM
    Commented Aug 7 at 15:31
  • Edited. Please, can you see?
    – bobr
    Commented Aug 8 at 5:42
  • Layers are loaded when the map starts.
    – bobr
    Commented Aug 8 at 5:45
  • Complete workflow of your app is not clear from your code above. If layers load successfully at the start and you then to try to change projection for the same layers, this is not possible in Leaflet. In Leaflet raster layers can be shown only in their native projection. If your WMS layer has projection EPSG:4326, it can be shown only in the map with this projection.
    – TomazicM
    Commented Aug 8 at 7:34
  • 1
    You can change CRS dynamically, but not for the layers that were displayed in previous CRS. This would mean reprojecting layers to different CRS, but Leaflet can't do that (but it's possible in OpenLayers). You would have to remove those layers and add layers that have this new CRS.
    – TomazicM
    Commented Aug 8 at 8:45

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.