Merge with modular_map
[navit-package] / src / coord.c
1 #include <glib.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <math.h>
6 #include "debug.h"
7 #include "coord.h"
8 #include "transform.h"
9 #include "projection.h"
10 /**
11  * @defgroup coord Coordinate handling functions
12  * @{
13  */
14
15 /**
16  * Get a coordinate
17  *
18  * @param p Pointer to the coordinate
19  * @returns the coordinate
20  */
21
22 struct coord *
23 coord_get(unsigned char **p)
24 {
25         struct coord *ret=(struct coord *)(*p);
26         *p += sizeof(*ret);
27         return ret;
28 }
29
30 struct coord *
31 coord_new(int x, int y)
32 {
33         struct coord *c=g_new(struct coord, 1);
34
35         c->x=x;
36         c->y=y;
37
38         return c;
39 }
40
41 void
42 coord_destroy(struct coord *c)
43 {
44         g_free(c);
45 }
46
47 struct coord_rect *
48 coord_rect_new(struct coord *lu, struct coord *rl)
49 {
50         struct coord_rect *r=g_new(struct coord_rect, 1);
51
52         g_assert(lu->x <= rl->x);
53         g_assert(lu->y >= rl->y);
54
55         r->lu=*lu;
56         r->rl=*rl;
57
58         return r;
59         
60 }
61
62 void
63 coord_rect_destroy(struct coord_rect *r)
64 {
65         g_free(r);
66 }
67
68 int 
69 coord_rect_overlap(struct coord_rect *r1, struct coord_rect *r2)
70 {
71         g_assert(r1->lu.x <= r1->rl.x);
72         g_assert(r1->lu.y >= r1->rl.y);
73         g_assert(r2->lu.x <= r2->rl.x);
74         g_assert(r2->lu.y >= r2->rl.y);
75         if (r1->lu.x > r2->rl.x)
76                 return 0;
77         if (r1->rl.x < r2->lu.x)
78                 return 0;
79         if (r1->lu.y < r2->rl.y)
80                 return 0;
81         if (r1->rl.y > r2->lu.y)
82                 return 0;
83         return 1;
84 }
85
86 int
87 coord_rect_contains(struct coord_rect *r, struct coord *c)
88 {
89         g_assert(r->lu.x <= r->rl.x);
90         g_assert(r->lu.y >= r->rl.y);
91         if (c->x < r->lu.x)
92                 return 0;
93         if (c->x > r->rl.x)
94                 return 0;
95         if (c->y < r->rl.y)
96                 return 0;
97         if (c->y > r->lu.y)
98                 return 0;
99         return 1;
100 }
101
102 void
103 coord_rect_extend(struct coord_rect *r, struct coord *c)
104 {
105         if (c->x < r->lu.x)
106                 r->lu.x=c->x;
107         if (c->x > r->rl.x)
108                 r->rl.x=c->x;
109         if (c->y < r->rl.y)
110                 r->rl.y=c->y;
111         if (c->y > r->lu.y)
112                 r->lu.y=c->y;
113 }
114
115         /* [Proj:][Ð]DMM.ss[S][S]... N/S [D][D]DMM.ss[S][S]... E/W */
116         /* [Proj:][-][D]D.d[d]... [-][D][D]D.d[d]... */
117         /* [Proj:][-]0xX [-]0xX */
118
119 int
120 coord_parse(const char *c_str, enum projection pro, struct coord *c_ret)
121 {
122         int debug=0;
123         char *proj=NULL,*s,*co;
124         const char *str=c_str;
125         int args,ret;
126         struct coord_geo g;
127         struct coord c;
128         enum projection str_pro=projection_none;
129
130         dbg(1,"enter('%s',%d,%p)\n", c_str, pro, c_ret);
131         s=index(str,' ');
132         co=index(str,':');
133         if (co && co < s) {
134                 proj=malloc(co-str+1);
135                 strncpy(proj, str, co-str);
136                 proj[co-str]='\0';
137                 dbg(1,"projection=%s\n", proj);
138                 str=co+1;
139                 s=index(str,' ');
140         }
141         while (*s == ' ') {
142                 s++;
143         }
144         if (!strncmp(str, "0x", 2) || !strncmp(str,"-0x", 3)) {
145                 args=sscanf(str, "%i %i%n",&c.x, &c.y, &ret);
146                 if (args < 2)
147                         return 0;
148                 dbg(1,"str='%s' x=0x%x y=0x%x c=%d\n", str, c.x, c.y, ret);
149                 dbg(1,"rest='%s'\n", str+ret);
150
151                 if (str_pro == projection_none) 
152                         str_pro=projection_mg;
153                 if (str_pro == projection_mg) {
154                         *c_ret=c;
155                 } else {
156                         printf("help\n");
157                 }
158         } else if (*s == 'N' || *s == 'n' || *s == 'S' || *s == 's') {
159                 dbg(1,"str='%s'\n", str);
160                 double lng, lat;
161                 char ns, ew;
162                 args=sscanf(str, "%lf %c %lf %c%n", &lat, &ns, &lng, &ew, &ret);
163                 if (args < 4)
164                         return 0;
165                 if (str_pro == projection_none) {
166                         g.lat=floor(lat/100);
167                         lat-=g.lat*100;
168                         g.lat+=lat/60;
169                         g.lng=floor(lng/100);
170                         lng-=g.lng*100;
171                         g.lng+=lng/60;
172                         transform_from_geo(pro, &g, c_ret);
173                 }
174                 if (debug) {
175                         printf("str='%s' x=%f ns=%c y=%f ew=%c c=%d\n", str, lng, ns, lat, ew, ret);
176                         printf("rest='%s'\n", str+ret);
177                 }
178         } else {
179                 double lng, lat;
180                 args=sscanf(str, "%lf %lf%n", &lng, &lat, &ret);
181                 if (args < 2)
182                         return 0;
183                 printf("str='%s' x=%f y=%f  c=%d\n", str, lng, lat, ret);
184                 printf("rest='%s'\n", str+ret);
185         }
186         if (debug)
187                 printf("rest='%s'\n", str+ret);
188         ret+=str-c_str;
189         if (debug) {
190                 printf("args=%d\n", args);
191                 printf("ret=%d delta=%d ret_str='%s'\n", ret, str-c_str, c_str+ret);
192         }
193         if (proj)
194                 free(proj);
195         return ret;
196 }
197
198 /** @} */