36using std::setiosflags;
37using std::setprecision;
48using std::normal_distribution;
60 return prLeft.second > prRight.second;
71 int nProfileGlobalID = -1;
73 for (
unsigned int nCoast = 0; nCoast <
m_VCoast.size(); nCoast++)
76 int nCoastSize =
m_VCoast[nCoast].nGetCoastlineSize();
79 vector<bool> bVCoastPointDone(nCoastSize,
false);
82 vector<pair<int, double>> prVCurvature;
83 for (
int nCoastPoint = 0; nCoastPoint < nCoastSize; nCoastPoint++)
89 dCurvature =
m_VCoast[nCoast].dGetSmoothCurvature(nCoastPoint);
94 dCurvature =
m_VCoast[nCoast].dGetDetailedCurvature(nCoastPoint);
96 prVCurvature.push_back(make_pair(nCoastPoint, dCurvature));
114 bVCoastPointDone[n] =
true;
116 int m = nCoastSize - n - 1;
118 bVCoastPointDone[m] =
true;
129 strErr +=
". Check the SWL";
149 m_VCoast[nCoast].InsertProfilesInProfileCoastPointIndex();
170 for (
int nCoastPoint = 0; nCoastPoint < nCoastSize; nCoastPoint++)
172 if (
m_VCoast[nCoast].bIsProfileAtCoastPoint(nCoastPoint))
174 pThisProfile =
m_VCoast[nCoast].pGetProfileAtCoastPoint(nCoastPoint);
177 if (nCoastPoint == 0)
183 pLastProfile = pThisProfile;
192 if (nCoastPoint == nCoastSize-1)
197 pLastProfile = pThisProfile;
203 m_VCoast[nCoast].CreateProfileDownCoastIndex();
271 int nCoastSize =
m_VCoast[nCoast].nGetCoastlineSize();
274 for (
int n = nCoastSize - 1; n >= 0; n--)
277 int nStillToSearch = 0;
278 for (
int m = 0; m < nCoastSize; m++)
279 if (! pbVCoastPointDone->at(m))
282 if (nStillToSearch == 0)
287 int nNormalPoint = prVCurvature->at(n).first;
290 if ((nNormalPoint == 0) || (nNormalPoint == nCoastSize - 1))
295 if (! pbVCoastPointDone->at(nNormalPoint))
298 bool bIntervention =
false;
302 bIntervention =
true;
308 int nRet =
nCreateProfile(nCoast, nCoastSize, nNormalPoint, nProfile, nProfileGlobalID, bIntervention, &PtiThis);
326 pbVCoastPointDone->at(nNormalPoint) =
true;
414 for (
int m = 1; m < dNumToMark; m++)
416 int nTmpPoint = nNormalPoint + m;
417 if (nTmpPoint < nCoastSize)
418 pbVCoastPointDone->at(nTmpPoint) =
true;
420 nTmpPoint = nNormalPoint - m;
422 pbVCoastPointDone->at(nTmpPoint) =
true;
447 int nXEnd = PtiEnd.
nGetX();
448 int nYEnd = PtiEnd.
nGetY();
451 if (!
m_pRasterGrid->m_Cell[nXEnd][nYEnd].bIsInContiguousSea())
469 CGeomProfile* pProfile =
new CGeomProfile(nCoast, nProfileStartPoint, nProfile, ++pnProfileGlobalID, pPtiStart, &PtiEnd, bIntervention);
472 vector<CGeom2DPoint> VNormal;
473 VNormal.push_back(PtStart);
474 VNormal.push_back(PtEnd);
484 m_VCoast[nCoast].AppendProfile(pProfile);
501 LogStream <<
m_ulIter <<
": coast " << nCoast <<
" profile " << nProfile <<
" (nCoastID = " << pProfile->
nGetCoastID() <<
" nGlobalID = " << pProfile->
nGetGlobalID() <<
") created at coast point " << nProfileStartPoint <<
" from [" << pPtiStart->
nGetX() <<
"][" << pPtiStart->
nGetY() <<
"] = {" << PtStart.
dGetX() <<
", " << PtStart.
dGetY() <<
"} to [" << PtiEnd.
nGetX() <<
"][" << PtiEnd.
nGetY() <<
"] = {" << PtEnd.
dGetX() <<
", " << PtEnd.
dGetY() <<
"}" << (pProfile->
bIsIntervention() ?
", from intervention" :
"") << endl;
511 int nCoastSize =
m_VCoast[nCoast].nGetCoastlineSize();
512 int nHandedness =
m_VCoast[nCoast].nGetSeaHandedness();
514 int nProfileStartEdge;
517 vector<CGeom2DIPoint> VPtiNormalPoints;
522 PtiProfileStart = *
m_VCoast[nCoast].pPtiGetCellMarkedAsCoastline(0);
523 nProfileStartEdge =
m_VCoast[nCoast].nGetStartEdge();
528 PtiProfileStart = *
m_VCoast[nCoast].pPtiGetCellMarkedAsCoastline(nCoastSize - 1);
529 nProfileStartEdge =
m_VCoast[nCoast].nGetEndEdge();
532 VPtiNormalPoints.push_back(PtiProfileStart);
546 int nPos =
static_cast<int>(it -
m_VEdgeCell.begin());
549 for (
int n = 0; n < nProfileLen; n++)
614 int nProfileStartPoint;
619 nProfileStartPoint = 0;
622 pProfile =
new CGeomProfile(nCoast, nProfileStartPoint, nProfile, ++nProfileGlobalID, &PtiProfileStart, &PtiDummy,
false);
629 nProfileStartPoint = nCoastSize-1;
632 pProfile =
new CGeomProfile(nCoast, nProfileStartPoint, nProfile, ++nProfileGlobalID, &PtiProfileStart, &PtiDummy,
false);
639 for (
unsigned int n = 0; n < VPtiNormalPoints.size(); n++)
641 int nX = VPtiNormalPoints[n].nGetX();
642 int nY = VPtiNormalPoints[n].nGetY();
655 if ((n == 0) || (n == VPtiNormalPoints.size()-1))
662 int nEndX = VPtiNormalPoints.back().nGetX();
663 int nEndY = VPtiNormalPoints.back().nGetY();
668 double dDeepWaterWaveHeight =
m_pRasterGrid->m_Cell[nEndX][nEndY].dGetCellDeepWaterWaveHeight();
669 double dDeepWaterWaveAngle =
m_pRasterGrid->m_Cell[nEndX][nEndY].dGetCellDeepWaterWaveAngle();
670 double dDeepWaterWavePeriod =
m_pRasterGrid->m_Cell[nEndX][nEndY].dGetCellDeepWaterWavePeriod();
682 m_VCoast[nCoast].AppendProfile(pProfile);
683 m_VCoast[nCoast].SetProfileAtCoastPoint(nProfileStartPoint, pProfile);
696 int const AVGSIZE = 21;
704 PtBefore = *
m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nStartCoastPoint-1);
705 PtAfter = *
m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nStartCoastPoint+1);
710 vector<CGeom2DPoint> PtBeforeToAverage;
711 for (
int n = 1; n <= AVGSIZE; n++)
713 int nPoint = nStartCoastPoint - n;
717 PtBeforeToAverage.push_back(*
m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nPoint));
721 vector<CGeom2DPoint> PtAfterToAverage;
722 for (
int n = 1; n <= AVGSIZE; n++)
724 int nPoint = nStartCoastPoint + n;
725 if (nPoint > nCoastSize-1)
728 PtAfterToAverage.push_back(*
m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nPoint));
732 PtBefore =
PtAverage(&PtBeforeToAverage);
737 double dYDiff = PtAfter.
dGetY() - PtBefore.
dGetY();
738 double dXDiff = PtAfter.
dGetX() - PtBefore.
dGetX();
740 double dXEnd1 = 0, dXEnd2 = 0, dYEnd1 = 0, dYEnd2 = 0;
745 dXEnd1 = dXEnd2 = pPtStart->
dGetX();
746 dYEnd1 = pPtStart->
dGetY() + dLineLength;
747 dYEnd2 = pPtStart->
dGetY() - dLineLength;
752 dYEnd1 = dYEnd2 = pPtStart->
dGetY();
753 dXEnd1 = pPtStart->
dGetX() + dLineLength;
754 dXEnd2 = pPtStart->
dGetX() - dLineLength;
759 double dA = dYDiff / dXDiff;
762 double dAPerp = -1 / dA;
763 double dBPerp = pPtStart->
dGetY() - (dAPerp * pPtStart->
dGetX());
766 double dQuadA = 1 + (dAPerp * dAPerp);
767 double dQuadB = 2 * ((dBPerp * dAPerp) - (dAPerp * pPtStart->
dGetY()) - pPtStart->
dGetX());
768 double dQuadC = ((pPtStart->
dGetX() * pPtStart->
dGetX()) + (pPtStart->
dGetY() * pPtStart->
dGetY()) + (dBPerp * dBPerp) - (2 * pPtStart->
dGetY() * dBPerp) - (dLineLength * dLineLength));
771 double dDiscriminant = (dQuadB * dQuadB) - (4 * dQuadA * dQuadC);
772 if (dDiscriminant < 0)
774 LogStream <<
ERR <<
"timestep " <<
m_ulIter <<
": discriminant < 0 when finding profile end point on coastline " << nCoast <<
", from coastline point " << nStartCoastPoint <<
"), ignored" << endl;
778 dXEnd1 = (-dQuadB + sqrt(dDiscriminant)) / (2 * dQuadA);
779 dYEnd1 = (dAPerp * dXEnd1) + dBPerp;
780 dXEnd2 = (-dQuadB - sqrt(dDiscriminant)) / (2 * dQuadA);
781 dYEnd2 = (dAPerp * dXEnd2) + dBPerp;
785 int nSeaHand =
m_VCoast[nCoast].nGetSeaHandedness();
786 *pPtEnd =
PtChooseEndPoint(nSeaHand, &PtBefore, &PtAfter, dXEnd1, dYEnd1, dXEnd2, dYEnd2);
825 PtChosen.
SetX(dXEnd1);
826 PtChosen.
SetY(dYEnd1);
830 PtChosen.
SetX(dXEnd2);
831 PtChosen.
SetY(dYEnd2);
834 else if (PtAfter->
dGetY() < PtBefore->
dGetY())
839 PtChosen.
SetX(dXEnd1);
840 PtChosen.
SetY(dYEnd1);
844 PtChosen.
SetX(dXEnd2);
845 PtChosen.
SetY(dYEnd2);
856 PtChosen.
SetX(dXEnd1);
857 PtChosen.
SetY(dYEnd1);
861 PtChosen.
SetX(dXEnd2);
862 PtChosen.
SetY(dYEnd2);
870 PtChosen.
SetX(dXEnd1);
871 PtChosen.
SetY(dYEnd1);
875 PtChosen.
SetX(dXEnd2);
876 PtChosen.
SetY(dYEnd2);
889 PtChosen.
SetX(dXEnd1);
890 PtChosen.
SetY(dYEnd1);
894 PtChosen.
SetX(dXEnd2);
895 PtChosen.
SetY(dYEnd2);
898 else if (PtAfter->
dGetY() < PtBefore->
dGetY())
903 PtChosen.
SetX(dXEnd1);
904 PtChosen.
SetY(dYEnd1);
908 PtChosen.
SetX(dXEnd2);
909 PtChosen.
SetY(dYEnd2);
920 PtChosen.
SetX(dXEnd1);
921 PtChosen.
SetY(dYEnd1);
925 PtChosen.
SetX(dXEnd2);
926 PtChosen.
SetY(dYEnd2);
934 PtChosen.
SetX(dXEnd1);
935 PtChosen.
SetY(dYEnd1);
939 PtChosen.
SetX(dXEnd2);
940 PtChosen.
SetY(dYEnd2);
955 int nCoastLines =
static_cast<int>(
m_VCoast.size());
956 for (
int nCoast = 0; nCoast < nCoastLines; nCoast++)
958 int nCoastSize =
m_VCoast[nCoast].nGetCoastlineSize();
961 for (
int nCoastPoint = 0; nCoastPoint < nCoastSize; nCoastPoint++)
963 if (!
m_VCoast[nCoast].bIsProfileAtCoastPoint(nCoastPoint))
983 nStartPoint = nCoastPoint + 1;
985 nStartPoint = nCoastPoint - 1;
987 for (
int nSecondCoastPoint = nStartPoint; (nDirection ==
DIRECTION_DOWNCOAST) ? nSecondCoastPoint < nCoastSize : nSecondCoastPoint >= 0; (nDirection ==
DIRECTION_DOWNCOAST) ? nSecondCoastPoint++ : nSecondCoastPoint--)
997 if (
m_VCoast[nCoast].bIsProfileAtCoastPoint(nSecondCoastPoint))
1001 int nSecondProfile = pSecondProfile->
nGetCoastID();
1020 int nProf1LineSeg = 0;
1021 int nProf2LineSeg = 0;
1022 double dIntersectX = 0;
1023 double dIntersectY = 0;
1024 double dAvgEndX = 0;
1025 double dAvgEndY = 0;
1027 if (
bCheckForIntersection(pFirstProfile, pSecondProfile, nProf1LineSeg, nProf2LineSeg, dIntersectX, dIntersectY, dAvgEndX, dAvgEndY))
1034 LogStream <<
m_ulIter <<
": profiles " << nFirstProfile <<
" and " << nSecondProfile <<
" intersect, truncate " << nFirstProfile <<
" since it is an intervention profile"<< endl;
1042 LogStream <<
m_ulIter <<
": profiles " << nFirstProfile <<
" and " << nSecondProfile <<
" intersect, truncate " << nSecondProfile <<
" since it is an intervention profile"<< endl;
1051 LogStream <<
m_ulIter <<
": profiles " << nFirstProfile <<
" and " << nSecondProfile <<
" intersect, but point {" << dIntersectX <<
", " << dIntersectY <<
"} is already present in profile " << nFirstProfile <<
" as point " << nPoint << endl;
1060 LogStream <<
m_ulIter <<
": profiles " << nFirstProfile <<
" and " << nSecondProfile <<
" intersect, but point {" << dIntersectX <<
", " << dIntersectY <<
"} is already present in profile " << nSecondProfile <<
" as point " << nPoint << endl;
1076 if ((nProf1LineSeg == (nFirstProfileLineSegments - 1)) && (nProf2LineSeg == (nSecondProfileLineSegments - 1)))
1079 MergeProfilesAtFinalLineSegments(nCoast, pFirstProfile, pSecondProfile, nFirstProfileLineSegments, nSecondProfileLineSegments, dIntersectX, dIntersectY, dAvgEndX, dAvgEndY);
1081 LogStream <<
m_ulIter <<
": " << ((nDirection ==
DIRECTION_DOWNCOAST) ?
"down" :
"up") <<
"-coast search, end-segment intersection between profiles " << nFirstProfile <<
" and " << nSecondProfile <<
" at [" << dIntersectX <<
", " << dIntersectY <<
"] in line segment [" << nProf1LineSeg <<
"] of " << nFirstProfileLineSegments <<
" segments, and line segment [" << nProf2LineSeg <<
"] of " << nSecondProfileLineSegments <<
" segments, respectively" << endl;
1098 LogStream <<
m_ulIter <<
": " << ((nDirection ==
DIRECTION_DOWNCOAST) ?
"down" :
"up") <<
"-coast search, intersection (NOT both end segments) between profiles " << nFirstProfile <<
" and " << nSecondProfile <<
" at [" << dIntersectX <<
", " << dIntersectY <<
"] in line segment [" << nProf1LineSeg <<
"] of " << nFirstProfileLineSegments <<
", and line segment [" << nProf2LineSeg <<
"] of " << nSecondProfileLineSegments <<
", respectively" << endl;
1104 LogStream <<
m_ulIter <<
": pFirstProfile = " << pFirstProfile->
nGetCoastID() <<
" pSecondProfile = " << pSecondProfile->
nGetCoastID() <<
", pFirstProfile is an intervention profile, so truncate pFirstProfile (" << pFirstProfile->
nGetCoastID() <<
")" << endl;
1111 LogStream <<
m_ulIter <<
": pFirstProfile = " << pFirstProfile->
nGetCoastID() <<
" pSecondProfile = " << pSecondProfile->
nGetCoastID() <<
", pSecondProfile is an intervention profile, so truncate pSecondProfile (" << pSecondProfile->
nGetCoastID() <<
")" << endl;
1115 else if (nFirstProfileLineSegments < nSecondProfileLineSegments)
1118 LogStream <<
m_ulIter <<
": pFirstProfile = " << pFirstProfile->
nGetCoastID() <<
" pSecondProfile = " << pSecondProfile->
nGetCoastID() <<
", pFirstProfile has a smaller number of line segments, so truncate pFirstProfile (" << pFirstProfile->
nGetCoastID() <<
")" << endl;
1122 else if (nFirstProfileLineSegments > nSecondProfileLineSegments)
1125 LogStream <<
m_ulIter <<
": pFirstProfile = " << pFirstProfile->
nGetCoastID() <<
" pSecondProfile = " << pSecondProfile->
nGetCoastID() <<
", pSecondProfile has a smaller number of line segments, so truncate pSecondProfile (" << pSecondProfile->
nGetCoastID() <<
")" << endl;
1135 LogStream <<
m_ulIter <<
": pFirstProfile = " << pFirstProfile->
nGetCoastID() <<
" pSecondProfile = " << pSecondProfile->
nGetCoastID() <<
", same number of line segment, randomly truncate pFirstProfile" << endl;
1140 LogStream <<
m_ulIter <<
": pFirstProfile = " << pFirstProfile->
nGetCoastID() <<
" pSecondProfile = " << pSecondProfile->
nGetCoastID() <<
", same number of line segment, randomly truncate pSecondProfile" << endl;
1163 for (
unsigned int nCoast = 0; nCoast <
m_VCoast.size(); nCoast++)
1165 for (
int n = 0; n <
m_VCoast[nCoast].nGetNumProfiles(); n++)
1178 m_VCoast[nCoast].pGetProfile(nProfile)->SetTooShort(
true);
1179 LogStream <<
"Profile " << nProfile <<
" is too short, size = " << nSize << endl;
1185 int nXEnd = PtiEnd.
nGetX();
1186 int nYEnd = PtiEnd.
nGetY();
1191 nXEnd =
tMax(nXEnd, 0);
1192 nYEnd =
tMax(nYEnd, 0);
1195 m_VCoast[nCoast].pGetProfile(nProfile)->SetEndPoint(&PtiEnd);
1200 LogStream <<
m_ulIter <<
": coast " << nCoast <<
", profile " << nProfile <<
" is invalid, is too short for depth of closure " <<
m_dDepthOfClosure <<
" at end point [" << nXEnd <<
"][" << nYEnd <<
"] = {" << pPtEnd->
dGetX() <<
", " << pPtEnd->
dGetY() <<
"}, flagging as too short" << endl;
1203 m_VCoast[nCoast].pGetProfile(nProfile)->SetTooShort(
true);
1209 int nValidProfiles = 0;
1212 if (nValidProfiles == 0)
1215 cerr <<
m_ulIter <<
": " <<
ERR <<
"no coastline-normal profiles created" << endl;
1281 for (
int i = 0; i < nProfile1NumSegments; i++)
1283 for (
int j = 0; j < nProfile2NumSegments; j++)
1288 double dX2 = pVProfile1->
pPtVGetPoints()->at(i + 1).dGetX();
1289 double dY2 = pVProfile1->
pPtVGetPoints()->at(i + 1).dGetY();
1293 double dX4 = pVProfile2->
pPtVGetPoints()->at(j + 1).dGetX();
1294 double dY4 = pVProfile2->
pPtVGetPoints()->at(j + 1).dGetY();
1297 double dDiffX1 = dX2 - dX1;
1298 double dDiffY1 = dY2 - dY1;
1299 double dDiffX2 = dX4 - dX3;
1300 double dDiffY2 = dY4 - dY3;
1306 dTmp = -dDiffX2 * dDiffY1 + dDiffX1 * dDiffY2;
1308 dS = (-dDiffY1 * (dX1 - dX3) + dDiffX1 * (dY1 - dY3)) / dTmp;
1310 dTmp = -dDiffX2 * dDiffY1 + dDiffX1 * dDiffY2;
1312 dT = (dDiffX2 * (dY1 - dY3) - dDiffY2 * (dX1 - dX3)) / dTmp;
1314 if (dS >= 0 && dS <= 1 && dT >= 0 && dT <= 1)
1317 dXIntersect = dX1 + (dT * dDiffX1);
1318 dYIntersect = dY1 + (dT * dDiffY1);
1321 dXAvgEnd = (dX2 + dX4) / 2;
1322 dYAvgEnd = (dY2 + dY4) / 2;
1325 nProfile1LineSegment = i;
1326 nProfile2LineSegment = j;
1344 int nProfiles =
m_VCoast[nCoast].nGetNumProfiles();
1354 static bool bDownCoast =
true;
1357 for (
int n = 0; n < nProfiles; n++)
1362 pProfile =
m_VCoast[nCoast].pGetProfileWithDownCoastSeq(n);
1364 pProfile =
m_VCoast[nCoast].pGetProfileWithUpCoastSeq(n);
1383 m_VCoast[nCoast].pGetProfile(nProfile)->SetTooShort(
true);
1386 LogStream <<
m_ulIter <<
": coast " << nCoast <<
", profile " << nProfile <<
" is invalid, has only " << nPoints <<
" points" << endl;
1392 vector<CGeom2DIPoint> VCellsToMark;
1393 vector<bool> bVShared;
1394 bool bTooShort =
false;
1395 bool bTruncated =
false;
1396 bool bHitCoast =
false;
1397 bool bHitLand =
false;
1398 bool bHitIntervention =
false;
1399 bool bHitAnotherProfile =
false;
1401 CreateRasterizedProfile(nCoast, pProfile, &VCellsToMark, &bVShared, bTooShort, bTruncated, bHitCoast, bHitLand, bHitIntervention, bHitAnotherProfile);
1403 if ((bTruncated && (!
ACCEPT_TRUNCATED_PROFILES)) || bTooShort || bHitCoast || bHitLand || bHitIntervention || bHitAnotherProfile || VCellsToMark.size() == 0)
1409 for (
unsigned int k = 0; k < VCellsToMark.size(); k++)
1412 if ((k > 0) && (VCellsToMark[k] ==
m_VCoast[nCoast].pGetProfile(nProfile)->pPtiGetLastCellInProfile()))
1416 m_pRasterGrid->m_Cell[VCellsToMark[k].nGetX()][VCellsToMark[k].nGetY()].SetProfileID(nProfile);
1419 m_VCoast[nCoast].pGetProfile(nProfile)->AppendCellInProfile(VCellsToMark[k].nGetX(), VCellsToMark[k].nGetY());
1439 double dDeepWaterWaveHeight =
m_pRasterGrid->m_Cell[VCellsToMark.back().nGetX()][VCellsToMark.back().nGetY()].dGetCellDeepWaterWaveHeight();
1440 double dDeepWaterWaveAngle =
m_pRasterGrid->m_Cell[VCellsToMark.back().nGetX()][VCellsToMark.back().nGetY()].dGetCellDeepWaterWaveAngle();
1441 double dDeepWaterWavePeriod =
m_pRasterGrid->m_Cell[VCellsToMark.back().nGetX()][VCellsToMark.back().nGetY()].dGetCellDeepWaterWavePeriod();
1444 m_VCoast[nCoast].pGetProfile(nProfile)->SetProfileDeepWaterWaveHeight(dDeepWaterWaveHeight);
1445 m_VCoast[nCoast].pGetProfile(nProfile)->SetProfileDeepWaterWaveAngle(dDeepWaterWaveAngle);
1446 m_VCoast[nCoast].pGetProfile(nProfile)->SetProfileDeepWaterWavePeriod(dDeepWaterWavePeriod);
1449 bDownCoast = ! bDownCoast;
1455void CSimulation::CreateRasterizedProfile(
int const nCoast,
CGeomProfile* pProfile, vector<CGeom2DIPoint>* pVIPointsOut, vector<bool>* pbVShared,
bool& bTooShort,
bool& bTruncated,
bool& bHitCoast,
bool& bHitLand,
bool& bHitIntervention,
bool& bHitAnotherProfile)
1461 pVIPointsOut->clear();
1470 for (nSeg = 0; nSeg < nNumSegments; nSeg++)
1493 if (PtiSegStart == PtiSegEnd)
1496 int nXStart = PtiSegStart.
nGetX();
1497 int nYStart = PtiSegStart.
nGetY();
1498 int nXEnd = PtiSegEnd.
nGetX();
1499 int nYEnd = PtiSegEnd.
nGetY();
1501 bool bShared =
false;
1507 if ((nXStart == nXStartLast) && (nYStart == nYStartLast) && (nXEnd == nXEndLast) && (nYEnd == nYEndLast))
1512 double dXInc = nXEnd - nXStart;
1513 double dYInc = nYEnd - nYStart;
1519 double dX = nXStart;
1520 double dY = nYStart;
1523 for (
int m = 0; m <=
nRound(dLength); m++)
1588 bHitIntervention =
true;
1601 int nHitProfile =
m_pRasterGrid->m_Cell[nX][nY].nGetProfileID();
1610 bHitAnotherProfile =
true;
1619 pbVShared->push_back(bShared);
1626 nXStartLast = nXStart;
1627 nYStartLast = nYStart;
1637 if (nSeg < (nNumSegments - 1))
1642 int nLastX = pVIPointsOut->at(pVIPointsOut->size() - 1).nGetX();
1643 int nLastY = pVIPointsOut->at(pVIPointsOut->size() - 1).nGetY();
1657 if (pVIPointsOut->size() < 3)
1666 LogStream <<
m_ulIter <<
": profile " << nProfile <<
" is invalid, is too short, only " << pVIPointsOut->size() <<
" points, HitLand?" << bHitLand <<
". From [" << pVIPointsOut->at(0).nGetX() <<
"][" << pVIPointsOut->at(0).nGetY() <<
"] = {" <<
dGridCentroidXToExtCRSX(pVIPointsOut->at(0).nGetX()) <<
", " <<
dGridCentroidYToExtCRSY(pVIPointsOut->at(0).nGetY()) <<
"} to [" << pVIPointsOut->at(pVIPointsOut->size() - 1).nGetX() <<
"][" << pVIPointsOut->at(pVIPointsOut->size() - 1).nGetY() <<
"] = {" <<
dGridCentroidXToExtCRSX(pVIPointsOut->at(pVIPointsOut->size() - 1).nGetX()) <<
", " <<
dGridCentroidYToExtCRSY(pVIPointsOut->at(pVIPointsOut->size() - 1).nGetY()) <<
"}" << endl;
1677 int nCombinedLastSeg = 0;
1678 vector<pair<int, int>> prVCombinedProfilesCoincidentProfilesLastSeg;
1682 pair<int, int> prTmp;
1686 bool bFound =
false;
1687 for (
unsigned int m = 0; m < prVCombinedProfilesCoincidentProfilesLastSeg.size(); m++)
1689 if (prVCombinedProfilesCoincidentProfilesLastSeg[m].first == prTmp.first)
1698 prVCombinedProfilesCoincidentProfilesLastSeg.push_back(prTmp);
1705 pair<int, int> prTmp;
1709 bool bFound =
false;
1710 for (
unsigned int m = 0; m < prVCombinedProfilesCoincidentProfilesLastSeg.size(); m++)
1712 if (prVCombinedProfilesCoincidentProfilesLastSeg[m].first == prTmp.first)
1721 prVCombinedProfilesCoincidentProfilesLastSeg.push_back(prTmp);
1727 for (
int m = 0; m < nCombinedLastSeg; m++)
1728 prVCombinedProfilesCoincidentProfilesLastSeg[m].second++;
1732 int nNumFirstProfileCoincidentProfilesLastSeg =
static_cast<int>(prVFirstProfileCoincidentProfilesLastSeg.size());
1733 int nNumSecondProfileCoincidentProfilesLastSeg =
static_cast<int>(prVSecondProfileCoincidentProfilesLastSeg.size());
1738 for (
int n = 0; n < nNumFirstProfileCoincidentProfilesLastSeg; n++)
1740 int nThisProfile = prVFirstProfileCoincidentProfilesLastSeg[n].first;
1749 for (
int n = 0; n < nNumSecondProfileCoincidentProfilesLastSeg; n++)
1751 int nThisProfile = prVSecondProfileCoincidentProfilesLastSeg[n].first;
1760 for (
int nThisLineSeg = 0; nThisLineSeg < nNumFirstProfileCoincidentProfilesLastSeg; nThisLineSeg++)
1762 int nThisProfile = prVFirstProfileCoincidentProfilesLastSeg[nThisLineSeg].first;
1770 for (
int m = 0; m < nCombinedLastSeg; m++)
1775 for (
int nThisLineSeg = 0; nThisLineSeg < nNumSecondProfileCoincidentProfilesLastSeg; nThisLineSeg++)
1777 int nThisProfile = prVSecondProfileCoincidentProfilesLastSeg[nThisLineSeg].first;
1785 for (
int m = 0; m < nCombinedLastSeg; m++)
1856 int nRet =
nInsertPointIntoProfilesIfNeededThenUpdate(nCoast, pProfileToRetain, dIntersectX, dIntersectY, nProfileToRetainIntersectLineSeg, pProfileToTruncate, nProfileToTruncateIntersectLineSeg, bAlreadyPresent);
1864 vector<CGeom2DPoint> PtVProfileLastPart;
1865 vector<vector<pair<int, int>>> prVLineSegLastPart;
1866 if (bAlreadyPresent)
1881 TruncateProfileAndAppendNew(nCoast, pProfileToTruncate, nProfileToTruncateIntersectLineSeg, &PtVProfileLastPart, &prVLineSegLastPart);
1957 int nProfileToRetain = pProfileToRetain->
nGetCoastID();
1961 int nNumCoincident =
static_cast<int>(prVCoincidentProfiles.size());
1962 vector<int> nLineSegAfterIntersect(nNumCoincident, -1);
1965 for (
int nn = 0; nn < nNumCoincident; nn++)
1967 int nThisProfile = prVCoincidentProfiles[nn].first;
1968 int nThisLineSeg = prVCoincidentProfiles[nn].second;
1972 if (! bAlreadyPresent)
1978 LogStream <<
WARN <<
m_ulIter <<
": cannot insert a line segment after the final line segment (" << nThisLineSeg <<
") for " << (nThisProfile == nProfileToRetain ?
"main" :
"co-incident") <<
" profile (" << nThisProfile <<
"), abandoning" << endl;
1987 nLineSegAfterIntersect[nn] = nThisLineSeg + 1;
1995 int nNumToTruncateCoincident =
static_cast<int>(prVToTruncateCoincidentProfiles.size());
1998 for (
int nn = 0; nn < nNumCoincident; nn++)
2000 int nThisProfile = prVCoincidentProfiles[nn].first;
2007 for (
int nLineSeg = nLineSegAfterIntersect[nn], nIncr = 0; nLineSeg < nNumLineSegs; nLineSeg++, nIncr++)
2018 for (
int m = 0; m < nNumToTruncateCoincident; m++)
2020 int nProfileToAdd = prVToTruncateCoincidentProfiles[m].first;
2021 int nProfileToAddLineSeg = prVToTruncateCoincidentProfiles[m].second;
2122 int nNumCoincident =
static_cast<int>(prVCoincidentProfiles.size());
2124 for (
int nn = 0; nn < nNumCoincident; nn++)
2127 int nThisProfile = prVCoincidentProfiles[nn].first;
2128 int nThisProfileLineSeg = prVCoincidentProfiles[nn].second;
2142 for (
unsigned int mm = 0; mm < pPtVProfileLastPart->size(); mm++)
2149 for (
unsigned int mm = 0; mm < pprVLineSegLastPart->size(); mm++)
2151 vector<pair<int, int>> prVTmp = pprVLineSegLastPart->at(mm);
2158 vector<int> nVProfsLineSeg;
2163 int nProf = pThisProfile->
nGetProf(nSeg, nCoinc);
2166 auto it = find(nVProf.begin(), nVProf.end(), nProf);
2167 if (it == nVProf.end())
2170 nVProf.push_back(nProf);
2171 nVProfsLineSeg.push_back(nProfsLineSeg);
2176 int nPos =
static_cast<int>(it - nVProf.begin());
2177 int nNewProfsLineSeg = nVProfsLineSeg[nPos];
2180 nVProfsLineSeg[nPos] = nNewProfsLineSeg;
vector< CGeom2DPoint > * pPtVGetPoints(void)
Returns the address of the vector which represents this 2D shape.
Geometry class used to represent 2D point objects with integer coordinates.
int nGetY(void) const
Returns the CGeom2DIPoint object's integer Y coordinate.
void SetXY(int const, int const)
The two integer parameters set values for the CGeom2DIPoint object's X and Y coordinates.
int nGetX(void) const
Returns the CGeom2DIPoint object's integer X coordinate.
Geometry class used to represent 2D point objects with floating-point coordinates.
void SetY(double const)
The double parameter sets a value for the CGeom2DIPoint object's Y coordinate.
double dGetY(void) const
Returns the CGeom2DPoint object's double Y coordinate.
double dGetX(void) const
Returns the CGeom2DPoint object's double X coordinate.
void SetX(double const)
The double parameter sets a value for the CGeom2DIPoint object's X coordinate.
int nGetProfsLineSeg(int const, int const) const
Returns the profile's own line segment, given a line segment and the index of the co-incident profile...
bool bFindProfileInCoincidentProfilesOfLastLineSegment(int const)
Returns true if the given profile number is amongst the coincident profiles of the CGeomMultiLine obj...
int nGetNumCoincidentProfilesInLineSegment(int const)
Returns the count of coincident profiles in a specified line segment, or -1 if the line segment does ...
void AppendLineSegment(void)
Appends a new empty line segment.
int nGetProf(int const, int const) const
Returns the profile number, given a line segment and the index of the co-incident profile for that li...
void TruncateLineSegments(int const)
Cuts short the number of line segments.
vector< vector< pair< int, int > > > prVVGetAllLineSegAfter(int const)
Returns a vector of the line segments which succeed the specified line segment number.
void AppendCoincidentProfileToLineSegments(pair< int, int > const)
Appends a coincident profile pair to the CGeomMultiLine object's final line segment.
void SetProfsLineSeg(int const, int const, int const)
Sets a profile's own line segment number, given a line segment and the index of the co-incident profi...
vector< pair< int, int > > * pprVGetPairedCoincidentProfilesForLineSegment(int const)
Returns a vector of pairs (a line segment)
void AddCoincidentProfileToExistingLineSegment(int const, int const, int const)
Adds a coincident profile to a pre-existing line segment of the CGeomMultiLine object.
int nGetNumLineSegments(void) const
Appends a line segment which then inherits from the preceding line segments.
Geometry class used to represent coast profile objects.
void TruncateProfile(int const)
Truncates the profile.
void SetEndOfCoast(bool const)
Sets a switch to indicate whether this is an end-of-coast profile.
void AppendPointInProfile(double const, double const)
Appends a point to the profile.
void SetProfileDeepWaterWavePeriod(double const)
Sets the deep-water wave Period for this profile.
bool bIsPointInProfile(double const, double const)
Removes a line segment from the profile.
void SetHitCoast(bool const)
Sets a switch which indicates whether this profile has hit a coast.
bool bProfileOKIncTruncated(void) const
Returns true if this is a problem-free profile, and is not a start-of-coast or an end-of-coast profil...
void SetStartOfCoast(bool const)
Sets a switch to indicate whether this is a start-of-coast profile.
void AppendCellInProfileExtCRS(double const, double const)
Appends a cell (specified in the external coordinate system) to the profile.
void SetUpCoastAdjacentProfile(CGeomProfile *)
void SetHitAnotherProfile(bool const)
Sets a switch which indicates whether this profile hits another profile badly.
vector< CGeom2DPoint > PtVGetThisPointAndAllAfter(int const)
Returns a given point from the profile, and all points after this.
void SetTruncated(bool const)
Sets a switch which indicates whether this profile is truncated.
bool bInsertIntersection(double const, double const, int const)
Inserts an intersection into the profile.
bool bProfileOK(void) const
Returns true if this is a problem-free profile, and is not a start-of-coast or an end-of-coast profil...
void SetProfileDeepWaterWaveHeight(double const)
Sets the deep-water wave height for this profile.
void SetDownCoastAdjacentProfile(CGeomProfile *)
bool bIsIntervention(void) const
Returns true if this is an intervention profile.
int nGetGlobalID(void) const
Returns the profile's global ID.
void SetHitIntervention(bool const)
Sets a switch which indicates whether this profile has hit an intervention.
CGeom2DPoint * pPtGetPointInProfile(int const)
Returns a single point in the profile.
int nGetCoastID(void) const
Returns the profile's coast ID.
void AppendCellInProfile(CGeom2DIPoint const *)
Appends a cell to the profile.
void SetPointInProfile(int const, double const, double const)
Sets a single point in the profile.
int nGetProfileSize(void) const
Returns the number of points in the profile.
CGeom2DIPoint * pPtiGetStartPoint(void)
Returns a pointer to the location of the cell (grid CRS) on which the profile starts.
bool bStartOfCoast(void) const
Returns the switch to indicate whether this is a start-of-coast profile.
void SetEndPoint(CGeom2DIPoint const *)
Sets the the location of the cell (grid CRS) on which the profile ends.
void SetHitLand(bool const)
Sets a switch which indicates whether this profile has hit land.
void SetPointsInProfile(vector< CGeom2DPoint > const *)
Sets all points in the profile.
bool bEndOfCoast(void) const
Returns the switch to indicate whether this is an end-of-coast profile.
void SetProfileDeepWaterWaveAngle(double const)
Sets the deep-water wave orientation for this profile.
void SetTooShort(bool const)
Sets a switch which indicates whether this profile is too short to be useful.
int m_nLogFileDetail
The level of detail in the log file output. Can be LOG_FILE_LOW_DETAIL, LOG_FILE_MIDDLE_DETAIL,...
double m_dThisIterSWL
The still water level for this timestep (this includes tidal changes and any long-term SWL change)
CGeomRasterGrid * m_pRasterGrid
Pointer to the raster grid object.
int m_nXGridSize
The size of the grid in the x direction.
CGeom2DIPoint PtiExtCRSToGridRound(CGeom2DPoint const *) const
Transforms a pointer to a CGeom2DPoint in the external CRS to the equivalent CGeom2DIPoint in the ras...
vector< CRWCoast > m_VCoast
The coastline objects.
double m_dCoastNormalLength
Length of the coastline-normal profiles, in m.
void MarkProfilesOnGrid(int const, int &)
For this coastline, marks all coastline-normal profiles (apart from the two 'special' ones at the sta...
static CGeom2DPoint PtChooseEndPoint(int const, CGeom2DPoint const *, CGeom2DPoint const *, double const, double const, double const, double const)
Choose which end point to use for the coastline-normal profile.
int m_nYGridSize
The size of the grid in the y direction.
normal_distribution< double > m_dGetFromUnitNormalDist
c++11 unit normal distribution (mean = 0, stdev = 1)
void CreateRasterizedProfile(int const, CGeomProfile *, vector< CGeom2DIPoint > *, vector< bool > *, bool &, bool &, bool &, bool &, bool &, bool &)
Given a pointer to a coastline-normal profile, returns an output vector of cells which are 'under' ev...
static CGeom2DPoint PtAverage(CGeom2DPoint const *, CGeom2DPoint const *)
Returns a point (external CRS) which is the average of (i.e. is midway between) two other external CR...
int nLocateAndCreateGridEdgeProfile(bool const, int const, int &, int &)
Creates a 'special' profile at each end of a coastline, at the edge of the raster grid....
int m_nCoastNormalSpacing
Average spacing between coastline normals, measured in cells.
void MergeProfilesAtFinalLineSegments(int const, CGeomProfile *, CGeomProfile *, int const, int const, double const, double const, double const, double const)
Merges two profiles which intersect at their final (most seaward) line segments, seaward of their poi...
int m_nCoastNormalInterventionSpacing
Average spacing between coastline normals on interventions, measured in cells.
void CheckForIntersectingProfiles(void)
Checks all coastline-normal profiles for intersection, and modifies those that intersect.
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...
vector< CGeom2DIPoint > m_VEdgeCell
Edge cells.
static bool bCheckForIntersection(CGeomProfile *const, CGeomProfile *const, int &, int &, double &, double &, double &, double &)
Checks all line segments of a pair of coastline-normal profiles for intersection. If the lines inters...
int nGetCoastNormalEndPoint(int const, int const, int const, CGeom2DPoint const *, double const, CGeom2DPoint *, CGeom2DIPoint *, bool const)
Finds the end point of a coastline-normal line, given the start point on the vector coastline....
void TruncateProfileAndAppendNew(int const, CGeomProfile *, int const, vector< CGeom2DPoint > const *, vector< vector< pair< int, int > > > const *)
Truncate a profile at the point of intersection, and do the same for all its co-incident profiles.
double dExtCRSXToGridX(double const) const
Transforms an X-axis ordinate in the external CRS to the equivalent X-axis ordinate in the raster gri...
int nInsertPointIntoProfilesIfNeededThenUpdate(int const, CGeomProfile *, double const, double const, int const, CGeomProfile *, int const, bool const)
Inserts an intersection point into the profile that is to be retained, if that point is not already p...
void KeepWithinValidGrid(int, int, int &, int &) const
Given two points in the grid CRS (the points assumed not to be coincident), this routine modifies the...
default_random_engine m_Rand[NUMBER_OF_RNGS]
The c++11 random number generators.
int nCreateAllProfiles(void)
Create coastline-normal profiles for all coastlines. The first profiles are created 'around' the most...
double dExtCRSYToGridY(double const) const
Transforms a Y-axis ordinate in the external CRS to the equivalent Y-axis ordinate in the raster grid...
double m_dCoastNormalRandSpacingFactor
Random factor for spacing of along-coast normals.
bool bIsWithinValidGrid(int const, int const) const
Checks whether the supplied point (an x-y pair, in the grid CRS) is within the raster grid,...
int nCreateProfile(int const, int const, int const, int const, int &, bool const, CGeom2DIPoint const *)
Creates a single coastline-normal profile (which may be an intervention profile)
void LocateAndCreateProfiles(int const, int &, int &, vector< bool > *, vector< pair< int, double > > const *)
For a single coastline, locate the start points for all coastline-normal profiles (except the grid-ed...
static void AppendEnsureNoGap(vector< CGeom2DIPoint > *, CGeom2DIPoint const *)
Appends a CGeom2DIPoint to a vector<CGeom2DIPoint>, making sure that the new end point touches the pr...
unsigned long m_ulIter
The number of the current iteration (time step)
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...
void TruncateOneProfileRetainOtherProfile(int const, CGeomProfile *, CGeomProfile *, double, double, int, int, bool const)
Truncates one intersecting profile at the point of intersection, and retains the other profile.
double m_dCellSide
Length of a cell side (in external CRS units)
double m_dDepthOfClosure
Depth of closure (in m) TODO 007 can be calculated using Hallermeier, R.J. (1978) or Birkemeier (1985...
int nCheckAllProfiles(void)
Check all coastline-normal profiles and modify the profiles if they intersect, then mark valid profil...
vector< int > m_VEdgeCellEdge
The grid edge that each edge cell belongs to.
This file contains global definitions for CoastalME.
int const RTN_ERR_COAST_CANT_FIND_EDGE_CELL
int const DIRECTION_DOWNCOAST
bool const ACCEPT_TRUNCATED_PROFILES
int const LOG_FILE_MIDDLE_DETAIL
bool bFPIsEqual(const T d1, const T d2, const T dEpsilon)
int const RTN_ERR_PROFILE_END_INSUFFICIENT_DEPTH
int const PROFILE_CHECK_DIST_FROM_COAST
int const RTN_ERR_NO_PROFILES_2
int const RTN_ERR_PROFILE_ENDPOINT_IS_INLAND
int const RTN_ERR_NO_PROFILES_1
int const RTN_ERR_CANNOT_INSERT_POINT
int const DIRECTION_UPCOAST
string strDblToStr(const T &t)
int const RTN_ERR_NO_SOLUTION_FOR_ENDPOINT
int const LF_CAT_INTERVENTION
Contains CRWCoast definitions.
bool bCurvaturePairCompareDescending(const pair< int, double > &prLeft, const pair< int, double > &prRight)
Function used to sort coastline curvature values when locating start points of normal profiles.
Contains CSimulation definitions.
int nRound(double const d)
Version of the above that returns an int.