Geolocation doesn't update my walked distance - javascript

Hi I'm creating an walk tracker webapp by usiing geolocation with javascript. Everything works fine except the part when I have to calculate the distance by using the old latlong with new latlong.
The Code:
function updateLocation(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
var accuracy = position.coords.accuracy;
var timestamp = position.timestamp;
document.getElementById("latitude").innerHTML = latitude;
document.getElementById("longitude").innerHTML = longitude;
document.getElementById("accuracy").innerHTML = accuracy.toFixed(2) + " meter";
document.getElementById("timestamp").innerHTML = new Date(timestamp).toLocaleString();
if (accuracy >= 500) {
updateStatus("Need more accurate values to calculate distance.");
return;
}
if ((lastLat != null) && (lastLong != null)) {
var currentDistance = distance(latitude, longitude, lastLat, lastLong);
document.getElementById("currDist").innerHTML =
"Current distance traveled: " + currentDistance.toFixed(2) + " km";
totalDistance += currentDistance;
document.getElementById("totalDist").innerHTML =
"Total distance traveled: " + currentDistance.toFixed(2) + " km";
}
lastLat = latitude;
lastLong = longitude;
updateStatus("Location successfully updated.");
}
Added the distance function*
Number.prototype.toRadians = function() {
return this * Math.PI / 180;
}
function distance(latitude1, longitude1, latitude2, longitude2) {
// R is the radius of the earth in kilometers
var R = 6371;
var deltaLatitude = (latitude2-latitude1).toRadians();
var deltaLongitude = (longitude2-longitude1).toRadians();
latitude1 = latitude1.toRadians(), latitude2 = latitude2.toRadians();
var a = Math.sin(deltaLatitude/2) *
Math.sin(deltaLatitude/2) +
Math.cos(latitude1) *
Math.cos(latitude2) *
Math.sin(deltaLongitude/2) *
Math.sin(deltaLongitude/2);
var c = 2 * Math.atan2(Math.sqrt(a),
Math.sqrt(1-a));
var d = R * c;
return d;
}
Hope someone can find what Im doing wrong.
Thank you
Update:
I found the problem why geolocation didn't update my distance.. it's because the variable lastlong and lastlat which I declared didn't gave me the previous location, it gave me the current location of latitude and longitude which I declared inside updateLocation and assign lastlat and last long with those variable.
My question is now how can I calculate the previous location with the
new location, can't find any solution for it.
New Update:
Found my solution for this problem. For calculating the previous
distance I store the coords in a array and get the last position to
calculate the distance with the current position.
Code:
var coords = []; var distance = 0.0;
function calculateDistance(fromPos, toPos) {
var radius = 6371;
var toRad = function(number) {
return number * Math.PI / 180;
};
var latDistance = toRad(toPos.latitude - fromPos.latitude);
var lonDistance = toRad(toPos.longitude - fromPos.longitude);
var a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) +
Math.cos(toRad(fromPos.latitude)) * Math.cos(toRad(toPos.latitude)) *
Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
return radius * (2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)));
}
var lastPos = coords[coords.length-1];
if(lastPos) {
distance += calculateDistance(lastPos, position.coords);
document.getElementById("currDist").innerHTML =
"Current distance traveled: " + distance.toFixed(2) + " km";
}
coords.push(position.coords);
One thing that I not understand is why my timestamp inside my array is undefined? Because the lat and long can I get easy without problem.

For a complete working journey logger example please see Google Drive or GitHub.
Pay attention to the filterLocation function in TravelManagerPolyfil.js as you might just be getting many zero distance readings and need to throttle watchPosition.
This code works: -
<!DOCTYPE html>
<html>
<body>
<p>Click the button to get your coordinates.</p>
<button onclick="getLocation()">Try It</button>
<p id="demo"></p>
<script>
var perthLat = 31.9505;
var perthLon = 115.8605;
var freoLat = 32.0569;
var freoLon = 115.7439;
const EARTH_RADIUS = 6378137;
var toRad =
function (num) {
return num * Math.PI / 180;
};
var calculateDistance =
function(lat1, lon1, lat2, lon2){
var dLat = toRad(lat2 - lat1);
var dLon = toRad(lon2 - lon1);
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(this.toRad(lat1)) *
Math.cos(toRad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
var distance = EARTH_RADIUS * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return distance;
}
var x = document.getElementById("demo");
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
x.innerHTML = "Distance = " +
calculateDistance(perthLat, perthLon,
freoLat, freoLon) / 1000;
}
</script>
</body>
</html>

