11// geohash.js
22// Geohash library for Javascript
33// (c) 2008 David Troy
4+ // (c) 2010 Chris Williams
45// Distributed under the MIT License
56
6- BITS = [ 16 , 8 , 4 , 2 , 1 ] ;
7-
8- BASE32 = "0123456789bcdefghjkmnpqrstuvwxyz" ;
9- NEIGHBORS = { right : { even : "bc01fg45238967deuvhjyznpkmstqrwx" } ,
10- left : { even : "238967debc01fg45kmstqrwxuvhjyznp" } ,
11- top : { even : "p0r21436x8zb9dcf5h7kjnmqesgutwvy" } ,
12- bottom : { even : "14365h7k9dcfesgujnmqp0r2twvyx8zb" } } ;
13- BORDERS = { right : { even : "bcfguvyz" } ,
14- left : { even : "0145hjnp" } ,
15- top : { even : "prxz" } ,
16- bottom : { even : "028b" } } ;
17-
18- NEIGHBORS . bottom . odd = NEIGHBORS . left . even ;
19- NEIGHBORS . top . odd = NEIGHBORS . right . even ;
20- NEIGHBORS . left . odd = NEIGHBORS . bottom . even ;
21- NEIGHBORS . right . odd = NEIGHBORS . top . even ;
22-
23- BORDERS . bottom . odd = BORDERS . left . even ;
24- BORDERS . top . odd = BORDERS . right . even ;
25- BORDERS . left . odd = BORDERS . bottom . even ;
26- BORDERS . right . odd = BORDERS . top . even ;
27-
28- function refine_interval ( interval , cd , mask ) {
29- if ( cd & mask )
30- interval [ 0 ] = ( interval [ 0 ] + interval [ 1 ] ) / 2 ;
31- else
32- interval [ 1 ] = ( interval [ 0 ] + interval [ 1 ] ) / 2 ;
33- }
34-
35- function calculateAdjacent ( srcHash , dir ) {
36- srcHash = srcHash . toLowerCase ( ) ;
37- var lastChr = srcHash . charAt ( srcHash . length - 1 ) ;
38- var type = ( srcHash . length % 2 ) ? 'odd' : 'even' ;
39- var base = srcHash . substring ( 0 , srcHash . length - 1 ) ;
40- if ( BORDERS [ dir ] [ type ] . indexOf ( lastChr ) != - 1 )
41- base = calculateAdjacent ( base , dir ) ;
42- return base + BASE32 [ NEIGHBORS [ dir ] [ type ] . indexOf ( lastChr ) ] ;
43- }
44-
45- function decodeGeoHash ( geohash ) {
46- var is_even = 1 ;
47- var lat = [ ] ; var lon = [ ] ;
48- lat [ 0 ] = - 90.0 ; lat [ 1 ] = 90.0 ;
49- lon [ 0 ] = - 180.0 ; lon [ 1 ] = 180.0 ;
50- lat_err = 90.0 ; lon_err = 180.0 ;
51-
52- for ( i = 0 ; i < geohash . length ; i ++ ) {
53- c = geohash [ i ] ;
54- cd = BASE32 . indexOf ( c ) ;
55- for ( j = 0 ; j < 5 ; j ++ ) {
56- mask = BITS [ j ] ;
57- if ( is_even ) {
58- lon_err /= 2 ;
59- refine_interval ( lon , cd , mask ) ;
60- } else {
61- lat_err /= 2 ;
62- refine_interval ( lat , cd , mask ) ;
63- }
64- is_even = ! is_even ;
65- }
66- }
67- lat [ 2 ] = ( lat [ 0 ] + lat [ 1 ] ) / 2 ;
68- lon [ 2 ] = ( lon [ 0 ] + lon [ 1 ] ) / 2 ;
69-
70- return { latitude : lat , longitude : lon } ;
71- }
72-
73- function encodeGeoHash ( latitude , longitude ) {
74- var is_even = 1 ;
75- var i = 0 ;
76- var lat = [ ] ; var lon = [ ] ;
77- var bit = 0 ;
78- var ch = 0 ;
79- var precision = 12 ;
80- geohash = "" ;
81-
82- lat [ 0 ] = - 90.0 ; lat [ 1 ] = 90.0 ;
83- lon [ 0 ] = - 180.0 ; lon [ 1 ] = 180.0 ;
84-
85- while ( geohash . length < precision ) {
86- if ( is_even ) {
87- mid = ( lon [ 0 ] + lon [ 1 ] ) / 2 ;
88- if ( longitude > mid ) {
89- ch |= BITS [ bit ] ;
90- lon [ 0 ] = mid ;
91- } else
92- lon [ 1 ] = mid ;
93- } else {
94- mid = ( lat [ 0 ] + lat [ 1 ] ) / 2 ;
95- if ( latitude > mid ) {
96- ch |= BITS [ bit ] ;
97- lat [ 0 ] = mid ;
98- } else
99- lat [ 1 ] = mid ;
100- }
101-
102- is_even = ! is_even ;
103- if ( bit < 4 )
104- bit ++ ;
105- else {
106- geohash += BASE32 [ ch ] ;
107- bit = 0 ;
108- ch = 0 ;
109- }
110- }
111- return geohash ;
112- }
7+
8+ var GeoHash = ( function ( ) {
9+ BITS = [ 16 , 8 , 4 , 2 , 1 ] ;
10+
11+ BASE32 = "0123456789bcdefghjkmnpqrstuvwxyz" ;
12+ NEIGHBORS = { right : { even : "bc01fg45238967deuvhjyznpkmstqrwx" } ,
13+ left : { even : "238967debc01fg45kmstqrwxuvhjyznp" } ,
14+ top : { even : "p0r21436x8zb9dcf5h7kjnmqesgutwvy" } ,
15+ bottom : { even : "14365h7k9dcfesgujnmqp0r2twvyx8zb" } } ;
16+ BORDERS = { right : { even : "bcfguvyz" } ,
17+ left : { even : "0145hjnp" } ,
18+ top : { even : "prxz" } ,
19+ bottom : { even : "028b" } } ;
20+
21+ NEIGHBORS . bottom . odd = NEIGHBORS . left . even ;
22+ NEIGHBORS . top . odd = NEIGHBORS . right . even ;
23+ NEIGHBORS . left . odd = NEIGHBORS . bottom . even ;
24+ NEIGHBORS . right . odd = NEIGHBORS . top . even ;
25+
26+ BORDERS . bottom . odd = BORDERS . left . even ;
27+ BORDERS . top . odd = BORDERS . right . even ;
28+ BORDERS . left . odd = BORDERS . bottom . even ;
29+ BORDERS . right . odd = BORDERS . top . even ;
30+
31+ var refine_interval = function ( interval , cd , mask ) {
32+ if ( cd & mask )
33+ interval [ 0 ] = ( interval [ 0 ] + interval [ 1 ] ) / 2 ;
34+ else
35+ interval [ 1 ] = ( interval [ 0 ] + interval [ 1 ] ) / 2 ;
36+ } ;
37+
38+
39+
40+
41+
42+ return {
43+ encodeGeoHash : function ( latitude , longitude ) {
44+ var is_even = 1 ;
45+ var i = 0 ;
46+ var lat = [ ] ; var lon = [ ] ;
47+ var bit = 0 ;
48+ var ch = 0 ;
49+ var precision = 12 ;
50+ geohash = "" ;
51+
52+ lat [ 0 ] = - 90.0 ; lat [ 1 ] = 90.0 ;
53+ lon [ 0 ] = - 180.0 ; lon [ 1 ] = 180.0 ;
54+
55+ while ( geohash . length < precision ) {
56+ if ( is_even ) {
57+ mid = ( lon [ 0 ] + lon [ 1 ] ) / 2 ;
58+ if ( longitude > mid ) {
59+ ch |= BITS [ bit ] ;
60+ lon [ 0 ] = mid ;
61+ } else
62+ lon [ 1 ] = mid ;
63+ } else {
64+ mid = ( lat [ 0 ] + lat [ 1 ] ) / 2 ;
65+ if ( latitude > mid ) {
66+ ch |= BITS [ bit ] ;
67+ lat [ 0 ] = mid ;
68+ } else
69+ lat [ 1 ] = mid ;
70+ }
71+
72+ is_even = ! is_even ;
73+ if ( bit < 4 )
74+ bit ++ ;
75+ else {
76+ geohash += BASE32 [ ch ] ;
77+ bit = 0 ;
78+ ch = 0 ;
79+ }
80+ }
81+ return geohash ;
82+ } ,
83+ decodeGeoHash : function ( geohash ) {
84+ var is_even = 1 ;
85+ var lat = [ ] ; var lon = [ ] ;
86+ lat [ 0 ] = - 90.0 ; lat [ 1 ] = 90.0 ;
87+ lon [ 0 ] = - 180.0 ; lon [ 1 ] = 180.0 ;
88+ lat_err = 90.0 ; lon_err = 180.0 ;
89+
90+ for ( i = 0 ; i < geohash . length ; i ++ ) {
91+ c = geohash [ i ] ;
92+ cd = BASE32 . indexOf ( c ) ;
93+ for ( j = 0 ; j < 5 ; j ++ ) {
94+ mask = BITS [ j ] ;
95+ if ( is_even ) {
96+ lon_err /= 2 ;
97+ refine_interval ( lon , cd , mask ) ;
98+ } else {
99+ lat_err /= 2 ;
100+ refine_interval ( lat , cd , mask ) ;
101+ }
102+ is_even = ! is_even ;
103+ }
104+ }
105+ lat [ 2 ] = ( lat [ 0 ] + lat [ 1 ] ) / 2 ;
106+ lon [ 2 ] = ( lon [ 0 ] + lon [ 1 ] ) / 2 ;
107+
108+ return { latitude : lat , longitude : lon } ;
109+ } ,
110+ calculateAdjacent : function ( srcHash , dir ) {
111+ srcHash = srcHash . toLowerCase ( ) ;
112+ var lastChr = srcHash . charAt ( srcHash . length - 1 ) ;
113+ var type = ( srcHash . length % 2 ) ? 'odd' : 'even' ;
114+ var base = srcHash . substring ( 0 , srcHash . length - 1 ) ;
115+ if ( BORDERS [ dir ] [ type ] . indexOf ( lastChr ) != - 1 )
116+ base = calculateAdjacent ( base , dir ) ;
117+ return base + BASE32 [ NEIGHBORS [ dir ] [ type ] . indexOf ( lastChr ) ] ;
118+ }
119+ } ;
120+ } ) ( ) ;
121+
122+ if ( typeof exports == "undefined" ) { exports = { } ; }
123+
124+ exports . GeoHash = GeoHash ;
0 commit comments