Contents of /trunk/src/pos.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 221 - (hide annotations)
Mon Jul 13 14:29:58 2009 UTC (14 years, 10 months ago) by harbaum
File MIME type: text/plain
File size: 6747 byte(s)
Start new project without default data
1 harbaum 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 harbaum 9 void pos_lat_str(char *str, int len, pos_float_t latitude) {
27 harbaum 221 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 harbaum 1 }
40     strcat(str, "°");
41     }
42    
43 harbaum 9 void pos_lon_str(char *str, int len, pos_float_t longitude) {
44 harbaum 221 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 harbaum 1 }
57     strcat(str, "°");
58     }
59    
60 harbaum 9 pos_float_t pos_parse_lat(char *str) {
61 harbaum 1 return g_strtod(str, NULL);
62     }
63    
64 harbaum 9 pos_float_t pos_parse_lon(char *str) {
65 harbaum 1 return g_strtod(str, NULL);
66     }
67    
68 harbaum 9 gboolean pos_lat_valid(pos_float_t lat) {
69 harbaum 1 return(!isnan(lat) && (lat >= -90.0) && (lat <= 90.0));
70     }
71    
72 harbaum 9 gboolean pos_lon_valid(pos_float_t lon) {
73 harbaum 1 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 harbaum 9 pos_float_t i = pos_parse_lat((char*)gtk_entry_get_text(GTK_ENTRY(widget)));
83 harbaum 1 mark(widget, pos_lat_valid(i));
84     }
85    
86     /* a entry that is colored red when being "active" */
87 harbaum 9 GtkWidget *pos_lat_entry_new(pos_float_t lat) {
88 harbaum 1 GdkColor color;
89     GtkWidget *widget = gtk_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 harbaum 9 pos_float_t i = pos_parse_lon((char*)gtk_entry_get_text(GTK_ENTRY(widget)));
105 harbaum 1 mark(widget, pos_lon_valid(i));
106     }
107    
108     /* a entry that is colored red when filled with invalid coordinate */
109 harbaum 9 GtkWidget *pos_lon_entry_new(pos_float_t lon) {
110 harbaum 1 GdkColor color;
111     GtkWidget *widget = gtk_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 harbaum 9 pos_float_t pos_lat_get(GtkWidget *widget) {
126 harbaum 1 char *p = (char*)gtk_entry_get_text(GTK_ENTRY(widget));
127     return pos_parse_lat(p);
128     }
129    
130 harbaum 9 pos_float_t pos_lon_get(GtkWidget *widget) {
131 harbaum 1 char *p = (char*)gtk_entry_get_text(GTK_ENTRY(widget));
132     return pos_parse_lon(p);
133     }
134    
135 harbaum 9 void pos_lat_entry_set(GtkWidget *entry, pos_float_t lat) {
136 harbaum 1 char str[32];
137     pos_lat_str(str, sizeof(str), lat);
138     gtk_entry_set_text(GTK_ENTRY(entry), str);
139     }
140    
141 harbaum 9 void pos_lon_entry_set(GtkWidget *entry, pos_float_t lon) {
142 harbaum 1 char str[32];
143     pos_lon_str(str, sizeof(str), lon);
144     gtk_entry_set_text(GTK_ENTRY(entry), str);
145     }
146    
147 harbaum 9 GtkWidget *pos_lat_label_new(pos_float_t lat) {
148 harbaum 1 char str[32];
149     pos_lat_str(str, sizeof(str), lat);
150     return gtk_label_new(str);
151     }
152    
153 harbaum 9 GtkWidget *pos_lon_label_new(pos_float_t lon) {
154 harbaum 1 char str[32];
155     pos_lon_str(str, sizeof(str), lon);
156     return gtk_label_new(str);
157     }
158    
159 harbaum 9 void pos_lat_label_set(GtkWidget *label, pos_float_t lat) {
160 harbaum 1 char str[32];
161     pos_lat_str(str, sizeof(str), lat);
162     gtk_label_set_text(GTK_LABEL(label), str);
163     }
164    
165 harbaum 9 void pos_lon_label_set(GtkWidget *label, pos_float_t lon) {
166 harbaum 1 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 harbaum 40 #ifdef USE_FLOAT
174     lpos->y = POS_EQ_RADIUS * logf(tanf(M_PI/4 + DEG2RAD(pos->lat)/2));
175     #else
176 harbaum 1 lpos->y = POS_EQ_RADIUS * log(tan(M_PI/4 + DEG2RAD(pos->lat)/2));
177 harbaum 40 #endif
178 harbaum 1 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 harbaum 40 #ifdef USE_FLOAT
186     lpos->y = POS_EQ_RADIUS * logf(tanf(M_PI/4 + DEG2RAD(pos->lat)/2));
187     #else
188 harbaum 1 lpos->y = POS_EQ_RADIUS * log(tan(M_PI/4 + DEG2RAD(pos->lat)/2));
189 harbaum 40 #endif
190 harbaum 1 }
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 harbaum 40 #ifdef USE_FLOAT
200     pos->lat = RAD2DEG(2 * atanf(expf(tmp.y/POS_EQ_RADIUS)) - M_PI/2);
201     #else
202 harbaum 1 pos->lat = RAD2DEG(2 * atan(exp(tmp.y/POS_EQ_RADIUS)) - M_PI/2);
203 harbaum 40 #endif
204 harbaum 1 }
205    
206 harbaum 9 void pos_dist_str(char *str, int len, pos_float_t dist, gboolean is_mil) {
207 harbaum 221 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 harbaum 1
213 harbaum 221 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 harbaum 1 }
222     }
223    
224 harbaum 9 void pos_dist_entry_set(GtkWidget *entry, pos_float_t dist, gboolean is_mil) {
225 harbaum 1 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 harbaum 9 pos_float_t pos_parse_dist(char *str, gboolean is_mil) {
231 harbaum 1 return g_strtod(str, NULL) * (is_mil?KMPMIL:1.0);
232     }
233    
234 harbaum 9 pos_float_t pos_dist_get(GtkWidget *widget, gboolean is_mil) {
235 harbaum 1 char *p = (char*)gtk_entry_get_text(GTK_ENTRY(widget));
236     return pos_parse_dist(p, is_mil);
237     }