FireSTARR
Loading...
Searching...
No Matches
GridMap.h
1/* Copyright (c) Queen's Printer for Ontario, 2020. */
2/* Copyright (c) His Majesty the King in Right of Canada as represented by the Minister of Natural Resources, 2024-2025. */
3
4/* SPDX-License-Identifier: AGPL-3.0-or-later */
5
6#pragma once
7#include "Util.h"
8#include "Grid.h"
9#include "ConstantGrid.h"
10#include "Settings.h"
11namespace fs::data
12{
13using topo::Location;
14using topo::Position;
20template <class T, class V = T>
22 : public GridData<T, V, map<Location, T>>
23{
24public:
30 [[nodiscard]] bool contains(const Location& location) const
31 {
32 return this->data.end() != this->data.find(location);
33 }
34 template <class P>
35 [[nodiscard]] bool contains(const Position<P>& position) const
36 {
37 return contains(Location{position.hash()});
38 }
44 [[nodiscard]] T at(const Location& location) const override
45 {
46 const auto value = this->data.find(location);
47 if (value == this->data.end())
48 {
49 return this->nodataValue();
50 }
51 return get<1>(*value);
52 }
53 template <class P>
54 [[nodiscard]] T at(const Position<P>& position) const
55 {
56 return at(Location{position.hash()});
57 }
63 void set(const Location& location, const T value) override
64 {
65 this->data[location] = value;
66 assert(at(location) == value);
67 }
68 template <class P>
69 void set(const Position<P>& position, const T value)
70 {
71 return set(Location{position.hash()}, value);
72 }
73 ~GridMap() = default;
87 GridMap(const MathSize cell_size,
88 const Idx rows,
89 const Idx columns,
90 T no_data,
91 const int nodata,
92 const MathSize xllcorner,
93 const MathSize yllcorner,
94 const MathSize xurcorner,
95 const MathSize yurcorner,
96 string&& proj4)
97 : GridData<T, V, map<Location, T>>(cell_size,
98 rows,
99 columns,
100 no_data,
101 nodata,
102 xllcorner,
103 yllcorner,
104 xurcorner,
105 yurcorner,
106 std::forward<string>(proj4),
107 map<Location, T>())
108 {
109 constexpr auto max_hash = numeric_limits<HashSize>::max();
110 // HACK: we don't want overflow errors, but we want to play with the hash size
111 const auto max_columns = static_cast<MathSize>(max_hash) / static_cast<MathSize>(this->rows());
112 logging::check_fatal(this->columns() >= max_columns,
113 "Grid is too big for cells to be hashed - "
114 "recompile with a larger HashSize value");
115#ifdef DEBUG_GRIDS
116 // enforce converting to an int and back produces same V
117 const auto n0 = this->nodataInput();
118 const auto n1 = static_cast<NodataIntType>(n0);
119 const auto n2 = static_cast<V>(n1);
120 const auto n3 = static_cast<NodataIntType>(n2);
121 logging::check_equal(
122 n1,
123 n3,
124 "nodata_input_ as int");
125 logging::check_equal(
126 n0,
127 n2,
128 "nodata_input_ from int");
129#endif
130 // HACK: reserve space for this based on how big our Idx is because that
131 // tells us how many cells there could be
132 // HACK: divide because we expect most perimeters to be fairly small, but we
133 // want it to be reasonably large
134 // this->data.reserve(static_cast<size_t>(numeric_limits<Idx>::max() / 4));
135 // this->data.reserve(static_cast<size_t>(MAX_ROWS) * MAX_COLUMNS);
136 }
141 explicit GridMap(const Grid<T, V>& grid)
142 : GridMap<T, V>(grid.cellSize(),
143 grid.noData(),
144 grid.nodata(),
145 grid.xllcorner(),
146 grid.yllcorner(),
147 grid.xurcorner(),
148 grid.yurcorner(),
149 grid.proj4())
150 {
151 }
157 GridMap(const GridBase& grid_info, T no_data)
158 : GridMap<T, V>(grid_info.cellSize(),
159 static_cast<Idx>(grid_info.calculateRows()),
160 static_cast<Idx>(grid_info.calculateColumns()),
161 no_data,
162 static_cast<int>(no_data),
163 grid_info.xllcorner(),
164 grid_info.yllcorner(),
165 grid_info.xurcorner(),
166 grid_info.yurcorner(),
167 string(grid_info.proj4()))
168 {
169 }
174 GridMap(GridMap&& rhs) noexcept
175 : GridData<T, V, map<Location, T>>(std::move(rhs))
176 {
177 this->data = std::move(rhs.data);
178 }
183 GridMap(const GridMap& rhs)
184 : GridData<T, V, map<Location, T>>(rhs)
185 {
186 this->data = rhs.data;
187 }
193 GridMap& operator=(GridMap&& rhs) noexcept
194 {
195 if (this != &rhs)
196 {
197 this->data = std::move(rhs.data);
198 }
199 return *this;
200 }
207 {
208 if (this != &rhs)
209 {
210 this->data = rhs.data;
211 }
212 return *this;
213 }
217 void clear() noexcept
218 {
219 // this->data.clear();
220 this->data = {};
221 // this->data.reserve(static_cast<size_t>(numeric_limits<Idx>::max() / 4));
222 }
223protected:
224 tuple<Idx, Idx, Idx, Idx> dataBounds() const override
225 {
226 Idx min_row = this->rows();
227 Idx max_row = 0;
228 Idx min_column = this->columns();
229 Idx max_column = 0;
230 for (const auto& kv : this->data)
231 {
232 const Idx r = kv.first.row();
233 const Idx c = kv.first.column();
234 min_row = min(min_row, r);
235 max_row = max(max_row, r);
236 min_column = min(min_column, c);
237 max_column = max(max_column, c);
238 }
239 // do this so that we take the center point when there's no data since it should
240 // stay the same if the grid is centered on the fire
241 if (min_row > max_row)
242 {
243 min_row = max_row = this->rows() / 2;
244 }
245 if (min_column > max_column)
246 {
247 min_column = max_column = this->columns() / 2;
248 }
249 return tuple<Idx, Idx, Idx, Idx>{
250 min_column,
251 min_row,
252 max_column,
253 max_row};
254 }
255public:
262 template <class R>
263 string saveToProbabilityFile(const string& dir,
264 const string& base_name,
265 const R divisor) const
266 {
267 auto div = [divisor](T value) -> R {
268 return static_cast<R>(value / divisor);
269 };
270 return this->template saveToFile<R>(dir, base_name, div);
271 }
276 [[nodiscard]] MathSize fireSize() const noexcept
277 {
278 // we know that every cell is a key, so we convert that to hectares
279 const MathSize per_width = (this->cellSize() / 100.0);
280 // cells might have 0 as a value, but those shouldn't affect size
281 return static_cast<MathSize>(this->data.size()) * per_width * per_width;
282 }
287 [[nodiscard]] list<Location> makeEdge() const
288 {
289 list<Location> edge{};
290 for (const auto& kv : this->data)
291 {
292 auto loc = kv.first;
293 auto on_edge = false;
294 for (Idx r = -1; !on_edge && r <= 1; ++r)
295 {
296 const Idx row_index = loc.row() + r;
297 if (!(row_index < 0 || row_index >= this->rows()))
298 {
299 for (Idx c = -1; !on_edge && c <= 1; ++c)
300 {
301 const Idx col_index = loc.column() + c;
302 if (!(col_index < 0 || col_index >= this->columns())
303 && this->data.find(Location(row_index, col_index)) == this->data.end())
304 {
305 on_edge = true;
306 }
307 }
308 }
309 }
310 if (on_edge)
311 {
312 edge.push_back(loc);
313 }
314 }
315 logging::info("Created edge for perimeter with length %lu m",
316 static_cast<size_t>(this->cellSize() * edge.size()));
317 return edge;
318 }
323 [[nodiscard]] list<Location> makeList() const
324 {
325 list<Location> result{this->data.size()};
326 std::transform(this->data.begin(),
327 this->data.end(),
328 result.begin(),
329 [](const pair<const Location, const T>& kv) { return kv.first; });
330 return result;
331 }
332};
333}
The base class with information for a grid of data with geographic coordinates.
Definition Grid.h:43
constexpr MathSize xurcorner() const noexcept
Upper right corner X coordinate in meters.
Definition Grid.h:116
constexpr const string & proj4() const noexcept
Proj4 string defining coordinate system for this grid. Must be a UTM projection.
Definition Grid.h:132
constexpr FullIdx calculateRows() const noexcept
Number of rows in the GridBase.
Definition Grid.h:80
constexpr MathSize cellSize() const noexcept
Cell size used for GridBase.
Definition Grid.h:72
constexpr MathSize yllcorner() const noexcept
Lower left corner Y coordinate in meters.
Definition Grid.h:108
constexpr MathSize xllcorner() const noexcept
Lower left corner X coordinate in meters.
Definition Grid.h:100
constexpr MathSize yurcorner() const noexcept
Upper right corner Y coordinate in meters.
Definition Grid.h:124
constexpr FullIdx calculateColumns() const noexcept
Number of columns in the GridBase.
Definition Grid.h:90
A Grid that defines the data structure used for storing values.
Definition Grid.h:408
string saveToFile(const string &dir, const string &base_name, std::function< R(T value)> convert, const R no_data) const
Definition Grid.h:856
map< Location, T > data
Definition Grid.h:506
A GridData that uses an unordered_map for storage.
Definition GridMap.h:23
GridMap(const Grid< T, V > &grid)
Construct empty GridMap with same extent as given Grid.
Definition GridMap.h:141
GridMap & operator=(const GridMap &rhs)
Copy assignment.
Definition GridMap.h:206
list< Location > makeEdge() const
Make a list of all Locations that are on the edge of cells with a value.
Definition GridMap.h:287
GridMap(const MathSize cell_size, const Idx rows, const Idx columns, T no_data, const int nodata, const MathSize xllcorner, const MathSize yllcorner, const MathSize xurcorner, const MathSize yurcorner, string &&proj4)
Constructor.
Definition GridMap.h:87
GridMap & operator=(GridMap &&rhs) noexcept
Move assignment.
Definition GridMap.h:193
list< Location > makeList() const
Make a list of all Locations that have a value.
Definition GridMap.h:323
void set(const Location &location, const T value) override
Set value at Location.
Definition GridMap.h:63
GridMap(const GridMap &rhs)
Copy constructor.
Definition GridMap.h:183
GridMap(const GridBase &grid_info, T no_data)
Construct empty GridMap with same extent as given Grid.
Definition GridMap.h:157
string saveToProbabilityFile(const string &dir, const string &base_name, const R divisor) const
Save GridMap contents to .asc file as probability.
Definition GridMap.h:263
MathSize fireSize() const noexcept
Calculate area for cells that have a value (ha)
Definition GridMap.h:276
T at(const Location &location) const override
Retrieve value at Location.
Definition GridMap.h:44
void clear() noexcept
Clear data from GridMap.
Definition GridMap.h:217
bool contains(const Location &location) const
Determine if Location has a value.
Definition GridMap.h:30
GridMap(GridMap &&rhs) noexcept
Move constructor.
Definition GridMap.h:174
A GridBase with an associated type of data.
Definition Grid.h:251
constexpr T nodataInput() const noexcept
Definition Grid.h:273
constexpr Idx rows() const noexcept
Definition Grid.h:257
constexpr Idx columns() const noexcept
Definition Grid.h:265
constexpr T nodataValue() const noexcept
Definition Grid.h:281
Definition Location.h:229
A Position with a row and column.
Definition Location.h:57
constexpr HashSize hash() const noexcept
Hash derived from row and column.
Definition Location.h:80