/* ---- 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 #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(result.addr); // get Arguments Network *pNetwork = static_cast(args[0].addr); temporalalgebra::MPoint *pMPoint = static_cast(args[1].addr); CcReal *pNetworkScale = static_cast(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(result.addr); // get Arguments Network* pNetwork = static_cast(args[0].addr); FText* pFileName = static_cast(args[1].addr); std::string strFileName = pFileName->GetValue(); CcReal *pNetworkScale = static_cast(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 GetMMDataFromTupleStream( Supplier Stream, Word* args, int nOffset) { //cout << "Get Data from Tuple Stream" << endl; // see also GetMMDataIndexesOfTupleStream shared_ptr pContData(new MapMatchDataContainer); const CcInt* pIdxLat = static_cast(args[nOffset + 0].addr); const CcInt* pIdxLon = static_cast(args[nOffset + 1].addr); const CcInt* pIdxTime = static_cast(args[nOffset + 2].addr); const CcInt* pIdxFix = static_cast(args[nOffset + 3].addr); const CcInt* pIdxSat = static_cast(args[nOffset + 4].addr); const CcInt* pIdxHdop = static_cast(args[nOffset + 5].addr); const CcInt* pIdxVdop = static_cast(args[nOffset + 6].addr); const CcInt* pIdxPdop = static_cast(args[nOffset + 7].addr); const CcInt* pIdxCourse = static_cast(args[nOffset + 8].addr); const CcInt* pIdxSpeed = static_cast(args[nOffset + 9].addr); //const CcInt* pIdxEle = static_cast(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(pTpl->GetAttribute(nIdxLat)); CcReal* pLon = static_cast(pTpl->GetAttribute(nIdxLon)); DateTime* pTime = static_cast(pTpl->GetAttribute(nIdxTime)); CcInt* pFix = NULL; if (nIdxFix >= 0) pFix = static_cast(pTpl->GetAttribute(nIdxFix)); CcInt* pSat = NULL; if (nIdxSat >= 0) pSat = static_cast(pTpl->GetAttribute(nIdxSat)); CcReal* pHdop = NULL; if (nIdxHdop >= 0) pHdop = static_cast(pTpl->GetAttribute(nIdxHdop)); CcReal* pVdop = NULL; if (nIdxVdop >= 0) pVdop = static_cast(pTpl->GetAttribute(nIdxVdop)); CcReal* pPdop = NULL; if (nIdxPdop >= 0) pPdop = static_cast(pTpl->GetAttribute(nIdxPdop)); CcReal* pCourse = NULL; if (nIdxCourse >= 0) pCourse = static_cast(pTpl->GetAttribute(nIdxCourse)); CcReal* pSpeed = NULL; if (nIdxSpeed >= 0) pSpeed = static_cast(pTpl->GetAttribute(nIdxSpeed)); /*CcReal* pEle = NULL; if (nIdxEle >= 0) pEle = static_cast(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(result.addr); // get Arguments Network* pNetwork = static_cast(args[0].addr); shared_ptr pContData = GetMMDataFromTupleStream(args[1].addr, args, 3); CcReal *pNetworkScale = static_cast(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([," "StartTime:DateTime, EndTime:DateTime]))"; appendSignature(OrderedRelation::BasicType() + " x " + RTree2TID::BasicType() + " x " + Relation::BasicType() + " x " + FText::BasicType() + " -> " + "stream(tuple([," "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([," "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 static typename ONetwork::OEdgeAttrIndexes GetOEdgeAttrIndexes(Word* args, int nOffset) { // s. GetORelNetworkAttrIndexes typename ONetwork::OEdgeAttrIndexes Indexes; const CcInt* pIdxSource = static_cast(args[nOffset + 0].addr); const CcInt* pIdxTarget = static_cast(args[nOffset + 1].addr); const CcInt* pIdxSourcePos = static_cast(args[nOffset + 2].addr); const CcInt* pIdxTargetPos = static_cast(args[nOffset + 3].addr); const CcInt* pIdxCurve = static_cast(args[nOffset + 4].addr); const CcInt* pIdxRoadName = static_cast(args[nOffset + 5].addr); const CcInt* pIdxRoadType = static_cast(args[nOffset + 6].addr); const CcInt* pIdxMaxSpeed = static_cast(args[nOffset + 7].addr); const CcInt* pIdxWayId = static_cast(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 int OpOMapMatchingMHTMPoint2OStreamValueMapping( Word* args, Word& result, int message, Word& local, Supplier in_xSupplier, typename OEdgeTupleStreamCreator::EMode eMode) { // cout << "OpOMapMatchingMHTMPoint2OStreamValueMapping called" << endl; OEdgeTupleStreamCreator* pCreator = static_cast*>(local.addr); switch (message) { case OPEN: { if (pCreator != NULL) { delete pCreator; pCreator = NULL; } // get Arguments OrderedRelation* pORel = static_cast(args[0].addr); RTree2TID* pRTree = static_cast(args[1].addr); Relation* pRelation = static_cast(args[2].addr); typename ONetwork::OEdgeAttrIndexes Indexes = GetOEdgeAttrIndexes(args, 4); ONetwork Network(pORel, pRTree, pRelation, Indexes); temporalalgebra::MPoint* pMPoint = static_cast(args[3].addr); // Do Map Matching ONetworkAdapter NetworkAdapter(&Network); MapMatchingMHT MapMatching(&NetworkAdapter, pMPoint); OEdgeTupleStreamCreator* pCreator = new OEdgeTupleStreamCreator(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 int OpOMapMatchingMHTGPX2OStreamValueMapping( Word* args, Word& result, int message, Word& local, Supplier in_xSupplier, typename OEdgeTupleStreamCreator::EMode eMode) { // cout << "OpOMapMatchingMHTGPX2OStreamValueMapping called" << endl; OEdgeTupleStreamCreator* pCreator = static_cast*>(local.addr); switch (message) { case OPEN: { if (pCreator != NULL) { delete pCreator; pCreator = NULL; } // get Arguments OrderedRelation* pORel = static_cast(args[0].addr); RTree2TID* pRTree = static_cast(args[1].addr); Relation* pRelation = static_cast(args[2].addr); typename ONetwork::OEdgeAttrIndexes Indexes = GetOEdgeAttrIndexes(args, 4); ONetwork Network(pORel, pRTree, pRelation, Indexes); FText* pFileName = static_cast(args[3].addr); std::string strFileName = pFileName->GetValue(); // Do Map Matching ONetworkAdapter NetworkAdapter(&Network); MapMatchingMHT MapMatching(&NetworkAdapter, strFileName); OEdgeTupleStreamCreator* pCreator = new OEdgeTupleStreamCreator(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 int OpOMapMatchingMHTStream2OStreamValueMapping( Word* args, Word& result, int message, Word& local, Supplier in_xSupplier, typename OEdgeTupleStreamCreator::EMode eMode) { // cout << "OpOMapMatchingMHTStream2OStreamValueMapping called" << endl; OEdgeTupleStreamCreator* pCreator = static_cast*>(local.addr); switch (message) { case OPEN: { if (pCreator != NULL) { delete pCreator; pCreator = NULL; } // get Arguments OrderedRelation* pORel = static_cast(args[0].addr); RTree2TID* pRTree = static_cast(args[1].addr); Relation* pRelation = static_cast(args[2].addr); typename ONetwork::OEdgeAttrIndexes Indexes = GetOEdgeAttrIndexes(args, 4); ONetwork Network(pORel, pRTree, pRelation, Indexes); shared_ptr pContData = // 9 OEdge-Attr-Indexes GetMMDataFromTupleStream(args[3].addr, args, 4 + 9); // Do Map Matching ONetworkAdapter NetworkAdapter(&Network); MapMatchingMHT MapMatching(&NetworkAdapter, pContData); OEdgeTupleStreamCreator* pCreator = new OEdgeTupleStreamCreator(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 int OpOMapMatchingMHTMPoint2EdgesValueMapping(Word* args, Word& result, int message, Word& local, Supplier in_xSupplier) { return OpOMapMatchingMHTMPoint2OStreamValueMapping( args, result, message, local, in_xSupplier, OEdgeTupleStreamCreator::MODE_EDGES ); } template int OpOMapMatchingMHTGPX2EdgesValueMapping(Word* args, Word& result, int message, Word& local, Supplier in_xSupplier) { return OpOMapMatchingMHTGPX2OStreamValueMapping( args, result, message, local, in_xSupplier, OEdgeTupleStreamCreator::MODE_EDGES); } template int OpOMapMatchingMHTStream2EdgesValueMapping(Word* args, Word& result, int message, Word& local, Supplier in_xSupplier) { return OpOMapMatchingMHTStream2OStreamValueMapping( args, result, message, local, in_xSupplier, OEdgeTupleStreamCreator::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(result.addr); //cout << "get Arguments" << endl; JNetwork *pNetwork = static_cast(args[0].addr); temporalalgebra::MPoint *pMPoint = static_cast(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(result.addr); // get Arguments JNetwork* pNetwork = static_cast(args[0].addr); FText* pFileName = static_cast(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(result.addr); //cout << " get Arguments " << endl; JNetwork* pNetwork = static_cast(args[0].addr); shared_ptr 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([," "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([," "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([," "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 int OpOMapMatchingMHTMPoint2PositionsValueMapping(Word* args, Word& result, int message, Word& local, Supplier in_xSupplier) { // cout << "OpOMapMatchingMHTMPoint2PositionsValueMapping called" << endl; return OpOMapMatchingMHTMPoint2OStreamValueMapping( args, result, message, local, in_xSupplier, OEdgeTupleStreamCreator::MODE_EDGES_AND_POSITIONS); } template int OpOMapMatchingMHTGPX2PositionsValueMapping(Word* args, Word& result, int message, Word& local, Supplier in_xSupplier) { // cout << "OpOMapMatchingMHTGPX2PositionsValueMapping called" << endl; return OpOMapMatchingMHTGPX2OStreamValueMapping( args, result, message, local, in_xSupplier, OEdgeTupleStreamCreator::MODE_EDGES_AND_POSITIONS); } template int OpOMapMatchingMHTStream2PositionsValueMapping(Word* args, Word& result, int message, Word& local, Supplier in_xSupplier) { // cout << "OpOMapMatchingMHTStream2PositionsValueMapping called" << endl; return OpOMapMatchingMHTStream2OStreamValueMapping( args, result, message, local, in_xSupplier, OEdgeTupleStreamCreator::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 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(result.addr); // get Arguments OrderedRelation* pORel = static_cast(args[0].addr); RTree2TID* pRTree = static_cast(args[1].addr); Relation* pRelation = static_cast(args[2].addr); typename ONetwork::OEdgeAttrIndexes Indexes = GetOEdgeAttrIndexes(args, 4); ONetwork Network(pORel, pRTree, pRelation, Indexes); temporalalgebra::MPoint *pMPoint = static_cast(args[3].addr); // Matching ONetworkAdapter NetworkAdapter(&Network); MapMatchingMHT MapMatching(&NetworkAdapter, pMPoint); MPointCreator Creator(pRes, NetworkAdapter.GetNetworkScale()); if (!MapMatching.DoMatch(&Creator)) { // Error } return 0; } template 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(result.addr); // get Arguments OrderedRelation* pORel = static_cast(args[0].addr); RTree2TID* pRTree = static_cast(args[1].addr); Relation* pRelation = static_cast(args[2].addr); typename ONetwork::OEdgeAttrIndexes Indexes = GetOEdgeAttrIndexes(args, 4); ONetwork Network(pORel, pRTree, pRelation, Indexes); FText* pFileName = static_cast(args[3].addr); std::string strFileName = pFileName->GetValue(); // Matching ONetworkAdapter NetworkAdapter(&Network); MapMatchingMHT MapMatching(&NetworkAdapter, strFileName); MPointCreator Creator(pRes, NetworkAdapter.GetNetworkScale()); if (!MapMatching.DoMatch(&Creator)) { // Error } return 0; } template 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(result.addr); // get Arguments OrderedRelation* pORel = static_cast(args[0].addr); RTree2TID* pRTree = static_cast(args[1].addr); Relation* pRelation = static_cast(args[2].addr); typename ONetwork::OEdgeAttrIndexes Indexes = GetOEdgeAttrIndexes(args, 4); ONetwork Network(pORel, pRTree, pRelation, Indexes); shared_ptr pContData = // 9 OEdge-Attr-Indexes GetMMDataFromTupleStream(args[3].addr, args, 4 + 9); // Matching ONetworkAdapter 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(local.addr); switch (message) { case OPEN: { FText* pFileName = static_cast(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(local.addr); if (pImporter != NULL) { CcReal* pScale = static_cast(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, OpOMapMatchingMHTGPX2EdgesValueMapping, OpOMapMatchingMHTStream2EdgesValueMapping, OpOMapMatchingMHTMPoint2EdgesValueMapping, OpOMapMatchingMHTGPX2EdgesValueMapping, OpOMapMatchingMHTStream2EdgesValueMapping, 0 }; AddOperator(OMapMatchMHTInfo(), OMapMatchMHTFuns, OMapMatchMHTSelect, OpOMapMatchingMHTTypeMap); // OMapMatchMHT_P ValueMapping OMapMatchMHT_PFuns[] = { OpOMapMatchingMHTMPoint2PositionsValueMapping, OpOMapMatchingMHTGPX2PositionsValueMapping, OpOMapMatchingMHTStream2PositionsValueMapping, OpOMapMatchingMHTMPoint2PositionsValueMapping, OpOMapMatchingMHTGPX2PositionsValueMapping, OpOMapMatchingMHTStream2PositionsValueMapping, 0 }; AddOperator(OMapMatchMHT_PInfo(), OMapMatchMHT_PFuns, OMapMatchMHT_PSelect, OpOMapMatchingMHT_PTypeMap); // OMapMatchMHT_MPoint ValueMapping OMapMatchMHT_MPointFuns[] = { OpOMapMatchingMHTMPoint2MPointValueMapping, OpOMapMatchingMHTGPX2MPointValueMapping, OpOMapMatchingMHTStream2MPointValueMapping, OpOMapMatchingMHTMPoint2MPointValueMapping, OpOMapMatchingMHTGPX2MPointValueMapping, OpOMapMatchingMHTStream2MPointValueMapping, 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; }