Osmium
0.1
|
00001 #ifndef OSMIUM_HANDLER_STATISTICS_HPP 00002 #define OSMIUM_HANDLER_STATISTICS_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 <osmium/utils/sqlite.hpp> 00026 00027 namespace Osmium { 00028 00029 namespace Handler { 00030 00035 class Statistics : public Base { 00036 00037 public: 00038 00039 Statistics() : Base() { 00040 // if you change anything in this array, also change the corresponding struct below 00041 static const char *sn[] = { 00042 "nodes", 00043 "nodes_without_tags", 00044 "node_tags", 00045 "max_node_id", 00046 "max_tags_on_node", 00047 "ways", 00048 "way_tags", 00049 "way_nodes", 00050 "max_way_id", 00051 "max_tags_on_way", 00052 "max_nodes_on_way", 00053 "closed_ways", 00054 "relations", 00055 "relation_tags", 00056 "relation_members", 00057 "max_relation_id", 00058 "max_tags_on_relation", 00059 "max_members_on_relation", 00060 "max_user_id", 00061 "anon_user_objects", 00062 "max_node_version", 00063 "max_way_version", 00064 "max_relation_version", 00065 "sum_node_version", 00066 "sum_way_version", 00067 "sum_relation_version", 00068 "max_changeset_id", 00069 0 // last element (sentinel) must always be 0 00070 }; 00071 m_stat_names = sn; 00072 00073 // initialize all statistics to zero 00074 for (int i=0; m_stat_names[i]; ++i) { 00075 ((uint64_t*) &m_stats)[i] = 0; 00076 } 00077 } 00078 00079 void node(const shared_ptr<Osmium::OSM::Node const>& node) { 00080 update_common_stats(node); 00081 m_stats.nodes++; 00082 if (m_tag_count == 0) { 00083 m_stats.nodes_without_tags++; 00084 } 00085 if (m_id > (int64_t) m_stats.max_node_id) { 00086 m_stats.max_node_id = m_id; 00087 } 00088 m_stats.node_tags += m_tag_count; 00089 if (m_tag_count > (int64_t) m_stats.max_tags_on_node) { 00090 m_stats.max_tags_on_node = m_tag_count; 00091 } 00092 if (m_version > (int64_t) m_stats.max_node_version) { 00093 m_stats.max_node_version = m_version; 00094 } 00095 m_stats.sum_node_version += m_version; 00096 } 00097 00098 void way(const shared_ptr<Osmium::OSM::Way const>& way) { 00099 update_common_stats(way); 00100 m_stats.ways++; 00101 if (way->is_closed()) { 00102 m_stats.closed_ways++; 00103 } 00104 if (m_id > (int64_t) m_stats.max_way_id) { 00105 m_stats.max_way_id = m_id; 00106 } 00107 m_stats.way_tags += m_tag_count; 00108 m_stats.way_nodes += way->node_count(); 00109 if (m_tag_count > (int64_t) m_stats.max_tags_on_way) { 00110 m_stats.max_tags_on_way = m_tag_count; 00111 } 00112 if (way->node_count() > (int64_t) m_stats.max_nodes_on_way) { 00113 m_stats.max_nodes_on_way = way->node_count(); 00114 } 00115 if (m_version > (int64_t) m_stats.max_way_version) { 00116 m_stats.max_way_version = m_version; 00117 } 00118 m_stats.sum_way_version += m_version; 00119 } 00120 00121 void relation(const shared_ptr<Osmium::OSM::Relation const>& relation) { 00122 update_common_stats(relation); 00123 m_stats.relations++; 00124 if (m_id > (int64_t) m_stats.max_relation_id) { 00125 m_stats.max_relation_id = m_id; 00126 } 00127 m_stats.relation_tags += m_tag_count; 00128 osm_sequence_id_t member_count = relation->members().size(); 00129 m_stats.relation_members += member_count; 00130 if (m_tag_count > (int64_t) m_stats.max_tags_on_relation) { 00131 m_stats.max_tags_on_relation = m_tag_count; 00132 } 00133 if (member_count > (int64_t) m_stats.max_members_on_relation) { 00134 m_stats.max_members_on_relation = member_count; 00135 } 00136 if (m_version > (int64_t) m_stats.max_relation_version) { 00137 m_stats.max_relation_version = m_version; 00138 } 00139 m_stats.sum_relation_version += m_version; 00140 } 00141 00142 void final() { 00143 unlink("count.db"); 00144 Sqlite::Database db("count.db"); 00145 00146 sqlite3* sqlite_db = db.get_sqlite3(); 00147 if (SQLITE_OK != sqlite3_exec(sqlite_db, \ 00148 "CREATE TABLE stats (" \ 00149 " key TEXT, " \ 00150 " value INT64 " \ 00151 ");", 0, 0, 0)) { 00152 std::cerr << "Database error: " << sqlite3_errmsg(sqlite_db) << "\n"; 00153 sqlite3_close(sqlite_db); 00154 exit(1); 00155 } 00156 00157 Sqlite::Statement* statement_insert_into_main_stats = db.prepare("INSERT INTO stats (key, value) VALUES (?, ?);"); 00158 db.begin_transaction(); 00159 00160 for (int i=0; m_stat_names[i]; ++i) { 00161 statement_insert_into_main_stats 00162 ->bind_text(m_stat_names[i]) 00163 ->bind_int64( ((uint64_t*) &m_stats)[i] ) 00164 ->execute(); 00165 } 00166 statement_insert_into_main_stats 00167 ->bind_text("nodes_with_tags") 00168 ->bind_int64( ((uint64_t*) &m_stats)[0] - ((uint64_t*) &m_stats)[1] ) 00169 ->execute(); 00170 00171 db.commit(); 00172 00173 delete statement_insert_into_main_stats; 00174 } 00175 00176 private: 00177 00178 // if you change anything in this struct, also change the corresponding array above 00179 struct statistics { 00180 uint64_t nodes; 00181 uint64_t nodes_without_tags; 00182 uint64_t node_tags; 00183 uint64_t max_node_id; 00184 uint64_t max_tags_on_node; 00185 uint64_t ways; 00186 uint64_t way_tags; 00187 uint64_t way_nodes; 00188 uint64_t max_way_id; 00189 uint64_t max_tags_on_way; 00190 uint64_t max_nodes_on_way; 00191 uint64_t closed_ways; 00192 uint64_t relations; 00193 uint64_t relation_tags; 00194 uint64_t relation_members; 00195 uint64_t max_relation_id; 00196 uint64_t max_tags_on_relation; 00197 uint64_t max_members_on_relation; 00198 uint64_t max_user_id; 00199 uint64_t anon_user_objects; 00200 uint64_t max_node_version; 00201 uint64_t max_way_version; 00202 uint64_t max_relation_version; 00203 uint64_t sum_node_version; 00204 uint64_t sum_way_version; 00205 uint64_t sum_relation_version; 00206 uint64_t max_changeset_id; 00207 } m_stats; 00208 00209 const char **m_stat_names; 00210 00211 osm_object_id_t m_id; 00212 osm_version_t m_version; 00213 int m_tag_count; 00214 00215 void update_common_stats(const shared_ptr<Osmium::OSM::Object const>& object) { 00216 m_id = object->id(); 00217 m_version = object->version(); 00218 m_tag_count = object->tags().size(); 00219 00220 osm_user_id_t uid = object->uid(); 00221 if (uid == 0) { 00222 m_stats.anon_user_objects++; 00223 } 00224 if (uid > (int64_t) m_stats.max_user_id) { 00225 m_stats.max_user_id = uid; 00226 } 00227 00228 osm_changeset_id_t changeset = object->changeset(); 00229 if (changeset > (int64_t) m_stats.max_changeset_id) { 00230 m_stats.max_changeset_id = changeset; 00231 } 00232 } 00233 00234 }; // class Statistics 00235 00236 } // namespace Handler 00237 00238 } // namespace Osmium 00239 00240 #endif // OSMIUM_HANDLER_STATISTICS_HPP