1 // This is brl/bseg/bvxm/pro/processes/bvxm_create_ortho_camera_process.cxx
2 #include "bvxm_create_ortho_camera_process.h"
3 //:
4 // \file
5 #include <bprb/bprb_func_process.h>
6 #include <bvxm/bvxm_voxel_world.h>
7 #include <bvxm/bvxm_image_metadata.h>
8 #include <bvxm/bvxm_edge_ray_processor.h>
9 #include <brip/brip_vil_float_ops.h>
10 #include "vil/vil_image_view.h"
11 #include "vpgl/vpgl_utm.h"
12
bvxm_create_ortho_camera_process_cons(bprb_func_process & pro)13 bool bvxm_create_ortho_camera_process_cons(bprb_func_process& pro)
14 {
15 using namespace bvxm_create_ortho_camera_process_globals;
16 std::vector<std::string> input_types_(n_inputs_);
17 input_types_[0] = "bvxm_voxel_world_sptr";
18 input_types_[1] = "bool";
19 if (!pro.set_input_types(input_types_))
20 return false;
21
22 std::vector<std::string> output_types_(n_outputs_);
23 output_types_[0] = "vpgl_camera_double_sptr"; // return the ortho camera of the scene, as it may be needed for other processes
24 return pro.set_output_types(output_types_);
25 }
26
27 // generates an ortho camera from the scene bounding box, GSD of the image is 1 meter
bvxm_create_ortho_camera_process(bprb_func_process & pro)28 bool bvxm_create_ortho_camera_process(bprb_func_process& pro)
29 {
30 using namespace bvxm_create_ortho_camera_process_globals;
31
32 if (pro.n_inputs()<n_inputs_)
33 {
34 std::cout << pro.name() << " The input number should be " << n_inputs_<< std::endl;
35 return false;
36 }
37
38 //voxel_world
39 bvxm_voxel_world_sptr world = pro.get_input<bvxm_voxel_world_sptr>(0);
40 if (!world) {
41 std::cout << pro.name() <<" :-- Input 0 is not valid!\n";
42 return false;
43 }
44
45 bool is_utm = pro.get_input<bool>(1);
46
47 // generate vpgl_geo_camera for the scene
48 bvxm_world_params_sptr params = world->get_params();
49 vgl_box_3d<double> box = params->world_box_local();
50 vgl_point_3d<float> corner = params->corner();
51 vgl_point_3d<float> upper_left(corner.x(), (float)(corner.y() + box.height()), corner.z());
52 vgl_point_3d<float> lower_right((float)(corner.x()+box.width()), corner.y(), corner.z());
53 float voxel_length = params->voxel_length();
54
55 vpgl_lvcs_sptr lvcs = params->lvcs();
56 double lat, lon, elev;
57 lvcs->get_origin(lat, lon, elev);
58 std::cout << " lvcs origin: " << lat << " " << lon << " " << elev << std::endl;
59
60 // determine the upper left corner to use a vpgl_geo_cam, WARNING: assumes that the world is compass-alinged
61 double upper_left_lon, upper_left_lat, upper_left_elev;
62 lvcs->local_to_global(upper_left.x(), upper_left.y(), upper_left.z(), vpgl_lvcs::wgs84, upper_left_lon, upper_left_lat, upper_left_elev);
63 std::cout << "upper left corner in the image is: " << upper_left_lon << " lat: " << upper_left_lat << std::endl;
64
65 double lower_right_lon, lower_right_lat, lower_right_elev;
66 lvcs->local_to_global(lower_right.x(), lower_right.y(), lower_right.z(), vpgl_lvcs::wgs84, lower_right_lon, lower_right_lat, lower_right_elev);
67 std::cout << "lower right corner in the image is: " << lower_right_lon << " lat: " << lower_right_lat << std::endl;
68
69 vnl_matrix<double> trans_matrix(4,4,0.0);
70
71 if (is_utm) {
72 double scale_x = voxel_length;
73 double scale_y = -1*voxel_length;
74 // transfer upper left corner to utm system
75 vpgl_utm utm;
76 double upper_left_x, upper_left_y;
77 int utm_zone;
78 utm.transform(upper_left_lat, upper_left_lon, upper_left_x, upper_left_y, utm_zone);
79 std::cout << "upper left in utm = " << upper_left_x << " x " << upper_left_y << std::endl;
80 std::cout << "scale_x = " << scale_x << " scale_y = " << scale_y << std::endl;
81 trans_matrix[0][0] = scale_x;
82 trans_matrix[1][1] = scale_y;
83 trans_matrix[0][3] = upper_left_x;
84 trans_matrix[1][3] = upper_left_y;
85 vpgl_geo_camera* cam = new vpgl_geo_camera(trans_matrix, lvcs);
86 unsigned northing = 1;
87 if (upper_left_lat < 0 && lower_right_lat < 0)
88 northing = 0;
89 if (upper_left_lat*lower_right_lat < 0)
90 std::cout << "warning: scene world crosses the Equator" << std::endl;
91 cam->set_utm(utm_zone,northing);
92 cam->set_scale_format(true);
93 vpgl_camera_double_sptr camera = new vpgl_geo_camera(*cam);
94 pro.set_output_val<vpgl_camera_double_sptr>(0, camera);
95 return true;
96 }
97 else {
98 auto ni = (unsigned)std::ceil(box.width() / voxel_length);
99 auto nj = (unsigned)std::ceil(box.height()/ voxel_length);
100 //trans_matrix[0][0] = (lower_right_lon-lon)/ni; trans_matrix[1][1] = -(upper_left_lat-lat)/nj;
101 // lvcs origin is not necessarily one of the corners of the scene
102 trans_matrix[0][0] = (lower_right_lon-upper_left_lon)/ni; trans_matrix[1][1] = -(upper_left_lat-lower_right_lat)/nj;
103 trans_matrix[0][3] = upper_left_lon; trans_matrix[1][3] = upper_left_lat;
104 vpgl_geo_camera* cam = new vpgl_geo_camera(trans_matrix, lvcs);
105 cam->set_scale_format(true);
106 vpgl_camera_double_sptr camera = new vpgl_geo_camera(*cam);
107
108 pro.set_output_val<vpgl_camera_double_sptr>(0, camera);
109 return true;
110 }
111
112
113 }
114