summaryrefslogtreecommitdiff
path: root/tagstats
diff options
context:
space:
mode:
Diffstat (limited to 'tagstats')
-rw-r--r--tagstats/Makefile9
-rw-r--r--tagstats/osmstats.cpp57
-rw-r--r--tagstats/sqlite.hpp195
-rw-r--r--tagstats/statistics_handler.hpp8
-rw-r--r--tagstats/tagstats.cpp2
-rw-r--r--tagstats/tagstats_handler.hpp20
6 files changed, 273 insertions, 18 deletions
diff --git a/tagstats/Makefile b/tagstats/Makefile
index 04a453d..19e33cd 100644
--- a/tagstats/Makefile
+++ b/tagstats/Makefile
@@ -41,13 +41,16 @@ LDFLAGS = $(LIB_EXPAT) $(LIB_PBF) $(LIB_GD) $(LIB_SQLITE)
.PHONY: all clean install
-all: tagstats
+all: tagstats osmstats
+
+osmstats: osmstats.cpp statistics_handler.hpp
+ $(CXX) $(CXXFLAGS) -o $@ $< $(LDFLAGS)
tagstats: tagstats.cpp tagstats_handler.hpp statistics_handler.hpp string_store.hpp geodistribution.hpp
$(CXX) $(CXXFLAGS) -o $@ $< $(LDFLAGS)
check:
- cppcheck --enable=all tagstats.cpp
+ cppcheck --enable=all tagstats.cpp osmstats.cpp
indent:
astyle --style=java --indent-namespaces --indent-switches --pad-header --suffix=none \*.hpp \*.cpp
@@ -56,5 +59,5 @@ install:
install -m 755 tagstats ../sources/db/tagstats
clean:
- rm -f *.o core tagstats
+ rm -f *.o core tagstats osmstats
diff --git a/tagstats/osmstats.cpp b/tagstats/osmstats.cpp
new file mode 100644
index 0000000..f2cdda2
--- /dev/null
+++ b/tagstats/osmstats.cpp
@@ -0,0 +1,57 @@
+/*
+
+Copyright 2012 Jochen Topf <jochen@topf.org> and others (see README).
+
+This file is part of Taginfo (https://github.com/joto/taginfo).
+
+Osmium is free software: you can redistribute it and/or modify it under the
+terms of the GNU Lesser General Public License or (at your option) the GNU
+General Public License as published by the Free Software Foundation, either
+version 3 of the Licenses, or (at your option) any later version.
+
+Osmium 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 Lesser General Public License and the GNU
+General Public License for more details.
+
+You should have received a copy of the Licenses along with Osmium. If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#include <iostream>
+
+#define OSMIUM_WITH_PBF_INPUT
+#define OSMIUM_WITH_XML_INPUT
+
+#include <osmium.hpp>
+#include <osmium/handler.hpp>
+
+#include "statistics_handler.hpp"
+
+int main(int argc, char *argv[]) {
+ if (argc != 3) {
+ std::cerr << "Usage: " << argv[0] << " OSMFILE DATABASE" << std::endl;
+ exit(1);
+ }
+
+ Osmium::OSMFile infile(argv[1]);
+
+ Sqlite::Database db(argv[2]);
+ sqlite3* sqlite_db = db.get_sqlite3();
+ if (SQLITE_OK != sqlite3_exec(sqlite_db, \
+ "CREATE TABLE stats (" \
+ " key TEXT, " \
+ " value INT64 " \
+ ");", 0, 0, 0)) {
+ std::cerr << "Database error: " << sqlite3_errmsg(sqlite_db) << "\n";
+ sqlite3_close(sqlite_db);
+ exit(1);
+ }
+
+ StatisticsHandler handler(db);
+ Osmium::Input::read(infile, handler);
+
+ google::protobuf::ShutdownProtobufLibrary();
+}
+
diff --git a/tagstats/sqlite.hpp b/tagstats/sqlite.hpp
new file mode 100644
index 0000000..fac6bcf
--- /dev/null
+++ b/tagstats/sqlite.hpp
@@ -0,0 +1,195 @@
+#ifndef TAGSTATS_SQLITE_HPP
+#define TAGSTATS_SQLITE_HPP
+
+/*
+
+Copyright 2012 Jochen Topf <jochen@topf.org> and others (see README).
+
+This file is part of Taginfo (https://github.com/joto/taginfo).
+
+Osmium is free software: you can redistribute it and/or modify it under the
+terms of the GNU Lesser General Public License or (at your option) the GNU
+General Public License as published by the Free Software Foundation, either
+version 3 of the Licenses, or (at your option) any later version.
+
+Osmium 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 Lesser General Public License and the GNU
+General Public License for more details.
+
+You should have received a copy of the Licenses along with Osmium. If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#include <iostream>
+#include <stdexcept>
+#include <stdint.h>
+#include <string>
+
+#include <sqlite3.h>
+
+/**
+* @brief The %Sqlite classes wrap the %Sqlite C library.
+*/
+namespace Sqlite {
+
+ /**
+ * Exception returned by Sqlite wrapper classes when there are errors in the Sqlite3 lib
+ */
+ class Exception : public std::runtime_error {
+
+ public:
+
+ Exception(const std::string& msg, const std::string& error) :
+ std::runtime_error(msg + ": " + error + '\n') {
+ }
+
+ };
+
+ class Statement;
+
+ /**
+ * Wrapper class for Sqlite database
+ */
+ class Database {
+
+ private:
+
+ sqlite3* m_db;
+
+ public:
+
+ Database(const char* filename) {
+ if (sqlite3_open_v2(filename, &m_db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0)) {
+ sqlite3_close(m_db);
+ throw Sqlite::Exception("Can't open database", errmsg());
+ }
+ }
+
+ ~Database() {
+ sqlite3_close(m_db);
+ }
+
+ const std::string& errmsg() const {
+ static std::string error = std::string(sqlite3_errmsg(m_db));
+ return error;
+ }
+
+ sqlite3* get_sqlite3() {
+ return m_db;
+ }
+
+ void begin_transaction() {
+ if (SQLITE_OK != sqlite3_exec(m_db, "BEGIN TRANSACTION;", 0, 0, 0)) {
+ std::cerr << "Database error: " << sqlite3_errmsg(m_db) << "\n";
+ sqlite3_close(m_db);
+ throw std::runtime_error("Sqlite error");
+ }
+ }
+
+ void commit() {
+ if (SQLITE_OK != sqlite3_exec(m_db, "COMMIT;", 0, 0, 0)) {
+ std::cerr << "Database error: " << sqlite3_errmsg(m_db) << "\n";
+ sqlite3_close(m_db);
+ throw std::runtime_error("Sqlite error");
+ }
+ }
+
+ Statement* prepare(const char* sql);
+
+ }; // class Database
+
+ /**
+ * Wrapper class for Sqlite prepared statement.
+ */
+ class Statement {
+
+ private:
+
+ Database* m_db;
+ sqlite3_stmt* m_statement;
+ int m_bindnum;
+
+ public:
+
+ Statement(Database* db, const char* sql) :
+ m_db(db),
+ m_statement(0),
+ m_bindnum(1) {
+ sqlite3_prepare_v2(db->get_sqlite3(), sql, -1, &m_statement, 0);
+ if (m_statement == 0) {
+ throw Sqlite::Exception("Can't prepare statement", m_db->errmsg());
+ }
+ }
+
+ ~Statement() {
+ sqlite3_finalize(m_statement);
+ }
+
+ Statement* bind_null() {
+ if (SQLITE_OK != sqlite3_bind_null(m_statement, m_bindnum++)) {
+ throw Sqlite::Exception("Can't bind null value", m_db->errmsg());
+ }
+ return this;
+ }
+
+ Statement* bind_text(const char* value) {
+ if (SQLITE_OK != sqlite3_bind_text(m_statement, m_bindnum++, value, -1, SQLITE_STATIC)) {
+ throw Sqlite::Exception("Can't bind text value", m_db->errmsg());
+ }
+ return this;
+ }
+
+ Statement* bind_text(const std::string& value) {
+ if (SQLITE_OK != sqlite3_bind_text(m_statement, m_bindnum++, value.c_str(), -1, SQLITE_STATIC)) {
+ throw Sqlite::Exception("Can't bind text value", m_db->errmsg());
+ }
+ return this;
+ }
+
+ Statement* bind_int(int value) {
+ if (SQLITE_OK != sqlite3_bind_int(m_statement, m_bindnum++, value)) {
+ throw Sqlite::Exception("Can't bind int value", m_db->errmsg());
+ }
+ return this;
+ }
+
+ Statement* bind_int64(int64_t value) {
+ if (SQLITE_OK != sqlite3_bind_int64(m_statement, m_bindnum++, value)) {
+ throw Sqlite::Exception("Can't bind int64 value", m_db->errmsg());
+ }
+ return this;
+ }
+
+ Statement* bind_double(double value) {
+ if (SQLITE_OK != sqlite3_bind_double(m_statement, m_bindnum++, value)) {
+ throw Sqlite::Exception("Can't bind double value", m_db->errmsg());
+ }
+ return this;
+ }
+
+ Statement* bind_blob(const void* value, int length) {
+ if (SQLITE_OK != sqlite3_bind_blob(m_statement, m_bindnum++, value, length, 0)) {
+ throw Sqlite::Exception("Can't bind blob value", m_db->errmsg());
+ }
+ return this;
+ }
+
+ void execute() {
+ sqlite3_step(m_statement);
+ if (SQLITE_OK != sqlite3_reset(m_statement)) {
+ throw Sqlite::Exception("Can't execute statement", m_db->errmsg());
+ }
+ m_bindnum = 1;
+ }
+
+ }; // class Statement
+
+ inline Statement* Database::prepare(const char* sql) {
+ return new Statement(this, sql);
+ }
+
+} // namespace Sqlite
+
+#endif // TAGSTATS_SQLITE_HPP
diff --git a/tagstats/statistics_handler.hpp b/tagstats/statistics_handler.hpp
index f1ece07..89767bd 100644
--- a/tagstats/statistics_handler.hpp
+++ b/tagstats/statistics_handler.hpp
@@ -22,7 +22,7 @@ You should have received a copy of the Licenses along with Osmium. If not, see
*/
-#include <osmium/utils/sqlite.hpp>
+#include "sqlite.hpp"
/**
* Osmium handler that collects basic statistics from OSM data and
@@ -32,7 +32,7 @@ class StatisticsHandler : public Osmium::Handler::Base {
public:
- StatisticsHandler(Osmium::Sqlite::Database& database) : Base(), m_database(database) {
+ StatisticsHandler(Sqlite::Database& database) : Base(), m_database(database) {
// if you change anything in this array, also change the corresponding struct below
static const char *sn[] = {
"nodes",
@@ -136,7 +136,7 @@ public:
}
void final() {
- Osmium::Sqlite::Statement* statement_insert_into_main_stats = m_database.prepare("INSERT INTO stats (key, value) VALUES (?, ?);");
+ Sqlite::Statement* statement_insert_into_main_stats = m_database.prepare("INSERT INTO stats (key, value) VALUES (?, ?);");
m_database.begin_transaction();
for (int i=0; m_stat_names[i]; ++i) {
@@ -190,7 +190,7 @@ private:
const char **m_stat_names;
- Osmium::Sqlite::Database& m_database;
+ Sqlite::Database& m_database;
osm_object_id_t m_id;
osm_version_t m_version;
diff --git a/tagstats/tagstats.cpp b/tagstats/tagstats.cpp
index e941c88..fcb8cc8 100644
--- a/tagstats/tagstats.cpp
+++ b/tagstats/tagstats.cpp
@@ -154,7 +154,7 @@ int main(int argc, char *argv[]) {
GeoDistribution::set_dimensions(width, height);
Osmium::OSMFile infile(argv[optind]);
- Osmium::Sqlite::Database db(argv[optind+1]);
+ Sqlite::Database db(argv[optind+1]);
MapToInt<rough_position_t> map_to_int(left, bottom, right, top, width, height);
TagStatsHandler handler(db, tags_list, map_to_int);
Osmium::Input::read(infile, handler);
diff --git a/tagstats/tagstats_handler.hpp b/tagstats/tagstats_handler.hpp
index 29858d0..6d99e75 100644
--- a/tagstats/tagstats_handler.hpp
+++ b/tagstats/tagstats_handler.hpp
@@ -31,7 +31,7 @@ You should have received a copy of the Licenses along with Osmium. If not, see
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
-#include <osmium/utils/sqlite.hpp>
+#include "sqlite.hpp"
#include "string_store.hpp"
/**
@@ -207,7 +207,7 @@ class TagStatsHandler : public Osmium::Handler::Base {
static const int string_store_size = 1024 * 1024 * 10;
StringStore m_string_store;
- Osmium::Sqlite::Database& m_database;
+ Sqlite::Database& m_database;
void _timer_info(const char *msg) {
int duration = time(0) - timer;
@@ -287,7 +287,7 @@ class TagStatsHandler : public Osmium::Handler::Base {
void _print_and_clear_distribution_images(bool for_nodes) {
int sum_size=0;
- Osmium::Sqlite::Statement* statement_insert_into_key_distributions = m_database.prepare("INSERT INTO key_distributions (key, object_type, png) VALUES (?, ?, ?);");
+ Sqlite::Statement* statement_insert_into_key_distributions = m_database.prepare("INSERT INTO key_distributions (key, object_type, png) VALUES (?, ?, ?);");
m_database.begin_transaction();
for (key_hash_map_t::const_iterator it = tags_stat.begin(); it != tags_stat.end(); it++) {
@@ -400,7 +400,7 @@ class TagStatsHandler : public Osmium::Handler::Base {
public:
- TagStatsHandler(Osmium::Sqlite::Database& database, const std::string& tags_list, MapToInt<rough_position_t>& map_to_int) :
+ TagStatsHandler(Sqlite::Database& database, const std::string& tags_list, MapToInt<rough_position_t>& map_to_int) :
Base(),
m_max_timestamp(0),
m_string_store(string_store_size),
@@ -452,7 +452,7 @@ public:
int size;
void* ptr = GeoDistribution::create_empty_png(&size);
- Osmium::Sqlite::Statement* statement_insert_into_key_distributions = m_database.prepare("INSERT INTO key_distributions (png) VALUES (?);");
+ Sqlite::Statement* statement_insert_into_key_distributions = m_database.prepare("INSERT INTO key_distributions (png) VALUES (?);");
m_database.begin_transaction();
statement_insert_into_key_distributions
->bind_blob(ptr, size) // column: png
@@ -510,29 +510,29 @@ public:
_print_memory_usage();
timer = time(0);
- Osmium::Sqlite::Statement *statement_insert_into_keys = m_database.prepare("INSERT INTO keys (key, " \
+ Sqlite::Statement *statement_insert_into_keys = m_database.prepare("INSERT INTO keys (key, " \
" count_all, count_nodes, count_ways, count_relations, " \
"values_all, values_nodes, values_ways, values_relations, " \
" users_all, " \
"cells_nodes, cells_ways) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
- Osmium::Sqlite::Statement *statement_insert_into_tags = m_database.prepare("INSERT INTO tags (key, value, " \
+ Sqlite::Statement *statement_insert_into_tags = m_database.prepare("INSERT INTO tags (key, value, " \
"count_all, count_nodes, count_ways, count_relations) " \
"VALUES (?, ?, ?, ?, ?, ?);");
#ifdef TAGSTATS_COUNT_KEY_COMBINATIONS
- Osmium::Sqlite::Statement* statement_insert_into_key_combinations = m_database.prepare("INSERT INTO keypairs (key1, key2, " \
+ Sqlite::Statement* statement_insert_into_key_combinations = m_database.prepare("INSERT INTO keypairs (key1, key2, " \
"count_all, count_nodes, count_ways, count_relations) " \
"VALUES (?, ?, ?, ?, ?, ?);");
#endif // TAGSTATS_COUNT_KEY_COMBINATIONS
#ifdef TAGSTATS_COUNT_TAG_COMBINATIONS
- Osmium::Sqlite::Statement* statement_insert_into_tag_combinations = m_database.prepare("INSERT INTO tagpairs (key1, value1, key2, value2, " \
+ Sqlite::Statement* statement_insert_into_tag_combinations = m_database.prepare("INSERT INTO tagpairs (key1, value1, key2, value2, " \
"count_all, count_nodes, count_ways, count_relations) " \
"VALUES (?, ?, ?, ?, ?, ?, ?, ?);");
#endif // TAGSTATS_COUNT_TAG_COMBINATIONS
- Osmium::Sqlite::Statement* statement_update_meta = m_database.prepare("UPDATE source SET data_until=?");
+ Sqlite::Statement* statement_update_meta = m_database.prepare("UPDATE source SET data_until=?");
m_database.begin_transaction();