繁体   English   中英

用于切换“显示您的位置”的 Javascript 传单地图

[英]Javascript leaflet map to toggle "Show Your Location"

我有一张传单地图,显示该人当前所在位置(当前位置)周围的区域,通常我希望地图在他们旅行时“跟随”该人。 我为此使用了 mymap.panTo 命令。 这一切工作正常。 它每 5 秒更新一次地图并平移以完美地以当前人物为中心。

有时,尽管此人可能希望将地图滚动到更远的地方以查看某些内容。 这有效......直到 5 秒计数器启动并再次将地图平移回其位置。 恼人的。

我在各种地图应用程序上看到了地图上的按钮/切换按钮,人们可以点击它来停止地图跟随他们。 事实上,如果手动移动地图,它通常会关闭,然后他们会单击切换按钮平移回当前位置。 请参阅谷歌地图的附加图片,突出显示他们所谓的“显示您的位置”按钮。 这就是我想要的。

突出显示“显示您的位置”按钮的 Google 地图屏幕截图

但这是如何做到的? 这是我找不到的某种自定义传单控件吗? 或者它是以某种方式完全以编程方式完成的(以及任何示例代码片段?)。

任何帮助表示赞赏。

下面是我用来显示我的地图的代码。

var streetmap = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
      attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
      id: 'mapbox/streets-v11',
      accessToken: 'token code here' //redacted token
   }),
   satellite = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
      attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
      id: 'mapbox/satellite-v9',
      accessToken: 'token code here' //redacted token   });
var baseMaps = {
     "Streetmap": streetmap,
     "Satellite": satellite
};
    
var mymap = L.map('mapid', { 
   center: [latitude,longitude],
   zoom: 17,
   layers: [streetmap] //default layer
}); 

var personicon = L.icon({
    iconUrl: '/js/personicon.png',
    iconSize: [20, 20]
    });
var playerLoc = new L.marker([latitude,longitude], {icon: personicon}) // set player location marker as a declared variable but don't put it on the map yet

在其他地方我有代码来启动地图(一旦填充了变量)然后继续更新位置

   const interval = setInterval(function() {
         if (is_running) { // we need to know that there is data populated before showing or updating the map with it
         if (!map_started) {  //start the map only once 
        L.control.layers(baseMaps).addTo(mymap); //show choice of layer views
            L.control.scale().addTo(mymap); //show scale bar
        console.log("Create current player marker:",MYID,latitude,longitude); 
            playerLoc.setLatLng([latitude,longitude]).addTo(mymap).bindPopup(MYID); //update current player marker, and now show it on the map
                map_started=true;
             }; //start the map only once
         updatemap(); // for current player location and circle colour.
      }; //update only if is_running
          mymap.invalidateSize(); //reset map view
    }, 5000); // update map every 5 seconds 
function updatemap() {  // Update the current player location on map
    playerLoc.setLatLng([latitude,longitude]); //update current player marker instead of creating new ones
    mymap.panTo([latitude,longitude]); // pan the map to follow the player (TODO: Can we toggle pan mode?)
}; // end updatemap

这段代码一切正常。 mymap.panTo([latitude,longitude]); 行是需要包含在条件中的内容“如果允许平移,则执行 mymap.panTo([latitude,longitude]);” 但是肯定有标准的传单控制或方法吗? 我总是在别处看到这个东西

您需要监听movestart事件,以检测用户是否移动了地图。 但是这个事件也是从panTo函数触发的,所以你需要一个标志来指示movestart是由间隔还是由用户触发。


var currentAutoMove = false; // needed to check in `movestart` event-listener if moved from interval or by user
var pauseAutoMove = false; // if true -> Stops moving map

var latitude,longitude;
setInterval(()=>{
    latitude = playerLoc.getLatLng().lat + 0.001;
    longitude = playerLoc.getLatLng().lng + 0.001;
    updatemap();
}, 1000)


function updatemap() {  // Update the current player location on map
    playerLoc.setLatLng([latitude,longitude]);
    
    if(!pauseAutoMove){
       currentAutoMove = true; // Set flag, that currently map is moved by interval
       map.panTo([latitude,longitude]);
       currentAutoMove = false; // Remove flag, that currently map is moved by interval
   }
}


map.on('movestart',(e)=>{
    console.log(e, currentAutoMove);
  if(!currentAutoMove){ // Check if map is moved by interval or by user
    pauseAutoMove = true; // set flag, to stop moving map
  }
})

// Start auto move again, if button clicked
L.DomEvent.on(document.getElementById('toPos'),'click',(e)=>{
    pauseAutoMove = false; // reset flag, to stop moving map -> start moving map
  map.panTo([latitude,longitude]);
})

要创建一个控制/按钮来启动自动移动,你只需要在谷歌搜索有很多例子,否则你可以使用 L.easybutton。

演示: https : //jsfiddle.net/falkedesign/8akw3ust/

非常感谢 Falke Design,我使用了上面答案中的建议。 对于我想要的按钮,我的代码现在看起来像这样:

var panbtn = L.easyButton({
  states: [{
    stateName: 'pauseAutoMove',      
    icon:      'fa-sign-in fa-lg',               
    title:     'Centre display at current Player', //Tooltip
    onClick: function(btn, map) {
      console.log("AutoMoveButton pressed");
      panbtn.state('AutoMove');                               
      mymap.panTo([latitude,longitude]); 
    }
  }, {
    stateName: 'AutoMove',
    icon:      'fa-crosshairs fa-lg',
  }]
}).addTo(mymap);

mymap.on("zoomstart", function (e) { currentAutoMove = true }); //Set flag, that currently map is moved by a zoom command
mymap.on("zoomend", function (e) { currentAutoMove = false }); //Remove flag again

mymap.on('movestart',(e)=>{ //Check if map is being moved
    if(!currentAutoMove){ //ignore if it was a natural PlayerLoc Auto update
        pauseAutoMove = true; //set flag to stop Auto moving map 
            console.log("Map moved");
        panbtn.state('pauseAutoMove'); //change button style to remove crosshairs
    }
});

在 updatemap 函数中的代码:

    if(!pauseAutoMove){ //pan the map to follow the player unless it is on pause
            currentAutoMove = true; //Set flag, that currently map is moved by a normal PlayerLoc Auto update
            mymap.panTo([latitude,longitude]); 
            currentAutoMove = false; //Remove flag again
    };

非常感谢。

暂无
暂无

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

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