Fix:Core:Renamed src to navit for cleanup of includes
[navit-package] / navit / data / poi_geodownload / poi_geodownload.c
1 #include <mdbtools.h>
2 #include "config.h"
3 #include "debug.h"
4 #include "coord.h"
5 #include "projection.h"
6 #include "map.h"
7 #include "item.h"
8 #include "plugin.h"
9
10
11 #include <stdio.h>
12 #include <sys/types.h>
13 #include <dirent.h>
14
15 struct map_priv
16 {
17         char *filename;
18         MdbHandle *h;
19         MdbHandle *h_idx;
20         MdbTableDef *table;
21         GPtrArray *table_col;
22         MdbColumn **cols;
23         MdbIndex *idx;
24         int idx_size;
25         enum item_type type;
26         int name_col;
27 };
28
29 struct map_rect_priv
30 {
31         struct item item;
32         struct map_priv *m;
33         enum attr_type attr_next;
34         int cidx;
35         char buffer[4096];
36 };
37
38 #if 0
39 struct index_data {
40         unsigned char data[15];
41 };
42 struct poi {
43         char filename[1024];
44         char icon[1024];
45         long pos;
46         MdbHandle *h;
47         MdbHandle *h_idx;
48         MdbTableDef *table;
49         GPtrArray *table_col;
50         MdbColumn **cols;
51         MdbIndex *idx;
52         int idx_size;
53         struct index_data index_data;
54         MdbIndexChain chain;
55         struct poi *next;
56 } *poi_list;
57
58 struct poi_data {
59         struct poi *poi;
60         int page;
61         int row;
62 };
63
64         char poipath[256];
65         char poibmp[256];
66
67
68 #endif
69
70 static void
71 print_col(MdbHandle *h, MdbColumn *col, char *buffer, int hex)
72 {
73         char *s;
74         dbg(1,"type=%d\n", col->col_type);
75         switch (col->col_type) {
76         case MDB_BOOL:
77                 strcpy(buffer, mdb_pg_get_byte(h, col->cur_value_start) ? "True" : "False");
78                 break;
79         case MDB_BYTE:
80                 sprintf(buffer, "%d", mdb_pg_get_byte(h, col->cur_value_start));
81                 break;
82         case MDB_LONGINT:
83                 if (hex)
84                         sprintf(buffer, "0x%lx", mdb_pg_get_int32(h, col->cur_value_start));
85                 else
86                         sprintf(buffer, "%ld", mdb_pg_get_int32(h, col->cur_value_start));
87                 break;
88         case MDB_DOUBLE:
89                 sprintf(buffer, "%f", mdb_pg_get_double(h, col->cur_value_start));
90                 break;
91         case MDB_TEXT:
92                 dbg(1,"pg_buf %p start %d len %d\n", h->pg_buf, col->cur_value_start, col->cur_value_len);
93                 if (col->cur_value_len) {
94                         s=mdb_col_to_string (h, h->pg_buf, col->cur_value_start, col->col_type, col->cur_value_len);
95                         dbg(1,"s=%p\n", s);
96                         sprintf(buffer, "%s", s);
97                 }
98                 break;
99         default:
100                 sprintf(buffer, "unknown (%d)", col->col_type);
101         }
102 }
103
104 #if 0
105
106 static void
107 setup_idx_data(struct index_data *idx, struct coord *c, unsigned int geoflags, int size)
108 {
109         /* 7f 80 1c 91 0a 7f 80 5c  f5 41 7f 80 00 00 05 */
110         idx->data[0]=0x7f;
111         idx->data[1]=(c->x >> 24) ^ 0x80;
112         idx->data[2]=c->x >> 16;
113         idx->data[3]=c->x >> 8;
114         idx->data[4]=c->x;
115         idx->data[5]=0x7f;
116         idx->data[6]=(c->y >> 24) ^ 0x80;
117         idx->data[7]=c->y >> 16;
118         idx->data[8]=c->y >> 8;
119         idx->data[9]=c->y;
120         idx->data[10]=0x7f;
121         if (size > 12) {
122                 idx->data[11]=0x80 | (geoflags >> 24);
123                 idx->data[12]=geoflags >> 16;
124                 idx->data[13]=geoflags >> 8;
125                 idx->data[14]=geoflags;
126         } else {
127                 idx->data[11]=geoflags;
128         }
129 }
130
131 static void
132 setup_idx_rect(struct coord *rect, struct index_data *idx, int size)
133 {
134         struct coord r[2];
135         r[0].x=rect[0].x;
136         r[0].y=rect[1].y;
137         r[1].x=rect[1].x;
138         r[1].y=rect[0].y;
139 #if 0
140         printf("low 0x%x 0%x\n", r[0].x, r[0].y);
141         printf("high 0x%x 0%x\n", r[1].x, r[1].y);
142 #endif
143         setup_idx_data(idx, r, 0, size);
144         setup_idx_data(idx+1, r+1, 0xffffffff, size);
145 }
146
147 #endif
148
149 static int
150 load_row(struct map_priv *poi, int pg, int row)
151 {
152         int row_start, row_end, offset;
153         unsigned int num_fields, i;
154         MdbField fields[256];
155         MdbFormatConstants *fmt;
156         int debug=0;
157
158         fmt=poi->h->fmt;
159         mdb_read_pg(poi->h, pg);
160         dbg(1, "enter poi=%p pg=%d row=%d\n", poi, pg, row);
161         dbg(1,"Page Type %d row_count_offset %d\n",poi->h->pg_buf[0], fmt->row_count_offset);
162         for (i = 0; i <= row; i++) {
163                 offset=(fmt->row_count_offset + 2) + i * 2;
164                 dbg(1,"row %d %d 0x%x\n", i, offset, mdb_pg_get_int16(poi->h, offset));
165         }
166         row_start = mdb_pg_get_int16(poi->h, (fmt->row_count_offset + 2) + row * 2);
167         if (row_start & 0x4000)
168                 return 1;
169         row_end = mdb_find_end_of_row(poi->h, row);
170         if (debug) {
171                 printf("start=0x%x end=0x%x\n", row_start, row_end);
172                 buffer_dump(poi->h->pg_buf, row_start, row_end);
173         }
174
175         poi->h->cur_pos=row_start & 0x1fff;
176         poi->table->cur_row=row;
177         num_fields = mdb_crack_row(poi->table, row_start & 0x1fff, row_end, fields);
178         dbg(1,"num_fields=%d\n", num_fields);
179         for (i = 0; i < num_fields; i++) {
180                 dbg(1,"i=%d/%d\n", i, num_fields);
181                 poi->cols[i]->cur_value_start=fields[i].start;
182                 poi->cols[i]->cur_value_len=fields[i].siz;
183         }
184         return 0;
185 }
186
187 #if 0
188
189 static MdbIndexPage *
190 index_next_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
191 {
192         MdbIndexPage *ipg;
193
194         ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
195         if (!mdb_index_find_next_on_page(mdb, ipg)) {
196 #if 0
197                 printf("no next\n");    
198 #endif
199                 if (!chain->clean_up_mode) {
200 #if 0
201                         printf("no cleanup\n"); 
202 #endif
203                         if (!(ipg = mdb_index_unwind(mdb, idx, chain)))
204                                 chain->clean_up_mode = 1;
205                 }
206                 if (chain->clean_up_mode) {
207 #if 0
208                         printf("cleanup\n");    
209 #endif
210                         //fprintf(stdout,"in cleanup mode\n");
211
212                         if (!chain->last_leaf_found) {
213                                 printf("no last_leaf_found\n");
214                                 return NULL;
215                         }
216                         mdb_read_pg(mdb, chain->last_leaf_found);
217                         chain->last_leaf_found =
218                             mdb_pg_get_int24(mdb, 0x0c);
219                         //printf("next leaf %lu\n", chain->last_leaf_found);
220                         mdb_read_pg(mdb, chain->last_leaf_found);
221                         /* reuse the chain for cleanup mode */
222                         chain->cur_depth = 1;
223                         ipg = &chain->pages[0];
224                         mdb_index_page_init(ipg);
225                         ipg->pg = chain->last_leaf_found;
226                         //printf("next on page %d\n",
227                         if (!mdb_index_find_next_on_page(mdb, ipg)) {
228 #if 0
229                                 printf("no find_next_on_page\n");
230 #endif
231                                 return NULL;
232                         }
233                 }
234         }
235         return ipg;
236 }
237
238 static int
239 index_next(struct poi *poi, struct index_data *idx)
240 {
241         MdbIndexPage *ipg;
242         MdbIndexChain *chain = &poi->chain;
243         int row;
244         int pg;
245         int offset;
246         char *cmp, *low, *high;
247         int debug=0;
248
249
250         for(;;) {
251         for(;;) {
252         ipg=index_next_row(poi->h_idx, poi->idx, chain);
253         if (! ipg)
254                 return 0;
255         row = poi->h_idx->pg_buf[ipg->offset + ipg->len - 1];
256         pg = mdb_pg_get_int24_msb(poi->h_idx, ipg->offset + ipg->len - 4);
257
258         offset=poi->idx_size+4-ipg->len;
259         memcpy(poi->index_data.data+offset, poi->h_idx->pg_buf+ipg->offset, ipg->len - 4);
260         cmp=poi->index_data.data;
261         low=idx[0].data;
262         high=idx[1].data;
263         if (debug > 1) {
264                 buffer_dump(low, 0, poi->idx_size-1);
265                 buffer_dump(cmp, 0, poi->idx_size-1);
266                 buffer_dump(high, 0, poi->idx_size-1);
267                 printf("%d %d %d\n", memcmp(cmp, low, poi->idx_size), memcmp(cmp, high, poi->idx_size), offset);
268         }
269 #if 0
270         buffer_dump(poi->h_idx->pg_buf, ipg->offset, ipg->offset+ipg->len-1);
271 #endif
272         ipg->offset += ipg->len;
273         if (memcmp(cmp, low, poi->idx_size) >= 0) {
274                 if (memcmp(cmp, high, poi->idx_size) <=0 ) {
275                         if (debug) {
276                                 printf("match\n");
277                                 buffer_dump(low, 0, poi->idx_size-1);
278                                 buffer_dump(cmp, 0, poi->idx_size-1);
279                                 buffer_dump(high, 0, poi->idx_size-1);
280                                 printf("%d %d %d\n", memcmp(cmp, low, poi->idx_size), memcmp(cmp, high, poi->idx_size), offset);
281                         }
282                         break;
283                 } else {
284                         return 0;
285                 }
286         }
287         if (debug > 1)
288                 printf("row=0x%x pg=0x%x len=%d\n", row, pg, ipg->len);
289         }
290         if (debug)
291                 printf("match: row=0x%x pg=0x%x len=%d\n", row, pg, ipg->len);
292                 if (!load_row(poi, pg, row))
293                         break;
294         }
295         return 1;
296 }
297
298 #endif
299
300 static int
301 load_poi_table(struct map_priv *m, MdbCatalogEntry *entry)
302 {
303         int j;
304         MdbIndex *idx;
305
306         m->h_idx=NULL;
307         m->table = mdb_read_table(entry);
308         m->table_col = mdb_read_columns(m->table);
309         mdb_read_indices(m->table);
310         m->cols = (MdbColumn **) (m->table_col->pdata);
311         if (m->table_col->len < 4 || strcasecmp(m->cols[0]->name, "X") ||
312                 strcasecmp(m->cols[1]->name, "Y") || strcasecmp(m->cols[3]->name, "GEOFLAGS")) 
313                         return 1;
314         m->name_col=-1;
315         for (j = 0; j < m->table_col->len ; j++) {
316                 if (!strcasecmp(m->cols[j]->name, "NAME"))
317                         m->name_col=j;
318         }
319         for (j = 0; j < m->table->num_idxs; j++) {
320                 idx = m->table->indices->pdata[j];
321                 if (idx->num_keys == 3 && idx->key_col_num[0] == 1 &&
322                     idx->key_col_num[1] == 2 && idx->key_col_num[2] == 4) {
323                         m->idx = idx;
324                         m->idx_size=3+m->cols[0]->col_size+m->cols[1]->col_size+m->cols[3]->col_size;
325                         m->h_idx=mdb_clone_handle(m->h);
326                 }
327         }
328         return 0;       
329 }
330
331 #if 0
332
333 static void
334 load_poi(char *filename, char *icon, int type)
335 {
336         int i;
337         MdbCatalogEntry *entry;
338         GPtrArray *catalog;
339         struct poi *new = g_new0(struct poi, 1);
340
341        FILE *fp = fopen(filename,"r");
342        if( fp ) {
343                fclose(fp);
344        } else {
345                printf("ERR : POI file %s does not exists!\n",filename);
346                 exit(0);
347                return -1;
348        }
349
350
351        fp = fopen(icon,"r");
352        if( fp ) {
353                fclose(fp);
354        } else {
355                printf("ERR : WARNING INCORRECT PICTURE! %s!\n",icon);
356                 exit(0);
357                return -1;
358        }
359
360         strcpy(new->filename,filename);
361         strcpy(new->icon,icon);
362         new->type = type;
363
364
365         if (type == 0) {
366                 new->h = mdb_open(filename, MDB_NOFLAGS);
367                 catalog = mdb_read_catalog(new->h, MDB_TABLE);
368                 for (i = 0; i < catalog->len; i++) {
369                         entry = catalog->pdata[i];
370                         if (!strcasecmp(entry->object_name, "_INDEXDATA")) {
371                                 if (load_poi_table(new, entry)) {
372                                         printf("%s invalid\n", filename);
373                                         g_free(new);
374                                         new=NULL;
375                                 }
376                         }
377                 }
378                 g_ptr_array_free(catalog, 1);
379         }
380         if (new) {
381                 new->next = poi_list;
382                 poi_list = new;
383         }
384 }
385
386 static void
387 get_coord(struct poi *p, struct coord *c)
388 {
389         c->x=mdb_pg_get_int32(p->h, p->cols[0]->cur_value_start);
390         c->y=mdb_pg_get_int32(p->h, p->cols[1]->cur_value_start);
391 }
392
393 static void
394 poi_info(struct display_list *list, struct popup_item **popup)
395 {
396         struct poi_data *data=list->data;
397         struct poi *poi=data->poi;
398         struct popup_item *popup_last, *popup_val_last;
399         char *text,buffer[4096];
400         int j;
401         MdbColumn *col;
402         char *v;
403
404         popup_last = *popup;
405
406         popup_val_last = NULL;
407         sprintf(buffer,"File:%s", poi->filename);
408         popup_item_new_text(&popup_val_last, buffer, 1);
409         sprintf(buffer,"Icon:%s", poi->icon);
410         popup_item_new_text(&popup_val_last, buffer, 2);
411         if (poi->type == 0) {
412                 printf("poi_info pg=%d row=%d\n", data->page, data->row);
413                 load_row(poi, data->page, data->row);
414                 sprintf(buffer,"Page:%d", data->page);
415                 popup_item_new_text(&popup_val_last, buffer, 3);
416                 sprintf(buffer,"Row:%d", data->row);
417                 popup_item_new_text(&popup_val_last, buffer, 4);
418                 for (j = 0; j < poi->table_col->len; j++) {
419                         col = poi->table_col->pdata[j];
420         #if 0
421                         printf("start: %d type:%d\n", col->cur_value_start, col->col_type);
422         #endif
423                         sprintf(buffer, "%s:", col->name);
424                         v = buffer + strlen(buffer);
425                         if (!strcasecmp(col->name,"X") || !strcasecmp(col->name,"Y")) 
426                                 print_col(poi->h, col, v, 1);
427                         else
428                                 print_col(poi->h, col, v, 0);
429         #if 0
430                         printf("%s\n", buffer);
431         #endif
432                         text=g_convert(buffer,-1,"utf-8","iso8859-1",NULL,NULL,NULL);
433                         popup_item_new_text(&popup_val_last, buffer, j+10);
434                         g_free(text);
435                 }
436         }
437         popup_item_new_text(&popup_last, "POI", 20)->submenu = popup_val_last;
438         *popup=popup_last;
439 }
440
441 static void
442 draw_poi(struct poi *p, struct container *co, struct point *pnt)
443 {
444         struct poi_data data;
445         data.poi=p;
446         if (p->type == 0) {
447                 data.page=p->h->cur_pg;
448                 data.row=p->table->cur_row-1;
449         }
450         if (p->type == 1) {
451                 data.row=p->pos;
452         }
453         display_add(&co->disp[display_poi], 5, 0, p->icon, 1, pnt, poi_info, &data, sizeof(data));
454 }
455
456 static void
457 plugin_draw(struct container *co)
458 {
459         struct coord c;
460         struct point pnt;
461         struct poi *p;
462         struct index_data idx[2];
463         int use_index=0;
464         int debug=1;
465
466         p = poi_list;
467
468         if (co->trans->scale > 1024)
469                 return; 
470         if (debug) {
471                 printf("scale=%ld\n", co->trans->scale);
472                 printf("rect 0x%lx,0%lx-0x%lx,0x%lx\n", co->trans->rect[0].x, co->trans->rect[0].y, co->trans->rect[1].x, co->trans->rect[1].y);
473         }
474         while (p) {
475                 if (p->type == 0) {
476                         if (use_index)
477                                 setup_idx_rect(co->trans->rect, idx, p->idx_size);
478                         if (! use_index) {
479                                 printf("rewind %s %p\n", p->filename, p->table);
480                                 mdb_rewind_table(p->table);
481                                 while (mdb_fetch_row(p->table)) {
482                                         get_coord(p, &c);
483                                         if (transform(co->trans, &c, &pnt)) {
484                                                 if (debug)
485                                                         printf("coord 0x%lx,0x%lx pg %d row %d\n", c.x, c.y, p->h->cur_pg, p->table->cur_row);
486                                                 draw_poi(p, co, &pnt);
487                                         }
488                                 }
489                         }  else {
490                                 memset(&p->chain, 0, sizeof(p->chain));
491                                 while (index_next(p, idx)) {
492                                         get_coord(p, &c);
493                                         if (transform(co->trans, &c, &pnt)) {
494                                                 if (debug)
495                                                         printf("coord 0x%lx,0x%lx pg %d row %d\n", c.x, c.y, p->h->cur_pg, p->table->cur_row);
496                                                 draw_poi(p, co, &pnt);
497                                         }
498                                 }
499                         }
500                 }
501                 if (p->type == 1) {
502                         FILE *f;
503                         char line[1024];
504                         struct text_poi tpoi;
505                         if(!(f=fopen(p->filename, "r"))){
506                                 printf("can't open poi file for drawing!\n");
507                                 exit(0);
508                         }
509 #if 0
510                         printf("opened poi file %s for drawing!\n",p->filename);
511 #endif
512                         p->pos=ftell(f);
513                         fgets(line, 1024, f);
514                         while (!feof(f)) {
515                                 if (strlen(line)) {
516                                         line[strlen(line)-1]='\0';
517                                 }
518                                 if (parse_text_poi(line, &tpoi)) {
519                                         transform_mercator(&tpoi.lat,&tpoi.lng,&c);
520 //                                      printf("%ld %ld\n", c.x, c.y);
521                                         if (transform(co->trans, &c, &pnt)) {
522                                                 draw_poi(p, co, &pnt);
523                                         }
524                                 }
525                                 p->pos=ftell(f);
526                                 fgets(line, 1024, f);
527                         }
528                         fclose(f);                      
529                 }
530                 p = p->next;
531         }
532
533 }
534
535 #endif
536
537 static void
538 map_destroy_poi_geodownload(struct map_priv *m)
539 {
540         dbg(1,"enter\n");
541         g_free(m);
542 }
543
544 static void
545 poi_geodownload_coord_rewind(void *priv_data)
546 {
547         struct map_rect_priv *mr=priv_data;
548         mr->cidx=0;
549 }
550
551
552 static int
553 poi_geodownload_coord_get(void *priv_data, struct coord *c, int count)
554 {
555         struct map_rect_priv *mr=priv_data;
556         dbg(1,"enter\n");
557         if (mr->cidx || !count)
558                 return 0;
559         c->x=mdb_pg_get_int32(mr->m->h, mr->m->cols[0]->cur_value_start);
560         c->y=mdb_pg_get_int32(mr->m->h, mr->m->cols[1]->cur_value_start);
561         dbg(1,"x=0x%x y=0x%x\n", c->x, c->y);
562         return 1;
563 }
564
565 static void
566 poi_geodownload_attr_rewind(void *priv_data)
567 {
568         struct map_rect_priv *mr=priv_data;
569         mr->attr_next=attr_label;
570 }
571
572 static int
573 poi_geodownload_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
574 {
575         struct map_rect_priv *mr=priv_data;
576         struct map_priv *m=mr->m;
577         MdbColumn *col;
578         char *v;
579         int j;
580
581         dbg(1,"enter\n");
582         attr->type=attr_type;
583         switch (attr_type) {
584         case attr_any:
585                 while (mr->attr_next != attr_none) {
586                         if (poi_geodownload_attr_get(mr, mr->attr_next, attr))
587                                 return 1;
588                 }
589                 return 0;
590         case attr_label:
591                 mr->attr_next=attr_debug;
592                 if (m->name_col == -1)
593                         return 0;
594                 col=m->cols[m->name_col];
595                 if (col->cur_value_len) 
596                         attr->u.str=mdb_col_to_string (m->h, m->h->pg_buf, col->cur_value_start, col->col_type, col->cur_value_len);
597                 else
598                         attr->u.str="";
599                 return 1;
600         case attr_debug:
601                 mr->attr_next=attr_none;
602                 v=mr->buffer;
603                 *v='\0';
604                 for (j = 0; j < mr->m->table_col->len; j++) {
605                         col = mr->m->table_col->pdata[j];
606                         printf("start: %d type:%d\n", col->cur_value_start, col->col_type);
607                         sprintf(v, "%s:", col->name);
608                         v += strlen(v);
609                         if (!strcasecmp(col->name,"X") || !strcasecmp(col->name,"Y")) 
610                                 print_col(mr->m->h, col, v, 1);
611                         else
612                                 print_col(mr->m->h, col, v, 0);
613                         v += strlen(v);
614                         *v++='\n';
615                         *v='\0';
616                 }
617                 attr->u.str=mr->buffer;
618                 return 1;
619         default:
620                 break;
621         }
622         return 0;
623 }
624
625 static struct item_methods methods_poi_geodownload = {
626         poi_geodownload_coord_rewind,
627         poi_geodownload_coord_get,
628         poi_geodownload_attr_rewind,
629         poi_geodownload_attr_get,
630 };
631
632
633 static struct map_rect_priv *
634 map_rect_new_poi_geodownload(struct map_priv *map, struct map_selection *sel)
635 {
636         struct map_rect_priv *mr;
637
638         dbg(1,"enter\n");
639         mr=g_new0(struct map_rect_priv, 1);
640         mr->item.meth=&methods_poi_geodownload;
641         mr->item.id_hi=0;
642         mr->item.id_lo=0;
643         mr->item.priv_data=mr;
644         mr->item.type=map->type;
645         mr->m=map;
646         mdb_rewind_table(map->table);
647         return mr;
648 }
649
650
651 static void
652 map_rect_destroy_poi_geodownload(struct map_rect_priv *mr)
653 {
654         g_free(mr);
655 }
656
657 static struct item *
658 map_rect_get_item_poi_geodownload(struct map_rect_priv *mr)
659 {
660         dbg(1,"enter\n");
661         if (mdb_fetch_row(mr->m->table)) {
662                 mr->item.id_hi=mr->m->table->cur_phys_pg;
663                 mr->item.id_lo=mr->m->table->cur_row-1;
664                 poi_geodownload_attr_rewind(mr);
665                 return &mr->item;
666         }
667         return NULL;
668 }
669
670 static struct item *
671 map_rect_get_item_byid_poi_geodownload(struct map_rect_priv *mr, int id_hi, int id_lo)
672 {
673         char *v, buffer[4096];
674         int j;
675         MdbColumn *col;
676
677         dbg(1,"enter\n");
678         load_row(mr->m, id_hi, id_lo);
679         for (j = 0; j < mr->m->table_col->len; j++) {
680                 col = mr->m->table_col->pdata[j];
681                 printf("start: %d type:%d\n", col->cur_value_start, col->col_type);
682                 sprintf(buffer, "%s:", col->name);
683                 v = buffer + strlen(buffer);
684                 if (!strcasecmp(col->name,"X") || !strcasecmp(col->name,"Y")) 
685                         print_col(mr->m->h, col, v, 1);
686                 else
687                         print_col(mr->m->h, col, v, 0);
688                 printf("%s\n", buffer);
689         }
690         dbg(1,"ret=%p\n", &mr->item);
691         poi_geodownload_attr_rewind(mr);
692         return &mr->item;
693 }
694
695
696 static struct map_methods map_methods_poi_geodownload = {
697         projection_mg,
698         "iso8859-1",
699         map_destroy_poi_geodownload,
700         map_rect_new_poi_geodownload,
701         map_rect_destroy_poi_geodownload,
702         map_rect_get_item_poi_geodownload,
703         map_rect_get_item_byid_poi_geodownload,
704 };
705
706 static struct map_priv *
707 map_new_poi_geodownload(struct map_methods *meth, struct attr **attrs)
708 {
709         struct map_priv *m;
710         MdbCatalogEntry *entry;
711         GPtrArray *catalog;
712         int i;
713         struct attr *attr;
714         struct attr *data=attr_search(attrs, NULL, attr_data);
715         char *filename;
716         if (! data)
717                 return NULL;
718         filename=data->u.str;
719         dbg(1,"filename %s\n",filename);
720         *meth=map_methods_poi_geodownload;
721
722         m=g_new(struct map_priv, 1);
723         m->filename=g_strdup(filename);
724         m->h = mdb_open(m->filename, MDB_NOFLAGS);
725         m->type=type_none;
726         dbg(1,"attr_search\n");
727         attr=attr_search(attrs, NULL, attr_item_type);
728         dbg(1,"attr_search result %p\n", attr);
729         if (attr) 
730                 m->type=attr->u.item_type;
731                 
732         
733         catalog = mdb_read_catalog(m->h, MDB_TABLE);
734         for (i = 0; i < catalog->len; i++) {
735                 entry = catalog->pdata[i];
736                 dbg(1,"object name '%s'\n", entry->object_name);
737                 if (!strcasecmp(entry->object_name, "_INDEXDATA")) {
738                         if (load_poi_table(m, entry)) {
739                                 printf("%s invalid\n", filename);
740                                 g_free(m);
741                                 m=NULL;
742                         }
743                 }
744         }
745         g_ptr_array_free(catalog, 1);
746         return m;
747 }
748
749 void
750 plugin_init(void)
751 {
752         dbg(1,"plugin_init\n");
753         plugin_register_map_type("poi_geodownload", map_new_poi_geodownload);
754         mdb_init();
755 }
756