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