Is it possible in Leaflet or OpenLayers to compare two maps with a bar to slide between the two?

Examples include:

I know it's possible, I don't know how to do it though. Anyone got any ideas? Examples?

  • 1
    the Hurricane Sandy link seems to be dead now. Is this a better link to demonstrate the idea? – Stephen Lead Sep 28 '17 at 3:42
  • That works, I'll replace the other link @StephenLead – Alex Leith Sep 28 '17 at 6:39

What you want to do, is usually called a 'Swipe' tool.

There is no inbuilt tool or control for this in OpenLayers, but thankfully, there is an example here: Swipe Control with Google and OSM based on a custom class.

You just need to include this JavaScript file in your application.

Most Swipe Tools/controls that I have seen online, are based on the simple CSS clip. It is very simple to integrate this kind of Control in your application even without external patches.

Mango does it with Leaflet. Check out an example here.

Of course you could just save the time to code it yourself and just create the map for free using Mango.

  • That's a nice looking interface! But there's no reusable code there... I want something that is internal to our organisation, and I have already got infrastructure in place for styling and hosting data. – Alex Leith Apr 17 '13 at 23:14

This is a working Leaflet example using two WMS layers and leaflet 0.5. It does need a bit of tweaking, for example the layers aren't clipped while panning. But it works pretty well.

See here: https://github.com/gccgisteam/leaflet-examples/blob/master/leafletSwipe.html

  • I don't know if you are the author, but I'll give you two suggestions: Firstly using the Move event rather then the MoveEnd event gives real time swiping & secondly, I feel this is the opposite way of how a tool should be used. Instead of dragging the map, the slider should be dragged. – Devdatta Tengshe Apr 24 '13 at 4:48
  • I actually like having both the slider at the bottom and the on mouse move. It means that with a mouse you get it working all the time, and with touch, you can still do it. I only just got it together, it is a proof of concept only. I'm sure there are a lot of options. – Alex Leith Apr 24 '13 at 6:41

Have a look at WMS Split for Leaflet.

We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is right, ideally with citations. Answers that don't include explanations may be removed.

it is possible with leaflet. here what I done the swipe map with leaflet and jquery.

$(document).ready(function() {
        var currentX = $("#viewport").width() / 2;
        var resetPosition = function(x){
            var pos = $(".leaflet-map-pane").position(),
            coordLeft = ( - pos.top ) + "px, " + ( x - pos.left + 3 ) + "px, " + ( $("#viewport").height() - pos.top ) + "px, " + -pos.left + "px",
            coordRight = ( - pos.top ) + "px, " + ( $("#viewport").width() - pos.left ) + "px, " + ( $("#viewport").height() - pos.top ) + "px, " + ( x - pos.left + 3 ) + "px";
            $(".leaflet-layer:nth-child(3)").css("clip", "rect(" + coordLeft + ")");
            $(".leaflet-layer:nth-child(2)").css("clip", "rect(" + coordRight + ")");
        };
        resetPosition(currentX);
        map.on("move", function(){
            resetPosition(currentX);
        })
        map.on("zoomend", function(){
            resetPosition(currentX);
        });
        if( $.browser.msie && parseInt($.browser.version) < 9 ){
            $("#vbar-divider").draggable({
                drag: function(e){
                    currentX = $("#vbar-divider").position().left;
                    resetPosition(currentX);
                },
                axis: "x"
            });
        }else{
            $("#vbar-divider").draggable({
                drag: function(e){
                    currentX = $("#vbar-divider").position().left;
                    resetPosition(currentX);
                    $("#vbar-divider div").hide();
                },
                stop: function(){
                    $("#vbar-divider div").show();
                },
                axis: "x",
                containment: "parent"
            });
        }
        $('#vbar-divider').animate({
                left: currentX,
            }, 
            500 
        );
    }); 
  • Have you got a complete example? How do you set up the two maps to swipe between? – Alex Leith Apr 18 '13 at 3:23
  • you don't need two maps, what you need is one map with two layers, $(".leaflet-layer:nth-child(3)").css("clip", "rect(" + coordLeft + ")"); $(".leaflet-layer:nth-child(2)").css("clip", "rect(" + coordRight + ")"); – khousuylong Apr 18 '13 at 3:57
  • Ok, where (2) and (3) refer to layers 2 and 3 in order of adding to map? – Alex Leith Apr 18 '13 at 4:04
  • the above code is up and running, what you need first is create a map and add two layers, then with jquery you can get the container of top layer and second top layer. using "css" clip to clip the two containers accordingly – khousuylong Apr 18 '13 at 4:15
  • Ok, so I have a naive implementation here: jsfiddle.net/Ah6Bx what is missing? – Alex Leith Apr 18 '13 at 22:51

You should probably look into OpenLayers 3. You can look at the code of examples by using CTRL + U: The code does not look too complex either:

http://openlayers.org/en/v3.1.1/examples/layer-swipe.html

I am using a nice Openlayers 3 and 4 extensions by viglino. You can find the examples of Swipe tool and Synchronized maps here.

http://viglino.github.io/ol3-ext/examples/map.control.swipe.html

http://viglino.github.io/ol3-ext/examples/map.interaction.synchronize.html

His GitHub repository is located here: https://github.com/Viglino/ol3-ext

Those examples are included in the GitHub repository.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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