e5193ecc50ee65d597d0753446f5c6ac4b2b64c1
[ptas] / zouba / src / logic / location.cpp
1 #include "location.h"
2
3 #include "ytv.h"
4
5 #include <QString>
6 #include <QObject>
7 #include <QNetworkAccessManager>
8 #include <QUrl>
9 #include <QNetworkRequest>
10 #include <QNetworkReply>
11 #include <QXmlStreamReader>
12 #include <QDebug>
13 #include <QXmlStreamAttributes>
14 #include <QStringRef>
15 #include <QGeoPositionInfo>
16
17 #include <math.h>
18
19 const double KkjZoneInfo[6][2] = {
20     {18.0,  500000.0},
21     {21.0, 1500000.0},
22     {24.0, 2500000.0},
23     {27.0, 3500000.0},
24     {30.0, 4500000.0},
25     {33.0, 5500000.0}
26 };
27
28 #ifdef Q_WS_MAEMO_5
29 QTM_USE_NAMESPACE
30 #endif
31
32         Location::Location( const QString &x, const QString &y, const QString &label ) :
33         m_label(label),
34         m_address(QString()),
35         m_x(x),
36         m_y(y),
37         m_valid(true)
38 {
39 }
40 #ifdef Q_WS_MAEMO_5
41 Location::Location(const QGeoPositionInfo &positionInfo, const QString &label) :
42         m_label(label),
43         m_address(QString()),
44         m_x("0"),
45         m_y("0"),
46         m_valid(false)
47 {
48     setLocation(positionInfo);
49 }
50
51 void Location::setLocation(const QGeoPositionInfo &positionInfo)
52 {
53     qDebug() << "Setting new location based on GeoPositionInfo";
54     qreal latitude = positionInfo.coordinate().latitude();
55     qreal longitude = positionInfo.coordinate().longitude();
56
57     //qDebug() << "Calculating new values";
58
59     KKJ outX(0);
60     KKJ outY(0);
61
62     WGS84lola_to_KKJxy( longitude, latitude, &outX, &outY);
63
64     /*qDebug() << "Storing new values";
65     qDebug() << "x";
66     qDebug() << outX;
67     qDebug() << "y";
68     qDebug() << outY;*/
69
70     //qDebug() << "Setting x";
71     //this->m_x = QString("%1").arg(outX);
72     this->m_x.setNum(outX);
73     //qDebug() << "Setting y";
74     //this->m_y = QString("%1").arg(outY);
75     this->m_y.setNum(outY);
76     //qDebug() << "Setting as valid";
77     this->m_valid = true;
78     //emit(becomeValid());
79     //qDebug() << "Location set";
80 }
81 #endif
82
83 void Location::setPosition(const QString &x, const QString &y)
84 {
85     this->m_x = x;
86     this->m_y = y;
87     this->m_valid = true;
88 }
89
90 Location::Location(const QString &label) :
91         m_label(label),
92         m_address(QString()),
93         m_x("0"),
94         m_y("0"),
95         m_valid(false)
96 {
97 }
98
99 Location::Location(const Location &other) :
100     m_label(other.m_label),
101     m_address(other.m_address),
102     m_x(other.m_x),
103     m_y(other.m_y),
104     m_valid(other.m_valid)
105 {
106 }
107
108 /*Location* Location::copy_Location(const Location *other)
109 {
110     Location *ret = new Location(other->m_x, other->m_y, other->m_label);
111     ret->m_address = other->m_address;
112     ret->m_valid = other->m_valid;
113     return ret;
114 }*/
115
116
117 QString Location::x() const
118 {
119     return m_x;
120 }
121
122 QString Location::y() const
123 {
124     return m_y;
125 }
126
127 void Location::setLabel(const QString &label)
128 {
129     m_label = label;
130 }
131
132 QString Location::label() const
133 {
134     return m_label;
135 }
136
137 void Location::setAddress(const QString &address)
138 {
139     m_address = address;
140 }
141
142 QString Location::address() const
143 {
144     return m_address;
145 }
146
147 bool Location::isValid() const
148 {
149     return m_valid;
150 }
151
152 // Degrees to radians
153 double radians(double deg)
154 {
155     return deg * M_PI / 180.0;
156 }
157
158 // Radians to degrees
159 double degrees(double rad)
160 {
161     return rad * 180.0 / M_PI;
162 }
163
164 // Function:  KKJ_Zone_I
165 int KKJ_Zone_I(KKJ easting)
166 {
167     int zoneNumber = floor(easting / 1000000.0);
168     if (zoneNumber < 0 || zoneNumber > 5) {
169         zoneNumber = -1;
170     }
171
172     return zoneNumber;
173 }
174
175 // Function:  KKJ_Zone_Lo
176 int KKJ_Zone_Lo(double kkjlo)
177 {
178     // determine the zonenumber from KKJ easting
179     // takes KKJ zone which has center meridian
180     // longitude nearest (in math value) to
181     // the given KKJ longitude
182     int zoneNumber = 5;
183     while (zoneNumber >= 0) {
184         if (fabs(kkjlo - KkjZoneInfo[zoneNumber][0]) <= 1.5) {
185             break;
186         }
187         zoneNumber--;
188     }
189
190     return zoneNumber;
191 }
192
193
194 // Function:  KKJlalo_to_WGS84lalo
195 void KKJlola_to_WGS84lola(double kkjlo, double kkjla, double *outLongitude, double *outLatitude)
196 {
197     double dLa = radians(0.124867E+01 + -0.269982E+00 * kkjla + 0.191330E+00 * kkjlo + 0.356119E-02 * kkjla * kkjla + -0.122312E-02 * kkjla * kkjlo + -0.335514E-03 * kkjlo * kkjlo) / 3600.0;
198     double dLo = radians(-0.286111E+02 + 0.114183E+01 * kkjla + -0.581428E+00 * kkjlo + -0.152421E-01 * kkjla * kkjla + 0.118177E-01 * kkjla * kkjlo + 0.826646E-03 * kkjlo * kkjlo) / 3600.0;
199
200     *outLatitude = degrees(radians(kkjla) + dLa);
201     *outLongitude = degrees(radians(kkjlo) + dLo);
202 }
203
204
205 // Function:  WGS84lalo_to_KKJlalo
206 void WGS84lola_to_KKJlola(double longitude, double latitude, double *outLongitude, double *outLatitude)
207 {
208     double dLa = radians(-0.124766E+01 + 0.269941E+00 * latitude + -0.191342E+00 * longitude + -0.356086E-02 * latitude * latitude + 0.122353E-02 * latitude * longitude + 0.335456E-03 * longitude * longitude) / 3600.0;
209     double dLo = radians(0.286008E+02 + -0.114139E+01 * latitude + 0.581329E+00 * longitude + 0.152376E-01 * latitude * latitude + -0.118166E-01 * latitude * longitude + -0.826201E-03 * longitude * longitude) / 3600.0;
210
211     *outLatitude = degrees(radians(latitude) + dLa);
212     *outLongitude = degrees(radians(longitude) + dLo);
213 }
214
215
216 // Function:  KKJlalo_to_KKJxy
217 void KKJlola_to_KKJxy(double lon, double lat, int zoneNumber, KKJ *outX, KKJ *outY)
218 {
219     // Hayford ellipsoid
220     double a = 6378388.0;
221     double f  = 1.0 / 297.0;
222     double b  = (1.0 - f) * a;
223     double bb = b * b;
224     double c  = (a / b) * a;
225     double ee = (a * a - bb) / bb;
226     double n = (a - b) / (a + b);
227     double nn = n * n;
228
229     double Lo = radians(lon) - radians(KkjZoneInfo[zoneNumber][0]);
230     double cosLa = cos(radians(lat));
231     double NN = ee * cosLa * cosLa;
232     double LaF = atan(tan(radians(lat)) / cos(Lo * sqrt(1.0 + NN)));
233     double cosLaF = cos(LaF);
234     double t = (tan(Lo) * cosLaF) / sqrt(1.0 + ee * cosLaF * cosLaF);
235     double A = a / (1.0 + n);
236     double A1 = A * (1.0 + nn / 4.0 + nn * nn / 64.0);
237     double A2 = A * 1.5 * n * (1.0 - nn / 8.0);
238     double A3 = A * 0.9375 * nn * (1.0 - nn / 4.0);
239     double A4 = A * 35.0 / 48.0 * nn * n;
240
241     *outY = A1 * LaF - A2 * sin(2.0 * LaF) + A3 * sin(4.0 * LaF) - A4 * sin(6.0 * LaF);
242     *outX = c * log(t + sqrt(1.0 + t * t)) + 500000.0 + zoneNumber * 1000000.0;
243 }
244
245 // Function:  KKJxy_to_KKJlalo
246 void KKJxy_to_KKJlola(KKJ x, KKJ y, double *outLongitude, double *outLatitude)
247 {
248     // Scan iteratively the target area, until find matching
249     // KKJ coordinate value.  Area is defined with Hayford Ellipsoid.
250     int zoneNumber = KKJ_Zone_I(x);
251     double minLo = radians(18.5);
252     double maxLo = radians(32.0);
253     double minLa = radians(59.0);
254     double maxLa = radians(70.5);
255
256     int i = 1;
257     KKJ tmpX, tmpY;
258
259     while (i < 35) {
260         double deltaLo = maxLo - minLo;
261         double deltaLa = maxLa - minLa;
262         *outLongitude = degrees(minLo + 0.5 * deltaLo);
263         *outLatitude = degrees(minLa + 0.5 * deltaLa);
264         KKJlola_to_KKJxy(*outLongitude, *outLatitude, zoneNumber, &tmpX, &tmpY);
265         if (tmpY < y) {
266             minLa = minLa + 0.45 * deltaLa;
267         } else {
268             maxLa = minLa + 0.55 * deltaLa;
269         }
270
271         if (tmpX < x) {
272             minLo = minLo + 0.45 * deltaLo;
273         } else {
274             maxLo = minLo + 0.55 * deltaLo;
275         }
276
277         i++;
278     }
279 }
280
281 void WGS84lola_to_KKJxy(double longitude, double latitude, KKJ *outX, KKJ *outY)
282 {
283     double kkjlo, kkjla;
284
285     WGS84lola_to_KKJlola(longitude, latitude, &kkjlo, &kkjla);
286     int zoneNumber = KKJ_Zone_Lo(kkjlo);
287     KKJlola_to_KKJxy(kkjlo, kkjla, zoneNumber, outX, outY);
288 }
289
290 void KKJxy_to_WGS84lola(KKJ x, KKJ y, double *outLongitude, double *outLatitude)
291 {
292     double kkjlo, kkjla;
293
294     KKJxy_to_KKJlola(x, y, &kkjlo, &kkjla);
295     KKJlola_to_WGS84lola(kkjlo, kkjla, outLongitude, outLatitude);
296
297 }