【问题标题】:Leaflet detect when marker goes into and out of a circle传单检测标记何时进出圆圈
【发布时间】:2019-08-06 22:34:41
【问题描述】:

我正在尝试使用传单进行地理围栏,并且我有一个可以移动的标记和地图上的一个圆圈。

这里是完整的代码:

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title></title>

</head>
<body>

<head>
    <link href='https://api.mapbox.com/mapbox.js/plugins/leaflet-locatecontrol/v0.43.0/css/font-awesome.min.css' rel='stylesheet' />
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />

    <script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
  </head>
<body>
<div id="mapid" style="height: 600px"></div>
<script>

  var mymap = L.map('mapid', {
    center: [50.897819, -1.150189],
    zoom: 16
  });

    L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1Ijoic3RldmVuc2F0Y2giLCJhIjoiY2p5eDR6MWgzMHRvbjNocnJkN2d2MjRwaSJ9.wd0OtBUQQfUtNxdduQA3lg', {
        maxZoom: 18,
        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
            '<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
            'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
        id: 'mapbox.streets'
    }).addTo(mymap);

var marker = new L.marker([50.898422, -1.148444],{
    draggable: true,
    autoPan: true
}).addTo(mymap);


 var circle = L.circle([50.895763, -1.150556], {
    color: 'red',
    fillColor: '#f03',
    fillOpacity: 0.5,
    radius: 200
}).addTo(mymap);


</script>
</body>

</body>
</html>

我需要检测标记何时进出圆圈。

我该怎么做?

【问题讨论】:

    标签: javascript leaflet maps geofencing


    【解决方案1】:
    • 你可以听drag event在拖动标记时采取行动
    • 然后您可以确定标记是否在您的圆圈内,例如通过计算到中心的距离。

    有点像

    marker.on('drag', function(e) {
        // distance between the current position of the marker and the center of the circle
        var d = mymap.distance(e.latlng, circle.getLatLng());
    
        // the marker is inside the circle when the distance is inferior to the radius
        var isInside = d < circle.getRadius();
    
       // let's manifest this by toggling the color
        circle.setStyle({
            fillColor: isInside ? 'green' : '#f03'
        })
    });
    

    还有一个演示

    var mymap = L.map('mapid', {
        center: [50.895763, -1.150556],
        zoom: 16
    });
    
    L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1Ijoic3RldmVuc2F0Y2giLCJhIjoiY2p5eDR6MWgzMHRvbjNocnJkN2d2MjRwaSJ9.wd0OtBUQQfUtNxdduQA3lg', {
            maxZoom: 18,
            attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
                '<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
                'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
            id: 'mapbox.streets'
        }).addTo(mymap);
    
    var marker = new L.marker([50.896422, -1.148444],{
        draggable: true,
        autoPan: true
    }).addTo(mymap);
    
    var circle = L.circle([50.895763, -1.150556], {
        color: 'red',
        fillColor: '#f03',
        fillOpacity: 0.5,
        radius: 100
    }).addTo(mymap);
    
    marker.on('drag', function(e) {
        var d = mymap.distance(e.latlng, circle.getLatLng());
        var isInside = d < circle.getRadius();
        circle.setStyle({
            fillColor: isInside ? 'green' : '#f03'
        })
    });
    <link href='https://api.mapbox.com/mapbox.js/plugins/leaflet-locatecontrol/v0.43.0/css/font-awesome.min.css' rel='stylesheet' />
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
    
    <script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
    
    <script src="https://cdn.jsdelivr.net/npm/@turf/turf@5/turf.min.js"></script>
    
    <div id="mapid" style="height: 180px"></div>

    【讨论】:

      【解决方案2】:

      另一种方法是检查圆圈是否在标记被拖动到的像素处呈现;这可以通过利用Leaflet.CheapLayerAt plugin 来完成,例如:

      <script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
      <script src="https://unpkg.com/leaflet.cheaplayerat@0.1.2/Leaflet.CheapLayerAt.js"></script>
      

      marker.on('dragend', function(ev) {
          // Hide the marker momentarily, so CheapLayerAt doesn't return it
          marker.getElement().style.display = 'none';
      
          if (map.getLayerAtLatLng(marker.getLatLng()) === circle) {
            // The marker was dragged inside
          } else {
            // The marker was dragged outside
          }
      
          // Display the marker icon again
          marker.getElement().style.display = 'inherit';
      });
      

      这种方法有一些缺点 - 在拖动过程中很难使用 id ,因为隐藏标记然后在拖动操作中再次显示它可能会触发更多 DOM 事件并搞砸事情。如果标记看起来像默认标记,则可以计算像素下的图层就在标记的尖端下方,例如:

      marker.on('drag', function(ev) {
          var pxPos = map.latLngToContainerPoint(marker.getLatLng());
          pxPos.y += 1;
      
          if (map.getLayerAt(pxPos) === circle) {
            // The marker was dragged inside
          } else {
            // The marker was dragged outside
          }
      });
      

      请记住,当标记被拖到圆圈的边框上时,这种方法会告诉您。如果圆的stroke weight 太宽,即使标记到圆心的距离大于圆的半径,也会在标记刚好越过边界时得到结果。

      因此,即使这回答了您的问题(“标记何时拖过圆圈?”),我认为您问错了问题。对于地理围栏,您想知道一个点是否在另一个已知点的给定距离内,所以我会选择@nikoshr 的答案。

      【讨论】:

        猜你喜欢
        • 2015-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-16
        • 1970-01-01
        • 2018-08-26
        • 2018-10-14
        • 1970-01-01
        相关资源
        最近更新 更多