5 #include "projection.h"
12 #include <sys/types.h>
33 enum attr_type attr_next;
40 unsigned char data[15];
53 struct index_data index_data;
71 print_col(MdbHandle *h, MdbColumn *col, char *buffer, int hex)
74 dbg(1,"type=%d\n", col->col_type);
75 switch (col->col_type) {
77 strcpy(buffer, mdb_pg_get_byte(h, col->cur_value_start) ? "True" : "False");
80 sprintf(buffer, "%d", mdb_pg_get_byte(h, col->cur_value_start));
84 sprintf(buffer, "0x%lx", mdb_pg_get_int32(h, col->cur_value_start));
86 sprintf(buffer, "%ld", mdb_pg_get_int32(h, col->cur_value_start));
89 sprintf(buffer, "%f", mdb_pg_get_double(h, col->cur_value_start));
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);
96 sprintf(buffer, "%s", s);
100 sprintf(buffer, "unknown (%d)", col->col_type);
107 setup_idx_data(struct index_data *idx, struct coord *c, unsigned int geoflags, int size)
109 /* 7f 80 1c 91 0a 7f 80 5c f5 41 7f 80 00 00 05 */
111 idx->data[1]=(c->x >> 24) ^ 0x80;
112 idx->data[2]=c->x >> 16;
113 idx->data[3]=c->x >> 8;
116 idx->data[6]=(c->y >> 24) ^ 0x80;
117 idx->data[7]=c->y >> 16;
118 idx->data[8]=c->y >> 8;
122 idx->data[11]=0x80 | (geoflags >> 24);
123 idx->data[12]=geoflags >> 16;
124 idx->data[13]=geoflags >> 8;
125 idx->data[14]=geoflags;
127 idx->data[11]=geoflags;
132 setup_idx_rect(struct coord *rect, struct index_data *idx, int size)
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);
143 setup_idx_data(idx, r, 0, size);
144 setup_idx_data(idx+1, r+1, 0xffffffff, size);
150 load_row(struct map_priv *poi, int pg, int row)
152 int row_start, row_end, offset;
153 unsigned int num_fields, i;
154 MdbField fields[256];
155 MdbFormatConstants *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));
166 row_start = mdb_pg_get_int16(poi->h, (fmt->row_count_offset + 2) + row * 2);
167 if (row_start & 0x4000)
169 row_end = mdb_find_end_of_row(poi->h, row);
171 printf("start=0x%x end=0x%x\n", row_start, row_end);
172 buffer_dump(poi->h->pg_buf, row_start, row_end);
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;
189 static MdbIndexPage *
190 index_next_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
194 ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
195 if (!mdb_index_find_next_on_page(mdb, ipg)) {
199 if (!chain->clean_up_mode) {
201 printf("no cleanup\n");
203 if (!(ipg = mdb_index_unwind(mdb, idx, chain)))
204 chain->clean_up_mode = 1;
206 if (chain->clean_up_mode) {
210 //fprintf(stdout,"in cleanup mode\n");
212 if (!chain->last_leaf_found) {
213 printf("no last_leaf_found\n");
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)) {
229 printf("no find_next_on_page\n");
239 index_next(struct poi *poi, struct index_data *idx)
242 MdbIndexChain *chain = &poi->chain;
246 char *cmp, *low, *high;
252 ipg=index_next_row(poi->h_idx, poi->idx, chain);
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);
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;
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);
270 buffer_dump(poi->h_idx->pg_buf, ipg->offset, ipg->offset+ipg->len-1);
272 ipg->offset += ipg->len;
273 if (memcmp(cmp, low, poi->idx_size) >= 0) {
274 if (memcmp(cmp, high, poi->idx_size) <=0 ) {
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);
288 printf("row=0x%x pg=0x%x len=%d\n", row, pg, ipg->len);
291 printf("match: row=0x%x pg=0x%x len=%d\n", row, pg, ipg->len);
292 if (!load_row(poi, pg, row))
301 load_poi_table(struct map_priv *m, MdbCatalogEntry *entry)
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"))
315 for (j = 0; j < m->table_col->len ; j++) {
316 if (!strcasecmp(m->cols[j]->name, "NAME"))
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) {
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);
334 load_poi(char *filename, char *icon, int type)
337 MdbCatalogEntry *entry;
339 struct poi *new = g_new0(struct poi, 1);
341 FILE *fp = fopen(filename,"r");
345 printf("ERR : POI file %s does not exists!\n",filename);
351 fp = fopen(icon,"r");
355 printf("ERR : WARNING INCORRECT PICTURE! %s!\n",icon);
360 strcpy(new->filename,filename);
361 strcpy(new->icon,icon);
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);
378 g_ptr_array_free(catalog, 1);
381 new->next = poi_list;
387 get_coord(struct poi *p, struct coord *c)
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);
394 poi_info(struct display_list *list, struct popup_item **popup)
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];
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];
421 printf("start: %d type:%d\n", col->cur_value_start, col->col_type);
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);
428 print_col(poi->h, col, v, 0);
430 printf("%s\n", buffer);
432 text=g_convert(buffer,-1,"utf-8","iso8859-1",NULL,NULL,NULL);
433 popup_item_new_text(&popup_val_last, buffer, j+10);
437 popup_item_new_text(&popup_last, "POI", 20)->submenu = popup_val_last;
442 draw_poi(struct poi *p, struct container *co, struct point *pnt)
444 struct poi_data data;
447 data.page=p->h->cur_pg;
448 data.row=p->table->cur_row-1;
453 display_add(&co->disp[display_poi], 5, 0, p->icon, 1, pnt, poi_info, &data, sizeof(data));
457 plugin_draw(struct container *co)
462 struct index_data idx[2];
468 if (co->trans->scale > 1024)
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);
477 setup_idx_rect(co->trans->rect, idx, p->idx_size);
479 printf("rewind %s %p\n", p->filename, p->table);
480 mdb_rewind_table(p->table);
481 while (mdb_fetch_row(p->table)) {
483 if (transform(co->trans, &c, &pnt)) {
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);
490 memset(&p->chain, 0, sizeof(p->chain));
491 while (index_next(p, idx)) {
493 if (transform(co->trans, &c, &pnt)) {
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);
504 struct text_poi tpoi;
505 if(!(f=fopen(p->filename, "r"))){
506 printf("can't open poi file for drawing!\n");
510 printf("opened poi file %s for drawing!\n",p->filename);
513 fgets(line, 1024, f);
516 line[strlen(line)-1]='\0';
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);
526 fgets(line, 1024, f);
538 map_destroy_poi_geodownload(struct map_priv *m)
545 poi_geodownload_coord_rewind(void *priv_data)
547 struct map_rect_priv *mr=priv_data;
553 poi_geodownload_coord_get(void *priv_data, struct coord *c, int count)
555 struct map_rect_priv *mr=priv_data;
557 if (mr->cidx || !count)
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);
566 poi_geodownload_attr_rewind(void *priv_data)
568 struct map_rect_priv *mr=priv_data;
569 mr->attr_next=attr_label;
573 poi_geodownload_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
575 struct map_rect_priv *mr=priv_data;
576 struct map_priv *m=mr->m;
582 attr->type=attr_type;
585 while (mr->attr_next != attr_none) {
586 if (poi_geodownload_attr_get(mr, mr->attr_next, attr))
591 mr->attr_next=attr_debug;
592 if (m->name_col == -1)
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);
601 mr->attr_next=attr_none;
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);
609 if (!strcasecmp(col->name,"X") || !strcasecmp(col->name,"Y"))
610 print_col(mr->m->h, col, v, 1);
612 print_col(mr->m->h, col, v, 0);
617 attr->u.str=mr->buffer;
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,
633 static struct map_rect_priv *
634 map_rect_new_poi_geodownload(struct map_priv *map, struct map_selection *sel)
636 struct map_rect_priv *mr;
639 mr=g_new0(struct map_rect_priv, 1);
640 mr->item.meth=&methods_poi_geodownload;
643 mr->item.priv_data=mr;
644 mr->item.type=map->type;
646 mdb_rewind_table(map->table);
652 map_rect_destroy_poi_geodownload(struct map_rect_priv *mr)
658 map_rect_get_item_poi_geodownload(struct map_rect_priv *mr)
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);
671 map_rect_get_item_byid_poi_geodownload(struct map_rect_priv *mr, int id_hi, int id_lo)
673 char *v, buffer[4096];
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);
687 print_col(mr->m->h, col, v, 0);
688 printf("%s\n", buffer);
690 dbg(1,"ret=%p\n", &mr->item);
691 poi_geodownload_attr_rewind(mr);
696 static struct map_methods map_methods_poi_geodownload = {
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,
706 static struct map_priv *
707 map_new_poi_geodownload(struct map_methods *meth, struct attr **attrs)
710 MdbCatalogEntry *entry;
714 struct attr *data=attr_search(attrs, NULL, attr_data);
718 filename=data->u.str;
719 dbg(1,"filename %s\n",filename);
720 *meth=map_methods_poi_geodownload;
722 m=g_new(struct map_priv, 1);
723 m->filename=g_strdup(filename);
724 m->h = mdb_open(m->filename, MDB_NOFLAGS);
726 dbg(1,"attr_search\n");
727 attr=attr_search(attrs, NULL, attr_item_type);
728 dbg(1,"attr_search result %p\n", attr);
730 m->type=attr->u.item_type;
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);
745 g_ptr_array_free(catalog, 1);
752 dbg(1,"plugin_init\n");
753 plugin_register_map_type("poi_geodownload", map_new_poi_geodownload);