如何在谷歌地图中找到最近的坐标

时间:2015-01-26 06:49:34

标签: javascript google-maps google-maps-api-3

我目前正在使用输入字段,在输入地址时,系统会向用户指定Google地图上最近的标记。

我到目前为止所做的工作是能够让某人点击标记,点击“获取路线”,在javascript中调用calcRoute功能并向用户提供路线。

然而,当有人输入地址时,我仍然找不到一种方法可以动态找到最近标记的经度和纬度。

任何人都可以帮助我吗?

<!DOCTYPE html>
<html>
  <head>
    <style type="text/css">
      html, body { height: 100%; width: 100%;}
      #map-canvas { height: 100%; margin: 0; padding: 0; width: 80%; float: right;}
      #etc { height: 100%; margin: 0; padding: 0; width: 20%; float: left;}
      .highlight { background: red;}
    </style>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js"></script>
    <script type="text/javascript">
    var markers = [];

var directionsDisplay;
var directionsService = new google.maps.DirectionsService();

    function initialize() {
  directionsDisplay = new google.maps.DirectionsRenderer();

        var styles = [
          {
            stylers: [
              { hue: "#00ffe6" },
              { saturation: -20 }
            ]
          },{
            featureType: "road",
            elementType: "geometry",
            stylers: [
              { lightness: 100 },
              { visibility: "simplified" }
            ]
          },{
            featureType: "road",
            elementType: "labels",
            stylers: [
              { visibility: "off" }
            ]
          }
        ];
        var styledMap = new google.maps.StyledMapType(styles,{name: "Styled Map"});
        var mapOptions = {
          center: { lat: 49.154505, lng: -122.770924},
          zoom: 11,
        };
        var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
        directionsDisplay.setMap(map);
        directionsDisplay.setPanel(document.getElementById('directions-panel'));
        map.mapTypes.set('map_style', styledMap);
        map.setMapTypeId('map_style');

var locations = [
["Location 1<a href='#'' onclick='calcRoute(49.166563, -122.799776)'>Get Directions</a>", 49.166563, -122.799776],
["Location 2<a href='#'' onclick='calcRoute(49.11127, -122.67476)'>Get Directions</a>", 49.11127, -122.67476],
];

        var infowindow = new google.maps.InfoWindow();

        var marker, i;

        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,
            animation: google.maps.Animation.DROP
          });

          google.maps.event.addListener(marker, 'click', (function(marker, i) {
            return function() {
              infowindow.setContent(locations[i][0]);
              infowindow.open(map, marker);
              $("#locations li").removeClass("highlight");
              $("#locations li." + i).addClass("highlight");
            }
          })(marker, i));

          markers.push(marker);
        }

        }

function calcRoute(lat, lg) {
  var start = document.getElementById('start').value;
  var end = lat + ',' + lg;
  var request = {
    origin: start,
    destination: end,
    travelMode: google.maps.TravelMode.DRIVING
  };
  directionsService.route(request, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      directionsDisplay.setDirections(response);
    }
  });
}


      google.maps.event.addDomListener(window, 'load', initialize);

      $(document).ready(function(){
        $("#locations li").click(function(){
          var className = $(this).attr('class');
          google.maps.event.trigger(markers[className], 'click')
        })

        $("input").keyup(function(event){
          if(event.keyCode == 13){
              calcRoute();
          }
        });

      });
    </script>
  </head>
  <body>
  <div id="map-canvas"></div>
<div id="etc">
    <div id="control">
      <input type="text" name="start" id="start" value="Vancouver, BC" />
    </div>
    <div id="directions-panel"></div>
  <ul id="locations">
<li class='0'>Locaiton 1</li>
<li class='1'>Location 2</li>  </ul>
</div>
  </body>
</html>

更新了calcRoute功能并添加了find_closest_marker功能,但我一直收到Uncaught InvalidValueError: in property destination: not a string; and not a LatLng or LatLngLiteral: not an Object错误。似乎我的calcRoute函数在不等待find_closest_marker函数的结果的情况下继续执行。

