diff --git a/kml/pykmlib/CMakeLists.txt b/kml/pykmlib/CMakeLists.txt index d7418de919..573c9b79e0 100644 --- a/kml/pykmlib/CMakeLists.txt +++ b/kml/pykmlib/CMakeLists.txt @@ -27,6 +27,7 @@ omim_link_libraries( pugixml expat stats_client + succinct ) link_qt5_core(${PROJECT_NAME}) diff --git a/kml/pykmlib/bindings.cpp b/kml/pykmlib/bindings.cpp index ceaad2b87b..8678ebdfc6 100644 --- a/kml/pykmlib/bindings.cpp +++ b/kml/pykmlib/bindings.cpp @@ -8,6 +8,7 @@ #include "geometry/latlon.hpp" #include "geometry/mercator.hpp" +#include "geometry/point_with_altitude.hpp" #include "base/assert.hpp" @@ -125,6 +126,42 @@ struct LocalizableStringAdapter } }; +std::string LatLonToString(ms::LatLon const & latLon); + +struct PointWithAltitudeAdapter +{ + static m2::PointD const & GetPoint(geometry::PointWithAltitude const & ptWithAlt) + { + return ptWithAlt.GetPoint(); + } + + static geometry::Altitude GetAltitude(geometry::PointWithAltitude const & ptWithAlt) + { + return ptWithAlt.GetAltitude(); + } + + static void SetPoint(geometry::PointWithAltitude & ptWithAlt, m2::PointD const & pt) + { + ptWithAlt.SetPoint(pt); + } + + static void SetAltitude(geometry::PointWithAltitude & ptWithAlt, geometry::Altitude altitude) + { + ptWithAlt.SetAltitude(altitude); + } + + static std::string ToString(geometry::PointWithAltitude const & ptWithAlt) + { + auto const latLon = mercator::ToLatLon(ptWithAlt.GetPoint()); + std::ostringstream out; + out << "[" + << "point:" << LatLonToString(latLon) << ", " + << "altitude:" << ptWithAlt.GetAltitude() + << "]"; + return out.str(); + } +}; + struct PropertiesAdapter { static std::string const & Get(Properties const & props, std::string const & key) @@ -243,34 +280,10 @@ void VectorAdapter::PrintType(std::ostringstream & out, TrackLayer c } template<> -boost::python::list VectorAdapter::Get(std::vector const & points) +void VectorAdapter::PrintType(std::ostringstream & out, + geometry::PointWithAltitude const & pt) { - std::vector latLonArray; - latLonArray.reserve(points.size()); - for (size_t i = 0; i < points.size(); ++i) - latLonArray.emplace_back(mercator::YToLat(points[i].y), mercator::XToLon(points[i].x)); - return std_vector_to_python_list(latLonArray); -} - -template<> -void VectorAdapter::Set(std::vector & v, boost::python::object const & iterable) -{ - v.clear(); - if (iterable.is_none()) - return; - - auto const latLon = python_list_to_std_vector(iterable); - v.reserve(latLon.size()); - for (size_t i = 0; i < latLon.size(); ++i) - v.emplace_back(mercator::LonToX(latLon[i].m_lon), mercator::LatToY(latLon[i].m_lat)); -} - -std::string LatLonToString(ms::LatLon const & latLon); -template<> -void VectorAdapter::PrintType(std::ostringstream & out, m2::PointD const & pt) -{ - ms::LatLon const latLon(mercator::YToLat(pt.y), mercator::XToLon(pt.x)); - out << LatLonToString(latLon); + out << PointWithAltitudeAdapter::ToString(pt); } std::string BookmarkDataToString(BookmarkData const & bm); @@ -423,7 +436,8 @@ std::string TrackDataToString(TrackData const & t) << "description:" << LocalizableStringAdapter::ToString(t.m_description) << ", " << "timestamp:" << DebugPrint(t.m_timestamp) << ", " << "layers:" << VectorAdapter::ToString(t.m_layers) << ", " - << "points:" << VectorAdapter::ToString(t.m_points) << ", " + << "points_with_altitudes:" + << VectorAdapter::ToString(t.m_pointsWithAltitudes) << ", " << "visible:" << (t.m_visible ? "True" : "False") << ", " << "nearest_toponyms:" << VectorAdapter::ToString(t.m_nearestToponyms) << ", " << "properties:" << PropertiesAdapter::ToString(t.m_properties) @@ -768,6 +782,13 @@ BOOST_PYTHON_MODULE(pykmlib) .def_readwrite("lon", &ms::LatLon::m_lon) .def("__str__", &LatLonToString); + class_("PointWithAltitude") + .def("get_point", &PointWithAltitudeAdapter::GetPoint, return_value_policy()) + .def("set_point", &PointWithAltitudeAdapter::SetPoint) + .def("get_altitude", &PointWithAltitudeAdapter::GetAltitude) + .def("set_altitude", &PointWithAltitudeAdapter::SetAltitude) + .def("__str__", &PointWithAltitudeAdapter::ToString); + class_("PointD"); class_("Timestamp"); @@ -819,6 +840,12 @@ BOOST_PYTHON_MODULE(pykmlib) .def("set_list", &VectorAdapter::Set) .def("__str__", &VectorAdapter::ToString); + class_>("PointWithAltitudeList") + .def(vector_indexing_suite>()) + .def("get_list", &VectorAdapter::Get) + .def("set_list", &VectorAdapter::Set) + .def("__str__", &VectorAdapter::ToString); + class_>("LatLonList") .def(vector_indexing_suite>()); @@ -828,7 +855,7 @@ BOOST_PYTHON_MODULE(pykmlib) .def_readwrite("description", &TrackData::m_description) .def_readwrite("timestamp", &TrackData::m_timestamp) .def_readwrite("layers", &TrackData::m_layers) - .def_readwrite("points", &TrackData::m_points) + .def_readwrite("points_with_altitudes", &TrackData::m_pointsWithAltitudes) .def_readwrite("visible", &TrackData::m_visible) .def_readwrite("nearest_toponyms", &TrackData::m_nearestToponyms) .def_readwrite("properties", &TrackData::m_properties) diff --git a/kml/pykmlib/bindings_test.py b/kml/pykmlib/bindings_test.py index 524f9dae22..c1bd1d67a5 100644 --- a/kml/pykmlib/bindings_test.py +++ b/kml/pykmlib/bindings_test.py @@ -71,10 +71,16 @@ class PyKmlibAdsTest(unittest.TestCase): track.description['ru'] = 'Тестовое описание трека' track.timestamp = int(datetime.datetime.now().timestamp()) track.layers.set_list([layer1, layer2]) - track.points.set_list([ - pykmlib.LatLon(45.9242, 56.8679), - pykmlib.LatLon(45.2244, 56.2786), - pykmlib.LatLon(45.1964, 56.9832)]) + pt1 = pykmlib.PointWithAltitude() + pt1.set_point(pykmlib.LatLon(45.9242, 56.8679)) + pt1.set_altitude(100) + pt2 = pykmlib.PointWithAltitude() + pt2.set_point(pykmlib.LatLon(45.2244, 56.2786)) + pt2.set_altitude(110) + pt3 = pykmlib.PointWithAltitude() + pt3.set_point(pykmlib.LatLon(45.1964, 56.9832)) + pt3.set_altitude(120) + track.points_with_altitudes.set_list([pt1, pt2, pt3]) track.visible = True track.nearest_toponyms.set_list(['12345', '54321', '98765']) track.properties.set_dict({'tr_property1':'value1', 'tr_property2':'value2'})