removed libkdtree++ dependency.

This commit is contained in:
Dennis Luxen
2010-07-26 08:17:52 +00:00
parent 92963ced1f
commit ec0108553f
8 changed files with 283 additions and 81 deletions
+4 -10
View File
@@ -39,21 +39,21 @@ struct NodeCoords {
static NodeCoords<NodeT> min_value()
{
return NodeCoords<NodeT>(0,0,numeric_limits<NodeT>::min());
return NodeCoords<NodeT>(-90*100000,-180*100000,numeric_limits<NodeT>::min());
}
static NodeCoords<NodeT> max_value()
{
return NodeCoords<NodeT>(numeric_limits<int>::max(), numeric_limits<int>::max(), numeric_limits<NodeT>::max());
return NodeCoords<NodeT>(90*100000, 180*100000, numeric_limits<NodeT>::max());
}
value_type operator[](size_t n) const
{
switch(n)
{
case 0:
case 1:
return lat;
break;
case 1:
case 0:
return lon;
break;
default:
@@ -63,10 +63,4 @@ struct NodeCoords {
}
}
};
template<typename NodeT>
bool operator < (const NodeCoords<NodeT> & a, const NodeCoords<NodeT> & b)
{
return a.id < b.id;
}
#endif //_NODE_COORDS_H
+47 -48
View File
@@ -16,7 +16,7 @@ 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 NODEINFORMATIONHELPDESK_H_
#define NODEINFORMATIONHELPDESK_H_
@@ -37,88 +37,87 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <vector>
#include "../typedefs.h"
#include "StaticKDTree.h"
#include <kdtree++/kdtree.hpp>
typedef KDTree::KDTree<2, NodeInfo > KDTreeType;
typedef KDTree::StaticKDTree<2, int, NodeID> KDTreeType;
class NodeInformationHelpDesk{
public:
~NodeInformationHelpDesk();
NodeInformationHelpDesk() { int2ExtNodeMap = new vector<KDTreeType::iterator>();}
KDTreeType * initKDTree(ifstream& input);
NodeInformationHelpDesk() { int2ExtNodeMap = new vector<KDTreeType::InputPoint>();}
KDTreeType * initKDTree(ifstream& input);
NodeID getExternalNodeID(const NodeID node);
const NodeInfo& getExternalNodeInfo(const NodeID node) const;
int getLatitudeOfNode(const NodeID node) const;
int getLongitudeOfNode(const NodeID node) const;
NodeID getExternalNodeID(const NodeID node);
void getExternalNodeInfo(const NodeID node, NodeInfo * info) const;
int getLatitudeOfNode(const NodeID node) const;
int getLongitudeOfNode(const NodeID node) const;
NodeID getNumberOfNodes() const { return int2ExtNodeMap->size(); }
NodeID getNumberOfNodes() const { return int2ExtNodeMap->size(); }
inline NodeID findNearestNodeIDForLatLon(const int lat, const int lon, NodeCoords<NodeID> * data) const
{
NodeInfo nearestNeighbor = *(kdtree->find_nearest(NodeInfo(lat, lon, 0)).first);
data->id = nearestNeighbor.id;
data->lat = nearestNeighbor.lat;
data->lon = nearestNeighbor.lon;
return data->id;
}
inline NodeID findNearestNodeIDForLatLon(const int lat, const int lon, NodeCoords<NodeID> * data) const
{
KDTreeType::InputPoint i;
KDTreeType::InputPoint o;
i.coordinates[0] = lat;
i.coordinates[1] = lon;
kdtree->NearestNeighbor(&o, i);
data->id = o.data;
data->lat = o.coordinates[0];
data->lon = o.coordinates[1];
return data->id;
}
private:
vector<KDTreeType::iterator> * int2ExtNodeMap;
KDTreeType * kdtree;
vector<KDTreeType::InputPoint> * int2ExtNodeMap;
KDTreeType * kdtree;
};
//////////////////
//implementation//
//////////////////
NodeInformationHelpDesk::~NodeInformationHelpDesk(){
// delete graph;
// delete calc;
// delete c;
}
/* @brief: initialize kd-tree and internal->external node id map
*
*/
KDTreeType * NodeInformationHelpDesk::initKDTree(ifstream& in)
{
kdtree = new KDTreeType();
NodeID id = 0;
while(!in.eof())
{
NodeInfo b;
in.read((char *)&b, sizeof(b));
b.id = id;
KDTreeType::iterator kdit = kdtree->insert(b);
int2ExtNodeMap->push_back(kdit);
id++;
}
in.close();
// kdtree->optimise();
return kdtree;
NodeID id = 0;
while(!in.eof())
{
NodeInfo b;
in.read((char *)&b, sizeof(b));
b.id = id;
KDTreeType::InputPoint p;
p.coordinates[0] = b.lat;
p.coordinates[1] = b.lon;
p.data = id;
int2ExtNodeMap->push_back(p);
id++;
}
in.close();
kdtree = new KDTreeType(int2ExtNodeMap);
return kdtree;
}
NodeID NodeInformationHelpDesk::getExternalNodeID(const NodeID node)
{
return int2ExtNodeMap->at(node)->id;
return int2ExtNodeMap->at(node).data;
}
const NodeInfo& NodeInformationHelpDesk::getExternalNodeInfo(const NodeID node) const
void NodeInformationHelpDesk::getExternalNodeInfo(const NodeID node, NodeInfo * info) const
{
return *(int2ExtNodeMap->at(node) );
info->id = int2ExtNodeMap->at(node).data;
info->lat = int2ExtNodeMap->at(node).coordinates[0];
info->lon = int2ExtNodeMap->at(node).coordinates[1];
}
int NodeInformationHelpDesk::getLatitudeOfNode(const NodeID node) const
{
return int2ExtNodeMap->at(node)->lat;
return int2ExtNodeMap->at(node).coordinates[0];
}
int NodeInformationHelpDesk::getLongitudeOfNode(const NodeID node) const
{
return int2ExtNodeMap->at(node)->lon;
return int2ExtNodeMap->at(node).coordinates[1];
}
#endif /*NODEINFORMATIONHELPDESK_H_*/
+212
View File
@@ -0,0 +1,212 @@
/*
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.
KD Tree coded by Christian Vetter, Monav Project
*/
#ifndef STATICKDTREE_H_INCLUDED
#define STATICKDTREE_H_INCLUDED
#include <vector>
#ifdef _GLIBCXX_PARALLEL
#include <parallel/algorithm>
#else
#include <algorithm>
#endif
#include <stack>
#include <limits>
namespace KDTree {
template< unsigned k, typename T >
class BoundingBox {
public:
BoundingBox() {
for ( unsigned dim = 0; dim < k; ++dim ) {
min[dim] = std::numeric_limits< T >::min();
max[dim] = std::numeric_limits< T >::max();
}
}
T min[k];
T max[k];
};
struct NoData {};
template< unsigned k, typename T >
class EuclidianMetric {
public:
double operator() ( const T left[k], const T right[k] ) {
double result = 0;
for ( unsigned i = 0; i < k; ++i ) {
double temp = (double)left[i] - (double)right[i];
result += temp * temp;
}
return result;
}
double operator() ( const BoundingBox< k, T > &box, const T point[k] ) {
T nearest[k];
for ( unsigned dim = 0; dim < k; ++dim ) {
if ( point[dim] < box.min[dim] )
nearest[dim] = box.min[dim];
else if ( point[dim] > box.max[dim] )
nearest[dim] = box.max[dim];
else
nearest[dim] = point[dim];
}
return operator() ( point, nearest );
}
};
template < unsigned k, typename T, typename Data = NoData, typename Metric = EuclidianMetric< k, T > >
class StaticKDTree {
public:
struct InputPoint {
T coordinates[k];
Data data;
};
StaticKDTree( std::vector< InputPoint > * points ){
assert( k > 0 );
assert ( points->size() > 0 );
size = points->size();
kdtree = new InputPoint[size];
for ( Iterator i = 0; i != size; ++i ) {
kdtree[i] = points->at(i);
for ( unsigned dim = 0; dim < k; ++dim ) {
if ( kdtree[i].coordinates[dim] < boundingBox.min[dim] )
boundingBox.min[dim] = kdtree[i].coordinates[dim];
if ( kdtree[i].coordinates[dim] > boundingBox.max[dim] )
boundingBox.max[dim] = kdtree[i].coordinates[dim];
}
}
std::stack< Tree > s;
s.push ( Tree ( 0, size, 0 ) );
while ( !s.empty() ) {
Tree tree = s.top();
s.pop();
if ( tree.left == tree.right )
continue;
Iterator middle = tree.left + ( tree.right - tree.left ) / 2;
#ifdef _GLIBCXX_PARALLEL
__gnu_parallel::nth_element( kdtree + tree.left, kdtree + middle, kdtree + tree.right, Less( tree.dimension ) );
#else
std::nth_element( kdtree + tree.left, kdtree + middle, kdtree + tree.right, Less( tree.dimension ) );
#endif
s.push( Tree( tree.left, middle, ( tree.dimension + 1 ) % k ) );
s.push( Tree( middle + 1, tree.right, ( tree.dimension + 1 ) % k ) );
}
}
~StaticKDTree(){
delete[] kdtree;
}
bool NearestNeighbor( InputPoint* result, const InputPoint& point, double radius = std::numeric_limits< T >::max() ) {
Metric distance;
bool found = false;
double nearestDistance = radius;
std::stack< NNTree > s;
s.push ( NNTree ( 0, size, 0, boundingBox ) );
while ( !s.empty() ) {
NNTree tree = s.top();
s.pop();
if ( distance( tree.box, point.coordinates ) >= nearestDistance )
continue;
if ( tree.left == tree.right )
continue;
Iterator middle = tree.left + ( tree.right - tree.left ) / 2;
double newDistance = distance( kdtree[middle].coordinates, point.coordinates );
if ( newDistance < nearestDistance ) {
nearestDistance = newDistance;
*result = kdtree[middle];
found = true;
}
Less comperator( tree.dimension );
if ( !comperator( point, kdtree[middle] ) ) {
NNTree first( middle + 1, tree.right, ( tree.dimension + 1 ) % k, tree.box );
NNTree second( tree.left, middle, ( tree.dimension + 1 ) % k, tree.box );
first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
s.push( second );
s.push( first );
}
else {
NNTree first( middle + 1, tree.right, ( tree.dimension + 1 ) % k, tree.box );
NNTree second( tree.left, middle, ( tree.dimension + 1 ) % k, tree.box );
first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
s.push( first );
s.push( second );
}
}
return found;
}
private:
typedef unsigned Iterator;
struct Tree {
Iterator left;
Iterator right;
unsigned dimension;
Tree() {}
Tree( Iterator l, Iterator r, unsigned d ): left( l ), right( r ), dimension( d ) {}
};
struct NNTree {
Iterator left;
Iterator right;
unsigned dimension;
BoundingBox< k, T > box;
NNTree() {}
NNTree( Iterator l, Iterator r, unsigned d, const BoundingBox< k, T >& b ): left( l ), right( r ), dimension( d ), box ( b ) {}
};
class Less {
public:
Less( unsigned d ) {
dimension = d;
assert( dimension < k );
}
bool operator() ( const InputPoint& left, const InputPoint& right ) {
assert( dimension < k );
return left.coordinates[dimension] < right.coordinates[dimension];
}
private:
unsigned dimension;
};
BoundingBox< k, T > boundingBox;
InputPoint* kdtree;
Iterator size;
};
}
#endif // STATICKDTREE_H_INCLUDED