/* ---- This file is part of SECONDO. Copyright (C) 2017, University in Hagen, Faculty of Mathematics and 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 ---- //[_] [\_] */ #ifndef SIMPLELINET_H #define SIMPLELINET_H #include "PointsT.h" #include "LRS.h" #include "HalfSegment.h" /* 7 The class ~SimpleLineT~ This class represents a line building a simple polyline, i.e. a line without branches and zero or one components. */ templateclass Array> class SimpleLineT: public StandardSpatialAttribute<2> { public: /* 7.1 Constructors ~Constructor~ This constructor creates an undefined SimpleLineT object and initializes the contained arrays to have ~size~ number od slots. */ explicit SimpleLineT(int size): StandardSpatialAttribute<2>(false), segments(size),lrsArray(size/2), startSmaller(true), isCycle(false),isOrdered(true),length(0.0), bbox(false,0),currentHS(-1){ } /* ~Constructor~ Constructs a ~SimpleLineT~ from a complex one. */ template class Array2> explicit SimpleLineT(const LineT& src); /* ~CopyConstructor~ */ SimpleLineT(const SimpleLineT& src): StandardSpatialAttribute<2>(src.IsDefined()), segments(src.Size()+1),lrsArray(src.Size()/2 + 2), startSmaller(src.GetStartSmaller()), isCycle(src.IsCycle()), isOrdered(src.IsOrdered()), length(src.Length()), bbox(src.BoundingBox()), currentHS(src.currentHS) { segments.copyFrom(src.segments); lrsArray.copyFrom(src.lrsArray); lrsArray.TrimToSize(); segments.TrimToSize(); //Equalize(src); } template class Array2> SimpleLineT(const SimpleLineT& src): StandardSpatialAttribute<2>(src.IsDefined()), segments(src.Size()+1),lrsArray(src.Size()/2 + 2), startSmaller(src.GetStartSmaller()), isCycle(src.IsCycle()), isOrdered(src.IsOrdered()), length(src.Length()), bbox(src.BoundingBox()), currentHS(src.currentHS) { convertDbArrays(src.segments, segments); convertDbArrays(src.lrsArray, lrsArray); lrsArray.TrimToSize(); segments.TrimToSize(); } /* ~Destructor~ */ ~SimpleLineT() {} /* ~Assignment Operator~ */ SimpleLineT& operator=(const SimpleLineT& src){ Equalize(src); return *this; } template class Array2> SimpleLineT& operator=(const SimpleLineT& src){ Equalize(src); return *this; } /* ~Destroy~ */ void Destroy(){ segments.Destroy(); lrsArray.Destroy(); } /* ~BulkLoading~ */ void StartBulkLoad(); bool EndBulkLoad(); SimpleLineT& operator+=( const HalfSegment& hs); void Add(const HalfSegment& hs); inline bool IsOrdered() const{ return isOrdered; } /* ~Length~ Returns the length of this SimpleLineT (computed using metric (X,Y)-coordinates); */ inline double Length() const{ return length; } /* Returns the simple line's length computed for geographic (LON,LAT)-coordinates and a Geoid. If any coordinate is invalid, ~valid~ is set to false (true otherwise). */ double Length(const Geoid& g, bool& valid) const; inline double SpatialSize() const{ return Length(); } inline double SpatialSize(const Geoid& g, bool& valid) const{ return Length(g, valid); } /* Splits the simple line at the given pts into sublines. The set of sublines is returned in the result vector */ std::vector >* SplitAtPPoints(PointsT* pts); /* ~BoundingBox~ Returns the MBR of this SimpleLineT object. */ inline const Rectangle<2> BoundingBox(const Geoid* geoid = 0) const{ if(geoid){ // spherical geometry case: if(!geoid->IsDefined() || !IsDefined()){ return Rectangle<2>(false); } Rectangle<2> geobbox = Rectangle<2>(false); for (int i=0; i class Array2> bool Inside( const SimpleLineT& l, const Geoid* geoid=0 ) const; /* 6.4.4 Operation ~intersection~ */ template class Array2> void Intersection(const Point& p, PointsT& result, const Geoid* geoid=0) const; template class Array2, template class Array3> void Intersection(const PointsT& ps, PointsT& result, const Geoid* geoid=0) const; template class Array2, template class Array3> void Intersection( const LineT& l, SimpleLineT& result, const Geoid* geoid=0 ) const; template class Array2, template class Array3> void Intersection( const RegionT& l, SimpleLineT& result, const Geoid* geoid=0 ) const; template class Array2, template class Array3> void Intersection( const SimpleLineT& l, SimpleLineT& result, const Geoid* geoid = 0) const; /* 6.4.4 Operation ~minus~ */ template class Array2> void Minus( const Point& l, SimpleLineT& result, const Geoid* geoid=0 ) const; template class Array2, template class Array3> void Minus( const PointsT& l, SimpleLineT& result, const Geoid* geoid=0 ) const; template class Array2, template class Array3> void Minus( const LineT& l, SimpleLineT& result, const Geoid* geoid=0 ) const; template class Array2, template class Array3> void Minus( const RegionT& l, SimpleLineT& result, const Geoid* geoid=0 ) const; template class Array2, template class Array3> void Minus( const SimpleLineT& l, SimpleLineT& result, const Geoid* geoid=0 ) const; /* 6.4.4 Operation ~union~ */ template class Array2> void Union( const Point& l, SimpleLineT& result, const Geoid* geoid=0 ) const; template class Array2, template class Array3> void Union( const PointsT& l, SimpleLineT& result, const Geoid* geoid=0 ) const; template class Array2, template class Array3> void Union( const LineT& l, LineT& result, const Geoid* geoid=0 ) const; template class Array2, template class Array3> void Union( const RegionT& l, RegionT& result, const Geoid* geoid=0 ) const; template class Array2, template class Array3> void Union( const SimpleLineT& l, LineT& result, const Geoid* geoid=0 ) const; /* ~TrimToSize~ Changes the capacities of the contained arrays to the required size. */ inline void TrimToSize(){ segments.TrimToSize(); lrsArray.TrimToSize(); } /* ~StartsSmaller~ Returns true if SimpleLineT start at smaller end point. */ inline bool StartsSmaller() const{ return startSmaller; } /* ~Comparison~ The operator __==__ checks whether the structures of two simple lines are equal. This operator may return a __false__ result even if the lines have the same geometry. */ bool operator==(const SimpleLineT& sl) const{ if(!IsDefined() && !sl.IsDefined()){ return true; } if(!IsDefined() || !sl.IsDefined()){ return false; } if(bbox != sl.bbox){ return false; } if(segments.Size() != sl.segments.Size()){ return false; } if(startSmaller!=sl.startSmaller){ return false; } if(!AlmostEqual(length,sl.length)){ return false; } HalfSegment hs1; HalfSegment hs2; for(int i=0;i& sl) const{ return !(*this == sl); } /* ~Distance Operators~ */ double Distance(const Point& p, const Geoid* geoid=0 )const; template class Array2> double Distance(const PointsT& ps, const Geoid* geoid=0 ) const; template class Array2> double Distance(const SimpleLineT& sl, const Geoid* geoid=0) const; double Distance(const Rectangle<2>& r, const Geoid* geoid=0) const; bool Intersects(const Rectangle<2>& r, const Geoid* geoid=0) const; /* ~SetStartSmaller~ */ void SetStartSmaller(const bool smaller) { startSmaller = smaller; } /* ~GetStartSmaller~ */ bool GetStartSmaller() const { return IsDefined() && startSmaller; } /* ~AtPosition~ */ bool AtPosition(double pos, const bool startsSmaller, Point& p, const Geoid* geoid=0) const; bool AtPosition(double pos, Point& p, const Geoid* geoid = 0) const; /* ~AtPoint~ */ bool AtPoint(const Point& p, const bool startsSmaller, double& result, const Geoid* geoid= 0) const; bool AtPoint(const Point& p, const bool startsSmaller, const double tolerance, double& result, const Geoid* geoid=0) const; bool AtPoint(const Point& p, double& result, const double tolerance = 0.0, const Geoid* geoid=0) const; /* ~SubLine~ */ template< template class Array1> void SubLine(double pos1, double pos2, bool startsSmaller, SimpleLineT& l) const; template< template class Array1> void SubLine(double pos1, double pos2, SimpleLineT& l) const; /* ~Crossings~ */ template class Array2, template class Array3> void Crossings(const SimpleLineT& l, PointsT& result, const Geoid* geoid=0) const; /* ~Union~ */ template class Array2> bool Intersects(const SimpleLineT& l, const Geoid* geoid=0) const; /* ~Attribute Functions~ The following functions are needed to act as an attribute type. */ inline int NumOfFLOBs() const{ return 2; } inline Flob* GetFLOB(const int i){ if(i==0) return &segments; return &lrsArray; } inline size_t Sizeof() const{ return sizeof(*this); } inline bool Adjacent(const Attribute* arg) const{ return false; } size_t HashValue() const{ return bbox.HashValue() + segments.Size(); } void CopyFrom(const Attribute* right){ Equalize(*(static_cast*>(right))); } int Compare(const Attribute* arg) const; template< template class Array1> int Compare( const SimpleLineT* line) const; bool operator<(SimpleLineT *sl) const{ return (Compare(sl) < 0); } virtual SimpleLineT* Clone() const{ return new SimpleLineT(*this); } std::ostream& Print(std::ostream& os) const; void Clear(){ segments.clean(); lrsArray.clean(); SetDefined( true ); bbox.SetDefined(false); length=0.0; isOrdered=true; currentHS = -1; } bool SelectInitialSegment( const Point& startPoint, const double tolerance = 1.0, const Geoid* geoid=0); bool SelectSubsequentSegment(); bool getWaypoint(Point& destination) const; bool IsCycle()const { return isCycle; } template class Array2> void toLine(LineT& result) const; template class Array2> void fromLine(const LineT& src); template class Array2> void fromLine(const LineT& src, const bool smaller); static void* Cast(void* addr){ return new (addr) SimpleLineT(); } inline void Get( const int i, HalfSegment& hs ) const{ segments.Get(i,&hs); } inline int lrsSize()const{ return lrsArray.Size(); } bool Get(LRS &lrs, int &i){ return Find(lrs, i); } inline void Put(const int i, const HalfSegment& hs){ segments.Put(i,hs); } inline void Get( const int i, LRS& lrs ) const{ lrsArray.Get(i,&lrs); } inline void Put(const int i, const LRS& lrs){ lrsArray.Put(i,lrs); } inline void Resize(const int newSize){ if(newSize>segments.Size()){ segments.resize(newSize); } } static const std::string BasicType(){ return "sline"; } static const bool checkType(const ListExpr type){ return listutils::isSymbol(type, BasicType()); } bool Find( const LRS& lrs, int& pos ) const { assert( IsOrdered() ); if( IsEmpty() ){ // subsumes !IsDefined() return false; } if( (lrs.lrsPos < 0 && !AlmostEqual( lrs.lrsPos, 0 )) || (lrs.lrsPos > Length() && !AlmostEqual( lrs.lrsPos, Length() ) )){ return false; } lrsArray.Find( &lrs, LRSCompare, pos ); if( pos > 0 ){ pos--; } return true; } void printLRS(std::ostream& o) const{ LRS lrs; for(int i=0;i