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