relicence under MirOS Licence, granted by private deal with the CTO
[shellsnippets/shellsnippets.git] / mksh / maidenhead
1 #!/bin/mksh
2 #-
3 # Copyright © 2014, 2015
4 #       Thorsten “mirabilos” Glaser <tg@mirbsd.org>
5 #
6 # Provided that these terms and disclaimer and all copyright notices
7 # are retained or reproduced in an accompanying document, permission
8 # is granted to deal in this work without restriction, including un‐
9 # limited rights to use, publicly perform, distribute, sell, modify,
10 # merge, give away, or sublicence.
11 #
12 # This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
13 # the utmost extent permitted by applicable law, neither express nor
14 # implied; without malicious intent or gross negligence. In no event
15 # may a licensor, author or contributor be held liable for indirect,
16 # direct, other damage, loss, or other issues arising in any way out
17 # of dealing in the work, even if advised of the possibility of such
18 # damage or existence of a defect, except proven that it results out
19 # of said person’s immediate fault when using the work as intended.
20 #-
21 # Parse a Maidenhead Grid (Maidenhead Locator System) code ⇒ lat/lon
22
23 typeset -u code=$1
24
25 if [[ $code != [A-R][A-R]?([0-9][0-9]?([A-X][A-X]?([0-9][0-9]?([A-X][A-X]?([0-9][0-9]))))) ]]; then
26         # maybe later for the other conversion direction?
27         print -ru2 "E: not a Maidenhead Grid geocode: $code"
28         exit 1
29 fi
30
31 # from MirKarte
32 function decmin2min {
33         local x=${1#.}0000000
34         typeset -i10 -Z9 y
35
36         x=${x::7}
37         (( y = x * 60 ))
38
39         REPLY=${y::2}.${y:2}
40 }
41
42 # from MirKarte
43 function decmin2txt {
44         local graticule=$1 decimal=$2 plus=$3 minus=$4 places=$5 x
45         typeset -i10 -Z$places n
46
47         if [[ $graticule = -* ]]; then
48                 REPLY=$minus
49         else
50                 REPLY=$plus
51         fi
52         n=${graticule#-}
53         REPLY+=" ${n}° "
54
55         x=${|decmin2min $decimal;}
56         typeset -i10 -Z2 n=${x%.*}
57         x=${x#*.}
58         typeset -i10 -Z4 m=${x::4}
59         if (( ${x:4:1} >= 5 )); then
60                 if (( ++m > 9999 )); then
61                         (( ++n ))
62                         m=0
63                 fi
64         fi
65         REPLY+=$n.$m
66 }
67
68 lats=
69 lons=
70
71 function divlatlon {
72         local fac=$1 lat=$2 lon=$3
73
74         if [[ -n $lats ]]; then
75                 lats="($lats)/$fac+$lat"
76                 lons="($lons)/$fac+$lon"
77         else
78                 lats=".5+$lat"
79                 lons=".5+$lon"
80         fi
81 }
82
83 function dolatlon {
84         local olat="$1-1" olon="$1-2" osiz=$2 fac=$3
85
86         divlatlon $fac $((1#${code:$olat:1} - $osiz)) \
87             $((1#${code:$olon:1} - $osiz))
88 }
89
90 case ${#code} {
91 (12)
92         dolatlon 12 1#0 24
93         ;&
94 (10)
95         dolatlon 10 1#A 10
96         ;&
97 (8)
98         dolatlon 8 1#0 24
99         ;&
100 (6)
101         dolatlon 6 1#A 10
102         ;&
103 (4)
104         dolatlon 4 1#0 24
105         ;&
106 (2)
107         dolatlon 2 1#A 10
108         ;&
109 }
110 divlatlon 18 '(-.5)' '(-.5)'
111 print -ru2 -- "↑ $lats"
112 print -ru2 -- "→ $lons"
113 print "scale=20\n($lats)*180\n($lons)*360" | bc |&
114 read -p lat
115 read -p lon
116 print ": $lat / $lon"
117 lattxt=${|decmin2txt ${lat%.*} .${lat#*.} N S 2;}
118 lontxt=${|decmin2txt ${lon%.*} .${lon#*.} E W 3;}
119 print -r -- "$lattxt $lontxt"