Zip code distance calculator - excel

I have a spreadsheet of addresses and I need to calculate the distance between all of their zip codes and my zip code. I'm fairly flexible on the method used, but I'm hoping for some sort of webservice or mathematic algorithm. US addresses only. Basically I need to feed in 2 zip codes and get out the distance between them.
I'm willing to use Excel formulas or VBA, and I can even code something in C#.net if needed.
How would you go about calculating these distances?

You could use Latitude and Longitude.
Excel:
=IF(SIN(Lat1) * SIN(Lat2) + COS(Lat1) * COS(Lat2) * COS(Long1 - Long2) > 1,
RadiusofEarth * ACOS(1), RadiusofEarth *
ACOS(SIN(Lat1) * SIN(Lat2) + COS(Lat1) * COS(Lat2) * COS(Long1-Long2)))
VB.net imports System.Math
Private Function Distance(ByVal lat1 As Double, ByVal lon1 As Double, ByVal lat2 As Double, ByVal lon2 As Double, ByVal unit As String) As Double
Dim theta As Double = lon1 - lon2
Dim dist = System.Math.Sin(deg2rad(lat1)) * System.Math.Sin(deg2rad(lat2)) + System.Math.Cos(deg2rad(lat1)) * System.Math.Cos(deg2rad(lat2)) * System.Math.Cos(deg2rad(theta))
dist = System.Math.Acos(dist)
dist = rad2deg(dist)
dist = dist * 60 * 1.1515
Select Case unit
Case "K"
dist = dist * 1.609344
Case "N"
dist = dist * 0.8684
End Select
Return dist
End Function
Other Useful Links(First one also mentions VBA alternatives)
ExcelLatLong (Also mentions VBA alternatives)
Zips by Lat Long Lookup
VBA discussion
EDIT: Link added due to comment discussion
More Info(Excel Formula)

