distance between latitude and longitude or cities, proof of the great circle.steemCreated with Sketch.

in #programming7 years ago (edited)

One useful tool whether you are developing an ecommerce app, a dating app, event planning app, or a social network app, is to be able to calculate the distance between two different locations.

Unless you plan to track users location by ip address, which they could hide their real IP address by tor, proxyservers, or vpns, it is geberally a good idea to have a few databases of postal zip codes, towns/cities, states, [countries if you are building outside the US], and longitude and latitude. There may be some free or premium tools that can find an exact distance from two addresses, but I am not going to report on those. I suppose for android and iphones, the built in GPS could provide that info but I doubt that would be accessible through the web browser-but for an app you could just skip pas the database part. You can find free ones for the United states on Google. For example, I just downloaded the csv file from https://boutell.com/zipcodes/ which was the first search result from my swagbucks search (aka yahoo).

The last time I worked on the file appears to be in August 2011, and looking through the records it was still in the testing phase-it was parsing the data I wanted, and doing the calculations which appears to be within a small error from that reported by http://www.nhc.noaa.gov/gccalc.shtml , but I was still in the process of determining what else I could do-for example if someone said they lived in atlanta; there are dozens of zipcodes associated with Atlanta. My host provider at the time only allowed for 5k SQL queries per hour per database user (easy to get around, create new database users), but I wanted to avoid using databases so I chose to read from a txt file-same datastructure as the csv err txt file. I know there are more efficient methods of reading file data, it was more about getting a functional prototype.

As I said, the math on it is a good approximation. But back then, I just found probably some variant of the great sphere equations and never bothered to work on a mathematical proof. Lats night, I was hoping that the proof would be pretty easy from differential calculus, as the hours went by I kept thinking how stupid I was and how worthless a theoretical math education was-well I haven't had calc 3 in some 20 years anyways. There probably is one, but it eludes me.

Geometrically speaking, assuming a perfect sphere, if we have any two points on earth, they will be an equidistant from the center of the earth. If we were to connect the vectors, we would create an isosceles triangle. More than that if you were to take a ball, and put any two points on the surface, you would observe that you could rotate the ball so that the two points are on the equator, and so a cross sectional area could be cut out in the shape of a circle whose diameter is that of the sphere. With that cross section you have your two vectors on the circle with a vertex at the origin, in which you could still form your isosceles triangle. The length of your unknown leg depends on the angel formed by the vertex. But more importantly, the angle formed between the vortexes is crucial to finding the length of the arc between the two points-or your distance. basically the length of an arch is 2*pi*radius*(angle/(360)) or r*(rads)).

So how do we get this unknown angel? Let's back to 3 space. In linear Algebra, the angle between two vortexes are the arccosine of the dot product of the two vectors divided by their normals. A vector will generally be in the forma of a*i+b*j+c*k (or a*x+b*y+c*z) So basically acos(v1 (dot) v2/(|v1||v2)).

So how do we convert a longitude and latitude to a specific point. From the Latitude we can find the z location, as well as a ring R (notice upper case) in which it might be located. It is basic trigonometry. height(or z)=r*sin(lat), and the Radius of the ring it could fall on is R=r*cos(lat). The longitude is what tells us where on R our x and y values are. As far as what is our x-axis and y axis, it really doesn't matter. We could choose arbitrarily. But if we have a circles whose radius was R, our points-not suprizingly-would be R*cos(long) and R*sin(long).

For convenience for a given (long1, lat1)
v1={R*cos(long1),R*sin(long1), r*sin(lat1)}
recall that R=r*cos(lat1) and so
v1={r*cos(lat1)*cos(long1),r*cos(lat1)*sin(long1), r*sin(lat1)}
similarly for a given (long2, lat2)
v2={r*cos(lat2)*cos(long2),r*cos(lat2)*sin(long2), r*sin(lat2)}

