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