Distance between two points. East-west + North-south - mysql

I need to calculate the distance between two points, but not in the regular way. I need to know 'the east to west distance' + 'the north to south distance'. I guess this is more simple then the regular 'as the crow flies' calculation but i still can't figure out how to do it.
I want to do this using a MySQL query and preferably have the result returned in km. One of the points will be a constant in the query and the other point is a point from the DB so something like SELECT abs(longitude-39.12345)...+abs(latitude... AS Distance FROM shops WHERE shopname='Bingo'.
Thanks in advance!

The north-to-south distance is proportional to the difference in the latitudes. It's about 1 nautical mile per minute of arc (the circumference of the earth is about 21600 nautical miles).
The east-to-west distance is proportional to the difference in the longitudes, but it also varies with the latitude (e.g. it's zero at the poles): I think it's proportional to the cosine of latitude.

Your answer depends on the accuracy required in your answer. If you don't need an answer more accurate than a spherical earth model, you can use a solution similar to the one given by Captain Tom. If you require more accuracy, you'll need to assume the earth is an oblate spheroid. See http://en.wikipedia.org/wiki/Vincenty%27s_formulae for a couple of solutions.

The east-west difference between two points at different latitudes is a distinct number in degrees of longitude, but converting this to miles is problematic because the miles per degree vary according to the latitude. For example, Los Angles and New York City are 44.3 degrees of longitude apart, but converting this to miles would result in a larger number at LA's latitude than at NYC's latitude, since latitude lines are longest at the equator and shrink to zero at the poles.
A reasonable convention would be to count the E-W distance as the average of the two distances calculated at the two latitudes.

You can determine the distance between any two geocode points using the Great-Circle Distance. Here is another decent article on the subject.
The following is an example in C# which shows how to do this:
var earth_radius = Constants.EarthRadius; // 6377.8 km
var dLat = ToRadians(fromLatitude - toLatitude);
var dLon = ToRadians(fromLongitude - toLongitude);
var a =
Math.Sin(dLat / 2) *
Math.Sin(dLat / 2) +
Math.Cos(ToRadians(fromLatitude)) *
Math.Cos(ToRadians(toLatitude)) *
Math.Sin(dLon / 2) *
Math.Sin(dLon / 2);
var c = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)));
var distanceInKilometers = earth_radius * c;

Use simple trig. The normal "as the crow flies" distance is the hypotenuse of the right triangle formed with the two points you have in mind at either ends of the hypotenuse.
Just look at this http://en.wikipedia.org/wiki/Hypotenuse and the solution should become clear.

Related

MariaDB : calculate distance between 2 points in km

I try to get some approximate distance between 2 points in mariaDB.
I use that SQL:
SELECT st_distance(POINT(50.6333,3.0667),p) from p
It outputs results such as:
0
1.9128040446888426
8.103248262271125
It seems mariaDB does not handle SRID.
Is there a way to convert these values to km ? (looks like multiplying by 110 is quite correct)
My goal is to avoid handling maths such as sin, cos, atan and approximate result is ok for me.
The result returned by st_distance are not kilometer but minutes.
For a circumference of the equator of d = 40.075km, the distance between two minutes is d / 360 = 111,319 km.
While the distance between the latitudes is constant, the distance between the longitudes from the equator to the pole caps decreases constantly. According to your example the point from one location must be somewhere in France, where the distance between longitudes is around 70km.
Since you don't want to use the Haversine formula, you can also use the Pythagorean theorem to get a more accurate result:
# Distance between Eiffel tower and Lille
SELECT ST_DISTANCE(GeomFromText("Point(50.6333 3.0669)"), GeomFromText("Point(48.853. 2.348)")) * 111.38;
-> 213.84627307672486
select sqrt(pow((50.63333 - 48.853) * 111.38,2) + pow((3.0669 - 2.348) * 70, 2));
->204.57903071304386
ST_DISTANCE is designed for flat-earth advocates.
ST_DISTANCE_SPHERE is available in InnoDB as of 5.7.
https://dev.mysql.com/doc/refman/5.7/en/spatial-convenience-functions.html#function_st-distance-sphere

SQL Finding the coordinates that belong to a circle

I have a SQL database set of places to which I am assigned coordinates (lat, long). I would like to ask those points that lie within a radius of 5km from my point inside. I wonder how to construct a query in a way that does not collect unnecessary records?
Since you are talking about small distances of about 5 km and we are probably not in the direct vicinity of the north or south pole we can work with an approximated grid system of longitude and latitude values. Each degree in latidude is equivalent to a distance of km_per_lat=6371km*2*pi/360degrees = 111.195km. The distance between two longitudinal lines that are 1 degree apart depends on the actual latitude:
km_per_long=km_per_lat * cos(lat)
For areas here in North Germany (51 degrees north) this value would be around 69.98km.
So, assuming we are interested in small distances around lat0 and long0 we can safely assume that the translation factors for longitudinal and latitudinal angles will stay the same and we can simply apply the formula
SELECT 111.195*sqrt(power(lat-#lat0,2)
+power(cos(pi()/180*#lat0)*(long-#long0),2)) dist_in_km FROM tbl
Since you want to use the formula in the WHERE clause of your select you could use the following:
SELECT * FROM tbl
WHERE 111.195*sqrt(power(lat-#lat0,2)
+power(cos(pi()/180*#lat0)*(long-#long0),2)) < 5
The select statement will work for latitude and longitude values given in degree (in a decimal notation). Because of that we have to convert the value inside the cos() function to radians by multiplying it with pi()/180.
If you have to work with larger distances (>500km) then it is probably better to apply the appropriate distance formula used in navigation like
cos(delta)=cos(lat0)*cos(lat)*cos(long-long0) + sin(lat0)*sin(lat)
After calculating the actual angle delta by applying acos() you simply multiply that value by the earth's radius R = 6371km = 180/pi()*111.195km and you have your desired distance (see here: Wiki: great circle distance)
Update (reply to comment):
Not sure what you intend to do. If there is only one reference position you want to compare against then you can of course precompile your distance calculation a bit like
SELECT #lat0:=51,#long0:=-9; -- assuming a base position of: 51°N 9°E
SELECT #rad:=PI()/180,#fx:=#rad*6371,#fy:=#fx*cos(#rad*#lat0);
Your distance calculation will then simplify to just
SELECT #dist:=sqrt(power(#fx*(lat-#lat0),2)+power(#fy*(long-#long0),2))
with current positions in lat and long (no more cosine functions necessary). It is up to you whether you want to store all incoming positions in the database first or whether you want to do the calculations somewhere outside in Spring, Java or whatever language you are using. The equations are there and easy to use.
I would go with Euklid. dist=sqrt(power(x1-x2,2)+power(y1-y2,2)) . It works everywhere. Maybe you have to add a conversion to the x/y-coordinates, if degrees can't be translated in km that easy.
Than you can go and select everything you like WHERE x IS BETWEEN (x-5) AND (x+5) AND y IS BETWEEN (y-5) AND (y+5) . Now you can check the results with Euklid.
With an optimisation of the result order, you can get better results at first. Maybe there's a way to take Euklid to SQL, too.

Correct way of finding distance between two coordinates using spatial function in MySql

I am trying to calculate distance between two locations using spatial functions in both Mysql and PostgresSQL. I have taken the latitude and longitude from Google. The details are below
Location one - Lat: 42.260223; Lon: -71.800010
Location two - Lat: 42.245647; Lon: -71.802521
SQL Query used:
SELECT DISTANCE(GEOMFROMTEXT('Point(42.260223 -71.800010)'),GEOMFROMTEXT('Point(42.245647 -71.802521)'))
The both databases are giving the same result 0.014790703059697. But when I calculate distance in other systems the results are different. Please refer the below links
http://www.zip-codes.com/distance_calculator.asp?zip1=01601&zip2=01610&Submit=Search = 1.44 miles
http://www.distancecheck.com/zipcode-distance.php?start=01601&end=01610 = 1.53 miles
So I want to know whether my calculation method/query is right or not. And if it is wrong, then what is the right way of querying the db for the distance.
The simple answer is to use the Haversine formula. This assumes the earth is a sphere, which it isn't, but it's not a bad approximation. This, with lots of other details are described in this presentation:
http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL
In the case above, MySql is simply applying the pythagorean theorem: c2 = a^2 + b^2. In this specific case SQRT((42.245647 - 42.260223)^2 + (-71.802521^2 - -71.800010)^2) = 0.014790703.
There are actually two problems with using the MySql distance functon for distance with coordinates on a sphere. (1) MySql is caclulating distance on a plane, not a sphere. (2) The result is coming back in a form of degrees, not miles. To get a true, spherical distance in miles, km, ft etc, you need to convert your lat and long degrees into the units you want to measure by determining the radius from a line through the center of the earth for the latitude(s) you are measuring.
To get a true measure is quite complicated, many individuals and companies have made careers out of this.

Calculating geospatial distance with radians

I have a method in an API that takes a lat/long coordinate and will find other coordinates within a specified distance. That distance is in radians.
All the math I do these days deals with accounting or maybe x,y coordinates for laying out UI elements, so I appreciate some help validating these numbers.
Lets ignore people in buildings (altitude) and the fact that the planet isn't perfectly spherical. It is my understanding that the supplied method is doing the Haversine formula internally but that detail is isolated from me.
I am looking at the formula for radians:
θ = s /r, where θ is the subtended
angle in radians, s is arc length, and
r is radius
Given the convenient mean radius of the Earth of:
6371 km
(≈3,959 mi)
I have seen other places saying (6378km)
That means 1 radian on Earth is equal to 6371 km in arc length. That would mean the radian for finding coordinates 1 meter apart would be
( 1 / 6371 ) × 10-7
ie - 1.56961231 × 10-7.
Is that right? If not where is the above incorrect?
It's correct. Although I feel a little shame posting this as an answer :)

How to use linear interpolation estimate current position between two Geo Coordinates?

I have the following available:
last reported lat,lon w/timestamp
target lat,lon
estimated time to target
heading
How can I interpolate an estimated position over time?
I know that's enough to calculate the required average velocity for the remainder of the trip. Given a straight-line distance, it's pretty trivial. I know it has to do with vectors but I'm a bit rusty and thought it better to consult some experts.
The reason I need this update rate is limited, so to show smooth animation I need to guess at the current position between updates.
The target platform is a Google Maps application so I have available some basic functionality like a Geo-correct function for distance between two coordinates. Language is unimportant as I know many and can port or adapt any examples if needed. General solutions would be preferred however.
Is this simply two independent vector calculations?
latestimate = latstart + (Δlat * P)
lonestimate = lonstart + (Δlon * P)
Where:
testimated = the reported estimated time to target
telapsed = time since last time estimate
P = telapsed / testimated
Δlat = latreported - lattarget
Δlon = lonreported - lontarget
You want to use a Slerp, or spherical linear interpolation.
Convert your latitude and longitude to a unit 3-vector:
p=(x,y,z)=(cos(lon)*cos(lat), sin(lon)*cos(lat), sin(lat))
Then, "Slerp" gives you a constant-velocity interpolation along the surface of the unit sphere:
theta= angle between 3-vectors p0 and p1 (e.g., cos(theta)= p0.p1)
Slerp(p0,p1,t)= ( p0*sin((1-t)*theta) + p1*sin(t*theta) ) / sin(theta)
Note that if theta is very close to 0 or 180 degrees, this formula can be numerically unstable. In the small-angle case, you can fall back to linear interpolation; in the 180 degree case, your path is genuinely ambiguous.
Lat_to_Travel = CurLat - TargetLat
Long_to_Travel = CurLong - TargetLong
Time_to_Travel = ETA - now
If the distances are relatively small, it is probably ok to assume a linear progression on these three dimensions (*). You then need to decide on a number of intermediate position to display, say 10, and calculate each intermediate point accordingly
NbOfIntermediates = 10 // for example
Lat_at_Intermediate(n) = CurLat + (1/NbOfIntermediates * Lat_to_travel)
Long_at_Intermediate(n) = CurLong + (1/NbOfIntermediates * Long_to_travel)
Time_at_Intermediate(n) = now + (1/NbOfIntermediates * Time_to_travel)
The most complicated in all this is to keep the units ok.
( * ) A few considerations as to whether it is ok to assume a linear progression...
Obviously the specifics of the reality of the physical elements (marine currents, wind, visibility...) may matter more in this matter than geo-spatial mathematics. Assuming that the vehicle travels at a constant speed, in a direct line, it is [generally] ok to assume linearity in the Latitude dimension [well technically the earth not being exactly a sphere this is not fully true but damn close]. However, over longer distances that include a relatively big change in latitude, the angular progression along the longitude dimension is not linear. The reason for this is that as we move away from the equator, a degree of longitude expressed in linear miles (or kilometer...) diminishes. The following table should give a rough idea of this effect, for locations at various latitudes:
Latitude Length of a Degree Approximate examples
(of longitude) in
nautical miles
0 60 Kuala Lumpur, Bogota, Nairobi
20 56.5 Mexico city, Mecca, Mumbai, Rio de Janeiro
45 42.5 Geneva, Boston, Seattle, Beijing, Wellington (NZ)
60 30 Oslo, Stockholm, Anchorage AK, St Petersburg Russia
See this handy online calculator to calculate this for a particular latitude.
Another way to get a idea for this is to see that traveling due East (or West) at the lattitude of Jacksonville, Florida, or San Diego, California, it takes 52 miles to cover a degree of longitude; at the latitude of Montreal or Seattle, it takes only 40 miles.