[Mapbox GL]地图视图内过滤特性

        移动地图查询矢量瓦片层的可视化特性并且通过输入过滤


<!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>
#map {
    position:absolute;
    left:25%;
    top:0;
    bottom:0;
    width: 75%;
}
.map-overlay {
    position: absolute;
    width: 25%;
    top: 0;
    bottom: 0;
    left: 0;
    font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
    background-color: #fff;
    max-height: 100%;
    overflow: hidden;
}

.map-overlay fieldset {
    display: none;
    background: #ddd;
    border: none;
    padding: 10px;
    margin: 0;
}

.map-overlay input {
    display: block;
    border: none;
    width: 100%;
    border-radius: 3px;
    padding: 10px;
    margin: 0;
}

.map-overlay .listing {
    overflow: auto;
    max-height: 100%;
}

.map-overlay .listing > * {
    display: block;
    padding: 5px 10px;
    margin: 0;
}

.map-overlay .listing a {
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
    color: #404;
    text-decoration: none;
}

.map-overlay .listing a:last-child {
    border: none;
}

.map-overlay .listing a:hover {
    background: #f0f0f0;
}
</style>

<div id='map'></div>
<!-- 
<fieldset> 标签将表单内容的一部分打包,生成一组相关表单的字段。<fieldset> 标签没有必需的或唯一的属性。
当一组表单元素放到 <fieldset> 标签内时,浏览器会以特殊方式来显示它们,它们可能有特殊的边界、3D 效果,或者甚至可创建一个子表单来处理这些元素 
--><div class='map-overlay'> <fieldset> <input id='feature-filter' type='text' placeholder='Filter results by name' /> </fieldset> <div id='feature-listing' class='listing'></div> </div><script>mapboxgl.accessToken = '<your access token here>';var map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v9', center: [-98, 38.88], maxZoom: 5, minZoom: 1, zoom: 3});// Holds visible airport features for filteringvar airports = [];// Create a popup, but don't add it to the map yet.var popup = new mapboxgl.Popup({ /* new Popup(options: [Object]):Popup构造器 */ closeButton: false /* 设置Popup选项 */});var filterEl = document.getElementById('feature-filter');var listingEl = document.getElementById('feature-listing');function renderListings(features) { // Clear any existing listings listingEl.innerHTML = ''; /* 清除标签内部html文本内容 */ if (features.length) { /* 获取features,通过features的内容增加可视化的html */ features.forEach(function(feature) { /* 遍历 */ var prop = feature.properties; var item = document.createElement('a'); /* 创建html标签 */ item.href = prop.wikipedia; item.target = '_blank'; item.textContent = prop.name + ' (' + prop.abbrev + ')'; item.addEventListener('mouseover', function() { /* elem.addEventListener(type,callback)添加事件监听器 */ // Highlight corresponding feature on the map popup.setLngLat(feature.geometry.coordinates) /* setlngLat(lnglat):设置popup的位置并移动到那里 */ .setText(feature.properties.name + ' (' + feature.properties.abbrev + ')') /* setText(text)设置popup的文本显示内容 */ .addTo(map); /* addTo(map):将popup添加到地图上 */ }); listingEl.appendChild(item); /* 追加item html */ }); // Show the filter input filterEl.parentNode.style.display = 'block'; /* .style.display设置可见性 */ } else { var empty = document.createElement('p'); /* 添加<p>标签 */ empty.textContent = 'Drag the map to populate results'; /* .textContent属性设置文本内容 */ listingEl.appendChild(empty); // Hide the filter input filterEl.parentNode.style.display = 'none'; // remove features filter map.setFilter('airport', ['has', 'abbrev']); /* 过滤拥有"abbrev"的数据才显示 */ }}function normalize(string) { return string.trim().toLowerCase(); /* trim():移除字符串两端的空格,toLowerCase():改成小写 */}function getUniqueFeatures(array, comparatorProperty) { var existingFeatureKeys = {}; // Because features come from tiled vector data, feature geometries may be split // or duplicated across tile boundaries and, as a result, features may appear // multiple times in query results. var uniqueFeatures = array.filter(function(el) { /* array.filter(function(currentValue,index,arr), thisValue):filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素,currentValue,必须,当前元素的值;index,可选,当期元素的索引值;arr,可选,当期元素属于的数组对象;thisValue,可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。 */ if (existingFeatureKeys[el.properties[comparatorProperty]]) { return false; } else { existingFeatureKeys[el.properties[comparatorProperty]] = true; return true; } }); return uniqueFeatures;}map.on('load', function() { // Add our vector tile source: World wide // airports provided by Natural Earth map.addSource('airports', { "type": "vector", "url": "mapbox://mapbox.04w69w5j" }); map.addLayer({ "id": "airport", "source": "airports", "source-layer": "ne_10m_airports", "type": "symbol", "layout": { /* 设置layout属性 */ "icon-image": "airport-15", "icon-padding": 0, "icon-allow-overlap":true } }); map.on('moveend', function() { var features = map.queryRenderedFeatures({layers:['airport']}); if (features) { var uniqueFeatures = getUniqueFeatures(features, "iata_code"); // Populate features for the listing overlay. renderListings(uniqueFeatures); // Clear the input container filterEl.value = ''; // Store the current features in sn `airports` variable to // later use for filtering on `keyup`. airports = uniqueFeatures; } }); map.on('mousemove', function(e) { var features = map.queryRenderedFeatures(e.point, { layers: ['airport'] }); // Change the cursor style as a UI indicator. map.getCanvas().style.cursor = features.length ? 'pointer' : ''; /* 设置光标属性 */ if (!features.length) { popup.remove(); return; } var feature = features[0]; // Populate the popup and set its coordinates // based on the feature found. popup.setLngLat(feature.geometry.coordinates) .setText(feature.properties.name + ' (' + feature.properties.abbrev + ')') .addTo(map); }); filterEl.addEventListener('keyup', function(e) { var value = normalize(e.target.value); // Filter visible features that don't match the input value. var filtered = airports.filter(function(feature) { var name = normalize(feature.properties.name); var code = normalize(feature.properties.abbrev); return name.indexOf(value) > -1 || code.indexOf(value) > -1; }); // Populate the sidebar with filtered results renderListings(filtered); // Set the filter to populate features into the layer. map.setFilter('airport', ['in', 'abbrev'].concat(filtered.map(function(feature) { /* concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。map() 方法按照原始数组元素顺序依次处理元素。array.map(function(currentValue,index,arr), thisValue):currentValue,必须,当前元素的值;index,可选,当期元素的索引值;arr,可选,当期元素属于的数组对象;thisValue,可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。 */ return feature.properties.abbrev; }))); }); // Call this function on initialization // passing an empty array to render an empty state renderListings([]);});</script></body></html>



原文:https://www.mapbox.com/mapbox-gl-js/example/filter-features-within-map-view/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值