Google maps drag rectangle to select markers
It looks like the google.maps.Rectangle.getBounds is returning "invalid" bounds
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))
If you extend an empty google.maps.LatLng object with your two corners, it will work:
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
code snippet:
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>
I have some change base on geocodezip's working version.
If you use "extend" of LatLngBounds, it will be only getting bigger but not smaller when you move inside. So I generate LatLngBounds every mouse move to fit my requirement. (It might be optimized in another way I guess.)
Update: Found another issue, if user released the shift key before mouse up, the gridbound will stick on the map, fixed it in the following code.
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;
/*........*/
- Working fiddle http://jsfiddle.net/7ZxMA/4/
- demo http://fiddle.jshell.net/7ZxMA/4/show/
Update: Found another scenario that you might interested.
use a button to select map. (User could click the "select map" button to select markers or use shift key to select markers.)
- working fiddle http://jsfiddle.net/7ZxMA/6/
- demo http://fiddle.jshell.net/7ZxMA/6/show/
You missuse constructor of the google.maps.LatLngBounds class
. According to documentation you must pass two arguments: south-west and north-east corners. However, sometimes you pass south-east and north-west corners. This probably has impact on .contains
method.