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 "layer.h" |
||
27 | namespace qmapcontrol |
||
28 | { |
||
29 | Layer::Layer(QString layername, MapAdapter* mapadapter, enum LayerType layertype, bool takeevents) |
||
30 | :visible(true), mylayername(layername), mylayertype(layertype), mapAdapter(mapadapter), takeevents(takeevents), myoffscreenViewport(QRect(0,0,0,0)) |
||
31 | { |
||
32 | //qDebug() << "creating new Layer: " << layername << ", type: " << contents; |
||
33 | //qDebug() << this->layertype; |
||
34 | } |
||
35 | |||
36 | Layer::~Layer() |
||
37 | { |
||
38 | delete mapAdapter; |
||
39 | } |
||
40 | |||
41 | void Layer::setSize(QSize size) |
||
42 | { |
||
43 | this->size = size; |
||
44 | screenmiddle = QPoint(size.width()/2, size.height()/2); |
||
45 | //QMatrix mat; |
||
46 | //mat.translate(480/2, 640/2); |
||
47 | //mat.rotate(45); |
||
48 | //mat.translate(-480/2,-640/2); |
||
49 | //screenmiddle = mat.map(screenmiddle); |
||
50 | } |
||
51 | |||
52 | QString Layer::layername() const |
||
53 | { |
||
54 | return mylayername; |
||
55 | } |
||
56 | |||
57 | const MapAdapter* Layer::mapadapter() const |
||
58 | { |
||
59 | return mapAdapter; |
||
60 | } |
||
61 | |||
62 | void Layer::setVisible(bool visible) |
||
63 | { |
||
64 | this->visible = visible; |
||
65 | emit(updateRequest()); |
||
66 | } |
||
67 | |||
68 | void Layer::addGeometry(Geometry* geom) |
||
69 | { |
||
70 | //qDebug() << geom->getName() << ", " << geom->getPoints().at(0)->getWidget(); |
||
71 | |||
72 | geometries.append(geom); |
||
73 | emit(updateRequest(geom->boundingBox())); |
||
74 | //a geometry can request a redraw, e.g. when its position has been changed |
||
75 | connect(geom, SIGNAL(updateRequest(QRectF)), |
||
76 | this, SIGNAL(updateRequest(QRectF))); |
||
77 | } |
||
78 | void Layer::removeGeometry(Geometry* geometry) |
||
79 | { |
||
80 | for (int i=0; i<geometries.count(); i++) |
||
81 | { |
||
82 | if (geometry == geometries.at(i)) |
||
83 | { |
||
84 | disconnect(geometry); |
||
85 | geometries.removeAt(i); |
||
86 | //delete geometry; |
||
87 | } |
||
88 | } |
||
89 | } |
||
90 | |||
91 | void Layer::clearGeometries() |
||
92 | { |
||
93 | foreach(Geometry *geometry, geometries){ |
||
94 | disconnect(geometry); |
||
95 | } |
||
96 | geometries.clear(); |
||
97 | } |
||
98 | |||
99 | bool Layer::isVisible() const |
||
100 | { |
||
101 | return visible; |
||
102 | } |
||
103 | void Layer::zoomIn() const |
||
104 | { |
||
105 | mapAdapter->zoom_in(); |
||
106 | } |
||
107 | void Layer::zoomOut() const |
||
108 | { |
||
109 | mapAdapter->zoom_out(); |
||
110 | } |
||
111 | |||
112 | void Layer::mouseEvent(const QMouseEvent* evnt, const QPoint mapmiddle_px) |
||
113 | { |
||
114 | if (takesMouseEvents()) |
||
115 | { |
||
116 | if (evnt->button() == Qt::LeftButton && evnt->type() == QEvent::MouseButtonPress) |
||
117 | { |
||
118 | // check for collision |
||
119 | QPointF c = mapAdapter->displayToCoordinate(QPoint(evnt->x()-screenmiddle.x()+mapmiddle_px.x(), |
||
120 | evnt->y()-screenmiddle.y()+mapmiddle_px.y())); |
||
121 | Point* tmppoint = new Point(c.x(), c.y()); |
||
122 | for (int i=0; i<geometries.count(); i++) |
||
123 | { |
||
124 | if (geometries.at(i)->isVisible() && geometries.at(i)->Touches(tmppoint, mapAdapter)) |
||
125 | |||
126 | //if (geometries.at(i)->Touches(c, mapAdapter)) |
||
127 | { |
||
128 | emit(geometryClicked(geometries.at(i), QPoint(evnt->x(), evnt->y()))); |
||
129 | } |
||
130 | } |
||
131 | delete tmppoint; |
||
132 | } |
||
133 | } |
||
134 | } |
||
135 | |||
136 | bool Layer::takesMouseEvents() const |
||
137 | { |
||
138 | return takeevents; |
||
139 | } |
||
140 | |||
141 | void Layer::drawYourImage(QPainter* painter, const QPoint mapmiddle_px) const |
||
142 | { |
||
143 | if (mylayertype == MapLayer) |
||
144 | { |
||
145 | //qDebug() << ":: " << mapmiddle_px; |
||
146 | //QMatrix mat; |
||
147 | //mat.translate(480/2, 640/2); |
||
148 | //mat.rotate(45); |
||
149 | //mat.translate(-480/2,-640/2); |
||
150 | |||
151 | //mapmiddle_px = mat.map(mapmiddle_px); |
||
152 | //qDebug() << ":: " << mapmiddle_px; |
||
153 | _draw(painter, mapmiddle_px); |
||
154 | } |
||
155 | |||
156 | drawYourGeometries(painter, QPoint(mapmiddle_px.x()-screenmiddle.x(), mapmiddle_px.y()-screenmiddle.y()), myoffscreenViewport); |
||
157 | } |
||
158 | void Layer::drawYourGeometries(QPainter* painter, const QPoint mapmiddle_px, QRect viewport) const |
||
159 | { |
||
160 | QPoint offset; |
||
161 | if (mylayertype == MapLayer) |
||
162 | offset = mapmiddle_px; |
||
163 | else |
||
164 | offset = mapmiddle_px-screenmiddle; |
||
165 | |||
166 | painter->translate(-mapmiddle_px+screenmiddle); |
||
167 | for (int i=0; i<geometries.count(); i++) |
||
168 | { |
||
169 | geometries.at(i)->draw(painter, mapAdapter, viewport, offset); |
||
170 | } |
||
171 | painter->translate(mapmiddle_px-screenmiddle); |
||
172 | |||
173 | } |
||
174 | void Layer::_draw(QPainter* painter, const QPoint mapmiddle_px) const |
||
175 | { |
||
176 | // screen middle rotieren... |
||
177 | |||
178 | int tilesize = mapAdapter->tilesize(); |
||
179 | int cross_x = int(mapmiddle_px.x())%tilesize; // position on middle tile |
||
180 | int cross_y = int(mapmiddle_px.y())%tilesize; |
||
181 | //qDebug() << screenmiddle << " - " << cross_x << ", " << cross_y; |
||
182 | |||
183 | // calculate how many surrounding tiles have to be drawn to fill the display |
||
184 | int space_left = screenmiddle.x() - cross_x; |
||
185 | int tiles_left = space_left/tilesize; |
||
186 | if (space_left>0) |
||
187 | tiles_left+=1; |
||
188 | |||
189 | int space_above = screenmiddle.y() - cross_y; |
||
190 | int tiles_above = space_above/tilesize; |
||
191 | if (space_above>0) |
||
192 | tiles_above+=1; |
||
193 | |||
194 | int space_right = screenmiddle.x() - (tilesize-cross_x); |
||
195 | int tiles_right = space_right/tilesize; |
||
196 | if (space_right>0) |
||
197 | tiles_right+=1; |
||
198 | |||
199 | int space_bottom = screenmiddle.y() - (tilesize-cross_y); |
||
200 | int tiles_bottom = space_bottom/tilesize; |
||
201 | if (space_bottom>0) |
||
202 | tiles_bottom+=1; |
||
203 | |||
204 | //int tiles_displayed = 0; |
||
205 | int mapmiddle_tile_x = mapmiddle_px.x()/tilesize; |
||
206 | int mapmiddle_tile_y = mapmiddle_px.y()/tilesize; |
||
207 | |||
208 | const QPoint from = QPoint((-tiles_left+mapmiddle_tile_x)*tilesize, (-tiles_above+mapmiddle_tile_y)*tilesize); |
||
209 | const QPoint to = QPoint((tiles_right+mapmiddle_tile_x+1)*tilesize, (tiles_bottom+mapmiddle_tile_y+1)*tilesize); |
||
210 | |||
211 | myoffscreenViewport = QRect(from, to); |
||
212 | |||
213 | if (mapAdapter->isValid(mapmiddle_tile_x, mapmiddle_tile_y, mapAdapter->currentZoom())) |
||
214 | { |
||
215 | painter->drawPixmap(-cross_x+size.width(), |
||
216 | -cross_y+size.height(), |
||
217 | ImageManager::instance()->getImage(mapAdapter->host(), mapAdapter->query(mapmiddle_tile_x, mapmiddle_tile_y, mapAdapter->currentZoom()))); |
||
218 | } |
||
219 | |||
220 | for (int i=-tiles_left+mapmiddle_tile_x; i<=tiles_right+mapmiddle_tile_x; i++) |
||
221 | { |
||
222 | for (int j=-tiles_above+mapmiddle_tile_y; j<=tiles_bottom+mapmiddle_tile_y; j++) |
||
223 | { |
||
224 | // check if image is valid |
||
225 | if (!(i==mapmiddle_tile_x && j==mapmiddle_tile_y)) |
||
226 | if (mapAdapter->isValid(i, j, mapAdapter->currentZoom())) |
||
227 | { |
||
228 | |||
229 | painter->drawPixmap(((i-mapmiddle_tile_x)*tilesize)-cross_x+size.width(), |
||
230 | ((j-mapmiddle_tile_y)*tilesize)-cross_y+size.height(), |
||
231 | ImageManager::instance()->getImage(mapAdapter->host(), mapAdapter->query(i, j, mapAdapter->currentZoom()))); |
||
232 | //if (QCoreApplication::hasPendingEvents()) |
||
233 | // QCoreApplication::processEvents(); |
||
234 | } |
||
235 | } |
||
236 | } |
||
237 | |||
238 | |||
239 | // PREFETCHING |
||
240 | int upper = mapmiddle_tile_y-tiles_above-1; |
||
241 | int right = mapmiddle_tile_x+tiles_right+1; |
||
242 | int left = mapmiddle_tile_x-tiles_right-1; |
||
243 | int lower = mapmiddle_tile_y+tiles_bottom+1; |
||
244 | |||
245 | int j = upper; |
||
246 | for (int i=left; i<=right; i++) |
||
247 | { |
||
248 | if (mapAdapter->isValid(i, j, mapAdapter->currentZoom())) |
||
249 | ImageManager::instance()->prefetchImage(mapAdapter->host(), mapAdapter->query(i, j, mapAdapter->currentZoom())); |
||
250 | } |
||
251 | j = lower; |
||
252 | for (int i=left; i<=right; i++) |
||
253 | { |
||
254 | if (mapAdapter->isValid(i, j, mapAdapter->currentZoom())) |
||
255 | ImageManager::instance()->prefetchImage(mapAdapter->host(), mapAdapter->query(i, j, mapAdapter->currentZoom())); |
||
256 | } |
||
257 | int i = left; |
||
258 | for (int j=upper+1; j<=lower-1; j++) |
||
259 | { |
||
260 | if (mapAdapter->isValid(i, j, mapAdapter->currentZoom())) |
||
261 | ImageManager::instance()->prefetchImage(mapAdapter->host(), mapAdapter->query(i, j, mapAdapter->currentZoom())); |
||
262 | } |
||
263 | i = right; |
||
264 | for (int j=upper+1; j<=lower-1; j++) |
||
265 | { |
||
266 | if (mapAdapter->isValid(i, j, mapAdapter->currentZoom())) |
||
267 | ImageManager::instance()->prefetchImage(mapAdapter->host(), mapAdapter->query(i, j, mapAdapter->currentZoom())); |
||
268 | } |
||
269 | } |
||
270 | |||
271 | QRect Layer::offscreenViewport() const |
||
272 | { |
||
273 | return myoffscreenViewport; |
||
274 | } |
||
275 | |||
276 | void Layer::moveWidgets(const QPoint mapmiddle_px) const |
||
277 | { |
||
278 | for (int i=0; i<geometries.count(); i++) |
||
279 | { |
||
280 | const Geometry* geom = geometries.at(i); |
||
281 | if (geom->GeometryType == "Point") |
||
282 | { |
||
283 | if (((Point*)geom)->widget()!=0) |
||
284 | { |
||
285 | QPoint topleft_relative = QPoint(mapmiddle_px-screenmiddle); |
||
286 | ((Point*)geom)->drawWidget(mapAdapter, topleft_relative); |
||
287 | } |
||
288 | } |
||
289 | } |
||
290 | } |
||
291 | Layer::LayerType Layer::layertype() const |
||
292 | { |
||
293 | return mylayertype; |
||
294 | } |
||
295 | |||
296 | void Layer::setMapAdapter(MapAdapter* mapadapter) |
||
297 | { |
||
298 | |||
299 | mapAdapter = mapadapter; |
||
300 | } |
||
301 | } |