Fix:map_csv:Disable default notification of each deleted item.
[profile/ivi/navit.git] / navit / 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 struct default_flags {
37         enum item_type type;
38         int flags;
39 };
40
41 struct item busy_item;
42
43 struct default_flags default_flags2[]={
44         {type_street_nopass, AF_PBH},
45         {type_street_0, AF_ALL},
46         {type_street_1_city, AF_ALL},
47         {type_street_2_city, AF_ALL},
48         {type_street_3_city, AF_ALL},
49         {type_street_4_city, AF_ALL},
50         {type_highway_city, AF_MOTORIZED_FAST}, 
51         {type_street_1_land, AF_ALL},
52         {type_street_2_land, AF_ALL},
53         {type_street_3_land, AF_ALL},
54         {type_street_4_land, AF_ALL},
55         {type_street_n_lanes, AF_MOTORIZED_FAST},
56         {type_highway_land, AF_MOTORIZED_FAST},
57         {type_ramp, AF_MOTORIZED_FAST},
58         {type_roundabout, AF_ALL},
59         {type_ferry, AF_ALL},
60         {type_cycleway, AF_PBH},
61         {type_track_paved, AF_ALL},
62         {type_track_gravelled, AF_ALL},
63         {type_track_unpaved, AF_ALL},
64         {type_track_ground, AF_ALL},
65         {type_track_grass, AF_ALL},
66         {type_footway, AF_PBH},
67         {type_living_street, AF_ALL},
68         {type_street_service, AF_ALL},
69         {type_street_parking_lane, AF_ALL},
70         {type_bridleway, AF_PBH},
71         {type_path, AF_PBH},
72         {type_steps, AF_PBH},
73         {type_street_pedestrian, 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 static GHashTable *item_hash;
89
90 void
91 item_create_hash(void)
92 {
93         int i;
94         item_hash=g_hash_table_new(g_str_hash, g_str_equal);
95         for (i=0 ; i < sizeof(item_names)/sizeof(struct item_name) ; i++) {
96                 g_hash_table_insert(item_hash, item_names[i].name, GINT_TO_POINTER(item_names[i].item));
97         }
98 }
99
100 void
101 item_destroy_hash(void)
102 {
103         g_hash_table_destroy(item_hash);
104         item_hash=NULL;
105 }
106
107 int *
108 item_get_default_flags(enum item_type type)
109 {
110         if (!default_flags_hash) {
111                 int i;
112                 default_flags_hash=g_hash_table_new(NULL, NULL);
113                 for (i = 0 ; i < sizeof(default_flags2)/sizeof(struct default_flags); i++) {
114                         g_hash_table_insert(default_flags_hash, (void *)(long)default_flags2[i].type, &default_flags2[i].flags);
115                 }
116         }
117         return g_hash_table_lookup(default_flags_hash, (void *)(long)type);
118 }
119
120 void
121 item_cleanup(void)
122 {
123         if (default_flags_hash)
124                 g_hash_table_destroy(default_flags_hash);
125 }
126
127 void
128 item_coord_rewind(struct item *it)
129 {
130         it->meth->item_coord_rewind(it->priv_data);
131 }
132
133 int
134 item_coord_get(struct item *it, struct coord *c, int count)
135 {
136         return it->meth->item_coord_get(it->priv_data, c, count);
137 }
138
139 int
140 item_coord_set(struct item *it, struct coord *c, int count, enum change_mode mode)
141 {
142         if (!it->meth->item_coord_set)
143                 return 0;
144         return it->meth->item_coord_set(it->priv_data, c, count, mode);
145 }
146
147 int
148 item_coord_get_within_selection(struct item *it, struct coord *c, int count, struct map_selection *sel)
149 {
150         int i,ret=it->meth->item_coord_get(it->priv_data, c, count);
151         struct coord_rect r;
152         struct map_selection *curr;
153         if (ret <= 0 || !sel)
154                 return ret;
155         r.lu=c[0];
156         r.rl=c[0];
157         for (i = 1 ; i < ret ; i++) {
158                 if (r.lu.x > c[i].x)
159                         r.lu.x=c[i].x;
160                 if (r.rl.x < c[i].x)
161                         r.rl.x=c[i].x;
162                 if (r.rl.y > c[i].y)
163                         r.rl.y=c[i].y;
164                 if (r.lu.y < c[i].y)
165                         r.lu.y=c[i].y;
166         }
167         curr=sel;
168         while (curr) {
169                 struct coord_rect *sr=&curr->u.c_rect;
170                 if (r.lu.x <= sr->rl.x && r.rl.x >= sr->lu.x &&
171                     r.lu.y >= sr->rl.y && r.rl.y <= sr->lu.y)
172                         return ret;
173                 curr=curr->next;
174         }
175         return 0;
176 }
177
178 int
179 item_coord_get_pro(struct item *it, struct coord *c, int count, enum projection to)
180 {
181         int ret=item_coord_get(it, c, count);
182         int i;
183         enum projection from=map_projection(it->map);
184         if (from != to) 
185                 for (i = 0 ; i < count ; i++) 
186                         transform_from_to(c+i, from, c+i, to);
187         return ret;
188 }
189
190 int 
191 item_coord_is_node(struct item *it)
192 {
193         if (it->meth->item_coord_is_node)
194                 return it->meth->item_coord_is_node(it->priv_data);
195         return 0;
196 }
197
198 void
199 item_attr_rewind(struct item *it)
200 {
201         it->meth->item_attr_rewind(it->priv_data);
202 }
203
204 int
205 item_attr_get(struct item *it, enum attr_type attr_type, struct attr *attr)
206 {
207         return it->meth->item_attr_get(it->priv_data, attr_type, attr);
208 }
209
210 int
211 item_attr_set(struct item *it, struct attr *attr, enum change_mode mode)
212 {
213         if (!it->meth->item_attr_set)
214                 return 0;
215         return it->meth->item_attr_set(it->priv_data, attr, mode);
216 }
217 /**
218  * @brief Set map item type. 
219  *
220  * @param it reference to the item.
221  * @param type New type for the item. Setting it to type_none is expected to delete item from the map.
222  * @return  Non-zero if this action is supported by the map and type is set successfully, 0 on error.
223  */
224 int
225 item_type_set(struct item *it, enum item_type type)
226 {
227         if (!it->meth->item_type_set)
228                 return 0;
229         return it->meth->item_type_set(it->priv_data, type);
230 }
231
232 struct item * item_new(char *type, int zoom)
233 {
234         struct item * it;
235
236         it = g_new0(struct item, 1);
237
238         /* FIXME evaluate arguments */
239
240         return it;
241 }
242
243 enum item_type
244 item_from_name(const char *name)
245 {
246         int i;
247
248         if (item_hash)
249                 return GPOINTER_TO_INT(g_hash_table_lookup(item_hash, name));
250
251         for (i=0 ; i < sizeof(item_names)/sizeof(struct item_name) ; i++) {
252                 if (! strcmp(item_names[i].name, name))
253                         return item_names[i].item;
254         }
255         return type_none;
256 }
257
258 char *
259 item_to_name(enum item_type item)
260 {
261         int i;
262
263         for (i=0 ; i < sizeof(item_names)/sizeof(struct item_name) ; i++) {
264                 if (item_names[i].item == item)
265                         return item_names[i].name;
266         }
267         return NULL; 
268 }
269
270 struct item_hash {
271         GHashTable *h;
272 };
273
274 static guint
275 item_hash_hash(gconstpointer key)
276 {
277         const struct item *itm=key;
278         gconstpointer hashkey=(gconstpointer)GINT_TO_POINTER(itm->id_hi^itm->id_lo^(GPOINTER_TO_INT(itm->map)));
279         return g_direct_hash(hashkey);
280 }
281
282 static gboolean
283 item_hash_equal(gconstpointer a, gconstpointer b)
284 {
285         const struct item *itm_a=a;
286         const struct item *itm_b=b;
287         if (item_is_equal(*itm_a, *itm_b))
288                 return TRUE;
289         return FALSE;
290 }
291
292 unsigned int
293 item_id_hash(const void *key)
294 {
295         const struct item_id *id=key;
296         return id->id_hi^id->id_lo;
297 }
298
299 int
300 item_id_equal(const void *a, const void *b)
301 {
302         const struct item_id *id_a=a;
303         const struct item_id *id_b=b;
304         return (id_a->id_hi == id_b->id_hi && id_a->id_lo == id_b->id_lo);
305 }
306
307
308
309 struct item_hash *
310 item_hash_new(void)
311 {
312         struct item_hash *ret=g_new(struct item_hash, 1);
313
314         ret->h=g_hash_table_new_full(item_hash_hash, item_hash_equal, g_free, NULL);
315         return ret;
316 }
317
318 void
319 item_hash_insert(struct item_hash *h, struct item *item, void *val)
320 {
321         struct item *hitem=g_new(struct item, 1);
322         *hitem=*item;
323         dbg(2,"inserting (0x%x,0x%x) into %p\n", item->id_hi, item->id_lo, h->h);
324         g_hash_table_insert(h->h, hitem, val);
325 }
326
327 int
328 item_hash_remove(struct item_hash *h, struct item *item)
329 {
330         int ret;
331
332         dbg(2,"removing (0x%x,0x%x) from %p\n", item->id_hi, item->id_lo, h->h);
333         ret=g_hash_table_remove(h->h, item);
334         dbg(2,"ret=%d\n", ret);
335
336         return ret;
337 }
338
339 void *
340 item_hash_lookup(struct item_hash *h, struct item *item)
341 {
342         return g_hash_table_lookup(h->h, item);
343 }
344
345
346 void
347 item_hash_destroy(struct item_hash *h)
348 {
349         g_hash_table_destroy(h->h);
350         g_free(h);
351 }
352
353 int
354 item_range_intersects_range(struct item_range *range1, struct item_range *range2)
355 {
356         if (range1->max < range2->min)
357                 return 0;
358         if (range1->min > range2->max)
359                 return 0;
360         return 1;
361 }
362 int
363 item_range_contains_item(struct item_range *range, enum item_type type)
364 {
365         if (type >= range->min && type <= range->max)
366                 return 1;
367         return 0;
368 }
369
370 void
371 item_dump_attr(struct item *item, struct map *map, FILE *out)
372 {
373         struct attr attr;
374         fprintf(out,"type=%s", item_to_name(item->type));
375         while (item_attr_get(item, attr_any, &attr)) 
376                 fprintf(out," %s='%s'", attr_to_name(attr.type), attr_to_text(&attr, map, 1));
377 }
378
379 void
380 item_dump_filedesc(struct item *item, struct map *map, FILE *out)
381 {
382
383         int i,count,max=16384;
384         struct coord *ca=g_alloca(sizeof(struct coord)*max);
385
386         count=item_coord_get(item, ca, item->type < type_line ? 1: max);
387         if (item->type < type_line) 
388                 fprintf(out,"mg:0x%x 0x%x ", ca[0].x, ca[0].y);
389         item_dump_attr(item, map, out);
390         fprintf(out,"\n");
391         if (item->type >= type_line)
392                 for (i = 0 ; i < count ; i++)
393                         fprintf(out,"mg:0x%x 0x%x\n", ca[i].x, ca[i].y);
394 }