Stride Reference Manual  - generated for commit 9643b11
GeoGrid.cpp
Go to the documentation of this file.
1 /*
2  * This is free software: you can redistribute it and/or modify it
3  * under the terms of the GNU General Public License as published by
4  * the Free Software Foundation, either version 3 of the License, or
5  * any later version.
6  * The software is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  * You should have received a copy of the GNU General Public License
11  * along with the software. If not, see <http://www.gnu.org/licenses/>.
12  *
13  * Copyright 2018, 2019, Jan Broeckhove and Bistromatics group.
14  */
15 
16 #include "GeoGrid.h"
17 
18 #include "contact/ContactPool.h"
19 #include "geopop/Location.h"
22 #include "pop/Population.h"
23 
24 #include <queue>
25 #include <stdexcept>
26 #include <utility>
27 
28 namespace geopop {
29 
30 using namespace std;
33 
35  : m_locations(), m_id_to_index(), m_population(population), m_finalized(false), m_tree()
36 {
37 }
38 
39 void GeoGrid::AddLocation(shared_ptr<Location> location)
40 {
41  if (m_finalized) {
42  throw std::runtime_error("Calling addLocation while GeoGrid is finalized not supported!");
43  }
44  m_locations.emplace_back(location);
45  m_id_to_index[location->GetID()] = static_cast<unsigned int>(m_locations.size() - 1);
46 }
47 
48 template <typename Policy, typename F>
49 GeoAggregator<Policy, F> GeoGrid::BuildAggregator(F functor, typename Policy::Args&& args) const
50 {
51  return GeoAggregator<Policy, F>(m_tree, functor, std::forward<typename Policy::Args>(args));
52 }
53 
54 template <typename Policy>
55 GeoAggregator<Policy> GeoGrid::BuildAggregator(typename Policy::Args&& args) const
56 {
57  return GeoAggregator<Policy>(m_tree, std::forward<typename Policy::Args>(args));
58 }
59 
60 void GeoGrid::CheckFinalized(const string& functionName) const
61 {
62  if (!m_finalized) {
63  throw std::runtime_error("Calling \"" + functionName + "\" with GeoGrid not finalized not supported!");
64  }
65 }
66 
68 {
69  vector<geogrid_detail::KdTree2DPoint> points;
70  for (const auto& loc : m_locations) {
71  points.emplace_back(geogrid_detail::KdTree2DPoint(loc.get()));
72  }
73  m_tree = GeoGridKdTree::Build(points);
74  m_finalized = true;
75 }
76 
77 set<const Location*> GeoGrid::LocationsInBox(double long1, double lat1, double long2, double lat2) const
78 {
79  CheckFinalized(__func__);
80 
81  set<const Location*> result;
82 
83  auto agg = BuildAggregator<BoxPolicy>(
84  MakeCollector(inserter(result, result.begin())),
85  make_tuple(min(long1, long2), min(lat1, lat2), max(long1, long2), max(lat1, lat2)));
86  agg();
87 
88  return result;
89 }
90 
91 set<const Location*> GeoGrid::LocationsInBox(Location* loc1, Location* loc2) const
92 {
93  using boost::geometry::get;
94  return LocationsInBox(get<0>(loc1->GetCoordinate()), get<1>(loc1->GetCoordinate()),
95  get<0>(loc2->GetCoordinate()), get<1>(loc2->GetCoordinate()));
96 }
97 
98 vector<const Location*> GeoGrid::LocationsInRadius(const Location& start, double radius) const
99 {
100  CheckFinalized(__func__);
101 
102  geogrid_detail::KdTree2DPoint startPt(&start);
103  vector<const Location*> result;
104 
105  auto agg = BuildAggregator<RadiusPolicy>(MakeCollector(back_inserter(result)), make_tuple(startPt, radius));
106  agg();
107 
108  return result;
109 }
110 
111 vector<ContactPool*> GeoGrid::GetNearbyPools(Id id, const Location& start, double startRadius) const
112 {
113  double currentRadius = startRadius;
114  vector<ContactPool*> pools;
115 
116  while (pools.empty()) {
117  for (const Location* nearLoc : LocationsInRadius(start, currentRadius)) {
118  const auto& locPool = nearLoc->CRefPools(id);
119  pools.insert(pools.end(), locPool.begin(), locPool.end());
120  }
121  currentRadius *= 2;
122  if (currentRadius == numeric_limits<double>::infinity()) {
123  break;
124  }
125  }
126  return pools;
127 }
128 
129 vector<Location*> GeoGrid::TopK(size_t k) const
130 {
131  auto cmp = [](Location* rhs, Location* lhs) { return rhs->GetPopCount() > lhs->GetPopCount(); };
132 
133  priority_queue<Location*, vector<Location*>, decltype(cmp)> queue(cmp);
134  for (const auto& loc : m_locations) {
135  queue.push(loc.get());
136  if (queue.size() > k) {
137  queue.pop();
138  }
139  }
140 
141  vector<Location*> topLocations;
142  while (!queue.empty()) {
143  auto loc = queue.top();
144  topLocations.push_back(loc);
145  queue.pop();
146  }
147 
148  return topLocations;
149 }
150 
151 } // namespace geopop
GeoGridKdTree m_tree
Definition: GeoGrid.h:144
std::vector< const Location * > LocationsInRadius(const Location &start, double radius) const
Search for locations in radius (in km) around start.
Definition: GeoGrid.cpp:98
Id
Enumerates the ContactPool types.
Definition: ContactType.h:34
A GeoAggregator that has to be called with a functor.
Definition: GeoAggregator.h:85
A group of Persons that potentially have contacts with one another.
Definition: ContactPool.h:38
Collector< InsertIter, T > MakeCollector(const InsertIter &ins)
Build a Collector, useful for type inference.
Definition: GeoAggregator.h:59
Header for the core ContactPool class.
bool m_finalized
Internal KdTree for quick spatial lookup.
Definition: GeoGrid.h:141
void AddLocation(std::shared_ptr< Location > location)
Adds a location to this GeoGrid.
Definition: GeoGrid.cpp:39
GeoGrid(stride::Population *population)
GeoGrid and associated Population.
Definition: GeoGrid.cpp:34
std::vector< std::shared_ptr< Location > > m_locations
< Container for Locations in GeoGrid.
Definition: GeoGrid.h:132
std::set< const Location * > LocationsInBox(double long1, double lat1, double long2, double lat2) const
Gets the locations in a rectangle determined by the two coordinates (long1, lat1) and (long2...
Definition: GeoGrid.cpp:77
void Finalize()
Disables the addLocation method and builds the kdtree.
Definition: GeoGrid.cpp:67
STL namespace.
std::vector< Location * > TopK(size_t k) const
Gets the K biggest (in population count) locations of this GeoGrid.
Definition: GeoGrid.cpp:129
std::unordered_map< unsigned int, unsigned int > m_id_to_index
Stores pointer to Popluation, but does not take ownership.
Definition: GeoGrid.h:135
Key Data structure: container for (a) all individuals in the population (b) the ContactPoolSys wchich...
Definition: Population.h:47
Namespace for the geographic and demograhic classes.
Definition: Coordinate.h:21
const Coordinate GetCoordinate() const
Gets the Coordinate of this Location.
Definition: Location.h:60
GeoAggregator< Policy, F > BuildAggregator(F functor, typename Policy::Args &&args) const
Build a GeoAggregator with a predefined functor and given args for the Policy.
Definition: GeoGrid.cpp:49
KdTree for some more information on methods.
Definition: KdTree2DPoint.h:31
A GeoAggregator constructed with a functor.
unsigned int GetPopCount() const
Gets the absolute population.
Definition: Location.h:78
std::vector< stride::ContactPool * > GetNearbyPools(stride::ContactType::Id id, const Location &start, double startRadius=10.0) const
Find contactpools in startRadius (in km) around start and, if none are found, double the radius and s...
Definition: GeoGrid.cpp:111
Header file for the core Population class.
static KdTree Build(const std::vector< geogrid_detail::KdTree2DPoint > &points)
Build a balanced tree from the given set of points efficiently.
void CheckFinalized(const std::string &functionName) const
< Checks whether the GeoGrid is finalized i.e. certain operations can(not) be used.
Definition: GeoGrid.cpp:60
Location for use within the GeoGrid, contains Coordinate and index to ContactPools.
Definition: Location.h:41