23 votos

¿Añadir/Eliminar leyenda con el control de capas de Leaflet?

Tengo dos superposiciones http://02d0c8c.netsolhost.com/dev/lcb_census_layers3.html que se puede activar y desactivar con un Control de Capas. Me gustaría que la leyenda de cada capa se activara/desactivara junto con las capas.

Soy nuevo en JavaScript y en Leaflet.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Lake Champlain Basin Census Data</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.5/leaflet.css" />
<!--[if lte IE 8]>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.5/leaflet.ie.css" />
<![endif]-->

<style>
        #map {
            width: 750px;
            height: 580px;
        }
        .info {
            padding: 6px 8px;
            font: 14px/16px Verdana, Geneva, sans-serif;
            background: white;
            background: rgba(255,255,255,0.8);
            box-shadow: 0 0 15px rgba(0,0,0,0.2);
            border-radius: 5px;
        }
        .info h4 {
            font-family: Verdana, Geneva, sans-serif;
            margin: 0 0 5px;
            color: #065581;
        }
        .legend {
            line-height: 18px;
            color: #555;
        }
        .legend i {
            width: 18px;
            height: 18px;
            float: left;
            margin-right: 8px;
            opacity: 0.7;
        }
</style>
<script src="http://cdn.leafletjs.com/leaflet-0.4.5/leaflet.js"></script>
</head>

<body>
<div id="map">
<script type="text/javascript" src="js/LCB_Census_Towns.js"></script>

<script type="text/javascript">

        var map = L.map('map').setView([44.3, -73.1], 8);
        var cloudmade = L.tileLayer('http://{s}.tile.cloudmade.com/d2a498d874144e7dae5e7ab4807f3032/{styleId}/256/{z}/{x}/{y}.png', {
            attribution: 'Map data &copy; 2011 OpenStreetMap contributors, Imagery &copy; 2011 CloudMade',
            key: 'BC9A493B41014CAABB98F0471D759707',
            styleId: 22677
        }).addTo(map);

        // control that shows state info on hover
        var info = L.control({position: 'bottomleft'});

        info.onAdd = function (map) {
            this._div = L.DomUtil.create('div', 'info'); // create a div with a class "info"
            this.update();
            return this._div;
        };

        // method that we will use to update the control based on feature           properties passed
        info.update = function (props) {
            this._div.innerHTML = '<h4>Population Change</h4>' +  (props ?
        '<b>Town: ' + props.NAME10 + '</b><br />Percent change, 1970-2010<br />(2001-2011 in Qu&eacute;bec): <em><strong> ' + props.CHNG_70_10 + '</strong></em>%<br /><br />1970 Population: ' + props.POP1970 + '<br />1980 Population: ' + props.POP1980 + '<br />1990 Population: ' + props.POP1990 + '<br />2000 Population: ' + props.POP2000 + '<br />2010 Population: ' + props.POP2010 
        : '<b>Hover over a town</b>');
        };

        info.addTo(map);

        //STYLES FOR POPULATION CHANGE MAP

        // get color depending on population density value
        function getColor(d) {
            return d > 100  ? '#BD0026' :
                   d > 50  ? '#F03B20' :
                   d > 20  ? '#FD8D3C' :
                   d > 10   ? '#FEB24C' :
                   d > 0   ? '#FED976' :
                   d > -30   ? '#1C9099' :
                              '#1C9099';
        }

        function style(feature) {
            return {
                weight: 2,
                opacity: 1,
                color: 'white',
                dashArray: '3',
                fillOpacity: 0.7,
                fillColor: getColor(feature.properties.CHNG_70_10)
            };
        }

        //STYLES FOR POPULATION MAP

        // get color for Population Map depending on population value
        function getColor2(d) {
            return d > 20000  ? '#006D2C' :
                   d > 10000  ? '#31A354' :
                   d > 5000  ? '#74C476' :
                   d > 2500   ? '#A1D99B' :
                   d > 0   ? '#C7E9C0' :
                              '#1C9099';
        }

        function style2(feature) {
            return {
                weight: 2,
                opacity: 1,
                color: '#666',
                dashArray: '3',
                fillOpacity: 0.7,
                fillColor: getColor2(feature.properties.POP2010)
            };
        }

        //LAYER FUNCTIONALITY

        var popChange = new L.geoJson(lcbCensusData, {
            style: style,
            onEachFeature: function (feature, layer) {
            var defaultStyle = layer.style,
                that = this;//NEW

            layer.on('mouseover', function (e) {
                this.setStyle({
                weight: 5,
                color: '#666',
                dashArray: '',
                fillOpacity: 0.7
                });

            if (!L.Browser.ie && !L.Browser.opera) {
                layer.bringToFront();
            }

                info.update(layer.feature.properties);
            });
            layer.on('mouseout', function (e) {
                popChange.resetStyle(e.target); //NEW
                info.update();
            });
            }
            });

        var population = L.geoJson(lcbCensusData, {
            style: style2,
            onEachFeature: function (feature, layer) {
            var defaultStyle = layer.style,
                that = this;//NEW

            layer.on('mouseover', function (e) {
                this.setStyle({
                weight: 5,
                color: '#666',
                dashArray: '',
                fillOpacity: 0.7
                });

            if (!L.Browser.ie && !L.Browser.opera) {
                layer.bringToFront();
            }

                info.update(layer.feature.properties);
            });
            layer.on('mouseout', function (e) {
                population.resetStyle(e.target); //NEW
                info.update();
            });
            }
            }).addTo(map);

        //LAYER CONTROL 
        var overlays = {
            "Population Change,'70-'10": popChange,
            "Population": population
        };

        L.control.layers(null, overlays, {collapsed: false}).addTo(map);

        // LEGEND
        var legend = L.control({position: 'bottomright'});

        legend.onAdd = function (map) {
        var div = L.DomUtil.create('div', 'info legend');

            div.innerHTML +=
            '<img src="legend.png" alt="legend" width="134" height="147">';

        return div;
        };

        legend.addTo(map);

    </script>
