overview_path of the Directions Service api returns encoded lat lang [duplicate] - google-maps

This question already has answers here:
Google Map JS API changed event.latLng.* property names
(1 answer)
Cannot use google.maps.LatLng object's lat
(1 answer)
Google maps API: get lat / long separately
(3 answers)
google.maps.LatLng returns a function which returns 'a'. Why?
(1 answer)
Closed 2 months ago.
I want to get the longitude and latitude of the route. When I check the directions response object I see that overview_path returns an array of longitude and latitude but it is I think encoded.
This is what it looks like. Can someone please explain in which format is it and how can I get the longitude and latitude in numbers format.

See the documentation. overview_path is an array of google.maps.LatLng objects, each of them has a .lat() and a .lng() method that returns the associated latitude and longitude.
var overview_path=response.routes[0].overview_path;
for (var i=0; i<overview_path.length;i++) {
console.log("latitude="+overview_path[i].lat()+", longitude="+overview_path[i].lng())
}
proof of concept fiddle (logs each latitude/longitude from the overview_path)
code snippet:
function initMap() {
const directionsService = new google.maps.DirectionsService();
const directionsRenderer = new google.maps.DirectionsRenderer();
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 7,
center: {
lat: 41.85,
lng: -87.65
},
});
directionsRenderer.setMap(map);
calculateAndDisplayRoute("New York, NY", "Newark,NJ", directionsService, directionsRenderer);
}
function calculateAndDisplayRoute(start, end, directionsService, directionsRenderer) {
directionsService
.route({
origin: {
query: start,
},
destination: {
query: end,
},
travelMode: google.maps.TravelMode.DRIVING,
})
.then((response) => {
directionsRenderer.setDirections(response);
var overview_path = response.routes[0].overview_path;
for (var i = 0; i < overview_path.length; i++) {
console.log("latitude=" + overview_path[i].lat() + ", longitude=" + overview_path[i].lng())
}
})
.catch((e) => window.alert("Directions request failed due to " + status));
}
window.initMap = initMap;
/*
* Always set the map height explicitly to define the size of the div element
* that contains the map.
*/
#map {
height: 100%;
}
/*
* Optional: Makes the sample page fill the window.
*/
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#floating-panel {
position: absolute;
top: 10px;
left: 25%;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
text-align: center;
font-family: "Roboto", "sans-serif";
line-height: 30px;
padding-left: 10px;
}
<!DOCTYPE html>
<html>
<head>
<title>Directions Service</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<div id="map"></div>
<!--
The `defer` attribute causes the callback to execute after the full HTML
document has been parsed. For non-blocking uses, avoiding race conditions,
and consistent behavior across browsers, consider loading using Promises
with https://www.npmjs.com/package/#googlemaps/js-api-loader.
-->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&v=weekly" defer></script>
</body>
</html>

Related

How to make the polyline change with the draggable route [duplicate]

