1536 lines
42 KiB
C++
1536 lines
42 KiB
C++
/*
|
|
----
|
|
This file is part of SECONDO.
|
|
|
|
Copyright (C) 2004, University in Hagen, Department of Computer Science,
|
|
Database Systems for New Applications.
|
|
|
|
SECONDO 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 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
SECONDO 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.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with SECONDO; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
----
|
|
|
|
//paragraph [1] Title: [{\Large \bf \begin {center}] [\end {center}}]
|
|
//[TOC] [\tableofcontents]
|
|
//[_] [\_]
|
|
|
|
[1] Implementation of utilities for map matching
|
|
|
|
January-April, 2012. Matthias Roth
|
|
|
|
[TOC]
|
|
|
|
1 Overview
|
|
|
|
This implementation file contains the implementation of
|
|
the class ~MHTRouteCandidate~.
|
|
|
|
2 Defines and includes
|
|
|
|
*/
|
|
|
|
#include "MHTRouteCandidate.h"
|
|
#include "MapMatchingUtil.h"
|
|
#include "MapMatchingMHT.h"
|
|
#include "MapMatchingNetworkInterface.h"
|
|
|
|
#include "../Network/NetworkAlgebra.h"
|
|
#include "../TemporalNet/TemporalNetAlgebra.h"
|
|
|
|
|
|
using namespace std;
|
|
|
|
namespace mapmatch {
|
|
|
|
|
|
/*
|
|
3 class MHTRouteCandidate
|
|
Represents one route candidate for MHT-map matching
|
|
|
|
*/
|
|
|
|
MHTRouteCandidate::MHTRouteCandidate(MapMatchingMHT* pMM)
|
|
:m_pMM(pMM), m_dScore(0.0),
|
|
m_nCountLastEmptySections(0), m_nCountLastOffRoadPoints(0),
|
|
m_nCountPoints(0), m_bFailed(false)
|
|
{
|
|
}
|
|
|
|
MHTRouteCandidate::MHTRouteCandidate(const MHTRouteCandidate& rCandidate)
|
|
:m_pMM(rCandidate.m_pMM), m_dScore(rCandidate.m_dScore),
|
|
m_nCountLastEmptySections(rCandidate.m_nCountLastEmptySections),
|
|
m_nCountLastOffRoadPoints(rCandidate.m_nCountLastOffRoadPoints),
|
|
m_nCountPoints(rCandidate.m_nCountPoints),
|
|
m_bFailed(rCandidate.m_bFailed)
|
|
{
|
|
const size_t nSegments = rCandidate.m_Segments.size();
|
|
for (size_t i = 0; i < nSegments; ++i)
|
|
{
|
|
RouteSegmentPtr pSegment = rCandidate.m_Segments[i];
|
|
if (pSegment != NULL)
|
|
{
|
|
m_Segments.push_back(pSegment);
|
|
pSegment->IncRef();
|
|
}
|
|
}
|
|
|
|
m_SegmentsOutsourced = rCandidate.m_SegmentsOutsourced;
|
|
}
|
|
|
|
MHTRouteCandidate::~MHTRouteCandidate()
|
|
{
|
|
m_pMM = NULL;
|
|
|
|
const size_t nSegments = m_Segments.size();
|
|
for (size_t i = 0; i < nSegments; ++i)
|
|
{
|
|
RouteSegmentPtr& pSegment = m_Segments[i];
|
|
pSegment->DecRef();
|
|
}
|
|
m_Segments.clear();
|
|
m_SegmentsOutsourced.clear();
|
|
}
|
|
|
|
MHTRouteCandidate& MHTRouteCandidate::operator=
|
|
(const MHTRouteCandidate& rCandidate)
|
|
{
|
|
if (this != &rCandidate)
|
|
{
|
|
size_t nSegments = m_Segments.size();
|
|
for (size_t i = 0; i < nSegments; ++i)
|
|
{
|
|
RouteSegmentPtr& pSegment = m_Segments[i];
|
|
if (pSegment != NULL)
|
|
pSegment->DecRef();
|
|
}
|
|
m_Segments.clear();
|
|
|
|
nSegments = rCandidate.m_Segments.size();
|
|
for (size_t i = 0; i < nSegments; ++i)
|
|
{
|
|
RouteSegmentPtr pSegment = rCandidate.m_Segments[i];
|
|
if (pSegment != NULL)
|
|
{
|
|
m_Segments.push_back(pSegment);
|
|
pSegment->IncRef();
|
|
}
|
|
}
|
|
|
|
m_SegmentsOutsourced.clear();
|
|
m_SegmentsOutsourced = rCandidate.m_SegmentsOutsourced;
|
|
|
|
m_pMM = rCandidate.m_pMM;
|
|
m_dScore = rCandidate.m_dScore;
|
|
m_nCountLastEmptySections = rCandidate.m_nCountLastEmptySections;
|
|
m_nCountLastOffRoadPoints = rCandidate.m_nCountLastOffRoadPoints;
|
|
m_nCountPoints = rCandidate.m_nCountPoints;
|
|
m_bFailed = rCandidate.m_bFailed;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
#define SCORE_FOR_SECTION 5.0
|
|
|
|
void MHTRouteCandidate::AddSection(const shared_ptr<IMMNetworkSection>& pSect)
|
|
{
|
|
m_Segments.push_back(RouteSegmentPtr(new RouteSegment(pSect)));
|
|
|
|
// Add score for every Section -> prefer candidates with fewer sections
|
|
m_dScore += SCORE_FOR_SECTION;
|
|
|
|
++m_nCountLastEmptySections;
|
|
|
|
if (m_Segments.size() >= 20)
|
|
{
|
|
// outsource first segments
|
|
|
|
RouteSegmentContPtr pVecSegments(new std::deque<RouteSegmentPtr>());
|
|
m_SegmentsOutsourced.push_back(pVecSegments);
|
|
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
RouteSegmentPtr pRouteSegment = m_Segments.front();
|
|
if (pRouteSegment != NULL)
|
|
{
|
|
pRouteSegment->DecRef();
|
|
pVecSegments->push_back(pRouteSegment);
|
|
}
|
|
m_Segments.pop_front();
|
|
}
|
|
}
|
|
}
|
|
|
|
void MHTRouteCandidate::RemoveLastSection(void)
|
|
{
|
|
if (m_Segments.size() > 0)
|
|
{
|
|
RouteSegmentPtr pSegment = m_Segments.back();
|
|
|
|
if (pSegment != NULL &&
|
|
pSegment->IsOffRoad())
|
|
{
|
|
assert(pSegment->GetPoints().size() == 0);
|
|
|
|
pSegment->DecRef();
|
|
m_Segments.pop_back();
|
|
//m_dScore -= SCORE_FOR_SECTION; no score for offroad-segment
|
|
|
|
if (m_Segments.size() > 0)
|
|
pSegment = m_Segments.back();
|
|
else
|
|
pSegment = RouteSegmentPtr();
|
|
}
|
|
|
|
if (pSegment != NULL &&
|
|
pSegment->GetPoints().size() == 0 /*only delete empty segments*/ &&
|
|
!pSegment->IsOffRoad())
|
|
{
|
|
pSegment->DecRef();
|
|
m_Segments.pop_back();
|
|
m_dScore -= SCORE_FOR_SECTION;
|
|
if (m_nCountLastEmptySections > 0)
|
|
--m_nCountLastEmptySections;
|
|
else
|
|
assert(false);
|
|
}
|
|
else
|
|
{
|
|
assert(false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
assert(false);
|
|
}
|
|
}
|
|
|
|
MHTRouteCandidate::RouteSegmentPtr MHTRouteCandidate::GetLastOnroadSegment(
|
|
std::deque<RouteSegmentPtr>::reverse_iterator* pItRet)
|
|
{
|
|
if (m_Segments.size() > 0)
|
|
{
|
|
if (pItRet != NULL)
|
|
*pItRet = m_Segments.rend();
|
|
|
|
RouteSegmentPtr pSegment = m_Segments.back();
|
|
if (pSegment != NULL && !pSegment->IsOffRoad())
|
|
{
|
|
if (pItRet != NULL)
|
|
{
|
|
*pItRet = m_Segments.rbegin();
|
|
}
|
|
|
|
return pSegment;
|
|
}
|
|
else
|
|
{
|
|
std::deque<RouteSegmentPtr>::reverse_iterator it =
|
|
m_Segments.rbegin();
|
|
std::deque<RouteSegmentPtr>::reverse_iterator itEnd =
|
|
m_Segments.rend();
|
|
|
|
if (it != itEnd)
|
|
++it;
|
|
|
|
while (it != itEnd)
|
|
{
|
|
RouteSegmentPtr pSegment = *it;
|
|
if (pSegment != NULL && !pSegment->IsOffRoad())
|
|
{
|
|
if (pItRet != NULL)
|
|
*pItRet = it;
|
|
|
|
return pSegment;
|
|
}
|
|
|
|
++it;
|
|
}
|
|
}
|
|
}
|
|
|
|
return MHTRouteCandidate::RouteSegmentPtr();
|
|
}
|
|
|
|
shared_ptr<IMMNetworkSection> MHTRouteCandidate::GetLastSection(void) const
|
|
{
|
|
const RouteSegmentPtr& pSegment = const_cast<MHTRouteCandidate*>(this)->
|
|
GetLastOnroadSegment(NULL);
|
|
if (pSegment != NULL)
|
|
return pSegment->GetSection();
|
|
else
|
|
{
|
|
static shared_ptr<IMMNetworkSection> pDummy;
|
|
return pDummy;
|
|
}
|
|
}
|
|
|
|
const MHTRouteCandidate::PointDataPtr
|
|
MHTRouteCandidate::GetLastPoint(void) const
|
|
{
|
|
std::deque<RouteSegmentPtr>::const_reverse_iterator it =
|
|
m_Segments.rbegin();
|
|
std::deque<RouteSegmentPtr>::const_reverse_iterator itEnd =
|
|
m_Segments.rend();
|
|
|
|
while (it != itEnd)
|
|
{
|
|
const RouteSegmentPtr& pSegment = *it;
|
|
if (pSegment != NULL)
|
|
{
|
|
if (pSegment->GetPoints().size() > 0)
|
|
return pSegment->GetPoints().back();
|
|
}
|
|
|
|
++it;
|
|
}
|
|
|
|
return MHTRouteCandidate::PointDataPtr();
|
|
}
|
|
|
|
const std::vector<MHTRouteCandidate::PointDataPtr>& MHTRouteCandidate::
|
|
GetPointsOfLastSection(void) const
|
|
{
|
|
std::deque<RouteSegmentPtr>::const_reverse_iterator it =
|
|
m_Segments.rbegin();
|
|
std::deque<RouteSegmentPtr>::const_reverse_iterator itEnd =
|
|
m_Segments.rend();
|
|
while (it != itEnd)
|
|
{
|
|
const RouteSegmentPtr& pSegment = *it;
|
|
if (pSegment != NULL && !pSegment->IsOffRoad())
|
|
return pSegment->GetPoints();
|
|
|
|
++it;
|
|
}
|
|
|
|
assert(false);
|
|
static std::vector<PointDataPtr> vecDummy;
|
|
return vecDummy;
|
|
}
|
|
|
|
size_t MHTRouteCandidate::GetCountPointsOfLastSection(void) const
|
|
{
|
|
return GetPointsOfLastSection().size();
|
|
}
|
|
|
|
|
|
#define DISTANCE_FACTOR 2.0
|
|
|
|
static double CalcScore(const Point& rPtProjection,
|
|
const HalfSegment& rHSProjection,
|
|
const shared_ptr<IMMNetworkSection>& pSection,
|
|
const MapMatchData& rMMData,
|
|
double dDistance,
|
|
double dNetworkScale)
|
|
{
|
|
if (dDistance < 0.0)
|
|
{
|
|
dDistance = MMUtil::CalcDistance(rPtProjection,
|
|
rMMData.GetPoint(),
|
|
dNetworkScale);
|
|
}
|
|
|
|
double dScore = DISTANCE_FACTOR * dDistance;
|
|
|
|
if (rMMData.m_dCourse >= 0.)
|
|
{
|
|
// Course is defined -> add heading difference to score
|
|
|
|
IMMNetworkSection* pNetworkSection = pSection.get();
|
|
|
|
const double dHeadingSection = MMUtil::CalcHeading(pNetworkSection,
|
|
rHSProjection,
|
|
dNetworkScale);
|
|
|
|
//assert(dHeadingSection > 0. || AlmostEqual(dHeadingSection, 0.));
|
|
|
|
const double dReverseHeadingSection = (dHeadingSection < 180 ?
|
|
dHeadingSection + 180. : dHeadingSection - 180.);
|
|
|
|
const double dHeadingDiff =
|
|
std::min(abs(rMMData.m_dCourse - dHeadingSection),
|
|
360. - abs(rMMData.m_dCourse - dHeadingSection));
|
|
|
|
const double dReverseHeadingDiff =
|
|
std::min(abs(rMMData.m_dCourse - dReverseHeadingSection),
|
|
360. - abs(rMMData.m_dCourse - dReverseHeadingSection));
|
|
|
|
dScore += std::min(dHeadingDiff, dReverseHeadingDiff);
|
|
|
|
dScore += dHeadingDiff;
|
|
}
|
|
|
|
return dScore;
|
|
}
|
|
|
|
void MHTRouteCandidate::AddPoint(const Point& rPointProjection,
|
|
const HalfSegment& rHSProjection,
|
|
const MapMatchData* pMMData,
|
|
double dDistance)
|
|
{
|
|
if (m_Segments.size() == 0 || pMMData == NULL)
|
|
{
|
|
assert(false);
|
|
return;
|
|
}
|
|
|
|
RouteSegmentPtr pSegment = m_Segments.back();
|
|
if (pSegment == NULL)
|
|
{
|
|
assert(false);
|
|
return;
|
|
}
|
|
|
|
if (pSegment->IsOffRoad())
|
|
{
|
|
std::deque<RouteSegmentPtr>::const_reverse_iterator it =
|
|
m_Segments.rbegin();
|
|
std::deque<RouteSegmentPtr>::const_reverse_iterator itEnd =
|
|
m_Segments.rend();
|
|
if (it != itEnd)
|
|
++it;
|
|
|
|
while (it != itEnd)
|
|
{
|
|
pSegment = *it;
|
|
if (pSegment != NULL && !pSegment->IsOffRoad())
|
|
{
|
|
// add previous section
|
|
AddSection(pSegment->GetSection());
|
|
break;
|
|
}
|
|
|
|
++it;
|
|
}
|
|
|
|
pSegment = m_Segments.back();
|
|
if (pSegment == NULL || pSegment->IsOffRoad())
|
|
{
|
|
assert(false);
|
|
return;
|
|
}
|
|
|
|
assert(pSegment->GetRefCount() == 1);
|
|
}
|
|
else
|
|
{
|
|
if (pSegment->GetRefCount() != 1) // not unique
|
|
{
|
|
pSegment->DecRef();
|
|
pSegment = RouteSegmentPtr(new RouteSegment(*pSegment));
|
|
m_Segments.pop_back();
|
|
m_Segments.push_back(pSegment);
|
|
}
|
|
}
|
|
|
|
const double dScore = CalcScore(rPointProjection,
|
|
rHSProjection,
|
|
pSegment->GetSection(),
|
|
*pMMData,
|
|
dDistance,
|
|
m_pMM->GetNetworkScale());
|
|
|
|
const PointDataPtr pData = pSegment->AddPoint(pMMData,
|
|
rPointProjection,
|
|
dDistance,
|
|
dScore);
|
|
if (pData != NULL)
|
|
{
|
|
m_dScore += dScore;
|
|
++m_nCountPoints;
|
|
m_nCountLastEmptySections = 0;
|
|
m_nCountLastOffRoadPoints = 0;
|
|
}
|
|
}
|
|
|
|
void MHTRouteCandidate::AddPoint(const MapMatchData* pMMData)
|
|
{
|
|
if (pMMData == NULL)
|
|
return;
|
|
|
|
if (m_Segments.size() == 0 ||
|
|
m_Segments.back() == NULL ||
|
|
!m_Segments.back()->IsOffRoad())
|
|
{
|
|
// add Offroad-Segment
|
|
m_Segments.push_back(RouteSegmentPtr(new RouteSegment()));
|
|
}
|
|
|
|
const double dScore = DISTANCE_FACTOR * 40. +
|
|
(pMMData->m_dCourse >= 0 ? 40. : 0.);
|
|
|
|
RouteSegmentPtr pSegment = m_Segments.back();
|
|
if (pSegment->GetRefCount() != 1 /* not unique */)
|
|
{
|
|
pSegment->DecRef();
|
|
pSegment = RouteSegmentPtr(new RouteSegment(*pSegment));
|
|
m_Segments.pop_back();
|
|
m_Segments.push_back(pSegment);
|
|
}
|
|
|
|
const PointDataPtr pData = pSegment->AddPoint(pMMData, dScore);
|
|
if (pData != NULL)
|
|
{
|
|
m_dScore += dScore;
|
|
//m_nCountLastEmptySections = 0;
|
|
++m_nCountLastOffRoadPoints;
|
|
++m_nCountPoints;
|
|
}
|
|
}
|
|
|
|
void MHTRouteCandidate::RemoveLastPoint(void)
|
|
{
|
|
if (m_Segments.size() > 0)
|
|
{
|
|
std::deque<RouteSegmentPtr>::reverse_iterator it = m_Segments.rbegin();
|
|
std::deque<RouteSegmentPtr>::reverse_iterator itEnd =m_Segments.rend();
|
|
|
|
while (it != itEnd)
|
|
{
|
|
RouteSegmentPtr pSegment = *it;
|
|
if (pSegment != NULL && pSegment->GetPoints().size() > 0)
|
|
{
|
|
if (pSegment->GetRefCount() != 1) // not unique
|
|
{
|
|
pSegment->DecRef();
|
|
pSegment = RouteSegmentPtr(new RouteSegment(*pSegment));
|
|
*it = pSegment;
|
|
}
|
|
|
|
double dScoreOfLastPoint = pSegment->RemoveLastPoint();
|
|
if (dScoreOfLastPoint > 0.0 ||
|
|
AlmostEqual(dScoreOfLastPoint, 0.0))
|
|
{
|
|
m_dScore -= dScoreOfLastPoint;
|
|
--m_nCountPoints;
|
|
break;
|
|
}
|
|
}
|
|
|
|
++it;
|
|
}
|
|
|
|
// recalculate EmptySections
|
|
m_nCountLastEmptySections = 0;
|
|
it = m_Segments.rbegin();
|
|
while(it != itEnd)
|
|
{
|
|
RouteSegmentPtr pSegment = *it;
|
|
if (pSegment != NULL && !pSegment->IsOffRoad())
|
|
{
|
|
if (pSegment->GetPoints().size() == 0)
|
|
++m_nCountLastEmptySections;
|
|
else
|
|
break;
|
|
}
|
|
|
|
++it;
|
|
}
|
|
|
|
// recalculate Offroad-Points
|
|
m_nCountLastOffRoadPoints = 0;
|
|
it = m_Segments.rbegin();
|
|
while (it != itEnd)
|
|
{
|
|
RouteSegmentPtr pSegment = *it;
|
|
if (pSegment != NULL && pSegment->IsOffRoad())
|
|
{
|
|
m_nCountLastOffRoadPoints = pSegment->GetPoints().size();
|
|
break;
|
|
}
|
|
else if (pSegment != NULL && !pSegment->IsOffRoad())
|
|
{
|
|
if (pSegment->GetPoints().size() > 0)
|
|
break;
|
|
}
|
|
|
|
++it;
|
|
}
|
|
}
|
|
}
|
|
|
|
void MHTRouteCandidate::SetUTurn(double dAdditionalScore)
|
|
{
|
|
std::deque<RouteSegmentPtr>::reverse_iterator it;
|
|
RouteSegmentPtr pSegment = GetLastOnroadSegment(&it);
|
|
if (pSegment != NULL)
|
|
{
|
|
if (pSegment->GetRefCount() != 1)
|
|
{
|
|
// not unique
|
|
pSegment->DecRef();
|
|
RouteSegmentPtr pSegmentNew =
|
|
RouteSegmentPtr(new RouteSegment(*pSegment));
|
|
|
|
if (m_Segments.rend() != it)
|
|
{
|
|
*it = pSegmentNew;
|
|
pSegment = pSegmentNew;
|
|
}
|
|
else
|
|
{
|
|
pSegment->IncRef();
|
|
pSegmentNew->DecRef();
|
|
assert(false);
|
|
}
|
|
}
|
|
|
|
pSegment->SetUTurn(true);
|
|
}
|
|
else
|
|
{
|
|
assert(false);
|
|
}
|
|
|
|
m_dScore += dAdditionalScore;
|
|
}
|
|
|
|
static HalfSegment CalcHSOfEndPoint(const SimpleLine* pLine,
|
|
const Point& rPt)
|
|
{
|
|
|
|
if (pLine == NULL)
|
|
throw SecondoException("pLine is null");
|
|
|
|
const int nSize = pLine->Size();
|
|
if (nSize > 0)
|
|
{
|
|
HalfSegment hs;
|
|
pLine->Get(0, hs);
|
|
|
|
if (hs.GetLeftPoint() == rPt ||
|
|
hs.GetRightPoint() == rPt)
|
|
return hs;
|
|
|
|
if (nSize > 1)
|
|
{
|
|
pLine->Get(nSize - 1, hs);
|
|
return hs;
|
|
}
|
|
else
|
|
{
|
|
throw SecondoException(
|
|
"Got SimpleLine with only one point, ignoring");
|
|
//assert(false);
|
|
//return hs;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw SecondoException("Got SimpleLine with size=0, ignoring");
|
|
//assert(false);
|
|
//return HalfSegment(true, Point(0.,0.), Point(0.,0.));
|
|
}
|
|
}
|
|
|
|
bool MHTRouteCandidate::CorrectUTurn(void)
|
|
{
|
|
if (GetCountPointsOfLastSection() == 0 ||
|
|
m_pMM == NULL ||
|
|
m_Segments.size() < 2)
|
|
{
|
|
assert(false);
|
|
return false;
|
|
}
|
|
|
|
const IMMNetwork* pNetwork = m_pMM->GetNetwork();
|
|
if (pNetwork == NULL)
|
|
{
|
|
assert(false);
|
|
return false;
|
|
}
|
|
|
|
// Move all points of last segment to endpoint of second last segment
|
|
|
|
std::stack<MHTRouteCandidate::PointDataPtr> stackPointData;
|
|
int nPoints = 0;
|
|
while ((nPoints = GetCountPointsOfLastSection()) > 0)
|
|
{
|
|
stackPointData.push(GetLastPoint());
|
|
RemoveLastPoint();
|
|
}
|
|
|
|
RemoveLastSection();
|
|
|
|
// assign to endpoint of last section
|
|
const shared_ptr<IMMNetworkSection>& pNewSection = GetLastSection();
|
|
if (pNewSection == NULL)
|
|
return false;
|
|
|
|
Point PointNewProjection = (pNewSection->GetDirection() ==
|
|
IMMNetworkSection::DIR_UP ?
|
|
pNewSection->GetEndPoint() :
|
|
pNewSection->GetStartPoint());
|
|
|
|
if (!PointNewProjection.IsDefined())
|
|
return false;
|
|
|
|
while (!stackPointData.empty())
|
|
{
|
|
MHTRouteCandidate::PointDataPtr pData = stackPointData.top();
|
|
const MapMatchData* pMMData = pData != NULL ? pData->GetMMData() : NULL;
|
|
if (pMMData != NULL)
|
|
{
|
|
|
|
try {
|
|
HalfSegment segment = CalcHSOfEndPoint(
|
|
pNewSection->GetCurve(),
|
|
PointNewProjection);
|
|
|
|
AddPoint(PointNewProjection, segment, pMMData, -1.0);
|
|
} catch(SecondoException &e) {
|
|
cerr << "Got exception while calculating HalfSegment: "
|
|
<< e.msg() << endl;
|
|
}
|
|
|
|
}
|
|
|
|
stackPointData.pop();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
void MHTRouteCandidate::Print(std::ostream& os) const
|
|
{
|
|
os << "*******RouteCandidate********" << endl;
|
|
|
|
os << "Score: " << GetScore() << endl;
|
|
|
|
os << "CountLastEmptySections: " << GetCountLastEmptySections() << endl;
|
|
|
|
os << "Projected Points:" << endl;
|
|
PrintProjectedPoints(os);
|
|
|
|
RouteSegmentIterator it = RouteSegmentBegin();
|
|
RouteSegmentIterator itEnd = RouteSegmentEnd();
|
|
|
|
os << endl << "Segments:" << endl;
|
|
for (/*empty*/; it != itEnd; ++it)
|
|
{
|
|
if ((*it)->IsOffRoad())
|
|
os << "Offroad" << endl;
|
|
else
|
|
{
|
|
(*it)->GetSection()->PrintIdentifier(os);
|
|
os << endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
void MHTRouteCandidate::PrintProjectedPoints(std::ostream& os) const
|
|
{
|
|
PointDataIterator it = PointDataBegin();
|
|
PointDataIterator itEnd = PointDataEnd();
|
|
|
|
AttributePtr<Points> pPts(new Points((int)1));
|
|
|
|
while (it != itEnd)
|
|
{
|
|
const PointDataPtr& pData = *it;
|
|
if (pData != NULL)
|
|
{
|
|
const Point* pPoint = pData->GetPointProjection();
|
|
if (pPoint != NULL)
|
|
{
|
|
*pPts += *pPoint;
|
|
}
|
|
}
|
|
|
|
++it;
|
|
}
|
|
|
|
pPts->Print(os);
|
|
}
|
|
|
|
|
|
/*
|
|
4 class MHTRouteCandidate::PointData
|
|
|
|
*/
|
|
|
|
MHTRouteCandidate::PointData::PointData()
|
|
:m_pData(NULL),
|
|
m_pPointProjection(NULL),
|
|
m_pSection(),
|
|
m_dDistance(0.0),
|
|
m_dScore(0.0)
|
|
{
|
|
}
|
|
|
|
MHTRouteCandidate::PointData::PointData(
|
|
const MapMatchData* pMMData,
|
|
const Point& rPointProjection,
|
|
const shared_ptr<IMMNetworkSection>& pSection,
|
|
const double dDistance,
|
|
const double dScore)
|
|
:m_pData(pMMData),
|
|
m_pPointProjection(new Point(rPointProjection)),
|
|
m_pSection(pSection),
|
|
m_dDistance(dDistance),
|
|
m_dScore(dScore)
|
|
{
|
|
}
|
|
|
|
MHTRouteCandidate::PointData::PointData(const MapMatchData* pMMData,
|
|
const double dScore)
|
|
:m_pData(pMMData),
|
|
m_pPointProjection(NULL),
|
|
m_pSection(),
|
|
m_dDistance(0.0),
|
|
m_dScore(dScore)
|
|
{
|
|
}
|
|
|
|
MHTRouteCandidate::PointData::PointData(const PointData& rPointData)
|
|
:m_pData(rPointData.m_pData),
|
|
m_pPointProjection(rPointData.m_pPointProjection != NULL ?
|
|
new Point(*rPointData.m_pPointProjection) : NULL),
|
|
m_pSection(rPointData.m_pSection),
|
|
m_dDistance(rPointData.m_dDistance),
|
|
m_dScore(rPointData.m_dScore)
|
|
{
|
|
}
|
|
|
|
MHTRouteCandidate::PointData& MHTRouteCandidate::PointData::operator=(
|
|
const PointData& rPointData)
|
|
{
|
|
if (this != &rPointData)
|
|
{
|
|
m_pData = rPointData.m_pData;
|
|
|
|
if (m_pPointProjection != NULL)
|
|
m_pPointProjection->DeleteIfAllowed();
|
|
m_pPointProjection = NULL;
|
|
|
|
if (rPointData.m_pPointProjection != NULL)
|
|
m_pPointProjection = new Point(*rPointData.m_pPointProjection);
|
|
|
|
m_pSection = rPointData.m_pSection;
|
|
|
|
m_dDistance = rPointData.m_dDistance;
|
|
|
|
m_dScore = rPointData.m_dScore;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
bool MHTRouteCandidate::PointData::operator==(
|
|
const MHTRouteCandidate::PointData& rPointData) const
|
|
{
|
|
if (this == &rPointData)
|
|
return true;
|
|
|
|
if (m_pPointProjection != NULL && rPointData.m_pPointProjection != NULL &&
|
|
m_pData != NULL && rPointData.m_pData != NULL)
|
|
{
|
|
return ((*m_pPointProjection) == (*rPointData.m_pPointProjection) &&
|
|
(m_pData->GetPoint() == rPointData.m_pData->GetPoint()));
|
|
}
|
|
else
|
|
{
|
|
return m_pPointProjection == rPointData.m_pPointProjection &&
|
|
m_pData == rPointData.m_pData;
|
|
}
|
|
}
|
|
|
|
MHTRouteCandidate::PointData::~PointData()
|
|
{
|
|
m_pData = NULL;
|
|
|
|
if (m_pPointProjection != NULL)
|
|
m_pPointProjection->DeleteIfAllowed();
|
|
m_pPointProjection = NULL;
|
|
|
|
//m_pSection = NULL;
|
|
}
|
|
|
|
void MHTRouteCandidate::PointData::Print(std::ostream& os) const
|
|
{
|
|
os << "PointGPS: ";
|
|
if (m_pData != NULL)
|
|
{
|
|
m_pData->GetPoint().Print(os);
|
|
}
|
|
else
|
|
{
|
|
os << "NULL";
|
|
}
|
|
os << endl;
|
|
|
|
os << "PointProjection: ";
|
|
if (m_pPointProjection != NULL)
|
|
{
|
|
m_pPointProjection->Print(os);
|
|
}
|
|
else
|
|
{
|
|
os << "NULL";
|
|
}
|
|
os << endl;
|
|
|
|
os << "Section: ";
|
|
if (m_pSection != NULL)
|
|
{
|
|
m_pSection->PrintIdentifier(os);
|
|
}
|
|
else
|
|
{
|
|
os << "NULL";
|
|
}
|
|
os << endl;
|
|
|
|
os << "Score: " << m_dScore << endl;
|
|
}
|
|
|
|
|
|
/*
|
|
6 class MHTRouteCandidate::PointDataIterator
|
|
|
|
*/
|
|
|
|
MHTRouteCandidate::PointDataIterator::PointDataIterator(
|
|
const PointDataIterator& rIt)
|
|
:m_ItRouteSegment(rIt.m_ItRouteSegment),
|
|
m_ItPointData(rIt.m_ItPointData),
|
|
m_ItRouteSegment_R(rIt.m_ItRouteSegment_R),
|
|
m_ItPointData_R(rIt.m_ItPointData_R),
|
|
m_bReverse(rIt.m_bReverse),
|
|
m_pRouteCandidate(rIt.m_pRouteCandidate)
|
|
{
|
|
}
|
|
|
|
MHTRouteCandidate::PointDataIterator::PointDataIterator(
|
|
const MHTRouteCandidate* pCandidate,
|
|
bool bBegin, bool bReverse)
|
|
:m_ItRouteSegment(),
|
|
m_ItPointData(),
|
|
m_ItRouteSegment_R(),
|
|
m_ItPointData_R(),
|
|
m_bReverse(bReverse),
|
|
m_pRouteCandidate(pCandidate)
|
|
{
|
|
if (pCandidate == NULL)
|
|
return;
|
|
|
|
if (bBegin)
|
|
{
|
|
if (bReverse)
|
|
{
|
|
m_ItRouteSegment_R = pCandidate->RouteSegmentRBegin();
|
|
if (m_ItRouteSegment_R != pCandidate->RouteSegmentREnd())
|
|
{
|
|
RouteSegmentPtr pSegment = *m_ItRouteSegment_R;
|
|
if (pSegment != NULL)
|
|
{
|
|
m_ItPointData_R = pSegment->GetPoints().rbegin();
|
|
while (pSegment != NULL &&
|
|
m_ItPointData_R == pSegment->GetPoints().rend() &&
|
|
m_ItRouteSegment_R != pCandidate->RouteSegmentREnd())
|
|
{
|
|
this->operator ++();
|
|
if (m_ItRouteSegment_R !=
|
|
pCandidate->RouteSegmentREnd())
|
|
pSegment = *m_ItRouteSegment_R;
|
|
else
|
|
pSegment = RouteSegmentPtr();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
assert(false);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_ItRouteSegment = pCandidate->RouteSegmentBegin();
|
|
if (m_ItRouteSegment != pCandidate->RouteSegmentEnd())
|
|
{
|
|
RouteSegmentPtr pSegment = *m_ItRouteSegment;
|
|
if (pSegment != NULL)
|
|
{
|
|
m_ItPointData = pSegment->GetPoints().begin();
|
|
while (pSegment != NULL &&
|
|
m_ItPointData == pSegment->GetPoints().end() &&
|
|
m_ItRouteSegment != pCandidate->RouteSegmentEnd())
|
|
{
|
|
this->operator ++();
|
|
if (m_ItRouteSegment != pCandidate->RouteSegmentEnd())
|
|
pSegment = *m_ItRouteSegment;
|
|
else
|
|
pSegment = RouteSegmentPtr();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
assert(false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// end
|
|
if (bReverse)
|
|
{
|
|
m_ItRouteSegment_R = pCandidate->RouteSegmentREnd();
|
|
}
|
|
else
|
|
{
|
|
m_ItRouteSegment = pCandidate->RouteSegmentEnd();
|
|
}
|
|
}
|
|
}
|
|
|
|
MHTRouteCandidate::PointDataIterator::~PointDataIterator()
|
|
{
|
|
m_pRouteCandidate = NULL;
|
|
}
|
|
|
|
MHTRouteCandidate::PointDataIterator& MHTRouteCandidate::PointDataIterator::
|
|
operator=(const PointDataIterator& rIt)
|
|
{
|
|
m_bReverse = rIt.m_bReverse;
|
|
|
|
m_ItRouteSegment = rIt.m_ItRouteSegment;
|
|
m_ItPointData = rIt.m_ItPointData;
|
|
|
|
m_ItRouteSegment_R = rIt.m_ItRouteSegment_R;
|
|
m_ItPointData_R = rIt.m_ItPointData_R;
|
|
|
|
return *this;
|
|
}
|
|
|
|
bool MHTRouteCandidate::PointDataIterator::operator==(
|
|
const PointDataIterator& rIt) const
|
|
{
|
|
if (m_bReverse)
|
|
{
|
|
return (rIt.m_ItPointData_R == m_ItPointData_R &&
|
|
rIt.m_ItRouteSegment_R == m_ItRouteSegment_R);
|
|
}
|
|
else
|
|
{
|
|
return (rIt.m_ItPointData == m_ItPointData &&
|
|
rIt.m_ItRouteSegment == m_ItRouteSegment);
|
|
}
|
|
}
|
|
|
|
bool MHTRouteCandidate::PointDataIterator::operator!=(
|
|
const PointDataIterator& rIt) const
|
|
{
|
|
if (m_bReverse)
|
|
{
|
|
return (rIt.m_ItPointData_R != m_ItPointData_R ||
|
|
rIt.m_ItRouteSegment_R != m_ItRouteSegment_R);
|
|
}
|
|
else
|
|
{
|
|
return (rIt.m_ItPointData != m_ItPointData ||
|
|
rIt.m_ItRouteSegment != m_ItRouteSegment);
|
|
}
|
|
}
|
|
|
|
const MHTRouteCandidate::PointDataPtr MHTRouteCandidate::PointDataIterator::
|
|
operator*() const
|
|
{
|
|
if (m_bReverse)
|
|
{
|
|
return *m_ItPointData_R;
|
|
}
|
|
else
|
|
{
|
|
return *m_ItPointData;
|
|
}
|
|
}
|
|
|
|
MHTRouteCandidate::PointDataIterator& MHTRouteCandidate::PointDataIterator::
|
|
operator++()
|
|
{
|
|
if (m_pRouteCandidate == NULL)
|
|
{
|
|
assert(false);
|
|
return *this;
|
|
}
|
|
|
|
if (m_bReverse)
|
|
{
|
|
RouteSegmentPtr pSegment = *m_ItRouteSegment_R;
|
|
|
|
if (pSegment != NULL && m_ItPointData_R != pSegment->GetPoints().rend())
|
|
{
|
|
++m_ItPointData_R;
|
|
if (m_ItPointData_R == pSegment->GetPoints().rend())
|
|
{
|
|
return this->operator ++();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
++m_ItRouteSegment_R;
|
|
if (m_ItRouteSegment_R != m_pRouteCandidate->RouteSegmentREnd())
|
|
{
|
|
RouteSegmentPtr pSegment = *m_ItRouteSegment_R;
|
|
if (pSegment != NULL)
|
|
{
|
|
m_ItPointData_R = pSegment->GetPoints().rbegin();
|
|
if (m_ItPointData_R == pSegment->GetPoints().rend())
|
|
{
|
|
return this->operator ++();
|
|
}
|
|
}
|
|
else
|
|
assert(false);
|
|
}
|
|
else
|
|
{
|
|
m_ItPointData_R =
|
|
std::vector<PointDataPtr>::const_reverse_iterator();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RouteSegmentPtr pSegment = *m_ItRouteSegment;
|
|
|
|
if (pSegment != NULL && m_ItPointData != pSegment->GetPoints().end())
|
|
{
|
|
++m_ItPointData;
|
|
if (m_ItPointData == pSegment->GetPoints().end())
|
|
{
|
|
return this->operator ++();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
++m_ItRouteSegment;
|
|
if (m_ItRouteSegment != m_pRouteCandidate->RouteSegmentEnd())
|
|
{
|
|
RouteSegmentPtr pSegment = *m_ItRouteSegment;
|
|
if (pSegment != NULL)
|
|
{
|
|
m_ItPointData = pSegment->GetPoints().begin();
|
|
if (m_ItPointData == pSegment->GetPoints().end())
|
|
{
|
|
return this->operator ++();
|
|
}
|
|
}
|
|
else
|
|
assert(false);
|
|
}
|
|
else
|
|
{
|
|
m_ItPointData = std::vector<PointDataPtr>::const_iterator();
|
|
}
|
|
}
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
/*
|
|
6 class MHTRouteCandidate::RouteSegment
|
|
|
|
*/
|
|
|
|
MHTRouteCandidate::RouteSegment::RouteSegment(void)
|
|
:m_pSection(),
|
|
m_bUTurn(false),
|
|
m_nRefCount(1)
|
|
{
|
|
}
|
|
|
|
MHTRouteCandidate::RouteSegment::RouteSegment
|
|
(const shared_ptr<IMMNetworkSection>& pSection)
|
|
:m_pSection(pSection),
|
|
m_bUTurn(false),
|
|
m_nRefCount(1)
|
|
{
|
|
}
|
|
|
|
MHTRouteCandidate::RouteSegment::RouteSegment
|
|
(const RouteSegment& rCandidate)
|
|
:m_pSection(rCandidate.m_pSection),
|
|
m_bUTurn(rCandidate.m_bUTurn),
|
|
m_nRefCount(1)
|
|
{
|
|
m_Points = rCandidate.GetPoints();
|
|
}
|
|
|
|
MHTRouteCandidate::RouteSegment::~RouteSegment()
|
|
{
|
|
m_Points.clear();
|
|
assert(m_nRefCount == 0);
|
|
}
|
|
|
|
const MHTRouteCandidate::PointDataPtr MHTRouteCandidate::RouteSegment::AddPoint(
|
|
const MapMatchData* pMMData,
|
|
const Point& rPointProjection,
|
|
const double dDistance,
|
|
const double dScore)
|
|
{
|
|
PointDataPtr pData = PointDataPtr(new PointData(pMMData,
|
|
rPointProjection,
|
|
GetSection(),
|
|
dDistance,
|
|
dScore));
|
|
m_Points.push_back(pData);
|
|
|
|
return pData;
|
|
}
|
|
|
|
const MHTRouteCandidate::PointDataPtr MHTRouteCandidate::RouteSegment::AddPoint(
|
|
const MapMatchData* pMMData,
|
|
const double dScore)
|
|
{
|
|
if (!IsOffRoad())
|
|
{
|
|
assert(false);
|
|
return MHTRouteCandidate::PointDataPtr();
|
|
}
|
|
|
|
PointDataPtr pData = PointDataPtr(new PointData(pMMData,
|
|
dScore));
|
|
m_Points.push_back(pData);
|
|
|
|
return pData;
|
|
}
|
|
|
|
double MHTRouteCandidate::RouteSegment::RemoveLastPoint(void)
|
|
{
|
|
if (m_Points.size() > 0)
|
|
{
|
|
const PointDataPtr& pData = m_Points.back();
|
|
double dScore = 0.0;
|
|
if (pData != NULL)
|
|
{
|
|
dScore = pData->GetScore();
|
|
}
|
|
m_Points.pop_back();
|
|
|
|
return dScore;
|
|
}
|
|
else
|
|
{
|
|
return -1.0;
|
|
}
|
|
}
|
|
|
|
bool MHTRouteCandidate::RouteSegment::IsOffRoad(void) const
|
|
{
|
|
return m_pSection == NULL || !m_pSection->IsDefined();
|
|
}
|
|
|
|
void MHTRouteCandidate::RouteSegment::Print(std::ostream& os) const
|
|
{
|
|
os << "Section: ";
|
|
if (m_pSection != NULL)
|
|
{
|
|
m_pSection->PrintIdentifier(os);
|
|
}
|
|
else
|
|
{
|
|
os << "NULL";
|
|
}
|
|
os << endl;
|
|
|
|
if (m_Points.size() > 0)
|
|
{
|
|
std::vector<PointDataPtr>::const_iterator it = m_Points.begin();
|
|
while (it != m_Points.end())
|
|
{
|
|
os << "PointData : " << endl;
|
|
const PointDataPtr& pData = *it;
|
|
if (pData != NULL)
|
|
{
|
|
pData->Print(os);
|
|
}
|
|
else
|
|
{
|
|
os << "NULL-Data";
|
|
}
|
|
|
|
os << endl;
|
|
|
|
++it;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
os << "no points" << endl;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
7 class MHTRouteCandidate::RouteSegmentIterator
|
|
|
|
*/
|
|
|
|
MHTRouteCandidate::RouteSegmentIterator::RouteSegmentIterator(
|
|
const RouteSegmentIterator& rIt)
|
|
:m_ItRouteSegment(rIt.m_ItRouteSegment),
|
|
m_ItRouteSegment_R(rIt.m_ItRouteSegment_R),
|
|
m_nIdxContainer(rIt.m_nIdxContainer),
|
|
m_bReverse(rIt.m_bReverse),
|
|
m_pRouteCandidate(rIt.m_pRouteCandidate)
|
|
{
|
|
}
|
|
|
|
MHTRouteCandidate::RouteSegmentIterator::RouteSegmentIterator(
|
|
const MHTRouteCandidate* pCandidate,
|
|
bool bBegin, bool bReverse)
|
|
:m_ItRouteSegment(),
|
|
m_ItRouteSegment_R(),
|
|
m_nIdxContainer(-1),
|
|
m_bReverse(bReverse),
|
|
m_pRouteCandidate(pCandidate)
|
|
{
|
|
if (pCandidate == NULL)
|
|
return;
|
|
|
|
if (bBegin)
|
|
{
|
|
if (bReverse)
|
|
{
|
|
m_nIdxContainer = -1; // -1 => pCandidate->m_Segments
|
|
m_ItRouteSegment_R = pCandidate->m_Segments.rbegin();
|
|
|
|
if (m_ItRouteSegment_R == pCandidate->m_Segments.rend())
|
|
{
|
|
m_nIdxContainer = -2; // end
|
|
assert(pCandidate->m_SegmentsOutsourced.size() == 0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pCandidate->m_SegmentsOutsourced.size() > 0)
|
|
{
|
|
m_nIdxContainer = 0;
|
|
while (m_nIdxContainer <
|
|
(int)pCandidate->m_SegmentsOutsourced.size() &&
|
|
(pCandidate->m_SegmentsOutsourced[m_nIdxContainer] == NULL ||
|
|
pCandidate->m_SegmentsOutsourced[m_nIdxContainer]->size()
|
|
== 0))
|
|
{
|
|
++m_nIdxContainer;
|
|
}
|
|
|
|
if (m_nIdxContainer <
|
|
(int)pCandidate->m_SegmentsOutsourced.size())
|
|
{
|
|
m_ItRouteSegment =
|
|
pCandidate->m_SegmentsOutsourced[m_nIdxContainer]->begin();
|
|
}
|
|
else
|
|
{
|
|
m_nIdxContainer = -1; // -1 => pCandidate->m_Segments
|
|
m_ItRouteSegment = pCandidate->m_Segments.begin();
|
|
|
|
if (m_ItRouteSegment == pCandidate->m_Segments.end())
|
|
{
|
|
m_nIdxContainer = -2; // end
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_nIdxContainer = -1; // -1 => pCandidate->m_Segments
|
|
m_ItRouteSegment = pCandidate->m_Segments.begin();
|
|
|
|
if (m_ItRouteSegment == pCandidate->m_Segments.end())
|
|
{
|
|
m_nIdxContainer = -2; // end
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// end
|
|
m_nIdxContainer = -2; // -2 => end
|
|
}
|
|
}
|
|
|
|
MHTRouteCandidate::RouteSegmentIterator::~RouteSegmentIterator()
|
|
{
|
|
m_pRouteCandidate = NULL;
|
|
}
|
|
|
|
MHTRouteCandidate::RouteSegmentIterator&
|
|
MHTRouteCandidate::RouteSegmentIterator::
|
|
operator=(const RouteSegmentIterator& rIt)
|
|
{
|
|
m_ItRouteSegment = rIt.m_ItRouteSegment;
|
|
m_ItRouteSegment_R = rIt.m_ItRouteSegment_R;
|
|
m_nIdxContainer = rIt.m_nIdxContainer;
|
|
m_bReverse = rIt.m_bReverse;
|
|
m_pRouteCandidate = rIt.m_pRouteCandidate;
|
|
|
|
return *this;
|
|
}
|
|
|
|
bool MHTRouteCandidate::RouteSegmentIterator::operator==(
|
|
const RouteSegmentIterator& rIt) const
|
|
{
|
|
if (m_nIdxContainer == -2 || rIt.m_nIdxContainer == -2) // end
|
|
return m_nIdxContainer == rIt.m_nIdxContainer;
|
|
else
|
|
{
|
|
if (m_bReverse)
|
|
{
|
|
return (m_nIdxContainer == rIt.m_nIdxContainer &&
|
|
rIt.m_ItRouteSegment_R == m_ItRouteSegment_R);
|
|
}
|
|
else
|
|
{
|
|
return (m_nIdxContainer == rIt.m_nIdxContainer &&
|
|
rIt.m_ItRouteSegment == m_ItRouteSegment);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool MHTRouteCandidate::RouteSegmentIterator::operator!=(
|
|
const RouteSegmentIterator& rIt) const
|
|
{
|
|
return !(this->operator ==(rIt));
|
|
}
|
|
|
|
const MHTRouteCandidate::RouteSegmentPtr
|
|
MHTRouteCandidate::RouteSegmentIterator::operator*() const
|
|
{
|
|
if (m_bReverse)
|
|
{
|
|
return *m_ItRouteSegment_R;
|
|
}
|
|
else
|
|
{
|
|
return *m_ItRouteSegment;
|
|
}
|
|
}
|
|
|
|
MHTRouteCandidate::RouteSegmentIterator&
|
|
MHTRouteCandidate::RouteSegmentIterator::operator++()
|
|
{
|
|
if (m_pRouteCandidate == NULL || m_nIdxContainer == -2 /*end*/)
|
|
{
|
|
assert(false);
|
|
return *this;
|
|
}
|
|
|
|
if (m_bReverse)
|
|
{
|
|
const std::deque<RouteSegmentPtr>& rCont = (m_nIdxContainer == -1) ?
|
|
m_pRouteCandidate->m_Segments :
|
|
*(m_pRouteCandidate->m_SegmentsOutsourced[m_nIdxContainer]);
|
|
|
|
if (m_ItRouteSegment_R != rCont.rend())
|
|
{
|
|
++m_ItRouteSegment_R;
|
|
if (m_ItRouteSegment_R == rCont.rend())
|
|
{
|
|
return this->operator ++();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_nIdxContainer == -1)
|
|
{
|
|
// process last outsourced container
|
|
m_nIdxContainer =
|
|
(int) m_pRouteCandidate->m_SegmentsOutsourced.size() - 1;
|
|
}
|
|
else
|
|
{
|
|
--m_nIdxContainer;
|
|
}
|
|
|
|
if (m_nIdxContainer < 0 ||
|
|
m_nIdxContainer >=
|
|
(int) m_pRouteCandidate->m_SegmentsOutsourced.size())
|
|
{
|
|
m_nIdxContainer = -2; // end
|
|
}
|
|
else
|
|
{
|
|
const std::deque<RouteSegmentPtr>& rContNew =
|
|
*(m_pRouteCandidate->m_SegmentsOutsourced[m_nIdxContainer]);
|
|
m_ItRouteSegment_R = rContNew.rbegin();
|
|
if (m_ItRouteSegment_R == rContNew.rend())
|
|
{
|
|
return this->operator ++();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const std::deque<RouteSegmentPtr>& rCont = (m_nIdxContainer == -1) ?
|
|
m_pRouteCandidate->m_Segments :
|
|
*(m_pRouteCandidate->m_SegmentsOutsourced[m_nIdxContainer]);
|
|
|
|
if (m_ItRouteSegment != rCont.end())
|
|
{
|
|
++m_ItRouteSegment;
|
|
if (m_ItRouteSegment == rCont.end())
|
|
{
|
|
return this->operator ++();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_nIdxContainer == -1)
|
|
{
|
|
m_nIdxContainer = -2; // end
|
|
}
|
|
else
|
|
{
|
|
++m_nIdxContainer;
|
|
if (m_nIdxContainer >=
|
|
(int) m_pRouteCandidate->m_SegmentsOutsourced.size())
|
|
{
|
|
m_nIdxContainer = -1; // m_pRouteCandidate->m_Segments
|
|
m_ItRouteSegment = m_pRouteCandidate->m_Segments.begin();
|
|
if (m_ItRouteSegment == m_pRouteCandidate->m_Segments.end())
|
|
{
|
|
return this->operator ++();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const std::deque<RouteSegmentPtr>& rContNew =
|
|
*(m_pRouteCandidate->m_SegmentsOutsourced[m_nIdxContainer]);
|
|
m_ItRouteSegment = rContNew.begin();
|
|
if (m_ItRouteSegment == rContNew.end())
|
|
{
|
|
return this->operator ++();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
} // end of namespace mapmatch
|
|
|
|
|