Brian Ray's Blog

Painting is just another way of keeping a diary. --Picasso

Thu, 01 Dec 2005

Computer Lessons

7 weeks is not too young for Maura's first computer lesson:

http://brianray.chipy.org/Maura/mra.jpg

Snakes and more Snakes

Wow, already 122 people have RSVP'd for the Snakes and Rubies conference we are throwing this weekend here in Chicago. And who voted PyCon should not be held in Chicago? Tsk Tsk.

Good job Chipy organizers!


Calculating Longitude/Latitude Distances in SQL

It has been a long time since the "calculating distance on earth" debate. In fact, I was only able to find some notes.

Although, somebody asked for an equivalent in TSQL. I could not do this because I do not have access to this type of database server. Although, I am running PostgreSQL in a couple of locations and dug up this stored procedure (in plpgsql):

CREATE OR REPLACE FUNCTION zip_distance(integer, integer) returns float4 as '
 DECLARE
   zip1                alias for $1;
   zip2                alias for $2;
   v_zip1               integer;
   v_zip2               integer;
   longitude1          float8;
   latitude1           float8;
   longitude2          float8;
   latitude2           float8;
   delta_lon           float8;
   delta_lat           float8;
   temp                float8;
   dist                float4;
 BEGIN
   v_zip1 := zip1 ;
   while longitude1 IS NULL LOOP
      SELECT longitude_rad, latitude_rad INTO longitude1, latitude1 FROM zip_loc WHERE zip_code = v_zip1;
      v_zip1 := v_zip1 + 1;
   END LOOP;      

   v_zip2 := zip2 ;
   WHILE longitude2 IS NULL LOOP
      SELECT longitude_rad, latitude_rad INTO longitude2, latitude2 FROM zip_loc WHERE zip_code = v_zip2;
      v_zip2 := v_zip2 + 1;
   END LOOP;

   delta_lon := longitude2 - longitude1;
   delta_lat := latitude2 - latitude1;

   temp := pow(      sin(delta_lat/2.0::float8), 2.0::float8) 
            + cos(latitude1) 
            * cos(latitude2) 
            * pow(   sin(delta_lon/2.0::float8), 2.0::float8);

   dist := (3956 
         * 2 
         * atan2( sqrt(temp),sqrt(1 - temp)) )::float4;

   return dist::float4 ;

 END;
' language 'plpgsql';

zip_loc was a lookup table of zipcode longitude and latitudes. Actually, the final code used databases from US Census along with a modified version of the above (rewritten in Python), to find distances between street addresses. Also this data may have been cross referenced with USPS data. I no longer work on this project although I believe it is still in use.

If I remember correctly, this equation got me in some trouble with my meteorologist friends, Michael Tobis. Still, it's crazy fast and does the trick.