</div>
</body>
</html>

0 votos

¿Tiene la segunda leyenda disponible? 02d0c8c.netsolhost.com/dev/legend.png es el actual.

0 votos

Escribí una respuesta a una pregunta más reciente que también podría ser útil para resolver el problema de esta pregunta, ya que muestra dos jsfiddles que funcionan: gis.stackexchange.com/questions/164755/

24voto

Arthur Puntos 1172

Puedes escuchar el "overlayadd" y/o el "overlayremove" eventos en el objeto mapa y tener definidas dos leyendas distintas (dos controles), por ejemplo

map.on('overlayadd', function (eventLayer) {
    // Switch to the Population legend...
    if (eventLayer.name === 'Population') {
        this.removeControl(populationChangeLegend);
        populationLegend.addTo(this);
    } else { // Or switch to the Population Change legend...
        this.removeControl(populationLegend);
        populationChangeLegend.addTo(this);
    }
});

EDITAR: Un ejemplo más completo:

var populationLegend = L.control({position: 'bottomright'});
var populationChangeLegend = L.control({position: 'bottomright'});

populationLegend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend');
    div.innerHTML +=
    '<img src="legend.png" alt="legend" width="134" height="147">';
return div;
};

populationChangeLegend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend');
    div.innerHTML +=
    '<img src="change_legend.png" alt="legend" width="134" height="147">';
return div;
};

// Add this one (only) for now, as the Population layer is on by default
populationLegend.addTo(map);

map.on('overlayadd', function (eventLayer) {
    // Switch to the Population legend...
    if (eventLayer.name === 'Population') {
        this.removeControl(populationChangeLegend);
        populationLegend.addTo(this);
    } else { // Or switch to the Population Change legend...
        this.removeControl(populationLegend);
        populationChangeLegend.addTo(this);
    }
});

Tenga en cuenta que el this en el oyente de eventos es el objeto mapa, es decir this es lo mismo que map .

0 votos

