[Mapbox GL]通过输入过滤标志

本文介绍了一个使用Mapbox GL JS实现的图标过滤器示例,该过滤器允许用户通过输入框筛选地图上的图标标记。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        根据输入的图标名字过滤标志



<!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.29.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.29.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>
    .filter-ctrl {
        position: absolute;
        top: 10px;
        right: 10px;
        z-index: 1;
        width: 180px;
    }

    .filter-ctrl input[type=text] {
        font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
        width: 100%;
        border: 0;
        background-color: #fff;
        height: 40px;
        margin: 0;
        color: rgba(0,0,0,.5);
        padding: 10px;
        box-shadow: 0 0 0 2px rgba(0,0,0,0.1);
        border-radius: 3px;
    }
</style>
<div id='map'></div>
<div class='filter-ctrl'>
    <input id='filter-input' type='text' name='filter' placeholder='Filter by name' />
</div>

<script>
mapboxgl.accessToken = '<your access token here>';
var places = {
    "type": "FeatureCollection",
    "features": [{
        "type": "Feature",
        "properties": {
            "icon": "theatre"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [-77.038659, 38.931567]
        }
    }, {
        "type": "Feature",
        "properties": {
            "icon": "theatre"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [-77.003168, 38.894651]
        }
    }, {
        "type": "Feature",
        "properties": {
            "icon": "bar"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [-77.090372, 38.881189]
        }
    }, {
        "type": "Feature",
        "properties": {
            "icon": "bicycle"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [-77.052477, 38.943951]
        }
    }, {
        "type": "Feature",
        "properties": {
            "icon": "music"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [-77.031706, 38.914581]
        }
    }, {
        "type": "Feature",
        "properties": {
            "icon": "music"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [-77.020945, 38.878241]
        }
    }, {
        "type": "Feature",
        "properties": {
            "icon": "music"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [-77.007481, 38.876516]
        }
    }]
};

var layerIDs = []; // Will contain a list used to filter against.
var filterInput = document.getElementById('filter-input');
var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/light-v9',
    center: [-77.04, 38.907],
    zoom: 11.15
});

map.on('load', function() {  /* 地图加载时的处理 */
    // Add a GeoJSON source containing place coordinates and information.
    map.addSource('places', {
        "type": "geojson",
        "data": places
    });

    places.features.forEach(function(feature) {
        var symbol = feature.properties['icon'];
        var layerID = 'poi-' + symbol;

        // Add a layer for this symbol type if it hasn't been added already.
        if (!map.getLayer(layerID)) {   /* getLayer(layerID)获取layerID的layer  */
            map.addLayer({
                "id": layerID,
                "type": "symbol",
                "source": "places",
                "layout": {   /* 设置layout属性 */
                    "icon-image": symbol + "-15",
                    "icon-allow-overlap": true,
                    "text-field": symbol,
                    "text-font": ["Open Sans Bold", "Arial Unicode MS Bold"],
                    "text-size": 11,
                    "text-transform": "uppercase",
                    "text-letter-spacing": 0.05,
                    "text-offset": [0, 1.5]
                },
                "paint": {    /* 设置paint属性 */
                    "text-color": "#202",
                    "text-halo-color": "#fff",
                    "text-halo-width": 2
                },
                "filter": ["==", "icon", symbol] /* 根据icon名称过滤数据 */
            });

            layerIDs.push(layerID); /*push():数组添加成员*/
        }
    });

    filterInput.addEventListener('keyup', function(e) {   /* element.addEventListener(type,callback(e)):添加type事件监听器,KeyUp事件是键盘上的某个键按下后再松开时触发,此处为input标签添加,通过keyup事件更新layer对应数据的可见性*/
        // If the input value matches a layerID set
        // it's visibility to 'visible' or else hide it.
        var value = e.target.value.trim().toLowerCase(); /* e.target.property:获取事件目标的对应属性值,trim()消除字符串两端空格,toLowerCase()转换为小写 */
        layerIDs.forEach(function(layerID) {    /* forEach遍历数组 */
            map.setLayoutProperty(layerID, 'visibility',         /* setLayoutProperty()设置layer的对应Layout属性值 */
                layerID.indexOf(value) > -1 ? 'visible' : 'none'); /* indexOf(value):indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置,如果要检索的字符串值没有出现,则该方法返回 -1,字符位置是从 0 开始的 */
        });
    });
});
</script>

</body>
</html>

原文: https://www.mapbox.com/mapbox-gl-js/example/filter-markers-by-input/

