Skip to content

Instantly share code, notes, and snippets.

@aemkei
Created December 4, 2015 15:16
Show Gist options
  • Select an option

  • Save aemkei/6c061e53fcd1c7835e21 to your computer and use it in GitHub Desktop.

Select an option

Save aemkei/6c061e53fcd1c7835e21 to your computer and use it in GitHub Desktop.

Revisions

  1. aemkei created this gist Dec 4, 2015.
    115 changes: 115 additions & 0 deletions geosyl.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,115 @@
    // 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))