Files
secondo/Algebras/MapMatching/MapMatchingMHTOEdgeTupleStreamCreator.h

912 lines
28 KiB
C
Raw Normal View History

2026-01-23 17:03:45 +08:00
/*
----
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] Header File of the MapMatching Algebra
April, 2012. Matthias Roth
[TOC]
1 Overview
This header file essentially contains the definition of the class
~OEdgeTupleStreamCreator~.
2 Defines and includes
*/
#ifndef MAPMATCHINGMHTORELCREATOR_H_
#define MAPMATCHINGMHTORELCREATOR_H_
#include "MapMatchingMHT.h"
#include "MHTRouteCandidate.h"
#include <vector>
class Tuple;
class TupleBuffer;
class TupleType;
class GenericRelationIterator;
namespace datetime
{
class DateTime;
}
using datetime::DateTime;
namespace mapmatch {
/*
3 class OEdgeTupleStreamCreator
*/
template<class T>
class OEdgeTupleStreamCreator : public IMapMatchingMHTResultCreator
{
public:
enum EMode
{
MODE_EDGES,
MODE_EDGES_AND_POSITIONS
};
OEdgeTupleStreamCreator(Supplier s,
const class ONetworkAdapter<T>& rNetw,
EMode eMode);
virtual ~OEdgeTupleStreamCreator();
virtual bool CreateResult(const std::vector<MHTRouteCandidate*>&
rvecRouteCandidates);
Tuple* GetNextTuple(void) const;
private:
void Init(void);
const MHTRouteCandidate::PointDataPtr GetFirstPointOfNextSegment(
MHTRouteCandidate::RouteSegmentIterator itSegments,
MHTRouteCandidate::RouteSegmentIterator itSegmentsEnd,
double& dDistance);
DateTime ProcessSegment(
const MHTRouteCandidate::RouteSegment& rSegment,
const DateTime& rEndTimePrevSegment,
const MHTRouteCandidate::PointDataPtr& pPrevPointData,
const MHTRouteCandidate::PointDataPtr& pFirstPointofNextSeg,
double dDistance); // Distance to first point
// of next segment
DateTime ProcessSegment_Edges(
const MHTRouteCandidate::RouteSegment& rSegment,
const DateTime& rEndTimePrevSegment,
const MHTRouteCandidate::PointDataPtr& pPrevPointData,
const MHTRouteCandidate::PointDataPtr& pFirstPointofNextSeg,
double dDistance); // Distance to first point
// of next segment
DateTime ProcessSegment_EdgesAndPositions(
const MHTRouteCandidate::RouteSegment& rSegment,
const DateTime& rEndTimePrevSegment,
const MHTRouteCandidate::PointDataPtr& pPrevPointData,
const MHTRouteCandidate::PointDataPtr& pFirstPointofNextSeg,
double dDistance); // Distance to first point
// of next segment
void ProcessPoints(const MHTRouteCandidate::RouteSegment& rSegment,
const DateTime& rTimeStart,
const DateTime& rTimeEnd,
const Point& rPtStart,
const Point& rPtEnd);
const Tuple* GetEdgeTuple(const MHTRouteCandidate::RouteSegment& rSegment);
void CreateTuple(const MHTRouteCandidate::RouteSegment& rSegment,
const DateTime& rTimeStart,
const DateTime& rTimeEnd);
void CreateTuple(const MHTRouteCandidate::RouteSegment& rSegment,
const DateTime& rTimeStart,
const DateTime& rTimeEnd,
const Point& rPtStart,
const Point& rPtEnd,
const double dPosStart,
const double dPosEnd);
EMode m_eMode;
TupleType* m_pTupleType;
TupleBuffer* m_pTupleBuffer;
mutable GenericRelationIterator* m_pTupleIterator;
Tuple* m_pTupleUndefEdge;
double m_dNetworkScale;
};
/*
2 Implementation
*/
template<class T>
OEdgeTupleStreamCreator<T>::OEdgeTupleStreamCreator(
Supplier s,
const ONetworkAdapter<T>& rNetw,
EMode eMode)
:m_eMode(eMode),
m_pTupleType(NULL),
m_pTupleBuffer(NULL),
m_pTupleIterator(NULL),
m_pTupleUndefEdge(NULL),
m_dNetworkScale(rNetw.GetNetworkScale())
{
ListExpr tupleType = GetTupleResultType(s);
m_pTupleType = new TupleType(nl->Second(tupleType));
m_pTupleUndefEdge = rNetw.GetUndefEdgeTuple();
}
template<class T>
OEdgeTupleStreamCreator<T>::~OEdgeTupleStreamCreator()
{
if (m_pTupleType != NULL)
m_pTupleType->DeleteIfAllowed();
m_pTupleType = NULL;
if (m_pTupleUndefEdge != NULL)
m_pTupleUndefEdge->DeleteIfAllowed();
m_pTupleUndefEdge = NULL;
delete m_pTupleIterator;
m_pTupleIterator = NULL;
delete m_pTupleBuffer;
m_pTupleBuffer = NULL;
}
template<class T>
bool OEdgeTupleStreamCreator<T>::CreateResult(
const std::vector<MHTRouteCandidate*>& rvecRouteCandidates)
{
Init();
const size_t nCandidates = rvecRouteCandidates.size();
for (size_t i = 0; i < nCandidates; ++i)
{
MHTRouteCandidate* pCandidate = rvecRouteCandidates[i];
if (pCandidate == NULL)
continue;
DateTime EndTimePrev((int64_t)0);
MHTRouteCandidate::PointDataPtr pDataEnd =
MHTRouteCandidate::PointDataPtr();
MHTRouteCandidate::RouteSegmentIterator it =
pCandidate->RouteSegmentBegin();
MHTRouteCandidate::RouteSegmentIterator itEnd =
pCandidate->RouteSegmentEnd();
for (/*empty*/; it != itEnd; ++it)
{
const MHTRouteCandidate::RouteSegmentPtr& pSegment = *it;
if (pSegment == NULL)
continue;
double dDistance = 0.0;
const MHTRouteCandidate::PointDataPtr& pData =
GetFirstPointOfNextSegment(it,
itEnd,
dDistance);
EndTimePrev = ProcessSegment(*pSegment,
EndTimePrev,
pDataEnd,
pData,
dDistance);
if (pSegment->GetPoints().size() > 0)
pDataEnd = pSegment->GetPoints().back();
else
pDataEnd = MHTRouteCandidate::PointDataPtr();
}
}
return true;
}
template<class T>
void OEdgeTupleStreamCreator<T>::Init(void)
{
if (m_pTupleIterator != NULL)
{
delete m_pTupleIterator;
m_pTupleIterator = NULL;
}
if (m_pTupleBuffer != NULL)
{
delete m_pTupleBuffer;
m_pTupleBuffer = NULL;
}
m_pTupleBuffer = new TupleBuffer;
}
template<class T>
const MHTRouteCandidate::PointDataPtr OEdgeTupleStreamCreator<T>::
GetFirstPointOfNextSegment(
MHTRouteCandidate::RouteSegmentIterator itSegments,
MHTRouteCandidate::RouteSegmentIterator itSegmentsEnd,
double& dDistance)
{
++itSegments;
dDistance = 0.0;
while (itSegments != itSegmentsEnd)
{
const MHTRouteCandidate::RouteSegmentPtr& pSegment = *itSegments;
if (pSegment == NULL)
{
++itSegments;
continue;
}
const shared_ptr<IMMNetworkSection> pSect = pSegment->GetSection();
if (pSect != NULL && pSect->GetCurve() != NULL)
{
if (pSegment->GetPoints().size() == 0)
{
dDistance += pSect->GetCurveLength(m_dNetworkScale);
}
else
{
const MHTRouteCandidate::PointDataPtr pData =
pSegment->GetPoints().front();
if (pData != NULL && pData->GetPointProjection() != NULL)
{
const SimpleLine* pCurve = pSect->GetCurve();
const Point& rPtStart = pSect->GetStartPoint();
const Point* pPt = pData->GetPointProjection();
const double dDistStart2FirstPt =
MMUtil::CalcDistance(rPtStart,
*pPt,
*pCurve,
m_dNetworkScale);
dDistance += dDistStart2FirstPt;
return pData;
}
else
{
assert(false);
}
}
}
++itSegments;
}
return MHTRouteCandidate::PointDataPtr();
}
template<class T>
DateTime OEdgeTupleStreamCreator<T>::ProcessSegment(
const MHTRouteCandidate::RouteSegment& rSegment,
const DateTime& rEndTimePrevSegment,
const MHTRouteCandidate::PointDataPtr& pPrevPointData,
const MHTRouteCandidate::PointDataPtr& pFirstPointofNextSeg,
double dDistance) // Distance to first point of next segment
{
if (m_eMode == MODE_EDGES)
{
return ProcessSegment_Edges(rSegment,
rEndTimePrevSegment,
pPrevPointData,
pFirstPointofNextSeg,
dDistance);
}
else if (m_eMode == MODE_EDGES_AND_POSITIONS)
{
return ProcessSegment_EdgesAndPositions(rSegment,
rEndTimePrevSegment,
pPrevPointData,
pFirstPointofNextSeg,
dDistance);
}
else
{
assert(false);
DateTime TimeUndef((int64_t)0);
TimeUndef.SetDefined(false);
return TimeUndef;
}
}
static Point GetLastProjectedPoint(
const std::vector<MHTRouteCandidate::PointDataPtr>& rvecPts,
DateTime& rTimeLastPt)
{
std::vector<MHTRouteCandidate::PointDataPtr>::const_reverse_iterator
itEnd = rvecPts.rend();
std::vector<MHTRouteCandidate::PointDataPtr>::const_reverse_iterator it;
Point PtRes(false);
for (it = rvecPts.rbegin(); it != itEnd && !PtRes.IsDefined(); ++it)
{
const MHTRouteCandidate::PointDataPtr pData = *it;
if (pData != NULL)
{
const Point* pPtProj = pData->GetPointProjection();
if (pPtProj != NULL && pPtProj->IsDefined())
{
PtRes = *pPtProj;
rTimeLastPt = pData->GetTime();
}
}
}
return PtRes;
}
template<class T>
DateTime OEdgeTupleStreamCreator<T>::ProcessSegment_Edges(
const MHTRouteCandidate::RouteSegment& rSegment,
const DateTime& rEndTimePrevSegment,
const MHTRouteCandidate::PointDataPtr& pPrevPointData,
const MHTRouteCandidate::PointDataPtr& pFirstPointofNextSeg,
double dDistance) // Distance to first point of next segment
{
const shared_ptr<IMMNetworkSection> pSection = rSegment.GetSection();
if (pSection == NULL)
return DateTime((int64_t)0);
const std::vector<MHTRouteCandidate::PointDataPtr>& vecPoints =
rSegment.GetPoints();
const size_t nPoints = vecPoints.size();
const SimpleLine* pCurve = pSection->GetCurve();
if (rSegment.IsOffRoad() || pCurve == NULL) // Offroad
{
return DateTime((int64_t)0);
}
// Get first point
Point PtStart = pSection->GetStartPoint();
DateTime TimeStart = rEndTimePrevSegment;
if (!TimeStart.IsDefined() || TimeStart.IsZero())
{
// first segment -> Get first projected point
for (size_t i = 0; i < nPoints; ++i)
{
const MHTRouteCandidate::PointDataPtr& pData = vecPoints[i];
if (pData != NULL)
{
const Point* pPtProj = pData->GetPointProjection();
if (pPtProj != NULL && pPtProj->IsDefined())
{
PtStart = *pPtProj;
TimeStart = pData->GetTime();
break;
}
}
}
if (!TimeStart.IsDefined() || TimeStart.IsZero())
return DateTime((int64_t)0);; // first segment and no point
}
// get last point
DateTime TimeLastPt((int64_t) 0);
TimeLastPt.SetDefined(false);
Point PtLast(GetLastProjectedPoint(vecPoints, TimeLastPt));
// Process endpoint of segment
if (pFirstPointofNextSeg == NULL ||
!pFirstPointofNextSeg->GetTime().IsDefined() ||
pFirstPointofNextSeg->GetPointProjection() == NULL ||
!pFirstPointofNextSeg->GetPointProjection()->IsDefined())
{
// this is the last point or the next segment is offroad
if (!PtLast.IsDefined())
{
PtLast = PtStart;
TimeLastPt = TimeStart;
}
ProcessPoints(rSegment, TimeStart, TimeLastPt, PtStart, PtLast);
return TimeLastPt;
}
else
{
Point PtEnd = rSegment.HasUTurn() ? pSection->GetStartPoint():
pSection->GetEndPoint();
// Calculate distance to endpoint of section
double dDist2End = 0.0;
DateTime Duration((int64_t)0); // Time to first point of next segment
DateTime TimeEnd((int64_t)0);
if (!PtLast.IsDefined())
{
dDist2End = pSection->GetCurveLength(m_dNetworkScale);
Duration = pFirstPointofNextSeg->GetTime() - TimeStart;
TimeEnd = TimeStart;
}
else
{
dDist2End = MMUtil::CalcDistance(PtLast,
PtEnd,
*pCurve,
m_dNetworkScale);
Duration = pFirstPointofNextSeg->GetTime() - TimeLastPt;
TimeEnd = TimeLastPt;
}
double dDist2FirstPtOfNextSeg = dDist2End + dDistance;
if (!AlmostEqual(dDist2FirstPtOfNextSeg, 0.0))
{
TimeEnd += DateTime(datetime::durationtype,
(uint64_t)((Duration.millisecondsToNull()
/ dDist2FirstPtOfNextSeg) * dDist2End));
if (!MMUtil::CheckSpeed(dDist2FirstPtOfNextSeg,
TimeStart, TimeEnd, PtStart, PtEnd))
{
return TimeEnd;
}
}
ProcessPoints(rSegment, TimeStart, TimeEnd, PtStart, PtEnd);
return TimeEnd;
}
}
template<class T>
DateTime OEdgeTupleStreamCreator<T>::ProcessSegment_EdgesAndPositions(
const MHTRouteCandidate::RouteSegment& rSegment,
const DateTime& rEndTimePrevSegment,
const MHTRouteCandidate::PointDataPtr& pPrevPointData,
const MHTRouteCandidate::PointDataPtr& pFirstPointofNextSeg,
double dDistance) // Distance to first point of next segment
{
const shared_ptr<IMMNetworkSection> pSection = rSegment.GetSection();
const std::vector<MHTRouteCandidate::PointDataPtr>& vecPoints =
rSegment.GetPoints();
const size_t nPoints = vecPoints.size();
DateTime TimeStart = rEndTimePrevSegment;
Point PtStart(false);
const SimpleLine* pCurve = pSection != NULL ? pSection->GetCurve() : NULL;
bool bStartsSmaller = pSection != NULL ? pSection->GetCurveStartsSmaller() :
false;
if (!TimeStart.IsDefined() || TimeStart.IsZero())
{
// first segment
MHTRouteCandidate::PointDataPtr pData = (nPoints > 0) ?
vecPoints.front() :
MHTRouteCandidate::PointDataPtr();
if (pData != NULL)
{
TimeStart = pData->GetTime();
const Point* pPtProj = pData->GetPointProjection();
if (pPtProj != NULL && pPtProj->IsDefined())
PtStart = *pPtProj;
else
PtStart = pData->GetPointGPS();
}
else
{
return DateTime((int64_t)0); // first segment and no point
}
}
else
{
if (pCurve == NULL)
{
// this segment is offroad
if (pPrevPointData == NULL)
{
MHTRouteCandidate::PointDataPtr pData = (nPoints > 0) ?
vecPoints.front() :
MHTRouteCandidate::PointDataPtr();
if (pData != NULL)
{
const Point* pPtProj = pData->GetPointProjection();
if (pPtProj != NULL && pPtProj->IsDefined())
PtStart = *pPtProj;
else
PtStart = pData->GetPointGPS();
}
else
{
return DateTime((int64_t)0);
}
}
else
{
PtStart = *(pPrevPointData->GetPointProjection());
if (!PtStart.IsDefined())
PtStart = pPrevPointData->GetPointGPS();
}
const Point* pPtProj = pPrevPointData->GetPointProjection();
if (pPtProj != NULL)
PtStart = *pPtProj;
}
else
{
if (pPrevPointData == NULL ||
pPrevPointData->GetPointProjection() != NULL) // onroad
{
PtStart = pCurve->StartPoint(bStartsSmaller);
}
else
PtStart = pPrevPointData->GetPointGPS();
}
}
// Process all points
Point PtEnd(false);
DateTime TimeEnd((int64_t)0);
for (size_t i = 0; i < nPoints; ++i)
{
const MHTRouteCandidate::PointDataPtr& pData = vecPoints[i];
if (pData == NULL)
continue;
TimeEnd = pData->GetTime();
const Point* pPtProj = pData->GetPointProjection();
if (pPtProj != NULL && pPtProj->IsDefined())
{
PtEnd = *pPtProj;
}
else
{
PtEnd = pData->GetPointGPS();
}
if (TimeStart == TimeEnd && AlmostEqual(PtStart, PtEnd))
continue;
ProcessPoints(rSegment, TimeStart, TimeEnd, PtStart, PtEnd);
PtStart = PtEnd;
TimeStart = TimeEnd;
}
// Process endpoint of segment
if (pFirstPointofNextSeg == NULL ||
!pFirstPointofNextSeg->GetTime().IsDefined() ||
pFirstPointofNextSeg->GetPointProjection() == NULL ||
!pFirstPointofNextSeg->GetPointProjection()->IsDefined())
{
// this is the last point or the next segment is offroad
return TimeStart;
}
else if (pSection != NULL && pCurve != NULL)
{
// Calculate distance to endpoint of section
Point PtEndSegment = rSegment.HasUTurn() ? pSection->GetStartPoint():
pSection->GetEndPoint();
const double dDistLastPt2End = MMUtil::CalcDistance(PtStart,
PtEndSegment,
*pCurve,
m_dNetworkScale);
double dDistLastPt2FirstPtOfNextSeg = dDistLastPt2End + dDistance;
if (AlmostEqual(dDistLastPt2FirstPtOfNextSeg, 0.0))
{
return TimeStart;
}
DateTime Duration = pFirstPointofNextSeg->GetTime() - TimeStart;
DateTime TimeEnd = TimeStart +
DateTime(datetime::durationtype,
(uint64_t)((Duration.millisecondsToNull()
/ dDistLastPt2FirstPtOfNextSeg) *
dDistLastPt2End));
if (TimeStart != TimeEnd && !AlmostEqual(PtStart, PtEndSegment))
{
if (MMUtil::CheckSpeed(dDistLastPt2End, TimeStart, TimeEnd,
PtStart, PtEnd,
rSegment.GetSection()->GetRoadType(),
rSegment.GetSection()->GetMaxSpeed()))
{
ProcessPoints(rSegment,
TimeStart, TimeEnd,
PtStart, PtEndSegment);
}
}
return TimeEnd;
}
else
{
MHTRouteCandidate::PointDataPtr pData = (nPoints > 0) ?
vecPoints.back() :
MHTRouteCandidate::PointDataPtr();
if (pData != NULL)
return pData->GetTime();
else
return DateTime((int64_t)0);
}
}
template<class T>
void OEdgeTupleStreamCreator<T>::ProcessPoints(
const MHTRouteCandidate::RouteSegment& rSegment,
const DateTime& rTimeStart,
const DateTime& rTimeEnd,
const Point& rPtStart,
const Point& rPtEnd)
{
if (m_eMode == MODE_EDGES)
{
CreateTuple(rSegment, rTimeStart, rTimeEnd);
}
else if (m_eMode == MODE_EDGES_AND_POSITIONS)
{
double dPosStart = -1.0;
double dPosEnd = -1.0;
const shared_ptr<IMMNetworkSection>& pSection = rSegment.GetSection();
if (pSection != NULL && pSection->IsDefined())
{
const SimpleLine* pCurve = pSection->GetCurve();
if (pCurve != NULL && !pCurve->IsEmpty())
{
const bool bStartsSmaller = pSection->GetCurveStartsSmaller();
const Point& rPtStartCurve = pCurve->StartPoint(bStartsSmaller);
const Point& rPtEndCurve = pCurve->EndPoint(bStartsSmaller);
// calculate PosStart
if (AlmostEqual(rPtStart, rPtStartCurve) ||
AlmostEqual(rPtStart, rPtEndCurve))
{
pCurve->AtPoint(rPtStart, bStartsSmaller, 0.0, dPosStart);
}
if (dPosStart < 0.0)
{
MMUtil::GetPosOnSimpleLine(*pCurve,
rPtStart,
bStartsSmaller,
m_dNetworkScale,
dPosStart);
}
// calculate PosEnd
if (AlmostEqual(rPtEnd, rPtStartCurve) ||
AlmostEqual(rPtEnd, rPtEndCurve))
{
pCurve->AtPoint(rPtEnd, bStartsSmaller, 0.0, dPosEnd);
}
if (dPosEnd < 0.0)
{
MMUtil::GetPosOnSimpleLine(*pCurve,
rPtEnd,
bStartsSmaller,
m_dNetworkScale,
dPosEnd);
}
}
}
CreateTuple(rSegment,
rTimeStart, rTimeEnd,
rPtStart, rPtEnd,
dPosStart, dPosEnd);
}
else
{
assert(false);
}
}
template<class T>
const Tuple* OEdgeTupleStreamCreator<T>::GetEdgeTuple(
const MHTRouteCandidate::RouteSegment& rSegment)
{
const shared_ptr<IMMNetworkSection> pSection = rSegment.GetSection();
if (pSection == NULL)
{
return m_pTupleUndefEdge;
}
const ONetworkSectionAdapter<T>* pAdapter =
(const ONetworkSectionAdapter<T>*) pSection.get();
if (pAdapter == NULL)
{
assert(false); // only for ONetwork
return NULL;
}
const ONetworkEdge<T>* pEdge = pAdapter->GetNetworkEdge();
if (pEdge == NULL)
{
assert(false);
return NULL;
}
return pEdge->GetTuple();
}
template<class T>
void OEdgeTupleStreamCreator<T>::CreateTuple(
const MHTRouteCandidate::RouteSegment& rSegment,
const DateTime& rTimeStart,
const DateTime& rTimeEnd)
{
const Tuple* pTupleEdge = GetEdgeTuple(rSegment);
if (pTupleEdge == NULL)
{
return;
}
// Create new Tuple and copy attributes
Tuple* pResultTuple = new Tuple(m_pTupleType);
int i = 0;
while (i < pTupleEdge->GetNoAttributes())
{
pResultTuple->CopyAttribute(i, pTupleEdge, i);
++i;
}
// Create new attributes
DateTime* pTimeStart = new DateTime(rTimeStart);
pResultTuple->PutAttribute(i, pTimeStart);
++i;
DateTime* pTimeEnd = new DateTime(rTimeEnd);
pResultTuple->PutAttribute(i, pTimeEnd);
// Add new tuple to buffer
m_pTupleBuffer->AppendTuple(pResultTuple);
pResultTuple->DeleteIfAllowed();
}
template<class T>
void OEdgeTupleStreamCreator<T>::CreateTuple(
const MHTRouteCandidate::RouteSegment& rSegment,
const DateTime& rTimeStart,
const DateTime& rTimeEnd,
const Point& rPtStart,
const Point& rPtEnd,
const double dPosStart,
const double dPosEnd)
{
const Tuple* pTupleEdge = GetEdgeTuple(rSegment);
if (pTupleEdge == NULL)
{
//assert(false);
return;
}
// Create new Tuple and copy attributes
Tuple* pResultTuple = new Tuple(m_pTupleType);
int i = 0;
while (i < pTupleEdge->GetNoAttributes())
{
pResultTuple->CopyAttribute(i, pTupleEdge, i);
++i;
}
// Create new attributes
DateTime* pTimeStart = new DateTime(rTimeStart);
pResultTuple->PutAttribute(i, pTimeStart);
++i;
DateTime* pTimeEnd = new DateTime(rTimeEnd);
pResultTuple->PutAttribute(i, pTimeEnd);
++i;
Point* pPtStart = new Point(rPtStart);
pResultTuple->PutAttribute(i, pPtStart);
++i;
Point* pPtEnd = new Point(rPtEnd);
pResultTuple->PutAttribute(i, pPtEnd);
++i;
CcReal* pPosStart = NULL;
if (dPosStart < 0.0)
pPosStart = new CcReal(false);
else
pPosStart = new CcReal(true, dPosStart);
pResultTuple->PutAttribute(i, pPosStart);
++i;
CcReal* pPosEnd = NULL;
if (dPosEnd < 0.0)
pPosEnd = new CcReal(false);
else
pPosEnd = new CcReal(true, dPosEnd);
pResultTuple->PutAttribute(i, pPosEnd);
// Add new tuple to buffer
m_pTupleBuffer->AppendTuple(pResultTuple);
pResultTuple->DeleteIfAllowed();
}
template<class T>
Tuple* OEdgeTupleStreamCreator<T>::GetNextTuple(void) const
{
if (m_pTupleBuffer == NULL)
return NULL;
if (m_pTupleIterator == NULL)
{
m_pTupleIterator = m_pTupleBuffer->MakeScan();
}
if (m_pTupleIterator != NULL && !m_pTupleIterator->EndOfScan())
{
return m_pTupleIterator->GetNextTuple();
}
else
{
return NULL;
}
}
} // end of namespace mapmatch
#endif /* MAPMATCHINGMHTORELCREATOR_H_ */