9464 lines
310 KiB
C++
9464 lines
310 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 "NestedList.h"
|
|
#include "Algebras/Relation-C++/RelationAlgebra.h"
|
|
#include "Algebras/BTree/BTreeAlgebra.h"
|
|
#include "Algebras/TupleIdentifier/TupleIdentifier.h"
|
|
#include "Tools/Flob/DbArray.h"
|
|
#include "Tools/Flob/Flob.h"
|
|
#include "StandardTypes.h"
|
|
#include "Algebras/Network2/Network2Algebra.h"
|
|
#include "Algebras/Temporal/TemporalAlgebra.h"
|
|
#include "TemporalNet2Algebra.h"
|
|
#include "Algebras/Network2/Network2Manager.h"
|
|
#include "ListUtils.h"
|
|
#include "Symbols.h"
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include "QueryProcessor.h"
|
|
#include "Algebra.h"
|
|
#include "DateTime.h"
|
|
|
|
extern NestedList* nl;
|
|
extern QueryProcessor* qp;
|
|
|
|
using namespace temporalalgebra;
|
|
using namespace temporalalgebra::temporalnet2;
|
|
using namespace std;
|
|
using namespace network2;
|
|
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(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(DbArray<RouteInterval> &riint1,
|
|
DbArray<RouteInterval> &riint2,
|
|
bool sortedri1,
|
|
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(GPoint *pGPoint, 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 (fabs(pGPoint->GetPosition() - rI.GetStartPos()) < 0.01 ||
|
|
fabs(pGPoint->GetPosition() - rI.GetEndPos()) < 0.01) {
|
|
return true;
|
|
} else {
|
|
if (rI.GetStartPos() > pGPoint->GetPosition()) {
|
|
return searchRouteInterval(pGPoint, 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(DbArray<RouteInterval> &tra, 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(double &startPos, double &endPos, bool &MovingUp,
|
|
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 (SimpleLine *&route, Point point, bool startSmaller,
|
|
double &pos, double &difference){
|
|
bool result = false;
|
|
HalfSegment hs;
|
|
double k1, k2;
|
|
Point left, right;
|
|
for (int i = 0; i < route->Size()-1; i++) {
|
|
route->Get(i, hs);
|
|
left = hs.GetLeftPoint();
|
|
right = hs.GetRightPoint();
|
|
Coord xl = left.GetX(),
|
|
yl = left.GetY(),
|
|
xr = right.GetX(),
|
|
yr = right.GetY(),
|
|
x = point.GetX(),
|
|
y = point.GetY();
|
|
if ((fabs(x-xr) < 0.01 && fabs (y-yr) < 0.01) ||
|
|
(fabs(x-xl) < 0.01 && fabs (y-yl) < 0.01))
|
|
{
|
|
difference = 0.0;
|
|
result = true;
|
|
} else {
|
|
if (xl != xr && xl != x) {
|
|
k1 = (y - yl) / (x - xl);
|
|
k2 = (yr - yl) / (xr - xl);
|
|
if ((fabs(k1-k2) < 0.004) &&
|
|
((xl < xr &&
|
|
(x > xl || fabs(x-xl) < 0.01) &&
|
|
(x < xr || fabs(x-xr) < 0.01)) ||
|
|
(xl > xr &&
|
|
(x < xl || fabs(x-xl)<0.01) &&
|
|
(x > xr || fabs(x-xr) < 0.01))) &&
|
|
(((yl < yr || fabs(yl-yr)<0.01) &&
|
|
(y > yl || fabs(y-yl)<0.01 ) &&
|
|
(y < yr || fabs(y-yr)<0.01)) ||
|
|
(yl > yr &&
|
|
(y < yl || fabs(y-yl) <0.01) &&
|
|
(y > yr || fabs(y-yr)<0.01))))
|
|
{
|
|
difference = fabs(k1-k2);
|
|
result = true;
|
|
}
|
|
else {result = false;}
|
|
}
|
|
else
|
|
{
|
|
if (( fabs(xl - xr) < 0.01 && fabs(xl -x) < 0.01) &&
|
|
(((yl < yr|| fabs(yl-yr)<0.01) &&
|
|
(yl < y || fabs(yl-y) <0.01)&&
|
|
(y < yr ||fabs(y-yr)<0.01))||
|
|
(yl > yr &&
|
|
(yl > y || fabs(yl-y)<0.01)&&
|
|
(y > yr ||fabs(y-yr)<0.01))))
|
|
{
|
|
difference = 0.0;
|
|
result = true;
|
|
}
|
|
else {result = false;}
|
|
}
|
|
}
|
|
if (result) {
|
|
LRS lrs;
|
|
route->Get( hs.attr.edgeno, lrs );
|
|
route->Get( lrs.hsPos, hs );
|
|
pos = lrs.lrsPos + point.Distance( hs.GetDomPoint() );
|
|
if( startSmaller != route->GetStartSmaller())
|
|
pos = route->Length() - pos;
|
|
if( fabs(pos-0.0) < 0.01)
|
|
pos = 0.0;
|
|
else if (fabs(pos-route->Length())<0.01)
|
|
pos = route->Length();
|
|
return result;
|
|
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool checkPointN (SimpleLine route, Point point, bool startSmaller,
|
|
double &pos)
|
|
{
|
|
bool result = false;
|
|
HalfSegment hs;
|
|
double k1, k2;
|
|
Point left, right;
|
|
for (int i = 0; i < route.Size()-1; i++) {
|
|
route.Get(i, hs);
|
|
left = hs.GetLeftPoint();
|
|
right = hs.GetRightPoint();
|
|
Coord xl = left.GetX(),
|
|
yl = left.GetY(),
|
|
xr = right.GetX(),
|
|
yr = right.GetY(),
|
|
x = point.GetX(),
|
|
y = point.GetY();
|
|
if ((fabs(x-xr) < 0.01 && fabs (y-yr) < 0.01) ||
|
|
(fabs(x-xl) < 0.01 && fabs (y-yl) < 0.01))
|
|
result = true;
|
|
else
|
|
{
|
|
if (xl != xr && xl != x)
|
|
{
|
|
k1 = (y - yl) / (x - xl);
|
|
k2 = (yr - yl) / (xr - xl);
|
|
if ((fabs(k1-k2) < 0.004) &&
|
|
((xl < xr &&
|
|
(x > xl || fabs(x-xl) < 0.01) &&
|
|
(x < xr || fabs(x-xr) < 0.01)) ||
|
|
(xl > xr &&
|
|
(x < xl || fabs(x-xl) < 0.01) &&
|
|
(x > xr || fabs(x-xr) < 0.01))) &&
|
|
(((yl < yr || fabs(yl-yr) < 0.01) &&
|
|
(y > yl || fabs(y-yl) < 0.01) &&
|
|
(y < yr || fabs(y-yr) < 0.01)) ||
|
|
(yl > yr &&
|
|
(y < yl || fabs(y-yl) <0.01) &&
|
|
(y > yr || fabs(y-yr)<0.01))))
|
|
result = true;
|
|
else result = false;
|
|
}
|
|
else
|
|
{
|
|
if (( fabs(xl - xr) < 0.01 && fabs(xl -x) < 0.01) &&
|
|
(((yl < yr|| fabs(yl-yr)<0.01) &&
|
|
(yl < y || fabs(yl-y) <0.01)&&
|
|
(y < yr ||fabs(y-yr)<0.01))||
|
|
(yl > yr &&
|
|
(yl > y ||fabs(yl-y)<0.01)&&
|
|
(y > yr ||fabs(y-yr)<0.01))))
|
|
result = true;
|
|
else result = false;
|
|
}
|
|
}
|
|
if (result) {
|
|
LRS lrs;
|
|
route.Get( hs.attr.edgeno, lrs );
|
|
route.Get( lrs.hsPos, hs );
|
|
pos = lrs.lrsPos + point.Distance( hs.GetDomPoint() );
|
|
if( startSmaller != route.GetStartSmaller())
|
|
pos = route.Length() - pos;
|
|
if( fabs(pos-0.0) < 0.01)
|
|
pos = 0.0;
|
|
else if (fabs(pos-route.Length())<0.01)
|
|
pos = route.Length();
|
|
return result;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
Almost Equal to ~checkPoint~ but allows bigger differences. Used by
|
|
~mpoint2mgpoint~.
|
|
|
|
*/
|
|
|
|
bool checkPoint03 (SimpleLine *&route, Point point, bool startSmaller,
|
|
double &pos, double &difference){
|
|
bool result = false;
|
|
HalfSegment hs;
|
|
double k1, k2;
|
|
Point left, right;
|
|
for (int i = 0; i < route->Size()-1; i++) {
|
|
route->Get(i, hs);
|
|
left = hs.GetLeftPoint();
|
|
right = hs.GetRightPoint();
|
|
Coord xl = left.GetX(),
|
|
yl = left.GetY(),
|
|
xr = right.GetX(),
|
|
yr = right.GetY(),
|
|
x = point.GetX(),
|
|
y = point.GetY();
|
|
if ((fabs(x-xl) < 0.01 && fabs (y-yl) < 0.01) ||
|
|
(fabs(x-xr) < 0.01 && fabs (y-yr) < 0.01)) {
|
|
difference = 0.0;
|
|
result = true;
|
|
} else {
|
|
if (xl != xr && xl != x) {
|
|
k1 = (y - yl) / (x - xl);
|
|
k2 = (yr - yl) / (xr - xl);
|
|
if ((fabs(k1-k2) < 1.2) &&
|
|
((xl < xr &&
|
|
(x > xl || fabs(x-xl) < 0.01) &&
|
|
(x < xr || fabs(x-xr) < 0.01)) ||
|
|
(xl > xr &&
|
|
(x < xl || fabs(x-xl) < 0.01) &&
|
|
( x > xr || fabs(x-xr) < 0.01))) &&
|
|
(((yl < yr || fabs(yl-yr) < 0.01) &&
|
|
(y > yl || fabs(y-yl) < 0.01 ) &&
|
|
(y < yr || fabs(y-yr)<0.01)) ||
|
|
(yl > yr &&
|
|
(y < yl || fabs(y-yl) <0.01) &&
|
|
(y > yr || fabs(y-yr)<0.01))))
|
|
{
|
|
difference = fabs(k1-k2);
|
|
result = true;
|
|
}
|
|
else {result = false;}
|
|
}
|
|
else
|
|
{
|
|
if (( fabs(xl - xr) < 0.01 && fabs(xl -x) < 0.01) &&
|
|
(((yl < yr|| fabs(yl-yr)<0.01) &&
|
|
(yl < y || fabs(yl-y) <0.01)&&
|
|
(y < yr ||fabs(y-yr)<0.01))||
|
|
(yl > yr &&
|
|
(yl > y || fabs(yl-y)<0.01)&&
|
|
(y > yr ||fabs(y-yr)<0.01))))
|
|
{
|
|
difference = 0.0;
|
|
result = true;
|
|
}
|
|
else {result = false;}
|
|
}
|
|
}
|
|
if (result)
|
|
{
|
|
LRS lrs;
|
|
route->Get( hs.attr.edgeno, lrs );
|
|
route->Get( lrs.hsPos, hs );
|
|
pos = lrs.lrsPos + point.Distance( hs.GetDomPoint() );
|
|
if( startSmaller != route->GetStartSmaller())
|
|
pos = route->Length() - pos;
|
|
if( fabs(pos-0.0) < 0.01)
|
|
pos = 0.0;
|
|
else if (fabs(pos-route->Length())<0.01)
|
|
pos = route->Length();
|
|
return result;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool lastcheckPoint03 (SimpleLine *&route, Point point, bool startSmaller,
|
|
double &pos, double &difference){
|
|
bool result = false;
|
|
HalfSegment hs;
|
|
double k1, k2;
|
|
Point left, right;
|
|
for (int i = 0; i < route->Size()-1; i++) {
|
|
route->Get(i, hs);
|
|
left = hs.GetLeftPoint();
|
|
right = hs.GetRightPoint();
|
|
Coord xl = left.GetX(),
|
|
yl = left.GetY(),
|
|
xr = right.GetX(),
|
|
yr = right.GetY(),
|
|
x = point.GetX(),
|
|
y = point.GetY();
|
|
if ((fabs(x-xl) < 0.01 && fabs (y-yl) < 0.01) ||
|
|
(fabs(x-xr) < 0.01 && fabs (y-yr) < 0.01)) {
|
|
difference = 0.0;
|
|
result = true;
|
|
} else {
|
|
if (xl != xr && xl != x) {
|
|
k1 = (y - yl) / (x - xl);
|
|
k2 = (yr - yl) / (xr - xl);
|
|
if (((xl < xr &&
|
|
(x > xl || fabs(x-xl) < 0.1) &&
|
|
(x < xr || fabs(x-xr) < 0.01)) ||
|
|
(xl > xr &&
|
|
( x < xl || fabs(x-xl)<0.01) &&
|
|
( x > xr || fabs(x-xr)<0.01))) &&
|
|
(((yl < yr || fabs(yl-yr)<0.01) &&
|
|
(y > yl || fabs(y-yl)<0.01 )&&
|
|
(y < yr || fabs(y-yr)<0.01)) ||
|
|
(yl > yr &&
|
|
(y < yl || fabs(y-yl) <0.01) &&
|
|
(y > yr || fabs(y-yr)<0.01))))
|
|
{
|
|
difference = fabs(k1-k2);
|
|
result = true;
|
|
}
|
|
else {result = false;}
|
|
}
|
|
else
|
|
{
|
|
if (( fabs(xl - xr) < 0.1 && fabs(xl -x) < 0.1) &&
|
|
(((yl < yr|| fabs(yl-yr)<0.1) &&
|
|
(yl < y || fabs(yl-y) <0.1)&&
|
|
(y < yr || fabs(y-yr)<0.1))||
|
|
(yl > yr &&
|
|
(yl > y || fabs(yl-y)<0.1)&&
|
|
(y > yr ||fabs(y-yr)<0.1))))
|
|
{
|
|
difference = 0.0;
|
|
result = true;
|
|
}
|
|
else {result = false;}
|
|
}
|
|
}
|
|
if (result) {
|
|
LRS lrs;
|
|
route->Get( hs.attr.edgeno, lrs );
|
|
route->Get( lrs.hsPos, hs );
|
|
pos = lrs.lrsPos + point.Distance( hs.GetDomPoint() );
|
|
if( startSmaller != route->GetStartSmaller())
|
|
pos = route->Length() - pos;
|
|
if( pos < 0.0 || fabs(pos - 0.0) < 0.01)
|
|
pos = 0.0;
|
|
else if (pos > route->Length() || fabs(pos - route->Length()) < 0.01)
|
|
pos = route->Length();
|
|
return result;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
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,
|
|
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();
|
|
NList xMessage;
|
|
xMessage.append(NList("error"));
|
|
|
|
xMessage.append(NList().textAtom(in_strMessage));
|
|
xMessageCenter->Send(nl,xMessage.listExpr());
|
|
}
|
|
|
|
|
|
/*
|
|
Returns the ~RouteIntervals~ of a route between mgpstart and mgpend.
|
|
|
|
Used by operators ~at~ and ~inside~.
|
|
|
|
*/
|
|
|
|
void getRouteIntervals(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 (Interval<Instant> i1, 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 (MGPoint *a, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 );
|
|
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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 );
|
|
//}
|
|
}
|
|
|
|
ListExpr MGPoint::Property()
|
|
{
|
|
return (nl->TwoElemList(
|
|
nl->FourElemList(nl->StringAtom("Signature"),
|
|
nl->StringAtom("Example Type List"),
|
|
nl->StringAtom("List Rep"),
|
|
nl->StringAtom("Example List")),
|
|
nl->FourElemList(nl->StringAtom("-> MAPPING"),
|
|
nl->StringAtom("(mgpoint) "),
|
|
nl->StringAtom("( u1 ... un ) "),
|
|
nl->StringAtom("(((i1 i2 TRUE FALSE) "
|
|
"(1 1 0 0.1 2.4)) ...)"))));
|
|
}
|
|
|
|
bool MGPoint::Check(ListExpr type,
|
|
ListExpr& errorInfo)
|
|
{
|
|
return (nl->IsEqual( type, "mgpoint" ));
|
|
}
|
|
|
|
/*
|
|
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(){
|
|
if (IsDefined()) return m_length;
|
|
else return 0.0;
|
|
}
|
|
|
|
void MGPoint::SetBoundingBox(Rectangle<3> mbr){
|
|
m_bbox = mbr;
|
|
}
|
|
|
|
void MGPoint::SetTrajectory(const DbArray<RouteInterval>& tra){
|
|
if (tra.Size() > 0){
|
|
m_traj_Defined = true;
|
|
/*m_trajectory.resize(tra.Size());
|
|
RouteInterval ri;
|
|
for (int i = 0; i < tra.Size(); i++) {
|
|
tra.Get(i,ri);
|
|
m_trajectory.Put(i,ri);
|
|
}*/
|
|
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_trajectory.resize(src.NoOfComponents());
|
|
RouteInterval ri;
|
|
for (int i = 0; i < src.NoOfComponents(); i++) {
|
|
src.Get(i,ri);
|
|
m_trajectory.Put(i,ri);
|
|
}*/
|
|
m_traj_Defined = true;
|
|
}else m_traj_Defined = false;
|
|
}
|
|
|
|
void MGPoint::Trajectory(GLine* res) {
|
|
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();
|
|
}
|
|
|
|
void MGPoint::Deftime(Periods &res){
|
|
res.Clear();
|
|
Periods per(0);
|
|
UGPoint unit;
|
|
per.StartBulkLoad();
|
|
for( int i = 0; i < GetNoComponents(); i++ ) {
|
|
Get( i, unit );
|
|
if (unit.IsDefined())
|
|
per.MergeAdd(unit.timeInterval);
|
|
}
|
|
per.EndBulkLoad(false);
|
|
}
|
|
|
|
|
|
/*
|
|
Operations with ~mgpoint~
|
|
|
|
Euclidean Distance computing
|
|
|
|
*/
|
|
|
|
void MGPoint::Distance(MGPoint *&mgp, MReal *&result){
|
|
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(MGPoint* mgp, MReal* result){
|
|
//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(UGPoint* ug1,UGPoint* ug2,Network* pNetwork,
|
|
vector<UReal>& dist)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
cout<<l1<<" "<<l2<<" "<<l3<<" "<<l4<<endl;
|
|
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);
|
|
ep1_0->Print(cout);
|
|
ep1_1->Print(cout);
|
|
ep2_0->Print(cout);
|
|
ep2_1->Print(cout);
|
|
gl1->Print(cout);
|
|
gl2->Print(cout);
|
|
gl3->Print(cout);
|
|
gl4->Print(cout);
|
|
cout<<dist1<<" "<<dist2<<" "<<dist3<<" "<<dist4<<endl;
|
|
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) == ep2_1->Inside(gline1));
|
|
if(ep2_1->Inside(gl1)){ //gl1
|
|
if(ep1_1->Inside(gl1)){
|
|
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) == false);
|
|
assert(ep2_0->Inside(gl2) == ep2_0->Inside(gline2));
|
|
}else{
|
|
assert(ep1_1->Inside(gl1) == ep1_1->Inside(gline1));
|
|
if(ep1_1->Inside(gl1)){
|
|
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) == ep2_0->Inside(gline2));
|
|
if(ep2_0->Inside(gl2)){//gl2
|
|
if(ep1_1->Inside(gl1)){
|
|
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)){
|
|
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) == ep2_1->Inside(gline3));
|
|
if(ep2_1->Inside(gl3)){//gl3
|
|
if(ep1_0->Inside(gl3)){
|
|
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) == ep1_0->Inside(gline3));
|
|
if(ep1_0->Inside(gl3)){
|
|
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) == ep2_0->Inside(gline4));
|
|
if(ep2_0->Inside(gl4)){ //gl4
|
|
if(ep1_0->Inside(gl4)){
|
|
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)){
|
|
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) == ep2_1->Inside(gline1));
|
|
if(ep2_1->Inside(gl1)){ //gl1
|
|
if(ep1_1->Inside(gl1)){
|
|
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) == false);
|
|
assert(ep2_0->Inside(gl2) == ep2_0->Inside(gline2));
|
|
}else{
|
|
assert(ep1_1->Inside(gl1) == ep1_1->Inside(gline1));
|
|
if(ep1_1->Inside(gl1)){
|
|
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) == ep2_0->Inside(gline2));
|
|
if(ep2_0->Inside(gl2)){ //gl2
|
|
if(ep1_1->Inside(gl1)){
|
|
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)){
|
|
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) == ep2_1->Inside(gline3));
|
|
if(ep2_1->Inside(gl3)){ //gl3
|
|
if(ep1_0->Inside(gl3)){
|
|
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) == ep1_0->Inside(gline3));
|
|
if(ep1_0->Inside(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) == ep2_0->Inside(gline4));
|
|
if(ep2_0->Inside(gl4)){ //gl4
|
|
if(ep1_0->Inside(gl4)){
|
|
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)){
|
|
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) == ep2_1->Inside(gline1));
|
|
if(ep2_1->Inside(gl1)){ //gl1
|
|
if(ep1_1->Inside(gl1)){
|
|
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) == false);
|
|
assert(ep2_0->Inside(gl2) == ep2_0->Inside(gline2));
|
|
}else{
|
|
assert(ep1_1->Inside(gl1) == ep1_1->Inside(gline1));
|
|
if(ep1_1->Inside(gl1)){
|
|
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) == ep2_0->Inside(gline2));
|
|
if(ep2_0->Inside(gl2)){ //gl2
|
|
if(ep1_1->Inside(gl2)){
|
|
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)){
|
|
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) == ep2_1->Inside(gline3));
|
|
if(ep2_1->Inside(gl3)){ //gl3
|
|
if(ep1_0->Inside(gl3)){
|
|
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) == ep1_0->Inside(gline3));
|
|
if(ep1_0->Inside(gl3)){//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) == ep2_0->Inside(gline4));
|
|
if(ep2_0->Inside(gl4)){//gl4
|
|
if(ep1_0->Inside(gl4)){
|
|
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)){
|
|
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) == ep2_1->Inside(gline1));
|
|
if(ep2_1->Inside(gl1)){//gl1
|
|
if(ep1_1->Inside(gl1)){
|
|
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) == false);
|
|
assert(ep2_0->Inside(gl2) == ep2_0->Inside(gline2));
|
|
}else{
|
|
assert(ep1_1->Inside(gl1) == ep1_1->Inside(gline1));
|
|
if(ep1_1->Inside(gl1)){
|
|
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) == ep2_0->Inside(gline2));
|
|
if(ep2_0->Inside(gl2)){ //gl2
|
|
if(ep1_1->Inside(gl2)){
|
|
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)){
|
|
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) == ep2_1->Inside(gline3));
|
|
if(ep2_1->Inside(gl3)){ //gl3
|
|
if(ep1_0->Inside(gl3)){
|
|
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) == ep1_0->Inside(gline3));
|
|
if(ep1_0->Inside(gl3)){//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) == ep2_0->Inside(gline4));
|
|
if(ep2_0->Inside(gl4)){//gl4
|
|
if(ep1_0->Inside(gl4)){
|
|
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)){
|
|
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(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();
|
|
}
|
|
|
|
/*
|
|
Translation from network ~mgpoint~ to spatial ~mpoint~
|
|
|
|
*/
|
|
|
|
void MGPoint::Mgpoint2mpoint(MPoint *&mp) {
|
|
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) {
|
|
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*/) {
|
|
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) {
|
|
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(MGPoint *&mgp, MGPoint *&res){
|
|
// 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 (fabs(interPosition - pCurr1.p0.GetPosition()) < 0.01)
|
|
ok = ok && pCurr1.timeInterval.lc;
|
|
if (fabs(interPosition - pCurr1.p1.GetPosition()) < 0.01)
|
|
ok = ok && pCurr1.timeInterval.rc;
|
|
}
|
|
else
|
|
if (fabs(interPosition - pCurr1.p0.GetPosition()) < 0.01)
|
|
ok = true;
|
|
else ok = false;
|
|
if(pCurr2.p0.GetPosition() != pCurr2.p1.GetPosition())
|
|
{
|
|
if (fabs(interPosition - pCurr2.p0.GetPosition()) < 0.01)
|
|
ok = ok && pCurr2.timeInterval.lc;
|
|
if (fabs(interPosition - pCurr2.p1.GetPosition()) < 0.01)
|
|
ok = ok && pCurr2.timeInterval.rc;
|
|
}
|
|
else
|
|
if (fabs(interPosition-pCurr2.p0.GetPosition()) < 0.01)
|
|
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 (fabs(r1meas - pCurr1.p0.GetPosition()) < 0.01)
|
|
ok = ok && pCurr1.timeInterval.lc;
|
|
if (fabs(r1meas - pCurr1.p1.GetPosition()) < 0.01)
|
|
ok = ok && pCurr1.timeInterval.rc;
|
|
if (fabs(r2meas - pCurr2.p0.GetPosition()) < 0.01)
|
|
ok = ok && pCurr2.timeInterval.lc;
|
|
if (fabs(r2meas - pCurr2.p1.GetPosition()) < 0.01)
|
|
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(MGPoint *mgp)
|
|
{
|
|
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 (fabs(interPosition - pCurr1.p0.GetPosition()) < 0.01)
|
|
ok = ok && pCurr1.timeInterval.lc;
|
|
if (fabs(interPosition - pCurr1.p1.GetPosition()) < 0.01)
|
|
ok = ok && pCurr1.timeInterval.rc;
|
|
}
|
|
else
|
|
if (fabs(interPosition - pCurr1.p0.GetPosition()) < 0.01)
|
|
ok = true;
|
|
else ok = false;
|
|
if(pCurr2.p0.GetPosition() != pCurr2.p1.GetPosition())
|
|
{
|
|
if (fabs(interPosition - pCurr2.p0.GetPosition()) < 0.01)
|
|
ok = ok && pCurr2.timeInterval.lc;
|
|
if (fabs(interPosition - pCurr2.p1.GetPosition()) < 0.01)
|
|
ok = ok && pCurr2.timeInterval.rc;
|
|
}
|
|
else
|
|
if (fabs(interPosition-pCurr2.p0.GetPosition()) < 0.01)
|
|
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 (fabs(r1meas - pCurr1.p0.GetPosition()) < 0.01)
|
|
ok = ok && pCurr1.timeInterval.lc;
|
|
if (fabs(r1meas - pCurr1.p1.GetPosition()) < 0.01)
|
|
ok = ok && pCurr1.timeInterval.rc;
|
|
if (fabs(r2meas - pCurr2.p0.GetPosition()) < 0.01)
|
|
ok = ok && pCurr2.timeInterval.lc;
|
|
if (fabs(r2meas - pCurr2.p1.GetPosition()) < 0.01)
|
|
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(GLine *&gl, MBool *&res){
|
|
// 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(Periods *&per, MGPoint *&res){
|
|
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(Instant *&per, Intime<GPoint> *&res){
|
|
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(GPoint *&gp, MGPoint *&res){
|
|
// 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 (fabs(gp->GetPosition()-pCurrentUnit.p0.GetPosition()) < 0.01){
|
|
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(fabs(gp->GetPosition()-pCurrentUnit.p1.GetPosition())<0.01) {
|
|
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(GLine *&gl, MGPoint *&res){
|
|
// 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(double d, MGPoint* res){
|
|
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(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();
|
|
if (RIsIntersects(m_trajectory, *gltra, true, gl->IsSorted())) return true;
|
|
else return false;
|
|
}
|
|
|
|
|
|
MGPoint* MGPoint::Clone() const {
|
|
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{
|
|
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,0.0,0.0,0.0,0.0);
|
|
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;
|
|
bbox = Rectangle<3> (true,
|
|
ribox.MinD(0),
|
|
ribox.MaxD(0),
|
|
ribox.MinD(1),
|
|
ribox.MaxD(1),
|
|
x5, x6);
|
|
} else {
|
|
ribox3 = Rectangle<3> (true,
|
|
ribox.MinD(0),
|
|
ribox.MaxD(0),
|
|
ribox.MinD(1),
|
|
ribox.MaxD(1),
|
|
x5, x6);
|
|
bbox = bbox.Union(ribox3);
|
|
}
|
|
}
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
help->DeleteIfAllowed();
|
|
return bbox;
|
|
} else {
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
help->DeleteIfAllowed();
|
|
return Rectangle<3> (false, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
|
}
|
|
} else {
|
|
return Rectangle<3>(false, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
|
}
|
|
} else {
|
|
if (m_trajectory.Size() <= 0)
|
|
return Rectangle<3>(false, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
|
Rectangle<3> bbox, ribox3;
|
|
Rectangle<2> ribox = Rectangle<2u>(false,0.0,0.0,0.0,0.0);
|
|
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;
|
|
bbox = Rectangle<3> (true,
|
|
ribox.MinD(0),
|
|
ribox.MaxD(0),
|
|
ribox.MinD(1),
|
|
ribox.MaxD(1),
|
|
x5, x6);
|
|
} else {
|
|
ribox3 = Rectangle<3> (true,
|
|
ribox.MinD(0),
|
|
ribox.MaxD(0),
|
|
ribox.MinD(1),
|
|
ribox.MaxD(1),
|
|
x5, x6);
|
|
bbox = bbox.Union(ribox3);
|
|
}
|
|
}
|
|
NetworkManager::CloseNetwork(pNetwork);
|
|
return bbox;
|
|
}
|
|
} else return Rectangle<3>(false, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
|
}
|
|
}
|
|
|
|
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;
|
|
/*os <<", constains Trajectory " << m_trajectory.Size() << " intervals:";
|
|
for (int i = 0; i < m_trajectory.Size(); i++) {
|
|
const RouteInterval *ri;
|
|
m_trajectory.Get(i, ri);
|
|
os << "/n/t";
|
|
os << "(" << ri->GetRouteId() << ", ";
|
|
os << ri->GetStartPos() << ", " << ri->GetEndPos() << ")";
|
|
}
|
|
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(bool defined){
|
|
m_traj_Defined=defined;
|
|
}
|
|
|
|
void MGPoint::SetBoundingBoxDefined(bool defined){
|
|
m_bbox.SetDefined(defined);
|
|
if (!defined) m_bbox = Rectangle<3> (false, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
|
}
|
|
|
|
/*
|
|
Merges two MGPoint into one if the time intervals don't overlap.
|
|
Otherwise the union is undefined.
|
|
|
|
*/
|
|
|
|
void MGPoint::Union(MGPoint *mp, MGPoint *res)
|
|
{
|
|
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);
|
|
}
|
|
|
|
TypeConstructor movinggpoint(
|
|
"mgpoint", // Name
|
|
MGPoint::Property, // Property function
|
|
OutMapping<MGPoint, UGPoint, UGPoint::Out>, // Out and In functions
|
|
InMapping<MGPoint, UGPoint, UGPoint::In>,
|
|
/*InMGPoint,*/
|
|
0, // SaveToList and
|
|
0, // RestoreFromList
|
|
CreateMapping<MGPoint>, // Object creation and
|
|
DeleteMapping<MGPoint>, // deletion
|
|
OpenAttribute<MGPoint>, /*OpenMGPoint,*/
|
|
SaveAttribute<MGPoint>, // Object open and save
|
|
CloseMapping<MGPoint>, // Object close and clone
|
|
CloneMapping<MGPoint>,
|
|
CastMapping<MGPoint>, // Cast function
|
|
SizeOfMapping<MGPoint>, // Sizeof function
|
|
MGPoint::Check); // Kind checking function
|
|
|
|
|
|
|
|
/*
|
|
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~
|
|
|
|
*/
|
|
ListExpr UGPoint::Property()
|
|
{
|
|
return (nl->TwoElemList(
|
|
nl->FourElemList(nl->StringAtom("Signature"),
|
|
nl->StringAtom("Example Type List"),
|
|
nl->StringAtom("List Rep"),
|
|
nl->StringAtom("Example List")),
|
|
nl->FourElemList(nl->StringAtom("-> UNIT"),
|
|
nl->StringAtom("(ugpoint) "),
|
|
nl->TextAtom("( timeInterval (<nid> <rid> <side> <pos1> <pos2> ) ) "),
|
|
nl->StringAtom("((i1 i2 TRUE FALSE) (1 1 0 0.0 0.3))"))));
|
|
}
|
|
|
|
bool UGPoint::Check(ListExpr type, ListExpr& errorInfo)
|
|
{
|
|
return (nl->IsEqual( type, "ugpoint" ));
|
|
}
|
|
|
|
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){
|
|
per.Clear();
|
|
if (IsDefined()) {
|
|
per.StartBulkLoad();
|
|
per.Add(timeInterval);
|
|
per.EndBulkLoad();
|
|
per.SetDefined(true);
|
|
} else per.SetDefined(false);
|
|
}
|
|
|
|
Instant UGPoint::TimeAtPos(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() &&
|
|
fabs(rgp10.GetPosition()-rgp20.GetPosition()) < 0.01 &&
|
|
fabs(rgp11.GetPosition()-rgp21.GetPosition()) < 0.01)
|
|
{ // 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* g )const {
|
|
assert (g == 0);
|
|
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;
|
|
return Rectangle<3> (true,
|
|
rect.MinD(0), rect.MaxD(0),
|
|
rect.MinD(1), rect.MaxD(1),
|
|
timeInterval.start.ToDouble(),
|
|
timeInterval.end.ToDouble());
|
|
} else return Rectangle<3>(false, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
|
}
|
|
|
|
double UGPoint::Distance(const Rectangle<3>& rect, const Geoid* g) const{
|
|
assert( g == 0);
|
|
cerr << "Distance function not implemented yet";
|
|
if(!IsDefined() || !rect.IsDefined()){
|
|
return -1;
|
|
} else {
|
|
return BoundingBox().Distance(rect);
|
|
}
|
|
}
|
|
|
|
void UGPoint::GetPassedSections(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(UGPoint unit, double sectMeas1, double sectMeas2,
|
|
double &startPos, int &partNo, double maxSectLength,
|
|
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(UGPoint unit, double sectMeas1, double sectMeas2,
|
|
double &startPos, int &partNo, double maxSectLength,
|
|
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,
|
|
double maxSectLength,
|
|
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(Network*& pNetwork)const{
|
|
if(IsDefined()){
|
|
RouteInterval *ri = new RouteInterval(p0.GetRouteId(), p0.GetPosition(),
|
|
p1.GetPosition());
|
|
Rectangle<2> rect = ri->BoundingBox(pNetwork);
|
|
delete ri;
|
|
return Rectangle<3> (true,
|
|
rect.MinD(0), rect.MaxD(0),
|
|
rect.MinD(1), rect.MaxD(1),
|
|
timeInterval.start.ToDouble(),
|
|
timeInterval.end.ToDouble());
|
|
}else return Rectangle<3>(false,0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
|
}
|
|
|
|
|
|
TypeConstructor unitgpoint(
|
|
"ugpoint", // Name
|
|
UGPoint::Property, // Property function
|
|
UGPoint::Out, UGPoint::In, // Out and In functions
|
|
0, 0, // Save to and restore
|
|
// from list functions
|
|
UGPoint::Create, // Object creation
|
|
UGPoint::Delete, // and deletion
|
|
OpenAttribute<UGPoint>,SaveAttribute<UGPoint>, //Object open and save
|
|
UGPoint::Close, UGPoint::Clone, // Object close and clone
|
|
UGPoint::Cast, // Cast function
|
|
UGPoint::SizeOf, // Sizeof function
|
|
UGPoint::Check); // Kind checking function
|
|
|
|
/*
|
|
4 ~igpoint~
|
|
|
|
*/
|
|
|
|
ListExpr IntimeGPointProperty()
|
|
{
|
|
return (nl->TwoElemList(
|
|
nl->FourElemList(nl->StringAtom("Signature"),
|
|
nl->StringAtom("Example Type List"),
|
|
nl->StringAtom("List Rep"),
|
|
nl->StringAtom("Example List")),
|
|
nl->FourElemList(nl->StringAtom("-> TEMPORAL"),
|
|
nl->StringAtom("(igpoint) "),
|
|
nl->StringAtom("(instant gpoint-value)"),
|
|
nl->StringAtom("((instant) (1 1 1.0 2))"))));
|
|
}
|
|
|
|
|
|
bool CheckIntimeGPoint( ListExpr type, ListExpr& errorInfo )
|
|
{
|
|
return (nl->IsEqual( type, "igpoint" ));
|
|
}
|
|
|
|
|
|
TypeConstructor intimegpoint(
|
|
"igpoint", //name
|
|
IntimeGPointProperty, //property function describing signature
|
|
OutIntime<GPoint, GPoint::OutGPoint>,
|
|
InIntime<GPoint, GPoint::InGPoint>, //Out and In functions
|
|
0,
|
|
0, //SaveToList and RestoreFromList functions
|
|
CreateIntime<GPoint>,
|
|
DeleteIntime<GPoint>, //object creation and deletion
|
|
OpenAttribute<GPoint>,
|
|
OpenAttribute<GPoint>, // object open and save
|
|
CloseIntime<GPoint>,
|
|
CloneIntime<GPoint>, //object close and clone
|
|
CastIntime<GPoint>, //cast function
|
|
SizeOfIntime<GPoint>, //sizeof function
|
|
CheckIntimeGPoint ); //kind checking function
|
|
|
|
/*
|
|
2. Implementation of Class ~MGPSecUnit~
|
|
|
|
*/
|
|
MGPSecUnit::MGPSecUnit():Attribute()
|
|
{
|
|
}
|
|
|
|
MGPSecUnit::MGPSecUnit(bool defined, int secId, int part, Side direct,
|
|
double sp, 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(int secId)
|
|
{
|
|
m_secId = secId;
|
|
}
|
|
|
|
void MGPSecUnit::SetPart(int p)
|
|
{
|
|
m_part = p;
|
|
}
|
|
|
|
void MGPSecUnit::SetDirect(Side dir)
|
|
{
|
|
m_direct = dir;
|
|
}
|
|
|
|
void MGPSecUnit::SetSpeed(double x)
|
|
{
|
|
m_speed = x;
|
|
}
|
|
|
|
void MGPSecUnit::SetTimeInterval(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" ));
|
|
}
|
|
|
|
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";
|
|
signature = "-> DATA";
|
|
typeExample = "mgpsecunit";
|
|
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") && 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"))
|
|
{
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
|
|
nl->OneElemList(nl->IntAtom(j)),
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom("mgpsecunit")));
|
|
}
|
|
}
|
|
}
|
|
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 = "Builds a stream of mgpsecunits from mgpoint.";
|
|
}
|
|
};
|
|
|
|
/*
|
|
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") && length.isEqual(CcReal::BasicType()))
|
|
{
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom("mgpsecunit"));
|
|
}
|
|
}
|
|
return NList::typeError( "Expected <mgpoint>, <real>.");
|
|
}
|
|
|
|
/*
|
|
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 x real -> stream(mgpsecunit)";
|
|
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");
|
|
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"));
|
|
}
|
|
return NList::typeError( "Expected ((stream mgpoint) real).");
|
|
}
|
|
|
|
/*
|
|
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 = "stream(mgpoint) x real -> stream(mgpsecunit)";
|
|
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)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 2 ){
|
|
sendMessages("Expects a list of length 2.");
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
ListExpr xNetworkIdDesc = nl->First(in_xArgs);
|
|
ListExpr xMPointDesc = nl->Second(in_xArgs);
|
|
|
|
if( (!nl->IsAtom(xNetworkIdDesc)) ||
|
|
!nl->IsEqual(xNetworkIdDesc, "network"))
|
|
{
|
|
sendMessages("Expected network as first argument.");
|
|
return (nl->SymbolAtom(Symbol::TYPEERROR()));
|
|
}
|
|
|
|
if( (!nl->IsAtom( xMPointDesc )) ||
|
|
nl->AtomType( xMPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMPointDesc ) != MPoint::BasicType() )
|
|
{
|
|
sendMessages("Expected mpoint as second argument.");
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
return nl->SymbolAtom( "mgpoint" );
|
|
}
|
|
/*
|
|
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);
|
|
cout << "Network not defined!" << endl;
|
|
return 0;
|
|
}
|
|
MPoint *pMPoint = (MPoint*)args[1].addr;
|
|
if (pMPoint == 0 || !pMPoint->IsDefined())
|
|
{
|
|
res->SetDefined(false);
|
|
cout << "MPoint is not defined!" << endl;
|
|
return 0;
|
|
}
|
|
if (pMPoint->GetNoComponents() == 0)
|
|
{
|
|
cout << "MPoint is empty!" << endl;
|
|
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())
|
|
{
|
|
cout << "First Interval not found!"<< endl;
|
|
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 (checkPointN(pActRouteCurve, pUPoint.p1, true, dNewEndPos))
|
|
{
|
|
/*
|
|
End Found on same route like last ~ugpoint~
|
|
|
|
*/
|
|
if (((bMovingUp && aktUGPoint.GetUnitEndPos() <= dNewEndPos) ||
|
|
(!bMovingUp && aktUGPoint.GetUnitEndPos() >= dNewEndPos)) &&
|
|
(fabs(aktUGPoint.Speed() -
|
|
((fabs(aktUGPoint.GetUnitEndPos() - dNewEndPos))/
|
|
((pUPoint.timeInterval.end -
|
|
pUPoint.timeInterval.start).ToDouble()/0.00001157))) < 0.01))
|
|
{
|
|
/*
|
|
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.ShortestPath(&end,gl))
|
|
{
|
|
cout << "One unit couldn't be mapped to the network." << endl;
|
|
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)
|
|
{
|
|
cout << "MPoint lost Network! Translation stopped!" << endl;
|
|
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;
|
|
}
|
|
|
|
const string OpMPoint2MGPointSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
|
|
"\"Example\" ) "
|
|
"( <text>network x mpoint -> mgpoint" "</text--->"
|
|
"<text>mpoint2mgpoint(Networkobject, mpoint)</text--->"
|
|
"<text>Finds a path in a network for a moving point.</text--->"
|
|
"<text>mpoint2mgpoint(B_NETWORK, x)</text--->"
|
|
") )";
|
|
|
|
Operator mpoint2mgpoint (
|
|
"mpoint2mgpoint", // name
|
|
OpMPoint2MGPointSpec, // specification
|
|
OpMPoint2MGPointValueMappingNeu, // value mapping
|
|
Operator::SimpleSelect, // trivial selection function
|
|
OpMPoint2MGPointTypeMap // type mapping
|
|
);
|
|
|
|
/*
|
|
5.2 Operator ~passes~
|
|
|
|
Returns true if a ~MGPoint~ passes a given ~GPoint~ or ~GLine~.
|
|
|
|
*/
|
|
|
|
ListExpr OpPassesTypeMap( ListExpr args )
|
|
{
|
|
ListExpr arg1, arg2;
|
|
if ( nl->ListLength( args ) == 2 )
|
|
{
|
|
arg1 = nl->First( args );
|
|
arg2 = nl->Second( args );
|
|
|
|
if ( nl->IsAtom(arg1) && nl->AtomType(arg1) == SymbolType &&
|
|
nl->SymbolValue(arg1) == "mgpoint" ) {
|
|
if (nl->IsAtom(arg2) && nl->AtomType(arg2) == SymbolType &&
|
|
(nl->SymbolValue(arg2) == "gpoint" ||
|
|
nl->SymbolValue(arg2) == "gline")){
|
|
return (nl->SymbolAtom(CcBool::BasicType()));
|
|
}
|
|
}
|
|
}
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
int OpPasses_mgpgp(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->GetNoComponents() < 1 ||
|
|
!pMGPoint->IsDefined()) {
|
|
cerr << "MGPoint not Defined" << endl;
|
|
pPasses->Set(false, false);
|
|
return 0;
|
|
}
|
|
GPoint* pGPoint = (GPoint*)args[1].addr;
|
|
if(pGPoint == NULL || !pGPoint->IsDefined()) {
|
|
cerr << "GPoint not Defined" << endl;
|
|
pPasses->Set(false, false);
|
|
return 0;
|
|
}
|
|
pPasses->Set(true, pMGPoint->Passes(pGPoint));
|
|
return 0;
|
|
};
|
|
|
|
int OpPasses_mgpgl(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->GetNoComponents() < 1 ||
|
|
!pMGPoint->IsDefined()) {
|
|
cerr << "MGPoint does not exist." << endl;
|
|
pPasses->Set(false, false);
|
|
return 0;
|
|
}
|
|
GLine* pGLine = (GLine*)args[1].addr;
|
|
if(pGLine == NULL || !pGLine->IsDefined()) {
|
|
cerr << "GLine does not exist." << endl;
|
|
pPasses->Set(false, false);
|
|
return 0;
|
|
}
|
|
pPasses->Set(true, pMGPoint->Passes(pGLine));
|
|
return 0;
|
|
};
|
|
|
|
ValueMapping OpPassesvaluemap[] = {
|
|
OpPasses_mgpgp,
|
|
OpPasses_mgpgl
|
|
};
|
|
|
|
int OpPassesSelect( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
ListExpr arg2 = nl->Second( args );
|
|
|
|
if ( nl->SymbolValue(arg1) == "mgpoint" &&
|
|
nl->SymbolValue(arg2) == "gpoint")
|
|
return 0;
|
|
if ( nl->SymbolValue(arg1) == "mgpoint" &&
|
|
nl->SymbolValue(arg2) == "gline")
|
|
return 1;
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
const string OpPassesSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint x A -> bool for A gpoint or gline " "</text--->"
|
|
"<text>_ passes _</text--->"
|
|
"<text>Checks whether a moving point passes a gpoint or a gline.</text--->"
|
|
"<text>X_MGPOINT passes X_GPOINT </text--->"
|
|
") )";
|
|
|
|
Operator tempnetpasses (
|
|
"passes",
|
|
OpPassesSpec,
|
|
2,
|
|
OpPassesvaluemap,
|
|
OpPassesSelect,
|
|
OpPassesTypeMap );
|
|
|
|
|
|
/*
|
|
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)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 2 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMPointDesc = nl->First(in_xArgs);
|
|
ListExpr xEpsilonDesc = nl->Second(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMPointDesc )) ||
|
|
nl->AtomType( xMPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMPointDesc ) != "mgpoint" )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
if( (!nl->IsAtom( xEpsilonDesc)) ||
|
|
nl->AtomType( xEpsilonDesc ) != SymbolType ||
|
|
nl->SymbolValue( xEpsilonDesc ) != CcReal::BasicType() )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
return nl->SymbolAtom( "mgpoint" );
|
|
}
|
|
|
|
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->GetNoComponents() == 0)
|
|
{
|
|
string strMessage = "MGPoint is Empty.";
|
|
cerr << endl << strMessage << endl << endl;
|
|
pMGPoint->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pMGPoint->Simplify(dEpsilon, pMGPointSimplified);
|
|
return 0;
|
|
}
|
|
|
|
const string OpSimplifySpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint x real -> mgpoint" "</text--->"
|
|
"<text>simplify(0.0001, mgpoint)</text--->"
|
|
"<text>Removes unecessary units from a mgpoint.</text--->"
|
|
"<text>simplify(0.0001, mgpoint)</text--->"
|
|
") )";
|
|
|
|
Operator simplify("simplify",
|
|
OpSimplifySpec,
|
|
OpSimplifyValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpSimplifyTypeMap );
|
|
|
|
|
|
/*
|
|
5.4 Operator ~at~
|
|
|
|
Restricts the ~MGPoint~ to the times it was at a given ~GPoint~ or ~GLine~.
|
|
|
|
*/
|
|
|
|
ListExpr OpAtTypeMap(ListExpr in_xArgs)
|
|
{
|
|
ListExpr arg1, arg2;
|
|
if ( nl->ListLength( in_xArgs ) == 2 )
|
|
{
|
|
arg1 = nl->First( in_xArgs );
|
|
arg2 = nl->Second( in_xArgs );
|
|
|
|
if ( nl->IsAtom(arg1) && nl->AtomType(arg1) == SymbolType &&
|
|
nl->SymbolValue(arg1) == "mgpoint" ) {
|
|
if (nl->IsAtom(arg2) && nl->AtomType(arg2) == SymbolType &&
|
|
(nl->SymbolValue(arg2) == "gpoint" ||
|
|
nl->SymbolValue(arg2) == "gline")){
|
|
return (nl->SymbolAtom("mgpoint"));
|
|
}
|
|
}
|
|
}
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
int OpAt_mgpgp(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->GetNoComponents() < 1 ||
|
|
!pMGPoint->IsDefined()) {
|
|
cerr << "MGPoint not Defined" << endl;
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
GPoint* pGPoint = (GPoint*)args[1].addr;
|
|
if(pGPoint == NULL || !pGPoint->IsDefined()) {
|
|
cerr << "GPoint not Defined" << endl;
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pMGPoint->At(pGPoint, pResult);
|
|
return 0;
|
|
};
|
|
|
|
|
|
|
|
int OpAt_mgpgl(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->GetNoComponents() < 1 ||
|
|
!pMGPoint->IsDefined()) {
|
|
cerr << "MGPoint does not exist." << endl;
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
GLine* pGLine = (GLine*)args[1].addr;
|
|
if(pGLine == NULL || !pGLine->IsDefined() || pGLine->NoOfComponents() <= 0) {
|
|
cerr << "GLine does not exist or is empty." << endl;
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pMGPoint->At(pGLine, pResult);
|
|
return 0;
|
|
};
|
|
|
|
ValueMapping OpAtValueMap[] = {
|
|
OpAt_mgpgp,
|
|
OpAt_mgpgl
|
|
};
|
|
|
|
int OpAtSelect( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
ListExpr arg2 = nl->Second( args );
|
|
|
|
if ( nl->SymbolValue(arg1) == "mgpoint" &&
|
|
nl->SymbolValue(arg2) == "gpoint")
|
|
return 0;
|
|
if ( nl->SymbolValue(arg1) == "mgpoint" &&
|
|
nl->SymbolValue(arg2) == "gline")
|
|
return 1;
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
const string OpAtSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint x A -> mgpoint if A is gpoint or gline" "</text--->"
|
|
"<text> _ at _ </text--->"
|
|
"<text>Restricts the moving gpoint to the times he was at"
|
|
" the gpoint or gline.</text--->"
|
|
"<text> X_MGPOINT at X_GPOINT</text--->"
|
|
") )";
|
|
|
|
Operator tempnetat("at",
|
|
OpAtSpec,
|
|
2,
|
|
OpAtValueMap,
|
|
OpAtSelect,
|
|
OpAtTypeMap );
|
|
|
|
/*
|
|
5.5 Operator ~atinstant~
|
|
|
|
Restricts the ~MGPoint~ to a given time instant.
|
|
|
|
*/
|
|
|
|
ListExpr OpAtinstantTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 2 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMGPointDesc = nl->First(in_xArgs);
|
|
ListExpr xInstant = nl->Second(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMGPointDesc )) ||
|
|
nl->AtomType( xMGPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMGPointDesc ) != "mgpoint" )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
if (!nl->IsEqual( xInstant, Instant::BasicType() ))
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
return nl->SymbolAtom("igpoint");
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
const string OpAtinstantSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint x instant -> igpoint" "</text--->"
|
|
"<text> _ atinstant _</text--->"
|
|
"<text>Computes the position of a moving gpoint at a given instant.</text--->"
|
|
"<text>X_MGPOINT atinstant TIME </text--->"
|
|
") )";
|
|
|
|
Operator tempnetatinstant("atinstant",
|
|
OpAtinstantSpec,
|
|
OpAtinstantValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpAtinstantTypeMap );
|
|
|
|
|
|
/*
|
|
5.6 Operator ~atperiods~
|
|
|
|
Restricts a ~MGPoint~ to the given periods.
|
|
|
|
*/
|
|
|
|
ListExpr OpAtperiodsTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 2 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMGPointDesc = nl->First(in_xArgs);
|
|
ListExpr xPeriods = nl->Second(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMGPointDesc )) ||
|
|
nl->AtomType( xMGPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMGPointDesc ) != "mgpoint" )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
if (!nl->IsEqual( xPeriods, Periods::BasicType() ))
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
return nl->SymbolAtom("mgpoint");
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
const string OpAtperiodsSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint x periods -> mgpoint" "</text--->"
|
|
"<text> _ atperiods _</text--->"
|
|
"<text>Restricts the moving gpoint to the given periods.</text--->"
|
|
"<text>X_MGPOINT atperiods PERIODS </text--->"
|
|
") )";
|
|
|
|
Operator tempnetatperiods("atperiods",
|
|
OpAtperiodsSpec,
|
|
OpAtperiodsValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpAtperiodsTypeMap );
|
|
|
|
|
|
/*
|
|
5.7 Operator ~deftime~
|
|
|
|
Returns the deftime of a ~MGPoint~ respectively a ~ugpoint~ as ~periods~ value.
|
|
|
|
*/
|
|
|
|
ListExpr OpDeftimeTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMGPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (nl->IsAtom( xMGPointDesc )) &&
|
|
nl->AtomType( xMGPointDesc ) == SymbolType &&
|
|
(nl->SymbolValue( xMGPointDesc ) == "mgpoint" ||
|
|
nl->SymbolValue( xMGPointDesc ) == "ugpoint"))
|
|
{
|
|
return (nl->SymbolAtom( Periods::BasicType() ));
|
|
}
|
|
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
int OpDeftime_ugp(Word* args, Word& result, int message,
|
|
Word& local, Supplier in_xSupplier) {
|
|
Periods* pResult = (Periods*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pResult );
|
|
UGPoint* pUGP = (UGPoint*) args[0].addr;
|
|
pResult->Clear();
|
|
if (!pUGP->IsDefined()) {
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
pUGP->Deftime(*pResult);
|
|
return 0;
|
|
}
|
|
|
|
int OpDeftime_mgp(Word* args, Word& result, int message, Word& local,
|
|
Supplier in_xSupplier) {
|
|
Periods* res = (Periods*) qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord(res);
|
|
MGPoint* pMGP = (MGPoint*) args[0].addr;
|
|
if (!pMGP->IsDefined() || pMGP->GetNoComponents() == 0) {
|
|
res->Clear();
|
|
res->SetDefined(false);
|
|
return 0;
|
|
} else {
|
|
pMGP->Deftime(*res);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int OpDeftimeSelect(ListExpr args) {
|
|
ListExpr arg = nl->First(args);
|
|
if ( nl->SymbolValue(arg) == "mgpoint")
|
|
return 0;
|
|
if ( nl->SymbolValue(arg) == "ugpoint")
|
|
return 1;
|
|
return -1; // This point should never be reached
|
|
};
|
|
|
|
ValueMapping OpDeftimeValueMapping [] = {
|
|
OpDeftime_mgp,
|
|
OpDeftime_ugp
|
|
};
|
|
|
|
const string OpDeftimeSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>A -> periods if A is mgpoint or ugpoint" "</text--->"
|
|
"<text>deftime(_)</text--->"
|
|
"<text>Returns the periods in which the mgpoint is defined.</text--->"
|
|
"<text>deftime(mgpoint)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetdeftime("deftime",
|
|
OpDeftimeSpec,
|
|
2,
|
|
OpDeftimeValueMapping,
|
|
OpDeftimeSelect,
|
|
OpDeftimeTypeMap );
|
|
|
|
/*
|
|
5.8 Operator ~final~
|
|
|
|
Returns the final time and position of the ~MGPoint~ as ~IGPoint~
|
|
|
|
TypeMapping see operator ~final~.
|
|
|
|
*/
|
|
|
|
ListExpr OpFinalInitialTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMGPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMGPointDesc )) ||
|
|
nl->AtomType( xMGPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMGPointDesc ) != "mgpoint" )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
return nl->SymbolAtom("igpoint");
|
|
}
|
|
|
|
const string OpFinalSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint -> igpoint" "</text--->"
|
|
"<text> final (_)</text--->"
|
|
"<text>Computes the final instant of a moving gpoint.</text--->"
|
|
"<text>final (C_MGPOINT)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetfinal("final",
|
|
OpFinalSpec,
|
|
MappingFinal<MGPoint,UGPoint, GPoint>,
|
|
Operator::SimpleSelect,
|
|
OpFinalInitialTypeMap );
|
|
|
|
|
|
/*
|
|
5.9 Operator ~initial~
|
|
|
|
Returns the start point and time of the ~MGPoint~ as ~IGPoint~.
|
|
|
|
*/
|
|
|
|
const string OpInitialSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint -> igpoint" "</text--->"
|
|
"<text> initial (_)</text--->"
|
|
"<text>Computes the initial position of a moving gpoint.</text--->"
|
|
"<text>initial (C_MGPOINT)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetinitial("initial",
|
|
OpInitialSpec,
|
|
MappingInitial<MGPoint, UGPoint, GPoint>,
|
|
Operator::SimpleSelect,
|
|
OpFinalInitialTypeMap );
|
|
|
|
/*
|
|
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)
|
|
{
|
|
ListExpr arg1, arg2;
|
|
if ( nl->ListLength( in_xArgs ) == 2 )
|
|
{
|
|
arg1 = nl->First( in_xArgs );
|
|
arg2 = nl->Second( in_xArgs );
|
|
|
|
if ( nl->IsAtom(arg1) && nl->AtomType(arg1) == SymbolType &&
|
|
nl->SymbolValue(arg1) == "mgpoint" && nl->IsAtom(arg2) &&
|
|
nl->AtomType(arg2) == SymbolType && nl->SymbolValue(arg2) == "gline"){
|
|
return (nl->SymbolAtom(MBool::BasicType()));
|
|
}
|
|
}
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
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->GetNoComponents() < 1 ||
|
|
!pMGPoint->IsDefined()) {
|
|
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;
|
|
};
|
|
|
|
|
|
const string OpTInsideSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint x gline -> mbool" "</text--->"
|
|
"<text> _ inside _ </text--->"
|
|
"<text>Returns true for the times the mgpoint is at the gline."
|
|
" False elsewhere.</text--->"
|
|
"<text> X_MGPOINT inside GLINE</text--->"
|
|
") )";
|
|
|
|
Operator tempnetinside("inside",
|
|
OpTInsideSpec,
|
|
OpInsideValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpInsideTypeMapping );
|
|
|
|
|
|
/*
|
|
5.11 Operator ~inst~
|
|
|
|
Returns the time instant of the ~IGPoint~
|
|
|
|
*/
|
|
|
|
ListExpr OpInstTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xIGPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xIGPointDesc )) ||
|
|
nl->AtomType( xIGPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xIGPointDesc ) != "igpoint" )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
return nl->SymbolAtom( Instant::BasicType() );
|
|
}
|
|
|
|
const string OpInstSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>igpoint -> instant" "</text--->"
|
|
"<text>inst(igpoint)</text--->"
|
|
"<text>Returns the timeinstant value of the igpoint.</text--->"
|
|
"<text>inst(igpoint)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetinst("inst",
|
|
OpInstSpec,
|
|
IntimeInst<GPoint>,
|
|
Operator::SimpleSelect,
|
|
OpInstTypeMap );
|
|
|
|
/*
|
|
5.12 Operator ~intersection~
|
|
|
|
Computes a ~MGPoint~ representing the intersection of two ~MGPoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpIntersectionTypeMapping(ListExpr in_xArgs)
|
|
{
|
|
ListExpr arg1, arg2;
|
|
if( nl->ListLength(in_xArgs) == 2 ){
|
|
arg1 = nl->First(in_xArgs);
|
|
arg2 = nl->Second(in_xArgs);
|
|
if (nl->IsAtom(arg1) && nl->AtomType(arg1) == SymbolType &&
|
|
nl->SymbolValue(arg1) == "mgpoint" && nl->IsAtom(arg2) &&
|
|
nl->AtomType(arg2) == SymbolType &&
|
|
nl->SymbolValue(arg2) == "mgpoint"){
|
|
return (nl->SymbolAtom("mgpoint"));
|
|
}
|
|
}
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
const string OpIntersectionSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint x mgpoint -> mgpoint" "</text--->"
|
|
"<text>intersection(mgpoint, mgpoint)</text--->"
|
|
"<text>Returns a moving gpoint representing the intersection of the two "
|
|
" given moving gpoint.</text--->"
|
|
"<text>intersection(mgpoint, mgpoint)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetintersection("intersection",
|
|
OpIntersectionSpec,
|
|
OpIntersectionValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpIntersectionTypeMapping );
|
|
|
|
/*
|
|
5.12 Operator ~intersects~
|
|
|
|
Returns true if a intersection of the two ~MGPoint~ exists.
|
|
|
|
*/
|
|
|
|
ListExpr OpIntersectsTypeMapping(ListExpr in_xArgs)
|
|
{
|
|
ListExpr arg1, arg2;
|
|
if( nl->ListLength(in_xArgs) == 2 ){
|
|
arg1 = nl->First(in_xArgs);
|
|
arg2 = nl->Second(in_xArgs);
|
|
if (nl->IsAtom(arg1) && nl->AtomType(arg1) == SymbolType &&
|
|
nl->SymbolValue(arg1) == "mgpoint" && nl->IsAtom(arg2) &&
|
|
nl->AtomType(arg2) == SymbolType &&
|
|
nl->SymbolValue(arg2) == "mgpoint"){
|
|
return (nl->SymbolAtom(CcBool::BasicType()));
|
|
}
|
|
}
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
const string OpIntersectsSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint x mgpoint -> bool" "</text--->"
|
|
"<text>mgpoint intersects mgpoint</text--->"
|
|
"<text>Returns true if the mgpoint meet at any point, false"
|
|
" otherwise.</text--->"
|
|
"<text>mgpoint intersects mgpoint</text--->"
|
|
") )";
|
|
|
|
Operator tempnetintersects("intersects",
|
|
OpIntersectsSpec,
|
|
OpIntersectsValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpIntersectsTypeMapping );
|
|
|
|
/*
|
|
5.13 Operator ~isempty~
|
|
|
|
Returns true if the ~MGPoint~ has no units.
|
|
|
|
*/
|
|
|
|
ListExpr OpIsEmptyTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMGPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMGPointDesc )) ||
|
|
nl->AtomType( xMGPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMGPointDesc ) != "mgpoint" )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
return nl->SymbolAtom(CcBool::BasicType());
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
const string OpIsEmptySpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint -> bool" "</text--->"
|
|
"<text> isemtpy (_) </text--->"
|
|
"<text>Returns true if the moving gpoint is empty, false elsewhere.</text--->"
|
|
"<text>isempty (MGPOINT) </text--->"
|
|
") )";
|
|
|
|
Operator tempnetisempty("isempty",
|
|
OpIsEmptySpec,
|
|
OpIsEmptyValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpIsEmptyTypeMap );
|
|
|
|
/*
|
|
5.14 Operator ~length~
|
|
|
|
Returns the length of the trip of the ~MGPoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpLengthTypeMapping(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMGPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMGPointDesc )) ||
|
|
nl->AtomType( xMGPointDesc ) != SymbolType ||(
|
|
nl->SymbolValue( xMGPointDesc ) != "mgpoint" &&
|
|
nl->SymbolValue (xMGPointDesc) != "ugpoint"))
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
return nl->SymbolAtom( CcReal::BasicType() );
|
|
}
|
|
|
|
int OpLength_mgp(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
result = qp->ResultStorage(in_xSupplier);
|
|
CcReal* pResult = (CcReal*) result.addr;
|
|
// Get input value
|
|
MGPoint* pMGPoint = (MGPoint*)args[0].addr;
|
|
if(pMGPoint == NULL || pMGPoint->GetNoComponents() < 1 ||
|
|
!pMGPoint->IsDefined()) {
|
|
cmsg.inFunError("MGPoint does not exist.");
|
|
pResult->Set(false, 0.0);
|
|
return 0;
|
|
}
|
|
pResult-> Set(true, pMGPoint->Length());
|
|
return 1;
|
|
}
|
|
|
|
int OpLength_ugp(Word* args,
|
|
Word& result,
|
|
int message,
|
|
Word& local,
|
|
Supplier in_xSupplier)
|
|
{
|
|
result = qp->ResultStorage(in_xSupplier);
|
|
CcReal* pResult = (CcReal*) result.addr;
|
|
// Get input value
|
|
UGPoint* pUGPoint = (UGPoint*)args[0].addr;
|
|
if(pUGPoint == NULL || !pUGPoint->IsDefined()) {
|
|
cmsg.inFunError("UGPoint does not exist.");
|
|
pResult->Set(false, 0.0);
|
|
return 0;
|
|
}
|
|
pResult-> Set(true, pUGPoint->Length());
|
|
return 1;
|
|
}
|
|
|
|
const string OpTLengthSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint -> real, ugpoint -> real" "</text--->"
|
|
"<text>length(xgpoint)</text--->"
|
|
"<text>Returns the length of the path passed by a m(u)gpoint.</text--->"
|
|
"<text>length(xgpoint)</text--->"
|
|
") )";
|
|
|
|
int OpLengthSelect(ListExpr args){
|
|
ListExpr arg1 = nl->First( args );
|
|
|
|
if ( nl->SymbolValue(arg1) == "mgpoint")
|
|
return 0;
|
|
if ( nl->SymbolValue(arg1) == "ugpoint")
|
|
return 1;
|
|
return -1; // This point should never be reached
|
|
};
|
|
|
|
ValueMapping OpLengthValueMap[] = {
|
|
OpLength_mgp,
|
|
OpLength_ugp
|
|
};
|
|
|
|
Operator tempnetlength("length",
|
|
OpTLengthSpec,
|
|
2,
|
|
OpLengthValueMap,
|
|
OpLengthSelect,
|
|
OpLengthTypeMapping );
|
|
|
|
|
|
/*
|
|
5.15 Operator ~no\_components~
|
|
|
|
Returns the number of units of a ~MGPoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpNoCompTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMGPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMGPointDesc )) ||
|
|
nl->AtomType( xMGPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMGPointDesc ) != "mgpoint" )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
return nl->SymbolAtom(CcInt::BasicType());
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
const string OpNoCompSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint -> int" "</text--->"
|
|
"<text> no_components (_) </text--->"
|
|
"<text>Returns the number of components of the moving gpoint.</text--->"
|
|
"<text>no_components(MGPOINT) </text--->"
|
|
") )";
|
|
|
|
Operator tempnetnocomp("no_components",
|
|
OpNoCompSpec,
|
|
OpNoCompValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpNoCompTypeMap );
|
|
|
|
/*
|
|
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)
|
|
{
|
|
if( nl->ListLength(in_xArgs) == 2 ) {
|
|
ListExpr arg1 = nl->First(in_xArgs);
|
|
ListExpr arg2 = nl->Second(in_xArgs);
|
|
if( nl->IsEqual(arg1,"mgpoint") && (
|
|
nl->IsEqual(arg2,Instant::BasicType()) ||
|
|
nl->IsEqual(arg2, Periods::BasicType())))
|
|
return (nl->SymbolAtom( CcBool::BasicType() ));
|
|
}
|
|
return nl->SymbolAtom(Symbol::TYPEERROR());
|
|
}
|
|
|
|
int OpPresent_mgpi(Word* args, Word& result, int message,
|
|
Word& local,Supplier in_xSupplier){
|
|
CcBool* pPresent = (CcBool*)qp->ResultStorage(in_xSupplier).addr;
|
|
result = SetWord( pPresent );
|
|
MGPoint* pMGP = (MGPoint*)args[0].addr;
|
|
if(pMGP == NULL ||!pMGP->IsDefined()) {
|
|
cerr << "MGPoint does not exist." << endl;
|
|
pPresent->Set(false, false);
|
|
return 0;
|
|
}
|
|
Instant* ins = (Instant*)args[1].addr;
|
|
if(ins == NULL || !ins->IsDefined()) {
|
|
cerr << "Instant is not defined." << endl;
|
|
pPresent->Set(false, false);
|
|
return 0;
|
|
}
|
|
if (pMGP->GetNoComponents() < 1) {
|
|
pPresent->Set(true,false);
|
|
return 0;
|
|
}
|
|
pPresent->Set(true,pMGP->Present(ins));
|
|
return 0;
|
|
};
|
|
|
|
int OpPresent_mgpp(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
|
|
MGPoint* pMGPoint = (MGPoint*) args[0].addr;
|
|
if(pMGPoint == NULL){
|
|
cerr << "MGPoint == null." << endl;
|
|
pPresent->Set(false, false);
|
|
return 0;
|
|
}
|
|
if (!pMGPoint->IsDefined()) {
|
|
cerr << "MGPoint not defined." << endl;
|
|
pPresent->Set(false, false);
|
|
return 0;
|
|
}
|
|
Periods* pPeriods = (Periods*)args[1].addr;
|
|
if(pPeriods == NULL || !pPeriods->IsDefined()) {
|
|
cerr << "Periods does not exist." << endl;
|
|
pPresent->Set(false, false);
|
|
return 0;
|
|
}
|
|
if (pMGPoint->GetNoComponents() < 1 || pPeriods->IsEmpty()) {
|
|
pPresent->Set(true, false);
|
|
return 0;
|
|
}
|
|
pPresent->Set(true, pMGPoint->Present(pPeriods));
|
|
return 0;
|
|
}
|
|
|
|
int OpPresentSelect(ListExpr args){
|
|
ListExpr arg1 = nl->First( args );
|
|
ListExpr arg2 = nl->Second( args );
|
|
|
|
if ( nl->SymbolValue(arg1) == "mgpoint" &&
|
|
nl->SymbolValue( arg2) == Periods::BasicType() )
|
|
return 0;
|
|
if ( nl->SymbolValue(arg1) == "mgpoint" &&
|
|
nl->SymbolValue( arg2) == Instant::BasicType())
|
|
return 1;
|
|
return -1; // This point should never be reached
|
|
};
|
|
|
|
ValueMapping OpPresentValueMap[] = {
|
|
OpPresent_mgpp,
|
|
OpPresent_mgpi
|
|
};
|
|
|
|
const string OpPresentSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint x A -> bool with A = instant or periods" "</text--->"
|
|
"<text> _ present _</text--->"
|
|
"<text>Returns true if the moving gpoint at least once exists in the given "
|
|
"instant or one of the periods.</text--->"
|
|
"<text>X_MGPOINT present PERIODS </text--->"
|
|
") )";
|
|
|
|
Operator tempnetpresent(
|
|
"present",
|
|
OpPresentSpec,
|
|
2,
|
|
OpPresentValueMap,
|
|
OpPresentSelect,
|
|
OpPresentTypeMap );
|
|
|
|
|
|
/*
|
|
5.17 Operator ~val~
|
|
|
|
Returns the ~GPoint~ value of a ~IGPoint~
|
|
|
|
*/
|
|
|
|
ListExpr OpValTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xIGPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xIGPointDesc )) ||
|
|
nl->AtomType( xIGPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xIGPointDesc ) != "igpoint" )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
return nl->SymbolAtom( "gpoint" );
|
|
}
|
|
|
|
const string OpValSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>igpoint -> gpoint" "</text--->"
|
|
"<text>val(igpoint)</text--->"
|
|
"<text>Returns the gpoint value of the igpoint.</text--->"
|
|
"<text>val(igpoint)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetval("val",
|
|
OpValSpec,
|
|
IntimeVal<GPoint>,
|
|
Operator::SimpleSelect,
|
|
OpValTypeMap );
|
|
|
|
/*
|
|
5.18 Operator ~trajectory~
|
|
|
|
Returns the sorted ~GLine~ passed by a ~MGPoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpTrajectoryTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMGPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMGPointDesc )) ||
|
|
nl->AtomType( xMGPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMGPointDesc ) != "mgpoint" )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
return nl->SymbolAtom( "gline" );
|
|
}
|
|
|
|
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->GetNoComponents() < 1 ||
|
|
!pMGPoint->IsDefined()) {
|
|
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;
|
|
}
|
|
|
|
const string OpTrajectorySpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint -> gline" "</text--->"
|
|
"<text>trajectory(mgpoint)</text--->"
|
|
"<text>Calculates the trajectory for a moving gpoint.</text--->"
|
|
"<text>trajectory(mgpoint)</text--->"
|
|
") )";
|
|
|
|
Operator trajectory("trajectory",
|
|
OpTrajectorySpec,
|
|
OpTrajectoryValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpTrajectoryTypeMap );
|
|
|
|
/*
|
|
5.19 Operator ~units~
|
|
|
|
Returns the stream of ~UGPoint~ from the given ~MGPoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpUnitsTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMPointDesc )) ||
|
|
nl->AtomType( xMPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMPointDesc ) != "mgpoint" )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom("ugpoint"));
|
|
}
|
|
|
|
const string OpUnitsSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint -> (stream ugpoint)" "</text--->"
|
|
"<text>units(mgpoint)</text--->"
|
|
"<text>get the stream of units of the moving value.</text--->"
|
|
"<text>units(mgpoint)</text--->"
|
|
") )";
|
|
|
|
Operator units("units",
|
|
OpUnitsSpec,
|
|
MappingUnits<MGPoint, UGPoint>,
|
|
Operator::SimpleSelect,
|
|
OpUnitsTypeMap );
|
|
|
|
/*
|
|
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)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMGPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMGPointDesc )) ||
|
|
nl->AtomType( xMGPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMGPointDesc ) != "ugpoint" )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
return nl->SymbolAtom(CcReal::BasicType());
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
const string OpUnitEndPosSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>ugpoint -> double" "</text--->"
|
|
"<text> unitendpos (_)</text--->"
|
|
"<text>Returns the end position of a given ugpoint.</text--->"
|
|
"<text>unitendpos(UGPOINT)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetunitendpos("unitendpos",
|
|
OpUnitEndPosSpec,
|
|
OpUnitEndPosValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpUnitPosTimeTypeMap );
|
|
|
|
/*
|
|
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;
|
|
}
|
|
|
|
const string OpUnitStartPosSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>ugpoint -> double" "</text--->"
|
|
"<text> unitstartpos (_)</text--->"
|
|
"<text>Returns the start position of a given ugpoint.</text--->"
|
|
"<text>unitstartpos(UGPOINT)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetunitstartpos("unitstartpos",
|
|
OpUnitStartPosSpec,
|
|
OpUnitStartPosValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpUnitPosTimeTypeMap );
|
|
|
|
|
|
|
|
/*
|
|
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;
|
|
}
|
|
|
|
const string OpUnitEndTimeSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>ugpoint -> real" "</text--->"
|
|
"<text> unitendtime (_)</text--->"
|
|
"<text>Returns the double value representing the end time instant of the"
|
|
" given ugpoint.</text--->"
|
|
"<text>unitendtime(UGPOINT)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetunitendtime("unitendtime",
|
|
OpUnitEndTimeSpec,
|
|
OpUnitEndTimeValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpUnitPosTimeTypeMap );
|
|
|
|
|
|
/*
|
|
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;
|
|
}
|
|
|
|
const string OpUnitStartTimeSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>ugpoint -> real" "</text--->"
|
|
"<text> unitstarttime (_)</text--->"
|
|
"<text>Returns the double value representing the start time instant of the"
|
|
" given ugpoint.</text--->"
|
|
"<text>unitstarttime(UGPOINT)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetunitstarttime("unitstarttime",
|
|
OpUnitStartTimeSpec,
|
|
OpUnitStartTimeValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpUnitPosTimeTypeMap );
|
|
|
|
/*
|
|
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;
|
|
}
|
|
|
|
const string OpUnitRidSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>ugpoint -> real" "</text--->"
|
|
"<text> unitrid (_)</text--->"
|
|
"<text>Returns the route id of a given ugpoint.</text--->"
|
|
"<text>unitrid(UGPOINT)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetunitrid("unitrid",
|
|
OpUnitRidSpec,
|
|
OpUnitRidValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpUnitPosTimeTypeMap );
|
|
|
|
|
|
/*
|
|
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.
|
|
|
|
*/
|
|
|
|
ListExpr OpUnitBoxTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMGPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMGPointDesc )) ||
|
|
nl->AtomType( xMGPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMGPointDesc ) != "ugpoint" )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
return nl->SymbolAtom(Rectangle<3>::BasicType());
|
|
}
|
|
|
|
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->IsDefined()) box->SetDefined(false);
|
|
else (*box) = arg->NetBoundingBox3d();
|
|
return 0;
|
|
}
|
|
|
|
const string OpUnitBoxSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>ugpoint -> rect3" "</text--->"
|
|
"<text> unitbox (_)</text--->"
|
|
"<text>Returns the bounding box rectangle of the ugpoint in form: rid,"
|
|
" rid, min(startpos, endpos), max(startpos, endpos), timeInterval.start,"
|
|
" timeInterval.end. </text--->"
|
|
"<text>unitbox(UGPOINT)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetunitbox("unitbox",
|
|
OpUnitBoxSpec,
|
|
OpUnitBoxValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpUnitBoxTypeMap );
|
|
|
|
/*
|
|
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)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMGPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMGPointDesc )) ||
|
|
nl->AtomType( xMGPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMGPointDesc ) != "ugpoint" )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
return nl->SymbolAtom(Rectangle<2>::BasicType());
|
|
}
|
|
|
|
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->IsDefined()){
|
|
box->SetDefined(false);
|
|
} else {
|
|
(*box) = arg->NetBoundingBox2d();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const string OpUnitBox2Spec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>ugpoint -> rect2" "</text--->"
|
|
"<text> unitbox2 (_)</text--->"
|
|
"<text>Returns the bounding box rectangle of the ugpoint in form: rid,"
|
|
" rid, min(startpos, endpos), max(startpos, endpos). </text--->"
|
|
"<text>unitbox2(UGPOINT)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetunitbox2("unitbox2",
|
|
OpUnitBox2Spec,
|
|
OpUnitBox2ValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpUnitBox2TypeMap );
|
|
|
|
|
|
/*
|
|
5.27 Operator ~unitboundingbox~
|
|
|
|
Returns the spatialtemporal bounding box of the ~ugpoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpUnitBoundingBoxTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMGPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMGPointDesc )) ||
|
|
nl->AtomType( xMGPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMGPointDesc ) != "ugpoint" )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
return nl->SymbolAtom(Rectangle<3>::BasicType());
|
|
}
|
|
|
|
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->IsDefined()){
|
|
box->SetDefined(false);
|
|
} else {
|
|
(*box) = arg->BoundingBox();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const string OpUnitBoundingBoxSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>ugpoint -> rect3" "</text--->"
|
|
"<text> unitboundingbox (_)</text--->"
|
|
"<text>Returns the spatialtemporal bounding box of the ugpoint. </text--->"
|
|
"<text>unitboundingbox(UGPOINT)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetunitboundingbox("unitboundingbox",
|
|
OpUnitBoundingBoxSpec,
|
|
OpUnitBoundingBoxValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpUnitBoundingBoxTypeMap );
|
|
|
|
/*
|
|
5.28 Operator ~mgpointboundingbox~
|
|
|
|
Returns the spatialtemporal bounding box of the ~ugpoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpMGPointBoundingBoxTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMGPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMGPointDesc )) ||
|
|
nl->AtomType( xMGPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMGPointDesc ) != "mgpoint" )
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
return nl->SymbolAtom(Rectangle<3>::BasicType());
|
|
}
|
|
|
|
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->IsDefined() || arg->GetNoComponents()<1){
|
|
box->SetDefined(false);
|
|
} else {
|
|
*box = arg->BoundingBox();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const string OpMGPointBoundingBoxSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint -> rect3" "</text--->"
|
|
"<text> mgpbbox (_)</text--->"
|
|
"<text>Returns the spatialtemporal bounding box of the mgpoint. </text--->"
|
|
"<text>mgpbbox(MGPOINT)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetmgpointboundingbox("mgpbbox",
|
|
OpMGPointBoundingBoxSpec,
|
|
OpMGPointBoundingBoxValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpMGPointBoundingBoxTypeMap );
|
|
|
|
|
|
/*
|
|
5.29 Operator ~mgpoint2mpoint~
|
|
|
|
Returns the ~mpoint~ value of the given ~MGPoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpMGPoint2MPointTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 ){
|
|
sendMessages("Expects a list of length 1.");
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
ListExpr xsource = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom(xsource)) ||
|
|
!nl->IsEqual(xsource, "mgpoint"))
|
|
{
|
|
sendMessages("Element must be of type mgpoint.");
|
|
return (nl->SymbolAtom(Symbol::TYPEERROR()));
|
|
}
|
|
return nl->SymbolAtom( MPoint::BasicType() );
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
const string OpMGPoint2MPointSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
|
|
"\"Example\" ) "
|
|
"( <text>mgpoint -> mpoint" "</text--->"
|
|
"<text>mgpoint2mpoint(MGPOINT)</text--->"
|
|
"<text>Returns the mpoint value of the mgpoint.</text--->"
|
|
"<text> mgpoint2mpoint(mgpoint) </text--->"
|
|
") )";
|
|
|
|
Operator tempnetmgpoint2mpoint (
|
|
"mgpoint2mpoint", // name
|
|
OpMGPoint2MPointSpec, // specification
|
|
OpMGPoint2MPointValueMapping, // value mapping
|
|
Operator::SimpleSelect, // selection function
|
|
OpMGPoint2MPointTypeMap // type mapping
|
|
);
|
|
|
|
|
|
|
|
/*
|
|
5.30 Operator ~distance~
|
|
|
|
Computes a mreal representing the Euclidean Distance between the two ~mgpoint~.
|
|
|
|
*/
|
|
|
|
ListExpr OpDistanceTypeMapping(ListExpr in_xArgs)
|
|
{
|
|
ListExpr arg1, arg2;
|
|
if( nl->ListLength(in_xArgs) == 2 ){
|
|
arg1 = nl->First(in_xArgs);
|
|
arg2 = nl->Second(in_xArgs);
|
|
if (nl->IsAtom(arg1) && nl->AtomType(arg1) == SymbolType &&
|
|
nl->SymbolValue(arg1) == "mgpoint" && nl->IsAtom(arg2) &&
|
|
nl->AtomType(arg2) == SymbolType &&
|
|
nl->SymbolValue(arg2) == "mgpoint")
|
|
{
|
|
return (nl->SymbolAtom(MReal::BasicType()));
|
|
}
|
|
}
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
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->GetNoComponents() < 1 ||
|
|
!pMGPoint1->IsDefined()) {
|
|
cerr << "First mgpoint does not exist." << endl;
|
|
pResult->SetDefined(false);
|
|
return 0;
|
|
}
|
|
MGPoint* pMGPoint2 = (MGPoint*)args[1].addr;
|
|
if(pMGPoint2 == NULL || pMGPoint2->GetNoComponents() < 1 ||
|
|
!pMGPoint2->IsDefined()) {
|
|
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;
|
|
}
|
|
|
|
const string OpDistanceSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint x mgpoint -> mreal" "</text--->"
|
|
"<text>distance(mgpoint, mgpoint)</text--->"
|
|
"<text>Returns a moving real representing the Euclidean Distance of the two "
|
|
" given moving gpoint.</text--->"
|
|
"<text>query distance(mgpoint, mgpoint)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetdistance("distance",
|
|
OpDistanceSpec,
|
|
OpDistanceValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpDistanceTypeMapping );
|
|
|
|
|
|
/*
|
|
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)
|
|
{
|
|
ListExpr arg1, arg2;
|
|
if ( nl->ListLength( in_xArgs ) == 2 )
|
|
{
|
|
arg1 = nl->First( in_xArgs );
|
|
arg2 = nl->Second( in_xArgs );
|
|
|
|
if ( nl->IsAtom(arg1) && nl->AtomType(arg1) == SymbolType &&
|
|
nl->SymbolValue(arg1) == "mgpoint" && nl->IsAtom(arg2) &&
|
|
nl->AtomType(arg2) == SymbolType &&
|
|
nl->SymbolValue(arg2) == "mgpoint"){
|
|
return (nl->SymbolAtom("mgpoint"));
|
|
}
|
|
}
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
|
|
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;
|
|
};
|
|
|
|
const string OpUnionSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mgpoint x mgpoint -> mgpoint" "</text--->"
|
|
"<text> _ union _ </text--->"
|
|
"<text>Returns the union of the two given mgpoint if possible,"
|
|
" undef elsewhere.</text--->"
|
|
"<text> X_MGPOINTA union X_MGPOINTB</text--->"
|
|
") )";
|
|
|
|
Operator tempnetunion("union",
|
|
OpUnionSpec,
|
|
OpUnionValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpUnionTypeMap );
|
|
|
|
/*
|
|
5.32 Operator ~endunitinst~
|
|
|
|
Returns the end time instant of a ~UGPoint~ as ~Instant~
|
|
|
|
*/
|
|
|
|
ListExpr OpEndStartunitinstTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMGPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMGPointDesc )) ||
|
|
nl->AtomType( xMGPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMGPointDesc ) != "ugpoint")
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
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;
|
|
};
|
|
|
|
const string OpEndunitinstSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>ugpoint -> instant" "</text--->"
|
|
"<text>endunitinst (_)</text--->"
|
|
"<text>Computes the final time instant of a ugpoint.</text--->"
|
|
"<text>endunitinst(UGPOINT)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetendunitinst("endunitinst",
|
|
OpEndunitinstSpec,
|
|
OpEndunitinstValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpEndStartunitinstTypeMap);
|
|
|
|
|
|
/*
|
|
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;
|
|
};
|
|
|
|
const string OpStartunitinstSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>ugpoint -> instant" "</text--->"
|
|
"<text> startunitinst (_)</text--->"
|
|
"<text>Computes the start time instant of a ugpoint.</text--->"
|
|
"<text>startunitinst (UGPOINT)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetstartunitinst("startunitinst",
|
|
OpStartunitinstSpec,
|
|
OpStartunitinstValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpEndStartunitinstTypeMap);
|
|
|
|
/*
|
|
5.34 Operator ~ugpoint2mgpoint~
|
|
|
|
Builds a ~MGPoint~ from a single ~UGPoint~
|
|
|
|
*/
|
|
|
|
ListExpr OpUgpoint2mgpointTypeMap(ListExpr in_xArgs)
|
|
{
|
|
if( nl->ListLength(in_xArgs) != 1 )
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
|
|
ListExpr xMGPointDesc = nl->First(in_xArgs);
|
|
|
|
if( (!nl->IsAtom( xMGPointDesc )) ||
|
|
nl->AtomType( xMGPointDesc ) != SymbolType ||
|
|
nl->SymbolValue( xMGPointDesc ) != "ugpoint")
|
|
{
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
|
}
|
|
return nl->SymbolAtom("mgpoint");
|
|
}
|
|
|
|
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;
|
|
};
|
|
|
|
const string OpUgpoint2mgpointSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>ugpoint -> mgpoint" "</text--->"
|
|
"<text>upgoint2mgpoint (_)</text--->"
|
|
"<text>Constructs a mgpoint consisting of the single ugpoint.</text--->"
|
|
"<text>ugpoint2mgpoint(UGPOINT)</text--->"
|
|
") )";
|
|
|
|
Operator tempnetugpoint2mgpoint("ugpoint2mgpoint",
|
|
OpUgpoint2mgpointSpec,
|
|
OpUgpoint2mgpointValueMapping,
|
|
Operator::SimpleSelect,
|
|
OpUgpoint2mgpointTypeMap);
|
|
|
|
/*
|
|
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");
|
|
if (stream.length() == 2 && stream.checkStream(mgp))
|
|
{
|
|
ListExpr retList;
|
|
nl->ReadFromString(mgpSecTypeInfo, retList);
|
|
return retList;
|
|
}
|
|
}
|
|
return NList::typeError( "Expected a stream of mgpsecunit.");
|
|
}
|
|
|
|
/*
|
|
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;
|
|
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 = "stream(mgpsecunit)-> stream(tuple((secid)..(flow))";
|
|
syntax = "_ mgp2mgpsecunits3 ( _ ) ";
|
|
meaning = "Builds a stream of mgpsecunits from a stream of mgpoint.";
|
|
}
|
|
};
|
|
|
|
/*
|
|
6 Creating the Algebra
|
|
|
|
*/
|
|
|
|
class TemporalNetAlgebra : public Algebra
|
|
{
|
|
public:
|
|
|
|
TemporalNetAlgebra() : Algebra()
|
|
{
|
|
AddTypeConstructor( &unitgpoint );
|
|
AddTypeConstructor( &movinggpoint );
|
|
AddTypeConstructor( &intimegpoint);
|
|
AddTypeConstructor( &mgpsecunitTC);
|
|
|
|
movinggpoint.AssociateKind( Kind::TEMPORAL() );
|
|
movinggpoint.AssociateKind( Kind::DATA() );
|
|
unitgpoint.AssociateKind( Kind::TEMPORAL() );
|
|
unitgpoint.AssociateKind( Kind::DATA() );
|
|
intimegpoint.AssociateKind(Kind::TEMPORAL());
|
|
intimegpoint.AssociateKind(Kind::DATA());
|
|
mgpsecunitTC.AssociateKind( Kind::DATA() );
|
|
|
|
AddOperator(&mpoint2mgpoint);
|
|
AddOperator(&units);
|
|
AddOperator(&simplify);
|
|
AddOperator(&tempnetpasses);
|
|
AddOperator(&trajectory);
|
|
AddOperator(&tempnetlength);
|
|
AddOperator(&tempnetatinstant);
|
|
AddOperator(&tempnetinitial);
|
|
AddOperator(&tempnetfinal);
|
|
AddOperator(&tempnetat);
|
|
AddOperator(&tempnetval);
|
|
AddOperator(&tempnetinst);
|
|
AddOperator(&tempnetatperiods);
|
|
AddOperator(&tempnetpresent);
|
|
AddOperator(&tempnetisempty);
|
|
AddOperator(&tempnetnocomp);
|
|
AddOperator(&tempnetinside);
|
|
AddOperator(&tempnetintersection);
|
|
AddOperator(&tempnetdeftime);
|
|
AddOperator(&tempnetunitrid);
|
|
AddOperator(&tempnetunitstartpos);
|
|
AddOperator(&tempnetunitendpos);
|
|
AddOperator(&tempnetunitstarttime);
|
|
AddOperator(&tempnetunitendtime);
|
|
AddOperator(&tempnetunitbox);
|
|
AddOperator(&tempnetunitbox2);
|
|
AddOperator(&tempnetunitboundingbox);
|
|
AddOperator(&tempnetmgpointboundingbox);
|
|
AddOperator(&tempnetmgpoint2mpoint);
|
|
AddOperator(&tempnetdistance);
|
|
AddOperator(&tempnetunion);
|
|
AddOperator(&tempnetstartunitinst);
|
|
AddOperator(&tempnetendunitinst);
|
|
AddOperator(&tempnetugpoint2mgpoint);
|
|
AddOperator(&tempnetintersects);
|
|
AddOperator(mgp2mgpsecunitsInfo(), OpMgp2mgpsecunitsValueMap,
|
|
OpMgp2mgpsecunitsTypeMap);
|
|
AddOperator(mgp2mgpsecunits2Info(), OpMgp2mgpsecunits2ValueMap,
|
|
OpMgp2mgpsecunits2TypeMap);
|
|
AddOperator(mgp2mgpsecunits3Info(), OpMgp2mgpsecunits3ValueMap,
|
|
OpMgp2mgpsecunits3TypeMap);
|
|
AddOperator(mgpsu2tupleInfo(), OpMgpsu2tupleValueMap, OpMgpsu2tupleTypeMap);
|
|
}
|
|
|
|
|
|
~TemporalNetAlgebra() {delete netList;};
|
|
};
|
|
|
|
/*
|
|
Initialization
|
|
|
|
Each algebra module needs an initialization function. The algebra manager
|
|
has a reference to this function if this algebra is included in the list
|
|
of required algebras, thus forcing the linker to include this module.
|
|
|
|
The algebra manager invokes this function to get a reference to the instance
|
|
of the algebra class and to provide references to the global nested list
|
|
container (used to store constructor, type, operator and object information)
|
|
and to the query processor.
|
|
|
|
The function has a C interface to make it possible to load the algebra
|
|
dynamically at runtime.
|
|
|
|
*/
|
|
|
|
extern "C" Algebra* InitializeTemporalNet2Algebra( NestedList* in_pNL,
|
|
QueryProcessor* in_pQP )
|
|
{
|
|
nl = in_pNL;
|
|
qp = in_pQP;
|
|
netList = new map<int,string>();
|
|
return (new TemporalNetAlgebra());
|
|
}
|