00001
00002
00003
00004
00005
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
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
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
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
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
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 }