Osmium  0.1
include/osmium/input.hpp
Go to the documentation of this file.
00001 #ifndef OSMIUM_INPUT_HPP
00002 #define OSMIUM_INPUT_HPP
00003 
00004 /*
00005 
00006 Copyright 2011 Jochen Topf <jochen@topf.org> and others (see README).
00007 
00008 This file is part of Osmium (https://github.com/joto/osmium).
00009 
00010 Osmium is free software: you can redistribute it and/or modify it under the
00011 terms of the GNU Lesser General Public License or (at your option) the GNU
00012 General Public License as published by the Free Software Foundation, either
00013 version 3 of the Licenses, or (at your option) any later version.
00014 
00015 Osmium is distributed in the hope that it will be useful, but WITHOUT ANY
00016 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
00017 PARTICULAR PURPOSE. See the GNU Lesser General Public License and the GNU
00018 General Public License for more details.
00019 
00020 You should have received a copy of the Licenses along with Osmium. If not, see
00021 <http://www.gnu.org/licenses/>.
00022 
00023 */
00024 
00025 #include <boost/utility.hpp>
00026 #include <boost/tr1/memory.hpp>
00027 #include <boost/make_shared.hpp>
00028 
00029 using std::tr1::shared_ptr;
00030 using std::tr1::static_pointer_cast;
00031 using std::tr1::const_pointer_cast;
00032 using std::tr1::dynamic_pointer_cast;
00033 using boost::make_shared;
00034 
00035 #include <osmium/handler.hpp>
00036 #include <osmium/osmfile.hpp>
00037 
00038 namespace Osmium {
00039 
00043     namespace Input {
00044 
00055         class StopReading {
00056         };
00057 
00097         template <class THandler>
00098         class Base : boost::noncopyable {
00099 
00100         public:
00101 
00102             virtual ~Base() {
00103             }
00104 
00109             virtual void parse() = 0;
00110 
00111         protected:
00112 
00113             Base(Osmium::OSMFile& file,
00114                  THandler& handler)
00115                 : m_last_object_type(UNKNOWN),
00116                   m_file(file),
00117                   m_handler(handler),
00118                   m_meta(),
00119                   m_node(),
00120                   m_way(),
00121                   m_relation() {
00122 
00123                 m_meta.has_multiple_object_versions(m_file.has_multiple_object_versions());
00124                 m_file.open_for_input();
00125 
00126             }
00127 
00128             void call_after_and_before_on_handler(osm_object_type_t current_object_type) {
00129                 if (current_object_type != m_last_object_type) {
00130                     switch (m_last_object_type) {
00131                         case NODE:
00132                             m_handler.after_nodes();
00133                             break;
00134                         case WAY:
00135                             m_handler.after_ways();
00136                             break;
00137                         case RELATION:
00138                             m_handler.after_relations();
00139                             break;
00140                         default:
00141                             break;
00142                     }
00143                     switch (current_object_type) {
00144                         case NODE:
00145                             if (m_last_object_type == UNKNOWN) {
00146                                 m_handler.init(m_meta);
00147                             }
00148                             m_handler.before_nodes();
00149                             break;
00150                         case WAY:
00151                             m_handler.before_ways();
00152                             break;
00153                         case RELATION:
00154                             m_handler.before_relations();
00155                             break;
00156                         default:
00157                             break;
00158                     }
00159                     m_last_object_type = current_object_type;
00160                 }
00161             }
00162 
00163             void call_node_on_handler() const {
00164                 m_handler.node(m_node);
00165             }
00166 
00167             void call_way_on_handler() const {
00168                 m_handler.way(m_way);
00169             }
00170 
00171             void call_relation_on_handler() const {
00172                 m_handler.relation(m_relation);
00173             }
00174 
00175             void call_final_on_handler() const {
00176                 m_handler.final();
00177             }
00178 
00179             Osmium::OSM::Meta& meta() {
00180                 return m_meta;
00181             }
00182 
00183             int get_fd() const {
00184                 return m_file.get_fd();
00185             }
00186 
00187             const Osmium::OSMFile& get_file() const {
00188                 return m_file;
00189             }
00190 
00191             /*
00192                The following methods prepare the m_node/way/relation member
00193                variable for use. If it is empty or in use by somebody other
00194                than this parser, a new object will be allocated. If it not is
00195                use, it will be reset to it's pristine state by calling the
00196                destructor directly and then placement new. This gets around a
00197                memory deallocation and re-allocation which was timed to slow
00198                down the program noticably.
00199             */
00200             Osmium::OSM::Node& prepare_node() {
00201                 if (m_node && m_node.unique()) {
00202                     m_node->~Node();
00203                     new (m_node.get()) Osmium::OSM::Node();
00204                 } else {
00205                     m_node = make_shared<Osmium::OSM::Node>();
00206                 }
00207                 return *m_node;
00208             }
00209 
00210             Osmium::OSM::Way& prepare_way() {
00211                 if (m_way && m_way.unique()) {
00212                     m_way->~Way();
00213                     new (m_way.get()) Osmium::OSM::Way(2000);
00214                 } else {
00215                     m_way = make_shared<Osmium::OSM::Way>(2000);
00216                 }
00217                 return *m_way;
00218             }
00219 
00220             Osmium::OSM::Relation& prepare_relation() {
00221                 if (m_relation && m_relation.unique()) {
00222                     m_relation->~Relation();
00223                     new (m_relation.get()) Osmium::OSM::Relation();
00224                 } else {
00225                     m_relation = make_shared<Osmium::OSM::Relation>();
00226                 }
00227                 return *m_relation;
00228             }
00229 
00230         private:
00231 
00236             osm_object_type_t m_last_object_type;
00237 
00241             Osmium::OSMFile m_file;
00242 
00246             THandler& m_handler;
00247 
00248             Osmium::OSM::Meta m_meta;
00249 
00250         protected:
00251 
00252             shared_ptr<Osmium::OSM::Node>     m_node;
00253             shared_ptr<Osmium::OSM::Way>      m_way;
00254             shared_ptr<Osmium::OSM::Relation> m_relation;
00255 
00256         }; // class Base
00257 
00258     } // namespace Input
00259 
00260 } // namespace Osmium
00261 
00262 #include <osmium/input/xml.hpp>
00263 #include <osmium/input/pbf.hpp>
00264 
00265 #endif // OSMIUM_INPUT_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines