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
1127 case (RASTER_PLOT_NORMAL):
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
1549 case (RASTER_PLOT_NORMAL):
1550 dTmp = (m_pRasterGrid->m_Cell[nX][nY].bIsProfile() ? 1 : 0);
1551 break;
1552
1554 dTmp = (m_pRasterGrid->m_Cell[nX][nY].bIsInActiveZone() ? 1 : 0);
1555 break;
1556
1557 case (RASTER_PLOT_POLYGON):
1558 dTmp = m_pRasterGrid->m_Cell[nX][nY].nGetPolygonID();
1559 break;
1560
1562 dTmp = m_pRasterGrid->m_Cell[nX][nY].nGetShadowZoneNumber();
1563 break;
1564
1566 dTmp = m_pRasterGrid->m_Cell[nX][nY].nGetDownDriftZoneNumber();
1567 break;
1568
1570 nPoly = m_pRasterGrid->m_Cell[nX][nY].nGetPolygonID();
1571 if (nPoly == INT_NODATA)
1572 dTmp = m_nMissingValue;
1573 else
1574 {
1575 if (m_pVCoastPolygon[nPoly]->bDownCoastThisIter())
1576 dTmp = 1;
1577 else
1578 dTmp = 0;
1579 }
1580 break;
1581
1583 dTmp = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->dGetTotAllSedimentInputDepth();
1584 break;
1585
1587 dTmp = (m_pRasterGrid->m_Cell[nX][nY].bIsFloodBySetupSurge() ? 1 : 0);
1588 break;
1589
1591 dTmp = (m_pRasterGrid->m_Cell[nX][nY].bIsFloodBySetupSurgeRunup() ? 1 : 0);
1592 break;
1593
1595 dTmp = (m_pRasterGrid->m_Cell[nX][nY].bIsFloodLine() ? 1 : 0);
1596 break;
1597 }
1598
1599 // If necessary, scale this value
1600 if (bScaleOutput)
1601 {
1602 if (bFPIsEqual(dTmp, DBL_NODATA, TOLERANCE))
1603 dTmp = 0; // TODO 032 Improve this
1604 else
1605 dTmp = dRound(static_cast<double>(m_lGDALMinCanWrite) + (dRangeScale * (dTmp - dDataMin)));
1606 }
1607
1608 // Write this value to the array
1609 pdRaster[n++] = dTmp;
1610 }
1611 }
1612
1613 // Create a single raster band
1614 GDALRasterBand* pBand = pDataSet->GetRasterBand(1);
1615
1616 // And fill it with the NODATA value
1617 if (bIsInteger)
1618 pBand->Fill(m_nMissingValue);
1619 else
1620 pBand->Fill(m_dMissingValue);
1621
1622 // Set value units for this band
1623 string strUnits;
1624 switch (nDataItem)
1625 {
1629 case (RASTER_PLOT_SEA_DEPTH):
1664 strUnits = "m";
1665 break;
1666
1668 strUnits = "m/m";
1669 break;
1670
1673 strUnits = "degrees";
1674 break;
1675
1677 strUnits = "cumecs";
1678 break;
1680 strUnits = "secs";
1681 break;
1682
1686 case (RASTER_PLOT_SLICE):
1687 case (RASTER_PLOT_LANDFORM):
1689 case (RASTER_PLOT_COAST):
1690 case (RASTER_PLOT_NORMAL):
1692 case (RASTER_PLOT_POLYGON):
1699 strUnits = "none";
1700 break;
1701 }
1702
1703 CPLPushErrorHandler(CPLQuietErrorHandler); // Needed to get next line to fail silently, if it fails
1704 pBand->SetUnitType(strUnits.c_str()); // Not supported for some GIS formats
1705 CPLPopErrorHandler();
1706
1707 // Tell the output dataset about NODATA (missing values)
1708 CPLPushErrorHandler(CPLQuietErrorHandler); // Needed to get next line to fail silently, if it fails
1709 if (bIsInteger)
1710 pBand->SetNoDataValue(m_nMissingValue); // Will fail for some formats
1711 else
1712 pBand->SetNoDataValue(m_dMissingValue); // Will fail for some formats
1713 CPLPopErrorHandler();
1714
1715 // Construct the description
1716 string strDesc(*strPlotTitle);
1717 if (nDataItem == RASTER_PLOT_SLICE)
1718 {
1719 ststrTmp.clear();
1720 ststrTmp << dElev << "m, ";
1721 strDesc.append(ststrTmp.str());
1722 }
1723 strDesc.append(" at ");
1724 strDesc.append(strDispTime(m_dSimElapsed, false, false));
1725
1726 // Set the GDAL description
1727 pBand->SetDescription(strDesc.c_str());
1728
1729 // Set raster category names
1730 char** papszCategoryNames = NULL;
1731 switch (nDataItem)
1732 {
1733 case (RASTER_PLOT_SLICE):
1734 papszCategoryNames = CSLAddString(papszCategoryNames, "Basement");
1735 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 0");
1736 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 1");
1737 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 2");
1738 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 3");
1739 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 4");
1740 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 5");
1741 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 6");
1742 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 7");
1743 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 8");
1744 papszCategoryNames = CSLAddString(papszCategoryNames, "Layer 9");
1745 break;
1746
1747 case (RASTER_PLOT_LANDFORM):
1748 papszCategoryNames = CSLAddString(papszCategoryNames, "None");
1749 papszCategoryNames = CSLAddString(papszCategoryNames, "Hinterland");
1750 papszCategoryNames = CSLAddString(papszCategoryNames, "Sea");
1751 papszCategoryNames = CSLAddString(papszCategoryNames, "Cliff");
1752 papszCategoryNames = CSLAddString(papszCategoryNames, "Drift");
1753 papszCategoryNames = CSLAddString(papszCategoryNames, "Intervention");
1754
1755 papszCategoryNames = CSLAddString(papszCategoryNames, "Cliff on Coastline");
1756 papszCategoryNames = CSLAddString(papszCategoryNames, "Inland Cliff");
1757
1758 papszCategoryNames = CSLAddString(papszCategoryNames, "Mixed Drift");
1759 papszCategoryNames = CSLAddString(papszCategoryNames, "Talus");
1760 papszCategoryNames = CSLAddString(papszCategoryNames, "Beach");
1761 papszCategoryNames = CSLAddString(papszCategoryNames, "Dunes");
1762 break;
1763
1765 papszCategoryNames = CSLAddString(papszCategoryNames, "None");
1766 papszCategoryNames = CSLAddString(papszCategoryNames, "Structural");
1767 papszCategoryNames = CSLAddString(papszCategoryNames, "Non-Structural");
1768 break;
1769
1770 case (RASTER_PLOT_COAST):
1771 papszCategoryNames = CSLAddString(papszCategoryNames, "Not coastline");
1772 papszCategoryNames = CSLAddString(papszCategoryNames, "Coastline");
1773 break;
1774
1775 case (RASTER_PLOT_NORMAL):
1776 papszCategoryNames = CSLAddString(papszCategoryNames, "Not coastline-normal profile");
1777 papszCategoryNames = CSLAddString(papszCategoryNames, "Coastline-normal profile");
1778 break;
1779
1781 papszCategoryNames = CSLAddString(papszCategoryNames, "Not in active zone");
1782 papszCategoryNames = CSLAddString(papszCategoryNames, "In active zone");
1783 break;
1784
1785 case (RASTER_PLOT_POLYGON):
1786 papszCategoryNames = CSLAddString(papszCategoryNames, "Not polygon");
1787 papszCategoryNames = CSLAddString(papszCategoryNames, "In polygon");
1788 break;
1789
1791 papszCategoryNames = CSLAddString(papszCategoryNames, "Not in shadow zone");
1792 papszCategoryNames = CSLAddString(papszCategoryNames, "In shadow zone");
1793 break;
1794
1796 papszCategoryNames = CSLAddString(papszCategoryNames, "Not in shadow downdrift zone");
1797 papszCategoryNames = CSLAddString(papszCategoryNames, "In shadow downdrift zone");
1798 break;
1799
1801 papszCategoryNames = CSLAddString(papszCategoryNames, "Updrift movement of unconsolidated sediment ");
1802 papszCategoryNames = CSLAddString(papszCategoryNames, "Downdrift movement of unconsolidated sediment");
1803 break;
1804
1806 papszCategoryNames = CSLAddString(papszCategoryNames, "Inundated by swl setup and surge ");
1807 papszCategoryNames = CSLAddString(papszCategoryNames, "Not inundated by swl setup and surge");
1808 break;
1809
1811 papszCategoryNames = CSLAddString(papszCategoryNames, "Inundated by swl setup, surge and runup ");
1812 papszCategoryNames = CSLAddString(papszCategoryNames, "Not inundated by swl setup, surge and runup");
1813 break;
1814
1816 papszCategoryNames = CSLAddString(papszCategoryNames, "Intersection line of inundation ");
1817 papszCategoryNames = CSLAddString(papszCategoryNames, "Not inundated by swl waves and runup");
1818 break;
1819 }
1820
1821 CPLPushErrorHandler(CPLQuietErrorHandler); // Needed to get next line to fail silently, if it fails
1822 pBand->SetCategoryNames(papszCategoryNames); // Not supported for some GIS formats
1823 CPLPopErrorHandler();
1824
1825 // Now write the data
1826 if (CE_Failure == pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL))
1827 {
1828 // Write error, better error message
1829 cerr << ERR << "cannot write data for " << m_strRasterGISOutFormat << " file named " << strFilePathName << endl << CPLGetLastErrorMsg() << endl;
1830 delete[] pdRaster;
1831 return false;
1832 }
1833
1834 // Calculate statistics for this band
1835 double dMin, dMax, dMean, dStdDev;
1836 CPLPushErrorHandler(CPLQuietErrorHandler); // Needed to get next line to fail silently, if it fails
1837 pBand->ComputeStatistics(false, &dMin, &dMax, &dMean, &dStdDev, NULL, NULL);
1838 CPLPopErrorHandler();
1839
1840 // And then write the statistics
1841 CPLPushErrorHandler(CPLQuietErrorHandler); // Needed to get next line to fail silently, if it fails
1842 pBand->SetStatistics(dMin, dMax, dMean, dStdDev);
1843 CPLPopErrorHandler();
1844
1845 if (! m_bGDALCanCreate)
1846 {
1847 // 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
1848 GDALDriver* pOutDriver = GetGDALDriverManager()->GetDriverByName(m_strRasterGISOutFormat.c_str());
1849 GDALDataset* pOutDataSet = pOutDriver->CreateCopy(strFilePathName.c_str(), pDataSet, FALSE, m_papszGDALRasterOptions, NULL, NULL);
1850 if (NULL == pOutDataSet)
1851 {
1852 // Couldn't create file
1853 cerr << ERR << "cannot create " << m_strRasterGISOutFormat << " file named " << strFilePathName << endl
1854 << CPLGetLastErrorMsg() << endl;
1855 return false;
1856 }
1857
1858 // Get rid of this user-selected dataset object
1859 GDALClose(pOutDataSet);
1860 }
1861
1862 // Get rid of dataset object
1863 GDALClose(pDataSet);
1864
1865 // Also get rid of memory allocated to this array
1866 delete[] pdRaster;
1867
1868 return true;
1869}
1870
1871//===============================================================================================================================
1873//===============================================================================================================================
1874int CSimulation::nInterpolateWavesToPolygonCells(vector<double> const* pVdX, vector<double> const* pVdY, vector<double> const* pVdHeightX, vector<double> const* pVdHeightY)
1875{
1876 int nXSize = 0;
1877 int nYSize = 0;
1878
1879 double dXAvg = 0;
1880 double dYAvg = 0;
1881
1884 int nGridSize = nXSize * nYSize;
1885
1886 unsigned int nPoints = static_cast<unsigned int>(pVdX->size());
1887
1888 // // DEBUG CODE ============================================================================================================
1889 // for (int nn = 0; nn < nPoints; nn++)
1890 // {
1891 // LogStream << nn << " " << dX[nn] << " " << dY[nn] << " " << dZ[nn] << endl;
1892 // }
1893 //
1894 // m_nXMaxBoundingBox = m_nXGridSize-1;
1895 // m_nYMaxBoundingBox = m_nYGridSize-1;
1896 // m_nXMinBoundingBox = 0;
1897 // m_nYMinBoundingBox = 0;
1898 // // DEBUG CODE ============================================================================================================
1899
1900 vector<double> VdOutX(nGridSize, 0);
1901 vector<double> VdOutY(nGridSize, 0);
1902
1903 // Do first for X, then for Y
1904 for (int nDirection = 0; nDirection < 2; nDirection++)
1905 {
1906 // 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
1907 GDALGridLinearOptions* pOptions = new GDALGridLinearOptions();
1908 pOptions->dfNoDataValue = m_dMissingValue; // Set the no-data marker to fill empty points
1909 pOptions->dfRadius = -1; // Set the search radius to infinite
1910 pOptions->nSizeOfStructure = sizeof(GDALGridLinearOptions); // Needed for GDAL 3.6 onwards, see https://gdal.org/api/gdal_alg.html#_CPPv421GDALGridLinearOptions
1911
1912 // pOptions.dfRadius = static_cast<double>(nXSize + nYSize) / 2.0; // Set the search radius
1913
1914 // GDALGridNearestNeighborOptions* pOptions = new GDALGridNearestNeighborOptions();
1915 // pOptions->dfNoDataValue = m_dMissingValue; // Set the no-data marker to fill empty points
1916 // pOptions->dfRadius = -1; // Set the search radius to infinite
1917
1918 // Call GDALGridCreate() TODO 086
1919 int nRet;
1920 if (nDirection == 0)
1921 {
1922 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);
1923 }
1924 else
1925 {
1926 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);
1927 }
1928
1929 // int nRet;
1930 // if (nDirection == 0)
1931 // {
1932 // 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);
1933 // }
1934 // else
1935 // {
1936 // 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);
1937 // }
1938
1939 delete pOptions;
1940
1941 if (nRet == CE_Failure)
1942 {
1943 cerr << CPLGetLastErrorMsg() << endl;
1944 return RTN_ERR_GRIDCREATE;
1945 }
1946
1947 if (nDirection == 0)
1948 {
1949 int nXValid = 0;
1950
1951 // Safety check: unfortunately, GDALGridCreate(() outputs NaNs and other crazy values when the polygons are far from regular. So check for these
1952 for (unsigned int n = 0; n < VdOutX.size(); n++)
1953 {
1954 if (isnan(VdOutX[n]))
1955 VdOutX[n] = m_dMissingValue;
1956 else if (tAbs(VdOutX[n]) > 1e10)
1957 VdOutX[n] = m_dMissingValue;
1958 else
1959 {
1960 dXAvg += VdOutX[n];
1961 nXValid++;
1962 }
1963 }
1964
1965 dXAvg /= nXValid;
1966 }
1967 else
1968 {
1969 int nYValid = 0;
1970
1971 // Safety check: unfortunately, GDALGridCreate(() outputs NaNs and other crazy values when the polygon are far from regular. So check for these
1972 for (unsigned int n = 0; n < VdOutY.size(); n++)
1973 {
1974 if (isnan(VdOutY[n]))
1975 VdOutY[n] = m_dMissingValue;
1976 else if (tAbs(VdOutY[n]) > 1e10)
1977 VdOutY[n] = m_dMissingValue;
1978 else
1979 {
1980 dYAvg += VdOutY[n];
1981 nYValid++;
1982 }
1983 }
1984
1985 dYAvg /= nYValid;
1986 }
1987
1988 // // DEBUG CODE ===========================================================================================================
1989 // string strOutFile = m_strOutPath;
1990 // strOutFile += "sea_wave_interpolation_";
1991 // if (nDirection == 0)
1992 // strOutFile += "X_";
1993 // else
1994 // strOutFile += "Y_";
1995 // strOutFile += to_string(m_ulIter);
1996 // strOutFile += ".tif";
1997 //
1998 // GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("gtiff");
1999 // GDALDataset* pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
2000 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
2001 // pDataSet->SetGeoTransform(m_dGeoTransform);
2002 // double* pdRaster = new double[m_nXGridSize * m_nYGridSize];
2003 // int m = 0;
2004 // int n = 0;
2005 // for (int nY = 0; nY < m_nYGridSize; nY++)
2006 // {
2007 // for (int nX = 0; nX < m_nXGridSize; nX++)
2008 // {
2009 // if ((nX < m_nXMinBoundingBox) || (nY < m_nYMinBoundingBox))
2010 // {
2011 // pdRaster[n++] = DBL_NODATA;
2012 // }
2013 // else
2014 // {
2015 // // Write this value to the array
2016 // if (nDirection == 0)
2017 // {
2018 // if (m < static_cast<int>(VdOutX.size()))
2019 // {
2020 // pdRaster[n++] = VdOutX[m++];
2021 // // LogStream << "nDirection = " << nDirection << " [" << nX << "][" << nY << "] = " << VpdOutX[n] << endl;
2022 // }
2023 // }
2024 // else
2025 // {
2026 // if (m < static_cast<int>(VdOutY.size()))
2027 // {
2028 // pdRaster[n++] = VdOutY[m++];
2029 // // LogStream << "nDirection = " << nDirection << " [" << nX << "][" << nY << "] = " << VpdOutY[n] << endl;
2030 // }
2031 // }
2032 // }
2033 // }
2034 // }
2035 //
2036 // GDALRasterBand* pBand = pDataSet->GetRasterBand(1);
2037 // pBand->SetNoDataValue(m_dMissingValue);
2038 // nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
2039 //
2040 // if (nRet == CE_Failure)
2041 // return RTN_ERR_GRIDCREATE;
2042 //
2043 // GDALClose(pDataSet);
2044 // delete[] pdRaster;
2045 // // DEBUG CODE ===========================================================================================================
2046 }
2047
2048 // // DEBUG CODE ===========================================================================================================
2049 // string strOutFile = m_strOutPath;
2050 // strOutFile += "sea_wave_height_before_";
2051 // strOutFile += to_string(m_ulIter);
2052 // strOutFile += ".tif";
2053 //
2054 // GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("gtiff");
2055 // GDALDataset* pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
2056 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
2057 // pDataSet->SetGeoTransform(m_dGeoTransform);
2058 //
2059 // int nn = 0;
2060 // double* pdRaster = new double[m_nXGridSize * m_nYGridSize];
2061 // for (int nY = 0; nY < m_nYGridSize; nY++)
2062 // {
2063 // for (int nX = 0; nX < m_nXGridSize; nX++)
2064 // {
2065 // pdRaster[nn++] = m_pRasterGrid->m_Cell[nX][nY].dGetWaveHeight();
2066 // }
2067 // }
2068 //
2069 // GDALRasterBand* pBand = pDataSet->GetRasterBand(1);
2070 // pBand->SetNoDataValue(m_dMissingValue);
2071 // int nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
2072 //
2073 // if (nRet == CE_Failure)
2074 // return RTN_ERR_GRIDCREATE;
2075 //
2076 // GDALClose(pDataSet);
2077 // delete[] pdRaster;
2078 // // DEBUG CODE ===========================================================================================================
2079
2080 // // DEBUG CODE ===========================================================================================================
2081 // strOutFile = m_strOutPath;
2082 // strOutFile += "sea_wave_angle_before_";
2083 // strOutFile += to_string(m_ulIter);
2084 // strOutFile += ".tif";
2085 //
2086 // pDriver = GetGDALDriverManager()->GetDriverByName("gtiff");
2087 // pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
2088 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
2089 // pDataSet->SetGeoTransform(m_dGeoTransform);
2090 //
2091 // nn = 0;
2092 // pdRaster = new double[m_nXGridSize * m_nYGridSize];
2093 // for (int nY = 0; nY < m_nYGridSize; nY++)
2094 // {
2095 // for (int nX = 0; nX < m_nXGridSize; nX++)
2096 // {
2097 // pdRaster[nn++] = m_pRasterGrid->m_Cell[nX][nY].dGetWaveAngle();
2098 // }
2099 // }
2100 //
2101 // pBand = pDataSet->GetRasterBand(1);
2102 // pBand->SetNoDataValue(m_dMissingValue);
2103 // nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
2104 //
2105 // if (nRet == CE_Failure)
2106 // return RTN_ERR_GRIDCREATE;
2107 //
2108 // GDALClose(pDataSet);
2109 // delete[] pdRaster;
2110 // // DEBUG CODE ===========================================================================================================
2111
2112 // Now put the X and Y directions together and update the raster cells
2113 int n = 0;
2114 for (int nY = 0; nY < nYSize; nY++)
2115 {
2116 for (int nX = 0; nX < nXSize; nX++)
2117 {
2118 int nActualX = nX + m_nXMinBoundingBox;
2119 int nActualY = nY + m_nYMinBoundingBox;
2120
2121 if (m_pRasterGrid->m_Cell[nActualX][nActualY].bIsInContiguousSea())
2122 {
2123 // Only update sea cells
2124 if (m_pRasterGrid->m_Cell[nActualX][nActualY].nGetPolygonID() == INT_NODATA)
2125 {
2126 // This is a deep water sea cell (not in a polygon)
2127 double dDeepWaterWaveHeight = m_pRasterGrid->m_Cell[nActualX][nActualY].dGetCellDeepWaterWaveHeight();
2128 m_pRasterGrid->m_Cell[nActualX][nActualY].SetWaveHeight(dDeepWaterWaveHeight);
2129
2130 double dDeepWaterWaveAngle = m_pRasterGrid->m_Cell[nActualX][nActualY].dGetCellDeepWaterWaveAngle();
2131 m_pRasterGrid->m_Cell[nActualX][nActualY].SetWaveAngle(dDeepWaterWaveAngle);
2132 }
2133 else
2134 {
2135 // This is in a polygon so is not a deep water sea cell
2136 double dWaveHeightX;
2137 double dWaveHeightY;
2138
2139 // Safety checks
2140 if ((isnan(VdOutX[n])) || (bFPIsEqual(VdOutX[n], m_dMissingValue, TOLERANCE)))
2141 dWaveHeightX = dXAvg;
2142 else
2143 dWaveHeightX = VdOutX[n];
2144
2145 if ((isnan(VdOutY[n])) || (bFPIsEqual(VdOutY[n], m_dMissingValue, TOLERANCE)))
2146 dWaveHeightY = dYAvg;
2147 else
2148 dWaveHeightY = VdOutY[n];
2149
2150 // Now calculate wave direction
2151 double dWaveHeight = sqrt((dWaveHeightX * dWaveHeightX) + (dWaveHeightY * dWaveHeightY));
2152 double dWaveDir = atan2(dWaveHeightX, dWaveHeightY) * (180 / PI);
2153
2154// assert(isfinite(dWaveHeight));
2155// assert(isfinite(dWaveDir));
2156
2157 // Update the cell's wave attributes
2158 m_pRasterGrid->m_Cell[nActualX][nActualY].SetWaveHeight(dWaveHeight);
2159 m_pRasterGrid->m_Cell[nActualX][nActualY].SetWaveAngle(dKeepWithin360(dWaveDir));
2160
2161 // Calculate the wave height-to-depth ratio for this cell, then update the cell's active zone status
2162 double dSeaDepth = m_pRasterGrid->m_Cell[nActualX][nActualY].dGetSeaDepth();
2163 if ((dWaveHeight / dSeaDepth) >= m_dBreakingWaveHeightDepthRatio)
2164 m_pRasterGrid->m_Cell[nActualX][nActualY].SetInActiveZone(true);
2165
2166 // LogStream << " nX = " << nX << " nY = " << nY << " [" << nActualX << "][" << nActualY << "] waveheight = " << dWaveHeight << " dWaveDir = " << dWaveDir << " dKeepWithin360(dWaveDir) = " << dKeepWithin360(dWaveDir) << endl;
2167 }
2168 }
2169 // Increment with safety check
2170 n++;
2171 n = tMin(n, static_cast<int>(VdOutX.size()-1));
2172 }
2173 }
2174
2175 // // DEBUG CODE ===========================================================================================================
2176 // strOutFile = m_strOutPath;
2177 // strOutFile += "sea_wave_height_after_";
2178 // strOutFile += to_string(m_ulIter);
2179 // strOutFile += ".tif";
2180 //
2181 // pDriver = GetGDALDriverManager()->GetDriverByName("gtiff");
2182 // pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
2183 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
2184 // pDataSet->SetGeoTransform(m_dGeoTransform);
2185 //
2186 // nn = 0;
2187 // pdRaster = new double[m_nXGridSize * m_nYGridSize];
2188 // for (int nY = 0; nY < m_nYGridSize; nY++)
2189 // {
2190 // for (int nX = 0; nX < m_nXGridSize; nX++)
2191 // {
2192 // pdRaster[nn++] = m_pRasterGrid->m_Cell[nX][nY].dGetWaveHeight();
2193 // }
2194 // }
2195 //
2196 // pBand = pDataSet->GetRasterBand(1);
2197 // pBand->SetNoDataValue(m_dMissingValue);
2198 // nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
2199 //
2200 // if (nRet == CE_Failure)
2201 // return RTN_ERR_GRIDCREATE;
2202 //
2203 // GDALClose(pDataSet);
2204 // delete[] pdRaster;
2205 // // DEBUG CODE ===========================================================================================================
2206
2207 // // DEBUG CODE ===========================================================================================================
2208 // strOutFile = m_strOutPath;
2209 // strOutFile += "sea_wave_angle_after_";
2210 // strOutFile += to_string(m_ulIter);
2211 // strOutFile += ".tif";
2212 //
2213 // pDriver = GetGDALDriverManager()->GetDriverByName("gtiff");
2214 // pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
2215 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
2216 // pDataSet->SetGeoTransform(m_dGeoTransform);
2217 //
2218 // nn = 0;
2219 // pdRaster = new double[m_nXGridSize * m_nYGridSize];
2220 // for (int nY = 0; nY < m_nYGridSize; nY++)
2221 // {
2222 // for (int nX = 0; nX < m_nXGridSize; nX++)
2223 // {
2224 // pdRaster[nn++] = m_pRasterGrid->m_Cell[nX][nY].dGetWaveAngle();
2225 // }
2226 // }
2227 //
2228 // pBand = pDataSet->GetRasterBand(1);
2229 // pBand->SetNoDataValue(m_dMissingValue);
2230 // nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
2231 //
2232 // if (nRet == CE_Failure)
2233 // return RTN_ERR_GRIDCREATE;
2234 //
2235 // GDALClose(pDataSet);
2236 // delete[] pdRaster;
2237 // // DEBUG CODE ===========================================================================================================
2238
2239 return RTN_OK;
2240}
2241
2242//===============================================================================================================================
2244//===============================================================================================================================
2246{
2247 // Interpolate deep water height and orientation from multiple user-supplied values
2248 unsigned int nUserPoints = static_cast<unsigned int>(m_VdDeepWaterWaveStationX.size());
2249
2250 // 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
2251 GDALGridInverseDistanceToAPowerOptions* pOptions = new GDALGridInverseDistanceToAPowerOptions();
2252 pOptions->dfAngle = 0;
2253 pOptions->dfAnisotropyAngle = 0;
2254 pOptions->dfAnisotropyRatio = 0;
2255 pOptions->dfPower = 3;
2256 pOptions->dfSmoothing = 100;
2257 pOptions->dfRadius1 = 0;
2258 pOptions->dfRadius2 = 0;
2259 pOptions->nMaxPoints = 0;
2260 pOptions->nMinPoints = 0;
2261 pOptions->dfNoDataValue = m_nMissingValue;
2262
2263 // CPLSetConfigOption("CPL_DEBUG", "ON");
2264 // CPLSetConfigOption("GDAL_NUM_THREADS", "1");
2265
2266 // OK, now create a gridded version of wave height: first create the GDAL context TODO 086
2267 // GDALGridContext* pContext = GDALGridContextCreate(GGA_InverseDistanceToAPower, pOptions, nUserPoints, &m_VdDeepWaterWaveStationX[0], &m_VdDeepWaterWaveStationY[0], &m_VdThisIterDeepWaterWaveStationHeight[0], true);
2268 GDALGridContext* pContext = GDALGridContextCreate(GGA_InverseDistanceToAPower, pOptions, nUserPoints, m_VdDeepWaterWaveStationX.data(), m_VdDeepWaterWaveStationY.data(), m_VdThisIterDeepWaterWaveStationHeight.data(), true);
2269
2270 if (pContext == NULL)
2271 {
2272 delete pOptions;
2273 return RTN_ERR_GRIDCREATE;
2274 }
2275
2276 // Now process the context
2277 double *dHeightOut = new double[m_ulNumCells];
2278 int nRet = GDALGridContextProcess(pContext, 0, m_nXGridSize - 1, 0, m_nYGridSize - 1, m_nXGridSize, m_nYGridSize, GDT_Float64, dHeightOut, NULL, NULL);
2279 if (nRet == CE_Failure)
2280 {
2281 delete[] dHeightOut;
2282 delete pOptions;
2283 return RTN_ERR_GRIDCREATE;
2284 }
2285
2286 // Get rid of the context
2287 GDALGridContextFree(pContext);
2288
2289 // Next create a gridded version of wave orientation: first create the GDAL context
2290 // pContext = GDALGridContextCreate(GGA_InverseDistanceToAPower, pOptions, nUserPoints, &(m_VdDeepWaterWaveStationX[0]), &(m_VdDeepWaterWaveStationY[0]), (&m_VdThisIterDeepWaterWaveStationAngle[0]), true);
2291 pContext = GDALGridContextCreate(GGA_InverseDistanceToAPower, pOptions, nUserPoints, m_VdDeepWaterWaveStationX.data(), m_VdDeepWaterWaveStationY.data(), m_VdThisIterDeepWaterWaveStationAngle.data(), true);
2292 if (pContext == NULL)
2293 {
2294 delete[] dHeightOut;
2295 delete pOptions;
2296 return RTN_ERR_GRIDCREATE;
2297 }
2298
2299 // Now process the context TODO 086
2300 double *dAngleOut = new double[m_ulNumCells];
2301 nRet = GDALGridContextProcess(pContext, 0, m_nXGridSize - 1, 0, m_nYGridSize - 1, m_nXGridSize, m_nYGridSize, GDT_Float64, dAngleOut, NULL, NULL);
2302 if (nRet == CE_Failure)
2303 {
2304 delete[] dHeightOut;
2305 delete[] dAngleOut;
2306 delete pOptions;
2307 return RTN_ERR_GRIDCREATE;
2308 }
2309
2310 // Get rid of the context
2311 GDALGridContextFree(pContext);
2312
2313 // OK, now create a gridded version of wave period: first create the GDAL context
2314 // pContext = GDALGridContextCreate(GGA_InverseDistanceToAPower, pOptions, nUserPoints, &m_VdDeepWaterWaveStationX[0], &m_VdDeepWaterWaveStationY[0], &m_VdThisIterDeepWaterWaveStationPeriod[0], true);
2315 pContext = GDALGridContextCreate(GGA_InverseDistanceToAPower, pOptions, nUserPoints, m_VdDeepWaterWaveStationX.data(), m_VdDeepWaterWaveStationY.data(), m_VdThisIterDeepWaterWaveStationPeriod.data(), true);
2316 if (pContext == NULL)
2317 {
2318 delete pOptions;
2319 return RTN_ERR_GRIDCREATE;
2320 }
2321
2322 // Now process the context TODO 086
2323 double *dPeriopdOut = new double[m_ulNumCells];
2324 nRet = GDALGridContextProcess(pContext, 0, m_nXGridSize - 1, 0, m_nYGridSize - 1, m_nXGridSize, m_nYGridSize, GDT_Float64, dPeriopdOut, NULL, NULL);
2325 if (nRet == CE_Failure)
2326 {
2327 delete[] dPeriopdOut;
2328 delete pOptions;
2329 return RTN_ERR_GRIDCREATE;
2330 }
2331
2332 // Get rid of the context
2333 GDALGridContextFree(pContext);
2334
2335 // The output from GDALGridCreate() is in dHeightOut, dAngleOut and dPeriopdOut but must be reversed
2336 vector<double>
2337 VdHeight,
2338 VdAngle,
2339 VdPeriod;
2340
2341 int
2342 n = 0,
2343 nValidHeight = 0,
2344 nValidAngle = 0,
2345 nValidPeriod = 0;
2346
2347 double
2348 dAvgHeight = 0,
2349 dAvgAngle = 0,
2350 dAvgPeriod = 0;
2351
2352 for (int nY = m_nYGridSize - 1; nY >= 0; nY--)
2353 {
2354 for (int nX = 0; nX < m_nXGridSize; nX++)
2355 {
2356 if (isfinite(dHeightOut[n]))
2357 {
2358 VdHeight.push_back(dHeightOut[n]);
2359
2360 dAvgHeight += dHeightOut[n];
2361 nValidHeight++;
2362 }
2363 else
2364 {
2365 VdHeight.push_back(m_dMissingValue);
2366 }
2367
2368 if (isfinite(dAngleOut[n]))
2369 {
2370 VdAngle.push_back(dAngleOut[n]);
2371
2372 dAvgAngle += dAngleOut[n];
2373 nValidAngle++;
2374 }
2375 else
2376 {
2377 VdAngle.push_back(m_dMissingValue);
2378 }
2379
2380 if (isfinite(dPeriopdOut[n]))
2381 {
2382 VdPeriod.push_back(dPeriopdOut[n]);
2383
2384 dAvgPeriod += dPeriopdOut[n];
2385 nValidPeriod++;
2386 }
2387 else
2388 {
2389 VdPeriod.push_back(m_dMissingValue);
2390 }
2391
2392 // LogStream << " nX = " << nX << " nY = " << nY << " n = " << n << " dHeightOut[n] = " << dHeightOut[n] << " dAngleOut[n] = " << dAngleOut[n] << endl;
2393 n++;
2394 }
2395 }
2396
2397 // Calculate averages
2398 dAvgHeight /= nValidHeight;
2399 dAvgAngle /= nValidAngle;
2400 dAvgPeriod /= nValidPeriod;
2401
2402 // Tidy
2403 delete pOptions;
2404 delete[] dHeightOut;
2405 delete[] dAngleOut;
2406 delete[] dPeriopdOut;
2407
2408 // Now update all raster cells
2409 n = 0;
2410 for (int nY = 0; nY < m_nYGridSize; nY++)
2411 {
2412 for (int nX = 0; nX < m_nXGridSize; nX++)
2413 {
2414 if (bFPIsEqual(VdHeight[n], m_dMissingValue, TOLERANCE))
2415 m_pRasterGrid->m_Cell[nX][nY].SetCellDeepWaterWaveHeight(dAvgHeight);
2416 else
2417 m_pRasterGrid->m_Cell[nX][nY].SetCellDeepWaterWaveHeight(VdHeight[n]);
2418
2419 if (bFPIsEqual(VdAngle[n], m_dMissingValue, TOLERANCE))
2420 m_pRasterGrid->m_Cell[nX][nY].SetCellDeepWaterWaveAngle(dAvgAngle);
2421 else
2422 m_pRasterGrid->m_Cell[nX][nY].SetCellDeepWaterWaveAngle(VdAngle[n]);
2423
2424 if (bFPIsEqual(VdPeriod[n], m_dMissingValue, TOLERANCE))
2425 m_pRasterGrid->m_Cell[nX][nY].SetCellDeepWaterWavePeriod(dAvgPeriod);
2426 else
2427 m_pRasterGrid->m_Cell[nX][nY].SetCellDeepWaterWavePeriod(VdPeriod[n]);
2428
2429 // 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;
2430 n++;
2431 }
2432 }
2433
2434 // // DEBUG CODE ===========================================================================================================
2435 // string strOutFile = m_strOutPath;
2436 // strOutFile += "init_deep_water_wave_height_";
2437 // strOutFile += to_string(m_ulIter);
2438 // strOutFile += ".tif";
2439 // GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("gtiff");
2440 // GDALDataset* pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
2441 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
2442 // pDataSet->SetGeoTransform(m_dGeoTransform);
2443 // double* pdRaster = new double[m_ulNumCells];
2444 // int nn = 0;
2445 // for (int nY = 0; nY < m_nYGridSize; nY++)
2446 // {
2447 // for (int nX = 0; nX < m_nXGridSize; nX++)
2448 // {
2449 // // Write this value to the array
2450 // pdRaster[nn] = m_pRasterGrid->m_Cell[nX][nY].dGetCellDeepWaterWaveHeight();
2451 // nn++;
2452 // }
2453 // }
2454 //
2455 // GDALRasterBand* pBand = pDataSet->GetRasterBand(1);
2456 // pBand->SetNoDataValue(m_nMissingValue);
2457 // nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
2458 //
2459 // if (nRet == CE_Failure)
2460 // return RTN_ERR_GRIDCREATE;
2461 //
2462 // GDALClose(pDataSet);
2463 // // DEBUG CODE ===========================================================================================================
2464
2465 // // DEBUG CODE ===========================================================================================================
2466 // strOutFile = m_strOutPath;
2467 // strOutFile += "init_deep_water_wave_angle_";
2468 // strOutFile += to_string(m_ulIter);
2469 // strOutFile += ".tif";
2470 // pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
2471 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
2472 // pDataSet->SetGeoTransform(m_dGeoTransform);
2473 // nn = 0;
2474 // for (int nY = 0; nY < m_nYGridSize; nY++)
2475 // {
2476 // for (int nX = 0; nX < m_nXGridSize; nX++)
2477 // {
2478 // // Write this value to the array
2479 // pdRaster[nn] = m_pRasterGrid->m_Cell[nX][nY].dGetCellDeepWaterWaveAngle();
2480 // nn++;
2481 // }
2482 // }
2483 //
2484 // pBand = pDataSet->GetRasterBand(1);
2485 // pBand->SetNoDataValue(m_nMissingValue);
2486 // nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
2487 //
2488 // if (nRet == CE_Failure)
2489 // return RTN_ERR_GRIDCREATE;
2490 //
2491 // GDALClose(pDataSet);
2492 // delete[] pdRaster;
2493 // // DEBUG CODE ===========================================================================================================
2494
2495 return RTN_OK;
2496}
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:530
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:458
int m_nYMinBoundingBox
The minimum y value of the bounding box.
Definition simulation.h:500
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:667
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:431
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:547
double m_dSouthEastXExtCRS
The south-east x coordinate, in the external coordinate reference system (CRS)
Definition simulation.h:604
int m_nMissingValue
The value used for integer missing values.
Definition simulation.h:491
int m_nYGridSize
The size of the grid in the y direction.
Definition simulation.h:434
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:652
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:910
double m_dInvCellDiagonal
Inverse of m_dCellDiagonal.
Definition simulation.h:625
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:562
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:347
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:497
double m_dNorthWestYExtCRS
The north-west y coordinate, in the external coordinate reference system (CRS)
Definition simulation.h:601
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:592
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:706
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:619
double m_dInvCellSide
Inverse of m_dCellSide.
Definition simulation.h:622
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:634
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:598
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:607
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:422
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:503
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:461
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:550
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:631
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:494
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:616
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:356
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:553
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:610
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:613
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:544
bool m_bGDALCanWriteFloat
Is the selected GDAL output file format capable of writing floating-point values to files?
Definition simulation.h:350
char ** m_papszGDALRasterOptions
Options for GDAL when handling raster files.
Definition simulation.h:425
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:652
int const INT_NODATA
Definition cme.h:362
int const RASTER_PLOT_POLYGON
Definition cme.h:521
string const RASTER_SEA_DEPTH_NAME
Definition cme.h:826
T tMin(T a, T b)
Definition cme.h:1136
double const TOLERANCE
Definition cme.h:698
string const RASTER_SHADOW_DOWNDRIFT_ZONE_NAME
Definition cme.h:922
string const RASTER_POTENTIAL_BEACH_EROSION_NAME
Definition cme.h:856
string const RASTER_BEACH_MASK_NAME
Definition cme.h:842
string const RASTER_TOTAL_CLIFF_COLLAPSE_DEPOSITION_SAND_NAME
Definition cme.h:912
string const RASTER_POLYGON_UPDRIFT_OR_DOWNDRIFT_NAME
Definition cme.h:930
int const RASTER_PLOT_LOCAL_SLOPE_OF_CONSOLIDATED_SEDIMENT
Definition cme.h:518
int const RASTER_PLOT_TOTAL_ACTUAL_BEACH_EROSION
Definition cme.h:534
int const RASTER_PLOT_BEACH_DEPOSITION
Definition cme.h:498
int const RASTER_PLOT_SUSPENDED_SEDIMENT
Definition cme.h:533
string const RASTER_FINE_CONS_NAME
Definition cme.h:884
string const RASTER_SLICE_NAME
Definition cme.h:918
int const RTN_ERR_DEMFILE
Definition cme.h:590
int const RASTER_PLOT_FINE_UNCONSOLIDATED_SEDIMENT
Definition cme.h:513
string const RASTER_TOP_NAME
Definition cme.h:820
string const RASTER_BEACH_DEPOSITION_NAME
Definition cme.h:864
int const SAND_CONS_RASTER
Definition cme.h:454
string const RASTER_BEACH_PROTECTION_NAME
Definition cme.h:844
int const RTN_ERR_MEMALLOC
Definition cme.h:593
string const ERR
Definition cme.h:775
int const RASTER_PLOT_INUNDATION_MASK
Definition cme.h:516
int const RASTER_PLOT_SEDIMENT_TOP_ELEVATION_ELEV
Definition cme.h:529
string const RASTER_SAND_UNCONS_NAME
Definition cme.h:880
int const RASTER_PLOT_ACTUAL_BEACH_EROSION
Definition cme.h:491
string const RASTER_INUNDATION_MASK_NAME
Definition cme.h:830
string const RASTER_WAVE_PERIOD_NAME
Definition cme.h:838
int const RASTER_PLOT_POTENTIAL_PLATFORM_EROSION_MASK
Definition cme.h:546
int const RASTER_PLOT_TOTAL_CLIFF_COLLAPSE_DEPOSIT_COARSE
Definition cme.h:541
int const RTN_ERR_GRIDCREATE
Definition cme.h:634
int const RASTER_PLOT_SAND_CONSOLIDATED_SEDIMENT
Definition cme.h:526
int const RASTER_PLOT_AVG_WAVE_HEIGHT
Definition cme.h:495
string const RASTER_CLIFF_COLLAPSE_EROSION_SAND_NAME
Definition cme.h:898
string const RASTER_SEDIMENT_TOP_NAME
Definition cme.h:818
string const RASTER_FINE_UNCONS_NAME
Definition cme.h:878
string const RASTER_COAST_NAME
Definition cme.h:890
int const LF_CAT_DRIFT
Definition cme.h:430
int const RASTER_PLOT_FINE_CONSOLIDATED_SEDIMENT
Definition cme.h:512
string const RASTER_CLIFF_COLLAPSE_EROSION_FINE_NAME
Definition cme.h:896
int const RASTER_PLOT_TOTAL_CLIFF_COLLAPSE_DEPOSIT_SAND
Definition cme.h:540
string const RASTER_SEDIMENT_INPUT_EVENT_NAME
Definition cme.h:934
string const RASTER_CLIFF_COLLAPSE_DEPOSITION_SAND_NAME
Definition cme.h:908
int const RASTER_PLOT_ACTIVE_ZONE
Definition cme.h:490
string const RASTER_ACTIVE_ZONE_NAME
Definition cme.h:894
int const LOG_FILE_MIDDLE_DETAIL
Definition cme.h:377
string const RASTER_INTERVENTION_HEIGHT_NAME
Definition cme.h:872
string const RASTER_SHADOW_ZONE_NAME
Definition cme.h:920
int const RASTER_PLOT_DEEP_WATER_WAVE_PERIOD
Definition cme.h:511
int const RTN_ERR_RASTER_FILE_READ
Definition cme.h:591
string const RASTER_COARSE_CONS_NAME
Definition cme.h:888
string const RASTER_TOTAL_CLIFF_COLLAPSE_EROSION_SAND_NAME
Definition cme.h:904
int const RASTER_PLOT_CLIFF_COLLAPSE_DEPOSIT_SAND
Definition cme.h:504
double const PI
Definition cme.h:680
int const RASTER_PLOT_COAST
Definition cme.h:508
string const RASTER_ACTUAL_BEACH_EROSION_NAME
Definition cme.h:858
string const RASTER_SETUP_SURGE_RUNUP_FLOOD_MASK_NAME
Definition cme.h:938
bool bFPIsEqual(const T d1, const T d2, const T dEpsilon)
Definition cme.h:1176
string const RASTER_AVG_WAVE_ORIENTATION_NAME
Definition cme.h:840
string const RASTER_TOTAL_BEACH_DEPOSITION_NAME
Definition cme.h:866
int const RASTER_PLOT_POLYGON_UPDRIFT_OR_DOWNDRIFT
Definition cme.h:523
string const RASTER_TOTAL_CLIFF_COLLAPSE_DEPOSITION_COARSE_NAME
Definition cme.h:914
int const RASTER_PLOT_POLYGON_GAIN_OR_LOSS
Definition cme.h:522
int const RASTER_PLOT_DEEP_WATER_WAVE_ORIENTATION
Definition cme.h:510
int const RASTER_PLOT_TOTAL_CLIFF_COLLAPSE_EROSION_COARSE
Definition cme.h:539
int const RTN_ERR_BOUNDING_BOX
Definition cme.h:640
int const RASTER_PLOT_COARSE_UNCONSOLIDATED_SEDIMENT
Definition cme.h:507
int const RASTER_PLOT_AVG_WAVE_ORIENTATION
Definition cme.h:496
int const RASTER_PLOT_WAVE_ORIENTATION
Definition cme.h:545
string const RASTER_SUSP_SED_NAME
Definition cme.h:874
string const RASTER_LOCAL_SLOPE_NAME
Definition cme.h:824
int const RASTER_PLOT_BEACH_MASK
Definition cme.h:499
string const RASTER_AVG_SEA_DEPTH_NAME
Definition cme.h:828
int const RASTER_PLOT_WAVE_FLOOD_LINE
Definition cme.h:550
int const RASTER_PLOT_SEDIMENT_INPUT
Definition cme.h:547
int const RASTER_PLOT_POTENTIAL_BEACH_EROSION
Definition cme.h:524
int const RASTER_PLOT_AVG_SUSPENDED_SEDIMENT
Definition cme.h:494
string const RASTER_AVG_WAVE_HEIGHT_NAME
Definition cme.h:834
int const RASTER_PLOT_TOTAL_POTENTIAL_PLATFORM_EROSION
Definition cme.h:543
string const RASTER_WAVE_FLOOD_LINE_NAME
Definition cme.h:940
string const RASTER_POTENTIAL_PLATFORM_EROSION_NAME
Definition cme.h:848
int const INTERVENTION_CLASS_RASTER
Definition cme.h:461
string const RASTER_ACTUAL_PLATFORM_EROSION_NAME
Definition cme.h:850
string const RASTER_COARSE_UNCONS_NAME
Definition cme.h:882
int const RASTER_PLOT_INTERVENTION_CLASS
Definition cme.h:514
string const WARN
Definition cme.h:776
int const RASTER_PLOT_BEACH_PROTECTION
Definition cme.h:500
int const RASTER_PLOT_AVG_SEA_DEPTH
Definition cme.h:493
int const RASTER_PLOT_CLIFF_COLLAPSE_DEPOSIT_COARSE
Definition cme.h:505
int const RASTER_PLOT_OVERALL_TOP_ELEVATION
Definition cme.h:520
int const RASTER_PLOT_TOTAL_BEACH_DEPOSITION
Definition cme.h:536
string const RASTER_SETUP_SURGE_FLOOD_MASK_NAME
Definition cme.h:936
string const RASTER_INTERVENTION_CLASS_NAME
Definition cme.h:870
int const RASTER_PLOT_TOTAL_CLIFF_COLLAPSE_EROSION_FINE
Definition cme.h:537
string const RASTER_WAVE_ORIENTATION_NAME
Definition cme.h:836
int const RASTER_PLOT_TOTAL_CLIFF_COLLAPSE_EROSION_SAND
Definition cme.h:538
string const RASTER_DEEP_WATER_WAVE_ORIENTATION_NAME
Definition cme.h:924
string const RASTER_POTENTIAL_PLATFORM_EROSION_MASK_NAME
Definition cme.h:846
int const RASTER_PLOT_CLIFF_COLLAPSE_EROSION_FINE
Definition cme.h:501
int const SOUTH
Definition cme.h:387
int const RASTER_PLOT_ACTUAL_PLATFORM_EROSION
Definition cme.h:492
int const LOG_FILE_ALL
Definition cme.h:379
int const EAST
Definition cme.h:385
int const RTN_OK
Definition cme.h:577
string const RASTER_WAVE_HEIGHT_NAME
Definition cme.h:832
int const RASTER_PLOT_INTERVENTION_HEIGHT
Definition cme.h:515
int const SAND_UNCONS_RASTER
Definition cme.h:457
int const RASTER_PLOT_TOTAL_POTENTIAL_BEACH_EROSION
Definition cme.h:542
string const RASTER_TOTAL_POTENTIAL_BEACH_EROSION_NAME
Definition cme.h:860
int const RASTER_PLOT_SAND_UNCONSOLIDATED_SEDIMENT
Definition cme.h:527
string const RASTER_SAND_CONS_NAME
Definition cme.h:886
int const RASTER_PLOT_POTENTIAL_PLATFORM_EROSION
Definition cme.h:525
string const RASTER_BASEMENT_ELEVATION_NAME
Definition cme.h:822
int const FINE_UNCONS_RASTER
Definition cme.h:456
int const COARSE_UNCONS_RASTER
Definition cme.h:458
double const DBL_NODATA
Definition cme.h:707
int const RASTER_PLOT_WAVE_HEIGHT
Definition cme.h:544
int const RASTER_PLOT_SHADOW_ZONE
Definition cme.h:531
int const RASTER_PLOT_DEEP_WATER_WAVE_HEIGHT
Definition cme.h:509
string const RASTER_COAST_NORMAL_NAME
Definition cme.h:892
string const NOTE
Definition cme.h:777
string const RASTER_CLIFF_COLLAPSE_EROSION_COARSE_NAME
Definition cme.h:900
int const RASTER_PLOT_COARSE_CONSOLIDATED_SEDIMENT
Definition cme.h:506
string const RASTER_LANDFORM_NAME
Definition cme.h:868
int const RASTER_PLOT_TOTAL_ACTUAL_PLATFORM_EROSION
Definition cme.h:535
int const SUSP_SED_RASTER
Definition cme.h:459
int const FINE_CONS_RASTER
Definition cme.h:453
int const COARSE_CONS_RASTER
Definition cme.h:455
int const LF_CAT_CLIFF
Definition cme.h:429
int const RASTER_PLOT_SETUP_SURGE_RUNUP_FLOOD_MASK
Definition cme.h:549
int const RASTER_PLOT_BASEMENT_ELEVATION
Definition cme.h:497
int const RASTER_PLOT_LANDFORM
Definition cme.h:517
string const RASTER_TOTAL_ACTUAL_PLATFORM_EROSION_NAME
Definition cme.h:854
string const RASTER_POLYGON_NAME
Definition cme.h:916
int const RASTER_PLOT_CLIFF_COLLAPSE_EROSION_COARSE
Definition cme.h:503
T tAbs(T a)
Definition cme.h:1148
string const RASTER_TOTAL_CLIFF_COLLAPSE_EROSION_FINE_NAME
Definition cme.h:902
int const LANDFORM_RASTER
Definition cme.h:460
int const RASTER_PLOT_SHADOW_DOWNDRIFT_ZONE
Definition cme.h:530
int const RASTER_PLOT_SLICE
Definition cme.h:532
string const RASTER_TOTAL_POTENTIAL_PLATFORM_EROSION_NAME
Definition cme.h:852
string const RASTER_AVG_SUSP_SED_NAME
Definition cme.h:876
string const RASTER_DEEP_WATER_WAVE_HEIGHT_NAME
Definition cme.h:926
int const INTERVENTION_HEIGHT_RASTER
Definition cme.h:462
string const RASTER_TOTAL_CLIFF_COLLAPSE_EROSION_COARSE_NAME
Definition cme.h:906
string const RASTER_POLYGON_GAIN_OR_LOSS_NAME
Definition cme.h:932
string const RASTER_TOTAL_ACTUAL_BEACH_EROSION_NAME
Definition cme.h:862
int const RASTER_PLOT_CLIFF_COLLAPSE_EROSION_SAND
Definition cme.h:502
int const RASTER_PLOT_SEA_DEPTH
Definition cme.h:528
int const NORTH
Definition cme.h:383
string const RASTER_CLIFF_COLLAPSE_DEPOSITION_COARSE_NAME
Definition cme.h:910
int const RASTER_PLOT_SETUP_SURGE_FLOOD_MASK
Definition cme.h:548
int const RASTER_PLOT_NORMAL
Definition cme.h:519
int const WEST
Definition cme.h:389
Contains CRWCoast definitions.
Contains CGeomRasterGrid definitions.
Contains CSimulation definitions.
double dRound(double const d)
Correctly rounds doubles.