v1(dot)v2=r^2*cos(lat1)*cos(long1)*cos(lat2)*cos(long2)+r^2*cos(lat1)*sin(long1)*cos(lat2)*sin(long2)+r^2*sin(lat1)*sin(lat2)
v1(dot)v2=r^2*(cos(lat1)*cos(long1)*cos(lat2)*cos(long2)+cos(lat1)*sin(long1)*cos(lat2)*sin(long2)+sin(lat1)*sin(lat2))
v1(dot)v2=r^2((cos(lat1)*cos(lat2))*(cos(long1)*cos(long2)+cos(long1)*sin(long2))+sin(lat1)*sin(lat2))
v1(dot)v2=r^2
((cos(lat1)*cos(lat2))*[cos(long1)*cos(long2)+sin(long1)*sin(long2)]+sin(lat1)*sin(lat2))
Inside the brackets you may see a trig identity
cos(long1-long2)=cos(long1)*cos(long2)+sin(long1)*sin(long2)
For those who haven't used trig identities in a while, you could see this better using the real part of the exponential.
e^((a-b)*i)=e^(ai)*e^(-bi)
e^(ai)*e^(-bi)=(cos(a)+i*sin(a))*(cos(-b)-i*sin(b))
(cos(a)+i*sin(a))*(cos(-b)-i*sin(b))=(cos(a)+i*sin(a))*(cos(b)-i*sin(b))
(cos(a)+i*sin(a))*(cos(b)-i*sin(b))=cos(a)*cos(b)-i*cos(a)*sin(b)+i*sin(a)*cos(b)+sin(-a)*sin(b)
real(cos(a)*cos(b)-i*cos(a)*sin(b)+i*sin(a)*cos(b)+sin(a)*sin(b))=cos(a)*cos(b)+sin(a)*sin(b)
anyways
v1(dot)v2=r^2*((cos(lat1)*cos(lat2))*[cos(long1-long2)]+sin(lat1)*sin(lat2))
So we are done finding the dot product.

The Normal line is similar similar to the hypotenuse is trig, you probably seen it in 3 space when finding the diagonal of a box.
h^2=a^2+b^2+c^2
To digress for a big, and implementing the pythagorean theorem
Notice that h^2=(r*cos(lat)*cos(long))^2+(r*cos(lat)*sin(long))^2,+(r*sin(lat))^2
h^2=r^2*cos2(lat))(cos2(long))+r^2*cos2(lat))(sin2(long))+r^2*sin(lat))
h^2=r^2*cos2(lat))(cos2(long)+sin2(long))+r^2*sin(lat))
h^2=r^2*cos2(lat))+r^2*sin(lat))
h^2=r^2*(cos2(lat)+sin(lat))
h^2=r^2
so h=r, or |v1|=r and |v2|=r.

So to finally find your angel (or rads) theta between the vectors v1,v2
theta=acos(v1(dot)v2/(|v1|*|v2|))
theta=acos(r^2*(cos(lat1)*cos(lat2)*cos(long1-long2)+sin(lat1)*sin(lat2))/(r*r))
theta=acos(cos(lat1)*cos(lat2)*cos(long1-long2)+sin(lat1)*sin(lat2))

Let us assume that theta is in rads.
the radius of the earth we'll call r.
r*(theta)
if there is in degrees
2*pi*r*(theta/360)

if we again assume we are in radians, and we recall that theta=acos(cos(lat1)cos(lat2)cos(long1-long2)+sin(lat1)*sin(lat2))
we observe this matches the great sphere equation mentioned on wikipedia.

For my datafeed, I suppose it is a file called long.txt

and the data withing are as followed:
zip,city,state,latitude,longitude,timezone,dst
210,Portsmouth,NH,43.005895,-71.013202,-5,1
211,Portsmouth,NH,43.005895,-71.013202,-5,1
....

a sample php script would be (reading in data from a webpage, or with the following defaults).

<?php
//setting the inputs or defaults values
$s=$_GET[start] or $s=211;
$f=$_GET[jump] or $f=30305;
//we may need to clean up the inputs. An input may be 00211, but the data entra was 221
//better code would also get rid of all bad input after this point. No ensuring all numbers, no more than 5 digits or correcting for zip 9
if ($f<10000 && strlen($s)==4) {$f=substr($f,1);}
if ($f<1000 && strlen($s)==4) {$f=substr($f,1);}
if ($s<10000 && strlen($f)==5) {$s=substr($s,1);}
if ($s<1000 && strlen($f)==4) {$s=substr($s,1);}

//reading the datafile
$fp=fopen("long.txt","r");
$data=fread($fp,2000000);

//finding the locations of our zip codes following a new line char
$a=strpos($data,"\n$s");
$b=strpos($data,"\n$f");

