Skip to content

Instantly share code, notes, and snippets.

@josher19
Created December 22, 2011 02:48
Show Gist options
  • Save josher19/1508687 to your computer and use it in GitHub Desktop.
Save josher19/1508687 to your computer and use it in GitHub Desktop.
Convert Geohash to Lat-Lon pair.
GEOHASH = {
BASE32: "0123456789bcdefghjkmnpqrstuvwxyz"
, binlat: function (geobinary) { return geobinary.filter(GEOHASH.odd).join("") }
, binlong: function (geobinary) { return geobinary.filter(GEOHASH.even).join("") }
, even: function (item,ndx) { return (ndx + 1) % 2 }
, getGeobinary: function (geohash) { return GEOHASH.toBinary(geohash).join("").split(""); }
, odd: function (item,ndx) { return ndx % 2 }
, toBinary: function toBinary(geohash) { return geohash.toLowerCase().split("").map(function(g) { return GEOHASH.zeropad(GEOHASH.BASE32.indexOf(g).toString(2)) }); }
, toDecimal: function toDecimal(blat, mult) {
var min=-90*mult, max=90 * mult, mid=0.0;
if (window.console) console.log([blat, mult == 1 ? "LAT" : mult == 2 ? "LONG": "??"].join(" "));
for(var i=0; i<blat.length; ++i) {
var cur = blat[i];
if (window.console) console.log([cur,min,mid,max]);
if ("1" == cur) { min = mid; mid = (min + max) / 2; }
else if ("0" == cur) { max = mid; mid = (min + max) / 2; }
}
return mid;
}
, toLatLong: function toLatLong(geohash) { var geobinary = GEOHASH.getGeobinary(geohash); var blat = GEOHASH.binlat(geobinary), blong = GEOHASH.binlong(geobinary); return [ GEOHASH.toDecimal(blat, 1), GEOHASH.toDecimal(blong, 2) ]; }
, zeropad: function zeropad(num, digits) { if (null == digits) digits = 5; var len = num.length; var addZeros = digits - len; while(addZeros-- > 0) num = "0" + num; return num; }
, getGeohash : function getGeohash(lat,lng,accuracy,err) { var mygeohash="", geolat = GEOHASH.fromDecimal(lat, 1, accuracy || 55,err), geolng = GEOHASH.fromDecimal(lng, 2, accuracy||56,err); var bits = GEOHASH.mergebits(geolat, geolng); for(var i=0; bits.length && i < (accuracy||55); i += 5) mygeohash += GEOHASH.rebase(bits.splice(0,5).join("")); return mygeohash; }
, mergebits : function (geolat,geolng){ var geo=[], len=Math.max(geolat.length,geolng.length); for(var i=0; i<len; ++i) { geo.push(geolng[i]||"0"); geo.push(geolat[i]||"0"); }; return geo; }
, rebase : function (bits) { var base36 = parseInt(bits, 2).toString(32); if ("NaN" == base36 || bits === "0") { base36 = ""; } for (var word = "", i = 0; i < base36.length; ++i) { var cur = parseInt(base36[i], 32); word += GEOHASH.BASE32[cur]; } return word; }
, fromDecimal : function (deci, mult, strlen, err) {
var min=-90*mult, max=90 * mult, mid=0.0, blat="";
if (window.console) console.log([deci, mult == 1 ? "LAT" : mult == 2 ? "LNG": "??"].join(" "));
while(blat.length < strlen && Math.abs(deci - mid) >= (err||0.0)) {
if (window.console) console.log([cur,min,mid,max]);
if (deci > mid) { cur = "1"; min = mid; mid = (min + max) / 2; blat += cur;}
else if (deci < mid) { cur = "0", max = mid; mid = (min + max) / 2; blat += cur; }
else if (deci === mid) { window.console && console.log(["Exact:",blat,blat.length]); return blat; }
}
if (window.console) console.log(["Approx:",blat,blat.length])
return blat;
}
};
/*
Convert Geohash [http://en.wikipedia.org/wiki/Geohash] to Lat-Long pair.
Example usage: GEOHASH.toLatLong("ezs42");
GEOHASH.toLatLong( GEOHASH.getGeohash( 57.64911,10.40744 ) );
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment