Create new polyline on marker movement - javascript

Below is my code for delivery person tracking. I'm using Maps Javascript API v3 in Ionic-angular food delivery application. I need user to see delivery boy position in realtime. I have succeeded in drawing a polyline, placing delivery boy, user and restaurant markers. The delivery boy marker is moving on location change. But i need to redraw polyline everytime when delivery boy moves. How to do that? Click the link for full code
https://pastebin.com/We8BQd7H
directionsDisplay.setMap(map);
// directionsDisplay.setOptions({ suppressMarkers: true });
directionsDisplay.setOptions({
polylineOptions: {
strokeWeight: 4,
strokeOpacity: 1,
strokeColor: "#000000",
},
suppressMarkers: true,
});
var geocoder = new google.maps.Geocoder();
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [origin1],
destinations: [destinationA],
travelMode: "DRIVING",
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false,
},
function (response, status) {
console.log('distance matrix response', response);
if (status !== "OK") {
alert("Error was: " + status);
} else {
var originList = response.originAddresses;
var destinationList = response.destinationAddresses;
var outputDiv = document.getElementById("output");
// outputDiv.innerHTML = '';
// deleteMarkers(markersArray);
var showGeocodedAddressOnMap = function (asDestination) {
var icon = asDestination ? destinationIcon : originIcon;
return function (results, status) {
if (status === "OK") {
map.fitBounds(bounds.extend(results[0].geometry.location));
// markersArray.push(new google.maps.Marker({
// map: map,
// position: results[0].geometry.location,
// icon: icon
// }));
} else {
alert("Geocode was not successful due to: " + status);
}
};
};
directionsService.route(
{
origin: origin1,
destination: destinationA,
travelMode: "DRIVING",
},
function (response, status) {
console.log('direction response', response);
if (status === "OK") {
directionsDisplay.setDirections(response);
} else {
window.alert("Directions request failed due to " + status);
}
}
);
for (var i = 0; i < originList.length; i++) {
var results = response.rows[i].elements;
geocoder.geocode(
{ address: originList[i] },
showGeocodedAddressOnMap(false)
);
for (var j = 0; j < results.length; j++) {
geocoder.geocode(
{ address: destinationList[j] },
showGeocodedAddressOnMap(true)
);
}
}
}
}

