I am working with the google maps api. I have one issue that I was wondering if other people had and if it is fixable. When using the direction feature, sometimes the routes are unnecessarily long or complex. Like the picture in this link.
Is there anything i could change in my directions code??
var directionsDisplay = new google.maps.DirectionsRenderer({
suppressMarkers: true
});
var directionsService = new google.maps.DirectionsService;
directionsService.route({
origin: marker.position,
destination: dest_end,
travelMode: google.maps.TravelMode.WALKING
}, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
I haven't enough credit to make comment so i am answering here according to google map they have three walking route to your destination and it shows best from that routs by default, in your case this rout has 0.4 mile walking distance and other two has 0.4 and 0.5 respectively so it take smallest distance with less time.
Related
I'm trying to create a heatmap using Google's API, but running into a few issues. The main issue I have run into so far is converting a large set of about ~25000 addresses into geocoordinates for use in the API. The two approaches I have used are Google's own API, which has heavy limitations, and Python's Geopy module, which also has limitations. Since I am trying to convert ~25000, Geopy's one second delay is a pretty steep issue.
The second issue I can see coming is a size limitation. Once I have a list of ~25000 geocoordinates, putting those into an array in Javascript seems ridiculous. Assuming a user would upload a text file in a format like this:
12.3456,-12.3456
23.4567,-23.4567
...
Would there be a way to process the file in blocks, or some other work around?
In case it helps, this is my current Javascript code for processing a file of addresses. I'm planning on changing the file reading format to find a better system.
var map, heatmap, geocoder;
var MVCarr;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 36.85, lng: -75.97},
zoom: 7
});
MVCarr = new google.maps.MVCArray();
heatmap = new google.maps.visualization.HeatmapLayer({
data: MVCarr,
map: map
})
}
window.onload = function() {
var fileInput = document.getElementById('fileInput');
var fileDisplayArea = document.getElementById('fileDisplayArea');
geocoder = new google.maps.Geocoder();
fileInput.addEventListener('change', function(e) {
var file = fileInput.files[0];
var reader = new FileReader();
reader.onload = function(e) {
var mySplit = (reader.result).split("\n");
for(var i = 0, len = mySplit.length; i < len; i++) {
//console.log(mySplit[i]);
geocodeAddress(geocoder, mySplit[i]);
}
}
reader.readAsText(file);
});
}
function geocodeAddress(geocoder, address) {
geocoder.geocode({'address': address}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
MVCarr.push(results[0].geometry.location);
console.log(MVCarr.length);
} else {
console.log('Failed: ' + status);
}
});
}
So I've made this piece of code which turns an ordinary address into a geolocation and gives back a map and directions from your gps location (phonegap position, html5 location or whatever latlng). This function gets called on success of the phonegap or html5 location.
This code works fine in a browser but fails with a:
Error: TypeError: 'undefined' is not an object in file://bla bla at line 761
Line 761 = geocoder.geocode ( { 'address': address }, function(results, status) {
So i've checked all my variables and they are not empty just like in the online version and the return div exists. So I'm guessing there is something wrong in the geolocator link to Google.
The funny thing though, it shows the map but not the directions. And it marks the location where you need to go, but not where you are. Its as if just directions just doesnt load or something.
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
function bring_me_back(call_back_map,call_back_directions,address,position) {
var latlng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude); // your location
directionsDisplay = new google.maps.DirectionsRenderer();
var myOptions = {
zoom: 14,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: true
};
var map = new google.maps.Map(document.getElementById(call_back_map),myOptions);
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById(call_back_directions));
var marker = new google.maps.Marker({
position: latlng,
map: map,
title:"My location"
});
// find the address
var geocoder = new google.maps.Geocoder (map);
geocoder.geocode ( { 'address': address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var end = results [0].geometry.location;
map.setCenter(results [0].geometry.location);
marker.setPosition(results [0].geometry.location);
var start = latlng; // your gps location
var request = {
origin:start,
destination:end,
travelMode: google.maps.DirectionsTravelMode.WALKING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
} else alert("Directions was not successful for the following reason: " + status);
});
}
else {
$('#'+call_back).html("Geocode was not successful for the following reason: " + status);
}
});
}
The way I call google (it has plenty of time to load and "initialize" gets called way before I use this code).
function loadGoogleScript() {
if(!(navigator.network.connection.type == Connection.NONE)) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'http://maps.google.com/maps/api/js?v=3.6&sensor=false&callback=initialize';
document.body.appendChild(script);
return true;
}
else {
return false;
}
}
The feedback from the API is way to limited, so I can't make anything more of it.
After a hell of a search, I found out that one variable:
var directionsService = new google.maps.DirectionsService();
Was called before google script loaded. Changed it to
var directionsService;
And called:
directionsService = new google.maps.DirectionsService();
From inside the the function.
Thanks for help.
I would like to output multiple Google Map routes on to a single Google Map. The data is taken from an XML file which feature multiple markers. Each marker has a start point and an end point (in the form of latitude and longitude values). These markers are then added to the map and a call to the Google Maps Directions Service is made to draw a route between the start and end points of each marker.
The issue I'm having is that only one route is drawn (if I refresh the page it seems to just pick one of the markers at random and draw the directions between those two markers). The other markers aren't displayed at all.
I've console.logged the for loop to check it is running for each marker in the XML (it is). I'm guessing it is something to do with these two lines here, but that is a guess...
directionsDisplay = new google.maps.DirectionsRenderer();
directionsService = new google.maps.DirectionsService();
I've read this question - Using Google Maps 3 API to get multiple routes on a Map, but don't really understand the answer/know how relevant it is to my situation. Thanks.
jQuery(document).ready(function($) {
var map = new google.maps.Map(document.getElementById("map_canvas"), {
zoom: 13,
mapTypeId: 'roadmap'
});
// Try HTML5 geolocation
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(pos);
map.setZoom(13);
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
directionsDisplay = new google.maps.DirectionsRenderer();
directionsService = new google.maps.DirectionsService();
// Change this depending on the name of your PHP file
downloadUrl("xml.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var title = markers[i].getAttribute("title");
mode = markers[i].getAttribute("mode");
startpoint = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("startlat")),
parseFloat(markers[i].getAttribute("startlng")));
endpoint = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("endlat")),
parseFloat(markers[i].getAttribute("endlng")));
calcRoute();
console.log('marker');
}
});
directionsDisplay.setMap(map);
});
function calcRoute() {
var request = {
origin: startpoint,
destination: endpoint,
//waypoints: waypts,
travelMode: google.maps.DirectionsTravelMode[mode]
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function doNothing() {}
I think the key point in the answer you linked to is that each route needs its own DirectionsRenderer object. And it doesn't mention it, but it seems likely that each route should also have its own DirectionsService object. You're sharing a single one of each these objects among all your routes. I suspect that these shared objects are getting overwritten for each route.
Here's an update that should fix that by creating new objects for each route:
jQuery(document).ready(function($) {
var map = new google.maps.Map(document.getElementById("map_canvas"), {
zoom: 13,
mapTypeId: 'roadmap'
});
// Try HTML5 geolocation
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(pos);
map.setZoom(13);
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
// Change this depending on the name of your PHP file
$.get("xml.php", function( xml ) {
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
addMarkerPair( markers[i] );
}
}, 'xml' );
});
function addMarkerPair( pair ) {
function get( name ) {
return pair.getAttribute( name );
}
var title = get("title");
var mode = get("mode");
var startpoint = new google.maps.LatLng(
+get("startlat"),
+get("startlng")
);
var endpoint = new google.maps.LatLng(
+get("endlat"),
+get("endlng")
);
calcRoute( mode, startpoint, endpoint );
console.log('marker');
}
function calcRoute( mode, startpoint, endpoint ) {
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.setMap(map);
var request = {
origin: startpoint,
destination: endpoint,
//waypoints: waypts,
travelMode: google.maps.DirectionsTravelMode[mode]
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
I also took the liberty of fixing and simplifying a few things:
Moved the marker loop body out to a separate addMarkerPair function for better readability.
Added a get function inside addMarkerPair as a shorthand for pair.getAttribute.
Used + instead of parseInt. Either one will do the same thing; I like + for its brevity.
Add several missing var declarations.
Passed the necessary parameters to calcRoute as function parameters instead of global variables.
Used $.get instead of downloadUrl. No need for your own function when jQuery has it already.
Also, as another alternative to the XML parsing, you could use jQuery to access the XML elements. But I stuck with code closer to how you're already doing it.
I am creating a web page that lets a user enter a start location and an end location into textbox's and the distance between the two locations is output (this is using a google API). I have successfully been able to create a single instance of this that works as I want it to. However my problem is that I need multiple rows of this but as soon I duplicate the code I cannot seem to get it to work. This is my first real attempt at using javascript so my understanding of it is not that great. I realise that I need to change variables etc. but am unsure exactly as what to change. Sorry if I have not been clear enough but any help would be great, thanks.
Here is my code:
<body onload="initialize()">
<script type="text/javascript">
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
var belfast = new google.maps.LatLng(55, -5)
var myOptions = {
zoom:5,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: belfast,
}
map = new google.maps.Map(document.getElementById("map_canvas1"), myOptions);
directionsDisplay.setMap(map);
}
function calcRoute() {
var start = document.getElementById("pc1").value;
var end = document.getElementById("pc2").value;
var distanceInput = document.getElementById("distance");
var request = {
origin:start,
destination:end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
distanceInput.value = response.routes[0].legs[0].distance.value / 1000;
}
});
}
<td><input type="text" id="pc1" /></td>
If you're creating multiple instances of Google Maps, you need to make sure you're not mixing up global variables. These variables you're declaring on a global level:
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
So if you try to create a second map and assign the map to the map variable, which should destroy the previous map. Likewise your DirectionsService. So you need to create a variable for each of those for each instance.
function calcRoute() {
var start = document.getElementById("start_").value;
var end = document.getElementById("end_").value;
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);
}
});
}
Gives an error message in Chrome: "Uncaught TypeError: Cannot call method 'setDirections' of undefined". Could anyone suggest fixing this? thanx
You are missing (global var)
//var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer({ 'map': map });
So directionsDisplay is undefined.