最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Get nearest location from a set of predefined locations with Google Maps Javascript API - Stack Overflow

programmeradmin2浏览0评论

I have a set of 2 predefined locations and based on user's input of zipcode, I need to show the nearest one.

So far, I have searched the user input location using the zipcode:

$("form#zipcodeSearch").on("submit", function(event){
    event.preventDefault();
    var jsonUrl = '='+$("input#zipcode").val();
    
    $.ajax({
        type: "POST",
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'text/plain'
        },
        dataType: "json",
        url: jsonUrl,
        success: function (data) {
           
            var lat = (data.results[0].geometry.bounds.northeast.lat + data.results[0].geometry.bounds.southwest.lat) / 2;
            var lng = (data.results[0].geometry.bounds.northeast.lng + data.results[0].geometry.bounds.southwest.lng) / 2;

            initialize(lat, lng);            
            
        }
    });

});

var map;
function initialize(lat, lng) {
    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(lat, lng);
            
            var infowindow = new google.maps.InfoWindow({
                map: map,
                position: pos,
                content: '<div style="width: 75px">You are here!</div>'
            });
            
            map.setCenter(pos);
            
        }, function() {
            handleNoGeolocation(true);
        }, {
            enableHighAccuracy: true
        });
    } else {
        // Browser doesn't support Geolocation
        handleNoGeolocation(false);
    }    
}

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);
}
*{
    margin: 0;
    padding: 0;
}

body{
    font-family: arial;
    font-size: 62.5%;        /* so, 10px = 1rem */
}

#map-canvas{
    z-index: -1;
    position: absolute;
    top: 0;
    height: 100%;
    width: 100%;
}
<script src=".1.1/jquery.min.js"></script>
<script src=".exp"></script>

<form id="zipcodeSearch">
    <input type="text" id="zipcode" placeholder="Enter Zipcode"/>
    <input type="submit" value="Search" />
</form>

<div id="map-canvas"></div>

I have a set of 2 predefined locations and based on user's input of zipcode, I need to show the nearest one.

So far, I have searched the user input location using the zipcode:

$("form#zipcodeSearch").on("submit", function(event){
    event.preventDefault();
    var jsonUrl = 'http://maps.googleapis./maps/api/geocode/json?address='+$("input#zipcode").val();
    
    $.ajax({
        type: "POST",
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'text/plain'
        },
        dataType: "json",
        url: jsonUrl,
        success: function (data) {
           
            var lat = (data.results[0].geometry.bounds.northeast.lat + data.results[0].geometry.bounds.southwest.lat) / 2;
            var lng = (data.results[0].geometry.bounds.northeast.lng + data.results[0].geometry.bounds.southwest.lng) / 2;

            initialize(lat, lng);            
            
        }
    });

});

var map;
function initialize(lat, lng) {
    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(lat, lng);
            
            var infowindow = new google.maps.InfoWindow({
                map: map,
                position: pos,
                content: '<div style="width: 75px">You are here!</div>'
            });
            
            map.setCenter(pos);
            
        }, function() {
            handleNoGeolocation(true);
        }, {
            enableHighAccuracy: true
        });
    } else {
        // Browser doesn't support Geolocation
        handleNoGeolocation(false);
    }    
}

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);
}
*{
    margin: 0;
    padding: 0;
}

body{
    font-family: arial;
    font-size: 62.5%;        /* so, 10px = 1rem */
}

#map-canvas{
    z-index: -1;
    position: absolute;
    top: 0;
    height: 100%;
    width: 100%;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis./maps/api/js?v=3.exp"></script>

<form id="zipcodeSearch">
    <input type="text" id="zipcode" placeholder="Enter Zipcode"/>
    <input type="submit" value="Search" />
</form>

<div id="map-canvas"></div>

jsFiddle

Any ideas on how to achieve this? If it is not possible with the JS API, is there any other API that can help me achieve this?

EDIT: Cleaned-up jsFiddle version

