dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
urlfactory.cpp
Go to the documentation of this file.
1 
13 /*
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, see <http://www.gnu.org/licenses/>
26 */
27 #define _USE_MATH_DEFINES
28 #include <cmath>
29 #include "urlfactory.h"
30 #include <QRegExp>
31 
32 namespace core {
33 
34 const double UrlFactory::EarthRadiusKm = 6378.137; // WGS-84
35 
37 {
41 
42  Proxy.setType(QNetworkProxy::DefaultProxy);
43 
47  UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36";
48 
49  Timeout = 5 * 1000;
50  CorrectGoogleVersions=true;
51  isCorrectedGoogleVersions = false;
52  UseGeocoderCache=true;
53  UsePlacemarkCache=true;
54 }
56 {
57 }
58 QString UrlFactory::TileXYToQuadKey(const int &tileX,const int &tileY,const int &levelOfDetail) const
59 {
60  QString quadKey;
61  for(int i = levelOfDetail; i > 0; i--)
62  {
63  char digit = '0';
64  int mask = 1 << (i - 1);
65  if((tileX & mask) != 0)
66  {
67  digit++;
68  }
69  if((tileY & mask) != 0)
70  {
71  digit++;
72  digit++;
73  }
74  quadKey.append(digit);
75  }
76  return quadKey;
77 }
78 int UrlFactory::GetServerNum(const Point &pos,const int &max) const
79 {
80  return (pos.X() + 2 * pos.Y()) % max;
81 }
83 {
84  isCorrectedGoogleVersions=value;
85 }
86 
88 {
89  return isCorrectedGoogleVersions;
90 }
91 
92 void UrlFactory::TryCorrectGoogleVersions()
93 {
94  static bool versionRetrieved = false;
95  if (versionRetrieved){
96  return;
97  }
98 
99  QMutexLocker locker(&mutex);
100  if(CorrectGoogleVersions && !IsCorrectGoogleVersions())
101  {
102  QNetworkReply *reply = nullptr;
103  QNetworkRequest qheader;
104  QNetworkAccessManager network;
105  QEventLoop q;
106  QTimer tT;
107  tT.setSingleShot(true);
108  connect(&network, SIGNAL(finished(QNetworkReply*)),
109  &q, SLOT(quit()));
110  connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
111  network.setProxy(Proxy);
112 #ifdef DEBUG_URLFACTORY
113  qDebug()<<"Correct GoogleVersion";
114 #endif //DEBUG_URLFACTORY
116  QUrl url = QUrl(gAPIUrl);
117  qheader.setUrl(url);
118  qheader.setRawHeader("User-Agent",UserAgent);
119  reply = network.get(qheader);
120  tT.start(3 * Timeout);
121  q.exec();
122  if(!tT.isActive()) {
123  return;
124  }
125  tT.stop();
126  if( (reply->error()!=QNetworkReply::NoError))
127  {
128 #ifdef DEBUG_URLFACTORY
129  qDebug()<<"Try corrected version error:"<<reply->errorString();
130 #endif //DEBUG_URLFACTORY
131  return;
132  }
133  QString html = QString(reply->readAll());
134  QRegExp reg(gMapRegex,Qt::CaseInsensitive);
135  qDebug() << "index="<<reg.indexIn(html);
136  if(reg.indexIn(html)!=-1)
137  {
138  QStringList gc = reg.capturedTexts();
139  VersionGoogleMap = QString("m@%1").arg(gc[1]);
141 #ifdef DEBUG_URLFACTORY
142  qDebug()<<"TryCorrectGoogleVersions, VersionGoogleMap: "<<VersionGoogleMap;
143 #endif //DEBUG_URLFACTORY
144  }
145 
146  reg=QRegExp(gLabRegex,Qt::CaseInsensitive);
147  if(reg.indexIn(html)!=-1)
148  {
149  QStringList gc=reg.capturedTexts();
150  VersionGoogleLabels = QString("h@%1").arg(gc[1]);
152 #ifdef DEBUG_URLFACTORY
153  qDebug()<<"TryCorrectGoogleVersions, VersionGoogleLabels: "<<VersionGoogleLabels;
154 #endif //DEBUG_URLFACTORY
155  }
156  reg=QRegExp(gSatRegex,Qt::CaseInsensitive);
157  if(reg.indexIn(html)!=-1)
158  {
159  QStringList gc=reg.capturedTexts();
160  VersionGoogleSatellite = gc[1];
163 #ifdef DEBUG_URLFACTORY
164  qDebug()<<"TryCorrectGoogleVersions, VersionGoogleSatellite: "<<VersionGoogleSatellite;
165 #endif //DEBUG_URLFACTORY
166  }
167  reg=QRegExp(gTerRegex,Qt::CaseInsensitive);
168  if(reg.indexIn(html)!=-1)
169  {
170  QStringList gc=reg.capturedTexts();
171  VersionGoogleTerrain = QString("t@%1,r@%2").arg(gc[1]).arg(gc[2]);
173 #ifdef DEBUG_URLFACTORY
174  qDebug()<<"TryCorrectGoogleVersions, VersionGoogleTerrain: "<<VersionGoogleTerrain;
175 #endif //DEBUG_URLFACTORY
176  }
177  reply->deleteLater();
178  versionRetrieved = true;
179  }
180 
181 }
182 
191 QString UrlFactory::MakeImageUrl(const MapType::Types &type,const Point &pos,const int &zoom,const QString &language)
192 {
193 #ifdef DEBUG_URLFACTORY
194  // qDebug()<<"Entered MakeImageUrl";
195 #endif //DEBUG_URLFACTORY
196  switch(type)
197  {
198  case MapType::GoogleMap:
199  {
200  QString server = "mt";
201  QString request = "vt";
202  QString sec1 = ""; // after &x=...
203  QString sec2 = ""; // after &zoom=...
204  GetSecGoogleWords(pos, sec1, sec2);
205  TryCorrectGoogleVersions();
206 
207  return QString("http://%1%2.google.com/%3/lyrs=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleMap).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
208  }
209  break;
210  case MapType::GoogleSatellite:
211  {
212  QString server = "khm";
213  QString request = "kh";
214  QString sec1 = ""; // after &x=...
215  QString sec2 = ""; // after &zoom=...
216  GetSecGoogleWords(pos, sec1, sec2);
217  TryCorrectGoogleVersions();
218  return QString("http://%1%2.google.com/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleSatellite).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
219  }
220  break;
221  case MapType::GoogleLabels:
222  {
223  QString server = "mt";
224  QString request = "vt";
225  QString sec1 = ""; // after &x=...
226  QString sec2 = ""; // after &zoom=...
227  GetSecGoogleWords(pos, sec1, sec2);
228  TryCorrectGoogleVersions();
229 
230  return QString("http://%1%2.google.com/%3/lyrs=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleLabels).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
231  }
232  break;
233  case MapType::GoogleTerrain:
234  {
235  QString server = "mt";
236  QString request = "vt";
237  QString sec1 = ""; // after &x=...
238  QString sec2 = ""; // after &zoom=...
239  GetSecGoogleWords(pos, sec1, sec2);
240  TryCorrectGoogleVersions();
241  return QString("http://%1%2.google.com/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleTerrain).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
242  }
243  break;
244  case MapType::GoogleMapChina:
245  {
246  QString server = "mt";
247  QString request = "vt";
248  QString sec1 = ""; // after &x=...
249  QString sec2 = ""; // after &zoom=...
250  GetSecGoogleWords(pos, sec1, sec2);
251  TryCorrectGoogleVersions();
252  // http://mt0.google.cn/vt/v=w2.101&hl=zh-CN&gl=cn&x=12&y=6&z=4&s=Ga
253 
254  return QString("http://%1%2.google.cn/%3/lyrs=%4&hl=%5&gl=cn&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleMapChina).arg("zh-CN").arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
255  }
256  break;
257  case MapType::GoogleSatelliteChina:
258  {
259  QString server = "mt";
260  QString request = "vt";
261  QString sec1 = ""; // after &x=...
262  QString sec2 = ""; // after &zoom=...
263  GetSecGoogleWords(pos, sec1, sec2);
264  // TryCorrectGoogleVersions();
265  // http://khm0.google.cn/kh/v=46&x=12&y=6&z=4&s=Ga
266 
267  return QString("http://%1%2.google.cn/%3/lyrs=%4&gl=cn&x=%5%6&y=%7&z=%8&s=%9").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleSatelliteChina).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
268  }
269  break;
270  case MapType::GoogleLabelsChina:
271  {
272  QString server = "mt";
273  QString request = "vt";
274  QString sec1 = ""; // after &x=...
275  QString sec2 = ""; // after &zoom=...
276  GetSecGoogleWords(pos, sec1, sec2);
277  TryCorrectGoogleVersions();
278  // http://mt0.google.cn/vt/v=w2t.110&hl=zh-CN&gl=cn&x=12&y=6&z=4&s=Ga
279 
280  return QString("http://%1%2.google.cn/%3/imgtp=png32&lyrs=%4&hl=%5&gl=cn&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleLabelsChina).arg("zh-CN").arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
281  }
282  break;
283  case MapType::GoogleTerrainChina:
284  {
285  QString server = "mt";
286  QString request = "vt";
287  QString sec1 = ""; // after &x=...
288  QString sec2 = ""; // after &zoom=...
289  GetSecGoogleWords(pos, sec1, sec2);
290  TryCorrectGoogleVersions();
291  // http://mt0.google.cn/vt/v=w2p.110&hl=zh-CN&gl=cn&x=12&y=6&z=4&s=Ga
292 
293  return QString("http://%1%2.google.com/%3/lyrs=%4&hl=%5&gl=cn&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleTerrainChina).arg("zh-CN").arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
294  }
295  break;
296  case MapType::GoogleMapKorea:
297  {
298  QString server = "mt";
299  QString request = "mt";
300  QString sec1 = ""; // after &x=...
301  QString sec2 = ""; // after &zoom=...
302  GetSecGoogleWords(pos, sec1, sec2);
303 
304  //http://mt3.gmaptiles.co.kr/mt/v=kr1.11&hl=lt&x=109&y=49&z=7&s=
305 
306  QString ret = QString("http://%1%2.gmaptiles.co.kr/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleMapKorea).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
307  return ret;
308  }
309  break;
310  case MapType::GoogleSatelliteKorea:
311  {
312  QString server = "khm";
313  QString request = "kh";
314  QString sec1 = ""; // after &x=...
315  QString sec2 = ""; // after &zoom=...
316  GetSecGoogleWords(pos, sec1, sec2);
317 
318  // http://khm1.google.co.kr/kh/v=54&x=109&y=49&z=7&s=
319 
320  return QString("http://%1%2.google.co.kr/%3/v=%4&x=%5%6&y=%7&z=%8&s=%9").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleSatelliteKorea).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
321  }
322  break;
323  case MapType::GoogleLabelsKorea:
324  {
325  QString server = "mt";
326  QString request = "mt";
327  QString sec1 = ""; // after &x=...
328  QString sec2 = ""; // after &zoom=...
329  GetSecGoogleWords(pos, sec1, sec2);
330 
331  // http://mt1.gmaptiles.co.kr/mt/v=kr1t.11&hl=lt&x=109&y=50&z=7&s=G
332 
333  return QString("http://%1%2.gmaptiles.co.kr/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleLabelsKorea).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
334  }
335  break;
336  case MapType::YahooMap:
337  {
338  return QString("http://maps%1.yimg.com/hx/tl?v=%2&.intl=%3&x=%4&y=%5&z=%6&r=1").arg(((GetServerNum(pos, 2)) + 1)).arg(VersionYahooMap).arg(language).arg(pos.X()).arg((((1 << zoom) >> 1) - 1 - pos.Y())).arg((zoom + 1));
339  }
340 
341  case MapType::YahooSatellite:
342  {
343  return QString("http://maps%1.yimg.com/ae/ximg?v=%2&t=a&s=256&.intl=%3&x=%4&y=%5&z=%6&r=1").arg("3").arg(VersionYahooSatellite).arg(language).arg(pos.X()).arg(((1 << zoom) >> 1) - 1 - pos.Y()).arg(zoom + 1);
344  }
345  break;
346  case MapType::YahooLabels:
347  {
348  return QString("http://maps%1.yimg.com/hx/tl?v=%2&t=h&.intl=%3&x=%4&y=%5&z=%6&r=1").arg("1").arg(VersionYahooLabels).arg(language).arg(pos.X()).arg(((1 << zoom) >> 1) - 1 - pos.Y()).arg(zoom + 1);
349  }
350  break;
351  case MapType::OpenStreetMap:
352  {
353  char letter= "abc"[GetServerNum(pos, 3)];
354  return QString("http://%1.tile.openstreetmap.org/%2/%3/%4.png").arg(letter).arg(zoom).arg(pos.X()).arg(pos.Y());
355  }
356  break;
357  case MapType::OpenStreetOsm:
358  {
359  char letter = "abc"[GetServerNum(pos, 3)];
360  return QString("http://%1.tah.openstreetmap.org/Tiles/tile/%2/%3/%4.png").arg(letter).arg(zoom).arg(pos.X()).arg(pos.Y());
361  }
362  break;
363  case MapType::OpenStreetMapSurfer:
364  {
365  // http://tiles1.mapsurfer.net/tms_r.ashx?x=37378&y=20826&z=16
366 
367  return QString("http://tiles1.mapsurfer.net/tms_r.ashx?x=%1&y=%2&z=%3").arg(pos.X()).arg(pos.Y()).arg(zoom);
368  }
369  break;
370  case MapType::OpenStreetMapSurferTerrain:
371  {
372  // http://tiles2.mapsurfer.net/tms_t.ashx?x=9346&y=5209&z=14
373 
374  return QString("http://tiles2.mapsurfer.net/tms_t.ashx?x=%1&y=%2&z=%3").arg(pos.X()).arg(pos.Y()).arg(zoom);
375  }
376  break;
377  case MapType::BingMap:
378  {
379  QString key = TileXYToQuadKey(pos.X(), pos.Y(), zoom);
380  return QString("http://ecn.t%1.tiles.virtualearth.net/tiles/r%2.png?g=%3&mkt=%4%5").arg(GetServerNum(pos, 4)).arg(key).arg(VersionBingMaps).arg(language).arg(!(BingMapsClientToken.isNull()|BingMapsClientToken.isEmpty()) ? "&token=" + BingMapsClientToken : QString(""));
381  }
382  break;
383  case MapType::BingSatellite:
384  {
385  QString key = TileXYToQuadKey(pos.X(), pos.Y(), zoom);
386  return QString("http://ecn.t%1.tiles.virtualearth.net/tiles/a%2.jpeg?g=%3&mkt=%4%5").arg(GetServerNum(pos, 4)).arg(key).arg(VersionBingMaps).arg(language).arg(!(BingMapsClientToken.isNull()|BingMapsClientToken.isEmpty()) ? "&token=" + BingMapsClientToken : QString(""));
387  }
388  break;
389  case MapType::BingHybrid:
390  {
391  QString key = TileXYToQuadKey(pos.X(), pos.Y(), zoom);
392  return QString("http://ecn.t%1.tiles.virtualearth.net/tiles/h%2.jpeg?g=%3&mkt=%4%5").arg(GetServerNum(pos, 4)).arg(key).arg(VersionBingMaps).arg(language).arg(!(BingMapsClientToken.isNull()|BingMapsClientToken.isEmpty()) ? "&token=" + BingMapsClientToken : QString(""));
393  }
394 
395  case MapType::ArcGIS_Map:
396  {
397  // http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer/tile/0/0/0.jpg
398 
399  return QString("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer/tile/%1/%2/%3").arg(zoom).arg(pos.Y()).arg(pos.X());
400  }
401  break;
402  case MapType::ArcGIS_Satellite:
403  {
404  // http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer/tile/1/0/1.jpg
405 
406  return QString("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer/tile/%1/%2/%3").arg(zoom).arg(pos.Y()).arg(pos.X());
407  }
408  break;
409  case MapType::ArcGIS_ShadedRelief:
410  {
411  // http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_ShadedRelief_World_2D/MapServer/tile/1/0/1.jpg
412 
413  return QString("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_ShadedRelief_World_2D/MapServer/tile/%1/%2/%3").arg(zoom).arg(pos.Y()).arg(pos.X());
414  }
415  break;
416  case MapType::ArcGIS_Terrain:
417  {
418  // http://server.arcgisonline.com/ArcGIS/rest/services/NGS_Topo_US_2D/MapServer/tile/4/3/15
419 
420  return QString("http://server.arcgisonline.com/ArcGIS/rest/services/NGS_Topo_US_2D/MapServer/tile/%1/%2/%3").arg(zoom).arg(pos.Y()).arg(pos.X());
421  }
422  break;
423  case MapType::ArcGIS_MapsLT_OrtoFoto:
424  {
425  // http://www.maps.lt/ortofoto/mapslt_ortofoto_vector_512/map/_alllayers/L02/R0000001b/C00000028.jpg
426  // http://arcgis.maps.lt/ArcGIS/rest/services/mapslt_ortofoto/MapServer/tile/0/9/13
427  // return string.Format("http://www.maps.lt/ortofoto/mapslt_ortofoto_vector_512/map/_alllayers/L{0:00}/R{1:x8}/C{2:x8}.jpg", zoom, pos.Y(), pos.X());
428  // http://dc1.maps.lt/cache/mapslt_ortofoto_512/map/_alllayers/L03/R0000001c/C00000029.jpg
429  // return string.Format("http://arcgis.maps.lt/ArcGIS/rest/services/mapslt_ortofoto/MapServer/tile/{0}/{1}/{2}", zoom, pos.Y(), pos.X());
430  // http://dc1.maps.lt/cache/mapslt_ortofoto_512/map/_alllayers/L03/R0000001d/C0000002a.jpg
431  //TODO verificar
432  return QString("http://dc1.maps.lt/cache/mapslt_ortofoto/map/_alllayers/L%1/R%2/C%3.jpg").arg(zoom,2,10,(QChar)'0').arg(pos.Y(),8,16,(QChar)'0').arg(pos.X(),8,16,(QChar)'0');
433  }
434  break;
435  case MapType::ArcGIS_MapsLT_Map:
436  {
437  // http://www.maps.lt/ortofoto/mapslt_ortofoto_vector_512/map/_alllayers/L02/R0000001b/C00000028.jpg
438  // http://arcgis.maps.lt/ArcGIS/rest/services/mapslt_ortofoto/MapServer/tile/0/9/13
439  // return string.Format("http://www.maps.lt/ortofoto/mapslt_ortofoto_vector_512/map/_alllayers/L{0:00}/R{1:x8}/C{2:x8}.jpg", zoom, pos.Y(), pos.X());
440  // http://arcgis.maps.lt/ArcGIS/rest/services/mapslt/MapServer/tile/7/1162/1684.png
441  // http://dc1.maps.lt/cache/mapslt_512/map/_alllayers/L03/R0000001b/C00000029.png
442  //TODO verificar
443  // http://dc1.maps.lt/cache/mapslt/map/_alllayers/L02/R0000001c/C00000029.png
444  return QString("http://dc1.maps.lt/cache/mapslt/map/_alllayers/L%1/R%2/C%3.png").arg(zoom,2,10,(QChar)'0').arg(pos.Y(),8,16,(QChar)'0').arg(pos.X(),8,16,(QChar)'0');
445  }
446  break;
447  case MapType::ArcGIS_MapsLT_Map_Labels:
448  {
449  //http://arcgis.maps.lt/ArcGIS/rest/services/mapslt_ortofoto_overlay/MapServer/tile/0/9/13
450  //return string.Format("http://arcgis.maps.lt/ArcGIS/rest/services/mapslt_ortofoto_overlay/MapServer/tile/{0}/{1}/{2}", zoom, pos.Y(), pos.X());
451  //http://dc1.maps.lt/cache/mapslt_ortofoto_overlay_512/map/_alllayers/L03/R0000001d/C00000029.png
452  //TODO verificar
453  return QString("http://dc1.maps.lt/cache/mapslt_ortofoto_overlay/map/_alllayers/L%1/R%2/C%3.png").arg(zoom,2,10,(QChar)'0').arg(pos.Y(),8,16,(QChar)'0').arg(pos.X(),8,16,(QChar)'0');
454  }
455  break;
456  case MapType::PergoTurkeyMap:
457  {
458  // http://{domain}/{layerName}/{zoomLevel}/{first3LetterOfTileX}/{second3LetterOfTileX}/{third3LetterOfTileX}/{first3LetterOfTileY}/{second3LetterOfTileY}/{third3LetterOfTileXY}.png
459 
460  // http://map3.pergo.com.tr/tile/00/000/000/001/000/000/000.png
461  // That means: Zoom Level: 0 TileX: 1 TileY: 0
462 
463  // http://domain/tile/14/000/019/371/000/011/825.png
464  // That means: Zoom Level: 14 TileX: 19371 TileY:11825
465 
466  // string x = pos.X().ToString("000000000").Insert(3, "/").Insert(7, "/"); // - 000/000/001
467  // string y = pos.Y().ToString("000000000").Insert(3, "/").Insert(7, "/"); // - 000/000/000
468  QString x=QString("%1").arg(QString::number(pos.X()),9,(QChar)'0');
469  x.insert(3,"/").insert(7,"/");
470  QString y=QString("%1").arg(QString::number(pos.Y()),9,(QChar)'0');
471  y.insert(3,"/").insert(7,"/");
472  //"http://map03.pergo.com.tr/tile/2/000/000/003/000/000/002.png"
473  return QString("http://map%1.pergo.com.tr/tile/%2/%3/%4.png").arg(GetServerNum(pos, 4)).arg(zoom,2,10,(QChar)'0').arg(x).arg(y);
474  }
475  break;
476  case MapType::SigPacSpainMap:
477  {
478  return QString("http://sigpac.mapa.es/kmlserver/raster/%1@3785/%2.%3.%4.img").arg(levelsForSigPacSpainMap[zoom]).arg(zoom).arg(pos.X()).arg((2 << (zoom - 1)) - pos.Y() - 1);
479  }
480  break;
481 
482  case MapType::YandexMapRu:
483  {
484  QString server = "vec";
485 
486  //http://vec01.maps.yandex.ru/tiles?l=map&v=2.10.2&x=1494&y=650&z=11
487 
488  return QString("http://%1").arg(server)+QString("0%2.maps.yandex.ru/tiles?l=map&v=%3&x=%4&y=%5&z=%6").arg(GetServerNum(pos, 4)+1).arg(VersionYandexMap).arg(pos.X()).arg(pos.Y()).arg(zoom);
489  }
490  break;
491  default:
492  break;
493  }
494 
495  return QString();
496 }
497 void UrlFactory::GetSecGoogleWords(const Point &pos, QString &sec1, QString &sec2)
498 {
499  sec1 = ""; // after &x=...
500  sec2 = ""; // after &zoom=...
501  int seclen = ((pos.X() * 3) + pos.Y()) % 8;
502  sec2 = SecGoogleWord.left(seclen);
503  if(pos.Y() >= 10000 && pos.Y() < 100000)
504  {
505  sec1 = "&s=";
506  }
507 }
508 
509 QString UrlFactory::MakeGeocoderUrl(QString keywords,const QString &language)
510 {
511  QString key = keywords.replace(' ', '+');
512  if(language.contains("AUTO"))
513  return QString("http://maps.googleapis.com/maps/api/geocode/xml?address=%0&sensor=false").arg(key);
514  else
515  return QString("http://maps.googleapis.com/maps/api/geocode/xml?address=%0&sensor=false&language=%1").arg(key).arg(language);
516 }
517 
518 QString UrlFactory::MakeReverseGeocoderUrl(internals::PointLatLng &pt,const QString &language)
519 {
520  if(language.contains("AUTO"))
521  return QString("http://maps.googleapis.com/maps/api/geocode/xml?latlng=%0,%1&sensor=false").arg(QString::number(pt.Lat(), 'f', 7)).arg(QString::number(pt.Lng(), 'f', 7));
522  else
523  return QString("http://maps.googleapis.com/maps/api/geocode/xml?latlng=%0,%1&sensor=false&language=%2").arg(QString::number(pt.Lat(), 'f', 7)).arg(QString::number(pt.Lng(), 'f', 7)).arg(language);
524 }
525 
526 QList <UrlFactory::geoCodingStruct> UrlFactory::GetLatLngFromGeodecoder(const QString &keywords, GeoCoderStatusCode::Types &status,const QString &language)
527 {
528  return GetLatLngFromGeocoderUrl(MakeGeocoderUrl(keywords,language),UseGeocoderCache,status);
529 }
530 
531 QList <UrlFactory::geoCodingStruct> UrlFactory::GetLatLngFromGeocoderUrl(const QString &url, const bool &useCache, GeoCoderStatusCode::Types &status)
532 {
534 #ifdef DEBUG_URLFACTORY
535  qDebug()<<"Entered GetLatLngFromGeocoderUrl:";
536 #endif //DEBUG_URLFACTORY
537  status = GeoCoderStatusCode::UNKNOWN_ERROR;
538  QString urlEnd = url.mid(url.indexOf("xml?address=")+12,url.indexOf("&sensor")-url.indexOf("xml?address=")-12);
539  urlEnd.replace( QRegExp(
540  "[^"
541  "A-Z,a-z,0-9,"
542  "\\^,\\&,\\',\\@,"
543  "\\{,\\},\\[,\\],"
544  "\\,,\\$,\\=,\\!,"
545  "\\-,\\#,\\(,\\),"
546  "\\%,\\.,\\+,\\~,\\_"
547  "]"), "_" );
548 
549  QString geo = useCache ? Cache::Instance()->GetGeocoderFromCache(urlEnd) : "";
550  if(geo.isNull()|geo.isEmpty())
551  {
552 #ifdef DEBUG_URLFACTORY
553  qDebug()<<"GetLatLngFromGeocoderUrl:Not in cache going internet";
554 #endif //DEBUG_URLFACTORY
555  QNetworkReply::NetworkError error;
556  geo = FetchWebRequest(url,error);
557 #ifdef DEBUG_URLFACTORY
558  qDebug()<<"GetLatLngFromGeocoderUrl:URL="<<url;
559  qDebug()<<"Finished?"<< error;
560 #endif //DEBUG_URLFACTORY
561  if(error !=QNetworkReply::NoError)
562  {
563 #ifdef DEBUG_URLFACTORY
564  qDebug()<<"GetLatLngFromGeocoderUrl::Network error";
565 #endif //DEBUG_URLFACTORY
566  return results;
567  }
568  {
569 #ifdef DEBUG_URLFACTORY
570  qDebug()<<"GetLatLngFromGeocoderUrl:Reply ok";
571 #endif //DEBUG_URLFACTORY
572  results = GetGeoCodingFromXML(geo,status);
573  // cache geocoding
574  if(useCache && status == GeoCoderStatusCode::OK)
575  {
576  Cache::Instance()->CacheGeocoder(urlEnd, geo);
577  }
578  }
579  }
580  else
581  results = GetGeoCodingFromXML(geo,status);
582  return results;
583 }
584 
585 QList <UrlFactory::geoCodingStruct> UrlFactory::GetPlacemarkFromGeocoder(internals::PointLatLng location, GeoCoderStatusCode::Types &status,const QString &language)
586 {
587  return GetPlacemarkFromReverseGeocoderUrl(MakeReverseGeocoderUrl(location, language), UsePlacemarkCache,status);
588 }
589 
590 QList <UrlFactory::geoCodingStruct> UrlFactory::GetPlacemarkFromReverseGeocoderUrl(const QString &url, const bool &useCache, GeoCoderStatusCode::Types &status)
591 {
593 #ifdef DEBUG_URLFACTORY
594  qDebug()<<"Entered GetLatLngFromGeocoderUrl:";
595 #endif //DEBUG_URLFACTORY
596  status = GeoCoderStatusCode::UNKNOWN_ERROR;
597  QString urlEnd = url.mid(url.indexOf("xml?latlng=")+11,url.indexOf("&sensor")-url.indexOf("xml?latlng=")-11);
598  urlEnd.replace( QRegExp(
599  "[^"
600  "A-Z,a-z,0-9,"
601  "\\^,\\&,\\',\\@,"
602  "\\{,\\},\\[,\\],"
603  "\\,,\\$,\\=,\\!,"
604  "\\-,\\#,\\(,\\),"
605  "\\%,\\.,\\+,\\~,\\_"
606  "]"), "_" );
607 
608  QString geo = useCache ? Cache::Instance()->GetPlacemarkFromCache(urlEnd) : "";
609  if(geo.isNull()|geo.isEmpty())
610  {
611 #ifdef DEBUG_URLFACTORY
612  qDebug()<<"GetLatLngFromGeocoderUrl:Not in cache going internet";
613 #endif //DEBUG_URLFACTORY
614  QNetworkReply::NetworkError error;
615  geo = FetchWebRequest(url,error);
616 #ifdef DEBUG_URLFACTORY
617  qDebug()<<"GetLatLngFromGeocoderUrl:URL="<<url;
618  qDebug()<<"Finished?"<< error;
619 #endif //DEBUG_URLFACTORY
620  if(error !=QNetworkReply::NoError)
621  {
622 #ifdef DEBUG_URLFACTORY
623  qDebug()<<"GetLatLngFromGeocoderUrl::Network error";
624 #endif //DEBUG_URLFACTORY
625  return results;
626  }
627  {
628 #ifdef DEBUG_URLFACTORY
629  qDebug()<<"GetLatLngFromGeocoderUrl:Reply ok";
630 #endif //DEBUG_URLFACTORY
631  results = GetGeoCodingFromXML(geo,status);
632  // cache geocoding
633  if(useCache && status == GeoCoderStatusCode::OK)
634  {
635  Cache::Instance()->CachePlacemark(urlEnd, geo);
636  }
637  }
638  }
639  else
640  results = GetGeoCodingFromXML(geo,status);
641  return results;
642 }
643 
644 double UrlFactory::GetDistance(internals::PointLatLng p1, internals::PointLatLng p2)
645 {
646  double dLat1InRad = p1.Lat() * (M_PI / 180);
647  double dLong1InRad = p1.Lng() * (M_PI / 180);
648  double dLat2InRad = p2.Lat() * (M_PI / 180);
649  double dLong2InRad = p2.Lng() * (M_PI / 180);
650  double dLongitude = dLong2InRad - dLong1InRad;
651  double dLatitude = dLat2InRad - dLat1InRad;
652  double a = pow(sin(dLatitude / 2), 2) + cos(dLat1InRad) * cos(dLat2InRad) * pow(sin(dLongitude / 2), 2);
653  double c = 2 * atan2(sqrt(a), sqrt(1 - a));
654  double dDistance = EarthRadiusKm * c;
655  return dDistance;
656 }
657 
658 QList<UrlFactory::geoCodingStruct> UrlFactory::GetGeoCodingFromXML(QString xml,GeoCoderStatusCode::Types &status)
659 {
661  QDomDocument doc;
662  doc.setContent(xml);
663  QDomElement docElem = doc.documentElement();
664  status=GeoCoderStatusCode::TypeByStr(docElem.elementsByTagName("status").at(0).toElement().text());
665  if(status != GeoCoderStatusCode::OK)
666  return ret;
667  QDomNodeList resultsList=docElem.elementsByTagName("result");
668  for(int ii=0;ii<resultsList.count();++ii)
669  {
670  QDomNode result=resultsList.at(ii);
671  QString address=result.namedItem("formatted_address").toElement().text();
672  QDomNode location =result.namedItem("geometry").namedItem("location");
673  double lat = location.namedItem("lat").toElement().text().toDouble();
674  double lng = location.namedItem("lng").toElement().text().toDouble();
675  geoCodingStruct temp;
676  temp.coordinates=internals::PointLatLng(lat, lng);
677  temp.address=address;
678  ret.append(temp);
679  }
680  return ret;
681 }
682 
683 QByteArray UrlFactory::FetchWebRequest(QString url,QNetworkReply::NetworkError &result)
684 {
685  QNetworkReply *networkReply;
686  QNetworkRequest requestHeader;
687  QNetworkAccessManager network;
688  QEventLoop eventLoop;
689  QTimer timeoutTimer;
690  QByteArray ret;
691  timeoutTimer.setSingleShot(true);
692  connect(&network, SIGNAL(finished(QNetworkReply*)),
693  &eventLoop, SLOT(quit()));
694  connect(&timeoutTimer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
695  network.setProxy(Proxy);
696  requestHeader.setUrl(QUrl(url));
697  requestHeader.setRawHeader("User-Agent",UserAgent);
698  networkReply=network.get(requestHeader);
699  timeoutTimer.start(Timeout);
700  eventLoop.exec();
701  if(!timeoutTimer.isActive())
702  {
703  result = QNetworkReply::TimeoutError;
704  return ret;
705  }
706  timeoutTimer.stop();
707  result = networkReply->error();
708  ret = networkReply->readAll();
709  return ret;
710 }
711 
712 double UrlFactory::GetElevationFromCoordinate(const internals::PointLatLng &coordinate,GeoCoderStatusCode::Types &status)
713 {
714  QNetworkReply::NetworkError netResult;
715  status = GeoCoderStatusCode::UNKNOWN_ERROR;
716  QString url = QString("http://maps.googleapis.com/maps/api/elevation/xml?locations=%0,%1&sensor=false").arg(QString::number(coordinate.Lat(), 'f', 7)).arg(QString::number(coordinate.Lng(), 'f', 7));
717  QByteArray answer = FetchWebRequest(url,netResult);
718  if(netResult != QNetworkReply::NoError)
719  return 0;
720  QDomDocument doc;
721  doc.setContent(answer);
722  qDebug()<<url<<answer;
723  QDomElement docElem = doc.documentElement();
724  status=GeoCoderStatusCode::TypeByStr(docElem.elementsByTagName("status").at(0).toElement().text());
725  if(status != GeoCoderStatusCode::OK)
726  return 0;
727  QDomNodeList resultsList=docElem.elementsByTagName("result");
728  if(resultsList.count() > 0)
729  return resultsList.at(0).namedItem("elevation").toElement().text().toDouble();
730  else
731  return 0;
732 }
733 }
QList< UrlFactory::geoCodingStruct > GetLatLngFromGeodecoder(const QString &keywords, GeoCoderStatusCode::Types &status, const QString &language)
Definition: urlfactory.cpp:526
qint64 X() const
Definition: point.h:51
static Cache * Instance()
Definition: cache.cpp:34
QByteArray UserAgent
Gets or sets the value of the User-agent HTTP header.
Definition: urlfactory.h:55
QString GetGeocoderFromCache(const QString &urlEnd)
Definition: cache.cpp:61
QList< UrlFactory::geoCodingStruct > GetPlacemarkFromGeocoder(internals::PointLatLng location, GeoCoderStatusCode::Types &status, const QString &language)
Definition: urlfactory.cpp:585
double GetElevationFromCoordinate(const internals::PointLatLng &coordinate, GeoCoderStatusCode::Types &status)
Definition: urlfactory.cpp:712
QString MakeReverseGeocoderUrl(internals::PointLatLng &pt, const QString &language)
Definition: urlfactory.cpp:518
bool IsCorrectGoogleVersions()
Definition: urlfactory.cpp:87
QString MakeGeocoderUrl(QString keywords, const QString &language)
Definition: urlfactory.cpp:509
for i
Definition: OPPlots.m:140
QString VersionGoogleSatelliteKorea
QList< UrlFactory::geoCodingStruct > GetPlacemarkFromReverseGeocoderUrl(const QString &url, const bool &useCache, GeoCoderStatusCode::Types &status)
Definition: urlfactory.cpp:590
QList< UrlFactory::geoCodingStruct > GetLatLngFromGeocoderUrl(const QString &url, const bool &useCache, GeoCoderStatusCode::Types &status)
Definition: urlfactory.cpp:531
end a
Definition: OPPlots.m:98
double Lng() const
Definition: pointlatlng.h:76
double Lat() const
Definition: pointlatlng.h:64
QString VersionGoogleSatelliteChina
void CachePlacemark(const QString &urlEnd, const QString &content)
Definition: cache.cpp:158
QString BingMapsClientToken
Bing Maps Customer Identification, more info here http://msdn.microsoft.com/en-us/library/bb924353.aspx
static const QString levelsForSigPacSpainMap[]
void setIsCorrectGoogleVersions(bool value)
Definition: urlfactory.cpp:82
QString MakeImageUrl(const MapType::Types &type, const core::Point &pos, const int &zoom, const QString &language)
UrlFactory::MakeImageUrl Make the requesting URL for the desired quadtile.
Definition: urlfactory.cpp:191
end function found on Matlab s file exchange The two functions return identical results
QString GetPlacemarkFromCache(const QString &urlEnd)
Definition: cache.cpp:129
QNetworkProxy Proxy
Definition: urlfactory.h:56
Definition: icore.h:39
void CacheGeocoder(const QString &urlEnd, const QString &content)
Definition: cache.cpp:90
else error('Your technical computing program does not support file choosers.Please input the file name in the argument. ') end elseif nargin >0 logfile
QString VersionYahooMap
Google Maps API generated using http://greatmaps.codeplex.com/ from http://code.google.com/intl/en-us/apis/maps/signup.html
x
Definition: OPPlots.m:100
qint64 Y() const
Definition: point.h:52
y
Definition: OPPlots.m:101