[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [marble] tools/vectorosm-tilecreator: Use a pyramid approach to speed up creation of input osm tiles
From: Dennis_Nienhüser <nienhueser () kde ! org>
Date: 2016-11-16 19:37:05
Message-ID: E1c7613-0004cy-23 () code ! kde ! org
[Download RAW message or body]
Git commit 6855d0cea19b3212c15760d30aaa2400bcd52755 by Dennis Nienhüser.
Committed on 16/11/2016 at 19:36.
Pushed by nienhueser into branch 'master'.
Use a pyramid approach to speed up creation of input osm tiles.
M +58 -17 tools/vectorosm-tilecreator/TileDirectory.cpp
M +1 -0 tools/vectorosm-tilecreator/TileDirectory.h
http://commits.kde.org/marble/6855d0cea19b3212c15760d30aaa2400bcd52755
diff --git a/tools/vectorosm-tilecreator/TileDirectory.cpp \
b/tools/vectorosm-tilecreator/TileDirectory.cpp index 85ecd8a..3387e49 100644
--- a/tools/vectorosm-tilecreator/TileDirectory.cpp
+++ b/tools/vectorosm-tilecreator/TileDirectory.cpp
@@ -14,6 +14,7 @@
#include "MarbleZipReader.h"
#include <GeoDataLatLonAltBox.h>
#include "PeakAnalyzer.h"
+#include "TileCoordsPyramid.h"
#include <QFileInfo>
#include <QDebug>
@@ -347,8 +348,13 @@ void TileDirectory::setBoundingPolygon(const QString &file)
void TileDirectory::createTiles() const
{
- QSharedPointer<GeoDataDocument> map;
- QSharedPointer<VectorClipper> clipper;
+ if (m_tileType == OpenStreetMap) {
+ createOsmTiles();
+ return;
+ }
+
+ QSharedPointer<GeoDataDocument> map = open(m_inputFile, m_manager);
+ QSharedPointer<VectorClipper> clipper = QSharedPointer<VectorClipper>(new \
VectorClipper(map.data(), m_zoomLevel)); TileIterator iter(m_boundingBox, \
m_zoomLevel); qint64 count = 0;
foreach(auto const &tileId, iter) {
@@ -360,17 +366,58 @@ void TileDirectory::createTiles() const
}
printProgress(count / double(iter.total()));
- cout << " Creating " << (m_tileType == OpenStreetMap ? "osm" : "landmass");
- cout << " cache tile " << count << "/" << iter.total() << " (";
+ cout << " Creating landmass cache tile " << count << "/" << iter.total() << \
" (";
cout << m_zoomLevel << "/" << tileId.x() << "/" << tileId.y() << ')' << \
string(20, ' ') << '\r'; cout.flush();
QDir().mkpath(outputDir);
- if (m_tileType == OpenStreetMap) {
+ auto tile = clipper->clipTo(m_zoomLevel, tileId.x(), tileId.y());
+ if (!GeoDataDocumentWriter::write(outputFile, *tile)) {
+ qWarning() << "Failed to write tile" << outputFile;
+ }
+ }
+ printProgress(1.0);
+ cout << " landmass cache tiles complete." << string(20, ' ') << endl;
+}
+
+void TileDirectory::createOsmTiles() const
+{
+ int westX, northY, eastX, southY;
+ GeoSceneMercatorTileProjection tileProjection;
+ tileProjection.tileIndexes(m_boundingBox, m_zoomLevel, westX, northY, eastX, \
southY); + TileCoordsPyramid pyramid(0, m_zoomLevel);
+ pyramid.setBottomLevelCoords(QRect(QPoint(westX, northY), QPoint(eastX, \
southY))); +
+ qint64 const maxCount = pyramid.tilesCount();
+ bool first = true;
+ for (int zoomLevel=0; zoomLevel <= m_zoomLevel; ++zoomLevel) {
+ QRect const rect = pyramid.coords(zoomLevel);
+ if (zoomLevel < m_zoomLevel && rect.width()*rect.height() < 2) {
+ continue;
+ }
+
+ TileIterator iter(m_boundingBox, zoomLevel);
+ qint64 count = 0;
+ foreach(auto const &tileId, iter) {
+ ++count;
+ QString const inputFile = first ? m_inputFile : \
QString("%1/osm/%2/%3/%4.o5m"). + \
arg(m_cacheDir).arg(zoomLevel-1).arg(tileId.x()>>1).arg(tileId.y()>>1); + \
QString const outputDir = \
QString("%1/osm/%2/%3").arg(m_cacheDir).arg(zoomLevel).arg(tileId.x()); + \
QString const outputFile = QString("%1/%2.o5m").arg(outputDir).arg(tileId.y()); + \
if (QFileInfo(outputFile).exists()) { + continue;
+ }
+
+ printProgress(count / double(maxCount));
+ cout << " Creating osm cache tile " << count << "/" << maxCount << " (";
+ cout << zoomLevel << "/" << tileId.x() << "/" << tileId.y() << ')' << \
string(20, ' ') << '\r'; + cout.flush();
+
+ QDir().mkpath(outputDir);
QString const output = QString("-o=%1").arg(outputFile);
GeoDataLatLonBox tileBoundary;
- m_tileProjection.geoCoordinates(m_zoomLevel, tileId.x(), tileId.y(), \
tileBoundary); + m_tileProjection.geoCoordinates(zoomLevel, tileId.x(), \
tileId.y(), tileBoundary);
double const minLon = tileBoundary.west(GeoDataCoordinates::Degree);
double const maxLon = tileBoundary.east(GeoDataCoordinates::Degree);
@@ -379,25 +426,19 @@ void TileDirectory::createTiles() const
QString const bbox = \
QString("-b=%1,%2,%3,%4").arg(minLon).arg(minLat).arg(maxLon).arg(maxLat); QProcess \
osmconvert;
osmconvert.start("osmconvert", QStringList() << "--drop-author" << \
"--drop-version"
- << "--complete-ways" << "--complex-ways" << bbox << \
output << m_inputFile); + << "--complete-ways" << \
"--complex-ways" << bbox << output << inputFile); \
osmconvert.waitForFinished(10*60*1000); if (osmconvert.exitCode() != 0) {
qWarning() << osmconvert.readAllStandardError();
qWarning() << "osmconvert failed: " << osmconvert.errorString();
}
- } else {
- if (!map) {
- map = open(m_inputFile, m_manager);
- clipper = QSharedPointer<VectorClipper>(new \
VectorClipper(map.data(), m_zoomLevel));
- }
- auto tile = clipper->clipTo(m_zoomLevel, tileId.x(), tileId.y());
- if (!GeoDataDocumentWriter::write(outputFile, *tile)) {
- qWarning() << "Failed to write tile" << outputFile;
- }
}
+ first = false;
}
+
printProgress(1.0);
- cout << " " << (m_tileType == OpenStreetMap ? "osm" : "landmass") << " cache \
tiles complete." << endl; + cout << " osm cache tiles complete." << string(20, ' \
') << endl; +
}
int TileDirectory::innerNodes(const TileId &tile) const
diff --git a/tools/vectorosm-tilecreator/TileDirectory.h \
b/tools/vectorosm-tilecreator/TileDirectory.h index d32bd3f..6e0b6be 100644
--- a/tools/vectorosm-tilecreator/TileDirectory.h
+++ b/tools/vectorosm-tilecreator/TileDirectory.h
@@ -71,6 +71,7 @@ public:
void setBoundingBox(const GeoDataLatLonBox &boundingBox);
void setBoundingPolygon(const QString &filename);
void createTiles() const;
+ void createOsmTiles() const;
int innerNodes(const TileId &tile) const;
static void printProgress(double progress, int barWidth=40);
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic