CoastalME (Coastal Modelling Environment)
Simulates the long-term behaviour of complex coastlines
Loading...
Searching...
No Matches
multiple_coastlines.cpp
Go to the documentation of this file.
1
10
11/* ===============================================================================================================================
12
13 This file is part of CoastalME, the Coastal Modelling Environment.
14
15 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.
16
17 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.
18
19 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.
20
21===============================================================================================================================*/
22#include <assert.h>
23
24#include <iostream>
25using std::endl;
26
27#include <algorithm>
28using std::shuffle;
29
30#include "cme.h"
31#include "simulation.h"
32#include "coast.h"
33#include "2di_point.h"
34#include "2d_point.h"
35#include "multi_line.h"
36
37class CRWCoast; // Forward declaration
38
39//===============================================================================================================================
41//===============================================================================================================================
43{
44 int const nCoastSize = static_cast<int>(m_VCoast.size());
45
47 LogStream << endl << m_ulIter << ": " << nCoastSize << " coastlines found, checking coast-coast intersections" << endl;
48
49 // Create a vector of coast IDs and randomly shuffle it to avoid sequence-related artefacts
50 vector<int> VnCoastID(nCoastSize);
51 for (int nn = 0; nn < nCoastSize; nn++)
52 VnCoastID[nn] = nn;
53 shuffle(VnCoastID.begin(), VnCoastID.end(), m_Rand[1]);
54
55 // Check all coastlines
56 for (int nn = 0; nn < nCoastSize; nn++)
57 {
58 // Use the shuffled coast ID
59 int const nCoast = VnCoastID[nn];
60
61 // Create a vector of this coast's profile IDs and randomly shuffle it to avoid sequence-related artefacts
62 vector<int> VnProfileID(m_VCoast[nCoast].nGetNumProfiles());
63 for (int m = 0; m < m_VCoast[nCoast].nGetNumProfiles(); m++)
64 VnProfileID[m] = m;
65 shuffle(VnProfileID.begin(), VnProfileID.end(), m_Rand[1]);
66
67 // Check all profiles
68 for (int n = 0; n < m_VCoast[nCoast].nGetNumProfiles(); n++)
69 {
70 // Use the shuffled profile ID
71 CGeomProfile* pProfile = m_VCoast[nCoast].pGetProfileWithDownCoastSeq(VnProfileID[n]);
72 int const nProfile = pProfile->nGetProfileID();
73
74 // Check every cell that is 'under' this profile, start one cell seaward of coastline
75 for (int nCell = 1; nCell < pProfile->nGetNumCellsInProfile(); nCell++)
76 {
77 CGeom2DIPoint const* pCell = pProfile->pPtiGetCellInProfile(nCell);
78 int const nX = pCell->nGetX();
79 int const nY = pCell->nGetY();
80
81 // Have we hit a cell which is 'under' another coastline?
82 if (m_pRasterGrid->m_Cell[nX][nY].bIsCoastline())
83 {
84 // Yes this is a coastline cell, as well as a coast-normal profile cell
85 int const nHitCoast = m_pRasterGrid->m_Cell[nX][nY].nGetCoastline();
86 if (nHitCoast != nCoast)
87 {
88 // We have hit a different coastline, so truncate this profile
89 int const nRtn = nTruncateProfileHitDifferentCoast(nCoast, nProfile, nX, nY);
90 if (nRtn != RTN_OK)
91 return nRtn;
92 }
93 }
94 else
95 {
96 // We also need to check an adjacent cell, doesn't matter which one
97 int nYTmp = nY+1;
98 if (nY+1 >= m_nYGridSize)
99 nYTmp = nY-1;
100
101 if (m_pRasterGrid->m_Cell[nX][nYTmp].bIsCoastline())
102 {
103 // Yes this is a coastline cell, as well as a coast-normal profile cell
104 int const nHitCoast = m_pRasterGrid->m_Cell[nX][nYTmp].nGetCoastline();
105 if (nHitCoast != nCoast)
106 {
107 // We have hit a different coastline, so truncate this profile
108 int const nRtn = nTruncateProfileHitDifferentCoast(nCoast, nProfile, nX, nY);
109 if (nRtn != RTN_OK)
110 return nRtn;
111 }
112 }
113 }
114
115 // For grid-edge cells, don't check for intersection with other-coast profiles, instead wait until this profile hits a different coast
116 if (! pProfile->bIsGridEdge())
117 {
118 // Have we hit a cell which is 'under' a coast-normal profile belonging to another coast? NOTE Is a problem if get more than two coast normals passing through this cell
119 int nHitProfileCoast = m_pRasterGrid->m_Cell[nX][nY].nGetProfileCoastID();
120 if ((nHitProfileCoast != INT_NODATA) && (nHitProfileCoast != nCoast))
121 {
122 // Yes, we have hit a profile which belongs to a different coast
123 int const nHitProfile = m_pRasterGrid->m_Cell[nX][nY].nGetProfileID();
124
125 // Safety check
126 if (nHitProfile != INT_NODATA)
127 {
128 // Truncate both profiles
129 int const nRtn = nTruncateProfilesDifferentCoasts(nCoast, nProfile, nHitProfileCoast, nHitProfile, nX, nY);
130 if (nRtn != RTN_OK)
131 return nRtn;
132 }
133 }
134 else
135 {
136 // Try again with an adjacent point, does not matter wehich one NOTE Is a problem if get more than two coast normals passing through this cell
137 int nYTmp = nY+1;
138 if (nY+1 >= m_nYGridSize)
139 nYTmp = nY-1;
140
141 nHitProfileCoast = m_pRasterGrid->m_Cell[nX][nYTmp].nGetProfileCoastID();
142 if ((nHitProfileCoast != INT_NODATA) && (nHitProfileCoast != nCoast))
143 {
144 // Yes, we have hit a profile which belongs to a different coast
145 int const nHitProfile = m_pRasterGrid->m_Cell[nX][nYTmp].nGetProfileID();
146
147 // Safety check
148 if (nHitProfile != INT_NODATA)
149 {
150 // Truncate both profiles
151 int const nRtn = nTruncateProfilesDifferentCoasts(nCoast, nProfile, nHitProfileCoast, nHitProfile, nX, nYTmp);
152 if (nRtn != RTN_OK)
153 return nRtn;
154 }
155 }
156 }
157 }
158 }
159 }
160 // // DEBUG CODE ================
161 // m_nGISSave++;
162 // if (! bWriteVectorGISFile(VECTOR_PLOT_COAST, &VECTOR_PLOT_COAST_TITLE))
163 // return false;
164 // if (! bWriteVectorGISFile(VECTOR_PLOT_NORMALS, &VECTOR_PLOT_NORMALS_TITLE))
165 // return false;
166 // if (! bWriteVectorGISFile(VECTOR_PLOT_INVALID_NORMALS, &VECTOR_PLOT_INVALID_NORMALS_TITLE))
167 // return false;
168 // if (! bWriteRasterGISFile(RASTER_PLOT_NORMAL_PROFILE, &RASTER_PLOT_NORMAL_PROFILE_TITLE))
169 // return false;
170 // if (! bWriteRasterGISFile(RASTER_PLOT_COAST, &RASTER_PLOT_COAST_TITLE))
171 // return false;
172 // // DEBUG CODE ================
173 }
174
175 return RTN_OK;
176}
177
178//===============================================================================================================================
180//===============================================================================================================================
181int CSimulation::nTruncateProfilesDifferentCoasts(int const nThisProfileCoast, int const nThisProfile, int const nHitProfileCoast, int const nHitProfile, int const nXIntersect, int const nYIntersect)
182{
183 // LogStream << m_ulIter << ": coast " << nThisProfileCoast << " profile " << nThisProfile << " and coast " << nHitProfileCoast << " profile "<< nHitProfile << " intersect at [" << nXIntersect << "][" << nYIntersect << "] = {" << dGridCentroidXToExtCRSX(nXIntersect) << ", " << dGridCentroidYToExtCRSY(nYIntersect) << "}" << endl;
184
185 // OK, get pointers to 'this' profile and to the hit profile
186 CGeomProfile* pThisProfile = m_VCoast[nThisProfileCoast].pGetProfile(nThisProfile);
187 CGeomProfile* pHitProfile = m_VCoast[nHitProfileCoast].pGetProfile(nHitProfile);
188
189 // Get the length of each profile (grid CRS)
190 int const nThisProfileLen = pThisProfile->nGetNumCellsInProfile();
191 int const nHitProfileLen = pHitProfile->nGetNumCellsInProfile();
192
193 // Get the start points of both profiles
194 CGeom2DIPoint const* pPtiThisProfileStart = pThisProfile->pPtiGetFirstCellInProfile();
195 CGeom2DIPoint const* pPtiHitProfileStart = pHitProfile->pPtiGetFirstCellInProfile();
196
197 double const dXThisProfileStart = pPtiThisProfileStart->nGetX();
198 double const dYThisProfileStart = pPtiThisProfileStart->nGetY();
199 double const dXHitProfileStart = pPtiHitProfileStart->nGetX();
200 double const dYHitProfileStart = pPtiHitProfileStart->nGetY();
201 double dClosestX;
202 double dClosestY;
203
204 // On a line joining the start points of both profiles, find the point on that line which is closest to the intersection of both profiles
205 FindClosestPointOnStraightLine(dXThisProfileStart, dYThisProfileStart, dXHitProfileStart, dYHitProfileStart, nXIntersect, nYIntersect, dClosestX, dClosestY);
206
207 // Get the distance between this closest point and each profile start point
208 double const dThisDist = dGetDistanceBetween(pPtiThisProfileStart->nGetX(), pPtiThisProfileStart->nGetY(), dClosestX, dClosestY);
209 double const dHitDist = dGetDistanceBetween(pPtiHitProfileStart->nGetX(), pPtiHitProfileStart->nGetY(), dClosestX, dClosestY);
210 double const dTotDist = dThisDist + dHitDist;
211
212 // Calculate the proportion of each profile that is to be retained
213 double const dThisPropToRetain = dThisDist / dTotDist;
214 double const dHitPropToRetain = dHitDist / dTotDist;
215
216 // Now calculate the indices of the new endpoints for each profile
217 int const nThisProfileEndpointIndex = tMax(nRound(nThisProfileLen * dThisPropToRetain) - GAP_BETWEEN_DIFFERENT_COAST_PROFILES, MIN_PROFILE_SIZE);
218 int const nHitProfileEndpointIndex = tMax(nRound(nHitProfileLen * dHitPropToRetain) - GAP_BETWEEN_DIFFERENT_COAST_PROFILES, MIN_PROFILE_SIZE);
219
220 // Get pointers to the cells in the two profiles
221 vector<CGeom2DIPoint>* pVThisProfileCells = pThisProfile->pPtiVGetCellsInProfile();
222 vector<CGeom2DIPoint>* pVHitProfileCells = pHitProfile->pPtiVGetCellsInProfile();
223
224 // New endpoints of the two profiles (grid CRS)
225 int const nXThisProfileEndPoint = pVThisProfileCells->at(nThisProfileEndpointIndex).nGetX();
226 int const nYThisProfileEndPoint = pVThisProfileCells->at(nThisProfileEndpointIndex).nGetY();
227 int const nXHitProfileEndPoint = pVHitProfileCells->at(nHitProfileEndpointIndex).nGetX();
228 int const nYHitProfileEndPoint = pVHitProfileCells->at(nHitProfileEndpointIndex).nGetY();
229
230 // New endpoints of the two profiles (external CRS)
231 double const dXThisProfileEndPoint = dGridCentroidXToExtCRSX(nXThisProfileEndPoint);
232 double const dYThisProfileEndPoint = dGridCentroidYToExtCRSY(nYThisProfileEndPoint);
233 double const dXHitProfileEndPoint = dGridCentroidXToExtCRSX(nXHitProfileEndPoint);
234 double const dYHitProfileEndPoint = dGridCentroidYToExtCRSY(nYHitProfileEndPoint);
235
236 // LogStream << m_ulIter << ": new end point of coast " << nThisProfileCoast << " profile " << nThisProfile << " is at [" << nXThisProfileEndPoint << "][" << nYThisProfileEndPoint << "] = {" << dXThisProfileEndPoint << ", " << dYThisProfileEndPoint << "}, new end point of coast " << nHitProfileCoast << " profile " << nHitProfile << " is at [" << nXHitProfileEndPoint << "][" << nYHitProfileEndPoint << "] = {" << dXHitProfileEndPoint << ", " << dYHitProfileEndPoint << "}" << endl;
237
238 // Next unmark the cells that will no longer be 'under' this profile
239 for (int nn = nThisProfileEndpointIndex+1; nn < nThisProfileLen; nn++)
240 {
241 int const nXTmp = pVThisProfileCells->at(nn).nGetX();
242 int const nYTmp = pVThisProfileCells->at(nn).nGetY();
243
244 if ((m_pRasterGrid->m_Cell[nXTmp][nYTmp].nGetProfileID() == nThisProfile) && (m_pRasterGrid->m_Cell[nXTmp][nYTmp].nGetProfileCoastID() == nThisProfileCoast))
245 m_pRasterGrid->m_Cell[nXTmp][nYTmp].SetCoastAndProfileID(INT_NODATA, INT_NODATA);
246
247 // LogStream << "For coast " << nThisProfileCoast << " profile " << nThisProfile << " unmarking [" << nXTmp << "][" << nYTmp << "]" << endl;
248 }
249
250 // And unmark the cells that will no longer be 'under' the hit profile
251 for (int nn = nHitProfileEndpointIndex+1; nn < nHitProfileLen; nn++)
252 {
253 int const nXTmp = pVHitProfileCells->at(nn).nGetX();
254 int const nYTmp = pVHitProfileCells->at(nn).nGetY();
255
256 if ((m_pRasterGrid->m_Cell[nXTmp][nYTmp].nGetProfileID() == nHitProfile) && (m_pRasterGrid->m_Cell[nXTmp][nYTmp].nGetProfileCoastID() == nHitProfileCoast))
257 m_pRasterGrid->m_Cell[nXTmp][nYTmp].SetCoastAndProfileID(INT_NODATA, INT_NODATA);
258
259 // LogStream << "For coast " << nHitProfileCoast << " profile " << nHitProfile << " unmarking [" << nXTmp << "][" << nYTmp << "]" << endl;
260 }
261
262 // Truncate this profile's CGeomMultiLine (external CRS)
263 int nRtn = nTruncateProfileMultiLineDifferentCoasts(pThisProfile, dXThisProfileEndPoint, dYThisProfileEndPoint);
264 if (nRtn != RTN_OK)
265 return nRtn;
266
267 // Truncate the hit profile's CGeomMultiLine (external CRS)
268 nRtn = nTruncateProfileMultiLineDifferentCoasts(pHitProfile, dXHitProfileEndPoint, dYHitProfileEndPoint);
269 if (nRtn != RTN_OK)
270 return nRtn;
271
272 // Truncate the list of cells in this profile
273 pVThisProfileCells->resize(nThisProfileEndpointIndex);
274 pThisProfile->SetCellsInProfile(pVThisProfileCells);
275
276 // Truncate the list of cells in the hit profile
277 pVHitProfileCells->resize(nHitProfileEndpointIndex);
278 pHitProfile->SetCellsInProfile(pVHitProfileCells);
279
280 // Flag this profile as truncated
281 pThisProfile->SetTruncatedDifferentCoast(true);
282
283 // Flag the hit profile as truncated
284 pHitProfile->SetTruncatedDifferentCoast(true);
285
287 {
288 string strTmp;
289 if (pThisProfile->bIsGridEdge())
290 {
291 strTmp += " grid-edge ";
292
293 if (pThisProfile->bStartOfCoast())
294 strTmp += "start";
295
296 if (pThisProfile->bEndOfCoast())
297 strTmp += "end";
298 }
299
300 LogStream << m_ulIter << ": coast " << nThisProfileCoast << strTmp << " profile " << nThisProfile << " hit by coast " << nHitProfileCoast << " profile " << nHitProfile << " at [" << nXIntersect << "][" << nYIntersect << "] = {" << dGridCentroidXToExtCRSX(nXIntersect) << ", " << dGridCentroidYToExtCRSY(nYIntersect) << "}. Profile truncated, new endpoint is [" << nXThisProfileEndPoint << "][" << nYThisProfileEndPoint << "] = {" << dGridCentroidXToExtCRSX(nXThisProfileEndPoint) << ", " << dGridCentroidYToExtCRSY(nYThisProfileEndPoint) << "}. Length was " << nThisProfileLen << " cells, length is now " << nThisProfileEndpointIndex << " cells (" << 100 * nThisProfileEndpointIndex / nThisProfileLen << "%)" << endl;
301
302 if (pHitProfile->bIsGridEdge())
303 {
304 strTmp = " grid-edge ";
305
306 if (pHitProfile->bStartOfCoast())
307 strTmp += "start";
308
309 if (pHitProfile->bEndOfCoast())
310 strTmp += "end";
311 }
312
313 LogStream << m_ulIter << ": coast " << nHitProfileCoast << strTmp << " profile " << nHitProfile << " hit by coast " << nThisProfileCoast << " profile " << nThisProfile << " at [" << nXIntersect << "][" << nYIntersect << "] = {" << dGridCentroidXToExtCRSX(nXIntersect) << ", " << dGridCentroidYToExtCRSY(nYIntersect) << "}. Profile truncated, new endpoint is [" << nXHitProfileEndPoint << "][" << nYHitProfileEndPoint << "] = {" << dGridCentroidXToExtCRSX(nXHitProfileEndPoint) << ", " << dGridCentroidYToExtCRSY(nYHitProfileEndPoint) << "}. Length was " << nHitProfileLen << " cells, length is now " << nHitProfileEndpointIndex << " cells (" << 100 * nHitProfileEndpointIndex / nHitProfileLen << "%)" << endl;
314 }
315
316 return RTN_OK;
317}
318
319//===============================================================================================================================
321//===============================================================================================================================
322int CSimulation::nTruncateProfileHitDifferentCoast(int const nCoast, int const nProfile, int const nXHitCoast, int const nYHitCoast)
323{
324 // OK, get a pointer to 'this' profile
325 CGeomProfile* pProfile = m_VCoast[nCoast].pGetProfile(nProfile);
326
327 // And get the start point of this profile
328 CGeom2DIPoint const* pPtiProfileStart = pProfile->pPtiGetFirstCellInProfile();
329
330 // Get the distance between the point where the profile has hit the different coast, and the profile start point
331 double const dThisDist = dGetDistanceBetween(pPtiProfileStart->nGetX(), pPtiProfileStart->nGetY(), nXHitCoast, nYHitCoast);
332
333 // Then halve this distance: the result is the new length of the profile
334 int const nNewLenProfile = tMax(nRound(dThisDist / 2) - GAP_BETWEEN_DIFFERENT_COAST_PROFILES, MIN_PROFILE_SIZE);
335
336 // Now get pointers to the cells in this profile
337 vector<CGeom2DIPoint>* pVProfileCells = pProfile->pPtiVGetCellsInProfile();
338 int const nProfileLen = static_cast<int>(pVProfileCells->size());
339
340 // We have the new profile length so next unmark the cells that will no longer be 'under' the profile
341 for (int nn = nNewLenProfile-1; nn < nProfileLen; nn++)
342 {
343 int const nXThis = pVProfileCells->at(nn).nGetX();
344 int const nYThis = pVProfileCells->at(nn).nGetY();
345
346 if ((m_pRasterGrid->m_Cell[nXThis][nYThis].nGetProfileID() == nProfile) && (m_pRasterGrid->m_Cell[nXThis][nYThis].nGetProfileCoastID() == nCoast))
347 m_pRasterGrid->m_Cell[nXThis][nYThis].SetCoastAndProfileID(INT_NODATA, INT_NODATA);
348 }
349
350 // Truncate the list of cells in the profile, and then update
351 pVProfileCells->resize(nNewLenProfile);
352 pProfile->SetCellsInProfile(pVProfileCells);
353
354 // Get the endpoint of the truncated profile (external CRS)
355 double const dXEndPoint = dGridCentroidXToExtCRSX(pVProfileCells->back().nGetX());
356 double const dYEndPoint = dGridCentroidYToExtCRSY(pVProfileCells->back().nGetY());
357
358 // Now truncate the profile's CGeomMultiLine (external CRS)
359 int const nRtn = nTruncateProfileMultiLineDifferentCoasts(pProfile, dXEndPoint, dYEndPoint);
360 if (nRtn != RTN_OK)
361 return nRtn;
362
363 // And flag as truncated
364 pProfile->SetTruncatedDifferentCoast(true);
365
367 {
368 string strTmp;
369 if (pProfile->bStartOfCoast() || pProfile->bEndOfCoast())
370 {
371 strTmp += " grid-edge ";
372
373 if (pProfile->bStartOfCoast())
374 strTmp += "start";
375
376 if (pProfile->bEndOfCoast())
377 strTmp += "end";
378 }
379
380 LogStream << m_ulIter << ": coast " << nCoast << strTmp << " profile " << nProfile << " hit another coast at [" << nXHitCoast << "][" << nYHitCoast << "] = {" << dGridCentroidXToExtCRSX(nXHitCoast) << ", " << dGridCentroidYToExtCRSY(nYHitCoast) << "}. Profile truncated, length of profile " << nProfile << " was " << nProfileLen << " cells, is now " << nNewLenProfile << " cells (" << 100 * nNewLenProfile / nProfileLen << "%)" << endl;
381 }
382
383 // // DEBUG CODE ================
384 // m_nGISSave++;
385 // if (! bWriteVectorGISFile(VECTOR_PLOT_COAST, &VECTOR_PLOT_COAST_TITLE))
386 // return false;
387 // if (! bWriteVectorGISFile(VECTOR_PLOT_NORMALS, &VECTOR_PLOT_NORMALS_TITLE))
388 // return false;
389 // if (! bWriteVectorGISFile(VECTOR_PLOT_INVALID_NORMALS, &VECTOR_PLOT_INVALID_NORMALS_TITLE))
390 // return false;
391 // if (! bWriteRasterGISFile(RASTER_PLOT_NORMAL_PROFILE, &RASTER_PLOT_NORMAL_PROFILE_TITLE))
392 // return false;
393 // if (! bWriteRasterGISFile(RASTER_PLOT_POLYGON, &RASTER_PLOT_POLYGON_TITLE))
394 // return false;
395 // // DEBUG CODE ================
396
397 return RTN_OK;
398}
399
400//===============================================================================================================================
402//===============================================================================================================================
403int CSimulation::nTruncateProfileMultiLineDifferentCoasts(CGeomProfile* pProfile, double const dX, double const dY)
404{
405 // Find which multiline line segment 'contains' this ext CRS end point, then truncate at this point
406 bool bFound = false;
407
408 int const nProfileLineSegments = pProfile->CGeomMultiLine::nGetNumLineSegments();
409 for (int nSeg = 0; nSeg < nProfileLineSegments; nSeg++)
410 {
411 // Search each segment
412 int const nNumCoinc = pProfile->CGeomMultiLine::nGetNumCoincidentProfilesInLineSegment(nSeg);
413 for (int nCoinc = 0; nCoinc < nNumCoinc; nCoinc++)
414 {
415 vector<CGeom2DPoint>& pVPt = pProfile->CGeomMultiLine::pGetPoints();
416
417 for (int nLin = 0; nLin < static_cast<int>(pVPt.size())-1; nLin++)
418 {
419 double const dX1 = pVPt[nLin].dGetX();
420 double const dY1 = pVPt[nLin].dGetY();
421 double const dX2 = pVPt[nLin+1].dGetX();
422 double const dY2 = pVPt[nLin+1].dGetY();
423
424 double const dXMin = tMin(dX1, dX2);
425 double const dXMax = tMax(dX1, dX2);
426 double const dYMin = tMin(dY1, dY2);
427 double const dYMax = tMax(dY1, dY2);
428
429 // LogStream << m_ulIter << ": coast " << pProfile->nGetCoastID() << " profile " << pProfile->nGetProfileID() << " min is [" << dXMin << ", " << dYMin << "], search point is [" << dX << ", " << dY << "], max is [" << dXMax << ", " << dYMax << "]" << endl;
430
431 if ((dX >= dXMin) && (dX <= dXMax) && (dY >= dYMin) && (dY <= dYMax))
432 {
433 bFound = true;
434 // LogStream << "FOUND" << endl;
435
436 pProfile->TruncateProfile(nSeg+1);
437 pProfile->AppendPointInProfile(dX, dY);
438
439 break;
440 }
441 }
442 if (bFound)
443 break;
444 }
445 if (bFound)
446 break;
447 }
448
449 if (! bFound)
450 {
451 // LogStream << "NOT FOUND" << endl;
453 }
454
455 return RTN_OK;
456}
Contains CGeom2DPoint definitions.
Contains CGeom2DIPoint definitions.
Geometry class used to represent 2D point objects with integer coordinates.
Definition 2di_point.h:25
int nGetY(void) const
Returns the CGeom2DIPoint object's integer Y coordinate.
Definition 2di_point.cpp:51
int nGetX(void) const
Returns the CGeom2DIPoint object's integer X coordinate.
Definition 2di_point.cpp:45
Geometry class used to represent coast profile objects.
Definition profile.h:33
void TruncateProfile(int const)
Truncates the profile's CGeomLine (external CRS points)
Definition profile.cpp:338
void AppendPointInProfile(double const, double const)
Appends a point (external CRS) to the profile.
Definition profile.cpp:307
void SetCellsInProfile(vector< CGeom2DIPoint > const *)
Sets the profile's vector of cells (grid CRS)
Definition profile.cpp:506
int nGetProfileID(void) const
Returns the profile's this-coast ID.
Definition profile.cpp:74
CGeom2DIPoint * pPtiGetCellInProfile(int const)
Returns a single cell (grid CRS) in the profile.
Definition profile.cpp:518
bool bIsGridEdge(void) const
Returns true if this is a start-of-coast or an end-of-coast profile.
Definition profile.cpp:122
int nGetNumCellsInProfile(void) const
Returns the number of cells in the profile.
Definition profile.cpp:539
bool bStartOfCoast(void) const
Returns the switch to indicate whether this is a start-of-coast profile.
Definition profile.cpp:104
CGeom2DIPoint * pPtiGetFirstCellInProfile(void)
Returns the first cell (grid CRS) in the profile.
Definition profile.cpp:532
vector< CGeom2DIPoint > * pPtiVGetCellsInProfile(void)
Returns all cells (grid CRS) in the profile.
Definition profile.cpp:512
void SetTruncatedDifferentCoast(bool const)
Sets a switch which indicates whether this profile is truncated, due to hitting another profile from ...
Definition profile.cpp:203
bool bEndOfCoast(void) const
Returns the switch to indicate whether this is an end-of-coast profile.
Definition profile.cpp:116
Real-world class used to represent coastline objects.
Definition coast.h:39
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:588
CGeomRasterGrid * m_pRasterGrid
Pointer to the raster grid object.
ofstream LogStream
vector< CRWCoast > m_VCoast
The coastline objects.
int nDoMultipleCoastlines(void)
Checks all profiles on all coasts for intersections between profiles belonging to different coasts.
void FindClosestPointOnStraightLine(double const, double const, double const, double const, double const, double const, double &, double &)
For the straight line between two points A and B, and given another point C, this finds the closest p...
int m_nYGridSize
The size of the grid in the y direction.
Definition simulation.h:480
static double dGetDistanceBetween(CGeom2DPoint const *, CGeom2DPoint const *)
Returns the distance (in external CRS) between two points.
int nTruncateProfileMultiLineDifferentCoasts(CGeomProfile *, double const, double const)
Truncates the CGeomMultiLine (external CRS) of a profile which has hit a different coast,...
int nTruncateProfilesDifferentCoasts(int const, int const, int const, int const, int const, int const)
Truncates two intersecting coast-normal profile belonging to different coasts.
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:74
default_random_engine m_Rand[NUMBER_OF_RNGS]
The c++11 random number generators.
unsigned long m_ulIter
The number of the current iteration (time step)
Definition simulation.h:609
double dGridCentroidXToExtCRSX(int const) const
Given the integer X-axis ordinate of a cell in the raster grid CRS, returns the external CRS X-axis o...
Definition gis_utils.cpp:65
int nTruncateProfileHitDifferentCoast(int const, int const, int const, int const)
Truncates a profile which has hit a different coast.
This file contains global definitions for CoastalME.
int const INT_NODATA
Definition cme.h:380
T tMin(T a, T b)
Definition cme.h:1175
int const RTN_ERR_POINT_NOT_FOUND_IN_MULTILINE_DIFFERENT_COASTS
Definition cme.h:663
int const GAP_BETWEEN_DIFFERENT_COAST_PROFILES
Definition cme.h:694
int const LOG_FILE_MIDDLE_DETAIL
Definition cme.h:393
T tMax(T a, T b)
Definition cme.h:1162
int const LOG_FILE_ALL
Definition cme.h:395
int const RTN_OK
Definition cme.h:585
int const MIN_PROFILE_SIZE
Definition cme.h:386
Contains CRWCoast definitions.
Contains CGeomMultiLine definitions.
Contains CSimulation definitions.
int nRound(double const d)
Correctly rounds doubles, returns an int.