123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- /*!
- * Copyright© 2008 David Troy
- *
- * geohash.js
- * github: https://github.com/davetroy/geohash-js
- * license: MIT License
- *
- */
- BITS = [16, 8, 4, 2, 1];
- BASE32 = "0123456789bcdefghjkmnpqrstuvwxyz";
- NEIGHBORS = { right : { even : "bc01fg45238967deuvhjyznpkmstqrwx" },
- left : { even : "238967debc01fg45kmstqrwxuvhjyznp" },
- top : { even : "p0r21436x8zb9dcf5h7kjnmqesgutwvy" },
- bottom : { even : "14365h7k9dcfesgujnmqp0r2twvyx8zb" } };
- BORDERS = { right : { even : "bcfguvyz" },
- left : { even : "0145hjnp" },
- top : { even : "prxz" },
- bottom : { even : "028b" } };
- NEIGHBORS.bottom.odd = NEIGHBORS.left.even;
- NEIGHBORS.top.odd = NEIGHBORS.right.even;
- NEIGHBORS.left.odd = NEIGHBORS.bottom.even;
- NEIGHBORS.right.odd = NEIGHBORS.top.even;
- BORDERS.bottom.odd = BORDERS.left.even;
- BORDERS.top.odd = BORDERS.right.even;
- BORDERS.left.odd = BORDERS.bottom.even;
- BORDERS.right.odd = BORDERS.top.even;
- function refine_interval(interval, cd, mask) {
- if (cd&mask)
- interval[0] = (interval[0] + interval[1])/2;
- else
- interval[1] = (interval[0] + interval[1])/2;
- }
- function calculateAdjacent(srcHash, dir) {
- srcHash = srcHash.toLowerCase();
- var lastChr = srcHash.charAt(srcHash.length-1);
- var type = (srcHash.length % 2) ? 'odd' : 'even';
- var base = srcHash.substring(0,srcHash.length-1);
- if (BORDERS[dir][type].indexOf(lastChr)!=-1)
- base = calculateAdjacent(base, dir);
- return base + BASE32[NEIGHBORS[dir][type].indexOf(lastChr)];
- }
- function decodeGeoHash(geohash) {
- var is_even = 1;
- var lat = []; var lon = [];
- lat[0] = -90.0; lat[1] = 90.0;
- lon[0] = -180.0; lon[1] = 180.0;
- lat_err = 90.0; lon_err = 180.0;
-
- for (i=0; i<geohash.length; i++) {
- c = geohash[i];
- cd = BASE32.indexOf(c);
- for (j=0; j<5; j++) {
- mask = BITS[j];
- if (is_even) {
- lon_err /= 2;
- refine_interval(lon, cd, mask);
- } else {
- lat_err /= 2;
- refine_interval(lat, cd, mask);
- }
- is_even = !is_even;
- }
- }
- lat[2] = (lat[0] + lat[1])/2;
- lon[2] = (lon[0] + lon[1])/2;
- return { latitude: lat, longitude: lon};
- }
- function encodeGeoHash(latitude, longitude) {
- var is_even=1;
- var i=0;
- var lat = []; var lon = [];
- var bit=0;
- var ch=0;
- var precision = 12;
- geohash = "";
- lat[0] = -90.0; lat[1] = 90.0;
- lon[0] = -180.0; lon[1] = 180.0;
-
- while (geohash.length < precision) {
- if (is_even) {
- mid = (lon[0] + lon[1]) / 2;
- if (longitude > mid) {
- ch |= BITS[bit];
- lon[0] = mid;
- } else
- lon[1] = mid;
- } else {
- mid = (lat[0] + lat[1]) / 2;
- if (latitude > mid) {
- ch |= BITS[bit];
- lat[0] = mid;
- } else
- lat[1] = mid;
- }
- is_even = !is_even;
- if (bit < 4)
- bit++;
- else {
- geohash += BASE32[ch];
- bit = 0;
- ch = 0;
- }
- }
- return geohash;
- }
|