-
Notifications
You must be signed in to change notification settings - Fork 16
/
geo3x3.kk
80 lines (61 loc) · 1.81 KB
/
geo3x3.kk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
module geo3x3
import std/num/float64
pub fun geo3x3_encode (lat : float64, lng : float64, level: int) : div string
fun f ()
val (c,lng'') = if lng >= 0.0 then ('E',lng)
else ('W',lng + 180.0)
var lng' := lng''
var lat' := lat + 90.0
var unit := 180.0
var res := ""
fun loop (i : int)
if i < level then
unit := unit / 3.0
val x = int(floor (lng' / unit))
val y = int(floor (lat' / unit))
val c' = char ((int('0')) + x + y * 3 + 1)
lng' := lng' - float64(x) * unit
lat' := lat' - float64(y) * unit
res := res ++ string (c')
loop (i+1)
else ()
res := res ++ string (c)
loop(1)
res
if level < 0 then "" else f()
pub fun geo3x3_decode (code : string) : div (float64, float64, int, float64)
fun f ()
val (begin,isWest) =
match head-char(code)
Just ('-') -> (1,True)
Just ('W') -> (1,True)
Just ('+') -> (1,False)
Just ('E') -> (1,False)
_ -> (0,False)
var unit := 180.0
var lat := 0.0
var lng := 0.0
var level := 1
val clen = code.count
fun loop (i : int)
if i < clen then
val n = match code.first.advance(i).string.head-char
Just (c) -> int(c) - int('0')
_ -> 0
if 1 <= n && n <= 9 then
val n' = n - 1
unit := unit / 3.0
lng := lng + (float64 (n' % 3)) * unit
lat := lat + (float64 (n' / 3)) * unit
level := level + 1
loop (i+1)
else ()
else ()
loop (begin)
lat := lat + unit / 2.0
lng := lng + unit / 2.0
val lat' = lat - 90.0
val lng' = if isWest then lng - 180.0 else lng
(lat', lng', level, unit)
if is-empty(code) then (0.0, 0.0, 0, 0.0)
else f()