forked from organicmaps/organicmaps
Correct initialization of imperial/metric measurement system.
This commit is contained in:
parent
16aaf56c30
commit
41fa537d42
11 changed files with 165 additions and 105 deletions
|
@ -34,6 +34,8 @@
|
|||
- (void) onResize: (GLint)width withHeight: (GLint)height;
|
||||
- (void) drawFrame;
|
||||
|
||||
- (void) SetupMeasurementSystem;
|
||||
|
||||
// called when app is terminated by system
|
||||
- (void) OnTerminate;
|
||||
- (void) OnEnterForeground;
|
||||
|
|
|
@ -369,4 +369,9 @@ NSInteger compareAddress(id l, id r, void * context)
|
|||
[super viewWillDisappear:animated];
|
||||
}
|
||||
|
||||
- (void) SetupMeasurementSystem
|
||||
{
|
||||
m_framework->SetupMeasurementSystem();
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
- (void) applicationDidFinishLaunching: (UIApplication *) application
|
||||
{
|
||||
[Preferences setup];
|
||||
[Preferences setup:m_mapViewController];
|
||||
|
||||
[m_window addSubview:m_navigationController.view];
|
||||
[m_window makeKeyAndVisible];
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
// Initialize default preferences if they're not initialized
|
||||
@interface Preferences : NSObject
|
||||
+ (void)setup;
|
||||
+ (void)setup:(id)controller;
|
||||
@end
|
||||
|
|
|
@ -1,27 +1,36 @@
|
|||
#import "Preferences.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIAlertView.h>
|
||||
#import "../Classes/MapViewController.h"
|
||||
|
||||
#include "../../platform/settings.hpp"
|
||||
|
||||
@interface PrefDelegate : NSObject
|
||||
{
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) id m_controller;
|
||||
|
||||
@end
|
||||
@implementation PrefDelegate
|
||||
|
||||
@synthesize m_controller;
|
||||
|
||||
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
// User decided to override Imperial system with metric one
|
||||
if (buttonIndex != 0)
|
||||
Settings::Set("Units", Settings::Metric);
|
||||
|
||||
[m_controller SetupMeasurementSystem];
|
||||
|
||||
[self autorelease];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Preferences
|
||||
|
||||
+ (void)setup
|
||||
+ (void)setup:(id)controller
|
||||
{
|
||||
Settings::Units u;
|
||||
if (!Settings::Get("Units", u))
|
||||
|
@ -29,11 +38,15 @@
|
|||
// get system locale preferences
|
||||
BOOL const isMetric = [[[NSLocale autoupdatingCurrentLocale] objectForKey:NSLocaleUsesMetricSystem] boolValue];
|
||||
if (isMetric)
|
||||
{
|
||||
u = Settings::Metric;
|
||||
[controller SetupMeasurementSystem];
|
||||
}
|
||||
else
|
||||
{
|
||||
u = Settings::Foot;
|
||||
PrefDelegate * d = [[PrefDelegate alloc] init];
|
||||
d.m_controller = controller;
|
||||
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Which measurement system do you prefer?"
|
||||
message:nil
|
||||
delegate:d cancelButtonTitle:nil
|
||||
|
@ -43,6 +56,8 @@
|
|||
}
|
||||
Settings::Set("Units", u);
|
||||
}
|
||||
else
|
||||
[controller SetupMeasurementSystem];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -704,4 +704,11 @@ void Framework<TModel>::SetRenderPolicy(shared_ptr<RenderPolicy> const & renderP
|
|||
m_renderPolicy = renderPolicy;
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void Framework<TModel>::SetupMeasurementSystem()
|
||||
{
|
||||
m_informationDisplay.setupRuler();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
template class Framework<model::FeaturesFetcher>;
|
||||
|
|
|
@ -183,6 +183,8 @@ public:
|
|||
|
||||
public:
|
||||
|
||||
void SetupMeasurementSystem();
|
||||
|
||||
void DrawModel(shared_ptr<PaintEvent> const & e,
|
||||
ScreenBase const & screen,
|
||||
m2::RectD const & selectRect,
|
||||
|
|
|
@ -401,6 +401,11 @@ void InformationDisplay::drawBenchmarkInfo(DrawerYG * pDrawer)
|
|||
|
||||
}
|
||||
|
||||
void InformationDisplay::setupRuler()
|
||||
{
|
||||
m_ruler.setup();
|
||||
}
|
||||
|
||||
void InformationDisplay::doDraw(DrawerYG *drawer)
|
||||
{
|
||||
m_yOffset = 0;
|
||||
|
|
|
@ -84,6 +84,7 @@ public:
|
|||
void enableRuler(bool doEnable);
|
||||
void drawRuler(DrawerYG * pDrawer);
|
||||
void setRulerParams(unsigned pxMinWidth, double metresMinWidth, double metresMaxWidth);
|
||||
void setupRuler();
|
||||
|
||||
void enableCenter(bool doEnable);
|
||||
void setCenter(m2::PointD const & latLongPt);
|
||||
|
|
223
map/ruler.cpp
223
map/ruler.cpp
|
@ -14,6 +14,7 @@
|
|||
|
||||
void Ruler::initFeets()
|
||||
{
|
||||
m_units.clear();
|
||||
m_units.push_back(make_pair("100 ft", 100));
|
||||
m_units.push_back(make_pair("200 ft", 200));
|
||||
m_units.push_back(make_pair("0.1 mi", 528));
|
||||
|
@ -32,6 +33,7 @@ void Ruler::initFeets()
|
|||
|
||||
void Ruler::initYards()
|
||||
{
|
||||
m_units.clear();
|
||||
m_units.push_back(make_pair("50 yd", 50));
|
||||
m_units.push_back(make_pair("100 yd", 100));
|
||||
m_units.push_back(make_pair("200 yd", 200));
|
||||
|
@ -50,6 +52,7 @@ void Ruler::initYards()
|
|||
|
||||
void Ruler::initMetres()
|
||||
{
|
||||
m_units.clear();
|
||||
m_units.push_back(make_pair("20 m", 20));
|
||||
m_units.push_back(make_pair("50 m", 50));
|
||||
m_units.push_back(make_pair("100 m", 100));
|
||||
|
@ -74,8 +77,7 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
Ruler::Ruler(Params const & p)
|
||||
: base_t(p), m_boundRects(1)
|
||||
void Ruler::setup()
|
||||
{
|
||||
Settings::Units units;
|
||||
units = Settings::Metric;
|
||||
|
@ -103,6 +105,16 @@ Ruler::Ruler(Params const & p)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_isInitialized = true;
|
||||
if (m_hasPendingUpdate)
|
||||
update();
|
||||
}
|
||||
|
||||
Ruler::Ruler(Params const & p)
|
||||
: base_t(p), m_boundRects(1), m_isInitialized(false), m_hasPendingUpdate(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Ruler::setScreen(ScreenBase const & screen)
|
||||
|
@ -142,83 +154,88 @@ void Ruler::setFontDesc(yg::FontDesc const & fontDesc)
|
|||
|
||||
void Ruler::update()
|
||||
{
|
||||
m2::PointD glbPivot = m_screen.PtoG(pivot());
|
||||
|
||||
int rulerHeight = static_cast<int>(14 * m_visualScale);
|
||||
unsigned minPxWidth = static_cast<unsigned>(m_minPxWidth * m_visualScale);
|
||||
|
||||
m2::PointD pt0 = m_screen.PtoG(pivot() - m2::PointD(minPxWidth / 2, 0));
|
||||
m2::PointD pt1 = m_screen.PtoG(pivot() + m2::PointD(minPxWidth / 2, 0));
|
||||
|
||||
/// correction factor, calculated from Y-coordinate.
|
||||
double const lonDiffCorrection = cos(MercatorBounds::YToLat(glbPivot.y) / 180.0 * math::pi);
|
||||
|
||||
/// longitude difference between two points
|
||||
double lonDiff = fabs(MercatorBounds::XToLon(pt0.x) - MercatorBounds::XToLon(pt1.x));
|
||||
|
||||
/// converting into metres
|
||||
/// TODO : calculate in different units
|
||||
|
||||
m_metresDiff = lonDiff / MercatorBounds::degreeInMetres * lonDiffCorrection;
|
||||
|
||||
if (m_units[0].second > m_conversionFn(m_metresDiff))
|
||||
if (m_isInitialized)
|
||||
{
|
||||
m_scalerText = "<" + m_units[0].first;
|
||||
m_metresDiff = m_minUnitsWidth - 1;
|
||||
}
|
||||
else if (m_units.back().second <= m_conversionFn(m_metresDiff))
|
||||
{
|
||||
m_scalerText = ">" + m_units.back().first;
|
||||
m_metresDiff = m_maxUnitsWidth + 1;
|
||||
m2::PointD glbPivot = m_screen.PtoG(pivot());
|
||||
|
||||
int rulerHeight = static_cast<int>(14 * m_visualScale);
|
||||
unsigned minPxWidth = static_cast<unsigned>(m_minPxWidth * m_visualScale);
|
||||
|
||||
m2::PointD pt0 = m_screen.PtoG(pivot() - m2::PointD(minPxWidth / 2, 0));
|
||||
m2::PointD pt1 = m_screen.PtoG(pivot() + m2::PointD(minPxWidth / 2, 0));
|
||||
|
||||
/// correction factor, calculated from Y-coordinate.
|
||||
double const lonDiffCorrection = cos(MercatorBounds::YToLat(glbPivot.y) / 180.0 * math::pi);
|
||||
|
||||
/// longitude difference between two points
|
||||
double lonDiff = fabs(MercatorBounds::XToLon(pt0.x) - MercatorBounds::XToLon(pt1.x));
|
||||
|
||||
/// converting into metres
|
||||
/// TODO : calculate in different units
|
||||
|
||||
m_metresDiff = lonDiff / MercatorBounds::degreeInMetres * lonDiffCorrection;
|
||||
|
||||
if (m_units[0].second > m_conversionFn(m_metresDiff))
|
||||
{
|
||||
m_scalerText = "<" + m_units[0].first;
|
||||
m_metresDiff = m_minUnitsWidth - 1;
|
||||
}
|
||||
else if (m_units.back().second <= m_conversionFn(m_metresDiff))
|
||||
{
|
||||
m_scalerText = ">" + m_units.back().first;
|
||||
m_metresDiff = m_maxUnitsWidth + 1;
|
||||
}
|
||||
else
|
||||
for (size_t i = 0; i < m_units.size(); ++i)
|
||||
{
|
||||
if (m_units[i].second > m_conversionFn(m_metresDiff))
|
||||
{
|
||||
m_metresDiff = m_units[i].second / m_conversionFn(1);
|
||||
m_scalerText = m_units[i].first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool higherThanMax = m_metresDiff > m_maxUnitsWidth;
|
||||
bool lessThanMin = m_metresDiff < m_minUnitsWidth;
|
||||
|
||||
/// translating metres into pixels
|
||||
double scalerWidthLatDiff = (double)m_metresDiff * MercatorBounds::degreeInMetres / lonDiffCorrection;
|
||||
double scalerWidthXDiff = MercatorBounds::LonToX(glbPivot.x + scalerWidthLatDiff / 2)
|
||||
- MercatorBounds::LonToX(glbPivot.x - scalerWidthLatDiff / 2);
|
||||
|
||||
double scalerWidthInPx = m_screen.GtoP(glbPivot).x - m_screen.GtoP(glbPivot + m2::PointD(scalerWidthXDiff, 0)).x;
|
||||
scalerWidthInPx = (higherThanMax || lessThanMin) ? minPxWidth : abs(my::rounds(scalerWidthInPx));
|
||||
|
||||
m2::PointD scalerOrg = pivot() + m2::PointD(-scalerWidthInPx / 2, rulerHeight / 2);
|
||||
|
||||
if (position() & yg::EPosLeft)
|
||||
scalerOrg.x -= scalerWidthInPx / 2;
|
||||
|
||||
if (position() & yg::EPosRight)
|
||||
scalerOrg.x += scalerWidthInPx / 2;
|
||||
|
||||
if (position() & yg::EPosAbove)
|
||||
scalerOrg.y -= rulerHeight / 2;
|
||||
|
||||
if (position() & yg::EPosUnder)
|
||||
scalerOrg.y += rulerHeight / 2;
|
||||
|
||||
m_path.clear();
|
||||
m_path.push_back(scalerOrg + m2::PointD(0, -rulerHeight));
|
||||
m_path.push_back(scalerOrg);
|
||||
m_path.push_back(scalerOrg + m2::PointD(scalerWidthInPx, 0));
|
||||
m_path.push_back(m_path[2] + m2::PointD(0, -rulerHeight));
|
||||
|
||||
/// calculating bound rect
|
||||
|
||||
m_boundRect = m2::RectD(m_path[0], m_path[0]);
|
||||
m_boundRect.Add(m_path[1]);
|
||||
m_boundRect.Add(m_path[2]);
|
||||
m_boundRect.Add(m_path[3]);
|
||||
}
|
||||
else
|
||||
for (size_t i = 0; i < m_units.size(); ++i)
|
||||
{
|
||||
if (m_units[i].second > m_conversionFn(m_metresDiff))
|
||||
{
|
||||
m_metresDiff = m_units[i].second / m_conversionFn(1);
|
||||
m_scalerText = m_units[i].first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool higherThanMax = m_metresDiff > m_maxUnitsWidth;
|
||||
bool lessThanMin = m_metresDiff < m_minUnitsWidth;
|
||||
|
||||
/// translating metres into pixels
|
||||
double scalerWidthLatDiff = (double)m_metresDiff * MercatorBounds::degreeInMetres / lonDiffCorrection;
|
||||
double scalerWidthXDiff = MercatorBounds::LonToX(glbPivot.x + scalerWidthLatDiff / 2)
|
||||
- MercatorBounds::LonToX(glbPivot.x - scalerWidthLatDiff / 2);
|
||||
|
||||
double scalerWidthInPx = m_screen.GtoP(glbPivot).x - m_screen.GtoP(glbPivot + m2::PointD(scalerWidthXDiff, 0)).x;
|
||||
scalerWidthInPx = (higherThanMax || lessThanMin) ? minPxWidth : abs(my::rounds(scalerWidthInPx));
|
||||
|
||||
m2::PointD scalerOrg = pivot() + m2::PointD(-scalerWidthInPx / 2, rulerHeight / 2);
|
||||
|
||||
if (position() & yg::EPosLeft)
|
||||
scalerOrg.x -= scalerWidthInPx / 2;
|
||||
|
||||
if (position() & yg::EPosRight)
|
||||
scalerOrg.x += scalerWidthInPx / 2;
|
||||
|
||||
if (position() & yg::EPosAbove)
|
||||
scalerOrg.y -= rulerHeight / 2;
|
||||
|
||||
if (position() & yg::EPosUnder)
|
||||
scalerOrg.y += rulerHeight / 2;
|
||||
|
||||
m_path.clear();
|
||||
m_path.push_back(scalerOrg + m2::PointD(0, -rulerHeight));
|
||||
m_path.push_back(scalerOrg);
|
||||
m_path.push_back(scalerOrg + m2::PointD(scalerWidthInPx, 0));
|
||||
m_path.push_back(m_path[2] + m2::PointD(0, -rulerHeight));
|
||||
|
||||
/// calculating bound rect
|
||||
|
||||
m_boundRect = m2::RectD(m_path[0], m_path[0]);
|
||||
m_boundRect.Add(m_path[1]);
|
||||
m_boundRect.Add(m_path[2]);
|
||||
m_boundRect.Add(m_path[3]);
|
||||
m_hasPendingUpdate = true;
|
||||
}
|
||||
|
||||
vector<m2::AnyRectD> const & Ruler::boundRects() const
|
||||
|
@ -229,39 +246,41 @@ vector<m2::AnyRectD> const & Ruler::boundRects() const
|
|||
|
||||
void Ruler::draw(yg::gl::OverlayRenderer * s, math::Matrix<double, 3, 3> const & m) const
|
||||
{
|
||||
s->drawPath(
|
||||
&m_path[0], m_path.size(), 0,
|
||||
s->skin()->mapPenInfo(yg::PenInfo(yg::Color(255, 255, 255, 255), 2 * m_visualScale, 0, 0, 0)),
|
||||
depth() - 3);
|
||||
if (m_isInitialized)
|
||||
{
|
||||
s->drawPath(
|
||||
&m_path[0], m_path.size(), 0,
|
||||
s->skin()->mapPenInfo(yg::PenInfo(yg::Color(255, 255, 255, 255), 2 * m_visualScale, 0, 0, 0)),
|
||||
depth() - 3);
|
||||
|
||||
s->drawPath(
|
||||
&m_path[0], m_path.size(), 0,
|
||||
s->skin()->mapPenInfo(yg::PenInfo(yg::Color(0, 0, 0, 255), 1 * m_visualScale, 0, 0, 0)),
|
||||
depth() - 2);
|
||||
s->drawPath(
|
||||
&m_path[0], m_path.size(), 0,
|
||||
s->skin()->mapPenInfo(yg::PenInfo(yg::Color(0, 0, 0, 255), 1 * m_visualScale, 0, 0, 0)),
|
||||
depth() - 2);
|
||||
|
||||
if (position() & yg::EPosLeft)
|
||||
s->drawText(m_fontDesc,
|
||||
m_path[2] + m2::PointD(-7, -7),
|
||||
yg::EPosAboveLeft,
|
||||
m_scalerText.c_str(),
|
||||
depth(),
|
||||
false);
|
||||
else
|
||||
if (position() & yg::EPosRight)
|
||||
if (position() & yg::EPosLeft)
|
||||
s->drawText(m_fontDesc,
|
||||
m_path[1] + m2::PointD(7, -7),
|
||||
yg::EPosAboveRight,
|
||||
m_path[2] + m2::PointD(-7, -7),
|
||||
yg::EPosAboveLeft,
|
||||
m_scalerText.c_str(),
|
||||
depth(),
|
||||
false);
|
||||
else
|
||||
s->drawText(m_fontDesc,
|
||||
(m_path[1] + m_path[2]) * 0.5 + m2::PointD(0, -7),
|
||||
yg::EPosAbove,
|
||||
m_scalerText.c_str(),
|
||||
depth(),
|
||||
false);
|
||||
|
||||
if (position() & yg::EPosRight)
|
||||
s->drawText(m_fontDesc,
|
||||
m_path[1] + m2::PointD(7, -7),
|
||||
yg::EPosAboveRight,
|
||||
m_scalerText.c_str(),
|
||||
depth(),
|
||||
false);
|
||||
else
|
||||
s->drawText(m_fontDesc,
|
||||
(m_path[1] + m_path[2]) * 0.5 + m2::PointD(0, -7),
|
||||
yg::EPosAbove,
|
||||
m_scalerText.c_str(),
|
||||
depth(),
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
void Ruler::map(yg::StylesCache * stylesCache) const
|
||||
|
|
|
@ -47,6 +47,9 @@ private:
|
|||
vector<pair<string, double> > m_units;
|
||||
ConversionFn m_conversionFn;
|
||||
|
||||
bool m_isInitialized;
|
||||
bool m_hasPendingUpdate;
|
||||
|
||||
void initYards();
|
||||
void initMetres();
|
||||
void initFeets();
|
||||
|
@ -60,6 +63,7 @@ public:
|
|||
};
|
||||
|
||||
Ruler(Params const & p);
|
||||
void setup();
|
||||
|
||||
void setScreen(ScreenBase const & screen);
|
||||
ScreenBase const & screen() const;
|
||||
|
|
Loading…
Add table
Reference in a new issue