【问题标题】:Google maps drag rectangle to select markers谷歌地图拖动矩形选择标记
【发布时间】:2013-07-14 11:01:06
【问题描述】:

我正在尝试在谷歌地图上绘制一个矩形并检测矩形边界内是否有任何标记。

要绘制一个矩形,请按住 shift 键,单击并拖动。

我在这里有一个工作示例 - http://jsfiddle.net/dbwPQ/3/

为什么.contains方法只有在矩形是从左下角到右上角或从右上角到左下角绘制时才返回true。

然而从左上到右下或从右下到左上绘制的相同区域返回 false????

                if (boundsSelectionArea.contains(markers[key].position))
            //if (gribBoundingBox.getBounds().getNorthEast().lat() <= markers[key].position.lat() &&
            //    gribBoundingBox.getBounds().getSouthWest().lat() >= markers[key].position.lat() && 
            //    gribBoundingBox.getBounds().getSouthWest().lng() <= markers[key].position.lng() && 
            //    gribBoundingBox.getBounds().getNorthEast().lng() >= markers[key].position.lng() ) 
            {
                //if(flashMovie !== null && flashMovie !== undefined) {
                console.log("User selected:" + key + ", id:" + markers[key].id);
                //}
            } else {
                //if(flashMovie !== null && flashMovie !== undefined) {
                console.log("User NOT selected:" + key + ", id:" + markers[key].id);
                //} 
            }

UPDATE 这行得通,但我不知道为什么? http://jsfiddle.net/dbwPQ/4/

