Extracting coordinates from single 60 bit hex numbers

Thanks to the wonderful people on Stackoverflow, I’m making some progress with figuring out how some geographic information is saved in a DB2 database that I’m working with.

it turns out that, rather than using the spatial functionality of DB2 (which would make sense, but considering the source of this database, I wouldn’t ask for too much), coordinate pairs are being stored as Morton codes in a 16-byte Character column.

So far, I’ve sorted out decoding the coordinate values, and can shuffle points predictably on my test map; now I’m just trying to figure out what grid that these coordinates are on. I’m fairly certain (not that I know anything about these things) that it’s somehow related to the MGA grid, because 0 east is at almost exactly 114°, which is where MGA zone 50 starts (the ‘almost’ comes from my point-and-click measurement technique).

But I don’t know where I’m going next; I’ll leave it till the morning.


My test code for this has been in PHP, and I needed something to convert big numbers between bases; hadn’t realised that the BC math library didn’t include base_convert(), so I found the one below.

/**
 * Convert an arbitrary-length number between arbitrary bases.
 * Copied, and very slightly translated, from
 * http://www.technischedaten.de/pmwiki2/pmwiki.php?n=Php.BaseConvert
 *
 * @param $value
 * @param $from_base
 * @param $to_base
 * @return string
 */
function bc_base_convert($value, $from_base, $to_base)
{
    $valid_digits = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    if (min($from_base, $to_base) < 2)
    {
        trigger_error('Bad Format min: 2', E_USER_ERROR);
    }
    if (max($from_base, $to_base) > strlen($valid_digits))
    {
        trigger_error('Bad Format max: ' . strlen($valid_digits), E_USER_ERROR);
    }
    $dezi = '0';
    $level = 0;
    $result = '';
    $value = trim(strval($value), "\r\n\t +");
    $sign = ('-' === $value{0}) ? '-' : '';
    $value = ltrim($value, "-0");
    $len = strlen($value);
    for ($i = 0; $i < $len; $i++)
    {
        $wert = strpos($valid_digits, $value{$len - 1 - $i});
        if (FALSE === $wert)
        {
            trigger_error('Bad Char in input 1', E_USER_ERROR);
        }
        if ($wert >= $from_base)
        {
            trigger_error('Bad character in input 2', E_USER_ERROR);
        }
        $dezi = bcadd($dezi, bcmul(bcpow($from_base, $i), $wert));
    }
    if ($to_base == 10)
    {
        return $sign . $dezi; // Shortcut for base 10
    }
    while (1 !== bccomp(bcpow($to_base, $level++), $dezi));
    for ($i = $level - 2; $i >= 0; $i--)
    {
        $factor = bcpow($to_base, $i);
        $zahl = bcdiv($dezi, $factor, 0);
        $dezi = bcmod($dezi, $factor);
        $result .= $valid_digits{$zahl};
    }
    $result = empty($result) ? '0' : $result;
    return $sign . $result;
}


Retrieved from ‘https://samwilson.id.au/index.php?title=Extracting_coordinates_from_single_60_bit_hex_numbers&oldid=157