1 // Geographic projections for Canvas map element
3 // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Library General Public
7 // License as published by the Free Software Foundation; either
8 // version 2 of the License, or (at your option) any later version.
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Library General Public License for more details.
15 // You should have received a copy of the GNU Library General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #ifndef CANVAS_MAP_PROJECTION_HXX_
20 #define CANVAS_MAP_PROJECTION_HXX_
22 #include <simgear/math/SGMisc.hxx>
30 * Base class for all projections
39 ScreenPosition(double x, double y):
47 virtual ~Projection() {}
49 void setScreenRange(double range)
51 _screen_range = range;
54 virtual ScreenPosition worldToScreen(double x, double y) = 0;
62 * Base class for horizontal projections
64 class HorizontalProjection:
69 HorizontalProjection():
78 * Set world position of center point used for the projection
80 void setWorldPosition(double lat, double lon)
82 _ref_lat = SGMiscd::deg2rad(lat);
83 _ref_lon = SGMiscd::deg2rad(lon);
89 void setOrientation(float hdg)
91 hdg = SGMiscf::deg2rad(hdg);
96 void setRange(double range)
102 * Transform given world position to screen position
104 * @param lat Latitude in degrees
105 * @param lon Longitude in degrees
107 ScreenPosition worldToScreen(double lat, double lon)
109 lat = SGMiscd::deg2rad(lat);
110 lon = SGMiscd::deg2rad(lon);
111 ScreenPosition pos = project(lat, lon);
112 double scale = _screen_range / _range;
115 return ScreenPosition
117 _cos_rot * pos.x - _sin_rot * pos.y,
118 -_sin_rot * pos.x - _cos_rot * pos.y
125 * Project given geographic world position to screen space
127 * @param lat Latitude in radians
128 * @param lon Longitude in radians
130 virtual ScreenPosition project(double lat, double lon) const = 0;
140 * Sanson-Flamsteed projection, relative to the projection center
142 class SansonFlamsteedProjection:
143 public HorizontalProjection
147 virtual ScreenPosition project(double lat, double lon) const
149 double d_lat = lat - _ref_lat,
150 d_lon = lon - _ref_lon;
151 double r = getEarthRadius(lat);
155 pos.x = r * cos(lat) * d_lon;
162 * Returns Earth radius at a given latitude (Ellipsoide equation with two
165 float getEarthRadius(float lat) const
167 const float rec = 6378137.f / 1852; // earth radius, equator (?)
168 const float rpol = 6356752.314f / 1852; // earth radius, polar (?)
170 double a = cos(lat) / rec;
171 double b = sin(lat) / rpol;
172 return 1.0f / sqrt( a * a + b * b );
176 } // namespace canvas
177 } // namespace simgear
179 #endif /* CANVAS_MAP_PROJECTION_HXX_ */