49using std::normal_distribution;
62bool bCurvaturePairCompareDescending(
const pair<int, double>& prLeft,
const pair<int, double>& prRight)
65 return prLeft.second > prRight.second;
77 int nProfileGlobalID = -1;
79 for (
unsigned int nCoast = 0; nCoast <
m_VCoast.size(); nCoast++)
82 int const nCoastSize =
m_VCoast[nCoast].nGetCoastlineSize();
85 vector<bool> bVCoastPointDone(nCoastSize,
false);
88 vector<pair<int, double>> prVCurvature;
90 for (
int nCoastPoint = 0; nCoastPoint < nCoastSize; nCoastPoint++)
97 dCurvature =
m_VCoast[nCoast].dGetSmoothCurvature(nCoastPoint);
103 dCurvature =
m_VCoast[nCoast].dGetDetailedCurvature(nCoastPoint);
106 prVCurvature.push_back(make_pair(nCoastPoint, dCurvature));
110 sort(prVCurvature.begin(), prVCurvature.end(), bCurvaturePairCompareDescending);
124 bVCoastPointDone[n] =
true;
126 int const m = nCoastSize - n - 1;
129 bVCoastPointDone[m] =
true;
141 strErr +=
". Check the SWL";
164 m_VCoast[nCoast].InsertProfilesInProfileCoastPointIndex();
185 for (
int nCoastPoint = 0; nCoastPoint < nCoastSize; nCoastPoint++)
187 if (
m_VCoast[nCoast].bIsProfileAtCoastPoint(nCoastPoint))
189 pThisProfile =
m_VCoast[nCoast].pGetProfileAtCoastPoint(nCoastPoint);
192 if (nCoastPoint == 0)
198 pLastProfile = pThisProfile;
207 if (nCoastPoint == nCoastSize - 1)
212 pLastProfile = pThisProfile;
218 m_VCoast[nCoast].CreateProfileDownCoastIndex();
285 int const nCoastSize =
m_VCoast[nCoast].nGetCoastlineSize();
288 for (
int n = nCoastSize - 1; n >= 0;
292 int nStillToSearch = 0;
294 for (
int m = 0; m < nCoastSize; m++)
295 if (!pbVCoastPointDone->at(m))
298 if (nStillToSearch == 0)
303 int const nNormalPoint = prVCurvature->at(n).first;
306 if ((nNormalPoint == 0) || (nNormalPoint == nCoastSize - 1))
311 if (!pbVCoastPointDone->at(nNormalPoint))
314 bool bIntervention =
false;
319 bIntervention =
true;
325 int const nRet =
nCreateProfile(nCoast, nCoastSize, nNormalPoint, nProfile, nProfileGlobalID, bIntervention, &PtiThis);
343 pbVCoastPointDone->at(nNormalPoint) =
true;
433 for (
int m = 1; m < dNumToMark; m++)
435 int nTmpPoint = nNormalPoint + m;
437 if (nTmpPoint < nCoastSize)
438 pbVCoastPointDone->at(nTmpPoint) =
true;
440 nTmpPoint = nNormalPoint - m;
443 pbVCoastPointDone->at(nTmpPoint) =
true;
469 int const nXEnd = PtiEnd.
nGetX();
470 int const nYEnd = PtiEnd.
nGetY();
473 if (!
m_pRasterGrid->m_Cell[nXEnd][nYEnd].bIsInContiguousSea())
491 CGeomProfile* pProfile =
new CGeomProfile(nCoast, nProfileStartPoint, nProfile, ++pnProfileGlobalID, pPtiStart, &PtiEnd, bIntervention);
494 vector<CGeom2DPoint> VNormal;
495 VNormal.push_back(PtStart);
496 VNormal.push_back(PtEnd);
506 m_VCoast[nCoast].AppendProfile(pProfile);
523 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;
533 int const nCoastSize =
m_VCoast[nCoast].nGetCoastlineSize();
534 int const nHandedness =
m_VCoast[nCoast].nGetSeaHandedness();
536 int nProfileStartEdge;
539 vector<CGeom2DIPoint> VPtiNormalPoints;
544 PtiProfileStart = *
m_VCoast[nCoast].pPtiGetCellMarkedAsCoastline(0);
545 nProfileStartEdge =
m_VCoast[nCoast].nGetStartEdge();
551 PtiProfileStart = *
m_VCoast[nCoast].pPtiGetCellMarkedAsCoastline(nCoastSize - 1);
552 nProfileStartEdge =
m_VCoast[nCoast].nGetEndEdge();
555 VPtiNormalPoints.push_back(PtiProfileStart);
570 int nPos =
static_cast<int>(it -
m_VEdgeCell.begin());
573 for (
int n = 0; n < nProfileLen; n++)
641 int nProfileStartPoint;
647 nProfileStartPoint = 0;
650 pProfile =
new CGeomProfile(nCoast, nProfileStartPoint, nProfile, ++nProfileGlobalID, &PtiProfileStart, &PtiDummy,
false);
658 nProfileStartPoint = nCoastSize - 1;
661 pProfile =
new CGeomProfile(nCoast, nProfileStartPoint, nProfile, ++nProfileGlobalID, &PtiProfileStart, &PtiDummy,
false);
668 for (
unsigned int n = 0; n < VPtiNormalPoints.size(); n++)
670 int const nX = VPtiNormalPoints[n].nGetX();
671 int const nY = VPtiNormalPoints[n].nGetY();
684 if ((n == 0) || (n == VPtiNormalPoints.size() - 1))
691 int const nEndX = VPtiNormalPoints.back().nGetX();
692 int const nEndY = VPtiNormalPoints.back().nGetY();
697 double const dDeepWaterWaveHeight =
m_pRasterGrid->m_Cell[nEndX][nEndY].dGetCellDeepWaterWaveHeight();
698 double const dDeepWaterWaveAngle =
m_pRasterGrid->m_Cell[nEndX][nEndY].dGetCellDeepWaterWaveAngle();
699 double const dDeepWaterWavePeriod =
m_pRasterGrid->m_Cell[nEndX][nEndY].dGetCellDeepWaterWavePeriod();
711 m_VCoast[nCoast].AppendProfile(pProfile);
712 m_VCoast[nCoast].SetProfileAtCoastPoint(nProfileStartPoint, pProfile);
725 int const AVGSIZE = 21;
733 PtBefore = *
m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nStartCoastPoint - 1);
734 PtAfter = *
m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nStartCoastPoint + 1);
740 vector<CGeom2DPoint> PtBeforeToAverage;
742 for (
int n = 1; n <= AVGSIZE; n++)
744 int const nPoint = nStartCoastPoint - n;
749 PtBeforeToAverage.push_back(*
m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nPoint));
753 vector<CGeom2DPoint> PtAfterToAverage;
755 for (
int n = 1; n <= AVGSIZE; n++)
757 int const nPoint = nStartCoastPoint + n;
759 if (nPoint > nCoastSize - 1)
762 PtAfterToAverage.push_back(*
m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nPoint));
766 PtBefore =
PtAverage(&PtBeforeToAverage);
771 double const dYDiff = PtAfter.
dGetY() - PtBefore.
dGetY();
772 double const dXDiff = PtAfter.
dGetX() - PtBefore.
dGetX();
774 double dXEnd1 = 0, dXEnd2 = 0, dYEnd1 = 0, dYEnd2 = 0;
779 dXEnd1 = dXEnd2 = pPtStart->
dGetX();
780 dYEnd1 = pPtStart->
dGetY() + dLineLength;
781 dYEnd2 = pPtStart->
dGetY() - dLineLength;
787 dYEnd1 = dYEnd2 = pPtStart->
dGetY();
788 dXEnd1 = pPtStart->
dGetX() + dLineLength;
789 dXEnd2 = pPtStart->
dGetX() - dLineLength;
795 double const dA = dYDiff / dXDiff;
798 double const dAPerp = -1 / dA;
799 double const dBPerp = pPtStart->
dGetY() - (dAPerp * pPtStart->
dGetX());
802 double const dQuadA = 1 + (dAPerp * dAPerp);
803 double const dQuadB = 2 * ((dBPerp * dAPerp) - (dAPerp * pPtStart->
dGetY()) - pPtStart->
dGetX());
804 double const dQuadC = ((pPtStart->
dGetX() * pPtStart->
dGetX()) + (pPtStart->
dGetY() * pPtStart->
dGetY()) + (dBPerp * dBPerp) - (2 * pPtStart->
dGetY() * dBPerp) - (dLineLength * dLineLength));
807 double const dDiscriminant = (dQuadB * dQuadB) - (4 * dQuadA * dQuadC);
809 if (dDiscriminant < 0)
811 LogStream <<
ERR <<
"timestep " <<
m_ulIter <<
": discriminant < 0 when finding profile end point on coastline " << nCoast <<
", from coastline point " << nStartCoastPoint <<
"), ignored" << endl;
815 dXEnd1 = (-dQuadB + sqrt(dDiscriminant)) / (2 * dQuadA);
816 dYEnd1 = (dAPerp * dXEnd1) + dBPerp;
817 dXEnd2 = (-dQuadB - sqrt(dDiscriminant)) / (2 * dQuadA);
818 dYEnd2 = (dAPerp * dXEnd2) + dBPerp;
822 int const nSeaHand =
m_VCoast[nCoast].nGetSeaHandedness();
823 *pPtEnd =
PtChooseEndPoint(nSeaHand, &PtBefore, &PtAfter, dXEnd1, dYEnd1, dXEnd2, dYEnd2);
863 PtChosen.
SetX(dXEnd1);
864 PtChosen.
SetY(dYEnd1);
869 PtChosen.
SetX(dXEnd2);
870 PtChosen.
SetY(dYEnd2);
874 else if (PtAfter->
dGetY() < PtBefore->
dGetY())
879 PtChosen.
SetX(dXEnd1);
880 PtChosen.
SetY(dYEnd1);
885 PtChosen.
SetX(dXEnd2);
886 PtChosen.
SetY(dYEnd2);
898 PtChosen.
SetX(dXEnd1);
899 PtChosen.
SetY(dYEnd1);
904 PtChosen.
SetX(dXEnd2);
905 PtChosen.
SetY(dYEnd2);
914 PtChosen.
SetX(dXEnd1);
915 PtChosen.
SetY(dYEnd1);
920 PtChosen.
SetX(dXEnd2);
921 PtChosen.
SetY(dYEnd2);
935 PtChosen.
SetX(dXEnd1);
936 PtChosen.
SetY(dYEnd1);
941 PtChosen.
SetX(dXEnd2);
942 PtChosen.
SetY(dYEnd2);
946 else if (PtAfter->
dGetY() < PtBefore->
dGetY())
951 PtChosen.
SetX(dXEnd1);
952 PtChosen.
SetY(dYEnd1);
957 PtChosen.
SetX(dXEnd2);
958 PtChosen.
SetY(dYEnd2);
970 PtChosen.
SetX(dXEnd1);
971 PtChosen.
SetY(dYEnd1);
976 PtChosen.
SetX(dXEnd2);
977 PtChosen.
SetY(dYEnd2);
986 PtChosen.
SetX(dXEnd1);
987 PtChosen.
SetY(dYEnd1);
992 PtChosen.
SetX(dXEnd2);
993 PtChosen.
SetY(dYEnd2);
1008 int const nCoastLines =
static_cast<int>(
m_VCoast.size());
1010 for (
int nCoast = 0; nCoast < nCoastLines; nCoast++)
1012 int const nCoastSize =
m_VCoast[nCoast].nGetCoastlineSize();
1015 for (
int nCoastPoint = 0; nCoastPoint < nCoastSize; nCoastPoint++)
1017 if (!
m_VCoast[nCoast].bIsProfileAtCoastPoint(nCoastPoint))
1022 int const nFirstProfile = pFirstProfile->
nGetCoastID();
1038 nStartPoint = nCoastPoint + 1;
1041 nStartPoint = nCoastPoint - 1;
1043 for (
int nSecondCoastPoint = nStartPoint; (nDirection ==
DIRECTION_DOWNCOAST) ? nSecondCoastPoint < nCoastSize : nSecondCoastPoint >= 0; (nDirection ==
DIRECTION_DOWNCOAST) ? nSecondCoastPoint++ : nSecondCoastPoint--)
1053 if (
m_VCoast[nCoast].bIsProfileAtCoastPoint(nSecondCoastPoint))
1057 int const nSecondProfile = pSecondProfile->
nGetCoastID();
1076 int nProf1LineSeg = 0;
1077 int nProf2LineSeg = 0;
1078 double dIntersectX = 0;
1079 double dIntersectY = 0;
1080 double dAvgEndX = 0;
1081 double dAvgEndY = 0;
1083 if (
bCheckForIntersection(pFirstProfile, pSecondProfile, nProf1LineSeg, nProf2LineSeg, dIntersectX, dIntersectY, dAvgEndX, dAvgEndY))
1090 LogStream <<
m_ulIter <<
": profiles " << nFirstProfile <<
" and " << nSecondProfile <<
" intersect, truncate " << nFirstProfile <<
" since it is an intervention profile" << endl;
1098 LogStream <<
m_ulIter <<
": profiles " << nFirstProfile <<
" and " << nSecondProfile <<
" intersect, truncate " << nSecondProfile <<
" since it is an intervention profile" << endl;
1107 LogStream <<
m_ulIter <<
": profiles " << nFirstProfile <<
" and " << nSecondProfile <<
" intersect, but point {" << dIntersectX <<
", " << dIntersectY <<
"} is already present in profile " << nFirstProfile <<
" as point " << nPoint << endl;
1116 LogStream <<
m_ulIter <<
": profiles " << nFirstProfile <<
" and " << nSecondProfile <<
" intersect, but point {" << dIntersectX <<
", " << dIntersectY <<
"} is already present in profile " << nSecondProfile <<
" as point " << nPoint << endl;
1132 if ((nProf1LineSeg == (nFirstProfileLineSegments - 1)) && (nProf2LineSeg == (nSecondProfileLineSegments - 1)))
1135 MergeProfilesAtFinalLineSegments(nCoast, pFirstProfile, pSecondProfile, nFirstProfileLineSegments, nSecondProfileLineSegments, dIntersectX, dIntersectY, dAvgEndX, dAvgEndY);
1174 else if (nFirstProfileLineSegments < nSecondProfileLineSegments)
1182 else if (nFirstProfileLineSegments > nSecondProfileLineSegments)
1228 for (
unsigned int nCoast = 0; nCoast <
m_VCoast.size(); nCoast++)
1230 for (
int n = 0; n <
m_VCoast[nCoast].nGetNumProfiles(); n++)
1243 m_VCoast[nCoast].pGetProfile(nProfile)->SetTooShort(
true);
1244 LogStream <<
"Profile " << nProfile <<
" is too short, size = " << nSize << endl;
1250 int nXEnd = PtiEnd.
nGetX();
1251 int nYEnd = PtiEnd.
nGetY();
1256 nXEnd =
tMax(nXEnd, 0);
1257 nYEnd =
tMax(nYEnd, 0);
1260 m_VCoast[nCoast].pGetProfile(nProfile)->SetEndPoint(&PtiEnd);
1265 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;
1268 m_VCoast[nCoast].pGetProfile(nProfile)->SetTooShort(
true);
1274 int nValidProfiles = 0;
1277 if (nValidProfiles == 0)
1280 cerr <<
m_ulIter <<
": " <<
ERR <<
"no coastline-normal profiles created" << endl;
1346 for (
int i = 0; i < nProfile1NumSegments; i++)
1348 for (
int j = 0; j < nProfile2NumSegments; j++)
1351 double const dX1 = pVProfile1->
pPtVGetPoints()->at(i).dGetX();
1352 double const dY1 = pVProfile1->
pPtVGetPoints()->at(i).dGetY();
1353 double const dX2 = pVProfile1->
pPtVGetPoints()->at(i + 1).dGetX();
1354 double const dY2 = pVProfile1->
pPtVGetPoints()->at(i + 1).dGetY();
1356 double const dX3 = pVProfile2->
pPtVGetPoints()->at(j).dGetX();
1357 double const dY3 = pVProfile2->
pPtVGetPoints()->at(j).dGetY();
1358 double const dX4 = pVProfile2->
pPtVGetPoints()->at(j + 1).dGetX();
1359 double const dY4 = pVProfile2->
pPtVGetPoints()->at(j + 1).dGetY();
1362 double const dDiffX1 = dX2 - dX1;
1363 double const dDiffY1 = dY2 - dY1;
1364 double const dDiffX2 = dX4 - dX3;
1365 double const dDiffY2 = dY4 - dY3;
1371 dTmp = -dDiffX2 * dDiffY1 + dDiffX1 * dDiffY2;
1374 dS = (-dDiffY1 * (dX1 - dX3) + dDiffX1 * (dY1 - dY3)) / dTmp;
1376 dTmp = -dDiffX2 * dDiffY1 + dDiffX1 * dDiffY2;
1379 dT = (dDiffX2 * (dY1 - dY3) - dDiffY2 * (dX1 - dX3)) / dTmp;
1381 if (dS >= 0 && dS <= 1 && dT >= 0 && dT <= 1)
1384 dXIntersect = dX1 + (dT * dDiffX1);
1385 dYIntersect = dY1 + (dT * dDiffY1);
1388 dXAvgEnd = (dX2 + dX4) / 2;
1389 dYAvgEnd = (dY2 + dY4) / 2;
1392 nProfile1LineSegment = i;
1393 nProfile2LineSegment = j;
1411 int const nProfiles =
m_VCoast[nCoast].nGetNumProfiles();
1422 static bool bDownCoast =
true;
1425 for (
int n = 0; n < nProfiles; n++)
1430 pProfile =
m_VCoast[nCoast].pGetProfileWithDownCoastSeq(n);
1433 pProfile =
m_VCoast[nCoast].pGetProfileWithUpCoastSeq(n);
1453 m_VCoast[nCoast].pGetProfile(nProfile)->SetTooShort(
true);
1456 LogStream <<
m_ulIter <<
": coast " << nCoast <<
", profile " << nProfile <<
" is invalid, has only " << nPoints <<
" points" << endl;
1462 vector<CGeom2DIPoint> VCellsToMark;
1463 vector<bool> bVShared;
1464 bool bTooShort =
false;
1465 bool bTruncated =
false;
1466 bool bHitCoast =
false;
1467 bool bHitLand =
false;
1468 bool bHitIntervention =
false;
1469 bool bHitAnotherProfile =
false;
1471 CreateRasterizedProfile(nCoast, pProfile, &VCellsToMark, &bVShared, bTooShort, bTruncated, bHitCoast, bHitLand, bHitIntervention, bHitAnotherProfile);
1473 if ((bTruncated && (!
ACCEPT_TRUNCATED_PROFILES)) || bTooShort || bHitCoast || bHitLand || bHitIntervention || bHitAnotherProfile || VCellsToMark.size() == 0)
1479 for (
unsigned int k = 0; k < VCellsToMark.size(); k++)
1482 if ((k > 0) && (VCellsToMark[k] ==
m_VCoast[nCoast].pGetProfile(nProfile)->pPtiGetLastCellInProfile()))
1486 m_pRasterGrid->m_Cell[VCellsToMark[k].nGetX()][VCellsToMark[k].nGetY()].SetProfileID(nProfile);
1489 m_VCoast[nCoast].pGetProfile(nProfile)->AppendCellInProfile(VCellsToMark[k].nGetX(), VCellsToMark[k].nGetY());
1508 double const dDeepWaterWaveHeight =
m_pRasterGrid->m_Cell[VCellsToMark.back().nGetX()][VCellsToMark.back().nGetY()].dGetCellDeepWaterWaveHeight();
1509 double const dDeepWaterWaveAngle =
m_pRasterGrid->m_Cell[VCellsToMark.back().nGetX()][VCellsToMark.back().nGetY()].dGetCellDeepWaterWaveAngle();
1510 double const dDeepWaterWavePeriod =
m_pRasterGrid->m_Cell[VCellsToMark.back().nGetX()][VCellsToMark.back().nGetY()].dGetCellDeepWaterWavePeriod();
1513 m_VCoast[nCoast].pGetProfile(nProfile)->SetProfileDeepWaterWaveHeight(dDeepWaterWaveHeight);
1514 m_VCoast[nCoast].pGetProfile(nProfile)->SetProfileDeepWaterWaveAngle(dDeepWaterWaveAngle);
1515 m_VCoast[nCoast].pGetProfile(nProfile)->SetProfileDeepWaterWavePeriod(dDeepWaterWavePeriod);
1518 bDownCoast = !bDownCoast;
1524void 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)
1530 pVIPointsOut->clear();
1539 for (nSeg = 0; nSeg < nNumSegments; nSeg++)
1564 if (PtiSegStart == PtiSegEnd)
1567 int const nXStart = PtiSegStart.
nGetX();
1568 int const nYStart = PtiSegStart.
nGetY();
1569 int const nXEnd = PtiSegEnd.
nGetX();
1570 int const nYEnd = PtiSegEnd.
nGetY();
1572 bool bShared =
false;
1579 if ((nXStart == nXStartLast) && (nYStart == nYStartLast) && (nXEnd == nXEndLast) && (nYEnd == nYEndLast))
1584 double dXInc = nXEnd - nXStart;
1585 double dYInc = nYEnd - nYStart;
1591 double dX = nXStart;
1592 double dY = nYStart;
1595 for (
int m = 0; m <=
nRound(dLength); m++)
1597 int const nX =
nRound(dX);
1598 int const nY =
nRound(dY);
1660 bHitIntervention =
true;
1673 int const nHitProfile =
m_pRasterGrid->m_Cell[nX][nY].nGetProfileID();
1682 bHitAnotherProfile =
true;
1691 pbVShared->push_back(bShared);
1698 nXStartLast = nXStart;
1699 nYStartLast = nYStart;
1709 if (nSeg < (nNumSegments - 1))
1714 int const nLastX = pVIPointsOut->at(pVIPointsOut->size() - 1).nGetX();
1715 int const nLastY = pVIPointsOut->at(pVIPointsOut->size() - 1).nGetY();
1729 if (pVIPointsOut->size() < 3)
1738 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;
1749 int nCombinedLastSeg = 0;
1750 vector<pair<int, int>> prVCombinedProfilesCoincidentProfilesLastSeg;
1754 pair<int, int> prTmp;
1758 bool bFound =
false;
1760 for (
unsigned int m = 0; m < prVCombinedProfilesCoincidentProfilesLastSeg.size(); m++)
1762 if (prVCombinedProfilesCoincidentProfilesLastSeg[m].first == prTmp.first)
1771 prVCombinedProfilesCoincidentProfilesLastSeg.push_back(prTmp);
1778 pair<int, int> prTmp;
1782 bool bFound =
false;
1784 for (
unsigned int m = 0; m < prVCombinedProfilesCoincidentProfilesLastSeg.size(); m++)
1786 if (prVCombinedProfilesCoincidentProfilesLastSeg[m].first == prTmp.first)
1795 prVCombinedProfilesCoincidentProfilesLastSeg.push_back(prTmp);
1801 for (
int m = 0; m < nCombinedLastSeg; m++)
1802 prVCombinedProfilesCoincidentProfilesLastSeg[m].second++;
1806 int const nNumFirstProfileCoincidentProfilesLastSeg =
static_cast<int>(prVFirstProfileCoincidentProfilesLastSeg.size());
1807 int const nNumSecondProfileCoincidentProfilesLastSeg =
static_cast<int>(prVSecondProfileCoincidentProfilesLastSeg.size());
1812 for (
int n = 0; n < nNumFirstProfileCoincidentProfilesLastSeg; n++)
1814 int const nThisProfile = prVFirstProfileCoincidentProfilesLastSeg[n].first;
1823 for (
int n = 0; n < nNumSecondProfileCoincidentProfilesLastSeg; n++)
1825 int const nThisProfile = prVSecondProfileCoincidentProfilesLastSeg[n].first;
1834 for (
int nThisLineSeg = 0; nThisLineSeg < nNumFirstProfileCoincidentProfilesLastSeg; nThisLineSeg++)
1836 int const nThisProfile = prVFirstProfileCoincidentProfilesLastSeg[nThisLineSeg].first;
1845 for (
int m = 0; m < nCombinedLastSeg; m++)
1850 for (
int nThisLineSeg = 0; nThisLineSeg < nNumSecondProfileCoincidentProfilesLastSeg; nThisLineSeg++)
1852 int const nThisProfile = prVSecondProfileCoincidentProfilesLastSeg[nThisLineSeg].first;
1861 for (
int m = 0; m < nCombinedLastSeg; m++)
1932 int const nRet =
nInsertPointIntoProfilesIfNeededThenUpdate(nCoast, pProfileToRetain, dIntersectX, dIntersectY, nProfileToRetainIntersectLineSeg, pProfileToTruncate, nProfileToTruncateIntersectLineSeg, bAlreadyPresent);
1941 vector<CGeom2DPoint> PtVProfileLastPart;
1942 vector<vector<pair<int, int>>> prVLineSegLastPart;
1944 if (bAlreadyPresent)
1960 TruncateProfileAndAppendNew(nCoast, pProfileToTruncate, nProfileToTruncateIntersectLineSeg, &PtVProfileLastPart, &prVLineSegLastPart);
2036 int const nProfileToRetain = pProfileToRetain->
nGetCoastID();
2040 int const nNumCoincident =
static_cast<int>(prVCoincidentProfiles.size());
2041 vector<int> nLineSegAfterIntersect(nNumCoincident, -1);
2044 for (
int nn = 0; nn < nNumCoincident; nn++)
2046 int const nThisProfile = prVCoincidentProfiles[nn].first;
2047 int const nThisLineSeg = prVCoincidentProfiles[nn].second;
2051 if (!bAlreadyPresent)
2057 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;
2066 nLineSegAfterIntersect[nn] = nThisLineSeg + 1;
2074 int const nNumToTruncateCoincident =
static_cast<int>(prVToTruncateCoincidentProfiles.size());
2077 for (
int nn = 0; nn < nNumCoincident; nn++)
2079 int const nThisProfile = prVCoincidentProfiles[nn].first;
2086 for (
int nLineSeg = nLineSegAfterIntersect[nn], nIncr = 0; nLineSeg < nNumLineSegs; nLineSeg++, nIncr++)
2097 for (
int m = 0; m < nNumToTruncateCoincident; m++)
2099 int const nProfileToAdd = prVToTruncateCoincidentProfiles[m].first;
2100 int const nProfileToAddLineSeg = prVToTruncateCoincidentProfiles[m].second;
2201 int const nNumCoincident =
static_cast<int>(prVCoincidentProfiles.size());
2203 for (
int nn = 0; nn < nNumCoincident; nn++)
2206 int const nThisProfile = prVCoincidentProfiles[nn].first;
2207 int const nThisProfileLineSeg = prVCoincidentProfiles[nn].second;
2221 for (
unsigned int mm = 0; mm < pPtVProfileLastPart->size(); mm++)
2228 for (
unsigned int mm = 0; mm < pprVLineSegLastPart->size(); mm++)
2230 vector<pair<int, int>> prVTmp = pprVLineSegLastPart->at(mm);
2237 vector<int> nVProfsLineSeg;
2243 int const nProf = pThisProfile->
nGetProf(nSeg, nCoinc);
2246 auto it = find(nVProf.begin(), nVProf.end(), nProf);
2248 if (it == nVProf.end())
2251 nVProf.push_back(nProf);
2252 nVProfsLineSeg.push_back(nProfsLineSeg);
2258 int const nPos =
static_cast<int>(it - nVProf.begin());
2259 int nNewProfsLineSeg = nVProfsLineSeg[nPos];
2262 nVProfsLineSeg[nPos] = nNewProfsLineSeg;
Contains CGeom2DPoint definitions.
Contains CGeom2DIPoint definitions.
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
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 *)
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....
void KeepWithinValidGrid(int &, int &) const
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
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
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...
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
double m_dCoastNormalRandSpacingFactor
Random factor for spacing of along-coast normals.
bool bIsWithinValidGrid(int const, int const) const
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
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.
Contains CSimulation definitions.
int nRound(double const d)
Version of the above that returns an int.