/* This file is part of SECONDO. Copyright (C) 2004, University in Hagen, Department of Computer Science, Database Systems for New Applications. SECONDO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. SECONDO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with SECONDO; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //paragraph [1] Title: [{\Large \bf \begin{center}] [\end{center}}] //paragraph [10] Footnote: [{\footnote{] [}}] 1 Implementation of Algebra Network March 2004 Victor Almeida Mai-Oktober 2007 Martin Scheppokat February 2008 - Simone Jandt October 2008 - Jianqiu Xu April-Mai 2011 - Nina Wrede 1.1 Defines, includes, and constants */ #include #include #include #include #include "Algebras/TupleIdentifier/TupleIdentifier.h" #include "Algebras/Relation-C++/RelationAlgebra.h" #include "Algebras/BTree/BTreeAlgebra.h" #include "Algebras/RTree/RTreeAlgebra.h" #include "Tools/Flob/DbArray.h" #include "Tools/Flob/Flob.h" #include "Algebras/Spatial/SpatialAlgebra.h" #include "Network2Algebra.h" #include "Algebras/Rectangle/RectangleAlgebra.h" #include "StandardTypes.h" #include "Algebra.h" #include "Messages.h" #include "Network2Manager.h" #include "NestedList.h" #include "NList.h" #include "QueryProcessor.h" #include "AlgebraManager.h" #include "ListUtils.h" #include "TypeMapUtils.h" using namespace network2; using namespace std; extern NestedList* nl; extern QueryProcessor* qp; static map *netList; /* 2 Helping structs, methods and classes Sending a message via the message-center */ void sendMessage ( string in_strMessage ) { // Get message-center and initialize message-list static MessageCenter* xMessageCenter= MessageCenter::GetInstance(); NList xMessage; xMessage.append ( NList ( "error" ) ); xMessage.append ( NList().textAtom ( in_strMessage ) ); xMessageCenter->Send (nl, xMessage.listExpr() ); } /* Computes a spatial BoundingBox of a RouteInterval */ Rectangle<2> RouteInterval::BoundingBox ( Network* pNetwork, const Geoid* geoid /*=0*/ ) const { if(geoid){ cerr << __PRETTY_FUNCTION__ << ": Spherical geometry not implemented." << endl; assert( !geoid ); // TODO: implement spherical geometry case } if ( AlmostEqual ( m_dStart , m_dEnd ) ) { Point *p = ( GPoint ( true, pNetwork->GetId(), m_iRouteId, m_dStart ) ).ToPoint ( pNetwork ); double minMax[] = {p->GetX(), p->GetX(), p->GetY(), p->GetY()}; Rectangle<2> bbox = Rectangle<2> ( true,minMax); p->DeleteIfAllowed(); return bbox; } else { SimpleLine *line = new SimpleLine ( 0 ); pNetwork->GetLineValueOfRouteInterval ( this, line ); if ( !line->IsEmpty() ) { Rectangle<2> res = line->BoundingBox(); line->DeleteIfAllowed(); return res; } else { line->DeleteIfAllowed(); Point *p1 = ( GPoint ( true, pNetwork->GetId(), m_iRouteId, m_dStart ) ).ToPoint ( pNetwork ); Point *p2 = ( GPoint ( true, pNetwork->GetId(), m_iRouteId, m_dEnd ) ).ToPoint ( pNetwork ); double minMax[] = {min ( p1->GetX(), p2->GetX() ), max ( p1->GetX(), p2->GetX() ), min ( p1->GetY(), p2->GetY() ), max ( p1->GetY(), p2->GetY() ) }; Rectangle<2> bbox = Rectangle<2> ( true,minMax); p1->DeleteIfAllowed(); p2->DeleteIfAllowed(); return bbox; } } } /* ~searchRouteInterval~ Method for binary search after a route interval in a sorted ~GLine~. O(log n). Used for example by operator ~inside~. */ bool searchRouteInterval ( GPoint *pGPoint, GLine *&pGLine, size_t low, size_t high ) { RouteInterval rI; if ( low <= high ) { size_t mid = ( high + low ) / 2; int imid = mid; if ( ( imid < 0 ) || ( imid >= pGLine->NoOfComponents() ) ) { return false; } else { pGLine->Get ( mid, rI ); if ( rI.GetRouteId() < pGPoint->GetRouteId() ) { return searchRouteInterval ( pGPoint, pGLine, mid+1, high ); } else { if ( rI.GetRouteId() > pGPoint->GetRouteId() ) { return searchRouteInterval ( pGPoint, pGLine, low, mid-1 ); } else { if ( fabs ( pGPoint->GetPosition() - rI.GetStartPos() ) < 0.01 || fabs ( pGPoint->GetPosition() - rI.GetEndPos() ) < 0.01 ) { return true; } else { if ( rI.GetStartPos() > pGPoint->GetPosition() ) { return searchRouteInterval ( pGPoint, pGLine, low, mid-1 ); } else { if ( rI.GetEndPos() < pGPoint->GetPosition() ) { return searchRouteInterval ( pGPoint, pGLine, mid+1, high ); } else { return true; } } } } } } } return false; } /* Helper struct to store sections which have been visited before. Used in shortest path implementation of Dijkstras Algorithm. */ struct SectTree { SectTree() {}; SectTree ( SectTreeEntry *nEntry, SectTree *l = 0, SectTree *r = 0 ) { value = *nEntry; left = l; right = r; }; ~SectTree() {}; /* Inserts a section into the tree. If the section is already in the insert is ignored. */ void Insert ( SectTreeEntry *nEntry ) { if ( nEntry->secttid < value.secttid ) { if ( right != 0 ) right->Insert ( nEntry ); else right = new SectTree ( nEntry,0,0 ); } else { if ( nEntry->secttid > value.secttid ) { if ( left != 0 ) left->Insert ( nEntry ); else left = new SectTree ( nEntry,0,0 ); } } }; /* Returns a pointer to the node with the given id or 0 if not found. */ void Find ( TupleId n, SectTree *result, bool &found ) { if ( n < value.secttid ) { if ( right != 0 ) right->Find ( n, result, found ); else { found = false; result = 0; } } else { if ( n > value.secttid ) { if ( left != 0 ) left->Find ( n, result, found ); else { found = false; result = 0; } } else { found = true; result = this; } } }; void CheckSection ( Network *pNetwork, SectTreeEntry n, GPoints &result ) { vector sectList; sectList.clear(); SectTree *pSectTree = 0; if ( n.startbool || n.endbool ) { if ( n.startbool ) { pNetwork->GetAdjacentSections ( n.secttid, false, sectList ); size_t j = 0; bool found = true; while ( j < sectList.size() && found ) { DirectedSection actSection = sectList[j]; Find ( actSection.GetSectionTid(), pSectTree, found ); } if ( !found ) result += GPoint ( true, pNetwork->GetId(), n.rid, n.start, None ); } sectList.clear(); if ( n.endbool ) { pNetwork->GetAdjacentSections ( n.secttid, true, sectList ); size_t j = 0; bool found = true; while ( j < sectList.size() && found ) { DirectedSection actSection = sectList[j]; Find ( actSection.GetSectionTid(), pSectTree, found ); } if ( !found ) result+= GPoint ( true, pNetwork->GetId(), n.rid, n.end, None ); } sectList.clear(); } else result += GPoint ( true, pNetwork->GetId(), n.rid, n.end, None ); } void WriteResult ( Network* pNetwork, GPoints &result, SectTree &secTr ) { if ( left != 0 ) left->WriteResult ( pNetwork, result, secTr ); if ( right != 0 ) right ->WriteResult ( pNetwork, result, secTr ); secTr.CheckSection ( pNetwork, value, result ); //TODO: Remove duplicate GPoint from Result, which are caused by junction //problematic }; void Remove() { if ( left != 0 ) left->Remove(); if ( right != 0 ) right->Remove(); delete this; }; SectTreeEntry value; SectTree *left, *right; }; /* Almost similar to operator ~checkPoint~ but additional returning a difference value if the point is not exactly on the ~sline~. Used by operator ~point2gpoint~ */ bool chkPoint ( SimpleLine *&route, Point point, bool startSmaller, double &pos, double &difference ) { bool result = false; HalfSegment hs; double k1, k2; Point left, right; for ( int i = 0; i < route->Size()-1; i++ ) { route->Get ( i, hs ); left = hs.GetLeftPoint(); right = hs.GetRightPoint(); Coord xl = left.GetX(), yl = left.GetY(), xr = right.GetX(), yr = right.GetY(), x = point.GetX(), y = point.GetY(); if ( ( fabs ( x-xr ) < 0.01 && fabs ( y-yr ) < 0.01 ) || ( fabs ( x-xl ) < 0.01 && fabs ( y-yl ) < 0.01 ) ) { difference = 0.0; result = true; } else { if ( xl != xr && xl != x ) { k1 = ( y - yl ) / ( x - xl ); k2 = ( yr - yl ) / ( xr - xl ); if ( ( fabs ( k1-k2 ) < 0.004 ) && ( ( xl < xr && ( x > xl || fabs ( x-xl ) < 0.01 ) && ( x < xr || fabs ( x-xr ) < 0.01 ) ) || ( xl > xr && ( x < xl || fabs ( x-xl ) <0.01 ) && ( x > xr || fabs ( x-xr ) < 0.01 ) ) ) && ((( yl <= yr && ( y > yl || fabs ( y-yl ) <0.01 ) && ( y < yr || fabs ( y-yr ) <0.01 ) ) || ( yl > yr && ( y < yl || fabs ( y-yl ) <0.01 ) && ( y > yr || fabs ( y-yr ) <0.01 ) ) ) )) { difference = fabs ( k1-k2 ); result = true; } else {result = false;} } else { if ( ( fabs ( xl - xr ) < 0.01 && fabs ( xl -x ) < 0.01 ) && ( ( ( yl <= yr && ( yl < y || fabs (yl-y ) < 0.01 ) && ( y < yr ||fabs ( y-yr ) <0.01 ) ) || ( yl > yr && ( yl > y || fabs ( yl-y ) < 0.01) && ( y > yr ||fabs ( y-yr ) <0.01 ) ) ) )) { difference = 0.0; result = true; } else {result = false;} } } if ( result ) { LRS lrs; route->Get ( hs.attr.edgeno, lrs ); route->Get ( lrs.hsPos, hs ); pos = lrs.lrsPos + point.Distance ( hs.GetDomPoint() ); if ( startSmaller != route->GetStartSmaller() ) pos = route->Length() - pos; if ( fabs ( pos-0.0 ) < 0.01 ) pos = 0.0; else if ( fabs ( pos-route->Length() ) <0.01 ) pos = route->Length(); return result; } } return result; } /* Almost similar to operator ~chkPoint~ but allowing a greater difference if the point is not exactly on the ~sline~. Used by operator ~point2gpoint~ */ bool chkPoint03 ( SimpleLine *&route, Point point, bool startSmaller, double &pos, double &difference ) { bool result = false; HalfSegment hs; double k1, k2; Point left, right; for ( int i = 0; i < route->Size()-1; i++ ) { route->Get ( i, hs ); left = hs.GetLeftPoint(); right = hs.GetRightPoint(); Coord xl = left.GetX(), yl = left.GetY(), xr = right.GetX(), yr = right.GetY(), x = point.GetX(), y = point.GetY(); if ( ( fabs ( x-xl ) < 0.01 && fabs ( y-yl ) < 0.01 ) || ( fabs ( x-xr ) < 0.01 && fabs ( y-yr ) < 0.01 ) ) { difference = 0.0; result = true; } else { if ( xl != xr && xl != x ) { k1 = ( y - yl ) / ( x - xl ); k2 = ( yr - yl ) / ( xr - xl ); if ( ( fabs ( k1-k2 ) < 1.2 ) && ( ( xl < xr && ( x > xl || fabs ( x-xl ) < 0.01 ) && ( x < xr || fabs ( x-xr ) < 0.01 ) ) || ( xl > xr && ( x < xl || fabs ( x-xl ) < 0.01 ) && ( x > xr || fabs ( x-xr ) < 0.01 ) ) ) && ( ( ( yl < yr || fabs ( yl-yr ) < 0.01 ) && ( y > yl || fabs (y-yl ) <0.01 ) && ( y < yr || fabs ( y-yr ) <0.01 ) ) || ( yl > yr && ( y < yl || fabs ( y-yl ) <0.01 ) && ( y > yr || fabs ( y-yr ) <0.01 ) ) ) ) { difference = fabs ( k1-k2 ); result = true; } else {result = false;} } else { if ( ( fabs ( xl - xr ) < 0.01 && fabs ( xl -x ) < 0.01 ) && ( ( ( yl < yr|| fabs ( yl-yr ) <0.01 ) && ( yl < y || fabs (yl-y ) <0.01 ) && ( y < yr ||fabs ( y-yr ) <0.01 ) ) || ( yl > yr && ( yl > y || fabs ( yl-y ) < 0.01) && ( y > yr ||fabs ( y-yr ) <0.01 ) ) ) ) { difference = 0.0; result = true; } else {result = false;} } } if ( result ) { LRS lrs; route->Get ( hs.attr.edgeno, lrs ); route->Get ( lrs.hsPos, hs ); pos = lrs.lrsPos + point.Distance ( hs.GetDomPoint() ); if ( startSmaller != route->GetStartSmaller() ) pos = route->Length() - pos; if ( fabs ( pos-0.0 ) < 0.01 ) pos = 0.0; else if ( fabs ( pos-route->Length() ) <0.01 ) pos = route->Length(); return result; } } return result; } bool lastchkPoint03 ( SimpleLine *&route, Point point, bool startSmaller, double &pos, double &difference ) { bool result = false; HalfSegment hs; double k1, k2; Point left, right; for ( int i = 0; i < route->Size()-1; i++ ) { route->Get ( i, hs ); left = hs.GetLeftPoint(); right = hs.GetRightPoint(); Coord xl = left.GetX(), yl = left.GetY(), xr = right.GetX(), yr = right.GetY(), x = point.GetX(), y = point.GetY(); if ( ( fabs ( x-xl ) < 0.01 && fabs ( y-yl ) < 0.01 ) || ( fabs ( x-xr ) < 0.01 && fabs ( y-yr ) < 0.01 ) ) { difference = 0.0; result = true; } else { if ( xl != xr && xl != x ) { k1 = ( y - yl ) / ( x - xl ); k2 = ( yr - yl ) / ( xr - xl ); if ( ( ( xl < xr && ( x > xl || fabs ( x-xl ) < 0.1 ) && ( x < xr || fabs ( x-xr ) < 0.01 ) ) || ( xl > xr && ( x < xl || fabs ( x-xl ) <0.01 ) && ( x > xr || fabs ( x-xr ) < 0.01) ) ) && ( ( ( yl < yr || fabs ( yl-yr ) < 0.01 ) && ( y > yl || fabs (y-yl ) < 0.01 ) && ( y < yr || fabs ( y-yr ) < 0.01 ) ) || ( yl > yr && ( y < yl || fabs ( y-yl ) <0.01 ) && ( y > yr || fabs ( y-yr ) <0.01 ) ) ) ) { difference = fabs ( k1-k2 ); result = true; } else {result = false;} } else { if ( ( fabs ( xl - xr ) < 0.01 && fabs ( xl -x ) < 0.01 ) && ( ( ( yl < yr|| fabs ( yl-yr ) <0.01 ) && ( yl < y || fabs ( yl-y ) <0.01 ) && ( y < yr ||fabs ( y-yr ) <0.01 ) ) || ( yl > yr && ( yl > y || fabs ( yl-y ) < 0.01 ) && ( y > yr ||fabs ( y-yr ) <0.01 ) ) ) ) { difference = 0.0; result = true; } else {result = false;} } } if ( result ) { LRS lrs; route->Get ( hs.attr.edgeno, lrs ); route->Get ( lrs.hsPos, hs ); pos = lrs.lrsPos + point.Distance ( hs.GetDomPoint() ); if ( startSmaller != route->GetStartSmaller() ) pos = route->Length() - pos; if ( pos < 0.0 || fabs ( pos - 0.0 ) < 0.01 ) pos = 0.0; else if ( pos > route->Length() || fabs ( pos - route->Length() ) < 0.01 ) pos = route->Length(); return result; } } return result; } /* Returns true if a ~point~ is part of a ~sline~, false elsewhere. If the point is part of the sline his distance from the start is computed also. Used by operator ~line2gline~. */ bool checkPoint ( SimpleLine *&route, Point point, bool startSmaller, double &pos ) { bool result = false; HalfSegment hs; double k1, k2; Point left, right; for ( int i = 0; i < route->Size()-1; i++ ) { route->Get ( i, hs ); left = hs.GetLeftPoint(); right = hs.GetRightPoint(); Coord xl = left.GetX(), yl = left.GetY(), xr = right.GetX(), yr = right.GetY(), x = point.GetX(), y = point.GetY(); if ( ( fabs ( x-xr ) < 0.01 && fabs ( y-yr ) < 0.01 ) || ( fabs ( x-xl ) < 0.01 && fabs ( y-yl ) < 0.01 ) ) { result = true; } else { if ( xl != xr && xl != x ) { k1 = ( y - yl ) / ( x - xl ); k2 = ( yr - yl ) / ( xr - xl ); if ( ( fabs ( k1-k2 ) < 0.004 ) && ( ( xl < xr && ( x > xl || fabs ( x-xl ) < 0.01 ) && ( x < xr || fabs ( x-xr ) < 0.01 ) ) || ( xl > xr && ( x < xl || fabs ( x-xl ) < 0.01 ) && ( x > xr || fabs ( x-xr ) < 0.01 ) ) ) && ( ( ( yl < yr || fabs ( yl-yr ) < 0.01 ) && ( y > yl || fabs ( y-yl ) < 0.01 ) && ( y < yr || fabs ( y-yr ) < 0.01 ) ) || ( yl > yr && ( y < yl || fabs ( y-yl ) < 0.01 ) && ( y > yr || fabs ( y-yr ) < 0.01 ) ) ) ) { result = true; } else {result = false;} } else { if ( ( fabs ( xl - xr ) < 0.01 && fabs ( xl -x ) < 0.01 ) && ( ( ( yl < yr|| fabs ( yl-yr ) < 0.01 ) && ( yl < y || fabs ( yl-y ) <0.01 ) && ( y < yr ||fabs ( y-yr ) <0.01 ) ) || ( yl > yr && ( yl > y || fabs ( yl-y ) < 0.01) && ( y > yr ||fabs ( y-yr ) <0.01 ) ) ) ) { result = true; } else {result = false;} } } if ( result ) { LRS lrs; route->Get ( hs.attr.edgeno, lrs ); route->Get ( lrs.hsPos, hs ); pos = lrs.lrsPos + point.Distance ( hs.GetDomPoint() ); if ( startSmaller != route->GetStartSmaller() ) pos = route->Length() - pos; if ( fabs ( pos-0.0 ) < 0.01 ) pos = 0.0; else if ( fabs ( pos-route->Length() ) <0.01 ) pos = route->Length(); return result; } } return result; }; /* Precondition: ~GLine~ is sorted. Returns true if there is a ~RouteInterval~ in the sorted ~GLine~ which intersects with the given ~RouteInterval~ false elsewhere. Used by operator ~intersects~ */ bool searchUnit ( GLine *pGLine, size_t low, size_t high, RouteInterval pRi ) { assert ( pGLine->IsSorted() ); RouteInterval rI; if ( low <= high ) { size_t mid = ( high + low ) / 2; int imid = mid; if ( ( mid < 0 ) || ( imid >= pGLine->NoOfComponents() ) ) { return false; } else { pGLine->Get ( mid, rI ); if ( rI.GetRouteId() < pRi.GetRouteId() ) { return searchUnit ( pGLine, mid+1, high, pRi ); } else { if ( rI.GetRouteId() > pRi.GetRouteId() ) { return searchUnit ( pGLine, low, mid-1, pRi ); } else { if ( rI.GetStartPos() > pRi.GetEndPos() ) { return searchUnit ( pGLine, low, mid-1, pRi ); } else { if ( rI.GetEndPos() < pRi.GetStartPos() ) { return searchUnit ( pGLine, mid+1, high, pRi ); } else { return true; } } } } } } else { return false; } return false; } /* class ~GPointList~ Used by the operator ~polygpoint~. Computes and stores the resulting ~GPoints~ for the resulting ~stream~ of ~GPoint~. */ class GPointList { public: /* The constructor creates a GPointList from a given gpoint. */ GPointList ( GPoint *gp, Network *pNetwork ) : aliasGP ( 0 ) { lastPos = 0; aliasGP.clean(); aliasGP.Append ( *gp ); vector xJunctions; xJunctions.clear(); if ( pNetwork != 0 ) { CcInt iRouteId ( true, gp->GetRouteId() ); pNetwork->GetJunctionsOnRoute ( &iRouteId, xJunctions ); bool found = false; JunctionSortEntry pCurrJunction; size_t i = 0; while ( !found && i < xJunctions.size() ) { pCurrJunction = xJunctions[i]; if ( fabs ( pCurrJunction.GetRouteMeas() - gp->GetPosition() ) < 0.01 ) { found = true; GPoint test ( true, gp->GetNetworkId(), pCurrJunction.GetOtherRouteId(), pCurrJunction.GetOtherRouteMeas(), None ); aliasGP.Append ( test ); } i++; } while ( found && i < xJunctions.size() ) { pCurrJunction = xJunctions[i]; if ( fabs ( pCurrJunction.GetRouteMeas() - gp->GetPosition() ) <0.01 ) { GPoint test ( true, gp->GetNetworkId(), pCurrJunction.GetOtherRouteId(), pCurrJunction.GetOtherRouteMeas(), None ); aliasGP.Append ( test ); } else { found = false; } i++; } for ( unsigned int i=0;iDeleteIfAllowed(); } xJunctions.clear(); } } ~GPointList() {} /* ~NextGPoint~ This function returns the next GPoint from the GPointList. If there is no more GPoint in the List the result will be 0. This function creates a new GPoint instance via the new operator. The caller of this function has to ensure the deletion of this object. */ const GPoint NextGPoint() { GPoint pAktGPoint; if ( lastPos >= aliasGP.Size() || lastPos < 0 ) { pAktGPoint.SetDefined ( false ); } else { aliasGP.Get ( lastPos, pAktGPoint ); lastPos++; } return pAktGPoint; } private: DbArray aliasGP; int lastPos; }; /* class ~RectangleList~ Almost similar to ~GPointList~. But storing rectangles representing route intervals of a ~gline~. Used by operator ~routeintervals~ to create a ~stream~ of ~rectangles~. */ class RectangleList { public: /* ~Constructor~ Creates a RectangleList from a given gline. */ RectangleList ( GLine *gl ) : aliasRectangleList ( 0 ) { RouteInterval ri; lastPos = 0; aliasRectangleList.clean(); for ( int i = 0 ; i < gl->NoOfComponents(); i++ ) { gl->Get ( i, ri ); double minMax[] = {( double ) ri.GetRouteId(), ( double ) ri.GetRouteId(), min ( ri.GetStartPos(),ri.GetEndPos() ), max ( ri.GetStartPos(), ri.GetEndPos() ) }; Rectangle<2> elem ( true, minMax); aliasRectangleList.Append ( elem ); } } ~RectangleList() {} /* ~NextRectangle~ This function returns the next rectangle from the RectangleList. If there is no more route interval in the List the result will be 0. This function creates a new Rectangle instance via the new operator. The caller of this function has to ensure the deletion of this object. */ const Rectangle<2> NextRectangle() { Rectangle<2> pAktRectangle; if ( lastPos >= aliasRectangleList.Size() || lastPos < 0 ) { pAktRectangle.SetDefined ( false ); } else { aliasRectangleList.Get ( lastPos, pAktRectangle ); lastPos++; } return pAktRectangle; } private: DbArray > aliasRectangleList; int lastPos; }; /* ~struct RIStack~ Used to build compressed shortestpath ~gline~ values. The ~RouteIntervals~ of the shortest path computation are pushed to a stack to first the end section. Last the first section of the path. So they can be returned in the sequence they are needed in the path. When the stack is returned to the resulting ~gline~ it is checked if the ~RouteInterval~s on the stack can be connected to bigger parts. This is always possible if the shortest path follows the same route for more than one section. */ struct RIStack { RIStack() {}; RIStack ( int ri,double pos1, double pos2, RIStack* next = 0 ) { m_iRouteId = ri; m_dStart = pos1; m_dEnd = pos2; m_next = next; }; ~RIStack() {}; void Push ( int rid, double pos1, double pos2, RIStack *&first ) { RIStack *actElem = new RIStack ( rid, pos1, pos2, this ); first = actElem; }; void StackToGLine ( GLine *gline ) { int actRId = m_iRouteId; double actStartPos = m_dStart; double actEndPos = m_dEnd; RIStack *actElem = this->m_next; while ( actElem != 0 ) { if ( actRId == actElem->m_iRouteId && AlmostEqual ( actEndPos,actElem->m_dStart ) ) { actEndPos = actElem->m_dEnd; } else { gline->AddRouteInterval ( actRId, actStartPos, actEndPos ); actRId = actElem->m_iRouteId; actStartPos = actElem->m_dStart; actEndPos = actElem->m_dEnd; } actElem = actElem->m_next; } gline->AddRouteInterval ( actRId, actStartPos, actEndPos ); }; void RemoveStack() { if ( m_next != 0 ) m_next->RemoveStack(); delete this; }; int m_iRouteId; double m_dStart, m_dEnd; RIStack *m_next; }; /* Class PQEntry used for priority Queue in Dijkstras Algorithm for shortest path computing between two gpoint. */ class PQEntry { public: PQEntry() {} PQEntry ( TupleId aktID, double distance, bool upDown, TupleId beforeID ) { sectID = aktID; distFromStart = distance; upDownFlag = upDown; beforeSectID = beforeID; meas1 =0; meas2 =0; rid = 0; costFromStart = 0.0; } PQEntry(TupleId in_aktID, double in_distance, bool in_upDown, TupleId in_beforeID, double in_meas1, double in_meas2, int in_rid, double in_costs=0.0 ): sectID(in_aktID), distFromStart(in_distance), upDownFlag(in_upDown), beforeSectID(in_beforeID), meas1(in_meas1), meas2(in_meas2), rid(in_rid), costFromStart(in_costs) { } PQEntry ( PQEntry &e ) { sectID = e.sectID; distFromStart = e.distFromStart; upDownFlag = e.upDownFlag; beforeSectID = e.beforeSectID; meas1 = e.meas1; meas2 = e.meas2; rid = e.rid; costFromStart = e.costFromStart; } PQEntry ( const PQEntry &e ) { sectID = e.sectID; distFromStart = e.distFromStart; upDownFlag = e.upDownFlag; beforeSectID = e.beforeSectID; meas1 = e.meas1; meas2 = e.meas2; rid = e.rid; costFromStart = e.costFromStart; } ~PQEntry() {} TupleId sectID; double distFromStart; bool upDownFlag; TupleId beforeSectID; double meas1; double meas2; int rid; double costFromStart; }; /* struct sectIDTree stores the PQEntrys by section ID with identification flag for the PrioQueue-Array. An arrayIndex from max integer means not longer in PrioQ and already visited. */ struct SectIDTree { SectIDTree() {}; SectIDTree ( TupleId sectIdent, TupleId beforeSectIdent, bool upDown, int arrayIndex, SectIDTree *l = 0,SectIDTree *r = 0 ) { sectID = sectIdent; beforeSectId = beforeSectIdent; upDownFlag = upDown; index = arrayIndex; left = l; right = r; }; ~SectIDTree() {}; SectIDTree* Find ( TupleId sectIdent ) { if ( sectID > sectIdent ) { if ( left != 0 ) return left->Find ( sectIdent ); else { return this; } } else { if ( sectID < sectIdent ) { if ( right != 0 ) return right->Find ( sectIdent ); else { return this; } } else { return this; } } }; void Remove() { if ( left != 0 ) left->Remove(); if ( right != 0 ) right->Remove(); delete this; }; bool Insert ( TupleId sectIdent, TupleId beforeSectIdent, bool upDownFlag, int arrayIndex,SectIDTree *&pointer ) { pointer = Find ( sectIdent ); if ( pointer->sectID != sectIdent ) { if ( pointer->sectID > sectIdent ) { pointer->left = new SectIDTree ( sectIdent, beforeSectIdent, upDownFlag, arrayIndex ); pointer = pointer->left; return true; } else { if ( pointer->sectID < sectIdent ) { pointer->right = new SectIDTree ( sectIdent, beforeSectIdent, upDownFlag, arrayIndex ); pointer = pointer->right; return true; } else { //should never be reached return false; } } } else { return false; } }; void SetIndex ( TupleId sectIdent, int arrayIndex ) { Find ( sectIdent )->index = arrayIndex; }; void SetIndex ( int arrayIndex ) { index = arrayIndex; }; int GetIndex ( TupleId sectIdent ) { return Find ( sectIdent )->index; }; void SetBeforeSectId ( TupleId sectIdent, TupleId before ) { Find ( sectIdent )->beforeSectId = before; }; void SetBeforeSectId ( TupleId before ) { beforeSectId = before; }; TupleId sectID; TupleId beforeSectId; bool upDownFlag; int index; SectIDTree *left, *right; }; /* struct Priority Queue for Dijkstras Algorithm of shortest path computing between two gpoint. */ struct PrioQueue { PrioQueue() {}; PrioQueue ( int n ) : prioQ ( 0 ) {firstFree = 0;}; ~PrioQueue() {}; /* If a point is reached second time and the distance of the second way is smaller than on the path he has been found before. Its distance value and its position in the priority queue must be corrected. */ void CorrectPosition ( int checkX, const PQEntry nElem, SectIDTree *pSection, SectIDTree *sectTree, bool calcCost=false ) { int act = checkX; PQEntry test; bool found = false; while ( checkX >= 0 && !found ) { if ( ( act % 2 ) == 0 ) checkX = ( act-2 ) / 2; else checkX = ( act -1 ) / 2; if ( checkX >= 0 ) { prioQ.Get ( checkX, test ); if(calcCost){ if ( test.costFromStart > nElem.costFromStart ) { PQEntry help = test; prioQ.Put ( checkX, nElem ); pSection->SetIndex ( checkX ); prioQ.Put ( act, help ); SectIDTree *thelp = sectTree->Find ( help.sectID ); thelp->SetIndex ( act ); act = checkX; } else { found = true; } } else { if ( test.distFromStart > nElem.distFromStart ) { PQEntry help = test; prioQ.Put ( checkX, nElem ); pSection->SetIndex ( checkX ); prioQ.Put ( act, help ); SectIDTree *thelp = sectTree->Find ( help.sectID ); thelp->SetIndex ( act ); act = checkX; } else { found = true; } } } else { found = true; } } }; void Insert ( PQEntry nElem, SectIDTree *sectTree, bool calcCost=false ) { SectIDTree *pSection = sectTree->Find ( nElem.sectID ); PQEntry old; if ( pSection->sectID == nElem.sectID ) { if ( pSection->index != numeric_limits::max() ) { prioQ.Get ( pSection->index, old ); if(calcCost) { if ( nElem.costFromStart < old.costFromStart ) { prioQ.Put ( pSection->index, nElem ); pSection->SetBeforeSectId ( nElem.beforeSectID ); CorrectPosition( pSection->index, nElem, pSection, sectTree,true); } } else { if ( nElem.distFromStart < old.distFromStart ) { prioQ.Put ( pSection->index, nElem ); pSection->SetBeforeSectId ( nElem.beforeSectID ); CorrectPosition(pSection->index, nElem, pSection, sectTree,false); } } } } else { prioQ.Put ( firstFree, nElem ); sectTree->Insert ( nElem.sectID, nElem.beforeSectID, nElem.upDownFlag, firstFree, pSection ); CorrectPosition ( firstFree, nElem, pSection ,sectTree,calcCost ); firstFree++; } } PQEntry* GetAndDeleteMin ( SectIDTree *sectTree, bool calcCost=false) { if ( firstFree > 0 ) { PQEntry result, last, test1, test2; prioQ.Get ( 0,result ); PQEntry *retValue = new PQEntry ( result.sectID, result.distFromStart, result.upDownFlag, result.beforeSectID, result.meas1, result.meas2, result.rid, result.costFromStart); SectIDTree *tRet = sectTree->Find ( result.sectID ); tRet->SetIndex ( numeric_limits::max() ); prioQ.Get ( firstFree-1, last ); prioQ.Put ( 0, last ); firstFree--; SectIDTree *pSection = sectTree->Find ( last.sectID ); pSection->SetIndex ( 0 ); int act = 0; int checkX = 0; bool found = false; while ( checkX < firstFree && !found ) { checkX = 2*act + 1; if ( checkX < firstFree-1 ) { prioQ.Get ( checkX, test1 ); prioQ.Get ( checkX+1, test2 ); if(calcCost) { if ( test1.costFromStart < last.costFromStart || test2.costFromStart < last.costFromStart ) { if ( test1.costFromStart <= test2.costFromStart ) { PQEntry help = test1; prioQ.Put ( checkX, last ); pSection->SetIndex ( checkX ); prioQ.Put ( act, help ); SectIDTree *thelp = sectTree->Find ( help.sectID ); thelp->SetIndex ( act ); act = checkX; } else { PQEntry help = test2; prioQ.Put ( checkX+1, last ); pSection->SetIndex ( checkX+1 ); prioQ.Put ( act, help ); SectIDTree *thelp = sectTree->Find ( help.sectID ); thelp->SetIndex ( act ); act = checkX+1; } } else { found = true; } } else { if ( test1.distFromStart < last.distFromStart || test2.distFromStart < last.distFromStart ) { if ( test1.distFromStart <= test2.distFromStart ) { PQEntry help = test1; prioQ.Put ( checkX, last ); pSection->SetIndex ( checkX ); prioQ.Put ( act, help ); SectIDTree *thelp = sectTree->Find ( help.sectID ); thelp->SetIndex ( act ); act = checkX; } else { PQEntry help = test2; prioQ.Put ( checkX+1, last ); pSection->SetIndex ( checkX+1 ); prioQ.Put ( act, help ); SectIDTree *thelp = sectTree->Find ( help.sectID ); thelp->SetIndex ( act ); act = checkX+1; } } else { found = true; } } } else { if ( checkX != 0 && checkX == firstFree-1 ) { prioQ.Get ( checkX, test1 ); if(calcCost){ if ( test1.costFromStart < last.costFromStart ) { PQEntry help = test1; prioQ.Put ( checkX, last ); pSection->SetIndex ( checkX ); prioQ.Put ( act, help ); SectIDTree *thelp = sectTree->Find ( help.sectID ); thelp->SetIndex ( act ); act = checkX; } else { found = true; } } else { if ( test1.distFromStart < last.distFromStart ) { PQEntry help = test1; prioQ.Put ( checkX, last ); pSection->SetIndex ( checkX ); prioQ.Put ( act, help ); SectIDTree *thelp = sectTree->Find ( help.sectID ); thelp->SetIndex ( act ); act = checkX; } else { found = true; } } } } } return retValue; } else { return 0; } } void Clear() { prioQ.clean(); firstFree = 0; } bool IsEmpty() { if ( firstFree == 0 ) return true; else return false; } void Destroy() { prioQ.Destroy(); } DbArray prioQ; int firstFree; }; /* 3 Class Definitions 3.1 class ~Network~ 3.1.1 Network relations */ string Network::routesTypeInfo = "(rel (tuple ((Id int) (Length real) (Curve sline) " "(Dual bool) (StartsSmaller bool))))"; string Network::routesInternalTypeInfo = "(rel (tuple ((Id int) (Length real) (Curve sline) " "(Dual bool) (StartsSmaller bool) (Startposid int))))"; string Network::routesBTreeTypeInfo = "(btree (tuple ((Id int) (Length real) (Curve sline) " "(Dual bool) (StartsSmaller bool) (Startposid int) )) int)"; string Network::routesRTreeTypeInfo = "(rtree (tuple((Id int)(Length real)(Curve sline)(Dual bool)" "(StartsSmaller bool) (Startposid int) )) sline FALSE)"; string Network::junctionsTypeInfo = "(rel (tuple ((R1id int) (Meas1 real) (R2id int) " "(Meas2 real) (Cc int))))"; /*string Network::junctionsInternalTypeInfo = "(rel (tuple ((r1id int) (meas1 real) (r2id int) " "(meas2 real) (cc int) (pos point) (r1rc tid) (r2rc tid) " "(sauprc tid) (sadownrc tid)(sbuprc tid) (sbdownrc tid))))";*/ string Network::junctionsInternalTypeInfo = "(rel (tuple ((R1id int) (Meas1 real) (R2id int) " "(Meas2 real) (Cc int) (Loc point) (R1rc tid) (R2rc tid) " "(Sauprc tid) (Sadownrc tid)(Sbuprc tid) (Sbdownrc tid))))"; string Network::junctionsBTreeTypeInfo = "(btree (tuple ((R1id int) (Meas1 real) (R2id int) " "(Meas2 real) (Cc int) (Loc point) (R1rc tid) (R2rc tid) " "(Sauprc tid) (Sadownrc tid)(Sbuprc tid) (Sbdownrc tid))) int)"; string Network::sectionsInternalTypeInfo = "(rel (tuple ((Rid int) (Meas1 real) (Meas2 real) (Dual bool)" "(Curve sline)(CurveStartsSmaller bool) (Rrc tid) (Sid int) " "(Pnoup int) (Pnodown int) (Slotup int) (Slotdown int) " "(Cost real) (Time real))))"; string Network::sectionsBTreeTypeInfo = "(btree (tuple ((Rid int) (Meas1 real) (Meas2 real) (Dual bool)" "(Curve sline)(CurveStartsSmaller bool) (Rrc tid) (Sid int) " "(Pnoup int) (Pnodown int) (Slotup int) (Slotdown int) " "(Cost real) (Time real) )) int)"; string Network::distancestorageTypeInfo = "(rel (tuple((J1 tid)(J2 tid)(Dist real)(Sp gline))))"; /* 2.1.2 Constructors and destructors class ~Network~ */ Network::Network() : m_iId ( 0 ), m_bDefined ( false ), m_pRoutes ( 0 ), m_pJunctions ( 0 ), m_pSections ( 0 ), m_pBTreeRoutes ( 0 ), m_pBTreeRoutesByStartposId( 0 ), m_pRTreeRoutes ( 0 ), m_pBTreeJunctionsByRoute1 ( 0 ), m_pBTreeJunctionsByRoute2 ( 0 ), m_xAdjacencyList ( 0 ), m_xSubAdjacencyList ( 0 ), m_pBTreeSectionsByRoute ( 0 ), m_pBTreeSections (0) /*alldistance(0)*/ //only for experimental use with network distances { } Network::Network ( SmiRecord& in_xValueRecord, size_t& inout_iOffset, const ListExpr in_xTypeInfo ): m_xAdjacencyList(0), m_xSubAdjacencyList(0) { // Read network id in_xValueRecord.Read ( &m_iId, sizeof ( int ), inout_iOffset ); inout_iOffset += sizeof ( int ); // Open routes ListExpr xType; nl->ReadFromString ( routesInternalTypeInfo, xType ); ListExpr xNumericType = SecondoSystem::GetCatalog()->NumericType ( xType ); m_pRoutes = Relation::Open ( in_xValueRecord, inout_iOffset, xNumericType ); if ( !m_pRoutes ) { return; } // Open junctions nl->ReadFromString ( junctionsInternalTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); m_pJunctions = Relation::Open ( in_xValueRecord, inout_iOffset, xNumericType ); if ( !m_pJunctions ) { m_pRoutes->Delete(); return; } // Open sections nl->ReadFromString ( sectionsInternalTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); m_pSections = Relation::Open ( in_xValueRecord, inout_iOffset, xNumericType ); if ( !m_pSections ) { m_pRoutes->Delete(); m_pJunctions->Delete(); return; } // Open btree for routes nl->ReadFromString ( routesBTreeTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); m_pBTreeRoutes = BTree::Open ( in_xValueRecord, inout_iOffset, xNumericType ); if ( !m_pBTreeRoutes ) { m_pRoutes->Delete(); m_pJunctions->Delete(); m_pSections->Delete(); return; } // Open btree for routesByStartposId nl->ReadFromString ( routesBTreeTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); m_pBTreeRoutesByStartposId = BTree::Open ( in_xValueRecord, inout_iOffset, xNumericType ); if ( !m_pBTreeRoutesByStartposId ) { m_pRoutes->Delete(); m_pJunctions->Delete(); m_pSections->Delete(); delete m_pBTreeRoutes; return; } //Open rtree for routes Word xValue; if ( ! ( m_pRTreeRoutes->Open ( in_xValueRecord, inout_iOffset, routesRTreeTypeInfo, xValue ) ) ) { m_pRoutes->Delete(); m_pJunctions->Delete(); m_pSections->Delete(); delete m_pBTreeRoutes; delete m_pBTreeRoutesByStartposId; return; } m_pRTreeRoutes = ( R_Tree<2,TupleId>* ) xValue.addr; // Open first btree for junctions nl->ReadFromString ( junctionsBTreeTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); m_pBTreeJunctionsByRoute1 = BTree::Open ( in_xValueRecord, inout_iOffset, xNumericType ); if ( !m_pBTreeJunctionsByRoute1 ) { m_pRoutes->Delete(); m_pJunctions->Delete(); m_pSections->Delete(); delete m_pBTreeRoutes; delete m_pBTreeRoutesByStartposId; delete m_pRTreeRoutes; return; } // Open second btree for junctions nl->ReadFromString ( junctionsBTreeTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); m_pBTreeJunctionsByRoute2 = BTree::Open ( in_xValueRecord, inout_iOffset, xNumericType ); if ( !m_pBTreeJunctionsByRoute2 ) { m_pRoutes->Delete(); m_pJunctions->Delete(); m_pSections->Delete(); delete m_pBTreeRoutes; delete m_pBTreeRoutesByStartposId; delete m_pRTreeRoutes; delete m_pBTreeJunctionsByRoute1; return; } // m_xAdjacencyList.OpenFromRecord(in_xValueRecord, inout_iOffset); // m_xSubAdjacencyList.OpenFromRecord(in_xValueRecord,inout_iOffset); size_t bufsize = sizeof(FlobId) + sizeof(SmiSize) + 2*sizeof(int); SmiSize offset = 0; char* buf = (char*) malloc(bufsize); in_xValueRecord.Read(buf, bufsize, inout_iOffset); inout_iOffset += bufsize; assert(buf != NULL); m_xAdjacencyList.restoreHeader(buf,offset); free(buf); offset = 0; buf = (char*) malloc(bufsize); in_xValueRecord.Read(buf, bufsize, inout_iOffset); assert(buf != NULL); m_xSubAdjacencyList.restoreHeader(buf,offset); inout_iOffset += bufsize; free(buf); // Open btree for sections by Routes nl->ReadFromString ( sectionsBTreeTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); m_pBTreeSectionsByRoute = BTree::Open ( in_xValueRecord, inout_iOffset, xNumericType ); if ( !m_pBTreeSectionsByRoute ) { m_pRoutes->Delete(); m_pJunctions->Delete(); m_pSections->Delete(); delete m_pBTreeRoutes; delete m_pBTreeRoutesByStartposId; delete m_pRTreeRoutes; delete m_pBTreeJunctionsByRoute1; delete m_pBTreeJunctionsByRoute2; return; } // Open btree for sections nl->ReadFromString ( sectionsBTreeTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); m_pBTreeSections = BTree::Open ( in_xValueRecord, inout_iOffset, xNumericType ); if ( !m_pBTreeSections ) { m_pRoutes->Delete(); m_pJunctions->Delete(); m_pSections->Delete(); delete m_pBTreeRoutes; delete m_pBTreeRoutesByStartposId; delete m_pRTreeRoutes; delete m_pBTreeJunctionsByRoute1; delete m_pBTreeJunctionsByRoute2; delete m_pBTreeSectionsByRoute; return; } //Open distance storage /* nl->ReadFromString(distancestorageTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); alldistance = Relation::Open(in_xValueRecord,inout_iOffset,xNumericType); if(!alldistance){ m_pRoutes->Delete(); m_pJunctions->Delete(); m_pSections->Delete(); delete m_pBTreeRoutes; delete m_pRTreeRoutes; delete m_pBTreeJunctionsByRoute1; delete m_pBTreeJunctionsByRoute2; return; } */ m_bDefined = true; } Network::Network ( ListExpr in_xValue, int in_iErrorPos, ListExpr& inout_xErrorInfo, bool& inout_bCorrect ) : m_iId ( 0 ), m_bDefined ( false ), m_pRoutes ( 0 ), m_pJunctions ( 0 ), m_pSections ( 0 ), m_pBTreeRoutes ( 0 ), m_pBTreeRoutesByStartposId ( 0 ), m_pRTreeRoutes ( 0 ), m_pBTreeJunctionsByRoute1 ( 0 ), m_pBTreeJunctionsByRoute2 ( 0 ), m_xAdjacencyList ( 0 ), m_xSubAdjacencyList ( 0 ), m_pBTreeSectionsByRoute ( 0 ), m_pBTreeSections (0) /*alldistance(0)*/ { // Check the list if ( ! ( nl->ListLength ( in_xValue ) == 3 ) ) { string strErrorMessage = "Network(): List length must be 3."; inout_xErrorInfo = nl->Append ( inout_xErrorInfo, nl->StringAtom ( strErrorMessage ) ); inout_bCorrect = false; return; } // Get type-info for temporary table ListExpr xType; nl->ReadFromString ( routesTypeInfo, xType ); ListExpr xRoutesNumType = SecondoSystem::GetCatalog()->NumericType ( xType ); nl->ReadFromString ( junctionsTypeInfo, xType ); ListExpr xJunctionsNumType = SecondoSystem::GetCatalog()->NumericType ( xType ); // Split into the three parts ListExpr xIdList = nl->First ( in_xValue ); ListExpr xRouteList = nl->Second ( in_xValue ); ListExpr xJunctionList = nl->Third ( in_xValue ); // Sections will be calculated in the load-method // Read Id if ( !nl->IsAtom ( xIdList ) || nl->AtomType ( xIdList ) != IntType ) { string strErrorMessage = "Network(): Id is missing."; inout_xErrorInfo = nl->Append ( inout_xErrorInfo, nl->StringAtom ( strErrorMessage ) ); inout_bCorrect = false; return; } m_iId = nl->IntValue ( xIdList ); // Create new temporary relations. Relation* pRoutes = new Relation ( xRoutesNumType, false ); Relation* pJunctions = new Relation ( xJunctionsNumType, false ); // Iterate over all routes while ( !nl->IsEmpty ( xRouteList ) ) { ListExpr xCurrentRoute = nl->First ( xRouteList ); xRouteList = nl->Rest ( xRouteList ); // Create tuple for internal table Tuple* pNewRoute = new Tuple ( nl->Second ( xRoutesNumType ) ); // Check this part of the list if ( nl->ListLength ( xCurrentRoute ) != 5 || ( !nl->IsAtom ( nl->First ( xCurrentRoute ) ) ) || nl->AtomType ( nl->First ( xCurrentRoute ) ) != IntType || ( !nl->IsAtom ( nl->Second ( xCurrentRoute ) ) ) || nl->AtomType ( nl->Second ( xCurrentRoute ) ) != RealType || ( nl->IsAtom ( nl->Third ( xCurrentRoute ) ) ) || ( !nl->IsAtom ( nl->Fourth ( xCurrentRoute ) ) ) || nl->AtomType ( nl->Fourth ( xCurrentRoute ) ) != BoolType || ( !nl->IsAtom ( nl->Fifth ( xCurrentRoute ) ) ) || nl->AtomType ( nl->Fifth ( xCurrentRoute ) ) != BoolType ) { delete pRoutes; delete pRoutes; string strErrorMessage = "Network(): Error while reading out routes."; inout_xErrorInfo = nl->Append ( inout_xErrorInfo, nl->StringAtom ( strErrorMessage ) ); inout_bCorrect = false; return; } // Read attributes from list // Read values from table int iRouteId = nl->IntValue ( nl->First ( xCurrentRoute ) ); double dLength = nl->RealValue ( nl->Second ( xCurrentRoute ) ); Word xLineWord = InSimpleLine ( nl->TheEmptyList(), nl->Third ( xCurrentRoute ), in_iErrorPos, inout_xErrorInfo, inout_bCorrect ); SimpleLine* pLine = ( SimpleLine* ) ( xLineWord.addr ); bool bDual= nl->BoolValue ( nl->Fourth ( xCurrentRoute ) ); bool bStartsSmaller = nl->BoolValue ( nl->Fifth ( xCurrentRoute ) ); // Set all necessary attributes pNewRoute->PutAttribute ( ROUTE_ID, new CcInt ( true, iRouteId ) ); pNewRoute->PutAttribute ( ROUTE_LENGTH, new CcReal ( true, dLength ) ); pNewRoute->PutAttribute ( ROUTE_CURVE, pLine ); pNewRoute->PutAttribute ( ROUTE_DUAL, new CcBool ( true, bDual ) ); pNewRoute->PutAttribute ( ROUTE_STARTSSMALLER, new CcBool ( true, bStartsSmaller ) ); // Append new junction pRoutes->AppendTuple ( pNewRoute ); if ( pNewRoute ) { pNewRoute->DeleteIfAllowed(); pNewRoute=0; } } // Iterate over all junctions while ( !nl->IsEmpty ( xJunctionList ) ) { ListExpr xCurrentJunction = nl->First ( xJunctionList ); xJunctionList = nl->Rest ( xJunctionList ); // Create tuple for internal table Tuple* pNewJunction = new Tuple ( nl->Second ( xJunctionsNumType ) ); // Check this part of the list if ( nl->ListLength ( xCurrentJunction ) != 6 || ( !nl->IsAtom ( nl->First ( xCurrentJunction ) ) ) || nl->AtomType ( nl->First ( xCurrentJunction ) ) != IntType || ( !nl->IsAtom ( nl->Second ( xCurrentJunction ) ) ) || nl->AtomType ( nl->Second ( xCurrentJunction ) ) != RealType || ( !nl->IsAtom ( nl->Third ( xCurrentJunction ) ) ) || nl->AtomType ( nl->Third ( xCurrentJunction ) ) != IntType || ( !nl->IsAtom ( nl->Fourth ( xCurrentJunction ) ) ) || nl->AtomType ( nl->Fourth ( xCurrentJunction ) ) != RealType || ( !nl->IsAtom ( nl->Fifth ( xCurrentJunction ) ) ) || nl->AtomType ( nl->Fifth ( xCurrentJunction ) ) != IntType ) { delete pRoutes; delete pJunctions; string strErrorMessage = "Network(): Error while reading out junctions."; inout_xErrorInfo = nl->Append ( inout_xErrorInfo, nl->StringAtom ( strErrorMessage ) ); inout_bCorrect = false; return; } // Read attributes from list int iRoute1Id = nl->IntValue ( nl->First ( xCurrentJunction ) ); double dMeas1 = nl->RealValue ( nl->Second ( xCurrentJunction ) ); int iRoute2Id = nl->IntValue ( nl->Third ( xCurrentJunction ) ); double dMeas2 = nl->RealValue ( nl->Fourth ( xCurrentJunction ) ); int iConnectivityCode= nl->IntValue ( nl->Fifth ( xCurrentJunction ) ); // The location of the junction "Point" is calculated in the load-method // Set all necessary attributes pNewJunction->PutAttribute ( JUNCTION_ROUTE1_ID, new CcInt ( true, iRoute1Id ) ); pNewJunction->PutAttribute ( JUNCTION_ROUTE1_MEAS, new CcReal ( true, dMeas1 ) ); pNewJunction->PutAttribute ( JUNCTION_ROUTE2_ID, new CcInt ( true, iRoute2Id ) ); pNewJunction->PutAttribute ( JUNCTION_ROUTE2_MEAS, new CcReal ( true, dMeas2 ) ); pNewJunction->PutAttribute ( JUNCTION_CC, new CcInt ( true, iConnectivityCode ) ); // Append new junction pJunctions->AppendTuple ( pNewJunction ); if ( pNewJunction ) { pNewJunction->DeleteIfAllowed(); pNewJunction=0; } } Load ( m_iId, pRoutes, pJunctions ); delete pRoutes; delete pJunctions; m_bDefined = true; } /* Destructor */ Network::~Network() { delete m_pRoutes; delete m_pJunctions; delete m_pSections; delete m_pBTreeRoutes; delete m_pBTreeRoutesByStartposId; delete m_pRTreeRoutes; delete m_pBTreeJunctionsByRoute1; delete m_pBTreeJunctionsByRoute2; delete m_pBTreeSectionsByRoute; delete m_pBTreeSections; // delete alldistance; } /* 2.1.3 Methods of class ~network~ Method ~Destroy~ Removing a network from the database */ void Network::Destroy() { assert ( m_pRoutes != 0 ); m_pRoutes->Delete(); m_pRoutes = 0; assert ( m_pJunctions != 0 ); m_pJunctions->Delete(); m_pJunctions = 0; assert ( m_pSections != 0 ); m_pSections->Delete(); m_pSections = 0; assert ( m_pBTreeRoutes != 0 ); m_pBTreeRoutes->DeleteFile(); delete m_pBTreeRoutes; m_pBTreeRoutes = 0; assert ( m_pBTreeRoutesByStartposId != 0 ); m_pBTreeRoutesByStartposId->DeleteFile(); delete m_pBTreeRoutesByStartposId; m_pBTreeRoutesByStartposId = 0; assert ( m_pRTreeRoutes != 0 ); //m_pRTreeRoutes->DeleteFile(); delete m_pRTreeRoutes; m_pRTreeRoutes = 0; m_pBTreeJunctionsByRoute1->DeleteFile(); delete m_pBTreeJunctionsByRoute1; m_pBTreeJunctionsByRoute1 = 0; m_pBTreeJunctionsByRoute2->DeleteFile(); delete m_pBTreeJunctionsByRoute2; m_pBTreeJunctionsByRoute2 = 0; // m_xAdjacencyList.Destroy(); // m_xSubAdjacencyList.Destroy(); assert ( m_pBTreeSectionsByRoute != 0 ); m_pBTreeSectionsByRoute->DeleteFile(); delete m_pBTreeSectionsByRoute; m_pBTreeSectionsByRoute = 0; assert ( m_pBTreeSections != 0 ); m_pBTreeSections->DeleteFile(); delete m_pBTreeSections; m_pBTreeSections = 0; /* assert(alldistance != 0); delete alldistance; */ } /* Method ~Load~ Create a network from two external relations */ void Network::Load ( int in_iId, const Relation* in_pRoutes, const Relation* in_pJunctions ) { m_iId = in_iId; FillRoutes ( in_pRoutes ); FillJunctions ( in_pJunctions ); FillSections(); FillAdjacencyLists(); //FillDistanceStorage();//store distance m_bDefined = true; } /* Method ~OptimizeNetwork~ optimizes the order of the ~routes~, after that all ~sections~ are generated new and all structures based on these ~sections~ are adjusted */ bool Network::OptimizeNetwork(){ //sort routes OptimizationRoutes(); //DEBUG //cout << "output of all routes"<< endl; //for (int i =1; i<=m_pRoutes->GetNoTuples();i++) //{ //Tuple *n = m_pRoutes->GetTuple(i,false); //cout <<"("<< ((CcInt*)n->GetAttribute(ROUTE_ID))->GetIntval() << "," // << ((CcInt*)n->GetAttribute(ROUTE_STARTPOS_ID))->GetIntval() // << ")"<DeleteIfAllowed(); //} //update the BTree for routes by startPos_id delete m_pBTreeRoutesByStartposId; m_pBTreeRoutesByStartposId=0; ostringstream xThisRoutesPtrStream2; xThisRoutesPtrStream2 << ( long ) m_pRoutes; string strQuery = "(createbtree (" + routesInternalTypeInfo + " (ptr " + xThisRoutesPtrStream2.str() + "))" + " Startposid)"; Word xResult; int QueryExecuted = QueryProcessor::ExecuteQuery ( strQuery, xResult ); assert ( QueryExecuted ); // no query with side effects, please! m_pBTreeRoutesByStartposId = ( BTree* ) xResult.addr; //Fillsections new delete m_pBTreeSections; delete m_pBTreeSectionsByRoute; int anz = m_pSections->GetNoTuples(); for(int z=1;z <= anz ;z++){ m_pSections->DeleteTuple(m_pSections->GetTuple(z,false)); } m_pSections->Clear(); delete m_pSections; m_pSections = 0; FillSections(); //Update the Adjacencylist //DEBUG cout << "update AdjacencList mit "<< m_xAdjacencyList.Size()<< endl; m_xAdjacencyList.clean(); m_xAdjacencyList = 0; FillAdjacencyLists(); return true; } /* Mehtod ~OptimizationRoutes~ determined for all ~routes~ their lexicographic start point, stores them in an array and calls the sort method ~QuicksortRoutes~ */ bool Network::OptimizationRoutes(){ Tuple *route; GPoint *gp; Point *p = new Point(); int anzElemente = m_pRoutes->GetNoTuples(); int testarray[anzElemente][2]; bool opt= false; for (int i =1; i<=m_pRoutes->GetNoTuples();i++) { route = m_pRoutes->GetTuple(i,false); int id = ((CcInt*) route->GetAttribute(ROUTE_ID))->GetIntval(); //bool smaller= // ((CcBool*) route->GetAttribute(ROUTE_STARTSSMALLER))->GetBoolval(); // dermine points gp = new GPoint(true, GetId(),id, 0.0); gp->ToPoint(p); if (p->IsDefined()) opt = true; else return false; testarray[i-1][0] = id; testarray[i-1][1] = p->GetX(); } if(opt) { //DEBUG for testing //cout << "vor dem Sortieren" << endl; //for (int k =0; k< anzElemente; k++) //{ //cout << testarray[k][0] <<"," <GetTuple(testarray[k][0],false); vector xIndices; vector xAttrs; xIndices.push_back ( ROUTE_STARTPOS_ID ); xAttrs.push_back ( new CcInt ( true, k+1 ) ); m_pRoutes->UpdateTuple(route, xIndices, xAttrs); } } p->DeleteIfAllowed(); gp->DeleteIfAllowed(); route->DeleteIfAllowed(); return true; } /* Method ~QuicksortRoutes~ calculates the pivot-element-index with the method ~QuicksortRoutesPartition~. After that ~QuicksortRoutes~ is recursively called for the upper and lower part of the array */ void Network::QuicksortRoutes(int arr[][2], int low, int high) { int pivotIndex; if(low < high) { //split the array and calculate the pivot-element pivotIndex = QuicksortRoutesPartition(arr, low, high); //sort the bottom part QuicksortRoutes(arr, low, pivotIndex-1); //sort the top part QuicksortRoutes(arr, pivotIndex+1,high); } } /* Method ~QuicksortRoutesPartition~ split the given array and sorts the array so that all elements before the pivot-element are smaller and all elements that are above the pivot element are larger. */ int Network::QuicksortRoutesPartition(int arr[][2], int low, int high) { //DEBUG cout << "QuicksortPartiton: mit lowindex: " << low // << " und highindex: " << high << endl; int high_vac[2]={0},low_vac[2]={0},pivot[2]={0}; pivot[0] = arr[low][0]; pivot[1] = arr[low][1]; // while the lowindex is less than the highIndex while(high > low) { //DEBUG cout << "while high: "<< high // << " ist groesser als low: " << low << endl; high_vac[0] = arr[high][0]; high_vac[1] = arr[high][1]; //DEBUG cout << "highWert " << high_vac[1] << endl; //while the value of the high-element is greater than //or equal the pivot-element while(pivot[1] <= high_vac[1]) { //DEBUG cout << "while pivot : "<< pivot[1] // << " ist kleiner als hight_vac: " << high_vac[1]<< endl; // if hightindex less then or equal with // the lowindex BREAK the while-loop if(high <= low) break; high--; high_vac[0] = arr[high][0]; high_vac[1] = arr[high][1]; } arr[low][0] = high_vac[0]; arr[low][1] = high_vac[1]; low_vac[0] = arr[low][0]; low_vac[1] = arr[low][1]; //while the value of the pivot-element is greater than the low-element while(pivot[1] > low_vac[1]) { //cout << "while pivot : "<< pivot[1] // << " ist groesser als low_vac: " << low_vac[1]<< endl; // if hightindex less then or equal with // the lowindex BREAK the while-loop if(high<=low) break; low++; low_vac[0] = arr[low][0]; low_vac[1] = arr[low][1]; } arr[high][0] = low_vac[0]; arr[high][1] = low_vac[1]; } arr[low][0] = pivot[0]; arr[low][1] = pivot[1]; //return the lowindex value return low; } /* Method ~FillRoutes~ Fill routes relation of network */ void Network::FillRoutes ( const Relation *routes ) { //Create new table for the routes ListExpr xTypeInfo; nl->ReadFromString ( routesInternalTypeInfo, xTypeInfo ); ListExpr xNumType = SecondoSystem::GetCatalog()->NumericType ( xTypeInfo ); Relation *pIntRoutes = new Relation ( xNumType, true ); // Iterator for the input-table with routes GenericRelationIterator* pRoutesIter = routes->MakeScan(); Tuple* pCurrentRoute; int routeCounter =1; while ( ( pCurrentRoute = pRoutesIter->GetNextTuple() ) != 0 ) { // Create tuple for internal table and copy all attributes from input Tuple* pNewRoute = new Tuple ( nl->Second ( xNumType ) ); for ( int i = 0; i < pCurrentRoute->GetNoAttributes(); i++ ) { pNewRoute->CopyAttribute ( i, pCurrentRoute, i ); } // Fill other fields of the table pNewRoute->PutAttribute(ROUTE_STARTPOS_ID,new CcInt(true,routeCounter)); // Append new route pIntRoutes->AppendTuple ( pNewRoute ); //clean up pCurrentRoute->DeleteIfAllowed(); pNewRoute->DeleteIfAllowed(); // increment routeCounter for next route routeCounter++; } delete pRoutesIter; ostringstream xRoutesPtrStream; xRoutesPtrStream << ( long ) pIntRoutes; string strQuery = "(consume (sort (feed (" + routesInternalTypeInfo + " (ptr " + xRoutesPtrStream.str() + ")))))"; Word xResult; int QueryExecuted = QueryProcessor::ExecuteQuery ( strQuery, xResult ); assert ( QueryExecuted ); m_pRoutes = ( Relation * ) xResult.addr; delete pIntRoutes; // Create B-Tree for the routes ostringstream xThisRoutesPtrStream; xThisRoutesPtrStream << ( long ) m_pRoutes; strQuery = "(createbtree (" + routesInternalTypeInfo + " (ptr " + xThisRoutesPtrStream.str() + "))" + " Id)"; QueryExecuted = QueryProcessor::ExecuteQuery ( strQuery, xResult ); assert ( QueryExecuted ); // no query with side effects, please! m_pBTreeRoutes = ( BTree* ) xResult.addr; // Create B-Tree for the routes by startPos_id ostringstream xThisRoutesPtrStream2; xThisRoutesPtrStream2 << ( long ) m_pRoutes; strQuery = "(createbtree (" + routesInternalTypeInfo + " (ptr " + xThisRoutesPtrStream2.str() + "))" + " Startposid)"; QueryExecuted = QueryProcessor::ExecuteQuery ( strQuery, xResult ); assert ( QueryExecuted ); // no query with side effects, please! m_pBTreeRoutesByStartposId = ( BTree* ) xResult.addr; //Create R-Tree for the routes ostringstream xNetRoutes; xNetRoutes << ( long ) m_pRoutes; strQuery = "(bulkloadrtree(sortby(addid(feed (" + routesInternalTypeInfo + " (ptr " + xThisRoutesPtrStream.str() + "))))((Curve asc))) Curve)"; QueryExecuted = QueryProcessor::ExecuteQuery ( strQuery, xResult ); assert ( QueryExecuted ); m_pRTreeRoutes = ( R_Tree<2,TupleId>* ) xResult.addr; } /* Method ~FillJunctions~ Fill junctions relation of network */ void Network::FillJunctions ( const Relation *in_pJunctions ) { ///////////////////////////////////////////////////////////////////// // // Create new table for the junctions // ListExpr xTypeInfo; nl->ReadFromString ( junctionsInternalTypeInfo, xTypeInfo ); ListExpr xNumType = SecondoSystem::GetCatalog()->NumericType ( xTypeInfo ); Relation *pIntJunctions = new Relation ( xNumType, true ); ///////////////////////////////////////////////////////////////////// // // Iterator for the input-table with junctions // GenericRelationIterator* pJunctionsIter = in_pJunctions->MakeScan(); Tuple* pCurrentJunction; while ( ( pCurrentJunction = pJunctionsIter->GetNextTuple() ) != 0 ) { ///////////////////////////////////////////////////////////////////// // // Create tuple for internal table and copy all attributes from input // Tuple* pNewJunction = new Tuple ( nl->Second ( xNumType ) ); for ( int i = 0; i < pCurrentJunction->GetNoAttributes(); i++ ) { pNewJunction->CopyAttribute ( i, pCurrentJunction, i ); } ///////////////////////////////////////////////////////////////////// // // Fill other fields of the table // // Store Pointer to the first route in the new relation. CcInt* pR1Id = ( CcInt* ) pCurrentJunction->GetAttribute ( JUNCTION_ROUTE1_ID ); BTreeIterator* pRoutesIter = m_pBTreeRoutes->ExactMatch ( pR1Id ); int NextIter = pRoutesIter->Next(); assert ( NextIter ); TupleIdentifier *pR1RC = new TupleIdentifier ( true, pRoutesIter->GetId() ); pNewJunction->PutAttribute ( JUNCTION_ROUTE1_RC, pR1RC ); // Calculate and store the exakt location of the junction. Tuple* pRoute = m_pRoutes->GetTuple ( pRoutesIter->GetId(), false ); assert ( pRoute != 0 ); SimpleLine* pLine = ( SimpleLine* ) pRoute->GetAttribute ( ROUTE_CURVE ); assert ( pLine != 0 ); CcReal* pMeas = ( CcReal* ) pNewJunction->GetAttribute ( JUNCTION_ROUTE1_MEAS ); Point* pPoint = new Point ( false ); pLine->AtPosition ( pMeas->GetRealval(), true, *pPoint ); pNewJunction->PutAttribute ( JUNCTION_POS, pPoint ); pRoute->DeleteIfAllowed(); delete pRoutesIter; // Store Pointer to the second route in the new relation. CcInt* pR2Id = ( CcInt* ) pCurrentJunction->GetAttribute ( JUNCTION_ROUTE2_ID ); pRoutesIter = m_pBTreeRoutes->ExactMatch ( pR2Id ); NextIter = pRoutesIter->Next(); assert ( NextIter ); // no query with side effects, please! TupleIdentifier *pR2RC = new TupleIdentifier ( true, pRoutesIter->GetId() ); pNewJunction->PutAttribute ( JUNCTION_ROUTE2_RC, pR2RC ); delete pRoutesIter; // Pointers to sections are filled in FillSections pNewJunction->PutAttribute ( JUNCTION_SECTION_AUP_RC, new TupleIdentifier ( false ) ); pNewJunction->PutAttribute ( JUNCTION_SECTION_ADOWN_RC, new TupleIdentifier ( false ) ); pNewJunction->PutAttribute ( JUNCTION_SECTION_BUP_RC, new TupleIdentifier ( false ) ); pNewJunction->PutAttribute ( JUNCTION_SECTION_BDOWN_RC, new TupleIdentifier ( false ) ); ///////////////////////////////////////////////////////////////////// // // Append new junction // pIntJunctions->AppendTuple ( pNewJunction ); pCurrentJunction->DeleteIfAllowed(); pNewJunction->DeleteIfAllowed(); } delete pJunctionsIter; ///////////////////////////////////////////////////////////////////// // // Sort the table which is now containing all junctions // ostringstream xJunctionsStream; xJunctionsStream << ( long ) pIntJunctions; string strQuery = "(consume (sortby (feed (" + junctionsInternalTypeInfo + " (ptr " + xJunctionsStream.str() + "))) ((R1id asc)(Meas1 asc))))"; Word xResult; int QueryExecuted = QueryProcessor::ExecuteQuery ( strQuery, xResult ); assert ( QueryExecuted ); m_pJunctions = ( Relation * ) xResult.addr; // Delete internal table pIntJunctions->Delete(); ///////////////////////////////////////////////////////////////////// // // Create two b-trees for the junctions sorted by first and second id // ostringstream xThisJunctionsPtrStream; xThisJunctionsPtrStream << ( long ) m_pJunctions; strQuery = "(createbtree (" + junctionsInternalTypeInfo + " (ptr " + xThisJunctionsPtrStream.str() + "))" + " R1id)"; QueryExecuted = QueryProcessor::ExecuteQuery ( strQuery, xResult ); assert ( QueryExecuted ); // no query with side effects, please! m_pBTreeJunctionsByRoute1 = ( BTree* ) xResult.addr; ostringstream xThisJunctionsPtrStream2; xThisJunctionsPtrStream2 << ( long ) m_pJunctions; strQuery = "(createbtree (" + junctionsInternalTypeInfo + " (ptr " + xThisJunctionsPtrStream2.str() + "))" + " R2id)"; QueryExecuted = QueryProcessor::ExecuteQuery ( strQuery, xResult ); assert ( QueryExecuted ); // no query with side effects, please! m_pBTreeJunctionsByRoute2 = ( BTree* ) xResult.addr; } /* Method ~FillSections~ Fill section relation of network */ void Network::FillSections() { // The method will iterate over routes by StartposIndex BTreeIterator* pRoutesIt = m_pBTreeRoutesByStartposId->SelectAll(); // Create relation for sections ListExpr xType; nl->ReadFromString ( sectionsInternalTypeInfo, xType ); ListExpr xNumType = SecondoSystem::GetCatalog()->NumericType ( xType ); m_pSections = new Relation ( xNumType ); ///////////////////////////////////////////////////////////////////// // // Iterate over all Routes // Tuple* pRoute; TupleId iSectionTid = 0; while ( pRoutesIt->Next() ) { pRoute = m_pRoutes->GetTuple(pRoutesIt->GetId(),false); //DEBUG cout << "Rid " // <<((CcInt*)pRoute->GetAttribute(ROUTE_ID))->GetIntval()<GetAttribute ( ROUTE_CURVE ); TupleId iTupleId = pRoute->GetTupleId(); CcInt* xRouteId = ( CcInt* ) pRoute->GetAttribute ( ROUTE_ID ); int iRouteId = xRouteId->GetIntval(); bool bDual = ( ( CcBool* ) pRoute->GetAttribute ( ROUTE_DUAL ) )->GetBoolval(); ///////////////////////////////////////////////////////////////////// // // We need to find all junctions belonging to this route // vector xJunctions; GetJunctionsOnRoute ( xRouteId, xJunctions ); ///////////////////////////////////////////////////////////////////// // // Now that we found all relevant junctions we can iterate over them. // JunctionSortEntry xCurrentEntry; xCurrentEntry.m_pJunction = 0; xCurrentEntry.m_bFirstRoute = false; for ( size_t i = 0; i < xJunctions.size(); i++ ) { // Get next junction xCurrentEntry = xJunctions[i]; // Find values for the new section double dStartPos = dCurrentPosOnRoute; double dEndPos = xCurrentEntry.GetRouteMeas(); // If the first junction is at the very start of the route, no // section will be added if ( xCurrentEntry.GetRouteMeas() == 0 ) { vector xIndices; vector xAttrs; if ( xCurrentEntry.m_bFirstRoute ) { xIndices.push_back ( JUNCTION_SECTION_ADOWN_RC ); xAttrs.push_back ( new TupleIdentifier ( true, 0 ) ); } else { xIndices.push_back ( JUNCTION_SECTION_BDOWN_RC ); xAttrs.push_back ( new TupleIdentifier ( true, 0 ) ); } m_pJunctions->UpdateTuple ( xCurrentEntry.m_pJunction, xIndices, xAttrs ); continue; } ///////////////////////////////////////////////////////////////////// // // Create a new section // // Section will only be created if the length is > 0. Otherwise the // one before remains valid. if ( dEndPos - dStartPos > 0.01 ) { // A sline for the section SimpleLine* pLine = new SimpleLine ( 0 ); // Take start from the route bool bStartSmaller = ( ( CcBool* ) pRoute->GetAttribute ( ROUTE_STARTSSMALLER ) )->GetBoolval(); pRouteCurve->SubLine ( dStartPos, dEndPos, bStartSmaller, *pLine ); // Find out, if the orientation of the subline differs from the position // of the line. If so, the direction has to be changed. bool bLineStartsSmaller; Point pStartPoint ( false ); pRouteCurve->AtPosition ( dStartPos, bStartSmaller, pStartPoint ); Point pEndPoint ( false ); pRouteCurve->AtPosition ( dEndPos, bStartSmaller, pEndPoint ); if ( pStartPoint.GetX() < pEndPoint.GetX() || ( pStartPoint.GetX() == pEndPoint.GetX() && pStartPoint.GetY() < pEndPoint.GetY() ) ) { // Normal orientation bLineStartsSmaller = true; } else { // Opposite orientation bLineStartsSmaller = false; } // The new section Tuple* pNewSection = new Tuple ( nl->Second ( xNumType ) ); pNewSection->PutAttribute ( SECTION_RID, new CcInt ( true, iRouteId ) ); pNewSection->PutAttribute ( SECTION_DUAL, new CcBool ( true, bDual ) ); pNewSection->PutAttribute ( SECTION_MEAS1, new CcReal ( true, dStartPos ) ); pNewSection->PutAttribute ( SECTION_MEAS2, new CcReal ( true, dEndPos ) ); pNewSection->PutAttribute ( SECTION_RRC, new TupleIdentifier ( true, iTupleId ) ); pNewSection->PutAttribute ( SECTION_CURVE, pLine ); pNewSection->PutAttribute ( SECTION_CURVE_STARTS_SMALLER, new CcBool ( true, bLineStartsSmaller ) ); pNewSection->PutAttribute ( SECTION_SID, new CcInt ( true, m_pSections->GetNoTuples() +1 ) ); //new Attributes inserted pNewSection->PutAttribute (SECTION_PNO_UP, new CcInt(true,0)); pNewSection->PutAttribute (SECTION_PNO_DOWN, new CcInt(true,0)); pNewSection->PutAttribute (SECTION_SLOT_UP, new CcInt(true,0)); pNewSection->PutAttribute (SECTION_SLOT_DOWN, new CcInt(true,0)); pNewSection->PutAttribute (SECTION_COST, new CcReal(true,1.0)); pNewSection->PutAttribute (SECTION_DURATION, new CcReal(true,1.0)); m_pSections->AppendTuple ( pNewSection ); iSectionTid++; pNewSection->DeleteIfAllowed(); // Update position for next loop dCurrentPosOnRoute = dEndPos; } ///////////////////////////////////////////////////////////////////// // // Store ID of new section in junction behind that section. // vector xIndices; vector xAttrs; if ( xCurrentEntry.m_bFirstRoute ) { xIndices.push_back ( JUNCTION_SECTION_ADOWN_RC ); xAttrs.push_back ( new TupleIdentifier ( true, iSectionTid ) ); } else { xIndices.push_back ( JUNCTION_SECTION_BDOWN_RC ); xAttrs.push_back ( new TupleIdentifier ( true, iSectionTid ) ); } m_pJunctions->UpdateTuple ( xCurrentEntry.m_pJunction, xIndices, xAttrs ); if ( pRouteCurve->Length() - xCurrentEntry.GetRouteMeas() < 0.01 ) { vector xIndices; vector xAttrs; if ( xCurrentEntry.m_bFirstRoute ) { xIndices.push_back ( JUNCTION_SECTION_AUP_RC ); xAttrs.push_back ( new TupleIdentifier ( true, 0 ) ); } else { xIndices.push_back ( JUNCTION_SECTION_BUP_RC ); xAttrs.push_back ( new TupleIdentifier ( true, 0 ) ); } m_pJunctions->UpdateTuple ( xCurrentEntry.m_pJunction, xIndices, xAttrs ); } } // End junctions-loop ///////////////////////////////////////////////////////////////////// // // The last section of the route is still missing, if the last // junction is not at the end of the route. // if ( pRouteCurve->Length() - dCurrentPosOnRoute > 0.01 || dCurrentPosOnRoute == 0.0 ) { // Find values for the new section int iRouteId = ( ( CcInt* ) pRoute->GetAttribute ( ROUTE_ID ) )->GetIntval(); bool bDual = ( ( CcBool* ) pRoute->GetAttribute ( ROUTE_DUAL ) )->GetBoolval(); double dStartPos = dCurrentPosOnRoute; double dEndPos = pRouteCurve->Length(); TupleId iTupleId = pRoute->GetTupleId(); // Calculate line SimpleLine* pLine = new SimpleLine ( 0 ); bool bStartSmaller = ( ( CcBool* ) pRoute->GetAttribute ( ROUTE_STARTSSMALLER ) )->GetBoolval(); pRouteCurve->SubLine ( dStartPos, dEndPos, bStartSmaller, *pLine ); // Find out, if the orientation of the subline differs from the position // of the sline. If so, the direction has to be changed. bool bLineStartsSmaller; Point pStartPoint ( false ); pRouteCurve->AtPosition ( dStartPos, bStartSmaller, pStartPoint ); Point pEndPoint ( false ); pRouteCurve->AtPosition ( dEndPos, bStartSmaller, pEndPoint ); if ( pStartPoint.GetX() < pEndPoint.GetX() || ( pStartPoint.GetX() == pEndPoint.GetX() && pStartPoint.GetY() < pEndPoint.GetY() ) ) { // Normal orientation bLineStartsSmaller = true; } else { // Opposite orientation bLineStartsSmaller = false; } // Create a new Section Tuple* pNewSection = new Tuple ( nl->Second ( xNumType ) ); pNewSection->PutAttribute ( SECTION_RID, new CcInt ( true, iRouteId ) ); pNewSection->PutAttribute ( SECTION_DUAL, new CcBool ( true, bDual ) ); pNewSection->PutAttribute ( SECTION_MEAS1, new CcReal ( true, dStartPos ) ); pNewSection->PutAttribute ( SECTION_MEAS2, new CcReal ( true, dEndPos ) ); pNewSection->PutAttribute ( SECTION_RRC, new TupleIdentifier ( true, iTupleId ) ); pNewSection->PutAttribute ( SECTION_CURVE, pLine ); pNewSection->PutAttribute ( SECTION_CURVE_STARTS_SMALLER, new CcBool ( true, bLineStartsSmaller ) ); pNewSection->PutAttribute ( SECTION_SID, new CcInt ( true, m_pSections->GetNoTuples() +1 ) ); //new Attributes inserted pNewSection->PutAttribute (SECTION_PNO_UP, new CcInt(true,0)); pNewSection->PutAttribute (SECTION_PNO_DOWN, new CcInt(true,0)); pNewSection->PutAttribute (SECTION_SLOT_UP, new CcInt(true,0)); pNewSection->PutAttribute (SECTION_SLOT_DOWN, new CcInt(true,0)); pNewSection->PutAttribute (SECTION_COST, new CcReal(true,1.0)); pNewSection->PutAttribute (SECTION_DURATION, new CcReal(true,1.0)); m_pSections->AppendTuple ( pNewSection ); iSectionTid++; pNewSection->DeleteIfAllowed(); // Store ID of new section in Junction if ( xCurrentEntry.m_pJunction != 0 ) { vector xIndicesLast; vector xAttrsLast; if ( xCurrentEntry.m_bFirstRoute ) { xIndicesLast.push_back ( JUNCTION_SECTION_AUP_RC ); xAttrsLast.push_back ( new TupleIdentifier ( true, iSectionTid ) ); } else { xIndicesLast.push_back ( JUNCTION_SECTION_BUP_RC ); xAttrsLast.push_back ( new TupleIdentifier ( true, iSectionTid ) ); } m_pJunctions->UpdateTuple ( xCurrentEntry.m_pJunction, xIndicesLast, xAttrsLast ); } } // end if //////////////////////////////////////////////////////////////////// // // Fill Up-Pointers of all sections but the last // vector yJunctions; GetJunctionsOnRoute ( xRouteId, yJunctions ); if ( yJunctions.size() > 2 ) { for ( int i = yJunctions.size()-2; i >= 0; i-- ) { // Get next junction JunctionSortEntry xEntry = yJunctions[i]; JunctionSortEntry xEntryBehind = yJunctions[i + 1]; vector xIndices; if ( xEntry.m_bFirstRoute ) { xIndices.push_back ( JUNCTION_SECTION_AUP_RC ); } else { xIndices.push_back ( JUNCTION_SECTION_BUP_RC ); } vector xAttrs; if ( xEntryBehind.GetRouteMeas() - xEntry.GetRouteMeas() < 0.01 ) { // Two junctions at the same place. In this case they do have // the same up-pointers if ( xEntryBehind.m_bFirstRoute ) { TupleId iTid = xEntryBehind.GetUpSectionId(); xAttrs.push_back ( new TupleIdentifier ( true, iTid ) ); } else { TupleId iTid = xEntryBehind.GetUpSectionId(); xAttrs.push_back ( new TupleIdentifier ( true, iTid ) ); } } else { // Junctions not on the same place. The down-pointer of the second is // the up-pointer of the first. if ( xEntryBehind.m_bFirstRoute ) { TupleId iTid = xEntryBehind.GetDownSectionId(); xAttrs.push_back ( new TupleIdentifier ( true, iTid ) ); } else { TupleId iTid = xEntryBehind.GetDownSectionId(); xAttrs.push_back ( new TupleIdentifier ( true, iTid ) ); } } m_pJunctions->UpdateTuple ( xEntry.m_pJunction, xIndices, xAttrs ); } } else { if ( yJunctions.size() == 2 ) { JunctionSortEntry xEntry = yJunctions[0]; JunctionSortEntry xEntryBehind = yJunctions[1]; vector xIndices; if ( xEntry.m_bFirstRoute ) { xIndices.push_back ( JUNCTION_SECTION_AUP_RC ); } else { xIndices.push_back ( JUNCTION_SECTION_BUP_RC ); } vector xAttrs; if ( fabs ( xEntry.GetRouteMeas() - xEntryBehind.GetRouteMeas() ) < 0.01 ) { if ( xEntryBehind.m_bFirstRoute ) { TupleId iTid = xEntryBehind.GetUpSectionId(); xAttrs.push_back ( new TupleIdentifier ( true, iTid ) ); } else { TupleId iTid = xEntryBehind.GetUpSectionId(); xAttrs.push_back ( new TupleIdentifier ( true, iTid ) ); } m_pJunctions->UpdateTuple ( xEntry.m_pJunction, xIndices, xAttrs ); } else { if ( xEntryBehind.m_bFirstRoute ) { TupleId iTid = xEntryBehind.GetDownSectionId(); xAttrs.push_back ( new TupleIdentifier ( true, iTid ) ); } else { TupleId iTid = xEntryBehind.GetDownSectionId(); xAttrs.push_back ( new TupleIdentifier ( true, iTid ) ); } m_pJunctions->UpdateTuple ( xEntry.m_pJunction, xIndices, xAttrs ); } } } pRoute->DeleteIfAllowed(); // delete Tuples from xJunctions for ( unsigned int i=0;iDeleteIfAllowed(); } } xJunctions.clear(); // delete Tuples from yJunctions for ( unsigned int i=0;iDeleteIfAllowed(); } } yJunctions.clear(); } // End while Routes delete pRoutesIt; // Create B-Tree for the sections by Routes Word xResult; ostringstream xThisSectionsPtrStream; xThisSectionsPtrStream << ( long ) m_pSections; string strQuery = "(createbtree (" + sectionsInternalTypeInfo + " (ptr " + xThisSectionsPtrStream.str() + "))" + " Rid)"; int QueryExecuted = QueryProcessor::ExecuteQuery ( strQuery, xResult ); assert ( QueryExecuted ); // no query with side effects, please! m_pBTreeSectionsByRoute = ( BTree* ) xResult.addr; //Create B-Tree for the sections Word xResultNewBtree; ostringstream xStream2; xStream2 << (long) m_pSections; string query = "(createbtree (" + sectionsInternalTypeInfo + " (ptr " + xStream2.str() + "))" + " Sid)"; int QueryEx = QueryProcessor::ExecuteQuery ( query, xResultNewBtree ); assert ( QueryEx ); // no query with side effects, please! m_pBTreeSections = ( BTree* ) xResultNewBtree.addr; } /* Method ~FillAdjacencyLists~ Fill adjacency list of network */ void Network::FillAdjacencyLists() { //////////////////////////////////////////////////////////////////// //In a first step all pairs of adjacent sections will be collected GenericRelationIterator* pJunctionsIt = m_pJunctions->MakeScan(); Tuple* pCurrentJunction; vector xList; while ( ( pCurrentJunction = pJunctionsIt->GetNextTuple() ) != 0 ) { // Retrieve the connectivity code int iCc = (( CcInt* ) pCurrentJunction->GetAttribute ( JUNCTION_CC ))->GetIntval(); ConnectivityCode xCc ( iCc ); // Retrieve the four sections - if they exist TupleId tidpAUp, tidpADown, tidpBUp, tidpBDown; tidpAUp = (( TupleIdentifier* )pCurrentJunction ->GetAttribute ( JUNCTION_SECTION_AUP_RC ))->GetTid(); tidpADown =(( TupleIdentifier* )pCurrentJunction ->GetAttribute ( JUNCTION_SECTION_ADOWN_RC ))->GetTid(); tidpBUp = ( ( TupleIdentifier* )pCurrentJunction ->GetAttribute ( JUNCTION_SECTION_BUP_RC ))->GetTid(); tidpBDown = ( ( TupleIdentifier* )pCurrentJunction ->GetAttribute ( JUNCTION_SECTION_BDOWN_RC ))->GetTid(); // If a section is existing and the transition is possible // it will be added to the list. FillAdjacencyPair ( tidpAUp, false, tidpAUp, true, xCc, AUP_AUP, xList ); FillAdjacencyPair ( tidpAUp, false, tidpADown, false, xCc, AUP_ADOWN, xList); FillAdjacencyPair ( tidpAUp, false, tidpBUp, true, xCc, AUP_BUP, xList ); FillAdjacencyPair ( tidpAUp, false, tidpBDown, false, xCc, AUP_BDOWN, xList); FillAdjacencyPair ( tidpADown, true, tidpAUp, true, xCc, ADOWN_AUP, xList ); FillAdjacencyPair ( tidpADown, true, tidpADown, false, xCc,ADOWN_ADOWN,xList); FillAdjacencyPair ( tidpADown, true, tidpBUp, true, xCc, ADOWN_BUP, xList ); FillAdjacencyPair ( tidpADown, true, tidpBDown, false, xCc,ADOWN_BDOWN,xList); FillAdjacencyPair ( tidpBUp, false, tidpAUp, true, xCc, BUP_AUP, xList ); FillAdjacencyPair ( tidpBUp, false, tidpADown, false, xCc, BUP_ADOWN, xList); FillAdjacencyPair ( tidpBUp, false, tidpBUp, true, xCc, BUP_BUP, xList ); FillAdjacencyPair ( tidpBUp, false, tidpBDown, false, xCc, BUP_BDOWN, xList); FillAdjacencyPair ( tidpBDown, true, tidpAUp, true, xCc, BDOWN_AUP, xList ); FillAdjacencyPair ( tidpBDown, true, tidpADown, false, xCc,BDOWN_ADOWN,xList); FillAdjacencyPair ( tidpBDown, true, tidpBUp, true, xCc,BDOWN_BUP, xList ); FillAdjacencyPair ( tidpBDown, true, tidpBDown, false, xCc,BDOWN_BDOWN,xList); pCurrentJunction->DeleteIfAllowed(); } delete pJunctionsIt; //////////////////////////////////////////////////////////////////// // Now - as the second step the adjacency lists are filled. // Sort the list by the first directed section sort ( xList.begin(), xList.end() ); //m_pSections contains a sorted List of all sections //xList contains all neightbours of one section, if a section has no //neighbours, there is no Entry in xList for this section //search all neighbours of a section DirectedSectionPair xLastPair; //stored the last Entry TupleId actTid = 1; //actual TupleId of the section to be processed int counterN = 0; //counts the neighbours of one section bool flag = true; //toggelt after a pageEntry for section without neighbours DirectedSection actDS = DirectedSection (actTid, flag); DirectedSection lastDS = DirectedSection(m_pSections->GetNoTuples(),false); PageRecord actPage = PageRecord(0); int actPageNum = 1; int actSlotNum = 1; m_xAdjacencyList.clean(); //***************************************************************** // First step to fill the adjacencylist is to identify the number of // neighbours to calculate the necessery space for a section. for ( size_t i = 0; i < xList.size(); i++ ){ // Get next entry DirectedSectionPair xPair = xList[i]; //Special treatment for the first Entry if(i==0){ //set last Element xLastPair = xPair; //collect all Sections without neighbours, //there are listed befor the first Entry while(xPair.m_iFirstSectionTid != actDS.GetSectionTid() || xPair.m_bFirstUpDown != actDS.GetUpDownFlag()){ // if there is a section without neighbours put it in pageRecord if(xPair.m_iFirstSectionTid != actDS.GetSectionTid() || xPair.m_bFirstUpDown != actDS.GetUpDownFlag()){ //get sid, meas1, meas2 and rid Tuple *pSect = m_pSections->GetTuple (actDS.GetSectionTid(),false ); double actMeas1 = ((CcReal*)pSect->GetAttribute(SECTION_MEAS1))->GetRealval(); double actMeas2 = ((CcReal*)pSect->GetAttribute(SECTION_MEAS2))->GetRealval(); int actRid = (( CcInt* )pSect->GetAttribute(SECTION_RID))->GetIntval(); double actCost = (( CcReal* )pSect->GetAttribute(SECTION_COST))->GetRealval(); double actDuration = ((CcReal*)pSect->GetAttribute(SECTION_DURATION))->GetRealval(); int actSid = ((CcInt* )pSect->GetAttribute(SECTION_SID))->GetIntval(); // stored Section-Information in page bool success = actPage.SetSectionContent( actDS.GetSectionTid(),actSid, actDS.GetUpDownFlag(), actMeas1,actMeas2,actRid,actCost, actDuration, 0, actSlotNum); if(!success){ // page was full, store the pagerecord in adjacencylist m_xAdjacencyList.Append(actPage); // reset actSlotNum to 1 and increment actPageNum actSlotNum = 1; actPageNum++; //create a new Page and stored section information there actPage = PageRecord(0); actPage.SetSectionContent( actDS.GetSectionTid(),actSid, actDS.GetUpDownFlag(), actMeas1,actMeas2, actRid, actCost, actDuration , 0, actSlotNum); } //stored PageNum and SlotNum in Section vector xIndices; vector xAttrs; if(actDS.GetUpDownFlag()){ xIndices.push_back (SECTION_PNO_UP); xIndices.push_back (SECTION_SLOT_UP); }else{ xIndices.push_back (SECTION_PNO_DOWN); xIndices.push_back (SECTION_SLOT_DOWN); } xAttrs.push_back ( new CcInt(true,actPageNum) ); xAttrs.push_back ( new CcInt(true,actSlotNum) ); m_pSections->UpdateTuple(pSect, xIndices, xAttrs); pSect->DeleteIfAllowed(); //increment actSlotNum actSlotNum++; } //set next actDirectedSection to be processed if(flag){ flag = false; } else { flag= true; actTid++; } actDS = DirectedSection(actTid,flag); } } // Entry in adjacency list if all sections adjacent to one section have // been found. This is the case every time the first section changes. // Never at the first entry and always at the last. if (i == xList.size() -1 || (i != 0 && (xLastPair.m_iFirstSectionTid != xPair.m_iFirstSectionTid || xLastPair.m_bFirstUpDown != xPair.m_bFirstUpDown))){ if(i==xList.size() -1){ counterN++; //last entry, the counter must increment } //all neighbours of a section are found, //so put the section on the pageRecord //get sid, meas1, meas2 and rid Tuple *pSect = m_pSections->GetTuple (xLastPair.m_iFirstSectionTid,false ); double actMeas1 = ((CcReal*) pSect->GetAttribute (SECTION_MEAS1))->GetRealval();; double actMeas2 = ((CcReal*) pSect->GetAttribute (SECTION_MEAS2))->GetRealval(); int actRid = (( CcInt* )pSect->GetAttribute(SECTION_RID))->GetIntval(); double actCost = (( CcReal* )pSect->GetAttribute(SECTION_COST))->GetRealval(); double actDuration = (( CcReal* )pSect->GetAttribute(SECTION_DURATION))->GetRealval(); int actSid = ((CcInt*)pSect->GetAttribute(SECTION_SID))->GetIntval(); // stored Section-Information in page bool success = actPage.SetSectionContent( xLastPair.m_iFirstSectionTid,actSid, xLastPair.m_bFirstUpDown, actMeas1,actMeas2,actRid,actCost, actDuration, counterN, actSlotNum); if(!success){ // page was full, store the pagerecord in adjacencylist m_xAdjacencyList.Append(actPage); // reset actSlotNum to 1 and increment actPageNum actSlotNum = 1; actPageNum++; //create a new Page and stored the section information there actPage = PageRecord(0); actPage.SetSectionContent( xLastPair.m_iFirstSectionTid,actSid, xLastPair.m_bFirstUpDown,actMeas1, actMeas2, actRid, actCost, actDuration , counterN, actSlotNum); } //stored PageNum and SlotNum in Section vector xIndices; vector xAttrs; if(xLastPair.m_bFirstUpDown){ xIndices.push_back (SECTION_PNO_UP); xIndices.push_back (SECTION_SLOT_UP); }else{ xIndices.push_back (SECTION_PNO_DOWN); xIndices.push_back (SECTION_SLOT_DOWN); } xAttrs.push_back ( new CcInt(true,actPageNum) ); xAttrs.push_back ( new CcInt(true,actSlotNum) ); m_pSections->UpdateTuple(pSect, xIndices, xAttrs); pSect->DeleteIfAllowed(); //increment actSlotNum actSlotNum++; //check, if sections are between the last and the actual Entry //exist, which have no neighbours while(xPair.m_iFirstSectionTid != actDS.GetSectionTid() || xPair.m_bFirstUpDown != actDS.GetUpDownFlag()){ //set next actDirectedSection to be processed if(flag){ flag = false; } else { flag= true; actTid++; } actDS = DirectedSection(actTid,flag); //if there is a section without neighbours put it in pageRecord if(xPair.m_iFirstSectionTid != actDS.GetSectionTid() || xPair.m_bFirstUpDown != actDS.GetUpDownFlag()){ //get sid, meas1, meas2 and rid Tuple *pSect = m_pSections->GetTuple (actDS.GetSectionTid(),false ); double actMeas1 = ((CcReal*)pSect->GetAttribute(SECTION_MEAS1))->GetRealval(); double actMeas2 = ((CcReal*)pSect->GetAttribute(SECTION_MEAS2))->GetRealval(); int actRid = (( CcInt* )pSect->GetAttribute(SECTION_RID))->GetIntval(); double actCost = ((CcReal* )pSect->GetAttribute(SECTION_COST))->GetRealval(); double actDuration = ((CcReal*)pSect->GetAttribute(SECTION_DURATION))->GetRealval(); int actSid = ((CcInt*)pSect->GetAttribute(SECTION_SID))->GetIntval(); // stored Section-Information in page bool success = actPage.SetSectionContent( actDS.GetSectionTid(),actSid, actDS.GetUpDownFlag(), actMeas1, actMeas2,actRid, actCost,actDuration , 0, actSlotNum); if(!success){ // page was full, store the pagerecord in adjacencylist m_xAdjacencyList.Append(actPage); // reset actSlotNum to 1 and increment actPageNum actSlotNum = 1; actPageNum++; //create a new Page and stored section information there actPage = PageRecord(0); actPage.SetSectionContent( actDS.GetSectionTid(),actSid, actDS.GetUpDownFlag(), actMeas1, actMeas2,actRid, actCost, actDuration , 0, actSlotNum); } //stored PageNum and SlotNum in Section vector xIndices; vector xAttrs; if(actDS.GetUpDownFlag()){ xIndices.push_back (SECTION_PNO_UP); xIndices.push_back (SECTION_SLOT_UP); }else{ xIndices.push_back (SECTION_PNO_DOWN); xIndices.push_back (SECTION_SLOT_DOWN); } xAttrs.push_back ( new CcInt(true,actPageNum) ); xAttrs.push_back ( new CcInt(true,actSlotNum) ); m_pSections->UpdateTuple(pSect, xIndices, xAttrs); pSect->DeleteIfAllowed(); //increment actSlotNum actSlotNum++; } } // reset the counter of neighbours after the Entry in the pageRecord counterN =0; } // Check if entry allready exists in list. As the list is sorted it // has to be the entry before. if ( i == 0 || xLastPair.m_iFirstSectionTid != xPair.m_iFirstSectionTid || xLastPair.m_bFirstUpDown != xPair.m_bFirstUpDown || xLastPair.m_iSecondSectionTid != xPair.m_iSecondSectionTid || xLastPair.m_bSecondUpDown != xPair.m_bSecondUpDown ) { counterN++; // the counter of neighbours must increment } //check, if sections after the last Entry exist, that have no neighbours if (i == xList.size() -1){ while(lastDS.GetSectionTid() != actDS.GetSectionTid() || lastDS.GetUpDownFlag() != actDS.GetUpDownFlag()){ //set next actDirectedSection to be processed if(flag){ flag = false; } else { flag= true; actTid++; } actDS = DirectedSection(actTid,flag); // if there is a section without neighbours put it in pageRecord if(lastDS.GetSectionTid() != actDS.GetSectionTid() || lastDS.GetUpDownFlag() != actDS.GetUpDownFlag()){ //get sid, meas1,meas2and rid Tuple *pSect = m_pSections->GetTuple (actDS.GetSectionTid(),false ); double actMeas1 = ((CcReal*)pSect->GetAttribute(SECTION_MEAS1))->GetRealval(); double actMeas2 = ((CcReal*)pSect->GetAttribute(SECTION_MEAS2))->GetRealval(); int actRid = (( CcInt* )pSect->GetAttribute(SECTION_RID))->GetIntval(); double actCost = (( CcReal*)pSect->GetAttribute(SECTION_COST))->GetRealval(); double actDuration = ((CcReal*)pSect->GetAttribute(SECTION_DURATION))->GetRealval(); int actSid = ((CcInt*)pSect->GetAttribute(SECTION_SID))->GetIntval(); // stored Section-Information in page bool success = actPage.SetSectionContent( actDS.GetSectionTid(),actSid, actDS.GetUpDownFlag(), actMeas1, actMeas2, actRid, actCost, actDuration , 0, actSlotNum); if(!success){ // page was full, store the pagerecord in adjacencylist m_xAdjacencyList.Append(actPage); // reset actSlotNum to 1 and increment actPageNum actSlotNum = 1; actPageNum++; //create a new Page and stored section information there actPage = PageRecord(0); actPage.SetSectionContent( actDS.GetSectionTid(),actSid, actDS.GetUpDownFlag(), actMeas1, actMeas2, actRid, actCost, actDuration ,0, actSlotNum); } //stored PageNum and SlotNum in Section vector xIndices; vector xAttrs; if(actDS.GetUpDownFlag()){ xIndices.push_back (SECTION_PNO_UP); xIndices.push_back (SECTION_SLOT_UP); }else{ xIndices.push_back (SECTION_PNO_DOWN); xIndices.push_back (SECTION_SLOT_DOWN); } xAttrs.push_back ( new CcInt(true,actPageNum) ); xAttrs.push_back ( new CcInt(true,actSlotNum) ); m_pSections->UpdateTuple(pSect, xIndices, xAttrs); pSect->DeleteIfAllowed(); //increment actSlotNum actSlotNum++; } } } // set last Entry xLastPair = xPair; } if(xList.size()!= 0){ // store last Page in the AdjacencyList m_xAdjacencyList.Append(PageRecord(actPage)); } m_xAdjacencyList.TrimToSize(); // //***************************************************************** // Second step to fill the adjacencylist is to set all pagenumbers and // Slotindex for the neighbours of a section. Because that information // is collected in the first Step. actPageNum =0; // reset old used variable for actual PageNumber actSlotNum =0; // reset old used variable for actual SlotNumber actPage = PageRecord(0); // reset old used variable for actual Page DirectedSectionPair actPair;// actual read sectionPair from xList DirectedSectionPair lastPair; int nCounter=0;// counts the proceeded neighbours start even by 0 int actNPage,actNSlot; // actual PageNR and SlotNR of a Neighboursection TupleId nSTid; // sectionid and UpDownFlag of a neighbour bool nUpD; size_t actIndex = 0; // actual Index of the xList while(actIndex < xList.size()){ //get actual element actPair = xList[actIndex]; // get actual Tuple from section relation Tuple *pSect = m_pSections->GetTuple (actPair.m_iFirstSectionTid,false); // get page and slotnumber of this DirectionPair if (actPair.m_bFirstUpDown){ actPageNum =((CcInt*)pSect->GetAttribute(SECTION_PNO_UP))->GetIntval(); actSlotNum =((CcInt*)pSect->GetAttribute(SECTION_SLOT_UP))->GetIntval(); }else{ actPageNum=((CcInt*)pSect->GetAttribute(SECTION_PNO_DOWN))->GetIntval(); actSlotNum=((CcInt*)pSect->GetAttribute(SECTION_SLOT_DOWN))->GetIntval(); } // get page, where the actual section is stored m_xAdjacencyList.Get(actPageNum-1, actPage); nCounter =0; // at first element strored this as last element if(actIndex == 0){ lastPair = actPair; } while(actIndex==0 || (actPair.m_iFirstSectionTid== lastPair.m_iFirstSectionTid && actPair.m_bFirstUpDown==lastPair.m_bFirstUpDown)){ if(actIndex !=0 && !(lastPair.m_iSecondSectionTid == xList[actIndex].m_iSecondSectionTid && lastPair.m_bSecondUpDown ==xList[actIndex].m_bSecondUpDown)){ // read nSid and nUpD form xList nSTid = lastPair.m_iSecondSectionTid; nUpD = lastPair.m_bSecondUpDown; // for each Entry stored Information Tuple *pNSect = m_pSections->GetTuple (nSTid,false ); if (nUpD){ actNPage = (( CcInt* )pNSect->GetAttribute(SECTION_PNO_UP))->GetIntval(); actNSlot = (( CcInt* )pNSect->GetAttribute(SECTION_SLOT_UP))->GetIntval(); }else{ actNPage = (( CcInt* )pNSect->GetAttribute(SECTION_PNO_DOWN))->GetIntval(); actNSlot = (( CcInt* )pNSect->GetAttribute(SECTION_SLOT_DOWN))->GetIntval(); } pNSect->DeleteIfAllowed(); // Update the Information on the page actPage.SetSectionNeighbour(actSlotNum,nCounter,actNPage,actNSlot); nCounter++; } lastPair = xList[actIndex]; actIndex++; } // Delete section Tupel if allowed pSect->DeleteIfAllowed(); //page stored back in the adjacencyList // get page, where the actual section is stored m_xAdjacencyList.Put(actPageNum-1, actPage); //Reset all used values actPageNum=0; actSlotNum=0; actPage=PageRecord(0); } // test output //of the content from xList, m_xAdjacencyList, m_xSubAdjacencyList // and all neighbourSection which are issued from GetAdjacentSections() /* cout << "Output of xList:" < actVDS; for (int i=1; i<= m_pSections->GetNoTuples();i++){ actVDS.clear(); cout << "Sec:(" << i <<",0): ["; GetAdjacentSections(i,false,actVDS); for(size_t k=0; k &inout_xPairs ) { if ( in_pFirstSection != 0 && in_pSecondSection != 0 && in_xCc.IsPossible ( in_xTransition ) ) { inout_xPairs.push_back ( DirectedSectionPair ( in_pFirstSection, in_bFirstUp, in_pSecondSection, in_bSecondUp ) ); } } /* Method ~PrintAdjacentSectionInfo~ prints informations of ~sections~ which are stored in a ~PageRecord~. first output: all ~sections~ with there sectionId and cost-value second output: all ~routes~ iterated over the startposId third output: all neighbours-information of the ~sections~ Sec (SectionTupelId,UpDownFlag):[(NeighborSectionTId, UpDownFlag, Meas1, Meas2, RId, Cost, Time)(..)] */ bool Network::PrintAdjacentSectionInfo(){ cout << "output of all Sections: (Section_SId,Section_Cost)"<< endl; for (int i =1; i<=m_pSections->GetNoTuples();i++){ Tuple *n = m_pSections->GetTuple(i,false); cout <<"("<< ((CcInt*)n->GetAttribute(SECTION_SID))->GetIntval() << "," << ((CcReal*)n->GetAttribute(SECTION_COST))->GetRealval()<< ")"<DeleteIfAllowed(); } cout << "ROUTES over startposid: (Routes_Id, Routes_StartposId)" << endl; BTreeIterator* pRoutesIt = m_pBTreeRoutesByStartposId->SelectAll(); Tuple* pRoute; while ( pRoutesIt->Next() ) { pRoute = m_pRoutes->GetTuple(pRoutesIt->GetId(),false); cout <<"("<< ((CcInt*)pRoute->GetAttribute(ROUTE_ID))->GetIntval() << "," << ((CcInt*)pRoute->GetAttribute(ROUTE_STARTPOS_ID))->GetIntval()<< ")" <DeleteIfAllowed(); } delete pRoutesIt; cout << "output all neighbours with GetAdjacentSectionsInfo" << endl; cout << "Sec:(SectionTupelId,UpDownFlag):[(NeighborSectionTId," << " UpDownFlag, Meas1, Meas2, RId, Cost, Time)(..)]" << endl; vector actVDSI; BTreeIterator* pSectionIt; pSectionIt = m_pBTreeSections->SelectAll(); while ( pSectionIt->Next() ) { actVDSI.clear(); TupleId sTid = pSectionIt->GetId(); cout << "Sec:(" << sTid <<",0): ["; GetAdjacentSectionsInfo(sTid,false,actVDSI); for(size_t k=0; k in_xList){ cout << "count all neighbours of all sections:" << endl; //Counter for neighbours, if more then nine, the counter a10 is increased int a0=0,a1=0,a2=0,a3=0,a4=0,a5=0,a6=0,a7=0,a8=0,a9=0,a10=0; int actCounter=0; DirectedSectionPair xLastPair; //determin the number of neighbours of the sections actCounter=0; //pass through all pairs for (size_t i=0; iGetNoTuples() *2) -(a1+a2+a3+a4+a5+a6+a7+a8+a9+a10); // output of the results cout << "sections without neighbours: " << a0 << endl; cout << "sections with one neighbour: " << a1 << endl; cout << "sections with two neighbours: " << a2 << endl; cout << "sections with three neighbours: " << a3 << endl; cout << "sections with four neighbours: " << a4<< endl; cout << "sections with five neighbours: " << a5 << endl; cout << "sections with six neighbours: " << a6 << endl; cout << "sections with seven neighbours: " << a7 << endl; cout << "sections with eight neighbours: " << a8 << endl; cout << "sections with nine neighbours: " << a9 << endl; cout << "sections with more than nine neighbours : " << a10 << endl; } /* Method ~InShortestPath~ */ bool Network::InShortestPath ( GPoint*start,GPoint *to, GLine *result ) { GPoint* end = new GPoint ( *to );//copy the gpoint result->Clear(); if ( start == 0 || end == 0 || !start->IsDefined() || !end->IsDefined() ) { sendMessage ( "Both gpoints must exist and be defined." ); result->SetDefined ( false ); end->DeleteIfAllowed(); return false; } // Check wether both points belong to the same network if ( start->GetNetworkId() != end->GetNetworkId() ) { sendMessage ( "Both gpoints belong to different networks." ); result->SetDefined ( false ); end->DeleteIfAllowed(); return false; } result->SetNetworkId ( GetId() ); // Get sections where the path should start or end Tuple* startSection = GetSectionOnRoute ( start ); if ( startSection == 0 ) { sendMessage ( "Starting GPoint not found in network." ); result->SetDefined ( false ); end->DeleteIfAllowed(); return false; } Tuple* endSection = GetSectionOnRoute ( end ); if ( endSection == 0 ) { sendMessage ( "End GPoint not found in network." ); startSection->DeleteIfAllowed(); result->SetDefined ( false ); end->DeleteIfAllowed(); return false; } //////////////////////////////////////////////////// bool junctionpoint = false; Point* endp = new Point(); GetPointOnRoute ( end,endp ); //end point vector juns; CcInt* routeid = new CcInt ( true,end->GetRouteId() ); GetJunctionsOnRoute ( routeid,juns ); for ( unsigned int i = 0;i < juns.size();i++ ) { Tuple* t = juns[i].m_pJunction; if ( ( ( CcInt* ) t->GetAttribute ( JUNCTION_ROUTE1_ID ) )->GetIntval() == end->GetRouteId() && fabs ( ( ( CcReal* ) t->GetAttribute ( JUNCTION_ROUTE1_MEAS ) )->GetRealval()- end->GetPosition() ) < 0.1 ) junctionpoint = true; if ( ( ( CcInt* ) t->GetAttribute ( JUNCTION_ROUTE2_ID ) )->GetIntval() == end->GetRouteId() && fabs ( ( ( CcReal* ) t->GetAttribute ( JUNCTION_ROUTE2_MEAS ) )->GetRealval()- end->GetPosition() ) < 0.1 ) junctionpoint = true; } vector secjunid; if ( junctionpoint ) //it is a junction point { vector sectionlist; if ( fabs ( end->GetPosition()- ( ( CcReal* ) endSection->GetAttribute ( SECTION_MEAS1 ) )->GetRealval() ) < 0.1 ) GetAdjacentSections ( endSection->GetTupleId(),false,sectionlist ); else GetAdjacentSections ( endSection->GetTupleId(),true,sectionlist ); for ( unsigned int i = 0;i < sectionlist.size();i++ ) { if ( sectionlist[i].GetSectionTid() != endSection->GetTupleId() ) secjunid.push_back ( sectionlist[i].GetSectionTid() ); } } endp->DeleteIfAllowed(); routeid->DeleteIfAllowed(); ///////////////////////////////////////////////////// // Calculate the shortest path using dijkstras algorithm. TupleId startSectTID = startSection->GetTupleId(); TupleId lastSectTID = endSection->GetTupleId(); if ( startSectTID == lastSectTID ) { result->AddRouteInterval ( start->GetRouteId(), start->GetPosition(), end->GetPosition() ); } else { //Initialize PriorityQueue PrioQueue *prioQ = new PrioQueue ( 0 ); SectIDTree *visitedSect = 0; double sectMeas1 = ( ( CcReal* ) startSection->GetAttribute ( SECTION_MEAS1 ) )->GetRealval(); double sectMeas2 = ( ( CcReal* ) startSection->GetAttribute ( SECTION_MEAS2 ) )->GetRealval(); double dist = 0.0; vector adjSectionList; adjSectionList.clear(); if ( start->GetSide() == 0 ) { dist = start->GetPosition() - sectMeas1; GetAdjacentSections ( startSectTID, false, adjSectionList ); SectIDTree *startTree = new SectIDTree ( startSectTID, ( TupleId ) numeric_limits::max(), false, numeric_limits::max() ); visitedSect = startTree; for ( size_t i = 0; i < adjSectionList.size(); i++ ) { DirectedSection actNextSect = adjSectionList[i]; if ( actNextSect.GetSectionTid() != startSectTID ) { PQEntry *actEntry = new PQEntry ( actNextSect.GetSectionTid(), dist, actNextSect.GetUpDownFlag(), startSectTID ); prioQ->Insert ( *actEntry, visitedSect ) ; delete actEntry; } } adjSectionList.clear(); } else { if ( start->GetSide() == 1 ) { dist = sectMeas2 - start->GetPosition(); SectIDTree *startTree = new SectIDTree ( startSectTID, ( TupleId ) numeric_limits::max(), true, numeric_limits::max() ); visitedSect = startTree; GetAdjacentSections ( startSectTID, true, adjSectionList ); for ( size_t i = 0; i < adjSectionList.size(); i++ ) { DirectedSection actNextSect = adjSectionList[i]; if ( actNextSect.GetSectionTid() != startSectTID ) { PQEntry *actEntry = new PQEntry ( actNextSect.GetSectionTid(), dist, actNextSect.GetUpDownFlag(), startSectTID ); prioQ->Insert ( *actEntry, visitedSect ); delete actEntry; } } adjSectionList.clear(); } else { dist = start->GetPosition() - sectMeas1; GetAdjacentSections ( startSectTID, false, adjSectionList ); bool first = true; for ( size_t i = 0; i < adjSectionList.size(); i++ ) { DirectedSection actNextSect = adjSectionList[i]; if ( actNextSect.GetSectionTid() != startSectTID ) { if ( first ) { first = false; SectIDTree *startTree = new SectIDTree ( startSectTID, ( TupleId ) numeric_limits::max(), false, numeric_limits::max() ); visitedSect = startTree; } PQEntry *actEntry = new PQEntry ( actNextSect.GetSectionTid(), dist, actNextSect.GetUpDownFlag(), startSectTID ); prioQ->Insert ( *actEntry, visitedSect ); delete actEntry; } } adjSectionList.clear(); dist = sectMeas2 -start->GetPosition(); GetAdjacentSections ( startSectTID, true, adjSectionList ); for ( size_t i = 0; i < adjSectionList.size(); i++ ) { DirectedSection actNextSect = adjSectionList[i]; if ( actNextSect.GetSectionTid() != startSectTID ) { if ( first ) { first = false; SectIDTree *startTree = new SectIDTree ( startSectTID, ( TupleId ) numeric_limits::max(), true, numeric_limits::max() ); visitedSect = startTree; } PQEntry *actEntry = new PQEntry ( actNextSect.GetSectionTid(), dist, actNextSect.GetUpDownFlag(), startSectTID ); prioQ->Insert ( *actEntry, visitedSect ); delete actEntry; } } adjSectionList.clear(); } } // Use priorityQueue to find shortestPath. PQEntry *actPQEntry; bool found = false; while ( !prioQ->IsEmpty() && !found ) { actPQEntry = prioQ->GetAndDeleteMin ( visitedSect ); Tuple *actSection = GetSection ( actPQEntry->sectID ); sectMeas1 = ( ( CcReal* ) actSection->GetAttribute ( SECTION_MEAS1 ) )->GetRealval(); sectMeas2 = ( ( CcReal* ) actSection->GetAttribute ( SECTION_MEAS2 ) )->GetRealval(); dist = actPQEntry->distFromStart + fabs ( sectMeas2 - sectMeas1 ); ////////////////////////////////////// if ( junctionpoint ) //end point is a junction point { for ( unsigned int i = 0;i < secjunid.size();i++ ) { if ( secjunid[i] == actPQEntry->sectID ) { lastSectTID = actPQEntry->sectID; Tuple* sect = GetSection ( lastSectTID ); double m1 = ( ( CcReal* ) sect->GetAttribute ( SECTION_MEAS1 ) )->GetRealval(); double m2 = ( ( CcReal* ) sect->GetAttribute ( SECTION_MEAS2 ) )->GetRealval(); if ( actPQEntry->upDownFlag ) { GPoint* temp = new GPoint ( true,end->GetNetworkId(), end->GetRouteId(),m2,None ); *end = *temp; temp->DeleteIfAllowed(); } else { GPoint* temp = new GPoint ( true,end->GetNetworkId(), end->GetRouteId(),m1,None ); *end = *temp; temp->DeleteIfAllowed(); } sect->DeleteIfAllowed(); break; } } } //////////////////////////////////// if ( actPQEntry->sectID != lastSectTID ) { //Search further in the network unitl reached last section. //Get adjacent sections and insert into priority Queue. adjSectionList.clear(); GetAdjacentSections ( actPQEntry->sectID, actPQEntry->upDownFlag, adjSectionList ); for ( size_t i = 0; i sectID ) { PQEntry *actEntry = new PQEntry ( actNextSect.GetSectionTid(), dist, actNextSect.GetUpDownFlag(), actPQEntry->sectID ); prioQ->Insert ( *actEntry, visitedSect ); delete actEntry; } } delete actPQEntry; actSection->DeleteIfAllowed(); } else { // Shortest Path found. // Compute last route interval and resulting gline. found = true; double startRI, endRI; int actRouteId = ( ( CcInt* ) actSection->GetAttribute ( SECTION_RID ) )->GetIntval(); if ( actPQEntry->upDownFlag == true ) { startRI = sectMeas1; endRI = end->GetPosition(); } else { startRI = sectMeas2; endRI = end->GetPosition(); } actSection->DeleteIfAllowed(); //Get the sections used for shortest path and write them in right //order (from start to end ) in the resulting gline. Because dijkstra gives //the sections from end to start we first have to put the result sections on a //stack to turn in right order. RIStack *riStack = new RIStack ( actRouteId, startRI, endRI ); TupleId lastSectId = actPQEntry->sectID; SectIDTree *pElem = visitedSect->Find ( actPQEntry->beforeSectID ); bool end = false; bool upDown; // if (startRI >= endRI) upDown = false; if ( startRI > endRI || fabs ( startRI-endRI ) < 0.1 ) upDown = false; else upDown = true; while ( !end ) { //GetSection actSection = GetSection ( pElem->sectID ); actRouteId = ( ( CcInt* ) actSection->GetAttribute ( SECTION_RID ) )->GetIntval(); sectMeas1 = ( ( CcReal* ) actSection->GetAttribute ( SECTION_MEAS1 ) )->GetRealval(); sectMeas2 = ( ( CcReal* ) actSection->GetAttribute ( SECTION_MEAS2 ) )->GetRealval(); upDown = pElem->upDownFlag; if ( pElem->sectID != startSectTID ) { if ( upDown ) riStack->Push ( actRouteId, sectMeas1, sectMeas2, riStack ); else riStack->Push ( actRouteId, sectMeas2, sectMeas1, riStack ); lastSectId = pElem->sectID; pElem = visitedSect->Find ( pElem->beforeSectId ); } else { end = true; GetAdjacentSections ( startSectTID, true, adjSectionList ); size_t i = 0; bool stsectfound = false; while ( i < adjSectionList.size() && !stsectfound ) { DirectedSection adjSection = adjSectionList[i]; if ( adjSection.GetSectionTid() == lastSectId ) { if ( fabs ( start->GetPosition()-sectMeas2 ) > 0.1 ) { stsectfound = true; riStack->Push ( actRouteId, start->GetPosition(), sectMeas2, riStack ); end = true; } } i++; } adjSectionList.clear(); if ( !stsectfound ) { GetAdjacentSections ( startSectTID, false, adjSectionList ); i = 0; while ( i < adjSectionList.size() && !stsectfound ) { DirectedSection adjSection = adjSectionList[i]; if ( adjSection.GetSectionTid() == lastSectId ) { if ( fabs ( start->GetPosition() - sectMeas1 ) > 0.1 ) { stsectfound = true; riStack->Push ( actRouteId, start->GetPosition(), sectMeas1, riStack ); end = true; } } i++; } adjSectionList.clear(); } } } // Cleanup and return result riStack->StackToGLine ( result ); riStack->RemoveStack(); delete actPQEntry; } } visitedSect->Remove(); prioQ->Destroy(); delete prioQ; } startSection->DeleteIfAllowed(); endSection->DeleteIfAllowed(); result->SetSorted ( false ); result->SetDefined ( true ); result->TrimToSize(); end->DeleteIfAllowed(); return true; }; /* Method ~FindSP~ */ void Network::FindSP ( TupleId j1,TupleId j2,double& length,GLine* res ) { res->SetNetworkId ( GetId() ); for ( int i = 1; i <= alldistance->GetNoTuples();i++ ) { Tuple* tuple = alldistance->GetTuple ( i, false ); TupleId jun1 = ( ( CcInt* ) tuple->GetAttribute ( 0 ) )->GetIntval(); TupleId jun2 = ( ( CcInt* ) tuple->GetAttribute ( 1 ) )->GetIntval(); if ( ( jun1 == j1 && jun2 == j2 ) || ( jun1 ==j2 && jun2 == j1 ) ) { length = ( ( CcReal* ) tuple->GetAttribute ( 2 ) )->GetRealval(); GLine* gline = ( GLine* ) tuple->GetAttribute ( 3 ); *res = *gline; tuple->DeleteIfAllowed(); break; } tuple->DeleteIfAllowed(); } res->TrimToSize(); } /* Method ~FillDistanceStorage~ */ void Network::FillDistanceStorage() { ListExpr xType; nl->ReadFromString ( distancestorageTypeInfo,xType ); ListExpr xNumType = SecondoSystem::GetCatalog()->NumericType ( xType ); alldistance = new Relation ( xNumType ); //store the distance between each two junction points for ( int i = 1;i <= m_pJunctions->GetNoTuples();i++ ) { for ( int j = i+1; j <= m_pJunctions->GetNoTuples();j++ ) { Tuple* jun1 = m_pJunctions->GetTuple ( i, false ); Tuple* jun2 = m_pJunctions->GetTuple ( j , false); int rid1 = ( ( CcInt* ) jun1->GetAttribute ( JUNCTION_ROUTE1_ID ) )->GetIntval(); int rid2 = ( ( CcInt* ) jun2->GetAttribute ( JUNCTION_ROUTE1_ID ) )->GetIntval(); float pos1 = ( ( CcReal* ) jun1->GetAttribute ( JUNCTION_ROUTE1_MEAS ) )->GetRealval(); float pos2 = ( ( CcReal* ) jun2->GetAttribute ( JUNCTION_ROUTE1_MEAS ) )->GetRealval(); Side side = None; Point* p1 = ( Point* ) jun1->GetAttribute ( JUNCTION_POS ); Point* p2 = ( Point* ) jun2->GetAttribute ( JUNCTION_POS ); if ( fabs ( p1->GetX()-p2->GetX() ) < 0.1 && fabs ( p1->GetY()-p2->GetY() ) < 0.1 ) //different junction point continue; GPoint* gp1 = new GPoint ( true,GetId(),rid1,pos1,side ); GPoint* gp2 = new GPoint ( true,GetId(),rid2,pos2,side ); Tuple* tuple = new Tuple ( nl->Second ( xNumType ) ); tuple->PutAttribute ( 0,new TupleIdentifier ( true,i ) ); tuple->PutAttribute ( 1,new TupleIdentifier ( true,j ) ); GLine* gline = new GLine ( 0 ); assert ( InShortestPath ( gp1,gp2,gline ) ); tuple->PutAttribute ( 2,new CcReal ( true,gline->GetLength() ) ); GLine* temp = new GLine ( 0 ); temp->SetNetworkId ( gline->GetNetworkId() ); RouteInterval ri; gline->Get ( 0,ri ); temp->AddRouteInterval ( ri );//head gline->Get ( gline->Size()-1,ri ); temp->AddRouteInterval ( ri );//tail tuple->PutAttribute ( 3,new GLine ( temp ) ); temp->DeleteIfAllowed(); gline->DeleteIfAllowed(); alldistance->AppendTuple ( tuple ); tuple->DeleteIfAllowed(); gp1->DeleteIfAllowed(); gp2->DeleteIfAllowed(); } } } /* Method ~UpdateSectionCost~ update the cost of a given ~section~ returns ~true~, if the update was successful, otherwise ~false~ */ bool Network::UpdateSectionCost(int sectId,double newCost){ BTreeIterator* pSectIter; CcInt* ciSectId = new CcInt(true,sectId); pSectIter = m_pBTreeSections->ExactMatch (ciSectId); delete ciSectId; if(pSectIter->Next()){ //get act Tuple Tuple *actSect = 0; actSect = m_pSections->GetTuple(pSectIter->GetId(), false); //save cost in the section relation vector xIndices; vector xAttrs; xIndices.push_back ( SECTION_COST ); xAttrs.push_back ( new CcReal ( true, newCost ) ); m_pSections->UpdateTuple(actSect, xIndices, xAttrs); //save cost in the PageRecord of the section // read pages und Slots int pageUp = ((CcInt* )actSect->GetAttribute(SECTION_PNO_UP))->GetIntval(); int slotUp = ((CcInt* )actSect->GetAttribute(SECTION_SLOT_UP))->GetIntval(); int pageDown = ((CcInt* )actSect->GetAttribute(SECTION_PNO_DOWN))->GetIntval(); int slotDown = ((CcInt* )actSect->GetAttribute(SECTION_SLOT_DOWN))->GetIntval(); //get the page and save cost for both entries PageRecord actPage =PageRecord(0); m_xAdjacencyList.Get(pageUp-1, actPage); actPage.SetSectionCost(slotUp, newCost); if(pageDown == pageUp){ actPage.SetSectionCost(slotDown, newCost); m_xAdjacencyList.Put(pageUp-1, actPage); }else{ m_xAdjacencyList.Put(pageUp-1, actPage); m_xAdjacencyList.Get(pageDown-1, actPage); actPage.SetSectionCost(slotDown, newCost); m_xAdjacencyList.Put(pageDown-1, actPage); } //clean up actSect->DeleteIfAllowed(); delete pSectIter; return true; } else { //errormessage sendMessage ( "the section with the given SectId must exist." ); cout << "the section " <GetNoTuples() >0){ //for each tuple of the Relation for(int i=1; i<=in_pCosts->GetNoTuples();i++){ //Get sid and cost Tuple *actTuple = 0; actTuple = in_pCosts->GetTuple(i, false); int sid = ((CcInt*)actTuple->GetAttribute(0))->GetIntval(); double cost = ((CcReal*)actTuple->GetAttribute(1))->GetRealval(); //call the function UpdateSectionCost(sid,cost) UpdateSectionCost(sid,cost); // clean up actTuple->DeleteIfAllowed(); } //DEBUG PrintAdjacentSectionInfo(); return true; }else{ sendMessage ( "the relation is empty." ); cout << "the relation is empty." <ExactMatch (ciSectId); delete ciSectId; if(pSectIter->Next()){ //get act Tuple Tuple *actSect = 0; actSect = m_pSections->GetTuple(pSectIter->GetId(), false); //save duration in the section relation vector xIndices; vector xAttrs; xIndices.push_back ( SECTION_DURATION ); xAttrs.push_back ( new CcReal ( true, newDuration ) ); m_pSections->UpdateTuple(actSect, xIndices, xAttrs); //save duration in the PageRecord of the section // read pages und Slots int pageUp = ((CcInt* )actSect->GetAttribute(SECTION_PNO_UP))->GetIntval(); int slotUp = ((CcInt* )actSect->GetAttribute(SECTION_SLOT_UP))->GetIntval(); int pageDown = ((CcInt* )actSect->GetAttribute(SECTION_PNO_DOWN))->GetIntval(); int slotDown = ((CcInt* )actSect->GetAttribute(SECTION_SLOT_DOWN))->GetIntval(); //get the page and save duration for both entries PageRecord actPage; m_xAdjacencyList.Get(pageUp-1, actPage); actPage.SetSectionDuration(slotUp, newDuration); if(pageDown == pageUp){ actPage.SetSectionDuration(slotDown, newDuration); m_xAdjacencyList.Put(pageUp-1, actPage); }else{ m_xAdjacencyList.Put(pageUp-1, actPage); m_xAdjacencyList.Get(pageDown-1, actPage); actPage.SetSectionDuration(slotDown, newDuration); m_xAdjacencyList.Put(pageDown-1, actPage); } //clean up actSect->DeleteIfAllowed(); delete pSectIter; return true; } else { //errormessage sendMessage ( "the section with the given SectId must exist." ); cout << "the section " <GetNoTuples() >0){ //for each tuple of the Relation for(int i=1; i<=in_pDurations->GetNoTuples();i++){ //Get sid and duration Tuple *actTuple = 0; actTuple = in_pDurations->GetTuple(i, false); int sid = ((CcInt*)actTuple->GetAttribute(0))->GetIntval(); double duration =((CcReal*)actTuple->GetAttribute(1))->GetRealval(); //call the function UpdateSectionDuration(sid,duration) UpdateSectionDuration(sid,duration); // clean up actTuple->DeleteIfAllowed(); } //DEBUG PrintAdjacentSectionInfo(); return true; }else{ sendMessage ( "the relation is empty." ); cout << "the relation is emplty." < EndPos ) { help = StartPos; StartPos = EndPos; EndPos = help; } }; /* Method ~ShorterConnection~ */ bool Network::ShorterConnection ( Tuple *route, double &start, double &end, double &dpos, double &dpos2, int &rid, int &ridt, Point p1, Point p2 ) { if ( AlmostEqual ( p1.Distance ( p2 ), fabs ( end-start ) ) ) return false; double difference; GPoint *gp = new GPoint ( true, GetId(), route->GetTupleId(), end - 0.01 ); TupleId pSection1 = GetTupleIdSectionOnRoute ( gp ); gp->DeleteIfAllowed(); vector pAdjSect1; vector pAdjSect2; pAdjSect1.clear(); pAdjSect2.clear(); GetAdjacentSections ( pSection1,true, pAdjSect1 ); GetAdjacentSections ( pSection1,false, pAdjSect2 ); if ( pAdjSect1.size() == 0 || pAdjSect2.size() == 0 ) { pAdjSect1.clear(); pAdjSect2.clear(); return false; } else { size_t j = 0; while ( j < pAdjSect1.size() ) { DirectedSection actSection = pAdjSect1[j]; Tuple *pCurrSect = m_pSections->GetTuple ( actSection.GetSectionTid(), false ); ridt = ( ( CcInt* ) pCurrSect->GetAttribute ( SECTION_RID ) )->GetIntval(); pCurrSect->DeleteIfAllowed(); if ( ridt != rid ) { Tuple *pRoute = GetRoute ( ridt ); SimpleLine *pCurve = ( SimpleLine* ) pRoute->GetAttribute ( ROUTE_CURVE ); if ( ( chkPoint ( pCurve, p1, true, dpos, difference ) ) && ( chkPoint ( pCurve, p2, true, dpos2, difference ) ) ) { pAdjSect1.clear(); pAdjSect2.clear(); chkStartEndA ( dpos, dpos2 ); pRoute->DeleteIfAllowed(); if ( fabs ( dpos2 - dpos ) < fabs ( end - start ) ) return true; else return false; } pRoute->DeleteIfAllowed(); } j++; } pAdjSect1.clear(); j = 0; while ( j < pAdjSect2.size() ) { DirectedSection actSection = pAdjSect2[j]; Tuple *pCurrSect = m_pSections->GetTuple ( actSection.GetSectionTid(), false ); ridt = ( ( CcInt* ) pCurrSect->GetAttribute ( SECTION_RID ) )->GetIntval(); pCurrSect->DeleteIfAllowed(); if ( ridt != rid ) { Tuple *pRoute = GetRoute ( ridt ); SimpleLine *pCurve = ( SimpleLine* ) pRoute->GetAttribute ( ROUTE_CURVE ); if ( ( chkPoint ( pCurve, p1, true, dpos, difference ) ) && ( chkPoint ( pCurve, p2, true, dpos2, difference ) ) ) { pAdjSect2.clear(); chkStartEndA ( dpos, dpos2 ); pRoute->DeleteIfAllowed(); if ( fabs ( dpos2-dpos ) < fabs ( end - start ) ) return true; else return false; } pRoute->DeleteIfAllowed(); } j++; } return false; } } /* Method ~ShorterConnection2~ */ bool Network::ShorterConnection2 ( Tuple *route, double &start, double &end, double &dpos, double &dpos2, int &rid, int &ridt, Point p1, Point p2 ) { if ( AlmostEqual ( p1.Distance ( p2 ), fabs ( end-start ) ) ) return false; double difference = 0.0; if ( start < end && end > 0.01 ) difference = end - 0.01; else if ( start < end && end <= 0.01 ) difference = 0.01; else if ( start > end ) difference = end + 0.01; else difference = end; //start == end GPoint *gp = new GPoint ( true, GetId(), route->GetTupleId(), difference ); TupleId pSection1 = GetTupleIdSectionOnRoute ( gp ); gp->DeleteIfAllowed(); vector pAdjSect1; vector pAdjSect2; pAdjSect1.clear(); pAdjSect2.clear(); GetAdjacentSections ( pSection1,true, pAdjSect1 ); GetAdjacentSections ( pSection1,false, pAdjSect2 ); if ( pAdjSect1.size() == 0 || pAdjSect2.size() == 0 ) { pAdjSect1.clear(); pAdjSect2.clear(); return false; } else { size_t j = 0; while ( j < pAdjSect1.size() ) { DirectedSection actSection = pAdjSect1[j]; Tuple *pCurrSect = m_pSections->GetTuple ( actSection.GetSectionTid(), false ); ridt = ( ( CcInt* ) pCurrSect->GetAttribute ( SECTION_RID ) )->GetIntval(); pCurrSect->DeleteIfAllowed(); if ( ridt != rid ) { Tuple *pRoute = GetRoute ( ridt ); SimpleLine *pCurve = ( SimpleLine* ) pRoute->GetAttribute ( ROUTE_CURVE ); if ( ( chkPoint ( pCurve, p1, true, dpos, difference ) ) && ( chkPoint ( pCurve, p2, true, dpos2, difference ) ) ) { pAdjSect1.clear(); pAdjSect2.clear(); pRoute->DeleteIfAllowed(); if ( fabs ( dpos2 - dpos ) < fabs ( end - start ) ) return true; else return false; } pRoute->DeleteIfAllowed(); } j++; } pAdjSect1.clear(); j = 0; while ( j < pAdjSect2.size() ) { DirectedSection actSection = pAdjSect2[j]; Tuple *pCurrSect = m_pSections->GetTuple ( actSection.GetSectionTid(), false ); ridt = ( ( CcInt* ) pCurrSect->GetAttribute ( SECTION_RID ) )->GetIntval(); pCurrSect->DeleteIfAllowed(); if ( ridt != rid ) { Tuple *pRoute = GetRoute ( ridt ); SimpleLine *pCurve = ( SimpleLine* ) pRoute->GetAttribute ( ROUTE_CURVE ); if ( ( chkPoint ( pCurve, p1, true, dpos, difference ) ) && ( chkPoint ( pCurve, p2, true, dpos2, difference ) ) ) { pAdjSect2.clear(); pRoute->DeleteIfAllowed(); if ( fabs ( dpos2-dpos ) < fabs ( end - start ) ) return true; else return false; } pRoute->DeleteIfAllowed(); } j++; } return false; } } /* Method ~Find~ Searches the route interval between the two given point values. */ RouteInterval* Network::Find ( Point p1, Point p2 ) { GPoint *gpp1 = GetNetworkPosOfPoint ( p1 ); GPoint *gpp2 = GetNetworkPosOfPoint ( p2 ); assert ( gpp1->IsDefined() && gpp2->IsDefined() ); int rid, ridt; double start, end, dpos, dpos2, difference; if ( gpp1->GetRouteId() == gpp2->GetRouteId() ) { rid = gpp1->GetRouteId(); start = gpp1->GetPosition(); end = gpp2->GetPosition(); chkStartEndA ( start,end ); Tuple *pRoute = GetRoute ( rid ); if ( ShorterConnection ( pRoute, start, end, dpos, dpos2, rid, ridt, p1, p2 ) ) { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( ridt, dpos, dpos2 ); } else { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( rid, start, end ); } } else // different RouteIds { Tuple *pRoute = GetRoute ( gpp1->GetRouteId() ); SimpleLine *pCurve = ( SimpleLine* ) pRoute->GetAttribute ( ROUTE_CURVE ); if ( chkPoint ( pCurve, p2, true, dpos, difference ) ) { rid = ( ( CcInt* ) pRoute->GetAttribute ( ROUTE_ID ) )->GetIntval(); start = gpp1->GetPosition(); end = dpos; chkStartEndA ( start, end ); if ( ShorterConnection ( pRoute, start, end, dpos, dpos2, rid, ridt, p1, p2 ) ) { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( ridt, dpos, dpos2 ); } else { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( rid, start, end ); } } pRoute->DeleteIfAllowed(); pRoute = GetRoute ( gpp2->GetRouteId() ); pCurve = ( SimpleLine* ) pRoute->GetAttribute ( ROUTE_CURVE ); if ( chkPoint ( pCurve, p1, true, dpos, difference ) ) { rid = ( ( CcInt* ) pRoute->GetAttribute ( ROUTE_ID ) )->GetIntval(); start = gpp2->GetPosition(); end = dpos; chkStartEndA ( start, end ); if ( ShorterConnection ( pRoute, start, end, dpos, dpos2, rid, ridt, p1, p2 ) ) { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( ridt, dpos, dpos2 ); } else { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( rid, start, end ); } } pRoute->DeleteIfAllowed(); TupleId pSection = GetTupleIdSectionOnRoute ( gpp1 ); vector pAdjSect1; vector pAdjSect2; pAdjSect1.clear(); pAdjSect2.clear(); GetAdjacentSections ( pSection,true, pAdjSect1 ); GetAdjacentSections ( pSection,false, pAdjSect2 ); size_t j = 0; Tuple *pCurrSect; while ( j < pAdjSect1.size() ) { DirectedSection actSection = pAdjSect1[j]; pCurrSect = m_pSections->GetTuple ( actSection.GetSectionTid(), false ); rid = ( ( CcInt* ) pCurrSect->GetAttribute ( SECTION_RID ) )->GetIntval(); pCurrSect->DeleteIfAllowed(); pRoute = GetRoute ( rid ); pCurve = ( SimpleLine* ) pRoute->GetAttribute ( ROUTE_CURVE ); if ( ( chkPoint ( pCurve, p1, true, dpos, difference ) ) && ( chkPoint ( pCurve, p2, true, dpos2, difference ) ) ) { start = dpos; end = dpos2; chkStartEndA ( start, end ); pAdjSect1.clear(); pAdjSect2.clear(); if ( ShorterConnection ( pRoute, start, end, dpos, dpos2, rid, ridt, p1, p2 ) ) { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( ridt, dpos, dpos2 ); } else { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( rid, start, end ); } } j++; pRoute->DeleteIfAllowed(); } j = 0; pAdjSect1.clear(); while ( j < pAdjSect2.size() ) { DirectedSection actSection = pAdjSect2[j]; pCurrSect = m_pSections->GetTuple ( actSection.GetSectionTid(), false ); rid = ( ( CcInt* ) pCurrSect->GetAttribute ( SECTION_RID ) )->GetIntval(); pCurrSect->DeleteIfAllowed(); pRoute = GetRoute ( rid ); pCurve = ( SimpleLine* ) pRoute->GetAttribute ( ROUTE_CURVE ); if ( ( chkPoint ( pCurve, p1, true, dpos, difference ) ) && ( chkPoint ( pCurve, p2, true, dpos2, difference ) ) ) { start = dpos; end = dpos2; chkStartEndA ( start, end ); pAdjSect2.clear(); if ( ShorterConnection ( pRoute, start, end, dpos, dpos2, rid, ridt, p1, p2 ) ) { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( ridt, dpos, dpos2 ); } else { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( rid, start, end ); } } j++; pRoute->DeleteIfAllowed(); }//should never be reached pAdjSect2.clear(); }//should never be reached gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); return 0; } /* Method ~FindInterval~ Returns the route interval for the connection from p1 to p2 */ RouteInterval* Network::FindInterval ( Point p1, Point p2 ) { GPoint *gpp1 = GetNetworkPosOfPoint ( p1 ); GPoint *gpp2 = GetNetworkPosOfPoint ( p2 ); assert ( gpp1->IsDefined() && gpp2->IsDefined() ); int rid, ridt; double start, end, dpos, dpos2, difference; if ( gpp1->GetRouteId() == gpp2->GetRouteId() ) { rid = gpp1->GetRouteId(); start = gpp1->GetPosition(); end = gpp2->GetPosition(); Tuple *pRoute = GetRoute ( rid ); if ( ShorterConnection2 ( pRoute, start, end, dpos, dpos2, rid, ridt, p1, p2) ) { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( ridt, dpos, dpos2 ); } else { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( rid, start, end ); } } else { Tuple *pRoute = GetRoute ( gpp1->GetRouteId() ); SimpleLine *pCurve = ( SimpleLine* ) pRoute->GetAttribute ( ROUTE_CURVE ); if ( chkPoint ( pCurve, p2, true, dpos, difference ) ) { rid = ( ( CcInt* ) pRoute->GetAttribute ( ROUTE_ID ) )->GetIntval(); start = gpp1->GetPosition(); end = dpos; if ( ShorterConnection2 ( pRoute, start, end, dpos, dpos2, rid, ridt, p1, p2 ) ) { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( ridt, dpos, dpos2 ); } else { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( rid, start, end ); } } pRoute->DeleteIfAllowed(); pRoute = GetRoute ( gpp2->GetRouteId() ); pCurve = ( SimpleLine* ) pRoute->GetAttribute ( ROUTE_CURVE ); if ( chkPoint ( pCurve, p1, true, dpos, difference ) ) { rid = ( ( CcInt* ) pRoute->GetAttribute ( ROUTE_ID ) )->GetIntval(); start = dpos; end = gpp2->GetPosition(); if ( ShorterConnection2 ( pRoute, start, end, dpos, dpos2, rid, ridt, p1, p2 ) ) { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( ridt, dpos, dpos2 ); } else { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( rid, start, end ); } } pRoute->DeleteIfAllowed(); TupleId pSection = GetTupleIdSectionOnRoute ( gpp1 ); vector pAdjSect1; vector pAdjSect2; pAdjSect1.clear(); pAdjSect2.clear(); GetAdjacentSections ( pSection,true, pAdjSect1 ); GetAdjacentSections ( pSection,false, pAdjSect2 ); size_t j = 0; Tuple *pCurrSect; while ( j < pAdjSect1.size() ) { DirectedSection actSection = pAdjSect1[j]; pCurrSect = m_pSections->GetTuple ( actSection.GetSectionTid(), false ); rid = ( ( CcInt* ) pCurrSect->GetAttribute ( SECTION_RID ) )->GetIntval(); pCurrSect->DeleteIfAllowed(); pRoute = GetRoute ( rid ); pCurve = ( SimpleLine* ) pRoute->GetAttribute ( ROUTE_CURVE ); if ( ( chkPoint ( pCurve, p1, true, dpos, difference ) ) && ( chkPoint ( pCurve, p2, true, dpos2, difference ) ) ) { start = dpos; end = dpos2; pAdjSect1.clear(); pAdjSect2.clear(); if ( ShorterConnection2 ( pRoute, start, end, dpos, dpos2, rid, ridt, p1, p2 ) ) { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( ridt, dpos, dpos2 ); } else { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( rid, start, end ); } } j++; pRoute->DeleteIfAllowed(); } j = 0; pAdjSect1.clear(); while ( j < pAdjSect2.size() ) { DirectedSection actSection = pAdjSect2[j]; pCurrSect = m_pSections->GetTuple ( actSection.GetSectionTid(), false ); rid = ( ( CcInt* ) pCurrSect->GetAttribute ( SECTION_RID ) )->GetIntval(); pCurrSect->DeleteIfAllowed(); pRoute = GetRoute ( rid ); pCurve = ( SimpleLine* ) pRoute->GetAttribute ( ROUTE_CURVE ); if ( ( chkPoint ( pCurve, p1, true, dpos, difference ) ) && ( chkPoint ( pCurve, p2, true, dpos2, difference ) ) ) { start = dpos; end = dpos2; pAdjSect2.clear(); if ( ShorterConnection2 ( pRoute, start, end, dpos, dpos2, rid, ridt, p1, p2 ) ) { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( ridt, dpos, dpos2 ); } else { gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); pRoute->DeleteIfAllowed(); return new RouteInterval ( rid, start, end ); } } j++; pRoute->DeleteIfAllowed(); }//should never be reached pAdjSect2.clear(); }//should never be reached gpp1->DeleteIfAllowed(); gpp2->DeleteIfAllowed(); return 0; } /* Get-Methodes of network parameters. ~GetId~, ~GetRoutes~, ~GetJunctions~, ~GetJunctionsOnRoute~, ~GetSection~, ~GetTupleIdSectionOnRoute~, ~GetTupleIdSectionOnRoute~, ~GetSectionOnRoute~, ~GetRoute~, ~GetSectionsOfRouteInterval~, ~GetSectionsOfRoutInterval~, ~GetPointOnRoute~, ~GetSectionsInternal~, ~GetSections~, ~GetAdjacentSectionsInfo~, ~GetAdjacentSections~, ~GetRouteCurve~, ~GetDual~, ~GetTupleIdSectionOnRouteJun~, ~GetNetworkPosOfPoint~, ~GetJunctionMeasForRoutes~, ~GetLineValueOfRouteInterval~ */ int Network::GetId() { return m_iId; } Relation *Network::GetRoutes() { return m_pRoutes; /* ostringstream strRoutesPtr; strRoutesPtr << ( long ) m_pRoutes; string querystring = "(consume (feed (" + routesTypeInfo + " (ptr " + strRoutesPtr.str() + "))))"; Word resultWord; int QueryExecuted = QueryProcessor::ExecuteQuery ( querystring, resultWord ); assert ( QueryExecuted ); // no ASSERT with side effects, please return ( Relation * ) resultWord.addr;*/ } Relation *Network::GetJunctions() { ostringstream strJunctionsPtr; strJunctionsPtr << ( long ) m_pJunctions; string querystring = "(consume (feed (" + junctionsInternalTypeInfo + " (ptr " + strJunctionsPtr.str() + "))))"; Word resultWord; int QueryExecuted = QueryProcessor::ExecuteQuery ( querystring, resultWord ); assert ( QueryExecuted ); // no ASSERT with side effects, please return ( Relation * ) resultWord.addr; } void Network::GetJunctionsOnRoute ( CcInt* in_pRouteId, vector &inout_xJunctions ) { BTreeIterator* pJunctionsIt; pJunctionsIt = m_pBTreeJunctionsByRoute1->ExactMatch ( in_pRouteId ); while ( pJunctionsIt->Next() ) { // Get next junction Tuple* pCurrentJunction = m_pJunctions->GetTuple ( pJunctionsIt->GetId(), false ); inout_xJunctions.push_back ( JunctionSortEntry ( true, pCurrentJunction ) ); } delete pJunctionsIt; // Now we look up the second b-tree pJunctionsIt = m_pBTreeJunctionsByRoute2->ExactMatch ( in_pRouteId ); while ( pJunctionsIt->Next() ) { Tuple* pCurrentJunction = m_pJunctions->GetTuple ( pJunctionsIt->GetId(), false ); inout_xJunctions.push_back ( JunctionSortEntry ( false, pCurrentJunction ) ); } delete pJunctionsIt; // The junctions will be sorted by their mesure on the relevant route. sort ( inout_xJunctions.begin(), inout_xJunctions.end() ); } Tuple* Network::GetSection ( TupleId n ) { return m_pSections->GetTuple ( n, false ); } TupleId Network::GetTupleIdSectionOnRoute ( GPoint* in_xGPoint ) { CcInt *ciRouteId = new CcInt ( true, in_xGPoint->GetRouteId() ); BTreeIterator* pSectionIter = m_pBTreeSectionsByRoute->ExactMatch ( ciRouteId ); ciRouteId->DeleteIfAllowed(); Tuple *actSect = 0; TupleId result; while ( pSectionIter->Next() ) { result = pSectionIter->GetId(); actSect = m_pSections->GetTuple ( pSectionIter->GetId(), false ); if ( actSect != 0 ) { double start = ( ( CcReal* ) actSect->GetAttribute ( SECTION_MEAS1 ) )->GetRealval(); double end = ( ( CcReal* ) actSect->GetAttribute ( SECTION_MEAS2 ) )->GetRealval(); if ( in_xGPoint->GetPosition() >= start&&in_xGPoint->GetPosition() <= end ) { delete pSectionIter; actSect->DeleteIfAllowed(); return result; } else { if ( fabs ( in_xGPoint->GetPosition() - start ) <= 0.01 ) { delete pSectionIter; actSect->DeleteIfAllowed(); return result; } else { if ( fabs ( in_xGPoint->GetPosition() - end ) <= 0.01 ) { Tuple *pRoute = GetRoute ( ( ( TupleIdentifier* ) actSect->GetAttribute ( SECTION_RRC ) )->GetTid() ); if ( fabs ( ( ( CcReal* ) pRoute->GetAttribute ( ROUTE_LENGTH ) )->GetRealval() - end ) <= 0.01 ) { pRoute->DeleteIfAllowed(); delete pSectionIter; actSect->DeleteIfAllowed(); return result; } else { pRoute->DeleteIfAllowed(); } } } } actSect->DeleteIfAllowed(); } } delete pSectionIter; return 0; } Tuple* Network::GetSectionOnRoute ( GPoint* in_xGPoint ) { return GetSection ( GetTupleIdSectionOnRoute ( in_xGPoint ) ); /* New implementation using sectionsBTree CcInt *ciRouteId = new CcInt(true, in_xGPoint->GetRouteId()); BTreeIterator* pSectionIter = m_pBTreeSectionsByRoute->ExactMatch(ciRouteId); ciRouteId->DeleteIfAllowed(); Tuple *actSect = 0; while (pSectionIter->Next()){ actSect = m_pSections->GetTuple(pSectionIter->GetId()); if(actSect != 0){ double start = ((CcReal*)actSect->GetAttribute(SECTION_MEAS1))->GetRealval(); double end = ((CcReal*) actSect->GetAttribute(SECTION_MEAS2))->GetRealval(); if (in_xGPoint->GetPosition() >= start&&in_xGPoint->GetPosition() <= end) { delete pSectionIter; return actSect; } else { if (fabs(in_xGPoint->GetPosition() - start) <= 0.01) { delete pSectionIter; return actSect; } else { if (fabs(in_xGPoint->GetPosition() - end) <= 0.01) { Tuple *pRoute = GetRoute(((TupleIdentifier*) actSect->GetAttribute(SECTION_RRC))->GetTid()); if (fabs(((CcReal*) pRoute->GetAttribute(ROUTE_LENGTH))->GetRealval() - end) <= 0.01){ pRoute->DeleteIfAllowed(); delete pSectionIter; return actSect; } else { pRoute->DeleteIfAllowed(); } } } } actSect->DeleteIfAllowed(); } } delete pSectionIter; return 0; vector xJunctions; CcInt xRouteId(true, in_xGPoint->GetRouteId()); GetJunctionsOnRoute(&xRouteId, xJunctions); // Now that we found all relevant junctions we can iterate over them. int iSectionId = 0; double juncpos; for(size_t i = 0; i < xJunctions.size(); i++) { // Get next junction JunctionSortEntry xCurrentEntry = xJunctions[i]; iSectionId = xCurrentEntry.GetDownSectionId(); juncpos = xCurrentEntry.GetRouteMeas(); if(juncpos > in_xGPoint->GetPosition()) { break; } if (juncpos != 0 && fabs(juncpos - in_xGPoint->GetPosition()) < 0.01){ break; } iSectionId = xCurrentEntry.GetUpSectionId(); } for(size_t i = 0; i < xJunctions.size(); i++) { // Get next junction JunctionSortEntry xCurrentEntry = xJunctions[i]; xCurrentEntry.m_pJunction->DeleteIfAllowed(); } if(iSectionId == 0) return 0; else return m_pSections->GetTuple(iSectionId); */ } Tuple* Network::GetRoute ( int in_RouteId ) { CcInt* pRouteId = new CcInt ( true, in_RouteId ); BTreeIterator *pRoutesIter = m_pBTreeRoutes->ExactMatch ( pRouteId ); pRouteId->DeleteIfAllowed(); Tuple *pRoute = 0; if ( pRoutesIter->Next() ) pRoute = m_pRoutes->GetTuple ( pRoutesIter->GetId() , false); assert ( pRoute != 0 ); delete pRoutesIter; return pRoute; } Tuple* Network::GetRoute ( TupleId in_routeTID ) { return m_pRoutes->GetTuple ( in_routeTID, false ); } void Network::GetSectionsOfRouteInterval ( const RouteInterval *ri, DbArray *io_SectionIds ) { double ristart = min ( ri->GetStartPos(), ri->GetEndPos() ); double riend = max ( ri->GetStartPos(), ri->GetEndPos() ); CcInt* ciRouteId = new CcInt ( true, ri->GetRouteId() ); BTreeIterator* pSectionIter = m_pBTreeSectionsByRoute->ExactMatch ( ciRouteId ); ciRouteId->DeleteIfAllowed(); Tuple *actSect; TupleId actSectTID; bool bsectstart = true; bool bsectend = true; while ( pSectionIter->Next() ) { actSectTID = pSectionIter->GetId(); actSect = m_pSections->GetTuple ( actSectTID, false ); assert ( actSect != 0 ); double start = ( ( CcReal* ) actSect->GetAttribute ( SECTION_MEAS1 ) )->GetRealval(); double end = ( ( CcReal* ) actSect->GetAttribute ( SECTION_MEAS2 ) )->GetRealval(); if ( ( ristart <= start && riend >= end ) || ( start <= ristart && end >= ristart ) || ( start <= riend && end >= riend ) ) { if ( start <= ristart ) { start = ristart; bsectstart = false; } if ( riend <= end ) { end = riend; bsectend = false; } SectTreeEntry *sect = new SectTreeEntry ( actSect->GetTupleId(), ri->GetRouteId(), start, end, bsectstart, bsectend ); io_SectionIds->Append ( *sect ); delete sect; if ( riend <= end ) { actSect->DeleteIfAllowed(); break; } } actSect->DeleteIfAllowed(); } io_SectionIds->TrimToSize(); delete pSectionIter; }; void Network::GetSectionsOfRoutInterval ( const RouteInterval *ri, vector &res ) { res.clear(); double ristart = min ( ri->GetStartPos(), ri->GetEndPos() ); double riend = max ( ri->GetStartPos(), ri->GetEndPos() ); CcInt* ciRouteId = new CcInt ( true, ri->GetRouteId() ); BTreeIterator* pSectionIter = m_pBTreeSectionsByRoute->ExactMatch ( ciRouteId ); ciRouteId->DeleteIfAllowed(); Tuple *actSect; TupleId actSectTID; //bool bsectstart = true; //bool bsectend = true; while ( pSectionIter->Next() ) { actSectTID = pSectionIter->GetId(); actSect = m_pSections->GetTuple ( actSectTID, false ); assert ( actSect != 0 ); double start = ( ( CcReal* ) actSect->GetAttribute ( SECTION_MEAS1 ) )->GetRealval(); double end = ( ( CcReal* ) actSect->GetAttribute ( SECTION_MEAS2 ) )->GetRealval(); if ( fabs ( ristart - riend ) <= 0.01 && ( fabs ( ristart - start ) <= 0.01 || fabs ( ristart - end ) <= 0.01 ) ) { res.push_back ( actSectTID ); actSect->DeleteIfAllowed(); break; } else { if ( ( ( ristart <= start && end <= riend ) || ( start <= ristart && end > ristart ) || ( start < riend && riend <= end ) ) && ( ! ( fabs ( ristart - end ) <= 0.01 || fabs ( start - riend ) <= 0.01 ) ) ) res.push_back ( actSectTID ); } actSect->DeleteIfAllowed(); } delete pSectionIter; } void Network::GetPointOnRoute ( const GPoint* in_pGPoint, Point*& res ) { /*Point *res = new Point(false);*/ CcInt* pRouteId = new CcInt ( true, in_pGPoint->GetRouteId() ); BTreeIterator* pRoutesIter = m_pBTreeRoutes->ExactMatch ( pRouteId ); pRouteId->DeleteIfAllowed(); Tuple *pRoute = 0; if ( pRoutesIter->Next() ) pRoute = m_pRoutes->GetTuple ( pRoutesIter->GetId(), false ); assert ( pRoute != 0 ); SimpleLine* pLine = ( SimpleLine* ) pRoute->GetAttribute ( ROUTE_CURVE ); assert ( pLine != 0 ); pLine->AtPosition ( in_pGPoint->GetPosition(),true, *res ); pRoute->DeleteIfAllowed(); delete pRoutesIter; /*return res;*/ } Relation* Network::GetSectionsInternal() { return m_pSections; } Relation* Network::GetSections() { ostringstream strSectionsPtr; strSectionsPtr << ( long ) m_pSections; string querystring = "(consume (feed (" + sectionsInternalTypeInfo + " (ptr " + strSectionsPtr.str() + "))))"; Word resultWord; int QueryExecuted = QueryProcessor::ExecuteQuery ( querystring, resultWord ); assert ( QueryExecuted ); // No ASSERT with side effect, please! return ( Relation * ) resultWord.addr; } void Network::GetAdjacentSectionsInfo ( TupleId in_iSectionTId, bool in_bUpDown, vector &inout_xSections ) { inout_xSections.clear(); Tuple *pSect = GetSection ( in_iSectionTId ); if ( pSect != 0 ) { // get Sid, SectionPage and SectionSlot int iSectionPage, iSectionSlot; if (in_bUpDown){ iSectionPage=((CcInt*)pSect->GetAttribute(SECTION_PNO_UP))->GetIntval(); iSectionSlot=((CcInt*)pSect->GetAttribute(SECTION_SLOT_UP))->GetIntval(); }else{ iSectionPage=((CcInt*)pSect->GetAttribute(SECTION_PNO_DOWN))->GetIntval(); iSectionSlot=((CcInt*)pSect->GetAttribute(SECTION_SLOT_DOWN))->GetIntval(); } pSect->DeleteIfAllowed(); if(iSectionPage != 0 && iSectionSlot !=0){ //getSectionPage PageRecord xPage; m_xAdjacencyList.Get ( iSectionPage-1, xPage ); //get Number of Neighbours int iNeighbours=0; xPage.GetSectionNoNeighbours(iSectionSlot, iNeighbours); //Cache for Pages and Slots defined int **iPagesSlots; iPagesSlots = new int* [iNeighbours]; for (int i=0; i &inout_xSections ) { inout_xSections.clear(); Tuple *pSect = GetSection ( in_iSectionTId ); if ( pSect != 0 ) { // get Sid, SectionPage and SectionSlot int iSectionPage, iSectionSlot; if (in_bUpDown){ iSectionPage =((CcInt*)pSect->GetAttribute(SECTION_PNO_UP))->GetIntval(); iSectionSlot =((CcInt*)pSect->GetAttribute(SECTION_SLOT_UP))->GetIntval(); }else{ iSectionPage =((CcInt*)pSect->GetAttribute(SECTION_PNO_DOWN))->GetIntval(); iSectionSlot=((CcInt*)pSect->GetAttribute(SECTION_SLOT_DOWN))->GetIntval(); } pSect->DeleteIfAllowed(); if(iSectionPage != 0 && iSectionSlot !=0){ //getSectionPage PageRecord xPage; m_xAdjacencyList.Get ( iSectionPage-1, xPage ); //get Number of Neighbours int iNeighbours=0; xPage.GetSectionNoNeighbours(iSectionSlot, iNeighbours); //Cache for Pages and Slots defined int **iPagesSlots; iPagesSlots = new int* [iNeighbours]; for (int i=0; iGetAttribute ( ROUTE_CURVE ) ); pRoute->DeleteIfAllowed(); return sl; } bool Network::GetDual ( int in_iRouteId ) { Tuple *pRoute = GetRoute ( in_iRouteId ); bool dual = ( ( CcBool* ) pRoute->GetAttribute ( ROUTE_DUAL ) )->GetBoolval(); pRoute->DeleteIfAllowed(); return dual; } void Network::GetTupleIdSectionOnRouteJun(GPoint* in_xGPoint, vector& res) { CcInt *ciRouteId = new CcInt ( true, in_xGPoint->GetRouteId() ); BTreeIterator* pSectionIter = m_pBTreeSectionsByRoute->ExactMatch ( ciRouteId ); delete ciRouteId; Tuple *actSect = 0; TupleId result; while ( pSectionIter->Next() ) { result = pSectionIter->GetId(); actSect = m_pSections->GetTuple ( pSectionIter->GetId(), false ); if ( actSect != 0 ) { double start = ((CcReal*)actSect->GetAttribute(SECTION_MEAS1))->GetRealval(); double end = ((CcReal*)actSect->GetAttribute(SECTION_MEAS2))->GetRealval(); if(in_xGPoint->GetPosition() >= start&&in_xGPoint->GetPosition() <= end) { // delete pSectionIter; // actSect->DeleteIfAllowed(); // return result; res.push_back(result); } else { if ( fabs ( in_xGPoint->GetPosition() - start ) <= 0.01 ) { // delete pSectionIter; // actSect->DeleteIfAllowed(); // return result; res.push_back(result); } else { if ( fabs ( in_xGPoint->GetPosition() - end ) <= 0.01 ) { Tuple *pRoute = GetRoute(((TupleIdentifier* ) actSect->GetAttribute ( SECTION_RRC ))->GetTid() ); if ( fabs ( ( ( CcReal* ) pRoute->GetAttribute ( ROUTE_LENGTH ) )->GetRealval() - end ) <= 0.01 ) { // pRoute->DeleteIfAllowed(); // delete pSectionIter; // actSect->DeleteIfAllowed(); res.push_back(result); // return result; } pRoute->DeleteIfAllowed(); } } } // actSect->DeleteIfAllowed(); } actSect->DeleteIfAllowed(); } delete pSectionIter; } GPoint* Network::GetNetworkPosOfPoint ( Point p ) { const Rectangle<2> orig = p.BoundingBox(); double minMax[] = {orig.MinD ( 0 ) - 1.0, orig.MaxD ( 0 ) + 1.0, orig.MinD ( 1 ) - 1.0, orig.MaxD ( 1 ) + 1.0 }; const Rectangle<2> bbox = Rectangle<2> ( true,minMax); R_TreeLeafEntry<2,TupleId> res; Tuple *pCurrRoute = 0; if ( m_pRTreeRoutes->First ( bbox, res ) ) { pCurrRoute = m_pRoutes->GetTuple ( res.info, false ); // pCurrRoute->PutAttribute(0, new TupleIdentifier(true, res.info)); } else { GPoint *result = new GPoint ( false ); pCurrRoute->DeleteIfAllowed(); return result; } double dpos, difference; SimpleLine* pRouteCurve = ( SimpleLine* ) pCurrRoute->GetAttribute ( ROUTE_CURVE ); if ( chkPoint ( pRouteCurve, p, true, dpos, difference ) ) { int rid = ( ( CcInt* ) pCurrRoute->GetAttribute ( ROUTE_ID ) )->GetIntval(); GPoint *result = new GPoint ( true, GetId(), rid, dpos, None ); pCurrRoute->DeleteIfAllowed(); return result; } else { pCurrRoute->DeleteIfAllowed(); while ( m_pRTreeRoutes->Next ( res ) ) { pCurrRoute = m_pRoutes->GetTuple ( res.info, false ); pRouteCurve = ( SimpleLine* ) pCurrRoute->GetAttribute ( ROUTE_CURVE ); if ( chkPoint ( pRouteCurve, p, true, dpos, difference ) ) { int rid = ( ( CcInt* ) pCurrRoute->GetAttribute ( ROUTE_ID ) )->GetIntval(); GPoint *result = new GPoint ( true, GetId(), rid, dpos, None ); pCurrRoute->DeleteIfAllowed(); return result; } pCurrRoute->DeleteIfAllowed(); } /* If the point exact hits a route the route should be found here. If the point value is not exact on the route curve we try to map it in the next step with bigger tolerance for the hit of the route curve. */ if ( m_pRTreeRoutes->First ( bbox, res ) ) pCurrRoute = m_pRoutes->GetTuple ( res.info, false ); pRouteCurve = ( SimpleLine* ) pCurrRoute->GetAttribute ( ROUTE_CURVE ); if ( chkPoint03 ( pRouteCurve, p, true, dpos, difference ) ) { int rid = ( ( CcInt* ) pCurrRoute->GetAttribute ( ROUTE_ID ) )->GetIntval(); GPoint *result = new GPoint ( true, GetId(), rid, dpos, None ); pCurrRoute->DeleteIfAllowed(); return result; } else { pCurrRoute->DeleteIfAllowed(); while ( m_pRTreeRoutes->Next ( res ) ) { pCurrRoute = m_pRoutes->GetTuple ( res.info , false); pRouteCurve = ( SimpleLine* ) pCurrRoute->GetAttribute ( ROUTE_CURVE ); if ( chkPoint03 ( pRouteCurve, p, true, dpos, difference ) ) { int rid = ( ( CcInt* ) pCurrRoute->GetAttribute ( ROUTE_ID ) )->GetIntval(); GPoint *result = new GPoint ( true, GetId(), rid, dpos, None ); pCurrRoute->DeleteIfAllowed(); return result; } pCurrRoute->DeleteIfAllowed(); } } if ( m_pRTreeRoutes->First ( bbox, res ) ) pCurrRoute = m_pRoutes->GetTuple ( res.info, false ); pRouteCurve = ( SimpleLine* ) pCurrRoute->GetAttribute ( ROUTE_CURVE ); if ( lastchkPoint03 ( pRouteCurve, p, true, dpos, difference ) ) { int rid = ( ( CcInt* ) pCurrRoute->GetAttribute ( ROUTE_ID ) )->GetIntval(); GPoint *result = new GPoint ( true, GetId(), rid, dpos, None ); pCurrRoute->DeleteIfAllowed(); return result; } else { pCurrRoute->DeleteIfAllowed(); while ( m_pRTreeRoutes->Next ( res ) ) { pCurrRoute = m_pRoutes->GetTuple ( res.info, false ); pRouteCurve = ( SimpleLine* ) pCurrRoute->GetAttribute ( ROUTE_CURVE ); if ( lastchkPoint03 ( pRouteCurve, p, true, dpos, difference ) ) { int rid = ( ( CcInt* ) pCurrRoute->GetAttribute ( ROUTE_ID ) )->GetIntval(); GPoint *result = new GPoint ( true, GetId(), rid, dpos, None ); pCurrRoute->DeleteIfAllowed(); return result; } pCurrRoute->DeleteIfAllowed(); } } // should not be reached GPoint *result = new GPoint ( false ); pCurrRoute->DeleteIfAllowed(); return result; } } void Network::GetJunctionMeasForRoutes ( CcInt *pRoute1Id, CcInt *pRoute2Id, double &rid1meas, double &rid2meas ) { CcInt *pCurrJuncR2id, *pCurrJuncR1id; int iCurrJuncTupleR2id, iCurrJuncR1id, iRoute1Id, iRoute2Id; CcReal *pRid1Meas, *pRid2Meas; bool r1smallerr2, found; BTreeIterator *pJunctionsIt; if ( pRoute1Id->GetIntval() <= pRoute2Id->GetIntval() ) { pJunctionsIt = m_pBTreeJunctionsByRoute1->ExactMatch ( pRoute1Id ); iRoute1Id = pRoute1Id->GetIntval(); iRoute2Id = pRoute2Id->GetIntval(); r1smallerr2 = true; } else { pJunctionsIt = m_pBTreeJunctionsByRoute1->ExactMatch ( pRoute2Id ); iRoute1Id = pRoute2Id->GetIntval(); iRoute2Id = pRoute1Id->GetIntval(); r1smallerr2 = false; } found = false; while ( !found && pJunctionsIt->Next() ) { Tuple *pCurrJuncTuple = m_pJunctions->GetTuple ( pJunctionsIt->GetId(), false ); pCurrJuncR2id = ( CcInt* ) pCurrJuncTuple->GetAttribute ( JUNCTION_ROUTE2_ID ); iCurrJuncTupleR2id = pCurrJuncR2id->GetIntval(); pCurrJuncR1id = ( CcInt* ) pCurrJuncTuple->GetAttribute ( JUNCTION_ROUTE1_ID ); iCurrJuncR1id = pCurrJuncR1id->GetIntval(); if ( iCurrJuncTupleR2id == iRoute2Id && iCurrJuncR1id == iRoute1Id ) { found = true; if ( r1smallerr2 ) { pRid1Meas = ( CcReal* ) pCurrJuncTuple->GetAttribute ( JUNCTION_ROUTE1_MEAS ); rid1meas = pRid1Meas->GetRealval(); pRid2Meas = ( CcReal* ) pCurrJuncTuple->GetAttribute ( JUNCTION_ROUTE2_MEAS ); rid2meas = pRid2Meas->GetRealval(); } else { pRid1Meas = ( CcReal* ) pCurrJuncTuple->GetAttribute ( JUNCTION_ROUTE2_MEAS ); rid1meas = pRid1Meas->GetRealval(); pRid2Meas = ( CcReal* ) pCurrJuncTuple->GetAttribute ( JUNCTION_ROUTE1_MEAS ); rid2meas = pRid2Meas->GetRealval(); } } pCurrJuncTuple->DeleteIfAllowed(); } delete pJunctionsIt; if ( !found ) { rid1meas = numeric_limits::max(); rid2meas = numeric_limits::max(); } } void Network::GetLineValueOfRouteInterval ( const RouteInterval *in_ri, SimpleLine *out_Line ) { CcInt* pRouteId = new CcInt ( true, in_ri->GetRouteId() ); BTreeIterator *pRoutesIter = m_pBTreeRoutes->ExactMatch ( pRouteId ); pRouteId->DeleteIfAllowed(); Tuple *pRoute = 0; if ( pRoutesIter->Next() ) pRoute = m_pRoutes->GetTuple ( pRoutesIter->GetId(), false); assert ( pRoute != 0 ); SimpleLine* pLine = ( SimpleLine* ) pRoute->GetAttribute ( ROUTE_CURVE ); assert ( pLine != 0 ); CcBool* pStSm = ( CcBool* ) pRoute->GetAttribute ( ROUTE_STARTSSMALLER ); bool startSmaller = pStSm->GetBoolval(); pLine->SubLine ( min ( in_ri->GetStartPos(), in_ri->GetEndPos() ), max ( in_ri->GetStartPos(), in_ri->GetEndPos() ), startSmaller, *out_Line ); pRoute->DeleteIfAllowed(); delete pRoutesIter; } /* 3.1.4 Support functions of type constructor ~network~ ~Out~-function of type constructor ~network~ */ ListExpr Network::Out ( ListExpr typeInfo ) { //cout << "NetworkOut" << endl; /////////////////////// // Output of all routes GenericRelationIterator *pRoutesIter = m_pRoutes->MakeScan(); Tuple *pCurrentRoute = 0; ListExpr xLast = nl->TheEmptyList(); ListExpr xNext = nl->TheEmptyList(); ListExpr xRoutes = nl->TheEmptyList(); bool bFirst = true; while ( ( pCurrentRoute = pRoutesIter->GetNextTuple() ) != 0 ) { // Read values from table CcInt* pRouteId = ( CcInt* ) pCurrentRoute->GetAttribute ( ROUTE_ID ); int iRouteId = pRouteId->GetIntval(); CcReal* pLength = ( CcReal* ) pCurrentRoute->GetAttribute ( ROUTE_LENGTH ); double dLength = pLength->GetRealval(); SimpleLine *pCurve = ( SimpleLine* ) pCurrentRoute->GetAttribute ( ROUTE_CURVE ); // The list for the curve contains all segments of the curve. ListExpr xCurve = OutSimpleLine ( nl->TheEmptyList(), SetWord ( pCurve ) ); CcBool* pDual = ( CcBool* ) pCurrentRoute->GetAttribute ( ROUTE_DUAL ); bool bDual= pDual->GetBoolval(); CcBool* pStartsSmaller; pStartsSmaller = ( CcBool* ) pCurrentRoute->GetAttribute ( ROUTE_STARTSSMALLER ); bool bStartsSmaller = pStartsSmaller->GetBoolval(); // Build list xNext = nl->FiveElemList ( nl->IntAtom ( iRouteId ), nl->RealAtom ( dLength ), xCurve, nl->BoolAtom ( bDual ), nl->BoolAtom ( bStartsSmaller ) ); // Create new list or append element to existing list if ( bFirst ) { xRoutes = nl->OneElemList ( xNext ); xLast = xRoutes; bFirst = false; } else { xLast = nl->Append ( xLast, xNext ); } pCurrentRoute->DeleteIfAllowed(); } delete pRoutesIter; /////////////////////// // Output of all junctions GenericRelationIterator *pJunctionsIter = m_pJunctions->MakeScan(); Tuple *pCurrentJunction; ListExpr xJunctions = nl->TheEmptyList(); bFirst = true; while ( ( pCurrentJunction = pJunctionsIter->GetNextTuple() ) != 0 ) { // Read values from table CcInt* pRoute1Id; pRoute1Id = ( CcInt* ) pCurrentJunction->GetAttribute ( JUNCTION_ROUTE1_ID ); int iRoute1Id = pRoute1Id->GetIntval(); CcReal* pMeas1; pMeas1 = ( CcReal* ) pCurrentJunction->GetAttribute ( JUNCTION_ROUTE1_MEAS ); double dMeas1 = pMeas1->GetRealval(); CcInt* pRoute2Id; pRoute2Id = ( CcInt* ) pCurrentJunction->GetAttribute ( JUNCTION_ROUTE2_ID ); int iRoute2Id = pRoute2Id->GetIntval(); CcReal* pMeas2; pMeas2 = ( CcReal* ) pCurrentJunction->GetAttribute ( JUNCTION_ROUTE2_MEAS ); double dMeas2 = pMeas2->GetRealval(); CcInt* pConnectivityCode; pConnectivityCode = ( CcInt* ) pCurrentJunction->GetAttribute ( JUNCTION_CC ); int iConnectivityCode= pConnectivityCode->GetIntval(); Point* pPoint = ( Point* ) pCurrentJunction->GetAttribute ( JUNCTION_POS ); ListExpr xPoint = OutPoint ( nl->TheEmptyList(), SetWord ( pPoint ) ); // Build list xNext = nl->SixElemList ( nl->IntAtom ( iRoute1Id ), nl->RealAtom ( dMeas1 ), nl->IntAtom ( iRoute2Id ), nl->RealAtom ( dMeas2 ), nl->IntAtom ( iConnectivityCode ), xPoint ); // Create new list or append element to existing list if ( bFirst ) { xJunctions= nl->OneElemList ( xNext ); xLast = xJunctions; bFirst = false; } else { xLast = nl->Append ( xLast, xNext ); } pCurrentJunction->DeleteIfAllowed(); } delete pJunctionsIter; return nl->ThreeElemList ( nl->IntAtom ( m_iId ), xRoutes, xJunctions ); } /* ~Save~-function of type constructor ~network~ */ ListExpr Network::Save ( SmiRecord& in_xValueRecord, size_t& inout_iOffset, const ListExpr in_xTypeInfo ) { // Save id of the network int iId = m_iId; in_xValueRecord.Write ( &iId, sizeof ( int ), inout_iOffset ); inout_iOffset += sizeof ( int ); // Save routes ListExpr xType; nl->ReadFromString ( routesInternalTypeInfo, xType ); ListExpr xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); if ( !m_pRoutes->Save ( in_xValueRecord, inout_iOffset, xNumericType ) ) { return false; } // Save junctions nl->ReadFromString ( junctionsInternalTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); if ( !m_pJunctions->Save ( in_xValueRecord, inout_iOffset, xNumericType ) ) { return false; } // Save sections nl->ReadFromString ( sectionsInternalTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); if ( !m_pSections->Save ( in_xValueRecord, inout_iOffset, xNumericType ) ) { return false; } // Save btree for routes nl->ReadFromString ( routesBTreeTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); if ( !m_pBTreeRoutes->Save ( in_xValueRecord, inout_iOffset, xNumericType ) ) { return false; } // Save btree for routesByStartposId nl->ReadFromString ( routesBTreeTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); if ( !m_pBTreeRoutesByStartposId->Save ( in_xValueRecord, inout_iOffset, xNumericType ) ) { return false; } // Save rtree for routes if ( !m_pRTreeRoutes->Save ( in_xValueRecord, inout_iOffset ) ) { return false; } // Save first btree for junctions nl->ReadFromString ( junctionsBTreeTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); if ( !m_pBTreeJunctionsByRoute1->Save ( in_xValueRecord, inout_iOffset, xNumericType ) ) { return false; } // Save second btree for junctions nl->ReadFromString ( junctionsBTreeTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); if ( !m_pBTreeJunctionsByRoute2->Save ( in_xValueRecord, inout_iOffset, xNumericType ) ) { return false; } //SmiFileId fileId = 0; //m_xAdjacencyList.SaveToRecord(in_xValueRecord, inout_iOffset, fileId); //m_xSubAdjacencyList.SaveToRecord(in_xValueRecord, inout_iOffset, fileId); //save m_xAdjacencyLlist //Flob *tmpAdjList = &m_xAdjacencyList; /* cout << "before storing:" << endl; cout << "adjList" << ((Flob)m_xAdjacencyList) << endl; cout << "adjList" << ((Flob)m_xSubAdjacencyList) << endl; cout << "----" << endl;*/ SecondoCatalog *ctlg = SecondoSystem::GetCatalog(); SmiRecordFile *rf = ctlg->GetFlobFile(); m_xAdjacencyList.saveToFile(rf, m_xAdjacencyList); SmiSize offset = 0; size_t bufsize = m_xAdjacencyList.headerSize(); char* buf = (char*) malloc(bufsize); m_xAdjacencyList.serializeHeader(buf,offset); assert(offset==bufsize); in_xValueRecord.Write(buf, bufsize, inout_iOffset); inout_iOffset += bufsize; free(buf); //save m_xSubAdjacencyList //Flob *tmpSubAdjList = &m_xSubAdjacencyList; // SmiRecordFile *rf1 = ctlg->GetFlobFile(); m_xSubAdjacencyList.saveToFile(rf, m_xSubAdjacencyList); offset = 0; buf = (char*) malloc(bufsize); m_xSubAdjacencyList.serializeHeader(buf,offset); assert(offset==bufsize); in_xValueRecord.Write(buf,bufsize, inout_iOffset); free(buf); inout_iOffset += bufsize; // Save btree for sections nl->ReadFromString ( sectionsBTreeTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); if ( !m_pBTreeSectionsByRoute->Save ( in_xValueRecord, inout_iOffset, xNumericType ) ) { //cout << "cannot store BTree_sections" << endl; return false; } nl->ReadFromString ( sectionsBTreeTypeInfo, xType ); xNumericType =SecondoSystem::GetCatalog()->NumericType ( xType ); if ( !m_pBTreeSections->Save ( in_xValueRecord, inout_iOffset, xNumericType ) ) { //cout << "cannot store BTree_sections" << endl; return false; } //save distance storage /* nl->ReadFromString(distancestorageTypeInfo, xType); xNumericType =SecondoSystem::GetCatalog()->NumericType(xType); if(!alldistance->Save(in_xValueRecord, inout_iOffset, xNumericType)) { return false; } */ return true; } /* ~Open~-function of type constructor ~network~ */ Network *Network::Open ( SmiRecord& in_xValueRecord, size_t& inout_iOffset, const ListExpr in_xTypeInfo ) { //cout << "NetworkOpen" << endl; // Create network return new Network ( in_xValueRecord, inout_iOffset, in_xTypeInfo ); } /* ~NetworkProp~-funtion of the type constructor ~network~ */ ListExpr Network::NetworkProp() { ListExpr examplelist = nl->TextAtom(); nl->AppendText ( examplelist, "thenetwork(,, )" ); return ( nl->TwoElemList ( nl->TwoElemList ( nl->StringAtom ( "Creation" ), nl->StringAtom ( "Example Creation" ) ), nl->TwoElemList ( examplelist, nl->StringAtom ( "(let n = thenetwork(id, r,j))" ) ) )); } /* ~OutNetwork~-funtion of the type constructor ~network~ */ ListExpr Network::OutNetwork ( ListExpr typeInfo, Word value ) { Network *n = ( Network* ) value.addr; return n->Out ( typeInfo ); } /* ~InNetwork~-funtion of the type constructor ~network~ */ Word Network::InNetwork ( ListExpr in_xTypeInfo, ListExpr in_xValue, int in_iErrorPos, ListExpr& inout_xErrorInfo, bool& inout_bCorrect ) { //cout << "inNetwork" << endl; Network* pNetwork = new Network ( in_xValue, in_iErrorPos, inout_xErrorInfo, inout_bCorrect ); if ( inout_bCorrect ) { return SetWord ( pNetwork ); } else { delete pNetwork; return SetWord ( Address ( 0 ) ); } } /* ~CreateNetwork~-funtion of the type constructor ~network~ */ Word Network::CreateNetwork ( const ListExpr typeInfo ) { return SetWord ( new Network() ); } /* ~CloseNetwork~-funtion of the type constructor ~network~ */ void Network::CloseNetwork ( const ListExpr typeInfo, Word& w ) { delete static_cast ( w.addr ); w.addr = 0; } /* ~Clone~-function of type constructor ~network~ Not implemented yet. */ Word Network::CloneNetwork ( const ListExpr typeInfo, const Word& w ) { return SetWord ( Address ( 0 ) ); } /* ~DeleteNetwork~-funtion of the type constructor ~network~ */ void Network::DeleteNetwork ( const ListExpr typeInfo, Word& w ) { Network* n = ( Network* ) w.addr; //n->Destroy(); delete n; w.addr = 0; } /* ~CheckNetwork~-funtion of the type constructor ~network~ */ bool Network::CheckNetwork ( ListExpr type, ListExpr& errorInfo ) { return ( nl->IsEqual ( type, "network" ) ); } /* ~CastNetwork~-funtion of the type constructor ~network~ */ void* Network::CastNetwork ( void* addr ) { return ( 0 ); } /* ~SaveNetwork~-funtion of the type constructor ~network~ */ bool Network::SaveNetwork ( SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value ) { // cout << "Save Network" << endl; Network *n = ( Network* ) value.addr; return n->Save ( valueRecord, offset, typeInfo ); } /* ~OpenNetwork~-funtion of the type constructor ~network~ */ bool Network::OpenNetwork ( SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value ) { value.addr = Network::Open ( valueRecord, offset, typeInfo ); return value.addr != 0; } /* ~SizeOfNetwork~-funtion of the type constructor ~network~ */ int Network::SizeOfNetwork() { return 0; } /* ~IsDefined~-funtion of the type constructor ~network~ */ int Network::IsDefined() { return m_bDefined; } /* Secondo TypeConstructor for class ~Network~ */ TypeConstructor network ( "network", Network::NetworkProp, Network::OutNetwork, Network::InNetwork, 0, 0, Network::CreateNetwork, Network::DeleteNetwork, Network::OpenNetwork, Network::SaveNetwork, Network::CloseNetwork, Network::CloneNetwork, Network::CastNetwork, Network::SizeOfNetwork, Network::CheckNetwork ); /* 3.2 class ~GLine~ 3.2.1 Constructors The simple constructor. Should not be used. */ GLine::GLine():Attribute() {} GLine::GLine ( int in_iSize ) : Attribute(true), m_xRouteIntervals ( in_iSize ) { SetDefined(true); m_bSorted = false; m_dLength = 0.0; } GLine::GLine ( const GLine* in_xOther ) : Attribute(in_xOther->IsDefined()), m_xRouteIntervals ( 0 ) { SetDefined(in_xOther->IsDefined()); m_bSorted = in_xOther->m_bSorted; m_iNetworkId = in_xOther->m_iNetworkId; m_dLength = 0.0; // Iterate over all RouteIntervalls for ( int i = 0; i < in_xOther->m_xRouteIntervals.Size(); i++ ) { // Get next Interval RouteInterval pCurrentInterval; in_xOther->m_xRouteIntervals.Get ( i, pCurrentInterval ); int iRouteId = pCurrentInterval.GetRouteId(); double dStart = pCurrentInterval.GetStartPos(); double dEnd = pCurrentInterval.GetEndPos(); AddRouteInterval ( iRouteId, dStart, dEnd ); } TrimToSize(); } GLine::GLine ( ListExpr in_xValue, int in_iErrorPos, ListExpr& inout_xErrorInfo, bool& inout_bCorrect ): Attribute(true) { // Check the list if ( ! ( nl->ListLength ( in_xValue ) == 2 ) ) { string strErrorMessage = "GLine(): List length must be 2."; inout_xErrorInfo = nl->Append ( inout_xErrorInfo, nl->StringAtom ( strErrorMessage ) ); inout_bCorrect = false; SetDefined(false); m_bSorted = false; return; } // Split into the two parts ListExpr xNetworkIdList = nl->First ( in_xValue ); ListExpr xRouteIntervalList = nl->Second ( in_xValue ); // Check the parts if ( !nl->IsAtom ( xNetworkIdList ) || nl->AtomType ( xNetworkIdList ) != IntType ) { string strErrorMessage = "GLine(): Error while reading network-id."; inout_xErrorInfo = nl->Append ( inout_xErrorInfo, nl->StringAtom ( strErrorMessage ) ); SetDefined(false); m_bSorted = false; inout_bCorrect = false; return; } m_iNetworkId = nl->IntValue ( xNetworkIdList ); m_dLength = 0.0; if ( !nl->IsEmpty ( xRouteIntervalList ) ) { // Iterate over all routes while ( !nl->IsEmpty ( xRouteIntervalList ) ) { ListExpr xCurrentRouteInterval = nl->First ( xRouteIntervalList ); xRouteIntervalList = nl->Rest ( xRouteIntervalList ); if ( nl->ListLength ( xCurrentRouteInterval ) != 3 || ( !nl->IsAtom ( nl->First ( xCurrentRouteInterval ) ) ) || nl->AtomType ( nl->First ( xCurrentRouteInterval ) ) != IntType || ( !nl->IsAtom ( nl->Second ( xCurrentRouteInterval ) ) ) || nl->AtomType ( nl->Second ( xCurrentRouteInterval ) ) != RealType || ( !nl->IsAtom ( nl->Third ( xCurrentRouteInterval ) ) ) || nl->AtomType ( nl->Third ( xCurrentRouteInterval ) ) != RealType ) { string strErrorMessage = "GLine(): Error while reading route-interval."; inout_xErrorInfo = nl->Append ( inout_xErrorInfo, nl->StringAtom ( strErrorMessage ) ); inout_bCorrect = false; SetDefined(false); m_bSorted = false; return; } // Read attributes from list // Read values from table int iRouteId = nl->IntValue ( nl->First ( xCurrentRouteInterval ) ); double dStart = nl->RealValue ( nl->Second ( xCurrentRouteInterval ) ); double dEnd = nl->RealValue ( nl->Third ( xCurrentRouteInterval ) ); AddRouteInterval ( iRouteId, dStart, dEnd ); } inout_bCorrect = true; SetDefined(true); m_bSorted = false; } else { SetDefined(false); m_bSorted = false; inout_bCorrect = true; } TrimToSize(); return; } /* 2.2.2 Methods of class ~GLine~ */ void GLine::SetNetworkId ( int in_iNetworkId ) { m_iNetworkId = in_iNetworkId; SetDefined(true); } void GLine::AddRouteInterval ( RouteInterval ri ) { m_xRouteIntervals.Append ( ri ); m_dLength = m_dLength + fabs ( ri.GetEndPos() - ri.GetStartPos() ); } void GLine::AddRouteInterval ( int in_iRouteId, double in_dStart, double in_dEnd ) { RouteInterval *ri = new RouteInterval ( in_iRouteId, in_dStart, in_dEnd ); AddRouteInterval ( *ri ); delete ri; } bool GLine::IsSorted() { return m_bSorted; } void GLine::SetSorted ( bool in_bSorted ) { m_bSorted = in_bSorted; } /* Secondo Integration */ Word GLine::In ( const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct ) { GLine* pGline = new GLine ( 0 ); if ( nl->ListLength ( instance ) == 0 ) { correct = true; pGline->SetDefined ( false ); return SetWord ( pGline ); } if ( nl->ListLength ( instance ) != 2 ) { correct = false; pGline->DeleteIfAllowed(); cmsg.inFunError ( "Expecting (networkid (list of routeintervals))" ); return SetWord ( Address ( 0 ) ); } ListExpr FirstElem = nl->First ( instance ); ListExpr SecondElem = nl->Second ( instance ); if ( !nl->IsAtom ( FirstElem ) || !nl->AtomType ( FirstElem ) == IntType ) { correct = false; pGline->DeleteIfAllowed(); cmsg.inFunError ( "Networkadress is not evaluable" ); return SetWord ( Address ( 0 ) ); } pGline->SetNetworkId ( nl->IntValue ( FirstElem ) ); if ( nl->IsEmpty ( SecondElem ) ) { correct = false; pGline->DeleteIfAllowed(); return SetWord ( Address ( 0 ) ); } while ( !nl->IsEmpty ( SecondElem ) ) { ListExpr start = nl->First ( SecondElem ); SecondElem = nl->Rest ( SecondElem ); if ( nl->ListLength ( start ) != 3 ) { correct = false; pGline->DeleteIfAllowed(); cmsg.inFunError ( "Routeinterval incorrect.Expected list of 3 Elements." ); return SetWord ( Address ( 0 ) ); } ListExpr lrid = nl->First ( start ); ListExpr lpos1 = nl->Second ( start ); ListExpr lpos2 = nl->Third ( start ); if ( !nl->IsAtom ( lrid ) || !nl->AtomType ( lrid ) == IntType || !nl->IsAtom ( lpos1 ) || !nl->AtomType ( lpos1 ) == RealType || !nl->IsAtom ( lpos2 ) || !nl->AtomType ( lpos2 ) == RealType ) { correct = false; pGline->DeleteIfAllowed(); cmsg.inFunError ( "Routeinterval should be list int, real, real." ); return SetWord ( Address ( 0 ) ); } pGline->AddRouteInterval ( nl->IntValue ( lrid ), nl->RealValue ( lpos1 ), nl->RealValue ( lpos2 ) ); } correct = true; pGline->SetDefined(true); pGline->TrimToSize(); return SetWord ( pGline ); } ListExpr GLine::Out ( ListExpr in_xTypeInfo, Word in_xValue ) { GLine *pGline = ( GLine* ) in_xValue.addr; if ( pGline == 0 || !pGline->IsDefined() ) { return nl->SymbolAtom ( "undef" ); } ListExpr xLast = nl->TheEmptyList(); ListExpr xNext = nl->TheEmptyList(); bool bFirst = true; ListExpr xNetworkId = nl->IntAtom ( pGline->m_iNetworkId ); ListExpr xRouteIntervals = nl->TheEmptyList(); // Iterate over all RouteIntervalls for ( int i = 0; i < pGline->m_xRouteIntervals.Size(); ++i ) { // Get next Interval RouteInterval pCurrentInterval; pGline->m_xRouteIntervals.Get ( i, pCurrentInterval ); int iRouteId = pCurrentInterval.GetRouteId(); double dStart = pCurrentInterval.GetStartPos(); double dEnd = pCurrentInterval.GetEndPos(); // Build list xNext = nl->ThreeElemList ( nl->IntAtom ( iRouteId ), nl->RealAtom ( dStart ), nl->RealAtom ( dEnd ) ); // Create new list or append element to existing list if ( bFirst ) { xRouteIntervals = nl->OneElemList ( xNext ); xLast = xRouteIntervals; bFirst = false; } else { xLast = nl->Append ( xLast, xNext ); } } if ( pGline->m_xRouteIntervals.Size() == 0 ) { xRouteIntervals = nl->TheEmptyList(); } return nl->TwoElemList ( xNetworkId, xRouteIntervals ); } Word GLine::Create ( const ListExpr typeInfo ) { return SetWord ( new GLine ( 0 ) ); } void GLine::Clear() { m_xRouteIntervals.clean(); SetSorted ( false ); m_dLength = 0.0; } void GLine::Delete ( const ListExpr typeInfo, Word& w ) { GLine *l = ( GLine* ) w.addr; //if (l->del.refs == 1) l->m_xRouteIntervals.Destroy(); l->DeleteIfAllowed(); w.addr = 0; } void GLine::Close ( const ListExpr typeInfo, Word& w ) { ( ( GLine* ) w.addr )->DeleteIfAllowed(); w.addr = 0; } Word GLine::CloneGLine ( const ListExpr typeInfo, const Word& w ) { return SetWord ( ( ( GLine* ) w.addr )->Clone() ); } GLine* GLine::Clone() const { GLine *xOther = new GLine ( Size() ); xOther->SetDefined ( IsDefined() ); xOther->SetSorted ( m_bSorted ); xOther->SetNetworkId ( m_iNetworkId ); /*RouteInterval ri; for ( int i = 0; i < Size(); i++ ) { Get ( i, ri ); int rid = ri.GetRouteId(); double start = ri.GetStartPos(); double end = ri.GetEndPos(); xOther->AddRouteInterval ( rid, start, end ); }*/ xOther->m_xRouteIntervals.copyFrom(m_xRouteIntervals); return xOther; } void* GLine::Cast ( void* addr ) { return new ( addr ) GLine; } int GLine::Size() const { return m_xRouteIntervals.Size(); } int GLine::SizeOf() { return sizeof ( GLine ); } size_t GLine::Sizeof() const { return sizeof ( *this ); } ostream& GLine::Print ( ostream& os ) const { os << "GLine: NetworkId: " << m_iNetworkId << endl; for ( int i = 0; i < m_xRouteIntervals.Size() ; i++ ) { RouteInterval ri; Get ( i, ri ); os << "RouteInterval: " << i << " rid: " << ri.GetRouteId(); os << " from: " << ri.GetStartPos() << " to: " << ri.GetEndPos(); os << endl; } os << " end gline"; return os; }; bool GLine::Adjacent ( const Attribute* arg ) const { return false; } /* Compare */ int GLine::Compare ( const Attribute* arg ) const { GLine *gl2 = ( GLine* ) arg; if ( IsDefined() && !gl2->IsDefined() ) return 1; else if ( !IsDefined() && gl2->IsDefined() ) return -1; else if ( !IsDefined() && !gl2->IsDefined() ) return 0; else if ( m_dLength < gl2->m_dLength ) return -1; else if ( m_dLength > gl2->m_dLength ) return 1; else if ( m_xRouteIntervals.Size() < gl2->m_xRouteIntervals.Size() ) return -1; else if ( m_xRouteIntervals.Size() > gl2->m_xRouteIntervals.Size() ) return 1; else if ( *this == *gl2 ) return 0; else { RouteInterval ri1, ri2; int i = 0; while ( i < m_xRouteIntervals.Size() ) { Get ( i,ri1 ); gl2->Get ( i,ri2 ); if ( ri1.GetRouteId() < ri2.GetRouteId() ) return -1; else if ( ri1.GetRouteId() > ri2.GetRouteId() ) return 1; else if ( ri1.GetStartPos() < ri2.GetStartPos() ) return -1; else if ( ri1.GetStartPos() > ri2.GetStartPos() ) return 1; else if ( ri1.GetEndPos() < ri2.GetEndPos() ) return -1; else if ( ri1.GetEndPos() > ri2.GetEndPos() ) return 1; i++; } } return 0; } GLine& GLine::operator= ( const GLine& l ) { m_xRouteIntervals.copyFrom(l.m_xRouteIntervals); m_bSorted = l.m_bSorted; SetDefined(l.IsDefined()); m_iNetworkId = l.m_iNetworkId; TrimToSize(); return *this; } bool GLine::operator== ( const GLine& l ) const { if ( !IsDefined() || !l.IsDefined()) { return false; } else { RouteInterval rIt, rIl; if ( m_xRouteIntervals.Size() == l.m_xRouteIntervals.Size() && AlmostEqual ( m_dLength, l.m_dLength ) ) { if ( m_bSorted && l.m_bSorted ) { for ( int i=0; i < m_xRouteIntervals.Size(); i++ ) { Get ( i,rIt ); l.Get ( i,rIl ); if ( ! ( rIt.GetRouteId() == rIl.GetRouteId() && rIt.GetStartPos() == rIl.GetStartPos() && rIt.GetEndPos() == rIl.GetEndPos() ) ) return false; } return true; } else { for ( int i=0; i < m_xRouteIntervals.Size(); i++ ) { Get ( i,rIt ); for ( int j = 0; j < m_xRouteIntervals.Size(); j++ ) { l.Get ( i,rIl ); if ( ! ( rIt.GetRouteId() == rIl.GetRouteId() && rIt.GetStartPos() == rIl.GetStartPos() && rIt.GetEndPos() == rIl.GetEndPos() ) ) return false; } } return true; } } else return false; } } size_t GLine::HashValue() const { size_t xHash = m_iNetworkId; // Iterate over all RouteIntervalls for ( int i = 0; i < m_xRouteIntervals.Size(); ++i ) { // Get next Interval RouteInterval pCurrentInterval; m_xRouteIntervals.Get ( i, pCurrentInterval ); // Add something for each entry int iRouteId = pCurrentInterval.GetRouteId(); double dStart = pCurrentInterval.GetStartPos(); double dEnd = pCurrentInterval.GetEndPos(); xHash += iRouteId + ( size_t ) dStart + ( size_t ) dEnd; } return xHash; } int GLine::NumOfFLOBs() const { return 1; } Flob* GLine::GetFLOB ( const int i ) { if ( i == 0 ) return &m_xRouteIntervals; return 0; } DbArray* GLine::GetRouteIntervals() { if ( IsDefined() ) return &m_xRouteIntervals; else return 0; }; void GLine::CopyFrom ( const Attribute* right ) { *this = * ( ( const GLine* ) right ); //Clear(); /* GLine *src = (GLine*) right; SetDefined(src->IsDefined()); SetSorted(src->IsSorted()); const RouteInterval* ri; for (int i = 0; i < src->Size(); i++) { src->Get(i,ri); int rid = ri.GetRouteId(); double start = ri.GetStartPos(); double end = ri.GetEndPos(); AddRouteInterval(rid, start, end); } */ } double GLine::GetLength() { return m_dLength; } int GLine::GetNetworkId() { return m_iNetworkId; }; /* ~Get~ returns the route interval at position i in the route intervals ~DbArray~. */ void GLine::Get ( const int i, RouteInterval &ri ) const { m_xRouteIntervals.Get ( i, ri ); }; int GLine::NoOfComponents() { return m_xRouteIntervals.Size(); }; ListExpr GLine::Property() { return ( nl->TwoElemList ( nl->FourElemList ( nl->StringAtom ( "Signature" ), nl->StringAtom ( "Example Type List" ), nl->StringAtom ( "List Rep" ), nl->StringAtom ( "Example List" ) ), nl->FourElemList ( nl->StringAtom ( "-> DATA" ), nl->StringAtom ( "gline" ), nl->StringAtom ( "( (( )...))"), nl->StringAtom ( "(1 ((1 1.5 2.5)(2 1.5 2.0)))" ) ) ) ); } bool GLine::Check ( ListExpr type, ListExpr& errorInfo ) { return ( nl->IsEqual ( type, "gline" ) ); } /* Netdistance method computes the network distance between two glines. Uses network distance method of ~GPoint~. */ double GLine::Netdistance ( GLine* pgl2 ) { //GLine* pgl1 = (GLine*) this; double minDist = numeric_limits::max(); double aktDist = numeric_limits::max(); if ( GetNetworkId() != pgl2->GetNetworkId() ) { cmsg.inFunError ( "Both glines must belong to the network." ); return minDist; } GPoints *bGPgl1 = GetBGP(); GPoints *bGPgl2 = pgl2->GetBGP(); GPoint gp1, gp2; for ( int i = 0; i < bGPgl1->Size(); i++ ) { bGPgl1->Get ( i,gp1 ); if ( gp1.Inside ( pgl2 ) ) { bGPgl1->DeleteIfAllowed(); bGPgl2->DeleteIfAllowed(); return 0.0; } for ( int j = 0; j < bGPgl2->Size(); j++ ) { bGPgl2->Get ( j, gp2 ); if ( gp2.Inside ( this ) ) { bGPgl1->DeleteIfAllowed(); bGPgl2->DeleteIfAllowed(); return 0.0; } aktDist = gp1.Netdistance ( &gp2 ); if ( aktDist < minDist ) minDist = aktDist; if ( minDist <= 0.0 ) { bGPgl1->DeleteIfAllowed(); bGPgl2->DeleteIfAllowed(); return 0.0; } } } bGPgl1->DeleteIfAllowed(); bGPgl2->DeleteIfAllowed(); return minDist; } /* Distance method computes the Euclidean Distance between two glines. Uses distance method of ~GPoint~. */ double GLine::Distance ( GLine* pgl2 ) { Line *l1 = new Line ( 0 ); Line *l2 = new Line ( 0 ); Gline2line ( l1 ); pgl2->Gline2line ( l2 ); if ( l1->IsDefined() && l2->IsDefined() ) { double res = l1->Distance ( *l2 ); l1->DeleteIfAllowed(); l2->DeleteIfAllowed(); return res; } else return numeric_limits::max(); } void GLine::Uniongl ( GLine *pgl2, GLine *res ) { RouteInterval pRi1, pRi2; if ( !IsDefined() || NoOfComponents() == 0 ) { if ( pgl2->IsDefined() && pgl2->NoOfComponents() > 0 ) { if ( pgl2->IsSorted() ) { for ( int j = 0; j < pgl2->NoOfComponents(); j++ ) { pgl2->Get ( j,pRi2 ); res->AddRouteInterval ( pRi2.GetRouteId(), pRi2.GetStartPos(), pRi2.GetEndPos() ); } } else { pgl2->Get ( 0,pRi2 ); RITree *ritree = new RITree ( pRi2.GetRouteId(), pRi2.GetStartPos(), pRi2.GetEndPos(),0,0 ); for ( int j = 1; j < pgl2->NoOfComponents(); j++ ) { pgl2->Get ( j,pRi2 ); ritree->Insert ( pRi2.GetRouteId(), pRi2.GetStartPos(), pRi2.GetEndPos() ); } ritree->TreeToGLine ( res ); ritree->RemoveTree(); } res->SetDefined ( true ); res->SetSorted ( true ); res->SetNetworkId ( pgl2->GetNetworkId() ); } else { res->SetDefined ( false ); res->SetSorted ( false ); } } else { if ( !pgl2->IsDefined() || pgl2->NoOfComponents() == 0 ) { if ( IsDefined() && NoOfComponents() >0 ) { if ( IsSorted() ) { for ( int i = 0; i < NoOfComponents(); i++ ) { Get ( i,pRi1 ); res->AddRouteInterval ( pRi1.GetRouteId(), pRi1.GetStartPos(), pRi1.GetEndPos() ); } } else { Get ( 0,pRi1 ); RITree *ritree = new RITree ( pRi1.GetRouteId(), pRi1.GetStartPos(), pRi1.GetEndPos(),0,0 ); for ( int i = 1; i < NoOfComponents(); i++ ) { Get ( i,pRi1 ); ritree->Insert ( pRi1.GetRouteId(), pRi1.GetStartPos(), pRi1.GetEndPos() ); } ritree->TreeToGLine ( res ); ritree->RemoveTree(); } res->SetDefined ( true ); res->SetSorted ( true ); res->SetNetworkId ( GetNetworkId() ); } else { res->SetDefined ( false ); res->SetSorted ( false ); } } else { if ( GetNetworkId() != pgl2->GetNetworkId() ) { res->SetDefined ( false ); res->SetSorted ( false ); } else { res->SetNetworkId ( GetNetworkId() ); if ( IsSorted() && pgl2->IsSorted() ) { int i=0; int j=0; bool newroute = false; int iRouteId; double start, end; while ( i < NoOfComponents() && j < pgl2->NoOfComponents() ) { Get ( i, pRi1 ); pgl2->Get ( j, pRi2 ); if ( pRi1.GetRouteId() < pRi2.GetRouteId() ) { res->AddRouteInterval ( pRi1.GetRouteId(), pRi1.GetStartPos(), pRi1.GetEndPos() ); i++; } else { if ( pRi1.GetRouteId() > pRi2.GetRouteId() ) { res->AddRouteInterval ( pRi2.GetRouteId(), pRi2.GetStartPos(), pRi2.GetEndPos() ); j++; } else { if ( pRi1.GetEndPos() < pRi2.GetStartPos() ) { res->AddRouteInterval ( pRi1.GetRouteId(), pRi1.GetStartPos(), pRi1.GetEndPos() ); i++; } else { if ( pRi2.GetEndPos() < pRi1.GetStartPos() ) { res->AddRouteInterval ( pRi2.GetRouteId(), pRi2.GetStartPos(), pRi2.GetEndPos() ); j++; } else { iRouteId = pRi1.GetRouteId(); start = min ( pRi1.GetStartPos(), pRi2.GetStartPos() ), end = max ( pRi1.GetEndPos(), pRi2.GetEndPos() ); i++; j++; newroute = false; while ( i < NoOfComponents() && !newroute ) { Get ( i,pRi1 ); if ( pRi1.GetRouteId() == iRouteId ) { if ( pRi1.GetStartPos() <= end ) { end = max ( pRi1.GetEndPos(), end ); i++; } else newroute = true; } else newroute = true; } newroute = false; while ( j < pgl2->NoOfComponents() && !newroute ) { pgl2->Get ( j,pRi2 ); if ( pRi2.GetRouteId() == iRouteId ) { if ( pRi2.GetStartPos() <= end ) { end = max ( pRi2.GetEndPos(), end ); j++; } else newroute = true; } else newroute = true; } res->AddRouteInterval ( iRouteId, start, end ); } } } } } while ( i < NoOfComponents() ) { Get ( i,pRi1 ); res->AddRouteInterval ( pRi1.GetRouteId(), pRi1.GetStartPos(), pRi1.GetEndPos() ); i++; } while ( j < pgl2->NoOfComponents() ) { pgl2->Get ( j,pRi2 ); res->AddRouteInterval ( pRi2.GetRouteId(), pRi2.GetStartPos(), pRi2.GetEndPos() ); j++; } res->SetDefined ( true ); res->SetSorted ( true ); } else { RITree *ritree; Get ( 0,pRi1 ); ritree = new RITree ( pRi1.GetRouteId(), pRi1.GetStartPos(), pRi1.GetEndPos(),0,0 ); for ( int i = 1; i < NoOfComponents(); i++ ) { Get ( i,pRi1 ); ritree->Insert ( pRi1.GetRouteId(), pRi1.GetStartPos(), pRi1.GetEndPos() ); } for ( int j = 0; j < pgl2->NoOfComponents(); j++ ) { pgl2->Get ( j,pRi2 ); ritree->Insert ( pRi2.GetRouteId(), pRi2.GetStartPos(), pRi2.GetEndPos() ); } ritree->TreeToGLine ( res ); ritree->RemoveTree(); res->SetDefined ( true ); res->SetSorted ( true ); } } } } res->TrimToSize(); } void GLine::Gline2line ( Line* res ) { res->Clear(); if ( IsDefined() && NoOfComponents() > 0 ) { //Network* pNetwork = NetworkManager::GetNetwork(GetNetworkId()); Network* pNetwork = NetworkManager::GetNetworkNew ( GetNetworkId(), netList ); RouteInterval rI; Line *l = new Line ( 0 ); Line *x = l; for ( int i=0; i < this->NoOfComponents(); i++ ) { this->Get ( i,rI ); SimpleLine *pSubline = new SimpleLine ( 0 ); pNetwork->GetLineValueOfRouteInterval ( &rI, pSubline ); if ( pSubline->IsDefined() ) { Line *partLine = new Line ( 0 ); pSubline->toLine ( *partLine ); pSubline->DeleteIfAllowed(); x = SetOp ( *l, *partLine, avlseg::union_op ); partLine->DeleteIfAllowed(); l->DeleteIfAllowed(); l = x; } } NetworkManager::CloseNetwork ( pNetwork ); ( *res ) = *x; x->DeleteIfAllowed(); res->SetDefined ( true ); } else { if ( IsDefined() && NoOfComponents() == 0 ) { res->SetDefined ( true ); } else { res->SetDefined ( false ); } } res->TrimToSize(); } bool GLine::Intersects ( GLine *pgl ) { RouteInterval pRi1, pRi2; if ( !IsSorted() ) { for ( int i = 0; i < NoOfComponents(); i++ ) { Get ( i, pRi1 ); if ( pgl->IsSorted() ) { if ( searchUnit ( pgl, 0, pgl->NoOfComponents()-1, pRi1 ) ) { return true; }; } else { for ( int j = 0 ; j < pgl->NoOfComponents(); j ++ ) { pgl->Get ( j,pRi2 ); if ( pRi1.GetRouteId() == pRi2.GetRouteId() && ( ! ( pRi1.GetEndPos() < pRi2.GetStartPos() || pRi2.GetStartPos() > pRi1.GetEndPos() ) ) ) { return true; } } } } } else { if ( pgl->IsSorted() ) { int i = 0; int j = 0; while ( iNoOfComponents() ) { Get ( i,pRi1 ); pgl->Get ( j,pRi2 ); if ( pRi1.GetRouteId() < pRi2.GetRouteId() ) i++; else if ( pRi1.GetRouteId() > pRi2.GetRouteId() ) j++; else if ( pRi1.GetStartPos() > pRi2.GetEndPos() ) j++; else if ( pRi1.GetEndPos() < pRi2.GetStartPos() ) i++; else return true; } } else { for ( int i = 0; i < pgl->NoOfComponents(); i++ ) { pgl->Get ( i, pRi2 ); if ( searchUnit ( this, 0, NoOfComponents()-1, pRi2 ) ) return true; } } } return false; } /* Secondo Type Constructor for class ~GLine~ */ TypeConstructor gline ( "gline", //name GLine::Property, //property function GLine::Out, GLine::In, //Out and In functions 0, 0, //SaveToList and //RestoreFromList functions GLine::Create, GLine::Delete, //object creation and deletion OpenAttribute, SaveAttribute, //open and save functions GLine::Close, GLine::CloneGLine, //object close, and clone GLine::Cast, //cast function GLine::SizeOf, //sizeof function GLine::Check ); //kind checking function /* 3.3 class ~GPoint~ 3.3.1 Constructors See ~network.h~ class definition of ~GPoint~ 3.3.2 Methods of class ~GPoint~ */ Word GPoint::InGPoint ( const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct ) { if ( nl->ListLength ( instance ) == 4 ) { if ( nl->IsAtom ( nl->First ( instance ) ) && nl->AtomType ( nl->First ( instance ) ) == IntType && nl->IsAtom ( nl->Second ( instance ) ) && nl->AtomType ( nl->Second ( instance ) ) == IntType && nl->IsAtom ( nl->Third ( instance ) ) && nl->AtomType ( nl->Third ( instance ) ) == RealType && nl->IsAtom ( nl->Fourth ( instance ) ) && nl->AtomType ( nl->Fourth ( instance ) ) == IntType ) { GPoint *gp = new GPoint ( true, nl->IntValue ( nl->First ( instance ) ), nl->IntValue ( nl->Second ( instance ) ), nl->RealValue ( nl->Third ( instance ) ), ( Side ) nl->IntValue ( nl->Fourth ( instance ) ) ); correct = true; return SetWord ( gp ); } } correct = false; return SetWord ( Address ( 0 ) ); } ListExpr GPoint::OutGPoint ( ListExpr typeInfo, Word value ) { GPoint *gp = ( GPoint* ) value.addr; if ( gp->IsDefined() ) { return nl->FourElemList ( nl->IntAtom ( gp->GetNetworkId() ), nl->IntAtom ( gp->GetRouteId() ), nl->RealAtom ( gp->GetPosition() ), nl->IntAtom ( gp->GetSide() ) ); } return nl->SymbolAtom ( "undef" ); } Word GPoint::CreateGPoint ( const ListExpr typeInfo ) { return SetWord ( new GPoint ( false ) ); } void GPoint::DeleteGPoint ( const ListExpr typeInfo, Word& w ) { GPoint *gp = ( GPoint* ) w.addr; if (gp->DeleteIfAllowed()) w.addr = 0; } void GPoint::CloseGPoint ( const ListExpr typeInfo, Word& w ) { GPoint *gp = ( GPoint* ) w.addr; if(gp->DeleteIfAllowed()) w.addr = 0; } Word GPoint::CloneGPoint ( const ListExpr typeInfo, const Word& w ) { return SetWord ( ( ( GPoint* ) w.addr )->Clone() ); } void* GPoint::CastGPoint ( void* addr ) { return new ( addr ) GPoint; } int GPoint::SizeOfGPoint() { return sizeof ( GPoint ); } ListExpr GPoint::GPointProperty() { return ( nl->TwoElemList ( nl->FourElemList ( nl->StringAtom ( "Signature" ), nl->StringAtom ( "Example Type List" ), nl->StringAtom ( "List Rep" ), nl->StringAtom ( "Example List" ) ), nl->FourElemList ( nl->StringAtom ( "-> DATA" ), nl->StringAtom ( "gpoint" ), nl->StringAtom ( "( " " )" ), nl->StringAtom ( "(1 1 0.0 0)" ) ) ) ); } bool GPoint::CheckGPoint ( ListExpr type, ListExpr& errorInfo ) { return ( nl->IsEqual ( type, "gpoint" ) ); } /* Netdistance function computes the network distance between two ~GPoint~s. Using Dijkstras-Algorithm for shortest path computing */ double GPoint::Netdistance ( GPoint* pToGPoint ) { GLine* pGLine = new GLine ( 0 ); double res; if ( ShortestPath ( pToGPoint, pGLine ) ) { res = pGLine->GetLength(); pGLine->DeleteIfAllowed(); return res; } else { pGLine->DeleteIfAllowed(); return 0; } } double GPoint::NewNetdistance ( GPoint* pToGPoint,GLine* gline ) { GPoint* gp1 = new GPoint ( true,GetNetworkId(),GetRouteId(),GetPosition() ); GPoint* gp2 = new GPoint ( true,pToGPoint->GetNetworkId(), pToGPoint->GetRouteId(),pToGPoint->GetPosition() ); double res; if ( gp1->ShortestPath ( gp2, gline ) ) { res = gline->GetLength(); gp1->DeleteIfAllowed(); gp2->DeleteIfAllowed(); return res; } else { gp1->DeleteIfAllowed(); gp2->DeleteIfAllowed(); return 0; } } /* Distance function computes the Euclidean Distance between two ~GPoint~s. */ double GPoint::Distance ( GPoint* pToGPoint ) { map::iterator it = netList->begin(); if ( IsDefined() && pToGPoint->IsDefined() && GetNetworkId() == pToGPoint->GetNetworkId() ) { //Network* pNetwork=NetworkManager::GetNetwork(GetNetworkId()); Network* pNetwork = NetworkManager::GetNetworkNew ( GetNetworkId(), netList ); Point *from = new Point ( false ); pNetwork->GetPointOnRoute ( this, from ); Point *to = new Point ( false ); pNetwork->GetPointOnRoute ( pToGPoint,to ); double res = from->Distance ( *to ); from->DeleteIfAllowed(); to->DeleteIfAllowed(); NetworkManager::CloseNetwork ( pNetwork ); return res; } else return numeric_limits::max(); } /* Returns true if the gpoint is inside the gline false elsewhere. */ bool GPoint::Inside ( GLine *gl ) { if ( ! ( gl->IsDefined() ) || !IsDefined() || gl->NoOfComponents() < 1 ) return false; if ( GetNetworkId() != gl->GetNetworkId() ) return false; RouteInterval pCurrRInter; if ( gl->IsSorted() ) return ( searchRouteInterval ( this, gl, 0, gl->NoOfComponents()-1 ) ); else { int i = 0; while ( i < gl->NoOfComponents() ) { gl->Get ( i, pCurrRInter ); if ( pCurrRInter.GetRouteId() == GetRouteId() ) { if ( pCurrRInter.GetStartPos() < GetPosition() && GetPosition() < pCurrRInter.GetEndPos() ) return true; if ( pCurrRInter.GetStartPos() > GetPosition() && GetPosition() > pCurrRInter.GetEndPos() ) return true; if ( fabs ( pCurrRInter.GetStartPos() - GetPosition() ) < 0.1 ) return true; if ( fabs ( pCurrRInter.GetEndPos() - GetPosition() ) < 0.1 ) return true; } i++; } return false; } return false; } bool GPoint::operator== ( const GPoint& p ) const { if ( !IsDefined() || !p.IsDefined() ) return false; else { if ( m_iNetworkId == p.GetNetworkId() && m_xRouteLocation.rid == p.GetRouteId() && m_xRouteLocation.d == p.GetPosition() && ( m_xRouteLocation.side == p.GetSide() || m_xRouteLocation.side == 2 || p.GetSide() == 2 ) ) { return true; } else return false; } } bool GPoint::operator!= ( const GPoint& p ) const { return ! ( *this == p ); } /* Computes the shortest path between start and end in the network. Using Dijkstras Algorithm. The path is returned as gline value. */ bool GPoint::ShortestPath ( GPoint *to, GLine *result ) { GPoint* start = new GPoint ( true,GetNetworkId(),GetRouteId(),GetPosition(), GetSide() ); GPoint* end = new GPoint ( true,to->GetNetworkId(),to->GetRouteId(), to->GetPosition(),to->GetSide() );//copy the gpoint result->Clear(); if ( start == 0 || end == 0 || !start->IsDefined() || !end->IsDefined() ) { sendMessage ( "Both gpoints must exist and be defined." ); result->SetDefined ( false ); start->DeleteIfAllowed(); end->DeleteIfAllowed(); return false; } // Check wether both points belong to the same network if ( start->GetNetworkId() != end->GetNetworkId() ) { sendMessage ( "Both gpoints belong to different networks." ); result->SetDefined ( false ); start->DeleteIfAllowed(); end->DeleteIfAllowed(); return false; } result->SetNetworkId ( start->GetNetworkId() ); // Load the network //Network* pNetwork = NetworkManager::GetNetwork(start->GetNetworkId()); Network* pNetwork = NetworkManager::GetNetworkNew ( start->GetNetworkId(), netList ); if ( pNetwork == 0 ) { sendMessage ( "Network not found." ); result->SetDefined ( false ); start->DeleteIfAllowed(); end->DeleteIfAllowed(); return false; } // Get sections where the path should start or end TupleId startSectTID = pNetwork->GetTupleIdSectionOnRoute ( start ); Tuple* startSection = pNetwork->GetSection ( startSectTID ); if ( startSection == 0 ) { sendMessage ( "Starting GPoint not found in network." ); NetworkManager::CloseNetwork ( pNetwork ); result->SetDefined ( false ); start->DeleteIfAllowed(); end->DeleteIfAllowed(); return false; } TupleId lastSectTID = pNetwork->GetTupleIdSectionOnRoute ( end ); Tuple* endSection = pNetwork->GetSection ( lastSectTID ); if ( endSection == 0 ) { sendMessage ( "End GPoint not found in network." ); startSection->DeleteIfAllowed(); NetworkManager::CloseNetwork ( pNetwork ); result->SetDefined ( false ); start->DeleteIfAllowed(); end->DeleteIfAllowed(); return false; } //////////////////////////////////////////////////// /* bool junctionpoint = false; Point* endp = new Point(); pNetwork->GetPointOnRoute(end,endp); //end point Point* startp = new Point(); pNetwork->GetPointOnRoute(start,startp); if(fabs(endp->GetX() - startp->GetX()) < 0.1 && fabs(endp->GetY() - startp->GetY()) < 0.1){ endp->DeleteIfAllowed(); startp->DeleteIfAllowed(); start->DeleteIfAllowed(); end->DeleteIfAllowed(); startSection->DeleteIfAllowed(); endSection->DeleteIfAllowed(); NetworkManager::CloseNetwork(pNetwork); return false; } vector juns; CcInt* routeid = new CcInt(true,end->GetRouteId()); pNetwork->GetJunctionsOnRoute(routeid,juns); for(unsigned int i = 0;i < juns.size();i++){ Tuple* t = juns[i].m_pJunction; if(((CcInt*)t->GetAttribute(JUNCTION_ROUTE1_ID))->GetIntval() == end->GetRouteId() && fabs(((CcReal*)t->GetAttribute(JUNCTION_ROUTE1_MEAS))->GetRealval()- end->GetPosition()) < 0.1) junctionpoint = true; if(((CcInt*)t->GetAttribute(JUNCTION_ROUTE2_ID))->GetIntval() == end->GetRouteId() && fabs(((CcReal*)t->GetAttribute(JUNCTION_ROUTE2_MEAS))->GetRealval()- end->GetPosition()) < 0.1) junctionpoint = true; } vector secjunid; if(junctionpoint){//it is a junction point vector sectionlist; if(fabs(end->GetPosition()- ((CcReal*)endSection->GetAttribute(SECTION_MEAS1))->GetRealval())< 0.1) pNetwork->GetAdjacentSections(endSection->GetTupleId(),false,sectionlist); else pNetwork->GetAdjacentSections(endSection->GetTupleId(),true,sectionlist); for(unsigned int i = 0;i < sectionlist.size();i++){ if(sectionlist[i].GetSectionTid() != endSection->GetTupleId()) secjunid.push_back(sectionlist[i].GetSectionTid()); } } endp->DeleteIfAllowed(); routeid->DeleteIfAllowed();*/ ///////////////////////////////////////////////////// /* Calculate the shortest path using dijkstras algorithm. */ if ( startSectTID == lastSectTID || GetRouteId() == to->GetRouteId() ) { result->AddRouteInterval ( start->GetRouteId(), start->GetPosition(), end->GetPosition() ); } else { /* Initialize PriorityQueue */ PrioQueue *prioQ = new PrioQueue ( 0 ); SectIDTree *visitedSect = 0; double sectMeas1 = ( ( CcReal* ) startSection->GetAttribute ( SECTION_MEAS1 ) )->GetRealval(); double sectMeas2 = ( ( CcReal* ) startSection->GetAttribute ( SECTION_MEAS2 ) )->GetRealval(); double dist = 0.0; vector adjSectionList; adjSectionList.clear(); if ( start->GetSide() == 0 ) { dist = start->GetPosition() - sectMeas1; pNetwork->GetAdjacentSectionsInfo ( startSectTID, false, adjSectionList ); SectIDTree *startTree = new SectIDTree ( startSectTID, ( TupleId ) numeric_limits::max(), false, numeric_limits::max() ); visitedSect = startTree; for ( size_t i = 0; i < adjSectionList.size(); i++ ) { DirectedSectionInfo actNextSect = adjSectionList[i]; if ( actNextSect.GetSectionTid() != startSectTID ) { PQEntry *actEntry = new PQEntry ( actNextSect.GetSectionTid(), dist, actNextSect.GetUpDownFlag(), startSectTID, actNextSect.GetMeas1(), actNextSect.GetMeas2(), actNextSect.GetRid()); prioQ->Insert ( *actEntry, visitedSect ) ; delete actEntry; } } adjSectionList.clear(); } else { if ( start->GetSide() == 1 ) { dist = sectMeas2 - start->GetPosition(); SectIDTree *startTree = new SectIDTree ( startSectTID, ( TupleId ) numeric_limits::max(), true, numeric_limits::max() ); visitedSect = startTree; pNetwork->GetAdjacentSectionsInfo ( startSectTID, true, adjSectionList); for ( size_t i = 0; i < adjSectionList.size(); i++ ) { DirectedSectionInfo actNextSect = adjSectionList[i]; if ( actNextSect.GetSectionTid() != startSectTID ) { PQEntry *actEntry = new PQEntry ( actNextSect.GetSectionTid(), dist, actNextSect.GetUpDownFlag(), startSectTID, actNextSect.GetMeas1(), actNextSect.GetMeas2(), actNextSect.GetRid() ); prioQ->Insert ( *actEntry, visitedSect ); delete actEntry; } } adjSectionList.clear(); } else { dist = start->GetPosition() - sectMeas1; pNetwork->GetAdjacentSectionsInfo ( startSectTID, false, adjSectionList); bool first = true; for ( size_t i = 0; i < adjSectionList.size(); i++ ) { DirectedSectionInfo actNextSect = adjSectionList[i]; if ( actNextSect.GetSectionTid() != startSectTID ) { if ( first ) { first = false; SectIDTree *startTree = new SectIDTree ( startSectTID, ( TupleId ) numeric_limits::max(), false, numeric_limits::max() ); visitedSect = startTree; } PQEntry *actEntry = new PQEntry ( actNextSect.GetSectionTid(), dist, actNextSect.GetUpDownFlag(), startSectTID, actNextSect.GetMeas1(), actNextSect.GetMeas2(), actNextSect.GetRid() ); prioQ->Insert ( *actEntry, visitedSect ); delete actEntry; } } adjSectionList.clear(); dist = sectMeas2 -start->GetPosition(); pNetwork->GetAdjacentSectionsInfo ( startSectTID, true, adjSectionList); for ( size_t i = 0; i < adjSectionList.size(); i++ ) { DirectedSectionInfo actNextSect = adjSectionList[i]; if ( actNextSect.GetSectionTid() != startSectTID ) { if ( first ) { first = false; SectIDTree *startTree = new SectIDTree ( startSectTID, ( TupleId ) numeric_limits::max(), true, numeric_limits::max() ); visitedSect = startTree; } PQEntry *actEntry = new PQEntry ( actNextSect.GetSectionTid(), dist, actNextSect.GetUpDownFlag(), startSectTID, actNextSect.GetMeas1(), actNextSect.GetMeas2(), actNextSect.GetRid() ); prioQ->Insert ( *actEntry, visitedSect ); delete actEntry; } } adjSectionList.clear(); } } /* Use priorityQueue to find shortestPath. */ PQEntry *actPQEntry; bool found = false; vector candidate; while ( !prioQ->IsEmpty() && !found ) { actPQEntry = prioQ->GetAndDeleteMin ( visitedSect ); sectMeas1 = actPQEntry->meas1; sectMeas2 = actPQEntry->meas2; dist = actPQEntry->distFromStart + fabs ( sectMeas2 - sectMeas1 ); ////////////////////////////////////// /*if(junctionpoint){ //end point is a junction point for(unsigned int i = 0;i < secjunid.size();i++){ if(secjunid[i] == actPQEntry->sectID){ lastSectTID = actPQEntry->sectID; Tuple* sect = pNetwork->GetSection(lastSectTID); double m1 = ((CcReal*)sect->GetAttribute(SECTION_MEAS1))->GetRealval(); double m2 = ((CcReal*)sect->GetAttribute(SECTION_MEAS2))->GetRealval(); if(actPQEntry->upDownFlag){ GPoint* temp = new GPoint(true,end->GetNetworkId(), end->GetRouteId(),m2,None); *end = *temp; temp->DeleteIfAllowed(); }else{ GPoint* temp = new GPoint(true,end->GetNetworkId(), end->GetRouteId(),m1,None); *end = *temp; temp->DeleteIfAllowed(); } sect->DeleteIfAllowed(); break; } } }*/ //////////////////////////////////// if ( actPQEntry->sectID != lastSectTID ) { /* Search further in the network unitl reached last section. Get adjacent sections and insert into priority Queue. */ adjSectionList.clear(); pNetwork->GetAdjacentSectionsInfo ( actPQEntry->sectID, actPQEntry->upDownFlag, adjSectionList ); for ( size_t i = 0; i sectID ) { PQEntry *actEntry = new PQEntry ( actNextSect.GetSectionTid(), dist, actNextSect.GetUpDownFlag(), actPQEntry->sectID, actNextSect.GetMeas1(), actNextSect.GetMeas2(), actNextSect.GetRid() ); prioQ->Insert ( *actEntry, visitedSect ); delete actEntry; } } delete actPQEntry; actPQEntry=0; } else { /* Shortest Path found. Compute last route interval and resulting gline. */ //actually not really found /*candidate.push_back(*actPQEntry); while(!prioQ->IsEmpty()){ PQEntry* temp = prioQ->GetAndDeleteMin(visitedSect); Tuple *act = pNetwork->GetSection(temp->sectID); //double m1 = // ((CcReal*) act->GetAttribute(SECTION_MEAS1))->GetRealval(); //double m2 = // ((CcReal*) act->GetAttribute(SECTION_MEAS2))->GetRealval(); act->DeleteIfAllowed(); if(temp->distFromStart >= (actPQEntry->distFromStart+fabs(sectMeas2-sectMeas1))){ temp->DeleteIfAllowed(); break; } if(junctionpoint){ //end point is a junction point for(unsigned int i = 0;i < secjunid.size();i++){ if(secjunid[i] == temp->sectID){ Tuple* sect = pNetwork->GetSection(temp->sectID); double m1 = ((CcReal*)sect->GetAttribute(SECTION_MEAS1))->GetRealval(); double m2 = ((CcReal*)sect->GetAttribute(SECTION_MEAS2))->GetRealval(); if(temp->distFromStart+m2-m1 > actPQEntry->distFromStart+fabs(sectMeas2-sectMeas1)){ sect->DeleteIfAllowed(); continue; } lastSectTID = temp->sectID; if(actPQEntry->upDownFlag){ GPoint* temp = new GPoint(true,end->GetNetworkId(), end->GetRouteId(),m2,None); *end = *temp; temp->DeleteIfAllowed(); }else{ GPoint* temp = new GPoint(true,end->GetNetworkId(), end->GetRouteId(),m1,None); *end = *temp; temp->DeleteIfAllowed(); } sect->DeleteIfAllowed(); break; } } } if(temp->sectID == lastSectTID){ candidate.push_back(*temp); }else{ adjSectionList.clear(); pNetwork->GetAdjacentSections(temp->sectID, temp->upDownFlag, adjSectionList); Tuple *tempsec = pNetwork->GetSection(temp->sectID); double meas1 = ((CcReal*) tempsec->GetAttribute(SECTION_MEAS1))->GetRealval(); double meas2 = ((CcReal*) tempsec->GetAttribute(SECTION_MEAS2))->GetRealval(); dist = temp->distFromStart + fabs(meas2 - meas1); for (size_t i = 0; i sectID) { PQEntry *actEntry = new PQEntry(actNextSect.GetSectionTid(), dist, actNextSect.GetUpDownFlag(), temp->sectID); prioQ->Insert(*actEntry, visitedSect); delete actEntry; } } tempsec->DeleteIfAllowed(); } temp->DeleteIfAllowed(); } //double length; delete actPQEntry; actSection->DeleteIfAllowed(); double tempdist = numeric_limits::max(); actPQEntry = &candidate[0]; for(unsigned int i = 0; i < candidate.size();i++){ Tuple *sec = pNetwork->GetSection(candidate[i].sectID); double m1 = ((CcReal*)sec->GetAttribute(SECTION_MEAS1))->GetRealval(); double m2 = ((CcReal*)sec->GetAttribute(SECTION_MEAS2))->GetRealval(); if(candidate[i].upDownFlag == true){//UP double dist = candidate[i].distFromStart + m2-m1; if(dist < tempdist){ actPQEntry = &candidate[i]; tempdist = dist; } }else{//DOWN double dist = candidate[i].distFromStart + m2-m1; if(dist < tempdist){ actPQEntry = &candidate[i]; tempdist = dist; } } sec->DeleteIfAllowed(); } actSection = pNetwork->GetSection(actPQEntry->sectID); sectMeas1 = ((CcReal*) actSection->GetAttribute(SECTION_MEAS1))->GetRealval(); sectMeas2 = ((CcReal*) actSection->GetAttribute(SECTION_MEAS2))->GetRealval();*/ /////////////////////////////////////////////// found = true; double startRI, endRI; int actRouteId =actPQEntry->rid; if ( actPQEntry->upDownFlag == true ) { startRI = sectMeas1; endRI = end->GetPosition(); } else { startRI = sectMeas2; endRI = end->GetPosition(); } /* Get the sections used for shortest path and write them in right order (from start to end gpoint) in the resulting gline. Because dijkstra gives the sections from end to start we first have to put the result sections on a stack to turn in right order. */ RIStack *riStack = new RIStack ( actRouteId, startRI, endRI ); TupleId lastSectId = actPQEntry->sectID; SectIDTree *pElem = visitedSect->Find ( actPQEntry->beforeSectID ); bool end = false; bool upDown; // if (startRI >= endRI) upDown = false; if ( startRI > endRI || fabs ( startRI-endRI ) < 0.1 ) upDown = false; else upDown = true; while ( !end ) { //GetSection Tuple *actSection = pNetwork->GetSection ( pElem->sectID ); actRouteId = ( ( CcInt* ) actSection->GetAttribute ( SECTION_RID ) )->GetIntval(); sectMeas1 = ( ( CcReal* ) actSection->GetAttribute ( SECTION_MEAS1 ) )->GetRealval(); sectMeas2 = ( ( CcReal* ) actSection->GetAttribute ( SECTION_MEAS2 ) )->GetRealval(); upDown = pElem->upDownFlag; if ( pElem->sectID != startSectTID ) { if ( upDown ) riStack->Push ( actRouteId, sectMeas1, sectMeas2, riStack ); else riStack->Push ( actRouteId, sectMeas2, sectMeas1, riStack ); lastSectId = pElem->sectID; pElem = visitedSect->Find ( pElem->beforeSectId ); } else { end = true; pNetwork->GetAdjacentSectionsInfo (startSectTID, true,adjSectionList ); size_t i = 0; bool stsectfound = false; while ( i < adjSectionList.size() && !stsectfound ) { DirectedSectionInfo adjSection = adjSectionList[i]; if ( adjSection.GetSectionTid() == lastSectId ) { if ( fabs ( start->GetPosition()-sectMeas2 ) > 0.1 ) { stsectfound = true; riStack->Push ( actRouteId, start->GetPosition(), sectMeas2, riStack ); end = true; } } i++; } adjSectionList.clear(); if ( !stsectfound ) { pNetwork->GetAdjacentSectionsInfo ( startSectTID, false, adjSectionList ); i = 0; while ( i < adjSectionList.size() && !stsectfound ) { DirectedSectionInfo adjSection = adjSectionList[i]; if ( adjSection.GetSectionTid() == lastSectId ) { if ( fabs ( start->GetPosition()-sectMeas1 ) > 0.1 ) { stsectfound = true; riStack->Push ( actRouteId, start->GetPosition(), sectMeas1, riStack ); end = true; } } i++; } adjSectionList.clear(); } } if ( actSection ) { actSection->DeleteIfAllowed(); actSection = 0; } } // Cleanup and return result riStack->StackToGLine ( result ); riStack->RemoveStack(); } if ( actPQEntry ) { delete actPQEntry; actPQEntry = 0; } } if ( visitedSect != 0 ) visitedSect->Remove(); prioQ->Destroy(); delete prioQ; } startSection->DeleteIfAllowed(); endSection->DeleteIfAllowed(); NetworkManager::CloseNetwork ( pNetwork ); result->SetSorted ( false ); result->SetDefined ( true ); result->TrimToSize(); start->DeleteIfAllowed(); end->DeleteIfAllowed(); return true; }; /* Method ~ShortestPathAStarPlus~ Computes the shortest path between start- and endpoint in the network. Using AStar-algorithm. The path is returned as gline value. */ bool GPoint::ShortestPathAStarPlus(GPoint *pToGPoint,GLine *result,Word func){ bool withfunc = false; Word funcResult; ArgVectorPointer funargs; if (func.addr != 0) { withfunc = true; funargs = qp->Argument(func.addr); } //reset the result result->Clear(); //****************************************************************** // Check the Inputs whether they exist and are defined //1. generate the startpoint of the search, corresponds with the // pToGPoint, because we want to have the right sequence at the end GPoint *end = new GPoint(true, pToGPoint->GetNetworkId(), pToGPoint->GetRouteId(), pToGPoint->GetPosition(),pToGPoint->GetSide()); //2. generate the endpoint of the search, // corresponts with the startpoint of the path GPoint *start = new GPoint(true, GetNetworkId(), GetRouteId(), GetPosition(), GetSide()); //3. check whether both Points are not 0 if ( start == 0 || end == 0 || !start->IsDefined() || !end->IsDefined() ) { sendMessage ( "Both gpoints must exist and be defined." ); result->SetDefined ( false ); start->DeleteIfAllowed(); end->DeleteIfAllowed(); return false; } //4. check whether both Points belong to the same network if ( start->GetNetworkId() != end->GetNetworkId() ) { sendMessage ( "Both gpoints belong to different networks." ); result->SetDefined ( false ); start->DeleteIfAllowed(); end->DeleteIfAllowed(); return false; } //************************************************* // Get sections where the path should start or end //1. get the netwwork and check whether its not null Network* pNetwork = NetworkManager::GetNetworkNew ( start->GetNetworkId(),netList ); if ( pNetwork == 0 ) { sendMessage ( "Network not found." ); result->SetDefined ( false ); start->DeleteIfAllowed(); end->DeleteIfAllowed(); return false; } //2. set networkId to the result-gline TupleId netId = start->GetNetworkId(); result->SetNetworkId ( start->GetNetworkId() ); //3. determin the startsection and check whether its not null TupleId startSectTID = pNetwork->GetTupleIdSectionOnRoute(start); Tuple* startSection = pNetwork->GetSection(startSectTID); if ( startSection == 0 ) { sendMessage ( "Starting GPoint not found in network." ); NetworkManager::CloseNetwork ( pNetwork ); result->SetDefined ( false ); start->DeleteIfAllowed(); end->DeleteIfAllowed(); return false; } //4. determin the endsection and check whether its not null TupleId endSectTID = pNetwork->GetTupleIdSectionOnRoute(end); Tuple* endSection = pNetwork->GetSection(endSectTID); if ( endSection == 0 ) { sendMessage ( "End GPoint not found in network." ); startSection->DeleteIfAllowed(); NetworkManager::CloseNetwork ( pNetwork ); result->SetDefined ( false ); start->DeleteIfAllowed(); end->DeleteIfAllowed(); return false; } //****************************************************************** // CAlCULATE THE SHORTEST PATH WITH A* //1. check whether both Points on the same Route // if true, then the path can be directly calculated if ( startSectTID == endSectTID || start->GetRouteId() == end->GetRouteId()) { result->AddRouteInterval ( start->GetRouteId(), start->GetPosition(), end->GetPosition()); } // else calculate the shortespath with the A* algorithem else{ //1. Generate the openlist,which save all known Points on the searchpath // with the costs and a pointer to its predecessor used a PrioQueue PrioQueue *openList = new PrioQueue(0); //2. Generate the ClosedList, which save alle Points with the sid // to which the shortest path is known SectIDTree *closeList = 0; //3. other variables, they are needed double dist = 0.0; //distance double totalcost =0.0; //totalcost of the section double heuristic = 0.0; //heuristical part of the totalcost vector adjSectionList; adjSectionList.clear(); //4. Initialized the OpenList //Determin the Side of the section, where the point is located //DEBUG cout << start->GetSide()<GetSide() == 0) // Down-Side of the section { //4a. Calculate the distance double sectMeas1 = ((CcReal*)startSection->GetAttribute(SECTION_MEAS1))->GetRealval(); dist = start->GetPosition() - sectMeas1; //4b. get the adjacent sections pNetwork->GetAdjacentSectionsInfo(startSectTID,false,adjSectionList); //4c. get startsection and put it in the closelist SectIDTree *startTree = new SectIDTree ( startSectTID, ( TupleId ) numeric_limits::max(), false, numeric_limits::max() ); closeList = startTree; //4d. put all adjacent sections in the openlist for ( size_t i = 0; i < adjSectionList.size(); i++ ) { DirectedSectionInfo actNextSect = adjSectionList[i]; if (actNextSect.GetSectionTid() != startSectTID) { //calculate the totalcost GPoint *sectEP = new GPoint(true,netId, actNextSect.GetRid(),actNextSect.GetMeas1()); heuristic = sectEP->Distance(end); if(withfunc) { //funcargs[0]=cost,funcargs[1]=duration,funcargs[2]=laenge (*funargs)[0] =new CcReal(true,actNextSect.GetCost()); (*funargs)[1] =new CcReal(true,actNextSect.GetDuration()); (*funargs)[2] =new CcReal(true,actNextSect.GetLength()); qp->Request(func.addr, funcResult); double fr= ((CcReal*)(funcResult.addr))->GetRealval(); totalcost = fr + heuristic; //DEBUG cout << "ERGEBNIS:" <DeleteIfAllowed(); PQEntry *actEntry = new PQEntry( actNextSect.GetSectionTid(), dist, actNextSect.GetUpDownFlag(), startSectTID, actNextSect.GetMeas1(), actNextSect.GetMeas2(), actNextSect.GetRid(), totalcost); openList->Insert (*actEntry, closeList,true); delete actEntry; } } adjSectionList.clear(); }//END IF (DownSide) else if(start->GetSide() == 1) //Up-Side of the section { //4a. Calculate the distance double sectMeas2 = ((CcReal*)startSection->GetAttribute(SECTION_MEAS2))->GetRealval(); dist = sectMeas2 - start->GetPosition(); //4b. get the adjacent sections pNetwork->GetAdjacentSectionsInfo(startSectTID,true,adjSectionList); //4c. get startsection and put it in the closelist SectIDTree *startTree = new SectIDTree ( startSectTID, (TupleId) numeric_limits::max(), true, numeric_limits::max() ); closeList = startTree; //4d. put all adjacent sections in the openlist for ( size_t i = 0; i < adjSectionList.size(); i++ ) { DirectedSectionInfo actNextSect = adjSectionList[i]; if ( actNextSect.GetSectionTid() != startSectTID ) { //calculate the totalcost GPoint *sectEP = new GPoint(true,netId, actNextSect.GetRid(), actNextSect.GetMeas2()); heuristic = sectEP->Distance(end); if(withfunc) { //funcargs[0]=cost,funcargs[1]=duration,funcargs[2]=laenge (*funargs)[0] =new CcReal(true,actNextSect.GetCost()); (*funargs)[1] =new CcReal(true,actNextSect.GetDuration()); (*funargs)[2] =new CcReal(true,actNextSect.GetLength()); qp->Request(func.addr, funcResult); double fr= ((CcReal*)(funcResult.addr))->GetRealval(); totalcost = fr + heuristic; //DEBUG cout << "ERGEBNIS:" <DeleteIfAllowed(); //DEBUG //cout << "section: "<< actNextSect.GetSectionTid()<<"." // << actNextSect.GetUpDownFlag() << " heuristic: " // << heuristic << "+ kosten: " << actNextSect.GetCost() // <<"=totalcost: "<< totalcost <Insert ( *actEntry, closeList, true ); delete actEntry; } } adjSectionList.clear(); }//END ELSE IF (UpSide) else // NONE, not defined both ways must be calculate { bool first = true; //Entries for the DownSide //4a. Calculate the totalcost double sectMeas1 = ((CcReal*)startSection->GetAttribute(SECTION_MEAS1))->GetRealval(); dist = start->GetPosition() - sectMeas1; //4b. get the adjacent sections pNetwork->GetAdjacentSectionsInfo(startSectTID,false,adjSectionList); //4c. put all adjacent sections in the openlist for ( size_t i = 0; i < adjSectionList.size(); i++ ) { DirectedSectionInfo actNextSect = adjSectionList[i]; if ( actNextSect.GetSectionTid() != startSectTID ) { if ( first ) { //4d. get startsection and put it in the closelist first = false; SectIDTree *startTree = new SectIDTree ( startSectTID, ( TupleId ) numeric_limits::max(), false, numeric_limits::max() ); closeList = startTree; } //calculate the totalcost GPoint *sectEP = new GPoint(true,netId, actNextSect.GetRid(), actNextSect.GetMeas1()); heuristic = sectEP->Distance(end); if(withfunc) { //funcargs[0]=cost,funcargs[1]=duration,funcargs[2]=laenge (*funargs)[0] =new CcReal(true,actNextSect.GetCost()); (*funargs)[1] =new CcReal(true,actNextSect.GetDuration()); (*funargs)[2] = new CcReal(true,actNextSect.GetLength()); qp->Request(func.addr, funcResult); double fr= ((CcReal*)(funcResult.addr))->GetRealval(); totalcost = fr + heuristic; //DEBUG cout << "ERGEBNIS:" <DeleteIfAllowed(); //DEBUG //cout << "section: "<< actNextSect.GetSectionTid()<<"." // << actNextSect.GetUpDownFlag() << " heuristic: " // << heuristic << "+ kosten: " << actNextSect.GetCost() // <<"=totalcost: "<< totalcost <Insert ( *actEntry, closeList, true ); delete actEntry; } } adjSectionList.clear(); //Entries for the UpSide //4a. Calculate the distance double sectMeas2 = ((CcReal*)startSection->GetAttribute(SECTION_MEAS2))->GetRealval(); dist = sectMeas2 - start->GetPosition(); //4b. get the adjacent sections pNetwork->GetAdjacentSectionsInfo(startSectTID,true,adjSectionList); //4c. put all adjacent sections in the openlist for ( size_t i = 0; i < adjSectionList.size(); i++ ) { DirectedSectionInfo actNextSect = adjSectionList[i]; if ( actNextSect.GetSectionTid() != startSectTID ) { if ( first ) { //4d. get startsection and put it in the closelist first = false; SectIDTree *startTree = new SectIDTree ( startSectTID, ( TupleId ) numeric_limits::max(), true, numeric_limits::max() ); closeList = startTree; } //calculate the totalcost GPoint *sectEP = new GPoint(true,netId, actNextSect.GetRid(), actNextSect.GetMeas2()); heuristic = sectEP->Distance(end); if(withfunc) { //funcargs[0]=cost,funcargs[1]=duration,funcargs[2]=laenge (*funargs)[0] =new CcReal(true,actNextSect.GetCost()); (*funargs)[1] =new CcReal(true,actNextSect.GetDuration()); (*funargs)[2] =new CcReal(true,actNextSect.GetLength()); qp->Request(func.addr, funcResult); double fr= ((CcReal*)(funcResult.addr))->GetRealval(); totalcost = fr + heuristic; //DEBUG cout << "ERGEBNIS:" <DeleteIfAllowed(); //DEBUG //cout << "section: "<< actNextSect.GetSectionTid()<<"." // << actNextSect.GetUpDownFlag() << " heuristic: " // << heuristic << "+ kosten: " << actNextSect.GetCost() // <<"=totalcost: "<< totalcost <Insert ( *actEntry, closeList, true ); delete actEntry; } } adjSectionList.clear(); }//END ELSE (BothSide) //5. Use openList to find shortestPath. PQEntry *actPQEntry; bool found = false; vector candidate; while ( !openList->IsEmpty() && !found ) { //5a get the minimum of the openList actPQEntry = openList->GetAndDeleteMin ( closeList, true ); //5b calculate the totalcost of this element double sectMeas1 = actPQEntry->meas1; double sectMeas2 = actPQEntry->meas2; dist = actPQEntry->distFromStart + fabs ( sectMeas2 - sectMeas1 ); if ( actPQEntry->sectID != endSectTID ) { // Search further in the network unitl reached last section. // Get adjacent sections and insert into priority Queue. adjSectionList.clear(); //5c get adjacent section of the actual element pNetwork->GetAdjacentSectionsInfo ( actPQEntry->sectID, actPQEntry->upDownFlag, adjSectionList ); for ( size_t i = 0; i sectID ) { //calculate the totalcost GPoint *sectEP; if(actPQEntry->upDownFlag) sectEP = new GPoint(true,netId, actNextSect.GetRid(), actNextSect.GetMeas2()); else sectEP = new GPoint(true,netId, actNextSect.GetRid(), actNextSect.GetMeas1()); heuristic = sectEP->Distance(end); if(withfunc) {//fcargs[0]=cost,fcargs[1]=duration,fcargs[2]=laenge (*funargs)[0]= new CcReal(true,actNextSect.GetCost()); (*funargs)[1]= new CcReal(true,actNextSect.GetDuration()); (*funargs)[2] = new CcReal(true,actNextSect.GetLength()); qp->Request(func.addr, funcResult); double fr= ((CcReal*)(funcResult.addr))->GetRealval(); totalcost = fr + heuristic; //DEBUG cout << "ERGEBNIS:" <DeleteIfAllowed(); //DEBUG //cout << "section: "<< actNextSect.GetSectionTid() // <<"."<< actNextSect.GetUpDownFlag() // << " heuristic: "<< heuristic<<"+ vorkosten " // << actPQEntry->costFromStart << "+ kosten: " // << actNextSect.GetCost() <<"=totalcost: " // << totalcost <sectID, actNextSect.GetMeas1(), actNextSect.GetMeas2(), actNextSect.GetRid(), totalcost ); openList->Insert ( *actEntry, closeList, true ); delete actEntry; } } delete actPQEntry; actPQEntry=0; }//END IF the end is not reached else //shortespath has been found { //Compute last route interval and resulting gline. found = true; double startRI, endRI; int actRouteId =actPQEntry->rid; if ( actPQEntry->upDownFlag == true ) { startRI = sectMeas1; endRI = end->GetPosition(); } else { startRI = sectMeas2; endRI = end->GetPosition(); } //6. Get the sections used for shortest path and write them in // right order (from start to end gpoint) in the resulting // gline. Because Astar gives the sections from end to start // we first have to put the result sections on a stack to turn // in right order. RIStack *riStack = new RIStack ( actRouteId, startRI, endRI ); TupleId endSectId = actPQEntry->sectID; SectIDTree *pElem = closeList->Find ( actPQEntry->beforeSectID); bool end = false; bool upDown; if ( startRI > endRI || fabs ( startRI-endRI ) < 0.1 ) upDown = false; else upDown = true; while ( !end ) { //GetSection Tuple *actSection = pNetwork->GetSection ( pElem->sectID ); actRouteId = ((CcInt*)actSection->GetAttribute(SECTION_RID))->GetIntval(); sectMeas1 = ((CcReal*)actSection->GetAttribute(SECTION_MEAS1)) ->GetRealval(); sectMeas2 = (( CcReal*)actSection->GetAttribute(SECTION_MEAS2)) ->GetRealval(); upDown = pElem->upDownFlag; if ( pElem->sectID != startSectTID ) { if ( upDown ) riStack->Push(actRouteId,sectMeas1,sectMeas2,riStack); else riStack->Push(actRouteId,sectMeas2,sectMeas1,riStack); endSectId = pElem->sectID; pElem = closeList->Find ( pElem->beforeSectId ); } else { end = true; pNetwork->GetAdjacentSectionsInfo( startSectTID,true, adjSectionList); size_t i = 0; bool stsectfound = false; while ( i < adjSectionList.size() && !stsectfound ) { DirectedSectionInfo adjSection = adjSectionList[i]; if ( adjSection.GetSectionTid() == endSectId ) { if (fabs(start->GetPosition()-sectMeas2 ) > 0.1) { stsectfound = true; riStack->Push( actRouteId,start->GetPosition(), sectMeas2,riStack ); end = true; } } i++; } adjSectionList.clear(); if ( !stsectfound ) { pNetwork-> GetAdjacentSectionsInfo( startSectTID,false,adjSectionList); i = 0; while ( i < adjSectionList.size() && !stsectfound ) { DirectedSectionInfo adjSection = adjSectionList[i]; if ( adjSection.GetSectionTid() == endSectId ) { if (fabs(start->GetPosition()-sectMeas1) > 0.1) { stsectfound = true; riStack->Push ( actRouteId, start->GetPosition(), sectMeas1,riStack ); end = true; } } i++; } adjSectionList.clear(); } } if ( actSection ) { actSection->DeleteIfAllowed(); actSection = 0; } } // Cleanup and return result riStack->StackToGLine ( result ); riStack->RemoveStack(); } if ( actPQEntry ) { delete actPQEntry; actPQEntry = 0; } }// END ELSE shortesPath has been found //clean up if ( closeList != 0 ) closeList->Remove(); openList->Destroy(); delete openList; }//END ELSE Calculate the shortes path with A* //clean up endSection->DeleteIfAllowed(); startSection->DeleteIfAllowed(); NetworkManager::CloseNetwork ( pNetwork ); result->SetSorted ( false ); result->SetDefined ( true ); result->TrimToSize(); start->DeleteIfAllowed(); end->DeleteIfAllowed(); return true; } /* Returns the x,y point represented by gpoint. */ void GPoint::ToPoint ( Point *&res ) { //Network *pNetwork = NetworkManager::GetNetwork(GetNetworkId()); Network* pNetwork = NetworkManager::GetNetworkNew ( GetNetworkId(), netList ); if ( pNetwork != 0 ) { pNetwork->GetPointOnRoute ( this, res ); } else { res->SetDefined ( false ); } NetworkManager::CloseNetwork ( pNetwork ); }; Point* GPoint::ToPoint() const { Point *res = new Point ( false ); //Network *pNetwork = NetworkManager::GetNetwork(GetNetworkId()); Network* pNetwork = NetworkManager::GetNetworkNew ( GetNetworkId(), netList ); if ( pNetwork != 0 ) pNetwork->GetPointOnRoute ( this, res ); NetworkManager::CloseNetwork ( pNetwork ); return res; }; Point* GPoint::ToPoint ( Network*& pNetwork ) const { Point *res = new Point ( false ); if ( pNetwork != 0 ) pNetwork->GetPointOnRoute ( this, res ); return res; }; /* Returns the bounding GPoints of the given GLine. */ GPoints* GLine::GetBGP () { GPoints *result = new GPoints ( 0 ); if ( !IsDefined() || NoOfComponents() == 0 ) return result; else { SectTree *sectionTree = 0; RouteInterval ri; DbArray *actSections = new DbArray ( 0 ); //Network *pNetwork = NetworkManager::GetNetwork(GetNetworkId()); Network* pNetwork = NetworkManager::GetNetworkNew ( GetNetworkId(), netList ); bool first = true; SectTreeEntry nEntry; for ( int i = 0; i < Size(); i++ ) { Get ( i,ri ); pNetwork->GetSectionsOfRouteInterval ( &ri, actSections ); for ( int j = 0; j < actSections->Size(); j++ ) { actSections->Get ( j, nEntry ); if ( first ) { first = false; sectionTree = new SectTree ( &nEntry ); } else { sectionTree->Insert ( &nEntry ); } } actSections->clean(); } delete actSections; sectionTree->WriteResult ( pNetwork, *result, *sectionTree ); sectionTree->Remove(); NetworkManager::CloseNetwork ( pNetwork ); result->TrimToSize(); return result; } }; /* Secondo Type Constructor for class ~GPoint~ */ TypeConstructor gpoint ( "gpoint", //name GPoint::GPointProperty, //property function GPoint::OutGPoint, GPoint::InGPoint, //Out and In functions 0, 0, //SaveToList and //RestoreFromList functions GPoint::CreateGPoint, GPoint::DeleteGPoint, //object creation/deletion OpenAttribute,SaveAttribute,//open and save functions GPoint::CloseGPoint, GPoint::CloneGPoint, //object close, and clone GPoint::CastGPoint, //cast function GPoint::SizeOfGPoint, //sizeof function GPoint::CheckGPoint ); //kind checking function /* 3.4 Class GPoints implemented by Jianqiu Xu */ string edistjoinpointlist = "(rel(tuple((pid int)(p point))))"; enum edistjoinpointlistrelation {POINTSID = 0,POINTSOBJECT}; /* 3.4.1 Constructors */ GPoints::GPoints():Attribute() {} GPoints::GPoints ( int in_iSize ) :Attribute(true),m_xGPoints ( in_iSize ) {} GPoints::GPoints ( GPoints* in_xOther ) : Attribute(in_xOther->IsDefined()), m_xGPoints ( 0 ) { GPoint pCurrentInterval; for ( int i = 0; i < in_xOther->m_xGPoints.Size(); i++ ) { // Get next Interval in_xOther->m_xGPoints.Get ( i, pCurrentInterval ); m_xGPoints.Append ( pCurrentInterval ); } SetDefined(in_xOther->IsDefined()); TrimToSize(); } /* 3.4.2 Methods of class ~GPoints~ */ bool GPoints::IsEmpty() const { return m_xGPoints.Size() == 0; } ostream& GPoints::Print ( ostream& os ) const { for ( int i = 0;i < m_xGPoints.Size();i++ ) { GPoint pGP; m_xGPoints.Get ( i,pGP ); os<<"GPoint:"<= 0 && i < NumOfFLOBs() ); return &m_xGPoints; } size_t GPoints::Sizeof() const { return sizeof ( *this ); } int GPoints::SizeOf() { return sizeof ( GPoints ); } int GPoints::Size() const { return m_xGPoints.Size(); } GPoints& GPoints::operator+= ( const GPoint& gp ) { m_xGPoints.Append ( gp ); TrimToSize(); return *this; } GPoints& GPoints::operator-= ( const GPoint& gp ) { GPoints *nGPs = new GPoints ( 0 ); GPoint actGP; for ( int i = 0; i < m_xGPoints.Size(); i++ ) { m_xGPoints.Get ( i, actGP ); if ( gp != actGP ) nGPs->m_xGPoints.Append ( actGP ); } nGPs->TrimToSize(); return *nGPs; } void GPoints::Get ( int i, GPoint& pgp ) const { assert ( i >= 0 && i < m_xGPoints.Size() ); m_xGPoints.Get ( i,pgp ); } ListExpr GPoints:: Property() { return ( nl->TwoElemList ( nl->FourElemList ( nl->StringAtom ( "Signature" ), nl->StringAtom ( "Example Type List" ), nl->StringAtom ( "List Rep" ), nl->StringAtom ( "Example List" ) ), nl->FourElemList ( nl->StringAtom ( "-> DATA" ), nl->StringAtom ( "gpoints" ), nl->StringAtom ( "(...))" ), nl->StringAtom ( "((1 2.0 0)(2 3.0 0))" ) ) ) ); } ListExpr GPoints::Out ( ListExpr in_xTypeInfo, Word in_xValue ) { GPoints *pGPS = ( GPoints* ) in_xValue.addr; if ( pGPS->IsEmpty() ) { return nl->TheEmptyList(); } GPoint pgp; pGPS->Get ( 0,pgp ); ListExpr result = nl->OneElemList ( GPoint::OutGPoint ( nl->TheEmptyList(),SetWord ( ( void* ) &pgp ) ) ); ListExpr last = result; for ( int i = 1; i < pGPS->Size();i++ ) { pGPS->Get ( i,pgp ); last = nl->Append ( last,GPoint::OutGPoint ( nl->TheEmptyList(), SetWord ( ( void* ) &pgp ) ) ); } return result; } Word GPoints::In ( const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct ) { if ( nl->ListLength ( instance ) == 0 ) { correct = false; cmsg.inFunError ( "Empty List" ); return SetWord ( Address ( 0 ) ); } GPoints* pGPS = new GPoints ( nl->ListLength ( instance ) ); ListExpr rest = instance; while ( !nl->IsEmpty ( rest ) ) { ListExpr first = nl->First ( rest ); rest = nl->Rest ( rest ); if ( nl->ListLength ( first ) != 4 ) { correct = false; cmsg.inFunError ( "GPoint incorrect.Expected list of 4 Elements." ); return SetWord ( Address ( 0 ) ); } GPoint* pgp = ( GPoint* ) GPoint::InGPoint ( nl->TheEmptyList(),first,0,errorInfo,correct ).addr; if ( correct ) { ( *pGPS ) += ( *pgp ); pgp->DeleteIfAllowed(); } else { pgp->DeleteIfAllowed(); return SetWord ( Address ( 0 ) ); } } correct = true; pGPS->SetDefined ( true ); pGPS->TrimToSize(); return SetWord ( pGPS ); } bool GPoints::OpenGPoints ( SmiRecord& valueRecord,size_t& offset, const ListExpr typeInfo, Word& value ) { GPoints* pGPS = ( GPoints* ) Attribute::Open ( valueRecord,offset,typeInfo ); value = SetWord ( pGPS ); pGPS->TrimToSize(); return true; } bool GPoints::SaveGPoints ( SmiRecord& valueRecord,size_t& offset, const ListExpr typeInfo, Word& value ) { GPoints* pGPS = ( GPoints* ) value.addr; Attribute::Save ( valueRecord,offset,typeInfo,pGPS ); return true; } Word GPoints::Create ( const ListExpr typeInfo ) { return SetWord ( new GPoints ( 0 ) ); } void GPoints::Delete ( const ListExpr typeInfo, Word& w ) { GPoints *gp = ( GPoints * ) w.addr; // if (l->del.refs == 1) { l->m_xRouteIntervals.Destroy();} if ( gp->DeleteIfAllowed() == true ) w.addr = 0; } void GPoints::Close ( const ListExpr typeInfo, Word& w ) { if ( ( ( GPoints* ) w.addr )->DeleteIfAllowed() == true ) w.addr = 0; } Word GPoints::CloneGPoints ( const ListExpr typeInfo, const Word& w ) { return SetWord ( new GPoints ( * ( ( GPoints* ) w.addr ) ) ); } void* GPoints::Cast ( void* addr ) { return new ( addr ) GPoints(); } bool GPoints::Check ( ListExpr type, ListExpr& errorInfo ) { return ( nl->IsEqual ( type, "gpoints" ) ); } int GPoints::Compare ( const Attribute* ) const { return false; } bool GPoints::Adjacent ( const Attribute* ) const { return false; } GPoints* GPoints::Clone() const { GPoints* res = new GPoints ( *this ); return res; } size_t GPoints::HashValue() const { size_t xHash = 0; // Iterate over all GPoint objects for ( int i = 0; i < m_xGPoints.Size(); ++i ) { // Get next Interval GPoint pCurrentInterval; m_xGPoints.Get ( i, pCurrentInterval ); // Add something for each entry int iNetworkId = pCurrentInterval.GetNetworkId(); int iRouteId = pCurrentInterval.GetRouteId(); double iPosition = pCurrentInterval.GetPosition(); int iSide = ( int ) pCurrentInterval.GetSide(); xHash += iNetworkId + iRouteId + ( size_t ) iPosition + iSide; } return xHash; } void GPoints::CopyFrom ( const Attribute* right ) { *this = * ( ( const GPoints * ) right ); } TypeConstructor gpoints ( "gpoints", GPoints::Property, GPoints::Out, GPoints::In, 0, 0, GPoints::Create, GPoints::Delete, GPoints::OpenGPoints, GPoints::SaveGPoints, GPoints::Close, GPoints::CloneGPoints, GPoints::Cast, GPoints::SizeOf, GPoints::Check ); /* 4 Secondo Operators 4.1 Operator ~netdistance~ Returns the network distance between two ~Gpoints~ or two ~GLines~. Using Dijkstras Algorithm for computation of the shortest paths. */ ListExpr OpNetNetdistanceTypeMap ( ListExpr args ) { if ( nl->ListLength ( args ) != 2 ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr param1 = nl->First ( args ); ListExpr param2 = nl->Second ( args ); //ListExpr param3 = nl->Third(args); if ( ( nl->IsAtom ( param1 ) && nl->AtomType ( param1 ) == SymbolType && nl->IsAtom ( param2 ) && nl->AtomType ( param2 ) == SymbolType && ( ( nl->SymbolValue ( param1 ) == "gpoint" && nl->SymbolValue ( param2 ) == "gpoint" ) || ( nl->SymbolValue ( param1 ) == "gline" && nl->SymbolValue ( param2 ) == "gline" ) ) ) ) { return nl->SymbolAtom ( CcReal::BasicType() ); } return nl->SymbolAtom ( Symbol::TYPEERROR() ); } int OpNetNetdistance_gpgp ( Word* args, Word& result, int message, Word& local, Supplier in_pSupplier ) { GPoint* pFromGPoint = ( GPoint* ) args[0].addr; GPoint* pToGPoint = ( GPoint* ) args[1].addr; result = qp->ResultStorage ( in_pSupplier ); CcReal* pResult = ( CcReal* ) result.addr; if ( ! ( pFromGPoint->IsDefined() ) || ! ( pToGPoint->IsDefined() ) ) { cmsg.inFunError ( "Both gpoint must be defined!" ); return 0; }; double dist = pFromGPoint->Netdistance ( pToGPoint ); if ( dist != numeric_limits::max() ) pResult->Set ( true,dist ); else pResult->Set ( false, dist ); return 1; }; int OpNetNetdistance_glgl ( Word* args, Word& result, int message, Word& local, Supplier in_pSupplier ) { GLine* pGLine1 = ( GLine* ) args[0].addr; GLine* pGLine2 = ( GLine* ) args[1].addr; CcReal* pResult = ( CcReal* ) qp->ResultStorage ( in_pSupplier ).addr; result = SetWord ( pResult ); if ( ! ( pGLine1->IsDefined() ) || ! ( pGLine2->IsDefined() ) ) { cmsg.inFunError ( "Both gpoint must be defined!" ); return 0; }; double dist = pGLine1->Netdistance ( pGLine2 ); if ( dist != numeric_limits::max() ) pResult->Set ( true, dist ); else pResult->Set ( false, dist ); return 1; }; ValueMapping OpNetNetdistancemap[] = { OpNetNetdistance_gpgp, OpNetNetdistance_glgl }; int OpNetNetdistanceselect ( ListExpr args ) { ListExpr arg1 = nl->First ( args ); ListExpr arg2 = nl->Second ( args ); if ( nl->SymbolValue ( arg1 ) == "gpoint" && nl->SymbolValue ( arg2 ) == "gpoint" ) return 0; if ( nl->SymbolValue ( arg1 ) == "gline" && nl->SymbolValue ( arg2 ) == "gline" ) return 1; return -1; // This point should never be reached }; const string OpNetNetdistanceSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( A x A x network-> real with A = gpoint or gline" "" "netdistance(GPOINT1,GPOINT2, NETWORK)" "Calculates the network distance of two gpoints resp. glines." "query netdistance(gp1,gp2, B_NETWORK)" ") )"; Operator networknetdistance ( "netdistance", // name OpNetNetdistanceSpec, // specification 2, OpNetNetdistancemap, // value mapping OpNetNetdistanceselect, // selection function OpNetNetdistanceTypeMap // type mapping ); /* 4.2 Operator ~gpoint2rect~ Returns a rectangle degenerated to a point with coordinates rid, rid, pos, pos. */ ListExpr OpGPoint2RectTypeMap ( ListExpr in_xArgs ) { if ( nl->ListLength ( in_xArgs ) != 1 ) { sendMessage ( "Expects a list of length 1." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr xsource = nl->First ( in_xArgs ); if ( ( !nl->IsAtom ( xsource ) ) || !nl->IsEqual ( xsource, "gpoint" ) ) { sendMessage ( "Element must be of type gpoint." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } return ( nl->SymbolAtom ( Rectangle<2>::BasicType() ) ); } int OpGPoint2RectValueMapping ( Word* args, Word& result, int message, Word& local, Supplier in_xSupplier ) { result = qp->ResultStorage ( in_xSupplier ); Rectangle<2>* box = static_cast* > ( result.addr ); GPoint* arg = static_cast ( args[0].addr ); if ( !arg->IsDefined() ) { box->SetDefined ( false ); } else { ( *box ) = arg->NetBoundingBox(); } return 0; } //end ValueMapping const string OpGPoint2RectSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( gpoint -> rect" "" "gpoint2rect(GPOINT)" "Returns a rectangle representing the gpoint." " gpoint2rect (gpoint) " ") )"; Operator networkgpoint2rect ( "gpoint2rect", // name OpGPoint2RectSpec, // specification OpGPoint2RectValueMapping, // value mapping Operator::SimpleSelect, // selection function OpGPoint2RectTypeMap // type mapping ); /* 4.3 Operator ~inside~ Returns true if ths ~GPoint~ is inside the ~GLine~ false elsewhere. */ ListExpr OpInsideTypeMap ( ListExpr args ) { if ( nl->ListLength ( args ) != 2 ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr gpoint = nl->First ( args ); ListExpr gline = nl->Second ( args ); if ( !nl->IsAtom ( gpoint ) || nl->AtomType ( gpoint ) != SymbolType || nl->SymbolValue ( gpoint ) != "gpoint" || !nl->IsAtom ( gline ) || nl->AtomType ( gline ) != SymbolType || nl->SymbolValue ( gline ) != "gline" ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } return nl->SymbolAtom ( CcBool::BasicType() ); } int OpInsideValueMap ( Word* args, Word& result, int message, Word& local, Supplier in_pSupplier ) { GPoint* pGPoint = ( GPoint* ) args[0].addr; GLine* pGLine = ( GLine* ) args[1].addr; result = qp->ResultStorage ( in_pSupplier ); CcBool* pResult = ( CcBool* ) result.addr; if ( pGPoint->GetNetworkId() != pGLine->GetNetworkId() || !pGLine->IsDefined() || !pGPoint->IsDefined() ) { pResult->Set ( false, false ); } pResult->Set ( true, pGPoint->Inside ( pGLine ) ); return 0; } const string OpInsideSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( gpoint x gline -> bool" "" " _ inside _" "Returns true if gpoint is inside gline false elsewhere." "GPOINT inside GLINE" ") )"; Operator networkinside ( "inside", // name OpInsideSpec, // specification OpInsideValueMap, // value mapping Operator::SimpleSelect, // selection function OpInsideTypeMap // type mapping ); /* 4.4 Operator ~length~ Returns the length of a ~GLine~. */ ListExpr OpLengthTypeMap ( ListExpr args ) { if ( nl->ListLength ( args ) != 1 ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr gline = nl->First ( args ); if ( !nl->IsAtom ( gline ) || nl->AtomType ( gline ) != SymbolType || nl->SymbolValue ( gline ) != "gline" ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } return nl->SymbolAtom ( CcReal::BasicType() ); } int OpLengthValueMap ( Word* args, Word& result, int message, Word& local, Supplier in_pSupplier ) { GLine* pGline = ( GLine* ) args[0].addr; result = qp->ResultStorage ( in_pSupplier ); CcReal* pResult = ( CcReal* ) result.addr; if ( ! ( pGline->IsDefined() ) ) { cmsg.inFunError ( "gline is not defined!" ); return 0; }; pResult-> Set ( true, pGline->GetLength() ); return 1; } const string OpLengthSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( gline -> real" "" "length(_)" "Calculates the length of the gline." "query length(gline)" ") )"; Operator networklength ( "length", // name OpLengthSpec, // specification OpLengthValueMap, // value mapping Operator::SimpleSelect, // selection function OpLengthTypeMap // type mapping ); /* 4.5 Operator ~line2gline~ Translates a spatial ~line~ value into a network ~GLine~ value if possible. */ ListExpr OpLine2GLineTypeMap ( ListExpr in_xArgs ) { if ( nl->ListLength ( in_xArgs ) != 2 ) { sendMessage ( "Expects a list of length 2." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr xNetworkIdDesc = nl->First ( in_xArgs ); ListExpr xLineDesc = nl->Second ( in_xArgs ); if ( ( !nl->IsAtom ( xNetworkIdDesc ) ) || !nl->IsEqual ( xNetworkIdDesc, "network" ) ) { sendMessage ( "First element must be of type network." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } if ( ( !nl->IsAtom ( xLineDesc ) ) || nl->AtomType ( xLineDesc ) != SymbolType || nl->SymbolValue ( xLineDesc ) != Line::BasicType() ) { sendMessage ( "Second element must be of type sline." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } return nl->SymbolAtom ( "gline" ); } int OpLine2GLineValueMapping ( Word* args, Word& result, int message, Word& local, Supplier in_xSupplier ) { //Initialize return value GLine* pGLine = ( GLine* ) qp->ResultStorage ( in_xSupplier ).addr; result = SetWord ( pGLine ); // Get and check input values. Network* pNetwork = ( Network* ) args[0].addr; GLine *res = new GLine ( 0 ); if ( pNetwork == 0 || !pNetwork->IsDefined() ) { string strMessage = "Network is not defined."; cerr << strMessage << endl; sendMessage ( strMessage ); res->SetDefined ( false ); pGLine->CopyFrom ( res ); res->DeleteIfAllowed(); return 0; } res->SetNetworkId ( pNetwork->GetId() ); Line* pLine = ( Line* ) args[1].addr; if ( pLine == NULL || !pLine->IsDefined() ) { string strMessage = "line does not exist."; cerr << strMessage << endl; sendMessage ( strMessage ); res->SetDefined ( false ); pGLine->CopyFrom ( res ); res->DeleteIfAllowed(); return 0; } if ( pLine->Size() <= 0 ) { string strMessage = "line is empty"; cerr <SetDefined ( true ); pGLine->CopyFrom ( res ); res->DeleteIfAllowed(); return 0; } HalfSegment hs; pLine->Get ( 0,hs ); RouteInterval *ri = pNetwork->Find ( hs.GetLeftPoint(), hs.GetRightPoint() ); if ( ri!= 0 ) { RITree *riTree = new RITree ( ri->GetRouteId(), ri->GetStartPos(), ri->GetEndPos() ); delete ri; for ( int i = 1; i < pLine->Size();i++ ) { pLine->Get ( i,hs ); ri = pNetwork->Find ( hs.GetLeftPoint(), hs.GetRightPoint() ); if ( ri!=0 ) { riTree->Insert ( ri->GetRouteId(), ri->GetStartPos(), ri->GetEndPos() ); delete ri; } } riTree->TreeToGLine ( res ); riTree->RemoveTree(); res->SetDefined ( true ); res->SetSorted ( true ); pGLine->CopyFrom ( res ); res->DeleteIfAllowed(); } else { res->SetDefined ( false ); pGLine->CopyFrom ( res ); res->DeleteIfAllowed(); } return 0; } //end ValueMapping const string OpLine2GLineSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( network x line -> gline" "" "sline2gline(_,_)" "Translates a line to a gline value." "line2gline(B_NETWORK, sline)" ") )"; Operator sline2gline ( "line2gline", // name OpLine2GLineSpec, // specification OpLine2GLineValueMapping, // value mapping Operator::SimpleSelect, // selection function OpLine2GLineTypeMap // type mapping ); /* 4.6 Operator ~=~ Returns true if two ~GPoint~s respectively ~GLine~s are identical false elsewhere. */ ListExpr OpNetEqualTypeMap ( ListExpr args ) { if ( nl->ListLength ( args ) != 2 ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr first = nl->First ( args ); ListExpr second = nl->Second ( args ); if ( ( nl->IsAtom ( first ) && nl->AtomType ( first ) == SymbolType && nl->IsAtom ( second ) && nl->AtomType ( second ) == SymbolType ) && ( ( nl->SymbolValue ( first ) == "gpoint" && nl->SymbolValue ( second ) == "gpoint" ) || ( nl->SymbolValue ( first ) == "gline" && nl->SymbolValue ( second ) == "gline" ) ) ) { return nl->SymbolAtom ( CcBool::BasicType() ); } return nl->SymbolAtom ( Symbol::TYPEERROR() ); } int OpNetEqual_gpgp ( Word* args, Word& result, int message, Word& local, Supplier in_pSupplier ) { GPoint* p1 = ( GPoint* ) args[0].addr; GPoint* p2 = ( GPoint* ) args[1].addr; result = qp->ResultStorage ( in_pSupplier ); CcBool* pResult = ( CcBool* ) result.addr; if ( ! ( p1->IsDefined() ) || !p2->IsDefined() ) { cmsg.inFunError ( "Both gpoints must be defined!" ); pResult->Set ( false, false ); return 0; }; pResult-> Set ( true, *p1 == *p2 ); return 1; } int OpNetEqual_glgl ( Word* args, Word& result, int message, Word& local, Supplier in_pSupplier ) { GLine* l1 = ( GLine* ) args[0].addr; GLine* l2 = ( GLine* ) args[1].addr; result = qp->ResultStorage ( in_pSupplier ); CcBool* pResult = ( CcBool* ) result.addr; if ( ! ( l1->IsDefined() ) || !l2->IsDefined() ) { cmsg.inFunError ( "Both glines must be defined!" ); pResult->Set ( false, false ); return 0; }; pResult-> Set ( true, *l1 == *l2 ); return 1; } ValueMapping OpNetEqualmap[] = { OpNetEqual_gpgp, OpNetEqual_glgl }; int OpNetEqualselect ( ListExpr args ) { ListExpr arg1 = nl->First ( args ); ListExpr arg2 = nl->Second ( args ); if ( nl->SymbolValue ( arg1 ) == "gpoint" && nl->SymbolValue ( arg2 ) == "gpoint" ) return 0; if ( nl->SymbolValue ( arg1 ) == "gline" && nl->SymbolValue ( arg2 ) == "gline" ) return 1; return -1; // This point should never be reached }; const string OpNetEqualSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( A x A -> bool for GPoint and GLine" "" " _ = _" "Returns if two gpoints are equal." "query gpoint1 = gpoint2" ") )"; Operator netgpequal ( "=", // name OpNetEqualSpec, // specification 2, OpNetEqualmap, // value mapping OpNetEqualselect, // selection function OpNetEqualTypeMap // type mapping ); /* 4.7 Operator ~intersects~ Returns true if two ~Gline~ intersect false elsewhere. */ ListExpr OpNetIntersectsTypeMap ( ListExpr in_xArgs ) { ListExpr arg1, arg2; if ( nl->ListLength ( in_xArgs ) == 2 ) { arg1 = nl->First ( in_xArgs ); arg2 = nl->Second ( in_xArgs ); if ( nl->IsAtom ( arg1 ) && nl->AtomType ( arg1 ) == SymbolType && nl->SymbolValue ( arg1 ) == "gline" && nl->IsAtom ( arg2 ) && nl->AtomType ( arg2 ) == SymbolType && nl->SymbolValue ( arg2 ) == "gline" ) { return ( nl->SymbolAtom ( CcBool::BasicType() ) ); } } return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } int OpNetIntersectsValueMapping ( Word* args, Word& result, int message, Word& local, Supplier in_xSupplier ) { // Get (empty) return value CcBool* pResult = ( CcBool* ) qp->ResultStorage ( in_xSupplier ).addr; result = SetWord ( pResult ); pResult->Set ( false, false ); // Get input values GLine* pGLine1 = ( GLine* ) args[0].addr; if ( pGLine1 == NULL || !pGLine1->IsDefined() ) { cerr << "First gline does not exist." << endl; pResult->Set ( false, false ); return 0; } GLine* pGLine2 = ( GLine* ) args[1].addr; if ( pGLine2 == NULL || !pGLine2->IsDefined() ) { cerr << "Second gline does not exist." << endl; pResult->Set ( false, false ); return 0; } // const RouteInterval *pRi1, *pRi2; if ( pGLine1->GetNetworkId() != pGLine2->GetNetworkId() ) { cerr << "glines belong to different networks." << endl; pResult->Set ( true, false ); return 0; } pResult->Set ( true, pGLine1->Intersects ( pGLine2 ) ); return 0; } const string OpNetIntersectsSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( gline x gline -> bool" "" "intersects(gline, gline)" "Returns true if the both glines intersects false elsewhere." "intersects(gline, gline)" ") )"; Operator networkintersects ( "intersects", // name OpNetIntersectsSpec, // specification OpNetIntersectsValueMapping, // value mapping Operator::SimpleSelect, // selection function OpNetIntersectsTypeMap // type mapping ); /* 4.8 Operator ~junctions~ Returns the junctions relation of the network. */ ListExpr OpNetworkJunctionsTypeMap ( ListExpr args ) { ListExpr arg1; if ( nl->ListLength ( args ) == 1 ) { arg1 = nl->First ( args ); if ( nl->IsAtom ( arg1 ) && nl->AtomType ( arg1 ) == SymbolType && nl->SymbolValue ( arg1 ) == "network" ) { ListExpr xType; nl->ReadFromString ( Network::junctionsInternalTypeInfo, xType ); return xType; } } return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } int OpNetworkJunctionsValueMapping ( Word* args, Word& result, int message, Word& local, Supplier s ) { Network *network = ( Network* ) args[0].addr; result = SetWord ( network->GetJunctions() ); Relation *resultSt = ( Relation* ) qp->ResultStorage ( s ).addr; resultSt->Close(); qp->ChangeResultStorage ( s, result ); return 0; } const string OpNetworkJunctionsSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( network -> rel" "" "junctions(_)" "Return the junctions of a network." "query junctions(network)" ") )"; Operator networkjunctions ( "junctions", // name OpNetworkJunctionsSpec, // specification OpNetworkJunctionsValueMapping, // value mapping Operator::SimpleSelect, // trivial selection function OpNetworkJunctionsTypeMap // type mapping ); /* 4.9 Operator ~routes~ Returns the routes relation of the network. */ ListExpr OpNetworkRoutesTypeMap ( ListExpr args ) { ListExpr arg1; if ( nl->ListLength ( args ) == 1 ) { arg1 = nl->First ( args ); if ( nl->IsAtom ( arg1 ) && nl->AtomType ( arg1 ) == SymbolType && nl->SymbolValue ( arg1 ) == "network" ) { ListExpr xType; nl->ReadFromString ( Network::routesInternalTypeInfo, xType ); return xType; } } return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } int OpNetworkRoutesValueMapping ( Word* args, Word& result, int message, Word& local, Supplier s ) { Network *network = ( Network* ) args[0].addr; Relation* pRoute = network->GetRoutes(); result = SetWord ( pRoute->Clone() ); Relation *resultSt = ( Relation* ) qp->ResultStorage ( s ).addr; resultSt->Close(); qp->ChangeResultStorage ( s, result ); return 0; } const string OpNetworkRoutesSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( network -> rel" "" "routes(_)" "Return the routes of a network." "query routes(network)" ") )"; Operator networkroutes ( "routes", // name OpNetworkRoutesSpec, // specification OpNetworkRoutesValueMapping, // value mapping Operator::SimpleSelect, // trivial selection function OpNetworkRoutesTypeMap // type mapping ); /* 4.10 Operator ~sections~ Returns the sections relation of the network. */ ListExpr OpNetworkSectionsTypeMap ( ListExpr args ) { ListExpr arg1; if ( nl->ListLength ( args ) == 1 ) { arg1 = nl->First ( args ); if ( nl->IsAtom ( arg1 ) && nl->AtomType ( arg1 ) == SymbolType && nl->SymbolValue ( arg1 ) == "network" ) { ListExpr xType; nl->ReadFromString ( Network::sectionsInternalTypeInfo, xType ); return xType; } } return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } int OpNetworkSectionsValueMapping ( Word* args, Word& result, int message, Word& local, Supplier s ) { Network *network = ( Network* ) args[0].addr; result = SetWord ( network->GetSections() ); Relation *resultSt = ( Relation* ) qp->ResultStorage ( s ).addr; resultSt->Close(); qp->ChangeResultStorage ( s, result ); return 0; } const string OpNetworkSectionsSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( network -> rel" "" "sections(_)" "Return the sections of a network." "query sections(network)" ") )"; Operator networksections ( "sections", // name OpNetworkSectionsSpec, // specification OpNetworkSectionsValueMapping, // value mapping Operator::SimpleSelect, // trivial selection function OpNetworkSectionsTypeMap // type mapping ); /* 4.11 Operator ~thenetwork~ Creates a network with the given id, from the given routes and junctions relations. */ ListExpr OpNetworkTheNetworkTypeMap ( ListExpr in_xArgs ) { if ( nl->ListLength ( in_xArgs ) != 3 ) return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); ListExpr xIdDesc = nl->First ( in_xArgs ); ListExpr xRoutesRelDesc = nl->Second ( in_xArgs ); ListExpr xJunctionsRelDesc = nl->Third ( in_xArgs ); if ( !nl->IsEqual ( xIdDesc, CcInt::BasicType() ) ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } if ( !IsRelDescription ( xRoutesRelDesc ) || !IsRelDescription ( xJunctionsRelDesc ) ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr xType; nl->ReadFromString ( Network::routesTypeInfo, xType ); if ( !CompareSchemas ( xRoutesRelDesc, xType ) ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } nl->ReadFromString ( Network::junctionsTypeInfo, xType ); if ( !CompareSchemas ( xJunctionsRelDesc, xType ) ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } return nl->SymbolAtom ( "network" ); } int OpNetworkTheNetworkValueMapping ( Word* args, Word& result, int message, Word& local, Supplier s ) { Network* pNetwork = ( Network* ) qp->ResultStorage ( s ).addr; CcInt* pId = ( CcInt* ) args[0].addr; int iId = pId->GetIntval(); map::iterator it = netList->find ( iId ); if ( it != netList->end() ) { cerr << "NetworkId used before" << iId << endl; while ( it != netList->end() ) { it = netList->find ( ++iId ); } cerr << "NetworkId changed to: " << iId << endl; } netList->insert ( pair ( iId, "" ) ); Relation* pRoutes = ( Relation* ) args[1].addr; Relation* pJunctions = ( Relation* ) args[2].addr; pNetwork->Load ( iId, pRoutes, pJunctions ); result = SetWord ( pNetwork ); return 0; } const string OpNetworkTheNetworkSpec = "((\"Signature\" \"Syntax\" \"Meaning\" " "\"Example\") " "(int x rel x rel -> network" "" "thenetwork(_, _, _)" "Creates network with id or next free id." "let n = thenetwork(int, routes, junctions)" "))"; Operator networkthenetwork ( "thenetwork", // name OpNetworkTheNetworkSpec, // specification OpNetworkTheNetworkValueMapping, // value mapping Operator::SimpleSelect, // trivial selection function OpNetworkTheNetworkTypeMap // type mapping ); /* 4.12 Operator ~no\_components~ Returns the number of ~RouteIntervals~ of the ~GLine~. */ ListExpr OpNoComponentsTypeMap ( ListExpr args ) { if ( nl->ListLength ( args ) != 1 ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr gline = nl->First ( args ); if ( !nl->IsAtom ( gline ) || nl->AtomType ( gline ) != SymbolType || nl->SymbolValue ( gline ) != "gline" ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } return nl->SymbolAtom ( CcInt::BasicType() ); } int OpNoComponentsValueMapping ( Word* args, Word& result, int message, Word& local, Supplier in_pSupplier ) { GLine* pGline = ( GLine* ) args[0].addr; result = qp->ResultStorage ( in_pSupplier ); CcInt* pResult = ( CcInt* ) result.addr; if ( ! ( pGline->IsDefined() ) ) { pResult->Set ( false, 0 ); return 0; }; pResult-> Set ( true, pGline->NoOfComponents() ); return 1; } const string OpNoComponentsSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( gline -> int" "" "no_components(_)" "Returns the number of route intervals." "query no_components(gline)" ") )"; Operator networknocomponents ( "no_components", // name OpNoComponentsSpec, // specification OpNoComponentsValueMapping, // value mapping Operator::SimpleSelect, // selection function OpNoComponentsTypeMap // type mapping ); /* 4.13 Operator ~point2gpoint~ Translates a spatial ~Point~ value into a network ~GPoint~ value if possible. */ ListExpr OpPoint2GPointTypeMap ( ListExpr in_xArgs ) { if ( nl->ListLength ( in_xArgs ) != 2 ) { sendMessage ( "Expects a list of length 2." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr xNetworkIdDesc = nl->First ( in_xArgs ); ListExpr xMPointDesc = nl->Second ( in_xArgs ); if ( ( !nl->IsAtom ( xNetworkIdDesc ) ) || !nl->IsEqual ( xNetworkIdDesc, "network" ) ) { sendMessage ( "First element must be of type network." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } if ( ( !nl->IsAtom ( xMPointDesc ) ) || nl->AtomType ( xMPointDesc ) != SymbolType || nl->SymbolValue ( xMPointDesc ) != Point::BasicType() ) { sendMessage ( "Second element must be of type point." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } return nl->SymbolAtom ( "gpoint" ); } int OpPoint2GPointValueMapping ( Word* args, Word& result, int message, Word& local, Supplier in_xSupplier ) { GPoint* pGPoint = ( GPoint* ) qp->ResultStorage ( in_xSupplier ).addr; result = SetWord ( pGPoint ); Network* pNetwork = ( Network* ) args[0].addr; if ( pNetwork == 0 || !pNetwork->IsDefined() ) { string strMessage = "Network is not defined."; cerr << strMessage << endl; sendMessage ( strMessage ); pGPoint->SetDefined ( false ); return 0; } Point* pPoint = ( Point* ) args[1].addr; if ( pPoint == NULL || !pPoint->IsDefined() ) { string strMessage = "Point does not exist."; cerr << strMessage << endl; sendMessage ( strMessage ); pGPoint->SetDefined ( false ); return 0; } GPoint *res = pNetwork->GetNetworkPosOfPoint ( *pPoint ); pGPoint->CopyFrom ( res ); res->DeleteIfAllowed(); /*GPoint *res = pNetwork->GetNetworkPosOfPoint(*pPoint); qp->ChangeResultStorage(in_xSupplier, res);*/ return 0; } //end ValueMapping const string OpPoint2GPointSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( network x point -> gpoint" "" "point2gpoint(networkobject, point)" "Translates a point to a gpoint." "point2gpoint(b_network, point)" ") )"; Operator point2gpoint ( "point2gpoint", // name OpPoint2GPointSpec, // specification OpPoint2GPointValueMapping, // value mapping Operator::SimpleSelect, // selection function OpPoint2GPointTypeMap // type mapping ); /* 4.14 Operator ~gpoint2point~ Translates a ~gpoint~ into a spatial ~Point~ value. */ ListExpr OpGPoint2PointTypeMap ( ListExpr in_xArgs ) { if ( nl->ListLength ( in_xArgs ) != 1 ) { sendMessage ( "Expects a list of length 1." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr xMPointDesc = nl->First ( in_xArgs ); if ( ( !nl->IsAtom ( xMPointDesc ) ) || nl->AtomType ( xMPointDesc ) != SymbolType || nl->SymbolValue ( xMPointDesc ) != "gpoint" ) { sendMessage ( "Element must be of type gpoint." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } return nl->SymbolAtom ( Point::BasicType() ); } int OpGPoint2PointValueMapping ( Word* args, Word& result, int message, Word& local, Supplier in_xSupplier ) { Point* pPoint = ( Point* ) qp->ResultStorage ( in_xSupplier ).addr; result = SetWord ( pPoint ); GPoint* pGPoint = ( GPoint* ) args[0].addr; if ( pGPoint == NULL || !pGPoint->IsDefined() ) { string strMessage = "Point does not exist."; cerr << strMessage << endl; sendMessage ( strMessage ); pPoint->SetDefined ( false ); return 0; } pGPoint->ToPoint ( pPoint ); return 0; } //end ValueMapping const string OpGPoint2PointSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( gpoint -> point" "" "gpoint2point(gpoint)" "Translates a gpoint to a point." "gpoint2point(gpoint)" ") )"; Operator gpoint2point ( "gpoint2point", // name OpGPoint2PointSpec, // specification OpGPoint2PointValueMapping, // value mapping Operator::SimpleSelect, // selection function OpGPoint2PointTypeMap // type mapping ); /* 4.15 Operator ~polygpoint~ Returns a stream of all ~GPoint~ values which are at the same network position as the given ~GPoint~. Including the given ~GPoint~. */ ListExpr OpPolyGPointTypeMap ( ListExpr in_xArgs ) { if ( nl->ListLength ( in_xArgs ) != 2 ) { sendMessage ( "Expects a list of length 1." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr xsource = nl->First ( in_xArgs ); ListExpr xnetwork = nl->Second ( in_xArgs ); if ( ( !nl->IsAtom ( xsource ) ) || !nl->IsEqual ( xsource, "gpoint" ) ) { sendMessage ( "First Element must be of type gpoint." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } if ( ( !nl->IsAtom ( xnetwork ) ) || !nl->IsEqual ( xnetwork, "network" ) ) { sendMessage ( "Second Element must be of type network." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } return nl->TwoElemList ( nl->SymbolAtom ( Symbol::STREAM() ), nl->SymbolAtom ( "gpoint" ) ); } int OpPolyGPointValueMapping ( Word* args, Word& result, int message, Word& local, Supplier in_xSupplier ) { GPointList* localinfo; GPoint res; result = qp->ResultStorage ( in_xSupplier ); switch ( message ) { case OPEN: local = SetWord ( new GPointList ( ( GPoint* ) args[0].addr, ( Network* ) args[1].addr ) ); return 0; case REQUEST: localinfo = ( GPointList* ) local.addr; res = localinfo->NextGPoint(); if ( !res.IsDefined() ) { return CANCEL; } else { result = SetWord ( new GPoint ( res ) ); return YIELD; } case CLOSE: if ( local.addr != 0 ) { delete ( GPointList* ) local.addr; local = SetWord ( Address ( 0 ) ); } return 0; } return 0; // ignore unknown message } //end ValueMapping const string OpPolyGPointSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( gpoint x network -> stream(gpoint)" "" "gpoint polygpoint" "Returns the gpoint and gpoints with the same network position" " if the gpoint is a junction." " polygpoints (gpoint, network) " ") )"; Operator polygpoints ( "polygpoints", // name OpPolyGPointSpec, // specification OpPolyGPointValueMapping, // value mapping Operator::SimpleSelect, // selection function OpPolyGPointTypeMap // type mapping ); /* 4.16 Operator ~routeintervals~ Returns a stream of rectangles representing the ~RouteIntervals~ of the ~GLine~. */ ListExpr OpRouteIntervalsTypeMap ( ListExpr in_xArgs ) { if ( nl->ListLength ( in_xArgs ) != 1 ) { sendMessage ( "Expects a list of length 1." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr xsource = nl->First ( in_xArgs ); if ( ( !nl->IsAtom ( xsource ) ) || !nl->IsEqual ( xsource, "gline" ) ) { sendMessage ( "First Element must be of type gline." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } return nl->TwoElemList ( nl->SymbolAtom ( Symbol::STREAM() ), nl->SymbolAtom ( Rectangle<2>::BasicType() ) ); } int OpRouteIntervalsValueMapping ( Word* args, Word& result, int message, Word& local, Supplier in_xSupplier ) { RectangleList* localinfo; Rectangle<2> res; result = qp->ResultStorage ( in_xSupplier ); switch ( message ) { case OPEN: local = SetWord ( new RectangleList ( ( GLine* ) args[0].addr ) ); return 0; case REQUEST: localinfo = ( RectangleList* ) local.addr; res = localinfo->NextRectangle(); if ( !res.IsDefined() ) return CANCEL; else { result = SetWord ( new Rectangle<2> ( res ) ); return YIELD; } case CLOSE: if ( local.addr != 0 ) { delete ( RectangleList* ) local.addr; local = SetWord ( Address ( 0 ) ); } return 0; } return 0; // ignore unknown message } //end ValueMapping const string OpRouteIntervalsSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( gline -> stream(rect)" "" "routeintervals(GLINE)" "Returns a stream of rectangles representing the route intervals of the" " gline." " routeintervals (gline) " ") )"; Operator networkrouteintervals ( "routeintervals", // name OpRouteIntervalsSpec, // specification OpRouteIntervalsValueMapping, // value mapping Operator::SimpleSelect, // selection function OpRouteIntervalsTypeMap // type mapping ); /* 4.17 Operator ~shortest\_path~ Returns the shortest path in the ~Network~ between two ~GPoint~. Using Dijkstra Algorithm to compute the shortest path. */ ListExpr OpShortestPathTypeMap ( ListExpr in_xArgs ) { if ( nl->ListLength ( in_xArgs ) != 2 ) return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); ListExpr xGPoint1Desc = nl->First ( in_xArgs ); ListExpr xGPoint2Desc = nl->Second ( in_xArgs ); // ListExpr xGPoint3Desc = nl->Third(in_xArgs); if ( ( !nl->IsAtom ( xGPoint1Desc ) ) || nl->AtomType ( xGPoint1Desc ) != SymbolType || nl->SymbolValue ( xGPoint1Desc ) != "gpoint" ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } if ( ( !nl->IsAtom ( xGPoint2Desc ) ) || nl->AtomType ( xGPoint2Desc ) != SymbolType || nl->SymbolValue ( xGPoint2Desc ) != "gpoint" ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } //if((!nl->IsAtom(xGPoint3Desc))|| (!nl->IsEqual(xGPoint3Desc,"network"))) { // return (nl->SymbolAtom(Symbol::TYPEERROR())); //} return nl->SymbolAtom ( "gline" ); } int OpShortestPathValueMapping ( Word* args, Word& result, int message, Word& local, Supplier in_xSupplier ) { GPoint *pFromGPoint = ( GPoint* ) args[0].addr; GPoint *pToGPoint = ( GPoint* ) args[1].addr; GLine* pGLine = ( GLine* ) qp->ResultStorage ( in_xSupplier ).addr; result = SetWord ( pGLine ); pGLine->SetSorted ( false ); pGLine->SetDefined ( pFromGPoint->ShortestPath ( pToGPoint, pGLine ) ); return 0; } const string OpShortestPathSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( gpoint x gpoint -> gline" "" "shortest_path( _ , _)" "Calculates the shortest path between two gpoints." "query shortest_path(x, y)" ") )"; Operator shortest_path ( "shortest_path", // name OpShortestPathSpec, // specification OpShortestPathValueMapping, // value mapping Operator::SimpleSelect, // trivial selection function OpShortestPathTypeMap // type mapping ); /* 4.18 Operator ~gline2line~ Returns the ~line~ value of the given ~GLine~. */ ListExpr OpGLine2LineTypeMap ( ListExpr in_xArgs ) { if ( nl->ListLength ( in_xArgs ) != 1 ) { sendMessage ( "Expects a list of length 1." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr xsource = nl->First ( in_xArgs ); if ( ( !nl->IsAtom ( xsource ) ) || !nl->IsEqual ( xsource, "gline" ) ) { sendMessage ( "Element must be of type gline." ); return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } return nl->SymbolAtom ( Line::BasicType() ); } int OpGLine2LineValueMapping ( Word* args, Word& result, int message, Word& local, Supplier in_xSupplier ) { Line* pLine = ( Line* ) qp->ResultStorage ( in_xSupplier ).addr; result = SetWord ( pLine ); GLine* pGLine = ( GLine* ) args[0].addr; if ( pGLine == NULL || !pGLine->IsDefined() ) { sendMessage ( "GLine must be defined!" ); pLine->SetDefined ( false ); return 0; } pGLine->Gline2line ( pLine ); return 0; } const string OpGLine2LineSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( gline -> line" "" "gline2line(GLINE)" "Returns the line value of the gline." " gline2line(gline) " ") )"; Operator networkgline2line ( "gline2line", // name OpGLine2LineSpec, // specification OpGLine2LineValueMapping, // value mapping Operator::SimpleSelect, // selection function OpGLine2LineTypeMap // type mapping ); /* 4.19 Operator ~isempty~ Returns if the ~GLine~. is empty. */ ListExpr OpNetIsEmptyTypeMap ( ListExpr args ) { if ( nl->ListLength ( args ) != 1 ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr gline = nl->First ( args ); if ( !nl->IsAtom ( gline ) || nl->AtomType ( gline ) != SymbolType || nl->SymbolValue ( gline ) != "gline" ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } return nl->SymbolAtom ( CcBool::BasicType() ); } int OpNetIsEmptyValueMap ( Word* args, Word& result, int message, Word& local, Supplier in_pSupplier ) { GLine* pGline = ( GLine* ) args[0].addr; result = qp->ResultStorage ( in_pSupplier ); CcBool* pResult = ( CcBool* ) result.addr; if ( ( ! ( pGline->IsDefined() ) ) || pGline->NoOfComponents() == 0 ) { pResult->Set ( true, true ); return 0; } else { pResult->Set ( true,false ); return 0; } } const string OpNetIsEmptySpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( gline -> bool" "" "isemtpy(_)" "Returns true if the gline is empty." "query isempty(gline)" ") )"; Operator networkisempty ( "isempty", // name OpNetIsEmptySpec, // specification OpNetIsEmptyValueMap, // value mapping Operator::SimpleSelect, // selection function OpNetIsEmptyTypeMap // type mapping ); /* 4.20 Operator ~union~ Builds the union of the two given glines as sorted gline. */ ListExpr OpNetUnionTypeMap ( ListExpr args ) { if ( nl->ListLength ( args ) != 2 ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr gline1 = nl->First ( args ); ListExpr gline2 = nl->Second ( args ); if ( !nl->IsAtom ( gline1 ) || nl->AtomType ( gline1 ) != SymbolType || nl->SymbolValue ( gline1 ) != "gline" ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } if ( !nl->IsAtom ( gline2 ) || nl->AtomType ( gline2 ) != SymbolType || nl->SymbolValue ( gline2 ) != "gline" ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } return nl->SymbolAtom ( "gline" ); } int OpNetUnionValueMap ( Word* args, Word& result, int message, Word& local, Supplier in_pSupplier ) { GLine *pGL1 = ( GLine* ) args[0].addr; GLine *pGL2 = ( GLine* ) args[1].addr; GLine *pGLine = ( GLine* ) qp->ResultStorage ( in_pSupplier ).addr; result = SetWord ( pGLine ); pGL1->Uniongl ( pGL2, pGLine ); return 0; } const string OpNetUnionSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( gline x gline -> gline" "" "_ union _ " "Returns the sorted gline resulting of the union of both " "gline." "query gline1 union gline2" ") )"; Operator networkunion ( "union", // name OpNetUnionSpec, // specification OpNetUnionValueMap, // value mapping Operator::SimpleSelect, // selection function OpNetUnionTypeMap // type mapping ); /* 4.21 Operator ~distance~ Returns the Euclidean Distance between two ~Gpoints~ or two ~GLines~. */ ListExpr OpNetDistanceTypeMap ( ListExpr args ) { if ( nl->ListLength ( args ) != 2 ) { return ( nl->SymbolAtom ( Symbol::TYPEERROR() ) ); } ListExpr param1 = nl->First ( args ); ListExpr param2 = nl->Second ( args ); if ( ( nl->IsAtom ( param1 ) && nl->AtomType ( param1 ) == SymbolType && nl->IsAtom ( param2 ) && nl->AtomType ( param2 ) == SymbolType && ( ( nl->SymbolValue ( param1 ) == "gpoint" && nl->SymbolValue ( param2 ) == "gpoint" ) || ( nl->SymbolValue ( param1 ) == "gline" && nl->SymbolValue ( param2 ) == "gline" ) ) ) ) { return nl->SymbolAtom ( CcReal::BasicType() ); } return nl->SymbolAtom ( Symbol::TYPEERROR() ); } int OpNetDistance_gpgp ( Word* args, Word& result, int message, Word& local, Supplier in_pSupplier ) { GPoint* pFromGPoint = ( GPoint* ) args[0].addr; GPoint* pToGPoint = ( GPoint* ) args[1].addr; result = qp->ResultStorage ( in_pSupplier ); CcReal* pResult = ( CcReal* ) result.addr; if ( ! ( pFromGPoint->IsDefined() ) || ! ( pToGPoint->IsDefined() ) ) { cmsg.inFunError ( "Both gpoint must be defined!" ); return 0; }; pResult-> Set ( true, pFromGPoint->Distance ( pToGPoint ) ); return 0; }; int OpNetDistance_glgl ( Word* args, Word& result, int message, Word& local, Supplier in_pSupplier ) { GLine* pGLine1 = ( GLine* ) args[0].addr; GLine* pGLine2 = ( GLine* ) args[1].addr; result = qp->ResultStorage ( in_pSupplier ); CcReal* pResult = ( CcReal* ) result.addr; if ( ! ( pGLine1->IsDefined() ) || ! ( pGLine2->IsDefined() ) || pGLine1->NoOfComponents() == 0 || pGLine2->NoOfComponents() == 0 ) { cmsg.inFunError ( "Both gline must be defined! And have at least 1 interval" ); return 0; }; pResult-> Set ( true, pGLine1->Distance ( pGLine2 ) ); return 1; }; ValueMapping OpNetDistancemap[] = { OpNetDistance_gpgp, OpNetDistance_glgl }; int OpNetDistanceselect ( ListExpr args ) { ListExpr arg1 = nl->First ( args ); ListExpr arg2 = nl->Second ( args ); if ( nl->SymbolValue ( arg1 ) == "gpoint" && nl->SymbolValue ( arg2 ) == "gpoint" ) return 0; if ( nl->SymbolValue ( arg1 ) == "gline" && nl->SymbolValue ( arg2 ) == "gline" ) return 1; return -1; // This point should never be reached }; const string OpNetDistanceSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( A x A -> real with A = gpoint or gline" "" "distance(GPOINT1,GPOINT2)" "Calculates the Euclidean Distance of gpoints resp. glines." "query distance(gp1,gp2)" ") )"; Operator networkdistance ( "distance", // name OpNetDistanceSpec, // specification 2, OpNetDistancemap, // value mapping OpNetDistanceselect, // selection function OpNetDistanceTypeMap // type mapping ); /* 4.22 Operator ~update\_sectioncost~ Updates the costs of one or more sections. The oprator expects two or three arguments. The first argument should be a network. Is the number of arguments two. The second agument should be a relation like (rel (tuple ((sid int) (cost real)))). If the number of arguments is three, then the second argument should be an sectionid (int) and the third argument should be the cost of the section (real). */ ListExpr OpUpdateSectionCostTypeMap ( ListExpr in_xArgs ){ NList param(in_xArgs); //check the number of arguments if(param.length() <2 || param.length() >3) { return listutils::typeError( "update_sectioncost expects either 2 or 3 arguments."); } ListExpr xNetworkDesc = nl->First(in_xArgs); //check the type of the first arguments if ( ( !nl->IsAtom ( xNetworkDesc ) ) || !nl->IsEqual ( xNetworkDesc, "network" ) ) { return listutils::typeError("1.argument should be a network"); } if (param.length() == 2) { //read the arguments ListExpr xRelDesc = nl->Second(in_xArgs); if ( !IsRelDescription ( xRelDesc ) ) { return listutils::typeError( "2.agument should be a relation" ); } ListExpr xType; string costsTypeInfo = "(rel (tuple ((sid int) (cost real))))"; nl->ReadFromString ( costsTypeInfo, xType ); if ( !CompareSchemas ( xRelDesc, xType ) ) { return listutils::typeError("the pattern of the relation ist wrong"); } } if ( param.length() == 3 ) { //read the arguments ListExpr xIdDesc = nl->Second(in_xArgs); ListExpr xCostDesc = nl->Third(in_xArgs); if (!nl->IsEqual(xIdDesc, CcInt::BasicType())) { return listutils::typeError("2.argument should be an int."); } if(!nl->IsEqual (xCostDesc, CcReal::BasicType())) { return listutils::typeError("3.argument should be an real."); } } return nl->SymbolAtom ( CcBool::BasicType() ); } int OpUpdateSectionCost_One ( Word* args, Word& result, int message, Word& local, Supplier in_pSupplier ) { Network* pNetwork = ( Network* ) args[0].addr; int secId = (( CcInt* ) args[1].addr)->GetIntval(); double newCost = (( CcReal* ) args[2].addr)->GetRealval(); result = qp->ResultStorage ( in_pSupplier ); CcBool* pResult = ( CcBool* ) result.addr; if ( pNetwork == 0 || !pNetwork->IsDefined() ) { string strMessage = "Network is not defined."; cerr << strMessage << endl; sendMessage ( strMessage ); pResult->Set ( false, false ); return 0; } qp->SetModified(qp->GetSon(in_pSupplier,0)); pResult->Set ( true, pNetwork->UpdateSectionCost(secId,newCost)); return 0; } int OpUpdateSectionCost_More ( Word* args, Word& result, int message, Word& local, Supplier in_pSupplier ) { Network* pNetwork = ( Network* ) args[0].addr; Relation* pCosts = ( Relation* ) args[1].addr; result = qp->ResultStorage ( in_pSupplier ); CcBool* pResult = ( CcBool* ) result.addr; if ( pNetwork == 0 || !pNetwork->IsDefined() ) { string strMessage = "Network is not defined."; cerr << strMessage << endl; sendMessage ( strMessage ); pResult->Set ( false, false ); return 0; } qp->SetModified(qp->GetSon(in_pSupplier,0)); pResult->Set ( true, pNetwork->UpdateMoreSectionCost(pCosts)); return 0; } ValueMapping OpUpdateSectionCostMap[]= { OpUpdateSectionCost_One, OpUpdateSectionCost_More }; int OpUpdateSectionCostSelect(ListExpr in_xArgs){ NList param(in_xArgs); //check the number of arguments if ( param.length() == 3 ){ return 0; } if(param.length() == 2){ return 1; } return -1; } const string OpUpdateSectionCostSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( network x A [x real] -> bool with A as int or as rel " " update_sectioncost(_,_,_) " "Returns true, when the Update was successful." "query update_sectioncost(B_NETWORK,1,5.0)" ") )"; Operator update_sectioncost ( "update_sectioncost", // name OpUpdateSectionCostSpec, // specification 2, OpUpdateSectionCostMap, // value mapping OpUpdateSectionCostSelect, // selection function OpUpdateSectionCostTypeMap // type mapping ); /* 4.23 Operator ~update\_sectionduration~ Updates the duration of one or more sections. The oprator expects two or three arguments. The first argument should be a network. Is the number of arguments two. The second agument should be a relation like (rel (tuple ((sid int) (duration real)))). If the number of arguments is three, then the second argument should be an sectionid (int) and the third argument should be the duration of the section (real). */ ListExpr OpUpdateSectionDurationTypeMap ( ListExpr in_xArgs ){ NList param(in_xArgs); //check the number of arguments if(param.length() <2 || param.length() >3){ return listutils::typeError( "update_sectionduration expects either 2 or 3 arguments."); } ListExpr xNetworkDesc = nl->First(in_xArgs); //check the type of the first arguments if ( ( !nl->IsAtom ( xNetworkDesc ) ) || !nl->IsEqual ( xNetworkDesc, "network" ) ) { return listutils::typeError("1.argument should be a network"); } if (param.length() == 2) { //read the arguments ListExpr xRelDesc = nl->Second(in_xArgs); if ( !IsRelDescription ( xRelDesc ) ) { return listutils::typeError( "2.agument should be a relation" ); } ListExpr xType; string durationsTypeInfo = "(rel (tuple ((sid int) (duration real))))"; nl->ReadFromString ( durationsTypeInfo, xType ); if ( !CompareSchemas ( xRelDesc, xType ) ) { return listutils::typeError("the pattern of the relation ist wrong"); } } if ( param.length() == 3 ) { //read the arguments ListExpr xIdDesc = nl->Second(in_xArgs); ListExpr xDurationDesc = nl->Third(in_xArgs); if (!nl->IsEqual(xIdDesc, CcInt::BasicType())) { return listutils::typeError("2.argument should be an int."); } if(!nl->IsEqual (xDurationDesc, CcReal::BasicType())) { return listutils::typeError("3.argument should be an real."); } } return nl->SymbolAtom ( CcBool::BasicType() ); } int OpUpdateSectionDuration_One ( Word* args, Word& result, int message, Word& local, Supplier in_pSupplier ) { Network* pNetwork = ( Network* ) args[0].addr; int secId = (( CcInt* ) args[1].addr)->GetIntval(); double newDuration = (( CcReal* ) args[2].addr)->GetRealval(); result = qp->ResultStorage ( in_pSupplier ); CcBool* pResult = ( CcBool* ) result.addr; if ( pNetwork == 0 || !pNetwork->IsDefined() ) { string strMessage = "Network is not defined."; cerr << strMessage << endl; sendMessage ( strMessage ); pResult->Set ( false, false ); return 0; } qp->SetModified(qp->GetSon(in_pSupplier,0)); pResult->Set ( true, pNetwork->UpdateSectionDuration(secId,newDuration)); return 0; } int OpUpdateSectionDuration_More ( Word* args, Word& result, int message, Word& local, Supplier in_pSupplier ) { Network* pNetwork = ( Network* ) args[0].addr; Relation* pDurations = ( Relation* ) args[1].addr; result = qp->ResultStorage ( in_pSupplier ); CcBool* pResult = ( CcBool* ) result.addr; if ( pNetwork == 0 || !pNetwork->IsDefined() ) { string strMessage = "Network is not defined."; cerr << strMessage << endl; sendMessage ( strMessage ); pResult->Set ( false, false ); return 0; } qp->SetModified(qp->GetSon(in_pSupplier,0)); pResult->Set ( true, pNetwork->UpdateMoreSectionDuration(pDurations)); return 0; } ValueMapping OpUpdateSectionDurationMap[]= { OpUpdateSectionDuration_One, OpUpdateSectionDuration_More }; int OpUpdateSectionDurationSelect(ListExpr in_xArgs){ NList param(in_xArgs); //check the number of arguments if ( param.length() == 3 ){ return 0; } if(param.length() == 2){ return 1; } return -1; } const string OpUpdateSectionDurationSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( network x A [x real] -> bool with A as int or as rel " " update_sectionduration(_,_,_) " "Returns true, when the Update was successful." "query update_sectionduration(B_NETWORK,1,5.0)" ") )"; Operator update_sectionduration ( "update_sectionduration", // name OpUpdateSectionDurationSpec, // specification 2, OpUpdateSectionDurationMap, // value mapping OpUpdateSectionDurationSelect, // selection function OpUpdateSectionDurationTypeMap // type mapping ); /* 4.24 Operator ~shortespath\_astarplus~ Returns the shortest path in the ~Network~ between two ~GPoint~. Using AStar-Algorithm to compute the shortest path. The operator expects either 2 or 3 arguments. The first and the second argument should be a gpoint. If the number of arguments ist three, then the third argument should be a function with three parameters. */ ListExpr OpShortestPathAStarPlusTypeMap ( ListExpr in_xArgs ) { //check the number of arguments if(nl->ListLength ( in_xArgs ) <2 || nl->ListLength ( in_xArgs ) >3){ return listutils::typeError( "shortestpath_astarplus expects either 2 or 3 arguments."); } ListExpr xGPoint1Desc = nl->First (in_xArgs); ListExpr xGPoint2Desc = nl->Second (in_xArgs); if ( ( !nl->IsAtom ( xGPoint1Desc ) ) || nl->AtomType ( xGPoint1Desc ) != SymbolType || nl->SymbolValue ( xGPoint1Desc ) != "gpoint" ) { return listutils::typeError("the first parameter should be a gpoint."); } if ( ( !nl->IsAtom ( xGPoint2Desc ) ) || nl->AtomType ( xGPoint2Desc ) != SymbolType || nl->SymbolValue ( xGPoint2Desc ) != "gpoint" ) { return listutils::typeError("the second parameter should be a gpoint."); } if(nl->ListLength ( in_xArgs ) == 3) { ListExpr map = nl->Third(in_xArgs); if ( nl->IsAtom( map ) || !( nl->IsEqual(nl->First(map), Symbol::MAP()) ) ) { return listutils::typeError( "the third parameter should be a function."); } else { if ( nl->ListLength(map) != 5) { return NList::typeError( "the third parameter should be a function with three parameter."); } if(!( nl->IsEqual(nl->Second(map), CcReal::BasicType())) || !( nl->IsEqual(nl->Third(map), CcReal::BasicType())) || !( nl->IsEqual(nl->Fourth(map), CcReal::BasicType())) ){ return listutils::typeError( "one or more parameters has the wrong type, it should be a real."); } } } return nl->SymbolAtom ( "gline" ); } int OpShortestPathAStarPlusValueMapping ( Word* args, Word& result, int message, Word& local, Supplier in_xSupplier ) { GPoint *pFromGPoint = ( GPoint* ) args[0].addr; GPoint *pToGPoint = ( GPoint* ) args[1].addr; Word func = args[2].addr; GLine* pGLine = ( GLine* ) qp->ResultStorage ( in_xSupplier ).addr; result = SetWord ( pGLine ); pGLine->SetSorted ( false ); pGLine->SetDefined ( pFromGPoint->ShortestPathAStarPlus ( pToGPoint, pGLine, func ) ); return 0; } const string OpShortestPathAStarPlusSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( gpoint x gpoint [x A] -> gline with A as (map real real real real)" "" "shortestpath_astarplus( _ , _ ,_)" "Calculates the shortest path between two " "gpoints with the astar-algorithm." "query shortestpath_astarplus([const gpoint value(1 2 0.0 0)]," "[const gpoint value(1 10 5.0 1)]);" ") )"; Operator shortestpath_astarplus ( "shortestpath_astarplus", // name OpShortestPathAStarPlusSpec, // specification OpShortestPathAStarPlusValueMapping, // value mapping Operator::SimpleSelect, // trivial selection function OpShortestPathAStarPlusTypeMap // type mapping ); /* 4.25 Operator ~optimize\_network~ Optimizes the given ~network~ by all routes contained sorted by lexicographic starting point and all sections are rearranged. */ ListExpr OpOptimizeNetworkTypeMap ( ListExpr in_xArgs ) { //check the number of arguments if(nl->ListLength ( in_xArgs ) !=1){ return listutils::typeError( "optimize_network expects only one argument."); } ListExpr xNetworkDesc = nl->First(in_xArgs); //check the type of the first arguments if ( ( !nl->IsAtom ( xNetworkDesc ) ) || !nl->IsEqual ( xNetworkDesc, "network" ) ) { return listutils::typeError("1.argument should be a network"); } return nl->SymbolAtom ( CcBool::BasicType() ); } int OpOptimizeNetworkValueMapping ( Word* args, Word& result, int message, Word& local, Supplier in_xSupplier ) { Network* pNetwork = ( Network* ) args[0].addr; result = qp->ResultStorage ( in_xSupplier ); CcBool* pResult = ( CcBool* ) result.addr; if ( pNetwork == 0 || !pNetwork->IsDefined() ) { string strMessage = "Network is not defined."; cerr << strMessage << endl; sendMessage ( strMessage ); pResult->Set ( false, false ); return 0; } qp->SetModified(qp->GetSon(in_xSupplier,0)); pResult->Set ( true, pNetwork->OptimizeNetwork()); return 0; } const string OpOptimizeNetworkSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( network -> bool)" "" "optimizenet( _ )" "Optimized the storage of the sections." "query optimize_network(B_NETWORK)]);" ") )"; Operator optimizenet ( "optimizenet", // name OpOptimizeNetworkSpec, // specification OpOptimizeNetworkValueMapping, // value mapping Operator::SimpleSelect, // trivial selection function OpOptimizeNetworkTypeMap // type mapping ); /* 4.26 Operator ~print\_adjacencylist~ Prints infromations of routes, sections and their neighbours of the given ~network~. */ ListExpr OpPrintAdjacencyListTypeMap ( ListExpr in_xArgs ) { //check the number of arguments if(nl->ListLength ( in_xArgs ) !=1){ return listutils::typeError( "optimize_network expects only one argument."); } ListExpr xNetworkDesc = nl->First(in_xArgs); //check the type of the first arguments if ( ( !nl->IsAtom ( xNetworkDesc ) ) || !nl->IsEqual ( xNetworkDesc, "network" ) ) { return listutils::typeError("1.argument should be a network"); } return nl->SymbolAtom ( CcBool::BasicType() ); } int OpPrintAdjacencyListValueMapping ( Word* args, Word& result, int message, Word& local, Supplier in_xSupplier ) { Network* pNetwork = ( Network* ) args[0].addr; result = qp->ResultStorage ( in_xSupplier ); CcBool* pResult = ( CcBool* ) result.addr; if ( pNetwork == 0 || !pNetwork->IsDefined() ) { string strMessage = "Network is not defined."; cerr << strMessage << endl; sendMessage ( strMessage ); pResult->Set ( false, false ); return 0; } pResult->Set ( true, pNetwork->PrintAdjacentSectionInfo()); return 0; } const string OpPrintAdjacencyListSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( network -> bool)" "" "print_adjacencylist( _ )" "print the informations about the adjacent sections." "query print_adjacencylist(B_NETWORK)]);" ") )"; Operator print_adjacencylist ( "print_adjacencylist", // name OpPrintAdjacencyListSpec, // specification OpPrintAdjacencyListValueMapping, // value mapping Operator::SimpleSelect, // trivial selection function OpPrintAdjacencyListTypeMap // type mapping ); /* 5 Creating the ~NetworkAlgebra~ */ class NetworkAlgebra : public Algebra { public: NetworkAlgebra() : Algebra() { AddTypeConstructor ( &network ); AddTypeConstructor ( &gpoint ); AddTypeConstructor ( &gline ); AddTypeConstructor ( &gpoints ); gpoint.AssociateKind ( Kind::DATA() ); gline.AssociateKind ( Kind::DATA() ); network.AssociateKind ( Kind::NETWORK() ); gpoints.AssociateKind ( Kind::DATA() ); AddOperator ( &networkthenetwork ); AddOperator ( &networkroutes ); AddOperator ( &networkjunctions ); AddOperator ( &networksections ); AddOperator ( &shortest_path ); AddOperator ( &networklength ); AddOperator ( &networknetdistance ); AddOperator ( &point2gpoint ); AddOperator ( &gpoint2point ); AddOperator ( &netgpequal ); AddOperator ( &sline2gline ); AddOperator ( &networkinside ); AddOperator ( &networknocomponents ); AddOperator ( &polygpoints ); AddOperator ( &networkrouteintervals ); AddOperator ( &networkintersects ); AddOperator ( &networkgpoint2rect ); AddOperator ( &networkgline2line ); AddOperator ( &networkisempty ); AddOperator ( &networkunion ); AddOperator ( &networkdistance ); AddOperator ( &update_sectioncost); AddOperator ( &update_sectionduration); AddOperator ( &shortestpath_astarplus); AddOperator ( &optimizenet); AddOperator ( &print_adjacencylist); } ~NetworkAlgebra() {delete netList;}; }; /* Initialization Each algebra module needs an initialization function. The algebra manager has a reference to this function if this algebra is included in the list of required algebras, thus forcing the linker to include this module. The algebra manager invokes this function to get a reference to the instance of the algebra class and to provide references to the global nested list container (used to store constructor, type, operator and object information) and to the query processor. The function has a C interface to make it possible to load the algebra dynamically at runtime. */ extern "C" Algebra* InitializeNetwork2Algebra ( NestedList* nlRef, QueryProcessor* qpRef ) { nl = nlRef; qp = qpRef; netList = new map(); return ( new NetworkAlgebra() ); }