Google map api open tab with route from geolocation to placeId - javascript

I would like to create a link that open a new google map tab with route from navigator.geolocation.getCurrentPosition to a specific placeId.
If there is geolocation a problem then, open a new tab without origin completed
Here is what I try:
const options = {
placeId: 'ChIJDyx4bNhu5kcRqJ3RkAPGMEk',
latitude: 48.925606,
longitude: 2.327621,
};
const mapOptions = {
zoom: 15,
center: new google.maps.LatLng(options.latitude, options.longitude),
};
const map = new google.maps.Map(document.getElementById('Map'), mapOptions);
const service = new google.maps.places.PlacesService(map);
service.getDetails({
placeId: options.placeId,
}, (result, status) => {
if (status !== google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
const marker = new google.maps.Marker({
map: map,
position: result.geometry.location,
});
});
$('.js-ItinaryFromI').on('click', () => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
const pos = {
lat: position.coords.latitude,
lng: position.coords.longitude,
};
}, () => {
// The problem seems to come from this line :
window.open(`https://www.google.com/maps/dir/origin=pos&destination=place_id:${options.placeId}&travelmode=driving`, '_blank');
});
} else {
// And this line
window.open(`https://www.google.com/maps/dir//place_id${options.placeId}&travelmode=driving`, '_blank');
}
});
Any idea please ?

You should use Google Maps Directions API if you wanted to calculate directions between location. You can search for directions for several modes of transportation, including transit, driving, walking, or cycling.
These parameters (origin, destination, travel_mode) are used in Google Maps Directions API and probably won't work well using Google Maps.
I also noticed in the code you provided that certain variables were not properly concatenated into the request. Hence, your request would not provide accurate results.
Here's a sample of valid request:
window.open('https://maps.googleapis.com/maps/api/directions/json?origin='+pos.lat+','+pos.lng+'&destination=place_id:'+options.placeId+'&travelmode=driving&key=YOUR_API_KEY', '_blank');
Don't forget to include your API key in each request.
I modified your code a bit. You can check it below:
const options = {
placeId: 'ChIJDyx4bNhu5kcRqJ3RkAPGMEk',
//placeId: 'ChIJ51Ic7BXIlzMRK2WH8qoM6Ek',
latitude: 48.925606,
longitude: 2.327621,
};
function initMap() {
const mapOptions = {
zoom: 15,
center: new google.maps.LatLng(options.latitude, options.longitude),
};
const map = new google.maps.Map(document.getElementById('Map'), mapOptions);
const service = new google.maps.places.PlacesService(map);
service.getDetails({
placeId: options.placeId,
}, (result, status) => {
if (status !== google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
const marker = new google.maps.Marker({
map: map,
position: result.geometry.location,
});
});
if ( navigator.geolocation ) {
navigator.geolocation.getCurrentPosition((position) => {
const pos = {
lat: position.coords.latitude,
lng: position.coords.longitude,
};
document.getElementById('js-ItinaryFromI').addEventListener('click', () => {
window.open('https://maps.googleapis.com/maps/api/directions/json?origin='+pos.lat+','+pos.lng+'&destination=place_id:'+options.placeId+'&travelmode=driving&key=[API-KEY]', '_blank');
});
});
} else {
alert('Geolocation not found!');
}
}
html,body,#Map {
width:100%;
height:100%;
}
<button id="js-ItinaryFromI">Click Me</button>
<div id="Map" ></div>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCzjs-bUR6iIl8yGLr60p6-zbdFtRpuXTQ&callback=initMap&libraries=places">
</script>
You can try this using JSBin. For some reason it doesn't work here in Stackoverflow's code snippet. I don't know why.
Good luck and happy coding!

Related

Google Maps API Finding Details

I am trying to use the google maps details about a location to display in an info window from a marker. I am creating a marker and want to get the address of that marker so that I can store it in a database. I am able to get the title of the marker but I do not know how to get the full address. This is my code:
<script>
let pos;
let map;
let bounds;
let infoWindow;
let currentInfoWindow;
let service;
let infoPane;
function initMap() {
bounds = new google.maps.LatLngBounds();
infoWindow = new google.maps.InfoWindow;
currentInfoWindow = infoWindow;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
map = new google.maps.Map(document.getElementById('map'), {
center: pos,
zoom: 20
});
bounds.extend(pos);
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
infoWindow.open(map);
map.setCenter(pos);
getNearbyPlaces(pos);
}, () => {
handleLocationError(true, infoWindow);
});
} else {
handleLocationError(false, infoWindow);
}
}
function handleLocationError(browserHasGeolocation, infoWindow) {
pos = { lat: -33.856, lng: 151.215 };
map = new google.maps.Map(document.getElementById('map'), {
center: pos,
zoom: 20
});
infoWindow.setPosition(pos);
infoWindow.setContent(browserHasGeolocation ?
'Geolocation permissions denied. Using default location.' :
'Error: Your browser doesn\'t support geolocation.');
infoWindow.open(map);
currentInfoWindow = infoWindow;
getNearbyPlaces(pos);
}
function getNearbyPlaces(position) {
let request = {
location: position,
rankBy: google.maps.places.RankBy.DISTANCE,
keyword: 'basketball courts'
};
service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, nearbyCallback);
}
function nearbyCallback(results, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
createMarkers(results);
}
}
function createMarkers(places) {
places.forEach(place => {
let marker = new google.maps.Marker({
position: place.geometry.location,
map: map,
title: place.name
});
marker.addListener("click", () => {
map.setZoom(16);
map.setCenter(marker.getPosition());
});
bounds.extend(place.geometry.location);
});
map.fitBounds(bounds);
}
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap">
</script>
I am unfamiliar with javascript so I am not sure how exactly to format it. If it shows up in the infowindow I can work on it myself from there but if anyone has suggestions on how to show it there I would appreciate it.
To be fair you have done most of the work but if it is simply a case of taking the results from the nearbyPlaces search and adding to an infowindow then perhaps you can find use in the following. The work is done in the createMarkers function
<!doctype html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Google Maps: </title>
<style>
#map{
width:800px;
height:600px;
float:none;
margin:auto;
}
</style>
</head>
<body>
<div id='map'></div>
<script>
let pos;
let map;
let bounds;
let infoWindow;
let currentInfoWindow;
let service;
let infoPane;
function initMap() {
bounds = new google.maps.LatLngBounds();
infoWindow = new google.maps.InfoWindow;
currentInfoWindow = infoWindow;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
map = new google.maps.Map(document.getElementById('map'), {
center: pos,
zoom: 20
});
bounds.extend(pos);
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
infoWindow.open(map);
map.setCenter(pos);
getNearbyPlaces( pos );
}, () => {
handleLocationError(true, infoWindow);
});
} else {
handleLocationError(false, infoWindow);
}
}
function handleLocationError(browserHasGeolocation, infoWindow) {
pos = { lat: -33.856, lng: 151.215 };
map = new google.maps.Map(document.getElementById('map'), {
center: pos,
zoom: 20
});
infoWindow.setPosition(pos);
infoWindow.setContent(browserHasGeolocation ?
'Geolocation permissions denied. Using default location.' :
'Error: Your browser doesn\'t support geolocation.');
infoWindow.open(map);
currentInfoWindow = infoWindow;
getNearbyPlaces(pos);
}
function getNearbyPlaces(position) {
let request = {
location: position,
rankBy: google.maps.places.RankBy.DISTANCE,
keyword: 'basketball courts'
};
service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, nearbyCallback);
}
function nearbyCallback(results, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
createMarkers(results);
}
}
function createMarkers(places) {
places.forEach(place => {
console.log(place)
let marker = new google.maps.Marker({
position: place.geometry.location,
map: map,
title:place.name,
/* assign the response data as a property of the marker */
content:place
});
/*
for convenience a regular anonymous function is better here
as it allws us to use `this` to refer to the marker itself
within the body of the function.
*/
marker.addListener("click", function(e){
map.setZoom(16);
map.setCenter( marker.getPosition() );
/*
Iterate through ALL properties ( or just some ) of the `this.contents`
property and set as the content for the infowindow
*/
infoWindow.setContent( Object.keys(this.content).map(k=>{
return [k,this.content[k] ].join('=')
}).join( String.fromCharCode(10) ) );
/* open the infowindow */
infoWindow.setPosition(e.latLng)
infoWindow.open(map,this);
});
bounds.extend(place.geometry.location);
});
map.fitBounds(bounds);
}
</script>
<script async defer src="//maps.googleapis.com/maps/api/js?key=<APIKEY>&libraries=places&callback=initMap">
</script>
</body>
</html>
The data returned is JSON and has a structure like this for each individual result. The location data contained therein will bear no resemblance to that found for others running this self same script but show suffice.
{
"business_status" : "OPERATIONAL",
"geometry" : {
"location" : {
"lat" : 52.7525688,
"lng" : 0.4036446
},
"viewport" : {
"northeast" : {
"lat" : 52.75354047989272,
"lng" : 0.4048724298927222
},
"southwest" : {
"lat" : 52.75084082010728,
"lng" : 0.4021727701072778
}
}
},
"icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/generic_business-71.png",
"icon_background_color" : "#7B9EB0",
"icon_mask_base_uri" : "https://maps.gstatic.com/mapfiles/place_api/icons/v2/generic_pinlet",
"name" : "Multi-Use Games Area",
"place_id" : "ChIJX2Y4mjyL10cRQ0885NSSeTE",
"plus_code" : {
"compound_code" : "QC33+2F King's Lynn",
"global_code" : "9F42QC33+2F"
},
"rating" : 0,
"reference" : "ChIJX2Y4mjyL10cRQ0885NSSeTE",
"scope" : "GOOGLE",
"types" : [ "point_of_interest", "establishment" ],
"user_ratings_total" : 0,
"vicinity" : "The Walks, nr, South St, King's Lynn"
}
Within the marker click callback function, where previously there is this:
infoWindow.setContent( Object.keys(this.content).map(k=>{
return [k,this.content[k] ].join('=')
}).join( String.fromCharCode(10) ) );
We can build up a string of whatever items you wish to use:
infoWindow.setContent( this.content.name ); // simply display the name
or
infoWindow.setContent(
`<h1>${this.content.name}</h1>
<p>${this.content.vicinity}</p>
<ul>
<li>Lat: ${this.content.geometry.location.lat()}</li>
<li>Lng: ${this.content.geometry.location.lng()}</li>
</ul>
<img src="${this.content.icon}" />`
); // show some HTML content

