Select to view content in your preferred language

Use different CRS value for specific layer

280
1
Jump to solution
07-17-2024 05:00 AM
Labels (1)
rubenhesselink
New Contributor

esri-leaflet version: 3.0.12

leaflet version: 1.9.4

 

Hello there! I am creating a map with multiple overlay layers.

The base map is using the default CRS value of leaflet and this renders without any problems. But when I try to overlay a layer with a different CRS value for example the following arcgis map: https://tiles.arcgis.com/tiles/nSZVuSZjHpEZZbRo/arcgis/rest/services/Historische_tijdreis_2023/MapSe...
It will give me a 404 not found when switching to this specific layer.

(Failed to load resource: the server responded with a status of 404 (https://tiles2.arcgis.com/tiles/nSZVuSZjHpEZZbRo/arcgis/rest/services/Historische_tijdreis_2023/MapS...))

I load my basemap as follows:

this.leafletMap = L.map(config["map-element-id"], {
  attributionControl: false,
  zoomSnap: 0.1,
  crs: L.CRS.EPSG3857, // Use default CRS for base map layer
  layers: [L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png")],
});


And switch the layer looks like this:

this.historicalCrs = new L.Proj.CRS(
  "EPSG:28992",
  "+proj=sterea +lat_0=52.1561605555556 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +towgs84=565.4171,50.3319,465.5524,1.9342,-1.6677,9.1019,4.0725 +units=m +no_defs +type=crs",
  {
    origin: [-3.05155E7, 3.1112399999999993E7],
    resolutions: [
      3251.206502413005,
      1625.6032512065026,
      812.8016256032513,
      406.40081280162565,
      203.20040640081282,
      101.60020320040641,
      50.800101600203206,
      25.400050800101603,
      12.700025400050801,
      6.350012700025401,
      3.1750063500127004,
      1.5875031750063502,
    ]
  }
);

updateHistoricalLayer(element) {
  const self = this;
  if (this.activeHistoricalLayer) {
    this.leafletMap.removeLayer(this.activeHistoricalLayer);
    this.activeHistoricalLayer = null;
  }
  for (const index in this.historicalLayers) {
    const layer = this.historicalLayers[index];
    if (layer.id === element.value) {
      if (layer.wms) {
        this.activeHistoricalLayer = L.tileLayer.wms(layer.wms, {
          layers: layer.layer,
        });
      } else if (layer.wmts) {
        this.activeHistoricalLayer = L.esri.tiledMapLayer({
          url: "https://tiles.arcgis.com/tiles/nSZVuSZjHpEZZbRo/arcgis/rest/services/Historische_tijdreis_2023/MapServer",
          # crs: this.historicalCrs, TRIED ADDED IT HERE BUT DOESN'T DO ANYTHING
          continuousWorld: true,
        });
      }
      if (this.activeHistoricalLayer) {
        if (layer.wmts) {
          this.leafletMap.options.crs = this.historicalCrs;
        }
        console.log(this.activeHistoricalLayer);
        this.leafletMap.addLayer(this.activeHistoricalLayer);
      }
      document
        .querySelectorAll("input[name=historical-layer-opacity]")
        .forEach((element) => {
          self.setHistorcialLayerOpacity(element);
        });
      break; // Layer found and added, exit loop
    }
  }
}


I know my problem has something to do with the projection (CRS) but I cannot figure out what exactly is going wrong. And I would really appreciate it if someone could point me in the right direction.

(If more information/context is needed please let me know and I will provide it)

0 Kudos
1 Solution

Accepted Solutions
GavinRehkemper
Esri Contributor

Hi @rubenhesselink,

Thank you for the question. Please see here for a sample of using a non-mercator projection for a tiled service: https://developers.arcgis.com/esri-leaflet/samples/non-mercator-projection/

Following that sample, using your projection (https://epsg.io/28992), I am getting your layer to work here: https://jsbin.com/cejovuy/2/edit?html,output

 

/* create new Proj4Leaflet CRS:
  1. Proj4 and WKT definitions can be found at sites like https://epsg.io, https://spatialreference.org/ or by using gdalsrsinfo https://www.gdal.org/gdalsrsinfo.html
  2. Appropriate values to supply to the resolution and origin constructor options can be found in the ArcGIS Server tile server REST endpoint (ex: https://tiles.arcgis.com/tiles/qHLhLQrcvEnxjtPr/arcgis/rest/services/OS_Open_Background_2/MapServer).
  3. The numeric code within the first parameter (ex: `27700`) will be used to project the dynamic map layer on the fly
*/
const crs = new L.Proj.CRS(
  "EPSG:28992","+proj=sterea +lat_0=52.1561605555556 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +towgs84=565.4171,50.3319,465.5524,1.9342,-1.6677,9.1019,4.0725 +units=m +no_defs +type=crs",
  {
    origin: [-30515500, 31112399.999999993],
    resolutions: [
      3251.206502413005,
      1625.6032512065026,
      812.8016256032513,
      406.40081280162565,
      203.20040640081282,
      101.60020320040641,
      50.800101600203206,
      25.400050800101603,
      12.700025400050801,
      6.350012700025401,
      3.1750063500127004,
      1.5875031750063502,
    ]
  }
);

const map = L.map("map", {
  crs: crs
}).setView([51.92, 5.2], 3);

// The min/maxZoom values provided should match the actual cache thats been published. This information can be retrieved from the service endpoint directly.
L.esri
  .tiledMapLayer({
    url: "https://tiles.arcgis.com/tiles/nSZVuSZjHpEZZbRo/arcgis/rest/services/Historische_tijdreis_2023/MapServer",
    maxZoom: 11,
    minZoom: 0
  })
  .addTo(map);

 

I hope this helps!
Gavin

View solution in original post

0 Kudos
1 Reply
GavinRehkemper
Esri Contributor

Hi @rubenhesselink,

Thank you for the question. Please see here for a sample of using a non-mercator projection for a tiled service: https://developers.arcgis.com/esri-leaflet/samples/non-mercator-projection/

Following that sample, using your projection (https://epsg.io/28992), I am getting your layer to work here: https://jsbin.com/cejovuy/2/edit?html,output

 

/* create new Proj4Leaflet CRS:
  1. Proj4 and WKT definitions can be found at sites like https://epsg.io, https://spatialreference.org/ or by using gdalsrsinfo https://www.gdal.org/gdalsrsinfo.html
  2. Appropriate values to supply to the resolution and origin constructor options can be found in the ArcGIS Server tile server REST endpoint (ex: https://tiles.arcgis.com/tiles/qHLhLQrcvEnxjtPr/arcgis/rest/services/OS_Open_Background_2/MapServer).
  3. The numeric code within the first parameter (ex: `27700`) will be used to project the dynamic map layer on the fly
*/
const crs = new L.Proj.CRS(
  "EPSG:28992","+proj=sterea +lat_0=52.1561605555556 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +towgs84=565.4171,50.3319,465.5524,1.9342,-1.6677,9.1019,4.0725 +units=m +no_defs +type=crs",
  {
    origin: [-30515500, 31112399.999999993],
    resolutions: [
      3251.206502413005,
      1625.6032512065026,
      812.8016256032513,
      406.40081280162565,
      203.20040640081282,
      101.60020320040641,
      50.800101600203206,
      25.400050800101603,
      12.700025400050801,
      6.350012700025401,
      3.1750063500127004,
      1.5875031750063502,
    ]
  }
);

const map = L.map("map", {
  crs: crs
}).setView([51.92, 5.2], 3);

// The min/maxZoom values provided should match the actual cache thats been published. This information can be retrieved from the service endpoint directly.
L.esri
  .tiledMapLayer({
    url: "https://tiles.arcgis.com/tiles/nSZVuSZjHpEZZbRo/arcgis/rest/services/Historische_tijdreis_2023/MapServer",
    maxZoom: 11,
    minZoom: 0
  })
  .addTo(map);

 

I hope this helps!
Gavin

0 Kudos