From ebcd7f973612ff99cb5bee2c84045110dac5d40b Mon Sep 17 00:00:00 2001 From: Alex Zolotarev Date: Sat, 5 Feb 2011 05:10:44 +0200 Subject: [PATCH] Added world map generation support to country polygonizer Note that features will not be duplicated in world and countries files any more --- indexer/indexer_tool/feature_bucketer.hpp | 30 ++++---------- indexer/indexer_tool/feature_generator.cpp | 4 +- indexer/indexer_tool/indexer_tool.pro | 3 +- indexer/indexer_tool/polygonizer.hpp | 17 ++++++-- indexer/indexer_tool/world_map_generator.hpp | 41 ++++++++++++++++++++ tools/unix/build_common_planet.sh | 11 +----- 6 files changed, 70 insertions(+), 36 deletions(-) create mode 100644 indexer/indexer_tool/world_map_generator.hpp diff --git a/indexer/indexer_tool/feature_bucketer.hpp b/indexer/indexer_tool/feature_bucketer.hpp index bc66ec0353..dcad2423d5 100644 --- a/indexer/indexer_tool/feature_bucketer.hpp +++ b/indexer/indexer_tool/feature_bucketer.hpp @@ -1,20 +1,17 @@ #pragma once +#include "world_map_generator.hpp" + #include "../../base/base.hpp" -#include "../../base/logging.hpp" #include "../../coding/file_writer.hpp" #include "../../geometry/rect2d.hpp" #include "../../indexer/feature.hpp" -#include "../../indexer/feature_visibility.hpp" -#include "../../defines.hpp" #include "../../std/string.hpp" -#include - namespace feature { @@ -35,37 +32,28 @@ class CellFeatureBucketer CellIdConverter::GetCellBounds(cell, minX, minY, maxX, maxY); m_Buckets[i].m_Rect = m2::RectD(minX, minY, maxX, maxY); } - // create separate world bucket if necessary - if (m_maxWorldZoom >= 0) - m_worldBucket.reset(new FeatureOutT(WORLD_FILE_NAME, m_FeatureOutInitData)); } public: template explicit CellFeatureBucketer(TInfo & info) : m_Level(info.cellBucketingLevel), m_FeatureOutInitData(info.datFilePrefix, info.datFileSuffix), - m_maxWorldZoom(info.maxScaleForWorldFeatures) + m_worldMap(info.maxScaleForWorldFeatures, m_FeatureOutInitData) { Init(); } + /// @note this constructor doesn't support world file generation CellFeatureBucketer(int level, typename FeatureOutT::InitDataType const & initData) - : m_Level(level), m_FeatureOutInitData(initData), m_maxWorldZoom(-1) + : m_Level(level), m_FeatureOutInitData(initData), m_worldMap(-1, initData) { Init(); } void operator () (feature_builder_t const & fb) { - int minScale = feature::MinDrawableScaleForFeature(fb.GetFeatureBase()); - if (minScale == -1) - { - LOG(LWARNING, ("Non-drawable feature found, ignoring")); - return; - } - // separately store features needed for world map - if (m_worldBucket && m_maxWorldZoom >= minScale) - (*m_worldBucket)(fb); + if (m_worldMap(fb)) + return; // we do not duplicate features in world and bucket files FeatureClipperT clipper(fb); // TODO: Is feature fully inside GetLimitRect()? @@ -113,9 +101,7 @@ private: int m_Level; typename FeatureOutT::InitDataType m_FeatureOutInitData; vector m_Buckets; - /// if NULL, separate world data file is not generated - boost::scoped_ptr m_worldBucket; - int m_maxWorldZoom; + WorldMapGenerator m_worldMap; }; class SimpleFeatureClipper diff --git a/indexer/indexer_tool/feature_generator.cpp b/indexer/indexer_tool/feature_generator.cpp index e9acd5de4b..9af43ba3dc 100644 --- a/indexer/indexer_tool/feature_generator.cpp +++ b/indexer/indexer_tool/feature_generator.cpp @@ -302,13 +302,15 @@ bool GenerateImpl(GenerateInfo & info) FeaturePolygonizerType bucketer(info); TParser parser(bucketer, holder); ParseXMLFromStdIn(parser); + info.bucketNames = bucketer.Names(); } else { CHECK_GREATER_OR_EQUAL(info.cellBucketingLevel, 0, ()); CHECK_LESS(info.cellBucketingLevel, 10, ()); - typedef CellFeatureBucketer FeatureBucketerType; + typedef CellFeatureBucketer FeatureBucketerType; FeatureBucketerType bucketer(info); TParser parser(bucketer, holder); ParseXMLFromStdIn(parser); diff --git a/indexer/indexer_tool/indexer_tool.pro b/indexer/indexer_tool/indexer_tool.pro index eb214ee7b9..c67b7f33fc 100644 --- a/indexer/indexer_tool/indexer_tool.pro +++ b/indexer/indexer_tool/indexer_tool.pro @@ -24,7 +24,7 @@ SOURCES += \ update_generator.cpp \ grid_generator.cpp \ statistics.cpp \ - kml_parser.cpp \ + kml_parser.cpp HEADERS += \ osm_element.hpp \ @@ -39,3 +39,4 @@ HEADERS += \ statistics.hpp \ kml_parser.hpp \ polygonizer.hpp \ + world_map_generator.hpp diff --git a/indexer/indexer_tool/polygonizer.hpp b/indexer/indexer_tool/polygonizer.hpp index fa75cfd0e9..c83fef1eb6 100644 --- a/indexer/indexer_tool/polygonizer.hpp +++ b/indexer/indexer_tool/polygonizer.hpp @@ -17,6 +17,7 @@ #include #include "kml_parser.hpp" +#include "world_map_generator.hpp" namespace feature { @@ -26,11 +27,11 @@ namespace feature { public: template - Polygonizer(TInfo & info) - : m_FeatureOutInitData(info.datFilePrefix, info.datFileSuffix), m_Names(info.bucketNames) + Polygonizer(TInfo & info) : m_FeatureOutInitData(info.datFilePrefix, info.datFileSuffix), + m_worldMap(info.maxScaleForWorldFeatures, m_FeatureOutInitData) { CHECK(kml::LoadCountriesList(info.datFilePrefix, m_countries, info.simplifyCountriesLevel), - ("Error loading polygons")); + ("Error loading country polygons files")); //LOG_SHORT(LINFO, ("Loaded polygons count for regions:")); //for (size_t i = 0; i < m_countries.size(); ++i) @@ -79,6 +80,9 @@ namespace feature void operator () (FeatureBuilder1 const & fb) { + if (m_worldMap(fb)) + return; // do not duplicate feature in any country if it's stored in world map + buffer_vector vec; m_countries.ForEachInRect(fb.GetLimitRect(), InsertCountriesPtr(vec)); @@ -112,6 +116,11 @@ namespace feature (*(m_Buckets[country->m_index]))(fb); } + vector const & Names() + { + return m_Names; + } + private: typename FeatureOutT::InitDataType m_FeatureOutInitData; @@ -119,5 +128,7 @@ namespace feature vector m_Names; kml::CountriesContainerT m_countries; + + WorldMapGenerator m_worldMap; }; } diff --git a/indexer/indexer_tool/world_map_generator.hpp b/indexer/indexer_tool/world_map_generator.hpp new file mode 100644 index 0000000000..270b539deb --- /dev/null +++ b/indexer/indexer_tool/world_map_generator.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "../../defines.hpp" + +#include "../../indexer/feature.hpp" +#include "../../indexer/feature_visibility.hpp" + +#include + +template +class WorldMapGenerator +{ + /// if NULL, separate world data file is not generated + boost::scoped_ptr m_worldBucket; + /// features visible before or at this scale level will go to World map + int m_maxWorldScale; + +public: + WorldMapGenerator(int maxWorldScale, typename FeatureOutT::InitDataType featureOutInitData) + : m_maxWorldScale(maxWorldScale) + { + if (maxWorldScale >= 0) + m_worldBucket.reset(new FeatureOutT(WORLD_FILE_NAME, featureOutInitData)); + } + + bool operator()(FeatureBuilder1 const & fb) + { + if (m_worldBucket) + { + int minScale = feature::MinDrawableScaleForFeature(fb.GetFeatureBase()); + CHECK_GREATER(minScale, -1, ("Non-drawable feature found!?")); + // separately store features needed for world map + if (m_maxWorldScale >= minScale) + { + (*m_worldBucket)(fb); + return true; + } + } + return false; + } +}; diff --git a/tools/unix/build_common_planet.sh b/tools/unix/build_common_planet.sh index f1c2c072c6..faf9c9991e 100755 --- a/tools/unix/build_common_planet.sh +++ b/tools/unix/build_common_planet.sh @@ -14,8 +14,7 @@ PROCESSORS=4 # displays usage and exits function Usage { echo '' - echo "Usage: $0 [path_to_data_folder_with_classsif_and_planet.osm.bz2] [bucketing_level] [optional_path_to_intermediate_data] [world_only]" - echo "Note, that for coastlines bucketing_level should be 0" + echo "Usage: $0 [path_to_data_folder_with_classsif_and_planet.osm.bz2] [bucketing_level] [optional_path_to_intermediate_data]" echo "Planet squares size is (2^bucketing_level x 2^bucketing_level)" echo "If optional intermediate path is given, only second pass will be executed" exit 0 @@ -100,12 +99,6 @@ then PV=pv fi -WORLD_ONLY=false -if [ $# -ge 4 ]; then - WORLD_ONLY=true -fi - - # skip 1st pass if intermediate data path was given if [ $# -lt 3 ]; then # 1st pass - not paralleled @@ -117,7 +110,7 @@ fi # 2nd pass - not paralleled $PV $OSM_BZ2 | bzip2 -d | $INDEXER_TOOL --intermediate_data_path=$TMPDIR \ --use_light_nodes=$LIGHT_NODES --bucketing_level=$BUCKETING_LEVEL \ - --generate_features --worldmap_max_zoom=5 --world_only=$WORLD_ONLY \ + --generate_features --generate_world_scale=5 \ --data_path=$DATA_PATH # 3rd pass - do in parallel