【问题讨论】:

    标签: javascript jquery google-maps-api-3


    【解决方案1】:

    看起来 google.maps.Rectangle.getBounds 正在返回“无效”边界

    key:Vince posn:(53.801279, -1.5485670000000482) out of bnds:((55.45394132943307, -4.0869140625), (52.72298552457069, 1.7138671875))
    key:Vince posn:(53.801279, -1.5485670000000482) in bnds:((52.26815737376817, -4.04296875), (55.65279803318956, 2.2412109375))
    

    如果你用你的两个角扩展一个空的 google.maps.LatLng 对象,它会起作用:

    google.maps.event.addListener(themap, 'mousemove', function (e) {
        if (mouseIsDown && shiftPressed) {
            if (gribBoundingBox !== null) // box exists
            {
                bounds.extend(e.latLng);                
                gribBoundingBox.setBounds(bounds); // If this statement is enabled, I lose mouseUp events
    
            } else // create bounding box
            {
                bounds = new google.maps.LatLngBounds();
                bounds.extend(e.latLng);
                gribBoundingBox = new google.maps.Rectangle({
                    map: themap,
                    bounds: bounds,
                    fillOpacity: 0.15,
                    strokeWeight: 0.9,
                    clickable: false
                });
            }
        }
    });
    

    working example

    代码 sn-p:

    var map;
    var markers = {};
    var bounds = null;
    // add marker to object
    var posi = new google.maps.LatLng(53.801279, -1.548567);
    var name = 'Vince';
    markers[name] = {};
    markers[name].id = 1;
    markers[name].lat = 53.801279;
    markers[name].lng = -1.548567;
    markers[name].state = 'Online';
    markers[name].position = posi;
    markers[name].selected = false;
    
    $(document).ready(function() {
    
      var mapOptions = {
        zoom: 5,
        center: new google.maps.LatLng(53.801279, -1.548567),
        mapTypeId: google.maps.MapTypeId.ROADMAP
      };
      map = new google.maps.Map(document.getElementById('map'), mapOptions);
      var infowindow = new google.maps.InfoWindow();
      for (var key in markers) {
        var marker = new google.maps.Marker({
          position: new google.maps.LatLng(markers[key].lat, markers[key].lng),
          map: map
        });
        markers[key].marker = marker;
    
        google.maps.event.addListener(marker, 'click', (function(marker, key) {
          return function() {
            infowindow.setContent(key);
            infowindow.open(map, marker);
          }
        })(marker, key));
      }
    
      // Start drag rectangle to select markers !!!!!!!!!!!!!!!!
      var shiftPressed = false;
    
      $(window).keydown(function(evt) {
        if (evt.which === 16) { // shift
          shiftPressed = true;
        }
      }).keyup(function(evt) {
        if (evt.which === 16) { // shift
          shiftPressed = false;
        }
      });
    
      var mouseDownPos, gribBoundingBox = null,
        mouseIsDown = 0;
      var themap = map;
    
      google.maps.event.addListener(themap, 'mousemove', function(e) {
        if (mouseIsDown && shiftPressed) {
          if (gribBoundingBox !== null) // box exists
          {
            bounds.extend(e.latLng);
            gribBoundingBox.setBounds(bounds); // If this statement is enabled, I lose mouseUp events
    
          } else // create bounding box
          {
            bounds = new google.maps.LatLngBounds();
            bounds.extend(e.latLng);
            gribBoundingBox = new google.maps.Rectangle({
              map: themap,
              bounds: bounds,
              fillOpacity: 0.15,
              strokeWeight: 0.9,
              clickable: false
            });
          }
        }
      });
    
      google.maps.event.addListener(themap, 'mousedown', function(e) {
        if (shiftPressed) {
    
          mouseIsDown = 1;
          mouseDownPos = e.latLng;
          themap.setOptions({
            draggable: false
          });
        }
      });
    
      google.maps.event.addListener(themap, 'mouseup', function(e) {
        if (mouseIsDown && shiftPressed) {
          mouseIsDown = 0;
          if (gribBoundingBox !== null) // box exists
          {
            var boundsSelectionArea = new google.maps.LatLngBounds(gribBoundingBox.getBounds().getSouthWest(), gribBoundingBox.getBounds().getNorthEast());
    
            for (var key in markers) { // looping through my Markers Collection 
    
              //                    if (boundsSelectionArea.contains(markers[key].marker.getPosition())) 
              if (gribBoundingBox.getBounds().contains(markers[key].marker.getPosition())) {
                //if(flashMovie !== null && flashMovie !== undefined) {
                markers[key].marker.setIcon("http://maps.google.com/mapfiles/ms/icons/blue.png")
                document.getElementById('info').innerHTML += "key:" + key + " posn:" + markers[key].marker.getPosition() + " in bnds:" + gribBoundingBox.getBounds() + "<br>";
                // console.log("User selected:" + key + ", id:" + markers[key].id);
                //}   
              } else {
                //if(flashMovie !== null && flashMovie !== undefined) {
                markers[key].marker.setIcon("http://maps.google.com/mapfiles/ms/icons/red.png")
                document.getElementById('info').innerHTML += "key:" + key + " posn:" + markers[key].marker.getPosition() + " out of bnds:" + gribBoundingBox.getBounds() + "<br>";
                // console.log("User NOT selected:" + key + ", id:" + markers[key].id);
                //} 
              }
            }
    
            gribBoundingBox.setMap(null); // remove the rectangle
          }
          gribBoundingBox = null;
    
        }
    
        themap.setOptions({
          draggable: true
        });
        //stopDraw(e);
      });
    
    });
    #map {
      height: 500px;
      width: 500px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
    <div id="map"></div>
    <div id="info"></div>

    【讨论】:

    • 它不再起作用了。就我而言,我从 mousedown 处理程序中删除了 themap.setOptions({draggable: false}) 并将其移动到 keydown 处理程序中,在此行 shiftPressed = true 之后。有了这些变化,它就可以工作了。
    • 顺便说一下,draggable 已被弃用。所以你可以使用gestureHandling,在谷歌地图参考中查看更多。 developers.google.com/maps/documentation/javascript/…
    • 它适用于我(在桌面上使用 Chrome),shift-mousedown 开始矩形选择,mouseup 结束
    • 如果您使用 `` 保留对边界框的引用,并且在鼠标移动时重新创建新边界框之前,将前一个边界框的映射设置为 null,则效果很好:if (this.gripBoundingBox) this.gripBoundingBox.setMap(null);
    • 它在桌面上的 Chrome 中仍然适用于我。如果您遇到问题,请使用minimal reproducible example 创建一个新问题,并提供有关如何重现问题的说明。
    【解决方案2】:

    我根据 geocodezip 的工作版本进行了一些更改。

    如果您使用 LatLngBounds 的“扩展”,当您向内移动时,它只会变大而不是变小。所以我每次鼠标移动都会生成 LatLngBounds 以满足我的要求。 (我猜它可能会以另一种方式进行优化。)

    更新:发现另一个问题,如果用户在鼠标上移之前释放了shift键,网格会粘在地图上,在下面的代码中修复了它。

    google.maps.event.addListener(themap, 'mousemove', function (e) {
    +   if (mouseIsDown && (shiftPressed|| gribBoundingBox != null) ) {
            if (gribBoundingBox !== null) // box exists
            {         
    +           var newbounds = new google.maps.LatLngBounds(mouseDownPos,null);
    +           newbounds.extend(e.latLng);    
    +           gribBoundingBox.setBounds(newbounds); // If this statement is enabled, I lose mouseUp events
    
            } else // create bounding box
            {
                gribBoundingBox = new google.maps.Rectangle({
                    map: themap,
    +               bounds: null,
                    fillOpacity: 0.15,
                    strokeWeight: 0.9,
                    clickable: false
                });
            }
        }
    });
    
    google.maps.event.addListener(themap, 'mouseup', function (e) {
    +   if (mouseIsDown && (shiftPressed|| gribBoundingBox != null)) {
            mouseIsDown = 0;
    
        /*........*/
    

    更新: 找到了您可能感兴趣的另一个场景。

    使用按钮选择地图。 (用户可以点击“选择地图”按钮选择标记或使用shift键选择标记。)

    【讨论】:

    • @tonyq 当鼠标悬停在标记(或其他谷歌地图对象)上时它也会中断任何想法如何解决?
    • 谢谢你,非常适合我的项目 :)
    【解决方案3】:

    你误用了google.maps.LatLngBounds class 的构造函数。根据documentation,您必须传递两个参数:西南角和东北角。但是,有时您会经过东南角和西北角。这可能对.contains 方法有影响。

    【讨论】:

      猜你喜欢
      • 2016-04-10
      • 1970-01-01
      • 2012-08-07
      • 2011-08-07
      • 2016-08-30
      • 1970-01-01
      • 1970-01-01
      • 2015-06-04
      • 2011-03-25
      相关资源
      最近更新 更多