2016-03-18 2 views
5

Я нашел следующий код, чтобы показать и скрыть слои в MapBox GL:Показать и скрыть особенности слоя в MapBox GL JS

https://www.mapbox.com/mapbox-gl-js/example/toggle-layers/

Это полезно, однако, у меня есть только один .geojson слой (полилинии) со всеми необходимыми данными и не нужно создавать отдельные слои.

Я хотел бы сделать ту же самую функцию, что бы показывать и скрывать функции одного слоя в меню карты. Существует всего 12 различных типов объектов, которые содержатся в столбце «Тип». Я хотел бы включать и выключать типы, как в примере.

Есть ли простой способ сделать это в JS с помощью set.Filter? https://github.com/mapbox/mapbox-gl-js/blob/e9386d2880cc2c33e9a5a16b9bcb58834026a078/js/ui/map.js#L559-L562

Я не смог найти решение.

Мой .geojson слой здесь: https://iskandarblue.github.io/mapbox/data/simplify_prototype.geojson

<!DOCTYPE html> 
<html> 
<head> 
    <meta charset='utf-8' /> 
    <title></title> 
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> 
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.15.0/mapbox-gl.js'></script> 
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.15.0/mapbox-gl.css' rel='stylesheet' /> 
    <style> 
     body { margin:0; padding:0; } 
     #map { position:absolute; top:0; bottom:0; width:100%; } 
    </style> 
</head> 
<body> 

<style> 
    #menu { 
     background: #fff; 
     position: absolute; 
     z-index: 1; 
     top: 10px; 
     right: 10px; 
     border-radius: 3px; 
     width: 120px; 
     border: 1px solid rgba(0,0,0,0.4); 
     font-family: 'Open Sans', sans-serif; 
    } 

    #menu a { 
     font-size: 13px; 
     color: #404040; 
     display: block; 
     margin: 0; 
     padding: 0; 
     padding: 10px; 
     text-decoration: none; 
     border-bottom: 1px solid rgba(0,0,0,0.25); 
     text-align: center; 
    } 

    #menu a:last-child { 
     border: none; 
    } 

    #menu a:hover { 
     background-color: #f8f8f8; 
     color: #404040; 
    } 

    #menu a.active { 
     background-color: #3887be; 
     color: #ffffff; 
    } 

    #menu a.active:hover { 
     background: #3074a4; 
    } 
</style> 

<nav id="menu"></nav> 
<div id="map"></div> 

<script> 
mapboxgl.accessToken = 'pk.eyJ1IjoiaXNrYW5kYXJibHVlIiwiYSI6ImNpazE3MTJldjAzYzZ1Nm0wdXZnMGU2MGMifQ.i3E1_b9QXJS8xXuPy3OTcg'; 
var map = new mapboxgl.Map({ 
    container: 'map', 
    style: 'mapbox://styles/mapbox/streets-v8', 
    zoom: 15, 
    center: [-71.97722138410576, -13.517379300798098] 
}); 

map.on('style.load', function() { 
    map.addSource('museums', { 
     type: 'vector', 
     url: 'mapbox://mapbox.2opop9hr' 
    }); 
    map.addLayer({ 
     'id': 'museums', 
     'type': 'circle', 
     'source': 'museums', 
     'paint': { 
      'circle-radius': 8, 
      'circle-color': 'rgba(55,148,179,1)' 
     }, 
     'source-layer': 'museum-cusco' 
    }); 

    map.addSource('contours', { 
     type: 'vector', 
     url: 'mapbox://mapbox.mapbox-terrain-v2' 
    }); 
    map.addLayer({ 
     'id': 'contours', 
     'type': 'line', 
     'source': 'contours', 
     'source-layer': 'contour', 
     'layout': { 
      'line-join': 'round', 
      'line-cap': 'round' 
     }, 
     'paint': { 
      'line-color': '#877b59', 
      'line-width': 1 
     } 
    }); 
}); 

addLayer('Contours', 'contours'); 
addLayer('Museums', 'museums'); 

function addLayer(name, id) { 
    var link = document.createElement('a'); 
    link.href = '#'; 
    link.className = 'active'; 
    link.textContent = name; 

    link.onclick = function (e) { 
     e.preventDefault(); 
     e.stopPropagation(); 

     var visibility = map.getLayoutProperty(id, 'visibility'); 

     if (visibility === 'visible') { 
      map.setLayoutProperty(id, 'visibility', 'none'); 
      this.className = ''; 
     } else { 
      this.className = 'active'; 
      map.setLayoutProperty(id, 'visibility', 'visible'); 
     } 
    }; 

    var layers = document.getElementById('menu'); 
    layers.appendChild(link); 
} 

</script> 

</body> 
</html> 
+0

Вы видели https://www.mapbox.com/mapbox-gl-js/example/filter-markers/? Этот пример демонстрирует это поведение (скрывая показ функций через фильтр). – tristen

ответ

2

Я пытался сделать то же самое и в конечном итоге с помощью комбинированных фильтров. Подобно вам, у меня есть карта с источником GeoJSON:

map.addSource('routes', { 
    'type': 'geojson', 
    'data': geoJSON 
}); 

На этой карте, у меня есть слой со всеми моими маршрутами:

map.addLayer({ 
    'id': 'route-no-hover', 
    'type': 'line', 
    'source': 'routes', 
    'layout': { 
     'line-join': 'round', 
     'line-cap': 'round' 
    }, 
    'paint': { 
     'line-color': '#333', 
     'line-opacity': 0.25, 
     'line-width': 4 
    } 
}); 

я перечисляю все мои маршруты и обеспечивая пользователь с возможностью их включения и выключения. Похоже, моя концепция «маршрутов» эквивалентна вашим «типам». Когда пользователь нажимает на название маршрута, чтобы отключить его, я толкаю идентификатор этого маршрута в массив под названием «скрытый», затем создать ряд фильтров на основе этих идентификаторов:

let hiddenFilters = ['all']; 
_.forEach(mapMeta.hidden, (route) => { 
    hiddenFilters.push([ 
     '!=', 
     'id', 
     route.toString() 
    ]); 
}); 
map.setFilter('route-no-hover', hiddenFilters); 

Обратите внимание, что я использую lodash но вы могли бы просто использовать Array.forEach()

Я эффективно создать фильтр, который выглядит как this combining filter described in the filtering docs:

[ 
    "all", 
    ["!=", "id", "routeIDHere"], 
    ["!=", "id", "routeIDHere"], 
    ... 
] 

Это исключает все маршруты с идентификаторами я указать. В вашем случае, я думаю, что вы хотели бы иметь что-то вроде

[ 
    "all", 
    ["!=", "type" "YourTypeNameHere"] 
    ... 
]