9 #include "projection.h"
15 #include "transform.h"
18 #include "endianess.h"
44 struct zip_cd *index_cd;
50 struct map_rect_priv {
53 enum attr_type attr_last;
56 struct map_selection *sel;
65 struct map_search_priv {
66 struct map_rect_priv *mr;
68 struct map_selection *ms;
70 GHashTable *search_results;
74 static void minmax_to_cpu(struct minmax * mima) {
75 g_assert(mima != NULL);
76 mima->min = le16_to_cpu(mima->min);
77 mima->max = le16_to_cpu(mima->max);
80 static void lfh_to_cpu(struct zip_lfh *lfh) {
81 g_assert(lfh != NULL);
82 lfh->ziplocsig = le32_to_cpu(lfh->ziplocsig);
83 lfh->zipver = le16_to_cpu(lfh->zipver);
84 lfh->zipgenfld = le16_to_cpu(lfh->zipgenfld);
85 lfh->zipmthd = le16_to_cpu(lfh->zipmthd);
86 lfh->ziptime = le16_to_cpu(lfh->ziptime);
87 lfh->zipdate = le16_to_cpu(lfh->zipdate);
88 lfh->zipcrc = le32_to_cpu(lfh->zipcrc);
89 lfh->zipsize = le32_to_cpu(lfh->zipsize);
90 lfh->zipuncmp = le32_to_cpu(lfh->zipuncmp);
91 lfh->zipfnln = le16_to_cpu(lfh->zipfnln);
92 lfh->zipxtraln = le16_to_cpu(lfh->zipxtraln);
95 static void cd_to_cpu(struct zip_cd *zcd) {
96 g_assert(zcd != NULL);
97 zcd->zipccrc = le32_to_cpu(zcd->zipccrc);
98 zcd->zipcsiz = le32_to_cpu(zcd->zipcsiz);
99 zcd->zipcunc = le32_to_cpu(zcd->zipcunc);
100 zcd->zipcfnl = le16_to_cpu(zcd->zipcfnl);
101 zcd->zipcxtl = le16_to_cpu(zcd->zipcxtl);
102 zcd->zipccml = le16_to_cpu(zcd->zipccml);
103 zcd->zipdsk = le16_to_cpu(zcd->zipdsk);
104 zcd->zipint = le16_to_cpu(zcd->zipint);
105 zcd->zipext = le32_to_cpu(zcd->zipext);
106 zcd->zipofst = le32_to_cpu(zcd->zipofst);
109 static void eoc_to_cpu(struct zip_eoc *eoc) {
110 g_assert(eoc != NULL);
111 eoc->zipesig = le32_to_cpu(eoc->zipesig);
112 eoc->zipedsk = le16_to_cpu(eoc->zipedsk);
113 eoc->zipecen = le16_to_cpu(eoc->zipecen);
114 eoc->zipenum = le16_to_cpu(eoc->zipenum);
115 eoc->zipecenn = le16_to_cpu(eoc->zipecenn);
116 eoc->zipecsz = le32_to_cpu(eoc->zipecsz);
117 eoc->zipeofst = le32_to_cpu(eoc->zipeofst);
118 eoc->zipecoml = le16_to_cpu(eoc->zipecoml);
122 map_destroy_binfile(struct map_priv *m)
124 dbg(1,"map_destroy_binfile\n");
129 binfile_coord_rewind(void *priv_data)
131 struct map_rect_priv *mr=priv_data;
132 struct tile *t=mr->t;
133 t->pos_coord=t->pos_coord_start;
137 binfile_coord_get(void *priv_data, struct coord *c, int count)
139 struct map_rect_priv *mr=priv_data;
140 struct tile *t=mr->t;
142 dbg(2,"binfile_coord_get %d\n",count);
144 dbg(2,"%p vs %p\n", t->pos_coord, t->pos_attr_start);
145 if (t->pos_coord >= t->pos_attr_start)
147 c->x=le32_to_cpu(*(t->pos_coord++));
148 c->y=le32_to_cpu(*(t->pos_coord++));
156 binfile_attr_rewind(void *priv_data)
158 struct map_rect_priv *mr=priv_data;
159 struct tile *t=mr->t;
160 t->pos_attr=t->pos_attr_start;
165 binfile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
167 struct map_rect_priv *mr=priv_data;
168 struct tile *t=mr->t;
172 if (attr_type != mr->attr_last) {
173 t->pos_attr=t->pos_attr_start;
174 mr->attr_last=attr_type;
176 while (t->pos_attr < t->pos_next) {
177 size=le32_to_cpu(*(t->pos_attr++));
178 type=le32_to_cpu(t->pos_attr[0]);
179 if (type == attr_label)
181 if (type == attr_town_name)
182 mr->label_attr[0]=t->pos_attr;
183 if (type == attr_street_name)
184 mr->label_attr[0]=t->pos_attr;
185 if (type == attr_street_name_systematic)
186 mr->label_attr[1]=t->pos_attr;
187 if (type == attr_type || attr_type == attr_any) {
188 if (attr_type == attr_any) {
189 dbg(1,"pos %p attr %s size %d\n", t->pos_attr-1, attr_to_name(type), size);
192 attr_data_set(attr, t->pos_attr+1);
199 if (!mr->label && (attr_type == attr_any || attr_type == attr_label)) {
200 for (i = 0 ; i < sizeof(mr->label_attr)/sizeof(int *) ; i++) {
201 if (mr->label_attr[i]) {
203 attr->type=attr_label;
204 attr_data_set(attr, mr->label_attr[i]+1);
212 static struct item_methods methods_binfile = {
213 binfile_coord_rewind,
220 push_tile(struct map_rect_priv *mr, struct tile *t)
222 g_assert(mr->tile_depth < 8);
223 mr->t=&mr->tiles[mr->tile_depth++];
225 mr->t->pos=mr->t->pos_next=mr->t->start;
229 pop_tile(struct map_rect_priv *mr)
231 if (mr->tile_depth <= 1)
233 file_data_free(mr->m->fi, (unsigned char *)(mr->t->start));
234 mr->t=&mr->tiles[--mr->tile_depth-1];
240 zipfile_to_tile(struct file *f, struct zip_cd *cd, struct tile *t)
245 dbg(1,"enter %p %p %p\n", f, cd, t);
246 dbg(1,"cd->zipofst=0x%x\n", cd->zipofst);
248 lfh=(struct zip_lfh *)(file_data_read(f,cd->zipofst,sizeof(struct zip_lfh)));
250 zipfn=(char *)(file_data_read(f,cd->zipofst+sizeof(struct zip_lfh), lfh->zipfnln));
251 strncpy(buffer, zipfn, lfh->zipfnln);
252 buffer[lfh->zipfnln]='\0';
253 dbg(1,"0x%x '%s' %d %d,%d\n", lfh->ziplocsig, buffer, sizeof(*cd)+cd->zipcfnl, lfh->zipsize, lfh->zipuncmp);
254 switch (lfh->zipmthd) {
256 t->start=(int *)(file_data_read(f,cd->zipofst+sizeof(struct zip_lfh)+lfh->zipfnln, lfh->zipuncmp));
257 t->end=t->start+lfh->zipuncmp/4;
260 t->start=(int *)(file_data_read_compressed(f,cd->zipofst+sizeof(struct zip_lfh)+lfh->zipfnln, lfh->zipsize, lfh->zipuncmp));
261 t->end=t->start+lfh->zipuncmp/4;
264 dbg(0,"Unknown compression method %d\n", lfh->zipmthd);
266 file_data_free(f, (unsigned char *)zipfn);
267 file_data_free(f, (unsigned char *)lfh);
268 return t->start != NULL;
272 push_zipfile_tile(struct map_rect_priv *mr, int zipfile)
274 struct map_priv *m=mr->m;
275 struct file *f=m->fi;
277 struct zip_cd *cd=(struct zip_cd *)(file_data_read(f, m->eoc->zipeofst + zipfile*m->cde_size, sizeof(struct zip_cd)));
279 dbg(1,"enter %p %d\n", mr, zipfile);
280 t.zipfile_num=zipfile;
281 if (zipfile_to_tile(f, cd, &t))
283 file_data_free(f, (unsigned char *)cd);
286 static struct map_rect_priv *
287 map_rect_new_binfile(struct map_priv *map, struct map_selection *sel)
289 struct map_rect_priv *mr;
292 dbg(1,"map_rect_new_binfile\n");
293 mr=g_new0(struct map_rect_priv, 1);
298 dbg(1,"zip_members=%d\n", map->zip_members);
300 push_zipfile_tile(mr, map->zip_members-1);
302 unsigned char *d=file_data_read(map->fi, 0, map->fi->size);
304 t.end=(int *)(d+map->fi->size);
308 mr->item.meth=&methods_binfile;
309 mr->item.priv_data=mr;
315 map_rect_destroy_binfile(struct map_rect_priv *mr)
317 while (pop_tile(mr));
318 file_data_free(mr->m->fi, (unsigned char *)(mr->tiles[0].start));
323 setup_pos(struct map_rect_priv *mr)
326 struct tile *t=mr->t;
327 size=le32_to_cpu(*(t->pos++));
328 if (size > 1024*1024 || size < 0) {
329 fprintf(stderr,"size=0x%x\n", size);
331 fprintf(stderr,"offset=%d\n", (unsigned char *)(mr->pos)-mr->m->f->begin);
333 g_error("size error");
335 t->pos_next=t->pos+size;
336 mr->item.type=le32_to_cpu(*(t->pos++));
337 coord_size=le32_to_cpu(*(t->pos++));
338 t->pos_coord_start=t->pos_coord=t->pos;
339 t->pos_attr_start=t->pos_attr=t->pos_coord+coord_size;
343 selection_contains(struct map_selection *sel, struct coord_rect *r, struct minmax *mima)
349 if (coord_rect_overlap(r, &sel->u.c_rect)) {
351 if (sel->order[1] > order)
353 if (sel->order[2] > order)
355 dbg(1,"min %d max %d order %d\n", mima->min, mima->max, order);
356 if (!mima->min && !mima->max)
358 if (order >= mima->min && order <= mima->max)
367 map_parse_country_binfile(struct map_rect_priv *mr)
370 if (binfile_attr_get(mr->item.priv_data, attr_country_id, &at)) {
371 if (at.u.num == mr->country_id)
373 if (binfile_attr_get(mr->item.priv_data, attr_zipfile_ref, &at))
375 push_zipfile_tile(mr, at.u.num);
382 map_rect_get_item_binfile(struct map_rect_priv *mr)
391 if (t->pos >= t->end) {
396 mr->item.id_hi=t->zipfile_num;
397 mr->item.id_lo=t->pos-t->start;
399 memset(mr->label_attr, 0, sizeof(mr->label_attr));
401 if ((mr->item.type == type_submap) && (!mr->country_id)) {
403 r.lu.x=le32_to_cpu(t->pos_coord[0]);
404 r.lu.y=le32_to_cpu(t->pos_coord[3]);
405 r.rl.x=le32_to_cpu(t->pos_coord[2]);
406 r.rl.y=le32_to_cpu(t->pos_coord[1]);
407 mima=(struct minmax *)(t->pos_attr+2);
409 if (!mr->m->eoc || !selection_contains(mr->sel, &r, mima)) {
412 dbg(1,"pushing zipfile %d from %d\n", le32_to_cpu(t->pos_attr[5]), t->zipfile_num);
413 push_zipfile_tile(mr, le32_to_cpu(t->pos_attr[5]));
419 if (mr->item.type == type_countryindex) {
420 map_parse_country_binfile(mr);
422 if (mr->item.type >= type_town_label && mr->item.type <= type_district_label_1e7)
434 map_rect_get_item_byid_binfile(struct map_rect_priv *mr, int id_hi, int id_lo)
438 push_zipfile_tile(mr, id_hi);
440 t->pos=t->start+id_lo;
441 mr->item.id_hi=id_hi;
442 mr->item.id_lo=id_lo;
444 memset(mr->label_attr, 0, sizeof(mr->label_attr));
449 static struct map_search_priv *
450 binmap_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial)
452 struct map_rect_priv *map_rec;
453 struct map_search_priv *msp;
454 struct map_selection *ms;
458 switch (search->type) {
459 case attr_country_name:
462 msp = g_new(struct map_search_priv, 1);
463 msp->search_results = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
464 map_rec = map_rect_new_binfile(map, NULL);
465 map_rec->country_id = item->id_lo;
467 msp->search = search;
468 msp->partial = partial;
471 case attr_town_postal:
473 case attr_street_name:
474 ms = g_new(struct map_selection, 1);
476 for (i = 0; i < layer_end; i++)
480 map_rec = map_rect_new_binfile(map, ms);
481 town = map_rect_get_item_byid_binfile(map_rec, item->id_hi, item->id_lo);
483 struct map_search_priv *msp = g_new(struct map_search_priv, 1);
484 struct coord *c = g_new(struct coord, 1);
486 switch (town->type) {
487 case type_town_label_2e5:
490 case type_town_label_2e4:
493 case type_town_label_2e3:
496 case type_town_label_2e2:
502 item_coord_get(town, c, 1);
503 ms->u.c_rect.lu.x = c->x-size;
504 ms->u.c_rect.lu.y = c->y+size;
505 ms->u.c_rect.rl.x = c->x+size;
506 ms->u.c_rect.rl.y = c->y-size;
508 map_rect_destroy_binfile(map_rec);
509 map_rec = map_rect_new_binfile(map, ms);
511 msp->search = search;
512 msp->partial = partial;
513 msp->search_results = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
516 map_rect_destroy_binfile(map_rec);
525 ascii_cmp(char *name, char *match, int partial)
528 return g_ascii_strncasecmp(name, match, strlen(match));
530 return g_ascii_strcasecmp(name, match);
534 binmap_search_get_item(struct map_search_priv *map_search)
537 while ((it = map_rect_get_item_binfile(map_search->mr))) {
538 if (map_search->search->type == attr_town_name) {
539 if ((it->type >= type_town_label) && (it->type <= type_town_label_1e7)) {
541 if (binfile_attr_get(it->priv_data, attr_label, &at)) {
542 if (!ascii_cmp(at.u.str, map_search->search->u.str, map_search->partial)) {
547 } else if (map_search->search->type == attr_street_name) {
548 if ((it->type == type_street_3_city) || (it->type == type_street_2_city) || (it->type == type_street_1_city)) {
550 if (binfile_attr_get(it->priv_data, attr_label, &at)) {
551 if (!ascii_cmp(at.u.str, map_search->search->u.str, map_search->partial)) {
552 if (!g_hash_table_lookup(map_search->search_results, at.u.str)) {
553 g_hash_table_insert(map_search->search_results, g_strdup(at.u.str), "");
565 binmap_search_destroy(struct map_search_priv *ms)
567 g_hash_table_destroy(ms->search_results);
569 map_rect_destroy_binfile(ms->mr);
573 static struct map_methods map_methods_binfile = {
577 map_rect_new_binfile,
578 map_rect_destroy_binfile,
579 map_rect_get_item_binfile,
580 map_rect_get_item_byid_binfile,
582 binmap_search_destroy,
583 binmap_search_get_item
586 static struct map_priv *
587 map_new_binfile(struct map_methods *meth, struct attr **attrs)
590 struct attr *data=attr_search(attrs, NULL, attr_data);
591 struct file_wordexp *wexp;
592 struct zip_cd *first_cd;
594 int *magic,cde_index_size;
598 wexp=file_wordexp_new(data->u.str);
599 wexp_data=file_wordexp_get_array(wexp);
600 dbg(1,"map_new_binfile %s\n", data->u.str);
601 *meth=map_methods_binfile;
603 m=g_new0(struct map_priv, 1);
605 m->filename=g_strdup(wexp_data[0]);
606 dbg(0,"file_create %s\n", m->filename);
607 m->fi=file_create(m->filename);
609 dbg(0,"Failed to load %s\n", m->filename);
613 file_wordexp_destroy(wexp);
614 magic=(int *)file_data_read(m->fi, 0, 4);
615 *magic = le32_to_cpu(*magic);
616 if (*magic == 0x04034b50) {
617 cde_index_size=sizeof(struct zip_cd)+sizeof("index")-1;
618 m->eoc=(struct zip_eoc *)file_data_read(m->fi,m->fi->size-sizeof(struct zip_eoc), sizeof(struct zip_eoc));
620 printf("magic 0x%x\n", m->eoc->zipesig);
621 m->index_cd=(struct zip_cd *)file_data_read(m->fi,m->fi->size-sizeof(struct zip_eoc)-cde_index_size, cde_index_size);
622 cd_to_cpu(m->index_cd);
623 first_cd=(struct zip_cd *)file_data_read(m->fi,m->eoc->zipeofst, sizeof(struct zip_cd));
625 m->cde_size=sizeof(struct zip_cd)+first_cd->zipcfnl;
626 m->zip_members=(m->eoc->zipecsz-cde_index_size)/m->cde_size+1;
627 printf("cde_size %d\n", m->cde_size);
628 printf("members %d\n",m->zip_members);
629 printf("0x%x\n", m->eoc->zipesig);
630 printf("0x%x\n", m->index_cd->zipcensig);
631 file_data_free(m->fi, (unsigned char *)first_cd);
634 file_data_free(m->fi, (unsigned char *)magic);
641 dbg(1,"binfile: plugin_init\n");
642 plugin_register_map_type("binfile", map_new_binfile);