Saturday, April 22, 2006

Can Keith come out and play...?

Sitting down at my computer in the basement, I heard a rustle in the leaves collected in the window well. This drew my curiosity, as it drew his. The stare-off was a draw: he went his way and I went mine, though not until after I had rattled off some shots on the 20D.





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

For those of you not in the know, Amaryn celebrated her first birthday last week (April 6th to be exact), blissfully unaware of the whole thing, as a 1 year old should be. She did manage to play the part though in the traditional stick-your-hand-in-the-birthday-cake-and-smear-it-all-over-your-face routine that all 1 year-olds have to undergo.

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)