It's pretty simple actually. Download a database of zip codes' GPS coordinates, there's plenty of sites that have this data available for download. They would list the coordinates for the center of the zip code.
Use a formula to calculate shortest distance: (ex: http://www.movable-type.co.uk/scripts/latlong.html)

Related

Test Visual Basic Scripts behind an Excel Spreadsheet

First of all I need to point out that I have never coded Visual Basic before.
I have an old spreadsheet which has some functions that are apparently written in Visual Basic. An example functions is:
Function Helmert_X(X, Y, Z, DX, Y_Rot, Z_Rot, s)
'Computed Helmert transformed X coordinate.
'Input: - _
cartesian XYZ coords (X,Y,Z), X translation (DX) all in meters ; _
Y and Z rotations in seconds of arc (Y_Rot, Z_Rot) and scale in ppm (s).
'Convert rotations to radians and ppm scale to a factor
Pi = 3.14159265358979
sfactor = s * 0.000001
RadY_Rot = (Y_Rot / 3600) * (Pi / 180)
RadZ_Rot = (Z_Rot / 3600) * (Pi / 180)
'Compute transformed X coord
Helmert_X = X + (X * sfactor) - (Y * RadZ_Rot) + (Z * RadY_Rot) + DX
End Function
I'm trying to convert these functions into C. I have almost finished but what I would like to do is to build a visual basic project that calls the functions with various parameters. Then I will have a C project which uses the same parameters and checks that the C gets the same answers as the Visual Basic.
When I put the Visual Basic functions into a Module in Visual Studio I get a lot of errors. Firstly the comments don't all register as comments, and the variables apparently need to be declared.
Am I using the functions properly? Is there anyway to use them in code without modifying them? Could I use Excel to run test parameters through the functions?
It seems you need to declare all variables that exist in that function. Try to add theses lines after the comments:
Dim Pi As Double
Dim sfactor As Double
Dim RadY_Rot As Double
Dim RadZ_Rot As Double
You can also specify type for variables that came with function, as well the function itself:
Function Helmert_X(X as Double, Y as Double, Z as Double, DX as Double, Y_Rot as Double, Z_Rot as Double, s as Double) as Double
Let me know if it works or if there is still some issue.

VBA haversine formula

I am trying to implement Haversine formula into excel function. Its looks like this:
Public Function Haversine(Lat1 As Variant, Lon1 As Variant, Lat2 As Variant, Lon2 As Variant)
Dim R As Integer, dlon As Variant, dlat As Variant, Rad1 As Variant
Dim a As Variant, c As Variant, d As Variant, Rad2 As Variant
R = 6371
dlon = Excel.WorksheetFunction.Radians(Lon2 - Lon1)
dlat = Excel.WorksheetFunction.Radians(Lat2 - Lat1)
Rad1 = Excel.WorksheetFunction.Radians(Lat1)
Rad2 = Excel.WorksheetFunction.Radians(Lat2)
a = Sin(dlat / 2) * Sin(dlat / 2) + Cos(Rad1) * Cos(Rad2) * Sin(dlon / 2) * Sin(dlon / 2)
c = 2 * Excel.WorksheetFunction.Atan2(Sqr(a), Sqr(1 - a))
d = R * c
Haversine = d
End Function
But when im testing it I am getting wrong distance... I dont understand why. For coordinates used in this topic : Function to calculate distance between two coordinates shows wrong
I am getting 20013,44 as output. Anyone knows what is wrong here? Cant find my mistake...
Atan2 is defined back to front in Excel compared to JavaScript i.e. Atan2(x,y) rather than Atan2(y,x).
You need to reverse the order of the two arguments:-
c = 2 * Excel.WorksheetFunction.Atan2(Sqr(1 - a), Sqr(a))
See this
So
=haversine(59.3293371,13.4877472,59.3225525,13.4619422)
gives
1.65 km
which is the correct distance as the crow flies.
Great tool! Just underscoring that the result will be in kilometers, so if you want miles multiply the result by 0.62137.

calculating heading from latitude and longitude in excel

I would like to calculate heading direction from the north between 2 points with P1(lat1 , long2) and P2(lat2 long2), in excel.
It depends on what level of accuracy you are looking for. Haversine formula is simple yet may be insufficient since it assumes Earth surface is a perfect sphere (which it is not) and provides only limited accuracy.
Vincenty's formulae provide way better, geodesic grade accuracy (1.46E-6 degrees).
VBA Excel implementation I put together can be found on GitHub: https://github.com/tdjastrzebski/Vincenty-Excel.
VincentyInvFwdAzimuth() function should get you what you need.
I have a function used for ham radio calculations. A "pure" formula was too bulky for me.
Function BearingFromCoord(lat_base_deg, long_base_deg, lat_dest_deg, long_dest_deg As Single) As Long
Dim rad_deg_factor As Single
Dim long_diff As Single
Dim frac0 As Single
Dim frac1 As Single
Dim frac2 As Single
Dim lat_base As Single
Dim long_base As Single
Dim lat_dest As Single
Dim long_dest As Single
Dim bearing As Single
rad_deg_factor = 360 / (2 * pi())
long_diff = (long_base_deg - long_dest_deg) / rad_deg_factor
lat_base = lat_base_deg / rad_deg_factor
lat_dest = lat_dest_deg / rad_deg_factor
frac0 = Sin(lat_base) * Sin(lat_dest) _
+ Cos(lat_base) * Cos(lat_dest) _
* Cos(long_diff)
bearing = rad_deg_factor * Application.WorksheetFunction.Acos((Sin(lat_dest) _
- Sin(lat_base) * frac0) _
/ (Cos(lat_base) * Sin(WorksheetFunction.Acos(frac0))))
If Sin(long_diff) < 0 Then
BearingFromCoord = bearing
Else
BearingFromCoord = 360 - bearing
End If
End Function
Private Function pi() As Single
pi = 3.1415926535
End Function

Ceiling function in Access

How to create a Ceiling Function in MS access that behaves the same as the one in Excel?
Since Int() seems to work like Floor(), you can get Ceiling like this:
-Int(-x)
This answer uses VBA for Access, and is derived from http://www.tek-tips.com/faqs.cfm?fid=5031:
Public Function Ceiling(ByVal X As Double, Optional ByVal Factor As Double = 1) As Double
' X is the value you want to round
' Factor is the optional multiple to which you want to round, defaulting to 1
Ceiling = (Int(X / Factor) - (X / Factor - Int(X / Factor) > 0)) * Factor
End Function
Note that this answer is mathematically correct for negative X. See http://en.wikipedia.org/wiki/Floor_and_ceiling_functions#Spreadsheet_software for background.
Thanks, marg, for the answer. For future reference, here is the VBA function that I wrote after importing the Microsoft Excel Object Library:
Public Function Ceiling(Value As Double, Significance As Double) As Double
Ceiling = Excel.WorksheetFunction.Ceiling(Value, Significance)
End Function
Then in my query, I was trying to calculate billable hours from actual time worked, rounding up to the next quarter hour:
SELECT Ceiling(([WorkTimes]![EndTime]-[WorkTimes]![BeginTime])*24,0.25) AS BillableTime
FROM WorkTimes;
You can add a Reference to the Microsoft Excel Object Library and use Excel.WorksheetFunction.Ceiling
While this question specifically asked for Access here is the answer for VB.NET
Public Function Ceiling(ByVal value As Double, ByVal factor As Double) As Double
Return Math.Ceiling(value / factor) * factor
End Function
And the answer in C#
public double Ceiling(double value, double factor)
{
return Math.Ceiling(value / factor) * factor;
}
I'm posting it here because I needed such a function google sent me to this question but I couldn't find an answer for .Net. I finally figured it out for myself.

Find distance between two cities in Excel using Google Maps API

I would like a table of the following form:
Point A Point B Mileage
Los Angeles Miami 292100
Palo Alto San Francisco 90
I was hoping to use Google Maps or some other geo api to generate mileage based on input cities dynamically. Any ideas on how to do this?
UPDATE It looks like I could use the getDistance() function in GDirections. I could write JavaScript without too much difficulty to do this, but how would I incorporate that into Excel?
I could put the JS in an html file that takes a query string and returns the distance of the route. Then, I could set Excel up to use that connection. Or is that an excessive amount of work? And hasn't something like this been done before?
So, you can use Google's API to get a latitude and longitude for each point (maybe in your case, you just want any point in those cities). Then you can use the Halversine distance formula:
http://en.wikipedia.org/wiki/Haversine_formula
For VBA, I have this function in my library that I got from somewhere. On first glance, it looks right and it yields the distance in kilometers (just convert it to miles for your purpose).
Public Function HaversineDistance(ByVal Lat1 As Double, _
ByVal Lat2 As Double, _
ByVal Long1 As Double, _
ByVal Long2 As Double) As Double
Const R As Integer = 6371 'earth radius in km
Dim DeltaLat As Double, DeltaLong As Double
Dim a As Double, c As Double
Dim Pi As Double
On Error GoTo ErrorExit
Pi = 4 * Atn(1)
'convert Lat1, Lat2, Long1, Long2 from decimal degrees into radians
Lat1 = Lat1 * Pi / 180
Lat2 = Lat2 * Pi / 180
Long1 = Long1 * Pi / 180
Long2 = Long2 * Pi / 180
'calculate change in Latitude and Longitude
DeltaLat = Abs(Lat2 - Lat1)
DeltaLong = Abs(Long2 - Long1)
a = ((Sin(DeltaLat / 2)) ^ 2) + (Cos(Lat1) * Cos(Lat2) * ((Sin(DeltaLong / 2)) ^ 2))
'c = 2 * Application.WorksheetFunction.Atan2(Sqr(a), Sqr(1 - a)) 'expressed as radians
c = 2 * Application.WorksheetFunction.Atan((Sqr(1 - a)) / (Sqr(a)))
HaversineDistance = R * c
ErrorExit:
End Function
(Note to other commenters, I'm not interested in hearing about how such accuracy is unnecessary so please don't bother tell me!)
Google currently only provide legal access to driving distances through the client side APIs (Javascript and Flash). Even if they ever do get round to implementing Issue 235: Get driving directions via HTTP , it would still be against Google's Terms (para 10.12) to use the data for purposes other than display on a Google Map.

Resources