2331 lines
72 KiB
C++
2331 lines
72 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 ] [}]
|
|
//characters [2] verbatim: [\verb@] [@]
|
|
//[ue] [\"{u}]
|
|
//[toc] [\tableofcontents]
|
|
|
|
""[2]
|
|
|
|
[1] Implementation file of the MapMatching Algebra
|
|
|
|
January-April 2012, Matthias Roth
|
|
2012 November /December, Simone Jandt added mapmatching for jnetwork objects
|
|
|
|
[TOC]
|
|
|
|
1 Overview
|
|
|
|
This implementation file contains the implementation of the class
|
|
~MapMatchingAlgebra~.
|
|
|
|
For more detailed information see MapMatchingAlgebra.h.
|
|
|
|
2 Defines and Includes
|
|
|
|
*/
|
|
|
|
#include "ONetworkAdapter.h"
|
|
#include <string>
|
|
#include "NestedList.h"
|
|
#include "ListUtils.h"
|
|
#include "NList.h"
|
|
#include "LogMsg.h"
|
|
#include "QueryProcessor.h"
|
|
#include "ConstructorTemplates.h"
|
|
#include "StandardTypes.h"
|
|
#include "TypeMapUtils.h"
|
|
#include "Symbols.h"
|
|
|
|
#include "MapMatchingAlgebra.h"
|
|
#include "Algebras/Network/NetworkAlgebra.h"
|
|
#include "Algebras/TemporalNet/TemporalNetAlgebra.h"
|
|
#include "Algebras/OrderedRelation/OrderedRelationAlgebra.h"
|
|
#include "Algebras/FText/FTextAlgebra.h"
|
|
#include "ONetwork.h"
|
|
#include "ONetworkEdge.h"
|
|
#include "MapMatchingMHT.h"
|
|
#include "MapMatchingData.h"
|
|
#include "GPXImporter.h"
|
|
#include "NetworkAdapter.h"
|
|
#include "JNetworkAdapter.h"
|
|
#include "MapMatchingMHTMGPointCreator.h"
|
|
#include "MapMatchingMHTPointsCreator.h"
|
|
#include "MapMatchingMHTOEdgeTupleStreamCreator.h"
|
|
#include "MapMatchingMHTMPointCreator.h"
|
|
#include "MapMatchingMHTMJPointCreator.h"
|
|
|
|
#include "Algebras/Standard-C++/LongInt.h"
|
|
|
|
extern NestedList* nl;
|
|
extern QueryProcessor *qp;
|
|
|
|
using namespace std;
|
|
using namespace network;
|
|
using namespace jnetwork;
|
|
using namespace temporalnet;
|
|
|
|
namespace mapmatch {
|
|
|
|
/*
|
|
3 mapmatchmht-operator
|
|
|
|
3.1 Operator-Info
|
|
|
|
*/
|
|
struct MapMatchMHTInfo : OperatorInfo
|
|
{
|
|
|
|
MapMatchMHTInfo()
|
|
{
|
|
name = "mapmatchmht";
|
|
signature = Network::BasicType() + " x " +
|
|
temporalalgebra::MPoint::BasicType() + " -> " +
|
|
temporalnet::MGPoint::BasicType();
|
|
|
|
appendSignature(Network::BasicType() + " x " +
|
|
FText::BasicType() + " -> " +
|
|
temporalnet::MGPoint::BasicType());
|
|
|
|
appendSignature(Network::BasicType() + " x " +
|
|
"(stream (tuple([Lat:real, Lon:real, Time:DateTime "
|
|
"[,Fix:int] [,Sat:int] [,Hdop : real]"
|
|
"[,Vdop:real] [,Pdop:real] "
|
|
"[,Course:real] [,Speed(m/s):real]])))"
|
|
+ " -> " +
|
|
temporalnet::MGPoint::BasicType());
|
|
|
|
appendSignature(Network::BasicType() + " x " +
|
|
temporalalgebra::MPoint::BasicType() + " x " +
|
|
CcReal::BasicType() + " -> " +
|
|
temporalnet::MGPoint::BasicType());
|
|
|
|
appendSignature(Network::BasicType() + " x " +
|
|
FText::BasicType() + " x " +
|
|
CcReal::BasicType() + " -> " +
|
|
temporalnet::MGPoint::BasicType());
|
|
|
|
appendSignature(Network::BasicType() + " x " +
|
|
CcReal::BasicType() + " x " +
|
|
"(stream (tuple([Lat:real, Lon:real, Time:DateTime "
|
|
"[,Fix:int] [,Sat:int] [,Hdop : real]"
|
|
"[,Vdop:real] [,Pdop:real] "
|
|
"[,Course:real] [,Speed(m/s):real]])))"
|
|
+ CcReal::BasicType() + " -> " +
|
|
temporalnet::MGPoint::BasicType());
|
|
|
|
syntax = "mapmatchmht ( _ , _ [, _ ] )";
|
|
meaning = "The operation maps the MPoint or "
|
|
"the data of a gpx-file or "
|
|
"the data of a tuple stream "
|
|
"to the given network."
|
|
"With the optional real-parameter the scaling"
|
|
"factor of the network can be specified."
|
|
"Result is a MGPoint.";
|
|
example = "mapmatchmht (DortmundNet, 'Trk_Dortmund.gpx')";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
3.2 Type-Mapping
|
|
|
|
*/
|
|
|
|
static ListExpr GetMMDataIndexesOfTupleStream(ListExpr TupleStream);
|
|
static ListExpr AppendLists(ListExpr List1, ListExpr List2);
|
|
|
|
ListExpr OpMapMatchingMHTTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if(param.length() != 2 && param.length() != 3)
|
|
return listutils::typeError("two or three arguments expected");
|
|
|
|
if (!param.first().isSymbol(Network::BasicType()))
|
|
return listutils::typeError("1st argument must be " +
|
|
Network::BasicType());
|
|
|
|
if (!param.second().isSymbol(temporalalgebra::MPoint::BasicType()) &&
|
|
!param.second().isSymbol(FText::BasicType()) &&
|
|
!listutils::isTupleStream(param.second().listExpr()))
|
|
{
|
|
return listutils::typeError("2nd argument must be " +
|
|
temporalalgebra::MPoint::BasicType()
|
|
+ " or " +
|
|
FText::BasicType() + " or " +
|
|
"tuple stream");
|
|
}
|
|
|
|
if (param.length() == 3)
|
|
{
|
|
if (!param.third().isSymbol(CcReal::BasicType()))
|
|
return listutils::typeError("3rd argument must be " +
|
|
CcReal::BasicType());
|
|
}
|
|
|
|
if (listutils::isTupleStream(param.second().listExpr()))
|
|
{
|
|
ListExpr Ind = GetMMDataIndexesOfTupleStream(param.second().listExpr());
|
|
|
|
if(nl->Equal(Ind,nl->TypeError()))
|
|
return Ind;
|
|
else
|
|
{
|
|
if (param.length() == 2)
|
|
{
|
|
// Add scaling (default 1.0) and indexes
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
|
|
AppendLists(
|
|
nl->OneElemList(nl->RealAtom(1.0)),
|
|
Ind),
|
|
nl->SymbolAtom(temporalnet::MGPoint::BasicType()));
|
|
}
|
|
else
|
|
{
|
|
// Add indexes
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
|
|
Ind,
|
|
nl->SymbolAtom(temporalnet::MGPoint::BasicType()));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (param.length() == 2)
|
|
{
|
|
// Add scaling (default 1.0)
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
|
|
nl->OneElemList(nl->RealAtom(1.0)),
|
|
nl->SymbolAtom(temporalnet::MGPoint::BasicType()));
|
|
}
|
|
else
|
|
return nl->SymbolAtom(temporalnet::MGPoint::BasicType());
|
|
}
|
|
}
|
|
|
|
static ListExpr GetMMDataIndexesOfTupleStream(ListExpr TupleStream)
|
|
{
|
|
ListExpr attrType;
|
|
int nAttrLatIndex = listutils::findAttribute(
|
|
nl->Second(nl->Second(TupleStream)), "Lat", attrType);
|
|
if(nAttrLatIndex==0)
|
|
{
|
|
return listutils::typeError("'Lat' not found in attr list");
|
|
}
|
|
else
|
|
{
|
|
if (!listutils::isSymbol(attrType, CcReal::BasicType()))
|
|
{
|
|
return listutils::typeError("'Lat' must be " +
|
|
CcReal::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrLonIndex = listutils::findAttribute(
|
|
nl->Second(nl->Second(TupleStream)), "Lon", attrType);
|
|
if (nAttrLonIndex == 0)
|
|
{
|
|
return listutils::typeError("'Lon' not found in attr list");
|
|
}
|
|
else
|
|
{
|
|
if (!listutils::isSymbol(attrType, CcReal::BasicType()))
|
|
{
|
|
return listutils::typeError("'Lon' must be " +
|
|
CcReal::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrTimeIndex = listutils::findAttribute(
|
|
nl->Second(nl->Second(TupleStream)), "Time", attrType);
|
|
if (nAttrTimeIndex == 0)
|
|
{
|
|
return listutils::typeError("'Time' not found in attr list");
|
|
}
|
|
else
|
|
{
|
|
if (!listutils::isSymbol(attrType, DateTime::BasicType()))
|
|
{
|
|
return listutils::typeError("'Time' must be " +
|
|
DateTime::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrFixIndex = listutils::findAttribute(
|
|
nl->Second(nl->Second(TupleStream)), "Fix", attrType);
|
|
if (nAttrFixIndex != 0)
|
|
{
|
|
if (!listutils::isSymbol(attrType, CcInt::BasicType()))
|
|
{
|
|
return listutils::typeError("'Fix' must be " +
|
|
CcInt::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrSatIndex = listutils::findAttribute(
|
|
nl->Second(nl->Second(TupleStream)), "Sat", attrType);
|
|
if (nAttrSatIndex != 0)
|
|
{
|
|
if (!listutils::isSymbol(attrType, CcInt::BasicType()))
|
|
{
|
|
return listutils::typeError("'Sat' must be " +
|
|
CcInt::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrHdopIndex = listutils::findAttribute(
|
|
nl->Second(nl->Second(TupleStream)), "Hdop", attrType);
|
|
if (nAttrHdopIndex != 0)
|
|
{
|
|
if (!listutils::isSymbol(attrType, CcReal::BasicType()))
|
|
{
|
|
return listutils::typeError("'Hdop' must be " +
|
|
CcReal::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrVdopIndex = listutils::findAttribute(
|
|
nl->Second(nl->Second(TupleStream)), "Vdop", attrType);
|
|
if (nAttrVdopIndex != 0)
|
|
{
|
|
if (!listutils::isSymbol(attrType, CcReal::BasicType()))
|
|
{
|
|
return listutils::typeError("'Vdop' must be " +
|
|
CcReal::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrPdopIndex = listutils::findAttribute(
|
|
nl->Second(nl->Second(TupleStream)), "Pdop", attrType);
|
|
if (nAttrPdopIndex != 0)
|
|
{
|
|
if (!listutils::isSymbol(attrType, CcReal::BasicType()))
|
|
{
|
|
return listutils::typeError("'Pdop' must be " +
|
|
CcReal::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrCourseIndex = listutils::findAttribute(
|
|
nl->Second(nl->Second(TupleStream)), "Course", attrType);
|
|
if (nAttrCourseIndex != 0)
|
|
{
|
|
if (!listutils::isSymbol(attrType, CcReal::BasicType()))
|
|
{
|
|
return listutils::typeError(
|
|
"'Course' must be " + CcReal::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrSpeedIndex = listutils::findAttribute(
|
|
nl->Second(nl->Second(TupleStream)), "Speed", attrType);
|
|
if (nAttrSpeedIndex != 0)
|
|
{
|
|
if (!listutils::isSymbol(attrType, CcReal::BasicType()))
|
|
{
|
|
return listutils::typeError(
|
|
"'Speed' must be " + CcReal::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrEleIndex = listutils::findAttribute(
|
|
nl->Second(nl->Second(TupleStream)), "Ele", attrType);
|
|
if (nAttrEleIndex != 0)
|
|
{
|
|
if (!listutils::isSymbol(attrType, CcReal::BasicType()))
|
|
{
|
|
return listutils::typeError(
|
|
"'Ele' must be " + CcReal::BasicType());
|
|
}
|
|
}
|
|
|
|
--nAttrLatIndex;
|
|
--nAttrLonIndex;
|
|
--nAttrTimeIndex;
|
|
--nAttrFixIndex;
|
|
--nAttrSatIndex;
|
|
--nAttrHdopIndex;
|
|
--nAttrVdopIndex;
|
|
--nAttrPdopIndex;
|
|
--nAttrCourseIndex;
|
|
--nAttrSpeedIndex;
|
|
--nAttrEleIndex;
|
|
|
|
ListExpr Ind = nl->OneElemList(nl->IntAtom(nAttrLatIndex));
|
|
ListExpr Last = Ind;
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrLonIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrTimeIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrFixIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrSatIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrHdopIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrVdopIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrPdopIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrCourseIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrSpeedIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrEleIndex));
|
|
|
|
return Ind;
|
|
}
|
|
|
|
|
|
/*
|
|
3.3 Value-Mapping
|
|
|
|
*/
|
|
int OpMapMatchingMHTMPointValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// cout << "OpMapMatchingMHTMPointValueMapping called" << endl;
|
|
|
|
// Initialize Result
|
|
result = qp->ResultStorage(in_xSupplier);
|
|
temporalnet::MGPoint* pRes = static_cast<MGPoint*>(result.addr);
|
|
|
|
// get Arguments
|
|
Network *pNetwork = static_cast<Network*>(args[0].addr);
|
|
temporalalgebra::MPoint *pMPoint =
|
|
static_cast<temporalalgebra::MPoint*>(args[1].addr);
|
|
CcReal *pNetworkScale = static_cast<CcReal*>(args[2].addr);
|
|
|
|
// Do Map Matching
|
|
|
|
NetworkAdapter Network(pNetwork, pNetworkScale->GetValue());
|
|
MapMatchingMHT MapMatching(&Network, pMPoint);
|
|
|
|
MGPointCreator Creator(&Network, pRes);
|
|
|
|
if (!MapMatching.DoMatch(&Creator))
|
|
{
|
|
// Error
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int OpMapMatchingMHTGPXValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// cout << "OpMapMatchingMHTGPXValueMapping called" << endl;
|
|
|
|
// Initialize Result
|
|
result = qp->ResultStorage(in_xSupplier);
|
|
temporalnet::MGPoint* pRes = static_cast<MGPoint*>(result.addr);
|
|
|
|
// get Arguments
|
|
Network* pNetwork = static_cast<Network*>(args[0].addr);
|
|
FText* pFileName = static_cast<FText*>(args[1].addr);
|
|
std::string strFileName = pFileName->GetValue();
|
|
CcReal *pNetworkScale = static_cast<CcReal*>(args[2].addr);
|
|
|
|
// Do Map Matching
|
|
|
|
NetworkAdapter Network(pNetwork, pNetworkScale->GetValue());
|
|
MapMatchingMHT MapMatching(&Network, strFileName);
|
|
|
|
MGPointCreator Creator(&Network, pRes);
|
|
|
|
if (!MapMatching.DoMatch(&Creator))
|
|
{
|
|
// Error
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static shared_ptr<MapMatchDataContainer> GetMMDataFromTupleStream(
|
|
Supplier Stream,
|
|
Word* args,
|
|
int nOffset)
|
|
{
|
|
//cout << "Get Data from Tuple Stream" << endl;
|
|
// see also GetMMDataIndexesOfTupleStream
|
|
|
|
shared_ptr<MapMatchDataContainer> pContData(new MapMatchDataContainer);
|
|
|
|
const CcInt* pIdxLat = static_cast<CcInt*>(args[nOffset + 0].addr);
|
|
const CcInt* pIdxLon = static_cast<CcInt*>(args[nOffset + 1].addr);
|
|
const CcInt* pIdxTime = static_cast<CcInt*>(args[nOffset + 2].addr);
|
|
const CcInt* pIdxFix = static_cast<CcInt*>(args[nOffset + 3].addr);
|
|
const CcInt* pIdxSat = static_cast<CcInt*>(args[nOffset + 4].addr);
|
|
const CcInt* pIdxHdop = static_cast<CcInt*>(args[nOffset + 5].addr);
|
|
const CcInt* pIdxVdop = static_cast<CcInt*>(args[nOffset + 6].addr);
|
|
const CcInt* pIdxPdop = static_cast<CcInt*>(args[nOffset + 7].addr);
|
|
const CcInt* pIdxCourse = static_cast<CcInt*>(args[nOffset + 8].addr);
|
|
const CcInt* pIdxSpeed = static_cast<CcInt*>(args[nOffset + 9].addr);
|
|
//const CcInt* pIdxEle = static_cast<CcInt*>(args[nOffset + 10].addr);
|
|
|
|
const int nIdxLat = pIdxLat->GetValue();
|
|
const int nIdxLon = pIdxLon->GetValue();
|
|
const int nIdxTime = pIdxTime->GetValue();
|
|
const int nIdxFix = pIdxFix->GetValue();
|
|
const int nIdxSat = pIdxSat->GetValue();
|
|
const int nIdxHdop = pIdxHdop->GetValue();
|
|
const int nIdxVdop = pIdxVdop->GetValue();
|
|
const int nIdxPdop = pIdxPdop->GetValue();
|
|
const int nIdxCourse = pIdxCourse->GetValue();
|
|
const int nIdxSpeed = pIdxSpeed->GetValue();
|
|
//const int nIdxEle = pIdxEle->GetValue();
|
|
|
|
if (nIdxLat < 0 || nIdxLon < 0 || nIdxTime < 0)
|
|
{
|
|
assert(false);
|
|
return pContData;
|
|
}
|
|
|
|
Word wTuple;
|
|
qp->Open(Stream);
|
|
qp->Request(Stream, wTuple);
|
|
while (qp->Received(Stream))
|
|
{
|
|
Tuple* pTpl = (Tuple*)wTuple.addr;
|
|
|
|
CcReal* pLat = static_cast<CcReal*>(pTpl->GetAttribute(nIdxLat));
|
|
CcReal* pLon = static_cast<CcReal*>(pTpl->GetAttribute(nIdxLon));
|
|
DateTime* pTime = static_cast<DateTime*>(pTpl->GetAttribute(nIdxTime));
|
|
|
|
CcInt* pFix = NULL;
|
|
if (nIdxFix >= 0)
|
|
pFix = static_cast<CcInt*>(pTpl->GetAttribute(nIdxFix));
|
|
|
|
CcInt* pSat = NULL;
|
|
if (nIdxSat >= 0)
|
|
pSat = static_cast<CcInt*>(pTpl->GetAttribute(nIdxSat));
|
|
|
|
CcReal* pHdop = NULL;
|
|
if (nIdxHdop >= 0)
|
|
pHdop = static_cast<CcReal*>(pTpl->GetAttribute(nIdxHdop));
|
|
|
|
CcReal* pVdop = NULL;
|
|
if (nIdxVdop >= 0)
|
|
pVdop = static_cast<CcReal*>(pTpl->GetAttribute(nIdxVdop));
|
|
|
|
CcReal* pPdop = NULL;
|
|
if (nIdxPdop >= 0)
|
|
pPdop = static_cast<CcReal*>(pTpl->GetAttribute(nIdxPdop));
|
|
|
|
CcReal* pCourse = NULL;
|
|
if (nIdxCourse >= 0)
|
|
pCourse = static_cast<CcReal*>(pTpl->GetAttribute(nIdxCourse));
|
|
|
|
CcReal* pSpeed = NULL;
|
|
if (nIdxSpeed >= 0)
|
|
pSpeed = static_cast<CcReal*>(pTpl->GetAttribute(nIdxSpeed));
|
|
|
|
/*CcReal* pEle = NULL;
|
|
if (nIdxEle >= 0)
|
|
pEle = static_cast<CcReal*>(pTpl->GetAttribute(nIdxEle));
|
|
*/
|
|
|
|
if (pLat != NULL && pLon != NULL && pTime != NULL &&
|
|
pLat->IsDefined() && pLon->IsDefined() && pTime->IsDefined())
|
|
{
|
|
//cout << "found valid data point" << endl;
|
|
MapMatchData Data(pLat->GetValue(),
|
|
pLon->GetValue(),
|
|
pTime->millisecondsToNull());
|
|
|
|
if (pFix != NULL && pFix->IsDefined())
|
|
Data.m_nFix = pFix->GetValue();
|
|
|
|
if (pSat != NULL && pSat->IsDefined())
|
|
Data.m_nSat = pSat->GetValue();
|
|
|
|
if (pHdop != NULL && pHdop->IsDefined())
|
|
Data.m_dHdop = pHdop->GetValue();
|
|
|
|
if (pVdop != NULL && pVdop->IsDefined())
|
|
Data.m_dVdop = pVdop->GetValue();
|
|
|
|
if (pPdop != NULL && pPdop->IsDefined())
|
|
Data.m_dPdop = pPdop->GetValue();
|
|
|
|
if (pCourse != NULL && pCourse->IsDefined())
|
|
Data.m_dCourse = pCourse->GetValue();
|
|
|
|
if (pSpeed != NULL && pSpeed->IsDefined())
|
|
Data.m_dSpeed = pSpeed->GetValue();
|
|
|
|
/*
|
|
if (pEle != NULL && pEle->IsDefined())
|
|
Data.m_dEle = pEle->GetValue();
|
|
*/
|
|
|
|
pContData->Append(Data);
|
|
}
|
|
|
|
pTpl->DeleteIfAllowed();
|
|
pTpl = NULL;
|
|
|
|
qp->Request(Stream, wTuple);
|
|
}
|
|
qp->Close(Stream);
|
|
|
|
return pContData;
|
|
}
|
|
|
|
int OpMapMatchingMHTStreamValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// cout << "OpMapMatchingMHTStreamValueMapping called" << endl;
|
|
|
|
// Initialize Result
|
|
result = qp->ResultStorage(in_xSupplier);
|
|
MGPoint* pRes = static_cast<MGPoint*>(result.addr);
|
|
|
|
// get Arguments
|
|
Network* pNetwork = static_cast<Network*>(args[0].addr);
|
|
|
|
shared_ptr<MapMatchDataContainer> pContData =
|
|
GetMMDataFromTupleStream(args[1].addr, args, 3);
|
|
|
|
CcReal *pNetworkScale = static_cast<CcReal*>(args[2].addr);
|
|
|
|
// Matching
|
|
|
|
NetworkAdapter Network(pNetwork, pNetworkScale->GetValue());
|
|
MapMatchingMHT MapMatching(&Network, pContData);
|
|
|
|
MGPointCreator Creator(&Network, pRes);
|
|
|
|
if (!MapMatching.DoMatch(&Creator))
|
|
{
|
|
// Error
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
3.4 Selection Function
|
|
|
|
*/
|
|
int MapMatchMHTSelect(ListExpr args)
|
|
{
|
|
NList type(args);
|
|
if ((type.length() == 2 || type.length() == 3) &&
|
|
type.first().isSymbol(Network::BasicType()))
|
|
{
|
|
if (type.second().isSymbol(temporalalgebra::MPoint::BasicType()))
|
|
{
|
|
return 0;
|
|
}
|
|
else if (type.second().isSymbol(FText::BasicType()))
|
|
{
|
|
return 1;
|
|
}
|
|
else if (listutils::isTupleStream(type.second().listExpr()))
|
|
{
|
|
return 2;
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
4 omapmatchmht-operator
|
|
|
|
4.1 Operator-Info
|
|
map matching with an ordered relation
|
|
Result: Tuples of matched edges with timestamps
|
|
|
|
*/
|
|
struct OMapMatchMHTInfo : OperatorInfo
|
|
{
|
|
|
|
OMapMatchMHTInfo()
|
|
{
|
|
name = "omapmatchmht";
|
|
signature = OrderedRelation::BasicType() + " x " +
|
|
RTree2TID::BasicType() + " x " +
|
|
Relation::BasicType() + " x " +
|
|
temporalalgebra::MPoint::BasicType() + " -> " +
|
|
"stream(tuple([<attributes of tuple of edge>,"
|
|
"StartTime:DateTime, EndTime:DateTime]))";
|
|
|
|
appendSignature(OrderedRelation::BasicType() + " x " +
|
|
RTree2TID::BasicType() + " x " +
|
|
Relation::BasicType() + " x " +
|
|
FText::BasicType() + " -> " +
|
|
"stream(tuple([<attributes of tuple of edge>,"
|
|
"StartTime:DateTime, EndTime:DateTime]))");
|
|
|
|
appendSignature(OrderedRelation::BasicType() + " x " +
|
|
RTree2TID::BasicType() + " x " +
|
|
Relation::BasicType() + " x " +
|
|
"(stream (tuple([Lat:real, Lon:real, Time:DateTime "
|
|
"[,Fix:int] [,Sat:int] [,Hdop : real]"
|
|
"[,Vdop:real] [,Pdop:real] "
|
|
"[,Course:real] [,Speed(m/s):real]])))"
|
|
+ " -> " +
|
|
"stream(tuple([<attributes of tuple of edge>,"
|
|
"StartTime:DateTime, EndTime:DateTime]))");
|
|
|
|
|
|
syntax = "omapmatchmht ( _ , _ , _ , _ )";
|
|
meaning = "The operation maps the MPoint or "
|
|
"the data of a gpx-file or "
|
|
"the data of a tuple stream "
|
|
"to the given network, which is based on an "
|
|
"ordered relation."
|
|
"Result is a stream of tuples with the matched edges "
|
|
"of the network with timestamps.";
|
|
example = "omapmatchmht(Edges, EdgeIndex_Box_rtree, "
|
|
"EdgeIndex, 'Trk_Dortmund.gpx')";
|
|
}
|
|
};
|
|
|
|
static ListExpr GetORelNetworkAttrIndexes(ListExpr ORelAttrList);
|
|
|
|
/*
|
|
4.2 Type-Mapping
|
|
|
|
*/
|
|
enum EOMapMatchingMHTResultType
|
|
{
|
|
OMM_RESULT_EDGES,
|
|
OMM_RESULT_POSITIONS_ON_EDGES,
|
|
OMM_RESULT_MPOINT
|
|
};
|
|
|
|
ListExpr OpOMapMatchingMHTTypeMap_Common(ListExpr in_xArgs,
|
|
EOMapMatchingMHTResultType eResultType)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if( param.length() != 4)
|
|
return listutils::typeError("four arguments expected");
|
|
|
|
// Check Network - OrderedRelation, RTree, Relation
|
|
|
|
NList ParamORel = param.first();
|
|
NList ParamRTree = param.second();
|
|
NList ParamRel = param.third();
|
|
|
|
// Orel
|
|
|
|
if (!listutils::isOrelDescription(ParamORel.listExpr()))
|
|
{
|
|
return listutils::typeError("1st argument must be orel");
|
|
}
|
|
|
|
NList orelTuple = ParamORel.second();
|
|
if (!listutils::isTupleDescription(orelTuple.listExpr()))
|
|
{
|
|
return listutils::typeError("2nd value of orel is not of type tuple");
|
|
}
|
|
|
|
NList orelAttrList(orelTuple.second());
|
|
if (!listutils::isAttrList(orelAttrList.listExpr()))
|
|
{
|
|
return listutils::typeError("Error in orel attrlist");
|
|
}
|
|
|
|
// Check attributes of ORel
|
|
|
|
ListExpr IndNetwAttr = GetORelNetworkAttrIndexes(orelAttrList.listExpr());
|
|
|
|
if (nl->Equal(IndNetwAttr, nl->TypeError()))
|
|
return IndNetwAttr;
|
|
|
|
// Rtree
|
|
|
|
if (!listutils::isRTreeDescription(ParamRTree.listExpr()))
|
|
{
|
|
return listutils::typeError("2nd argument must be RTree2TID");
|
|
}
|
|
|
|
const int nRTreeDim = listutils::getRTreeDim(ParamRTree.listExpr());
|
|
if (nRTreeDim != 2)
|
|
{
|
|
return listutils::typeError("rtree with dim==2 expected");
|
|
}
|
|
|
|
if (!ParamRTree.first().isSymbol(RTree2TID::BasicType()))
|
|
{
|
|
return listutils::typeError("2nd argument must be RTree2TID");
|
|
}
|
|
|
|
ListExpr rtreeKeyType = listutils::getRTreeType(ParamRTree.listExpr());
|
|
|
|
if(!listutils::isSpatialType(rtreeKeyType) &&
|
|
!listutils::isRectangle(rtreeKeyType))
|
|
{
|
|
return listutils::typeError("tree not over a spatial attribute");
|
|
}
|
|
|
|
// Relation
|
|
|
|
if(!listutils::isRelDescription(ParamRel.listExpr()))
|
|
{
|
|
return listutils::typeError("3rd argument must be relation");
|
|
}
|
|
|
|
if(ParamRTree.second() != ParamRel.second())
|
|
{
|
|
return listutils::typeError("type of rtree and relation are different");
|
|
}
|
|
|
|
// GPS-Data (MPoint, FileName, TupleStream)
|
|
|
|
if (!param.fourth().isSymbol(temporalalgebra::MPoint::BasicType()) &&
|
|
!param.fourth().isSymbol(FText::BasicType()) &&
|
|
!listutils::isTupleStream(param.fourth().listExpr()))
|
|
{
|
|
return listutils::typeError("4th argument must be " +
|
|
temporalalgebra::MPoint::BasicType()
|
|
+ " or " +
|
|
FText::BasicType() + " or " +
|
|
"tuple stream");
|
|
}
|
|
|
|
// Result
|
|
|
|
ListExpr ResultType = nl->TheEmptyList();
|
|
|
|
switch (eResultType)
|
|
{
|
|
case OMM_RESULT_EDGES:
|
|
{
|
|
ListExpr addAttrs = nl->TwoElemList(
|
|
nl->TwoElemList(nl->SymbolAtom("StartTime"),
|
|
nl->SymbolAtom(DateTime::BasicType())),
|
|
nl->TwoElemList(nl->SymbolAtom("EndTime"),
|
|
nl->SymbolAtom(DateTime::BasicType())));
|
|
|
|
ListExpr ResAttr = AppendLists(orelAttrList.listExpr(), addAttrs);
|
|
|
|
ResultType = nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom(Tuple::BasicType()),
|
|
ResAttr));
|
|
}
|
|
break;
|
|
|
|
case OMM_RESULT_POSITIONS_ON_EDGES:
|
|
{
|
|
ListExpr addAttrs = nl->SixElemList(
|
|
nl->TwoElemList(nl->SymbolAtom("StartTime"),
|
|
nl->SymbolAtom(DateTime::BasicType())),
|
|
nl->TwoElemList(nl->SymbolAtom("EndTime"),
|
|
nl->SymbolAtom(DateTime::BasicType())),
|
|
nl->TwoElemList(nl->SymbolAtom("StartPos"),
|
|
nl->SymbolAtom(Point::BasicType())),
|
|
nl->TwoElemList(nl->SymbolAtom("EndPos"),
|
|
nl->SymbolAtom(Point::BasicType())),
|
|
nl->TwoElemList(nl->SymbolAtom("StartLength"),
|
|
nl->SymbolAtom(CcReal::BasicType())),
|
|
nl->TwoElemList(nl->SymbolAtom("EndLength"),
|
|
nl->SymbolAtom(CcReal::BasicType())));
|
|
|
|
ListExpr ResAttr = AppendLists(orelAttrList.listExpr(), addAttrs);
|
|
|
|
ResultType = nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom(Tuple::BasicType()),
|
|
ResAttr));
|
|
}
|
|
break;
|
|
|
|
case OMM_RESULT_MPOINT:
|
|
{
|
|
ResultType = nl->SymbolAtom(temporalalgebra::MPoint::BasicType());
|
|
}
|
|
break;
|
|
}
|
|
|
|
|
|
if (listutils::isTupleStream(param.fourth().listExpr()))
|
|
{
|
|
ListExpr IndMMData =
|
|
GetMMDataIndexesOfTupleStream(param.fourth().listExpr());
|
|
|
|
if (nl->Equal(IndMMData, nl->TypeError()))
|
|
return IndMMData;
|
|
else
|
|
{
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
|
|
AppendLists(IndNetwAttr, IndMMData),
|
|
ResultType);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
|
|
IndNetwAttr,
|
|
ResultType);
|
|
}
|
|
}
|
|
|
|
ListExpr OpOMapMatchingMHTTypeMap(ListExpr in_xArgs)
|
|
{
|
|
return OpOMapMatchingMHTTypeMap_Common(in_xArgs, OMM_RESULT_EDGES);
|
|
}
|
|
|
|
static ListExpr GetORelNetworkAttrIndexes(ListExpr ORelAttrList)
|
|
{
|
|
ListExpr attrType;
|
|
int nAttrSourceIndex = listutils::findAttribute(
|
|
ORelAttrList, "Source", attrType);
|
|
if (nAttrSourceIndex == 0)
|
|
{
|
|
return listutils::typeError("'Source' not found in attr list");
|
|
}
|
|
else
|
|
{
|
|
if (!CcInt::checkType(attrType) &&
|
|
!LongInt::checkType(attrType) )
|
|
{
|
|
return listutils::typeError(
|
|
"'Source' must be " + CcInt::BasicType()
|
|
+ " or " + LongInt::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrTargetIndex = listutils::findAttribute(
|
|
ORelAttrList, "Target", attrType);
|
|
if (nAttrTargetIndex == 0)
|
|
{
|
|
return listutils::typeError("'Target' not found in attr list");
|
|
}
|
|
else
|
|
{
|
|
if (!CcInt::checkType(attrType) &&
|
|
!LongInt::checkType(attrType))
|
|
{
|
|
return listutils::typeError(
|
|
"'Target' must be " + CcInt::BasicType()
|
|
+ " or " + LongInt::BasicType()) ;
|
|
}
|
|
}
|
|
|
|
int nAttrSourcePosIndex = listutils::findAttribute(
|
|
ORelAttrList, "SourcePos", attrType);
|
|
if (nAttrSourcePosIndex == 0)
|
|
{
|
|
return listutils::typeError("'SourcePos' not found in attr list");
|
|
}
|
|
else
|
|
{
|
|
if (!listutils::isSymbol(attrType, Point::BasicType()))
|
|
{
|
|
return listutils::typeError(
|
|
"'SourcePos' must be " + Point::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrTargetPosIndex = listutils::findAttribute(
|
|
ORelAttrList, "TargetPos", attrType);
|
|
if (nAttrTargetPosIndex == 0)
|
|
{
|
|
return listutils::typeError("'TargetPos' not found in attr list");
|
|
}
|
|
else
|
|
{
|
|
if (!listutils::isSymbol(attrType, Point::BasicType()))
|
|
{
|
|
return listutils::typeError(
|
|
"'TargetPos' must be " + Point::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrCurveIndex = listutils::findAttribute(
|
|
ORelAttrList, "Curve", attrType);
|
|
if (nAttrCurveIndex == 0)
|
|
{
|
|
return listutils::typeError("'Curve' not found in attr list");
|
|
}
|
|
else
|
|
{
|
|
if (!listutils::isSymbol(attrType, SimpleLine::BasicType()))
|
|
{
|
|
return listutils::typeError(
|
|
"'Curve' must be " + SimpleLine::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrRoadNameIndex = listutils::findAttribute(
|
|
ORelAttrList, "RoadName", attrType);
|
|
if (nAttrRoadNameIndex != 0)
|
|
{
|
|
if (!listutils::isSymbol(attrType, FText::BasicType()))
|
|
{
|
|
return listutils::typeError(
|
|
"'RoadName' must be " + FText::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrRoadTypeIndex = listutils::findAttribute(
|
|
ORelAttrList, "RoadType", attrType);
|
|
if (nAttrRoadTypeIndex != 0)
|
|
{
|
|
if (!listutils::isSymbol(attrType, FText::BasicType()))
|
|
{
|
|
return listutils::typeError(
|
|
"'RoadType' must be " + FText::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrMaxSpeedTypeIndex = listutils::findAttribute(
|
|
ORelAttrList, "MaxSpeed", attrType);
|
|
if (nAttrMaxSpeedTypeIndex != 0)
|
|
{
|
|
if (!listutils::isSymbol(attrType, FText::BasicType()))
|
|
{
|
|
return listutils::typeError(
|
|
"'MaxSpeed' must be " + FText::BasicType());
|
|
}
|
|
}
|
|
|
|
int nAttrWayIdTypeIndex = listutils::findAttribute(
|
|
ORelAttrList, "WayId", attrType);
|
|
if (nAttrWayIdTypeIndex == 0)
|
|
{
|
|
return listutils::typeError("'WayId' not found in attr list");
|
|
}
|
|
else
|
|
{
|
|
if (!CcInt::checkType(attrType) &&
|
|
!LongInt::checkType(attrType))
|
|
{
|
|
return listutils::typeError(
|
|
"'WayId' must be " + CcInt::BasicType()
|
|
+ " or " + LongInt::BasicType());
|
|
}
|
|
}
|
|
|
|
--nAttrSourceIndex;
|
|
--nAttrTargetIndex;
|
|
--nAttrSourcePosIndex;
|
|
--nAttrTargetPosIndex;
|
|
--nAttrCurveIndex;
|
|
--nAttrRoadNameIndex;
|
|
--nAttrRoadTypeIndex;
|
|
--nAttrMaxSpeedTypeIndex;
|
|
--nAttrWayIdTypeIndex;
|
|
|
|
ListExpr Ind = nl->OneElemList(nl->IntAtom(nAttrSourceIndex));
|
|
ListExpr Last = Ind;
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrTargetIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrSourcePosIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrTargetPosIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrCurveIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrRoadNameIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrRoadTypeIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrMaxSpeedTypeIndex));
|
|
Last = nl->Append(Last, nl->IntAtom(nAttrWayIdTypeIndex));
|
|
|
|
return Ind;
|
|
}
|
|
|
|
static ListExpr AppendLists(ListExpr List1, ListExpr List2)
|
|
{
|
|
ListExpr ResultList = nl->TheEmptyList();
|
|
ListExpr last = nl->TheEmptyList();
|
|
|
|
ListExpr Lauf = List1;
|
|
|
|
while (!nl->IsEmpty(Lauf))
|
|
{
|
|
ListExpr attr = nl->First(Lauf);
|
|
|
|
if (nl->IsEmpty(ResultList))
|
|
{
|
|
ResultList = nl->OneElemList(attr);
|
|
last = ResultList;
|
|
}
|
|
else
|
|
{
|
|
last = nl->Append(last, attr);
|
|
}
|
|
|
|
Lauf = nl->Rest(Lauf);
|
|
}
|
|
|
|
Lauf = List2;
|
|
|
|
while (!nl->IsEmpty(Lauf))
|
|
{
|
|
ListExpr attr = nl->First(Lauf);
|
|
|
|
if (nl->IsEmpty(ResultList))
|
|
{
|
|
ResultList = nl->OneElemList(attr);
|
|
last = ResultList;
|
|
}
|
|
else
|
|
{
|
|
last = nl->Append(last, attr);
|
|
}
|
|
|
|
Lauf = nl->Rest(Lauf);
|
|
}
|
|
|
|
return ResultList;
|
|
}
|
|
|
|
|
|
/*
|
|
4.3 Value-Mapping
|
|
|
|
*/
|
|
template<class T>
|
|
static typename ONetwork<T>::OEdgeAttrIndexes
|
|
GetOEdgeAttrIndexes(Word* args, int nOffset)
|
|
{
|
|
// s. GetORelNetworkAttrIndexes
|
|
|
|
typename ONetwork<T>::OEdgeAttrIndexes Indexes;
|
|
|
|
const CcInt* pIdxSource = static_cast<CcInt*>(args[nOffset + 0].addr);
|
|
const CcInt* pIdxTarget = static_cast<CcInt*>(args[nOffset + 1].addr);
|
|
const CcInt* pIdxSourcePos = static_cast<CcInt*>(args[nOffset + 2].addr);
|
|
const CcInt* pIdxTargetPos = static_cast<CcInt*>(args[nOffset + 3].addr);
|
|
const CcInt* pIdxCurve = static_cast<CcInt*>(args[nOffset + 4].addr);
|
|
const CcInt* pIdxRoadName = static_cast<CcInt*>(args[nOffset + 5].addr);
|
|
const CcInt* pIdxRoadType = static_cast<CcInt*>(args[nOffset + 6].addr);
|
|
const CcInt* pIdxMaxSpeed = static_cast<CcInt*>(args[nOffset + 7].addr);
|
|
const CcInt* pIdxWayId = static_cast<CcInt*>(args[nOffset + 8].addr);
|
|
|
|
|
|
Indexes.m_IdxSource = pIdxSource->GetValue();
|
|
Indexes.m_IdxTarget = pIdxTarget->GetValue();
|
|
Indexes.m_IdxSourcePos = pIdxSourcePos->GetValue();
|
|
Indexes.m_IdxTargetPos = pIdxTargetPos->GetValue();
|
|
Indexes.m_IdxCurve = pIdxCurve->GetValue();
|
|
Indexes.m_IdxRoadName = pIdxRoadName->GetValue();
|
|
Indexes.m_IdxRoadType = pIdxRoadType->GetValue();
|
|
Indexes.m_IdxMaxSpeed = pIdxMaxSpeed->GetValue();
|
|
Indexes.m_IdxWayId = pIdxWayId->GetValue();
|
|
|
|
if (Indexes.m_IdxSource < 0 || Indexes.m_IdxTarget < 0 ||
|
|
Indexes.m_IdxSourcePos < 0 || Indexes.m_IdxTargetPos < 0 ||
|
|
Indexes.m_IdxCurve < 0 || Indexes.m_IdxWayId < 0)
|
|
{
|
|
assert(false);
|
|
}
|
|
|
|
return Indexes;
|
|
}
|
|
|
|
|
|
template<class T>
|
|
int OpOMapMatchingMHTMPoint2OStreamValueMapping(
|
|
Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier,
|
|
typename OEdgeTupleStreamCreator<T>::EMode eMode)
|
|
{
|
|
// cout << "OpOMapMatchingMHTMPoint2OStreamValueMapping called" << endl;
|
|
|
|
OEdgeTupleStreamCreator<T>* pCreator =
|
|
static_cast<OEdgeTupleStreamCreator<T>*>(local.addr);
|
|
switch (message)
|
|
{
|
|
case OPEN:
|
|
{
|
|
if (pCreator != NULL)
|
|
{
|
|
delete pCreator;
|
|
pCreator = NULL;
|
|
}
|
|
|
|
// get Arguments
|
|
OrderedRelation* pORel = static_cast<OrderedRelation*>(args[0].addr);
|
|
RTree2TID* pRTree = static_cast<RTree2TID*>(args[1].addr);
|
|
Relation* pRelation = static_cast<Relation*>(args[2].addr);
|
|
|
|
typename ONetwork<T>::OEdgeAttrIndexes Indexes =
|
|
GetOEdgeAttrIndexes<T>(args, 4);
|
|
|
|
ONetwork<T> Network(pORel, pRTree, pRelation, Indexes);
|
|
|
|
temporalalgebra::MPoint* pMPoint =
|
|
static_cast<temporalalgebra::MPoint*>(args[3].addr);
|
|
|
|
// Do Map Matching
|
|
|
|
ONetworkAdapter<T> NetworkAdapter(&Network);
|
|
MapMatchingMHT MapMatching(&NetworkAdapter, pMPoint);
|
|
|
|
OEdgeTupleStreamCreator<T>* pCreator =
|
|
new OEdgeTupleStreamCreator<T>(in_xSupplier,
|
|
NetworkAdapter,
|
|
eMode);
|
|
|
|
if (!MapMatching.DoMatch(pCreator))
|
|
{
|
|
// Error
|
|
delete pCreator;
|
|
pCreator = NULL;
|
|
}
|
|
|
|
local.setAddr(pCreator);
|
|
return 0;
|
|
}
|
|
case REQUEST:
|
|
{
|
|
if (pCreator == NULL)
|
|
{
|
|
return CANCEL;
|
|
}
|
|
else
|
|
{
|
|
result.addr = pCreator->GetNextTuple();
|
|
return result.addr ? YIELD : CANCEL;
|
|
}
|
|
}
|
|
case CLOSE:
|
|
{
|
|
if (pCreator)
|
|
{
|
|
delete pCreator;
|
|
local.addr = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
default:
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
int OpOMapMatchingMHTGPX2OStreamValueMapping(
|
|
Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier,
|
|
typename OEdgeTupleStreamCreator<T>::EMode eMode)
|
|
{
|
|
// cout << "OpOMapMatchingMHTGPX2OStreamValueMapping called" << endl;
|
|
|
|
OEdgeTupleStreamCreator<T>* pCreator =
|
|
static_cast<OEdgeTupleStreamCreator<T>*>(local.addr);
|
|
switch (message)
|
|
{
|
|
case OPEN:
|
|
{
|
|
if (pCreator != NULL)
|
|
{
|
|
delete pCreator;
|
|
pCreator = NULL;
|
|
}
|
|
|
|
// get Arguments
|
|
OrderedRelation* pORel = static_cast<OrderedRelation*>(args[0].addr);
|
|
RTree2TID* pRTree = static_cast<RTree2TID*>(args[1].addr);
|
|
Relation* pRelation = static_cast<Relation*>(args[2].addr);
|
|
|
|
typename ONetwork<T>::OEdgeAttrIndexes Indexes =
|
|
GetOEdgeAttrIndexes<T>(args, 4);
|
|
|
|
ONetwork<T> Network(pORel, pRTree, pRelation, Indexes);
|
|
|
|
FText* pFileName = static_cast<FText*>(args[3].addr);
|
|
std::string strFileName = pFileName->GetValue();
|
|
|
|
// Do Map Matching
|
|
|
|
ONetworkAdapter<T> NetworkAdapter(&Network);
|
|
MapMatchingMHT MapMatching(&NetworkAdapter, strFileName);
|
|
|
|
OEdgeTupleStreamCreator<T>* pCreator =
|
|
new OEdgeTupleStreamCreator<T>(in_xSupplier,
|
|
NetworkAdapter,
|
|
eMode);
|
|
|
|
if (!MapMatching.DoMatch(pCreator))
|
|
{
|
|
// Error
|
|
delete pCreator;
|
|
pCreator = NULL;
|
|
}
|
|
|
|
local.setAddr(pCreator);
|
|
return 0;
|
|
}
|
|
case REQUEST:
|
|
{
|
|
if (pCreator == NULL)
|
|
{
|
|
return CANCEL;
|
|
}
|
|
else
|
|
{
|
|
result.addr = pCreator->GetNextTuple();
|
|
return result.addr ? YIELD : CANCEL;
|
|
}
|
|
}
|
|
case CLOSE:
|
|
{
|
|
if (pCreator)
|
|
{
|
|
delete pCreator;
|
|
local.addr = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
default:
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
int OpOMapMatchingMHTStream2OStreamValueMapping(
|
|
Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier,
|
|
typename OEdgeTupleStreamCreator<T>::EMode eMode)
|
|
{
|
|
// cout << "OpOMapMatchingMHTStream2OStreamValueMapping called" << endl;
|
|
|
|
OEdgeTupleStreamCreator<T>* pCreator =
|
|
static_cast<OEdgeTupleStreamCreator<T>*>(local.addr);
|
|
switch (message)
|
|
{
|
|
case OPEN:
|
|
{
|
|
if (pCreator != NULL)
|
|
{
|
|
delete pCreator;
|
|
pCreator = NULL;
|
|
}
|
|
|
|
// get Arguments
|
|
OrderedRelation* pORel = static_cast<OrderedRelation*>(args[0].addr);
|
|
RTree2TID* pRTree = static_cast<RTree2TID*>(args[1].addr);
|
|
Relation* pRelation = static_cast<Relation*>(args[2].addr);
|
|
|
|
typename ONetwork<T>::OEdgeAttrIndexes Indexes =
|
|
GetOEdgeAttrIndexes<T>(args, 4);
|
|
|
|
ONetwork<T> Network(pORel, pRTree, pRelation, Indexes);
|
|
|
|
shared_ptr<MapMatchDataContainer> pContData = // 9 OEdge-Attr-Indexes
|
|
GetMMDataFromTupleStream(args[3].addr, args, 4 + 9);
|
|
|
|
// Do Map Matching
|
|
|
|
ONetworkAdapter<T> NetworkAdapter(&Network);
|
|
MapMatchingMHT MapMatching(&NetworkAdapter, pContData);
|
|
|
|
OEdgeTupleStreamCreator<T>* pCreator =
|
|
new OEdgeTupleStreamCreator<T>(in_xSupplier,
|
|
NetworkAdapter,
|
|
eMode);
|
|
|
|
if (!MapMatching.DoMatch(pCreator))
|
|
{
|
|
// Error
|
|
delete pCreator;
|
|
pCreator = NULL;
|
|
}
|
|
|
|
local.setAddr(pCreator);
|
|
return 0;
|
|
}
|
|
case REQUEST:
|
|
{
|
|
if (pCreator == NULL)
|
|
{
|
|
return CANCEL;
|
|
}
|
|
else
|
|
{
|
|
result.addr = pCreator->GetNextTuple();
|
|
return result.addr ? YIELD : CANCEL;
|
|
}
|
|
}
|
|
case CLOSE:
|
|
{
|
|
if (pCreator)
|
|
{
|
|
delete pCreator;
|
|
local.addr = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
default:
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
template<class T>
|
|
int OpOMapMatchingMHTMPoint2EdgesValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
return OpOMapMatchingMHTMPoint2OStreamValueMapping<T>(
|
|
args,
|
|
result,
|
|
message,
|
|
local,
|
|
in_xSupplier,
|
|
OEdgeTupleStreamCreator<T>::MODE_EDGES );
|
|
}
|
|
|
|
template<class T>
|
|
int OpOMapMatchingMHTGPX2EdgesValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
return OpOMapMatchingMHTGPX2OStreamValueMapping<T>(
|
|
args,
|
|
result,
|
|
message,
|
|
local,
|
|
in_xSupplier,
|
|
OEdgeTupleStreamCreator<T>::MODE_EDGES);
|
|
}
|
|
|
|
template<class T>
|
|
int OpOMapMatchingMHTStream2EdgesValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
return OpOMapMatchingMHTStream2OStreamValueMapping<T>(
|
|
args,
|
|
result,
|
|
message,
|
|
local,
|
|
in_xSupplier,
|
|
OEdgeTupleStreamCreator<T>::MODE_EDGES);
|
|
}
|
|
|
|
|
|
/*
|
|
4.4 Selection Function
|
|
|
|
*/
|
|
int OMapMatchMHTSelect(ListExpr args)
|
|
{
|
|
NList type(args);
|
|
if (type.length() == 4 &&
|
|
listutils::isOrelDescription(type.first().listExpr()) &&
|
|
listutils::isRTreeDescription(type.second().listExpr()) &&
|
|
listutils::isRelDescription(type.third().listExpr()))
|
|
{
|
|
ListExpr attrList = nl->Second(nl->Second(nl->First(args)));
|
|
ListExpr attrType;
|
|
listutils::findAttribute(attrList,"Source",attrType);
|
|
int offset = CcInt::checkType(attrType)?0:3;
|
|
|
|
if (type.fourth().isSymbol(temporalalgebra::MPoint::BasicType()))
|
|
{
|
|
return 0 + offset;
|
|
}
|
|
else if (type.fourth().isSymbol(FText::BasicType()))
|
|
{
|
|
return 1 + offset;
|
|
}
|
|
else if (listutils::isTupleStream(type.fourth().listExpr()))
|
|
{
|
|
return 2 + offset;
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1 jmapmatchmht-operator
|
|
|
|
1.1 Operator-Info
|
|
|
|
*/
|
|
|
|
struct JMapMatchMHTInfo : OperatorInfo
|
|
{
|
|
|
|
JMapMatchMHTInfo()
|
|
{
|
|
name = "jmapmatchmht";
|
|
signature = JNetwork::BasicType() + " x " +
|
|
temporalalgebra::MPoint::BasicType() + " -> " +
|
|
MJPoint::BasicType();
|
|
|
|
appendSignature(JNetwork::BasicType() + " x " +
|
|
FText::BasicType() + " -> " +
|
|
MJPoint::BasicType());
|
|
|
|
appendSignature(JNetwork::BasicType() + " x " +
|
|
"(stream (tuple([Lat:real, Lon:real, Time:DateTime "
|
|
"[,Fix:int] [,Sat:int] [,Hdop : real]"
|
|
"[,Vdop:real] [,Pdop:real] "
|
|
"[,Course:real] [,Speed(m/s):real]])))"
|
|
+ " -> " +
|
|
MJPoint::BasicType());
|
|
|
|
syntax = "jmapmatchmht ( _ , _ )";
|
|
meaning = "The operation maps the MPoint or "
|
|
"the data of a gpx-file or "
|
|
"the data of a tuple stream "
|
|
"to the given jnetwork."
|
|
"Result is a MJPoint.";
|
|
example = "jmapmatchmht (DortmundJNet, 'Trk_Dortmund.gpx')";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
1.1 Type-Mapping
|
|
|
|
*/
|
|
|
|
ListExpr OpJMapMatchingMHTTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if(param.length() != 2)
|
|
return listutils::typeError("two arguments expected");
|
|
|
|
if (!param.first().isSymbol(JNetwork::BasicType()))
|
|
return listutils::typeError("1st argument must be " +
|
|
JNetwork::BasicType());
|
|
|
|
if (!param.second().isSymbol(temporalalgebra::MPoint::BasicType()) &&
|
|
!param.second().isSymbol(FText::BasicType()) &&
|
|
!listutils::isTupleStream(param.second().listExpr()))
|
|
{
|
|
return listutils::typeError("2nd argument must be " +
|
|
temporalalgebra::MPoint::BasicType()
|
|
+ " or " +
|
|
FText::BasicType() + " or " +
|
|
"tuple stream");
|
|
}
|
|
|
|
if (listutils::isTupleStream(param.second().listExpr()))
|
|
{
|
|
ListExpr Ind = GetMMDataIndexesOfTupleStream(param.second().listExpr());
|
|
|
|
if(nl->Equal(Ind,nl->TypeError()))
|
|
return Ind;
|
|
else
|
|
{
|
|
// Add indexes
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
|
|
Ind,
|
|
nl->SymbolAtom(MJPoint::BasicType()));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return nl->SymbolAtom(MJPoint::BasicType());
|
|
}
|
|
}
|
|
|
|
/*
|
|
3.3 Value-Mapping
|
|
|
|
*/
|
|
|
|
int OpJMapMatchingMHTMPointValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
//cout << "OpJMapMatchingMHTMPointValueMapping called" << endl;
|
|
|
|
// cout << "Initialize Result" << endl;
|
|
result = qp->ResultStorage(in_xSupplier);
|
|
MJPoint* pRes = static_cast<MJPoint*>(result.addr);
|
|
|
|
//cout << "get Arguments" << endl;
|
|
JNetwork *pNetwork = static_cast<JNetwork*>(args[0].addr);
|
|
temporalalgebra::MPoint *pMPoint =
|
|
static_cast<temporalalgebra::MPoint*>(args[1].addr);
|
|
|
|
//cout << "Do Map Matching" << endl;
|
|
|
|
JNetworkAdapter jnet(pNetwork);
|
|
MapMatchingMHT MapMatching(&jnet, pMPoint);
|
|
|
|
MJPointCreator Creator(&jnet, pRes);
|
|
|
|
if (!MapMatching.DoMatch(&Creator))
|
|
{
|
|
assert(false);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int OpJMapMatchingMHTGPXValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
//cout << "OpJMapMatchingMHTGPXValueMapping called" << endl;
|
|
// Initialize Result
|
|
result = qp->ResultStorage(in_xSupplier);
|
|
MJPoint* pRes = static_cast<MJPoint*>(result.addr);
|
|
|
|
// get Arguments
|
|
JNetwork* pNetwork = static_cast<JNetwork*>(args[0].addr);
|
|
FText* pFileName = static_cast<FText*>(args[1].addr);
|
|
std::string strFileName = pFileName->GetValue();
|
|
|
|
// Do Map Matching
|
|
|
|
JNetworkAdapter jnet(pNetwork);
|
|
MapMatchingMHT MapMatching(&jnet, strFileName);
|
|
|
|
MJPointCreator Creator(&jnet, pRes);
|
|
|
|
if (!MapMatching.DoMatch(&Creator))
|
|
{
|
|
assert(false);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int OpJMapMatchingMHTStreamValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
//cout << "OpJMapMatchingMHTStreamValueMapping called" << endl;
|
|
|
|
//cout << "Initialize Result" << endl;
|
|
result = qp->ResultStorage(in_xSupplier);
|
|
MJPoint* pRes = static_cast<MJPoint*>(result.addr);
|
|
|
|
//cout << " get Arguments " << endl;
|
|
JNetwork* pNetwork = static_cast<JNetwork*>(args[0].addr);
|
|
|
|
shared_ptr<MapMatchDataContainer> pContData =
|
|
GetMMDataFromTupleStream(args[1].addr, args, 2);
|
|
|
|
//cout << " Matching" << endl;
|
|
|
|
JNetworkAdapter jnet(pNetwork);
|
|
MapMatchingMHT MapMatching(&jnet, pContData);
|
|
|
|
MJPointCreator Creator(&jnet, pRes);
|
|
|
|
if (!MapMatching.DoMatch(&Creator))
|
|
{
|
|
assert(false);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
3.4 Selection Function
|
|
|
|
*/
|
|
|
|
int JMapMatchMHTSelect(ListExpr args)
|
|
{
|
|
NList type(args);
|
|
if ((type.length() == 2) &&
|
|
type.first().isSymbol(JNetwork::BasicType()))
|
|
{
|
|
if (type.second().isSymbol(temporalalgebra::MPoint::BasicType())) return 0;
|
|
if (type.second().isSymbol(FText::BasicType())) return 1;
|
|
if (listutils::isTupleStream(type.second().listExpr())) return 2;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
5 omapmatchmht\_P-operator
|
|
|
|
5.1 Operator-Info
|
|
map matching with an ordered relation
|
|
Result: Tuples of matched points on edges
|
|
|
|
*/
|
|
|
|
struct OMapMatchMHT_PInfo : OperatorInfo
|
|
{
|
|
|
|
OMapMatchMHT_PInfo()
|
|
{
|
|
name = "omapmatchmht_p";
|
|
signature = OrderedRelation::BasicType() + " x " +
|
|
RTree2TID::BasicType() + " x " +
|
|
Relation::BasicType() + " x " +
|
|
temporalalgebra::MPoint::BasicType() + " -> " +
|
|
"stream(tuple([<attributes of tuple of edge>,"
|
|
"StartTime:DateTime, EndTime:DateTime,"
|
|
"StartPos:Point, EndPos:Point,"
|
|
"StartLength:real, EndPos:real]))";
|
|
|
|
appendSignature(OrderedRelation::BasicType() + " x " +
|
|
RTree2TID::BasicType() + " x " +
|
|
Relation::BasicType() + " x " +
|
|
FText::BasicType() + " -> " +
|
|
"stream(tuple([<attributes of tuple of edge>,"
|
|
"StartTime:DateTime, EndTime:DateTime,"
|
|
"StartPos:Point, EndPos:Point,"
|
|
"StartLength:real, EndPos:real]))");
|
|
|
|
appendSignature(OrderedRelation::BasicType() + " x " +
|
|
RTree2TID::BasicType() + " x " +
|
|
Relation::BasicType() + " x " +
|
|
"(stream (tuple([Lat:real, Lon:real, Time:DateTime "
|
|
"[,Fix:int] [,Sat:int] [,Hdop : real]"
|
|
"[,Vdop:real] [,Pdop:real] "
|
|
"[,Course:real] [,Speed(m/s):real]])))"
|
|
+ " -> " +
|
|
"stream(tuple([<attributes of tuple of edge>,"
|
|
"StartTime:DateTime, EndTime:DateTime,"
|
|
"StartPos:Point, EndPos:Point,"
|
|
"StartLength:real, EndPos:real]))");
|
|
|
|
|
|
syntax = "omapmatchmht_p ( _ , _ , _ , _ )";
|
|
meaning = "The operation maps the MPoint or "
|
|
"the data of a gpx-file or "
|
|
"the data of a tuple stream "
|
|
"to the given network, which is based on an "
|
|
"ordered relation."
|
|
"Result is a stream of tuples with the matched edges "
|
|
"of the network with timestamps, and matched positions.";
|
|
example = "omapmatchmht_p(Edges, EdgeIndex_Box_rtree, "
|
|
"EdgeIndex, 'Trk_Dortmund.gpx')";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
5.2 Type-Mapping
|
|
|
|
*/
|
|
|
|
ListExpr OpOMapMatchingMHT_PTypeMap(ListExpr in_xArgs)
|
|
{
|
|
return OpOMapMatchingMHTTypeMap_Common(in_xArgs,
|
|
OMM_RESULT_POSITIONS_ON_EDGES);
|
|
}
|
|
|
|
|
|
/*
|
|
5.3 Value-Mapping
|
|
|
|
*/
|
|
|
|
template<class T>
|
|
int OpOMapMatchingMHTMPoint2PositionsValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// cout << "OpOMapMatchingMHTMPoint2PositionsValueMapping called" << endl;
|
|
|
|
return OpOMapMatchingMHTMPoint2OStreamValueMapping<T>(
|
|
args,
|
|
result,
|
|
message,
|
|
local,
|
|
in_xSupplier,
|
|
OEdgeTupleStreamCreator<T>::MODE_EDGES_AND_POSITIONS);
|
|
}
|
|
|
|
template<class T>
|
|
int OpOMapMatchingMHTGPX2PositionsValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// cout << "OpOMapMatchingMHTGPX2PositionsValueMapping called" << endl;
|
|
|
|
return OpOMapMatchingMHTGPX2OStreamValueMapping<T>(
|
|
args,
|
|
result,
|
|
message,
|
|
local,
|
|
in_xSupplier,
|
|
OEdgeTupleStreamCreator<T>::MODE_EDGES_AND_POSITIONS);
|
|
}
|
|
|
|
template<class T>
|
|
int OpOMapMatchingMHTStream2PositionsValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// cout << "OpOMapMatchingMHTStream2PositionsValueMapping called" << endl;
|
|
|
|
return OpOMapMatchingMHTStream2OStreamValueMapping<T>(
|
|
args,
|
|
result,
|
|
message,
|
|
local,
|
|
in_xSupplier,
|
|
OEdgeTupleStreamCreator<T>::MODE_EDGES_AND_POSITIONS);
|
|
}
|
|
|
|
|
|
/*
|
|
5.4 Selection Function
|
|
|
|
*/
|
|
int OMapMatchMHT_PSelect(ListExpr args)
|
|
{
|
|
return OMapMatchMHTSelect(args);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
6 omapmatchmht\_mpoint-operator
|
|
|
|
6.1 Operator-Info
|
|
map matching with an ordered relation
|
|
result is a mpoint
|
|
|
|
*/
|
|
struct OMapMatchMHT_MPointInfo : OperatorInfo
|
|
{
|
|
|
|
OMapMatchMHT_MPointInfo()
|
|
{
|
|
name = "omapmatchmht_mpoint";
|
|
signature = OrderedRelation::BasicType() + " x " +
|
|
RTree2TID::BasicType() + " x " +
|
|
Relation::BasicType() + " x " +
|
|
temporalalgebra::MPoint::BasicType() + " -> " +
|
|
temporalalgebra::MPoint::BasicType();
|
|
|
|
appendSignature(OrderedRelation::BasicType() + " x " +
|
|
RTree2TID::BasicType() + " x " +
|
|
Relation::BasicType() + " x " +
|
|
FText::BasicType() + " -> " +
|
|
temporalalgebra::MPoint::BasicType());
|
|
|
|
appendSignature(OrderedRelation::BasicType() + " x " +
|
|
RTree2TID::BasicType() + " x " +
|
|
Relation::BasicType() + " x " +
|
|
"(stream (tuple([Lat:real, Lon:real, Time:DateTime "
|
|
"[,Fix:int] [,Sat:int] [,Hdop : real]"
|
|
"[,Vdop:real] [,Pdop:real] "
|
|
"[,Course:real] [,Speed(m/s):real]])))"
|
|
+ " -> " +
|
|
temporalalgebra::MPoint::BasicType());
|
|
|
|
|
|
syntax = "omapmatchmht_mpoint ( _ , _ , _ , _ )";
|
|
meaning = "The operation maps the MPoint or "
|
|
"the data of a gpx-file or "
|
|
"the data of a tuple stream "
|
|
"to the given network, which is based on an "
|
|
"ordered relation."
|
|
"Result is a MPoint.";
|
|
example = "omapmatchmht_mpoint(Edges, EdgeIndex_Box_rtree, "
|
|
"EdgeIndex, 'Trk_Dortmund.gpx')";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
6.2 Type-Mapping
|
|
|
|
*/
|
|
|
|
ListExpr OpOMapMatchingMHT_MPointTypeMap(ListExpr in_xArgs)
|
|
{
|
|
return OpOMapMatchingMHTTypeMap_Common(in_xArgs, OMM_RESULT_MPOINT);
|
|
}
|
|
|
|
|
|
/*
|
|
6.3 Value-Mapping
|
|
|
|
*/
|
|
|
|
template<class T>
|
|
int OpOMapMatchingMHTMPoint2MPointValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// cout << "OpOMapMatchingMHTMPoint2MPointValueMapping called" << endl;
|
|
|
|
// Initialize Result
|
|
result = qp->ResultStorage(in_xSupplier);
|
|
temporalalgebra::MPoint* pRes =
|
|
static_cast<temporalalgebra::MPoint*>(result.addr);
|
|
|
|
// get Arguments
|
|
OrderedRelation* pORel = static_cast<OrderedRelation*>(args[0].addr);
|
|
RTree2TID* pRTree = static_cast<RTree2TID*>(args[1].addr);
|
|
Relation* pRelation = static_cast<Relation*>(args[2].addr);
|
|
|
|
typename ONetwork<T>::OEdgeAttrIndexes Indexes =
|
|
GetOEdgeAttrIndexes<T>(args, 4);
|
|
|
|
ONetwork<T> Network(pORel, pRTree, pRelation, Indexes);
|
|
|
|
temporalalgebra::MPoint *pMPoint =
|
|
static_cast<temporalalgebra::MPoint*>(args[3].addr);
|
|
|
|
// Matching
|
|
|
|
ONetworkAdapter<T> NetworkAdapter(&Network);
|
|
MapMatchingMHT MapMatching(&NetworkAdapter, pMPoint);
|
|
|
|
MPointCreator Creator(pRes,
|
|
NetworkAdapter.GetNetworkScale());
|
|
|
|
if (!MapMatching.DoMatch(&Creator))
|
|
{
|
|
// Error
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
template<class T>
|
|
int OpOMapMatchingMHTGPX2MPointValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// cout << "OpOMapMatchingMHTStream2MPointValueMapping called" << endl;
|
|
|
|
// Initialize Result
|
|
result = qp->ResultStorage(in_xSupplier);
|
|
temporalalgebra::MPoint* pRes =
|
|
static_cast<temporalalgebra::MPoint*>(result.addr);
|
|
|
|
// get Arguments
|
|
OrderedRelation* pORel = static_cast<OrderedRelation*>(args[0].addr);
|
|
RTree2TID* pRTree = static_cast<RTree2TID*>(args[1].addr);
|
|
Relation* pRelation = static_cast<Relation*>(args[2].addr);
|
|
|
|
typename ONetwork<T>::OEdgeAttrIndexes Indexes =
|
|
GetOEdgeAttrIndexes<T>(args, 4);
|
|
|
|
ONetwork<T> Network(pORel, pRTree, pRelation, Indexes);
|
|
|
|
FText* pFileName = static_cast<FText*>(args[3].addr);
|
|
std::string strFileName = pFileName->GetValue();
|
|
|
|
// Matching
|
|
|
|
ONetworkAdapter<T> NetworkAdapter(&Network);
|
|
MapMatchingMHT MapMatching(&NetworkAdapter, strFileName);
|
|
|
|
MPointCreator Creator(pRes, NetworkAdapter.GetNetworkScale());
|
|
|
|
if (!MapMatching.DoMatch(&Creator))
|
|
{
|
|
// Error
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
template<class T>
|
|
int OpOMapMatchingMHTStream2MPointValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// cout << "OpOMapMatchingMHTStream2MPointValueMapping called" << endl;
|
|
|
|
// Initialize Result
|
|
result = qp->ResultStorage(in_xSupplier);
|
|
temporalalgebra::MPoint* pRes =
|
|
static_cast<temporalalgebra::MPoint*>(result.addr);
|
|
|
|
// get Arguments
|
|
OrderedRelation* pORel = static_cast<OrderedRelation*>(args[0].addr);
|
|
RTree2TID* pRTree = static_cast<RTree2TID*>(args[1].addr);
|
|
Relation* pRelation = static_cast<Relation*>(args[2].addr);
|
|
|
|
typename ONetwork<T>::OEdgeAttrIndexes Indexes =
|
|
GetOEdgeAttrIndexes<T>(args, 4);
|
|
|
|
ONetwork<T> Network(pORel, pRTree, pRelation, Indexes);
|
|
|
|
shared_ptr<MapMatchDataContainer> pContData = // 9 OEdge-Attr-Indexes
|
|
GetMMDataFromTupleStream(args[3].addr, args, 4 + 9);
|
|
|
|
// Matching
|
|
|
|
ONetworkAdapter<T> NetworkAdapter(&Network);
|
|
MapMatchingMHT MapMatching(&NetworkAdapter, pContData);
|
|
|
|
MPointCreator Creator(pRes, NetworkAdapter.GetNetworkScale());
|
|
|
|
if (!MapMatching.DoMatch(&Creator))
|
|
{
|
|
// Error
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
6.4 Selection Function
|
|
|
|
*/
|
|
int OMapMatchMHT_MPointSelect(ListExpr args)
|
|
{
|
|
return OMapMatchMHTSelect(args);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
7 gpximport-operator
|
|
|
|
7.1 Operator-Info
|
|
|
|
*/
|
|
struct GPXImportInfo : OperatorInfo
|
|
{
|
|
GPXImportInfo()
|
|
{
|
|
name = "gpximport";
|
|
signature = FText::BasicType() + " -> " +
|
|
"stream(tuple([Time: DateTime, Lat: CcReal, Lon: CcReal, "
|
|
"Fix: CcInt, Sat: CcInt, Hdop: CcReal, "
|
|
"Vdop: CcReal, Pdop: CcReal, Course: CcReal, "
|
|
"Speed: CcReal]))";
|
|
|
|
appendSignature(FText::BasicType() + " X " +
|
|
CcReal::BasicType() + " -> " +
|
|
"stream(tuple([Time: DateTime, Lat: CcReal, "
|
|
"Lon: CcReal, Fix: CcInt, Sat: CcInt, Hdop: CcReal, "
|
|
"Vdop: CcReal, Pdop: CcReal, Course: CcReal, "
|
|
"Speed: CcReal]))");
|
|
|
|
syntax = "gpximport ( _ [, _ ] )";
|
|
meaning = "Imports the trackpoint data of a gpx file."
|
|
"With the optional parameter (CcReal) a scaling factor "
|
|
"for the coordinates (Lat, Lon) can be specified.";
|
|
example = "gpximport ('Trk_Dortmund.gpx')";
|
|
}
|
|
};
|
|
|
|
/*
|
|
7.2 Type-Mapping
|
|
|
|
*/
|
|
|
|
ListExpr OpGPXImportTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if( (param.length() !=1) && (param.length()!=2))
|
|
return listutils::typeError("one or two arguments expected");
|
|
|
|
if (!param.first().isSymbol(FText::BasicType()))
|
|
return listutils::typeError("1st argument must be " +
|
|
FText::BasicType());
|
|
|
|
if (param.length() == 2 && !param.second().isSymbol(CcReal::BasicType()))
|
|
return listutils::typeError("2nd argument must be " +
|
|
CcReal::BasicType());
|
|
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
GPXImporter::GetTupleTypeTrkPtListExpr());
|
|
}
|
|
|
|
/*
|
|
7.3 Value-Mapping
|
|
|
|
*/
|
|
|
|
int OpGPXImportValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
GPXImporter* pImporter = static_cast<GPXImporter*>(local.addr);
|
|
switch (message)
|
|
{
|
|
case OPEN:
|
|
{
|
|
FText* pFileName = static_cast<FText*>(args[0].addr);
|
|
if (pImporter != NULL)
|
|
{
|
|
delete pImporter;
|
|
pImporter = NULL;
|
|
}
|
|
|
|
std::string strFileName = pFileName->GetValue();
|
|
|
|
pImporter = new GPXImporter(strFileName);
|
|
|
|
local.setAddr(pImporter);
|
|
return 0;
|
|
}
|
|
case REQUEST:
|
|
{
|
|
if (pImporter == NULL)
|
|
{
|
|
return CANCEL;
|
|
}
|
|
else
|
|
{
|
|
result.addr = pImporter->GetNextTrkPt();
|
|
return result.addr ? YIELD : CANCEL;
|
|
}
|
|
}
|
|
case CLOSE:
|
|
{
|
|
if (pImporter)
|
|
{
|
|
delete pImporter;
|
|
local.addr = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
default:
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
int OpGPXImportValueMappingWithScale(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
|
|
int nRet = OpGPXImportValueMapping(args, result, message,
|
|
local, in_xSupplier);
|
|
|
|
if (message == OPEN)
|
|
{
|
|
GPXImporter* pImporter = static_cast<GPXImporter*>(local.addr);
|
|
if (pImporter != NULL)
|
|
{
|
|
CcReal* pScale = static_cast<CcReal*>(args[1].addr);
|
|
pImporter->SetScaleFactor((pScale != NULL && pScale->IsDefined()) ?
|
|
pScale->GetValue() : 1.0);
|
|
}
|
|
else
|
|
{
|
|
assert(false);
|
|
}
|
|
}
|
|
|
|
return nRet;
|
|
}
|
|
|
|
/*
|
|
7.4 Selection Function
|
|
|
|
*/
|
|
|
|
int GPXImportSelect(ListExpr args)
|
|
{
|
|
NList type(args);
|
|
if (type.length() == 1)
|
|
{
|
|
return 0;
|
|
}
|
|
else if (type.length() == 2)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
8 Implementation of the MapMatchingAlgebra Class
|
|
|
|
*/
|
|
|
|
MapMatchingAlgebra::MapMatchingAlgebra()
|
|
:Algebra()
|
|
{
|
|
|
|
/*
|
|
8.1 Registration of Types
|
|
|
|
*/
|
|
|
|
|
|
/*
|
|
8.2 Registration of Operators
|
|
|
|
*/
|
|
//JMapMatchMHT
|
|
ValueMapping JMapMatchMHTFuns[] = {OpJMapMatchingMHTMPointValueMapping,
|
|
OpJMapMatchingMHTGPXValueMapping,
|
|
OpJMapMatchingMHTStreamValueMapping,
|
|
0
|
|
};
|
|
|
|
AddOperator(JMapMatchMHTInfo(),
|
|
JMapMatchMHTFuns,
|
|
JMapMatchMHTSelect,
|
|
OpJMapMatchingMHTTypeMap);
|
|
|
|
|
|
// MapMatchMHT
|
|
ValueMapping MapMatchMHTFuns[] = { OpMapMatchingMHTMPointValueMapping,
|
|
OpMapMatchingMHTGPXValueMapping,
|
|
OpMapMatchingMHTStreamValueMapping,
|
|
0 };
|
|
|
|
AddOperator(MapMatchMHTInfo(),
|
|
MapMatchMHTFuns,
|
|
MapMatchMHTSelect,
|
|
OpMapMatchingMHTTypeMap);
|
|
|
|
// OMapMatchMHT
|
|
ValueMapping OMapMatchMHTFuns[] =
|
|
{ OpOMapMatchingMHTMPoint2EdgesValueMapping<CcInt>,
|
|
OpOMapMatchingMHTGPX2EdgesValueMapping<CcInt>,
|
|
OpOMapMatchingMHTStream2EdgesValueMapping<CcInt>,
|
|
OpOMapMatchingMHTMPoint2EdgesValueMapping<LongInt>,
|
|
OpOMapMatchingMHTGPX2EdgesValueMapping<LongInt>,
|
|
OpOMapMatchingMHTStream2EdgesValueMapping<LongInt>,
|
|
0 };
|
|
|
|
AddOperator(OMapMatchMHTInfo(),
|
|
OMapMatchMHTFuns,
|
|
OMapMatchMHTSelect,
|
|
OpOMapMatchingMHTTypeMap);
|
|
|
|
// OMapMatchMHT_P
|
|
ValueMapping OMapMatchMHT_PFuns[] =
|
|
{ OpOMapMatchingMHTMPoint2PositionsValueMapping<CcInt>,
|
|
OpOMapMatchingMHTGPX2PositionsValueMapping<CcInt>,
|
|
OpOMapMatchingMHTStream2PositionsValueMapping<CcInt>,
|
|
OpOMapMatchingMHTMPoint2PositionsValueMapping<LongInt>,
|
|
OpOMapMatchingMHTGPX2PositionsValueMapping<LongInt>,
|
|
OpOMapMatchingMHTStream2PositionsValueMapping<LongInt>,
|
|
0 };
|
|
|
|
AddOperator(OMapMatchMHT_PInfo(),
|
|
OMapMatchMHT_PFuns,
|
|
OMapMatchMHT_PSelect,
|
|
OpOMapMatchingMHT_PTypeMap);
|
|
|
|
// OMapMatchMHT_MPoint
|
|
ValueMapping OMapMatchMHT_MPointFuns[] = {
|
|
OpOMapMatchingMHTMPoint2MPointValueMapping<CcInt>,
|
|
OpOMapMatchingMHTGPX2MPointValueMapping<CcInt>,
|
|
OpOMapMatchingMHTStream2MPointValueMapping<CcInt>,
|
|
OpOMapMatchingMHTMPoint2MPointValueMapping<LongInt>,
|
|
OpOMapMatchingMHTGPX2MPointValueMapping<LongInt>,
|
|
OpOMapMatchingMHTStream2MPointValueMapping<LongInt>,
|
|
0 };
|
|
|
|
AddOperator(OMapMatchMHT_MPointInfo(),
|
|
OMapMatchMHT_MPointFuns,
|
|
OMapMatchMHT_MPointSelect,
|
|
OpOMapMatchingMHT_MPointTypeMap);
|
|
|
|
// GPXImport
|
|
ValueMapping GPXImportFuns[] = { OpGPXImportValueMapping,
|
|
OpGPXImportValueMappingWithScale,
|
|
0 };
|
|
|
|
AddOperator(GPXImportInfo(),
|
|
GPXImportFuns,
|
|
GPXImportSelect,
|
|
OpGPXImportTypeMap);
|
|
}
|
|
|
|
MapMatchingAlgebra::~MapMatchingAlgebra()
|
|
{
|
|
}
|
|
|
|
} // end of namespace ~mapmatch~
|
|
|
|
|
|
/*
|
|
8 Initialization
|
|
|
|
*/
|
|
|
|
extern "C" Algebra* InitializeMapMatchingAlgebra(NestedList* /*nlRef*/,
|
|
QueryProcessor* /*qpRef*/)
|
|
{
|
|
return new mapmatch::MapMatchingAlgebra;
|
|
}
|
|
|