/home/martin/workspace/OpenStreetNav/src/importer/main.cc
Go to the documentation of this file.
00001 /*
00002  * main.cc
00003  *
00004  *  Created on: Nov 8, 2011
00005  *      Author: martin
00006  */
00007 
00008 #include <boost/program_options.hpp>
00009 #include <iostream>
00010 #include "../osmdb/osmdb.h"
00011 #include "../xmlparse/xmlparse.h"
00012 #include <functional>
00013 
00014 void progress(int& i)
00015 {
00016     i++;
00017     if (i % 100000 == 0)
00018         std::cout << "Processed approximately " << i << " elements" << std::endl;
00019 }
00020 
00021 void action_handler(osmdb::ImportTableAction act, int64_t amount)
00022 {
00023     using osmdb::ImportTableAction;
00024     switch (act)
00025     {
00026         case ImportTableAction::ANALYZE:
00027             std::cout << "Done analyzing" << std::endl;
00028             break;
00029         case ImportTableAction::CLEAR_IMPORT:
00030             std::cout << "Done cleaning up" << std::endl;
00031             break;
00032         case ImportTableAction::CREATE_IMPORT_INDEX:
00033             std::cout << "Created import indexes" << std::endl;
00034             break;
00035         case ImportTableAction::CREATE_IMPORT_PKEY:
00036             std::cout << "Created import primary key" << std::endl;
00037             break;
00038         case ImportTableAction::DELETE_DUPLICIT_NODE:
00039             std::cout << "Deleted " << amount << " duplicit nodes in import" << std::endl;
00040             break;
00041         case ImportTableAction::DELETE_DUPLICIT_RELATION:
00042             std::cout << "Deleted " << amount << " duplicit relations in import" << std::endl;
00043             break;
00044         case ImportTableAction::DELETE_DUPLICIT_WAY:
00045             std::cout << "Deleted " << amount << " duplicit ways in import" << std::endl;
00046             break;
00047         case ImportTableAction::DELETE_IMPORT_ORPHANS:
00048             std::cout << "Deleted " << amount << " orphan elements in import" << std::endl;
00049             break;
00050         case ImportTableAction::DELETE_INCOMPLETE_RELATION:
00051             std::cout << "Deleted " << amount << " incomplete relations in import" << std::endl;
00052             break;
00053         case ImportTableAction::DELETE_INCOMPLETE_WAY:
00054             std::cout << "Deleted " << amount << " incomplete ways in import" << std::endl;
00055             break;
00056         case ImportTableAction::DELETE_NODE_TO_DELETE:
00057             std::cout << "Deleted " << amount << " nodes which should be deleted" << std::endl;
00058             break;
00059         case ImportTableAction::DELETE_NODE_TO_UPDATE:
00060             std::cout << "Deleted " << amount << " nodes which should be updated" << std::endl;
00061             break;
00062         case ImportTableAction::DELETE_ORPHAN:
00063             std::cout << "Deleted " << amount << " orphan elements" << std::endl;
00064             break;
00065         case ImportTableAction::DELETE_RELATION_TO_DELETE:
00066             std::cout << "Deleted " << amount << " relations which should be deleted" << std::endl;
00067             break;
00068         case ImportTableAction::DELETE_RELATION_TO_UPDATE:
00069             std::cout << "Deleted " << amount << " relations which should be updated" << std::endl;
00070             break;
00071         case ImportTableAction::DELETE_WAY_TO_DELETE:
00072             std::cout << "Deleted " << amount << " ways which should be deleted" << std::endl;
00073             break;
00074         case ImportTableAction::DELETE_WAY_TO_UPDATE:
00075             std::cout << "Deleted " << amount << " ways which should be updated" << std::endl;
00076             break;
00077         case ImportTableAction::IMPORT_EDGES:
00078             std::cout << "Imported " << amount << " edges" << std::endl;
00079             break;
00080         case ImportTableAction::IMPORT_MEMBER_NODE:
00081             std::cout << "Imported " << amount << " member nodes" << std::endl;
00082             break;
00083         case ImportTableAction::IMPORT_MEMBER_REL:
00084             std::cout << "Imported " << amount << " member relations" << std::endl;
00085             break;
00086         case ImportTableAction::IMPORT_MEMBER_WAY:
00087             std::cout << "Imported " << amount << " member ways" << std::endl;
00088             break;
00089         case ImportTableAction::IMPORT_NODE:
00090             std::cout << "Imported " << amount << " nodes" << std::endl;
00091             break;
00092         case ImportTableAction::IMPORT_NODE_ATTR:
00093             std::cout << "Imported " << amount << " node attributes" << std::endl;
00094             break;
00095         case ImportTableAction::IMPORT_RELATION:
00096             std::cout << "Imported " << amount << " relations" << std::endl;
00097             break;
00098         case ImportTableAction::IMPORT_REL_ATTR:
00099             std::cout << "Imported " << amount << " relation attributes" << std::endl;
00100             break;
00101         case ImportTableAction::IMPORT_WAY:
00102             std::cout << "Imported " << amount << " ways" << std::endl;
00103             break;
00104         case ImportTableAction::IMPORT_WAY_ATTR:
00105             std::cout << "Imported " << amount << " way attributes" << std::endl;
00106             break;
00107         case ImportTableAction::IMPORT_WAY_NODE:
00108             std::cout << "Imported " << amount << " way nodes" << std::endl;
00109             break;
00110         case ImportTableAction::DELETE_DUPLICIT_ATTR:
00111             std::cout << "Deleted " << amount << " duplicit attributes in import" << std::endl;
00112             break;
00113         case ImportTableAction::DELETE_DUPLICIT_WAYNODE:
00114             std::cout << "Deleted " << amount << " duplicit waynodes in import" << std::endl;
00115             break;
00116         case ImportTableAction::DELETE_DUPLICIT_MEMBER:
00117             std::cout << "Deleted " << amount << " duplicit member elements in import" << std::endl;
00118             break;
00119     }
00120 }
00121 
00122 bool proceed_handler()
00123 {
00124     while (true)
00125     {
00126         std::cout << "Proceed? (y/n)" << std::endl;
00127         std::string s;
00128         std::cin >> s;
00129         if (s == "y" || s == "yes")
00130         {
00131             return true;
00132         }
00133         if (s == "n" || s == "no")
00134         {
00135             return false;
00136         }
00137         std::cout << "Sorry, didn't understand, try again" << std::endl;
00138     }
00139     return true;
00140 }
00141 
00142 void copy_to_db(std::string const& filename, osmdb::OsmDatabase& db)
00143 {
00144     osmdb::ElementCopy ins(db);
00145     osmxml::XmlParser pars;
00146     int done = 0;
00147     pars.node_handler = [&ins](osm::Node const & n)
00148     {
00149         ins.insert_node(n);
00150     };
00151     pars.way_handler = [&ins](osm::Way const & w)
00152     {
00153         ins.insert_way(w);
00154     };
00155     pars.relation_handler = [&ins](osm::Relation const & r)
00156     {
00157         ins.insert_relation(r);
00158     };
00159     pars.progress_handler = [&done]()
00160     {
00161         progress(done);
00162     };
00163     std::cout << "Starting copy" << std::endl;
00164     ins.start_copy();
00165     pars.parse_file(filename);
00166     ins.end_copy();
00167     std::cout << "Done copying" << std::endl;
00168 }
00169 
00170 bool process_import_table(osmdb::OsmDatabase& db, bool quiet, bool recreate)
00171 {
00172     osmdb::ImportTableProcessor proc(db);
00173     bool status = false;
00174     proc.proceed_signal.connect([&]()
00175     {
00176         if (quiet)
00177             status = true;
00178         else
00179             status = proceed_handler();
00180         if (status && recreate)
00181             db.drop_primary_keys();
00182         return status;
00183     });
00184     proc.action_signal.connect(action_handler);
00185     proc.process();
00186     return status;
00187 }
00188 
00189 int import(std::string const& inp, std::string const& dbname, std::string const& schema, bool init, bool recreate, bool copy, bool import, bool quiet, bool analyze)
00190 {
00191     try
00192     {
00193         std::string connstr;
00194         if (dbname != "")
00195             connstr = "dbname=" + dbname;
00196         psql::Database pdb(connstr, true);
00197         if (init && schema != "")
00198             pdb.create_schema(schema);
00199         if (schema != "")
00200             pdb.set_schema(schema);
00201         osmdb::OsmDatabase db(pdb);
00202         if (init)
00203         {
00204             db.create_tables();
00205             db.create_indexes_and_keys();
00206         }
00207         pdb.begin_transaction();
00208         if (recreate)
00209         {
00210             std::cout << "Dropping foreign keys and indexes" << std::endl;
00211             db.drop_foreign_keys();
00212             db.drop_indexes();
00213         }
00214         std::cout << "Starting import" << std::endl;
00215         bool status = true;
00216         if (copy)
00217             copy_to_db(inp, db);
00218         if (import)
00219             status = process_import_table(db, quiet, recreate);
00220         if (recreate)
00221         {
00222             std::cout << "Recreating indexes and keys" << std::endl;
00223             db.create_indexes_and_keys();
00224         }
00225         if (status)
00226         {
00227             pdb.commit_transaction();
00228             if (analyze)
00229             {
00230                 std::cout << "Running analyze" << std::endl;
00231                 pdb.analyze();
00232             }
00233             std::cout << "Success" << std::endl;
00234         }
00235         else
00236         {
00237             std::cout << "Cancelling changes" << std::endl;
00238             pdb.rollback_transaction();
00239         }
00240     }
00241     catch (xml_schema::parsing& p)
00242     {
00243         std::cout << "Error parsing input document" << std::endl << p;
00244         return 1;
00245     }
00246     catch (std::exception& ex)
00247     {
00248         std::cout << "Error occured" << std::endl << ex.what() << std::endl;
00249         return 1;
00250     }
00251     return 0;
00252 }
00253 
00254 int main(int argc, char** argv)
00255 {
00256     boost::program_options::options_description desc("Utility to import data from xml file and do related tasks. Allowed options");
00257     desc.add_options()
00258     ("help,h", "print this help")
00259     ("input,i", boost::program_options::value<std::string>(), "input xml file")
00260     ("output-db,d", boost::program_options::value<std::string>(), "output postgresql database name")
00261     ("output-schema,s", boost::program_options::value<std::string>(), "output postgresql database schema")
00262     ("initialize,I", "create schema, tables keys and indexes")
00263     ("recreate-indexes,r", "drop indexes and keys before import and recreate afterward")
00264     ("no-questions,q", "do not ask questions")
00265     ("do-import,e", "execute import procedure (put data into appropriate tables)")
00266     ("analyze,a", "run analyze on database");
00267     boost::program_options::variables_map vm;
00268     boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
00269     boost::program_options::notify(vm);
00270     if (vm.count("help"))
00271     {
00272         std::cout << desc << std::endl;
00273         return 0;
00274     }
00275     bool proc_inp = false;
00276     std::string inp;
00277     if (vm.count("input"))
00278     {
00279         inp = vm["input"].as<std::string>();
00280         proc_inp = true;
00281     }
00282     std::string db;
00283     if (vm.count("output-db"))
00284     {
00285         db = vm["output-db"].as<std::string>();
00286     }
00287     std::string sch;
00288     if (vm.count("output-schema"))
00289         sch = vm["output-schema"].as<std::string>();
00290     bool init = vm.count("initialize");
00291     bool recreate = vm.count("recreate-indexes");
00292     bool quiet = vm.count("no-questions");
00293     bool process = vm.count("do-import");
00294     bool analyze = vm.count("analyze");
00295     if (!init && !analyze && !process && !proc_inp)
00296     {
00297         std::cout << "No action to be done" << std::endl;
00298         std::cout << desc << std::endl;
00299         return 0;
00300     }
00301     return import(inp, db, sch, init, recreate, proc_inp, process, quiet, analyze);
00302 
00303 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines