66 if (nX > 0 && nX < m_nXGridSize - 1 && nY > 0 && nY <
m_nYGridSize - 1) {
76 double dSlopeX = (dElevRight - dElevLeft) / (2.0 *
m_dCellSide);
77 double dSlopeY = (dElevDown - dElevUp) / (2.0 *
m_dCellSide);
78 double dSlope = sqrt(dSlopeX * dSlopeX + dSlopeY * dSlopeY);
111 vector<vector<bool>> bVisited(
static_cast<unsigned int>(
m_nXGridSize),
112 vector<bool>(
static_cast<unsigned int>(
m_nYGridSize),
false));
115 vector<pair<int, int>> VSmallIslandCells;
118 for (
unsigned int nX = 0; nX < static_cast<unsigned int>(
m_nXGridSize); nX++) {
119 for (
unsigned int nY = 0; nY < static_cast<unsigned int>(
m_nYGridSize); nY++) {
121 if (!bVisited[nX][nY] &&
m_pRasterGrid->m_Cell[nX][nY].bIsCliff()) {
124 vector<pair<int, int>> VCurrentCliffRegion;
127 vector<pair<int, int>> VStack;
128 VStack.push_back(std::make_pair(nX, nY));
131 while (!VStack.empty()) {
132 pair<int, int> currentCell = VStack.back();
135 size_t nCurX =
static_cast<size_t>(currentCell.first);
136 size_t nCurY =
static_cast<size_t>(currentCell.second);
140 nCurY >=
static_cast<unsigned int>(
m_nYGridSize) || bVisited[nCurX][nCurY] ||
146 bVisited[nCurX][nCurY] =
true;
147 VCurrentCliffRegion.push_back(std::make_pair(nCurX, nCurY));
151 VStack.push_back(std::make_pair(nCurX - 1, nCurY));
152 VStack.push_back(std::make_pair(nCurX - 1, nCurY + 1));
153 VStack.push_back(std::make_pair(nCurX, nCurY + 1));
154 VStack.push_back(std::make_pair(nCurX + 1, nCurY + 1));
155 VStack.push_back(std::make_pair(nCurX + 1, nCurY));
156 VStack.push_back(std::make_pair(nCurX + 1, nCurY - 1));
157 VStack.push_back(std::make_pair(nCurX, nCurY - 1));
158 VStack.push_back(std::make_pair(nCurX - 1, nCurY - 1));
162 int dCliffRegionArea =
static_cast<int>(VCurrentCliffRegion.size());
165 if (dCliffRegionArea < dMinCliffCellThreshold) {
166 VSmallIslandCells.insert(VSmallIslandCells.end(),
167 VCurrentCliffRegion.begin(),
168 VCurrentCliffRegion.end());
175 for (
const auto &cell : VSmallIslandCells) {
176 m_pRasterGrid->m_Cell[cell.first][cell.second].SetAsCliff(
false);
191 vector<CGeom2DIPoint> V2DIPossibleStartCell;
192 vector<bool> VbPossibleStartCellHandedness;
193 vector<int> VnSearchDirection;
203 VbPossibleStartCellHandedness.push_back(
true);
204 VnSearchDirection.push_back(
EAST);
210 VbPossibleStartCellHandedness.push_back(
true);
211 VnSearchDirection.push_back(
SOUTH);
217 VbPossibleStartCellHandedness.push_back(
true);
218 VnSearchDirection.push_back(
WEST);
224 VbPossibleStartCellHandedness.push_back(
true);
225 VnSearchDirection.push_back(
NORTH);
235 int nCliffEdgesTraced = 0;
238 for (
size_t nStartPoint = 0; nStartPoint < V2DIPossibleStartCell.size();
240 int nXStart = V2DIPossibleStartCell[nStartPoint].nGetX();
241 int nYStart = V2DIPossibleStartCell[nStartPoint].nGetY();
244 if (bUsedInCliffTrace[nXStart][nYStart]) {
249 vector<CGeom2DIPoint> VCliffEdge;
250 int nSearchDirection = VnSearchDirection[nStartPoint];
260 bUsedInCliffTrace[nX][nY] =
true;
264 int nXSeaward, nYSeaward, nXStraightOn, nYStraightOn;
265 int nXAntiSeaward, nYAntiSeaward, nXGoBack, nYGoBack;
268 switch (nSearchDirection) {
273 nYStraightOn = nY - 1;
274 nXAntiSeaward = nX - 1;
282 nXStraightOn = nX + 1;
285 nYAntiSeaward = nY - 1;
293 nYStraightOn = nY + 1;
294 nXAntiSeaward = nX + 1;
302 nXStraightOn = nX - 1;
305 nYAntiSeaward = nY + 1;
310 nXSeaward = nXStraightOn = nXAntiSeaward = nXGoBack = nX;
311 nYSeaward = nYStraightOn = nYAntiSeaward = nYGoBack = nY;
317 bool bFoundNextCell =
false;
325 switch (nSearchDirection) {
327 nSearchDirection =
EAST;
330 nSearchDirection =
SOUTH;
333 nSearchDirection =
WEST;
336 nSearchDirection =
NORTH;
339 bFoundNextCell =
true;
343 m_pRasterGrid->m_Cell[nXStraightOn][nYStraightOn].bIsCliff()) {
347 bFoundNextCell =
true;
351 m_pRasterGrid->m_Cell[nXAntiSeaward][nYAntiSeaward].bIsCliff()) {
355 switch (nSearchDirection) {
357 nSearchDirection =
WEST;
360 nSearchDirection =
NORTH;
363 nSearchDirection =
EAST;
366 nSearchDirection =
SOUTH;
369 bFoundNextCell =
true;
378 bFoundNextCell =
true;
381 if (!bFoundNextCell) {
385 }
while ((nX != nXStart || nY != nYStart) && nLength < nMaxLength);
388 if (VCliffEdge.size() > 2) {
393 for (
const auto &point : VCliffEdge) {
396 bUsedInCliffTrace[point.nGetX()][point.nGetY()] =
true;
454 int nConsecutiveFailures = 0;
455 const int nMaxConsecutiveFailures = 2;
460 for (
int i = 0; i < nSize - 1; i++) {
462 int nPoint = bReverse ? (nSize - 1 - i) : i;
463 int nNextPoint = bReverse ? (nSize - 2 - i) : (i + 1);
466 if (nNextPoint < 0 || nNextPoint >= nSize)
477 int nNextX =
static_cast<int>(
480 int nNextY =
static_cast<int>(
487 nNextX = std::max(0, std::min(
m_nXGridSize - 1, nNextX));
488 nNextY = std::max(0, std::min(
m_nYGridSize - 1, nNextY));
491 int nDirX = nNextX - nX;
492 int nDirY = nNextY - nY;
495 int nLeftX = nX - nDirY;
496 int nLeftY = nY + nDirX;
497 int nRightX = nX + nDirY;
498 int nRightY = nY - nDirX;
500 bool bIsValidToe =
true;
505 bool bLeftIsCliff =
m_pRasterGrid->m_Cell[nLeftX][nLeftY].bIsCliff();
506 bool bRightIsCliff =
m_pRasterGrid->m_Cell[nRightX][nRightY].bIsCliff();
510 if (bLeftIsCliff != bRightIsCliff) {
515 m_pRasterGrid->m_Cell[nRightX][nRightY].dGetSedimentTopElev();
518 double dCliffElev, dNonCliffElev;
520 dCliffElev = dLeftElev;
521 dNonCliffElev = dRightElev;
523 dCliffElev = dRightElev;
524 dNonCliffElev = dLeftElev;
529 if (dNonCliffElev > dCliffElev) {
537 nConsecutiveFailures = 0;
543 nConsecutiveFailures++;
546 if (nConsecutiveFailures < nMaxConsecutiveFailures) {
556 return ValidatedEdge;