1 //This is brl/bbas/volm/pro/processes/volm_create_satellite_site_process.cxx
2 //:
3 // \file
4 #include <string>
5 #include <iostream>
6 #include <cstdio>
7 #include <functional>
8 #include <bprb/bprb_func_process.h>
9 #include <bprb/bprb_parameters.h>
10 #ifdef _MSC_VER
11 #  include "vcl_msvc_warnings.h"
12 #endif
13 
14 #include <brdb/brdb_value.h>
15 
16 #include <volm/volm_satellite_resources.h>
17 #include <volm/volm_satellite_resources_sptr.h>
18 
19 #include "vgl/vgl_polygon.h"
20 #include <bkml/bkml_parser.h>
21 
22 #include "vul/vul_file.h"
23 #include "vgl/vgl_area.h"
24 
25 //: sets input and output types
volm_create_satellite_resources_process_cons(bprb_func_process & pro)26 bool volm_create_satellite_resources_process_cons(bprb_func_process& pro)
27 {
28   //inputs
29   std::vector<std::string> input_types_(3);
30   input_types_[0] = "vcl_string";      // polygon file (kml) of ROI
31   input_types_[1] = "float";           // leaf size
32   input_types_[2] = "bool";    // if true: eliminate the images which have different names but 'same' extent and 'same' collection time up to seconds
33 
34   if (!pro.set_input_types(input_types_))
35     return false;
36   //output
37   std::vector<std::string> output_types_(1);
38   output_types_[0] = "volm_satellite_resources_sptr";
39   return pro.set_output_types(output_types_);
40 }
41 
volm_create_satellite_resources_process(bprb_func_process & pro)42 bool volm_create_satellite_resources_process(bprb_func_process& pro)
43 {
44   //check number of inputs
45   if (!pro.verify_inputs())
46   {
47     std::cout << pro.name() << " invalid inputs" << std::endl;
48     return false;
49   }
50 
51   //get the inputs
52   std::string poly_file = pro.get_input<std::string>(0);
53   auto leaf_size = pro.get_input<float>(1);
54   bool eliminate_same = pro.get_input<bool>(2);
55 
56   // find the bbox of the polygon
57   vgl_polygon<double> poly = bkml_parser::parse_polygon(poly_file);
58   std::cout << "outer poly  has: " << poly[0].size() << " points " << std::endl;
59 
60   // find the bbox of ROI from its polygon
61   vgl_box_2d<double> bbox;
62   for (auto i : poly[0]) {
63     bbox.add(i);
64   }
65   std::cout << "bbox of ROI: " << bbox << std::endl;
66 
67   volm_satellite_resources_sptr res = new volm_satellite_resources(bbox, leaf_size,eliminate_same);
68   pro.set_output_val<volm_satellite_resources_sptr>(0, res);
69 
70   return true;
71 }
72 
73 
volm_save_satellite_resources_process_cons(bprb_func_process & pro)74 bool volm_save_satellite_resources_process_cons(bprb_func_process& pro)
75 {
76   //inputs
77   std::vector<std::string> input_types_(2);
78   input_types_[0] = "volm_satellite_resources_sptr";
79   input_types_[1] = "vcl_string";      // output file to save as binar
80 
81   if (!pro.set_input_types(input_types_))
82     return false;
83   //output
84   std::vector<std::string> output_types_(0);
85   return pro.set_output_types(output_types_);
86 }
87 
volm_save_satellite_resources_process(bprb_func_process & pro)88 bool volm_save_satellite_resources_process(bprb_func_process& pro)
89 {
90   //check number of inputs
91   if (!pro.verify_inputs())
92   {
93     std::cout << pro.name() << " invalid inputs" << std::endl;
94     return false;
95   }
96 
97   //get the inputs
98   volm_satellite_resources_sptr res = pro.get_input<volm_satellite_resources_sptr>(0);
99   std::string out_file = pro.get_input<std::string>(1);
100 
101   vsl_b_ofstream ofs(out_file);
102   res->b_write(ofs);
103   ofs.close();
104 
105   pro.set_output_val<volm_satellite_resources_sptr>(0, res);
106 
107   return true;
108 }
109 
volm_load_satellite_resources_process_cons(bprb_func_process & pro)110 bool volm_load_satellite_resources_process_cons(bprb_func_process& pro)
111 {
112   //inputs
113   std::vector<std::string> input_types_(1);
114   input_types_[0] = "vcl_string";
115 
116   if (!pro.set_input_types(input_types_))
117     return false;
118   //output
119   std::vector<std::string> output_types_(1);
120   output_types_[0] = "volm_satellite_resources_sptr";
121   return pro.set_output_types(output_types_);
122 }
123 
volm_load_satellite_resources_process(bprb_func_process & pro)124 bool volm_load_satellite_resources_process(bprb_func_process& pro)
125 {
126   //check number of inputs
127   if (!pro.verify_inputs())
128   {
129     std::cout << pro.name() << " invalid inputs" << std::endl;
130     return false;
131   }
132 
133   //get the inputs
134   std::string res_file = pro.get_input<std::string>(0);
135 
136   volm_satellite_resources_sptr res = new volm_satellite_resources();
137   vsl_b_ifstream is(res_file);
138   res->b_read(is);
139   is.close();
140 
141   std::cout << "there are " << res->resources_size() << " resources in the file!\n";
142 
143   pro.set_output_val<volm_satellite_resources_sptr>(0, res);
144   return true;
145 }
146 
147 
volm_query_satellite_resources_process_cons(bprb_func_process & pro)148 bool volm_query_satellite_resources_process_cons(bprb_func_process& pro)
149 {
150   //inputs
151   std::vector<std::string> input_types_(10);
152   input_types_[0] = "volm_satellite_resources_sptr";
153   input_types_[1] = "double";      // lower left lon
154   input_types_[2] = "double";      // lower left lat
155   input_types_[3] = "double";      // upper right lon
156   input_types_[4] = "double";      // upper right lat
157   input_types_[5] = "vcl_string";      // output file to print the list
158   input_types_[6] = "vcl_string";      // the band: PAN or MULTI
159   input_types_[7] = "bool";      // if TRUE, pick seed images randomly with a certain order of satellites
160   input_types_[8] = "int";       // number of seed images to pick, if not enough then creates from all available
161   input_types_[9] = "double";       // GSD threshold in meters, any image with GSD more than this GSD will not be returned, e.g. pass 1 to eliminate images with pixel resolution more than 1 meter
162 
163   if (!pro.set_input_types(input_types_))
164     return false;
165   //output
166   std::vector<std::string> output_types_(1);
167   output_types_[0] = "unsigned";  // return number of resources that intersect this region
168   return pro.set_output_types(output_types_);
169 }
170 
volm_query_satellite_resources_process(bprb_func_process & pro)171 bool volm_query_satellite_resources_process(bprb_func_process& pro)
172 {
173   //check number of inputs
174   if (!pro.verify_inputs())
175   {
176     std::cout << pro.name() << " invalid inputs" << std::endl;
177     return false;
178   }
179 
180   //get the inputs
181   volm_satellite_resources_sptr res = pro.get_input<volm_satellite_resources_sptr>(0);
182   auto lower_left_lon = pro.get_input<double>(1);
183   auto lower_left_lat = pro.get_input<double>(2);
184   auto upper_right_lon = pro.get_input<double>(3);
185   auto upper_right_lat = pro.get_input<double>(4);
186   std::string out_file = pro.get_input<std::string>(5);
187   std::string band = pro.get_input<std::string>(6);
188   bool pick_seed = pro.get_input<bool>(7);
189   int n_seeds = pro.get_input<int>(8);
190   auto gsd_thres = pro.get_input<double>(9);
191 
192   unsigned cnt; bool out = false;
193   if (!pick_seed) {
194     out = res->query_print_to_file(lower_left_lon, lower_left_lat, upper_right_lon, upper_right_lat, cnt, out_file, band, gsd_thres);
195     pro.set_output_val<unsigned>(0, cnt);
196   } else {
197     out = res->query_seeds_print_to_file(lower_left_lon, lower_left_lat, upper_right_lon, upper_right_lat, n_seeds, cnt, out_file, band, gsd_thres);
198     pro.set_output_val<unsigned>(0, cnt);
199   }
200   return out;
201 }
202 
203 
204 // obtain the satellite resources that intersects with given polygon
volm_query_satellite_resources_kml_process_cons(bprb_func_process & pro)205 bool volm_query_satellite_resources_kml_process_cons(bprb_func_process& pro)
206 {
207   // inputs
208   std::vector<std::string> input_types_(7);
209   input_types_[0] = "volm_satellite_resources_sptr";  // satellite resource
210   input_types_[1] = "vcl_string";                     // kml polygon
211   input_types_[2] = "vcl_string";                     // output file to print the list
212   input_types_[3] = "vcl_string";                     // the band: PAN or MULTI
213   input_types_[4] = "bool";                           // if TRUE, pick seed images randomly with a certain order of satellites
214   input_types_[5] = "int";                            // number of seed images to pick, if not enough then creates from all available
215   input_types_[6] = "double";                         // GSD threshold in meters, any image with GSD more than this GSD will not be returned, e.g. pass 1 to eliminate images with pixel resolution more than 1 meter
216 
217   // output
218   std::vector<std::string> output_types_(1);
219   output_types_[0] = "unsigned";  // return number of resources that intersect this region
220   return pro.set_input_types(input_types_) && pro.set_output_types(output_types_);
221 
222 }
223 
volm_query_satellite_resources_kml_process(bprb_func_process & pro)224 bool volm_query_satellite_resources_kml_process(bprb_func_process& pro)
225 {
226   // check inputs
227   if (!pro.verify_inputs())
228   {
229     std::cout << pro.name() << " invalid inputs" << std::endl;
230     return false;
231   }
232 
233   // get the inputs
234   volm_satellite_resources_sptr res = pro.get_input<volm_satellite_resources_sptr>(0);
235   std::string kml_file = pro.get_input<std::string>(1);
236   std::string out_file = pro.get_input<std::string>(2);
237   std::string band = pro.get_input<std::string>(3);
238   bool pick_seed = pro.get_input<bool>(4);
239   int n_seeds = pro.get_input<int>(5);
240   auto gsd_thres = pro.get_input<double>(6);
241 
242   // parse the polygon and construct its bounding box
243   if (!vul_file::exists(kml_file)) {
244     std::cout << pro.name() << ": can not find input kml file: " << kml_file << std::endl;
245     return false;
246   }
247   vgl_polygon<double> poly = bkml_parser::parse_polygon(kml_file);
248   vgl_box_2d<double> bbox;
249   for (auto i : poly[0])
250     bbox.add(i);
251   double lower_left_lon  = bbox.min_x();
252   double lower_left_lat  = bbox.min_y();
253   double upper_right_lon = bbox.max_x();
254   double upper_right_lat = bbox.max_y();
255 
256   unsigned cnt;  bool out = false;
257   if (!pick_seed) {
258     out = res->query_print_to_file(lower_left_lon, lower_left_lat, upper_right_lon, upper_right_lat, cnt, out_file, band, gsd_thres);
259     pro.set_output_val<unsigned>(0, cnt);
260   } else {
261     out = res->query_seeds_print_to_file(lower_left_lon, lower_left_lat, upper_right_lon, upper_right_lat, n_seeds, cnt, out_file, band, gsd_thres);
262     pro.set_output_val<unsigned>(0, cnt);
263   }
264   return out;
265 
266 }
267 
268 //: sets input and output types
volm_add_satellite_resources_process_cons(bprb_func_process & pro)269 bool volm_add_satellite_resources_process_cons(bprb_func_process& pro)
270 {
271   //inputs
272   std::vector<std::string> input_types_(2);
273   input_types_[0] = "volm_satellite_resources_sptr";
274   input_types_[1] = "vcl_string"; // folder -- will be traversed recursively to find NITF files and add to the resources
275 
276   if (!pro.set_input_types(input_types_))
277     return false;
278   //output
279   std::vector<std::string> output_types_(0);
280   return pro.set_output_types(output_types_);
281 }
282 
volm_add_satellite_resources_process(bprb_func_process & pro)283 bool volm_add_satellite_resources_process(bprb_func_process& pro)
284 {
285   //check number of inputs
286   if (!pro.verify_inputs())
287   {
288     std::cout << pro.name() << " invalid inputs" << std::endl;
289     return false;
290   }
291 
292   //get the inputs
293   volm_satellite_resources_sptr res = pro.get_input<volm_satellite_resources_sptr>(0);
294   std::string folder = pro.get_input<std::string>(1);
295   res->add_path(folder);
296 
297   std::cout << " AFTER addition, there are " << res->resources_size() << " resources in the file!\n";
298   return true;
299 }
300 
volm_pick_nadir_resource_process_cons(bprb_func_process & pro)301 bool volm_pick_nadir_resource_process_cons(bprb_func_process& pro)
302 {
303   //inputs
304   std::vector<std::string> input_types_(8);
305   input_types_[0] = "volm_satellite_resources_sptr";
306   input_types_[1] = "double";      // lower left lon
307   input_types_[2] = "double";      // lower left lat
308   input_types_[3] = "double";      // upper right lon
309   input_types_[4] = "double";      // upper right lat
310   input_types_[5] = "vcl_string";      // the band: PAN or MULTI
311   input_types_[6] = "vcl_string";      // satellite name
312   input_types_[7] = "vcl_string";      // a folder where all the non-cloud images saved for current rectangular region
313 
314   if (!pro.set_input_types(input_types_))
315     return false;
316   //output
317   std::vector<std::string> output_types_(1);
318   output_types_[0] = "vcl_string";  // full path of the satellite image
319   return pro.set_output_types(output_types_);
320 }
321 
volm_pick_nadir_resource_process(bprb_func_process & pro)322 bool volm_pick_nadir_resource_process(bprb_func_process& pro)
323 {
324   //check number of inputs
325   if (!pro.verify_inputs())
326   {
327     std::cout << pro.name() << " invalid inputs" << std::endl;
328     return false;
329   }
330 
331   //get the inputs
332   volm_satellite_resources_sptr res = pro.get_input<volm_satellite_resources_sptr>(0);
333   auto lower_left_lon = pro.get_input<double>(1);
334   auto lower_left_lat = pro.get_input<double>(2);
335   auto upper_right_lon = pro.get_input<double>(3);
336   auto upper_right_lat = pro.get_input<double>(4);
337   std::string band = pro.get_input<std::string>(5);
338   std::string sat_name = pro.get_input<std::string>(6);
339   std::string non_cloud_folder = pro.get_input<std::string>(7);
340 
341   std::vector<unsigned> ids;
342   res->query(lower_left_lon, lower_left_lat, upper_right_lon, upper_right_lat, band, ids,10.0); // pass gsd_thres very high, only interested in finding all the images that intersect the box
343   double largest_view_angle = -100.0;
344   unsigned id = 0;
345   for (unsigned int i : ids) {
346     if (res->resources_[i].meta_->satellite_name_.compare(sat_name) == 0) {
347       std::cout << "res: " << res->resources_[i].name_
348                << " view azimuth: " << res->resources_[i].meta_->view_azimuth_
349                << " view elev: " << res->resources_[i].meta_->view_elevation_ << '\n';
350       // pick the image with largest view angle and least could coverage if possible
351       if (largest_view_angle < res->resources_[i].meta_->view_elevation_) {
352         // check whether this image is non-cloud one or not
353         if (non_cloud_folder.compare("") != 0) {
354           std::string non_cloud_img = non_cloud_folder + "/" + res->resources_[i].name_ + "_cropped.tif";
355           if (vul_file::exists(non_cloud_img)) {
356             largest_view_angle = res->resources_[i].meta_->view_elevation_;
357             id = i;
358           }
359         }
360         else {  // TO DO -- add edge detection here if non-cloud images folder is not given
361           largest_view_angle = res->resources_[i].meta_->view_elevation_;
362           id = i;
363         }
364       }
365     }
366   }
367   std::cout << "picked: " << res->resources_[id].full_path_ << std::endl;
368   pro.set_output_val<std::string>(0, res->resources_[id].full_path_);
369   return true;
370 }
371 
372 // find the non-cloud PAN/MULTI pair from satellite resource
373 // Note it will output all PAN/MULTI pairs that intersect with current scene, sorted by the view angles
volm_pick_nadir_resource_pair_process_cons(bprb_func_process & pro)374 bool volm_pick_nadir_resource_pair_process_cons(bprb_func_process& pro)
375 {
376   //inputs
377   std::vector<std::string> input_types_(9);
378   input_types_[0] = "volm_satellite_resources_sptr";
379   input_types_[1] = "double";      // lower left lon
380   input_types_[2] = "double";      // lower left lat
381   input_types_[3] = "double";      // upper right lon
382   input_types_[4] = "double";      // upper right lat
383   input_types_[5] = "vcl_string";      // the band: PAN or MULTI
384   input_types_[6] = "vcl_string";      // satellite name
385   input_types_[7] = "vcl_string";      // a folder where all the non-cloud images saved for current rectangular region
386   input_types_[8] = "vcl_string";      // folder where the sorted PAN/MULTI pair list file will be stored
387   // output
388   std::vector<std::string> output_types_(2);
389   output_types_[0] = "vcl_string";  // full path of the PAN image
390   output_types_[1] = "vcl_string";  // full path of the MULTI image
391   return pro.set_output_types(output_types_) && pro.set_input_types(input_types_);
392 }
393 
volm_pick_nadir_resource_pair_process(bprb_func_process & pro)394 bool volm_pick_nadir_resource_pair_process(bprb_func_process& pro)
395 {
396   // input check
397   if (!pro.verify_inputs())
398   {
399     std::cout << pro.name() << " invalid inputs" << std::endl;
400     return false;
401   }
402   // get the inputs
403   volm_satellite_resources_sptr res = pro.get_input<volm_satellite_resources_sptr>(0);
404   auto lower_left_lon = pro.get_input<double>(1);
405   auto lower_left_lat = pro.get_input<double>(2);
406   auto upper_right_lon = pro.get_input<double>(3);
407   auto upper_right_lat = pro.get_input<double>(4);
408   std::string band = pro.get_input<std::string>(5);
409   std::string sat_name = pro.get_input<std::string>(6);
410   std::string non_cloud_folder = pro.get_input<std::string>(7);
411   std::string out_folder = pro.get_input<std::string>(8);
412   // obtain resources having given band that overlap with current region
413   std::vector<unsigned> ids;
414   res->query(lower_left_lon, lower_left_lat, upper_right_lon, upper_right_lat, band, ids,10.0);
415   // map of resources that have given band and sat_name, sorted by the view angle
416   std::map<double, unsigned, std::greater<double> > band_res;
417   for (unsigned int & id : ids)
418     if (res->resources_[id].meta_->satellite_name_.compare(sat_name) == 0)
419       band_res.insert(std::pair<double, unsigned>(res->resources_[id].meta_->view_elevation_, id));
420 
421   // text file where the sorted PAN/MULTI pair will be stored
422   std::string out_txt = out_folder + "/pan_multi_pair_list.txt";
423   std::ofstream ofs(out_txt.c_str());
424   ofs << "view_angle(deg) \t pan_img \t multi_img \t" << std::endl;
425 
426   // find the PAN/MULTI pair
427   std::map<double, std::pair<std::string, std::string>, std::greater<double> > pairs;
428   for (auto & band_re : band_res) {
429     std::string img_name = res->resources_[band_re.second].name_;
430     std::string pair_name = res->find_pair(img_name);
431     if (pair_name.compare("") == 0)
432       continue;
433     if (non_cloud_folder.compare("") != 0)
434     {
435       std::string non_cloud_img_band = non_cloud_folder + "/" + img_name  + "_cropped.tif";
436       std::cout << " view_angle = " << band_re.first << " img_name = " << res->resources_[band_re.second].full_path_
437              << " pair_name = " << res->full_path(pair_name).first
438              << " non_cloud_img = " << non_cloud_img_band
439              << std::endl;
440       if (vul_file::exists(non_cloud_img_band)) {
441         std::pair<std::string, std::string> name_pair;
442         if (band == "PAN") {
443           name_pair.first  = res->resources_[band_re.second].full_path_;
444           name_pair.second = res->full_path(pair_name).first;
445         }
446         else if (band == "MULTI") {
447           name_pair.first  = res->full_path(pair_name).first;
448           name_pair.second = res->resources_[band_re.second].full_path_;
449         }
450         else {
451           std::cout << pro.name() << ": unknown input band " << band << std::endl;
452           return false;
453         }
454         pairs.insert(std::pair<double, std::pair<std::string, std::string> >(band_re.first, name_pair));
455       }
456     }
457     else {
458       std::pair<std::string, std::string> name_pair;
459       if (band == "PAN") {
460         name_pair.first = res->resources_[band_re.second].full_path_;
461         name_pair.second = res->full_path(pair_name).first;
462       } else if (band == "MULTI") {
463         name_pair.first = res->full_path(pair_name).first;
464         name_pair.second = res->resources_[band_re.second].full_path_;
465       } else {
466         std::cout << pro.name() << ": unknown input band " << band << std::endl;
467         return false;
468       }
469       pairs.insert(std::pair<double, std::pair<std::string, std::string> >(band_re.first, name_pair));
470     }
471   }
472   // output
473   if (pairs.size() == 0) {
474     std::cout << pro.name() << ": can not find any PAN/MULTI pair for current scene" << std::endl;
475     return false;
476   }
477 
478   for (auto & mit : pairs)
479     ofs << mit.first << " \t " << mit.second.first << " \t " << mit.second.second << std::endl;
480   ofs.close();
481 
482   pro.set_output_val<std::string>(0, pairs.begin()->second.first);
483   pro.set_output_val<std::string>(1, pairs.begin()->second.second);
484 
485 #if 0
486   for (std::map<double, unsigned, std::greater<double> >::iterator mit = band_res.begin(); mit != band_res.end(); ++mit) {
487     std::string img_name = res->resources_[mit->second].name_;
488     std::string pair_name = res->find_pair(img_name);
489     if (pair_name.compare("") == 0)
490       continue;
491     if (non_cloud_folder.compare("") != 0)
492     {
493       std::string non_cloud_img_band = non_cloud_folder + "/" + img_name  + "_cropped.tif";
494       if (vul_file::exists(non_cloud_img_band)) {
495         std::string pan_path, multi_path;
496         if (band == "PAN") {
497           pan_path = res->resources_[mit->second].full_path_;
498           std::pair<std::string, std::string> pp = res->full_path(pair_name);
499           multi_path = pp.first;
500         }
501         else if (band == "MULTI") {
502           multi_path = res->resources_[mit->second].full_path_;
503           std::pair<std::string, std::string> pp = res->full_path(pair_name);
504           pan_path = pp.first;
505         }
506         else {
507           std::cout << pro.name() << ": unknown input band " << band << std::endl;
508           return false;
509         }
510         pro.set_output_val<std::string>(0, pan_path);
511         pro.set_output_val<std::string>(1, multi_path);
512         return true;
513       }
514     }
515     else // TO DO -- add edge detection here if non-cloud images folder is not given
516     {
517       std::string pan_path, multi_path;
518       if (band == "PAN") {
519         pan_path = res->resources_[mit->second].full_path_;
520         std::pair<std::string, std::string> pp = res->full_path(pair_name);
521         multi_path = pp.first;
522       }
523       else if (band == "MULTI") {
524         multi_path = res->resources_[mit->second].full_path_;
525         std::pair<std::string, std::string> pp = res->full_path(pair_name);
526         pan_path = pp.first;
527       }
528       else {
529         std::cout << pro.name() << ": unknown input band " << band << std::endl;
530         return false;
531       }
532       pro.set_output_val<std::string>(0, pan_path);
533       pro.set_output_val<std::string>(1, multi_path);
534       return true;
535     }
536   }
537 
538   return false;
539 #endif
540 
541   return true;
542 }
543 
544 // find the PAN counterpart if given a multi band image, and vice versa
volm_get_full_path_process_cons(bprb_func_process & pro)545 bool volm_get_full_path_process_cons(bprb_func_process& pro)
546 {
547   //inputs
548   std::vector<std::string> input_types_(2);
549   input_types_[0] = "volm_satellite_resources_sptr";
550   input_types_[1] = "vcl_string";      // satellite img name
551 
552   if (!pro.set_input_types(input_types_))
553     return false;
554   //output
555   std::vector<std::string> output_types_(1);
556   output_types_[0] = "vcl_string";  // full path of the satellite whose name is passed
557   return pro.set_output_types(output_types_);
558 }
559 
volm_get_full_path_process(bprb_func_process & pro)560 bool volm_get_full_path_process(bprb_func_process& pro)
561 {
562   //check number of inputs
563   if (!pro.verify_inputs())
564   {
565     std::cout << pro.name() << " invalid inputs" << std::endl;
566     return false;
567   }
568 
569   //get the inputs
570   volm_satellite_resources_sptr res = pro.get_input<volm_satellite_resources_sptr>(0);
571   std::string name = pro.get_input<std::string>(1);
572   std::pair<std::string, std::string> full = res->full_path(name);
573   pro.set_output_val<std::string>(0, full.first);
574   return true;
575 }
576 
577 // find the PAN counterpart if given a multi band image, and vice versa
volm_find_res_pair_process_cons(bprb_func_process & pro)578 bool volm_find_res_pair_process_cons(bprb_func_process& pro)
579 {
580   //inputs
581   std::vector<std::string> input_types_(3);
582   input_types_[0] = "volm_satellite_resources_sptr";
583   input_types_[1] = "vcl_string";      // satellite img name  // only the name, don't need the full path
584   input_types_[2] = "double";          // tolerance of footprint difference ( in meters)
585   if (!pro.set_input_types(input_types_))
586     return false;
587   //output
588   std::vector<std::string> output_types_(3);
589   output_types_[0] = "vcl_string";  // full path of the satellite whose name is passed
590   output_types_[1] = "vcl_string";  // name of the pair satellite image, process returns false if not found
591   output_types_[2] = "vcl_string";  // full path of the pair satellite image, process returns false if not found
592   return pro.set_output_types(output_types_);
593 }
594 
volm_find_res_pair_process(bprb_func_process & pro)595 bool volm_find_res_pair_process(bprb_func_process& pro)
596 {
597   //check number of inputs
598   if (!pro.verify_inputs())
599   {
600     std::cout << pro.name() << " invalid inputs" << std::endl;
601     return false;
602   }
603 
604   //get the inputs
605   volm_satellite_resources_sptr res = pro.get_input<volm_satellite_resources_sptr>(0);
606   std::string name = pro.get_input<std::string>(1);
607   auto tol = pro.get_input<double>(2);
608   std::pair<std::string, std::string> full = res->full_path(name);
609   std::string pair_name = res->find_pair(name, tol);
610   std::cout << "pair_name = " << pair_name << std::endl;
611   if (pair_name.compare("") == 0) {
612     pro.set_output_val<std::string>(0, "");
613     pro.set_output_val<std::string>(1, "");
614     pro.set_output_val<std::string>(2, "");
615     return false;
616   }
617   std::pair<std::string, std::string> pp = res->full_path(pair_name);
618   pro.set_output_val<std::string>(0, full.first);
619   pro.set_output_val<std::string>(1, pair_name);
620   pro.set_output_val<std::string>(2, pp.first);
621   return true;
622 }
623 
624 // a process to return a text file with names of 'pairs' of satellite images that are taken a few minutes apart from each other
volm_find_satellite_pairs_process_cons(bprb_func_process & pro)625 bool volm_find_satellite_pairs_process_cons(bprb_func_process& pro)
626 {
627   //inputs
628   std::vector<std::string> input_types_(8);
629   input_types_[0] = "volm_satellite_resources_sptr";
630   input_types_[1] = "double";      // lower left lon
631   input_types_[2] = "double";      // lower left lat
632   input_types_[3] = "double";      // upper right lon
633   input_types_[4] = "double";      // upper right lat
634   input_types_[5] = "vcl_string";      // output file to print the list
635   input_types_[6] = "vcl_string";      // satellite name
636   input_types_[7] = "float";       // GSD_threshold
637 
638   if (!pro.set_input_types(input_types_))
639     return false;
640   //output
641   std::vector<std::string> output_types_(1);
642   output_types_[0] = "unsigned";  // return number of pairs that intersect this region
643   return pro.set_output_types(output_types_);
644 }
645 
volm_find_satellite_pairs_process(bprb_func_process & pro)646 bool volm_find_satellite_pairs_process(bprb_func_process& pro)
647 {
648   //check number of inputs
649   if (!pro.verify_inputs())
650   {
651     std::cout << pro.name() << " invalid inputs" << std::endl;
652     return false;
653   }
654 
655   //get the inputs
656   volm_satellite_resources_sptr res = pro.get_input<volm_satellite_resources_sptr>(0);
657   auto lower_left_lon = pro.get_input<double>(1);
658   auto lower_left_lat = pro.get_input<double>(2);
659   auto upper_right_lon = pro.get_input<double>(3);
660   auto upper_right_lat = pro.get_input<double>(4);
661   std::string out_file = pro.get_input<std::string>(5);
662   std::string sat_name = pro.get_input<std::string>(6);
663   auto GSD_thres = pro.get_input<float>(7);
664 
665   unsigned cnt = 0; bool out = false;
666   out = res->query_pairs_print_to_file(lower_left_lon, lower_left_lat, upper_right_lon, upper_right_lat, GSD_thres, cnt, out_file, sat_name);
667   pro.set_output_val<unsigned>(0, cnt);
668   return out;
669 }
670 
671 // a process to return a text file with names of 'pairs' of satellite images that are taken a few miutues apart from each other
672 // (the time difference is within 5 minutes and more than 1 minutes)
volm_find_satellite_pairs_poly_process_cons(bprb_func_process & pro)673 bool volm_find_satellite_pairs_poly_process_cons(bprb_func_process& pro)
674 {
675   //inputs
676   std::vector<std::string> input_types_(5);
677   input_types_[0] = "volm_satellite_resources_sptr";
678   input_types_[1] = "vcl_string";      // kml file that gives the region of interest polygon
679   input_types_[2] = "vcl_string";      // output file to print the list
680   input_types_[3] = "vcl_string";      // satellite name
681   input_types_[4] = "float";       // GSD_threshold
682   if (!pro.set_input_types(input_types_))
683     return false;
684   //output
685   std::vector<std::string> output_types_(1);
686   output_types_[0] = "unsigned";  // return number of pairs that intersect this region
687   return pro.set_output_types(output_types_);
688 }
689 
volm_find_satellite_pairs_poly_process(bprb_func_process & pro)690 bool volm_find_satellite_pairs_poly_process(bprb_func_process& pro)
691 {
692   // check number of inputs
693   if (!pro.verify_inputs())
694   {
695     std::cout << pro.name() << " invalid inputs" << std::endl;
696     return false;
697   }
698   //get the inputs
699   volm_satellite_resources_sptr res = pro.get_input<volm_satellite_resources_sptr>(0);
700   std::string poly_file = pro.get_input<std::string>(1);
701   std::string out_file = pro.get_input<std::string>(2);
702   std::string sat_name = pro.get_input<std::string>(3);
703   auto GSD_thres = pro.get_input<float>(4);
704 
705   // find the bbox of the polygon
706   vgl_polygon<double> poly = bkml_parser::parse_polygon(poly_file);
707   std::cout << "outer poly  has: " << poly[0].size() << " points " << std::endl;
708 
709   // find the bbox of ROI from its polygon
710   vgl_box_2d<double> bbox;
711   for (auto i : poly[0]) {
712     bbox.add(i);
713   }
714   double lower_left_lon  = bbox.min_x();
715   double lower_left_lat  = bbox.min_y();
716   double upper_right_lon = bbox.max_x();
717   double upper_right_lat = bbox.max_y();
718 
719   unsigned cnt = 0; bool out = false;
720   out = res->query_pairs_print_to_file(lower_left_lon, lower_left_lat, upper_right_lon, upper_right_lat, GSD_thres, cnt, out_file, sat_name);
721   pro.set_output_val<unsigned>(0, cnt);
722   return out;
723 }
724 
725 #include "vgl/vgl_intersection.h"
726 // a simple process to return the area of the region where to satellite images intersect
volm_satellite_pair_intersection_process_cons(bprb_func_process & pro)727 bool volm_satellite_pair_intersection_process_cons(bprb_func_process& pro)
728 {
729   //inputs
730   std::vector<std::string> input_types_(2);
731   input_types_[0] = "vcl_string";      // satellite image 1
732   input_types_[1] = "vcl_string";      // satellite image 2
733   if (!pro.set_input_types(input_types_))
734     return false;
735   //output
736   std::vector<std::string> output_types_(5);
737   output_types_[0] = "double";  // lower left  lon of intersection region
738   output_types_[1] = "double";  // lower left  lat of intersection region
739   output_types_[2] = "double";  // upper right lon of intersection region
740   output_types_[3] = "double";  // upper right lat of intersection region
741   output_types_[4] = "double";  // intersection area
742   return pro.set_output_types(output_types_);
743 }
744 
volm_satellite_pair_intersection_process(bprb_func_process & pro)745 bool volm_satellite_pair_intersection_process(bprb_func_process& pro)
746 {
747   // check number of inputs
748   if (!pro.verify_inputs())
749   {
750     std::cout << pro.name() << " invalid inputs" << std::endl;
751     return false;
752   }
753   //get the inputs
754   volm_satellite_resources_sptr res = pro.get_input<volm_satellite_resources_sptr>(0);
755   std::string img_file1 = pro.get_input<std::string>(1);
756   std::string img_file2 = pro.get_input<std::string>(2);
757 
758   if (!vul_file::exists(img_file1)) {
759     std::cout << pro.name() << ": " << img_file1 << " is missing" << std::endl;
760     return false;
761   }
762   if (!vul_file::exists(img_file2)) {
763     std::cout << pro.name() << ": " << img_file2 << " is missing" << std::endl;
764     return false;
765   }
766 
767   // load two nitf images
768   brad_image_metadata meta1(img_file1,"");
769   brad_image_metadata meta2(img_file2,"");
770   vgl_box_2d<double> bbox1(meta1.lower_left_.x(), meta1.upper_right_.x(),
771                            meta1.lower_left_.y(), meta1.upper_right_.y());
772   vgl_box_2d<double> bbox2(meta2.lower_left_.x(), meta2.upper_right_.x(),
773                            meta2.lower_left_.y(), meta2.upper_right_.y());
774 
775   vgl_box_2d<double> intersection_bbox = vgl_intersection(bbox1, bbox2);
776   double area = vgl_area(intersection_bbox);
777 
778   // generate output
779   unsigned i = 0;
780   pro.set_output_val<double>(i++, intersection_bbox.min_x());
781   pro.set_output_val<double>(i++, intersection_bbox.min_y());
782   pro.set_output_val<double>(i++, intersection_bbox.max_x());
783   pro.set_output_val<double>(i++, intersection_bbox.max_y());
784   pro.set_output_val<double>(i++, area);
785   return true;
786 
787 
788 
789 }
790