Related

Addition of big decimal values in javascript for calculating distance on google map

I am a fresher in coding and working on web designing on googlemap. I have a problem in finding total distance covered by user because i am using a formula for finding distance and then adding this distance one by one.The distance is like 0.41384640620101654 so when i am adding number of values of this type it is giving 0 or error.
here is my code
getDistance();
var mn = 0.00;
function getDistance()
{
for (var i = 0; i < polyline_data.length-1; i++)
{
$lngfrom = polyline_data[i].lng;
$lngto = polyline_data[i+1].lng;
$latfrom = polyline_data[i].lat;
$latto = polyline_data[i+1].lat;
$theta = $lngfrom - $lngto;
var pi = Math.PI;
var x = $latfrom * (pi/180);
var y = $latto * (pi/180);
var z = $theta * (pi/180);
var dist = new Array();
var distance = Math.sin(x) * Math.sin(y)+ Math.cos(x) * Math.cos(y) * Math.cos(z);
distance = Math.acos(distance);
distance = distance*(180/pi);
var miles = distance * 60 * 1.8515;
distance = miles * 1.609344;
distance = parseFloat(distance);
//distance = Math.round(distance);
//dist = dist.push(distance);
//distance+=distance;
console.log(distance);
//console.log(all);
//console.log(distance);
}
//var all = new Array();
//for(j=0;j<polyline_data.length-1;j++)
//{
//all[j]=distance;
//}
//console.log(all);
}

Get nearest distance based on geolocation

i made a script that gets the geolocation of the user, calculates the distance between the position and items in the object using the Haversine formula, and console.log the distances. My question is how can i console.log only the nearest item ? hope someone can help :)
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
</head>
<body>
<p id="demo"></p>
<script>
var obj = [
{
name:"location1",
lat:60.413750,
long:5.322036
},
{
name:"location2",
lat:59.749054,
long:10.203781
},
{
name:"location3",
lat:59.286271,
long:11.109228
},
{
name: "location4",
lat:59.913869,
long:10.752245
}
];
var x = $("#demo");
var hblat ;
var hblong ;
var distance ;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showDistance);
} else {
x.html("Geolocation is not supported by this browser.");
}
function showDistance(position) {
hblat = position.coords.latitude;
hblong = position.coords.longitude;
$.each(obj, function(key, value){
distance = hbdistance(hblat, hblong, value.lat, value.long, 'K');
console.log(Math.round(distance*1000)/1000);
});
}
function hbdistance(lat1, lon1, lat2, lon2, unit) {
var radlat1 = Math.PI * lat1/180
var radlat2 = Math.PI * lat2/180
var radlon1 = Math.PI * lon1/180
var radlon2 = Math.PI * lon2/180
var theta = lon1-lon2
var radtheta = Math.PI * theta/180
var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
dist = Math.acos(dist)
dist = dist * 180/Math.PI
dist = dist * 60 * 1.1515
if (unit=="K") { dist = dist * 1.609344 }
if (unit=="N") { dist = dist * 0.8684 }
return dist
}
</script>
</body>
</html>
In showDistance() you have an each block where you calculate the distances and that looks right. You're even logging them to console too, so we're almost there.
Let's go with a simple solution here and build up an array of distances:
function showDistance(position) {
hblat = position.coords.latitude;
hblong = position.coords.longitude;
var distances = []; // Array to store distances
$.each(obj, function(key, value){
distance = hbdistance(hblat, hblong, value.lat, value.long, 'K');
distances.push(distance); // Add our distance to the array
});
var min = Math.min.apply(Math, distances); // Get minimum value
console.log(min); // Log minimum value
}
You can see another SO post which explains obtaining minimum values from arrays here: Obtain smallest value from array in Javascript?
Hope that helps!

How to combine device orientation with bearing to properly rotate an image?

