/home/martin/workspace/OpenStreetNav/src/osmdb/WayLister.cpp
Go to the documentation of this file.
00001 /*
00002  * WayLister.cpp
00003  *
00004  *  Created on: Jan 12, 2012
00005  *      Author: martin
00006  */
00007 
00008 #include "WayLister.h"
00009 #include <boost/property_tree/xml_parser.hpp>
00010 #include "../sqllib/sqllib.h"
00011 #include <cmath>
00012 
00013 namespace osmdb
00014 {
00015 
00016 WayLister::WayLister(OsmDatabase& db, std::multimap<std::string, std::string> const& attributes, unsigned int fetch_size):
00017     db(db),
00018     done(false),
00019     fetch_size(fetch_size)
00020 {
00021     boost::property_tree::ptree ptree = get_entries(attributes);
00022     get_way_descr = psql::Cursor<psql::BindTypes<>, psql::RetTypes<int64_t, int64_t, double, double, int64_t, std::string, std::string, int> >(db.get_db(), "wayred_crs", sqllib::get_decl_wayred_crs(ptree, db.get_db()));
00023     get_way_descr.open();
00024 }
00025 
00026 std::map<osm::Way, std::multimap<osm::Node, osm::Way, osm::LtByID>, osm::LtByID> const& WayLister::get_current_connected_ways() const
00027 {
00028     return current_connected_ways;
00029 }
00030 
00031 void WayLister::next()
00032 {
00033     current_connected_ways.clear();
00034     get_way_descr.fetch(fetch_size);
00035     if (get_way_descr.get_buffer().size() < fetch_size)
00036     {
00037         done = true;
00038     }
00039     std::vector<osm::Way> cross_ways;
00040     osm::Way last_cross_way(-1);
00041     auto const& buf = get_way_descr.get_buffer();
00042     std::multimap<osm::Node, osm::Way, osm::LtByID> conn_ways_for_way;
00043 
00044     osm::Node last_node(-1);
00045 
00046     osm::Way way(-1);
00047     unsigned int max = buf.size() + rest.size();
00048     if (done)
00049         max++;
00050     unsigned int last_wayid_change = 0;
00051     unsigned int rest_size = rest.size();
00052 
00053     //loop through returned rows and fill current_ways and current_connected_ways
00054     for (unsigned int i = 0; i < max; ++i)
00055     {
00056         int64_t wid, cwid, nid;
00057         double lon, lat;
00058         std::string key, val;
00059         int sqno;
00060         if (i < rest_size)
00061             std::tie(wid, nid, lon, lat, cwid, key, val, sqno) = rest[i];
00062         else if (i < buf.size() + rest_size)
00063             std::tie(wid, nid, lon, lat, cwid, key, val, sqno) = buf[i-rest_size];
00064         else
00065             std::tie(wid, nid, lon, lat, cwid, key, val, sqno) = std::make_tuple(-1, -1, 0, 0, -1, "", "", 0);
00066         //new way
00067         if (way.id != wid)
00068         {
00069             if (way.id != -1)
00070             {
00071                 if (last_cross_way.id != -1)
00072                 {
00073                     cross_ways.push_back(last_cross_way);
00074                 }
00075                 if (last_node.id != -1)
00076                 {
00077                     for (unsigned int j = 0; j < cross_ways.size(); ++j)
00078                         conn_ways_for_way.insert(std::pair<osm::Node, osm::Way>(last_node, cross_ways[j]));
00079                     way.nodes.push_back(last_node);
00080                 }
00081                 current_connected_ways.insert(std::make_pair(way, conn_ways_for_way));
00082             }
00083             conn_ways_for_way.clear();
00084             way.id = wid;
00085             way.nodes.clear();
00086             last_node.id = -1;
00087             last_cross_way.id = -1;
00088             last_wayid_change = i;
00089         }
00090         //new node
00091         if (last_node.id != nid)
00092         {
00093             if (last_node.id != -1)
00094             {
00095                 way.nodes.push_back(last_node);
00096                 if (last_cross_way.id != -1)
00097                     cross_ways.push_back(last_cross_way);
00098                 for (unsigned int j = 0; j < cross_ways.size(); ++j)
00099                     conn_ways_for_way.insert(std::pair<osm::Node, osm::Way>(last_node, cross_ways[j]));
00100             }
00101             last_node.id = nid;
00102             last_node.position.lon = lon;
00103             last_node.position.lat = lat;
00104             cross_ways.clear();
00105             last_cross_way.id = -1;
00106 
00107         }
00108         //new cross way
00109         if (last_cross_way.id != cwid)
00110         {
00111             if (last_cross_way.id != -1)
00112                 cross_ways.push_back(last_cross_way);
00113             last_cross_way.tags.clear();
00114             last_cross_way.id = cwid;
00115         }
00116         if (key != "")
00117             last_cross_way.tags.insert(osm::Tag(key, val));
00118     }
00119 
00120     //fix rest
00121     if (last_wayid_change != 0)
00122         rest.clear();
00123     for (unsigned int i = (unsigned int)std::max(0, (int)last_wayid_change - (int)rest_size); i < buf.size(); ++i)
00124     {
00125         rest.push_back(buf[i]);
00126     }
00127 }
00128 
00129 void WayLister::reset()
00130 {
00131     get_way_descr.close();
00132     get_way_descr.open();
00133 }
00134 
00135 bool WayLister::end()
00136 {
00137     return done;
00138 }
00139 
00140 boost::property_tree::ptree WayLister::get_entries(std::multimap<std::string, std::string> const& attributes)
00141 {
00142     boost::property_tree::ptree ret;
00143     boost::property_tree::ptree entries;
00144     for (auto it = attributes.begin(); it != attributes.end(); ++it)
00145     {
00146         boost::property_tree::ptree entry;
00147         boost::property_tree::ptree kv;
00148         kv.put("key", it->first);
00149         kv.put("value", it->second);
00150         entry.put_child("elements.el", kv);
00151         entries.add_child("entry", entry);
00152     }
00153     ret.add_child("entries", entries);
00154     return ret;
00155 }
00156 
00157 WayLister::~WayLister()
00158 {
00159 }
00160 
00161 } /* namespace osmdb */
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines