-
Notifications
You must be signed in to change notification settings - Fork 2
/
GeoHash.Encode.sql
59 lines (50 loc) · 1.53 KB
/
GeoHash.Encode.sql
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
CREATE OR REPLACE FUNCTION GEOHASH_ENCODE (latitude in number, longitude in number, precision in number:=5) RETURN VARCHAR2 AS
even boolean := true;
bit number := 0;
ch number := 0;
mid number := 0.0;
geohash varchar2(20) := '';
TYPE varchar2_table IS TABLE OF VARCHAR2(12);
Base32 varchar2_table;
TYPE number_table IS TABLE OF NUMBER;
lat number_table;
lon number_table;
Bits number_table;
FUNCTION bitor( x IN NUMBER, y IN NUMBER ) RETURN NUMBER AS
BEGIN
RETURN x + y - bitand(x,y);
END;
BEGIN
lat := number_table(-90.0, 90.0);
lon := number_table(-180.0, 180.0);
Bits := number_table(16, 8, 4, 2, 1);
Base32 := varchar2_table('0','1','2','3','4','5','6','7','8','9','b','c','d','e','f','g','h','j','k','m','n','p','q','r','s','t','u','v','w','x','y','z');
while (nvl(length(geohash),0) < precision) loop
if (even) then
mid := (lon(0+1) + lon(1+1)) / 2;
if (longitude > mid) then
ch := bitor(ch, Bits(bit+1));
lon(0+1) := mid;
else
lon(1+1) := mid;
end if;
else
mid := (lat(0+1) + lat(1+1)) / 2;
if (latitude > mid) then
ch := bitor(ch, Bits(bit+1));
lat(0+1) := mid;
else
lat(1+1) := mid;
end if;
end if;
even:=not even;
if (bit<4) then
bit:=bit+1;
else
geohash:=geohash||Base32(ch+1);
bit:=0;
ch:=0;
end if;
end loop;
RETURN geohash;
END GEOHASH_ENCODE;