Greg Rowles
Greg Rowles

Reputation: 341

No setBounds function for Leaflet imageOverlay

I'm reading an imageOverlay URL from an ArcGIS webserver that uses the leaflet getBound() coordinates as part of the URL (we have large maps that are filtered for the current window 'extent'). Apologies for not including the actual path (I'm working with sensitive client data). Eg:

http://myarcgiswebserver.com/MapServer/export/dpi=96&format=png32&bbox=27.119750976562504%2C-31.194007509998823%2C32.39044189453126%2C-29.692824739380754&size=1719%2C434

[bbox] = current imageBounds

When dragging my map the imageOverlay url is updated correctly but my leaflet window is no longer aligned to the imageBound values that were set when first adding the imageOverlay which results in a skewed output (this is my assumption):

image of skewed results when i drag my map

The only workaround is to remove the existing imageOverlay and add a new one (which ruins the user experience as the map disappears then reappears each time the window is dragged or zoomed).

Am i approaching this problem incorrectly or would the introduction of a function to update the current imageBounds resolve this? Perhaps not a new function but the expansion of setUrl with additional parameters...?

Many thanks for any feedback...

Upvotes: 1

Views: 1538

Answers (2)

IvanSanchez
IvanSanchez

Reputation: 19069

As @ghybs pointed out, your use case might be better served by using the WMS interface of your ArcGIS server.

Anyway, you say

The only workaround is to remove the existing imageOverlay and add a new one (which ruins the user experience as the map disappears then reappears each time the window is dragged or zoomed).

Well, that glitch is due to you probably doing something like:

  • Remove old overlay
  • Add new overlay
  • Wait until the image is received from the network
  • Wait one frame so the new overlay is shown

and instead you should be doing something like:

  • Add new overlay
  • Wait until the image is received from the network
  • Remove old overlay
  • Wait one frame so the new overlay is shown

The problem is just the async wait and the possible race conditions there, but should be easy to hack together, e.g.:

var activeOverlay = null;
var overlayInRequest = null;

map.on('moveend zoomend', {

    // If we are already requesting a new overlay, ignore it.
    // This might need some additional debouncing logic to prevent
    // lots of concurrent requests
    if (overlayInRequest) {
        overlayInRequest.off('load', showOverlay);
    }

    overlayInRequest = L.imageOverlay( computeUrl( map.getBounds() ), myOverlayOptions );
    overlayInRequest.on('load', showOverlay);
});

function showOverlay(ev) {
    activeOverlay.remove();
    activeOverlay = overlayInRequest;
    activeOverlay.addTo(map);
    overlayInRequest = undefined;
}

Upvotes: 1

ghybs
ghybs

Reputation: 53185

If you use an ImageOverlay but change its url dynamically, with a new image that reflects a new bounding box, then indeed that is the reason for the behaviour you describe: you display an image that has been generated using a new bbox, but positioned in the initial bbox, since the image overlay remains at the same geographical position on the map.

Instead, it sounds to me that you should use a TileLayer.WMS.

It would automatically manage the bounding box update for you. You may need to find the correct options to fit your service provider required URL syntax, though.

Example: http://playground-leaflet.rhcloud.com/yel/1/edit?html,output

Upvotes: 1

Related Questions