I am developing this page for a site, that generates search results based on the current logged in user. My aim is to loop through every house and assign it a distance.
My issue is I cannot seem to use context (this) inside of a distance matrix request/response.
$('.houseWrapper').each(function() {
var origin = $(this).children('.houseMeta').attr('data-origin');
var destination = $(this).children('.houseMeta').attr('data-destination');
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
origins: [origin],
destinations: [destination],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false,
}, callback);
function callback(response, status) {
if (status == google.maps.DistanceMatrixStatus.OK) {
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
for (var i = 0; i < origins.length; i++) {
var results = response.rows[i].elements;
for (var j = 0; j < results.length; j++) {
var element = results[j];
var distance = element.distance.text;
var duration = element.duration.text;
console.log($(this).html());
}
}
}
}
});
try :
var that = this;
var origin = $(this).children('.houseMeta').attr('data-origin');
....
Then later:
console.log($(that).html());
I would make "this" passed in as an argument to the function, kind of like how a partial function works.
var callback = function(this) {
return function(response, status) {
// ...
}
}(this);
there are 2 arguments that will be passed to the $.each()-callback, the index of the element and the element.
Just use these arguments:
$('.houseWrapper').each(function(index,node) {
//somewhere
console.log($(node).html());
});
Related
I am a bit confused with my code and I don't really know which way to go.
Let's consider I have a car marker that is running through a polyline.
I change its position each 500 ms by setting a timer :
function animate() {
var p = polyline.GetPointAtDistance(distanceFromBeginning);
carMarker.setPosition(p);
distanceFromBeginning += step;
timerHandle = setTimeout("animate("+(distanceFromBeginning)+")", tick);
}
I also added the fact that my car can be dragged on the route :
google.maps.event.addDomListener(carMarker, 'dragend', function(e) {
var p = find_closest_point_on_path(e.latLng,polyline.getPath());
console.log("position is : " + p);
carMarker.setPosition(p);
console.log("dragend")
});
Now that I have a new position after dragging the car on the polyline, how can I get its distance from the start location so I can update it correctly in my timer?
Once you have the coordinates for the end location (lets call the "destination"), and assuming that on your 'dragend' event you set the coordinates for the car (let call "origin") location you can call this function on your listener:
function calculateDistances() {
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [origin],
destinations: [destination],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false
}, callback);
}
function callback(response, status) {
if (status != google.maps.DistanceMatrixStatus.OK) {
alert('Error was: ' + status);
} else {
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
for (var i = 0; i < origins.length; i++) {
var results = response.rows[i].elements;
for (var j = 0; j < results.length; j++) {
console.log(results[j].distance.text);
console.log(results[j].duration.text);
}
}
}
}
Check this example on jsfiddle based on the Google documentation(look the result on your console)
Fell free to reply if you need more help with this code or if it's not what you want.
I've created the following testcase in JSFiddle: http://jsfiddle.net/4Wtb3/15/. When I check a checkbox for route A or route B, the routes are displayed. So far, so good ...
if (routes.length > 0) {
for (var i = 0; i < routes.length; i++) {
var route = routes[i];
var request = {
origin: route.origin,
destination: route.destination,
travelMode: google.maps.TravelMode.WALKING
};
var directionsDisplay = new google.maps.DirectionsRenderer({
suppressMarkers: true,
preserveViewport: true,
polylineOptions: {
strokeColor: '#C6D300'
}
});
directionsDisplay.setMap(map);
directionsDisplays.push(directionsDisplay);
directionsService.route(request, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
}
});
}
}
But when I uncheck them, I want to clear the selected route. I keep track of all directionDisplay's using an array (to put the map value to 'null'). First I clear everything, then I redraw every route which is still in the list.
The problem: routes are still in the map, even if I uncheck them ...
Any idea's what exactly is going wrong?
There is no length of array in for loop so setMap(null) is never called. Code should be changed from
if (directionsDisplays.length > 0) {
for(var i = 0; i < directionsDisplays; i++) {
directionsDisplays[i].setMap(null);
}
}
to
if (directionsDisplays.length > 0) {
for(var i = 0; i < directionsDisplays.length; i++) {
directionsDisplays[i].setMap(null);
}
}
...
And additional fix for closure problem:
// Draw all routes
if (routes.length > 0) {
for (var i = 0; i < routes.length; i++) {
(function(i){
var route = routes[i];
var request = {
origin: route.origin,
destination: route.destination,
travelMode: google.maps.TravelMode.WALKING
};
....
})(i);
}
}
Updated example at jsfiddle
I have been playing a little bit with Google's DistanceMatrixService. The code below works, but, how can I pass another parameter to the callback function or grab one of the values out of the callback?
For example: I have two divs that I want to show different results in (Results1 and Results2), so I am thinking I need to either
pass another value to the GoogleMapDistance function like GoogleMapDistance(YourLatLong,DestLatLong,TheDiv)
or
be able to grab the ResultStr externally outside of the callback document.getElementById("Results1").innerHTML = ResultStr;
or
set the innerHTM to the returned value of the function document.getElementById("Results1").innerHTML = GoogleMapDistance(YourLatLong,DestLatLong);
I'm stuck. How can I do accomplish this? The way it looks right now is that I am only going to be able to run all this code once and have it only write to one div.
<div id="Results1"></div>
<div id="Results2"></div>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script>
function GoogleMapDistance(YourLatLong,DestLatLong)
{
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [YourLatLong],
destinations: [DestLatLong],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.IMPERIAL,
avoidHighways: false,
avoidTolls: false
}, callback);
}
function callback(response, status)
{
if (status == google.maps.DistanceMatrixStatus.OK)
{
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
for (var i = 0; i < origins.length; i++)
{
var results = response.rows[i].elements;
for (var j = 0; j < results.length; j++)
{
var element = results[j];
var from = origins[i];
var to = destinations[j];
var distance = element.distance.text;
var duration = element.duration.text;
var ResultStr = distance + " (<i>" + duration + "</i>)";
}
}
document.getElementById("Results1").innerHTML = ResultStr;
}
}
var YourLatLong = "45.4049,-122.797997";
var DestLatLong1 = "47.468893,-122.227978";
var DestLatLong2 = "61.221274,-149.831545";
GoogleMapDistance(YourLatLong,DestLatLong1);
</script>
You can't change how Google calls the callback, but you can let it call your own locally function as the callback and then have that (via a closure) call another callback after adding the desired extra argument like this:
function GoogleMapDistance(YourLatLong,DestLatLong, item)
{
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [YourLatLong],
destinations: [DestLatLong],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.IMPERIAL,
avoidHighways: false,
avoidTolls: false
}, function(response, status) {callback(response, status, item)});
}
Or, you could just define your callback inline so it has access to the parent function variables directly:
function GoogleMapDistance(YourLatLong,DestLatLong, item)
{
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [YourLatLong],
destinations: [DestLatLong],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.IMPERIAL,
avoidHighways: false,
avoidTolls: false
}, function callback(response, status)
{
// you can access the parent scope arguments like item here
if (status == google.maps.DistanceMatrixStatus.OK)
{
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
for (var i = 0; i < origins.length; i++)
{
var results = response.rows[i].elements;
for (var j = 0; j < results.length; j++)
{
var element = results[j];
var from = origins[i];
var to = destinations[j];
var distance = element.distance.text;
var duration = element.duration.text;
var ResultStr = distance + " (<i>" + duration + "</i>)";
}
}
document.getElementById("Results1").innerHTML = ResultStr;
}
}
)}
I have the following code which is successfully plotting a route between two points. However I wish to search a recordset to see which georeferences lie within a range of this route. E.g. 50 yards off the main route
function plot_route() {
var rendererOptions = { map: map };
directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
var org = new google.maps.LatLng ( $("#start_lat").html(), $("#start_long").html() );
var dest = new google.maps.LatLng ( $("#finish_lat").html(), $("#finish_long").html() );
if ($("#via_lat").html() != "") {
var point1 = new google.maps.LatLng($("#via_lat").html(), $("#via_long").html());
}
else
{
point1 = dest;
}
var wps = [{ location: point1 }];
if (($("#start_lat").html() != "") && ($("#finish_lat").html() != "")) {
var request = {
origin: org,
destination: dest,
waypoints: wps,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService = new google.maps.DirectionsService();
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
else
alert ('failed to get directions');
});
}
}
I have tried breaking down the response but it shows that the calculation does not return an array of values to make up the route.
Has anyone conquered this one before?
edit
Digging Deeper, it seems the response does contain the array of route points. For those in the community who are looking for help rather than contributions from people gung ho with the -1 button i attach the following
function plot_route() {
var rendererOptions = { map: map };
directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
var org = new google.maps.LatLng ( $("#start_lat").html(), $("#start_long").html() );
var dest = new google.maps.LatLng ( $("#finish_lat").html(), $("#finish_long").html() );
if ($("#via_lat").html() != "") {
var point1 = new google.maps.LatLng($("#via_lat").html(), $("#via_long").html());
}
else
{
point1 = dest;
}
var wps = [{ location: point1 }];
if (($("#start_lat").html() != "") && ($("#finish_lat").html() != "")) {
var request = {
origin: org,
destination: dest,
waypoints: wps,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService = new google.maps.DirectionsService();
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
var myroute = response.routes[0];
if(myroute)
{
$.each(myroute, function(key, value) {
if (key == "overview_path") {
alert(value); //the array of points for the route
}
});
}
directionsDisplay.setDirections(response);
}
else
alert ('failed to get directions');
});
}
}
I play with distance matrix
http://code.google.com/apis/maps/documentation/javascript/services.html#distance_matrix
to get the duration from one origin to multiple destinations.
I have this code:
var duration = new Array();
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [origin],
destinations: destination,
travelMode: google.maps.TravelMode.DRIVING,
avoidHighways: false,
avoidTolls: false
},
function(response, status)
{
if (status == google.maps.DistanceMatrixStatus.OK)
{
var destinations = response.destinationAddresses;
var results = response.rows[0].elements;
for (var j = 0; j < results.length; j++)
duration[j] = results[j].duration.value;
}
});
alert(duration[0]);
but i have alert "undefined". when i put the alert command inside the callback function i have the alert i want. why is that??? how can i fix it?
Thank u in advance!
var duration = new Array();
function calculate_distance(){
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [origin],
destinations: destination,
travelMode: google.maps.TravelMode.DRIVING,
avoidHighways: false,
avoidTolls: false
},
function(response, status)
{
if (status == google.maps.DistanceMatrixStatus.OK)
{
var destinations = response.destinationAddresses;
var results = response.rows[0].elements;
for (var j = 0; j < results.length; j++)
duration[j] = results[j].duration.value;
}
});
}
google.maps.event.addListener(autocomplete, 'place_changed', calculate_distance);
alert(duration[0]);
Try anything like that
Move the alert in to the callback. The function is a callback that is executed asynchronously.