8

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

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

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

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

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

                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);
                //} 
            }

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

4

3 回答 3

17

看起来 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
            });
        }
    }
});

工作示例

代码片段:

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>

于 2013-07-16T14:13:23.063 回答
9

我根据 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 键选择标记。)

于 2014-02-09T07:52:31.997 回答
2

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

于 2013-07-16T13:42:11.767 回答