function find_closest_marker( address ) {

    var lat, lng, pos;
    var closestMarker = -1;
    var closestDistance = Number.MAX_VALUE;

    geocoder.geocode( { 'address': address}, function(results, status) {
      // and this is function which processes response
      if (status == google.maps.GeocoderStatus.OK) {
        lat = results[0].geometry.location.lat();
        lng = results[0].geometry.location.lng();
        pos = new google.maps.LatLng(lat, lng);

          for( i=0;i<markers.length; i++ ) {
              var distance = google.maps.geometry.spherical.computeDistanceBetween(markers[i].getPosition(), pos);
              if ( distance < closestDistance ) {
                  closestMarker = i;
                  closestDistance = distance;
              }
          }

        }

          lat = markers[closestMarker].position.lat();
          lng = markers[closestMarker].position.lng();
          pos = new google.maps.LatLng(lat, lng);
          return pos;
    });
}

function calcRoute(lat, lg) {
  var start, end;
  
  start = document.getElementById('start').value;

  if (!lat) {
    end = find_closest_marker(start);
  }

  else {
    end = lat + ',' + lg;
  }

  var request = {
    origin: start,
    destination: end,
    travelMode: google.maps.TravelMode.DRIVING
  };
  directionsService.route(request, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      directionsDisplay.setDirections(response);
    }
  });
}

2 个答案:

答案 0 :(得分:1)

我找到了问题的解决方案。我试图挖掘一个解决方法并通过一个find_closest_marker执行完成后通过回调函数赋予变量值来解决问题:

&#13;
&#13;
    function find_closest_marker( address, callback ) {

      var lat, lng, pos;
      var closestMarker = -1;
      var closestDistance = Number.MAX_VALUE;

      geocoder.geocode( { 'address': address}, function(results, status) {
        // and this is function which processes response
        if (status == google.maps.GeocoderStatus.OK) {
          lat = results[0].geometry.location.lat();
          lng = results[0].geometry.location.lng();
          pos = new google.maps.LatLng(lat, lng);

            for( i = 0; i< markers.length; i++ ) {
                var distance = google.maps.geometry.spherical.computeDistanceBetween(markers[i].getPosition(), pos);
                if ( distance < closestDistance ) {
                    closestMarker = i;
                    closestDistance = distance;
                }
            }

            lat = markers[closestMarker].position.lat();
            lng = markers[closestMarker].position.lng();
            pos = new google.maps.LatLng(lat, lng);
            callback(pos);

          }
      });
    } // find_closest_marker

    function calculate_route(lat, lng) {
      var start, end;
      
      start = document.getElementById('start').value;

      if (!lat && !lng) {
        find_closest_marker(start, function(end) {
          var request = {
            origin: start,
            destination: end,
            travelMode: google.maps.TravelMode.DRIVING
          };
          directionsService.route(request, function(response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
              directionsDisplay.setDirections(response);
            }
          });
        });
      }

      else {
        end = lat + ',' + lng;
          var request = {
            origin: start,
            destination: end,
            travelMode: google.maps.TravelMode.DRIVING
          };
          directionsService.route(request, function(response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
              directionsDisplay.setDirections(response);
            }
          });
      }
    } //calculate_route
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我做了类似之前的事情并且现在正在运行:

HTML:

