Contents of /trunk/src/pos.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Tue Dec 9 20:06:06 2008 UTC (15 years, 5 months ago) by harbaum
Original Path: src/pos.c
File MIME type: text/plain
File size: 6130 byte(s)
Initial import
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     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     }