diff options
author | vng <viktor.govako@gmail.com> | 2011-09-06 20:29:07 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 01:23:13 +0300 |
commit | aaaf1eac99193fc6ce187cf78d136814c99b26c6 (patch) | |
tree | 0ab822fd75a6184a89aaa9c387edd81db53d5898 /generator | |
parent | 32bb0f3d11e08ad9bfc52b60aa85ba872cee12ed (diff) |
Add simplification routine with specified 'Distance' policy object.
Use special simplification (don't remove bound points) in coasts generation algorithm.
Diffstat (limited to 'generator')
-rw-r--r-- | generator/coastlines_generator.cpp | 1 | ||||
-rw-r--r-- | generator/feature_builder.cpp | 9 | ||||
-rw-r--r-- | generator/feature_builder.hpp | 15 | ||||
-rw-r--r-- | generator/feature_generator.cpp | 2 | ||||
-rw-r--r-- | generator/feature_generator.hpp | 2 | ||||
-rw-r--r-- | generator/feature_sorter.cpp | 52 | ||||
-rw-r--r-- | generator/feature_sorter.hpp | 10 |
7 files changed, 77 insertions, 14 deletions
diff --git a/generator/coastlines_generator.cpp b/generator/coastlines_generator.cpp index bfeca2623e..989a8e7520 100644 --- a/generator/coastlines_generator.cpp +++ b/generator/coastlines_generator.cpp @@ -176,6 +176,7 @@ bool CoastlineFeaturesGenerator::GetFeature(size_t i, FeatureBuilder1 & fb) doDiff.AssignGeometry(fb); fb.SetArea(); fb.AddType(m_coastType); + fb.SetCoastCell(i); return true; } diff --git a/generator/feature_builder.cpp b/generator/feature_builder.cpp index 3d746a2d49..30277b2673 100644 --- a/generator/feature_builder.cpp +++ b/generator/feature_builder.cpp @@ -17,6 +17,7 @@ using namespace feature; /////////////////////////////////////////////////////////////////////////////////////////////////// FeatureBuilder1::FeatureBuilder1() +: m_coastCell(-1U) { m_Polygons.push_back(points_t()); } @@ -168,6 +169,8 @@ bool FeatureBuilder1::operator == (FeatureBuilder1 const & fb) const { if (!(m_Params == fb.m_Params)) return false; + if (m_coastCell != fb.m_coastCell) return false; + if (m_Params.GetGeomType() == GEOM_POINT && !is_equal(m_Center, fb.m_Center)) { @@ -235,12 +238,14 @@ void FeatureBuilder1::Serialize(buffer_t & data) const if (m_Params.GetGeomType() != GEOM_POINT) { - WriteVarUint(sink, uint32_t(m_Polygons.size())); + WriteVarUint(sink, static_cast<uint32_t>(m_Polygons.size())); for (list<points_t>::const_iterator i = m_Polygons.begin(); i != m_Polygons.end(); ++i) serial::SaveOuterPath(*i, cp, sink); } + WriteVarUint(sink, m_coastCell); + // check for correct serialization #ifdef DEBUG buffer_t tmp(data); @@ -280,6 +285,8 @@ void FeatureBuilder1::Deserialize(buffer_t & data) CalcRect(m_Polygons.back(), m_LimitRect); } + m_coastCell = ReadVarUint<uint32_t>(source); + CHECK ( CheckValid(), () ); } diff --git a/generator/feature_builder.hpp b/generator/feature_builder.hpp index 5a64fbb88f..7bb871d803 100644 --- a/generator/feature_builder.hpp +++ b/generator/feature_builder.hpp @@ -91,13 +91,24 @@ public: int GetMinFeatureDrawScale() const; + inline void SetCoastCell(uint32_t cell) { m_coastCell = cell; } + inline bool GetCoastCell(uint32_t & cell) const + { + if (m_coastCell != -1U) + { + cell = m_coastCell; + return true; + } + else return false; + } + protected: /// Used for feature debugging vector<osm::OsmId> m_osmIds; /// @name For diagnostic use only. //@{ - bool operator == (FeatureBuilder1 const &) const; + bool operator== (FeatureBuilder1 const &) const; bool CheckValid() const; //@} @@ -118,6 +129,8 @@ protected: /// List of geometry polygons. list<points_t> m_Polygons; // Check HEADER_IS_AREA + + uint32_t m_coastCell; }; /// Used for serialization of features during final pass. diff --git a/generator/feature_generator.cpp b/generator/feature_generator.cpp index aae1329129..7a8dc91d3a 100644 --- a/generator/feature_generator.cpp +++ b/generator/feature_generator.cpp @@ -273,7 +273,7 @@ public: if (info.m_createWorld) { m_world.reset(new WorldMapGenerator<FeaturesCollector>(info)); - m_coasts.reset(new CoastlineFeaturesGenerator(m_coastType)); + m_coasts.reset(new CoastlineFeaturesGenerator(m_coastType, g_coastsCellLevel)); m_coastsHolder.reset(new FeaturesCollector( info.m_datFilePrefix + WORLD_COASTS_FILE_NAME + info.m_datFileSuffix)); } diff --git a/generator/feature_generator.hpp b/generator/feature_generator.hpp index 40f94f1a64..dbb5e40458 100644 --- a/generator/feature_generator.hpp +++ b/generator/feature_generator.hpp @@ -34,4 +34,6 @@ namespace feature void operator() (FeatureBuilder1 const & f); }; + + static const int g_coastsCellLevel = 6; } diff --git a/generator/feature_sorter.cpp b/generator/feature_sorter.cpp index 795312190f..5c31e2fe59 100644 --- a/generator/feature_sorter.cpp +++ b/generator/feature_sorter.cpp @@ -337,11 +337,51 @@ namespace feature } }; + class BoundsDistance : public mn::DistanceToLineSquare<m2::PointD> + { + double m_eps; + double m_minX, m_minY, m_maxX, m_maxY; + + public: + BoundsDistance(uint32_t cellID, int level) + { + RectId cell = RectId::FromBitsAndLevel(cellID, level); + CellIdConverter<MercatorBounds, RectId>::GetCellBounds(cell, m_minX, m_minY, m_maxX, m_maxY); + } + + void SetEpsilon(double eps) { m_eps = 2.0*eps; } + + double operator() (m2::PointD const & p) const + { + if (fabs(p.x - m_minX) <= m_eps || fabs(p.x - m_maxX) <= m_eps || + fabs(p.y - m_minY) <= m_eps || fabs(p.y - m_maxY) <= m_eps) + { + return std::numeric_limits<double>::max(); + } + + return mn::DistanceToLineSquare<m2::PointD>::operator()(p); + } + }; + + void SimplifyPoints(points_t const & in, points_t & out, int level, + FeatureBuilder2 const & fb) + { + uint32_t cellID; + if (fb.GetCoastCell(cellID)) + { + BoundsDistance dist(cellID, g_coastsCellLevel); + feature::SimplifyPoints(dist, in, out, level); + } + else + { + mn::DistanceToLineSquare<m2::PointD> dist; + feature::SimplifyPoints(dist, in, out, level); + } + } + public: void operator() (FeatureBuilder2 & fb) { - (void)GetFileSize(m_datFile); - GeometryHolder holder(*this, fb, m_header.GetCodingParams()); bool const isLine = fb.IsLine(); @@ -349,11 +389,12 @@ namespace feature for (int i = m_header.GetScalesCount()-1; i >= 0; --i) { - if (fb.IsDrawableInRange(i > 0 ? m_header.GetScale(i-1) + 1 : 0, m_header.GetScale(i))) + int const level = m_header.GetScale(i); + if (fb.IsDrawableInRange(i > 0 ? m_header.GetScale(i-1) + 1 : 0, level)) { // simplify and serialize geometry points_t points; - SimplifyPoints(holder.GetSourcePoints(), points, m_header.GetScale(i)); + SimplifyPoints(holder.GetSourcePoints(), points, level, fb); if (isLine) holder.AddPoints(points, i); @@ -374,7 +415,7 @@ namespace feature { simplified.push_back(points_t()); - SimplifyPoints(*iH, simplified.back(), m_header.GetScale(i)); + SimplifyPoints(*iH, simplified.back(), level, fb); if (simplified.back().size() < 3) simplified.pop_back(); @@ -453,7 +494,6 @@ namespace feature // remove old not-sorted dat file FileWriter::DeleteFileX(tempDatFilePath); - FileWriter::DeleteFileX(datFilePath + DATA_FILE_TAG); return true; diff --git a/generator/feature_sorter.hpp b/generator/feature_sorter.hpp index 39e2c60a35..02e5279dcc 100644 --- a/generator/feature_sorter.hpp +++ b/generator/feature_sorter.hpp @@ -25,16 +25,16 @@ namespace feature return AlmostEqual(p1, p2); } - template <class PointsContainerT> - void SimplifyPoints(PointsContainerT const & in, PointsContainerT & out, int level) + template <class DistanceT, class PointsContainerT> + void SimplifyPoints(DistanceT dist, PointsContainerT const & in, PointsContainerT & out, int level) { if (in.size() >= 2) { - typedef mn::DistanceToLineSquare<m2::PointD> DistanceF; double const eps = my::sq(scales::GetEpsilonForSimplify(level)); + dist.SetEpsilon(eps); - SimplifyNearOptimal<DistanceF>(20, in.begin(), in.end(), eps, - AccumulateSkipSmallTrg<DistanceF, m2::PointD>(out, eps)); + SimplifyNearOptimal(20, in.begin(), in.end(), eps, dist, + AccumulateSkipSmallTrg<DistanceT, m2::PointD>(dist, out, eps)); CHECK_GREATER ( out.size(), 1, () ); CHECK ( are_points_equal(in.front(), out.front()), () ); |