/* ---- 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 #include #include #include #include #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 unit_interval; vector sgms; }; struct GroupOfIntervals { int unit_nr; Interval 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 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 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 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 points; vector hsegments; bool contained; for(int i=0;iClear(); result->StartBulkLoad(); for(size_t i=0;iSize();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 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;jSize();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 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 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 && jSize() ) { 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 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 && jSize() ) { 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: " < object Return: nothing */ template void MappingExt::AtMin( Mapping &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::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 object Return: nothing */ template void MappingExt::AtMax( Mapping &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::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;iSetUnitMin( 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;iSetUnitMin( 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;iSetUnitMin( 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;iSetUnitMin( 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 object result: a reference to a Mapping object Return: nothing */ template void MappingExt::At( Range* inv, Mapping &result ) const { result.Clear(); if( !this->IsDefined() || !inv->IsDefined() ){ result.SetDefined( false ); return; } result.SetDefined( true ); Unit utemp; bool is_valid = true; Interval 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::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 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 minintervals, maxintervals; result.Clear(); result.StartBulkLoad(); for( int i=0; iGet(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 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;jGetNoComponents();j++) { Interval inv_tmp; Interval 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 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 temp2; Interval temp3; MSegmentData oldsmg; MSegmentData newsmg; vector temp_intervals; GroupOfIntervals inter_temp; vector tempsgms; USegments usegtemp; const DbArray* oldsgms; unsigned int starting_segments_pos; for(int i=0;iGetNoComponents();i++) { mregparam->Get(i, utemp); for(int j=0;jGetNoComponents();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;iGetMSegmentData(); for(unsigned int i=0;iGet(temp_intervals[i].unit_nr, utemp); usegtemp.unit_nr = i; for(int k=0;k 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 start, end; Initial(start); Final(end); Interval 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 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 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::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 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 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::BasicType() )); } /* 4.3 Creation of the type constructor ~istring~ */ TypeConstructor intimestring( Intime::BasicType(), //name IntimeStringProperty, //property function describing signature OutIntime, InIntime, //Out and In functions 0, 0, //SaveToList and RestoreFromList functions CreateIntime, DeleteIntime, //object creation and deletion 0, 0, // object open and save CloseIntime, CloneIntime, //object close and clone CastIntime, //cast function SizeOfIntime, //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, InConstTemporalUnit, //Out and In functions 0, 0, //SaveToList and RestoreFromList functions CreateConstTemporalUnit, DeleteConstTemporalUnit, //object creation and deletion 0, 0, // object open and save CloseConstTemporalUnit, CloneConstTemporalUnit, //object close and clone CastConstTemporalUnit, //cast function SizeOfConstTemporalUnit, //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 >, InMapping >, 0, 0, //SaveToList and RestoreFromList functions CreateMapping, DeleteMapping, //object creation and deletion 0, 0, // object open and save CloseMapping, CloneMapping, //object close and clone CastMapping, //cast function SizeOfMapping, //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, InRange, //Out and In functions 0, 0, //SaveToList and RestoreFromList functions CreateRange,DeleteRange, //object creation and deletion OpenRange, SaveRange, // object open and save CloseRange, CloneRange, //object close and clone CastRange, //cast function SizeOfRange, //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, InRange, //Out and In functions 0, 0, //SaveToList and RestoreFromList functions CreateRange,DeleteRange, //obj. creation and deletion OpenRange, SaveRange, // object open and save CloseRange, CloneRange, //object close and clone CastRange, //cast function SizeOfRange, //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::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::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::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::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::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 int MappingAtInstantExt( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); Intime* pResult = (Intime*)result.addr; ((Mapping*)args[0].addr)->AtInstant( *((Instant*)args[1].addr), *pResult ); return 0; } /* 9.3.2 Value mapping functions of operator ~atperiods~ */ template 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 int MappingInitialExt( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); Mapping *m = ((Mapping*)args[0].addr); Intime* pResult = ((Intime*)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 int MappingFinalExt( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); Mapping *m = ((Mapping*)args[0].addr); Intime* pResult = ((Intime*)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 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 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 int MappingAtExt( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MappingExt *m = ((MappingExt*)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 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 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 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 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 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;iSize();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 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 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 int IntimeInstExt( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); Intime* i = (Intime*)args[0].addr; if( i->IsDefined()) ((Instant*)result.addr)->CopyFrom( &((Intime*)args[0].addr)->instant); else ((Instant*)result.addr)->SetDefined( false ); return 0; } /* 9.3.10 Value mapping functions of operator ~val~ */ template int IntimeValExt( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); Intime* i = (Intime*)args[0].addr; if( i->IsDefined() ) ((Alpha*)result.addr)->CopyFrom( &((Intime*)args[0].addr)->value ); else ((Alpha*)result.addr)->SetDefined( false ); return 0; } /* 9.3.11 Value mapping functions of operator ~derivativeext~ */ template 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;iGetNoComponents();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 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;iGetNoComponents();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 int MovingSpeedExt( Word* args, Word& result, int message, Word& local, Supplier s ){ result = qp->ResultStorage(s); MReal* res = static_cast(result.addr); MPoint* arg1 = static_cast(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(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;iGetNoComponents();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 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 BTree; // clock_t clock1, clock2, clock3, clock4; // double time1, time2; // clock1 = clock(); for(int i=0;iGetNoComponents();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::iterator iter; CcInt mincc, maxcc; int min=0, max=0; bool start=true; Interval 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 BTree; string temp; // clock_t clock1, clock2, clock3, clock4; // double time1, time2; // clock1 = clock(); for(int i=0;iGetNoComponents();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::iterator iter; CcString minmaxcc; STRING_T minmax; Interval 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;iAdd(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& j, const Interval& 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 inter; multimap< double,const Interval > intermap; // clock1 = clock(); vector resvector; for(int i=0;iGetNoComponents();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 >(max, inter)); } // clock2 = clock(); // time1 = ((clock2-clock1)/CLOCKS_PER_SEC) * 1000.; // cout << endl << "Time to insert values: " // << time1 << " milliseconds" << endl; multimap< double,const Interval >::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;iGetNoComponents();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;iGetNoComponents();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;iGetNoComponents();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;iGetNoComponents();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 int MovingMDirectionExt( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MReal* pResult = static_cast(result.addr); MPoint* m = static_cast(args[0].addr); const Geoid* geoid = (qp->GetNoSons(s)>=2)?static_cast(args[1].addr):0; const CcReal* eps = (qp->GetNoSons(s)==3)?static_cast(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 int MappingAtminExt( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MappingExt* m = ((MappingExt*)args[0].addr); Mapping* pResult = ((Mapping*)result.addr); m->AtMin( *pResult ); return 0; } template int MappingAtmaxExt( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MappingExt* m = ((MappingExt*)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 rs(arg0, arg1); Interval 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 resvec; upoint.Distance(*arg0, resvec, geoid); bool correct = false; for(vector::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 int EverNearerThan_vm( Word* args, Word& result, int message, Word& local, Supplier s ) { // args[0] : S* S* arg0 = static_cast(args[0].addr); T* arg1 = static_cast(args[1].addr); CcReal* arg2 = static_cast(args[2].addr); Geoid* geoid = (qp->GetNoSons(s)==4)?static_cast(args[3].addr):0; result = qp->ResultStorage(s); CcBool* res = static_cast(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(result.addr); MPointExt* arg1 = static_cast(args[0].addr); Region* arg2 = static_cast(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 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 int splitatgapsVM(Word* args, Word& result, int message, Word& local, Supplier s) { SplitAtGapsLI *li = (SplitAtGapsLI*)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(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 }; ValueMapping temporalatperiodsextmap[] = { MappingAtPeriodsExt, MappingAtPeriodsExtMRegion}; ValueMapping temporalinitialextmap[] = { MappingInitialExt }; ValueMapping temporalfinalextmap[] = { MappingFinalExt }; ValueMapping temporalpresentextmap[] = { MappingPresentExt_i, MappingPresentExt_p, }; ValueMapping temporalatextmap[] = { MappingRealAtExt, MappingStringAtExt, MappingAtExt, MappingAtExt, MappingAtExt, MappingRRealAtExt, MappingMPointPointsAtExt, MappingMPointLineAtExt, MRegionPointAtExt, }; ValueMapping temporalpassesextmap[] = { MRealRealPassesExt, MappingPassesExt, MPointPointsPassesExt, MPointLinePassesExt, MRegionPointPassesExt, MRegionPointsPassesExt}; ValueMapping temporaldeftimeextmap[] = { MappingDefTimeExt }; ValueMapping temporalinstextmap[] = { IntimeInstExt, IntimeInstExt }; ValueMapping temporalvalextmap[] = { IntimeValExt, IntimeValExt }; ValueMapping temporalderivativeextmap[] = { MovingDerivativeExt }; ValueMapping temporalderivableextmap[] = { MovingDerivableExt }; ValueMapping temporalspeedextmap[] = { MovingSpeedExt }; 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 }; ValueMapping temporalmheadingextmap[] = { MovingMDirectionExt }; ValueMapping temporallocationsextmap[] = { MovingLocationsExt }; ValueMapping temporalatminextmap[] = { MappingAtminExt, MappingAtminExt, MappingAtminExt, MappingAtminExt_r,}; ValueMapping temporalatmaxextmap[] = { MappingAtmaxExt, MappingAtmaxExt, MappingAtmaxExt, MappingAtmaxExt_r,}; ValueMapping EverNearerThan_vms[] = { EverNearerThan_vm, EverNearerThan_vm, EverNearerThan_vm}; ValueMapping berlin2wgsVMs_lifted[] = { berlin2wgsVM_lifted, berlin2wgsVM_lifted, berlin2wgsVM_lifted}; ValueMapping splitatgapsVMs[] = { splitatgapsVM, splitatgapsVM, splitatgapsVM, splitatgapsVM, splitatgapsVM, splitatgapsVM, splitatgapsVM, splitatgapsVM, splitatgapsVM, splitatgapsVM}; /* 9.5 Specification strings */ const string TemporalSpecAtInstantExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( T in {int, bool, real, string, point, region},\n" "mT x instant -> iT" "_ atinstant _ " "get the Intime value corresponding to the instant." "mpoint1 atinstant instant1" ") )"; const string TemporalSpecAtPeriodsExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( T in {int, bool, real, string, point, region*},\n" "mT x periods -> mT\n" "(*) Not yet implemented for this type constructor." "_ atperiods _ " "restrict the movement to the given periods." "mpoint1 atperiods periods1" ") )"; const string TemporalSpecInitialExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( T in {int, bool, real, string, point, region*},\n" "(*) Not yet implemented for this type constructor.\n" "mT -> iT" " initial( _ )" "Get intime value corresponding to the initial instant." "initial( mpoint1 )" ") )"; const string TemporalSpecFinalExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( T in {int, bool, real, string, point, region*},\n" "(*) Not yet implemented for this type constructor.\n" "mT -> iT" " final( _ )" "get the intime value corresponding to the final instant." "final( mpoint1 )" ") )"; const string TemporalSpecPresentExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( mstring x instant -> bool,\n" "mstring x periods -> bool" "_ present _ " "whether the object is present at the given instant " "or period." "ms1 present instant1" ") )"; const string TemporalSpecAtExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( 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." " _ at _ " "restrict the movement at the times where the equality " "occurs." "mpoint1 at point1" ") )"; const string TemporalSpecPassesExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( 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" "_ passes _ " "whether the object passes the given value." "mpoint1 passes point1" ") )"; const string TemporalSpecInstExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( T in {int, bool, real, string, point, region},\n" "iT -> instant " "inst( _ ) " "Extract time instant from an intime value. " "inst( i1 )" ") )"; const string TemporalSpecValExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( T in {int, bool, real, string, point, region},\n" "iT -> T" "val( _ )" "Extract value from an intime value." "val ( i1 )" ") )"; const string TemporalSpecDefTimeExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( T in {int, bool, real, string, point, region*},\n" "mT -> periods\n" "(*) Not yet implemented for this type constructor." " deftime( _ )" "get the defined time intervals for the corresponding moving " "data object as a periods value." "deftime( mp1 )" ") )"; const string TemporalSpecDerivativeExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( mreal -> mreal" "derivative_new ( _ )" "Derivative of a mreal." "derivative_new ( mr1 )" ") )"; const string TemporalSpecDerivableExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( mreal -> mbool" "derivable_new ( _ )" "Checking if mreal is derivable." "derivable_new ( mr1 )" ") )"; const string TemporalSpecSpeedExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( mpoint [ x geoid ] -> mreal" "speed_new ( M [, Geoid ] )" "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)." "speed_new ( mp1 )" ") )"; const string RangeSpecRangevaluesExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( T in {int, bool, real, string},\n" "mT -> rT" "rangevalues ( _ )" "Returns the smallest interval, that contains all " "values assumed by the argument within its definition time " "as a range value." "rangevalues ( mb1 )" ") )"; const string BoolSpecSometimesExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( mbool -> bool" "sometimes ( _ )" "Returns true if a unit at least once assumes value 'TRUE'." "sometimes ( mb1 )" ") )"; const string BoolSpecAlwaysExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( mbool -> bool" "always ( _ )" "Returns 'true' iff the moving bool does not assume value 'FALSE' " "within its definition time." "always ( mb1 )" ") )"; const string BoolSpecNeverExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( mbool -> bool" "never ( _ )" "Returns 'true' iff the moving bool does not " "assume value 'TRUE' within its definition time." "never ( mb1 )" ") )"; const string TemporalSpecVelocityExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( mpoint -> mpoint" "velocity_new ( _ )" "Return the component-wise velocity vector of a mpoint as " "a mpoint." "velocity_new ( mp1 )" ") )"; const string GlobalSpecUnitOfTimeExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( real -> real" "setunitoftime ( _ )" "Set factor for unit of time: ms * real." "setunitoftime ( 0.001 )" ") )"; const string GlobalSpecUnitOfDistanceExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( real -> real" "setunitofdistance ( _ )" "Set factor for unit of distance: m * real." "setunitofdistance ( 1000.0 )" ") )"; const string TemporalSpecMDirectionExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( mpoint [ x geoid [ x real ] ] -> mreal" "direction ( Obj [, Geoid [, Precision] ] )" "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." "" "query direction ( train7 )" ") )"; const string TemporalSpecMHeadingExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( mpoint [ x geoid [ x real ] ] -> mreal" "heading ( Obj [, Geoid [, Precision] ] )" "Compute the heading of the object Obj as a temporal function. " "Result unit is degree [°]. 0" "query heading ( train7 )" ") )"; const string TemporalSpecLocationsExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( mpoint -> points" "locations( _ )" "Project a mpoint onto its immobile and isolated points. " "Return the result as a points value." "locations( mp1 )" ") )"; const string TemporalSpecAtminExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( T in {int, bool, real, string},\n" "mT -> mT" "atmin ( _ )" "Get mT restricted to the least value." "atmin ( mi1 )" ") )"; const string TemporalSpecAtmaxExt = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( T in {int, bool, real, string},\n" "mT -> mT" "atmax ( _ )" "Get moving object restricted to its largest value." "atmax ( mi1 )" ") )"; const string TemporalSpecConcatS = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( stream(mpoint) -> mpoint" " _ concatS " "Concatenates all mpoints within the stream if possible." "query train6 feed concatS " ") )"; const string TemporalSpecConcatS2 = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( stream(mpoint) x int -> mpoint" " _ concatS2 [ _ ] " "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." "" "query train6 feed concatS2 [1000] " ") )"; const string insideSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( mpoint x region-> mbool " " _ inside _ " "the lifted inside predicate for mpoint X region" "query train7 inside thecenter" ") )"; const string berlin2wgsSpec_lifted = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( T -> T, where T in {ipoint, upoint, mpoint} " " berlin2wgs( _ ) " "Converts coordinates from bbbike/BerlinMOD format into WGS84 " "coordinates." "query berlin2wgs([const point value (13132, 10876)])" ") )"; const string splitatgapsSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( mT (x duration) -> stream(mT), where T in {bool, int, real, string, " "label(s), place(s), point, region} " " splitAtGaps( _ , _ ) " "Splits an mT at its temporal gaps. The object will not be splitted at " "gaps with a duration shorter than the optional second parameter. " "query splitAtGaps(train7) count" ") )"; const string splitatspeedSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( mpoint x real (x geoid) -> stream(mpoint) " " splitAtSpeed( _ , _ , _ ) " "Splits an mpoint at units with a speed exceeding the second " "argument " "query splitAtSpeed(train7, 0.1) count" ") )"; const string splitatlengthSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( mpoint x real (x geoid) -> stream(mpoint) " " splitAtLength( _ , _ , _ ) " "Splits an mpoint at units with a length exceeding the second " "argument " "query splitAtLength(train7, 5.0) count" ") )"; 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 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::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*>(args[1].addr); int numCells = static_cast(args[2].addr)->GetValue(); int cycleTime = static_cast(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(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(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()); }