Commit 84d0710a authored by Dennis Nienhüser's avatar Dennis Nienhüser
Browse files

Traverse by input map file to improve speed

Input map files are usually the largest files and traversing them
instead of output tiles ensures they have to be loaded into memory
just once
parent c2803467
......@@ -21,24 +21,31 @@ TileDirectory::TileDirectory(const QString &baseDir, ParsingRunnerManager &manag
m_zoomLevel(QFileInfo(baseDir).baseName().toInt()),
m_tileX(-1),
m_tileY(-1),
m_tagZoomLevel(-1),
m_extension(extension),
m_filterTags(false)
{
// nothing to do
}
QSharedPointer<GeoDataDocument> TileDirectory::load(int zoomLevel, int tileX, int tileY)
TileId TileDirectory::tileFor(int zoomLevel, int tileX, int tileY) const
{
int const zoomDiff = zoomLevel - m_zoomLevel;
int const x = tileX >> zoomDiff;
int const y = tileY >> zoomDiff;
if (x == m_tileX && y == m_tileY) {
return TileId(QString(), m_zoomLevel, x, y);
}
QSharedPointer<GeoDataDocument> TileDirectory::load(int zoomLevel, int tileX, int tileY)
{
auto const tile = tileFor(zoomLevel, tileX, tileY);
if (tile.x() == m_tileX && tile.y() == m_tileY) {
return m_landmass;
}
m_tileX = x;
m_tileY = y;
QString const filename = QString("%1/%2/%3.%4").arg(m_baseDir).arg(x).arg(y).arg(m_extension);
m_tileX = tile.x();
m_tileY = tile.y();
QString const filename = QString("%1/%2/%3.%4").arg(m_baseDir).arg(tile.x()).arg(tile.y()).arg(m_extension);
m_landmass = open(filename, m_manager);
return m_landmass;
}
......@@ -47,16 +54,9 @@ GeoDataDocument* TileDirectory::clip(int zoomLevel, int tileX, int tileY)
{
QSharedPointer<GeoDataDocument> oldMap = m_landmass;
load(zoomLevel, tileX, tileY);
if (!m_clipper || oldMap != m_landmass) {
GeoDataDocument* input = m_landmass.data();
if (m_filterTags) {
QStringList const tags = tagsFilteredIn(zoomLevel);
if (zoomLevel < 17) {
m_tagsFilter = QSharedPointer<TagsFilter>(new TagsFilter(m_landmass.data(), tags));
input = m_tagsFilter->accepted();
}
}
if (!m_clipper || oldMap != m_landmass || m_tagZoomLevel != zoomLevel) {
setTagZoomLevel(zoomLevel);
GeoDataDocument* input = m_tagsFilter ? m_tagsFilter->accepted() : m_landmass.data();
m_clipper = QSharedPointer<VectorClipper>(new VectorClipper(input));
}
return m_clipper->clipTo(zoomLevel, tileX, tileY);
......@@ -172,6 +172,19 @@ QStringList TileDirectory::tagsFilteredIn(int zoomLevel) const
return tags;
}
void TileDirectory::setTagZoomLevel(int zoomLevel)
{
m_tagZoomLevel = zoomLevel;
if (m_filterTags) {
QStringList const tags = tagsFilteredIn(m_tagZoomLevel);
if (m_tagZoomLevel < 17) {
m_tagsFilter = QSharedPointer<TagsFilter>(new TagsFilter(m_landmass.data(), tags));
} else {
m_tagsFilter.clear();
}
}
}
void TileDirectory::setFilterTags(bool filter)
{
m_filterTags = filter;
......
......@@ -11,6 +11,7 @@
#include "VectorClipper.h"
#include "TagsFilter.h"
#include <TileId.h>
#include <QSharedPointer>
#include <ParsingRunnerManager.h>
......@@ -24,6 +25,7 @@ public:
QSharedPointer<GeoDataDocument> load(int zoomLevel, int tileX, int tileY);
void setFilterTags(bool filter);
TileId tileFor(int zoomLevel, int tileX, int tileY) const;
GeoDataDocument *clip(int zoomLevel, int tileX, int tileY);
QString name() const;
......@@ -31,6 +33,7 @@ public:
private:
QStringList tagsFilteredIn(int zoomLevel) const;
void setTagZoomLevel(int zoomLevel);
QString m_baseDir;
ParsingRunnerManager &m_manager;
......@@ -38,6 +41,7 @@ private:
int m_zoomLevel;
int m_tileX;
int m_tileY;
int m_tagZoomLevel;
QString m_extension;
QSharedPointer<VectorClipper> m_clipper;
QSharedPointer<TagsFilter> m_tagsFilter;
......
......@@ -265,15 +265,29 @@ int main(int argc, char *argv[])
TileDirectory mapTiles("tiles/10", manager, parser.value("extension"));
mapTiles.setFilterTags(true);
typedef QMap<QString, QVector<TileId> > Tiles;
Tiles tiles;
qint64 total = 0;
foreach(auto zoomLevel, zoomLevels) {
// @todo FIXME Assumes placemark ownership
//WayConcatenator concatenator(tagsFilter.accepted(), QStringList() << "highway=*", false);
TileIterator iter(boundingBox(inputFileName), zoomLevel);
qint64 count = 0;
qint64 const total = iter.total();
total += iter.total();
foreach(auto const &tileId, iter) {
auto const tile = TileId(QString(), zoomLevel, tileId.x(), tileId.y());
auto const mapTile = mapTiles.tileFor(zoomLevel, tileId.x(), tileId.y());
auto const name = QString("%1/%2/%3").arg(mapTile.zoomLevel()).arg(mapTile.x()).arg(mapTile.y());
tiles[name] << tile;
}
}
qint64 count = 0;
foreach(auto const &tileList, tiles) {
foreach(auto const &tileId, tileList) {
++count;
int const zoomLevel = tileId.zoomLevel();
GeoDataDocument* tile1 = mapTiles.clip(zoomLevel, tileId.x(), tileId.y());
GeoDataDocument* tile2 = loader.clip(zoomLevel, tileId.x(), tileId.y());
GeoDataDocument* combined = mergeDocuments(tile1, tile2);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment