-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Prototype tools for generating persistent stellar IDs
- Loading branch information
Oliver Smith
committed
Nov 7, 2014
1 parent
dd59c96
commit 2db26c6
Showing
2 changed files
with
169 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
*/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) |