<?php ## -*- PHP -*- ##
#
# THE BEGIN COMMENTS ARE IN FINNISH AND IN ENGLISH
#
# ### FINNISH FINNISH FINNISH FINNISH FINNISH ####
#
# Maidenhead ruudukko on määritelty WGS84:n kuvaamalle
# globaalille koordinatistolle ja se vuorottelee
# pituusastetta ja leveysastetta koodaavia merkkejä
# pareittain. ("PiLePiLePiLe...")
#
# Koodattaessa myös kantaluku vaihtelee.
# Ensimmäinen pari koodaa kantaluvulla 18 ja merkkeinä
# kirjaimet 'A'..'R'. Toinen koodaa kantaluvulla 10
# ja numeroilla ('0'..'9'). Kolmas koodaa kantaluvulla
# 24 kirjaimilla 'A'..'X'. Neljäs on kuten toinen ja
# viides on kuten kolmas.
#
# Radioamatöörit käyttävät tätä ruudukkoa kilpailu-
# toiminnassaan kertoen kuinka kaukana toisistaan he
# ovat. HF taajuuksilla käytetään 4 merkin tarkkuutta
# (KP30), VHF:llä yleensä 6:tta merkkiä (KP30CR), mutta
# on joitain erityistarpeita joilla tarvitaan tarkempaa
# tietoa (jos ollenkaan käytetään Maidenheadia).
# IARU Region 1 on määritellyt Brittien RSGB:n esityksestä
# 8 merkkisen "extended locator":n (KP30CR56), mutta siitä
# eteenpäin ei ole mitään määrityksiä ja käytetty menetelmä
# on vain omaa fantasiaani...
#
# Merkkejä leveysasteen koko Pituusasteen koko
# 4 1° 111 km 2°
# 6 2.5' / 2'30" 4.6 km 5.0' / 5'00"
# 8 0.25' / 0'15" 462 m 0.5' / 0'30"
# 10 0.625" 19.3 m 1.25"
# 12 0.063" 1.9 m 0.125"
#
# Pituusasteen (itä-länsi) lineaarinen pituus suhtautuu
# leveysasteen annettuun pituuteen kertoimella: ``cos(leveysaste)''
#
# KOODI OLETTAA ASCII-MERKISTÖN KÄYTTÖÄ (joskin olisi
# suhteelisen helppo muuntaa merkistöriippumattomaksi)!
#
#
# ### ENGLISH ENGLISH ENGLISH ENGLISH ENGLISH ###
#
# The Maidenhead grid is defined on WGS84 (it being only
# GLOBAL grid), and it uses intermixed Longitude/Latitude
# character pairs. ("LoLaLoLaLoLa...")
#
# Base series vary also. First pair uses base 18,
# and encodes as characters from 'A' thru 'R'.
# Second pair uses base 10 and encoded as digit.
# Third pair uses base 24 and encoded as 'A' thru 'X'.
# Fourth pair is same as second, and the fift
# pair is same as third.
#
# The radio-amateurs use this grid in their competitions
# to figure out how far from each they are. At the HF-
# frequencies 4 character codes are used (KP30), at VHF
# usually 6 characters (KP30CR) are sufficient, but some
# special needs may need more fine-grained locators.
# IARU Region 1 has defined after British RSGB proposal
# 8 character "extended locator" system (KP30CR56), but
# beyond that there are no definitions, and what I use
# here is purely my own fantacy.
#
# Characters Latitudal size Longitudal size
# 4 1° 111 km 2°
# 6 2.5' / 2'30" 4.6 km 5.0' / 5'00"
# 8 0.25' / 0'15" 462 m 0.5' / 0'30"
# 10 0.625" 19.3 m 1.25"
# 12 0.063" 1.9 m 0.125"
#
# Longitudal linear size relates to Latitudal size by
# factor ``cos(Latitude)''.
#
#
# CODE ASSUMES ASCII (OR EQUIVALENT) CHARACTER CODING,
# although it should be easy to support also e.g. EBCDIC.
#
#
# Convert WGS84-La/Lo to Maidenhead grid coordinates
# Input: LaLo[Lo] = Longitude, East positive, radians (+- Pi )
# LaLo[La] = Latitude, North positive, radians (+- Pi/2)
# Output: String, 12 chars
#
function LaLo_to_maidenhead($LaLo) {
# PHP4.x defines M_PI = Pi (3.1415926...), M_PI_2 = M_PI / 2
$La = ($LaLo[La] + M_PI_2) / M_PI;
$Lo = ($LaLo[Lo] + M_PI) / (M_PI * 2);
$La += 0.000000000000001;
$Lo += 0.000000000000001;
# Above the +- angles have been converted into 0..1 range for
# the full value ranges, including offsetting the zero to 0.5.
$MH = "";
$La = 18.0 * ($La - floor($La));
$Lo = 18.0 * ($Lo - floor($Lo));
$MH .= sprintf("%c%c", 65+(int)floor($Lo), 65+(int)floor($La));
#printf(" MH conv1 Lo %2.7f La %2.7f\n", $Lo, $La);
for ($i = 0; $i < 4; ++$i) {
$La = 10.0 * ($La - floor($La));
$Lo = 10.0 * ($Lo - floor($Lo));
$MH .= sprintf("%d%d", (int)floor($Lo), (int)floor($La));
#printf(" MH conv%d Lo %2.7f La %2.7f\n", 1+$i+$i, $Lo, $La);
$La = 24.0 * ($La - floor($La));
$Lo = 24.0 * ($Lo - floor($Lo));
$MH .= sprintf("%c%c", 65+(int)floor($Lo), 65+(int)floor($La));
#printf(" MH conv%d Lo %2.7f La %2.7f\n", 2+$i+$i, $Lo, $La);
}
return $MH;
}
#
# Input: $str Maidenhead grid locator string
# Output: $MH[La] Most precise grid square midpoint Latitude
# that given input was able to encode, IN RADIANS
# $MH[Lo] Most precise grid square midpoint Longitude
# that given input was able to encode, IN RADIANS
# $MH[dLa] Half of achieved grid square height, IN RADIANS
# $MH[dLo] Half of achieved grid square width, IN RADIANS
#
function parsemaidenhead($Str) {
$delta = 1.0; # One full value range is 0.0 thru 1.0
$str = strtoupper($Str);
$BADINPUT = 0;
$Lat = 0.0;
$Long = 0.0;
while (1) {
# First character pair, alphabets, base 18
$LO = substr($str,0,1);
$LA = substr($str,1,1);
$str = substr($str,2);
# printf("1st pair: LO='%s' LA='%s' rest='%s'\n",$LO,$LA,$str);
if ($LO == "" || $LA == "") break;
if (!strstr("ABCDEFGHIJKLMNOPQR",$LO) ||
!strstr("ABCDEFGHIJKLMNOPQR",$LA)) {
$BADINPUT = 1;
# echo("BAD INPUT\n");
break;
}
$lo = ord($LO) - ord('A');
$la = ord($LA) - ord('A');
$delta = $delta / 18.0;
$Lat += $delta * $la;
$Long += $delta * $lo;
while ($str && !$BADINPUT) {
# 2nd/4th/6th pair, digits, base 10
$LO = substr($str,0,1);
$LA = substr($str,1,1);
$str = substr($str,2);
# printf("even pair: LO='%s' LA='%s' rest='%s'\n",$LO,$LA,$str);
if ($LO == "" || $LA == "" ||
!strstr("0123456789",$LO) ||
!strstr("0123456789",$LA)) {
$BADINPUT = 1;
# echo("BAD INPUT\n");
break;
}
$lo = ord($LO) - ord('0');
$la = ord($LA) - ord('0');
$delta = $delta / 10.0;
$Lat += $delta * $la;
$Long += $delta * $lo;
if ($str == "") { break; }
# 3rd/5th/7th pair, alphabets, base 24
$LO = substr($str,0,1);
$LA = substr($str,1,1);
$str = substr($str,2);
# printf("odd pair: LO='%s' LA='%s' rest='%s'\n",$LO,$LA,$str);
if ($LO == "" || $LA == "" ||
!strstr("ABCDEFGHIJKLMNOPQRSTUVWX",$LO) ||
!strstr("ABCDEFGHIJKLMNOPQRSTUVWX",$LA)) {
$BADINPUT = 1;
# echo("BAD INPUT\n");
break;
}
$lo = ord($LO) - ord('A');
$la = ord($LA) - ord('A');
$delta = $delta / 24.0;
$Lat += $delta * $la;
$Long += $delta * $lo;
}
break;
}
if ($BADINPUT) return 0;
# Output: $MH[La] Most precise grid square midpoint Latitude
# that given input was able to encode, IN RADIANS
# $MH[Lo] Most precise grid square midpoint Longitude
# that given input was able to encode, IN RADIANS
# $MH[dLa] Half of achieved grid square height, IN RADIANS
# $MH[dLo] Half of achieved grid square width, IN RADIANS
#
# printf("MH La = %3.7f Lo = %3.7f delta = %1.9f\n",
# 180*$Lat-90, 360*$Long-180, 180*$delta);
$MH[dLa] = $delta * M_PI * 0.5;
$MH[dLo] = $delta * M_PI;
$MH[La] = ($Lat - 0.5) * M_PI + $MH[dLa];
$MH[Lo] = ($Long - 0.5) * M_PI * 2.0 + $MH[dLo];
$MH[MH] = strtoupper($Str);
return ($MH);
}
#
# Matti Aarnio - OH2MQK <matti.aarnio@zmailer.org>
# This is part of one of tools at http://www.viestikallio.fi/tools/
#
if ($_REQUEST["SOURCE"] != "" || $_REQUEST["source"] != "") {
printf("\n<FONT SIZE=1>\n");
# highlight_file("maidenheadfuncs.php");
show_source("maidenheadfuncs.php");
printf("</FONT><P><HR><P>\n");
include("../include/sign-oh2mqk.inc");
printf("<P></TR></TABLE>\n");
include("../include/base.inc");
include("../include/foot.inc");
exit;
}
?>
Matti Aarnio <matti.aarnio@zmailer.org>; OH2MQK