Ilwis-Objects  1.0
GIS and Remote Sensing framework for data access and processing
All Classes Functions Enumerations Pages
location.h
1 #ifndef Point_H
2 #define Point_H
3 
4 #include <QSize>
5 #include "angle.h"
6 
7 namespace Ilwis {
8 
13 template<class CrdType=qint32, bool useDouble = false> class Location{
14 public:
18  Location() : x(undefined()), y(undefined()), z(undefined()){
19  }
25  Location(CrdType d1, CrdType d2, CrdType d3=Location::undefined()) : x(d1), y(d2), z(d3){
26  }
27 
28  template<typename U> Location(const Location<U>& p) {
29  if ( p.isValid()) {
30  this->x =(CrdType)p.x;
31  this->y =(CrdType)p.y;
32  this->z =(CrdType)p.z;
33  } else{
34  this->x =undefined();
35  this->y =undefined();
36  this->z = undefined();
37 
38  }
39  }
40 
41  Location(const Location<CrdType>& p) {
42  if ( p.isValid()) {
43  this->x =p.x;
44  this->y =p.y;
45  this->z =p.z;
46  } else{
47  this->x =undefined();
48  this->y =undefined();
49  this->z = undefined();
50 
51  }
52  }
53 
54  Location(Location<CrdType>&& crd) : x(crd.x), y(crd.y), z(crd.z){
55  crd.x = crd.y = this->undefined();
56  }
57 
58 
59  Location(const std::vector<CrdType>& v) : Location() {
60  if ( v.size() < 2) {
61  *this = Location<CrdType>();
62  return;
63  }
64  this->x =v[0];
65  this->y =v[1];
66  if ( v.size() >= 3)
67  this->z = v[2];
68  }
69 
70  virtual ~Location() {
71  }
72 
77  bool isValid() const{
78  return x != undefined() && y != undefined() ;
79  }
80 
81  bool is0() const{
82  return x == 0 && y == 0 ;
83  }
84 
85  bool is3D() const {
86  return isValid() && (z != undefined());
87  }
88 
89  operator std::vector<CrdType> () {
90  std::vector<CrdType> v {this->x, this->y, this->z};
91  return v;
92  }
93 
95  this->x = p2.x;
96  this->y = p2.y;
97  this->z = p2.z;
98  return *this;
99  }
100 
101  Ilwis::Location<CrdType>& operator=(const Ilwis::Location<CrdType>&& p2) {
102  this->x = p2.x;
103  this->y = p2.y;
104  this->z = p2.z;
105  return *this;
106  }
107 
108 
109 
115  Location<CrdType>& operator+= (const std::vector<CrdType>& vec){
116  if (!this->isValid() || vec.size() < 2)
117  return *this;
118 
119  this->x =this->x + vec[0];
120  this->y =this->y + vec[1];
121  if ( vec.size() >= 3 && z != undefined())
122  this->z =this->z + vec[2];
123 
124  return *this;
125  }
126 
127  Location<CrdType>& operator-= (const std::vector<CrdType>& vec){
128  if (!this->isValid() || vec.size() < 22)
129  return *this;
130  this->x =this->x - vec[0];
131  this->y =this->y - vec[1];
132  if ( vec.size() >= 3 && z != undefined())
133  this->z =this->z - vec[2];
134 
135  return *this;
136  }
137 
138  double distance(const Location<CrdType>& crd) {
139  if ( !crd.isValid() || !this->isValid())
140  return rUNDEF;
141  if ( z == undefined() || crd.z == undefined())
142  return std::sqrt(std::pow(abs(this->x - crd.x),2) + std::pow(abs(this->y - crd.y),2));
143  return std::sqrt(std::pow(abs(this->x - crd.x),2) + std::pow(abs(this->y - crd.y),2) + std::pow(abs(this->z - crd.z),2));
144  }
145 
151  Location<CrdType>& operator*=(const std::vector<CrdType>& vec){
152  if (!this->isValid() || vec.size() < 2)
153  return *this;
154  this->x =this->x * vec[0];
155  this->y =this->y * vec[1];
156  if ( vec.size() >= 3 && z != undefined())
157  this->z =this->z * vec[2];
158 
159  return *this;
160  }
161 
168  if (!this->isValid())
169  return *this;
170  this->x =this->x * v;
171  this->y =this->y * v;
172  if ( z != undefined())
173  this->z =this->z * v;
174 
175  return *this;
176  }
177 
185  if (!this->isValid() || v == 0){
186  *this = Location<CrdType>();
187  return *this;
188  }
189  this->x =this->x / v;
190  this->y =this->y / v;
191  if ( z != undefined())
192  this->z =this->z / v;
193 
194  return *this;
195  }
196 
202  bool operator==(const Location<CrdType>& pnt) const {
203  if (!this->isValid() && !pnt.isValid())
204  return true;
205 
206  if (!this->isValid() || !pnt.isValid())
207  return false;
208 
209  return pnt.x == this->x && pnt.y == this->y && pnt.z == this->z;
210  }
216  bool operator!=(const Location<CrdType>& pnt){
217  return !(operator==(pnt));
218  }
219 
220  static double undefined(){ return useDouble ? rUNDEF : iUNDEF;}
221  static quint64 valuetype(){ return useDouble ? itDOUBLE : itINTEGER;}
222 
223  CrdType x;
224  CrdType y;
225  CrdType z;
226 
227 };
228 
233 //class LatLon : public Ilwis::Location<Degrees>{
234 //public:
235 // LatLon() : Ilwis::Location<Degrees>() {}
236 // LatLon(const Degrees& lat, const Degrees& lon, double h=0) : Ilwis::Location<Degrees>(lon, lat, h) {}
237 
238 // LatLon(const LatLon&& ll) : Location<Degrees>(ll.x, ll.y, ll.z) {
239 // }
240 
241 // LatLon(const LatLon& ll) : Location<Degrees>(ll.x, ll.y, ll.z) {
242 // }
243 
244 // LatLon& operator=(const LatLon& ll) {
245 // this->x = ll.x;
246 // this->y = ll.y;
247 // this->z = ll.z;
248 // return *this;
249 // }
250 
251 // /*!
252 // returns the north-south position as an angle of a point ("y" direction). The value ranges between -90 and 90
253 // * \return angle
254 // */
255 // double lat(Angle::Unit u=Angle::uDEGREES) const {
256 // if ( u == Angle::uRADIANS)
257 // return y.radians();
258 // else
259 // return y.degrees();
260 // }
261 
262 // /*!
263 // returns the east-west position as an angle of a point ("x" direction). The value ranges between -180 and 180
264 // * \return angle
265 // */
266 // double lon(Angle::Unit u=Angle::uDEGREES) const {
267 // if ( u == Angle::uRADIANS)
268 // return x.radians();
269 // else
270 // return x.degrees();
271 // }
272 
273 // /*!
274 // sets the latitude of a LatLon point.
275 // * \param l
276 // */
277 // void setLat(double l) {
278 // y = Degrees(l);
279 // }
280 
281 // void setLon(double l) {
282 // x = Degrees(l);
283 // }
284 
285 
286 //};
287 
288 //#define llUNDEF Ilwis::LatLon(rUNDEF, rUNDEF)
289 
290 
291 
292 template<typename CrdType>
293 std::vector<CrdType> operator-(const Ilwis::Location<CrdType>& p1, const Ilwis::Location<CrdType>& p2) {
294  if (!(p1.isValid() && p2.isValid()))
295  return std::vector<int>();
296  std::vector<CrdType> v(3,0);
297  v[0] = p1.x - p2.x;
298  v[1] = p1.y - p2.y ;
299  if ( p1.z != p1.undefined() && p2.z != p2.undefined())
300  v[2] = p1.z - p2.z ;
301  return v;
302 }
303 
304 template<typename CrdType>
305 Ilwis::Location<CrdType> operator+(const Ilwis::Location<CrdType>& p1, const std::vector<double>& vec) {
306  if (p1.isValid() == false || vec.size() < 2 )
307  return Ilwis::Location<CrdType>();
309  p3.x = p1.x + vec[0];
310  p3.y = p1.y + vec[1] ;
311  if ( vec.size() >= 3 && p1.z != p1.undefined())
312  p3.z = p1.z + vec[2];
313 
314  return p3;
315 }
316 template<typename CrdType>
317 Ilwis::Location<CrdType> operator-(const Ilwis::Location<CrdType>& p1, const std::vector<double>& vec) {
318  if (p1.isValid() == false || vec.size() < 2 )
319  return Ilwis::Location<CrdType>();
321  p3.x = p1.x - vec[0];
322  p3.y = p1.y - vec[1] ;
323 
324  if ( vec.size() >= 3 && p1.z != p1.undefined())
325  p3.z = p1.z - vec[2];
326  return p3;
327 }
328 
329 template<typename CrdType>
330 Ilwis::Location<CrdType> operator*(const Ilwis::Location<CrdType>& p1, double v) {
331  Ilwis::Location<CrdType> p3(p1.x * v, p1.y * v) ;
332  if ( p1.z != p1.undefined())
333  p3.z = p1.z * v;
334  return p3;
335 }
336 
337 template<typename CrdType>
338 Ilwis::Location<CrdType> operator/(const Ilwis::Location<CrdType>& p1, double v) {
339  if (!p1.isValid() || v == 0)
340  return Ilwis::Location<CrdType>();
341  Ilwis::Location<CrdType> p3(p1.x / v, p1.y / v) ;
342  if ( p1.z != p1.undefined())
343  p3.z = p1.z / v;
344  return p3;
345 }
346 
347 typedef Location<int> Pixel;
348 typedef Location<double> Pixeld;
349 
350 } // end Ilwis namespace
351 
352 Q_DECLARE_METATYPE(Ilwis::Pixel)
353 Q_DECLARE_METATYPE(Ilwis::Pixeld)
354 
355 
356 
357 
358 
359 
360 
361 
362 
363 
364 
365 
366 #endif // Point_H