/* 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 NODEINFORMATIONHELPDESK_H_ #define NODEINFORMATIONHELPDESK_H_ #include "QueryNode.h" #include "PhantomNodes.h" #include "StaticRTree.h" #include "../Contractor/EdgeBasedGraphFactory.h" #include "../Util/OSRMException.h" #include "../typedefs.h" #include #include #include #include #include #include #include typedef EdgeBasedGraphFactory::EdgeBasedNode RTreeLeaf; class NodeInformationHelpDesk : boost::noncopyable { public: NodeInformationHelpDesk( const std::string & ram_index_filename, const std::string & mem_index_filename, const std::string & nodes_filename, const std::string & edges_filename, const unsigned m_number_of_nodes, const unsigned m_check_sum ) : m_number_of_nodes(m_number_of_nodes), m_check_sum(m_check_sum) { if ( ram_index_filename.empty() ) { throw OSRMException("no ram index file name in server ini"); } if ( mem_index_filename.empty() ) { throw OSRMException("no mem index file name in server ini"); } if ( nodes_filename.empty() ) { throw OSRMException("no nodes file name in server ini"); } if ( edges_filename.empty() ) { throw OSRMException("no edges file name in server ini"); } m_ro_rtree_ptr = new StaticRTree( ram_index_filename, mem_index_filename ); BOOST_ASSERT_MSG( 0 == m_coordinate_list.size(), "Coordinate vector not empty" ); LoadNodesAndEdges(nodes_filename, edges_filename); } ~NodeInformationHelpDesk() { delete m_ro_rtree_ptr; } inline FixedPointCoordinate GetCoordinateOfNode(const unsigned id) const { const NodeID node = m_via_node_list.at(id); return m_coordinate_list.at(node); } inline unsigned GetNameIndexFromEdgeID(const unsigned id) const { return m_name_ID_list.at(id); } inline TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const { return m_turn_instruction_list.at(id); } inline NodeID GetNumberOfNodes() const { return m_number_of_nodes; } inline bool FindNearestNodeCoordForLatLon( const FixedPointCoordinate& input_coordinate, FixedPointCoordinate& result, const unsigned zoom_level = 18 ) const { PhantomNode resulting_phantom_node; bool found_node = FindPhantomNodeForCoordinate( input_coordinate, resulting_phantom_node, zoom_level ); result = resulting_phantom_node.location; return found_node; } inline bool FindPhantomNodeForCoordinate( const FixedPointCoordinate & input_coordinate, PhantomNode & resulting_phantom_node, const unsigned zoom_level ) const { return m_ro_rtree_ptr->FindPhantomNodeForCoordinate( input_coordinate, resulting_phantom_node, zoom_level ); } inline unsigned GetCheckSum() const { return m_check_sum; } private: void LoadNodesAndEdges( const std::string & nodes_filename, const std::string & edges_filename ) { boost::filesystem::path nodes_file(nodes_filename); if ( !boost::filesystem::exists( nodes_file ) ) { throw OSRMException("nodes file does not exist"); } if ( 0 == boost::filesystem::file_size( nodes_file ) ) { throw OSRMException("nodes file is empty"); } boost::filesystem::path edges_file(edges_filename); if ( !boost::filesystem::exists( edges_file ) ) { throw OSRMException("edges file does not exist"); } if ( 0 == boost::filesystem::file_size( edges_file ) ) { throw OSRMException("edges file is empty"); } boost::filesystem::ifstream nodes_input_stream( nodes_file, std::ios::binary ); boost::filesystem::ifstream edges_input_stream( edges_file, std::ios::binary ); SimpleLogger().Write(logDEBUG) << "Loading node data"; NodeInfo current_node; while(!nodes_input_stream.eof()) { nodes_input_stream.read((char *)¤t_node, sizeof(NodeInfo)); m_coordinate_list.push_back( FixedPointCoordinate( current_node.lat, current_node.lon ) ); } std::vector(m_coordinate_list).swap(m_coordinate_list); nodes_input_stream.close(); SimpleLogger().Write(logDEBUG) << "Loading edge data"; unsigned number_of_edges = 0; edges_input_stream.read((char*)&number_of_edges, sizeof(unsigned)); m_via_node_list.resize(number_of_edges); m_name_ID_list.resize(number_of_edges); m_turn_instruction_list.resize(number_of_edges); OriginalEdgeData current_edge_data; for(unsigned i = 0; i < number_of_edges; ++i) { edges_input_stream.read( (char*)&(current_edge_data), sizeof(OriginalEdgeData) ); m_via_node_list[i] = current_edge_data.viaNode; m_name_ID_list[i] = current_edge_data.nameID; m_turn_instruction_list[i] = current_edge_data.turnInstruction; } edges_input_stream.close(); SimpleLogger().Write(logDEBUG) << "Loaded " << number_of_edges << " orig edges"; SimpleLogger().Write(logDEBUG) << "Opening NN indices"; } std::vector m_coordinate_list; std::vector m_via_node_list; std::vector m_name_ID_list; std::vector m_turn_instruction_list; StaticRTree * m_ro_rtree_ptr; const unsigned m_number_of_nodes; const unsigned m_check_sum; }; #endif /*NODEINFORMATIONHELPDESK_H_*/