ZIP Codes, Latitude/Longitude, lack of understanding.

Discussion in 'General Math' started by Michael Trausch, Mar 2, 2006.

  1. Hello everyone,

    I'd like to first apologize for the length of this post -- I'm really
    confused and I'm not even sure if I make any sense in it. Hopefully,
    somebody can make sense of this to help me, and I'd greatly appreciate it!

    I have what I would think would be a relatively simple problem to solve,
    however, I don't know how to go about solving it. At the most
    simplistic, what I need is a way, given a single ZIP code, to search for
    everything within a given radius of it.

    For example, the types of questions I want to be able to answer are
    "What ZIP codes are within a 20 mile radius of ZIP 30034?"

    Now, I've done some looking up, and the more and more I look things up
    on this subject, the more and more perplexed I become. Allow me to
    state first, that math /definitely/ isn't my strong point, and that
    might be why I'm not "grasping" it.

    What I do know is that each ZIP code "maps" to a latitude/longitude. I
    also know that there are a number of formulas out there that can compute
    the distance between (latitude 1, longitude 1) and (latitude 2,
    longitude 2). It seems that the Haversine formula is the most discussed
    and reasonably accurate, so it seems to be a reasonable choice for
    working with this data. The alternatives are all seemingly
    exponentially over my head, in addition, and this one I've been beating
    my head on the desk over for a couple of days now, anyway.

    What I don't know is:

    * How to compute distance using the Haversine formula. I was
    on a site that tries to explain such things, and where it
    would get a result of 884.2 km (about correct) for two points
    I entered, the only result I can manage to get out of the
    formula by "hand" (using GNU bc) is 11,148.534.... somethings,
    presumably kilometers, which I know is not correct.

    * How to understand the Haversine formula -- That's really
    important to me, to understand how it works before I try using
    it extensively. The point is going to be to implement it into
    a program, nonetheless, I'd like to understand it and how it
    works before I write it into the program. It probably does not
    help that I haven't the foggiest about what things like atan2,
    sin, and cos actually *do*.

    * How to determine what the input really is. The coordinates that
    I have access to are in decimal, e.g.:

    mysql> SELECT * FROM dataZipCode WHERE zipcode='43609';
    | zipcode | latitude | longitude | city | state | abbr |
    | 43609 | +41.6247490 | -083.5842340 | TOLEDO | OHIO | OH |
    1 row in set (0.00 sec)

    From what I'm reading, I see lots of discussion of "radians" and
    the like. Is that what these latitudes/longitudes are expressed

    * How to determine what the output should be. Everywhere I see
    km in use. I'm in the U.S., where we like to be very different
    from everywhere else and use miles. How retarded is that? Well,
    anyway, I can convert from miles <--> km without a problem as
    that is relatively easy. What I don't know is if any actual
    other adjustments need to be made to account for miles vs. km in
    the formula itself.

    * The formula that I have is as follows. I'm not sure if all the
    special characters will show up or not, so I've pasted it as well
    as rewritten as I understand it in plaintext.

    R = earth’s radius (mean radius = 6,371km)
    Δlat = lat2 − lat1
    Δlong = long2 − long1
    a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
    c = 2.atan2(√a, √(1−a))
    d = R.c

    R = earth's radius (6371 km)
    d_lat = lat2 - lat1
    d_long = long2 - long1
    a = sin(d_lat/2)^2 + cos(lat1)*cos(lat2)*sin(d_long/2)^2
    c = 2*atan2(sqrt(a), sqrt(1-a))
    d = R*c

    Now, as I understand things, this means that given:

    mysql> SELECT * FROM dataZipCode WHERE zipcode='30034' OR zipcode='43609';
    | zipcode | latitude | longitude | city | state | abbr |
    | 30034 | +33.6907570 | -084.2511710 | DECATUR | GEORGIA | GA |
    | 43609 | +41.6247490 | -083.5842340 | TOLEDO | OHIO | OH |
    2 rows in set (0.00 sec)


    I, according to the few places I've been, should get something around
    884.2 km (549.4 mi) as a result. However, I actually get (this is from
    GNU bc, which is the best calculator I have access to right now):

    lat1 = 33.6907570
    long1 = -084.2511710

    lat2 = 41.6247490
    long2 = -083.5842340

    d_lat = lat2-lat1
    d_long = long2-long1

    a = s(d_lat/2)^2 + c(lat1)*c(lat2)*s(d_long/2)^2
    c = 2*(a(sqrt(a)/sqrt(1-a)))
    d = 6371*c


    .... which does not appear to be correct. AFAIK, bc doesn't have atan2,
    but I read somewhere that a (which in bc is atan) works as long as you
    divide y by x instead of writing (y,x). However, the result is still
    just as invalid if I flip y and x, yielding:


    At the end of all of this, what I really need to know is what am I doing
    wrong in the formula, and if there is a mathematical way to find every
    valid latitude/longitude pair given a radius from the starting point so
    that I can just get the ranges and find the ZIP codes that are
    associated with them?

    I apologize for the probably excess verbosity. I really am confused
    here, and I just don't know what to make of it all. It's probably
    pretty obvious that I stink at this level of mathematics.

    Thanks in advance for any help,

    Michael Trausch, Mar 2, 2006
    1. Advertisements

  2. Michael Trausch

    mensanator Guest

    You need to convert latitude and longitude to radians (they're given
    in degrees) because your trig functions require radians.

    Here's a Python version.

    Note that this calculation does not take into account that the Earth
    is not a perfect sphere. Hopefully, its good enough for your purposes.
    mensanator, Mar 2, 2006
    1. Advertisements

  3. Michael Trausch

    Bill Guest

    I don't know what you mean by "everything within a given radius of it." The
    points you have are most likely the long. and lat. for the PO itself. I live
    about a mile away from my PO. and my long. & lat. would be different. There is
    another PO NE of me and another SW. (Each about 2 miles away.) You can't tell
    which zip code a given house is in without knowing the zip code boundries.
    However, you can tell whether POs themselves are within x miles of each other.

    Also, there is something called spherical geomatry which assumes the earth is
    round, not flat, and that can be important if distances are large.

    Bill, Mar 3, 2006
  4. Thank you for the reply. I've managed to tackle this formula, I think.
    I've got a UNIX bc function written that manages it quite nicely both
    finding the distance between point A and B, and giving me points to use
    as a box containing lots of addresses. Running manual SQL queries
    against my database with the resulting output gives me the data that I'm
    looking for now.

    Now my only leftover problem is that I'm having a hard time getting the
    same formulas to work in PHP. That, however, is another topic for
    another place. Since I'm only working with segments of no more then 400
    sq. miles, I don't think that the fact that the shape of the Earth is
    not a perfect sphere is going to cause me a problem for that small of a
    distance - though if I am wrong, please correct me.

    Thank you for your help!

    Take care,
    Michael Trausch, Mar 3, 2006
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.