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