This question already has answers here:
How to get a draggable waypoint's location from google directions result
(1 answer)
Google Maps API v3 - Directions with draggable alternate routes
(1 answer)
suppressMarkers and draggable for DirectionsRendererOptions Google Maps API
(1 answer)
How do I change the route provided to me by the directions API on web?
(1 answer)
Closed last month.
I am trying to create a polyline from the route. The route is draggable and it has waypoints. I am using the directions_changed event listener to draw the polyline so that whenever the route changes the polyline also changes. I am able to achieve all of this except then when I drag the route I get the new polyline but I also have the older polyline drawn on the route. Whenever the route is dragged I don't want the older polyline to appear along with the new polyline.
How can I achieve this?
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 4,
center: { lat: -24.345, lng: 134.46 }, // Australia.
});
const directionsService = new google.maps.DirectionsService();
const directionsRenderer = new google.maps.DirectionsRenderer({
draggable: true,
map,
panel: document.getElementById("panel"),
});
directionsRenderer.addListener("directions_changed", () => {
const directions = directionsRenderer.getDirections();
if (directions) {
computeTotalDistance(directions);
var polyline = new google.maps.Polyline(
{
path:google.maps.geometry.encoding.decodePath(directions.routes[0].overview_polyline),
map : map
}
)
if(polyline)
{
console.log(polyline)
polyline.setMap(map)
}
}
});
displayRoute(
"Perth, WA",
"Sydney, NSW",
directionsService,
directionsRenderer
);
}
function displayRoute(origin, destination, service, display) {
service
.route({
origin: origin,
destination: destination,
waypoints: [
{ location: "Adelaide, SA" },
{ location: "Broken Hill, NSW" },
],
travelMode: google.maps.TravelMode.DRIVING,
avoidTolls: true,
})
.then((result) => {
display.setDirections(result);
})
.catch((e) => {
alert("Could not display directions due to: " + e);
});
}
function computeTotalDistance(result) {
let total = 0;
const myroute = result.routes[0];
if (!myroute) {
return;
}
for (let i = 0; i < myroute.legs.length; i++) {
total += myroute.legs[i].distance.value;
}
total = total / 1000;
document.getElementById("total").innerHTML = total + " km";
}
window.initMap = initMap;
If you want to hide the old polyline, keep a reference to it (outside the scope of the directions_changed listener) and remove it from the map with polyline.setMap(null); before creating the new polyline:
if (polyline) {
// if polyline already exists, remove it from the map.
polyline.setMap(null)
}
polyline = new google.maps.Polyline({
path: google.maps.geometry.encoding.decodePath(directions.routes[0].overview_polyline),
map: map
})
proof of concept fiddle
code snippet:
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 4,
center: {
lat: -24.345,
lng: 134.46
}, // Australia.
});
const directionsService = new google.maps.DirectionsService();
const directionsRenderer = new google.maps.DirectionsRenderer({
draggable: true,
map,
panel: document.getElementById("panel"),
});
let polyline;
directionsRenderer.addListener("directions_changed", () => {
const directions = directionsRenderer.getDirections();
if (directions) {
computeTotalDistance(directions);
if (polyline) {
// if polyline already exists, remove it from the map.
polyline.setMap(null)
}
polyline = new google.maps.Polyline({
path: google.maps.geometry.encoding.decodePath(directions.routes[0].overview_polyline),
map: map
})
if (polyline) {
console.log(polyline)
polyline.setMap(map)
}
}
});
displayRoute(
"Perth, WA",
"Sydney, NSW",
directionsService,
directionsRenderer
);
}
function displayRoute(origin, destination, service, display) {
service
.route({
origin: origin,
destination: destination,
waypoints: [{
location: "Adelaide, SA"
},
{
location: "Broken Hill, NSW"
},
],
travelMode: google.maps.TravelMode.DRIVING,
avoidTolls: true,
})
.then((result) => {
display.setDirections(result);
})
.catch((e) => {
alert("Could not display directions due to: " + e);
});
}
function computeTotalDistance(result) {
let total = 0;
const myroute = result.routes[0];
if (!myroute) {
return;
}
for (let i = 0; i < myroute.legs.length; i++) {
total += myroute.legs[i].distance.value;
}
total = total / 1000;
document.getElementById("total").innerHTML = total + " km";
}
window.initMap = initMap;
/*
* Always set the map height explicitly to define the size of the div element
* that contains the map.
*/
#map {
height: 90%;
}
/*
* Optional: Makes the sample page fill the window.
*/
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#floating-panel {
position: absolute;
top: 10px;
left: 25%;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
text-align: center;
font-family: "Roboto", "sans-serif";
line-height: 30px;
padding-left: 10px;
}
<!DOCTYPE html>
<html>
<head>
<title>Directions Service</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<div id="total"></div>
<div id="map"></div>
<!--
The `defer` attribute causes the callback to execute after the full HTML
document has been parsed. For non-blocking uses, avoiding race conditions,
and consistent behavior across browsers, consider loading using Promises
with https://www.npmjs.com/package/#googlemaps/js-api-loader.
-->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&v=weekly" defer></script>
</body>
</html>

Take coordinates from Google map URL for my JSON

I need to take coordinates from Google map URL for my JSON.
I am taking lat, lng, and zoom from URL.
But my mark doesn't appear on the same spot as on Google map mark.
For example here:
https://www.google.com/maps/place/ADRA+Laos/#17.8575854,102.1769446,8.81z/data=!4m5!3m4!1s0x3124662d079f33c5:0xcef5f2b499df9a6e!8m2!3d17.9613965!4d102.6307923
I take
lat: 17.8575854,
lng: 102.1769446,
zoom: 8.81
I guess I am missing something that I have to take.
My mark is not far from original, but not on the same spot.
Please, say me what I am missing
The coordinates after the # sign are the center of the map, not the coordinates of the place. The coordinates of the place/marker are at the end of the URL: !8m2!3d17.9613965!4d102.6307923
17.9613965,102.6307923
proof of concept fiddle
code snippet:
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 17.9613965, lng: 102.6307923},
zoom: 18
});
var marker = new google.maps.Marker({
position: map.getCenter(),
map: map
})
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap" async defer></script>

