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