According to the documentation If you want to redraw you're polyline, store it in a variable and use the setmap(null) method.
You can write an update function to remove you're old polyline, update his path, and redraw it. The code can look like this :
let map;
let directionsDisplay;
// assuming you have almost the first two point of the line to draw it
let pathCoordinate = [
{ lat: 37.772, lng: -122.214 },
{ lat: 21.291, lng: -157.821 },
];
let polylineShape = {
strokeWeight: 4,
strokeOpacity: 1,
strokeColor: "#000000",
}
function initMap() {
map = new google.maps.Map(document.getElementById("map"), {
//... you're configuration
});
}
function updatePath(newCoordinate) {
// remove old polyline
directionsDisplay.setMap(null);
// update coordinate
pathCoordinate.push(newCoordinate);
// set the new polyline
directionsDisplay = new google.maps.Polyline({...polylineShape, ...{path:pathCoordinate});
directionsDisplay.setMap(map);
}
//
initmap();
directionsDisplay = new google.maps.Polyline({...polylineShape, ...{path:pathCoordinate});
directionsDisplay.setMap(map);
// then call updatePath() every time you need to update
updatePath({ lat: -18.142, lng: 178.431 });

Related

Getting issue to show autocompleter address in google map on click on button?

I have added the google map code on the page. you can check it on page https://artificialgrass.lazylawn.ca/estimate/
It is not showing the search location in a zoom (20) that I have set it in code. If again I search the address then it displays. Can I load the map on button click? I'm using the following google map code.
var map, measureTool;
var componentForm = {
street_number: 'short_name',
route: 'long_name',
locality: 'long_name',
administrative_area_level_1: 'short_name',
country: 'long_name',
postal_code: 'short_name'
};
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 43.6916507,
lng: -79.41045
},
mapTypeId: google.maps.MapTypeId.SATELLITE,
zoom: 20,
scaleControl: true
});
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
var markers = [];
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
for (var component in componentForm) {
document.getElementById(component).value = '';
document.getElementById(component).disabled = false;
}
// Get each component of the address from the place details,
// and then fill-in the corresponding field on the form.
for (var i = 0; i < places[0]['address_components'].length; i++) {
var addressType = places[0]['address_components'][i].types[0];
if (componentForm[addressType]) {
var val = places[0]['address_components'][i]
[componentForm[addressType]];
document.getElementById(addressType).value = val;
}
}
// Clear out the old markers.
markers.forEach(function(marker) {
marker.setMap(null);
});
markers = [];
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place) {
if (!place.geometry) {
console.log("Returned place contains no geometry");
return;
}
var icon = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
// Create a marker for each place.
markers.push(new google.maps.Marker({
map: map,
icon: icon,
title: place.name,
position: place.geometry.location
}));
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
measureTool = new MeasureTool(map, {
contextMenu: true,
showSegmentLength: true,
tooltip: true,
unit: MeasureTool.UnitTypeId.IMPERIAL,
// metric, imperial, or nautical
});
// test for setting units
// measureTool.setOption('unit', MeasureTool.UnitTypeId.METRIC);
measureTool.addListener('measure_start', () => {
console.log('started');
// measureTool.removeListener('measure_start')
});
measureTool.addListener('measure_end', (e) => {
console.log('ended', e.result);
// measureTool.removeListener('measure_end');
var area2 = e.result['area'].toFixed(2);
document.getElementById("selected_area").value = area2;
document.getElementById("area_size").value = area2;
});
measureTool.addListener('measure_change', (e) => {
console.log('changed', e.result);
});
}
document.getElementById("get-start").onclick = function() {
document.getElementById("maparea").style.display = 'block';
}
Got the solution.
<script>
var map, measureTool;
var componentForm = {
street_number: 'short_name',
route: 'long_name',
locality: 'long_name',
administrative_area_level_1: 'short_name',
country: 'long_name',
postal_code: 'short_name'
};
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 43.6916507, lng: -79.41045 },
mapTypeId:google.maps.MapTypeId.SATELLITE,
zoom: 20,
scaleControl: true
});
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
var searchBtn = document.getElementById('get-start');
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
var markers = [];
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
});
searchBtn.onclick = function () {
document.getElementById("maparea").style.display = 'block';
displaySearchResults(map,searchBox,markers);
}
measureTool = new MeasureTool(map, {
contextMenu: true,
showSegmentLength: true,
tooltip: true,
unit: MeasureTool.UnitTypeId.METRIC,
// metric, imperial, or nautical
});
// test for setting units
// measureTool.setOption('unit', MeasureTool.UnitTypeId.METRIC);
measureTool.addListener('measure_start', () => {
console.log('started');
// measureTool.removeListener('measure_start')
});
measureTool.addListener('measure_end', (e) => {
console.log('ended', e.result);
// measureTool.removeListener('measure_end');
var area2 = e.result['area'].toFixed(2);
document.getElementById("selected_area").value= area2;
});
measureTool.addListener('measure_change', (e) => {
console.log('changed', e.result);
});
}
function displaySearchResults(map, searchBox, markers) {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
for (var component in componentForm) {
document.getElementById(component).value = '';
document.getElementById(component).disabled = false;
}
// Get each component of the address from the place details,
// and then fill-in the corresponding field on the form.
for (var i = 0; i < places[0]['address_components'].length; i++) {
var addressType = places[0]['address_components'][i].types[0];
if (componentForm[addressType]) {
var val = places[0]['address_components'][i][componentForm[addressType]];
document.getElementById(addressType).value = val;
}
}
// Clear out the old markers.
markers.forEach(function (marker) {
marker.setMap(null);
});
markers = [];
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function (place) {
if (!place.geometry) {
console.log("Returned place contains no geometry");
return;
}
var icon = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
// Create a marker for each place.
markers.push(new google.maps.Marker({
map: map,
icon: icon,
title: place.name,
position: place.geometry.location
}));
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
}
</script>

Difficulty with Google Maps API

I am trying to create a simple program that takes in specifically two specifically placed destinations and shows the directions in between them. For whatever reason, I just cannot get the directions to show up.
<script>
var directionsService = new google.maps.directionsService();
var directionsDisplay = new google.maps.directionsRenderer();
var new_york = {lat: 40.7128, lng: -74.0060};
var los_angeles = {lat: 34.0522, lng: -118.2437};
function initMap() {
var mapMarkers = [];
var map = new google.maps.Map(
document.getElementById('map'), {zoom: 4, center: {lat: 40, lng: -99}}
);
var marker1 = new google.maps.Marker({
position: new_york,
map: map,
title: 'Home'
});
var marker2 = new google.maps.Marker({
position: los_angeles,
map: map,
title: 'School'
});
}
calculateAndDisplayRoute: function(directionsService, directionsDisplay, new_york, los_angeles) {
directionsService.route({
origin: new_york,
destination: los_angeles,
travelMode: 'DRIVING'
}, function(response, status) {
if (status === 'OK') {
directionsDisplay.setDirections(response);
} else {
alert('Directions request failed due to ' + status);
}
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDmA98U4We-2IAaHbxa354v_C91IktiSKM3&callback=calculateAndDisplayRoute"></script>
I think there are a few problems with your code, first you need to be aware that the google maps library needs to be loaded before you can create new instances of DirectionsService and DirectionsRenderer, which btw should be in CamelCase:
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
Since you are not loading the maps library asynchronously you can place the script at the top of your page and just drop the callback argument. I've made a few changes to your code, please check it out below (you need to add your api key):
var new_york = {lat: 40.7128, lng: -74.0060};
var los_angeles = {lat: 34.0522, lng: -118.2437};
function initMap() {
var mapMarkers = [];
var map = new google.maps.Map(
document.getElementById('map'), {zoom: 4, center: {lat: 40, lng: -99}}
);
var marker1 = new google.maps.Marker({
position: new_york,
map: map,
title: 'Home'
});
var marker2 = new google.maps.Marker({
position: los_angeles,
map: map,
title: 'School'
});
}
function calculateAndDisplayRoute() {
initMap();
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
var route = {
origin: new_york,
destination: los_angeles,
travelMode: 'DRIVING'
};
directionsService.route(route, function(response, status) {
if (status === 'OK') {
directionsDisplay.setDirections(response);
} else {
alert('Directions request failed due to ' + status);
}
});
}
calculateAndDisplayRoute();
<script src="https://maps.googleapis.com/maps/api/js?key=???"></script>
<div id="map" style="width: 100%; height: 500px;"></div>

HTML 5 Geolocation not working with Directions API

I am trying to use the geolocations API with the Directions service but I get:
var UserLoc;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var lat=position.coords.latitude;
var lng=position.coords.longitude;
console.log(lat);
console.log(lng);
UserLoc = new google.maps.LatLng(lat,lng);
var NewMarker = new google.maps.Marker({
position: UserLoc,
draggable: false,
animation: google.maps.Animation.DROP,
map: SEVTmap
});
}
);
}
else {
alert ( "Възникна проблем при намирането на местонахождението ви!" );
}
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.setMap(SEVTmap);
var request = {
origin: UserLoc,
destination: Destination,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
Error : InvalidValueError: in property origin: not a string; and not a LatLng or LatLngLiteral: not an Object; and not an Object
The marker is created;
The geolocation service is asynchronous, you have to use the result in its callback function when/where it is available
var UserLoc;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var lat = position.coords.latitude;
var lng = position.coords.longitude;
console.log(lat);
console.log(lng);
UserLoc = new google.maps.LatLng(lat, lng);
var NewMarker = new google.maps.Marker({
position: UserLoc,
draggable: false,
animation: google.maps.Animation.DROP,
map: SEVTmap
});
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer({
map: SEVTmap
});
directionsDisplay.setMap(SEVTmap);
var request = {
origin: UserLoc,
destination: Destination,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}, function (PositionError) {alert("geolocation error:"+PositionError.code+" msg="+PositionError.message);});
} else {
alert("Възникна проблем при намирането на местонахождението ви!");
}

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);
});
});

