1 #ifndef MERKATOR_COORD_H_
2 #define MERKATOR_COORD_H_
3 
4 #include <math.h>
5 #ifndef M_PI
6 #define M_PI        3.14159265358979323846
7 #endif
8 #include <QRectF>
9 #include <QtDebug>
10 #include <QtXml>
11 
12 #define COORD_MAX (qreal)180.0
13 #define COORD_ENLARGE (qreal)0.00015
14 
15 #define COORD2STRING(c) QString::number(c, 'f', 7)
Coord2Sexa(qreal c)16 inline QString Coord2Sexa(qreal c)
17 {
18     int deg = int(c);
19     qreal min = fabs((c - deg)*60);
20     qreal sec = (min - int(min)) *60;
21 
22     return QString::fromUtf8("%1° %2' %3\"").arg(deg).arg(int(min)).arg(sec, 0, 'f', 2);
23 }
24 
25 
angToRad(qreal a)26 inline qreal angToRad(qreal a)
27 {
28     return a*M_PI/180.;
29 }
30 
radToAng(qreal a)31 inline qreal radToAng(qreal a)
32 {
33     return a*180/M_PI;
34 }
35 
36 class Coord : public QPointF
37 {
38     public:
Coord()39         Coord()
40             : QPointF() {}
Coord(const Coord & c)41         Coord(const Coord& c)
42             : QPointF(c.x(), c.y()) {}
Coord(const QPoint & P)43         Coord(const QPoint& P)
44             : QPointF(P.x(), P.y()) {}
Coord(const QPointF & P)45         Coord(const QPointF& P)
46             : QPointF(P.x(), P.y()) {}
Coord(qreal aLon,qreal aLat)47         Coord(qreal aLon, qreal aLat)
48             : QPointF(aLon, aLat) {}
49 
length()50         qreal length() const
51         {
52             return sqrt((y()*y()+x()*x()));
53         }
54 
55         qreal distanceFrom(const Coord& other) const;
56 
57         bool toXML(QString elName, QXmlStreamWriter& stream) const;
58         bool toXML(QString elName, QDomElement& xParent) const;
59         static Coord fromXML(QDomElement e);
60         static Coord fromXML(QXmlStreamReader& stream);
61 
62 
63         Coord& operator=(const Coord&) = default;
64 };
65 
66 uint qHash(const Coord &c);
67 
68 
69 inline Coord operator-(const Coord& A, const Coord& B)
70 {
71     return Coord(A.x()-B.x(), A.y()-B.y());
72 }
73 
74 inline Coord operator-(const Coord& A, const qreal B)
75 {
76     return Coord(A.x()-B, A.y()-B);
77 }
78 
79 inline Coord operator+(const Coord& A, const Coord& B)
80 {
81     return Coord(A.x()+B.x(), A.y()+B.y());
82 }
83 
84 inline Coord operator+(const Coord& A, const qreal B)
85 {
86     return Coord(A.x()+B, A.y()+B);
87 }
88 
89 inline Coord operator*(const Coord& A, qreal d)
90 {
91     return Coord(A.x()*d, A.y()*d);
92 }
93 
94 inline Coord operator/(const Coord& A, qreal d)
95 {
96     if(d==0)
97     {
98         qDebug()<<"Error: divide by 0"<<endl;
99         return A;
100     }
101     return Coord(A.x()/d, A.y()/d);
102 }
103 
104 inline bool operator==(const Coord& A,const Coord& B)
105 {
106     return A.y()==B.y() && A.x()==B.x();
107 }
108 
109 qreal angle(Coord p1);
110 void rotate(Coord & p1,qreal angle);
111 
112 class CoordBox : public QRectF
113 {
114     public:
CoordBox()115         CoordBox()
116             : QRectF() {}
CoordBox(const CoordBox & cb)117         CoordBox(const CoordBox& cb)
118             : QRectF(cb) {}
CoordBox(const QRectF & r)119         CoordBox(const QRectF& r)
120             : QRectF(r) {}
121         CoordBox(const Coord& C1, const Coord& C2);
122 
isNull()123         bool isNull() const
124         {
125             return (bottomLeft().isNull() && topRight().isNull());
126         }
isEmpty()127         bool isEmpty() const
128         {
129             return (lonDiff() == 0 || latDiff() == 0);
130         }
131 
merge(const Coord & C)132         void merge(const Coord& C)
133         {
134             if (C.y() < bottom())
135                 setBottom(C.y());
136             if (C.x() < left())
137                 setLeft(C.x());
138             if (C.y() > top())
139                 setTop(C.y());
140             if (C.x() > right())
141                 setRight(C.x());
142         }
143 
merge(const CoordBox & B)144         void merge(const CoordBox& B)
145         {
146             merge(B.bottomLeft());
147             merge(B.topRight());
148         }
149 
center()150         Coord center() const
151         {
152             return Coord(QRectF::center());
153         }
154 
lonDiff()155         qreal lonDiff() const
156         {
157             return width();
158         }
latDiff()159         qreal latDiff() const
160         {
161             return -height();
162         }
163         CoordBox zoomed(qreal f) const;
164 
contains(const Coord & C)165         bool contains(const Coord& C) const
166         {
167             return (bottomLeft().y() <= C.y()) && (bottomLeft().x() <= C.x()) &&
168                 (C.y() < topRight().y()) && (C.x() <= topRight().x());
169         }
170 
contains(const CoordBox & B)171         bool contains(const CoordBox& B) const
172         {
173             return contains(B.bottomLeft()) && contains(B.topRight());
174         }
175 
intersects(const CoordBox & B)176         bool intersects(const CoordBox& B) const
177         {
178             if ((B.latDiff() == 0) && (B.lonDiff() == 0)) {
179                 return contains(B.bottomLeft());
180             }
181             return QRectF::intersects(B);
182         }
183 
disjunctFrom(const CoordBox & B)184         bool disjunctFrom(const CoordBox& B) const
185         {
186             return !intersects(B);
187         }
188 
189         void resize(qreal f);
190 
191         static bool visibleLine(const CoordBox & viewport, Coord & last, Coord & here);
192 
193         bool toXML(QString elName, QXmlStreamWriter& stream) const;
194         bool toXML(QString elName, QDomElement& xParent) const;
195         static CoordBox fromXML(QDomElement e);
196         static CoordBox fromXML(QXmlStreamReader& stream);
197 
198         CoordBox& operator=(const CoordBox&) = default;
199 };
200 
201 Q_DECLARE_METATYPE( CoordBox );
202 
203 #ifndef _MOBILE
204 #if QT_VERSION < 0x040700 || defined(FORCE_46)
205 #include <ggl/geometries/register/box.hpp>
206 
207 GEOMETRY_REGISTER_BOX(CoordBox, Coord, bottomLeft, topRight)
208 #endif
209 #endif
210 
211 #endif
212 
213 
214