Osmium
0.1
|
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