Mapbox GL NavigationControl事件

时间:2018-01-11 17:22:38

标签: mapbox-gl-js

我有一个Mapbox GL地图的实例,在加载我的数据源后,我正在调用fitBounds()来更改地图的中心并缩放以适合我的数据集。我还在此地图上附加了一些事件监听器,因为我想知道用户何时手动更改了地图的缩放或位置。

Mapbox也会触发' movestart'和' zoomstart'在fitBounds()上,虽然我通过检查事件回调中是否存在originalEvent属性来解决该问题。

问题是,我还在地图中添加了NavigationControl,通过缩放或旋转按钮触发的用户互动会在没有originalEvent属性的情况下触发我的地图事件。我无法在Mapbox文档中找到任何方法来监听附加事件监听器NavigationControl,也无法区分fitBounds调用启动的缩放/平移与通过该组件的用户交互。

我有什么遗失的东西吗?有没有办法将鼠标/触摸事件监听器附加到NavigationControl组件?或者,事件对象中是否有某些属性可以告诉我事件的来源?

简化代码示例 -

this._userMoved = false;
this._map = new mapboxgl.Map(options);

// listen for user actions that update the map display
['movestart', 'zoomstart', 'boxzoomstart', 'rotatestart', 'pitchstart'].forEach((action) => {
  this._map.on(action, (e) => {
    if (e.originalEvent) {
      // if this property is set, the event in question was triggered by an actual user ineraction.
      // EXCEPT when the user interaction came from the NavigationControl, hence the problem
      this._userMoved = true;
    }
  });
});
this._map.on('load', () => {
  // add the control after map load
  this._map.addControl(new mapboxgl.NavigationControl(),'top-left');
  this._setMapData(); // adds my data source to the map
  this._setMapView(); // calls this._map.fitBounds() using my data source
});

1 个答案:

答案 0 :(得分:3)

如果您需要专门处理被调用一次的特定事件(fitbounds),那么您可以这样做:

this._map.once('moveend', e => {
   // do whatever you do after the fitbounds event.
   this._map.on(['movestart', 'zoomstart', 'boxzoomstart', 'rotatestart', 'pitchstart'], userMovementHandler)
});

<强> 修改

我只是仔细查看了文档,eventData确实有一个fitBounds参数,旨在解决这个问题。

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8' />
    <title>Display a map</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.43.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.43.0/mapbox-gl.css' rel='stylesheet' />
    <style>
        body { margin:0; padding:0; }
        #map { position:absolute; top:0; bottom:0; width:100%; }
    </style>
</head>
<body>

<div id='map'></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1Ijoic3RldmFnZSIsImEiOiJGcW03aExzIn0.QUkUmTGIO3gGt83HiRIjQw';
var map = new mapboxgl.Map({
    container: 'map', // container id
    style: 'mapbox://styles/mapbox/streets-v9', // stylesheet location
    center: [-74.50, 40], // starting position [lng, lat]
    zoom: 9 // starting zoom
}).on('moveend', e => { 
    if (e.source === 'fitBounds') {
        console.log('Caused by fitBounds');
    } else {
        console.log('Caused by user');
    }
})
map.fitBounds([140,-42, 150,-37], {}, {source: 'fitBounds'})
</script>

</body>
</html>