/* 3.15 ~LinearPointsMove~ */ #include #include #include "NestedList.h" #include "StandardTypes.h" #include "PeriodicSupport.h" #include "PeriodicTypes.h" #include "DateTime.h" #include "Algebras/Spatial/SpatialAlgebra.h" using namespace std; using namespace datetime; extern NestedList* nl; namespace periodic{ /* ~Constructor~ */ LinearPointsMove::LinearPointsMove(){} LinearPointsMove::LinearPointsMove(const LinearPointsMove& source): interval(0), bbox(0){ Equalize(&source); } /* ~Destructor~ */ LinearPointsMove::~LinearPointsMove(){} /* ~Assignment Operator~ */ LinearPointsMove& LinearPointsMove::operator=(const LinearPointsMove& source){ Equalize(&source); return *this; } /* ~IsDefined~ */ bool LinearPointsMove::IsDefined()const{ return defined; } /* ~IsStatic~ */ bool LinearPointsMove::IsStatic()const{ return isStatic; } /* ~Accessing the occupied array range~ */ unsigned int LinearPointsMove::GetStartIndex()const { return startIndex; } unsigned int LinearPointsMove::GetEndIndex()const { return endIndex; } /* ~Constructor~ This Constructor creates an undefined instance of this class. [3] O(1) */ LinearPointsMove::LinearPointsMove(int dummy):interval(0),bbox(0){ __TRACE__ startIndex=0; endIndex=0; isStatic = true; defined = false; } /* ~ToListEpr~ This function returns the nested list corresponding to this LinearPointsMove. Because this class can't manage the location of the points, the array containing the points is given as an argument. If the array not contains enough entries, the result will be zero. [3] O(P) where P is the number of contained moving points */ ListExpr LinearPointsMove::ToListExpr(const DbArray &Points) const{ __TRACE__ if(!defined) return ::nl->SymbolAtom("undefined"); TwoPoints Entry; unsigned int s = Points.Size(); if(sTwoElemList( ::nl->RealAtom(Entry.startX), ::nl->RealAtom(Entry.startY)); Pe = ::nl->TwoElemList( ::nl->RealAtom(Entry.endX), ::nl->RealAtom(Entry.endY)); starts = ::nl->OneElemList(Ps); ends = ::nl->OneElemList(Pe); LastStart = starts; LastEnd = ends; for(unsigned int i=startIndex+1;iTwoElemList( ::nl->RealAtom(Entry.startX), ::nl->RealAtom(Entry.startY)); Pe = ::nl->TwoElemList( ::nl->RealAtom(Entry.endX), ::nl->RealAtom(Entry.endY)); LastStart = ::nl->Append(LastStart,Ps); LastEnd = ::nl->Append(LastEnd,Pe); } ListExpr res = ::nl->TwoElemList(::nl->SymbolAtom("linear"), ::nl->ThreeElemList( interval.ToListExpr(false), starts,ends)); return res; } /* ~ReadFrom~ This function reads the value of this LinearPointsMove from value. The points are appended to the Points array beginning at the given index. If value don't represent a valid LinearPointsMove, the return value will be false. Nevertheless it may be that the Points array is changed. After calling this function the index value will be points to the elements after the last inserted one. If an error is occured this instance will be undefined. [3] O(P) where P is the number of contained moving points */ bool LinearPointsMove::ReadFrom(const ListExpr value, DbArray &Pts, int &Index){ __TRACE__ // value has to be a list if(::nl->AtomType(value)!=NoAtom){ if(DEBUG_MODE){ cerr << "List for LinearPointsMove is an atom " << endl; } defined = false; return false; } // check the ListLength if(::nl->ListLength(value)!=3){ // (interval starts ends) if(DEBUG_MODE){ cerr << "Wrong listlength for LinearPointsMove; should be 3, is "; cerr << ::nl->ListLength(value) << endl; } defined = false; return false; } // read the Interval if(!interval.ReadFrom(::nl->First(value),false)){ if(DEBUG_MODE){ cerr << "LinearPointsMove::ReadFFrom: error in reding interval" << endl; } defined = false; return false; } ListExpr starts = ::nl->Second(value); ListExpr ends = ::nl->Third(value); int L1 = ::nl->ListLength(starts); if(L1 != ::nl->ListLength(ends)){ if(DEBUG_MODE){ cerr << "Error in LinearPointsMove::ReadFrom" << endl; cerr << "Different lengths for start and end points " << endl; } return false; } if(L1==0){ isStatic = true; startIndex = 0; endIndex = 0; defined = true; bbox.SetEmpty(); return true; } double xs,ys,xe,ye; TwoPoints TP(0,0,0,0); ListExpr Start,End; startIndex = Index; endIndex = Index+L1; while(! ::nl->IsEmpty(starts)){ Start = ::nl->First(starts); End = ::nl->First(ends); if(::nl->AtomType(Start)!=NoAtom || ::nl->AtomType(End)!=NoAtom){ if(DEBUG_MODE){ cerr << "Error in LinearPointsMove::ReadFrom" << endl; cerr << "start or end is not a list" << endl; } defined = false; return false; } if(::nl->ListLength(Start)!=2 || ::nl->ListLength(End)!=2) { if(DEBUG_MODE){ cerr << "Error in LinearPointsMove::ReadFrom" << endl; cerr << "Wrong listlength for Start or for End " << endl; cerr << "Expected 2 for both, received " << ::nl->ListLength(Start); cerr << "(start) and "<<::nl->ListLength(End) << "(end)" << endl; } defined = false; return false; } if(!periodic::GetNumeric(::nl->First(Start),xs) || !periodic::GetNumeric(::nl->Second(Start),ys) || !periodic::GetNumeric(::nl->First(End),xe) || !periodic::GetNumeric(::nl->Second(End),ye)){ if(DEBUG_MODE){ cerr << "Error in LinearPointsMove::ReadFrom" << endl; cerr << "Cannot find numerical value " << endl; } defined = false; return false; } TP = TwoPoints(xs,ys,xe,ye); bbox.Union(xe,ye); bbox.Union(xs,ys); if(xe!=xs || ye!=ys) isStatic=false; Pts.Put(Index,TP); Index++; starts=::nl->Rest(starts); ends=::nl->Rest(ends); } defined = true; return true; } /* ~At~ This function computes the locations of the contained points at the given point of time. If the duration is outside of the relative interval of this LinearPointsMove, NULL is returned. [3] O(P log(P)) where P is the number of contained moving points. The reason is the sorting of the points in the result. I'm not sure whether this time is reached because i don't know the implementation of the sorting of the points. */ void LinearPointsMove::At(const DateTime* duration, const DbArray &Pts, Points& res) const{ __TRACE__ if(!interval.Contains(duration)){ res.SetDefined(false); return; } res.SetDefined(true); double w = interval.Where(duration); res.Resize(Pts.Size()); TwoPoints Element; Point aPoint; double x,y; res.StartBulkLoad(); for(unsigned int i=startIndex;i &MyPoints, DbArray &PointsOfP2) const{ __TRACE__ if(!interval.CanAppended(&(P2->interval))) return false; // First we check for defined if(!defined && !P2->defined) return true; if(defined != P2->defined) return false; // now both LinearPointsMove are defined // check for the same number of contained points if( (endIndex-startIndex) != (P2->endIndex-P2->startIndex)) return false; // now we have to check wether each endpoint of this LinearPointsMove // has a matching start point in P2. // To do this, we insert all endpoints of this into an array and // all start points of P2 to another one. After sorting both arrays // we have to check the equality of this ones. int size = endIndex-startIndex; SimplePoint endPoints[size]; SimplePoint startPoints[size]; TwoPoints CurrentPoint; for(unsigned int i=startIndex;istartIndex;iendIndex;i++){ PointsOfP2.Get(i,CurrentPoint); startPoints[i-P2->startIndex].x=CurrentPoint.startX; startPoints[i-P2->startIndex].y=CurrentPoint.startY; startPoints[i-P2->startIndex].intinfo=i; startPoints[i-P2->startIndex].boolinfo=false; } heapsort(size,endPoints); heapsort(size,startPoints); for(int i=0;iinterval)){ //mathc found startPoints[cpos].boolinfo=true; // mark as used found = true; } }else{ cpos++; // try the next } } } if(!found) return false; if(!morethanone) pos++; } return true; } /* ~ExtendsWith~ This function summarized two LinearPointsMove together to a single one if possible. The return values indicates the success of this function. The result shows whether the LinearPointsMoves can be put together. If the result is __false__, this LinearPointsMove is not changed. */ bool LinearPointsMove::ExtendWith(const LinearPointsMove* P2, DbArray &MyPoints, DbArray &PointsOfP2){ __TRACE__ if(!CanBeExtendedBy(P2,MyPoints,PointsOfP2)) return false; interval.Append(&(P2->interval)); bbox.Union(&(P2->bbox)); // this is very closed to the CanBeExtededFunction but here we need no // checks because we know that this units can be putted together. cout << __POS__ << endl; cout << "ExtendWith(...) notimplemented " << endl; return false; } /* ~Equalize~ This functions makes this equal to the argument. [3] O(1) */ void LinearPointsMove::Equalize(const LinearPointsMove* P2){ __TRACE__ interval.Equalize(&(P2->interval)); bbox.Equalize(&(P2->bbox)); startIndex=P2->startIndex; endIndex=P2->endIndex; isStatic = P2->isStatic; defined = P2->defined; } /* ~Shift Operator~ */ ostream& operator<< (ostream& os, const LinearPointsMove LM){ __TRACE__ os << "LPsM[" ; os << LM.startIndex << "," << LM.endIndex << "]"; // add also bbox, interval isstatic and so on if required ! return os; } } // end of namespace