Fix:maptool:Another name for faroe islands
[navit-package] / navit / item.c
1 /**
2  * Navit, a modular navigation system.
3  * Copyright (C) 2005-2008 Navit Team
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <glib.h>
23 #include "coord.h"
24 #include "debug.h"
25 #include "item.h"
26 #include "map.h"
27 #include "transform.h"
28
29 struct item_name {
30         enum item_type item;
31         char *name;
32 };
33
34 struct item_range item_range_all = { type_none, type_last };
35
36 #define AF_PBH (AF_PEDESTRIAN|AF_BIKE|AF_HORSE)
37 #define AF_MOTORIZED_FAST (AF_MOTORCYCLE|AF_CAR|AF_HIGH_OCCUPANCY_CAR|AF_TAXI|AF_PUBLIC_BUS|AF_DELIVERY_TRUCK|AF_TRANSPORT_TRUCK|AF_EMERGENCY_VEHICLES|AF_DANGEROUS_GOODS)
38 #define AF_ALL (AF_PBH|AF_MOPED|AF_MOTORIZED_FAST)
39
40
41 struct default_flags {
42         enum item_type type;
43         int flags;
44 };
45
46 struct default_flags default_flags2[]={
47         {type_street_nopass, AF_PBH},
48         {type_street_0, AF_ALL},
49         {type_street_1_city, AF_ALL},
50         {type_street_2_city, AF_ALL},
51         {type_street_3_city, AF_ALL},
52         {type_street_4_city, AF_ALL},
53         {type_highway_city, AF_MOTORIZED_FAST}, 
54         {type_street_1_land, AF_ALL},
55         {type_street_2_land, AF_ALL},
56         {type_street_3_land, AF_ALL},
57         {type_street_4_land, AF_ALL},
58         {type_street_n_lanes, AF_MOTORIZED_FAST},
59         {type_highway_land, AF_MOTORIZED_FAST},
60         {type_ramp, AF_MOTORIZED_FAST},
61         {type_roundabout, AF_ALL},
62         {type_ferry, AF_ALL},
63         {type_cycleway, AF_PBH},
64         {type_track_paved, AF_ALL},
65         {type_track_gravelled, AF_ALL},
66         {type_track_unpaved, AF_ALL},
67         {type_track_ground, AF_ALL},
68         {type_track_grass, AF_ALL},
69         {type_footway, AF_PBH},
70         {type_living_street, AF_ALL},
71         {type_street_service, AF_ALL},
72         {type_bridleway, AF_PBH},
73         {type_path, AF_PBH},
74 };
75
76
77
78 struct item_name item_names[]={
79 #define ITEM2(x,y) ITEM(y)
80 #define ITEM(x) { type_##x, #x },
81 #include "item_def.h"
82 #undef ITEM2
83 #undef ITEM
84 };
85
86 static GHashTable *default_flags_hash;
87
88 int *
89 item_get_default_flags(enum item_type type)
90 {
91         if (!default_flags_hash) {
92                 int i;
93                 default_flags_hash=g_hash_table_new(NULL, NULL);
94                 for (i = 0 ; i < sizeof(default_flags2)/sizeof(struct default_flags); i++) {
95                         g_hash_table_insert(default_flags_hash, (void *)(long)default_flags2[i].type, &default_flags2[i].flags);
96                 }
97         }
98         return g_hash_table_lookup(default_flags_hash, (void *)(long)type);
99 }
100
101 void
102 item_coord_rewind(struct item *it)
103 {
104         it->meth->item_coord_rewind(it->priv_data);
105 }
106
107 int
108 item_coord_get(struct item *it, struct coord *c, int count)
109 {
110         return it->meth->item_coord_get(it->priv_data, c, count);
111 }
112
113 int
114 item_coord_set(struct item *it, struct coord *c, int count, enum change_mode mode)
115 {
116         if (!it->meth->item_coord_set)
117                 return 0;
118         return it->meth->item_coord_set(it->priv_data, c, count, mode);
119 }
120
121 int
122 item_coord_get_within_selection(struct item *it, struct coord *c, int count, struct map_selection *sel)
123 {
124         int i,ret=it->meth->item_coord_get(it->priv_data, c, count);
125         struct coord_rect r;
126         struct map_selection *curr;
127         if (ret <= 0 || !sel)
128                 return ret;
129         r.lu=c[0];
130         r.rl=c[0];
131         for (i = 1 ; i < ret ; i++) {
132                 if (r.lu.x > c[i].x)
133                         r.lu.x=c[i].x;
134                 if (r.rl.x < c[i].x)
135                         r.rl.x=c[i].x;
136                 if (r.rl.y > c[i].y)
137                         r.rl.y=c[i].y;
138                 if (r.lu.y < c[i].y)
139                         r.lu.y=c[i].y;
140         }
141         curr=sel;
142         while (curr) {
143                 struct coord_rect *sr=&curr->u.c_rect;
144                 if (r.lu.x <= sr->rl.x && r.rl.x >= sr->lu.x &&
145                     r.lu.y >= sr->rl.y && r.rl.y <= sr->lu.y)
146                         return ret;
147                 curr=curr->next;
148         }
149         return 0;
150 }
151
152 int
153 item_coord_get_pro(struct item *it, struct coord *c, int count, enum projection to)
154 {
155         int ret=item_coord_get(it, c, count);
156         int i;
157         enum projection from=map_projection(it->map);
158         if (from != to) 
159                 for (i = 0 ; i < count ; i++) 
160                         transform_from_to(c+i, from, c+i, to);
161         return ret;
162 }
163
164 int 
165 item_coord_is_node(struct item *it)
166 {
167         if (it->meth->item_coord_is_node)
168                 return it->meth->item_coord_is_node(it->priv_data);
169         return 0;
170 }
171
172 void
173 item_attr_rewind(struct item *it)
174 {
175         it->meth->item_attr_rewind(it->priv_data);
176 }
177
178 int
179 item_attr_get(struct item *it, enum attr_type attr_type, struct attr *attr)
180 {
181         return it->meth->item_attr_get(it->priv_data, attr_type, attr);
182 }
183
184 int
185 item_attr_set(struct item *it, struct attr *attr, enum change_mode mode)
186 {
187         if (!it->meth->item_attr_set)
188                 return 0;
189         return it->meth->item_attr_set(it->priv_data, attr, mode);
190 }
191
192 struct item * item_new(char *type, int zoom)
193 {
194         struct item * it;
195
196         it = g_new0(struct item, 1);
197
198         /* FIXME evaluate arguments */
199
200         return it;
201 }
202
203 enum item_type
204 item_from_name(const char *name)
205 {
206         int i;
207
208         for (i=0 ; i < sizeof(item_names)/sizeof(struct item_name) ; i++) {
209                 if (! strcmp(item_names[i].name, name))
210                         return item_names[i].item;
211         }
212         return type_none;
213 }
214
215 char *
216 item_to_name(enum item_type item)
217 {
218         int i;
219
220         for (i=0 ; i < sizeof(item_names)/sizeof(struct item_name) ; i++) {
221                 if (item_names[i].item == item)
222                         return item_names[i].name;
223         }
224         return NULL; 
225 }
226
227 struct item_hash {
228         GHashTable *h;
229 };
230
231 static guint
232 item_hash_hash(gconstpointer key)
233 {
234         const struct item *itm=key;
235         gconstpointer hashkey=(gconstpointer)GINT_TO_POINTER(itm->id_hi^itm->id_lo^(GPOINTER_TO_INT(itm->map)));
236         return g_direct_hash(hashkey);
237 }
238
239 static gboolean
240 item_hash_equal(gconstpointer a, gconstpointer b)
241 {
242         const struct item *itm_a=a;
243         const struct item *itm_b=b;
244         if (item_is_equal(*itm_a, *itm_b))
245                 return TRUE;
246         return FALSE;
247 }
248
249 unsigned int
250 item_id_hash(const void *key)
251 {
252         const struct item_id *id=key;
253         return id->id_hi^id->id_lo;
254 }
255
256 int
257 item_id_equal(const void *a, const void *b)
258 {
259         const struct item_id *id_a=a;
260         const struct item_id *id_b=b;
261         return (id_a->id_hi == id_b->id_hi && id_a->id_lo == id_b->id_lo);
262 }
263
264
265
266 struct item_hash *
267 item_hash_new(void)
268 {
269         struct item_hash *ret=g_new(struct item_hash, 1);
270
271         ret->h=g_hash_table_new_full(item_hash_hash, item_hash_equal, g_free, NULL);
272         return ret;
273 }
274
275 void
276 item_hash_insert(struct item_hash *h, struct item *item, void *val)
277 {
278         struct item *hitem=g_new(struct item, 1);
279         *hitem=*item;
280         dbg(2,"inserting (0x%x,0x%x) into %p\n", item->id_hi, item->id_lo, h->h);
281         g_hash_table_insert(h->h, hitem, val);
282 }
283
284 int
285 item_hash_remove(struct item_hash *h, struct item *item)
286 {
287         int ret;
288
289         dbg(2,"removing (0x%x,0x%x) from %p\n", item->id_hi, item->id_lo, h->h);
290         ret=g_hash_table_remove(h->h, item);
291         dbg(2,"ret=%d\n", ret);
292
293         return ret;
294 }
295
296 void *
297 item_hash_lookup(struct item_hash *h, struct item *item)
298 {
299         return g_hash_table_lookup(h->h, item);
300 }
301
302
303 void
304 item_hash_destroy(struct item_hash *h)
305 {
306         g_hash_table_destroy(h->h);
307         g_free(h);
308 }
309
310 int
311 item_range_intersects_range(struct item_range *range1, struct item_range *range2)
312 {
313         if (range1->max < range2->min)
314                 return 0;
315         if (range1->min > range2->max)
316                 return 0;
317         return 1;
318 }
319 int
320 item_range_contains_item(struct item_range *range, enum item_type type)
321 {
322         if (type >= range->min && type <= range->max)
323                 return 1;
324         return 0;
325 }
326
327 void
328 item_dump_attr(struct item *item, struct map *map, FILE *out)
329 {
330         struct attr attr;
331         fprintf(out,"type=%s", item_to_name(item->type));
332         while (item_attr_get(item, attr_any, &attr)) 
333                 fprintf(out," %s='%s'", attr_to_name(attr.type), attr_to_text(&attr, map, 1));
334 }
335
336 void
337 item_dump_filedesc(struct item *item, struct map *map, FILE *out)
338 {
339
340         int i,count,max=16384;
341         struct coord ca[max];
342
343         count=item_coord_get(item, ca, item->type < type_line ? 1: max);
344         if (item->type < type_line) 
345                 fprintf(out,"mg:0x%x 0x%x ", ca[0].x, ca[0].y);
346         item_dump_attr(item, map, out);
347         fprintf(out,"\n");
348         if (item->type >= type_line)
349                 for (i = 0 ; i < count ; i++)
350                         fprintf(out,"mg:0x%x 0x%x\n", ca[i].x, ca[i].y);
351 }