CoastalME (Coastal Modelling Environment)
Simulates the long-term behaviour of complex coastlines
Loading...
Searching...
No Matches
gis_raster.cpp
Go to the documentation of this file.
1
12
13/*===============================================================================================================================
14
15This file is part of CoastalME, the Coastal Modelling Environment.
16
17CoastalME is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
18
19This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23===============================================================================================================================*/
24#include <assert.h>
25
26#include <iostream>
27using std::cerr;
28using std::cout;
29using std::endl;
30using std::ios;
31
32#include <fstream>
33using std::ifstream;
34
35#include <sstream>
36using std::stringstream;
37
38#include <string>
39using std::to_string;
40
41#include <gdal_priv.h>
42#include <gdal_alg.h>
43
44#include "cme.h"
45#include "simulation.h"
46#include "raster_grid.h"
47#include "coast.h"
48
49//===============================================================================================================================
51//===============================================================================================================================
53{
54 // Use GDAL to create a dataset object, which then opens the DEM file
55 GDALDataset* pGDALDataset = static_cast<GDALDataset*>(GDALOpen(m_strInitialBasementDEMFile.c_str(), GA_ReadOnly));
56 if (NULL == pGDALDataset)
57 {
58 // Can't open file (note will already have sent GDAL error message to stdout)
59 cerr << ERR << "cannot open " << m_strInitialBasementDEMFile << " for input: " << CPLGetLastErrorMsg() << endl;
60 return RTN_ERR_DEMFILE;
61 }
62
63 // Opened OK, so get GDAL basement DEM dataset information
64 m_strGDALBasementDEMDriverCode = pGDALDataset->GetDriver()->GetDescription();
65 m_strGDALBasementDEMDriverDesc = pGDALDataset->GetDriver()->GetMetadataItem(GDAL_DMD_LONGNAME);
66 m_strGDALBasementDEMProjection = pGDALDataset->GetProjectionRef();
67
68 // If we have reference units, then check that they are in meters (note US spelling)
70 {
72 if (strTmp.find("meter") == string::npos)
73 {
74 // error: x-y values must be in metres
75 cerr << ERR << "GIS file x-y values (" << m_strGDALBasementDEMProjection << ") in " << m_strInitialBasementDEMFile << " must be in metres" << endl;
76 return RTN_ERR_DEMFILE;
77 }
78 }
79
80 // Now get dataset size, and do some rudimentary checks
81 m_nXGridSize = pGDALDataset->GetRasterXSize();
82 if (m_nXGridSize == 0)
83 {
84 // Error: silly number of columns specified
85 cerr << ERR << "invalid number of columns (" << m_nXGridSize << ") in " << m_strInitialBasementDEMFile << endl;
86 return RTN_ERR_DEMFILE;
87 }
88
89 m_nYGridSize = pGDALDataset->GetRasterYSize();
90 if (m_nYGridSize == 0)
91 {
92 // Error: silly number of rows specified
93 cerr << ERR << "invalid number of rows (" << m_nYGridSize << ") in " << m_strInitialBasementDEMFile << endl;
94 return RTN_ERR_DEMFILE;
95 }
96
97 // Get geotransformation info (see http://www.gdal.org/classGDALDataset.html)
98 if (CE_Failure == pGDALDataset->GetGeoTransform(m_dGeoTransform))
99 {
100 // Can't get geotransformation (note will already have sent GDAL error message to stdout)
101 cerr << ERR << CPLGetLastErrorMsg() << " in " << m_strInitialBasementDEMFile << endl;
102 return RTN_ERR_DEMFILE;
103 }
104
105 // CoastalME can only handle rasters that are oriented N-S and W-E. (If you need to work with a raster that is oriented differently, then you must rotate it before running CoastalME). So here we check whether row rotation (m_dGeoTransform[2]) and column rotation (m_dGeoTransform[4]) are both zero. See https://gdal.org/tutorials/geotransforms_tut.html
106 if ((! bFPIsEqual(m_dGeoTransform[2], 0.0, TOLERANCE)) || (! bFPIsEqual(m_dGeoTransform[4], 0.0, TOLERANCE)))
107 {
108 // Error: not oriented NS and W-E
109 cerr << ERR << m_strInitialBasementDEMFile << " is not oriented N-S and W-E. Row rotation = " << m_dGeoTransform[2] << " and column rotation = " << m_dGeoTransform[4] << endl;
111 }
112
113 // Get the X and Y cell sizes, in external CRS units. Note that while the cell is supposed to be square, it may not be exactly so due to oddities with some GIS calculations
114 double dCellSideX = tAbs(m_dGeoTransform[1]);
115 double dCellSideY = tAbs(m_dGeoTransform[5]);
116
117 // Check that the cell is more or less square
118 if (! bFPIsEqual(dCellSideX, dCellSideY, 1e-2))
119 {
120 // Error: cell is not square enough
121 cerr << ERR << "cell is not square in " << m_strInitialBasementDEMFile << ", is " << dCellSideX << " x " << dCellSideY << endl;
123 }
124
125 // Calculate the average length of cell side, the cell's diagonal, and the area of a cell (in external CRS units)
126 m_dCellSide = (dCellSideX + dCellSideY) / 2.0;
129
130 // And calculate the inverse values
133
134 // Save some values in external CRS
139
140 // And calc the grid area in external CRS units
142
143 // Now get GDAL raster band information
144 GDALRasterBand* pGDALBand = pGDALDataset->GetRasterBand(1);
145 int nBlockXSize = 0, nBlockYSize = 0;
146 pGDALBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
147 m_strGDALBasementDEMDataType = GDALGetDataTypeName(pGDALBand->GetRasterDataType());
148
149 // If we have value units, then check them
150 string strUnits = pGDALBand->GetUnitType();
151 if ((! strUnits.empty()) && (strUnits.find("m") == string::npos))
152 {
153 // Error: value units must be m
154 cerr << ERR << "DEM vertical units are (" << strUnits << " ) in " << m_strInitialBasementDEMFile << ", should be 'm'" << endl;
155 return RTN_ERR_DEMFILE;
156 }
157
158 // If present, get the missing value (NODATA) setting
159 CPLPushErrorHandler(CPLQuietErrorHandler); // Needed to get next line to fail silently, if it fails
160 double dMissingValue = pGDALBand->GetNoDataValue(); // Will fail for some formats
161 CPLPopErrorHandler();
162
163 if (! bFPIsEqual(dMissingValue, m_dMissingValue, TOLERANCE))
164 {
165 cerr << " " << NOTE << "NODATA value in " << m_strInitialBasementDEMFile << " is " << dMissingValue << "\n instead using CoastalME's default floating-point NODATA value " << m_dMissingValue << endl;
166 }
167
168 // Next allocate memory for a 2D array of raster cell objects: tell the user what is happening
170 int nRet = m_pRasterGrid->nCreateGrid();
171 if (nRet != RTN_OK)
172 return nRet;
173
174 // Allocate memory for a 1D floating-point array, to hold the scan line for GDAL
175 double* pdScanline = new double[m_nXGridSize];
176 if (NULL == pdScanline)
177 {
178 // Error, can't allocate memory
179 cerr << ERR << "cannot allocate memory for " << m_nXGridSize << " x 1D array" << endl;
180 return (RTN_ERR_MEMALLOC);
181 }
182
183 // Now read in the data
184 for (int j = 0; j < m_nYGridSize; j++)
185 {
186 // Read scanline
187 if (CE_Failure == pGDALBand->RasterIO(GF_Read, 0, j, m_nXGridSize, 1, pdScanline, m_nXGridSize, 1, GDT_Float64, 0, 0, NULL))
188 {
189 // Error while reading scanline
190 cerr << ERR << CPLGetLastErrorMsg() << " in " << m_strInitialBasementDEMFile << endl;
191 return RTN_ERR_DEMFILE;
192 }
193
194 // All OK, so read scanline into cell elevations (including any missing values)
195 for (int i = 0; i < m_nXGridSize; i++)
196 {
197 double dTmp = pdScanline[i];
198
199 if (isnan(dTmp)) // Deal with any NaN values
200 dTmp = m_dMissingValue;
201
202 m_pRasterGrid->m_Cell[i][j].SetBasementElev(dTmp);
203 }
204 }
205
206 // Finished, so get rid of dataset object
207 GDALClose(pGDALDataset);
208
209 // Get rid of memory allocated to this array
210 delete[] pdScanline;
211
212 return RTN_OK;
213}
214
215//===============================================================================================================================
217//===============================================================================================================================
219{
220 // The bounding box must touch the edge of the grid at least once on each side of the grid, so store these points. Search in a clockwise direction around the edge of the grid
221 vector<CGeom2DIPoint> VPtiBoundingBoxCorner;
222
223 // Start with the top (north) edge
224 bool bFound = false;
225 for (int nX = 0; nX < m_nXGridSize; nX++)
226 {
227 if (bFound)
228 break;
229
230 for (int nY = 0; nY < m_nYGridSize; nY++)
231 {
232 if (! m_pRasterGrid->m_Cell[nX][nY].bBasementElevIsMissingValue())
233 {
234 CGeom2DIPoint PtiTmp(nX, nY);
235 VPtiBoundingBoxCorner.push_back(PtiTmp);
236 bFound = true;
237 break;
238 }
239 }
240 }
241
242 if (! bFound)
243 {
245 LogStream << m_ulIter << ": north (top) edge of bounding box not found" << endl;
247 }
248
249 // Do the same for the right (east) edge
250 bFound = false;
251 for (int nY = 0; nY < m_nYGridSize; nY++)
252 {
253 if (bFound)
254 break;
255
256 for (int nX = m_nXGridSize - 1; nX >= 0; nX--)
257 {
258 if (! m_pRasterGrid->m_Cell[nX][nY].bBasementElevIsMissingValue())
259 {
260 CGeom2DIPoint PtiTmp(nX, nY);
261 VPtiBoundingBoxCorner.push_back(PtiTmp);
262 bFound = true;
263 break;
264 }
265 }
266 }
267
268 if (! bFound)
269 {
271 LogStream << m_ulIter << ": east (right) edge of bounding box not found" << endl;
273 }
274
275 // Do the same for the south (bottom) edge
276 bFound = false;
277 for (int nX = m_nXGridSize - 1; nX >= 0; nX--)
278 {
279 if (bFound)
280 break;
281
282 for (int nY = m_nYGridSize - 1; nY >= 0; nY--)
283 {
284 if (! m_pRasterGrid->m_Cell[nX][nY].bBasementElevIsMissingValue())
285 {
286 CGeom2DIPoint PtiTmp(nX, nY);
287 VPtiBoundingBoxCorner.push_back(PtiTmp);
288 bFound = true;
289 break;
290 }
291 }
292 }
293
294 if (! bFound)
295 {
297 LogStream << m_ulIter << ": south (bottom) edge of bounding box not found" << endl;
299 }
300
301 // And finally repeat for the west (left) edge
302 bFound = false;
303 for (int nY = m_nYGridSize - 1; nY >= 0; nY--)
304 {
305 if (bFound)
306 break;
307
308 for (int nX = 0; nX < m_nXGridSize; nX++)
309 {
310 if (! m_pRasterGrid->m_Cell[nX][nY].bBasementElevIsMissingValue())
311 {
312 CGeom2DIPoint PtiTmp(nX, nY);
313 VPtiBoundingBoxCorner.push_back(PtiTmp);
314 bFound = true;
315 break;
316 }
317 }
318 }
319
320 if (! bFound)
321 {
323 LogStream << m_ulIter << ": west (left) edge of bounding box not found" << endl;
325 }
326
327 // OK, so we have a point on each side of the grid, so start at this point and find the edges of the bounding box. Go round in a clockwise direction: top (north) edge first
328 for (int nX = VPtiBoundingBoxCorner[0].nGetX(); nX <= VPtiBoundingBoxCorner[1].nGetX(); nX++)
329 {
330 bFound = false;
331 for (int nY = VPtiBoundingBoxCorner[0].nGetY(); nY < m_nYGridSize; nY++)
332 {
333 if (m_pRasterGrid->m_Cell[nX][nY].bBasementElevIsMissingValue())
334 {
336 continue;
337 }
338
339 // Found a bounding box edge cell
340 m_pRasterGrid->m_Cell[nX][nY].SetBoundingBoxEdge(NORTH);
341
342 m_VEdgeCell.push_back(CGeom2DIPoint(nX, nY));
343 m_VEdgeCellEdge.push_back(NORTH);
344
345 bFound = true;
346 break;
347 }
348
349 if (! bFound)
350 {
352 LogStream << m_ulIter << ": could not find a bounding box edge cell for grid column " << nX << endl;
354 }
355 }
356
357 // Right (east) edge
358 for (int nY = VPtiBoundingBoxCorner[1].nGetY(); nY <= VPtiBoundingBoxCorner[2].nGetY(); nY++)
359 {
360 bFound = false;
361 for (int nX = VPtiBoundingBoxCorner[1].nGetX(); nX >= 0; nX--)
362 {
363 if (m_pRasterGrid->m_Cell[nX][nY].bBasementElevIsMissingValue())
364 {
366 continue;
367 }
368
369 // Found a bounding box edge cell
370 m_pRasterGrid->m_Cell[nX][nY].SetBoundingBoxEdge(EAST);
371
372 m_VEdgeCell.push_back(CGeom2DIPoint(nX, nY));
373 m_VEdgeCellEdge.push_back(EAST);
374
375 bFound = true;
376 break;
377 }
378
379 if (! bFound)
380 {
382 LogStream << m_ulIter << ": could not find a bounding box edge cell for grid row " << nY << endl;
384 }
385 }
386
387 // Bottom (south) edge
388 for (int nX = VPtiBoundingBoxCorner[2].nGetX(); nX >= VPtiBoundingBoxCorner[3].nGetX(); nX--)
389 {
390 bFound = false;
391 for (int nY = VPtiBoundingBoxCorner[2].nGetY(); nY >= 0; nY--)
392 {
393 if (m_pRasterGrid->m_Cell[nX][nY].bBasementElevIsMissingValue())
394 {
396 continue;
397 }
398
399 // Found a bounding box edge cell
400 m_pRasterGrid->m_Cell[nX][nY].SetBoundingBoxEdge(SOUTH);
401
402 m_VEdgeCell.push_back(CGeom2DIPoint(nX, nY));
403 m_VEdgeCellEdge.push_back(SOUTH);
404
405 bFound = true;
406 break;
407 }
408
409 if (! bFound)
410 {
412 LogStream << m_ulIter << ": could not find a bounding box edge cell for grid column " << nX << endl;
414 }
415 }
416
417 // Left (west) edge
418 for (int nY = VPtiBoundingBoxCorner[3].nGetY(); nY >= VPtiBoundingBoxCorner[0].nGetY(); nY--)
419 {
420 for (int nX = VPtiBoundingBoxCorner[3].nGetX(); nX < m_nXGridSize - 1; nX++)
421 // for (int nX = VPtiBoundingBoxCorner[3].nGetX(); nX < VPtiBoundingBoxCorner[3].nGetX(); nX++)
422 {
423 if (m_pRasterGrid->m_Cell[nX][nY].bBasementElevIsMissingValue())
424 {
426 continue;
427 }
428
429 // Found a bounding box edge cell
430 m_pRasterGrid->m_Cell[nX][nY].SetBoundingBoxEdge(WEST);
431
432 m_VEdgeCell.push_back(CGeom2DIPoint(nX, nY));
433 m_VEdgeCellEdge.push_back(WEST);
434
435 bFound = true;
436 break;
437 }
438
439 if (! bFound)
440 {
442 LogStream << m_ulIter << ": could not find a bounding box edge cell for grid row " << nY << endl;
444 }
445 }
446
447 return RTN_OK;
448}
449
450//===============================================================================================================================
452//===============================================================================================================================
453int CSimulation::nReadRasterGISFile(int const nDataItem, int const nLayer)
454{
455 string
456 strGISFile,
457 strDriverCode,
458 strDriverDesc,
459 strProjection,
460 strDataType;
461
462 switch (nDataItem)
463 {
464 case (LANDFORM_RASTER):
465 // Initial Landform Class GIS data
466 strGISFile = m_strInitialLandformFile;
467 break;
468
470 // Intervention class
471 strGISFile = m_strInterventionClassFile;
472 break;
473
475 // Intervention height
476 strGISFile = m_strInterventionHeightFile;
477 break;
478
479 case (SUSP_SED_RASTER):
480 // Initial Suspended Sediment GIS data
481 strGISFile = m_strInitialSuspSedimentFile;
482 break;
483
484 case (FINE_UNCONS_RASTER):
485 // Initial Unconsolidated Fine Sediment GIS data
486 strGISFile = m_VstrInitialFineUnconsSedimentFile[nLayer];
487 break;
488
489 case (SAND_UNCONS_RASTER):
490 // Initial Unconsolidated Sand Sediment GIS data
491 strGISFile = m_VstrInitialSandUnconsSedimentFile[nLayer];
492 break;
493
495 // Initial Unconsolidated Coarse Sediment GIS data
496 strGISFile = m_VstrInitialCoarseUnconsSedimentFile[nLayer];
497 break;
498
499 case (FINE_CONS_RASTER):
500 // Initial Consolidated Fine Sediment GIS data
501 strGISFile = m_VstrInitialFineConsSedimentFile[nLayer];
502 break;
503
504 case (SAND_CONS_RASTER):
505 // Initial Consolidated Sand Sediment GIS data
506 strGISFile = m_VstrInitialSandConsSedimentFile[nLayer];
507 break;
508
509 case (COARSE_CONS_RASTER):
510 // Initial Consolidated Coarse Sediment GIS data
511 strGISFile = m_VstrInitialCoarseConsSedimentFile[nLayer];
512 break;
513 }
514
515 // Do we have a filename for this data item? If we don't then just return
516 if (! strGISFile.empty())
517 {
518 // We do have a filename, so use GDAL to create a dataset object, which then opens the GIS file
519 GDALDataset* pGDALDataset = static_cast<GDALDataset*>(GDALOpen(strGISFile.c_str(), GA_ReadOnly));
520 if (NULL == pGDALDataset)
521 {
522 // Can't open file (note will already have sent GDAL error message to stdout)
523 cerr << ERR << "cannot open " << strGISFile << " for input: " << CPLGetLastErrorMsg() << endl;
525 }
526
527 // Opened OK, so get dataset information
528 strDriverCode = pGDALDataset->GetDriver()->GetDescription();
529 strDriverDesc = pGDALDataset->GetDriver()->GetMetadataItem(GDAL_DMD_LONGNAME);
530 strProjection = pGDALDataset->GetProjectionRef();
531
532 // Get geotransformation info
533 double dGeoTransform[6];
534 if (CE_Failure == pGDALDataset->GetGeoTransform(dGeoTransform))
535 {
536 // Can't get geotransformation (note will already have sent GDAL error message to stdout)
537 cerr << ERR << CPLGetLastErrorMsg() << " in " << strGISFile << endl;
539 }
540
541 // Now get dataset size, and do some checks
542 int nTmpXSize = pGDALDataset->GetRasterXSize();
543 if (nTmpXSize != m_nXGridSize)
544 {
545 // Error: incorrect number of columns specified
546 cerr << ERR << "different number of columns in " << strGISFile << " (" << nTmpXSize << ") and " << m_strInitialBasementDEMFile << "(" << m_nXGridSize << ")" << endl;
548 }
549
550 int nTmpYSize = pGDALDataset->GetRasterYSize();
551 if (nTmpYSize != m_nYGridSize)
552 {
553 // Error: incorrect number of rows specified
554 cerr << ERR << "different number of rows in " << strGISFile << " (" << nTmpYSize << ") and " << m_strInitialBasementDEMFile << " (" << m_nYGridSize << ")" << endl;
556 }
557
558 double dTmp = m_dGeoTransform[0] - (m_dGeoTransform[1] / 2);
560 {
561 // Error: different min x from DEM file
562 cerr << ERR << "different min x values in " << strGISFile << " (" << dTmp << ") and " << m_strInitialBasementDEMFile << " (" << m_dNorthWestXExtCRS << ")" << endl;
564 }
565
566 dTmp = m_dGeoTransform[3] - (m_dGeoTransform[5] / 2);
568 {
569 // Error: different min x from DEM file
570 cerr << ERR << "different min y values in " << strGISFile << " (" << dTmp << ") and " << m_strInitialBasementDEMFile << " (" << m_dNorthWestYExtCRS << ")" << endl;
572 }
573
574 double dTmpResX = tAbs(dGeoTransform[1]);
575 if (! bFPIsEqual(dTmpResX, m_dCellSide, 1e-2))
576 {
577 // Error: different cell size in X direction: note that due to rounding errors in some GIS packages, must expect some discrepancies
578 cerr << ERR << "cell size in X direction (" << dTmpResX << ") in " << strGISFile << " differs from cell size in of basement DEM (" << m_dCellSide << ")" << endl;
580 }
581
582 double dTmpResY = tAbs(dGeoTransform[5]);
583 if (! bFPIsEqual(dTmpResY, m_dCellSide, 1e-2))
584 {
585 // Error: different cell size in Y direction: note that due to rounding errors in some GIS packages, must expect some discrepancies
586 cerr << ERR << "cell size in Y direction (" << dTmpResY << ") in " << strGISFile << " differs from cell size of basement DEM (" << m_dCellSide << ")" << endl;
588 }
589
590 // Now get GDAL raster band information
591 GDALRasterBand* pGDALBand = pGDALDataset->GetRasterBand(1); // TODO 028 Give a message if there are several bands
592 int nBlockXSize = 0, nBlockYSize = 0;
593 pGDALBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
594 strDataType = GDALGetDataTypeName(pGDALBand->GetRasterDataType());
595
596 switch (nDataItem)
597 {
598 case (LANDFORM_RASTER):
599 // Initial Landform Class GIS data
600 m_strGDALLDriverCode = strDriverCode;
601 m_strGDALLDriverDesc = strDriverDesc;
602 m_strGDALLProjection = strProjection;
603 m_strGDALLDataType = strDataType;
604 break;
605
607 // Intervention class
608 m_strGDALICDriverCode = strDriverCode;
609 m_strGDALICDriverDesc = strDriverDesc;
610 m_strGDALICProjection = strProjection;
611 m_strGDALICDataType = strDataType;
612 break;
613
615 // Intervention height
616 m_strGDALIHDriverCode = strDriverCode;
617 m_strGDALIHDriverDesc = strDriverDesc;
618 m_strGDALIHProjection = strProjection;
619 m_strGDALIHDataType = strDataType;
620 break;
621
622 case (SUSP_SED_RASTER):
623 // Initial Suspended Sediment GIS data
624 m_strGDALISSDriverCode = strDriverCode;
625 m_strGDALISSDriverDesc = strDriverDesc;
626 m_strGDALISSProjection = strProjection;
627 m_strGDALISSDataType = strDataType;
628 break;
629
630 case (FINE_UNCONS_RASTER):
631 // Initial Unconsolidated Fine Sediment GIS data
632 m_VstrGDALIUFDriverCode[nLayer] = strDriverCode;
633 m_VstrGDALIUFDriverDesc[nLayer] = strDriverDesc;
634 m_VstrGDALIUFProjection[nLayer] = strProjection;
635 m_VstrGDALIUFDataType[nLayer] = strDataType;
636 break;
637
638 case (SAND_UNCONS_RASTER):
639 // Initial Unconsolidated Sand Sediment GIS data
640 m_VstrGDALIUSDriverCode[nLayer] = strDriverCode;
641 m_VstrGDALIUSDriverDesc[nLayer] = strDriverDesc;
642 m_VstrGDALIUSProjection[nLayer] = strProjection;
643 m_VstrGDALIUSDataType[nLayer] = strDataType;
644 break;
645
647 // Initial Unconsolidated Coarse Sediment GIS data
648 m_VstrGDALIUCDriverCode[nLayer] = strDriverCode;
649 m_VstrGDALIUCDriverDesc[nLayer] = strDriverDesc;
650 m_VstrGDALIUCProjection[nLayer] = strProjection;
651 m_VstrGDALIUCDataType[nLayer] = strDataType;
652 break;
653
654 case (FINE_CONS_RASTER):
655 // Initial Consolidated Fine Sediment GIS data
656 m_VstrGDALICFDriverCode[nLayer] = strDriverCode;
657 m_VstrGDALICFDriverDesc[nLayer] = strDriverDesc;
658 m_VstrGDALICFProjection[nLayer] = strProjection;
659 m_VstrGDALICFDataType[nLayer] = strDataType;
660 break;
661
662 case (SAND_CONS_RASTER):
663 // Initial Consolidated Sand Sediment GIS data
664 m_VstrGDALICSDriverCode[nLayer] = strDriverCode;
665 m_VstrGDALICSDriverDesc[nLayer] = strDriverDesc;
666 m_VstrGDALICSProjection[nLayer] = strProjection;
667 m_VstrGDALICSDataType[nLayer] = strDataType;
668 break;
669
670 case (COARSE_CONS_RASTER):
671 // Initial Consolidated Coarse Sediment GIS data
672 m_VstrGDALICCDriverCode[nLayer] = strDriverCode;
673 m_VstrGDALICCDriverDesc[nLayer] = strDriverDesc;
674 m_VstrGDALICCProjection[nLayer] = strProjection;
675 m_VstrGDALICCDataType[nLayer] = strDataType;
676 break;
677 }
678
679 // If present, get the missing value setting
680 string strTmp = strToLower(&strDataType);
681 if (strTmp.find("int") != string::npos)
682 {
683 // This is an integer layer
684 CPLPushErrorHandler(CPLQuietErrorHandler); // Needed to get next line to fail silently, if it fails
685 int nMissingValue = static_cast<int>(pGDALBand->GetNoDataValue()); // Note will fail for some formats
686 CPLPopErrorHandler();
687
688 if (nMissingValue != m_nMissingValue)
689 {
690 cerr << " " << NOTE << "NODATA value in " << strGISFile << " is " << nMissingValue << "\n instead using CoatalME's default integer NODATA value " << m_nMissingValue << endl;
691 }
692 }
693 else
694 {
695 // This is a floating point layer
696 CPLPushErrorHandler(CPLQuietErrorHandler); // Needed to get next line to fail silently, if it fails
697 double dMissingValue = pGDALBand->GetNoDataValue(); // Note will fail for some formats
698 CPLPopErrorHandler();
699
700 if (! bFPIsEqual(dMissingValue, m_dMissingValue, TOLERANCE))
701 {
702 cerr << " " << NOTE << "NODATA value in " << strGISFile << " is " << dMissingValue << "\n instead using CoastalME's default floating-point NODATA value " << m_dMissingValue << endl;
703 }
704 }
705
706 // Allocate memory for a 1D array, to hold the scan line for GDAL
707 double* pdScanline = new double[m_nXGridSize];
708 if (NULL == pdScanline)
709 {
710 // Error, can't allocate memory
711 cerr << ERR << "cannot allocate memory for " << m_nXGridSize << " x 1D array" << endl;
712 return (RTN_ERR_MEMALLOC);
713 }
714
715 // Now read in the data
716 int nMissing = 0;
717 for (int nY = 0; nY < m_nYGridSize; nY++)
718 {
719 // Read scanline
720 if (CE_Failure == pGDALBand->RasterIO(GF_Read, 0, nY, m_nXGridSize, 1, pdScanline, m_nXGridSize, 1, GDT_Float64, 0, 0, NULL))
721 {
722 // Error while reading scanline
723 cerr << ERR << CPLGetLastErrorMsg() << " in " << strGISFile << endl;
725 }
726
727 // All OK, so read scanline into cells (including any missing values)
728 for (int nX = 0; nX < m_nXGridSize; nX++)
729 {
730 int nTmp;
731 switch (nDataItem)
732 {
733 case (LANDFORM_RASTER):
734 // Initial Landform Class GIS data, is integer TODO 030 Do we also need a landform sub-category input?
735 nTmp = static_cast<int>(pdScanline[nX]);
736
737 if (isnan(nTmp)) // Deal with any NaN values
738 {
739 nTmp = m_nMissingValue;
740 nMissing++;
741 }
742
743 m_pRasterGrid->m_Cell[nX][nY].pGetLandform()->SetLFCategory(nTmp);
744 break;
745
747 // Intervention class, is integer
748 nTmp = static_cast<int>(pdScanline[nX]);
749
750 if (isnan(nTmp)) // Deal with any NaN values
751 {
752 nTmp = m_nMissingValue;
753 nMissing++;
754 }
755
756 m_pRasterGrid->m_Cell[nX][nY].SetInterventionClass(nTmp);
757 break;
758
760 // Intervention height
761 dTmp = pdScanline[nX];
762
763 if (isnan(dTmp)) // Deal with any NaN values
764 {
765 dTmp = m_dMissingValue;
766 nMissing++;
767 }
768
769 m_pRasterGrid->m_Cell[nX][nY].SetInterventionHeight(dTmp);
770 break;
771
772 case (SUSP_SED_RASTER):
773 // Initial Suspended Sediment GIS data
774 dTmp = pdScanline[nX];
775
776 if (isnan(dTmp)) // Deal with any NaN values
777 {
778 dTmp = m_dMissingValue;
779 nMissing++;
780 }
781
782 m_pRasterGrid->m_Cell[nX][nY].SetSuspendedSediment(dTmp);
783 break;
784
785 case (FINE_UNCONS_RASTER):
786 // Initial Unconsolidated Fine Sediment GIS data
787 dTmp = pdScanline[nX];
788
789 if (isnan(dTmp)) // Deal with any NaN values
790 {
791 dTmp = m_dMissingValue;
792 nMissing++;
793 }
794
795 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nLayer)->pGetUnconsolidatedSediment()->SetFineDepth(dTmp);
796 break;
797
798 case (SAND_UNCONS_RASTER):
799 // Initial Unconsolidated Sand Sediment GIS data
800 dTmp = pdScanline[nX];
801
802 if (isnan(dTmp)) // Deal with any NaN values
803 {
804 dTmp = m_dMissingValue;
805 nMissing++;
806 }
807
808 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nLayer)->pGetUnconsolidatedSediment()->SetSandDepth(dTmp);
809 break;
810
812 // Initial Unconsolidated Coarse Sediment GIS data
813 dTmp = pdScanline[nX];
814
815 if (isnan(dTmp)) // Deal with any NaN values
816 {
817 dTmp = m_dMissingValue;
818 nMissing++;
819 }
820
821 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nLayer)->pGetUnconsolidatedSediment()->SetCoarseDepth(dTmp);
822 break;
823
824 case (FINE_CONS_RASTER):
825 // Initial Consolidated Fine Sediment GIS data
826 dTmp = pdScanline[nX];
827
828 if (isnan(dTmp)) // Deal with any NaN values
829 {
830 dTmp = m_dMissingValue;
831 nMissing++;
832 }
833
834 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nLayer)->pGetConsolidatedSediment()->SetFineDepth(dTmp);
835 break;
836
837 case (SAND_CONS_RASTER):
838 // Initial Consolidated Sand Sediment GIS data
839 dTmp = pdScanline[nX];
840
841 if (isnan(dTmp)) // Deal with any NaN values
842 {
843 dTmp = m_dMissingValue;
844 nMissing++;
845 }
846
847 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nLayer)->pGetConsolidatedSediment()->SetSandDepth(dTmp);
848 break;
849
850 case (COARSE_CONS_RASTER):
851 // Initial Consolidated Coarse Sediment GIS data
852 dTmp = pdScanline[nX];
853
854 if (isnan(dTmp)) // Deal with any NaN values
855 {
856 dTmp = m_dMissingValue;
857 nMissing++;
858 }
859
860 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nLayer)->pGetConsolidatedSediment()->SetCoarseDepth(dTmp);
861 break;
862 }
863 }
864 }
865
866 // Finished, so get rid of dataset object
867 GDALClose(pGDALDataset);
868
869 // Get rid of memory allocated to this array
870 delete[] pdScanline;
871
872 if (nMissing > 0)
873 {
874 cerr << WARN << nMissing << " missing values in " << strGISFile << endl;
875 LogStream << WARN << nMissing << " missing values in " << strGISFile << endl;
876 }
877 }
878
879 return RTN_OK;
880}
881
882//===============================================================================================================================
884//===============================================================================================================================
885bool CSimulation::bWriteRasterGISFile(int const nDataItem, string const *strPlotTitle, int const nLayer, double const dElev)
886{
887 bool bIsInteger = false;
888
889 // Begin constructing the file name for this save
890 string
891 strFilePathName(m_strOutPath),
892 strLayer = "_layer_";
893
894 stringstream ststrTmp;
895
896 strLayer.append(to_string(nLayer + 1));
897
898 switch (nDataItem)
899 {
901 strFilePathName.append(RASTER_BASEMENT_ELEVATION_NAME);
902 break;
903
905 strFilePathName.append(RASTER_SEDIMENT_TOP_NAME);
906 break;
907
909 strFilePathName.append(RASTER_TOP_NAME);
910 break;
911
913 strFilePathName.append(RASTER_LOCAL_SLOPE_NAME);
914 break;
915
917 strFilePathName.append(RASTER_SEA_DEPTH_NAME);
918 break;
919
921 strFilePathName.append(RASTER_AVG_SEA_DEPTH_NAME);
922 break;
923
925 strFilePathName.append(RASTER_WAVE_HEIGHT_NAME);
926 break;
927
929 strFilePathName.append(RASTER_AVG_WAVE_HEIGHT_NAME);
930 break;
931
933 strFilePathName.append(RASTER_WAVE_ORIENTATION_NAME);
934 break;
935
937 strFilePathName.append(RASTER_AVG_WAVE_ORIENTATION_NAME);
938 break;
939
941 strFilePathName.append(RASTER_BEACH_PROTECTION_NAME);
942 break;
943
945 strFilePathName.append(RASTER_POTENTIAL_PLATFORM_EROSION_NAME);
946 break;
947
949 strFilePathName.append(RASTER_ACTUAL_PLATFORM_EROSION_NAME);
950 break;
951
953 strFilePathName.append(RASTER_TOTAL_POTENTIAL_PLATFORM_EROSION_NAME);
954 break;
955
957 strFilePathName.append(RASTER_TOTAL_ACTUAL_PLATFORM_EROSION_NAME);
958 break;
959
961 strFilePathName.append(RASTER_POTENTIAL_BEACH_EROSION_NAME);
962 break;
963
965 strFilePathName.append(RASTER_ACTUAL_BEACH_EROSION_NAME);
966 break;
967
969 strFilePathName.append(RASTER_TOTAL_POTENTIAL_BEACH_EROSION_NAME);
970 break;
971
973 strFilePathName.append(RASTER_TOTAL_ACTUAL_BEACH_EROSION_NAME);
974 break;
975
977 strFilePathName.append(RASTER_BEACH_DEPOSITION_NAME);
978 break;
979
981 strFilePathName.append(RASTER_TOTAL_BEACH_DEPOSITION_NAME);
982 break;
983
985 strFilePathName.append(RASTER_SUSP_SED_NAME);
986 break;
987
989 strFilePathName.append(RASTER_AVG_SUSP_SED_NAME);
990 break;
991
993 strFilePathName.append(RASTER_FINE_UNCONS_NAME);
994 strFilePathName.append(strLayer);
995 break;
996
998 strFilePathName.append(RASTER_SAND_UNCONS_NAME);
999 strFilePathName.append(strLayer);
1000 break;
1001
1003 strFilePathName.append(RASTER_COARSE_UNCONS_NAME);
1004 strFilePathName.append(strLayer);
1005 break;
1006
1008 strFilePathName.append(RASTER_FINE_CONS_NAME);
1009 strFilePathName.append(strLayer);
1010 break;
1011
1013 strFilePathName.append(RASTER_SAND_CONS_NAME);
1014 strFilePathName.append(strLayer);
1015 break;
1016
1018 strFilePathName.append(RASTER_COARSE_CONS_NAME);
1019 strFilePathName.append(strLayer);
1020 break;
1021
1023 strFilePathName.append(RASTER_CLIFF_COLLAPSE_EROSION_FINE_NAME);
1024 break;
1025
1027 strFilePathName.append(RASTER_CLIFF_COLLAPSE_EROSION_SAND_NAME);
1028 break;
1029
1031 strFilePathName.append(RASTER_CLIFF_COLLAPSE_EROSION_COARSE_NAME);
1032 break;
1033
1035 strFilePathName.append(RASTER_TOTAL_CLIFF_COLLAPSE_EROSION_FINE_NAME);
1036 break;
1037
1039 strFilePathName.append(RASTER_TOTAL_CLIFF_COLLAPSE_EROSION_SAND_NAME);
1040 break;
1041
1044 break;
1045
1047 strFilePathName.append(RASTER_CLIFF_COLLAPSE_DEPOSITION_SAND_NAME);
1048 break;
1049
1051 strFilePathName.append(RASTER_CLIFF_COLLAPSE_DEPOSITION_COARSE_NAME);
1052 break;
1053
1056 break;
1057
1060 break;
1061
1063 strFilePathName.append(RASTER_INTERVENTION_HEIGHT_NAME);
1064 break;
1065
1067 strFilePathName.append(RASTER_DEEP_WATER_WAVE_ORIENTATION_NAME);
1068 break;
1069
1071 strFilePathName.append(RASTER_DEEP_WATER_WAVE_HEIGHT_NAME);
1072 break;
1073
1075 strFilePathName.append(RASTER_POLYGON_GAIN_OR_LOSS_NAME);
1076 break;
1077
1079 strFilePathName.append(RASTER_WAVE_PERIOD_NAME);
1080 break;
1081
1083 strFilePathName.append(RASTER_SEDIMENT_INPUT_EVENT_NAME);
1084 break;
1085
1087 bIsInteger = true;
1088 strFilePathName.append(RASTER_BEACH_MASK_NAME);
1089 break;
1090
1092 bIsInteger = true;
1093 strFilePathName.append(RASTER_POTENTIAL_PLATFORM_EROSION_MASK_NAME);
1094 break;
1095
1097 bIsInteger = true;
1098 strFilePathName.append(RASTER_INUNDATION_MASK_NAME);
1099 break;
1100
1101 case (RASTER_PLOT_SLICE):
1102 bIsInteger = true;
1103 ststrTmp.str("");
1104 ststrTmp.clear();
1105
1106 // TODO 031 Get working for multiple slices
1107 strFilePathName.append(RASTER_SLICE_NAME);
1108 ststrTmp << "_" << dElev << "_";
1109 strFilePathName.append(ststrTmp.str());
1110 break;
1111
1112 case (RASTER_PLOT_LANDFORM):
1113 bIsInteger = true;
1114 strFilePathName.append(RASTER_LANDFORM_NAME);
1115 break;
1116
1118 bIsInteger = true;
1119 strFilePathName.append(RASTER_INTERVENTION_CLASS_NAME);
1120 break;
1121
1122 case (RASTER_PLOT_COAST):
1123 bIsInteger = true;
1124 strFilePathName.append(RASTER_COAST_NAME);
1125 break;
1126
1128 bIsInteger = true;
1129 strFilePathName.append(RASTER_COAST_NORMAL_NAME);
1130 break;
1131
1133 bIsInteger = true;
1134 strFilePathName.append(RASTER_ACTIVE_ZONE_NAME);
1135 break;
1136
1137 case (RASTER_PLOT_POLYGON):
1138 bIsInteger = true;
1139 strFilePathName.append(RASTER_POLYGON_NAME);
1140 break;
1141
1143 bIsInteger = true;
1144 strFilePathName.append(RASTER_SHADOW_ZONE_NAME);
1145 break;
1146
1148 bIsInteger = true;
1149 strFilePathName.append(RASTER_SHADOW_DOWNDRIFT_ZONE_NAME);
1150 break;
1151
1153 bIsInteger = true;
1154 strFilePathName.append(RASTER_POLYGON_UPDRIFT_OR_DOWNDRIFT_NAME);
1155 break;
1156
1158 bIsInteger = true;
1159 strFilePathName.append(RASTER_SETUP_SURGE_FLOOD_MASK_NAME);
1160 break;
1161
1163 bIsInteger = true;
1164 strFilePathName.append(RASTER_SETUP_SURGE_RUNUP_FLOOD_MASK_NAME);
1165 break;
1166
1168 bIsInteger = true;
1169 strFilePathName.append(RASTER_WAVE_FLOOD_LINE_NAME);
1170 break;
1171 }
1172
1173 // Append the 'save number' to the filename, and prepend zeros to the save number
1174 ststrTmp.str("");
1175 ststrTmp.clear();
1176
1177 strFilePathName.append("_");
1179 {
1180 // Save number is m_bGISSaveDigitsSequential
1181 ststrTmp << FillToWidth('0', m_nGISMaxSaveDigits) << m_nGISSave;
1182 }
1183 else
1184 {
1185 // Save number is iteration
1186 ststrTmp << FillToWidth('0', m_nGISMaxSaveDigits) << m_ulIter;
1187 }
1188 strFilePathName.append(ststrTmp.str());
1189
1190 // Finally, maybe append the extension
1192 {
1193 strFilePathName.append(".");
1194 strFilePathName.append(m_strGDALRasterOutputDriverExtension);
1195 }
1196
1197 // TODO 065 Used to try to debug floating point exception in pDriver->Create() below
1198 // CPLSetConfigOption("CPL_DEBUG", "ON");
1199 // CPLSetConfigOption("GDAL_NUM_THREADS", "1");
1200
1201 GDALDriver* pDriver;
1202 GDALDataset* pDataSet;
1203 if (m_bGDALCanCreate)
1204 {
1205 // The user-requested raster driver supports the Create() method
1206 pDriver = GetGDALDriverManager()->GetDriverByName(m_strRasterGISOutFormat.c_str());
1207
1209 {
1210 pDataSet = pDriver->Create(strFilePathName.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Int16, m_papszGDALRasterOptions);
1211 }
1212 else if (m_strRasterGISOutFormat == "gpkg")
1213 {
1214 // TODO 065 Floating point exception here
1215 pDataSet = pDriver->Create(strFilePathName.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Byte, m_papszGDALRasterOptions);
1216 }
1217 else
1218 {
1219 pDataSet = pDriver->Create(strFilePathName.c_str(), m_nXGridSize, m_nYGridSize, 1, m_GDALWriteFloatDataType, m_papszGDALRasterOptions);
1220 }
1221
1222 if (NULL == pDataSet)
1223 {
1224 // Error, couldn't create file
1225 cerr << ERR << "cannot create " << m_strRasterGISOutFormat << " file named " << strFilePathName << endl
1226 << CPLGetLastErrorMsg() << endl;
1227 return false;
1228 }
1229 }
1230 else
1231 {
1232 // The user-requested raster driver does not support the Create() method, so we must first create a memory-file dataset
1233 pDriver = GetGDALDriverManager()->GetDriverByName("MEM");
1234 pDataSet = pDriver->Create("", m_nXGridSize, m_nYGridSize, 1, m_GDALWriteFloatDataType, NULL);
1235 if (NULL == pDataSet)
1236 {
1237 // Couldn't create in-memory file dataset
1238 cerr << ERR << "cannot create in-memory file for " << m_strRasterGISOutFormat << " file named " << strFilePathName << endl
1239 << CPLGetLastErrorMsg() << endl;
1240 return false;
1241 }
1242 }
1243
1244 // Set projection info for output dataset (will be same as was read in from basement DEM)
1245 CPLPushErrorHandler(CPLQuietErrorHandler); // Needed to get next line to fail silently, if it fails
1246 pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str()); // Will fail for some formats
1247 CPLPopErrorHandler();
1248
1249 // Set geotransformation info for output dataset (will be same as was read in from DEM)
1250 if (CE_Failure == pDataSet->SetGeoTransform(m_dGeoTransform))
1251 LogStream << WARN << "cannot write geotransformation information to " << m_strRasterGISOutFormat << " file named " << strFilePathName << endl << CPLGetLastErrorMsg() << endl;
1252
1253 // Allocate memory for a 1D array, to hold the floating point raster band data for GDAL
1254 double* pdRaster = new double[m_ulNumCells];
1255 if (NULL == pdRaster)
1256 {
1257 // Error, can't allocate memory
1258 cerr << ERR << "cannot allocate memory for " << m_ulNumCells << " x 1D floating-point array for " << m_strRasterGISOutFormat << " file named " << strFilePathName << endl;
1259 return (RTN_ERR_MEMALLOC);
1260 }
1261
1262 bool bScaleOutput = false;
1263 double dRangeScale = 0;
1264 double dDataMin = 0;
1265
1267 {
1268 double dDataMax = 0;
1269
1270 // The output file format cannot handle floating-point numbers, so we may need to scale the output
1271 GetRasterOutputMinMax(nDataItem, dDataMin, dDataMax, nLayer, 0);
1272
1273 double
1274 dDataRange = dDataMax - dDataMin,
1275 dWriteRange = static_cast<double>(m_lGDALMaxCanWrite - m_lGDALMinCanWrite);
1276
1277 if (dDataRange > 0)
1278 dRangeScale = dWriteRange / dDataRange;
1279
1280 // If we are attempting to write values which are outside this format's allowable range, and the user has set the option, then scale the output
1281 if (((dDataMin < static_cast<double>(m_lGDALMinCanWrite)) || (dDataMax > static_cast<double>(m_lGDALMaxCanWrite))) && m_bScaleRasterOutput)
1282 bScaleOutput = true;
1283 }
1284
1285 // Fill the array
1286 int
1287 n = 0,
1288 nPoly = 0,
1289 nTopLayer = 0;
1290 double dTmp = 0;
1291 for (int nY = 0; nY < m_nYGridSize; nY++)
1292 {
1293 for (int nX = 0; nX < m_nXGridSize; nX++)
1294 {
1295 switch (nDataItem)
1296 {
1298 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetBasementElev();
1299 break;
1300
1302 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev();
1303 break;
1304
1306 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetSedimentPlusInterventionTopElev();
1307 break;
1308
1310 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetLocalConsSlope();
1311 break;
1312
1313 case (RASTER_PLOT_SEA_DEPTH):
1314 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetSeaDepth();
1315 break;
1316
1318 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetTotSeaDepth() / static_cast<double>(m_ulIter);
1319 break;
1320
1322 if (m_pRasterGrid->m_Cell[nX][nY].bIsInundated())
1323 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetWaveHeight();
1324 else
1325 dTmp = 0;
1326 break;
1327
1329 if (m_pRasterGrid->m_Cell[nX][nY].bIsInundated())
1330 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetTotWaveHeight() / static_cast<double>(m_ulIter);
1331 else
1332 dTmp = 0;
1333 break;
1334
1336 if (m_pRasterGrid->m_Cell[nX][nY].bIsInundated())
1337 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetWaveAngle();
1338 else
1339 dTmp = 0;
1340 break;
1341
1343 if (m_pRasterGrid->m_Cell[nX][nY].bIsInundated())
1344 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetTotWaveAngle() / static_cast<double>(m_ulIter);
1345 else
1346 dTmp = 0;
1347 break;
1348
1350 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetBeachProtectionFactor();
1351
1352 if (bFPIsEqual(dTmp, DBL_NODATA, TOLERANCE))
1353 dTmp = m_dMissingValue;
1354 else
1355 dTmp = 1 - dTmp; // Output the inverse, seems more intuitive
1356
1357 break;
1358
1360 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetPotentialPlatformErosion();
1361 break;
1362
1364 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetActualPlatformErosion();
1365 break;
1366
1368 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetTotPotentialPlatformErosion();
1369 break;
1370
1372 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetTotActualPlatformErosion();
1373 break;
1374
1376 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetPotentialBeachErosion();
1377 break;
1378
1380 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetActualBeachErosion();
1381 break;
1382
1384 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetTotPotentialBeachErosion();
1385 break;
1386
1388 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetTotActualBeachErosion();
1389 break;
1390
1392 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetBeachDeposition();
1393 break;
1394
1396 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetTotBeachDeposition();
1397 break;
1398
1400 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetSuspendedSediment();
1401 break;
1402
1404 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetTotSuspendedSediment() / static_cast<double>(m_ulIter);
1405 break;
1406
1408 dTmp = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nLayer)->pGetUnconsolidatedSediment()->dGetFineDepth();
1409 break;
1410
1412 dTmp = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nLayer)->pGetUnconsolidatedSediment()->dGetSandDepth();
1413 break;
1414
1416 dTmp = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nLayer)->pGetUnconsolidatedSediment()->dGetCoarseDepth();
1417 break;
1418
1420 dTmp = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nLayer)->pGetConsolidatedSediment()->dGetFineDepth();
1421 break;
1422
1424 dTmp = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nLayer)->pGetConsolidatedSediment()->dGetSandDepth();
1425 break;
1426
1428 dTmp = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nLayer)->pGetConsolidatedSediment()->dGetCoarseDepth();
1429 break;
1430
1432 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetThisIterCliffCollapseErosionFine();
1433 break;
1434
1436 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetThisIterCliffCollapseErosionSand();
1437 break;
1438
1440 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetThisIterCliffCollapseErosionCoarse();
1441 break;
1442
1444 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetTotCliffCollapseFine();
1445 break;
1446
1448 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetTotCliffCollapseSand();
1449 break;
1450
1452 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetTotCliffCollapseCoarse();
1453 break;
1454
1456 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetThisIterCliffCollapseSandTalusDeposition();
1457 break;
1458
1460 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetThisIterCliffCollapseCoarseTalusDeposition();
1461 break;
1462
1464 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetTotSandTalusDeposition();
1465 break;
1466
1468 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetTotCoarseTalusDeposition();
1469 break;
1470
1472 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetInterventionHeight();
1473 break;
1474
1476 if (m_pRasterGrid->m_Cell[nX][nY].bIsInundated())
1477 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetCellDeepWaterWaveAngle();
1478 else
1479 dTmp = 0;
1480 break;
1481
1483 if (m_pRasterGrid->m_Cell[nX][nY].bIsInundated())
1484 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetCellDeepWaterWaveHeight();
1485 else
1486 dTmp = 0;
1487 break;
1488
1490 if (m_pRasterGrid->m_Cell[nX][nY].bIsInundated())
1491 dTmp = m_pRasterGrid->m_Cell[nX][nY].dGetCellDeepWaterWavePeriod();
1492 else
1493 dTmp = 0;
1494 break;
1495
1497 nPoly = m_pRasterGrid->m_Cell[nX][nY].nGetPolygonID();
1498
1499 if (nPoly == INT_NODATA)
1500 dTmp = m_dMissingValue;
1501 else
1502 {
1503 // Get total volume (all sediment size classes) of change in sediment for this polygon for this timestep (-ve erosion, +ve deposition)
1504 dTmp = m_pVCoastPolygon[nPoly]->dGetBeachDepositionAndSuspensionAllUncons() * m_dCellArea;
1505
1506 // Calculate the rate in m^3 / sec
1507 dTmp /= (m_dTimeStep * 3600);
1508 }
1509 break;
1510
1512 // cppcheck-suppress assignBoolToFloat
1513 dTmp = m_pRasterGrid->m_Cell[nX][nY].bPotentialPlatformErosion();
1514 break;
1515
1517 // cppcheck-suppress assignBoolToFloat
1518 dTmp = m_pRasterGrid->m_Cell[nX][nY].bIsInContiguousSea();
1519 break;
1520
1522 dTmp = 0;
1523 nTopLayer = m_pRasterGrid->m_Cell[nX][nY].nGetTopNonZeroLayerAboveBasement();
1524 if ((nTopLayer == INT_NODATA) || (nTopLayer == NO_NONZERO_THICKNESS_LAYERS))
1525 break;
1526
1527 if ((m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->dGetUnconsolidatedThickness() > 0) && (m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev() > m_dThisIterSWL))
1528 dTmp = 1;
1529 break;
1530
1531 case (RASTER_PLOT_SLICE):
1532 dTmp = m_pRasterGrid->m_Cell[nX][nY].nGetLayerAtElev(dElev);
1533 break;
1534
1535 case (RASTER_PLOT_LANDFORM):
1536 dTmp = m_pRasterGrid->m_Cell[nX][nY].pGetLandform()->nGetLFCategory();
1537 if ((static_cast<int>(dTmp) == LF_CAT_DRIFT) || (static_cast<int>(dTmp) == LF_CAT_CLIFF))
1538 dTmp = m_pRasterGrid->m_Cell[nX][nY].pGetLandform()->nGetLFSubCategory();
1539 break;
1540
1542 dTmp = m_pRasterGrid->m_Cell[nX][nY].nGetInterventionClass();
1543 break;
1544
1545 case (RASTER_PLOT_COAST):
1546 dTmp = (m_pRasterGrid->m_Cell[nX][nY].bIsCoastline() ? 1 : 0);
1547 break;
1548
1550 // dTmp = (m_pRasterGrid->m_Cell[nX][nY].bIsProfile() ? 1 : 0);
1551 dTmp = m_pRasterGrid->m_Cell[nX][nY].nGetProfileID();
1552 break;
1553
1555 dTmp = (m_pRasterGrid->m_Cell[nX][nY].bIsInActiveZone() ? 1 : 0);
1556 break;
1557
1558 case (RASTER_PLOT_POLYGON):
1559 dTmp = m_pRasterGrid->m_Cell[nX][nY].nGetPolygonID();
1560 break;
1561
1563 dTmp = m_pRasterGrid->m_Cell[nX][nY].nGetShadowZoneNumber();
1564 break;
1565
1567 dTmp = m_pRasterGrid->m_Cell[nX][nY].nGetDownDriftZoneNumber();
1568 break;
1569
1571 nPoly = m_pRasterGrid->m_Cell[nX][nY].nGetPolygonID();
1572 if (nPoly == INT_NODATA)
1573 dTmp = m_nMissingValue;
1574 else
1575 {
1576 if (m_pVCoastPolygon[nPoly]->bDownCoastThisIter())
1577 dTmp = 1;
1578 else
1579 dTmp = 0;
1580 }
1581 break;
1582
1584 dTmp = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->dGetTotAllSedimentInputDepth();
1585 break;
1586
1588 dTmp = (m_pRasterGrid->m_Cell[nX][nY].bIsFloodBySetupSurge() ? 1 : 0);
1589 break;
1590
1592 dTmp = (m_pRasterGrid->m_Cell[nX][nY].bIsFloodBySetupSurgeRunup() ? 1 : 0);
1593 break;
1594
1596 dTmp = (m_pRasterGrid->m_Cell[nX][nY].bIsFloodLine() ? 1 : 0);
1597 break;
1598 }
1599
1600 // If necessary, scale this value
1601 if (bScaleOutput)
1602 {
1603 if (bFPIsEqual(dTmp, DBL_NODATA, TOLERANCE))
1604 dTmp = 0; // TODO 032 Improve this
1605 else
1606 dTmp = dRound(static_cast<double>(m_lGDALMinCanWrite) + (dRangeScale * (dTmp - dDataMin)));
1607 }
1608
1609 // Write this value to the array
1610 pdRaster[n++] = dTmp;
1611 }
1612 }
1613
1614 // Create a single raster band
1615 GDALRasterBand* pBand = pDataSet->GetRasterBand(1);
1616
1617 // And fill it with the NODATA value
1618 if (bIsInteger)
1619 pBand->Fill(m_nMissingValue);
1620 else
1621 pBand->Fill(m_dMissingValue);
1622
1623 // Set value units for this band
1624 string strUnits;
1625 switch (nDataItem)
1626 {
1630 case (RASTER_PLOT_SEA_DEPTH):
1665 strUnits = "m";
1666 break;
1667
1669 strUnits = "m/m";
1670 break;
1671
1674 strUnits = "degrees";
1675 break;
1676
1678 strUnits = "cumecs";
1679 break;
1681 strUnits = "secs";
1682 break;
1683
1687 case (RASTER_PLOT_SLICE):
1688 case (RASTER_PLOT_LANDFORM):
1690 case (RASTER_PLOT_COAST):
1693 case (RASTER_PLOT_POLYGON):
1700 strUnits = "none";
1701 break;
1702 }
1703
1704 CPLPushErrorHandler(CPLQuietErrorHandler); // Needed to get next line to fail silently, if it fails
1705 pBand->SetUnitType(strUnits.c_str()); // Not supported for some GIS formats
1706 CPLPopErrorHandler();
1707
1708 // Tell the output dataset about NODATA (missing values)
1709 CPLPushErrorHandler(CPLQuietErrorHandler); // Needed to get next line to fail silently, if it fails
1710 if (bIsInteger)
1711 pBand->SetNoDataValue(m_nMissingValue); // Will fail for some formats
1712 else
1713 pBand->SetNoDataValue(m_dMissingValue); // Will fail for some formats
1714 CPLPopErrorHandler();
1715
1716 // Construct the description
1717 string strDesc(*strPlotTitle);
1718 if (nDataItem == RASTER_PLOT_SLICE)
1719 {
1720 ststrTmp.clear();
1721 ststrTmp << dElev << "m, ";
1722 strDesc.append(ststrTmp.str());
1723 }
1724 strDesc.append(" at ");
1725 strDesc.append(strDispTime(m_dSimElapsed, false, false));
1726
1727 // Set the GDAL description
1728 pBand->SetDescription(strDesc.c_str());
1729
1730 // Set raster category names
1731 char** papszCategoryNames = NULL;
1732 switch (nDataItem)
1733 {
1734 case (RASTER_PLOT_SLICE):
1735 papszCategoryNames = CSLAddString(papszCategoryNames, "Basement");
1736 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 0");
1737 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 1");
1738 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 2");
1739 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 3");
1740 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 4");
1741 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 5");
1742 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 6");
1743 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 7");
1744 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 8");
1745 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 9");
1746 break;
1747
1748 case (RASTER_PLOT_LANDFORM):
1749 papszCategoryNames = CSLAddString(papszCategoryNames, "None");
1750 papszCategoryNames = CSLAddString(papszCategoryNames, "Hinterland");
1751 papszCategoryNames = CSLAddString(papszCategoryNames, "Sea");
1752 papszCategoryNames = CSLAddString(papszCategoryNames, "Cliff");
1753 papszCategoryNames = CSLAddString(papszCategoryNames, "Drift");
1754 papszCategoryNames = CSLAddString(papszCategoryNames, "Intervention");
1755
1756 papszCategoryNames = CSLAddString(papszCategoryNames, "Cliff on Coastline");
1757 papszCategoryNames = CSLAddString(papszCategoryNames, "Inland Cliff");
1758
1759 papszCategoryNames = CSLAddString(papszCategoryNames, "Mixed Drift");
1760 papszCategoryNames = CSLAddString(papszCategoryNames, "Talus");
1761 papszCategoryNames = CSLAddString(papszCategoryNames, "Beach");
1762 papszCategoryNames = CSLAddString(papszCategoryNames, "Dunes");
1763 break;
1764
1766 papszCategoryNames = CSLAddString(papszCategoryNames, "None");
1767 papszCategoryNames = CSLAddString(papszCategoryNames, "Structural");
1768 papszCategoryNames = CSLAddString(papszCategoryNames, "Non-Structural");
1769 break;
1770
1771 case (RASTER_PLOT_COAST):
1772 papszCategoryNames = CSLAddString(papszCategoryNames, "Not coastline");
1773 papszCategoryNames = CSLAddString(papszCategoryNames, "Coastline");
1774 break;
1775
1776 // case (RASTER_PLOT_NORMAL_PROFILE):
1777 // papszCategoryNames = CSLAddString(papszCategoryNames, "Not coastline-normal profile");
1778 // papszCategoryNames = CSLAddString(papszCategoryNames, "Coastline-normal profile");
1779 // break;
1780
1782 papszCategoryNames = CSLAddString(papszCategoryNames, "Not in active zone");
1783 papszCategoryNames = CSLAddString(papszCategoryNames, "In active zone");
1784 break;
1785
1786 case (RASTER_PLOT_POLYGON):
1787 papszCategoryNames = CSLAddString(papszCategoryNames, "Not polygon");
1788 papszCategoryNames = CSLAddString(papszCategoryNames, "In polygon");
1789 break;
1790
1792 papszCategoryNames = CSLAddString(papszCategoryNames, "Not in shadow zone");
1793 papszCategoryNames = CSLAddString(papszCategoryNames, "In shadow zone");
1794 break;
1795
1797 papszCategoryNames = CSLAddString(papszCategoryNames, "Not in shadow downdrift zone");
1798 papszCategoryNames = CSLAddString(papszCategoryNames, "In shadow downdrift zone");
1799 break;
1800
1802 papszCategoryNames = CSLAddString(papszCategoryNames, "Updrift movement of unconsolidated sediment ");
1803 papszCategoryNames = CSLAddString(papszCategoryNames, "Downdrift movement of unconsolidated sediment");
1804 break;
1805
1807 papszCategoryNames = CSLAddString(papszCategoryNames, "Inundated by swl setup and surge ");
1808 papszCategoryNames = CSLAddString(papszCategoryNames, "Not inundated by swl setup and surge");
1809 break;
1810
1812 papszCategoryNames = CSLAddString(papszCategoryNames, "Inundated by swl setup, surge and runup ");
1813 papszCategoryNames = CSLAddString(papszCategoryNames, "Not inundated by swl setup, surge and runup");
1814 break;
1815
1817 papszCategoryNames = CSLAddString(papszCategoryNames, "Intersection line of inundation ");
1818 papszCategoryNames = CSLAddString(papszCategoryNames, "Not inundated by swl waves and runup");
1819 break;
1820 }
1821
1822 CPLPushErrorHandler(CPLQuietErrorHandler); // Needed to get next line to fail silently, if it fails
1823 pBand->SetCategoryNames(papszCategoryNames); // Not supported for some GIS formats
1824 CPLPopErrorHandler();
1825
1826 // Now write the data
1827 if (CE_Failure == pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL))
1828 {
1829 // Write error, better error message
1830 cerr << ERR << "cannot write data for " << m_strRasterGISOutFormat << " file named " << strFilePathName << endl << CPLGetLastErrorMsg() << endl;
1831 delete[] pdRaster;
1832 return false;
1833 }
1834
1835 // Calculate statistics for this band
1836 double dMin, dMax, dMean, dStdDev;
1837 CPLPushErrorHandler(CPLQuietErrorHandler); // Needed to get next line to fail silently, if it fails
1838 pBand->ComputeStatistics(false, &dMin, &dMax, &dMean, &dStdDev, NULL, NULL);
1839 CPLPopErrorHandler();
1840
1841 // And then write the statistics
1842 CPLPushErrorHandler(CPLQuietErrorHandler); // Needed to get next line to fail silently, if it fails
1843 pBand->SetStatistics(dMin, dMax, dMean, dStdDev);
1844 CPLPopErrorHandler();
1845
1846 if (! m_bGDALCanCreate)
1847 {
1848 // Since the user-selected raster driver cannot use the Create() method, we have been writing to a dataset created by the in-memory driver. So now we need to use CreateCopy() to copy this in-memory dataset to a file in the user-specified raster driver format
1849 GDALDriver* pOutDriver = GetGDALDriverManager()->GetDriverByName(m_strRasterGISOutFormat.c_str());
1850 GDALDataset* pOutDataSet = pOutDriver->CreateCopy(strFilePathName.c_str(), pDataSet, FALSE, m_papszGDALRasterOptions, NULL, NULL);
1851 if (NULL == pOutDataSet)
1852 {
1853 // Couldn't create file
1854 cerr << ERR << "cannot create " << m_strRasterGISOutFormat << " file named " << strFilePathName << endl
1855 << CPLGetLastErrorMsg() << endl;
1856 return false;
1857 }
1858
1859 // Get rid of this user-selected dataset object
1860 GDALClose(pOutDataSet);
1861 }
1862
1863 // Get rid of dataset object
1864 GDALClose(pDataSet);
1865
1866 // Also get rid of memory allocated to this array
1867 delete[] pdRaster;
1868
1869 return true;
1870}
1871
1872//===============================================================================================================================
1874//===============================================================================================================================
1875int CSimulation::nInterpolateWavesToPolygonCells(vector<double> const* pVdX, vector<double> const* pVdY, vector<double> const* pVdHeightX, vector<double> const* pVdHeightY)
1876{
1877 int nXSize = 0;
1878 int nYSize = 0;
1879
1880 double dXAvg = 0;
1881 double dYAvg = 0;
1882
1885 int nGridSize = nXSize * nYSize;
1886
1887 unsigned int nPoints = static_cast<unsigned int>(pVdX->size());
1888
1889 // // DEBUG CODE ============================================================================================================
1890 // for (int nn = 0; nn < nPoints; nn++)
1891 // {
1892 // LogStream << nn << " " << dX[nn] << " " << dY[nn] << " " << dZ[nn] << endl;
1893 // }
1894 //
1895 // m_nXMaxBoundingBox = m_nXGridSize-1;
1896 // m_nYMaxBoundingBox = m_nYGridSize-1;
1897 // m_nXMinBoundingBox = 0;
1898 // m_nYMinBoundingBox = 0;
1899 // // DEBUG CODE ============================================================================================================
1900
1901 vector<double> VdOutX(nGridSize, 0);
1902 vector<double> VdOutY(nGridSize, 0);
1903
1904 // Do first for X, then for Y
1905 for (int nDirection = 0; nDirection < 2; nDirection++)
1906 {
1907 // Use the GDALGridCreate() linear interpolation algorithm: this computes a Delaunay triangulation of the point cloud, finding in which triangle of the triangulation the point is, and by doing linear interpolation from its barycentric coordinates within the triangle. If the point is not in any triangle, depending on the radius, the algorithm will use the value of the nearest point or the nodata value. Only available in GDAL 2.1 and later TODO 086
1908 GDALGridLinearOptions* pOptions = new GDALGridLinearOptions();
1909 pOptions->dfNoDataValue = m_dMissingValue; // Set the no-data marker to fill empty points
1910 pOptions->dfRadius = -1; // Set the search radius to infinite
1911 pOptions->nSizeOfStructure = sizeof(GDALGridLinearOptions); // Needed for GDAL 3.6 onwards, see https://gdal.org/api/gdal_alg.html#_CPPv421GDALGridLinearOptions
1912
1913 // pOptions.dfRadius = static_cast<double>(nXSize + nYSize) / 2.0; // Set the search radius
1914
1915 // GDALGridNearestNeighborOptions* pOptions = new GDALGridNearestNeighborOptions();
1916 // pOptions->dfNoDataValue = m_dMissingValue; // Set the no-data marker to fill empty points
1917 // pOptions->dfRadius = -1; // Set the search radius to infinite
1918
1919 // Call GDALGridCreate() TODO 086
1920 int nRet;
1921 if (nDirection == 0)
1922 {
1923 nRet = GDALGridCreate(GGA_Linear, pOptions, nPoints, pVdX->data(), pVdY->data(), pVdHeightX->data(), m_nXMinBoundingBox, m_nXMaxBoundingBox, m_nYMinBoundingBox, m_nYMaxBoundingBox, nXSize, nYSize, GDT_Float64, VdOutX.data(), NULL, NULL);
1924 }
1925 else
1926 {
1927 nRet = GDALGridCreate(GGA_Linear, pOptions, nPoints, pVdX->data(), pVdY->data(), pVdHeightY->data(), m_nXMinBoundingBox, m_nXMaxBoundingBox, m_nYMinBoundingBox, m_nYMaxBoundingBox, nXSize, nYSize, GDT_Float64, VdOutY.data(), NULL, NULL);
1928 }
1929
1930 // int nRet;
1931 // if (nDirection == 0)
1932 // {
1933 // nRet = GDALGridCreate(GGA_NearestNeighbor, pOptions, nPoints, pVdX->data(), pVdY->data(), pVdHeightX->data(), m_nXMinBoundingBox, m_nXMaxBoundingBox, m_nYMinBoundingBox, m_nYMaxBoundingBox, nXSize, nYSize, GDT_Float64, VdOutX.data(), NULL, NULL);
1934 // }
1935 // else
1936 // {
1937 // nRet = GDALGridCreate(GGA_NearestNeighbor, pOptions, nPoints, pVdX->data(), pVdY->data(), pVdHeightY->data(), m_nXMinBoundingBox, m_nXMaxBoundingBox, m_nYMinBoundingBox, m_nYMaxBoundingBox, nXSize, nYSize, GDT_Float64, VdOutY.data(), NULL, NULL);
1938 // }
1939
1940 delete pOptions;
1941
1942 if (nRet == CE_Failure)
1943 {
1944 cerr << CPLGetLastErrorMsg() << endl;
1945 return RTN_ERR_GRIDCREATE;
1946 }
1947
1948 if (nDirection == 0)
1949 {
1950 int nXValid = 0;
1951
1952 // Safety check: unfortunately, GDALGridCreate(() outputs NaNs and other crazy values when the polygons are far from regular. So check for these
1953 for (unsigned int n = 0; n < VdOutX.size(); n++)
1954 {
1955 if (isnan(VdOutX[n]))
1956 VdOutX[n] = m_dMissingValue;
1957 else if (tAbs(VdOutX[n]) > 1e10)
1958 VdOutX[n] = m_dMissingValue;
1959 else
1960 {
1961 dXAvg += VdOutX[n];
1962 nXValid++;
1963 }
1964 }
1965
1966 dXAvg /= nXValid;
1967 }
1968 else
1969 {
1970 int nYValid = 0;
1971
1972 // Safety check: unfortunately, GDALGridCreate(() outputs NaNs and other crazy values when the polygon are far from regular. So check for these
1973 for (unsigned int n = 0; n < VdOutY.size(); n++)
1974 {
1975 if (isnan(VdOutY[n]))
1976 VdOutY[n] = m_dMissingValue;
1977 else if (tAbs(VdOutY[n]) > 1e10)
1978 VdOutY[n] = m_dMissingValue;
1979 else
1980 {
1981 dYAvg += VdOutY[n];
1982 nYValid++;
1983 }
1984 }
1985
1986 dYAvg /= nYValid;
1987 }
1988
1989 // // DEBUG CODE ===========================================================================================================
1990 // string strOutFile = m_strOutPath;
1991 // strOutFile += "sea_wave_interpolation_";
1992 // if (nDirection == 0)
1993 // strOutFile += "X_";
1994 // else
1995 // strOutFile += "Y_";
1996 // strOutFile += to_string(m_ulIter);
1997 // strOutFile += ".tif";
1998 //
1999 // GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("gtiff");
2000 // GDALDataset* pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
2001 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
2002 // pDataSet->SetGeoTransform(m_dGeoTransform);
2003 // double* pdRaster = new double[m_nXGridSize * m_nYGridSize];
2004 // int m = 0;
2005 // int n = 0;
2006 // for (int nY = 0; nY < m_nYGridSize; nY++)
2007 // {
2008 // for (int nX = 0; nX < m_nXGridSize; nX++)
2009 // {
2010 // if ((nX < m_nXMinBoundingBox) || (nY < m_nYMinBoundingBox))
2011 // {
2012 // pdRaster[n++] = DBL_NODATA;
2013 // }
2014 // else
2015 // {
2016 // // Write this value to the array
2017 // if (nDirection == 0)
2018 // {
2019 // if (m < static_cast<int>(VdOutX.size()))
2020 // {
2021 // pdRaster[n++] = VdOutX[m++];
2022 // // LogStream << "nDirection = " << nDirection << " [" << nX << "][" << nY << "] = " << VpdOutX[n] << endl;
2023 // }
2024 // }
2025 // else
2026 // {
2027 // if (m < static_cast<int>(VdOutY.size()))
2028 // {
2029 // pdRaster[n++] = VdOutY[m++];
2030 // // LogStream << "nDirection = " << nDirection << " [" << nX << "][" << nY << "] = " << VpdOutY[n] << endl;
2031 // }
2032 // }
2033 // }
2034 // }
2035 // }
2036 //
2037 // GDALRasterBand* pBand = pDataSet->GetRasterBand(1);
2038 // pBand->SetNoDataValue(m_dMissingValue);
2039 // nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
2040 //
2041 // if (nRet == CE_Failure)
2042 // return RTN_ERR_GRIDCREATE;
2043 //
2044 // GDALClose(pDataSet);
2045 // delete[] pdRaster;
2046 // // DEBUG CODE ===========================================================================================================
2047 }
2048
2049 // // DEBUG CODE ===========================================================================================================
2050 // string strOutFile = m_strOutPath;
2051 // strOutFile += "sea_wave_height_before_";
2052 // strOutFile += to_string(m_ulIter);
2053 // strOutFile += ".tif";
2054 //
2055 // GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("gtiff");
2056 // GDALDataset* pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
2057 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
2058 // pDataSet->SetGeoTransform(m_dGeoTransform);
2059 //
2060 // int nn = 0;
2061 // double* pdRaster = new double[m_nXGridSize * m_nYGridSize];
2062 // for (int nY = 0; nY < m_nYGridSize; nY++)
2063 // {
2064 // for (int nX = 0; nX < m_nXGridSize; nX++)
2065 // {
2066 // pdRaster[nn++] = m_pRasterGrid->m_Cell[nX][nY].dGetWaveHeight();
2067 // }
2068 // }
2069 //
2070 // GDALRasterBand* pBand = pDataSet->GetRasterBand(1);
2071 // pBand->SetNoDataValue(m_dMissingValue);
2072 // int nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
2073 //
2074 // if (nRet == CE_Failure)
2075 // return RTN_ERR_GRIDCREATE;
2076 //
2077 // GDALClose(pDataSet);
2078 // delete[] pdRaster;
2079 // // DEBUG CODE ===========================================================================================================
2080
2081 // // DEBUG CODE ===========================================================================================================
2082 // strOutFile = m_strOutPath;
2083 // strOutFile += "sea_wave_angle_before_";
2084 // strOutFile += to_string(m_ulIter);
2085 // strOutFile += ".tif";
2086 //
2087 // pDriver = GetGDALDriverManager()->GetDriverByName("gtiff");
2088 // pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
2089 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
2090 // pDataSet->SetGeoTransform(m_dGeoTransform);
2091 //
2092 // nn = 0;
2093 // pdRaster = new double[m_nXGridSize * m_nYGridSize];
2094 // for (int nY = 0; nY < m_nYGridSize; nY++)
2095 // {
2096 // for (int nX = 0; nX < m_nXGridSize; nX++)
2097 // {
2098 // pdRaster[nn++] = m_pRasterGrid->m_Cell[nX][nY].dGetWaveAngle();
2099 // }
2100 // }
2101 //
2102 // pBand = pDataSet->GetRasterBand(1);
2103 // pBand->SetNoDataValue(m_dMissingValue);
2104 // nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
2105 //
2106 // if (nRet == CE_Failure)
2107 // return RTN_ERR_GRIDCREATE;
2108 //
2109 // GDALClose(pDataSet);
2110 // delete[] pdRaster;
2111 // // DEBUG CODE ===========================================================================================================
2112
2113 // Now put the X and Y directions together and update the raster cells
2114 int n = 0;
2115 for (int nY = 0; nY < nYSize; nY++)
2116 {
2117 for (int nX = 0; nX < nXSize; nX++)
2118 {
2119 int nActualX = nX + m_nXMinBoundingBox;
2120 int nActualY = nY + m_nYMinBoundingBox;
2121
2122 if (m_pRasterGrid->m_Cell[nActualX][nActualY].bIsInContiguousSea())
2123 {
2124 // Only update sea cells
2125 if (m_pRasterGrid->m_Cell[nActualX][nActualY].nGetPolygonID() == INT_NODATA)
2126 {
2127 // This is a deep water sea cell (not in a polygon)
2128 double dDeepWaterWaveHeight = m_pRasterGrid->m_Cell[nActualX][nActualY].dGetCellDeepWaterWaveHeight();
2129 m_pRasterGrid->m_Cell[nActualX][nActualY].SetWaveHeight(dDeepWaterWaveHeight);
2130
2131 double dDeepWaterWaveAngle = m_pRasterGrid->m_Cell[nActualX][nActualY].dGetCellDeepWaterWaveAngle();
2132 m_pRasterGrid->m_Cell[nActualX][nActualY].SetWaveAngle(dDeepWaterWaveAngle);
2133 }
2134 else
2135 {
2136 // This is in a polygon so is not a deep water sea cell
2137 double dWaveHeightX;
2138 double dWaveHeightY;
2139
2140 // Safety checks
2141 if ((isnan(VdOutX[n])) || (bFPIsEqual(VdOutX[n], m_dMissingValue, TOLERANCE)))
2142 dWaveHeightX = dXAvg;
2143 else
2144 dWaveHeightX = VdOutX[n];
2145
2146 if ((isnan(VdOutY[n])) || (bFPIsEqual(VdOutY[n], m_dMissingValue, TOLERANCE)))
2147 dWaveHeightY = dYAvg;
2148 else
2149 dWaveHeightY = VdOutY[n];
2150
2151 // Now calculate wave direction
2152 double dWaveHeight = sqrt((dWaveHeightX * dWaveHeightX) + (dWaveHeightY * dWaveHeightY));
2153 double dWaveDir = atan2(dWaveHeightX, dWaveHeightY) * (180 / PI);
2154
2155// assert(isfinite(dWaveHeight));
2156// assert(isfinite(dWaveDir));
2157
2158 // Update the cell's wave attributes
2159 m_pRasterGrid->m_Cell[nActualX][nActualY].SetWaveHeight(dWaveHeight);
2160 m_pRasterGrid->m_Cell[nActualX][nActualY].SetWaveAngle(dKeepWithin360(dWaveDir));
2161
2162 // Calculate the wave height-to-depth ratio for this cell, then update the cell's active zone status
2163 double dSeaDepth = m_pRasterGrid->m_Cell[nActualX][nActualY].dGetSeaDepth();
2164 if ((dWaveHeight / dSeaDepth) >= m_dBreakingWaveHeightDepthRatio)
2165 m_pRasterGrid->m_Cell[nActualX][nActualY].SetInActiveZone(true);
2166
2167 // LogStream << " nX = " << nX << " nY = " << nY << " [" << nActualX << "][" << nActualY << "] waveheight = " << dWaveHeight << " dWaveDir = " << dWaveDir << " dKeepWithin360(dWaveDir) = " << dKeepWithin360(dWaveDir) << endl;
2168 }
2169 }
2170 // Increment with safety check
2171 n++;
2172 n = tMin(n, static_cast<int>(VdOutX.size()-1));
2173 }
2174 }
2175
2176 // // DEBUG CODE ===========================================================================================================
2177 // strOutFile = m_strOutPath;
2178 // strOutFile += "sea_wave_height_after_";
2179 // strOutFile += to_string(m_ulIter);
2180 // strOutFile += ".tif";
2181 //
2182 // pDriver = GetGDALDriverManager()->GetDriverByName("gtiff");
2183 // pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
2184 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
2185 // pDataSet->SetGeoTransform(m_dGeoTransform);
2186 //
2187 // nn = 0;
2188 // pdRaster = new double[m_nXGridSize * m_nYGridSize];
2189 // for (int nY = 0; nY < m_nYGridSize; nY++)
2190 // {
2191 // for (int nX = 0; nX < m_nXGridSize; nX++)
2192 // {
2193 // pdRaster[nn++] = m_pRasterGrid->m_Cell[nX][nY].dGetWaveHeight();
2194 // }
2195 // }
2196 //
2197 // pBand = pDataSet->GetRasterBand(1);
2198 // pBand->SetNoDataValue(m_dMissingValue);
2199 // nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
2200 //
2201 // if (nRet == CE_Failure)
2202 // return RTN_ERR_GRIDCREATE;
2203 //
2204 // GDALClose(pDataSet);
2205 // delete[] pdRaster;
2206 // // DEBUG CODE ===========================================================================================================
2207
2208 // // DEBUG CODE ===========================================================================================================
2209 // strOutFile = m_strOutPath;
2210 // strOutFile += "sea_wave_angle_after_";
2211 // strOutFile += to_string(m_ulIter);
2212 // strOutFile += ".tif";
2213 //
2214 // pDriver = GetGDALDriverManager()->GetDriverByName("gtiff");
2215 // pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
2216 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
2217 // pDataSet->SetGeoTransform(m_dGeoTransform);
2218 //
2219 // nn = 0;
2220 // pdRaster = new double[m_nXGridSize * m_nYGridSize];
2221 // for (int nY = 0; nY < m_nYGridSize; nY++)
2222 // {
2223 // for (int nX = 0; nX < m_nXGridSize; nX++)
2224 // {
2225 // pdRaster[nn++] = m_pRasterGrid->m_Cell[nX][nY].dGetWaveAngle();
2226 // }
2227 // }
2228 //
2229 // pBand = pDataSet->GetRasterBand(1);
2230 // pBand->SetNoDataValue(m_dMissingValue);
2231 // nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
2232 //
2233 // if (nRet == CE_Failure)
2234 // return RTN_ERR_GRIDCREATE;
2235 //
2236 // GDALClose(pDataSet);
2237 // delete[] pdRaster;
2238 // // DEBUG CODE ===========================================================================================================
2239
2240 return RTN_OK;
2241}
2242
2243//===============================================================================================================================
2245//===============================================================================================================================
2247{
2248 // Interpolate deep water height and orientation from multiple user-supplied values
2249 unsigned int nUserPoints = static_cast<unsigned int>(m_VdDeepWaterWaveStationX.size());
2250
2251 // Call GDALGridCreate() with the GGA_InverseDistanceToAPower interpolation algorithm. It has following parameters: radius1 is the first radius (X axis if rotation angle is 0) of the search ellipse, set this to zero (the default) to use the whole point array; radius2 is the second radius (Y axis if rotation angle is 0) of the search ellipse, again set this parameter to zero (the default) to use the whole point array; angle is the angle of the search ellipse rotation in degrees (counter clockwise, default 0.0); nodata is the NODATA marker to fill empty points (default 0.0) TODO 086
2252 GDALGridInverseDistanceToAPowerOptions* pOptions = new GDALGridInverseDistanceToAPowerOptions();
2253 pOptions->dfAngle = 0;
2254 pOptions->dfAnisotropyAngle = 0;
2255 pOptions->dfAnisotropyRatio = 0;
2256 pOptions->dfPower = 3;
2257 pOptions->dfSmoothing = 100;
2258 pOptions->dfRadius1 = 0;
2259 pOptions->dfRadius2 = 0;
2260 pOptions->nMaxPoints = 0;
2261 pOptions->nMinPoints = 0;
2262 pOptions->dfNoDataValue = m_nMissingValue;
2263
2264 // CPLSetConfigOption("CPL_DEBUG", "ON");
2265 // CPLSetConfigOption("GDAL_NUM_THREADS", "1");
2266
2267 // OK, now create a gridded version of wave height: first create the GDAL context TODO 086
2268 // GDALGridContext* pContext = GDALGridContextCreate(GGA_InverseDistanceToAPower, pOptions, nUserPoints, &m_VdDeepWaterWaveStationX[0], &m_VdDeepWaterWaveStationY[0], &m_VdThisIterDeepWaterWaveStationHeight[0], true);
2269 GDALGridContext* pContext = GDALGridContextCreate(GGA_InverseDistanceToAPower, pOptions, nUserPoints, m_VdDeepWaterWaveStationX.data(), m_VdDeepWaterWaveStationY.data(), m_VdThisIterDeepWaterWaveStationHeight.data(), true);
2270
2271 if (pContext == NULL)
2272 {
2273 delete pOptions;
2274 return RTN_ERR_GRIDCREATE;
2275 }
2276
2277 // Now process the context
2278 double *dHeightOut = new double[m_ulNumCells];
2279 int nRet = GDALGridContextProcess(pContext, 0, m_nXGridSize - 1, 0, m_nYGridSize - 1, m_nXGridSize, m_nYGridSize, GDT_Float64, dHeightOut, NULL, NULL);
2280 if (nRet == CE_Failure)
2281 {
2282 delete[] dHeightOut;
2283 delete pOptions;
2284 return RTN_ERR_GRIDCREATE;
2285 }
2286
2287 // Get rid of the context
2288 GDALGridContextFree(pContext);
2289
2290 // Next create a gridded version of wave orientation: first create the GDAL context
2291 // pContext = GDALGridContextCreate(GGA_InverseDistanceToAPower, pOptions, nUserPoints, &(m_VdDeepWaterWaveStationX[0]), &(m_VdDeepWaterWaveStationY[0]), (&m_VdThisIterDeepWaterWaveStationAngle[0]), true);
2292 pContext = GDALGridContextCreate(GGA_InverseDistanceToAPower, pOptions, nUserPoints, m_VdDeepWaterWaveStationX.data(), m_VdDeepWaterWaveStationY.data(), m_VdThisIterDeepWaterWaveStationAngle.data(), true);
2293 if (pContext == NULL)
2294 {
2295 delete[] dHeightOut;
2296 delete pOptions;
2297 return RTN_ERR_GRIDCREATE;
2298 }
2299
2300 // Now process the context TODO 086
2301 double *dAngleOut = new double[m_ulNumCells];
2302 nRet = GDALGridContextProcess(pContext, 0, m_nXGridSize - 1, 0, m_nYGridSize - 1, m_nXGridSize, m_nYGridSize, GDT_Float64, dAngleOut, NULL, NULL);
2303 if (nRet == CE_Failure)
2304 {
2305 delete[] dHeightOut;
2306 delete[] dAngleOut;
2307 delete pOptions;
2308 return RTN_ERR_GRIDCREATE;
2309 }
2310
2311 // Get rid of the context
2312 GDALGridContextFree(pContext);
2313
2314 // OK, now create a gridded version of wave period: first create the GDAL context
2315 // pContext = GDALGridContextCreate(GGA_InverseDistanceToAPower, pOptions, nUserPoints, &m_VdDeepWaterWaveStationX[0], &m_VdDeepWaterWaveStationY[0], &m_VdThisIterDeepWaterWaveStationPeriod[0], true);
2316 pContext = GDALGridContextCreate(GGA_InverseDistanceToAPower, pOptions, nUserPoints, m_VdDeepWaterWaveStationX.data(), m_VdDeepWaterWaveStationY.data(), m_VdThisIterDeepWaterWaveStationPeriod.data(), true);
2317 if (pContext == NULL)
2318 {
2319 delete pOptions;
2320 return RTN_ERR_GRIDCREATE;
2321 }
2322
2323 // Now process the context TODO 086
2324 double *dPeriopdOut = new double[m_ulNumCells];
2325 nRet = GDALGridContextProcess(pContext, 0, m_nXGridSize - 1, 0, m_nYGridSize - 1, m_nXGridSize, m_nYGridSize, GDT_Float64, dPeriopdOut, NULL, NULL);
2326 if (nRet == CE_Failure)
2327 {
2328 delete[] dPeriopdOut;
2329 delete pOptions;
2330 return RTN_ERR_GRIDCREATE;
2331 }
2332
2333 // Get rid of the context
2334 GDALGridContextFree(pContext);
2335
2336 // The output from GDALGridCreate() is in dHeightOut, dAngleOut and dPeriopdOut but must be reversed
2337 vector<double>
2338 VdHeight,
2339 VdAngle,
2340 VdPeriod;
2341
2342 int
2343 n = 0,
2344 nValidHeight = 0,
2345 nValidAngle = 0,
2346 nValidPeriod = 0;
2347
2348 double
2349 dAvgHeight = 0,
2350 dAvgAngle = 0,
2351 dAvgPeriod = 0;
2352
2353 for (int nY = m_nYGridSize - 1; nY >= 0; nY--)
2354 {
2355 for (int nX = 0; nX < m_nXGridSize; nX++)
2356 {
2357 if (isfinite(dHeightOut[n]))
2358 {
2359 VdHeight.push_back(dHeightOut[n]);
2360
2361 dAvgHeight += dHeightOut[n];
2362 nValidHeight++;
2363 }
2364 else
2365 {
2366 VdHeight.push_back(m_dMissingValue);
2367 }
2368
2369 if (isfinite(dAngleOut[n]))
2370 {
2371 VdAngle.push_back(dAngleOut[n]);
2372
2373 dAvgAngle += dAngleOut[n];
2374 nValidAngle++;
2375 }
2376 else
2377 {
2378 VdAngle.push_back(m_dMissingValue);
2379 }
2380
2381 if (isfinite(dPeriopdOut[n]))
2382 {
2383 VdPeriod.push_back(dPeriopdOut[n]);
2384
2385 dAvgPeriod += dPeriopdOut[n];
2386 nValidPeriod++;
2387 }
2388 else
2389 {
2390 VdPeriod.push_back(m_dMissingValue);
2391 }
2392
2393 // LogStream << " nX = " << nX << " nY = " << nY << " n = " << n << " dHeightOut[n] = " << dHeightOut[n] << " dAngleOut[n] = " << dAngleOut[n] << endl;
2394 n++;
2395 }
2396 }
2397
2398 // Calculate averages
2399 dAvgHeight /= nValidHeight;
2400 dAvgAngle /= nValidAngle;
2401 dAvgPeriod /= nValidPeriod;
2402
2403 // Tidy
2404 delete pOptions;
2405 delete[] dHeightOut;
2406 delete[] dAngleOut;
2407 delete[] dPeriopdOut;
2408
2409 // Now update all raster cells
2410 n = 0;
2411 for (int nY = 0; nY < m_nYGridSize; nY++)
2412 {
2413 for (int nX = 0; nX < m_nXGridSize; nX++)
2414 {
2415 if (bFPIsEqual(VdHeight[n], m_dMissingValue, TOLERANCE))
2416 m_pRasterGrid->m_Cell[nX][nY].SetCellDeepWaterWaveHeight(dAvgHeight);
2417 else
2418 m_pRasterGrid->m_Cell[nX][nY].SetCellDeepWaterWaveHeight(VdHeight[n]);
2419
2420 if (bFPIsEqual(VdAngle[n], m_dMissingValue, TOLERANCE))
2421 m_pRasterGrid->m_Cell[nX][nY].SetCellDeepWaterWaveAngle(dAvgAngle);
2422 else
2423 m_pRasterGrid->m_Cell[nX][nY].SetCellDeepWaterWaveAngle(VdAngle[n]);
2424
2425 if (bFPIsEqual(VdPeriod[n], m_dMissingValue, TOLERANCE))
2426 m_pRasterGrid->m_Cell[nX][nY].SetCellDeepWaterWavePeriod(dAvgPeriod);
2427 else
2428 m_pRasterGrid->m_Cell[nX][nY].SetCellDeepWaterWavePeriod(VdPeriod[n]);
2429
2430 // LogStream << " [" << nX << "][" << nY << "] deep water wave height = " << m_pRasterGrid->m_Cell[nX][nY].dGetCellDeepWaterWaveHeight() << " deep water wave angle = " << m_pRasterGrid->m_Cell[nX][nY].dGetCellDeepWaterWaveAngle() << endl;
2431 n++;
2432 }
2433 }
2434
2435 // // DEBUG CODE ===========================================================================================================
2436 // string strOutFile = m_strOutPath;
2437 // strOutFile += "init_deep_water_wave_height_";
2438 // strOutFile += to_string(m_ulIter);
2439 // strOutFile += ".tif";
2440 // GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("gtiff");
2441 // GDALDataset* pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
2442 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
2443 // pDataSet->SetGeoTransform(m_dGeoTransform);
2444 // double* pdRaster = new double[m_ulNumCells];
2445 // int nn = 0;
2446 // for (int nY = 0; nY < m_nYGridSize; nY++)
2447 // {
2448 // for (int nX = 0; nX < m_nXGridSize; nX++)
2449 // {
2450 // // Write this value to the array
2451 // pdRaster[nn] = m_pRasterGrid->m_Cell[nX][nY].dGetCellDeepWaterWaveHeight();
2452 // nn++;
2453 // }
2454 // }
2455 //
2456 // GDALRasterBand* pBand = pDataSet->GetRasterBand(1);
2457 // pBand->SetNoDataValue(m_nMissingValue);
2458 // nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
2459 //
2460 // if (nRet == CE_Failure)
2461 // return RTN_ERR_GRIDCREATE;
2462 //
2463 // GDALClose(pDataSet);
2464 // // DEBUG CODE ===========================================================================================================
2465
2466 // // DEBUG CODE ===========================================================================================================
2467 // strOutFile = m_strOutPath;
2468 // strOutFile += "init_deep_water_wave_angle_";
2469 // strOutFile += to_string(m_ulIter);
2470 // strOutFile += ".tif";
2471 // pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
2472 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
2473 // pDataSet->SetGeoTransform(m_dGeoTransform);
2474 // nn = 0;
2475 // for (int nY = 0; nY < m_nYGridSize; nY++)
2476 // {
2477 // for (int nX = 0; nX < m_nXGridSize; nX++)
2478 // {
2479 // // Write this value to the array
2480 // pdRaster[nn] = m_pRasterGrid->m_Cell[nX][nY].dGetCellDeepWaterWaveAngle();
2481 // nn++;
2482 // }
2483 // }
2484 //
2485 // pBand = pDataSet->GetRasterBand(1);
2486 // pBand->SetNoDataValue(m_nMissingValue);
2487 // nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
2488 //
2489 // if (nRet == CE_Failure)
2490 // return RTN_ERR_GRIDCREATE;
2491 //
2492 // GDALClose(pDataSet);
2493 // delete[] pdRaster;
2494 // // DEBUG CODE ===========================================================================================================
2495
2496 return RTN_OK;
2497}
Geometry class used to represent 2D point objects with integer coordinates.
Definition 2di_point.h:29
int m_nLogFileDetail
The level of detail in the log file output. Can be LOG_FILE_LOW_DETAIL, LOG_FILE_MIDDLE_DETAIL,...
Definition simulation.h:531
string m_strGDALISSDriverCode
GDAL code for the initial suspended sediment raster file.
vector< string > m_VstrInitialSandConsSedimentFile
The name of the initial sand-sized consolidated sediment GIS file.
bool bWriteRasterGISFile(int const, string const *, int const =0, double const =0)
Writes GIS raster files using GDAL, using data from the RasterGrid array.
int m_nGISMaxSaveDigits
The maximum number of digits in GIS filenames. These can be sequential, or the iteration number.
Definition simulation.h:459
int m_nYMinBoundingBox
The minimum y value of the bounding box.
Definition simulation.h:501
string m_strGDALISSProjection
GDAL projection string for the initial suspended sediment raster file.
string m_strInitialSuspSedimentFile
Name of initial suspended sediment file.
void GetRasterOutputMinMax(int const, double &, double &, int const, double const)
Finds the max and min values in order to scale raster output if we cannot write doubles.
vector< string > m_VstrInitialCoarseUnconsSedimentFile
The name of the initial coarse-sized unconsolidated sediment GIS file.
double m_dThisIterSWL
The still water level for this timestep (this includes tidal changes and any long-term SWL change)
Definition simulation.h:668
string m_strGDALICDataType
GDAL data type of the initial intervention class raster file.
CGeomRasterGrid * m_pRasterGrid
Pointer to the raster grid object.
vector< string > m_VstrGDALICCDataType
GDAL data type for the initial consolidated coarse sediment GIS data.
int m_nXGridSize
The size of the grid in the x direction.
Definition simulation.h:429
vector< double > m_VdDeepWaterWaveStationY
Y coordinate (grid CRS) for deep water wave station.
vector< string > m_VstrGDALICFDataType
GDAL data type for the initial consolidated fine sediment GIS data.
ofstream LogStream
vector< string > m_VstrGDALICCDriverCode
GDAL driver code for the initial consolidated coarse sediment GIS data.
int nReadRasterGISFile(int const, int const)
Reads all other raster GIS datafiles into the RasterGrid array.
vector< string > m_VstrGDALIUFDataType
GDAL data type for the initial unconsolidated fine sediment GIS data.
long m_lGDALMaxCanWrite
The maximum integer value which GDAL can write, can be UINT8_MAX, INT16_MAX, UINT16_MAX,...
Definition simulation.h:548
double m_dSouthEastXExtCRS
The south-east x coordinate, in the external coordinate reference system (CRS)
Definition simulation.h:605
int m_nMissingValue
The value used for integer missing values.
Definition simulation.h:492
int m_nYGridSize
The size of the grid in the y direction.
Definition simulation.h:432
vector< string > m_VstrGDALIUFProjection
GDAL projection for the initial unconsolidated fine sediment GIS data.
double m_dGeoTransform[6]
GDAL geotransformation info (see http://www.gdal.org/classGDALDataset.html)
Definition simulation.h:653
vector< string > m_VstrGDALICFDriverCode
GDAL driver code for the initial consolidated fine sediment GIS data.
vector< string > m_VstrInitialFineConsSedimentFile
The name of the initial fine-sized consolidated sediment GIS file.
double m_dMissingValue
Missing value.
Definition simulation.h:914
double m_dInvCellDiagonal
Inverse of m_dCellDiagonal.
Definition simulation.h:626
string m_strGDALLDriverCode
GDAL code for the for the initial landform class raster file.
static double dKeepWithin360(double const)
Constrains the supplied angle to be within 0 and 360 degrees.
vector< string > m_VstrGDALICSDriverCode
GDAL driver code for the initial consolidated sand sediment GIS data.
unsigned long m_ulNumCells
The number of cells in the grid.
Definition simulation.h:563
string m_strGDALISSDataType
GDAL data type for the initial suspended sediment raster file.
vector< string > m_VstrGDALIUCProjection
GDAL projection for the initial unconsolidated coarse sediment GIS data.
bool m_bGDALCanCreate
Is the selected GDAL output file format capable of writing files?
Definition simulation.h:345
string m_strGDALLDataType
GDAL data type for the initial landform class raster file.
string m_strRasterGISOutFormat
Base name for CME raster GIS output files.
int m_nXMaxBoundingBox
The maximum x value of the bounding box.
Definition simulation.h:498
double m_dNorthWestYExtCRS
The north-west y coordinate, in the external coordinate reference system (CRS)
Definition simulation.h:602
vector< string > m_VstrGDALICSDriverDesc
GDAL driver description for the initial consolidated sand sediment GIS data.
static string strToLower(string const *)
Returns the lower case version of an string, leaving the original unchanged.
Definition utils.cpp:2219
int nInterpolateWavesToPolygonCells(vector< double > const *, vector< double > const *, vector< double > const *, vector< double > const *)
Interpolates wave properties from all profiles to all within-polygon sea cells, using GDALGridCreate(...
vector< double > m_VdThisIterDeepWaterWaveStationHeight
This-iteration wave height at deep water wave station.
string m_strGDALBasementDEMDriverCode
GDAL code for the basement DEM raster file type.
vector< string > m_VstrGDALIUFDriverCode
GDAL driver code for the initial unconsolidated fine sediment GIS data.
unsigned long m_ulMissingValueBasementCells
The number of basement cells marked with as missing value.
Definition simulation.h:593
string m_strInitialBasementDEMFile
Name of initial basement DEM file.
vector< double > m_VdDeepWaterWaveStationX
X coordinate (grid CRS) for deep water wave station.
double m_dBreakingWaveHeightDepthRatio
Breaking wave height-to-depth ratio.
Definition simulation.h:707
string m_strGDALLProjection
GDAL projection string for the initial landform class raster file.
vector< string > m_VstrInitialSandUnconsSedimentFile
The name of the initial sand-sized unconsolidated sediment GIS file.
string m_strGDALIHProjection
GDAL projection string for the initial intervention height raster file.
string m_strGDALICDriverDesc
GDAL description of the initial intervention class raster file.
vector< string > m_VstrGDALIUSProjection
GDAL projection for the initial unconsolidated sand sediment GIS data.
vector< double > m_VdThisIterDeepWaterWaveStationPeriod
This-iteration wave period at deep water wave station.
double m_dCellDiagonal
Length of a cell's diagonal (in external CRS units)
Definition simulation.h:620
double m_dInvCellSide
Inverse of m_dCellSide.
Definition simulation.h:623
vector< string > m_VstrGDALICFProjection
GDAL projection for the initial consolidated fine sediment GIS data.
double m_dSimElapsed
Time simulated so far, in hours.
Definition simulation.h:635
vector< string > m_VstrGDALICCProjection
GDAL projection for the initial consolidated coarse sediment GIS data.
string m_strGDALLDriverDesc
GDAL description of the initial landform class raster file.
double m_dNorthWestXExtCRS
The north-west x coordinate, in the external coordinate reference system (CRS)
Definition simulation.h:599
vector< CGeom2DIPoint > m_VEdgeCell
Edge cells.
int nInterpolateAllDeepWaterWaveValues(void)
If the user supplies multiple deep water wave height and angle values, this routine interplates these...
double m_dSouthEastYExtCRS
The south-east y coordinate, in the external coordinate reference system (CRS)
Definition simulation.h:608
bool m_bGISSaveDigitsSequential
Are the GIS save digits (which are part of each GIS file name) sequential, or are they the iteration ...
Definition simulation.h:420
vector< string > m_VstrGDALIUSDriverDesc
GDAL driver description for the initial unconsolidated sand sediment GIS data.
vector< string > m_VstrInitialFineUnconsSedimentFile
The name of the initial fine-sized unconsolidated sediment GIS file.
string m_strOutPath
Path for all output files.
int m_nYMaxBoundingBox
The maximum y value of the bounding box.
Definition simulation.h:504
vector< string > m_VstrGDALICFDriverDesc
GDAL driver description for the initial consolidated fine sediment GIS data.
vector< string > m_VstrGDALIUFDriverDesc
GDAL driver description for the initial unconsolidated fine sediment GIS data.
vector< string > m_VstrGDALIUSDataType
GDAL data type for the initial unconsolidated sand sediment GIS data.
int m_nGISSave
The save number for GIS files (can be sequential, or the iteration number)
Definition simulation.h:462
string m_strInterventionClassFile
Name of intervention class file.
string m_strGDALBasementDEMDataType
GDAL data type for the basement DEM raster file.
string m_strGDALICProjection
GDAL projection string for the initial intervention class raster file.
long m_lGDALMinCanWrite
The minimum integer value which GDAL can write, can be zero, INT16_MIN, INT32_MIN.
Definition simulation.h:551
string m_strGDALISSDriverDesc
GDAL description for the initial suspended sediment raster file.
double m_dTimeStep
The length of an iteration (a time step) in hours.
Definition simulation.h:632
static void AnnounceAllocateMemory(void)
Tells the user that we are now allocating memory.
Definition utils.cpp:390
int m_nXMinBoundingBox
The minimum x value of the bounding box.
Definition simulation.h:495
vector< string > m_VstrGDALIUCDriverCode
GDAL driver code for the initial unconsolidated coarse sediment GIS data.
double m_dCellArea
Area of a cell (in external CRS units)
Definition simulation.h:617
static string strDispTime(double const, bool const, bool const)
strDispTime returns a string formatted as h:mm:ss, given a parameter in seconds, with rounding and fr...
Definition utils.cpp:1522
string m_strGDALBasementDEMDriverDesc
GDAL description of the basement DEM raster file type.
string m_strInitialLandformFile
Name of initial landform file.
string m_strInterventionHeightFile
Name of intervention height file.
vector< string > m_VstrGDALICSDataType
GDAL data type for the initial consolidated sand sediment GIS data.
bool m_bScaleRasterOutput
Scale raster output?
Definition simulation.h:354
vector< string > m_VstrGDALICSProjection
GDAL dprojection for the initial consolidated sand sediment GIS data.
string m_strGDALRasterOutputDriverExtension
GDAL raster output driver file extension.
string m_strGDALBasementDEMProjection
GDAL projection string for the basement DEM raster file.
unsigned long m_ulIter
The number of the current iteration (time step)
Definition simulation.h:554
vector< string > m_VstrInitialCoarseConsSedimentFile
The name of the initial coarse-sized consolidated sediment GIS file.
int nReadRasterBasementDEM(void)
Reads a raster DEM of basement elevation data to the Cell array.
string m_strGDALIHDriverCode
GDAL code for the initial intervention height raster file.
string m_strGDALICDriverCode
GDAL code for the initial intervention class raster file.
double m_dExtCRSGridArea
The area of the grid (in external CRS units)
Definition simulation.h:611
vector< double > m_VdThisIterDeepWaterWaveStationAngle
This-iteration wave orientation at deep water wave station.
double m_dCellSide
Length of a cell side (in external CRS units)
Definition simulation.h:614
vector< string > m_VstrGDALIUCDriverDesc
GDAL driver description for the initial unconsolidated coarse sediment GIS data.
int nMarkBoundingBoxEdgeCells(void)
Mark cells which are at the edge of a bounding box which represents the valid part of the grid,...
string m_strGDALIHDriverDesc
GDAL description for the initial intervention height raster file.
vector< string > m_VstrGDALICCDriverDesc
GDAL driver decription for the initial consolidated coarse sediment GIS data.
string m_strGDALIHDataType
GDAL data type for the initial intervention height raster file.
vector< string > m_VstrGDALIUCDataType
GDAL data type for the initial unconsolidated coarse sediment GIS data.
GDALDataType m_GDALWriteFloatDataType
Thw data type used by GDAL for floating point operations, can be GDT_Byte, GDT_Int16,...
Definition simulation.h:545
bool m_bGDALCanWriteFloat
Is the selected GDAL output file format capable of writing floating-point values to files?
Definition simulation.h:348
char ** m_papszGDALRasterOptions
Options for GDAL when handling raster files.
Definition simulation.h:423
vector< string > m_VstrGDALIUSDriverCode
GDAL driver code for the initial unconsolidated sand sediment GIS data.
vector< int > m_VEdgeCellEdge
The grid edge that each edge cell belongs to.
vector< CGeomCoastPolygon * > m_pVCoastPolygon
Pointers to coast polygon objects, in down-coast sequence TODO 044 Will need to use global polygon ID...
This file contains global definitions for CoastalME.
int const NO_NONZERO_THICKNESS_LAYERS
Definition cme.h:655
int const INT_NODATA
Definition cme.h:365
int const RASTER_PLOT_POLYGON
Definition cme.h:524
string const RASTER_SEA_DEPTH_NAME
Definition cme.h:828
T tMin(T a, T b)
Definition cme.h:1138
double const TOLERANCE
Definition cme.h:699
string const RASTER_SHADOW_DOWNDRIFT_ZONE_NAME
Definition cme.h:924
string const RASTER_POTENTIAL_BEACH_EROSION_NAME
Definition cme.h:858
string const RASTER_BEACH_MASK_NAME
Definition cme.h:844
string const RASTER_TOTAL_CLIFF_COLLAPSE_DEPOSITION_SAND_NAME
Definition cme.h:914
string const RASTER_POLYGON_UPDRIFT_OR_DOWNDRIFT_NAME
Definition cme.h:932
int const RASTER_PLOT_LOCAL_SLOPE_OF_CONSOLIDATED_SEDIMENT
Definition cme.h:521
int const RASTER_PLOT_TOTAL_ACTUAL_BEACH_EROSION
Definition cme.h:537
int const RASTER_PLOT_CLIFF_COLLAPSE_DEPOSITION_SAND
Definition cme.h:507
int const RASTER_PLOT_BEACH_DEPOSITION
Definition cme.h:501
int const RASTER_PLOT_SUSPENDED_SEDIMENT
Definition cme.h:536
string const RASTER_FINE_CONS_NAME
Definition cme.h:886
string const RASTER_SLICE_NAME
Definition cme.h:920
int const RTN_ERR_DEMFILE
Definition cme.h:593
int const RASTER_PLOT_FINE_UNCONSOLIDATED_SEDIMENT
Definition cme.h:516
string const RASTER_TOP_NAME
Definition cme.h:822
string const RASTER_BEACH_DEPOSITION_NAME
Definition cme.h:866
int const SAND_CONS_RASTER
Definition cme.h:457
string const RASTER_BEACH_PROTECTION_NAME
Definition cme.h:846
int const RTN_ERR_MEMALLOC
Definition cme.h:596
string const ERR
Definition cme.h:777
int const RASTER_PLOT_INUNDATION_MASK
Definition cme.h:519
int const RASTER_PLOT_SEDIMENT_TOP_ELEVATION_ELEV
Definition cme.h:532
string const RASTER_SAND_UNCONS_NAME
Definition cme.h:882
int const RASTER_PLOT_ACTUAL_BEACH_EROSION
Definition cme.h:494
string const RASTER_INUNDATION_MASK_NAME
Definition cme.h:832
string const RASTER_WAVE_PERIOD_NAME
Definition cme.h:840
int const RASTER_PLOT_POTENTIAL_PLATFORM_EROSION_MASK
Definition cme.h:549
int const RTN_ERR_GRIDCREATE
Definition cme.h:637
int const RASTER_PLOT_SAND_CONSOLIDATED_SEDIMENT
Definition cme.h:529
int const RASTER_PLOT_AVG_WAVE_HEIGHT
Definition cme.h:498
string const RASTER_CLIFF_COLLAPSE_EROSION_SAND_NAME
Definition cme.h:900
string const RASTER_SEDIMENT_TOP_NAME
Definition cme.h:820
string const RASTER_FINE_UNCONS_NAME
Definition cme.h:880
string const RASTER_COAST_NAME
Definition cme.h:892
int const LF_CAT_DRIFT
Definition cme.h:433
int const RASTER_PLOT_FINE_CONSOLIDATED_SEDIMENT
Definition cme.h:515
string const RASTER_CLIFF_COLLAPSE_EROSION_FINE_NAME
Definition cme.h:898
string const RASTER_SEDIMENT_INPUT_EVENT_NAME
Definition cme.h:936
string const RASTER_CLIFF_COLLAPSE_DEPOSITION_SAND_NAME
Definition cme.h:910
int const RASTER_PLOT_ACTIVE_ZONE
Definition cme.h:493
string const RASTER_ACTIVE_ZONE_NAME
Definition cme.h:896
int const LOG_FILE_MIDDLE_DETAIL
Definition cme.h:380
string const RASTER_INTERVENTION_HEIGHT_NAME
Definition cme.h:874
string const RASTER_SHADOW_ZONE_NAME
Definition cme.h:922
int const RASTER_PLOT_DEEP_WATER_WAVE_PERIOD
Definition cme.h:514
int const RTN_ERR_RASTER_FILE_READ
Definition cme.h:594
string const RASTER_COARSE_CONS_NAME
Definition cme.h:890
int const RASTER_PLOT_TOTAL_CLIFF_COLLAPSE_DEPOSITION_SAND
Definition cme.h:543
string const RASTER_TOTAL_CLIFF_COLLAPSE_EROSION_SAND_NAME
Definition cme.h:906
double const PI
Definition cme.h:681
int const RASTER_PLOT_COAST
Definition cme.h:511
string const RASTER_ACTUAL_BEACH_EROSION_NAME
Definition cme.h:860
string const RASTER_SETUP_SURGE_RUNUP_FLOOD_MASK_NAME
Definition cme.h:940
bool bFPIsEqual(const T d1, const T d2, const T dEpsilon)
Definition cme.h:1178
string const RASTER_AVG_WAVE_ORIENTATION_NAME
Definition cme.h:842
string const RASTER_TOTAL_BEACH_DEPOSITION_NAME
Definition cme.h:868
int const RASTER_PLOT_POLYGON_UPDRIFT_OR_DOWNDRIFT
Definition cme.h:526
string const RASTER_TOTAL_CLIFF_COLLAPSE_DEPOSITION_COARSE_NAME
Definition cme.h:916
int const RASTER_PLOT_POLYGON_GAIN_OR_LOSS
Definition cme.h:525
int const RASTER_PLOT_DEEP_WATER_WAVE_ORIENTATION
Definition cme.h:513
int const RASTER_PLOT_TOTAL_CLIFF_COLLAPSE_EROSION_COARSE
Definition cme.h:542
int const RTN_ERR_BOUNDING_BOX
Definition cme.h:643
int const RASTER_PLOT_COARSE_UNCONSOLIDATED_SEDIMENT
Definition cme.h:510
int const RASTER_PLOT_AVG_WAVE_ORIENTATION
Definition cme.h:499
int const RASTER_PLOT_WAVE_ORIENTATION
Definition cme.h:548
string const RASTER_SUSP_SED_NAME
Definition cme.h:876
string const RASTER_LOCAL_SLOPE_NAME
Definition cme.h:826
int const RASTER_PLOT_BEACH_MASK
Definition cme.h:502
string const RASTER_AVG_SEA_DEPTH_NAME
Definition cme.h:830
int const RASTER_PLOT_WAVE_FLOOD_LINE
Definition cme.h:553
int const RASTER_PLOT_SEDIMENT_INPUT
Definition cme.h:550
int const RASTER_PLOT_POTENTIAL_BEACH_EROSION
Definition cme.h:527
int const RASTER_PLOT_AVG_SUSPENDED_SEDIMENT
Definition cme.h:497
string const RASTER_AVG_WAVE_HEIGHT_NAME
Definition cme.h:836
int const RASTER_PLOT_TOTAL_POTENTIAL_PLATFORM_EROSION
Definition cme.h:546
string const RASTER_WAVE_FLOOD_LINE_NAME
Definition cme.h:942
string const RASTER_POTENTIAL_PLATFORM_EROSION_NAME
Definition cme.h:850
int const INTERVENTION_CLASS_RASTER
Definition cme.h:464
string const RASTER_ACTUAL_PLATFORM_EROSION_NAME
Definition cme.h:852
string const RASTER_COARSE_UNCONS_NAME
Definition cme.h:884
int const RASTER_PLOT_INTERVENTION_CLASS
Definition cme.h:517
string const WARN
Definition cme.h:778
int const RASTER_PLOT_BEACH_PROTECTION
Definition cme.h:503
int const RASTER_PLOT_AVG_SEA_DEPTH
Definition cme.h:496
int const RASTER_PLOT_OVERALL_TOP_ELEVATION
Definition cme.h:523
int const RASTER_PLOT_TOTAL_BEACH_DEPOSITION
Definition cme.h:539
string const RASTER_SETUP_SURGE_FLOOD_MASK_NAME
Definition cme.h:938
string const RASTER_INTERVENTION_CLASS_NAME
Definition cme.h:872
int const RASTER_PLOT_TOTAL_CLIFF_COLLAPSE_EROSION_FINE
Definition cme.h:540
string const RASTER_WAVE_ORIENTATION_NAME
Definition cme.h:838
int const RASTER_PLOT_TOTAL_CLIFF_COLLAPSE_EROSION_SAND
Definition cme.h:541
string const RASTER_DEEP_WATER_WAVE_ORIENTATION_NAME
Definition cme.h:926
string const RASTER_POTENTIAL_PLATFORM_EROSION_MASK_NAME
Definition cme.h:848
int const RASTER_PLOT_CLIFF_COLLAPSE_EROSION_FINE
Definition cme.h:504
int const SOUTH
Definition cme.h:390
int const RASTER_PLOT_ACTUAL_PLATFORM_EROSION
Definition cme.h:495
int const LOG_FILE_ALL
Definition cme.h:382
int const EAST
Definition cme.h:388
int const RTN_OK
Definition cme.h:580
string const RASTER_WAVE_HEIGHT_NAME
Definition cme.h:834
int const RASTER_PLOT_INTERVENTION_HEIGHT
Definition cme.h:518
int const SAND_UNCONS_RASTER
Definition cme.h:460
int const RASTER_PLOT_TOTAL_POTENTIAL_BEACH_EROSION
Definition cme.h:545
string const RASTER_TOTAL_POTENTIAL_BEACH_EROSION_NAME
Definition cme.h:862
int const RASTER_PLOT_SAND_UNCONSOLIDATED_SEDIMENT
Definition cme.h:530
string const RASTER_SAND_CONS_NAME
Definition cme.h:888
int const RASTER_PLOT_POTENTIAL_PLATFORM_EROSION
Definition cme.h:528
string const RASTER_BASEMENT_ELEVATION_NAME
Definition cme.h:824
int const FINE_UNCONS_RASTER
Definition cme.h:459
int const COARSE_UNCONS_RASTER
Definition cme.h:461
int const RASTER_PLOT_NORMAL_PROFILE
Definition cme.h:522
double const DBL_NODATA
Definition cme.h:709
int const RASTER_PLOT_CLIFF_COLLAPSE_DEPOSITION_COARSE
Definition cme.h:508
int const RASTER_PLOT_WAVE_HEIGHT
Definition cme.h:547
int const RASTER_PLOT_SHADOW_ZONE
Definition cme.h:534
int const RASTER_PLOT_DEEP_WATER_WAVE_HEIGHT
Definition cme.h:512
string const RASTER_COAST_NORMAL_NAME
Definition cme.h:894
string const NOTE
Definition cme.h:779
string const RASTER_CLIFF_COLLAPSE_EROSION_COARSE_NAME
Definition cme.h:902
int const RASTER_PLOT_COARSE_CONSOLIDATED_SEDIMENT
Definition cme.h:509
string const RASTER_LANDFORM_NAME
Definition cme.h:870
int const RASTER_PLOT_TOTAL_ACTUAL_PLATFORM_EROSION
Definition cme.h:538
int const SUSP_SED_RASTER
Definition cme.h:462
int const FINE_CONS_RASTER
Definition cme.h:456
int const COARSE_CONS_RASTER
Definition cme.h:458
int const LF_CAT_CLIFF
Definition cme.h:432
int const RASTER_PLOT_SETUP_SURGE_RUNUP_FLOOD_MASK
Definition cme.h:552
int const RASTER_PLOT_BASEMENT_ELEVATION
Definition cme.h:500
int const RASTER_PLOT_LANDFORM
Definition cme.h:520
string const RASTER_TOTAL_ACTUAL_PLATFORM_EROSION_NAME
Definition cme.h:856
string const RASTER_POLYGON_NAME
Definition cme.h:918
int const RASTER_PLOT_CLIFF_COLLAPSE_EROSION_COARSE
Definition cme.h:506
T tAbs(T a)
Definition cme.h:1150
string const RASTER_TOTAL_CLIFF_COLLAPSE_EROSION_FINE_NAME
Definition cme.h:904
int const LANDFORM_RASTER
Definition cme.h:463
int const RASTER_PLOT_SHADOW_DOWNDRIFT_ZONE
Definition cme.h:533
int const RASTER_PLOT_SLICE
Definition cme.h:535
string const RASTER_TOTAL_POTENTIAL_PLATFORM_EROSION_NAME
Definition cme.h:854
string const RASTER_AVG_SUSP_SED_NAME
Definition cme.h:878
string const RASTER_DEEP_WATER_WAVE_HEIGHT_NAME
Definition cme.h:928
int const INTERVENTION_HEIGHT_RASTER
Definition cme.h:465
string const RASTER_TOTAL_CLIFF_COLLAPSE_EROSION_COARSE_NAME
Definition cme.h:908
string const RASTER_POLYGON_GAIN_OR_LOSS_NAME
Definition cme.h:934
int const RASTER_PLOT_TOTAL_CLIFF_COLLAPSE_DEPOSITION_COARSE
Definition cme.h:544
string const RASTER_TOTAL_ACTUAL_BEACH_EROSION_NAME
Definition cme.h:864
int const RASTER_PLOT_CLIFF_COLLAPSE_EROSION_SAND
Definition cme.h:505
int const RASTER_PLOT_SEA_DEPTH
Definition cme.h:531
int const NORTH
Definition cme.h:386
string const RASTER_CLIFF_COLLAPSE_DEPOSITION_COARSE_NAME
Definition cme.h:912
int const RASTER_PLOT_SETUP_SURGE_FLOOD_MASK
Definition cme.h:551
int const WEST
Definition cme.h:392
Contains CRWCoast definitions.
Contains CGeomRasterGrid definitions.
Contains CSimulation definitions.
double dRound(double const d)
Correctly rounds doubles.