Haversine Formula Implementation on Arduino - arduino-ide

I'm working on creating a geofence using GPS & Arduino. I want to implement the Haversine Formula to find the distance between two points, in order to compute it with the radius. The problem is I'm finding it hard to implement the Haversine Formula on the Arduino IDE, I'm relatively beginner on Arduino.
a = sin²(Δφ/2) + cos(φ1).cos(φ2).sin²(Δλ/2)
c = 2.atan2(√a, √(1−a))
d = R.c
How can I implement the above formula on Arduino IDE?

To use Haversine or Spherical Law of Cosines you require either atan2() or acos() functions which do not seem to be available in Arduino.
Pythagoras’ theorem can be used on an equirectangular projection to calculate distance. This is less complicated than Haversine or Spherical Law of Cosines but still allows for the convergence towards poles and uses the trig functions available in Arduino.
Theory
The circumference of the earth at equator = 40,076 km. The equator is divided into 360 degrees of longitude, so each degree at the equator represents approximately 111.32 km. Moving away from the equator towards a pole this distance decreases to zero at the pole.
1 degrees aproximates to 111.32 km at equator.
96.41km at 30 degrees N/S
78.71 km at 45 degrees N/S
55.66 km at 60 degrees N/S
28.82 km at 75 degrees N/S
Application
In pseudo code as I don't know Arduino
R = 6371;km
lat/lng in radians
var x = (lng2-lng1) * cos((lat1+lat2)/2);
var y = (lat2-lat1);
var dist = sqrt(x*x + y*y) * R;
Result
coordinates = (0,0) to (1,0) Haversine 157.293809 km Equirectangular 157.294807 km
coordinates = (10,0) to (11,0) Haversine 155.985273 km Equirectangular 155.986379 km
coordinates = (20,0) to (21,0) Haversine 152.397156 km Equirectangular 152.39855 km
coordinates = (30,0) to (31,0) Haversine 146.81715 km Equirectangular 146.818975 km
coordinates = (40,0) to (41,0) Haversine 139.728101 km Equirectangular 139.730447 km
coordinates = (50,0) to (51,0) Haversine 131.817706 km Equirectangular 131.820603 km
coordinates = (60,0) to (61,0) Haversine 123.976838 km Equirectangular 123.980256 km
coordinates = (70,0) to (71,0) Haversine 117.255674 km Equirectangular 117.259525 km
coordinates = (80,0) to (81,0) Haversine 112.726966 km Equirectangular 112.731106 km

TinyGPS library for the arduino has a function to measure distance between two points as well as course/bearing between two points.

Related

calculate walking distance between gps points

I have pairs of gps coordinates (longitude latitude) and I would like to calculate the walking distance between them. i.e. using road data (from google maps or another open source) calculate the km of the shortest route between the two gps points. I could do it using google maps, but I have thousands of pairs so I would like to find a more automated way.
Does somebody know how to do it?
I am not quite sure about what you looking for. Just share some thoughts here:
1) If you want to calculate great circle distance between two points in lat/lon, you could use haversine formula distance. Example in JS:
function Haversine_distance(lat1,lon1,lat2,lon2) {
var R = 6371; // in km
var x1 = lat2 - lat1;
var dLat = x1.toRad();
var x2 = lon2 - lon1;
var dLon = x2.toRad();
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
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*1.0;
};
2) If you need more accurate distance calculation you need some correction factor, since earth is not a perfer sphere. It is always easier to project the locations you have to an appropriate projection and calculate distance there. For instance, project to UTM zones using proj4js, then calculate the distance to reduce the inaccuracy.
3) If you are talking about walking distance in cities, then it is network distance. It is required to have your road network build up first, then calculate from there. Without the road network, giving only point locations will not be enough to calculate the walking distance. Commercial data for road network is available from such as TeleAtlas. Free data can also be found via OpenStreetMap.

google maps - extending polygon boundaries by a certain distance

I have a rectangular polygon and I want to extend the boundaries by 10 km for example.
How would I do that ?
I could use extend method, but how Do I find the distance of 10 km in lat lng ?
So far I have :
bounds = new google.maps.LatLngBounds();
pt = new google.maps.LatLng(lat,lng);
bounds.extend(pt)
It depends on how exact an answer you need.
You could use the following approximation:
Latitude: 1 deg = 110.57 km; Longitude: 1 deg = 111.320 km source: http://en.wikipedia.org/wiki/Latitude
For a more exact formula, you need to check http://www.movable-type.co.uk/scripts/latlong.html . It has various formulas and also some code. You are looking for the section called 'Destination point given distance and bearing from start point'
It depends where you are looking at but a longitude is 111km and a latitude 110km:http://en.m.wikipedia.org/wiki/Latitude.

Is there a way of selecting lat1,lat2,lon1,lon2 from Envelope(Poly) in MySQL?

