forked from organicmaps/organicmaps
Fix buildings from xml loading.
This commit is contained in:
parent
abb449bc7f
commit
1a467a1b97
3 changed files with 24 additions and 21 deletions
|
@ -10,19 +10,6 @@
|
|||
#include "std/algorithm.hpp"
|
||||
#include "std/unique_ptr.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
m2::PointD CalculateCenter(vector<m2::PointD> const & geometry)
|
||||
{
|
||||
ASSERT(!geometry.empty() && geometry.size() % 3 == 0,
|
||||
("Invalid geometry should be handled in caller. geometry.size() =", geometry.size()));
|
||||
|
||||
auto const boundingBox = ApplyCalculator(begin(geometry), end(geometry),
|
||||
m2::CalculateBoundingBox());
|
||||
return ApplyCalculator(begin(geometry), end(geometry), m2::CalculatePointOnSurface(boundingBox));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace editor
|
||||
{
|
||||
FeatureID MigrateNodeFeatureIndex(osm::Editor::TForEachFeaturesNearByFn & forEach,
|
||||
|
@ -57,10 +44,11 @@ FeatureID MigrateWayFeatureIndex(osm::Editor::TForEachFeaturesNearByFn & forEach
|
|||
auto bestScore = 0.6; // initial score is used as a threshold.
|
||||
auto geometry = xml.GetGeometry();
|
||||
|
||||
if (geometry.empty() || geometry.size() % 3 != 0)
|
||||
if (geometry.empty())
|
||||
MYTHROW(MigrationError, ("Feature has invalid geometry", xml));
|
||||
|
||||
auto const someFeaturePoint = CalculateCenter(geometry);
|
||||
// This can be any point on a feature.
|
||||
auto const someFeaturePoint = geometry[0];
|
||||
|
||||
sort(begin(geometry), end(geometry)); // Sort to use in set_intersection.
|
||||
auto count = 0;
|
||||
|
|
|
@ -389,8 +389,14 @@ Framework::Framework()
|
|||
return streets.first[streets.second].m_name;
|
||||
return {};
|
||||
});
|
||||
editor.SetForEachFeatureAtPointFn(bind(&Framework::ForEachFeatureAtPoint, this, _1, _2));
|
||||
// Due to floating points accuracy issues (geometry is saved in editor up to 7 digits
|
||||
// after dicimal poin) some feature vertexes are threated as external to a given feature.
|
||||
auto const pointToFeatureDistanceToleranceInMeters = 1e-3;
|
||||
editor.SetForEachFeatureAtPointFn(bind(&Framework::ForEachFeatureAtPoint, this, _1, _2,
|
||||
pointToFeatureDistanceToleranceInMeters));
|
||||
editor.LoadMapEdits();
|
||||
|
||||
m_model.GetIndex().AddObserver(editor);
|
||||
}
|
||||
|
||||
Framework::~Framework()
|
||||
|
@ -1741,7 +1747,8 @@ bool Framework::ShowMapForURL(string const & url)
|
|||
return false;
|
||||
}
|
||||
|
||||
void Framework::ForEachFeatureAtPoint(TFeatureTypeFn && fn, m2::PointD const & mercator) const
|
||||
void Framework::ForEachFeatureAtPoint(TFeatureTypeFn && fn, m2::PointD const & mercator,
|
||||
double featureDistanceToleranceInMeters) const
|
||||
{
|
||||
constexpr double kSelectRectWidthInMeters = 1.1;
|
||||
constexpr double kMetersToLinearFeature = 3;
|
||||
|
@ -1760,10 +1767,17 @@ void Framework::ForEachFeatureAtPoint(TFeatureTypeFn && fn, m2::PointD const & m
|
|||
fn(ft);
|
||||
break;
|
||||
case feature::GEOM_AREA:
|
||||
if (ft.GetLimitRect(kScale).IsPointInside(mercator) &&
|
||||
feature::GetMinDistanceMeters(ft, mercator) == 0.0)
|
||||
{
|
||||
fn(ft);
|
||||
auto limitRect = ft.GetLimitRect(kScale);
|
||||
// Be a little more tolerant. When used by editor mercator is given
|
||||
// with some error, so we must extend limit rect a bit.
|
||||
limitRect.Inflate(MercatorBounds::GetCellID2PointAbsEpsilon(),
|
||||
MercatorBounds::GetCellID2PointAbsEpsilon());
|
||||
if (limitRect.IsPointInside(mercator) &&
|
||||
feature::GetMinDistanceMeters(ft, mercator) <= featureDistanceToleranceInMeters)
|
||||
{
|
||||
fn(ft);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case feature::GEOM_UNDEFINED:
|
||||
|
|
|
@ -523,7 +523,8 @@ public:
|
|||
/// @returns nullptr if no feature was found at the given mercator point.
|
||||
unique_ptr<FeatureType> GetFeatureAtPoint(m2::PointD const & mercator) const;
|
||||
using TFeatureTypeFn = function<void(FeatureType &)>;
|
||||
void ForEachFeatureAtPoint(TFeatureTypeFn && fn, m2::PointD const & mercator) const;
|
||||
void ForEachFeatureAtPoint(TFeatureTypeFn && fn, m2::PointD const & mercator,
|
||||
double featureDistanceToleranceInMeters = 0.0) const;
|
||||
/// Set parse to false if you don't need all feature fields ready.
|
||||
/// TODO(AlexZ): Refactor code which uses this method to get rid of it.
|
||||
/// FeatureType instances shoud not be used outside ForEach* core methods.
|
||||
|
|
Loading…
Add table
Reference in a new issue