I am looking to add a feature to a order entry system to show the distance in KM between the order location and assigned delivery van in real time.
The vans have a GPS Tracking system from High Point GPS, comes with an API to query driver location, returns in format of LAT/LONG, and location address if available.
Once I get the location I can use a web service to calculate the distance between the 2 locations, does anyone know what is the best way to get the distance between 2 locations using LAT/LONG for vehicle and address lookup for the delivery location?
You can use Google Maps to get Lat/Long of address
See answer by Thomas Clayson
How can I get latitude, longitude of a location programmatically or using a api
Then you can calculate the distance between the two sets of coordinates by using the Law of Cosines or the Haversine formula
See Law of Cosines
It depends on the other services you are already using. For example, we already use google maps to display the route, so we use their geocoding service to translate from an address to coordinates, as well as their distance service to compute distances.
Create two DbGeography instance for source and destination point (http://msdn.microsoft.com/en-us/library/system.data.spatial.dbgeography.distance(v=vs.110).aspx). Then use distance method of DbGeography for find the distance between two points.
For distance unit refer this post : System.Data.Spatial DbGeography.Distance units?
The simple answer you may find , is a simple formula :
Calculate distance between two points in google maps V3
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
};
using google maps api will be the best solution:
https://developers.google.com/maps/documentation/distancematrix/
I've done this but in Java, probably you can port it to c# with no much effort.
This is very accurate for distances shorter than 2000 kilometers, then it can vary a little bit from the real distance. This is due to the earth curvature. But for small distances you can assume it is plain with none or very small impact in the result.
Here is a link I found useful.
And another link, an implementation of Haversine in C#.
Hope it helps.
Best regards, Federico.
public String execute(String plat1, String plon1, String plat2, String plon2) {
String distance;
double lat1, lon1, lat2, lon2;
try{
lat1 = Double.parseDouble(plat1);
lon1 = Double.parseDouble(plon1);
lat2 = Double.parseDouble(plat2);
lon2 = Double.parseDouble(plon2);
} catch (Exception e){
lat1 = 0.0d;
lon1 = 0.0d;
lat2 = 0.0d;
lon2 = 0.0d;
}
//theta and distance
double theta = lon1 - lon2;
double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
//distance
dist = Math.acos(dist);
dist = rad2deg(dist);
dist = dist * 60 * 1.1515;
dist = dist * 1.609344;
//convert to meters
dist = dist * 1000;
//output in meters
distance = Double.toString(dist);
return distance;
}
private double deg2rad(double deg) {
return (deg * Math.PI / 180.0);
}
private double rad2deg(double rad) {
return (rad * 180.0 / Math.PI);
}
A little explanation:
(plat1, plon1) is lat and lng of point 1 or origin
(plat2, plon2) is lat and lng of point 2 or destination
the method "execute" is the one you call, it returns a string containing the distance in meters (conversion to other units can be done easily)
two assisting functions are declared as "deg2rad" and "rad2deg".
Related
I've been searching for a while but haven't found exactly what I'm looking for.
I'm working on an app that will go in a race car. It will give the driver the ability to press a button to mark a Start/Finish line. It will also have a button to allow a driver to set segment times.
Keep in mind a track can be an oval which I'm working on first. It could be a road course or it could be an auto cross where the start and finish line aren't the exact same location. They could be with 50 feet of each other or so but the car never crosses where it starts.
I have my gps data coming in and I convert the NMea messages to my classes and I store Lat, Lon, Speed, Course etc. In my research I've ran across this which is interesting. The GPS will be mounted outside the roof for better signal. It generates 10 hits per second. (Garmin Glo)
http://www.drdobbs.com/windows/gps-programming-net/184405690?pgno=1
It's old but it talks about UTM and the Cartesian coordinate system. So using the DecDeg2UTM, I convert Lat & Lon to X & coordinates as well.
I've also been trying to use the Intersect formula I found Here I took the intersect and tried to convert it to C# which I'll post at the end. However, feeding coordinates of an oval track, it doesn't seem to be working. Also, I'm not sure exactly what it's supposed to be doing. But the coordinates it returns when it does somethign like -35.xxx & 98.xxxx which out in an ocean somewhere 1000's of miles from where the track is.
I looking for answers to the following.
I assume I need to take the location recorded when a button is pressed for Start/Finish or Segment and calculate a line perpendicular to the direction the car in able to be able to do some sort of Line Intersection calculation. The Cartesian coordinates seems to calculate the bearing fairly well. But the question here is how do you get the "left and right coordinates". Also, keep in mind, an oval track may be 60 feet wide. But as mentioned an auto cross track may only be 20 ft wide and part of the track may be with 50 ft. Note I'm fine with indicating to set the points, the car needs to be going slow or stopped at the points to get an accurate coordinate. Some tracks they will have to be set while walking the track.
Based on this, should I be trying to use decimal lat lon or would utilizing the Cartesian coordinate system based on UTM be a more accurate method for what I'm trying to do?
Either one is there a .Net library or C based library with source code that has methods for making these calculations?
How can this be accurately handled. (Not that great with Math, links to code samples would help tremendously.)
Next, after I have the lines or whatever is needed for start/finish and segments, as I get GPS sign from the car racing, I need to figure out the most accurate way to tell when a car has crossed those segments. again if I'm lucky I'll get 10 hits per second but it will probably be lower. Then the vehicle speeds could vary significantly depending on the type of track and vehicle. So the GPS hit could be many feet "left or right" of a segment. Also, it could be many feet before or after a segment.
Again, if there is a GIS library out there I can feed coordinates and all this is calculated, that's would work as well as long as it's performant. If not again I'm trying to decide if it's best to break down coordinates to X Y or some geometry formulas for coordinates in decimal format. Mods, I assume there is hard data to support an answer of either way and this isn't responses aren't fully subjective to opinions.
Here is the C# code I came up with from the Script page above. I'm starting to feel UTM and the Cartesian Coordinate system would be better for accuracy and performance. But again I'm open to evidence to the contrary if it exists.
Thanks
P.S. Note GeoCoordinate is from the .Net System.Device.Location assemble. GpsData is just a class I use to convert NMEA messages into Lat, Lon, Course, NumSats, DateTime etc.
The degree Radian methods are extensions as as follows.
public static double DegreeToRadians(this double angle)
{
return Math.PI * angle / 180.0;
}
public static double RadianToDegree(this double angle)
{
return angle * (180.0 / Math.PI);
}
}
public static GeoCoordinate CalculateIntersection(GpsData p1, double brng1, GpsData p2, double brng2)
{
// see http://williams.best.vwh.net/avform.htm#Intersection
// Not sure I need to use Cosine
double _p1LatRadians = p1.Latitude.DegreeToRadians();
double _p1LonToRadians = p1.Longitude.DegreeToRadians();
double _p2LatToRadians = p2.Latitude.DegreeToRadians();
double _p2LonToRadians = p2.Longitude.DegreeToRadians();
double _brng1ToRadians = brng1.DegreeToRadians();
double _brng2ToRadians = brng2.DegreeToRadians();
double _deltaLat = _p2LatToRadians - _p1LatRadians;
double _deltaLon = _p2LonToRadians - _p1LonToRadians;
var _var1 = 2 * Math.Asin(Math.Sqrt(Math.Sin(_deltaLat / 2) * Math.Sin(_deltaLat / 2)
+ Math.Cos(_p1LatRadians) * Math.Cos(_p2LatToRadians) * Math.Sin(_deltaLon / 2) * Math.Sin(_deltaLon / 2)));
if (_var1 == 0) return null;
// initial/final bearings between points
var _finalBrng = Math.Acos((Math.Sin(_p2LatToRadians) - Math.Sin(_p1LatRadians) * Math.Cos(_var1)) / (Math.Sin(_var1) * Math.Cos(_p1LatRadians)));
//if (isNaN(θa)) θa = 0; // protect against rounding
var θb = Math.Acos((Math.Sin(_p1LatRadians) - Math.Sin(_p2LatToRadians) * Math.Cos(_var1)) / (Math.Sin(_var1) * Math.Cos(_p2LatToRadians)));
var θ12 = Math.Sin(_p2LonToRadians - _p1LonToRadians) > 0 ? _finalBrng : 2 * Math.PI - _finalBrng;
var θ21 = Math.Sin(_p2LonToRadians - _p1LonToRadians) > 0 ? 2 * Math.PI - θb : θb;
var α1 = (_brng1ToRadians - θ12 + Math.PI) % (2 * Math.PI) - Math.PI; // angle 2-1-3
var α2 = (θ21 - _brng2ToRadians + Math.PI) % (2 * Math.PI) - Math.PI; // angle 1-2-3
if (Math.Sin(α1) == 0 && Math.Sin(α2) == 0) return null; // infinite intersections
if (Math.Sin(α1) * Math.Sin(α2) < 0) return null; // ambiguous intersection
α1 = Math.Abs(α1);
α2 = Math.Abs(α2);
// ... Ed Williams takes abs of α1/α2, but seems to break calculation?
var α3 = Math.Acos(-Math.Cos(α1) * Math.Cos(α2) + Math.Sin(α1) * Math.Sin(α2) * Math.Cos(_var1));
var δ13 = Math.Atan2(Math.Sin(_var1) * Math.Sin(α1) * Math.Sin(α2), Math.Cos(α2) + Math.Cos(α1) * Math.Cos(α3));
var _finalLatRadians = Math.Asin(Math.Sin(_p1LatRadians) * Math.Cos(δ13) + Math.Cos(_p1LatRadians) * Math.Sin(δ13) * Math.Cos(_brng1ToRadians));
var _lonBearing = Math.Atan2(Math.Sin(_brng1ToRadians) * Math.Sin(δ13) * Math.Cos(_p1LatRadians), Math.Cos(δ13) - Math.Sin(_p1LatRadians) * Math.Sin(_finalLatRadians));
var _finalLon = _p1LonToRadians + _lonBearing;
var _returnLat = _finalLatRadians.RadianToDegree();
var _latToDegree = _finalLon.RadianToDegree();
var _returnLon = ( _latToDegree + 540) % 360 - 180;
return new GeoCoordinate(_returnLat, _returnLon);
//return new LatLon(φ3.toDegrees(), (λ3.toDegrees() + 540) % 360 - 180); // normalise to −180..+180°
}
I'm trying to calculate distance of cannon shot using velocity and angle. I'm testing results using utility tests. The formula for range should be someting like v^2 * sin2a aka velocity squared * sin2alpha . As far as i know, sin2a is supposed to be 2*sina*cosa, but i may be wrong.
Anyway, whatever i do, i get wrong results, because it doesn't seem to be calculating sin.
Here's the code
Cannon.cs
public int CalculateDistance(int angle, int velocity)
{
int distance = 0;
double radian_angle = (Math.PI / 180) * angle;
distance_of_shot = (Math.Pow(velocity, 2)) * (2 * Math.Sin(radian_angle) * Math.Cos(radian_angle));
distance = (int)distance_of_shot;
return distance;
}
CannonAttackTest.cs
[TestMethod]
public void Calculations()
{
Canon new_canon = new Canon();
var data = new_canon.CalculateDistance(45, 450);
Assert.AreEqual(20682, data);
}
The results is suppose to be 20682, but i get 202500, which is exactly a number of squared 450...whichs points to sin not being calculated.
Any help is appreciated!
Thank you!
Check your units, you need to divide by the value of "g" because velocity is m/s and your "distance of shot" is in m^2/s^2.
distance_of_shot = (Math.Pow(velocity, 2)) * (2 * Math.Sin(radian_angle) * Math.Cos(radian_angle))/9.81;
You have a mistake sin 0.70710678118654746 and cos 0.70710678118654757 but after
(2 * Math.Sin(radian_angle) * Math.Cos(radian_angle)) result coming 1
Maths is not my strong suit and I think I have something mixed up here but I cannot figure out what.
I'm just trying to populate 2 new coordinates given a number of variables and constants.
if I make Origin coordinate 5,5 and Destination coordinate 10,5, I can work out that distance =5 and that the bearing from Origin to Destination is 90 using these two functions:
private static double GetDistance(PointF point1, PointF point2)
{
double a = (double)(point2.X - point1.X);
double b = (double)(point2.Y - point1.Y);
return Math.Sqrt(a * a + b * b);
}
public static double GetBearing(PointF coord1, PointF coord2)
{
double result = 0.0;
result = Math.Atan2(coord2.X - coord1.X, coord2.Y - coord1.Y) * (180 / Math.PI); //- Math.Atan2(coord4.y - coord3.y, coord4.x - coord3.x))
if (result < 0)
{
result = result + 360;
}
return result;
}
What I want to be able to do given an offset Distance of xd=1 and an offset bearing of 180(ie directly opposite direction to the destination) is plot the location 4,5. I'd also like to be able to feed a different offset bearing in of say 90 and plot 5,6.
Here's what I've tried but I get completely nonsensical values.
public static PointF CalculateCoordinate(double Angle, double Distance)
{
PointF coord = new PointF(Convert.ToSingle(Distance * Math.Cos(Angle)), Convert.ToSingle(Distance * Math.Sin(Angle)));
return coord;
}
and CalculateCoordinate(GetBearing(Destination, Origin),1) to reverse the bearing directly 180. I've tried this CalculateCoordinate(90,1) to calculate an offset to the side but that's not working either.
Where have I gone wrong, I'm sure it's something pretty stupid and simple.
There's two mistakes that I can see. First, Atan2 takes the Y value for the first parameter and the X value for the second:
Math.Atan2(coord2.Y - coord1.Y, coord2.X - coord1.X) * (180 / Math.PI);
Secondly, you're converting from radians to degrees in GetBearing, but you're not converting Angle from degrees to radians inside CalculateCoordinate e.g:
Math.Cos(Angle * (Math.PI / 180))
This question already has answers here:
Calculating Distance between two Latitude and Longitude GeoCoordinates
(14 answers)
Closed 8 years ago.
I need to find the distance(Km) between 2 points in windows 8.1 apps using c# so i used the function below, but the returned value not correct any help please:
public static double DistanceTo(Double latitude1, Double longitude1, Double latitude2, Double longitude2)
{
var a = latitude1 - latitude2;
var b = longitude1 - longitude2;
return Math.Sqrt(a * a + b * b);
}
You use the wrong formula. That's the reason you don't get the correct result.
The formula you use is the one we use for the calculation of the distance between two points
in the same plane and can be proved using the pythagora's theorem. However when we want to calculate the distance between two point on the surface of a sphere (we assume that the earth is a perfect sphere), we don't use this type.
Here is a link with the correct formula and an implementation in JavaScript.
Below, I have an implementation in C#
At first we have to define a method that would take as a parameter an angle and it will return it's value in radians.
public double ConvertToRadians(double angle)
{
return (Math.PI / 180) * angle;
}
Then we could define our method for the calculation of the distance:
public static double DistanceTo(double latitude1,
double longitude1,
double latitude2,
double longitude2)
{
// The radius of the earth in Km.
// You could also use a better estimation of the radius of the earth
// using decimals digits, but you have to change then the int to double.
int R = 6371;
double f1 = ConvertToRadians(latitude1);
double f2 = ConvertToRadians(latitude2);
double df = ConvertToRadians(latitude1-latitude2);
double dl = ConvertToRadians(longitude1-longitude2);
double a = Math.Sin(dφ/2) * Math.Sin(dφ/2) +
Math.Cos(f1) * Math.Cos(f2) *
Math.Sin(dλ/2) * Math.Sin(dλ/2);
double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1-a));
// Calculate the distance.
double d = R * c;
return d;
}
If you don't want to implement it as above, you could use the GeoCoordinate class, which
Represents a geographical location that is determined by latitude and
longitude coordinates. May also include altitude, accuracy, speed, and
course information.
If you do so, then:
var point1 = new GeoCoordinate(latitude1, longitude1);
var point2 = new GeoCoordinate(latitude2, latitude2);
and then you get the distance between point1 and point2 like below:
point1.GetDistanceTo(point2);
Try something like this:
var coord1 = new GeoCoordinate(lat1, long1);
var coord2 = new GeoCoordinate(lat2, long2);
var distance = coord1.GetDistanceTo(coord2);
Look here. Seems like a duplicate
In the Iphone SDK the distanceFromLocation: says it doesn't use altitude at all. If I'm writing an app to track how far I walk/cycle/ect (yes I know there are a number that do this already), I'm curious how much that matters. Does anyone have experience with this?
When I say cartesian cords I mean something like this (in C#, not objective C):
double lattitude, longitude, altitude, x, y, z, x1, y1, z1, S;
double a = 6378137, C, f = 1 / 298.257224;
lattitude = <insert degrees> * Math.PI / 180.0;
longitude = <insert degrees> * Math.PI / 180.0;
altitiude = <insert altitude>
C= 1 / (Math.Sqrt(Math.Pow(Math.Cos(lattitude),2.0) + Math.Pow((1 - f),2.0) *Math.Pow(Math.Sin(lattitude),2.0)));
S = Math.Pow(1 - f, 2.0) * C;
x = (a*C+altitude) * Math.Cos(lattitude) * Math.Cos(longitude);
y = (a*C+altitude) *Math.Cos(lattitude) * Math.Sin(longitude);
z = (a*S+altitude) * Math.Sin(lattitude);
lattitude = <insert degrees new> * Math.PI / 180.0;
longitude = <insert degrees new> * Math.PI / 180.0;
altitiude = <insert altitude new>;
x1 = (a * C + altitude) * Math.Cos(lattitude) * Math.Cos(longitude);
y1 = (a * C + altitude) * Math.Cos(lattitude) * Math.Sin(longitude);
z1 = (a * S + altitude) * Math.Sin(lattitude);
double distance;
distance = Math.Sqrt(Math.Pow(x1 - x, 2.0) + Math.Pow(y1 - y, 2.0) + Math.Pow(z1 - z, 2.0));
Does anyone know how much of a difference it actually makes? Essentially how it is calculated precisely on iphone? Great circle distance? I can't seem to find the answer anywhere
The docs say:
"This method measures the distance
between the two locations by tracing a
line between them that follows the
curvature of the Earth. The resulting
arc is a smooth curve and does not
take into account specific altitude
changes between the two locations."
To me, that implies Great Circle distance (in fact, it's nearly the definition of it).
My understanding (though I'm certainly no expert) is that great circle calculations (such as Haversine) are very typical, and generally considered "good enough" for most applications.
There's probably way more information than you want on the topic here. This question is semi-related as well.
If you're really concerned about it, I'd try a few different algorithms, and see if you can determine which best suits your needs.