Hello,

I think you didn't get my first emails about this subject so I send it here again.

When zooming is at an low level and you want to download OSM-data there comes this very serious error with the hint that zooming in could help. So downloading large areas at once is not possible. To fix this I changed the code to let merkaartor automatically download the data in several parts/tiles. Through this you can download areas as large as you want to without that error, but it needs a lot of time.

Please tell me if you think this is a good thing and maybe someone can apply the patch to the svn-repos.


You can vary the size of the parts with the #define directive for MAXLON and MAXLAT. The highest possible value is 0.25° (taken from the api documentation on wiki.openstreetmap.org). Currently I set the values to 0.0005 Rad for better testing and faster results (a 0.25° part needs some time). You may also want to try #define DEBUG_TILES.


thx in advance,
timo
Index: Map/DownloadOSM.cpp
===================================================================
--- Map/DownloadOSM.cpp (revision 8128)
+++ Map/DownloadOSM.cpp (working copy)
@@ -30,7 +30,16 @@
 // #define DEBUG_EVERY_CALL
 // #define DEBUG_MAPCALL_ONLY
 // #define DEBUG_NONGET_CALL
+// #define DEBUG_TILES
 
+
+#ifdef DEBUG_TILES
+#include "Command/DocumentCommands.h"
+#include "Command/FeatureCommands.h"
+#include "Map/Road.h"
+#include "Map/TrackPoint.h"
+#endif
+
 /* DOWNLOADER */
 
 Downloader::Downloader(const QString& aWeb, const QString& aUser, const 
QString& aPwd, bool aUseProxy, const QString& aProxyHost, int aProxyPort)
@@ -104,6 +113,19 @@
        b->raise();
 }
 
+#ifdef DEBUG_TILES
+void debugTile(QString id, const CoordBox& box, MapLayer * theLayer)
+{
+       Road *tile = new Road;
+       tile->add(new TrackPoint(box.topLeft()));
+       tile->add(new TrackPoint(box.bottomLeft()));
+       tile->add(new TrackPoint(box.bottomRight()));
+       tile->add(new TrackPoint(box.topRight()));
+       tile->add(new TrackPoint(box.topLeft()));
+       new AddFeatureCommand(theLayer, tile, true);
+       tile->setId(id);
+}
+#endif // DEBUG_TILES
 
 #define CHUNK 4096
 
@@ -365,50 +387,109 @@
        return URL;
 }
 
