3736 lines
85 KiB
C++
3736 lines
85 KiB
C++
/*
|
|
This file is part of SECONDO.
|
|
|
|
Copyright (C) 2004, University in Hagen, Department of Computer Science,
|
|
Database Systems for New Applications.
|
|
|
|
SECONDO is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
SECONDO is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with SECONDO; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
/*
|
|
//paragraph [1] Title: [{\Large \bf \begin{center}] [\end{center}}]
|
|
//paragraph [10] Footnote: [{\footnote{] [}}]
|
|
|
|
1.1 Declarations and Inclusions Necessary for Algebra Network
|
|
|
|
*/
|
|
#ifndef __NETWORK_ALGEBRA_H__
|
|
#define __NETWORK_ALGEBRA_H__
|
|
|
|
#include "NestedList.h"
|
|
#include "../TupleIdentifier/TupleIdentifier.h"
|
|
#include "../Relation-C++/RelationAlgebra.h"
|
|
#include "../BTree/BTreeAlgebra.h"
|
|
#include "../../Tools/Flob/DbArray.h"
|
|
#include "../../Tools/Flob/Flob.h"
|
|
#include "Attribute.h"
|
|
#include "../Spatial/SpatialAlgebra.h"
|
|
#include "../RTree/RTreeAlgebra.h"
|
|
#include "ListUtils.h"
|
|
|
|
namespace network{
|
|
|
|
/*
|
|
2 Helpful Data Types and Data Structures
|
|
|
|
2.1 ~SectionValue ~
|
|
For some operations in connection with paths we need lists containing
|
|
sections ids and corresponding directions, e.g. in a list of adjacent sections.
|
|
The data type ~SectionValue~ is defined to be used in this lists.
|
|
|
|
*/
|
|
|
|
class SectionValue
|
|
{
|
|
public:
|
|
SectionValue(){};
|
|
|
|
SectionValue(const int sid, const bool up): sectId(sid), upDown(up){};
|
|
|
|
~SectionValue(){};
|
|
|
|
inline int GetSectionID() const
|
|
{
|
|
return sectId;
|
|
}
|
|
|
|
inline bool GetUpDownFlag() const
|
|
{
|
|
return upDown;
|
|
}
|
|
|
|
inline void SetSectionID(const int sid)
|
|
{
|
|
sectId = sid;
|
|
}
|
|
|
|
inline void SetUpDownFlag(const bool up)
|
|
{
|
|
upDown = up;
|
|
}
|
|
|
|
std::ostream& Print(std::ostream& os) const
|
|
{
|
|
os << "SectId: " << sectId << ", Direction: ";
|
|
if (upDown) os << "up";
|
|
else os << "down";
|
|
os << endl;
|
|
return os;
|
|
}
|
|
|
|
int Compare(const SectionValue sv) const
|
|
{
|
|
if (sectId < sv.GetSectionID()) return -1;
|
|
if (sectId > sv.GetSectionID()) return 1;
|
|
if (upDown == sv.GetUpDownFlag()) return 0;
|
|
if (upDown < sv.GetUpDownFlag()) return -1;
|
|
return 1;
|
|
}
|
|
|
|
void operator=(const SectionValue sv)
|
|
{
|
|
sectId = sv.GetSectionID();
|
|
upDown = sv.GetUpDownFlag();
|
|
}
|
|
|
|
private:
|
|
|
|
int sectId;
|
|
bool upDown;
|
|
|
|
};
|
|
|
|
/*
|
|
2.2 ~Entry~
|
|
Extends a arbirtray class object by two int values used as pointers to the
|
|
index of the left respectively right son, to use them as nodes in a tree
|
|
data structure which is embedded in a DbArray to be not limited by available
|
|
main memory ressources.
|
|
|
|
The class Value must support Compare,Print and operator=.
|
|
|
|
*/
|
|
|
|
template <class Value>
|
|
class Entry
|
|
{
|
|
public:
|
|
Entry<Value>(){};
|
|
|
|
Entry<Value>(const Value val, const int left = -1, const int right = -1):
|
|
value(val), leftSonIndex(left), rightSonIndex(right) {};
|
|
|
|
~Entry(){};
|
|
|
|
inline Value GetValue() const {
|
|
return value;
|
|
};
|
|
|
|
inline int GetLeftSonIndex() const {
|
|
return leftSonIndex;
|
|
};
|
|
|
|
inline int GetRightSonIndex() const {
|
|
return rightSonIndex;
|
|
};
|
|
|
|
inline void SetValue(const Value v) {
|
|
value = v;
|
|
}
|
|
|
|
inline void SetLeftSonIndex(const int left) {
|
|
leftSonIndex = left;
|
|
};
|
|
|
|
inline void SetRightSonIndex(const int right) {
|
|
rightSonIndex = right;
|
|
};
|
|
|
|
inline int Compare(const Entry ev) const {
|
|
return value.Compare(ev.GetValue());
|
|
};
|
|
|
|
inline int Compare (const Value v) const{
|
|
return value.Compare(v);
|
|
}
|
|
|
|
std::ostream& Print(std::ostream& os) const {
|
|
os << "EntryValue: ";
|
|
value.Print(os);
|
|
os << "LeftSon: " << leftSonIndex;
|
|
os << ", RigthSon: " << rightSonIndex << endl;
|
|
return os;
|
|
};
|
|
|
|
private:
|
|
|
|
Value value;
|
|
int leftSonIndex;
|
|
int rightSonIndex;
|
|
};
|
|
|
|
/*
|
|
2.3 ~SortedTree~
|
|
Uses a DbArray to store a sorted tree of ~TreeEntry~. The elements can be
|
|
searched, inserted and removed.
|
|
|
|
*/
|
|
|
|
template <class TreeEntry>
|
|
class SortedTree {
|
|
|
|
public:
|
|
|
|
SortedTree<TreeEntry>():tree(0) {
|
|
freePos = 0;
|
|
numOfElements = 0;
|
|
};
|
|
|
|
SortedTree<TreeEntry>(const int n): tree(n){
|
|
freePos = 0;
|
|
numOfElements = 0;
|
|
};
|
|
|
|
~SortedTree(){};
|
|
|
|
void Destroy(){
|
|
tree.Destroy();
|
|
};
|
|
|
|
std::ostream& Print(std::ostream& os) const
|
|
{
|
|
TreeEntry elem;
|
|
for (int i = 0; i < freePos; i++){
|
|
tree.Get(i,elem);
|
|
os << i << ".Element: ";
|
|
elem.Print(os);
|
|
os << endl;
|
|
}
|
|
return os;
|
|
}
|
|
|
|
/*
|
|
Returns the index of entry if entry is in the tree. Elsewhere the position
|
|
where entry would have to be inserted. If the tree is empty -1 is returned.
|
|
|
|
*/
|
|
int Find(const TreeEntry entry, const int pos, int& posFather) const{
|
|
assert((0 <= pos && pos < freePos) || (freePos == 0 && pos == 0));
|
|
if (isEmpty()) return -1;
|
|
TreeEntry actEntry;
|
|
tree.Get(pos,actEntry);
|
|
switch (actEntry.Compare(entry)){
|
|
case -1:{
|
|
if (actEntry.GetRightSonIndex() > -1){
|
|
posFather = pos;
|
|
return Find(entry, actEntry.GetRightSonIndex(), posFather);
|
|
} else {
|
|
posFather = -1;
|
|
return pos;
|
|
}
|
|
}
|
|
|
|
case 1:{
|
|
if (actEntry.GetLeftSonIndex() > -1){
|
|
posFather = pos;
|
|
return Find(entry, actEntry.GetLeftSonIndex(),posFather);
|
|
}
|
|
else{
|
|
posFather = -1;
|
|
return pos;
|
|
}
|
|
}
|
|
|
|
case 0: {
|
|
return pos;
|
|
}
|
|
|
|
default:{ //should never been reached
|
|
posFather = -1;
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
Inserts ~TreeEntry~ if it is not inserted before.
|
|
If te is already in the tree, the tree remains unchanged and false is returned.
|
|
|
|
*/
|
|
void Insert(const TreeEntry te) {
|
|
int posFather = -1;
|
|
int pos = Find(te,0,posFather);
|
|
if (pos < 0){
|
|
tree.Put(freePos, te);
|
|
freePos++;
|
|
numOfElements++;
|
|
} else {
|
|
TreeEntry test;
|
|
tree.Get(pos,test);
|
|
switch (test.Compare(te)){
|
|
case -1:{
|
|
tree.Put(freePos, te);
|
|
test.SetRightSonIndex(freePos);
|
|
tree.Put(pos,test);
|
|
freePos++;
|
|
numOfElements++;
|
|
break;
|
|
}
|
|
|
|
case 1: {
|
|
tree.Put(freePos, te);
|
|
test.SetLeftSonIndex(freePos);
|
|
tree.Put(pos,test);
|
|
freePos++;
|
|
numOfElements++;
|
|
break;
|
|
}
|
|
|
|
default:{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Removes te from the tree, if it is in there.
|
|
|
|
*/
|
|
|
|
void Remove(const TreeEntry te){
|
|
int posFather = -1;
|
|
int pos = Find(te,0,posFather);
|
|
if (pos >= 0){
|
|
TreeEntry test;
|
|
tree.Get(pos,test);
|
|
if (test.Compare(te) == 0){
|
|
if (pos > 0){
|
|
TreeEntry father;
|
|
tree.Get(posFather, father);
|
|
if (test.GetRightSonIndex() > 0 && test.GetLeftSonIndex() > 0) {
|
|
int newPos = test.GetRightSonIndex();
|
|
int newFatherPos = pos;
|
|
TreeEntry smallestBigger;
|
|
tree.Get(newPos,smallestBigger);
|
|
while (smallestBigger.GetLeftSonIndex() > 0){
|
|
newFatherPos = newPos;
|
|
newPos = smallestBigger.GetLeftSonIndex();
|
|
tree.Get(newPos, smallestBigger);
|
|
}
|
|
if (newFatherPos == pos){
|
|
if (father.GetRightSonIndex() == pos){
|
|
father.SetRightSonIndex(newPos);
|
|
} else {
|
|
father.SetLeftSonIndex(newPos);
|
|
}
|
|
smallestBigger.SetLeftSonIndex(test.GetLeftSonIndex());
|
|
tree.Put(newPos, smallestBigger);
|
|
} else {
|
|
TreeEntry newFather;
|
|
tree.Get(newFatherPos, newFather);
|
|
newFather.SetLeftSonIndex(smallestBigger.GetRightSonIndex());
|
|
tree.Put(newFatherPos,newFather);
|
|
if (father.GetRightSonIndex() == pos){
|
|
father.SetRightSonIndex(newPos);
|
|
} else {
|
|
father.SetLeftSonIndex(newPos);
|
|
}
|
|
smallestBigger.SetLeftSonIndex(test.GetLeftSonIndex());
|
|
smallestBigger.SetRightSonIndex(test.GetRightSonIndex());
|
|
tree.Put(newPos, smallestBigger);
|
|
}
|
|
} else {
|
|
if (test.GetLeftSonIndex() > 0 || test.GetRightSonIndex() > 0){
|
|
if (test.GetLeftSonIndex() > 0){
|
|
if (father.GetRightSonIndex() == pos){
|
|
father.SetRightSonIndex(test.GetLeftSonIndex());
|
|
} else {
|
|
father.SetLeftSonIndex(test.GetLeftSonIndex());
|
|
}
|
|
} else {
|
|
if (father.GetRightSonIndex() == pos){
|
|
father.SetRightSonIndex(test.GetRightSonIndex());
|
|
} else {
|
|
father.SetLeftSonIndex(test.GetRightSonIndex());
|
|
}
|
|
}
|
|
} else {
|
|
if (father.GetRightSonIndex() == pos){
|
|
father.SetRightSonIndex(-1);
|
|
} else {
|
|
father.SetLeftSonIndex(-1);
|
|
}
|
|
}
|
|
}
|
|
tree.Put(posFather,father);
|
|
} else {
|
|
if (test.GetRightSonIndex() > 0 && test.GetLeftSonIndex() > 0) {
|
|
int newPos = test.GetRightSonIndex();
|
|
int newFatherPos = pos;
|
|
TreeEntry smallestBigger;
|
|
tree.Get(newPos,smallestBigger);
|
|
while (smallestBigger.GetLeftSonIndex() > 0){
|
|
newFatherPos = newPos;
|
|
newPos = smallestBigger.GetLeftSonIndex();
|
|
tree.Get(newPos, smallestBigger);
|
|
}
|
|
TreeEntry newFather;
|
|
tree.Get(newFatherPos, newFather);
|
|
newFather.SetLeftSonIndex(smallestBigger.GetRightSonIndex());
|
|
tree.Put(newFatherPos,newFather);
|
|
smallestBigger.SetLeftSonIndex(test.GetLeftSonIndex());
|
|
smallestBigger.SetRightSonIndex(test.GetRightSonIndex());
|
|
tree.Put(pos, smallestBigger);
|
|
} else {
|
|
if (test.GetLeftSonIndex() > 0 || test.GetRightSonIndex() > 0){
|
|
TreeEntry newRoot;
|
|
if (test.GetLeftSonIndex() > 0){
|
|
tree.Get(test.GetLeftSonIndex(),newRoot);
|
|
} else {
|
|
tree.Get(test.GetRightSonIndex(),newRoot);
|
|
}
|
|
tree.Put(pos,newRoot);
|
|
} else {
|
|
freePos = 0;
|
|
}
|
|
}
|
|
}
|
|
numOfElements--;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Returns true if the tree is empty.
|
|
|
|
*/
|
|
inline bool isEmpty() const{
|
|
return numOfElements == 0;
|
|
}
|
|
|
|
private:
|
|
DbArray<TreeEntry> tree;
|
|
int freePos;
|
|
int numOfElements;
|
|
|
|
};
|
|
|
|
|
|
/*
|
|
1.1.2 struct SectTreeEntry
|
|
|
|
The struct ~SectTreeEntry~ is used for the shortest path computation. The
|
|
sections already visited by the Dijkstra's algorithm for shortest path search
|
|
will be stored sorted by their section tuple ids in a tree. ~secttid~ is the
|
|
tuple id of the section in the sections relation of the network. ~rid~ is
|
|
the route identifier of the route the section belongs to. ~start~ respectively
|
|
~end~ gives the position on the route as distance from the start of the route
|
|
for the start and the end point of the section. ~startbool~ and ~endbool~ tell
|
|
us if the whole section is part described or only a part of the section.
|
|
|
|
*/
|
|
|
|
struct SectTreeEntry{
|
|
SectTreeEntry() {};
|
|
|
|
SectTreeEntry(const TupleId n, const int r, const double st, const double e,
|
|
const bool stb, const bool eb) {
|
|
secttid = n;
|
|
rid = r;
|
|
start = st;
|
|
end = e;
|
|
startbool = stb;
|
|
endbool = eb;
|
|
};
|
|
|
|
~SectTreeEntry(){};
|
|
|
|
SectTreeEntry& operator=(const SectTreeEntry nEntry) {
|
|
secttid = nEntry.secttid;
|
|
rid = nEntry.rid;
|
|
start = nEntry.start;
|
|
end = nEntry.end;
|
|
startbool = nEntry.startbool;
|
|
endbool = nEntry.endbool;
|
|
return *this;
|
|
};
|
|
|
|
std::ostream& Print ( std::ostream& os ) const
|
|
{
|
|
os << "SectTreeEntry: TupleId: " << secttid << endl;
|
|
os << "RouteId: " << rid << ", start: " << start;
|
|
os << ", end: " << end << ", startbool: " << startbool;
|
|
os << ", endbool: " << endbool << endl;
|
|
os << endl;
|
|
return os;
|
|
};
|
|
|
|
TupleId secttid;
|
|
int rid;
|
|
double start, end;
|
|
bool startbool, endbool;
|
|
};
|
|
|
|
|
|
class ShortestPathTreeEntry
|
|
{
|
|
public:
|
|
ShortestPathTreeEntry(){};
|
|
|
|
ShortestPathTreeEntry(const double d, const bool up):
|
|
dist(d),upDown(up)
|
|
{};
|
|
|
|
~ShortestPathTreeEntry(){};
|
|
|
|
inline void SetDist(const double d)
|
|
{
|
|
dist = d;
|
|
}
|
|
|
|
inline void SetUpDown (const bool up)
|
|
{
|
|
upDown = up;
|
|
}
|
|
|
|
inline double GetDist() const
|
|
{
|
|
return dist;
|
|
}
|
|
|
|
inline bool GetUpDown() const
|
|
{
|
|
return upDown;
|
|
}
|
|
|
|
std::ostream& Print(std::ostream& os) const
|
|
{
|
|
os << "Distance: " << dist << ", Up: " << upDown << endl;
|
|
return os;
|
|
}
|
|
|
|
int Compare(const ShortestPathTreeEntry sp) const
|
|
{
|
|
if (dist < sp.dist) return -1;
|
|
if (dist > sp.dist) return 1;
|
|
return 0;
|
|
}
|
|
|
|
private:
|
|
double dist;
|
|
bool upDown;
|
|
};
|
|
|
|
|
|
class GPoints;
|
|
class Network;
|
|
class GLine;
|
|
class GPoint;
|
|
|
|
/*
|
|
2 GLine
|
|
|
|
Every ~gline~ consists of a set of ~RouteInterval~s stored in a ~DbArray~.
|
|
|
|
2.1 struct RouteInterval
|
|
Each ~RouteInterval~ consists of a ~rid~, ~startpos~ and ~endpos~. Telling to
|
|
which route of the network the route interval belongs to. And giving the start
|
|
and end position of the ~RouteInterval~ of this route.
|
|
|
|
Different from the definitions in the original paper the implemented
|
|
~RouteInterval~ does not contain a side value. This should be changed to enable
|
|
us for example to store traffic jams as possibly ~moving(gline)~ values.
|
|
|
|
*/
|
|
|
|
class RouteInterval
|
|
{
|
|
public:
|
|
RouteInterval()
|
|
{
|
|
};
|
|
|
|
RouteInterval(const int in_iRouteId,
|
|
const double in_dStart,
|
|
const double in_dEnd):
|
|
m_iRouteId(in_iRouteId),
|
|
m_dStart(in_dStart),
|
|
m_dEnd(in_dEnd) {};
|
|
|
|
RouteInterval(const RouteInterval& ri):
|
|
m_iRouteId(ri.m_iRouteId),
|
|
m_dStart(ri.m_dStart),
|
|
m_dEnd(ri.m_dEnd) {};
|
|
|
|
~RouteInterval() {};
|
|
|
|
/*
|
|
Computes the spatial Bounding Box of the given ~RouteInterval~ as 2 dimensional
|
|
rectangle. Using the subline of the route curve defined by the given ~route-
|
|
interval~.
|
|
|
|
*/
|
|
|
|
Rectangle<2> BoundingBox(const Network* pNetwork) const;
|
|
|
|
/*
|
|
Get and Set private values.
|
|
|
|
*/
|
|
inline int GetRouteId() const
|
|
{
|
|
return m_iRouteId;
|
|
};
|
|
|
|
inline double GetStartPos() const
|
|
{
|
|
return m_dStart;
|
|
};
|
|
|
|
inline double GetEndPos() const
|
|
{
|
|
return m_dEnd;
|
|
};
|
|
|
|
inline double GetValue(const bool start) const
|
|
{
|
|
if (start) return m_dStart;
|
|
else return m_dEnd;
|
|
};
|
|
|
|
inline void SetRouteId(const int rid)
|
|
{
|
|
m_iRouteId = rid;
|
|
};
|
|
|
|
inline void SetStartPos(const double pos)
|
|
{
|
|
m_dStart = pos;
|
|
};
|
|
|
|
inline void SetEndPos(const double pos)
|
|
{
|
|
m_dEnd = pos;
|
|
};
|
|
|
|
inline double Length() const
|
|
{
|
|
return fabs(GetEndPos() - GetStartPos());
|
|
}
|
|
|
|
RouteInterval& operator=(const RouteInterval& ri)
|
|
{
|
|
m_iRouteId = ri.m_iRouteId;
|
|
m_dStart = ri.m_dStart;
|
|
m_dEnd = ri.m_dEnd;
|
|
return *this;
|
|
}
|
|
|
|
bool Contains(const RouteInterval *ri, const double tolerance) const;
|
|
bool Contains(const GPoint *gp)const;
|
|
bool Intersects(const RouteInterval *ri, const double tolerance) const;
|
|
std::ostream& Print(std::ostream& os) const;
|
|
|
|
|
|
private:
|
|
/*
|
|
The route id.
|
|
|
|
*/
|
|
|
|
int m_iRouteId;
|
|
|
|
/*
|
|
Start position on route.
|
|
|
|
*/
|
|
|
|
double m_dStart;
|
|
|
|
/*
|
|
End position on route.
|
|
|
|
*/
|
|
|
|
double m_dEnd;
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
3 class GPoint
|
|
|
|
3.1 enumeration of side
|
|
|
|
Attention in the original paper the enumeration of the side value is given by
|
|
Down, Up, None!!!
|
|
|
|
*/
|
|
enum Side { Down, Up, None };
|
|
|
|
/*
|
|
3.2 struct for route location (~rloc~)
|
|
Every single position in the network is given by an route location. That means
|
|
by a route id ~rid~, the distance of the position from the start of the route
|
|
~d~, and the side ~side~ value. If the route is simple side is always ~None~.
|
|
|
|
*/
|
|
|
|
struct RLoc
|
|
{
|
|
RLoc() {}
|
|
/*
|
|
|
|
Constuructors:
|
|
|
|
The simple constructor. Should not be used.
|
|
|
|
*/
|
|
RLoc( const int rid,
|
|
const double d,
|
|
const Side side ):
|
|
rid( rid ), d( d ), side( side )
|
|
{}
|
|
|
|
RLoc( const RLoc& rloc ):
|
|
rid( rloc.rid ), d( rloc.d ), side( rloc.side )
|
|
{}
|
|
|
|
/*
|
|
|
|
Assignment operator.
|
|
|
|
*/
|
|
|
|
RLoc& operator=( const RLoc& rloc )
|
|
{
|
|
rid = rloc.rid; d = rloc.d; side = rloc.side;
|
|
return *this;
|
|
}
|
|
|
|
void SetRouteId(const int r){rid = r;}
|
|
void SetPosition(const double p) {d = p;}
|
|
void SetSide(const Side s){side = s;}
|
|
|
|
/*
|
|
|
|
Private fields.
|
|
|
|
Route Id
|
|
|
|
*/
|
|
|
|
int rid;
|
|
|
|
/*
|
|
The distance from the 0.0 point of the route.
|
|
|
|
*/
|
|
|
|
double d;
|
|
|
|
/*
|
|
side value
|
|
|
|
*/
|
|
|
|
Side side;
|
|
};
|
|
|
|
/*
|
|
3.4 class ~gpoint~
|
|
|
|
Represents single positions in the network. Each ~GPoint~ consists of a network
|
|
id the ~gpoint~ belongs to, a ~rloc~ and a boolean defined flag. Because
|
|
~gpoint~ should be usable in relations the class ~gpoint~ derives from
|
|
class Attribute.
|
|
|
|
*/
|
|
|
|
class GPoint : public Attribute
|
|
{
|
|
public:
|
|
|
|
/*
|
|
3.4.1 Constructors and Destructor
|
|
|
|
*/
|
|
|
|
GPoint():Attribute()
|
|
{}
|
|
|
|
GPoint(const bool def)
|
|
: Attribute(def)
|
|
{}
|
|
|
|
GPoint( const bool in_bDefined,
|
|
const int in_iNetworkId,
|
|
const int in_xRid,
|
|
const double in_dLocation,
|
|
const Side in_xSide = None ):
|
|
Attribute(in_bDefined),
|
|
m_iNetworkId( in_iNetworkId ),
|
|
m_xRouteLocation( in_xRid, in_dLocation, in_xSide )
|
|
{
|
|
SetDefined(in_bDefined);
|
|
}
|
|
|
|
GPoint( const GPoint& in_xOther ):
|
|
Attribute(in_xOther.IsDefined()),
|
|
m_iNetworkId( in_xOther.m_iNetworkId ),
|
|
m_xRouteLocation( in_xOther.m_xRouteLocation )
|
|
{
|
|
SetDefined(in_xOther.IsDefined());
|
|
}
|
|
|
|
~GPoint(){};
|
|
|
|
/*
|
|
3.4.2 Methods of class ~gpoint~
|
|
|
|
*/
|
|
|
|
GPoint& operator=( const GPoint& in_xOther )
|
|
{
|
|
SetDefined(in_xOther.IsDefined());
|
|
if( IsDefined())
|
|
{
|
|
m_iNetworkId = in_xOther.m_iNetworkId;
|
|
m_xRouteLocation = in_xOther.m_xRouteLocation;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
/*
|
|
Get Methods of ~gpoint~
|
|
|
|
*/
|
|
|
|
inline int GetNetworkId() const
|
|
{
|
|
return m_iNetworkId;
|
|
}
|
|
|
|
inline int GetRouteId() const
|
|
{
|
|
return m_xRouteLocation.rid;
|
|
}
|
|
|
|
inline double GetPosition() const
|
|
{
|
|
return m_xRouteLocation.d;
|
|
}
|
|
|
|
inline Side GetSide() const
|
|
{
|
|
return m_xRouteLocation.side;
|
|
}
|
|
|
|
|
|
/*
|
|
Set Methods of ~gpoint~
|
|
|
|
*/
|
|
|
|
inline void SetRouteId( const int in_rid )
|
|
{
|
|
m_xRouteLocation.SetRouteId(in_rid);
|
|
}
|
|
|
|
inline void SetPosition(const double pos )
|
|
{
|
|
m_xRouteLocation.SetPosition(pos);
|
|
}
|
|
|
|
inline void SetSide( const Side s )
|
|
{
|
|
m_xRouteLocation.SetSide(s);
|
|
}
|
|
|
|
size_t Sizeof() const
|
|
{
|
|
return sizeof(GPoint);
|
|
}
|
|
|
|
size_t HashValue() const
|
|
{
|
|
size_t hash = m_iNetworkId + m_xRouteLocation.rid +
|
|
(size_t) m_xRouteLocation.d;
|
|
return hash;
|
|
}
|
|
|
|
void CopyFrom( const Attribute* right )
|
|
{
|
|
const GPoint* gp = (const GPoint*)right;
|
|
*this = *gp;
|
|
}
|
|
|
|
int Compare( const Attribute* arg ) const
|
|
{
|
|
const GPoint *p = (const GPoint*) arg;
|
|
return Compare(*p);
|
|
}
|
|
|
|
int Compare(const GPoint p) const
|
|
{
|
|
if (m_iNetworkId < p.GetNetworkId())
|
|
{
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
if (m_iNetworkId > p.GetNetworkId())
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{ // same network
|
|
if (m_xRouteLocation.rid < p.GetRouteId())
|
|
{
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
if (m_xRouteLocation.rid > p.GetRouteId())
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{ //same route
|
|
if (m_xRouteLocation.d < p.GetPosition())
|
|
{
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
if (m_xRouteLocation.d > p.GetPosition())
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{ //same Position
|
|
if (m_xRouteLocation.side == 2 || p.GetSide() == 2 ||
|
|
m_xRouteLocation.side == p.GetSide())
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
if (m_xRouteLocation.side < p.GetSide())
|
|
{
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return -1; //should never been reached
|
|
}
|
|
|
|
bool Adjacent( const Attribute *arg ) const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
GPoint *Clone() const
|
|
{
|
|
return new GPoint( *this );
|
|
}
|
|
|
|
std::ostream& Print( std::ostream& os ) const
|
|
{
|
|
if(IsDefined())
|
|
{
|
|
os << "NetworkId: " << m_iNetworkId
|
|
<< " RouteId: " << m_xRouteLocation.rid
|
|
<< " Position: " << m_xRouteLocation.d
|
|
<< " Side: " << m_xRouteLocation.side << endl;
|
|
}
|
|
else
|
|
os << "not defined." << endl;
|
|
return os;
|
|
}
|
|
|
|
/*
|
|
Functions for Secondo integration.
|
|
|
|
*/
|
|
static ListExpr OutGPoint( ListExpr typeInfo, Word value );
|
|
|
|
static Word InGPoint( const ListExpr typeInfo, const ListExpr instance,
|
|
const int errorPos, ListExpr& errorInfo, bool& correct );
|
|
|
|
static Word CreateGPoint( const ListExpr typeInfo );
|
|
|
|
static void DeleteGPoint( const ListExpr typeInfo, Word& w );
|
|
|
|
static void CloseGPoint( const ListExpr typeInfo, Word& w );
|
|
|
|
static Word CloneGPoint( const ListExpr typeInfo, const Word& w );
|
|
|
|
static void* CastGPoint( void* addr );
|
|
|
|
static int SizeOfGPoint();
|
|
|
|
static bool CheckGPoint( ListExpr type, ListExpr& errorInfo );
|
|
|
|
inline static const std::string BasicType() { return "gpoint"; }
|
|
static const bool checkType(const ListExpr type){
|
|
return listutils::isSymbol(type, BasicType());
|
|
}
|
|
|
|
|
|
/*
|
|
Returns the network distance between 2 ~gpoint~ using DijkstrasAlgorithm.
|
|
|
|
*/
|
|
|
|
double Netdistance (const GPoint* toGPoint) const;
|
|
|
|
/*
|
|
Returns the network distance between 2 ~gpoint~ using AStar-Algorithm.
|
|
|
|
*/
|
|
|
|
double NetdistanceNew (const GPoint* toGPoint) const;
|
|
double NetdistanceNew (const GPoint* toGPoint,
|
|
const Network* pNetwork) const;
|
|
|
|
double NetdistanceNew (const GLine* toGLine) const;
|
|
double NetdistanceNew (const GLine* toGLine,
|
|
const Network* pNetwork) const;
|
|
|
|
double NetdistanceNew (const GPoints* toGPoints) const;
|
|
double NetdistanceNew (const GPoints* toGPoints,
|
|
const Network* pNetwork) const;
|
|
|
|
/*
|
|
Never used ?
|
|
|
|
*/
|
|
double NewNetdistance(const GPoint* pToGPoint, GLine* res) const;//new
|
|
|
|
/*
|
|
Computes the euclidean distance of 2 glines.
|
|
|
|
*/
|
|
double Distance (const GPoint* toGPoint) const ;
|
|
|
|
/*
|
|
Returns true if the gpoint is inside the gline false elsewhere.
|
|
|
|
*/
|
|
|
|
bool Inside( const GLine *gl, const double tolerance) const;
|
|
|
|
/*
|
|
Returns true if two gpoint are identical.
|
|
|
|
*/
|
|
|
|
bool operator== (const GPoint& p) const;
|
|
|
|
/*
|
|
Returns false if two gpoint are identical.
|
|
|
|
*/
|
|
|
|
bool operator!= (const GPoint&p) const;
|
|
|
|
/*
|
|
Translates a ~gpoint~ into a ~point~ in the 2D plane.
|
|
|
|
*/
|
|
|
|
void ToPoint(Point *& res) const;
|
|
|
|
Point* ToPoint() const;
|
|
|
|
Point* ToPoint(const Network *&pNetwork) const;
|
|
|
|
/*
|
|
Returns the spatial Bounding Box of the point which is a rectangle degenerated
|
|
to a single point.
|
|
|
|
*/
|
|
|
|
inline const Rectangle<2> BoundingBox(){
|
|
if (IsDefined()) {
|
|
Point *p = ToPoint();
|
|
Rectangle<2> result = p->BoundingBox();
|
|
p->DeleteIfAllowed();
|
|
return result;
|
|
} else return Rectangle<2> (false);
|
|
};
|
|
|
|
/*
|
|
Returns a point degenerated rectangle as network bounding box of the gpoint
|
|
|
|
*/
|
|
|
|
inline const Rectangle<2> NetBoundingBox() const {
|
|
if (IsDefined()){
|
|
double minMax[] = { (double) m_xRouteLocation.rid,
|
|
(double) m_xRouteLocation.rid,
|
|
m_xRouteLocation.d - 0.000001,
|
|
m_xRouteLocation.d + 0.000001};
|
|
//0.000001 correcture of rounding differences
|
|
return Rectangle<2>(true,minMax);
|
|
}else return Rectangle<2> (false);
|
|
};
|
|
|
|
/*
|
|
Returns a gline representing the shortest path between two GPoint.
|
|
Using DijkstrasAlgorithm
|
|
|
|
*/
|
|
|
|
bool ShortestPath(const GPoint *ziel, GLine *result,
|
|
DbArray<TupleId>* touchedSects = 0) const;
|
|
bool ShortestPath(const GPoint* ziel, GLine *result,
|
|
const Network* pNetwork,
|
|
DbArray<TupleId>* touchedSects = 0) const;
|
|
|
|
/*
|
|
Returns a gline representing the shortest path between a GPoint.and
|
|
a gpoint or gline.
|
|
|
|
Using AStarAlgorithm
|
|
|
|
*/
|
|
|
|
bool ShortestPathAStar(const GPoint *ziel, GLine *result,
|
|
DbArray<TupleId>* touchedSects = 0) const;
|
|
bool ShortestPathAStar(const GPoint* ziel, GLine* result,
|
|
const Network *pNetwork,
|
|
DbArray<TupleId>* touchedSects = 0) const;
|
|
|
|
bool ShortestPathAStar(const GLine *ziel, GLine *result,
|
|
DbArray<TupleId>* touchedSects = 0) const;
|
|
bool ShortestPathAStar(const GLine* ziel, GLine* result,
|
|
const Network *pNetwork,
|
|
DbArray<TupleId>* touchedSects = 0) const;
|
|
|
|
bool ShortestPathAStar(const GPoints *ziel, GLine *result,
|
|
DbArray<TupleId>* touchedSects = 0) const;
|
|
bool ShortestPathAStar(const GPoints* ziel, GLine* result,
|
|
const Network *pNetwork,
|
|
DbArray<TupleId>* touchedSects = 0) const;
|
|
|
|
/*
|
|
Returns the shortest path tree from the gpoint to all sections of the
|
|
network. The distances are stored in an DbArray<double>, where the index
|
|
of the Array-Field is two times the section number for up sections and
|
|
two times the section number plus one for down sections.
|
|
|
|
*/
|
|
|
|
void ShortestPathTree(const Network* pNetwork,
|
|
DbArray<ShortestPathTreeEntry> *res) const;
|
|
|
|
/*
|
|
Almost analogous to shortest path tree but stops computation if all sections
|
|
of ~toReach~ are inserted.
|
|
|
|
*/
|
|
|
|
void ShortestPathTree(const Network* pNetwork,
|
|
DbArray<ShortestPathTreeEntry> *res,
|
|
SortedTree<Entry<SectionValue> > *toReach) const;
|
|
|
|
|
|
/*
|
|
Returns the reverse shortest path tree of the gpoint from all sections of the
|
|
network. The distances are stored in an DbArray<double>, where the index
|
|
of the Array-Field is two times the section number for up sections and
|
|
two times the section number plus one for down sections.
|
|
|
|
*/
|
|
|
|
void ReverseShortestPathTree(const Network* pNetwork,
|
|
DbArray<ShortestPathTreeEntry> *res) const;
|
|
|
|
/*
|
|
Almost analogous to reverse shortest path tree but stops computation if all
|
|
sections of ~toReach~ are inserted.
|
|
|
|
*/
|
|
|
|
void ReverseShortestPathTree(const Network* pNetwork,
|
|
DbArray<ShortestPathTreeEntry> *res,
|
|
SortedTree<Entry<SectionValue> > *toReach) const;
|
|
|
|
/*
|
|
Returns the route intervals from which the ~GPoint~ can be reached within a
|
|
given distance.
|
|
|
|
*/
|
|
|
|
void In_Circle(const Network* pNetwork, GLine *res,
|
|
const double maxdist) const;
|
|
|
|
/*
|
|
Returns the route intervals which can be reached from the ~GPoint~ within a
|
|
given distance.
|
|
|
|
*/
|
|
|
|
void Out_Circle(const Network* pNetwork, GLine *res,
|
|
const double maxdist) const;
|
|
|
|
/*
|
|
Returns the route intervals whithin distance maxdist from ~GPoint~ ignoring
|
|
connectivity in the junctions.
|
|
|
|
*/
|
|
void Circle(const Network* pNetwork, GLine *res,
|
|
const double maxdist) const;
|
|
|
|
|
|
private:
|
|
|
|
/*
|
|
|
|
3.4 private Fields of class ~gpoint~
|
|
|
|
Network id
|
|
|
|
*/
|
|
|
|
int m_iNetworkId;
|
|
|
|
/*
|
|
Route location see struct ~rloc~ for detailed fields
|
|
|
|
*/
|
|
RLoc m_xRouteLocation;
|
|
|
|
};
|
|
|
|
/*
|
|
4. Network
|
|
|
|
4.1 Enumerations of columns for relations
|
|
|
|
*/
|
|
|
|
enum PositionRoutesRelation { ROUTE_ID = 0,
|
|
ROUTE_LENGTH,
|
|
ROUTE_CURVE,
|
|
ROUTE_DUAL,
|
|
ROUTE_STARTSSMALLER };
|
|
enum PositionJunctionsRelation { JUNCTION_ROUTE1_ID = 0,
|
|
JUNCTION_ROUTE1_MEAS,
|
|
JUNCTION_ROUTE2_ID,
|
|
JUNCTION_ROUTE2_MEAS,
|
|
JUNCTION_CC,
|
|
JUNCTION_POS,
|
|
JUNCTION_ROUTE1_RC,
|
|
JUNCTION_ROUTE2_RC,
|
|
JUNCTION_SECTION_AUP_RC,
|
|
JUNCTION_SECTION_ADOWN_RC,
|
|
JUNCTION_SECTION_BUP_RC,
|
|
JUNCTION_SECTION_BDOWN_RC};
|
|
enum PositionSectionsRelation { SECTION_RID = 0,
|
|
SECTION_MEAS1,
|
|
SECTION_MEAS2,
|
|
SECTION_DUAL,
|
|
SECTION_CURVE,
|
|
SECTION_CURVE_STARTS_SMALLER,
|
|
SECTION_RRC,
|
|
SECTION_SID};
|
|
|
|
|
|
/*
|
|
4.2 Class ConnectivityCode
|
|
|
|
Enum defining binary coding for the possible transitions between to routes.
|
|
|
|
*/
|
|
enum Transition
|
|
{
|
|
AUP_AUP = 1,
|
|
AUP_ADOWN = 2,
|
|
AUP_BUP = 4,
|
|
AUP_BDOWN = 8,
|
|
ADOWN_AUP = 16,
|
|
ADOWN_ADOWN = 32,
|
|
ADOWN_BUP = 64,
|
|
ADOWN_BDOWN = 128,
|
|
BUP_AUP = 256,
|
|
BUP_ADOWN = 512,
|
|
BUP_BUP = 1024,
|
|
BUP_BDOWN = 2048,
|
|
BDOWN_AUP = 4096,
|
|
BDOWN_ADOWN = 8192,
|
|
BDOWN_BUP = 16384,
|
|
BDOWN_BDOWN = 32768
|
|
};
|
|
|
|
class ConnectivityCode
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
/*
|
|
4.2.1 Constructor.
|
|
|
|
Constructs the connectivity code given an integer value ~cc~.
|
|
|
|
*/
|
|
ConnectivityCode( const int in_iCc ):
|
|
m_iConnectivityCode( in_iCc )
|
|
{
|
|
}
|
|
|
|
/*
|
|
4.2.2 Constructor for boolean values.
|
|
|
|
Constructs the connectivity code given the Boolean values for
|
|
all possibilities.
|
|
|
|
*/
|
|
ConnectivityCode( const bool in_bAup_Aup,
|
|
const bool in_bAup_Adown,
|
|
const bool in_bAup_Bup,
|
|
const bool in_bAup_Bdown,
|
|
const bool in_bAdown_Aup,
|
|
const bool in_bAdown_Adown,
|
|
const bool in_bAdown_Bup,
|
|
const bool in_bAdown_Bdown,
|
|
const bool in_bBup_Aup,
|
|
const bool in_bBup_Adown,
|
|
const bool in_bBup_Bup,
|
|
const bool in_bBup_Bdown,
|
|
const bool in_bBdown_Aup,
|
|
const bool in_bBdown_Adown,
|
|
const bool in_bBdown_Bup,
|
|
const bool in_bBdown_Bdown ):
|
|
m_iConnectivityCode( (in_bAup_Aup ? AUP_AUP: 0u) |
|
|
(in_bAup_Adown? AUP_ADOWN:0u) |
|
|
(in_bAup_Bup? AUP_BUP: 0u) |
|
|
(in_bAup_Bdown? AUP_BDOWN:0u) |
|
|
(in_bAdown_Aup ? ADOWN_AUP:0u) |
|
|
(in_bAdown_Adown ? ADOWN_ADOWN:0u) |
|
|
(in_bAdown_Bup ? ADOWN_BUP:0u) |
|
|
(in_bAdown_Bdown ? ADOWN_BDOWN:0u) |
|
|
(in_bBup_Aup ? BUP_AUP:0u) |
|
|
(in_bBup_Adown ? BUP_ADOWN:0u) |
|
|
(in_bBup_Bup ? BUP_BUP:0u) |
|
|
(in_bBup_Bdown ? BUP_BDOWN:0u) |
|
|
(in_bBdown_Aup ? BDOWN_AUP:0u) |
|
|
(in_bBdown_Adown ? BDOWN_ADOWN:0u) |
|
|
(in_bBdown_Bup ? BDOWN_BUP:0u) |
|
|
(in_bBdown_Bdown ? BDOWN_BDOWN:0u) )
|
|
{
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
4.2.3 Method isPossible
|
|
|
|
Checks if a transition is possible.
|
|
|
|
*/
|
|
bool IsPossible( const Transition in_xTransition ) const
|
|
{
|
|
return in_xTransition & m_iConnectivityCode;
|
|
}
|
|
|
|
std::ostream& Print(std::ostream& os) const
|
|
{
|
|
os << m_iConnectivityCode << endl;
|
|
return os;
|
|
}
|
|
|
|
private:
|
|
|
|
/*
|
|
4.2.4 private fields ConnectivtyCode
|
|
|
|
The connectivity code
|
|
|
|
*/
|
|
int m_iConnectivityCode;
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
4.2.5 Class DirectedSection
|
|
|
|
This class is needed for the list of sections used in each entry
|
|
in the adjacency-list
|
|
|
|
*/
|
|
class DirectedSection
|
|
{
|
|
public:
|
|
|
|
/*
|
|
Constructor
|
|
|
|
*/
|
|
DirectedSection()
|
|
{
|
|
}
|
|
|
|
/*
|
|
Constructor giving a section
|
|
|
|
*/
|
|
DirectedSection( const TupleId in_iSectionTid,
|
|
const bool in_bUpDown):
|
|
m_iSectionTid( in_iSectionTid ),
|
|
m_bUpDown( in_bUpDown )
|
|
{
|
|
}
|
|
|
|
/*
|
|
Copy-Constructor
|
|
|
|
*/
|
|
|
|
DirectedSection( const DirectedSection& in_xSection ):
|
|
m_iSectionTid( in_xSection.m_iSectionTid),
|
|
m_bUpDown( in_xSection.m_bUpDown )
|
|
{
|
|
}
|
|
|
|
/*
|
|
Redefinition of the assignment operator.
|
|
|
|
*/
|
|
DirectedSection& operator=( const DirectedSection& in_xSection )
|
|
{
|
|
m_bUpDown = in_xSection.m_bUpDown;
|
|
m_iSectionTid = in_xSection.m_iSectionTid;
|
|
return *this;
|
|
}
|
|
|
|
bool GetUpDownFlag() const
|
|
{
|
|
return m_bUpDown;
|
|
}
|
|
|
|
TupleId GetSectionTid() const
|
|
{
|
|
return m_iSectionTid;
|
|
}
|
|
|
|
std::ostream& Print(std::ostream& os) const
|
|
{
|
|
os << "Directed Section: TupleId: " << (long) m_iSectionTid;
|
|
os << ", UpDownFlag: ";
|
|
if (m_bUpDown ) os << "Up" << endl;
|
|
else os << "Down" << endl;
|
|
return os;
|
|
}
|
|
|
|
private:
|
|
|
|
/*
|
|
Field with section-pointer
|
|
|
|
A pointer to the section.
|
|
|
|
*/
|
|
TupleId m_iSectionTid;
|
|
|
|
/*
|
|
Field Direction-flag
|
|
|
|
A flag indicating the direction: ~true~ means up and ~false~ means down.
|
|
|
|
*/
|
|
bool m_bUpDown;
|
|
};
|
|
|
|
/*
|
|
4.2.7 Class DirectedSectionPair
|
|
|
|
This class is needed for the list of sections used in each entry
|
|
in the adjacency-list
|
|
|
|
*/
|
|
class DirectedSectionPair
|
|
{
|
|
public:
|
|
|
|
/*
|
|
Constructor
|
|
|
|
*/
|
|
DirectedSectionPair()
|
|
{
|
|
}
|
|
|
|
/*
|
|
Constructor giving a section
|
|
|
|
*/
|
|
DirectedSectionPair(const TupleId in_iFirstSectionTid,
|
|
const bool in_bFirstUpDown,
|
|
const TupleId in_iSecondSectionTid,
|
|
const bool in_bSecondUpDown):
|
|
m_iFirstSectionTid( in_iFirstSectionTid ),
|
|
m_bFirstUpDown( in_bFirstUpDown ),
|
|
m_iSecondSectionTid( in_iSecondSectionTid ),
|
|
m_bSecondUpDown( in_bSecondUpDown )
|
|
{
|
|
}
|
|
|
|
/*
|
|
Copy-Constructor
|
|
|
|
*/
|
|
DirectedSectionPair( const DirectedSectionPair& in_xSection ):
|
|
m_iFirstSectionTid(in_xSection.m_iFirstSectionTid ),
|
|
m_bFirstUpDown(in_xSection.m_bFirstUpDown ),
|
|
m_iSecondSectionTid(in_xSection.m_iSecondSectionTid ),
|
|
m_bSecondUpDown(in_xSection.m_bSecondUpDown )
|
|
{
|
|
}
|
|
|
|
std::ostream& Print(std::ostream& os) const {
|
|
os << "1.Section: " << m_iFirstSectionTid;
|
|
if (m_bFirstUpDown) os << " Up";
|
|
else os << " Down";
|
|
os << " 2.Section: " << m_iSecondSectionTid;
|
|
if (m_bSecondUpDown) os << " Up" << endl;
|
|
else os << " Down" << endl;
|
|
return os;
|
|
}
|
|
|
|
~DirectedSectionPair(){};
|
|
|
|
bool operator<(const DirectedSectionPair& in_xOther) const
|
|
{
|
|
if(m_iFirstSectionTid < in_xOther.m_iFirstSectionTid)
|
|
return true;
|
|
if (m_iFirstSectionTid > in_xOther.m_iFirstSectionTid)
|
|
return false;
|
|
if(m_bFirstUpDown != in_xOther.m_bFirstUpDown)
|
|
return m_bFirstUpDown;
|
|
if (m_iSecondSectionTid < in_xOther.m_iSecondSectionTid)
|
|
return true;
|
|
if (m_iSecondSectionTid > in_xOther.m_iSecondSectionTid)
|
|
return false;
|
|
return m_bSecondUpDown;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
Field with a pointer to the first section.
|
|
|
|
*/
|
|
TupleId m_iFirstSectionTid;
|
|
|
|
/*
|
|
|
|
Field Direction-flag
|
|
|
|
Indicating the first sections direction: ~true~ means up and ~false~ means down.
|
|
|
|
*/
|
|
bool m_bFirstUpDown;
|
|
|
|
/*
|
|
Field with a pointer to the second section.
|
|
|
|
*/
|
|
TupleId m_iSecondSectionTid;
|
|
|
|
/*
|
|
Field Direction-flag
|
|
|
|
Indicating the second section direction: ~true~ means up and ~false~ means down.
|
|
|
|
*/
|
|
bool m_bSecondUpDown;
|
|
};
|
|
|
|
|
|
/*
|
|
4.2.8 Class AdjacencyListEntry
|
|
|
|
Used for the adjacency-list of the network
|
|
|
|
*/
|
|
struct AdjacencyListEntry
|
|
{
|
|
/*
|
|
The simple constructor.
|
|
|
|
*/
|
|
AdjacencyListEntry() {}
|
|
|
|
/*
|
|
The constructor.
|
|
|
|
*/
|
|
AdjacencyListEntry( const int in_iLow,
|
|
const int in_iHigh ):
|
|
m_iLow( in_iLow ),
|
|
m_iHigh( in_iHigh )
|
|
{
|
|
}
|
|
|
|
/*
|
|
The copy constructor.
|
|
|
|
*/
|
|
AdjacencyListEntry( const AdjacencyListEntry& in_xEntry ):
|
|
m_iLow( in_xEntry.m_iLow ),
|
|
m_iHigh( in_xEntry.m_iHigh )
|
|
{
|
|
}
|
|
|
|
/*
|
|
The lower index in the adjacency lists sub-array.
|
|
|
|
*/
|
|
int m_iLow;
|
|
|
|
/*
|
|
The higher index in the adjacency lists sub-array.
|
|
|
|
*/
|
|
int m_iHigh;
|
|
};
|
|
|
|
/*
|
|
4.2.9 Class JunctionSortEntry
|
|
|
|
A helper struct for junction lists.
|
|
|
|
*/
|
|
struct JunctionSortEntry
|
|
{
|
|
JunctionSortEntry()
|
|
{
|
|
}
|
|
|
|
JunctionSortEntry(const bool in_bFirstRoute,
|
|
Tuple* in_pJunction):
|
|
m_bFirstRoute(in_bFirstRoute),
|
|
m_pJunction(in_pJunction)
|
|
{
|
|
}
|
|
|
|
~JunctionSortEntry(){}
|
|
|
|
bool m_bFirstRoute;
|
|
Tuple* m_pJunction;
|
|
|
|
int Compare(const JunctionSortEntry& in_xOther) const {
|
|
if (GetRouteId() < in_xOther.GetRouteId()) return -1;
|
|
if (GetRouteId() > in_xOther.GetRouteId()) return 1;
|
|
if (GetRouteMeas() < in_xOther.GetRouteMeas()) return -1;
|
|
if (GetRouteMeas() > in_xOther.GetRouteMeas()) return 1;
|
|
if (GetOtherRouteId() < in_xOther.GetOtherRouteId()) return -1;
|
|
if (GetOtherRouteId() > in_xOther.GetOtherRouteId()) return 1;
|
|
if (GetOtherRouteMeas()< in_xOther.GetOtherRouteMeas())return -1;
|
|
if (GetOtherRouteMeas()> in_xOther.GetOtherRouteMeas())return 1;
|
|
if (m_bFirstRoute == in_xOther.m_bFirstRoute) return 0;
|
|
if (m_bFirstRoute) return -1;
|
|
if (in_xOther.m_bFirstRoute) return 1;
|
|
return 1;
|
|
}
|
|
|
|
bool operator<(const JunctionSortEntry& in_xOther) const
|
|
{
|
|
return Compare(in_xOther) < 0;
|
|
}
|
|
|
|
bool operator<=(const JunctionSortEntry& in_xOther) const
|
|
{
|
|
return Compare(in_xOther) < 1;
|
|
}
|
|
|
|
double GetRouteMeas() const
|
|
{
|
|
CcReal* pMeas;
|
|
if(m_bFirstRoute)
|
|
{
|
|
pMeas = (CcReal*)m_pJunction->GetAttribute(JUNCTION_ROUTE1_MEAS);
|
|
}
|
|
else
|
|
{
|
|
pMeas = (CcReal*)m_pJunction->GetAttribute(JUNCTION_ROUTE2_MEAS);
|
|
}
|
|
return pMeas->GetRealval();
|
|
|
|
}
|
|
|
|
double GetOtherRouteMeas() const
|
|
{
|
|
CcReal* pMeas;
|
|
if(m_bFirstRoute)
|
|
{
|
|
pMeas = (CcReal*)m_pJunction->GetAttribute(JUNCTION_ROUTE2_MEAS);
|
|
}
|
|
else
|
|
{
|
|
pMeas = (CcReal*)m_pJunction->GetAttribute(JUNCTION_ROUTE1_MEAS);
|
|
}
|
|
return pMeas->GetRealval();
|
|
|
|
}
|
|
|
|
int GetRouteId() const{
|
|
CcInt* pRouteId;
|
|
if (m_bFirstRoute) {
|
|
pRouteId = (CcInt*)m_pJunction->GetAttribute(JUNCTION_ROUTE1_ID);
|
|
} else {
|
|
pRouteId = (CcInt*)m_pJunction->GetAttribute(JUNCTION_ROUTE2_ID);
|
|
}
|
|
return pRouteId->GetIntval();
|
|
}
|
|
|
|
int GetOtherRouteId() const {
|
|
CcInt* pRouteId;
|
|
if (m_bFirstRoute) {
|
|
pRouteId = (CcInt*)m_pJunction->GetAttribute(JUNCTION_ROUTE2_ID);
|
|
} else {
|
|
pRouteId = (CcInt*)m_pJunction->GetAttribute(JUNCTION_ROUTE1_ID);
|
|
}
|
|
return pRouteId->GetIntval();
|
|
}
|
|
|
|
|
|
TupleId GetUpSectionId() const
|
|
{
|
|
TupleId pTid;
|
|
if(m_bFirstRoute)
|
|
{
|
|
pTid = ((TupleIdentifier*)
|
|
m_pJunction->GetAttribute(JUNCTION_SECTION_AUP_RC))->GetTid();
|
|
}
|
|
else
|
|
{
|
|
pTid =((TupleIdentifier*)
|
|
m_pJunction->GetAttribute(JUNCTION_SECTION_BUP_RC))->GetTid();
|
|
}
|
|
return pTid;
|
|
}
|
|
|
|
TupleId GetDownSectionId() const
|
|
{
|
|
TupleId pTid;
|
|
if(m_bFirstRoute)
|
|
{
|
|
pTid = ((TupleIdentifier*)
|
|
m_pJunction->GetAttribute(JUNCTION_SECTION_ADOWN_RC))->GetTid();
|
|
}
|
|
else
|
|
{
|
|
pTid =((TupleIdentifier*)
|
|
m_pJunction->GetAttribute(JUNCTION_SECTION_BDOWN_RC))->GetTid();
|
|
}
|
|
return pTid;
|
|
}
|
|
|
|
std::ostream& Print(std::ostream& os) const
|
|
{
|
|
os << "JunctionSortEntry First Route : " << m_bFirstRoute;
|
|
os << "Tuple: ";
|
|
m_pJunction->Print(os);
|
|
os << endl;
|
|
return os;
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
4.2.9 Class JunctionSortEntry
|
|
|
|
A helper struct for junction lists.
|
|
|
|
*/
|
|
|
|
struct JunctionTidSortEntry
|
|
{
|
|
JunctionTidSortEntry()
|
|
{}
|
|
|
|
JunctionTidSortEntry(const bool in_bFirstRoute,
|
|
TupleId in_pJunction,
|
|
Relation* in_JuncRel):
|
|
m_bFirstRoute(in_bFirstRoute),
|
|
m_pJunction(in_pJunction),
|
|
m_JuncRel(in_JuncRel)
|
|
{
|
|
}
|
|
|
|
~JunctionTidSortEntry(){}
|
|
|
|
bool m_bFirstRoute;
|
|
TupleId m_pJunction;
|
|
Relation* m_JuncRel;
|
|
|
|
void GetValues(int& rid1, double& rmeas1, int& rid2, double& rmeas2) const
|
|
{
|
|
Tuple *t = GetTuple();
|
|
if (m_bFirstRoute)
|
|
{
|
|
rid1 = ((CcInt*)t->GetAttribute(JUNCTION_ROUTE1_ID))->GetIntval();
|
|
rid2 = ((CcInt*)t->GetAttribute(JUNCTION_ROUTE2_ID))->GetIntval();
|
|
rmeas1 = ((CcReal*)t->GetAttribute(JUNCTION_ROUTE1_MEAS))->GetRealval();
|
|
rmeas2 = ((CcReal*)t->GetAttribute(JUNCTION_ROUTE2_MEAS))->GetRealval();
|
|
}
|
|
else
|
|
{
|
|
rid1 = ((CcInt*)t->GetAttribute(JUNCTION_ROUTE2_ID))->GetIntval();
|
|
rid2 = ((CcInt*)t->GetAttribute(JUNCTION_ROUTE1_ID))->GetIntval();
|
|
rmeas1 = ((CcReal*)t->GetAttribute(JUNCTION_ROUTE2_MEAS))->GetRealval();
|
|
rmeas2 = ((CcReal*)t->GetAttribute(JUNCTION_ROUTE1_MEAS))->GetRealval();
|
|
}
|
|
t->DeleteIfAllowed();
|
|
}
|
|
|
|
int Compare(const JunctionTidSortEntry& in_xOther) const
|
|
{
|
|
if (m_pJunction == in_xOther.m_pJunction)
|
|
{
|
|
if (m_bFirstRoute == in_xOther.m_bFirstRoute) return 0;
|
|
if (m_bFirstRoute) return -1;
|
|
return 1;
|
|
}
|
|
int trid1, trid2, orid1, orid2;
|
|
double trm1, trm2, orm1, orm2;
|
|
GetValues(trid1, trm1, trid2, trm2);
|
|
in_xOther.GetValues(orid1, orm1, orid2, orm2);
|
|
if (trid1 < orid1) return -1;
|
|
if (trid1 > orid1) return 1;
|
|
if (trm1 < orm1) return -1;
|
|
if (trm1 > orm1) return 1;
|
|
if (m_bFirstRoute != in_xOther.m_bFirstRoute){
|
|
if (m_bFirstRoute) return -1;
|
|
return 1;
|
|
}
|
|
if (trid2 < orid2) return -1;
|
|
if (trid2 > orid2) return 1;
|
|
if (trm2 < orm2) return -1;
|
|
if (trm2 > orm2) return 1;
|
|
return 0;
|
|
}
|
|
|
|
bool operator<(const JunctionTidSortEntry& in_xOther) const
|
|
{
|
|
return Compare(in_xOther) < 0;
|
|
}
|
|
|
|
bool operator<=(const JunctionTidSortEntry& in_xOther) const
|
|
{
|
|
return Compare(in_xOther) < 1;
|
|
}
|
|
|
|
Tuple* GetTuple() const
|
|
{
|
|
return m_JuncRel->GetTuple(m_pJunction,false);
|
|
}
|
|
|
|
double GetRouteMeas() const
|
|
{
|
|
Tuple* actJunct = GetTuple();
|
|
double result = 0.0;
|
|
if(m_bFirstRoute)
|
|
{
|
|
result =
|
|
((CcReal*)actJunct->GetAttribute(JUNCTION_ROUTE1_MEAS))->GetRealval();
|
|
}
|
|
else
|
|
{
|
|
result =
|
|
((CcReal*)actJunct->GetAttribute(JUNCTION_ROUTE2_MEAS))->GetRealval();
|
|
}
|
|
actJunct->DeleteIfAllowed();
|
|
return result;
|
|
}
|
|
|
|
double GetOtherRouteMeas() const
|
|
{
|
|
Tuple* actJunct = GetTuple();
|
|
double result = 0.0;
|
|
if(m_bFirstRoute)
|
|
{
|
|
result =
|
|
((CcReal*)actJunct->GetAttribute(JUNCTION_ROUTE2_MEAS))->GetRealval();
|
|
}
|
|
else
|
|
{
|
|
result =
|
|
((CcReal*)actJunct->GetAttribute(JUNCTION_ROUTE1_MEAS))->GetRealval();
|
|
}
|
|
actJunct->DeleteIfAllowed();
|
|
return result;
|
|
}
|
|
|
|
int GetRouteId() const{
|
|
Tuple* actJunct = GetTuple();
|
|
int result = 0;
|
|
if(m_bFirstRoute)
|
|
{
|
|
result =
|
|
((CcInt*)actJunct->GetAttribute(JUNCTION_ROUTE1_ID))->GetIntval();
|
|
}
|
|
else
|
|
{
|
|
result =
|
|
((CcInt*)actJunct->GetAttribute(JUNCTION_ROUTE2_ID))->GetIntval();
|
|
}
|
|
actJunct->DeleteIfAllowed();
|
|
return result;
|
|
}
|
|
|
|
int GetOtherRouteId() const {
|
|
Tuple* actJunct = GetTuple();
|
|
int result = 0;
|
|
if(m_bFirstRoute)
|
|
{
|
|
result =
|
|
((CcInt*)actJunct->GetAttribute(JUNCTION_ROUTE2_ID))->GetIntval();
|
|
}
|
|
else
|
|
{
|
|
result =
|
|
((CcInt*)actJunct->GetAttribute(JUNCTION_ROUTE1_ID))->GetIntval();
|
|
}
|
|
actJunct->DeleteIfAllowed();
|
|
return result;
|
|
}
|
|
|
|
TupleId GetUpSectionId() const
|
|
{
|
|
Tuple* actJunct = GetTuple();
|
|
TupleId result = 0;
|
|
if(m_bFirstRoute)
|
|
{
|
|
result =
|
|
((TupleIdentifier*) actJunct->GetAttribute(JUNCTION_SECTION_AUP_RC)
|
|
)->GetTid();
|
|
}
|
|
else
|
|
{
|
|
result =
|
|
((TupleIdentifier*)actJunct->GetAttribute(JUNCTION_SECTION_BUP_RC)
|
|
)->GetTid();
|
|
}
|
|
actJunct->DeleteIfAllowed();
|
|
return result;
|
|
}
|
|
|
|
TupleId GetDownSectionId() const
|
|
{
|
|
Tuple* actJunct = GetTuple();
|
|
TupleId result = 0;
|
|
if(m_bFirstRoute)
|
|
{
|
|
result =
|
|
((TupleIdentifier*) actJunct->GetAttribute(JUNCTION_SECTION_ADOWN_RC)
|
|
)->GetTid();
|
|
}
|
|
else
|
|
{
|
|
result =
|
|
((TupleIdentifier*)actJunct->GetAttribute(JUNCTION_SECTION_BDOWN_RC)
|
|
)->GetTid();
|
|
}
|
|
actJunct->DeleteIfAllowed();
|
|
return result;
|
|
}
|
|
|
|
std::ostream& Print(std::ostream& os) const
|
|
{
|
|
os << "JunctionTidSortEntry: ";
|
|
if (m_bFirstRoute) os << "firstRoute";
|
|
else os << "secondRoute";
|
|
os << ", TupleId: " << m_pJunction << endl;
|
|
return os;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
4.2.9 Class ~Network~
|
|
|
|
Central object of network concept. All other positions are given related to a
|
|
network object.
|
|
|
|
*/
|
|
class Network
|
|
{
|
|
public:
|
|
|
|
/*
|
|
|
|
4.2.9.1 The public methods of the class ~network~
|
|
|
|
The internal and external (they are equal) ~routes~ relation type info
|
|
as string.
|
|
|
|
*/
|
|
|
|
static std::string routesTypeInfo;
|
|
|
|
|
|
/*
|
|
The B-Tree in the ~routes~ relation type info as string.
|
|
|
|
*/
|
|
|
|
static std::string routesBTreeTypeInfo;
|
|
|
|
/*
|
|
The R-Tree in the ~routes~ relation type info as string.
|
|
|
|
*/
|
|
|
|
static std::string routesRTreeTypeInfo;
|
|
|
|
/*
|
|
The B-Tree in the ~junctions~ relation type info as string.
|
|
|
|
*/
|
|
|
|
static std::string junctionsBTreeTypeInfo;
|
|
|
|
|
|
/*
|
|
The external ~junctions~ relation type info as string.
|
|
|
|
*/
|
|
|
|
static std::string junctionsTypeInfo;
|
|
|
|
/*
|
|
The internal ~junctions~ relation type info as string.
|
|
|
|
*/
|
|
|
|
static std::string junctionsInternalTypeInfo;
|
|
|
|
/*
|
|
The internal ~sections~ relation type info as string.
|
|
|
|
*/
|
|
|
|
static std::string sectionsInternalTypeInfo;
|
|
|
|
/*
|
|
The sectionsBTreeTypeInfo
|
|
|
|
*/
|
|
|
|
static std::string sectionsBTreeTypeInfo;
|
|
|
|
|
|
/*
|
|
~distancestoreageTypeInfo~ only used for experimental netdistance precomputing.
|
|
|
|
*/
|
|
static std::string distancestorageTypeInfo;
|
|
/*
|
|
|
|
4.2.9.2 Constructors of the class ~network~
|
|
|
|
The simple constructor.
|
|
|
|
*/
|
|
Network();
|
|
|
|
/*
|
|
Relation-Constuctor
|
|
|
|
The constructor that receives all information to create a network.
|
|
|
|
*/
|
|
Network(SmiRecord& in_xValueRecord,
|
|
size_t& inout_iOffset,
|
|
const ListExpr in_xTypeInfo);
|
|
|
|
/*
|
|
List-Constructor
|
|
|
|
The constructor that receives a list containing a network
|
|
|
|
*/
|
|
Network(ListExpr in_xValue,
|
|
int in_iErrorPos,
|
|
ListExpr& inout_xErrorInfo,
|
|
bool& inout_bCorrect);
|
|
|
|
/*
|
|
The destructor.
|
|
|
|
*/
|
|
~Network();
|
|
|
|
/*
|
|
|
|
4.2.9.3 Methods of the class ~network~
|
|
|
|
Destroy-Method
|
|
|
|
This function sets all information inside the network to be
|
|
destroyed when the destructor is called.
|
|
|
|
*/
|
|
void Destroy();
|
|
|
|
/*
|
|
Load-Method
|
|
|
|
Loads a network given two relations containing the routes and junctions.
|
|
This function corresponds to the operator ~thenetwork~.
|
|
|
|
*/
|
|
void Load(int in_iId, double scalef,
|
|
const Relation *in_pRoutes,
|
|
const Relation *in_pJunctions);
|
|
|
|
/*
|
|
Out-Method
|
|
|
|
Outputs a network
|
|
|
|
*/
|
|
ListExpr Out(ListExpr typeInfo);
|
|
|
|
/*
|
|
Save-Method
|
|
|
|
Saves all relations of the network
|
|
|
|
*/
|
|
ListExpr Save( SmiRecord& valueRecord,
|
|
size_t& offset,
|
|
const ListExpr typeInfo );
|
|
|
|
/*
|
|
Open-Method
|
|
|
|
Opens a network
|
|
|
|
*/
|
|
static Network* Open( SmiRecord& valueRecord,
|
|
size_t& offset,
|
|
const ListExpr typeInfo );
|
|
|
|
/*
|
|
The ~Out~, ~Save~, and ~Open~ functions of the type constructor ~network~.
|
|
The ~In~ function is not provided, given that the creation of the network
|
|
is only done via the ~thenetwork~ operator.
|
|
|
|
*/
|
|
|
|
|
|
/*
|
|
Method GetId
|
|
|
|
Returns the id of this network
|
|
|
|
*/
|
|
int GetId() const;
|
|
|
|
double GetScalefactor() const
|
|
{
|
|
return m_scalefactor;
|
|
}
|
|
|
|
/*
|
|
GetRoutes
|
|
|
|
Returns a copy of the ~routes~ relation in external representation.
|
|
This function is used in the ~routes~ operator.
|
|
|
|
*/
|
|
Relation *GetRoutes() const;
|
|
|
|
/*
|
|
GetJunctions
|
|
|
|
Returns a copy of the ~junctions~ relation in external representation.
|
|
This function is used in the ~junctions~ operator.
|
|
|
|
*/
|
|
Relation *GetJunctions() const;
|
|
|
|
/*
|
|
GetJunctionsOnRoute
|
|
|
|
Returns the junction from the start of the route to the end.
|
|
|
|
*/
|
|
void GetJunctionsOnRoute(CcInt* in_pRouteId,
|
|
std::vector<JunctionSortEntry>& inout_xJunctions) const;
|
|
|
|
void GetTidJunctionsOnRoute(CcInt* in_pRouteId,
|
|
std::vector<JunctionTidSortEntry>& io_xJunctions) const;
|
|
|
|
/*
|
|
Returns the section ~tuple~ of the network which includes the ~GPoint~.
|
|
Attention: The tupleId of the returned Tuple is not the TupleId in the sections
|
|
relation! If you need the correct tupleId of the sections relation use
|
|
~GetTupleIdSectionOnRoute~ instead.
|
|
|
|
*/
|
|
|
|
Tuple* GetSectionOnRoute(const GPoint* in_xGPoint) const;
|
|
|
|
/*
|
|
Returns the ~tupleid~ of the section which includes the ~GPoint~ .
|
|
|
|
*/
|
|
|
|
|
|
TupleId GetTupleIdSectionOnRoute(const GPoint* in_xGPoint) const;
|
|
|
|
/*
|
|
GetPointOnRoute
|
|
|
|
Returns the point value of the GPoint on the route. Used for translation of
|
|
network positions into spatial 2D positions.
|
|
|
|
*/
|
|
void GetPointOnRoute(const GPoint* in_xGPoint, Point *&res) const;
|
|
|
|
/*
|
|
GetRoute
|
|
|
|
Returns the route tuple for the given route id.
|
|
|
|
*/
|
|
|
|
Tuple* GetRoute(const int in_RouteId) const;
|
|
Tuple* GetRoute(const TupleId in_routeTID) const;
|
|
|
|
/*
|
|
GetRouteCurve
|
|
|
|
Returns the route curve for the given route id.
|
|
|
|
*/
|
|
|
|
SimpleLine GetRouteCurve(const int in_iRouteId) const;
|
|
|
|
/*
|
|
GetDual
|
|
|
|
Returns the dual value of the given route id.
|
|
|
|
*/
|
|
|
|
bool GetDual(const int in_iRouteId) const;
|
|
|
|
/*
|
|
GetLineValueOfRouteInterval
|
|
|
|
Returns the ~sline~ representing the ~RouteInterval~ in spatial data. Used
|
|
to translate network values into spatial 2D values.
|
|
|
|
*/
|
|
|
|
void GetLineValueOfRouteInterval(const RouteInterval* in_rI,
|
|
SimpleLine *out_line) const;
|
|
|
|
/*
|
|
GetSections
|
|
|
|
Returns a copy of the ~sections~ relation in external representation.
|
|
This function is used in the ~sections~ operator.
|
|
|
|
*/
|
|
Relation *GetSections() const;
|
|
|
|
/*
|
|
GetNetworkPosOfPoint
|
|
|
|
Returns a GPoint representing the point value in the network if possible, undef
|
|
elsewhere. Used to translate spatial 2D positions into network positions.
|
|
|
|
*/
|
|
|
|
GPoint* GetNetworkPosOfPoint(const Point p) const;
|
|
GPoint* GetNetworkPosOfPointOnRoute(const Point p, const int rid) const;
|
|
|
|
/*
|
|
GetSectionsInternal
|
|
|
|
Returns the ~sections~ relation (in internal representation).
|
|
|
|
*/
|
|
Relation *GetSectionsInternal() const;
|
|
|
|
/*
|
|
Method GetAdjacentSection
|
|
Returns a vector of sections which can be reached next upwards respectively
|
|
downwards bool from the section given by TupleId.
|
|
|
|
*/
|
|
|
|
void GetAdjacentSections(const TupleId in_iSectionId,
|
|
const bool in_bUpDown,
|
|
std::vector<DirectedSection> &inout_xSections) const;
|
|
|
|
void GetAdjacentSections(const int sectId, const bool upDown,
|
|
DbArray<SectionValue> *resArray) const;
|
|
|
|
void GetReverseAdjacentSections(const TupleId in_iSectionId,
|
|
const bool in_bUpDown,
|
|
std::vector<DirectedSection> &inout_xSections)
|
|
const;
|
|
|
|
void GetReverseAdjacentSections(const int sectId,
|
|
const bool upDown,
|
|
DbArray<SectionValue> *resArray)
|
|
const;
|
|
|
|
/*
|
|
GetSections on RouteInterval.
|
|
|
|
Returns a set of sections which are covered by the given ~RouteInterval~
|
|
~inri~ as ~DbArray~ of SectTreeEntries.
|
|
|
|
*/
|
|
|
|
void GetSectionsOfRouteInterval(const RouteInterval *in_ri,
|
|
std::vector<SectTreeEntry>& io_SectionIds) const;
|
|
|
|
void GetSectionsOfRoutInterval(const RouteInterval *in_ri,
|
|
std::vector<TupleId> &res) const;
|
|
|
|
/*
|
|
Get Routeinterval for Halfsegment defined by point interval. Used to translate
|
|
spatial 2D values into network values.
|
|
|
|
*/
|
|
|
|
RouteInterval* Find(const Point p1, const Point p2) const;
|
|
|
|
/*
|
|
Get Routepart passed limited by the two points.
|
|
|
|
*/
|
|
|
|
RouteInterval* FindInterval(const Point p1, const Point p2) const;
|
|
|
|
|
|
/*
|
|
Computes the junction of the two given routes and returns the route measure
|
|
values of the junction on this routes.
|
|
|
|
*/
|
|
|
|
void GetJunctionMeasForRoutes( CcInt *pLastRouteId,
|
|
CcInt *pCurrentSectionRid,
|
|
double& rid1meas, double& rid2meas) const;
|
|
|
|
/*
|
|
Returns the section with the given id.
|
|
|
|
*/
|
|
Tuple* GetSection(const TupleId n) const ;
|
|
|
|
void FindSP(const TupleId j1, const TupleId j2,
|
|
double& length, GLine* res) const;
|
|
/*
|
|
4.2.9.4 Secondo Integration Methods of Class ~Network~
|
|
|
|
NetworkProp
|
|
|
|
*/
|
|
static ListExpr NetworkProp();
|
|
|
|
/*
|
|
OutNetwork
|
|
|
|
*/
|
|
static ListExpr OutNetwork(ListExpr typeInfo, Word value);
|
|
|
|
/*
|
|
InNetwork
|
|
|
|
*/
|
|
static Word InNetwork(ListExpr in_xTypeInfo,
|
|
ListExpr in_xValue,
|
|
int in_iErrorPos,
|
|
ListExpr& inout_xErrorInfo,
|
|
bool& inout_bCorrect);
|
|
|
|
/*
|
|
CreateNetwork
|
|
|
|
*/
|
|
static Word CreateNetwork(const ListExpr typeInfo);
|
|
|
|
/*
|
|
CloseNetwork
|
|
|
|
*/
|
|
static void CloseNetwork(const ListExpr typeInfo, Word& w);
|
|
|
|
/*
|
|
CloneNetwork
|
|
|
|
*/
|
|
static Word CloneNetwork(const ListExpr typeInfo, const Word& w);
|
|
|
|
/*
|
|
DeleteNetwork
|
|
|
|
*/
|
|
static void DeleteNetwork(const ListExpr typeInfo, Word& w);
|
|
|
|
/*
|
|
CheckNetwork
|
|
|
|
*/
|
|
static bool CheckNetwork(ListExpr type, ListExpr& errorInfo);
|
|
|
|
/*
|
|
CastNetwork
|
|
|
|
*/
|
|
static void* CastNetwork(void* addr);
|
|
|
|
/*
|
|
SaveNetwork
|
|
|
|
*/
|
|
static bool SaveNetwork( SmiRecord& valueRecord,
|
|
size_t& offset,
|
|
const ListExpr typeInfo,
|
|
Word& value );
|
|
|
|
/*
|
|
OpenNetwork
|
|
|
|
*/
|
|
static bool OpenNetwork( SmiRecord& valueRecord,
|
|
size_t& offset,
|
|
const ListExpr typeInfo,
|
|
Word& value );
|
|
|
|
/*
|
|
SizeOfNetwork
|
|
|
|
*/
|
|
static int SizeOfNetwork();
|
|
|
|
/*
|
|
isDefined
|
|
|
|
*/
|
|
|
|
int IsDefined() const;
|
|
|
|
void SetDefined(const bool def)
|
|
{
|
|
m_bDefined = def;
|
|
};
|
|
|
|
|
|
void GetTupleIdSectionOnRouteJun(const GPoint* in_xGPoint,
|
|
std::vector<TupleId>&) const;
|
|
inline int GetNoJunctions() const
|
|
{
|
|
return m_pJunctions->GetNoTuples();
|
|
}
|
|
|
|
inline int GetNoRoutes() const
|
|
{
|
|
return m_pRoutes->GetNoTuples();
|
|
}
|
|
|
|
inline int GetNoSections() const
|
|
{
|
|
return m_pSections->GetNoTuples();
|
|
}
|
|
|
|
R_Tree<2,TupleId>* GetRTree(){ return m_pRTreeRoutes;}
|
|
|
|
inline static const std::string BasicType() { return "network"; }
|
|
|
|
static const bool checkType(const ListExpr type){
|
|
return listutils::isSymbol(type, BasicType());
|
|
}
|
|
|
|
inline Rectangle<2> BoundingBox() const{
|
|
return m_pRTreeRoutes->BoundingBox();
|
|
}
|
|
|
|
private:
|
|
|
|
|
|
/*
|
|
4.2.9.5 Private methods of class ~Network~
|
|
|
|
FillRoutes
|
|
|
|
Copies the relation given as argument to the ~routes~ relations sorted by
|
|
the ~id~ attribute and creates the B-Tree in this attribute.
|
|
|
|
*/
|
|
void FillRoutes( const Relation *in_pRoutes );
|
|
|
|
void CreateRoutesIndexes();
|
|
|
|
/*
|
|
FillJunctions
|
|
|
|
Copies the relation given as argument to the ~junctions~ relation appending
|
|
the new attributes.
|
|
|
|
*/
|
|
void FillJunctions( const Relation *in_pJunctions );
|
|
|
|
/*
|
|
FillSections
|
|
|
|
Given the ~routes~ and ~junctions~ relation, the ~sections~ relation
|
|
is retrieved.
|
|
|
|
*/
|
|
void FillSections();
|
|
|
|
/*
|
|
FillAdjacencyLists
|
|
|
|
Given that all relations are set up, the adjacency lists are created.
|
|
|
|
*/
|
|
void FillAdjacencyLists();
|
|
|
|
void FillAdjacencyPair(const TupleId in_pFirstSection,
|
|
const bool in_bFirstUp,
|
|
const TupleId in_pSecondSection,
|
|
const bool in_bSecondUp,
|
|
const ConnectivityCode in_xCc,
|
|
const Transition in_xTransition,
|
|
std::vector<DirectedSectionPair> &inout_xPairs);
|
|
|
|
void FillReverseAdjacencyPair (const TupleId in_pFirstSection,
|
|
const bool in_bFirstUp,
|
|
const TupleId in_pSecondSection,
|
|
const bool in_bSecondUp,
|
|
const ConnectivityCode in_xCc,
|
|
const Transition in_xTransition,
|
|
std::vector<DirectedSectionPair> &inout_xPairs);
|
|
|
|
/*
|
|
Used for experiments with network distance computation to store precomputed
|
|
distances. Because of the big data overhead and computation time this methods
|
|
and parameters should not be used if not needed. Therefore their calls are
|
|
comment out in the code. Of network constructors.
|
|
|
|
*/
|
|
|
|
void FillDistanceStorage();
|
|
|
|
/*
|
|
Helpful functions for Find respectively FindInterval. Tests Network if there
|
|
is a shorter connection between the two points p1 and p2 than given by
|
|
start, end.
|
|
Function doubled because FindInterval is used for ~mpoint~ to ~mgpoint~
|
|
translation and therefore the values of end and start respectively
|
|
dpos and dpos2 may not be changed to each other than it is done in Find
|
|
for ~gline~ ~routeInterval~.
|
|
|
|
*/
|
|
|
|
bool ShorterConnection(Tuple *route, double &start,
|
|
double &end, double &dpos, double &dpos2, int &rid,
|
|
int &ridt, Point p1, Point p2 ) const;
|
|
|
|
bool ShorterConnection2(Tuple *route, double &start,
|
|
double &end, double &dpos, double &dpos2, int &rid,
|
|
int &ridt, Point p1, Point p2 ) const ;
|
|
|
|
bool InShortestPath(GPoint* start, GPoint* end, GLine *result) const;
|
|
|
|
|
|
/*
|
|
4.2.9.6 Private fields of Class ~Network~
|
|
|
|
The ID of the network
|
|
|
|
*/
|
|
int m_iId;
|
|
|
|
/*
|
|
MapMatching needs information about dimension of data values.
|
|
The scalefactor 1.0 tells, position of meter is right in front of the decimal
|
|
point. 0.001 tells the position of meter in the coordinates is at the third
|
|
position behind the decimal point.
|
|
|
|
*/
|
|
|
|
double m_scalefactor;
|
|
|
|
/*
|
|
True if all values of this network have been defined
|
|
|
|
*/
|
|
int m_bDefined;
|
|
|
|
|
|
/*
|
|
The ~routes~ relation.
|
|
|
|
*/
|
|
Relation* m_pRoutes;
|
|
|
|
/*
|
|
The ~junctions~ relation.
|
|
|
|
*/
|
|
Relation* m_pJunctions;
|
|
|
|
/*
|
|
The ~sections~ relation.
|
|
|
|
*/
|
|
Relation* m_pSections;
|
|
|
|
/*
|
|
The BTree in the ~routes~ relation.
|
|
|
|
*/
|
|
BTree* m_pBTreeRoutes;
|
|
|
|
/*
|
|
The BTree in the ~routes~ relation.
|
|
|
|
*/
|
|
|
|
R_Tree<2,TupleId> *m_pRTreeRoutes;
|
|
|
|
/*
|
|
The RTree in the ~routes~ relation
|
|
|
|
*/
|
|
BTree* m_pBTreeJunctionsByRoute1;
|
|
|
|
/*
|
|
The BTree in the ~junctions~ relation.
|
|
|
|
*/
|
|
BTree* m_pBTreeJunctionsByRoute2;
|
|
|
|
|
|
/*
|
|
The adjacency lists of sections.
|
|
|
|
*/
|
|
|
|
DbArray<AdjacencyListEntry> m_xAdjacencyList;
|
|
|
|
DbArray<DirectedSection> m_xSubAdjacencyList;
|
|
|
|
/*
|
|
The reverse adjacency lists of sections.
|
|
|
|
*/
|
|
|
|
DbArray<AdjacencyListEntry> m_reverseAdjacencyList;
|
|
DbArray<DirectedSection> m_reverseSubAdjancencyList;
|
|
|
|
/*
|
|
The BTree of the sections route ids.
|
|
|
|
*/
|
|
|
|
BTree* m_pBTreeSectionsByRoute;
|
|
|
|
/*
|
|
Stores the precomputed distances between every possible pair of two junction
|
|
points. Only for experimental use in network distance computing. Comment out
|
|
in the code if not needed the computational and storage space overhead is to
|
|
big.
|
|
|
|
*/
|
|
|
|
Relation* alldistance;
|
|
|
|
};
|
|
|
|
|
|
/*
|
|
5 class ~gline~
|
|
|
|
*/
|
|
|
|
|
|
class GLine : public Attribute
|
|
{
|
|
/*
|
|
5.1 Constructors and Destructor
|
|
|
|
The simple constructor. Should not be used.
|
|
|
|
*/
|
|
public:
|
|
GLine();
|
|
|
|
/*
|
|
~iniSize~ gives the number of expected ~RouteIntervals~. If it is to small
|
|
the size of the ~DbArray~ is dynamically extended later.
|
|
|
|
*/
|
|
GLine(const int in_iSize);
|
|
|
|
GLine(const GLine* in_xOther);
|
|
|
|
GLine(const bool def);
|
|
|
|
GLine(const int networkid, const bool sorted,
|
|
const DbArray<RouteInterval>* routeIntervals);
|
|
|
|
~GLine() {};
|
|
|
|
GLine( ListExpr in_xValue,
|
|
int in_iErrorPos,
|
|
ListExpr& inout_xErrorInfo,
|
|
bool& inout_bCorrect);
|
|
|
|
/*
|
|
5.2 Methods of class ~gline~
|
|
|
|
*/
|
|
|
|
std::ostream& Print( std::ostream& os ) const;
|
|
|
|
void SetNetworkId(const int in_iNetworkId);
|
|
|
|
void AddRouteInterval(const int in_iRouteId,
|
|
const double in_dStart,
|
|
const double in_dEnd);
|
|
|
|
void AddRouteInterval(const RouteInterval ri);
|
|
|
|
double GetLength () const;
|
|
void SetLength(const double l);
|
|
|
|
int GetNetworkId() const;
|
|
|
|
void Get(const int i, RouteInterval &ri) const;
|
|
|
|
int NoOfComponents() const;
|
|
|
|
bool IsSorted() const;
|
|
|
|
void SetSorted(const bool b);
|
|
|
|
DbArray<RouteInterval>* GetRouteIntervals() const ;
|
|
|
|
/*
|
|
Returns true if the gline includes at least one of the gpoints.
|
|
|
|
*/
|
|
bool Includes(const GPoints* gps) const;
|
|
bool Includes(const GPoints* gps, const Network* pNetwork) const;
|
|
|
|
|
|
/*
|
|
Computes the network distance of 2 glines.
|
|
|
|
*/
|
|
|
|
double Netdistance(const GLine* pgl2) const;
|
|
double Netdistance (const GLine* pgl2, const Network* pNetwork )const ;
|
|
|
|
double NetdistanceNew(const GLine* pgl2)const ;
|
|
double NetdistanceNew(const GLine* pgl2, const Network* pNetwork)const ;
|
|
|
|
double NetdistanceNew(const GPoint* pgl2)const ;
|
|
double NetdistanceNew(const GPoint* pgl2, const Network* pNetwork)const ;
|
|
|
|
double NetdistanceNew(const GPoints* pgl2) const;
|
|
double NetdistanceNew(const GPoints* pgl2, const Network* pNetwork)const ;
|
|
|
|
|
|
bool ShortestPathAStar(const GLine *to, GLine *result,
|
|
DbArray<TupleId>* touchedSects = 0)const ;
|
|
bool ShortestPathAStar(const GLine *to, GLine *result,
|
|
const Network* pNetwork,
|
|
DbArray<TupleId>* touchedSects = 0)const ;
|
|
|
|
bool ShortestPathAStar(const GPoint *to, GLine *result,
|
|
DbArray<TupleId>* touchedSects = 0)const ;
|
|
bool ShortestPathAStar(const GPoint *to, GLine *result,
|
|
const Network* pNetwork,
|
|
DbArray<TupleId>* touchedSects = 0)const ;
|
|
|
|
bool ShortestPathAStar(const GPoints *to, GLine *result,
|
|
DbArray<TupleId>* touchedSects = 0)const ;
|
|
bool ShortestPathAStar(const GPoints *to, GLine *result,
|
|
const Network* pNetwork,
|
|
DbArray<TupleId>* touchedSects = 0)const ;
|
|
|
|
bool ShortestPathBF(const GLine *pgl2, GLine *result,
|
|
DbArray<TupleId>* touchedSects)const ;
|
|
bool ShortestPathBF(const GLine *pgl2, GLine *result,
|
|
const Network *pNetwork,
|
|
DbArray<TupleId>* touchedSects)const ;
|
|
/*
|
|
Computes the euclidean distance of 2 glines.
|
|
|
|
*/
|
|
|
|
double Distance (const GLine* pgl2)const ;
|
|
|
|
/*
|
|
Computes the union of 2 glines.
|
|
|
|
*/
|
|
|
|
|
|
void Uniongl (const GLine* pgl2, GLine *res) const ;
|
|
|
|
/*
|
|
Translates a gline value into a line value.
|
|
|
|
*/
|
|
|
|
void Gline2line (Line *res)const ;
|
|
|
|
|
|
/*
|
|
Returns true if the glines intersect false elswhere.
|
|
|
|
*/
|
|
|
|
|
|
bool Intersects (const GLine* pgl) const ;
|
|
|
|
|
|
/*
|
|
Returns the Bounding GPoints of the GLine.
|
|
|
|
*/
|
|
|
|
void GetBGP(const Network* pNetwork, GPoints* result)const ;
|
|
void GetBGP(GPoints* result)const ;
|
|
|
|
void Clear();
|
|
|
|
GLine& operator=( const GLine& l );
|
|
|
|
bool operator== (const GLine& p) const;
|
|
|
|
/*
|
|
5.3 Secondo Integration
|
|
|
|
*/
|
|
|
|
static ListExpr Out( ListExpr typeInfo, Word value );
|
|
|
|
static Word In( const ListExpr typeInfo,
|
|
const ListExpr instance,
|
|
const int errorPos,
|
|
ListExpr& errorInfo,
|
|
bool& correct );
|
|
|
|
static Word Create( const ListExpr typeInfo );
|
|
|
|
static void Delete( const ListExpr typeInfo, Word& w );
|
|
|
|
static void Close( const ListExpr typeInfo, Word& w );
|
|
|
|
static Word CloneGLine( const ListExpr typeInfo,
|
|
const Word& w );
|
|
|
|
static void* Cast( void* addr );
|
|
|
|
int NumOfFLOBs() const;
|
|
|
|
Flob *GetFLOB( const int i );
|
|
|
|
static int SizeOf();
|
|
|
|
size_t Sizeof() const;
|
|
|
|
int Size() const;
|
|
|
|
static ListExpr Property();
|
|
|
|
static bool Check( ListExpr type, ListExpr& errorInfo );
|
|
|
|
int Compare(const Attribute*) const;
|
|
|
|
bool Adjacent(const Attribute*) const;
|
|
|
|
GLine* Clone() const;
|
|
|
|
size_t HashValue() const;
|
|
|
|
void CopyFrom(const Attribute*);
|
|
|
|
void TrimToSize()
|
|
{
|
|
m_xRouteIntervals.TrimToSize();
|
|
};
|
|
|
|
inline static const std::string BasicType() { return "gline"; }
|
|
static const bool checkType(const ListExpr type){
|
|
return listutils::isSymbol(type, BasicType());
|
|
}
|
|
|
|
bool Contains(const RouteInterval* ri, const double tolerance)const ;
|
|
bool Intersects(const RouteInterval* ri, const double tolerance)const ;
|
|
|
|
private:
|
|
|
|
/*
|
|
5.4 Private Fields of class ~gline~
|
|
|
|
The network id.
|
|
|
|
*/
|
|
|
|
int m_iNetworkId;
|
|
|
|
|
|
/*
|
|
Sorted Flag: True if route intervals of the gline are sorted.
|
|
|
|
*/
|
|
|
|
bool m_bSorted;
|
|
|
|
/*
|
|
Length of the gline.
|
|
|
|
*/
|
|
|
|
double m_dLength;
|
|
|
|
/*
|
|
The array of route intervals.
|
|
|
|
*/
|
|
|
|
DbArray<RouteInterval> m_xRouteIntervals;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
1.2.3 ~struct RITree~
|
|
|
|
Used to compress and sort ~RouteInterval~s. Because many operators take profit
|
|
from sorted ~RouteInterval~s. We sort and compress resulting ~DbArray~s of
|
|
~RouteInterval~s whenever it is possible.
|
|
|
|
*/
|
|
|
|
struct RITree {
|
|
|
|
RITree(){};
|
|
|
|
RITree( const int ri, const double pos1, const double pos2
|
|
, RITree *left = 0, RITree *right = 0){
|
|
m_iRouteId = ri;
|
|
m_dStart = pos1;
|
|
m_dEnd = pos2;
|
|
m_left = left;
|
|
m_right = right;
|
|
};
|
|
|
|
~RITree(){};
|
|
|
|
/*
|
|
Checks if in the ~RITree~ exist son intervals which are covered by the
|
|
previos changed interval of the father.
|
|
|
|
*/
|
|
|
|
double CheckTree(RITree& father, int rid, double pos1,
|
|
double pos2, bool bleft) {
|
|
if (rid < this->m_iRouteId) {
|
|
if (this->m_left != 0) {
|
|
return this->m_left->CheckTree(*this, rid, pos1, pos2, bleft);
|
|
} else {
|
|
if (bleft) return pos1;
|
|
else return pos2;
|
|
}
|
|
} else {
|
|
if (rid > this->m_iRouteId) {
|
|
if (this->m_right != 0) {
|
|
return this->m_right->CheckTree(*this, rid, pos1, pos2,bleft);
|
|
} else {
|
|
if (bleft) return pos1;
|
|
else return pos2;
|
|
}
|
|
} else {
|
|
if (pos2 < this->m_dStart) {
|
|
if (this->m_left != 0) {
|
|
return this->m_left->CheckTree(*this, rid, pos1, pos2,bleft);
|
|
} else {
|
|
if (bleft) return pos1;
|
|
else return pos2;
|
|
}
|
|
} else {
|
|
if (pos1 > this->m_dEnd) {
|
|
if (this->m_right != 0 ) {
|
|
return this->m_right->CheckTree(*this, rid, pos1, pos2,bleft);
|
|
} else {
|
|
if (bleft) return pos1;
|
|
else return pos2;
|
|
}
|
|
} else {
|
|
// Overlapping interval found. Rebuild Tree and return new interval
|
|
// limit.
|
|
if (bleft) {
|
|
if (this->m_dStart <= pos1) {
|
|
pos1 = this->m_dStart;
|
|
}
|
|
if (father.m_left == this) {
|
|
father.m_left = this->m_left;
|
|
this->m_left = 0;
|
|
} else {
|
|
father.m_right = this->m_left;
|
|
this->m_left = 0;
|
|
}
|
|
this->RemoveTree();
|
|
if (father.m_left != 0) {
|
|
return father.m_left->CheckTree(father, rid, pos1, pos2, bleft);
|
|
} else {
|
|
return pos1;
|
|
}
|
|
} else {
|
|
if (this->m_dEnd >= pos2) {
|
|
pos2 = this->m_dEnd;
|
|
}
|
|
if (father.m_left == this) {
|
|
father.m_left = this->m_right;
|
|
this->m_right = 0;
|
|
} else {
|
|
father.m_right = this->m_right;
|
|
this->m_right = 0;
|
|
}
|
|
this->RemoveTree();
|
|
if (father.m_right != 0 ) {
|
|
return father.m_right->CheckTree(father, rid, pos1, pos2,bleft);
|
|
} else {
|
|
return pos2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (bleft) return pos1;
|
|
else return pos2;
|
|
};
|
|
|
|
/*
|
|
Inserts a ~RouteInterval~ in the ~RITree~ checking if there are already
|
|
~RouteIntervals~ which overlap or are adjacent to the current ~RouteInterval~.
|
|
|
|
*/
|
|
void InsertUnit(const int rid, const double pos1, const double pos2)
|
|
{
|
|
if (pos1 < pos2) Insert(rid, pos1, pos2);
|
|
else Insert(rid, pos2, pos1);
|
|
}
|
|
|
|
void Insert (const int rid, const double pos1, const double pos2) {
|
|
double test;
|
|
if (rid < this->m_iRouteId) {
|
|
if (this->m_left != 0) {
|
|
this->m_left->Insert(rid, pos1, pos2);
|
|
} else {
|
|
this->m_left = new RITree(rid, pos1, pos2,0,0);
|
|
}
|
|
} else {
|
|
if (rid > this->m_iRouteId) {
|
|
if (this->m_right != 0) {
|
|
this->m_right->Insert(rid, pos1, pos2);
|
|
} else {
|
|
this->m_right = new RITree(rid, pos1, pos2,0,0);
|
|
}
|
|
}else{
|
|
if(rid == this->m_iRouteId) {
|
|
if (pos2 < this->m_dStart) {
|
|
if (this->m_left != 0) {
|
|
this->m_left->Insert(rid, pos1, pos2);
|
|
} else {
|
|
this->m_left = new RITree(rid, pos1, pos2,0,0);
|
|
}
|
|
} else {
|
|
if (pos1 > this->m_dEnd) {
|
|
if (this->m_right != 0) {
|
|
this->m_right->Insert(rid, pos1, pos2);
|
|
} else {
|
|
this->m_right =
|
|
new RITree(rid, pos1, pos2,0,0);
|
|
}
|
|
} else {
|
|
// Overlapping route intervals merge and check sons if they need
|
|
// to be corrected too.
|
|
if (this->m_dStart > pos1) {
|
|
this->m_dStart = pos1;
|
|
if (this->m_left != 0) {
|
|
test = this->m_left->CheckTree(*this, rid, this->m_dStart,
|
|
this->m_dEnd, true);
|
|
if (this->m_dStart > test) {
|
|
this->m_dStart = test;
|
|
}
|
|
}
|
|
}
|
|
if (this->m_dEnd < pos2) {
|
|
this->m_dEnd = pos2;
|
|
if (this->m_right != 0) {
|
|
test = this->m_right->CheckTree(*this, rid, this->m_dStart,
|
|
this->m_dEnd, false);
|
|
if (this->m_dEnd < test) {
|
|
this->m_dEnd = test;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} // endif rid=rid
|
|
}
|
|
}
|
|
};
|
|
|
|
/*
|
|
Stores the ~RouteInterval~s of the ~RITree~ sorted by their route ids and
|
|
start positions into ~gline~.
|
|
|
|
*/
|
|
|
|
void TreeToGLine (GLine* gline) const {
|
|
if (this->m_left != 0) {
|
|
this->m_left->TreeToGLine (gline);
|
|
}
|
|
gline->AddRouteInterval(this->m_iRouteId, this->m_dStart, this->m_dEnd);
|
|
if (this->m_right != 0) {
|
|
this->m_right->TreeToGLine (gline);
|
|
}
|
|
};
|
|
|
|
/*
|
|
Stores the ~RouteInterval~s of the ~RITree~ sorted by their route ids and
|
|
start positions into a ~DbArray~. Used to build trajectory of ~mgpoint~.
|
|
|
|
*/
|
|
|
|
void TreeToDbArray (DbArray<RouteInterval>* arr) const {
|
|
if (this->m_left != 0) {
|
|
this->m_left->TreeToDbArray (arr);
|
|
}
|
|
arr->Append(RouteInterval(this->m_iRouteId, this->m_dStart, this->m_dEnd));
|
|
if (this->m_right != 0) {
|
|
this->m_right->TreeToDbArray (arr);
|
|
}
|
|
};
|
|
|
|
/*
|
|
Deletes the tree.
|
|
|
|
*/
|
|
void RemoveTree(){
|
|
if (m_left != 0) m_left->RemoveTree();
|
|
if (m_right != 0) m_right->RemoveTree();
|
|
delete this;
|
|
};
|
|
|
|
std::ostream& Print ( std::ostream& os ) const
|
|
{
|
|
os << "Root: rid: " << m_iRouteId ;
|
|
os << ", small: " << m_dStart ;
|
|
os << ", big: " << m_dEnd << endl;
|
|
os << "left son: ";
|
|
if (m_left != 0) m_left->Print(os);
|
|
else os << "not defined" << endl;
|
|
os << "right son: ";
|
|
if (m_right != 0) m_right->Print(os);
|
|
else os << "not defined" << endl;
|
|
os << endl;
|
|
return os;
|
|
}
|
|
|
|
int m_iRouteId;
|
|
double m_dStart, m_dEnd;
|
|
RITree *m_left, *m_right;
|
|
};
|
|
|
|
/*
|
|
struct RouteIntervalEntry
|
|
|
|
EntryType for RITreeP
|
|
|
|
*/
|
|
|
|
struct RouteIntervalEntry
|
|
{
|
|
RouteIntervalEntry(){};
|
|
|
|
RouteIntervalEntry(const RouteIntervalEntry& rie)
|
|
{
|
|
ri = rie.ri;
|
|
left = rie.left;
|
|
right = rie.right;
|
|
}
|
|
|
|
RouteIntervalEntry(const RouteInterval& rin, int l = -1, int r = -1)
|
|
{
|
|
ri = rin;
|
|
left = l;
|
|
right = r;
|
|
}
|
|
|
|
RouteIntervalEntry( const int rid, const double pos1, const double pos2,
|
|
const int l = -1, const int r = -1)
|
|
{
|
|
ri = RouteInterval(rid, pos1, pos2);
|
|
left = l;
|
|
right = r;
|
|
};
|
|
|
|
~RouteIntervalEntry(){};
|
|
|
|
std::ostream& Print(std::ostream& os) const
|
|
{
|
|
os << "RouteInterval:";
|
|
ri.Print(os);
|
|
os << ", left: " << left << ", right: " << right << endl;
|
|
return os;
|
|
}
|
|
|
|
void operator=(const RouteIntervalEntry& rie)
|
|
{
|
|
ri = rie.ri;
|
|
left = rie.left;
|
|
right = rie.right;
|
|
}
|
|
|
|
inline RouteInterval GetEntry() const
|
|
{
|
|
return ri;
|
|
}
|
|
|
|
inline int GetLeft() const
|
|
{
|
|
return left;
|
|
}
|
|
|
|
inline int GetRight() const
|
|
{
|
|
return right;
|
|
}
|
|
|
|
inline void SetLeft(const int l)
|
|
{
|
|
left = l;
|
|
}
|
|
|
|
inline void SetRight(const int r)
|
|
{
|
|
right = r;
|
|
}
|
|
|
|
inline void SetEntry(const int select, const double value)
|
|
{
|
|
switch(select)
|
|
{
|
|
case(0):
|
|
ri.SetRouteId((int) value);
|
|
break;
|
|
|
|
case(1):
|
|
ri.SetStartPos(value);
|
|
break;
|
|
|
|
case(2):
|
|
ri.SetEndPos(value);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
RouteInterval ri;
|
|
int left, right;
|
|
};
|
|
|
|
/*
|
|
struct RITreeP
|
|
|
|
Almost the same like RITree but with memory independent data structure.auto
|
|
|
|
*/
|
|
|
|
struct RITreeP
|
|
{
|
|
RITreeP():ritreep(0)
|
|
{
|
|
firstFree = 0;
|
|
}
|
|
|
|
RITreeP(const int n):ritreep(n)
|
|
{
|
|
firstFree = 0;
|
|
}
|
|
|
|
~RITreeP(){};
|
|
|
|
void Destroy()
|
|
{
|
|
ritreep.Destroy();
|
|
};
|
|
|
|
bool IsEmpty() const
|
|
{
|
|
return (firstFree == 0);
|
|
}
|
|
|
|
std::ostream& Print(std::ostream& os) const
|
|
{
|
|
return Print(os, 0);
|
|
|
|
}
|
|
|
|
std::ostream& Print(std::ostream&os, int pos) const
|
|
{
|
|
if (!IsEmpty() && -1 < pos && pos < firstFree){
|
|
RouteIntervalEntry rie;
|
|
ritreep.Get(pos, rie);
|
|
os << "Root: ";
|
|
rie.GetEntry().Print(os);
|
|
os << "left son: ";
|
|
if (rie.GetLeft() > -1) Print(os, rie.GetLeft());
|
|
else os << "not defined" << endl;
|
|
os << "right son: ";
|
|
if (rie.GetRight() > -1) Print(os, rie.GetRight());
|
|
else os << "not defined" << endl;
|
|
os << endl;
|
|
return os;
|
|
}
|
|
return os;
|
|
}
|
|
|
|
/*
|
|
Checks if in the ~RITree~ exist son intervals which are covered by the
|
|
previos changed interval of the father.
|
|
|
|
*/
|
|
|
|
double CheckTree(RouteIntervalEntry& father, const int posfather,
|
|
RouteIntervalEntry& testRI, const int postest,
|
|
const bool bleft)
|
|
{
|
|
assert(postest > -1 && postest < firstFree &&
|
|
posfather > -1 && posfather < firstFree);
|
|
RouteIntervalEntry test;
|
|
ritreep.Get(postest,test);
|
|
if (testRI.GetEntry().GetRouteId() < test.GetEntry().GetRouteId())
|
|
{
|
|
if (test.GetLeft() > -1)
|
|
return CheckTree(test, postest, testRI, test.GetLeft(), bleft);
|
|
else
|
|
return testRI.GetEntry().GetValue(bleft);
|
|
}
|
|
else
|
|
{
|
|
if (testRI.GetEntry().GetRouteId() > test.GetEntry().GetRouteId())
|
|
{
|
|
if (test.GetRight() > -1)
|
|
return CheckTree(test, postest, testRI, test.GetRight(), bleft);
|
|
else
|
|
return testRI.GetEntry().GetValue(bleft);
|
|
}
|
|
else
|
|
{
|
|
if (testRI.GetEntry().GetEndPos() < test.GetEntry().GetStartPos())
|
|
{
|
|
if (test.GetLeft() > -1)
|
|
return CheckTree(test, postest, testRI, test.GetLeft(), bleft);
|
|
else
|
|
return testRI.GetEntry().GetValue(bleft);
|
|
}
|
|
else
|
|
{
|
|
if (testRI.GetEntry().GetStartPos() > test.GetEntry().GetEndPos())
|
|
{
|
|
if (test.GetRight() > -1 )
|
|
return CheckTree(test, postest, testRI, test.GetRight(), bleft);
|
|
else
|
|
return testRI.GetEntry().GetValue(bleft);
|
|
}
|
|
else
|
|
{
|
|
// Overlapping interval found. Rebuild Tree and return new interval
|
|
// limit.
|
|
if (bleft)
|
|
{
|
|
if (test.GetEntry().GetStartPos() <
|
|
testRI.GetEntry().GetStartPos())
|
|
testRI.SetEntry(1,test.GetEntry().GetStartPos());
|
|
if (father.GetLeft() == postest)
|
|
{
|
|
father.SetLeft(test.GetLeft());
|
|
ritreep.Put(posfather,father);
|
|
test.SetLeft(-1);
|
|
ritreep.Put(postest,test);
|
|
}
|
|
else
|
|
{
|
|
father.SetRight(test.GetLeft());
|
|
ritreep.Put(posfather,father);
|
|
test.SetLeft(-1);
|
|
ritreep.Put(postest,test);
|
|
}
|
|
if (father.GetLeft() > -1)
|
|
return CheckTree(father, posfather, testRI, father.GetLeft(),
|
|
bleft);
|
|
else
|
|
return testRI.GetEntry().GetStartPos();
|
|
}
|
|
else
|
|
{
|
|
if (test.GetEntry().GetEndPos() > testRI.GetEntry().GetEndPos())
|
|
testRI.SetEntry(2, test.GetEntry().GetEndPos());
|
|
if (father.GetLeft() == postest)
|
|
{
|
|
father.SetLeft(test.GetRight());
|
|
ritreep.Put(posfather,father);
|
|
test.SetRight(-1);
|
|
ritreep.Put(postest,test);
|
|
}
|
|
else
|
|
{
|
|
father.SetRight(test.GetRight());
|
|
ritreep.Put(posfather,father);
|
|
test.SetRight(-1);
|
|
ritreep.Put(postest,test);
|
|
}
|
|
if (father.GetRight() > -1 )
|
|
return CheckTree(father, posfather, testRI, father.GetRight(),
|
|
bleft);
|
|
else
|
|
return testRI.GetEntry().GetEndPos();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return testRI.GetEntry().GetValue(bleft);
|
|
};
|
|
|
|
|
|
/*
|
|
Inserts a ~RouteInterval~ in the ~RITree~ checking if there are already
|
|
~RouteIntervals~ which overlap or are adjacent to the current ~RouteInterval~.
|
|
|
|
*/
|
|
void InsertUnit(const int rid, const double pos1, const double pos2)
|
|
{
|
|
if (pos1 <= pos2) Insert(rid, pos1, pos2, 0);
|
|
else Insert(rid, pos2, pos1, 0);
|
|
}
|
|
|
|
void Insert (const bool left, const int pos, RouteIntervalEntry& testRI,
|
|
const int r, const double p1, const double p2)
|
|
{
|
|
if (left) testRI.SetLeft(firstFree);
|
|
else testRI.SetRight(firstFree);
|
|
ritreep.Put(pos,testRI);
|
|
ritreep.Put(firstFree, RouteIntervalEntry(RouteInterval(r, p1, p2),
|
|
-1,-1));
|
|
firstFree++;
|
|
}
|
|
|
|
void Insert(const RouteInterval ri)
|
|
{
|
|
Insert(ri.GetRouteId(), ri.GetStartPos(), ri.GetEndPos());
|
|
}
|
|
|
|
void Insert (const int rid, const double p1, const double p2, int pos = 0)
|
|
{
|
|
double pos1 = p1;
|
|
double pos2 = p2;
|
|
if (p1 > p2) {
|
|
pos1 = p2;
|
|
pos2 = p1;
|
|
}
|
|
|
|
if (IsEmpty())
|
|
{
|
|
ritreep.Put(firstFree, RouteIntervalEntry(RouteInterval(rid,pos1,pos2),
|
|
-1,-1));
|
|
firstFree++;
|
|
}
|
|
else
|
|
{
|
|
RouteIntervalEntry testRI;
|
|
ritreep.Get(pos, testRI);
|
|
double test;
|
|
if (rid < testRI.GetEntry().GetRouteId())
|
|
{
|
|
if (testRI.GetLeft() > -1)
|
|
Insert(rid, pos1, pos2, testRI.GetLeft());
|
|
else
|
|
Insert(true, pos, testRI, rid, pos1, pos2);
|
|
}
|
|
else
|
|
{
|
|
if (rid > testRI.GetEntry().GetRouteId())
|
|
{
|
|
if (testRI.GetRight() > -1)
|
|
Insert(rid, pos1, pos2, testRI.GetRight());
|
|
else
|
|
Insert(false, pos, testRI, rid, pos1, pos2);
|
|
}
|
|
else
|
|
{
|
|
if (pos2 < testRI.GetEntry().GetStartPos())
|
|
{
|
|
if (testRI.GetLeft() > -1 )
|
|
Insert(rid, pos1, pos2, testRI.GetLeft());
|
|
else
|
|
Insert(true, pos, testRI, rid, pos1, pos2);
|
|
}
|
|
else
|
|
{
|
|
if (pos1 > testRI.GetEntry().GetEndPos())
|
|
{
|
|
if (testRI.GetRight() > -1)
|
|
Insert(rid, pos1, pos2, testRI.GetRight());
|
|
else
|
|
{
|
|
Insert(false, pos, testRI, rid, pos1, pos2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Overlapping route intervals merge and check sons if they need
|
|
// to be corrected too.
|
|
if (testRI.GetEntry().GetStartPos() > pos1)
|
|
{
|
|
testRI.SetEntry(1, pos1);
|
|
ritreep.Put(pos,testRI);
|
|
if (testRI.GetLeft() > -1)
|
|
{
|
|
test = CheckTree(testRI, pos, testRI, testRI.GetLeft(),true);
|
|
testRI.SetEntry(1,test);
|
|
ritreep.Put(pos,testRI);
|
|
}
|
|
}
|
|
if (testRI.GetEntry().GetEndPos() < pos2)
|
|
{
|
|
testRI.SetEntry(2,pos2);
|
|
ritreep.Put(pos,testRI);
|
|
if (testRI.GetRight() > -1)
|
|
{
|
|
test =
|
|
CheckTree(testRI, pos, testRI, testRI.GetRight(),false);
|
|
testRI.SetEntry(2,test);
|
|
ritreep.Put(pos,testRI);
|
|
|
|
}
|
|
}
|
|
}
|
|
} // endif rid=rid
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/*
|
|
Stores the ~RouteInterval~s of the ~RITree~ sorted by their route ids and
|
|
start positions into ~gline~.
|
|
|
|
*/
|
|
|
|
void TreeToGLine (GLine* gline, int pos) const
|
|
{
|
|
assert(pos >= 0 && pos < firstFree);
|
|
RouteIntervalEntry test;
|
|
ritreep.Get(pos, test);
|
|
if (test.GetLeft() > -1)
|
|
TreeToGLine(gline, test.GetLeft());
|
|
gline->AddRouteInterval(test.GetEntry());
|
|
if (test.GetRight() > -1)
|
|
TreeToGLine (gline, test.GetRight());
|
|
};
|
|
|
|
/*
|
|
Stores the ~RouteInterval~s of the ~RITree~ sorted by their route ids and
|
|
start positions into a ~DbArray~. Used to build trajectory of ~mgpoint~.
|
|
|
|
*/
|
|
|
|
void TreeToDbArray (DbArray<RouteInterval>* arr, int pos) const
|
|
{
|
|
assert(pos > -1 && pos < firstFree);
|
|
RouteIntervalEntry test;
|
|
ritreep.Get(pos,test);
|
|
if (test.GetLeft() > -1)
|
|
TreeToDbArray(arr, test.GetLeft());
|
|
arr->Append(test.GetEntry());
|
|
if (test.GetRight() > -1)
|
|
TreeToDbArray (arr, test.GetRight());
|
|
};
|
|
|
|
DbArray<RouteIntervalEntry> ritreep;
|
|
int firstFree;
|
|
};
|
|
|
|
class GPointsSections
|
|
{
|
|
public:
|
|
GPointsSections(){};
|
|
|
|
GPointsSections(const GPoint g, const TupleId t, const Point p)
|
|
: m_gp(g), m_tid(t), m_p(p)
|
|
{
|
|
};
|
|
|
|
~GPointsSections(){};
|
|
|
|
GPoint GetGP() const {return m_gp;};
|
|
|
|
TupleId GetTid() const {return m_tid;};
|
|
|
|
Point GetPoint() const {return m_p;};
|
|
|
|
std::ostream& Print(std::ostream& os) const
|
|
{
|
|
os << "GPoint: ";
|
|
m_gp.Print(os);
|
|
os << ", Point: ";
|
|
m_p.Print(os);
|
|
os << ", TupleId: " << (long int) m_tid << endl;
|
|
return os;
|
|
};
|
|
|
|
private:
|
|
GPoint m_gp;
|
|
TupleId m_tid;
|
|
Point m_p;
|
|
};
|
|
/*
|
|
6. class GPoints by Jianqiu Xu.
|
|
|
|
*/
|
|
|
|
extern std::string edistjoinpointlist;
|
|
|
|
class GPoints: public Attribute{
|
|
public:
|
|
GPoints();
|
|
GPoints(const int in_iSize);
|
|
GPoints(const bool defined);
|
|
GPoints(const GPoints* in_xOther);
|
|
~GPoints(){}
|
|
std::ostream& Print(std::ostream& os)const;
|
|
inline bool IsEmpty()const;
|
|
size_t Sizeof()const;
|
|
GPoints& operator+=(const GPoint &gp);
|
|
GPoints& operator-=(const GPoint &gp);
|
|
GPoints& operator=(const GPoints& otherGPoints);
|
|
int NumOfFLOBs()const;
|
|
Flob* GetFLOB(const int i);
|
|
void Get(int i, GPoint& gp)const;
|
|
inline int Size()const;
|
|
static int SizeOf();
|
|
static ListExpr Out(ListExpr typeInfo,Word value);
|
|
static Word In(const ListExpr typeInfo,const ListExpr instance,
|
|
const int errorPos,ListExpr& errorInfo,bool& correct);
|
|
static Word Create(const ListExpr typeInfo);
|
|
static void Delete(const ListExpr typeInfo,Word& w);
|
|
static void Close(const ListExpr typeInfo,Word& w);
|
|
static Word CloneGPoints(const ListExpr typeInfo,const Word& w);
|
|
static void* Cast(void* addr);
|
|
static ListExpr Property();
|
|
static bool Check(ListExpr type, ListExpr& errorInfo);
|
|
static bool SaveGPoints(SmiRecord& valueRecord,size_t& offset,
|
|
const ListExpr typeInfo, Word& value);
|
|
static bool OpenGPoints(SmiRecord& valueRecord,size_t& offset,
|
|
const ListExpr typeInfo, Word& value);
|
|
inline static const std::string BasicType() { return "gpoints"; }
|
|
static const bool checkType(const ListExpr type){
|
|
return listutils::isSymbol(type, BasicType());
|
|
}
|
|
int Compare(const Attribute*)const;
|
|
bool Adjacent(const Attribute*)const;
|
|
GPoints* Clone() const;
|
|
size_t HashValue()const;
|
|
void CopyFrom(const Attribute* right);
|
|
void FilterAliasGPoints(Network *pNetwork);
|
|
void TrimToSize () {m_xGPoints.TrimToSize();}
|
|
void MergeAdd(const GPoint gp, const Network* pNetwork);
|
|
bool Contains(const GPoint gp, const Network* pNetwork)const;
|
|
bool Contains(const GPoint gp)const;
|
|
double NetdistanceNew(const GPoints* bgp, const Network* pNetwork)const ;
|
|
double NetdistanceNew(const GPoints* bgp)const ;
|
|
double NetdistanceNew(const GPoint* gp, const Network* pNetwork)const ;
|
|
double NetdistanceNew(const GPoint* gp) const ;
|
|
double NetdistanceNew(const GLine* gl, const Network* pNetwork)const ;
|
|
double NetdistanceNew(const GLine* gl)const ;
|
|
int GetNetworkId()const ;
|
|
bool ShortestPathAStar(const GPoints* bgp, GLine* res,
|
|
DbArray<TupleId>* touchedSects = 0)const ;
|
|
bool ShortestPathAStar(const GPoints* bgp, GLine* res,
|
|
const Network* pNetwork,
|
|
DbArray<TupleId>* touchedSects = 0)const ;
|
|
bool ShortestPathAStar(const GPoint* gp, GLine* res,
|
|
DbArray<TupleId>* touchedSects = 0)const ;
|
|
bool ShortestPathAStar(const GPoint* gp, GLine* res,
|
|
const Network* pNetwork,
|
|
DbArray<TupleId>* touchedSects = 0)const ;
|
|
bool ShortestPathAStar(const GLine* gl, GLine* res,
|
|
DbArray<TupleId>* touchedSects = 0)const ;
|
|
bool ShortestPathAStar(const GLine* gl, GLine* res,
|
|
const Network* pNetwork,
|
|
DbArray<TupleId>* touchedSects = 0)const ;
|
|
bool Inside(const GPoint gp)const ;
|
|
bool Intersects(const GPoints* bgp, const Network* pNetwork)const;
|
|
bool Intersects(const GPoints* bgp)const ;
|
|
void Clear();
|
|
|
|
private:
|
|
void GetSectionTupleIds(DbArray<GPointsSections>* gpSections,
|
|
const Network* pNetwork)const ;
|
|
|
|
DbArray<GPoint> m_xGPoints;
|
|
};
|
|
|
|
} //end of namespace network
|
|
|
|
#endif // __NETWORK_ALGEBRA_H__
|