]> git.street.me.uk Git - andy/viking.git/blame - src/vikcoord.c
Make each tool contain it's own icon definition.
[andy/viking.git] / src / vikcoord.c
CommitLineData
50a14534
EB
1/*
2 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
3 *
4 * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
50a14534
EB
22#include "coords.h"
23#include "vikcoord.h"
24
25/* all coord operations MUST BE ABSTRACTED!!! */
26
27void vik_coord_convert(VikCoord *coord, VikCoordMode dest_mode)
28{
06fe50c3 29 VikCoord tmp;
50a14534
EB
30 if ( coord->mode != dest_mode )
31 {
32 if ( dest_mode == VIK_COORD_LATLON ) {
33 a_coords_utm_to_latlon ( (struct UTM *)coord, (struct LatLon *)&tmp );
34 *((struct LatLon *)coord) = *((struct LatLon *)&tmp);
35 } else {
36 a_coords_latlon_to_utm ( (struct LatLon *)coord, (struct UTM *)&tmp );
37 *((struct UTM *)coord) = *((struct UTM *)&tmp);
38 }
39 coord->mode = dest_mode;
40 }
41}
42
43void vik_coord_copy_convert(const VikCoord *coord, VikCoordMode dest_mode, VikCoord *dest)
44{
45 if ( coord->mode == dest_mode ) {
46 *dest = *coord;
47 } else {
48 if ( dest_mode == VIK_COORD_LATLON )
49 a_coords_utm_to_latlon ( (struct UTM *)coord, (struct LatLon *)dest );
50 else
51 a_coords_latlon_to_utm ( (struct LatLon *)coord, (struct UTM *)dest );
52 dest->mode = dest_mode;
53 }
54}
55
56static gdouble vik_coord_diff_safe(const VikCoord *c1, const VikCoord *c2)
57{
06fe50c3 58 struct LatLon a, b;
50a14534
EB
59 vik_coord_to_latlon ( c1, &a );
60 vik_coord_to_latlon ( c2, &b );
61 return a_coords_latlon_diff ( &a, &b );
62}
63
64gdouble vik_coord_diff(const VikCoord *c1, const VikCoord *c2)
65{
66 if ( c1->mode == c2->mode )
67 return vik_coord_diff_safe ( c1, c2 );
68 if ( c1->mode == VIK_COORD_UTM )
69 return a_coords_utm_diff ( (const struct UTM *) c1, (const struct UTM *) c2 );
70 else
71 return a_coords_latlon_diff ( (const struct LatLon *) c1, (const struct LatLon *) c2 );
72}
73
74void vik_coord_load_from_latlon ( VikCoord *coord, VikCoordMode mode, const struct LatLon *ll )
75{
76 if ( mode == VIK_COORD_LATLON )
77 *((struct LatLon *)coord) = *ll;
78 else
79 a_coords_latlon_to_utm ( ll, (struct UTM *) coord );
80 coord->mode = mode;
81}
82
83void vik_coord_load_from_utm ( VikCoord *coord, VikCoordMode mode, const struct UTM *utm )
84{
85 if ( mode == VIK_COORD_UTM )
86 *((struct UTM *)coord) = *utm;
87 else
88 a_coords_utm_to_latlon ( utm, (struct LatLon *) coord );
89 coord->mode = mode;
90}
91
92void vik_coord_to_latlon ( const VikCoord *coord, struct LatLon *dest )
93{
94 if ( coord->mode == VIK_COORD_LATLON )
95 *dest = *((const struct LatLon *)coord);
96 else
97 a_coords_utm_to_latlon ( (const struct UTM *) coord, dest );
98}
99
100void vik_coord_to_utm ( const VikCoord *coord, struct UTM *dest )
101{
102 if ( coord->mode == VIK_COORD_UTM )
103 *dest = *((const struct UTM *)coord);
104 else
105 a_coords_latlon_to_utm ( (const struct LatLon *) coord, dest );
106}
107
108gboolean vik_coord_equals ( const VikCoord *coord1, const VikCoord *coord2 )
109{
110 if ( coord1->mode != coord2->mode )
111 return FALSE;
112 if ( coord1->mode == VIK_COORD_LATLON )
113 return coord1->north_south == coord2->north_south && coord1->east_west == coord2->east_west;
114 else /* VIK_COORD_UTM */
115 return coord1->utm_zone == coord2->utm_zone && coord1->north_south == coord2->north_south && coord1->east_west == coord2->east_west;
116}
7114e879
QT
117
118static void get_north_west(struct LatLon *center, struct LatLon *dist, struct LatLon *nw)
119{
120 nw->lat = center->lat + dist->lat;
121 nw->lon = center->lon - dist->lon;
122 if (nw->lon < -180)
123 nw->lon += 360.0;
124 if (nw->lat > 90.0) { /* over north pole */
125 nw->lat = 180 - nw->lat;
126 nw->lon = nw->lon - 180;
127 }
128}
129
130static void get_south_east(struct LatLon *center, struct LatLon *dist, struct LatLon *se)
131{
132 se->lat = center->lat - dist->lat;
133 se->lon = center->lon + dist->lon;
134 if (se->lon > 180.0)
135 se->lon -= 360.0;
136 if (se->lat < -90.0) { /* over south pole */
137 se->lat += 180;
138 se->lon = se->lon - 180;
139 }
140}
141
142void vik_coord_set_area(const VikCoord *coord, const struct LatLon *wh, VikCoord *tl, VikCoord *br)
143{
144 struct LatLon center, nw, se;
145 struct LatLon dist;
146
147 dist.lat = wh->lat/2;
148 dist.lon = wh->lon/2;
149
150 vik_coord_to_latlon(coord, &center);
151 get_north_west(&center, &dist, &nw);
152 get_south_east(&center, &dist, &se);
153
7114e879
QT
154 *((struct LatLon *)tl) = nw;
155 *((struct LatLon *)br) = se;
35e22ed8 156 tl->mode = br->mode = VIK_COORD_LATLON;
7114e879
QT
157}
158
159gboolean vik_coord_inside(const VikCoord *coord, const VikCoord *tl, const VikCoord *br)
160{
161 struct LatLon ll, tl_ll, br_ll;
162
163 vik_coord_to_latlon(coord, &ll);
164 vik_coord_to_latlon(tl, &tl_ll);
165 vik_coord_to_latlon(br, &br_ll);
166
7114e879
QT
167 if ((ll.lat > tl_ll.lat) || (ll.lon < tl_ll.lon))
168 return FALSE;
169 if ((ll.lat < br_ll.lat) || (ll.lon > br_ll.lon))
170 return FALSE;
171 return TRUE;
172}