I found this article which includes a great example. What I would like to do differently, however, is to add a bearing for the rotation to focus on.
I've managed to get my current position as follows:
var lat = null;
var lng = null;
var intId = null;
function showPosition(position) {
lat = position.coords.latitude.toFixed(7);
lng = position.coords.longitude.toFixed(7);
$('#status').html('Latitude: ' + lat + '<br>Longitude: ' + lng);
}
function showError(error) {}
var watchId = null;
if (navigator.geolocation) {
var optn = {
enableHighAccuracy : true,
timeout : Infinity,
maximumAge : 0
};
watchId = navigator.geolocation.watchPosition(showPosition, showError, optn);
intId = setInterval(function() {
if (lat !== null && lng !== null) {
clearInterval(intId);
}
}, 1000);
} else {
$('#status').html('Geolocation is not supported in your browser.');
}
Likewise, I can take my current position along with another fixed postion, and get the bearing with the following functions:
function getBearing(lat1, lng1, lat2, lng2) {
var dLon = toRad(lng2-lng1);
lat1 = toRad(lat1);
lat2 = toRad(lat2);
var y = Math.sin(dLon) * Math.cos(lat2);
var x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
var rad = Math.atan2(y, x);
var brng = toDeg(rad);
return (brng + 360) % 360;
}
function toRad(deg) {
return deg * Math.PI / 180;
}
function toDeg(rad) {
return rad * 180 / Math.PI;
}
Where I am struggling is how to bring the two together (device orientation & bearing)?
Combined with the code from the link above, here is a JSFiddle. I believe I have all the information I need (gamma, beta, alpha & bearing) but I don't know how to apply them together in style.transform so the image points at a specific location rather than north.
Can anyone help me please!?

select marker using google maps and leap motion

I have been trying to select a marker on google maps closest to the leap motion coordinate. I have tried converting the leap motion coordinate to google maps coordinate and find the closest marker on google maps to the leap motion device by doing marker.lat and marker.lng for the markers compared to the lat and longitude calculated. However, it isn't working instead it is returning the marker at the bottom of the screen or the top of the screen. Here is my current javaScript code.
var results = document.getElementById('resultsTable');
console.log("Key Tap Gesture at: " + keyTapGesture.position[0]);
//google.maps.event.dispatchEvent(ktEvent);
var closestMarkerDistance = 10000000000000000000000000; //big number to start, so any calculation will override this value
var closestMarker = null;
var distance = 10000000000000000000000000;
console.log("marker distances to keytap are: " + results.length);
var hand = frame.hands[0];
var stabilized = hand.stabilizedPalmPosition;
for (var i = 0; i < markers.length; i++) {
var markerPos = 0;
var keyTapX = 0;
var keyTapY = 0;
var newLatLngPt = 0;
var keyLng = 0;
var keyLat = 0;
markerPos = markers[i].position;
keyTapX = stabilized[0];
keyTapY = stabilized[1];
newLatLngPt = convertToLatLng(keyTapX, keyTapY);
var scaling = 4.0 / Math.pow(2, map.getZoom() - 1);
keyLng = keyTapX * scaling;
keyLat = keyTapY * scaling;
//var keyTapCoord = new google.maps.LatLng(keyLat, keyLng);
distance = getDistanceFromLatLonInKm(markerPos.lat(), markerPos.lng(), newLatLngPt.lat(), newLatLngPt.lng());
if (distance < closestMarkerDistance) {
closestMarkerDistance = distance;
closestMarker = markers[i];
}
console.log(" \n" + distance + markers[i].getTitle());
}
if(closestMarker != null) {
console.log("\nclosest marker is : " + closestMarker.name + " title: " + closestMarker.getTitle() + " at pos: " + closestMarker.getPosition());
infowindow.setContent(closestMarker.getTitle());
infowindow.open(map,closestMarker);
console.log("\n ALSO: --> " + stabilized[0] + " ::::::" + stabilized[1]);
console.log("\n ANNNNNND: --> " + keyLng + " ::::::" + keyLat + "and then real la/lo = " + markerPos.lng() + " ____ " + markerPos.lat());
//document.getElementById(choices).innerHTML = place.name + "<br/>" + place.vicinity;
}
else {
console.log("\nclosest marker Does Not Exist");
}
function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1); // deg2rad below
var dLon = deg2rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c; // Distance in km
return d;
}
function convertToLatLng(x, y) {
// retrieve the lat lng for the far extremities of the (visible) map
var latLngBounds = map.getBounds();
var neBound = latLngBounds.getNorthEast();
var swBound = latLngBounds.getSouthWest();
// convert the bounds in pixels
var neBoundInPx = map.getProjection().fromLatLngToPoint(neBound);
var swBoundInPx = map.getProjection().fromLatLngToPoint(swBound);
// compute the percent of x and y coordinates related to the div containing the map; in my case the screen
var procX = x / window.innerWidth;
var procY = y / window.innerHeight;
// compute new coordinates in pixels for lat and lng;
// for lng : subtract from the right edge of the container the left edge,
// multiply it by the percentage where the x coordinate was on the screen
// related to the container in which the map is placed and add back the left boundary
// you should now have the Lng coordinate in pixels
// do the same for lat
var newLngInPx = (neBoundInPx.x - swBoundInPx.x) * procX + swBoundInPx.x;
var newLatInPx = (swBoundInPx.y - neBoundInPx.y) * procY + neBoundInPx.y;
// convert from google point in lat lng and have fun :)
var newLatLng = map.getProjection().fromPointToLatLng(new google.maps.Point(newLngInPx, newLatInPx));
return newLatLng;
}
function deg2rad(deg) {
return deg * (Math.PI / 180)
}
The Leap Motion coordinate system has nothing to do with your browser window. The X axis extends from approx. -300mm to +300mm. The Y axis extends from about 0 to +600mm -- it also is positive upward, while your browser Y-axis is more positive downward. If I read your code correctly, you are trying to use the Leap Motion coordinates as if they were pixel coordinates. They aren't.
You need to map the Leap Motion coordinates to something that makes sense for your application. This article in the documentation may help: https://developer.leapmotion.com/documentation/javascript/devguide/Leap_Coordinate_Mapping.html
In particular, have a look at the InteractionBox class, with which you can normalize the Leap Motion coordinates to the range [0..1]. It is generally easier to map the normalized coordinates to your application coordinate system.

