Contents of /src/pos.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Tue Dec 9 20:06:06 2008 UTC (15 years, 5 months ago) by harbaum
File MIME type: text/plain
File size: 6130 byte(s)
Initial import
1 /*
2 * Copyright (C) 2008 Till Harbaum <till@harbaum.org>.
3 *
4 * This file is part of OSM2Go.
5 *
6 * OSM2Go 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 3 of the License, or
9 * (at your option) any later version.
10 *
11 * OSM2Go 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 OSM2Go. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <ctype.h>
21
22 #include "appdata.h"
23
24 #define TAG_STATE GTK_STATE_PRELIGHT
25
26 void pos_lat_str(char *str, int len, double latitude) {
27 snprintf(str, len-1, "%.5f", latitude);
28 /* eliminate trailing zeros */
29 if((strchr(str, '.') != NULL) || (strchr(str, ',') != NULL)) {
30 char *p = str+strlen(str)-1;
31 while(*p == '0') *p-- = 0;
32 if((*p == '.')||(*p == ','))
33 *p = 0;
34 }
35 strcat(str, "°");
36 }
37
38 void pos_lon_str(char *str, int len, double longitude) {
39 snprintf(str, len-1, "%.5f", longitude);
40 /* eliminate trailing zeros */
41 if((strchr(str, '.') != NULL) || (strchr(str, ',') != NULL)) {
42 char *p = str+strlen(str)-1;
43 while(*p == '0') *p-- = 0;
44 if((*p == '.')||(*p == ','))
45 *p = 0;
46 }
47 strcat(str, "°");
48 }
49
50 double pos_parse_lat(char *str) {
51 return g_strtod(str, NULL);
52 }
53
54 double pos_parse_lon(char *str) {
55 return g_strtod(str, NULL);
56 }
57
58 gboolean pos_lat_valid(double lat) {
59 return(!isnan(lat) && (lat >= -90.0) && (lat <= 90.0));
60 }
61
62 gboolean pos_lon_valid(double lon) {
63 return(!isnan(lon) && (lon >= -180.0) && (lon <= 180.0));
64 }
65
66 static gboolean mark(GtkWidget *widget, gboolean valid) {
67 gtk_widget_set_state(widget, valid?GTK_STATE_NORMAL:TAG_STATE);
68 return valid;
69 }
70
71 static void callback_modified_lat(GtkWidget *widget, gpointer data ) {
72 double i = pos_parse_lat((char*)gtk_entry_get_text(GTK_ENTRY(widget)));
73 mark(widget, pos_lat_valid(i));
74 }
75
76 /* a entry that is colored red when being "active" */
77 GtkWidget *pos_lat_entry_new(double lat) {
78 GdkColor color;
79 GtkWidget *widget = gtk_entry_new();
80 gdk_color_parse("red", &color);
81 gtk_widget_modify_text(widget, TAG_STATE, &color);
82
83 char str[32];
84 pos_lat_str(str, sizeof(str), lat);
85 gtk_entry_set_text(GTK_ENTRY(widget), str);
86
87 g_signal_connect(G_OBJECT(widget), "changed",
88 G_CALLBACK(callback_modified_lat), NULL);
89
90 return widget;
91 }
92
93 static void callback_modified_lon(GtkWidget *widget, gpointer data ) {
94 double i = pos_parse_lon((char*)gtk_entry_get_text(GTK_ENTRY(widget)));
95 mark(widget, pos_lon_valid(i));
96 }
97
98 /* a entry that is colored red when filled with invalid coordinate */
99 GtkWidget *pos_lon_entry_new(double lon) {
100 GdkColor color;
101 GtkWidget *widget = gtk_entry_new();
102 gdk_color_parse("#ff0000", &color);
103 gtk_widget_modify_text(widget, TAG_STATE, &color);
104
105 char str[32];
106 pos_lon_str(str, sizeof(str), lon);
107 gtk_entry_set_text(GTK_ENTRY(widget), str);
108
109 g_signal_connect(G_OBJECT(widget), "changed",
110 G_CALLBACK(callback_modified_lon), NULL);
111
112 return widget;
113 }
114
115 double pos_lat_get(GtkWidget *widget) {
116 char *p = (char*)gtk_entry_get_text(GTK_ENTRY(widget));
117 return pos_parse_lat(p);
118 }
119
120 double pos_lon_get(GtkWidget *widget) {
121 char *p = (char*)gtk_entry_get_text(GTK_ENTRY(widget));
122 return pos_parse_lon(p);
123 }
124
125 void pos_lat_entry_set(GtkWidget *entry, double lat) {
126 char str[32];
127 pos_lat_str(str, sizeof(str), lat);
128 gtk_entry_set_text(GTK_ENTRY(entry), str);
129 }
130
131 void pos_lon_entry_set(GtkWidget *entry, double lon) {
132 char str[32];
133 pos_lon_str(str, sizeof(str), lon);
134 gtk_entry_set_text(GTK_ENTRY(entry), str);
135 }
136
137 GtkWidget *pos_lat_label_new(double lat) {
138 char str[32];
139 pos_lat_str(str, sizeof(str), lat);
140 return gtk_label_new(str);
141 }
142
143 GtkWidget *pos_lon_label_new(double lon) {
144 char str[32];
145 pos_lon_str(str, sizeof(str), lon);
146 return gtk_label_new(str);
147 }
148
149 void pos_lat_label_set(GtkWidget *label, double lat) {
150 char str[32];
151 pos_lat_str(str, sizeof(str), lat);
152 gtk_label_set_text(GTK_LABEL(label), str);
153 }
154
155 void pos_lon_label_set(GtkWidget *label, double lon) {
156 char str[32];
157 pos_lon_str(str, sizeof(str), lon);
158 gtk_label_set_text(GTK_LABEL(label), str);
159 }
160
161 void pos2lpos(bounds_t *bounds, pos_t *pos, lpos_t *lpos) {
162 lpos->x = POS_EQ_RADIUS * DEG2RAD(pos->lon);
163 lpos->y = POS_EQ_RADIUS * log(tan(M_PI/4 + DEG2RAD(pos->lat)/2));
164
165 lpos->x = ( lpos->x - bounds->center.x) * bounds->scale;
166 lpos->y = (-lpos->y + bounds->center.y) * bounds->scale;
167 }
168
169 /* the maps center is special as it isn't offset (by itself) */
170 void pos2lpos_center(pos_t *pos, lpos_t *lpos) {
171 lpos->x = POS_EQ_RADIUS * DEG2RAD(pos->lon);
172 lpos->y = POS_EQ_RADIUS * log(tan(M_PI/4 + DEG2RAD(pos->lat)/2));
173 }
174
175 void lpos2pos(bounds_t *bounds, lpos_t *lpos, pos_t *pos) {
176 lpos_t tmp = *lpos;
177
178 tmp.x = ( tmp.x/bounds->scale) + bounds->center.x;
179 tmp.y = (-tmp.y/bounds->scale) + bounds->center.y;
180
181 pos->lon = RAD2DEG(tmp.x / POS_EQ_RADIUS);
182 pos->lat = RAD2DEG(2 * atan(exp(tmp.y/POS_EQ_RADIUS)) - M_PI/2);
183 }
184
185 void pos_dist_str(char *str, int len, double dist, gboolean is_mil) {
186 /* is this to be displayed as miles? */
187 if(is_mil) dist /= KMPMIL; // kilometer per mile
188
189 snprintf(str, len, "%.4f", dist);
190 /* eliminate trailing zeros */
191 if((strchr(str, '.') != NULL) || (strchr(str, ',') != NULL)) {
192 char *p = str+strlen(str)-1;
193 while(*p == '0') *p-- = 0;
194 if((*p == '.')||(*p == ','))
195 *p = 0;
196 }
197 }
198
199 void pos_dist_entry_set(GtkWidget *entry, double dist, gboolean is_mil) {
200 char str[32];
201 pos_dist_str(str, sizeof(str), dist, is_mil);
202 gtk_entry_set_text(GTK_ENTRY(entry), str);
203 }
204
205 double pos_parse_dist(char *str, gboolean is_mil) {
206 return g_strtod(str, NULL) * (is_mil?KMPMIL:1.0);
207 }
208
209 double pos_dist_get(GtkWidget *widget, gboolean is_mil) {
210 char *p = (char*)gtk_entry_get_text(GTK_ENTRY(widget));
211 return pos_parse_dist(p, is_mil);
212 }