Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Magidovich <mgsergio@mapswithme.com>2016-02-04 11:15:05 +0300
committerSergey Yershov <yershov@corp.mail.ru>2016-03-23 16:20:41 +0300
commit0e5fd3b1fbc0af74ec4cc9ecdc5988010a35f48e (patch)
tree028cfa64194b56f3e9beb6c68bc83a88074ccd7b
parent26b38cff750e2ce01c1d7fe06680878583ade380 (diff)
Geometry serialization.
-rw-r--r--editor/editor_tests/xml_feature_test.cpp17
-rw-r--r--editor/xml_feature.cpp51
-rw-r--r--editor/xml_feature.hpp11
-rw-r--r--indexer/feature.cpp11
4 files changed, 82 insertions, 8 deletions
diff --git a/editor/editor_tests/xml_feature_test.cpp b/editor/editor_tests/xml_feature_test.cpp
index aa7bfd82ce..6ccc0e713f 100644
--- a/editor/editor_tests/xml_feature_test.cpp
+++ b/editor/editor_tests/xml_feature_test.cpp
@@ -236,3 +236,20 @@ UNIT_TEST(XMLFeature_FromXmlNode)
TEST_EQUAL(copy.GetAttribute("id"), "4", ());
TEST_EQUAL(copy.GetTagValue("amenity"), "fountain", ());
}
+
+UNIT_TEST(XMLFeature_Geometry)
+{
+ XMLFeature::TMercatorGeometry const geometry = {
+ {28.7206411, 3.7182409},
+ {46.7569003, 47.0774689},
+ {22.5909217, 41.6994874},
+ {14.7537008, 17.7788229},
+ {55.1261701, 10.3199476},
+ {28.6519654, 50.0305930},
+ {28.7206411, 3.7182409}
+ };
+
+ XMLFeature feature(XMLFeature::Type::Way);
+ feature.SetGeometry(geometry);
+ TEST_EQUAL(feature.GetGeometry(), geometry, ());
+}
diff --git a/editor/xml_feature.cpp b/editor/xml_feature.cpp
index b3b46a210e..b5729a98cb 100644
--- a/editor/xml_feature.cpp
+++ b/editor/xml_feature.cpp
@@ -26,7 +26,7 @@ pugi::xml_node FindTag(pugi::xml_document const & document, string const & key)
return document.select_node(("//tag[@k='" + key + "']").data()).node();
}
-ms::LatLon PointFromLatLon(pugi::xml_node const & node)
+ms::LatLon GetLatLonFromNode(pugi::xml_node const & node)
{
ms::LatLon ll;
if (!strings::to_double(node.attribute("lat").value(), ll.lat))
@@ -36,6 +36,16 @@ ms::LatLon PointFromLatLon(pugi::xml_node const & node)
return ll;
}
+m2::PointD GetMercatorPointFromNode(pugi::xml_node const & node)
+{
+ m2::PointD p;
+ if (!strings::to_double(node.attribute("x").value(), p.x))
+ MYTHROW(editor::NoXY, ("Can't parse x attribute: " + string(node.attribute("x").value())));
+ if (!strings::to_double(node.attribute("y").value(), p.y))
+ MYTHROW(editor::NoXY, ("Can't parse y attribute: " + string(node.attribute("y").value())));
+ return p;
+}
+
void ValidateElement(pugi::xml_node const & nodeOrWay)
{
if (!nodeOrWay)
@@ -43,14 +53,13 @@ void ValidateElement(pugi::xml_node const & nodeOrWay)
string const type = nodeOrWay.name();
if (type == kNodeType)
- UNUSED_VALUE(PointFromLatLon(nodeOrWay));
+ UNUSED_VALUE(GetLatLonFromNode(nodeOrWay));
else if (type != kWayType)
MYTHROW(editor::InvalidXML, ("XMLFeature does not support root tag", type));
if (!nodeOrWay.attribute(kTimestamp))
MYTHROW(editor::NoTimestamp, ("Node has no timestamp attribute"));
}
-
} // namespace
namespace editor
@@ -157,7 +166,7 @@ void XMLFeature::ApplyPatch(XMLFeature const & featureWithChanges)
ms::LatLon XMLFeature::GetCenter() const
{
- return PointFromLatLon(GetRootNode());
+ return GetLatLonFromNode(GetRootNode());
}
void XMLFeature::SetCenter(ms::LatLon const & ll)
@@ -172,6 +181,32 @@ void XMLFeature::SetCenter(m2::PointD const & mercatorCenter)
SetCenter(MercatorBounds::ToLatLon(mercatorCenter));
}
+XMLFeature::TMercatorGeometry XMLFeature::GetGeometry() const
+{
+ ASSERT_EQUAL(GetType(), Type::Way, ("Only ways have geometry"));
+ TMercatorGeometry geometry;
+ for (auto const xCenter : GetRootNode().select_nodes("nd"))
+ {
+ ASSERT(xCenter.node(), ("no nd attribute."));
+ geometry.emplace_back(GetMercatorPointFromNode(xCenter.node()));
+ }
+ return geometry;
+}
+
+/// Geometry points are now stored in <nd x="..." y="..." /> nodes like in osm <way>.
+/// But they are not the same as osm's. I.e. osm's one stores reference to a <node>
+/// with it's own data and lat, lon. Here we store only cooridanes in mercator.
+void XMLFeature::SetGeometry(TMercatorGeometry const & geometry)
+{
+ ASSERT_EQUAL(GetType(), Type::Way, ("Only ways have geometry"));
+ for (auto const & point : geometry)
+ {
+ auto nd = GetRootNode().append_child("nd");
+ nd.append_attribute("x") = strings::to_string_dac(point.x, kLatLonTolerance).data();
+ nd.append_attribute("y") = strings::to_string_dac(point.y, kLatLonTolerance).data();
+ }
+}
+
string XMLFeature::GetName(string const & lang) const
{
auto const suffix = (lang == kDefaultLang || lang.empty()) ? "" : ":" + lang;
@@ -332,4 +367,12 @@ string DebugPrint(XMLFeature const & feature)
return ost.str();
}
+string DebugPrint(XMLFeature::Type const type)
+{
+ switch (type)
+ {
+ case XMLFeature::Type::Node: return "Node";
+ case XMLFeature::Type::Way: return "Way";
+ }
+}
} // namespace editor
diff --git a/editor/xml_feature.hpp b/editor/xml_feature.hpp
index 0c368f3226..83578a89e9 100644
--- a/editor/xml_feature.hpp
+++ b/editor/xml_feature.hpp
@@ -18,6 +18,7 @@ namespace editor
DECLARE_EXCEPTION(XMLFeatureError, RootException);
DECLARE_EXCEPTION(InvalidXML, XMLFeatureError);
DECLARE_EXCEPTION(NoLatLon, XMLFeatureError);
+DECLARE_EXCEPTION(NoXY, XMLFeatureError);
DECLARE_EXCEPTION(NoTimestamp, XMLFeatureError);
DECLARE_EXCEPTION(NoHeader, XMLFeatureError);
@@ -34,6 +35,8 @@ public:
Way
};
+ using TMercatorGeometry = vector<m2::PointD>;
+
/// Creates empty node or way.
XMLFeature(Type const type);
XMLFeature(string const & xml);
@@ -60,6 +63,12 @@ public:
void SetCenter(ms::LatLon const & ll);
void SetCenter(m2::PointD const & mercatorCenter);
+ TMercatorGeometry GetGeometry() const;
+
+ /// Sets geometry in mercator to match against FeatureType's geometry in mwm
+ /// when megrating to a new mwm build.
+ void SetGeometry(TMercatorGeometry const & geometry);
+
string GetName(string const & lang) const;
string GetName(uint8_t const langCode = StringUtf8Multilang::DEFAULT_CODE) const;
@@ -133,5 +142,5 @@ private:
};
string DebugPrint(XMLFeature const & feature);
-
+string DebugPrint(XMLFeature::Type const type);
} // namespace editor
diff --git a/indexer/feature.cpp b/indexer/feature.cpp
index 54eaa6bf9a..5789fe9481 100644
--- a/indexer/feature.cpp
+++ b/indexer/feature.cpp
@@ -96,10 +96,15 @@ editor::XMLFeature FeatureType::ToXML() const
? editor::XMLFeature::Type::Node
: editor::XMLFeature::Type::Way);
- // Only Poins are completely serialized and deserialized.
- // Other types could only be patched.
if (GetFeatureType() == feature::GEOM_POINT)
+ {
feature.SetCenter(GetCenter());
+ }
+ else
+ {
+ ParseTriangles(BEST_GEOMETRY);
+ feature.SetGeometry({begin(m_triangles), end(m_triangles)});
+ }
ForEachName([&feature](uint8_t const & lang, string const & name)
{
@@ -124,7 +129,7 @@ editor::XMLFeature FeatureType::ToXML() const
// feature.SetTagValue(tag.first, tag.second);
// }
- for (auto const type : m_metadata.GetPresentTypes())
+ for (auto const type : GetMetadata().GetPresentTypes())
{
auto const attributeName = DebugPrint(static_cast<Metadata::EType>(type));
feature.SetTagValue(attributeName, m_metadata.Get(type));