From kde-commits Sun Dec 04 16:52:58 2016 From: =?utf-8?q?Dennis_Nienh=C3=BCser?= Date: Sun, 04 Dec 2016 16:52:58 +0000 To: kde-commits Subject: [marble] tools/vectorosm-tilecreator: Add a tool for server-side dynamic tile generation Message-Id: X-MARC-Message: https://marc.info/?l=kde-commits&m=148087039027630 Git commit fa86770842341286f70ae08c8aaa48b0bfd73de2 by Dennis Nienh=C3=BCse= r. 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 [Li= cense: LGPL] https://commits.kde.org/marble/fa86770842341286f70ae08c8aaa48b0bfd73de2 diff --git a/tools/vectorosm-tilecreator/CMakeLists.txt b/tools/vectorosm-t= ilecreator/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/v= ectorosm-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=C3=BCser +// + +#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 +#include +#include +#include +#include +#include + +#include + +using namespace Marble; + +GeoDataDocument* mergeDocuments(GeoDataDocument* map1, GeoDataDocument* ma= p2) +{ + GeoDataDocument* mergedMap =3D new GeoDataDocument(*map1); + + OsmPlacemarkData marbleLand; + marbleLand.addTag("marble_land","landmass"); + foreach (auto placemark, map2->placemarkList()) { + GeoDataPlacemark* land =3D new GeoDataPlacemark(*placemark); + if(land->geometry()->nodeType() =3D=3D GeoDataTypes::GeoDataPolygo= nType) { + 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 neig= hborhood"); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument("tile", "The tile to create (in z/x/y.ext= ension 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 =3D parser.positionalArguments(); + if (args.size() !=3D 1) { + parser.showHelp(); + return 0; + } + + auto const input =3D args.first().split('/'); + if (input.size() !=3D 3) { + qWarning() << "Tile" << input << "does not match the z/x/y.format = convention"; + parser.showHelp(); + return 1; + } + + bool canParse[] =3D {false, false, false}; + TileId centerTile(0, input[0].toInt(&canParse[0]), input[1].toInt(&can= Parse[1]), QFileInfo(input[2]).baseName().toInt(&canParse[2])); + if (!canParse[0] || !canParse[1] || !canParse[2]) { + qWarning() << "Tile" << input << "does not consist of digits in th= e format z/x/y.format"; + parser.showHelp(); + return 1; + } + QString const extension =3D QFileInfo(input[2]).completeSuffix(); + QString const mbtile =3D parser.value("mbtile"); + QSharedPointer mbtileWriter =3D QSharedPointer(new MbTileWriter(mbtile, extension)); + mbtileWriter->setReportProgress(false); + mbtileWriter->setCommitInterval(500); + + MarbleModel model; + ParsingRunnerManager manager(model.pluginManager()); + QString const cacheDirectory =3D 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, m= anager, extension, centerTile.zoomLevel()); + TileDirectory landTiles(TileDirectory::Landmass, cacheDirectory, manag= er, extension, centerTile.zoomLevel()); + + int const offset =3D 3; + int const N =3D pow(2,centerTile.zoomLevel()); + QRect boundaries =3D QRect(0, 0, N-1, N-1) & QRect(QPoint(centerTile.x= ()-offset, centerTile.y()-offset), + QPoint(centerTile.x()= +offset, centerTile.y()+offset)); + int count =3D 0; + int const total =3D boundaries.width() * boundaries.height(); + bool const printProgress =3D parser.isSet("verbose"); + for (int x=3Dboundaries.left(); x<=3Dboundaries.right(); ++x) { + for (int y=3Dboundaries.top(); y<=3Dboundaries.bottom(); ++y) { + auto const tileId =3D TileId (0, centerTile.zoomLevel(), x, y); + ++count; + if (mbtileWriter->hasTile(x, y, tileId.zoomLevel())) { + continue; + } + + typedef QSharedPointer GeoDocPtr; + GeoDocPtr tile1 =3D 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 =3D GeoDocPtr(landTiles.clip(tileId.zoomLevel(= ), tileId.x(), tileId.y())); + GeoDocPtr combined =3D 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(), til= eId.zoomLevel()); + } else { + qWarning() << "Could not write the tile " << combined->nam= e(); + } + + 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; +}