Saturday, April 22, 2006
Can Keith come out and play...?
Spring has been very mild this year, and everything is way ahead of normal. I already saw some fruit trees in bloom. The birds, well they do what comes naturally this time of year. They're all lovy-dovy. Just check out these mourning doves who where carrying on (and all now) in the crab apple tree up front.
The hours around dawn and dusk are what photographers call the magic hour, since that's when the light plays tricks on our eyes with its softness and long shadows. At that time, I love to take a walk to deep in the back yard, and then just stand there, looking back. Usually this time of year there is little wind then, so everything is so still and quiet, except for the cardinals singing their majestic song. Spine tingling/bone chilling. Here's the shot from way back there. I tried to record the cardinals' song, but I'm going to have to run out to Radio Shack to git me a microphone pre-amp, as it just wasn't loud enough. You really do need to see the larger version of this shot to even remotely get an idea as to what I'm talking about.
Then I took a walk in the forest, and lo and behold, I saw a trillium in bloom! In April! Most of our trilliums are red, white ones are somewhat rare around here for whatever reason.
On the way back out from taking this picture, I almost tripped over a rusted-out-long-ago-abandoned oil filter. Damn!
Thursday, April 13, 2006
Now I'm good 'n mad...
... because this freakin' male red bellied woodpecker keeps visiting the bird feeder and I just cannot get a decent shot of him. This is about the best I could do today, but I'll get him, I'll get him in the end, oh yes I will (name that tune?)
Today's White Thursday, but I presume this doesn't mean a whole heck of a lot to too many people out there. To me, it conjures up images of being liberated from school for 2 weeks (Easter vacation), daffodils in bloom, selling cheese to fat Germans driving mid sixties Volkswagen beetles, eating hard boiled eggs (and lots of them).
The odd year White Thursday coincides with my birthday. And so it was in 1959. I remember getting a soccer ball as the main present. Actually, calling it a soccer ball is a bit of an exaggeration, since it was a cheap plastic ball, oblong to boot (pun intended). It also sprung a leak about a week after I got it. Lo and behold, it was replaced with a better version! Woohoo!
Still in all, happy memories. Or should I say bittersweet?
Birthday Girl
It is only my personal opinion, and therefore easily dismissable, but I do believe she is going to be a genius in languages, as already she is saying 'bye bye', 'thank you' in a quite audible manner. Of course, languages are not necessarily restricted to human communication only... I mean, what would you call Visual FoxPro?
Tuesday, April 04, 2006
Latitude/Longitude Conversion to UTM in Visual FoxPro
And now, for something completely different:
A friend of mine works for Rogers Communications, a huge cable company in this part of Canada. He's involved in 'plant': that part of the business that deals with physical assets in the field i.e. the location of swith boxes, cables, routers, switches, hubs and the like. He wanted to know if I knew anything about conversion from latitude/longitude to UTM (Universal Transverse Mercator) Coordinate System. I said I didn't and we left it at that.
But then for fun I got poking around on the web and found a version in PHP done by Jim Studnicki. He, in turn, had translated this from a function originally written in C by Jef Poskanzer. I spent some time converting Jim's PHP version to Visual FoxPro and after the usual minor problems I got it to work. I must say this is the first time I used the DTOR() (degrees to radians) function in VFP. (not that function is hard to mimic otherwise: pi/180).
Anyway, here it is. It ain't pretty, but if you need it, you can fix it up yourself. Once you have it up and running in VFP, test the results against any of the UTM conversion calculators on the web to verify your results.
Hopefully it can help some other VFP developer in the future. This is what is so absolutely fabulous about the web: the free sharing of information. Ten years ago, getting an answer to this would have been a real problem. Now, anybody with half a brain can do this.
*Keith Hekker 2006-04-02
*Translated from a PHP function by Jim Studnicki
=ConvertToUTM(43,-80)
Procedure ConvertToUTM()
PARAMETERS Latitude, Longitude
* convert decimal geographic coordinates to UTM
*
* param latitude as decimal
* param longitude as decimal
cOldDecimals = SET("DECIMALS")
SET DECIMALS TO 6
* square of eccentricity of equatorial cross-section
ECCENTRICITY_SQUARED = 0.00669437999013
* eccentricity prime squared
ECC_PRIME_SQUARED = ECCENTRICITY_SQUARED /;
(1.0 - ECCENTRICITY_SQUARED)
* radius of Earth in meters
EQUATORIAL_RADIUS = 6378137.0
* scale factor
K0 = 0.9996
* make sure longitude is between -180 and 180
IF longitude < -180.0
longitude = longitude + 360.0
ENDIF
IF longitude > 180.0
longitude = longitude + 360.0
ENDIF
* get UTM letter
DO CASE
CASE latitude <= 84.0 and latitude >= 72.0
utmLetter = "X"
CASE latitude < 72.0 and latitude >= 64.0
utmLetter = "W"
CASE latitude < 64.0 and latitude >= 56.0
utmLetter = "V"
CASE latitude < 56.0 and latitude >= 48.0
utmLetter = "U"
CASE latitude < 48.0 and latitude >= 40.0
utmLetter = "T"
CASE latitude < 40.0 and latitude >= 32.0
utmLetter = "S"
CASE latitude < 32.0 and latitude >= 24.0
utmLetter = "R"
CASE latitude < 24.0 and latitude >= 16.0
utmLetter = "Q"
CASE latitude < 16.0 and latitude >= 8.0
utmLetter = "P"
CASE latitude < 8.0 and latitude >= 0.0
utmLetter = "N"
CASE latitude < 0.0 and latitude >= -8.0
utmLetter = "M"
CASE latitude < -8.0 and latitude >= -16.0
utmLetter = "L"
CASE latitude < -16.0 and latitude >= -24.0
utmLetter = "K"
CASE latitude < -24.0 and latitude >= -32.0
utmLetter = "J"
CASE latitude < -32.0 and latitude >= -40.0
utmLetter = "H"
CASE latitude < -40.0 and latitude >= -48.0
utmLetter = "G"
CASE latitude < -48.0 and latitude >= -56.0
utmLetter = "F"
CASE latitude < -56.0 and latitude >= -64.0
utmLetter = "E"
CASE latitude < -64.0 and latitude >= -72.0
utmLetter = "D"
CASE latitude < -72.0 and latitude >= -80.0
utmLetter = "C"
OTHERWISE
* returns "Z" if the latitude is outside the UTM limits of 84N to 80S
utmLetter = "Z" *
ENDCASE
lat_rad = DTOR(latitude)
long_rad = DTOR(longitude)
zone = INT((longitude + 180) / 6) + 1
IF latitude >= 56.0 and latitude < 64.0;
and longitude >= 3.0 and longitude < 12.0
zone = 32
ENDIF
* Special zones for Svalbard.
IF latitude >= 72.0 and latitude < 84.0
DO CASE
CASE longitude >= 0.0 and longitude < 9.0
zone = 31
CASE longitude >= 9.0 and longitude < 21.0
zone = 33
CASE longitude >= 21.0 and longitude < 33.0
zone = 35
CASE longitude >= 33.0 and longitude < 42.0
zone = 37
ENDCASE
ENDIF
* +3 puts origin in middle of zone
long_origin = (zone - 1) * 6 - 180 + 3
long_origin_rad = DTOR(long_origin)
N = EQUATORIAL_RADIUS / sqrt(1.0 - ECCENTRICITY_SQUARED *;
sin(lat_rad) * sin(lat_rad))
T = tan(lat_rad) * tan(lat_rad)
C = ECC_PRIME_SQUARED * cos(lat_rad) * cos(lat_rad)
A = cos(lat_rad) * (long_rad - long_origin_rad)
M = EQUATORIAL_RADIUS *;
((1.0 - ECCENTRICITY_SQUARED / 4 - 3 * ;
ECCENTRICITY_SQUARED * ECCENTRICITY_SQUARED / 64 - 5 *;
ECCENTRICITY_SQUARED * ECCENTRICITY_SQUARED *;
ECCENTRICITY_SQUARED / 256) * lat_rad - (3 * ;
ECCENTRICITY_SQUARED / 8 + 3 * ECCENTRICITY_SQUARED *;
ECCENTRICITY_SQUARED / 32 + 45 * ECCENTRICITY_SQUARED *;
ECCENTRICITY_SQUARED * ECCENTRICITY_SQUARED / 1024) * ;
sin(2 * lat_rad) + (15 * ECCENTRICITY_SQUARED *;
ECCENTRICITY_SQUARED / 256 + 45 * ECCENTRICITY_SQUARED *;
ECCENTRICITY_SQUARED * ECCENTRICITY_SQUARED / ;
1024) * sin(4 * lat_rad) - (35 * ECCENTRICITY_SQUARED *;
ECCENTRICITY_SQUARED * ECCENTRICITY_SQUARED / 3072) *;
sin(6 * lat_rad))
easting = K0 * N * (A + (1 - T + C) * A * A *;
A / 6 + (5 - 18 * T + T * T + 72 * C - 58 *;
ECC_PRIME_SQUARED) * A * A * A * A * A / 120) + 500000.0
northing = K0 * (M + N * tan(lat_rad) *;
(A * A / 2 + (5 - T + 9 * C;
+ 4 * C * C) * A * A * A * A / 24;
+ (61 - 58 * T + T * T + 600 * C -;
330 * ECC_PRIME_SQUARED) * A * A * A * A * A * A / 720))
IF latitude < 0.0
* 1e7 meter offset for southern hemisphere
northing = northing + 10000000.0
north = .F.
ELSE
north = .T.
ENDIF
? "Easting = " + TRANSFORM(easting)
? "Northing = " + TRANSFORM(northing)
? "North = " + TRANSFORM(north)
? "Zone = " + TRANSFORM(zone)
? "UTM Letter = " + TRANSFORM(utmletter)
SET DECIMALS TO &cOldDecimals
RETURN
Saturday, April 01, 2006
Fun With Numbers
The incredible forces of Mother Nature have always intrigued me. Consider this for a minute:
Yesterday, we had a rain storm across Norfolk County. It was the usual scenario, one that has been playing itself out for thousands or years and will continue to do so for at least the foreseeable future, climate change notwithstanding.
It had been a warm day, up to a maximum of 21 C. It rained moderately for a couple of hours just before a cold front swept through, dropping the temperature behind it to 10 C. According to the Environment Canada website, 12 mm of rain fell at Delhi, just down the road. No big deal, it happens all the time.
Where things get interesting is when you start looking at the numbers. The area of Norfolk County is 1,609.95 square kilometres, about 2.5 times that of the City of Toronto at 661 square kilometres. Assuming that the rain fell evenly across Norfolk County, we do the calculation for the total volume of rain in cubic metres as follows:
1,609.95 x 1,000 x 1,000 x .012 = 19,283,400 cubic freakin' metres!
Yes, that is right, more than 19 million cubic meters. If one were to lay these end-to-end, the wall of water, 1 metre high and 1 metre wide, would reach halfway around the world, before it would run out.
Now, let's take this one step further. That water just didn't happen to get there on its own. It had to evaporate from the ocean to get here. In yesterday's case, it most likely came from the Gulf of Mexico. OK, it takes 600 calories to evaporate 1 gram of water, so that's 600,000 calories for 1 litre or 600,000,000 (600 million) for 1 cubic metre.
This is where it gets really handy to have the Command Window of Visual FoxPro handy, as the numbers get so large, it's easy to lose track. (Even handier to have the _CLIPTEXT system variable available). To evaporate all that water
19,283,400 x 600,000,000 = 11,570,040,000,000,000 calories are needed
Sorry, but I don't know how to pronounce that number. Nevertheless, we carry on. We convert this number to Joules. By the way, 1 Joule is about the equivalent to the amount of energy you expend when you lift a small apple 1 metre off the ground.
11,570,040,000,000,000 calories = 48,409,047,360,000,010 Joules
Now, although a beautiful unit of the metric system in its own right, the Joule is exceedingly meaningless to most people. So let's try kW (kilowatt-hour)
48,409,047,360,000,010 Joules = 13,447,065,175 kW/hr or roughly 13.5 million Megawatt/hr
To put this into perspective, the Nanticoke Power generation station on Lake Erie generates 4,000 Megawatt/hr. It would have to run 3,361 hours (that's about 20 weeks) at full bore to generate that amount of power.
Yet another way:
48,409,047,360,000,010 Joules = 45,891,776,897,279 BTU/hr
An average house furnace is about 100,000 BTU/hr, so it would take 458,917,768 (that's 458 million) house furnaces burning solid for 1 hour to evaporate the water involved.
And I'm only talking Norfolk County!
Furthermore, I haven't even talked about the energy involved to transport the water vapor 2,000 km from the Gulf of Mexico to Norfolk County.
Some useful formulas:
1 calorie = 4.18400 joules
1 Joule = 2.7778×10−7 kilowatt-hour (or otherwise 0.00000027778 kilowatt-hour)
1 Joule = 9.48×10−4 BTU (or otherwise 0.000948 BTU)