If I have a column called Poly of type polygon in MySQL and I want to get the NW corner and the NE corner and the SE corner and the SW corner, how would I do that? From an Envelope() there should be lat1, lat2, lon1, and lon2 that form the four corners as follows lat1,lon1 is NW; lat1,lon2 is NE; lat2,lon2 is SE; and lat2,lon1 is SW. When I try X(PointN(Envelope(Poly),1)) AS lat1 it always returns NULL. Can this be done in MySQL?
SELECT
X(PointN(Envelope(Poly),1)) AS lat1, X(PointN(Envelope(Poly),3)) AS lat2,
Y(PointN(Envelope(Poly),1)) AS lon1, Y(PointN(Envelope(Poly),2)) AS lon2
FROM boundaries.mt_us_zip5_2013_boundaries_polys_bin
WHERE zip = '00601';
The query above returns:
NULL,NULL,NULL,NULL
Here's what the Envelope looks like:
SELECT AsText(Envelope(Poly))
FROM boundaries.mt_us_zip5_2013_boundaries_polys_bin
WHERE zip = '00601';
This last query returns:
POLYGON((18.111929 -66.836366,18.250344 -66.836366,18.250344 -66.659293,18.111929 -66.659293,18.111929 -66.836366))
I'm using MySQL version 5.5.36, would upgrading to a new version of MySQL give me the functions I need?
PointN is only defined on LineString, but luckily you can call ExteriorRing on the Polygon to get a LineString. In your example:
SELECT
X(PointN(ExteriorRing(Envelope(Poly)),1)) AS lat1,
X(PointN(ExteriorRing(Envelope(Poly)),3)) AS lat2,
Y(PointN(ExteriorRing(Envelope(Poly)),1)) AS lon1,
Y(PointN(ExteriorRing(Envelope(Poly)),2)) AS lon2
FROM boundaries.mt_us_zip5_2013_boundaries_polys_bin
WHERE zip = '00601';
I'm not familiar enough with MySQL if it has this built-in but my first thought was to first find in the center of the polygon, then compute the bearing at each point on the poly from the center. A bearing of 0 would be north and a bearing of 90 deg would be east, thus north-east would be 45 deg. Find the points closest to the 45 deg angles gives you the corners.
Center of the polygon is here: Computing latitude longitude center point of a Polygon in PHP
Computing bearing from 2 lat/lon points: http://www.movable-type.co.uk/scripts/latlong.html

Calculate approximate distance between two points

I am trying to calculate approximate distance between two points with respect to road map on Google Maps. 75% of the time the points are not on a straight line, and they form a triangle on the road map. I am taking right angle as well as obtuse angle into consideration. And the line created by the points to be the hypotenuse.
Lets take the line formed by the points: "x"
Other Two lines: "y" & "z"
Assuming y and z equal
Now I am taking two options as stated earlier for best result:
Option 1:
y = x(sin 45)/(sin90)
Total Distance = 2y
Option 2:
y = x(sin 30)/(sin120)
Total Distance = 2y
On calculation the distance by getting the all the coordinates of the distance. It is different from both at and approximately 10 to 20%.
In almost all cases the second one provides the best value on checking with the Google Maps vehicle distance.
Is there any better alternative for maximum accuracy?
Did you try Haversine formula?
which is:
dlon = lon2 - lon1
dlat = lat2 - lat1
a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2
c = 2 * atan2(sqrt(a), sqrt(1-a))
d = R * c

Lat/Lon + Distance + Heading --> Lat/Lon

So: I have the following function, adapted from a formula found online, which takes two lat/lon coordinates and finds the distance between them in miles (along a spherical Earth):
public static double distance (double lat1, double lon1, double lat2, double lon2) {
double theta = toRadians(lon1-lon2);
lat1 = toRadians(lat1);
lon1 = toRadians(lon1);
lat2 = toRadians(lat2);
lon2 = toRadians(lon2);
double dist = sin(lat1)*sin(lat2) + cos(lat1)*cos(lat2)*cos(theta);
dist = toDegrees(acos(dist)) * 60 * 1.1515 * 1.609344 * 1000;
return dist;
}
As far as I can tell this works just fine.
What I need is a second function which, using the exact same model of the Earth's geometry, takes a single lat/lon pair [A], a heading, and a distance, and outputs a new lat/lon pair [B] such that if you started at point [A], and traveled the given distance at the given heading, you'd wind up at point [B].
This is where the fact that my geometry skills have left me entirely comes into play :)
Any help would be much appreciated!
Thanks,
-Dan
I get most of those types of formulas from The Aviation Formulary.
The formula he gives is:
Lat/lon given radial and distance
A point {lat,lon} is a distance d out on
the tc radial from point 1 if:
lat=asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc))
IF (cos(lat)=0)
lon=lon1 // endpoint a pole
ELSE
lon=mod(lon1-asin(sin(tc)*sin(d)/cos(lat))+pi,2*pi)-pi
ENDIF
This algorithm is limited to distances such that dlon < pi/2, i.e
those that extend around less than one
quarter of the circumference of the
earth in longitude. A completely
general, but more complicated
algorithm is necessary if greater
distances are allowed:
lat =asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc))
dlon=atan2(sin(tc)*sin(d)*cos(lat1),cos(d)-sin(lat1)*sin(lat))
lon=mod( lon1-dlon +pi,2*pi )-pi
Note that he's using "tc" to stand for true course (in radians clockwise from North) and the distances he gives are in radians of arc along the surface of the earth. This is explained (along with formulas to convert back and forth from nautical miles) in the first section of the Formulary. Also, check out the "Implementation Notes" and "Worked Examples" on that page.