2 * This file is part of mapper
4 * Copyright (C) 2007 Kaj-Michael Lang
6 * Original Algorithms from misc web sites
8 * Default map data provided by http://www.openstreetmap.org/
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * Different Lat/Lon and related functions
27 * (conversion, distances, etc)
37 /* Int ranges for integerized lat/lon */
38 #define LATLON_MAX 2147483646
39 #define LATLON_MIN -2147483646
41 #define EARTH_RADIUS (3440.06479f)
44 magnitude(gdouble x1, gdouble y1, gdouble x2, gdouble y2)
50 return sqrt((x*x)+(y*y));
54 distance_point_to_line(gdouble x, gdouble y, gdouble x1, gdouble y1, gdouble x2, gdouble y2, gdouble *d)
59 lm=magnitude(x1,y1,x2,y2);
63 tmp=((x-x1)*(x2-x1))+((y-y1)*(y2-y1));
72 *d=magnitude(x,y, ix, iy);
78 * QuadTile calculation functions, from:
79 * http://trac.openstreetmap.org/browser/sites/rails_port/lib/quad_tile/quad_tile.h
82 xy2tile(guint x, guint y)
88 tile=(tile << 1) | ((x >> i) & 1);
89 tile=(tile << 1) | ((y >> i) & 1);
97 return round((lon + 180.0) * 65535.0 / 360.0);
103 return round((lat + 90.0) * 65535.0 / 180.0);
107 * Convert latitude to integerized+mercator projected value
110 lat2mp_int(gdouble lat)
112 return lat > 85.051128779 ? LATLON_MAX : lat < -85.051128779 ? LATLON_MIN :
113 lrint(log(tan(M_PI_4l+lat*M_PIl/360))/M_PIl*LATLON_MAX);
117 * Convert longitude to integerized+mercator projected value
120 lon2mp_int(gdouble lon)
122 return lrint(lon/180*LATLON_MAX);
128 return (gdouble)lon/LATLON_MAX*180;
138 * Quick distance calculation, (does not handle earth curvature, so use for quick non exact needs only)
141 calculate_idistance(gint lat1, gint lon1, gint lat2, gint lon2)
143 return lrint(sqrt((double)((lat1-lat2)*(lat1-lat2)+(lon1-lon2)*(lon1-lon2))));
147 calculate_ddistance(gint lat1, gint lon1, gint lat2, gint lon2)
149 return sqrt((double)((lat1-lat2)*(lat1-lat2)+(lon1-lon2)*(lon1-lon2)));
153 * Quick distance for comparing, skips the final square root
156 calculate_idistance_cmp(gint lat1, gint lon1, gint lat2, gint lon2)
158 return ((lat1-lat2)*(lat1-lat2)+(lon1-lon2)*(lon1-lon2));
162 * Calculate the distance between two lat/lon pairs.
163 * The distance is returned in kilometers.
167 calculate_distance(gdouble lat1, gdouble lon1, gdouble lat2, gdouble lon2)
169 gdouble dlat, dlon, slat, slon, a;
171 /* Convert to radians. */
172 lat1*=(M_PIl / 180.f);
173 lon1*=(M_PIl / 180.f);
174 lat2*=(M_PIl / 180.f);
175 lon2*=(M_PIl / 180.f);
180 slat=sin(dlat / 2.f);
181 slon=sin(dlon / 2.f);
183 a=(slat * slat) + (cos(lat1) * cos(lat2) * slon * slon);
185 return ((2.f * atan2(sqrt(a), sqrt(1.f - a))) * EARTH_RADIUS);
189 * Calculate course from lat1,lon1 to lat2,lon2
193 calculate_course(gdouble lat1, gdouble lon1, gdouble lat2, gdouble lon2)
197 lat1*=(M_PIl / 180.f);
198 lon1*=(M_PIl / 180.f);
199 lat2*=(M_PIl / 180.f);
200 lon2*=(M_PIl / 180.f);
203 y=sin(dlon)*cos(lat2);
204 x=cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(dlon);
207 /* Fixup for compass */