Using react hooks and google maps api How to show one directions with waypoints and single different marker on same map?

Using react hooks and google maps API I have a code that puts a marker on the map but I don't know add show directions in this code. I searched but couldn't find a map example that includes both and also there is no definite google maps documentation for react hooks. I believe many other people are wondering this too, adding a marker and directions same map in react. I don't want to ask nonspecific questions but I have to. Thank you in advance
My goal is that the map component shows the location as a marker but I have directions too.
Only pins marker working code HERE
Here is my map component I've tried to implement directions but not worked.
MapTest.js
import { Fragment, useEffect, useState, useRef } from 'react';
import { useGoogleMaps } from 'react-hook-google-maps';
import {
withGoogleMap,
withScriptjs,
GoogleMap,
DirectionsRenderer,
} from 'react-google-maps';
const directions = [
{
lat: 35,
lng: -100,
},
{
lat: 36,
lng: -100,
},
];
const MapTest = () => {
const prevMarkersRef = useRef([]);
const [directions, setDirections] = useState('');
// incoming location to set
let point = {
lat: 34,
lng: -100,
};
// Map options
const { ref, map, google } = useGoogleMaps(
'YOUR API KEY',
{
zoom: 8,
center: point,
},
<DirectionsRenderer directions={directions} />
);
// directions
if (map) {
const directionsService = new google.maps.DirectionsService();
const origin = {
lat: 35,
lng: -100,
};
const destination = origin;
directionsService.route(
{
origin: origin,
destination: point,
travelMode: google.maps.TravelMode.DRIVING,
waypoints: directions,
},
(result, status) => {
if (status === google.maps.DirectionsStatus.OK) {
console.log(result);
setDirections(result);
} else {
console.error(`error fetching directions ${result}`);
}
}
);
}
useEffect(() => {
if (map) {
// ADD MARKER
const m = addMarker();
clearMarkers(prevMarkersRef.current); //clear prev markers
prevMarkersRef.current.push(m);
map.setCenter(point);
}
}, [point]);
// SIDE FUNCTIONS
function addMarker() {
return new window.google.maps.Marker({
position: point,
map: map,
});
}
function clearMarkers(markers) {
for (let m of markers) {
m.setMap(null);
}
}
return (
<div>
<div
ref={ref}
style={{ width: 400, height: 300 }}
/>
</div>
);
};
export default MapTest;
You can use the google.maps.DirectionsService() to call the Google Maps Directions API and google.maps.DirectionsRenderer() to display the directions to the map. You can instantiate them inside of your useEffect, bind the DirectionsRenderer to your map using setMap() then pass them in the function calcRoute(directionsService, directionsRenderer)` that will call the DirectionService:
useEffect(() => {
if (map) {
// ADD MARKER
const m = addMarker();
clearMarkers(prevMarkersRef.current); //clear prev markers
prevMarkersRef.current.push(m);
map.setCenter(point);
let directionsService = new google.maps.DirectionsService();
let directionsRenderer = new google.maps.DirectionsRenderer();
directionsRenderer.setMap(map);
calcRoute(directionsService, directionsRenderer);
}
}, [point]);
For the calcRoute function, build the directions request by setting your origin, destination, mode and other parameters. Then pass them to the directionService.route to send the request. If the DirectionService result status is OK, show your result via the DirectionsRenderer:
function calcRoute(directionsService, directionsRenderer) {
let request = {
origin: point,
destination: dest,
travelMode: "DRIVING"
};
directionsService.route(request, function(result, status) {
if (status == "OK") {
directionsRenderer.setDirections(result);
}
});
}
Here is a sample working code.

Google geocode function returning undefined

function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 15,
center: {lat: 24.149950, lng: 120.638610},
mapId: '63d22d3ae6cf15ff'
});
console.log(getCoordinates("Bouverie Street"));
}
// geocoder
function getCoordinates(address) {
const geocoder = new google.maps.Geocoder();
geocoder.geocode({address: address}, (results, status) => {
if (status === 'OK') {
return results[0].geometry.location;
} else {
alert("Geocode error: " + status);
console.log(("Geocode error: " + status));
}
});
}
On line 9 I'm trying to log the return object from getCoordinates(). However it shows up as undefined for some reason. I think the function works as intended as, if I added "console.log(results);" above the return statement, it logs the result object as intended.
if (status === 'OK') {
return results[0].geometry.location;
}
What am I doing wrong? Thanks in advance.
There has occurred an asynchronous issue. To get rid of that(in this case, you're printing latitude and longitude) you can pass a callback parameter when you're calling getCoordinates function.
Here I'm going to use below script for the example:
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&callback=initMap" defer></script>
So replace this with your own which will be like this:
<script type="text/javascript" src="http://maps.google.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" defer></script>
So here I'm going to pass a callback parameter to getCoordinates function which will print coordinates passed from getCoordinates in this way:
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 15,
center: { lat: 24.149950, lng: 120.638610 },
mapId: '63d22d3ae6cf15ff'
});
getCoordinates("Bouverie Street", printLocation);
}
function printLocation(location) {
console.log("location");
console.log(location.lat());
console.log(location.lng());
}
// geocoder
function getCoordinates(address, myCallback) {
const geocoder = new google.maps.Geocoder();
geocoder.geocode({ address: address }, (results, status) => {
if (status === 'OK') {
myCallback(results[0].geometry.location);
} else {
console.warn = () => {}; // stop printing warnings
console.log(("Geocode error: " + status));
}
});
}
#map {
height: 400px;
width: 100%;
}
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&callback=initMap" defer></script>
<div id="map"></div>

i'm unable to get current location in ionic 3

i'm not getting google map in ionic 3 i'm using plain javascript so i think it is not displaying in my mobile.
here is my code
geocodeLatLng(lat, lng) {
var geocoder = new google.maps.Geocoder;
var latlng = {
lat: lat,
lng: lng
};
geocoder.geocode({
'location': latlng
}, (results, status) => {
if (status === 'OK') {
if (results[0]) {
console.log(results[0].formatted_address);
} else {
window.alert('No results found');
}
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
}
here is demo online: how to get current postion name using google map api
i tried to convert it to ionic 3
import { Geolocation } from '#ionic-native/geolocation';
loadMap(){
this.geolocation.getCurrentPosition().then((position) => {
let latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
// don't know further steps
}, (err) => {
console.log(err);
});
}
Question i want to achieve same result as this with ionic 3:how to get current postion name using google map api
First install the google map library using this,
npm install #types/googlemaps --save-dev
Now go to node_modules and then #types and inside that googlemaps folder and add below line,
declare module 'googlemaps';
Then import google map module in your component file,
import { Geolocation ,GeolocationOptions } from '#ionic-native/geolocation';
import { googlemaps } from 'googlemaps';
export class HomePage {
#ViewChild('map') mapElement: ElementRef;
map:any;
latLng:any;
mapOptions:any;
constructor(private geolocation : Geolocation){ }
ionViewDidLoad(){
this.loadMap();
}
loadMap(){
this.geolocation.getCurrentPosition().then((position) => {
this.latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
console.log('latLng',this.latLng);
this.mapOptions = {
center: this.latLng,
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(this.mapElement.nativeElement, this.mapOptions);
}, (err) => {
alert('err '+err);
});
}
}
Now add this code in your HTML file,
<div #map id="map"></div>
Thanks,

Meteor implementing Google Maps and Google Places

I'm attempting to implement a Google Map on my Meteor app that will get the user's location and then will find places that serve food near the user. I began by implementing the example
given by Google, and it worked fine when I did it that way; however I'm trying to implement it properly by adding it to the actual Javascript file and it is now giving me a "Google is undefined" error.
menuList = new Mongo.Collection('items');
if (Meteor.isClient) {
var pls;
var map;
var infowindow;
Meteor.startup(function () {
//get user location and return location in console
var options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
function success(pos) {
var crd = pos.coords;
console.log('Your current position is:');
console.log('Latitude : ' + crd.latitude);
console.log('Longitude: ' + crd.longitude);
console.log('More or less ' + crd.accuracy + ' meters.');
pls = {lat: crd.latitude, lng: crd.longitude};
};
function error(err) {
console.warn('ERROR(' + err.code + '): ' + err.message);
};
navigator.geolocation.getCurrentPosition(success, error, options);
})
Meteor.methods({
callback: function (results, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
},
createMarker: function (place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(place.name);
infowindow.open(map, this);
});
}
})
Template.searchIt.helpers({
'initMap': function () {
console.log("HERE");
//Dummy values I placed for StackOverflow
var pyrmont = {lat: -33.234, lng: 95.343};
map = new google.maps.Map(document.getElementById('map'), {
center: pyrmont,
zoom: 15
});
infowindow = new google.maps.InfoWindow();
var service = new google.maps.places.PlacesService(map);
service.nearbySearch({
location: pyrmont,
radius: 500,
types: ['food']
}, callback);
}
})
}
<head>
<title>Place searches</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyACgaDFJrh2pMm-bSta1S40wpKDDSpXO2M
&signed_in=true&libraries=places" async defer></script>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
</style>
</head>
<body>
{{>searchIt}}
</body>
<template name="searchIt">
{{initMap}}
</template>
You should try the dburles:google-maps package.
Here is an example written by its author: http://meteorcapture.com/how-to-create-a-reactive-google-map/
Have fun!
i had to place the code you have above inside of a GoogleMaps.ready('map', callback) block. or inside of an if (GoogleMaps.loaded()) {} block...
for instance.. this works just fine:
caveat: i'm using the radarSearch, but the concept is the same.
Template.galleryCard.onRendered(function() {
GoogleMaps.ready('minimap', function(map) {
const params = {
map: map,
name: 'The Spice Suite',
loc: {lat: 38.9738619, lng: -77.01829699999999},
};
const service = new google.maps.places.PlacesService(params.map.instance);
let request2 = {
//name & location & radius (meters).
name: params.name,
location: params.loc,
radius: 100,
};
let callback = function(results,status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
console.log(results[0]);
return results[0].place_id;
} else {
console.log(status);
}
};
service.radarSearch(request2,callback);
});
});

Categories