/* This file is part of SECONDO. Copyright (C) 2011, 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 2012, May- Simone Jandt 1 Includes */ #include #include #include "AlgebraTypes.h" #include "ListUtils.h" #include "SecondoSystem.h" #include "Symbols.h" #include "LogMsg.h" #include "Algebras/Spatial/SpatialAlgebra.h" #include "Direction.h" #include "JNetwork.h" #include "RouteLocation.h" #include "JRouteInterval.h" #include "MJPoint.h" #include "JUnit.h" #include "JRITree.h" #include "JNetUtil.h" #include "Algebras/RTree/RTreeAlgebra.h" extern NestedList* nl; using namespace jnetwork; using namespace std; using namespace datetime; /* 1 Helpful Operations 1.1 ~getRelationCopy~ Returns a pointer to the copy of the relation of relPointer. */ OrderedRelation* getRelationCopy(const string relTypeInfo, OrderedRelation* relPointer) { ListExpr relType; nl->ReadFromString ( relTypeInfo, relType ); ListExpr relNumType = SecondoSystem::GetCatalog()->NumericType(relType); Word wrel; wrel.setAddr(relPointer); Word res = OrderedRelation::Clone(relNumType, wrel); return (OrderedRelation*) res.addr; } Relation* getRelationCopy(const string relTypeInfo, const Relation* relPointer) { ListExpr strPtr = listutils::getPtrList(relPointer); string querystring = "(consume (feed (" + relTypeInfo + "(ptr "+ nl->ToString(strPtr) + "))))"; Word resultWord; int QueryExecuted = QueryProcessor::ExecuteQuery(querystring, resultWord); assert (QueryExecuted); return (Relation*) resultWord.addr; } /* 1.1 ~relationToList~ Returns the list representation of rel. */ ListExpr relationToList(Relation* rel, const string relTypeInfo) { if (rel != 0) { GenericRelationIterator* it = rel->MakeScan(); ListExpr typeInfo; nl->ReadFromString(relTypeInfo, typeInfo); ListExpr relList = Relation::Out(typeInfo, it); return relList; } else return nl->TheEmptyList(); } ListExpr relationToList(OrderedRelation* rel, const string relTypeInfo) { if (rel != 0) { ListExpr typeInfo; nl->ReadFromString(relTypeInfo, typeInfo); Word w; w.setAddr(rel); ListExpr relList = OrderedRelation::Out(typeInfo, w); return relList; } else return nl->TheEmptyList(); } Relation* relationFromList(const ListExpr nlRel, const string descriptor, const int errorPos, ListExpr& errorInfo, bool& correct) { ListExpr relType; nl->ReadFromString(descriptor, relType); ListExpr relNumType = SecondoSystem::GetCatalog()->NumericType ( relType ); return (Relation*) Relation::In(relNumType, nlRel, errorPos, errorInfo, correct); } OrderedRelation* ordRelationFromList(const ListExpr nlRel, const string descriptor, const int errorPos, ListExpr& errorInfo, bool& correct) { ListExpr relType; nl->ReadFromString(descriptor, relType); ListExpr relNumType = SecondoSystem::GetCatalog()->NumericType ( relType ); Word wRel = OrderedRelation::In(relNumType, nlRel, errorPos, errorInfo, correct); return (OrderedRelation*) wRel.addr; } /* 1.1 ~createBTree~ Creates an BTree over the attribut attr of the given relation rel, which is described by descriptor. */ BTree* createBTree(const Relation* rel, const string descriptor, const string attr) { ListExpr relPtr = listutils::getPtrList(rel); string strQuery = "(createbtree (" + descriptor + " (ptr " + nl->ToString(relPtr) + "))" + attr + ")"; Word w; int QueryExecuted = QueryProcessor::ExecuteQuery ( strQuery, w); assert ( QueryExecuted ); return ( BTree* ) w.addr; } /* 1.1 ~createRTree~ Creates the RTree over the given spatial attribute attr of the given relation rel, which is described by descriptor. */ R_Tree<2,TupleId>* createRTree(const Relation* rel, const string descriptor, const string attr) { ListExpr relPtr = listutils::getPtrList(rel); string strQuery = "(bulkloadrtree(sortby(addid(feed (" + descriptor + " (ptr " + nl->ToString(relPtr) + "))))((" + attr +" asc)))" + attr +" TID)"; Word w; int QueryExecuted = QueryProcessor::ExecuteQuery ( strQuery, w ); assert ( QueryExecuted ); return ( R_Tree<2,TupleId>* ) w.addr; } /* 1.1 ~openRelation~ Opens the relation described by descriptor from valueRecord starting at offset. */ bool openRelation(Relation*& rel, const string descriptor, SmiRecord& valueRecord, size_t& offset) { ListExpr relType; nl->ReadFromString ( descriptor, relType ); ListExpr relNumType = SecondoSystem::GetCatalog()->NumericType(relType); rel = Relation::Open(valueRecord,offset,relNumType); return (rel != 0); } bool openRelation(OrderedRelation*& rel, const string descriptor, SmiRecord& valueRecord, size_t& offset) { rel = 0; ListExpr relType; nl->ReadFromString ( descriptor, relType ); ListExpr relNumType = SecondoSystem::GetCatalog()->NumericType(relType); Word wrel; bool ok = OrderedRelation::Open(valueRecord, offset, relNumType, wrel); if (ok) rel = (OrderedRelation*) wrel.addr; return ok; } /* 1.1 ~openBTree~ Opens the btree described by descriptor from valueRecord starting at offset. */ bool openBTree(BTree*& tree, const string descriptor, SmiRecord& valueRecord, size_t& offset) { ListExpr treeType; nl->ReadFromString(descriptor,treeType); ListExpr treeNumType = SecondoSystem::GetCatalog()->NumericType(treeType); tree = BTree::Open(valueRecord,offset,treeNumType); return (tree != 0); } /* 1.1 ~saveRelation~ */ bool saveRelation(const string descriptor, Relation* rel, SmiRecord& valueRecord, size_t& offset) { ListExpr relType; nl->ReadFromString ( descriptor, relType ); ListExpr relNumType = SecondoSystem::GetCatalog()->NumericType ( relType ); return rel->Save(valueRecord, offset, relNumType); } bool saveRelation(const string descriptor, OrderedRelation* rel, SmiRecord& valueRecord, size_t& offset) { ListExpr relType; nl->ReadFromString ( descriptor, relType ); ListExpr relNumType = SecondoSystem::GetCatalog()->NumericType ( relType ); Word wrel; wrel.setAddr(rel); return OrderedRelation::Save(valueRecord, offset, relNumType, wrel); } /* 1.1 ~saveBTree~ */ bool saveBTree(const string descriptor, BTree* tree, SmiRecord& valueRecord, size_t& offset) { ListExpr treeType; nl->ReadFromString ( descriptor, treeType ); ListExpr treeNumericType = SecondoSystem::GetCatalog()->NumericType ( treeType ); return tree->Save(valueRecord, offset, treeNumericType); } /* 1.1. reachedEndpoint Checks if curPQElement endJID is enclosed in endJunctions list */ bool reachedEndpoint(const JPQEntry* actEntry, const DbArray* endJunctions, double& dist, int& tgtPosInArray, bool& tgtIsStartJunc, int& srcStartPathJID) { PosJNetSpatial curEntry; int i = 0; double tmp = numeric_limits< double >::max(); while(i < endJunctions->Size()) { endJunctions->Get(i,curEntry); if(curEntry.GetStartJID() == actEntry->GetStartPartJID() && curEntry.GetSectionId() == actEntry->GetSectionId() ) { if (tmp > curEntry.GetDistFromStartJunction()) { tmp = curEntry.GetDistFromEndJunction(); tgtPosInArray = i; tgtIsStartJunc = false; srcStartPathJID = actEntry->GetStartPathJID(); } } if (curEntry.GetStartJID() == actEntry->GetEndPartJID()) { if (tmp > curEntry.GetDistFromStartJunction()) { tmp = curEntry.GetDistFromStartJunction(); tgtPosInArray = i; tgtIsStartJunc = true; srcStartPathJID = actEntry->GetStartPathJID(); } } if (curEntry.GetEndJID() == actEntry->GetEndPartJID()) { if (tmp > curEntry.GetDistFromEndJunction()) { tmp = curEntry.GetDistFromEndJunction(); tgtPosInArray = i; tgtIsStartJunc = false; srcStartPathJID = actEntry->GetStartPathJID(); } } i++; } dist = tmp; bool result = (tgtPosInArray > -1); return result; } void getStartPosJNet(const DbArray* srcEntries, const int srcStartPathJID, int& srcPosInArray, bool& srcOverStartJunc, PosJNetSpatial& start) { if (srcEntries != NULL && srcEntries->Size() > 0) { double minDist = numeric_limits< double >::max(); int i = 0; PosJNetSpatial tmp; while (i < srcEntries->Size()) { srcEntries->Get(i,tmp); if (tmp.GetStartJID() == srcStartPathJID) { if (minDist > tmp.GetDistFromStartJunction()) { minDist = tmp.GetDistFromStartJunction(); srcPosInArray = i; srcOverStartJunc = true; start = tmp; } } if (tmp.GetEndJID() == srcStartPathJID) { if (minDist > tmp.GetDistFromEndJunction()) { minDist = tmp.GetDistFromEndJunction(); srcPosInArray = i; srcOverStartJunc = false; start = tmp; } } i++; } } } double getLength(const DbArray* sp) { double result = 0.0; if (sp != NULL && sp->Size() > 0) { JRouteInterval rint(false); for (int i = 0; i < sp->Size(); i++) { sp->Get(i,rint); result = result + rint.GetLength(); } } return result; } /* 1.1 correctedPos Corrects rounding errors at start or end of an section curve. */ double correctedPos(const double oldpos, const double routeLength, const double tolerance) { if (AlmostEqualAbsolute(oldpos, routeLength, tolerance)) return routeLength; else if (AlmostEqualAbsolute(oldpos, 0.0, tolerance)) return 0.0; else return oldpos; } void checkEndTimeCorrected(bool& endTimeCorrected, Instant& instInter1, Instant& instInter2, const Instant TIMECORRECTION) { if (endTimeCorrected && instInter1 < instInter2) endTimeCorrected = false; if (instInter1 >= instInter2) { instInter2 = instInter1 + TIMECORRECTION; endTimeCorrected = true; } } Point* getPointFromCurveForPosRememberLRSPos(double pos, const SimpleLine* curve, LRS& lrs, int& lrspos) { Point result(false); if( !curve->GetStartSmaller()) pos = curve->Length() - pos; LRS lrs1( pos, 0 ); lrs = lrs1; if(curve->Find( lrs, lrspos )) { result.SetDefined( true ); curve->Get( lrspos, lrs ); HalfSegment hs; curve->Get( lrs.hsPos, hs ); result = hs.AtPosition( pos); } return new Point(result); } Point* getPointFromCurveForPosFromLRS(double pos, const SimpleLine* curve, LRS& lrs) { if( !curve->GetStartSmaller()) pos = curve->Length() - pos; HalfSegment hs; curve->Get( lrs.hsPos, hs ); return new Point(hs.AtPosition(pos-lrs.lrsPos)); } void addSimulatedTrip(const JUnit& ju, const Instant starttime, const Instant endtime, const bool lc, const bool rc, Point*& startPoint, const double epos, SimpleLine*& lastCurve, LRS& lrs, int& lrspos, Instant& lastEndTime, temporalalgebra::MPoint& result, const bool up, const Instant& TIMECORRECTION, bool& endTimeCorrected) { Instant instInter1 = starttime; Instant instInter2 = endtime; Point interStart(*startPoint); Point interEnd(*startPoint); HalfSegment curHS; bool end = false; if (up) { while (!end && lrspos < lastCurve->Size()/2) { lrspos++; lastCurve->Get(lrspos, lrs); lastCurve->Get(lrs.hsPos, curHS); if (lrs.lrsPos <= epos) { interEnd = curHS.AtPosition(0); instInter2 = ju.TimeAtPos(lrs.lrsPos); checkEndTimeCorrected (endTimeCorrected, instInter1, instInter2, TIMECORRECTION); result.Add(temporalalgebra::UPoint( temporalalgebra::Interval (instInter1, instInter2, lc,rc), interStart, interEnd)); instInter1 = instInter2; interStart = interEnd; end = AlmostEqual(epos, lrs.lrsPos); } else end = true; } if (lrs.lrsPos > epos) { lrspos--; lastCurve->Get(lrspos, lrs); lastCurve->Get(lrs.hsPos, curHS); interEnd = curHS.AtPosition(epos-lrs.lrsPos); instInter2 = endtime; checkEndTimeCorrected (endTimeCorrected, instInter1, instInter2, TIMECORRECTION); result.Add(temporalalgebra::UPoint( temporalalgebra::Interval ( instInter1, instInter2, lc,rc), interStart, interEnd)); } } else { while (!end && lrspos >= 0) { lastCurve->Get(lrs.hsPos, curHS); if (lrs.lrsPos >= epos) { interEnd = curHS.AtPosition(0); instInter2 = ju.TimeAtPos(lrs.lrsPos); checkEndTimeCorrected (endTimeCorrected, instInter1, instInter2, TIMECORRECTION); result.Add(temporalalgebra::UPoint( temporalalgebra::Interval ( instInter1, instInter2, lc,rc), interStart, interEnd)); instInter1 = instInter2; interStart = interEnd; end = AlmostEqual(epos, lrs.lrsPos); if (!end) lrspos--; lastCurve->Get(lrspos, lrs); } else end = true; } if (lrs.lrsPos < epos) { lastCurve->Get(lrspos, lrs); lastCurve->Get(lrs.hsPos, curHS); interEnd = curHS.AtPosition(epos-lrs.lrsPos); instInter2 = endtime; checkEndTimeCorrected (endTimeCorrected, instInter1, instInter2, TIMECORRECTION); result.Add(temporalalgebra::UPoint( temporalalgebra::Interval ( instInter1, instInter2, lc,rc), interStart, interEnd)); } } lastEndTime = instInter2; *startPoint = interEnd; } void addUnitsToResult(const JUnit& ju, SimpleLine*& routeCurve, const double tolerance, LRS& lrs, int& lrspos, bool& endTimeCorrected, Instant& instInter1, Instant& instInter2, const Instant TIMECORRECTION, Point*& lastEndPoint, Instant& lastEndTime, temporalalgebra::MPoint& result) { Direction compD(Down); JRouteInterval jurint = ju.GetRouteInterval(); temporalalgebra::Interval jutime = ju.GetTimeInterval(); double epos = correctedPos(jurint.GetEndPosition(), routeCurve->Length(), tolerance); if (jurint.GetSide().Compare(compD) == 0) { if (epos >= lrs.lrsPos ) { Point* endP = getPointFromCurveForPosFromLRS(epos, routeCurve, lrs); checkEndTimeCorrected (endTimeCorrected, instInter1, instInter2, TIMECORRECTION); result.Add(temporalalgebra::UPoint( temporalalgebra::Interval( instInter1, instInter2, jutime.lc, jutime.rc), *lastEndPoint, *endP)); lastEndPoint->DeleteIfAllowed(); lastEndPoint = endP; lastEndTime = instInter2; endP = 0; } else { addSimulatedTrip(ju, instInter1, instInter2, jutime.lc, jutime.rc, lastEndPoint, epos, routeCurve, lrs, lrspos, lastEndTime, result, false, TIMECORRECTION, endTimeCorrected); } } else { int lrsnext = lrspos; if (lrsnext < routeCurve->Size()/2) lrsnext++; LRS lrsX; routeCurve->Get(lrsnext, lrsX); if (epos <= lrsX.lrsPos) { Point* endP = getPointFromCurveForPosFromLRS(epos, routeCurve, lrs); checkEndTimeCorrected (endTimeCorrected, instInter1, instInter2, TIMECORRECTION); result.Add(temporalalgebra::UPoint( temporalalgebra::Interval (instInter1, instInter2, jutime.lc, jutime.rc), *lastEndPoint, *endP)); lastEndPoint->DeleteIfAllowed(); lastEndPoint = endP; lastEndTime = instInter2; endP = 0; } else { addSimulatedTrip(ju, instInter1, instInter2, jutime.lc, jutime.rc, lastEndPoint, epos, routeCurve, lrs, lrspos, lastEndTime, result, true, TIMECORRECTION, endTimeCorrected); } } } /* 1 Implementation of class JNetwork 1.1 Constructors and Deconstructor */ JNetwork::JNetwork() {} JNetwork::JNetwork(const bool def) : defined(def), tolerance(0.0), junctions(0), sections(0), routes(0), netdistances(0), junctionsBTree(0), junctionsRTree(0), sectionsBTree(0), sectionsRTree(0), routesBTree(0) { strcpy(id,""); } JNetwork::JNetwork(const string nid, const double t, const Relation* injunctions, const Relation* insections, const Relation* inroutes) : defined(true), tolerance(t), junctions(getRelationCopy(JNetUtil::GetJunctionsRelationTypeInfo(), injunctions)), sections(getRelationCopy(JNetUtil::GetSectionsRelationTypeInfo(), insections)), routes(getRelationCopy(JNetUtil::GetRoutesRelationTypeInfo(), inroutes)), netdistances(0), junctionsBTree(0), junctionsRTree(0), sectionsBTree(0), sectionsRTree(0), routesBTree(0) { strcpy(id, nid.c_str()); InitNetdistances(); CreateTrees(); } JNetwork::JNetwork(const string nid, const double t, const Relation* injunctions, const Relation* insections, const Relation* inroutes, OrderedRelation* inDist) : defined(true), tolerance(t), junctions(getRelationCopy(JNetUtil::GetJunctionsRelationTypeInfo(), injunctions)), sections(getRelationCopy(JNetUtil::GetSectionsRelationTypeInfo(), insections)), routes(getRelationCopy(JNetUtil::GetRoutesRelationTypeInfo(), inroutes)), netdistances(getRelationCopy(JNetUtil::GetNetdistancesRelationTypeInfo(), inDist)), junctionsBTree(0), junctionsRTree(0), sectionsBTree(0), sectionsRTree(0), routesBTree(0) { strcpy(id, nid.c_str()); CreateTrees(); } JNetwork::JNetwork(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, bool& ok) : defined(ok), tolerance(0.0), junctions(0), sections(0), routes(0), netdistances(0), junctionsBTree(0), junctionsRTree(0), sectionsBTree(0), sectionsRTree(0), routesBTree(0) { Word w; ListExpr idLE; nl->ReadFromString(CcString::BasicType(), idLE); ListExpr numId = SecondoSystem::GetCatalog()->NumericType(idLE); ok = OpenAttribute(valueRecord, offset, numId, w); if (ok) { CcString* stn = (CcString*)w.addr; strcpy(id, stn->GetValue().c_str()); stn->DeleteIfAllowed(); } else { strcpy(id,""); } if (ok && id == Symbol::UNDEFINED()) { ok = false; } if (ok) { nl->ReadFromString(CcReal::BasicType(), idLE); numId = SecondoSystem::GetCatalog()->NumericType(idLE); ok = OpenAttribute(valueRecord, offset, numId, w); } if (ok) { CcReal* tol = (CcReal*) w.addr; tolerance = tol->GetRealval(); tol->DeleteIfAllowed(); } if (ok) ok = openRelation(junctions, JNetUtil::GetJunctionsRelationTypeInfo(), valueRecord, offset); if (ok) ok = openRelation(sections, JNetUtil::GetSectionsRelationTypeInfo(), valueRecord, offset); if (ok) ok = openRelation(routes, JNetUtil::GetRoutesRelationTypeInfo(), valueRecord, offset); if (ok) ok = openRelation(netdistances, JNetUtil::GetNetdistancesRelationTypeInfo(), valueRecord, offset); if (ok) ok = openBTree(junctionsBTree, JNetUtil::GetJunctionsBTreeTypeInfo(), valueRecord, offset); if (ok) ok = openBTree(sectionsBTree, JNetUtil::GetSectionsBTreeTypeInfo(), valueRecord, offset); if (ok) ok = openBTree(routesBTree, JNetUtil::GetRoutesBTreeTypeInfo(), valueRecord, offset); Word wTree; if (ok) ok = junctionsRTree->Open(valueRecord, offset, JNetUtil::GetJunctionsRTreeTypeInfo(), wTree); if (ok) junctionsRTree = (R_Tree<2,TupleId>*) wTree.addr; if (ok) ok = sectionsRTree->Open(valueRecord, offset, JNetUtil::GetSectionsRTreeTypeInfo(), wTree); if (ok) sectionsRTree = (R_Tree<2,TupleId>*) wTree.addr; defined = ok; if (!ok) Destroy(); } JNetwork::~JNetwork() { delete junctions; delete sections; delete routes; delete netdistances; delete junctionsBTree; delete junctionsRTree; delete sectionsBTree; delete sectionsRTree; delete routesBTree; } void JNetwork::Destroy() { if (junctions != 0) { junctions->Delete(); junctions = 0; } if (sections != 0) { sections->Delete(); sections = 0; } if (routes != 0) { routes->Delete(); sections = 0; } if (netdistances != 0) { netdistances->Clear(); netdistances = 0; } if (junctionsBTree != 0) { junctionsBTree->DeleteFile(); junctionsBTree = 0; } if (sectionsBTree != 0) { sectionsBTree->DeleteFile(); sectionsBTree = 0; } if (routesBTree != 0) { routesBTree->DeleteFile(); routesBTree = 0; } if (junctionsRTree != 0) { junctionsRTree->DeleteFile(); junctionsRTree = 0; } if (sectionsRTree != 0) { sectionsRTree->DeleteFile(); sectionsRTree = 0; } SetDefined(false); } /* 1.1 Get Network Data */ bool JNetwork::IsDefined() const { return defined; } const STRING_T* JNetwork::GetId() const { return &id; } double JNetwork::GetTolerance() const { return tolerance; } string JNetwork::GetJunctionsRelationType() { return JNetUtil::GetJunctionsRelationTypeInfo(); } string JNetwork::GetSectionsRelationType() { return JNetUtil::GetSectionsRelationTypeInfo(); } string JNetwork::GetRoutesRelationType() { return JNetUtil::GetRoutesRelationTypeInfo(); } string JNetwork::GetNetdistancesRelationType() { return JNetUtil::GetNetdistancesRelationTypeInfo(); } string JNetwork::GetNetdistancesTupleType() { return JNetUtil::GetNetdistancesTupleTypeInfo(); } Rectangle< 2 > JNetwork::GetBoundingBox() const { if (sectionsRTree != 0) return sectionsRTree->BoundingBox(); else return Rectangle<2>(false); } Relation* JNetwork::GetJunctionsCopy() const { return junctions->Clone(); } Relation* JNetwork::GetRoutesCopy() const { return routes->Clone(); } Relation* JNetwork::GetSectionsCopy() const { return sections->Clone(); } OrderedRelation* JNetwork::GetNetdistancesCopy() const { return getRelationCopy(JNetUtil::GetNetdistancesRelationTypeInfo(), netdistances); } void JNetwork::SetDefined(const bool def) { defined = def; } void JNetwork::SetTolerance(const double t) { tolerance = t; } /* 1.1 Secondo Integration */ ListExpr JNetwork::Out(ListExpr typeInfo, Word value) { JNetwork* source = (JNetwork*) value.addr; if (source == 0 || !source->IsDefined()) { return nl->SymbolAtom(Symbol::UNDEFINED()); } else { ListExpr netId = nl->StringAtom(*source->GetId()); ListExpr toleranceList = nl->RealAtom(source->GetTolerance()); ListExpr junclist = source->JunctionsToList(); ListExpr sectlist = source->SectionsToList(); ListExpr routelist = source->RoutesToList(); ListExpr dislist = source->NetdistancesToList(); return nl->SixElemList(netId, toleranceList, junclist, sectlist, routelist, dislist); } } Word JNetwork::In(const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct) { correct = true; if(nl->ListLength(instance) == 1) { if (nl->IsAtom(instance) && nl->SymbolValue(instance) == Symbol::UNDEFINED()) { correct = true; JNetwork* n = new JNetwork(false); return SetWord(n); } } else { if (nl->ListLength(instance) == 6) { ListExpr netId = nl->First(instance); string nid = nl->StringValue(netId); ListExpr tolList = nl->Second(instance); double tol = nl->RealValue(tolList); Relation* juncRel = 0; Relation* sectRel = 0; Relation* routeRel = 0; OrderedRelation* distRel = 0; juncRel = relationFromList(nl->Third(instance), JNetUtil::GetJunctionsRelationTypeInfo(), errorPos, errorInfo, correct); if (correct) { sectRel = relationFromList(nl->Fourth(instance), JNetUtil::GetSectionsRelationTypeInfo(), errorPos, errorInfo, correct); } if (correct) { routeRel = relationFromList(nl->Fifth(instance), JNetUtil::GetRoutesRelationTypeInfo(), errorPos, errorInfo, correct); } if (correct) { distRel = ordRelationFromList(nl->Sixth(instance), JNetUtil::GetNetdistancesRelationTypeInfo(), errorPos, errorInfo, correct); } if (!correct) { if (juncRel != 0) juncRel->Delete(); if (sectRel != 0) sectRel->Delete(); if (routeRel != 0) routeRel->Delete(); if (distRel != 0) { distRel->Clear(); delete distRel; } return SetWord(Address(0)); } JNetwork* n = new JNetwork(nid, tol, juncRel, sectRel, routeRel, distRel); juncRel->Delete(); sectRel->Delete(); routeRel->Delete(); distRel->Clear(); delete distRel; return SetWord(n); } } correct = false; return SetWord(Address(0)); } Word JNetwork::Create(const ListExpr typeInfo) { return SetWord ( new JNetwork(false)); } void JNetwork::Delete( const ListExpr typeInfo, Word& w ) { JNetwork* net = (JNetwork*) w.addr; delete net; w.addr = 0; } void JNetwork::Close( const ListExpr typeInfo, Word& w ) { delete static_cast ( w.addr ); w.addr = 0; } Word JNetwork::Clone( const ListExpr typeInfo, const Word& w ) { JNetwork* source = (JNetwork*) w.addr; JNetwork* clone = new JNetwork(*source->GetId(), source->GetTolerance(), source->junctions, source->sections, source->routes, source->netdistances); return SetWord(clone); } void* JNetwork::Cast( void* addr ) { return (new (addr) JNetwork); } bool JNetwork::KindCheck ( ListExpr type, ListExpr& errorInfo ) { return nl->IsEqual(type, BasicType()); } int JNetwork::SizeOf() { return sizeof(JNetwork); } bool JNetwork::Save(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { JNetwork* source = (JNetwork*) value.addr; if (source->IsDefined()) { return source->Save(valueRecord, offset, typeInfo); } else { CcString* stn = new CcString(true,Symbol::UNDEFINED()); ListExpr idLE; nl->ReadFromString(CcString::BasicType(), idLE); ListExpr numId = SecondoSystem::GetCatalog()->NumericType(idLE); Attribute::Save(valueRecord, offset, numId, stn); return true; } } bool JNetwork::Save(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo) { CcString* stn = new CcString(true, id); ListExpr idLE; nl->ReadFromString(CcString::BasicType(), idLE); ListExpr numId = SecondoSystem::GetCatalog()->NumericType(idLE); Attribute::Save(valueRecord, offset, numId, stn); stn->DeleteIfAllowed(); CcReal* tol = new CcReal(true, tolerance); nl->ReadFromString(CcReal::BasicType(), idLE); numId = SecondoSystem::GetCatalog()->NumericType(idLE); Attribute::Save(valueRecord, offset, numId, tol); tol->DeleteIfAllowed(); bool ok = saveRelation(JNetUtil::GetJunctionsRelationTypeInfo(), junctions, valueRecord, offset); if (ok) ok = saveRelation(JNetUtil::GetSectionsRelationTypeInfo(), sections, valueRecord, offset); if (ok) ok = saveRelation(JNetUtil::GetRoutesRelationTypeInfo(), routes, valueRecord, offset); if (ok) ok = saveRelation(JNetUtil::GetNetdistancesRelationTypeInfo(), netdistances, valueRecord, offset); if (ok) ok = saveBTree(JNetUtil::GetJunctionsBTreeTypeInfo(), junctionsBTree, valueRecord, offset); if (ok) ok = saveBTree(JNetUtil::GetSectionsBTreeTypeInfo(), sectionsBTree, valueRecord, offset); if (ok) ok = saveBTree(JNetUtil::GetRoutesBTreeTypeInfo(), routesBTree, valueRecord, offset); if (ok) ok = junctionsRTree->Save(valueRecord, offset); if (ok) ok = sectionsRTree->Save(valueRecord, offset); return ok; } bool JNetwork::Open(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value ) { bool ok = false; value.setAddr(new JNetwork(valueRecord, offset, typeInfo, ok)); return ok; } ListExpr JNetwork::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("-> " + Kind::JNETWORK()), nl->StringAtom(BasicType()), nl->TextAtom("(" + CcString::BasicType() + " " + CcReal::BasicType() + " " + JNetUtil::GetJunctionsRelationTypeInfo() + " " + JNetUtil::GetSectionsRelationTypeInfo() + " " + JNetUtil::GetRoutesRelationTypeInfo() + " " + JNetUtil::GetNetdistancesRelationTypeInfo() + "), the" + " string defines the name of the network, it is followed by the " + "tolerance value for the network representation used in map matching "+ "algorithms, and the network data for junctions, sections, routes and "+ "network distances in nested list format."), nl->StringAtom("(name tol junctions sections routes dist)"))); } /* 1.1 Standard Operations */ ostream& JNetwork::Print(ostream& os) const { os << "Network: "; if (!IsDefined()) os << Symbol::UNDEFINED() << endl; else { os << "Id: " << id << endl; os << "Tolerance: " << tolerance << endl; os << "Junctions: " << endl; if (junctions != 0)junctions->Print(os); else os << "not defined" << endl; os << "Sections: " << endl; if (sections != 0) sections->Print(os); else os << "not defined" << endl; os << "Routes: " << endl; if (routes != 0) routes->Print(os); else os << "not defined" << endl; os << "Network Distances:" << endl; if (netdistances != 0) netdistances->Print(os); else os << "not defined" << endl; } os << endl; return os; } const string JNetwork::BasicType() { return "jnet"; } const bool JNetwork::checkType(const ListExpr type) { return listutils::isSymbol(type, BasicType()); } /* 1.1 Translation operations 1.1.1 GetNetworkValueOf Translates spatial data types into their Network representation. */ RouteLocation* JNetwork::GetNetworkValueOf(const Point* p) const { RouteLocation* res = 0; double pos = 0.0; Tuple* actSect = GetSectionTupleFor(p, pos); if (actSect != 0) { JRouteInterval* actInt = GetSectionFirstRouteInterval(actSect); res = GetRLocOfPosOnRouteInterval(actInt, pos); actSect->DeleteIfAllowed(); actInt->DeleteIfAllowed(); } return res; } RouteLocation* JNetwork::GetNetworkValueOfOn(const Point* p, const Tuple* sectTup) const { RouteLocation* result = 0; SimpleLine* actCurve = GetSectionCurve(sectTup); if (actCurve != 0) { double pos = 0.0; if(actCurve->AtPoint(*p, pos, tolerance)) { JRouteInterval* actInt = GetSectionFirstRouteInterval(sectTup); result = GetRLocOfPosOnRouteInterval(actInt, pos); actInt->DeleteIfAllowed(); } actCurve->DeleteIfAllowed(); } return result; } JListRLoc* JNetwork::GetNetworkValuesOf(const Point* p) const { JListRLoc* res = 0; double pos = 0.0; Tuple* actSect = GetSectionTupleFor(p, pos); if (AlmostEqual(pos, 0.0)) res = GetSectionStartJunctionRLocs(actSect); else { if (AlmostEqual(pos, GetSectionLength(actSect))) res = GetSectionEndJunctionRLocs(actSect); else { res = new JListRLoc(0); res->StartBulkload(); JListRInt* rints = GetSectionListRouteIntervals(actSect); JRouteInterval actInt; for(int i = 0; i < rints->GetNoOfComponents(); i++) { rints->Get(i,actInt); RouteLocation* result = GetRLocOfPosOnRouteInterval(&actInt, pos); res->operator+=(*result); result->DeleteIfAllowed(); } res->EndBulkload(); rints->Destroy(); rints->DeleteIfAllowed(); } } actSect->DeleteIfAllowed(); return res; } bool JNetwork::GetNetworkValueOf(const Line* in, JLine* result) const { result->Clear(); result->SetNetworkId(*GetId()); if (in != 0 && in->IsDefined() && !in->IsEmpty()) { result->StartBulkload(); HalfSegment hs; for (int i = 0; i < in->Size(); i++) { in->Get(i,hs); if (hs.IsLeftDomPoint()) { JRouteInterval* actInt = GetNetworkValueOf(hs); if (actInt != NULL) { if (actInt->IsDefined()) result->Add(*actInt); actInt->DeleteIfAllowed(); actInt = 0; } } } result->EndBulkload(); return true; } else return false; } bool JNetwork::GetNetworkValueOf( const temporalalgebra::MPoint* in, MJPoint* result) { result->Clear(); if (in != 0 && in->IsDefined()) { result->SetDefined(true); result->SetNetworkId(*GetId()); if (!in->IsEmpty()) { temporalalgebra::UPoint actSource; int i = 0; RouteLocation* startPos = 0; RouteLocation* endPos = 0; Instant starttime(0.0); Instant endtime(0.0); bool lc = false; bool rc = false; Tuple* actSectTup = 0; Tuple* startSectTup = 0; Tuple* endSectTup = 0; JRouteInterval* actRInt = 0; SimpleLine* actCurve = 0; double distStart = 0.0; double distEnd = 0.0; result->StartBulkload(); while (i < in->GetNoComponents()) { //find valid startposition in network while((startPos == 0 || !startPos->IsDefined()) && i < in->GetNoComponents()) { if (startPos != 0) { startPos->DeleteIfAllowed(); startPos = 0; } in->Get(i,actSource); if (actCurve != 0) { if (actCurve->AtPoint(actSource.p0, distStart, tolerance)) { startPos = GetRLocOfPosOnRouteInterval(actRInt, distStart); } else { actCurve->DeleteIfAllowed(); actCurve = 0; if (actSectTup != 0) { actSectTup->DeleteIfAllowed(); actSectTup = 0; } if (actRInt != 0) { actRInt->DeleteIfAllowed(); actRInt = 0; } if (startSectTup != 0) { startSectTup->DeleteIfAllowed(); startSectTup = 0; } } } if (actSectTup == 0) { actSectTup = GetSectionTupleFor(&actSource.p0, distStart); if (actSectTup != 0) { actRInt = GetSectionFirstRouteInterval(actSectTup); actCurve = GetSectionCurve(actSectTup); startPos = GetRLocOfPosOnRouteInterval(actRInt, distStart); startSectTup = actSectTup; startSectTup->IncReference(); } } starttime = actSource.getTimeInterval().start; lc = actSource.getTimeInterval().lc; if (startPos == 0 || !startPos->IsDefined()) i++; } //find valid endposition in network while((endPos == 0 || !endPos->IsDefined()) && i < in->GetNoComponents()) { if (endPos != 0) { endPos->DeleteIfAllowed(); endPos = 0; } in->Get(i, actSource); if (actCurve != 0 && actCurve->AtPoint(actSource.p1, distEnd, tolerance)) { endPos = GetRLocOfPosOnRouteInterval(actRInt, distEnd); endSectTup = actSectTup; endSectTup->IncReference(); } else { if (actSectTup != 0) actSectTup->DeleteIfAllowed(); actSectTup = GetSectionTupleFor(&actSource.p1, distEnd); if (actSectTup != 0) { if (actRInt != 0) actRInt->DeleteIfAllowed(); actRInt = GetSectionFirstRouteInterval(actSectTup); if (actCurve != 0) actCurve->DeleteIfAllowed(); actCurve = GetSectionCurve(actSectTup); endPos = GetRLocOfPosOnRouteInterval(actRInt, distEnd); endSectTup = actSectTup; endSectTup->IncReference(); } } endtime = actSource.getTimeInterval().end; rc = actSource.getTimeInterval().rc; if (endPos == 0 || !endPos->IsDefined()) i++; } if (startPos != 0 && startPos->IsDefined() && endPos != 0 && endPos->IsDefined() && actSource.p1.IsDefined() && startSectTup != 0 && endSectTup != 0) { // got valid RouteLocations and SimulateTrip(*startPos, *endPos, starttime, endtime, lc, rc, result); } startPos->DeleteIfAllowed(); startSectTup->DeleteIfAllowed(); startSectTup = endSectTup; endSectTup = 0; startPos = endPos; endPos = 0; distStart = distEnd; starttime = endtime; lc = !rc; i++; } if (startPos != 0) startPos->DeleteIfAllowed(); if (endPos != 0) endPos->DeleteIfAllowed(); if (actSectTup != 0) actSectTup->DeleteIfAllowed(); if (actRInt != 0) actRInt->DeleteIfAllowed(); if (actCurve != 0) actCurve->DeleteIfAllowed(); if (startSectTup != 0) startSectTup->DeleteIfAllowed(); if (endSectTup != 0) endSectTup->DeleteIfAllowed(); result->EndBulkload(); } return true; } else return false; } JListRLoc* JNetwork::GetNetworkValuesOf(const Tuple* actSect, const double distStart) const { JListRLoc* res = 0; if (AlmostEqualAbsolute(distStart, 0.0, tolerance)) res = GetSectionStartJunctionRLocs(actSect); else { if (AlmostEqualAbsolute(distStart, GetSectionLength(actSect), tolerance)) res = GetSectionEndJunctionRLocs(actSect); else { if (0.0 <= distStart && distStart <= GetSectionLength(actSect)) { JListRInt* rintList = GetSectionListRouteIntervals(actSect); if (rintList != 0) { if (rintList->IsDefined() && !rintList->IsEmpty()) { res = new JListRLoc(true); res->StartBulkload(); JRouteInterval actInt; for (int i = 0; i < rintList->GetNoOfComponents(); i++) { rintList->Get(i, actInt); RouteLocation* result = GetRLocOfPosOnRouteInterval(&actInt, distStart); if (result != 0) { res->operator+=(*result); result->DeleteIfAllowed(); result = 0; } } res->EndBulkload(); } rintList->Destroy(); rintList->DeleteIfAllowed(); } } } } return res; } JListRLoc* JNetwork::GetNetworkValuesOf(const RouteLocation& rloc) const { JListRLoc* res = 0; double pos = 0.0; Tuple* actSect = GetSectionTupleFor(rloc,pos); if (actSect != 0) { res = GetNetworkValuesOf(actSect,pos); actSect->DeleteIfAllowed(); } return res; } JRouteInterval* JNetwork::GetNetworkValueOf(const HalfSegment& hs) const { JRouteInterval* res = 0; Point lp = hs.GetLeftPoint(); Point rp = hs.GetRightPoint(); JListRLoc* leftrlocs = GetNetworkValuesOf(&lp); JListRLoc* rightrlocs = GetNetworkValuesOf(&rp); res = GetRouteIntervalFor(leftrlocs, rightrlocs, true); if (res != 0 && res->IsDefined()) res->SetSide((Direction) Both); rightrlocs->DeleteIfAllowed(); leftrlocs->DeleteIfAllowed(); return res; } /* 1.1.1 GetSpatialValueOf Transforms network datatypes into their corresponding spatial data types. */ Point* JNetwork::GetSpatialValueOf(const RouteLocation& rloc, const JListInt* routeSectList) const { Point* res = 0; double pos = 0.0; int index = -1; Tuple* sectTup = GetSectionTupleFor(rloc, pos, routeSectList, index); res = GetSpatialValueOf(rloc, pos, sectTup); sectTup->DeleteIfAllowed(); return res; } Point* JNetwork::GetSpatialValueOf(const JPoint& jp) const { Point* res = 0; double relpos = 0.0; RouteLocation rloc = jp.GetLocation(); Tuple* sectTup = GetSectionTupleFor(rloc, relpos); res = GetSpatialValueOf(rloc, relpos, sectTup); sectTup->DeleteIfAllowed(); return res; } void JNetwork::GetSpatialValueOf(const JLine* jl, Line& result) const { if (jl != 0 && jl->IsDefined() && !jl->IsEmpty()) { result.Clear(); result.StartBulkLoad();; JRouteInterval rint; for (int i = 0; i < jl->GetNoComponents(); i++) { jl->Get(i,rint); SimpleLine tmp(0); GetSpatialValueOf(rint, tmp); if (tmp.IsDefined() && !tmp.IsEmpty()) { HalfSegment hs; for (int i = 0; i < tmp.Size(); i++) { tmp.Get(i,hs); result += hs; } } } result.EndBulkLoad(); } else result.SetDefined(false); } void JNetwork::GetSpatialValueOf( const MJPoint* mjp, temporalalgebra::MPoint& result) const { if (mjp != 0 && mjp->IsDefined() && !mjp->IsEmpty()) { result.Clear(); result.StartBulkLoad(); JUnit ju; bool endTimeCorrected = false; Instant lastEnd(instanttype); JRouteInterval* lastRint = 0; SimpleLine* lastCurve = 0; Point* lastEndPoint = new Point(true,0.0,0.0); LRS lrs; int lrspos = -1; for (int i = 0; i < mjp->GetNoComponents(); i++) { mjp->Get(i,ju); SplitJUnit(ju, lastRint, lastCurve, endTimeCorrected, lastEnd, lastEndPoint, lrs, lrspos, result); } result.EndBulkLoad(); if (lastRint != 0) lastRint->DeleteIfAllowed(); if (lastCurve != 0) lastCurve->DeleteIfAllowed(); lastEndPoint->DeleteIfAllowed(); } else result.SetDefined(false); } Point* JNetwork::GetSpatialValueOf(const RouteLocation& rloc, double relpos, const Tuple* actSect) const { Point* res = 0; SimpleLine* sectCurve = GetSectionCurve(actSect); if (sectCurve != 0) { res = new Point(false); if (AlmostEqualAbsolute(relpos, sectCurve->Length(), tolerance)) relpos = sectCurve->Length(); else if (AlmostEqualAbsolute(relpos, 0.0, tolerance)) relpos = 0.0; sectCurve->AtPosition(relpos, *res); sectCurve->DeleteIfAllowed(); } return res; } void JNetwork::GetSpatialValueOf(const JRouteInterval& rint, SimpleLine& result) const { JListInt* sectList = GetRouteSectionList(rint.GetRouteId()); int fromInd = 0; int toInd = sectList->GetNoOfComponents()-1; GetSpatialValueOf(rint, sectList, fromInd, toInd, result); sectList->Destroy(); sectList->DeleteIfAllowed(); } Point* JNetwork::GetSpatialValueOf(const RouteLocation& rloc) const { JListInt* sectList = GetRouteSectionList(rloc.GetRouteId()); Point* res = GetSpatialValueOf(rloc, sectList); sectList->DeleteIfAllowed(); return res; } void JNetwork::GetSpatialValueOf(const JRouteInterval& rint, const JListInt* sectList, const int fromIndex, const int toIndex, SimpleLine& result) const { if (sectList != 0 && 0 <= fromIndex && fromIndex < sectList->GetNoOfComponents()) { result.Clear(); result.StartBulkLoad(); HalfSegment hs; CcInt sidC; bool dirChanged = false; if (fromIndex > toIndex) dirChanged = true; int actindex = min(fromIndex, toIndex); if (actindex < 0) actindex = 0; int lastindex = max(fromIndex, toIndex); if (lastindex < 0 || lastindex > sectList->GetNoOfComponents()-1) lastindex = sectList->GetNoOfComponents()-1; while(actindex < sectList->GetNoOfComponents() && actindex <= lastindex) { sectList->Get(actindex,sidC); int sid = sidC.GetIntval(); JListRInt* rintList = GetSectionListRouteIntervals(sid); if (rintList != 0) { JRouteInterval actInt; int j = 0; while (j < rintList->GetNoOfComponents()) { rintList->Get(j,actInt); if (actInt.Overlaps(rint, false)) { SimpleLine* actCurve = GetSectionCurve(sid); j = rintList->GetNoOfComponents(); if (actInt.Inside(rint)) { for (int i = 0; i < actCurve->Size(); i++) { actCurve->Get(i,hs); result += hs; } } else { double spos(0.0); double epos(0.0); SimpleLine* sl = new SimpleLine(0); if (actInt.Contains(rint)) { spos = fabs(rint.GetFirstPosition() - actInt.GetFirstPosition()); epos = fabs(rint.GetLastPosition() - actInt.GetFirstPosition()); } else if (actInt.Contains(RouteLocation(rint.GetRouteId(), rint.GetFirstPosition(), rint.GetSide()))) { spos = fabs(rint.GetFirstPosition() - actInt.GetFirstPosition()); epos = fabs(actInt.GetLastPosition()- actInt.GetFirstPosition()); } else if (actInt.Contains(RouteLocation(rint.GetRouteId(), rint.GetLastPosition(), rint.GetSide()))) { spos = 0.0; epos = fabs(rint.GetLastPosition() - actInt.GetFirstPosition()); } else { assert(false); //should never happen } actCurve->SubLine(min(spos,epos), max(spos,epos), *sl); if (sl != 0 && sl->IsDefined() && !sl->IsEmpty()) { for (int i = 0; i < sl->Size(); i++) { sl->Get(i,hs); result += hs; } } if (sl != 0) { sl->Destroy(); sl->DeleteIfAllowed(); } } actCurve->DeleteIfAllowed(); actCurve = 0; } j++; } rintList->Destroy(); rintList->DeleteIfAllowed(); rintList = 0; } actindex++; } result.EndBulkLoad();; if (dirChanged) result.SetStartSmaller(!result.StartsSmaller()); } else result.SetDefined(false); } Point* JNetwork::GetSpatialValueOf(const RouteLocation& rloc, JRouteInterval*& routeRint, SimpleLine*& routeCurve, LRS& lrs, int& lrspos) const { if (routeCurve != 0) routeCurve->DeleteIfAllowed(); routeCurve = new SimpleLine(0); routeCurve->StartBulkLoad(); Tuple* routeTuple = GetRouteTupleWithId(rloc.GetRouteId()); JListInt* routeSectList = GetRouteSectionList(routeTuple); double routeLength = GetRouteLength(routeTuple); if (routeRint != 0) routeRint->DeleteIfAllowed(); routeRint = new JRouteInterval(rloc.GetRouteId(), 0.0, routeLength, Both); Point startP, endP; int index = 0; CcInt cSid; Tuple* sectTup = 0; while(index < routeSectList->GetNoOfComponents()) { routeSectList->Get(index, cSid); if (cSid.IsDefined()) { sectTup = GetSectionTupleWithId(cSid.GetIntval()); if (sectTup != 0) { JRouteInterval* curRint = GetSectionRouteIntervalForRID(rloc.GetRouteId(), sectTup); SimpleLine* sectCurve = GetSectionCurve(sectTup); if (AlmostEqual(curRint->GetFirstPosition(), 0.0)) startP = sectCurve->StartPoint(); if (AlmostEqual(curRint->GetLastPosition(), routeLength)) endP = sectCurve->EndPoint(); HalfSegment hs; for (int i = 0; i < sectCurve->Size(); i++) { sectCurve->Get(i,hs); routeCurve->operator+=(hs); } curRint->DeleteIfAllowed(); curRint = 0; sectCurve->DeleteIfAllowed(); sectCurve = 0; sectTup->DeleteIfAllowed(); sectTup = 0; } } index++; } routeCurve->EndBulkLoad(); routeTuple->DeleteIfAllowed(); if (startP > endP) routeCurve->SetStartSmaller(false); else routeCurve->SetStartSmaller(true); double pos = correctedPos(rloc.GetPosition(), routeCurve->Length(), tolerance); routeSectList->DeleteIfAllowed(); return getPointFromCurveForPosRememberLRSPos(pos, routeCurve, lrs, lrspos); } Point* JNetwork::GetSpatialValueOf(const RouteLocation& rloc, int& curRid, JListInt*& routeSectList, int& index, JRouteInterval*& lastRint, SimpleLine*& lastCurve, LRS& lrs, int& lrspos) const { if(rloc.GetRouteId() != curRid) { curRid = rloc.GetRouteId(); if (routeSectList != 0) routeSectList->DeleteIfAllowed(); routeSectList = GetRouteSectionList(curRid); index = 0; } CcInt cSid; bool found = false; Tuple* sectTup = 0; while(0 <= index && index < routeSectList->GetNoOfComponents() && !found) { if (sectTup != 0) { sectTup->DeleteIfAllowed(); sectTup = 0; } if (lastRint != 0) { lastRint->DeleteIfAllowed(); lastRint = 0; } routeSectList->Get(index, cSid); if (cSid.IsDefined()) { sectTup = GetSectionTupleWithId(cSid.GetIntval()); if (sectTup != 0) { lastRint = GetSectionRouteIntervalForRLoc(rloc, sectTup); } } if (lastRint == 0) index++; else found = true; } if (!found) { index = routeSectList->GetNoOfComponents() -1; while (index >= 0 && index < routeSectList->GetNoOfComponents() && !found) { if (sectTup != 0) { sectTup->DeleteIfAllowed(); sectTup = 0; } if (lastRint != 0) { lastRint->DeleteIfAllowed(); lastRint = 0; } routeSectList->Get(index, cSid); if (cSid.IsDefined()) { sectTup = GetSectionTupleWithId(cSid.GetIntval()); if (sectTup != 0) lastRint = GetSectionRouteIntervalForRLoc(rloc, sectTup); } if (lastRint == 0) index--; else found = true; } } if (found) { if (lastCurve != 0) lastCurve->DeleteIfAllowed(); lastCurve = GetSectionCurve(sectTup); if (sectTup != 0) sectTup->DeleteIfAllowed(); double pos = correctedPos(fabs(rloc.GetPosition() - lastRint->GetFirstPosition()), lastCurve->Length(), tolerance); return getPointFromCurveForPosRememberLRSPos(pos, lastCurve, lrs, lrspos); } if (sectTup != 0) sectTup->DeleteIfAllowed(); return 0; } Point* JNetwork::GetSpatialValueOf(const RouteLocation& rloc, int& curRid, JListInt*& routeSectList, int& index, JRouteInterval*& lastRint, SimpleLine*& lastCurve) const { if (rloc.GetRouteId() != curRid) { curRid = rloc.GetRouteId(); if (routeSectList != 0) routeSectList->DeleteIfAllowed(); routeSectList = GetRouteSectionList(curRid); index = 0; } CcInt cSid; bool found = false; Tuple* sectTup = 0; while(0 <= index && index < routeSectList->GetNoOfComponents() && !found) { if (sectTup != 0) { sectTup->DeleteIfAllowed(); sectTup = 0; } if (lastRint != 0) { lastRint->DeleteIfAllowed(); lastRint = 0; } routeSectList->Get(index, cSid); if (cSid.IsDefined()) { sectTup = GetSectionTupleWithId(cSid.GetIntval()); if (sectTup != 0) { lastRint = GetSectionRouteIntervalForRLoc(rloc, sectTup); } } if (lastRint == 0) index++; else found = true; } if (!found) { index = routeSectList->GetNoOfComponents() -1; while (index >= 0 && index < routeSectList->GetNoOfComponents() && !found) { if (sectTup != 0) { sectTup->DeleteIfAllowed(); sectTup = 0; } if (lastRint != 0) { lastRint->DeleteIfAllowed(); lastRint = 0; } routeSectList->Get(index, cSid); if (cSid.IsDefined()) { sectTup = GetSectionTupleWithId(cSid.GetIntval()); if (sectTup != 0) lastRint = GetSectionRouteIntervalForRLoc(rloc, sectTup); } if (lastRint == 0) index--; else found = true; } } if (found) { if (lastCurve != 0) lastCurve->DeleteIfAllowed(); lastCurve = GetSectionCurve(sectTup); if (sectTup != 0) sectTup->DeleteIfAllowed(); double pos = correctedPos(fabs(rloc.GetPosition() - lastRint->GetFirstPosition()), lastCurve->Length(), tolerance); Point* result = new Point(true); lastCurve->AtPosition(pos, *result); return result; } if (sectTup != 0) sectTup->DeleteIfAllowed(); return 0; } /* 1.1. BoundingBox */ Rectangle< 3 > JNetwork::BoundingBox(const JUnit& ju) const { SimpleLine resLine(0); GetSpatialValueOf(ju.GetRouteInterval(), resLine); Rectangle<2> curveBB = resLine.BoundingBox(); double mintime = ju.GetTimeInterval().start.ToDouble(); double maxtime = ju.GetTimeInterval().end.ToDouble(); if (mintime == maxtime) { double minMax[] = { curveBB.MinD(0) - tolerance, curveBB.MaxD(0) + tolerance, curveBB.MinD(1) - tolerance, curveBB.MaxD(1) + tolerance, mintime - tolerance, maxtime + tolerance}; return Rectangle<3>(true,minMax); } else { double minMax[] = { curveBB.MinD(0) - tolerance, curveBB.MaxD(0) + tolerance, curveBB.MinD(1) - tolerance, curveBB.MaxD(1) + tolerance, mintime, maxtime}; return Rectangle<3>(true,minMax); } } Rectangle< 2 > JNetwork::BoundingBox(const JRouteInterval& rint) const { if (rint.IsDefined()) { Rectangle<2> bBox(false); if (AlmostEqualAbsolute(rint.GetFirstPosition(), rint.GetLastPosition(), tolerance)) { Point* tmpRes = GetSpatialValueOf(rint.GetStartLocation()); bBox = tmpRes->BoundingBox(); tmpRes->DeleteIfAllowed(); } else { SimpleLine tmpRes(0); GetSpatialValueOf(rint, tmpRes); bBox = tmpRes.BoundingBox(); } double minMax[] = { bBox.MinD(0), bBox.MaxD(0), bBox.MinD(1), bBox.MaxD(1)}; return Rectangle<2>(true,minMax); } return Rectangle<2>(false); } Rectangle<3> JNetwork::BoundingBox(const DbArray& traj, const double mintime, const double maxtime) const { JRouteInterval actRint; int i = 0; traj.Get(i,actRint); Rectangle<2> tmpres = BoundingBox(actRint); i++; while (i < traj.Size()) { traj.Get(i,actRint); tmpres = tmpres.Union(BoundingBox(actRint)); i++; } if (mintime == maxtime) { double minMax[] = { tmpres.MinD(0), tmpres.MaxD(0), tmpres.MinD(1), tmpres.MaxD(1), mintime - tolerance, maxtime + tolerance}; return Rectangle<3> (true,minMax); } else { double minMax[] = {tmpres.MinD(0), tmpres.MaxD(0), tmpres.MinD(1), tmpres.MaxD(1), mintime, maxtime}; return Rectangle<3> (true,minMax); } } /* 1.1 Operations for other network data types 1.1.1 ~Contains~ Checks if the given position(s) exist in the network. */ bool JNetwork::Contains(const RouteLocation& rloc) const { return ((rloc.GetPosition() >= 0.0 && rloc.GetPosition() <= GetRouteLength(rloc.GetRouteId())) || AlmostEqualAbsolute(rloc.GetPosition(), 0.0, tolerance) || AlmostEqualAbsolute(rloc.GetPosition(),0.0, tolerance)); } bool JNetwork::Contains(const JRouteInterval& rint) const{ return ((rint.GetFirstPosition() >= 0.0 && rint.GetLastPosition()<= GetRouteLength(rint.GetRouteId()))|| AlmostEqualAbsolute(rint.GetFirstPosition(),0.0,tolerance) || AlmostEqualAbsolute(rint.GetLastPosition(), 0.0, GetRouteLength(rint.GetRouteId()))); } /* 1.1.1 ~SimulateTrip~ */ void JNetwork::SimulateTrip(const RouteLocation& source, const RouteLocation& target, const Instant& starttime, const Instant& endtime, MJPoint* result) { bool lc = true; bool rc = (starttime == endtime); SimulateTrip(source, target, starttime, endtime, lc, rc, result); } void JNetwork::SimulateTrip(const RouteLocation& source, const RouteLocation& target, const Instant& starttime, const Instant& endtime, const bool& lc, const bool& rc, MJPoint* result) { JPath* tmpPath = new JPath(true); ShortestPath(source, target, tmpPath); double length = tmpPath->Length(); if (tmpPath->IsDefined()) { if (length == 0 && starttime.ToDouble() != endtime.ToDouble()) { JUnit actUnit(JUnit( temporalalgebra::Interval(starttime, endtime, lc, rc), JRouteInterval(source.GetRouteId(), min(source.GetPosition(), target.GetPosition()), max(source.GetPosition(), target.GetPosition()), (Direction) Both))); result->Add(actUnit); } else { if (tmpPath->GetNoComponents() > 0) { ComputeAndAddUnits(tmpPath, starttime, endtime, lc, rc, length, result); } } } tmpPath->Destroy(); delete tmpPath; } void JNetwork::ComputeAndAddUnits(const JPath* sp, const Instant& starttime, const Instant& endtime, const bool lc, const bool rc, double length, MJPoint* result) const { JRouteInterval actInt; Instant unitstart = starttime; bool unitlc = lc; Instant unitend = endtime; bool unitrc = rc; for (int i = 0; i < sp->GetNoComponents(); i++) { sp->Get(i,actInt); if (actInt.GetLength() != 0.0) { if (i == sp->GetNoComponents()-1) { unitend = endtime; unitrc = rc; } else { unitend = unitstart + ((endtime - starttime) * (actInt.GetLength() / length)); } if (unitstart < unitend) { JUnit actUnit(JUnit( temporalalgebra::Interval(unitstart, unitend, unitlc, unitrc), actInt)); result->Add(actUnit); unitstart = unitend; unitlc = !unitrc; unitrc = !unitlc; unitend = endtime; } } } } /* 1.1.1 ShortestPathTree */ void JNetwork::ShortestPathTree(const RouteLocation& source, DbArray* result, const double distLimit) { if (result != NULL) { result->clean(); if (source.IsDefined()) { PQManagement* pqueue = new PQManagement(); InitPriorityQueue(pqueue, source, result); ProcessPriorityQueue(pqueue, result, distLimit); pqueue->Destroy(); delete pqueue; } } } void JNetwork::ReverseShortestPathTree(const RouteLocation& source, DbArray* result, const double distLimit) { if (result != NULL) { result->clean(); if (source.IsDefined()) { PQManagement* pqueue = new PQManagement(); InitReversePriorityQueue(pqueue, source, result); ProcessReversePriorityQueue(pqueue, result, distLimit); pqueue->Destroy(); delete pqueue; } } } /* 1.1.1 Network parts around location */ void JNetwork::OutCircle(const jnetwork::RouteLocation& src, const double distLimit, JLine* result) { if (result != NULL) result->Clear(); if (IsDefined() && src.IsDefined()) { result->SetDefined(true); result->SetNetworkId(id); result->StartBulkload(); PQManagement* pqueue = new PQManagement(); InitPriorityQueue(pqueue, src, distLimit, result); ProcessPriorityQueue(pqueue, distLimit, result); result->EndBulkload(); } else result->SetDefined(false); } void JNetwork::InCircle(const jnetwork::RouteLocation& src, const double distLimit, JLine* result) { if (result != NULL) result->Clear(); if (IsDefined() && src.IsDefined()) { result->SetDefined(true); result->SetNetworkId(id); result->StartBulkload(); PQManagement* pqueue = new PQManagement(); InitReversePriorityQueue(pqueue, src, distLimit, result); ProcessReversePriorityQueue(pqueue, distLimit, result); result->EndBulkload(); } else result->SetDefined(false); } void JNetwork::Circle(const jnetwork::RouteLocation& src, const double netdist, JLine* result) { if (result != NULL) result->Clear(); if (IsDefined() && src.IsDefined()) { JLine* inJL = new JLine(false); JLine* outJL = new JLine(false); InCircle(src, netdist, inJL); OutCircle(src, netdist, outJL); inJL->Union(outJL, result); inJL->DeleteIfAllowed(); outJL->DeleteIfAllowed(); } else { result->SetDefined(false); } } /* 1.1.1 ShortestPath */ void JNetwork::ShortestPath(const RouteLocation& source, const RouteLocation& target, JPath* result) { DbArray* srcPositions = new DbArray(0); srcPositions->Append(source); DbArray* tgtPositions = new DbArray(0); tgtPositions->Append(target); ShortestPath(srcPositions, tgtPositions, result); srcPositions->Destroy(); delete srcPositions; tgtPositions->Destroy(); delete tgtPositions; } void JNetwork::ShortestPath(const RouteLocation& source, const DbArray< RouteLocation >& target, JPath* result) { DbArray* srcPositions = new DbArray(0); srcPositions->Append(source); ShortestPath(srcPositions, &target, result); srcPositions->Destroy(); delete srcPositions; } void JNetwork::ShortestPath(const DbArray< RouteLocation >& source, const RouteLocation& target, JPath* result) { DbArray* tgtPositions = new DbArray(0); tgtPositions->Append(target); ShortestPath(&source, tgtPositions, result); tgtPositions->Destroy(); delete tgtPositions; } void JNetwork::ShortestPath(const DbArray* sources, const DbArray* targets, JPath* result) { if (sources != NULL && targets != NULL && result != NULL && sources->Size() > 0 && targets->Size() > 0) { result->Clear(); result->SetNetworkId(id); if (!JNetUtil::ArrayContainIntersections(*sources, *targets)) { DbArray* tgtEntries = new DbArray (0); Points* spatialEndPositions = new Points(0); ConnectSpatialPositions(targets, tgtEntries, false, spatialEndPositions); DbArray* srcEntries = new DbArray (0); ConnectSpatialPositions(sources, srcEntries, true, 0); DbArray* sp = 0; int tgtPosInArray = -1; bool tgtOverStartJunction = false; int srcStartPathJID = -1; double minDist = numeric_limits< double >::max(); if (!CheckForSameSections(srcEntries,tgtEntries,sp)) { if (!CheckForExistingNetdistance(srcEntries, tgtEntries, srcStartPathJID, tgtPosInArray, tgtOverStartJunction, minDist)) { PQManagement* pqueue = new PQManagement(); if (InitPriorityQueue(pqueue, srcEntries, spatialEndPositions)) { if (ProcessPriorityQueue(pqueue, tgtEntries, spatialEndPositions, tgtPosInArray, tgtOverStartJunction, srcStartPathJID, minDist)) { sp = new DbArray(0); WriteShortestPath(srcEntries, tgtEntries, srcStartPathJID, tgtPosInArray, tgtOverStartJunction, sp); } } pqueue->Destroy(); delete pqueue; } else { sp = new DbArray(0); WriteShortestPath(srcEntries, tgtEntries, srcStartPathJID, tgtPosInArray, tgtOverStartJunction, sp); } } if (sp != NULL) { result->SetPath(*sp, false, this); result->SetDefined(true); sp->Destroy(); delete sp; } else { result->SetDefined(false); } tgtEntries->Destroy(); delete tgtEntries; srcEntries->Destroy(); delete srcEntries; spatialEndPositions->Destroy(); spatialEndPositions->DeleteIfAllowed(); } } else { result->SetDefined(false); } } /* 1.1.1 Netdistance */ void JNetwork::Netdistance(const RouteLocation& source, const RouteLocation& target, CcReal* result) { DbArray* srcPositions = new DbArray(0); srcPositions->Append(source); DbArray* tgtPositions = new DbArray(0); tgtPositions->Append(target); Netdistance(srcPositions, tgtPositions, result); srcPositions->Destroy(); delete srcPositions; tgtPositions->Destroy(); delete tgtPositions; } void JNetwork::Netdistance(const RouteLocation& source, const DbArray< RouteLocation >& target, CcReal* result) { DbArray* srcPositions = new DbArray(0); srcPositions->Append(source); Netdistance(srcPositions, &target, result); srcPositions->Destroy(); delete srcPositions; } void JNetwork::Netdistance(const DbArray< RouteLocation >& source, const RouteLocation& target, CcReal* result) { DbArray* tgtPositions = new DbArray(0); tgtPositions->Append(target); Netdistance(&source, tgtPositions, result); tgtPositions->Destroy(); delete tgtPositions; } void JNetwork::Netdistance(const DbArray* sources, const DbArray* targets, CcReal* result) { if (sources != NULL && targets != NULL && result != NULL && sources->Size() > 0 && targets->Size() > 0) { if (!JNetUtil::ArrayContainIntersections(*sources, *targets)) { // there is no source-target pair on the same location DbArray* tgtEntries = new DbArray (0); Points* spatialEndPositions = new Points(0); ConnectSpatialPositions(targets, tgtEntries, false, spatialEndPositions); DbArray* srcEntries = new DbArray (0); ConnectSpatialPositions(sources, srcEntries, true, 0); DbArray* sp = 0; int tgtPosInArray = -1; bool tgtOverStartJunction = false; int srcStartPathJID = -1; double minDist = numeric_limits< double >::max(); if (!CheckForSameSections(srcEntries,tgtEntries,sp)) { if (!CheckForExistingNetdistance(srcEntries, tgtEntries, srcStartPathJID, tgtPosInArray, tgtOverStartJunction, minDist)) { PQManagement* pqueue = new PQManagement(); if (InitPriorityQueue(pqueue, srcEntries, spatialEndPositions)) { if (ProcessPriorityQueue(pqueue, tgtEntries, spatialEndPositions, tgtPosInArray, tgtOverStartJunction, srcStartPathJID, minDist)) { WriteNetdistance(srcEntries, tgtEntries, srcStartPathJID, tgtPosInArray, tgtOverStartJunction, result); } } pqueue->Destroy(); delete pqueue; } else { WriteNetdistance(srcEntries, tgtEntries, srcStartPathJID, tgtPosInArray, tgtOverStartJunction, result); } } else { if (sp != NULL) { result->SetDefined(true); result->Set(getLength(sp)); sp->Destroy(); delete sp; } else { result->SetDefined(false); } } tgtEntries->Destroy(); delete tgtEntries; srcEntries->Destroy(); delete srcEntries; spatialEndPositions->Destroy(); spatialEndPositions->DeleteIfAllowed(); } else { result->SetDefined(true); result->Set(0.0); } } else { result->SetDefined(false); } } /* 1.1 Private functions 1.1.1 Build ListExpr for Out-Function of Network */ ListExpr JNetwork::JunctionsToList() const { return relationToList(junctions, JNetUtil::GetJunctionsRelationTypeInfo()); } ListExpr JNetwork::SectionsToList() const { return relationToList(sections, JNetUtil::GetSectionsRelationTypeInfo()); } ListExpr JNetwork::RoutesToList() const { return relationToList(routes, JNetUtil::GetRoutesRelationTypeInfo()); } ListExpr JNetwork::NetdistancesToList() const { return relationToList(netdistances, JNetUtil::GetNetdistancesRelationTypeInfo()); } /* 1.1 Creates Trees */ void JNetwork::CreateTrees() { junctionsBTree = createBTree(junctions, JNetUtil::GetJunctionsRelationTypeInfo(), "Id"); junctionsRTree = createRTree(junctions, JNetUtil::GetJunctionsRelationTypeInfo(), "Pos"); sectionsBTree = createBTree(sections, JNetUtil::GetSectionsRelationTypeInfo(), "Id"); sectionsRTree = createRTree(sections, JNetUtil::GetSectionsRelationTypeInfo(), "Curve"); routesBTree = createBTree(routes, JNetUtil::GetRoutesRelationTypeInfo(),"Id"); } /* 1.1 Initialize netdistance ordered relation */ void JNetwork::InitNetdistances() { ListExpr relType; nl->ReadFromString(GetNetdistancesRelationType(), relType); ListExpr relNumType = SecondoSystem::GetCatalog()->NumericType(relType); netdistances = new OrderedRelation(relNumType); GenericRelationIterator* it = sections->MakeScan(); Tuple* actTuple = 0; while ((actTuple = it->GetNextTuple()) != 0) { Direction* sectDir = GetSectionDirection(actTuple); Direction compD(Down); if (sectDir->Compare(compD) != 0) { InsertNetdistanceTuple( ((CcInt*)actTuple->GetAttribute(SEC_STARTNODE_ID))->GetIntval(), ((CcInt*)actTuple->GetAttribute(SEC_ENDNODE_ID))->GetIntval(), ((CcInt*)actTuple->GetAttribute(SEC_ENDNODE_ID))->GetIntval(), ((CcInt*)actTuple->GetAttribute(SEC_ID))->GetIntval(), ((CcReal*)actTuple->GetAttribute(SEC_LENGTH))->GetRealval()); } Direction compU(Up); if (sectDir->Compare(compU) != 0) { InsertNetdistanceTuple( ((CcInt*)actTuple->GetAttribute(SEC_ENDNODE_ID))->GetIntval(), ((CcInt*)actTuple->GetAttribute(SEC_STARTNODE_ID))->GetIntval(), ((CcInt*)actTuple->GetAttribute(SEC_STARTNODE_ID))->GetIntval(), ((CcInt*)actTuple->GetAttribute(SEC_ID))->GetIntval(), ((CcReal*)actTuple->GetAttribute(SEC_LENGTH))->GetRealval()); } actTuple->DeleteIfAllowed(); actTuple = 0; sectDir->DeleteIfAllowed(); } delete it; it = junctions->MakeScan(); while ((actTuple = it->GetNextTuple()) != 0) { InsertNetdistanceTuple( ((CcInt*)actTuple->GetAttribute(JUNC_ID))->GetIntval(), ((CcInt*)actTuple->GetAttribute(JUNC_ID))->GetIntval(), ((CcInt*)actTuple->GetAttribute(JUNC_ID))->GetIntval(), -1, 0.0); actTuple->DeleteIfAllowed(); actTuple = 0; } delete it; } void JNetwork::InsertNetdistanceTuple(const int fromjid, const JPQEntry* entry, DbArray* wayEntries) { if (entry != NULL) { InsertNetdistanceTuple(fromjid, entry); if (wayEntries != NULL) { int i = 0; int oldWayEntrySize = wayEntries->Size(); InterSP curSPEntry; while (i < oldWayEntrySize) { wayEntries->Get(i,curSPEntry); if (curSPEntry.GetOrigStartPathJID() == fromjid) { if (curSPEntry.GetNextJID() < 0) { curSPEntry.SetNextJID(entry->GetEndPartJID()); curSPEntry.SetNextSID(entry->GetSectionId()); wayEntries->Put(i, curSPEntry); } InsertNetdistanceTuple(curSPEntry.GetCurStartPathJID(), entry->GetEndPartJID(), curSPEntry.GetNextJID(), curSPEntry.GetNextSID(), entry->GetDistFromStartPoint() - curSPEntry.GetDistFromOrigStartPath()); } i++; } wayEntries->Append(InterSP(fromjid, entry->GetEndPartJID(), entry->GetDistFromStartPoint(), -1,-1, entry->GetDistStartToStartJID())); } } } void JNetwork::InsertNetdistanceTuple(const int fromjid, const JPQEntry* jp) { if (jp != 0 && jp->GetEndPartJID() > -1 && jp->GetStartNextJID() > -1 && jp->GetStartNextSID() > -1 && jp->GetDistFromStartPoint() >= 0.0 && jp->GetStartNextJID() != jp->GetEndPartJID()) { InsertNetdistanceTuple(fromjid, jp->GetEndPartJID(),jp->GetStartNextJID(), jp->GetStartNextSID(), jp->GetDistFromStartPoint() - jp->GetDistStartToStartJID()); } } void JNetwork::InsertNetdistanceTuple(const int fromjid, const int tojid, const int viajid, const int viasid, const double dist) { if (fromjid != tojid && viasid > -1) { Tuple* existingTuple = GetNetdistanceTupleFor(fromjid, tojid); if (existingTuple == 0) { TupleType* tt = JNetUtil::getNetdistancesTupleType(); Tuple* insertTuple = new Tuple(tt); insertTuple->PutAttribute(NETDIST_FROM_JID, new CcInt(true, fromjid)); insertTuple->PutAttribute(NETDIST_TO_JID, new CcInt(true, tojid)); insertTuple->PutAttribute(NETDIST_NEXT_JID, new CcInt(true, viajid)); insertTuple->PutAttribute(NETDIST_NEXT_SID, new CcInt(true, viasid)); insertTuple->PutAttribute(NETDIST_DIST, new CcReal(true, dist)); netdistances->AppendTuple(insertTuple); insertTuple->DeleteIfAllowed(); } else { double existingDist = ((CcReal*)existingTuple->GetAttribute(NETDIST_DIST))->GetRealval(); if (!AlmostEqualAbsolute(existingDist,dist,tolerance) && existingDist > dist) { vector indexes(0); vector attrs(0); indexes.push_back(NETDIST_NEXT_JID); attrs.push_back(new CcInt(true, viajid)); indexes.push_back(NETDIST_NEXT_SID); attrs.push_back(new CcInt(true, viasid)); indexes.push_back(NETDIST_DIST); attrs.push_back(new CcReal(true, dist)); netdistances->UpdateTuple(existingTuple, indexes, attrs); indexes.clear(); attrs.clear(); } existingTuple->DeleteIfAllowed(); } } } /* 1.1 Get Tuples by identifier */ Tuple* JNetwork::GetRouteTupleWithId(const int rid) const { if (rid > -1) return GetTupleWithId(routesBTree, routes, rid); else return 0; } Tuple* JNetwork::GetSectionTupleWithId(const int sid) const { if (sid > -1) return GetTupleWithId(sectionsBTree, sections, sid); else return 0; } Tuple* JNetwork::GetSectionTupleWithTupleId(const TupleId tid) const { return sections->GetTuple(tid, false); } Tuple* JNetwork::GetJunctionTupleWithId(const int jid) const { if (jid > -1) return GetTupleWithId(junctionsBTree, junctions, jid); else return 0; } Tuple* JNetwork::GetTupleWithId(BTree* tree, const Relation* rel, const int id) const { CcInt* cid = new CcInt(true, id); Tuple* res = 0; BTreeIterator* it = tree->ExactMatch(cid); cid->DeleteIfAllowed(); if (it->Next() != 0) res = rel->GetTuple(it->GetId(), false); delete it; return res; } Tuple* JNetwork::GetNetdistanceTupleFor(const int fid, const int tid) const { CcInt* minNodeId = new CcInt(true,0); CcInt* maxNodeId = new CcInt(true,numeric_limits::max()); vector attributes(2); vector kElems(2); SmiKey::KeyDataType k = CcInt::getSMIKeyType(); kElems[0] = k; kElems[1] = k; CcInt* from = new CcInt(true,fid); attributes[0] = from; attributes[1] = minNodeId; CompositeKey lowerKey(attributes,kElems,false); attributes[1] = maxNodeId; CompositeKey upperKey(attributes,kElems,true); OrderedRelationIterator* it = (OrderedRelationIterator*) netdistances->MakeRangeScan(lowerKey, upperKey); Tuple* res = it->GetNextTuple(); bool found = false; while(res != 0 && !found) { if (tid == ((CcInt*)res->GetAttribute(NETDIST_TO_JID))->GetIntval()) { found = true; } else { res->DeleteIfAllowed(); res = it->GetNextTuple(); } } from->DeleteIfAllowed(); minNodeId->DeleteIfAllowed(); maxNodeId->DeleteIfAllowed(); attributes.clear(); kElems.clear(); delete it; return res; } /* 1.1. Get Tuple by Spatial Position */ Tuple* JNetwork::GetSectionTupleFor(const Point* p, double& pos) const { const Rectangle<2> pbox = p->BoundingBox(); double minMax[] = { pbox.MinD(0) - tolerance, pbox.MaxD(0) + tolerance, pbox.MinD(1) - tolerance, pbox.MaxD(1) + tolerance}; const Rectangle<2> searchbox(true,minMax); R_TreeLeafEntry<2,TupleId> curEntry; Tuple* actSect = 0; if (sectionsRTree->First(searchbox, curEntry)) actSect = sections->GetTuple(curEntry.info, false); else return 0; double diff; double mindiff = numeric_limits::max(); TupleId minTupId; bool found = false; SimpleLine* actCurve = GetSectionCurve(actSect); if (actCurve != 0) { found = actCurve->AtPoint(*p, pos, tolerance); if (!found) { mindiff = actCurve->Distance(*p); minTupId = curEntry.info; } } while (!found && sectionsRTree->Next(curEntry)) { if (actSect != 0) actSect->DeleteIfAllowed(); actSect = sections->GetTuple(curEntry.info, false); if (actSect != 0) { if (actCurve != 0) actCurve->DeleteIfAllowed(); actCurve = GetSectionCurve(actSect); if (actCurve != 0) { found = actCurve->AtPoint(*p, pos, tolerance); if (!found) { diff = actCurve->Distance(*p); if (diff < mindiff) { mindiff = diff; minTupId = curEntry.info; } } } } } if (!found) { if (actSect != 0) actSect->DeleteIfAllowed(); actSect = sections->GetTuple(minTupId, false); if (actSect != 0) { if (actCurve != 0) actCurve->DeleteIfAllowed(); actCurve = GetSectionCurve(actSect); if (actCurve != 0){ HalfSegment hs; double k1, k2; Point left, right; for ( int i = 0; i < actCurve->Size()-1; i++ ) { actCurve->Get ( i, hs ); left = hs.GetLeftPoint(); right = hs.GetRightPoint(); if (left.IsDefined() && right.IsDefined()) { double xl = left.GetX(); double yl = left.GetY(); double xr = right.GetX(); double yr = right.GetY(); double x = p->GetX(); double y = p->GetY(); if((AlmostEqualAbsolute(x, xl, tolerance) && AlmostEqualAbsolute(y, yl, tolerance)) || (AlmostEqualAbsolute(x, xr, tolerance) && AlmostEqualAbsolute(y, yr, tolerance))) { diff = 0.0; found = true; } else { if ( xl != xr && xl != x ) { k1 = ( y - yl ) / ( x - xl ); k2 = ( yr - yl ) / ( xr - xl ); if ((( xl < xr && ( x > xl || AlmostEqualAbsolute(x, xl, tolerance)) && ( x < xr || AlmostEqualAbsolute(x, xr, tolerance))) || (xl > xr && ( x < xl || AlmostEqualAbsolute(x, xl, tolerance)) && ( x > xr || AlmostEqualAbsolute(x, xr, tolerance)))) && ((( yl < yr || AlmostEqualAbsolute(yl, yr, tolerance)) && ( y > yl || AlmostEqualAbsolute(y, yl, tolerance)) && ( y < yr || AlmostEqualAbsolute(y, yr, tolerance))) || ( yl > yr && ( y < yl || AlmostEqualAbsolute(y, yl, tolerance)) && ( y > yr || AlmostEqualAbsolute(y, yr, tolerance))))) { diff = fabs ( k1-k2 ); found = true; } else { found = false; } } else { if((AlmostEqualAbsolute(xl, xr, tolerance) && AlmostEqualAbsolute(xl, x, tolerance)) && ((( yl < yr || AlmostEqualAbsolute(yl, yr, tolerance)) && ( yl < y || AlmostEqualAbsolute(yl, y , tolerance)) && ( y < yr || AlmostEqualAbsolute(y, yr, tolerance))) || ( yl > yr && ( yl > y || AlmostEqualAbsolute(yl, y, tolerance)) && ( y > yr || AlmostEqualAbsolute(y, yr, tolerance))))) { diff = 0.0; found = true; } else { found = false; } } } if ( found ) { LRS lrs; actCurve->Get ( hs.attr.edgeno, lrs ); actCurve->Get ( lrs.hsPos, hs ); pos = lrs.lrsPos + p->Distance(hs.GetDomPoint()); if(!actCurve->GetStartSmaller()) pos = actCurve->Length() - pos; if ( pos < 0.0 || AlmostEqualAbsolute( pos, 0.0, tolerance)) pos = 0.0; else if ( pos > actCurve->Length() || AlmostEqualAbsolute(pos, actCurve->Length(), tolerance)) pos = actCurve->Length(); break; } } } } } } if (actCurve != 0) actCurve->DeleteIfAllowed(); return actSect; } Tuple* JNetwork::GetSectionTupleFor(const RouteLocation& rloc, double& relpos) const { Tuple* res = 0; JListInt* sectList = GetRouteSectionList(rloc.GetRouteId()); if (sectList != 0) { int index = -1; res = GetSectionTupleFor(rloc, relpos, sectList, index); sectList->Destroy(); sectList->DeleteIfAllowed(); } return res; } Tuple* JNetwork::GetSectionTupleFor(const RouteLocation& rloc, double& pos, const JListInt* sectList, int& index) const { if (sectList != 0) { if (sectList->IsDefined() && !sectList->IsEmpty()) { Tuple* actSect = 0; CcInt actSid; if (index > -1 && index < sectList->GetNoOfComponents()) { sectList->Get(index, actSid); actSect = GetSectionTupleWithId(actSid.GetIntval()); if (actSect != 0) { if (CheckTupleForRLoc(actSect, rloc, pos)) return actSect; } } int i = 0; while (i < sectList->GetNoOfComponents()) { sectList->Get(i, actSid); actSect = GetSectionTupleWithId(actSid.GetIntval()); if (actSect != 0) { if (CheckTupleForRLoc(actSect, rloc, pos)) { index = i; return actSect; } actSect->DeleteIfAllowed(); actSect = 0; } i++; } } } index = -1; return 0; } void JNetwork::GetSectionTuplesFor(const Rectangle<2> bbox, vector& listSectTupIds) const { listSectTupIds.clear(); R_TreeLeafEntry<2,TupleId> curEntry; if (sectionsRTree->First(bbox, curEntry)) listSectTupIds.push_back(curEntry.info); while (sectionsRTree->Next(curEntry)) { listSectTupIds.push_back(curEntry.info); } } /* 1.1.1.1 By parts of Network */ void JNetwork::GetCoveredSections(const JRouteInterval& rint, DbArray* result) const { JListInt* sectList = GetRouteSectionList(rint.GetRouteId()); if (sectList != 0) { if (sectList->IsDefined() && !sectList->IsEmpty()) { CcInt curSid(false); for (int i = 0; i < sectList->GetNoOfComponents(); i++) { sectList->Get(i,curSid); Tuple* sectTuple = GetSectionTupleWithId(curSid.GetIntval()); if(sectTuple != 0) { JListRInt* sectRis = GetSectionListRouteIntervals(sectTuple); if (sectRis != 0) { JRouteInterval actInt(false); int j = 0; while (j < sectRis->GetNoOfComponents()) { sectRis->Get(j,actInt); if (rint.Overlaps(actInt, false)) { SectionInterval actSectInt(curSid.GetIntval(), JRouteInterval( rint.GetRouteId(), max(rint.GetFirstPosition(), actInt.GetFirstPosition()), min(rint.GetLastPosition(), actInt.GetLastPosition()), actInt.GetSide()), (actInt.GetFirstPosition() >= rint.GetFirstPosition()), (actInt.GetLastPosition() <= rint.GetLastPosition())); result->Append(actSectInt); j = sectRis->GetNoOfComponents(); } j++; } sectRis->DeleteIfAllowed(); sectRis = 0; } sectTuple->DeleteIfAllowed(); sectTuple = 0; } } } sectList->DeleteIfAllowed(); sectList = 0; } } /* 1.1 Access to attributes of the relations 1.1.1 Routes Relation Attributes */ double JNetwork::GetRouteLength(const int rid) const { Tuple* routeTup = GetRouteTupleWithId(rid); double res = GetRouteLength(routeTup); routeTup->DeleteIfAllowed(); return res; } double JNetwork::GetRouteLength(const Tuple* routeTuple) const { if (routeTuple != 0) return ((CcReal*)routeTuple->GetAttribute(ROUTE_LENGTH))->GetRealval(); else return 0.0; } JListInt* JNetwork::GetRouteSectionList(const int rid) const { JListInt* res = 0; Tuple* actRouteTup = GetRouteTupleWithId(rid); if (actRouteTup != 0) { res = GetRouteSectionList(actRouteTup); actRouteTup->DeleteIfAllowed(); } return res; } JListInt* JNetwork::GetRouteSectionList(const Tuple* actRoute) const { if (actRoute != 0) return new JListInt(*( (JListInt*) actRoute->GetAttribute(ROUTE_LIST_SECTIONS))); else return 0; } /* 1.1.1 Sections Relation Attributes */ SimpleLine* JNetwork::GetSectionCurve(const int sid) const { Tuple* actSect = GetSectionTupleWithId(sid); SimpleLine* res = GetSectionCurve(actSect); actSect->DeleteIfAllowed(); return res; } SimpleLine* JNetwork::GetSectionCurve(const Tuple* sectTuple) const { if (sectTuple != 0) return new SimpleLine(*((SimpleLine*) sectTuple->GetAttribute(SEC_CURVE))); else return 0; } SimpleLine* JNetwork::GetSectionCurve(const RouteLocation& rloc, double& relpos) const { Tuple* actSect = GetSectionTupleFor(rloc, relpos); SimpleLine* res = GetSectionCurve(actSect); actSect->DeleteIfAllowed(); return res; } JListRInt* JNetwork::GetSectionListRouteIntervals(const int sectid) const { Tuple* sectTup = GetSectionTupleWithId(sectid); JListRInt* res = GetSectionListRouteIntervals(sectTup); sectTup->DeleteIfAllowed(); return res; } JListRInt* JNetwork::GetSectionListRouteIntervals(const Tuple* sectTuple) const { if (sectTuple != 0) return new JListRInt(*( (JListRInt*) sectTuple->GetAttribute(SEC_LIST_ROUTEINTERVALS))); else return 0; } JRouteInterval* JNetwork::GetSectionFirstRouteInterval(const Tuple* sectTuple) const { JRouteInterval* result = 0; if (sectTuple != 0) { JListRInt* rintList = GetSectionListRouteIntervals(sectTuple); if(rintList != 0) { if (!rintList->IsEmpty()) { JRouteInterval res; rintList->Get(0,res); result = new JRouteInterval(res); } rintList->DeleteIfAllowed(); rintList = 0; } } return result; } JRouteInterval* JNetwork::GetSectionRouteIntervalForRID(int rid, const Tuple* sectTup) const { if (sectTup != 0) { JListRInt* rintList = GetSectionListRouteIntervals(sectTup); if (rintList != 0) { if (rintList->IsDefined() && !rintList->IsEmpty()) { JRouteInterval actInt; int j = 0; while (j < rintList->GetNoOfComponents()) { rintList->Get(j,actInt); if (actInt.GetRouteId() == rid) { rintList->Destroy(); rintList->DeleteIfAllowed(); return new JRouteInterval(actInt); } j++; } } rintList->Destroy(); rintList->DeleteIfAllowed(); } } return 0; } JRouteInterval* JNetwork::GetSectionRouteIntervalForRLoc( const RouteLocation& rloc, const Tuple* sectTup) const { if (sectTup != 0) { JListRInt* rintList = GetSectionListRouteIntervals(sectTup); if (rintList != 0) { if (rintList->IsDefined() && !rintList->IsEmpty()) { JRouteInterval actInt; int j = 0; while (j < rintList->GetNoOfComponents()) { rintList->Get(j,actInt); if (actInt.Contains(rloc, tolerance)) { rintList->Destroy(); rintList->DeleteIfAllowed(); return new JRouteInterval(actInt); } j++; } } rintList->Destroy(); rintList->DeleteIfAllowed(); } } return 0; } double JNetwork::GetSectionLength(const Tuple* actSect) const { if (actSect != 0) return ((CcReal*)actSect->GetAttribute(SEC_LENGTH))->GetRealval(); else return 0.0; } Direction* JNetwork::GetSectionDirection(const Tuple* actSect) const { if (actSect != 0) return new Direction(*((Direction*)actSect->GetAttribute(SEC_DIRECTION))); else return 0; } int JNetwork::GetSectionId(const Tuple* actSect) const { if (actSect != 0) return ((CcInt*)actSect->GetAttribute(SEC_ID))->GetIntval(); else return -1; } JRouteInterval* JNetwork::GetRouteIntervalFor(const JListRLoc* leftrlocs, const JListRLoc* rightrlocs, const bool allowResetSide) const { JRouteInterval* res = 0; if (leftrlocs != 0 && rightrlocs != 0 && leftrlocs->IsDefined() && rightrlocs->IsDefined() && !leftrlocs->IsEmpty() && !rightrlocs->IsEmpty()) { int i = 0; int j = 0; while (i < leftrlocs->GetNoOfComponents() && j < rightrlocs->GetNoOfComponents()) { RouteLocation left, right; leftrlocs->Get(i,left); rightrlocs->Get(j,right); if (left.IsOnSameRoute(right)) { if (res == 0) { res = new JRouteInterval(left, right, allowResetSide); } else { JRouteInterval* inter = new JRouteInterval(left, right, allowResetSide); if (inter->GetLength() < res->GetLength()) { res->DeleteIfAllowed(); res = inter; } else { inter->DeleteIfAllowed(); inter = 0; } } i++; j++; } else { switch(left.Compare(right)) { case -1: { i++; break; } case 1: { j++; break; } default: {//should never happen assert(false); i = leftrlocs->GetNoOfComponents(); j = rightrlocs->GetNoOfComponents(); break; } } } } } return res; } JRouteInterval* JNetwork::GetRouteIntervalFor(const RouteLocation& left, const RouteLocation& right, const bool allowResetSide) const { JListRLoc* leftrlocs = GetNetworkValuesOf(left); JListRLoc* rightrlocs = GetNetworkValuesOf(right); JRouteInterval* res = GetRouteIntervalFor(leftrlocs, rightrlocs, allowResetSide); leftrlocs->Destroy(); leftrlocs->DeleteIfAllowed(); rightrlocs->Destroy(); rightrlocs->DeleteIfAllowed(); return res; } void JNetwork::GetAdjacentSections(const int sid, const jnetwork::Direction* dir, JListInt* result) const { result->Clear(); Tuple* sectTuple = GetSectionTupleWithId(sid); if (sectTuple != 0) { result->StartBulkload(); JListInt* tmp = 0; Direction compD(Down); int compResult = dir->Compare(compD); if ( compResult > -1) //down or both { tmp = GetSectionListAdjSectionsDown(sectTuple); if (tmp != 0) { result->operator+=(*tmp); tmp->Destroy(); tmp->DeleteIfAllowed(); tmp = 0; } } if (compResult != 0) //up or both { tmp = GetSectionListAdjSectionsUp(sectTuple); if (tmp != 0) { result->operator+=(*tmp); tmp->Destroy(); tmp->DeleteIfAllowed(); tmp = 0; } } result->EndBulkload(); sectTuple->DeleteIfAllowed(); sectTuple = 0; } } void JNetwork::GetReverseAdjacentSections(const int sid, const jnetwork::Direction* dir, JListInt* result) const { result->Clear(); Tuple* sectTuple = GetSectionTupleWithId(sid); if (sectTuple != 0) { result->StartBulkload(); JListInt* tmp = 0; Direction compD(Down); int compResult = dir->Compare(compD); if ( compResult > -1) //down or both { tmp = GetSectionListReverseAdjSectionsDown(sectTuple); if (tmp != 0) { result->operator+=(*tmp); tmp->Destroy(); tmp->DeleteIfAllowed(); tmp = 0; } } if (compResult != 0) //up or both { tmp = GetSectionListReverseAdjSectionsUp(sectTuple); if (tmp != 0) { result->operator+=(*tmp); tmp->Destroy(); tmp->DeleteIfAllowed(); tmp = 0; } } result->EndBulkload(); sectTuple->DeleteIfAllowed(); sectTuple = 0; } } JListInt* JNetwork::GetSectionListAdjSectionsUp(const Tuple* sectTuple) const { if (sectTuple != 0) return new JListInt(*( (JListInt*)sectTuple->GetAttribute(SEC_LIST_ADJ_SECTIONS_UP))); else return 0; } JListInt* JNetwork::GetSectionListAdjSectionsDown(const Tuple* sectTuple) const { if (sectTuple != 0) return new JListInt(*( (JListInt*)sectTuple->GetAttribute(SEC_LIST_ADJ_SECTIONS_DOWN))); else return 0; } JListInt* JNetwork::GetSectionListReverseAdjSectionsUp(const Tuple* sectTuple) const { if (sectTuple != 0) return new JListInt(*( (JListInt*)sectTuple->GetAttribute(SEC_LIST_REV_ADJ_SECTIONS_UP))); else return 0; } JListInt* JNetwork::GetSectionListReverseAdjSectionsDown(const Tuple* sectTuple) const { if (sectTuple != 0) return new JListInt(*( (JListInt*)sectTuple->GetAttribute(SEC_LIST_REV_ADJ_SECTIONS_DOWN))); else return 0; } Tuple* JNetwork::GetSectionStartJunctionTuple(const Tuple* sectTuple) const { if (sectTuple != 0) return GetJunctionTupleWithId( ((CcInt*)sectTuple->GetAttribute(SEC_STARTNODE_ID))->GetIntval()); else return 0; } Tuple* JNetwork::GetSectionEndJunctionTuple(const Tuple* sectTuple) const { return GetJunctionTupleWithId( ((CcInt*)sectTuple->GetAttribute(SEC_ENDNODE_ID))->GetIntval()); } JListRLoc* JNetwork::GetSectionStartJunctionRLocs(const Tuple* sectTuple) const { JListRLoc* res = 0; if (sectTuple != 0) { Tuple* juncTup = GetSectionStartJunctionTuple(sectTuple); res = GetJunctionListRLoc(juncTup); juncTup->DeleteIfAllowed(); } return res; } JListRLoc* JNetwork::GetSectionEndJunctionRLocs(const Tuple* sectTuple) const { JListRLoc* res = 0; if (sectTuple != 0) { Tuple* juncTup = GetSectionEndJunctionTuple(sectTuple); res = GetJunctionListRLoc(juncTup); juncTup->DeleteIfAllowed(); } return res; } int JNetwork::GetSectionStartJunctionID(const Tuple* sectTuple) const { if (sectTuple != 0) return ((CcInt*)sectTuple->GetAttribute(SEC_STARTNODE_ID))->GetIntval(); else return -1; } int JNetwork::GetSectionEndJunctionID(const Tuple* sectTuple) const { if (sectTuple != 0) return ((CcInt*)sectTuple->GetAttribute(SEC_ENDNODE_ID))->GetIntval(); else return -1; } Point* JNetwork::GetSectionStartPoint(const Tuple* sectTuple) const { Point* res = 0; if (sectTuple != 0) { int jid = GetSectionStartJunctionID(sectTuple); if (jid > -1) { Tuple* juncTuple = GetJunctionTupleWithId(jid); if (juncTuple != 0) { res = GetJunctionSpatialPos(juncTuple); juncTuple->DeleteIfAllowed(); } } } return res; } Point* JNetwork::GetSectionEndPoint(const Tuple* sectTuple) const { Point* res = 0; if (sectTuple != 0) { int jid = GetSectionEndJunctionID(sectTuple); if (jid > -1) { Tuple* juncTuple = GetJunctionTupleWithId(jid); if (juncTuple != 0) { res = GetJunctionSpatialPos(juncTuple); juncTuple->DeleteIfAllowed(); } } } return res; } double JNetwork::GetSectionMaxSpeed(const Tuple* sectTuple) const { if (sectTuple != 0) return ((CcReal*)sectTuple->GetAttribute(SEC_VMAX))->GetRealval(); else return 0.0; } /* 1.1.1 Juctions Attributes */ int JNetwork::GetJunctionId(const Tuple* juncTup) const { if (juncTup != 0) return ((CcInt*)juncTup->GetAttribute(JUNC_ID))->GetIntval(); else return -1; } JListRLoc* JNetwork::GetJunctionListRLoc(const Tuple* juncTuple) const { if (juncTuple != 0) return new JListRLoc(*((JListRLoc*) juncTuple->GetAttribute(JUNC_LIST_ROUTEPOSITIONS))); else return 0; } Point* JNetwork::GetJunctionSpatialPos(const Tuple* juncTuple) const { if (juncTuple != 0) return new Point(*((Point*) juncTuple->GetAttribute(JUNC_POS))); else return 0; } JListInt* JNetwork::GetJunctionOutSectionList(const Tuple* juncTup) const { if (juncTup != 0) return new JListInt(*( (JListInt*) juncTup->GetAttribute(JUNC_LIST_OUTSECTIONS))); else return 0; } JListInt* JNetwork::GetJunctionInSectionList(const Tuple* juncTup) const { if (juncTup != 0) return new JListInt(*( (JListInt*) juncTup->GetAttribute(JUNC_LIST_INSECTIONS))); else return 0; } /* 1.1.1 Netdistance Relation */ int JNetwork::GetNetdistanceNextSID(const Tuple* actNetDistTup) const { if (actNetDistTup != 0) return ((CcInt*)actNetDistTup->GetAttribute(NETDIST_NEXT_SID))->GetIntval(); else return -1; } double JNetwork::GetNetdistanceDistance(const Tuple* netDistTup) const { if (netDistTup != NULL) { return ((CcReal*)netDistTup->GetAttribute(NETDIST_DIST))->GetRealval(); } else return numeric_limits< double >::max(); } /* 1.1 DirectConnectionExists */ JRouteInterval* JNetwork::DirectConnection(const int sectId, const RouteLocation& source, const RouteLocation& target) const { JRouteInterval* res = 0; Tuple* sectTup = GetSectionTupleWithId(sectId); if (sectTup != NULL) { Direction* sectDir = GetSectionDirection(sectTup); if (sectDir != NULL) { Direction moveDir(Both); if (source.GetRouteId() == target.GetRouteId()) { if (source.GetPosition() <= target.GetPosition()) moveDir.SetDirection((Direction)Up); else moveDir.SetDirection((Direction)Down); if (sectDir->SameSide(moveDir, false)) { res = new JRouteInterval(source.GetRouteId(), source.GetPosition(), target.GetPosition(), moveDir); } } sectDir->DeleteIfAllowed(); } sectTup->DeleteIfAllowed(); } return res; } bool JNetwork::DirectConnectionExists(const int startSID, const int endSID, const Tuple* sourceSectTup, const Tuple* targetSectTup, const RouteLocation& source, const RouteLocation& target, DbArray* res, double& length) const { if (sourceSectTup != 0 && targetSectTup != 0) { if (source.GetRouteId() == target.GetRouteId()) { Direction* sectDir = GetSectionDirection(sourceSectTup); Direction dirU(Up); Direction dirD(Down); Direction movDir(Both); JRouteInterval* tmp = 0; if (source.GetPosition() > target.GetPosition()) movDir = dirD; else movDir = dirU; if (startSID == endSID && sectDir->SameSide(movDir, false)) { tmp = new JRouteInterval(source.GetRouteId(), source.GetPosition(), target.GetPosition(), movDir); } else { JListInt* sectlist = GetRouteSectionList(source.GetRouteId()); CcInt curSid; for (int i = 0; i < sectlist->GetNoOfComponents(); i++) { sectlist->Get(i,curSid); Tuple* actSect = GetSectionTupleWithId(curSid.GetIntval()); JListRInt* sectRis = GetSectionListRouteIntervals(actSect); JRouteInterval actInt; int j = 0; while (j < sectRis->GetNoOfComponents()) { sectRis->Get(j,actInt); if (actInt.GetRouteId() == source.GetRouteId() && (actInt.Between(source,target) || actInt.Contains(source) || actInt.Contains(target)) && !movDir.SameSide(actInt.GetSide(), false)) { sectRis->Destroy(); sectRis->DeleteIfAllowed(); sectlist->Destroy(); sectlist->DeleteIfAllowed(); actSect->DeleteIfAllowed(); sectDir->DeleteIfAllowed(); return false; } j++; } sectRis->Destroy(); sectRis->DeleteIfAllowed(); actSect->DeleteIfAllowed(); } sectlist->Destroy(); sectlist->DeleteIfAllowed(); tmp = new JRouteInterval(source.GetRouteId(), min(source.GetPosition(), target.GetPosition()), max(source.GetPosition(), target.GetPosition()), movDir); } res->Append(*tmp); length += tmp->GetLength(); tmp->DeleteIfAllowed(); sectDir->DeleteIfAllowed(); return true; } else return false; } else return false; } /* 1.1.1.1 AddAdjacentSections */ template void JNetwork::AddAdjacentSections(PQManagement* pq, JPQEntry curEntry, const SpatialPos* targetPos) { if (pq != 0) { Tuple* pqSectTup = GetSectionTupleWithId(curEntry.GetSectionId()); if (pqSectTup != 0) { Direction movDir = curEntry.GetDirection(); JListInt* listSID = 0; Direction compU(Up); if (movDir.Compare(compU) == 0) listSID = GetSectionListAdjSectionsUp(pqSectTup); else listSID = GetSectionListAdjSectionsDown(pqSectTup); if (listSID != 0) { AddAdjacentSections(pq, listSID, curEntry, targetPos); listSID->Destroy(); listSID->DeleteIfAllowed(); listSID = 0; } pqSectTup->DeleteIfAllowed(); pqSectTup = 0; } } } template void JNetwork::AddAdjacentSections(PQManagement* pq, const JListInt* listSID, JPQEntry curEntry, const SpatialPos* targetPos) { if (pq != 0 && listSID != 0) { Tuple* curSectTup = 0; CcInt nextSID; JPQEntry* tmpEntry= 0; for (int i = 0; i < listSID->GetNoOfComponents(); i++) { listSID->Get(i,nextSID); int curSID = nextSID.GetIntval(); tmpEntry = new JPQEntry(curEntry); if (curEntry.GetSectionId() < 0 && curEntry.GetStartNextSID() < 0) { tmpEntry->SetSectionId(curSID); tmpEntry->SetStartNextSID(curSID); } tmpEntry->SetSectionId(curSID); curSectTup = GetSectionTupleWithId(nextSID.GetIntval()); if (curSectTup != 0) { int sectEndJuncId = GetSectionEndJunctionID(curSectTup); int sectStartJuncId = GetSectionStartJunctionID(curSectTup); if (sectEndJuncId == tmpEntry->GetEndPartJID()) { tmpEntry->SetDirection((Direction) Down); tmpEntry->SetStartPartJID(sectEndJuncId); tmpEntry->SetEndPartJID(sectStartJuncId); } else { tmpEntry->SetDirection((Direction) Up); tmpEntry->SetStartPartJID(sectStartJuncId); tmpEntry->SetEndPartJID(sectEndJuncId); } Tuple* curJunc = GetJunctionTupleWithId(tmpEntry->GetEndPartJID()); if (curJunc != 0) { Point* curEndPoint = GetJunctionSpatialPos(curJunc); if (curEndPoint != 0) { double curDist = curEntry.GetDistFromStartPoint() + GetSectionLength(curSectTup); tmpEntry->SetDistFromStartPoint(curDist); if (targetPos != NULL) tmpEntry->SetPriority(curDist+targetPos->Distance(*curEndPoint)); else tmpEntry->SetPriority(curDist); pq->Insert(*tmpEntry); curEndPoint->DeleteIfAllowed(); curEndPoint = 0; } curJunc->DeleteIfAllowed(); curJunc = 0; } curSectTup->DeleteIfAllowed(); curSectTup = 0; } delete tmpEntry; tmpEntry = 0; } } } void JNetwork::AddAdjacentSections(PQManagement* pq, JPQEntry curEntry, JLine* result, const double distLimit) { if (pq != 0 && curEntry.GetDistFromStartPoint() < distLimit) { Tuple* pqSectTup = GetSectionTupleWithId(curEntry.GetSectionId()); if (pqSectTup != 0) { Direction movDir = curEntry.GetDirection(); JListInt* listSID = 0; Direction compU(Up); if (movDir.Compare(compU) == 0) listSID = GetSectionListAdjSectionsUp(pqSectTup); else listSID = GetSectionListAdjSectionsDown(pqSectTup); if (listSID != 0) { AddAdjacentSections(pq, listSID, curEntry, result, distLimit); listSID->Destroy(); listSID->DeleteIfAllowed(); listSID = 0; } pqSectTup->DeleteIfAllowed(); pqSectTup = 0; } } } void JNetwork::AddAdjacentSections(PQManagement* pq, const JListInt* listSID, JPQEntry curEntry, JLine* result, const double distLimit) { if (pq != 0 && listSID != 0) { Tuple* curSectTup = 0; CcInt nextSID; JPQEntry* tmpEntry= 0; for (int i = 0; i < listSID->GetNoOfComponents(); i++) { listSID->Get(i,nextSID); int curSID = nextSID.GetIntval(); tmpEntry = new JPQEntry(curEntry); if (curEntry.GetSectionId() < 0 && curEntry.GetStartNextSID() < 0) { tmpEntry->SetSectionId(curSID); tmpEntry->SetStartNextSID(curSID); } tmpEntry->SetSectionId(curSID); curSectTup = GetSectionTupleWithId(nextSID.GetIntval()); if (curSectTup != 0) { int sectEndJuncId = GetSectionEndJunctionID(curSectTup); int sectStartJuncId = GetSectionStartJunctionID(curSectTup); if (sectEndJuncId == tmpEntry->GetEndPartJID()) { tmpEntry->SetDirection((Direction) Down); tmpEntry->SetStartPartJID(sectEndJuncId); tmpEntry->SetEndPartJID(sectStartJuncId); } else { tmpEntry->SetDirection((Direction) Up); tmpEntry->SetStartPartJID(sectStartJuncId); tmpEntry->SetEndPartJID(sectEndJuncId); } Tuple* curJunc = GetJunctionTupleWithId(tmpEntry->GetEndPartJID()); if (curJunc != 0) { Point* curEndPoint = GetJunctionSpatialPos(curJunc); if (curEndPoint != 0) { double curDist = curEntry.GetDistFromStartPoint() + GetSectionLength(curSectTup); tmpEntry->SetDistFromStartPoint(curDist); tmpEntry->SetPriority(curDist); JRouteInterval* sectRint = GetSectionFirstRouteInterval(curSectTup); if (sectRint != NULL) { JRouteInterval tmp(*sectRint); sectRint->DeleteIfAllowed(); sectRint = 0; if (curDist <= distLimit) { result->Add(tmp); pq->Insert(*tmpEntry); } else { Direction compD(Down); int test2 = tmpEntry->GetDirection().Compare(compD); if (test2 < 0) // Up { tmp.SetInterval(tmp.GetFirstPosition(), tmp.GetFirstPosition() + distLimit - curEntry.GetDistFromStartPoint()); } else // Down { tmp.SetInterval(tmp.GetLastPosition() - (distLimit - curEntry.GetDistFromStartPoint()), tmp.GetLastPosition()); } result->Add(tmp); } } curEndPoint->DeleteIfAllowed(); curEndPoint = 0; } curJunc->DeleteIfAllowed(); curJunc = 0; } curSectTup->DeleteIfAllowed(); curSectTup = 0; } delete tmpEntry; tmpEntry = 0; } } } void JNetwork::AddReverseAdjacentSections(PQManagement* pq, JPQEntry curEntry) { if (pq != 0) { Tuple* pqSectTup = GetSectionTupleWithId(curEntry.GetSectionId()); if (pqSectTup != 0) { Direction movDir = curEntry.GetDirection(); JListInt* listSID = 0; Direction compU(Up); if (movDir.Compare(compU) == 0) listSID = GetSectionListReverseAdjSectionsUp(pqSectTup); else listSID = GetSectionListReverseAdjSectionsDown(pqSectTup); if (listSID != 0) { AddReverseAdjacentSections(pq, listSID, curEntry); listSID->Destroy(); listSID->DeleteIfAllowed(); listSID = 0; } pqSectTup->DeleteIfAllowed(); pqSectTup = 0; } } } void JNetwork::AddReverseAdjacentSections(PQManagement* pq, const JListInt* listSID, JPQEntry curEntry) { if (pq != 0 && listSID != 0) { Tuple* curSectTup = 0; CcInt nextSID; JPQEntry* tmpEntry= 0; for (int i = 0; i < listSID->GetNoOfComponents(); i++) { listSID->Get(i,nextSID); int curSID = nextSID.GetIntval(); tmpEntry = new JPQEntry(curEntry); if (curEntry.GetSectionId() < 0 && curEntry.GetStartNextSID() < 0) { tmpEntry->SetSectionId(curSID); tmpEntry->SetStartNextSID(curSID); } tmpEntry->SetSectionId(curSID); curSectTup = GetSectionTupleWithId(curSID); if (curSectTup != 0) { int sectEndJuncId = GetSectionEndJunctionID(curSectTup); int sectStartJuncId = GetSectionStartJunctionID(curSectTup); if (sectEndJuncId == tmpEntry->GetEndPartJID()) { tmpEntry->SetDirection((Direction) Up); tmpEntry->SetStartPartJID(sectEndJuncId); tmpEntry->SetEndPartJID(sectStartJuncId); } else { tmpEntry->SetDirection((Direction) Down); tmpEntry->SetStartPartJID(sectStartJuncId); tmpEntry->SetEndPartJID(sectEndJuncId); } Tuple* curJunc = GetJunctionTupleWithId(tmpEntry->GetEndPartJID()); if (curJunc != 0) { Point* curEndPoint = GetJunctionSpatialPos(curJunc); if (curEndPoint != 0) { double curDist = curEntry.GetDistFromStartPoint() + GetSectionLength(curSectTup); tmpEntry->SetDistFromStartPoint(curDist); tmpEntry->SetPriority(curDist); pq->Insert(*tmpEntry); curEndPoint->DeleteIfAllowed(); curEndPoint = 0; } curJunc->DeleteIfAllowed(); curJunc = 0; } curSectTup->DeleteIfAllowed(); curSectTup = 0; } delete tmpEntry; tmpEntry = 0; } } } void JNetwork::AddReverseAdjacentSections(PQManagement* pq, JPQEntry curEntry, JLine* result, const double distLimit) { if (pq != 0) { Tuple* pqSectTup = GetSectionTupleWithId(curEntry.GetSectionId()); if (pqSectTup != 0) { Direction movDir = curEntry.GetDirection(); JListInt* listSID = 0; Direction compU(Up); if (movDir.Compare(compU) == 0) listSID = GetSectionListReverseAdjSectionsUp(pqSectTup); else listSID = GetSectionListReverseAdjSectionsDown(pqSectTup); if (listSID != 0) { AddReverseAdjacentSections(pq, listSID, curEntry, result, distLimit); listSID->Destroy(); listSID->DeleteIfAllowed(); listSID = 0; } pqSectTup->DeleteIfAllowed(); pqSectTup = 0; } } } void JNetwork::AddReverseAdjacentSections(PQManagement* pq, const JListInt* listSID, JPQEntry curEntry, JLine* result, const double distLimit) { if (pq != 0 && listSID != 0) { Tuple* curSectTup = 0; CcInt nextSID; JPQEntry* tmpEntry= 0; for (int i = 0; i < listSID->GetNoOfComponents(); i++) { listSID->Get(i,nextSID); int curSID = nextSID.GetIntval(); tmpEntry = new JPQEntry(curEntry); if (curEntry.GetSectionId() < 0 && curEntry.GetStartNextSID() < 0) { tmpEntry->SetSectionId(curSID); tmpEntry->SetStartNextSID(curSID); } tmpEntry->SetSectionId(curSID); curSectTup = GetSectionTupleWithId(curSID); if (curSectTup != 0) { int sectEndJuncId = GetSectionEndJunctionID(curSectTup); int sectStartJuncId = GetSectionStartJunctionID(curSectTup); if (sectEndJuncId == tmpEntry->GetEndPartJID()) { tmpEntry->SetDirection((Direction) Up); tmpEntry->SetStartPartJID(sectEndJuncId); tmpEntry->SetEndPartJID(sectStartJuncId); } else { tmpEntry->SetDirection((Direction) Down); tmpEntry->SetStartPartJID(sectStartJuncId); tmpEntry->SetEndPartJID(sectEndJuncId); } Tuple* curJunc = GetJunctionTupleWithId(tmpEntry->GetEndPartJID()); if (curJunc != 0) { Point* curEndPoint = GetJunctionSpatialPos(curJunc); if (curEndPoint != 0) { double curDist = curEntry.GetDistFromStartPoint() + GetSectionLength(curSectTup); tmpEntry->SetDistFromStartPoint(curDist); tmpEntry->SetPriority(curDist); JRouteInterval* sectRint = GetSectionFirstRouteInterval(curSectTup); if (sectRint != NULL) { JRouteInterval tmp(*sectRint); sectRint->DeleteIfAllowed(); sectRint = 0; if (curDist <= distLimit) { result->Add(tmp); pq->Insert(*tmpEntry); } else { Direction compD(Down); int test = tmpEntry->GetDirection().Compare(compD); if (test < 0) // Up { tmp.SetInterval(tmp.GetLastPosition() - (distLimit - curEntry.GetDistFromStartPoint()), tmp.GetLastPosition()); } else // Down { tmp.SetInterval(tmp.GetFirstPosition(), tmp.GetFirstPosition() + distLimit - curEntry.GetDistFromStartPoint()); } result->Add(tmp); } } curEndPoint->DeleteIfAllowed(); curEndPoint = 0; } curJunc->DeleteIfAllowed(); curJunc = 0; } curSectTup->DeleteIfAllowed(); curSectTup = 0; } delete tmpEntry; tmpEntry = 0; } } } /* 1.1.1.1 WriteShortestPath */ void JNetwork::WriteShortestPath(const DbArray< PosJNetSpatial >* sources, const DbArray< PosJNetSpatial >* targets, const int srcStartPathJID, const int tgtPosInArray, const bool tgtOverStartJunction, DbArray*& result) { if (sources != NULL && targets != NULL && result != NULL && sources->Size() > 0 && targets->Size() > 0 && targets->Size() > tgtPosInArray) { JRouteInterval* curRint = 0; JRouteInterval* tmp = 0; int srcPosInArray(-1); bool srcOverStartJunc(false); PosJNetSpatial start, end; Tuple* sectTup = 0; getStartPosJNet(sources, srcStartPathJID, srcPosInArray, srcOverStartJunc, start); int startJID = srcStartPathJID; if (start.GetSectionId() > -1) { sectTup = GetSectionTupleWithId(start.GetSectionId()); if (sectTup != NULL) { curRint = GetSectionFirstRouteInterval(sectTup); if (curRint != NULL) { if (srcOverStartJunc) { if (start.GetDistFromStartJunction() >= 0.0) { tmp = new JRouteInterval(curRint->GetRouteId(), curRint->GetFirstPosition(), curRint->GetFirstPosition() + start.GetDistFromStartJunction(), Down); } startJID = start.GetStartJID(); } else { if (start.GetDistFromEndJunction() >= 0.0) { tmp = new JRouteInterval(curRint->GetRouteId(), curRint->GetLastPosition() - start.GetDistFromEndJunction(), curRint->GetLastPosition(), Up); } startJID = start.GetEndJID(); } if (tmp != NULL) { if (tmp->GetLength() > 0.0) { result->Append(*tmp); } tmp->DeleteIfAllowed(); tmp = 0; } curRint->DeleteIfAllowed(); curRint = 0; } sectTup->DeleteIfAllowed(); sectTup = 0; } } bool found = false; targets->Get(tgtPosInArray,end); if (srcStartPathJID == end.GetStartJID() || srcStartPathJID == end.GetEndJID()) { found = true; } Tuple* netDistTup = 0; int endPathJID; if (tgtOverStartJunction) endPathJID = end.GetStartJID(); else endPathJID = end.GetEndJID(); while (!found) { netDistTup = GetNetdistanceTupleFor(startJID, endPathJID); if (netDistTup != NULL) { sectTup = GetSectionTupleWithId(GetNetdistanceNextSID(netDistTup)); if (sectTup != NULL) { curRint = GetSectionFirstRouteInterval(sectTup); if (curRint != NULL) { if (startJID == GetSectionStartJunctionID(sectTup)) { curRint->SetSide((Direction) Up); startJID = GetSectionEndJunctionID(sectTup); } else { curRint->SetSide((Direction) Down); startJID = GetSectionStartJunctionID(sectTup); } result->Append(*curRint); if (endPathJID == startJID) { found = true; } curRint->DeleteIfAllowed(); curRint = 0; } sectTup->DeleteIfAllowed(); sectTup = 0; } netDistTup->DeleteIfAllowed(); netDistTup = 0; } } targets->Get(tgtPosInArray, end); if (end.GetSectionId() > -1) { sectTup = GetSectionTupleWithId(end.GetSectionId()); if (sectTup != NULL) { curRint = GetSectionFirstRouteInterval(sectTup); if (curRint != NULL) { if (tgtOverStartJunction) { if (end.GetDistFromStartJunction() >= 0.0) { tmp = new JRouteInterval(curRint->GetRouteId(), curRint->GetFirstPosition(), curRint->GetFirstPosition() + end.GetDistFromStartJunction(), Up); } } else { if (end.GetDistFromEndJunction() >= 0.0) { tmp = new JRouteInterval(curRint->GetRouteId(), curRint->GetLastPosition(), curRint->GetLastPosition() - end.GetDistFromEndJunction(), Down); } } if (tmp != NULL) { if (tmp->GetLength() > 0.0) { result->Append(*tmp); } tmp->DeleteIfAllowed(); tmp = 0; } curRint->DeleteIfAllowed(); curRint = 0; } sectTup->DeleteIfAllowed(); sectTup = 0; } } } } /* 1.1.1.1 WriteNetdistance */ void JNetwork::WriteNetdistance(const DbArray< PosJNetSpatial >* sources, const DbArray< PosJNetSpatial >* targets, const int srcStartPathJID, const int tgtPosInArray, const bool tgtOverStartJunction, CcReal* res) { if (sources != NULL && targets != NULL && res != NULL && sources->Size() > 0 && targets->Size() > 0 && targets->Size() > tgtPosInArray) { double result = 0.0; res->SetDefined(true); int srcPosInArray(-1); bool srcOverStartJunc(false); PosJNetSpatial start, end; getStartPosJNet(sources, srcStartPathJID, srcPosInArray, srcOverStartJunc, start); if (srcOverStartJunc) result = result + start.GetDistFromStartJunction(); else result = result + start.GetDistFromEndJunction(); targets->Get(tgtPosInArray, end); int endPathJID; if (tgtOverStartJunction) { result = result + end.GetDistFromStartJunction(); endPathJID = end.GetStartJID(); } else { result = result + end.GetDistFromEndJunction(); endPathJID = end.GetEndJID(); } if (srcStartPathJID != endPathJID) { Tuple* netDistTup = GetNetdistanceTupleFor(srcStartPathJID, endPathJID); if (netDistTup != NULL) { result = result + GetNetdistanceDistance(netDistTup); netDistTup->DeleteIfAllowed(); netDistTup = 0; } } res->Set(result); } else res->SetDefined(false); } /* 1.1.1 ExistsCommonRoute */ bool JNetwork::ExistsCommonRoute(RouteLocation& src, RouteLocation& tgt) const { if (!src.IsDefined() || !tgt.IsDefined()) { return false; } if (src.IsOnSameRoute(tgt)) { return true; } else { JListRLoc* left = GetNetworkValuesOf(src); if (left != 0) { JListRLoc* right = GetNetworkValuesOf(tgt); if (right != 0) { if (left->GetNoOfComponents() > 0 && right->GetNoOfComponents() > 0) { int i = 0; while (i < left->GetNoOfComponents()) { left->Get(i,src); int j = 0; while (j < right->GetNoOfComponents()) { right->Get(j,tgt); if (src.IsOnSameRoute(tgt)) { left->Destroy(); left->DeleteIfAllowed(); right->Destroy(); right->DeleteIfAllowed(); return true; } j++; } i++; } } right->Destroy(); right->DeleteIfAllowed(); } left->Destroy(); left->DeleteIfAllowed(); } return false; } } /* 1.1.1 GetRLocOfPosOnRouteInterval */ RouteLocation* JNetwork::GetRLocOfPosOnRouteInterval( const JRouteInterval* actInt, const double pos) const { if (actInt != 0) { Direction compD(Down); if (actInt->GetSide().Compare(compD) != 0) return new RouteLocation(actInt->GetRouteId(), actInt->GetFirstPosition() + pos, actInt->GetSide()); else return new RouteLocation(actInt->GetRouteId(), actInt->GetLastPosition() - pos, actInt->GetSide()); } else return 0; } /* 1.1.1 Split Junit */ void JNetwork::SplitJUnit(const JUnit& ju, JRouteInterval*& lastRint, SimpleLine*& lastRouteCurve, bool& endTimeCorrected, Instant& lastEndTime, Point*& lastEndPoint, LRS& lrs, int& lrspos, temporalalgebra::MPoint& result) const { if (ju.IsDefined()) { JRouteInterval jurint = ju.GetRouteInterval(); temporalalgebra::Interval jutime = ju.GetTimeInterval(); Instant instInter1 = jutime.start; Instant instInter2 = jutime.end; Direction compD(Down); if (lrspos < 0 || jutime.start > lastEndTime) { lastEndPoint->DeleteIfAllowed(); lastEndPoint = 0; } const Instant TIMECORRECTION(0,1, durationtype); if (endTimeCorrected) { endTimeCorrected = false; if (instInter1 < lastEndTime) instInter1 = lastEndTime; if (instInter1 >= instInter2) { endTimeCorrected = true; instInter2 = instInter1 + TIMECORRECTION; } } if (lastEndPoint == 0) { lastEndPoint = GetSpatialValueOf(jurint.GetStartLocation(), lastRint, lastRouteCurve, lrs, lrspos); } if (AlmostEqual(jurint.GetLength(), 0.0)) { checkEndTimeCorrected (endTimeCorrected, instInter1, instInter2, TIMECORRECTION); result.Add(temporalalgebra::UPoint( temporalalgebra::Interval(instInter1, instInter2, jutime.lc, jutime.rc), *lastEndPoint, *lastEndPoint)); lastEndTime = instInter2; } else { if(jurint.GetRouteId() != lastRint->GetRouteId()){ // route changed -> update values if (lastEndPoint != 0) lastEndPoint->DeleteIfAllowed(); lastEndPoint = GetSpatialValueOf(jurint.GetStartLocation(), lastRint, lastRouteCurve, lrs, lrspos); } addUnitsToResult(ju, lastRouteCurve, tolerance, lrs, lrspos, endTimeCorrected, instInter1, instInter2, TIMECORRECTION, lastEndPoint, lastEndTime, result); } } } bool JNetwork::CheckTupleForRLoc(const Tuple* actSect, const RouteLocation& rloc, double& pos) const { if (actSect != 0) { JRouteInterval* actInt = GetSectionRouteIntervalForRLoc(rloc, actSect); if (actInt != 0) { if (actInt->Contains(rloc, tolerance)) { pos = correctedPos(fabs(rloc.GetPosition() - actInt->GetFirstPosition()), actInt->GetLength(), tolerance); actInt->DeleteIfAllowed(); return true; } actInt->DeleteIfAllowed(); } } return false; } /* 1.1.1. ConnectSpatialPositions */ void JNetwork::ConnectSpatialPositions(const DbArray* targets, DbArray* tgtEntries, const bool start, Points* spatialPositions /*=0*/) { if (targets != NULL && tgtEntries != NULL && targets->Size() > 0) { tgtEntries->clean(); if (spatialPositions != 0) { spatialPositions->Clear(); spatialPositions->StartBulkLoad(); } RouteLocation rloc; for (int i = 0; i < targets->Size(); i ++) { targets->Get(i, rloc); double distFromStart; Tuple* sectTup = GetSectionTupleFor(rloc, distFromStart); if (sectTup != NULL) { Point* p = GetSpatialValueOf(rloc, distFromStart, sectTup); Direction* sectDir = GetSectionDirection(sectTup); if (sectDir != NULL) { if (p != NULL) { switch(sectDir->GetDirection()) { case Up: { if (spatialPositions != 0) spatialPositions->operator+=(*p); if (start) { if (AlmostEqualAbsolute(distFromStart, 0.0, tolerance)) { tgtEntries->Append(PosJNetSpatial(rloc, p, GetSectionId(sectTup), GetSectionStartJunctionID(sectTup), 0.0, GetSectionEndJunctionID(sectTup), GetSectionLength(sectTup))); } else { tgtEntries->Append(PosJNetSpatial(rloc, p, GetSectionId(sectTup), -1, -1000.0, GetSectionEndJunctionID(sectTup), GetSectionLength(sectTup)- distFromStart)); } } else { if (AlmostEqualAbsolute(GetSectionLength(sectTup), distFromStart, tolerance)) { tgtEntries->Append(PosJNetSpatial(rloc, p, GetSectionId(sectTup), GetSectionStartJunctionID(sectTup), GetSectionLength(sectTup), GetSectionEndJunctionID(sectTup), 0.0)); } else { tgtEntries->Append(PosJNetSpatial(rloc, p, GetSectionId(sectTup), GetSectionStartJunctionID(sectTup), distFromStart, -1, -1000.0)); } } break; } case Down: { if (spatialPositions != 0) spatialPositions->operator+=(*p); if (start) { if (AlmostEqualAbsolute(distFromStart, GetSectionLength(sectTup), tolerance)) { tgtEntries->Append(PosJNetSpatial(rloc, p, GetSectionId(sectTup), GetSectionStartJunctionID(sectTup), distFromStart, GetSectionEndJunctionID(sectTup), 0.0)); } else { tgtEntries->Append(PosJNetSpatial(rloc, p, GetSectionId(sectTup), GetSectionStartJunctionID(sectTup), distFromStart, -1,-1000.0)); } } else { if (AlmostEqualAbsolute(distFromStart, 0.0, tolerance)) { tgtEntries->Append(PosJNetSpatial(rloc, p, GetSectionId(sectTup), GetSectionStartJunctionID(sectTup), 0.0, GetSectionEndJunctionID(sectTup), GetSectionLength(sectTup))); } else { tgtEntries->Append(PosJNetSpatial(rloc, p, GetSectionId(sectTup), -1,-1000.0, GetSectionEndJunctionID(sectTup), GetSectionLength(sectTup) - distFromStart)); } } break; } case Both: { if (spatialPositions != 0) spatialPositions->operator+=(*p); tgtEntries->Append(PosJNetSpatial(rloc, p, GetSectionId(sectTup), GetSectionStartJunctionID(sectTup), distFromStart, GetSectionEndJunctionID(sectTup), GetSectionLength(sectTup) - distFromStart)); break; } default: { break; } } p->DeleteIfAllowed(); p = 0; } sectDir->DeleteIfAllowed(); sectDir = 0; } sectTup->DeleteIfAllowed(); sectTup = 0; } } if (spatialPositions != NULL) spatialPositions->EndBulkLoad(); } } /* 1.1.1 InitPriorityQueue */ bool JNetwork::InitPriorityQueue(PQManagement* pqueue, const DbArray* sources, const Points* endPositions) { if (pqueue != NULL && sources != NULL && endPositions != NULL && sources->Size() > 0 && endPositions->Size() > 0) { PosJNetSpatial curSource; Tuple *juncTup = 0; JListInt* adjSectList = 0; Direction compD(Down); int jid = -1; for (int i = 0; i < sources->Size(); i++) { sources->Get(i, curSource); if (AlmostEqual(curSource.GetDistFromStartJunction(), 0.0) || AlmostEqual(curSource.GetDistFromEndJunction(), 0.0)) { jid = -1; if (AlmostEqual(curSource.GetDistFromStartJunction(), 0.0)) { jid = curSource.GetStartJID(); juncTup = GetJunctionTupleWithId(jid); } else { jid = curSource.GetEndJID(); juncTup = GetJunctionTupleWithId(jid); } if (juncTup != NULL) { adjSectList = GetJunctionOutSectionList(juncTup); if (adjSectList != NULL) { JPQEntry tmp(curSource.GetNetworkPos().GetSide(), -1, jid, jid, -1, jid, jid, 0.0, endPositions->Distance(curSource.GetSpatialPos()), 0.0); pqueue->InsertJunctionAsVisited(tmp); AddAdjacentSections(pqueue, adjSectList, tmp, endPositions); adjSectList->Destroy(); adjSectList->DeleteIfAllowed(); } juncTup->DeleteIfAllowed(); } } else { Tuple* sectTup = GetSectionTupleWithId(curSource.GetSectionId()); if (sectTup != 0) { Direction* sectDir = GetSectionDirection(sectTup); if (sectDir != NULL) { int test = sectDir->Compare(compD); if (test != 0) { jid = curSource.GetEndJID(); juncTup = GetJunctionTupleWithId(jid); if (juncTup != 0) { Point* curJuncPoint = GetJunctionSpatialPos(juncTup); if (curJuncPoint != 0) { adjSectList = GetSectionListAdjSectionsUp(sectTup); JPQEntry tmp1((Direction) Up, -1, jid, jid, -1, jid, jid, curSource.GetDistFromEndJunction(), curSource.GetDistFromEndJunction() + endPositions->Distance(*curJuncPoint), curSource.GetDistFromEndJunction()); pqueue->InsertJunctionAsVisited(tmp1); AddAdjacentSections(pqueue, adjSectList, tmp1, endPositions); adjSectList->Destroy(); adjSectList->DeleteIfAllowed(); curJuncPoint->DeleteIfAllowed(); } juncTup->DeleteIfAllowed(); } } if (test >= 0) { jid = curSource.GetStartJID(); juncTup = GetJunctionTupleWithId(jid); if (juncTup != 0) { Point* curJuncPoint = GetJunctionSpatialPos(juncTup); if (curJuncPoint != 0) { adjSectList = GetSectionListAdjSectionsDown(sectTup); JPQEntry tmp2((Direction) Down, -1, jid, jid, -1, jid, jid, curSource.GetDistFromStartJunction(), curSource.GetDistFromStartJunction() + endPositions->Distance(*curJuncPoint), curSource.GetDistFromStartJunction()); pqueue->InsertJunctionAsVisited(tmp2); AddAdjacentSections(pqueue, adjSectList, tmp2, endPositions); adjSectList->Destroy(); adjSectList->DeleteIfAllowed(); curJuncPoint->DeleteIfAllowed(); } juncTup->DeleteIfAllowed(); } } sectDir->DeleteIfAllowed(); sectDir = 0; } sectTup->DeleteIfAllowed(); sectTup = 0; } } } return true; } else return false; } void JNetwork::InitPriorityQueue(PQManagement* pqueue, const RouteLocation& source, DbArray* result) { double distFromStart(0.0); Tuple* sectTup = GetSectionTupleFor(source, distFromStart); if (sectTup != NULL) { int endJuncId = GetSectionEndJunctionID(sectTup); double distFromEnd = GetSectionLength(sectTup)- distFromStart; JPQEntry end((Direction) Up, -1, endJuncId, endJuncId, -1, endJuncId, endJuncId, distFromEnd, distFromEnd, distFromEnd); int startJuncId = GetSectionStartJunctionID(sectTup); JPQEntry start((Direction) Down, -1, startJuncId, startJuncId, -1, startJuncId, startJuncId, distFromStart, distFromStart, distFromStart); Direction* sectDir = GetSectionDirection(sectTup); if (sectDir != NULL) { if (AlmostEqualAbsolute(distFromStart, 0.0, tolerance) || AlmostEqualAbsolute(distFromStart, GetSectionLength(sectTup), tolerance)) { if (AlmostEqualAbsolute(distFromStart, 0.0, tolerance)) WriteToLists(pqueue, result, start); else WriteToLists(pqueue, result, end); } else { Direction compD(Down); switch(sectDir->Compare(compD)) { case -1: //sectDir up { WriteToLists(pqueue, result, end); break; } case 0: //sectDir down { WriteToLists(pqueue, result, start); break; } case 1: //sectDir both { WriteToLists(pqueue, result, start, end, sectTup); break; } default: //should never been reached { assert(false); break; } } } sectDir->DeleteIfAllowed(); sectDir = 0; } sectTup->DeleteIfAllowed(); sectTup = 0; } } void JNetwork::InitPriorityQueue(PQManagement* pqueue, const jnetwork::RouteLocation& source, const double distLimit, JLine* result) { double distFromStart(0.0); Tuple* sectTup = GetSectionTupleFor(source, distFromStart); if (sectTup != NULL) { int endJuncId = GetSectionEndJunctionID(sectTup); double distFromEnd = GetSectionLength(sectTup)- distFromStart; JPQEntry end((Direction) Up, -1, endJuncId, endJuncId, -1, endJuncId, endJuncId, distFromEnd, distFromEnd, distFromEnd); int startJuncId = GetSectionStartJunctionID(sectTup); JPQEntry start((Direction) Down, -1, startJuncId, startJuncId, -1, startJuncId, startJuncId, distFromStart, distFromStart, distFromStart); Direction* sectDir = GetSectionDirection(sectTup); if (sectDir != NULL) { if (AlmostEqualAbsolute(distFromStart, 0.0, tolerance) || AlmostEqualAbsolute(distFromStart, GetSectionLength(sectTup), tolerance)) { if (AlmostEqualAbsolute(distFromStart, 0.0, tolerance)) WriteToLists(pqueue, result, start, distLimit, source, false, sectDir); else WriteToLists(pqueue, result, end, distLimit, source, true, sectDir); } else { Direction compD(Down); switch(sectDir->Compare(compD)) { case -1: //sectDir up { WriteToLists(pqueue, result, end, distLimit, source, true, sectDir); break; } case 0: //sectDir down { WriteToLists(pqueue, result, start, distLimit, source, false, sectDir); break; } case 1: //sectDir both { WriteToLists(pqueue, result, start, end, sectTup, distLimit, source, sectDir); break; } default: //should never been reached { assert(false); break; } } } sectDir->DeleteIfAllowed(); sectDir = 0; } sectTup->DeleteIfAllowed(); sectTup = 0; } } void JNetwork::InitReversePriorityQueue(PQManagement* pqueue, const RouteLocation& source, DbArray* result) { double distFromStart(0.0); Tuple* sectTup = GetSectionTupleFor(source, distFromStart); if (sectTup != NULL) { int endJuncId = GetSectionEndJunctionID(sectTup); double distFromEnd = GetSectionLength(sectTup)- distFromStart; JPQEntry end((Direction) Down, -1, endJuncId, endJuncId, -1, endJuncId, endJuncId, distFromEnd, distFromEnd, distFromEnd); int startJuncId = GetSectionStartJunctionID(sectTup); JPQEntry start((Direction) Up, -1, startJuncId, startJuncId, -1, startJuncId, startJuncId, distFromStart, distFromStart, distFromStart); Direction* sectDir = GetSectionDirection(sectTup); if (sectDir != NULL) { if (AlmostEqualAbsolute(distFromStart, 0.0, tolerance) || AlmostEqualAbsolute(distFromStart, GetSectionLength(sectTup), tolerance)) { if (AlmostEqualAbsolute(distFromStart, 0.0, tolerance)) WriteToReverseLists(pqueue, result, start); else WriteToReverseLists(pqueue, result, end); } else { Direction compD(Down); switch(sectDir->Compare(compD)) { case -1: //sectDir up { WriteToReverseLists(pqueue, result, start); break; } case 0: //sectDir down { WriteToReverseLists(pqueue, result, end); break; } case 1: //sectDir both { WriteToReverseLists(pqueue, result, start, end, sectTup); break; } default: //should never been reached { assert(false); break; } } } sectDir->DeleteIfAllowed(); sectDir = 0; } sectTup->DeleteIfAllowed(); sectTup = 0; } } void JNetwork::InitReversePriorityQueue(PQManagement* pqueue, const jnetwork::RouteLocation& source, const double distLimit, JLine* result) { double distFromStart(0.0); Tuple* sectTup = GetSectionTupleFor(source, distFromStart); if (sectTup != NULL) { int endJuncId = GetSectionEndJunctionID(sectTup); double distFromEnd = GetSectionLength(sectTup)- distFromStart; JPQEntry end((Direction) Down, -1, endJuncId, endJuncId, -1, endJuncId, endJuncId, distFromEnd, distFromEnd, distFromEnd); int startJuncId = GetSectionStartJunctionID(sectTup); JPQEntry start((Direction) Up, -1, startJuncId, startJuncId, -1, startJuncId, startJuncId, distFromStart, distFromStart, distFromStart); Direction* sectDir = GetSectionDirection(sectTup); if (sectDir != NULL) { if (AlmostEqualAbsolute(distFromStart, 0.0, tolerance) || AlmostEqualAbsolute(distFromStart, GetSectionLength(sectTup), tolerance)) { if (AlmostEqualAbsolute(distFromStart, 0.0, tolerance)) WriteToReverseLists(pqueue, result, start, distLimit, source, true, sectDir); else WriteToReverseLists(pqueue, result, end, distLimit, source, false, sectDir); } else { Direction compD(Down); switch(sectDir->Compare(compD)) { case -1: //sectDir up { WriteToReverseLists(pqueue, result, start, distLimit, source, true, sectDir); break; } case 0: //sectDir down { WriteToReverseLists(pqueue, result, end, distLimit, source, false, sectDir); break; } case 1: //sectDir both { WriteToReverseLists(pqueue, result, start, end, sectTup, distLimit, source, sectDir); break; } default: //should never been reached { assert(false); break; } } } sectDir->DeleteIfAllowed(); sectDir = 0; } sectTup->DeleteIfAllowed(); sectTup = 0; } } bool JNetwork::CheckForSameSections(const DbArray< PosJNetSpatial >* sources, const DbArray< PosJNetSpatial >* targets, DbArray< JRouteInterval >*& sp) { if (sources != NULL && targets != NULL && sources->Size() > 0 && targets->Size() > 0) { JRouteInterval* jri = 0; JRouteInterval* tmp = 0; PosJNetSpatial src, tgt; for (int i = 0; i < sources->Size(); i++) { sources->Get(i, src); for (int j = 0; j < targets->Size(); j++) { targets->Get(j,tgt); if (src.GetSectionId() == tgt.GetSectionId()) { RouteLocation sour = src.GetNetworkPos(); RouteLocation targ = tgt.GetNetworkPos(); if (ExistsCommonRoute(sour, targ)) { tmp = DirectConnection(src.GetSectionId(), sour, targ); if (jri != NULL) { if (jri->GetLength() > tmp->GetLength()) { jri->DeleteIfAllowed(); jri = new JRouteInterval(*tmp); } } else { jri = new JRouteInterval(*tmp); } tmp->DeleteIfAllowed(); } } } } if (jri != NULL) { sp = new DbArray(0); if (jri->GetLength() > 0.0) sp->Append(*jri); jri->DeleteIfAllowed(); } } return (sp != NULL); } /* Process Priority Queue */ bool JNetwork::ProcessPriorityQueue(PQManagement* pqueue, const DbArray< PosJNetSpatial >* targets, const Points* spatialPosTargets, int& tgtPosInArray, bool& tgtIsStartJunction, int& srcStartPathJID, double& minDist) { bool found = false; JPQEntry* curPQElement = 0; DbArray* wayEntries = new DbArray(0); double lastPrio = numeric_limits::min(); while(!found && !pqueue->IsEmpty()) { curPQElement = pqueue->GetAndDeleteMin(); if(lastPrio > curPQElement->GetPriority()) { cerr << "error in processing, priority found that " << "is smaller than the last one" << endl; cerr << "priorities in queue " << endl; while(curPQElement){ cout << curPQElement->GetPriority() << endl; delete curPQElement; curPQElement = pqueue->GetAndDeleteMin(); } assert(false); } lastPrio = curPQElement->GetPriority(); if (minDist >= curPQElement->GetPriority()) { InsertNetdistanceTuple(curPQElement->GetStartPathJID(), curPQElement, wayEntries); double distLastJuncEndPoint = -1.0; if (reachedEndpoint(curPQElement, targets, distLastJuncEndPoint, tgtPosInArray, tgtIsStartJunction, srcStartPathJID)) { found = true; minDist = curPQElement->GetDistFromStartPoint()+ distLastJuncEndPoint; //check for shorter other end bool testOther = false; JPQEntry* test = 0; while(!testOther && !pqueue->IsEmpty()) { test = pqueue->GetAndDeleteMin(); if (test->GetPriority() < minDist) { double testDistLastJuncEndPoint = -1.0; int testPosInArray = -1; bool testIsStartJunction = false; int testSrcStartPathJID = -1; if (reachedEndpoint(test, targets, testDistLastJuncEndPoint, testPosInArray, testIsStartJunction, testSrcStartPathJID)) { if (minDist > test->GetDistFromStartPoint() + testDistLastJuncEndPoint) { if (curPQElement != 0) delete curPQElement; curPQElement = test; minDist = test->GetDistFromStartPoint() + testDistLastJuncEndPoint; tgtPosInArray = testPosInArray; tgtIsStartJunction = testIsStartJunction; srcStartPathJID = testSrcStartPathJID; } } else AddAdjacentSections(pqueue, *test, spatialPosTargets); } else testOther = true; if (test != NULL) { if (test != curPQElement) delete test; test = 0; } } } else AddAdjacentSections(pqueue, *curPQElement, spatialPosTargets); } else found = true; if (curPQElement != NULL) delete curPQElement; curPQElement = 0; } wayEntries->Destroy(); delete wayEntries; return found; } void JNetwork::ProcessPriorityQueue(PQManagement* pqueue, DbArray* result, const double distLimit) { JPQEntry* curPQElement = 0; DbArray* wayEntries = new DbArray(0); double lastDist = numeric_limits::min(); while(!pqueue->IsEmpty() && lastDist <= distLimit) { curPQElement = pqueue->GetAndDeleteMin(); lastDist = curPQElement->GetDistFromStartPoint(); if(curPQElement != NULL) { PairIntDouble curPair(curPQElement->GetEndPartJID(), curPQElement->GetDistFromStartPoint()); result->Append(curPair); InsertNetdistanceTuple(curPQElement->GetStartPathJID(), curPQElement, wayEntries); AddAdjacentSections(pqueue, *curPQElement, 0); delete curPQElement; curPQElement = 0; } } wayEntries->Destroy(); delete wayEntries; } void JNetwork::ProcessPriorityQueue(PQManagement* pqueue, const double distLimit, JLine* result) { JPQEntry* curPQElement = 0; double lastDist = numeric_limits::min(); while(!pqueue->IsEmpty() && lastDist <= distLimit) { curPQElement = pqueue->GetAndDeleteMin(); lastDist = curPQElement->GetDistFromStartPoint(); if(curPQElement != NULL) { AddAdjacentSections(pqueue, *curPQElement, result, distLimit); delete curPQElement; curPQElement = 0; } } } void JNetwork::ProcessReversePriorityQueue(PQManagement* pqueue, DbArray* result, const double distLimit) { JPQEntry* curPQElement = 0; double lastDist = numeric_limits::min(); while(!pqueue->IsEmpty() && lastDist <= distLimit) { curPQElement = pqueue->GetAndDeleteMin(); lastDist = curPQElement->GetDistFromStartPoint(); if(curPQElement != NULL) { PairIntDouble curPair(curPQElement->GetEndPartJID(), curPQElement->GetDistFromStartPoint()); result->Append(curPair); AddReverseAdjacentSections(pqueue, *curPQElement); delete curPQElement; curPQElement = 0; } } } void JNetwork::ProcessReversePriorityQueue(PQManagement* pqueue, const double distLimit, JLine* result) { JPQEntry* curPQElement = 0; double lastDist = numeric_limits::min(); while(!pqueue->IsEmpty() && lastDist <= distLimit) { curPQElement = pqueue->GetAndDeleteMin(); lastDist = curPQElement->GetDistFromStartPoint(); if(curPQElement != NULL) { AddReverseAdjacentSections(pqueue, *curPQElement, result, distLimit); delete curPQElement; curPQElement = 0; } } } bool JNetwork::CheckForExistingNetdistance( const DbArray< PosJNetSpatial >* srcEntries, const DbArray< PosJNetSpatial >* tgtEntries, int& srcStartPathJID, int& tgtPosInArray, bool& tgtOverStartJunction, double& minDist) { bool result = false; if (srcEntries != NULL && tgtEntries != NULL && srcEntries->Size() > 0 && tgtEntries->Size() > 0) { PosJNetSpatial start, end; double tmpMinDist = minDist; int tmpSrcStartPathJID = srcStartPathJID; bool tmpTgtOverStartJunction = tgtOverStartJunction; for (int i = 0; i < srcEntries->Size(); i++) { srcEntries->Get(i,start); for (int j = 0; j < tgtEntries->Size(); j++) { tgtEntries->Get(j,end); if (ExistsNetdistancesFor(start, end, tmpMinDist, tmpSrcStartPathJID, tmpTgtOverStartJunction)) { result = true; if (tmpMinDist < minDist) { minDist = tmpMinDist; srcStartPathJID = tmpSrcStartPathJID; tgtPosInArray = j; tgtOverStartJunction = tmpTgtOverStartJunction; } } } } } return result; } bool JNetwork::ExistsNetdistancesFor(const PosJNetSpatial& start, const PosJNetSpatial& end, double& minDist, int& srcStartPathJID, bool& tgtOverStartJunction) { bool result = false; bool tmp = false; if (start.GetStartJID() > -1) { if (end.GetStartJID() > -1) { tmp = ExistsNetdistanceFor(start.GetStartJID(), start.GetDistFromStartJunction(), end.GetStartJID(), end.GetDistFromStartJunction(), true, minDist, srcStartPathJID, tgtOverStartJunction); result = result || tmp; } if (end.GetEndJID() > -1) { tmp = ExistsNetdistanceFor(start.GetStartJID(), start.GetDistFromStartJunction(), end.GetEndJID(), end.GetDistFromEndJunction(), false, minDist, srcStartPathJID, tgtOverStartJunction); result = result || tmp; } } if (start.GetEndJID() > -1) { if (end.GetStartJID() > -1) { tmp = ExistsNetdistanceFor(start.GetEndJID(), start.GetDistFromEndJunction(), end.GetStartJID(), end.GetDistFromStartJunction(), true, minDist, srcStartPathJID, tgtOverStartJunction); result = result || tmp; } if (end.GetEndJID() > -1) { tmp = ExistsNetdistanceFor(start.GetEndJID(), start.GetDistFromEndJunction(), end.GetEndJID(), end.GetDistFromEndJunction(), false, minDist, srcStartPathJID, tgtOverStartJunction); result = result || tmp; } } return result; } bool JNetwork::ExistsNetdistanceFor(const int startjid, const double startdist, const int endjid, const double enddist, const bool endJIDisStartJunc, double& minDist, int& srcStartPathJID, bool& tgtOverStartJunction) { Tuple* netDistTup = GetNetdistanceTupleFor(startjid, endjid); if (netDistTup != 0) { double netDist = GetNetdistanceDistance(netDistTup); double tmpMinDist = startdist + netDist + enddist; if (tmpMinDist < minDist) { minDist = tmpMinDist; srcStartPathJID = startjid; tgtOverStartJunction = endJIDisStartJunc; } netDistTup->DeleteIfAllowed(); netDistTup = 0; return true; } else return false; } /* 1.1.1.1 Helpful Functions for Priority Queue Initialization */ void JNetwork::WriteToLists(PQManagement* pqueue, DbArray* result, JPQEntry& junc) { PairIntDouble curPair(junc.GetEndPartJID(), junc.GetDistFromStartPoint()); result->Append(curPair); WriteToLists(pqueue, junc); } void JNetwork::WriteToLists(PQManagement* pqueue, JLine* result, JPQEntry& junc, const double distLimit, const RouteLocation& src, const bool up, const Direction* sectDir) { JRouteInterval tmp(false); Direction compD(Down); int test = sectDir->Compare(compD); double distcorrection = distLimit; if (distLimit >= junc.GetDistStartToStartJID()) { distcorrection = junc.GetDistStartToStartJID(); } if (up) { if (test < 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition(), src.GetPosition() + distcorrection, (Direction) Up); } else if (test > 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition(), src.GetPosition() + distcorrection, (Direction) Both); } } else { if (test == 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition()- distcorrection, src.GetPosition(), (Direction) Down); } else if (test > 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition()- distcorrection, src.GetPosition(), (Direction) Both); } } if (tmp.IsDefined() && tmp.GetLength() > 0.0) result->Add(tmp); pqueue->InsertJunctionAsVisited(junc); Tuple* juncTup = GetJunctionTupleWithId(junc.GetEndPartJID()); if (juncTup != NULL) { JListInt* adjSect = GetJunctionOutSectionList(juncTup); if (adjSect != NULL) { AddAdjacentSections(pqueue, adjSect, junc, result, distLimit); adjSect->Destroy(); adjSect->DeleteIfAllowed(); } juncTup->DeleteIfAllowed(); } } void JNetwork::WriteToLists(PQManagement* pqueue, JPQEntry& junc) { pqueue->InsertJunctionAsVisited(junc); Tuple* juncTup = GetJunctionTupleWithId(junc.GetEndPartJID()); if (juncTup != NULL) { JListInt* adjSect = GetJunctionOutSectionList(juncTup); if (adjSect != NULL) { AddAdjacentSections(pqueue, adjSect, junc, 0); adjSect->Destroy(); adjSect->DeleteIfAllowed(); } juncTup->DeleteIfAllowed(); } } void JNetwork::WriteToLists(PQManagement* pqueue, DbArray* result, JPQEntry& start, JPQEntry& end, const Tuple* sectTup) { PairIntDouble startPair(start.GetEndPartJID(), start.GetDistFromStartPoint()); result->Append(startPair); PairIntDouble endPair(end.GetEndPartJID(), end.GetDistFromStartPoint()); result->Append(endPair); WriteToLists(pqueue, start, end, sectTup); } void JNetwork::WriteToLists(PQManagement* pqueue, JLine* result, JPQEntry& start, JPQEntry& end, const Tuple* sectTup, const double distLimit, const jnetwork::RouteLocation& src, const Direction* sectDir) { JRouteInterval tmp(false); Direction compD(Down); int test = sectDir->Compare(compD); double distcorrection = distLimit; if (distLimit >= start.GetDistStartToStartJID()) { distcorrection = start.GetDistStartToStartJID(); } if (test == 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition(), src.GetPosition() - distcorrection, (Direction) Down); } else if (test > 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition(), src.GetPosition() - distcorrection, (Direction) Both); } if (tmp.IsDefined() && tmp.GetLength() > 0.0) { result->Add(tmp); tmp.SetDefined(false); } distcorrection = distLimit; if (distLimit >= end.GetDistStartToStartJID()) { distcorrection = end.GetDistStartToStartJID(); } if (test < 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition(), src.GetPosition() + distcorrection, (Direction) Up); } else if (test == 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition(), src.GetPosition() + distcorrection, (Direction) Both); } if (tmp.IsDefined() && tmp.GetLength() > 0.0) { result->Add(tmp); } pqueue->InsertJunctionAsVisited(start); pqueue->InsertJunctionAsVisited(end); if (sectTup != 0) { JListInt* adjSect = GetSectionListAdjSectionsUp(sectTup); if (adjSect != NULL) { AddAdjacentSections(pqueue, adjSect, end, result, distLimit); adjSect->Destroy(); adjSect->DeleteIfAllowed(); adjSect = 0; } adjSect = GetSectionListAdjSectionsDown(sectTup); if (adjSect != NULL) { AddAdjacentSections(pqueue, adjSect, start, result, distLimit); adjSect->Destroy(); adjSect->DeleteIfAllowed(); adjSect = 0; } } } void JNetwork::WriteToLists(PQManagement* pqueue, JPQEntry& start, JPQEntry& end, const Tuple* sectTup) { pqueue->InsertJunctionAsVisited(start); pqueue->InsertJunctionAsVisited(end); if (sectTup != 0) { JListInt* adjSect = GetSectionListAdjSectionsUp(sectTup); if (adjSect != NULL) { AddAdjacentSections(pqueue, adjSect, end, 0); adjSect->Destroy(); adjSect->DeleteIfAllowed(); adjSect = 0; } adjSect = GetSectionListAdjSectionsDown(sectTup); if (adjSect != NULL) { AddAdjacentSections(pqueue, adjSect, start, 0); adjSect->Destroy(); adjSect->DeleteIfAllowed(); adjSect = 0; } } } void JNetwork::WriteToReverseLists(PQManagement* pqueue, DbArray* result, JPQEntry& junc) { PairIntDouble curPair(junc.GetEndPartJID(), junc.GetDistFromStartPoint()); result->Append(curPair); WriteToReverseLists(pqueue, junc); } void JNetwork::WriteToReverseLists(PQManagement* pqueue, JLine* result, JPQEntry& junc, const double distLimit, const jnetwork::RouteLocation& src, const bool up, const Direction* sectDir) { JRouteInterval tmp(false); Direction compD(Down); int test = sectDir->Compare(compD); double distcorrection = distLimit; if (distLimit >= junc.GetDistStartToStartJID()) { distcorrection = junc.GetDistStartToStartJID(); } if (up) { if (test < 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition()- distcorrection, src.GetPosition(), (Direction) Up); } else if (test > 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition()- distcorrection, src.GetPosition(), (Direction) Both); } } else { if (test == 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition(), src.GetPosition() + distcorrection, (Direction) Down); } else if ( test > 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition(), src.GetPosition() + distcorrection, (Direction) Both); } } if (tmp.IsDefined() && tmp.GetLength() > 0.0) result->Add(tmp); pqueue->InsertJunctionAsVisited(junc); Tuple* juncTup = GetJunctionTupleWithId(junc.GetEndPartJID()); if (juncTup != NULL) { JListInt* adjSect = GetJunctionInSectionList(juncTup); if (adjSect != NULL) { AddReverseAdjacentSections(pqueue, adjSect, junc, result, distLimit); adjSect->Destroy(); adjSect->DeleteIfAllowed(); } juncTup->DeleteIfAllowed(); } } void JNetwork::WriteToReverseLists(PQManagement* pqueue, JPQEntry& junc) { pqueue->InsertJunctionAsVisited(junc); Tuple* juncTup = GetJunctionTupleWithId(junc.GetEndPartJID()); if (juncTup != NULL) { JListInt* adjSect = GetJunctionInSectionList(juncTup); if (adjSect != NULL) { AddReverseAdjacentSections(pqueue, adjSect, junc); adjSect->Destroy(); adjSect->DeleteIfAllowed(); } juncTup->DeleteIfAllowed(); } } void JNetwork::WriteToReverseLists(PQManagement* pqueue, DbArray* result, JPQEntry& start, JPQEntry& end, const Tuple* sectTup) { PairIntDouble startPair(start.GetEndPartJID(), start.GetDistFromStartPoint()); result->Append(startPair); PairIntDouble endPair(end.GetEndPartJID(), end.GetDistFromStartPoint()); result->Append(endPair); WriteToReverseLists(pqueue, start, end, sectTup); } void JNetwork::WriteToReverseLists(PQManagement* pqueue, JLine* result, JPQEntry& start, JPQEntry& end, const Tuple* sectTup, const double distLimit, const jnetwork::RouteLocation& src, const Direction* sectDir) { JRouteInterval tmp(false); Direction compD(Down); int test = sectDir->Compare(compD); double distCorrection = distLimit; if (distLimit >= start.GetDistStartToStartJID()) { distCorrection = start.GetDistStartToStartJID(); } if (test < 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition() - distCorrection, src.GetPosition(), (Direction) Up); } else if (test > 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition() - distCorrection, src.GetPosition(), (Direction) Both); } if (tmp.IsDefined() && tmp.GetLength() > 0.0) { result->Add(tmp); tmp.SetDefined(false); } distCorrection = distLimit; if (distLimit >= end.GetDistStartToStartJID()) { distCorrection = end.GetDistStartToStartJID(); } if (test == 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition(), src.GetPosition() + distCorrection, (Direction) Down); } else if (test > 0) { tmp = JRouteInterval(src.GetRouteId(), src.GetPosition(), src.GetPosition() + distCorrection, (Direction) Both); } if (tmp.IsDefined() && tmp.GetLength() > 0.0) result->Add(tmp); pqueue->InsertJunctionAsVisited(start); pqueue->InsertJunctionAsVisited(end); if (sectTup != 0) { JListInt* adjSect = GetSectionListReverseAdjSectionsUp(sectTup); if (adjSect != NULL) { AddReverseAdjacentSections(pqueue, adjSect, start, result, distLimit); adjSect->Destroy(); adjSect->DeleteIfAllowed(); adjSect = 0; } adjSect = GetSectionListReverseAdjSectionsDown(sectTup); if (adjSect != NULL) { AddReverseAdjacentSections(pqueue, adjSect, end, result, distLimit); adjSect->Destroy(); adjSect->DeleteIfAllowed(); adjSect = 0; } } } void JNetwork::WriteToReverseLists(PQManagement* pqueue, JPQEntry& start, JPQEntry& end, const Tuple* sectTup) { pqueue->InsertJunctionAsVisited(start); pqueue->InsertJunctionAsVisited(end); if (sectTup != 0) { JListInt* adjSect = GetSectionListReverseAdjSectionsUp(sectTup); if (adjSect != NULL) { AddReverseAdjacentSections(pqueue, adjSect, start); adjSect->Destroy(); adjSect->DeleteIfAllowed(); adjSect = 0; } adjSect = GetSectionListReverseAdjSectionsDown(sectTup); if (adjSect != NULL) { AddReverseAdjacentSections(pqueue, adjSect, end); adjSect->Destroy(); adjSect->DeleteIfAllowed(); adjSect = 0; } } } /* 1 Overwrite output operator */ ostream& operator<< (ostream& os, const JNetwork& n) { n.Print(os); return os; }