// Geosyl.js – Convert Latitude longitude Pairs to Readable Words. // based on David Troy's https://github.com/davetroy/hash-js // also see: http://www.movable-type.co.uk/scripts/hash.html // Distributed under the MIT License geosyl = (function(){ var bits = [32, 16, 8, 4, 2, 1], vocals = 'aeiou'.split(''), consonants = 'kgsztdnhfpmyr'.split(''), syllables = []; vocals.forEach(function(vocal){ consonants.forEach(function(consonant) { syllables.push(consonant + vocal); }); }); function refine_interval(interval, cd, mask) { var mid = (interval[0] + interval[1]) / 2; interval[cd & mask ? 0 : 1] = mid; } return { decode: function (hash) { hash = hash .replace(/\W/g, '') .toLowerCase() .match(/\w{2}/g); var isEven = 1, lat = [-90, 90], lng = [-180, 180], mask, part, i; for (i = 0; i < hash.length; i++) { part = hash[i]; index = syllables.indexOf(part); for (j = 0; j < bits.length; j++) { mask = bits[j]; if (isEven) { refine_interval(lng, index, mask); } else { refine_interval(lat, index, mask); } isEven = !isEven; } } return [lat[0], lng[0], lat[1], lng[1]]; }, encode: function(latitude, longitude, precision) { var isEven = true, lat = [-90, 90], lng = [-180, 180], bit = 0, index = 0, hash = [], mid; precision = precision || 9; while (hash.length < precision) { if (isEven) { mid = (lng[0] + lng[1]) / 2; if (longitude > mid) { index |= bits[bit]; lng[0] = mid; } else lng[1] = mid; } else { mid = (lat[0] + lat[1]) / 2; if (latitude > mid) { index |= bits[bit]; lat[0] = mid; } else lat[1] = mid; } isEven = !isEven; if (bit < bits.length-1) { bit++; } else { hash.push(syllables[index]); bit = 0; index = 0; } } return hash.map(function(syllable, index) { return syllable + (( index % 3 == 2 && index < hash.length - 1 ) ? ' ' : ''); }).join(''); } } })(); var lat = 51.5, lng = 10, hash = geosyl.encode(lat, lng), bounds = geosyl.decode(hash); console.log(lat, lng); console.log(hash); console.log(bounds); console.log(Math.abs(bounds[0] - lat)) console.log(Math.abs(bounds[1] - lng))