1 //This is brl/bbas/volm/volm_geo_index.h
2 #ifndef volm_geo_index_h_
3 #define volm_geo_index_h_
4 //:
5 // \file
6 // \brief Classes to enable fast access to geographic areas and attributes
7 // Units are in lat, lon
8 //        index is a quadtree
9 //        some of the 4 children of a node may have zero as sptr which means that region is pruned (out of ROI or eliminated for some reason)
10 //        WARNING: this class assumes that the areas in question are small enough so that Euclidean distances approximate geodesic distances
11 //                 also assumes that the regions do not cross over lon = 0
12 //
13 //
14 //
15 // \author Ozge C. Ozcanli
16 // \date Jan 10, 2013
17 
18 #include <iostream>
19 #include <string>
20 #include <vector>
21 #include <vbl/vbl_ref_count.h>
22 #ifdef _MSC_VER
23 #  include <vcl_msvc_warnings.h>
24 #endif
25 #include <vil/vil_image_view.h>
26 #include "volm_tile.h"
27 #include "volm_geo_index_sptr.h"
28 #include "volm_loc_hyp_sptr.h"
29 #include <vgl/vgl_box_2d.h>
30 #include <vgl/vgl_polygon.h>
31 
32 class volm_geo_index_node : public vbl_ref_count
33 {
34  public:
volm_geo_index_node(vgl_box_2d<double> const & extent,volm_geo_index_node_sptr & parent)35    volm_geo_index_node(vgl_box_2d<double> const& extent, volm_geo_index_node_sptr& parent) : extent_(extent), parent_(parent) {}
volm_geo_index_node(vgl_box_2d<double> const & extent)36    volm_geo_index_node(vgl_box_2d<double> const& extent) : extent_(extent), parent_(nullptr) {}
37    ~volm_geo_index_node() override;
38    std::string get_string();
get_hyp_name(std::string const & geo_index_name_pre)39    std::string get_hyp_name(std::string const& geo_index_name_pre) { return geo_index_name_pre + "_" + this->get_string() + ".bin"; }
get_index_name(std::string const & geo_index_name_pre)40    std::string get_index_name(std::string const& geo_index_name_pre) { return geo_index_name_pre + "_" + this->get_string() + "_index.bin"; }
41    std::string get_label_index_name(std::string const& geo_index_name_pre, std::string const& identifier);
42 
43  public:
44    // mini tile
45    vgl_box_2d<double> extent_;   // min point of this box is lower left corner of the mini tile of this node
46                                  // max point of this box is used as upper bound if pixels in the mini tile are iterated
47 
48    volm_geo_index_node_sptr parent_;
49    std::vector<volm_geo_index_node_sptr> children_;
50 
51    // other data, e.g. keywords of geographic attributes that this tile contains, a set of hypotheses
52    //
53    volm_loc_hyp_sptr hyps_;
54 };
55 
56 class volm_geo_index
57 {
58  public:
59   //: construct a tree such that the given tile is the root, and the hierarchy of its children form a quadtree space partition
60   static volm_geo_index_node_sptr construct_tree(volm_tile t, float min_size);
61 
62   //: construct with a polygon with possibly multiple sheets, only keep the children who intersect one of the sheets of the polygon
63   //static volm_geo_index_node_sptr construct_tree(volm_tile t, float min_size, vgl_polygon<float> const& poly);
64   static volm_geo_index_node_sptr construct_tree(volm_tile t, float min_size, vgl_polygon<double> const& poly);
65 
66   //: prune the children which do not intersect the poly
67   static bool prune_tree(const volm_geo_index_node_sptr& root, vgl_polygon<float> const& poly);
68   static bool prune_tree(const volm_geo_index_node_sptr& root, vgl_polygon<double> const& poly);
69   //: prune nodes whose bbox is not in the utm_zone
70   static bool prune_by_zone(const volm_geo_index_node_sptr& root, unsigned utm_zone);
71 
72   //: depth at leaf level is 0
73   static unsigned depth(const volm_geo_index_node_sptr& node);
74 
75   //: write the bboxes of the nodes at the given depth to kml file
76   static void write_to_kml(const volm_geo_index_node_sptr& root, unsigned depth, std::string const& file_name);
77   static void write_to_kml_node(std::ofstream& ofs, const volm_geo_index_node_sptr& n, unsigned current_depth, unsigned depth, std::string explanation = "location");
78 
79   //: write index quadtree in a text file, only the tree structure and not the leaf data
80   static void write(const volm_geo_index_node_sptr& root, std::string const& file_name, float min_size);
81 
82   //: even if a child has zero pointer, it's order in the children_ array is the same, this is to make sure that the children have consistent geographic meaning
83   static volm_geo_index_node_sptr read_and_construct(std::string const& file_name, float& min_size);
84 
85   static void get_leaves(const volm_geo_index_node_sptr& root, std::vector<volm_geo_index_node_sptr>& leaves);
86 
87   //: return all the leaves that intersect a given rectangular area
88   static void get_leaves(const volm_geo_index_node_sptr& root, std::vector<volm_geo_index_node_sptr>& leaves, vgl_box_2d<double>& area);
89 
90   static void get_leaves_with_hyps(const volm_geo_index_node_sptr& root, std::vector<volm_geo_index_node_sptr>& leaves);
91   //: write the geo index hyps
92   static void write_hyps(const volm_geo_index_node_sptr& root, std::string const& file_name_pre);
93   static void read_hyps(const volm_geo_index_node_sptr& root, std::string const& file_name_pre);
94 
95   static unsigned hypo_size(const volm_geo_index_node_sptr& root);
96 
97   static bool add_hypothesis(const volm_geo_index_node_sptr& root, double lon, double lat, double elev);
98 
99   //: return the leaf and the hyp id of the closest hyp to the given location
100   static volm_geo_index_node_sptr get_closest(const volm_geo_index_node_sptr& root, double lat, double lon, unsigned& hyp_id);
101 
102   //: return true if a hyp exists within the given radius to the given point
103   static bool exists(const volm_geo_index_node_sptr& root, double lat, double lon, double inc_in_sec_rad);
104 };
105 
106 #endif // volm_geo_index_h_
107