<think>好的,我现在需要在Mapbox GL过滤掉所有属性值为空的数据。用户的问题是如何使用Mapbox GL过滤器(filter)来排除那些属性为空或null的数据。首先,我需要回忆一下Mapbox GL中关于图层过滤器的文档。 记得Mapbox GL的图层可以使用`filter`属性来设置条件,只显示符合条件的数据。过滤器的语法是基于表达式的,可能涉及到各种操作符,比如`!=`、`==`,还有检查属性是否存在的方法。例如,使用`["has", "propertyName"]`可以检查某个属性是否存在。 用户想要过滤掉属性值为null或空的。这里的“空”可能指的是空字符串或者根本不存在该属性。所以需要分情况处理。对于null值,可以用`["!=", ["get", "propertyName"], null]`。对于空字符串,则是`["!=", ["get", "propertyName"], ""]`。但如果属性不存在的话,使用`["get", "propertyName"]`可能会导致错误,这时候可能需要结合`["has", "propertyName"]`来判断属性是否存在。 接下来,我需要把这些条件组合起来。可能需要使用`all`操作符来同时满足多个条件。比如,要排除属性不存在、为null或空字符串的情况,可以写成: `["all", ["has", "propertyName"], ["!=", ["get", "propertyName"], null], ["!=", ["get", "propertyName"], ""]]`。但这样可能会漏掉某些情况,比如属性存在但值为空字符串或null的情况。 不过用户的需求是过滤掉所有属性值为空的数据,不管该属性是否存在。可能需要遍历所有属性,但Mapbox GL过滤器可能不支持动态检查所有属性,只能在已知属性名称的情况下进行过滤。因此,用户可能需要为每个已知的属性单独设置过滤条件。 例如,假设数据有一个属性叫`name`,要过滤掉`name`为空或null的要素,可以这样写: `["all", ["!=", ["get", "name"], null], ["!=", ["get", "name"], ""]]`。然后将这个过滤器应用到对应的图层上。 如果用户不知道具体属性名称,或者需要过滤所有属性,可能需要不同的方法,但Mapbox GL可能不支持动态检查所有属性是否存在或为空。这时候可能需要预处理数据,在数据源中清理掉这些空值,或者在生成矢量瓦片时处理,比如使用工具如Tippecanoe时设置相应的过滤选项,如引用[1]提到的矢量瓦片集创建工具可能支持在生成瓦片时过滤掉属性为空的数据。 此外,引用[2]中提到的点聚合可能涉及到前端处理,但这里的过滤主要是在渲染时处理,所以应该在Mapbox GL的图层配置中设置过滤器。 总结步骤: 1. 确定需要过滤的属性名称。 2. 对每个属性使用`["all", ["has", "属性名"], ["!=", ["get", "属性名"], null], ["!=", ["get", "属性名"], ""]]`来过滤。 3. 将这些条件组合到图层的filter属性中。 可能的代码示例: ```javascript map.addLayer({ id: 'my-layer', type: 'circle', source: 'my-source', filter: ['all', ['!=', ['get', 'property1'], null], ['!=', ['get', 'property1'], ''], ['!=', ['get', 'property2'], null], ['!=', ['get', 'property2'], ''] ], paint: { ... } }); ``` 如果属性较多,可能需要动态生成过滤数组,但需要确保语法正确。 另外,如果用户想过滤掉任何属性存在空值的情况,可能需要更复杂的处理,或者预处理数据。例如,在数据源生成阶段,如使用引用[1]的工具生成矢量瓦片时,排除这些属性为空的要素。 最后,检查是否有其他可能的边界情况,比如属性值为0或false是否会被误判为空,但根据用户需求,可能只需处理null和空字符串。</think>在Mapbox GL过滤属性值为空或null的数据,可以使用`filter`表达式结合`has`和`!=`操作符。以下是具体步骤和示例: ### 1. **过滤单个属性** 假设需要过滤名为`name`的属性,确保其不为空或null: ```javascript map.addLayer({ id: 'my-layer', type: 'circle', source: 'my-source', filter: [ 'all', ['has', 'name'], // 属性存在 ['!=', ['get', 'name'], null], // 值非null ['!=', ['get', 'name'], ''] // 值非空字符串 ], paint: { ... } }); ``` ### 2. **过滤多个属性** 若需同时过滤多个属性(如`name`和`type`): ```javascript filter: [ 'all', ['!=', ['get', 'name'], null], ['!=', ['get', 'name'], ''], ['!=', ['get', 'type'], null], ['!=', ['get', 'type'], ''] ] ``` ### 3. **动态处理数据源** 如果数据中存在大量需过滤的属性,建议在生成矢量瓦片时预处理数据。例如,使用工具如**Tippecanoe**或引用[1]提到的矢量瓦片集创建工具,在数据转换阶段剔除空值属性[^1]。 ### 4. **边界情况** - **数值0或布尔值false**:不会被上述条件排除,需根据需求调整逻辑。 - **属性不存在**:`['has', 'property']`确保仅保留已定义属性的要素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值