Webpage using html5 geolocation not as accurate as Google Map?

Using web browser Chrome on my laptop, I opened a local html web page to get the current location. The returned location (1.3238272, 103.8606336) is no where close to my actual location. Similarity, websites like [1] (1.3238272
103.8606336) [2] (1.32383, 103.86063) all return not accurate results.
However, using google map, it returned (1.287264, 103.831497) a much accurate location. Do google map use a different approach/technology to obtain a location?
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var g_lat = 0;
var g_lng = 0;
var map, infoWindow;
function initMap() {
navigator.geolocation.getCurrentPosition(updatePosition);
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: g_lat, lng: g_lng},
zoom: 8
});
infoWindow = new google.maps.InfoWindow;
}
function updatePosition(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
infoWindow.open(map);
map.setCenter(pos);
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?callback=initMap"
async defer></script>
</body>
</html>
The mistake is using Google Map when user logged in, this will produce a better location result. Without logging in, resulting location is the same as geolocation.

How to directly identify the co ordinates of a city in google maps?

I am trying to achieve the following
home page: visitor will search for a city or location from the search field. The zoom level as per google documentation is below.
1: World
5: Landmass/continent
10: City
15: Streets
20: Buildings
On Search Page: I want to list all the properties which is there in the locality searched e.g. California so i want to show all the properties on map with the Zoom level 10 .. but the issue is i am struggling to find the co ordinates of the city.. do i have to add all the cities co ordinates in the database? see below code.. how can i make center: {lat: 19.1760, lng: 72.7954} dynamic so it changes accordingly.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBkyMvhWRirAMPvBnjgzXEH6DIkjwXwW_A&callback=initMap">
</script>
</head>
<body>
<div id="map"></div>
<script>
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: {lat: 19.1760, lng: 72.7954}
});
setMarkers(map);
}
var beaches = [
['Aksa Beach', 19.1760, 72.7954, 1],
['Juhu Beach', 19.0969, 72.8266, 1]
];
function setMarkers(map) {
var shape = {
coords: [1, 1, 1, 20, 18, 20, 18, 1],
type: 'poly'
};
for (var i = 0; i < beaches.length; i++) {
var beach = beaches[i];
var marker = new google.maps.Marker({
position: {lat: beach[1], lng: beach[2]},
map: map,
shape: shape,
title: beach[0],
zIndex: beach[3]
});
marker.addListener('click', function() {
map.setZoom(20);
map.setCenter(marker.getPosition());
});
}
}
</script>
</body>
</html>
So in short how can i get the co ordinates of the city/continent/streen etc dynamically to render the map? as co ordinates are required attributes.
Use geocoder.
geocoder.geocode( { 'address': Address_text}, function(results, status) {
if (status== google.maps.GeocoderStatus.OK) {
loc_lat = results[0].geometry.location.lat();
loc_lon = results[0].geometry.location.lng()]
fmaddress = results[0].formatted_address;
alert('LAT: '+loc_lat+', LON: '+loc_lon+' ADDRESS: '+fmaddress);
} else {
if(Address_text != '' && Address_text!= null) {
alert('Couldnt get the X,Y');
}
}
});
Note, you wont be able to use location lat,lon, address, until the request is over, you have to wait for the request to get back, then use the data. Since JS works in asynchronous way. Dont forget to use '&libraries=places'. ->
https://maps.googleapis.com/maps/api/js?key=AIzaSyBkyMvhWRirAMPvBnjgzXEH6DIkjwXwW_A&libraries=places&callback=initMap

Google Maps API finding area by address

