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

mercator.hpp « geometry - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 95b04c6f408e8d3271533de9008e61a964fc00f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#pragma once
#include "geometry/latlon.hpp"
#include "geometry/point2d.hpp"
#include "geometry/rect2d.hpp"

#include "base/math.hpp"


struct MercatorBounds
{
  static double minX;
  static double maxX;
  static double minY;
  static double maxY;

  inline static m2::RectD FullRect() { return m2::RectD(minX, minY, maxX, maxY); }

  inline static bool ValidLon(double d)
  {
    return my::between_s(-180.0, 180.0, d);
  }
  inline static bool ValidLat(double d)
  {
    return my::between_s(-90.0, 90.0, d);
  }

  inline static bool ValidX(double d)
  {
    return my::between_s(minX, maxX, d);
  }
  inline static bool ValidY(double d)
  {
    return my::between_s(minY, maxY, d);
  }

  inline static double ClampX(double d)
  {
    return my::clamp(d, minX, maxX);
  }
  inline static double ClampY(double d)
  {
    return my::clamp(d, minY, maxY);
  }

  inline static double YToLat(double y)
  {
    return my::RadToDeg(2.0 * atan(tanh(0.5 * my::DegToRad(y))));
  }

  inline static double LatToY(double lat)
  {
    double const sinx = sin(my::DegToRad(my::clamp(lat, -86.0, 86.0)));
    double const res = my::RadToDeg(0.5 * log((1.0 + sinx) / (1.0 - sinx)));
    return ClampY(res);
  }

  inline static double XToLon(double x)
  {
    return x;
  }

  inline static double LonToX(double lon)
  {
    return lon;
  }

  static double constexpr degreeInMetres = 360.0 / 40008245;

  /// @name Get rect for center point (lon, lat) and dimensions in metres.
  //@{
  /// @return mercator rect.
  static m2::RectD MetresToXY(double lon, double lat,
                              double lonMetresR, double latMetresR);

  inline static m2::RectD MetresToXY(double lon, double lat, double metresR)
  {
    return MetresToXY(lon, lat, metresR, metresR);
  }
  //@}

  inline static m2::RectD RectByCenterXYAndSizeInMeters(double centerX, double centerY,
                                                        double sizeX, double sizeY)
  {
    ASSERT_GREATER_OR_EQUAL(sizeX, 0, ());
    ASSERT_GREATER_OR_EQUAL(sizeY, 0, ());

    return MetresToXY(XToLon(centerX), YToLat(centerY), sizeX, sizeY);
  }

  inline static m2::RectD RectByCenterXYAndSizeInMeters(m2::PointD const & center, double size)
  {
    return RectByCenterXYAndSizeInMeters(center.x, center.y, size, size);
  }

  static m2::PointD GetSmPoint(m2::PointD const & pt, double lonMetresR, double latMetresR);

  static double constexpr GetCellID2PointAbsEpsilon() { return 1.0E-4; }

  inline static m2::PointD FromLatLon(double lat, double lon)
  {
    return m2::PointD(LonToX(lon), LatToY(lat));
  }

  inline static m2::PointD FromLatLon(ms::LatLon const & point)
  {
    return FromLatLon(point.lat, point.lon);
  }

  inline static m2::RectD RectByCenterLatLonAndSizeInMeters(double lat, double lon, double size)
  {
    return RectByCenterXYAndSizeInMeters(FromLatLon(lat, lon), size);
  }

  inline static ms::LatLon ToLatLon(m2::PointD const & point)
  {
    return {YToLat(point.y), XToLon(point.x)};
  }

  /// Converts lat lon rect to mercator one
  inline static m2::RectD FromLatLonRect(m2::RectD const & latLonRect)
  {
    return m2::RectD(FromLatLon(latLonRect.minY(), latLonRect.minX()),
                     FromLatLon(latLonRect.maxY(), latLonRect.maxX()));
  }

  /// Calculates distance on Earth by two points in mercator
  static double DistanceOnEarth(m2::PointD const & p1, m2::PointD const & p2);

  /// Calculates area of a triangle on Earth in m² by three points
  static double AreaOnEarth(m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3);
};