-bool downloadOSM(QMainWindow* aParent, const QString& aWeb, const QString& 
aUser, const QString& aPassword, bool UseProxy, const QString& ProxyHost, int 
ProxyPort, const CoordBox& aBox , MapDocument* theDocument, MapLayer* theLayer)
+#define MAXLON 0.0005
+//#define MAXLON angToRad(0.25)
+#define MAXLAT 0.0005
+//#define MAXLAT angToRad(0.25)
+
+bool downloadOSM(QMainWindow* aParent, const QString& aWeb, const QString& 
aUser, const QString& aPassword, bool UseProxy, const QString& ProxyHost, int 
ProxyPort, const CoordBox& dBox , MapDocument* theDocument, MapLayer* theLayer)
 {
+               
+       int tile[2] = { 1, 1}, tilesVert = 1, tilesHoriz = 1; // tile[0] is the 
current line (vert) and tile[1] is the current column (horiz)
+       CoordBox aBox(Coord(0, 0), Coord(0, 0));
+
+       if (dBox.lonDiff() > MAXLON || dBox.latDiff() > MAXLAT)
+       {
+               double tilesHorizD = dBox.lonDiff() / MAXLON;
+               tilesHoriz = tilesHorizD - (int)tilesHorizD == 0 ? 
(int)tilesHorizD : (int)tilesHorizD + 1;
+
+               double tilesVertD = dBox.latDiff() / MAXLAT;
+               tilesVert = tilesVertD - (int)tilesVertD == 0 ? (int)tilesVertD 
: (int)tilesVertD + 1;
+
+               QMessageBox::warning(aParent, 
QApplication::translate("Downloader", "Downloading in tiles"), 
QApplication::translate("Downloader","Your selection will be downloaded in %1 
tiles.").arg(tilesHoriz * tilesVert));
+       } 
+       
        if (checkForConflicts(theDocument))
        {
                
QMessageBox::warning(aParent,QApplication::translate("Downloader","Unresolved 
conflicts"), QApplication::translate("Downloader","Please resolve existing 
conflicts first"));
                return false;
        }
        Downloader Rcv(aWeb, aUser, aPassword, UseProxy, ProxyHost, ProxyPort);
-       QString URL = Rcv.getURLToMap();
-       URL = 
URL.arg(radToAng(aBox.bottomLeft().lon())).arg(radToAng(aBox.bottomLeft().lat())).arg(radToAng(aBox.topRight().lon())).arg(radToAng(aBox.topRight().lat()));
        QProgressDialog* ProgressDialog = new QProgressDialog(aParent);
        ProgressDialog->setWindowModality(Qt::ApplicationModal);
        QProgressBar* Bar = new QProgressBar(ProgressDialog);
        Bar->setTextVisible(false);
        ProgressDialog->setBar(Bar);
+       ProgressDialog->setMaximum(11);
        ProgressDialog->setMinimumDuration(0);
-       
ProgressDialog->setLabelText(QApplication::translate("Downloader","Downloading 
from OSM (connecting)"));
-       ProgressDialog->setMaximum(11);
        Rcv.setAnimator(ProgressDialog,Bar,true);
 
-       if (!Rcv.go(URL))
+       #ifdef DEBUG_TILES
+       debugTile("id_all", dBox, theLayer);
+       #endif
+
+       QString URL, type;
+       QByteArray content("<osm>"); // <osm> is the root-tag
+       while (tile[0] <= tilesVert)
        {
-               aParent->setCursor(QCursor(Qt::ArrowCursor));
-               delete ProgressDialog;
-               return false;
+
+               if (tile[1] == 1) // when we are in the first column we have to 
adjust the height of the box
+                       aBox = CoordBox(Coord( dBox.topLeft().lat() - (tile[0] 
- 1) * MAXLAT, dBox.topLeft().lon()), Coord(dBox.topLeft().lat() - tile[0] * 
MAXLAT, dBox.topLeft().lon()));
+       
+               if (tile[0] == tilesVert && tile[1] == tilesHoriz) aBox = 
CoordBox(aBox.topRight(), dBox.bottomRight()); // last tile
+               else if (tile[0] == tilesVert) aBox = CoordBox(aBox.topRight(), 
Coord(dBox.bottomRight().lat(), aBox.topRight().lon() + MAXLON)); // last line 
vert
+               else if (tile[1] == tilesHoriz) aBox = 
CoordBox(aBox.topRight(), Coord(aBox.bottomRight().lat(), 
dBox.topRight().lon())); // last line horiz
+               else aBox = CoordBox(aBox.topRight(), 
Coord(aBox.bottomRight().lat(), aBox.topRight().lon() + MAXLON)); // normal 
next tile
+
+               #ifdef DEBUG_TILES
+               debugTile(QString("id_tile_%1").arg((tile[0]-1)*tilesHoriz + 
tile[1]), aBox, theLayer);
+               #endif
+
+               URL = Rcv.getURLToMap();
+               URL = 
URL.arg(radToAng(aBox.bottomLeft().lon())).arg(radToAng(aBox.bottomLeft().lat())).arg(radToAng(aBox.topRight().lon())).arg(radToAng(aBox.topRight().lat()));
+
+               Bar->reset();
+               ProgressDialog->setMaximum(11);
+               ProgressDialog->setMinimumDuration(0);
+               
ProgressDialog->setLabelText(QApplication::translate("Downloader","Downloading 
tile %1 from OSM (connecting)").arg((tile[0]-1)*tilesHoriz + tile[1]));
+
+               if (!Rcv.go(URL))
+               {
+                       aParent->setCursor(QCursor(Qt::ArrowCursor));
+                       delete ProgressDialog;
+                       return false;
+               }
+
+               #ifdef DEBUG_MAPCALL_ONLY
+               showDebug("GET", URL,QByteArray(), Rcv.content());
+               #endif
+
+               int x = Rcv.resultCode();
+               switch (x)
+               {
+               case 200:
+                       break;
+               case 401:
+                       
QMessageBox::warning(aParent,QApplication::translate("Downloader","Download 
failed"),QApplication::translate("Downloader","Username/password invalid"));
+                       return false;
+               default:
+                       
QMessageBox::warning(aParent,QApplication::translate("Downloader","Download 
failed"),QApplication::translate("Downloader","Unexpected http status code 
(%1)\nServer message is '%2'\nPossibly reducing the download area 
helps.").arg(x).arg(Rcv.resultText()));
+                       return false;
+               }
+
+               QByteArray contentPart = Rcv.content();
+               contentPart.remove(0, contentPart.indexOf("\n", 
contentPart.indexOf("\n"))); // we have to delete the first two lines because 
of <xml> and <osm> tags
+               content.append(contentPart.replace("</osm>", "")); // we don't 
need the closing </osm>-tag here
+       
+               tile[1]++;
+               if (tile[1] > tilesHoriz) { tile[1] = 1; tile[0]++; }
        }
        delete ProgressDialog;
-#ifdef DEBUG_MAPCALL_ONLY
-       showDebug("GET", URL,QByteArray(), Rcv.content());
-#endif
-       int x = Rcv.resultCode();
-       switch (x)
-       {
-       case 200:
-               break;
-       case 401:
-               
QMessageBox::warning(aParent,QApplication::translate("Downloader","Download 
failed"),QApplication::translate("Downloader","Username/password invalid"));
-               return false;
-       default:
-               
QMessageBox::warning(aParent,QApplication::translate("Downloader","Download 
failed"),QApplication::translate("Downloader","Unexpected http status code 
(%1)\nServer message is '%2'\nPossibly reducing the download area 
helps.").arg(x).arg(Rcv.resultText()));
-               return false;
-       }
+
+       content.append("</osm>"); // here we can close the root-tag
        Downloader Down(aWeb, aUser, aPassword, UseProxy, ProxyHost, ProxyPort);
-       bool OK = importOSM(aParent, Rcv.content(), theDocument, theLayer, 
&Down);
+       bool OK = importOSM(aParent, content, theDocument, theLayer, &Down);
+
        return OK;
 }
 
@@ -551,14 +632,14 @@
                                end = link.indexOf("&", start);
                                int zoom = link.mid(start, end - start).toInt();
 
-
+                       /*
                                if (zoom <= 10) {
                                        QMessageBox::warning(dlg, 
QApplication::translate("Downloader", "Zoom factor too low"),
                                                
QApplication::translate("Downloader", "Please use a higher zoom factor!"));
                                        retry = true;
                                }
                                else {
-
+                       */
                                        double zoomD;
 
                                        /* zoom-levels taken from 
http://wiki.openstreetmap.org/index.php/Zoom_levels */
@@ -586,7 +667,7 @@
 
                                        /* the OSM link contains the 
coordinates from the middle of the visible map so we have to add and sub zoomD 
*/
                                        Clip = 
CoordBox(Coord(angToRad(lat-zoomD), angToRad(lon-zoomD)), 
Coord(angToRad(lat+zoomD), angToRad(lon+zoomD)));
-                               }
+                       //      }
                        }
                        else if (ui.FromMap->isChecked())
                        {
_______________________________________________
Merkaartor mailing list
[email protected]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/merkaartor

Reply via email to