1 votos

¿Filtrar el mapa de folletos interactivo con un menú desplegable?

Trato de establecer un "gráfico de disparos" filtrable como http://graphics.latimes.com/kobe-every-shot-ever/ con leaflet. Tengo un archivo geojson que almacena todos los datos de las tomas, los tengo mostrando en una capa.

Ejemplo GEOJSON:

{
  "type": "Feature",
  "properties": {
    "ID": 2,
    "SEASON_SHO": "1998-1999",
    "GAME_TYPE": "Regular",
    "PERIOD": 1,
    "MINUTES_RE": "06:25:00",
    "ACTION_TYP": "Jump Shot",
    "SHOT_TYPE": "2-PT-Wurf",
    "SHOT_DISTA": 15,
    "GAME_DATE": "05.02.1999",
    "HEIM": "SEA",
    "GAST": "DAL",
    "GEGNER": "Seattle SuperSonics",
    "SHOT_ATTEM": 1,
    "SHOT_MADE_": 0
  },
  "geometry": {
    "type": "Point",
    "coordinates": [
      -0.314959,
      -0.159125
    ]
  }
}

He creado una capa para todas las tomas y un grupo de capas para filtrar los marcadores.

var url = 'data/Wuerfe.geojson';
var allewuerfe;

allewuerfe = L.geoJson(null, {

    onEachFeature: onEachFeature,
    style: style,
    pointToLayer: function (feature, latlng) {
        return L.circleMarker(latlng, allewuerfe);
    }
});

$.getJSON(url, function (data) {
    allewuerfe.addData(data);
});

var data = L.layerGroup([
    ]);
data.addLayer(allewuerfe);
data.addTo(map);

Ya tengo algunos filtros-botones para eventos individuales, como "reset".

<button class="btn reset-btn" id="all">Reset</button>

document.getElementById("all").addEventListener('click', function (event) {
    data.clearLayers();
    data.addLayer(allewuerfe);
    data.addTo(map);
});

Pero lo que me gustaría configurar es un filtro desplegable para "tiros fallados", "tiros acertados" y "todos los tiros".

           <select name="shot-result" class="custom-select" id="shotresult">
                <option value="all">All Shots</option>
                <option value="Made">Made</option>
                <option value="Missed">Missed</option>
            </select>

La información de datos para esto se almacena en el geojson en "SHOT_MADE_", 1 significa que el tiro fue hecho, 0 tiro fue perdido.

Me gustaría obtener un código-ejemplo de cómo hacer funcionar el filtro.

2voto

IvanSanchez Puntos 491

En este caso concreto, utilizaría los datos GeoJSON para crear varias instancias de L.GeoJSON (uno por filtro) y luego utilizar un L.Control.Layers para apagarlos y encenderlos, algo así:

fetch(geoJsonURL)
.then(function(response){ return response.json() })
.then(function(data){

  var missedShots = L.geoJson(data, { 
    filter: function(feature) { return feature.properties.SHOT_MADE_ == 0 }
  });

  var madeShots = L.geoJson(data, { 
    filter: function(feature) { return feature.properties.SHOT_MADE_ == 1 }
  });

  var allShots = L.layerGroup([madeShots, missedShots]);

  allShots.addTo(map);

  L.control.layers({
    "All shots": allShots,
    "Made shots": madeShots,
    "Missed shots": missedShots
  }).addTo(map);

});

Tenga en cuenta que este método analiza los datos GeoJSON sólo una vez.

Si realmente quieres un menú desplegable en lugar del predeterminado L.Control.Layers entonces te animo a que consultes el sección de conmutadores de capas de la lista de plugins de Leaflet .

También es posible utilizar esta técnica en muchas categorías (sigue el pseudocódigo, ya que no estoy seguro de cómo se estructurarían los equipos:

var allTeams = L.layerGroup().addTo(map);
var teamLayers = { "All teams": allTeams };

for (var team in teams) {
   var teamLayer = L.geoJson(data, {
     filter: function(feat) { return feat.properties.team === team; }
   });
   var teamName = 'Team ' + team;
   allTeams.addLayer(teamLayer);
   teamLayers[ teamName ] = teamLayer;
}

L.control.layers(teamLayers).addTo(map);

Observe que esto es funcionalmente lo mismo que el otro bloque de código anterior, sólo que utilizando estructuras de datos que crecen en lugar de estructuras de datos codificadas.

0voto

Steve Gray Puntos 156

Aquí hay un ejemplo de trabajo de filtrado, solo muestro 2 opciones y comienzo con una, luego dependiendo del botón de radio seleccionado, los datos cambian. http://www.gistechsolutions.com/leaflet/DEMO/filter/filter.html

Básicamente tienes un layergroup, y al cambiarlo, lo borras y lo quitas del mapa. Entonces

    myData.clearLayers();
    map.removeLayer(myData);

Entonces su capa tiene el filtro en su función onEachFeature:

    filter: function(feature, layer) {   
         return (feature.properties.SHOT_MADE_,  == 1 );
    },

A continuación, sólo hay que añadir la capa al grupo de capas y añadirla al mapa.

0voto

Steve Gray Puntos 156

Con 30 algunos equipos y varias condiciones utilizando 2 desplegables de selección, algo como esto puede ser mejor.

Esto es más que nada un pseudocódigo, dos selecciones llaman a una "Equipo", a la otra "Condiciones", establecen las condiciones para disparar onchange="SelectPoints();"

//Using a Layer Group to add/ remove data from the map.
//initial setup your layer as "myLayer" and add it to the grouplayer.
var myData =  L.layerGroup([]);
    myData.addLayer(myLayer);
    myData.addTo(map); 

var selPts = [];

function SelectPoints(){
    var team = document.getElementById("Team").value;
    var cond= document.getElementById("Conditions").value;

    //Clear existing data 
    myData.clearLayers();
    map.removeLayer(myData);

    selPts.length =0;  //Reset the array if selecting new points

    myLayer.eachLayer(function (layer) {

        // query  (Rough example/ something like this)
        if (  GEGNER  == team &&  SHOT_MADE_ ==cond  ) {
             selPts.push(layer.feature);  
        }
    });

    //Symbolize the Selected Points
         geojsonLayer = L.geoJson(selPts, {

            pointToLayer: function(feature, latlng) {
                return L.circleMarker(latlng, {
                radius: 4, //expressed in pixels circle size
                color: "green", //or whatever
                stroke: true,
                weight: 7,      //outline width  increased width to look like a filled circle.
                fillOpcaity: 1
                });
                }
        });
        //Add selected points back into map as green circles.
        myData.addLayer(geojsonLayer);
        myData.addTo(map);
}

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