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 "tilemapadapter.h"
27
namespace qmapcontrol
28
{
29
    TileMapAdapter::TileMapAdapter(const QString& host, const QString& serverPath, int tilesize, int minZoom, int maxZoom)
30
        :MapAdapter(host, serverPath, tilesize, minZoom, maxZoom)
31
    {
32
        PI = acos(-1.0);
33
 
34
        /*
35
            Initialize the "substring replace engine". First the string replacement
36
            in getQuery was made by QString().arg() but this was very slow. So this
37
            splits the servers path into substrings and when calling getQuery the
38
            substrings get merged with the parameters of the URL.
39
            Pretty complicated, but fast.
40
        */
41
        param1 = serverPath.indexOf("%1");
42
        param2 = serverPath.indexOf("%2");
43
        param3 = serverPath.indexOf("%3");
44
 
45
        int min = param1 < param2 ? param1 : param2;
46
        min = param3 < min ? param3 : min;
47
 
48
        int max = param1 > param2 ? param1 : param2;
49
        max = param3 > max ? param3 : max;
50
 
51
        int middle = param1+param2+param3-min-max;
52
 
53
        order[0][0] = min;
54
        if (min == param1)
55
            order[0][1] = 0;
56
        else if (min == param2)
57
            order[0][1] = 1;
58
        else
59
            order[0][1] = 2;
60
 
61
        order[1][0] = middle;
62
        if (middle == param1)
63
            order[1][1] = 0;
64
        else if (middle == param2)
65
            order[1][1] = 1;
66
        else
67
            order[1][1] = 2;
68
 
69
        order[2][0] = max;
70
        if (max == param1)
71
            order[2][1] = 0;
72
        else if(max == param2)
73
            order[2][1] = 1;
74
        else
75
            order[2][1] = 2;
76
 
77
        int zoom = max_zoom < min_zoom ? min_zoom - current_zoom : current_zoom;
78
        numberOfTiles = tilesonzoomlevel(zoom);
79
        loc.setNumberOptions(QLocale::OmitGroupSeparator);
80
    }
81
 
82
    TileMapAdapter::~TileMapAdapter()
83
    {
84
    }
85
    //TODO: pull out
86
    void TileMapAdapter::zoom_in()
87
    {
88
        if (min_zoom > max_zoom)
89
        {
90
            //current_zoom = current_zoom-1;
91
            current_zoom = current_zoom > max_zoom ? current_zoom-1 : max_zoom;
92
        }
93
        else if (min_zoom < max_zoom)
94
        {
95
            //current_zoom = current_zoom+1;
96
            current_zoom = current_zoom < max_zoom ? current_zoom+1 : max_zoom;
97
        }
98
 
99
        int zoom = max_zoom < min_zoom ? min_zoom - current_zoom : current_zoom;
100
        numberOfTiles = tilesonzoomlevel(zoom);
101
 
102
    }
103
    void TileMapAdapter::zoom_out()
104
    {
105
        if (min_zoom > max_zoom)
106
        {
107
            //current_zoom = current_zoom+1;
108
            current_zoom = current_zoom < min_zoom ? current_zoom+1 : min_zoom;
109
        }
110
        else if (min_zoom < max_zoom)
111
        {
112
            //current_zoom = current_zoom-1;
113
            current_zoom = current_zoom > min_zoom ? current_zoom-1 : min_zoom;
114
        }
115
 
116
        int zoom = max_zoom < min_zoom ? min_zoom - current_zoom : current_zoom;
117
        numberOfTiles = tilesonzoomlevel(zoom);
118
    }
119
 
120
    qreal TileMapAdapter::deg_rad(qreal x) const
121
    {
122
        return x * (PI/180.0);
123
    }
124
    qreal TileMapAdapter::rad_deg(qreal x) const
125
    {
126
        return x * (180/PI);
127
    }
128
 
129
    QString TileMapAdapter::query(int x, int y, int z) const
130
    {
131
        x = xoffset(x);
132
        y = yoffset(y);
133
 
134
        int a[3] = {z, x, y};
135
        return QString(serverPath).replace(order[2][0],2, loc.toString(a[order[2][1]]))
136
                .replace(order[1][0],2, loc.toString(a[order[1][1]]))
137
                .replace(order[0][0],2, loc.toString(a[order[0][1]]));
138
 
139
    }
140
 
141
    QPoint TileMapAdapter::coordinateToDisplay(const QPointF& coordinate) const
142
    {
143
        qreal x = (coordinate.x()+180) * (numberOfTiles*mytilesize)/360.; // coord to pixel!
144
        qreal y = (1-(log(tan(PI/4+deg_rad(coordinate.y())/2)) /PI)) /2  * (numberOfTiles*mytilesize);
145
 
146
        return QPoint(int(x), int(y));
147
    }
148
 
149
    QPointF TileMapAdapter::displayToCoordinate(const QPoint& point) const
150
    {
151
        qreal longitude = (point.x()*(360/(numberOfTiles*mytilesize)))-180;
152
        qreal latitude = rad_deg(atan(sinh((1-point.y()*(2/(numberOfTiles*mytilesize)))*PI)));
153
 
154
        return QPointF(longitude, latitude);
155
 
156
    }
157
 
158
    bool TileMapAdapter::isValid(int x, int y, int z) const
159
    {
160
        if (max_zoom < min_zoom)
161
        {
162
            z= min_zoom - z;
163
        }
164
 
165
        if (x<0 || x>pow(2,z)-1 ||
166
            y<0 || y>pow(2,z)-1)
167
        {
168
            return false;
169
        }
170
        return true;
171
 
172
    }
173
    int TileMapAdapter::tilesonzoomlevel(int zoomlevel) const
174
    {
175
        return int(pow(2, zoomlevel));
176
    }
177
    int TileMapAdapter::xoffset(int x) const
178
    {
179
        return x;
180
    }
181
    int TileMapAdapter::yoffset(int y) const
182
    {
183
        return y;
184
    }
185
}