简体   繁体   中英

How to replace default leaflet.control to the set of individual buttons

I have three base layers and three layers with markers on my map. Now I'm switching between them using standart leaflet control. I need to replace it to the set of individual buttons for each layer at the bottom of my map. It should looks like in the picture below: 个别按钮

Can somebody tell me how to replace default leaflet control

L.control.layers(baseLayers, overlays).addTo(map);

to the set of custom buttons? Here is my fiddle: http://jsfiddle.net/anton9ov/eu1840f1/

Also I need to add an initial value to the selector in the top left. The first value from the JSON is coming there now, but I need to replace it to something like «choose a place».

To create a centered control like you have in your mockup, you can adapt this solution that @ghybs posted for a previous question. Basically, you create a css class to center controls within the map pane:

.leaflet-horizontalcenter {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  padding-top: 10px;
}

.leaflet-horizontalcenter .leaflet-control {
  margin-bottom: 10px;
}

then create a new placeholder with that class attached to the map container:

function addControlPlaceholders(map) {
  var corners = map._controlCorners,
    l = 'leaflet-',
    container = map._controlContainer;

  function createCorner(vSide, hSide) {
    var className = l + vSide + ' ' + l + hSide;
    corners[vSide + hSide] = L.DomUtil.create('div', className, container);
  }
  createCorner('horizontalcenter', 'bottom');
}
addControlPlaceholders(map);

You can use any method you like for creating the buttons, but this codepen example shows a reasonably straightforward way to style radio buttons as rectangular boxes. Creating a custom control with these buttons would go like this:

var buttonBar = L.control({
  position: 'horizontalcenterbottom'
});

buttonBar.onAdd = function(map) {
  //create div container for control
  var div = L.DomUtil.create('div', 'myButtonBar');
  //prevent mouse events from propagating through to the map
  L.DomEvent.disableClickPropagation(div);
  //create custom radio buttons
  div.innerHTML = '<div class="switch-field noselect"><div class="switch-title">MAPS</div>'
    + '<input type="radio" id="switch_map1" name="map_switch" checked/>'
    + '<label for="switch_map1">Map 1</label>'
    + '<input type="radio" id="switch_map2" name="map_switch" />'
    + '<label for="switch_map2">Map 2</label>'
    + '<input type="radio" id="switch_map3" name="map_switch" />'
    + '<label for="switch_map3">Map 3</label></div>'
    + '<div class="switch-field noselect">'
    + '<input type="radio" id="switch_marker1" name="marker_switch" checked/>'
    + '<label for="switch_marker1">Marker 1</label>'
    + '<input type="radio" id="switch_marker2" name="marker_switch" />'
    + '<label for="switch_marker2">Marker 2</label>'
    + '<input type="radio" id="switch_marker3" name="marker_switch" />'
    + '<label for="switch_marker3">Marker 3</label>'
    + '<div class="switch-title">MARKERS</div></div>';
  return div;
};

buttonBar.addTo(map);

This is a bit less convenient than the standard layer control, since you have to enter the button names etc. manually, but with a little more work, this could be done programmatically from the baseLayers and overlays objects you've already created. If you want to create a box around the buttons to visually isolate it from the map, you can also add some css like this to style the div created for the control:

.myButtonBar {
    background: white;
    box-shadow: 0 1px 7px rgba(0, 0, 0, 0.25);
    -webkit-border-radius: 4px;
    border-radius: 4px;
    text-align: center;
    padding: 0px 10px;
    position: relative;
}

Finally, to get the layers to change when buttons are clicked, you attach some event listeners. Since you are already using jQuery, we'll just use that:

$("#switch_map1").click(function() {
  switchLayer(baseLayers, "Map 1");
});
$("#switch_map2").click(function() {
  switchLayer(baseLayers, "Map 2");
});
$("#switch_map3").click(function() {
  switchLayer(baseLayers, "Map 3");
});
$("#switch_marker1").click(function() {
  switchLayer(overlays, "Marker 1");
});
$("#switch_marker2").click(function() {
  switchLayer(overlays, "Marker 2");
});
$("#switch_marker3").click(function() {
  switchLayer(overlays, "Marker 3");
});

where switchLayer is a function that gets the layer from a baseLayers or overlays object based on its key, then adds it to the map and removes the others:

function switchLayer(collection, layerKey) {
  if (layerKey in collection) {
    $.each(collection, function(key, layer) {
      if (key === layerKey) {
        if (!map.hasLayer(layer)) {
          map.addLayer(layer);
        }
      } else if (map.hasLayer(layer)) {
        map.removeLayer(layer);
      }
    });
  } else {
    console.log('There is no layer key by the name "' + layerKey + '" in the specified object.');
  }
}

Here is all this working together in a fiddle:

http://jsfiddle.net/nathansnider/j0abypqf/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM