1 /**************************************************************************
2 * newbucket.hxx -- new bucket routines for better world modeling
4 * Written by Curtis L. Olson, started February 1999.
6 * Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
24 **************************************************************************/
34 #include <simgear/misc/fgpath.hxx>
36 #include "newbucket.hxx"
39 // Build the path name for this bucket
40 string FGBucket::gen_base_path() const {
42 int top_lon, top_lat, main_lon, main_lat;
48 if ( (lon < 0) && (top_lon * 10 != lon) ) {
64 if ( (lat < 0) && (top_lat * 10 != lat) ) {
78 sprintf(raw_path, "%c%03d%c%02d/%c%03d%c%02d",
79 hem, top_lon, pole, top_lat,
80 hem, main_lon, pole, main_lat);
82 FGPath path( raw_path );
88 // return width of the tile in meters
89 double FGBucket::get_width_m() const {
90 double clat = (int)get_center_lat();
92 clat = (int)clat + 0.5;
94 clat = (int)clat - 0.5;
96 double clat_rad = clat * DEG_TO_RAD;
97 double cos_lat = cos( clat_rad );
98 double local_radius = cos_lat * EQUATORIAL_RADIUS_M;
99 double local_perimeter = 2.0 * local_radius * FG_PI;
100 double degree_width = local_perimeter / 360.0;
102 return bucket_span( get_center_lat() ) * degree_width;
106 // return height of the tile in meters
107 double FGBucket::get_height_m() const {
108 double perimeter = 2.0 * EQUATORIAL_RADIUS_M * FG_PI;
109 double degree_height = perimeter / 360.0;
111 return FG_BUCKET_SPAN * degree_height;
115 // find the bucket which is offset by the specified tile units in the
116 // X & Y direction. We need the current lon and lat to resolve
117 // ambiguities when going from a wider tile to a narrower one above or
118 // below. This assumes that we are feeding in
119 FGBucket fgBucketOffset( double dlon, double dlat, int dx, int dy ) {
120 FGBucket result( dlon, dlat );
121 double clat = result.get_center_lat() + dy * FG_BUCKET_SPAN;
123 // walk dy units in the lat direction
124 result.set_bucket( dlon, clat );
126 // find the lon span for the new latitude
127 double span = bucket_span( clat );
129 // walk dx units in the lon direction
130 double tmp = dlon + dx * span;
131 while ( tmp < -180.0 ) {
134 while ( tmp >= 180.0 ) {
137 result.set_bucket( tmp, clat );
143 // calculate the offset between two buckets
144 void fgBucketDiff( const FGBucket& b1, const FGBucket& b2, int *dx, int *dy ) {
146 // Latitude difference
147 double c1_lat = b1.get_center_lat();
148 double c2_lat = b2.get_center_lat();
149 double diff_lat = c2_lat - c1_lat;
152 *dy = (int)rint( diff_lat / FG_BUCKET_SPAN );
154 if ( diff_lat > 0 ) {
155 *dy = (int)( diff_lat / FG_BUCKET_SPAN + 0.5 );
157 *dy = (int)( diff_lat / FG_BUCKET_SPAN - 0.5 );
161 // longitude difference
162 double c1_lon = b1.get_center_lon();
163 double c2_lon = b2.get_center_lon();
164 double diff_lon = c2_lon - c1_lon;
166 if ( bucket_span(c1_lat) <= bucket_span(c2_lat) ) {
167 span = bucket_span(c1_lat);
169 span = bucket_span(c2_lat);
173 *dx = (int)rint( diff_lon / span );
175 if ( diff_lon > 0 ) {
176 *dx = (int)( diff_lon / span + 0.5 );
178 *dx = (int)( diff_lon / span - 0.5 );