Share Improve this question edited Feb 9, 2017 at 19:50 Rahul Desai asked Jan 30, 2015 at 5:21 Rahul DesaiRahul Desai 15.5k20 gold badges88 silver badges145 bronze badges 5
  • What are the two locations? Why are you using the geolocation service if you are having the user enter the zip code? Here is an example that finds the closest point (of a lot more than two) to the geocoded point (can be a zip code) – geocodezip Commented Jan 30, 2015 at 5:32
  • @geocodezip Yes, I have cleaned up the code. In the example that you gave, is it possible to show the nearest location on the screen? Ideally, it should show the searched address and the nearest location. Is that possible? – Rahul Desai Commented Jan 30, 2015 at 5:58
  • What location? This is unclear. I do not see your set of 2 predefined locations? In any case, you can calculate distances with the geometry library (don't forget to include the library in your API call) and the puteDistanceBetween method. – MrUpsidown Commented Jan 30, 2015 at 7:12
  • Your "cleaned up" fiddle still doesn't have any markers on it. – geocodezip Commented Jan 30, 2015 at 12:00
  • @geocodezip I was able to solve this. Please see the answer below. Sorry, I added markers later. – Rahul Desai Commented Jan 30, 2015 at 12:18
Add a ment  | 

1 Answer 1

Reset to default 5

Update:
Keyless access to Google Maps Platform is now deprecated. You will need to have an API key with all your API calls to avoid service interruption . For further details please refer to http://g.co/dev/maps-no-account


Original Answer:
I was able to solve this in following way:

  1. Get lat, long co-ordinates of the input zipcode from this URL: http://maps.googleapis./maps/api/geocode/json?address=zipcode (add zipcode)
  2. Take average of the lats and longs of northeast and southwest returned in the response of this URL. Consider the calculated average lat and long as the input co-ordinates.
  3. Compute the distance to get the closest location using google.maps.geometry.spherical.puteDistanceBetween()
  4. Initialize the Google Map with all of the markers.
  5. Use google.maps.LatLngBounds() to adjust the zoom so that the map includes the input zipcode's location and the nearest searched location.

Here's a demo. The H icon stands for the input zipcode location and C icon stands for the closest location among the searched ones. (For now, I have kept only 2 predefined locations).

var predefinedLocations = [{
    "name": "Brookwood Medical Center",
    "lat": 33.4636415,
    "lng": -86.7771671
  },
  {
    "name": "Lutheran Medical Center",
    "lat": 40.646872,
    "lng": -74.020892
  }
];

$("form#zipcodeSearch").on("submit", function(event) {
  event.preventDefault();
  var jsonUrl = 'http://maps.googleapis./maps/api/geocode/json?address=' + $("input#zipcode").val();

  $.ajax({
    type: "POST",
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'text/plain'
    },
    dataType: "json",
    url: jsonUrl,
    success: function(data) {

      var lat = (data.results[0].geometry.bounds.northeast.lat + data.results[0].geometry.bounds.southwest.lat) / 2;
      var lng = (data.results[0].geometry.bounds.northeast.lng + data.results[0].geometry.bounds.southwest.lng) / 2;
      var p1, p2;

      predefinedLocations.forEach(function(obj) {
        p1 = new google.maps.LatLng(obj.lat, obj.lng);
        p2 = new google.maps.LatLng(lat, lng);

        obj.distance = calcDistance(p1, p2);
      });

      // sort by distance
      var locationInfo = predefinedLocations.sort(pare);

      //console.log('locationInfo', locationInfo);

      initializeGoogleMap(locationInfo, lat, lng);

    }
  });

});

var map;

function initializeGoogleMap(locationInfo, lat, lng) {
  var mapOptions = {
    zoom: 15
  };
  map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

  // zoom to only the input zipcode and closest location    
  var latlngbounds = new google.maps.LatLngBounds();
  latlngbounds.extend(new google.maps.LatLng(locationInfo[0].lat, locationInfo[0].lng));
  latlngbounds.extend(new google.maps.LatLng(lat, lng));
  map.fitBounds(latlngbounds);

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

  var marker, i;

  // set marker for input location
  setMarker(lat, lng, map, 'http://www.lsac/images/default-source/mainportalimages/icon-h-grey-bg.jpg?sfvrsn=2', "You are here!", i, infowindow);

  // set marker for closest location
  setMarker(locationInfo[0].lat, locationInfo[0].lng, map, 'http://alert.mta.info/sites/all/themes/mta/images/subway_bullets/c.png', locationInfo[0].name, i, infowindow);

  for (var j = 1; j < locationInfo.length; j++) {
    // set marker for other location
    setMarker(locationInfo[j].lat, locationInfo[j].lng, map, '', locationInfo[j].name, i, infowindow);
  }

}

function calcDistance(p1, p2) {
  return (google.maps.geometry.spherical.puteDistanceBetween(p1, p2) / 1000).toFixed(2);
}

function pare(a, b) {
  if (parseFloat(a.distance) < parseFloat(b.distance)) {
    return -1;
  }

  if (parseFloat(a.distance) > parseFloat(b.distance)) {
    return 1;
  }

  return 0;
}

function setMarker(lat, lng, map, icon, content, i, infowindow) {

  var marker = new google.maps.Marker({
    position: new google.maps.LatLng(lat, lng),
    map: map,
    icon: icon
  });

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

}
* {
  margin: 0;
  padding: 0;
}

html {
  font-size: 62.5%;
  /* so, 10px = 1rem */
}

body {
  font-family: arial;
}

#map-canvas {
  z-index: -1;
  position: absolute;
  top: 0;
  height: 100%;
  width: 100%;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://maps.google./maps/api/js?sensor=false&libraries=geometry"></script>

<form id="zipcodeSearch">
  <input type="text" id="zipcode" placeholder="Enter zipcode here" />
  <input type="submit" value="Search" />
</form>

<div id="map-canvas"></div>

jsFiddle version of the same code

I hope this answer helps someone facing the same problem as I did.

发布评论

评论列表(0)

  1. 暂无评论