I am trying to create a Google Map where the user can plot the route he walked/ran/bicycled and see how long he ran. The GPolyline class with it’s getLeng
I have used Martin Zeitler method to work with Google Map V3 and its working fine.
function init() {
var mapOptions = {
zoom: 15,
center: new google.maps.LatLng(-6.208437004433984, 106.84543132781982),
suppressInfoWindows: true,
};
// Get all html elements for map
var mapElement = document.getElementById('map1');
// Create the Google Map using elements
map = new google.maps.Map(mapElement, mapOptions);
var nextMarkerAt = 0; // Counter for the marker checkpoints.
var nextPoint = null; // The point where to place the next marker.
while (true) {
var routePoints = [ new google.maps.LatLng(47.656, -122.360),
new google.maps.LatLng(47.656, -122.343),
new google.maps.LatLng(47.690, -122.310),
new google.maps.LatLng(47.690, -122.270)];
nextPoint = moveAlongPath(routePoints, nextMarkerAt);
if (nextPoint) {
//Adding marker from localhost
MarkerIcon = "http://192.168.1.1/star.png";
var marker = new google.maps.Marker
({position: nextPoint,
map: map,
icon: MarkerIcon
});
// Add +1000 meters for the next checkpoint.
nextMarkerAt +=1000;
}
else {
// moveAlongPath returned null, so there are no more check points.
break;
}
}
}
Number.prototype.toRad = function () {
return this * Math.PI / 180;
}
Number.prototype.toDeg = function () {
return this * 180 / Math.PI;
}
function moveAlongPath(point, distance, index) {
index = index || 0; // Set index to 0 by default.
var routePoints = [];
for (var i = 0; i < point.length; i++) {
routePoints.push(point[i]);
}
if (index < routePoints.length) {
// There is still at least one point further from this point.
// Construct a GPolyline to use the getLength() method.
var polyline = new google.maps.Polyline({
path: [routePoints[index], routePoints[index + 1]],
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});
// Get the distance from this point to the next point in the polyline.
var distanceToNextPoint = polyline.Distance();
if (distance <= distanceToNextPoint) {
// distanceToNextPoint is within this point and the next.
// Return the destination point with moveTowards().
return moveTowards(routePoints, distance,index);
}
else {
// The destination is further from the next point. Subtract
// distanceToNextPoint from distance and continue recursively.
return moveAlongPath(routePoints,
distance - distanceToNextPoint,
index + 1);
}
}
else {
// There are no further points. The distance exceeds the length
// of the full path. Return null.
return null;
}
}
function moveTowards(point, distance,index) {
var lat1 = point[index].lat.toRad();
var lon1 = point[index].lng.toRad();
var lat2 = point[index+1].lat.toRad();
var lon2 = point[index+1].lng.toRad();
var dLon = (point[index + 1].lng - point[index].lng).toRad();
// Find the bearing from this point to the next.
var brng = Math.atan2(Math.sin(dLon) * Math.cos(lat2),
Math.cos(lat1) * Math.sin(lat2) -
Math.sin(lat1) * Math.cos(lat2) *
Math.cos(dLon));
var angDist = distance / 6371000; // Earth's radius.
// Calculate the destination point, given the source and bearing.
lat2 = Math.asin(Math.sin(lat1) * Math.cos(angDist) +
Math.cos(lat1) * Math.sin(angDist) *
Math.cos(brng));
lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(angDist) *
Math.cos(lat1),
Math.cos(angDist) - Math.sin(lat1) *
Math.sin(lat2));
if (isNaN(lat2) || isNaN(lon2)) return null;
return new google.maps.LatLng(lat2.toDeg(), lon2.toDeg());
}
google.maps.Polyline.prototype.Distance = function () {
var dist = 0;
for (var i = 1; i < this.getPath().getLength(); i++) {
dist += this.getPath().getAt(i).distanceFrom(this.getPath().getAt(i - 1));
}
return dist;
}
google.maps.LatLng.prototype.distanceFrom = function (newLatLng) {
//var R = 6371; // km (change this constant to get miles)
var R = 6378100; // meters
var lat1 = this.lat();
var lon1 = this.lng();
var lat2 = newLatLng.lat();
var lon2 = newLatLng.lng();
var dLat = (lat2 - lat1) * Math.PI / 180;
var dLon = (lon2 - lon1) * Math.PI / 180;
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
}