source: subversion/applications/editors/osm-editor/qt3/LandsatManager2.cpp @ 16590

Last change on this file since 16590 was 1158, checked in by nick, 13 years ago

moved current version to qt3 directory in preparation for qt4

File size: 8.7 KB
Line 
1/*
2    Copyright (C) 2005 Nick Whitelegg, Hogweed Software, nick@hogweed.org
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
17
18 */
19#include "LandsatManager2.h"
20#include "MainWindow2.h"
21
22#include <iostream>
23using namespace std;
24
25#include <cmath>
26
27namespace OpenStreetMap
28{
29
30
31
32LandsatManager2::LandsatManager2(MainWindow2 *p, int w, int h, int ts) :
33                                                lshttp("onearth.jpl.nasa.gov")
34{
35        widget=p; dataDisplayed = false; tileSize = ts;
36        nRows = ((h-1)/tileSize) + 1; nCols = ((w-1)/tileSize) + 1;
37        tiles = new QPixmap[nRows*nCols];       
38       
39        for(int count=0; count<nRows*nCols; count++)
40                tiles[count].resize(tileSize,tileSize);
41}
42
43
44/*
45QPixmap LandsatManager2::doGrab(double w,double s,double e,double n,
46                                                        int width, int height)
47{
48        int *dimensions = new int[4];
49        QPixmap pixmap(tileSize,tileSize);
50        CURL_LOAD_DATA *landsatData = grab_landsat (w,s,e,n,width,height);
51        pixmap.loadFromData((const uchar*)landsatData->data,landsatData->nbytes);
52        free(landsatData->data);
53        free(landsatData);
54        return pixmap;
55}
56*/
57
58       
59bool LandsatManager2::doNeedMoreData()
60{
61        ScreenPos topLeftPos=widget->getMap().getScreenPos
62                                (topLeft.x,topLeft.y),
63                          bottomRightPos = widget->getMap().getScreenPos
64                                          (bottomRight.x,bottomRight.y);
65
66        return( topLeftPos.x>=0 || topLeftPos.y>=0 || 
67                        bottomRightPos.x<=widget->width() || 
68                        bottomRightPos.y<=widget->height() );
69}
70
71
72void LandsatManager2::draw(QPainter& p)
73{
74        if(dataDisplayed) 
75        {
76                ScreenPos topLeftPos=
77                                widget->getMap().getScreenPos(topLeft.x,topLeft.y);
78
79                p.drawPixmap(0,0,pixmap,-topLeftPos.x,-topLeftPos.y,
80                                                widget->width(),widget->height());
81        }
82}
83
84void LandsatManager2::drawTiles(QPainter& p)
85{
86        if(dataDisplayed)
87        {
88                for(int row=0; row<nRows; row++)
89                {
90                        for(int col=0; col<nCols; col++)
91                        {
92                                p.drawPixmap( col*tileSize, row*tileSize , 
93                                                                tiles[row*nCols+col], 0, 0, 
94                                                        tileSize, tileSize );
95                        }
96                }
97        }
98}
99
100void LandsatManager2::drawTilesNew(QPainter& p)
101{
102        if(dataDisplayed)
103        {
104                for(int count=0; count<newtiles.size(); count++)
105                {
106                        //cerr << count << " ";
107                        double a = ((double)newtiles[count]->lon) / 1000000;
108                        double b = ((double)newtiles[count]->lat) / 1000000;
109                        //cerr << " lon=" <<a << " lat=" <<b;
110                        ScreenPos pos = widget->getMap().getScreenPos (a,b);
111                        //cerr << "(" << pos.x << "," << pos.y << ") ";
112                        //if(newtiles[count]->hasData)
113                        //      cerr << "*HAS DATA* ";
114                        newtiles[count]->draw(p,pos.x,pos.y-400);
115                        //cerr << endl;
116                }
117        }
118}
119
120bool LandsatManager2::toggleDisplay()
121{
122        /*
123        if(doNeedMoreData()&&!dataDisplayed)
124                forceGrab ();
125        else
126                dataDisplayed=!dataDisplayed;
127        */
128        dataDisplayed = !dataDisplayed;
129        if(dataDisplayed)
130        {
131                //grabTiles(0,0,nCols,nRows);
132                grabTilesNew();
133        }
134        return dataDisplayed;
135}
136
137void LandsatManager2::left()
138{
139        if(dataDisplayed)
140        {
141                for(int row=0; row<nRows; row++)
142                {
143                        for(int col=nCols-1; col>0; col--)
144                        {
145                                tiles[row*nCols + col] = tiles[row*nCols + (col-1)];
146                        }
147                }
148               
149
150                // grab using lat/lon
151                //grabTiles(0,0,1,nRows);
152                grabTilesNew();
153        }
154}
155
156void LandsatManager2::right()
157{
158        if(dataDisplayed)
159        {
160                for(int row=0; row<nRows; row++)
161                {
162                        for(int col=0; col<nCols-1; col++)
163                        {
164                                tiles[row*nCols + col] = tiles[row*nCols + (col+1)];
165                        }
166                }
167
168                // grab using lat/lon
169                //grabTiles(nCols-1,0,nCols,nRows);
170                grabTilesNew();
171        }
172}
173
174void LandsatManager2::up()
175{
176        if(dataDisplayed)
177        {
178                for(int row=nRows-1; row>0; row--)
179                {
180                        for(int col=0; col<nCols; col++)
181                        {
182                                tiles[row*nCols + col] = tiles[(row-1)*nCols + col];
183                        }
184                }
185
186                // grab using lat/lon
187                //grabTiles(0,0,nCols,1);
188                grabTilesNew();
189        }
190}
191
192void LandsatManager2::down()
193{
194        if(dataDisplayed)
195        {
196                for(int row=0; row<nRows-1; row++)
197                {
198                        for(int col=0; col<nCols; col++)
199                        {
200                                tiles[row*nCols + col] = tiles[(row+1)*nCols + col];
201                        }
202                }
203
204                // grab using lat/lon
205                //grabTiles(0,nRows-1,nCols,nRows);
206                grabTilesNew();
207        }
208}
209
210void LandsatManager2::resize(int w,int h)
211{
212        nRows = ((h-1)/tileSize) + 1,
213        nCols = ((w-1)/tileSize) + 1;
214
215
216        delete[] tiles;
217        tiles = new QPixmap[nRows*nCols];
218
219        for(int row=0; row<nRows; row++)
220        {
221                for(int col=0; col<nCols; col++)
222                {
223                        tiles[row*nCols + col].resize(tileSize,tileSize); 
224                }
225
226        }
227
228        if(dataDisplayed)
229                grabAll();
230
231}
232
233void LandsatManager2::grabTiles(int x1,int y1,int x2,int y2)
234{
235        EarthPoint bottomLeft = widget->getMap().getEarthPoint
236                        (x1*tileSize, y2*tileSize),
237                                topRight = widget->getMap().getEarthPoint
238                        (x2*tileSize, y1*tileSize);
239
240
241        int *dimensions = new int[4];
242        dimensions[0] = x1;
243        dimensions[1] = y1;
244        dimensions[2] = x2;
245        dimensions[3] = y2;
246
247        QString url;
248
249        url.sprintf("/wms.cgi?request=GetMap&width=%d&height=%d&layers=global_mosaic&styles=&srs=EPSG:4326&format=image/jpeg&bbox=%lf,%lf,%lf,%lf", (x2-x1)*tileSize, (y2-y1)*tileSize, bottomLeft.x,bottomLeft.y,topRight.x,topRight.y);
250
251        cerr << "Landsat URL: " << url << endl;
252
253        lshttp.scheduleCommand("GET",url,this,
254                                                SLOT(dataReceived(const QByteArray&,void*)),
255                                                dimensions,
256                                                SLOT(handleNetCommError(const QString&)), widget);
257
258}
259
260void LandsatManager2::dataReceived(const QByteArray& response,void *dim)
261{
262        cerr << "dataReceived()"  << endl;
263
264        int *dimensions = (int *)dim;
265        int x1 = dimensions[0], y1 = dimensions[1], x2 = dimensions[2], 
266                y2 = dimensions[3];
267
268        QPixmap pixmap(tileSize,tileSize);
269        pixmap.loadFromData(response);
270
271        for(int row=y1; row<=y2-1; row++)
272        {
273                for(int col=x1; col<=x2-1; col++)
274                {
275                        copyBlt (&tiles[row*nCols+col],0,0,
276                                        &pixmap,(col-x1)*tileSize,(row-y1)*tileSize , 
277                                        tileSize, tileSize );
278                }
279        }
280
281        delete[] dimensions;
282}
283
284
285// this should be called every time the screen state changes
286void LandsatManager2::grabTilesNew()
287{
288        // want a constant dimension of 400x400
289        double pixelsperll = widget->getMap().getScale();
290
291        // grab 400x400 pixel tiles
292        int llstep = (400 / pixelsperll) * 1000000; 
293
294        EarthPoint bottomLeft = widget->getMap().getBottomLeft(),
295                                topRight = widget->getMap().getTopRight();
296
297        cerr << "bottomLeft: lon=" << bottomLeft.x << " lat=" <<bottomLeft.y
298                        << endl;
299        cerr << "topRight: lon=" << topRight.x << " lat=" <<topRight.y
300                        << endl;
301        int lonmin = ( floor((bottomLeft.x*1000000) / llstep)) * llstep,
302            lonmax = ( ceil((topRight.x*1000000) / llstep)) * llstep,
303            latmin = ( floor((bottomLeft.y*1000000) / llstep)) * llstep,
304            latmax = ( ceil((topRight.y*1000000) / llstep)) * llstep;
305
306
307        cerr << "lonmin:" << lonmin << endl;
308        cerr << "lonmax:" << lonmax << endl;
309        cerr << "latmin:" << latmin << endl;
310        cerr << "latmax:" << latmax << endl;
311
312        // Erase old tiles no longer in view
313        /* no don't do this - it's be better to cache them
314        vector<Tile*>::iterator j;
315
316        for(vector<Tile*>::iterator i=newtiles.begin(); i!=newtiles.end(); i++)
317        {
318                if((*i)->lat<lonmin||(*i)->lon>=lonmax||(*i)->lat<latmin||
319                                                (*i)->lat>=latmax)
320                {
321                        delete *i;
322                        newtiles.erase(i);
323                        i--;
324                }
325        }
326        */
327
328        // Loop through tiles in view - if any don't exist yet, grab them
329        for(int loncount=lonmin; loncount<lonmax; loncount+=llstep)
330        {
331                for(int latcount=latmin; latcount<latmax; latcount+=llstep)
332                {
333                        if(!tileExists(latcount,loncount))
334                        {
335                                int tilewidth = 400; 
336                                int tileheight =  400; 
337                                Tile *tile = new Tile (latcount,loncount,tilewidth,tileheight);
338                                newtiles.push_back(tile);
339                                QString url = tile->getURL(llstep);
340                                cerr<<"Tile URL = " << url << endl;
341                                lshttp.scheduleCommand("GET",url,this,
342                                                SLOT(newDataReceived(const QByteArray&,void*)),tile,
343                                                SLOT(handleNetCommError(const QString&)), widget);
344                        }
345                }
346        }
347}
348
349void LandsatManager2::clearTiles()
350{
351        // 090706 clear any pending requests - otherwise there will be an
352        // almighty crash :-)
353        lshttp.clearRequests();
354
355        vector<Tile*>::iterator i = newtiles.begin();
356        while(i!=newtiles.end())
357        {
358        delete *i;
359                newtiles.erase(i);
360        }
361}
362
363void LandsatManager2::newDataReceived(const QByteArray& response,void *t)
364{
365
366        Tile *tile = (Tile *)t;
367        cerr << "newDataReceived()"  << endl;
368        cerr << "lat=" << tile->lat << " lon=" << tile->lon << endl;
369        tile->pixmap.loadFromData(response);
370        tile->hasData = true;
371        widget->update();
372}
373
374bool LandsatManager2::tileExists(int lat,int lon)
375{
376        for(int count=0; count<newtiles.size(); count++)
377        {
378                if(newtiles[count]->lon==lon && newtiles[count]->lat==lat)
379                        return true;
380        }
381        return false;
382}
383
384}
Note: See TracBrowser for help on using the repository browser.