Skip to content

Instantly share code, notes, and snippets.

@plugnburn

plugnburn/olc.js

Last active Oct 27, 2020
Embed
What would you like to do?
TinyOLC - smallest Open Location Code implementation in JS
/**
* TinyOLC - Open Location Code for smallest applications
* Differences from Google's open-source JS implementation:
* - less than 600 bytes minified (as opposed to over 4.5 KB from Google)
* - only 2 methods exposed - encode (lat, lng => str) and decode (str => [lat, lng])
* - only floating point degrees accepted as encoding input (positive as N and E, negative as S and W)
* - no short code resolution
* - no area encoding, only points with 11-digit resolution
* - assuming the block lower left corner only when decoding a low-res code
* - no validation checks
* - public domain
* @author Luxferre 2020
* @license Unlicense <unlicense.org>
*/
OLC = (function() {
var alpha = '23456789CFGHJMPQRVWX'
return {
encode: function(lat, lng) {
var res = [], i = 0, latr, lngr, fact = 20
for(lat+=90,lng+=180;i<11;i+=2) { //main step
if(i===8)
res[i++] = '+'
res[i] = alpha[latr = 0|(lat/fact)]
res[i+1] = alpha[lngr = 0|(lng/fact)]
lat -= latr*fact
lng -= lngr*fact
fact /= 20
}
return res.join('') + alpha[4*(0|(lat/fact/4)) + (0|(lng/fact/5))] //additional step
},
decode: function(code) {
code = code.split(0)[0].split('').map(function(c){return (c=alpha.indexOf(c)) > -1 ? c : NaN}).filter(isFinite)
var lat, lng, i, fact = 20, l = code.length,
bl = l > 10 ? 10 : l
for(lat=lng=i=0;i<bl;i+=2) { //main step
lat += code[i] * fact
lng += code[i+1] * fact
fact /= 20
}
if(l>10) { //additional step
fact = 125e-6
lat += fact*(0|(code[10]/5))
lng += fact*(code[10]%4)
}
return [lat - 90, lng - 180].map(function(n){return Math.round(n*1e6)/1e6})
}
}
})()
OLC=function(){var Z="23456789CFGHJMPQRVWX";return{encode:function(a,c){var d=[],b=0,e,g,f=20;a+=90;for(c+=180;11>b;b+=2)8===b&&(d[b++]="+"),d[b]=Z[e=0|a/f],d[b+1]=Z[g=0|c/f],a-=e*f,c-=g*f,f/=20;return d.join("")+Z[4*(0|a/f/4)+(0|c/f/5)]},decode:function(a){a=a.split(0)[0].split("").map(function(h){return-1<(h=Z.indexOf(h))?h:NaN}).filter(isFinite);var c,d,b,e=20,g=a.length,f=10<g?10:g;for(c=d=b=0;b<f;b+=2)c+=a[b]*e,d+=a[b+1]*e,e/=20;10<g&&(e=1.25E-4,c+=e*(0|a[10]/5),d+=a[10]%4*e);return[c-90,d-180].map(function(h){return Math.round(1E6*h)/1E6})}}}()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment