3 #include "location_p.h"
9 #include <QNetworkAccessManager>
11 #include <QNetworkRequest>
12 #include <QNetworkReply>
13 #include <QXmlStreamReader>
15 #include <QXmlStreamAttributes>
17 #include <QGeoPositionInfo>
21 const double Location::KkjZoneInfo[6][2] = {
32 Location::Location( const QString &x, const QString &y, const QString &label ) :
33 q( new LocationPrivate( x, y, label ) ),
34 manager( new QNetworkAccessManager(this) )
36 qDebug() << "Location::Location(" << x << "," << y << "," << label <<")";
38 manager, SIGNAL( finished(QNetworkReply*) ),
39 this, SLOT( replyFinished(QNetworkReply*) )
43 Location::Location( const QGeoPositionInfo &positionInfo, const QString &label ) :
44 q( new LocationPrivate( label ) ),
47 setLocation( positionInfo );
50 void Location::setLocation( const QGeoPositionInfo &positionInfo )
52 qreal latitude = positionInfo.coordinate().latitude();
53 qreal longitude = positionInfo.coordinate().longitude();
58 WGS84lola_to_KKJxy( longitude, latitude, &outX, &outY);
65 Location::Location( const Location &from ) :
67 q( new LocationPrivate( from.label() ) ),
70 qDebug() << "Location::Location( const Location [" << from.label() << "] )";
71 q->setAddress( from.address() );
74 q->setValid( from.isValid() );
75 if ( from.manager != 0 ) {
76 manager = new QNetworkAccessManager(this);
77 connect( manager, SIGNAL( finished(QNetworkReply*) ), this, SLOT( replyFinished(QNetworkReply*) ) );
81 Location::Location( const QString &label ) :
82 q( new LocationPrivate( label ) ),
83 manager( new QNetworkAccessManager(this) )
85 qDebug() << "Location::Location( const QString &label=" << label << " )";
86 connect( manager, SIGNAL( finished(QNetworkReply*) ), this, SLOT( replyFinished(QNetworkReply*) ) );
97 Location &Location::operator=( const Location &from )
99 qDebug() << "Location::Location( const Location &from )";
100 q = new LocationPrivate( from.label() );
101 q->setAddress( from.address() );
104 q->setValid( from.isValid() );
106 if ( from.manager != 0 ) {
107 manager = new QNetworkAccessManager(this);
108 connect( manager, SIGNAL( finished(QNetworkReply*) ), this, SLOT( replyFinished(QNetworkReply*) ) );
116 void Location::resolveAddress( const QString &address )
118 qDebug() << "resolving address";
121 q->setAddress( address );
122 q->setValid( false );
124 QUrl fullUrl( Ytv::Url );
126 fullUrl.addEncodedQueryItem( "key", address.toAscii().toPercentEncoding() );
127 fullUrl.addQueryItem( "user", Ytv::Username );
128 fullUrl.addQueryItem( "pass", Ytv::Password );
130 manager->get( QNetworkRequest( fullUrl ) );
131 qDebug() << "waiting for reply from Ytv";
134 void Location::replyFinished( QNetworkReply * reply )
136 qDebug() << "address resolved";
137 q->parseReply( reply->readAll() );
140 qDebug() << label() << "becomeValid";
141 emit( becomeValid() );
145 QString Location::x() const
150 QString Location::y() const
155 void Location::setLabel( const QString &label ) const
157 q->setLabel( label );
160 QString Location::label() const
165 void Location::setAddress( const QString &address ) const
167 qDebug() << "setting address to" << address;
168 q->setAddress( address );
171 QString Location::address() const
176 bool Location::isValid() const
181 // Degrees to radians
182 double Location::radians(double deg)
184 return deg * M_PI / 180.0;
187 // Radians to degrees
188 double Location::degrees(double rad)
190 return rad * 180.0 / M_PI;
193 // Function: KKJ_Zone_I
194 int Location::KKJ_Zone_I(KKJ easting)
196 int zoneNumber = floor(easting / 1000000.0);
197 if (zoneNumber < 0 || zoneNumber > 5) {
204 // Function: KKJ_Zone_Lo
205 int Location::KKJ_Zone_Lo(double kkjlo)
207 // determine the zonenumber from KKJ easting
208 // takes KKJ zone which has center meridian
209 // longitude nearest (in math value) to
210 // the given KKJ longitude
212 while (zoneNumber >= 0) {
213 if (fabs(kkjlo - KkjZoneInfo[zoneNumber][0]) <= 1.5) {
223 // Function: KKJlalo_to_WGS84lalo
224 void Location::KKJlola_to_WGS84lola(double kkjlo, double kkjla, double *outLongitude, double *outLatitude)
226 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;
227 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;
229 *outLatitude = degrees(radians(kkjla) + dLa);
230 *outLongitude = degrees(radians(kkjlo) + dLo);
234 // Function: WGS84lalo_to_KKJlalo
235 void Location::WGS84lola_to_KKJlola(double longitude, double latitude, double *outLongitude, double *outLatitude)
237 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;
238 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;
240 *outLatitude = degrees(radians(latitude) + dLa);
241 *outLongitude = degrees(radians(longitude) + dLo);
245 // Function: KKJlalo_to_KKJxy
246 void Location::KKJlola_to_KKJxy(double lon, double lat, int zoneNumber, KKJ *outX, KKJ *outY)
249 double a = 6378388.0;
250 double f = 1.0 / 297.0;
251 double b = (1.0 - f) * a;
253 double c = (a / b) * a;
254 double ee = (a * a - bb) / bb;
255 double n = (a - b) / (a + b);
258 double Lo = radians(lon) - radians(KkjZoneInfo[zoneNumber][0]);
259 double cosLa = cos(radians(lat));
260 double NN = ee * cosLa * cosLa;
261 double LaF = atan(tan(radians(lat)) / cos(Lo * sqrt(1.0 + NN)));
262 double cosLaF = cos(LaF);
263 double t = (tan(Lo) * cosLaF) / sqrt(1.0 + ee * cosLaF * cosLaF);
264 double A = a / (1.0 + n);
265 double A1 = A * (1.0 + nn / 4.0 + nn * nn / 64.0);
266 double A2 = A * 1.5 * n * (1.0 - nn / 8.0);
267 double A3 = A * 0.9375 * nn * (1.0 - nn / 4.0);
268 double A4 = A * 35.0 / 48.0 * nn * n;
270 *outY = A1 * LaF - A2 * sin(2.0 * LaF) + A3 * sin(4.0 * LaF) - A4 * sin(6.0 * LaF);
271 *outX = c * log(t + sqrt(1.0 + t * t)) + 500000.0 + zoneNumber * 1000000.0;
274 // Function: KKJxy_to_KKJlalo
275 void Location::KKJxy_to_KKJlola(KKJ x, KKJ y, double *outLongitude, double *outLatitude)
277 // Scan iteratively the target area, until find matching
278 // KKJ coordinate value. Area is defined with Hayford Ellipsoid.
279 int zoneNumber = KKJ_Zone_I(x);
280 double minLo = radians(18.5);
281 double maxLo = radians(32.0);
282 double minLa = radians(59.0);
283 double maxLa = radians(70.5);
289 double deltaLo = maxLo - minLo;
290 double deltaLa = maxLa - minLa;
291 *outLongitude = degrees(minLo + 0.5 * deltaLo);
292 *outLatitude = degrees(minLa + 0.5 * deltaLa);
293 KKJlola_to_KKJxy(*outLongitude, *outLatitude, zoneNumber, &tmpX, &tmpY);
295 minLa = minLa + 0.45 * deltaLa;
297 maxLa = minLa + 0.55 * deltaLa;
301 minLo = minLo + 0.45 * deltaLo;
303 maxLo = minLo + 0.55 * deltaLo;
310 void Location::WGS84lola_to_KKJxy(double longitude, double latitude, KKJ *outX, KKJ *outY)
314 WGS84lola_to_KKJlola(longitude, latitude, &kkjlo, &kkjla);
315 int zoneNumber = KKJ_Zone_Lo(kkjlo);
316 KKJlola_to_KKJxy(kkjlo, kkjla, zoneNumber, outX, outY);
319 void Location::KKJxy_to_WGS84lola(KKJ x, KKJ y, double *outLongitude, double *outLatitude)
323 KKJxy_to_KKJlola(x, y, &kkjlo, &kkjla);
324 KKJlola_to_WGS84lola(kkjlo, kkjla, outLongitude, outLatitude);