javascript 查找离我的地理位置最近的标记 Google Maps API V3

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21634343/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 21:22:50  来源:igfitidea点击:

Find nearest marker to my geolocation Google Maps API V3

javascriptgoogle-mapsgoogle-maps-api-3geolocationgoogle-maps-markers

提问by Mr Dansk

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.

我有一个脚本显示了我在页面中实现的谷歌地图,目前它显示了一系列由雷达搜索生成的标记。我想我可能已经将这些生成的标记放入一个数组中,但我不知道如何做到这一点。我还查找了“haversine 公式”,因为这似乎是计算 Geolocation 和数组中点之间距离的一种方法。我希望能够使用标签 ID“#findMe”来执行搜索,因此单击它会找到离我的地理位置最近的标记,然后用它打印警报。我在使用 google api 内置方法时遇到了困难,但我再次认为我需要将标记放入数组中。

AMENDED CODE- Is this right Dr.Molle?

修改后的代码- 这是正确的 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')
  }
});


});

回答by Dr.Molle

Populating an array with these markers:

使用这些标记填充数组:

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

    return marker;
    
  2. 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);
    }
    
  1. 让 createMarker 函数返回标记,在函数末尾添加:

    return marker;
    
  2. 存储数组(例如作为 #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):

还将地理定位返回的位置存储在某处,(例如也作为#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)

要找到最近的标记,您可以使用computeDistanceBetween几何库的方法-method(不要忘记加载库,默认情况下不会加载)

$( "#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')
  }
});