1

I am working on a fast food customer service application The call center should be able to add the address of the caller (a marker on the map) by clicking on the map that already has old markers (the branches) and automatically it should calculate the closest branch from the marker added.

I could add the markers into an array and I used this calculation function, nevertheless I need to know how to call this function after the clicking event and connect it to the new marker added. The code is as follow

Identifying the branches

var map;
var markers = [];
var marker, i;
var locations = [
 ['Title A', 3.180967,101.715546, 1],
 ['Title B', 3.200848,101.616669, 2],
 ['Title C', 3.147372,101.597443, 3],
 ['Title D', 3.19125,101.710052, 4]];

The Initialization function

function initialize() {
   var haightAshbury = new google.maps.LatLng(3.171368, 101.653404);
   var mapOptions = {
      zoom: 12,
      center: haightAshbury,
      mapTypeId: google.maps.MapTypeId.TERRAIN
   };

   map = new google.maps.Map(document.getElementById('map-canvas'),
      mapOptions);

   google.maps.event.addListener(map, 'click', function(event) {
      addMarker(event.latLng);
   });

   for (i = 0; i < locations.length; i++) {  
      marker = new google.maps.Marker({
         position: new google.maps.LatLng(locations[i][1], locations[i][2]),
         map: map
      });

      google.maps.event.addListener(marker, 'click', (function(marker, i) {
         return function() {
            infowindow.setContent(locations[i][0]);
            infowindow.open(map, marker);
         }
      })(marker, i));

      google.maps.event.addListener(map, 'click', find_closest_marker);

   }
}

Adding new marker

function addMarker(location) {
   var marker1 = new google.maps.Marker({
      position: location,
      map: map
   });

   markers.push(marker); 
}

Adding new marker to the array

setAllMap(map) 
{
   for (var i = 0; i < markers.length; i++)
   {
      markers[i].setMap(map);
   }
}

Calculating function

function rad(x) {return x*Math.PI/180;}
function find_closest_marker( event ) {
var lat = event.latLng.lat();
var lng = event.latLng.lng();
var R = 6371; // radius of earth in km
var distances = [];
var closest = -1;
    for( i=0;i<map.markers.length; i++ ) {
       var mlat = map.markers[i].position.lat();
       var mlng = map.markers[i].position.lng();
       var dLat  = rad(mlat - lat);
       var dLong = rad(mlng - lng);
       var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
       Math.cos(rad(lat)) * Math.cos(rad(lat)) * Math.sin(dLong/2) * Math.sin(dLong/2);
       var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
       var d = R * c;
       distances[i] = d;
       if ( closest == -1 || d < distances[closest] ) {
          closest = i;
       }
    }

alert(map.markers[closest].title);
}

Thank you.

Community
  • 1
  • 1
Hashim Adel
  • 715
  • 3
  • 8
  • 14

2 Answers2

1

Use Google Maps Geometry Library to calculate distances. Both parameters must be LatLng objects.

google.maps.geometry.spherical.computeDistanceBetween(markerPosition, mainPosition);

Ofcourse you need to load geometry library

&libraries=geometry

Working example of your code in jsfiddle. Closest marker will be printed in console (F12). Note the comments in code, all mistakes fixed.

Rene Korss
  • 5,414
  • 3
  • 31
  • 38
  • whats the use of this line ?`$(document).ready(function () { initialize();` – Hashim Adel Mar 10 '14 at 09:56
  • The example is working perfect on the link you gave me, but when I copy the code in my localhost project the map does not show up are not I supposed to just add the library like this `` – Hashim Adel Mar 10 '14 at 10:41
  • You must call `initialize();` on page load. Thats what `$(document).ready(function () {initialize();});` does with jQuery. You can also call it simply in script tag. I updated example not to use jQuery. And yes, you have to add library like that. – Rene Korss Mar 10 '14 at 12:54
  • Thank you so much, best support ever seen since I joined – Hashim Adel Mar 10 '14 at 15:29
0

Before adding new marker to map and pushing to the array, you need to pass latitude and longitude values of that point to the function find_closest_marker().

google.maps.event.addListener(map, 'click', function(event) {
   find_closest_marker( event );
   addMarker(event.latLng);
});

will alert closest marker's title.

However, your code has a few mistakes:

  1. Your marker array is just markers, but in find_closest_marker, it is map.markers[] so you must change them to markers[].
  2. In addMarker(), you are defining your marker with name marker1 but pushing to array as marker.
  3. Not a mistake but forgotten one, when you are creating markers from your locations[] array in for loop, you need also push them into your markers[] array: markers.push(marker); at the bottom of for loop.
alpakyol
  • 2,402
  • 2
  • 29
  • 35
  • Should I put both the `markers[]` and `locations[]` in one array? – Hashim Adel Mar 10 '14 at 08:26
  • No you won't put `locations`, but when you are creating markers from `locations` array in for loop, you need also put them into array `markers`. – alpakyol Mar 10 '14 at 08:31
  • Followed all your steps exactly like they are, and it alerts "undefined" right now, I also have the following warning when inspect the page "event.returnValue is deprecated. Please use the standard event.preventDefault() instead." , where do you think the problem could be? – Hashim Adel Mar 10 '14 at 08:42
  • I have found that your markers don't have titles and we are trying to show titles. Try displaying latitude-longitude values in alert: `alert(markers[closest].getPosition().lat());` for latitude – alpakyol Mar 10 '14 at 09:18
  • Also look at infowindow, you are not creating them as new infowindows. – alpakyol Mar 10 '14 at 09:21