I succeeded to determine if the user is within a certain distance of a single marker.
What I want to do next is to have the script check, if the user is close to one of multiple locations stored in an array. If yes, I want to have the script trigger the event specific to the respective location.
Here is my code:
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=geometry&sensor=true"></script>
<script>
var map, GeoMarker;
function initialize() {
var mapOptions = {
panControl: false,
mapTypeControl: false,
streetViewControl: false,
overviewMapControl: false,
disableDoubleClickZoom: false,
scrollwheel: false,
zoom: 17,
center: new google.maps.LatLng(99.000, 10.000),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
// Markers
var locations = [
['1', 49.463344,11.079942, 6],
['2', 49.462309,11.078335, 4],
['3', 49.463466,11.084214, 5],
['4', 49.46348,11.076061, 3],
['5', 49.464345,11.07885, 2],
['6', 49.461095,11.079601, 1]
];
var infowindow = new google.maps.InfoWindow();
var mark1, i;
for (i = 0; i < locations.length; i++) {
mark1 = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
google.maps.event.addListener(mark1, 'click', (function(mark1, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, mark1);
}
})(mark1, i));
}
GeoMarker = new GeolocationMarker();
var IsWithinRadius = false;
var RadiusInMeters = 10;
var LocationOfInterest = new google.maps.LatLng(49.463344,11.079942); // Needs to be a variable!
google.maps.event.addListener(GeoMarker, 'position_changed', function() {map.setCenter(this.getPosition());
var UserPosition = this.getPosition();
var DisplayElement = document.getElementById('UserCoordinates');
if(UserPosition === null) {IsWithinRadius = false;}
var IsCurrentPositionInRadius =
Math.abs(google.maps.geometry.spherical.computeDistanceBetween(UserPosition, LocationOfInterest)) <= RadiusInMeters; // Radius reached?
var JustEnteredRadius = !IsWithinRadius && IsCurrentPositionInRadius; // Radius reached!
IsWithinRadius = IsCurrentPositionInRadius;
if(JustEnteredRadius) {
// Trigger Event
}
}
});
GeoMarker.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
As you can see, I have a script that checks if the user is within a radius of 10 meters around a specific coordinate. How do I have to modify my script in order to have it check for all the locations in the array?
Help greatly appreciated!
When you create the markers, either store them in an array or just convert each location to that marker and store the locations data within the marker it's self. Then you need a function to loop through that array and check and store each markers distance from the user, placing each marker into a new array for temporary use. Then sort the markers in that new array by distance from user, then remove any markers from that array which are greater than max distance from user. Once you have this array, if there's anything left in it you know that the first item is the closest marker. You determine what 'event' you wish to have happen based upon which marker you are currently dealing with.
For example, here is a demo which utilizes a marker that follows your mouse to simulate an instance of GeolocationMarker. Note that for this example the radiusInMeters is set to 100 meters to make the demo simpler to actuate, and the demo also only acts upon markers which have not yet been 'visited' by the user.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Markers Treasure Hunt</title>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry&sensor=false"></script>
</head>
<body>
<div id="map_canvas" style="width:500px; height:400px; margin:0 auto;"></div>
<div id="UserCoordinates" style="text-align:center;">Mouse over the map and go close to the markers</div>
<script>
function initialize() {
var i, marker, GeoMarker,
gm = google.maps,
mapOptions = {
panControl: false,
mapTypeControl: false,
streetViewControl: false,
overviewMapControl: false,
disableDoubleClickZoom: false,
scrollwheel: false,
zoom: 17,
center: new google.maps.LatLng(49.452, 11.077),
mapTypeId: google.maps.MapTypeId.ROADMAP
},
map = new gm.Map(document.getElementById('map_canvas'), mapOptions),
locations = [
['Treasure 1', 49.463344, 11.079942, 6],
['Treasure 2', 49.462309, 11.078335, 4],
['Treasure 3', 49.463466, 11.084214, 5],
['Treasure 4', 49.46348, 11.076061, 3],
['Treasure 5', 49.464345, 11.07885, 2],
['Treasure 6', 49.461095, 11.079601, 1]
],
infowindow = new gm.InfoWindow(),
markersVisited = 0,
bounds = new gm.LatLngBounds(),
GeoMarker = new gm.Marker({
position: new gm.LatLng(100, 0),
icon: 'http://maps.google.com/mapfiles/kml/pal3/icon20.png'
});
gm.event.addListener(map, 'mousemove', function (evt) {
GeoMarker.setPosition(evt.latLng);
});
for (i = 0; i < locations.length; i++) {
latLng = new gm.LatLng(locations[i][1], locations[i][2]);
bounds.extend(latLng);
marker = new gm.Marker({
position: latLng,
map: map,
icon: 'http://google.com/mapfiles/kml/paddle/'+ (i + 1) +'-lv.png',
index: i,
title: locations[i][0],
data: locations[i][3],
visited: false
});
gm.event.addListener(marker, 'click', function () {
infowindow.setContent(this.title);
infowindow.open(map, this);
});
locations[i] = marker;
}
map.fitBounds(bounds);
function getClosestMarkers(userPosition, maxDistance) {
var i, marker, mPos,
len = locations.length,
arr = [];
//assign distanceFromUser for all markers
for (i = 0; i < len; i++) {
marker = locations[i];
mPos = marker.getPosition();
marker.distanceFromUser = gm.geometry.spherical.computeDistanceBetween(userPosition, mPos);
//ignoring markers which have been 'visited' already, if they
//have not yet been 'visited', store them in arr
if (!marker.visited) {
arr.push(marker);
}
}
//arrange items in arr by distanceFromUser, closest to furthest
arr.sort(function (m1, m2) {
var a = m1.distanceFromUser,
b = m2.distanceFromUser;
if (a == b) {
return 0;
}
return (a > b) ? 1 : -1;
});
//remove all markers from arr which are greater than maxDistance away from userPosition
for (i = arr.length - 1; i >= 0; i--) {
marker = arr[i];
if (marker.distanceFromUser > maxDistance) {
arr.pop();
}
}
return arr;
}
gm.event.addListener(
GeoMarker,
'position_changed',
function () {
var marker, closestMarkers,
radiusInMeters = 100,
userPosition = this.getPosition(),
displayElement = document.getElementById('UserCoordinates');
if (userPosition === null) {
return;
}
//only use the below line with your actual GeoMarker instance of GeolocationMarker
//map.setCenter(userPosition);
closestMarkers = getClosestMarkers(userPosition, radiusInMeters);
if (markersVisited == locations.length) {
displayElement.innerHTML = 'All markers already found';
} else if (closestMarkers.length) {
//here is where you would determine what event to trigger,
//based upon which marker closestMarkers[0] is
//location.replace("puzzle.php");
marker = closestMarkers[0];
displayElement.innerHTML = marker.title;
displayElement.innerHTML += ', marker.data = '+ marker.data +', marker.index = '+ marker.index;
marker.visited = true;
markersVisited++;
}
}
);
GeoMarker.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</body>
</html>
Example fiddle: http://jsfiddle.net/uXpGD/
Hopefully you can see how to incorporate GeolocationMarker instead of the mousemove stuff there, basically would just need to add the GeolocationMarker script, remove the event listener for mousemove over the map, create your GeolocationMarker instead of the Marker used here, and uncomment the map.setCenter(userPosition) call in the position_changed event handler. Oh, and change the radiusInMeters back to 10