问题描述
我需要能够使用this example中所示的Mapbox GL突出显示边界框中的要素。我的地图还需要具有更改样式图层的功能,例如将基本样式从mapbox://styles/mapbox/light-v10
更改为mapbox://styles/mapbox/satellite-v9
。这具有挑战性,因为Mapbox GL本身不支持“底图”的概念,例如传单。
我的解决方案经过大量搜索(我相信最终我遵循了github问题中发布的解决方法)涉及
-
使用
map.on('style.load')
代替示例中的map.on('load')
(我相信map.on('style.load')
不是其公共API的一部分,但我可能是错的),> -
遍历一系列源/图层(请参见下面的代码
vectorTileLayers
),以便在每次加载新样式时向地图添加矢量图块图层。
这在某些方面对我很有用-我可以向数组添加任意数量的矢量图块源,并且如果更改了基本样式,它们也会全部添加回地图。但是,如果将源/图层以数组形式添加到地图中并进行迭代,如下图所示,则无法按照Mapbox提供的示例添加查询功能。边界功能有效,但是在绘制并释放该功能时,通过运行下面的代码片段,我看到了错误显示。
这是我的实际问题的简化版本,它将允许其他人运行和操纵代码。实际上,我要添加自己的矢量平铺图层(存储在vectorTileLayers
数组中,该图层可以正常工作。当尝试添加具有相同来源和不同样式的另一层时,如示例所示, “我无法实际查询所需的图层。将不胜感激。请仅供参考-此代码段中未显示可切换图层的按钮,但解决问题并不重要。
mapboxgl.accessToken = 'pk.eyJ1IjoiamFtZXljc21pdGgiLCJhIjoiY2p4NTRzdTczMDA1dzRhbXBzdmFpZXV6eCJ9.-k7Um-xmYy4xhNDN6kDvpg';
var map = new mapboxgl.Map({
container: 'map',style: 'mapbox://styles/mapbox/light-v10',center: [-98,38.88],minZoom: 2,zoom: 3
});
var vectorTileLayers = [{
source: {
type: 'vector',url: 'mapbox://mapbox.82pkq93d'
},layer: {
id: 'counties',type: 'fill',source: 'counties','source-layer': 'original',paint: {
'fill-outline-color': 'rgba(0,0.1)','fill-color': 'rgba(0,0.1)'
},}
},{
source: {
type: 'vector',layer: {
id: 'counties-highlighted',paint: {
'fill-outline-color': '#484896','fill-color': '#6e599f','fill-opacity': 0.75
},filter: ['in','FIPS','']
}
}
]
map.on('style.load',function() {
for (var i = 0; i < vectorTileLayers.length; i++) {
var tileLayer = vectorTileLayers[i];
map.addSource(tileLayer.layer.source,tileLayer.source);
map.addLayer(tileLayer.layer);
}
var layerList = document.getElementById('basemapmenu');
var inputs = layerList.getElementsByTagName('input');
function switchLayer(layer) {
var layerId = layer.target.id;
map.setStyle('mapbox://styles/mapbox/' + layerId);
}
for (var i = 0; i < inputs.length; i++) {
inputs[i].onclick = switchLayer;
}
});
// Disable default box zooming.
map.boxZoom.disable();
// Create a popup,but don't add it to the map yet.
var popup = new mapboxgl.Popup({
closeButton: false
});
var canvas = map.getCanvasContainer();
var start;
var current;
var box;
canvas.addEventListener('mousedown',mouseDown,true);
// Return the xy coordinates of the mouse position
function mousePos(e) {
var rect = canvas.getBoundingClientRect();
return new mapboxgl.Point(
e.clientX - rect.left - canvas.clientLeft,e.clientY - rect.top - canvas.clientTop
);
}
function mouseDown(e) {
// Continue the rest of the function if the shiftkey is pressed.
if (!(e.shiftKey && e.button === 0)) return;
// Disable default drag zooming when the shift key is held down.
map.dragPan.disable();
// Call functions for the following events
document.addEventListener('mousemove',onMouseMove);
document.addEventListener('mouseup',onMouseUp);
document.addEventListener('keydown',onKeyDown);
// Capture the first xy coordinates
start = mousePos(e);
}
function onMouseMove(e) {
// Capture the ongoing xy coordinates
current = mousePos(e);
// Append the box element if it doesnt exist
if (!box) {
box = document.createElement('div');
box.classList.add('boxdraw');
canvas.appendChild(box);
}
var minX = Math.min(start.x,current.x),maxX = Math.max(start.x,minY = Math.min(start.y,current.y),maxY = Math.max(start.y,current.y);
// Adjust width and xy position of the box element ongoing
var pos = 'translate(' + minX + 'px,' + minY + 'px)';
box.style.transform = pos;
box.style.WebkitTransform = pos;
box.style.width = maxX - minX + 'px';
box.style.height = maxY - minY + 'px';
}
function onMouseUp(e) {
// Capture xy coordinates
finish([start,mousePos(e)]);
}
function onKeyDown(e) {
// If the ESC key is pressed
if (e.keyCode === 27) finish();
}
function finish(bbox) {
// Remove these events now that finish has been called.
document.removeEventListener('mousemove',onMouseMove);
document.removeEventListener('keydown',onKeyDown);
document.removeEventListener('mouseup',onMouseUp);
if (box) {
box.parentNode.removeChild(box);
box = null;
}
// If bbox exists. use this value as the argument for `queryRenderedFeatures`
if (bbox) {
var features = map.queryRenderedFeatures(bbox,{
layers: ['counties']
});
if (features.length >= 1000) {
return window.alert('Select a smaller number of features');
}
// Run through the selected features and set a filter
// to match features with unique FIPS codes to activate
// the `counties-highlighted` layer.
var filter = features.reduce(
function(memo,feature) {
memo.push(feature.properties.FIPS);
return memo;
},['in','FIPS']
);
map.setFilter('counties-highlighted',filter);
}
map.dragPan.enable();
}
map.on('mousemove',function(e) {
var features = map.queryRenderedFeatures(e.point,{
layers: ['counties-highlighted']
});
// 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];
popup
.setLngLat(e.lngLat)
.setText(feature.properties.COUNTY)
.addTo(map);
});
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
#basemapmenu {
position: absolute;
display: inline-block;
background-color: transparent;
bottom: 0;
left: 0;
margin-left: 10px;
margin-bottom: 40px;
}
.boxdraw {
background: rgba(56,135,190,0.1);
border: 2px solid #3887be;
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
}
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel="stylesheet"/>
<script src="https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js"></script>
<div id="map"></div>
<div id='basemapmenu'>
<input id='light-v10' class='btn btn-outline-primary' type='button' name='rtoggle' value='Light' checked='checked'>
<input id='dark-v10' class='btn btn-outline-primary' type='button' name='rtoggle' value='Dark'>
<input id='satellite-v9' class='btn btn-outline-primary' type='button' name='rtoggle' value='Satellite'>
</div>
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)