In my application I want to group items addresses by areas, my items already use Google maps API to choose address and has Lat/Long coordinates. I want to group them by areas automatically.
The example would be
If we have address https://www.google.com/maps/place/Erfurto+g.+1,+Vilnius+04220,+Lietuva/#54.6765968,25.2102183,15.5z/data=!4m2!3m1!1s0x46dd9398506f84bd:0x6cc62f1d26bc6613
It should automatically be assigned to area, marked here:
https://www.google.com/maps/place/Lazdynai,+Vilnius,+Lietuva/#54.6702541,25.1870655,14z/data=!4m2!3m1!1s0x46dd93a6cc53ba05:0x2600d18d4c454331
Areas should be also administered in my application.
As I understand I should store all MultiPolygon coordinates in my back-end, and then use some algorithm to find if the coordinates of address belong to that polygon? Am I right? Or I can fetch that somehow using Google Map API?
I made some very rough polygons (sorry if I insult anybody from Vilnius :) ), but I think you'll get the idea.
the main method you're looking for is google.maps.geometry.poly.containsLocation()
So I think this gives you the components you need; the plinciles. But if there is something specific you want to happen, please tell me.
<!DOCTYPE html>
<html>
<head>
<style>
html, body, #map-canvas {
height: 400px;
margin: 0px;
padding: 0px
}
#my_div {
border: 1px solid grey;
}
</style>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<script>
// these are very rough estimations of the Elderships of Vilnius
// please use the correct boundaries
var polygonData = [
{name: 'Senamiestis', color: '#ff0000', points: [[54.68256489008578, 25.315074920654297],[54.67631238544733, 25.30803680419922],[54.670555259971174, 25.288639068603516],[54.6752205795425, 25.269927978515625],[54.68812186362444, 25.259113311767578],[54.69506701073871, 25.26529312133789],[54.68832031289468, 25.30099868774414]]},
{name: 'Rasos', color: '#00ff00', points: [[54.669066215366605, 25.305633544921875],[54.68554193480844, 25.329322814941406],[54.68335879002739, 25.362625122070312],[54.656754688760536, 25.345458984375],[54.610254981579146, 25.328292846679688],[54.60568162741719, 25.308380126953125],[54.65516583289068, 25.29705047607422]]},
{name: 'Antakalnis', color: '#0000ff', points: [[54.72699938009521, 25.30426025390625],[54.71589532099472, 25.34820556640625],[54.80780860259057, 25.500640869140625],[54.81967870427071, 25.335845947265625],[54.771385204918595, 25.300140380859375]]}
];
var polygons = [];
var map;
// random markers.
var markerData = [
[54.75478050308602,25.3638149499893],
[54.68324427673198,25.27517330646513],
[54.70583916710748,25.240154385566694],
[54.68453433466152,25.293562531471235],
[54.72900384013322,25.330534100532514],
[54.682078227560325,25.28394949436186],
[54.65034635955749,25.30793917179106]
];
var markers = [];
var mapOptions = {
zoom: 10,
center: new google.maps.LatLng(54.682611637187925,25.287838697433454), // Vilnius university
mapTypeId: google.maps.MapTypeId.ROADMAP
};
function initialize() {
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
// draw the markers
var markerLocations = toLatLng(markerData);
for(var i in markerLocations) {
markers.push( new google.maps.Marker({
position: markerLocations[i],
title: i, // I'll just set the index as title.
map: map
}) );
}
// draw the polygons
for(var j in polygonData) {
var points = toLatLng(polygonData[j].points);
polygons[j] = drawPolygon(points, polygonData[j].color, polygonData[j].name);
// let's see if markers are in this polygon
var content = '';
for(var i in markerLocations) {
if (google.maps.geometry.poly.containsLocation(markers[i].position, polygons[j])) {
// display
content += '<li>' + markers[i].title + '</li>';
// I guess what you really want to do, is put this data in an array, or so
}
}
document.getElementById('display-data').innerHTML += '<h3>' + polygonData[j].name + '</h3>' + '<ul>' + content + '</ul><hr/>';
}
}
// takes an array of coordinats, [ [], [], [] ] , and returns Google Maps LatLng objects
function toLatLng(point_arrays) {
var locations = [];
for(var i in point_arrays) {
locations.push( new google.maps.LatLng(point_arrays[i][0], point_arrays[i][1]));
}
return locations;
}
// draws a polygon
function drawPolygon(points, color, name) {
if(points.length < 3) {
return;
}
// #see https://developers.google.com/maps/documentation/javascript/examples/polygon-simple
polygon = new google.maps.Polygon({
paths: points,
strokeColor: color,
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: color,
fillOpacity: 0.35,
title: name,
map: map
});
return polygon;
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<style>
ul, li {
list-style: none;
}
li {
display: inline;
border: 1px solid grey;
padding: 5px;
margin: 5px;
}
</style>
</head>
<body>
<div id="map-canvas"></div>
<div id="display-data"></div>
</body>
</html>
What you could do, is update the markers table in the database; add a field 'eldership'.
You send the data you get from my script to the server, with Ajax, you update the table (= you fill in the id of the eldership in the eldership field of the marker), so you only have to do this once (and you need to update the new markers ...).