<script src="http://maps.google.com/maps/api/js?sensor=false&language=ar"  type="text/javascript"></script>
    <script type="text/javascript">        
        var markers = [
                            [24.46727273186149,39.606807231903076, 'Al salam Stop', '1'],
                            [24.422826,39.520943, 'ALduaytha Station', '2'],
                            [24.462189756758278,39.545153975486755, 'Prince Mohammed Spor City Station', '2'],
                            [24.468498279212913,39.615068435668945, 'Al Baqee Stop', '1'],
                            [24.467270,39.606753, 'Al salam Stop', '1'],
                            [24.467275173202733,39.6067750453949, 'Al salam Stop', '1'],
                            [24.41422098604895,39.62093710899353, 'Alia Mall Station', '2'],
                            [24.46727273186149,39.606807231903076, 'Al salam Stop', '1'],
                            [24.462189756758278,39.545153975486755, 'Prince Mohammed Spor City Station', '2'],
                            [24.46727273186149,39.606807231903076, 'Al salam Stop', '1'],
                            [24.422826,39.520943, 'ALduaytha Station', '2'],
                            [24.467270,39.606753, 'Al salam Stop', '1'],
                            [24.45985083570312,39.66432183980942, 'Al Khaledia Station', '2'],
                            [24.45985083570312,39.66432183980942, 'Al Khaledia Station', '2'],
                            [24.471681716990837,39.61108535528183, 'Saied Alshuhada', '1'],
                            [24.501539614912353,39.61090564727783, 'Saied Alshuhada station', '2'],
                            [24.471681716990837,39.61108535528183, 'Saied Alshuhada Stop', '1'],
                            [24.468498279212913,39.615068435668945, 'Al Baqee Stop', '1'],
                            [24.501539614912353,39.61090564727783, 'Saied Alshuhada Station', '2'],

        ];            

        var rendererOptions;
        var directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
        var directionsService = new google.maps.DirectionsService();
        var geocoder = new google.maps.Geocoder();
        var map;

        function initialize() {

            var mapOptions = {

                center: new google.maps.LatLng(24.4676711,39.610379),
                zoom: 15,
                mapTypeId: google.maps.MapTypeId.ROADMAP,
                streetViewControl: false,
                mapTypeControl: true,
                mapTypeControlOptions: {
                    style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
                    position: google.maps.ControlPosition.BOTTOM_CENTER
                },
                zoomControl: true,
                zoomControlOptions: {
                    style: google.maps.ZoomControlStyle.LARGE,
                    position: google.maps.ControlPosition.LEFT_BOTTOM
                },
                disableDefaultUI: true,
                scaleControl: true,
                styles: [{featureType: "landscape", stylers: [{saturation: -100}, {lightness: 65}, {visibility: "on"}]}, {featureType: "poi", stylers: [{saturation: -100}, {lightness: 51}, {visibility: "simplified"}]}, {featureType: "road.highway", stylers: [{saturation: -100}, {visibility: "simplified"}]}, {featureType: "road.arterial", stylers: [{saturation: -100}, {lightness: 30}, {visibility: "on"}]}, {featureType: "road.local", stylers: [{saturation: -100}, {lightness: 40}, {visibility: "on"}]}, {featureType: "transit", stylers: [{saturation: -100}, {visibility: "simplified"}]}, {featureType: "administrative.province", stylers: [{visibility: "off"}]/**/}, {featureType: "administrative.locality", stylers: [{visibility: "off"}]}, {featureType: "administrative.neighborhood", stylers: [{visibility: "on"}]/**/}, {featureType: "water", elementType: "labels", stylers: [{visibility: "on"}, {lightness: -25}, {saturation: -100}]}, {featureType: "water", elementType: "geometry", stylers: [{hue: "#ffff00"}, {lightness: -25}, {saturation: -97}]}]
            };
            map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);

            var infowindow = new google.maps.InfoWindow({
              maxWidth: 500,
            });

            var marker;

            var bounds = new google.maps.LatLngBounds();

            for (var i = 0; i < markers.length; ++i) {
                marker = new google.maps.Marker({
                    position: new google.maps.LatLng(markers[i][0], markers[i][1]),
                    map: map,
                    title:markers[i][2],
                    icon: '/images/'+markers[i][3]+'_icn.png' ,
                    optimized: false
                });

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

                  bounds.extend(new google.maps.LatLng(markers[i][0], markers[i][1]));
            }

            map.fitBounds(bounds);
        }

        function mylocation(position){
            // start the geolocation API
            if (navigator.geolocation) {
                // when geolocation is available on your device, run this function
                navigator.geolocation.getCurrentPosition(foundYou, notFound);
            } else {
                // when no geolocation is available, alert this message
                alert('Geolocation not supported or not enabled.');
            }

            var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

            // then try to reverse geocode the location to return a human-readable address
            geocoder.geocode({'latLng': latlng}, function(results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    // if the geolocation was recognized and an address was found
                    if (results[0]) {
                        // add a marker to the map on the geolocated point
                        marker = new google.maps.Marker({
                            position: latlng,
                            map: map
                        });
                        //set my location to get the closest point
                        find_closest_marker(position.coords.latitude, position.coords.longitude);
                    }
                } else {
                    // if the address couldn't be determined, alert and error with the status message
                    alert("Geocoder failed due to: " + status);
                }
            });
        }

        function rad(x) {return x*Math.PI/180;}
        function find_closest_marker( myLat, myLng ) {
            var lat = myLat;
            var lng = myLng;
            var R = 6371; // radius of earth in km
            var distances = [];
            var closest = -1;
            for( i=0;i<markers.length; i++ ) {
                var mlat = markers[i][0];
                var mlng = markers[i][1];
                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;
                }
            }

            var newpoint =  markers[closest][0]+','+markers[closest][1];
            return newpoint;
        }

        function notFound(msg) {  
          alert('Could not find your location :(')
        }
        function foundYou(position) {
            // convert the position returned by the geolocation API to a google coordinate object
            var latlng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
            // then try to reverse geocode the location to return a human-readable address
            geocoder.geocode({'latLng': latlng}, function(results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    // if the geolocation was recognized and an address was found
                    if (results[0]) {
                        // add a marker to the map on the geolocated point
                        marker = new google.maps.Marker({
                                position: latlng,
                                map: map
                        });
                        //set my location to get the closest point
                        var startpoint = find_closest_marker(position.coords.latitude, position.coords.longitude);
                        var endpoint = position.coords.latitude+','+position.coords.longitude;

                        calcRoute(endpoint, startpoint, '#ffff00');
                    }
                } else {
                    // if the address couldn't be determined, alert and error with the status message
                    alert("Geocoder failed due to: " + status);
                }
            });
        }

        function calcRoute(ss, ee, color, ide) {

            rendererOptions = {
             suppressMarkers : true,
             polylineOptions: {
              strokeColor: color
            }
          };

          directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);

          var start = ee.toString();
          var end = ss.toString();

          if(ide != null){
            var waypts = [];
            var checkboxArray = document.getElementById('points_'+ide);

            for (var i = 0; i < checkboxArray.length; i++) {
              waypts.push({
                  location:checkboxArray[i].value,
                  stopover:true});

            }

            var request = {
              origin:start,
              destination:end,
              waypoints: waypts,
              optimizeWaypoints: true,
              travelMode: google.maps.TravelMode.DRIVING
            };
          }else{
            var request = {
              origin:start,
              destination:end,
              travelMode: google.maps.TravelMode.DRIVING
            };
          }

          directionsService.route(request, function(response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
              directionsDisplay.setDirections(response);

                directionsDisplay.setMap(map);

            }
          });
        }

        google.maps.event.addDomListener(window, 'load', initialize);


      function clearWaypoints() {

        origin = null;
        destination = null;
        waypoints = [];
        directionsVisible = false;
      }

    function reset() {
        clearWaypoints();
        directionsDisplay.setMap(null);
        directionsDisplay.setPanel(null);
        directionsDisplay = new google.maps.DirectionsRenderer();
        directionsDisplay.setMap(map); 
      }
    </script>

JavaScript:

<div class="map_fullscreen" id="map_canvas"></div>

最后HTML:

{{1}}

并且它运行良好,没有错误