我正在尝试重构一些代码,并尝试使用Google地图来计算经度和纬度。我特意遇到谷歌地图的问题,以获取数据ascynronously。有人很好地提出了一个解决方案,但几天之后,我必须得出结论,我很遗憾地让一个JS新手太过分了。这是整个代码,以及我原来的问题:Asynchronous Google Maps request throwing off Javascript我确定它很小,但我已经尝试了2天而无法获得正常工作的版本。任何帮助都会非常感激 - 我觉得它很小,但是无法理解那是什么。
<script type="text/javascript">
//declare variables
var map;
var directionsService;
var directionsDisplay1, directionsDisplay2, directionsDisplay3;
var markersArray = [];
var stations;
var autocomplete_options = {componentRestrictions: {country: 'us'}};
var places = new Array();
places[0] = "Barlays Center, Brooklyn NY";
places[1] = "Union Square, nyc";
//formerly var autocomplete_start = new google.maps.places.Autocomplete(document.getElementById("id_start"), autocomplete_options);
var autocomplete_start = places[0];
//var autocomplete_start = new google.maps.places.PlacesService(places[0]);
var autocomplete_end = places[1];
//Figure out the distance between your location and the nearest Citibike station
function getDistance(lat1,lng1,lat2,lng2) {
var i = lat1 - lat2;
var j = lng1 - lng2;
return i*i + j*j;
}
function findNearestStation(lat,lng) {
var min_distance = 99999;
var closest_station_id;
$.each(stations.stationBeanList, function(i, station) {
var distance = getDistance(lat,lng, station.latitude, station.longitude);
if (distance < min_distance) {
min_distance = distance;
closest_station_id = i;
}
});
console.log('Closest station idx: ' + closest_station_id);
return stations.stationBeanList[closest_station_id];
}
//Draw on the map
function drawMarker(lat, lng, map, title, marker_text) {
var point = new google.maps.LatLng(lat, lng);
var marker = new google.maps.Marker({
position : point,
map : map,
title : title,
icon: 'http://chart.apis.google.com/chartchst=d_map_pin_letter&chld='+marker_text+'|FE6256|000000'
});
markersArray.push(marker);
}
function clearMarkers() {
for (var i = 0; i < markersArray.length; i++ ) {
markersArray[i].setMap(null);
}
markersArray = [];
}
function drawMap() {
var center = new google.maps.LatLng(40.704066,-73.992727);
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.DROPDOWN_MENU },
zoom: 14,
center: center
};
map = new google.maps.Map(document.getElementById("map"), mapOptions);
directionsService = new google.maps.DirectionsService();
directionsDisplay1 = new google.maps.DirectionsRenderer();
directionsDisplay1.setMap(map);
directionsDisplay1.setPanel(document.getElementById("directions-panel1"));
directionsDisplay2 = new google.maps.DirectionsRenderer();
directionsDisplay2.setMap(map);
directionsDisplay2.setPanel(document.getElementById("directions-panel2"));
directionsDisplay3 = new google.maps.DirectionsRenderer();
directionsDisplay3.setMap(map);
directionsDisplay3.setPanel(document.getElementById("directions-panel3"));
$.getJSON('./static/js/stations.json', function(data) {
stations = data;
var bounds = new google.maps.LatLngBounds();
$.each(data.stationBeanList, function(i, station) {
if (station.statusValue == 'In Service') {
var point = new google.maps.LatLng(station.latitude, station.longitude);
bounds.extend(point);
}
});
map.setCenter(bounds.getCenter(), map.fitBounds(bounds));
autocomplete_start.bindTo('bounds', map);
autocomplete_end.bindTo('bounds', map);
});
}
$(document).ready(function(){
drawMap();
});
$('#btn-reset').click(function(){
$('#directions-panel1').empty();
$('#directions-panel2').empty();
$('#directions-panel3').empty();
$('#directions-info1').empty();
$('#directions-info2').empty();
$('#directions-info3').empty();
drawMap();
});
$('#btn-get-directions').click(function(){
//take directions on the map
var start = autocomplete_start;
var end = autocomplete_end;
var start_lat=getLat(start);
//this is legacy code - the original had Google autocomplete
var start_lng;
var end_lat;
var end_lng;
// getLat(start);
function getLat(loc) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'address': loc}, function postcodesearch(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
var lat = results[0].geometry.location.lat();
//alert(lat);
return lat;
//alert(start_lng);
}
else {
alert("Error");
}
});
}
//These are original functions I wrote
function getLng(loc) {
var geocoder_lng = new google.maps.Geocoder();
geocoder_lng.geocode({'address': loc}, function postcodesearch(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
var lng = results[0].geometry.location.lng();
// alert(lng);
return lng;
//alert(end_lat);
//doRest();
}
else {
alert("Error");
}
});
}
//This is a far superior function someone else wrote, which I cannot implement
function getLatLng(loc, callback) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'address': loc}, function postcodesearch(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
var lat = results[0].geometry.location.lat();
var lng = results[0].geometry.location.lng();
alert("234234");
return(lat, lng);
}
}
);}
getLatLng(start);
doRest()
//This is the rest of the code
function doRest(){
//var start_lat = start.geometry.location.lat();
//alert("DO REST");
var start_lng = getLng(start);
alert(start_lng);
var start_p = new google.maps.LatLng(getLatLng(start));
//alert(start_p);
//alert(start_p);
//var end_lat = end.geometry.location.lat();
//var end_lng = end.geometry.location.lng();
var end_p = new google.maps.LatLng(getLatLng(end));
var start_station = findNearestStation(start_p);
var end_station = findNearestStation(end_p);
alert("asdf");
var start_station_p = new google.maps.LatLng(start_station.latitude, start_station.longitude);
alert("wtf");
var end_station_p = new google.maps.LatLng(end_station.latitude, end_station.longitude);
// alert("stations");
var dir_bounds = new google.maps.LatLngBounds();
dir_bounds.extend(start_p);
dir_bounds.extend(end_p);
dir_bounds.extend(start_station_p);
dir_bounds.extend(end_station_p);
drawMarker(start_lat, start_lng, map, $('#id_start').val(), '1');
drawMarker(start_station.latitude, start_station.longitude, map, start_station.stationName, '2');
drawMarker(end_station.latitude, end_station.longitude, map, end_station.stationName, '3');
drawMarker(end_lat, end_lng, map, $('#id_end').val(), '4');
}
// We'll make 3 calls, 1) walking, 2) biking, 3) walking
// Walk from start to station 1
var request1 = {
origin:start_p,
destination:start_station_p,
travelMode: google.maps.TravelMode.WALKING
};
directionsService.route(request1, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
$('#directions-info1').html('Walk from ' + $('#id_start').val() + ' to station at ' + start_station.stationName);
directionsDisplay1.setDirections(result);
}
});
// Bike from station 1 to station 2
var request2 = {
origin:start_station_p,
destination:end_station_p,
travelMode: google.maps.TravelMode.BICYCLING
};
directionsService.route(request2, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
$('#directions-info2').html('Bike from station at ' + start_station.stationName + ' to station at ' + end_station.stationName);
directionsDisplay2.setDirections(result);
}
});
// Walk from station 2 to end
var request3 = {
origin:end_station_p,
destination:end_p,
travelMode: google.maps.TravelMode.WALKING
};
directionsService.route(request3, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
$('#directions-info3').html('Walk from station at ' + end_station.stationName + ' to ' + $('#id_end').val() );
directionsDisplay3.setDirections(result);
}
});
google.maps.event.addListener(directionsDisplay1, 'directions_changed', function() {
map.setCenter(dir_bounds.getCenter(), map.fitBounds(dir_bounds));
});
google.maps.event.addListener(directionsDisplay2, 'directions_changed', function() {
map.setCenter(dir_bounds.getCenter(), map.fitBounds(dir_bounds));
});
google.maps.event.addListener(directionsDisplay3, 'directions_changed', function() {
map.setCenter(dir_bounds.getCenter(), map.fitBounds(dir_bounds));
});
});
答案 0 :(得分:1)
我看到的主要问题是你试图从getlatLng
返回值 - 这是行不通的,因为地理编码调用是异步的。关键是使用回调。而不是这样做:
function getLatLng() {
return somevalue;
}
latlng = getLatLng();
// do something
请改为:
function getLatLng(callback) {
callback(somevalue);
}
getLatLng(function(latlng) {
// do something
});
这是getLatLng
的实现,它采用开始,结束和回调。反过来,回调是一个带有四个参数的函数:start_lat,start_lng,end_lat,end_lng。它没有检查语法,但希望它有所帮助。
function getLatLng(start, end, callback) {
var geocoder = new google.maps.Geocoder();
// geocode the start
geocoder.geocode({'address': start}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var startlat = results[0].geometry.location.lat();
var startlng = results[0].geometry.location.lng();
console.log('Got start: ' + startlat + ', ' + startlng);
// geocode the end
geocoder.geocode({'address': end}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var endlat = results[0].geometry.location.lat();
var endlng = results[0].geometry.location.lng();
console.log('Got end: ' + endlat + ', ' + endlng);
// invoke the callback function
callback(startlat, startlng, endlat, endlng);
}
});
}
});
}
// the third parameter provided here to getLatLng is the callback function:
getLatLng(start, end, function(start_lat, start_lng, end_lat, end_lng) {
//This is the rest of the code
var start_p = new google.maps.LatLng(start_lat, start_lng);
var end_p = new google.maps.LatLng(end_lat, end_lng);
var start_station = findNearestStation(start_p);
var end_station = findNearestStation(end_p);
// etc
});
注意作为一般提示,请使用浏览器的调试工具(Chrome中的Shift-Ctl-J)。这应该允许你: