Como adicionar / remover legenda com controle de camadas de folhetos?


18

Eu tenho duas sobreposições http://02d0c8c.netsolhost.com/dev/lcb_census_layers3.html que podem ser ativadas e desativadas com um controle de camada. Gostaria que a legenda de cada camada fosse ativada / desativada junto com as camadas.

Eu sou novo no JavaScript e novo no 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>

Você tem a segunda legenda disponível? 02d0c8c.netsolhost.com/dev/legend.png é o atual.
Mapperz

Eu escrevi uma resposta a uma pergunta mais recente, que também poderia ser útil para soving o problema desta questão, pois mostra dois jsfiddles de trabalho: gis.stackexchange.com/questions/164755/...
Thomas B

Respostas:


19

Você pode ouvir os eventos "overlayadd" e / ou "overlayremove" no objeto de mapa e ter duas legendas separadas (dois controles) definidas, por exemplo:

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);
    }
});

EDIT: Um exemplo mais 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);
    }
});

Observe que a thispalavra - chave no ouvinte de eventos é o objeto de mapa, ou seja, thisé o mesmo que map.


Obrigado, receio que vou precisar de algumas mãos dadas. Agradeço sua ajuda, se você estiver inclinado ... Definei uma segunda legenda (e alterei o nome da imagem na primeira) aqui < 02d0c8c.netsolhost.com/dev/lcb_census_layers4.html >. Preciso alterar a maneira como adiciono sobreposições ao controle antes de usar o evento overlayadd?
ryan

Você pode adicionar a segunda legenda da mesma maneira que adicionou a primeira. Vou editar minha resposta para fornecer um exemplo mais completo.
19613 Arthur

Sim, foi o que tentei sem sorte. Como a instrução if / else no evento overlayadd funcionaria se as duas camadas estivessem ativadas? Parece que a legenda de alteração de população não pôde ser adicionada enquanto a camada de população foi marcada. Também tentei usar as sobreposições como camadas base com a alternância de botões de opção, mas ainda não funcionou.
quer
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.