## 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)