Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
305 KeyOz 1
/*
2
*
3
* This file is part of QMapControl,
4
* an open-source cross-platform map widget
5
*
6
* Copyright (C) 2007 - 2008 Kai Winter
7
*
8
* This program is free software: you can redistribute it and/or modify
9
* it under the terms of the GNU Lesser General Public License as published by
10
* the Free Software Foundation, either version 3 of the License, or
11
* (at your option) any later version.
12
*
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
* GNU Lesser General Public License for more details.
17
*
18
* You should have received a copy of the GNU Lesser General Public License
19
* along with QMapControl. If not, see <http://www.gnu.org/licenses/>.
20
*
21
* Contact e-mail: kaiwinter@gmx.de
22
* Program URL   : http://qmapcontrol.sourceforge.net/
23
*
24
*/
25
 
26
#include "googlesatmapadapter.h"
27
 
28
#include <math.h>
29
namespace qmapcontrol
30
{
31
    GoogleSatMapAdapter::GoogleSatMapAdapter()
32
        : MapAdapter("kh.google.com", "/kh?n=404&v=8&t=trtqtt", 256, 0, 19)
33
    {
34
        // name = "googlesat";
35
 
36
        numberOfTiles = pow(2, current_zoom+0.0);
37
        coord_per_x_tile = 360. / numberOfTiles;
38
        coord_per_y_tile = 180. / numberOfTiles;
39
    }
40
 
41
    GoogleSatMapAdapter::~GoogleSatMapAdapter()
42
    {
43
    }
44
 
45
    QString GoogleSatMapAdapter::getHost() const
46
    {
47
        int random = qrand() % 4;
48
        return QString("kh%1.google.com").arg(random);
49
    }
50
 
51
    QPoint GoogleSatMapAdapter::coordinateToDisplay(const QPointF& coordinate) const
52
    {
53
        //double x = ((coordinate.x()+180)*(tilesize*numberOfTiles/360));
54
        //double y = (((coordinate.y()*-1)+90)*(tilesize*numberOfTiles/180));
55
 
56
        qreal x = (coordinate.x()+180.) * (numberOfTiles*mytilesize)/360.;              // coord to pixel!
57
        //double y = -1*(coordinate.y()-90) * (numberOfTiles*tilesize)/180.;    // coord to pixel!
58
        qreal y = (getMercatorYCoord(coordinate.y())-M_PI) * -1 * (numberOfTiles*mytilesize)/(2*M_PI);  // coord to pixel!
59
        return QPoint(int(x), int(y));
60
    }
61
 
62
    QPointF GoogleSatMapAdapter::displayToCoordinate(const QPoint& point) const
63
    {
64
        //double lon = ((point.x()/tilesize*numberOfTiles)*360)-180;
65
        //double lat = (((point.y()/tilesize*numberOfTiles)*180)-90)*-1;
66
 
67
        qreal lon = (point.x()*(360./(numberOfTiles*mytilesize)))-180.;
68
        //double lat = -(point.y()*(180./(numberOfTiles*tilesize)))+90;
69
        //qreal lat = getMercatorLatitude(point.y()*-1*(2*M_PI/(numberOfTiles*tilesize)) + M_PI);
70
        qreal lat = lat *180./M_PI;
71
        return QPointF(lon, lat);
72
    }
73
 
74
    qreal GoogleSatMapAdapter::getMercatorLatitude(qreal YCoord) const
75
    {
76
        //http://welcome.warnercnr.colostate.edu/class_info/nr502/lg4/projection_mathematics/converting.html
77
        if (YCoord > M_PI) return 9999.;
78
        if (YCoord < -M_PI) return -9999.;
79
 
80
        qreal t = atan(exp(YCoord));
81
        qreal res = (2.*(t))-(M_PI/2.);
82
        return res;
83
    }
84
 
85
    qreal GoogleSatMapAdapter::getMercatorYCoord(qreal lati) const
86
    {
87
        qreal lat = lati;
88
 
89
        // conversion degre=>radians
90
        qreal phi = M_PI * lat / 180;
91
 
92
        qreal res;
93
        //double temp = Math.Tan(Math.PI / 4 - phi / 2);
94
        //res = Math.Log(temp);
95
        res = 0.5 * log((1 + sin(phi)) / (1 - sin(phi)));
96
 
97
        return res;
98
    }
99
 
100
    void GoogleSatMapAdapter::zoom_in()
101
    {
102
        current_zoom+=1;
103
        numberOfTiles = pow(2, current_zoom+0.0);
104
        coord_per_x_tile = 360. / numberOfTiles;
105
        coord_per_y_tile = 180. / numberOfTiles;
106
    }
107
 
108
    void GoogleSatMapAdapter::zoom_out()
109
    {
110
        current_zoom-=1;
111
        numberOfTiles = pow(2, current_zoom+0.0);
112
        coord_per_x_tile = 360. / numberOfTiles;
113
        coord_per_y_tile = 180. / numberOfTiles;
114
    }
115
 
116
    bool GoogleSatMapAdapter::isValid(int x, int y, int z) const
117
    {
118
        if ((x>=0 && x < numberOfTiles) && (y>=0 && y < numberOfTiles) && z>=0)
119
        {
120
            return true;
121
        }
122
        return false;
123
    }
124
    QString GoogleSatMapAdapter::query(int i, int j, int z) const
125
    {
126
        return getQ(-180+i*coord_per_x_tile,
127
                    90-(j+1)*coord_per_y_tile, z);
128
    }
129
 
130
    QString GoogleSatMapAdapter::getQ(qreal longitude, qreal latitude, int zoom) const
131
    {
132
        qreal xmin=-180;
133
        qreal xmax=180;
134
        qreal ymin=-90;
135
        qreal ymax=90;
136
 
137
        qreal xmoy=0;
138
        qreal ymoy=0;
139
        QString location="t";
140
 
141
        //Google uses a latitude divided by 2;
142
        qreal halflat = latitude;
143
 
144
        for (int i = 0; i < zoom; i++)
145
        {
146
            xmoy = (xmax + xmin) / 2;
147
            ymoy = (ymax + ymin) / 2;
148
            if (halflat >= ymoy) //upper part (q or r)
149
            {
150
                ymin = ymoy;
151
                if (longitude < xmoy)
152
                { /*q*/
153
                    location+= "q";
154
                    xmax = xmoy;
155
                }
156
                else
157
                {/*r*/
158
                    location+= "r";
159
                    xmin = xmoy;
160
                }
161
            }
162
            else //lower part (t or s)
163
            {
164
                ymax = ymoy;
165
                if (longitude < xmoy)
166
                { /*t*/
167
 
168
                    location+= "t";
169
                    xmax = xmoy;
170
                }
171
                else
172
                {/*s*/
173
                    location+= "s";
174
                    xmin = xmoy;
175
                }
176
            }
177
        }
178
        return QString("/kh?n=404&v=24&t=%1").arg(location);
179
    }
180
}
181