10877 lines
363 KiB
C++
10877 lines
363 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{] [}}]
|
|
//[TOC] [\tableofcontents]
|
|
|
|
1 Implementation of Algebra TemporalNet
|
|
|
|
May 2007 - October 2007 Martin Scheppokat
|
|
|
|
February 2008 - Simone Jandt
|
|
|
|
Defines, includes, and constants
|
|
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <string>
|
|
|
|
#include "../Relation-C++/RelationAlgebra.h"
|
|
#include "../BTree/BTreeAlgebra.h"
|
|
#include "../TupleIdentifier/TupleIdentifier.h"
|
|
#include "../Network/NetworkAlgebra.h"
|
|
#include "TemporalNetAlgebra.h"
|
|
#include "../Temporal/TemporalAlgebra.h"
|
|
#include "../Network/NetworkManager.h"
|
|
#include "../../Tools/Flob/DbArray.h"
|
|
#include "../../Tools/Flob/Flob.h"
|
|
#include "StandardTypes.h"
|
|
#include "ListUtils.h"
|
|
#include "Symbols.h"
|
|
#include "NestedList.h"
|
|
#include "QueryProcessor.h"
|
|
#include "Algebra.h"
|
|
#include "DateTime.h"
|
|
#include "ConstructorTemplates.h"
|
|
#include "TypeMapUtils.h"
|
|
#include "Operator.h"
|
|
#include "Symbols.h"
|
|
#include "../Rectangle/RectangleAlgebra.h"
|
|
|
|
|
|
|
|
|
|
extern NestedList* nl;
|
|
extern QueryProcessor* qp;
|
|
|
|
using namespace network;
|
|
using namespace temporalnet;
|
|
using namespace temporalalgebra;
|
|
using namespace std;
|
|
using namespace datetime;
|
|
|
|
map<int,string> *netList;
|
|
|
|
/*
|
|
|
|
1.1 Additional Methods
|
|
|
|
Returns true if the ~RouteInterval~ ~pRi~ is found in the set of ~rint~.
|
|
false elsewhere.
|
|
|
|
*/
|
|
bool searchUnit(const DbArray<RouteInterval> &rint, int low, int high,
|
|
RouteInterval pRi){
|
|
RouteInterval rI;
|
|
if (low <= high) {
|
|
int mid = (high + low) / 2;
|
|
int n = 0;
|
|
if (mid < n || mid >= rint.Size()) {
|
|
return false;
|
|
}else {
|
|
rint.Get(mid, rI);
|
|
if (rI.GetRouteId() < pRi.GetRouteId()) {
|
|
return searchUnit(rint, mid+1, high, pRi);
|
|
} else {
|
|
if (rI.GetRouteId() > pRi.GetRouteId()){
|
|
if (mid == n) return false;
|
|
else return searchUnit(rint, low, mid-1, pRi);
|
|
} else {
|
|
if (rI.GetStartPos() > pRi.GetEndPos()) {
|
|
if (mid == n) return false;
|
|
else return searchUnit(rint, low, mid-1, pRi);
|
|
} else {
|
|
if (rI.GetEndPos() < pRi.GetStartPos()){
|
|
return searchUnit(rint, mid+1, high, pRi);
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else return false;
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
Returns true if the two given sets of ~RouteIntervals~ at least intersect once.
|
|
|
|
*/
|
|
bool RIsIntersects(const DbArray<RouteInterval> &riint1,
|
|
const DbArray<RouteInterval> &riint2,
|
|
const bool sortedri1,
|
|
const bool sortedri2){
|
|
RouteInterval pRi1, pRi2;
|
|
if (!sortedri1) {
|
|
for (int i = 0; i < riint1.Size(); i++){
|
|
riint1.Get(i, pRi1);
|
|
if (sortedri2){
|
|
if (searchUnit(riint2, 0, riint2.Size()-1, pRi1)){
|
|
return true;
|
|
};
|
|
} else {
|
|
for (int j = 0 ; j < riint2.Size(); j++){
|
|
riint2.Get(j,pRi2);
|
|
if (pRi1.GetRouteId() == pRi2.GetRouteId() &&
|
|
(!(pRi1.GetEndPos() < pRi2.GetStartPos() ||
|
|
pRi2.GetStartPos() > pRi1.GetEndPos()))){
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (sortedri2) {
|
|
int i = 0;
|
|
int j = 0;
|
|
while (i<riint1.Size() && j < riint2.Size()) {
|
|
riint1.Get(i,pRi1);
|
|
riint2.Get(j,pRi2);
|
|
if (pRi1.GetRouteId() < pRi2.GetRouteId()) i++;
|
|
else
|
|
if (pRi1.GetRouteId() > pRi2.GetRouteId()) j++;
|
|
else
|
|
if (pRi1.GetStartPos() > pRi2.GetEndPos()) j++;
|
|
else
|
|
if (pRi1.GetEndPos() < pRi2.GetStartPos()) i++;
|
|
else return true;
|
|
}
|
|
} else {
|
|
for (int i = 0; i < riint2.Size(); i++){
|
|
riint2.Get(i, pRi2);
|
|
if (searchUnit(riint1, 0, riint1.Size()-1, pRi2)) return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
Returns true if a ~RouteInterval~ is found that contains the ~gpoint~
|
|
|
|
*/
|
|
bool searchRouteInterval(const GPoint *pGPoint,
|
|
const DbArray<RouteInterval> &tra,
|
|
int low, int high) {
|
|
RouteInterval rI;
|
|
if (low <= high) {
|
|
int mid = (high + low) / 2;
|
|
if ((mid < 0) || (mid >= tra.Size())) {
|
|
return false;
|
|
}else {
|
|
tra.Get(mid, rI);
|
|
if (rI.GetRouteId() < pGPoint->GetRouteId()) {
|
|
return searchRouteInterval(pGPoint, tra, mid+1, high);
|
|
} else {
|
|
if (rI.GetRouteId() > pGPoint->GetRouteId()){
|
|
return searchRouteInterval(pGPoint, tra, low, mid-1);
|
|
} else {
|
|
if (AlmostEqual(pGPoint->GetPosition(), rI.GetStartPos()) ||
|
|
AlmostEqual(pGPoint->GetPosition(), rI.GetEndPos())) {
|
|
return true;
|
|
} else {
|
|
if (rI.GetStartPos() > pGPoint->GetPosition()) {
|
|
return searchRouteInterval(pGPoint, tra, low, mid-1);
|
|
} else {
|
|
if (rI.GetEndPos() < pGPoint->GetPosition()){
|
|
return searchRouteInterval(pGPoint, tra, mid+1, high);
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
/*
|
|
Returns true if a ~RouteInterval~ is found that contains the ~gpoint~
|
|
|
|
*/
|
|
bool Includes(const DbArray<RouteInterval> &tra, const GPoint *gp){
|
|
if (tra.Size() < 1) return false;
|
|
return (searchRouteInterval(gp, tra, 0, tra.Size()-1));
|
|
}
|
|
|
|
/*
|
|
Sets parameter movingUp and side for the given Unit. Used by ~mpoint2mgpoint~.
|
|
|
|
*/
|
|
|
|
void setMoveAndSide(const double &startPos, const double &endPos,
|
|
bool &MovingUp,
|
|
const bool &dual, Side &side){
|
|
if (MovingUp && startPos <= endPos) { MovingUp = true;}
|
|
else {
|
|
if (MovingUp && startPos > endPos) { MovingUp = false;}
|
|
else {
|
|
if (!MovingUp && startPos < endPos) { MovingUp = true;}
|
|
else {
|
|
if (!MovingUp && startPos >= endPos) { MovingUp = false;}
|
|
}
|
|
}
|
|
}
|
|
if (dual && MovingUp) { side = Up;}
|
|
else {
|
|
if (dual && !MovingUp) { side = Down;}
|
|
else { side = None;}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Gets the parameter Values of the given ~upoint~.Used by
|
|
|
|
*/
|
|
|
|
void getUnitValues(const UPoint *curUnit,
|
|
Point &endPoint, Point &startPoint,
|
|
Instant &startTime, Instant &endTime,
|
|
double &lStartTime, double &lEndTime, double &duration)
|
|
{
|
|
startPoint = curUnit->p0;
|
|
endPoint = curUnit->p1;
|
|
startTime = curUnit->timeInterval.start;
|
|
lStartTime = startTime.ToDouble();
|
|
endTime = curUnit->timeInterval.end;
|
|
lEndTime = endTime.ToDouble();
|
|
duration = lEndTime - lStartTime;
|
|
}
|
|
|
|
/*
|
|
Checks sline value for the point and computes the position from the point on
|
|
the sline including difference value if not exactly on the sline. The problem
|
|
is caused by the gps value simulation which is mostly not exactly on the sline.
|
|
So that AtPosition and AtPoint could not find the point on the sline.
|
|
Returns true if the ~point~ is on the sline false elsewhere.
|
|
Used by ~mpoint2mgpoint~.
|
|
|
|
*/
|
|
|
|
bool checkPoint (const SimpleLine *route, const Point point,
|
|
const bool startSmaller,
|
|
double &pos, double &difference){
|
|
bool result = false;
|
|
HalfSegment hs;
|
|
double k1, k2;
|
|
Point left, right;
|
|
for (int i = 0; i < route->Size()-1; i++) {
|
|
route->Get(i, hs);
|
|
left = hs.GetLeftPoint();
|
|
right = hs.GetRightPoint();
|
|
Coord xl = left.GetX(),
|
|
yl = left.GetY(),
|
|
xr = right.GetX(),
|
|
yr = right.GetY(),
|
|
x = point.GetX(),
|
|
y = point.GetY();
|
|
if ((AlmostEqual(x,xr) && AlmostEqual (y,yr)) ||
|
|
(AlmostEqual(x,xl) && AlmostEqual (y,yl)))
|
|
{
|
|
difference = 0.0;
|
|
result = true;
|
|
} else {
|
|
if (xl != xr && xl != x) {
|
|
k1 = (y - yl) / (x - xl);
|
|
k2 = (yr - yl) / (xr - xl);
|
|
if ((fabs(k1-k2) < 0.004) &&
|
|
((xl < xr &&
|
|
(x > xl || AlmostEqual(x,xl)) &&
|
|
(x < xr || AlmostEqual(x,xr))) ||
|
|
(xl > xr &&
|
|
(x < xl || AlmostEqual(x,xl)) &&
|
|
(x > xr || AlmostEqual(x,xr)))) &&
|
|
(((yl < yr || AlmostEqual(yl,yr)) &&
|
|
(y > yl || AlmostEqual(y,yl)) &&
|
|
(y < yr || AlmostEqual(y,yr))) ||
|
|
(yl > yr &&
|
|
(y < yl || AlmostEqual(y,yl)) &&
|
|
(y > yr || AlmostEqual(y,yr)))))
|
|
{
|
|
difference = fabs(k1-k2);
|
|
result = true;
|
|
}
|
|
else {result = false;}
|
|
}
|
|
else
|
|
{
|
|
if (( AlmostEqual(xl, xr) && AlmostEqual(xl,x)) &&
|
|
(((yl < yr|| AlmostEqual(yl,yr)) &&
|
|
(yl < y || AlmostEqual(yl,y))&&
|
|
(y < yr ||AlmostEqual(y,yr)))||
|
|
(yl > yr &&
|
|
(yl > y || AlmostEqual(yl,y))&&
|
|
(y > yr || AlmostEqual(y,yr)))))
|
|
{
|
|
difference = 0.0;
|
|
result = true;
|
|
}
|
|
else {result = false;}
|
|
}
|
|
}
|
|
if (result) {
|
|
LRS lrs;
|
|
route->Get( hs.attr.edgeno, lrs );
|
|
route->Get( lrs.hsPos, hs );
|
|
pos = lrs.lrsPos + point.Distance( hs.GetDomPoint() );
|
|
if( startSmaller != route->GetStartSmaller())
|
|
pos = route->Length() - pos;
|
|
if( AlmostEqual(pos,0.0))
|
|
pos = 0.0;
|
|
else if (AlmostEqual(pos,route->Length()))
|
|
pos = route->Length();
|
|
return result;
|
|
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool checkPointN (const SimpleLine route, const Point point,
|
|
const bool startSmaller,
|
|
double &pos)
|
|
{
|
|
bool result = false;
|
|
HalfSegment hs;
|
|
double k1, k2;
|
|
Point left, right;
|
|
for (int i = 0; i < route.Size()-1; i++) {
|
|
route.Get(i, hs);
|
|
left = hs.GetLeftPoint();
|
|
right = hs.GetRightPoint();
|
|
Coord xl = left.GetX(),
|
|
yl = left.GetY(),
|
|
xr = right.GetX(),
|
|
yr = right.GetY(),
|
|
x = point.GetX(),
|
|
y = point.GetY();
|
|
if ((AlmostEqual(x,xr) && AlmostEqual (y,yr)) ||
|
|
(AlmostEqual(x,xl) && AlmostEqual (y,yl)))
|
|
result = true;
|
|
else
|
|
{
|
|
if (xl != xr && xl != x)
|
|
{
|
|
k1 = (y - yl) / (x - xl);
|
|
k2 = (yr - yl) / (xr - xl);
|
|
if ((fabs(k1-k2) < 0.004) &&
|
|
((xl < xr &&
|
|
(x > xl || AlmostEqual(x,xl)) &&
|
|
(x < xr || AlmostEqual(x,xr))) ||
|
|
(xl > xr &&
|
|
(x < xl || AlmostEqual(x,xl)) &&
|
|
(x > xr || AlmostEqual(x,xr)))) &&
|
|
(((yl < yr || AlmostEqual(yl,yr)) &&
|
|
(y > yl || AlmostEqual(y,yl)) &&
|
|
(y < yr || AlmostEqual(y,yr))) ||
|
|
(yl > yr &&
|
|
(y < yl || AlmostEqual(y,yl)) &&
|
|
(y > yr || AlmostEqual(y,yr)))))
|
|
result = true;
|
|
else result = false;
|
|
}
|
|
else
|
|
{
|
|
if (( AlmostEqual(xl, xr) && AlmostEqual(xl,x)) &&
|
|
(((yl < yr|| AlmostEqual(yl,yr)) &&
|
|
(yl < y || AlmostEqual(yl,y))&&
|
|
(y < yr ||AlmostEqual(y,yr)))||
|
|
(yl > yr &&
|
|
(yl > y ||AlmostEqual(yl,y))&&
|
|
(y > yr ||AlmostEqual(y,yr)))))
|
|
result = true;
|
|
else result = false;
|
|
}
|
|
}
|
|
if (result) {
|
|
LRS lrs;
|
|
route.Get( hs.attr.edgeno, lrs );
|
|
route.Get( lrs.hsPos, hs );
|
|
pos = lrs.lrsPos + point.Distance( hs.GetDomPoint() );
|
|
if( startSmaller != route.GetStartSmaller())
|
|
pos = route.Length() - pos;
|
|
if( AlmostEqual(pos,0.0))
|
|
pos = 0.0;
|
|
else if (AlmostEqual(pos,route.Length()))
|
|
pos = route.Length();
|
|
return result;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
Almost Equal to ~checkPoint~ but allows bigger differences. Used by
|
|
~mpoint2mgpoint~.
|
|
|
|
*/
|
|
|
|
bool checkPoint03 (const SimpleLine *route, const Point point,
|
|
const bool startSmaller,
|
|
double &pos, double &difference){
|
|
bool result = false;
|
|
HalfSegment hs;
|
|
double k1, k2;
|
|
Point left, right;
|
|
for (int i = 0; i < route->Size()-1; i++) {
|
|
route->Get(i, hs);
|
|
left = hs.GetLeftPoint();
|
|
right = hs.GetRightPoint();
|
|
Coord xl = left.GetX(),
|
|
yl = left.GetY(),
|
|
xr = right.GetX(),
|
|
yr = right.GetY(),
|
|
x = point.GetX(),
|
|
y = point.GetY();
|
|
if ((AlmostEqual(x,xl) && AlmostEqual (y,yl)) ||
|
|
(AlmostEqual(x,xr) && AlmostEqual (y,yr))) {
|
|
difference = 0.0;
|
|
result = true;
|
|
} else {
|
|
if (xl != xr && xl != x) {
|
|
k1 = (y - yl) / (x - xl);
|
|
k2 = (yr - yl) / (xr - xl);
|
|
if ((fabs(k1-k2) < 1.2) &&
|
|
((xl < xr &&
|
|
(x > xl || AlmostEqual(x,xl)) &&
|
|
(x < xr || AlmostEqual(x,xr))) ||
|
|
(xl > xr &&
|
|
(x < xl || AlmostEqual(x,xl)) &&
|
|
( x > xr || AlmostEqual(x,xr)))) &&
|
|
(((yl < yr || AlmostEqual(yl,yr)) &&
|
|
(y > yl || AlmostEqual(y,yl) ) &&
|
|
(y < yr || AlmostEqual(y,yr))) ||
|
|
(yl > yr &&
|
|
(y < yl || AlmostEqual(y,yl)) &&
|
|
(y > yr || AlmostEqual(y,yr)))))
|
|
{
|
|
difference = fabs(k1-k2);
|
|
result = true;
|
|
}
|
|
else {result = false;}
|
|
}
|
|
else
|
|
{
|
|
if (( AlmostEqual(xl, xr) && AlmostEqual(xl,x)) &&
|
|
(((yl < yr|| AlmostEqual(yl,yr)) &&
|
|
(yl < y || AlmostEqual(yl,y))&&
|
|
(y < yr ||AlmostEqual(y,yr)))||
|
|
(yl > yr &&
|
|
(yl > y || AlmostEqual(yl,y))&&
|
|
(y > yr ||AlmostEqual(y,yr)))))
|
|
{
|
|
difference = 0.0;
|
|
result = true;
|
|
}
|
|
else {result = false;}
|
|
}
|
|
}
|
|
if (result)
|
|
{
|
|
LRS lrs;
|
|
route->Get( hs.attr.edgeno, lrs );
|
|
route->Get( lrs.hsPos, hs );
|
|
pos = lrs.lrsPos + point.Distance( hs.GetDomPoint() );
|
|
if( startSmaller != route->GetStartSmaller())
|
|
pos = route->Length() - pos;
|
|
if( AlmostEqual(pos,0.0))
|
|
pos = 0.0;
|
|
else if (AlmostEqual(pos, route->Length()))
|
|
pos = route->Length();
|
|
return result;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool lastcheckPoint03 (const SimpleLine *route, const Point point,
|
|
const bool startSmaller,
|
|
double &pos, double &difference){
|
|
bool result = false;
|
|
HalfSegment hs;
|
|
double k1, k2;
|
|
Point left, right;
|
|
for (int i = 0; i < route->Size()-1; i++) {
|
|
route->Get(i, hs);
|
|
left = hs.GetLeftPoint();
|
|
right = hs.GetRightPoint();
|
|
Coord xl = left.GetX(),
|
|
yl = left.GetY(),
|
|
xr = right.GetX(),
|
|
yr = right.GetY(),
|
|
x = point.GetX(),
|
|
y = point.GetY();
|
|
if ((AlmostEqual(x,xl) && AlmostEqual (y,yl)) ||
|
|
(AlmostEqual(x,xr) && AlmostEqual (y,yr))) {
|
|
difference = 0.0;
|
|
result = true;
|
|
} else {
|
|
if (xl != xr && xl != x) {
|
|
k1 = (y - yl) / (x - xl);
|
|
k2 = (yr - yl) / (xr - xl);
|
|
if (((xl < xr &&
|
|
(x > xl || AlmostEqual(x,xl)) &&
|
|
(x < xr || AlmostEqual(x,xr))) ||
|
|
(xl > xr &&
|
|
( x < xl || AlmostEqual(x,xl)) &&
|
|
( x > xr || AlmostEqual(x,xr)))) &&
|
|
(((yl < yr || AlmostEqual(yl,yr)) &&
|
|
(y > yl || AlmostEqual(y,yl))&&
|
|
(y < yr || AlmostEqual(y,yr))) ||
|
|
(yl > yr &&
|
|
(y < yl || AlmostEqual(y,yl)) &&
|
|
(y > yr || AlmostEqual(y,yr)))))
|
|
{
|
|
difference = fabs(k1-k2);
|
|
result = true;
|
|
}
|
|
else {result = false;}
|
|
}
|
|
else
|
|
{
|
|
if (( AlmostEqual(xl, xr) && AlmostEqual(xl,x)) &&
|
|
(((yl < yr|| AlmostEqual(yl,yr)) &&
|
|
(yl < y || AlmostEqual(yl,y))&&
|
|
(y < yr || AlmostEqual(y,yr)))||
|
|
(yl > yr &&
|
|
(yl > y || AlmostEqual(yl,y))&&
|
|
(y > yr || AlmostEqual(y,yr)))))
|
|
{
|
|
difference = 0.0;
|
|
result = true;
|
|
}
|
|
else {result = false;}
|
|
}
|
|
}
|
|
if (result) {
|
|
LRS lrs;
|
|
route->Get( hs.attr.edgeno, lrs );
|
|
route->Get( lrs.hsPos, hs );
|
|
pos = lrs.lrsPos + point.Distance( hs.GetDomPoint() );
|
|
if( startSmaller != route->GetStartSmaller())
|
|
pos = route->Length() - pos;
|
|
if( pos < 0.0 || AlmostEqual(pos , 0.0))
|
|
pos = 0.0;
|
|
else if (pos > route->Length() || AlmostEqual(pos, route->Length()))
|
|
pos = route->Length();
|
|
return result;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
Used by operator ~inside~ to check the rest of the ~UGPoint~ if there is a
|
|
further intersection.
|
|
|
|
Two different parameter lists are possible.
|
|
|
|
*/
|
|
void checkEndOfUGPoint(double startPos, double endPos, Instant startTime,
|
|
bool bstart, Instant endTime, bool bend, int actRoutInt,
|
|
const GLine* pGLine, MBool* pResult,
|
|
int iRouteId){
|
|
RouteInterval pCurrInt;
|
|
UBool interbool(true);
|
|
bool swapped = false;
|
|
bool found = false;
|
|
double lStart, lEnd, factor, help;
|
|
Instant tInterStart, tInterEnd;
|
|
int k = actRoutInt + 1;
|
|
while ( k < pGLine->NoOfComponents()) {
|
|
pGLine->Get(k, pCurrInt);
|
|
if (pCurrInt.GetRouteId() == iRouteId) {
|
|
if (endPos < startPos) {
|
|
help = startPos;
|
|
startPos = endPos;
|
|
endPos = help;
|
|
swapped = true;
|
|
}
|
|
lStart = pCurrInt.GetStartPos();
|
|
lEnd = pCurrInt.GetEndPos();
|
|
if (lStart > lEnd) {
|
|
lStart = pCurrInt.GetEndPos();
|
|
lEnd = pCurrInt.GetStartPos();
|
|
}
|
|
if (!(endPos < lStart || startPos > lEnd || startPos == endPos ||
|
|
lStart == lEnd)){
|
|
//intersection exists compute intersecting part and timevalues for
|
|
//resulting unit
|
|
if (!swapped) {
|
|
if (lStart <= startPos) {
|
|
found = true;
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
interbool.constValue.Set(true, true);
|
|
} else {
|
|
found = true;
|
|
// compute and write unit befor mgpoint inside gline
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
factor = fabs(lStart - startPos) / fabs(endPos - startPos);
|
|
tInterStart = (endTime - startTime) * factor + startTime;
|
|
interbool.timeInterval.end = tInterStart;
|
|
interbool.timeInterval.rc = false;
|
|
interbool.constValue.Set(true,false);
|
|
pResult->MergeAdd(interbool);
|
|
//compute start of unit inside
|
|
interbool.timeInterval.start = tInterStart;
|
|
interbool.timeInterval.lc = true;
|
|
interbool.constValue.Set(true, true);
|
|
}
|
|
if (lEnd >= endPos) {
|
|
interbool.timeInterval.end = endTime;
|
|
interbool.timeInterval.rc = bend;
|
|
pResult->MergeAdd(interbool);
|
|
} else {
|
|
// compute end of mgpoint at end of gline.and add result unit
|
|
interbool.timeInterval.rc = true;
|
|
factor = fabs(lEnd - startPos) / fabs(endPos -startPos);
|
|
tInterEnd = (endTime -startTime) * factor + startTime;
|
|
interbool.timeInterval.end = tInterEnd;
|
|
pResult->MergeAdd(interbool);
|
|
// the rest of the current unit is not in the current
|
|
// routeinterval.
|
|
checkEndOfUGPoint(lEnd, endPos, tInterEnd, false, endTime, bend,
|
|
k, pGLine, pResult, iRouteId);
|
|
}
|
|
} else {
|
|
help = startPos;
|
|
startPos = endPos;
|
|
endPos = help;
|
|
if (lEnd >= startPos) {
|
|
found = true;
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
interbool.constValue.Set(true, true);
|
|
} else {
|
|
found = true;
|
|
// compute and write unit befor mgpoint inside gline
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
factor = fabs(lEnd - startPos) / fabs(endPos - startPos);
|
|
tInterStart = (endTime - startTime) * factor + startTime;
|
|
interbool.timeInterval.end = tInterStart;
|
|
interbool.timeInterval.rc = false;
|
|
interbool.constValue.Set(true,false);
|
|
pResult->MergeAdd(interbool);
|
|
//compute start of unit inside
|
|
interbool.timeInterval.start = tInterStart;
|
|
interbool.timeInterval.lc = true;
|
|
interbool.constValue.Set(true, true);
|
|
}
|
|
if (lStart <= endPos) {
|
|
interbool.timeInterval.end = endTime;
|
|
interbool.timeInterval.rc = bend;
|
|
pResult->MergeAdd(interbool);
|
|
} else {
|
|
// compute end of mgpoint at end of gline.and add result unit
|
|
interbool.timeInterval.rc = true;
|
|
factor = fabs(lStart - startPos) / fabs(endPos - startPos);
|
|
tInterEnd = (endTime - startTime) * factor + startTime;
|
|
interbool.timeInterval.end = tInterEnd;
|
|
pResult->MergeAdd(interbool);
|
|
// the rest of the current unit is not in the current
|
|
// routeinterval.
|
|
checkEndOfUGPoint(lEnd, endPos, tInterEnd, false, endTime, bend,
|
|
k, pGLine, pResult, iRouteId);
|
|
}
|
|
}
|
|
}else{
|
|
if (startPos == endPos && bstart && bend){
|
|
found = true;
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
interbool.timeInterval.end = endTime;
|
|
interbool.timeInterval.rc = bend;
|
|
interbool.constValue.Set(true,true);
|
|
pResult->MergeAdd(interbool);
|
|
} else {
|
|
if (lStart == lEnd) {
|
|
found = true;
|
|
if ((lStart > startPos && lStart < endPos) ||
|
|
(lStart < startPos && lStart > endPos)) {
|
|
// compute and write unit befor mgpoint inside gline
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
factor = fabs(lStart - startPos) / fabs(endPos -startPos);
|
|
tInterStart = (endTime - startTime) * factor + startTime;
|
|
interbool.timeInterval.end = tInterStart;
|
|
interbool.timeInterval.rc = false;
|
|
interbool.constValue.Set(true,false);
|
|
pResult->MergeAdd(interbool);
|
|
interbool.timeInterval.start = tInterStart;
|
|
interbool.timeInterval.rc = true;
|
|
interbool.timeInterval.lc = true;
|
|
interbool.constValue.Set(true, true);
|
|
pResult->MergeAdd(interbool);
|
|
checkEndOfUGPoint(lEnd, endPos, tInterEnd, false, endTime, bend,
|
|
k, pGLine, pResult, iRouteId);
|
|
} else {
|
|
if (lStart == startPos && bstart) {
|
|
found = true;
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
interbool.timeInterval.end = startTime;
|
|
interbool.timeInterval.rc = true;
|
|
interbool.constValue.Set(true,true);
|
|
pResult->MergeAdd(interbool);
|
|
checkEndOfUGPoint(lEnd, endPos, tInterEnd, false, endTime, bend,
|
|
k, pGLine, pResult, iRouteId);
|
|
} else {
|
|
if (lStart == endPos && bend) {
|
|
found = true;
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
interbool.timeInterval.end = endTime;
|
|
interbool.timeInterval.rc = false;
|
|
interbool.constValue.Set(true,false);
|
|
pResult->MergeAdd(interbool);
|
|
interbool.timeInterval.start = endTime;
|
|
interbool.timeInterval.rc = bend;
|
|
interbool.timeInterval.lc = true;
|
|
interbool.constValue.Set(true, true);
|
|
pResult->MergeAdd(interbool);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if ((startPos == lStart && endPos == lEnd)||
|
|
(startPos == lEnd && endPos == lStart)){
|
|
found = true;
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.end = endTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
interbool.timeInterval.rc = bend;
|
|
interbool.constValue.Set(true, true);
|
|
pResult->MergeAdd(interbool);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} // end if routeid==
|
|
k++;
|
|
} // end while
|
|
if (!found) {
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
interbool.timeInterval.end = endTime;
|
|
interbool.timeInterval.rc = bend;
|
|
interbool.constValue.Set(true,false);
|
|
pResult->MergeAdd(interbool);
|
|
}
|
|
}
|
|
|
|
void checkEndOfUGPoint(double startPos, double endPos, Instant startTime,
|
|
bool bstart, Instant endTime, bool bend,
|
|
size_t actRoutInt, vector<RouteInterval> &vRI,
|
|
MBool* pResult, int iRouteId){
|
|
RouteInterval pCurrInt;
|
|
UBool interbool(true);
|
|
double help, factor;
|
|
bool swapped = false;
|
|
if (endPos < startPos) {
|
|
help = startPos;
|
|
startPos = endPos;
|
|
endPos = help;
|
|
swapped = true;
|
|
}
|
|
bool found = false;
|
|
Instant tInterStart, tInterEnd;
|
|
size_t k = actRoutInt + 1;
|
|
while ( k < vRI.size()) {
|
|
pCurrInt = vRI[k];
|
|
if (pCurrInt.GetRouteId() == iRouteId) {
|
|
if (!(endPos < pCurrInt.GetStartPos() ||
|
|
startPos > pCurrInt.GetEndPos() ||
|
|
startPos == endPos ||
|
|
pCurrInt.GetStartPos() == pCurrInt.GetEndPos())){
|
|
//intersection exists compute intersecting part and timevalues for
|
|
//resulting unit
|
|
if (!swapped) {
|
|
if (pCurrInt.GetStartPos() <= startPos) {
|
|
found = true;
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
interbool.constValue.Set(true, true);
|
|
} else {
|
|
found = true;
|
|
// compute and write unit befor mgpoint inside gline
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
factor = fabs(pCurrInt.GetStartPos() - startPos) /
|
|
fabs(endPos - startPos);
|
|
tInterStart = (endTime - startTime) * factor + startTime;
|
|
interbool.timeInterval.end = tInterStart;
|
|
interbool.timeInterval.rc = false;
|
|
interbool.constValue.Set(true,false);
|
|
pResult->MergeAdd(interbool);
|
|
//compute start of unit inside
|
|
interbool.timeInterval.start = tInterStart;
|
|
interbool.timeInterval.lc = true;
|
|
interbool.constValue.Set(true, true);
|
|
}
|
|
if (pCurrInt.GetEndPos() >= endPos) {
|
|
interbool.timeInterval.end = endTime;
|
|
interbool.timeInterval.rc = bend;
|
|
pResult->MergeAdd(interbool);
|
|
} else {
|
|
// compute end of mgpoint at end of gline.and add result unit
|
|
interbool.timeInterval.rc = true;
|
|
factor = fabs(pCurrInt.GetEndPos() - startPos) /
|
|
fabs(endPos -startPos);
|
|
tInterEnd = (endTime -startTime) * factor + startTime;
|
|
interbool.timeInterval.end = tInterEnd;
|
|
pResult->MergeAdd(interbool);
|
|
// the rest of the current unit is not in the current
|
|
// routeinterval.
|
|
checkEndOfUGPoint(pCurrInt.GetEndPos(), endPos, tInterEnd, false,
|
|
endTime, bend, k, vRI, pResult, iRouteId);
|
|
}
|
|
} else {
|
|
help = startPos;
|
|
startPos = endPos;
|
|
endPos = help;
|
|
if (pCurrInt.GetEndPos() >= startPos) {
|
|
found = true;
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
interbool.constValue.Set(true, true);
|
|
} else {
|
|
found = true;
|
|
// compute and write unit befor mgpoint inside gline
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
factor = fabs(pCurrInt.GetEndPos() - startPos) /
|
|
fabs(endPos - startPos);
|
|
tInterStart = (endTime - startTime) * factor + startTime;
|
|
interbool.timeInterval.end = tInterStart;
|
|
interbool.timeInterval.rc = false;
|
|
interbool.constValue.Set(true,false);
|
|
pResult->MergeAdd(interbool);
|
|
//compute start of unit inside
|
|
interbool.timeInterval.start = tInterStart;
|
|
interbool.timeInterval.lc = true;
|
|
interbool.constValue.Set(true, true);
|
|
}
|
|
if (pCurrInt.GetStartPos() <= endPos) {
|
|
interbool.timeInterval.end = endTime;
|
|
interbool.timeInterval.rc = bend;
|
|
pResult->MergeAdd(interbool);
|
|
} else {
|
|
// compute end of mgpoint at end of gline.and add result unit
|
|
interbool.timeInterval.rc = true;
|
|
factor = fabs(pCurrInt.GetStartPos() - startPos) /
|
|
fabs(endPos - startPos);
|
|
tInterEnd = (endTime - startTime) * factor + startTime;
|
|
interbool.timeInterval.end = tInterEnd;
|
|
pResult->MergeAdd(interbool);
|
|
// the rest of the current unit is not in the current
|
|
// routeinterval.
|
|
checkEndOfUGPoint(pCurrInt.GetEndPos(), endPos, tInterEnd, false,
|
|
endTime, bend, k, vRI, pResult, iRouteId);
|
|
}
|
|
}
|
|
}else{
|
|
if (startPos == endPos && bstart && bend){
|
|
found = true;
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
interbool.timeInterval.end = endTime;
|
|
interbool.timeInterval.rc = bend;
|
|
interbool.constValue.Set(true,true);
|
|
pResult->MergeAdd(interbool);
|
|
} else {
|
|
if (pCurrInt.GetStartPos() == pCurrInt.GetEndPos()) {
|
|
found = true;
|
|
if ((pCurrInt.GetStartPos() > startPos &&
|
|
pCurrInt.GetStartPos() < endPos)||
|
|
(pCurrInt.GetStartPos() < startPos &&
|
|
pCurrInt.GetStartPos() > endPos)) {
|
|
// compute and write unit befor mgpoint inside gline
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
factor = fabs(pCurrInt.GetStartPos() - startPos) /
|
|
fabs(endPos -startPos);
|
|
tInterStart = (endTime - startTime) * factor + startTime;
|
|
interbool.timeInterval.end = tInterStart;
|
|
interbool.timeInterval.rc = false;
|
|
interbool.constValue.Set(true,false);
|
|
pResult->MergeAdd(interbool);
|
|
interbool.timeInterval.start = tInterStart;
|
|
interbool.timeInterval.rc = true;
|
|
interbool.timeInterval.lc = true;
|
|
interbool.constValue.Set(true, true);
|
|
pResult->MergeAdd(interbool);
|
|
checkEndOfUGPoint(pCurrInt.GetEndPos(), endPos, tInterEnd, false,
|
|
endTime, bend, k, vRI, pResult, iRouteId);
|
|
} else {
|
|
if (pCurrInt.GetStartPos() == startPos && bstart) {
|
|
found = true;
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
interbool.timeInterval.end = startTime;
|
|
interbool.timeInterval.rc = true;
|
|
interbool.constValue.Set(true,true);
|
|
pResult->MergeAdd(interbool);
|
|
checkEndOfUGPoint(pCurrInt.GetEndPos(), endPos, tInterEnd,
|
|
false, endTime, bend, k, vRI, pResult,
|
|
iRouteId);
|
|
} else {
|
|
if (pCurrInt.GetStartPos() == endPos && bend) {
|
|
found = true;
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
interbool.timeInterval.end = endTime;
|
|
interbool.timeInterval.rc = false;
|
|
interbool.constValue.Set(true,false);
|
|
pResult->MergeAdd(interbool);
|
|
interbool.timeInterval.start = endTime;
|
|
interbool.timeInterval.rc = bend;
|
|
interbool.timeInterval.lc = true;
|
|
interbool.constValue.Set(true, true);
|
|
pResult->MergeAdd(interbool);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if ((startPos == pCurrInt.GetStartPos() &&
|
|
endPos == pCurrInt.GetEndPos())||
|
|
(startPos == pCurrInt.GetEndPos() &&
|
|
endPos == pCurrInt.GetStartPos())){
|
|
found = true;
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.end = endTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
interbool.timeInterval.rc = bend;
|
|
interbool.constValue.Set(true, true);
|
|
pResult->MergeAdd(interbool);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} // end if routeid==
|
|
k++;
|
|
} // end while
|
|
if (!found) {
|
|
interbool.timeInterval.start = startTime;
|
|
interbool.timeInterval.lc = bstart;
|
|
interbool.timeInterval.end = endTime;
|
|
interbool.timeInterval.rc = bend;
|
|
interbool.constValue.Set(true,false);
|
|
pResult->MergeAdd(interbool);
|
|
}
|
|
}
|
|
|
|
/*
|
|
1.1.7 ~sendMessage~
|
|
|
|
Sending a message via the message-center
|
|
|
|
*/
|
|
|
|
void sendMessages(string in_strMessage)
|
|
{
|
|
// Get message-center and initialize message-list
|
|
static MessageCenter* xMessageCenter= MessageCenter::GetInstance();
|
|
ListExpr list = nl->TwoElemList(nl->SymbolAtom("error"),
|
|
nl->TextAtom(in_strMessage));
|
|
xMessageCenter->Send(nl,list);
|
|
}
|
|
|
|
|
|
/*
|
|
Returns the ~RouteIntervals~ of a route between mgpstart and mgpend.
|
|
|
|
Used by operators ~at~ and ~inside~.
|
|
|
|
*/
|
|
|
|
void getRouteIntervals(const GLine *pGLine, int iRouteId, double mgpstart,
|
|
double mgpend, int low, int high,
|
|
vector<RouteInterval> &vRI){
|
|
vRI.clear();
|
|
RouteInterval aktRI;
|
|
bool found;
|
|
int mid;
|
|
if (low <= high) {
|
|
mid = (high + low) / 2;
|
|
if (!(mid < 0 || mid >= pGLine->NoOfComponents())) {
|
|
pGLine->Get(mid, aktRI);
|
|
if (aktRI.GetRouteId() < iRouteId) {
|
|
getRouteIntervals(pGLine, iRouteId, mgpstart, mgpend, mid+1, high, vRI);
|
|
} else {
|
|
if (aktRI.GetRouteId() > iRouteId) {
|
|
getRouteIntervals(pGLine, iRouteId, mgpstart, mgpend, low, mid-1,
|
|
vRI);
|
|
} else {
|
|
if (aktRI.GetStartPos() > mgpend) {
|
|
getRouteIntervals(pGLine, iRouteId, mgpstart, mgpend, low, mid-1,
|
|
vRI);
|
|
} else {
|
|
if (aktRI.GetEndPos() < mgpstart) {
|
|
getRouteIntervals(pGLine, iRouteId, mgpstart, mgpend, mid+1, high,
|
|
vRI);
|
|
} else {
|
|
if (mid > 0) {
|
|
mid--;
|
|
found = false;
|
|
while (mid >= 0 && !found) {
|
|
pGLine->Get(mid, aktRI);
|
|
if (aktRI.GetRouteId() == iRouteId &&
|
|
aktRI.GetEndPos() >= mgpstart) {
|
|
mid--;
|
|
} else {
|
|
found = true;
|
|
mid++;
|
|
pGLine->Get(mid, aktRI);
|
|
}
|
|
}
|
|
} else {
|
|
pGLine->Get(0, aktRI);
|
|
}
|
|
vRI.push_back(aktRI);
|
|
mid++;
|
|
found = false;
|
|
while (!found && mid < pGLine->NoOfComponents() ){
|
|
pGLine->Get(mid, aktRI);
|
|
if (aktRI.GetRouteId() == iRouteId &&
|
|
aktRI.GetStartPos() <= mgpend) {
|
|
vRI.push_back(aktRI);
|
|
mid++;
|
|
} else {
|
|
found = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Compares two time intervals and returns a case number describing their
|
|
intersection.
|
|
|
|
Used by ~refinementMovingGPoint~.
|
|
|
|
*/
|
|
|
|
int intervalCheck (const Interval<Instant> i1,
|
|
const Interval<Instant> i2) {
|
|
if (i1.start > i2.end) return 1;
|
|
if (i1.end < i2.start ) return 16;
|
|
if (i1.start > i2.start && i1.start == i2.end && i1.start < i1.end) return 2;
|
|
if (i1.start > i2.start && i1.start < i2.end && i1.end < i2.end &&
|
|
i1.start < i1.end) return 3;
|
|
if (i1.start > i2.start && i1.end == i2.end && i1.start < i1.end) return 4;
|
|
if (i1.start > i2.start && i1.end > i2.end && i2.end > i1.start &&
|
|
i1.start < i1.end) return 5;
|
|
if (i1.start == i2.start && i1.start == i2.end && i1.start < i1.end) return 9;
|
|
if (i1.start == i2.start && i1.end > i2.end && i2.start < i2.end &&
|
|
i1.start < i1.end) return 6;
|
|
if (i1.start == i2.start && i1.end == i2.end && i1.start < i1.end) return 7;
|
|
if (i1.start == i2.start && i1.end < i2.end && i1.start < i1.end) return 8;
|
|
if (i1.start < i2.start && i1.end > i2.end && i2.start == i2.end &&
|
|
i1.start < i1.end) return 13;
|
|
if (i1.start < i2.start && i1.end > i2.end && i2.start < i2.end &&
|
|
i1.start < i1.end) return 10;
|
|
if (i1.start < i2.start && i1.end == i2.end && i2.start < i2.end &&
|
|
i1.start < i1.end) return 11;
|
|
if (i1.start < i2.start && i1.end < i2.end && i1.end > i2.start &&
|
|
i1.start < i1.end) return 12;
|
|
if (i1.end == i2.start && i2.start == i2.end && i1.start < i1.end) return 14;
|
|
if (i1.end == i2.start && i1.end < i2.end && i2.start < i2.end &&
|
|
i1.start < i1.end) return 15;
|
|
if (i1.start == i1.end && i2.start == i2.end &&
|
|
i1.start == i2.start) return 19;
|
|
if (i1.start == i1.end && i1.start == i2.start &&
|
|
i2.start < i2.end) return 17;
|
|
if (i1.start == i1.end && i1.start == i2.end && i2.start < i2.end) return 18;
|
|
if (i1.start == i1.end && i1.start > i2.start && i1.start < i2.end) return 20;
|
|
return -1; //should never be reached
|
|
};
|
|
|
|
/*
|
|
Translates two given ~MGPoint~ to two ~MGPoint~ which have a identical number
|
|
of units with identical time intervals. Used by operator ~intersection~ and
|
|
later on ~distance~ and ~netdistance~
|
|
|
|
*/
|
|
|
|
void refinementMovingGPoint (const MGPoint *a, const MGPoint *b,
|
|
MGPoint *resA, MGPoint *resB){
|
|
UGPoint ua, ub;
|
|
GPoint pos1, pos2;
|
|
int i = 0;
|
|
int j = 0;
|
|
a->Get(i,ua);
|
|
b->Get(j,ub);
|
|
resA->StartBulkLoad();
|
|
resB->StartBulkLoad();
|
|
while (i < a->GetNoComponents() && j < b->GetNoComponents()) {
|
|
switch (intervalCheck(ua.timeInterval, ub.timeInterval)) {
|
|
case 1: //no units to add
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
break;
|
|
case 2:
|
|
if (ua.timeInterval.lc && ub.timeInterval.rc) {
|
|
resA->Add(UGPoint(Interval<Instant>
|
|
(ua.timeInterval.start,
|
|
ua.timeInterval.start,
|
|
true, true),
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
ua.p0.GetPosition(),
|
|
ua.p0.GetPosition()));
|
|
resB->Add(UGPoint(Interval<Instant>(
|
|
ub.timeInterval.end,
|
|
ub.timeInterval.end,
|
|
true, true),
|
|
ub.p1.GetNetworkId(),
|
|
ub.p1.GetRouteId(),
|
|
ub.p1.GetSide(),
|
|
ub.p1.GetPosition(),
|
|
ub.p1.GetPosition()));
|
|
}
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
break;
|
|
case 3:
|
|
ub.TemporalFunction(ua.timeInterval.start, pos1, false);
|
|
ub.TemporalFunction(ua.timeInterval.end, pos2, false);
|
|
resA->Add(UGPoint(ua.timeInterval,
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
ua.p0.GetPosition(),
|
|
ua.p1.GetPosition()));
|
|
resB->Add(UGPoint(ua.timeInterval,
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
pos1.GetPosition(),
|
|
pos2.GetPosition()));
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
break;
|
|
case 4:
|
|
ub.TemporalFunction(ua.timeInterval.start, pos2, false);
|
|
resA->Add(UGPoint(Interval<Instant>(
|
|
ua.timeInterval.start,
|
|
ua.timeInterval.end,
|
|
ua.timeInterval.lc,
|
|
ua.timeInterval.rc &&
|
|
ub.timeInterval.rc),
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
ua.p0.GetPosition(),
|
|
ua.p1.GetPosition()));
|
|
resB->Add(UGPoint(Interval<Instant>(
|
|
ua.timeInterval.start,
|
|
ua.timeInterval.end,
|
|
ua.timeInterval.lc,
|
|
ua.timeInterval.rc &&
|
|
ub.timeInterval.rc),
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
pos2.GetPosition(),
|
|
ub.p1.GetPosition()));
|
|
if ((ua.timeInterval.rc && ub.timeInterval.rc) ||
|
|
(!ua.timeInterval.rc && !ub.timeInterval.rc)) {
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
} else {
|
|
if (ua.timeInterval.rc && !ub.timeInterval.rc) {
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
}
|
|
if (ub.timeInterval.rc && !ua.timeInterval.rc) {
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
}
|
|
}
|
|
break;
|
|
case 5:
|
|
ua.TemporalFunction(ub.timeInterval.end, pos1, false);
|
|
ub.TemporalFunction(ua.timeInterval.start, pos2, false);
|
|
resA->Add(UGPoint(Interval<Instant>(
|
|
ua.timeInterval.start,
|
|
ub.timeInterval.end,
|
|
ua.timeInterval.lc,
|
|
ub.timeInterval.rc),
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
ua.p0.GetPosition(),
|
|
pos1.GetPosition()));
|
|
resB->Add(UGPoint(Interval<Instant>(
|
|
ua.timeInterval.start,
|
|
ub.timeInterval.end,
|
|
ua.timeInterval.lc,
|
|
ub.timeInterval.rc),
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
pos2.GetPosition(),
|
|
ub.p1.GetPosition()));
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
break;
|
|
case 6:
|
|
ua.TemporalFunction(ub.timeInterval.end, pos1, false);
|
|
resA->Add(UGPoint(Interval<Instant>(
|
|
ub.timeInterval.start,
|
|
ub.timeInterval.end,
|
|
ub.timeInterval.lc &&
|
|
ua.timeInterval.lc,
|
|
ub.timeInterval.rc),
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
ua.p0.GetPosition(),
|
|
pos1.GetPosition()));
|
|
resB->Add(UGPoint(Interval<Instant>(
|
|
ub.timeInterval.start,
|
|
ub.timeInterval.end,
|
|
ub.timeInterval.lc &&
|
|
ua.timeInterval.lc,
|
|
ub.timeInterval.rc),
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
ub.p0.GetPosition(),
|
|
ub.p1.GetPosition()));
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
break;
|
|
case 7:
|
|
resA->Add(UGPoint(Interval<Instant>(
|
|
ua.timeInterval.start,
|
|
ua.timeInterval.end,
|
|
ua.timeInterval.lc &&
|
|
ub.timeInterval.lc,
|
|
ua.timeInterval.rc &&
|
|
ub.timeInterval.rc),
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
ua.p0.GetPosition(),
|
|
ua.p1.GetPosition()));
|
|
resB->Add(UGPoint(Interval<Instant>(
|
|
ua.timeInterval.start,
|
|
ua.timeInterval.end,
|
|
ua.timeInterval.lc &&
|
|
ub.timeInterval.lc,
|
|
ua.timeInterval.rc &&
|
|
ub.timeInterval.rc),
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
ub.p0.GetPosition(),
|
|
ub.p1.GetPosition()));
|
|
if ((ua.timeInterval.rc && ub.timeInterval.rc) ||
|
|
(!ua.timeInterval.rc && !ub.timeInterval.rc)) {
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
} else {
|
|
if (ua.timeInterval.rc && !ub.timeInterval.rc) {
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
}
|
|
if (ub.timeInterval.rc && !ua.timeInterval.rc) {
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
}
|
|
}
|
|
break;
|
|
case 8:
|
|
ub.TemporalFunction(ua.timeInterval.end, pos2, false);
|
|
resA->Add(UGPoint(Interval<Instant>(
|
|
ua.timeInterval.start,
|
|
ua.timeInterval.end,
|
|
ua.timeInterval.lc &&
|
|
ub.timeInterval.lc,
|
|
ua.timeInterval.rc),
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
ua.p0.GetPosition(),
|
|
ua.p1.GetPosition()));
|
|
resB->Add(UGPoint(Interval<Instant>(
|
|
ua.timeInterval.start,
|
|
ua.timeInterval.end,
|
|
ua.timeInterval.lc &&
|
|
ub.timeInterval.lc,
|
|
ua.timeInterval.rc),
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
ub.p0.GetPosition(),
|
|
pos2.GetPosition()));
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
break;
|
|
case 9:
|
|
if (ua.timeInterval.lc && ub.timeInterval.lc && ub.timeInterval.rc){
|
|
resA->Add(UGPoint(Interval<Instant>(
|
|
ua.timeInterval.start,
|
|
ua.timeInterval.start,
|
|
true, true),
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
ua.p0.GetPosition(),
|
|
ua.p0.GetPosition()));
|
|
resB->Add(UGPoint(Interval<Instant>(
|
|
ua.timeInterval.start,
|
|
ua.timeInterval.start,
|
|
true, true),
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
ub.p0.GetPosition(),
|
|
ub.p0.GetPosition()));
|
|
}
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
break;
|
|
case 10:
|
|
ua.TemporalFunction(ub.timeInterval.start, pos1, false);
|
|
ua.TemporalFunction(ub.timeInterval.end, pos2, false);
|
|
resA->Add(UGPoint(ub.timeInterval,
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
pos1.GetPosition(),
|
|
pos2.GetPosition()));
|
|
resB->Add(UGPoint(ub.timeInterval,
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
ub.p0.GetPosition(),
|
|
ub.p1.GetPosition()));
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
break;
|
|
case 11:
|
|
ua.TemporalFunction(ub.timeInterval.start, pos1, false);
|
|
resA->Add(UGPoint(ub.timeInterval,
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
pos1.GetPosition(),
|
|
ua.p1.GetPosition()));
|
|
resB->Add(UGPoint(ub.timeInterval,
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
ub.p0.GetPosition(),
|
|
ub.p1.GetPosition()));
|
|
if ((ua.timeInterval.rc && ub.timeInterval.rc) ||
|
|
(!ua.timeInterval.rc && !ub.timeInterval.rc)) {
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
} else {
|
|
if (ua.timeInterval.rc && !ub.timeInterval.rc) {
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
}
|
|
if (ub.timeInterval.rc && !ua.timeInterval.rc) {
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
}
|
|
}
|
|
break;
|
|
case 12:
|
|
ua.TemporalFunction(ub.timeInterval.start, pos1, false);
|
|
ub.TemporalFunction(ua.timeInterval.end, pos2, false);
|
|
resA->Add(UGPoint(Interval<Instant>(
|
|
ub.timeInterval.start,
|
|
ua.timeInterval.end,
|
|
ub.timeInterval.lc,
|
|
ua.timeInterval.rc),
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
pos1.GetPosition(),
|
|
ua.p1.GetPosition()));
|
|
resB->Add(UGPoint(Interval<Instant>(
|
|
ub.timeInterval.start,
|
|
ua.timeInterval.end,
|
|
ub.timeInterval.lc,
|
|
ua.timeInterval.rc),
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
ub.p0.GetPosition(),
|
|
pos2.GetPosition()));
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
break;
|
|
case 13:
|
|
if (ub.timeInterval.lc && ub.timeInterval.rc) {
|
|
ua.TemporalFunction(ub.timeInterval.start, pos1, false);
|
|
resA->Add(UGPoint(ub.timeInterval,
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
pos1.GetPosition(),
|
|
pos1.GetPosition()));
|
|
resB->Add(UGPoint(ub.timeInterval,
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
ub.p0.GetPosition(),
|
|
ub.p0.GetPosition()));
|
|
}
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
break;
|
|
case 14:
|
|
if (ua.timeInterval.rc && ub.timeInterval.lc && ub.timeInterval.rc) {
|
|
resA->Add(UGPoint(ub.timeInterval, ua.p1, ua.p1));
|
|
resB->Add(UGPoint(ub.timeInterval, ub.p0, ub.p0));
|
|
}
|
|
if ((ua.timeInterval.rc && ub.timeInterval.rc) ||
|
|
(!ua.timeInterval.rc && !ub.timeInterval.rc)) {
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
} else {
|
|
if (ua.timeInterval.rc && !ub.timeInterval.rc) {
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
}
|
|
if (ub.timeInterval.rc && !ua.timeInterval.rc) {
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
}
|
|
}
|
|
break;
|
|
case 15:
|
|
if (ua.timeInterval.rc && ub.timeInterval.lc) {
|
|
resA->Add(UGPoint(Interval<Instant>(
|
|
ua.timeInterval.end,
|
|
ua.timeInterval.end,
|
|
true, true),
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
ua.p1.GetPosition(),
|
|
ua.p1.GetPosition()));
|
|
resB->Add(UGPoint(Interval<Instant>(ua.timeInterval.end,
|
|
ua.timeInterval.end,
|
|
true, true),
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
ub.p0.GetPosition(),
|
|
ub.p0.GetPosition()));
|
|
}
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
break;
|
|
case 16: //nothing to add
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
break;
|
|
case 17:
|
|
if (ua.timeInterval.lc && ua.timeInterval.rc && ub.timeInterval.lc){
|
|
resA->Add(UGPoint(Interval<Instant>(
|
|
ua.timeInterval.start,
|
|
ua.timeInterval.end,
|
|
true, true),
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
ua.p0.GetPosition(),
|
|
ua.p0.GetPosition()));
|
|
resB->Add(UGPoint(Interval<Instant>(
|
|
ua.timeInterval.start,
|
|
ua.timeInterval.end,
|
|
true, true),
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
ub.p0.GetPosition(),
|
|
ub.p0.GetPosition()));
|
|
}
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
break;
|
|
case 18:
|
|
if (ua.timeInterval.lc && ua.timeInterval.rc && ub.timeInterval.rc){
|
|
resA->Add(UGPoint(Interval<Instant>(ua.timeInterval.start,
|
|
ua.timeInterval.end,
|
|
true, true),
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
ua.p0.GetPosition(),
|
|
ua.p0.GetPosition()));
|
|
resB->Add(UGPoint(Interval<Instant>(ua.timeInterval.start,
|
|
ua.timeInterval.end,
|
|
true, true),
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
ub.p1.GetPosition(),
|
|
ub.p1.GetPosition()));
|
|
}
|
|
if ((ua.timeInterval.rc && ub.timeInterval.rc) ||
|
|
(!ua.timeInterval.rc && !ub.timeInterval.rc)) {
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
} else {
|
|
if (ua.timeInterval.rc && !ub.timeInterval.rc) {
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
}
|
|
if (ub.timeInterval.rc && !ua.timeInterval.rc) {
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
}
|
|
}
|
|
break;
|
|
case 19:
|
|
if (ua.timeInterval.lc && ua.timeInterval.rc &&
|
|
ub.timeInterval.lc && ub.timeInterval.rc) {
|
|
resA->Add(UGPoint(Interval<Instant> (ua.timeInterval.start,
|
|
ua.timeInterval.start,
|
|
true,true),
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
ua.p0.GetPosition(),
|
|
ua.p0.GetPosition()));
|
|
resB->Add(UGPoint(Interval<Instant> (ub.timeInterval.end,
|
|
ub.timeInterval.end,
|
|
true,true),
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
ub.p0.GetPosition(),
|
|
ub.p0.GetPosition()));
|
|
}
|
|
if ((ua.timeInterval.rc && ub.timeInterval.rc) ||
|
|
(!ua.timeInterval.rc && !ub.timeInterval.rc)) {
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
} else {
|
|
if (ua.timeInterval.rc && !ub.timeInterval.rc) {
|
|
j++;
|
|
if (j < b->GetNoComponents()) b->Get(j, ub);
|
|
}
|
|
if (ub.timeInterval.rc && !ua.timeInterval.rc) {
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
}
|
|
}
|
|
break;
|
|
case 20:
|
|
if (ua.timeInterval.lc && ua.timeInterval.rc) {
|
|
ub.TemporalFunction(ua.timeInterval.start, pos2, false);
|
|
resA->Add(UGPoint(ua.timeInterval,
|
|
ua.p0.GetNetworkId(),
|
|
ua.p0.GetRouteId(),
|
|
ua.p0.GetSide(),
|
|
ua.p0.GetPosition(),
|
|
ua.p0.GetPosition()));
|
|
resB->Add(UGPoint(ua.timeInterval,
|
|
ub.p0.GetNetworkId(),
|
|
ub.p0.GetRouteId(),
|
|
ub.p0.GetSide(),
|
|
pos2.GetPosition(),
|
|
pos2.GetPosition()));
|
|
}
|
|
i++;
|
|
if (i < a->GetNoComponents()) a->Get(i, ua);
|
|
break;
|
|
default: //should never happen
|
|
cerr << "an error occured while checking the time interval." << endl;
|
|
resA->EndBulkLoad(false);
|
|
resB->EndBulkLoad(false);
|
|
resA->SetDefined(false);
|
|
resB->SetDefined(false);
|
|
resA->SetTrajectoryDefined(false);
|
|
resB->SetTrajectoryDefined(false);
|
|
resA->SetBoundingBoxDefined(false);
|
|
resB->SetBoundingBoxDefined(false);
|
|
return;
|
|
} // end switch
|
|
}//end while
|
|
resA->EndBulkLoad(true);
|
|
resB->EndBulkLoad(true);
|
|
resA->SetDefined(true);
|
|
resB->SetDefined(true);
|
|
resA->SetTrajectoryDefined(false);
|
|
resB->SetTrajectoryDefined(false);
|
|
resA->m_trajectory.TrimToSize();
|
|
resB->m_trajectory.TrimToSize();
|
|
resA->SetBoundingBoxDefined(false);
|
|
resB->SetBoundingBoxDefined(false);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
Checks if StartPos <= EndPos if not changes StartPos and EndPos. Used by
|
|
operator ~trajectory~.
|
|
|
|
*/
|
|
|
|
void chkStartEnd(double &StartPos, double &EndPos){
|
|
double help;
|
|
if (StartPos > EndPos) {
|
|
help = StartPos;
|
|
StartPos = EndPos;
|
|
EndPos = help;
|
|
}
|
|
};
|
|
|
|
/*
|
|
2 class ~MGPoint~
|
|
|
|
Constructors
|
|
|
|
*/
|
|
|
|
MGPoint::MGPoint( const int n ):Mapping< UGPoint, GPoint >(n), m_trajectory (0)
|
|
{
|
|
m_length = 0.0;
|
|
m_bbox = Rectangle<3>(false);
|
|
m_traj_Defined = false;
|
|
}
|
|
|
|
/*
|
|
Functions for integration in SECONDO
|
|
|
|
*/
|
|
void MGPoint::Clear()
|
|
{
|
|
//if (IsDefined()){
|
|
Mapping<UGPoint, GPoint>::Clear();
|
|
m_length = 0.0;
|
|
m_trajectory.clean();
|
|
m_traj_Defined = false;
|
|
m_bbox = Rectangle<3>(false );
|
|
//}
|
|
}
|
|
|
|
void* MGPoint::Cast(void* addr)
|
|
{
|
|
return new (addr) MGPoint;
|
|
}
|
|
|
|
bool MGPoint::Check(ListExpr type,
|
|
ListExpr& errorInfo)
|
|
{
|
|
return (nl->IsEqual( type, MGPoint::BasicType() ));
|
|
}
|
|
|
|
/*
|
|
Getter and Setter Methods
|
|
|
|
*/
|
|
|
|
int MGPoint::GetNetworkId() const{
|
|
if (GetNoComponents()>0)
|
|
{
|
|
UGPoint u;
|
|
Get(0,u);
|
|
return u.p0.GetNetworkId();
|
|
}
|
|
else return numeric_limits<int>::min();
|
|
}
|
|
|
|
Network* MGPoint::GetNetwork() const
|
|
{
|
|
return NetworkManager::GetNetworkNew(GetNetworkId(),netList);
|
|
}
|
|
|
|
double MGPoint::GetLength() const{
|
|
if (IsDefined()) return m_length;
|
|
else return 0.0;
|
|
}
|
|
|
|
double MGPoint::Length() const{
|
|
if (IsDefined()) return m_length;
|
|
else return 0.0;
|
|
}
|
|
|
|
void MGPoint::SetBoundingBox(const Rectangle<3> mbr){
|
|
m_bbox = mbr;
|
|
}
|
|
|
|
void MGPoint::SetTrajectory(const DbArray<RouteInterval>& tra){
|
|
if (tra.Size() > 0){
|
|
m_traj_Defined = true;
|
|
m_trajectory.copyFrom(tra);
|
|
} else m_traj_Defined = false;
|
|
}
|
|
|
|
void MGPoint::SetTrajectory(GLine src){
|
|
if (src.IsDefined() && src.NoOfComponents() > 0) {
|
|
m_trajectory.copyFrom(*(src.GetRouteIntervals()));
|
|
m_traj_Defined = true;
|
|
}else m_traj_Defined = false;
|
|
}
|
|
|
|
void MGPoint::Trajectory(GLine* res) {
|
|
if (IsDefined())
|
|
{
|
|
if (m_traj_Defined) {
|
|
if (m_trajectory.Size() > 0) {
|
|
res->SetNetworkId(GetNetworkId());
|
|
RouteInterval ri;
|
|
for (int i = 0; i < m_trajectory.Size(); i++){
|
|
m_trajectory.Get(i,ri);
|
|
res->AddRouteInterval(ri.GetRouteId(), ri.GetStartPos(),
|
|
ri.GetEndPos());
|
|
}
|
|
res->SetSorted(true);
|
|
res->SetDefined(true);
|
|
} else res->SetDefined(false);
|
|
} else {
|
|
if (GetNoComponents() > 0) {
|
|
UGPoint pCurrentUnit;
|
|
Get(0, pCurrentUnit);
|
|
res->SetNetworkId(GetNetworkId());
|
|
res->SetDefined(true);
|
|
int aktRouteId = pCurrentUnit.p0.GetRouteId();
|
|
double aktStartPos = pCurrentUnit.p0.GetPosition();
|
|
double aktEndPos = pCurrentUnit.p1.GetPosition();
|
|
chkStartEnd(aktStartPos, aktEndPos);
|
|
RITree *tree;
|
|
tree = new RITree(aktRouteId, aktStartPos, aktEndPos,0,0);
|
|
int curRoute;
|
|
double curStartPos, curEndPos;
|
|
for (int i = 1; i < GetNoComponents(); i++)
|
|
{
|
|
// Get start and end of current unit
|
|
Get(i, pCurrentUnit);
|
|
curRoute = pCurrentUnit.p0.GetRouteId();
|
|
curStartPos = pCurrentUnit.p0.GetPosition();
|
|
curEndPos = pCurrentUnit.p1.GetPosition();
|
|
chkStartEnd(curStartPos, curEndPos);
|
|
if (curRoute != aktRouteId) {
|
|
tree->Insert(aktRouteId, aktStartPos, aktEndPos);
|
|
aktRouteId = curRoute;
|
|
aktStartPos = curStartPos;
|
|
aktEndPos = curEndPos;
|
|
} else { // curRoute == aktRouteId concat pieces if possible
|
|
if (curEndPos >= aktStartPos && curStartPos < aktStartPos)
|
|
aktStartPos = curStartPos;
|
|
else {
|
|
if (curStartPos <= aktEndPos && aktEndPos < curEndPos)
|
|
aktEndPos = curEndPos;
|
|
else { //concat impossible start new routeInterval for gline.
|
|
tree->Insert(aktRouteId, aktStartPos, aktEndPos);
|
|
aktRouteId = curRoute;
|
|
aktStartPos = curStartPos;
|
|
aktEndPos = curEndPos;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
tree->Insert(aktRouteId, aktStartPos, aktEndPos);
|
|
tree->TreeToGLine(res);
|
|
tree->TreeToDbArray(&(this->m_trajectory));
|
|
tree->RemoveTree();
|
|
res->SetSorted(true);
|
|
res->SetDefined(true);
|
|
SetTrajectoryDefined(true);
|
|
} else res->SetDefined(false);
|
|
}
|
|
res->TrimToSize();
|
|
}
|
|
else
|
|
{
|
|
res->SetDefined(false);
|
|
}
|
|
}
|
|
|
|
void MGPoint::Deftime(Periods &res) const{
|
|
res.Clear();
|
|
Periods per(0);
|
|
UGPoint unit;
|
|
res.StartBulkLoad();
|
|
for( int i = 0; i < GetNoComponents(); i++ ) {
|
|
Get( i, unit );
|
|
if (unit.IsDefined())
|
|
res.MergeAdd(unit.timeInterval);
|
|
}
|
|
res.EndBulkLoad(false);
|
|
}
|
|
|
|
|
|
/*
|
|
Operations with ~mgpoint~
|
|
|
|
Euclidean Distance computing
|
|
|
|
*/
|
|
|
|
void MGPoint::Distance(const MGPoint *mgp, MReal *result) const{
|
|
if (IsDefined()&&mgp->IsDefined()){
|
|
MPoint *p1 = new MPoint(0);
|
|
MPoint *p2 = new MPoint(0);
|
|
Mgpoint2mpoint(p1);
|
|
mgp->Mgpoint2mpoint(p2);
|
|
UReal uReal(true);
|
|
|
|
RefinementPartition<MPoint, MPoint, UPoint,
|
|
UPoint> rp(*p1, *p2);
|
|
|
|
result->Clear();
|
|
result->Resize(rp.Size());
|
|
result->StartBulkLoad();
|
|
for( unsigned int i = 0; i < rp.Size(); i++ )
|
|
{
|
|
Interval<Instant> iv;
|
|
int u1Pos, u2Pos;
|
|
UPoint u1;
|
|
UPoint u2;
|
|
|
|
rp.Get(i, iv, u1Pos, u2Pos);
|
|
if (u1Pos == -1 || u2Pos == -1)
|
|
continue;
|
|
else {
|
|
p1->Get(u1Pos, u1);
|
|
p2->Get(u2Pos, u2);
|
|
}
|
|
if(u1.IsDefined() && u2.IsDefined())
|
|
{ // do not need to test for overlapping deftimes anymore...
|
|
u1.Distance( u2, uReal );
|
|
result->MergeAdd( uReal );
|
|
}
|
|
}
|
|
result->EndBulkLoad();
|
|
p1->DeleteIfAllowed();
|
|
p2->DeleteIfAllowed();
|
|
}
|
|
}
|
|
|
|
void MGPoint::DistanceE(const MGPoint* mgp, MReal* result)const{
|
|
//Network* pNetwork = NetworkManager::GetNetwork(mgp->GetNetworkId());
|
|
Network* pNetwork = GetNetwork();
|
|
UReal uReal(true);
|
|
result->StartBulkLoad();
|
|
UGPoint ugp1;
|
|
UGPoint ugp2;
|
|
UGPoint* ug1 = new UGPoint(true);
|
|
UGPoint* ug2 = new UGPoint(true);
|
|
Instant start;
|
|
Instant end;
|
|
Get(0,ugp1);
|
|
Get(0,ugp2);
|
|
if(ugp1.timeInterval.start < ugp2.timeInterval.start)
|
|
start = ugp2.timeInterval.start;
|
|
else
|
|
start = ugp1.timeInterval.start;
|
|
Get(GetNoComponents() - 1,ugp1);
|
|
mgp->Get(mgp->GetNoComponents() -1 ,ugp2);
|
|
if(ugp1.timeInterval.end < ugp2.timeInterval.end)
|
|
end = ugp1.timeInterval.end;
|
|
else
|
|
end = ugp2.timeInterval.end;
|
|
int pos1 = 0,pos2 = 0;
|
|
uReal.timeInterval.start = start;
|
|
Get(pos1,ugp1);
|
|
mgp->Get(pos2,ugp2);
|
|
*ug1 = ugp1;
|
|
*ug2 = ugp2;
|
|
while(1){
|
|
assert(ug1->timeInterval.start >= uReal.timeInterval.start);
|
|
assert(ug2->timeInterval.start >= uReal.timeInterval.start);
|
|
if(ug2->timeInterval.end < ug1->timeInterval.start){
|
|
pos2++;
|
|
mgp->Get(pos2,ugp2);
|
|
*ug2 = ugp2;
|
|
continue;
|
|
}
|
|
if(ug2->timeInterval.start > ug1->timeInterval.end){
|
|
pos1++;
|
|
Get(pos1,ugp1);
|
|
*ug1 = ugp1;
|
|
continue;
|
|
}
|
|
//starttime
|
|
if(ug1->timeInterval.start < uReal.timeInterval.start){ //split
|
|
GPoint gp0;
|
|
ug1->TemporalFunction(uReal.timeInterval.start,gp0,true);
|
|
assert(gp0.IsDefined());
|
|
ug1->timeInterval.start = uReal.timeInterval.start;
|
|
ug1->p0 = gp0;
|
|
}
|
|
if(ug2->timeInterval.start < uReal.timeInterval.start){ //split
|
|
GPoint gp0;
|
|
ug2->TemporalFunction(uReal.timeInterval.start,gp0,true);
|
|
assert(gp0.IsDefined());
|
|
ug2->timeInterval.start = uReal.timeInterval.start;
|
|
ug2->p0 = gp0;
|
|
}
|
|
//endtime
|
|
if(ug1->timeInterval.end < ug2->timeInterval.end){
|
|
uReal.timeInterval.end = ug1->timeInterval.end;
|
|
GPoint gp1;
|
|
ug2->TemporalFunction(uReal.timeInterval.end,gp1,true);
|
|
assert(gp1.IsDefined());
|
|
ug2->timeInterval.end = uReal.timeInterval.end;
|
|
ug2->p1 = gp1;
|
|
Point* p1_0 = new Point();
|
|
p1_0->SetDefined(true);
|
|
pNetwork->GetPointOnRoute(&ug1->p0,p1_0);
|
|
Point* p1_1 = new Point();
|
|
p1_1->SetDefined(true);
|
|
pNetwork->GetPointOnRoute(&ug1->p1,p1_1);
|
|
Point* p2_0 = new Point();
|
|
p2_0->SetDefined(true);
|
|
pNetwork->GetPointOnRoute(&ug2->p0,p2_0);
|
|
Point* p2_1 = new Point();
|
|
p2_1->SetDefined(true);
|
|
pNetwork->GetPointOnRoute(&ug2->p0,p2_1);
|
|
double dt = (uReal.timeInterval.end-uReal.timeInterval.start).ToDouble();
|
|
if(AlmostEqual(dt,0)){
|
|
uReal.a = 0.0;
|
|
uReal.b = 0.0;
|
|
uReal.c = pow(fabs(p1_0->GetX()-p2_0->GetX()),2) +
|
|
pow(fabs(p1_0->GetY()-p2_0->GetY()),2);
|
|
uReal.r = false;
|
|
result->MergeAdd(uReal);
|
|
}else{
|
|
double v1_x = (p1_1->GetX() - p1_0->GetX()) / dt;
|
|
double v1_y = (p1_1->GetY() - p1_0->GetY()) / dt;
|
|
double v2_x = (p2_1->GetX() - p2_0->GetX()) / dt;
|
|
double v2_y = (p2_1->GetY() - p2_0->GetY()) / dt;
|
|
double a = pow(fabs(v1_x-v2_x),2)+pow(fabs(v1_y-v2_y),2);
|
|
double b = 2*((p1_0->GetX()-p2_0->GetX())*(v1_x-v2_x) +
|
|
(p1_0->GetY()-p2_0->GetY())*(v1_y-v2_y));
|
|
double c = pow(fabs(p1_0->GetX()-p2_0->GetX()),2) +
|
|
pow(fabs(p1_0->GetY()-p2_0->GetY()),2);
|
|
uReal.a = a;
|
|
uReal.b = b;
|
|
uReal.c = c;
|
|
uReal.r = true;
|
|
result->MergeAdd(uReal);
|
|
}
|
|
uReal.r = false;
|
|
uReal.timeInterval.start = uReal.timeInterval.end;
|
|
pos1++;
|
|
if(pos1 == GetNoComponents()){
|
|
p1_0->DeleteIfAllowed();
|
|
p1_1->DeleteIfAllowed();
|
|
p2_0->DeleteIfAllowed();
|
|
p2_1->DeleteIfAllowed();
|
|
break;
|
|
}
|
|
Get(pos1,ugp1);
|
|
*ug1 = ugp1;
|
|
mgp->Get(pos2,ugp2);
|
|
*ug2 = ugp2;
|
|
GPoint gp0;
|
|
ug2->TemporalFunction(uReal.timeInterval.start,gp0,true);
|
|
assert(gp0.IsDefined());
|
|
ug2->timeInterval.start = uReal.timeInterval.start;
|
|
ug2->p0 = gp0;
|
|
p1_0->DeleteIfAllowed();
|
|
p1_1->DeleteIfAllowed();
|
|
p2_0->DeleteIfAllowed();
|
|
p2_1->DeleteIfAllowed();
|
|
}else{ //ugp1->end > ugp2.end
|
|
uReal.timeInterval.end = ug2->timeInterval.end;
|
|
GPoint gp1;
|
|
ug1->TemporalFunction(uReal.timeInterval.end,gp1,true);
|
|
assert(gp1.IsDefined());
|
|
ug1->timeInterval.end = uReal.timeInterval.end;
|
|
ug1->p1 = gp1;
|
|
Point* p1_0 = new Point();
|
|
p1_0->SetDefined(true);
|
|
pNetwork->GetPointOnRoute(&ug1->p0,p1_0);
|
|
Point* p1_1 = new Point();
|
|
p1_1->SetDefined(true);
|
|
pNetwork->GetPointOnRoute(&ug1->p1,p1_1);
|
|
Point* p2_0 = new Point();
|
|
p2_0->SetDefined(true);
|
|
pNetwork->GetPointOnRoute(&ug2->p0,p2_0);
|
|
Point* p2_1 = new Point();
|
|
p2_1->SetDefined(true);
|
|
pNetwork->GetPointOnRoute(&ug2->p0,p2_1);
|
|
double dt = (uReal.timeInterval.end-uReal.timeInterval.start).ToDouble();
|
|
if(AlmostEqual(dt,0)){
|
|
uReal.a = 0.0;
|
|
uReal.b = 0.0;
|
|
uReal.c = pow(fabs(p1_0->GetX()-p2_0->GetX()),2) +
|
|
pow(fabs(p1_0->GetY()-p2_0->GetY()),2);
|
|
uReal.r = false;
|
|
result->MergeAdd(uReal);
|
|
}else{
|
|
double v1_x = (p1_1->GetX() - p1_0->GetX()) / dt;
|
|
double v1_y = (p1_1->GetY() - p1_0->GetY()) / dt;
|
|
double v2_x = (p2_1->GetX() - p2_0->GetX()) / dt;
|
|
double v2_y = (p2_1->GetY() - p2_0->GetY()) / dt;
|
|
double a = pow(fabs(v1_x-v2_x),2)+pow(fabs(v1_y-v2_y),2);
|
|
double b = 2*((p1_0->GetX()-p2_0->GetX())*(v1_x-v2_x) +
|
|
(p1_0->GetY()-p2_0->GetY())*(v1_y-v2_y));
|
|
double c = pow(fabs(p1_0->GetX()-p2_0->GetX()),2) +
|
|
pow(fabs(p1_0->GetY()-p2_0->GetY()),2);
|
|
uReal.a = a;
|
|
uReal.b = b;
|
|
uReal.c = c;
|
|
uReal.r = true;
|
|
result->MergeAdd(uReal);
|
|
}
|
|
uReal.r = false;
|
|
uReal.timeInterval.start = uReal.timeInterval.end;
|
|
pos2++;
|
|
if(pos2 == mgp->GetNoComponents()){
|
|
p1_0->DeleteIfAllowed();
|
|
p1_1->DeleteIfAllowed();
|
|
p2_0->DeleteIfAllowed();
|
|
p2_1->DeleteIfAllowed();
|
|
break;
|
|
}
|
|
mgp->Get(pos2,ugp2);
|
|
*ug2 = ugp2;
|
|
Get(pos1,ugp1);
|
|
*ug1 = ugp1;
|
|
GPoint gp0;
|
|
ug1->TemporalFunction(uReal.timeInterval.start,gp0,true);
|
|
assert(gp0.IsDefined());
|
|
ug1->timeInterval.start = uReal.timeInterval.start;
|
|
ug1->p0 = gp0;
|
|
p1_0->DeleteIfAllowed();
|
|
p1_1->DeleteIfAllowed();
|
|
p2_0->DeleteIfAllowed();
|
|
p2_1->DeleteIfAllowed();
|
|
}
|
|
}
|
|
ug1->DeleteIfAllowed();
|
|
ug2->DeleteIfAllowed();
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
result->EndBulkLoad();
|
|
}
|
|
|
|
void MGPoint::DistanceFunction(const UGPoint* ug1, const UGPoint* ug2,
|
|
const Network* pNetwork, vector<UReal>& dist)
|
|
const{
|
|
assert(ug1->timeInterval.start == ug2->timeInterval.start);
|
|
assert(ug1->timeInterval.end == ug2->timeInterval.end);
|
|
if(*ug1 == *ug2){
|
|
UReal* ureal = new UReal(true);
|
|
ureal->timeInterval = ug1->timeInterval;
|
|
ureal->a = 0.0;
|
|
ureal->b = 0.0;
|
|
ureal->c = 0.0;
|
|
ureal->r = true;
|
|
dist.push_back(*ureal);
|
|
ureal->DeleteIfAllowed();
|
|
return;
|
|
}
|
|
GPoint* gp1 = new GPoint(true,GetNetworkId(),ug1->p0.GetRouteId(),
|
|
(ug1->p0.GetPosition()+ug1->p1.GetPosition())/2,ug1->p0.GetSide());
|
|
Tuple* sec1 = pNetwork->GetSectionOnRoute(gp1);
|
|
GPoint* gp2 = new GPoint(true,GetNetworkId(),ug2->p0.GetRouteId(),
|
|
(ug2->p0.GetPosition()+ug2->p1.GetPosition())/2,ug2->p0.GetSide());
|
|
Tuple* sec2 = pNetwork->GetSectionOnRoute(gp2);
|
|
gp1->DeleteIfAllowed();
|
|
gp2->DeleteIfAllowed();
|
|
double m1 = ((CcReal*)sec1->GetAttribute(SECTION_MEAS1))->GetRealval();
|
|
double m2 = ((CcReal*)sec1->GetAttribute(SECTION_MEAS2))->GetRealval();
|
|
int rid1 = ug1->p0.GetRouteId();
|
|
GPoint* ep1_0 = new GPoint(true,GetNetworkId(),rid1,m1,ug1->p0.GetSide());
|
|
GPoint* ep1_1 = new GPoint(true,GetNetworkId(),rid1,m2,ug1->p0.GetSide());
|
|
double meas1 = fabs(ug1->p0.GetPosition() - ep1_0->GetPosition());
|
|
double meas2 = fabs(ug1->p0.GetPosition() - ep1_1->GetPosition());
|
|
m1 = ((CcReal*)sec2->GetAttribute(SECTION_MEAS1))->GetRealval();
|
|
m2 = ((CcReal*)sec2->GetAttribute(SECTION_MEAS2))->GetRealval();
|
|
int rid2 = ug2->p0.GetRouteId();
|
|
GPoint* ep2_0 = new GPoint(true,GetNetworkId(),rid2,m1,ug2->p0.GetSide());
|
|
GPoint* ep2_1 = new GPoint(true,GetNetworkId(),rid2,m2,ug2->p0.GetSide());
|
|
double meas3 = fabs(ug2->p0.GetPosition() - ep2_0->GetPosition());
|
|
double meas4 = fabs(ug2->p0.GetPosition() - ep2_1->GetPosition());
|
|
//get the junction id
|
|
vector<JunctionSortEntry> juns;
|
|
CcInt* routeid1 = new CcInt(true,rid1);
|
|
pNetwork->GetJunctionsOnRoute(routeid1,juns);
|
|
TupleId j1 = 0;
|
|
TupleId j2 = 0;
|
|
for(unsigned int i = 0;i < juns.size();i++){
|
|
Tuple* t_jun = juns[i].m_pJunction;
|
|
if(((CcInt*)t_jun->GetAttribute(JUNCTION_ROUTE1_ID))->GetIntval() == rid1){
|
|
if(fabs(((CcReal*)t_jun->GetAttribute(JUNCTION_ROUTE1_MEAS))->GetRealval()
|
|
-ep1_0->GetPosition()) < 0.1)
|
|
j1 = t_jun->GetTupleId();
|
|
if(fabs(((CcReal*)t_jun->GetAttribute(JUNCTION_ROUTE1_MEAS))->GetRealval()
|
|
-ep1_1->GetPosition()) < 0.1)
|
|
j2 = t_jun->GetTupleId();
|
|
}
|
|
if(((CcInt*)t_jun->GetAttribute(JUNCTION_ROUTE2_ID))->GetIntval() == rid1){
|
|
if(fabs(((CcReal*)t_jun->GetAttribute(JUNCTION_ROUTE2_MEAS))->GetRealval()
|
|
-ep1_0->GetPosition()) < 0.1)
|
|
j1 = t_jun->GetTupleId();
|
|
if(fabs(((CcReal*)t_jun->GetAttribute(JUNCTION_ROUTE2_MEAS))->GetRealval()
|
|
-ep1_1->GetPosition()) < 0.1)
|
|
j2 = t_jun->GetTupleId();
|
|
}
|
|
}
|
|
routeid1->DeleteIfAllowed();
|
|
juns.clear();
|
|
CcInt* routeid2 = new CcInt(true,rid2);
|
|
pNetwork->GetJunctionsOnRoute(routeid2,juns);
|
|
TupleId j3 = 0;
|
|
TupleId j4 = 0;
|
|
for(unsigned int i = 0;i < juns.size();i++){
|
|
Tuple* t_jun = juns[i].m_pJunction;
|
|
if(((CcInt*)t_jun->GetAttribute(JUNCTION_ROUTE1_ID))->GetIntval() == rid2){
|
|
if(fabs(((CcReal*)t_jun->GetAttribute(JUNCTION_ROUTE1_MEAS))->GetRealval()
|
|
-ep2_0->GetPosition()) < 0.1)
|
|
j3 = t_jun->GetTupleId();
|
|
if(fabs(((CcReal*)t_jun->GetAttribute(JUNCTION_ROUTE1_MEAS))->GetRealval()
|
|
-ep2_1->GetPosition()) < 0.1)
|
|
j4 = t_jun->GetTupleId();
|
|
}
|
|
if(((CcInt*)t_jun->GetAttribute(JUNCTION_ROUTE2_ID))->GetIntval() == rid2){
|
|
if(fabs(((CcReal*)t_jun->GetAttribute(JUNCTION_ROUTE2_MEAS))->GetRealval()
|
|
-ep2_0->GetPosition()) < 0.1)
|
|
j3 = t_jun->GetTupleId();
|
|
if(fabs(((CcReal*)t_jun->GetAttribute(JUNCTION_ROUTE2_MEAS))->GetRealval()
|
|
-ep2_1->GetPosition()) < 0.1)
|
|
j4 = t_jun->GetTupleId();
|
|
}
|
|
}
|
|
routeid2->DeleteIfAllowed();
|
|
//cout<<j1<<" "<<j2<<" "<<j3<<" "<<j4<<endl;
|
|
//find network distance from storage
|
|
double l1,l2,l3,l4;
|
|
GLine* gline1 = new GLine(0);
|
|
GLine* gline2 = new GLine(0);
|
|
GLine* gline3 = new GLine(0);
|
|
GLine* gline4 = new GLine(0);
|
|
l1 = l2 = l3 = l4 = 0;
|
|
if(j1 == 0){ // not junction point, the start or end point of one route
|
|
assert(j2 != 0);
|
|
if(j3 == 0){
|
|
assert(j4 != 0);
|
|
pNetwork->FindSP(j2,j4,l4,gline4);
|
|
l3 = l4;
|
|
l3 += fabs(ep2_1->GetPosition()-ep2_0->GetPosition());
|
|
*gline3 = *gline4;
|
|
gline3->AddRouteInterval(rid2,ep2_1->GetPosition(),ep2_0->GetPosition());
|
|
}else{
|
|
pNetwork->FindSP(j2,j3,l3,gline3);
|
|
if(j4 == 0){
|
|
l4 = l3;
|
|
l4 += fabs(ep2_0->GetPosition()-ep2_1->GetPosition());
|
|
*gline4 = *gline3;
|
|
gline4->AddRouteInterval(rid2,ep2_0->GetPosition(),ep2_1->GetPosition());
|
|
}else
|
|
pNetwork->FindSP(j2,j4,l4,gline4);
|
|
}
|
|
l1 = l3;
|
|
l1 += fabs(ep1_0->GetPosition()-ep1_1->GetPosition());
|
|
*gline1 = *gline3;
|
|
gline1->AddRouteInterval(rid1,ep1_0->GetPosition(),ep1_1->GetPosition());
|
|
l2 = l4;
|
|
l2 += fabs(ep1_0->GetPosition()-ep1_1->GetPosition());
|
|
*gline2 = *gline4;
|
|
gline2->AddRouteInterval(rid1,ep1_0->GetPosition(),ep1_1->GetPosition());
|
|
}else{
|
|
if(j2 == 0){ //j2 not junction point
|
|
if(j3 == 0){
|
|
assert(j4 != 0);
|
|
pNetwork->FindSP(j1,j4,l2,gline2);
|
|
l1 = l2;
|
|
l1 += fabs(ep2_1->GetPosition()-ep2_0->GetPosition());
|
|
*gline1 = *gline2;
|
|
gline1->AddRouteInterval(rid2,ep2_1->GetPosition(),ep2_0->GetPosition());
|
|
}else{
|
|
pNetwork->FindSP(j1,j3,l1,gline1);
|
|
if(j4 == 0){
|
|
l2 = l1;
|
|
l2 += fabs(ep2_0->GetPosition()-ep2_1->GetPosition());
|
|
*gline2 = *gline1;
|
|
gline2->AddRouteInterval(rid2,ep2_0->GetPosition(),ep2_1->GetPosition());
|
|
}else //j3 !=0 j4 != 0
|
|
pNetwork->FindSP(j1,j4,l2,gline2);
|
|
}
|
|
l3 = l1;
|
|
l3 += fabs(ep1_1->GetPosition()-ep1_0->GetPosition());
|
|
*gline3 = *gline1;
|
|
gline3->AddRouteInterval(rid1,ep1_1->GetPosition(),ep1_0->GetPosition());
|
|
l4 = l2;
|
|
l4 += fabs(ep1_1->GetPosition()-ep1_0->GetPosition());
|
|
*gline4 = *gline2;
|
|
gline4->AddRouteInterval(rid1,ep1_1->GetPosition(),ep1_0->GetPosition());
|
|
}else{
|
|
if(j3 == 0){
|
|
assert(j4 != 0);
|
|
pNetwork->FindSP(j1,j4,l2,gline2);
|
|
pNetwork->FindSP(j2,j4,l4,gline4);
|
|
if(j1 == j3)
|
|
gline1->SetNetworkId(gline2->GetNetworkId());
|
|
else{
|
|
l1 = l2;
|
|
l1 += fabs(ep2_1->GetPosition()-ep2_0->GetPosition());
|
|
*gline1 = *gline2;
|
|
gline1->AddRouteInterval(rid2,ep2_1->GetPosition(),ep2_0->GetPosition());
|
|
}
|
|
l3 = l4;
|
|
l3 += fabs(ep2_1->GetPosition()-ep2_0->GetPosition());
|
|
*gline3 = *gline4;
|
|
gline3->AddRouteInterval(rid2,ep2_1->GetPosition(),ep2_0->GetPosition());
|
|
}else{
|
|
pNetwork->FindSP(j1,j3,l1,gline1);
|
|
pNetwork->FindSP(j2,j3,l3,gline3);
|
|
if(j4 == 0){
|
|
if(j1 == j4)
|
|
gline2->SetNetworkId(gline1->GetNetworkId());
|
|
else{
|
|
l2 = l1;
|
|
l2 += fabs(ep2_0->GetPosition()-ep2_1->GetPosition());
|
|
*gline2 = *gline1;
|
|
gline2->AddRouteInterval(rid2,ep2_0->GetPosition(),ep2_1->GetPosition());
|
|
}
|
|
l4 = l3;
|
|
l4 += fabs(ep2_0->GetPosition()-ep2_1->GetPosition());
|
|
*gline4 = *gline3;
|
|
gline4->AddRouteInterval(rid2,ep2_0->GetPosition(),ep2_1->GetPosition());
|
|
}else{
|
|
pNetwork->FindSP(j1,j4,l2,gline2);
|
|
pNetwork->FindSP(j2,j4,l4,gline4);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GLine* gl1 = new GLine(0);
|
|
GLine* gl2 = new GLine(0);
|
|
GLine* gl3 = new GLine(0);
|
|
GLine* gl4 = new GLine(0);
|
|
double dist1 = ep1_0->NewNetdistance(ep2_0,gl1);//ignore side info
|
|
double dist2 = ep1_0->NewNetdistance(ep2_1,gl2);
|
|
double dist3 = ep1_1->NewNetdistance(ep2_0,gl3);
|
|
double dist4 = ep1_1->NewNetdistance(ep2_1,gl4);
|
|
double v1 = ug1->p0.Netdistance(&ug1->p1)/
|
|
(ug1->timeInterval.end-ug1->timeInterval.start).ToDouble();
|
|
double v2 = ug2->p0.Netdistance(&ug2->p1)/
|
|
(ug2->timeInterval.end-ug2->timeInterval.start).ToDouble();
|
|
vector<double> c;
|
|
vector<double> b;
|
|
if(sec1->GetTupleId() == sec2->GetTupleId()){ // in the same section
|
|
double dist = fabs(ug1->p0.GetPosition()-ug2->p0.GetPosition());
|
|
c.push_back(dist);
|
|
if(ug1->p0.GetSide() == 0){
|
|
if(ug2->p0.GetSide() == 0){ //ug1 down ug2 down
|
|
if(ug1->p0.GetPosition() < ug2->p0.GetPosition())
|
|
b.push_back(v1-v2);
|
|
else
|
|
b.push_back(v2-v1);
|
|
}else{//ug1 down ug2 up
|
|
if(ug1->p0.GetPosition() < ug2->p0.GetPosition())
|
|
b.push_back(v1+v2);
|
|
else
|
|
b.push_back(-(v1+v2));
|
|
}
|
|
}else{
|
|
if(ug2->p0.GetSide() == 0){ //ug1 up ug2 down
|
|
if(ug1->p0.GetPosition() < ug2->p0.GetPosition())
|
|
b.push_back(-(v1+v2));
|
|
else
|
|
b.push_back(v1+v2);
|
|
}else{ //ug1 up ug2 up
|
|
if(ug1->p0.GetPosition() < ug2->p0.GetPosition())
|
|
b.push_back(v2-v1);
|
|
else
|
|
b.push_back(v1-v2);
|
|
}
|
|
}
|
|
}else{ //different section
|
|
if(ug1->p0.GetSide() == 0){ //ug1 Down
|
|
if(ug2->p0.GetSide() == 0){ //ug1 Down ug2 Down
|
|
assert(ep2_1->Inside(gl1,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_1->Inside(gline1,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){ //gl1
|
|
if(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist1-meas1-meas3);
|
|
b.push_back(v1+v2);
|
|
}
|
|
else{
|
|
c.push_back(meas1+dist1-meas3);
|
|
b.push_back(v2-v1);
|
|
}
|
|
assert(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01) == false);
|
|
assert(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_0->Inside(gline2,pNetwork->GetScalefactor()*0.01));
|
|
}else{
|
|
assert(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01) ==
|
|
ep1_1->Inside(gline1,pNetwork->GetScalefactor()*0.01));
|
|
if(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist1-meas1+meas3);
|
|
b.push_back(v1-v2);
|
|
}
|
|
else{
|
|
c.push_back(meas1+dist1+meas3);
|
|
b.push_back(-(v2+v1));
|
|
}
|
|
}
|
|
assert(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_0->Inside(gline2,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01)){//gl2
|
|
if(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist2-meas1-meas4);
|
|
b.push_back(v1-v2);
|
|
}else{
|
|
c.push_back(dist2+meas1-meas4);
|
|
b.push_back(-(v2+v1));
|
|
}
|
|
}else{
|
|
if(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist2-meas1+meas4);
|
|
b.push_back(v1+v2);
|
|
}
|
|
else{
|
|
c.push_back(meas1+dist2+meas4);
|
|
b.push_back(v2-v1);
|
|
}
|
|
}
|
|
assert(ep2_1->Inside(gl3,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_1->Inside(gline3,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_1->Inside(gl3,pNetwork->GetScalefactor()*0.01)){//gl3
|
|
if(ep1_0->Inside(gl3,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist3-meas2-meas3);
|
|
b.push_back(v2-v1);
|
|
}
|
|
else{
|
|
c.push_back(meas2+dist3-meas3);
|
|
b.push_back(v1+v2);
|
|
}
|
|
}else{
|
|
assert(ep1_0->Inside(gl3,pNetwork->GetScalefactor()*0.01) ==
|
|
ep1_0->Inside(gline3,pNetwork->GetScalefactor()*0.01));
|
|
if(ep1_0->Inside(gl3,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist3-meas2+meas3);
|
|
b.push_back(-(v1+v2));
|
|
}
|
|
else{
|
|
c.push_back(meas2+dist3+meas3);
|
|
b.push_back(v1-v2);
|
|
}
|
|
}
|
|
assert(ep2_0->Inside(gl4,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_0->Inside(gline4,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_0->Inside(gl4,pNetwork->GetScalefactor()*0.01)){ //gl4
|
|
if(ep1_0->Inside(gl4,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist4-meas2-meas4);
|
|
b.push_back(-(v2+v1));
|
|
}else{
|
|
c.push_back(dist4+meas2-meas4);
|
|
b.push_back(v1-v2);
|
|
}
|
|
}else{
|
|
if(ep1_0->Inside(gl4,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist4-meas2+meas4);
|
|
b.push_back(v2-v1);
|
|
}
|
|
else{
|
|
c.push_back(meas2+dist4+meas4);
|
|
b.push_back(v1+v2);
|
|
}
|
|
}
|
|
}else{ //case2 ug1 down ug2 Up
|
|
assert(ep2_1->Inside(gl1,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_1->Inside(gline1,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){ //gl1
|
|
if(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist1-meas1-meas3);
|
|
b.push_back(v1-v2);
|
|
}
|
|
else{
|
|
c.push_back(meas1+dist1-meas3);
|
|
b.push_back(-(v1+v2));
|
|
}
|
|
assert(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01) == false);
|
|
assert(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_0->Inside(gline2,pNetwork->GetScalefactor()*0.01));
|
|
}else{
|
|
assert(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01) ==
|
|
ep1_1->Inside(gline1,pNetwork->GetScalefactor()*0.01));
|
|
if(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist1-meas1+meas3);
|
|
b.push_back(v1+v2);
|
|
}
|
|
else{
|
|
c.push_back(meas1+dist1+meas3);
|
|
b.push_back(v2-v1);
|
|
}
|
|
}
|
|
assert(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_0->Inside(gline2,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01)){ //gl2
|
|
if(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist2-meas1-meas4);
|
|
b.push_back(v1+v2);
|
|
}else{
|
|
c.push_back(dist2+meas1-meas4);
|
|
b.push_back(v2-v1);
|
|
}
|
|
}else{
|
|
if(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist2-meas1+meas4);
|
|
b.push_back(v1-v2);
|
|
}
|
|
else{
|
|
c.push_back(meas1+dist2+meas4);
|
|
b.push_back(-(v1+v2));
|
|
}
|
|
}
|
|
assert(ep2_1->Inside(gl3,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_1->Inside(gline3,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_1->Inside(gl3,pNetwork->GetScalefactor()*0.01)){ //gl3
|
|
if(ep1_0->Inside(gl3,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist3-meas2-meas3);
|
|
b.push_back(-(v1+v2));
|
|
}
|
|
else{
|
|
c.push_back(meas2+dist3-meas3);
|
|
b.push_back(v1-v2);
|
|
}
|
|
}else{
|
|
assert(ep1_0->Inside(gl3,pNetwork->GetScalefactor()*0.01) ==
|
|
ep1_0->Inside(gline3,pNetwork->GetScalefactor()*0.01));
|
|
if(ep1_0->Inside(gl3,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist3-meas2+meas3);
|
|
b.push_back(v1-v2);
|
|
}
|
|
else{
|
|
c.push_back(meas2+dist3+meas3);
|
|
b.push_back(v2+v1);
|
|
}
|
|
}
|
|
assert(ep2_0->Inside(gl4,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_0->Inside(gline4,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_0->Inside(gl4,pNetwork->GetScalefactor()*0.01)){ //gl4
|
|
if(ep1_0->Inside(gl4,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist4-meas2-meas4);
|
|
b.push_back(v2-v1);
|
|
}else{
|
|
c.push_back(dist4+meas2-meas4);
|
|
b.push_back(v1+v2);
|
|
}
|
|
}else{
|
|
if(ep1_0->Inside(gl4,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist4-meas2+meas4);
|
|
b.push_back(-(v1+v2));
|
|
}
|
|
else{
|
|
c.push_back(meas2+dist4+meas4);
|
|
b.push_back(v1-v2);
|
|
}
|
|
}
|
|
}
|
|
}else{ //ug1 Up
|
|
if(ug2->p0.GetSide() == 0){ //case3 ug1 Up ug2 Down
|
|
assert(ep2_1->Inside(gl1,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_1->Inside(gline1,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){ //gl1
|
|
if(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist1-meas1-meas3);
|
|
b.push_back(v2-v1);
|
|
}
|
|
else{
|
|
c.push_back(meas1+dist1-meas3);
|
|
b.push_back(v1+v2);
|
|
}
|
|
assert(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01) == false);
|
|
assert(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_0->Inside(gline2,pNetwork->GetScalefactor()*0.01));
|
|
}else{
|
|
assert(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01) ==
|
|
ep1_1->Inside(gline1,pNetwork->GetScalefactor()*0.01));
|
|
if(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist1-meas1+meas3);
|
|
b.push_back(-(v2+v1));
|
|
}
|
|
else{
|
|
c.push_back(meas1+dist1+meas3);
|
|
b.push_back(v1-v2);
|
|
}
|
|
}
|
|
assert(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_0->Inside(gline2,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01)){ //gl2
|
|
if(ep1_1->Inside(gl2,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist2-meas1-meas4);
|
|
b.push_back(-(v2+v1));
|
|
}else{
|
|
c.push_back(dist2+meas1-meas4);
|
|
b.push_back(v1-v2);
|
|
}
|
|
}else{
|
|
if(ep1_1->Inside(gl2,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist2-meas1+meas4);
|
|
b.push_back(v2-v1);
|
|
}
|
|
else{
|
|
c.push_back(meas1+dist2+meas4);
|
|
b.push_back(v2+v1);
|
|
}
|
|
}
|
|
assert(ep2_1->Inside(gl3,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_1->Inside(gline3,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_1->Inside(gl3,pNetwork->GetScalefactor()*0.01)){ //gl3
|
|
if(ep1_0->Inside(gl3,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist3-meas2-meas3);
|
|
b.push_back(v1+v2);
|
|
}
|
|
else{
|
|
c.push_back(meas2+dist3-meas3);
|
|
b.push_back(v2-v1);
|
|
}
|
|
}else{
|
|
assert(ep1_0->Inside(gl3,pNetwork->GetScalefactor()*0.01) ==
|
|
ep1_0->Inside(gline3,pNetwork->GetScalefactor()*0.01));
|
|
if(ep1_0->Inside(gl3,pNetwork->GetScalefactor()*0.01)){//gl3
|
|
c.push_back(dist3-meas2+meas3);
|
|
b.push_back(v1-v2);
|
|
}
|
|
else{
|
|
c.push_back(meas2+dist3+meas3);
|
|
b.push_back(-(v2+v1));
|
|
}
|
|
}
|
|
assert(ep2_0->Inside(gl4,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_0->Inside(gline4,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_0->Inside(gl4,pNetwork->GetScalefactor()*0.01)){//gl4
|
|
if(ep1_0->Inside(gl4,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist4-meas2-meas4);
|
|
b.push_back(v1-v2);
|
|
}else{
|
|
c.push_back(dist4+meas2-meas4);
|
|
b.push_back(-(v2+v1));
|
|
}
|
|
}else{
|
|
if(ep1_0->Inside(gl4,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist4-meas2+meas4);
|
|
b.push_back(v1+v2);
|
|
}
|
|
else{
|
|
c.push_back(meas2+dist4+meas4);
|
|
b.push_back(v2-v1);
|
|
}
|
|
}
|
|
}else{//case4 ug1 Up ug2 Up
|
|
assert(ep2_1->Inside(gl1,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_1->Inside(gline1,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){//gl1
|
|
if(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist1-meas1-meas3);
|
|
b.push_back(-(v1+v2));
|
|
}
|
|
else{
|
|
c.push_back(meas1+dist1-meas3);
|
|
b.push_back(v1-v2);
|
|
}
|
|
assert(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01) == false);
|
|
assert(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_0->Inside(gline2,pNetwork->GetScalefactor()*0.01));
|
|
}else{
|
|
assert(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01) ==
|
|
ep1_1->Inside(gline1,pNetwork->GetScalefactor()*0.01));
|
|
if(ep1_1->Inside(gl1,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist1-meas1+meas3);
|
|
b.push_back(v2-v1);
|
|
}
|
|
else{
|
|
c.push_back(meas1+dist1+meas3);
|
|
b.push_back(v1+v2);
|
|
}
|
|
}
|
|
assert(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_0->Inside(gline2,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_0->Inside(gl2,pNetwork->GetScalefactor()*0.01)){ //gl2
|
|
if(ep1_1->Inside(gl2,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist2-meas1-meas4);
|
|
b.push_back(v2-v1);
|
|
}else{
|
|
c.push_back(dist2+meas1-meas4);
|
|
b.push_back(v1+v2);
|
|
}
|
|
}else{
|
|
if(ep1_1->Inside(gl2,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist2-meas1+meas4);
|
|
b.push_back(-(v1+v2));
|
|
}
|
|
else{
|
|
c.push_back(meas1+dist2+meas4);
|
|
b.push_back(v1-v2);
|
|
}
|
|
}
|
|
assert(ep2_1->Inside(gl3,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_1->Inside(gline3,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_1->Inside(gl3,pNetwork->GetScalefactor()*0.01)){ //gl3
|
|
if(ep1_0->Inside(gl3,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist3-meas2-meas3);
|
|
b.push_back(v1-v2);
|
|
}
|
|
else{
|
|
c.push_back(meas2+dist3-meas3);
|
|
b.push_back(-(v1+v2));
|
|
}
|
|
}else{
|
|
assert(ep1_0->Inside(gl3,pNetwork->GetScalefactor()*0.01) ==
|
|
ep1_0->Inside(gline3,pNetwork->GetScalefactor()*0.01));
|
|
if(ep1_0->Inside(gl3,pNetwork->GetScalefactor()*0.01)){//gl3
|
|
c.push_back(dist3-meas2+meas3);
|
|
b.push_back(v1+v2);
|
|
}
|
|
else{
|
|
c.push_back(meas2+dist3+meas3);
|
|
b.push_back(v2-v1);
|
|
}
|
|
}
|
|
assert(ep2_0->Inside(gl4,pNetwork->GetScalefactor()*0.01) ==
|
|
ep2_0->Inside(gline4,pNetwork->GetScalefactor()*0.01));
|
|
if(ep2_0->Inside(gl4,pNetwork->GetScalefactor()*0.01)){//gl4
|
|
if(ep1_0->Inside(gl4,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist4-meas2-meas4);
|
|
b.push_back(v1+v2);
|
|
}else{
|
|
c.push_back(dist4+meas2-meas4);
|
|
b.push_back(v2-v1);
|
|
}
|
|
}else{
|
|
if(ep1_0->Inside(gl4,pNetwork->GetScalefactor()*0.01)){
|
|
c.push_back(dist4-meas2+meas4);
|
|
b.push_back(v1-v2);
|
|
}
|
|
else{
|
|
c.push_back(meas2+dist4+meas4);
|
|
b.push_back(-(v1+v2));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//find the split points
|
|
vector<double> split_time;
|
|
for(unsigned int i = 0;i < c.size();i++){
|
|
for(unsigned int j = i + 1;j< c.size();j++){
|
|
double cc = c[j] - c[i];
|
|
double bb = b[i] - b[j];
|
|
if(!AlmostEqual(bb,0)){
|
|
if(!AlmostEqual(cc/bb,0) && cc/bb > 0.0){
|
|
Instant time(instanttype);
|
|
time.ReadFrom(cc/bb);
|
|
if(time > ug1->timeInterval.start && time < ug1->timeInterval.end )
|
|
split_time.push_back(cc/bb);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
sort(split_time.begin(),split_time.end());
|
|
vector<double>::iterator end = unique(split_time.begin(),split_time.end());
|
|
vector<double>::iterator begin = split_time.begin();
|
|
Instant time(instanttype);
|
|
|
|
double d = c[0]; //store distance
|
|
vector<double> result_time;
|
|
vector<double> result_dist;
|
|
for(unsigned int i = 1;i < c.size();i ++){
|
|
if(c[i] < d)
|
|
d = c[i];
|
|
}
|
|
result_time.push_back(0); //start time;
|
|
result_dist.push_back(d); //start distance
|
|
|
|
for(;begin != end;begin++){
|
|
time.ReadFrom(*begin);
|
|
double dt = (time - ug1->timeInterval.start).ToDouble();
|
|
d = b[0]*dt+c[0];
|
|
for(unsigned int i = 1;i < c.size();i++){
|
|
if(b[i]*dt+c[i] < d)
|
|
d = b[i]*dt+c[i];
|
|
}
|
|
result_time.push_back(dt);
|
|
result_dist.push_back(d);
|
|
}
|
|
double dt = (ug1->timeInterval.end-ug1->timeInterval.start).ToDouble();
|
|
d = b[0]*dt+c[0];//dist
|
|
for(unsigned int i = 1;i < c.size();i ++){
|
|
if(b[i]*dt+c[i] < d)
|
|
d = b[i]*dt+c[i];
|
|
}
|
|
result_time.push_back((ug1->timeInterval.end-
|
|
ug1->timeInterval.start).ToDouble());//end time;
|
|
result_dist.push_back(d);//end distance
|
|
for(unsigned int i = 0;i < result_time.size() - 1;i++){
|
|
UReal* ureal = new UReal(true);
|
|
time.ReadFrom(result_time[i]+ug1->timeInterval.start.ToDouble());
|
|
ureal->timeInterval.start = time;
|
|
time.ReadFrom(result_time[i+1]+ug1->timeInterval.start.ToDouble());
|
|
ureal->timeInterval.end = time;
|
|
double b = (result_dist[i+1]-result_dist[i])/
|
|
(result_time[i+1]-result_time[i]);
|
|
double c = result_dist[i]-b*result_time[i];
|
|
ureal->a = pow(b,2);
|
|
ureal->b = 2*b*c;
|
|
ureal->c = pow(c,2);
|
|
ureal->r = true;
|
|
dist.push_back(*ureal);
|
|
ureal->DeleteIfAllowed();
|
|
}
|
|
gl1->DeleteIfAllowed();
|
|
gl2->DeleteIfAllowed();
|
|
gl3->DeleteIfAllowed();
|
|
gl4->DeleteIfAllowed();
|
|
ep1_0->DeleteIfAllowed();
|
|
ep1_1->DeleteIfAllowed();
|
|
ep2_0->DeleteIfAllowed();
|
|
ep2_1->DeleteIfAllowed();
|
|
gline1->DeleteIfAllowed();
|
|
gline2->DeleteIfAllowed();
|
|
gline3->DeleteIfAllowed();
|
|
gline4->DeleteIfAllowed();
|
|
sec1->DeleteIfAllowed();
|
|
sec2->DeleteIfAllowed();
|
|
}
|
|
|
|
|
|
/*
|
|
|
|
let p0 and p1 of the UGPoint in the same section
|
|
|
|
*/
|
|
void MGPoint::DivideUGPoint(const Network* pNetwork)
|
|
{
|
|
MGPoint* mgp = new MGPoint(0);
|
|
mgp->StartBulkLoad();
|
|
UGPoint ug1;
|
|
UGPoint* ug;
|
|
for(int i = 0;i < GetNoComponents();i++){
|
|
Get(i,ug1);
|
|
ug = &ug1;
|
|
Tuple* tuple1 = pNetwork->GetSectionOnRoute(&ug->p0);
|
|
Tuple* tuple2 = pNetwork->GetSectionOnRoute(&ug->p1);
|
|
assert(tuple1 != NULL);
|
|
assert(tuple2 != NULL);
|
|
if(tuple1->GetTupleId() == tuple2->GetTupleId()){
|
|
mgp->Add(*ug);
|
|
continue;
|
|
}
|
|
/*
|
|
assume that there is at most one junction point between p0 and p1
|
|
this is very important because more junction points make it much complex
|
|
to split the UGPoint
|
|
*/
|
|
double dt = (ug->timeInterval.end-ug->timeInterval.start).ToDouble();
|
|
|
|
if(AlmostEqual(dt,0)){
|
|
continue;
|
|
}
|
|
double length = ug->p0.Netdistance(&ug->p1);
|
|
GPoint* endp1;
|
|
assert(ug->p0.GetSide() != None); //None is not allowed
|
|
double pos1 = 0.0;
|
|
if(ug->p0.GetSide() == Down)
|
|
pos1 = ((CcReal*)tuple1->GetAttribute(SECTION_MEAS1))->GetRealval();
|
|
if(ug->p0.GetSide() == Up)
|
|
pos1 = ((CcReal*)tuple1->GetAttribute(SECTION_MEAS2))->GetRealval();
|
|
endp1 = new GPoint(true,GetNetworkId(),ug->p0.GetRouteId(),
|
|
pos1,ug->p0.GetSide());
|
|
|
|
|
|
double dist1 = fabs(pos1-ug->p0.GetPosition());
|
|
UGPoint* u1 = new UGPoint(ug1);
|
|
Instant middle( (u1->timeInterval.start.ToDouble() +
|
|
(ug->timeInterval.end.ToDouble() -
|
|
ug->timeInterval.start.ToDouble())*dist1/length));
|
|
GPoint gp;
|
|
u1->TemporalFunction(middle,gp,true);
|
|
assert(gp.IsDefined());
|
|
u1->timeInterval.end = middle;
|
|
u1->timeInterval.rc = false;
|
|
u1->p1 = gp;
|
|
mgp->Add(*u1);
|
|
u1->DeleteIfAllowed();
|
|
|
|
GPoint* endp2;
|
|
double pos2 = 0.0;
|
|
if(ug->p1.GetSide() == Down)
|
|
pos2 = ((CcReal*)tuple2->GetAttribute(SECTION_MEAS2))->GetRealval();
|
|
if(ug->p1.GetSide() == Up)
|
|
pos2 = ((CcReal*)tuple2->GetAttribute(SECTION_MEAS1))->GetRealval();
|
|
endp2 = new GPoint(true,GetNetworkId(),ug->p1.GetRouteId(),
|
|
pos2,ug->p0.GetSide());
|
|
|
|
//double dist2 = fabs(pos2-ug->p1.GetPosition());
|
|
UGPoint* u2 = new UGPoint(ug1);
|
|
u2->TemporalFunction(middle,gp,true);
|
|
assert(gp.IsDefined());
|
|
u2->timeInterval.start = middle;
|
|
u2->p0 = gp;
|
|
mgp->Add(*u2);
|
|
|
|
u2->DeleteIfAllowed();
|
|
endp1->DeleteIfAllowed();
|
|
endp2->DeleteIfAllowed();
|
|
}
|
|
mgp->EndBulkLoad(true);
|
|
// *this = *mgp;
|
|
this->CopyFrom(mgp);
|
|
mgp->DeleteIfAllowed();
|
|
}
|
|
|
|
|
|
void MGPoint::DistanceN(MGPoint* mgp, MReal* result){
|
|
|
|
//Network* pNetwork = NetworkManager::GetNetwork(mgp->GetNetworkId());
|
|
Network* pNetwork = GetNetwork();
|
|
DivideUGPoint(pNetwork); //partition ugpoints
|
|
mgp->DivideUGPoint(pNetwork);
|
|
|
|
UReal uReal(true);
|
|
result->StartBulkLoad();
|
|
UGPoint ugp1;
|
|
UGPoint ugp2;
|
|
UGPoint* ug1 = new UGPoint(true);
|
|
UGPoint* ug2 = new UGPoint(true);
|
|
Instant start;
|
|
Instant end;
|
|
Get(0,ugp1);
|
|
mgp->Get(0,ugp2);
|
|
|
|
if(ugp1.timeInterval.start < ugp2.timeInterval.start)
|
|
start = ugp2.timeInterval.start;
|
|
else
|
|
start = ugp1.timeInterval.start;
|
|
Get(GetNoComponents() - 1,ugp1);
|
|
mgp->Get(mgp->GetNoComponents() - 1 ,ugp2);
|
|
if(ugp1.timeInterval.end < ugp2.timeInterval.end)
|
|
end = ugp1.timeInterval.end;
|
|
else
|
|
end = ugp2.timeInterval.end;
|
|
int pos1 = 0,pos2 = 0;
|
|
uReal.timeInterval.start = start;
|
|
Get(pos1,ugp1);
|
|
mgp->Get(pos2,ugp2);
|
|
*ug1 = ugp1;
|
|
*ug2 = ugp2;
|
|
|
|
while(1){
|
|
|
|
if(ug2->timeInterval.end < ug1->timeInterval.start){
|
|
pos2++;
|
|
mgp->Get(pos2,ugp2);
|
|
*ug2 = ugp2;
|
|
continue;
|
|
}
|
|
if(ug2->timeInterval.start > ug1->timeInterval.end){
|
|
pos1++;
|
|
Get(pos1,ugp1);
|
|
*ug1 = ugp1;
|
|
continue;
|
|
}
|
|
|
|
//starttime
|
|
if(ug1->timeInterval.start < uReal.timeInterval.start){ //time split
|
|
GPoint gp0;
|
|
ug1->TemporalFunction(uReal.timeInterval.start,gp0,true);
|
|
assert(gp0.IsDefined());
|
|
ug1->timeInterval.start = uReal.timeInterval.start;
|
|
ug1->p0 = gp0;
|
|
}
|
|
if(ug2->timeInterval.start < uReal.timeInterval.start){ //time split
|
|
GPoint gp0;
|
|
ug2->TemporalFunction(uReal.timeInterval.start,gp0,true);
|
|
assert(gp0.IsDefined());
|
|
ug2->timeInterval.start = uReal.timeInterval.start;
|
|
ug2->p0 = gp0;
|
|
}
|
|
//endtime
|
|
if(ug1->timeInterval.end < ug2->timeInterval.end){ //ug1.end < ug2.end
|
|
uReal.timeInterval.end = ug1->timeInterval.end;
|
|
GPoint gp1;
|
|
ug2->TemporalFunction(uReal.timeInterval.end,gp1,true);
|
|
assert(gp1.IsDefined());
|
|
ug2->timeInterval.end = uReal.timeInterval.end;
|
|
ug2->p1 = gp1;
|
|
|
|
double dt = (uReal.timeInterval.end-uReal.timeInterval.start).ToDouble();
|
|
if(AlmostEqual(dt,0)){
|
|
uReal.a = 0.0;
|
|
uReal.b = 0.0;
|
|
uReal.c = 0;
|
|
uReal.r = false;
|
|
// result->MergeAdd(uReal);
|
|
}else{
|
|
vector<UReal> df;//distance function
|
|
DistanceFunction(ug1,ug2,pNetwork,df);
|
|
for(unsigned int i = 0;i < df.size();i++){
|
|
uReal.timeInterval = df[i].timeInterval;
|
|
if(uReal.timeInterval.end == end)
|
|
uReal.timeInterval.rc = true;
|
|
else
|
|
uReal.timeInterval.rc = false;
|
|
uReal.a = df[i].a;
|
|
uReal.b = df[i].b;
|
|
uReal.c = df[i].c;
|
|
uReal.r = true;
|
|
|
|
result->MergeAdd(uReal);
|
|
}
|
|
}
|
|
uReal.r = false;
|
|
uReal.timeInterval.start = uReal.timeInterval.end;
|
|
pos1++;
|
|
if(pos1 == GetNoComponents()){
|
|
break;
|
|
}
|
|
Get(pos1,ugp1);
|
|
*ug1 = ugp1;
|
|
mgp->Get(pos2,ugp2);
|
|
*ug2 = ugp2;
|
|
GPoint gp0;
|
|
ug2->TemporalFunction(uReal.timeInterval.start,gp0,true);
|
|
assert(gp0.IsDefined());
|
|
ug2->timeInterval.start = uReal.timeInterval.start;
|
|
ug2->p0 = gp0;
|
|
|
|
}else{ //ugp1.end > ugp2.end
|
|
uReal.timeInterval.end = ug2->timeInterval.end;
|
|
GPoint gp1;
|
|
ug1->TemporalFunction(uReal.timeInterval.end,gp1,true);
|
|
assert(gp1.IsDefined());
|
|
ug1->timeInterval.end = uReal.timeInterval.end;
|
|
ug1->p1 = gp1;
|
|
|
|
double dt = (uReal.timeInterval.end-uReal.timeInterval.start).ToDouble();
|
|
if(AlmostEqual(dt,0)){
|
|
uReal.a = 0.0;
|
|
uReal.b = 0.0;
|
|
uReal.c = 0.0;
|
|
uReal.r = false;
|
|
// result->MergeAdd(uReal);
|
|
}else{
|
|
//double v1 = ug1->p0.Distance(&ug1->p1)/dt;
|
|
//double v2 = ug2->p0.Distance(&ug2->p1)/dt;
|
|
vector<UReal> df;//distance function
|
|
DistanceFunction(ug1,ug2,pNetwork,df);
|
|
for(unsigned int i = 0;i < df.size();i++){
|
|
uReal.timeInterval = df[i].timeInterval;
|
|
if(uReal.timeInterval.end == end)
|
|
uReal.timeInterval.rc = true;
|
|
else
|
|
uReal.timeInterval.rc = false;
|
|
|
|
uReal.a = df[i].a;
|
|
uReal.b = df[i].b;
|
|
uReal.c = df[i].c;
|
|
uReal.r = true;
|
|
result->MergeAdd(uReal);
|
|
}
|
|
}
|
|
uReal.r = false;
|
|
uReal.timeInterval.start = uReal.timeInterval.end;
|
|
pos2++;
|
|
if(pos2 == mgp->GetNoComponents()){
|
|
break;
|
|
}
|
|
mgp->Get(pos2,ugp2);
|
|
*ug2 = ugp2;
|
|
Get(pos1,ugp1);
|
|
*ug1 = ugp1;
|
|
GPoint gp0;
|
|
ug1->TemporalFunction(uReal.timeInterval.start,gp0,true);
|
|
assert(gp0.IsDefined());
|
|
ug1->timeInterval.start = uReal.timeInterval.start;
|
|
ug1->p0 = gp0;
|
|
}
|
|
}
|
|
ug1->DeleteIfAllowed();
|
|
ug2->DeleteIfAllowed();
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
result->EndBulkLoad();
|
|
}
|
|
|
|
/*
|
|
Networkdistance from ~gpoint~ to ~mgpoint~.
|
|
|
|
*/
|
|
|
|
void MGPoint::NetdistanceFromArg(const GPoint* gp, MReal* result) const
|
|
{
|
|
result->Clear();
|
|
if (!IsDefined() || gp == 0 || !gp->IsDefined() ||
|
|
GetNetworkId() != gp->GetNetworkId())
|
|
result->SetDefined(false);
|
|
else
|
|
{
|
|
Network *pNetwork = GetNetwork();
|
|
DbArray<ShortestPathTreeEntry> *spTree =
|
|
new DbArray<ShortestPathTreeEntry>(2 * pNetwork->GetNoSections() + 1);
|
|
ShortestPathTreeEntry actSectionSPEntryUp, actSectionSPEntryDown;
|
|
gp->ShortestPathTree(pNetwork, spTree);
|
|
UGPoint actMGPUnit;
|
|
vector<TupleId> passedSections;
|
|
result->StartBulkLoad();
|
|
Instant splittime;
|
|
for (int i = 0; i < units.Size(); i++ )
|
|
{
|
|
Get(i,actMGPUnit);
|
|
double startPos = actMGPUnit.GetUnitStartPos();
|
|
double endPos = actMGPUnit.GetUnitEndPos();
|
|
Instant starttime = actMGPUnit.GetUnitStartTime();
|
|
Instant endtime = actMGPUnit.GetUnitEndTime();
|
|
passedSections.clear();
|
|
actMGPUnit.GetPassedSections(pNetwork, passedSections);
|
|
size_t j = 0;
|
|
while (j < passedSections.size())
|
|
{
|
|
TupleId actSectTid = passedSections[j++];
|
|
Tuple *pActSect = pNetwork->GetSection(actSectTid);
|
|
int actSectId =
|
|
((CcInt*) pActSect->GetAttribute(SECTION_SID))->GetIntval();
|
|
double sectMeas1 =
|
|
((CcReal*)pActSect->GetAttribute(SECTION_MEAS1))->GetRealval();
|
|
double sectMeas2 =
|
|
((CcReal*)pActSect->GetAttribute(SECTION_MEAS2))->GetRealval();
|
|
double sectLength = fabs (sectMeas2 - sectMeas1);
|
|
int pos = 2*actSectId;
|
|
spTree->Get(pos, actSectionSPEntryUp);
|
|
spTree->Get(pos+1, actSectionSPEntryDown);
|
|
double startdist = 0.0;
|
|
double enddist = 0.0;
|
|
if (actSectionSPEntryUp.GetDist() == 0.0 &&
|
|
actSectionSPEntryDown.GetDist() == 0.0)
|
|
{
|
|
startdist = fabs(gp->GetPosition() - startPos);
|
|
enddist = fabs (gp->GetPosition() - endPos);
|
|
result->MergeAdd(UReal(actMGPUnit.GetUnitTimeInterval(),
|
|
startdist, enddist));
|
|
}
|
|
else
|
|
{
|
|
double diffDistanceUpDown =
|
|
fabs (actSectionSPEntryUp.GetDist() -
|
|
actSectionSPEntryDown.GetDist());
|
|
double correction = (sectLength - diffDistanceUpDown) / 2;
|
|
if (AlmostEqual(correction,0.0)) correction = 0.0;
|
|
double posOfSameDistance = 0.0;
|
|
double distOfPosOfSameDistance = 0.0;
|
|
if (actSectionSPEntryUp.GetDist() < actSectionSPEntryDown.GetDist())
|
|
{
|
|
posOfSameDistance = sectMeas2 - correction;
|
|
distOfPosOfSameDistance =
|
|
actSectionSPEntryDown.GetDist() - correction;
|
|
}
|
|
else
|
|
{
|
|
posOfSameDistance = sectMeas1 + correction;
|
|
distOfPosOfSameDistance =
|
|
actSectionSPEntryUp.GetDist() + correction;
|
|
}
|
|
if (startPos < posOfSameDistance)
|
|
startdist =
|
|
actSectionSPEntryUp.GetDist() + fabs(startPos - sectMeas1);
|
|
else
|
|
startdist =
|
|
actSectionSPEntryDown.GetDist() + fabs(startPos - sectMeas2);
|
|
if (endPos < posOfSameDistance)
|
|
enddist = actSectionSPEntryUp.GetDist() + fabs(endPos - sectMeas1);
|
|
else
|
|
enddist =
|
|
actSectionSPEntryDown.GetDist() + fabs(endPos - sectMeas2);
|
|
if (passedSections.size() == 1)
|
|
{
|
|
if ((startPos <= posOfSameDistance && endPos <= posOfSameDistance)||
|
|
(startPos >= posOfSameDistance && endPos >= posOfSameDistance))
|
|
{
|
|
result->MergeAdd(UReal(actMGPUnit.GetUnitTimeInterval(),
|
|
startdist, enddist));
|
|
|
|
}
|
|
else
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(posOfSameDistance);
|
|
if (starttime != splittime)
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime, splittime,
|
|
true, false),
|
|
startdist, distOfPosOfSameDistance));
|
|
|
|
if (splittime != endtime)
|
|
result->MergeAdd(UReal(Interval<Instant>(splittime, endtime,
|
|
true, false),
|
|
distOfPosOfSameDistance, enddist));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch(actMGPUnit.MovingDirection())
|
|
{
|
|
case Up:
|
|
{
|
|
if (startPos >= posOfSameDistance)
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas2);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryDown.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas2;
|
|
}
|
|
else
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(posOfSameDistance);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist, distOfPosOfSameDistance));
|
|
starttime = splittime;
|
|
}
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas2);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryDown.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas2;
|
|
}
|
|
break;
|
|
}
|
|
case Down:
|
|
{
|
|
if (startPos <= posOfSameDistance)
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas1);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryUp.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas1;
|
|
}
|
|
else
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(posOfSameDistance);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist, distOfPosOfSameDistance));
|
|
starttime = splittime;
|
|
}
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas1);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryUp.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas1;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case None: //should never been reached. No move => only 1 section
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
pActSect->DeleteIfAllowed();
|
|
pActSect = 0;
|
|
}
|
|
}
|
|
}
|
|
result->EndBulkLoad();
|
|
spTree->Destroy();
|
|
delete spTree;
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Returns the network distance from the ~mgpoint~ to the ~gpoint~
|
|
|
|
*/
|
|
|
|
void MGPoint::NetdistanceToArg(const GPoint* gp, MReal* result) const
|
|
{
|
|
result->Clear();
|
|
if (!IsDefined() || gp == 0 || !gp->IsDefined() ||
|
|
GetNetworkId() != gp->GetNetworkId())
|
|
result->SetDefined(false);
|
|
else
|
|
{
|
|
Network *pNetwork = GetNetwork();
|
|
DbArray<ShortestPathTreeEntry> *spTree =
|
|
new DbArray<ShortestPathTreeEntry>(2 * pNetwork->GetNoSections() + 1);
|
|
ShortestPathTreeEntry actSectionSPEntryUp, actSectionSPEntryDown;
|
|
gp->ReverseShortestPathTree(pNetwork, spTree);
|
|
UGPoint actMGPUnit;
|
|
vector<TupleId> passedSections;
|
|
result->StartBulkLoad();
|
|
Instant splittime;
|
|
for (int i = 0; i < units.Size(); i++ )
|
|
{
|
|
Get(i,actMGPUnit);
|
|
double startPos = actMGPUnit.GetUnitStartPos();
|
|
double endPos = actMGPUnit.GetUnitEndPos();
|
|
Instant starttime = actMGPUnit.GetUnitStartTime();
|
|
Instant endtime = actMGPUnit.GetUnitEndTime();
|
|
passedSections.clear();
|
|
actMGPUnit.GetPassedSections(pNetwork, passedSections);
|
|
size_t j = 0;
|
|
while (j < passedSections.size())
|
|
{
|
|
TupleId actSectTid = passedSections[j++];
|
|
Tuple *pActSect = pNetwork->GetSection(actSectTid);
|
|
int actSectId =
|
|
((CcInt*) pActSect->GetAttribute(SECTION_SID))->GetIntval();
|
|
double sectMeas1 =
|
|
((CcReal*)pActSect->GetAttribute(SECTION_MEAS1))->GetRealval();
|
|
double sectMeas2 =
|
|
((CcReal*)pActSect->GetAttribute(SECTION_MEAS2))->GetRealval();
|
|
double sectLength = fabs (sectMeas2 - sectMeas1);
|
|
int pos = 2*actSectId;
|
|
spTree->Get(pos, actSectionSPEntryUp);
|
|
spTree->Get(pos+1, actSectionSPEntryDown);
|
|
double startdist = 0.0;
|
|
double enddist = 0.0;
|
|
if (actSectionSPEntryDown.GetDist() == 0.0 &&
|
|
actSectionSPEntryUp.GetDist() == 0.0)
|
|
{
|
|
startdist = fabs(gp->GetPosition() - startPos);
|
|
enddist = fabs(gp->GetPosition() - endPos);
|
|
result->MergeAdd(UReal(actMGPUnit.GetUnitTimeInterval(),
|
|
startdist, enddist));
|
|
}
|
|
else
|
|
{
|
|
double diffDistanceUpDown =
|
|
fabs (actSectionSPEntryUp.GetDist() -
|
|
actSectionSPEntryDown.GetDist());
|
|
double correction = (sectLength - diffDistanceUpDown) / 2;
|
|
if (AlmostEqual(correction, 0.0))correction = 0.0;
|
|
double posOfSameDistance = 0.0;
|
|
double distOfPosOfSameDistance = 0.0;
|
|
if (actSectionSPEntryUp.GetDist() < actSectionSPEntryDown.GetDist())
|
|
{
|
|
posOfSameDistance = sectMeas2 - correction;
|
|
distOfPosOfSameDistance =
|
|
actSectionSPEntryDown.GetDist() + correction;
|
|
}
|
|
else
|
|
{
|
|
posOfSameDistance = sectMeas1 + correction;
|
|
distOfPosOfSameDistance =
|
|
actSectionSPEntryUp.GetDist() + correction;
|
|
}
|
|
if (startPos < posOfSameDistance)
|
|
startdist =
|
|
actSectionSPEntryDown.GetDist() + fabs(startPos - sectMeas1);
|
|
else
|
|
startdist =
|
|
actSectionSPEntryUp.GetDist() + fabs(startPos - sectMeas2);
|
|
if (endPos < posOfSameDistance)
|
|
enddist =
|
|
actSectionSPEntryDown.GetDist() + fabs(endPos - sectMeas1);
|
|
else
|
|
enddist =
|
|
actSectionSPEntryUp.GetDist() + fabs(endPos - sectMeas2);
|
|
if (passedSections.size() == 1)
|
|
{
|
|
if ((startPos <= posOfSameDistance && endPos <= posOfSameDistance)||
|
|
(startPos >= posOfSameDistance && endPos >= posOfSameDistance))
|
|
{
|
|
result->MergeAdd(UReal(actMGPUnit.GetUnitTimeInterval(),
|
|
startdist, enddist));
|
|
}
|
|
else
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(posOfSameDistance);
|
|
if (starttime != splittime)
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime, splittime,
|
|
true, false),
|
|
startdist, distOfPosOfSameDistance));
|
|
if (splittime != endtime)
|
|
result->MergeAdd(UReal(Interval<Instant>(splittime, endtime,
|
|
true, false),
|
|
distOfPosOfSameDistance, enddist));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch(actMGPUnit.MovingDirection())
|
|
{
|
|
case Up:
|
|
{
|
|
if (startPos >= posOfSameDistance)
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas2);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryDown.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas2;
|
|
}
|
|
else
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(posOfSameDistance);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist, distOfPosOfSameDistance));
|
|
starttime = splittime;
|
|
}
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas2);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryDown.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas2;
|
|
}
|
|
break;
|
|
}
|
|
case Down:
|
|
{
|
|
if (startPos <= posOfSameDistance)
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas1);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryUp.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas1;
|
|
}
|
|
else
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(posOfSameDistance);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
distOfPosOfSameDistance));
|
|
starttime = splittime;
|
|
}
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas1);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryUp.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas1;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case None:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
pActSect->DeleteIfAllowed();
|
|
pActSect = 0;
|
|
}
|
|
}
|
|
}
|
|
result->EndBulkLoad();
|
|
spTree->Destroy();
|
|
delete spTree;
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Networkdistance from ~gpoint~ to ~mgpoint~.
|
|
|
|
*/
|
|
|
|
void MGPoint::NetdistanceFromArgShort(const GPoint* gp, MReal* result) const
|
|
{
|
|
result->Clear();
|
|
if (!IsDefined() || gp == 0 || !gp->IsDefined() ||
|
|
GetNetworkId() != gp->GetNetworkId())
|
|
result->SetDefined(false);
|
|
else
|
|
{
|
|
Network *pNetwork = GetNetwork();
|
|
DbArray<ShortestPathTreeEntry> *spTree =
|
|
new DbArray<ShortestPathTreeEntry>(2 * pNetwork->GetNoSections() + 1);
|
|
SortedTree<Entry<SectionValue> > *targets =
|
|
new SortedTree<Entry<SectionValue> > (0);
|
|
GetPassedSections(pNetwork, targets);
|
|
gp->ShortestPathTree(pNetwork, spTree, targets);
|
|
targets->Destroy();
|
|
delete targets;
|
|
targets = 0;
|
|
ShortestPathTreeEntry actSectionSPEntryUp, actSectionSPEntryDown;
|
|
UGPoint actMGPUnit;
|
|
vector<TupleId> passedSections;
|
|
result->StartBulkLoad();
|
|
Instant splittime;
|
|
for (int i = 0; i < units.Size(); i++ )
|
|
{
|
|
Get(i,actMGPUnit);
|
|
double startPos = actMGPUnit.GetUnitStartPos();
|
|
double endPos = actMGPUnit.GetUnitEndPos();
|
|
Instant starttime = actMGPUnit.GetUnitStartTime();
|
|
Instant endtime = actMGPUnit.GetUnitEndTime();
|
|
passedSections.clear();
|
|
actMGPUnit.GetPassedSections(pNetwork, passedSections);
|
|
size_t j = 0;
|
|
while (j < passedSections.size())
|
|
{
|
|
TupleId actSectTid = passedSections[j++];
|
|
Tuple *pActSect = pNetwork->GetSection(actSectTid);
|
|
int actSectId =
|
|
((CcInt*) pActSect->GetAttribute(SECTION_SID))->GetIntval();
|
|
double sectMeas1 =
|
|
((CcReal*)pActSect->GetAttribute(SECTION_MEAS1))->GetRealval();
|
|
double sectMeas2 =
|
|
((CcReal*)pActSect->GetAttribute(SECTION_MEAS2))->GetRealval();
|
|
double sectLength = fabs (sectMeas2 - sectMeas1);
|
|
int pos = 2*actSectId;
|
|
spTree->Get(pos, actSectionSPEntryUp);
|
|
spTree->Get(pos+1, actSectionSPEntryDown);
|
|
double startdist = 0.0;
|
|
double enddist = 0.0;
|
|
if (actSectionSPEntryUp.GetDist() == 0.0 &&
|
|
actSectionSPEntryDown.GetDist() == 0.0)
|
|
{
|
|
startdist = fabs(gp->GetPosition() - startPos);
|
|
enddist = fabs (gp->GetPosition() - endPos);
|
|
result->MergeAdd(UReal(actMGPUnit.GetUnitTimeInterval(),
|
|
startdist, enddist));
|
|
}
|
|
else
|
|
{
|
|
double diffDistanceUpDown =
|
|
fabs (actSectionSPEntryUp.GetDist() -
|
|
actSectionSPEntryDown.GetDist());
|
|
double correction = (sectLength - diffDistanceUpDown) / 2;
|
|
if (AlmostEqual(correction,0.0)) correction = 0.0;
|
|
double posOfSameDistance = 0.0;
|
|
double distOfPosOfSameDistance = 0.0;
|
|
if (actSectionSPEntryUp.GetDist() < actSectionSPEntryDown.GetDist())
|
|
{
|
|
posOfSameDistance = sectMeas2 - correction;
|
|
distOfPosOfSameDistance =
|
|
actSectionSPEntryDown.GetDist() - correction;
|
|
}
|
|
else
|
|
{
|
|
posOfSameDistance = sectMeas1 + correction;
|
|
distOfPosOfSameDistance =
|
|
actSectionSPEntryUp.GetDist() + correction;
|
|
}
|
|
if (startPos < posOfSameDistance)
|
|
startdist =
|
|
actSectionSPEntryUp.GetDist() + fabs(startPos - sectMeas1);
|
|
else
|
|
startdist =
|
|
actSectionSPEntryDown.GetDist() + fabs(startPos - sectMeas2);
|
|
if (endPos < posOfSameDistance)
|
|
enddist = actSectionSPEntryUp.GetDist() + fabs(endPos - sectMeas1);
|
|
else
|
|
enddist =
|
|
actSectionSPEntryDown.GetDist() + fabs(endPos - sectMeas2);
|
|
if (passedSections.size() == 1)
|
|
{
|
|
if ((startPos <= posOfSameDistance && endPos <= posOfSameDistance)||
|
|
(startPos >= posOfSameDistance && endPos >= posOfSameDistance))
|
|
{
|
|
result->MergeAdd(UReal(actMGPUnit.GetUnitTimeInterval(),
|
|
startdist, enddist));
|
|
}
|
|
else
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(posOfSameDistance);
|
|
if (starttime != splittime)
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime, splittime,
|
|
true, false),
|
|
startdist, distOfPosOfSameDistance));
|
|
if (splittime != endtime)
|
|
result->MergeAdd(UReal(Interval<Instant>(splittime, endtime,
|
|
true, false),
|
|
distOfPosOfSameDistance, enddist));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch(actMGPUnit.MovingDirection())
|
|
{
|
|
case Up:
|
|
{
|
|
if (startPos >= posOfSameDistance){
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas2);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryDown.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas2;
|
|
}
|
|
else
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(posOfSameDistance);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist, distOfPosOfSameDistance));
|
|
starttime = splittime;
|
|
}
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas2);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryDown.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas2;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case Down:
|
|
{
|
|
if (startPos <= posOfSameDistance)
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas1);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryUp.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas1;
|
|
}
|
|
else
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(posOfSameDistance);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist, distOfPosOfSameDistance));
|
|
starttime = splittime;
|
|
}
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas1);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryUp.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas1;
|
|
}
|
|
break;
|
|
}
|
|
case None: //should never been reached. No move => only 1 section
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
pActSect->DeleteIfAllowed();
|
|
pActSect = 0;
|
|
}
|
|
}
|
|
}
|
|
result->EndBulkLoad();
|
|
spTree->Destroy();
|
|
delete spTree;
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Returns the network distance from the ~mgpoint~ to the ~gpoint~
|
|
|
|
*/
|
|
|
|
void MGPoint::NetdistanceToArgShort(const GPoint* gp, MReal* result) const
|
|
{
|
|
result->Clear();
|
|
if (!IsDefined() || gp == 0 || !gp->IsDefined() ||
|
|
GetNetworkId() != gp->GetNetworkId())
|
|
result->SetDefined(false);
|
|
else
|
|
{
|
|
Network *pNetwork = GetNetwork();
|
|
DbArray<ShortestPathTreeEntry> *spTree =
|
|
new DbArray<ShortestPathTreeEntry>(2 * pNetwork->GetNoSections() + 1);
|
|
SortedTree<Entry<SectionValue> > *targets =
|
|
new SortedTree<Entry<SectionValue> >(2*pNetwork->GetNoSections() + 1);
|
|
GetPassedSections(pNetwork, targets);
|
|
gp->ReverseShortestPathTree(pNetwork, spTree, targets);
|
|
ShortestPathTreeEntry actSectionSPEntryUp, actSectionSPEntryDown;
|
|
targets->Destroy();
|
|
delete targets;
|
|
targets = 0;
|
|
UGPoint actMGPUnit;
|
|
vector<TupleId> passedSections;
|
|
result->StartBulkLoad();
|
|
Instant splittime;
|
|
for (int i = 0; i < units.Size(); i++ )
|
|
{
|
|
Get(i,actMGPUnit);
|
|
double startPos = actMGPUnit.GetUnitStartPos();
|
|
double endPos = actMGPUnit.GetUnitEndPos();
|
|
Instant starttime = actMGPUnit.GetUnitStartTime();
|
|
Instant endtime = actMGPUnit.GetUnitEndTime();
|
|
passedSections.clear();
|
|
actMGPUnit.GetPassedSections(pNetwork, passedSections);
|
|
size_t j = 0;
|
|
while (j < passedSections.size())
|
|
{
|
|
TupleId actSectTid = passedSections[j++];
|
|
Tuple *pActSect = pNetwork->GetSection(actSectTid);
|
|
int actSectId =
|
|
((CcInt*) pActSect->GetAttribute(SECTION_SID))->GetIntval();
|
|
double sectMeas1 =
|
|
((CcReal*)pActSect->GetAttribute(SECTION_MEAS1))->GetRealval();
|
|
double sectMeas2 =
|
|
((CcReal*)pActSect->GetAttribute(SECTION_MEAS2))->GetRealval();
|
|
double sectLength = fabs (sectMeas2 - sectMeas1);
|
|
int pos = 2*actSectId;
|
|
spTree->Get(pos, actSectionSPEntryUp);
|
|
spTree->Get(pos+1, actSectionSPEntryDown);
|
|
double startdist = 0.0;
|
|
double enddist = 0.0;
|
|
if (actSectionSPEntryDown.GetDist() == 0.0 &&
|
|
actSectionSPEntryUp.GetDist() == 0.0)
|
|
{
|
|
startdist = fabs(gp->GetPosition() - startPos);
|
|
enddist = fabs(gp->GetPosition() - endPos);
|
|
result->MergeAdd(UReal(actMGPUnit.GetUnitTimeInterval(),
|
|
startdist, enddist));
|
|
}
|
|
else
|
|
{
|
|
double diffDistanceUpDown =
|
|
fabs (actSectionSPEntryUp.GetDist() -
|
|
actSectionSPEntryDown.GetDist());
|
|
double correction = (sectLength - diffDistanceUpDown) / 2;
|
|
if (AlmostEqual(correction, 0.0))correction = 0.0;
|
|
double posOfSameDistance = 0.0;
|
|
double distOfPosOfSameDistance = 0.0;
|
|
if (actSectionSPEntryUp.GetDist() < actSectionSPEntryDown.GetDist())
|
|
{
|
|
posOfSameDistance = sectMeas2 - correction;
|
|
distOfPosOfSameDistance =
|
|
actSectionSPEntryDown.GetDist() + correction;
|
|
}
|
|
else
|
|
{
|
|
posOfSameDistance = sectMeas1 + correction;
|
|
distOfPosOfSameDistance =
|
|
actSectionSPEntryUp.GetDist() + correction;
|
|
}
|
|
if (startPos < posOfSameDistance)
|
|
startdist =
|
|
actSectionSPEntryDown.GetDist() + fabs(startPos - sectMeas1);
|
|
else
|
|
startdist =
|
|
actSectionSPEntryUp.GetDist() + fabs(startPos - sectMeas2);
|
|
if (endPos < posOfSameDistance)
|
|
enddist =
|
|
actSectionSPEntryDown.GetDist() + fabs(endPos - sectMeas1);
|
|
else
|
|
enddist =
|
|
actSectionSPEntryUp.GetDist() + fabs(endPos - sectMeas2);
|
|
if (passedSections.size() == 1)
|
|
{
|
|
if ((startPos <= posOfSameDistance && endPos <= posOfSameDistance)||
|
|
(startPos >= posOfSameDistance && endPos >= posOfSameDistance))
|
|
{
|
|
result->MergeAdd(UReal(actMGPUnit.GetUnitTimeInterval(),
|
|
startdist, enddist));
|
|
}
|
|
else
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(posOfSameDistance);
|
|
if (starttime != splittime)
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime, splittime,
|
|
true, false),
|
|
startdist, distOfPosOfSameDistance));
|
|
if (splittime != endtime)
|
|
result->MergeAdd(UReal(Interval<Instant>(splittime, endtime,
|
|
true, false),
|
|
distOfPosOfSameDistance, enddist));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch(actMGPUnit.MovingDirection())
|
|
{
|
|
case Up:
|
|
{
|
|
if (startPos >= posOfSameDistance)
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas2);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryDown.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas2;
|
|
}
|
|
else
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(posOfSameDistance);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist, distOfPosOfSameDistance));
|
|
starttime = splittime;
|
|
}
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas2);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryDown.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas2;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case Down:
|
|
{
|
|
if (startPos <= posOfSameDistance)
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas1);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryUp.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas1;
|
|
}
|
|
else
|
|
{
|
|
splittime = actMGPUnit.TimeAtPos(posOfSameDistance);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
distOfPosOfSameDistance));
|
|
starttime = splittime;
|
|
}
|
|
splittime = actMGPUnit.TimeAtPos(sectMeas1);
|
|
if (starttime != splittime)
|
|
{
|
|
result->MergeAdd(UReal(Interval<Instant>(starttime ,
|
|
splittime,
|
|
true, false),
|
|
startdist,
|
|
actSectionSPEntryUp.GetDist()));
|
|
starttime = splittime;
|
|
}
|
|
startPos = sectMeas1;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case None:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
pActSect->DeleteIfAllowed();
|
|
pActSect = 0;
|
|
}
|
|
}
|
|
}
|
|
result->EndBulkLoad();
|
|
spTree->Destroy();
|
|
delete spTree;
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Returns the sections passed by the mgpoint.
|
|
|
|
*/
|
|
|
|
void MGPoint::GetPassedSections(SortedTree<Entry<SectionValue> > *result) const{
|
|
Network *pNetwork = GetNetwork();
|
|
GetPassedSections(pNetwork, result);
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
}
|
|
|
|
void MGPoint::GetPassedSections(const Network *pNetwork,
|
|
SortedTree<Entry<SectionValue> > *result) const{
|
|
if (IsDefined() && GetNoComponents() > 0){
|
|
UGPoint actUnit;
|
|
for (int i = 0; i < GetNoComponents(); i++){
|
|
Get(i,actUnit);
|
|
vector<TupleId> passedSections;
|
|
passedSections.clear();
|
|
actUnit.GetPassedSections(pNetwork, passedSections);
|
|
for (size_t j = 0; j < passedSections.size(); j++){
|
|
TupleId actSectTID = passedSections[j];
|
|
Tuple *actSectTuple = pNetwork->GetSection(actSectTID);
|
|
int sectID =
|
|
((CcInt*)actSectTuple->GetAttribute(SECTION_SID))->GetIntval();
|
|
result->Insert(Entry<SectionValue>(SectionValue(sectID, true)));
|
|
result->Insert(Entry<SectionValue>(SectionValue(sectID, false)));
|
|
actSectTuple->DeleteIfAllowed();
|
|
actSectTuple = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Translation from network ~mgpoint~ to spatial ~mpoint~
|
|
|
|
*/
|
|
|
|
void MGPoint::Mgpoint2mpoint(MPoint *mp) const {
|
|
if (IsDefined() && !IsEmpty()){
|
|
//Network* pNetwork = NetworkManager::GetNetwork(GetNetworkId());
|
|
Network* pNetwork = GetNetwork();
|
|
UGPoint pCurrUnit;
|
|
UGPoint CurrUnit;
|
|
int iAktRouteId = 1;
|
|
int lrsposakt = 0;
|
|
int lrsposnext = 0;
|
|
Tuple *pRoute = pNetwork->GetRoute(iAktRouteId);
|
|
SimpleLine *pRouteCurve = (SimpleLine*) pRoute->GetAttribute(ROUTE_CURVE);
|
|
Instant correcture(0,1,durationtype);
|
|
bool bendcorrecture = false;
|
|
Instant tStart, tEnd, tInter1, tInter2, tEndNew;
|
|
Point pStart(false);
|
|
Point pEnd(false);
|
|
LRS lrsAkt, lrsNext;
|
|
HalfSegment hs;
|
|
mp->Clear();
|
|
mp->StartBulkLoad();
|
|
for (int i = 0 ; i < GetNoComponents(); i++) {
|
|
Get(i, pCurrUnit);
|
|
CurrUnit = pCurrUnit;
|
|
tStart = pCurrUnit.timeInterval.start;
|
|
tEnd = pCurrUnit.timeInterval.end;
|
|
if (bendcorrecture) {
|
|
bendcorrecture = false;
|
|
if (tStart <= tEndNew) {
|
|
tStart = tEndNew;
|
|
if (tStart >= tEnd ) {
|
|
tEnd = tStart + correcture;
|
|
bendcorrecture = true;
|
|
tEndNew = tEnd;
|
|
}
|
|
}
|
|
}
|
|
if (pCurrUnit.p0.GetRouteId() != iAktRouteId || i == 0) {
|
|
pRoute->DeleteIfAllowed();
|
|
iAktRouteId = pCurrUnit.p0.GetRouteId();
|
|
pRoute = pNetwork->GetRoute(iAktRouteId);
|
|
pRouteCurve = (SimpleLine*) pRoute->GetAttribute(ROUTE_CURVE);
|
|
LRS lrs(pCurrUnit.p0.GetPosition(),0);
|
|
if (!pRouteCurve->Get(lrs, lrsposakt)) {
|
|
break;
|
|
}
|
|
pRouteCurve->Get( lrsposakt, lrsAkt );
|
|
pRouteCurve->Get( lrsAkt.hsPos, hs );
|
|
pStart = hs.AtPosition(pCurrUnit.p0.GetPosition() - lrsAkt.lrsPos);
|
|
}
|
|
if (pCurrUnit.p0.GetPosition() == pCurrUnit.p1.GetPosition()){
|
|
mp->Add(UPoint(
|
|
Interval<Instant> (tStart, tEnd,
|
|
pCurrUnit.timeInterval.lc, pCurrUnit.timeInterval.rc),
|
|
pStart, pStart));
|
|
} else {
|
|
if (pCurrUnit.p0.GetPosition() < pCurrUnit.p1.GetPosition()){
|
|
tInter1 = tStart;
|
|
lrsposnext = lrsposakt + 1;
|
|
if (lrsposnext < (pRouteCurve->Size()/2)){
|
|
pRouteCurve->Get(lrsposnext, lrsNext);
|
|
if (lrsNext.lrsPos >= pCurrUnit.p1.GetPosition()) {
|
|
pEnd = hs.AtPosition(pCurrUnit.p1.GetPosition() - lrsAkt.lrsPos);
|
|
mp->Add(UPoint(
|
|
Interval<Instant> (tInter1, tEnd,
|
|
pCurrUnit.timeInterval.lc, pCurrUnit.timeInterval.rc),
|
|
pStart, pEnd));
|
|
pStart = pEnd;
|
|
} else {
|
|
while (lrsNext.lrsPos <= pCurrUnit.p1.GetPosition() &&
|
|
lrsposnext < (pRouteCurve->Size()/2)){
|
|
tInter2 = CurrUnit.TimeAtPos(lrsNext.lrsPos);
|
|
pRouteCurve->Get(lrsNext.hsPos, hs);
|
|
pEnd = hs.AtPosition(0);
|
|
if (tInter1 >= tInter2) {
|
|
tInter2 = tInter1 + correcture;
|
|
bendcorrecture = true;
|
|
tEndNew = tInter2;
|
|
}
|
|
mp->Add(UPoint(
|
|
Interval<Instant> (tInter1, tInter2,
|
|
true, false),
|
|
pStart, pEnd));
|
|
tInter1 = tInter2;
|
|
pStart = pEnd;
|
|
lrsposakt = lrsposnext;
|
|
pRouteCurve->Get(lrsposakt, lrsAkt);
|
|
lrsposnext = lrsposakt +1;
|
|
if (lrsposnext < (pRouteCurve->Size()/2))
|
|
pRouteCurve->Get(lrsposnext, lrsNext);
|
|
}
|
|
pEnd = hs.AtPosition(pCurrUnit.p1.GetPosition() - lrsAkt.lrsPos);
|
|
if (tInter1 >= tEnd) {
|
|
tEnd = tInter1 + correcture;
|
|
bendcorrecture = true;
|
|
tEndNew = tEnd;
|
|
}
|
|
mp->Add(UPoint(
|
|
Interval<Instant>(
|
|
tInter1, tEnd, true, false),
|
|
pStart, pEnd));
|
|
pStart = pEnd;
|
|
}
|
|
} else {
|
|
pEnd = hs.AtPosition(pCurrUnit.p1.GetPosition() - lrsAkt.lrsPos);
|
|
if (tInter1 >= tEnd) {
|
|
tEnd = tInter1 + correcture;
|
|
bendcorrecture = true;
|
|
tEndNew = tEnd;
|
|
}
|
|
mp->Add(UPoint(
|
|
Interval<Instant>(
|
|
tInter1, tEnd, true, false),
|
|
pStart, pEnd));
|
|
pStart = pEnd;
|
|
}
|
|
} else {
|
|
if (lrsAkt.lrsPos <= pCurrUnit.p1.GetPosition()) {
|
|
pEnd = hs.AtPosition(pCurrUnit.p1.GetPosition() - lrsAkt.lrsPos);
|
|
mp->Add(UPoint(
|
|
Interval<Instant> (tStart, tEnd,
|
|
pCurrUnit.timeInterval.lc, pCurrUnit.timeInterval.rc),
|
|
pStart, pEnd));
|
|
pStart = pEnd;
|
|
} else {
|
|
tInter1 = tStart;
|
|
while (lrsAkt.lrsPos > pCurrUnit.p1.GetPosition() &&
|
|
lrsposakt >= 0){
|
|
pEnd = hs.AtPosition(0);
|
|
tInter2 = CurrUnit.TimeAtPos(lrsAkt.lrsPos);
|
|
if (tInter1 >= tInter2) {
|
|
tInter2 = tInter1 + correcture;
|
|
bendcorrecture = true;
|
|
tEndNew = tInter2;
|
|
}
|
|
mp->Add(UPoint(
|
|
Interval<Instant>
|
|
(tInter1,tInter2,true, false),
|
|
pStart, pEnd));
|
|
tInter1 = tInter2;
|
|
pStart = pEnd;
|
|
lrsposakt = lrsposakt - 1;
|
|
if (lrsposakt >= 0) {
|
|
pRouteCurve->Get(lrsposakt, lrsAkt);
|
|
pRouteCurve->Get(lrsAkt.hsPos, hs);
|
|
}
|
|
}
|
|
pEnd = hs.AtPosition(pCurrUnit.p1.GetPosition() - lrsAkt.lrsPos);
|
|
if (tInter1 >= tEnd) {
|
|
tEnd = tInter1 + correcture;
|
|
bendcorrecture = true;
|
|
tEndNew = tEnd;
|
|
}
|
|
mp->Add(UPoint(
|
|
Interval<Instant> (tInter1, tEnd,
|
|
pCurrUnit.timeInterval.lc, pCurrUnit.timeInterval.rc),
|
|
pStart, pEnd));
|
|
pStart = pEnd;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
mp->EndBulkLoad();
|
|
pRoute->DeleteIfAllowed();
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
}
|
|
else mp->SetDefined(false);
|
|
}
|
|
|
|
/*
|
|
Checks if ~mgpoint~ is present in the given ~periods~
|
|
|
|
*/
|
|
|
|
bool MGPoint::Present(Periods *per) const{
|
|
if (!IsDefined() || !per->IsDefined() || IsEmpty() || per->IsEmpty())
|
|
return false;
|
|
Interval<Instant> intper;
|
|
UGPoint pCurrUnit;
|
|
int j = 0;
|
|
int mid, first, last;
|
|
while (j < per->GetNoComponents()) {
|
|
per->Get( j, intper );
|
|
Get(0, pCurrUnit);
|
|
if(!intper.Before(pCurrUnit.timeInterval)){
|
|
Get(GetNoComponents()-1, pCurrUnit);
|
|
if (!pCurrUnit.timeInterval.Before(intper)){
|
|
first = 0;
|
|
last = GetNoComponents()-1;
|
|
while (first <= last) {
|
|
mid = (first + last) /2;
|
|
if (mid < 0 || mid >= GetNoComponents()) break;
|
|
Get( mid, pCurrUnit );
|
|
if (pCurrUnit.timeInterval.Before(intper)) first = mid + 1;
|
|
else {
|
|
if (intper.Before(pCurrUnit.timeInterval)) last = mid - 1;
|
|
else return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
j++;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
Searches binary the unit id of the mpgoint unit which includes the given time
|
|
stamp. Returns -1 if the time stamp is not found.
|
|
|
|
*/
|
|
int MGPoint::Position(const Instant &ins, bool atinst /*=true*/) const {
|
|
if(GetNoComponents() <= 0) return -1;
|
|
int mid = -1;
|
|
int first = 0;
|
|
int last = GetNoComponents() - 1;
|
|
UGPoint pCurrUnit;
|
|
Get(first, pCurrUnit);
|
|
if (pCurrUnit.timeInterval.start > ins) return -1;
|
|
Get(last, pCurrUnit);
|
|
if (pCurrUnit.timeInterval.end < ins) return -1;
|
|
while (first <= last) {
|
|
mid = (first+last)/2;
|
|
if (mid<0 || mid >= GetNoComponents()) return -1;
|
|
Get(mid, pCurrUnit);
|
|
if (pCurrUnit.timeInterval.end < ins) first = mid + 1;
|
|
else
|
|
if (pCurrUnit.timeInterval.start > ins ) last = mid - 1;
|
|
else return mid;
|
|
}
|
|
/*
|
|
If we try to find a start position of a period inside a mgpoint it must not
|
|
be the exact position it reaches to find the position nearest before the start
|
|
of the periods start to catch the units inside the periods.
|
|
|
|
*/
|
|
if (atinst) return -1;
|
|
else return mid-1;
|
|
}
|
|
|
|
|
|
bool MGPoint::Present(Instant *per) const {
|
|
if (!IsDefined() || IsEmpty()) return false;
|
|
int pos = Position(*per);
|
|
if (pos == -1) return false;
|
|
else return true;
|
|
}
|
|
|
|
/*
|
|
Computes the intersection of two ~mgpoint~
|
|
|
|
*/
|
|
void MGPoint::Intersection(const MGPoint *mgp, MGPoint *res) const {
|
|
// DbArray<RouteInterval> tra1 = GetTrajectory();
|
|
// DbArray<RouteInterval> tra2 = mgp->GetTrajectory();
|
|
// if (Intersects(tra1,tra2,true, true)){
|
|
UGPoint pCurr1, pCurr2;
|
|
Get(0, pCurr1);
|
|
mgp->Get(0, pCurr2);
|
|
//Network *pNetwork = NetworkManager::GetNetwork(pCurr1.p0.GetNetworkId());
|
|
Network* pNetwork = GetNetwork();
|
|
if (!pNetwork->IsDefined() || pNetwork == NULL) {
|
|
cerr << "Network does not exist."<< endl;
|
|
res->SetDefined(false);
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
} else {
|
|
if (pCurr1.p0.GetNetworkId() != pCurr2.p0.GetNetworkId()) {
|
|
cerr <<"mgpoints belong to different networks." << endl;
|
|
res->SetDefined(false);
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
} else {
|
|
MGPoint *resA = new MGPoint(0);
|
|
MGPoint *resB = new MGPoint(0);
|
|
refinementMovingGPoint (this, mgp, resA, resB);
|
|
if (resA == NULL || !resA->IsDefined() ||
|
|
resB == NULL || !resB->IsDefined() ||
|
|
resA->GetNoComponents() != resB->GetNoComponents ()){
|
|
res->SetDefined(false);
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
} else {
|
|
if (resA->GetNoComponents() < 1) {
|
|
res->SetDefined(false);
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
} else {
|
|
res->StartBulkLoad();
|
|
double interPosition;
|
|
Instant tinter, tinter2, tlast;
|
|
for (int i = 0; i < resA->GetNoComponents() ; i++) {
|
|
resA->Get(i,pCurr1);
|
|
resB->Get(i,pCurr2);
|
|
if (pCurr1.p0.GetRouteId() == pCurr2.p0.GetRouteId()) {
|
|
if (pCurr1.p0.GetPosition() == pCurr2.p0.GetPosition() &&
|
|
pCurr1.p1.GetPosition() == pCurr2.p1.GetPosition()) {
|
|
res->Add(pCurr1/*, pNetwork*/);
|
|
} else {
|
|
tinter =
|
|
(pCurr1.timeInterval.end - pCurr1.timeInterval.start)
|
|
* ((pCurr2.p0.GetPosition() - pCurr1.p0.GetPosition())/
|
|
(pCurr1.p1.GetPosition() - pCurr1.p0.GetPosition()-
|
|
pCurr2.p1.GetPosition() + pCurr2.p0.GetPosition()))+
|
|
pCurr1.timeInterval.start;
|
|
if (pCurr1.timeInterval.start <= tinter &&
|
|
tinter <= pCurr1.timeInterval.end)
|
|
{
|
|
interPosition = pCurr1.p0.GetPosition() +
|
|
(((pCurr1.p1.GetPosition() - pCurr1.p0.GetPosition())*
|
|
(tinter.ToDouble()-pCurr1.timeInterval.start.ToDouble())
|
|
/ (pCurr1.timeInterval.end.ToDouble() -
|
|
pCurr1.timeInterval.start.ToDouble())));
|
|
bool ok = true;
|
|
if (pCurr1.p0.GetPosition()!= pCurr1.p1.GetPosition())
|
|
{
|
|
if (AlmostEqual(interPosition, pCurr1.p0.GetPosition()))
|
|
ok = ok && pCurr1.timeInterval.lc;
|
|
if (AlmostEqual(interPosition , pCurr1.p1.GetPosition()))
|
|
ok = ok && pCurr1.timeInterval.rc;
|
|
}
|
|
else
|
|
if (AlmostEqual(interPosition, pCurr1.p0.GetPosition()))
|
|
ok = true;
|
|
else ok = false;
|
|
if(pCurr2.p0.GetPosition() != pCurr2.p1.GetPosition())
|
|
{
|
|
if (AlmostEqual(interPosition, pCurr2.p0.GetPosition()))
|
|
ok = ok && pCurr2.timeInterval.lc;
|
|
if (AlmostEqual(interPosition, pCurr2.p1.GetPosition()))
|
|
ok = ok && pCurr2.timeInterval.rc;
|
|
}
|
|
else
|
|
if (AlmostEqual(interPosition, pCurr2.p0.GetPosition()))
|
|
ok = true;
|
|
else ok = false;
|
|
if (ok)
|
|
{
|
|
res->Add(UGPoint(Interval<Instant> (tinter, tinter,
|
|
true, true),
|
|
pCurr1.p0.GetNetworkId(),
|
|
pCurr1.p0.GetRouteId(),
|
|
pCurr1.p0.GetSide(),
|
|
interPosition,
|
|
interPosition));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CcInt *pRid1 = new CcInt(true,pCurr1.p0.GetRouteId());
|
|
CcInt *pRid2 = new CcInt(true,pCurr2.p0.GetRouteId());
|
|
double r1meas = numeric_limits<double>::max();
|
|
double r2meas = numeric_limits<double>::max();
|
|
pNetwork->GetJunctionMeasForRoutes(pRid1,pRid2,r1meas,r2meas);
|
|
if ((r1meas != numeric_limits<double>::max() &&
|
|
r2meas != numeric_limits<double>::max())&&
|
|
(((pCurr1.p0.GetPosition() <= r1meas &&
|
|
r1meas <= pCurr1.p1.GetPosition()) ||
|
|
(pCurr1.p0.GetPosition() >= r1meas &&
|
|
r1meas >= pCurr1.p1.GetPosition())) &&
|
|
((pCurr2.p0.GetPosition() <= r2meas &&
|
|
r2meas <= pCurr2.p1.GetPosition()) ||
|
|
(pCurr2.p0.GetPosition() >= r2meas &&
|
|
r2meas >= pCurr2.p1.GetPosition()))))
|
|
{
|
|
UGPoint pCurr = pCurr1;
|
|
tinter = pCurr.TimeAtPos(r1meas);
|
|
pCurr = pCurr2;
|
|
tinter2 = pCurr.TimeAtPos(r2meas);
|
|
if (tinter == tinter2) {
|
|
bool ok = true;
|
|
if (AlmostEqual(r1meas, pCurr1.p0.GetPosition()))
|
|
ok = ok && pCurr1.timeInterval.lc;
|
|
if (AlmostEqual(r1meas, pCurr1.p1.GetPosition()))
|
|
ok = ok && pCurr1.timeInterval.rc;
|
|
if (AlmostEqual(r2meas, pCurr2.p0.GetPosition()))
|
|
ok = ok && pCurr2.timeInterval.lc;
|
|
if (AlmostEqual(r2meas, pCurr2.p1.GetPosition()))
|
|
ok = ok && pCurr2.timeInterval.rc;
|
|
if (ok)
|
|
res->Add(UGPoint(Interval<Instant> (tinter, tinter,
|
|
true, true),
|
|
pCurr1.p0.GetNetworkId(),
|
|
pCurr1.p0.GetRouteId(),
|
|
pCurr1.p0.GetSide(),
|
|
r1meas,
|
|
r1meas));
|
|
}
|
|
}
|
|
}// end if else same route
|
|
}// end for
|
|
res->EndBulkLoad(true);
|
|
if (res->GetNoComponents() > 0) res->SetDefined(true);
|
|
else res->SetDefined(false);
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
}
|
|
}
|
|
resA->DeleteIfAllowed();
|
|
resB->DeleteIfAllowed();
|
|
}
|
|
}
|
|
// } else {
|
|
// res->Clear();
|
|
// res->SetDefined(true);
|
|
// }
|
|
res->SetTrajectoryDefined(false);
|
|
res->m_trajectory.TrimToSize();
|
|
res->SetBoundingBoxDefined(false);
|
|
}
|
|
|
|
/*
|
|
Returns true if the two mgpoint met at any point of their trips.
|
|
|
|
*/
|
|
|
|
bool MGPoint::Intersects(const MGPoint *mgp) const
|
|
{
|
|
UGPoint pCurr1, pCurr2;
|
|
Get(0, pCurr1);
|
|
mgp->Get(0, pCurr2);
|
|
//Network *pNetwork = NetworkManager::GetNetwork(pCurr1.p0.GetNetworkId());
|
|
Network* pNetwork = GetNetwork();
|
|
if (!pNetwork->IsDefined() || pNetwork == NULL)
|
|
{
|
|
cerr << "Network does not exist."<< endl;
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if (pCurr1.p0.GetNetworkId() != pCurr2.p0.GetNetworkId())
|
|
{
|
|
cerr <<"mgpoints belong to different networks." << endl;
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
MGPoint *resA = new MGPoint(0);
|
|
MGPoint *resB = new MGPoint(0);
|
|
refinementMovingGPoint (this, mgp, resA, resB);
|
|
if (resA == NULL || !resA->IsDefined() ||
|
|
resB == NULL || !resB->IsDefined() ||
|
|
resA->GetNoComponents() != resB->GetNoComponents ())
|
|
{
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
resA->DeleteIfAllowed();
|
|
resB->DeleteIfAllowed();
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if (resA->GetNoComponents() < 1)
|
|
{
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
resA->DeleteIfAllowed();
|
|
resB->DeleteIfAllowed();
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
double interPosition;
|
|
Instant tinter, tinter2, tlast;
|
|
for (int i = 0; i < resA->GetNoComponents() ; i++)
|
|
{
|
|
resA->Get(i,pCurr1);
|
|
resB->Get(i,pCurr2);
|
|
if (pCurr1.p0.GetRouteId() == pCurr2.p0.GetRouteId())
|
|
{
|
|
if (pCurr1.p0.GetPosition() == pCurr2.p0.GetPosition() &&
|
|
pCurr1.p1.GetPosition() == pCurr2.p1.GetPosition())
|
|
{
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
resA->DeleteIfAllowed();
|
|
resB->DeleteIfAllowed();
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
tinter =
|
|
(pCurr1.timeInterval.end - pCurr1.timeInterval.start)
|
|
* ((pCurr2.p0.GetPosition() - pCurr1.p0.GetPosition())/
|
|
(pCurr1.p1.GetPosition() - pCurr1.p0.GetPosition()-
|
|
pCurr2.p1.GetPosition() + pCurr2.p0.GetPosition()))+
|
|
pCurr1.timeInterval.start;
|
|
if (pCurr1.timeInterval.start <= tinter &&
|
|
tinter <= pCurr1.timeInterval.end)
|
|
{
|
|
interPosition = pCurr1.p0.GetPosition() +
|
|
(((pCurr1.p1.GetPosition() - pCurr1.p0.GetPosition())*
|
|
(tinter.ToDouble()-pCurr1.timeInterval.start.ToDouble())
|
|
/ (pCurr1.timeInterval.end.ToDouble() -
|
|
pCurr1.timeInterval.start.ToDouble())));
|
|
bool ok = true;
|
|
if (pCurr1.p0.GetPosition()!= pCurr1.p1.GetPosition())
|
|
{
|
|
if (AlmostEqual(interPosition, pCurr1.p0.GetPosition()))
|
|
ok = ok && pCurr1.timeInterval.lc;
|
|
if (AlmostEqual(interPosition, pCurr1.p1.GetPosition()))
|
|
ok = ok && pCurr1.timeInterval.rc;
|
|
}
|
|
else
|
|
if (AlmostEqual(interPosition, pCurr1.p0.GetPosition()))
|
|
ok = true;
|
|
else ok = false;
|
|
if(pCurr2.p0.GetPosition() != pCurr2.p1.GetPosition())
|
|
{
|
|
if (AlmostEqual(interPosition, pCurr2.p0.GetPosition()))
|
|
ok = ok && pCurr2.timeInterval.lc;
|
|
if (AlmostEqual(interPosition, pCurr2.p1.GetPosition()))
|
|
ok = ok && pCurr2.timeInterval.rc;
|
|
}
|
|
else
|
|
if (AlmostEqual(interPosition,pCurr2.p0.GetPosition()))
|
|
ok = true;
|
|
else ok = false;
|
|
if (ok)
|
|
{
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
resA->DeleteIfAllowed();
|
|
resB->DeleteIfAllowed();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CcInt *pRid1 = new CcInt(true,pCurr1.p0.GetRouteId());
|
|
CcInt *pRid2 = new CcInt(true,pCurr2.p0.GetRouteId());
|
|
double r1meas = numeric_limits<double>::max();
|
|
double r2meas = numeric_limits<double>::max();
|
|
pNetwork->GetJunctionMeasForRoutes(pRid1,pRid2,r1meas,r2meas);
|
|
if ((r1meas != numeric_limits<double>::max() &&
|
|
r2meas != numeric_limits<double>::max())&&
|
|
(((pCurr1.p0.GetPosition() <= r1meas &&
|
|
r1meas <= pCurr1.p1.GetPosition()) ||
|
|
(pCurr1.p0.GetPosition() >= r1meas &&
|
|
r1meas >= pCurr1.p1.GetPosition())) &&
|
|
((pCurr2.p0.GetPosition() <= r2meas &&
|
|
r2meas <= pCurr2.p1.GetPosition()) ||
|
|
(pCurr2.p0.GetPosition() >= r2meas &&
|
|
r2meas >= pCurr2.p1.GetPosition()))))
|
|
{
|
|
UGPoint pCurr = pCurr1;
|
|
tinter = pCurr.TimeAtPos(r1meas);
|
|
pCurr = pCurr2;
|
|
tinter2 = pCurr.TimeAtPos(r2meas);
|
|
if (tinter == tinter2)
|
|
{
|
|
bool ok = true;
|
|
if (AlmostEqual(r1meas, pCurr1.p0.GetPosition()))
|
|
ok = ok && pCurr1.timeInterval.lc;
|
|
if (AlmostEqual(r1meas, pCurr1.p1.GetPosition()))
|
|
ok = ok && pCurr1.timeInterval.rc;
|
|
if (AlmostEqual(r2meas, pCurr2.p0.GetPosition()))
|
|
ok = ok && pCurr2.timeInterval.lc;
|
|
if (AlmostEqual(r2meas, pCurr2.p1.GetPosition()))
|
|
ok = ok && pCurr2.timeInterval.rc;
|
|
if (ok)
|
|
{
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
resA->DeleteIfAllowed();
|
|
resB->DeleteIfAllowed();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}// end if else same route
|
|
}// end for
|
|
}
|
|
}
|
|
resA->DeleteIfAllowed();
|
|
resB->DeleteIfAllowed();
|
|
}
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
Checks if ~mgpoint~ is inside a ~gline~. Returns a ~mbool~ which is true for the
|
|
times the ~mgpoint~ is inside the ~gline~ false elsewhere.
|
|
|
|
*/
|
|
|
|
void MGPoint::Inside(const GLine *gl, MBool *res) const{
|
|
// DbArray<RouteInterval> riarr = GetTrajectory();
|
|
// DbArray<RouteInterval>* riglarr = gl->GetRouteIntervals();
|
|
// if (Intersects(riarr, *riglarr, true, gl->IsSorted())){
|
|
UGPoint pCurrentUnit;
|
|
Get(0, pCurrentUnit);
|
|
if (gl->GetNetworkId() != pCurrentUnit.p0.GetNetworkId()) {
|
|
res->SetDefined(false);
|
|
} else {
|
|
double mgStart, mgEnd, lStart, lEnd;
|
|
RouteInterval pCurrRInter;
|
|
bool swapped, found, bInterStart, bInterEnd;
|
|
Instant tInterStart, tInterEnd;
|
|
UBool interbool(true);
|
|
int iRouteMgp;
|
|
double interStart, interEnd;
|
|
res->StartBulkLoad();
|
|
for (int i = 0; i < GetNoComponents(); i++){
|
|
Get(i, pCurrentUnit);
|
|
UGPoint CurrUnit = pCurrentUnit;
|
|
int j = 0;
|
|
iRouteMgp = pCurrentUnit.p0.GetRouteId();
|
|
swapped = false;
|
|
mgStart = pCurrentUnit.p0.GetPosition();
|
|
mgEnd = pCurrentUnit.p1.GetPosition();
|
|
if (mgEnd < mgStart) {
|
|
mgStart = pCurrentUnit.p1.GetPosition();
|
|
mgEnd = pCurrentUnit.p0.GetPosition();
|
|
swapped = true;
|
|
}
|
|
if (gl->IsSorted()){
|
|
vector<RouteInterval> vRI;
|
|
RouteInterval currRInter;
|
|
vRI.clear();
|
|
getRouteIntervals(gl, iRouteMgp, mgStart, mgEnd, 0,
|
|
gl->NoOfComponents(), vRI);
|
|
if (vRI.size() > 0) {
|
|
size_t k = 0;
|
|
while (k < vRI.size()) {
|
|
currRInter = vRI[k];
|
|
if (pCurrentUnit.p0.GetPosition() <
|
|
pCurrentUnit.p1.GetPosition())
|
|
{
|
|
if (pCurrentUnit.p0.GetPosition() >=
|
|
currRInter.GetStartPos()) {
|
|
interbool.timeInterval.start =
|
|
pCurrentUnit.timeInterval.start;
|
|
interbool.timeInterval.lc = pCurrentUnit.timeInterval.lc;
|
|
interbool.constValue.Set(true, true);
|
|
} else {
|
|
interbool.timeInterval.start =
|
|
pCurrentUnit.timeInterval.start;
|
|
interbool.timeInterval.lc = pCurrentUnit.timeInterval.lc;
|
|
tInterStart = CurrUnit.TimeAtPos(currRInter.GetStartPos());
|
|
interbool.timeInterval.end = tInterStart;
|
|
interbool.timeInterval.rc = false;
|
|
interbool.constValue.Set(true,false);
|
|
res->MergeAdd(interbool);
|
|
//compute start of unit inside
|
|
interbool.timeInterval.start = tInterStart;
|
|
interbool.timeInterval.lc = true;
|
|
interbool.constValue.Set(true, true);
|
|
}
|
|
if (pCurrentUnit.p1.GetPosition() <= currRInter.GetEndPos()) {
|
|
interbool.timeInterval.end = pCurrentUnit.timeInterval.end;
|
|
interbool.timeInterval.rc = pCurrentUnit.timeInterval.rc;
|
|
res->MergeAdd(interbool);
|
|
} else {
|
|
// compute end of mgpoint at end of gline.and add result unit
|
|
interbool.timeInterval.rc = true;
|
|
tInterEnd = CurrUnit.TimeAtPos(currRInter.GetEndPos());
|
|
interbool.timeInterval.end = tInterEnd;
|
|
res->MergeAdd(interbool);
|
|
// the rest of the current unit is not in the current
|
|
// routeinterval.
|
|
checkEndOfUGPoint(currRInter.GetEndPos(),
|
|
pCurrentUnit.p1.GetPosition(), tInterEnd,
|
|
false, pCurrentUnit.timeInterval.end,
|
|
pCurrentUnit.timeInterval.rc, k, vRI,
|
|
res, iRouteMgp);
|
|
}
|
|
} else {
|
|
if (currRInter.GetEndPos() >= pCurrentUnit.p0.GetPosition()) {
|
|
interStart = pCurrentUnit.p0.GetPosition();
|
|
tInterStart = pCurrentUnit.timeInterval.start;
|
|
bInterStart = pCurrentUnit.timeInterval.lc;
|
|
} else {
|
|
interStart = currRInter.GetEndPos();
|
|
bInterStart = true;
|
|
tInterStart = CurrUnit.TimeAtPos(interStart);
|
|
}
|
|
if (currRInter.GetStartPos() <=
|
|
pCurrentUnit.p1.GetPosition()) {
|
|
interEnd = pCurrentUnit.p1.GetPosition();
|
|
tInterEnd = pCurrentUnit.timeInterval.end;
|
|
bInterEnd = pCurrentUnit.timeInterval.rc;
|
|
} else {
|
|
interEnd = currRInter.GetStartPos();
|
|
bInterEnd = true;
|
|
tInterEnd = CurrUnit.TimeAtPos(interEnd);
|
|
}
|
|
if (!(interStart == interEnd && (!bInterStart || !bInterEnd))) {
|
|
res->MergeAdd(interbool);
|
|
}
|
|
}
|
|
k++;
|
|
}
|
|
}
|
|
} else {
|
|
found = false;
|
|
while (j < gl->NoOfComponents()) {
|
|
gl->Get(j, pCurrRInter);
|
|
if (iRouteMgp == pCurrRInter.GetRouteId()){
|
|
mgStart = pCurrentUnit.p0.GetPosition();
|
|
mgEnd = pCurrentUnit.p1.GetPosition();
|
|
if (mgEnd < mgStart) {
|
|
mgStart = pCurrentUnit.p1.GetPosition();
|
|
mgEnd = pCurrentUnit.p0.GetPosition();
|
|
swapped = true;
|
|
}
|
|
lStart = pCurrRInter.GetStartPos();
|
|
lEnd = pCurrRInter.GetEndPos();
|
|
if (lStart > lEnd) {
|
|
lStart = pCurrRInter.GetEndPos();
|
|
lEnd = pCurrRInter.GetStartPos();
|
|
}
|
|
if (!(mgEnd < lStart || mgStart > lEnd || mgStart == mgEnd ||
|
|
lStart == lEnd)){
|
|
//intersection exists compute intersecting part and timevalues
|
|
//for resulting unit
|
|
found = true;
|
|
if (!swapped) {
|
|
if (lStart <= mgStart) {
|
|
interbool.timeInterval.start =
|
|
pCurrentUnit.timeInterval.start;
|
|
interbool.timeInterval.lc = pCurrentUnit.timeInterval.lc;
|
|
interbool.constValue.Set(true, true);
|
|
} else {
|
|
// compute and write unit befor mgpoint inside gline
|
|
interbool.timeInterval.start =
|
|
pCurrentUnit.timeInterval.start;
|
|
interbool.timeInterval.lc = pCurrentUnit.timeInterval.lc;
|
|
tInterStart = CurrUnit.TimeAtPos(lStart);
|
|
interbool.timeInterval.end = tInterStart;
|
|
interbool.timeInterval.rc = false;
|
|
interbool.constValue.Set(true,false);
|
|
res->MergeAdd(interbool);
|
|
//compute start of unit inside
|
|
interbool.timeInterval.start = tInterStart;
|
|
interbool.timeInterval.lc = true;
|
|
interbool.constValue.Set(true, true);
|
|
}
|
|
if (lEnd >= mgEnd) {
|
|
interbool.timeInterval.end = pCurrentUnit.timeInterval.end;
|
|
interbool.timeInterval.rc = pCurrentUnit.timeInterval.rc;
|
|
res->MergeAdd(interbool);
|
|
} else {
|
|
// compute end of mgpoint at end of gline.and add resultunit
|
|
interbool.timeInterval.rc = true;
|
|
tInterEnd = CurrUnit.TimeAtPos(lEnd);
|
|
interbool.timeInterval.end = tInterEnd;
|
|
res->MergeAdd(interbool);
|
|
// the rest of the current unit is not in the current
|
|
// routeinterval.
|
|
checkEndOfUGPoint(lEnd, pCurrentUnit.p1.GetPosition(),
|
|
tInterEnd, false,
|
|
pCurrentUnit.timeInterval.end,
|
|
pCurrentUnit.timeInterval.rc, j, gl,
|
|
res, iRouteMgp);
|
|
}
|
|
} else {
|
|
mgStart = pCurrentUnit.p0.GetPosition();
|
|
mgEnd = pCurrentUnit.p1.GetPosition();
|
|
if (lEnd >= mgStart) {
|
|
interbool.timeInterval.start =
|
|
pCurrentUnit.timeInterval.start;
|
|
interbool.timeInterval.lc = pCurrentUnit.timeInterval.lc;
|
|
interbool.constValue.Set(true, true);
|
|
} else {
|
|
// compute and write unit befor mgpoint inside gline
|
|
interbool.timeInterval.start =
|
|
pCurrentUnit.timeInterval.start;
|
|
interbool.timeInterval.lc = pCurrentUnit.timeInterval.lc;
|
|
tInterStart = CurrUnit.TimeAtPos(lEnd);
|
|
interbool.timeInterval.end = tInterStart;
|
|
interbool.timeInterval.rc = false;
|
|
interbool.constValue.Set(true,false);
|
|
res->MergeAdd(interbool);
|
|
//compute start of unit inside
|
|
interbool.timeInterval.start = tInterStart;
|
|
interbool.timeInterval.lc = true;
|
|
interbool.constValue.Set(true, true);
|
|
}
|
|
if (lStart <= mgEnd) {
|
|
interbool.timeInterval.end = pCurrentUnit.timeInterval.end;
|
|
interbool.timeInterval.rc = pCurrentUnit.timeInterval.rc;
|
|
res->MergeAdd(interbool);
|
|
} else {
|
|
// compute end of mgpoint at end of gline.and add resultunit
|
|
interbool.timeInterval.rc = true;
|
|
tInterEnd = CurrUnit.TimeAtPos(lStart);
|
|
interbool.timeInterval.end = tInterEnd;
|
|
res->MergeAdd(interbool);
|
|
// the rest of the current unit is not in the current
|
|
// routeinterval.
|
|
checkEndOfUGPoint(lEnd, pCurrentUnit.p1.GetPosition(),
|
|
tInterEnd, false,
|
|
pCurrentUnit.timeInterval.end,
|
|
pCurrentUnit.timeInterval.rc, j, gl,
|
|
res, iRouteMgp);
|
|
}
|
|
}
|
|
}else{
|
|
if (mgStart == mgEnd && pCurrentUnit.timeInterval.lc &&
|
|
pCurrentUnit.timeInterval.rc){
|
|
found = true;
|
|
interbool.timeInterval.start =
|
|
pCurrentUnit.timeInterval.start;
|
|
interbool.timeInterval.lc = pCurrentUnit.timeInterval.lc;
|
|
interbool.timeInterval.end = pCurrentUnit.timeInterval.end;
|
|
interbool.timeInterval.rc = pCurrentUnit.timeInterval.rc;
|
|
interbool.constValue.Set(true,true);
|
|
res->MergeAdd(interbool);
|
|
} else {
|
|
if (lStart == lEnd) {
|
|
if ((lStart > mgStart && lStart < mgEnd) ||
|
|
(lStart < mgStart && lStart > mgEnd)) {
|
|
found = true;
|
|
// compute and write unit befor mgpoint inside gline
|
|
interbool.timeInterval.start =
|
|
pCurrentUnit.timeInterval.start;
|
|
interbool.timeInterval.lc = pCurrentUnit.timeInterval.lc;
|
|
tInterStart = CurrUnit.TimeAtPos(lStart);
|
|
interbool.timeInterval.end = tInterStart;
|
|
interbool.timeInterval.rc = false;
|
|
interbool.constValue.Set(true,false);
|
|
res->MergeAdd(interbool);
|
|
interbool.timeInterval.start = tInterStart;
|
|
interbool.timeInterval.rc = true;
|
|
interbool.timeInterval.lc = true;
|
|
interbool.constValue.Set(true, true);
|
|
res->MergeAdd(interbool);
|
|
checkEndOfUGPoint(lEnd, pCurrentUnit.p1.GetPosition(),
|
|
tInterEnd, false,
|
|
pCurrentUnit.timeInterval.end,
|
|
pCurrentUnit.timeInterval.rc, j, gl,
|
|
res, iRouteMgp);
|
|
} else {
|
|
if (lStart == mgStart && pCurrentUnit.timeInterval.lc) {
|
|
found = true;
|
|
interbool.timeInterval.start =
|
|
pCurrentUnit.timeInterval.start;
|
|
interbool.timeInterval.lc =
|
|
pCurrentUnit.timeInterval.lc;
|
|
interbool.timeInterval.end =
|
|
pCurrentUnit.timeInterval.start;
|
|
interbool.timeInterval.rc = true;
|
|
interbool.constValue.Set(true,true);
|
|
res->MergeAdd(interbool);
|
|
checkEndOfUGPoint(lEnd, pCurrentUnit.p1.GetPosition(),
|
|
tInterEnd, false,
|
|
pCurrentUnit.timeInterval.end,
|
|
pCurrentUnit.timeInterval.rc, j, gl,
|
|
res, iRouteMgp);
|
|
} else {
|
|
if (lStart == mgEnd && pCurrentUnit.timeInterval.rc) {
|
|
found = true;
|
|
interbool.timeInterval.start =
|
|
pCurrentUnit.timeInterval.start;
|
|
interbool.timeInterval.lc =
|
|
pCurrentUnit.timeInterval.lc;
|
|
interbool.timeInterval.end =
|
|
pCurrentUnit.timeInterval.end;
|
|
interbool.timeInterval.rc = false;
|
|
interbool.constValue.Set(true,false);
|
|
res->MergeAdd(interbool);
|
|
interbool.timeInterval.start =
|
|
pCurrentUnit.timeInterval.end;
|
|
interbool.timeInterval.rc =
|
|
pCurrentUnit.timeInterval.rc;
|
|
interbool.timeInterval.lc = true;
|
|
interbool.constValue.Set(true, true);
|
|
res->MergeAdd(interbool);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if ((mgStart == lStart && mgEnd == lEnd) ||
|
|
(mgStart == lEnd && mgEnd == lStart)) {
|
|
found = true;
|
|
interbool.timeInterval = pCurrentUnit.timeInterval;
|
|
interbool.constValue.Set(true, true);
|
|
res->MergeAdd(interbool);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
j++;
|
|
} // end while
|
|
if (!found) {
|
|
//no intersection found mgpoint not inside gline
|
|
interbool.timeInterval = pCurrentUnit.timeInterval;
|
|
interbool.constValue.Set(true,false);
|
|
res->MergeAdd(interbool);
|
|
}
|
|
}
|
|
} // end for
|
|
res->EndBulkLoad();
|
|
}
|
|
// } else {
|
|
// const UGPoint *pFirst, *pLast;
|
|
// Get(0, pFirst);
|
|
// Get(GetNoComponents()-1, pLast);
|
|
// UBool interbool;
|
|
// interbool.timeInterval.start = pFirst->timeInterval.start;
|
|
// interbool.timeInterval.end = pLast->timeInterval.end;
|
|
// interbool.timeInterval.lc = pFirst->timeInterval.lc;
|
|
// interbool.timeInterval.rc = pLast->timeInterval.rc;
|
|
// interbool.constValue.Set(true,false);
|
|
// res->StartBulkLoad();
|
|
// res->MergeAdd(interbool);
|
|
// res->EndBulkLoad();
|
|
// }
|
|
}
|
|
|
|
/*
|
|
Restricts the ~mgpoint~ to the given ~periods~
|
|
|
|
*/
|
|
|
|
void MGPoint::Atperiods(const Periods *per, MGPoint *res) const{
|
|
if(!IsDefined() || !per->IsDefined() || IsEmpty() || per->IsEmpty())
|
|
{
|
|
res->SetDefined(false);
|
|
}
|
|
else //both are defined and have at least one interval
|
|
{
|
|
Instant utstart, utend;
|
|
GPoint uGPstart, uGPend;
|
|
bool ulc = true;
|
|
bool urc = true;
|
|
UGPoint pCurrentUnit;
|
|
int i = 0;
|
|
Get(i, pCurrentUnit);
|
|
int j = 0;
|
|
Interval<Instant> interval;
|
|
per->Get(j,interval);
|
|
while (interval.Before(pCurrentUnit.timeInterval))
|
|
{
|
|
if (++j >= per->GetNoComponents()) break;
|
|
else per->Get(j,interval);
|
|
}
|
|
if(pCurrentUnit.timeInterval.Before(interval))
|
|
{
|
|
i = Position(interval.start, false);
|
|
if (i != -1) Get(i, pCurrentUnit);
|
|
else i = 0;
|
|
}
|
|
res->StartBulkLoad();
|
|
while( i < GetNoComponents() && j < per->GetNoComponents())
|
|
{
|
|
if (pCurrentUnit.timeInterval.end < interval.start)
|
|
{
|
|
if( ++i >= GetNoComponents()) break;
|
|
else Get( i, pCurrentUnit );
|
|
}
|
|
else
|
|
{ // we have overlapping intervals, now
|
|
if (pCurrentUnit.timeInterval.start > interval.start &&
|
|
pCurrentUnit.timeInterval.end < interval.end)
|
|
{
|
|
res->Add(pCurrentUnit);
|
|
if (++i >= GetNoComponents()) break;
|
|
else Get(i,pCurrentUnit);
|
|
}
|
|
else
|
|
{
|
|
if (pCurrentUnit.timeInterval.start == interval.start)
|
|
{
|
|
utstart = interval.start;
|
|
uGPstart = pCurrentUnit.p0;
|
|
ulc = pCurrentUnit.timeInterval.lc && interval.lc;
|
|
}
|
|
else
|
|
{
|
|
if (pCurrentUnit.timeInterval.start > interval.start)
|
|
{
|
|
utstart = pCurrentUnit.timeInterval.start;
|
|
uGPstart = pCurrentUnit.p0;
|
|
ulc = pCurrentUnit.timeInterval.lc;
|
|
}
|
|
else
|
|
{
|
|
if (pCurrentUnit.timeInterval.start < interval.start)
|
|
{
|
|
utstart = interval.start;
|
|
ulc = interval.lc;
|
|
pCurrentUnit.TemporalFunction(utstart, uGPstart, false);
|
|
}
|
|
}
|
|
}
|
|
if (pCurrentUnit.timeInterval.end == interval.end)
|
|
{
|
|
utend = interval.end;
|
|
uGPend = pCurrentUnit.p1;
|
|
urc = pCurrentUnit.timeInterval.rc && interval.rc;
|
|
}
|
|
else
|
|
{
|
|
if (pCurrentUnit.timeInterval.end < interval.end)
|
|
{
|
|
utend = pCurrentUnit.timeInterval.end;
|
|
urc = pCurrentUnit.timeInterval.rc;
|
|
uGPend = pCurrentUnit.p1;
|
|
}
|
|
else
|
|
{
|
|
if (pCurrentUnit.timeInterval.end > interval.end)
|
|
{
|
|
utend = interval.end;
|
|
pCurrentUnit.TemporalFunction(utend, uGPend , false);
|
|
urc = interval.rc;
|
|
}
|
|
}
|
|
}
|
|
res->Add(UGPoint(Interval<Instant>(utstart, utend, ulc, urc),
|
|
uGPstart.GetNetworkId(),
|
|
uGPstart.GetRouteId(),
|
|
uGPstart.GetSide(),
|
|
uGPstart.GetPosition(),
|
|
uGPend.GetPosition()));
|
|
if( interval.end == pCurrentUnit.timeInterval.end )
|
|
{
|
|
// same ending instant
|
|
if (interval.rc == pCurrentUnit.timeInterval.rc)
|
|
{
|
|
if( ++i >= GetNoComponents()) break;
|
|
else Get( i, pCurrentUnit );
|
|
if( ++j >= per->GetNoComponents()) break;
|
|
else per->Get( j, interval );
|
|
}
|
|
else
|
|
{
|
|
if(interval.rc)
|
|
{
|
|
if( ++i >= GetNoComponents()) break;
|
|
else Get( i, pCurrentUnit );
|
|
}
|
|
else
|
|
{ // !interval->rc
|
|
if( ++j >= per->GetNoComponents() ) break;
|
|
else per->Get( j, interval );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (interval.end > pCurrentUnit.timeInterval.end)
|
|
{
|
|
if( ++i >= GetNoComponents() ) break;
|
|
else Get( i, pCurrentUnit );
|
|
}
|
|
else
|
|
{
|
|
if( ++j >= per->GetNoComponents()) break;
|
|
else per->Get( j, interval );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
res->EndBulkLoad(true);
|
|
res->SetDefined(true);
|
|
res->SetTrajectoryDefined(false);
|
|
res->m_trajectory.TrimToSize();
|
|
res->SetBoundingBoxDefined(false);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Restricts the ~mgpoint~ to the given ~instant~
|
|
|
|
*/
|
|
|
|
void MGPoint::Atinstant(const Instant *per, Intime<GPoint> *res) const{
|
|
if (IsDefined() && !IsEmpty() && per->IsDefined())
|
|
{
|
|
UGPoint pCurrUnit;
|
|
int pos = Position(*per);
|
|
if (pos == -1) res->SetDefined(false);
|
|
else
|
|
{
|
|
res->SetDefined(true);
|
|
Get(pos,pCurrUnit);
|
|
GPoint gp = GPoint(false);
|
|
pCurrUnit.TemporalFunction(*per, gp);
|
|
if (gp.IsDefined()) *res=Intime<GPoint>(*per,gp);
|
|
else res->SetDefined(false);
|
|
}
|
|
}
|
|
else res->SetDefined(false);
|
|
}
|
|
|
|
/*
|
|
Restricts the ~mgpoint~ to the times it was at the given places.
|
|
|
|
*/
|
|
|
|
void MGPoint::At(const GPoint *gp, MGPoint *res) const{
|
|
// DbArray<RouteInterval> tra = GetTrajectory();
|
|
// if (Includes(tra, gp)){
|
|
if (!IsDefined() || IsEmpty() || !gp->IsDefined()) res->SetDefined(false);
|
|
else {
|
|
Instant tPos;
|
|
UGPoint pCurrentUnit, pCheckUnit;
|
|
Get(0, pCurrentUnit);
|
|
if (gp->GetNetworkId() != pCurrentUnit.p0.GetNetworkId()) {
|
|
res->SetDefined(false);
|
|
} else {
|
|
res->StartBulkLoad();
|
|
int i= 0;
|
|
while (i < GetNoComponents()) {
|
|
Get(i, pCurrentUnit);
|
|
UGPoint CurrUnit = pCurrentUnit;
|
|
if (pCurrentUnit.p0.GetRouteId() == gp->GetRouteId() &&
|
|
(pCurrentUnit.p0.GetSide() == gp->GetSide() ||
|
|
pCurrentUnit.p0.GetSide() ==2 || gp->GetSide()== 2)){
|
|
if (AlmostEqual(gp->GetPosition(),pCurrentUnit.p0.GetPosition())){
|
|
if (pCurrentUnit.p0.GetPosition() ==
|
|
pCurrentUnit.p1.GetPosition()){
|
|
res->Add(UGPoint(pCurrentUnit.timeInterval,
|
|
gp->GetNetworkId(), gp->GetRouteId(),
|
|
pCurrentUnit.p0.GetSide(), gp->GetPosition(),
|
|
gp->GetPosition()));
|
|
} else {
|
|
if(pCurrentUnit.timeInterval.lc) {
|
|
res->Add(UGPoint(Interval<Instant>(
|
|
pCurrentUnit.timeInterval.start,
|
|
pCurrentUnit.timeInterval.start,
|
|
true, true),
|
|
gp->GetNetworkId(), gp->GetRouteId(),
|
|
pCurrentUnit.p0.GetSide(), gp->GetPosition(),
|
|
gp->GetPosition()));
|
|
}
|
|
}
|
|
} else {
|
|
if(AlmostEqual(gp->GetPosition(),pCurrentUnit.p1.GetPosition())) {
|
|
if (pCurrentUnit.timeInterval.rc) {
|
|
if (i < GetNoComponents()-1){
|
|
i++;
|
|
Get(i,pCheckUnit);
|
|
if (pCheckUnit.p0.GetRouteId() ==
|
|
pCurrentUnit.p1.GetRouteId() &&
|
|
pCheckUnit.p0.GetPosition() ==
|
|
pCurrentUnit.p1.GetPosition()&&
|
|
pCheckUnit.timeInterval.start ==
|
|
pCurrentUnit.timeInterval.end){
|
|
if (pCheckUnit.p0.GetPosition() !=
|
|
pCheckUnit.p1.GetPosition()){
|
|
res->Add(UGPoint(Interval<Instant>(
|
|
pCurrentUnit.timeInterval.end,
|
|
pCurrentUnit.timeInterval.end,
|
|
true, true),
|
|
gp->GetNetworkId(), gp->GetRouteId(),
|
|
pCurrentUnit.p0.GetSide(), gp->GetPosition(),
|
|
gp->GetPosition()));
|
|
} else {
|
|
res->Add(UGPoint(pCheckUnit.timeInterval,
|
|
gp->GetNetworkId(), gp->GetRouteId(),
|
|
pCheckUnit.p0.GetSide(), gp->GetPosition(),
|
|
gp->GetPosition()));
|
|
}
|
|
}
|
|
} else {
|
|
res->Add(UGPoint(Interval<Instant>(
|
|
pCurrentUnit.timeInterval.end,
|
|
pCurrentUnit.timeInterval.end,
|
|
true, true),
|
|
gp->GetNetworkId(), gp->GetRouteId(),
|
|
pCurrentUnit.p0.GetSide(), gp->GetPosition(),
|
|
gp->GetPosition()));
|
|
}
|
|
} else {
|
|
if (i < GetNoComponents()-1) {
|
|
i++;
|
|
Get(i,pCheckUnit);
|
|
if (pCheckUnit.p0.GetRouteId() ==
|
|
pCurrentUnit.p1.GetRouteId()
|
|
&& pCheckUnit.p0.GetPosition() ==
|
|
pCurrentUnit.p1.GetPosition()
|
|
&& pCheckUnit.timeInterval.start ==
|
|
pCurrentUnit.timeInterval.end){
|
|
if (pCheckUnit.p0.GetPosition() !=
|
|
pCheckUnit.p1.GetPosition()){
|
|
res->Add(UGPoint(Interval<Instant>(
|
|
pCurrentUnit.timeInterval.end,
|
|
pCurrentUnit.timeInterval.end,
|
|
true, true),
|
|
gp->GetNetworkId(), gp->GetRouteId(),
|
|
pCurrentUnit.p0.GetSide(), gp->GetPosition(),
|
|
gp->GetPosition()));
|
|
} else {
|
|
res->Add(UGPoint(pCheckUnit.timeInterval,
|
|
gp->GetNetworkId(), gp->GetRouteId(),
|
|
pCheckUnit.p0.GetSide(), gp->GetPosition(),
|
|
gp->GetPosition()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if((pCurrentUnit.p0.GetPosition() < gp->GetPosition() &&
|
|
gp->GetPosition() < pCurrentUnit.p1.GetPosition()) ||
|
|
(pCurrentUnit.p1.GetPosition() < gp->GetPosition() &&
|
|
gp->GetPosition() < pCurrentUnit.p0.GetPosition())) {
|
|
Instant tPos = CurrUnit.TimeAtPos(gp->GetPosition());
|
|
res->Add(UGPoint(Interval<Instant>(tPos, tPos, true, true),
|
|
gp->GetNetworkId(), gp->GetRouteId(),
|
|
pCurrentUnit.p0.GetSide(), gp->GetPosition(),
|
|
gp->GetPosition()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
res->EndBulkLoad(true);
|
|
res->SetDefined(true);
|
|
}
|
|
}
|
|
// }else{
|
|
// res->SetDefined(true);
|
|
// }
|
|
res->SetTrajectoryDefined(false);
|
|
res->m_trajectory.TrimToSize();
|
|
res->SetBoundingBoxDefined(false);
|
|
}
|
|
|
|
void MGPoint::At(const GLine *gl, MGPoint *res) const{
|
|
// DbArray<RouteInterval> tra = GetTrajectory();
|
|
// DbArray<RouteInterval>* gltra = gl->GetRouteIntervals();
|
|
// if (Intersects(tra, *gltra, true, gl->IsSorted())){
|
|
UGPoint pCurrentUnit;
|
|
Get(0, pCurrentUnit);
|
|
if (gl->GetNetworkId() != pCurrentUnit.p0.GetNetworkId()) {
|
|
res->SetDefined(false);
|
|
} else {
|
|
int iNetworkId = gl->GetNetworkId();
|
|
double mgStart, mgEnd, lStart, lEnd, interStart, interEnd;
|
|
RouteInterval pCurrRInter;
|
|
Instant tInterStart, tInterEnd;
|
|
bool bInterStart, bInterEnd, swapped;
|
|
int iRouteMgp;
|
|
res->StartBulkLoad();
|
|
for (int i = 0; i < GetNoComponents(); i++) {
|
|
Get(i, pCurrentUnit);
|
|
UGPoint CurrUnit = pCurrentUnit;
|
|
iRouteMgp = pCurrentUnit.p0.GetRouteId();
|
|
mgStart = pCurrentUnit.p0.GetPosition();
|
|
mgEnd = pCurrentUnit.p1.GetPosition();
|
|
swapped = false;
|
|
if (mgEnd < mgStart) {
|
|
mgStart = pCurrentUnit.p1.GetPosition();
|
|
mgEnd = pCurrentUnit.p0.GetPosition();
|
|
swapped = true;
|
|
}
|
|
if (gl->IsSorted()){
|
|
|
|
vector<RouteInterval> vRI;
|
|
const RouteInterval *currRInter;
|
|
vRI.clear();
|
|
getRouteIntervals(gl, iRouteMgp, mgStart, mgEnd, 0,
|
|
gl->NoOfComponents(), vRI);
|
|
if (vRI.size() > 0) {
|
|
size_t k = 0;
|
|
while (k < vRI.size()) {
|
|
currRInter = &vRI[k];
|
|
if (pCurrentUnit.p0.GetPosition() ==
|
|
pCurrentUnit.p1.GetPosition() &&
|
|
((currRInter->GetStartPos() <=
|
|
pCurrentUnit.p0.GetPosition() &&
|
|
currRInter->GetEndPos() >= pCurrentUnit.p0.GetPosition())||
|
|
(currRInter->GetStartPos() >=
|
|
pCurrentUnit.p0.GetPosition() &&
|
|
currRInter->GetEndPos() <=
|
|
pCurrentUnit.p0.GetPosition()))) {
|
|
res->Add(pCurrentUnit);
|
|
} else {
|
|
if(pCurrentUnit.p0.GetPosition() <
|
|
pCurrentUnit.p1.GetPosition())
|
|
{
|
|
if (pCurrentUnit.p0.GetPosition() >=
|
|
currRInter->GetStartPos() &&
|
|
pCurrentUnit.p1.GetPosition() <= currRInter->GetEndPos()){
|
|
res->Add(pCurrentUnit);
|
|
}else{
|
|
if (pCurrentUnit.p0.GetPosition() >=
|
|
currRInter->GetStartPos()){
|
|
interStart = pCurrentUnit.p0.GetPosition();
|
|
tInterStart = pCurrentUnit.timeInterval.start;
|
|
bInterStart = pCurrentUnit.timeInterval.lc;
|
|
} else {
|
|
interStart = currRInter->GetStartPos();
|
|
bInterStart = true;
|
|
tInterStart = CurrUnit.TimeAtPos(interStart);
|
|
}
|
|
if (pCurrentUnit.p1.GetPosition() <=
|
|
currRInter->GetEndPos()) {
|
|
interEnd = pCurrentUnit.p1.GetPosition();
|
|
tInterEnd = pCurrentUnit.timeInterval.end;
|
|
bInterEnd = pCurrentUnit.timeInterval.rc;
|
|
} else {
|
|
interEnd = currRInter->GetEndPos();
|
|
bInterEnd = true;
|
|
tInterEnd = CurrUnit.TimeAtPos(interEnd);
|
|
}
|
|
if (interStart != interEnd || (bInterStart && bInterEnd)) {
|
|
res->Add(UGPoint(Interval<Instant> (tInterStart,tInterEnd,
|
|
bInterStart, bInterEnd), iNetworkId,
|
|
iRouteMgp, pCurrentUnit.p0.GetSide(),
|
|
interStart, interEnd));
|
|
}
|
|
}
|
|
} else {
|
|
if(pCurrentUnit.p0.GetPosition() >
|
|
pCurrentUnit.p1.GetPosition())
|
|
{
|
|
if(pCurrentUnit.p1.GetPosition() >=
|
|
currRInter->GetStartPos() &&
|
|
pCurrentUnit.p0.GetPosition()<=currRInter->GetEndPos()){
|
|
res->Add(pCurrentUnit);
|
|
}else{
|
|
if (currRInter->GetEndPos() >=
|
|
pCurrentUnit.p0.GetPosition()){
|
|
interStart = pCurrentUnit.p0.GetPosition();
|
|
tInterStart = pCurrentUnit.timeInterval.start;
|
|
bInterStart = pCurrentUnit.timeInterval.lc;
|
|
} else {
|
|
interStart = currRInter->GetEndPos();
|
|
bInterStart = true;
|
|
tInterStart = CurrUnit.TimeAtPos(interStart);
|
|
}
|
|
if(currRInter->GetStartPos() <=
|
|
pCurrentUnit.p1.GetPosition()){
|
|
interEnd = pCurrentUnit.p1.GetPosition();
|
|
tInterEnd = pCurrentUnit.timeInterval.end;
|
|
bInterEnd = pCurrentUnit.timeInterval.rc;
|
|
} else {
|
|
interEnd = currRInter->GetStartPos();
|
|
bInterEnd = true;
|
|
tInterEnd = CurrUnit.TimeAtPos(interEnd);
|
|
}
|
|
if(interStart != interEnd || (bInterStart && bInterEnd)){
|
|
res->Add(UGPoint(Interval<Instant> (tInterStart,
|
|
tInterEnd, bInterStart, bInterEnd),
|
|
iNetworkId, iRouteMgp,
|
|
pCurrentUnit.p0.GetSide(),
|
|
interStart, interEnd));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
k++;
|
|
}
|
|
}
|
|
} else {
|
|
|
|
int j = 0;
|
|
while (j < gl->NoOfComponents()) {
|
|
|
|
gl->Get(j,pCurrRInter);
|
|
if (iRouteMgp == pCurrRInter.GetRouteId()){
|
|
|
|
lStart = pCurrRInter.GetStartPos();
|
|
lEnd = pCurrRInter.GetEndPos();
|
|
if (lStart > lEnd) {
|
|
lStart = pCurrRInter.GetEndPos();
|
|
lEnd = pCurrRInter.GetStartPos();
|
|
}
|
|
if (!(mgEnd < lStart || mgStart > lEnd)){
|
|
//intersection exists compute intersecting part and timevalues
|
|
//for resulting unit
|
|
|
|
if (!swapped) {
|
|
if (lStart <= mgStart) {
|
|
|
|
interStart = pCurrentUnit.p0.GetPosition();
|
|
tInterStart = pCurrentUnit.timeInterval.start;
|
|
bInterStart = pCurrentUnit.timeInterval.lc;
|
|
} else {
|
|
|
|
interStart = lStart;
|
|
bInterStart = true;
|
|
tInterStart = CurrUnit.TimeAtPos(interStart);
|
|
}
|
|
if (lEnd >= mgEnd) {
|
|
|
|
interEnd = pCurrentUnit.p1.GetPosition();
|
|
tInterEnd = pCurrentUnit.timeInterval.end;
|
|
bInterEnd = pCurrentUnit.timeInterval.rc;
|
|
} else {
|
|
|
|
interEnd = lEnd;
|
|
bInterEnd = true;
|
|
tInterEnd = CurrUnit.TimeAtPos(interEnd);
|
|
}
|
|
if (!(interStart == interEnd &&
|
|
(!bInterStart || !bInterEnd))) {
|
|
if (tInterStart == pCurrentUnit.timeInterval.start &&
|
|
tInterEnd == pCurrentUnit.timeInterval.end &&
|
|
interStart == pCurrentUnit.p0.GetPosition()&&
|
|
interEnd == pCurrentUnit.p1.GetPosition()){
|
|
res->Add(pCurrentUnit);
|
|
}else{
|
|
res->Add(UGPoint(Interval<Instant> (tInterStart,
|
|
tInterEnd,
|
|
bInterStart, bInterEnd), iNetworkId,
|
|
iRouteMgp, pCurrentUnit.p0.GetSide(),
|
|
interStart, interEnd));
|
|
}
|
|
} else {
|
|
if (pCurrentUnit.p0.GetPosition() ==
|
|
pCurrentUnit.p1.GetPosition() && interStart == interEnd){
|
|
res->Add(pCurrentUnit);
|
|
}
|
|
}
|
|
} else {
|
|
mgStart = pCurrentUnit.p0.GetPosition();
|
|
mgEnd = pCurrentUnit.p1.GetPosition();
|
|
if (lEnd >= mgStart) {
|
|
interStart = pCurrentUnit.p0.GetPosition();
|
|
tInterStart = pCurrentUnit.timeInterval.start;
|
|
bInterStart = pCurrentUnit.timeInterval.lc;
|
|
} else {
|
|
interStart = lEnd;
|
|
bInterStart = true;
|
|
tInterStart = CurrUnit.TimeAtPos(interStart);
|
|
}
|
|
if (lStart <= mgEnd) {
|
|
interEnd = pCurrentUnit.p1.GetPosition();
|
|
tInterEnd = pCurrentUnit.timeInterval.end;
|
|
bInterEnd = pCurrentUnit.timeInterval.rc;
|
|
} else {
|
|
interEnd = lStart;
|
|
bInterEnd = true;
|
|
tInterEnd = CurrUnit.TimeAtPos(interEnd);
|
|
}
|
|
if (!(interStart == interEnd &&
|
|
(!bInterStart || !bInterEnd))) {
|
|
if (tInterStart== pCurrentUnit.timeInterval.start &&
|
|
tInterEnd == pCurrentUnit.timeInterval.end &&
|
|
interStart == pCurrentUnit.p0.GetPosition() &&
|
|
interEnd == pCurrentUnit.p1.GetPosition()){
|
|
res->Add(pCurrentUnit);
|
|
}else{
|
|
res->Add(UGPoint(Interval<Instant> (tInterStart,
|
|
tInterEnd,
|
|
bInterStart, bInterEnd), iNetworkId,
|
|
iRouteMgp, pCurrentUnit.p0.GetSide(),
|
|
interStart, interEnd));
|
|
}
|
|
} else {
|
|
if (pCurrentUnit.p0.GetPosition() ==
|
|
pCurrentUnit.p1.GetPosition() &&
|
|
interStart == interEnd)
|
|
{
|
|
res->Add(pCurrentUnit);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
res->EndBulkLoad(true);
|
|
res->SetDefined(true);
|
|
}
|
|
// }else{
|
|
// res->SetDefined(true);
|
|
// }
|
|
res->SetTrajectoryDefined(false);
|
|
res->m_trajectory.TrimToSize();
|
|
res->SetBoundingBoxDefined(false);
|
|
}
|
|
|
|
/*
|
|
Compresses the ~mgpoint~ by equalizing speed differences witch are smaller than
|
|
~d~
|
|
|
|
*/
|
|
|
|
void MGPoint::Simplify(const double d, MGPoint* res) const{
|
|
res->StartBulkLoad();
|
|
|
|
int iNetworkId;
|
|
int iStartRouteId = 0;
|
|
Side xStartSide = None;
|
|
double dStartSpeed = 0.0;
|
|
|
|
Instant xStartStartTime;
|
|
double dStartStartPosition = 0.0;
|
|
double dLastEndPosition = 0.0;
|
|
Instant xLastEndTime;
|
|
for (int i = 0; i < GetNoComponents(); i++)
|
|
{
|
|
//////////////////////////////
|
|
//
|
|
// Get values for current unit
|
|
//
|
|
//////////////////////////////
|
|
UGPoint pCurrentUnit;
|
|
Get(i, pCurrentUnit);
|
|
|
|
// Duration
|
|
Instant xCurrentStartTime = pCurrentUnit.timeInterval.start;
|
|
int32_t lCurrentStartTime = xCurrentStartTime.GetAllMilliSeconds();
|
|
Instant xCurrentEndTime = pCurrentUnit.timeInterval.end;
|
|
int32_t lCurrentEndTime = xCurrentEndTime.GetAllMilliSeconds();
|
|
int32_t lCurrentDuration = lCurrentEndTime - lCurrentStartTime;
|
|
|
|
// Distance
|
|
GPoint xCurrentStart = pCurrentUnit.p0;
|
|
GPoint xCurrentEnd = pCurrentUnit.p1;
|
|
iNetworkId = xCurrentStart.GetNetworkId();
|
|
int iCurrentRouteId = xCurrentStart.GetRouteId();
|
|
Side xCurrentSide = xCurrentStart.GetSide();
|
|
double dCurrentStartPosition = xCurrentStart.GetPosition();
|
|
double dCurrentEndPosition = xCurrentEnd.GetPosition();
|
|
double dCurrentDistance = dCurrentEndPosition - dCurrentStartPosition;
|
|
|
|
// Speed
|
|
double dCurrentSpeed = dCurrentDistance / lCurrentDuration;
|
|
//////////////////////////////
|
|
//
|
|
// Set start values if this
|
|
// is the first unit-start
|
|
//
|
|
//////////////////////////////
|
|
if(iStartRouteId == 0)
|
|
{
|
|
iStartRouteId = iCurrentRouteId;
|
|
xStartSide = xCurrentSide;
|
|
dStartSpeed = dCurrentSpeed;
|
|
xStartStartTime = xCurrentStartTime;
|
|
dStartStartPosition = dCurrentStartPosition;
|
|
dLastEndPosition = dCurrentEndPosition;
|
|
}
|
|
|
|
//////////////////////////////
|
|
//
|
|
// Check if this units differs
|
|
// from the ones before.
|
|
// If so create unit for all
|
|
// units before this.
|
|
//
|
|
//////////////////////////////
|
|
double dSpeedDifference = dCurrentSpeed > dStartSpeed ?
|
|
dCurrentSpeed - dStartSpeed :
|
|
dStartSpeed - dCurrentSpeed;
|
|
|
|
if( iCurrentRouteId != iStartRouteId ||
|
|
xCurrentSide != xStartSide ||
|
|
dSpeedDifference > d)
|
|
{
|
|
// Create new unit
|
|
if (xStartStartTime == pCurrentUnit.timeInterval.start &&
|
|
xLastEndTime == pCurrentUnit.timeInterval.end &&
|
|
iStartRouteId == pCurrentUnit.p0.GetRouteId()&&
|
|
xStartSide == pCurrentUnit.p0.GetSide() &&
|
|
dStartStartPosition == pCurrentUnit.p0.GetPosition() &&
|
|
dLastEndPosition == pCurrentUnit.p1.GetPosition()) {
|
|
res->Add(pCurrentUnit/*, false*/);
|
|
} else {
|
|
res->Add(UGPoint(Interval<Instant>(xStartStartTime,
|
|
xLastEndTime,
|
|
true,
|
|
false),
|
|
iNetworkId,
|
|
iStartRouteId,
|
|
xStartSide,
|
|
dStartStartPosition,
|
|
dLastEndPosition)/*, false*/);
|
|
}
|
|
// Set new Start-Values
|
|
iStartRouteId = iCurrentRouteId;
|
|
xStartSide = xCurrentSide;
|
|
dStartSpeed = dCurrentSpeed;
|
|
xStartStartTime = xCurrentStartTime;
|
|
dStartStartPosition = dCurrentStartPosition;
|
|
dLastEndPosition = dCurrentEndPosition;
|
|
}
|
|
|
|
if( i == GetNoComponents() -1)
|
|
{
|
|
// Last loop - create last unit
|
|
if (xStartStartTime == pCurrentUnit.timeInterval.start &&
|
|
xLastEndTime == pCurrentUnit.timeInterval.end &&
|
|
iStartRouteId == pCurrentUnit.p0.GetRouteId()&&
|
|
xStartSide == pCurrentUnit.p0.GetSide() &&
|
|
dStartStartPosition == pCurrentUnit.p0.GetPosition() &&
|
|
dLastEndPosition == pCurrentUnit.p1.GetPosition()){
|
|
res->Add(pCurrentUnit );
|
|
} else {
|
|
res->Add(UGPoint(Interval<Instant>(xStartStartTime,
|
|
xCurrentEndTime,
|
|
true,
|
|
false),
|
|
iNetworkId,
|
|
iStartRouteId,
|
|
xStartSide,
|
|
dStartStartPosition,
|
|
dCurrentEndPosition) );
|
|
}
|
|
}
|
|
|
|
// Set Last-Values for next loop
|
|
dLastEndPosition = dCurrentEndPosition;
|
|
xLastEndTime = xCurrentEndTime;
|
|
}
|
|
// Units were added to the moving gpoint. They are sorted and
|
|
// the bulk-load is ended:
|
|
res->EndBulkLoad(true);
|
|
if (m_traj_Defined) {
|
|
res->SetTrajectory(m_trajectory);
|
|
}
|
|
if (m_bbox.IsDefined()) {
|
|
res->SetBoundingBox(BoundingBox());
|
|
res->SetBoundingBoxDefined(true);
|
|
}
|
|
res->m_trajectory.TrimToSize();
|
|
}
|
|
|
|
/*
|
|
Checks if the ~mgpoint~ passes the given ~gpoint~ respectively ~gline~.
|
|
|
|
*/
|
|
|
|
bool MGPoint::Passes(const GPoint *gp){
|
|
if (!m_traj_Defined){
|
|
GLine *help = new GLine(0);
|
|
Trajectory(help);
|
|
help->DeleteIfAllowed();
|
|
}
|
|
if (Includes(m_trajectory, gp)) return true;
|
|
else return false;
|
|
}
|
|
|
|
|
|
|
|
bool MGPoint::Passes(GLine *gl){
|
|
if (!m_traj_Defined){
|
|
GLine *help = new GLine(0);
|
|
Trajectory(help);
|
|
help->DeleteIfAllowed();
|
|
}
|
|
DbArray<RouteInterval>* gltra = gl->GetRouteIntervals();
|
|
bool result = RIsIntersects(m_trajectory, *gltra, true, gl->IsSorted());
|
|
gltra->Destroy();
|
|
delete gltra;
|
|
return result;
|
|
}
|
|
|
|
|
|
MGPoint* MGPoint::Clone() const {
|
|
if (!IsDefined())
|
|
{
|
|
MGPoint* result = new MGPoint(0);
|
|
result->SetDefined(false);
|
|
return result;
|
|
}
|
|
|
|
MGPoint* result = new MGPoint( GetNoComponents() );
|
|
if(GetNoComponents()>0)
|
|
{
|
|
result->units.resize(GetNoComponents());
|
|
}
|
|
result->StartBulkLoad();
|
|
UGPoint unit;
|
|
for( int i = 0; i < GetNoComponents(); i++ )
|
|
{
|
|
Get( i, unit );
|
|
result->Add( unit);
|
|
}
|
|
result->EndBulkLoad( false);
|
|
if (m_traj_Defined)
|
|
result->SetTrajectory(m_trajectory);
|
|
result->SetTrajectoryDefined(m_traj_Defined);
|
|
result->m_trajectory.TrimToSize();
|
|
if (m_bbox.IsDefined())
|
|
result->SetBoundingBox(m_bbox);
|
|
result->SetBoundingBoxDefined(m_bbox.IsDefined());
|
|
return result;
|
|
}
|
|
|
|
void MGPoint::Restrict( const vector< pair<int, int> >& intervals )
|
|
{
|
|
units.Restrict( intervals, units ); // call super
|
|
SetTrajectoryDefined(false);
|
|
m_trajectory.TrimToSize();
|
|
SetBoundingBoxDefined(false);
|
|
}
|
|
|
|
void MGPoint::Add(const UGPoint& u/*, bool setbbox =true*/){
|
|
if (u.IsValid()) {
|
|
units.Append(u);
|
|
if (units.Size() == 1){;
|
|
m_length = u.Length();
|
|
} else {
|
|
m_length += u.Length();
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle<3> MGPoint::BoundingBox(const Geoid* geoid /*=0*/) const{
|
|
if(geoid){
|
|
cerr << __PRETTY_FUNCTION__ << ": Spherical geometry not implemented."
|
|
<< endl;
|
|
assert( !geoid ); // TODO: implement spherical geometry case
|
|
}
|
|
if (m_bbox.IsDefined()) return m_bbox;
|
|
else {
|
|
if(IsDefined() && !IsEmpty()){
|
|
if (!m_traj_Defined) {
|
|
if (GetNoComponents() > 0) {
|
|
UGPoint pCurrentUnit;
|
|
Get(0, pCurrentUnit);
|
|
int aktRouteId = pCurrentUnit.p0.GetRouteId();
|
|
double aktStartPos = pCurrentUnit.p0.GetPosition();
|
|
double aktEndPos = pCurrentUnit.p1.GetPosition();
|
|
chkStartEnd(aktStartPos, aktEndPos);
|
|
RITree *tree = new RITree(aktRouteId, aktStartPos, aktEndPos,0,0);
|
|
int curRoute;
|
|
double curStartPos, curEndPos;
|
|
for (int i = 1; i < GetNoComponents(); i++)
|
|
{
|
|
// Get start and end of current unit
|
|
Get(i, pCurrentUnit);
|
|
curRoute = pCurrentUnit.p0.GetRouteId();
|
|
curStartPos = pCurrentUnit.p0.GetPosition();
|
|
curEndPos = pCurrentUnit.p1.GetPosition();
|
|
chkStartEnd(curStartPos, curEndPos);
|
|
if (curRoute != aktRouteId) {
|
|
tree->Insert(aktRouteId, aktStartPos, aktEndPos);
|
|
aktRouteId = curRoute;
|
|
aktStartPos = curStartPos;
|
|
aktEndPos = curEndPos;
|
|
} else { // curRoute == aktRouteId concat pieces if possible
|
|
if (AlmostEqual(aktStartPos,curEndPos)) {
|
|
aktStartPos = curStartPos;
|
|
} else {
|
|
if (AlmostEqual(aktEndPos,curStartPos)) {
|
|
aktEndPos = curEndPos;
|
|
} else { //concat impossible start new routeInterval for gline.
|
|
tree->Insert(aktRouteId, aktStartPos, aktEndPos);
|
|
aktRouteId = curRoute;
|
|
aktStartPos = curStartPos;
|
|
aktEndPos = curEndPos;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
tree->Insert(aktRouteId, aktStartPos, aktEndPos);
|
|
GLine *help = new GLine(0);
|
|
tree->TreeToGLine(help);
|
|
tree->RemoveTree();
|
|
Rectangle<3> bbox, ribox3;
|
|
Rectangle<2> ribox = Rectangle<2u>(false);
|
|
UGPoint unit;
|
|
Get(0,unit);
|
|
/*Network *pNetwork =
|
|
NetworkManager::GetNetwork(unit->p0.GetNetworkId());*/
|
|
Network* pNetwork = GetNetwork();
|
|
double x5 = unit.timeInterval.start.ToDouble();
|
|
Get(GetNoComponents()-1,unit);
|
|
double x6 = unit.timeInterval.end.ToDouble();
|
|
RouteInterval ri;
|
|
bool firstri = true;
|
|
if (help->NoOfComponents()>0) {
|
|
for (int i = 0; i < help->NoOfComponents(); i++) {
|
|
help->Get(i,ri);
|
|
ribox = ri.BoundingBox(pNetwork);
|
|
if (firstri) {
|
|
firstri = false;
|
|
double minMax[] = {ribox.MinD(0),
|
|
ribox.MaxD(0),
|
|
ribox.MinD(1),
|
|
ribox.MaxD(1),
|
|
x5, x6};
|
|
bbox = Rectangle<3> (true,minMax);
|
|
} else {
|
|
double minMax[] = { ribox.MinD(0),
|
|
ribox.MaxD(0),
|
|
ribox.MinD(1),
|
|
ribox.MaxD(1),
|
|
x5, x6};
|
|
ribox3 = Rectangle<3> (true,minMax);
|
|
bbox = bbox.Union(ribox3);
|
|
}
|
|
}
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
help->DeleteIfAllowed();
|
|
return bbox;
|
|
} else {
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
help->DeleteIfAllowed();
|
|
return Rectangle<3> (false);
|
|
}
|
|
} else {
|
|
return Rectangle<3>(false);
|
|
}
|
|
} else {
|
|
if (m_trajectory.Size() <= 0)
|
|
return Rectangle<3>(false);
|
|
Rectangle<3> bbox, ribox3;
|
|
Rectangle<2> ribox = Rectangle<2u>(false);
|
|
UGPoint unit;
|
|
Get(0,unit);
|
|
/*Network *pNetwork =
|
|
NetworkManager::GetNetwork(unit->p0.GetNetworkId());*/
|
|
Network* pNetwork = GetNetwork();
|
|
double x5 = unit.timeInterval.start.ToDouble();
|
|
Get(GetNoComponents()-1,unit);
|
|
double x6 = unit.timeInterval.end.ToDouble();
|
|
RouteInterval ri;
|
|
bool firstri = true;
|
|
for (int i = 0; i < m_trajectory.Size(); i++) {
|
|
m_trajectory.Get(i,ri);
|
|
ribox = ri.BoundingBox(pNetwork);
|
|
if (firstri) {
|
|
firstri = false;
|
|
double minMax[] = { ribox.MinD(0),
|
|
ribox.MaxD(0),
|
|
ribox.MinD(1),
|
|
ribox.MaxD(1),
|
|
x5, x6};
|
|
bbox = Rectangle<3> (true,minMax);
|
|
} else {
|
|
double minMax[] = {ribox.MinD(0),
|
|
ribox.MaxD(0),
|
|
ribox.MinD(1),
|
|
ribox.MaxD(1),
|
|
x5, x6};
|
|
ribox3 = Rectangle<3> (true,minMax);
|
|
bbox = bbox.Union(ribox3);
|
|
}
|
|
}
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
return bbox;
|
|
}
|
|
} else return Rectangle<3>(false);
|
|
}
|
|
}
|
|
|
|
void MGPoint::GetMGPSecUnits(vector<MGPSecUnit> &res,
|
|
double maxSectLength,
|
|
Network *pNet) const
|
|
{
|
|
res.clear();
|
|
if (IsDefined() && 0 < GetNoComponents())
|
|
{
|
|
UGPoint unit;
|
|
MGPSecUnit actUnit, nextUnit;
|
|
vector<MGPSecUnit> intermediate;
|
|
intermediate.clear();
|
|
Get(0,unit);
|
|
unit.GetMGPSecUnits(intermediate, maxSectLength, pNet);
|
|
actUnit = intermediate[0];
|
|
if (intermediate.size()>1)
|
|
{
|
|
for (size_t j = 1; j < intermediate.size() ; j++)
|
|
{
|
|
res.push_back(actUnit);
|
|
actUnit = intermediate[j];
|
|
}
|
|
}
|
|
for (int i = 1; i < GetNoComponents(); i++)
|
|
{
|
|
Get(i,unit);
|
|
intermediate.clear();
|
|
unit.GetMGPSecUnits(intermediate, maxSectLength, pNet);
|
|
nextUnit = intermediate[0];
|
|
if (actUnit.GetSecId() == nextUnit.GetSecId() &&
|
|
actUnit.GetPart() == nextUnit.GetPart() &&
|
|
(actUnit.GetDirect() == nextUnit.GetDirect() ||
|
|
actUnit.GetDirect() == None || nextUnit.GetDirect() == None)&&
|
|
actUnit.GetTimeInterval().end == nextUnit.GetTimeInterval().start)
|
|
{
|
|
if(actUnit.GetDirect() == None) actUnit.SetDirect(nextUnit.GetDirect());
|
|
double speed = (actUnit.GetDurationInSeconds() * actUnit.GetSpeed() +
|
|
nextUnit.GetDurationInSeconds() * nextUnit.GetSpeed()) /
|
|
(actUnit.GetDurationInSeconds() +
|
|
nextUnit.GetDurationInSeconds());
|
|
actUnit.SetSpeed(speed);
|
|
actUnit.SetTimeInterval(Interval<Instant> (
|
|
actUnit.GetTimeInterval().start,
|
|
nextUnit.GetTimeInterval().end,
|
|
actUnit.GetTimeInterval().lc,
|
|
nextUnit.GetTimeInterval().rc));
|
|
}
|
|
else
|
|
{
|
|
res.push_back(actUnit);
|
|
actUnit = nextUnit;
|
|
}
|
|
if (intermediate.size() > 1)
|
|
{
|
|
for (size_t j = 1; j < intermediate.size() ; j++)
|
|
{
|
|
res.push_back(actUnit);
|
|
actUnit = intermediate[j];
|
|
}
|
|
}
|
|
}
|
|
res.push_back(actUnit);
|
|
intermediate.clear();
|
|
}
|
|
}
|
|
|
|
ostream& MGPoint::Print( ostream &os ) const
|
|
{
|
|
if( !IsDefined() )
|
|
{
|
|
return os << "(MGPoint: undefined)";
|
|
}
|
|
os << "(MGPoint: defined ";
|
|
os << ", contains " << GetNoComponents() << " units: ";
|
|
for(int i=0; i<GetNoComponents(); i++)
|
|
{
|
|
UGPoint unit;
|
|
Get( i , unit );
|
|
os << "\n\t";
|
|
unit.Print(os);
|
|
}
|
|
os << "\n" << endl;
|
|
return os;
|
|
}
|
|
|
|
Word InMGPoint(const ListExpr typeInfo, const ListExpr instance,
|
|
const int errorPos, ListExpr& errorInfo, bool& correct)
|
|
{
|
|
int numUnits = nl->ListLength(instance);
|
|
MGPoint* m = new MGPoint( numUnits );
|
|
correct = true;
|
|
int unitcounter = 0;
|
|
string errmsg;
|
|
m->StartBulkLoad();
|
|
ListExpr rest = instance;
|
|
if (nl->AtomType( rest ) != NoAtom)
|
|
{ if(nl->IsEqual(rest,"undef")){
|
|
m->EndBulkLoad(true);
|
|
m->SetDefined(false);
|
|
return SetWord( Address( m ) );
|
|
} else {
|
|
correct = false;
|
|
m->DeleteIfAllowed();
|
|
return SetWord( Address( 0 ) );
|
|
}
|
|
}
|
|
else {
|
|
double test1, test2;
|
|
RITree *tree = 0;
|
|
bool firstunit = true;
|
|
while( !nl->IsEmpty( rest ) )
|
|
{
|
|
ListExpr first = nl->First( rest );
|
|
rest = nl->Rest( rest );
|
|
|
|
UGPoint *unit = (UGPoint*) UGPoint::In( nl->TheEmptyList(), first,
|
|
errorPos, errorInfo, correct ).addr;
|
|
|
|
if( correct && (!unit->IsDefined() || !unit->IsValid() ) )
|
|
{
|
|
errmsg = "InMapping(): Unit " + int2string(unitcounter) + " is undef.";
|
|
errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg));
|
|
correct = false;
|
|
unit->DeleteIfAllowed();
|
|
m->DeleteIfAllowed();
|
|
//if (!bfirst) NetworkManager::CloseNetwork(pNetwork);
|
|
return SetWord( Address(0) );
|
|
}
|
|
if ( !correct )
|
|
{
|
|
errmsg = "InMapping(): Representation of Unit "
|
|
+ int2string(unitcounter) + " is wrong.";
|
|
errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg));
|
|
m->Destroy();
|
|
m->DeleteIfAllowed();
|
|
//if (!bfirst) NetworkManager::CloseNetwork(pNetwork);
|
|
return SetWord( Address(0) );
|
|
}
|
|
m->Add( *unit);
|
|
unitcounter++;
|
|
test1 = unit->p0.GetPosition();
|
|
test2 = unit->p1.GetPosition();
|
|
chkStartEnd(test1, test2);
|
|
if (firstunit) {
|
|
firstunit = false;
|
|
tree = new RITree(unit->p0.GetRouteId(), test1, test2);
|
|
} else
|
|
tree->Insert(unit->p0.GetRouteId(), test1, test2);
|
|
unit->DeleteIfAllowed();
|
|
}
|
|
m->EndBulkLoad(true); // if this succeeds, all is OK
|
|
tree->TreeToDbArray(&(m->m_trajectory));
|
|
m->SetTrajectoryDefined(true);
|
|
m->m_trajectory.TrimToSize();
|
|
tree->RemoveTree();
|
|
m->SetBoundingBoxDefined(false);
|
|
}
|
|
return SetWord( m );
|
|
}
|
|
|
|
|
|
bool OpenMGPoint(SmiRecord& valueRecord,
|
|
size_t& offset,
|
|
const ListExpr typeInfo,
|
|
Word& value)
|
|
{
|
|
MGPoint *m =
|
|
static_cast<MGPoint*>(Attribute::Open( valueRecord, offset, typeInfo ));
|
|
value = SetWord( m );
|
|
m->m_trajectory.TrimToSize();
|
|
return true;
|
|
}
|
|
|
|
DbArray<RouteInterval>& MGPoint::GetTrajectory(){
|
|
if (!m_traj_Defined) {
|
|
GLine *help = new GLine(0);
|
|
Trajectory(help);
|
|
help->DeleteIfAllowed();
|
|
}
|
|
return m_trajectory;
|
|
}
|
|
|
|
void MGPoint::SetTrajectoryDefined(const bool defined){
|
|
m_traj_Defined=defined;
|
|
}
|
|
|
|
void MGPoint::SetBoundingBoxDefined(const bool defined){
|
|
m_bbox.SetDefined(defined);
|
|
if (!defined) m_bbox = Rectangle<3> (false);
|
|
}
|
|
|
|
/*
|
|
Merges two MGPoint into one if the time intervals don't overlap.
|
|
Otherwise the union is undefined.
|
|
|
|
*/
|
|
|
|
void MGPoint::Union(const MGPoint *mp, MGPoint *res) const
|
|
{
|
|
if (IsDefined() && mp->IsDefined() &&
|
|
GetNoComponents() > 0 && mp->GetNoComponents() > 0)
|
|
{
|
|
int i = 0;
|
|
int j = 0;
|
|
UGPoint u1, u2;
|
|
res->StartBulkLoad();
|
|
while (i < GetNoComponents() && j < mp->GetNoComponents())
|
|
{
|
|
Get(i, u1);
|
|
mp->Get(j,u2);
|
|
if (u1.timeInterval.end.ToDouble() <=
|
|
u2.timeInterval.start.ToDouble())
|
|
{
|
|
res->Add(UGPoint(Interval<Instant> (u1.timeInterval.start,
|
|
u1.timeInterval.end,
|
|
true, false),
|
|
u1.p0.GetNetworkId(),
|
|
u1.p0.GetRouteId(),
|
|
u1.p0.GetSide(),
|
|
u1.p0.GetPosition(),
|
|
u1.p1.GetPosition()));
|
|
i++;
|
|
}
|
|
else
|
|
{
|
|
if (u2.timeInterval.end.ToDouble() <=
|
|
u1.timeInterval.start.ToDouble())
|
|
{
|
|
res->Add(UGPoint(Interval<Instant> (u2.timeInterval.start,
|
|
u2.timeInterval.end,
|
|
true, false),
|
|
u2.p0.GetNetworkId(),
|
|
u2.p0.GetRouteId(),
|
|
u2.p0.GetSide(),
|
|
u2.p0.GetPosition(),
|
|
u2.p1.GetPosition()));
|
|
j++;
|
|
}
|
|
else
|
|
{
|
|
if (u1 == u2)
|
|
{
|
|
res->Add(UGPoint(Interval<Instant> (u1.timeInterval.start,
|
|
u1.timeInterval.end,
|
|
true, false),
|
|
u1.p0.GetNetworkId(),
|
|
u1.p0.GetRouteId(),
|
|
u1.p0.GetSide(),
|
|
u1.p0.GetPosition(),
|
|
u1.p1.GetPosition()));
|
|
i++;
|
|
j++;
|
|
}
|
|
else
|
|
{
|
|
if (fabs(u1.timeInterval.end.ToDouble() -
|
|
u2.timeInterval.start.ToDouble())<= 0.00000002)
|
|
{
|
|
res->Add(UGPoint(Interval<Instant> (u1.timeInterval.start,
|
|
u2.timeInterval.start,true, false),
|
|
u1.p0.GetNetworkId(),
|
|
u1.p0.GetRouteId(),
|
|
u1.p0.GetSide(),
|
|
u1.p0.GetPosition(),
|
|
u1.p1.GetPosition()));
|
|
res->Add(UGPoint(Interval<Instant> (u2.timeInterval.start,
|
|
u2.timeInterval.end,true, false),
|
|
u2.p0.GetNetworkId(),
|
|
u2.p0.GetRouteId(),
|
|
u2.p0.GetSide(),
|
|
u2.p0.GetPosition(),
|
|
u2.p1.GetPosition()));
|
|
i++;
|
|
j++;
|
|
}
|
|
else
|
|
{
|
|
if (fabs(u2.timeInterval.end.ToDouble() -
|
|
u1.timeInterval.start.ToDouble()) <= 0.00000002)
|
|
{
|
|
res->Add(UGPoint(Interval<Instant> (u2.timeInterval.start,
|
|
u1.timeInterval.start,true, false),
|
|
u2.p0.GetNetworkId(),
|
|
u2.p0.GetRouteId(),
|
|
u2.p0.GetSide(),
|
|
u2.p0.GetPosition(),
|
|
u2.p1.GetPosition()));
|
|
res->Add(UGPoint(Interval<Instant> (u1.timeInterval.start,
|
|
u1.timeInterval.end,true, false),
|
|
u1.p0.GetNetworkId(),
|
|
u1.p0.GetRouteId(),
|
|
u1.p0.GetSide(),
|
|
u1.p0.GetPosition(),
|
|
u1.p1.GetPosition()));
|
|
i++;
|
|
j++;
|
|
}
|
|
else
|
|
{
|
|
res->SetDefined(false);
|
|
i = GetNoComponents();
|
|
j = mp->GetNoComponents();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (i < GetNoComponents())
|
|
{
|
|
Get(i,u1);
|
|
res->Add(UGPoint(Interval<Instant> (u1.timeInterval.start,
|
|
u1.timeInterval.end,
|
|
true, false),
|
|
u1.p0.GetNetworkId(),
|
|
u1.p0.GetRouteId(),
|
|
u1.p0.GetSide(),
|
|
u1.p0.GetPosition(),
|
|
u1.p1.GetPosition()));
|
|
i++;
|
|
while (i < GetNoComponents())
|
|
{
|
|
Get(i,u1);
|
|
res->Add(UGPoint(Interval<Instant> (u1.timeInterval.start,
|
|
u1.timeInterval.end,
|
|
true, false),
|
|
u1.p0.GetNetworkId(),
|
|
u1.p0.GetRouteId(),
|
|
u1.p0.GetSide(),
|
|
u1.p0.GetPosition(),
|
|
u1.p1.GetPosition()));
|
|
i++;
|
|
}
|
|
}
|
|
if (j < mp->GetNoComponents())
|
|
{
|
|
mp->Get(j,u2);
|
|
res->Add(UGPoint(Interval<Instant> (u2.timeInterval.start,
|
|
u2.timeInterval.end,
|
|
true, false),
|
|
u2.p0.GetNetworkId(),
|
|
u2.p0.GetRouteId(),
|
|
u2.p0.GetSide(),
|
|
u2.p0.GetPosition(),
|
|
u2.p1.GetPosition()));
|
|
j++;
|
|
while (j < mp->GetNoComponents())
|
|
{
|
|
mp->Get(j,u2);
|
|
res->Add(UGPoint(Interval<Instant> (u2.timeInterval.start,
|
|
u2.timeInterval.end,
|
|
true, false),
|
|
u2.p0.GetNetworkId(),
|
|
u2.p0.GetRouteId(),
|
|
u2.p0.GetSide(),
|
|
u2.p0.GetPosition(),
|
|
u2.p1.GetPosition()));
|
|
j++;
|
|
}
|
|
}
|
|
res->EndBulkLoad();
|
|
}
|
|
else
|
|
{
|
|
if (IsDefined() && !(mp->IsDefined()) && GetNoComponents() > 0)
|
|
{
|
|
int i = 0;
|
|
UGPoint u1;
|
|
res->StartBulkLoad();
|
|
while (i < GetNoComponents())
|
|
{
|
|
Get(i,u1);
|
|
res->Add(UGPoint(Interval<Instant> (u1.timeInterval.start,
|
|
u1.timeInterval.end,
|
|
true, false),
|
|
u1.p0.GetNetworkId(),
|
|
u1.p0.GetRouteId(),
|
|
u1.p0.GetSide(),
|
|
u1.p0.GetPosition(),
|
|
u1.p1.GetPosition()));
|
|
i++;
|
|
}
|
|
res->EndBulkLoad();
|
|
}
|
|
else
|
|
{
|
|
if (mp->IsDefined() && !(IsDefined()) && mp->GetNoComponents() > 0)
|
|
{
|
|
int j = 0;
|
|
UGPoint u2;
|
|
res->StartBulkLoad();
|
|
while (j < mp->GetNoComponents())
|
|
{
|
|
mp->Get(j,u2);
|
|
res->Add(UGPoint(Interval<Instant> (u2.timeInterval.start,
|
|
u2.timeInterval.end,
|
|
true, false),
|
|
u2.p0.GetNetworkId(),
|
|
u2.p0.GetRouteId(),
|
|
u2.p0.GetSide(),
|
|
u2.p0.GetPosition(),
|
|
u2.p1.GetPosition()));
|
|
j++;
|
|
}
|
|
res->EndBulkLoad();
|
|
}
|
|
else
|
|
{
|
|
res->SetDefined(false);
|
|
}
|
|
}
|
|
}
|
|
res->SetTrajectoryDefined(false);
|
|
res->m_trajectory.TrimToSize();
|
|
res->SetBoundingBoxDefined(false);
|
|
}
|
|
|
|
struct mgpInfo:ConstructorInfo{
|
|
mgpInfo(){
|
|
name = MGPoint::BasicType();
|
|
signature = "-> MAPPING";
|
|
typeExample = MGPoint::BasicType();
|
|
listRep = "(<list of ugpoint)>";
|
|
valueExample = "(<ugpoint1> <ugpoint2> ...)";
|
|
remarks = "Describes a single moving network position.";
|
|
}
|
|
};
|
|
|
|
struct mgpFunctions:ConstructorFunctions<MGPoint>{
|
|
mgpFunctions(){
|
|
in = InMapping<MGPoint, UGPoint, UGPoint::In>;
|
|
out = OutMapping<MGPoint, UGPoint, UGPoint::Out>;
|
|
create = CreateMapping<MGPoint>;
|
|
deletion = DeleteMapping<MGPoint>;
|
|
open = OpenAttribute<MGPoint>;
|
|
save = SaveAttribute<MGPoint>;
|
|
close = CloseMapping<MGPoint>;
|
|
clone = CloneMapping<MGPoint>;
|
|
sizeOf = SizeOfMapping<MGPoint>;
|
|
kindCheck = MGPoint::Check;
|
|
cast = MGPoint::Cast;
|
|
}
|
|
};
|
|
|
|
mgpInfo mgpi;
|
|
mgpFunctions mgpf;
|
|
TypeConstructor mgpointTC(mgpi,mgpf);
|
|
|
|
/*
|
|
3 Classe UGPoint
|
|
|
|
Temporal Function
|
|
|
|
*/
|
|
|
|
void UGPoint::TemporalFunction( const Instant& t,
|
|
GPoint& result,
|
|
bool ignoreLimits ) const
|
|
{
|
|
if( !IsDefined() ||
|
|
!t.IsDefined() ||
|
|
(!timeInterval.Contains( t ) && !ignoreLimits) ){
|
|
result.SetDefined(false);
|
|
} else {
|
|
if( t == timeInterval.start ){
|
|
result = p0;
|
|
result.SetDefined(true);
|
|
} else {
|
|
if( t == timeInterval.end ) {
|
|
result = p1;
|
|
result.SetDefined(true);
|
|
} else {
|
|
result = GPoint(true, p0.GetNetworkId(), p0.GetRouteId(),
|
|
(((p1.GetPosition()-p0.GetPosition()) *
|
|
((t-timeInterval.start) /
|
|
(timeInterval.end - timeInterval.start)))
|
|
+ p0.GetPosition()),
|
|
p0.GetSide());
|
|
result.SetDefined(true);
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
Checks wether a unit passes a fixed point in the network
|
|
|
|
*/
|
|
|
|
bool UGPoint::Passes( const GPoint& p ) const
|
|
{
|
|
assert( IsDefined() );
|
|
assert( p.IsDefined() );
|
|
// Check if this unit is on the same route as the GPoint
|
|
if(p0.GetRouteId()!= p.GetRouteId())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// p is between p0 and p1
|
|
if((p0.GetPosition() < p.GetPosition() &&
|
|
p.GetPosition() < p1.GetPosition()) ||
|
|
(p1.GetPosition() < p.GetPosition() &&
|
|
p.GetPosition() < p0.GetPosition()))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// If the edge of the interval is included we need to check the exakt
|
|
// Position too.
|
|
if((timeInterval.lc &&
|
|
AlmostEqual(p0.GetPosition(), p.GetPosition())) ||
|
|
(timeInterval.rc &&
|
|
AlmostEqual(p1.GetPosition(),p.GetPosition())))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
Restricts the ~UGPoint~ to the times he was at a given ~GPoint~.
|
|
|
|
*/
|
|
|
|
bool UGPoint::At( const GPoint& p, TemporalUnit<GPoint>& result ) const
|
|
{
|
|
if (!IsDefined() || !p.IsDefined()) {
|
|
cerr << "mgpoint and gpoint must be defined." << endl;
|
|
return false;
|
|
}
|
|
assert (IsDefined());
|
|
assert (p.IsDefined());
|
|
UGPoint *pResult = (UGPoint*) &result;
|
|
if (p0.GetNetworkId() != p.GetNetworkId()) {
|
|
return false;
|
|
} else {
|
|
if (p0.GetRouteId() != p.GetRouteId()){
|
|
return false;
|
|
} else {
|
|
if (p.GetSide() != p0.GetSide() &&
|
|
!(p.GetSide() == 2 || p0.GetSide() == 2)) {
|
|
return false;
|
|
} else {
|
|
double start = p0.GetPosition();
|
|
double end = p1.GetPosition();
|
|
double pos = p.GetPosition();
|
|
if (AlmostEqual(start,pos) && timeInterval.lc) {
|
|
Interval<Instant> interval(timeInterval.start,
|
|
timeInterval.start, true, true);
|
|
UGPoint aktunit(interval, p,p);
|
|
*pResult = aktunit;
|
|
return true;
|
|
} else {
|
|
if (AlmostEqual(end,pos) && timeInterval.rc) {
|
|
Interval<Instant> interval(timeInterval.end,
|
|
timeInterval.end, true, true);
|
|
UGPoint aktunit(interval, p,p);
|
|
*pResult = aktunit;
|
|
return true;
|
|
} else {
|
|
if ((start < pos && pos < end) || (end < pos && pos < start)) {
|
|
double factor = fabs(pos-start) / fabs(end-start);
|
|
Instant tpos = (timeInterval.end - timeInterval.start) * factor +
|
|
timeInterval.start;
|
|
Interval<Instant> interval(tpos, tpos, true, true);
|
|
UGPoint aktunit(interval, p, p);
|
|
*pResult = aktunit;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
SECONDO Integration of ~ugpoint~
|
|
|
|
*/
|
|
|
|
bool UGPoint::Check(ListExpr type, ListExpr& errorInfo)
|
|
{
|
|
return (nl->IsEqual( type, UGPoint::BasicType() ));
|
|
}
|
|
|
|
ListExpr UGPoint::Out(ListExpr typeInfo,
|
|
Word value)
|
|
{
|
|
UGPoint* ugpoint = (UGPoint*)(value.addr);
|
|
|
|
if( !(((UGPoint*)value.addr)->IsDefined()) )
|
|
{
|
|
return (nl->SymbolAtom("undef"));
|
|
}
|
|
else
|
|
{
|
|
ListExpr timeintervalList =
|
|
nl->FourElemList(OutDateTime( nl->TheEmptyList(),
|
|
SetWord(&ugpoint->timeInterval.start) ),
|
|
OutDateTime( nl->TheEmptyList(),
|
|
SetWord(&ugpoint->timeInterval.end) ),
|
|
nl->BoolAtom( ugpoint->timeInterval.lc ),
|
|
nl->BoolAtom( ugpoint->timeInterval.rc));
|
|
|
|
ListExpr pointsList =
|
|
nl->FiveElemList(nl->IntAtom( ugpoint->p0.GetNetworkId() ),
|
|
nl->IntAtom( ugpoint->p0.GetRouteId() ),
|
|
nl->IntAtom( ugpoint->p0.GetSide() ),
|
|
nl->RealAtom( ugpoint->p0.GetPosition()),
|
|
nl->RealAtom( ugpoint->p1.GetPosition()));
|
|
return nl->TwoElemList( timeintervalList, pointsList );
|
|
}
|
|
}
|
|
|
|
Word UGPoint::In(const ListExpr typeInfo,
|
|
const ListExpr instance,
|
|
const int errorPos,
|
|
ListExpr& errorInfo,
|
|
bool& correct)
|
|
{
|
|
string errmsg;
|
|
if ( nl->ListLength( instance ) == 2 )
|
|
{
|
|
ListExpr first = nl->First( instance );
|
|
|
|
if( nl->ListLength( first ) == 4 &&
|
|
nl->IsAtom( nl->Third( first ) ) &&
|
|
nl->AtomType( nl->Third( first ) ) == BoolType &&
|
|
nl->IsAtom( nl->Fourth( first ) ) &&
|
|
nl->AtomType( nl->Fourth( first ) ) == BoolType )
|
|
{
|
|
correct = true;
|
|
Instant *start = (Instant *)InInstant( nl->TheEmptyList(),
|
|
nl->First( first ),
|
|
errorPos, errorInfo, correct ).addr;
|
|
|
|
if( !correct )
|
|
{
|
|
errmsg = "InUGPoint(): Error in first instant.";
|
|
errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg));
|
|
start->DeleteIfAllowed();
|
|
return SetWord( Address(0) );
|
|
}
|
|
|
|
Instant *end = (Instant *)InInstant( nl->TheEmptyList(),
|
|
nl->Second( first ),
|
|
errorPos, errorInfo, correct ).addr;
|
|
|
|
if( !correct )
|
|
{
|
|
errmsg = "InUGPoint(): Error in second instant.";
|
|
errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg));
|
|
start->DeleteIfAllowed();
|
|
end->DeleteIfAllowed();
|
|
return SetWord( Address(0) );
|
|
}
|
|
|
|
Interval<Instant> tinterval( *start, *end,
|
|
nl->BoolValue( nl->Third( first ) ),
|
|
nl->BoolValue( nl->Fourth( first ) ) );
|
|
start->DeleteIfAllowed();
|
|
end->DeleteIfAllowed();
|
|
|
|
correct = tinterval.IsValid();
|
|
if (!correct)
|
|
{
|
|
errmsg = "InGUPoint(): Non valid time interval.";
|
|
errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg));
|
|
return SetWord( Address(0) );
|
|
}
|
|
|
|
ListExpr second = nl->Second( instance );
|
|
if( nl->ListLength( second ) == 5 &&
|
|
nl->IsAtom( nl->First( second ) ) &&
|
|
nl->AtomType( nl->First( second ) ) == IntType &&
|
|
nl->IsAtom( nl->Second( second ) ) &&
|
|
nl->AtomType( nl->Second( second ) ) == IntType &&
|
|
nl->IsAtom( nl->Third( second ) ) &&
|
|
nl->AtomType( nl->Third( second ) ) == IntType &&
|
|
nl->IsAtom( nl->Fourth( second ) ) &&
|
|
nl->AtomType( nl->Fourth( second ) ) == RealType &&
|
|
nl->IsAtom( nl->Fifth( second ) ) &&
|
|
nl->AtomType( nl->Fifth( second ) ) == RealType )
|
|
{
|
|
UGPoint *ugpoint = new UGPoint(tinterval,
|
|
nl->IntValue( nl->First( second ) ),
|
|
nl->IntValue( nl->Second( second ) ),
|
|
(Side)nl->IntValue( nl->Third( second ) ),
|
|
nl->RealValue( nl->Fourth( second ) ),
|
|
nl->RealValue( nl->Fifth( second ) ));
|
|
|
|
correct = ugpoint->IsValid();
|
|
if( correct )
|
|
return SetWord( ugpoint );
|
|
|
|
errmsg = "InUGPoint(): Error in start/end point.";
|
|
errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg));
|
|
ugpoint->DeleteIfAllowed();
|
|
}
|
|
}
|
|
}
|
|
else if ( nl->IsAtom( instance ) && nl->AtomType( instance ) == SymbolType
|
|
&& nl->SymbolValue( instance ) == "undef" )
|
|
{
|
|
UGPoint *ugpoint = new UGPoint(true);
|
|
ugpoint->SetDefined(false);
|
|
ugpoint->timeInterval=
|
|
Interval<DateTime>(DateTime(instanttype),
|
|
DateTime(instanttype),true,true);
|
|
correct = ugpoint->timeInterval.IsValid();
|
|
if ( correct )
|
|
return (SetWord( ugpoint ));
|
|
}
|
|
errmsg = "InUGPoint(): Error in representation.";
|
|
errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg));
|
|
correct = false;
|
|
return SetWord( Address(0) );
|
|
}
|
|
|
|
Word UGPoint::Create(const ListExpr typeInfo)
|
|
{
|
|
return (SetWord( new UGPoint(true) ));
|
|
}
|
|
|
|
void UGPoint::Delete(const ListExpr typeInfo,
|
|
Word& w)
|
|
{
|
|
UGPoint *u = (UGPoint *)w.addr;
|
|
if(u->DeleteIfAllowed()) w.addr = 0;
|
|
}
|
|
|
|
void UGPoint::Close(const ListExpr typeInfo,
|
|
Word& w)
|
|
{
|
|
UGPoint *u = (UGPoint *)w.addr;
|
|
if(u->DeleteIfAllowed()) w.addr = 0;
|
|
}
|
|
|
|
Word UGPoint::Clone(const ListExpr typeInfo,
|
|
const Word& w )
|
|
{
|
|
UGPoint *ugpoint = (UGPoint *)w.addr;
|
|
return SetWord( new UGPoint( *ugpoint ) );
|
|
}
|
|
|
|
int UGPoint::SizeOf()
|
|
{
|
|
return sizeof(UGPoint);
|
|
}
|
|
|
|
void* UGPoint::Cast(void* addr)
|
|
{
|
|
return new (addr) UGPoint;
|
|
}
|
|
|
|
|
|
void UGPoint::Deftime(Periods &per) const{
|
|
per.Clear();
|
|
if (IsDefined()) {
|
|
per.StartBulkLoad();
|
|
per.Add(timeInterval);
|
|
per.EndBulkLoad();
|
|
per.SetDefined(true);
|
|
} else per.SetDefined(false);
|
|
}
|
|
|
|
Instant UGPoint::TimeAtPos(const double pos) const{
|
|
double factor = fabs(pos - p0.GetPosition())/
|
|
fabs(p1.GetPosition() - p0.GetPosition());
|
|
return (timeInterval.end - timeInterval.start) * factor + timeInterval.start;
|
|
}
|
|
|
|
|
|
/*
|
|
Computes the distance between two ~ugpoint~
|
|
|
|
*/
|
|
|
|
void UGPoint::Distance (const UGPoint &ugp, UReal &ur) const {
|
|
assert( IsDefined() && ugp.IsDefined() );
|
|
assert( timeInterval.Intersects(ugp.timeInterval) );
|
|
Interval<Instant>iv;
|
|
DateTime DT(durationtype);
|
|
GPoint rgp10, rgp11, rgp20, rgp21;
|
|
double
|
|
x10, x11, x20, x21,
|
|
y10, y11, y20, y21,
|
|
dx1, dy1,
|
|
dx2, dy2,
|
|
dx12, dy12,
|
|
dt;
|
|
|
|
timeInterval.Intersection(ugp.timeInterval, iv);
|
|
ur.timeInterval = iv;
|
|
// ignore closedness for TemporalFunction:
|
|
TemporalFunction( iv.start, rgp10, true);
|
|
TemporalFunction( iv.end, rgp11, true);
|
|
ugp.TemporalFunction(iv.start, rgp20, true);
|
|
ugp.TemporalFunction(iv.end, rgp21, true);
|
|
if (rgp10.GetRouteId() == rgp20.GetRouteId() &&
|
|
AlmostEqual(rgp10.GetPosition(),rgp20.GetPosition()) &&
|
|
AlmostEqual(rgp11.GetPosition(),rgp21.GetPosition()))
|
|
{ // identical points -> zero distance!
|
|
ur.a = 0.0;
|
|
ur.b = 0.0;
|
|
ur.c = 0.0;
|
|
ur.r = false;
|
|
return;
|
|
}
|
|
DT = iv.end - iv.start;
|
|
dt = DT.ToDouble();
|
|
//Network* pNetwork = NetworkManager::GetNetwork(rgp10.GetNetworkId());
|
|
Network* pNetwork = NetworkManager::GetNetworkNew(rgp10.GetNetworkId(),
|
|
netList);
|
|
Point *rp10;
|
|
pNetwork->GetPointOnRoute(&rgp10, rp10);
|
|
Point *rp11;
|
|
pNetwork->GetPointOnRoute(&rgp11, rp11);
|
|
Point *rp20;
|
|
pNetwork->GetPointOnRoute(&rgp20, rp20);
|
|
Point *rp21;
|
|
pNetwork->GetPointOnRoute(&rgp21, rp21);
|
|
x10 = rp10->GetX(); y10 = rp10->GetY();
|
|
x11 = rp11->GetX(); y11 = rp11->GetY();
|
|
x20 = rp20->GetX(); y20 = rp20->GetY();
|
|
x21 = rp21->GetX(); y21 = rp21->GetY();
|
|
dx1 = x11 - x10; // x-difference final-initial for u1
|
|
dy1 = y11 - y10; // y-difference final-initial for u1
|
|
dx2 = x21 - x20; // x-difference final-initial for u2
|
|
dy2 = y21 - y20; // y-difference final-initial for u2
|
|
dx12 = x10 - x20; // x-distance at initial instant
|
|
dy12 = y10 - y20; // y-distance at initial instant
|
|
rp10->DeleteIfAllowed();
|
|
rp11->DeleteIfAllowed();
|
|
rp20->DeleteIfAllowed();
|
|
rp21->DeleteIfAllowed();
|
|
if ( AlmostEqual(dt, 0) )
|
|
{ // almost equal start and end time -> constant distance
|
|
ur.a = 0.0;
|
|
ur.b = 0.0;
|
|
ur.c = pow( ( (x11-x10) - (x21-x20) ) / 2, 2)
|
|
+ pow( ( (y11-y10) - (y21-y20) ) / 2, 2);
|
|
ur.r = true;
|
|
return;
|
|
}
|
|
|
|
double a1 = (pow((dx1-dx2),2)+pow(dy1-dy2,2))/pow(dt,2);
|
|
double b1 = dx12 * (dx1-dx2);
|
|
double b2 = dy12 * (dy1-dy2);
|
|
|
|
ur.a = a1;
|
|
ur.b = 2*(b1+b2)/dt;
|
|
ur.c = pow(dx12,2) + pow(dy12,2);
|
|
ur.r = true;
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
return;
|
|
}
|
|
|
|
const Rectangle<3> UGPoint::BoundingBox(const Geoid* geoid /*=0*/)const {
|
|
if(geoid){
|
|
cerr << __PRETTY_FUNCTION__ << ": Spherical geometry not implemented."
|
|
<< endl;
|
|
assert( !geoid ); // TODO: implement spherical geometry case
|
|
}
|
|
if (IsDefined()) {
|
|
RouteInterval *ri = new RouteInterval(p0.GetRouteId(), p0.GetPosition(),
|
|
p1.GetPosition());
|
|
//Network *pNetwork = NetworkManager::GetNetwork(p0.GetNetworkId());
|
|
Network* pNetwork = NetworkManager::GetNetworkNew(p0.GetNetworkId(),
|
|
netList);
|
|
Rectangle<2> rect = ri->BoundingBox(pNetwork);
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
delete ri;
|
|
double minMax[] = { rect.MinD(0), rect.MaxD(0),
|
|
rect.MinD(1), rect.MaxD(1),
|
|
timeInterval.start.ToDouble(),
|
|
timeInterval.end.ToDouble()};
|
|
return Rectangle<3> (true,minMax);
|
|
} else return Rectangle<3>(false);
|
|
}
|
|
|
|
double UGPoint::Distance(const Rectangle<3>& rect,
|
|
const Geoid* geoid /*=0*/) const{
|
|
cerr << "Distance function not implemented yet";
|
|
if(!IsDefined() || !rect.IsDefined()){
|
|
return -1;
|
|
} else {
|
|
return BoundingBox().Distance(rect);
|
|
}
|
|
}
|
|
|
|
void UGPoint::GetPassedSections(const Network* pNet,
|
|
vector<TupleId>& pS) const
|
|
{
|
|
const RouteInterval *ri = new RouteInterval(p0.GetRouteId(),p0.GetPosition(),
|
|
p1.GetPosition());
|
|
pNet->GetSectionsOfRoutInterval(ri,pS);
|
|
delete ri;
|
|
if (pS.size() > 1 && MovingDirection() == Down)
|
|
{
|
|
vector<TupleId> help;
|
|
help.clear();
|
|
for (size_t a = 0; a < pS.size() ; a++)
|
|
{
|
|
help.push_back(pS[a]);
|
|
}
|
|
pS.clear();
|
|
size_t b = help.size()-1;
|
|
while (b > 0)
|
|
{
|
|
pS.push_back(help[b]);
|
|
b--;
|
|
}
|
|
pS.push_back(help[b]);
|
|
help.clear();
|
|
}
|
|
}
|
|
|
|
|
|
void PartedSection(const UGPoint unit, const double sectMeas1,
|
|
const double sectMeas2,
|
|
double &startPos, int &partNo, const double maxSectLength,
|
|
const int secId, Instant &tStart, Instant &tEnd,
|
|
vector<MGPSecUnit> &res)
|
|
{
|
|
if (unit.MovingDirection() == Up)
|
|
{
|
|
double actEndPos = sectMeas1 + partNo * maxSectLength;
|
|
while (unit.p1.GetPosition() > actEndPos && !(actEndPos > sectMeas2))
|
|
{
|
|
tEnd = unit.TimeAtPos(actEndPos);
|
|
double speed = (actEndPos - startPos)/
|
|
((tEnd - tStart).ToDouble()/0.00001157);
|
|
if (tStart != tEnd)
|
|
res.push_back(MGPSecUnit(true, secId, partNo, Up, speed,
|
|
Interval<Instant> (tStart, tEnd, true, false)));
|
|
tStart = tEnd;
|
|
startPos = actEndPos;
|
|
partNo++;
|
|
actEndPos = sectMeas1 + partNo * maxSectLength;
|
|
}
|
|
if (unit.p1.GetPosition() > sectMeas2)
|
|
{
|
|
tEnd = unit.TimeAtPos(sectMeas2);
|
|
double speed = (sectMeas2 - startPos)/
|
|
((tEnd-tStart).ToDouble()/0.00001157);
|
|
if (tStart != tEnd)
|
|
res.push_back(MGPSecUnit(true, secId, partNo, Up, speed,
|
|
Interval<Instant> (tStart, tEnd, true, false)));
|
|
tStart = tEnd;
|
|
startPos = sectMeas2;
|
|
}
|
|
else
|
|
{
|
|
double speed = (unit.p1.GetPosition()-startPos)/
|
|
((unit.timeInterval.end - tStart).ToDouble()/0.00001157);
|
|
if (tStart != unit.timeInterval.end)
|
|
res.push_back(MGPSecUnit(true, secId, partNo, Up, speed,
|
|
Interval<Instant> (tStart,
|
|
unit.timeInterval.end,
|
|
true, false)));
|
|
startPos = unit.p1.GetPosition();
|
|
tStart = unit.timeInterval.end;
|
|
}
|
|
}
|
|
else //MovingDirection == Down
|
|
{
|
|
double actEndPos = sectMeas1 + (partNo-1) * maxSectLength;
|
|
while (unit.p1.GetPosition() < actEndPos && !(actEndPos < sectMeas1) &&
|
|
partNo > 0)
|
|
{
|
|
tEnd = unit.TimeAtPos(actEndPos);
|
|
double speed = (startPos-actEndPos)/
|
|
((tEnd - tStart).ToDouble()/0.00001157);
|
|
if (tStart != tEnd)
|
|
res.push_back(MGPSecUnit(true, secId, partNo, Down, speed,
|
|
Interval<Instant> (tStart, tEnd, true, false)));
|
|
tStart = tEnd;
|
|
startPos = actEndPos;
|
|
partNo--;
|
|
actEndPos = sectMeas1 + (partNo-1) * maxSectLength;
|
|
}
|
|
if (partNo <= 0) partNo = 1;
|
|
if (unit.p1.GetPosition() < sectMeas1)
|
|
{
|
|
tEnd = unit.TimeAtPos(sectMeas1);
|
|
if (tStart != tEnd)
|
|
{
|
|
double speed = (startPos - sectMeas1)/
|
|
((tEnd-tStart).ToDouble()/0.00001157);
|
|
res.push_back(MGPSecUnit(true, secId, partNo, Down, speed,
|
|
Interval<Instant> (tStart, tEnd, true, false)));
|
|
}
|
|
tStart = tEnd;
|
|
startPos = sectMeas1;
|
|
}
|
|
else
|
|
{
|
|
double speed = (startPos - unit.p1.GetPosition())/
|
|
((unit.timeInterval.end - tStart).ToDouble()/0.00001157);
|
|
if(tStart != unit.timeInterval.end)
|
|
res.push_back(MGPSecUnit(true, secId, partNo, Down, speed,
|
|
Interval<Instant> (tStart,
|
|
unit.timeInterval.end,
|
|
true, false)));
|
|
startPos = unit.p1.GetPosition();
|
|
tStart = unit.timeInterval.end;
|
|
}
|
|
}
|
|
}
|
|
|
|
void NotPartedSection(const UGPoint unit, const double sectMeas1,
|
|
const double sectMeas2, double &startPos, int &partNo,
|
|
const double maxSectLength,
|
|
const int secId, Instant &tStart, Instant &tEnd,
|
|
vector<MGPSecUnit> &res)
|
|
{
|
|
if(unit.MovingDirection() == Up)
|
|
{
|
|
if (unit.p1.GetPosition() > sectMeas2)
|
|
{
|
|
tEnd = unit.TimeAtPos(sectMeas2);
|
|
double speed = (sectMeas2 - startPos)/
|
|
((tEnd - tStart).ToDouble()/0.00001157);
|
|
if (tStart != tEnd)
|
|
res.push_back(MGPSecUnit(true, secId, partNo, Up, speed,
|
|
Interval<Instant> (tStart, tEnd, true, false)));
|
|
tStart = tEnd;
|
|
startPos = sectMeas2;
|
|
}
|
|
else
|
|
{
|
|
double speed = (unit.p1.GetPosition()-startPos)/
|
|
((unit.timeInterval.end - tStart).ToDouble()/0.00001157);
|
|
if (tStart != unit.timeInterval.end)
|
|
res.push_back(MGPSecUnit(true, secId, partNo, Up, speed,
|
|
Interval<Instant> (tStart,
|
|
unit.timeInterval.end,
|
|
true, false)));
|
|
tStart = unit.timeInterval.end;
|
|
startPos = unit.p1.GetPosition();
|
|
}
|
|
}
|
|
else //Moving Down
|
|
{
|
|
if(unit.p1.GetPosition() < sectMeas1)
|
|
{
|
|
tEnd = unit.TimeAtPos(sectMeas1);
|
|
double speed = (startPos - sectMeas1)/
|
|
((tEnd - tStart).ToDouble()/0.00001157);
|
|
if (tStart != tEnd)
|
|
res.push_back(MGPSecUnit(true, secId, partNo, Down, speed,
|
|
Interval<Instant> (tStart, tEnd, true, false)));
|
|
tStart = tEnd;
|
|
startPos = sectMeas1;
|
|
}
|
|
else
|
|
{
|
|
double speed = (startPos - unit.p1.GetPosition())/
|
|
((unit.timeInterval.end - tStart).ToDouble()/0.00001157);
|
|
if (tStart != unit.timeInterval.end)
|
|
res.push_back(MGPSecUnit(true, secId, partNo, Down, speed,
|
|
Interval<Instant> (tStart,
|
|
unit.timeInterval.end,
|
|
true, false)));
|
|
tStart = unit.timeInterval.end;
|
|
startPos = unit.p1.GetPosition();
|
|
}
|
|
}
|
|
}
|
|
|
|
void UGPoint::GetMGPSecUnits(vector<MGPSecUnit>& res,
|
|
const double maxSectLength,
|
|
const Network *pNet) const
|
|
{
|
|
res.clear();
|
|
vector<TupleId> passedSections;
|
|
passedSections.clear();
|
|
GetPassedSections(pNet, passedSections);
|
|
bool moreThanOneSection = false;
|
|
size_t j = 0;
|
|
if (passedSections.size() > 1) moreThanOneSection = true;
|
|
TupleId actSectTid = passedSections[j++];
|
|
Tuple *pActSect = pNet->GetSection(actSectTid);
|
|
int actSectId = ((CcInt*) pActSect->GetAttribute(SECTION_SID))->GetIntval();
|
|
double sectMeas1 =
|
|
((CcReal*)pActSect->GetAttribute(SECTION_MEAS1))->GetRealval();
|
|
double sectMeas2 =
|
|
((CcReal*)pActSect->GetAttribute(SECTION_MEAS2))->GetRealval();
|
|
double sectLength = sectMeas2 - sectMeas1;
|
|
bool sectionParted = false;
|
|
pActSect->DeleteIfAllowed();
|
|
if (sectLength > maxSectLength) sectionParted = true;
|
|
int partNo = 1;
|
|
if (sectionParted) //find section partition of start gpoint
|
|
{
|
|
while (p0.GetPosition() > sectMeas1 + partNo * maxSectLength )
|
|
{
|
|
partNo++;
|
|
}
|
|
}
|
|
if ((!sectionParted && !moreThanOneSection) ||
|
|
(sectionParted && !moreThanOneSection &&
|
|
(p1.GetPosition() >= sectMeas1 + (partNo-1) * maxSectLength &&
|
|
p1.GetPosition() <= sectMeas1 + partNo * maxSectLength)))
|
|
{ //whole unit one mgpsecunit
|
|
res.push_back(MGPSecUnit(true,actSectId, partNo, MovingDirection(),
|
|
Speed(), GetUnitTimeInterval()));
|
|
}
|
|
else
|
|
{
|
|
Instant tStart = timeInterval.start;
|
|
Instant tEnd = tStart;
|
|
double startPos = p0.GetPosition();
|
|
if (!sectionParted) NotPartedSection(*this, sectMeas1, sectMeas2, startPos,
|
|
partNo, maxSectLength, actSectId,
|
|
tStart, tEnd, res);
|
|
else PartedSection(*this, sectMeas1, sectMeas2, startPos,
|
|
partNo, maxSectLength, actSectId, tStart,
|
|
tEnd, res);
|
|
while (moreThanOneSection && j < passedSections.size())
|
|
{
|
|
actSectTid = passedSections[j++];
|
|
pActSect = pNet->GetSection(actSectTid);
|
|
actSectId =
|
|
((CcInt*) pActSect->GetAttribute(SECTION_SID))->GetIntval();
|
|
sectMeas1 =
|
|
((CcReal*)pActSect->GetAttribute(SECTION_MEAS1))->GetRealval();
|
|
sectMeas2 =
|
|
((CcReal*)pActSect->GetAttribute(SECTION_MEAS2))->GetRealval();
|
|
sectLength = sectMeas2 - sectMeas1;
|
|
pActSect->DeleteIfAllowed();
|
|
sectionParted = false;
|
|
if (sectLength > maxSectLength) sectionParted = true;
|
|
partNo = 1;
|
|
if (sectionParted) //find section partition of start gpoint
|
|
{
|
|
while (startPos > sectMeas1 + partNo * maxSectLength )
|
|
{
|
|
partNo++;
|
|
}
|
|
PartedSection(*this, sectMeas1, sectMeas2, startPos, partNo,
|
|
maxSectLength, actSectId, tStart, tEnd, res);
|
|
}
|
|
else
|
|
{
|
|
NotPartedSection(*this, sectMeas1, sectMeas2, startPos, partNo,
|
|
maxSectLength, actSectId, tStart, tEnd, res);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
Rectangle<3> UGPoint::BoundingBox(const Network* pNetwork,
|
|
const Geoid* geoid /*=0*/)const{
|
|
if(geoid){
|
|
cerr << __PRETTY_FUNCTION__ << ": Spherical geometry not implemented."
|
|
<< endl;
|
|
assert( !geoid ); // TODO: implement spherical geometry case
|
|
}
|
|
if(IsDefined()){
|
|
RouteInterval *ri = new RouteInterval(p0.GetRouteId(), p0.GetPosition(),
|
|
p1.GetPosition());
|
|
Rectangle<2> rect = ri->BoundingBox(pNetwork);
|
|
delete ri;
|
|
double minMax[] = { rect.MinD(0), rect.MaxD(0),
|
|
rect.MinD(1), rect.MaxD(1),
|
|
timeInterval.start.ToDouble(),
|
|
timeInterval.end.ToDouble()};
|
|
return Rectangle<3> (true,minMax);
|
|
}else return Rectangle<3>(false);
|
|
}
|
|
|
|
/*
|
|
Network Distance computation for ~ugpoint~ values.
|
|
|
|
*/
|
|
|
|
void UGPoint::NetdistanceFromArg(const GPoint* gp, UReal* result) const
|
|
{
|
|
if (!IsDefined() || gp == 0 || !gp->IsDefined() ||
|
|
GetNetworkId() != gp->GetNetworkId())
|
|
result->SetDefined(false);
|
|
else
|
|
{
|
|
Network *pNetwork = NetworkManager::GetNetworkNew(GetNetworkId(),netList);
|
|
|
|
GLine *pPath = new GLine(0);
|
|
|
|
if (gp->ShortestPathAStar(&p0,pPath,pNetwork,0))
|
|
{
|
|
if (pPath->NoOfComponents() > 0)
|
|
{
|
|
RouteInterval lastRI;
|
|
double dist = pPath->GetLength();
|
|
pPath->Get(pPath->NoOfComponents()-1, lastRI);
|
|
if (lastRI.Contains(&p1))
|
|
*result = UReal(GetUnitTimeInterval(), dist,
|
|
dist - fabs(p0.GetPosition()-p1.GetPosition()));
|
|
else
|
|
*result = UReal(GetUnitTimeInterval(), dist,
|
|
dist + fabs(p0.GetPosition() - p1.GetPosition()));
|
|
}
|
|
else
|
|
*result = UReal(GetUnitTimeInterval(), 0.0,
|
|
fabs(p0.GetPosition() - p1.GetPosition()));
|
|
}
|
|
else
|
|
result->SetDefined(false);
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
pPath->DeleteIfAllowed();
|
|
}
|
|
}
|
|
|
|
void UGPoint::NetdistanceToArg(const GPoint* gp, UReal *result) const
|
|
{
|
|
if (!IsDefined() || !gp->IsDefined() ||
|
|
GetNetworkId()!= gp->GetNetworkId())
|
|
result->SetDefined(false);
|
|
else
|
|
{
|
|
Network *pNetwork = NetworkManager::GetNetworkNew(GetNetworkId(),netList);
|
|
GLine *pPath = new GLine(0);
|
|
if (p0.ShortestPathAStar(gp,pPath,pNetwork,0))
|
|
{
|
|
if (pPath->IsDefined() && pPath->NoOfComponents() > 0)
|
|
{
|
|
RouteInterval firstRI;
|
|
double dist = pPath->GetLength();
|
|
pPath->Get(0, firstRI);
|
|
if (firstRI.Contains(&p1))
|
|
*result = UReal(GetUnitTimeInterval(), dist,
|
|
dist - fabs(p0.GetPosition() - p1.GetPosition()));
|
|
else
|
|
*result = UReal(GetUnitTimeInterval(), dist,
|
|
dist + fabs(p0.GetPosition() - p1.GetPosition()));
|
|
}
|
|
else
|
|
*result = UReal(GetUnitTimeInterval(), 0.0,
|
|
fabs(p0.GetPosition() - p1.GetPosition()));
|
|
}
|
|
else
|
|
result->SetDefined(false);
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
pPath->DeleteIfAllowed();
|
|
}
|
|
}
|
|
|
|
void UGPoint::Netdistance(const UGPoint* ugp, UReal* result) const
|
|
{
|
|
if (!IsDefined() || !ugp->IsDefined() ||
|
|
GetNetworkId()!= ugp->GetNetworkId() ||
|
|
GetUnitTimeInterval() != ugp->GetUnitTimeInterval())
|
|
result->SetDefined(false);
|
|
else
|
|
{
|
|
Network *pNetwork = NetworkManager::GetNetworkNew(GetNetworkId(),netList);
|
|
GLine *pPath = new GLine(0);
|
|
GPoint startPos = ugp->GetStartPoint();
|
|
GPoint endPos = ugp->GetEndPoint();
|
|
if (p0.ShortestPathAStar(&startPos,pPath,pNetwork))
|
|
{
|
|
if (pPath->IsDefined() && pPath->NoOfComponents() > 0)
|
|
{
|
|
RouteInterval firstRI, lastRI;
|
|
double startdist = pPath->GetLength();
|
|
double enddist = startdist;
|
|
pPath->Get(0, firstRI);
|
|
pPath->Get(pPath->NoOfComponents()-1,lastRI);
|
|
if (firstRI.Contains(&p1))
|
|
enddist = enddist - fabs(p0.GetPosition()-p1.GetPosition());
|
|
else
|
|
enddist = enddist + fabs(p0.GetPosition()-p1.GetPosition());
|
|
if (lastRI.Contains(&endPos))
|
|
enddist =
|
|
enddist - fabs(endPos.GetPosition() - startPos.GetPosition());
|
|
else
|
|
enddist =
|
|
enddist + fabs(endPos.GetPosition() - startPos.GetPosition());
|
|
*result = UReal(GetUnitTimeInterval(), startdist, enddist);
|
|
}
|
|
else
|
|
{
|
|
if (GetUnitRid() == ugp->GetUnitRid())
|
|
*result = UReal(GetUnitTimeInterval(), 0.0,
|
|
fabs(endPos.GetPosition() - p1.GetPosition()));
|
|
else
|
|
*result = UReal(GetUnitTimeInterval(), 0.0,
|
|
endPos.GetPosition() + p1.GetPosition());
|
|
}
|
|
}
|
|
else
|
|
result->SetDefined(false);
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
pPath->DeleteIfAllowed();
|
|
}
|
|
}
|
|
|
|
/*
|
|
Restricts the result to the given time interval.
|
|
|
|
*/
|
|
void UGPoint::AtInterval( const Interval<Instant>& i,
|
|
TemporalUnit<GPoint>& result ) const
|
|
{
|
|
assert( IsDefined() );
|
|
assert( i.IsValid() );
|
|
|
|
TemporalUnit<GPoint>::AtInterval( i, result );
|
|
|
|
UGPoint *pResult = (UGPoint*)&result;
|
|
pResult->SetDefined( IsDefined() );
|
|
|
|
if( !IsDefined() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if( timeInterval.start == result.timeInterval.start )
|
|
{
|
|
pResult->p0 = p0;
|
|
pResult->timeInterval.start = timeInterval.start;
|
|
pResult->timeInterval.lc = (pResult->timeInterval.lc && timeInterval.lc);
|
|
}
|
|
else
|
|
TemporalFunction( result.timeInterval.start, pResult->p0 );
|
|
|
|
if( timeInterval.end == result.timeInterval.end )
|
|
{
|
|
pResult->p1 = p1;
|
|
pResult->timeInterval.end = timeInterval.end;
|
|
pResult->timeInterval.rc = (pResult->timeInterval.rc && timeInterval.rc);
|
|
}
|
|
else
|
|
TemporalFunction( result.timeInterval.end, pResult->p1 );
|
|
}
|
|
|
|
struct ugpointInfo:ConstructorInfo{
|
|
ugpointInfo(){
|
|
name = UGPoint::BasicType();
|
|
signature = "-> UNIT";
|
|
typeExample = UGPoint::BasicType();
|
|
listRep = "(<timeInterval> <gpoint1> <gpoint2>)";
|
|
valueExample = "(<timeInterval><gpoint1><gpoint2>)";
|
|
remarks = "Linear movement of a mgpoint in the network.";
|
|
}
|
|
};
|
|
|
|
struct ugpointFunctions:ConstructorFunctions<UGPoint>{
|
|
ugpointFunctions(){
|
|
in = UGPoint::In;
|
|
out = UGPoint::Out;
|
|
create = UGPoint::Create;
|
|
deletion = UGPoint::Delete;
|
|
open = OpenAttribute<UGPoint>;
|
|
save = SaveAttribute<UGPoint>;
|
|
close = UGPoint::Close;
|
|
clone = UGPoint::Clone;
|
|
cast = UGPoint::Cast;
|
|
sizeOf = UGPoint::SizeOf;
|
|
kindCheck = UGPoint::Check;
|
|
}
|
|
};
|
|
|
|
ugpointInfo ugpi;
|
|
ugpointFunctions ugpf;
|
|
TypeConstructor ugpointTC(ugpi,ugpf);
|
|
|
|
/*
|
|
4 ~igpoint~
|
|
|
|
*/
|
|
|
|
bool CheckIntimeGPoint( ListExpr type, ListExpr& errorInfo )
|
|
{
|
|
return (nl->IsEqual( type, IGPoint::BasicType() ));
|
|
}
|
|
|
|
struct igpointInfo:ConstructorInfo{
|
|
igpointInfo(){
|
|
name = IGPoint::BasicType();
|
|
signature = "->TEMPORAL";
|
|
typeExample = IGPoint::BasicType();
|
|
listRep = "(<instant> <gpoint>)";
|
|
valueExample ="((instant) (1 1 3.0 1))";
|
|
remarks = "Position of a mgpoint at a that point in time.";
|
|
}
|
|
};
|
|
|
|
struct igpointFunctions:ConstructorFunctions<Intime<GPoint> >{
|
|
igpointFunctions(){
|
|
in = InIntime<GPoint,GPoint::InGPoint>;
|
|
out = OutIntime<GPoint, GPoint::OutGPoint>;
|
|
create = CreateIntime<GPoint>;
|
|
deletion = DeleteIntime<GPoint>;
|
|
open = OpenAttribute<Intime<GPoint> >;
|
|
save = SaveAttribute<Intime<GPoint> >;
|
|
close = CloseIntime<GPoint>;
|
|
clone = CloneIntime<GPoint>;
|
|
cast = CastIntime<GPoint>;
|
|
sizeOf = SizeOfIntime<GPoint>;
|
|
kindCheck = CheckIntimeGPoint;
|
|
}
|
|
};
|
|
|
|
igpointInfo igpi;
|
|
igpointFunctions igpf;
|
|
TypeConstructor igpointTC(igpi,igpf);
|
|
|
|
/*
|
|
2. Implementation of Class ~MGPSecUnit~
|
|
|
|
*/
|
|
MGPSecUnit::MGPSecUnit():Attribute()
|
|
{
|
|
}
|
|
|
|
MGPSecUnit::MGPSecUnit(const bool defined, const int secId, const int part,
|
|
const Side direct, const double sp,
|
|
const Interval<Instant> timeInterval):
|
|
Attribute(defined),
|
|
m_secId(secId),
|
|
m_part(part),
|
|
m_direct(direct),
|
|
m_speed(sp),
|
|
m_time(timeInterval)
|
|
{
|
|
SetDefined(defined);
|
|
}
|
|
|
|
MGPSecUnit::MGPSecUnit( const MGPSecUnit& in_xOther):
|
|
Attribute(in_xOther.IsDefined())
|
|
{
|
|
SetDefined(in_xOther.IsDefined());
|
|
if (IsDefined())
|
|
{
|
|
m_secId = in_xOther.GetSecId();
|
|
m_part = in_xOther.GetPart();
|
|
m_direct = in_xOther.GetDirect();
|
|
m_speed = in_xOther.GetSpeed();
|
|
m_time = in_xOther.GetTimeInterval();
|
|
}
|
|
}
|
|
|
|
MGPSecUnit::~MGPSecUnit() {}
|
|
|
|
int MGPSecUnit::GetSecId() const
|
|
{
|
|
return m_secId;
|
|
}
|
|
|
|
int MGPSecUnit::GetPart() const
|
|
{
|
|
return m_part;
|
|
}
|
|
|
|
Side MGPSecUnit::GetDirect() const
|
|
{
|
|
return m_direct;
|
|
}
|
|
|
|
double MGPSecUnit::GetSpeed() const
|
|
{
|
|
return m_speed;
|
|
}
|
|
|
|
Interval<Instant> MGPSecUnit::GetTimeInterval() const
|
|
{
|
|
return m_time;
|
|
}
|
|
|
|
double MGPSecUnit::GetDurationInSeconds() const
|
|
{
|
|
return (m_time.end - m_time.start).ToDouble()/0.00001157;
|
|
}
|
|
|
|
|
|
void MGPSecUnit::SetSecId(const int secId)
|
|
{
|
|
m_secId = secId;
|
|
}
|
|
|
|
void MGPSecUnit::SetPart(const int p)
|
|
{
|
|
m_part = p;
|
|
}
|
|
|
|
void MGPSecUnit::SetDirect(const Side dir)
|
|
{
|
|
m_direct = dir;
|
|
}
|
|
|
|
void MGPSecUnit::SetSpeed(const double x)
|
|
{
|
|
m_speed = x;
|
|
}
|
|
|
|
void MGPSecUnit::SetTimeInterval(const Interval<Instant> time)
|
|
{
|
|
m_time = time;
|
|
}
|
|
|
|
MGPSecUnit& MGPSecUnit::operator=( const MGPSecUnit& in_xOther )
|
|
{
|
|
m_secId = in_xOther.GetSecId();
|
|
m_part = in_xOther.GetPart();
|
|
m_direct = in_xOther.GetDirect();
|
|
m_speed = in_xOther.GetSpeed();
|
|
m_time = in_xOther.GetTimeInterval();
|
|
SetDefined(in_xOther.IsDefined());
|
|
return *this;
|
|
}
|
|
|
|
size_t MGPSecUnit::Sizeof() const
|
|
{
|
|
return sizeof(MGPSecUnit);
|
|
}
|
|
|
|
size_t MGPSecUnit::HashValue() const
|
|
{
|
|
size_t hash = m_secId + m_part + (int) m_direct + (int) m_speed +
|
|
(int) m_time.start.ToDouble() +
|
|
(int) m_time.end.ToDouble();
|
|
return hash;
|
|
}
|
|
|
|
void MGPSecUnit::CopyFrom( const Attribute* right )
|
|
{
|
|
const MGPSecUnit* gp = (const MGPSecUnit*)right;
|
|
*this = *gp;
|
|
}
|
|
|
|
int MGPSecUnit::Compare( const Attribute* arg ) const
|
|
{
|
|
const MGPSecUnit *p = (const MGPSecUnit*) arg;
|
|
if (!IsDefined() && !p->IsDefined()) return 0;
|
|
if (!IsDefined() && p->IsDefined()) return -1;
|
|
if (IsDefined() && !p->IsDefined()) return 1;
|
|
if (m_secId < p->GetSecId()) return -1;
|
|
else
|
|
if (m_secId > p->GetSecId()) return 1;
|
|
else
|
|
if (m_part < p->GetPart()) return -1;
|
|
else
|
|
if (m_part > p->GetPart()) return 1;
|
|
else
|
|
if (m_direct < p->GetDirect()) return -1;
|
|
else
|
|
if (m_direct > p->GetDirect()) return 1;
|
|
else
|
|
if (m_time.start < p->GetTimeInterval().start) return -1;
|
|
else
|
|
if (m_time.start > p->GetTimeInterval().start) return 1;
|
|
else
|
|
if (m_time.end < p->GetTimeInterval().end) return -1;
|
|
else
|
|
if (m_time.end > p->GetTimeInterval().end) return 1;
|
|
else
|
|
if (m_speed < p->GetSpeed()) return -1;
|
|
else
|
|
if (m_speed > p->GetSpeed()) return 1;
|
|
else return 0;
|
|
}
|
|
|
|
bool MGPSecUnit::operator<(const MGPSecUnit arg) const
|
|
{
|
|
return Compare(&arg) < 0;
|
|
}
|
|
|
|
bool MGPSecUnit::operator>(const MGPSecUnit arg) const
|
|
{
|
|
return Compare(&arg) > 0;
|
|
}
|
|
|
|
bool MGPSecUnit::operator==(const MGPSecUnit arg)const{
|
|
return Compare(&arg)==0;
|
|
}
|
|
|
|
bool MGPSecUnit::operator!=(const MGPSecUnit arg)const{
|
|
return Compare(&arg)!=0;
|
|
}
|
|
|
|
bool MGPSecUnit::operator<=(const MGPSecUnit arg)const{
|
|
return Compare(&arg)<=0;
|
|
}
|
|
|
|
bool MGPSecUnit::operator>=(const MGPSecUnit arg)const{
|
|
return Compare(&arg)>=0;
|
|
}
|
|
|
|
bool MGPSecUnit::Adjacent( const Attribute *arg ) const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
MGPSecUnit* MGPSecUnit::Clone() const
|
|
{
|
|
return new MGPSecUnit( *this );
|
|
}
|
|
|
|
ostream& MGPSecUnit::Print( ostream& os ) const
|
|
{
|
|
os << "MGPSecUnit: " << m_secId
|
|
<< ", Part: " << m_part
|
|
<< ", Side: " << m_direct
|
|
<< ", Speed: " << m_speed
|
|
<< ", Timeinterval: " ;
|
|
m_time.Print(os);
|
|
os << endl;
|
|
return os;
|
|
}
|
|
|
|
|
|
ListExpr MGPSecUnit::Out(ListExpr typeInfo, Word value)
|
|
{
|
|
MGPSecUnit* msec = static_cast<MGPSecUnit*> (value.addr);
|
|
if (msec->IsDefined())
|
|
return nl->FiveElemList(nl->IntAtom(msec->GetSecId()),
|
|
nl->IntAtom(msec->GetPart()),
|
|
nl->IntAtom(msec->GetDirect()),
|
|
nl->RealAtom(msec->GetSpeed()),
|
|
nl->FourElemList(OutDateTime(nl->TheEmptyList(),
|
|
SetWord(&msec->m_time.start)),
|
|
OutDateTime(nl->TheEmptyList(),
|
|
SetWord(&msec->m_time.end)),
|
|
nl->BoolAtom(msec->m_time.lc),
|
|
nl->BoolAtom(msec->m_time.rc)));
|
|
else return nl->SymbolAtom("undef");
|
|
}
|
|
|
|
Word MGPSecUnit::In(const ListExpr typeInfo, const ListExpr instance,
|
|
const int errorPos, ListExpr& errorInfo, bool& correct)
|
|
{
|
|
NList list(instance);
|
|
if (list.length() == 5)
|
|
{
|
|
NList seclist = list.first();
|
|
NList partlist = list.second();
|
|
NList dirlist = list.third();
|
|
NList speedlist = list.fourth();
|
|
if (seclist.isInt() && dirlist.isInt()
|
|
&& partlist.isInt() && speedlist.isReal())
|
|
{
|
|
NList timelist = list.fifth();
|
|
if (timelist.length() == 4)
|
|
{
|
|
NList stinst = timelist.first();
|
|
NList einst = timelist.second();
|
|
NList lclist = timelist.third();
|
|
NList rclist = timelist.fourth();
|
|
if (lclist.isBool() && rclist.isBool())
|
|
{
|
|
correct = true;
|
|
Instant *start = (Instant*)InInstant(nl->TheEmptyList(),
|
|
stinst.listExpr(),
|
|
errorPos,
|
|
errorInfo,
|
|
correct).addr;
|
|
if(correct)
|
|
{
|
|
Instant *end = (Instant*)InInstant(nl->TheEmptyList(),
|
|
einst.listExpr(),
|
|
errorPos,
|
|
errorInfo,
|
|
correct).addr;
|
|
if (correct)
|
|
{
|
|
Word w = new MGPSecUnit(true,
|
|
seclist.intval(),
|
|
partlist.intval(),
|
|
(Side) dirlist.intval(),
|
|
nl->RealValue(speedlist.listExpr()),
|
|
Interval<Instant> (*start, *end,
|
|
lclist.boolval(),
|
|
rclist.boolval()));
|
|
return w;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
errorInfo = nl->Append(errorInfo, nl->StringAtom(
|
|
"Expected <int><int><int><real><timeinterval>."));
|
|
correct = false;
|
|
return SetWord(Address(0));
|
|
}
|
|
|
|
bool MGPSecUnit::CheckKind( ListExpr type, ListExpr& errorInfo )
|
|
{
|
|
return (nl->IsEqual( type, MGPSecUnit::BasicType() ));
|
|
}
|
|
|
|
int MGPSecUnit::NumOfFLOBs()const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
Flob* MGPSecUnit::GetFLOB(const int i)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void* MGPSecUnit::Cast(void* addr)
|
|
{
|
|
return new (addr) MGPSecUnit;
|
|
}
|
|
|
|
/*
|
|
3 Type Constructor for ~mgpsecunit~
|
|
|
|
*/
|
|
struct mgpsecFunctions:ConstructorFunctions<MGPSecUnit>
|
|
{
|
|
mgpsecFunctions()
|
|
{
|
|
in = MGPSecUnit::In;
|
|
out = MGPSecUnit::Out;
|
|
kindCheck = MGPSecUnit::CheckKind;
|
|
cast = MGPSecUnit::Cast;
|
|
}
|
|
};
|
|
|
|
struct mgpsecInfo:ConstructorInfo
|
|
{
|
|
mgpsecInfo()
|
|
{
|
|
name = MGPSecUnit::BasicType();
|
|
signature = "-> DATA";
|
|
typeExample = MGPSecUnit::BasicType();
|
|
listRep = "(<secId><part><dir><speed>(<timeinterval>))";
|
|
valueExample = "(15 1 1 3.5 <timeinterval>)";
|
|
remarks = "direction:down=0,up=1,none=2. Speed: m/s";
|
|
}
|
|
};
|
|
|
|
mgpsecInfo mgpinfo;
|
|
mgpsecFunctions mgpfunct;
|
|
TypeConstructor mgpsecunitTC(mgpinfo, mgpfunct);
|
|
|
|
/*
|
|
5 Operators
|
|
|
|
5.0 ~mgp2mgpsecunit~
|
|
|
|
The operation ~mgp2mgpsecunit~ gets a network and a maximum section
|
|
length and a stream of ~mgpoint~. With this values it computes the
|
|
|
|
TypeMapping:
|
|
|
|
*/
|
|
|
|
ListExpr OpMgp2mgpsecunitsTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList type(in_xArgs);
|
|
if (type.length() == 4)
|
|
{
|
|
ListExpr rel = type.first().listExpr();
|
|
ListExpr attr = type.second().listExpr();
|
|
NList net = type.third();
|
|
NList length = type.fourth();
|
|
if (net.isEqual(Network::BasicType()) && length.isEqual(CcReal::BasicType())
|
|
&& (!(nl->IsAtom(attr) && nl->AtomType(attr) != SymbolType))
|
|
&& IsRelDescription(rel))
|
|
{
|
|
string attrname = nl->SymbolValue(attr);
|
|
ListExpr attrtype;
|
|
ListExpr tupleDescr = nl->Second(rel);
|
|
int j=listutils::findAttribute(nl->Second(tupleDescr),attrname, attrtype);
|
|
if (j!=0 && nl->IsEqual(attrtype, MGPoint::BasicType()))
|
|
{
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
|
|
nl->OneElemList(nl->IntAtom(j)),
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(MGPSecUnit::BasicType())));
|
|
}
|
|
}
|
|
}
|
|
return NList::typeError(
|
|
"Expected <rel(tuple(..ai xi..)><ai><network><real> with xi=mgpoint.");
|
|
}
|
|
|
|
/*
|
|
Auxilliary Functions
|
|
|
|
*/
|
|
|
|
struct OpMgp2mgpsecLocalInfo
|
|
{
|
|
OpMgp2mgpsecLocalInfo()
|
|
{
|
|
vmgpsecunit.clear();
|
|
pos = 0;
|
|
pNetwork = 0;
|
|
iterRel = 0;
|
|
attrIndex = 0;
|
|
maxSectLength = numeric_limits<double>::max();
|
|
}
|
|
|
|
vector<MGPSecUnit> vmgpsecunit; // vector mit mgpsecunits
|
|
size_t pos; //position im Vector
|
|
Network *pNetwork; //networkobject
|
|
GenericRelationIterator *iterRel; //pointer to actual tuple of rel
|
|
int attrIndex; //attribute index of mgpoint attribut in rel
|
|
double maxSectLength; //maximum section part length
|
|
};
|
|
|
|
/*
|
|
Value Mapping
|
|
|
|
*/
|
|
|
|
int OpMgp2mgpsecunitsValueMap(Word* args, Word& result, int message,
|
|
Word& local, Supplier s)
|
|
{
|
|
OpMgp2mgpsecLocalInfo* li = 0;
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
{
|
|
li = new OpMgp2mgpsecLocalInfo();
|
|
GenericRelation *rel = (GenericRelation*) args[0].addr;
|
|
li->pNetwork = (Network*) args[2].addr;
|
|
li->maxSectLength = ((CcReal*) args[3].addr)->GetRealval();
|
|
li->attrIndex = ((CcInt*)args[4].addr)->GetIntval()-1;
|
|
li->iterRel = rel->MakeScan();
|
|
local.addr = li;
|
|
return 0;
|
|
}
|
|
|
|
case REQUEST:
|
|
{
|
|
result = qp->ResultStorage(s);
|
|
if (local.addr)
|
|
li = (OpMgp2mgpsecLocalInfo*) local.addr;
|
|
else return CANCEL;
|
|
if (!li->vmgpsecunit.empty() && li->pos < li->vmgpsecunit.size())
|
|
{
|
|
result = SetWord(new MGPSecUnit(li->vmgpsecunit[li->pos++]));
|
|
return YIELD;
|
|
}
|
|
else
|
|
{
|
|
li->vmgpsecunit.clear();
|
|
Tuple *actTuple = li->iterRel->GetNextTuple() ;
|
|
while (actTuple != 0)
|
|
{
|
|
MGPoint *m = (MGPoint*) actTuple->GetAttribute(li->attrIndex);
|
|
if (m != 0)
|
|
{
|
|
m->GetMGPSecUnits(li->vmgpsecunit, li->maxSectLength, li->pNetwork);
|
|
if (li->vmgpsecunit.size() > 0)
|
|
{
|
|
li->pos = 0;
|
|
result = SetWord(new MGPSecUnit(li->vmgpsecunit[li->pos++]));
|
|
actTuple->DeleteIfAllowed();
|
|
return YIELD;
|
|
}
|
|
}
|
|
actTuple->DeleteIfAllowed();
|
|
actTuple = li->iterRel->GetNextTuple();
|
|
}
|
|
return CANCEL;
|
|
}
|
|
}
|
|
|
|
case CLOSE:
|
|
{
|
|
if (local.addr)
|
|
{
|
|
li = (OpMgp2mgpsecLocalInfo*) local.addr;
|
|
li->pNetwork = 0;
|
|
if (li->iterRel)
|
|
delete li->iterRel;
|
|
li->iterRel = 0;
|
|
li->vmgpsecunit.clear();
|
|
delete li;
|
|
li = 0;
|
|
local.addr = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
default:
|
|
{
|
|
// should not happen
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
struct mgp2mgpsecunitsInfo : OperatorInfo {
|
|
|
|
mgp2mgpsecunitsInfo()
|
|
{
|
|
name = "mgp2mgpsecunits";
|
|
signature = "rel x attr x net x real->stream(mgpsecunit)";
|
|
syntax = "_ mgp2mgpsecunits[_,_,_]";
|
|
meaning = "Stream of mgpsecunits from mgpoint attr in rel.";
|
|
}
|
|
};
|
|
|
|
/*
|
|
5.0.1 ~mgp2mgpsecunit2~
|
|
|
|
The operation ~mgp2mgpsecunit2~ gets a maximum section
|
|
length and a ~mgpoint~. With this values it computes the mgpsecunits of
|
|
the mgpoint.
|
|
|
|
TypeMapping:
|
|
|
|
*/
|
|
|
|
ListExpr OpMgp2mgpsecunits2TypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList type(in_xArgs);
|
|
if (type.length() == 2)
|
|
{
|
|
NList mgp = type.first();
|
|
NList length = type.second();
|
|
if (mgp.isEqual(MGPoint::BasicType()) &&
|
|
length.isEqual(CcReal::BasicType()))
|
|
{
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(MGPSecUnit::BasicType()));
|
|
}
|
|
}
|
|
return NList::typeError( MGPoint::BasicType() + " and " + CcReal::BasicType()
|
|
+ " expected.");
|
|
}
|
|
|
|
/*
|
|
Auxilliary Functions
|
|
|
|
*/
|
|
|
|
struct OpMgp2mgpsec2LocalInfo
|
|
{
|
|
OpMgp2mgpsec2LocalInfo()
|
|
{
|
|
vmgpsecunit.clear();
|
|
pos = 0;
|
|
}
|
|
|
|
vector<MGPSecUnit> vmgpsecunit; // vector mit mgpsecunits
|
|
size_t pos; //position im Vector
|
|
};
|
|
|
|
/*
|
|
Value Mapping
|
|
|
|
*/
|
|
|
|
int OpMgp2mgpsecunits2ValueMap(Word* args, Word& result, int message,
|
|
Word& local, Supplier s)
|
|
{
|
|
OpMgp2mgpsec2LocalInfo* li = 0;
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
{
|
|
li = new OpMgp2mgpsec2LocalInfo();
|
|
MGPoint *m = (MGPoint*) args[0].addr;
|
|
Network *pNetwork = m->GetNetwork();
|
|
double maxSectLength = ((CcReal*) args[1].addr)->GetRealval();
|
|
li->vmgpsecunit.clear();
|
|
m->GetMGPSecUnits(li->vmgpsecunit, maxSectLength, pNetwork);
|
|
li->pos = 0;
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
local.addr = li;
|
|
return 0;
|
|
}
|
|
|
|
case REQUEST:
|
|
{
|
|
result = qp->ResultStorage(s);
|
|
if (local.addr)
|
|
li = (OpMgp2mgpsec2LocalInfo*) local.addr;
|
|
else return CANCEL;
|
|
if (!li->vmgpsecunit.empty() && li->pos < li->vmgpsecunit.size())
|
|
{
|
|
result = SetWord(new MGPSecUnit(li->vmgpsecunit[li->pos++]));
|
|
return YIELD;
|
|
}
|
|
else return CANCEL;
|
|
}
|
|
|
|
case CLOSE:
|
|
{
|
|
if (local.addr)
|
|
{
|
|
li = (OpMgp2mgpsec2LocalInfo*) local.addr;
|
|
li->vmgpsecunit.clear();
|
|
delete li;
|
|
li = 0;
|
|
local.addr = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
default:
|
|
{
|
|
// should not happen
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
struct mgp2mgpsecunits2Info : OperatorInfo {
|
|
|
|
mgp2mgpsecunits2Info()
|
|
{
|
|
name = "mgp2mgpsecunits2";
|
|
signature = MGPoint::BasicType() + " x " + CcReal::BasicType() + " -> " +
|
|
Symbol::STREAM() + "(" + MGPSecUnit::BasicType()+")";
|
|
syntax = "mgp2mgpsecunits2 (_ , _ )";
|
|
meaning = "Builds a stream of mgpsecunits from mgpoint.";
|
|
}
|
|
};
|
|
|
|
/*
|
|
5.0.2 ~mgp2mgpsecunit3~
|
|
|
|
The operation ~mgp2mgpsecunit3~ gets a maximum section
|
|
length and a ~stream~ of ~mgpoint~. With this values it computes a
|
|
~stream~ of ~mgpsecunit~s for this mgpoints.
|
|
|
|
TypeMapping:
|
|
|
|
*/
|
|
|
|
ListExpr OpMgp2mgpsecunits3TypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList type(in_xArgs);
|
|
if (type.length() == 2)
|
|
{
|
|
NList stream = type.first();
|
|
NList mgp(MGPoint::BasicType());
|
|
NList partlength = type.second();
|
|
if (stream.length() == 2 && stream.checkStream(mgp) &&
|
|
partlength.isEqual(CcReal::BasicType()))
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(MGPSecUnit::BasicType()));
|
|
}
|
|
return NList::typeError( "Expected a" + Symbol::STREAM() + " of " +
|
|
MGPoint::BasicType() + " and an " + CcReal::BasicType() + " value.");
|
|
}
|
|
|
|
/*
|
|
Auxilliary Functions
|
|
|
|
*/
|
|
|
|
struct OpMgp2mgpsec3LocalInfo
|
|
{
|
|
OpMgp2mgpsec3LocalInfo()
|
|
{
|
|
vmgpsecunit.clear();
|
|
pos = 0;
|
|
maxLength = 0.0;
|
|
pNetwork = 0;
|
|
}
|
|
|
|
vector<MGPSecUnit> vmgpsecunit; // vector mit mgpsecunits
|
|
size_t pos; //position im Vector
|
|
double maxLength; //maxLength of section part
|
|
Network* pNetwork; //network the mgpoint belong to
|
|
};
|
|
|
|
/*
|
|
Value Mapping
|
|
|
|
*/
|
|
|
|
int OpMgp2mgpsecunits3ValueMap(Word* args, Word& result, int message,
|
|
Word& local, Supplier s)
|
|
{
|
|
OpMgp2mgpsec3LocalInfo* li = 0;
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
{
|
|
li = new OpMgp2mgpsec3LocalInfo();
|
|
li->maxLength = ((CcReal*) args[1].addr)->GetRealval();
|
|
Word curAddr;
|
|
qp->Open(args[0].addr);
|
|
qp->Request(args[0].addr,curAddr);
|
|
if (qp->Received(args[0].addr))
|
|
{
|
|
MGPoint *m = (MGPoint*) curAddr.addr;
|
|
li->pNetwork = m->GetNetwork();
|
|
li->vmgpsecunit.clear();
|
|
m->GetMGPSecUnits(li->vmgpsecunit, li->maxLength, li->pNetwork);
|
|
li->pos = 0;
|
|
local.addr = li;
|
|
m->DeleteIfAllowed();
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
qp->Close(args[0].addr);
|
|
delete li;
|
|
li = 0;
|
|
return CANCEL;
|
|
}
|
|
}
|
|
|
|
case REQUEST:
|
|
{
|
|
result = qp->ResultStorage(s);
|
|
if (local.addr)
|
|
li = (OpMgp2mgpsec3LocalInfo*) local.addr;
|
|
else return CANCEL;
|
|
if (!li->vmgpsecunit.empty() && li->pos < li->vmgpsecunit.size())
|
|
{
|
|
result = SetWord(new MGPSecUnit(li->vmgpsecunit[li->pos++]));
|
|
return YIELD;
|
|
}
|
|
else
|
|
{
|
|
Word curAddr;
|
|
qp->Request(args[0].addr, curAddr);
|
|
if (qp->Received(args[0].addr))
|
|
{
|
|
MGPoint *m = (MGPoint*) curAddr.addr;
|
|
li->vmgpsecunit.clear();
|
|
m->GetMGPSecUnits(li->vmgpsecunit, li->maxLength, li->pNetwork);
|
|
li->pos = 0;
|
|
m->DeleteIfAllowed();
|
|
result = SetWord (new MGPSecUnit(li->vmgpsecunit[li->pos++]));
|
|
return YIELD;
|
|
}
|
|
else
|
|
{
|
|
qp->Close(args[0].addr);
|
|
NetworkManager::CloseNetwork(li->pNetwork);
|
|
li->pNetwork = 0;
|
|
li->vmgpsecunit.clear();
|
|
delete li;
|
|
li = 0;
|
|
local.addr = 0;
|
|
return CANCEL;
|
|
}
|
|
}
|
|
}
|
|
|
|
case CLOSE:
|
|
{
|
|
qp->Close(args[0].addr);
|
|
if (local.addr)
|
|
{
|
|
li = (OpMgp2mgpsec3LocalInfo*) local.addr;
|
|
NetworkManager::CloseNetwork(li->pNetwork);
|
|
li->pNetwork = 0;
|
|
li->vmgpsecunit.clear();
|
|
delete li;
|
|
li = 0;
|
|
local.addr = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
default:
|
|
{
|
|
// should not happen
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
struct mgp2mgpsecunits3Info : OperatorInfo {
|
|
|
|
mgp2mgpsecunits3Info()
|
|
{
|
|
name = "mgp2mgpsecunits3";
|
|
signature = Symbol::STREAM() +"(" + MGPoint::BasicType() +") x " +
|
|
CcReal::BasicType() + " -> " + Symbol::STREAM() + "(" +
|
|
MGPSecUnit::BasicType() + ")";
|
|
syntax = "_ mgp2mgpsecunits3 ( _ ) ";
|
|
meaning = "Builds a stream of mgpsecunits from a stream of mgpoint.";
|
|
}
|
|
};
|
|
/*
|
|
|
|
|
|
5.1 Operator ~mpoint2mgpoint~
|
|
|
|
Translates a spatial ~MPoint~ into a network based ~MGPoint~.
|
|
|
|
*/
|
|
|
|
|
|
ListExpr OpMPoint2MGPointTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if( param.length() != 2 )
|
|
return listutils::typeError("two arguments expected");
|
|
|
|
if (!param.first().isSymbol(Network::BasicType()))
|
|
return listutils::typeError("1. argument must be " + Network::BasicType());
|
|
|
|
if (!param.second().isSymbol(MPoint::BasicType()))
|
|
return listutils::typeError("2. argument must be " + MPoint::BasicType());
|
|
|
|
return nl->SymbolAtom( MGPoint::BasicType() );
|
|
}
|
|
|
|
/*
|
|
Value mapping function of operator ~mpoint2mgpoint~
|
|
|
|
The method will first look for a segment at the start of the mpoint.
|
|
|
|
Preconditions:
|
|
- The moving point has to be exactly over the routes of the network.
|
|
- The trajectory of the mpoint must not be disjoint i.e. each unit starts
|
|
where the one before ended.
|
|
- If the mpoint changes the route at the crossing a new unit has to be started
|
|
- A change of the direction on a route is only allowed at crossings (and only
|
|
if the opposite lane can be reached at the crossing e.g. a u-turn is allowed).
|
|
|
|
*/
|
|
int OpMPoint2MGPointValueMappingNeu(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
/*
|
|
Initialize Result. Load and Check Arguments.
|
|
|
|
*/
|
|
result = qp->ResultStorage(in_xSupplier);
|
|
MGPoint* res = static_cast<MGPoint*>(result.addr);
|
|
res->Clear();
|
|
Network *pNetwork = (Network*) args[0].addr;
|
|
if (pNetwork == 0 || !pNetwork->IsDefined())
|
|
{
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
MPoint *pMPoint = (MPoint*)args[1].addr;
|
|
if (pMPoint == 0 || !pMPoint->IsDefined() || pMPoint->IsEmpty())
|
|
{
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
if (pMPoint->GetNoComponents() == 0)
|
|
{
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
/*
|
|
Use Startunit to initialize values
|
|
|
|
*/
|
|
int iNetworkId = pNetwork->GetId();
|
|
UPoint pUPoint;
|
|
int i = 0;
|
|
pMPoint->Get(i,pUPoint);
|
|
RouteInterval *ri = pNetwork->FindInterval(pUPoint.p0, pUPoint.p1);
|
|
if (ri == 0 || ri->GetRouteId() == numeric_limits<int>::max())
|
|
{
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
res->SetDefined(true);
|
|
res->StartBulkLoad();
|
|
SimpleLine pActRouteCurve = pNetwork->GetRouteCurve(ri->GetRouteId());
|
|
bool bDual = pNetwork->GetDual(ri->GetRouteId());
|
|
bool bMovingUp = true;
|
|
if (ri->GetStartPos() > ri->GetEndPos()) bMovingUp = false;
|
|
Side side = None;
|
|
if (bDual && bMovingUp) side = Up;
|
|
else
|
|
if (bDual && !bMovingUp) side = Down;
|
|
else side = None;
|
|
UGPoint aktUGPoint = UGPoint(Interval<Instant> (
|
|
pUPoint.timeInterval.start,
|
|
pUPoint.timeInterval.end,
|
|
pUPoint.timeInterval.lc,
|
|
pUPoint.timeInterval.rc),
|
|
iNetworkId,
|
|
ri->GetRouteId(),
|
|
side,
|
|
ri->GetStartPos(),
|
|
ri->GetEndPos());
|
|
RITree *riTree = 0;
|
|
if (ri->GetStartPos() < ri->GetEndPos())
|
|
riTree = new RITree(ri->GetRouteId(), ri->GetStartPos(), ri->GetEndPos());
|
|
else
|
|
riTree = new RITree(ri->GetRouteId(), ri->GetEndPos(), ri->GetStartPos());
|
|
delete ri;
|
|
ri = 0;
|
|
/*
|
|
Continue with translation of all other units.
|
|
|
|
*/
|
|
while (++i < pMPoint->GetNoComponents())
|
|
{
|
|
pMPoint->Get(i,pUPoint);
|
|
double dNewEndPos;
|
|
if (pActRouteCurve.AtPoint(pUPoint.p1, pActRouteCurve.GetStartSmaller(),
|
|
pNetwork->GetScalefactor()*0.01,dNewEndPos))
|
|
{
|
|
/*
|
|
End Found on same route like last ~ugpoint~
|
|
|
|
*/
|
|
if (((bMovingUp && aktUGPoint.GetUnitEndPos() <= dNewEndPos) ||
|
|
(!bMovingUp && aktUGPoint.GetUnitEndPos() >= dNewEndPos)) &&
|
|
(AlmostEqual(aktUGPoint.Speed(),
|
|
((fabs(aktUGPoint.GetUnitEndPos() - dNewEndPos))/
|
|
((pUPoint.timeInterval.end -
|
|
pUPoint.timeInterval.start).ToDouble()/0.00001157)))))
|
|
{
|
|
/*
|
|
0.00001157 = miliseconds to seconds. Compare meter per second.
|
|
|
|
Unit moves same direction and speed like previous units.
|
|
Extend akt ~ugpoint~ to include unit values.
|
|
|
|
*/
|
|
aktUGPoint.SetUnitEndPos(dNewEndPos);
|
|
aktUGPoint.SetUnitEndTime(pUPoint.timeInterval.end);
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
Speed changed save akt ~ugpoint~ and start new ~ugpoint~
|
|
for actual ~upoint~ values
|
|
|
|
*/
|
|
res->Add(aktUGPoint);
|
|
riTree->InsertUnit(aktUGPoint.GetUnitRid(),
|
|
aktUGPoint.GetUnitStartPos(),
|
|
aktUGPoint.GetUnitEndPos());
|
|
aktUGPoint.SetUnitStartTime(pUPoint.timeInterval.start);
|
|
aktUGPoint.SetUnitEndTime(pUPoint.timeInterval.end);
|
|
aktUGPoint.SetUnitStartPos(aktUGPoint.GetUnitEndPos());
|
|
aktUGPoint.SetUnitEndPos(dNewEndPos);
|
|
if (aktUGPoint.GetUnitStartPos() > aktUGPoint.GetUnitEndPos())
|
|
bMovingUp = false;
|
|
else bMovingUp = true;
|
|
if (bDual && bMovingUp) side = Up;
|
|
else
|
|
if(bDual && !bMovingUp) side = Down;
|
|
else side = None;
|
|
aktUGPoint.SetUnitSide(side);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
Route must have been changed. Save akt ~ugpoint~ and compute new ~ugpoint~
|
|
for actual ~upoint~ values
|
|
|
|
*/
|
|
res->Add(aktUGPoint);
|
|
riTree->InsertUnit(aktUGPoint.GetUnitRid(),
|
|
aktUGPoint.GetUnitStartPos(),
|
|
aktUGPoint.GetUnitEndPos());
|
|
//TODO:Remove simple FindInterval against adjacent section version
|
|
ri = pNetwork->FindInterval(pUPoint.p0, pUPoint.p1);
|
|
if (ri == 0 || ri->GetRouteId() == numeric_limits<int>::max())
|
|
{
|
|
/*
|
|
MPoint lost Network!
|
|
|
|
*/
|
|
Instant tstart = pUPoint.timeInterval.start;
|
|
GPoint start = aktUGPoint.p1;
|
|
while (ri == 0 && ++i < pMPoint->GetNoComponents())
|
|
{
|
|
/*
|
|
Find first unit of Mpoint back on Network.
|
|
|
|
*/
|
|
pMPoint->Get(i,pUPoint);
|
|
ri = pNetwork->FindInterval(pUPoint.p0, pUPoint.p1);
|
|
|
|
if (ri != 0)
|
|
{
|
|
/*
|
|
Calculate shortest path between last known network position and
|
|
new network position. Fill in ugpoint units for the shortest path
|
|
route intervals. For the time interval between network lost and
|
|
network found again.
|
|
|
|
*/
|
|
Instant tend = pUPoint.timeInterval.start;
|
|
Side s = None;
|
|
if (ri->GetStartPos() > ri->GetEndPos()) bMovingUp = false;
|
|
else bMovingUp = true;
|
|
if (bDual && bMovingUp) s = Up;
|
|
else
|
|
if (bDual && !bMovingUp) s = Down;
|
|
else s = None;
|
|
pActRouteCurve = pNetwork->GetRouteCurve(ri->GetRouteId());
|
|
bDual = pNetwork->GetDual(ri->GetRouteId());
|
|
GPoint end = GPoint(true, iNetworkId, ri->GetRouteId(),
|
|
ri->GetStartPos(), s);
|
|
GLine *gl = new GLine(0);
|
|
if (!start.ShortestPathAStar(&end,gl))
|
|
{
|
|
delete ri;
|
|
ri = 0;
|
|
}
|
|
else
|
|
{
|
|
for (int k = 0; k < gl->NoOfComponents(); k++)
|
|
{
|
|
RouteInterval gri;
|
|
gl->Get(k,gri);
|
|
Instant tpos =(tend - tstart) *
|
|
(fabs(gri.GetEndPos()-gri.GetStartPos())/
|
|
gl->GetLength()) +
|
|
tstart;
|
|
if (gri.GetRouteId() == end.GetRouteId() &&
|
|
gri.GetEndPos() == end.GetPosition()) tpos = tend;
|
|
Side s = None;
|
|
if (ri->GetStartPos() > ri->GetEndPos()) bMovingUp = false;
|
|
else bMovingUp = true;
|
|
if (bDual && gri.GetStartPos() <= gri.GetEndPos()) s = Up;
|
|
else
|
|
if (bDual && gri.GetStartPos() > gri.GetEndPos()) s = Down;
|
|
else s = None;
|
|
res->Add(UGPoint(Interval<Instant> (tstart, tpos, true, false),
|
|
iNetworkId,
|
|
gri.GetRouteId(),
|
|
s,
|
|
gri.GetStartPos(),
|
|
gri.GetEndPos()));
|
|
riTree->InsertUnit(gri.GetRouteId(),
|
|
gri.GetStartPos(),
|
|
gri.GetEndPos());
|
|
tstart = tpos;
|
|
}
|
|
}
|
|
gl->DeleteIfAllowed();
|
|
}
|
|
}
|
|
if (ri == 0)
|
|
{
|
|
res->EndBulkLoad(true);
|
|
riTree->TreeToDbArray(&(res->m_trajectory));
|
|
res->SetTrajectoryDefined(true);
|
|
res->m_trajectory.TrimToSize();
|
|
res->SetBoundingBox(pMPoint->BoundingBox());
|
|
riTree->RemoveTree();
|
|
return 0;
|
|
}
|
|
}
|
|
aktUGPoint.SetUnitStartTime(pUPoint.timeInterval.start);
|
|
aktUGPoint.SetUnitEndTime(pUPoint.timeInterval.end);
|
|
pActRouteCurve = pNetwork->GetRouteCurve(ri->GetRouteId());
|
|
bDual = pNetwork->GetDual(ri->GetRouteId());
|
|
aktUGPoint.SetUnitRid(ri->GetRouteId());
|
|
aktUGPoint.SetUnitStartPos(ri->GetStartPos());
|
|
aktUGPoint.SetUnitEndPos(ri->GetEndPos());
|
|
if (ri->GetStartPos() > ri->GetEndPos()) bMovingUp = false;
|
|
else bMovingUp = true;
|
|
if (bDual && bMovingUp) side = Up;
|
|
else
|
|
if (bDual && !bMovingUp) side = Down;
|
|
else side = None;
|
|
aktUGPoint.SetUnitSide(side);
|
|
delete ri;
|
|
ri = 0;
|
|
}
|
|
}
|
|
/*
|
|
Finish mgpoint computation
|
|
|
|
*/
|
|
res->Add(aktUGPoint);
|
|
riTree->InsertUnit(aktUGPoint.GetUnitRid(), aktUGPoint.GetUnitStartPos(),
|
|
aktUGPoint.GetUnitEndPos());
|
|
res->EndBulkLoad(true);
|
|
riTree->TreeToDbArray(&(res->m_trajectory));
|
|
res->SetTrajectoryDefined(true);
|
|
res->m_trajectory.TrimToSize();
|
|
res->SetBoundingBox(pMPoint->BoundingBox());
|
|
/*
|
|
Clean Memory.
|
|
|
|
*/
|
|
riTree->RemoveTree();
|
|
return 0;
|
|
}
|
|
|
|
struct mpoint2mgpointInfo:OperatorInfo{
|
|
mpoint2mgpointInfo(){
|
|
name = "mpoint2mgpoint";
|
|
signature = Network::BasicType() + " X " + MPoint::BasicType() + " -> " +
|
|
MGPoint::BasicType();
|
|
syntax = "mpoint2mgpoint(_,_)";
|
|
meaning = "Translates the mpoint into an mgpoint if possible.";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
1.2 MapMatching for not exact gps-Signals
|
|
|
|
The operation tries to map the ~mpoint~ as well as possible to the given
|
|
network. Missing route parts are approximated by shortest path search if any
|
|
connection to the network can be established for two or more positions of
|
|
he mpoint. Corresponding ugpoint units are written to the result.
|
|
|
|
*/
|
|
|
|
ListExpr OpMapMatchingTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if( param.length() != 2)
|
|
return listutils::typeError("two arguments expected");
|
|
|
|
if (!param.first().isSymbol(Network::BasicType()))
|
|
return listutils::typeError("1. argument must be " + Network::BasicType());
|
|
|
|
if (!param.second().isSymbol(MPoint::BasicType()))
|
|
return listutils::typeError("2. argument must be " + MPoint::BasicType());
|
|
|
|
return nl->SymbolAtom( MGPoint::BasicType() );
|
|
}
|
|
|
|
int OpMapMatchingValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// cout << "OpMapMatching called" << endl;
|
|
// Initialize Result. Load and Check Arguments.
|
|
result = qp->ResultStorage(in_xSupplier);
|
|
MGPoint* res = static_cast<MGPoint*>(result.addr);
|
|
res->Clear();
|
|
Network *pNetwork = (Network*) args[0].addr;
|
|
if (pNetwork == 0 || !pNetwork->IsDefined())
|
|
{
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
MPoint *pMPoint = (MPoint*)args[1].addr;
|
|
if (pMPoint == 0 || !pMPoint->IsDefined() || pMPoint->IsEmpty())
|
|
{
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
if (pMPoint->GetNoComponents() == 0)
|
|
{
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
// initialize values
|
|
res->SetDefined(true);
|
|
res->StartBulkLoad();
|
|
UGPoint* aktUGPoint = 0;
|
|
RITreeP *riTree = new RITreeP(0);
|
|
int iNetworkId = pNetwork->GetId();
|
|
UPoint pUPoint;
|
|
bool bMovingUp = true;
|
|
int i = 0;
|
|
pMPoint->Get(i,pUPoint);
|
|
GPoint* startGP = pNetwork->GetNetworkPosOfPoint(pUPoint.p0);
|
|
bool first = true;
|
|
do
|
|
{
|
|
if (!first) {
|
|
pMPoint->Get(i++,pUPoint);
|
|
}
|
|
first = false;
|
|
while ((startGP == 0 || !startGP->IsDefined()) &&
|
|
i < pMPoint->GetNoComponents()-1)
|
|
{
|
|
if (startGP != 0)
|
|
{
|
|
startGP->DeleteIfAllowed();
|
|
startGP = 0;
|
|
}
|
|
pMPoint->Get(i++,pUPoint);
|
|
startGP = pNetwork->GetNetworkPosOfPoint(pUPoint.p0);
|
|
}
|
|
if (startGP == 0 || !startGP->IsDefined())
|
|
{
|
|
cout << "no (further) start gp found in network" << endl;
|
|
startGP->DeleteIfAllowed();
|
|
if (aktUGPoint != 0)
|
|
{
|
|
res->Add(*aktUGPoint);
|
|
riTree->InsertUnit(aktUGPoint->GetStartPoint().GetRouteId(),
|
|
aktUGPoint->GetStartPoint().GetPosition(),
|
|
aktUGPoint->GetEndPoint().GetPosition());
|
|
aktUGPoint->DeleteIfAllowed();
|
|
}
|
|
res->EndBulkLoad(true);
|
|
res->SetDefined(!riTree->IsEmpty());
|
|
if (!riTree->IsEmpty())
|
|
{
|
|
riTree->TreeToDbArray(&res->m_trajectory,0);
|
|
res->SetTrajectoryDefined(true);
|
|
res->m_trajectory.TrimToSize();
|
|
res->SetBoundingBoxDefined(false);
|
|
}
|
|
riTree->Destroy();
|
|
delete riTree;
|
|
riTree=0;
|
|
return 0;
|
|
}
|
|
Instant startTime = pUPoint.timeInterval.start;
|
|
bool scl = pUPoint.timeInterval.lc;
|
|
GPoint* endGP =
|
|
pNetwork->GetNetworkPosOfPointOnRoute(pUPoint.p1,
|
|
startGP->GetRouteId());
|
|
if (endGP == 0 || !endGP->IsDefined())
|
|
endGP = pNetwork->GetNetworkPosOfPoint(pUPoint.p1);
|
|
|
|
while ((endGP == 0 || !endGP->IsDefined()) &&
|
|
i < pMPoint->GetNoComponents()-1)
|
|
{
|
|
if (endGP != 0)
|
|
{
|
|
endGP->DeleteIfAllowed();
|
|
endGP =0;
|
|
}
|
|
pMPoint->Get(i++,pUPoint);
|
|
endGP = pNetwork->GetNetworkPosOfPoint(pUPoint.p1);
|
|
}
|
|
|
|
if (endGP == 0 || !endGP->IsDefined())
|
|
{
|
|
startGP->DeleteIfAllowed();
|
|
if (endGP != 0) endGP->DeleteIfAllowed();
|
|
if (aktUGPoint != 0)
|
|
{
|
|
res->Add(*aktUGPoint);
|
|
riTree->InsertUnit(aktUGPoint->GetStartPoint().GetRouteId(),
|
|
aktUGPoint->GetStartPoint().GetPosition(),
|
|
aktUGPoint->GetEndPoint().GetPosition());
|
|
aktUGPoint->DeleteIfAllowed();
|
|
}
|
|
res->EndBulkLoad(true);
|
|
res->SetDefined(!riTree->IsEmpty());
|
|
if (!riTree->IsEmpty())
|
|
{
|
|
riTree->TreeToDbArray(&res->m_trajectory,0);
|
|
res->SetTrajectoryDefined(true);
|
|
res->m_trajectory.TrimToSize();
|
|
res->SetBoundingBoxDefined(false);
|
|
}
|
|
riTree->Destroy();
|
|
delete riTree;
|
|
riTree = 0;
|
|
return 0;
|
|
}
|
|
Instant endTime = pUPoint.timeInterval.end;
|
|
bool ecl = pUPoint.timeInterval.rc;
|
|
if (startGP->GetRouteId() == endGP->GetRouteId())
|
|
{
|
|
if (aktUGPoint == 0)
|
|
{
|
|
aktUGPoint = new UGPoint(Interval<Instant> (startTime, endTime,
|
|
scl, ecl),
|
|
*startGP, *endGP);
|
|
riTree->InsertUnit(startGP->GetRouteId(), startGP->GetPosition(),
|
|
endGP->GetPosition());
|
|
}
|
|
else
|
|
{
|
|
if (startGP->GetPosition() > endGP->GetPosition()) bMovingUp = false;
|
|
else bMovingUp = true;
|
|
if (aktUGPoint->GetStartPoint().GetRouteId() == startGP->GetRouteId())
|
|
{
|
|
if(((aktUGPoint->GetStartPoint().GetSide() == Up && bMovingUp &&
|
|
aktUGPoint->GetEndPoint().GetPosition() <= endGP->GetPosition())
|
|
||(aktUGPoint->GetStartPoint().GetSide() == Down && !bMovingUp &&
|
|
aktUGPoint->GetEndPoint().GetPosition()>=endGP->GetPosition()))
|
|
&& AlmostEqual(aktUGPoint->Speed(),
|
|
(fabs(aktUGPoint->GetEndPoint().GetPosition() -
|
|
endGP->GetPosition()))*0.00001157/
|
|
(endTime - startTime).ToDouble()))
|
|
{ // Direction and Speed almost similar extend aktugpoint
|
|
aktUGPoint->SetUnitEndPos(endGP->GetPosition());
|
|
aktUGPoint->SetUnitEndTime(endTime);
|
|
}
|
|
else
|
|
{
|
|
//speed or direction changed write aktUGPoint and initialize next
|
|
res->Add(*aktUGPoint);
|
|
riTree->InsertUnit(aktUGPoint->GetStartPoint().GetRouteId(),
|
|
aktUGPoint->GetStartPoint().GetPosition(),
|
|
aktUGPoint->GetEndPoint().GetPosition());
|
|
aktUGPoint->DeleteIfAllowed();
|
|
aktUGPoint = new UGPoint(Interval<Instant> (startTime, endTime,
|
|
scl, ecl),
|
|
*startGP, *endGP);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//changed route write aktUGPoint and initialize next one
|
|
res->Add(*aktUGPoint);
|
|
riTree->InsertUnit(aktUGPoint->GetStartPoint().GetRouteId(),
|
|
aktUGPoint->GetStartPoint().GetPosition(),
|
|
aktUGPoint->GetEndPoint().GetPosition());
|
|
aktUGPoint->DeleteIfAllowed();
|
|
aktUGPoint = new UGPoint(Interval<Instant> (startTime, endTime,
|
|
scl, ecl),
|
|
*startGP, *endGP);
|
|
}
|
|
}
|
|
*startGP = *endGP;
|
|
startTime = endTime;
|
|
scl = !ecl;
|
|
}
|
|
else
|
|
{
|
|
//write aktUGPoint if exists
|
|
if (aktUGPoint != 0)
|
|
{
|
|
res->Add(*aktUGPoint);
|
|
riTree->InsertUnit(aktUGPoint->GetStartPoint().GetRouteId(),
|
|
aktUGPoint->GetStartPoint().GetPosition(),
|
|
aktUGPoint->GetEndPoint().GetPosition());
|
|
aktUGPoint->DeleteIfAllowed();
|
|
aktUGPoint = 0;
|
|
}
|
|
// Interpolate movement between start and end by shortest path search
|
|
GLine *gl = new GLine(0);
|
|
if (!startGP->ShortestPathAStar(endGP,gl,pNetwork))
|
|
{
|
|
//failure no path found stop computation
|
|
startGP->DeleteIfAllowed();
|
|
endGP->DeleteIfAllowed();
|
|
res->EndBulkLoad(true);
|
|
res->SetDefined(!riTree->IsEmpty());
|
|
if (!riTree->IsEmpty())
|
|
{
|
|
riTree->TreeToDbArray(&res->m_trajectory,0);
|
|
res->SetTrajectoryDefined(true);
|
|
res->m_trajectory.TrimToSize();
|
|
res->SetBoundingBoxDefined(false);
|
|
}
|
|
riTree->Destroy();
|
|
delete riTree;
|
|
gl->DeleteIfAllowed();
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
RouteInterval gri;
|
|
Side s = None;
|
|
//success simulate trip over shortest path route intervals.
|
|
for (int k = 0; k < gl->NoOfComponents(); k++)
|
|
{
|
|
if (aktUGPoint != 0)
|
|
{
|
|
res->Add(*aktUGPoint);
|
|
riTree->InsertUnit(aktUGPoint->GetStartPoint().GetRouteId(),
|
|
aktUGPoint->GetStartPoint().GetPosition(),
|
|
aktUGPoint->GetEndPoint().GetPosition());
|
|
aktUGPoint->DeleteIfAllowed();
|
|
aktUGPoint = 0;
|
|
}
|
|
gl->Get(k,gri);
|
|
Instant tpos =(endTime - startTime) *
|
|
(fabs(gri.GetEndPos()-gri.GetStartPos())/
|
|
gl->GetLength()) + startTime;
|
|
if (gri.GetRouteId() == endGP->GetRouteId() &&
|
|
AlmostEqual(gri.GetEndPos(),endGP->GetPosition()))
|
|
tpos = endTime;
|
|
if (gri.GetStartPos() > gri.GetEndPos()) s = Down;
|
|
else if (gri.GetStartPos() < gri.GetEndPos()) s = Up;
|
|
else s = None;
|
|
aktUGPoint = new UGPoint(Interval<Instant> (startTime, tpos,
|
|
true, false),
|
|
iNetworkId,
|
|
gri.GetRouteId(),
|
|
s,
|
|
gri.GetStartPos(),
|
|
gri.GetEndPos());
|
|
startTime = tpos;
|
|
}
|
|
startGP->DeleteIfAllowed();
|
|
startGP = new GPoint(true, iNetworkId, gri.GetRouteId(),
|
|
gri.GetEndPos(), s);
|
|
startTime = endTime;
|
|
}
|
|
gl->DeleteIfAllowed();
|
|
}
|
|
endGP->DeleteIfAllowed();
|
|
endGP = 0;
|
|
} while (i < pMPoint->GetNoComponents()-1);
|
|
// write last unit if exists
|
|
if (aktUGPoint != 0)
|
|
{
|
|
res->Add(*aktUGPoint);
|
|
riTree->InsertUnit(aktUGPoint->GetStartPoint().GetRouteId(),
|
|
aktUGPoint->GetStartPoint().GetPosition(),
|
|
aktUGPoint->GetEndPoint().GetPosition());
|
|
aktUGPoint->DeleteIfAllowed();
|
|
aktUGPoint = 0;
|
|
}
|
|
res->EndBulkLoad(true);
|
|
res->SetDefined(!riTree->IsEmpty());
|
|
if (!riTree->IsEmpty())
|
|
{
|
|
riTree->TreeToDbArray(&res->m_trajectory,0);
|
|
res->m_trajectory.TrimToSize();
|
|
res->SetTrajectoryDefined(true);
|
|
res->SetBoundingBoxDefined(false);
|
|
}
|
|
riTree->Destroy();
|
|
delete riTree;
|
|
startGP->DeleteIfAllowed();
|
|
return 0;
|
|
}
|
|
|
|
const string OpMapMatchingSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
|
|
"\"Example\" ) "
|
|
"( <text>network X mpoint -> mgpoint </text--->"
|
|
"<text>mapmatching (network,mpoint)</text--->"
|
|
"<text>The operation tries to map the mpoint to the given network as well"
|
|
" as possible. Parts of movement, which can not be mapped directly"
|
|
" are interpolated by shortest path computing. And trip simulation.</text--->"
|
|
"<text>query mapmatching(B_NETWORK, train7)</text--->) )";
|
|
|
|
Operator mapmatching (
|
|
"mapmatching", // name
|
|
OpMapMatchingSpec, // specification
|
|
OpMapMatchingValueMapping, // value mapping
|
|
Operator::SimpleSelect,
|
|
OpMapMatchingTypeMap // type mapping
|
|
);
|
|
/*
|
|
5.2 Operator ~passes~
|
|
|
|
Returns true if a ~MGPoint~ passes a given ~GPoint~ or ~GLine~.
|
|
|
|
*/
|
|
|
|
ListExpr OpPassesTypeMap( ListExpr args )
|
|
{
|
|
NList param(args);
|
|
|
|
if ( param.length() != 2 )
|
|
return listutils::typeError("two arguments expected");
|
|
|
|
if ( !param.first().isSymbol(MGPoint::BasicType()))
|
|
return listutils::typeError("1. argument must be " + MGPoint::BasicType());
|
|
|
|
if (!(param.second().isSymbol(GPoint::BasicType()) ||
|
|
param.second().isSymbol(GLine::BasicType())))
|
|
return listutils::typeError("2. argument must be " + GPoint::BasicType() +
|
|
" or " + GLine::BasicType());
|
|
|
|
return (nl->SymbolAtom( CcBool::BasicType() ));
|
|
}
|
|
|
|
template<class Arg2>
|
|
int OpPasses(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
CcBool* pPasses = (CcBool*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pPasses);
|
|
// Get input values
|
|
MGPoint* pMGPoint = (MGPoint*)args[0].addr;
|
|
if(pMGPoint == NULL || !pMGPoint->IsDefined() ||
|
|
pMGPoint->GetNoComponents() < 1 ) {
|
|
pPasses->Set(false, false);
|
|
return 0;
|
|
}
|
|
Arg2* pArg = (Arg2*)args[1].addr;
|
|
if(pArg == NULL || !pArg->IsDefined()) {
|
|
pPasses->Set(false, false);
|
|
return 0;
|
|
}
|
|
pPasses->Set(true, pMGPoint->Passes(pArg));
|
|
return 0;
|
|
};
|
|
|
|
ValueMapping OpPassesvaluemap[] = {
|
|
OpPasses<GPoint>,
|
|
OpPasses<GLine>,
|
|
0
|
|
};
|
|
|
|
int OpPassesSelect( ListExpr args )
|
|
{
|
|
ListExpr arg2 = nl->Second( args );
|
|
|
|
if ( nl->SymbolValue(arg2) == GPoint::BasicType())
|
|
return 0;
|
|
if ( nl->SymbolValue(arg2) == GLine::BasicType())
|
|
return 1;
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
struct passesInfo:OperatorInfo{
|
|
passesInfo(){
|
|
name = "passes";
|
|
signature = MGPoint::BasicType() + " X " + GPoint::BasicType() + " -> " +
|
|
CcBool::BasicType();
|
|
appendSignature(MGPoint::BasicType() + " X " + GLine::BasicType() + " -> " +
|
|
CcBool::BasicType());
|
|
syntax = "_ passes _";
|
|
meaning = "Returns true if the mgpoint passes the given places.";
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
5.3 Operator ~simplify~
|
|
|
|
Reduces units of a ~MGPoint~ by concatenation if the speed difference is
|
|
smaller than a given value.
|
|
|
|
*/
|
|
|
|
ListExpr OpSimplifyTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if (param.length()!= 2 )
|
|
return listutils::typeError("two arguments expected");
|
|
|
|
if (!param.first().isSymbol(MGPoint::BasicType()))
|
|
return listutils::typeError("1. argument must be " + MGPoint::BasicType());
|
|
|
|
if (!param.second().isSymbol(CcReal::BasicType()))
|
|
return listutils::typeError("2. argument must be " + CcReal::BasicType());
|
|
|
|
return nl->SymbolAtom( MGPoint::BasicType() );
|
|
}
|
|
|
|
int OpSimplifyValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
MGPoint* pMGPoint = (MGPoint*)args[0].addr;
|
|
CcReal* pEpsilon = (CcReal*)args[1].addr;
|
|
double dEpsilon = pEpsilon->GetRealval();
|
|
|
|
// Get (empty) return value
|
|
MGPoint* pMGPointSimplified = (MGPoint*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pMGPointSimplified );
|
|
|
|
if(pMGPoint == NULL || !pMGPoint->IsDefined() ||
|
|
pMGPoint->GetNoComponents() == 0)
|
|
{
|
|
pMGPointSimplified->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pMGPoint->Simplify(dEpsilon, pMGPointSimplified);
|
|
return 0;
|
|
}
|
|
|
|
struct simplifyInfo:OperatorInfo{
|
|
simplifyInfo(){
|
|
name = "simplify";
|
|
signature = MGPoint::BasicType() + " X " + CcReal::BasicType() + " -> " +
|
|
MGPoint::BasicType();
|
|
syntax = "simplify(_,_)";
|
|
meaning = "Reduces the number of units by a speed deviation threshold.";
|
|
}
|
|
};
|
|
|
|
/*
|
|
5.4 Operator ~at~
|
|
|
|
Restricts the ~MGPoint~ to the times it was at a given ~GPoint~ or ~GLine~.
|
|
|
|
*/
|
|
|
|
ListExpr OpAtTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if (param.length()!= 2 )
|
|
return listutils::typeError("two arguments expected");
|
|
|
|
if (!param.first().isSymbol(MGPoint::BasicType()))
|
|
return listutils::typeError("1. argument must be " + MGPoint::BasicType());
|
|
|
|
if (!(param.second().isSymbol(GPoint::BasicType()) ||
|
|
param.second().isSymbol(GLine::BasicType())))
|
|
return listutils::typeError("2. argument must be " + GPoint::BasicType() +
|
|
" or " + GLine::BasicType());
|
|
|
|
return (nl->SymbolAtom(MGPoint::BasicType()));
|
|
}
|
|
|
|
template<class Arg2>
|
|
int OpAt(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
MGPoint* pResult = (MGPoint*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pResult);
|
|
pResult->Clear();
|
|
// Get input values
|
|
MGPoint* pMGPoint = (MGPoint*)args[0].addr;
|
|
if(pMGPoint == NULL || !pMGPoint->IsDefined() ||
|
|
pMGPoint->GetNoComponents() < 1 ) {
|
|
pResult->SetDefined(false);
|
|
return 1;
|
|
}
|
|
Arg2* pArg = (Arg2*)args[1].addr;
|
|
if(pArg == NULL || !pArg->IsDefined()) {
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pMGPoint->At(pArg, pResult);
|
|
return 0;
|
|
};
|
|
|
|
ValueMapping OpAtValueMap[] = {
|
|
OpAt<GPoint>,
|
|
OpAt<GLine>,
|
|
0
|
|
};
|
|
|
|
int OpAtSelect( ListExpr args )
|
|
{
|
|
ListExpr arg2 = nl->Second( args );
|
|
|
|
if (nl->SymbolValue(arg2) == GPoint::BasicType())
|
|
return 0;
|
|
if (nl->SymbolValue(arg2) == GLine::BasicType())
|
|
return 1;
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
struct atInfo:OperatorInfo{
|
|
atInfo(){
|
|
name = "at";
|
|
signature = MGPoint::BasicType() + " X " + GPoint::BasicType() + " -> " +
|
|
MGPoint::BasicType();
|
|
appendSignature(MGPoint::BasicType() + " X " + GLine::BasicType() + " -> " +
|
|
MGPoint::BasicType());
|
|
syntax = "_ at _";
|
|
meaning = "Restricts the mgpoint to the given places.";
|
|
}
|
|
};
|
|
|
|
/*
|
|
5.5 Operator ~atinstant~
|
|
|
|
Restricts the ~MGPoint~ to a given time instant.
|
|
|
|
*/
|
|
|
|
ListExpr OpAtinstantTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if( param.length() != 2 )
|
|
return listutils::typeError("one argument expected");
|
|
if(!param.first().isSymbol(MGPoint::BasicType()))
|
|
return listutils::typeError("1. argument must be " + MGPoint::BasicType());
|
|
if(!param.second().isSymbol(Instant::BasicType()))
|
|
return listutils::typeError("2. argument must be " + Instant::BasicType());
|
|
|
|
return (nl->SymbolAtom( IGPoint::BasicType() ));
|
|
}
|
|
|
|
int OpAtinstantValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
Intime<GPoint>* pIGPres =
|
|
(Intime<GPoint>*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pIGPres );
|
|
MGPoint* pMGP = (MGPoint*)args[0].addr;
|
|
if(pMGP == NULL ||!pMGP->IsDefined()) {
|
|
cerr << "MGPoint does not exist." << endl;
|
|
pIGPres->SetDefined(false);
|
|
return 0;
|
|
}
|
|
|
|
Instant* per = (Instant*)args[1].addr;
|
|
if(per == NULL || !per->IsDefined()) {
|
|
cerr << "Periods are not defined." << endl;
|
|
pIGPres->SetDefined(false);
|
|
return 0;
|
|
}
|
|
if (pMGP->GetNoComponents() < 1) {
|
|
pIGPres->SetDefined(true);
|
|
return 0;
|
|
}
|
|
pMGP->Atinstant(per, pIGPres);
|
|
return 0;
|
|
}
|
|
|
|
struct atinstantInfo:OperatorInfo{
|
|
atinstantInfo(){
|
|
name = "atinstant";
|
|
signature = MGPoint::BasicType() + " X " + Instant::BasicType() + " -> " +
|
|
IGPoint::BasicType();
|
|
syntax = "_ atinstant _";
|
|
meaning = "Computes the position of mgpoint at the given instant.";
|
|
}
|
|
};
|
|
|
|
/*
|
|
5.6 Operator ~atperiods~
|
|
|
|
Restricts a ~MGPoint~ to the given periods.
|
|
|
|
*/
|
|
|
|
ListExpr OpAtperiodsTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if( param.length() != 2 )
|
|
return listutils::typeError("one argument expected");
|
|
|
|
if (!param.first().isSymbol(MGPoint::BasicType()))
|
|
return listutils::typeError("1. argument must be " + MGPoint::BasicType());
|
|
if (!param.second().isSymbol(Periods::BasicType()))
|
|
return listutils::typeError("2. argument must be " + Periods::BasicType());
|
|
|
|
return (nl->SymbolAtom( MGPoint::BasicType() ));
|
|
|
|
}
|
|
|
|
int OpAtperiodsValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
MGPoint* pMGPres = (MGPoint*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pMGPres );
|
|
pMGPres->Clear();
|
|
pMGPres->SetDefined(true);
|
|
|
|
MGPoint* pMGP = (MGPoint*)args[0].addr;
|
|
if(pMGP == NULL ||!pMGP->IsDefined()) {
|
|
cerr << "MGPoint does not exist." << endl;
|
|
pMGPres->SetDefined(false);
|
|
return 0;
|
|
}
|
|
|
|
Periods* per = (Periods*)args[1].addr;
|
|
if(per == NULL || !per->IsDefined()) {
|
|
cerr << "Periods are not defined." << endl;
|
|
pMGPres->SetDefined(false);
|
|
return 0;
|
|
}
|
|
if (pMGP->GetNoComponents() < 1 || per->IsEmpty()) {
|
|
pMGPres->SetDefined(true);
|
|
return 0;
|
|
}
|
|
pMGP->Atperiods(per, pMGPres);
|
|
return 0;
|
|
}
|
|
|
|
struct atperiodsInfo:OperatorInfo{
|
|
atperiodsInfo(){
|
|
name = "atperiods";
|
|
signature = MGPoint::BasicType() + " X " + Periods::BasicType() + " -> " +
|
|
MGPoint::BasicType();
|
|
syntax = "_ atperiods _";
|
|
meaning = "Restricts the mgpoint to the given periods.";
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
5.7 Operator ~deftime~
|
|
|
|
Returns the deftime of a ~MGPoint~ respectively a ~ugpoint~ as ~periods~ value.
|
|
|
|
*/
|
|
|
|
ListExpr OpDeftimeTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if( param.length() != 1 )
|
|
return listutils::typeError("one argument expected");
|
|
|
|
if (param.first().isSymbol(MGPoint::BasicType()) ||
|
|
param.first().isSymbol(UGPoint::BasicType()))
|
|
return (nl->SymbolAtom( Periods::BasicType()));
|
|
else
|
|
return listutils::typeError(MGPoint::BasicType() + " or " +
|
|
UGPoint::BasicType() + " expected.");
|
|
}
|
|
|
|
template<class Arg>
|
|
int OpDeftime(Word* args, Word& result, int message, Word& local,
|
|
Supplier in_xSupplier) {
|
|
Periods* res = (Periods*) qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord(res);
|
|
Arg* pArg = (Arg*) args[0].addr;
|
|
if (pArg == NULL || !pArg->IsDefined()) {
|
|
res->Clear();
|
|
res->SetDefined(false);
|
|
return 1;
|
|
} else {
|
|
pArg->Deftime(*res);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int OpDeftimeSelect(ListExpr args) {
|
|
ListExpr arg = nl->First(args);
|
|
if ( nl->SymbolValue(arg) == MGPoint::BasicType())
|
|
return 0;
|
|
if ( nl->SymbolValue(arg) == UGPoint::BasicType())
|
|
return 1;
|
|
return -1; // This point should never be reached
|
|
};
|
|
|
|
ValueMapping OpDeftimeValueMapping [] = {
|
|
OpDeftime<MGPoint>,
|
|
OpDeftime<UGPoint>,
|
|
0
|
|
};
|
|
|
|
struct deftimeInfo:OperatorInfo{
|
|
deftimeInfo(){
|
|
name = "deftime";
|
|
signature = MGPoint::BasicType() + " -> " + Periods::BasicType();
|
|
appendSignature(UGPoint::BasicType() + " -> " + Periods::BasicType());
|
|
syntax = "deftime(_)";
|
|
meaning = "Returns the defintion times of the object.";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
5.8 Operator ~final~
|
|
|
|
Returns the final time and position of the ~MGPoint~ as ~IGPoint~
|
|
|
|
TypeMapping see operator ~final~.
|
|
|
|
*/
|
|
|
|
ListExpr OpFinalInitialTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if( param.length() != 1 )
|
|
return listutils::typeError("one argument expected");
|
|
|
|
if (param.first().isSymbol(MGPoint::BasicType()))
|
|
return nl->SymbolAtom( IGPoint::BasicType() );
|
|
else
|
|
return listutils::typeError(MGPoint::BasicType() + " expected.");
|
|
}
|
|
|
|
struct finalInfo:OperatorInfo{
|
|
finalInfo(){
|
|
name = "final";
|
|
signature = MGPoint::BasicType() + " -> " + IGPoint::BasicType();
|
|
syntax = "final(_)";
|
|
meaning = "Returns the final time instant and position of the mgpoint.";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
5.9 Operator ~initial~
|
|
|
|
Returns the start point and time of the ~MGPoint~ as ~IGPoint~.
|
|
|
|
*/
|
|
|
|
struct initialInfo:OperatorInfo{
|
|
initialInfo(){
|
|
name = "initial";
|
|
signature = MGPoint::BasicType() + " -> " + IGPoint::BasicType();
|
|
syntax = "initial(_)";
|
|
meaning = "Returns the start time and position of the mgpoint.";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
5.10 Operator ~inside~
|
|
|
|
Returns a ~mbool~ which is true for the times the ~MGPoint~ is inside a ~GLine~
|
|
false elsewhere.
|
|
|
|
*/
|
|
|
|
ListExpr OpInsideTypeMapping(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if ( param.length() != 2 )
|
|
return listutils::typeError("two arguments expected");
|
|
|
|
if (!param.first().isSymbol(MGPoint::BasicType()))
|
|
return listutils::typeError("1. argument must be " + MGPoint::BasicType());
|
|
|
|
if (!param.second().isSymbol(GLine::BasicType()))
|
|
return listutils::typeError("2. argument must be " + GLine::BasicType());
|
|
|
|
return (nl->SymbolAtom(MBool::BasicType()));
|
|
|
|
}
|
|
|
|
int OpInsideValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
MBool* pResult = (MBool*)
|
|
qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pResult);
|
|
pResult->Clear();
|
|
// Get input values
|
|
MGPoint* pMGPoint = (MGPoint*)args[0].addr;
|
|
if(pMGPoint == NULL || !pMGPoint->IsDefined()||
|
|
pMGPoint->GetNoComponents() < 1 ) {
|
|
cerr << "MGPoint does not exist." << endl;
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
GLine* pGLine = (GLine*)args[1].addr;
|
|
if(pGLine == NULL || !pGLine->IsDefined()) {
|
|
cerr << "GLine does not exist." << endl;
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pMGPoint->Inside(pGLine, pResult);
|
|
return 0;
|
|
};
|
|
|
|
struct insideInfo:OperatorInfo{
|
|
insideInfo(){
|
|
name = "inside";
|
|
signature = MGPoint::BasicType() + " X " + GLine::BasicType() + " -> " +
|
|
MBool::BasicType();
|
|
syntax = "_ inside _";
|
|
meaning = "True while mgpoint moves inside gline.";
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
5.11 Operator ~inst~
|
|
|
|
Returns the time instant of the ~IGPoint~
|
|
|
|
*/
|
|
|
|
ListExpr OpInstTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if( param.length() != 1 )
|
|
return listutils::typeError("one argument expected");
|
|
|
|
if (param.first().isSymbol(IGPoint::BasicType()))
|
|
return nl->SymbolAtom( Instant::BasicType() );
|
|
else
|
|
return listutils::typeError(IGPoint::BasicType()+ " expected.");
|
|
}
|
|
|
|
struct instInfo:OperatorInfo{
|
|
instInfo(){
|
|
name = "inst";
|
|
signature = IGPoint::BasicType() + " -> " + Instant::BasicType();
|
|
syntax = "inst(_)";
|
|
meaning = "Returns the time instant of the igpoint.";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
5.12 Operator ~intersection~
|
|
|
|
Computes a ~MGPoint~ representing the intersection of two ~MGPoint~.
|
|
|
|
*/
|
|
|
|
int OpIntersectionValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
MGPoint* pResult = (MGPoint*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pResult);
|
|
pResult->Clear();
|
|
// Get input values
|
|
MGPoint* pMGPoint1 = (MGPoint*)args[0].addr;
|
|
if(pMGPoint1 == NULL || !pMGPoint1->IsDefined() ||
|
|
pMGPoint1->GetNoComponents() < 1) {
|
|
cerr << "First mgpoint does not exist." << endl;
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
MGPoint* pMGPoint2 = (MGPoint*)args[1].addr;
|
|
if(pMGPoint2 == NULL || !pMGPoint2->IsDefined() ||
|
|
pMGPoint2->GetNoComponents() < 1 ) {
|
|
sendMessages("Second mgpoint does not exist.");
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pMGPoint1->Intersection(pMGPoint2, pResult);
|
|
return 0;
|
|
}
|
|
|
|
struct intersectionInfo:OperatorInfo{
|
|
intersectionInfo(){
|
|
name = "intersection";
|
|
signature = MGPoint::BasicType() + " X " + MGPoint::BasicType() +" -> " +
|
|
MGPoint::BasicType();
|
|
syntax = "intersection(_._)";
|
|
meaning = "Returns times and places mgpoints met.";
|
|
}
|
|
};
|
|
|
|
/*
|
|
5.12 Operator ~intersects~
|
|
|
|
Returns true if a intersection of the two ~MGPoint~ exists.
|
|
|
|
*/
|
|
|
|
ListExpr OpIntersectsTypeMapping(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if (param.length() != 2)
|
|
return listutils::typeError("2 arguments expected");
|
|
|
|
if (!(param.first().isSymbol(MGPoint::BasicType()) &&
|
|
param.second().isSymbol(MGPoint::BasicType())))
|
|
return listutils::typeError("Two " + MGPoint::BasicType() + " expected.");
|
|
|
|
return (nl->SymbolAtom(CcBool::BasicType()));
|
|
}
|
|
|
|
int OpIntersectsValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
CcBool* pResult = (CcBool*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pResult);
|
|
// Get input values
|
|
MGPoint* pMGPoint1 = (MGPoint*)args[0].addr;
|
|
if(pMGPoint1 == NULL || !pMGPoint1->IsDefined() ||
|
|
pMGPoint1->GetNoComponents() < 1) {
|
|
cerr << "First mgpoint does not exist." << endl;
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
MGPoint* pMGPoint2 = (MGPoint*)args[1].addr;
|
|
if(pMGPoint2 == NULL || !pMGPoint2->IsDefined() ||
|
|
pMGPoint2->GetNoComponents() < 1 ) {
|
|
sendMessages("Second mgpoint does not exist.");
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pResult->Set(true,pMGPoint1->Intersects(pMGPoint2));
|
|
return 0;
|
|
}
|
|
|
|
struct intersectsInfo:OperatorInfo{
|
|
intersectsInfo(){
|
|
name = "intersects";
|
|
signature = MGPoint::BasicType() + " X " + MGPoint::BasicType() +" -> " +
|
|
CcBool::BasicType();
|
|
syntax = "_ intersects _";
|
|
meaning = "Returns true if the mgpoint meet at any place.";
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
5.13 Operator ~isempty~
|
|
|
|
Returns true if the ~MGPoint~ has no units.
|
|
|
|
*/
|
|
|
|
ListExpr OpIsEmptyTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if( param.length() != 1)
|
|
return listutils::typeError("one argument expected");
|
|
|
|
if (param.first().isSymbol(MGPoint::BasicType()))
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
|
else
|
|
return listutils::typeError(MGPoint::BasicType() + " expected.");
|
|
}
|
|
|
|
int OpIsEmptyValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
CcBool* pEmpty = (CcBool*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pEmpty );
|
|
MGPoint* pMGP = (MGPoint*)args[0].addr;
|
|
if (pMGP == NULL ||!pMGP->IsDefined()) {
|
|
pEmpty->Set(false, false);
|
|
} else {
|
|
pEmpty->Set(true,pMGP->GetNoComponents() == 0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct isemptyInfo:OperatorInfo{
|
|
isemptyInfo(){
|
|
name = "isempty";
|
|
signature = MGPoint::BasicType() + " -> " + CcBool::BasicType();
|
|
syntax = "isempty(_)";
|
|
meaning = "Returns true if the mgpoint has no units.";
|
|
}
|
|
};
|
|
|
|
/*
|
|
5.14 Operator ~length~
|
|
|
|
Returns the length of the trip of the ~MGPoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpLengthTypeMapping(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if( param.length() != 1)
|
|
return listutils::typeError("one argument expected");
|
|
|
|
if (param.first().isSymbol(MGPoint::BasicType()) ||
|
|
param.first().isSymbol(UGPoint::BasicType()))
|
|
return nl->SymbolAtom( CcReal::BasicType() );
|
|
else
|
|
return listutils::typeError(MGPoint::BasicType() + " or " +
|
|
UGPoint::BasicType() + " expected.");
|
|
}
|
|
|
|
template<class Arg>
|
|
int OpLength(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
result = qp->ResultStorage(in_xSupplier);
|
|
CcReal* pResult = (CcReal*) result.addr;
|
|
// Get input value
|
|
Arg* pArg = (Arg*)args[0].addr;
|
|
if(pArg == NULL || !pArg->IsDefined()) {
|
|
pResult->Set(false, 0.0);
|
|
return 1;
|
|
}
|
|
pResult-> Set(true, pArg->Length());
|
|
return 0;
|
|
}
|
|
|
|
int OpLengthSelect(ListExpr args){
|
|
ListExpr arg1 = nl->First( args );
|
|
|
|
if ( nl->SymbolValue(arg1) == MGPoint::BasicType())
|
|
return 0;
|
|
if ( nl->SymbolValue(arg1) == UGPoint::BasicType())
|
|
return 1;
|
|
return -1; // This point should never be reached
|
|
};
|
|
|
|
ValueMapping OpLengthValueMap[] = {
|
|
OpLength<MGPoint>,
|
|
OpLength<UGPoint>,
|
|
0
|
|
};
|
|
|
|
struct lengthInfo:OperatorInfo{
|
|
lengthInfo(){
|
|
name = "length";
|
|
signature = MGPoint::BasicType() + " -> " + CcReal::BasicType();
|
|
appendSignature(UGPoint::BasicType() + " -> " + CcReal::BasicType());
|
|
syntax = "length(_)";
|
|
meaning = "Returns distance driven by the object.";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
5.15 Operator ~no\_components~
|
|
|
|
Returns the number of units of a ~MGPoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpNoCompTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if (param.length() != 1)
|
|
return listutils::typeError("one argument expected.");
|
|
|
|
if (param.first().isSymbol(MGPoint::BasicType()))
|
|
return nl->SymbolAtom(CcInt::BasicType());
|
|
else
|
|
return listutils::typeError(MGPoint::BasicType() + " expected.");
|
|
}
|
|
|
|
int OpNoCompValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
CcInt* pNumber = (CcInt*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pNumber );
|
|
MGPoint* pMGP = (MGPoint*)args[0].addr;
|
|
pNumber->Set(false, 0);
|
|
if(pMGP == NULL ||!pMGP->IsDefined()) {
|
|
pNumber->Set(false,0);
|
|
cerr << "MGPoint is not defined." << endl;
|
|
} else {
|
|
pNumber->Set(true, pMGP->GetNoComponents());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct noComponentsInfo:OperatorInfo{
|
|
noComponentsInfo(){
|
|
name = "no_components";
|
|
signature = MGPoint::BasicType() + " -> " + CcInt::BasicType();
|
|
syntax = "no_components(_)";
|
|
meaning = "Returns the number of units of the mgpoint.";
|
|
}
|
|
};
|
|
|
|
/*
|
|
5.16 Operator ~present~
|
|
|
|
Returns true if the ~MGPoint~ has at least almost one unit with the time instant
|
|
respectively one of the periods.
|
|
|
|
*/
|
|
|
|
ListExpr OpPresentTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if(param.length() != 2 )
|
|
return listutils::typeError("two arguments expected");
|
|
|
|
if (!param.first().isSymbol(MGPoint::BasicType()))
|
|
return listutils::typeError("1.argument must be " + MGPoint::BasicType());
|
|
|
|
if (! (param.second().isSymbol(Periods::BasicType()) ||
|
|
param.second().isSymbol(Instant::BasicType())))
|
|
return listutils::typeError("2.argument must be " + Periods::BasicType() +
|
|
" or " + Instant::BasicType());
|
|
|
|
return nl->SymbolAtom(CcBool::BasicType());
|
|
}
|
|
|
|
template<class Arg1, class Arg2>
|
|
int OpPresent(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
CcBool* pPresent = (CcBool*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pPresent);
|
|
// Get input values
|
|
Arg1* pMGPoint = (Arg1*) args[0].addr;
|
|
Arg2* pTime = (Arg2*) args[1].addr;
|
|
if (pMGPoint == NULL || pTime == NULL || !pMGPoint->IsDefined() ||
|
|
!pTime->IsDefined()){
|
|
pPresent->Set(false, false);
|
|
return 1;
|
|
}
|
|
if (pMGPoint->GetNoComponents() < 1) {
|
|
pPresent->Set(true, false);
|
|
return 0;
|
|
}
|
|
pPresent->Set(true, pMGPoint->Present(pTime));
|
|
return 0;
|
|
}
|
|
|
|
int OpPresentSelect(ListExpr args){
|
|
ListExpr arg1 = nl->First( args );
|
|
ListExpr arg2 = nl->Second( args );
|
|
|
|
if ( nl->SymbolValue(arg1) == MGPoint::BasicType() &&
|
|
nl->SymbolValue( arg2) == Periods::BasicType() )
|
|
return 0;
|
|
if ( nl->SymbolValue(arg1) == MGPoint::BasicType() &&
|
|
nl->SymbolValue( arg2) == Instant::BasicType())
|
|
return 1;
|
|
return -1; // This point should never be reached
|
|
};
|
|
|
|
ValueMapping OpPresentValueMap[] = {
|
|
OpPresent<MGPoint, Periods>,
|
|
OpPresent<MGPoint, Instant>,
|
|
0
|
|
};
|
|
|
|
struct presentInfo:OperatorInfo{
|
|
presentInfo(){
|
|
name = "present";
|
|
signature = MGPoint::BasicType() + " X " + Instant::BasicType() + " -> " +
|
|
CcBool::BasicType();
|
|
appendSignature(MGPoint::BasicType() + " X " +
|
|
Periods::BasicType() + " -> " +
|
|
CcBool::BasicType());
|
|
syntax = "_ present _";
|
|
meaning = "True if mgpoint exists in time value.";
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
5.17 Operator ~val~
|
|
|
|
Returns the ~GPoint~ value of a ~IGPoint~
|
|
|
|
*/
|
|
|
|
ListExpr OpValTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if (param.length() != 1)
|
|
return listutils::typeError("one argument expected");
|
|
|
|
if (param.first().isSymbol(IGPoint::BasicType()))
|
|
return nl->SymbolAtom(GPoint::BasicType());
|
|
else
|
|
return listutils::typeError(IGPoint::BasicType() + " expected.");
|
|
}
|
|
|
|
struct valInfo:OperatorInfo{
|
|
valInfo(){
|
|
name = "val";
|
|
signature = IGPoint::BasicType() + " -> " + GPoint::BasicType();
|
|
syntax = "val(_)";
|
|
meaning = "Returns the gpoint value of the igpoint.";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
5.18 Operator ~trajectory~
|
|
|
|
Returns the sorted ~GLine~ passed by a ~MGPoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpTrajectoryTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if (param.length() != 1)
|
|
return listutils::typeError("one argument expected");
|
|
|
|
if (param.first().isSymbol(MGPoint::BasicType()))
|
|
return nl->SymbolAtom(GLine::BasicType());
|
|
else
|
|
return listutils::typeError(MGPoint::BasicType() + " expected.");
|
|
}
|
|
|
|
int OpTrajectoryValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
GLine* pGLine = (GLine*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pGLine);
|
|
// Get input values
|
|
MGPoint* pMGPoint = (MGPoint*)args[0].addr;
|
|
if(pMGPoint == NULL || !pMGPoint->IsDefined() ||
|
|
pMGPoint->GetNoComponents() < 1) {
|
|
cerr << "MGPoint does not exist." << endl;
|
|
pGLine->SetDefined(false);
|
|
return 0;
|
|
}
|
|
|
|
GLine *res = new GLine(0);
|
|
pMGPoint->Trajectory(res);
|
|
result = SetWord(res);
|
|
qp->ChangeResultStorage(in_xSupplier, result);
|
|
pGLine->DeleteIfAllowed();
|
|
//(*pGLine) = *res;
|
|
return 0;
|
|
}
|
|
|
|
struct trajectoryInfo:OperatorInfo{
|
|
trajectoryInfo(){
|
|
name = "trajectory";
|
|
signature = MGPoint::BasicType() + " -> " + GLine::BasicType();
|
|
syntax = "trajectory(_)";
|
|
meaning = "Returns the places traversed by the mgpoint as gline.";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
5.19 Operator ~units~
|
|
|
|
Returns the stream of ~UGPoint~ from the given ~MGPoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpUnitsTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if (param.length() != 1)
|
|
return listutils::typeError("one argument expected");
|
|
|
|
if (param.first().isSymbol(MGPoint::BasicType()))
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UGPoint::BasicType()));
|
|
else
|
|
return listutils::typeError(MGPoint::BasicType() + " expected.");
|
|
|
|
|
|
}
|
|
|
|
struct unitsInfo:OperatorInfo{
|
|
unitsInfo(){
|
|
name = "units";
|
|
signature = MGPoint::BasicType() + " -> " + Symbol::STREAM() + "(" +
|
|
UGPoint::BasicType() + ")";
|
|
syntax = "units(_)";
|
|
meaning = "Builds a stream from the units of the mgpoint.";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
5.20 Operator ~unitendpos~
|
|
|
|
Returns the end position of the ~UGPoint~ as ~real~.
|
|
|
|
TypeMapping for ~unitendpos~, ~unitstartpos~, ~unitendtime~, ~unitstarttime~
|
|
and ~unitrid~.
|
|
|
|
*/
|
|
|
|
ListExpr OpUnitPosTimeTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if (param.length() != 1)
|
|
return listutils::typeError("one argument expected");
|
|
|
|
if (param.first().isSymbol(UGPoint::BasicType()))
|
|
return nl->SymbolAtom(CcReal::BasicType());
|
|
else
|
|
return listutils::typeError(UGPoint::BasicType() + " expected");
|
|
}
|
|
|
|
int OpUnitEndPosValueMapping( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ){
|
|
CcReal* pNumber = (CcReal*)qp->ResultStorage(s).addr;
|
|
result = SetWord( pNumber );
|
|
UGPoint* pUGP = (UGPoint*)args[0].addr;
|
|
pNumber->Set(false, 0.0);
|
|
if(pUGP == NULL ||!pUGP->IsDefined()) {
|
|
pNumber->Set(false,0.0);
|
|
cerr << "UGPoint is not defined." << endl;
|
|
} else {
|
|
pNumber->Set(true, pUGP->GetUnitEndPos());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct unitendposInfo:OperatorInfo{
|
|
unitendposInfo(){
|
|
name = "unitendpos";
|
|
signature = UGPoint::BasicType() + " -> " + CcReal::BasicType();
|
|
syntax = "unitendpos(_)";
|
|
meaning = "Returns the end position of the ugpoint.";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
5.21 Operator ~unitstartpos~
|
|
|
|
Returns the start position of the ~UGPoint~ as ~real~.
|
|
|
|
TypeMapping see operator ~unitendpos~
|
|
|
|
*/
|
|
|
|
int OpUnitStartPosValueMapping( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ){
|
|
CcReal* pNumber = (CcReal*)qp->ResultStorage(s).addr;
|
|
result = SetWord( pNumber );
|
|
UGPoint* pUGP = (UGPoint*)args[0].addr;
|
|
pNumber->Set(false, 0.0);
|
|
if(pUGP == NULL ||!pUGP->IsDefined()) {
|
|
pNumber->Set(false,0.0);
|
|
cerr << "UGPoint is not defined." << endl;
|
|
} else {
|
|
pNumber->Set(true, pUGP->GetUnitStartPos());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct unitstartposInfo:OperatorInfo{
|
|
unitstartposInfo(){
|
|
name = "unitstartpos";
|
|
signature = UGPoint::BasicType() + " -> " + CcReal::BasicType();
|
|
syntax = "unitstartpos(_)";
|
|
meaning = "Returns the start position of the ugpoint.";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
5.22 Operator ~unitendtime~
|
|
|
|
Returns the last time instant of the ~UGPoint~ as ~real~.
|
|
|
|
TypeMapping see operator ~unitendpos~
|
|
|
|
*/
|
|
int OpUnitEndTimeValueMapping( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ){
|
|
CcReal* pNumber = (CcReal*)qp->ResultStorage(s).addr;
|
|
result = SetWord( pNumber );
|
|
UGPoint* pUGP = (UGPoint*)args[0].addr;
|
|
pNumber->Set(false, 0.0);
|
|
if(pUGP == NULL ||!pUGP->IsDefined()) {
|
|
pNumber->Set(false,0.0);
|
|
cerr << "UGPoint is not defined." << endl;
|
|
} else {
|
|
pNumber->Set(true, (double) pUGP->GetDoubleUnitEndTime());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct unitendtimeInfo:OperatorInfo{
|
|
unitendtimeInfo(){
|
|
name = "unitendtime";
|
|
signature = UGPoint::BasicType() + " -> " + CcReal::BasicType();
|
|
syntax = "unitendtime(_)";
|
|
meaning = "Returns double value of end time instant of ugpoint.";
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
5.23 Operator ~unitstarttime~
|
|
|
|
Returns the starting time instant of the ~UGPoint~ as ~real~.
|
|
|
|
TypeMapping see operator ~unitendpos~
|
|
|
|
*/
|
|
|
|
int OpUnitStartTimeValueMapping( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ){
|
|
CcReal* pNumber = (CcReal*)qp->ResultStorage(s).addr;
|
|
result = SetWord( pNumber );
|
|
UGPoint* pUGP = (UGPoint*)args[0].addr;
|
|
pNumber->Set(false, 0.0);
|
|
if(pUGP == NULL ||!pUGP->IsDefined()) {
|
|
pNumber->Set(false,0.0);
|
|
cerr << "UGPoint is not defined." << endl;
|
|
} else {
|
|
pNumber->Set(true, (double) pUGP->GetDoubleUnitStartTime());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct unitstarttimeInfo:OperatorInfo{
|
|
unitstarttimeInfo(){
|
|
name = "unitstarttime";
|
|
signature = UGPoint::BasicType() + " -> " + CcReal::BasicType();
|
|
syntax = "unitstarttime(_)";
|
|
meaning = "Returns the double value of the start time instant.";
|
|
}
|
|
};
|
|
|
|
/*
|
|
5.24 Operator ~unitrid~
|
|
|
|
Returns the route id of the ~UGPoint~ as ~real~.
|
|
|
|
TypeMapping see operator ~unitendpos~
|
|
|
|
*/
|
|
|
|
int OpUnitRidValueMapping( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ){
|
|
CcReal* pNumber = (CcReal*)qp->ResultStorage(s).addr;
|
|
result = SetWord( pNumber );
|
|
UGPoint* pUGP = (UGPoint*)args[0].addr;
|
|
pNumber->Set(false, 0.0);
|
|
if(pUGP == NULL ||!pUGP->IsDefined()) {
|
|
pNumber->Set(false,0.0);
|
|
cerr << "UGPoint is not defined." << endl;
|
|
} else {
|
|
pNumber->Set(true, (double) pUGP->GetUnitRid());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct unitridInfo:OperatorInfo{
|
|
unitridInfo(){
|
|
name = "unitrid";
|
|
signature = UGPoint::BasicType() + " -> " + CcReal::BasicType();
|
|
syntax = "unitrid(_)";
|
|
meaning = "Returns the route id of ugpoint as real value.";
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
5.25 Operator ~unitbox~
|
|
|
|
Returns the bounding box of the ~ugpoint~ as rectangle of dimension 3. with
|
|
rid, rid, min(p0.pos. p1.pos), max(p0.pos, p1.pos), timeInterval.start,
|
|
timeInterval.end.
|
|
|
|
*/
|
|
|
|
int OpUnitBoxValueMapping( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ){
|
|
result = qp->ResultStorage( s );
|
|
Rectangle<3>* box = static_cast<Rectangle<3>* >(result.addr);
|
|
UGPoint* arg = static_cast<UGPoint*>(args[0].addr);
|
|
if(arg == NULL || !arg->IsDefined()) box->SetDefined(false);
|
|
else (*box) = arg->NetBoundingBox3d();
|
|
return 0;
|
|
}
|
|
|
|
struct unitboxInfo:OperatorInfo{
|
|
unitboxInfo(){
|
|
name = "unitbox";
|
|
signature = UGPoint::BasicType() + " -> " + Rectangle<3>::BasicType();
|
|
syntax = "unitbox(_)";
|
|
meaning = "Returns the temporal netbox of ugpoint.";
|
|
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
5.26 Operator ~unitbox~
|
|
|
|
Returns the bounding box of the ~ugpoint~ as rectangle of dimension 2. with
|
|
rid, rid, min(p0.pos. p1.pos), max(p0.pos, p1.pos).
|
|
|
|
*/
|
|
|
|
ListExpr OpUnitBox2TypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if (param.length() != 1)
|
|
return listutils::typeError("one argument expected");
|
|
|
|
if (param.first().isSymbol(UGPoint::BasicType()))
|
|
return nl->SymbolAtom( Rectangle<2>::BasicType() );
|
|
else
|
|
return listutils::typeError(UGPoint::BasicType() + " expected.");
|
|
}
|
|
|
|
int OpUnitBox2ValueMapping( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ){
|
|
|
|
result = qp->ResultStorage( s );
|
|
Rectangle<2>* box = static_cast<Rectangle<2>* >(result.addr);
|
|
UGPoint* arg = static_cast<UGPoint*>(args[0].addr);
|
|
if(arg == NULL || !arg->IsDefined()){
|
|
box->SetDefined(false);
|
|
} else {
|
|
(*box) = arg->NetBoundingBox2d();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct unitbox2Info:OperatorInfo{
|
|
unitbox2Info(){
|
|
name = "unitbox2";
|
|
signature = UGPoint::BasicType() + " -> " + Rectangle<2>::BasicType();
|
|
syntax = "unitbox2(_)";
|
|
meaning = "Returns netbox (<rid><rid><min(start,end)><max(start,end)>)";
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
5.27 Operator ~unitboundingbox~
|
|
|
|
Returns the spatialtemporal bounding box of the ~ugpoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpUnitBoundingBoxTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if (param.length() != 1)
|
|
return listutils::typeError("one argument expected");
|
|
|
|
if (param.first().isSymbol(UGPoint::BasicType()))
|
|
return nl->SymbolAtom( Rectangle<3>::BasicType() );
|
|
else
|
|
return listutils::typeError(UGPoint::BasicType() + " expected");
|
|
}
|
|
|
|
int OpUnitBoundingBoxValueMapping( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ){
|
|
|
|
result = qp->ResultStorage( s );
|
|
Rectangle<3>* box = static_cast<Rectangle<3>* >(result.addr);
|
|
UGPoint* arg = static_cast<UGPoint*>(args[0].addr);
|
|
if(arg == NULL || !arg->IsDefined()){
|
|
box->SetDefined(false);
|
|
} else {
|
|
(*box) = arg->BoundingBox();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct unitboundingboxInfo:OperatorInfo{
|
|
unitboundingboxInfo(){
|
|
name = "unitboundingbox";
|
|
signature = UGPoint::BasicType() + " -> " + Rectangle<3>::BasicType();
|
|
syntax = "unitboundingbox(_)";
|
|
meaning = "Returns the spatio-temporal bounding box of the ugpoint.";
|
|
}
|
|
};
|
|
|
|
/*
|
|
5.28 Operator ~mgpointboundingbox~
|
|
|
|
Returns the spatialtemporal bounding box of the ~ugpoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpMGPointBoundingBoxTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if (param.length() != 1)
|
|
return listutils::typeError("one argument expected");
|
|
|
|
if (param.first().isSymbol(MGPoint::BasicType()))
|
|
return nl->SymbolAtom( Rectangle<3>::BasicType() );
|
|
else
|
|
return listutils::typeError(MGPoint::BasicType() + " expected.");
|
|
}
|
|
|
|
int OpMGPointBoundingBoxValueMapping( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ){
|
|
|
|
result = qp->ResultStorage( s );
|
|
Rectangle<3>* box = static_cast<Rectangle<3>* >(result.addr);
|
|
MGPoint* arg = static_cast<MGPoint*>(args[0].addr);
|
|
if(arg == NULL || !arg->IsDefined() || arg->GetNoComponents()<1){
|
|
box->SetDefined(false);
|
|
} else {
|
|
*box = arg->BoundingBox();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct mgpbboxInfo:OperatorInfo{
|
|
mgpbboxInfo(){
|
|
name = "mgpbbox";
|
|
signature = MGPoint::BasicType() + " -> " + Rectangle<3>::BasicType();
|
|
syntax = "mgpbbox(_)";
|
|
meaning = "Returns the spatio-temporal bounding box of the mgpoint.";
|
|
}
|
|
};
|
|
|
|
/*
|
|
5.29 Operator ~mgpoint2mpoint~
|
|
|
|
Returns the ~mpoint~ value of the given ~MGPoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpMGPoint2MPointTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if (param.length() != 1)
|
|
return listutils::typeError("one argument expected");
|
|
|
|
if (param.first().isSymbol(MGPoint::BasicType()))
|
|
return nl->SymbolAtom( MPoint::BasicType() );
|
|
else
|
|
return listutils::typeError(MGPoint::BasicType() + " expected.");
|
|
}
|
|
|
|
int OpMGPoint2MPointValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
MPoint* pMPoint = (MPoint*) qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord(pMPoint);
|
|
pMPoint->SetDefined(true);
|
|
MGPoint* pMGPoint = (MGPoint*)args[0].addr;
|
|
if (pMGPoint == NULL || !pMGPoint->IsDefined()) {
|
|
sendMessages("MGPoint must be defined!");
|
|
pMPoint->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pMGPoint->Mgpoint2mpoint(pMPoint);
|
|
return 0;
|
|
}
|
|
|
|
struct mgpoint2mpointInfo:OperatorInfo{
|
|
mgpoint2mpointInfo(){
|
|
name = "mgpoint2mpoint";
|
|
signature = MGPoint::BasicType() + " -> " + MPoint::BasicType();
|
|
syntax = "mgpoint2mpoint(_)";
|
|
meaning = "Translates the mgpoint into an mpoint value.";
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
5.30 Operator ~distance~
|
|
|
|
Computes a mreal representing the Euclidean Distance between the two ~mgpoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpDistanceTypeMapping(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if (param.length() != 2)
|
|
return listutils::typeError("2 arguments expected");
|
|
|
|
if (!(param.first().isSymbol(MGPoint::BasicType()) &&
|
|
param.second().isSymbol(MGPoint::BasicType())))
|
|
return listutils::typeError("Two " + MGPoint::BasicType() + " expected.");
|
|
|
|
return (nl->SymbolAtom(MReal::BasicType()));
|
|
}
|
|
|
|
int OpDistanceValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
MReal* pResult = (MReal*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pResult);
|
|
// pResult->Clear();
|
|
// pResult->SetDefined(true);
|
|
// Get input values
|
|
MGPoint* pMGPoint1 = (MGPoint*)args[0].addr;
|
|
if(pMGPoint1 == NULL || !pMGPoint1->IsDefined() ||
|
|
pMGPoint1->GetNoComponents() < 1) {
|
|
cerr << "First mgpoint does not exist." << endl;
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
MGPoint* pMGPoint2 = (MGPoint*)args[1].addr;
|
|
if(pMGPoint2 == NULL || !pMGPoint2->IsDefined() ||
|
|
pMGPoint2->GetNoComponents() < 1 ) {
|
|
sendMessages("Second mgpoint does not exist.");
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
if(pMGPoint1->GetNetworkId() != pMGPoint2->GetNetworkId()) {
|
|
sendMessages("MGPoints must belong to the same network.");
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pMGPoint1->Distance(pMGPoint2, pResult);
|
|
// pMGPoint1->DistanceE(pMGPoint2, pResult);
|
|
// pMGPoint1->DistanceN(pMGPoint2, pResult);
|
|
return 0;
|
|
}
|
|
|
|
struct distanceInfo:OperatorInfo{
|
|
distanceInfo(){
|
|
name = "distance";
|
|
signature = MGPoint::BasicType() + " X " + MGPoint::BasicType() + " -> " +
|
|
MReal::BasicType();
|
|
syntax = "distance(_,_)";
|
|
meaning = "Returns the Euclidean Distance between the two objects.";
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
5.31 Operator ~union~
|
|
|
|
Returns a ~MGPoint~ which is the ~union~ of the two given MGPoints if possible,
|
|
undefined elsewhere.
|
|
|
|
*/
|
|
|
|
|
|
ListExpr OpUnionTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
|
|
if (param.length() != 2)
|
|
return listutils::typeError("2 arguments expected");
|
|
|
|
if (!(param.first().isSymbol(MGPoint::BasicType()) &&
|
|
param.second().isSymbol(MGPoint::BasicType())))
|
|
return listutils::typeError("Two " + MGPoint::BasicType() + " expected.");
|
|
|
|
return (nl->SymbolAtom(MGPoint::BasicType()));
|
|
}
|
|
|
|
int OpUnionValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
MGPoint* pResult = (MGPoint*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pResult);
|
|
pResult->Clear();
|
|
// Get input values
|
|
MGPoint *pMGP1 = (MGPoint*)args[0].addr;
|
|
if(pMGP1 == NULL) {
|
|
cerr << "MGPoint1 not Defined" << endl;
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
MGPoint *pMGP2 = (MGPoint*)args[1].addr;
|
|
if(pMGP2 == NULL) {
|
|
cerr << "MGPoint2 not Defined" << endl;
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pMGP1->Union(pMGP2, pResult);
|
|
return 0;
|
|
};
|
|
|
|
struct unionInfo:OperatorInfo{
|
|
unionInfo(){
|
|
name = "union";
|
|
signature = MGPoint::BasicType() +" X " + MGPoint::BasicType()+ " -> " +
|
|
MGPoint::BasicType();
|
|
syntax = "_ union _";
|
|
meaning = "Create the union of the two mgpoint if possible.";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
5.32 Operator ~endunitinst~
|
|
|
|
Returns the end time instant of a ~UGPoint~ as ~Instant~
|
|
|
|
*/
|
|
|
|
ListExpr OpEndStartunitinstTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
if( param.length() != 1 )
|
|
return listutils::typeError("One argument expected.");
|
|
|
|
if (!param.first().isSymbol(UGPoint::BasicType()))
|
|
return listutils::typeError(UGPoint::BasicType() + " expected.");
|
|
|
|
return nl->SymbolAtom(Instant::BasicType());
|
|
}
|
|
|
|
int OpEndunitinstValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
Instant* pResult = (Instant*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pResult);
|
|
// Get input values
|
|
UGPoint *pUGP = (UGPoint*)args[0].addr;
|
|
if(pUGP == NULL || !pUGP->IsDefined()) {
|
|
cerr << "UGPoint not Defined" << endl;
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
*pResult = pUGP->timeInterval.end;
|
|
return 0;
|
|
};
|
|
|
|
struct endunitinstInfo:OperatorInfo{
|
|
endunitinstInfo(){
|
|
name = "endunitinst";
|
|
signature = UGPoint::BasicType() + " -> " + Instant::BasicType();
|
|
syntax = "endunitinst(_)";
|
|
meaning = "Returns the final time instant form the ugpoint.";
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
5.33 Operator ~startunitinst~
|
|
|
|
Returns the start time of the ~UGPoint~ as ~Instant~.
|
|
|
|
TypeMapping see 5.32 ~OpEndStartunitinstTypeMap~
|
|
|
|
*/
|
|
|
|
int OpStartunitinstValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
Instant* pResult = (Instant*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pResult);
|
|
// Get input values
|
|
UGPoint *pUGP = (UGPoint*)args[0].addr;
|
|
if(pUGP == NULL || !pUGP->IsDefined()) {
|
|
cerr << "UGPoint not Defined" << endl;
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
*pResult = pUGP->timeInterval.start;
|
|
return 0;
|
|
};
|
|
|
|
struct startunitinstInfo:OperatorInfo{
|
|
startunitinstInfo(){
|
|
name = "startunitinst";
|
|
signature = UGPoint::BasicType() + " -> " + Instant::BasicType();
|
|
syntax = "startunitinst(_)";
|
|
meaning = "Returns the start time instant of the ugpoint.";
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
5.34 Operator ~ugpoint2mgpoint~
|
|
|
|
Builds a ~MGPoint~ from a single ~UGPoint~
|
|
|
|
*/
|
|
|
|
ListExpr OpUgpoint2mgpointTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList param(in_xArgs);
|
|
if( param.length() != 1 )
|
|
return listutils::typeError("One argument expected.");
|
|
|
|
if (!param.first().isSymbol(UGPoint::BasicType()))
|
|
return listutils::typeError(UGPoint::BasicType() + " expected.");
|
|
|
|
return nl->SymbolAtom(MGPoint::BasicType());
|
|
}
|
|
|
|
int OpUgpoint2mgpointValueMapping(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
MGPoint* pResult = (MGPoint*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pResult);
|
|
// Get input values
|
|
UGPoint *pUGP = (UGPoint*)args[0].addr;
|
|
if(pUGP == NULL || !pUGP->IsDefined()) {
|
|
cerr << "UGPoint not Defined" << endl;
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pResult->Clear();
|
|
pResult->StartBulkLoad();
|
|
pResult->Add(*pUGP);
|
|
pResult->EndBulkLoad();
|
|
pResult->SetTrajectoryDefined(false);
|
|
pResult->m_trajectory.TrimToSize();
|
|
pResult->SetBoundingBoxDefined(false);
|
|
return 0;
|
|
};
|
|
|
|
struct ugpoint2mgpointInfo:OperatorInfo{
|
|
ugpoint2mgpointInfo(){
|
|
name = "ugpoint2mgpoint";
|
|
signature = UGPoint::BasicType() + " -> " + MGPoint::BasicType();
|
|
syntax = "ugpoint2mgpoint(_)";
|
|
meaning = "Transfers the ugpoint to an mgpoint with a single unit.";
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
5.35 ~mgpsu2tuple~
|
|
|
|
The operation ~mgpsu2tuple~ gets a ~stream~ of ~mgpsecunits~ and translates
|
|
them into a stream of tuples with the mgpsecunit values as attributes.
|
|
|
|
TypeMapping:
|
|
|
|
*/
|
|
static string mgpSecTypeInfo =
|
|
"(stream (tuple ((Secid int) (Part int) (Dir int) (Speed real)"
|
|
"(Starttime instant)(Endtime instant)"
|
|
"(Leftclosed bool)(Rightclosed bool))))";
|
|
|
|
|
|
ListExpr OpMgpsu2tupleTypeMap(ListExpr in_xArgs)
|
|
{
|
|
NList type(in_xArgs);
|
|
if (type.length() == 1)
|
|
{
|
|
NList stream = type.first();
|
|
NList mgp(MGPSecUnit::BasicType());
|
|
if (stream.length() == 2 && stream.checkStream(mgp))
|
|
{
|
|
ListExpr retList;
|
|
nl->ReadFromString(mgpSecTypeInfo, retList);
|
|
return retList;
|
|
}
|
|
}
|
|
return NList::typeError( "Expected a " + Symbol::STREAM() + " of " +
|
|
MGPSecUnit::BasicType() + ".");
|
|
}
|
|
|
|
/*
|
|
Value Mapping
|
|
|
|
*/
|
|
|
|
int OpMgpsu2tupleValueMap(Word* args, Word& result, int message,
|
|
Word& local, Supplier s)
|
|
{
|
|
TupleType *resultTupleType;
|
|
ListExpr resultType;
|
|
Word curAddr;
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
{
|
|
qp->Open(args[0].addr);
|
|
resultType = GetTupleResultType( s );
|
|
resultTupleType = new TupleType( nl->Second( resultType ) );
|
|
local.setAddr( resultTupleType );
|
|
return 0;
|
|
}
|
|
|
|
case REQUEST:
|
|
{
|
|
resultTupleType = (TupleType *)local.addr;
|
|
qp->Request(args[0].addr, curAddr);
|
|
if (qp->Received(args[0].addr))
|
|
{
|
|
MGPSecUnit *m = (MGPSecUnit*) curAddr.addr;
|
|
if (m != NULL && m->IsDefined()){
|
|
Tuple *newTuple = new Tuple( resultTupleType );
|
|
newTuple->PutAttribute(0, new CcInt(true, m->GetSecId()));
|
|
newTuple->PutAttribute(1, new CcInt(true, m->GetPart()));
|
|
newTuple->PutAttribute(2, new CcInt(true, m->GetDirect()));
|
|
newTuple->PutAttribute(3, new CcReal(true, m->GetSpeed()));
|
|
newTuple->PutAttribute(4, new Instant(m->GetTimeInterval().start));
|
|
newTuple->PutAttribute(5, new Instant(m->GetTimeInterval().end));
|
|
newTuple->PutAttribute(6, new CcBool(true,m->GetTimeInterval().lc));
|
|
newTuple->PutAttribute(7, new CcBool(true,m->GetTimeInterval().rc));
|
|
result.setAddr(newTuple);
|
|
m->DeleteIfAllowed();
|
|
return YIELD;
|
|
}
|
|
}
|
|
else return CANCEL;
|
|
}
|
|
|
|
case CLOSE:
|
|
{
|
|
qp->Close(args[0].addr);
|
|
if (local.addr) ((TupleType*) local.addr)->DeleteIfAllowed();
|
|
local.setAddr(0);
|
|
return 0;
|
|
}
|
|
default:
|
|
{
|
|
// should not happen
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
struct mgpsu2tupleInfo : OperatorInfo {
|
|
|
|
mgpsu2tupleInfo()
|
|
{
|
|
name = "mgpsu2tuple";
|
|
signature = Symbol::STREAM() + "("+ MGPSecUnit::BasicType() + ") -> " +
|
|
mgpSecTypeInfo;
|
|
syntax = "_ mgpsu2tuple ( _ ) ";
|
|
meaning = "Transforms stream of mgpsecunits to tuplestream.";
|
|
}
|
|
};
|
|
|
|
/*
|
|
5.36 ~netdistance~
|
|
Computes the shortest path in the network from first to second argument.
|
|
|
|
*/
|
|
|
|
ListExpr OpNetdistanceTypeMap( ListExpr args )
|
|
{
|
|
NList param(args);
|
|
if (param.length() != 2)
|
|
{
|
|
return listutils::typeError("netdistance expects 2 arguments.");
|
|
}
|
|
NList firstArg(param.first());
|
|
NList secondArg(param.second());
|
|
|
|
if (!(firstArg.isSymbol(GPoint::BasicType()) ||
|
|
firstArg.isSymbol(UGPoint::BasicType()) ||
|
|
firstArg.isSymbol(MGPoint::BasicType())))
|
|
return
|
|
listutils::typeError("1.argument must be gpoint, ugpoint or mgpoint.");
|
|
|
|
if (!(secondArg.isSymbol(GPoint::BasicType()) ||
|
|
secondArg.isSymbol(UGPoint::BasicType()) ||
|
|
secondArg.isSymbol(MGPoint::BasicType())))
|
|
return
|
|
listutils::typeError("2.argument must be gpoint,ugpoint or mgpoint.");
|
|
|
|
if ((firstArg.isSymbol(GPoint::BasicType()) &&
|
|
secondArg.isSymbol(MGPoint::BasicType())) ||
|
|
(firstArg.isSymbol(MGPoint::BasicType()) &&
|
|
secondArg.isSymbol(GPoint::BasicType())))
|
|
return nl->SymbolAtom(MReal::BasicType());
|
|
|
|
if (firstArg.isSymbol(MGPoint::BasicType()) ||
|
|
secondArg.isSymbol(MGPoint::BasicType()))
|
|
return
|
|
listutils::typeError("Netdistance" + MGPoint::BasicType() + " only " +
|
|
"defined for " + GPoint::BasicType() + " yet.");
|
|
|
|
if (firstArg == secondArg && firstArg.isSymbol(GPoint::BasicType()))
|
|
return
|
|
listutils::typeError(GPoint::BasicType() + " x " +
|
|
GPoint::BasicType() + " is not covered here.");
|
|
|
|
return nl->SymbolAtom ( UReal::BasicType() );
|
|
}
|
|
|
|
template<class FixPos, class MovPos, class RetValue>
|
|
int OpNetdistanceFixMov(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
RetValue* pDistance = (RetValue*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pDistance);
|
|
// Get input values
|
|
FixPos* pFrom = (FixPos*)args[0].addr;
|
|
MovPos* pTo = (MovPos*)args[1].addr;
|
|
if(pFrom == NULL || !pFrom->IsDefined() ||
|
|
pTo == NULL || !pTo->IsDefined())
|
|
{
|
|
cerr << "Both arguments must be well defined" << endl;
|
|
pDistance->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pTo->NetdistanceFromArg(pFrom, pDistance);
|
|
return 0;
|
|
};
|
|
|
|
template<class MovPos, class FixPos, class RetValue>
|
|
int OpNetdistanceMovFix(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
RetValue* pDistance = (RetValue*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pDistance);
|
|
// Get input values
|
|
MovPos* pFrom = (MovPos*)args[0].addr;
|
|
FixPos* pTo = (FixPos*)args[1].addr;
|
|
if(pFrom == NULL || !pFrom->IsDefined() ||
|
|
pTo == NULL || !pTo->IsDefined())
|
|
{
|
|
cerr << "Both arguments must be well defined" << endl;
|
|
pDistance->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pFrom->NetdistanceToArg(pTo, pDistance);
|
|
return 0;
|
|
};
|
|
|
|
template<class MovPos1, class MovPos2, class RetValue>
|
|
int OpNetdistanceMovMov(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
RetValue* pDistance = (RetValue*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pDistance);
|
|
// Get input values
|
|
MovPos1* pFrom = (MovPos1*)args[0].addr;
|
|
MovPos2* pTo = (MovPos2*)args[1].addr;
|
|
if(pFrom == NULL || !pFrom->IsDefined() ||
|
|
pTo == NULL || !pTo->IsDefined())
|
|
{
|
|
cerr << "Both arguments must be well defined" << endl;
|
|
pDistance->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pFrom->Netdistance(pTo, pDistance);
|
|
return 0;
|
|
};
|
|
|
|
|
|
ValueMapping OpNetdistanceValueMap[] = {
|
|
OpNetdistanceFixMov<GPoint, UGPoint, UReal>,
|
|
OpNetdistanceMovFix<UGPoint, GPoint, UReal>,
|
|
OpNetdistanceMovMov<UGPoint, UGPoint, UReal>,
|
|
OpNetdistanceFixMov<GPoint, MGPoint, MReal>,
|
|
OpNetdistanceMovFix<MGPoint, GPoint, MReal>
|
|
};
|
|
|
|
int OpNetdistanceSelect( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
ListExpr arg2 = nl->Second( args );
|
|
|
|
if ( nl->SymbolValue(arg1) == GPoint::BasicType() &&
|
|
nl->SymbolValue(arg2) == UGPoint::BasicType())
|
|
return 0;
|
|
if ( nl->SymbolValue(arg1) == UGPoint::BasicType() &&
|
|
nl->SymbolValue(arg2) == GPoint::BasicType())
|
|
return 1;
|
|
if (nl->SymbolValue(arg1) == UGPoint::BasicType() &&
|
|
nl->SymbolValue(arg2) == UGPoint::BasicType())
|
|
return 2;
|
|
if (nl->SymbolValue(arg1) == GPoint::BasicType() &&
|
|
nl->SymbolValue(arg2) == MGPoint::BasicType())
|
|
return 3;
|
|
if (nl->SymbolValue(arg1) == MGPoint::BasicType() &&
|
|
nl->SymbolValue(arg2) == GPoint::BasicType())
|
|
return 4;
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
struct NetdistanceInfo:OperatorInfo{
|
|
NetdistanceInfo(){
|
|
name = "netdistance";
|
|
signature = GPoint::BasicType() + " X " +
|
|
UGPoint::BasicType() + " -> " +
|
|
UReal::BasicType();
|
|
appendSignature(UGPoint::BasicType() + " X " +
|
|
GPoint::BasicType() + " -> " +
|
|
UReal::BasicType());
|
|
appendSignature(UGPoint::BasicType() + " X " +
|
|
UGPoint::BasicType() + " -> " +
|
|
UReal::BasicType());
|
|
appendSignature(GPoint::BasicType() + " X " +
|
|
MGPoint::BasicType() + " -> " +
|
|
MReal::BasicType());
|
|
appendSignature(MGPoint::BasicType() + " X " +
|
|
GPoint::BasicType() + " -> " +
|
|
MReal::BasicType());
|
|
syntax = "netdistance(_,_)";
|
|
meaning = "Computes the netdistance from 1.to 2. argument";
|
|
}
|
|
};
|
|
|
|
/*
|
|
|
|
5.36 ~netdistancenew~
|
|
|
|
Computes the shortest path in the network from first to second argument.
|
|
Reduces shortest path tree computation to the necessary sections.
|
|
|
|
*/
|
|
|
|
ListExpr OpNetdistanceNewTypeMap( ListExpr args )
|
|
{
|
|
NList param(args);
|
|
if (param.length() != 2)
|
|
{
|
|
return listutils::typeError("netdistance expects 2 arguments.");
|
|
}
|
|
NList firstArg(param.first());
|
|
NList secondArg(param.second());
|
|
|
|
if (!(firstArg.isSymbol(GPoint::BasicType()) ||
|
|
firstArg.isSymbol(MGPoint::BasicType())))
|
|
return
|
|
listutils::typeError("1.argument must be gpoint or mgpoint.");
|
|
|
|
if (!(secondArg.isSymbol(GPoint::BasicType()) ||
|
|
secondArg.isSymbol(MGPoint::BasicType())))
|
|
return
|
|
listutils::typeError("2.argument must be gpoint or mgpoint.");
|
|
|
|
if ((firstArg.isSymbol(GPoint::BasicType()) &&
|
|
secondArg.isSymbol(MGPoint::BasicType())) ||
|
|
(firstArg.isSymbol(MGPoint::BasicType()) &&
|
|
secondArg.isSymbol(GPoint::BasicType())))
|
|
return nl->SymbolAtom(MReal::BasicType());
|
|
else
|
|
return
|
|
listutils::typeError("1. and 2. argument must be different.");
|
|
}
|
|
|
|
template<class FixPos, class MovPos, class RetValue>
|
|
int OpNetdistanceNewFixMov(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
RetValue* pDistance = (RetValue*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pDistance);
|
|
// Get input values
|
|
FixPos* pFrom = (FixPos*)args[0].addr;
|
|
MovPos* pTo = (MovPos*)args[1].addr;
|
|
if(pFrom == NULL || !pFrom->IsDefined() ||
|
|
pTo == NULL || !pTo->IsDefined())
|
|
{
|
|
cerr << "Both arguments must be well defined" << endl;
|
|
pDistance->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pTo->NetdistanceFromArgShort(pFrom, pDistance);
|
|
return 0;
|
|
};
|
|
|
|
template<class MovPos, class FixPos, class RetValue>
|
|
int OpNetdistanceNewMovFix(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
// Get (empty) return value
|
|
RetValue* pDistance = (RetValue*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pDistance);
|
|
// Get input values
|
|
MovPos* pFrom = (MovPos*)args[0].addr;
|
|
FixPos* pTo = (FixPos*)args[1].addr;
|
|
if(pFrom == NULL || !pFrom->IsDefined() ||
|
|
pTo == NULL || !pTo->IsDefined())
|
|
{
|
|
cerr << "Both arguments must be well defined" << endl;
|
|
pDistance->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pFrom->NetdistanceToArgShort(pTo, pDistance);
|
|
return 0;
|
|
};
|
|
|
|
ValueMapping OpNetdistanceNewValueMap[] = {
|
|
OpNetdistanceNewFixMov<GPoint, MGPoint, MReal>,
|
|
OpNetdistanceNewMovFix<MGPoint, GPoint, MReal>
|
|
};
|
|
|
|
int OpNetdistanceNewSelect( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
ListExpr arg2 = nl->Second( args );
|
|
if (nl->SymbolValue(arg1) == GPoint::BasicType() &&
|
|
nl->SymbolValue(arg2) == MGPoint::BasicType())
|
|
return 0;
|
|
if (nl->SymbolValue(arg1) == MGPoint::BasicType() &&
|
|
nl->SymbolValue(arg2) == GPoint::BasicType())
|
|
return 1;
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
struct NetdistanceNewInfo:OperatorInfo{
|
|
NetdistanceNewInfo(){
|
|
name = "netdistancenew";
|
|
signature = GPoint::BasicType() + " X " + MGPoint::BasicType() + " -> " +
|
|
MReal::BasicType();
|
|
appendSignature(MGPoint::BasicType() + " X " +
|
|
GPoint::BasicType() + " -> " +
|
|
MReal::BasicType());
|
|
syntax = "netdistancenew(_,_)";
|
|
meaning = "Computes the netdistance from 1.to 2. argument";
|
|
}
|
|
};
|
|
|
|
/*
|
|
6 Creating the Algebra
|
|
|
|
*/
|
|
|
|
class TemporalNetAlgebra : public Algebra
|
|
{
|
|
public:
|
|
|
|
TemporalNetAlgebra() : Algebra()
|
|
{
|
|
AddTypeConstructor( &ugpointTC);
|
|
AddTypeConstructor( &mgpointTC);
|
|
AddTypeConstructor( &igpointTC);
|
|
AddTypeConstructor( &mgpsecunitTC);
|
|
|
|
mgpointTC.AssociateKind( Kind::TEMPORAL() );
|
|
mgpointTC.AssociateKind( Kind::DATA() );
|
|
ugpointTC.AssociateKind( Kind::TEMPORAL() );
|
|
ugpointTC.AssociateKind( Kind::DATA() );
|
|
igpointTC.AssociateKind(Kind::TEMPORAL());
|
|
igpointTC.AssociateKind(Kind::DATA());
|
|
mgpsecunitTC.AssociateKind( Kind::DATA() );
|
|
|
|
|
|
AddOperator(atperiodsInfo(), OpAtperiodsValueMapping, OpAtperiodsTypeMap);
|
|
AddOperator(deftimeInfo(), OpDeftimeValueMapping, OpDeftimeSelect,
|
|
OpDeftimeTypeMap);
|
|
AddOperator(mpoint2mgpointInfo(), OpMPoint2MGPointValueMappingNeu,
|
|
OpMPoint2MGPointTypeMap);
|
|
AddOperator(simplifyInfo(), OpSimplifyValueMapping, OpSimplifyTypeMap);
|
|
AddOperator(passesInfo(), OpPassesvaluemap, OpPassesSelect,
|
|
OpPassesTypeMap);
|
|
AddOperator(atinstantInfo(), OpAtinstantValueMapping, OpAtinstantTypeMap);
|
|
AddOperator(atInfo(), OpAtValueMap, OpAtSelect, OpAtTypeMap);
|
|
AddOperator(initialInfo(), MappingInitial<MGPoint, UGPoint, GPoint>,
|
|
OpFinalInitialTypeMap);
|
|
AddOperator(finalInfo(), MappingFinal<MGPoint,UGPoint, GPoint>,
|
|
OpFinalInitialTypeMap);
|
|
AddOperator(insideInfo(), OpInsideValueMapping, OpInsideTypeMapping);
|
|
AddOperator(instInfo(), IntimeInst<GPoint>, OpInstTypeMap);
|
|
AddOperator(intersectionInfo(), OpIntersectionValueMapping,
|
|
OpUnionTypeMap);
|
|
AddOperator(lengthInfo(), OpLengthValueMap, OpLengthSelect,
|
|
OpLengthTypeMapping);
|
|
AddOperator(valInfo(), IntimeVal<GPoint>, OpValTypeMap);
|
|
AddOperator(presentInfo(), OpPresentValueMap, OpPresentSelect,
|
|
OpPresentTypeMap);
|
|
AddOperator(isemptyInfo(), OpIsEmptyValueMapping, OpIsEmptyTypeMap);
|
|
AddOperator(noComponentsInfo(), OpNoCompValueMapping, OpNoCompTypeMap);
|
|
AddOperator(trajectoryInfo(), OpTrajectoryValueMapping,
|
|
OpTrajectoryTypeMap);
|
|
AddOperator(unitsInfo(), MappingUnits<MGPoint, UGPoint>, OpUnitsTypeMap);
|
|
AddOperator(unitridInfo() , OpUnitRidValueMapping, OpUnitPosTimeTypeMap);
|
|
AddOperator(unitboxInfo(), OpUnitBoxValueMapping, OpUnitBoundingBoxTypeMap);
|
|
AddOperator(unitstartposInfo(), OpUnitStartPosValueMapping,
|
|
OpUnitPosTimeTypeMap);
|
|
AddOperator(unitendposInfo() , OpUnitEndPosValueMapping,
|
|
OpUnitPosTimeTypeMap);
|
|
AddOperator(unitstarttimeInfo(), OpUnitStartTimeValueMapping,
|
|
OpUnitPosTimeTypeMap);
|
|
AddOperator(unitendtimeInfo(), OpUnitEndTimeValueMapping,
|
|
OpUnitPosTimeTypeMap);
|
|
AddOperator(unitboundingboxInfo(), OpUnitBoundingBoxValueMapping,
|
|
OpUnitBoundingBoxTypeMap);
|
|
AddOperator(unitbox2Info(), OpUnitBox2ValueMapping, OpUnitBox2TypeMap);
|
|
AddOperator(mgpbboxInfo(), OpMGPointBoundingBoxValueMapping,
|
|
OpMGPointBoundingBoxTypeMap);
|
|
AddOperator(mgpbboxInfo(), OpMGPointBoundingBoxValueMapping,
|
|
OpMGPointBoundingBoxTypeMap);
|
|
AddOperator(mgpoint2mpointInfo(), OpMGPoint2MPointValueMapping,
|
|
OpMGPoint2MPointTypeMap);
|
|
AddOperator(distanceInfo(), OpDistanceValueMapping, OpDistanceTypeMapping);
|
|
AddOperator(unionInfo(), OpUnionValueMapping, OpUnionTypeMap);
|
|
AddOperator(startunitinstInfo(), OpStartunitinstValueMapping,
|
|
OpEndStartunitinstTypeMap);
|
|
AddOperator(endunitinstInfo(), OpEndunitinstValueMapping,
|
|
OpEndStartunitinstTypeMap);
|
|
AddOperator(ugpoint2mgpointInfo(), OpUgpoint2mgpointValueMapping,
|
|
OpUgpoint2mgpointTypeMap);
|
|
AddOperator(intersectsInfo(), OpIntersectsValueMapping,
|
|
OpIntersectsTypeMapping);
|
|
AddOperator(mgp2mgpsecunitsInfo(), OpMgp2mgpsecunitsValueMap,
|
|
OpMgp2mgpsecunitsTypeMap);
|
|
AddOperator(mgp2mgpsecunits2Info(), OpMgp2mgpsecunits2ValueMap,
|
|
OpMgp2mgpsecunits2TypeMap);
|
|
AddOperator(mgp2mgpsecunits3Info(), OpMgp2mgpsecunits3ValueMap,
|
|
OpMgp2mgpsecunits3TypeMap);
|
|
AddOperator(mgpsu2tupleInfo(), OpMgpsu2tupleValueMap, OpMgpsu2tupleTypeMap);
|
|
AddOperator(NetdistanceInfo(), OpNetdistanceValueMap,
|
|
OpNetdistanceSelect, OpNetdistanceTypeMap);
|
|
AddOperator(NetdistanceNewInfo(), OpNetdistanceNewValueMap,
|
|
OpNetdistanceNewSelect, OpNetdistanceNewTypeMap);
|
|
AddOperator(&mapmatching);
|
|
}
|
|
|
|
|
|
~TemporalNetAlgebra()
|
|
{
|
|
delete netList;
|
|
netList = 0;
|
|
};
|
|
};
|
|
|
|
/*
|
|
Initialization
|
|
|
|
Each algebra module needs an initialization function. The algebra manager
|
|
has a reference to this function if this algebra is included in the list
|
|
of required algebras, thus forcing the linker to include this module.
|
|
|
|
The algebra manager invokes this function to get a reference to the instance
|
|
of the algebra class and to provide references to the global nested list
|
|
container (used to store constructor, type, operator and object information)
|
|
and to the query processor.
|
|
|
|
The function has a C interface to make it possible to load the algebra
|
|
dynamically at runtime.
|
|
|
|
*/
|
|
|
|
extern "C" Algebra* InitializeTemporalNetAlgebra( NestedList* in_pNL,
|
|
QueryProcessor* in_pQP )
|
|
{
|
|
nl = in_pNL;
|
|
qp = in_pQP;
|
|
netList = new map<int,string>();
|
|
return (new TemporalNetAlgebra());
|
|
}
|
|
|