1 #include <iostream>
2 #include <algorithm>
3 #include "volm_osm_objects.h"
4 //:
5 // \file
6 #include "vul/vul_file.h"
7 #include <bkml/bkml_write.h>
8 #ifdef _MSC_VER
9 #  include "vcl_msvc_warnings.h"
10 #endif
11 
12 // create volm_osm_objects from open street map xml file
volm_osm_objects(std::string const & osm_file,std::string const & osm_to_volm_file)13 volm_osm_objects::volm_osm_objects(std::string const& osm_file, std::string const& osm_to_volm_file)
14 {
15   // load osm_to_volm table
16   std::map<std::pair<std::string, std::string>, volm_land_layer> osm_land_table;
17   volm_osm_category_io::load_category_table(osm_to_volm_file, osm_land_table);
18 
19   // load all open street map objects from
20   std::vector<vgl_point_2d<double> > osm_pts;
21   std::vector<std::vector<std::pair<std::string, std::string> > > osm_pt_keys;
22   volm_osm_parser::parse_points(osm_pts, osm_pt_keys, osm_file);
23 
24   std::vector<std::vector<vgl_point_2d<double> > > osm_lines;
25   std::vector<std::vector<std::pair<std::string, std::string> > > osm_line_keys;
26   volm_osm_parser::parse_lines(osm_lines, osm_line_keys, osm_file);
27 
28   std::vector<vgl_polygon<double> > osm_polys;
29   std::vector<std::vector<std::pair<std::string, std::string> > > osm_poly_keys;
30   volm_osm_parser::parse_polygons(osm_polys, osm_poly_keys, osm_file);
31 
32   // transfer osm objects to volm_osm_objects (ignore the osm objects whose properties is not defined in osm_to_volm table)
33   std::map<std::pair<std::string, std::string>, volm_land_layer>::iterator mit;
34   auto num_pts = (unsigned)osm_pts.size();
35   for (unsigned i = 0; i < num_pts; i++)
36   {
37     std::vector<std::pair<std::string, std::string> > curr_keys = osm_pt_keys[i];
38     // find pier first as first priority
39     bool pier_found = false;
40     for (auto vit = curr_keys.begin(); (vit != curr_keys.end() && !pier_found); ++vit) {
41       if (vit->first == "man_made" && vit->second == "pier") {
42         mit = osm_land_table.find(*vit);
43         if (mit != osm_land_table.end()) {
44           pier_found = true;  volm_land_layer prop = mit->second;  volm_osm_object_point_sptr loc_pt = new volm_osm_object_point(prop, osm_pts[i]);
45           loc_pts_.push_back(loc_pt);
46         }
47       }
48     }
49     if (pier_found)
50       continue;
51     bool found = false;
52     for (auto vit = curr_keys.begin(); (vit != curr_keys.end() && !found); ++vit) {
53       mit = osm_land_table.find(*vit);
54       if (mit != osm_land_table.end()) { // the key is in the table
55         found = true;
56         volm_land_layer prop = mit->second;
57         volm_osm_object_point_sptr loc_pt = new volm_osm_object_point(prop, osm_pts[i]);
58         loc_pts_.push_back(loc_pt);
59       }
60     }
61   }
62 
63   auto num_lines = (unsigned)osm_lines.size();
64   for (unsigned i = 0; i < num_lines; i++)
65   {
66     std::vector<std::pair<std::string, std::string> > curr_keys = osm_line_keys[i];
67     // find pier first as first priority
68     bool pier_found = false;
69     for (auto vit = curr_keys.begin(); (vit != curr_keys.end() && !pier_found); ++vit) {
70       if (vit->first == "man_made" && vit->second == "pier") {
71         mit = osm_land_table.find(*vit);
72         if (mit != osm_land_table.end()) {
73           pier_found = true;  volm_land_layer prop = mit->second;  volm_osm_object_line_sptr loc_line = new volm_osm_object_line(mit->second, osm_lines[i]);
74           loc_lines_.push_back(loc_line);
75         }
76       }
77     }
78     if (pier_found)
79       continue;
80     bool found = false;
81     for (auto vit = curr_keys.begin(); (vit != curr_keys.end() && !found); ++vit) {
82       mit = osm_land_table.find(*vit);
83       if (mit != osm_land_table.end()) {
84         found = true;
85         volm_osm_object_line_sptr loc_line = new volm_osm_object_line(mit->second, osm_lines[i]);
86         loc_lines_.push_back(loc_line);
87       }
88     }
89   }
90 
91   auto num_polys = (unsigned)osm_polys.size();
92   for (unsigned i = 0; i < num_polys; i++)
93   {
94     std::vector<std::pair<std::string, std::string> > curr_keys = osm_poly_keys[i];
95     // find pier first
96     bool pier_found = false;
97     for (auto vit = curr_keys.begin(); (vit != curr_keys.end() && !pier_found); ++vit) {
98       if (vit->first == "man_made" && vit->second == "pier") {
99         mit = osm_land_table.find(*vit);
100         if (mit != osm_land_table.end()) {
101           pier_found = true;  volm_osm_object_polygon_sptr loc_poly = new volm_osm_object_polygon(mit->second, osm_polys[i]);
102           loc_polys_.push_back(loc_poly);
103         }
104       }
105     }
106 
107     bool found = false;
108     for (auto vit = curr_keys.begin(); (vit != curr_keys.end() && !found); ++vit) {
109       mit = osm_land_table.find(*vit);
110       if (mit != osm_land_table.end()) {
111         found = true;
112         volm_osm_object_polygon_sptr loc_poly = new volm_osm_object_polygon(mit->second, osm_polys[i]);
113         loc_polys_.push_back(loc_poly);
114       }
115     }
116   }
117 
118 }
119 
volm_osm_objects(std::string const & bin_file)120 volm_osm_objects::volm_osm_objects(std::string const& bin_file)
121 {
122   vsl_b_ifstream is(bin_file.c_str());
123   if (!is) {
124     std::cerr << "In volm_osm_object::volm_osm_object() -- cannot open: " << bin_file << std::endl;
125     return;
126   }
127   this->b_read(is);
128   is.close();
129 }
130 
write_osm_objects(std::string const & bin_file)131 bool volm_osm_objects::write_osm_objects(std::string const& bin_file)
132 {
133   vsl_b_ofstream os(bin_file.c_str());
134   if (!os) {
135     return false;
136   }
137   this->b_write(os);
138   os.close();
139   return true;
140 }
141 
142 
b_write(vsl_b_ostream & os)143 void volm_osm_objects::b_write(vsl_b_ostream& os)
144 {
145   vsl_b_write(os, version());
146   vsl_b_write(os, loc_pts_.size());
147   for (const auto & loc_pt : loc_pts_)
148     vsl_b_write(os, loc_pt);
149   vsl_b_write(os, loc_lines_.size());
150   for (const auto & loc_line : loc_lines_)
151     vsl_b_write(os, loc_line);
152   vsl_b_write(os, loc_polys_.size());
153   for (const auto & loc_poly : loc_polys_)
154     vsl_b_write(os, loc_poly);
155 }
156 
b_read(vsl_b_istream & is)157 void volm_osm_objects::b_read(vsl_b_istream& is)
158 {
159   if (!is) return;
160   short ver;
161   vsl_b_read(is,ver);
162   if (ver == 1) {
163     unsigned loc_pts_size;
164     vsl_b_read(is, loc_pts_size);
165     for (unsigned i = 0; i < loc_pts_size; i++) {
166       volm_osm_object_point_sptr loc_pt;
167       vsl_b_read(is, loc_pt);
168       loc_pts_.push_back(loc_pt);
169     }
170     unsigned loc_lines_size;
171     vsl_b_read(is, loc_lines_size);
172     for (unsigned i = 0; i < loc_lines_size; i++) {
173       volm_osm_object_line_sptr loc_line;
174       vsl_b_read(is, loc_line);
175       loc_lines_.push_back(loc_line);
176     }
177     unsigned loc_polys_size;
178     vsl_b_read(is, loc_polys_size);
179     for (unsigned i = 0; i < loc_polys_size; i++) {
180       volm_osm_object_polygon_sptr loc_poly;
181       vsl_b_read(is, loc_poly);
182       loc_polys_.push_back(loc_poly);
183     }
184   }
185   else {
186     std::cout << "volm_osm_objects -- unknown binary io version " << ver << '\n';
187     return;
188   }
189 }
190 
write_pts_to_kml(std::string const & kml_file)191 bool volm_osm_objects::write_pts_to_kml(std::string const& kml_file)
192 {
193   std::ofstream ofs(kml_file.c_str());
194   bkml_write::open_document(ofs);
195 
196   // write the points into kml
197   unsigned cnt = 0;
198   for (auto & loc_pt : loc_pts_)
199   {
200     std::string name = loc_pt->prop().name_;
201     std::stringstream str_w;  str_w << "id=" << cnt++;
202     bkml_write::write_location(ofs, loc_pt->loc(), name, str_w.str(), 0.6);
203   }
204   bkml_write::close_document(ofs);
205   ofs.close();
206   return true;
207 }
208 
write_lines_to_kml(std::string const & kml_file)209 bool volm_osm_objects::write_lines_to_kml(std::string const& kml_file)
210 {
211   std::ofstream ofs(kml_file.c_str());
212   bkml_write::open_document(ofs);
213 
214   // write the roads into kml
215   unsigned cnt = 0;
216   for (auto & loc_line : loc_lines_)
217   {
218     double width = loc_line->prop().width_;
219     std::string name = loc_line->prop().name_;
220     std::stringstream str_w;
221     str_w << "width=" << width << ", id=" << cnt++;
222     bkml_write::write_path(ofs, loc_line->line(), name, str_w.str(), 1.0, width);
223   }
224   bkml_write::close_document(ofs);
225   ofs.close();
226   return true;
227 }
228 
write_polys_to_kml(std::string const & kml_file)229 bool volm_osm_objects::write_polys_to_kml(std::string const& kml_file)
230 {
231   std::ofstream ofs(kml_file.c_str());
232   bkml_write::open_document(ofs);
233 
234   // write the regions into kml
235   unsigned cnt = 0;
236   for (auto & loc_poly : loc_polys_)
237   {
238     unsigned char level = loc_poly->prop().level_;
239     std::string name = loc_poly->prop().name_;
240     std::stringstream str_l;
241     str_l << "level=" << (int)level << ", id=" << cnt++;
242     unsigned char r,g,b;
243     if (level == 0)      { r = 85;   g = 255;  b = 255; }
244     else if (level == 1) { r = 255;  g = 170;  b = 127; }
245     else if (level == 2) { r = 85,   g = 255;  b = 0;   }
246     else if (level == 3) { r = 170,  g = 170;  b = 255; }
247     else if (level == 4) { r = 0;    g = 255;  b = 127; }
248     else                 { r = 170;  g = 170;  b = 170; }
249     bkml_write::write_polygon(ofs, loc_poly->poly(), name, str_l.str(), 1.0, 3.0, 0.4, r, g, b);
250   }
251   bkml_write::close_document(ofs);
252   ofs.close();
253   return true;
254 }
255 
volm_osm_object_ids(std::string const & bin_file)256 volm_osm_object_ids::volm_osm_object_ids(std::string const& bin_file)
257 {
258   vsl_b_ifstream is(bin_file.c_str());
259   if (!is) {
260     std::cerr << "In volm_osm_object_ids::volm_osm_object_ids() -- cannot open file: " << bin_file << std::endl;
261     return;
262   }
263   this->b_read(is);
264   is.close();
265 }
266 
add_pt(unsigned const & pt_id)267 void volm_osm_object_ids::add_pt(unsigned const& pt_id)
268 {
269   auto vit = std::find(pt_ids_.begin(), pt_ids_.end(), pt_id);
270   if (vit == pt_ids_.end())
271     pt_ids_.push_back(pt_id);
272 }
273 
add_line(unsigned const & line_id)274 void volm_osm_object_ids::add_line(unsigned const& line_id)
275 {
276   auto vit = std::find(line_ids_.begin(), line_ids_.end(), line_id);
277   if (vit == line_ids_.end())
278     line_ids_.push_back(line_id);
279 }
280 
add_region(unsigned const & region_id)281 void volm_osm_object_ids::add_region(unsigned const& region_id)
282 {
283   auto vit = std::find(region_ids_.begin(), region_ids_.end(), region_id);
284   if (vit == region_ids_.end())
285     region_ids_.push_back(region_id);
286 }
287 
288 //: write self to binary
write_osm_ids(std::string const & bin_file)289 bool volm_osm_object_ids::write_osm_ids(std::string const& bin_file)
290 {
291   vsl_b_ofstream os(bin_file.c_str());
292   if (!os)
293     return false;
294   this->b_write(os);
295   os.close();
296   return true;
297 }
298 
299 //: binary save self to stream
b_write(vsl_b_ostream & os) const300 void volm_osm_object_ids::b_write(vsl_b_ostream& os) const
301 {
302   vsl_b_write(os, version());
303   vsl_b_write(os, pt_ids_.size());
304   for (unsigned int pt_id : pt_ids_)
305     vsl_b_write(os, pt_id);
306   vsl_b_write(os, line_ids_.size());
307   for (unsigned int line_id : line_ids_)
308     vsl_b_write(os, line_id);
309   vsl_b_write(os, region_ids_.size());
310   for (unsigned int region_id : region_ids_)
311     vsl_b_write(os, region_id);
312 }
313 
314 //: binary load self from stream
b_read(vsl_b_istream & is)315 void volm_osm_object_ids::b_read(vsl_b_istream& is)
316 {
317   if (!is) return;
318   short ver;
319   vsl_b_read(is, ver);
320   if (ver == 1) {
321     unsigned num_pts;
322     vsl_b_read(is, num_pts);
323     for (unsigned i = 0; i < num_pts; i++) {
324       unsigned id;
325       vsl_b_read(is, id);  pt_ids_.push_back(id);
326     }
327     unsigned num_lines;
328     vsl_b_read(is, num_lines);
329     for (unsigned i = 0; i < num_lines; i++) {
330       unsigned id;
331       vsl_b_read(is, id);  line_ids_.push_back(id);
332     }
333     unsigned num_regions;
334     vsl_b_read(is, num_regions);
335     for (unsigned i = 0; i < num_regions; i++) {
336       unsigned id;
337       vsl_b_read(is, id);  region_ids_.push_back(id);
338     }
339   }
340   else {
341     std::cout << "volm_osm_object_ids -- unknown binary io version " << ver << '\n';
342     return;
343   }
344 }
345