Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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?

share|improve this question
add comment

5 Answers 5

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.

share|improve this answer
    
Seen anyone do it with Leaflet? –  alexgleith Apr 17 '13 at 6:38
    
@alexgleith Have a look at this:groups.google.com/forum/#!msg/leaflet-js/vXU_bir6JsA/… –  Devdatta Tengshe Apr 17 '13 at 8:15
add comment

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.

share|improve this answer
    
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. –  alexgleith Apr 17 '13 at 23:14
add comment

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

share|improve this answer
    
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. –  alexgleith Apr 24 '13 at 6:41
add comment

Have a look at WMS Split for Leaflet.

share|improve this answer
add comment

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 
        );
    }); 
share|improve this answer
    
Have you got a complete example? How do you set up the two maps to swipe between? –  alexgleith 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? –  alexgleith 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? –  alexgleith Apr 18 '13 at 22:51
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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