diff --git a/map/chart_generator.cpp b/map/chart_generator.cpp index 55c5468a12..e83f3d0460 100644 --- a/map/chart_generator.cpp +++ b/map/chart_generator.cpp @@ -83,6 +83,24 @@ agg::rgba8 GetCurveColor(MapStyle mapStyle) namespace maps { +void ScaleChartData(vector & chartData, double scale) +{ + for (size_t i = 0; i < chartData.size(); ++i) + chartData[i] *= scale; +} + +void ShiftChartData(vector & chartData, double shift) +{ + for (size_t i = 0; i < chartData.size(); ++i) + chartData[i] += shift; +} + +void ReflectChartData(vector & chartData) +{ + for (size_t i = 0; i < chartData.size(); ++i) + chartData[i] = -chartData[i]; +} + bool NormalizeChartData(vector const & distanceDataM, feature::TAltitudes const & altitudeDataM, size_t resultPointCount, vector & uniformAltitudeDataM) @@ -166,10 +184,20 @@ bool GenerateYAxisChartData(uint32_t height, double minMetersPerPxl, return false; } - size_t const altitudeDataSize = altitudeDataM.size(); - yAxisDataPxl.resize(altitudeDataSize); - for (size_t i = 0; i < altitudeDataSize; ++i) - yAxisDataPxl[i] = height - heightIndentPxl - (altitudeDataM[i] - minAltM) / metersPerPxl; + double const deltaAltPxl = deltaAltM / metersPerPxl; + double const freeHeightSpacePxl = drawHeightPxl - deltaAltPxl; + if (freeHeightSpacePxl < 0 || freeHeightSpacePxl > drawHeightPxl) + { + LOG(LERROR, ("Number of pixels free of chart points (", freeHeightSpacePxl, + ") is below zero or greater than the number of pixels for the chart (", drawHeightPxl, ").")); + return false; + } + + double const maxAltPxl = maxAltM / metersPerPxl; + yAxisDataPxl.assign(altitudeDataM.cbegin(), altitudeDataM.cend()); + ScaleChartData(yAxisDataPxl, 1.0 / metersPerPxl); + ReflectChartData(yAxisDataPxl); + ShiftChartData(yAxisDataPxl, maxAltPxl + heightIndentPxl + freeHeightSpacePxl / 2.0); return true; } diff --git a/map/chart_generator.hpp b/map/chart_generator.hpp index 34e56dc92f..e3f5bfc04f 100644 --- a/map/chart_generator.hpp +++ b/map/chart_generator.hpp @@ -10,8 +10,13 @@ namespace maps { + uint32_t constexpr kAltitudeChartBPP = 4; +void ScaleChartData(vector & chartData, double scale); +void ShiftChartData(vector & chartData, double shift); +void ReflectChartData(vector & chartData); + /// \brief fills uniformAltitudeDataM with altitude data which evenly distributed by /// |resultPointCount| points. |distanceDataM| and |altitudeDataM| form a curve of route altitude. /// This method is used to generalize and evenly distribute points of the chart. diff --git a/map/map_tests/chart_generator_tests.cpp b/map/map_tests/chart_generator_tests.cpp index 510e9aa517..3ca39d4aa1 100644 --- a/map/map_tests/chart_generator_tests.cpp +++ b/map/map_tests/chart_generator_tests.cpp @@ -47,6 +47,30 @@ void TestAngleColors(size_t width, size_t height, vector const & frameB expectedR, expectedG, expectedB, expectedA), ()); } +UNIT_TEST(ScaleChartData_Test) +{ + vector chartData = {0.0, -1.0, 2.0}; + maps::ScaleChartData(chartData, 2.0 /* scale */); + vector const expectedChartData = {0.0, -2.0, 4.0}; + TEST_EQUAL(chartData, expectedChartData, ()); +} + +UNIT_TEST(ShiftChartData_Test) +{ + vector chartData = {0.0, -1.0, 2.0}; + maps::ShiftChartData(chartData, 1 /* shift */); + vector const expectedChartData = {1.0, 0.0, 3.0}; + TEST_EQUAL(chartData, expectedChartData, ()); +} + +UNIT_TEST(ReflectChartData_Test) +{ + vector chartData = {0.0, -1.0, 2.0}; + maps::ReflectChartData(chartData); + vector const expectedChartData = {0.0, 1.0, -2.0}; + TEST_EQUAL(chartData, expectedChartData, ()); +} + UNIT_TEST(NormalizeChartData_SmokeTest) { vector const distanceDataM = {0.0, 0.0, 0.0}; @@ -104,8 +128,8 @@ UNIT_TEST(GenerateYAxisChartData_SmokeTest) vector yAxisDataPxl; TEST(maps::GenerateYAxisChartData(30 /* height */, 1.0 /* minMetersPerPxl */, altitudeDataM, yAxisDataPxl), ()); - vector expecttedYAxisDataPxl = {28.0, 28.0}; - TEST(AlmostEqualAbs(yAxisDataPxl, expecttedYAxisDataPxl), ()); + vector expectedYAxisDataPxl = {15.0, 15.0}; + TEST(AlmostEqualAbs(yAxisDataPxl, expectedYAxisDataPxl), ()); } UNIT_TEST(GenerateYAxisChartData_EmptyAltitudeDataTest) @@ -123,8 +147,8 @@ UNIT_TEST(GenerateYAxisChartData_Test) vector yAxisDataPxl; TEST(maps::GenerateYAxisChartData(100 /* height */, 1.0 /* minMetersPerPxl */, altitudeDataM, yAxisDataPxl), ()); - vector expecttedYAxisDataPxl = {96.0, 94.0, 96.0, 98.0, 95.0}; - TEST(AlmostEqualAbs(yAxisDataPxl, expecttedYAxisDataPxl), ()); + vector expectedYAxisDataPxl = {50.0, 48.0, 50.0, 52.0, 49.0}; + TEST(AlmostEqualAbs(yAxisDataPxl, expectedYAxisDataPxl), ()); } UNIT_TEST(GenerateChartByPoints_NoGeometryTest)