1

I am creating a leaflet application that uses various data sources / map layers. I found a great source for global ground cover from esri. It is an imageLayer. Using an esri-leaflet imageLayer, I am able to add this layer to my map. My application will likely need to draw data from various raster layers like this one. I am also able to load an urban-wildland boundary layer as an esri-leaflet featureLayer.

I am also using leaflet-active-area, which is a plugin that shifts the center and bounds of the map to the div of your choosing. I love this plugin for creating a better UI experience.

The featureLayer works just fine in conjunction with the activeArea. However, the imageLayer is having problems. It seems that the imageLayer is calculating what section of the layer should be currently in the map based on the original map bounds, but then squishing the image itself into the activeArea div. Check it out:

enter image description here

Working demo of the problem

I made a codesandbox that shows this problem. There is a 'toggle activearea' button there, so you can see how the imageLayer works properly when not using the activearea, but has this issue when using it.

What might be going wrong here? What is it about an imageLayer (or its underlying L.ImageOverlay) that it knows to sample the correct bounds from the entire map, but then it squishes it into the activearea, instead of the total area? I tried using other types of esri layers (L.esri.tiledMapLayer, L.esri.dynamicMapLayer, etc.) but these don't work as they are not the correct functions to recieve and apply this layer source. I don't want to give up my activearea, but I'm going to need to apply and ready from raster layers in my application. Ideas?

Thanks for reading.

Edit: altering codesandbox to use public esri imagemaplayer

I had been using an auth-requires esri imagemaplayer in my initial example, which had my personal client_id and client_secret exposed. I changed it to use a public layer for esri so people can still view the problem. Also,

Here is a codesandbox with the patch / fix js file

But thanks to TomazicM for getting to the crux of the matter.

1
+50

Problem stems from the fact that esri-leaflet image layer is calling Leaflet map getBounds() method, which is modified by leaflet-active-area plugin to return only active area bounds instead of map bounds. As a consequence ESRI image layer is rendered inside active area only.

Brute force method to remedy this is to modify getBounds() method again and in case of ESRI layer use normal getBounds() procedure. To detect that getBounds() method is called from esri-leaflet plugin, I'm using hacking method of checking call stack for esri string. This is dependant on implementation and should be changed accordingly.

So to achieve desired behavior, the following code has to be placed before map definition:

L.Map.include({
  getBounds: function() {
    var trace = new Error().stack;
    if (this._viewport && (trace.search(/esri/i) == 0)) {
      return this.getViewportLatLngBounds();
    } else {
      var bounds = this.getPixelBounds(),
      sw = this.unproject(bounds.getBottomLeft()),
      ne = this.unproject(bounds.getTopRight());
      return new L.LatLngBounds(sw, ne);
    }
  }
});
| improve this answer | |
  • Yes! This does it. I knew the answer was related to the way L.esri.RasterLayer uses getBounds, and the fact that activeArea modifies it, but I got lost trying to pinpoint how to separate them out. The only thing about your answer is that it uses Error().stack, which mozilla says its a big no no in production code. I recycled some of your code and did some L.esri.RasterLayer.include({ ... }), making it more production-friendly. Its a little messy, but it works the same. Check it out – Seth Lutske Mar 18 at 18:10
  • I do feel like the way I wrote my L.esri.RasterLayer.modification file might not be the most slim it can be. I end up importing a bunch of things from leaflet and esr-leaflet just to make sure they're in the namespace, even though they're already imported when leaflet and esr-leaflet are imported. This would enlarge the bundle size. If you're curious, any ideas how to streamline this, without importing these components again in my modification file? – Seth Lutske Mar 18 at 18:17
  • I see you went for esri-leaflet plugin modification, which is the right way, I just didn't want to touch it beacuse it's more complex. Since I'm not familiar with Node.js environment, I can't comment on your implementation. As for using Error().stack method, I knew it's questionable, it was just quick momentary hack (at my job :-). – TomazicM Mar 18 at 19:07
0

I finally got around to making an npm package to fix this issue. You can check it out here:

esri-leaflet-active-area-patch

Maybe I'll get around to putting in a PR to the esri-leaflet repo one day so that you don't need to use the patch. Until then, its available for the one in a million chance someone else needs it.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.