forked from organicmaps/organicmaps
[generator] Filter equal place-xxx features nearby.
This commit is contained in:
parent
56db1951c8
commit
4939108827
6 changed files with 107 additions and 8 deletions
|
@ -47,6 +47,20 @@ m2::PointD FeatureBuilder1::GetGeometryCenter() const
|
|||
return ret / count;
|
||||
}
|
||||
|
||||
m2::PointD FeatureBuilder1::GetKeyPoint() const
|
||||
{
|
||||
switch (GetGeomType())
|
||||
{
|
||||
case GEOM_POINT:
|
||||
return m_center;
|
||||
case GEOM_LINE: case GEOM_AREA:
|
||||
return GetGeometryCenter();
|
||||
default:
|
||||
ASSERT(false, ());
|
||||
return m2::PointD(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void FeatureBuilder1::SetCenter(m2::PointD const & p)
|
||||
{
|
||||
m_center = p;
|
||||
|
@ -444,10 +458,18 @@ void FeatureBuilder1::SetCoastCell(int64_t iCell, string const & strCell)
|
|||
{
|
||||
m_coastCell = iCell;
|
||||
|
||||
ASSERT ( m_params.name.IsEmpty(), () );
|
||||
ASSERT(m_params.name.IsEmpty(), ());
|
||||
m_params.name.AddString(0, strCell);
|
||||
}
|
||||
|
||||
string FeatureBuilder1::GetName(int8_t lang) const
|
||||
{
|
||||
string s;
|
||||
bool const res = m_params.name.GetString(lang, s);
|
||||
ASSERT(res != s.empty(), ());
|
||||
return s;
|
||||
}
|
||||
|
||||
string DebugPrint(FeatureBuilder1 const & f)
|
||||
{
|
||||
ostringstream out;
|
||||
|
|
|
@ -85,6 +85,7 @@ public:
|
|||
|
||||
bool IsGeometryClosed() const;
|
||||
m2::PointD GetGeometryCenter() const;
|
||||
m2::PointD GetKeyPoint() const;
|
||||
|
||||
inline size_t GetPointsCount() const { return GetGeometry().size(); }
|
||||
inline size_t GetPolygonsCount() const { return m_polygons.size(); }
|
||||
|
@ -157,12 +158,7 @@ public:
|
|||
else return false;
|
||||
}
|
||||
|
||||
inline string GetName(int8_t lang = StringUtf8Multilang::DEFAULT_CODE) const
|
||||
{
|
||||
string s;
|
||||
m_params.name.GetString(lang, s);
|
||||
return s;
|
||||
}
|
||||
string GetName(int8_t lang = StringUtf8Multilang::DEFAULT_CODE) const;
|
||||
|
||||
/// @name For diagnostic use only.
|
||||
//@{
|
||||
|
|
|
@ -440,9 +440,12 @@ bool GenerateImpl(GenerateInfo & info, string const & osmFileName = string())
|
|||
else
|
||||
ParseXMLFromFile(parser, osmFileName);
|
||||
|
||||
parser.Finish();
|
||||
|
||||
// Stop if coasts are not merged and FLAG_fail_on_coasts is set
|
||||
if (!bucketer.Finish())
|
||||
return false;
|
||||
|
||||
bucketer.GetNames(info.m_bucketNames);
|
||||
}
|
||||
catch (Reader::Exception const & e)
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
|
||||
#include "../indexer/ftypes_matcher.hpp"
|
||||
#include "../indexer/feature_visibility.hpp"
|
||||
#include "../indexer/classificator.hpp"
|
||||
|
||||
#include "../geometry/tree4d.hpp"
|
||||
|
||||
#include "../base/string_utils.hpp"
|
||||
#include "../base/logging.hpp"
|
||||
|
@ -264,6 +267,48 @@ class SecondPassParser : public BaseOSMParser
|
|||
return m_addrWriter && checker(params.m_Types);
|
||||
}
|
||||
|
||||
class Place
|
||||
{
|
||||
FeatureBuilderT m_ft;
|
||||
m2::PointD m_pt;
|
||||
uint32_t m_type;
|
||||
|
||||
static constexpr long double THRESHOLD_M = 5000.0;
|
||||
|
||||
bool IsPoint() const { return (m_ft.GetGeomType() == feature::GEOM_POINT); }
|
||||
|
||||
public:
|
||||
Place(FeatureBuilderT const & ft, uint32_t type)
|
||||
: m_ft(ft), m_pt(ft.GetKeyPoint()), m_type(type)
|
||||
{
|
||||
}
|
||||
|
||||
FeatureBuilderT const & GetFeature() const { return m_ft; }
|
||||
|
||||
m2::RectD GetLimitRect() const
|
||||
{
|
||||
return MercatorBounds::RectByCenterXYAndSizeInMeters(m_pt, THRESHOLD_M);
|
||||
}
|
||||
|
||||
/// @name Always replace point features and leave area features.
|
||||
//@{
|
||||
bool IsEqual(Place const & r) const
|
||||
{
|
||||
return (m_type == r.m_type &&
|
||||
m_ft.GetName() == r.m_ft.GetName() &&
|
||||
(IsPoint() || r.IsPoint()) &&
|
||||
MercatorBounds::DistanceOnEarth(m_pt, r.m_pt) < THRESHOLD_M);
|
||||
}
|
||||
|
||||
bool NeedReplace(Place const & r) const
|
||||
{
|
||||
return r.IsPoint();
|
||||
}
|
||||
//@}
|
||||
};
|
||||
|
||||
m4::Tree<Place> m_places;
|
||||
|
||||
void EmitFeatureBase(FeatureBuilderT & ft, FeatureParams const & params)
|
||||
{
|
||||
ft.SetParams(params);
|
||||
|
@ -273,7 +318,17 @@ class SecondPassParser : public BaseOSMParser
|
|||
if (NeedWriteAddress(params) && ft.FormatFullAddress(addr))
|
||||
m_addrWriter->Write(addr.c_str(), addr.size());
|
||||
|
||||
m_emitter(ft);
|
||||
static uint32_t const placeType = classif().GetTypeByPath({"place"});
|
||||
uint32_t const type = params.FindType(placeType, 1);
|
||||
|
||||
if (type != ftype::GetEmptyValue() && !ft.GetName().empty())
|
||||
{
|
||||
m_places.ReplaceEqualInRect(Place(ft, type),
|
||||
bind(&Place::IsEqual, _1, _2),
|
||||
bind(&Place::NeedReplace, _1, _2));
|
||||
}
|
||||
else
|
||||
m_emitter(ft);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -435,4 +490,12 @@ public:
|
|||
if (!addrFilePath.empty())
|
||||
m_addrWriter.reset(new FileWriter(addrFilePath));
|
||||
}
|
||||
|
||||
void Finish()
|
||||
{
|
||||
m_places.ForEach([this] (Place const & p)
|
||||
{
|
||||
m_emitter(p.GetFeature());
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -306,6 +306,18 @@ bool FeatureParams::IsTypeExist(uint32_t t) const
|
|||
return (find(m_Types.begin(), m_Types.end(), t) != m_Types.end());
|
||||
}
|
||||
|
||||
uint32_t FeatureParams::FindType(uint32_t comp, uint8_t level) const
|
||||
{
|
||||
for (uint32_t const type : m_Types)
|
||||
{
|
||||
uint32_t t = type;
|
||||
ftype::TruncValue(t, level);
|
||||
if (t == comp)
|
||||
return type;
|
||||
}
|
||||
return ftype::GetEmptyValue();
|
||||
}
|
||||
|
||||
bool FeatureParams::CheckValid() const
|
||||
{
|
||||
CHECK(!m_Types.empty() && m_Types.size() <= max_types_count, ());
|
||||
|
|
|
@ -258,6 +258,9 @@ public:
|
|||
bool PopExactType(uint32_t t);
|
||||
bool IsTypeExist(uint32_t t) const;
|
||||
|
||||
/// Find type that matches "comp" with "level" in classificator hierarchy.
|
||||
uint32_t FindType(uint32_t comp, uint8_t level) const;
|
||||
|
||||
bool CheckValid() const;
|
||||
|
||||
uint8_t GetHeader() const;
|
||||
|
|
Loading…
Add table
Reference in a new issue