[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [marble] tools/vectorosm-tilecreator: Add a tool for server-side dynamic tile generation
From: Dennis_Nienhüser <nienhueser () kde ! org>
Date: 2016-12-04 16:52:58
Message-ID: E1cDa26-0007F1-KK () code ! kde ! org
[Download RAW message or body]
Git commit fa86770842341286f70ae08c8aaa48b0bfd73de2 by Dennis Nienhüser.
Committed on 04/12/2016 at 16:53.
Pushed by nienhueser into branch 'master'.
Add a tool for server-side dynamic tile generation
M +3 -0 tools/vectorosm-tilecreator/CMakeLists.txt
A +165 -0 tools/vectorosm-tilecreator/vectorosm-cachetiles.cpp [License: \
LGPL]
https://commits.kde.org/marble/fa86770842341286f70ae08c8aaa48b0bfd73de2
diff --git a/tools/vectorosm-tilecreator/CMakeLists.txt \
b/tools/vectorosm-tilecreator/CMakeLists.txt index f39d2fc..607273d 100644
--- a/tools/vectorosm-tilecreator/CMakeLists.txt
+++ b/tools/vectorosm-tilecreator/CMakeLists.txt
@@ -36,3 +36,6 @@ target_link_libraries(${TARGET} marblewidget Qt5::Sql)
add_executable(marble-vectorosm-tilecreator vectorosm-tilecreator.cpp)
target_link_libraries(marble-vectorosm-tilecreator ${TARGET})
+
+add_executable(marble-vectorosm-cachetiles vectorosm-cachetiles.cpp)
+target_link_libraries(marble-vectorosm-cachetiles ${TARGET})
diff --git a/tools/vectorosm-tilecreator/vectorosm-cachetiles.cpp \
b/tools/vectorosm-tilecreator/vectorosm-cachetiles.cpp new file mode 100644
index 0000000..ff51425
--- /dev/null
+++ b/tools/vectorosm-tilecreator/vectorosm-cachetiles.cpp
@@ -0,0 +1,165 @@
+//
+// This file is part of the Marble Virtual Globe.
+//
+// This program is free software licensed under the GNU LGPL. You can
+// find a copy of this license in LICENSE.txt in the top directory of
+// the source code.
+//
+// Copyright 2016 Dennis Nienhüser <nienhueser@kde.org>
+//
+
+#include "GeoDataDocumentWriter.h"
+#include "GeoDataGeometry.h"
+#include "GeoDataLatLonAltBox.h"
+#include "GeoDataPlacemark.h"
+#include "GeoDataTypes.h"
+#include "MarbleDirs.h"
+#include "MarbleModel.h"
+#include "MbTileWriter.h"
+#include "NodeReducer.h"
+#include "ParsingRunnerManager.h"
+#include "TileDirectory.h"
+#include "TileId.h"
+#include "VectorClipper.h"
+#include "WayConcatenator.h"
+
+#include <QApplication>
+#include <QBuffer>
+#include <QCommandLineParser>
+#include <QDebug>
+#include <QFileInfo>
+#include <QRect>
+
+#include <iostream>
+
+using namespace Marble;
+
+GeoDataDocument* mergeDocuments(GeoDataDocument* map1, GeoDataDocument* map2)
+{
+ GeoDataDocument* mergedMap = new GeoDataDocument(*map1);
+
+ OsmPlacemarkData marbleLand;
+ marbleLand.addTag("marble_land","landmass");
+ foreach (auto placemark, map2->placemarkList()) {
+ GeoDataPlacemark* land = new GeoDataPlacemark(*placemark);
+ if(land->geometry()->nodeType() == GeoDataTypes::GeoDataPolygonType) {
+ land->setOsmData(marbleLand);
+ }
+ mergedMap->append(land);
+ }
+
+ return mergedMap;
+}
+
+int main(int argc, char *argv[])
+{
+ QTime timer;
+ timer.start();
+
+ QCoreApplication app(argc, argv);
+
+ QCoreApplication::setApplicationName("marble-vectorosm-cachetiles");
+ QCoreApplication::setApplicationVersion("0.1");
+
+ QCommandLineParser parser;
+ parser.setApplicationDescription("Create a vectorosm tile and its \
neighborhood"); + parser.addHelpOption();
+ parser.addVersionOption();
+ parser.addPositionalArgument("tile", "The tile to create (in z/x/y.extension \
format)"); +
+ parser.addOptions({
+ {{"c", "cache-directory"}, "Directory for temporary data.", \
"cache", "cache"}, + {{"m", "mbtile"}, "Store tiles in a mbtile \
database.", "mbtile"}, + {"verbose", "Write progress information \
to standard output."} + });
+ parser.process(app);
+
+ const QStringList args = parser.positionalArguments();
+ if (args.size() != 1) {
+ parser.showHelp();
+ return 0;
+ }
+
+ auto const input = args.first().split('/');
+ if (input.size() != 3) {
+ qWarning() << "Tile" << input << "does not match the z/x/y.format \
convention"; + parser.showHelp();
+ return 1;
+ }
+
+ bool canParse[] = {false, false, false};
+ TileId centerTile(0, input[0].toInt(&canParse[0]), input[1].toInt(&canParse[1]), \
QFileInfo(input[2]).baseName().toInt(&canParse[2])); + if (!canParse[0] || \
!canParse[1] || !canParse[2]) { + qWarning() << "Tile" << input << "does not \
consist of digits in the format z/x/y.format"; + parser.showHelp();
+ return 1;
+ }
+ QString const extension = QFileInfo(input[2]).completeSuffix();
+ QString const mbtile = parser.value("mbtile");
+ QSharedPointer<MbTileWriter> mbtileWriter = QSharedPointer<MbTileWriter>(new \
MbTileWriter(mbtile, extension)); + mbtileWriter->setReportProgress(false);
+ mbtileWriter->setCommitInterval(500);
+
+ MarbleModel model;
+ ParsingRunnerManager manager(model.pluginManager());
+ QString const cacheDirectory = parser.value("cache-directory");
+ QDir().mkpath(cacheDirectory);
+ if (!QFileInfo(cacheDirectory).isWritable()) {
+ qWarning() << "Cannot write to cache directory" << cacheDirectory;
+ parser.showHelp(1);
+ }
+
+ TileDirectory mapTiles(TileDirectory::OpenStreetMap, cacheDirectory, manager, \
extension, centerTile.zoomLevel()); + TileDirectory \
landTiles(TileDirectory::Landmass, cacheDirectory, manager, extension, \
centerTile.zoomLevel()); +
+ int const offset = 3;
+ int const N = pow(2,centerTile.zoomLevel());
+ QRect boundaries = QRect(0, 0, N-1, N-1) & QRect(QPoint(centerTile.x()-offset, \
centerTile.y()-offset), + \
QPoint(centerTile.x()+offset, centerTile.y()+offset)); + int count = 0;
+ int const total = boundaries.width() * boundaries.height();
+ bool const printProgress = parser.isSet("verbose");
+ for (int x=boundaries.left(); x<=boundaries.right(); ++x) {
+ for (int y=boundaries.top(); y<=boundaries.bottom(); ++y) {
+ auto const tileId = TileId (0, centerTile.zoomLevel(), x, y);
+ ++count;
+ if (mbtileWriter->hasTile(x, y, tileId.zoomLevel())) {
+ continue;
+ }
+
+ typedef QSharedPointer<GeoDataDocument> GeoDocPtr;
+ GeoDocPtr tile1 = GeoDocPtr(mapTiles.clip(tileId.zoomLevel(), \
tileId.x(), tileId.y())); + \
TagsFilter::removeAnnotationTags(tile1.data()); + if (tileId.zoomLevel() < \
17) { + WayConcatenator concatenator(tile1.data());
+ }
+ NodeReducer nodeReducer(tile1.data(), tileId);
+ GeoDocPtr tile2 = GeoDocPtr(landTiles.clip(tileId.zoomLevel(), \
tileId.x(), tileId.y())); + GeoDocPtr combined = \
GeoDocPtr(mergeDocuments(tile1.data(), tile2.data())); +
+ QBuffer buffer;
+ buffer.open(QBuffer::ReadWrite);
+ if (GeoDataDocumentWriter::write(&buffer, *combined, extension)) {
+ buffer.seek(0);
+ mbtileWriter->addTile(&buffer, tileId.x(), tileId.y(), \
tileId.zoomLevel()); + } else {
+ qWarning() << "Could not write the tile " << combined->name();
+ }
+
+ if (printProgress) {
+ TileDirectory::printProgress(qreal(count) / total);
+ std::cout << " Tile " << count << "/" << total << " (";
+ std::cout << combined->name().toStdString() << ").";
+ std::cout << std::string(20, ' ') << '\r';
+ std::cout.flush();
+ }
+ }
+ }
+
+ if (printProgress) {
+ TileDirectory::printProgress(1.0);
+ std::cout << "Vector OSM tiles complete after " << timer.elapsed() << " ms." \
<< std::string(30, ' ') << std::endl; + }
+
+ return 0;
+}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic