1 // This is//external/acal/acal_metadata.h
2 #ifndef acal_metadata_h
3 #define acal_metadata_h
4
5 //:
6 // \file
7 // \brief A class to represent metadata for a regoin of interest
8 // \author J.L. Mundy
9 // \date Dec 16, 2018
10 //
11 // \verbatim
12 // Modifications
13 // <none yet>
14 // \endverbatim
15
16 #include <iostream>
17 #include <vcl_compiler.h>
18 #include <fstream>
19 #include <sstream>
20 #include <string>
21 #include <vector>
22 #include <map>
23 #include <bjson/bjson.h>
24 #include <vgl/vgl_point_2d.h>
25 #include <vgl/vgl_point_3d.h>
26 #include <vgl/vgl_box_3d.h>
27 #include <vgl/vgl_vector_2d.h>
28 #include <vpgl/vpgl_lvcs.h>
29 #include <vul/vul_file.h>
30
31 struct image_metadata
32 {
33 std::string image_name_;
34 vgl_vector_2d<double> sph_view_dir_;
35 size_t year_;
36 size_t month_;
37 size_t day_;
38 size_t hour_;
39 size_t min_;
40 size_t sec_;
41 double gsd_;
42 std::string img_type_;
43 vgl_vector_2d<double> sph_sun_dir_;
44 std::string sensor_platform_;
45 double cloud_per_;
46 };
47
48 struct tile_metadata
49 {
50 size_t tile_id_;
51 double dsm_resolution_;
52 double aster_mean_;
53 vgl_point_3d<double> global_lower_left_;
54 vgl_point_3d<double> global_upper_right_;
55 vgl_box_3d<double> global_bb_;
56 vgl_point_3d<double> local_lower_left_;
57 vgl_point_3d<double> local_upper_right_;
58 vgl_box_3d<double> local_bb_;
59 };
60
61 struct tile_image_metadata
62 {
63 size_t image_id_;
64 std::string image_name_;
65 };
66
67 struct geo_corr_metadata
68 {
69 size_t image_id_;
70 std::string image_name_;
71 vgl_vector_2d<double> translation_;
72 double rms_proj_err_;
73 bool seed_camera_;
74 };
75
76 struct pair_selection_metadata
77 {
78 size_t pair_index_;
79 size_t image1_id_;
80 size_t image2_id_;
81 double gsd_cost_;
82 double sun_angle_cost_;
83 double view_angle_cost_;
84 double cost_;
85 };
86
87
88 class acal_metadata
89 {
90 public:
acal_metadata()91 acal_metadata(){}
92
deserialize_image_meta(Json::Value & root)93 void deserialize_image_meta( Json::Value& root)
94 {
95 const Json::Value img_list = root;
96 for(Json::Value::const_iterator lit = img_list.begin();
97 lit != img_list.end(); ++lit)
98 {
99 image_metadata im;
100 im.image_name_ = (*lit).get("id", "").asString();
101 const Json::Value meta = (*lit)["meta"];
102 if(meta != Json::nullValue){
103 const Json::Value vdir = meta["view_angles"];
104 if(vdir != Json::nullValue){
105 Json::Value::const_iterator vit = vdir.begin();
106 double az = (*vit++).asDouble(), el = (*vit).asDouble();
107 im.sph_view_dir_.set(az, el);
108 }
109 const Json::Value dt = meta["acquisition_time"];
110 if(dt != Json::nullValue){
111 Json::Value::const_iterator dit = dt.begin();
112 im.year_ = (*dit++).asUInt();
113 im.month_ = (*dit++).asUInt();
114 im.day_ = (*dit++).asUInt();
115 im.hour_ = (*dit++).asUInt();
116 im.min_ = (*dit++).asUInt();
117 im.sec_ = (*dit).asUInt();
118 }
119 im.gsd_ = meta.get("gsd", 0.0).asDouble();
120 im.sensor_platform_ = meta.get("platform_name", "").asString();
121 const Json::Value sdir = meta["sun_angles"];
122 if(dt != Json::nullValue){
123 Json::Value::const_iterator sit = sdir.begin();
124 double az = (*sit++).asDouble(); double el = (*sit).asDouble();
125 im.sph_sun_dir_.set(az, el);
126 }
127 im.img_type_ = meta.get("image_type", "").asString();
128 im.cloud_per_ = meta.get("cloud_percentage", 0.0).asDouble();
129 }
130 img_meta_.push_back(im);
131 }
132 }
133
deserialize_tile_meta(Json::Value & root)134 void deserialize_tile_meta( Json::Value& root)
135 {
136 const Json::Value img_list = root;
137 Json::Value::Members tile_ids = root.getMemberNames();
138 size_t n = tile_ids.size();
139 for(size_t i = 0; i<n; ++i)
140 {
141 tile_metadata tm;
142 std::string key = tile_ids[i];
143 const Json::Value tile_info = root.get(key, "");
144 tm.tile_id_ = std::stoi(key);
145 tm.aster_mean_ = tile_info["aster_mean"].asDouble();
146 tm.dsm_resolution_ = tile_info["dsm_resolution"].asDouble();
147 const Json::Value local = tile_info["local"];
148 const Json::Value ll = local["lower_left"];
149 if(ll != Json::nullValue){
150 Json::Value::const_iterator vit = ll.begin();
151 double lon = (*vit++).asDouble(), lat = (*vit++).asDouble(), elev = (*vit++).asDouble();
152 tm.local_lower_left_.set(lon, lat, elev);
153 }
154 const Json::Value ur = local["upper_right"];
155 if (ur != Json::nullValue) {
156 Json::Value::const_iterator vit = ur.begin();
157 double lon = (*vit++).asDouble(), lat = (*vit++).asDouble(), elev = (*vit++).asDouble();
158 tm.local_upper_right_.set(lon, lat, elev);
159 }
160 tm.local_bb_ = vgl_box_3d<double>(tm.local_lower_left_, tm.local_upper_right_);
161 const Json::Value global = tile_info["global"];
162 const Json::Value gll = global["lower_left"];
163 if (gll != Json::nullValue) {
164 Json::Value::const_iterator vit = gll.begin();
165 double lon = (*vit++).asDouble(), lat = (*vit++).asDouble(), elev = (*vit++).asDouble();
166 tm.global_lower_left_.set(lon, lat, elev);
167 }
168 const Json::Value gur = global["upper_right"];
169 if (gur != Json::nullValue) {
170 Json::Value::const_iterator vit = gur.begin();
171 double lon = (*vit++).asDouble(), lat = (*vit++).asDouble(), elev = (*vit++).asDouble();
172 tm.global_upper_right_.set(lon, lat, elev);
173 }
174 tm.global_bb_ = vgl_box_3d<double>(tm.global_lower_left_, tm.global_upper_right_);
175
176 tile_meta_.push_back(tm);
177 }
178 }
deserialize_tile_image_meta(Json::Value & root)179 void deserialize_tile_image_meta( Json::Value& root)
180 {
181 const Json::Value img_list = root;
182 Json::Value::Members image_ids = root.getMemberNames();
183 size_t n = image_ids.size();
184 for(size_t i = 0; i<n; ++i)
185 {
186 std::string key = image_ids[i];
187 std::string image_path = root.get(key, "").asString();
188 std::string base_name = vul_file::strip_directory(image_path);
189 base_name = vul_file::strip_extension(base_name);
190 tile_image_metadata tim;
191 std::stringstream ss;
192 ss << key;
193 size_t id = -1;
194 ss >> id;
195 tim.image_id_ = id;
196 tim.image_name_ = base_name;
197 tile_image_meta_.push_back(tim);
198 }
199 }
serialize_geo_corr_meta(Json::Value & root)200 void serialize_geo_corr_meta( Json::Value& root)
201 {
202 Json::Value geo_corr_list;
203 size_t n = geo_corr_meta_.size();
204 if(n == 0){
205 std::cout << "no geo-correction to serialize" << std::endl;
206 return;
207 }
208 for(size_t i = 0; i<n; ++i)
209 {
210 Json::Value geo_corr;
211 geo_corr["iname"] = geo_corr_meta_[i].image_name_;
212 geo_corr["image_id"] = static_cast<Json::LargestUInt>(geo_corr_meta_[i].image_id_);
213 geo_corr["samp_trans"] = geo_corr_meta_[i].translation_.x();
214 geo_corr["line_trans"] = geo_corr_meta_[i].translation_.y();
215 geo_corr["rms_proj_err"] = geo_corr_meta_[i].rms_proj_err_;
216 geo_corr["seed_camera"] = geo_corr_meta_[i].seed_camera_;
217 Json::Value::ArrayIndex ai = static_cast<Json::Value::ArrayIndex>(i);
218 geo_corr_list[ai] = geo_corr;
219 }
220 root = geo_corr_list;
221 }
222
deserialize_geo_corr_meta(Json::Value & root)223 void deserialize_geo_corr_meta( Json::Value& root)
224 {
225 geo_corr_meta_.clear();
226 const Json::Value geo_corr_list = root;
227 for(Json::Value::const_iterator glit = geo_corr_list.begin();
228 glit != geo_corr_list.end(); ++glit)
229 {
230 geo_corr_metadata gm;
231 gm.image_id_ = (*glit).get("image_id", -1).asUInt();
232 gm.image_name_ = (*glit).get("iname", "").asString();
233 gm.rms_proj_err_ = (*glit).get("rms_proj_err", 0.0).asDouble();
234 gm.seed_camera_ = (*glit).get("seed_camera", false).asBool();
235 double tu = 0.0, tv = 0.0;
236 tu = (*glit).get("samp_trans", 0.0).asDouble();
237 tv = (*glit).get("line_trans", 0.0).asDouble();
238 gm.translation_.set(tu, tv);
239 geo_corr_meta_.push_back(gm);
240 }
241 }
242
serialize_pair_selection_meta(Json::Value & root)243 void serialize_pair_selection_meta( Json::Value& root)
244 {
245 Json::Value pair_list;
246 size_t n = pair_meta_.size();
247 if(n == 0){
248 std::cout << "no pair selection to serialize" << std::endl;
249 return;
250 }
251 for(size_t i = 0; i<n; ++i)
252 {
253 Json::Value pair;
254 pair["pair_index"] = static_cast<Json::LargestUInt>(pair_meta_[i].pair_index_);
255 pair["image1_id"] = static_cast<Json::LargestUInt>(pair_meta_[i].image1_id_);
256 pair["image2_id"] = static_cast<Json::LargestUInt>(pair_meta_[i].image2_id_);
257 pair["gsd_cost"] = pair_meta_[i].gsd_cost_;
258 pair["sun_angle_cost"] = pair_meta_[i].sun_angle_cost_;
259 pair["view_angle_cost"] = pair_meta_[i].view_angle_cost_;
260 pair["total_cost"] = pair_meta_[i].cost_;
261 Json::Value::ArrayIndex ai = static_cast<Json::Value::ArrayIndex>(i);
262 pair_list[ai] = pair;
263 }
264 root = pair_list;
265 }
deserialize_pair_selection_meta(Json::Value & root)266 void deserialize_pair_selection_meta( Json::Value& root)
267 {
268 pair_meta_.clear();
269 const Json::Value pair_list = root;
270 for(Json::Value::const_iterator prit = pair_list.begin();
271 prit != pair_list.end(); ++prit)
272 {
273 pair_selection_metadata pm;
274 pm.pair_index_ = (*prit).get("pair_index", -1).asUInt();
275 pm.image1_id_ = (*prit).get("image1_id", -1).asUInt();
276 pm.image2_id_ = (*prit).get("image2_id", -1).asUInt();
277 pm.gsd_cost_ = (*prit).get("gsd_cost", 0.0).asDouble();
278 pm.sun_angle_cost_ = (*prit).get("sun_angle_cost", 0.0).asDouble();
279 pm.view_angle_cost_ = (*prit).get("view_angle_cost", 0.0).asDouble();
280 pm.cost_ = (*prit).get("total_cost", 0.0).asDouble();
281 pair_meta_.push_back(pm);
282 }
283 }
284
285 // metadata elements
286 std::vector<image_metadata> img_meta_;
287 std::vector<tile_metadata> tile_meta_;
288 std::vector<tile_image_metadata> tile_image_meta_;
289 std::vector<geo_corr_metadata> geo_corr_meta_;
290 std::vector<pair_selection_metadata> pair_meta_;
291 };
292
293 #endif
294