Skip to content

Instantly share code, notes, and snippets.

@webstory
Last active April 4, 2018 07:00
Show Gist options
  • Save webstory/9739339b163f765a36a3f7f353d55590 to your computer and use it in GitHub Desktop.
Save webstory/9739339b163f765a36a3f7f353d55590 to your computer and use it in GitHub Desktop.
Google plus code decoder/encoder
'use strct'
const _ = require('lodash')
const LETTERS = Array.from("23456789CFGHJMPQRVWX")
const R_LETTERS = _.invert(LETTERS)
const ELEVENTH = (function() {
const dy = 0.000025
const dx = 0.00003125
let res = {}
for(let y = 0; y <= 4; y++) {
for(let x = 0; x <= 3; x++) {
res[LETTERS[y * 4 + x]] = [y * dy + (dy / 2), x * dx + (dx / 2)]
}
}
return res
})()
function plus2coords(code) {
code = code.replace("+", "")
let eleventh = [0, 0]
if(code.length == 11) {
eleventh = ELEVENTH[code[10]]
code = code.slice(0, 10)
}
let chunks = _.chunk(code, 2)
let [ys, xs] = _.zip(...chunks)
let x = -180.0
let y = -90.0
let dx = 20
let dy = 20
for(let letterPos in xs) {
let digit = R_LETTERS[xs[letterPos]] - 0
dx = Math.pow(20, 1 - letterPos)
x = x + dx * digit
}
for(let letterPos in ys) {
let digit = R_LETTERS[ys[letterPos]] - 0
dy = Math.pow(20, 1 - letterPos)
y = y + dy * digit
}
if(eleventh[0] != 0.0) {
y = y + eleventh[0]
x = x + eleventh[1]
} else {
y = y + dy / 2
x = x + dx / 2
}
return [y, x]
}
function divmod(n, d) {
return [Math.floor(n / d), n % d]
}
function coords2pluscode(lat, lon) {
if(Math.abs(lat) > 90) { return "" }
lat = lat + 90
let rad = lon * Math.PI / 180
norm_r = rad - (2 * Math.PI) * Math.floor((rad + Math.PI) / (2 * Math.PI))
lon = norm_r * 180 / Math.PI + 180
let q, r
let dy = 20
let dx = 20
let code = Array.from("0000000000")
ry = lat
for(let i = 0; i < 5; i++) {
[q, r] = divmod(ry, dy)
dy = dy / 20
ry = r
code[i * 2] = LETTERS[q]
}
rx = lon
for(let i = 0; i < 5; i++) {
[q, r] = divmod(rx, dx)
dx = dx / 20
rx = r
code[i * 2 + 1] = LETTERS[q]
}
code.splice(8, 0, '+')
// Calculate eleventh letter
qy = Math.floor(ry / 0.000025)
qx = Math.floor(rx / 0.00003125)
code.push(LETTERS[qy * 4 + qx])
return code.join("")
}
console.log(plus2coords("8Q98HX6J+9F2")) // 37.560887,126.981141
console.log(plus2coords("8Q98HX6J+C58")) // 37.561037,126.980453
console.log(plus2coords("8Q98HX6J+9F")) // 37.560937,126.981187
console.log(coords2pluscode(37.560937,126.981187)) // 8Q98HX6J+9FF
console.log(coords2pluscode(37.560937,126.981203)) // 8Q98HX6J+9FG
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment