I have a page at http://www.no1hastings.check.com.au/directions.html where visitors can get directions from anywhere to a fixed point. The destination that the Google geocoder recognises is a street address (1 Morwong Drive) but I would like it to display the name of the building there (No. 1 in Hastings Street) which Google doesn't recognise.
Is there way to set the street address as the destination but alias it to the building name when the result is displayed?
One option would be to modify the string in the response before sending it to the DirectionsRenderer:
function calcRoute() {
var request = {
origin: 'Brisbane QLD Australia Australia',
// origin: 'Brisbane Qld, Australia',
destination: '1 Morwong Drive, Noosa Heads Qld, Australia',
// waypoints:[{location: 'Bourke, NSW'}, {location: 'Broken Hill, NSW'}],
travelMode: google.maps.DirectionsTravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
var route = response.routes[0];
var lastleg = route.legs[route.legs.length-1];
response.routes[0].legs[route.legs.length-1].end_address = 'No. 1 in Hastings Street';
directionsDisplay.setDirections(response);
} else alert("Directions request failed: "+status);
});
}
To handle the case where the directions are changed by the directionsRenderer (i.e. for dragging the origin), you could do something like this (where changeEnd is a global and set to false), note that it will have undesireable results if the user drags the destination (you may want to prevent that: Google maps api v3 Two markers one fixed one dragged):
google.maps.event.addListener(directionsDisplay, 'directions_changed', function() {
computeTotalDistance(directionsDisplay.directions);
if (!changeEnd) {
var response = directionsDisplay.getDirections();
var route = response.routes[0];
var lastleg = route.legs[route.legs.length-1];
response.routes[0].legs[route.legs.length-1].end_address = 'No. 1 in Hastings Street';
changeEnd = true;
directionsDisplay.setDirections(response);
} else changeEnd = false;
});
Related
I am using google maps API for calculating a route with waypoints
Sometimes route is correctly calculated but sometimes not
I take some values from Apex (this is a VisualForce Page Salesforce with Javascript)
var wayptsApresMidi = [];
var wayPointApresMidi = {!wayPointsLocationOfPCEApresMidi};
for(var i= 0; i < wayPointApresMidi.length; i++){
wayptsApresMidi.push({
location: new google.maps.LatLng(wayPointApresMidi[i][1], wayPointApresMidi[i][0]),
stopover: true
});
}
console.log('firstLocationOfPCELatitudeApresMidi '+'{!firstLocationOfPCELatitudeApresMidi}');
console.log('firstLocationOfPCELongitudeApresMidi '+'{!firstLocationOfPCELongitudeApresMidi}');
console.log('lastLocationOfPCELatitudeApresMidi '+'{!lastLocationOfPCELatitudeApresMidi}');
console.log('lastLocationOfPCELongitudeApresMidi '+'{!lastLocationOfPCELongitudeApresMidi}');
for(var i=0; i<wayptsApresMidi.length; i++){
console.debug('wayptsApresMidi Longitude and Latitude '+wayptsApresMidi[i].location);
}
directionsServiceApresMidi.route({
origin: new google.maps.LatLng('{!firstLocationOfPCELatitudeApresMidi}', '{!firstLocationOfPCELongitudeApresMidi}'),
destination: new google.maps.LatLng('{!lastLocationOfPCELatitudeApresMidi}','{!lastLocationOfPCELongitudeApresMidi}'),
waypoints: wayptsApresMidi,
optimizeWaypoints: true,
travelMode: 'DRIVING',
unitSystem: google.maps.UnitSystem.METRIC,
language: 'fr'
}, function(response, status) {
if (status === 'OK') {
console.log(response);
for (var i = 0; i < response.routes[0].legs.length; i++)
{
console.log(response.routes[0].legs[i].start_address);
console.log(response.routes[0].legs[i].end_address);
}
});
When not functions the values returned for waypoint_order can be [4294967295, 4294967295] (The number of wayPoints is correct but values are 4294967295)
for (var i = 0; i < response.routes[0].legs.length; i++)
{
console.log(response.routes[0].legs[i].start_address);
console.log(response.routes[0].legs[i].end_address);
}
ten times
38 Rue Verte, xxxx, France
firstPoint/ WAyPoints/ LastPoint have some good values
Furthermore, when the travelMode is WALKING to put travelMode DRIVING can function
(the contrary is true -> when DRIVING is not functionned WALKING can function)
The before weeks it worked always
i don't know if it functions only sometimes because of changes in my code or if Google Maps API has modified something in the process
It can have 16 digits after dot for latitude/ longitude (Is it a problem ?)
Do you have an idea ?
Thanks,
Looks like this is a known issue.
Please see the following google issue tracker.
https://issuetracker.google.com/issues/135627404
I am creating a walkthrough for the interior of a building and am wondering how to draw a marker on a StreetViewPanorama. Maybe I'm missing something basic, but everything I have read indicates that you need a lat and lng to draw the marker.
Here is what I have:
var initPosPanoID, streetView;
function initPano() {
// Set StreetView provider.
var streetViewOptions = {
zoom: 0,
panoProvider: getCustomPanorama,
pano : "lobby",
addressControlOptions: {
position: google.maps.ControlPosition.BOTTOM_CENTER
}
};
// Create a StreetView object.
var streetViewDiv = document.getElementById('map');
streetView = new google.maps.StreetViewPanorama(streetViewDiv, streetViewOptions);
// Add links when it happens "links_change" event.
google.maps.event.addListener(streetView, "links_changed", createCustomLink);
google.maps.event.addListener(streetView, "pano_changed", function() {
var panoCell = document.getElementById('pano-cell');
panoCell.innerHTML = panorama.getPano();
});
}
function getCustomPanoramaTileUrl(panoID, zoom, tileX, tileY) {
// Return a pano image given the panoID.
return "images/he/" + panoID + '.jpg';
}
function getHeading(panoID) {
var heading;
switch(panoID) {
case "lobby":
heading = 0;
break;
case "secorner":
heading = 100;
break;
}
return heading;
}
function getCustomPanorama(panoID) {
// get a custom heading for the pano
var heading = getHeading(panoID);
var streetViewPanoramaData = {
links: [],
copyright: 'Imagery (c) HumanElement',
tiles: {
tileSize : new google.maps.Size(1024, 512),
worldSize : new google.maps.Size(1024, 512),
// The heading in degrees at the origin of the panorama
// tile set.
centerHeading : heading,
getTileUrl : getCustomPanoramaTileUrl
}
};
switch(panoID) {
case "lobby":
// Description of this point.
streetViewPanoramaData["location"] = {
pano: 'lobby',
description: "Human Element",
latLng: new google.maps.LatLng(42.282138, -83.751471)
};
return streetViewPanoramaData;
case "secorner":
streetViewPanoramaData["location"] = {
pano: 'secorner',
description: "SouthEast Corner",
latLng: new google.maps.LatLng(42.282078, -83.751413)
};
return streetViewPanoramaData;
}
}
function createCustomLink() {
var links = streetView.getLinks();
var panoID = streetView.getPano();
switch(panoID) {
case "lobby":
links.push({
description : "SouthEast Corner",
pano : "secorner",
heading : 280
});
break;
case "secorner":
links.push({
description : "HumanElement Lobby",
pano : "lobby",
heading : 90
});
break;
}
}
I would like to have different markers or touchpoints at different locations, but am not sure how to get them on there.
Trying to draw a standard marker does not work without the lat/lng.
I thought about trying to create it around a google.maps.Point thinking I might be able to use the x and y from my tiles, but couldn't seem to get that working.
The other options I see are related to google.maps.drawing.DrawingManager.
Does anyone have any advice on this?
Setting up the map this way helped: It creates the map and panorama separately and then sets the panorama into the map, rather than just having the panorama object by itself.
map = new google.maps.Map(document.getElementById('map'), {
center: position,
zoom: 10
});
// Create the panorama and set it into the map
panorama = new google.maps.StreetViewPanorama(
document.getElementById('map'), {
position: position,
pov: {
heading: 0,
pitch: -10
},
// Override the default panoId to outside the building to start
pano:'e_giRekRylYAAAQn7y2xAg'
});
map.setStreetView(panorama);
For placing markers on the map, I found an excellent plugin which creates points and then places elements on those points.
https://github.com/marmat/google-maps-api-addons/tree/master/panomarker
So far this is working very well. If you have an interior walkthrough, you should be able to toggle markers based on the PanoId. You can even add click listeners to open up dialogs.
Is there a way to get the results from Google Autocomplete API before it's displayed below the input? I want to show results from any country except U.S.A.
I found this question: Google Maps API V3 - Anyway to retrieve Autocomplete results instead of dropdown rendering it? but it's not useful, because the method getQueryPredictions only returns 5 elements.
This is an example with UK and US Results: http://jsfiddle.net/LVdBK/
Is it possible?
I used the jquery autocomplete widget and called the google methods manually.
For our case, we only wanted to show addresses in Michigan, US.
Since Google doesn't allow filtering out responses to that degree you have to do it manually.
Override the source function of the jquery autocomplete
Call the google autocompleteService.getQueryPredictions method
Filter out the results you want and return them as the "response" callback of the jquery autocomplete.
Optionally, if you need more detail about the selected item from Google, override the select function of the jquery autocomplete and make a call to Google's PlacesService.getDetails method.
The below assumes you have the Google api reference with the "places" library.
<script src="https://maps.googleapis.com/maps/api/js?key=[yourKeyHere]&libraries=places&v=weekly" defer></script>
var _autoCompleteService; // defined globally in script
var _placesService; // defined globally in script
//...
// setup autocomplete wrapper for google places
// starting point in our city
var defaultBounds = new google.maps.LatLngBounds(
new google.maps.LatLng('42.9655426','-85.6769166'),
new google.maps.LatLng('42.9655426','-85.6769166'));
if (_autoCompleteService == null) {
_autoCompleteService = new google.maps.places.AutocompleteService();
}
$("#CustomerAddress_Street").autocomplete({
minLength: 2,
source: function (request, response) {
if (request.term != '') {
var googleRequest = {
input: request.term,
bounds: defaultBounds,
types: ["geocode"],
componentRestrictions: { 'country': ['us'] },
fields: ['geometry', 'formatted_address']
}
_autoCompleteService.getQueryPredictions(googleRequest, function (predictions) {
var michiganOnly = new Array(); // array to hold only addresses in Michigan
for (var i = 0; i < predictions.length; i++) {
if (predictions[i].terms.length > 0) {
// find the State term. Could probably assume it's predictions[4], but not sure if it is guaranteed.
for (var j = 0; j < predictions[i].terms.length; j++) {
if (predictions[i].terms[j].value.length == 2) {
if (predictions[i].terms[j].value.toUpperCase() == 'MI') {
michiganOnly.push(predictions[i]);
}
}
}
}
}
response(michiganOnly);
});
}
},
select: function (event, ui) {
if (ui != null) {
var item = ui.item;
var request = {
placeId: ui.item.place_id
}
if (_placesService == null) {
$("body").append("<div id='GoogleAttribution'></div>"); // PlacesService() requires a field to put it's attribution image in. For now, just put on on the body
_placesService = new google.maps.places.PlacesService(document.getElementById('GoogleAttribution'));
}
_placesService.getDetails(request, function (result, status) {
if (result != null) {
const place = result;
if (!place.geometry) {
// User entered the name of a Place that was not suggested and
// pressed the Enter key, or the Place Details request failed.
//window.alert("No details available for input: '" + place.name + "'");
return;
}
else {
var latitude = place.geometry.location.lat();
var longitude = place.geometry.location.lng();
// do something with Lat/Lng
}
}
});
}
}
}).autocomplete("instance")._renderItem = function (ul, item) {
// item is the prediction object returned from our call to getQueryPredictions
// return the prediction object's "description" property or do something else
return $("<li>")
.append("<div>" + item.description + "</div>")
.appendTo(ul);
};
$("#CustomerAddress_Street").autocomplete("instance")._renderMenu = function (ul, items) {
// Google's terms require attribution, so when building the menu, append an item pointing to their image
var that = this;
$.each(items, function (index, item) {
that._renderItemData(ul, item);
});
$(ul).append("<li class='ui-menu-item'><div style='display:flex;justify-content:flex-end;'><img src='https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-white3.png' /></div></li>")
}
From a GAS, is it possible to call Maps API services such as DistanceMatrix?
I'd like to calculate distance between addresses stored in a spreadsheet.
I suppose displaying a map is required, to comply with terms of the Maps API.
Would something like the following be possible?
var service = new Maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [OAddresses],
destinations: [DAddresses],
travelMode: Maps.TravelMode.DRIVING,
unitSystem: Maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false
}, callback);
This will help you..It is the complete code with file parsing.
It skips 1st row because of headings.
please change "sheet name" according to your need.
Check the screenshot for better understanding.
ScreenShot: https://docs.google.com/file/d/0B5nG8jqFwu2eMk9uajZJX2VhRjg/edit
function geoDistance() {
var sheetName = 'xyz';
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var selectedSheet = activeSpreadsheet.getSheetByName(sheetName);
var sheet = selectedSheet;
var lastRow = sheet.getLastRow();
var N = lastRow;
for (var i=2;i<=N;i++){
var startpoint = sheet.getRange(i, 1, 1, 1).getValue();
var endpoint = sheet.getRange(i, 2, 1, 1).getValue();
var directions = Maps.newDirectionFinder()
.setOrigin(startpoint)
.setDestination(endpoint)
.setMode(Maps.DirectionFinder.Mode.DRIVING)
.getDirections();
var print = sheet.getRange(i,3,1,1).setValue(directions.routes[0].legs[0].distance.text);
}}
I'm not sure this is the right group. If not, please let me know.
My dilemma:
I need to add Polylines to Google Earth from the results I get back from the Google Maps v3 DirectionsService. There seems to be nothing on the web to that extent. It has to be possible, because Roman does this in his driving simulator: http://earth-api-samples.googlecode.com/svn/trunk/demos/drive-simulator/index.html
Unfortunately, he is using Google Maps v2 there and I can't seem to figure out how to transfer this code into Google Maps v3.
If anyone is interested, here is how I managed to solve it:
function DrawLinesOnEarth() {
var sLat;
var sLon;
//var start = document.getElementById("start").value;
//var end = document.getElementById("end").value;
var request = {
origin: '40.306134,-74.05018',
destination: '40.313223,-74.043496',
travelMode: google.maps.TravelMode.WALKING
};
directionsService.route(request, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
var steps = result.routes[0].legs[0].steps;
//Step through array of step legs and create polylines one by one
var lineStringPlacemark = IMC_ge.createPlacemark('');
var lineString = IMC_ge.createLineString('');
lineStringPlacemark.setGeometry(lineString);
// Add LineString points
for (var x in steps) {
for (var y in steps[x].path) {
sLat = steps[x].path[y].Na;
sLon = steps[x].path[y].Oa;
lineString.getCoordinates().pushLatLngAlt(sLat, sLon, 0);
}
}
// Add the feature to Earth
IMC_ge.getFeatures().appendChild(lineStringPlacemark);
}
});
}