1

I want to create a side-by-side leaflet map and I use the resources available on github (https://github.com/digidem/leaflet-side-by-side). I have downloaded the code locally and I have created a map with two different sides. I have also added a button to activate and de-activate the splitter (when the splitter is off, there is only one map). I have also created a marker and a circle. The left map should show openstreetmap basemap, the right one (Google Maps basemap with the marker and the circle). When there is no splitter (side by side), the basemap should be Google Maps, and only the marker should be shown.

enter image description here

Based on the instructions on github, I can add an array of layers (e.g. rightLayers) but it seems that I miss something. I tried the following but I got an error.

sideBySideControl = L.control.sideBySide(openstreetmap, [googleSat, circle]).addTo(map);

This is the error:

Uncaught TypeError: this._leftLayer.getContainer is not a function
    at i._updateClip (leaflet-side-by-side.js:135:23)
    at i._updateLayers (leaflet-side-by-side.js:167:10)
    at i.addTo (leaflet-side-by-side.js:89:10)
    at HTMLButtonElement.toggleSplitter (my_first_map_v2_splitter_toggle_button.html:74:91)

I have attached the entire code below.

<!DOCTYPE html>
<html>
<head>
    <title>Simple Leaflet Map Example</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
    <link rel="stylesheet" href="leaflet-side-by-side-gh-pages\leaflet-side-by-side-gh-pages\range.css" />
    <link rel="stylesheet" href="leaflet-side-by-side-gh-pages\leaflet-side-by-side-gh-pages\layout.css" />
    <style>
        #map { height: 400px; }
        #toggleSplitterBtn {
            position: absolute;
            top: 10px;
            right: 10px;
            z-index: 1000;
            background-color: #fff;
            padding: 5px 10px;
            border: 1px solid #ccc;
            cursor: pointer;
        }
    </style>
</head>
<body>

<div id="map"></div>
<button id="toggleSplitterBtn">Toggle Splitter</button>

<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="lib/leaflet-geoserver-request-master/leaflet-geoserver-request-master/src/L.Geoserver.js"></script>
<script src="leaflet-side-by-side-gh-pages/leaflet-side-by-side-gh-pages/leaflet-side-by-side.js"></script>
<!-- <script src="data/buildings.js"></script> -->


<script>
    // Initialize the map
    var map = L.map('map').setView([35.5, 23.92], 14);// Centered at (latitude, longitude) and zoom level
    
    // Add a tile layer (OpenStreetMap)
    var openstreetmap = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 25,
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);


    var googleSat = L.tileLayer('http://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',{
    maxZoom: 20,
    subdomains:['mt0','mt1','mt2','mt3']
    }).addTo(map)

    var marker_1 = L.marker([35.5, 24]).addTo(map)
        .bindPopup('Hello, I am a marker!').openPopup();

    var circle = L.circle([35.5, 23.98], {
        color: 'red',
        fillColor: '#f03',
        fillOpacity: 0.5,
        radius: 500
    }).addTo(map).bindPopup('I am a circle - hello .');


    var sideBySideControl = null; // Define a variable to hold the control instance

    // Function to toggle the side-by-side control
    function toggleSplitter() {
        if (sideBySideControl) {
            map.removeControl(sideBySideControl);
            sideBySideControl = null;
        } else {
            
            sideBySideControl = L.control.sideBySide(openstreetmap, googleSat,).addTo(map);
        }
    }

    // Event listener for the button
    document.getElementById('toggleSplitterBtn').addEventListener('click', toggleSplitter);
    

</script>

</body>
</html>
0

1 Answer 1

4

Leaflet side-by-side plugin is a bit outdated for newer versions of Leaflet. You can find updated plugin code in the answer to this question: imageOverlay is not working with Leaflet side-by-side.

To use updated plugin you have to create two map panes (for example named 'left' and 'right') and use them when creating all layers to be used. That goes even for the marker popup.

So in your case complete code would look something like this:

<!DOCTYPE html>
<html>
<head>
  <title>Simple Leaflet Map Example</title>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
  <style>
    #map { height: 400px; }
    #toggleSplitterBtn {
        position: absolute;
        top: 10px;
        right: 10px;
        z-index: 1000;
        background-color: #fff;
        padding: 5px 10px;
        border: 1px solid #ccc;
        cursor: pointer;
    }
    .rightPopup {
      z-index: 750;
    }
  </style>
</head>
<body>

<div id="map"></div>
<button id="toggleSplitterBtn">Toggle Splitter</button>

<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="lib/leaflet-side-by-side/leaflet-side-by-side.js"></script>

<script>
  var map = L.map('map').setView([35.5, 23.92], 14);// Centered at (latitude, longitude) and zoom level

  map.createPane('left');
  map.createPane('right');
  
  var openstreetmap = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    pane: 'left',
    maxZoom: 25,
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
  }).addTo(map);


  var googleSat = L.tileLayer('http://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',{
    pane: 'right',
    maxZoom: 20,
    subdomains:['mt0','mt1','mt2','mt3']
  }).addTo(map)

  var marker_1 = L.marker([35.5, 24], {
    pane: 'right'
  }).addTo(map).bindPopup('Hello, I am a marker!', {
    pane: 'right',
    className: 'rightPopup'
  }).openPopup();

  var circle = L.circle([35.5, 23.98], {
    pane: 'right',
    color: 'red',
    fillColor: '#f03',
    fillOpacity: 0.5,
    radius: 500
  }).addTo(map).bindPopup('I am a circle - hello .');


  var sideBySideControl = null;

  function toggleSplitter() {
    if (sideBySideControl) {
      map.removeControl(sideBySideControl);
      sideBySideControl = null;
    } else {          
      sideBySideControl = L.control.sideBySide(openstreetmap, googleSat).addTo(map);
    }
  }
  document.getElementById('toggleSplitterBtn').addEventListener('click', toggleSplitter);
</script>

</body>
</html>

This is how side-by-side map looks like then:

enter image description here

enter image description here

1
  • It works like a charm! Commented Dec 25, 2023 at 21:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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