Skip to content

Commit

Permalink
Prototype tools for generating persistent stellar IDs
Browse files Browse the repository at this point in the history
  • Loading branch information
Oliver Smith committed Nov 7, 2014
1 parent dd59c96 commit 2db26c6
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 0 deletions.
87 changes: 87 additions & 0 deletions misc/coord64.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Coordinate ID generator:
* Takes a set of 3d coordinates (x, y, z), truncates to 2dp and then
* generates a base64-like(*) representation that can be used as an id
* for the object.
*
* The actual encoding is not base64, since base64 contains characters
* that present a problem when used, e.g, in URIs. I replaced the '+'
* and '/' characters with '_' and '.' respectively.
*
* Example usage:
* coord_to_id64(51.5625, 32.1875, -27.125)
* Generates:
* "1gA:Oi:-Go"
*
* A reversing function is also provided.
*
* Original Author: Oliver "kfsone" Smith <[email protected]>
* Released under the "use it with attribution" license.
*/

var alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_.";
var precision = 100.;

function coord_to_d64(coord) {
var i = parseInt(Math.abs(coord * precision));

var digits = ""
do {
digits = alphabet[i & 63] + digits;
i >>= 6; // shift right by a digit (>>= 6)
} while (i > 0);

return (coord < 0) ? ("-"+digits) : (digits);
}

function d64_to_coord(d64) {
var divisor = precision;
var pos = 0;
if (d64[0] == '-') {
divisor = -divisor;
pos++;
}

var number = 0;
for ( ; pos < d64.length ; ++pos ) {
var value = alphabet.indexOf(d64[pos]);
if (value < 0)
throw "Invalid d64 value: " + d64;
number = (number * 64) + value;
}

return number / divisor;
}

function pos_to_id64(x, y, z) {
return coord_to_d64(x) + ':' + coord_to_d64(y) + ':' + coord_to_d64(z);
}

function id64_to_pos(id64) {
d64s = id64.split(':');
return [ d64_to_coord(d64s[0]),
d64_to_coord(d64s[1]),
d64_to_coord(d64s[2])
];
}

/*
* Test cases
*
function test_conv(testPos) {
id64 = pos_to_id64(testPos[0], testPos[1], testPos[2]);
document.write("id64 [", testPos.join(','), "] = ", id64, "\n")
pos = id64_to_pos(id64);
document.write("pos of ", id64, " = [", pos.join(','), "]\n");
}
var test1 = [ 51.5625,32.1875,-27.125 ];
var test2 = [ -154.65625,40.34375,-82.78125 ];
test_conv(test1);
test_conv(test1);
test_conv(test2);
*/

82 changes: 82 additions & 0 deletions misc/coord64.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Coordinate ID generator:
# Takes a set of 3d coordinates (x, y, z), truncates to 2dp and then
# generates a base64-like(*) representation that can be used as an id
# for the object.
#
# The actual encoding is not base64, since base64 contains characters
# that present a problem when used, e.g, in URIs. I replaced the '+'
# and '/' characters with '_' and '.' respectively.
#
# Example usage:
# coord_to_id64(51.5625, 32.1875, -27.125)
# Generates:
# "1gA:Oi:-Go"
#
# A reversing function is also provided.
#
# Original Author: Oliver "kfsone" Smith <[email protected]>
# Released under the "use it with attribution" license.

from __future__ import print_function, division
import string

alphabet = string.digits + string.ascii_lowercase + string.ascii_uppercase + '_.'
precision = 100.

def coord_to_d64(coord):
i = int(abs(coord * precision))

digits = ""
while True:
digits = alphabet[i & 63] + digits
i >>= 6 # divides by 64, or one digit
if i == 0:
break

sign = '-' if coord < 0 else ''
return sign + digits


def d64_to_coord(d64):
divisor, digits = precision, d64
if d64.startswith('-'):
divisor = -divisor
digits = digits[1:]

number = 0
for digit in digits:
value = alphabet.find(digit)
if value < 0:
raise ValueError("Invalid d64 value: {}".format(value))
number = (number * 64) + value

return number / divisor


def pos_to_id64(x, y, z):
return coord_to_d64(x) + ':' + coord_to_d64(y) + ':' + coord_to_d64(z)


def id64_to_pos(id64):
(x64, y64, z64) = id64.split(':')
return (d64_to_coord(x64), d64_to_coord(y64), d64_to_coord(z64))


if __name__ == "__main__":
test1 = ( 51.5625,32.1875,-27.125 )
test2 = ( -154.65625,40.34375,-82.78125 )

id64 = pos_to_id64(test1[0], test1[1], test1[2])
print("id64 of {} = {}".format(test1, id64))
pos = id64_to_pos(id64)
print("pos of {} = {}".format(id64, pos))

id64 = pos_to_id64(test1[0], test1[1], test1[2])
print("id64 of {} = {}".format(test1, id64))
pos = id64_to_pos(id64)
print("pos of {} = {}".format(id64, pos))

id64 = pos_to_id64(test2[0], test2[1], test2[2])
print("id64 of {} = {}".format(test2, id64))
pos = id64_to_pos(id64)
print("pos of {} = {}".format(id64, pos))

0 comments on commit 2db26c6

Please sign in to comment.