//cuts out that one date line we are looking for
$endl1=substr($data,$a,strpos($data,"\n"));
$endl2=substr($data,$b,strpos($data,"\n"));
//cuts out the zip code
$endl1=substr($endl1,strpos($endl1,",")+1);
$endl2=substr($endl2,strpos($endl2,",")+1);
//cuts out the town
$endl1=substr($endl1,strpos($endl1,",")+1);
$endl2=substr($endl2,strpos($endl2,",")+1);
//cuts out the state
$endl1=substr($endl1,strpos($endl1,",")+1);
$endl2=substr($endl2,strpos($endl2,",")+1);
//gets our latitude
$lat1=substr($endl1,0,strpos($endl1,","));
$lat2=substr($endl2,0,strpos($endl2,","));
//skips latitude
$endl1=substr($endl1,strpos($endl1,",")+1);
$endl2=substr($endl2,strpos($endl2,",")+1);
//gets longitude
$long1=substr($endl1,0,strpos($endl1,","));
$long2=substr($endl2,0,strpos($endl2,","));

//radius of the earth
$r=3963;
//we have to convert degrees into radians and perform the trig functions
$a1=cos((pi()/180)*($lat1));
$a2=cos((pi()/180)*($lat2));
$a3=sin((pi()/180)*($lat1));
$a4=sin((pi()/180)*($lat2));
$a5=cos((pi()/180)*($long1-$long2));

echo $r*acos($a3*$a4+$a1*$a2*$a5);

I have provided a sample. All you need to do is enter in the two zip code.
http://neophytesoftware.com/steemitfirstamendment/distance.html

Sort:  

Lol I am a tech person but this is over my head.

The mathematics is perhaps superlative for the tech people. In the end it is a simple math function, whose parameters you can get from a file or a database. But there are examples of such code everywhere on the web, where a user inputs longitude and latitude.

I added some uniqueness in that I don't require longitude and latitude as inputs. Your users on a host browser based applications won't know that, but they will know their zip. The link at the end, you enter in two zip codes, and it looks up the longitude and latitude; It prints out the towns/cities, the longitude, latitude, and the distance based upon the zip codes-which is more realistic for development. The php code on my server does a little more than the code shown above. But the above code does pretty much the same, based upon two zip codes it looks up the longitide and latitudes from a text file, and produces the distances.

As far as the math, I was hoping to make it easy to visualize. Maybe that got lost when I mixed up vector and vertices when I first posted it, but I hope I fixed that mistake. But much of it is all just basic trigonometry, with the exception of that one part from linear algebra. But Even though I was pulling an A in Advanced linear Algebra without a calculator, much of linear algebra will remain voodoo to me. It is that use of arccosine from linear algebra is ultimately whats important.

This post is cool - I will follow you. But, formulas is not so understandable. It's not your fault - steemit has dull mardown system

This post recieved an upvote from minnowpond. If you would like to recieve upvotes from minnowponds team on all your posts, simply FOLLOW @minnowpond.

    To receive an upvote send 0.25 SBD to @minnowpond with your posts url as the memo
    To receive an reSteem send 0.75 SBD to @minnowpond with your posts url as the memo
    To receive an upvote and a reSteem send 1.00SBD to @minnowpond with your posts url as the memo

@minnowpond1 has voted on behalf of @minnowpond. If you would like to recieve upvotes from minnowponds team on all your posts, simply FOLLOW @minnowpond.

        To receive an upvote send 0.25 SBD to @minnowpond with your posts url as the memo
        To receive an reSteem send 0.75 SBD to @minnowpond with your posts url as the memo
        To receive an upvote and a reSteem send 1.00SBD to @minnowpond with your posts url as the memo

Congratulations! This post has been upvoted from the communal account, @minnowsupport, by firstamendment from the Minnow Support Project. It's a witness project run by aggroed, ausbitbank, teamsteem, theprophet0, someguy123, neoxian, followbtcnews/crimsonclad, and netuoso. The goal is to help Steemit grow by supporting Minnows and creating a social network. Please find us in the Peace, Abundance, and Liberty Network (PALnet) Discord Channel. It's a completely public and open space to all members of the Steemit community who voluntarily choose to be there.

@reported has voted on behalf of @minnowpond. If you would like to recieve upvotes from minnowponds team on all your posts, simply FOLLOW @minnowpond.

        To receive an upvote send 0.25 SBD to @minnowpond with your posts url as the memo
        To receive an reSteem send 0.75 SBD to @minnowpond with your posts url as the memo
        To receive an upvote and a reSteem send 1.00SBD to @minnowpond with your posts url as the memo