CoastalME (Coastal Modelling Environment)
Simulates the long-term behaviour of complex coastlines
Loading...
Searching...
No Matches
locate_coast.cpp
Go to the documentation of this file.
1
12
13/* ==============================================================================================================================
14
15 This file is part of CoastalME, the Coastal Modelling Environment.
16
17 CoastalME 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
19 This 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
21 You 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#include <cfloat>
26
27#include <iostream>
28using std::cerr;
29using std::endl;
30using std::ios;
31
32#include <stack>
33using std::stack;
34
35#include "cme.h"
36#include "2di_point.h"
37#include "i_line.h"
38#include "line.h"
39#include "simulation.h"
40#include "raster_grid.h"
41#include "coast.h"
42
43//===============================================================================================================================
45//===============================================================================================================================
47{
48 // Find all connected sea cells
50
51 // Find every coastline on the raster grid, mark raster cells, then create the vector coastline
52 int const nRet = nTraceAllCoasts(nValidCoast);
53
54 if (nRet != RTN_OK)
55 return nRet;
56
57 // Have we created any coasts?
58 if (m_VCoast.empty())
59 {
60 cerr << m_ulIter << ": " << ERR << "no coastline located: this iteration SWL = " << m_dThisIterSWL << ", maximum DEM top surface elevation = " << m_dThisIterTopElevMax << ", minimum DEM top surface elevation = " << m_dThisIterTopElevMin << endl;
61 return RTN_ERR_NOCOAST;
62 }
63
64 return RTN_OK;
65}
66
67//===============================================================================================================================
69//===============================================================================================================================
71{
72 // Go along the list of edge cells
73 for (unsigned int n = 0; n < m_VEdgeCell.size(); n++)
74 {
76 continue;
77
79 continue;
80
82 continue;
83
85 continue;
86
87 int const nX = m_VEdgeCell[n].nGetX();
88 int const nY = m_VEdgeCell[n].nGetY();
89
90 if ((m_pRasterGrid->m_Cell[nX][nY].bIsInundated()) && (bFPIsEqual(m_pRasterGrid->m_Cell[nX][nY].dGetSeaDepth(), 0.0, TOLERANCE)))
91 // This edge cell is below SWL and sea depth remains set to zero
92 CellByCellFillSea(nX, nY);
93 }
94}
95
96//===============================================================================================================================
98//===============================================================================================================================
99void CSimulation::CellByCellFillSea(int const nXStart, int const nYStart)
100{
101 // For safety check
102 int const nRoundLoopMax = m_nXGridSize * m_nYGridSize;
103
104 // Create an empty stack
105 stack<CGeom2DIPoint> PtiStack;
106
107 // Start at the given edge cell, push this onto the stack
108 PtiStack.push(CGeom2DIPoint(nXStart, nYStart));
109
110 // Then do the cell-by-cell fill loop until there are no more cell coordinates on the stack
111 int nRoundLoop = 0;
112
113 while (! PtiStack.empty())
114 {
115 // Safety check
116 if (nRoundLoop++ > nRoundLoopMax)
117 break;
118
119 CGeom2DIPoint const Pti = PtiStack.top();
120 PtiStack.pop();
121
122 int nX = Pti.nGetX();
123 int const nY = Pti.nGetY();
124
125 while ((nX >= 0) && (!m_pRasterGrid->m_Cell[nX][nY].bBasementElevIsMissingValue()) && (m_pRasterGrid->m_Cell[nX][nY].bIsInundated()))
126 nX--;
127
128 nX++;
129
130 bool bSpanAbove = false;
131 bool bSpanBelow = false;
132
133 while ((nX < m_nXGridSize) && (!m_pRasterGrid->m_Cell[nX][nY].bBasementElevIsMissingValue()) && (m_pRasterGrid->m_Cell[nX][nY].bIsInundated()) && (bFPIsEqual(m_pRasterGrid->m_Cell[nX][nY].dGetSeaDepth(), 0.0, TOLERANCE)))
134 {
135 // Set the sea depth for this cell
136 m_pRasterGrid->m_Cell[nX][nY].SetSeaDepth();
137
138 CRWCellLandform* pLandform = m_pRasterGrid->m_Cell[nX][nY].pGetLandform();
139 int const nCat = pLandform->nGetLFCategory();
140
141 // Have we had sediment input here?
143 {
144 if (m_pRasterGrid->m_Cell[nX][nY].bIsInundated())
145 {
147 m_pRasterGrid->m_Cell[nX][nY].SetInContiguousSea();
148
149 // Set this sea cell to have deep water (off-shore) wave orientation and height, will change this later for cells closer to the shoreline if we have on-shore waves
150 m_pRasterGrid->m_Cell[nX][nY].SetWaveValuesToDeepWaterWaveValues();
151 }
152
153 else
154 {
156 }
157 }
158
159 else
160 {
161 // No sediment input here, just mark as sea
162 m_pRasterGrid->m_Cell[nX][nY].SetInContiguousSea();
163 pLandform->SetLFCategory(LF_CAT_SEA);
164
165 // Set this sea cell to have deep water (off-shore) wave orientation and height, will change this later for cells closer to the shoreline if we have on-shore waves
166 m_pRasterGrid->m_Cell[nX][nY].SetWaveValuesToDeepWaterWaveValues();
167 }
168
169 // Now sort out the x-y extremities of the contiguous sea for the bounding box (used later in wave propagation)
170 if (nX < m_nXMinBoundingBox)
172
173 if (nX > m_nXMaxBoundingBox)
175
176 if (nY < m_nYMinBoundingBox)
178
179 if (nY > m_nYMaxBoundingBox)
181
182 // Update count
184
185 if ((! bSpanAbove) && (nY > 0) && (!m_pRasterGrid->m_Cell[nX][nY - 1].bBasementElevIsMissingValue()) && (m_pRasterGrid->m_Cell[nX][nY - 1].bIsInundated()))
186 {
187 PtiStack.push(CGeom2DIPoint(nX, nY - 1));
188 bSpanAbove = true;
189 }
190
191 else if (bSpanAbove && (nY > 0) && (!m_pRasterGrid->m_Cell[nX][nY - 1].bBasementElevIsMissingValue()) && (!m_pRasterGrid->m_Cell[nX][nY - 1].bIsInundated()))
192 {
193 bSpanAbove = false;
194 }
195
196 if ((! bSpanBelow) && (nY < m_nYGridSize - 1) && (!m_pRasterGrid->m_Cell[nX][nY + 1].bBasementElevIsMissingValue()) && (m_pRasterGrid->m_Cell[nX][nY + 1].bIsInundated()))
197 {
198 PtiStack.push(CGeom2DIPoint(nX, nY + 1));
199 bSpanBelow = true;
200 }
201
202 else if (bSpanBelow && (nY < m_nYGridSize - 1) && (!m_pRasterGrid->m_Cell[nX][nY + 1].bBasementElevIsMissingValue()) && (!m_pRasterGrid->m_Cell[nX][nY + 1].bIsInundated()))
203 {
204 bSpanBelow = false;
205 }
206
207 nX++;
208 }
209 }
210
211 // // DEBUG CODE ===========================================================================================================
212 // string strOutFile = m_strOutPath + "is_contiguous_sea_";
213 // strOutFile += to_string(m_ulIter);
214 // strOutFile += ".tif";
215 //
216 // GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("gtiff");
217 // GDALDataset* pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
218 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
219 // pDataSet->SetGeoTransform(m_dGeoTransform);
220 // double* pdRaster = new double[m_nXGridSize * m_nYGridSize];
221 // int n = 0;
222 // for (int nY = 0; nY < m_nYGridSize; nY++)
223 // {
224 // for (int nX = 0; nX < m_nXGridSize; nX++)
225 // {
226 // pdRaster[n++] = m_pRasterGrid->m_Cell[nX][nY].bIsInContiguousSea();
227 // }
228 // }
229 //
230 // GDALRasterBand* pBand = pDataSet->GetRasterBand(1);
231 // pBand->SetNoDataValue(m_dMissingValue);
232 // int nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
233 // if (nRet == CE_Failure)
234 // return;
235 //
236 // GDALClose(pDataSet);
237 // delete[] pdRaster;
238 // // DEBUG CODE ===========================================================================================================
239
240 // // DEBUG CODE ===========================================================================================================
241 // string strOutFile = m_strOutPath + "is_inundated_";
242 // strOutFile += to_string(m_ulIter);
243 // strOutFile += ".tif";
244 //
245 // GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("gtiff");
246 // GDALDataset* pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
247 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
248 // pDataSet->SetGeoTransform(m_dGeoTransform);
249 // double* pdRaster = new double[m_nXGridSize * m_nYGridSize];
250 //
251 // pDataSet = pDriver->Create(strOutFile.c_str(), m_nXGridSize, m_nYGridSize, 1, GDT_Float64, m_papszGDALRasterOptions);
252 // pDataSet->SetProjection(m_strGDALBasementDEMProjection.c_str());
253 // pDataSet->SetGeoTransform(m_dGeoTransform);
254 //
255 // pdRaster = new double[m_nXGridSize * m_nYGridSize];
256 // int n = 0;
257 // for (int nY = 0; nY < m_nYGridSize; nY++)
258 // {
259 // for (int nX = 0; nX < m_nXGridSize; nX++)
260 // {
261 // pdRaster[n++] = m_pRasterGrid->m_Cell[nX][nY].bIsInundated();
262 // }
263 // }
264 //
265 // GDALRasterBand* pBand = pDataSet->GetRasterBand(1);
266 // pBand = pDataSet->GetRasterBand(1);
267 // pBand->SetNoDataValue(m_dMissingValue);
268 // int nRet = pBand->RasterIO(GF_Write, 0, 0, m_nXGridSize, m_nYGridSize, pdRaster, m_nXGridSize, m_nYGridSize, GDT_Float64, 0, 0, NULL);
269 // if (nRet == CE_Failure)
270 // return;
271 //
272 // GDALClose(pDataSet);
273 // delete[] pdRaster;
274 // // DEBUG CODE ===========================================================================================================
275
276 // // DEBUG CODE ===========================================================================================================
277 // LogStream << m_ulIter << ": cell-by-cell fill of sea from [" << nXStart << "][" << nYStart << "] = {" << dGridCentroidXToExtCRSX(nXStart) << ", " << dGridCentroidYToExtCRSY(nYStart) << "} with SWL = " << m_dThisIterSWL << ", " << m_ulThisIterNumSeaCells << " of " << m_ulNumCells << " cells now marked as sea (" << fixed << setprecision(3) << 100.0 * m_ulThisIterNumSeaCells / m_ulNumCells << " %)" << endl;
278
279 // LogStream << " m_nXMinBoundingBox = " << m_nXMinBoundingBox << " m_nXMaxBoundingBox = " << m_nXMaxBoundingBox << " m_nYMinBoundingBox = " << m_nYMinBoundingBox << " m_nYMaxBoundingBox = " << m_nYMaxBoundingBox << endl;
280 // // DEBUG CODE ===========================================================================================================
281}
282
283//===============================================================================================================================
285//===============================================================================================================================
286int CSimulation::nTraceAllCoasts(int& nValidCoast)
287{
289 LogStream << m_ulIter << ": Tracing coast" << endl;
290
291 vector<bool> VbPossibleStartCellLHEdge;
292 vector<bool> VbTraced;
293 vector<int> VnSearchDirection;
294 vector<CGeom2DIPoint> V2DIPossibleStartCell;
295
296 // Go along the list of edge cells and look for possible coastline start/finish cells
297 for (unsigned int n = 0; n < m_VEdgeCell.size() - 1; n++)
298 {
300 continue;
301
303 continue;
304
306 continue;
307
309 continue;
310
311 int const nXThis = m_VEdgeCell[n].nGetX();
312 int const nYThis = m_VEdgeCell[n].nGetY();
313 int const nXNext = m_VEdgeCell[n + 1].nGetX();
314 int const nYNext = m_VEdgeCell[n + 1].nGetY();
315
316 // Get "Is it sea?" information for 'this' and 'next' cells
317 bool const bThisCellIsSea = m_pRasterGrid->m_Cell[nXThis][nYThis].bIsInContiguousSea();
318 bool const bNextCellIsSea = m_pRasterGrid->m_Cell[nXNext][nYNext].bIsInContiguousSea();
319
320 // Are we at a coast?
321 if ((! bThisCellIsSea) && bNextCellIsSea)
322 {
323 // 'This' cell is just inland, has it already been flagged as a possible start for a coastline (even if this subsequently 'failed' as a coastline)?
324 if (! m_pRasterGrid->m_Cell[nXThis][nYThis].bIsPossibleCoastStartCell())
325 {
326 // It has not, so flag it
327 m_pRasterGrid->m_Cell[nXThis][nYThis].SetPossibleCoastStartCell();
328
330 LogStream << m_ulIter << ": Flagging [" << nXThis << "][" << nYThis << "] = {" << dGridCentroidXToExtCRSX(nXThis) << ", " << dGridCentroidYToExtCRSY(nYThis) << "} as possible coast start cell (left_handed edge)" << endl;
331
332 // And save it
333 V2DIPossibleStartCell.push_back(CGeom2DIPoint(nXThis, nYThis));
334 VbPossibleStartCellLHEdge.push_back(true);
335 VnSearchDirection.push_back(nGetOppositeDirection(m_VEdgeCellEdge[n]));
336 VbTraced.push_back(false);
337 }
338 }
339 else if (bThisCellIsSea && (! bNextCellIsSea))
340 {
341 // The 'next' cell is just inland, has it already been flagged as a possible start for a coastline (even if this subsequently 'failed' as a coastline)?
342 if (! m_pRasterGrid->m_Cell[nXNext][nYNext].bIsPossibleCoastStartCell())
343 {
344 // It has not, so flag it
345 m_pRasterGrid->m_Cell[nXNext][nYNext].SetPossibleCoastStartCell();
346
348 LogStream << m_ulIter << ": Flagging [" << nXNext << "][" << nYNext << "] = {" << dGridCentroidXToExtCRSX(nXNext) << ", " << dGridCentroidYToExtCRSY(nYNext) << "} as possible coast start cell (right_handed edge)" << endl;
349
350 // And save it
351 V2DIPossibleStartCell.push_back(CGeom2DIPoint(nXNext, nYNext));
352 VbPossibleStartCellLHEdge.push_back(false);
353 VnSearchDirection.push_back(nGetOppositeDirection(m_VEdgeCellEdge[n + 1]));
354 VbTraced.push_back(false);
355 }
356 }
357 }
358
359 // Any possible coastline start/finish cells found?
360 if (V2DIPossibleStartCell.size() == 0)
361 {
362 LogStream << m_ulIter << ": no coastline start/finish points found after grid edges searched.";
363
365 {
366 LogStream << " Note that the following grid edges were not searched: " << (m_bOmitSearchNorthEdge ? "N " : "") << (m_bOmitSearchSouthEdge ? "S " : "") << (m_bOmitSearchWestEdge ? "W " : "") << (m_bOmitSearchEastEdge ? "E " : "");
367 }
368
369 LogStream << endl;
370
372 }
373
374 // Some possible coastline start/finish points were found
375 LogStream << m_ulIter << ": " << V2DIPossibleStartCell.size() << " possible coastline start/finish points found" << endl;
376
377 // OK, so trace from each of these possible start/finish points
378 for (unsigned int n = 0; n < V2DIPossibleStartCell.size(); n++)
379 {
380 if (! VbTraced[n])
381 {
382 int nRet = 0;
383
384 if (VbPossibleStartCellLHEdge[n])
385 {
386 nRet = nTraceCoastLine(n, VnSearchDirection[n], LEFT_HANDED, &VbTraced, &V2DIPossibleStartCell);
387 }
388 else
389 {
390 nRet = nTraceCoastLine(n, VnSearchDirection[n], RIGHT_HANDED, &VbTraced, &V2DIPossibleStartCell);
391 }
392
393 if (nRet == RTN_OK)
394 {
395 // We have a valid coastline starting from this possible start cell
396 VbTraced[n] = true;
397 nValidCoast++;
398 }
399 }
400 }
401
402 if (nValidCoast > 0)
403 return RTN_OK;
404 else
405 {
406 cerr << m_ulIter << ": no valid coasts found, see " << m_strLogFile << " for more information" << endl;
408 }
409}
410
411//===============================================================================================================================
413//===============================================================================================================================
414int CSimulation::nTraceCoastLine(unsigned int const nTraceFromStartCellIndex, int const nStartSearchDirection, int const nHandedness, vector<bool>* pVbTraced, vector<CGeom2DIPoint> const* pV2DIPossibleStartCell)
415{
416 bool bHitStartCell = false;
417 bool bAtCoast = false;
418 bool bHasLeftStartEdge = false;
419 bool bTooLong = false;
420 bool bOffEdge = false;
421 bool bRepeating = false;
422
423 int const nStartX = pV2DIPossibleStartCell->at(nTraceFromStartCellIndex).nGetX();
424 int const nStartY = pV2DIPossibleStartCell->at(nTraceFromStartCellIndex).nGetY();
425 int nX = nStartX;
426 int nY = nStartY;
427 int nSearchDirection = nStartSearchDirection;
428 int nRoundLoop = -1;
429 // nThisLen = 0;
430 // nLastLen = 0,
431 // nPreLastLen = 0;
432
433 // Temporary coastline as integer points (grid CRS)
434 CGeomILine ILTempGridCRS;
435
436 // Add the start cell to the vector
437 CGeom2DIPoint const PtiStart(nStartX, nStartY);
438 ILTempGridCRS.Append(&PtiStart);
439
440 // Start at this grid-edge point and trace the rest of the coastline using the 'wall follower' rule for maze traversal, trying to keep next to cells flagged as sea
441 do
442 {
443 // // DEBUG CODE ==============================================================================================================
444 // LogStream << "Now at [" << nX << "][" << nY << "] = {" << dGridCentroidXToExtCRSX(nX) << ", " << dGridCentroidYToExtCRSY(nY) << "}" << endl;
445 // LogStream << "ILTempGridCRS is now:" << endl;
446 // for (int n = 0; n < ILTempGridCRS.nGetSize(); n++)
447 // LogStream << "[" << ILTempGridCRS[n].nGetX() << "][" << ILTempGridCRS[n].nGetY() << "] = {" << dGridCentroidXToExtCRSX(ILTempGridCRS[n].nGetX()) << ", " << dGridCentroidYToExtCRSY(ILTempGridCRS[n].nGetY()) << "}" << endl;
448 // LogStream << "=================" << endl;
449 // // DEBUG CODE ==============================================================================================================
450
451 // Safety check
452 if (++nRoundLoop > m_nCoastMax)
453 {
454 bTooLong = true;
455
456 // LogStream << m_ulIter << ": abandoning coastline tracing from [" << nStartX << "][" << nStartY << "] = {" << dGridCentroidXToExtCRSX(nStartX) << ", " << dGridCentroidYToExtCRSY(nStartY) << "}, exceeded maximum search length (" << m_nCoastMax << ")" << endl;
457
458 // for (int n = 0; n < ILTempGridCRS.nGetSize(); n++)
459 // LogStream << "[" << ILTempGridCRS[n].nGetX() << "][" << ILTempGridCRS[n].nGetY() << "] = {" << dGridCentroidXToExtCRSX(ILTempGridCRS[n].nGetX()) << ", " << dGridCentroidYToExtCRSY(ILTempGridCRS[n].nGetY()) << "}" << endl;
460 // LogStream << endl;
461
462 break;
463 }
464
465 // Another safety check
466 if ((nRoundLoop > 10) && (ILTempGridCRS.nGetSize() < 2))
467 {
468 // We've been 10 times round the loop but the coast is still less than 2 coastline points in length, so we must be repeating
469 bRepeating = true;
470
471 break;
472 }
473
474 // OK so far: so have we left the start edge?
475 if (! bHasLeftStartEdge)
476 {
477 // We have not yet left the start edge
478 if (((nStartSearchDirection == SOUTH) && (nY > nStartY)) || ((nStartSearchDirection == NORTH) && (nY < nStartY)) ||
479 ((nStartSearchDirection == EAST) && (nX > nStartX)) || ((nStartSearchDirection == WEST) && (nX < nStartX)))
480 bHasLeftStartEdge = true;
481
482 // Flag this cell to ensure that it is not chosen as a coastline start cell later
483 m_pRasterGrid->m_Cell[nX][nY].SetPossibleCoastStartCell();
484 // LogStream << "Flagging [" << nX << "][" << nY << "] as possible coast start cell NOT YET LEFT EDGE" << endl;
485 }
486
487 // Leave the loop if the vector coastline has left the start edge, then we find a coast cell which is a possible start cell from which a coastline has not yet been traced
488 // if (bHasLeftStartEdge && bAtCoast)
489 {
490 for (unsigned int nn = 0; nn < pVbTraced->size(); nn++)
491 {
492 if ((nn != nTraceFromStartCellIndex) && (! pVbTraced->at(nn)))
493 {
494 // LogStream << "[" << pV2DIPossibleStartCell->at(nn).nGetX() << "][" << pV2DIPossibleStartCell->at(nn).nGetY() << "]" << endl;
495
496 if (bAtCoast && (nX == pV2DIPossibleStartCell->at(nn).nGetX()) && (nY == pV2DIPossibleStartCell->at(nn).nGetY()))
497 {
499 LogStream << m_ulIter << ": Possible coastline found, traced from [" << nStartX << "][" << nStartY << "] and hit another possible coast start cell at [" << nX << "][" << nY << "]" << endl;
500
501 pVbTraced->at(nn) = true;
502 bHitStartCell = true;
503 break;
504 }
505 }
506 }
507
508 // LogStream << endl;
509 }
510
511 if (bHitStartCell)
512 break;
513
514 // OK now sort out the next iteration of the search
515 int nXSeaward = 0;
516 int nYSeaward = 0;
517 int nSeawardNewDirection = 0;
518 int nXStraightOn = 0;
519 int nYStraightOn = 0;
520 int nXAntiSeaward = 0;
521 int nYAntiSeaward = 0;
522 int nAntiSeawardNewDirection = 0;
523 int nXGoBack = 0;
524 int nYGoBack = 0;
525 int nGoBackNewDirection = 0;
526
527 CGeom2DIPoint const Pti(nX, nY);
528
529 // Set up the variables
530 switch (nHandedness)
531 {
532 case RIGHT_HANDED:
533
534 // The sea is to the right-hand side of the coast as we traverse it. We are just inland, so we need to keep heading right to find the sea
535 switch (nSearchDirection)
536 {
537 case NORTH:
538 // The sea is towards the RHS (E) of the coast, so first try to go right (to the E)
539 nXSeaward = nX + 1;
540 nYSeaward = nY;
541 nSeawardNewDirection = EAST;
542
543 // If can't do this, try to go straight on (to the N)
544 nXStraightOn = nX;
545 nYStraightOn = nY - 1;
546
547 // If can't do either of these, try to go anti-seaward i.e. towards the LHS (W)
548 nXAntiSeaward = nX - 1;
549 nYAntiSeaward = nY;
550 nAntiSeawardNewDirection = WEST;
551
552 // As a last resort, go back (to the S)
553 nXGoBack = nX;
554 nYGoBack = nY + 1;
555 nGoBackNewDirection = SOUTH;
556
557 break;
558
559 case EAST:
560 // The sea is towards the RHS (S) of the coast, so first try to go right (to the S)
561 nXSeaward = nX;
562 nYSeaward = nY + 1;
563 nSeawardNewDirection = SOUTH;
564
565 // If can't do this, try to go straight on (to the E)
566 nXStraightOn = nX + 1;
567 nYStraightOn = nY;
568
569 // If can't do either of these, try to go anti-seaward i.e. towards the LHS (N)
570 nXAntiSeaward = nX;
571 nYAntiSeaward = nY - 1;
572 nAntiSeawardNewDirection = NORTH;
573
574 // As a last resort, go back (to the W)
575 nXGoBack = nX - 1;
576 nYGoBack = nY;
577 nGoBackNewDirection = WEST;
578
579 break;
580
581 case SOUTH:
582 // The sea is towards the RHS (W) of the coast, so first try to go right (to the W)
583 nXSeaward = nX - 1;
584 nYSeaward = nY;
585 nSeawardNewDirection = WEST;
586
587 // If can't do this, try to go straight on (to the S)
588 nXStraightOn = nX;
589 nYStraightOn = nY + 1;
590
591 // If can't do either of these, try to go anti-seaward i.e. towards the LHS (E)
592 nXAntiSeaward = nX + 1;
593 nYAntiSeaward = nY;
594 nAntiSeawardNewDirection = EAST;
595
596 // As a last resort, go back (to the N)
597 nXGoBack = nX;
598 nYGoBack = nY - 1;
599 nGoBackNewDirection = NORTH;
600
601 break;
602
603 case WEST:
604 // The sea is towards the RHS (N) of the coast, so first try to go right (to the N)
605 nXSeaward = nX;
606 nYSeaward = nY - 1;
607 nSeawardNewDirection = NORTH;
608
609 // If can't do this, try to go straight on (to the W)
610 nXStraightOn = nX - 1;
611 nYStraightOn = nY;
612
613 // If can't do either of these, try to go anti-seaward i.e. towards the LHS (S)
614 nXAntiSeaward = nX;
615 nYAntiSeaward = nY + 1;
616 nAntiSeawardNewDirection = SOUTH;
617
618 // As a last resort, go back (to the E)
619 nXGoBack = nX + 1;
620 nYGoBack = nY;
621 nGoBackNewDirection = EAST;
622
623 break;
624 }
625
626 break;
627
628 case LEFT_HANDED:
629
630 // The sea is to the left-hand side of the coast as we traverse it. We are just inland, so we need to keep heading left to find the sea
631 switch (nSearchDirection)
632 {
633 case NORTH:
634 // The sea is towards the LHS (W) of the coast, so first try to go left (to the W)
635 nXSeaward = nX - 1;
636 nYSeaward = nY;
637 nSeawardNewDirection = WEST;
638
639 // If can't do this, try to go straight on (to the N)
640 nXStraightOn = nX;
641 nYStraightOn = nY - 1;
642
643 // If can't do either of these, try to go anti-seaward i.e. towards the RHS (E)
644 nXAntiSeaward = nX + 1;
645 nYAntiSeaward = nY;
646 nAntiSeawardNewDirection = EAST;
647
648 // As a last resort, go back (to the S)
649 nXGoBack = nX;
650 nYGoBack = nY + 1;
651 nGoBackNewDirection = SOUTH;
652
653 break;
654
655 case EAST:
656 // The sea is towards the LHS (N) of the coast, so first try to go left (to the N)
657 nXSeaward = nX;
658 nYSeaward = nY - 1;
659 nSeawardNewDirection = NORTH;
660
661 // If can't do this, try to go straight on (to the E)
662 nXStraightOn = nX + 1;
663 nYStraightOn = nY;
664
665 // If can't do either of these, try to go anti-seaward i.e. towards the RHS (S)
666 nXAntiSeaward = nX;
667 nYAntiSeaward = nY + 1;
668 nAntiSeawardNewDirection = SOUTH;
669
670 // As a last resort, go back (to the W)
671 nXGoBack = nX - 1;
672 nYGoBack = nY;
673 nGoBackNewDirection = WEST;
674
675 break;
676
677 case SOUTH:
678 // The sea is towards the LHS (E) of the coast, so first try to go left (to the E)
679 nXSeaward = nX + 1;
680 nYSeaward = nY;
681 nSeawardNewDirection = EAST;
682
683 // If can't do this, try to go straight on (to the S)
684 nXStraightOn = nX;
685 nYStraightOn = nY + 1;
686
687 // If can't do either of these, try to go anti-seaward i.e. towards the RHS (W)
688 nXAntiSeaward = nX - 1;
689 nYAntiSeaward = nY;
690 nAntiSeawardNewDirection = WEST;
691
692 // As a last resort, go back (to the N)
693 nXGoBack = nX;
694 nYGoBack = nY - 1;
695 nGoBackNewDirection = NORTH;
696
697 break;
698
699 case WEST:
700 // The sea is towards the LHS (S) of the coast, so first try to go left (to the S)
701 nXSeaward = nX;
702 nYSeaward = nY + 1;
703 nSeawardNewDirection = SOUTH;
704
705 // If can't do this, try to go straight on (to the W)
706 nXStraightOn = nX - 1;
707 nYStraightOn = nY;
708
709 // If can't do either of these, try to go anti-seaward i.e. towards the RHS (N)
710 nXAntiSeaward = nX;
711 nYAntiSeaward = nY - 1;
712 nAntiSeawardNewDirection = NORTH;
713
714 // As a last resort, go back (to the E)
715 nXGoBack = nX + 1;
716 nYGoBack = nY;
717 nGoBackNewDirection = EAST;
718
719 break;
720 }
721
722 break;
723 }
724
725 // Now do the actual search for this timestep: first try going in the direction of the sea. Is this seaward cell still within the grid?
726 if (bIsWithinValidGrid(nXSeaward, nYSeaward))
727 {
728 // It is, so check if the cell in the seaward direction is a sea cell
729 if (m_pRasterGrid->m_Cell[nXSeaward][nYSeaward].bIsInContiguousSea())
730 {
731 // There is sea in this seaward direction, so we are on the coast
732 bAtCoast = true;
733
734 // Has the current cell already marked been marked as a coast cell?
735 if (! m_pRasterGrid->m_Cell[nX][nY].bIsCoastline())
736 {
737 // Not already marked, is this an intervention cell with the top above SWL?
738 if ((bIsInterventionCell(nX, nY)) && (m_pRasterGrid->m_Cell[nX][nY].dGetInterventionTopElev() >= m_dThisIterSWL))
739 {
740 // It is, so add it to the vector
741 ILTempGridCRS.Append(&Pti);
742 }
743
744 else if (m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev() >= m_dThisIterSWL)
745 {
746 // The sediment top is above SWL so add it to the vector object
747 ILTempGridCRS.Append(&Pti);
748 }
749 }
750 }
751
752 else
753 {
754 // The seaward cell is not a sea cell, so we will move to it next time
755 nX = nXSeaward;
756 nY = nYSeaward;
757
758 // And set a new search direction, to keep turning seaward
759 nSearchDirection = nSeawardNewDirection;
760 continue;
761 }
762 }
763
764 // OK, we couldn't move seaward (but we may have marked the current cell as coast) so next try to move straight on. Is this straight-ahead cell still within the grid?
765 if (bIsWithinValidGrid(nXStraightOn, nYStraightOn))
766 {
767 // It is, so check if there is sea immediately in front
768 if (m_pRasterGrid->m_Cell[nXStraightOn][nYStraightOn].bIsInContiguousSea())
769 {
770 // Sea is in front, so we are on the coast
771 bAtCoast = true;
772
773 // Has the current cell already marked been marked as a coast cell?
774 if (! m_pRasterGrid->m_Cell[nX][nY].bIsCoastline())
775 {
776 // Not already marked, is this an intervention cell with the top above SWL?
777 if ((bIsInterventionCell(nX, nY)) && (m_pRasterGrid->m_Cell[nX][nY].dGetInterventionTopElev() >= m_dThisIterSWL))
778 {
779 // It is, so add it to the vector object
780 ILTempGridCRS.Append(&Pti);
781 }
782
783 else if (m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev() >= m_dThisIterSWL)
784 {
785 // The sediment top is above SWL so add it to the vector object
786 ILTempGridCRS.Append(&Pti);
787 }
788 }
789 }
790
791 else
792 {
793 // The straight-ahead cell is not a sea cell, so we will move to it next time
794 nX = nXStraightOn;
795 nY = nYStraightOn;
796
797 // The search direction remains unchanged
798 continue;
799 }
800 }
801
802 // Couldn't move either seaward or straight on (but we may have marked the current cell as coast) so next try to move in the anti-seaward direction. Is this anti-seaward cell still within the grid?
803 if (bIsWithinValidGrid(nXAntiSeaward, nYAntiSeaward))
804 {
805 // It is, so check if there is sea in this anti-seaward cell
806 if (m_pRasterGrid->m_Cell[nXAntiSeaward][nYAntiSeaward].bIsInContiguousSea())
807 {
808 // There is sea on the anti-seaward side, so we are on the coast
809 bAtCoast = true;
810
811 // Has the current cell already marked been marked as a coast cell?
812 if (! m_pRasterGrid->m_Cell[nX][nY].bIsCoastline())
813 {
814 // Not already marked, is this an intervention cell with the top above SWL?
815 if ((bIsInterventionCell(nX, nY)) && (m_pRasterGrid->m_Cell[nX][nY].dGetInterventionTopElev() >= m_dThisIterSWL))
816 {
817 // It is, so add it to the vector object
818 ILTempGridCRS.Append(&Pti);
819 }
820
821 else if (m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev() >= m_dThisIterSWL)
822 {
823 // The sediment top is above SWL so add it to the vector object
824 ILTempGridCRS.Append(&Pti);
825 }
826 }
827 }
828
829 else
830 {
831 // The anti-seaward cell is not a sea cell, so we will move to it next time
832 nX = nXAntiSeaward;
833 nY = nYAntiSeaward;
834
835 // And set a new search direction, to keep turning seaward
836 nSearchDirection = nAntiSeawardNewDirection;
837 continue;
838 }
839 }
840
841 // Could not move to the seaward side, move straight ahead, or move to the anti-seaward side, so we must be in a single-cell dead end! As a last resort, turn round and move back to where we just came from, but first check that this is a valid cell
842 if (bIsWithinValidGrid(nXGoBack, nYGoBack))
843 {
844 nX = nXGoBack;
845 nY = nYGoBack;
846
847 // And change the search direction
848 nSearchDirection = nGoBackNewDirection;
849 }
850
851 else
852 {
853 // Our final choice is not a valid cell, so give up
854 bOffEdge = true;
855 break;
856 }
857 } while (true);
858
859 // OK, we have finished tracing this coastline on the grid. But is the coastline too long or too short?
860 int nCoastSize = ILTempGridCRS.nGetSize();
861
862 if (bOffEdge)
863 {
865 LogStream << m_ulIter << ": Ignoring possible coastline from [" << nStartX << "][" << nStartY << "] = {" << dGridCentroidXToExtCRSX(nStartX) << ", " << dGridCentroidYToExtCRSY(nStartY) << "} since hit off-edge cell at [" << nX << "][" << nY << "] = {" << dGridCentroidXToExtCRSX(nX) << ", " << dGridCentroidYToExtCRSY(nY) << "}, coastline size is " << nCoastSize << endl;
866
868 }
869
870 if (bTooLong)
871 {
872 // Around loop too many times, so abandon this coastline
874 {
875 LogStream << m_ulIter << ": Ignoring possible coastline from [" << nStartX << "][" << nStartY << "] = {" << dGridCentroidXToExtCRSX(nStartX) << ", " << dGridCentroidYToExtCRSY(nStartY) << "} since round loop " << nRoundLoop << " times (m_nCoastMax = " << m_nCoastMax << "), coastline size is " << nCoastSize;
876
877 if (nCoastSize > 0)
878 LogStream << ", it ended at [" << ILTempGridCRS[nCoastSize - 1].nGetX() << "][" << ILTempGridCRS[nCoastSize - 1].nGetY() << "] = {" << dGridCentroidXToExtCRSX(ILTempGridCRS[nCoastSize - 1].nGetX()) << ", " << dGridCentroidYToExtCRSY(ILTempGridCRS[nCoastSize - 1].nGetY()) << "}";
879
880 LogStream << endl;
881 }
882
884 }
885
886 if (bRepeating)
887 {
889 {
890 LogStream << m_ulIter << ": Ignoring possible coastline from [" << nStartX << "][" << nStartY << "] = {" << dGridCentroidXToExtCRSX(nStartX) << ", " << dGridCentroidYToExtCRSY(nStartY) << "} since repeating, coastline size is " << nCoastSize;
891
892 if (nCoastSize > 0)
893 LogStream << ", it ended at [" << ILTempGridCRS[nCoastSize - 1].nGetX() << "][" << ILTempGridCRS[nCoastSize - 1].nGetY() << "] = {" << dGridCentroidXToExtCRSX(ILTempGridCRS[nCoastSize - 1].nGetX()) << ", " << dGridCentroidYToExtCRSY(ILTempGridCRS[nCoastSize - 1].nGetY()) << "}";
894
895 LogStream << endl;
896 }
897
899 }
900
901 if (nCoastSize == 0)
902 {
903 // Zero-length coastline, so abandon it
905 LogStream << m_ulIter << ": abandoning zero-length coastline from [" << nStartX << "][" << nStartY << "] = {" << dGridCentroidXToExtCRSX(nStartX) << ", " << dGridCentroidYToExtCRSY(nStartY) << "}" << endl;
906
908 }
909
910 if (nCoastSize < m_nCoastMin)
911 {
912 // The vector coastline is too small, so abandon it
914 LogStream << m_ulIter << ": Ignoring possible coastline from [" << nStartX << "][" << nStartY << "] = {" << dGridCentroidXToExtCRSX(nStartX) << ", " << dGridCentroidYToExtCRSY(nStartY) << "} to [" << ILTempGridCRS[nCoastSize - 1].nGetX() << "][" << ILTempGridCRS[nCoastSize - 1].nGetY() << "] = {" << dGridCentroidXToExtCRSX(ILTempGridCRS[nCoastSize - 1].nGetX()) << ", " << dGridCentroidYToExtCRSY(ILTempGridCRS[nCoastSize - 1].nGetY()) << "} since size (" << nCoastSize << ") is less than minimum (" << m_nCoastMin << ")" << endl;
915
917 }
918
919 // OK this new coastline is fine
920 int const nEndX = nX;
921 int const nEndY = nY;
922 int const nCoastEndX = ILTempGridCRS[nCoastSize - 1].nGetX();
923 int const nCoastEndY = ILTempGridCRS[nCoastSize - 1].nGetY();
924
925 if ((nCoastEndX != nEndX) || (nCoastEndY != nEndY))
926 {
927 // The grid-edge cell at nEndX, nEndY is not already at end of ILTempGridCRS. But is the final cell in ILTempGridCRS already at the edge of the grid?
928 if (! m_pRasterGrid->m_Cell[nCoastEndX][nCoastEndY].bIsBoundingBoxEdge())
929 {
930 // The final cell in ILTempGridCRS is not a grid-edge cell, so add the grid-edge cell and mark the cell as coastline
931 ILTempGridCRS.Append(nEndX, nEndY);
932 nCoastSize++;
933 }
934 }
935
936 // Need to specify start edge and end edge for smoothing routines
937 int const nStartEdge = m_pRasterGrid->m_Cell[nStartX][nStartY].nGetBoundingBoxEdge();
938 int const nEndEdge = m_pRasterGrid->m_Cell[nEndX][nEndY].nGetBoundingBoxEdge();
939
940 // Next, convert the grid coordinates in ILTempGridCRS (integer values stored as doubles) to external CRS coordinates (which will probably be non-integer, again stored as doubles). This is done now, so that smoothing is more effective
941 CGeomLine LTempExtCRS;
942
943 for (int j = 0; j < nCoastSize; j++)
944 {
945 LTempExtCRS.Append(dGridCentroidXToExtCRSX(ILTempGridCRS[j].nGetX()), dGridCentroidYToExtCRSY(ILTempGridCRS[j].nGetY()));
946 }
947
948 // Now do some smoothing of the vector output, if desired
950 LTempExtCRS = LSmoothCoastRunningMean(&LTempExtCRS);
951
953 LTempExtCRS = LSmoothCoastSavitzkyGolay(&LTempExtCRS, nStartEdge, nEndEdge);
954
955 // // DEBUG CODE ==================================================================================================
956 // LogStream << "==================================" << endl;
957 // for (int j = 0; j < nCoastSize; j++)
958 // {
959 // LogStream << "{" << dGridCentroidXToExtCRSX(ILTempGridCRS[j].nGetX()) << ", " << dGridCentroidYToExtCRSY(ILTempGridCRS[j].nGetY()) << "}" << "\t{" << LTempExtCRS.dGetXAt(j) << ", " << LTempExtCRS.dGetYAt(j) << "}" << endl;
960 // }
961 // LogStream << "==================================" << endl;
962 // // DEBUG CODE ==================================================================================================
963
964 // Create a new coastline object and append to it the vector of coastline objects
965 CRWCoast const CoastTmp(this);
966 m_VCoast.push_back(CoastTmp);
967 int const nCoast = static_cast<int>(m_VCoast.size()) - 1;
968
969 // Now mark the coastline on the grid
970 for (int n = 0; n < nCoastSize; n++)
971 m_pRasterGrid->m_Cell[ILTempGridCRS[n].nGetX()][ILTempGridCRS[n].nGetY()].SetAsCoastline(nCoast);
972
973 // Set the coastline (Ext CRS)
974 m_VCoast[nCoast].SetCoastlineExtCRS(&LTempExtCRS);
975
976 // Set the coastline (Grid CRS)
977 m_VCoast[nCoast].SetCoastlineGridCRS(&ILTempGridCRS);
978
979 // CGeom2DPoint PtLast(DBL_MIN, DBL_MIN);
980 // for (int j = 0; j < nCoastSize; j++)
981 // {
982 // // Store the smoothed points (in external CRS) in the coast's m_LCoastlineExtCRS object, also append dummy values to the other attribute vectors
983 // if (PtLast != &LTempExtCRS[j]) // Avoid duplicate points
984 // {
985 // m_VCoast[nCoast].AppendPointToCoastlineExtCRS(LTempExtCRS[j].dGetX(), LTempExtCRS[j].dGetY());
986 //
987 // // Also store the locations of the corresponding unsmoothed points (in raster grid CRS) in the coast's m_ILCellsMarkedAsCoastline vector
988 // m_VCoast[nCoast].AppendCellMarkedAsCoastline(&ILTempGridCRS[j]);
989 // }
990 //
991 // PtLast = LTempExtCRS[j];
992 // }
993
994 // Set values for the coast's other attributes: set the coast's handedness, and start and end edges
995 m_VCoast[nCoast].SetSeaHandedness(nHandedness);
996 m_VCoast[nCoast].SetStartEdge(nStartEdge);
997 m_VCoast[nCoast].SetEndEdge(nEndEdge);
998
1000 {
1001 LogStream << m_ulIter << ": Valid coast " << nCoast << " created, from [" << nStartX << "][" << nStartY << "] to [" << nEndX << "][" << nEndY << "] = {" << dGridCentroidXToExtCRSX(nStartX) << ", " << dGridCentroidYToExtCRSY(nStartY) << "} to {" << dGridCentroidXToExtCRSX(nEndX) << ", " << dGridCentroidYToExtCRSY(nEndY) << "} with " << nCoastSize << " points, handedness = " << (nHandedness == LEFT_HANDED ? "left" : "right") << endl;
1002
1003 LogStream << m_ulIter << ": Smoothed coastline " << nCoast << " runs from {" << LTempExtCRS[0].dGetX() << ", " << LTempExtCRS[0].dGetY() << "} to {" << LTempExtCRS[nCoastSize - 1].dGetX() << ", " << LTempExtCRS[nCoastSize - 1].dGetY() << "} i.e. from the ";
1004
1005 if (nStartEdge == NORTH)
1006 LogStream << "north";
1007
1008 else if (nStartEdge == SOUTH)
1009 LogStream << "south";
1010
1011 else if (nStartEdge == WEST)
1012 LogStream << "west";
1013
1014 else if (nStartEdge == EAST)
1015 LogStream << "east";
1016
1017 LogStream << " edge to the ";
1018
1019 if (nEndEdge == NORTH)
1020 LogStream << "north";
1021
1022 else if (nEndEdge == SOUTH)
1023 LogStream << "south";
1024
1025 else if (nEndEdge == WEST)
1026 LogStream << "west";
1027
1028 else if (nEndEdge == EAST)
1029 LogStream << "east";
1030
1031 LogStream << " edge" << endl;
1032 }
1033
1034 // LogStream << "-----------------" << endl;
1035 // for (int kk = 0; kk < m_VCoast.back().nGetCoastlineSize(); kk++)
1036 // LogStream << kk << " [" << m_VCoast.back().pPtiGetCellMarkedAsCoastline(kk)->nGetX() << "][" << m_VCoast.back().pPtiGetCellMarkedAsCoastline(kk)->nGetY() << "] = {" << dGridCentroidXToExtCRSX(m_VCoast.back().pPtiGetCellMarkedAsCoastline(kk)->nGetX()) << ", " << dGridCentroidYToExtCRSY(m_VCoast.back().pPtiGetCellMarkedAsCoastline(kk)->nGetY()) << "}" << endl;
1037 // LogStream << "-----------------" << endl;
1038
1039 // Next calculate the curvature of the vector coastline
1040 DoCoastCurvature(nCoast, nHandedness);
1041
1042 // Calculate values for the coast's flux orientation vector
1043 CalcCoastTangents(nCoast);
1044
1045 // And create the vector of pointers to coastline-normal objects
1046 m_VCoast[nCoast].CreateProfilesAtCoastPoints();
1047
1048 return RTN_OK;
1049}
1050
1051//===============================================================================================================================
1053//===============================================================================================================================
1055{
1056 // Find all connected sea cells
1058
1059 // Find every coastline on the raster grid, mark raster cells, then create the vector coastline
1060 int const nRet = nTraceAllFloodCoasts();
1061
1062 if (nRet != RTN_OK)
1063 return nRet;
1064
1065 // Have we created any coasts?
1066 switch (m_nLevel)
1067 {
1068 case 0: // WAVESETUP + SURGE:
1069 {
1070 if (m_VFloodWaveSetupSurge.empty())
1071 {
1072 cerr << m_ulIter << ": " << ERR << "no flood coastline located: this iteration SWL = " << m_dThisIterSWL << ", maximum DEM top surface elevation = " << m_dThisIterTopElevMax << ", minimum DEM top surface elevation = " << m_dThisIterTopElevMin << endl;
1073 return RTN_ERR_NOCOAST;
1074 }
1075
1076 break;
1077 }
1078
1079 case 1: // WAVESETUP + SURGE + RUNUP:
1080 {
1081 if (m_VFloodWaveSetupSurgeRunup.empty())
1082 {
1083 cerr << m_ulIter << ": " << ERR << "no flood coastline located: this iteration SWL = " << m_dThisIterSWL << ", maximum DEM top surface elevation = " << m_dThisIterTopElevMax << ", minimum DEM top surface elevation = " << m_dThisIterTopElevMin << endl;
1084 return RTN_ERR_NOCOAST;
1085 }
1086
1087 break;
1088 }
1089 }
1090
1091 return RTN_OK;
1092}
1093
1094//===============================================================================================================================
1096//===============================================================================================================================
1098{
1099 for (int nX = 0; nX < m_nXGridSize; nX++)
1100 {
1101 for (int nY = 0; nY < m_nYGridSize; nY++)
1102 {
1103 m_pRasterGrid->m_Cell[nX][nY].UnSetCheckFloodCell();
1104 m_pRasterGrid->m_Cell[nX][nY].UnSetInContiguousFlood();
1105 m_pRasterGrid->m_Cell[nX][nY].SetAsFloodline(false);
1106 }
1107 }
1108
1109 // Go along the list of edge cells
1110 for (unsigned int n = 0; n < m_VEdgeCell.size(); n++)
1111 {
1113 continue;
1114
1116 continue;
1117
1119 continue;
1120
1122 continue;
1123
1124 int const nX = m_VEdgeCell[n].nGetX();
1125 int const nY = m_VEdgeCell[n].nGetY();
1126
1127 if ((!m_pRasterGrid->m_Cell[nX][nY].bIsCellFloodCheck()) && (m_pRasterGrid->m_Cell[nX][nY].bIsInundated()))
1128 {
1129 // This edge cell is below SWL and sea depth remains set to zero
1130 FloodFillLand(nX, nY);
1131 }
1132 }
1133
1134 return RTN_OK;
1135}
Contains CGeom2DIPoint definitions.
int nGetSize(void) const
Returns the number of integer point in the vector which represents this 2D shape.
Definition 2di_shape.cpp:69
void Append(CGeom2DIPoint const *)
Appends a new integer point to the vector which represents this 2D shape.
Definition 2di_shape.cpp:80
void Append(CGeom2DPoint const *)
Appends a point to this 2D shape.
Definition 2d_shape.cpp:67
Geometry class used to represent 2D point objects with integer coordinates.
Definition 2di_point.h:29
int nGetY(void) const
Returns the CGeom2DIPoint object's integer Y coordinate.
Definition 2di_point.cpp:55
int nGetX(void) const
Returns the CGeom2DIPoint object's integer X coordinate.
Definition 2di_point.cpp:49
Geometry class used to represent 2D vector integer line objects.
Definition i_line.h:31
Geometry class used to represent 2D vector line objects.
Definition line.h:32
Real-world class used to represent the landform of a cell.
int nGetLFCategory(void) const
Get the landform category.
void SetLFCategory(int const)
Set the landform category.
Real-world class used to represent coastline objects.
Definition coast.h:43
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:574
int m_nYMinBoundingBox
The minimum y value of the bounding box.
Definition simulation.h:544
void FindAllSeaCells(void)
Finds and flags all sea areas which have at least one cell at a grid edge (i.e. does not flag 'inland...
CGeomLine LSmoothCoastRunningMean(CGeomLine *) const
Does running-mean smoothing of a CGeomLine coastline vector (is in external CRS coordinates)
int nLocateSeaAndCoasts(int &)
First find all connected sea areas, then locate the vector coastline(s), then put these onto the rast...
double m_dThisIterSWL
The still water level for this timestep (this includes tidal changes and any long-term SWL change)
Definition simulation.h:712
CGeomRasterGrid * m_pRasterGrid
Pointer to the raster grid object.
int m_nXGridSize
The size of the grid in the x direction.
Definition simulation.h:457
static int nGetOppositeDirection(int const)
Returns the opposite direction.
ofstream LogStream
vector< CRWCoast > m_VFloodWaveSetupSurgeRunup
TODO 007 Info needed.
vector< CRWCoast > m_VCoast
The coastline objects.
int nLocateFloodAndCoasts(void)
First find all connected sea areas, then locate the vector coastline(s), then put these onto the rast...
int nTraceCoastLine(unsigned int const, int const, int const, vector< bool > *, vector< CGeom2DIPoint > const *)
Traces a coastline (which is defined to be just above still water level) on the grid using the 'wall ...
int nTraceAllFloodCoasts(void)
Locates all the potential coastline start points on the edges of the raster grid, then traces vector ...
void FloodFillLand(int const, int const)
Use the sealevel, wave set-up and run-up to evaluate flood hydraulically connected TODO 007 Not clear...
int m_nYGridSize
The size of the grid in the y direction.
Definition simulation.h:460
double m_dThisIterTopElevMin
This-iteration lowest elevation of DEM.
Definition simulation.h:970
void CalcCoastTangents(int const)
Calculates tangents to a coastline: the tangent is assumed to be the orientation of energy/sediment f...
vector< CRWCoast > m_VFloodWaveSetupSurge
TODO 007 Info needed.
int m_nCoastMax
Maximum valid coast length when searching for coasts.
Definition simulation.h:511
int m_nXMaxBoundingBox
The maximum x value of the bounding box.
Definition simulation.h:541
string m_strLogFile
Name of output log file.
bool m_bOmitSearchWestEdge
Omit the west edge of the grid from coast-end searches?
Definition simulation.h:355
double dGridCentroidYToExtCRSY(int const) const
Given the integer Y-axis ordinate of a cell in the raster grid CRS, returns the external CRS Y-axis o...
Definition gis_utils.cpp:78
int m_nCoastMin
Minimum valid coast length when searching for coasts.
Definition simulation.h:514
bool m_bOmitSearchNorthEdge
Omit the north edge of the grid from coast-end searches?
Definition simulation.h:349
vector< CGeom2DIPoint > m_VEdgeCell
Edge cells.
int m_nYMaxBoundingBox
The maximum y value of the bounding box.
Definition simulation.h:547
unsigned long m_ulThisIterNumSeaCells
The number of grid cells which are marked as sea, for this iteration.
Definition simulation.h:610
CGeomLine LSmoothCoastSavitzkyGolay(CGeomLine *, int const, int const) const
Does smoothing of a CGeomLine coastline vector (is in external CRS coordinates) using a Savitzky-Gola...
int m_nXMinBoundingBox
The minimum x value of the bounding box.
Definition simulation.h:538
bool bIsWithinValidGrid(int const, int const) const
int m_nCoastSmooth
Which method to use for coast smoothing.
Definition simulation.h:466
void DoCoastCurvature(int const, int const)
Calculates both detailed and smoothed curvature for every point on a coastline.
bool m_bOmitSearchSouthEdge
Omit the south edge of the grid from coast-end searches?
Definition simulation.h:352
unsigned long m_ulIter
The number of the current iteration (time step)
Definition simulation.h:598
double dGridCentroidXToExtCRSX(int const) const
Definition gis_utils.cpp:68
int nTraceAllCoasts(int &)
Locates all the potential coastline start/finish points on the edges of the raster grid,...
void CellByCellFillSea(int const, int const)
Cell-by-cell fills all sea cells starting from a given cell. The cell-by-cell fill (aka 'floodfill') ...
bool bIsInterventionCell(int const, int const) const
Returns true if the cell is an intervention.
Definition utils.cpp:2954
double m_dThisIterTopElevMax
This-iteration highest elevation of DEM.
Definition simulation.h:967
int FindAllInundatedCells(void)
Finds and flags all sea areas which have at least one cell at a grid edge (i.e. does not flag 'inland...
int m_nLevel
TODO 007 Used in WAVESETUP + SURGE + RUNUP.
Definition simulation.h:580
bool m_bOmitSearchEastEdge
Omit the east edge of the grid from coast-end searches?
Definition simulation.h:358
vector< int > m_VEdgeCellEdge
The grid edge that each edge cell belongs to.
This file contains global definitions for CoastalME.
double const TOLERANCE
Definition cme.h:823
int const LF_CAT_SEA
Definition cme.h:536
int const RTN_ERR_NOCOAST
Definition cme.h:727
int const LF_CAT_SEDIMENT_INPUT
Definition cme.h:538
string const ERR
Definition cme.h:902
int const LF_CAT_SEDIMENT_INPUT_SUBMERGED
Definition cme.h:539
int const RTN_ERR_TOO_LONG_TRACING_COAST
Definition cme.h:770
int const RTN_ERR_IGNORING_COAST
Definition cme.h:769
int const LOG_FILE_MIDDLE_DETAIL
Definition cme.h:491
bool bFPIsEqual(const T d1, const T d2, const T dEpsilon)
Definition cme.h:1303
int const LOG_FILE_HIGH_DETAIL
Definition cme.h:492
int const RTN_ERR_NO_START_FINISH_POINTS_TRACING_COAST
Definition cme.h:764
int const SMOOTH_SAVITZKY_GOLAY
Definition cme.h:783
int const SMOOTH_RUNNING_MEAN
Definition cme.h:782
int const SOUTH
Definition cme.h:501
int const LOG_FILE_ALL
Definition cme.h:493
int const EAST
Definition cme.h:499
int const RTN_OK
Definition cme.h:694
int const RTN_ERR_COAST_TOO_SMALL
Definition cme.h:768
int const RTN_ERR_NO_VALID_COAST
Definition cme.h:765
int const RTN_ERR_ZERO_LENGTH_COAST
Definition cme.h:767
int const LF_CAT_SEDIMENT_INPUT_NOT_SUBMERGED
Definition cme.h:540
int const RTN_ERR_REPEATING_WHEN_TRACING_COAST
Definition cme.h:766
int const RIGHT_HANDED
Definition cme.h:511
int const NORTH
Definition cme.h:497
int const LEFT_HANDED
Definition cme.h:512
int const WEST
Definition cme.h:503
Contains CRWCoast definitions.
Contains CGeomILine definitions.
Contains CGeomLine definitions.
Contains CGeomRasterGrid definitions.
Contains CSimulation definitions.