Gracias, me temo que necesitaré que me echen una mano. Aprecio su ayuda, si usted está tan inclinado ... He definido una segunda leyenda (y cambiado el nombre de la imagen en la primera) aquí < 02d0c8c.netsolhost.com/dev/lcb_census_layers4.html >. ¿Tengo que cambiar la forma de añadir superposiciones al control antes de utilizar el evento overlayadd?

0 votos

Puedes añadir la segunda leyenda del mismo modo que añadiste la primera. Voy a editar mi respuesta para proporcionar un ejemplo más completo.

0 votos

Sí, eso es lo que he intentado sin suerte. ¿Cómo funcionaría la sentencia if/else en el evento overlayadd si ambas capas estuvieran activadas? Parece que la leyenda de cambio de población no se puede añadir mientras la capa de población esté activada. También he probado a utilizar las capas superpuestas como capas base con la alternancia de botones de opción, pero sigue sin funcionar.

0voto

Zeta10 Puntos 238

¡Este código realmente funciona para mí!

    var divLegend = `
        <h4>Legend</h4>
        <div id="marker-geo"><i class="icon" style="background-image: url(./assets/marker.svg);background-repeat: no-repeat;"></i><span>Marker GeoJson (Intersect)</span></div>
        <div id="marker-geo-not-intersect"><i class="icon" style="background-image: url(./assets/marker_green.png);background-repeat: no-repeat;"></i><span>Marker GeoJson (Not Intersect)</span></div>
        <div id="ruas-geo"><i style="background: #3388FF"></i><span>Jalan Nasional dari GeoJson</span></div>
        <div id="ruas-zip"><i style="background: #858585"></i><span>Jalan Nasional dari Zip</span></div>
        <div id="marker-zip"><i class="icon" style="background-image: url(https://unpkg.com/leaflet@1.0.3/dist/images/marker-icon.png);background-repeat: no-repeat;"></i><span>Marker Zip</span></div>
    `

    function stripSpaces(str){
        return str.replace(/\s+/g, '');
    }
var div = L.DomUtil.create("div", "legend");
    div.innerHTML = divLegend;

        L.LegendControl = L.Control.extend({
            onAdd: function (map) {

                return div;
            }
        });

        var strDivMarkerUser = "#"+stripSpaces("marker-user");
        var strDivMarkerGeo = "#"+stripSpaces("marker-geo");
        var strDivRuasGeo = "#"+stripSpaces("ruas-geo");
        var strDivRuasZip = "#"+stripSpaces("ruas-zip");
        var strDivMarkerZip = "#"+stripSpaces("marker-zip");
        var strDivLegend = "#"+stripSpaces("legend");
        var strDivNotIntersectMarker = "#"+stripSpaces("marker-geo-not-intersect");

        $(document).ready(function(){
            $(strDivMarkerUser).hide();
            $(strDivMarkerGeo).hide();
            $(strDivRuasGeo).hide();
            $(strDivRuasZip).hide();
            $(strDivMarkerZip).hide();
            $(strDivLegend).hide();
            $(strDivNotIntersectMarker).hide();
        });

Entonces puedes añadir este código para la lógica de overlayadd

map.on('overlayadd', function (e) {
    $(strDivLegend).show();
    if (e.name == "Marker dari url geojson") {
        $(strDivMarkerGeo).show();
        $(strDivNotIntersectMarker).show();
    }
    if (e.name == "Ruas Jalan dari url geojson") {
        $(strDivRuasGeo).show();
    }
    if (e.name == "Ruas Jalan dari file zip") {
        $(strDivRuasZip).show();
    }
    if (e.name == "Marker dari file zip") {
        $(strDivMarkerZip).show();
    }
})

map.on('overlayremove', function (e) {
    if (e.name == "Marker dari url geojson") {
        $(strDivMarkerGeo).hide();
    }
    if (e.name == "Ruas Jalan dari url geojson") {
        $(strDivRuasGeo).hide();
    }
    if (e.name == "Ruas Jalan dari file zip") {
        $(strDivRuasZip).hide();
    }
    if (e.name == "Marker dari file zip") {
        $(strDivMarkerZip).hide();
    }
})

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X