Parent Directory | Revision Log
Various fremantleization
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, pos_float_t latitude) { |
27 | if(isnan(latitude)) |
28 | strcpy(str, "---"); |
29 | else { |
30 | snprintf(str, len-1, "%.5f", latitude); |
31 | |
32 | /* eliminate trailing zeros */ |
33 | if((strchr(str, '.') != NULL) || (strchr(str, ',') != NULL)) { |
34 | char *p = str+strlen(str)-1; |
35 | while(*p == '0') *p-- = 0; |
36 | if((*p == '.')||(*p == ',')) |
37 | *p = 0; |
38 | } |
39 | } |
40 | strcat(str, "°"); |
41 | } |
42 | |
43 | void pos_lon_str(char *str, int len, pos_float_t longitude) { |
44 | if(isnan(longitude)) |
45 | strcpy(str, "---"); |
46 | else { |
47 | snprintf(str, len-1, "%.5f", longitude); |
48 | |
49 | /* eliminate trailing zeros */ |
50 | if((strchr(str, '.') != NULL) || (strchr(str, ',') != NULL)) { |
51 | char *p = str+strlen(str)-1; |
52 | while(*p == '0') *p-- = 0; |
53 | if((*p == '.')||(*p == ',')) |
54 | *p = 0; |
55 | } |
56 | } |
57 | strcat(str, "°"); |
58 | } |
59 | |
60 | pos_float_t pos_parse_lat(char *str) { |
61 | return g_strtod(str, NULL); |
62 | } |
63 | |
64 | pos_float_t pos_parse_lon(char *str) { |
65 | return g_strtod(str, NULL); |
66 | } |
67 | |
68 | gboolean pos_lat_valid(pos_float_t lat) { |
69 | return(!isnan(lat) && (lat >= -90.0) && (lat <= 90.0)); |
70 | } |
71 | |
72 | gboolean pos_lon_valid(pos_float_t lon) { |
73 | return(!isnan(lon) && (lon >= -180.0) && (lon <= 180.0)); |
74 | } |
75 | |
76 | static gboolean mark(GtkWidget *widget, gboolean valid) { |
77 | gtk_widget_set_state(widget, valid?GTK_STATE_NORMAL:TAG_STATE); |
78 | return valid; |
79 | } |
80 | |
81 | static void callback_modified_lat(GtkWidget *widget, gpointer data ) { |
82 | pos_float_t i = pos_parse_lat((char*)gtk_entry_get_text(GTK_ENTRY(widget))); |
83 | mark(widget, pos_lat_valid(i)); |
84 | } |
85 | |
86 | /* a entry that is colored red when being "active" */ |
87 | GtkWidget *pos_lat_entry_new(pos_float_t lat) { |
88 | GdkColor color; |
89 | GtkWidget *widget = entry_new(); |
90 | gdk_color_parse("red", &color); |
91 | gtk_widget_modify_text(widget, TAG_STATE, &color); |
92 | |
93 | char str[32]; |
94 | pos_lat_str(str, sizeof(str), lat); |
95 | gtk_entry_set_text(GTK_ENTRY(widget), str); |
96 | |
97 | g_signal_connect(G_OBJECT(widget), "changed", |
98 | G_CALLBACK(callback_modified_lat), NULL); |
99 | |
100 | return widget; |
101 | } |
102 | |
103 | static void callback_modified_lon(GtkWidget *widget, gpointer data ) { |
104 | pos_float_t i = pos_parse_lon((char*)gtk_entry_get_text(GTK_ENTRY(widget))); |
105 | mark(widget, pos_lon_valid(i)); |
106 | } |
107 | |
108 | /* a entry that is colored red when filled with invalid coordinate */ |
109 | GtkWidget *pos_lon_entry_new(pos_float_t lon) { |
110 | GdkColor color; |
111 | GtkWidget *widget = entry_new(); |
112 | gdk_color_parse("#ff0000", &color); |
113 | gtk_widget_modify_text(widget, TAG_STATE, &color); |
114 | |
115 | char str[32]; |
116 | pos_lon_str(str, sizeof(str), lon); |
117 | gtk_entry_set_text(GTK_ENTRY(widget), str); |
118 | |
119 | g_signal_connect(G_OBJECT(widget), "changed", |
120 | G_CALLBACK(callback_modified_lon), NULL); |
121 | |
122 | return widget; |
123 | } |
124 | |
125 | pos_float_t pos_lat_get(GtkWidget *widget) { |
126 | char *p = (char*)gtk_entry_get_text(GTK_ENTRY(widget)); |
127 | return pos_parse_lat(p); |
128 | } |
129 | |
130 | pos_float_t pos_lon_get(GtkWidget *widget) { |
131 | char *p = (char*)gtk_entry_get_text(GTK_ENTRY(widget)); |
132 | return pos_parse_lon(p); |
133 | } |
134 | |
135 | void pos_lat_entry_set(GtkWidget *entry, pos_float_t lat) { |
136 | char str[32]; |
137 | pos_lat_str(str, sizeof(str), lat); |
138 | gtk_entry_set_text(GTK_ENTRY(entry), str); |
139 | } |
140 | |
141 | void pos_lon_entry_set(GtkWidget *entry, pos_float_t lon) { |
142 | char str[32]; |
143 | pos_lon_str(str, sizeof(str), lon); |
144 | gtk_entry_set_text(GTK_ENTRY(entry), str); |
145 | } |
146 | |
147 | GtkWidget *pos_lat_label_new(pos_float_t lat) { |
148 | char str[32]; |
149 | pos_lat_str(str, sizeof(str), lat); |
150 | return gtk_label_new(str); |
151 | } |
152 | |
153 | GtkWidget *pos_lon_label_new(pos_float_t lon) { |
154 | char str[32]; |
155 | pos_lon_str(str, sizeof(str), lon); |
156 | return gtk_label_new(str); |
157 | } |
158 | |
159 | void pos_lat_label_set(GtkWidget *label, pos_float_t lat) { |
160 | char str[32]; |
161 | pos_lat_str(str, sizeof(str), lat); |
162 | gtk_label_set_text(GTK_LABEL(label), str); |
163 | } |
164 | |
165 | void pos_lon_label_set(GtkWidget *label, pos_float_t lon) { |
166 | char str[32]; |
167 | pos_lon_str(str, sizeof(str), lon); |
168 | gtk_label_set_text(GTK_LABEL(label), str); |
169 | } |
170 | |
171 | void pos2lpos(bounds_t *bounds, pos_t *pos, lpos_t *lpos) { |
172 | lpos->x = POS_EQ_RADIUS * DEG2RAD(pos->lon); |
173 | #ifdef USE_FLOAT |
174 | lpos->y = POS_EQ_RADIUS * logf(tanf(M_PI/4 + DEG2RAD(pos->lat)/2)); |
175 | #else |
176 | lpos->y = POS_EQ_RADIUS * log(tan(M_PI/4 + DEG2RAD(pos->lat)/2)); |
177 | #endif |
178 | lpos->x = ( lpos->x - bounds->center.x) * bounds->scale; |
179 | lpos->y = (-lpos->y + bounds->center.y) * bounds->scale; |
180 | } |
181 | |
182 | /* the maps center is special as it isn't offset (by itself) */ |
183 | void pos2lpos_center(pos_t *pos, lpos_t *lpos) { |
184 | lpos->x = POS_EQ_RADIUS * DEG2RAD(pos->lon); |
185 | #ifdef USE_FLOAT |
186 | lpos->y = POS_EQ_RADIUS * logf(tanf(M_PI/4 + DEG2RAD(pos->lat)/2)); |
187 | #else |
188 | lpos->y = POS_EQ_RADIUS * log(tan(M_PI/4 + DEG2RAD(pos->lat)/2)); |
189 | #endif |
190 | } |
191 | |
192 | void lpos2pos(bounds_t *bounds, lpos_t *lpos, pos_t *pos) { |
193 | lpos_t tmp = *lpos; |
194 | |
195 | tmp.x = ( tmp.x/bounds->scale) + bounds->center.x; |
196 | tmp.y = (-tmp.y/bounds->scale) + bounds->center.y; |
197 | |
198 | pos->lon = RAD2DEG(tmp.x / POS_EQ_RADIUS); |
199 | #ifdef USE_FLOAT |
200 | pos->lat = RAD2DEG(2 * atanf(expf(tmp.y/POS_EQ_RADIUS)) - M_PI/2); |
201 | #else |
202 | pos->lat = RAD2DEG(2 * atan(exp(tmp.y/POS_EQ_RADIUS)) - M_PI/2); |
203 | #endif |
204 | } |
205 | |
206 | void pos_dist_str(char *str, int len, pos_float_t dist, gboolean is_mil) { |
207 | if(isnan(dist)) |
208 | strcpy(str, "---"); |
209 | else { |
210 | /* is this to be displayed as miles? */ |
211 | if(is_mil) dist /= KMPMIL; // kilometer per mile |
212 | |
213 | snprintf(str, len, "%.4f", dist); |
214 | /* eliminate trailing zeros */ |
215 | if((strchr(str, '.') != NULL) || (strchr(str, ',') != NULL)) { |
216 | char *p = str+strlen(str)-1; |
217 | while(*p == '0') *p-- = 0; |
218 | if((*p == '.')||(*p == ',')) |
219 | *p = 0; |
220 | } |
221 | } |
222 | } |
223 | |
224 | void pos_dist_entry_set(GtkWidget *entry, pos_float_t dist, gboolean is_mil) { |
225 | char str[32]; |
226 | pos_dist_str(str, sizeof(str), dist, is_mil); |
227 | gtk_entry_set_text(GTK_ENTRY(entry), str); |
228 | } |
229 | |
230 | pos_float_t pos_parse_dist(char *str, gboolean is_mil) { |
231 | return g_strtod(str, NULL) * (is_mil?KMPMIL:1.0); |
232 | } |
233 | |
234 | pos_float_t pos_dist_get(GtkWidget *widget, gboolean is_mil) { |
235 | char *p = (char*)gtk_entry_get_text(GTK_ENTRY(widget)); |
236 | return pos_parse_dist(p, is_mil); |
237 | } |