summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Nienhüser <nienhueser@kde.org>2016-10-09 14:04:19 (GMT)
committerDennis Nienhüser <nienhueser@kde.org>2016-10-20 17:00:43 (GMT)
commitfdac3b5b8c187601d9ff5ab64f50284592019cd8 (patch)
tree9079821c2797a1bad3ae41df7021d44606f0fc9c
parent1a62251551071f7868aee693f1211ad2c1ecca06 (diff)
Merge rectangular boundary tiles of adjacent polygonal input files
Spatially adjacent regions (e.g. neighboring states) share borders such that in rectangular tiles data from both appears. These need to be handled individually in order to have data from both (or more) input files appear in the final tile. (cherry picked from commit f6618ae6b986b5591136341fd8c7eab790fc5831)
-rw-r--r--tools/vectorosm-tilecreator/TileDirectory.cpp16
-rw-r--r--tools/vectorosm-tilecreator/TileDirectory.h2
-rw-r--r--tools/vectorosm-tilecreator/main.cpp77
3 files changed, 74 insertions, 21 deletions
diff --git a/tools/vectorosm-tilecreator/TileDirectory.cpp b/tools/vectorosm-tilecreator/TileDirectory.cpp
index ffd7b02..13be0cf 100644
--- a/tools/vectorosm-tilecreator/TileDirectory.cpp
+++ b/tools/vectorosm-tilecreator/TileDirectory.cpp
@@ -64,6 +64,7 @@ TileDirectory::TileDirectory(TileType tileType, const QString &cacheDir, Parsing
m_zoomLevel = 10;
m_baseDir = QString("%1/osm/%2").arg(cacheDir).arg(m_zoomLevel);
}
+ QDir().mkpath(m_baseDir);
}
TileId TileDirectory::tileFor(int zoomLevel, int tileX, int tileY) const
@@ -393,7 +394,7 @@ void TileDirectory::createTiles() const
cout << " " << (m_tileType == OpenStreetMap ? "osm" : "landmass") << " cache tiles complete." << endl;
}
-bool TileDirectory::contains(const TileId &tile) const
+int TileDirectory::innerNodes(const TileId &tile) const
{
GeoDataLatLonBox tileBoundary;
m_tileProjection.geoCoordinates(tile.zoomLevel(), tile.x(), tile.y(), tileBoundary);
@@ -408,23 +409,24 @@ bool TileDirectory::contains(const TileId &tile) const
bounds << GeoDataCoordinates(east, south);
bounds << GeoDataCoordinates(west, south);
+ int innerNodes = 0;
if (m_boundingPolygon.isEmpty()) {
foreach(auto const &coordinate, bounds) {
if (m_boundingBox.contains(coordinate)) {
- return true;
+ ++innerNodes;
}
}
- return false;
+ return innerNodes;
}
- foreach(auto const &ring, m_boundingPolygon) {
- foreach(auto const &coordinate, bounds) {
+ foreach(auto const &coordinate, bounds) {
+ foreach(auto const &ring, m_boundingPolygon) {
if (ring.contains(coordinate)) {
- return true;
+ ++innerNodes;
}
}
}
- return false;
+ return innerNodes;
}
void TileDirectory::updateProgress()
diff --git a/tools/vectorosm-tilecreator/TileDirectory.h b/tools/vectorosm-tilecreator/TileDirectory.h
index 52de4d5..d32bd3f 100644
--- a/tools/vectorosm-tilecreator/TileDirectory.h
+++ b/tools/vectorosm-tilecreator/TileDirectory.h
@@ -71,7 +71,7 @@ public:
void setBoundingBox(const GeoDataLatLonBox &boundingBox);
void setBoundingPolygon(const QString &filename);
void createTiles() const;
- bool contains(const TileId &tile) const;
+ int innerNodes(const TileId &tile) const;
static void printProgress(double progress, int barWidth=40);
diff --git a/tools/vectorosm-tilecreator/main.cpp b/tools/vectorosm-tilecreator/main.cpp
index e3e66c9..7ae31a8 100644
--- a/tools/vectorosm-tilecreator/main.cpp
+++ b/tools/vectorosm-tilecreator/main.cpp
@@ -69,6 +69,45 @@ QString tileFileName(const QCommandLineParser &parser, int x, int y, int zoomLev
return outputFile;
}
+void writeBoundaryTile(GeoDataDocument* tile, const QString &region, const QCommandLineParser &parser, int x, int y, int zoomLevel)
+{
+ QString const extension = parser.value("extension");
+ QString const outputDir = QString("%1/boundaries/%2/%3/%4").arg(parser.value("cache-directory")).arg(region).arg(zoomLevel).arg(x);
+ QString const outputFile = QString("%1/%2.%3").arg(outputDir).arg(y).arg(extension);
+ QDir().mkpath(outputDir);
+ GeoDataDocumentWriter::write(outputFile, *tile);
+}
+
+QSharedPointer<GeoDataDocument> mergeBoundaryTiles(const QSharedPointer<GeoDataDocument> &background, ParsingRunnerManager &manager, const QCommandLineParser &parser, int x, int y, int zoomLevel)
+{
+ GeoDataDocument* mergedMap = new GeoDataDocument;
+ OsmPlacemarkData marbleLand;
+ marbleLand.addTag("marble_land","landmass");
+ foreach (auto placemark, background->placemarkList()) {
+ GeoDataPlacemark* land = new GeoDataPlacemark(*placemark);
+ if(land->geometry()->nodeType() == GeoDataTypes::GeoDataPolygonType) {
+ land->setOsmData(marbleLand);
+ }
+ mergedMap->append(land);
+ }
+
+ QString const extension = parser.value("extension");
+ QString const boundaryDir = QString("%1/boundaries").arg(parser.value("cache-directory"));
+ foreach(auto const &dir, QDir(boundaryDir).entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
+ QString const file = QString("%1/%2/%3/%4/%5.%6").arg(boundaryDir).arg(dir).arg(zoomLevel).arg(x).arg(y).arg(extension);
+ if (QFileInfo(file).exists()) {
+ auto tile = TileDirectory::open(file, manager);
+ if (tile) {
+ foreach (auto placemark, tile->placemarkList()) {
+ mergedMap->append(new GeoDataPlacemark(*placemark));
+ }
+ }
+ }
+ }
+
+ return QSharedPointer<GeoDataDocument>(mergedMap);
+}
+
bool writeTile(GeoDataDocument* tile, const QString &outputFile)
{
QDir().mkpath(QFileInfo(outputFile).path());
@@ -174,7 +213,9 @@ int main(int argc, char *argv[])
}
}
} else {
- TileDirectory mapTiles(TileDirectory::OpenStreetMap, cacheDirectory, manager, extension, maxZoomLevel);
+ QString const region = QFileInfo(inputFileName).fileName();
+ QString const regionDir = QString("%1/%2").arg(cacheDirectory).arg(region);
+ TileDirectory mapTiles(TileDirectory::OpenStreetMap, regionDir, manager, extension, maxZoomLevel);
mapTiles.setInputFile(inputFileName);
mapTiles.createTiles();
auto const boundingBox = mapTiles.boundingBox();
@@ -187,6 +228,7 @@ int main(int argc, char *argv[])
Tiles tiles;
qint64 total = 0;
+ QSet<QString> boundaryTiles;
foreach(auto zoomLevel, zoomLevels) {
// @todo FIXME Assumes placemark ownership
//WayConcatenator concatenator(tagsFilter.accepted(), QStringList() << "highway=*", false);
@@ -195,17 +237,21 @@ int main(int argc, char *argv[])
total += iter.total();
foreach(auto const &tileId, iter) {
auto const tile = TileId(QString(), zoomLevel, tileId.x(), tileId.y());
- if (mapTiles.contains(tile)) {
+ int const innerNodes = mapTiles.innerNodes(tile);
+ if (innerNodes > 0) {
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;
+ if (innerNodes < 4) {
+ boundaryTiles << name;
+ }
}
}
}
qint64 count = 0;
- foreach(auto const &tileList, tiles) {
- foreach(auto const &tileId, tileList) {
+ for (auto iter = tiles.begin(), end = tiles.end(); iter != end; ++iter) {
+ foreach(auto const &tileId, iter.value()) {
++count;
int const zoomLevel = tileId.zoomLevel();
QString const filename = tileFileName(parser, tileId.x(), tileId.y(), zoomLevel);
@@ -216,11 +262,19 @@ int main(int argc, char *argv[])
continue;
}
}
- GeoDataDocument* tile1 = mapTiles.clip(zoomLevel, tileId.x(), tileId.y());
- TagsFilter::removeAnnotationTags(tile1);
- GeoDataDocument* tile2 = loader.clip(zoomLevel, tileId.x(), tileId.y());
- GeoDataDocument* combined = mergeDocuments(tile1, tile2);
- NodeReducer nodeReducer(combined, zoomLevel);
+
+ typedef QSharedPointer<GeoDataDocument> GeoDocPtr;
+ GeoDocPtr tile1 = GeoDocPtr(mapTiles.clip(zoomLevel, tileId.x(), tileId.y()));
+ TagsFilter::removeAnnotationTags(tile1.data());
+ GeoDocPtr tile2 = GeoDocPtr(loader.clip(zoomLevel, tileId.x(), tileId.y()));
+ GeoDocPtr combined = GeoDocPtr(mergeDocuments(tile1.data(), tile2.data()));
+ NodeReducer nodeReducer(combined.data(), zoomLevel);
+
+ if (boundaryTiles.contains(iter.key())) {
+ writeBoundaryTile(tile1.data(), region, parser, tileId.x(), tileId.y(), zoomLevel);
+ combined = mergeBoundaryTiles(tile2, manager, parser, tileId.x(), tileId.y(), zoomLevel);
+ }
+
if (zoomLevel > 13 && mbtileWriter) {
QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
@@ -231,7 +285,7 @@ int main(int argc, char *argv[])
qWarning() << "Could not write the tile " << combined->name();
}
} else {
- if (!writeTile(combined, filename)) {
+ if (!writeTile(combined.data(), filename)) {
return 4;
}
}
@@ -243,9 +297,6 @@ int main(int argc, char *argv[])
std::cout << " Node reduction: " << qRound(reduction * 100.0) << "%";
std::cout << " \r";
std::cout.flush();
- delete combined;
- delete tile1;
- delete tile2;
}
}
TileDirectory::printProgress(1.0);