我目前正在使用输入字段,在输入地址时,系统会向用户指定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);
}
});
}
答案 0 :(得分:1)
我找到了问题的解决方案。我试图挖掘一个解决方法并通过一个find_closest_marker
执行完成后通过回调函数赋予变量值来解决问题:
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;
答案 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}}
并且它运行良好,没有错误