Calculate distance between 2 co-ordinates [duplicate]

How do you calculate the distance between two markers in Google maps V3? (Similar to the distanceFrom function inV2.)
Thanks..
If you want to calculate it yourself, then you can use the Haversine formula:
var rad = function(x) {
return x * Math.PI / 180;
};
var getDistance = function(p1, p2) {
var R = 6378137; // Earth’s mean radius in meter
var dLat = rad(p2.lat() - p1.lat());
var dLong = rad(p2.lng() - p1.lng());
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(rad(p1.lat())) * Math.cos(rad(p2.lat())) *
Math.sin(dLong / 2) * Math.sin(dLong / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d; // returns the distance in meter
};
There actually seems to be a method in GMap3. It's a static method of the google.maps.geometry.spherical namespace.
It takes as arguments two LatLng objects and will utilize a default Earth radius of 6378137 meters, although the default radius can be overridden with a custom value if necessary.
Make sure you include:
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&v=3&libraries=geometry"></script>
in your head section.
The call will be:
google.maps.geometry.spherical.computeDistanceBetween (latLngA, latLngB);
Example using GPS latitude/longitude of 2 points.
var latitude1 = 39.46;
var longitude1 = -0.36;
var latitude2 = 40.40;
var longitude2 = -3.68;
var distance = google.maps.geometry.spherical.computeDistanceBetween(new google.maps.LatLng(latitude1, longitude1), new google.maps.LatLng(latitude2, longitude2));
Just add this to the beginning of your JavaScript code:
google.maps.LatLng.prototype.distanceFrom = function(latlng) {
var lat = [this.lat(), latlng.lat()]
var lng = [this.lng(), latlng.lng()]
var R = 6378137;
var dLat = (lat[1]-lat[0]) * Math.PI / 180;
var dLng = (lng[1]-lng[0]) * Math.PI / 180;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat[0] * Math.PI / 180 ) * Math.cos(lat[1] * Math.PI / 180 ) *
Math.sin(dLng/2) * Math.sin(dLng/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return Math.round(d);
}
and then use the function like this:
var loc1 = new GLatLng(52.5773139, 1.3712427);
var loc2 = new GLatLng(52.4788314, 1.7577444);
var dist = loc2.distanceFrom(loc1);
alert(dist/1000);
//p1 and p2 are google.maps.LatLng(x,y) objects
function calcDistance(p1, p2) {
var d = (google.maps.geometry.spherical.computeDistanceBetween(p1, p2) / 1000).toFixed(2);
console.log(d);
}
Here is the c# implementation of the this forumula
public class DistanceAlgorithm
{
const double PIx = 3.141592653589793;
const double RADIO = 6378.16;
/// <summary>
/// This class cannot be instantiated.
/// </summary>
private DistanceAlgorithm() { }
/// <summary>
/// Convert degrees to Radians
/// </summary>
/// <param name="x">Degrees</param>
/// <returns>The equivalent in radians</returns>
public static double Radians(double x)
{
return x * PIx / 180;
}
/// <summary>
/// Calculate the distance between two places.
/// </summary>
/// <param name="lon1"></param>
/// <param name="lat1"></param>
/// <param name="lon2"></param>
/// <param name="lat2"></param>
/// <returns></returns>
public static double DistanceBetweenPlaces(
double lon1,
double lat1,
double lon2,
double lat2)
{
double dlon = Radians(lon2 - lon1);
double dlat = Radians(lat2 - lat1);
double a = (Math.Sin(dlat / 2) * Math.Sin(dlat / 2)) + Math.Cos(Radians(lat1)) * Math.Cos(Radians(lat2)) * (Math.Sin(dlon / 2) * Math.Sin(dlon / 2));
double angle = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
return (angle * RADIO) * 0.62137;//distance in miles
}
}
With google you can do it using the spherical api, google.maps.geometry.spherical.computeDistanceBetween (latLngA, latLngB);.
However, if the precision of a spherical projection or a haversine solution is not precise enough for you (e.g. if you're close to the pole or computing longer distances), you should use a different library.
Most information on the subject I found on Wikipedia here.
A trick to see if the precision of any given algorithm is adequate is to fill in the maximum and minimum radius of the earth and see if the difference might cause problems for your use case. Many more details can be found in this article
In the end the google api or haversine will serve most purposes without problems.
Using PHP, you can calculate the distance using this simple function :
// to calculate distance between two lat & lon
function calculate_distance($lat1, $lon1, $lat2, $lon2, $unit='N')
{
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$miles = $dist * 60 * 1.1515;
$unit = strtoupper($unit);
if ($unit == "K") {
return ($miles * 1.609344);
} else if ($unit == "N") {
return ($miles * 0.8684);
} else {
return $miles;
}
}
// function ends here
OFFLINE SOLUTION - Haversine Algorithm
In Javascript
var _eQuatorialEarthRadius = 6378.1370;
var _d2r = (Math.PI / 180.0);
function HaversineInM(lat1, long1, lat2, long2)
{
return (1000.0 * HaversineInKM(lat1, long1, lat2, long2));
}
function HaversineInKM(lat1, long1, lat2, long2)
{
var dlong = (long2 - long1) * _d2r;
var dlat = (lat2 - lat1) * _d2r;
var a = Math.pow(Math.sin(dlat / 2.0), 2.0) + Math.cos(lat1 * _d2r) * Math.cos(lat2 * _d2r) * Math.pow(Math.sin(dlong / 2.0), 2.0);
var c = 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1.0 - a));
var d = _eQuatorialEarthRadius * c;
return d;
}
var meLat = -33.922982;
var meLong = 151.083853;
var result1 = HaversineInKM(meLat, meLong, -32.236457779983745, 148.69094705162837);
var result2 = HaversineInKM(meLat, meLong, -33.609020205923713, 150.77061469270831);
C#
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
var meLat = -33.922982;
double meLong = 151.083853;
var result1 = HaversineInM(meLat, meLong, -32.236457779983745, 148.69094705162837);
var result2 = HaversineInM(meLat, meLong, -33.609020205923713, 150.77061469270831);
Console.WriteLine(result1);
Console.WriteLine(result2);
}
static double _eQuatorialEarthRadius = 6378.1370D;
static double _d2r = (Math.PI / 180D);
private static int HaversineInM(double lat1, double long1, double lat2, double long2)
{
return (int)(1000D * HaversineInKM(lat1, long1, lat2, long2));
}
private static double HaversineInKM(double lat1, double long1, double lat2, double long2)
{
double dlong = (long2 - long1) * _d2r;
double dlat = (lat2 - lat1) * _d2r;
double a = Math.Pow(Math.Sin(dlat / 2D), 2D) + Math.Cos(lat1 * _d2r) * Math.Cos(lat2 * _d2r) * Math.Pow(Math.Sin(dlong / 2D), 2D);
double c = 2D * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1D - a));
double d = _eQuatorialEarthRadius * c;
return d;
}
}
Reference:
https://en.wikipedia.org/wiki/Great-circle_distance
Had to do it... The action script way
//just make sure you pass a number to the function because it would accept you mother in law...
public var rad = function(x:*) {return x*Math.PI/180;}
protected function distHaversine(p1:Object, p2:Object):Number {
var R:int = 6371; // earth's mean radius in km
var dLat:Number = rad(p2.lat() - p1.lat());
var dLong:Number = rad(p2.lng() - p1.lng());
var a:Number = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(rad(p1.lat())) * Math.cos(rad(p2.lat())) * Math.sin(dLong/2) * Math.sin(dLong/2);
var c:Number = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d:Number = R * c;
return d;
}
In my case it was best to calculate this in SQL Server, since i wanted to take current location and then search for all zip codes within a certain distance from current location. I also had a DB which contained a list of zip codes and their lat longs. Cheers
--will return the radius for a given number
create function getRad(#variable float)--function to return rad
returns float
as
begin
declare #retval float
select #retval=(#variable * PI()/180)
--print #retval
return #retval
end
go
--calc distance
--drop function dbo.getDistance
create function getDistance(#cLat float,#cLong float, #tLat float, #tLong float)
returns float
as
begin
declare #emr float
declare #dLat float
declare #dLong float
declare #a float
declare #distance float
declare #c float
set #emr = 6371--earth mean
set #dLat = dbo.getRad(#tLat - #cLat);
set #dLong = dbo.getRad(#tLong - #cLong);
set #a = sin(#dLat/2)*sin(#dLat/2)+cos(dbo.getRad(#cLat))*cos(dbo.getRad(#tLat))*sin(#dLong/2)*sin(#dLong/2);
set #c = 2*atn2(sqrt(#a),sqrt(1-#a))
set #distance = #emr*#c;
set #distance = #distance * 0.621371 -- i needed it in miles
--print #distance
return #distance;
end
go
--get all zipcodes within 2 miles, the hardcoded #'s would be passed in by C#
select *
from cityzips a where dbo.getDistance(29.76,-95.38,a.lat,a.long) <3
order by zipcode
//JAVA
public Double getDistanceBetweenTwoPoints(Double latitude1, Double longitude1, Double latitude2, Double longitude2) {
final int RADIUS_EARTH = 6371;
double dLat = getRad(latitude2 - latitude1);
double dLong = getRad(longitude2 - longitude1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(getRad(latitude1)) * Math.cos(getRad(latitude2)) * Math.sin(dLong / 2) * Math.sin(dLong / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return (RADIUS_EARTH * c) * 1000;
}
private Double getRad(Double x) {
return x * Math.PI / 180;
}
/**
* Calculates the haversine distance between point A, and B.
* #param {number[]} latlngA [lat, lng] point A
* #param {number[]} latlngB [lat, lng] point B
* #param {boolean} isMiles If we are using miles, else km.
*/
function haversineDistance(latlngA, latlngB, isMiles) {
const squared = x => x * x;
const toRad = x => (x * Math.PI) / 180;
const R = 6371; // Earth’s mean radius in km
const dLat = toRad(latlngB[0] - latlngA[0]);
const dLon = toRad(latlngB[1] - latlngA[1]);
const dLatSin = squared(Math.sin(dLat / 2));
const dLonSin = squared(Math.sin(dLon / 2));
const a = dLatSin +
(Math.cos(toRad(latlngA[0])) * Math.cos(toRad(latlngB[0])) * dLonSin);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
let distance = R * c;
if (isMiles) distance /= 1.609344;
return distance;
}
I found a version online which is 80% right but plugged in the wrong parameter and is inconsistent in using the inputs, this version fixed that completely
It's Quite easy using Google Distance Matrix service
First step is to activate Distance Matrix service from google API console.
it returns distances between a set of locations.
And apply this simple function
function initMap() {
var bounds = new google.maps.LatLngBounds;
var markersArray = [];
var origin1 = {lat:23.0203, lng: 72.5562};
//var origin2 = 'Ahmedabad, India';
var destinationA = {lat:23.0436503, lng: 72.55008939999993};
//var destinationB = {lat: 23.2156, lng: 72.6369};
var destinationIcon = 'https://chart.googleapis.com/chart?' +
'chst=d_map_pin_letter&chld=D|FF0000|000000';
var originIcon = 'https://chart.googleapis.com/chart?' +
'chst=d_map_pin_letter&chld=O|FFFF00|000000';
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 55.53, lng: 9.4},
zoom: 10
});
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) {
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);
}
};
};
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));
//outputDiv.innerHTML += originList[i] + ' to ' + destinationList[j] + ': ' + results[j].distance.text + ' in ' + results[j].duration.text + '<br>';
outputDiv.innerHTML += results[j].distance.text + '<br>';
}
}
}
});
}
Where origin1 is your location and destinationA is destindation location.you can add above two or more data.
Rad Full Documentation with an example
To calculate distance on Google Maps, you can use Directions API. That will be one of the easiest way to do it. To get data from Google Server, you can use Retrofit or Volley. Both has their own advantage. Take a look at following code where I have used retrofit to implement it:
private void build_retrofit_and_get_response(String type) {
String url = "https://maps.googleapis.com/maps/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitMaps service = retrofit.create(RetrofitMaps.class);
Call<Example> call = service.getDistanceDuration("metric", origin.latitude + "," + origin.longitude,dest.latitude + "," + dest.longitude, type);
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(Response<Example> response, Retrofit retrofit) {
try {
//Remove previous line from map
if (line != null) {
line.remove();
}
// This loop will go through all the results and add marker on each location.
for (int i = 0; i < response.body().getRoutes().size(); i++) {
String distance = response.body().getRoutes().get(i).getLegs().get(i).getDistance().getText();
String time = response.body().getRoutes().get(i).getLegs().get(i).getDuration().getText();
ShowDistanceDuration.setText("Distance:" + distance + ", Duration:" + time);
String encodedString = response.body().getRoutes().get(0).getOverviewPolyline().getPoints();
List<LatLng> list = decodePoly(encodedString);
line = mMap.addPolyline(new PolylineOptions()
.addAll(list)
.width(20)
.color(Color.RED)
.geodesic(true)
);
}
} catch (Exception e) {
Log.d("onResponse", "There is an error");
e.printStackTrace();
}
}
#Override
public void onFailure(Throwable t) {
Log.d("onFailure", t.toString());
}
});
}
Above is the code of function build_retrofit_and_get_response for calculating distance. Below is corresponding Retrofit Interface:
package com.androidtutorialpoint.googlemapsdistancecalculator;
import com.androidtutorialpoint.googlemapsdistancecalculator.POJO.Example;
import retrofit.Call;
import retrofit.http.GET;
import retrofit.http.Query;
public interface RetrofitMaps {
/*
* Retrofit get annotation with our URL
* And our method that will return us details of student.
*/
#GET("api/directions/json?key=AIzaSyC22GfkHu9FdgT9SwdCWMwKX1a4aohGifM")
Call<Example> getDistanceDuration(#Query("units") String units, #Query("origin") String origin, #Query("destination") String destination, #Query("mode") String mode);
}
I hope this explains your query. All the best :)
Source: Google Maps Distance Calculator
First, are you referring to distance as in length of the entire path or you want to know only the displacement (straight line distance)? I see no one is pointing the difference between distance and displacement here. For distance calculate each route point given by JSON/XML data, as for displacement there is a built-in solution using Spherical class
//calculates distance between two points in km's
function calcDistance(p1, p2) {
return (google.maps.geometry.spherical.computeDistanceBetween(p1, p2) / 1000).toFixed(2);
}
In PHP, with Google Map Distance Matrix API:
//Get the Driving(Mode) distance between two Geo-location points(Latitude, Longitude) pair.
function get_distance($lat1, $lat2, $long1, $long2)
{
$url = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=".$lat1.",".$long1."&destinations=".$lat2.",".$long2."&mode=driving"."&units=imperial";
//You can request distance data for different travel modes, request distance data in different units such as kilometers or miles, and estimate travel time in traffic.
try{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_PROXYPORT, 3128);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
curl_close($ch);
$response_a = json_decode($response, true);
//Invalid request OR Empty response
if(isset($response_a['error_message']) || empty($response_a['rows']))
throw new Exception($response_a['error_message']);
} catch(Exception $e){
//Handle error here.
return [];
}
//The unit parameter in the request URL only affects the text displayed within distance fields. The distance fields in response also contain values that are always expressed in meters.
$dist = $response_a['rows'][0]['elements'][0]['distance']['text'];
$time = $response_a['rows'][0]['elements'][0]['duration']['text'];
return ['distance' => $dist, 'time' => $time];
}
Reference: Distance Matrix API request and response

Categories