Recreate the navit git/gerrit project that vanished
[profile/ivi/navit.git] / navit / map / mg / poly.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 <string.h>
21 #include "debug.h"
22 #include "mg.h"
23
24 static void
25 poly_coord_rewind(void *priv_data)
26 {
27         struct poly_priv *poly=priv_data;
28
29         poly->p=poly->subpoly_start;    
30
31 }
32
33 static int
34 poly_coord_get(void *priv_data, struct coord *c, int count)
35 {
36         struct poly_priv *poly=priv_data;
37         int ret=0;
38
39         while (count--) {
40                 if (poly->p >= poly->subpoly_next)
41                         break;
42                 c->x=get_u32_unal(&poly->p);
43                 c->y=get_u32_unal(&poly->p);
44                 c++;
45                 ret++;
46         }
47         return ret;
48 }
49
50 static void 
51 poly_attr_rewind(void *priv_data)
52 {
53         struct poly_priv *poly=priv_data;
54
55         poly->aidx=0;
56 }
57
58 static int
59 poly_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
60 {
61         struct poly_priv *poly=priv_data;
62
63         attr->type=attr_type;
64         switch (attr_type) {
65         case attr_any:
66                 while (poly->attr_next != attr_none) {
67                         if (poly_attr_get(poly, poly->attr_next, attr))
68                                 return 1;
69                 }
70                 return 0;
71         case attr_label:
72                 attr->u.str=poly->name;
73                 poly->attr_next=attr_none;
74                 if (attr->u.str[0])
75                         return 1;
76                 return 0;
77         default:
78                 return 0;
79         }
80         return 1;
81 }
82
83 static struct item_methods poly_meth = {
84         poly_coord_rewind,
85         poly_coord_get,
86         poly_attr_rewind,
87         poly_attr_get,
88 };
89
90 static void
91 poly_get_data(struct poly_priv *poly, unsigned char **p)
92 {
93         poly->c[0].x=get_u32_unal(p);
94         poly->c[0].y=get_u32_unal(p);
95         poly->c[1].x=get_u32_unal(p);
96         poly->c[1].y=get_u32_unal(p);
97         *p+=sizeof(struct coord);
98         poly->name=(char *)(*p);
99         while (**p) {
100                 (*p)++;
101         }
102         (*p)++;
103         poly->order=*(*p)++;
104         poly->type=*(*p)++;
105         poly->polys=get_u32_unal(p);
106         poly->count=(unsigned int *)(*p); (*p)+=poly->polys*sizeof(unsigned int);
107         poly->count_sum=get_u32_unal(p);
108 }
109
110 int
111 poly_get(struct map_rect_priv *mr, struct poly_priv *poly, struct item *item)
112 {
113         struct coord_rect r;
114
115         for (;;) {
116                 if (mr->b.p >= mr->b.end)
117                         return 0;
118                 if (mr->b.p == mr->b.p_start) {
119                         poly->poly_num=0;
120                         poly->subpoly_num=0;
121                         poly->subpoly_num_all=0;
122                         poly->poly_next=mr->b.p;
123                         item->meth=&poly_meth;
124                 }
125                 if (poly->poly_num >= block_get_count(mr->b.b))
126                         return 0;
127                 if (!poly->subpoly_num) {
128                         mr->b.p=poly->poly_next;
129                         item->id_lo=mr->b.p-mr->file->begin;
130                         poly_get_data(poly, &mr->b.p);
131                         poly->poly_next=mr->b.p+poly->count_sum*sizeof(struct coord);
132                         poly->poly_num++;
133                         r.lu=poly->c[0];
134                         r.rl=poly->c[1];
135                         if (mr->cur_sel && (poly->order > mr->cur_sel->order*3 || !coord_rect_overlap(&mr->cur_sel->u.c_rect, &r))) {
136                                 poly->subpoly_num_all+=poly->polys;
137                                 mr->b.p=poly->poly_next;
138                                 continue;
139                         }
140                         switch(poly->type) {
141                         case 0x13:
142                                 item->type=type_poly_wood;
143                                 break;
144                         case 0x14:
145                                 item->type=type_poly_town;
146                                 break;
147                         case 0x15:
148                                 item->type=type_poly_cemetery;
149                                 break;
150                         case 0x16:
151                                 item->type=type_poly_building;
152                                 break;
153                         case 0x17:
154                                 item->type=type_poly_museum;
155                                 break;
156                         case 0x19:
157                                 item->type=type_poly_place;
158                                 break;
159                         case 0x1b:
160                                 item->type=type_poly_commercial_center;
161                                 break;
162                         case 0x1e:
163                                 item->type=type_poly_industry;
164                                 break;
165                         case 0x23:
166                                 /* FIXME: what is this ?*/
167                                 item->type=type_poly_place;
168                                 break;
169                         case 0x24:
170                                 item->type=type_poly_car_parking;
171                                 break;
172                         case 0x28:
173                                 item->type=type_poly_airport;
174                                 break;
175                         case 0x29:
176                                 item->type=type_poly_station;
177                                 break;
178                         case 0x2d:
179                                 item->type=type_poly_hospital;
180                                 break;
181                         case 0x2e:
182                                 item->type=type_poly_hospital;
183                                 break;
184                         case 0x2f:
185                                 item->type=type_poly_university;
186                                 break;
187                         case 0x30:
188                                 item->type=type_poly_university;
189                                 break;
190                         case 0x32:
191                                 item->type=type_poly_park;
192                                 break;
193                         case 0x34:
194                                 item->type=type_poly_sport;
195                                 break;
196                         case 0x35:
197                                 item->type=type_poly_sport;
198                                 break;
199                         case 0x37:
200                                 item->type=type_poly_golf_course;
201                                 break;
202                         case 0x38:
203                                 item->type=type_poly_national_park;
204                                 break;
205                         case 0x39:
206                                 item->type=type_poly_nature_park;
207                                 break;
208                         case 0x3c:
209                                 item->type=type_poly_water;
210                                 break;
211                         case 0xbc:
212                                 item->type=type_water_line;
213                                 break;
214                         case 0xc3:
215                                 /* FIXME: what is this ?*/
216                                 item->type=type_border_state;
217                                 break;
218                         case 0xc6:
219                                 item->type=type_border_country;
220                                 break;
221                         case 0xc7:
222                                 item->type=type_border_state;
223                                 break;
224                         case 0xd0:
225                                 item->type=type_rail;
226                                 break;
227                         default:
228                                 dbg(0,"Unknown poly type 0x%x '%s' 0x%x,0x%x\n", poly->type,poly->name,r.lu.x,r.lu.y);
229                                 item->type=type_street_unkn;
230                         }
231                         if (!map_selection_contains_item(mr->cur_sel, 0, item->type)) {
232                                 poly->subpoly_num_all+=poly->polys;
233                                 mr->b.p=poly->poly_next;
234                                 continue;
235                         }
236                 } else 
237                         mr->b.p=poly->subpoly_next;
238                 dbg(1,"%d %d %s\n", poly->subpoly_num_all, mr->b.block_num, poly->name);
239                 item->id_lo=poly->subpoly_num_all | (mr->b.block_num << 16);
240                 item->id_hi=(mr->current_file << 16);
241                 dbg(1,"0x%x 0x%x\n", item->id_lo, item->id_hi);
242                 poly->subpoly_next=mr->b.p+L(poly->count[poly->subpoly_num])*sizeof(struct coord);
243                 poly->subpoly_num++;
244                 poly->subpoly_num_all++;
245                 if (poly->subpoly_num >= poly->polys) 
246                         poly->subpoly_num=0;
247                 poly->subpoly_start=poly->p=mr->b.p;
248                 item->priv_data=poly;
249                 poly->attr_next=attr_label;
250                 return 1;
251         }
252 }
253
254 int
255 poly_get_byid(struct map_rect_priv *mr, struct poly_priv *poly, int id_hi, int id_lo, struct item *item)
256 {
257         int count=id_lo & 0xffff;
258         int ret=0;
259         block_get_byindex(mr->m->file[mr->current_file], id_lo >> 16, &mr->b);
260         while (count-- >= 0) {
261                 ret=poly_get(mr, poly, item);
262         }
263         return ret;
264 }
265