Multiple markers on google maps using json and placeid

the problem i've got is that I don't know where the problem is :P
From the beginning. I've got 3 files, the json file JS and html. JS should get placeid from json and based on that place a marker on the map. It's all pretty simple but somehow it doesn't work, the map is being created but no markers show up.
Here're the files:
JSON:
[{ "placeid": 'ChIJu6HrLMVWIkcRWHTA90kiueI' , "content": " 1 " } ,
{ "placeid": 'ChIJnXBuJ34zGUcRvt9FTKrPeeM' , "content": " 2 " } ,
{ "placeid": 'ChIJiwUNhqX7PEcRdJjYqzrWYjs' , "content": " 3 " } ]
HTML:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="http://code.jquery.com/jquery-migrate-1.1.1.min.js"></script>
<script src="functions_edit.js"></script>
</head>
<body>
<div id="map-canvas" style="width:500px; height:400px"></div>
</body>
</html>
JS:
var openedInfoWindow = null;
function initialize() {
var latitude = 51.9315631,
longitude = 19.473451,
radius = 8000,
center = new google.maps.LatLng(latitude,longitude),
mapOptions = {
center: center,
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
setMarkers(center, radius, map);
}
function setMarkers(center, radius, map) {
var json = (function () {
var json = null;
$.ajax({
'async': false,
'global': false,
'url': "placeid.json",
'dataType': "json",
'success': function (data) {
json = data;
}
});
return json;
})();
for (var i = 0, length = json.length; i < length; i++) {
var data = json[i];
var service = new google.maps.places.PlacesService(map);
service.getDetails({
placeId: data.placeid
}, function (result, status) {
if (status != google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
var marker = new google.maps.Marker({
map: map,
place: {
placeId: data.placeid,
location: result.geometry.location
}
//position: result.geometry.location
});
});
infoBox(map, marker, data);
}
}
function infoBox(map, marker, data) {
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, "click", function(e) {
infoWindow.setContent(data.content);
infoWindow.open(map, marker);
});
(function(marker, data) {
google.maps.event.addListener(marker, "click", function(e) {
infoWindow.setContent(data.content);
infoWindow.open(map, marker);
});
})(marker, data);
}
google.maps.event.addDomListener(window, 'load', initialize);
With the posted code I get a javascript error: Uncaught ReferenceError: marker is not defined
You are calling the InfoBox function in the wrong place (outside the scope where marker exists).
Once I fix that I get infowindows, but you have an issue that can be solved by function closure (all the infowindows have the content "3", the last marker processed). (For an example of function closure see Google Maps JS API v3 - Simple Multiple Marker Example)
working fiddle
code snippet:
var placeid_json = [{
"placeid": 'ChIJu6HrLMVWIkcRWHTA90kiueI',
"content": " 1 "
}, {
"placeid": 'ChIJnXBuJ34zGUcRvt9FTKrPeeM',
"content": " 2 "
}, {
"placeid": 'ChIJiwUNhqX7PEcRdJjYqzrWYjs',
"content": " 3 "
}];
var openedInfoWindow = null;
function initialize() {
var latitude = 51.9315631,
longitude = 19.473451,
radius = 8000,
center = new google.maps.LatLng(latitude, longitude),
mapOptions = {
center: center,
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
setMarkers(center, radius, map);
}
function setMarkers(center, radius, map) {
/* var json = (function () {
var json = null;
$.ajax({
'async': false,
'global': false,
'url': "placeid.json",
'dataType': "json",
'success': function (data) {
json = data;
}
});
return json;
})(); */
var json = placeid_json;
for (var i = 0, length = json.length; i < length; i++) {
var data = json[i];
createMarker(data, map);
}
}
function createMarker(data, map) {
var service = new google.maps.places.PlacesService(map);
service.getDetails({
placeId: data.placeid
}, function (result, status) {
if (status != google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
var marker = new google.maps.Marker({
map: map,
place: {
placeId: data.placeid,
location: result.geometry.location
}
//position: result.geometry.location
});
infoBox(map, marker, data, result);
});
}
function infoBox(map, marker, data, result) {
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent(data.content);
infoWindow.open(map, marker);
});
(function (marker, data) {
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent(data.content+"<br>"+result.name);
infoWindow.open(map, marker);
});
})(marker, data);
}
google.maps.event.addDomListener(window, 'load', initialize);
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map-canvas" style="width:500px; height:400px"></div>

Categories