简体   繁体   English

在Mapbox GL JS中显示和隐藏图层的功能

[英]Show and hide features of a layer in Mapbox GL JS

I have found the following code to show and hide layers in Mapbox GL: 我找到了以下代码来显示和隐藏Mapbox GL中的图层:

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

This is helpful, however, I only have one .geojson layer (polylines) with all of the necessary data and do not need to create separate layers. 这是有帮助的,但是,我只有一个带有所有必要数据的.geojson图层(折线),不需要创建单独的图层。

I would like to make the exact same function of being able to show and hide features of one layer in the map menu. 我想做一个完全相同的功能,能够在地图菜单中显示和隐藏一个图层的功能。 There are a total of 12 different feature types, contained in the column named "Type". 共有12种不同的要素类型,包含在名为“类型”的列中。 I would like to toggle types on and off, just like in the example. 我想打开和关闭类型,就像在示例中一样。

Is there an easy way to do this in JS with the set.Filter ? 有没有一种简单的方法在JS中使用set.Filter执行此set.Filter https://github.com/mapbox/mapbox-gl-js/blob/e9386d2880cc2c33e9a5a16b9bcb58834026a078/js/ui/map.js#L559-L562 https://github.com/mapbox/mapbox-gl-js/blob/e9386d2880cc2c33e9a5a16b9bcb58834026a078/js/ui/map.js#L559-L562

I have been unable to come up with a solution. 我一直无法提出解决方案。

My .geojson layer is here: https://iskandarblue.github.io/mapbox/data/simplify_prototype.geojson 我的.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>

I was trying to do the same thing and ended up using combo filters. 我试图做同样的事情,最后使用组合过滤器。 Similar to you, I have a map with a geoJSON source: 与您类似,我有一个带有geoJSON源的地图:

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

On that map, I have a layer with all my routes: 在该地图上,我有一个包含所有路线的图层:

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

I'm listing all my routes and providing the user with the availability to toggle them on and off. 我列出了我的所有路线,并为用户提供了打开和关闭它们的可用性。 It sounds like my concept of "routes" is equivalent to your "types". 听起来我的“路线”概念等同于你的“类型”。 When a user clicks a route name to turn it off, I push that route's ID into an array called 'hidden' then create a series of filters based on those IDs: 当用户单击路由名称将其关闭时,我将该路由的ID推送到名为“hidden”的数组中,然后根据这些ID创建一系列过滤器:

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

Note that I'm using lodash but you could just use Array.forEach() 请注意,我正在使用lodash,但您可以使用Array.forEach()

I'm effectively creating a filter that looks like this combining filter described in the filtering docs : 我正在创建一个看起来像过滤文档中描述的组合过滤器的过滤器

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

This excludes all the routes with the IDs I specify. 这将排除具有我指定的ID的所有路由。 In your case, I think you'd want to have something like 在你的情况下,我想你想要有类似的东西

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM