hivemind 1.0.0
Loading...
Searching...
No Matches
height_manager.cpp
Go to the documentation of this file.
2
3#include <gdal.h>
4#include <gdal_priv.h>
5
6namespace HeightManagement
7{
8
10
11 void
12 HeightManager::LoadTif(const char* filePath, double x, double y)
13 {
14 m_CachedTifName = filePath;
15 Core::UTMCoordinate UTMCoord{ x, y };
16 UpdateOrigin(UTMCoord, m_Size);
17 return;
18 }
19
20 void
22 {
23 m_Origo = { UTMCoord.Easting, UTMCoord.Northing, 0 };
24 m_Size = size;
26
28
29 if (!OrigoWithinBounds(UTMCoord.Easting, UTMCoord.Northing)) {
30 // If I get the WCS request to work, that will be initialized here!
31 std::cerr
32 << "Selected origin not within bounds! Please ensure x is "
33 "within the range "
34 << m_UpperLeftX << " - " << m_LowerRightX
35 << " and Y is within the range " << long(m_LowerRightY) << " - "
36 << long(m_UpperLeftY) << " (" << m_CoordinateSystem << ")"
37 << "." << std::endl;
38 return;
39 }
40
42 m_Origo.z = GetHeightAbsolute(UTMCoord.Easting, UTMCoord.Northing);
43 }
44
45 void
47 {
48 // Opening the dataset
49 GDALAllRegister();
50
51 GDALDataset* dataset =
52 (GDALDataset*)GDALOpen(m_CachedTifName, GA_ReadOnly);
53 if (dataset == NULL) {
54 std::cerr << "Failed to open file" << std::endl;
55 }
56
57 // Extracting raster band data. Elevation data is located on band 1 as a
58 // rule for GeoTiff files.
59 GDALRasterBand* band = dataset->GetRasterBand(1);
60 if (band == NULL) {
61 std::cerr << "Failed to get raster band" << std::endl;
62 }
63
64 // Converting and extracting data from pixels/lines to coordinates
65 double geoTransform[6];
66 dataset->GetGeoTransform(geoTransform);
67
68 // The corners for the entire dataset can be found on [0] and [3] of the
69 // geotransformed array.
70 double upperLeftX = geoTransform[0];
71 double upperLeftY = geoTransform[3];
72
73 // Defining the upper right corner of our selection. Because the origin
74 // point is in the center of the dataset, the distance from the origin
75 // x, y to each corner is half of the total size of the subset.
76 double selectionCornerX = (m_Origo.x - m_Size / 2);
77 double selectionCornerY = (m_Origo.y + m_Size / 2);
78
79 // Updating the member variable for the selected subset's top left
80 // corner coordinate for use in other methods.
81 m_SelectionCorner = { selectionCornerX, selectionCornerY, 0 };
82
83 // Extracting height values from the band containing height data
84 // (elevationData). This is placed in a one-dimensional array
85 // elevationData.
86 int xOffset = (selectionCornerX - upperLeftX);
87 int yOffset = (upperLeftY - selectionCornerY);
88
89 float* elevationData = new float[m_Size * m_Size];
90
91 CPLErr result =
92 band->RasterIO(GF_Read, xOffset, yOffset, m_Size, m_Size,
93 elevationData, m_Size, m_Size, GDT_Float32, 0, 0);
94
95 // Placing height data into member variable for use in other methods.
96 // The method to find any given point in a coordinate system with 0, 0
97 // in the top left corner is (y coordinate * size of one dimension of
98 // the imagined two-dimensional array) + x coordinate. If the array is
99 // 500*500 in size and you want the height for the (5, 10) coordinate,
100 // the calculation will be (10 * 500) + 5.
101 for (int yDex = 0; yDex < m_Size; yDex++) {
102 for (int xDex = 0; xDex < m_Size; xDex++) {
103 m_Vertices[yDex * m_Size + xDex].x = selectionCornerX + xDex;
104 m_Vertices[yDex * m_Size + xDex].y = selectionCornerY - yDex;
105 m_Vertices[yDex * m_Size + xDex].z =
106 elevationData[yDex * m_Size + xDex];
107 }
108 }
109
110 // Cleaning up and closing dataset.
111 delete[] elevationData;
112 GDALClose(dataset);
113 }
114
115 bool
116 HeightManager::GetVertex(int inputRelativeX, int inputRelativeY,
118 {
119 if (ValidInput(inputRelativeX, inputRelativeY)) {
120 vertex.z = m_Vertices[inputRelativeY * m_Size + inputRelativeX].z;
121 return true;
122 }
123
124 else {
125 std::cerr << "Request out of bounds" << std::endl;
126 return false;
127 }
128 }
129
130 bool
131 HeightManager::GetVertexAbsolute(double inputX, double inputY,
133 {
134 if (ValidInput(inputX, inputY)) {
135 double inputOffsetX = inputX - m_SelectionCorner.x;
136 double inputOffsetY = m_SelectionCorner.y - inputY;
137 vertex.z = m_Vertices[int(inputOffsetY * m_Size + inputOffsetX)].z;
138 return true;
139 }
140
141 else {
142 std::cerr << "Request out of bounds" << std::endl;
143 return false;
144 }
145 }
146
147 float
148 HeightManager::GetHeightAbsolute(double inputX, double inputY)
149 {
150 if (ValidInput(inputX, inputY)) {
151 double inputOffsetX = inputX - m_SelectionCorner.x;
152 double inputOffsetY = m_SelectionCorner.y - inputY;
153 return m_Vertices[int(inputOffsetY * m_Size + inputOffsetX)].z;
154 }
155
156 else {
157 std::cerr << "Request out of bounds" << std::endl;
158 return 0;
159 }
160 }
161
162 bool
163 HeightManager::GetHeight(int inputRelativeX, int inputRelativeY,
164 float& height)
165 {
166 if (ValidInput(inputRelativeX, inputRelativeY)) {
167 height = m_Vertices[inputRelativeY * m_Size + inputRelativeX].z;
168 return true;
169 }
170
171 else {
172 std::cerr << "Request out of bounds" << std::endl;
173 return false;
174 }
175 }
176
177 bool
179 {
180 bool validInput = (0 <= y) && (y < m_Size) && (0 <= x) && (x < m_Size);
181 return validInput;
182 }
183
184 bool
185 HeightManager::ValidInput(double x, double y)
186 {
187 bool validInput = (m_SelectionCorner.x <= x) &&
188 (x <= (m_SelectionCorner.x + m_Size)) &&
189 (m_SelectionCorner.y >= y) &&
190 (y >= m_SelectionCorner.y - m_Size);
191 return validInput;
192 }
193
194 bool
196 {
197 double min_x = m_UpperLeftX + m_Size / 2;
198 double max_x = m_LowerRightX - m_Size / 2;
199 double min_y = m_LowerRightY + m_Size / 2;
200 double max_y = m_UpperLeftY - m_Size / 2;
201
202 return ((x <= max_x) && (x >= min_x) && (y <= max_y) && (y >= min_y));
203 }
204
205 void
207 {
208 GDALAllRegister();
209
210 GDALDataset* dataset =
211 (GDALDataset*)GDALOpen(m_CachedTifName, GA_ReadOnly);
212 if (dataset == NULL) {
213 std::cerr << "Failed to open file" << std::endl;
214 }
215
216 GDALRasterBand* band = dataset->GetRasterBand(1);
217 if (band == NULL) {
218 std::cerr << "Failed to get raster band" << std::endl;
219 }
220
221 double geoTransform[6];
222 dataset->GetGeoTransform(geoTransform);
223
224 m_UpperLeftX = geoTransform[0];
225 m_UpperLeftY = geoTransform[3];
227 m_UpperLeftX + geoTransform[1] * dataset->GetRasterXSize();
229 m_UpperLeftY + geoTransform[5] * dataset->GetRasterXSize();
230
231 GDALClose(dataset);
232 }
233
234} // namespace HeightManagement
bool GetVertexAbsolute(double inputX, double inputY, heightdata &vertex)
Function to get the height_management of an absolute (geographic) coordinate, using the same coordina...
void UpdateCornerCoords()
Function to update the corner coordinates saved within the member instance of the chosen dataset.
void PopulateVertices()
Function that will open the GeoTiff file and extract all heights for the given subset of the dataset ...
HeightManager()
Constructor of HeightManager class.
void LoadTif(const char *filePath, double x, double y)
Function to allow user to change GeoTiff file used in planning.
bool GetHeight(int inputRelativeX, int inputRelativeY, float &height)
Function to return height, given relative coordinates (from a system where 0, 0 is in the upper left ...
void UpdateOrigin(Core::UTMCoordinate UTMCoord, int size)
Function to update the origin point.
bool GetVertex(int inputRelativeX, int inputRelativeY, heightdata &vertex)
Function to return the whole "height_management" for a given point.
bool ValidInput(int x, int y)
Function to test whether a point exists within the scope of the selected data subset.
float GetHeightAbsolute(double inputX, double inputY)
Function to get the height of an absolute (geographic) coordinate, using the same coordinate system o...
bool OrigoWithinBounds(double x, double y)
Function that tests whether the selected origin point is within the bounds of the currently active da...
\ A structure that represents a coordinate in the Universal Transverse Mercator coordinate system
Definition: types.h:46
double Easting
Definition: types.h:54
double Northing
Definition: types.h:54