Вопрос

I am helping my students with a map of some data related to Hurricane Sandy. They have four tile layers (MapBox Street, MapBox Satellite, NOAA Satellite, and NOAA Inundation) and several vector layers.

When it first loads, the map shows the MapBox Streets tiles with some vector data on top, with the ability to switch to the MapBox Satellite layer as the base map. Users can then add the inundation layer on top of the base map (the inundation layer is complex enough that it needs tiles instead of rendered polygons).

The problem occurs when you switch base map layers after the inundation layer has been added to the map. My students use the L.map.addLayer(data, insertAtTheBottom) function to add the new base map layer to the bottom (after removing the old one), but for some reason the layer is only added below the vector layers and not below the inundation tile layer. When the base layers are switching out you can clearly see that the inundation tile layer is still there, it just won't go on top of the new base layer.

Does anyone know why this is the case? The documentation states that this parameter ensures that the new layer will be added below all other layers.

Live example of the page: http://personal.psu.edu/rsm5068/src/map.html

Relevant code segment

<body>
  <div id="map"></div>
  <div id="controls">
    <input type="checkbox" id="toggleSatellite" /><label for="toggleSatellite">Toggle Satellite</label>
  </div>
  <script type="text/javascript">

    var map = null,
        layerStreets,
        layerSatelliteNow,
        layerSatelliteThen,
        layer1MSurge,
        layer3MSurge,
        lgrpBase,
        lgrpSurge;

    map = L.map("map", {
      'center' : L.latLng(40.7127, -74.0059),
      'zoom' : 10,
      'minZoom' : 9,
      'maxZoom' : 16
    })

    // ---- Tile Layers ----

    layerStreets = L.mapbox.tileLayer("user.id");
    layerSatelliteNow = L.mapbox.tileLayer("user.id");
    layer1MSurge = L.mapbox.tileLayer("user.id");
    layer3MSurge = L.mapbox.tileLayer("user.id");

    lgrpSurge = L.layerGroup();
    lgrpSurge
      .addLayer(layer3MSurge)
      .addLayer(layer1MSurge);

    // ---- Adding Data to Map ----

    map
      .setMaxBounds(L.latLngBounds(L.latLng(40.4600,-74.33),L.latLng(40.9400,-73.667)))
      .addLayer(layerStreets)
      .addLayer(lgrpSurge)
      .addLayer(fgrpEvacCenters);

    // ---- Interactivity ----

    $("#toggleSatellite").change(function () {
      if ($("input[id='toggleSatellite']:checked").length > 0) {
        map
          .removeLayer(layerStreets)
          .addLayer(layerSatelliteNow, true);
      } else {
        map
          .removeLayer(layerSatelliteNow)
          .addLayer(layerStreets, true);
      }
    })
  </script>
</body>
Это было полезно?

Решение

Your Inundation layer should be added to the map as an overlay and not as a basemap (tiled layers can be overlays as well as basemaps).

First you'll want to distinguish between your basemap layers and your overlays.

Your basemap layers (streets, satellite, etc) are those layers that are mutually exclusive and should always be on the bottom.

Your overlay layers are not mutually exclusive and will always sit on top of the basemap layers.

The following example is from the Leaflet LayersControl docs page

var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/API-key/{styleId}/256/{z}/{x}/{y}.png',
    cloudmadeAttribution = 'Map data &copy; 2011 OpenStreetMap contributors, Imagery &copy; 2011 CloudMade';

var minimal   = L.tileLayer(cloudmadeUrl, {styleId: 22677, attribution: cloudmadeAttribution}),
    midnight  = L.tileLayer(cloudmadeUrl, {styleId: 999,   attribution: cloudmadeAttribution}),
    motorways = L.tileLayer(cloudmadeUrl, {styleId: 46561, attribution: cloudmadeAttribution});

var map = L.map('map', {
    center: new L.LatLng(39.73, -104.99),
    zoom: 10,
    layers: [minimal, motorways, cities]
});

var baseMaps = {
    "Minimal": minimal,
    "Night View": midnight
};

var overlayMaps = {
    "Motorways": motorways,
    "Cities": cities
};

L.control.layers(baseMaps, overlayMaps).addTo(map);

At this point, the basemaps (Minimal and Night View) will always be underneath the overlays (Motorways and Cities).

Make sure your Inundation layer is added to the map as an overlay and not a basemap.

Другие советы

This I think is a bug. I have tried it too but it is not working correctly. Please use bringToBack() (or bringToFront() if you want it in front) to force layer to correct position: So: map.addLayer(layerSatelliteNow); layerSatelliteNow.bringToBack();

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top