6518 lines
177 KiB
C++
6518 lines
177 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
|
||
|
|
----
|
||
|
|
|
||
|
|
0 TODO
|
||
|
|
|
||
|
|
|
||
|
|
1 Includes and Initializationtemporallocationsext
|
||
|
|
|
||
|
|
Place for initialization of pointer variables, constants and namespaces and
|
||
|
|
inclusion of header files concerning Secondo.
|
||
|
|
|
||
|
|
*/
|
||
|
|
#include <set>
|
||
|
|
#include <time.h>
|
||
|
|
#include <vector>
|
||
|
|
#include <map>
|
||
|
|
#include <cmath>
|
||
|
|
#include "Algebra.h"
|
||
|
|
#include "NestedList.h"
|
||
|
|
#include "QueryProcessor.h"
|
||
|
|
#include "StandardTypes.h"
|
||
|
|
#include "Algebras/Spatial/SpatialAlgebra.h"
|
||
|
|
#include "Algebras/Temporal/TemporalAlgebra.h"
|
||
|
|
#include "Algebras/MovingRegion/MovingRegionAlgebra.h"
|
||
|
|
#include "DateTime.h"
|
||
|
|
#include "TemporalExtAlgebra.h"
|
||
|
|
#include "Algebras/Temporal/RefinementStream.h"
|
||
|
|
#include "Algebras/Geoid/Geoid.h"
|
||
|
|
#include "Algebras/SymbolicTrajectoryBasic/SymbolicTrajectoryBasicAlgebra.h"
|
||
|
|
#include "Algebras/RTree/RTreeAlgebra.h"
|
||
|
|
|
||
|
|
extern NestedList* nl;
|
||
|
|
extern QueryProcessor *qp;
|
||
|
|
|
||
|
|
#include "TypeMapUtils.h"
|
||
|
|
#include "Symbols.h"
|
||
|
|
#include "ListUtils.h"
|
||
|
|
|
||
|
|
using namespace mappings;
|
||
|
|
using namespace std;
|
||
|
|
using namespace datetime;
|
||
|
|
|
||
|
|
|
||
|
|
namespace temporalalgebra{
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
2 Type definitions, Auxiliary Functions
|
||
|
|
|
||
|
|
2.1 Global variable for unit of time: milliseconds [*] FactorForUnitOfTime
|
||
|
|
FactorForUnitOfTime = 1. (default)
|
||
|
|
|
||
|
|
*/
|
||
|
|
double FactorForUnitOfTime = 1.;
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.2 Global variable for unit of distance: meter [*] FactorForUnitOfDistance
|
||
|
|
FactorForUnitOfDistance = 1. (default)
|
||
|
|
|
||
|
|
*/
|
||
|
|
double FactorForUnitOfDistance = 1.;
|
||
|
|
|
||
|
|
struct USegments
|
||
|
|
{
|
||
|
|
int unit_nr;
|
||
|
|
Interval<Instant> unit_interval;
|
||
|
|
vector<MSegmentData> sgms;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct GroupOfIntervals
|
||
|
|
{
|
||
|
|
int unit_nr;
|
||
|
|
Interval<Instant> str_inst;
|
||
|
|
};
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.3 Function: MinMaxValueFunction
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
utemp: pointer to UReal
|
||
|
|
minimum: a double (by reference)
|
||
|
|
maximum: a double (by reference)
|
||
|
|
|
||
|
|
Return: nothing
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
void MinMaxValueFunction(const UReal* utemp, double& minimum, double& maximum)
|
||
|
|
{
|
||
|
|
double ts, te, ts_value, te_value, a, b, c;
|
||
|
|
double t_extrem, t_extrem_value;
|
||
|
|
bool lh = utemp->timeInterval.lc;
|
||
|
|
bool rh = utemp->timeInterval.rc;
|
||
|
|
bool conv_conc = true;
|
||
|
|
|
||
|
|
|
||
|
|
ts = 0;
|
||
|
|
te = utemp->timeInterval.end.ToDouble()
|
||
|
|
- utemp->timeInterval.start.ToDouble();
|
||
|
|
|
||
|
|
a = utemp->a;
|
||
|
|
b = utemp->b;
|
||
|
|
c = utemp->c;
|
||
|
|
|
||
|
|
ts_value = c;
|
||
|
|
te_value = a*pow(te,2) + b*te + c;
|
||
|
|
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << endl << "Range: " << endl;
|
||
|
|
cout << "ts: " << ts << endl;
|
||
|
|
cout << "te: " << te << endl << endl;
|
||
|
|
cout << "ts_value: " << ts_value << endl;
|
||
|
|
cout << "te_value: " << te_value << endl << endl;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
if( utemp->a != 0 )
|
||
|
|
{
|
||
|
|
t_extrem = - b / ( 2 * a );
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << endl << "t_extrem = " << t_extrem << endl;
|
||
|
|
}
|
||
|
|
if( (!lh && !rh && ( t_extrem <= ts || t_extrem >= te ) ) ||
|
||
|
|
(lh && rh && ( t_extrem < ts || t_extrem > te) ) ||
|
||
|
|
(!lh && rh && ( t_extrem <= ts || t_extrem > te ) ) ||
|
||
|
|
(lh && !rh && ( t_extrem < ts || t_extrem >= te ) )
|
||
|
|
)
|
||
|
|
{
|
||
|
|
conv_conc = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
conv_conc = false;
|
||
|
|
|
||
|
|
if(conv_conc)
|
||
|
|
{
|
||
|
|
t_extrem_value = a*pow(t_extrem,2) + b*t_extrem + c;
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "t_extrem_value = " << t_extrem_value << endl;
|
||
|
|
}
|
||
|
|
/*
|
||
|
|
Find maximum
|
||
|
|
|
||
|
|
*/
|
||
|
|
maximum = ts_value;
|
||
|
|
if(t_extrem_value > maximum)
|
||
|
|
maximum = t_extrem_value;
|
||
|
|
if(te_value > maximum)
|
||
|
|
maximum = te_value;
|
||
|
|
|
||
|
|
/*
|
||
|
|
Find minimum
|
||
|
|
|
||
|
|
*/
|
||
|
|
minimum = ts_value;
|
||
|
|
if(t_extrem_value < minimum)
|
||
|
|
minimum = t_extrem_value;
|
||
|
|
if(te_value < minimum)
|
||
|
|
minimum = te_value;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << endl << "Ist NICHT conv_conc" << endl;
|
||
|
|
}
|
||
|
|
if(ts_value < te_value)
|
||
|
|
{
|
||
|
|
maximum = te_value;
|
||
|
|
minimum = ts_value;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
maximum = ts_value;
|
||
|
|
minimum = te_value;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << endl << "RETURN:" << endl;
|
||
|
|
cout << "minimum = " << minimum << endl;
|
||
|
|
cout << "maximum = " << maximum << endl << endl;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.4 Function timeIntervalOfRealInUReal
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
|
||
|
|
value: real value
|
||
|
|
ur: a pointer to the real unit
|
||
|
|
t\_value: time as double value to return (by reference)
|
||
|
|
|
||
|
|
Return:
|
||
|
|
|
||
|
|
bool: returns true, if val is contained in the ureal,
|
||
|
|
otherwise false.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
bool timeIntervalOfRealInUReal2(const double &value, const UReal* ur,
|
||
|
|
double& t_value)
|
||
|
|
{
|
||
|
|
Periods times(2);
|
||
|
|
Interval<Instant> invinst;
|
||
|
|
|
||
|
|
ur->PeriodsAtVal(value, times);
|
||
|
|
if ( times.GetNoComponents() < 2 ){
|
||
|
|
times.Get(0, invinst);
|
||
|
|
if ( invinst.start == invinst.end ){
|
||
|
|
t_value = invinst.start.ToDouble();
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool timeIntervalOfRealInUReal( const double &value, const UReal &ur,
|
||
|
|
double& t_value )
|
||
|
|
{
|
||
|
|
double unit_min, unit_max, ts, te;
|
||
|
|
bool lh, rh;
|
||
|
|
|
||
|
|
unit_min = ((URealExt*)(&ur))->GetUnitMin();
|
||
|
|
unit_max = ((URealExt*)(&ur))->GetUnitMax();
|
||
|
|
lh = ur.timeInterval.lc;
|
||
|
|
rh = ur.timeInterval.rc;
|
||
|
|
ts = (ur.timeInterval.start).ToDouble();
|
||
|
|
te = (ur.timeInterval.end).ToDouble();
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << endl << "GetUnitMin(): " << unit_min << endl;
|
||
|
|
cout << "GetUnitMax(): " << unit_max << endl;
|
||
|
|
cout << "Value: " << value << endl;
|
||
|
|
cout << "ts: " << ts << endl;
|
||
|
|
cout << "te: " << te << endl;
|
||
|
|
}
|
||
|
|
if( (!lh && !rh && ( value <= unit_min || value >= unit_max ) ) ||
|
||
|
|
(lh && rh && ( value < unit_min || value > unit_max) ) ||
|
||
|
|
(!lh && rh && ( value <= unit_min || value > unit_max ) ) ||
|
||
|
|
(lh && !rh && ( value < unit_min || value >= unit_max ) )
|
||
|
|
)
|
||
|
|
{
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "Value outside of the unit range!!!!" << endl;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(ur.a == 0 && ur.b != 0)
|
||
|
|
{
|
||
|
|
/*
|
||
|
|
Find value in a linear function
|
||
|
|
|
||
|
|
*/
|
||
|
|
t_value = ((value - ur.c) / ur.b) + ts;
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "---> value in a linear function" << endl;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(ur.a == 0 && ur.b == 0)
|
||
|
|
{
|
||
|
|
/*
|
||
|
|
Find value in a constant function
|
||
|
|
|
||
|
|
*/
|
||
|
|
t_value = ur.c;
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "---> value in a constant function" << endl;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/*
|
||
|
|
Find value in a quadratic function with Newtons Method
|
||
|
|
|
||
|
|
*/
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "---> value in a quadratic function" << endl;
|
||
|
|
}
|
||
|
|
|
||
|
|
double t_newton = te;
|
||
|
|
double t_newton_old;
|
||
|
|
double t, dt, t_newton_diff, t_var;
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "t_newton(Start) = " << t_newton << endl;
|
||
|
|
cout << "a = " << ur.a << endl;
|
||
|
|
cout << "b = " << ur.b << endl;
|
||
|
|
cout << "c = " << ur.c << endl;
|
||
|
|
}
|
||
|
|
do
|
||
|
|
{
|
||
|
|
t_newton_old = t_newton;
|
||
|
|
t_var = t_newton - ts;
|
||
|
|
if(ur.r)
|
||
|
|
{
|
||
|
|
t = sqrt(pow(t_var, 2)*ur.a + t_var*ur.b
|
||
|
|
+ ur.c - value);
|
||
|
|
dt = (1/2)*(1/sqrt(t)) + (2*ur.a*t_var + ur.b);
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "t = " << t << endl;
|
||
|
|
cout << "dt = " << dt << endl;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
t = pow(t_var, 2)*ur.a + t_var*ur.b + ur.c - value;
|
||
|
|
dt = 2*ur.a*t_var + ur.b;
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "t = " << t << endl;
|
||
|
|
cout << "dt = " << dt << endl;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
t_newton = t_newton - (t/dt);
|
||
|
|
t_newton_diff = abs(t_newton_old) - abs(t_newton);
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "t_newton = "
|
||
|
|
<< t_newton << endl;
|
||
|
|
cout << "t_newton_old = "
|
||
|
|
<< t_newton_old << endl;
|
||
|
|
cout << "t_newton_diff = "
|
||
|
|
<< t_newton_diff << endl;
|
||
|
|
}
|
||
|
|
}while(abs(t_newton_diff) > 0.0000001);
|
||
|
|
t_value = t_newton;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << endl << "x-Value = " << t_value << endl;
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.6 Function ~IntersectionRPExt~
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
mreg: a pointer to a MRegion
|
||
|
|
mp: a MPoint (by reference)
|
||
|
|
res: a MPoint for result (by reference)
|
||
|
|
rp: a reference to an object
|
||
|
|
RefinementStream<MRegion, MPoint, URegionEmb, UPoint>
|
||
|
|
merge: a boolean
|
||
|
|
|
||
|
|
Return: nothing
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
void IntersectionRPExt(
|
||
|
|
MRegion* mreg,
|
||
|
|
MPoint& mp,
|
||
|
|
MPoint& res,
|
||
|
|
RefinementStream<
|
||
|
|
MRegion,
|
||
|
|
MPoint,
|
||
|
|
URegionEmb,
|
||
|
|
UPoint>& rp,
|
||
|
|
bool merge)
|
||
|
|
{
|
||
|
|
res = 0;
|
||
|
|
UPoint* pending = 0;
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
For each interval in the refinement partition, we have to check whether
|
||
|
|
it maps to a region and point unit. If not, there is obviously no intersection
|
||
|
|
during this interval and we can skip if. Otherwise, we check if the region
|
||
|
|
and point unit, both restricted to this interval, intersect.
|
||
|
|
|
||
|
|
*/
|
||
|
|
while(rp.hasNext()){
|
||
|
|
Interval<Instant> iv;
|
||
|
|
int urPos;
|
||
|
|
int upPos;
|
||
|
|
|
||
|
|
rp.getNext( iv, urPos, upPos);
|
||
|
|
|
||
|
|
if (urPos == -1 || upPos == -1) continue;
|
||
|
|
|
||
|
|
URegionEmb ur;
|
||
|
|
UPoint up;
|
||
|
|
|
||
|
|
mreg->Get(urPos, ur);
|
||
|
|
mp.Get(upPos, up);
|
||
|
|
|
||
|
|
ur.RestrictedIntersection(
|
||
|
|
mreg->GetMSegmentData(), up, iv, res, pending, merge);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pending) {
|
||
|
|
if (!((abs(pending->timeInterval.start.ToDouble()-
|
||
|
|
pending->timeInterval.end.ToDouble()) <= 0.00001)
|
||
|
|
&& (!pending->timeInterval.lc
|
||
|
|
|| !pending->timeInterval.rc))) {
|
||
|
|
res.Add(*pending);
|
||
|
|
}
|
||
|
|
delete pending;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3 Implementation for methods of classes declared in header file
|
||
|
|
|
||
|
|
3.2 Method Locations of class MPointExt
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
|
||
|
|
result: a pointer to a Points object
|
||
|
|
|
||
|
|
Return: nothing
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
void MPointExt::Locations( Points* result ) const
|
||
|
|
{
|
||
|
|
if(0) {
|
||
|
|
cout << "MPointExt::Locations called!" << endl;
|
||
|
|
}
|
||
|
|
UPoint unitin;
|
||
|
|
vector<Point> points;
|
||
|
|
vector<HalfSegment> hsegments;
|
||
|
|
bool contained;
|
||
|
|
|
||
|
|
for(int i=0;i<GetNoComponents();i++) {
|
||
|
|
Get(i, unitin);
|
||
|
|
if(unitin.p0 == unitin.p1) {
|
||
|
|
points.push_back(unitin.p0);
|
||
|
|
} else {
|
||
|
|
HalfSegment temp_hs( false, unitin.p0, unitin.p1 );
|
||
|
|
hsegments.push_back(temp_hs);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
result->Clear();
|
||
|
|
result->StartBulkLoad();
|
||
|
|
for(size_t i=0;i<points.size();i++) {
|
||
|
|
contained = false;
|
||
|
|
for(size_t j=0;j<hsegments.size();j++) {
|
||
|
|
if(hsegments[j].Contains(points[i]))
|
||
|
|
contained = true;
|
||
|
|
}
|
||
|
|
if(!contained) {
|
||
|
|
if(0) {
|
||
|
|
cout << endl << "NOT CONTAINED!!!!!!!!!!!!!!!" << endl;
|
||
|
|
cout << "x=" << points[i].GetX() << endl;
|
||
|
|
cout << "y=" << points[i].GetY() << endl;
|
||
|
|
}
|
||
|
|
*result += points[i];
|
||
|
|
} else {
|
||
|
|
if(0) {
|
||
|
|
cout << endl << "CONTAINED!!!!!!!!!!!!!!!" << endl;
|
||
|
|
cout << "x=" << points[i].GetX() << endl;
|
||
|
|
cout << "y=" << points[i].GetY() << endl;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
result->EndBulkLoad( true );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.3 Method At of class MPointExt
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
|
||
|
|
pts: a pointer to a Points object
|
||
|
|
result: a reference to a MPoint object
|
||
|
|
|
||
|
|
Return: nothing
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
void MPointExt::At( Points* pts, MPoint &result ) const
|
||
|
|
{
|
||
|
|
UPoint unitin;
|
||
|
|
clock_t clock1, clock2, clock3, clock4, clock_ges;
|
||
|
|
double time1, time2;
|
||
|
|
|
||
|
|
result.Clear();
|
||
|
|
result.StartBulkLoad();
|
||
|
|
clock1 = clock();
|
||
|
|
clock_ges = 0;
|
||
|
|
for(int i=0;i<GetNoComponents();i++) {
|
||
|
|
clock3 = clock();
|
||
|
|
Get(i, unitin);
|
||
|
|
const Rectangle<3> temp_pbb = (Rectangle<3>)unitin.BoundingBox();
|
||
|
|
Rectangle<2> unit_pbb;
|
||
|
|
const Rectangle<2> obj_pbb = (Rectangle<2>)pts->BoundingBox();
|
||
|
|
if(0) {
|
||
|
|
cout << "Boundingbox of points: "
|
||
|
|
<< "MinD(0): " << obj_pbb.MinD(0)
|
||
|
|
<< ", MinD(1): " << obj_pbb.MinD(1)
|
||
|
|
<< ", MaxD(0): " << obj_pbb.MaxD(0)
|
||
|
|
<< ", MaxD(1): " << obj_pbb.MaxD(1) << endl;
|
||
|
|
|
||
|
|
}
|
||
|
|
double min[2] = { temp_pbb.MinD(0), temp_pbb.MinD(1) };
|
||
|
|
double max[2] = { temp_pbb.MaxD(0), temp_pbb.MaxD(1) };
|
||
|
|
|
||
|
|
unit_pbb.Set(true, min, max);
|
||
|
|
if(unit_pbb.Intersects( obj_pbb )) {
|
||
|
|
for(int j=0;j<pts->Size();j++) {
|
||
|
|
Point tmp_pt;
|
||
|
|
pts->Get( j, tmp_pt );
|
||
|
|
if( unitin.Passes( tmp_pt ) ) {
|
||
|
|
if(0) {
|
||
|
|
cout << "( " << tmp_pt.GetX()
|
||
|
|
<< ", " << tmp_pt.GetY() << " ) ";
|
||
|
|
}
|
||
|
|
UPoint uresult(true);
|
||
|
|
if(unitin.At( tmp_pt, uresult ))
|
||
|
|
result.Add( uresult );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
clock4 = clock();
|
||
|
|
clock_ges = clock_ges + (clock4 - clock3);
|
||
|
|
}
|
||
|
|
clock2 = clock();
|
||
|
|
time2 = ((double)(clock_ges / GetNoComponents())/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
time1 = ((double)(clock2-clock1)/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
cout << "Average computing time per unit: " << time2 << " ms/unit" << endl;
|
||
|
|
cout << "Total computing time : " << time1 << " ms" << endl;
|
||
|
|
result.EndBulkLoad( false );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.4 Method At of class MPointExt
|
||
|
|
|
||
|
|
Parameter:
|
||
|
|
|
||
|
|
ln: a pointer to a Line object
|
||
|
|
result: a reference to a MPoint object
|
||
|
|
|
||
|
|
Return: nothing
|
||
|
|
|
||
|
|
It returns a projection of ln on the moving point. The
|
||
|
|
method seeks for intersections between a unit point
|
||
|
|
and each HalfSegment in ln. Actually intersections in a point
|
||
|
|
are supported.
|
||
|
|
|
||
|
|
*/
|
||
|
|
bool checkunits( const UPoint& u1, const UPoint& u2 )
|
||
|
|
{
|
||
|
|
bool res= ( (u1.timeInterval.end.Compare( &u2.timeInterval.start ) < 0) ||
|
||
|
|
(u1.timeInterval.end.Compare( &u2.timeInterval.start ) == 0 &&
|
||
|
|
!( u1.timeInterval.rc && u2.timeInterval.lc )) ||
|
||
|
|
((u1.timeInterval.end == u2.timeInterval.start) &&
|
||
|
|
(u2.timeInterval.start < u2.timeInterval.end) &&
|
||
|
|
u1.timeInterval.rc && u2.timeInterval.lc) );
|
||
|
|
return res;
|
||
|
|
}
|
||
|
|
|
||
|
|
void MPointExt::At( Line* ln, MPoint &result ) const
|
||
|
|
{
|
||
|
|
UPoint unitin;
|
||
|
|
UPoint unitincopy, lastunit(true);
|
||
|
|
clock_t clock1, clock2, clock3, clock4, clock_ges;
|
||
|
|
double time1, time2;
|
||
|
|
|
||
|
|
result.Clear();
|
||
|
|
result.StartBulkLoad();
|
||
|
|
clock1 = clock();
|
||
|
|
clock_ges = 0;
|
||
|
|
for(int i=0;i<GetNoComponents();i++) {
|
||
|
|
clock3 = clock();
|
||
|
|
Get(i, unitin);
|
||
|
|
unitincopy = unitin;
|
||
|
|
const Rectangle<3> temp_pbb = (Rectangle<3>)unitin.BoundingBox();
|
||
|
|
Rectangle<2> unit_pbb;
|
||
|
|
const Rectangle<2> obj_pbb = (Rectangle<2>)ln->BoundingBox();
|
||
|
|
if(0) {
|
||
|
|
cout << "Boundingbox of points: "
|
||
|
|
<< "MinD(0): " << obj_pbb.MinD(0)
|
||
|
|
<< ", MinD(1): " << obj_pbb.MinD(1)
|
||
|
|
<< ", MaxD(0): " << obj_pbb.MaxD(0)
|
||
|
|
<< ", MaxD(1): " << obj_pbb.MaxD(1) << endl;
|
||
|
|
} // end debug
|
||
|
|
double min[2] = { temp_pbb.MinD(0), temp_pbb.MinD(1) };
|
||
|
|
double max[2] = { temp_pbb.MaxD(0), temp_pbb.MaxD(1) };
|
||
|
|
unit_pbb.Set(true, min, max);
|
||
|
|
|
||
|
|
//Raw intersection with Bounding Boxes const
|
||
|
|
|
||
|
|
if(unit_pbb.Intersects( obj_pbb )) {
|
||
|
|
HalfSegment up_chs;
|
||
|
|
if ( unitin.p0 != unitin.p1 ){
|
||
|
|
up_chs.Set( false, unitin.p0, unitin.p1 );
|
||
|
|
}
|
||
|
|
if(0){
|
||
|
|
cout << "No of HS: " << ln->Size() << endl;
|
||
|
|
} // end debug
|
||
|
|
for(int j=0;j<ln->Size();j++) {
|
||
|
|
HalfSegment ln_chs;
|
||
|
|
ln->Get( j, ln_chs );
|
||
|
|
|
||
|
|
// Scanning of one 1 of 2 HalfSegment
|
||
|
|
|
||
|
|
if( ln_chs.GetRightPoint() == ln_chs.GetDomPoint() ) {
|
||
|
|
if(0) {
|
||
|
|
cout << "P0.X = " << ln_chs.GetLeftPoint().GetX()
|
||
|
|
<< " P0.Y = " << ln_chs.GetLeftPoint().GetY()
|
||
|
|
<< " P1.X = " << ln_chs.GetRightPoint().GetX()
|
||
|
|
<< " P1.Y = " << ln_chs.GetRightPoint().GetY()
|
||
|
|
<< " D0.X = " << ln_chs.GetDomPoint().GetX()
|
||
|
|
<< " D0.Y = " << ln_chs.GetDomPoint().GetY()
|
||
|
|
<< " S1.X = " << ln_chs.GetSecPoint().GetX()
|
||
|
|
<< " S1.Y = " << ln_chs.GetSecPoint().GetY()
|
||
|
|
<< endl;
|
||
|
|
} // end debug
|
||
|
|
|
||
|
|
// For unit points which do not have any motion
|
||
|
|
|
||
|
|
if( unitin.p0 == unitin.p1 ) {
|
||
|
|
if( ln_chs.Contains( unitin.p0 ) ) {
|
||
|
|
if(0) {
|
||
|
|
cout << "Intersects up " << i
|
||
|
|
<< " as a point at " << j << "!!" << endl
|
||
|
|
<< "HS: ( " << ln_chs.GetLeftPoint().GetX()
|
||
|
|
<< ", " << ln_chs.GetLeftPoint().GetY()
|
||
|
|
<< " ; " << ln_chs.GetRightPoint().GetX()
|
||
|
|
<< ", " << ln_chs.GetRightPoint().GetY()
|
||
|
|
<< "p0: " << unitin.p0 << " p1: " << unitin.p1
|
||
|
|
<< " unitstart: "
|
||
|
|
<< unitin.timeInterval.start.ToString()
|
||
|
|
<< " unitend: " << unitin.timeInterval.end.ToString()
|
||
|
|
<< " )" << endl;
|
||
|
|
} // end debug
|
||
|
|
UPoint res(true);
|
||
|
|
UPoint uttmp;
|
||
|
|
res.CopyFrom( &unitin );
|
||
|
|
bool unit_present = false;
|
||
|
|
for(int z=0;z<result.GetNoComponents();z++) {
|
||
|
|
result.Get( z, uttmp );
|
||
|
|
if( res == uttmp )
|
||
|
|
unit_present = true;
|
||
|
|
}
|
||
|
|
if( !unit_present ) {
|
||
|
|
if ( i == 0 ) {
|
||
|
|
result.MergeAdd( res );
|
||
|
|
lastunit = res;
|
||
|
|
} else {
|
||
|
|
if ( checkunits(lastunit, res) ) {
|
||
|
|
if ( (lastunit.timeInterval.end ==
|
||
|
|
res.timeInterval.start) &&
|
||
|
|
(res.timeInterval.start < res.timeInterval.end) &&
|
||
|
|
lastunit.timeInterval.rc && res.timeInterval.lc ) {
|
||
|
|
res.timeInterval.lc = false;
|
||
|
|
}
|
||
|
|
lastunit = res;
|
||
|
|
result.MergeAdd( res );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
if( up_chs.Intersects( ln_chs ) ) {
|
||
|
|
if(0) {
|
||
|
|
cout << "In unit " << i << " ..." << endl;
|
||
|
|
cout << "( " << up_chs.GetLeftPoint().GetX()
|
||
|
|
<< ", "
|
||
|
|
<< up_chs.GetLeftPoint().GetY()
|
||
|
|
<< "; "
|
||
|
|
<< up_chs.GetRightPoint().GetX()
|
||
|
|
<< ", "
|
||
|
|
<< up_chs.GetRightPoint().GetY()
|
||
|
|
<< " )" << endl;
|
||
|
|
cout << "intersects ( "
|
||
|
|
<< ln_chs.GetLeftPoint().GetX()
|
||
|
|
<< ", "
|
||
|
|
<< ln_chs.GetLeftPoint().GetY()
|
||
|
|
<< "; "
|
||
|
|
<< ln_chs.GetRightPoint().GetX()
|
||
|
|
<< ", "
|
||
|
|
<< ln_chs.GetRightPoint().GetY()
|
||
|
|
<< " ) at " << j << endl;
|
||
|
|
}
|
||
|
|
Point inter_p;
|
||
|
|
HalfSegment inter_chs;
|
||
|
|
if( up_chs.Intersection( ln_chs, inter_chs ) ) {
|
||
|
|
if(0) {
|
||
|
|
cout << "Intersection is a line!!" << endl
|
||
|
|
<< "2inter_chs: ( "
|
||
|
|
<< inter_chs.GetLeftPoint().GetX()
|
||
|
|
<< ", "
|
||
|
|
<< inter_chs.GetLeftPoint().GetY()
|
||
|
|
<< "; "
|
||
|
|
<< inter_chs.GetRightPoint().GetX()
|
||
|
|
<< ", "
|
||
|
|
<< inter_chs.GetRightPoint().GetY()
|
||
|
|
<< " )" << endl;
|
||
|
|
}
|
||
|
|
UPoint trash1(true);
|
||
|
|
UPoint trash2(true);
|
||
|
|
bool tmpunitlc = true;
|
||
|
|
if ( (AlmostEqual(ln_chs.GetLeftPoint(), unitin.p0) ||
|
||
|
|
AlmostEqual(ln_chs.GetRightPoint(), unitin.p0))
|
||
|
|
&& !unitin.timeInterval.lc ) {
|
||
|
|
tmpunitlc = false;
|
||
|
|
unitincopy.timeInterval.lc = true;
|
||
|
|
}
|
||
|
|
bool tmpunitrc = true;
|
||
|
|
if ( (AlmostEqual(ln_chs.GetRightPoint(), unitin.p1) ||
|
||
|
|
AlmostEqual(ln_chs.GetLeftPoint(), unitin.p1))
|
||
|
|
&& !unitin.timeInterval.rc ) {
|
||
|
|
tmpunitrc = false;
|
||
|
|
unitincopy.timeInterval.rc = true;
|
||
|
|
}
|
||
|
|
unitincopy.At( inter_chs.GetLeftPoint(), trash1 );
|
||
|
|
unitincopy.At( inter_chs.GetRightPoint(), trash2 );
|
||
|
|
bool inv_def = true;
|
||
|
|
|
||
|
|
if(!trash1.timeInterval.lc && !trash1.timeInterval.rc)
|
||
|
|
inv_def = false;
|
||
|
|
|
||
|
|
if(!trash2.timeInterval.rc && trash2.timeInterval.lc)
|
||
|
|
inv_def = false;
|
||
|
|
|
||
|
|
if(inv_def && trash1.timeInterval.lc &&
|
||
|
|
trash2.timeInterval.rc) {
|
||
|
|
|
||
|
|
// if(!trash1.timeInterval.lc){
|
||
|
|
// ls = false;
|
||
|
|
// }
|
||
|
|
// if(!trash2.timeInterval.rc) {
|
||
|
|
// rs = false;
|
||
|
|
// }
|
||
|
|
|
||
|
|
Interval<Instant> ii(
|
||
|
|
((trash1.timeInterval.start
|
||
|
|
> trash2.timeInterval.start)
|
||
|
|
? trash2.timeInterval.start
|
||
|
|
: trash1.timeInterval.start
|
||
|
|
),
|
||
|
|
((trash1.timeInterval.start
|
||
|
|
> trash2.timeInterval.start)
|
||
|
|
? trash1.timeInterval.start
|
||
|
|
: trash2.timeInterval.start
|
||
|
|
),
|
||
|
|
tmpunitlc, tmpunitrc);
|
||
|
|
|
||
|
|
UPoint res( ii,
|
||
|
|
(unitin.p0 > unitin.p1)
|
||
|
|
? inter_chs.GetRightPoint()
|
||
|
|
: inter_chs.GetLeftPoint(),
|
||
|
|
(unitin.p0 > unitin.p1)
|
||
|
|
? inter_chs.GetLeftPoint()
|
||
|
|
: inter_chs.GetRightPoint()
|
||
|
|
);
|
||
|
|
if(0){
|
||
|
|
cout << "UPoint created: " << res << endl;
|
||
|
|
}
|
||
|
|
if ( i == 0 ){
|
||
|
|
result.MergeAdd( res );
|
||
|
|
lastunit = res;
|
||
|
|
} else {
|
||
|
|
if ( checkunits(lastunit, res) ) {
|
||
|
|
if ( (lastunit.timeInterval.end ==
|
||
|
|
res.timeInterval.start) &&
|
||
|
|
(res.timeInterval.start
|
||
|
|
< res.timeInterval.end)
|
||
|
|
&& lastunit.timeInterval.rc &&
|
||
|
|
res.timeInterval.lc ) {
|
||
|
|
res.timeInterval.lc = false;
|
||
|
|
}
|
||
|
|
lastunit = res;
|
||
|
|
result.MergeAdd( res );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
|
||
|
|
// Looks for intersections in a point
|
||
|
|
|
||
|
|
if( up_chs.Intersection( ln_chs, inter_p ) ) {
|
||
|
|
if(0) {
|
||
|
|
cout << "Intersection is a point!! " << inter_p << endl;
|
||
|
|
}
|
||
|
|
UPoint res(true);
|
||
|
|
if ( (AlmostEqual(unitin.p0, inter_p) &&
|
||
|
|
unitin.timeInterval.lc) ||
|
||
|
|
(AlmostEqual(unitin.p1, inter_p) &&
|
||
|
|
unitin.timeInterval.rc) ||
|
||
|
|
((inter_p > unitin.p0) && (inter_p < unitin.p1)) ||
|
||
|
|
((inter_p < unitin.p0) && (inter_p > unitin.p1)) ) {
|
||
|
|
unitin.At( inter_p, res );
|
||
|
|
if ( i == 0 ) {
|
||
|
|
result.MergeAdd( res );
|
||
|
|
lastunit = res;
|
||
|
|
} else {
|
||
|
|
if ( checkunits(lastunit, res) ) {
|
||
|
|
if ( (lastunit.timeInterval.end ==
|
||
|
|
res.timeInterval.start) &&
|
||
|
|
(res.timeInterval.start <
|
||
|
|
res.timeInterval.end) &&
|
||
|
|
lastunit.timeInterval.rc &&
|
||
|
|
res.timeInterval.lc ) {
|
||
|
|
res.timeInterval.lc = false;
|
||
|
|
}
|
||
|
|
lastunit = res;
|
||
|
|
result.MergeAdd( res );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
clock4 = clock();
|
||
|
|
clock_ges = clock_ges + (clock4 - clock3);
|
||
|
|
}
|
||
|
|
clock2 = clock();
|
||
|
|
time2 = ((double)(clock_ges / GetNoComponents())/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
time1 = ((double)(clock2-clock1)/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
if ( 0 ){
|
||
|
|
cout << "Average computing time per unit: "
|
||
|
|
<< time2 << " ms/unit" << endl;
|
||
|
|
cout << "Total computing time : " << time1 << " ms" << endl;
|
||
|
|
} // end debug
|
||
|
|
result.EndBulkLoad( false );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.5 Method Passes of class MPointExt
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
|
||
|
|
pts: a pointer to a Points object
|
||
|
|
|
||
|
|
Return: a boolean
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
bool MPointExt::Passes( Points* pts ) const
|
||
|
|
{
|
||
|
|
UPoint unitin;
|
||
|
|
clock_t clock1, clock2, clock3, clock4, clock_ges;
|
||
|
|
double time1, time2;
|
||
|
|
bool result = false;
|
||
|
|
|
||
|
|
clock1 = clock();
|
||
|
|
clock_ges = 0;
|
||
|
|
int i = 0;
|
||
|
|
while( !result && i<GetNoComponents() )
|
||
|
|
{
|
||
|
|
clock3 = clock();
|
||
|
|
Get(i, unitin);
|
||
|
|
const Rectangle<3> temp_pbb = (Rectangle<3>)unitin.BoundingBox();
|
||
|
|
Rectangle<2> unit_pbb;
|
||
|
|
const Rectangle<2> obj_pbb = (Rectangle<2>)pts->BoundingBox();
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "Boundingbox of points: "
|
||
|
|
<< "MinD(0): " << obj_pbb.MinD(0)
|
||
|
|
<< ", MinD(1): " << obj_pbb.MinD(1)
|
||
|
|
<< ", MaxD(0): " << obj_pbb.MaxD(0)
|
||
|
|
<< ", MaxD(1): " << obj_pbb.MaxD(1) << endl;
|
||
|
|
|
||
|
|
}
|
||
|
|
double min[2] = { temp_pbb.MinD(0), temp_pbb.MinD(1) };
|
||
|
|
double max[2] = { temp_pbb.MaxD(0), temp_pbb.MaxD(1) };
|
||
|
|
|
||
|
|
unit_pbb.Set(true, min, max);
|
||
|
|
if(unit_pbb.Intersects( obj_pbb ))
|
||
|
|
{
|
||
|
|
int j = 0;
|
||
|
|
while( !result && j<pts->Size() )
|
||
|
|
{
|
||
|
|
Point tmp_pt;
|
||
|
|
pts->Get( j, tmp_pt );
|
||
|
|
if( unitin.Passes( tmp_pt ) )
|
||
|
|
{
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "( " << tmp_pt.GetX()
|
||
|
|
<< ", " << tmp_pt.GetY() << " ) ";
|
||
|
|
}
|
||
|
|
result = true;
|
||
|
|
}
|
||
|
|
j++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
clock4 = clock();
|
||
|
|
clock_ges = clock_ges + (clock4 - clock3);
|
||
|
|
i++;
|
||
|
|
}
|
||
|
|
clock2 = clock();
|
||
|
|
time2 = ((double)(clock_ges / GetNoComponents())/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
time1 = ((double)(clock2-clock1)/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
cout << "Average computing time per unit: " << time2 << " ms/unit" << endl;
|
||
|
|
cout << "Total computing time : " << time1 << " ms" << endl;
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.6 Method Passes of class MPointExt
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
|
||
|
|
ln: a pointer to a Line object
|
||
|
|
|
||
|
|
Return: a boolean
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
bool MPointExt::Passes( Line* ln ) const
|
||
|
|
{
|
||
|
|
UPoint unitin;
|
||
|
|
// clock_t clock1, clock2, clock3, clock4, clock_ges;
|
||
|
|
// double time1, time2;
|
||
|
|
bool result = false;
|
||
|
|
|
||
|
|
// clock1 = clock();
|
||
|
|
// clock_ges = 0;
|
||
|
|
int i = 0;
|
||
|
|
while( !result && i<GetNoComponents() )
|
||
|
|
{
|
||
|
|
// clock3 = clock();
|
||
|
|
Get(i, unitin);
|
||
|
|
const Rectangle<3> temp_pbb = (Rectangle<3>)unitin.BoundingBox();
|
||
|
|
Rectangle<2> unit_pbb;
|
||
|
|
const Rectangle<2> obj_pbb = (Rectangle<2>)ln->BoundingBox();
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "Boundingbox of points: "
|
||
|
|
<< "MinD(0): " << obj_pbb.MinD(0)
|
||
|
|
<< ", MinD(1): " << obj_pbb.MinD(1)
|
||
|
|
<< ", MaxD(0): " << obj_pbb.MaxD(0)
|
||
|
|
<< ", MaxD(1): " << obj_pbb.MaxD(1) << endl;
|
||
|
|
|
||
|
|
}
|
||
|
|
double min[2] = { temp_pbb.MinD(0), temp_pbb.MinD(1) };
|
||
|
|
double max[2] = { temp_pbb.MaxD(0), temp_pbb.MaxD(1) };
|
||
|
|
|
||
|
|
unit_pbb.Set(true, min, max);
|
||
|
|
/*
|
||
|
|
Raw intersection with Bounding Boxes ...
|
||
|
|
|
||
|
|
*/
|
||
|
|
if(unit_pbb.Intersects( obj_pbb ))
|
||
|
|
{
|
||
|
|
bool isSegment = false;
|
||
|
|
HalfSegment up_chs;
|
||
|
|
Point up_point(true);
|
||
|
|
if(!AlmostEqual(unitin.p0, unitin.p1)){
|
||
|
|
up_chs.Set( false, unitin.p0, unitin.p1 );
|
||
|
|
isSegment = true;
|
||
|
|
} else {
|
||
|
|
up_point = unitin.p0;
|
||
|
|
isSegment = false;
|
||
|
|
}
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "No of HS: " << ln->Size() << endl;
|
||
|
|
}
|
||
|
|
|
||
|
|
int j = 0;
|
||
|
|
while( !result && j<ln->Size() )
|
||
|
|
{
|
||
|
|
HalfSegment ln_chs;
|
||
|
|
ln->Get( j, ln_chs );
|
||
|
|
/*
|
||
|
|
Scanning of one 1 of 2 HalfSegment
|
||
|
|
|
||
|
|
*/
|
||
|
|
if( ln_chs.GetRightPoint() == ln_chs.GetDomPoint() )
|
||
|
|
{
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "P0.X = " << ln_chs.GetLeftPoint().GetX()
|
||
|
|
<< " P0.Y = " << ln_chs.GetLeftPoint().GetY()
|
||
|
|
<< " P1.X = " << ln_chs.GetRightPoint().GetX()
|
||
|
|
<< " P1.Y = " << ln_chs.GetRightPoint().GetY()
|
||
|
|
<< " D0.X = " << ln_chs.GetDomPoint().GetX()
|
||
|
|
<< " D0.Y = " << ln_chs.GetDomPoint().GetY()
|
||
|
|
<< " S1.X = " << ln_chs.GetSecPoint().GetX()
|
||
|
|
<< " S1.Y = " << ln_chs.GetSecPoint().GetY()
|
||
|
|
<< endl;
|
||
|
|
}
|
||
|
|
/*
|
||
|
|
For unit points which do not have any motion
|
||
|
|
|
||
|
|
*/
|
||
|
|
if( !isSegment )
|
||
|
|
{
|
||
|
|
if( ln_chs.Contains( unitin.p0 ) )
|
||
|
|
{
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "Intersects up " << i
|
||
|
|
<< " as a point at " << j << "!!" << endl
|
||
|
|
<< "HS: ( "
|
||
|
|
<< ln_chs.GetLeftPoint().GetX()
|
||
|
|
<< ", " << ln_chs.GetLeftPoint().GetY()
|
||
|
|
<< " ; " << ln_chs.GetRightPoint().GetX()
|
||
|
|
<< ", " << ln_chs.GetRightPoint().GetY()
|
||
|
|
<< " )" << endl;
|
||
|
|
}
|
||
|
|
result = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
Point inter_p;
|
||
|
|
HalfSegment inter_chs;
|
||
|
|
/*
|
||
|
|
Looks for intersections in a point inter\_p
|
||
|
|
|
||
|
|
*/
|
||
|
|
if( up_chs.Intersection( ln_chs, inter_p ) )
|
||
|
|
{
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "In unit " << i << " ..." << endl;
|
||
|
|
cout << "( " << up_chs.GetLeftPoint().GetX()
|
||
|
|
<< ", "
|
||
|
|
<< up_chs.GetLeftPoint().GetY()
|
||
|
|
<< "; "
|
||
|
|
<< up_chs.GetRightPoint().GetX()
|
||
|
|
<< ", "
|
||
|
|
<< up_chs.GetRightPoint().GetY()
|
||
|
|
<< " )" << endl;
|
||
|
|
cout << "intersects ( "
|
||
|
|
<< ln_chs.GetLeftPoint().GetX()
|
||
|
|
<< ", "
|
||
|
|
<< ln_chs.GetLeftPoint().GetY()
|
||
|
|
<< "; "
|
||
|
|
<< ln_chs.GetRightPoint().GetX()
|
||
|
|
<< ", "
|
||
|
|
<< ln_chs.GetRightPoint().GetY()
|
||
|
|
<< " ) at " << j << endl;
|
||
|
|
}
|
||
|
|
result = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
j++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// clock4 = clock();
|
||
|
|
// clock_ges = clock_ges + (clock4 - clock3);
|
||
|
|
i++;
|
||
|
|
}
|
||
|
|
// clock2 = clock();
|
||
|
|
// time2 = ((double)(clock_ges / GetNoComponents())/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
// time1 = ((double)(clock2-clock1)/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
// cout << "Average computing time per unit: " <<time2<< " ms/unit" << endl;
|
||
|
|
// cout << "Total computing time : " << time1 << " ms" << endl;
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.7 Method AtMin of class MappingExt
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
|
||
|
|
result: a reference to a Mapping<Unit, Alpha> object
|
||
|
|
|
||
|
|
Return: nothing
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
template <class Unit, class Alpha>
|
||
|
|
void MappingExt<Unit, Alpha>::AtMin( Mapping<Unit, Alpha> &result ) const
|
||
|
|
{
|
||
|
|
Unit unit;
|
||
|
|
int compRes = 0;
|
||
|
|
Unit umin;
|
||
|
|
|
||
|
|
result.Clear();
|
||
|
|
result.StartBulkLoad();
|
||
|
|
|
||
|
|
this->Get(0, unit);
|
||
|
|
result.Add( unit );
|
||
|
|
umin = unit;
|
||
|
|
|
||
|
|
for(int i=1;i<Mapping<Unit, Alpha>::GetNoComponents();i++)
|
||
|
|
{
|
||
|
|
this->Get(i, unit);
|
||
|
|
compRes = (unit.constValue).Compare( &(umin.constValue) );
|
||
|
|
if(compRes > 0)
|
||
|
|
continue;
|
||
|
|
if(compRes == 0)
|
||
|
|
{
|
||
|
|
result.Add( unit );
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
if(compRes < 0)
|
||
|
|
{
|
||
|
|
result.Clear();
|
||
|
|
result.StartBulkLoad();
|
||
|
|
result.Add( unit );
|
||
|
|
umin = unit;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
result.EndBulkLoad( false );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.7 Method AtMin of class MappingExt
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
|
||
|
|
result: a reference to a Mapping<Unit, Alpha> object
|
||
|
|
|
||
|
|
Return: nothing
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
template <class Unit, class Alpha>
|
||
|
|
void MappingExt<Unit, Alpha>::AtMax( Mapping<Unit, Alpha> &result ) const
|
||
|
|
{
|
||
|
|
Unit unit;
|
||
|
|
int compRes = 0;
|
||
|
|
Unit umin;
|
||
|
|
|
||
|
|
result.Clear();
|
||
|
|
result.StartBulkLoad();
|
||
|
|
|
||
|
|
this->Get(0, unit);
|
||
|
|
result.Add( unit );
|
||
|
|
umin = unit;
|
||
|
|
|
||
|
|
for(int i=1;i<Mapping<Unit, Alpha>::GetNoComponents();i++)
|
||
|
|
{
|
||
|
|
this->Get(i, unit);
|
||
|
|
compRes = (unit.constValue).Compare( &(umin.constValue) );
|
||
|
|
if(compRes < 0)
|
||
|
|
continue;
|
||
|
|
if(compRes == 0)
|
||
|
|
{
|
||
|
|
result.Add( unit );
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
if(compRes > 0)
|
||
|
|
{
|
||
|
|
result.Clear();
|
||
|
|
result.StartBulkLoad();
|
||
|
|
result.Add( unit );
|
||
|
|
umin = unit;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
result.EndBulkLoad( false );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.8 Method AtMin of class MRealExt
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
|
||
|
|
result: a reference to a MReal object
|
||
|
|
|
||
|
|
Return: nothing
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
void MRealExt::AtMin( MReal &result ) const
|
||
|
|
{
|
||
|
|
cerr << "WARNING: " << __PRETTY_FUNCTION__
|
||
|
|
<< " has a wrong implementation!" << endl;
|
||
|
|
result.Clear();
|
||
|
|
if(!IsDefined()){
|
||
|
|
result.SetDefined( false );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
result.SetDefined( true );
|
||
|
|
|
||
|
|
UReal utemp;
|
||
|
|
UReal uresult;
|
||
|
|
double min;
|
||
|
|
int unit_num;
|
||
|
|
double unit_min, unit_max;
|
||
|
|
|
||
|
|
Get(0, utemp);
|
||
|
|
MinMaxValueFunction(&utemp, unit_min, unit_max);
|
||
|
|
((URealExt*)(&utemp))->SetUnitMin( unit_min );
|
||
|
|
((URealExt*)(&utemp))->SetUnitMax( unit_max );
|
||
|
|
min = ((URealExt*)(&utemp))->GetUnitMin();
|
||
|
|
unit_num = 0;
|
||
|
|
|
||
|
|
if(0)
|
||
|
|
cout << "GetUnitMin(): " << ((URealExt*)(&utemp))->GetUnitMin() << endl;
|
||
|
|
|
||
|
|
for(int i=1;i<GetNoComponents();i++)
|
||
|
|
{
|
||
|
|
Get(i, utemp);
|
||
|
|
MinMaxValueFunction(&utemp, unit_min, unit_max);
|
||
|
|
((URealExt*)(&utemp))->SetUnitMin( unit_min );
|
||
|
|
((URealExt*)(&utemp))->SetUnitMax( unit_max );
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "GetUnitMin(): " << ((URealExt*)(&utemp))->GetUnitMin();
|
||
|
|
cout << endl;
|
||
|
|
}
|
||
|
|
if(((URealExt*)(&utemp))->GetUnitMin() < min)
|
||
|
|
{
|
||
|
|
min = ((URealExt*)(&utemp))->GetUnitMin();
|
||
|
|
unit_num = i;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// ATTENTION! This seems to be wrong. A moving object can reach its extrema
|
||
|
|
// several times! To return a single unit is NOT correct! Instead, one has
|
||
|
|
// to find ALL units with the appropriate extremum, restrict their deftimes
|
||
|
|
// to the interval, where they take the extreme value and add them to the
|
||
|
|
// result!
|
||
|
|
Get( unit_num, uresult );
|
||
|
|
|
||
|
|
result.Clear();
|
||
|
|
result.StartBulkLoad();
|
||
|
|
result.Add( uresult );
|
||
|
|
result.EndBulkLoad( false );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.9 Method AtMax of class MRealExt
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
|
||
|
|
result: a reference to a MReal object
|
||
|
|
|
||
|
|
Return: nothing
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
void MRealExt::AtMax( MReal &result ) const
|
||
|
|
{
|
||
|
|
cerr << "WARNING: " << __PRETTY_FUNCTION__
|
||
|
|
<< " has a wrong implementation!" << endl;
|
||
|
|
result.Clear();
|
||
|
|
if(!IsDefined()){
|
||
|
|
result.SetDefined( false );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
result.SetDefined( true );
|
||
|
|
|
||
|
|
UReal utemp;
|
||
|
|
UReal uresult;
|
||
|
|
double max;
|
||
|
|
int unit_num;
|
||
|
|
double unit_min, unit_max;
|
||
|
|
|
||
|
|
Get(0, utemp);
|
||
|
|
MinMaxValueFunction(&utemp, unit_min, unit_max);
|
||
|
|
((URealExt*)(&utemp))->SetUnitMin( unit_min );
|
||
|
|
((URealExt*)(&utemp))->SetUnitMax( unit_max );
|
||
|
|
max = ((URealExt*)(&utemp))->GetUnitMax();
|
||
|
|
unit_num = 0;
|
||
|
|
|
||
|
|
if(0)
|
||
|
|
cout << "GetUnitMax(): " << ((URealExt*)(&utemp))->GetUnitMax() << endl;
|
||
|
|
|
||
|
|
for(int i=1;i<GetNoComponents();i++)
|
||
|
|
{
|
||
|
|
Get(i, utemp);
|
||
|
|
MinMaxValueFunction(&utemp, unit_min, unit_max);
|
||
|
|
((URealExt*)(&utemp))->SetUnitMin( unit_min );
|
||
|
|
((URealExt*)(&utemp))->SetUnitMax( unit_max );
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "GetUnitMax(): " << ((URealExt*)(&utemp))->GetUnitMax();
|
||
|
|
cout << endl;
|
||
|
|
}
|
||
|
|
if(((URealExt*)(&utemp))->GetUnitMax() > max)
|
||
|
|
{
|
||
|
|
max = ((URealExt*)(&utemp))->GetUnitMax();
|
||
|
|
unit_num = i;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// ATTENTION! This seems to be wrong. A moving object can reach its extrema
|
||
|
|
// several times! To return a single unit is NOT correct! Instead, one has
|
||
|
|
// to find ALL units with the appropriate extremum, restrict their deftimes
|
||
|
|
// to the interval, where they take the extreme value and add them to the
|
||
|
|
// result!
|
||
|
|
Get( unit_num, uresult );
|
||
|
|
|
||
|
|
result.Clear();
|
||
|
|
result.StartBulkLoad();
|
||
|
|
result.Add( uresult );
|
||
|
|
result.EndBulkLoad( false );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.10 Method AtMin of class MRealExt
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
|
||
|
|
val: a CcReal object
|
||
|
|
result: a reference to a MReal object
|
||
|
|
|
||
|
|
Return: nothing
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
void MRealExt::At( CcReal val, MReal &result ) const
|
||
|
|
{
|
||
|
|
result.Clear();
|
||
|
|
if( !IsDefined() || !val.IsDefined() ){
|
||
|
|
result.SetDefined( false );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
result.SetDefined( true );
|
||
|
|
|
||
|
|
UReal utemp;
|
||
|
|
UReal uresult(true);
|
||
|
|
double unit_min, unit_max, time1, time2;
|
||
|
|
double value = val.GetRealval();
|
||
|
|
clock_t clock1, clock2, clock3, clock4, clock_ges;
|
||
|
|
|
||
|
|
result.Clear();
|
||
|
|
result.StartBulkLoad();
|
||
|
|
clock1 = clock();
|
||
|
|
clock_ges = 0;
|
||
|
|
for(int i=0;i<GetNoComponents();i++)
|
||
|
|
{
|
||
|
|
clock3 = clock();
|
||
|
|
Get(i, utemp);
|
||
|
|
MinMaxValueFunction(&utemp, unit_min, unit_max);
|
||
|
|
((URealExt*)(&utemp))->SetUnitMin( unit_min );
|
||
|
|
((URealExt*)(&utemp))->SetUnitMax( unit_max );
|
||
|
|
double t_value;
|
||
|
|
// ORIGINAL: if(timeIntervalOfRealInUReal(value, &utemp, t_value))
|
||
|
|
if(timeIntervalOfRealInUReal(value, utemp, t_value))
|
||
|
|
{
|
||
|
|
uresult.a = utemp.a;
|
||
|
|
uresult.b = utemp.b;
|
||
|
|
uresult.c = utemp.c;
|
||
|
|
uresult.r = utemp.r;
|
||
|
|
if(utemp.a == 0 && utemp.b == 0)
|
||
|
|
{
|
||
|
|
uresult.timeInterval = utemp.timeInterval;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
uresult.timeInterval = utemp.timeInterval;
|
||
|
|
uresult.timeInterval.start.ReadFrom(
|
||
|
|
(const double)(t_value - 0.0000001) );
|
||
|
|
uresult.timeInterval.end.ReadFrom(
|
||
|
|
(const double)(t_value + 0.0000001) );
|
||
|
|
}
|
||
|
|
result.Add( uresult );
|
||
|
|
}
|
||
|
|
clock4 = clock();
|
||
|
|
clock_ges = clock_ges + (clock4 - clock3);
|
||
|
|
}
|
||
|
|
clock2 = clock();
|
||
|
|
time2 = ((double)(clock_ges / GetNoComponents())/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
time1 = ((double)(clock2-clock1)/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
cout << "Average computing time per unit: " << time2 << " ms/unit" << endl;
|
||
|
|
cout << "Total computing time : " << time1 << " ms" << endl;
|
||
|
|
result.EndBulkLoad( false );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.11 Method Passes of class MRealExt
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
|
||
|
|
val: a CcReal object
|
||
|
|
|
||
|
|
Return: a boolean
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
bool MRealExt::Passes( CcReal val ) const
|
||
|
|
{
|
||
|
|
assert( IsDefined() );
|
||
|
|
assert( val.IsDefined() );
|
||
|
|
if( !IsDefined() || !val.IsDefined() ){
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
UReal utemp;
|
||
|
|
UReal uresult(true);
|
||
|
|
double unit_min, unit_max, time1, time2;
|
||
|
|
double value = val.GetRealval();
|
||
|
|
clock_t clock1, clock2, clock3, clock4, clock_ges;
|
||
|
|
bool result = false;
|
||
|
|
|
||
|
|
clock1 = clock();
|
||
|
|
clock_ges = 0;
|
||
|
|
for(int i=0;i<GetNoComponents();i++)
|
||
|
|
{
|
||
|
|
clock3 = clock();
|
||
|
|
Get(i, utemp);
|
||
|
|
MinMaxValueFunction(&utemp, unit_min, unit_max);
|
||
|
|
((URealExt*)(&utemp))->SetUnitMin( unit_min );
|
||
|
|
((URealExt*)(&utemp))->SetUnitMax( unit_max );
|
||
|
|
bool lh = utemp.timeInterval.lc;
|
||
|
|
bool rh = utemp.timeInterval.rc;
|
||
|
|
if( !((!lh && !rh && ( value <= unit_min || value >= unit_max ) ) ||
|
||
|
|
(lh && rh && ( value < unit_min || value > unit_max) ) ||
|
||
|
|
(!lh && rh && ( value <= unit_min || value > unit_max ) ) ||
|
||
|
|
(lh && !rh && ( value < unit_min || value >= unit_max ) )
|
||
|
|
) )
|
||
|
|
{
|
||
|
|
result = true;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
clock4 = clock();
|
||
|
|
clock_ges = clock_ges + (clock4 - clock3);
|
||
|
|
}
|
||
|
|
clock2 = clock();
|
||
|
|
time2 = ((double)(clock_ges / GetNoComponents())/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
time1 = ((double)(clock2-clock1)/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
cout << "Average computing time per unit: " << time2 << " ms/unit" << endl;
|
||
|
|
cout << "Total computing time : " << time1 << " ms" << endl;
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.12 Method At of class MappingExt
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
|
||
|
|
inv: a pointer to a Range<Alpha> object
|
||
|
|
result: a reference to a Mapping<Unit, Alpha> object
|
||
|
|
|
||
|
|
Return: nothing
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
template <class Unit, class Alpha>
|
||
|
|
void MappingExt<Unit, Alpha>::At( Range<Alpha>* inv,
|
||
|
|
Mapping<Unit, Alpha> &result ) const
|
||
|
|
{
|
||
|
|
result.Clear();
|
||
|
|
if( !this->IsDefined() || !inv->IsDefined() ){
|
||
|
|
result.SetDefined( false );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
result.SetDefined( true );
|
||
|
|
|
||
|
|
Unit utemp;
|
||
|
|
bool is_valid = true;
|
||
|
|
Interval<Alpha> lastInterval, interval;
|
||
|
|
|
||
|
|
if( !inv->IsOrdered() )
|
||
|
|
is_valid = false;
|
||
|
|
|
||
|
|
if( inv->GetNoComponents() == 1 && is_valid)
|
||
|
|
{
|
||
|
|
inv->Get( 0, interval );
|
||
|
|
is_valid = interval.IsValid();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
|
||
|
|
if(is_valid)
|
||
|
|
{
|
||
|
|
/*
|
||
|
|
This implementation was token from method Range::IsValid() which is
|
||
|
|
private. The method Range::Contains() has an assert(!IsValid()) what
|
||
|
|
causes a unesthetic termination of DB-UI.
|
||
|
|
|
||
|
|
*/
|
||
|
|
for( int i = 1; i < inv->GetNoComponents(); i++ )
|
||
|
|
{
|
||
|
|
inv->Get( i-1, lastInterval );
|
||
|
|
if( !lastInterval.IsValid() )
|
||
|
|
{
|
||
|
|
is_valid = false;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
inv->Get( i, interval );
|
||
|
|
if( !interval.IsValid() )
|
||
|
|
{
|
||
|
|
is_valid = false;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
if( (!lastInterval.Disjoint( interval )) &&
|
||
|
|
(!lastInterval.Adjacent( interval )) )
|
||
|
|
{
|
||
|
|
is_valid = false;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if(is_valid)
|
||
|
|
{
|
||
|
|
result.Clear();
|
||
|
|
result.StartBulkLoad();
|
||
|
|
for(int i=0;i<Mapping<Unit, Alpha>::GetNoComponents();i++)
|
||
|
|
{
|
||
|
|
this->Get(i, utemp);
|
||
|
|
if(inv->Contains(utemp.constValue))
|
||
|
|
result.Add( utemp );
|
||
|
|
}
|
||
|
|
result.EndBulkLoad( false );
|
||
|
|
}
|
||
|
|
else
|
||
|
|
cout << "Invalid Range!!" << endl;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.13 Method At of class MappingExt
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
|
||
|
|
inv: a pointer to a RReal object
|
||
|
|
result: a reference to a Mapping<Unit, Alpha> object
|
||
|
|
|
||
|
|
Return: nothing
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
void MRealExt::At(RReal* inv, MReal &result ) const
|
||
|
|
{
|
||
|
|
result.Clear();
|
||
|
|
if( !IsDefined() || !inv->IsDefined() ){
|
||
|
|
result.SetDefined( false );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
result.SetDefined( true );
|
||
|
|
|
||
|
|
UReal utemp;
|
||
|
|
UReal uresult(true);
|
||
|
|
double unit_min, unit_max;
|
||
|
|
|
||
|
|
vector<UReal> minintervals, maxintervals;
|
||
|
|
|
||
|
|
result.Clear();
|
||
|
|
result.StartBulkLoad();
|
||
|
|
for( int i=0; i<GetNoComponents(); i++ )
|
||
|
|
{
|
||
|
|
Get( i, utemp );
|
||
|
|
//mr->Get(i, utemp);
|
||
|
|
//cout << "got ureal no " << i << endl;
|
||
|
|
|
||
|
|
//MinMaxValueFunction( &utemp, unit_min, unit_max );
|
||
|
|
//((URealExt*)(&utemp))->SetUnitMin( unit_min );
|
||
|
|
//((URealExt*)(&utemp))->SetUnitMax( unit_max );
|
||
|
|
|
||
|
|
//utemp.AtMin(minintervals);
|
||
|
|
//utemp.AtMax(maxintervals);
|
||
|
|
//cout << "\ta=" << utemp.a << " b=" << utemp.b << " c="
|
||
|
|
//<< utemp.c << " r=" << utemp.r << endl;
|
||
|
|
bool correct = true;
|
||
|
|
unit_min = utemp.Min(correct);
|
||
|
|
unit_max = utemp.Max(correct);
|
||
|
|
|
||
|
|
Interval<CcReal> minmax;
|
||
|
|
minmax.start.Set( unit_min );
|
||
|
|
minmax.end.Set( unit_max );
|
||
|
|
minmax.lc = true;
|
||
|
|
minmax.rc = true;
|
||
|
|
//cout << "(min max)[ " << minmax.start.GetValue()
|
||
|
|
//<< ", " << minmax.end.GetValue() << " ] " << endl;
|
||
|
|
|
||
|
|
for(int j=0;j<inv->GetNoComponents();j++)
|
||
|
|
{
|
||
|
|
Interval<CcReal> inv_tmp;
|
||
|
|
Interval<CcReal> inv_result;
|
||
|
|
inv->Get( j, inv_tmp);
|
||
|
|
if(minmax.Intersects( inv_tmp ))
|
||
|
|
{
|
||
|
|
minmax.Intersection( inv_tmp, inv_result );
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "(min max)[ " << minmax.start.GetValue()
|
||
|
|
<< ", " << minmax.end.GetValue() << " ] "
|
||
|
|
<< " intersects "
|
||
|
|
<< "[ " << inv_tmp.start.GetValue()
|
||
|
|
<< ", " << inv_tmp.end.GetValue() << " ]";
|
||
|
|
cout << " = [ " << inv_result.start.GetValue()
|
||
|
|
<< ", " << inv_result.end.GetValue() << " ] " << endl;
|
||
|
|
}
|
||
|
|
//cout << "\ta=" << utemp.a << " b=" << utemp.b << " c="
|
||
|
|
//<< utemp.c << " r=" << utemp.r << endl;
|
||
|
|
double t_value, t_value2;
|
||
|
|
uresult.a = utemp.a;
|
||
|
|
uresult.b = utemp.b;
|
||
|
|
uresult.c = utemp.c;
|
||
|
|
uresult.r = utemp.r;
|
||
|
|
if(utemp.a == 0 && utemp.b == 0)
|
||
|
|
{
|
||
|
|
uresult.timeInterval = utemp.timeInterval;
|
||
|
|
result.Add( uresult );
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
//uresult.timeInterval = utemp.timeInterval;
|
||
|
|
//result.Add( uresult );
|
||
|
|
|
||
|
|
if( timeIntervalOfRealInUReal2(
|
||
|
|
inv_result.start.GetValue(),
|
||
|
|
&utemp,
|
||
|
|
t_value) )
|
||
|
|
{
|
||
|
|
if( timeIntervalOfRealInUReal2(
|
||
|
|
inv_result.end.GetValue(),
|
||
|
|
&utemp,
|
||
|
|
t_value2) )
|
||
|
|
{
|
||
|
|
uresult.timeInterval = utemp.timeInterval;
|
||
|
|
if( t_value < t_value2 )
|
||
|
|
{
|
||
|
|
uresult.timeInterval.start.ReadFrom(
|
||
|
|
(const double)t_value );
|
||
|
|
uresult.timeInterval.end.ReadFrom(
|
||
|
|
(const double)t_value2 );
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
uresult.timeInterval.start.ReadFrom(
|
||
|
|
(const double)t_value2 );
|
||
|
|
uresult.timeInterval.end.ReadFrom(
|
||
|
|
(const double)t_value );
|
||
|
|
}
|
||
|
|
result.Add( uresult );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
result.EndBulkLoad( false );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.14 Method AtPeriods of class MRegion
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
|
||
|
|
per: a pointer to a Periods object
|
||
|
|
mregparam: a pointer to a Mapping<Unit, Alpha> object
|
||
|
|
|
||
|
|
Return: nothing
|
||
|
|
|
||
|
|
NOTE: The declaration of this method is placed on MovingRegion.h
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
void MRegion::AtPeriods(const Periods* per, MRegion* mregparam)
|
||
|
|
{
|
||
|
|
Clear();
|
||
|
|
if( !mregparam->IsDefined() || !per->IsDefined() ){
|
||
|
|
SetDefined( false );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
SetDefined( true );
|
||
|
|
|
||
|
|
URegionEmb utemp;
|
||
|
|
Interval<Instant> temp2;
|
||
|
|
Interval<Instant> temp3;
|
||
|
|
MSegmentData oldsmg;
|
||
|
|
MSegmentData newsmg;
|
||
|
|
vector<GroupOfIntervals> temp_intervals;
|
||
|
|
GroupOfIntervals inter_temp;
|
||
|
|
vector<USegments> tempsgms;
|
||
|
|
USegments usegtemp;
|
||
|
|
const DbArray<MSegmentData>* oldsgms;
|
||
|
|
unsigned int starting_segments_pos;
|
||
|
|
|
||
|
|
for(int i=0;i<mregparam->GetNoComponents();i++)
|
||
|
|
{
|
||
|
|
mregparam->Get(i, utemp);
|
||
|
|
for(int j=0;j<per->GetNoComponents();j++)
|
||
|
|
{
|
||
|
|
per->Get(j, temp2);
|
||
|
|
if((utemp.timeInterval).Intersects(temp2))
|
||
|
|
{
|
||
|
|
(utemp.timeInterval).Intersection(temp2, temp3);
|
||
|
|
inter_temp.unit_nr = i;
|
||
|
|
(inter_temp.str_inst).CopyFrom(temp3);
|
||
|
|
temp_intervals.push_back(inter_temp);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if(1)
|
||
|
|
{
|
||
|
|
for(unsigned int i=0;i<temp_intervals.size();i++)
|
||
|
|
{
|
||
|
|
cout << endl << "Interval:" << endl;
|
||
|
|
cout << "unit nr.: " << temp_intervals[i].unit_nr << endl;
|
||
|
|
cout << "interval start: "
|
||
|
|
<< ((temp_intervals[i].str_inst).start).ToString()
|
||
|
|
<< endl;
|
||
|
|
cout << "interval end: "
|
||
|
|
<< ((temp_intervals[i].str_inst).end).ToString()
|
||
|
|
<< endl;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
oldsgms = mregparam->GetMSegmentData();
|
||
|
|
for(unsigned int i=0;i<temp_intervals.size();i++)
|
||
|
|
{
|
||
|
|
mregparam->Get(temp_intervals[i].unit_nr, utemp);
|
||
|
|
usegtemp.unit_nr = i;
|
||
|
|
for(int k=0;k<utemp.GetSegmentsNum();k++)
|
||
|
|
{
|
||
|
|
utemp.GetSegment(oldsgms, k, oldsmg);
|
||
|
|
oldsmg.restrictToInterval(
|
||
|
|
utemp.timeInterval,
|
||
|
|
temp_intervals[i].str_inst,
|
||
|
|
newsmg
|
||
|
|
);
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << endl << "Old Segments: Unit "
|
||
|
|
<< temp_intervals[i].unit_nr
|
||
|
|
<< ", Segmentnr. " << k << ": ["
|
||
|
|
<< oldsmg.GetInitialStartX() << " , "
|
||
|
|
<< oldsmg.GetInitialStartY() << " ; "
|
||
|
|
<< oldsmg.GetInitialEndX() << " , "
|
||
|
|
<< oldsmg.GetInitialEndY() << " ; "
|
||
|
|
<< oldsmg.GetFinalStartX() << " , "
|
||
|
|
<< oldsmg.GetFinalStartY() << " ; "
|
||
|
|
<< oldsmg.GetFinalEndX() << " , "
|
||
|
|
<< oldsmg.GetFinalEndY()
|
||
|
|
<< "]" << endl;
|
||
|
|
}
|
||
|
|
(usegtemp.unit_interval).start =
|
||
|
|
(temp_intervals[i].str_inst).start;
|
||
|
|
(usegtemp.unit_interval).end = (temp_intervals[i].str_inst).end;
|
||
|
|
(usegtemp.unit_interval).lc = (temp_intervals[i].str_inst).lc;
|
||
|
|
(usegtemp.unit_interval).rc = (temp_intervals[i].str_inst).rc;
|
||
|
|
(usegtemp.sgms).push_back(newsmg);
|
||
|
|
}
|
||
|
|
tempsgms.push_back(usegtemp);
|
||
|
|
usegtemp.unit_nr = 0;
|
||
|
|
(usegtemp.sgms).clear();
|
||
|
|
}
|
||
|
|
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
starting_segments_pos = 0;
|
||
|
|
for(unsigned int i=0;i<tempsgms.size();i++)
|
||
|
|
{
|
||
|
|
cout << endl << "Unit Nr.: " << tempsgms[i].unit_nr << endl;
|
||
|
|
cout << endl << "starting_segments_pos: ";
|
||
|
|
cout << starting_segments_pos << endl;
|
||
|
|
cout << "interval start: ";
|
||
|
|
cout << ((tempsgms[i].unit_interval).start).ToString() << endl;
|
||
|
|
cout << "interval end: ";
|
||
|
|
cout << ((tempsgms[i].unit_interval).end).ToString() << endl;
|
||
|
|
for(unsigned int j=0;j<(tempsgms[i].sgms).size();j++)
|
||
|
|
{
|
||
|
|
cout << endl << j << ": ["
|
||
|
|
<< (tempsgms[i].sgms)[j].GetInitialStartX() << " , "
|
||
|
|
<< (tempsgms[i].sgms)[j].GetInitialStartY() << " ; "
|
||
|
|
<< (tempsgms[i].sgms)[j].GetInitialEndX() << " , "
|
||
|
|
<< (tempsgms[i].sgms)[j].GetInitialEndY() << " ; "
|
||
|
|
<< (tempsgms[i].sgms)[j].GetFinalStartX() << " , "
|
||
|
|
<< (tempsgms[i].sgms)[j].GetFinalStartY() << " ; "
|
||
|
|
<< (tempsgms[i].sgms)[j].GetFinalEndX() << " , "
|
||
|
|
<< (tempsgms[i].sgms)[j].GetFinalEndY()
|
||
|
|
<< "]" << endl;
|
||
|
|
cout << "GetFaceNo: "
|
||
|
|
<< (tempsgms[i].sgms)[j].GetFaceNo()
|
||
|
|
<< endl;
|
||
|
|
cout << "GetCycleNo: "
|
||
|
|
<< (tempsgms[i].sgms)[j].GetCycleNo()
|
||
|
|
<< endl;
|
||
|
|
cout << "GetSegmentNo: "
|
||
|
|
<< (tempsgms[i].sgms)[j].GetSegmentNo()
|
||
|
|
<< endl;
|
||
|
|
starting_segments_pos++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
starting_segments_pos = 0;
|
||
|
|
Clear();
|
||
|
|
StartBulkLoad();
|
||
|
|
for(unsigned int i=0;i<tempsgms.size();i++)
|
||
|
|
{
|
||
|
|
URegionEmb out_ureg( tempsgms[i].unit_interval,
|
||
|
|
starting_segments_pos);
|
||
|
|
for(unsigned int j=0;j<(tempsgms[i].sgms).size();j++)
|
||
|
|
{
|
||
|
|
MSegmentData dms = (tempsgms[i].sgms)[j];
|
||
|
|
Rectangle<3> bbox = (Rectangle<3>)out_ureg.BoundingBox();
|
||
|
|
if (bbox.IsDefined())
|
||
|
|
{
|
||
|
|
double min[3] = { bbox.MinD(0), bbox.MinD(1), bbox.MinD(2) };
|
||
|
|
double max[3] = { bbox.MaxD(0), bbox.MaxD(1), bbox.MaxD(2) };
|
||
|
|
if (dms.GetInitialStartX() < min[0])
|
||
|
|
min[0] = dms.GetInitialStartX();
|
||
|
|
if (dms.GetFinalStartX() < min[0])
|
||
|
|
min[0] = dms.GetFinalStartX();
|
||
|
|
if (dms.GetInitialStartY() < min[1])
|
||
|
|
min[1] = dms.GetInitialStartY();
|
||
|
|
if (dms.GetFinalStartY() < min[1])
|
||
|
|
min[1] = dms.GetFinalStartY();
|
||
|
|
if (dms.GetInitialStartX() > max[0])
|
||
|
|
max[0] = dms.GetInitialStartX();
|
||
|
|
if (dms.GetFinalStartX() > max[0])
|
||
|
|
max[0] = dms.GetFinalStartX();
|
||
|
|
if (dms.GetInitialStartY() > max[1])
|
||
|
|
max[1] = dms.GetInitialStartY();
|
||
|
|
if (dms.GetFinalStartY() > max[1])
|
||
|
|
max[1] = dms.GetFinalStartY();
|
||
|
|
bbox.Set(true, min, max);
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "bbox was defined, just update it!!" << endl;
|
||
|
|
cout << "bbox.MinD0 : " << min[0] << endl;
|
||
|
|
cout << "bbox.MinD1 : " << min[1] << endl;
|
||
|
|
cout << "bbox.MinD2 : " << min[2] << endl;
|
||
|
|
cout << "bbox.MaxD0 : " << max[0] << endl;
|
||
|
|
cout << "bbox.MaxD1 : " << max[1] << endl;
|
||
|
|
cout << "bbox.MaxD2 : " << max[2] << endl;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
double min[3] = { dms.GetInitialStartX() < dms.GetFinalStartX()
|
||
|
|
? dms.GetInitialStartX() : dms.GetFinalStartX(),
|
||
|
|
dms.GetInitialStartY() < dms.GetFinalStartY()
|
||
|
|
? dms.GetInitialStartY() : dms.GetFinalStartY(),
|
||
|
|
out_ureg.timeInterval.start.ToDouble() };
|
||
|
|
double max[3] = { dms.GetInitialStartX() > dms.GetFinalStartX()
|
||
|
|
? dms.GetInitialStartX() : dms.GetFinalStartX(),
|
||
|
|
dms.GetInitialStartY() > dms.GetFinalStartY()
|
||
|
|
? dms.GetInitialStartY() : dms.GetFinalStartY(),
|
||
|
|
out_ureg.timeInterval.end.ToDouble() };
|
||
|
|
bbox.Set(true, min, max);
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "bbox was not defined!!" << endl;
|
||
|
|
cout << "bbox.MinD0 : " << min[0] << endl;
|
||
|
|
cout << "bbox.MinD1 : " << min[1] << endl;
|
||
|
|
cout << "bbox.MinD2 : " << min[2] << endl;
|
||
|
|
cout << "bbox.MaxD0 : " << max[0] << endl;
|
||
|
|
cout << "bbox.MaxD1 : " << max[1] << endl;
|
||
|
|
cout << "bbox.MaxD2 : " << max[2] << endl;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
out_ureg.PutSegment(
|
||
|
|
&msegmentdata,
|
||
|
|
j,
|
||
|
|
dms,
|
||
|
|
true
|
||
|
|
);
|
||
|
|
out_ureg.SetBBox(bbox);
|
||
|
|
starting_segments_pos++;
|
||
|
|
}
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << endl << "GetSegmentsNum(): "
|
||
|
|
<< out_ureg.GetSegmentsNum()
|
||
|
|
<< endl;
|
||
|
|
cout << "GetStartPos(): "
|
||
|
|
<< out_ureg.GetStartPos()
|
||
|
|
<< endl << endl;
|
||
|
|
}
|
||
|
|
|
||
|
|
Add(out_ureg);
|
||
|
|
}
|
||
|
|
EndBulkLoad( false );
|
||
|
|
|
||
|
|
MSegmentData tmp_dms;
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "Size of DbArray: " << msegmentdata.Size() << endl;
|
||
|
|
for(int i=0;i<msegmentdata.Size();i++)
|
||
|
|
{
|
||
|
|
msegmentdata.Get(i, &tmp_dms);
|
||
|
|
cout << endl << i << ": ["
|
||
|
|
<< tmp_dms.GetInitialStartX() << " , "
|
||
|
|
<< tmp_dms.GetInitialStartY() << " ; "
|
||
|
|
<< tmp_dms.GetInitialEndX() << " , "
|
||
|
|
<< tmp_dms.GetInitialEndY() << " ; "
|
||
|
|
<< tmp_dms.GetFinalStartX() << " , "
|
||
|
|
<< tmp_dms.GetFinalStartY() << " ; "
|
||
|
|
<< tmp_dms.GetFinalEndX() << " , "
|
||
|
|
<< tmp_dms.GetFinalEndY()
|
||
|
|
<< "]" << endl;
|
||
|
|
cout << "GetFaceNo: " << tmp_dms.GetFaceNo() << endl;
|
||
|
|
cout << "GetCycleNo: " << tmp_dms.GetCycleNo() << endl;
|
||
|
|
cout << "GetSegmentNo: " << tmp_dms.GetSegmentNo() << endl;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.15 Method Inside of class MPointExt
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
|
||
|
|
r: region
|
||
|
|
|
||
|
|
Return: an mbool
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
MBool MPointExt::Inside( const Region& r ) const
|
||
|
|
{
|
||
|
|
bool debugme=false;
|
||
|
|
MBool res(0);
|
||
|
|
if( !IsDefined() || !r.IsDefined() ){
|
||
|
|
res.SetDefined( false );
|
||
|
|
} else {
|
||
|
|
res.SetDefined( true );
|
||
|
|
Intime<Point> start, end;
|
||
|
|
Initial(start); Final(end);
|
||
|
|
Interval<Instant> dtime(start.instant, end.instant, true, true);
|
||
|
|
|
||
|
|
UPoint up(dtime,start.value.GetX(),start.value.GetY(),
|
||
|
|
start.value.GetX(),start.value.GetY());
|
||
|
|
MPoint mp(0);
|
||
|
|
mp.Add(up);
|
||
|
|
|
||
|
|
|
||
|
|
MRegion mr(mp, r);
|
||
|
|
mr.Inside( *(MPoint*)this, res);
|
||
|
|
if(debugme)
|
||
|
|
{
|
||
|
|
cout<< "mpoint = "; mp.Print(cout);
|
||
|
|
cout<< "\nmregion = "; mr.Print(cout);
|
||
|
|
cout<< "\nresult = "; res.Print(cout);
|
||
|
|
cout.flush();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return res;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
\subsection{Local Info Class for ~splitAtGaps~}
|
||
|
|
|
||
|
|
*/
|
||
|
|
template<class T, class U>
|
||
|
|
class SplitAtGapsLI {
|
||
|
|
public:
|
||
|
|
SplitAtGapsLI(T *src, DateTime *dur) : counter(0) {
|
||
|
|
U unit(true), lastUnit(true);
|
||
|
|
T *res = new T(true);
|
||
|
|
if (!src->IsEmpty()) {
|
||
|
|
src->Get(0, lastUnit);
|
||
|
|
res->Add(lastUnit);
|
||
|
|
if (dur == 0) {
|
||
|
|
if (src->GetNoComponents() > 1) {
|
||
|
|
for (int i = 1; i < src->GetNoComponents(); i++) {
|
||
|
|
src->Get(i, unit);
|
||
|
|
if (unit.timeInterval.start == lastUnit.timeInterval.end) {
|
||
|
|
res->MergeAdd(unit);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
result.push_back(res);
|
||
|
|
res = new T(true);
|
||
|
|
}
|
||
|
|
lastUnit = unit;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (src->GetNoComponents() > 1) {
|
||
|
|
for (int i = 1; i < src->GetNoComponents(); i++) {
|
||
|
|
src->Get(i, unit);
|
||
|
|
if (unit.timeInterval.start <= lastUnit.timeInterval.end + *dur) {
|
||
|
|
res->MergeAdd(unit);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
result.push_back(res);
|
||
|
|
res = new T(true);
|
||
|
|
}
|
||
|
|
lastUnit = unit;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
result.push_back(res);
|
||
|
|
}
|
||
|
|
|
||
|
|
T* nextResult() {
|
||
|
|
counter++;
|
||
|
|
if (counter - 1 >= result.size()) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
return result[counter - 1];
|
||
|
|
}
|
||
|
|
|
||
|
|
private:
|
||
|
|
vector<T*> result;
|
||
|
|
size_t counter;
|
||
|
|
};
|
||
|
|
|
||
|
|
/*
|
||
|
|
\subsection{Local Info Class for ~splitAtSpeed~}
|
||
|
|
|
||
|
|
*/
|
||
|
|
class SplitAtSpeedLI {
|
||
|
|
public:
|
||
|
|
SplitAtSpeedLI(MPoint *src, double maxspeed, Geoid *geoid) : counter(0) {
|
||
|
|
UPoint unit(true);
|
||
|
|
UReal uspeed(true);
|
||
|
|
MPoint *res = new MPoint(true);
|
||
|
|
if (src->IsEmpty()) {
|
||
|
|
result.push_back(res);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
bool correct1, correct2;
|
||
|
|
double min, max, speed;
|
||
|
|
for (int i = 0; i < src->GetNoComponents(); i++) {
|
||
|
|
src->Get(i, unit);
|
||
|
|
unit.USpeed(uspeed, geoid);
|
||
|
|
min = uspeed.Min(correct1);
|
||
|
|
max = uspeed.Max(correct2);
|
||
|
|
if (!correct1 || !correct2) {
|
||
|
|
if (correct1) {
|
||
|
|
speed = min;
|
||
|
|
}
|
||
|
|
else if (correct2) {
|
||
|
|
speed = max;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
speed = std::numeric_limits<double>::max();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
speed = (min + max) / 2;
|
||
|
|
}
|
||
|
|
if (speed <= maxspeed) {
|
||
|
|
res->MergeAdd(unit);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (!res->IsEmpty()) {
|
||
|
|
result.push_back(res);
|
||
|
|
res = new MPoint(true);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
result.push_back(res);
|
||
|
|
}
|
||
|
|
|
||
|
|
MPoint* nextResult() {
|
||
|
|
counter++;
|
||
|
|
if (counter - 1 >= result.size()) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
return result[counter - 1];
|
||
|
|
}
|
||
|
|
|
||
|
|
private:
|
||
|
|
vector<MPoint*> result;
|
||
|
|
size_t counter;
|
||
|
|
};
|
||
|
|
|
||
|
|
/*
|
||
|
|
\subsection{Local Info Class for ~splitAtLength~}
|
||
|
|
|
||
|
|
*/
|
||
|
|
class SplitAtLengthLI {
|
||
|
|
public:
|
||
|
|
SplitAtLengthLI(MPoint *src, double maxlength, Geoid *geoid) : counter(0) {
|
||
|
|
UPoint unit(true);
|
||
|
|
CcReal length(true, 0.0);
|
||
|
|
MPoint *res = new MPoint(true);
|
||
|
|
if (src->IsEmpty()) {
|
||
|
|
result.push_back(res);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
for (int i = 0; i < src->GetNoComponents(); i++) {
|
||
|
|
src->Get(i, unit);
|
||
|
|
if (geoid != 0) {
|
||
|
|
unit.Length(*geoid, length);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
unit.Length(length);
|
||
|
|
}
|
||
|
|
if (!length.IsDefined()) {
|
||
|
|
if (!res->IsEmpty()) { // split if length is undefined
|
||
|
|
result.push_back(res);
|
||
|
|
res = new MPoint(true);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (length.GetValue() <= maxlength) {
|
||
|
|
res->MergeAdd(unit);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (!res->IsEmpty()) { // split if maxlength is exceeded
|
||
|
|
result.push_back(res);
|
||
|
|
res = new MPoint(true);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
result.push_back(res);
|
||
|
|
}
|
||
|
|
|
||
|
|
MPoint* nextResult() {
|
||
|
|
counter++;
|
||
|
|
if (counter - 1 >= result.size()) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
return result[counter - 1];
|
||
|
|
}
|
||
|
|
|
||
|
|
private:
|
||
|
|
vector<MPoint*> result;
|
||
|
|
size_t counter;
|
||
|
|
};
|
||
|
|
|
||
|
|
/*
|
||
|
|
4 Auxiliary Functions
|
||
|
|
|
||
|
|
4.1 Aux. Function ~CheckURealDerivable~
|
||
|
|
|
||
|
|
Parameter:
|
||
|
|
unit: a pointer t a UReal object
|
||
|
|
|
||
|
|
Return: a boolean
|
||
|
|
|
||
|
|
*/
|
||
|
|
bool CheckURealDerivable(const UReal* unit)
|
||
|
|
{
|
||
|
|
assert( unit->IsDefined() );
|
||
|
|
UReal* tmp_unit = (UReal*)unit;
|
||
|
|
return !tmp_unit->r;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
4 Type Constructor ~istring~
|
||
|
|
|
||
|
|
Type ~istring~ represents an (instant, value)-pair of strings.
|
||
|
|
|
||
|
|
The list representation of an ~istring~ is
|
||
|
|
|
||
|
|
---- ( t string-value )
|
||
|
|
----
|
||
|
|
|
||
|
|
For example:
|
||
|
|
|
||
|
|
---- ( (instant 1.0) "My String" )
|
||
|
|
----
|
||
|
|
|
||
|
|
4.1 function Describing the Signature of the Type Constructor
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
IntimeStringProperty()
|
||
|
|
{
|
||
|
|
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("(istring) "),
|
||
|
|
nl->StringAtom("(instant string-value)"),
|
||
|
|
nl->StringAtom("((instant 0.5) My String)"))));
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
4.2 Kind Checking Function
|
||
|
|
|
||
|
|
This function checks whether the type constructor is applied correctly.
|
||
|
|
|
||
|
|
*/
|
||
|
|
bool
|
||
|
|
CheckIntimeString( ListExpr type, ListExpr& errorInfo )
|
||
|
|
{
|
||
|
|
return (nl->IsEqual( type, Intime<CcString>::BasicType() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
4.3 Creation of the type constructor ~istring~
|
||
|
|
|
||
|
|
*/
|
||
|
|
TypeConstructor intimestring(
|
||
|
|
Intime<CcString>::BasicType(), //name
|
||
|
|
IntimeStringProperty, //property function describing signature
|
||
|
|
OutIntime<CcString, OutCcString>,
|
||
|
|
InIntime<CcString, InCcString>, //Out and In functions
|
||
|
|
0,
|
||
|
|
0, //SaveToList and RestoreFromList functions
|
||
|
|
CreateIntime<CcString>,
|
||
|
|
DeleteIntime<CcString>, //object creation and deletion
|
||
|
|
0,
|
||
|
|
0, // object open and save
|
||
|
|
CloseIntime<CcString>,
|
||
|
|
CloneIntime<CcString>, //object close and clone
|
||
|
|
CastIntime<CcString>, //cast function
|
||
|
|
SizeOfIntime<CcString>, //sizeof function
|
||
|
|
CheckIntimeString //kind checking function
|
||
|
|
);
|
||
|
|
|
||
|
|
/*
|
||
|
|
5 Type Constructor ~ustring~
|
||
|
|
|
||
|
|
Type ~ustring~ represents an (tinterval, stringvalue)-pair.
|
||
|
|
|
||
|
|
5.1 List Representation
|
||
|
|
|
||
|
|
The list representation of an ~ustring~ is
|
||
|
|
|
||
|
|
---- ( timeinterval string-value )
|
||
|
|
----
|
||
|
|
|
||
|
|
For example:
|
||
|
|
|
||
|
|
---- ( ( (instant 6.37) (instant 9.9) TRUE FALSE) ["]My String["] )
|
||
|
|
----
|
||
|
|
|
||
|
|
5.2 function Describing the Signature of the Type Constructor
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
UStringProperty()
|
||
|
|
{
|
||
|
|
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("(ustring) "),
|
||
|
|
nl->StringAtom("(timeInterval string) "),
|
||
|
|
nl->StringAtom("((i1 i2 FALSE FALSE) My String)"))));
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.3 Kind Checking Function
|
||
|
|
|
||
|
|
*/
|
||
|
|
bool
|
||
|
|
CheckUString( ListExpr type, ListExpr& errorInfo )
|
||
|
|
{
|
||
|
|
return (nl->IsEqual( type, UString::BasicType() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.4 Creation of the type constructor ~uint~
|
||
|
|
|
||
|
|
*/
|
||
|
|
TypeConstructor unitstring(
|
||
|
|
UString::BasicType(), //name
|
||
|
|
UStringProperty, //property function describing signature
|
||
|
|
OutConstTemporalUnit<CcString, OutCcString>,
|
||
|
|
InConstTemporalUnit<CcString, InCcString>, //Out and In functions
|
||
|
|
0,
|
||
|
|
0, //SaveToList and RestoreFromList functions
|
||
|
|
CreateConstTemporalUnit<CcString>,
|
||
|
|
DeleteConstTemporalUnit<CcString>, //object creation and deletion
|
||
|
|
0,
|
||
|
|
0, // object open and save
|
||
|
|
CloseConstTemporalUnit<CcString>,
|
||
|
|
CloneConstTemporalUnit<CcString>, //object close and clone
|
||
|
|
CastConstTemporalUnit<CcString>, //cast function
|
||
|
|
SizeOfConstTemporalUnit<CcString>, //sizeof function
|
||
|
|
CheckUString //kind checking function
|
||
|
|
);
|
||
|
|
|
||
|
|
/*
|
||
|
|
6 Type Constructor ~mstring~
|
||
|
|
|
||
|
|
Type ~mstring~ represents a moving string.
|
||
|
|
|
||
|
|
6.1 List Representation
|
||
|
|
|
||
|
|
The list representation of a ~mstring~ is
|
||
|
|
|
||
|
|
---- ( u1 ... un )
|
||
|
|
----
|
||
|
|
|
||
|
|
,where u1, ..., un are units of type ~ustring~.
|
||
|
|
|
||
|
|
For example:
|
||
|
|
|
||
|
|
---- (
|
||
|
|
( (instant 6.37) (instant 9.9) TRUE FALSE) ["]String 1["] )
|
||
|
|
( (instant 11.4) (instant 13.9) FALSE FALSE) ["]String 2["] )
|
||
|
|
)
|
||
|
|
----
|
||
|
|
|
||
|
|
6.2 function Describing the Signature of the Type Constructor
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
MStringProperty()
|
||
|
|
{
|
||
|
|
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("(mstring) "),
|
||
|
|
nl->StringAtom("( u1 ... un)"),
|
||
|
|
nl->StringAtom("(((i1 i2 TRUE TRUE) My String) ...)"))));
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
6.3 Kind Checking Function
|
||
|
|
|
||
|
|
This function checks whether the type constructor is applied correctly.
|
||
|
|
|
||
|
|
*/
|
||
|
|
bool
|
||
|
|
CheckMString( ListExpr type, ListExpr& errorInfo )
|
||
|
|
{
|
||
|
|
return (nl->IsEqual( type, MString::BasicType() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
6.4 Creation of the type constructor ~mstring~
|
||
|
|
|
||
|
|
*/
|
||
|
|
TypeConstructor movingstring(
|
||
|
|
MString::BasicType(), //name
|
||
|
|
MStringProperty, //property function describing signature
|
||
|
|
//Out and In functions
|
||
|
|
OutMapping<MString, UString, OutConstTemporalUnit<CcString, OutCcString> >,
|
||
|
|
InMapping<MString, UString, InConstTemporalUnit<CcString, InCcString> >,
|
||
|
|
0,
|
||
|
|
0, //SaveToList and RestoreFromList functions
|
||
|
|
CreateMapping<MString>,
|
||
|
|
DeleteMapping<MString>, //object creation and deletion
|
||
|
|
0,
|
||
|
|
0, // object open and save
|
||
|
|
CloseMapping<MString>,
|
||
|
|
CloneMapping<MString>, //object close and clone
|
||
|
|
CastMapping<MString>, //cast function
|
||
|
|
SizeOfMapping<MString>, //sizeof function
|
||
|
|
CheckMString //kind checking function
|
||
|
|
);
|
||
|
|
|
||
|
|
/*
|
||
|
|
7 Type Constructor ~rbool~
|
||
|
|
|
||
|
|
Type ~rbool~ represents a range bool.
|
||
|
|
|
||
|
|
7.1 List Representation
|
||
|
|
|
||
|
|
The list representation of a ~rbool~ is
|
||
|
|
|
||
|
|
---- ( (bb1 eb1 lc1 rc1) (bb2 eb2 lc2 rc2) ... (bbn ebn lcn rcn) )
|
||
|
|
----
|
||
|
|
|
||
|
|
|
||
|
|
For example:
|
||
|
|
|
||
|
|
---- (
|
||
|
|
( (TRUE FALSE TRUE FALSE) (FALSE FALSE TRUE TRUE) )
|
||
|
|
)
|
||
|
|
----
|
||
|
|
|
||
|
|
7.2 Function describing the Signature of the Type Constructor
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
RangeBoolProperty()
|
||
|
|
{
|
||
|
|
ListExpr remarkslist = nl->TextAtom();
|
||
|
|
nl->AppendText(remarkslist,
|
||
|
|
"lci means left closed interval, rci respectively right closed interval,"
|
||
|
|
" e.g. (TRUE TRUE TRUE FALSE) means the range [TRUE, TRUE[");
|
||
|
|
|
||
|
|
return (nl->TwoElemList(
|
||
|
|
nl->FiveElemList(nl->StringAtom("Signature"),
|
||
|
|
nl->StringAtom("Example Type List"),
|
||
|
|
nl->StringAtom("List Rep"),
|
||
|
|
nl->StringAtom("Example List"),
|
||
|
|
nl->StringAtom("Remarks")),
|
||
|
|
nl->FiveElemList(nl->StringAtom("-> RANGE"),
|
||
|
|
nl->StringAtom("(rbool) "),
|
||
|
|
nl->StringAtom("((bb1 eb1 lci rci) ... (bbn ebn lci rci))"),
|
||
|
|
nl->StringAtom("((TRUE TRUE TRUE FALSE) (FALSE FALSE TRUE TRUE))"),
|
||
|
|
remarkslist)));
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
7.3 Kind Checking Function
|
||
|
|
|
||
|
|
This function checks whether the type constructor is applied correctly.
|
||
|
|
|
||
|
|
*/
|
||
|
|
bool
|
||
|
|
CheckRBool( ListExpr type, ListExpr& errorInfo )
|
||
|
|
{
|
||
|
|
return (nl->IsEqual( type, RBool::BasicType() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
7.4 Creation of the type constructor ~rbool~
|
||
|
|
|
||
|
|
*/
|
||
|
|
TypeConstructor rangebool(
|
||
|
|
RBool::BasicType(), //name
|
||
|
|
RangeBoolProperty, //property function describing signature
|
||
|
|
OutRange<CcBool, OutCcBool>,
|
||
|
|
InRange<CcBool, InCcBool>, //Out and In functions
|
||
|
|
0, 0, //SaveToList and RestoreFromList functions
|
||
|
|
CreateRange<CcBool>,DeleteRange<CcBool>, //object creation and deletion
|
||
|
|
OpenRange<CcBool>, SaveRange<CcBool>, // object open and save
|
||
|
|
CloseRange<CcBool>, CloneRange<CcBool>, //object close and clone
|
||
|
|
CastRange<CcBool>, //cast function
|
||
|
|
SizeOfRange<CcBool>, //sizeof function
|
||
|
|
CheckRBool //kind checking function
|
||
|
|
);
|
||
|
|
|
||
|
|
/*
|
||
|
|
8 Type Constructor ~rstring~
|
||
|
|
|
||
|
|
Type ~rstring~ represents a range string.
|
||
|
|
|
||
|
|
8.1 List Representation
|
||
|
|
|
||
|
|
The list representation of a ~rstring~ is
|
||
|
|
|
||
|
|
---- ( (bs1 es1 lc1 rc1) (bs2 es2 lc2 rc2) ... (bsn esn lcn rcn) )
|
||
|
|
----
|
||
|
|
|
||
|
|
|
||
|
|
For example:
|
||
|
|
|
||
|
|
---- (
|
||
|
|
( (["]First string["] ["]Second string["] TRUE FALSE)
|
||
|
|
(["]New York["] ["]Washington["] TRUE TRUE) )
|
||
|
|
)
|
||
|
|
----
|
||
|
|
|
||
|
|
8.2 function Describing the Signature of the Type Constructor
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
RangeStringProperty()
|
||
|
|
{
|
||
|
|
ListExpr remarkslist = nl->TextAtom();
|
||
|
|
nl->AppendText(remarkslist,
|
||
|
|
"lci means left closed interval, rci respectively right closed interval,"
|
||
|
|
" e.g. (String1 String2 TRUE FALSE) means the range [String1, String2[");
|
||
|
|
|
||
|
|
return (nl->TwoElemList(
|
||
|
|
nl->FiveElemList(nl->StringAtom("Signature"),
|
||
|
|
nl->StringAtom("Example Type List"),
|
||
|
|
nl->StringAtom("List Rep"),
|
||
|
|
nl->StringAtom("Example List"),
|
||
|
|
nl->StringAtom("Remarks")),
|
||
|
|
nl->FiveElemList(nl->StringAtom("-> RANGE"),
|
||
|
|
nl->StringAtom("(rstring) "),
|
||
|
|
nl->StringAtom("((bs1 es1 lci rci) ... (bsn esn lci rci))"),
|
||
|
|
nl->StringAtom("((String1 String2 TRUE FALSE))"), remarkslist)));
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
8.3 Kind Checking Function
|
||
|
|
|
||
|
|
This function checks whether the type constructor is applied correctly.
|
||
|
|
|
||
|
|
*/
|
||
|
|
bool
|
||
|
|
CheckRString( ListExpr type, ListExpr& errorInfo )
|
||
|
|
{
|
||
|
|
return (nl->IsEqual( type, RString::BasicType() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
8.4 Creation of the type constructor ~rstring~
|
||
|
|
|
||
|
|
*/
|
||
|
|
TypeConstructor rangestring(
|
||
|
|
RString::BasicType(), //name
|
||
|
|
RangeStringProperty, //property function describing signature
|
||
|
|
OutRange<CcString, OutCcString>,
|
||
|
|
InRange<CcString, InCcString>, //Out and In functions
|
||
|
|
0, 0, //SaveToList and RestoreFromList functions
|
||
|
|
CreateRange<CcString>,DeleteRange<CcString>, //obj. creation and deletion
|
||
|
|
OpenRange<CcString>, SaveRange<CcString>, // object open and save
|
||
|
|
CloseRange<CcString>, CloneRange<CcString>, //object close and clone
|
||
|
|
CastRange<CcString>, //cast function
|
||
|
|
SizeOfRange<CcString>, //sizeof function
|
||
|
|
CheckRString //kind checking function
|
||
|
|
);
|
||
|
|
|
||
|
|
/*
|
||
|
|
9 Operators
|
||
|
|
|
||
|
|
9.1 Type mapping function
|
||
|
|
|
||
|
|
A type mapping function takes a nested list as argument. Its contents are
|
||
|
|
type descriptions of an operator's input parameters. A nested list describing
|
||
|
|
the output type of the operator is returned.
|
||
|
|
|
||
|
|
9.1.1 Type mapping function ~MovingInstantTypeMapIntime~
|
||
|
|
|
||
|
|
It is for the operator ~atinstant~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
MovingInstantExtTypeMapIntime( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( nl->ListLength( args ) == 2 )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args ),
|
||
|
|
arg2 = nl->Second( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg2, Instant::BasicType() ) )
|
||
|
|
{
|
||
|
|
if( nl->IsEqual( arg1, MString::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( Intime<CcString>::BasicType() );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.2 Type mapping function ~MovingPeriodsTypeMapMoving~
|
||
|
|
|
||
|
|
It is for the operator ~atperiods~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
MovingPeriodsExtTypeMapMoving( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( nl->ListLength( args ) == 2 )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args ),
|
||
|
|
arg2 = nl->Second( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg2, Periods::BasicType() ) )
|
||
|
|
{
|
||
|
|
if( nl->IsEqual( arg1, MString::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MString::BasicType() );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MRegion::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MRegion::BasicType() );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.3 Type mapping function ~MovingTypeMapeIntime~
|
||
|
|
|
||
|
|
It is for the operators ~initial~ and ~final~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
MovingExtTypeMapIntime( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MString::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( Intime<CcString>::BasicType() );
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.4 Type mapping function ~MovingInstantPeriodsTypeMapBool~
|
||
|
|
|
||
|
|
It is for the operator ~present~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
MovingInstantPeriodsExtTypeMapBool( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( nl->ListLength( args ) == 2 )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args ),
|
||
|
|
arg2 = nl->Second( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg2, Instant::BasicType() ) ||
|
||
|
|
nl->IsEqual( arg2, Periods::BasicType() ) )
|
||
|
|
{
|
||
|
|
if( nl->IsEqual( arg1, MString::BasicType() ))
|
||
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.5 Type mapping function ~MovingBaseTypeMapBool~
|
||
|
|
|
||
|
|
It is for the operator ~at~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
MovingBaseExtTypeMapMoving( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1, arg2;
|
||
|
|
if( nl->ListLength( args ) == 2 )
|
||
|
|
{
|
||
|
|
arg1 = nl->First( args );
|
||
|
|
arg2 = nl->Second( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MReal::BasicType() )
|
||
|
|
&& nl->IsEqual( arg2, CcReal::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MReal::BasicType() );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MString::BasicType() )
|
||
|
|
&& nl->IsEqual( arg2, CcString::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MString::BasicType() );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MBool::BasicType() )
|
||
|
|
&& nl->IsEqual( arg2, RBool::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MBool::BasicType() );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MInt::BasicType() )
|
||
|
|
&& nl->IsEqual( arg2, RInt::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MInt::BasicType() );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MString::BasicType() )
|
||
|
|
&& nl->IsEqual( arg2, RString::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MString::BasicType() );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MReal::BasicType() )
|
||
|
|
&& nl->IsEqual( arg2, RReal::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MReal::BasicType() );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MPoint::BasicType() )
|
||
|
|
&& nl->IsEqual( arg2, Points::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MPoint::BasicType() );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MPoint::BasicType() )
|
||
|
|
&& nl->IsEqual( arg2, Line::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MPoint::BasicType() );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MRegion::BasicType() )
|
||
|
|
&& nl->IsEqual( arg2, Point::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MPoint::BasicType() );
|
||
|
|
}
|
||
|
|
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.6 Type mapping function ~MovingBaseTypeMapBool~
|
||
|
|
|
||
|
|
It is for the operator ~passes~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
MovingBaseExtTypeMapBool( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1, arg2;
|
||
|
|
if( nl->ListLength( args ) == 2 )
|
||
|
|
{
|
||
|
|
arg1 = nl->First( args );
|
||
|
|
arg2 = nl->Second( args );
|
||
|
|
|
||
|
|
if( (nl->IsEqual( arg1, MReal::BasicType() )
|
||
|
|
&& nl->IsEqual( arg2, CcReal::BasicType() ))
|
||
|
|
||
|
||
|
|
(nl->IsEqual( arg1, MString::BasicType() )
|
||
|
|
&& nl->IsEqual( arg2, CcString::BasicType() ))
|
||
|
|
||
|
||
|
|
(nl->IsEqual( arg1, MPoint::BasicType() )
|
||
|
|
&& nl->IsEqual( arg2, Points::BasicType() ))
|
||
|
|
||
|
||
|
|
(nl->IsEqual( arg1, MPoint::BasicType() )
|
||
|
|
&& nl->IsEqual( arg2, Line::BasicType() ))
|
||
|
|
||
|
||
|
|
(nl->IsEqual( arg1, MRegion::BasicType() )
|
||
|
|
&& nl->IsEqual( arg2, Point::BasicType() ))
|
||
|
|
||
|
||
|
|
(nl->IsEqual( arg1, MRegion::BasicType() )
|
||
|
|
&& nl->IsEqual( arg2, Points::BasicType() ))
|
||
|
|
)
|
||
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.7 Type mapping function ~MovingTypeMapRange~
|
||
|
|
|
||
|
|
It is for the operator ~deftime~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
MovingExtTypeMapPeriods( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MString::BasicType() ))
|
||
|
|
|
||
|
|
return nl->SymbolAtom( Periods::BasicType() );
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.8 Type mapping function ~IntimeTypeMapInstant~
|
||
|
|
|
||
|
|
It is for the operator ~inst~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
IntimeExtTypeMapInstant( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, Intime<CcString>::BasicType() ))
|
||
|
|
return nl->SymbolAtom( Instant::BasicType() );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, IRegion::BasicType() ))
|
||
|
|
return nl->SymbolAtom( Instant::BasicType() );
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.9 Type mapping function ~IntimeTypeMapBase~
|
||
|
|
|
||
|
|
It is for the operator ~val~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
IntimeExtTypeMapBase( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, Intime<CcString>::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( CcString::BasicType() );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, IRegion::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( Region::BasicType() );
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.10 Type mapping function ~MovingRExtTypeMapMovingR~
|
||
|
|
|
||
|
|
It is for the operator ~derivative~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
MovingRExtTypeMapMovingR( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MReal::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MReal::BasicType() );
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.11 Type mapping function ~MovingRExtTypeMapBool~
|
||
|
|
|
||
|
|
It is for the operator ~derivable~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
MovingRExtTypeMapBool( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MReal::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MBool::BasicType() );
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.12 Type mapping function ~MovingPointExtTypeMapMReal~
|
||
|
|
|
||
|
|
It is for the operators ~speed~, ~direction~, and ~heading~
|
||
|
|
|
||
|
|
---- mpoint [ x geoid [ x real ] ] --> mreal
|
||
|
|
----
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
MovingPointExtTypeMapMReal( ListExpr args )
|
||
|
|
{
|
||
|
|
int noargs = nl->ListLength( args );
|
||
|
|
if ( (noargs<1) || (noargs>3) ){
|
||
|
|
return listutils::typeError("Expecting 1 or 2 arguments.");
|
||
|
|
}
|
||
|
|
if(!listutils::isSymbol(nl->First( args ),MPoint::BasicType())){
|
||
|
|
return listutils::typeError("Expecting mpoint as 1st argument.");
|
||
|
|
}
|
||
|
|
if((noargs>=2) && !listutils::isSymbol(nl->Second(args),Geoid::BasicType())){
|
||
|
|
return listutils::typeError("Expecting geoid as 2nd argument.");
|
||
|
|
}
|
||
|
|
if((noargs==3) && !listutils::isSymbol(nl->Second(args),Geoid::BasicType())){
|
||
|
|
return listutils::typeError("Expecting real as 3rd argument.");
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( MReal::BasicType() );
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.12 Type mapping function ~MPointOptGeoid2MReal\_TM~
|
||
|
|
~Avg\_SpeedTypeMap~
|
||
|
|
|
||
|
|
signatures:
|
||
|
|
mpoint [ x geoid ] -> real
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr MPointOptGeoid2MReal_TM(ListExpr args){
|
||
|
|
string errmsg = "Expected (mpoint) or (mpoint x geoid).";
|
||
|
|
int noargs = nl->ListLength(args);
|
||
|
|
if((noargs<1) || (noargs>2)){
|
||
|
|
return listutils::typeError(errmsg);
|
||
|
|
}
|
||
|
|
if(!listutils::isSymbol(nl->First(args),MPoint::BasicType())){
|
||
|
|
return listutils::typeError(errmsg);
|
||
|
|
}
|
||
|
|
if( (noargs==2)
|
||
|
|
&& (!listutils::isSymbol(nl->Second(args),Geoid::BasicType())) ){
|
||
|
|
return listutils::typeError(errmsg);
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom(MReal::BasicType());
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.13 Type mapping function RangeRangevaluesExtTypeMapRange
|
||
|
|
|
||
|
|
It is for the operator ~rangevalues~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
RangeRangevaluesExtTypeMapRange( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MBool::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( RBool::BasicType() );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MInt::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( RInt::BasicType() );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MString::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( RString::BasicType() );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MReal::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( RReal::BasicType() );
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.14 Type mapping function MovingSANExtTypeMap
|
||
|
|
|
||
|
|
It is for the operators ~sometimes~, ~always~ and ~never~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
MovingSANExtTypeMap( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MBool::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.15 Type mapping function ~MPointExtTypeMapMPoint~
|
||
|
|
|
||
|
|
It is for the operator ~velocity~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
MPointExtTypeMapMPoint( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MPoint::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MPoint::BasicType() );
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.16 Type mapping function RealPhysicalUnitsExtTypeMap
|
||
|
|
|
||
|
|
It is for the operators ~setunitoftime~ and ~setunitofdistance~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
RealPhysicalUnitsExtTypeMap( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, CcReal::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( CcReal::BasicType() );
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.17 Type mapping function MovingPointExtTypeMapPoints
|
||
|
|
|
||
|
|
It is for the operator ~locations~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
MovingPointExtTypeMapPoints( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MPoint::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( Points::BasicType() );
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.18 Type mapping function MovingExtTypeMapMoving
|
||
|
|
|
||
|
|
It is for the operators ~atmin~ and ~atmax~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr
|
||
|
|
MovingExtTypeMapMoving( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->IsEqual( arg1, MInt::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MInt::BasicType() );
|
||
|
|
if( nl->IsEqual( arg1, MBool::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MBool::BasicType() );
|
||
|
|
if( nl->IsEqual( arg1, MString::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MString::BasicType() );
|
||
|
|
if( nl->IsEqual( arg1, MReal::BasicType() ) )
|
||
|
|
return nl->SymbolAtom( MReal::BasicType() );
|
||
|
|
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.19 Type mapping for the concatS operator
|
||
|
|
|
||
|
|
This operator concatenates a stream of stream of mpoints which are
|
||
|
|
sorted in time dimension.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
ListExpr
|
||
|
|
ConcatSTypeMap(ListExpr args){
|
||
|
|
|
||
|
|
int len = nl->ListLength(args);
|
||
|
|
if((len!=1) && (len!=2)){
|
||
|
|
ErrorReporter::ReportError("one or two arguments required.");
|
||
|
|
return nl->TypeError();
|
||
|
|
}
|
||
|
|
if(len==2){
|
||
|
|
if(!nl->IsEqual(nl->Second(args),CcInt::BasicType())){
|
||
|
|
ErrorReporter::ReportError("stream(mpoint) or "
|
||
|
|
"stream(mpoint) x int required");
|
||
|
|
return nl->TypeError();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ListExpr stream = nl->First(args);
|
||
|
|
if( nl->ListLength(stream)!=2 ||
|
||
|
|
!nl->IsEqual(nl->First(stream),Symbol::STREAM()) ||
|
||
|
|
!nl->IsEqual(nl->Second(stream),MPoint::BasicType())){
|
||
|
|
ErrorReporter::ReportError("stream(mpoint) expected.");
|
||
|
|
return nl->TypeError();
|
||
|
|
}
|
||
|
|
return nl->SymbolAtom(MPoint::BasicType());
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.20 Type mapping for ~evernearerthan~
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
const string mapsEverNearerThan[3][4] =
|
||
|
|
{
|
||
|
|
{MPoint::BasicType(),MPoint::BasicType(),
|
||
|
|
CcReal::BasicType(),CcBool::BasicType()},
|
||
|
|
{MPoint::BasicType(),Point::BasicType(),
|
||
|
|
CcReal::BasicType(),CcBool::BasicType()},
|
||
|
|
{Point::BasicType(), MPoint::BasicType(),
|
||
|
|
CcReal::BasicType(),CcBool::BasicType()}
|
||
|
|
};
|
||
|
|
|
||
|
|
ListExpr
|
||
|
|
EverNearerThan_tm( ListExpr args )
|
||
|
|
{
|
||
|
|
return SimpleMaps<3,4>(mapsEverNearerThan, args);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.1.20 Type mapping for ~inside~
|
||
|
|
|
||
|
|
signatures:
|
||
|
|
mpoint X region -> mbool
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr InsideTypeMapMPR(ListExpr args){
|
||
|
|
string err = "mpoint x region expected";
|
||
|
|
int len = nl->ListLength(args);
|
||
|
|
if(len!=2){
|
||
|
|
ErrorReporter::ReportError(err);
|
||
|
|
return nl->TypeError();
|
||
|
|
}
|
||
|
|
|
||
|
|
if(nl->IsEqual(nl->First(args),MPoint::BasicType()) &&
|
||
|
|
nl->IsEqual(nl->Second(args),Region::BasicType())){
|
||
|
|
return nl->SymbolAtom(MBool::BasicType());
|
||
|
|
}
|
||
|
|
ErrorReporter::ReportError(err);
|
||
|
|
return nl->TypeError();
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
\subsubsection{Type Mapping for ~berlin2wgs~}
|
||
|
|
|
||
|
|
signatures:
|
||
|
|
ipoint -> ipoint
|
||
|
|
upoint -> upoint
|
||
|
|
mpoint -> mpoint
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr berlin2wgsTM_lifted(ListExpr args) {
|
||
|
|
if (!nl->HasLength(args, 1)) {
|
||
|
|
return listutils::typeError("Exactly one argument expected.");
|
||
|
|
}
|
||
|
|
if (IPoint::checkType(nl->First(args)) ||
|
||
|
|
UPoint::checkType(nl->First(args)) ||
|
||
|
|
MPoint::checkType(nl->First(args))) {
|
||
|
|
return nl->First(args);
|
||
|
|
}
|
||
|
|
return listutils::typeError("Type ipoint, upoint, or mpoint expected.");
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
\subsubsection{Type Mapping for ~splitAtGaps~}
|
||
|
|
|
||
|
|
signatures:
|
||
|
|
mT (x duration) -> stream(mT), for T in {bool, int, real, string, label(s),
|
||
|
|
place(s), point, region}
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr splitatgapsTM(ListExpr args) {
|
||
|
|
if (!(nl->HasLength(args, 1) || nl->HasLength(args, 2))) {
|
||
|
|
return listutils::typeError("Either one or two arguments expected");
|
||
|
|
}
|
||
|
|
ListExpr a1 = nl->First(args);
|
||
|
|
if (!(MBool::checkType(a1) || MInt::checkType(a1) || MReal::checkType(a1) ||
|
||
|
|
MString::checkType(a1) || stj::MLabel::checkType(a1) ||
|
||
|
|
stj::MLabels::checkType(a1) || stj::MPlace::checkType(a1) ||
|
||
|
|
stj::MPlaces::checkType(a1) || MPoint::checkType(a1) ||
|
||
|
|
MRegion::checkType(a1))) {
|
||
|
|
return listutils::typeError("First argument must have one of the types "
|
||
|
|
"{mbool, mint, mreal, mstring, mlabel(s), mplace(s), mpoint, mregion}");
|
||
|
|
}
|
||
|
|
if (nl->HasLength(args, 2)) {
|
||
|
|
if (!Duration::checkType(nl->Second(args))) {
|
||
|
|
return listutils::typeError("Second argument must be a duration");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()), a1);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
\subsubsection{Type Mapping for ~splitAtSpeed~ and ~splitAtLength~}
|
||
|
|
|
||
|
|
signature:
|
||
|
|
mpoint x real (x geoid) -> stream(mpoint)
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr splitatspeedlengthTM(ListExpr args) {
|
||
|
|
if (!(nl->HasLength(args, 2) || nl->HasLength(args, 3))) {
|
||
|
|
return listutils::typeError("Either two or three arguments expected");
|
||
|
|
}
|
||
|
|
if (!MPoint::checkType(nl->First(args))) {
|
||
|
|
return listutils::typeError("First argument must be an mpoint");
|
||
|
|
}
|
||
|
|
if (!CcReal::checkType(nl->Second(args))) {
|
||
|
|
return listutils::typeError("Second argument must be a real");
|
||
|
|
}
|
||
|
|
if (nl->HasLength(args, 3)) {
|
||
|
|
if (!Geoid::checkType(nl->Third(args))) {
|
||
|
|
return listutils::typeError("Third argument must be a geoid");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
||
|
|
nl->SymbolAtom(MPoint::BasicType()));
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.2 Selection function
|
||
|
|
|
||
|
|
A selection function is quite similar to a type mapping function. The only
|
||
|
|
difference is that it doesn't return a type but the index of a value
|
||
|
|
mapping function being able to deal with the respective combination of
|
||
|
|
input parameter types.
|
||
|
|
|
||
|
|
Note that a selection function does not need to check the correctness of
|
||
|
|
argument types; it has already been checked by the type mapping function that it
|
||
|
|
is applied to correct arguments.
|
||
|
|
|
||
|
|
9.2.1 Selection function ~MovingSimpleSelect~
|
||
|
|
|
||
|
|
Is used for the ~deftime~, ~initial~, ~final~, ~inst~, ~val~,
|
||
|
|
~atinstant~,
|
||
|
|
~atperiods~ operations.
|
||
|
|
|
||
|
|
*/
|
||
|
|
int
|
||
|
|
MovingExtSimpleSelect( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MString::BasicType() )
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
return -1; // This point should never be reached
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.2.2 Selection function ~MovingInstantPeriodsSelect~
|
||
|
|
|
||
|
|
Is used for the ~present~ operations.
|
||
|
|
|
||
|
|
*/
|
||
|
|
int
|
||
|
|
MovingExtInstantPeriodsSelect( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args ),
|
||
|
|
arg2 = nl->Second( args );
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MString::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == Instant::BasicType() )
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MString::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == Periods::BasicType() )
|
||
|
|
return 1;
|
||
|
|
|
||
|
|
return -1; // This point should never be reached
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.2.3 Selection function MovingBaseRangeSelect
|
||
|
|
|
||
|
|
Is used for the ~at~ operations.
|
||
|
|
|
||
|
|
*/
|
||
|
|
int
|
||
|
|
MovingExtBaseRangeSelect( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args ),
|
||
|
|
arg2 = nl->Second( args );
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MReal::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == CcReal::BasicType() )
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MString::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == CcString::BasicType() )
|
||
|
|
return 1;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MBool::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == RBool::BasicType() )
|
||
|
|
return 2;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MInt::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == RInt::BasicType() )
|
||
|
|
return 3;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MString::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == RString::BasicType() )
|
||
|
|
return 4;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MReal::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == RReal::BasicType())
|
||
|
|
return 5;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MPoint::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == Points::BasicType())
|
||
|
|
return 6;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MPoint::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == Line::BasicType())
|
||
|
|
return 7;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MRegion::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == Point::BasicType())
|
||
|
|
return 8;
|
||
|
|
|
||
|
|
return -1; // This point should never be reached
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.2.4 Selection function ~MovingBaseSelect~
|
||
|
|
|
||
|
|
Is used for the ~passes~ operations.
|
||
|
|
|
||
|
|
*/
|
||
|
|
int
|
||
|
|
MovingExtBaseSelect( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args ),
|
||
|
|
arg2 = nl->Second( args );
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MReal::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == CcReal::BasicType() )
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MString::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == CcString::BasicType() )
|
||
|
|
return 1;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MPoint::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == Points::BasicType())
|
||
|
|
return 2;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MPoint::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == Line::BasicType())
|
||
|
|
return 3;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MRegion::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == Point::BasicType() )
|
||
|
|
return 4;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MRegion::BasicType() &&
|
||
|
|
nl->SymbolValue( arg2 ) == Points::BasicType() )
|
||
|
|
return 5;
|
||
|
|
|
||
|
|
return -1; // This point should never be reached
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.2.5 Selection function ~IntimeSimpleSelect~
|
||
|
|
|
||
|
|
Is used for the ~inst~ and ~val~ operations.
|
||
|
|
|
||
|
|
*/
|
||
|
|
int
|
||
|
|
IntimeExtSimpleSelect( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == Intime<CcString>::BasicType() )
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == IRegion::BasicType() )
|
||
|
|
return 1;
|
||
|
|
|
||
|
|
return -1; // This point should never be reached
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.2.6 Selection function RangeRangevaluesExtBaseSelect
|
||
|
|
|
||
|
|
Is used for the ~rangevalues~ operations.
|
||
|
|
|
||
|
|
*/
|
||
|
|
int
|
||
|
|
RangeRangevaluesExtBaseSelect( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MBool::BasicType() )
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MInt::BasicType() )
|
||
|
|
return 1;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MString::BasicType() )
|
||
|
|
return 2;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MReal::BasicType() )
|
||
|
|
return 3;
|
||
|
|
|
||
|
|
return -1; // This point should never be reached
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.2.7 Selection function ~MovingPeriodsSelect~
|
||
|
|
|
||
|
|
Is used for the ~atperiods~ operation.
|
||
|
|
|
||
|
|
*/
|
||
|
|
int
|
||
|
|
MovingPeriodsSelect( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MString::BasicType() )
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MRegion::BasicType() )
|
||
|
|
return 1;
|
||
|
|
|
||
|
|
return -1; // This point should never be reached
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.2.8 Selection function ~MovingAtMinMaxSelect~
|
||
|
|
|
||
|
|
Is used for the operators ~atmin~ and ~atmax~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
int
|
||
|
|
MovingAtMinMaxSelect( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1 = nl->First( args );
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MBool::BasicType() )
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MInt::BasicType() )
|
||
|
|
return 1;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MString::BasicType() )
|
||
|
|
return 2;
|
||
|
|
|
||
|
|
if( nl->SymbolValue( arg1 ) == MReal::BasicType() )
|
||
|
|
return 3;
|
||
|
|
|
||
|
|
return -1; // This point should never be reached
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.2.9 Selection Function for ~everNearerThan~
|
||
|
|
|
||
|
|
*/
|
||
|
|
int
|
||
|
|
EverNearerThan_sf( ListExpr args )
|
||
|
|
{
|
||
|
|
return SimpleSelect<3,4>(mapsEverNearerThan, args);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
\subsubsection{Selection Function for ~berlin2wgs~}
|
||
|
|
|
||
|
|
*/
|
||
|
|
int berlin2wgsSelect_lifted(ListExpr args) {
|
||
|
|
if (IPoint::checkType(nl->First(args))) return 0;
|
||
|
|
if (UPoint::checkType(nl->First(args))) return 1;
|
||
|
|
if (MPoint::checkType(nl->First(args))) return 2;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
\subsubsection{Selection Function for ~splitAtGaps~}
|
||
|
|
|
||
|
|
*/
|
||
|
|
int splitatgapsSelect(ListExpr args) {
|
||
|
|
if (MBool::checkType(nl->First(args))) return 0;
|
||
|
|
if (MInt::checkType(nl->First(args))) return 1;
|
||
|
|
if (MReal::checkType(nl->First(args))) return 2;
|
||
|
|
if (MString::checkType(nl->First(args))) return 3;
|
||
|
|
if (stj::MLabel::checkType(nl->First(args))) return 4;
|
||
|
|
if (stj::MLabels::checkType(nl->First(args))) return 5;
|
||
|
|
if (stj::MPlace::checkType(nl->First(args))) return 6;
|
||
|
|
if (stj::MPlaces::checkType(nl->First(args))) return 7;
|
||
|
|
if (MPoint::checkType(nl->First(args))) return 8;
|
||
|
|
if (MRegion::checkType(nl->First(args))) return 9;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3 Value mapping functions
|
||
|
|
|
||
|
|
A value mapping function implements an operator's main functionality: it takes
|
||
|
|
input arguments and computes the result. Each operator consists of at least
|
||
|
|
one value mapping function. In the case of overloaded operators there are
|
||
|
|
several value mapping functions, one for each possible combination of input
|
||
|
|
parameter types.
|
||
|
|
|
||
|
|
9.3.1 Value mapping functions of operator ~atinstant~
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <class Mapping, class Alpha>
|
||
|
|
int MappingAtInstantExt(
|
||
|
|
Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
Intime<Alpha>* pResult = (Intime<Alpha>*)result.addr;
|
||
|
|
|
||
|
|
((Mapping*)args[0].addr)->AtInstant( *((Instant*)args[1].addr), *pResult );
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.2 Value mapping functions of operator ~atperiods~
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <class Mapping>
|
||
|
|
int MappingAtPeriodsExt( Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
((Mapping*)args[0].addr)->AtPeriods( *((Periods*)args[1].addr),
|
||
|
|
*((Mapping*)result.addr) );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int MappingAtPeriodsExtMRegion(
|
||
|
|
Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
MRegion* mr = (MRegion*)args[0].addr;
|
||
|
|
Periods* per = (Periods*)args[1].addr;
|
||
|
|
MRegion* pResult = (MRegion*)result.addr;
|
||
|
|
|
||
|
|
pResult->AtPeriods(per, mr);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.3 Value mapping functions of operator ~initial~
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <class Mapping, class Unit, class Alpha>
|
||
|
|
int MappingInitialExt( Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
Mapping *m = ((Mapping*)args[0].addr);
|
||
|
|
Intime<Alpha>* pResult = ((Intime<Alpha>*)result.addr);
|
||
|
|
|
||
|
|
Unit unit;
|
||
|
|
m->Get( 0, unit );
|
||
|
|
|
||
|
|
if( m->IsDefined() && unit.timeInterval.lc )
|
||
|
|
m->Initial( *pResult );
|
||
|
|
else
|
||
|
|
pResult->SetDefined(false);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.4 Value mapping functions of operator ~final~
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <class Mapping, class Unit, class Alpha>
|
||
|
|
int MappingFinalExt( Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
Mapping *m = ((Mapping*)args[0].addr);
|
||
|
|
Intime<Alpha>* pResult = ((Intime<Alpha>*)result.addr);
|
||
|
|
|
||
|
|
Unit unit;
|
||
|
|
m->Get( m->GetNoComponents()-1, unit );
|
||
|
|
|
||
|
|
if( m->IsDefined() && unit.timeInterval.rc )
|
||
|
|
m->Final( *pResult );
|
||
|
|
else
|
||
|
|
pResult->SetDefined(false);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.5 Value mapping functions of operator ~present~
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <class Mapping>
|
||
|
|
int MappingPresentExt_i( Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
Mapping *m = ((Mapping*)args[0].addr);
|
||
|
|
Instant* inst = ((Instant*)args[1].addr);
|
||
|
|
|
||
|
|
if( !inst->IsDefined() )
|
||
|
|
((CcBool *)result.addr)->Set( false, false );
|
||
|
|
else
|
||
|
|
((CcBool *)result.addr)->Set( true, m->Present( *inst ) );
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <class Mapping>
|
||
|
|
int MappingPresentExt_p( Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
Mapping *m = ((Mapping*)args[0].addr);
|
||
|
|
Periods* periods = ((Periods*)args[1].addr);
|
||
|
|
|
||
|
|
if( periods->IsEmpty() )
|
||
|
|
((CcBool *)result.addr)->Set( false, false );
|
||
|
|
else
|
||
|
|
((CcBool *)result.addr)->Set( true, m->Present( *periods ) );
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.6 Value mapping functions of operator ~at~
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int MappingStringAtExt(
|
||
|
|
Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
MString *m = ((MString*)args[0].addr);
|
||
|
|
CcString* val = ((CcString*)args[1].addr);
|
||
|
|
MString* pResult = ((MString*)result.addr);
|
||
|
|
m->At( *val, *pResult );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int MappingRealAtExt(
|
||
|
|
Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
MReal *m = ((MReal*)args[0].addr);
|
||
|
|
CcReal* val = ((CcReal*)args[1].addr);
|
||
|
|
MReal* pResult = ((MReal*)result.addr);
|
||
|
|
m->AtValue( *val, *pResult );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <class Mapping, class Unit, class Alpha, class Range>
|
||
|
|
int MappingAtExt(
|
||
|
|
Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
MappingExt<Unit, Alpha> *m = ((MappingExt<Unit, Alpha>*)args[0].addr);
|
||
|
|
Range* rng = ((Range*)args[1].addr);
|
||
|
|
Mapping* pResult = ((Mapping*)result.addr);
|
||
|
|
m->At( rng, *pResult );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int MappingRRealAtExt(
|
||
|
|
Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
MRealExt *m = ((MRealExt*)args[0].addr);
|
||
|
|
RReal* rng = ((RReal*)args[1].addr);
|
||
|
|
MReal* pResult = ((MReal*)result.addr);
|
||
|
|
m->At( rng, *pResult );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int MappingMPointPointsAtExt(
|
||
|
|
Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
MPointExt *m = ((MPointExt*)args[0].addr);
|
||
|
|
Points* pts = ((Points*)args[1].addr);
|
||
|
|
MPoint* pResult = ((MPoint*)result.addr);
|
||
|
|
m->At( pts, *pResult );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int MappingMPointLineAtExt(
|
||
|
|
Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
MPointExt *m = ((MPointExt*)args[0].addr);
|
||
|
|
Line* ln = ((Line*)args[1].addr);
|
||
|
|
MPoint* pResult = ((MPoint*)result.addr);
|
||
|
|
m->At( ln, *pResult );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int MRegionPointAtExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
MRegion *m = ((MRegion*)args[0].addr);
|
||
|
|
Point* pt = ((Point*)args[1].addr);
|
||
|
|
MPoint* pResult = ((MPoint*)result.addr);
|
||
|
|
double time1 = 0.;
|
||
|
|
|
||
|
|
pResult->Clear();
|
||
|
|
if( !m->IsDefined() || !pt->IsDefined() ){
|
||
|
|
pResult->SetDefined( false );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
pResult->SetDefined( true );
|
||
|
|
|
||
|
|
clock_t clock1 = clock();
|
||
|
|
MPoint tmp(1);
|
||
|
|
URegionEmb urtmp1;
|
||
|
|
URegionEmb urtmp2;
|
||
|
|
m->Get( 0, urtmp1 );
|
||
|
|
m->Get( m->GetNoComponents()-1, urtmp2 );
|
||
|
|
|
||
|
|
Interval<Instant> inv_tmp;
|
||
|
|
inv_tmp.start = urtmp1.timeInterval.start;
|
||
|
|
inv_tmp.end = urtmp2.timeInterval.end;
|
||
|
|
inv_tmp.lc = true;
|
||
|
|
inv_tmp.rc = true;
|
||
|
|
|
||
|
|
UPoint utmp(
|
||
|
|
inv_tmp,
|
||
|
|
pt->GetX(),
|
||
|
|
pt->GetY(),
|
||
|
|
pt->GetX(),
|
||
|
|
pt->GetY());
|
||
|
|
|
||
|
|
tmp.Add( utmp );
|
||
|
|
|
||
|
|
m->Intersection( tmp, *pResult );
|
||
|
|
clock_t clock2 = clock();
|
||
|
|
time1 = ((double)(clock2-clock1)/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
cout << "Total computing time : " << time1 << " ms" << endl;
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.7 Value mapping functions of operator ~passes~
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <class Mapping, class Alpha>
|
||
|
|
int MappingPassesExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "TemporalExtAlgebra: passes" << endl;
|
||
|
|
}
|
||
|
|
|
||
|
|
Mapping *m = ((Mapping*)args[0].addr);
|
||
|
|
Alpha* val = ((Alpha*)args[1].addr);
|
||
|
|
|
||
|
|
if( !m->IsDefined() || !val->IsDefined() )
|
||
|
|
((CcBool *)result.addr)->Set( false, false );
|
||
|
|
else
|
||
|
|
((CcBool *)result.addr)->Set( true, m->Passes( *val ) );
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int MRealRealPassesExt(
|
||
|
|
Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
MRealExt *m = ((MRealExt*)args[0].addr);
|
||
|
|
CcReal* v = ((CcReal*)args[1].addr);
|
||
|
|
|
||
|
|
if( !m->IsDefined() || !v->IsDefined() )
|
||
|
|
((CcBool *)result.addr)->Set( false, false );
|
||
|
|
else
|
||
|
|
((CcBool *)result.addr)->Set( true, m->Passes( *v ) );
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int MPointPointsPassesExt(
|
||
|
|
Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
MPointExt *m = ((MPointExt*)args[0].addr);
|
||
|
|
Points* pts = ((Points*)args[1].addr);
|
||
|
|
|
||
|
|
if( !m->IsDefined() || !pts->IsDefined() )
|
||
|
|
((CcBool *)result.addr)->Set( false, false );
|
||
|
|
else
|
||
|
|
((CcBool *)result.addr)->Set( true, m->Passes( pts ) );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int MPointLinePassesExt(
|
||
|
|
Word* args,
|
||
|
|
Word& result,
|
||
|
|
int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
MPointExt *m = ((MPointExt*)args[0].addr);
|
||
|
|
Line* ln = ((Line*)args[1].addr);
|
||
|
|
|
||
|
|
if( !m->IsDefined() || !ln->IsDefined() )
|
||
|
|
((CcBool *)result.addr)->Set( false, false );
|
||
|
|
else
|
||
|
|
((CcBool *)result.addr)->Set( true, m->Passes( ln ) );
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int MRegionPointPassesExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
MRegion *m = ((MRegion*)args[0].addr);
|
||
|
|
Point* pt = ((Point*)args[1].addr);
|
||
|
|
CcBool* pResult = ((CcBool*)result.addr);
|
||
|
|
clock_t clock1, clock2;
|
||
|
|
double time1 = 0.;
|
||
|
|
|
||
|
|
clock1 = clock();
|
||
|
|
|
||
|
|
if( !m->IsDefined() || !pt->IsDefined() )
|
||
|
|
pResult->Set( false, false );
|
||
|
|
else
|
||
|
|
{
|
||
|
|
MPoint mp(1);
|
||
|
|
URegionEmb urtmp1;
|
||
|
|
URegionEmb urtmp2;
|
||
|
|
m->Get( 0, urtmp1 );
|
||
|
|
m->Get( m->GetNoComponents()-1, urtmp2 );
|
||
|
|
|
||
|
|
Interval<Instant> inv_tmp;
|
||
|
|
inv_tmp.start = urtmp1.timeInterval.start;
|
||
|
|
inv_tmp.end = urtmp2.timeInterval.end;
|
||
|
|
inv_tmp.lc = true;
|
||
|
|
inv_tmp.rc = true;
|
||
|
|
|
||
|
|
UPoint utmp(
|
||
|
|
inv_tmp,
|
||
|
|
pt->GetX(),
|
||
|
|
pt->GetY(),
|
||
|
|
pt->GetX(),
|
||
|
|
pt->GetY());
|
||
|
|
|
||
|
|
mp.Add( utmp );
|
||
|
|
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "timeInterval of utmp: "
|
||
|
|
<< utmp.timeInterval.start.ToString()
|
||
|
|
<< " " << utmp.timeInterval.end.ToString()
|
||
|
|
<< endl;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool result = false;
|
||
|
|
|
||
|
|
RefinementStream<
|
||
|
|
MRegion,
|
||
|
|
MPoint,
|
||
|
|
URegionEmb,
|
||
|
|
UPoint> rs(m, &mp);
|
||
|
|
|
||
|
|
MPoint resMp(0);
|
||
|
|
IntersectionRPExt( m, mp, resMp, rs ,false);
|
||
|
|
|
||
|
|
int mpPos = 0;
|
||
|
|
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "Data for resMp ..." << endl;
|
||
|
|
for(int i=0;i<resMp.GetNoComponents();i++)
|
||
|
|
{
|
||
|
|
UPoint uptemp2;
|
||
|
|
resMp.Get( i, uptemp2 );
|
||
|
|
cout << "timeInterval of up of resMp: "
|
||
|
|
<< uptemp2.timeInterval.start.ToString()
|
||
|
|
<< " " << uptemp2.timeInterval.end.ToString()
|
||
|
|
<< endl;
|
||
|
|
cout << "p0.x: " << uptemp2.p0.GetX()
|
||
|
|
<< " p0.y: " << uptemp2.p0.GetY()
|
||
|
|
<< " p1.x: " << uptemp2.p1.GetX()
|
||
|
|
<< " p1.y: " << uptemp2.p1.GetY() << endl;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
rs.reset(); // second run
|
||
|
|
while(rs.hasNext())
|
||
|
|
{
|
||
|
|
|
||
|
|
Interval<Instant> iv;
|
||
|
|
int urPos;
|
||
|
|
int upPos;
|
||
|
|
|
||
|
|
rs.getNext( iv, urPos, upPos);
|
||
|
|
|
||
|
|
if (upPos < 0) continue;
|
||
|
|
|
||
|
|
double prevtime = iv.start.ToDouble();
|
||
|
|
Instant prev(instanttype);
|
||
|
|
prev.ReadFrom(prevtime);
|
||
|
|
|
||
|
|
for (; mpPos < resMp.GetNoComponents(); mpPos++)
|
||
|
|
{
|
||
|
|
if (0)
|
||
|
|
cerr << "MRegion::Inside() mpPos=" << mpPos
|
||
|
|
<< endl;
|
||
|
|
|
||
|
|
UPoint up;
|
||
|
|
resMp.Get(mpPos, up);
|
||
|
|
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "timeInterval of up: "
|
||
|
|
<< up.timeInterval.start.ToString()
|
||
|
|
<< " " << up.timeInterval.end.ToString()
|
||
|
|
<< endl;
|
||
|
|
cout << "timeInterval of iv: "
|
||
|
|
<< iv.end.ToString()
|
||
|
|
<< endl;
|
||
|
|
cout << "up.timeInterval.start.Compare(&iv.end) > 0"
|
||
|
|
<< "|| (up.timeInterval.start.Compare(&iv.end) == 0"
|
||
|
|
<< "&& up.timeInterval.lc"
|
||
|
|
<< "&& !iv.rc))" << endl;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( !(up.timeInterval.start.Compare(&iv.end) > 0
|
||
|
|
|| (up.timeInterval.start.Compare(&iv.end) == 0
|
||
|
|
&& up.timeInterval.lc
|
||
|
|
&& !iv.rc)) )
|
||
|
|
{
|
||
|
|
result = true;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if(result)
|
||
|
|
break;
|
||
|
|
if (mpPos == resMp.GetNoComponents())
|
||
|
|
mpPos = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
pResult->Set( true, result );
|
||
|
|
}
|
||
|
|
|
||
|
|
clock2 = clock();
|
||
|
|
time1 = ((double)(clock2-clock1)/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
cout << "Total computing time : " << time1 << " ms" << endl;
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int MRegionPointsPassesExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
MRegion *m = ((MRegion*)args[0].addr);
|
||
|
|
Points* pts = ((Points*)args[1].addr);
|
||
|
|
CcBool* pResult = ((CcBool*)result.addr);
|
||
|
|
clock_t clock1, clock2, clock3, clock4;
|
||
|
|
double time1 = 0., time2 = 0., clock_ges = 0.;
|
||
|
|
|
||
|
|
clock1 = clock();
|
||
|
|
|
||
|
|
if( !m->IsDefined() || !pts->IsDefined() )
|
||
|
|
pResult->Set( false, false );
|
||
|
|
else
|
||
|
|
{
|
||
|
|
MPoint mp(1);
|
||
|
|
URegionEmb urtmp1;
|
||
|
|
URegionEmb urtmp2;
|
||
|
|
m->Get( 0, urtmp1 );
|
||
|
|
m->Get( m->GetNoComponents()-1, urtmp2 );
|
||
|
|
Interval<Instant> inv_tmp;
|
||
|
|
inv_tmp.start = urtmp1.timeInterval.start;
|
||
|
|
inv_tmp.end = urtmp2.timeInterval.end;
|
||
|
|
inv_tmp.lc = true;
|
||
|
|
inv_tmp.rc = true;
|
||
|
|
bool result = false;
|
||
|
|
|
||
|
|
clock3 = clock();
|
||
|
|
|
||
|
|
for(int i=0;i<pts->Size();i++)
|
||
|
|
{
|
||
|
|
Point pt;
|
||
|
|
pts->Get( i, pt );
|
||
|
|
|
||
|
|
UPoint utmp(
|
||
|
|
inv_tmp,
|
||
|
|
pt.GetX(),
|
||
|
|
pt.GetY(),
|
||
|
|
pt.GetX(),
|
||
|
|
pt.GetY());
|
||
|
|
|
||
|
|
mp.Clear();
|
||
|
|
mp.Add( utmp );
|
||
|
|
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "timeInterval of utmp: "
|
||
|
|
<< utmp.timeInterval.start.ToString()
|
||
|
|
<< " " << utmp.timeInterval.end.ToString()
|
||
|
|
<< endl;
|
||
|
|
}
|
||
|
|
|
||
|
|
RefinementStream<
|
||
|
|
MRegion,
|
||
|
|
MPoint,
|
||
|
|
URegionEmb,
|
||
|
|
UPoint> rs(m, &mp);
|
||
|
|
|
||
|
|
MPoint resMp(0);
|
||
|
|
IntersectionRPExt( m, mp, resMp, rs, false);
|
||
|
|
|
||
|
|
int mpPos = 0;
|
||
|
|
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "Data for resMp ..." << endl;
|
||
|
|
for(int i=0;i<resMp.GetNoComponents();i++)
|
||
|
|
{
|
||
|
|
UPoint uptemp;
|
||
|
|
resMp.Get( i, uptemp );
|
||
|
|
cout << "timeInterval of up of resMp: "
|
||
|
|
<< uptemp.timeInterval.start.ToString()
|
||
|
|
<< " " << uptemp.timeInterval.end.ToString()
|
||
|
|
<< endl;
|
||
|
|
cout << "p0.x: " << uptemp.p0.GetX()
|
||
|
|
<< " p0.y: " << uptemp.p0.GetY()
|
||
|
|
<< " p1.x: " << uptemp.p1.GetX()
|
||
|
|
<< " p1.y: " << uptemp.p1.GetY() << endl;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
rs.reset();
|
||
|
|
while(rs.hasNext()) {
|
||
|
|
|
||
|
|
Interval<Instant> iv;
|
||
|
|
int urPos;
|
||
|
|
int upPos;
|
||
|
|
|
||
|
|
rs.getNext( iv, urPos, upPos);
|
||
|
|
|
||
|
|
if (upPos < 0) continue;
|
||
|
|
|
||
|
|
double prevtime = iv.start.ToDouble();
|
||
|
|
Instant prev(instanttype);
|
||
|
|
prev.ReadFrom(prevtime);
|
||
|
|
|
||
|
|
for (; mpPos < resMp.GetNoComponents(); mpPos++)
|
||
|
|
{
|
||
|
|
if (0)
|
||
|
|
cerr << "MRegion::Inside() mpPos=" << mpPos
|
||
|
|
<< endl;
|
||
|
|
|
||
|
|
UPoint up;
|
||
|
|
resMp.Get(mpPos, up);
|
||
|
|
|
||
|
|
if(0)
|
||
|
|
{
|
||
|
|
cout << "timeInterval of up: "
|
||
|
|
<< up.timeInterval.start.ToString()
|
||
|
|
<< " " << up.timeInterval.end.ToString()
|
||
|
|
<< endl;
|
||
|
|
cout << "timeInterval of iv: "
|
||
|
|
<< iv.end.ToString()
|
||
|
|
<< endl;
|
||
|
|
cout << "up.timeInterval.start.Compare(&iv.end) > 0"
|
||
|
|
<< "|| (up.timeInterval.start.Compare(&iv.end)"
|
||
|
|
<< " == 0 && up.timeInterval.lc"
|
||
|
|
<< "&& !iv.rc))" << endl;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( !(up.timeInterval.start.Compare(&iv.end) > 0
|
||
|
|
|| (up.timeInterval.start.Compare(&iv.end) == 0
|
||
|
|
&& up.timeInterval.lc
|
||
|
|
&& !iv.rc)) )
|
||
|
|
{
|
||
|
|
result = true;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if(result)
|
||
|
|
break;
|
||
|
|
if (mpPos == resMp.GetNoComponents())
|
||
|
|
mpPos = 0;
|
||
|
|
}
|
||
|
|
clock4 = clock();
|
||
|
|
clock_ges = clock_ges + (clock4 - clock3);
|
||
|
|
if(result)
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
pResult->Set( true, result );
|
||
|
|
}
|
||
|
|
|
||
|
|
clock2 = clock();
|
||
|
|
time2 = ((double)(clock_ges / pts->Size())/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
time1 = ((double)(clock2-clock1)/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
cout << "Average computing time per elemtn of Points: "
|
||
|
|
<< time2 << " ms/unit" << endl;
|
||
|
|
cout << "Total computing time : " << time1 << " ms" << endl;
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.8 Value mapping functions of operator ~deftime~
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <class Mapping>
|
||
|
|
int MappingDefTimeExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
((Mapping*)args[0].addr)->DefTime( *(Periods*)result.addr );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.9 Value mapping functions of operator ~inst~
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <class Alpha>
|
||
|
|
int IntimeInstExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
Intime<Alpha>* i = (Intime<Alpha>*)args[0].addr;
|
||
|
|
|
||
|
|
if( i->IsDefined())
|
||
|
|
((Instant*)result.addr)->CopyFrom(
|
||
|
|
&((Intime<Alpha>*)args[0].addr)->instant);
|
||
|
|
else
|
||
|
|
((Instant*)result.addr)->SetDefined( false );
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.10 Value mapping functions of operator ~val~
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <class Alpha>
|
||
|
|
int IntimeValExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
Intime<Alpha>* i = (Intime<Alpha>*)args[0].addr;
|
||
|
|
|
||
|
|
if( i->IsDefined() )
|
||
|
|
((Alpha*)result.addr)->CopyFrom(
|
||
|
|
&((Intime<Alpha>*)args[0].addr)->value );
|
||
|
|
else
|
||
|
|
((Alpha*)result.addr)->SetDefined( false );
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.11 Value mapping functions of operator ~derivativeext~
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <class Mapping>
|
||
|
|
int MovingDerivativeExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
Mapping* m = ((Mapping*)args[0].addr);
|
||
|
|
Mapping* pResult = ((Mapping*)result.addr);
|
||
|
|
UReal unitin;
|
||
|
|
UReal unitout(true);
|
||
|
|
|
||
|
|
pResult->Clear();
|
||
|
|
if( !m->IsDefined() ){
|
||
|
|
pResult->SetDefined( false );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
pResult->SetDefined( true );
|
||
|
|
pResult->StartBulkLoad();
|
||
|
|
for(int i=0;i<m->GetNoComponents();i++)
|
||
|
|
{
|
||
|
|
m->Get(i, unitin);
|
||
|
|
if(CheckURealDerivable(&unitin))
|
||
|
|
{
|
||
|
|
unitout.a = 0.;
|
||
|
|
unitout.b = 2*unitin.a;
|
||
|
|
unitout.c = unitin.b;
|
||
|
|
unitout.r = false;
|
||
|
|
unitout.timeInterval = unitin.timeInterval;
|
||
|
|
pResult->MergeAdd(unitout);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
pResult->EndBulkLoad( false );
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.12 Value mapping functions of operator ~derivableext~
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <class Mapping>
|
||
|
|
int MovingDerivableExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
Mapping* m = ((Mapping*)args[0].addr);
|
||
|
|
MBool* pResult = ((MBool*)result.addr);
|
||
|
|
UReal unitin;
|
||
|
|
UBool unitout(true);
|
||
|
|
CcBool myValue;
|
||
|
|
|
||
|
|
pResult->Clear();
|
||
|
|
if( !m->IsDefined() ){
|
||
|
|
pResult->SetDefined( false );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
pResult->SetDefined( true );
|
||
|
|
pResult->StartBulkLoad();
|
||
|
|
for(int i=0;i<m->GetNoComponents();i++)
|
||
|
|
{
|
||
|
|
m->Get(i, unitin);
|
||
|
|
if(i==0)
|
||
|
|
{
|
||
|
|
/*
|
||
|
|
Steps for the first Unit
|
||
|
|
|
||
|
|
*/
|
||
|
|
myValue.Set(true, !unitin.r);
|
||
|
|
unitout.SetDefined(true);
|
||
|
|
unitout.constValue.CopyFrom(&myValue);
|
||
|
|
|
||
|
|
if(m->GetNoComponents()==1)
|
||
|
|
{
|
||
|
|
/*
|
||
|
|
Only one Unit available
|
||
|
|
|
||
|
|
*/
|
||
|
|
unitout.timeInterval = unitin.timeInterval;
|
||
|
|
pResult->Add(unitout);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/*
|
||
|
|
Just the first Unit ...
|
||
|
|
|
||
|
|
*/
|
||
|
|
unitout.timeInterval.start = unitin.timeInterval.start;
|
||
|
|
unitout.timeInterval.end = unitin.timeInterval.end;
|
||
|
|
unitout.timeInterval.lc = unitin.timeInterval.lc;
|
||
|
|
unitout.timeInterval.rc = unitin.timeInterval.rc;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(!unitin.r == unitout.constValue.GetBoolval())
|
||
|
|
{
|
||
|
|
/*
|
||
|
|
The Unit has the same Bool value as the
|
||
|
|
previous. So, the time interval of the previous
|
||
|
|
Unit will be extended.
|
||
|
|
|
||
|
|
*/
|
||
|
|
unitout.timeInterval.end = unitin.timeInterval.end;
|
||
|
|
unitout.timeInterval.rc = unitin.timeInterval.rc;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/*
|
||
|
|
The current Unit has another Bool value as the
|
||
|
|
previous. The previous Unit must be created. New
|
||
|
|
values must be assumed from the current Unit.
|
||
|
|
|
||
|
|
*/
|
||
|
|
pResult->Add(unitout);
|
||
|
|
myValue.Set(true, !unitin.r);
|
||
|
|
unitout.constValue.CopyFrom(&myValue);
|
||
|
|
unitout.timeInterval.start = unitin.timeInterval.start;
|
||
|
|
unitout.timeInterval.end = unitin.timeInterval.end;
|
||
|
|
unitout.timeInterval.lc = unitin.timeInterval.lc;
|
||
|
|
unitout.timeInterval.rc = unitin.timeInterval.rc;
|
||
|
|
}
|
||
|
|
if(i==m->GetNoComponents()-1)
|
||
|
|
{
|
||
|
|
/*
|
||
|
|
Last Unit must be created.
|
||
|
|
|
||
|
|
*/
|
||
|
|
pResult->Add(unitout);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
pResult->EndBulkLoad( false );
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.12 Value mapping functions of operator ~speedext~
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <class Mapping>
|
||
|
|
int MovingSpeedExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s ){
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
MReal* res = static_cast<MReal*>(result.addr);
|
||
|
|
MPoint* arg1 = static_cast<MPoint*>(args[0].addr);
|
||
|
|
res->Clear();
|
||
|
|
if(!arg1->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
res->SetDefined( true );
|
||
|
|
|
||
|
|
Geoid* g = 0;
|
||
|
|
if(qp->GetNoSons(s)==2){ // setting up geoid for (LON,LAT)-variant
|
||
|
|
g = static_cast<Geoid*>(args[1].addr);
|
||
|
|
if(!g->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
arg1->MSpeed( *res, g );
|
||
|
|
if(qp->GetNoSons(s)!=2){
|
||
|
|
delete g;
|
||
|
|
g = 0;
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.13 Value mapping functions of operator ~rangevalues~
|
||
|
|
|
||
|
|
*/
|
||
|
|
int RangeRangevaluesBoolExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
MBool* m = ((MBool*)args[0].addr);
|
||
|
|
RBool* pResult = ((RBool*)result.addr);
|
||
|
|
pResult->Clear();
|
||
|
|
if( !m->IsDefined() ){
|
||
|
|
pResult->SetDefined( false );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
pResult->SetDefined( true );
|
||
|
|
|
||
|
|
UBool utemp;
|
||
|
|
CcBool min, max;
|
||
|
|
bool findmin=false, findmax=false, temp;
|
||
|
|
|
||
|
|
m->Get(0, utemp);
|
||
|
|
temp = utemp.constValue.GetBoolval();
|
||
|
|
min.Set(true, temp);
|
||
|
|
max.Set(true, temp);
|
||
|
|
|
||
|
|
for(int i=1;i<m->GetNoComponents();i++)
|
||
|
|
{
|
||
|
|
m->Get(i, utemp);
|
||
|
|
temp = utemp.constValue.GetBoolval();
|
||
|
|
|
||
|
|
if(temp)
|
||
|
|
{
|
||
|
|
max.Set(true, temp);
|
||
|
|
findmax = true;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
min.Set(true, temp);
|
||
|
|
findmin = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(findmin && findmax) break;
|
||
|
|
}
|
||
|
|
|
||
|
|
Interval<CcBool> inter(min, max, true, true);
|
||
|
|
pResult->MergeAdd(inter);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int RangeRangevaluesIntExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
MInt* m = ((MInt*)args[0].addr);
|
||
|
|
RInt* pResult = ((RInt*)result.addr);
|
||
|
|
pResult->Clear();
|
||
|
|
if( !m->IsDefined() ){
|
||
|
|
pResult->SetDefined( false );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
UInt utemp;
|
||
|
|
int temp;
|
||
|
|
set<int> BTree;
|
||
|
|
// clock_t clock1, clock2, clock3, clock4;
|
||
|
|
// double time1, time2;
|
||
|
|
|
||
|
|
// clock1 = clock();
|
||
|
|
for(int i=0;i<m->GetNoComponents();i++) {
|
||
|
|
m->Get(i, utemp);
|
||
|
|
temp = utemp.constValue.GetIntval();
|
||
|
|
BTree.insert(temp);
|
||
|
|
}
|
||
|
|
// clock2 = clock();
|
||
|
|
// time1 = ((clock2-clock1)/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
// cout << endl << "Time to insert values: "
|
||
|
|
// << time1 << " milliseconds" << endl;
|
||
|
|
|
||
|
|
set<int>::iterator iter;
|
||
|
|
CcInt mincc, maxcc;
|
||
|
|
int min=0, max=0;
|
||
|
|
bool start=true;
|
||
|
|
Interval<CcInt> inter;
|
||
|
|
|
||
|
|
// clock3 = clock();
|
||
|
|
pResult->Clear();
|
||
|
|
pResult->StartBulkLoad();
|
||
|
|
for(iter=BTree.begin(); iter!=BTree.end(); ++iter) {
|
||
|
|
if(start) {
|
||
|
|
min = *iter;
|
||
|
|
max = min;
|
||
|
|
start = false;
|
||
|
|
} else {
|
||
|
|
if(*iter-max != 1) {
|
||
|
|
mincc.Set(true, min);
|
||
|
|
maxcc.Set(true, max);
|
||
|
|
inter.start = mincc;
|
||
|
|
inter.end = maxcc;
|
||
|
|
inter.lc = true;
|
||
|
|
inter.rc = true;
|
||
|
|
pResult->Add(inter);
|
||
|
|
min = *iter;
|
||
|
|
max = min;
|
||
|
|
} else {
|
||
|
|
max = *iter;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
mincc.Set(true, min);
|
||
|
|
maxcc.Set(true, max);
|
||
|
|
inter.start = mincc;
|
||
|
|
inter.end = maxcc;
|
||
|
|
inter.lc = true;
|
||
|
|
inter.rc = true;
|
||
|
|
pResult->Add(inter);
|
||
|
|
// clock4 = clock();
|
||
|
|
// time2 = ((clock4-clock3)/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
// cout << "Time to scan and build intervals: "
|
||
|
|
// << time2 << " milliseconds" << endl;
|
||
|
|
pResult->EndBulkLoad( false );
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int RangeRangevaluesStringExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
MString* m = ((MString*)args[0].addr);
|
||
|
|
RString* pResult = ((RString*)result.addr);
|
||
|
|
pResult->Clear();
|
||
|
|
if( !m->IsDefined() ){
|
||
|
|
pResult->SetDefined( false );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
pResult->SetDefined( true );
|
||
|
|
|
||
|
|
UString utemp;
|
||
|
|
set<string> BTree;
|
||
|
|
string temp;
|
||
|
|
// clock_t clock1, clock2, clock3, clock4;
|
||
|
|
// double time1, time2;
|
||
|
|
|
||
|
|
// clock1 = clock();
|
||
|
|
for(int i=0;i<m->GetNoComponents();i++) {
|
||
|
|
m->Get(i, utemp);
|
||
|
|
temp = utemp.constValue.GetValue();
|
||
|
|
BTree.insert(temp);
|
||
|
|
}
|
||
|
|
// clock2 = clock();
|
||
|
|
// time1 = ((clock2-clock1)/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
// cout << endl << "Time to insert values: "
|
||
|
|
// << time1 << " milliseconds" << endl;
|
||
|
|
|
||
|
|
set<string>::iterator iter;
|
||
|
|
CcString minmaxcc;
|
||
|
|
STRING_T minmax;
|
||
|
|
Interval<CcString> inter;
|
||
|
|
|
||
|
|
// clock3 = clock();
|
||
|
|
pResult->Clear();
|
||
|
|
pResult->StartBulkLoad();
|
||
|
|
for(iter=BTree.begin(); iter!=BTree.end(); ++iter) {
|
||
|
|
temp = *iter;
|
||
|
|
// cout << "temp.size: " << temp.size() << endl;
|
||
|
|
for(size_t i=0;i<temp.size();++i){
|
||
|
|
minmax[i] = temp[i];
|
||
|
|
}
|
||
|
|
minmax[temp.size()] = '\0';
|
||
|
|
minmaxcc.Set(true, &minmax);
|
||
|
|
inter.start = minmaxcc;
|
||
|
|
inter.end = minmaxcc;
|
||
|
|
inter.lc = true;
|
||
|
|
inter.rc = true;
|
||
|
|
pResult->Add(inter);
|
||
|
|
}
|
||
|
|
// clock4 = clock();
|
||
|
|
// time2 = ((clock4-clock3)/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
// cout << "Time to scan and build intervals: "
|
||
|
|
// << time2 << " milliseconds" << endl;
|
||
|
|
BTree.clear();
|
||
|
|
pResult->EndBulkLoad( false );
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
bool IntervalRealAlmostIntersects(
|
||
|
|
const Interval<CcReal>& j, const Interval<CcReal>& i )
|
||
|
|
{
|
||
|
|
assert( j.IsValid());
|
||
|
|
assert( i.IsValid() );
|
||
|
|
return !( (j.start.CompareAlmost(&i.end) > 0 ) ||
|
||
|
|
((j.start.CompareAlmost(&i.end) == 0) && ( !j.lc || !i.rc)) ||
|
||
|
|
(j.end.CompareAlmost(&i.start) < 0 ) ||
|
||
|
|
((j.end.CompareAlmost(&i.start) == 0 ) && (!j.rc || !i.lc))
|
||
|
|
);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int RangeRangevaluesRealExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
MReal* m = ((MReal*)args[0].addr);
|
||
|
|
RReal* pResult = ((RReal*)result.addr);
|
||
|
|
pResult->Clear();
|
||
|
|
if( !m->IsDefined() ){
|
||
|
|
pResult->SetDefined( false );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
pResult->SetDefined( true );
|
||
|
|
|
||
|
|
// clock_t clock1, clock2, clock3, clock4;
|
||
|
|
// double time1, time2;
|
||
|
|
|
||
|
|
UReal utemp;
|
||
|
|
double min=0.,max=0.;
|
||
|
|
CcReal mincc, maxcc;
|
||
|
|
Interval<CcReal> inter;
|
||
|
|
multimap< double,const Interval<CcReal> > intermap;
|
||
|
|
|
||
|
|
// clock1 = clock();
|
||
|
|
vector<UReal> resvector;
|
||
|
|
for(int i=0;i<m->GetNoComponents();i++) {
|
||
|
|
m->Get(i, utemp);
|
||
|
|
//MinMaxValueFunction(utemp, min, max);
|
||
|
|
//yields wrong min and max values
|
||
|
|
|
||
|
|
size_t size = utemp.AtMin(resvector);
|
||
|
|
assert(size>0);
|
||
|
|
min = resvector[0].c;
|
||
|
|
utemp.AtMax(resvector);
|
||
|
|
max = resvector[0].c;
|
||
|
|
|
||
|
|
mincc.Set(true, min);
|
||
|
|
maxcc.Set(true, max);
|
||
|
|
inter.start = mincc;
|
||
|
|
inter.end = maxcc;
|
||
|
|
inter.lc = true;
|
||
|
|
inter.rc = true;
|
||
|
|
intermap.insert(pair< double,const Interval<CcReal> >(max, inter));
|
||
|
|
}
|
||
|
|
// clock2 = clock();
|
||
|
|
// time1 = ((clock2-clock1)/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
// cout << endl << "Time to insert values: "
|
||
|
|
// << time1 << " milliseconds" << endl;
|
||
|
|
|
||
|
|
multimap< double,const Interval<CcReal> >::iterator iter = intermap.end();
|
||
|
|
pResult->Clear();
|
||
|
|
pResult->StartBulkLoad();
|
||
|
|
--iter;
|
||
|
|
bool start=true;
|
||
|
|
// clock3 = clock();
|
||
|
|
inter = (*iter).second;
|
||
|
|
while(iter != intermap.begin()) {
|
||
|
|
if(start) {
|
||
|
|
start = false;
|
||
|
|
} else {
|
||
|
|
if(0) {
|
||
|
|
cout << "[" << (((*iter).second).start).GetValue();
|
||
|
|
cout << "," << (((*iter).second).end).GetValue() << "]";
|
||
|
|
cout << " intersects ";
|
||
|
|
cout << "[" << (inter.start).GetValue();
|
||
|
|
cout << "," << (inter.end).GetValue() << "]?" << endl;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
if(IntervalRealAlmostIntersects(inter, (*iter).second)) {
|
||
|
|
//cout << "Yes" << endl;
|
||
|
|
if(inter.start.GetValue() > ((*iter).second).start.GetValue()) {
|
||
|
|
inter.start = ((*iter).second).start;
|
||
|
|
if(0) {
|
||
|
|
cout << endl << "... expanding interval" << endl;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
pResult->Add(inter);
|
||
|
|
inter = (*iter).second;
|
||
|
|
if(0) {
|
||
|
|
cout << endl << "... creating new interval" << endl;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
--iter;
|
||
|
|
}
|
||
|
|
if ( inter.IsValid() && (*iter).second.IsValid() ) {
|
||
|
|
if(inter.Intersects((*iter).second)) {
|
||
|
|
if(inter.start.GetValue() > ((*iter).second).start.GetValue()) {
|
||
|
|
inter.start = ((*iter).second).start;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
pResult->Add(inter);
|
||
|
|
// clock4 = clock();
|
||
|
|
// time2 = ((clock4-clock3)/CLOCKS_PER_SEC) * 1000.;
|
||
|
|
// cout << "Time to scan and build intervals: "
|
||
|
|
// << time2 << " milliseconds" << endl;
|
||
|
|
|
||
|
|
pResult->EndBulkLoad( true );
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.14 Value mapping functions of operator ~sometimes~
|
||
|
|
|
||
|
|
*/
|
||
|
|
int MovingSometimesExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
MBool* m = ((MBool*)args[0].addr);
|
||
|
|
if(!m->IsDefined()){
|
||
|
|
((CcBool *)result.addr)->Set( false, false );
|
||
|
|
} else {
|
||
|
|
UBool utemp;
|
||
|
|
bool temp=false;
|
||
|
|
|
||
|
|
for(int i=0;i<m->GetNoComponents();i++){
|
||
|
|
m->Get(i, utemp);
|
||
|
|
temp = utemp.constValue.GetBoolval();
|
||
|
|
if(temp) break;
|
||
|
|
}
|
||
|
|
((CcBool *)result.addr)->Set( true, temp );
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.15 Value mapping functions of operator ~always~
|
||
|
|
|
||
|
|
*/
|
||
|
|
int MovingAlwaysExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
MBool* m = ((MBool*)args[0].addr);
|
||
|
|
if(!m->IsDefined()){
|
||
|
|
((CcBool *)result.addr)->Set( false, false );
|
||
|
|
} else {
|
||
|
|
UBool utemp;
|
||
|
|
bool temp=true;
|
||
|
|
|
||
|
|
for(int i=0;i<m->GetNoComponents();i++) {
|
||
|
|
m->Get(i, utemp);
|
||
|
|
temp = utemp.constValue.GetBoolval();
|
||
|
|
if(!temp) break;
|
||
|
|
}
|
||
|
|
((CcBool *)result.addr)->Set( true, temp );
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.16 Value mapping functions of operator ~never~
|
||
|
|
|
||
|
|
*/
|
||
|
|
int MovingNeverExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
MBool* m = ((MBool*)args[0].addr);
|
||
|
|
if(!m->IsDefined()){
|
||
|
|
((CcBool *)result.addr)->Set( false, false );
|
||
|
|
} else {
|
||
|
|
UBool utemp;
|
||
|
|
bool temp=true;
|
||
|
|
|
||
|
|
for(int i=0;i<m->GetNoComponents();i++) {
|
||
|
|
m->Get(i, utemp);
|
||
|
|
temp = utemp.constValue.GetBoolval();
|
||
|
|
if(temp) break;
|
||
|
|
}
|
||
|
|
((CcBool *)result.addr)->Set( true, !temp );
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.17 Value mapping functions of operator ~velocity~
|
||
|
|
|
||
|
|
*/
|
||
|
|
int MovingVelocityExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
MPoint* m = ((MPoint*)args[0].addr);
|
||
|
|
MPoint* pResult = ((MPoint*)result.addr);
|
||
|
|
pResult->Clear();
|
||
|
|
if(!m->IsDefined()){
|
||
|
|
pResult->SetDefined( false );
|
||
|
|
} else {
|
||
|
|
pResult->SetDefined( true );
|
||
|
|
UPoint unitin;
|
||
|
|
double dx, dy, dt;
|
||
|
|
|
||
|
|
pResult->StartBulkLoad();
|
||
|
|
for(int i=0;i<m->GetNoComponents();i++) {
|
||
|
|
m->Get(i, unitin);
|
||
|
|
dx = unitin.p1.GetX()-unitin.p0.GetX();
|
||
|
|
dy = unitin.p1.GetY()-unitin.p0.GetY();
|
||
|
|
dt = ((unitin.timeInterval.end).ToDouble() -
|
||
|
|
(unitin.timeInterval.start).ToDouble()) *
|
||
|
|
FactorForUnitOfTime;
|
||
|
|
UPoint unitout(
|
||
|
|
unitin.timeInterval,
|
||
|
|
0, 0, dx/dt, dy/dt
|
||
|
|
);
|
||
|
|
pResult->Add(unitout);
|
||
|
|
}
|
||
|
|
pResult->EndBulkLoad( false );
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.18 Value mapping function of operator ~setunitoftime~
|
||
|
|
|
||
|
|
*/
|
||
|
|
int GlobalUnitOfTimeExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcReal* f = ((CcReal*)args[0].addr);
|
||
|
|
|
||
|
|
if(f->IsDefined() && f->GetRealval() > 0.0) {
|
||
|
|
FactorForUnitOfTime = f->GetRealval();
|
||
|
|
((CcReal *)result.addr)->Set( true, FactorForUnitOfTime );
|
||
|
|
} else {
|
||
|
|
((CcReal *)result.addr)->Set( false, 0.0 );
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.19 Value mapping function of operator ~setunitofdistance~
|
||
|
|
|
||
|
|
*/
|
||
|
|
int GlobalUnitOfDistanceExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcReal* f = ((CcReal*)args[0].addr);
|
||
|
|
|
||
|
|
if(f->IsDefined() && f->GetRealval() > 0.0) {
|
||
|
|
FactorForUnitOfDistance = f->GetRealval();
|
||
|
|
((CcReal *)result.addr)->Set( true, FactorForUnitOfDistance );
|
||
|
|
} else {
|
||
|
|
((CcReal *)result.addr)->SetDefined( false );
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.20 Value mapping function of operator ~direction~
|
||
|
|
|
||
|
|
*/
|
||
|
|
template<bool useHeading>
|
||
|
|
int MovingMDirectionExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
MReal* pResult = static_cast<MReal*>(result.addr);
|
||
|
|
|
||
|
|
MPoint* m = static_cast<MPoint*>(args[0].addr);
|
||
|
|
const Geoid* geoid =
|
||
|
|
(qp->GetNoSons(s)>=2)?static_cast<const Geoid*>(args[1].addr):0;
|
||
|
|
const CcReal* eps =
|
||
|
|
(qp->GetNoSons(s)==3)?static_cast<const CcReal*>(args[2].addr):0;
|
||
|
|
double epsilon = 0.00001;
|
||
|
|
if(eps){
|
||
|
|
if(!eps->IsDefined()){
|
||
|
|
m->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
epsilon = eps->GetValue();
|
||
|
|
if(epsilon <= 0){
|
||
|
|
m->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
m->Direction( pResult, useHeading, geoid, epsilon );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.21 Value mapping function of operator ~locations~
|
||
|
|
|
||
|
|
*/
|
||
|
|
int MovingLocationsExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
MPointExt* m = ((MPointExt*)args[0].addr);
|
||
|
|
Points* pResult = ((Points*)result.addr);
|
||
|
|
|
||
|
|
m->Locations( pResult );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.3.22 Value mapping functions of operator ~atmin~
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
template <class Mapping, class Unit, class Alpha>
|
||
|
|
int MappingAtminExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
MappingExt<Unit, Alpha>* m = ((MappingExt<Unit, Alpha>*)args[0].addr);
|
||
|
|
Mapping* pResult = ((Mapping*)result.addr);
|
||
|
|
m->AtMin( *pResult );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <class Mapping, class Unit, class Alpha>
|
||
|
|
int MappingAtmaxExt( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
|
||
|
|
MappingExt<Unit, Alpha>* m = ((MappingExt<Unit, Alpha>*)args[0].addr);
|
||
|
|
Mapping* pResult = ((Mapping*)result.addr);
|
||
|
|
//pResult->Clear();
|
||
|
|
m->AtMax( *pResult );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int MappingAtminExt_r( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
MReal* m = ((MReal*)args[0].addr);
|
||
|
|
MReal* pResult = ((MReal*)result.addr);
|
||
|
|
m->AtMin( *pResult );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int MappingAtmaxExt_r( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
MReal* m = ((MReal*)args[0].addr);
|
||
|
|
MReal* pResult = ((MReal*)result.addr);
|
||
|
|
m->AtMax( *pResult );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int ConcatSValueMap(Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s){
|
||
|
|
|
||
|
|
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
MPoint* res = (MPoint*) result.addr;
|
||
|
|
res->Clear();
|
||
|
|
res->SetDefined(true);
|
||
|
|
|
||
|
|
Word next;
|
||
|
|
bool autoresize=true;
|
||
|
|
if(qp->GetNoSons(s)==2){
|
||
|
|
CcInt* size = (CcInt*)args[1].addr;
|
||
|
|
if(!size->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
int isize = size->GetIntval();
|
||
|
|
if(isize>0){
|
||
|
|
res->Resize(isize);
|
||
|
|
autoresize=false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
qp->Open(args[0].addr);
|
||
|
|
qp->Request(args[0].addr, next);
|
||
|
|
bool d = true;
|
||
|
|
while(qp->Received(args[0].addr) && d){
|
||
|
|
if( !((MPoint*) next.addr)->IsEmpty() ){ // includes undefined mpoint
|
||
|
|
d = res->Append(* ((MPoint*) next.addr),autoresize);
|
||
|
|
}
|
||
|
|
((MPoint*)next.addr)->DeleteIfAllowed();
|
||
|
|
qp->Request(args[0].addr, next);
|
||
|
|
}
|
||
|
|
qp->Close(args[0].addr);
|
||
|
|
res->TrimToSize();
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static bool EverNearerThan(MPoint* arg0, MPoint* arg1, double dist,
|
||
|
|
const Geoid* geoid){
|
||
|
|
assert( arg0->IsDefined() );
|
||
|
|
assert( arg1->IsDefined() );
|
||
|
|
if(geoid){
|
||
|
|
assert( geoid->IsDefined() );
|
||
|
|
}
|
||
|
|
|
||
|
|
RefinementStream<MPoint, MPoint, UPoint, UPoint> rs(arg0, arg1);
|
||
|
|
Interval<Instant> iv;
|
||
|
|
int u1Pos;
|
||
|
|
int u2Pos;
|
||
|
|
UPoint u1;
|
||
|
|
UPoint u2;
|
||
|
|
UReal uReal(true);
|
||
|
|
bool correct = false;
|
||
|
|
while(rs.hasNext() && !rs.finished1() && !rs.finished2()){
|
||
|
|
rs.getNext( iv, u1Pos, u2Pos);
|
||
|
|
if ((u1Pos) >=0 && (u2Pos>=0)){
|
||
|
|
arg0->Get(u1Pos, u1);
|
||
|
|
arg1->Get(u2Pos, u2);
|
||
|
|
if(u1.IsDefined() && u2.IsDefined()) {
|
||
|
|
correct = false;
|
||
|
|
u1.Distance( u2, uReal, geoid );
|
||
|
|
if(uReal.Min(correct) < dist && correct){
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
static bool EverNearerThan(Point* arg0, MPoint* arg1, double dist,
|
||
|
|
const Geoid* geoid){
|
||
|
|
assert( arg0->IsDefined() );
|
||
|
|
assert( arg1->IsDefined() );
|
||
|
|
if(geoid){
|
||
|
|
assert( geoid->IsDefined() );
|
||
|
|
}
|
||
|
|
|
||
|
|
for(int i = 0; i< arg1->GetNoComponents(); i++){
|
||
|
|
UPoint upoint;
|
||
|
|
arg1->Get(i, upoint);
|
||
|
|
vector<UReal> resvec;
|
||
|
|
upoint.Distance(*arg0, resvec, geoid);
|
||
|
|
bool correct = false;
|
||
|
|
for(vector<UReal>::iterator it(resvec.begin()); it!=resvec.end(); it++){
|
||
|
|
if(it->IsDefined() && ( it->Min(correct) < dist && correct )){
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
static bool EverNearerThan(MPoint* arg0, Point* arg1, double dist,
|
||
|
|
const Geoid* geoid){
|
||
|
|
assert( arg0->IsDefined() );
|
||
|
|
assert( arg1->IsDefined() );
|
||
|
|
if(geoid){
|
||
|
|
assert( geoid->IsDefined() );
|
||
|
|
}
|
||
|
|
return EverNearerThan(arg1,arg0,dist,geoid);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
template<class S, class T>
|
||
|
|
int
|
||
|
|
EverNearerThan_vm( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
// args[0] : S*
|
||
|
|
S* arg0 = static_cast<S*>(args[0].addr);
|
||
|
|
T* arg1 = static_cast<T*>(args[1].addr);
|
||
|
|
CcReal* arg2 = static_cast<CcReal*>(args[2].addr);
|
||
|
|
Geoid* geoid = (qp->GetNoSons(s)==4)?static_cast<Geoid*>(args[3].addr):0;
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
CcBool* res = static_cast<CcBool*>(result.addr);
|
||
|
|
|
||
|
|
if(!arg0->IsDefined() || !arg1->IsDefined() || !arg2->IsDefined() ||
|
||
|
|
(geoid && !geoid->IsDefined()) ){
|
||
|
|
res->Set(false,false);
|
||
|
|
} else {
|
||
|
|
res->Set(true,EverNearerThan(arg0, arg1, arg2->GetRealval(),geoid));
|
||
|
|
}
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
int InsideVM( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s ) {
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
MBool* res = static_cast<MBool*>(result.addr);
|
||
|
|
MPointExt* arg1 = static_cast<MPointExt*>(args[0].addr);
|
||
|
|
Region* arg2 = static_cast<Region*>(args[1].addr);
|
||
|
|
res->Clear();
|
||
|
|
if(!arg1->IsDefined() ||!arg2->IsDefined() ||
|
||
|
|
arg1->GetNoComponents() < 1){
|
||
|
|
res->SetDefined( false );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
res->SetDefined( true );
|
||
|
|
*res = arg1->Inside(*arg2);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
template<class T>
|
||
|
|
int berlin2wgsVM_lifted(Word* args, Word& result, int message, Word& local,
|
||
|
|
Supplier s) {
|
||
|
|
T* src = (T*)args[0].addr;
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
T* res = (T*)result.addr;
|
||
|
|
res->Clear();
|
||
|
|
if (src->IsDefined()) {
|
||
|
|
Berlin2WGSTemporal converter;
|
||
|
|
converter.convert(src, res);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
res->SetDefined(false);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
template<class T, class U>
|
||
|
|
int splitatgapsVM(Word* args, Word& result, int message, Word& local,
|
||
|
|
Supplier s) {
|
||
|
|
SplitAtGapsLI<T, U> *li = (SplitAtGapsLI<T, U>*)local.addr;
|
||
|
|
switch (message) {
|
||
|
|
case OPEN: {
|
||
|
|
if (li) {
|
||
|
|
delete li;
|
||
|
|
li = 0;
|
||
|
|
local.addr = 0;
|
||
|
|
}
|
||
|
|
T *src = (T*)args[0].addr;
|
||
|
|
if (!src->IsDefined()) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
DateTime *dur = 0;
|
||
|
|
if (qp->GetNoSons(s) == 2) {
|
||
|
|
dur = (DateTime*)args[1].addr;
|
||
|
|
if (!dur->IsDefined()) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
local.addr = new SplitAtGapsLI<T, U>(src, dur);
|
||
|
|
}
|
||
|
|
case REQUEST: {
|
||
|
|
result.addr = li ? li->nextResult() : 0;
|
||
|
|
return result.addr ? YIELD : CANCEL;
|
||
|
|
}
|
||
|
|
case CLOSE: {
|
||
|
|
if (li) {
|
||
|
|
delete li;
|
||
|
|
local.addr = 0;
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
default: {
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int splitatspeedVM(Word* args, Word& result, int message, Word& local,
|
||
|
|
Supplier s) {
|
||
|
|
SplitAtSpeedLI *li = (SplitAtSpeedLI*)local.addr;
|
||
|
|
switch (message) {
|
||
|
|
case OPEN: {
|
||
|
|
if (li) {
|
||
|
|
delete li;
|
||
|
|
li = 0;
|
||
|
|
local.addr = 0;
|
||
|
|
}
|
||
|
|
MPoint *src = (MPoint*)args[0].addr;
|
||
|
|
CcReal *ccspeed = (CcReal*)args[1].addr;
|
||
|
|
if (!src->IsDefined() || !ccspeed->IsDefined()) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
if (ccspeed->GetValue() < 0) {
|
||
|
|
cout << "speed limit must be a non-negative value" << endl;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
Geoid *geoid = 0;
|
||
|
|
if (qp->GetNoSons(s) == 3) {
|
||
|
|
geoid = (Geoid*)args[2].addr;
|
||
|
|
if (!geoid->IsDefined()) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
local.addr = new SplitAtSpeedLI(src, ccspeed->GetValue(), geoid);
|
||
|
|
}
|
||
|
|
case REQUEST: {
|
||
|
|
result.addr = li ? li->nextResult() : 0;
|
||
|
|
return result.addr ? YIELD : CANCEL;
|
||
|
|
}
|
||
|
|
case CLOSE: {
|
||
|
|
if (li) {
|
||
|
|
delete li;
|
||
|
|
local.addr = 0;
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
default: {
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
int splitatlengthVM(Word* args, Word& result, int message, Word& local,
|
||
|
|
Supplier s) {
|
||
|
|
SplitAtLengthLI *li = (SplitAtLengthLI*)local.addr;
|
||
|
|
switch (message) {
|
||
|
|
case OPEN: {
|
||
|
|
if (li) {
|
||
|
|
delete li;
|
||
|
|
li = 0;
|
||
|
|
local.addr = 0;
|
||
|
|
}
|
||
|
|
MPoint *src = (MPoint*)args[0].addr;
|
||
|
|
CcReal *cclength = (CcReal*)args[1].addr;
|
||
|
|
if (!src->IsDefined() || !cclength->IsDefined()) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
if (cclength->GetValue() < 0) {
|
||
|
|
cout << "length limit must be a non-negative value" << endl;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
Geoid *geoid = 0;
|
||
|
|
if (qp->GetNoSons(s) == 3) {
|
||
|
|
geoid = (Geoid*)args[2].addr;
|
||
|
|
if (!geoid->IsDefined()) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
local.addr = new SplitAtLengthLI(src, cclength->GetValue(), geoid);
|
||
|
|
}
|
||
|
|
case REQUEST: {
|
||
|
|
result.addr = li ? li->nextResult() : 0;
|
||
|
|
return result.addr ? YIELD : CANCEL;
|
||
|
|
}
|
||
|
|
case CLOSE: {
|
||
|
|
if (li) {
|
||
|
|
delete li;
|
||
|
|
local.addr = 0;
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
default: {
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.4 Definition of operators
|
||
|
|
|
||
|
|
Definition of operators is done in a way similar to definition of
|
||
|
|
type constructors: an instance of class ~Operator~ is defined.
|
||
|
|
|
||
|
|
Because almost all operators are overloaded, we have first do define an array of
|
||
|
|
value
|
||
|
|
mapping functions for each operator. For nonoverloaded operators there is also
|
||
|
|
such and array
|
||
|
|
defined, so it easier to make them overloaded.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
ValueMapping temporalatinstantextmap[] = {
|
||
|
|
MappingAtInstantExt<MString, CcString> };
|
||
|
|
|
||
|
|
ValueMapping temporalatperiodsextmap[] = {
|
||
|
|
MappingAtPeriodsExt<MString>,
|
||
|
|
MappingAtPeriodsExtMRegion};
|
||
|
|
|
||
|
|
ValueMapping temporalinitialextmap[] = {
|
||
|
|
MappingInitialExt<MString, UString, CcString> };
|
||
|
|
|
||
|
|
ValueMapping temporalfinalextmap[] = {
|
||
|
|
MappingFinalExt<MString, UString, CcString> };
|
||
|
|
|
||
|
|
ValueMapping temporalpresentextmap[] = {
|
||
|
|
MappingPresentExt_i<MString>,
|
||
|
|
MappingPresentExt_p<MString>, };
|
||
|
|
|
||
|
|
ValueMapping temporalatextmap[] = {
|
||
|
|
MappingRealAtExt,
|
||
|
|
MappingStringAtExt,
|
||
|
|
MappingAtExt<MBool, UBool, CcBool, RBool>,
|
||
|
|
MappingAtExt<MInt, UInt, CcInt, RInt>,
|
||
|
|
MappingAtExt<MString, UString, CcString, RString>,
|
||
|
|
MappingRRealAtExt,
|
||
|
|
MappingMPointPointsAtExt,
|
||
|
|
MappingMPointLineAtExt,
|
||
|
|
MRegionPointAtExt,
|
||
|
|
};
|
||
|
|
|
||
|
|
ValueMapping temporalpassesextmap[] = {
|
||
|
|
MRealRealPassesExt,
|
||
|
|
MappingPassesExt<MString, CcString>,
|
||
|
|
MPointPointsPassesExt,
|
||
|
|
MPointLinePassesExt,
|
||
|
|
MRegionPointPassesExt,
|
||
|
|
MRegionPointsPassesExt};
|
||
|
|
|
||
|
|
ValueMapping temporaldeftimeextmap[] = {
|
||
|
|
MappingDefTimeExt<MString> };
|
||
|
|
|
||
|
|
ValueMapping temporalinstextmap[] = {
|
||
|
|
IntimeInstExt<CcString>,
|
||
|
|
IntimeInstExt<Region> };
|
||
|
|
|
||
|
|
|
||
|
|
ValueMapping temporalvalextmap[] = {
|
||
|
|
IntimeValExt<CcString>,
|
||
|
|
IntimeValExt<Region> };
|
||
|
|
|
||
|
|
ValueMapping temporalderivativeextmap[] = {
|
||
|
|
MovingDerivativeExt<MReal> };
|
||
|
|
|
||
|
|
ValueMapping temporalderivableextmap[] = {
|
||
|
|
MovingDerivableExt<MReal> };
|
||
|
|
|
||
|
|
ValueMapping temporalspeedextmap[] = {
|
||
|
|
MovingSpeedExt<MPoint> };
|
||
|
|
|
||
|
|
ValueMapping rangerangevaluesextmap[] = {
|
||
|
|
RangeRangevaluesBoolExt,
|
||
|
|
RangeRangevaluesIntExt,
|
||
|
|
RangeRangevaluesStringExt,
|
||
|
|
RangeRangevaluesRealExt};
|
||
|
|
|
||
|
|
ValueMapping temporalsometimesextmap[] = {
|
||
|
|
MovingSometimesExt };
|
||
|
|
|
||
|
|
ValueMapping temporalalwaysextmap[] = {
|
||
|
|
MovingAlwaysExt };
|
||
|
|
|
||
|
|
ValueMapping temporalneverextmap[] = {
|
||
|
|
MovingNeverExt };
|
||
|
|
|
||
|
|
ValueMapping globalunitoftimeextmap[] = {
|
||
|
|
GlobalUnitOfTimeExt };
|
||
|
|
|
||
|
|
ValueMapping globalunitofdistanceextmap[] = {
|
||
|
|
GlobalUnitOfDistanceExt };
|
||
|
|
|
||
|
|
ValueMapping temporalvelocityextmap[] = {
|
||
|
|
MovingVelocityExt };
|
||
|
|
|
||
|
|
ValueMapping temporalmdirectionextmap[] = {
|
||
|
|
MovingMDirectionExt<false> };
|
||
|
|
|
||
|
|
ValueMapping temporalmheadingextmap[] = {
|
||
|
|
MovingMDirectionExt<true> };
|
||
|
|
|
||
|
|
ValueMapping temporallocationsextmap[] = {
|
||
|
|
MovingLocationsExt };
|
||
|
|
|
||
|
|
ValueMapping temporalatminextmap[] = {
|
||
|
|
MappingAtminExt<MBool, UBool, CcBool>,
|
||
|
|
MappingAtminExt<MInt, UInt, CcInt>,
|
||
|
|
MappingAtminExt<MString, UString, CcString>,
|
||
|
|
MappingAtminExt_r,};
|
||
|
|
|
||
|
|
ValueMapping temporalatmaxextmap[] = {
|
||
|
|
MappingAtmaxExt<MBool, UBool, CcBool>,
|
||
|
|
MappingAtmaxExt<MInt, UInt, CcInt>,
|
||
|
|
MappingAtmaxExt<MString, UString, CcString>,
|
||
|
|
MappingAtmaxExt_r,};
|
||
|
|
|
||
|
|
|
||
|
|
ValueMapping EverNearerThan_vms[] =
|
||
|
|
{
|
||
|
|
EverNearerThan_vm<MPoint,MPoint>,
|
||
|
|
EverNearerThan_vm<MPoint, Point>,
|
||
|
|
EverNearerThan_vm<Point, MPoint>};
|
||
|
|
|
||
|
|
ValueMapping berlin2wgsVMs_lifted[] = {
|
||
|
|
berlin2wgsVM_lifted<IPoint>,
|
||
|
|
berlin2wgsVM_lifted<UPoint>,
|
||
|
|
berlin2wgsVM_lifted<MPoint>};
|
||
|
|
|
||
|
|
ValueMapping splitatgapsVMs[] = {
|
||
|
|
splitatgapsVM<MBool, UBool>,
|
||
|
|
splitatgapsVM<MInt, UInt>,
|
||
|
|
splitatgapsVM<MReal, UReal>,
|
||
|
|
splitatgapsVM<MString, UString>,
|
||
|
|
splitatgapsVM<stj::MLabel, stj::ULabel>,
|
||
|
|
splitatgapsVM<stj::MLabels, stj::ULabels>,
|
||
|
|
splitatgapsVM<stj::MPlace, stj::UPlace>,
|
||
|
|
splitatgapsVM<stj::MPlaces, stj::UPlaces>,
|
||
|
|
splitatgapsVM<MPoint, UPoint>,
|
||
|
|
splitatgapsVM<MRegion, URegionEmb>};
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.5 Specification strings
|
||
|
|
|
||
|
|
*/
|
||
|
|
const string TemporalSpecAtInstantExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>T in {int, bool, real, string, point, region},\n"
|
||
|
|
"mT x instant -> iT</text--->"
|
||
|
|
"<text>_ atinstant _ </text--->"
|
||
|
|
"<text>get the Intime value corresponding to the instant.</text--->"
|
||
|
|
"<text>mpoint1 atinstant instant1</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecAtPeriodsExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>T in {int, bool, real, string, point, region*},\n"
|
||
|
|
"mT x periods -> mT\n"
|
||
|
|
"(*) Not yet implemented for this type constructor.</text--->"
|
||
|
|
"<text>_ atperiods _ </text--->"
|
||
|
|
"<text>restrict the movement to the given periods.</text--->"
|
||
|
|
"<text>mpoint1 atperiods periods1</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecInitialExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>T in {int, bool, real, string, point, region*},\n"
|
||
|
|
"(*) Not yet implemented for this type constructor.\n"
|
||
|
|
"mT -> iT</text--->"
|
||
|
|
"<text> initial( _ )</text--->"
|
||
|
|
"<text>Get intime value corresponding to the initial instant.</text--->"
|
||
|
|
"<text>initial( mpoint1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecFinalExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>T in {int, bool, real, string, point, region*},\n"
|
||
|
|
"(*) Not yet implemented for this type constructor.\n"
|
||
|
|
"mT -> iT</text--->"
|
||
|
|
"<text> final( _ )</text--->"
|
||
|
|
"<text>get the intime value corresponding to the final instant.</text--->"
|
||
|
|
"<text>final( mpoint1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecPresentExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>mstring x instant -> bool,\n"
|
||
|
|
"mstring x periods -> bool</text--->"
|
||
|
|
"<text>_ present _ </text--->"
|
||
|
|
"<text>whether the object is present at the given instant "
|
||
|
|
"or period.</text--->"
|
||
|
|
"<text>ms1 present instant1</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecAtExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>T in {real, string},\n"
|
||
|
|
"mT x T -> mT;\n"
|
||
|
|
"T in {int, bool, real, string},\n"
|
||
|
|
"mT x rT -> mT;\n"
|
||
|
|
"T in {points, line},\n"
|
||
|
|
"mpoint x T -> mpoint\n"
|
||
|
|
"mregion x point -> mpoint**\n"
|
||
|
|
"(*) Not yet implemented for this type constructor.\n"
|
||
|
|
"(**) Operator signature is not implemented yet.</text--->"
|
||
|
|
"<text> _ at _ </text--->"
|
||
|
|
"<text>restrict the movement at the times where the equality "
|
||
|
|
"occurs.</text--->"
|
||
|
|
"<text>mpoint1 at point1</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecPassesExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>T in {int, bool, real, string},\n"
|
||
|
|
"mT x T -> bool;\n"
|
||
|
|
"T in {points, line},\n"
|
||
|
|
"mpoint x T -> bool\n"
|
||
|
|
"T in {point, points},\n"
|
||
|
|
"mregion x T -> bool</text--->"
|
||
|
|
"<text>_ passes _ </text--->"
|
||
|
|
"<text>whether the object passes the given value.</text--->"
|
||
|
|
"<text>mpoint1 passes point1</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecInstExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>T in {int, bool, real, string, point, region},\n"
|
||
|
|
"iT -> instant </text--->"
|
||
|
|
"<text>inst( _ ) </text--->"
|
||
|
|
"<text>Extract time instant from an intime value. </text--->"
|
||
|
|
"<text>inst( i1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecValExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>T in {int, bool, real, string, point, region},\n"
|
||
|
|
"iT -> T</text--->"
|
||
|
|
"<text>val( _ )</text--->"
|
||
|
|
"<text>Extract value from an intime value.</text--->"
|
||
|
|
"<text>val ( i1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecDefTimeExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>T in {int, bool, real, string, point, region*},\n"
|
||
|
|
"mT -> periods\n"
|
||
|
|
"(*) Not yet implemented for this type constructor.</text--->"
|
||
|
|
"<text> deftime( _ )</text--->"
|
||
|
|
"<text>get the defined time intervals for the corresponding moving "
|
||
|
|
"data object as a periods value.</text--->"
|
||
|
|
"<text>deftime( mp1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecDerivativeExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>mreal -> mreal</text--->"
|
||
|
|
"<text>derivative_new ( _ )</text--->"
|
||
|
|
"<text>Derivative of a mreal.</text--->"
|
||
|
|
"<text>derivative_new ( mr1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecDerivableExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>mreal -> mbool</text--->"
|
||
|
|
"<text>derivable_new ( _ )</text--->"
|
||
|
|
"<text>Checking if mreal is derivable.</text--->"
|
||
|
|
"<text>derivable_new ( mr1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecSpeedExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>mpoint [ x geoid ] -> mreal</text--->"
|
||
|
|
"<text>speed_new ( M [, Geoid ] )</text--->"
|
||
|
|
"<text>Query the scalar velocity of the moving point M in unit/s as a mreal"
|
||
|
|
". If the optional string parameter is not used, coordinates in M are "
|
||
|
|
"metric (X,Y)-pairs. Otherwise, Geoid specifies a geoid to use for "
|
||
|
|
"orthodrome-based speed-over-ground calculation and coordinates in M must "
|
||
|
|
"be validgeographic coordinates (LON,LAT).</text--->"
|
||
|
|
"<text>speed_new ( mp1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string RangeSpecRangevaluesExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>T in {int, bool, real, string},\n"
|
||
|
|
"mT -> rT</text--->"
|
||
|
|
"<text>rangevalues ( _ )</text--->"
|
||
|
|
"<text>Returns the smallest interval, that contains all "
|
||
|
|
"values assumed by the argument within its definition time "
|
||
|
|
"as a range value.</text--->"
|
||
|
|
"<text>rangevalues ( mb1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string BoolSpecSometimesExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>mbool -> bool</text--->"
|
||
|
|
"<text>sometimes ( _ )</text--->"
|
||
|
|
"<text>Returns true if a unit at least once assumes value 'TRUE'.</text--->"
|
||
|
|
"<text>sometimes ( mb1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string BoolSpecAlwaysExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>mbool -> bool</text--->"
|
||
|
|
"<text>always ( _ )</text--->"
|
||
|
|
"<text>Returns 'true' iff the moving bool does not assume value 'FALSE' "
|
||
|
|
"within its definition time.</text--->"
|
||
|
|
"<text>always ( mb1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string BoolSpecNeverExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>mbool -> bool</text--->"
|
||
|
|
"<text>never ( _ )</text--->"
|
||
|
|
"<text>Returns 'true' iff the moving bool does not "
|
||
|
|
"assume value 'TRUE' within its definition time.</text--->"
|
||
|
|
"<text>never ( mb1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecVelocityExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>mpoint -> mpoint</text--->"
|
||
|
|
"<text>velocity_new ( _ )</text--->"
|
||
|
|
"<text>Return the component-wise velocity vector of a mpoint as "
|
||
|
|
"a mpoint.</text--->"
|
||
|
|
"<text>velocity_new ( mp1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string GlobalSpecUnitOfTimeExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>real -> real</text--->"
|
||
|
|
"<text>setunitoftime ( _ )</text--->"
|
||
|
|
"<text>Set factor for unit of time: ms * real.</text--->"
|
||
|
|
"<text>setunitoftime ( 0.001 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string GlobalSpecUnitOfDistanceExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>real -> real</text--->"
|
||
|
|
"<text>setunitofdistance ( _ )</text--->"
|
||
|
|
"<text>Set factor for unit of distance: m * real.</text--->"
|
||
|
|
"<text>setunitofdistance ( 1000.0 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecMDirectionExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>mpoint [ x geoid [ x real ] ] -> mreal</text--->"
|
||
|
|
"<text>direction ( Obj [, Geoid [, Precision] ] )</text--->"
|
||
|
|
"<text>Compute the direction of the object Obj's movement as a temporal "
|
||
|
|
"function. Result unit is degree [°]. 0<=direction<360, counterclockwise "
|
||
|
|
"orientation, starting with 0° along the positive X-halfaxis. If Geoid is "
|
||
|
|
"passed, computations use great circle navigation with the given presision "
|
||
|
|
"(deafults to 0.00001). Non-positive Precision results in UNDEFINED."
|
||
|
|
"</text--->"
|
||
|
|
"<text>query direction ( train7 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecMHeadingExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>mpoint [ x geoid [ x real ] ] -> mreal</text--->"
|
||
|
|
"<text>heading ( Obj [, Geoid [, Precision] ] )</text--->"
|
||
|
|
"<text>Compute the heading of the object Obj as a temporal function. "
|
||
|
|
"Result unit is degree [°]. 0<heading<=360, NORTH = 360°, clockwise "
|
||
|
|
"orientation. If Geoid is passed, computations use great circle navigation "
|
||
|
|
"with the given presision (deafults to 0.00001). Non-positive Precision "
|
||
|
|
"results in UNDEFINED."
|
||
|
|
"</text--->"
|
||
|
|
"<text>query heading ( train7 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecLocationsExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>mpoint -> points</text--->"
|
||
|
|
"<text>locations( _ )</text--->"
|
||
|
|
"<text>Project a mpoint onto its immobile and isolated points. "
|
||
|
|
"Return the result as a points value.</text--->"
|
||
|
|
"<text>locations( mp1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecAtminExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>T in {int, bool, real, string},\n"
|
||
|
|
"mT -> mT</text--->"
|
||
|
|
"<text>atmin ( _ )</text--->"
|
||
|
|
"<text>Get mT restricted to the least value.</text--->"
|
||
|
|
"<text>atmin ( mi1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecAtmaxExt =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>T in {int, bool, real, string},\n"
|
||
|
|
"mT -> mT</text--->"
|
||
|
|
"<text>atmax ( _ )</text--->"
|
||
|
|
"<text>Get moving object restricted to its largest value.</text--->"
|
||
|
|
"<text>atmax ( mi1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecConcatS =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>stream(mpoint) -> mpoint</text--->"
|
||
|
|
"<text> _ concatS </text--->"
|
||
|
|
"<text>Concatenates all mpoints within the stream if possible.</text--->"
|
||
|
|
"<text>query train6 feed concatS </text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string TemporalSpecConcatS2 =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>stream(mpoint) x int -> mpoint</text--->"
|
||
|
|
"<text> _ concatS2 [ _ ] </text--->"
|
||
|
|
"<text>Concatenates all mpoints within the stream. Undefined mpoints are "
|
||
|
|
"Ignored. In a first step, the size of the result is set to the int arg."
|
||
|
|
"</text--->"
|
||
|
|
"<text>query train6 feed concatS2 [1000] </text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string insideSpec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>mpoint x region-> mbool </text---> "
|
||
|
|
"<text> _ inside _ </text--->"
|
||
|
|
"<text>the lifted inside predicate for mpoint X region</text--->"
|
||
|
|
"<text>query train7 inside thecenter</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string berlin2wgsSpec_lifted =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>T -> T, where T in {ipoint, upoint, mpoint} </text---> "
|
||
|
|
"<text> berlin2wgs( _ ) </text--->"
|
||
|
|
"<text>Converts coordinates from bbbike/BerlinMOD format into WGS84 "
|
||
|
|
"coordinates.</text--->"
|
||
|
|
"<text>query berlin2wgs([const point value (13132, 10876)])</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string splitatgapsSpec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>mT (x duration) -> stream(mT), where T in {bool, int, real, string, "
|
||
|
|
"label(s), place(s), point, region} </text---> "
|
||
|
|
"<text> splitAtGaps( _ , _ ) </text--->"
|
||
|
|
"<text>Splits an mT at its temporal gaps. The object will not be splitted at "
|
||
|
|
"gaps with a duration shorter than the optional second parameter. </text--->"
|
||
|
|
"<text>query splitAtGaps(train7) count</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string splitatspeedSpec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>mpoint x real (x geoid) -> stream(mpoint) </text---> "
|
||
|
|
"<text> splitAtSpeed( _ , _ , _ ) </text--->"
|
||
|
|
"<text>Splits an mpoint at units with a speed exceeding the second "
|
||
|
|
"argument </text--->"
|
||
|
|
"<text>query splitAtSpeed(train7, 0.1) count</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
const string splitatlengthSpec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
||
|
|
"( <text>mpoint x real (x geoid) -> stream(mpoint) </text---> "
|
||
|
|
"<text> splitAtLength( _ , _ , _ ) </text--->"
|
||
|
|
"<text>Splits an mpoint at units with a length exceeding the second "
|
||
|
|
"argument </text--->"
|
||
|
|
"<text>query splitAtLength(train7, 5.0) count</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
|
||
|
|
struct EverNearerThanInfo : OperatorInfo {
|
||
|
|
|
||
|
|
EverNearerThanInfo() : OperatorInfo()
|
||
|
|
{
|
||
|
|
name = "everNearerThan";
|
||
|
|
signature = "mpoint x mpoint x real -> bool, mpoint x point x real -> bool,"
|
||
|
|
" point x mpoint x real -> bool";
|
||
|
|
syntax = "everNearerThan(P1, P2, D)";
|
||
|
|
meaning = "Returns true, iff the distance between P1 and P2 ever becomes "
|
||
|
|
"smaller than D";
|
||
|
|
}
|
||
|
|
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
9.6 Operators
|
||
|
|
|
||
|
|
*/
|
||
|
|
Operator temporalatinstantext(
|
||
|
|
"atinstant",
|
||
|
|
TemporalSpecAtInstantExt,
|
||
|
|
5,
|
||
|
|
temporalatinstantextmap,
|
||
|
|
MovingExtSimpleSelect,
|
||
|
|
MovingInstantExtTypeMapIntime );
|
||
|
|
|
||
|
|
Operator temporalatperiodsext(
|
||
|
|
"atperiods",
|
||
|
|
TemporalSpecAtPeriodsExt,
|
||
|
|
2,
|
||
|
|
temporalatperiodsextmap,
|
||
|
|
MovingPeriodsSelect,
|
||
|
|
MovingPeriodsExtTypeMapMoving );
|
||
|
|
|
||
|
|
Operator temporalinitialext(
|
||
|
|
"initial",
|
||
|
|
TemporalSpecInitialExt,
|
||
|
|
5,
|
||
|
|
temporalinitialextmap,
|
||
|
|
MovingExtSimpleSelect,
|
||
|
|
MovingExtTypeMapIntime );
|
||
|
|
|
||
|
|
Operator temporalfinalext(
|
||
|
|
"final",
|
||
|
|
TemporalSpecFinalExt,
|
||
|
|
5,
|
||
|
|
temporalfinalextmap,
|
||
|
|
MovingExtSimpleSelect,
|
||
|
|
MovingExtTypeMapIntime );
|
||
|
|
|
||
|
|
Operator temporalpresentext(
|
||
|
|
"present",
|
||
|
|
TemporalSpecPresentExt,
|
||
|
|
2,
|
||
|
|
temporalpresentextmap,
|
||
|
|
MovingExtInstantPeriodsSelect,
|
||
|
|
MovingInstantPeriodsExtTypeMapBool);
|
||
|
|
|
||
|
|
Operator temporalatext(
|
||
|
|
"at",
|
||
|
|
TemporalSpecAtExt,
|
||
|
|
9,
|
||
|
|
temporalatextmap,
|
||
|
|
MovingExtBaseRangeSelect,
|
||
|
|
MovingBaseExtTypeMapMoving );
|
||
|
|
|
||
|
|
Operator temporalpassesext(
|
||
|
|
"passes",
|
||
|
|
TemporalSpecPassesExt,
|
||
|
|
6,
|
||
|
|
temporalpassesextmap,
|
||
|
|
MovingExtBaseSelect,
|
||
|
|
MovingBaseExtTypeMapBool);
|
||
|
|
|
||
|
|
Operator temporaldeftimeext(
|
||
|
|
"deftime",
|
||
|
|
TemporalSpecDefTimeExt,
|
||
|
|
5,
|
||
|
|
temporaldeftimeextmap,
|
||
|
|
MovingExtSimpleSelect,
|
||
|
|
MovingExtTypeMapPeriods );
|
||
|
|
|
||
|
|
Operator temporalinstext(
|
||
|
|
"inst",
|
||
|
|
TemporalSpecInstExt,
|
||
|
|
2,
|
||
|
|
temporalinstextmap,
|
||
|
|
IntimeExtSimpleSelect,
|
||
|
|
IntimeExtTypeMapInstant );
|
||
|
|
|
||
|
|
Operator temporalvalext(
|
||
|
|
"val",
|
||
|
|
TemporalSpecValExt,
|
||
|
|
2,
|
||
|
|
temporalvalextmap,
|
||
|
|
IntimeExtSimpleSelect,
|
||
|
|
IntimeExtTypeMapBase );
|
||
|
|
|
||
|
|
Operator temporalderivativeext(
|
||
|
|
"derivative_new",
|
||
|
|
TemporalSpecDerivativeExt,
|
||
|
|
1,
|
||
|
|
temporalderivativeextmap,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
MovingRExtTypeMapMovingR);
|
||
|
|
|
||
|
|
Operator temporalderivableext(
|
||
|
|
"derivable_new",
|
||
|
|
TemporalSpecDerivableExt,
|
||
|
|
1,
|
||
|
|
temporalderivableextmap,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
MovingRExtTypeMapBool);
|
||
|
|
|
||
|
|
Operator temporalspeedext(
|
||
|
|
"speed_new",
|
||
|
|
TemporalSpecSpeedExt,
|
||
|
|
1,
|
||
|
|
temporalspeedextmap,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
MPointOptGeoid2MReal_TM);
|
||
|
|
|
||
|
|
Operator rangerangevaluesext(
|
||
|
|
"rangevalues",
|
||
|
|
RangeSpecRangevaluesExt,
|
||
|
|
4,
|
||
|
|
rangerangevaluesextmap,
|
||
|
|
RangeRangevaluesExtBaseSelect,
|
||
|
|
RangeRangevaluesExtTypeMapRange );
|
||
|
|
|
||
|
|
Operator sometimesext(
|
||
|
|
"sometimes",
|
||
|
|
BoolSpecSometimesExt,
|
||
|
|
1,
|
||
|
|
temporalsometimesextmap,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
MovingSANExtTypeMap );
|
||
|
|
|
||
|
|
Operator alwaysext(
|
||
|
|
"always",
|
||
|
|
BoolSpecAlwaysExt,
|
||
|
|
1,
|
||
|
|
temporalalwaysextmap,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
MovingSANExtTypeMap );
|
||
|
|
|
||
|
|
Operator neverext(
|
||
|
|
"never",
|
||
|
|
BoolSpecNeverExt,
|
||
|
|
1,
|
||
|
|
temporalneverextmap,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
MovingSANExtTypeMap );
|
||
|
|
|
||
|
|
Operator setunitoftimeext(
|
||
|
|
"setunitoftime",
|
||
|
|
GlobalSpecUnitOfTimeExt,
|
||
|
|
1,
|
||
|
|
globalunitoftimeextmap,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
RealPhysicalUnitsExtTypeMap );
|
||
|
|
|
||
|
|
Operator setunitofdistanceext(
|
||
|
|
"setunitofdistance",
|
||
|
|
GlobalSpecUnitOfDistanceExt,
|
||
|
|
1,
|
||
|
|
globalunitofdistanceextmap,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
RealPhysicalUnitsExtTypeMap );
|
||
|
|
|
||
|
|
Operator temporalvelocityext(
|
||
|
|
"velocity_new",
|
||
|
|
TemporalSpecVelocityExt,
|
||
|
|
1,
|
||
|
|
temporalvelocityextmap,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
MPointExtTypeMapMPoint);
|
||
|
|
|
||
|
|
Operator temporaldirectionext(
|
||
|
|
"direction",
|
||
|
|
TemporalSpecMDirectionExt,
|
||
|
|
1,
|
||
|
|
temporalmdirectionextmap,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
MovingPointExtTypeMapMReal);
|
||
|
|
|
||
|
|
Operator temporalheadingext(
|
||
|
|
"heading",
|
||
|
|
TemporalSpecMHeadingExt,
|
||
|
|
1,
|
||
|
|
temporalmheadingextmap,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
MovingPointExtTypeMapMReal);
|
||
|
|
|
||
|
|
Operator temporallocationsext(
|
||
|
|
"locations",
|
||
|
|
TemporalSpecLocationsExt,
|
||
|
|
1,
|
||
|
|
temporallocationsextmap,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
MovingPointExtTypeMapPoints);
|
||
|
|
|
||
|
|
Operator temporalatminext(
|
||
|
|
"atmin",
|
||
|
|
TemporalSpecAtminExt,
|
||
|
|
4,
|
||
|
|
temporalatminextmap,
|
||
|
|
MovingAtMinMaxSelect,
|
||
|
|
MovingExtTypeMapMoving);
|
||
|
|
|
||
|
|
Operator temporalatmaxext(
|
||
|
|
"atmax",
|
||
|
|
TemporalSpecAtmaxExt,
|
||
|
|
4,
|
||
|
|
temporalatmaxextmap,
|
||
|
|
MovingAtMinMaxSelect,
|
||
|
|
MovingExtTypeMapMoving);
|
||
|
|
|
||
|
|
Operator temporalconcatS(
|
||
|
|
"concatS",
|
||
|
|
TemporalSpecConcatS,
|
||
|
|
ConcatSValueMap,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
ConcatSTypeMap);
|
||
|
|
|
||
|
|
Operator temporalconcatS2(
|
||
|
|
"concatS2",
|
||
|
|
TemporalSpecConcatS2,
|
||
|
|
ConcatSValueMap,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
ConcatSTypeMap);
|
||
|
|
|
||
|
|
Operator inside( "inside",
|
||
|
|
insideSpec,
|
||
|
|
InsideVM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
InsideTypeMapMPR);
|
||
|
|
|
||
|
|
Operator berlin2wgs_lifted(
|
||
|
|
"berlin2wgs",
|
||
|
|
berlin2wgsSpec_lifted,
|
||
|
|
3,
|
||
|
|
berlin2wgsVMs_lifted,
|
||
|
|
berlin2wgsSelect_lifted,
|
||
|
|
berlin2wgsTM_lifted);
|
||
|
|
|
||
|
|
Operator splitatgaps(
|
||
|
|
"splitAtGaps",
|
||
|
|
splitatgapsSpec,
|
||
|
|
10,
|
||
|
|
splitatgapsVMs,
|
||
|
|
splitatgapsSelect,
|
||
|
|
splitatgapsTM);
|
||
|
|
|
||
|
|
Operator splitatspeed(
|
||
|
|
"splitAtSpeed",
|
||
|
|
splitatspeedSpec,
|
||
|
|
splitatspeedVM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
splitatspeedlengthTM);
|
||
|
|
|
||
|
|
Operator splitatlength(
|
||
|
|
"splitAtLength",
|
||
|
|
splitatlengthSpec,
|
||
|
|
splitatlengthVM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
splitatspeedlengthTM);
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
5.15 Operator ~cyclicbulkload~
|
||
|
|
|
||
|
|
5.15.1. Data structures
|
||
|
|
|
||
|
|
5.15.1.1 GridArea
|
||
|
|
|
||
|
|
The GridArea structure defines the boundary of a 2D-grid.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
struct GridArea
|
||
|
|
{
|
||
|
|
GridArea(){}
|
||
|
|
GridArea( double X1, double Y1, double X2, double Y2 ):
|
||
|
|
x1( X1 ), y1( Y1 ), x2( X2 ), y2( Y2 ){}
|
||
|
|
double x1;
|
||
|
|
double y1;
|
||
|
|
double x2;
|
||
|
|
double y2;
|
||
|
|
};
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
5.15.1.2 Unit
|
||
|
|
|
||
|
|
Unit structure constists of a TupleId and an UPoint.
|
||
|
|
|
||
|
|
*/
|
||
|
|
struct Unit
|
||
|
|
{
|
||
|
|
TupleId tupId;
|
||
|
|
temporalalgebra::UPoint up;
|
||
|
|
};
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
5.15.1.2 Cell
|
||
|
|
|
||
|
|
Every Cell stores a map container for Units.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
struct Cell
|
||
|
|
{
|
||
|
|
GridArea area;
|
||
|
|
multimap<double,Unit> units;
|
||
|
|
};
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
5.15.1.3 Grid (2D-Cell-Array)
|
||
|
|
|
||
|
|
The grid is represented by a 2D-Cell-Array
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
const int maxSplits = 64;
|
||
|
|
Cell* cells[maxSplits][maxSplits];
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
5.15.2 Auxiliary methods
|
||
|
|
|
||
|
|
5.15.2.1 ModifyArea
|
||
|
|
|
||
|
|
Modifies the given area. x1/x2 and y1/y2 will be swapped if necessary.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
GridArea ModifyArea(GridArea AREA)
|
||
|
|
{
|
||
|
|
double tempX = 0;
|
||
|
|
double tempY = 0;
|
||
|
|
|
||
|
|
if (AREA.x1 > AREA.x2)
|
||
|
|
{
|
||
|
|
tempX = AREA.x2;
|
||
|
|
AREA.x2 = AREA.x1;
|
||
|
|
AREA.x1 = tempX;
|
||
|
|
}
|
||
|
|
if (AREA.y1 > AREA.y2)
|
||
|
|
{
|
||
|
|
tempY = AREA.y2;
|
||
|
|
AREA.y2 = AREA.y1;
|
||
|
|
AREA.y1 = tempY;
|
||
|
|
}
|
||
|
|
AREA.x1 = AREA.x1 - 0.00001;
|
||
|
|
AREA.y1 = AREA.y1 - 0.00001;
|
||
|
|
AREA.x2 = AREA.x2 + 0.00001;
|
||
|
|
AREA.y2 = AREA.y2 + 0.00001;
|
||
|
|
return AREA;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
5.15.2.2 ComputeLine
|
||
|
|
|
||
|
|
Identifies a column or a row in a grid in dependence of a given position.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int ComputeLine(double BORDER1 ,double BORDER2, int SPLITS, double POS)
|
||
|
|
{
|
||
|
|
double len = abs(BORDER1-BORDER2) / SPLITS;
|
||
|
|
int i = 0;
|
||
|
|
|
||
|
|
while ((BORDER1 + (i*len)) <= POS) i++;
|
||
|
|
|
||
|
|
return i-1;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
5.15.2.3 InsertUnits
|
||
|
|
|
||
|
|
Creates bounding boxes for the units and inserts them in Z-Order by bulk load
|
||
|
|
into the RTree.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
void InsertUnits (int SQUARES, int RIGHTCOL, int TOPROW,
|
||
|
|
R_Tree<3, TupleId>* RTREE)
|
||
|
|
{
|
||
|
|
if (SQUARES > 4)
|
||
|
|
{
|
||
|
|
InsertUnits( (SQUARES/4), (RIGHTCOL-((int)sqrt(SQUARES)/2)),
|
||
|
|
(TOPROW-((int)sqrt(SQUARES)/2)), RTREE);
|
||
|
|
InsertUnits( (SQUARES/4), (RIGHTCOL-((int)sqrt(SQUARES)/2)),TOPROW,RTREE);
|
||
|
|
InsertUnits( (SQUARES/4), RIGHTCOL, (TOPROW-((int)sqrt(SQUARES)/2)),RTREE);
|
||
|
|
InsertUnits( (SQUARES/4), RIGHTCOL, TOPROW, RTREE );
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
for (int i = 0; i < 4; i++)
|
||
|
|
{
|
||
|
|
int col = RIGHTCOL-1;
|
||
|
|
int row = TOPROW-1;
|
||
|
|
|
||
|
|
// Select cell
|
||
|
|
if ( i == 0 ) { col = col-1; row = row-1; } // leftBottomCell
|
||
|
|
if ( i == 1 ) { col = col-1; } // leftTopCell
|
||
|
|
if ( i == 2 ) { row = row-1; } // rightBottomCell
|
||
|
|
|
||
|
|
map<double,Unit>::iterator it;
|
||
|
|
|
||
|
|
for ( it = cells[col][row]->units.begin();
|
||
|
|
it != cells[col][row]->units.end(); )
|
||
|
|
{
|
||
|
|
// Get all UPoints from cell
|
||
|
|
double x1 = it->second.up.p0.GetX();
|
||
|
|
double x2 = it->second.up.p1.GetX();
|
||
|
|
double y1 = it->second.up.p0.GetY();
|
||
|
|
double y2 = it->second.up.p1.GetY();
|
||
|
|
if (x1 > x2)
|
||
|
|
{
|
||
|
|
x1 = it->second.up.p1.GetX();
|
||
|
|
x2 = it->second.up.p0.GetX();
|
||
|
|
}
|
||
|
|
if (y1 > y2)
|
||
|
|
{
|
||
|
|
y1 = it->second.up.p1.GetY();
|
||
|
|
y2 = it->second.up.p0.GetY();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Create bounding box
|
||
|
|
const double tol = 0.00001;
|
||
|
|
double start = it->second.up.timeInterval.start.ToDouble();
|
||
|
|
double end = it->second.up.timeInterval.end.ToDouble();
|
||
|
|
if ( start < end )
|
||
|
|
{
|
||
|
|
double minMax[] = { x1-tol, x2+tol, y1-tol, y2+tol, start, end};
|
||
|
|
Rectangle<3>* box = new Rectangle<3>(true,minMax);
|
||
|
|
// Insert entry into RTree
|
||
|
|
R_TreeLeafEntry<3, TupleId> e(*box, it->second.tupId);
|
||
|
|
RTREE->InsertBulkLoad(e);
|
||
|
|
delete box;
|
||
|
|
}
|
||
|
|
cells[col][row]->units.erase(it++);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
5.15.3 TypeMapping for operator ~cyclicbulkload~
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
ListExpr CyclicBulkloadTM(ListExpr args)
|
||
|
|
{
|
||
|
|
NList typeList(args);
|
||
|
|
if ( !typeList.hasLength(5) )
|
||
|
|
{
|
||
|
|
return listutils::typeError("Expecting five arguments.");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check first argument
|
||
|
|
ListExpr stream = nl->First(args);
|
||
|
|
if(!listutils::isTupleStream(stream))
|
||
|
|
{
|
||
|
|
return listutils::typeError("First arg is not a tuple stream!");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check grid size
|
||
|
|
if ( !nl->IsEqual(nl->Second(args), Rectangle<2>::BasicType()) )
|
||
|
|
{
|
||
|
|
return NList::typeError( "Rectangle for second argument expected!" );
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check number of partitions
|
||
|
|
if ( !nl->IsEqual(nl->Third(args), CcInt::BasicType()) )
|
||
|
|
{
|
||
|
|
return NList::typeError( "Integer for third argument expected!" );
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check cycle time
|
||
|
|
if ( !nl->IsEqual(nl->Fourth(args), CcInt::BasicType()) )
|
||
|
|
{
|
||
|
|
return NList::typeError( "Integer for fourth argument expected!" );
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check for index attribute
|
||
|
|
ListExpr fifth = nl->Fifth(args);
|
||
|
|
if(nl->AtomType(fifth)!=SymbolType)
|
||
|
|
{
|
||
|
|
return listutils::typeError("Fifth argument is not a valid attr name!");
|
||
|
|
}
|
||
|
|
|
||
|
|
string attrName = nl->SymbolValue(fifth);
|
||
|
|
ListExpr attrList = nl->Second(nl->Second(stream));
|
||
|
|
ListExpr attrType;
|
||
|
|
int attrIndex = listutils::findAttribute(attrList, attrName, attrType);
|
||
|
|
if(attrIndex <= 0){
|
||
|
|
return listutils::typeError("Expecting the attribute for fifth argument.");
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( nl->SymbolValue(attrType) != MPoint::BasicType() &&
|
||
|
|
nl->SymbolValue(attrType) != UPoint::BasicType() )
|
||
|
|
{
|
||
|
|
return NList::typeError("Attribute type is not of type mpoint or upoint.");
|
||
|
|
}
|
||
|
|
|
||
|
|
bool isMPoint = MPoint::checkType(attrType);
|
||
|
|
|
||
|
|
ListExpr first, rest,
|
||
|
|
newAttrList=nl->TheEmptyList(),
|
||
|
|
lastNewAttrList=nl->TheEmptyList();
|
||
|
|
int tidIndex = 0;
|
||
|
|
string type;
|
||
|
|
bool firstcall = true;
|
||
|
|
|
||
|
|
rest = attrList;
|
||
|
|
int j = 1;
|
||
|
|
while (!nl->IsEmpty(rest))
|
||
|
|
{
|
||
|
|
first = nl->First(rest);
|
||
|
|
rest = nl->Rest(rest);
|
||
|
|
|
||
|
|
type = nl->SymbolValue(nl->Second(first));
|
||
|
|
if (type == TupleIdentifier::BasicType())
|
||
|
|
{
|
||
|
|
if( tidIndex != 0 ){
|
||
|
|
return listutils::typeError("Expecting exactly one attribute of type "
|
||
|
|
"'tid' in the 1st argument.");
|
||
|
|
}
|
||
|
|
tidIndex = j;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (firstcall)
|
||
|
|
{
|
||
|
|
firstcall = false;
|
||
|
|
newAttrList = nl->OneElemList(first);
|
||
|
|
lastNewAttrList = newAttrList;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
lastNewAttrList = nl->Append(lastNewAttrList, first);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
j++;
|
||
|
|
}
|
||
|
|
if( tidIndex == 0 )
|
||
|
|
{
|
||
|
|
return listutils::typeError("Expecting exactly one attribute of type "
|
||
|
|
"'tid' in the 1st argument.");
|
||
|
|
}
|
||
|
|
|
||
|
|
return
|
||
|
|
nl->ThreeElemList(
|
||
|
|
nl->SymbolAtom(Symbol::APPEND()),
|
||
|
|
nl->ThreeElemList(
|
||
|
|
nl->IntAtom(attrIndex),
|
||
|
|
nl->IntAtom(tidIndex),
|
||
|
|
nl->BoolAtom(isMPoint)),
|
||
|
|
nl->FourElemList(
|
||
|
|
nl->SymbolAtom(RTree3TID::BasicType()),
|
||
|
|
nl->TwoElemList(
|
||
|
|
nl->SymbolAtom(Tuple::BasicType()),
|
||
|
|
newAttrList),
|
||
|
|
attrType,
|
||
|
|
nl->BoolAtom(false)));
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
ValueMapping for operator ~cyclicbulkload~
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
int CyclicBulkloadVM(Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s)
|
||
|
|
{
|
||
|
|
Rectangle<2>* rect = static_cast<Rectangle<2>*>(args[1].addr);
|
||
|
|
int numCells = static_cast<CcInt*>(args[2].addr)->GetValue();
|
||
|
|
int cycleTime = static_cast<CcInt*>(args[3].addr)->GetValue();
|
||
|
|
int entries = 0;
|
||
|
|
|
||
|
|
// Create new RTree
|
||
|
|
R_Tree<3, TupleId>* rtree = (R_Tree<3, TupleId>*)qp->ResultStorage(s).addr;
|
||
|
|
result.setAddr( rtree );
|
||
|
|
|
||
|
|
// Initialize RTree for bulk load
|
||
|
|
int BulkLoadInitialized = rtree->InitializeBulkLoad();
|
||
|
|
assert(BulkLoadInitialized);
|
||
|
|
|
||
|
|
// Create grid area
|
||
|
|
double x1(rect->MinD(0));
|
||
|
|
double x2(rect->MaxD(0));
|
||
|
|
double y1(rect->MinD(1));
|
||
|
|
double y2(rect->MaxD(1));
|
||
|
|
GridArea area(x1,y1,x2,y2);
|
||
|
|
area = ModifyArea(area);
|
||
|
|
|
||
|
|
// Check number of cells
|
||
|
|
if ( !( numCells == 16 ||
|
||
|
|
numCells == 64 ||
|
||
|
|
numCells == 256 ||
|
||
|
|
numCells == 4096 )) numCells = 4;
|
||
|
|
const int splits = (int)sqrt(numCells);
|
||
|
|
|
||
|
|
// Check cycle time
|
||
|
|
if ( cycleTime < 1000 ) cycleTime = 1000;
|
||
|
|
|
||
|
|
// Calculate x/y cell length
|
||
|
|
double areaLenX = abs(area.x2 - area.x1);
|
||
|
|
double areaLenY = abs(area.y2 - area.y1);
|
||
|
|
double cellLenX = areaLenX / splits;
|
||
|
|
double cellLenY = areaLenY / splits;
|
||
|
|
|
||
|
|
GridArea partition(0,0,0,0);
|
||
|
|
for (int i = 0; i < splits; i++)
|
||
|
|
{
|
||
|
|
for (int j = 0; j < splits; j++)
|
||
|
|
{
|
||
|
|
partition.x1 = area.x1 + (cellLenX * j);
|
||
|
|
partition.x2 = partition.x1 + cellLenX;
|
||
|
|
partition.y1 = area.y1 + (cellLenY * i);
|
||
|
|
partition.y2 = partition.y1 + cellLenY;
|
||
|
|
cells[j][i] = new Cell();
|
||
|
|
cells[j][i]->area = partition;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Create an instant object for systemTime
|
||
|
|
Instant systemTime(0,0,datetime::instanttype);
|
||
|
|
systemTime.Now();
|
||
|
|
int32_t startTime = systemTime.GetAllMilliSeconds();
|
||
|
|
|
||
|
|
Word wTuple;
|
||
|
|
qp->Open(args[0].addr);
|
||
|
|
qp->Request(args[0].addr, wTuple);
|
||
|
|
|
||
|
|
int attrIndex = ((CcInt*)args[5].addr)->GetIntval() - 1;
|
||
|
|
int tidIndex = ((CcInt*)args[6].addr)->GetIntval() - 1;
|
||
|
|
bool isMPoint = ((CcBool*)args[7].addr)->GetBoolval();
|
||
|
|
while (qp->Received(args[0].addr))
|
||
|
|
{
|
||
|
|
Tuple* tuple = (Tuple*)wTuple.addr;
|
||
|
|
|
||
|
|
systemTime.Now();
|
||
|
|
if ( systemTime.GetAllMilliSeconds() > (startTime + cycleTime))
|
||
|
|
{
|
||
|
|
// Insert units into RTree (Z-Order)
|
||
|
|
InsertUnits(numCells, splits, splits, rtree);
|
||
|
|
|
||
|
|
// Start time for the next slice
|
||
|
|
startTime += cycleTime;
|
||
|
|
|
||
|
|
// Clear grid
|
||
|
|
for (int i = 0; i < splits; i++)
|
||
|
|
{
|
||
|
|
for (int j = 0; j < splits; j++)
|
||
|
|
{
|
||
|
|
cells[j][i]->units.clear();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( isMPoint )
|
||
|
|
{
|
||
|
|
// Attribute type is mpoint
|
||
|
|
MPoint* mp = static_cast<MPoint*>(tuple->GetAttribute(attrIndex));
|
||
|
|
int i = 0;
|
||
|
|
while ( i < mp->GetNoComponents() )
|
||
|
|
{
|
||
|
|
|
||
|
|
Unit u;
|
||
|
|
u.tupId = ((TupleIdentifier *)tuple->GetAttribute(tidIndex))->GetTid();
|
||
|
|
mp->Get(i, u.up);
|
||
|
|
|
||
|
|
// Insert upoint into cell, sorted by start time
|
||
|
|
systemTime.Now();
|
||
|
|
if ( u.up.timeInterval.end < systemTime &&
|
||
|
|
u.up.p0.GetX() > area.x1 && u.up.p0.GetX() < area.x2 &&
|
||
|
|
u.up.p1.GetX() > area.x1 && u.up.p1.GetX() < area.x2 &&
|
||
|
|
u.up.p0.GetY() > area.y1 && u.up.p0.GetY() < area.y2 &&
|
||
|
|
u.up.p1.GetY() > area.y1 && u.up.p1.GetY() < area.y2 )
|
||
|
|
{
|
||
|
|
int col = ComputeLine(area.x1, area.x2, splits, u.up.p0.GetX());
|
||
|
|
int row = ComputeLine(area.y1, area.y2, splits, u.up.p0.GetY());
|
||
|
|
|
||
|
|
cells[col][row]->
|
||
|
|
units.insert(make_pair(u.up.timeInterval.start.ToDouble(),u));
|
||
|
|
}
|
||
|
|
i++;
|
||
|
|
entries++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
// Attribute type is upoint
|
||
|
|
UPoint* up = static_cast<UPoint*>(tuple->GetAttribute(attrIndex));
|
||
|
|
Unit u;
|
||
|
|
u.tupId = ((TupleIdentifier *)tuple->GetAttribute(tidIndex))->GetTid();
|
||
|
|
u.up = *up;
|
||
|
|
|
||
|
|
// Insert upoint into cell, sorted by start time
|
||
|
|
systemTime.Now();
|
||
|
|
if ( u.up.timeInterval.end < systemTime &&
|
||
|
|
u.up.p0.GetX() > area.x1 && u.up.p0.GetX() < area.x2 &&
|
||
|
|
u.up.p1.GetX() > area.x1 && u.up.p1.GetX() < area.x2 &&
|
||
|
|
u.up.p0.GetY() > area.y1 && u.up.p0.GetY() < area.y2 &&
|
||
|
|
u.up.p1.GetY() > area.y1 && u.up.p1.GetY() < area.y2 )
|
||
|
|
{
|
||
|
|
int col = ComputeLine(area.x1, area.x2, splits, u.up.p0.GetX());
|
||
|
|
int row = ComputeLine(area.y1, area.y2, splits, u.up.p0.GetY());
|
||
|
|
|
||
|
|
cells[col][row]->
|
||
|
|
units.insert(make_pair(u.up.timeInterval.start.ToDouble(),u));
|
||
|
|
entries++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
delete tuple;
|
||
|
|
qp->Request(args[0].addr, wTuple);
|
||
|
|
}
|
||
|
|
qp->Close(args[0].addr);
|
||
|
|
// Insert the last entries into the RTree
|
||
|
|
InsertUnits(numCells, splits, splits, rtree);
|
||
|
|
|
||
|
|
// Insert dummy if the rtree is empty
|
||
|
|
if (entries == 0)
|
||
|
|
{ double minMax[] ={0.0,1.0,0.0,1.0,0.0,1.0 };
|
||
|
|
Rectangle<3>* box = new Rectangle<3>(true,minMax);
|
||
|
|
R_TreeLeafEntry<3, TupleId> e(*box,0);
|
||
|
|
rtree->InsertBulkLoad(e);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Finalize bulk load
|
||
|
|
int FinalizedBulkLoad = rtree->FinalizeBulkLoad();
|
||
|
|
assert(FinalizedBulkLoad);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
Specification for operator ~cyclicbulkload~
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
struct CyclicBulkloadInfo : OperatorInfo {
|
||
|
|
CyclicBulkloadInfo()
|
||
|
|
{
|
||
|
|
name = "cyclicbulkload";
|
||
|
|
signature = "((stream (tuple([a1:d1, ..., {aj:mpoint, aj:upoint}, ...,"
|
||
|
|
" an:dn, id:tid]))) x rect x int int x aj) -> rtree3";
|
||
|
|
syntax = "_ cyclicbulkload [ _, _, _, _ ]";
|
||
|
|
meaning = "Cyclic bulkload method for moving points.";
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
class TemporalExtAlgebra : public Algebra
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
TemporalExtAlgebra() : Algebra()
|
||
|
|
{
|
||
|
|
AddTypeConstructor( &intimestring );
|
||
|
|
|
||
|
|
AddTypeConstructor( &unitstring );
|
||
|
|
|
||
|
|
AddTypeConstructor( &movingstring );
|
||
|
|
|
||
|
|
AddTypeConstructor( &rangebool );
|
||
|
|
AddTypeConstructor( &rangestring );
|
||
|
|
|
||
|
|
intimestring.AssociateKind( Kind::TEMPORAL() );
|
||
|
|
intimestring.AssociateKind( Kind::DATA() );
|
||
|
|
|
||
|
|
unitstring.AssociateKind( Kind::TEMPORAL() );
|
||
|
|
unitstring.AssociateKind( Kind::DATA() );
|
||
|
|
|
||
|
|
movingstring.AssociateKind( Kind::TEMPORAL() );
|
||
|
|
movingstring.AssociateKind( Kind::DATA() );
|
||
|
|
|
||
|
|
rangebool.AssociateKind( Kind::RANGE() );
|
||
|
|
rangebool.AssociateKind( Kind::DATA() );
|
||
|
|
|
||
|
|
rangestring.AssociateKind( Kind::RANGE() );
|
||
|
|
rangestring.AssociateKind( Kind::DATA() );
|
||
|
|
|
||
|
|
AddOperator( &temporalatinstantext );
|
||
|
|
AddOperator( &temporalatperiodsext );
|
||
|
|
AddOperator( &temporalinitialext );
|
||
|
|
AddOperator( &temporalfinalext );
|
||
|
|
AddOperator( &temporalpresentext );
|
||
|
|
AddOperator( &temporalatext );
|
||
|
|
AddOperator( &temporalpassesext );
|
||
|
|
AddOperator( &temporaldeftimeext );
|
||
|
|
AddOperator( &temporalinstext );
|
||
|
|
AddOperator( &temporalvalext );
|
||
|
|
AddOperator( &temporalderivativeext );
|
||
|
|
AddOperator( &temporalderivableext );
|
||
|
|
AddOperator( &temporalspeedext );
|
||
|
|
AddOperator( &temporalvelocityext );
|
||
|
|
AddOperator( &temporaldirectionext );
|
||
|
|
AddOperator( &temporalheadingext );
|
||
|
|
AddOperator( &temporallocationsext );
|
||
|
|
AddOperator( &temporalatminext );
|
||
|
|
AddOperator( &temporalatmaxext );
|
||
|
|
|
||
|
|
AddOperator( &rangerangevaluesext );
|
||
|
|
|
||
|
|
AddOperator( &sometimesext );
|
||
|
|
AddOperator( &alwaysext );
|
||
|
|
AddOperator( &neverext );
|
||
|
|
AddOperator( &setunitoftimeext );
|
||
|
|
AddOperator( &setunitofdistanceext );
|
||
|
|
AddOperator( &temporalconcatS );
|
||
|
|
AddOperator( &temporalconcatS2 );
|
||
|
|
|
||
|
|
AddOperator( EverNearerThanInfo(), EverNearerThan_vms,
|
||
|
|
EverNearerThan_sf, EverNearerThan_tm );
|
||
|
|
AddOperator(&inside);
|
||
|
|
|
||
|
|
AddOperator(&berlin2wgs_lifted);
|
||
|
|
AddOperator(&splitatgaps);
|
||
|
|
AddOperator(&splitatspeed);
|
||
|
|
AddOperator(&splitatlength);
|
||
|
|
|
||
|
|
AddOperator(CyclicBulkloadInfo(), CyclicBulkloadVM, CyclicBulkloadTM);
|
||
|
|
|
||
|
|
}
|
||
|
|
~TemporalExtAlgebra() {}
|
||
|
|
};
|
||
|
|
|
||
|
|
} // end of namespace temporalalgebra
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
10 Initialization
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
extern "C"
|
||
|
|
Algebra*
|
||
|
|
InitializeTemporalExtAlgebra(NestedList *nlRef, QueryProcessor *qpRef)
|
||
|
|
{
|
||
|
|
nl = nlRef;
|
||
|
|
qp = qpRef;
|
||
|
|
return (new temporalalgebra::TemporalExtAlgebra());
|
||
|
|
}
|
||
|
|
|