diff --git a/generator/coastlines_generator.cpp b/generator/coastlines_generator.cpp index 0bdc73d8f6..766075dcf3 100644 --- a/generator/coastlines_generator.cpp +++ b/generator/coastlines_generator.cpp @@ -1,6 +1,7 @@ #include "coastlines_generator.hpp" #include "feature_builder.hpp" +//#include "../indexer/tesselator.hpp" #include "../indexer/point_to_int64.hpp" #include "../geometry/region2d/binary_operators.hpp" @@ -66,6 +67,48 @@ namespace tree.Add(m_rgn, GetLimitRect(m_rgn)); } }; + + /* + class DoTesselateRegion + { + typedef vector PointsT; + PointsT m_vec; + public: + bool operator() (m2::PointD const & p) + { + m_vec.push_back(p); + return true; + } + + template class DoAddRegion + { + TreeT & m_tree; + public: + DoAddRegion(TreeT & tree) : m_tree(tree) {} + + void operator() (m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3) + { + RegionT rgn; + rgn.AddPoint(D2I(p1)); + rgn.AddPoint(D2I(p2)); + rgn.AddPoint(D2I(p3)); + m_tree.Add(rgn, GetLimitRect(rgn)); + } + }; + + template void Add(TreeT & tree) + { + list lst; + lst.push_back(PointsT()); + lst.back().swap(m_vec); + + tesselator::TrianglesInfo info; + tesselator::TesselateInterior(lst, info); + + info.ForEachTriangle(DoAddRegion(tree)); + } + }; + */ } void CoastlineFeaturesGenerator::AddRegionToTree(FeatureBuilder1 const & fb) @@ -73,6 +116,7 @@ void CoastlineFeaturesGenerator::AddRegionToTree(FeatureBuilder1 const & fb) ASSERT ( fb.IsGeometryClosed(), () ); DoCreateRegion createRgn; + //DoTesselateRegion createRgn; fb.ForEachGeometryPoint(createRgn); createRgn.Add(m_tree); } diff --git a/generator/feature_sorter.cpp b/generator/feature_sorter.cpp index 1237ef0922..5efa10b818 100644 --- a/generator/feature_sorter.cpp +++ b/generator/feature_sorter.cpp @@ -87,10 +87,10 @@ namespace feature vector m_geoFile, m_trgFile; - feature::DataHeader m_header; + DataHeader m_header; public: - FeaturesCollector2(string const & fName, feature::DataHeader const & header) + FeaturesCollector2(string const & fName, DataHeader const & header) : FeaturesCollector(fName + DATA_FILE_TAG), m_writer(fName), m_header(header) { for (size_t i = 0; i < m_header.GetScalesCount(); ++i) @@ -176,7 +176,11 @@ namespace feature tesselator::TrianglesInfo info; tesselator::TesselateInterior(polys, info); - if (info.IsEmpty()) return; + if (info.IsEmpty()) + { + LOG(LINFO, ("NO TRIANGLES")); + return; + } serial::TrianglesChainSaver saver(m_codingParams); @@ -338,6 +342,7 @@ namespace feature } }; + /* class less_points { double const m_eps; @@ -366,17 +371,15 @@ namespace feature }; typedef set points_set_t; + */ class BoundsDistance : public mn::DistanceToLineSquare { - points_set_t const & m_skip; - double m_eps; double m_minX, m_minY, m_maxX, m_maxY; public: - BoundsDistance(uint32_t cellID, int level, points_set_t const & skip) - : m_skip(skip) + BoundsDistance(uint32_t cellID, int level) { RectId const cell = RectId::FromBitsAndLevel(cellID, level); CellIdConverter::GetCellBounds(cell, m_minX, m_minY, m_maxX, m_maxY); @@ -393,12 +396,6 @@ namespace feature return std::numeric_limits::max(); } - if (m_skip.count(p) > 0) - { - // if we have more than one point with equal coordinates - do not simplify them - return std::numeric_limits::max(); - } - return mn::DistanceToLineSquare::operator()(p); } }; @@ -409,17 +406,17 @@ namespace feature uint32_t cellID; if (fb.GetCoastCell(cellID)) { + /* points_set_t toSkip; { points_t v(in); sort(v.begin(), v.end(), less_points()); toSkip.insert(unique(v.begin(), v.end(), equal_points()), v.end()); } + */ - BoundsDistance dist(cellID, g_coastsCellLevel, toSkip); + BoundsDistance dist(cellID, g_coastsCellLevel); feature::SimplifyPoints(dist, in, out, level); - - //LOG(LINFO, ("Special simplification", in.size(), out.size())); } else { @@ -428,6 +425,30 @@ namespace feature } } + static double CalcSquare(points_t const & poly) + { + ASSERT ( poly.front() == poly.back(), () ); + + double res = 0; + for (size_t i = 0; i < poly.size()-1; ++i) + { + res += (poly[i+1].x - poly[i].x) * + (poly[i+1].y + poly[i].y) / 2.0; + } + return fabs(res); + } + + static bool IsGoodArea(points_t const & poly, int level) + { + if (poly.size() < 4) + return false; + + m2::RectD r; + CalcRect(poly, r); + + return scales::IsGoodForLevel(level, r); + } + public: void operator() (FeatureBuilder2 & fb) { @@ -448,7 +469,7 @@ namespace feature if (isLine) holder.AddPoints(points, i); - if (isArea && points.size() > 3 && holder.NeedProcessTriangles()) + if (isArea && IsGoodArea(points, level) && holder.NeedProcessTriangles()) { // simplify and serialize triangles @@ -466,7 +487,7 @@ namespace feature SimplifyPoints(*iH, simplified.back(), level, fb); - if (simplified.back().size() < 3) + if (!IsGoodArea(simplified.back(), level)) simplified.pop_back(); } @@ -517,16 +538,16 @@ namespace feature { FileReader reader(tempDatFilePath); - bool const isWorld = (mapType != feature::DataHeader::country); + bool const isWorld = (mapType != DataHeader::country); - feature::DataHeader header; + DataHeader header; uint32_t coordBits = 27; if (isWorld) coordBits -= (scales::GetUpperScale() - scales::GetUpperWorldScale()); header.SetCodingParams(serial::CodingParams(coordBits, midPoints.GetCenter())); header.SetScales(isWorld ? g_arrWorldScales : g_arrCountryScales); - header.SetType(static_cast(mapType)); + header.SetType(static_cast(mapType)); FeaturesCollector2 collector(datFilePath, header); @@ -536,7 +557,7 @@ namespace feature src.Skip(midPoints.m_vec[i].second); FeatureBuilder1 f; - feature::ReadFromSourceRowFormat(src, f); + ReadFromSourceRowFormat(src, f); // emit the feature collector(GetFeatureBuilder2(f)); diff --git a/generator/feature_sorter.hpp b/generator/feature_sorter.hpp index b10384314c..279e1aedde 100644 --- a/generator/feature_sorter.hpp +++ b/generator/feature_sorter.hpp @@ -30,9 +30,10 @@ namespace feature { if (in.size() >= 2) { - double const eps = my::sq(scales::GetEpsilonForSimplify(level)); + double eps = scales::GetEpsilonForSimplify(level); dist.SetEpsilon(eps); + eps = my::sq(eps); SimplifyNearOptimal(20, in.begin(), in.end(), eps, dist, AccumulateSkipSmallTrg(dist, out, eps));