Find nearest marker to my geolocation Google Maps API V3

geolocation, google-maps, google-maps-api-3, google-maps-markers, javascript

Solution

Populating an array with these markers:

let the createMarker-function return the marker, add this at the end of the function:

return marker;

store the array (e.g. as data-property of #findMe )

function callback(results, status) {
  var markers=[];
  if (status == google.maps.places.PlacesServiceStatus.OK) {
    for (var i = 0; i < results.length; i++) {
      markers.push(createMarker(results[i]));
    }
  }
  $('#findMe').data('markers',markers);
}

also store the position returned by geolocation somewhere, (e.g. also as data of #findMe):

  //add this after defining pos in the success-callback of geolocation
  $('#findMe').data('pos',pos);

To find the nearest marker you may use the method `computeDistanceBetween`-method of the geometry-library(don't forget to load the library, it's not loaded by default)

$( "#findMe" ).click(function() {

  var pos     = $(this).data('pos'),
      markers = $(this).data('markers'),
      closest;

  if(!pos || !markers){
    return;
  }

  $.each(markers,function(){
    var distance=google.maps.geometry.spherical
                  .computeDistanceBetween(this.getPosition(),pos);
    if(!closest || closest.distance > distance){
      closest={marker:this,
               distance:distance}
    }
  });
  if(closest){
    //closest.marker will be the nearest marker, do something with it
    //here we simply trigger a click, which will open the InfoWindow 
    google.maps.event.trigger(closest.marker,'click')
  }
});

Problem

I have a script showing a Google map I've implemented into my page, currently it shows a series of markers generated by a radar-search. I think I may have put these generated markers in to an array but I am not sure how to do this. I have also looked up the "haversine formula" as this seems to be one way of calculating the distance between the Geolocation and points in the array. I want to be able to use the tag Id "#findMe" to perform the search, so clicking it will find the nearest marker to my geolocation and then print an alert with it. I have had a crack at doing the google api built in method but I think again I need to put the markers in an array. AMENDED CODE - Is this right Dr.Molle? ``` jQuery(function($){ var $overlay = $('.overlay'), resize = true, map; var service; var marker = []; var pos; var infowindow; var placeLoc function initialize() { /*var mapOptions = { zoom: 8, center: new google.maps.LatLng(-34.397, 150.644), mapTypeId: google.maps.MapTypeId.ROADMAP }; map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions); }*/ var mapOptions = { zoom: 15 }; map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions); // Try HTML5 geolocation if(navigator.geolocation) { navigator.geolocation.getCurrentPosition(function(position) { var pos = new google.maps.LatLng(position.coords.latitude,position.coords.longitude); var request = { location:pos, radius:1000, }; infowindow = new google.maps.InfoWindow(); var service = new google.maps.places.PlacesService(map); service.nearbySearch(request,callback); pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); infowindow = new google.maps.InfoWindow({ map: map, position: pos, content: 'You Are Here' }); $('#findMe').data('pos',pos); map.setCenter(pos); }, function() { handleNoGeolocation(true); }); } else { // Browser doesn't support Geolocation handleNoGeolocation(false); } function callback(results, status) { var markers = []; if (status == google.maps.places.PlacesServiceStatus.OK) { for (var i = 0; i < results.length; i++) { markers.push(createMarker(results[i])); } } $('#findMe').data('markers',markers); } } function createMarker(place) { placeLoc = place.geometry.location; var marker = new google.maps.Marker({ map: map, position: place.geometry.location, icon: { path: google.maps.SymbolPath.CIRCLE, scale: 8, fillColor:'00a14b', fillOpacity:0.3, fillStroke: '00a14b', strokeWeight:4, strokeOpacity: 0.7 }, }); google.maps.event.addListener(marker, 'click', function() { infowindow.setContent(place.name); infowindow.open(map, this); }); return marker; } function handleNoGeolocation(errorFlag) { if (errorFlag) { var content = 'Error: The Geolocation service failed.'; } else { var content = 'Error: Your browser doesn\'t support geolocation.'; } var options = { map: map, position: new google.maps.LatLng(60, 105), content: content }; var infowindow = new google.maps.InfoWindow(options); map.setCenter(options.position); } google.maps.event.addDomListener(window, 'load', initialize); $('#show').click(function(){ $overlay.show(); if ( resize ){ google.maps.event.trigger(map, 'resize'); resize = false; } }); $('.overlay-bg').click(function(){ $overlay.hide(); }); $( "#findMe" ).click(function() { var pos = $(this).data('pos'), markers = $(this).data('markers'), closest; if(!pos || !markers){ return; } $.each(markers,function(){ var distance=google.maps.geometry.spherical .computeDistanceBetween(this.getPosition(),pos); if(!closest || closest.distance > distance){ closest={marker:this, distance:distance} } }); if(closest){ //closest.marker will be the nearest marker, do something with it //here we simply trigger a click, which will open the InfoWindow google.maps.event.trigger(closest.marker,'click') } }); }); ```

Original source