88 lines
2.2 KiB
C++
88 lines
2.2 KiB
C++
/*
|
|
open source routing machine
|
|
Copyright (C) Dennis Luxen, others 2010
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU AFFERO General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
or see http://www.gnu.org/licenses/agpl.txt.
|
|
*/
|
|
|
|
#ifndef HILBERTVALUE_H_
|
|
#define HILBERTVALUE_H_
|
|
|
|
#include <boost/integer.hpp>
|
|
#include <boost/noncopyable.hpp>
|
|
|
|
// computes a 64 bit value that corresponds to the hilbert space filling curve
|
|
|
|
class HilbertCode : boost::noncopyable {
|
|
public:
|
|
static uint64_t GetHilbertNumberForCoordinate(
|
|
const _Coordinate & current_coordinate) {
|
|
unsigned location[2];
|
|
location[0] = current_coordinate.lat+( 90*100000);
|
|
location[1] = current_coordinate.lon+(180*100000);
|
|
|
|
TransposeCoordinate(location);
|
|
const uint64_t result = BitInterleaving(location[0], location[1]);
|
|
return result;
|
|
}
|
|
private:
|
|
static inline uint64_t BitInterleaving(const uint32_t a, const uint32_t b) {
|
|
uint64_t result = 0;
|
|
for(int8_t index = 31; index >= 0; --index){
|
|
result |= (a >> index) & 1;
|
|
result <<= 1;
|
|
result |= (b >> index) & 1;
|
|
if(0 != index){
|
|
result <<= 1;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
static inline void TransposeCoordinate( uint32_t * X) {
|
|
uint32_t M = 1 << (32-1), P, Q, t;
|
|
int i;
|
|
// Inverse undo
|
|
for( Q = M; Q > 1; Q >>= 1 ) {
|
|
P=Q-1;
|
|
for( i = 0; i < 2; ++i ) {
|
|
if( X[i] & Q ) {
|
|
X[0] ^= P; // invert
|
|
} else {
|
|
t = (X[0]^X[i]) & P;
|
|
X[0] ^= t;
|
|
X[i] ^= t;
|
|
}
|
|
} // exchange
|
|
}
|
|
// Gray encode
|
|
for( i = 1; i < 2; ++i ) {
|
|
X[i] ^= X[i-1];
|
|
}
|
|
t=0;
|
|
for( Q = M; Q > 1; Q >>= 1 ) {
|
|
if( X[2-1] & Q ) {
|
|
t ^= Q-1;
|
|
}
|
|
} //check if this for loop is wrong
|
|
for( i = 0; i < 2; ++i ) {
|
|
X[i] ^= t;
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif /* HILBERTVALUE_H_ */
|