Esri / esri-leaflet

A lightweight set of tools for working with ArcGIS services in Leaflet. :rocket:

Home Page:https://developers.arcgis.com/esri-leaflet/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

proj4 is not defined in TiledMapLayer

theashyster opened this issue · comments

  • Browser and version:
    Any browser you like
  • Version of Leaflet (L.version):
    1.2.0
  • Version of esri Leaflet (L.esri.VERSION):
    2.1.1
  • Steps to reproduce the error:
  1. Use Leaflet and esri-leaflet together with proj4leaflet
  2. proj4leaflet has a dependency of proj4
  3. Import proj4leaflet AMD style without importing proj4 manually anywhere else since proj4leaflet will pick it up from dependencies and will work fine

What happens is that when doing this I will get an error on this line https://github.com/Esri/esri-leaflet/blob/master/src/Layers/TiledMapLayer.js#L141 saying Uncaught ReferenceError: proj4 is not defined.

I was expecting for this to work fine, since only the proj4leaflet library is dependant on proj4 and esri-leaflet is not.

It is quite hard to replicate this problem using jsbin, since I use npm and package.json and webpack.

  • Optional: I'm not using the CDN, I'm loading/bundling the library using:
    Webpack

Adding this as a workaround helps to get it work and no errors are shown, but I think that should not be required for esri-leaflet to work without issues.

import * as proj4 from 'proj4';
window['proj4'] = proj4;

thanks for the report. i'll have to think about how we might make this check more friendly for bundlers.

luckily the issue is pretty benign (ie: we're just logging an irrelevant error in the console in some situations where proj4 is available).

@jgravois No problem, that would be awesome.
Yeah, nothing big, but still everybody likes their code not to throw errors you cannot control. 😄

Btw, I played around with it a bit this morning and adding something like this on top of that check for proj4 worked for me - var proj4 = window.proj4 || require('proj4');

Yeah, but I guess it won't work in a situation when you don't have proj4 added at all, then the require will fail quite hard. Tried different ways, even with a try / catch around the require, but it still did not work for me if I tried to require something like proj4x.

took me awhile to look at this, but today i rewrote our custom projection check to stop worrying about whether proj4 is present entirely.

how i learned to stop worrying

@jgravois I'm getting proj4 is not defined error. Did you fix this....do I need the latest leaflet library?

TiledMapLayer.js:136 Uncaught ReferenceError: proj4 is not defined
    at NewClass.<anonymous> (https://cdn.jsdelivr.net/leaflet.esri/2.0.8/esri-leaflet.js:4:29721)
    at NewClass.<anonymous> (https://cdn.jsdelivr.net/leaflet.esri/2.0.8/esri-leaflet.js:4:20023)
    at Object.window._EsriLeafletCallbacks.(anonymous function) [as c1] (https://cdn.jsdelivr.net/leaflet.esri/2.0.8/esri-leaflet.js:4:2602)

Live in production issue
https://www.nwfsc.noaa.gov/data/map

go to Essential Fish Habitat (EFH) Catalog
then click on Amendment 19
then click on EFH 700 ftm bottom trawl closure

the fix has landed in master but i haven't tagged a release yet.

that said, its not going to solve your problem. besides the cryptic error you see in the console, your tiledMapLayer isn't displaying because you can't mix and match tiled services that use the Web Mercator coordinate system used by Google/Bing/ArcGIS Online with ones that don't.

you have to either:

  1. exclusively use tiled services in the same CRS (and one Leaflet supports out of the box)
  2. use a plugin like proj4 to define a custom CRS for leaflet that matches all the tiled map services you want to display.

What do you recommend? I'm not sure what CRS even is.

Is the mixing and matching tile service issue on the map service side or how I call the map services?

you should ask the data provider to republish their tile services with a tiling scheme that has the same wkid, origin, and levels of detail as our ArcGIS Online basemaps. until they do, you can't mix and match their tile services.

you could use a dynamicMapLayer instead (because they support reprojecting on the fly), but i have a vague recollection that you tried doing that in the past and experienced unusually poor performance.

Yeap, you are right, we did use dynamicMapLayer and had issues...not sure if it was performance
I have notified the data provider, thank you.