diff options
author | Joseph Herlant <herlantj@gmail.com> | 2018-05-25 22:06:51 -0700 |
---|---|---|
committer | Joseph Herlant <aerostitch@users.noreply.github.com> | 2018-05-25 22:17:50 -0700 |
commit | 8a76acb966f7059caf9d72c853175bd923b1e9d7 (patch) | |
tree | 1735178f7a0718831b88d2c36ea18a9955de3224 /navit/map | |
parent | 032f15287b472f1a4b5349533f3e5b468684b281 (diff) | |
download | navit-8a76acb966f7059caf9d72c853175bd923b1e9d7.tar.gz |
cleanup:global:Use astyle to reformat everything
Diffstat (limited to 'navit/map')
-rw-r--r-- | navit/map/binfile/binfile.c | 4669 | ||||
-rw-r--r-- | navit/map/csv/csv.c | 1458 | ||||
-rw-r--r-- | navit/map/csv/quadtree.c | 952 | ||||
-rw-r--r-- | navit/map/filter/filter.c | 598 | ||||
-rw-r--r-- | navit/map/garmin/gar2navit.c | 294 | ||||
-rw-r--r-- | navit/map/garmin/garmin.c | 1609 | ||||
-rw-r--r-- | navit/map/garmin/gentypes.c | 165 | ||||
-rw-r--r-- | navit/map/garmin_img/garmin_img.c | 2375 | ||||
-rw-r--r-- | navit/map/mg/block.c | 438 | ||||
-rw-r--r-- | navit/map/mg/map.c | 1001 | ||||
-rw-r--r-- | navit/map/mg/poly.c | 418 | ||||
-rw-r--r-- | navit/map/mg/street.c | 1667 | ||||
-rw-r--r-- | navit/map/mg/town.c | 432 | ||||
-rw-r--r-- | navit/map/mg/tree.c | 463 | ||||
-rw-r--r-- | navit/map/shapefile/shapefile.c | 1055 | ||||
-rw-r--r-- | navit/map/textfile/textfile.c | 578 |
16 files changed, 8943 insertions, 9229 deletions
diff --git a/navit/map/binfile/binfile.c b/navit/map/binfile/binfile.c index cd6fec8dc..5349a6717 100644 --- a/navit/map/binfile/binfile.c +++ b/navit/map/binfile/binfile.c @@ -62,40 +62,40 @@ static int map_id; * used for working with the data. */ struct tile { - int *start; //!< Memory address of the buffer containing the tile data (the actual map data). - int *end; //!< First memory address not belonging to the tile data. - /**< Thus tile->end - tile->start represents the size of the tile data - * in multiples of 4 Bytes. - */ - int *pos; //!< Pointer to current position (start of current item) inside the tile data. - int *pos_coord_start; //!< Pointer to the first element inside the current item that is a coordinate. - /**< That is the first position after the header of an - * item. The header holds 3 entries each 32bit wide integers: - * header[0] holds the size of the whole item (excluding this size field) - * header[1] holds the type of the item - * header[2] holds the size of the coordinates in the tile - */ - int *pos_coord; //!< Current position in the coordinates region of the current item. - int *pos_attr_start; //!< Pointer to the first attr data structure of the current item. - int *pos_attr; //!< Current position in the attr region of the current item. - int *pos_next; //!< Pointer to the next item (the item which follows the "current item" as indicated by *pos). - struct file *fi; //!< The file from which this tile was loaded. - int zipfile_num; - int mode; + int *start; //!< Memory address of the buffer containing the tile data (the actual map data). + int *end; //!< First memory address not belonging to the tile data. + /**< Thus tile->end - tile->start represents the size of the tile data + * in multiples of 4 Bytes. + */ + int *pos; //!< Pointer to current position (start of current item) inside the tile data. + int *pos_coord_start; //!< Pointer to the first element inside the current item that is a coordinate. + /**< That is the first position after the header of an + * item. The header holds 3 entries each 32bit wide integers: + * header[0] holds the size of the whole item (excluding this size field) + * header[1] holds the type of the item + * header[2] holds the size of the coordinates in the tile + */ + int *pos_coord; //!< Current position in the coordinates region of the current item. + int *pos_attr_start; //!< Pointer to the first attr data structure of the current item. + int *pos_attr; //!< Current position in the attr region of the current item. + int *pos_next; //!< Pointer to the next item (the item which follows the "current item" as indicated by *pos). + struct file *fi; //!< The file from which this tile was loaded. + int zipfile_num; + int mode; }; struct map_download { - int state; - struct map_priv *m; - struct map_rect_priv *mr; - struct file *http,*file; - int zipfile,toffset,tlength,progress,read,dl_size; - long long offset,start_offset,cd1offset,size; - struct zip64_eoc *zip64_eoc; - struct zip64_eocl *zip64_eocl; - struct zip_eoc *zip_eoc; - struct zip_cd *cd_copy,*cd; + int state; + struct map_priv *m; + struct map_rect_priv *mr; + struct file *http,*file; + int zipfile,toffset,tlength,progress,read,dl_size; + long long offset,start_offset,cd1offset,size; + struct zip64_eoc *zip64_eoc; + struct zip64_eocl *zip64_eocl; + struct zip_eoc *zip_eoc; + struct zip_cd *cd_copy,*cd; }; /** @@ -103,56 +103,56 @@ struct map_download { * */ struct map_priv { - int id; - char *filename; //!< Filename of the binfile. - char *cachedir; - struct file *fi,*http; - struct file **fis; - struct zip_cd *index_cd; - int index_offset; - int cde_size; - struct zip_eoc *eoc; - struct zip64_eoc *eoc64; - int zip_members; - unsigned char *search_data; - int search_offset; - int search_size; - int version; - int check_version; - int map_version; - GHashTable *changes; - char *map_release; - int flags; - char *url; - int update_available; - char *progress; - struct callback_list *cbl; - struct map_download *download; - int redirect; - long download_enabled; - int last_searched_town_id_hi; - int last_searched_town_id_lo; + int id; + char *filename; //!< Filename of the binfile. + char *cachedir; + struct file *fi,*http; + struct file **fis; + struct zip_cd *index_cd; + int index_offset; + int cde_size; + struct zip_eoc *eoc; + struct zip64_eoc *eoc64; + int zip_members; + unsigned char *search_data; + int search_offset; + int search_size; + int version; + int check_version; + int map_version; + GHashTable *changes; + char *map_release; + int flags; + char *url; + int update_available; + char *progress; + struct callback_list *cbl; + struct map_download *download; + int redirect; + long download_enabled; + int last_searched_town_id_hi; + int last_searched_town_id_lo; }; struct map_rect_priv { - int *start; - int *end; - enum attr_type attr_last; - int label; - int *label_attr[5]; - struct map_selection *sel; - struct map_priv *m; - struct item item; - int tile_depth; - struct tile tiles[8]; - struct tile *t; - int country_id; - char *url; - struct attr attrs[8]; - int status; - struct map_search_priv *msp; + int *start; + int *end; + enum attr_type attr_last; + int label; + int *label_attr[5]; + struct map_selection *sel; + struct map_priv *m; + struct item item; + int tile_depth; + struct tile tiles[8]; + struct tile *t; + int country_id; + char *url; + struct attr attrs[8]; + int status; + struct map_search_priv *msp; #ifdef DEBUG_SIZE - int size; + int size; #endif }; @@ -162,18 +162,18 @@ struct map_rect_priv { * when starting a search, and is used for retrieving results. */ struct map_search_priv { - struct map_priv *map; /**< Map to search in. */ - struct map_rect_priv *mr; /**< Map rectangle to search inside. */ - struct map_rect_priv *mr_item; - struct item *item; - struct attr search; /**< Attribute specifying what to search for. */ - struct map_selection ms; - GList *boundaries; - int partial; /**< Find partial matches? */ - int mode; - struct coord_rect rect_new; - char *parent_name; - GHashTable *search_results; + struct map_priv *map; /**< Map to search in. */ + struct map_rect_priv *mr; /**< Map rectangle to search inside. */ + struct map_rect_priv *mr_item; + struct item *item; + struct attr search; /**< Attribute specifying what to search for. */ + struct map_selection ms; + GList *boundaries; + int partial; /**< Find partial matches? */ + int mode; + struct coord_rect rect_new; + char *parent_name; + GHashTable *search_results; }; @@ -184,127 +184,124 @@ static int map_binfile_open(struct map_priv *m); static void map_binfile_destroy(struct map_priv *m); static void lfh_to_cpu(struct zip_lfh *lfh) { - dbg_assert(lfh != NULL); - if (lfh->ziplocsig != zip_lfh_sig) { - lfh->ziplocsig = le32_to_cpu(lfh->ziplocsig); - lfh->zipver = le16_to_cpu(lfh->zipver); - lfh->zipgenfld = le16_to_cpu(lfh->zipgenfld); - lfh->zipmthd = le16_to_cpu(lfh->zipmthd); - lfh->ziptime = le16_to_cpu(lfh->ziptime); - lfh->zipdate = le16_to_cpu(lfh->zipdate); - lfh->zipcrc = le32_to_cpu(lfh->zipcrc); - lfh->zipsize = le32_to_cpu(lfh->zipsize); - lfh->zipuncmp = le32_to_cpu(lfh->zipuncmp); - lfh->zipfnln = le16_to_cpu(lfh->zipfnln); - lfh->zipxtraln = le16_to_cpu(lfh->zipxtraln); - } + dbg_assert(lfh != NULL); + if (lfh->ziplocsig != zip_lfh_sig) { + lfh->ziplocsig = le32_to_cpu(lfh->ziplocsig); + lfh->zipver = le16_to_cpu(lfh->zipver); + lfh->zipgenfld = le16_to_cpu(lfh->zipgenfld); + lfh->zipmthd = le16_to_cpu(lfh->zipmthd); + lfh->ziptime = le16_to_cpu(lfh->ziptime); + lfh->zipdate = le16_to_cpu(lfh->zipdate); + lfh->zipcrc = le32_to_cpu(lfh->zipcrc); + lfh->zipsize = le32_to_cpu(lfh->zipsize); + lfh->zipuncmp = le32_to_cpu(lfh->zipuncmp); + lfh->zipfnln = le16_to_cpu(lfh->zipfnln); + lfh->zipxtraln = le16_to_cpu(lfh->zipxtraln); + } } static void cd_to_cpu(struct zip_cd *zcd) { - dbg_assert(zcd != NULL); - if (zcd->zipcensig != zip_cd_sig) { - zcd->zipcensig = le32_to_cpu(zcd->zipcensig); - zcd->zipccrc = le32_to_cpu(zcd->zipccrc); - zcd->zipcsiz = le32_to_cpu(zcd->zipcsiz); - zcd->zipcunc = le32_to_cpu(zcd->zipcunc); - zcd->zipcfnl = le16_to_cpu(zcd->zipcfnl); - zcd->zipcxtl = le16_to_cpu(zcd->zipcxtl); - zcd->zipccml = le16_to_cpu(zcd->zipccml); - zcd->zipdsk = le16_to_cpu(zcd->zipdsk); - zcd->zipint = le16_to_cpu(zcd->zipint); - zcd->zipext = le32_to_cpu(zcd->zipext); - zcd->zipofst = le32_to_cpu(zcd->zipofst); - } + dbg_assert(zcd != NULL); + if (zcd->zipcensig != zip_cd_sig) { + zcd->zipcensig = le32_to_cpu(zcd->zipcensig); + zcd->zipccrc = le32_to_cpu(zcd->zipccrc); + zcd->zipcsiz = le32_to_cpu(zcd->zipcsiz); + zcd->zipcunc = le32_to_cpu(zcd->zipcunc); + zcd->zipcfnl = le16_to_cpu(zcd->zipcfnl); + zcd->zipcxtl = le16_to_cpu(zcd->zipcxtl); + zcd->zipccml = le16_to_cpu(zcd->zipccml); + zcd->zipdsk = le16_to_cpu(zcd->zipdsk); + zcd->zipint = le16_to_cpu(zcd->zipint); + zcd->zipext = le32_to_cpu(zcd->zipext); + zcd->zipofst = le32_to_cpu(zcd->zipofst); + } } static void eoc_to_cpu(struct zip_eoc *eoc) { - dbg_assert(eoc != NULL); - if (eoc->zipesig != zip_eoc_sig) { - eoc->zipesig = le32_to_cpu(eoc->zipesig); - eoc->zipedsk = le16_to_cpu(eoc->zipedsk); - eoc->zipecen = le16_to_cpu(eoc->zipecen); - eoc->zipenum = le16_to_cpu(eoc->zipenum); - eoc->zipecenn = le16_to_cpu(eoc->zipecenn); - eoc->zipecsz = le32_to_cpu(eoc->zipecsz); - eoc->zipeofst = le32_to_cpu(eoc->zipeofst); - eoc->zipecoml = le16_to_cpu(eoc->zipecoml); - } + dbg_assert(eoc != NULL); + if (eoc->zipesig != zip_eoc_sig) { + eoc->zipesig = le32_to_cpu(eoc->zipesig); + eoc->zipedsk = le16_to_cpu(eoc->zipedsk); + eoc->zipecen = le16_to_cpu(eoc->zipecen); + eoc->zipenum = le16_to_cpu(eoc->zipenum); + eoc->zipecenn = le16_to_cpu(eoc->zipecenn); + eoc->zipecsz = le32_to_cpu(eoc->zipecsz); + eoc->zipeofst = le32_to_cpu(eoc->zipeofst); + eoc->zipecoml = le16_to_cpu(eoc->zipecoml); + } } static void binfile_check_version(struct map_priv *m); static struct zip_eoc * -binfile_read_eoc(struct file *fi) -{ - struct zip_eoc *eoc; - eoc=(struct zip_eoc *)file_data_read(fi,fi->size-sizeof(struct zip_eoc), sizeof(struct zip_eoc)); - if (eoc) { - eoc_to_cpu(eoc); - dbg(lvl_debug,"sig 0x%x", eoc->zipesig); - if (eoc->zipesig != zip_eoc_sig) { - dbg(lvl_error,"map file %s: eoc signature check failed: 0x%x vs 0x%x", fi->name, eoc->zipesig,zip_eoc_sig); - file_data_free(fi,(unsigned char *)eoc); - eoc=NULL; - } - } - return eoc; +binfile_read_eoc(struct file *fi) { + struct zip_eoc *eoc; + eoc=(struct zip_eoc *)file_data_read(fi,fi->size-sizeof(struct zip_eoc), sizeof(struct zip_eoc)); + if (eoc) { + eoc_to_cpu(eoc); + dbg(lvl_debug,"sig 0x%x", eoc->zipesig); + if (eoc->zipesig != zip_eoc_sig) { + dbg(lvl_error,"map file %s: eoc signature check failed: 0x%x vs 0x%x", fi->name, eoc->zipesig,zip_eoc_sig); + file_data_free(fi,(unsigned char *)eoc); + eoc=NULL; + } + } + return eoc; } static struct zip64_eoc * -binfile_read_eoc64(struct file *fi) -{ - struct zip64_eocl *eocl; - struct zip64_eoc *eoc; - eocl=(struct zip64_eocl *)file_data_read(fi,fi->size-sizeof(struct zip_eoc)-sizeof(struct zip64_eocl), sizeof(struct zip64_eocl)); - if (!eocl) - return NULL; - dbg(lvl_debug,"sig 0x%x", eocl->zip64lsig); - if (eocl->zip64lsig != zip64_eocl_sig) { - file_data_free(fi,(unsigned char *)eocl); - dbg(lvl_warning,"map file %s: eocl wrong", fi->name); - return NULL; - } - eoc=(struct zip64_eoc *)file_data_read(fi,eocl->zip64lofst, sizeof(struct zip64_eoc)); - if (eoc) { - if (eoc->zip64esig != zip64_eoc_sig) { - file_data_free(fi,(unsigned char *)eoc); - dbg(lvl_warning,"map file %s: eoc wrong", fi->name); - eoc=NULL; - } - dbg(lvl_debug,"eoc64 ok 0x"LONGLONG_HEX_FMT " 0x"LONGLONG_HEX_FMT "",eoc->zip64eofst,eoc->zip64ecsz); - } - file_data_free(fi,(unsigned char *)eocl); - return eoc; +binfile_read_eoc64(struct file *fi) { + struct zip64_eocl *eocl; + struct zip64_eoc *eoc; + eocl=(struct zip64_eocl *)file_data_read(fi,fi->size-sizeof(struct zip_eoc)-sizeof(struct zip64_eocl), + sizeof(struct zip64_eocl)); + if (!eocl) + return NULL; + dbg(lvl_debug,"sig 0x%x", eocl->zip64lsig); + if (eocl->zip64lsig != zip64_eocl_sig) { + file_data_free(fi,(unsigned char *)eocl); + dbg(lvl_warning,"map file %s: eocl wrong", fi->name); + return NULL; + } + eoc=(struct zip64_eoc *)file_data_read(fi,eocl->zip64lofst, sizeof(struct zip64_eoc)); + if (eoc) { + if (eoc->zip64esig != zip64_eoc_sig) { + file_data_free(fi,(unsigned char *)eoc); + dbg(lvl_warning,"map file %s: eoc wrong", fi->name); + eoc=NULL; + } + dbg(lvl_debug,"eoc64 ok 0x"LONGLONG_HEX_FMT " 0x"LONGLONG_HEX_FMT "",eoc->zip64eofst,eoc->zip64ecsz); + } + file_data_free(fi,(unsigned char *)eocl); + return eoc; } static int -binfile_cd_extra(struct zip_cd *cd) -{ - return cd->zipcfnl+cd->zipcxtl; +binfile_cd_extra(struct zip_cd *cd) { + return cd->zipcfnl+cd->zipcxtl; } static struct zip_cd * -binfile_read_cd(struct map_priv *m, int offset, int len) -{ - struct zip_cd *cd; - long long cdoffset=m->eoc64?m->eoc64->zip64eofst:m->eoc->zipeofst; - if (len == -1) { - cd=(struct zip_cd *)file_data_read(m->fi,cdoffset+offset, sizeof(*cd)); - cd_to_cpu(cd); - len=binfile_cd_extra(cd); - file_data_free(m->fi,(unsigned char *)cd); - } - cd=(struct zip_cd *)file_data_read(m->fi,cdoffset+offset, sizeof(*cd)+len); - if (cd) { - dbg(lvl_debug,"cd at "LONGLONG_FMT" %zu bytes",cdoffset+offset, sizeof(*cd)+len); - cd_to_cpu(cd); - dbg(lvl_debug,"sig 0x%x", cd->zipcensig); - if (cd->zipcensig != zip_cd_sig) { - file_data_free(m->fi,(unsigned char *)cd); - cd=NULL; - } - } - return cd; +binfile_read_cd(struct map_priv *m, int offset, int len) { + struct zip_cd *cd; + long long cdoffset=m->eoc64?m->eoc64->zip64eofst:m->eoc->zipeofst; + if (len == -1) { + cd=(struct zip_cd *)file_data_read(m->fi,cdoffset+offset, sizeof(*cd)); + cd_to_cpu(cd); + len=binfile_cd_extra(cd); + file_data_free(m->fi,(unsigned char *)cd); + } + cd=(struct zip_cd *)file_data_read(m->fi,cdoffset+offset, sizeof(*cd)+len); + if (cd) { + dbg(lvl_debug,"cd at "LONGLONG_FMT" %zu bytes",cdoffset+offset, sizeof(*cd)+len); + cd_to_cpu(cd); + dbg(lvl_debug,"sig 0x%x", cd->zipcensig); + if (cd->zipcensig != zip_cd_sig) { + file_data_free(m->fi,(unsigned char *)cd); + cd=NULL; + } + } + return cd; } /** @@ -315,17 +312,16 @@ binfile_read_cd(struct map_priv *m, int offset, int len) * @return pointer to ZIP64 extra field, or NULL if not available */ static struct zip_cd_ext * -binfile_cd_ext(struct zip_cd *cd) -{ - struct zip_cd_ext *ext; - if (cd->zipofst != zip_size_64bit_placeholder) - return NULL; - if (cd->zipcxtl != sizeof(*ext)) - return NULL; - ext=(struct zip_cd_ext *)((unsigned char *)cd+sizeof(*cd)+cd->zipcfnl); - if (ext->tag != zip_extra_header_id_zip64 || ext->size != 8) - return NULL; - return ext; +binfile_cd_ext(struct zip_cd *cd) { + struct zip_cd_ext *ext; + if (cd->zipofst != zip_size_64bit_placeholder) + return NULL; + if (cd->zipcxtl != sizeof(*ext)) + return NULL; + ext=(struct zip_cd_ext *)((unsigned char *)cd+sizeof(*cd)+cd->zipcfnl); + if (ext->tag != zip_extra_header_id_zip64 || ext->size != 8) + return NULL; + return ext; } /** @@ -334,147 +330,140 @@ binfile_cd_ext(struct zip_cd *cd) * Will use ZIP64 data if present. */ static long long -binfile_cd_offset(struct zip_cd *cd) -{ - struct zip_cd_ext *ext=binfile_cd_ext(cd); - if (ext) - return ext->zipofst; - else - return cd->zipofst; +binfile_cd_offset(struct zip_cd *cd) { + struct zip_cd_ext *ext=binfile_cd_ext(cd); + if (ext) + return ext->zipofst; + else + return cd->zipofst; } static struct zip_lfh * -binfile_read_lfh(struct file *fi, long long offset) -{ - struct zip_lfh *lfh; - - lfh=(struct zip_lfh *)(file_data_read(fi,offset,sizeof(struct zip_lfh))); - if (lfh) { - lfh_to_cpu(lfh); - if (lfh->ziplocsig != zip_lfh_sig) { - file_data_free(fi,(unsigned char *)lfh); - lfh=NULL; - } - } - return lfh; +binfile_read_lfh(struct file *fi, long long offset) { + struct zip_lfh *lfh; + + lfh=(struct zip_lfh *)(file_data_read(fi,offset,sizeof(struct zip_lfh))); + if (lfh) { + lfh_to_cpu(lfh); + if (lfh->ziplocsig != zip_lfh_sig) { + file_data_free(fi,(unsigned char *)lfh); + lfh=NULL; + } + } + return lfh; } static unsigned char * -binfile_read_content(struct map_priv *m, struct file *fi, long long offset, struct zip_lfh *lfh) -{ - unsigned char *ret=NULL; - - offset+=sizeof(struct zip_lfh)+lfh->zipfnln; - switch (lfh->zipmthd) { - case 0: - offset+=lfh->zipxtraln; - ret=file_data_read(fi,offset, lfh->zipuncmp); - break; - case 8: - offset+=lfh->zipxtraln; - ret=file_data_read_compressed(fi,offset, lfh->zipsize, lfh->zipuncmp); - break; - default: - dbg(lvl_error,"map file %s: unknown compression method %d", fi->name, lfh->zipmthd); - } - return ret; +binfile_read_content(struct map_priv *m, struct file *fi, long long offset, struct zip_lfh *lfh) { + unsigned char *ret=NULL; + + offset+=sizeof(struct zip_lfh)+lfh->zipfnln; + switch (lfh->zipmthd) { + case 0: + offset+=lfh->zipxtraln; + ret=file_data_read(fi,offset, lfh->zipuncmp); + break; + case 8: + offset+=lfh->zipxtraln; + ret=file_data_read_compressed(fi,offset, lfh->zipsize, lfh->zipuncmp); + break; + default: + dbg(lvl_error,"map file %s: unknown compression method %d", fi->name, lfh->zipmthd); + } + return ret; } static int -binfile_search_cd(struct map_priv *m, int offset, char *name, int partial, int skip) -{ - int size=4096; - int end=m->eoc64?m->eoc64->zip64ecsz:m->eoc->zipecsz; - int len=strlen(name); - long long cdoffset=m->eoc64?m->eoc64->zip64eofst:m->eoc->zipeofst; - struct zip_cd *cd; +binfile_search_cd(struct map_priv *m, int offset, char *name, int partial, int skip) { + int size=4096; + int end=m->eoc64?m->eoc64->zip64ecsz:m->eoc->zipecsz; + int len=strlen(name); + long long cdoffset=m->eoc64?m->eoc64->zip64eofst:m->eoc->zipeofst; + struct zip_cd *cd; #if 0 - dbg(lvl_debug,"end=%d",end); + dbg(lvl_debug,"end=%d",end); #endif - while (offset < end) { - cd=(struct zip_cd *)(m->search_data+offset-m->search_offset); - if (! m->search_data || - m->search_offset > offset || - offset-m->search_offset+sizeof(*cd) > m->search_size || - offset-m->search_offset+sizeof(*cd)+cd->zipcfnl+cd->zipcxtl > m->search_size - ) { + while (offset < end) { + cd=(struct zip_cd *)(m->search_data+offset-m->search_offset); + if (! m->search_data || + m->search_offset > offset || + offset-m->search_offset+sizeof(*cd) > m->search_size || + offset-m->search_offset+sizeof(*cd)+cd->zipcfnl+cd->zipcxtl > m->search_size + ) { #if 0 - dbg(lvl_debug,"reload %p %d %d", m->search_data, m->search_offset, offset); + dbg(lvl_debug,"reload %p %d %d", m->search_data, m->search_offset, offset); #endif - if (m->search_data) - file_data_free(m->fi,m->search_data); - m->search_offset=offset; - m->search_size=end-offset; - if (m->search_size > size) - m->search_size=size; - m->search_data=file_data_read(m->fi,cdoffset+m->search_offset,m->search_size); - cd=(struct zip_cd *)m->search_data; - } + if (m->search_data) + file_data_free(m->fi,m->search_data); + m->search_offset=offset; + m->search_size=end-offset; + if (m->search_size > size) + m->search_size=size; + m->search_data=file_data_read(m->fi,cdoffset+m->search_offset,m->search_size); + cd=(struct zip_cd *)m->search_data; + } #if 0 - dbg(lvl_debug,"offset=%d search_offset=%d search_size=%d search_data=%p cd=%p", offset, m->search_offset, m->search_size, m->search_data, cd); - dbg(lvl_debug,"offset=%d fn='%s'",offset,cd->zipcfn); + dbg(lvl_debug,"offset=%d search_offset=%d search_size=%d search_data=%p cd=%p", offset, m->search_offset, + m->search_size, m->search_data, cd); + dbg(lvl_debug,"offset=%d fn='%s'",offset,cd->zipcfn); #endif - if (!skip && - (partial || cd->zipcfnl == len) && - !strncmp(cd->zipcfn, name, len)) - return offset; - skip=0; - offset+=sizeof(*cd)+cd->zipcfnl+cd->zipcxtl+cd->zipccml; -; - } - return -1; + if (!skip && + (partial || cd->zipcfnl == len) && + !strncmp(cd->zipcfn, name, len)) + return offset; + skip=0; + offset+=sizeof(*cd)+cd->zipcfnl+cd->zipcxtl+cd->zipccml; + ; + } + return -1; } static void -map_destroy_binfile(struct map_priv *m) -{ - dbg(lvl_debug,"map_destroy_binfile"); - if (m->fi) - map_binfile_close(m); - map_binfile_destroy(m); +map_destroy_binfile(struct map_priv *m) { + dbg(lvl_debug,"map_destroy_binfile"); + if (m->fi) + map_binfile_close(m); + map_binfile_destroy(m); } static void -binfile_coord_rewind(void *priv_data) -{ - struct map_rect_priv *mr=priv_data; - struct tile *t=mr->t; - t->pos_coord=t->pos_coord_start; +binfile_coord_rewind(void *priv_data) { + struct map_rect_priv *mr=priv_data; + struct tile *t=mr->t; + t->pos_coord=t->pos_coord_start; } static inline int -binfile_coord_left(void *priv_data) -{ - struct map_rect_priv *mr=priv_data; - struct tile *t=mr->t; - return (t->pos_attr_start-t->pos_coord)/2; +binfile_coord_left(void *priv_data) { + struct map_rect_priv *mr=priv_data; + struct tile *t=mr->t; + return (t->pos_attr_start-t->pos_coord)/2; } static int -binfile_coord_get(void *priv_data, struct coord *c, int count) -{ - struct map_rect_priv *mr=priv_data; - struct tile *t=mr->t; - int max,ret=0; - max=binfile_coord_left(priv_data); - if (count > max) - count=max; +binfile_coord_get(void *priv_data, struct coord *c, int count) { + struct map_rect_priv *mr=priv_data; + struct tile *t=mr->t; + int max,ret=0; + max=binfile_coord_left(priv_data); + if (count > max) + count=max; #if __BYTE_ORDER == __LITTLE_ENDIAN - memcpy(c, t->pos_coord, count*sizeof(struct coord)); + memcpy(c, t->pos_coord, count*sizeof(struct coord)); #else - { - int i=0,end=count*sizeof(struct coord)/sizeof(int); - int *src=(int *)t->pos_coord; - int *dst=(int *)c; - while (i++ < end) { - *dst++=le32_to_cpu(*src); - src++; - } - } + { + int i=0,end=count*sizeof(struct coord)/sizeof(int); + int *src=(int *)t->pos_coord; + int *dst=(int *)c; + while (i++ < end) { + *dst++=le32_to_cpu(*src); + src++; + } + } #endif - t->pos_coord+=count*2; - ret=count; - return ret; + t->pos_coord+=count*2; + ret=count; + return ret; } /** @@ -483,1688 +472,1632 @@ binfile_coord_get(void *priv_data, struct coord *c, int count) * @return */ static void -binfile_attr_rewind(void *priv_data) -{ - struct map_rect_priv *mr=priv_data; - struct tile *t=mr->t; - t->pos_attr=t->pos_attr_start; - mr->label=0; - memset(mr->label_attr, 0, sizeof(mr->label_attr)); +binfile_attr_rewind(void *priv_data) { + struct map_rect_priv *mr=priv_data; + struct tile *t=mr->t; + t->pos_attr=t->pos_attr_start; + mr->label=0; + memset(mr->label_attr, 0, sizeof(mr->label_attr)); } static char * -binfile_extract(struct map_priv *m, char *dir, char *filename, int partial) -{ - char *full,*fulld,*sep; - unsigned char *start; - int len,offset=m->index_offset; - struct zip_cd *cd; - struct zip_lfh *lfh; - FILE *f; - - for (;;) { - offset=binfile_search_cd(m, offset, filename, partial, 1); - if (offset == -1) - break; - cd=binfile_read_cd(m, offset, -1); - len=strlen(dir)+1+cd->zipcfnl+1; - full=g_malloc(len); - strcpy(full,dir); - strcpy(full+strlen(full),"/"); - strncpy(full+strlen(full),cd->zipcfn,cd->zipcfnl); - full[len-1]='\0'; - fulld=g_strdup(full); - sep=strrchr(fulld, '/'); - if (sep) { - *sep='\0'; - file_mkdir(fulld, 1); - } - if (full[len-2] != '/') { - lfh=binfile_read_lfh(m->fi, binfile_cd_offset(cd)); - start=binfile_read_content(m, m->fi, binfile_cd_offset(cd), lfh); - dbg(lvl_debug,"fopen '%s'", full); - f=fopen(full,"w"); - fwrite(start, lfh->zipuncmp, 1, f); - fclose(f); - file_data_free(m->fi, start); - file_data_free(m->fi, (unsigned char *)lfh); - } - file_data_free(m->fi, (unsigned char *)cd); - g_free(fulld); - g_free(full); - if (! partial) - break; - } - - return g_strdup_printf("%s/%s",dir,filename); +binfile_extract(struct map_priv *m, char *dir, char *filename, int partial) { + char *full,*fulld,*sep; + unsigned char *start; + int len,offset=m->index_offset; + struct zip_cd *cd; + struct zip_lfh *lfh; + FILE *f; + + for (;;) { + offset=binfile_search_cd(m, offset, filename, partial, 1); + if (offset == -1) + break; + cd=binfile_read_cd(m, offset, -1); + len=strlen(dir)+1+cd->zipcfnl+1; + full=g_malloc(len); + strcpy(full,dir); + strcpy(full+strlen(full),"/"); + strncpy(full+strlen(full),cd->zipcfn,cd->zipcfnl); + full[len-1]='\0'; + fulld=g_strdup(full); + sep=strrchr(fulld, '/'); + if (sep) { + *sep='\0'; + file_mkdir(fulld, 1); + } + if (full[len-2] != '/') { + lfh=binfile_read_lfh(m->fi, binfile_cd_offset(cd)); + start=binfile_read_content(m, m->fi, binfile_cd_offset(cd), lfh); + dbg(lvl_debug,"fopen '%s'", full); + f=fopen(full,"w"); + fwrite(start, lfh->zipuncmp, 1, f); + fclose(f); + file_data_free(m->fi, start); + file_data_free(m->fi, (unsigned char *)lfh); + } + file_data_free(m->fi, (unsigned char *)cd); + g_free(fulld); + g_free(full); + if (! partial) + break; + } + + return g_strdup_printf("%s/%s",dir,filename); } static int -binfile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct map_rect_priv *mr=priv_data; - struct tile *t=mr->t; - enum attr_type type; - int i,size; - - if (attr_type != mr->attr_last) { - t->pos_attr=t->pos_attr_start; - mr->attr_last=attr_type; - } - while (t->pos_attr < t->pos_next) { - size=le32_to_cpu(*(t->pos_attr++)); - type=le32_to_cpu(t->pos_attr[0]); - if (type == attr_label) - mr->label=1; - if (type == attr_house_number) - mr->label_attr[0]=t->pos_attr; - if (type == attr_street_name) - mr->label_attr[1]=t->pos_attr; - if (type == attr_street_name_systematic) - mr->label_attr[2]=t->pos_attr; - if (type == attr_district_name && mr->item.type < type_line) - mr->label_attr[3]=t->pos_attr; - if (type == attr_town_name && mr->item.type < type_line) - mr->label_attr[4]=t->pos_attr; - if (type == attr_type || attr_type == attr_any) { - if (attr_type == attr_any) { - dbg(lvl_debug,"pos %p attr %s size %d", t->pos_attr-1, attr_to_name(type), size); - } - attr->type=type; - if (ATTR_IS_GROUP(type)) { - int i=0; - int *subpos=t->pos_attr+1; - int size_rem=size-1; - i=0; - while (size_rem > 0 && i < 7) { - int subsize=le32_to_cpu(*subpos++); - int subtype=le32_to_cpu(subpos[0]); - mr->attrs[i].type=subtype; - attr_data_set_le(&mr->attrs[i], subpos+1); - subpos+=subsize; - size_rem-=subsize+1; - i++; - } - mr->attrs[i].type=type_none; - mr->attrs[i].u.data=NULL; - attr->u.attrs=mr->attrs; - } else { - attr_data_set_le(attr, t->pos_attr+1); - if (type == attr_url_local) { - g_free(mr->url); - mr->url=binfile_extract(mr->m, mr->m->cachedir, attr->u.str, 1); - attr->u.str=mr->url; - } - if (type == attr_flags && mr->m->map_version < 1) - attr->u.num |= AF_CAR; - } - t->pos_attr+=size; - return 1; - } else { - t->pos_attr+=size; - } - } - if (!mr->label && (attr_type == attr_any || attr_type == attr_label)) { - for (i = 0 ; i < sizeof(mr->label_attr)/sizeof(int *) ; i++) { - if (mr->label_attr[i]) { - mr->label=1; - attr->type=attr_label; - attr_data_set_le(attr,mr->label_attr[i]+1); - return 1; - } - } - } - return 0; +binfile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct map_rect_priv *mr=priv_data; + struct tile *t=mr->t; + enum attr_type type; + int i,size; + + if (attr_type != mr->attr_last) { + t->pos_attr=t->pos_attr_start; + mr->attr_last=attr_type; + } + while (t->pos_attr < t->pos_next) { + size=le32_to_cpu(*(t->pos_attr++)); + type=le32_to_cpu(t->pos_attr[0]); + if (type == attr_label) + mr->label=1; + if (type == attr_house_number) + mr->label_attr[0]=t->pos_attr; + if (type == attr_street_name) + mr->label_attr[1]=t->pos_attr; + if (type == attr_street_name_systematic) + mr->label_attr[2]=t->pos_attr; + if (type == attr_district_name && mr->item.type < type_line) + mr->label_attr[3]=t->pos_attr; + if (type == attr_town_name && mr->item.type < type_line) + mr->label_attr[4]=t->pos_attr; + if (type == attr_type || attr_type == attr_any) { + if (attr_type == attr_any) { + dbg(lvl_debug,"pos %p attr %s size %d", t->pos_attr-1, attr_to_name(type), size); + } + attr->type=type; + if (ATTR_IS_GROUP(type)) { + int i=0; + int *subpos=t->pos_attr+1; + int size_rem=size-1; + i=0; + while (size_rem > 0 && i < 7) { + int subsize=le32_to_cpu(*subpos++); + int subtype=le32_to_cpu(subpos[0]); + mr->attrs[i].type=subtype; + attr_data_set_le(&mr->attrs[i], subpos+1); + subpos+=subsize; + size_rem-=subsize+1; + i++; + } + mr->attrs[i].type=type_none; + mr->attrs[i].u.data=NULL; + attr->u.attrs=mr->attrs; + } else { + attr_data_set_le(attr, t->pos_attr+1); + if (type == attr_url_local) { + g_free(mr->url); + mr->url=binfile_extract(mr->m, mr->m->cachedir, attr->u.str, 1); + attr->u.str=mr->url; + } + if (type == attr_flags && mr->m->map_version < 1) + attr->u.num |= AF_CAR; + } + t->pos_attr+=size; + return 1; + } else { + t->pos_attr+=size; + } + } + if (!mr->label && (attr_type == attr_any || attr_type == attr_label)) { + for (i = 0 ; i < sizeof(mr->label_attr)/sizeof(int *) ; i++) { + if (mr->label_attr[i]) { + mr->label=1; + attr->type=attr_label; + attr_data_set_le(attr,mr->label_attr[i]+1); + return 1; + } + } + } + return 0; } struct binfile_hash_entry { - struct item_id id; - int flags; - int data[0]; + struct item_id id; + int flags; + int data[0]; }; static guint -binfile_hash_entry_hash(gconstpointer key) -{ - const struct binfile_hash_entry *entry=key; - return (entry->id.id_hi ^ entry->id.id_lo); +binfile_hash_entry_hash(gconstpointer key) { + const struct binfile_hash_entry *entry=key; + return (entry->id.id_hi ^ entry->id.id_lo); } static gboolean -binfile_hash_entry_equal(gconstpointer a, gconstpointer b) -{ - const struct binfile_hash_entry *entry1=a,*entry2=b; - return (entry1->id.id_hi==entry2->id.id_hi && entry1->id.id_lo == entry2->id.id_lo); +binfile_hash_entry_equal(gconstpointer a, gconstpointer b) { + const struct binfile_hash_entry *entry1=a,*entry2=b; + return (entry1->id.id_hi==entry2->id.id_hi && entry1->id.id_lo == entry2->id.id_lo); } static int * -binfile_item_dup(struct map_priv *m, struct item *item, struct tile *t, int extend) -{ - int size=le32_to_cpu(t->pos[0]); - struct binfile_hash_entry *entry=g_malloc(sizeof(struct binfile_hash_entry)+(size+1+extend)*sizeof(int)); - void *ret=entry->data; - entry->id.id_hi=item->id_hi; - entry->id.id_lo=item->id_lo; - entry->flags=1; - dbg(lvl_debug,"id 0x%x,0x%x",entry->id.id_hi,entry->id.id_lo); - - memcpy(ret, t->pos, (size+1)*sizeof(int)); - if (!m->changes) - m->changes=g_hash_table_new_full(binfile_hash_entry_hash, binfile_hash_entry_equal, g_free, NULL); - g_hash_table_replace(m->changes, entry, entry); - dbg(lvl_debug,"ret %p",ret); - return ret; +binfile_item_dup(struct map_priv *m, struct item *item, struct tile *t, int extend) { + int size=le32_to_cpu(t->pos[0]); + struct binfile_hash_entry *entry=g_malloc(sizeof(struct binfile_hash_entry)+(size+1+extend)*sizeof(int)); + void *ret=entry->data; + entry->id.id_hi=item->id_hi; + entry->id.id_lo=item->id_lo; + entry->flags=1; + dbg(lvl_debug,"id 0x%x,0x%x",entry->id.id_hi,entry->id.id_lo); + + memcpy(ret, t->pos, (size+1)*sizeof(int)); + if (!m->changes) + m->changes=g_hash_table_new_full(binfile_hash_entry_hash, binfile_hash_entry_equal, g_free, NULL); + g_hash_table_replace(m->changes, entry, entry); + dbg(lvl_debug,"ret %p",ret); + return ret; } static int -binfile_coord_set(void *priv_data, struct coord *c, int count, enum change_mode mode) -{ - struct map_rect_priv *mr=priv_data; - struct tile *t=mr->t,*tn,new; - int i,delta,move_len; - int write_offset,move_offset,aoffset,coffset,clen; - int *data; - - { - int *i=t->pos,j=0; - dbg(lvl_debug,"Before: pos_coord=%td",t->pos_coord-i); - while (i < t->pos_next) - dbg(lvl_debug,"%d:0x%x",j++,*i++); - - } - aoffset=t->pos_attr-t->pos_attr_start; - coffset=t->pos_coord-t->pos_coord_start-2; - clen=t->pos_attr_start-t->pos_coord+2; - dbg(lvl_debug,"coffset=%d clen=%d",coffset,clen); - switch (mode) { - case change_mode_delete: - if (count*2 > clen) - count=clen/2; - delta=-count*2; - move_offset=coffset+count*2; - move_len=t->pos_next-t->pos_coord_start-move_offset; - write_offset=0; - break; - case change_mode_modify: - write_offset=coffset; - if (count*2 > clen) { - delta=count*2-clen; - move_offset=t->pos_attr_start-t->pos_coord_start; - move_len=t->pos_next-t->pos_coord_start-move_offset; - } else { - move_len=0; - move_offset=0; - delta=0; - } - break; - case change_mode_prepend: - delta=count*2; - move_offset=coffset-2; - move_len=t->pos_next-t->pos_coord_start-move_offset; - write_offset=coffset-2; - break; - case change_mode_append: - delta=count*2; - move_offset=coffset; - move_len=t->pos_next-t->pos_coord_start-move_offset; - write_offset=coffset; - break; - default: - return 0; - } - dbg(lvl_debug,"delta %d",delta); - data=binfile_item_dup(mr->m, &mr->item, t, delta > 0 ? delta:0); - data[0]=cpu_to_le32(le32_to_cpu(data[0])+delta); - data[2]=cpu_to_le32(le32_to_cpu(data[2])+delta); - new.pos=new.start=data; - new.zipfile_num=t->zipfile_num; - new.mode=2; - push_tile(mr, &new, 0, 0); - setup_pos(mr); - tn=mr->t; - tn->pos_coord=tn->pos_coord_start+coffset; - tn->pos_attr=tn->pos_attr_start+aoffset; - dbg(lvl_debug,"moving %d ints from offset %td to %td",move_len,tn->pos_coord_start+move_offset-data,tn->pos_coord_start+move_offset+delta-data); - memmove(tn->pos_coord_start+move_offset+delta, tn->pos_coord_start+move_offset, move_len*4); - { - int *i=tn->pos,j=0; - dbg(lvl_debug,"After move: pos_coord=%td",tn->pos_coord-i); - while (i < tn->pos_next) - dbg(lvl_debug,"%d:0x%x",j++,*i++); - } - if (mode != change_mode_append) - tn->pos_coord+=move_offset; - if (mode != change_mode_delete) { - dbg(lvl_debug,"writing %d ints at offset %td",count*2,write_offset+tn->pos_coord_start-data); - for (i = 0 ; i < count ; i++) { - tn->pos_coord_start[write_offset++]=c[i].x; - tn->pos_coord_start[write_offset++]=c[i].y; - } - - } - { - int *i=tn->pos,j=0; - dbg(lvl_debug,"After: pos_coord=%td",tn->pos_coord-i); - while (i < tn->pos_next) - dbg(lvl_debug,"%d:0x%x",j++,*i++); - } - return 1; +binfile_coord_set(void *priv_data, struct coord *c, int count, enum change_mode mode) { + struct map_rect_priv *mr=priv_data; + struct tile *t=mr->t,*tn,new; + int i,delta,move_len; + int write_offset,move_offset,aoffset,coffset,clen; + int *data; + + { + int *i=t->pos,j=0; + dbg(lvl_debug,"Before: pos_coord=%td",t->pos_coord-i); + while (i < t->pos_next) + dbg(lvl_debug,"%d:0x%x",j++,*i++); + + } + aoffset=t->pos_attr-t->pos_attr_start; + coffset=t->pos_coord-t->pos_coord_start-2; + clen=t->pos_attr_start-t->pos_coord+2; + dbg(lvl_debug,"coffset=%d clen=%d",coffset,clen); + switch (mode) { + case change_mode_delete: + if (count*2 > clen) + count=clen/2; + delta=-count*2; + move_offset=coffset+count*2; + move_len=t->pos_next-t->pos_coord_start-move_offset; + write_offset=0; + break; + case change_mode_modify: + write_offset=coffset; + if (count*2 > clen) { + delta=count*2-clen; + move_offset=t->pos_attr_start-t->pos_coord_start; + move_len=t->pos_next-t->pos_coord_start-move_offset; + } else { + move_len=0; + move_offset=0; + delta=0; + } + break; + case change_mode_prepend: + delta=count*2; + move_offset=coffset-2; + move_len=t->pos_next-t->pos_coord_start-move_offset; + write_offset=coffset-2; + break; + case change_mode_append: + delta=count*2; + move_offset=coffset; + move_len=t->pos_next-t->pos_coord_start-move_offset; + write_offset=coffset; + break; + default: + return 0; + } + dbg(lvl_debug,"delta %d",delta); + data=binfile_item_dup(mr->m, &mr->item, t, delta > 0 ? delta:0); + data[0]=cpu_to_le32(le32_to_cpu(data[0])+delta); + data[2]=cpu_to_le32(le32_to_cpu(data[2])+delta); + new.pos=new.start=data; + new.zipfile_num=t->zipfile_num; + new.mode=2; + push_tile(mr, &new, 0, 0); + setup_pos(mr); + tn=mr->t; + tn->pos_coord=tn->pos_coord_start+coffset; + tn->pos_attr=tn->pos_attr_start+aoffset; + dbg(lvl_debug,"moving %d ints from offset %td to %td",move_len,tn->pos_coord_start+move_offset-data, + tn->pos_coord_start+move_offset+delta-data); + memmove(tn->pos_coord_start+move_offset+delta, tn->pos_coord_start+move_offset, move_len*4); + { + int *i=tn->pos,j=0; + dbg(lvl_debug,"After move: pos_coord=%td",tn->pos_coord-i); + while (i < tn->pos_next) + dbg(lvl_debug,"%d:0x%x",j++,*i++); + } + if (mode != change_mode_append) + tn->pos_coord+=move_offset; + if (mode != change_mode_delete) { + dbg(lvl_debug,"writing %d ints at offset %td",count*2,write_offset+tn->pos_coord_start-data); + for (i = 0 ; i < count ; i++) { + tn->pos_coord_start[write_offset++]=c[i].x; + tn->pos_coord_start[write_offset++]=c[i].y; + } + + } + { + int *i=tn->pos,j=0; + dbg(lvl_debug,"After: pos_coord=%td",tn->pos_coord-i); + while (i < tn->pos_next) + dbg(lvl_debug,"%d:0x%x",j++,*i++); + } + return 1; } static int -binfile_attr_set(void *priv_data, struct attr *attr, enum change_mode mode) -{ - struct map_rect_priv *mr=priv_data; - struct tile *t=mr->t,*tn,new; - int offset,delta,move_len; - int write_offset,move_offset,naoffset,coffset,oattr_len; - int nattr_size,nattr_len,pad; - int *data; - - { - int *i=t->pos,j=0; - dbg(lvl_debug,"Before: pos_attr=%td",t->pos_attr-i); - while (i < t->pos_next) - dbg(lvl_debug,"%d:0x%x",j++,*i++); - - } - - write_offset=0; - naoffset=t->pos_attr-t->pos_attr_start; - coffset=t->pos_coord-t->pos_coord_start; - offset=0; - oattr_len=0; - if (!naoffset) { - if (mode == change_mode_delete || mode == change_mode_modify) { - dbg(lvl_error,"no attribute selected"); - return 0; - } - if (mode == change_mode_append) - naoffset=t->pos_next-t->pos_attr_start; - } - while (offset < naoffset) { - oattr_len=le32_to_cpu(t->pos_attr_start[offset])+1; - dbg(lvl_debug,"len %d",oattr_len); - write_offset=offset; - offset+=oattr_len; - } - move_len=t->pos_next-t->pos_attr_start-offset; - move_offset=offset; - switch (mode) { - case change_mode_delete: - nattr_size=0; - nattr_len=0; - pad=0; - break; - case change_mode_modify: - case change_mode_prepend: - case change_mode_append: - nattr_size=attr_data_size(attr); - pad=(4-(nattr_size%4))%4; - nattr_len=(nattr_size+pad)/4+2; - if (mode == change_mode_prepend) { - move_offset=write_offset; - move_len+=oattr_len; - } - if (mode == change_mode_append) { - write_offset=move_offset; - } - break; - default: - return 0; - } - if (mode == change_mode_delete || mode == change_mode_modify) - delta=nattr_len-oattr_len; - else - delta=nattr_len; - dbg(lvl_debug,"delta %d oattr_len %d nattr_len %d",delta,oattr_len, nattr_len); - data=binfile_item_dup(mr->m, &mr->item, t, delta > 0 ? delta:0); - data[0]=cpu_to_le32(le32_to_cpu(data[0])+delta); - new.pos=new.start=data; - new.zipfile_num=t->zipfile_num; - new.mode=2; - push_tile(mr, &new, 0, 0); - setup_pos(mr); - tn=mr->t; - tn->pos_coord=tn->pos_coord_start+coffset; - tn->pos_attr=tn->pos_attr_start+offset; - dbg(lvl_debug,"attr start %td offset %d",tn->pos_attr_start-data,offset); - dbg(lvl_debug,"moving %d ints from offset %td to %td",move_len,tn->pos_attr_start+move_offset-data,tn->pos_attr_start+move_offset+delta-data); - memmove(tn->pos_attr_start+move_offset+delta, tn->pos_attr_start+move_offset, move_len*4); - if (mode != change_mode_append) - tn->pos_attr+=delta; - { - int *i=tn->pos,j=0; - dbg(lvl_debug,"After move: pos_attr=%td",tn->pos_attr-i); - while (i < tn->pos_next) - dbg(lvl_debug,"%d:0x%x",j++,*i++); - } - if (nattr_len) { - int *nattr=tn->pos_attr_start+write_offset; - dbg(lvl_debug,"writing %d ints at %td",nattr_len,nattr-data); - nattr[0]=cpu_to_le32(nattr_len-1); - nattr[1]=cpu_to_le32(attr->type); - memcpy(nattr+2, attr_data_get(attr), nattr_size); - memset((unsigned char *)(nattr+2)+nattr_size, 0, pad); - } - { - int *i=tn->pos,j=0; - dbg(lvl_debug,"After: pos_attr=%td",tn->pos_attr-i); - while (i < tn->pos_next) - dbg(lvl_debug,"After: pos_attr=%td",tn->pos_attr-i); - while (i < tn->pos_next) - dbg(lvl_debug,"%d:0x%x",j++,*i++); - } - return 1; +binfile_attr_set(void *priv_data, struct attr *attr, enum change_mode mode) { + struct map_rect_priv *mr=priv_data; + struct tile *t=mr->t,*tn,new; + int offset,delta,move_len; + int write_offset,move_offset,naoffset,coffset,oattr_len; + int nattr_size,nattr_len,pad; + int *data; + + { + int *i=t->pos,j=0; + dbg(lvl_debug,"Before: pos_attr=%td",t->pos_attr-i); + while (i < t->pos_next) + dbg(lvl_debug,"%d:0x%x",j++,*i++); + + } + + write_offset=0; + naoffset=t->pos_attr-t->pos_attr_start; + coffset=t->pos_coord-t->pos_coord_start; + offset=0; + oattr_len=0; + if (!naoffset) { + if (mode == change_mode_delete || mode == change_mode_modify) { + dbg(lvl_error,"no attribute selected"); + return 0; + } + if (mode == change_mode_append) + naoffset=t->pos_next-t->pos_attr_start; + } + while (offset < naoffset) { + oattr_len=le32_to_cpu(t->pos_attr_start[offset])+1; + dbg(lvl_debug,"len %d",oattr_len); + write_offset=offset; + offset+=oattr_len; + } + move_len=t->pos_next-t->pos_attr_start-offset; + move_offset=offset; + switch (mode) { + case change_mode_delete: + nattr_size=0; + nattr_len=0; + pad=0; + break; + case change_mode_modify: + case change_mode_prepend: + case change_mode_append: + nattr_size=attr_data_size(attr); + pad=(4-(nattr_size%4))%4; + nattr_len=(nattr_size+pad)/4+2; + if (mode == change_mode_prepend) { + move_offset=write_offset; + move_len+=oattr_len; + } + if (mode == change_mode_append) { + write_offset=move_offset; + } + break; + default: + return 0; + } + if (mode == change_mode_delete || mode == change_mode_modify) + delta=nattr_len-oattr_len; + else + delta=nattr_len; + dbg(lvl_debug,"delta %d oattr_len %d nattr_len %d",delta,oattr_len, nattr_len); + data=binfile_item_dup(mr->m, &mr->item, t, delta > 0 ? delta:0); + data[0]=cpu_to_le32(le32_to_cpu(data[0])+delta); + new.pos=new.start=data; + new.zipfile_num=t->zipfile_num; + new.mode=2; + push_tile(mr, &new, 0, 0); + setup_pos(mr); + tn=mr->t; + tn->pos_coord=tn->pos_coord_start+coffset; + tn->pos_attr=tn->pos_attr_start+offset; + dbg(lvl_debug,"attr start %td offset %d",tn->pos_attr_start-data,offset); + dbg(lvl_debug,"moving %d ints from offset %td to %td",move_len,tn->pos_attr_start+move_offset-data, + tn->pos_attr_start+move_offset+delta-data); + memmove(tn->pos_attr_start+move_offset+delta, tn->pos_attr_start+move_offset, move_len*4); + if (mode != change_mode_append) + tn->pos_attr+=delta; + { + int *i=tn->pos,j=0; + dbg(lvl_debug,"After move: pos_attr=%td",tn->pos_attr-i); + while (i < tn->pos_next) + dbg(lvl_debug,"%d:0x%x",j++,*i++); + } + if (nattr_len) { + int *nattr=tn->pos_attr_start+write_offset; + dbg(lvl_debug,"writing %d ints at %td",nattr_len,nattr-data); + nattr[0]=cpu_to_le32(nattr_len-1); + nattr[1]=cpu_to_le32(attr->type); + memcpy(nattr+2, attr_data_get(attr), nattr_size); + memset((unsigned char *)(nattr+2)+nattr_size, 0, pad); + } + { + int *i=tn->pos,j=0; + dbg(lvl_debug,"After: pos_attr=%td",tn->pos_attr-i); + while (i < tn->pos_next) + dbg(lvl_debug,"After: pos_attr=%td",tn->pos_attr-i); + while (i < tn->pos_next) + dbg(lvl_debug,"%d:0x%x",j++,*i++); + } + return 1; } static struct item_methods methods_binfile = { - binfile_coord_rewind, - binfile_coord_get, - binfile_attr_rewind, - binfile_attr_get, - NULL, - binfile_attr_set, - binfile_coord_set, + binfile_coord_rewind, + binfile_coord_get, + binfile_attr_rewind, + binfile_attr_get, + NULL, + binfile_attr_set, + binfile_coord_set, }; static void -push_tile(struct map_rect_priv *mr, struct tile *t, int offset, int length) -{ - dbg_assert(mr->tile_depth < 8); - mr->t=&mr->tiles[mr->tile_depth++]; - *(mr->t)=*t; - mr->t->pos=mr->t->pos_next=mr->t->start+offset; - if (length == -1) - length=le32_to_cpu(mr->t->pos[0])+1; - if (length > 0) - mr->t->end=mr->t->pos+length; +push_tile(struct map_rect_priv *mr, struct tile *t, int offset, int length) { + dbg_assert(mr->tile_depth < 8); + mr->t=&mr->tiles[mr->tile_depth++]; + *(mr->t)=*t; + mr->t->pos=mr->t->pos_next=mr->t->start+offset; + if (length == -1) + length=le32_to_cpu(mr->t->pos[0])+1; + if (length > 0) + mr->t->end=mr->t->pos+length; } static int -pop_tile(struct map_rect_priv *mr) -{ - if (mr->tile_depth <= 1) - return 0; - if (mr->t->mode < 2) - file_data_free(mr->m->fi, (unsigned char *)(mr->t->start)); +pop_tile(struct map_rect_priv *mr) { + if (mr->tile_depth <= 1) + return 0; + if (mr->t->mode < 2) + file_data_free(mr->m->fi, (unsigned char *)(mr->t->start)); #ifdef DEBUG_SIZE #if DEBUG_SIZE > 0 - dbg(lvl_debug,"leave %d",mr->t->zipfile_num); + dbg(lvl_debug,"leave %d",mr->t->zipfile_num); #endif #endif - mr->t=&mr->tiles[--mr->tile_depth-1]; - return 1; + mr->t=&mr->tiles[--mr->tile_depth-1]; + return 1; } static int -zipfile_to_tile(struct map_priv *m, struct zip_cd *cd, struct tile *t) -{ - char buffer[1024]; - struct zip_lfh *lfh; - char *zipfn; - struct file *fi; - dbg(lvl_debug,"enter %p %p %p", m, cd, t); - dbg(lvl_debug,"cd->zipofst=0x"LONGLONG_HEX_FMT "", binfile_cd_offset(cd)); - t->start=NULL; - t->mode=1; - if (m->fis) - fi=m->fis[cd->zipdsk]; - else - fi=m->fi; - lfh=binfile_read_lfh(fi, binfile_cd_offset(cd)); - zipfn=(char *)(file_data_read(fi,binfile_cd_offset(cd)+sizeof(struct zip_lfh), lfh->zipfnln)); - strncpy(buffer, zipfn, lfh->zipfnln); - buffer[lfh->zipfnln]='\0'; - t->start=(int *)binfile_read_content(m, fi, binfile_cd_offset(cd), lfh); - t->end=t->start+lfh->zipuncmp/4; - t->fi=fi; - file_data_free(fi, (unsigned char *)zipfn); - file_data_free(fi, (unsigned char *)lfh); - return t->start != NULL; +zipfile_to_tile(struct map_priv *m, struct zip_cd *cd, struct tile *t) { + char buffer[1024]; + struct zip_lfh *lfh; + char *zipfn; + struct file *fi; + dbg(lvl_debug,"enter %p %p %p", m, cd, t); + dbg(lvl_debug,"cd->zipofst=0x"LONGLONG_HEX_FMT "", binfile_cd_offset(cd)); + t->start=NULL; + t->mode=1; + if (m->fis) + fi=m->fis[cd->zipdsk]; + else + fi=m->fi; + lfh=binfile_read_lfh(fi, binfile_cd_offset(cd)); + zipfn=(char *)(file_data_read(fi,binfile_cd_offset(cd)+sizeof(struct zip_lfh), lfh->zipfnln)); + strncpy(buffer, zipfn, lfh->zipfnln); + buffer[lfh->zipfnln]='\0'; + t->start=(int *)binfile_read_content(m, fi, binfile_cd_offset(cd), lfh); + t->end=t->start+lfh->zipuncmp/4; + t->fi=fi; + file_data_free(fi, (unsigned char *)zipfn); + file_data_free(fi, (unsigned char *)lfh); + return t->start != NULL; } static int -map_binfile_handle_redirect(struct map_priv *m) -{ - char *location=file_http_header(m->http, "location"); - if (!location) { - m->redirect=0; - return 0; - } - if (m->redirect) - return 0; - m->redirect=1; - dbg(lvl_debug,"redirected from %s to %s",m->url,location); - g_free(m->url); - m->url=g_strdup(location); - file_destroy(m->http); - m->http=NULL; - - return 1; +map_binfile_handle_redirect(struct map_priv *m) { + char *location=file_http_header(m->http, "location"); + if (!location) { + m->redirect=0; + return 0; + } + if (m->redirect) + return 0; + m->redirect=1; + dbg(lvl_debug,"redirected from %s to %s",m->url,location); + g_free(m->url); + m->url=g_strdup(location); + file_destroy(m->http); + m->http=NULL; + + return 1; } static int -map_binfile_http_request(struct map_priv *m, struct attr **attrs) -{ - if (!m->http) { - m->http=file_create(NULL, attrs); - } else { - file_request(m->http, attrs); - } - return 1; +map_binfile_http_request(struct map_priv *m, struct attr **attrs) { + if (!m->http) { + m->http=file_create(NULL, attrs); + } else { + file_request(m->http, attrs); + } + return 1; } static long long -map_binfile_download_size(struct map_priv *m) -{ - struct attr url={attr_url}; - struct attr http_method={attr_http_method}; - struct attr persistent={attr_persistent}; - struct attr *attrs[4]; - int size_ret; - long long ret; - void *data; - - do { - attrs[0]=&url; - url.u.str=m->url; - attrs[1]=&http_method; - http_method.u.str="HEAD"; - persistent.u.num=1; - attrs[2]=&persistent; - attrs[3]=NULL; - - map_binfile_http_request(m, attrs); - data=file_data_read_special(m->http, 0, &size_ret); - g_free(data); - if (size_ret < 0) - return 0; - } while (map_binfile_handle_redirect(m)); - - ret=file_size(m->http); - dbg(lvl_debug,"file size "LONGLONG_FMT"",ret); - return ret; +map_binfile_download_size(struct map_priv *m) { + struct attr url= {attr_url}; + struct attr http_method= {attr_http_method}; + struct attr persistent= {attr_persistent}; + struct attr *attrs[4]; + int size_ret; + long long ret; + void *data; + + do { + attrs[0]=&url; + url.u.str=m->url; + attrs[1]=&http_method; + http_method.u.str="HEAD"; + persistent.u.num=1; + attrs[2]=&persistent; + attrs[3]=NULL; + + map_binfile_http_request(m, attrs); + data=file_data_read_special(m->http, 0, &size_ret); + g_free(data); + if (size_ret < 0) + return 0; + } while (map_binfile_handle_redirect(m)); + + ret=file_size(m->http); + dbg(lvl_debug,"file size "LONGLONG_FMT"",ret); + return ret; } static int -map_binfile_http_close(struct map_priv *m) -{ - if (m->http) { - file_destroy(m->http); - m->http=NULL; - } - return 1; +map_binfile_http_close(struct map_priv *m) { + if (m->http) { + file_destroy(m->http); + m->http=NULL; + } + return 1; } static struct file * -map_binfile_http_range(struct map_priv *m, long long offset, int size) -{ - struct attr *attrs[4]; - struct attr url={attr_url}; - struct attr http_header={attr_http_header}; - struct attr persistent={attr_persistent}; +map_binfile_http_range(struct map_priv *m, long long offset, int size) { + struct attr *attrs[4]; + struct attr url= {attr_url}; + struct attr http_header= {attr_http_header}; + struct attr persistent= {attr_persistent}; - persistent.u.num=1; - attrs[0]=&url; - attrs[1]=&http_header; - attrs[2]=&persistent; - attrs[3]=NULL; + persistent.u.num=1; + attrs[0]=&url; + attrs[1]=&http_header; + attrs[2]=&persistent; + attrs[3]=NULL; - url.u.str=m->url; - http_header.u.str=g_strdup_printf("Range: bytes="LONGLONG_FMT"-"LONGLONG_FMT,offset, offset+size-1); - map_binfile_http_request(m, attrs); - g_free(http_header.u.str); - return m->http; + url.u.str=m->url; + http_header.u.str=g_strdup_printf("Range: bytes="LONGLONG_FMT"-"LONGLONG_FMT,offset, offset+size-1); + map_binfile_http_request(m, attrs); + g_free(http_header.u.str); + return m->http; } static unsigned char * -map_binfile_download_range(struct map_priv *m, long long offset, int size) -{ - unsigned char *ret; - int size_ret; - struct file *http=map_binfile_http_range(m, offset, size); +map_binfile_download_range(struct map_priv *m, long long offset, int size) { + unsigned char *ret; + int size_ret; + struct file *http=map_binfile_http_range(m, offset, size); - ret=file_data_read_special(http, size, &size_ret); - if (size_ret != size) { - dbg(lvl_debug,"size %d vs %d",size,size_ret); - g_free(ret); - return NULL; - } - return ret; + ret=file_data_read_special(http, size, &size_ret); + if (size_ret != size) { + dbg(lvl_debug,"size %d vs %d",size,size_ret); + g_free(ret); + return NULL; + } + return ret; } static struct zip_cd * -download_cd(struct map_download *download) -{ - struct map_priv *m=download->m; - struct zip64_eoc *zip64_eoc=(struct zip64_eoc *)file_data_read(m->fi, 0, sizeof(*zip64_eoc)); - struct zip_cd *cd=(struct zip_cd *)map_binfile_download_range(m, zip64_eoc->zip64eofst+download->zipfile*m->cde_size,m->cde_size); - file_data_free(m->fi, (unsigned char *)zip64_eoc); - dbg(lvl_debug,"needed cd, result %p",cd); - return cd; +download_cd(struct map_download *download) { + struct map_priv *m=download->m; + struct zip64_eoc *zip64_eoc=(struct zip64_eoc *)file_data_read(m->fi, 0, sizeof(*zip64_eoc)); + struct zip_cd *cd=(struct zip_cd *)map_binfile_download_range(m, zip64_eoc->zip64eofst+download->zipfile*m->cde_size, + m->cde_size); + file_data_free(m->fi, (unsigned char *)zip64_eoc); + dbg(lvl_debug,"needed cd, result %p",cd); + return cd; } static int -download_request(struct map_download *download) -{ - struct attr url={attr_url}; - struct attr http_header={attr_http_header}; - struct attr persistent={attr_persistent}; - struct attr *attrs[4]; - - if(!download->m->download_enabled) - { - dbg(lvl_error,"Tried downloading while it's not allowed"); - return 0; - } - attrs[0]=&url; - persistent.u.num=1; - attrs[1]=&persistent; - attrs[2]=NULL; - if (strchr(download->m->url,'?')) { - url.u.str=g_strdup_printf("%smemberid=%d",download->m->url,download->zipfile); - download->dl_size=-1; - } else { - long long offset=binfile_cd_offset(download->cd_copy); - int size=download->cd_copy->zipcsiz+sizeof(struct zip_lfh)+download->cd_copy->zipcfnl; - url.u.str=g_strdup(download->m->url); - http_header.u.str=g_strdup_printf("Range: bytes="LONGLONG_FMT"-"LONGLONG_FMT,offset,offset+size-1); - attrs[2]=&http_header; - attrs[3]=NULL; - download->dl_size=size; - } - dbg(lvl_debug,"encountered missing tile %d %s(%s), Downloading %d bytes at "LONGLONG_FMT"",download->zipfile, url.u.str,(char *)(download->cd_copy+1), download->dl_size, download->offset); - map_binfile_http_request(download->m, attrs); - g_free(url.u.str); - download->http=download->m->http; - return 1; +download_request(struct map_download *download) { + struct attr url= {attr_url}; + struct attr http_header= {attr_http_header}; + struct attr persistent= {attr_persistent}; + struct attr *attrs[4]; + + if(!download->m->download_enabled) { + dbg(lvl_error,"Tried downloading while it's not allowed"); + return 0; + } + attrs[0]=&url; + persistent.u.num=1; + attrs[1]=&persistent; + attrs[2]=NULL; + if (strchr(download->m->url,'?')) { + url.u.str=g_strdup_printf("%smemberid=%d",download->m->url,download->zipfile); + download->dl_size=-1; + } else { + long long offset=binfile_cd_offset(download->cd_copy); + int size=download->cd_copy->zipcsiz+sizeof(struct zip_lfh)+download->cd_copy->zipcfnl; + url.u.str=g_strdup(download->m->url); + http_header.u.str=g_strdup_printf("Range: bytes="LONGLONG_FMT"-"LONGLONG_FMT,offset,offset+size-1); + attrs[2]=&http_header; + attrs[3]=NULL; + download->dl_size=size; + } + dbg(lvl_debug,"encountered missing tile %d %s(%s), Downloading %d bytes at "LONGLONG_FMT"",download->zipfile, url.u.str, + (char *)(download->cd_copy+1), download->dl_size, download->offset); + map_binfile_http_request(download->m, attrs); + g_free(url.u.str); + download->http=download->m->http; + return 1; } static int -download_start(struct map_download *download) -{ - long long offset; - struct zip_eoc *eoc; - - if (!download->cd->zipcensig) { - download->cd_copy=download_cd(download); - } else { - download->cd_copy=g_malloc(download->m->cde_size); - memcpy(download->cd_copy, download->cd, download->m->cde_size); - } - file_data_remove(download->file, (unsigned char *)download->cd); - download->cd=NULL; - offset=file_size(download->file); - offset-=sizeof(struct zip_eoc); - eoc=(struct zip_eoc *)file_data_read(download->file, offset, sizeof(struct zip_eoc)); - download->zip_eoc=g_malloc(sizeof(struct zip_eoc)); - memcpy(download->zip_eoc, eoc, sizeof(struct zip_eoc)); - file_data_remove(download->file, (unsigned char *)eoc); - download->start_offset=download->offset=offset; - return download_request(download); +download_start(struct map_download *download) { + long long offset; + struct zip_eoc *eoc; + + if (!download->cd->zipcensig) { + download->cd_copy=download_cd(download); + } else { + download->cd_copy=g_malloc(download->m->cde_size); + memcpy(download->cd_copy, download->cd, download->m->cde_size); + } + file_data_remove(download->file, (unsigned char *)download->cd); + download->cd=NULL; + offset=file_size(download->file); + offset-=sizeof(struct zip_eoc); + eoc=(struct zip_eoc *)file_data_read(download->file, offset, sizeof(struct zip_eoc)); + download->zip_eoc=g_malloc(sizeof(struct zip_eoc)); + memcpy(download->zip_eoc, eoc, sizeof(struct zip_eoc)); + file_data_remove(download->file, (unsigned char *)eoc); + download->start_offset=download->offset=offset; + return download_request(download); } static int -download_download(struct map_download *download) -{ - int size=64*1024,size_ret; - unsigned char *data; - if (download->dl_size != -1 && size > download->dl_size) - size=download->dl_size; - if (!size) - return 1; - data=file_data_read_special(download->http, size, &size_ret); - if (!download->read && download->m->http && map_binfile_handle_redirect(download->m)) { - g_free(data); - download_request(download); - return 0; - } - - dbg(lvl_debug,"got %d bytes writing at offset "LONGLONG_FMT"",size_ret,download->offset); - if (size_ret <= 0) { - g_free(data); - return 1; - } - file_data_write(download->file, download->offset, size_ret, data); - download->offset+=size_ret; - download->read+=size_ret; - download->dl_size-=size_ret; - if (download->dl_size != -1) - download->progress=download->read*100/(download->read+download->dl_size); - return 0; +download_download(struct map_download *download) { + int size=64*1024,size_ret; + unsigned char *data; + if (download->dl_size != -1 && size > download->dl_size) + size=download->dl_size; + if (!size) + return 1; + data=file_data_read_special(download->http, size, &size_ret); + if (!download->read && download->m->http && map_binfile_handle_redirect(download->m)) { + g_free(data); + download_request(download); + return 0; + } + + dbg(lvl_debug,"got %d bytes writing at offset "LONGLONG_FMT"",size_ret,download->offset); + if (size_ret <= 0) { + g_free(data); + return 1; + } + file_data_write(download->file, download->offset, size_ret, data); + download->offset+=size_ret; + download->read+=size_ret; + download->dl_size-=size_ret; + if (download->dl_size != -1) + download->progress=download->read*100/(download->read+download->dl_size); + return 0; } static int -download_finish(struct map_download *download) -{ - struct zip_lfh *lfh; - char *lfh_filename; - struct zip_cd_ext *ext; - long long lfh_offset; - file_data_write(download->file, download->offset, sizeof(struct zip_eoc), (void *)download->zip_eoc); - lfh=(struct zip_lfh *)(file_data_read(download->file,download->start_offset, sizeof(struct zip_lfh))); - ext=binfile_cd_ext(download->cd_copy); - if (ext) - ext->zipofst=download->start_offset; - else - download->cd_copy->zipofst=download->start_offset; - download->cd_copy->zipcsiz=lfh->zipsize; - download->cd_copy->zipcunc=lfh->zipuncmp; - download->cd_copy->zipccrc=lfh->zipcrc; - lfh_offset = binfile_cd_offset(download->cd_copy)+sizeof(struct zip_lfh); - lfh_filename=(char *)file_data_read(download->file,lfh_offset,lfh->zipfnln); - memcpy(download->cd_copy+1,lfh_filename,lfh->zipfnln); - file_data_remove(download->file,(void *)lfh_filename); - file_data_remove(download->file,(void *)lfh); - file_data_write(download->file, download->m->eoc->zipeofst + download->zipfile*download->m->cde_size, binfile_cd_extra(download->cd_copy)+sizeof(struct zip_cd), (void *)download->cd_copy); - file_data_flush(download->file, download->m->eoc->zipeofst + download->zipfile*download->m->cde_size, sizeof(struct zip_cd)); - - g_free(download->cd_copy); - download->cd=(struct zip_cd *)(file_data_read(download->file, download->m->eoc->zipeofst + download->zipfile*download->m->cde_size, download->m->cde_size)); - cd_to_cpu(download->cd); - dbg(lvl_debug,"Offset %d",download->cd->zipofst); - return 1; +download_finish(struct map_download *download) { + struct zip_lfh *lfh; + char *lfh_filename; + struct zip_cd_ext *ext; + long long lfh_offset; + file_data_write(download->file, download->offset, sizeof(struct zip_eoc), (void *)download->zip_eoc); + lfh=(struct zip_lfh *)(file_data_read(download->file,download->start_offset, sizeof(struct zip_lfh))); + ext=binfile_cd_ext(download->cd_copy); + if (ext) + ext->zipofst=download->start_offset; + else + download->cd_copy->zipofst=download->start_offset; + download->cd_copy->zipcsiz=lfh->zipsize; + download->cd_copy->zipcunc=lfh->zipuncmp; + download->cd_copy->zipccrc=lfh->zipcrc; + lfh_offset = binfile_cd_offset(download->cd_copy)+sizeof(struct zip_lfh); + lfh_filename=(char *)file_data_read(download->file,lfh_offset,lfh->zipfnln); + memcpy(download->cd_copy+1,lfh_filename,lfh->zipfnln); + file_data_remove(download->file,(void *)lfh_filename); + file_data_remove(download->file,(void *)lfh); + file_data_write(download->file, download->m->eoc->zipeofst + download->zipfile*download->m->cde_size, + binfile_cd_extra(download->cd_copy)+sizeof(struct zip_cd), (void *)download->cd_copy); + file_data_flush(download->file, download->m->eoc->zipeofst + download->zipfile*download->m->cde_size, + sizeof(struct zip_cd)); + + g_free(download->cd_copy); + download->cd=(struct zip_cd *)(file_data_read(download->file, + download->m->eoc->zipeofst + download->zipfile*download->m->cde_size, download->m->cde_size)); + cd_to_cpu(download->cd); + dbg(lvl_debug,"Offset %d",download->cd->zipofst); + return 1; } static int -download_planet_size(struct map_download *download) -{ - download->size=map_binfile_download_size(download->m); - dbg(lvl_debug,"Planet size "LONGLONG_FMT"",download->size); - if (!download->size) - return 0; - return 1; +download_planet_size(struct map_download *download) { + download->size=map_binfile_download_size(download->m); + dbg(lvl_debug,"Planet size "LONGLONG_FMT"",download->size); + if (!download->size) + return 0; + return 1; } static int -download_eoc(struct map_download *download) -{ - download->zip64_eoc=(struct zip64_eoc *)map_binfile_download_range(download->m, download->size-98, 98); - if (!download->zip64_eoc) - return 0; - download->zip64_eocl=(struct zip64_eocl *)(download->zip64_eoc+1); - download->zip_eoc=(struct zip_eoc *)(download->zip64_eocl+1); - if (download->zip64_eoc->zip64esig != zip64_eoc_sig || download->zip64_eocl->zip64lsig != zip64_eocl_sig || download->zip_eoc->zipesig != zip_eoc_sig) - { - dbg(lvl_error,"wrong signature on zip64_eoc downloaded from "LONGLONG_FMT"",download->size-98); - g_free(download->zip64_eoc); - return 0; - } - return 1; +download_eoc(struct map_download *download) { + download->zip64_eoc=(struct zip64_eoc *)map_binfile_download_range(download->m, download->size-98, 98); + if (!download->zip64_eoc) + return 0; + download->zip64_eocl=(struct zip64_eocl *)(download->zip64_eoc+1); + download->zip_eoc=(struct zip_eoc *)(download->zip64_eocl+1); + if (download->zip64_eoc->zip64esig != zip64_eoc_sig || download->zip64_eocl->zip64lsig != zip64_eocl_sig + || download->zip_eoc->zipesig != zip_eoc_sig) { + dbg(lvl_error,"wrong signature on zip64_eoc downloaded from "LONGLONG_FMT"",download->size-98); + g_free(download->zip64_eoc); + return 0; + } + return 1; } static int -download_directory_start(struct map_download *download) -{ - download->http=map_binfile_http_range(download->m, download->zip64_eoc->zip64eofst, download->zip64_eoc->zip64ecsz); - if (!download->http) - return 0; - return 1; +download_directory_start(struct map_download *download) { + download->http=map_binfile_http_range(download->m, download->zip64_eoc->zip64eofst, download->zip64_eoc->zip64ecsz); + if (!download->http) + return 0; + return 1; } static int -download_directory_do(struct map_download *download) -{ - int count; - - for (count = 0 ; count < 100 ; count++) { - int cd_xlen, size_ret; - unsigned char *cd_data; - struct zip_cd *cd; - cd=(struct zip_cd *)file_data_read_special(download->http, sizeof(*cd), &size_ret); - cd->zipcunc=0; - dbg(lvl_debug,"size_ret=%d",size_ret); - if (!size_ret) - return 0; - if (size_ret != sizeof(*cd) || cd->zipcensig != zip_cd_sig) { - dbg(lvl_error,"error1 size=%d vs %zu",size_ret, sizeof(*cd)); - return 0; - } - file_data_write(download->file, download->offset, sizeof(*cd), (unsigned char *)cd); - download->offset+=sizeof(*cd); - cd_xlen=cd->zipcfnl+cd->zipcxtl; - cd_data=file_data_read_special(download->http, cd_xlen, &size_ret); - if (size_ret != cd_xlen) { - dbg(lvl_error,"error2 size=%d vs %d",size_ret,cd_xlen); - return 0; - } - file_data_write(download->file, download->offset, cd_xlen, cd_data); - download->offset+=cd_xlen; - g_free(cd); - g_free(cd_data); - } - return 1; +download_directory_do(struct map_download *download) { + int count; + + for (count = 0 ; count < 100 ; count++) { + int cd_xlen, size_ret; + unsigned char *cd_data; + struct zip_cd *cd; + cd=(struct zip_cd *)file_data_read_special(download->http, sizeof(*cd), &size_ret); + cd->zipcunc=0; + dbg(lvl_debug,"size_ret=%d",size_ret); + if (!size_ret) + return 0; + if (size_ret != sizeof(*cd) || cd->zipcensig != zip_cd_sig) { + dbg(lvl_error,"error1 size=%d vs %zu",size_ret, sizeof(*cd)); + return 0; + } + file_data_write(download->file, download->offset, sizeof(*cd), (unsigned char *)cd); + download->offset+=sizeof(*cd); + cd_xlen=cd->zipcfnl+cd->zipcxtl; + cd_data=file_data_read_special(download->http, cd_xlen, &size_ret); + if (size_ret != cd_xlen) { + dbg(lvl_error,"error2 size=%d vs %d",size_ret,cd_xlen); + return 0; + } + file_data_write(download->file, download->offset, cd_xlen, cd_data); + download->offset+=cd_xlen; + g_free(cd); + g_free(cd_data); + } + return 1; } static int -download_directory_finish(struct map_download *download) -{ - download->http=NULL; - return 1; +download_directory_finish(struct map_download *download) { + download->http=NULL; + return 1; } static int -download_initial_finish(struct map_download *download) -{ - download->zip64_eoc->zip64eofst=download->cd1offset; - download->zip64_eocl->zip64lofst=download->offset; - download->zip_eoc->zipeofst=download->cd1offset; +download_initial_finish(struct map_download *download) { + download->zip64_eoc->zip64eofst=download->cd1offset; + download->zip64_eocl->zip64lofst=download->offset; + download->zip_eoc->zipeofst=download->cd1offset; #if 0 - file_data_write(download->file, download->offset, sizeof(*download->zip64_eoc), (unsigned char *)download->zip64_eoc); - download->offset+=sizeof(*download->zip64_eoc); - file_data_write(download->file, download->offset, sizeof(*download->zip64_eocl), (unsigned char *)download->zip64_eocl); - download->offset+=sizeof(*download->zip64_eocl); + file_data_write(download->file, download->offset, sizeof(*download->zip64_eoc), (unsigned char *)download->zip64_eoc); + download->offset+=sizeof(*download->zip64_eoc); + file_data_write(download->file, download->offset, sizeof(*download->zip64_eocl), (unsigned char *)download->zip64_eocl); + download->offset+=sizeof(*download->zip64_eocl); #endif - file_data_write(download->file, download->offset, sizeof(*download->zip_eoc), (unsigned char *)download->zip_eoc); - download->offset+=sizeof(*download->zip_eoc); - g_free(download->zip64_eoc); - download->zip64_eoc=NULL; - return 1; + file_data_write(download->file, download->offset, sizeof(*download->zip_eoc), (unsigned char *)download->zip_eoc); + download->offset+=sizeof(*download->zip_eoc); + g_free(download->zip64_eoc); + download->zip64_eoc=NULL; + return 1; } static void push_zipfile_tile_do(struct map_rect_priv *mr, struct zip_cd *cd, int zipfile, int offset, int length) { - struct tile t; - struct map_priv *m=mr->m; - struct file *f=m->fi; + struct tile t; + struct map_priv *m=mr->m; + struct file *f=m->fi; - dbg(lvl_debug,"enter %p %d", mr, zipfile); + dbg(lvl_debug,"enter %p %d", mr, zipfile); #ifdef DEBUG_SIZE #if DEBUG_SIZE > 0 - { - char filename[cd->zipcfnl+1]; - memcpy(filename, cd+1, cd->zipcfnl); - filename[cd->zipcfnl]='\0'; - dbg(lvl_debug,"enter %d (%s) %d",zipfile, filename, cd->zipcunc); - } + { + char filename[cd->zipcfnl+1]; + memcpy(filename, cd+1, cd->zipcfnl); + filename[cd->zipcfnl]='\0'; + dbg(lvl_debug,"enter %d (%s) %d",zipfile, filename, cd->zipcunc); + } #endif - mr->size+=cd->zipcunc; + mr->size+=cd->zipcunc; #endif - t.zipfile_num=zipfile; - if (zipfile_to_tile(m, cd, &t)) - push_tile(mr, &t, offset, length); - file_data_free(f, (unsigned char *)cd); + t.zipfile_num=zipfile; + if (zipfile_to_tile(m, cd, &t)) + push_tile(mr, &t, offset, length); + file_data_free(f, (unsigned char *)cd); } static struct zip_cd * -download(struct map_priv *m, struct map_rect_priv *mr, struct zip_cd *cd, int zipfile, int offset, int length, int async) -{ - struct map_download *download; - - if(!m->download_enabled) - return NULL; - - if (async == 2) { - download=m->download; - } else { - download=g_new0(struct map_download, 1); - if (mr) { - download->m=m; - download->mr=mr; - download->file=m->fi; - download->cd=cd; - download->zipfile=zipfile; - download->toffset=offset; - download->tlength=length; - download->state=1; - } else { - struct attr readwrite={attr_readwrite,{(void *)1}}; - struct attr create={attr_create,{(void *)1}}; - struct attr *attrs[3]; - attrs[0]=&readwrite; - attrs[1]=&create; - attrs[2]=NULL; - download->file=file_create(m->filename,attrs); - download->m=m; - download->state=4; - } - } - if (async == 1) { - m->download=download; - g_free(m->progress); - if (download->mr) - m->progress=g_strdup_printf("Download Tile %d 0%%",download->zipfile); - else - m->progress=g_strdup_printf("Download Map Information 0%%"); - callback_list_call_attr_0(m->cbl, attr_progress); - return NULL; - } - for (;;) { - dbg(lvl_debug,"state=%d",download->state); - switch (download->state) { - case 0: - dbg(lvl_error,"error"); - break; - case 1: - if (download_start(download)) - download->state=2; - else - download->state=0; - break; - case 2: - if (download_download(download)) - download->state=3; - else { - g_free(m->progress); - m->progress=g_strdup_printf("Download Tile %d %d%%",download->zipfile,download->progress); - callback_list_call_attr_0(m->cbl, attr_progress); - } - break; - case 3: - if (download_finish(download)) { - struct zip_cd *ret; - g_free(m->progress); - m->progress=g_strdup_printf("Download Tile %d 100%%",download->zipfile); - callback_list_call_attr_0(m->cbl, attr_progress); - if (async) { - push_zipfile_tile_do(download->mr, download->cd, download->zipfile, download->toffset, download->tlength); - ret=NULL; - } else - ret=download->cd; - g_free(m->progress); - m->progress=NULL; - g_free(download); - if (async) - m->download=NULL; - return ret; - } else - download->state=0; - break; - case 4: - if (download_planet_size(download)) - download->state=5; - else - download->state=0; - break; - case 5: - g_free(m->progress); - m->progress=g_strdup_printf("Download Map Information 50%%"); - callback_list_call_attr_0(m->cbl, attr_progress); - if (download_eoc(download)) - download->state=6; - else { - dbg(lvl_error,"download of eoc failed"); - download->state=0; - } - break; - case 6: - g_free(m->progress); - m->progress=g_strdup_printf("Download Map Information 100%%"); - callback_list_call_attr_0(m->cbl, attr_progress); - if (download_directory_start(download)) - download->state=7; - else - download->state=0; - break; - case 7: - g_free(m->progress); - m->progress=g_strdup_printf("Download Map Directory %d%%",(int)(download->offset*100/download->zip64_eoc->zip64ecsz)); - callback_list_call_attr_0(m->cbl, attr_progress); - if (!download_directory_do(download)) - download->state=8; - break; - case 8: - if (download_directory_finish(download)) - download->state=9; - else - download->state=0; - break; - case 9: - download_initial_finish(download); - m->fi=download->file; - g_free(m->progress); - m->progress=NULL; - g_free(download); - if (async) - m->download=NULL; - map_binfile_open(m); - break; - } - if (async) - return NULL; - } +download(struct map_priv *m, struct map_rect_priv *mr, struct zip_cd *cd, int zipfile, int offset, int length, + int async) { + struct map_download *download; + + if(!m->download_enabled) + return NULL; + + if (async == 2) { + download=m->download; + } else { + download=g_new0(struct map_download, 1); + if (mr) { + download->m=m; + download->mr=mr; + download->file=m->fi; + download->cd=cd; + download->zipfile=zipfile; + download->toffset=offset; + download->tlength=length; + download->state=1; + } else { + struct attr readwrite= {attr_readwrite,{(void *)1}}; + struct attr create= {attr_create,{(void *)1}}; + struct attr *attrs[3]; + attrs[0]=&readwrite; + attrs[1]=&create; + attrs[2]=NULL; + download->file=file_create(m->filename,attrs); + download->m=m; + download->state=4; + } + } + if (async == 1) { + m->download=download; + g_free(m->progress); + if (download->mr) + m->progress=g_strdup_printf("Download Tile %d 0%%",download->zipfile); + else + m->progress=g_strdup_printf("Download Map Information 0%%"); + callback_list_call_attr_0(m->cbl, attr_progress); + return NULL; + } + for (;;) { + dbg(lvl_debug,"state=%d",download->state); + switch (download->state) { + case 0: + dbg(lvl_error,"error"); + break; + case 1: + if (download_start(download)) + download->state=2; + else + download->state=0; + break; + case 2: + if (download_download(download)) + download->state=3; + else { + g_free(m->progress); + m->progress=g_strdup_printf("Download Tile %d %d%%",download->zipfile,download->progress); + callback_list_call_attr_0(m->cbl, attr_progress); + } + break; + case 3: + if (download_finish(download)) { + struct zip_cd *ret; + g_free(m->progress); + m->progress=g_strdup_printf("Download Tile %d 100%%",download->zipfile); + callback_list_call_attr_0(m->cbl, attr_progress); + if (async) { + push_zipfile_tile_do(download->mr, download->cd, download->zipfile, download->toffset, download->tlength); + ret=NULL; + } else + ret=download->cd; + g_free(m->progress); + m->progress=NULL; + g_free(download); + if (async) + m->download=NULL; + return ret; + } else + download->state=0; + break; + case 4: + if (download_planet_size(download)) + download->state=5; + else + download->state=0; + break; + case 5: + g_free(m->progress); + m->progress=g_strdup_printf("Download Map Information 50%%"); + callback_list_call_attr_0(m->cbl, attr_progress); + if (download_eoc(download)) + download->state=6; + else { + dbg(lvl_error,"download of eoc failed"); + download->state=0; + } + break; + case 6: + g_free(m->progress); + m->progress=g_strdup_printf("Download Map Information 100%%"); + callback_list_call_attr_0(m->cbl, attr_progress); + if (download_directory_start(download)) + download->state=7; + else + download->state=0; + break; + case 7: + g_free(m->progress); + m->progress=g_strdup_printf("Download Map Directory %d%%",(int)(download->offset*100/download->zip64_eoc->zip64ecsz)); + callback_list_call_attr_0(m->cbl, attr_progress); + if (!download_directory_do(download)) + download->state=8; + break; + case 8: + if (download_directory_finish(download)) + download->state=9; + else + download->state=0; + break; + case 9: + download_initial_finish(download); + m->fi=download->file; + g_free(m->progress); + m->progress=NULL; + g_free(download); + if (async) + m->download=NULL; + map_binfile_open(m); + break; + } + if (async) + return NULL; + } } static int -push_zipfile_tile(struct map_rect_priv *mr, int zipfile, int offset, int length, int async) -{ - struct map_priv *m=mr->m; - struct file *f=m->fi; - long long cdoffset=m->eoc64?m->eoc64->zip64eofst:m->eoc->zipeofst; - struct zip_cd *cd=(struct zip_cd *)(file_data_read(f, cdoffset + zipfile*m->cde_size, m->cde_size)); - dbg(lvl_debug,"read from "LONGLONG_FMT" %d bytes",cdoffset + zipfile*m->cde_size, m->cde_size); - cd_to_cpu(cd); - if (!cd->zipcunc && m->url) { - cd=download(m, mr, cd, zipfile, offset, length, async); - if (!cd) - return 1; - } - push_zipfile_tile_do(mr, cd, zipfile, offset, length); - return 0; +push_zipfile_tile(struct map_rect_priv *mr, int zipfile, int offset, int length, int async) { + struct map_priv *m=mr->m; + struct file *f=m->fi; + long long cdoffset=m->eoc64?m->eoc64->zip64eofst:m->eoc->zipeofst; + struct zip_cd *cd=(struct zip_cd *)(file_data_read(f, cdoffset + zipfile*m->cde_size, m->cde_size)); + dbg(lvl_debug,"read from "LONGLONG_FMT" %d bytes",cdoffset + zipfile*m->cde_size, m->cde_size); + cd_to_cpu(cd); + if (!cd->zipcunc && m->url) { + cd=download(m, mr, cd, zipfile, offset, length, async); + if (!cd) + return 1; + } + push_zipfile_tile_do(mr, cd, zipfile, offset, length); + return 0; } static struct map_rect_priv * -map_rect_new_binfile_int(struct map_priv *map, struct map_selection *sel) -{ - struct map_rect_priv *mr; - - binfile_check_version(map); - dbg(lvl_debug,"map_rect_new_binfile"); - if (!map->fi && !map->url) - return NULL; - map_binfile_http_close(map); - mr=g_new0(struct map_rect_priv, 1); - mr->m=map; - mr->sel=sel; - mr->item.id_hi=0; - mr->item.id_lo=0; - mr->item.meth=&methods_binfile; - mr->item.priv_data=mr; - return mr; +map_rect_new_binfile_int(struct map_priv *map, struct map_selection *sel) { + struct map_rect_priv *mr; + + binfile_check_version(map); + dbg(lvl_debug,"map_rect_new_binfile"); + if (!map->fi && !map->url) + return NULL; + map_binfile_http_close(map); + mr=g_new0(struct map_rect_priv, 1); + mr->m=map; + mr->sel=sel; + mr->item.id_hi=0; + mr->item.id_lo=0; + mr->item.meth=&methods_binfile; + mr->item.priv_data=mr; + return mr; } static void -tile_bbox(char *tile, int len, struct coord_rect *r) -{ - struct coord c; - int overlap=1; - int xo,yo; - struct coord_rect world_bbox = { - { WORLD_BOUNDINGBOX_MIN_X, WORLD_BOUNDINGBOX_MAX_Y}, /* left upper corner */ - { WORLD_BOUNDINGBOX_MAX_X, WORLD_BOUNDINGBOX_MIN_Y}, /* right lower corner */ - }; - *r=world_bbox; - while (len) { - c.x=(r->lu.x+r->rl.x)/2; - c.y=(r->lu.y+r->rl.y)/2; - xo=(r->rl.x-r->lu.x)*overlap/100; - yo=(r->lu.y-r->rl.y)*overlap/100; - switch (*tile) { - case 'a': - r->lu.x=c.x-xo; - r->rl.y=c.y-yo; - break; - case 'b': - r->rl.x=c.x+xo; - r->rl.y=c.y-yo; - break; - case 'c': - r->lu.x=c.x-xo; - r->lu.y=c.y+yo; - break; - case 'd': - r->rl.x=c.x+xo; - r->lu.y=c.y+yo; - break; - default: - return; - } - tile++; - len--; +tile_bbox(char *tile, int len, struct coord_rect *r) { + struct coord c; + int overlap=1; + int xo,yo; + struct coord_rect world_bbox = { + { WORLD_BOUNDINGBOX_MIN_X, WORLD_BOUNDINGBOX_MAX_Y}, /* left upper corner */ + { WORLD_BOUNDINGBOX_MAX_X, WORLD_BOUNDINGBOX_MIN_Y}, /* right lower corner */ + }; + *r=world_bbox; + while (len) { + c.x=(r->lu.x+r->rl.x)/2; + c.y=(r->lu.y+r->rl.y)/2; + xo=(r->rl.x-r->lu.x)*overlap/100; + yo=(r->lu.y-r->rl.y)*overlap/100; + switch (*tile) { + case 'a': + r->lu.x=c.x-xo; + r->rl.y=c.y-yo; + break; + case 'b': + r->rl.x=c.x+xo; + r->rl.y=c.y-yo; + break; + case 'c': + r->lu.x=c.x-xo; + r->lu.y=c.y+yo; + break; + case 'd': + r->rl.x=c.x+xo; + r->lu.y=c.y+yo; + break; + default: + return; } + tile++; + len--; + } } static int -map_download_selection_check(struct zip_cd *cd, struct map_selection *sel) -{ - struct coord_rect cd_rect; - if (cd->zipcunc) - return 0; - tile_bbox((char *)(cd+1), cd->zipcfnl, &cd_rect); - while (sel) { - if (coord_rect_overlap(&cd_rect, &sel->u.c_rect)) - return 1; - sel=sel->next; - } - return 0; +map_download_selection_check(struct zip_cd *cd, struct map_selection *sel) { + struct coord_rect cd_rect; + if (cd->zipcunc) + return 0; + tile_bbox((char *)(cd+1), cd->zipcfnl, &cd_rect); + while (sel) { + if (coord_rect_overlap(&cd_rect, &sel->u.c_rect)) + return 1; + sel=sel->next; + } + return 0; } static void -map_download_selection(struct map_priv *m, struct map_rect_priv *mr, struct map_selection *sel) -{ - int i; - struct zip_cd *cd; - for (i = 0 ; i < m->zip_members ; i++) { - cd=binfile_read_cd(m, m->cde_size*i, -1); - if (map_download_selection_check(cd, sel)) - download(m, mr, cd, i, 0, 0, 0); - file_data_free(m->fi, (unsigned char *)cd); - } +map_download_selection(struct map_priv *m, struct map_rect_priv *mr, struct map_selection *sel) { + int i; + struct zip_cd *cd; + for (i = 0 ; i < m->zip_members ; i++) { + cd=binfile_read_cd(m, m->cde_size*i, -1); + if (map_download_selection_check(cd, sel)) + download(m, mr, cd, i, 0, 0, 0); + file_data_free(m->fi, (unsigned char *)cd); + } } static struct map_rect_priv * -map_rect_new_binfile(struct map_priv *map, struct map_selection *sel) -{ - struct map_rect_priv *mr=map_rect_new_binfile_int(map, sel); - struct tile t; - dbg(lvl_debug,"zip_members=%d", map->zip_members); - if (map->url && map->fi && sel && sel->order == 255) { - map_download_selection(map, mr, sel); - } - if (map->eoc) - mr->status=1; - else { - unsigned char *d; - if (map->fi) { - d=file_data_read(map->fi, 0, map->fi->size); - t.start=(int *)d; - t.end=(int *)(d+map->fi->size); - t.fi=map->fi; - t.zipfile_num=0; - t.mode=0; - push_tile(mr, &t, 0, 0); - } else if (map->url && !map->download) { - download(map, NULL, NULL, 0, 0, 0, 1); - mr->status=1; - } - } - return mr; +map_rect_new_binfile(struct map_priv *map, struct map_selection *sel) { + struct map_rect_priv *mr=map_rect_new_binfile_int(map, sel); + struct tile t; + dbg(lvl_debug,"zip_members=%d", map->zip_members); + if (map->url && map->fi && sel && sel->order == 255) { + map_download_selection(map, mr, sel); + } + if (map->eoc) + mr->status=1; + else { + unsigned char *d; + if (map->fi) { + d=file_data_read(map->fi, 0, map->fi->size); + t.start=(int *)d; + t.end=(int *)(d+map->fi->size); + t.fi=map->fi; + t.zipfile_num=0; + t.mode=0; + push_tile(mr, &t, 0, 0); + } else if (map->url && !map->download) { + download(map, NULL, NULL, 0, 0, 0, 1); + mr->status=1; + } + } + return mr; } static void -write_changes_do(gpointer key, gpointer value, gpointer user_data) -{ - struct binfile_hash_entry *entry=key; - FILE *out=user_data; - if (entry->flags) { - entry->flags=0; - fwrite(entry, sizeof(*entry)+(le32_to_cpu(entry->data[0])+1)*4, 1, out); - dbg(lvl_debug,"yes"); - } +write_changes_do(gpointer key, gpointer value, gpointer user_data) { + struct binfile_hash_entry *entry=key; + FILE *out=user_data; + if (entry->flags) { + entry->flags=0; + fwrite(entry, sizeof(*entry)+(le32_to_cpu(entry->data[0])+1)*4, 1, out); + dbg(lvl_debug,"yes"); + } } static void -write_changes(struct map_priv *m) -{ - FILE *changes; - char *changes_file; - if (!m->changes) - return; - changes_file=g_strdup_printf("%s.log",m->filename); - changes=fopen(changes_file,"ab"); - g_hash_table_foreach(m->changes, write_changes_do, changes); - fclose(changes); - g_free(changes_file); +write_changes(struct map_priv *m) { + FILE *changes; + char *changes_file; + if (!m->changes) + return; + changes_file=g_strdup_printf("%s.log",m->filename); + changes=fopen(changes_file,"ab"); + g_hash_table_foreach(m->changes, write_changes_do, changes); + fclose(changes); + g_free(changes_file); } static void -load_changes(struct map_priv *m) -{ - FILE *changes; - char *changes_file; - struct binfile_hash_entry entry,*e; - int size; - changes_file=g_strdup_printf("%s.log",m->filename); - changes=fopen(changes_file,"rb"); - if (! changes) { - g_free(changes_file); - return; - } - m->changes=g_hash_table_new_full(binfile_hash_entry_hash, binfile_hash_entry_equal, g_free, NULL); - while (fread(&entry, sizeof(entry), 1, changes) == 1) { - if (fread(&size, sizeof(size), 1, changes) != 1) - break; - e=g_malloc(sizeof(struct binfile_hash_entry)+(le32_to_cpu(size)+1)*4); - *e=entry; - e->data[0]=size; - if (fread(e->data+1, le32_to_cpu(size)*4, 1, changes) != 1) - break; - g_hash_table_replace(m->changes, e, e); - } - fclose(changes); - g_free(changes_file); +load_changes(struct map_priv *m) { + FILE *changes; + char *changes_file; + struct binfile_hash_entry entry,*e; + int size; + changes_file=g_strdup_printf("%s.log",m->filename); + changes=fopen(changes_file,"rb"); + if (! changes) { + g_free(changes_file); + return; + } + m->changes=g_hash_table_new_full(binfile_hash_entry_hash, binfile_hash_entry_equal, g_free, NULL); + while (fread(&entry, sizeof(entry), 1, changes) == 1) { + if (fread(&size, sizeof(size), 1, changes) != 1) + break; + e=g_malloc(sizeof(struct binfile_hash_entry)+(le32_to_cpu(size)+1)*4); + *e=entry; + e->data[0]=size; + if (fread(e->data+1, le32_to_cpu(size)*4, 1, changes) != 1) + break; + g_hash_table_replace(m->changes, e, e); + } + fclose(changes); + g_free(changes_file); } static void -map_rect_destroy_binfile(struct map_rect_priv *mr) -{ - write_changes(mr->m); - while (pop_tile(mr)); +map_rect_destroy_binfile(struct map_rect_priv *mr) { + write_changes(mr->m); + while (pop_tile(mr)); #ifdef DEBUG_SIZE - dbg(lvl_debug,"size=%d kb",mr->size/1024); + dbg(lvl_debug,"size=%d kb",mr->size/1024); #endif - if (mr->tiles[0].fi && mr->tiles[0].start) - file_data_free(mr->tiles[0].fi, (unsigned char *)(mr->tiles[0].start)); - g_free(mr->url); - map_binfile_http_close(mr->m); - g_free(mr); + if (mr->tiles[0].fi && mr->tiles[0].start) + file_data_free(mr->tiles[0].fi, (unsigned char *)(mr->tiles[0].start)); + g_free(mr->url); + map_binfile_http_close(mr->m); + g_free(mr); } static void -setup_pos(struct map_rect_priv *mr) -{ - int size,coord_size; - struct tile *t=mr->t; - size=le32_to_cpu(t->pos[0]); - if (size > 1024*1024 || size < 0) { - dbg(lvl_debug,"size=0x%x", size); +setup_pos(struct map_rect_priv *mr) { + int size,coord_size; + struct tile *t=mr->t; + size=le32_to_cpu(t->pos[0]); + if (size > 1024*1024 || size < 0) { + dbg(lvl_debug,"size=0x%x", size); #if 0 - fprintf(stderr,"offset=%d\n", (unsigned char *)(mr->pos)-mr->m->f->begin); + fprintf(stderr,"offset=%d\n", (unsigned char *)(mr->pos)-mr->m->f->begin); #endif - dbg(lvl_debug,"size error"); - } - t->pos_next=t->pos+size+1; - mr->item.type=le32_to_cpu(t->pos[1]); - coord_size=le32_to_cpu(t->pos[2]); - t->pos_coord_start=t->pos+3; - t->pos_attr_start=t->pos_coord_start+coord_size; + dbg(lvl_debug,"size error"); + } + t->pos_next=t->pos+size+1; + mr->item.type=le32_to_cpu(t->pos[1]); + coord_size=le32_to_cpu(t->pos[2]); + t->pos_coord_start=t->pos+3; + t->pos_attr_start=t->pos_coord_start+coord_size; } static int -selection_contains(struct map_selection *sel, struct coord_rect *r, struct range *mima) -{ - int order; - if (! sel) - return 1; - while (sel) { - if (coord_rect_overlap(r, &sel->u.c_rect)) { - order=sel->order; - dbg(lvl_debug,"min %d max %d order %d", mima->min, mima->max, order); - if (!mima->min && !mima->max) - return 1; - if (order >= mima->min && order <= mima->max) - return 1; - } - sel=sel->next; - } - return 0; +selection_contains(struct map_selection *sel, struct coord_rect *r, struct range *mima) { + int order; + if (! sel) + return 1; + while (sel) { + if (coord_rect_overlap(r, &sel->u.c_rect)) { + order=sel->order; + dbg(lvl_debug,"min %d max %d order %d", mima->min, mima->max, order); + if (!mima->min && !mima->max) + return 1; + if (order >= mima->min && order <= mima->max) + return 1; + } + sel=sel->next; + } + return 0; } static void -map_parse_country_binfile(struct map_rect_priv *mr) -{ - struct attr at; - - if (!binfile_attr_get(mr->item.priv_data, attr_country_id, &at)) - return; - - if( at.u.num != mr->country_id) - return; - - if (!binfile_attr_get(mr->item.priv_data, attr_zipfile_ref, &at)) - return; - - if(mr->msp) - { - struct attr *search=&mr->msp->search; - if(search->type==attr_town_name || search->type==attr_district_name || search->type==attr_town_or_district_name) { - struct attr af, al; - if(binfile_attr_get(mr->item.priv_data, attr_first_key, &af)) { - if(linguistics_compare(af.u.str,search->u.str,linguistics_cmp_partial)>0) { - dbg(lvl_debug,"Skipping index item with first_key='%s'", af.u.str); - return; - } - } - if(binfile_attr_get(mr->item.priv_data, attr_last_key, &al)) { - if(linguistics_compare(al.u.str,search->u.str,linguistics_cmp_partial)<0) { - dbg(lvl_debug,"Skipping index item with first_key='%s', last_key='%s'", af.u.str, al.u.str); - return; - } - } - } - } - - push_zipfile_tile(mr, at.u.num, 0, 0, 0); +map_parse_country_binfile(struct map_rect_priv *mr) { + struct attr at; + + if (!binfile_attr_get(mr->item.priv_data, attr_country_id, &at)) + return; + + if( at.u.num != mr->country_id) + return; + + if (!binfile_attr_get(mr->item.priv_data, attr_zipfile_ref, &at)) + return; + + if(mr->msp) { + struct attr *search=&mr->msp->search; + if(search->type==attr_town_name || search->type==attr_district_name || search->type==attr_town_or_district_name) { + struct attr af, al; + if(binfile_attr_get(mr->item.priv_data, attr_first_key, &af)) { + if(linguistics_compare(af.u.str,search->u.str,linguistics_cmp_partial)>0) { + dbg(lvl_debug,"Skipping index item with first_key='%s'", af.u.str); + return; + } + } + if(binfile_attr_get(mr->item.priv_data, attr_last_key, &al)) { + if(linguistics_compare(al.u.str,search->u.str,linguistics_cmp_partial)<0) { + dbg(lvl_debug,"Skipping index item with first_key='%s', last_key='%s'", af.u.str, al.u.str); + return; + } + } + } + } + + push_zipfile_tile(mr, at.u.num, 0, 0, 0); } static int -map_parse_submap(struct map_rect_priv *mr, int async) -{ - struct coord_rect r; - struct coord c[2]; - struct attr at; - struct range mima; - if (binfile_coord_get(mr->item.priv_data, c, 2) != 2) - return 0; - r.lu.x=c[0].x; - r.lu.y=c[1].y; - r.rl.x=c[1].x; - r.rl.y=c[0].y; - if (!binfile_attr_get(mr->item.priv_data, attr_order, &at)) - return 0; +map_parse_submap(struct map_rect_priv *mr, int async) { + struct coord_rect r; + struct coord c[2]; + struct attr at; + struct range mima; + if (binfile_coord_get(mr->item.priv_data, c, 2) != 2) + return 0; + r.lu.x=c[0].x; + r.lu.y=c[1].y; + r.rl.x=c[1].x; + r.rl.y=c[0].y; + if (!binfile_attr_get(mr->item.priv_data, attr_order, &at)) + return 0; #if __BYTE_ORDER == __BIG_ENDIAN - mima.min=le16_to_cpu(at.u.range.max); - mima.max=le16_to_cpu(at.u.range.min); + mima.min=le16_to_cpu(at.u.range.max); + mima.max=le16_to_cpu(at.u.range.min); #else - mima=at.u.range; + mima=at.u.range; #endif - if (!mr->m->eoc || !selection_contains(mr->sel, &r, &mima)) - return 0; - if (!binfile_attr_get(mr->item.priv_data, attr_zipfile_ref, &at)) - return 0; - dbg(lvl_debug,"pushing zipfile %ld from %d", at.u.num, mr->t->zipfile_num); - return push_zipfile_tile(mr, at.u.num, 0, 0, async); + if (!mr->m->eoc || !selection_contains(mr->sel, &r, &mima)) + return 0; + if (!binfile_attr_get(mr->item.priv_data, attr_zipfile_ref, &at)) + return 0; + dbg(lvl_debug,"pushing zipfile %ld from %d", at.u.num, mr->t->zipfile_num); + return push_zipfile_tile(mr, at.u.num, 0, 0, async); } static int -push_modified_item(struct map_rect_priv *mr) -{ - struct item_id id; - struct binfile_hash_entry *entry; - id.id_hi=mr->item.id_hi; - id.id_lo=mr->item.id_lo; - entry=g_hash_table_lookup(mr->m->changes, &id); - if (entry) { - struct tile tn; - tn.pos_next=tn.pos=tn.start=entry->data; - tn.zipfile_num=mr->item.id_hi; - tn.mode=2; - tn.end=tn.start+le32_to_cpu(entry->data[0])+1; - push_tile(mr, &tn, 0, 0); - return 1; - } - return 0; +push_modified_item(struct map_rect_priv *mr) { + struct item_id id; + struct binfile_hash_entry *entry; + id.id_hi=mr->item.id_hi; + id.id_lo=mr->item.id_lo; + entry=g_hash_table_lookup(mr->m->changes, &id); + if (entry) { + struct tile tn; + tn.pos_next=tn.pos=tn.start=entry->data; + tn.zipfile_num=mr->item.id_hi; + tn.mode=2; + tn.end=tn.start+le32_to_cpu(entry->data[0])+1; + push_tile(mr, &tn, 0, 0); + return 1; + } + return 0; } static struct item * -map_rect_get_item_binfile(struct map_rect_priv *mr) -{ - struct tile *t; - struct map_priv *m=mr->m; - if (m->download) { - download(m, NULL, NULL, 0, 0, 0, 2); - return &busy_item; - } - if (mr->status == 1) { - mr->status=0; - if (push_zipfile_tile(mr, m->zip_members-1, 0, 0, 1)) - return &busy_item; - } - for (;;) { - t=mr->t; - if (! t) - return NULL; - t->pos=t->pos_next; - if (t->pos >= t->end) { - if (pop_tile(mr)) - continue; - return NULL; - } - setup_pos(mr); - binfile_coord_rewind(mr); - binfile_attr_rewind(mr); - if ((mr->item.type == type_submap) && (!mr->country_id)) { - if (map_parse_submap(mr, 1)) - return &busy_item; - continue; - } - if (t->mode != 2) { - mr->item.id_hi=t->zipfile_num; - mr->item.id_lo=t->pos-t->start; - if (mr->m->changes && push_modified_item(mr)) - continue; - } - if (mr->country_id) - { - if (mr->item.type == type_countryindex) { - map_parse_country_binfile(mr); - } - if (item_is_town(mr->item)) - { - return &mr->item; - } else { - continue; - } - } - return &mr->item; - } +map_rect_get_item_binfile(struct map_rect_priv *mr) { + struct tile *t; + struct map_priv *m=mr->m; + if (m->download) { + download(m, NULL, NULL, 0, 0, 0, 2); + return &busy_item; + } + if (mr->status == 1) { + mr->status=0; + if (push_zipfile_tile(mr, m->zip_members-1, 0, 0, 1)) + return &busy_item; + } + for (;;) { + t=mr->t; + if (! t) + return NULL; + t->pos=t->pos_next; + if (t->pos >= t->end) { + if (pop_tile(mr)) + continue; + return NULL; + } + setup_pos(mr); + binfile_coord_rewind(mr); + binfile_attr_rewind(mr); + if ((mr->item.type == type_submap) && (!mr->country_id)) { + if (map_parse_submap(mr, 1)) + return &busy_item; + continue; + } + if (t->mode != 2) { + mr->item.id_hi=t->zipfile_num; + mr->item.id_lo=t->pos-t->start; + if (mr->m->changes && push_modified_item(mr)) + continue; + } + if (mr->country_id) { + if (mr->item.type == type_countryindex) { + map_parse_country_binfile(mr); + } + if (item_is_town(mr->item)) { + return &mr->item; + } else { + continue; + } + } + return &mr->item; + } } static struct item * -map_rect_get_item_byid_binfile(struct map_rect_priv *mr, int id_hi, int id_lo) -{ - struct tile *t; - if (mr->m->eoc) { - while (pop_tile(mr)); - push_zipfile_tile(mr, id_hi, 0, 0, 0); - } - t=mr->t; - t->pos=t->start+id_lo; - mr->item.id_hi=id_hi; - mr->item.id_lo=id_lo; - if (mr->m->changes) - push_modified_item(mr); - setup_pos(mr); - binfile_coord_rewind(mr); - binfile_attr_rewind(mr); - return &mr->item; +map_rect_get_item_byid_binfile(struct map_rect_priv *mr, int id_hi, int id_lo) { + struct tile *t; + if (mr->m->eoc) { + while (pop_tile(mr)); + push_zipfile_tile(mr, id_hi, 0, 0, 0); + } + t=mr->t; + t->pos=t->start+id_lo; + mr->item.id_hi=id_hi; + mr->item.id_lo=id_lo; + if (mr->m->changes) + push_modified_item(mr); + setup_pos(mr); + binfile_coord_rewind(mr); + binfile_attr_rewind(mr); + return &mr->item; } static int -binmap_search_by_index(struct map_priv *map, struct item *item, struct map_rect_priv **ret) -{ - struct attr zipfile_ref; - int *data; - - if (!item) { - *ret=NULL; - return 0; - } - if (item_attr_get(item, attr_item_id, &zipfile_ref)) { - data=zipfile_ref.u.data; - *ret=map_rect_new_binfile_int(map, NULL); - push_zipfile_tile(*ret, le32_to_cpu(data[0]), le32_to_cpu(data[1]), -1, 0); - return 3; - } - if (item_attr_get(item, attr_zipfile_ref, &zipfile_ref)) { - *ret=map_rect_new_binfile_int(map, NULL); - push_zipfile_tile(*ret, zipfile_ref.u.num, 0, 0, 0); - return 1; - } - if (item_attr_get(item, attr_zipfile_ref_block, &zipfile_ref)) { - data=zipfile_ref.u.data; - *ret=map_rect_new_binfile_int(map, NULL); - push_zipfile_tile(*ret, le32_to_cpu(data[0]), le32_to_cpu(data[1]), le32_to_cpu(data[2]), 0); - return 2; - } - *ret=NULL; - return 0; +binmap_search_by_index(struct map_priv *map, struct item *item, struct map_rect_priv **ret) { + struct attr zipfile_ref; + int *data; + + if (!item) { + *ret=NULL; + return 0; + } + if (item_attr_get(item, attr_item_id, &zipfile_ref)) { + data=zipfile_ref.u.data; + *ret=map_rect_new_binfile_int(map, NULL); + push_zipfile_tile(*ret, le32_to_cpu(data[0]), le32_to_cpu(data[1]), -1, 0); + return 3; + } + if (item_attr_get(item, attr_zipfile_ref, &zipfile_ref)) { + *ret=map_rect_new_binfile_int(map, NULL); + push_zipfile_tile(*ret, zipfile_ref.u.num, 0, 0, 0); + return 1; + } + if (item_attr_get(item, attr_zipfile_ref_block, &zipfile_ref)) { + data=zipfile_ref.u.data; + *ret=map_rect_new_binfile_int(map, NULL); + push_zipfile_tile(*ret, le32_to_cpu(data[0]), le32_to_cpu(data[1]), le32_to_cpu(data[2]), 0); + return 2; + } + *ret=NULL; + return 0; } static struct map_rect_priv * -binmap_search_street_by_place(struct map_priv *map, struct item *town, struct coord *c, struct map_selection *sel, GList **boundaries) -{ - struct attr town_name, poly_town_name; - struct map_rect_priv *map_rec2; - struct item *place; - int found=0; - - if (!item_attr_get(town, attr_label, &town_name)) - return NULL; - sel->range = item_range_all; - sel->order = 18; - sel->next = NULL; - sel->u.c_rect.lu=*c; - sel->u.c_rect.rl=*c; - map_rec2=map_rect_new_binfile(map, sel); - while ((place=map_rect_get_item_binfile(map_rec2))) { - if (item_is_poly_place(*place) && - item_attr_get(place, attr_label, &poly_town_name) && - !strcmp(poly_town_name.u.str,town_name.u.str)) { - struct coord *c; - int i,count; - struct geom_poly_segment *bnd; - count=binfile_coord_left(map_rec2); - c=g_new(struct coord,count); - found=1; - item_coord_get(place, c, count); - for (i = 0 ; i < count ; i++) - coord_rect_extend(&sel->u.c_rect, &c[i]); - bnd=g_new(struct geom_poly_segment,1); - bnd->first=c; - bnd->last=c+count-1; - bnd->type=geom_poly_segment_type_way_outer; - *boundaries=g_list_prepend(*boundaries,bnd); - } - } - map_rect_destroy_binfile(map_rec2); - if (found) - return map_rect_new_binfile(map, sel); - return NULL; +binmap_search_street_by_place(struct map_priv *map, struct item *town, struct coord *c, struct map_selection *sel, + GList **boundaries) { + struct attr town_name, poly_town_name; + struct map_rect_priv *map_rec2; + struct item *place; + int found=0; + + if (!item_attr_get(town, attr_label, &town_name)) + return NULL; + sel->range = item_range_all; + sel->order = 18; + sel->next = NULL; + sel->u.c_rect.lu=*c; + sel->u.c_rect.rl=*c; + map_rec2=map_rect_new_binfile(map, sel); + while ((place=map_rect_get_item_binfile(map_rec2))) { + if (item_is_poly_place(*place) && + item_attr_get(place, attr_label, &poly_town_name) && + !strcmp(poly_town_name.u.str,town_name.u.str)) { + struct coord *c; + int i,count; + struct geom_poly_segment *bnd; + count=binfile_coord_left(map_rec2); + c=g_new(struct coord,count); + found=1; + item_coord_get(place, c, count); + for (i = 0 ; i < count ; i++) + coord_rect_extend(&sel->u.c_rect, &c[i]); + bnd=g_new(struct geom_poly_segment,1); + bnd->first=c; + bnd->last=c+count-1; + bnd->type=geom_poly_segment_type_way_outer; + *boundaries=g_list_prepend(*boundaries,bnd); + } + } + map_rect_destroy_binfile(map_rec2); + if (found) + return map_rect_new_binfile(map, sel); + return NULL; } static int -binmap_get_estimated_town_size(struct item *town) -{ - int size = 10000; - switch (town->type) { - case type_town_label_1e5: - case type_town_label_5e4: - case type_town_label_2e4: - case type_district_label_1e5: - case type_district_label_5e4: - case type_district_label_2e4: - size = 5000; - break; - case type_town_label_1e4: - case type_town_label_5e3: - case type_town_label_2e3: - case type_district_label_1e4: - case type_district_label_5e3: - case type_district_label_2e3: - size = 2500; - break; - case type_town_label_1e3: - case type_town_label_5e2: - case type_town_label_2e2: - case type_town_label_1e2: - case type_town_label_5e1: - case type_town_label_2e1: - case type_town_label_1e1: - case type_town_label_5e0: - case type_town_label_2e0: - case type_town_label_1e0: - case type_town_label_0e0: - case type_district_label_1e3: - case type_district_label_5e2: - case type_district_label_2e2: - case type_district_label_1e2: - case type_district_label_5e1: - case type_district_label_2e1: - case type_district_label_1e1: - case type_district_label_5e0: - case type_district_label_2e0: - case type_district_label_1e0: - case type_district_label_0e0: - size = 1000; - break; - default: - break; - } - return size; +binmap_get_estimated_town_size(struct item *town) { + int size = 10000; + switch (town->type) { + case type_town_label_1e5: + case type_town_label_5e4: + case type_town_label_2e4: + case type_district_label_1e5: + case type_district_label_5e4: + case type_district_label_2e4: + size = 5000; + break; + case type_town_label_1e4: + case type_town_label_5e3: + case type_town_label_2e3: + case type_district_label_1e4: + case type_district_label_5e3: + case type_district_label_2e3: + size = 2500; + break; + case type_town_label_1e3: + case type_town_label_5e2: + case type_town_label_2e2: + case type_town_label_1e2: + case type_town_label_5e1: + case type_town_label_2e1: + case type_town_label_1e1: + case type_town_label_5e0: + case type_town_label_2e0: + case type_town_label_1e0: + case type_town_label_0e0: + case type_district_label_1e3: + case type_district_label_5e2: + case type_district_label_2e2: + case type_district_label_1e2: + case type_district_label_5e1: + case type_district_label_2e1: + case type_district_label_1e1: + case type_district_label_5e0: + case type_district_label_2e0: + case type_district_label_1e0: + case type_district_label_0e0: + size = 1000; + break; + default: + break; + } + return size; } static struct map_rect_priv * -binmap_search_street_by_estimate(struct map_priv *map, struct item *town, struct coord *c, struct map_selection *sel) -{ - int size = binmap_get_estimated_town_size(town); +binmap_search_street_by_estimate(struct map_priv *map, struct item *town, struct coord *c, struct map_selection *sel) { + int size = binmap_get_estimated_town_size(town); - sel->u.c_rect.lu.x = c->x-size; - sel->u.c_rect.lu.y = c->y+size; - sel->u.c_rect.rl.x = c->x+size; - sel->u.c_rect.rl.y = c->y-size; - return map_rect_new_binfile(map, sel); + sel->u.c_rect.lu.x = c->x-size; + sel->u.c_rect.lu.y = c->y+size; + sel->u.c_rect.rl.x = c->x+size; + sel->u.c_rect.rl.y = c->y-size; + return map_rect_new_binfile(map, sel); } static struct map_rect_priv * -binmap_search_housenumber_by_estimate(struct map_priv *map, struct coord *c, struct map_selection *sel) -{ - int size = 400; - sel->u.c_rect.lu.x = c->x-size; - sel->u.c_rect.lu.y = c->y+size; - sel->u.c_rect.rl.x = c->x+size; - sel->u.c_rect.rl.y = c->y-size; +binmap_search_housenumber_by_estimate(struct map_priv *map, struct coord *c, struct map_selection *sel) { + int size = 400; + sel->u.c_rect.lu.x = c->x-size; + sel->u.c_rect.lu.y = c->y+size; + sel->u.c_rect.rl.x = c->x+size; + sel->u.c_rect.rl.y = c->y-size; - sel->range = item_range_all; - sel->order = 18; + sel->range = item_range_all; + sel->order = 18; - return map_rect_new_binfile(map, sel); + return map_rect_new_binfile(map, sel); } static int -binmap_get_estimated_boundaries (struct item *town, GList **boundaries) -{ - int size = binmap_get_estimated_town_size(town); - struct coord tc; - - if (item_coord_get(town, &tc, 1)) - { - struct geom_poly_segment *bnd; - struct coord *c; - c=g_new(struct coord,5); - bnd=g_new(struct geom_poly_segment,1); - c[0].x = tc.x + size; - c[0].y = tc.y - size; - c[1].x = tc.x - size; - c[1].y = tc.y - size; - c[2].x = tc.x - size; - c[2].y = tc.y + size; - c[3].x = tc.x + size; - c[3].y = tc.y + size; - c[4].x = c[0].x; - c[4].y = c[0].y; - bnd->first=&c[0]; - bnd->last=&c[4]; - bnd->type=geom_poly_segment_type_way_outer; - *boundaries=g_list_prepend(*boundaries,bnd); - return 1; - } - return 0; +binmap_get_estimated_boundaries (struct item *town, GList **boundaries) { + int size = binmap_get_estimated_town_size(town); + struct coord tc; + + if (item_coord_get(town, &tc, 1)) { + struct geom_poly_segment *bnd; + struct coord *c; + c=g_new(struct coord,5); + bnd=g_new(struct geom_poly_segment,1); + c[0].x = tc.x + size; + c[0].y = tc.y - size; + c[1].x = tc.x - size; + c[1].y = tc.y - size; + c[2].x = tc.x - size; + c[2].y = tc.y + size; + c[3].x = tc.x + size; + c[3].y = tc.y + size; + c[4].x = c[0].x; + c[4].y = c[0].y; + bnd->first=&c[0]; + bnd->last=&c[4]; + bnd->type=geom_poly_segment_type_way_outer; + *boundaries=g_list_prepend(*boundaries,bnd); + return 1; + } + return 0; } static struct map_search_priv * -binmap_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial) -{ - struct map_rect_priv *map_rec; - struct map_search_priv *msp=g_new0(struct map_search_priv, 1); - struct item *town; - int idx; - - msp->search = *search; - msp->partial = partial; - if(ATTR_IS_STRING(msp->search.type)) - msp->search.u.str=linguistics_casefold(search->u.str); - - /* +binmap_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial) { + struct map_rect_priv *map_rec; + struct map_search_priv *msp=g_new0(struct map_search_priv, 1); + struct item *town; + int idx; + + msp->search = *search; + msp->partial = partial; + if(ATTR_IS_STRING(msp->search.type)) + msp->search.u.str=linguistics_casefold(search->u.str); + + /* * NOTE: If you implement search for other attributes than attr_town_name and attr_street_name, * please update this comment and the documentation for map_search_new() in map.c */ - switch (search->type) { - case attr_country_name: - break; - case attr_town_name: - case attr_town_or_district_name: - case attr_town_postal: - map_rec = map_rect_new_binfile(map, NULL); - if (!map_rec) - break; - map_rec->country_id = item->id_lo; - map_rec->msp = msp; - msp->mr = map_rec; - return msp; - break; - case attr_street_name: - if (! item->map) - break; - if (!map_priv_is(item->map, map)) - break; - map_rec = map_rect_new_binfile(map, NULL); - town = map_rect_get_item_byid_binfile(map_rec, item->id_hi, item->id_lo); - if (town) { - struct coord c; - - if (binmap_search_by_index(map, town, &msp->mr)) - msp->mode = 1; - else { - map->last_searched_town_id_hi = town->id_hi; - map->last_searched_town_id_lo = town->id_lo; - if (item_coord_get(town, &c, 1)) { - if ((msp->mr=binmap_search_street_by_place(map, town, &c, &msp->ms, &msp->boundaries))) - msp->mode = 2; - else { - msp->mr=binmap_search_street_by_estimate(map, town, &c, &msp->ms); - msp->mode = 3; - } - } - } - map_rect_destroy_binfile(map_rec); - if (!msp->mr) - break; - return msp; - } - map_rect_destroy_binfile(map_rec); - break; - case attr_house_number: - dbg(lvl_debug,"case house_number"); - if (! item->map) - break; - if (!map_priv_is(item->map, map)) - break; - msp->map=map; - msp->mr_item = map_rect_new_binfile(map, NULL); - msp->item = map_rect_get_item_byid_binfile(msp->mr_item, item->id_hi, item->id_lo); - idx=binmap_search_by_index(map, msp->item, &msp->mr); - if (idx) - msp->mode = 1; - else - { - struct coord c; - if (item_coord_get(msp->item, &c, 1)) - { - struct attr attr; - map_rec = map_rect_new_binfile(map, NULL); - town = map_rect_get_item_byid_binfile(map_rec, map->last_searched_town_id_hi, map->last_searched_town_id_lo); - if (town) - msp->mr = binmap_search_street_by_place(map, town, &c, &msp->ms, &msp->boundaries); - if (msp->boundaries) - dbg(lvl_debug, "using map town boundaries"); - if (!msp->boundaries && town) - { - binmap_get_estimated_boundaries(town, &msp->boundaries); - if (msp->boundaries) - dbg(lvl_debug, "using estimated boundaries"); - } - map_rect_destroy_binfile(map_rec); - /* start searching in area around the street segment even if town boundaries are available */ - msp->mr=binmap_search_housenumber_by_estimate(map, &c, &msp->ms); - msp->mode = 2; - msp->rect_new=msp->ms.u.c_rect; - if(item_attr_get(msp->item, attr_street_name, &attr)) - msp->parent_name=g_strdup(attr.u.str); - dbg(lvl_debug,"pn=%s",msp->parent_name); - } - } - if (idx != 3) { - map_rect_destroy_binfile(msp->mr_item); - msp->mr_item=NULL; - } - if (!msp->mr) - { - break; - } - return msp; - default: - break; - } - if(ATTR_IS_STRING(msp->search.type)) - g_free(msp->search.u.str); - g_free(msp); - return NULL; -} - - -struct duplicate -{ - struct coord c; - char str[0]; + switch (search->type) { + case attr_country_name: + break; + case attr_town_name: + case attr_town_or_district_name: + case attr_town_postal: + map_rec = map_rect_new_binfile(map, NULL); + if (!map_rec) + break; + map_rec->country_id = item->id_lo; + map_rec->msp = msp; + msp->mr = map_rec; + return msp; + break; + case attr_street_name: + if (! item->map) + break; + if (!map_priv_is(item->map, map)) + break; + map_rec = map_rect_new_binfile(map, NULL); + town = map_rect_get_item_byid_binfile(map_rec, item->id_hi, item->id_lo); + if (town) { + struct coord c; + + if (binmap_search_by_index(map, town, &msp->mr)) + msp->mode = 1; + else { + map->last_searched_town_id_hi = town->id_hi; + map->last_searched_town_id_lo = town->id_lo; + if (item_coord_get(town, &c, 1)) { + if ((msp->mr=binmap_search_street_by_place(map, town, &c, &msp->ms, &msp->boundaries))) + msp->mode = 2; + else { + msp->mr=binmap_search_street_by_estimate(map, town, &c, &msp->ms); + msp->mode = 3; + } + } + } + map_rect_destroy_binfile(map_rec); + if (!msp->mr) + break; + return msp; + } + map_rect_destroy_binfile(map_rec); + break; + case attr_house_number: + dbg(lvl_debug,"case house_number"); + if (! item->map) + break; + if (!map_priv_is(item->map, map)) + break; + msp->map=map; + msp->mr_item = map_rect_new_binfile(map, NULL); + msp->item = map_rect_get_item_byid_binfile(msp->mr_item, item->id_hi, item->id_lo); + idx=binmap_search_by_index(map, msp->item, &msp->mr); + if (idx) + msp->mode = 1; + else { + struct coord c; + if (item_coord_get(msp->item, &c, 1)) { + struct attr attr; + map_rec = map_rect_new_binfile(map, NULL); + town = map_rect_get_item_byid_binfile(map_rec, map->last_searched_town_id_hi, map->last_searched_town_id_lo); + if (town) + msp->mr = binmap_search_street_by_place(map, town, &c, &msp->ms, &msp->boundaries); + if (msp->boundaries) + dbg(lvl_debug, "using map town boundaries"); + if (!msp->boundaries && town) { + binmap_get_estimated_boundaries(town, &msp->boundaries); + if (msp->boundaries) + dbg(lvl_debug, "using estimated boundaries"); + } + map_rect_destroy_binfile(map_rec); + /* start searching in area around the street segment even if town boundaries are available */ + msp->mr=binmap_search_housenumber_by_estimate(map, &c, &msp->ms); + msp->mode = 2; + msp->rect_new=msp->ms.u.c_rect; + if(item_attr_get(msp->item, attr_street_name, &attr)) + msp->parent_name=g_strdup(attr.u.str); + dbg(lvl_debug,"pn=%s",msp->parent_name); + } + } + if (idx != 3) { + map_rect_destroy_binfile(msp->mr_item); + msp->mr_item=NULL; + } + if (!msp->mr) { + break; + } + return msp; + default: + break; + } + if(ATTR_IS_STRING(msp->search.type)) + g_free(msp->search.u.str); + g_free(msp); + return NULL; +} + + +struct duplicate { + struct coord c; + char str[0]; }; static guint -duplicate_hash(gconstpointer key) -{ - const struct duplicate *d=key; - return d->c.x^d->c.y^g_str_hash(d->str); +duplicate_hash(gconstpointer key) { + const struct duplicate *d=key; + return d->c.x^d->c.y^g_str_hash(d->str); } static gboolean -duplicate_equal(gconstpointer a, gconstpointer b) -{ - const struct duplicate *da=a; - const struct duplicate *db=b; - return (da->c.x == db->c.x && da->c.y == db->c.y && g_str_equal(da->str,db->str)); +duplicate_equal(gconstpointer a, gconstpointer b) { + const struct duplicate *da=a; + const struct duplicate *db=b; + return (da->c.x == db->c.x && da->c.y == db->c.y && g_str_equal(da->str,db->str)); } /** @@ -2177,42 +2110,41 @@ duplicate_equal(gconstpointer a, gconstpointer b) * - NULL if this item already exists in duplicate hash or doesnt have an attr_type attr; */ static struct duplicate* -duplicate_test(struct map_search_priv *msp, struct item *item, enum attr_type attr_type, enum attr_type attr_type2) -{ -struct attr attr; - struct attr attr2; - int len; - char *buffer; - struct duplicate *d; - - if (!msp->search_results) - msp->search_results = g_hash_table_new_full(duplicate_hash, duplicate_equal, g_free, NULL); - binfile_attr_rewind(item->priv_data); - if (!item_attr_get(item, attr_type, &attr)) - return NULL; - len=sizeof(struct coord)+strlen(attr.u.str)+1; - binfile_attr_rewind(item->priv_data); - if (attr_type2 && item_attr_get(item, attr_type2, &attr2) && attr2.u.str) { - len = len + strlen(attr2.u.str); - } - buffer=g_alloca(sizeof(char)*len); - d=(struct duplicate *)buffer; - if (!item_coord_get(item, &d->c, 1)) { - d->c.x=0; - d->c.y=0; - } - strcpy(d->str, attr.u.str); - if(attr_type2 && attr2.u.str){ - strcat(d->str,attr2.u.str); - } - binfile_coord_rewind(item->priv_data); - binfile_attr_rewind(item->priv_data); - if (!g_hash_table_lookup(msp->search_results, d)) { - struct duplicate *dr=g_malloc(len); - memcpy(dr, d, len); - return dr; - } - return NULL; +duplicate_test(struct map_search_priv *msp, struct item *item, enum attr_type attr_type, enum attr_type attr_type2) { + struct attr attr; + struct attr attr2; + int len; + char *buffer; + struct duplicate *d; + + if (!msp->search_results) + msp->search_results = g_hash_table_new_full(duplicate_hash, duplicate_equal, g_free, NULL); + binfile_attr_rewind(item->priv_data); + if (!item_attr_get(item, attr_type, &attr)) + return NULL; + len=sizeof(struct coord)+strlen(attr.u.str)+1; + binfile_attr_rewind(item->priv_data); + if (attr_type2 && item_attr_get(item, attr_type2, &attr2) && attr2.u.str) { + len = len + strlen(attr2.u.str); + } + buffer=g_alloca(sizeof(char)*len); + d=(struct duplicate *)buffer; + if (!item_coord_get(item, &d->c, 1)) { + d->c.x=0; + d->c.y=0; + } + strcpy(d->str, attr.u.str); + if(attr_type2 && attr2.u.str) { + strcat(d->str,attr2.u.str); + } + binfile_coord_rewind(item->priv_data); + binfile_attr_rewind(item->priv_data); + if (!g_hash_table_lookup(msp->search_results, d)) { + struct duplicate *dr=g_malloc(len); + memcpy(dr, d, len); + return dr; + } + return NULL; } /** @@ -2221,9 +2153,8 @@ struct attr attr; * @param duplicate Duplicate info to insert */ static void -duplicate_insert(struct map_search_priv *msp, struct duplicate *d) -{ - g_hash_table_insert(msp->search_results, d, GINT_TO_POINTER(1)); +duplicate_insert(struct map_search_priv *msp, struct duplicate *d) { + g_hash_table_insert(msp->search_results, d, GINT_TO_POINTER(1)); } /** @@ -2236,618 +2167,598 @@ duplicate_insert(struct map_search_priv *msp, struct duplicate *d) * 1 if item is duplicate or doesn't have required attr_type attribute */ static int -duplicate(struct map_search_priv *msp, struct item *item, enum attr_type attr_type, enum attr_type attr_type2) -{ - struct duplicate *d=duplicate_test(msp, item, attr_type, attr_type2); - if(!d) - return 1; - duplicate_insert(msp,d); - return 0; +duplicate(struct map_search_priv *msp, struct item *item, enum attr_type attr_type, enum attr_type attr_type2) { + struct duplicate *d=duplicate_test(msp, item, attr_type, attr_type2); + if(!d) + return 1; + duplicate_insert(msp,d); + return 0; } static int -item_inside_poly_list(struct item *it, GList *l) -{ +item_inside_poly_list(struct item *it, GList *l) { - while(l) { - struct geom_poly_segment *p=l->data; - int count=p->last-p->first+1; - struct coord c; - int ccount; - item_coord_rewind(it); - ccount=binfile_coord_left(it->priv_data); - if(ccount==1) - item_coord_get(it,&c,1); - else if(ccount==2) { - struct coord c2; - item_coord_get(it,&c,1); - item_coord_get(it,&c2,1); - c.x=(c.x+c2.x)/2; - c.y=(c.y+c2.y)/2; - } else { - if(ccount>3) - ccount/=2; - else - ccount=2; - while(--ccount>0) - item_coord_get(it,&c,1); - } - if(geom_poly_point_inside(p->first,count,&c)) - return 1; - l=g_list_next(l); - } - return 0; + while(l) { + struct geom_poly_segment *p=l->data; + int count=p->last-p->first+1; + struct coord c; + int ccount; + item_coord_rewind(it); + ccount=binfile_coord_left(it->priv_data); + if(ccount==1) + item_coord_get(it,&c,1); + else if(ccount==2) { + struct coord c2; + item_coord_get(it,&c,1); + item_coord_get(it,&c2,1); + c.x=(c.x+c2.x)/2; + c.y=(c.y+c2.y)/2; + } else { + if(ccount>3) + ccount/=2; + else + ccount=2; + while(--ccount>0) + item_coord_get(it,&c,1); + } + if(geom_poly_point_inside(p->first,count,&c)) + return 1; + l=g_list_next(l); + } + return 0; } static struct item * -binmap_search_get_item(struct map_search_priv *map_search) -{ - struct item* it; - struct attr at; - enum linguistics_cmp_mode mode=(map_search->partial?linguistics_cmp_partial:0); - - for (;;) { - while ((it = map_rect_get_item_binfile(map_search->mr))) { - int has_house_number=0; - switch (map_search->search.type) { - case attr_town_postal: - case attr_town_name: - case attr_district_name: - case attr_town_or_district_name: - if (map_search->mr->tile_depth > 1 && item_is_town(*it) && map_search->search.type == attr_town_postal) { - if (binfile_attr_get(it->priv_data, attr_town_postal, &at)) { - if (!linguistics_compare(at.u.str, map_search->search.u.str, mode)) { - /* check for duplicate combination of town_name and town_postal */ - if (!duplicate(map_search, it, attr_town_name, attr_town_postal)) { - return it; - } else { - break; - } - } - } - } - if (map_search->mr->tile_depth > 1 && item_is_town(*it) && map_search->search.type != attr_district_name) { - if (binfile_attr_get(it->priv_data, attr_town_name_match, &at) || binfile_attr_get(it->priv_data, attr_town_name, &at)) { - if (!linguistics_compare(at.u.str, map_search->search.u.str, mode) && !duplicate(map_search, it, attr_town_name,0)) - return it; - } - } - if (map_search->mr->tile_depth > 1 && item_is_district(*it) && map_search->search.type != attr_town_name) { - if (binfile_attr_get(it->priv_data, attr_district_name_match, &at) || binfile_attr_get(it->priv_data, attr_district_name, &at)) { - if (!linguistics_compare(at.u.str, map_search->search.u.str, mode) && !duplicate(map_search, it, attr_town_name,0)) - return it; - } - } - break; - case attr_street_name: - if (map_search->mode == 1) { - if (binfile_attr_get(it->priv_data, attr_street_name_match, &at) || binfile_attr_get(it->priv_data, attr_street_name, &at)) { - if (!linguistics_compare(at.u.str, map_search->search.u.str, mode) && !duplicate(map_search, it, attr_street_name,0)) { - return it; - } - } - continue; - } - if (item_is_street(*it)) { - struct attr at; - if (!map_selection_contains_item_rect(map_search->mr->sel, it)) - break; - - if(binfile_attr_get(it->priv_data, attr_label, &at)) { - struct coord c[128]; - struct duplicate *d; - - /* Extracting all coords here makes duplicate_new() not consider them (we don't want all - * street segments to be reported as separate streets). */ - while(item_coord_get(it,c,128)>0); - d=duplicate_test(map_search, it, attr_label,0); - if(!d) - break; - - if(linguistics_compare(at.u.str, map_search->search.u.str, mode|linguistics_cmp_expand|linguistics_cmp_words)) { - /* Remember this non-matching street name in duplicate hash to skip name - * comparison for its following segments */ - duplicate_insert(map_search, d); - break; - } - - if(map_search->boundaries && !item_inside_poly_list(it,map_search->boundaries)) { - /* Other segments may fit the town poly. Do not update hash for now. */ - g_free(d); - break; - } - - duplicate_insert(map_search, d); - item_coord_rewind(it); - return it; - } - } - break; - case attr_house_number: - has_house_number=binfile_attr_get(it->priv_data, attr_house_number, &at); - if ((has_house_number - || it->type == type_house_number_interpolation_even || it->type == type_house_number_interpolation_odd - || it->type == type_house_number_interpolation_all - || (map_search->mode == 1 && item_is_street(*it))|| it->type == type_house_number) - && !(map_search->boundaries && !item_inside_poly_list(it,map_search->boundaries))) - { - if (has_house_number) - { - struct attr at2; - if ((binfile_attr_get(it->priv_data, attr_street_name, &at2) || map_search->mode!=2) && !linguistics_compare(at.u.str, map_search->search.u.str, mode) - && !strcmp(at2.u.str, map_search->parent_name)) - { - if (!duplicate(map_search, it, attr_house_number,0)) - { - binfile_attr_rewind(it->priv_data); - return it; - } - } - } - else - { - struct attr at2; - if ((binfile_attr_get(it->priv_data, attr_street_name, &at2) || map_search->mode!=2) && !strcmp(at2.u.str, map_search->parent_name)) - { - if (!duplicate(map_search, it, attr_house_number_interpolation_no_ends_incrmt_2,0)) - { - binfile_attr_rewind(it->priv_data); - return it; - } - else if (!duplicate(map_search, it, attr_house_number_interpolation_no_ends_incrmt_1,0)) - { - binfile_attr_rewind(it->priv_data); - return it; - } - } else { - if (!( it->type == type_house_number_interpolation_even || it->type == type_house_number_interpolation_odd - || it->type == type_house_number_interpolation_all)) - return it; - } - - } - } else if( item_is_street(*it) && map_search->mode==2 && map_search->parent_name && binfile_attr_get(it->priv_data, attr_street_name, &at) && !strcmp(at.u.str, map_search->parent_name) ) - { - /* If matching street segment found, prepare to expand house number search region +100m around each way point */ - if (!(map_search->boundaries && !item_inside_poly_list(it,map_search->boundaries))) - { - struct coord c; - while(item_coord_get(it,&c,1)) - { - c.x-=100; - c.y-=100; - coord_rect_extend(&map_search->rect_new,&c); - c.x+=200; - c.y+=200; - coord_rect_extend(&map_search->rect_new,&c); - } - } - } - continue; - default: - return NULL; - } - } - if(map_search->search.type==attr_house_number && map_search->mode==2 && map_search->parent_name) { - /* For unindexed house number search, check if street segments extending possible housenumber locations were found */ - if(map_search->ms.u.c_rect.lu.x!=map_search->rect_new.lu.x || map_search->ms.u.c_rect.lu.y!=map_search->rect_new.lu.y || - map_search->ms.u.c_rect.rl.x!=map_search->rect_new.rl.x || map_search->ms.u.c_rect.rl.y!=map_search->rect_new.rl.y) { - map_search->ms.u.c_rect=map_search->rect_new; - map_rect_destroy_binfile(map_search->mr); - map_search->mr=map_rect_new_binfile(map_search->map, &map_search->ms); - dbg(lvl_debug,"Extended house number search region to %d x %d, restarting...",map_search->ms.u.c_rect.rl.x - map_search->ms.u.c_rect.lu.x, map_search->ms.u.c_rect.lu.y-map_search->ms.u.c_rect.rl.y); - continue; - } - } - if (!map_search->mr_item) - return NULL; - map_rect_destroy_binfile(map_search->mr); - if (!binmap_search_by_index(map_search->map, map_search->item, &map_search->mr)) - return NULL; - } +binmap_search_get_item(struct map_search_priv *map_search) { + struct item* it; + struct attr at; + enum linguistics_cmp_mode mode=(map_search->partial?linguistics_cmp_partial:0); + + for (;;) { + while ((it = map_rect_get_item_binfile(map_search->mr))) { + int has_house_number=0; + switch (map_search->search.type) { + case attr_town_postal: + case attr_town_name: + case attr_district_name: + case attr_town_or_district_name: + if (map_search->mr->tile_depth > 1 && item_is_town(*it) && map_search->search.type == attr_town_postal) { + if (binfile_attr_get(it->priv_data, attr_town_postal, &at)) { + if (!linguistics_compare(at.u.str, map_search->search.u.str, mode)) { + /* check for duplicate combination of town_name and town_postal */ + if (!duplicate(map_search, it, attr_town_name, attr_town_postal)) { + return it; + } else { + break; + } + } + } + } + if (map_search->mr->tile_depth > 1 && item_is_town(*it) && map_search->search.type != attr_district_name) { + if (binfile_attr_get(it->priv_data, attr_town_name_match, &at) + || binfile_attr_get(it->priv_data, attr_town_name, &at)) { + if (!linguistics_compare(at.u.str, map_search->search.u.str, mode) && !duplicate(map_search, it, attr_town_name,0)) + return it; + } + } + if (map_search->mr->tile_depth > 1 && item_is_district(*it) && map_search->search.type != attr_town_name) { + if (binfile_attr_get(it->priv_data, attr_district_name_match, &at) + || binfile_attr_get(it->priv_data, attr_district_name, &at)) { + if (!linguistics_compare(at.u.str, map_search->search.u.str, mode) && !duplicate(map_search, it, attr_town_name,0)) + return it; + } + } + break; + case attr_street_name: + if (map_search->mode == 1) { + if (binfile_attr_get(it->priv_data, attr_street_name_match, &at) + || binfile_attr_get(it->priv_data, attr_street_name, &at)) { + if (!linguistics_compare(at.u.str, map_search->search.u.str, mode) && !duplicate(map_search, it, attr_street_name,0)) { + return it; + } + } + continue; + } + if (item_is_street(*it)) { + struct attr at; + if (!map_selection_contains_item_rect(map_search->mr->sel, it)) + break; + + if(binfile_attr_get(it->priv_data, attr_label, &at)) { + struct coord c[128]; + struct duplicate *d; + + /* Extracting all coords here makes duplicate_new() not consider them (we don't want all + * street segments to be reported as separate streets). */ + while(item_coord_get(it,c,128)>0); + d=duplicate_test(map_search, it, attr_label,0); + if(!d) + break; + + if(linguistics_compare(at.u.str, map_search->search.u.str, mode|linguistics_cmp_expand|linguistics_cmp_words)) { + /* Remember this non-matching street name in duplicate hash to skip name + * comparison for its following segments */ + duplicate_insert(map_search, d); + break; + } + + if(map_search->boundaries && !item_inside_poly_list(it,map_search->boundaries)) { + /* Other segments may fit the town poly. Do not update hash for now. */ + g_free(d); + break; + } + + duplicate_insert(map_search, d); + item_coord_rewind(it); + return it; + } + } + break; + case attr_house_number: + has_house_number=binfile_attr_get(it->priv_data, attr_house_number, &at); + if ((has_house_number + || it->type == type_house_number_interpolation_even || it->type == type_house_number_interpolation_odd + || it->type == type_house_number_interpolation_all + || (map_search->mode == 1 && item_is_street(*it))|| it->type == type_house_number) + && !(map_search->boundaries && !item_inside_poly_list(it,map_search->boundaries))) { + if (has_house_number) { + struct attr at2; + if ((binfile_attr_get(it->priv_data, attr_street_name, &at2) || map_search->mode!=2) + && !linguistics_compare(at.u.str, map_search->search.u.str, mode) + && !strcmp(at2.u.str, map_search->parent_name)) { + if (!duplicate(map_search, it, attr_house_number,0)) { + binfile_attr_rewind(it->priv_data); + return it; + } + } + } else { + struct attr at2; + if ((binfile_attr_get(it->priv_data, attr_street_name, &at2) || map_search->mode!=2) + && !strcmp(at2.u.str, map_search->parent_name)) { + if (!duplicate(map_search, it, attr_house_number_interpolation_no_ends_incrmt_2,0)) { + binfile_attr_rewind(it->priv_data); + return it; + } else if (!duplicate(map_search, it, attr_house_number_interpolation_no_ends_incrmt_1,0)) { + binfile_attr_rewind(it->priv_data); + return it; + } + } else { + if (!( it->type == type_house_number_interpolation_even || it->type == type_house_number_interpolation_odd + || it->type == type_house_number_interpolation_all)) + return it; + } + + } + } else if( item_is_street(*it) && map_search->mode==2 && map_search->parent_name + && binfile_attr_get(it->priv_data, attr_street_name, &at) && !strcmp(at.u.str, map_search->parent_name) ) { + /* If matching street segment found, prepare to expand house number search region +100m around each way point */ + if (!(map_search->boundaries && !item_inside_poly_list(it,map_search->boundaries))) { + struct coord c; + while(item_coord_get(it,&c,1)) { + c.x-=100; + c.y-=100; + coord_rect_extend(&map_search->rect_new,&c); + c.x+=200; + c.y+=200; + coord_rect_extend(&map_search->rect_new,&c); + } + } + } + continue; + default: + return NULL; + } + } + if(map_search->search.type==attr_house_number && map_search->mode==2 && map_search->parent_name) { + /* For unindexed house number search, check if street segments extending possible housenumber locations were found */ + if(map_search->ms.u.c_rect.lu.x!=map_search->rect_new.lu.x || map_search->ms.u.c_rect.lu.y!=map_search->rect_new.lu.y || + map_search->ms.u.c_rect.rl.x!=map_search->rect_new.rl.x || map_search->ms.u.c_rect.rl.y!=map_search->rect_new.rl.y) { + map_search->ms.u.c_rect=map_search->rect_new; + map_rect_destroy_binfile(map_search->mr); + map_search->mr=map_rect_new_binfile(map_search->map, &map_search->ms); + dbg(lvl_debug,"Extended house number search region to %d x %d, restarting...", + map_search->ms.u.c_rect.rl.x - map_search->ms.u.c_rect.lu.x, map_search->ms.u.c_rect.lu.y-map_search->ms.u.c_rect.rl.y); + continue; + } + } + if (!map_search->mr_item) + return NULL; + map_rect_destroy_binfile(map_search->mr); + if (!binmap_search_by_index(map_search->map, map_search->item, &map_search->mr)) + return NULL; + } } static void -binmap_search_destroy(struct map_search_priv *ms) -{ - if (ms->search_results) - g_hash_table_destroy(ms->search_results); - if(ATTR_IS_STRING(ms->search.type)) - g_free(ms->search.u.str); - if(ms->parent_name) - g_free(ms->parent_name); - if (ms->mr_item) - map_rect_destroy_binfile(ms->mr_item); - if (ms->mr) - map_rect_destroy_binfile(ms->mr); - while(ms->boundaries) { - geom_poly_segment_destroy(ms->boundaries->data); - ms->boundaries=g_list_delete_link(ms->boundaries,ms->boundaries); - } - g_free(ms); +binmap_search_destroy(struct map_search_priv *ms) { + if (ms->search_results) + g_hash_table_destroy(ms->search_results); + if(ATTR_IS_STRING(ms->search.type)) + g_free(ms->search.u.str); + if(ms->parent_name) + g_free(ms->parent_name); + if (ms->mr_item) + map_rect_destroy_binfile(ms->mr_item); + if (ms->mr) + map_rect_destroy_binfile(ms->mr); + while(ms->boundaries) { + geom_poly_segment_destroy(ms->boundaries->data); + ms->boundaries=g_list_delete_link(ms->boundaries,ms->boundaries); + } + g_free(ms); } static int -binmap_get_attr(struct map_priv *m, enum attr_type type, struct attr *attr) -{ - attr->type=type; - switch (type) { - case attr_map_release: - if (m->map_release) { - attr->u.str=m->map_release; - return 1; - } - break; - case attr_progress: - if (m->progress) { - attr->u.str=m->progress; - return 1; - } - default: - break; - } - return 0; +binmap_get_attr(struct map_priv *m, enum attr_type type, struct attr *attr) { + attr->type=type; + switch (type) { + case attr_map_release: + if (m->map_release) { + attr->u.str=m->map_release; + return 1; + } + break; + case attr_progress: + if (m->progress) { + attr->u.str=m->progress; + return 1; + } + default: + break; + } + return 0; } static int -binmap_set_attr(struct map_priv *map, struct attr *attr) -{ - switch (attr->type) { - case attr_update: - map->download_enabled = attr->u.num; - return 1; - default: - return 0; - } +binmap_set_attr(struct map_priv *map, struct attr *attr) { + switch (attr->type) { + case attr_update: + map->download_enabled = attr->u.num; + return 1; + default: + return 0; + } } static struct map_methods map_methods_binfile = { - projection_mg, - "utf-8", - map_destroy_binfile, - map_rect_new_binfile, - map_rect_destroy_binfile, - map_rect_get_item_binfile, - map_rect_get_item_byid_binfile, - binmap_search_new, - binmap_search_destroy, - binmap_search_get_item, - NULL, - binmap_get_attr, - binmap_set_attr, + projection_mg, + "utf-8", + map_destroy_binfile, + map_rect_new_binfile, + map_rect_destroy_binfile, + map_rect_get_item_binfile, + map_rect_get_item_byid_binfile, + binmap_search_new, + binmap_search_destroy, + binmap_search_get_item, + NULL, + binmap_get_attr, + binmap_set_attr, }; static int -binfile_get_index(struct map_priv *m) -{ - int len; - int cde_index_size; - int offset; - struct zip_cd *cd; - - len = strlen("index"); - cde_index_size = sizeof(struct zip_cd)+len; - if (m->eoc64) - offset = m->eoc64->zip64ecsz-cde_index_size; - else - offset = m->eoc->zipecsz-cde_index_size; - cd = binfile_read_cd(m, offset, len); - - if (!cd) { - cde_index_size+=sizeof(struct zip_cd_ext); - if (m->eoc64) - offset = m->eoc64->zip64ecsz-cde_index_size; - else - offset = m->eoc->zipecsz-cde_index_size; - cd = binfile_read_cd(m, offset, len+sizeof(struct zip_cd_ext)); - } - if (cd) { - if (cd->zipcfnl == len && !strncmp(cd->zipcfn, "index", len)) { - m->index_offset=offset; - m->index_cd=cd; - return 1; - } - } - offset=binfile_search_cd(m, 0, "index", 0, 0); - if (offset == -1) - return 0; - cd=binfile_read_cd(m, offset, -1); - if (!cd) - return 0; - m->index_offset=offset; - m->index_cd=cd; - return 1; +binfile_get_index(struct map_priv *m) { + int len; + int cde_index_size; + int offset; + struct zip_cd *cd; + + len = strlen("index"); + cde_index_size = sizeof(struct zip_cd)+len; + if (m->eoc64) + offset = m->eoc64->zip64ecsz-cde_index_size; + else + offset = m->eoc->zipecsz-cde_index_size; + cd = binfile_read_cd(m, offset, len); + + if (!cd) { + cde_index_size+=sizeof(struct zip_cd_ext); + if (m->eoc64) + offset = m->eoc64->zip64ecsz-cde_index_size; + else + offset = m->eoc->zipecsz-cde_index_size; + cd = binfile_read_cd(m, offset, len+sizeof(struct zip_cd_ext)); + } + if (cd) { + if (cd->zipcfnl == len && !strncmp(cd->zipcfn, "index", len)) { + m->index_offset=offset; + m->index_cd=cd; + return 1; + } + } + offset=binfile_search_cd(m, 0, "index", 0, 0); + if (offset == -1) + return 0; + cd=binfile_read_cd(m, offset, -1); + if (!cd) + return 0; + m->index_offset=offset; + m->index_cd=cd; + return 1; } static int -map_binfile_zip_setup(struct map_priv *m, char *filename, int mmap) -{ - struct zip_cd *first_cd; - int i; - if (!(m->eoc=binfile_read_eoc(m->fi))) { - dbg(lvl_error,"map file %s: unable to read eoc", filename); - return 0; - } - dbg_assert(m->eoc->zipedsk == m->eoc->zipecen); - if (m->eoc->zipedsk && strlen(filename) > 3) { - char *tmpfilename=g_strdup(filename),*ext=tmpfilename+strlen(tmpfilename)-3; - m->fis=g_new(struct file *,m->eoc->zipedsk); - for (i = 0 ; i < m->eoc->zipedsk-1 ; i++) { - sprintf(ext,"b%02d",i+1); - m->fis[i]=file_create(tmpfilename, 0); - if (mmap) - file_mmap(m->fis[i]); - } - m->fis[m->eoc->zipedsk-1]=m->fi; - g_free(tmpfilename); - } - dbg(lvl_debug,"num_disk %d",m->eoc->zipedsk); - m->eoc64=binfile_read_eoc64(m->fi); - if (!binfile_get_index(m)) { - dbg(lvl_error,"map file %s: no index found", filename); - return 0; - } - if (!(first_cd=binfile_read_cd(m, 0, 0))) { - dbg(lvl_error,"map file %s: unable to get first cd", filename); - return 0; - } - m->cde_size=sizeof(struct zip_cd)+first_cd->zipcfnl+first_cd->zipcxtl; - m->zip_members=m->index_offset/m->cde_size+1; - dbg(lvl_debug,"cde_size %d", m->cde_size); - dbg(lvl_debug,"members %d",m->zip_members); - file_data_free(m->fi, (unsigned char *)first_cd); - if (mmap) - file_mmap(m->fi); - return 1; +map_binfile_zip_setup(struct map_priv *m, char *filename, int mmap) { + struct zip_cd *first_cd; + int i; + if (!(m->eoc=binfile_read_eoc(m->fi))) { + dbg(lvl_error,"map file %s: unable to read eoc", filename); + return 0; + } + dbg_assert(m->eoc->zipedsk == m->eoc->zipecen); + if (m->eoc->zipedsk && strlen(filename) > 3) { + char *tmpfilename=g_strdup(filename),*ext=tmpfilename+strlen(tmpfilename)-3; + m->fis=g_new(struct file *,m->eoc->zipedsk); + for (i = 0 ; i < m->eoc->zipedsk-1 ; i++) { + sprintf(ext,"b%02d",i+1); + m->fis[i]=file_create(tmpfilename, 0); + if (mmap) + file_mmap(m->fis[i]); + } + m->fis[m->eoc->zipedsk-1]=m->fi; + g_free(tmpfilename); + } + dbg(lvl_debug,"num_disk %d",m->eoc->zipedsk); + m->eoc64=binfile_read_eoc64(m->fi); + if (!binfile_get_index(m)) { + dbg(lvl_error,"map file %s: no index found", filename); + return 0; + } + if (!(first_cd=binfile_read_cd(m, 0, 0))) { + dbg(lvl_error,"map file %s: unable to get first cd", filename); + return 0; + } + m->cde_size=sizeof(struct zip_cd)+first_cd->zipcfnl+first_cd->zipcxtl; + m->zip_members=m->index_offset/m->cde_size+1; + dbg(lvl_debug,"cde_size %d", m->cde_size); + dbg(lvl_debug,"members %d",m->zip_members); + file_data_free(m->fi, (unsigned char *)first_cd); + if (mmap) + file_mmap(m->fi); + return 1; } #if 0 static int -map_binfile_download_initial(struct map_priv *m) -{ - struct attr readwrite={attr_readwrite,{(void *)1}}; - struct attr create={attr_create,{(void *)1}}; - struct attr *attrs[4]; - struct file *out; - long long woffset=0,planet_size; - int size_ret; - int cd1size,cdisize; - long long cd1offset,cdioffset; - struct zip64_eoc *zip64_eoc; - struct zip64_eocl *zip64_eocl; - struct zip_eoc *zip_eoc; - struct zip_cd *cd1,*cdn,*cdi; - int count,chunk,cdoffset=0; - int mode=1; - struct map_download *download=g_new0(struct map_download, 1); - - attrs[0]=&readwrite; - attrs[1]=&create; - attrs[2]=NULL; - download->file=file_create(m->filename,attrs); - download->m=m; - download_planet_size(download); - download_eoc(download); - download_directory_start(download); - while (download_directory_do(download)); - download_directory_finish(download); - download_initial_finish(download); - m->fi=download->file; - g_free(download); - return 1; - - - cd1size=sizeof(*cd1); - cd1offset=zip64_eoc->zip64eofst; - cd1=(struct zip_cd *)map_binfile_download_range(m, cd1offset, cd1size); - if (!cd1) - return 0; - cd1size=sizeof(*cd1)+binfile_cd_extra(cd1); - g_free(cd1); - cd1=(struct zip_cd *)map_binfile_download_range(m, cd1offset, cd1size); - if (!cd1) - return 0; - cd1->zipcunc=0; - cdisize=sizeof(*cdi)+strlen("index")+cd1->zipcxtl; - cdioffset=zip64_eoc->zip64eofst+zip64_eoc->zip64ecsz-cdisize; - cdi=(struct zip_cd *)map_binfile_download_range(m, cdioffset, cdisize); - if (!cdi) { - g_free(cd1); - return 0; - } - cdi->zipcunc=0; - cdn=g_malloc0(cd1size*256); - - file_data_write(out, woffset, sizeof(*zip64_eoc), (unsigned char *)zip64_eoc); - woffset+=sizeof(*zip64_eoc); - cdoffset=woffset; - - file_data_write(out, woffset, cd1size, (unsigned char *)cd1); - woffset+=cd1size; - count=(cdioffset-cd1offset)/cd1size-1; - while (count > 0) { - if (count > 256) - chunk=256; - else - chunk=count; - file_data_write(out, woffset, cd1size*chunk, (unsigned char *)cdn); - woffset+=cd1size*chunk; - count-=chunk; - } - g_free(cdn); - g_free(cd1); - file_data_write(out, woffset, cdisize, (unsigned char *)cdi); - woffset+=cdisize; +map_binfile_download_initial(struct map_priv *m) { + struct attr readwrite= {attr_readwrite,{(void *)1}}; + struct attr create= {attr_create,{(void *)1}}; + struct attr *attrs[4]; + struct file *out; + long long woffset=0,planet_size; + int size_ret; + int cd1size,cdisize; + long long cd1offset,cdioffset; + struct zip64_eoc *zip64_eoc; + struct zip64_eocl *zip64_eocl; + struct zip_eoc *zip_eoc; + struct zip_cd *cd1,*cdn,*cdi; + int count,chunk,cdoffset=0; + int mode=1; + struct map_download *download=g_new0(struct map_download, 1); + + attrs[0]=&readwrite; + attrs[1]=&create; + attrs[2]=NULL; + download->file=file_create(m->filename,attrs); + download->m=m; + download_planet_size(download); + download_eoc(download); + download_directory_start(download); + while (download_directory_do(download)); + download_directory_finish(download); + download_initial_finish(download); + m->fi=download->file; + g_free(download); + return 1; + + + cd1size=sizeof(*cd1); + cd1offset=zip64_eoc->zip64eofst; + cd1=(struct zip_cd *)map_binfile_download_range(m, cd1offset, cd1size); + if (!cd1) + return 0; + cd1size=sizeof(*cd1)+binfile_cd_extra(cd1); + g_free(cd1); + cd1=(struct zip_cd *)map_binfile_download_range(m, cd1offset, cd1size); + if (!cd1) + return 0; + cd1->zipcunc=0; + cdisize=sizeof(*cdi)+strlen("index")+cd1->zipcxtl; + cdioffset=zip64_eoc->zip64eofst+zip64_eoc->zip64ecsz-cdisize; + cdi=(struct zip_cd *)map_binfile_download_range(m, cdioffset, cdisize); + if (!cdi) { + g_free(cd1); + return 0; + } + cdi->zipcunc=0; + cdn=g_malloc0(cd1size*256); + + file_data_write(out, woffset, sizeof(*zip64_eoc), (unsigned char *)zip64_eoc); + woffset+=sizeof(*zip64_eoc); + cdoffset=woffset; + + file_data_write(out, woffset, cd1size, (unsigned char *)cd1); + woffset+=cd1size; + count=(cdioffset-cd1offset)/cd1size-1; + while (count > 0) { + if (count > 256) + chunk=256; + else + chunk=count; + file_data_write(out, woffset, cd1size*chunk, (unsigned char *)cdn); + woffset+=cd1size*chunk; + count-=chunk; + } + g_free(cdn); + g_free(cd1); + file_data_write(out, woffset, cdisize, (unsigned char *)cdi); + woffset+=cdisize; } #endif static int -map_binfile_open(struct map_priv *m) -{ - int *magic; - struct map_rect_priv *mr; - struct item *item; - struct attr attr; - struct attr readwrite={attr_readwrite, {(void *)1}}; - struct attr *attrs[]={&readwrite, NULL}; - - dbg(lvl_debug,"file_create %s", m->filename); - m->fi=file_create(m->filename, m->url?attrs:NULL); - if (! m->fi && m->url) - return 0; - if (! m->fi) { - dbg(lvl_error,"Failed to load '%s'", m->filename); - return 0; - } - if (m->check_version) - m->version=file_version(m->fi, m->check_version); - magic=(int *)file_data_read(m->fi, 0, 4); - if (!magic) { - file_destroy(m->fi); - m->fi=NULL; - return 0; - } - *magic = le32_to_cpu(*magic); - if (*magic == zip_lfh_sig || *magic == zip_split_sig || *magic == zip_cd_sig || *magic == zip64_eoc_sig) { - if (!map_binfile_zip_setup(m, m->filename, m->flags & 1)) { - dbg(lvl_error,"invalid file format for '%s'", m->filename); - file_destroy(m->fi); - m->fi=NULL; - return 0; - } - } else if (*magic == zip_lfh_sig_rev || *magic == zip_split_sig_rev || *magic == zip_cd_sig_rev || *magic == zip64_eoc_sig_rev) { - dbg(lvl_error,"endianness mismatch for '%s'", m->filename); - file_destroy(m->fi); - m->fi=NULL; - return 0; - } else - file_mmap(m->fi); - file_data_free(m->fi, (unsigned char *)magic); - m->cachedir=g_strdup("/tmp/navit"); - m->map_version=0; - mr=map_rect_new_binfile(m, NULL); - if (mr) { - while ((item=map_rect_get_item_binfile(mr)) == &busy_item); - if (item && item->type == type_map_information) { - if (binfile_attr_get(item->priv_data, attr_version, &attr)) - m->map_version=attr.u.num; - if (binfile_attr_get(item->priv_data, attr_map_release, &attr)) - m->map_release=g_strdup(attr.u.str); - if (m->url && binfile_attr_get(item->priv_data, attr_url, &attr)) { - dbg(lvl_debug,"url config %s map %s",m->url,attr.u.str); - if (strcmp(m->url, attr.u.str)) - m->update_available=1; - g_free(m->url); - m->url=g_strdup(attr.u.str); - } - } - map_rect_destroy_binfile(mr); - if (m->map_version >= 16) { - dbg(lvl_error,"%s: This map is incompatible with your navit version. Please update navit. (map version %d)", - m->filename, m->map_version); - return 0; - } - } - return 1; +map_binfile_open(struct map_priv *m) { + int *magic; + struct map_rect_priv *mr; + struct item *item; + struct attr attr; + struct attr readwrite= {attr_readwrite, {(void *)1}}; + struct attr *attrs[]= {&readwrite, NULL}; + + dbg(lvl_debug,"file_create %s", m->filename); + m->fi=file_create(m->filename, m->url?attrs:NULL); + if (! m->fi && m->url) + return 0; + if (! m->fi) { + dbg(lvl_error,"Failed to load '%s'", m->filename); + return 0; + } + if (m->check_version) + m->version=file_version(m->fi, m->check_version); + magic=(int *)file_data_read(m->fi, 0, 4); + if (!magic) { + file_destroy(m->fi); + m->fi=NULL; + return 0; + } + *magic = le32_to_cpu(*magic); + if (*magic == zip_lfh_sig || *magic == zip_split_sig || *magic == zip_cd_sig || *magic == zip64_eoc_sig) { + if (!map_binfile_zip_setup(m, m->filename, m->flags & 1)) { + dbg(lvl_error,"invalid file format for '%s'", m->filename); + file_destroy(m->fi); + m->fi=NULL; + return 0; + } + } else if (*magic == zip_lfh_sig_rev || *magic == zip_split_sig_rev || *magic == zip_cd_sig_rev + || *magic == zip64_eoc_sig_rev) { + dbg(lvl_error,"endianness mismatch for '%s'", m->filename); + file_destroy(m->fi); + m->fi=NULL; + return 0; + } else + file_mmap(m->fi); + file_data_free(m->fi, (unsigned char *)magic); + m->cachedir=g_strdup("/tmp/navit"); + m->map_version=0; + mr=map_rect_new_binfile(m, NULL); + if (mr) { + while ((item=map_rect_get_item_binfile(mr)) == &busy_item); + if (item && item->type == type_map_information) { + if (binfile_attr_get(item->priv_data, attr_version, &attr)) + m->map_version=attr.u.num; + if (binfile_attr_get(item->priv_data, attr_map_release, &attr)) + m->map_release=g_strdup(attr.u.str); + if (m->url && binfile_attr_get(item->priv_data, attr_url, &attr)) { + dbg(lvl_debug,"url config %s map %s",m->url,attr.u.str); + if (strcmp(m->url, attr.u.str)) + m->update_available=1; + g_free(m->url); + m->url=g_strdup(attr.u.str); + } + } + map_rect_destroy_binfile(mr); + if (m->map_version >= 16) { + dbg(lvl_error,"%s: This map is incompatible with your navit version. Please update navit. (map version %d)", + m->filename, m->map_version); + return 0; + } + } + return 1; } static void -map_binfile_close(struct map_priv *m) -{ - int i; - file_data_free(m->fi, (unsigned char *)m->index_cd); - file_data_free(m->fi, (unsigned char *)m->eoc); - file_data_free(m->fi, (unsigned char *)m->eoc64); - g_free(m->cachedir); - g_free(m->map_release); - if (m->fis) { - for (i = 0 ; i < m->eoc->zipedsk ; i++) { - file_destroy(m->fis[i]); - } - } else - file_destroy(m->fi); +map_binfile_close(struct map_priv *m) { + int i; + file_data_free(m->fi, (unsigned char *)m->index_cd); + file_data_free(m->fi, (unsigned char *)m->eoc); + file_data_free(m->fi, (unsigned char *)m->eoc64); + g_free(m->cachedir); + g_free(m->map_release); + if (m->fis) { + for (i = 0 ; i < m->eoc->zipedsk ; i++) { + file_destroy(m->fis[i]); + } + } else + file_destroy(m->fi); } static void -map_binfile_destroy(struct map_priv *m) -{ - g_free(m->filename); - g_free(m->url); - g_free(m->progress); - g_free(m); +map_binfile_destroy(struct map_priv *m) { + g_free(m->filename); + g_free(m->url); + g_free(m->progress); + g_free(m); } static void -binfile_check_version(struct map_priv *m) -{ - int version=-1; - if (!m->check_version) - return; - if (m->fi) - version=file_version(m->fi, m->check_version); - if (version != m->version) { - if (m->fi) - map_binfile_close(m); - map_binfile_open(m); - } +binfile_check_version(struct map_priv *m) { + int version=-1; + if (!m->check_version) + return; + if (m->fi) + version=file_version(m->fi, m->check_version); + if (version != m->version) { + if (m->fi) + map_binfile_close(m); + map_binfile_open(m); + } } static struct map_priv * -map_new_binfile(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) -{ - struct map_priv *m; - struct attr *data=attr_search(attrs, NULL, attr_data); - struct attr *check_version,*flags,*url,*download_enabled; - struct file_wordexp *wexp; - char **wexp_data; - if (! data) - return NULL; - - wexp=file_wordexp_new(data->u.str); - wexp_data=file_wordexp_get_array(wexp); - dbg(lvl_debug,"map_new_binfile %s", data->u.str); - *meth=map_methods_binfile; - - m=g_new0(struct map_priv, 1); - m->cbl=cbl; - m->id=++map_id; - m->filename=g_strdup(wexp_data[0]); - file_wordexp_destroy(wexp); - check_version=attr_search(attrs, NULL, attr_check_version); - if (check_version) - m->check_version=check_version->u.num; - flags=attr_search(attrs, NULL, attr_flags); - if (flags) - m->flags=flags->u.num; - url=attr_search(attrs, NULL, attr_url); - if (url) - m->url=g_strdup(url->u.str); - download_enabled = attr_search(attrs, NULL, attr_update); - if (download_enabled) - m->download_enabled=download_enabled->u.num; - - if (!map_binfile_open(m) && !m->check_version && !m->url) { - map_binfile_destroy(m); - m=NULL; - } else { - load_changes(m); - } - return m; +map_new_binfile(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) { + struct map_priv *m; + struct attr *data=attr_search(attrs, NULL, attr_data); + struct attr *check_version,*flags,*url,*download_enabled; + struct file_wordexp *wexp; + char **wexp_data; + if (! data) + return NULL; + + wexp=file_wordexp_new(data->u.str); + wexp_data=file_wordexp_get_array(wexp); + dbg(lvl_debug,"map_new_binfile %s", data->u.str); + *meth=map_methods_binfile; + + m=g_new0(struct map_priv, 1); + m->cbl=cbl; + m->id=++map_id; + m->filename=g_strdup(wexp_data[0]); + file_wordexp_destroy(wexp); + check_version=attr_search(attrs, NULL, attr_check_version); + if (check_version) + m->check_version=check_version->u.num; + flags=attr_search(attrs, NULL, attr_flags); + if (flags) + m->flags=flags->u.num; + url=attr_search(attrs, NULL, attr_url); + if (url) + m->url=g_strdup(url->u.str); + download_enabled = attr_search(attrs, NULL, attr_update); + if (download_enabled) + m->download_enabled=download_enabled->u.num; + + if (!map_binfile_open(m) && !m->check_version && !m->url) { + map_binfile_destroy(m); + m=NULL; + } else { + load_changes(m); + } + return m; } void -plugin_init(void) -{ - dbg(lvl_debug,"binfile: plugin_init"); - if (sizeof(struct zip_cd) != 46) { - dbg(lvl_error,"error: sizeof(struct zip_cd)=%zu",sizeof(struct zip_cd)); - } - plugin_register_category_map("binfile", map_new_binfile); +plugin_init(void) { + dbg(lvl_debug,"binfile: plugin_init"); + if (sizeof(struct zip_cd) != 46) { + dbg(lvl_error,"error: sizeof(struct zip_cd)=%zu",sizeof(struct zip_cd)); + } + plugin_register_category_map("binfile", map_new_binfile); } diff --git a/navit/map/csv/csv.c b/navit/map/csv/csv.c index 3ee2d6239..5fcaebb4d 100644 --- a/navit/map/csv/csv.c +++ b/navit/map/csv/csv.c @@ -52,335 +52,324 @@ static void quadtree_item_free(void *mr, struct quadtree_item *qitem); static void quadtree_item_free_do(void *qitem); -struct quadtree_data -{ - enum item_type type; - int id_lo; - GList* attr_list; - struct item *item; +struct quadtree_data { + enum item_type type; + int id_lo; + GList* attr_list; + struct item *item; }; -struct quadtree_data *quadtree_data_dup(struct quadtree_data *qdata) -{ - struct quadtree_data *ret=g_new0(struct quadtree_data,1); - GList *l; - ret->type=qdata->type; - ret->id_lo=qdata->id_lo; - ret->item=g_new(struct item,1); - *(ret->item)=*(qdata->item); - for(l=qdata->attr_list;l;l=g_list_next(l)) { - ret->attr_list=g_list_prepend(ret->attr_list,attr_dup(l->data)); - } - return ret; +struct quadtree_data *quadtree_data_dup(struct quadtree_data *qdata) { + struct quadtree_data *ret=g_new0(struct quadtree_data,1); + GList *l; + ret->type=qdata->type; + ret->id_lo=qdata->id_lo; + ret->item=g_new(struct item,1); + *(ret->item)=*(qdata->item); + for(l=qdata->attr_list; l; l=g_list_next(l)) { + ret->attr_list=g_list_prepend(ret->attr_list,attr_dup(l->data)); + } + return ret; } static void -save_map_csv(struct map_priv *m) -{ - if(m->filename && m->dirty) { - char* filename = g_strdup_printf("%s.tmp",m->filename); - FILE* fp; - int ferr = 0; - char *csv_line = 0; - char *tmpstr = 0; - char *oldstr = 0; - struct quadtree_iter *iter; - struct quadtree_item *qitem; - - if( ! (fp=fopen(filename,"w+"))) { - dbg(lvl_error, "Error opening csv file to write new entries"); - return; - } - /*query the world*/ - iter=quadtree_query(m->tree_root, -180, 180, -180, 180, quadtree_item_free, m); - - while((qitem = quadtree_item_next(iter))!=NULL) { - int i; - enum attr_type *at = m->attr_types; - if(qitem->deleted) - continue; - csv_line = NULL; - tmpstr = NULL; - for(i=0;i<m->attr_cnt;++i) { - if(*at == attr_position_latitude) { - tmpstr = g_strdup_printf("%lf",qitem->latitude); - } else if(*at == attr_position_longitude) { - tmpstr = g_strdup_printf("%lf",qitem->longitude); - } else { - GList* attr_list = ((struct quadtree_data*)(qitem->data))->attr_list; - GList* attr_it = attr_list; - struct attr* found_attr = NULL; - /*search attributes*/ - while(attr_it) { - if(((struct attr*)(attr_it->data))->type == *at) { - found_attr = attr_it->data; - break; - } - attr_it = g_list_next(attr_it); - } - if(found_attr) { - if(ATTR_IS_INT(*at)) { - tmpstr = g_strdup_printf("%d", (int)found_attr->u.num); - } else if(ATTR_IS_DOUBLE(*at)) { - tmpstr = g_strdup_printf("%lf", *found_attr->u.numd); - } else if(ATTR_IS_STRING(*at)) { - tmpstr = g_strdup(found_attr->u.str); - } else { - dbg(lvl_error,"Cant represent attribute %s",attr_to_name(*at)); - tmpstr=g_strdup(""); - } - } else { - dbg(lvl_debug,"No value defined for the attribute %s, assuming empty string",attr_to_name(*at)); - tmpstr=g_strdup(""); - } - } - if(i>0) { - oldstr = csv_line; - csv_line = g_strdup_printf("%s,%s",csv_line,tmpstr); - g_free(tmpstr); - g_free(oldstr); - tmpstr = NULL; - } else { - csv_line=tmpstr; - } - ++at; - } - - if(m->charset) { - tmpstr=g_convert(csv_line, -1,m->charset,"utf-8",NULL,NULL,NULL); - if(!tmpstr) - dbg(lvl_error,"Error converting '%s' to %s",csv_line, m->charset); - } else - tmpstr=csv_line; - - if(tmpstr && fprintf(fp,"%s\n", tmpstr)<0) { - ferr = 1; - } - g_free(csv_line); - if(m->charset) - g_free(tmpstr); - } - - if(fclose(fp)) { - ferr = 1; - } - - if(! ferr) { - unlink(m->filename); - rename(filename,m->filename); - m->dirty = 0; - } - g_free(filename); - quadtree_query_free(iter); - - } +save_map_csv(struct map_priv *m) { + if(m->filename && m->dirty) { + char* filename = g_strdup_printf("%s.tmp",m->filename); + FILE* fp; + int ferr = 0; + char *csv_line = 0; + char *tmpstr = 0; + char *oldstr = 0; + struct quadtree_iter *iter; + struct quadtree_item *qitem; + + if( ! (fp=fopen(filename,"w+"))) { + dbg(lvl_error, "Error opening csv file to write new entries"); + return; + } + /*query the world*/ + iter=quadtree_query(m->tree_root, -180, 180, -180, 180, quadtree_item_free, m); + + while((qitem = quadtree_item_next(iter))!=NULL) { + int i; + enum attr_type *at = m->attr_types; + if(qitem->deleted) + continue; + csv_line = NULL; + tmpstr = NULL; + for(i=0; i<m->attr_cnt; ++i) { + if(*at == attr_position_latitude) { + tmpstr = g_strdup_printf("%lf",qitem->latitude); + } else if(*at == attr_position_longitude) { + tmpstr = g_strdup_printf("%lf",qitem->longitude); + } else { + GList* attr_list = ((struct quadtree_data*)(qitem->data))->attr_list; + GList* attr_it = attr_list; + struct attr* found_attr = NULL; + /*search attributes*/ + while(attr_it) { + if(((struct attr*)(attr_it->data))->type == *at) { + found_attr = attr_it->data; + break; + } + attr_it = g_list_next(attr_it); + } + if(found_attr) { + if(ATTR_IS_INT(*at)) { + tmpstr = g_strdup_printf("%d", (int)found_attr->u.num); + } else if(ATTR_IS_DOUBLE(*at)) { + tmpstr = g_strdup_printf("%lf", *found_attr->u.numd); + } else if(ATTR_IS_STRING(*at)) { + tmpstr = g_strdup(found_attr->u.str); + } else { + dbg(lvl_error,"Cant represent attribute %s",attr_to_name(*at)); + tmpstr=g_strdup(""); + } + } else { + dbg(lvl_debug,"No value defined for the attribute %s, assuming empty string",attr_to_name(*at)); + tmpstr=g_strdup(""); + } + } + if(i>0) { + oldstr = csv_line; + csv_line = g_strdup_printf("%s,%s",csv_line,tmpstr); + g_free(tmpstr); + g_free(oldstr); + tmpstr = NULL; + } else { + csv_line=tmpstr; + } + ++at; + } + + if(m->charset) { + tmpstr=g_convert(csv_line, -1,m->charset,"utf-8",NULL,NULL,NULL); + if(!tmpstr) + dbg(lvl_error,"Error converting '%s' to %s",csv_line, m->charset); + } else + tmpstr=csv_line; + + if(tmpstr && fprintf(fp,"%s\n", tmpstr)<0) { + ferr = 1; + } + g_free(csv_line); + if(m->charset) + g_free(tmpstr); + } + + if(fclose(fp)) { + ferr = 1; + } + + if(! ferr) { + unlink(m->filename); + rename(filename,m->filename); + m->dirty = 0; + } + g_free(filename); + quadtree_query_free(iter); + + } } static const int zoom_max = 18; static void -map_destroy_csv(struct map_priv *m) -{ - dbg(lvl_debug,"map_destroy_csv"); - /*save if changed */ - save_map_csv(m); - g_hash_table_destroy(m->qitem_hash); - quadtree_destroy(m->tree_root); - g_free(m->filename); - g_free(m->charset); - g_free(m->attr_types); - g_free(m); +map_destroy_csv(struct map_priv *m) { + dbg(lvl_debug,"map_destroy_csv"); + /*save if changed */ + save_map_csv(m); + g_hash_table_destroy(m->qitem_hash); + quadtree_destroy(m->tree_root); + g_free(m->filename); + g_free(m->charset); + g_free(m->attr_types); + g_free(m); } static void -csv_coord_rewind(void *priv_data) -{ +csv_coord_rewind(void *priv_data) { } static int -csv_coord_get(void *priv_data, struct coord *c, int count) -{ - struct map_rect_priv *mr=priv_data; - if(mr) { - *c = mr->c; - return 1; - } - else { - return 0; - } +csv_coord_get(void *priv_data, struct coord *c, int count) { + struct map_rect_priv *mr=priv_data; + if(mr) { + *c = mr->c; + return 1; + } else { + return 0; + } } static void -csv_attr_rewind(void *priv_data) -{ - /*TODO implement if needed*/ +csv_attr_rewind(void *priv_data) { + /*TODO implement if needed*/ } static int -csv_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - int i, bAttrFound = 0; - GList* attr_list; - struct map_rect_priv *mr=priv_data; - enum attr_type *at; - if( !mr || !mr->m || !mr->m->attr_types ) { - return 0; - } - - attr_list = ((struct quadtree_data*)(mr->qitem->data))->attr_list; - - if (attr_type == attr_any) { - if (mr->at_iter==NULL) { /*start iteration*/ - mr->at_iter = attr_list; - if (mr->at_iter) { - *attr = *(struct attr*)(mr->at_iter->data); - return 1; - } else { /*empty attr list*/ - mr->at_iter = NULL; - return 0; - } - } else { /*continue iteration*/ - mr->at_iter = g_list_next(mr->at_iter); - if(mr->at_iter) { - *attr = *(struct attr*)mr->at_iter->data; - return 1; - } else { - return 0; - } - } - return 0; - } - - at = mr->m->attr_types; - - for(i=0;i<mr->m->attr_cnt;++i) { - if(*at == attr_type) { - bAttrFound = 1; - break; - } - ++at; - } - - if(!bAttrFound) { - return 0; - } - - while(attr_list) { - if(((struct attr*)attr_list->data)->type == attr_type) { - *attr = *(struct attr*)attr_list->data; - return 1; - } - attr_list = g_list_next(attr_list); - } - return 0; +csv_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + int i, bAttrFound = 0; + GList* attr_list; + struct map_rect_priv *mr=priv_data; + enum attr_type *at; + if( !mr || !mr->m || !mr->m->attr_types ) { + return 0; + } + + attr_list = ((struct quadtree_data*)(mr->qitem->data))->attr_list; + + if (attr_type == attr_any) { + if (mr->at_iter==NULL) { /*start iteration*/ + mr->at_iter = attr_list; + if (mr->at_iter) { + *attr = *(struct attr*)(mr->at_iter->data); + return 1; + } else { /*empty attr list*/ + mr->at_iter = NULL; + return 0; + } + } else { /*continue iteration*/ + mr->at_iter = g_list_next(mr->at_iter); + if(mr->at_iter) { + *attr = *(struct attr*)mr->at_iter->data; + return 1; + } else { + return 0; + } + } + return 0; + } + + at = mr->m->attr_types; + + for(i=0; i<mr->m->attr_cnt; ++i) { + if(*at == attr_type) { + bAttrFound = 1; + break; + } + ++at; + } + + if(!bAttrFound) { + return 0; + } + + while(attr_list) { + if(((struct attr*)attr_list->data)->type == attr_type) { + *attr = *(struct attr*)attr_list->data; + return 1; + } + attr_list = g_list_next(attr_list); + } + return 0; } static int -csv_attr_set(void *priv_data, struct attr *attr, enum change_mode mode) -{ - struct map_rect_priv* mr; - struct map_priv* m; - int i, bFound; - struct attr *attr_new; - GList *attr_list, *curr_attr_list; - enum attr_type *at; - - mr = (struct map_rect_priv*)priv_data; - if(!mr || !mr->qitem) { - return 0; - } - - m = mr->m; - bFound = 0; - at = m->attr_types; - - /*if attribute is not supported by this csv map return 0*/ - for(i=0;i<m->attr_cnt;++i) { - if(*at==attr->type) { - bFound = 1; - break; - } - ++at; - } - if( ! bFound) { - return 0; - } - m->dirty = 1; - attr_new = attr_dup(attr); - attr_list = ((struct quadtree_data*)(mr->qitem->data))->attr_list; - curr_attr_list = attr_list; - - while(attr_list) { - if(((struct attr*)attr_list->data)->type == attr->type) { - switch(mode) { - case change_mode_delete: - attr_free((struct attr*)attr_list->data); - curr_attr_list = g_list_delete_link(curr_attr_list,attr_list); - m->dirty = 1; - /* FIXME: To preserve consistency, may be the save_map_csv should be called here... */ - attr_free(attr_new); - return 1; - case change_mode_modify: - case change_mode_prepend: - case change_mode_append: - /* replace existing attribute */ - if(attr_list->data) { - attr_free((struct attr*)attr_list->data); - } - attr_list->data = attr_new; - m->dirty = 1; - save_map_csv(m); - return 1; - default: - attr_free(attr_new); - return 0; - } - } - attr_list = g_list_next(attr_list); - } - - if( mode==change_mode_modify || mode==change_mode_prepend || mode==change_mode_append) { - /* add new attribute */ - curr_attr_list = g_list_prepend(curr_attr_list, attr_new); - ((struct quadtree_data*)(mr->qitem->data))->attr_list = curr_attr_list; - m->dirty = 1; - save_map_csv(m); - return 1; - } - attr_free(attr_new); - return 0; +csv_attr_set(void *priv_data, struct attr *attr, enum change_mode mode) { + struct map_rect_priv* mr; + struct map_priv* m; + int i, bFound; + struct attr *attr_new; + GList *attr_list, *curr_attr_list; + enum attr_type *at; + + mr = (struct map_rect_priv*)priv_data; + if(!mr || !mr->qitem) { + return 0; + } + + m = mr->m; + bFound = 0; + at = m->attr_types; + + /*if attribute is not supported by this csv map return 0*/ + for(i=0; i<m->attr_cnt; ++i) { + if(*at==attr->type) { + bFound = 1; + break; + } + ++at; + } + if( ! bFound) { + return 0; + } + m->dirty = 1; + attr_new = attr_dup(attr); + attr_list = ((struct quadtree_data*)(mr->qitem->data))->attr_list; + curr_attr_list = attr_list; + + while(attr_list) { + if(((struct attr*)attr_list->data)->type == attr->type) { + switch(mode) { + case change_mode_delete: + attr_free((struct attr*)attr_list->data); + curr_attr_list = g_list_delete_link(curr_attr_list,attr_list); + m->dirty = 1; + /* FIXME: To preserve consistency, may be the save_map_csv should be called here... */ + attr_free(attr_new); + return 1; + case change_mode_modify: + case change_mode_prepend: + case change_mode_append: + /* replace existing attribute */ + if(attr_list->data) { + attr_free((struct attr*)attr_list->data); + } + attr_list->data = attr_new; + m->dirty = 1; + save_map_csv(m); + return 1; + default: + attr_free(attr_new); + return 0; + } + } + attr_list = g_list_next(attr_list); + } + + if( mode==change_mode_modify || mode==change_mode_prepend || mode==change_mode_append) { + /* add new attribute */ + curr_attr_list = g_list_prepend(curr_attr_list, attr_new); + ((struct quadtree_data*)(mr->qitem->data))->attr_list = curr_attr_list; + m->dirty = 1; + save_map_csv(m); + return 1; + } + attr_free(attr_new); + return 0; } static int -csv_type_set(void *priv_data, enum item_type type) -{ - struct map_rect_priv* mr = (struct map_rect_priv*)priv_data; - dbg(lvl_debug,"Enter %d", type); +csv_type_set(void *priv_data, enum item_type type) { + struct map_rect_priv* mr = (struct map_rect_priv*)priv_data; + dbg(lvl_debug,"Enter %d", type); - if(!mr || !mr->qitem) { - dbg(lvl_debug,"Nothing to do"); - return 0; - } + if(!mr || !mr->qitem) { + dbg(lvl_debug,"Nothing to do"); + return 0; + } - if(type!=type_none) - return 0; + if(type!=type_none) + return 0; - mr->qitem->deleted=1; - dbg(lvl_debug,"Item %p is deleted",mr->qitem); + mr->qitem->deleted=1; + dbg(lvl_debug,"Item %p is deleted",mr->qitem); - return 1; + return 1; } static struct item_methods methods_csv = { - csv_coord_rewind, - csv_coord_get, - csv_attr_rewind, - csv_attr_get, - NULL, - csv_attr_set, - csv_coord_set, - csv_type_set + csv_coord_rewind, + csv_coord_get, + csv_attr_rewind, + csv_attr_get, + NULL, + csv_attr_set, + csv_coord_set, + csv_type_set }; @@ -388,498 +377,477 @@ static struct item_methods methods_csv = { * Sets coordinate of an existing item (either on the new list or an item with coord ) */ static int -csv_coord_set(void *priv_data, struct coord *c, int count, enum change_mode mode) -{ - struct quadtree_item query_item, *insert_item, *query_res; - struct coord_geo cg; - struct map_rect_priv* mr; - struct map_priv* m; - struct quadtree_item* qi; - GList* new_it; - dbg(lvl_debug,"Set coordinates %d %d", c->x, c->y); - - /* for now we only support coord modification only */ - if( ! change_mode_modify) { - return 0; - } - /* csv driver supports one coord per record only */ - if( count != 1) { - return 0; - } - - /* get curr_item of given map_rect */ - mr = (struct map_rect_priv*)priv_data; - m = mr->m; - - if(!mr->qitem) { - return 0; - } - - qi = mr->qitem; - - transform_to_geo(projection_mg, &c[0], &cg); - - /* if it is on the new list remove from new list and add it to the tree with the coord */ - new_it = m->new_items; - while(new_it) { - if(new_it->data==qi) { - break; - } - new_it = g_list_next(new_it); - } - if(new_it) { - qi->longitude = cg.lng; - qi->latitude = cg.lat; - quadtree_add( m->tree_root, qi, mr->qiter); - dbg(lvl_debug,"Set coordinates %f %f", cg.lng, cg.lat); - m->new_items = g_list_remove_link(m->new_items,new_it); - m->dirty=1; - save_map_csv(m); - return 1; - } - - /* else update quadtree item with the new coord - remove item from the quadtree */ - query_item.longitude = cg.lng; - query_item.latitude = cg.lat; - query_res = quadtree_find_item(m->tree_root, &query_item); - if(!query_res) { - return 0; - } - quadtree_delete_item(m->tree_root, query_res); - /* add item to the tree with the new coord */ - insert_item=g_new0(struct quadtree_item,1); - insert_item->data=quadtree_data_dup(query_res->data); - insert_item->longitude = cg.lng; - insert_item->latitude = cg.lat; - quadtree_add(m->tree_root, query_res, mr->qiter); - - mr->qitem->ref_count--; - mr->qitem=insert_item; - mr->qitem->ref_count++; - - m->dirty = 1; - save_map_csv(m); - return 1; +csv_coord_set(void *priv_data, struct coord *c, int count, enum change_mode mode) { + struct quadtree_item query_item, *insert_item, *query_res; + struct coord_geo cg; + struct map_rect_priv* mr; + struct map_priv* m; + struct quadtree_item* qi; + GList* new_it; + dbg(lvl_debug,"Set coordinates %d %d", c->x, c->y); + + /* for now we only support coord modification only */ + if( ! change_mode_modify) { + return 0; + } + /* csv driver supports one coord per record only */ + if( count != 1) { + return 0; + } + + /* get curr_item of given map_rect */ + mr = (struct map_rect_priv*)priv_data; + m = mr->m; + + if(!mr->qitem) { + return 0; + } + + qi = mr->qitem; + + transform_to_geo(projection_mg, &c[0], &cg); + + /* if it is on the new list remove from new list and add it to the tree with the coord */ + new_it = m->new_items; + while(new_it) { + if(new_it->data==qi) { + break; + } + new_it = g_list_next(new_it); + } + if(new_it) { + qi->longitude = cg.lng; + qi->latitude = cg.lat; + quadtree_add( m->tree_root, qi, mr->qiter); + dbg(lvl_debug,"Set coordinates %f %f", cg.lng, cg.lat); + m->new_items = g_list_remove_link(m->new_items,new_it); + m->dirty=1; + save_map_csv(m); + return 1; + } + + /* else update quadtree item with the new coord + remove item from the quadtree */ + query_item.longitude = cg.lng; + query_item.latitude = cg.lat; + query_res = quadtree_find_item(m->tree_root, &query_item); + if(!query_res) { + return 0; + } + quadtree_delete_item(m->tree_root, query_res); + /* add item to the tree with the new coord */ + insert_item=g_new0(struct quadtree_item,1); + insert_item->data=quadtree_data_dup(query_res->data); + insert_item->longitude = cg.lng; + insert_item->latitude = cg.lat; + quadtree_add(m->tree_root, query_res, mr->qiter); + + mr->qitem->ref_count--; + mr->qitem=insert_item; + mr->qitem->ref_count++; + + m->dirty = 1; + save_map_csv(m); + return 1; } -static void quadtree_item_free(void *this, struct quadtree_item *qitem) -{ - struct map_priv* m=this; - struct quadtree_data * qdata=qitem->data; - if(m) { - g_hash_table_remove(m->qitem_hash,&(qdata->item->id_lo)); - } +static void quadtree_item_free(void *this, struct quadtree_item *qitem) { + struct map_priv* m=this; + struct quadtree_data * qdata=qitem->data; + if(m) { + g_hash_table_remove(m->qitem_hash,&(qdata->item->id_lo)); + } } -static void quadtree_item_free_do(void *data) -{ - struct quadtree_item *qitem=data; - GList* attr_it; - struct attr* attr; - struct quadtree_data * qdata=qitem->data; - if(qdata) { - for(attr_it = qdata->attr_list;attr_it;attr_it = g_list_next(attr_it)) { - attr = attr_it->data; - attr_free(attr); - } - g_list_free(qdata->attr_list); - g_free(qdata->item); - g_free(qitem->data); - } - g_free(data); +static void quadtree_item_free_do(void *data) { + struct quadtree_item *qitem=data; + GList* attr_it; + struct attr* attr; + struct quadtree_data * qdata=qitem->data; + if(qdata) { + for(attr_it = qdata->attr_list; attr_it; attr_it = g_list_next(attr_it)) { + attr = attr_it->data; + attr_free(attr); + } + g_list_free(qdata->attr_list); + g_free(qdata->item); + g_free(qitem->data); + } + g_free(data); } -static void map_csv_debug_dump_hash_item(gpointer key, gpointer value, gpointer user_data) -{ - struct quadtree_item *qi=value; - GList *attrs; - dbg(lvl_debug,"%p del=%d ref=%d", qi,qi->deleted, qi->ref_count); - attrs=((struct quadtree_data *)qi->data)->attr_list; - while(attrs) { - if(((struct attr*)attrs->data)->type==attr_label) - dbg(lvl_debug,"... %s",((struct attr*)attrs->data)->u.str); - attrs=g_list_next(attrs); - } +static void map_csv_debug_dump_hash_item(gpointer key, gpointer value, gpointer user_data) { + struct quadtree_item *qi=value; + GList *attrs; + dbg(lvl_debug,"%p del=%d ref=%d", qi,qi->deleted, qi->ref_count); + attrs=((struct quadtree_data *)qi->data)->attr_list; + while(attrs) { + if(((struct attr*)attrs->data)->type==attr_label) + dbg(lvl_debug,"... %s",((struct attr*)attrs->data)->u.str); + attrs=g_list_next(attrs); + } } /** * Dump all map data (including deleted items) to the log. */ -static void map_csv_debug_dump(struct map_priv *map) -{ - g_hash_table_foreach(map->qitem_hash, map_csv_debug_dump_hash_item, NULL); +static void map_csv_debug_dump(struct map_priv *map) { + g_hash_table_foreach(map->qitem_hash, map_csv_debug_dump_hash_item, NULL); } static struct map_rect_priv * -map_rect_new_csv(struct map_priv *map, struct map_selection *sel) -{ - struct map_rect_priv *mr; - struct coord_geo lu; - struct coord_geo rl; - struct quadtree_iter *res = NULL; - dbg(lvl_debug,"map_rect_new_csv"); - if(debug_level_get("map_csv")>2) { - map_csv_debug_dump(map); - } - mr=g_new0(struct map_rect_priv, 1); - mr->m=map; - mr->bStarted = 0; - mr->sel=sel; - if (map->flags & 1) - mr->item.id_hi=1; - else - mr->item.id_hi=0; - mr->item.id_lo=0; - mr->item.meth=&methods_csv; - mr->item.priv_data=mr; - - if(!sel) { - lu.lng=-180; - lu.lat=180; - rl.lng=180; - rl.lat=-180; - } else { - transform_to_geo(projection_mg, &sel->u.c_rect.lu, &lu); - transform_to_geo(projection_mg, &sel->u.c_rect.rl, &rl); - } - res=quadtree_query(map->tree_root, lu.lng, rl.lng, rl.lat, lu.lat, quadtree_item_free, mr->m); - mr->qiter = res; - mr->qitem = NULL; - return mr; +map_rect_new_csv(struct map_priv *map, struct map_selection *sel) { + struct map_rect_priv *mr; + struct coord_geo lu; + struct coord_geo rl; + struct quadtree_iter *res = NULL; + dbg(lvl_debug,"map_rect_new_csv"); + if(debug_level_get("map_csv")>2) { + map_csv_debug_dump(map); + } + mr=g_new0(struct map_rect_priv, 1); + mr->m=map; + mr->bStarted = 0; + mr->sel=sel; + if (map->flags & 1) + mr->item.id_hi=1; + else + mr->item.id_hi=0; + mr->item.id_lo=0; + mr->item.meth=&methods_csv; + mr->item.priv_data=mr; + + if(!sel) { + lu.lng=-180; + lu.lat=180; + rl.lng=180; + rl.lat=-180; + } else { + transform_to_geo(projection_mg, &sel->u.c_rect.lu, &lu); + transform_to_geo(projection_mg, &sel->u.c_rect.rl, &rl); + } + res=quadtree_query(map->tree_root, lu.lng, rl.lng, rl.lat, lu.lat, quadtree_item_free, mr->m); + mr->qiter = res; + mr->qitem = NULL; + return mr; } static void -map_rect_destroy_csv(struct map_rect_priv *mr) -{ - if(mr->qitem) - mr->qitem->ref_count--; +map_rect_destroy_csv(struct map_rect_priv *mr) { + if(mr->qitem) + mr->qitem->ref_count--; - if(mr->qiter) - quadtree_query_free(mr->qiter); + if(mr->qiter) + quadtree_query_free(mr->qiter); - g_free(mr); + g_free(mr); } static struct item * -map_rect_get_item_csv(struct map_rect_priv *mr) -{ - - if(mr->qitem) - mr->qitem->ref_count--; - - mr->qitem=quadtree_item_next(mr->qiter); - - if(mr->qitem) { - struct item* ret=&(mr->item); - struct coord_geo cg; - mr->qitem->ref_count++; - mr->item = *(((struct quadtree_data*)(mr->qitem->data))->item); - ret->priv_data=mr; - cg.lng = mr->qitem->longitude; - cg.lat = mr->qitem->latitude; - transform_from_geo(projection_mg, &cg, &mr->c); - return ret; - } - return NULL; +map_rect_get_item_csv(struct map_rect_priv *mr) { + + if(mr->qitem) + mr->qitem->ref_count--; + + mr->qitem=quadtree_item_next(mr->qiter); + + if(mr->qitem) { + struct item* ret=&(mr->item); + struct coord_geo cg; + mr->qitem->ref_count++; + mr->item = *(((struct quadtree_data*)(mr->qitem->data))->item); + ret->priv_data=mr; + cg.lng = mr->qitem->longitude; + cg.lat = mr->qitem->latitude; + transform_from_geo(projection_mg, &cg, &mr->c); + return ret; + } + return NULL; } static struct item * -map_rect_get_item_byid_csv(struct map_rect_priv *mr, int id_hi, int id_lo) -{ - /*currently id_hi is ignored*/ - - struct quadtree_item *qit = g_hash_table_lookup(mr->m->qitem_hash,&id_lo); - - if(mr->qitem ) - mr->qitem->ref_count--; - - if(qit) { - mr->qitem = qit; - mr->qitem->ref_count++; - mr->item=*(((struct quadtree_data*)(qit->data))->item); - mr->item.priv_data=mr; - return &(mr->item); - } else { - mr->qitem = NULL; - return NULL; - } +map_rect_get_item_byid_csv(struct map_rect_priv *mr, int id_hi, int id_lo) { + /*currently id_hi is ignored*/ + + struct quadtree_item *qit = g_hash_table_lookup(mr->m->qitem_hash,&id_lo); + + if(mr->qitem ) + mr->qitem->ref_count--; + + if(qit) { + mr->qitem = qit; + mr->qitem->ref_count++; + mr->item=*(((struct quadtree_data*)(qit->data))->item); + mr->item.priv_data=mr; + return &(mr->item); + } else { + mr->qitem = NULL; + return NULL; + } } static int -csv_get_attr(struct map_priv *m, enum attr_type type, struct attr *attr) -{ - return 0; +csv_get_attr(struct map_priv *m, enum attr_type type, struct attr *attr) { + return 0; } static struct item * -csv_create_item(struct map_rect_priv *mr, enum item_type it_type) -{ - struct map_priv* m; - struct quadtree_data* qd; - struct quadtree_item* qi; - struct item* curr_item; - int* pID; - if(mr && mr->m) { - m = mr->m; - } - else { - return NULL; - } - - if( m->item_type != it_type) { - return NULL; - } - - m->dirty = 1; - /*add item to the map*/ - curr_item = item_new("",zoom_max); - curr_item->type = m->item_type; - curr_item->meth=&methods_csv; - - curr_item->id_lo = m->next_item_idx; - if (m->flags & 1) - curr_item->id_hi=1; - else - curr_item->id_hi=0; - - qd = g_new0(struct quadtree_data,1); - qi = g_new0(struct quadtree_item,1); - qd->item = curr_item; - qd->attr_list = NULL; - qi->data = qd; - /*we don`t have valid coord yet*/ - qi->longitude = 0; - qi->latitude = 0; - /*add the coord less item to the new list*/ - m->new_items = g_list_prepend(m->new_items, qi); - if(mr->qitem) - mr->qitem->ref_count--; - mr->qitem=qi; - mr->item=*curr_item; - mr->item.priv_data=mr; - mr->qitem->ref_count++; - /*don't add to the quadtree yet, wait until we have a valid coord*/ - pID = g_new(int,1); - *pID = m->next_item_idx; - g_hash_table_insert(m->qitem_hash, pID,qi); - ++m->next_item_idx; - return &mr->item; +csv_create_item(struct map_rect_priv *mr, enum item_type it_type) { + struct map_priv* m; + struct quadtree_data* qd; + struct quadtree_item* qi; + struct item* curr_item; + int* pID; + if(mr && mr->m) { + m = mr->m; + } else { + return NULL; + } + + if( m->item_type != it_type) { + return NULL; + } + + m->dirty = 1; + /*add item to the map*/ + curr_item = item_new("",zoom_max); + curr_item->type = m->item_type; + curr_item->meth=&methods_csv; + + curr_item->id_lo = m->next_item_idx; + if (m->flags & 1) + curr_item->id_hi=1; + else + curr_item->id_hi=0; + + qd = g_new0(struct quadtree_data,1); + qi = g_new0(struct quadtree_item,1); + qd->item = curr_item; + qd->attr_list = NULL; + qi->data = qd; + /*we don`t have valid coord yet*/ + qi->longitude = 0; + qi->latitude = 0; + /*add the coord less item to the new list*/ + m->new_items = g_list_prepend(m->new_items, qi); + if(mr->qitem) + mr->qitem->ref_count--; + mr->qitem=qi; + mr->item=*curr_item; + mr->item.priv_data=mr; + mr->qitem->ref_count++; + /*don't add to the quadtree yet, wait until we have a valid coord*/ + pID = g_new(int,1); + *pID = m->next_item_idx; + g_hash_table_insert(m->qitem_hash, pID,qi); + ++m->next_item_idx; + return &mr->item; } static struct map_methods map_methods_csv = { - projection_mg, - "utf-8", - map_destroy_csv, - map_rect_new_csv, - map_rect_destroy_csv, - map_rect_get_item_csv, - map_rect_get_item_byid_csv, - NULL, - NULL, - NULL, - csv_create_item, - csv_get_attr, + projection_mg, + "utf-8", + map_destroy_csv, + map_rect_new_csv, + map_rect_destroy_csv, + map_rect_get_item_csv, + map_rect_get_item_byid_csv, + NULL, + NULL, + NULL, + csv_create_item, + csv_get_attr, }; static struct map_priv * -map_new_csv(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) -{ - struct map_priv *m = NULL; - struct attr *attr_types; - struct attr *item_type_attr; - struct attr *data; - struct attr *flags; - struct attr *charset; - int bLonFound = 0; - int bLatFound = 0; - int attr_cnt = 0; - enum attr_type* attr_type_list = NULL; - struct quadtree_node* tree_root = quadtree_node_new(NULL,-180,180,-180,180); - m = g_new0(struct map_priv, 1); - m->id = ++map_id; - m->qitem_hash = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, quadtree_item_free_do); - m->tree_root = tree_root; - - attr_types = attr_search(attrs, NULL, attr_attr_types); - if(attr_types) { - enum attr_type* at = attr_types->u.attr_types; - while(*at != attr_none) { - attr_type_list = g_realloc(attr_type_list,sizeof(enum attr_type)*(attr_cnt+1)); - attr_type_list[attr_cnt] = *at; - if(*at==attr_position_latitude) { - bLatFound = 1; - } - else if(*at==attr_position_longitude) { - bLonFound = 1; - } - ++attr_cnt; - ++at; - } - m->attr_cnt = attr_cnt; - m->attr_types = attr_type_list; - } else { - m->attr_types = NULL; - return NULL; - } - - charset = attr_search(attrs, NULL, attr_charset); - if(charset) { - dbg(lvl_debug,"charset:%s",charset->u.str); - m->charset=g_strdup(charset->u.str); - } else { - m->charset=g_strdup(map_methods_csv.charset); - } - - if(bLonFound==0 || bLatFound==0) { - return NULL; - } - - item_type_attr=attr_search(attrs, NULL, attr_item_type); - - if( !item_type_attr || item_type_attr->u.item_type==type_none) { - return NULL; - } - - m->item_type = item_type_attr->u.item_type; - - flags=attr_search(attrs, NULL, attr_flags); - if (flags) - m->flags=flags->u.num; - - *meth = map_methods_csv; - - data=attr_search(attrs, NULL, attr_data); - - if(data) { - struct file_wordexp *wexp; - char **wexp_data; - FILE *fp; - wexp=file_wordexp_new(data->u.str); - wexp_data=file_wordexp_get_array(wexp); - dbg(lvl_debug,"map_new_csv %s", data->u.str); - m->filename=g_strdup(wexp_data[0]); - file_wordexp_destroy(wexp); - - /*load csv file into quadtree structure*/ - /*if column number is wrong skip*/ - if((fp=fopen(m->filename,"rt"))) { - const int max_line_len = 256; - char *linebuf=g_alloca(sizeof(char)*max_line_len); - while(!feof(fp)) { - if(fgets(linebuf,max_line_len,fp)) { - char *line=g_convert(linebuf, -1,"utf-8",m->charset,NULL,NULL,NULL); - char *line2=NULL; - char *delim = ","; - int col_cnt=0; - char *tok; - if(!line) { - dbg(lvl_error,"Error converting '%s' to utf-8 from %s",linebuf, m->charset); - continue; - } - if(line[strlen(line)-1]=='\n' || line[strlen(line)-1]=='\r') { - line[strlen(line)-1] = '\0'; - } - line2 = g_strdup(line); - while((tok=strtok( (col_cnt==0)?line:NULL , delim))) { - ++col_cnt; - } - - if(col_cnt==attr_cnt) { - int cnt = 0; /*index of current attr*/ - char*tok; - GList* attr_list = NULL; - int bAddSum = 1; - double longitude = 0.0, latitude=0.0; - struct item *curr_item = item_new("",zoom_max);/*does not use parameters*/ - - curr_item->type = item_type_attr->u.item_type; - curr_item->id_lo = m->next_item_idx; - if (m->flags & 1) - curr_item->id_hi=1; - else - curr_item->id_hi=0; - curr_item->meth=&methods_csv; - - - while((tok=strtok( (cnt==0)?line2:NULL , delim))) { - struct attr*curr_attr = g_new0(struct attr,1); - int bAdd = 1; - curr_attr->type = attr_types->u.attr_types[cnt]; - if(ATTR_IS_STRING(attr_types->u.attr_types[cnt])) { - curr_attr->u.str = g_strdup(tok); - } - else if(ATTR_IS_INT(attr_types->u.attr_types[cnt])) { - curr_attr->u.num = atoi(tok); - } - else if(ATTR_IS_DOUBLE(attr_types->u.attr_types[cnt])) { - double *d = g_new(double,1); - *d = atof(tok); - curr_attr->u.numd = d; - if(attr_types->u.attr_types[cnt] == attr_position_longitude) { - longitude = *d; - } - if(attr_types->u.attr_types[cnt] == attr_position_latitude) { - latitude = *d; - } - } - else { - /*unknown attribute*/ - bAddSum = bAdd = 0; - g_free(curr_attr); - } - - if(bAdd) { - attr_list = g_list_prepend(attr_list, curr_attr); - } - ++cnt; - } - if(bAddSum && (longitude!=0.0 || latitude!=0.0)) { - struct quadtree_data* qd = g_new0(struct quadtree_data,1); - struct quadtree_item* qi =g_new0(struct quadtree_item,1); - int* pID = g_new(int,1); - qd->item = curr_item; - qd->attr_list = attr_list; - qi->data = qd; - qi->longitude = longitude; - qi->latitude = latitude; - quadtree_add(tree_root, qi, NULL); - *pID = m->next_item_idx; - g_hash_table_insert(m->qitem_hash, pID,qi); - ++m->next_item_idx; - dbg(lvl_debug,"%s",line); - } - else { - g_free(curr_item); - } - - } - else { - dbg(lvl_error,"ERROR: Non-matching attr count and column count: %d %d SKIPPING line: %s",col_cnt, attr_cnt,line); - } - g_free(line); - g_free(line2); - } - } - fclose(fp); - } - else { - dbg(lvl_error,"Error opening csv map file '%s': %s", m->filename, strerror(errno)); - return NULL; - } - } else { - dbg(lvl_debug,"No data attribute, starting with in-memory map"); - } - - dbg(lvl_info,"%p",tree_root); - return m; +map_new_csv(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) { + struct map_priv *m = NULL; + struct attr *attr_types; + struct attr *item_type_attr; + struct attr *data; + struct attr *flags; + struct attr *charset; + int bLonFound = 0; + int bLatFound = 0; + int attr_cnt = 0; + enum attr_type* attr_type_list = NULL; + struct quadtree_node* tree_root = quadtree_node_new(NULL,-180,180,-180,180); + m = g_new0(struct map_priv, 1); + m->id = ++map_id; + m->qitem_hash = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, quadtree_item_free_do); + m->tree_root = tree_root; + + attr_types = attr_search(attrs, NULL, attr_attr_types); + if(attr_types) { + enum attr_type* at = attr_types->u.attr_types; + while(*at != attr_none) { + attr_type_list = g_realloc(attr_type_list,sizeof(enum attr_type)*(attr_cnt+1)); + attr_type_list[attr_cnt] = *at; + if(*at==attr_position_latitude) { + bLatFound = 1; + } else if(*at==attr_position_longitude) { + bLonFound = 1; + } + ++attr_cnt; + ++at; + } + m->attr_cnt = attr_cnt; + m->attr_types = attr_type_list; + } else { + m->attr_types = NULL; + return NULL; + } + + charset = attr_search(attrs, NULL, attr_charset); + if(charset) { + dbg(lvl_debug,"charset:%s",charset->u.str); + m->charset=g_strdup(charset->u.str); + } else { + m->charset=g_strdup(map_methods_csv.charset); + } + + if(bLonFound==0 || bLatFound==0) { + return NULL; + } + + item_type_attr=attr_search(attrs, NULL, attr_item_type); + + if( !item_type_attr || item_type_attr->u.item_type==type_none) { + return NULL; + } + + m->item_type = item_type_attr->u.item_type; + + flags=attr_search(attrs, NULL, attr_flags); + if (flags) + m->flags=flags->u.num; + + *meth = map_methods_csv; + + data=attr_search(attrs, NULL, attr_data); + + if(data) { + struct file_wordexp *wexp; + char **wexp_data; + FILE *fp; + wexp=file_wordexp_new(data->u.str); + wexp_data=file_wordexp_get_array(wexp); + dbg(lvl_debug,"map_new_csv %s", data->u.str); + m->filename=g_strdup(wexp_data[0]); + file_wordexp_destroy(wexp); + + /*load csv file into quadtree structure*/ + /*if column number is wrong skip*/ + if((fp=fopen(m->filename,"rt"))) { + const int max_line_len = 256; + char *linebuf=g_alloca(sizeof(char)*max_line_len); + while(!feof(fp)) { + if(fgets(linebuf,max_line_len,fp)) { + char *line=g_convert(linebuf, -1,"utf-8",m->charset,NULL,NULL,NULL); + char *line2=NULL; + char *delim = ","; + int col_cnt=0; + char *tok; + if(!line) { + dbg(lvl_error,"Error converting '%s' to utf-8 from %s",linebuf, m->charset); + continue; + } + if(line[strlen(line)-1]=='\n' || line[strlen(line)-1]=='\r') { + line[strlen(line)-1] = '\0'; + } + line2 = g_strdup(line); + while((tok=strtok( (col_cnt==0)?line:NULL, delim))) { + ++col_cnt; + } + + if(col_cnt==attr_cnt) { + int cnt = 0; /*index of current attr*/ + char*tok; + GList* attr_list = NULL; + int bAddSum = 1; + double longitude = 0.0, latitude=0.0; + struct item *curr_item = item_new("",zoom_max);/*does not use parameters*/ + + curr_item->type = item_type_attr->u.item_type; + curr_item->id_lo = m->next_item_idx; + if (m->flags & 1) + curr_item->id_hi=1; + else + curr_item->id_hi=0; + curr_item->meth=&methods_csv; + + + while((tok=strtok( (cnt==0)?line2:NULL, delim))) { + struct attr*curr_attr = g_new0(struct attr,1); + int bAdd = 1; + curr_attr->type = attr_types->u.attr_types[cnt]; + if(ATTR_IS_STRING(attr_types->u.attr_types[cnt])) { + curr_attr->u.str = g_strdup(tok); + } else if(ATTR_IS_INT(attr_types->u.attr_types[cnt])) { + curr_attr->u.num = atoi(tok); + } else if(ATTR_IS_DOUBLE(attr_types->u.attr_types[cnt])) { + double *d = g_new(double,1); + *d = atof(tok); + curr_attr->u.numd = d; + if(attr_types->u.attr_types[cnt] == attr_position_longitude) { + longitude = *d; + } + if(attr_types->u.attr_types[cnt] == attr_position_latitude) { + latitude = *d; + } + } else { + /*unknown attribute*/ + bAddSum = bAdd = 0; + g_free(curr_attr); + } + + if(bAdd) { + attr_list = g_list_prepend(attr_list, curr_attr); + } + ++cnt; + } + if(bAddSum && (longitude!=0.0 || latitude!=0.0)) { + struct quadtree_data* qd = g_new0(struct quadtree_data,1); + struct quadtree_item* qi =g_new0(struct quadtree_item,1); + int* pID = g_new(int,1); + qd->item = curr_item; + qd->attr_list = attr_list; + qi->data = qd; + qi->longitude = longitude; + qi->latitude = latitude; + quadtree_add(tree_root, qi, NULL); + *pID = m->next_item_idx; + g_hash_table_insert(m->qitem_hash, pID,qi); + ++m->next_item_idx; + dbg(lvl_debug,"%s",line); + } else { + g_free(curr_item); + } + + } else { + dbg(lvl_error,"ERROR: Non-matching attr count and column count: %d %d SKIPPING line: %s",col_cnt, attr_cnt,line); + } + g_free(line); + g_free(line2); + } + } + fclose(fp); + } else { + dbg(lvl_error,"Error opening csv map file '%s': %s", m->filename, strerror(errno)); + return NULL; + } + } else { + dbg(lvl_debug,"No data attribute, starting with in-memory map"); + } + + dbg(lvl_info,"%p",tree_root); + return m; } void -plugin_init(void) -{ - dbg(lvl_debug,"csv: plugin_init"); - plugin_register_category_map("csv", map_new_csv); +plugin_init(void) { + dbg(lvl_debug,"csv: plugin_init"); + plugin_register_category_map("csv", map_new_csv); } diff --git a/navit/map/csv/quadtree.c b/navit/map/csv/quadtree.c index 32d075a3d..6e025c0d6 100644 --- a/navit/map/csv/quadtree.c +++ b/navit/map/csv/quadtree.c @@ -34,34 +34,33 @@ /* Structure describing quadtree iterative query */ struct quadtree_iter { - /* List representing stack of quad_tree_iter_nodes referring to higher-level quadtree_nodes */ - GList *iter_nodes; - double xmin,xmax,ymin,ymax; - /* Current item pointer */ - struct quadtree_item *item; - void (*item_free)(void *context, struct quadtree_item *qitem); - void *item_free_context; + /* List representing stack of quad_tree_iter_nodes referring to higher-level quadtree_nodes */ + GList *iter_nodes; + double xmin,xmax,ymin,ymax; + /* Current item pointer */ + struct quadtree_item *item; + void (*item_free)(void *context, struct quadtree_item *qitem); + void *item_free_context; }; /* Structure describing one level of the quadtree iterative query */ struct quadtree_iter_node { - struct quadtree_node *node; - /* Number of subnode being analyzed (for non-leafs) */ - int subnode; - /* Number of item being analyzed (for leafs) */ - int item; - /* Number of subitems in items array (for leafs) */ - int node_num; - /* If the node referenced was a leaf when it was analyzed */ - int is_leaf; - struct quadtree_item *items[QUADTREE_NODE_CAPACITY]; -}; - - -static double -dist_sq(double x1,double y1,double x2,double y2) -{ - return (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1); + struct quadtree_node *node; + /* Number of subnode being analyzed (for non-leafs) */ + int subnode; + /* Number of item being analyzed (for leafs) */ + int item; + /* Number of subitems in items array (for leafs) */ + int node_num; + /* If the node referenced was a leaf when it was analyzed */ + int is_leaf; + struct quadtree_item *items[QUADTREE_NODE_CAPACITY]; +}; + + +static double +dist_sq(double x1,double y1,double x2,double y2) { + return (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1); } struct quadtree_node* @@ -79,81 +78,81 @@ quadtree_node_new(struct quadtree_node* parent, double xmin, double xmax, double /* * searches all four subnodes recursively for the list of items within a rectangle */ -void -quadtree_find_rect_items(struct quadtree_node* this_, double dXMin, double dXMax, double dYMin, double dYMax, GList**out) { +void +quadtree_find_rect_items(struct quadtree_node* this_, double dXMin, double dXMax, double dYMin, double dYMax, + GList**out) { struct quadtree_node* nodes[4] = { this_->aa, this_->ab, this_->ba, this_->bb }; - if( this_->is_leaf ) { + if( this_->is_leaf ) { + int i; + for(i=0; i<this_->node_num; ++i) { //select only items within input rectangle + if(dXMin<=this_->items[i]->longitude && this_->items[i]->longitude<=dXMax && + dYMin<=this_->items[i]->latitude && this_->items[i]->latitude<=dYMax + ) { + *out=g_list_prepend(*out,this_->items[i]); + } + } + } else { int i; - for(i=0;i<this_->node_num;++i) { //select only items within input rectangle - if(dXMin<=this_->items[i]->longitude && this_->items[i]->longitude<=dXMax && - dYMin<=this_->items[i]->latitude && this_->items[i]->latitude<=dYMax - ) { - *out=g_list_prepend(*out,this_->items[i]); - } + for( i=0; i<4; ++i) { + if(nodes[i] ) { + //limit flooding + if(nodes[i]->xmax<dXMin || dXMax<nodes[i]->xmin || + nodes[i]->ymax<dYMin || dYMax<nodes[i]->ymin + ) { + continue; + } + //recurse into subtiles if there is at least one subtile corner within input rectangle + quadtree_find_rect_items(nodes[i],dXMin,dXMax,dYMin,dYMax,out); + } } } - else { - int i; - for( i=0;i<4;++i) { - if(nodes[i] ) { - //limit flooding - if(nodes[i]->xmax<dXMin || dXMax<nodes[i]->xmin || - nodes[i]->ymax<dYMin || dYMax<nodes[i]->ymin - ) { - continue; - } - //recurse into subtiles if there is at least one subtile corner within input rectangle - quadtree_find_rect_items(nodes[i],dXMin,dXMax,dYMin,dYMax,out); - } - } - } } /* * searches all four subnodes recursively for the closest item */ struct quadtree_item* -quadtree_find_nearest_flood(struct quadtree_node* this_, struct quadtree_item* item, double current_max, struct quadtree_node* toSkip) { +quadtree_find_nearest_flood(struct quadtree_node* this_, struct quadtree_item* item, double current_max, + struct quadtree_node* toSkip) { struct quadtree_node* nodes[4] = { this_->aa, this_->ab, this_->ba, this_->bb }; struct quadtree_item*res = NULL; - if( this_->is_leaf ) { + if( this_->is_leaf ) { int i; double distance_sq = current_max; - for(i=0;i<this_->node_num;++i) { + for(i=0; i<this_->node_num; ++i) { double curr_dist_sq = dist_sq(item->longitude,item->latitude,this_->items[i]->longitude,this_->items[i]->latitude); if(curr_dist_sq<distance_sq) { distance_sq = curr_dist_sq; res = this_->items[i]; } } - } - else { - int i; - for( i=0;i<4;++i) { - if(nodes[i] && nodes[i]!=toSkip) { - //limit flooding - struct quadtree_item*res_tmp = NULL; - if( - dist_sq(nodes[i]->xmin,nodes[i]->ymin,item->longitude,item->latitude)<current_max || - dist_sq(nodes[i]->xmax,nodes[i]->ymin,item->longitude,item->latitude)<current_max || - dist_sq(nodes[i]->xmax,nodes[i]->ymax,item->longitude,item->latitude)<current_max || - dist_sq(nodes[i]->xmin,nodes[i]->ymax,item->longitude,item->latitude)<current_max - ) { - res_tmp = quadtree_find_nearest_flood(nodes[i],item,current_max,NULL); - } - if(res_tmp) { - double curr_dist_sq; - res = res_tmp; - curr_dist_sq = dist_sq(item->longitude,item->latitude,res->longitude,res->latitude); - if(curr_dist_sq<current_max) { - current_max = curr_dist_sq; + } else { + int i; + for( i=0; i<4; ++i) { + if(nodes[i] && nodes[i]!=toSkip) { + //limit flooding + struct quadtree_item*res_tmp = NULL; + if( + dist_sq(nodes[i]->xmin,nodes[i]->ymin,item->longitude,item->latitude)<current_max || + dist_sq(nodes[i]->xmax,nodes[i]->ymin,item->longitude,item->latitude)<current_max || + dist_sq(nodes[i]->xmax,nodes[i]->ymax,item->longitude,item->latitude)<current_max || + dist_sq(nodes[i]->xmin,nodes[i]->ymax,item->longitude,item->latitude)<current_max + ) { + res_tmp = quadtree_find_nearest_flood(nodes[i],item,current_max,NULL); + } + if(res_tmp) { + double curr_dist_sq; + res = res_tmp; + curr_dist_sq = dist_sq(item->longitude,item->latitude,res->longitude,res->latitude); + if(curr_dist_sq<current_max) { + current_max = curr_dist_sq; + } + } } - } - } - } + } } - return res; + return res; } /* @@ -163,129 +162,117 @@ struct quadtree_item* quadtree_find_item(struct quadtree_node* this_, struct quadtree_item* item) { struct quadtree_item*res = NULL; if( ! this_ ) { - return NULL; + return NULL; } - if( this_->is_leaf ) { + if( this_->is_leaf ) { int i; - for(i=0;i<this_->node_num;++i) { + for(i=0; i<this_->node_num; ++i) { //TODO equality check may not be correct on float values! maybe it can be replaced by range check with some tolerance if(item->longitude==this_->items[i]->longitude && item->latitude==this_->items[i]->latitude) { res = this_->items[i]; return res; } } - return NULL; - } - else { + return NULL; + } else { if( - this_->aa && - this_->aa->xmin<=item->longitude && item->longitude<this_->aa->xmax && - this_->aa->ymin<=item->latitude && item->latitude<this_->aa->ymax - ) { - res = quadtree_find_item(this_->aa,item); - } - else if( - this_->ab && - this_->ab->xmin<=item->longitude && item->longitude<this_->ab->xmax && - this_->ab->ymin<=item->latitude && item->latitude<this_->ab->ymax - ) { - res = quadtree_find_item(this_->ab,item); - } - else if( - this_->ba && - this_->ba->xmin<=item->longitude && item->longitude<this_->ba->xmax && - this_->ba->ymin<=item->latitude && item->latitude<this_->ba->ymax - ) { - res = quadtree_find_item(this_->ba,item); - } - else if( - this_->bb && - this_->bb->xmin<=item->longitude && item->longitude<this_->bb->xmax && - this_->bb->ymin<=item->latitude && item->latitude<this_->bb->ymax - ) { - res = quadtree_find_item(this_->bb,item); - } - else { - return NULL; + this_->aa && + this_->aa->xmin<=item->longitude && item->longitude<this_->aa->xmax && + this_->aa->ymin<=item->latitude && item->latitude<this_->aa->ymax + ) { + res = quadtree_find_item(this_->aa,item); + } else if( + this_->ab && + this_->ab->xmin<=item->longitude && item->longitude<this_->ab->xmax && + this_->ab->ymin<=item->latitude && item->latitude<this_->ab->ymax + ) { + res = quadtree_find_item(this_->ab,item); + } else if( + this_->ba && + this_->ba->xmin<=item->longitude && item->longitude<this_->ba->xmax && + this_->ba->ymin<=item->latitude && item->latitude<this_->ba->ymax + ) { + res = quadtree_find_item(this_->ba,item); + } else if( + this_->bb && + this_->bb->xmin<=item->longitude && item->longitude<this_->bb->xmax && + this_->bb->ymin<=item->latitude && item->latitude<this_->bb->ymax + ) { + res = quadtree_find_item(this_->bb,item); + } else { + return NULL; } } - return res; + return res; } /* * returns the containing node for an item */ -struct quadtree_node* -quadtree_find_containing_node(struct quadtree_node* root, struct quadtree_item* item) -{ +struct quadtree_node* +quadtree_find_containing_node(struct quadtree_node* root, struct quadtree_item* item) { struct quadtree_node*res = NULL; if( ! root ) { - return NULL; + return NULL; } - if( root->is_leaf ) { + if( root->is_leaf ) { int i; - for(i=0;i<root->node_num;++i) { + for(i=0; i<root->node_num; ++i) { if(item == root->items[i]) { res = root; } } - } - else { + } else { if( - root->aa && - root->aa->xmin<=item->longitude && item->longitude<root->aa->xmax && - root->aa->ymin<=item->latitude && item->latitude<root->aa->ymax - ) { - res = quadtree_find_containing_node(root->aa,item); - } - else if( - root->ab && - root->ab->xmin<=item->longitude && item->longitude<root->ab->xmax && - root->ab->ymin<=item->latitude && item->latitude<root->ab->ymax - ) { - res = quadtree_find_containing_node(root->ab,item); - } - else if( - root->ba && - root->ba->xmin<=item->longitude && item->longitude<root->ba->xmax && - root->ba->ymin<=item->latitude && item->latitude<root->ba->ymax - ) { - res = quadtree_find_containing_node(root->ba,item); - } - else if( - root->bb && - root->bb->xmin<=item->longitude && item->longitude<root->bb->xmax && - root->bb->ymin<=item->latitude && item->latitude<root->bb->ymax - ) { - res = quadtree_find_containing_node(root->bb,item); - } - else { - //this should not happen + root->aa && + root->aa->xmin<=item->longitude && item->longitude<root->aa->xmax && + root->aa->ymin<=item->latitude && item->latitude<root->aa->ymax + ) { + res = quadtree_find_containing_node(root->aa,item); + } else if( + root->ab && + root->ab->xmin<=item->longitude && item->longitude<root->ab->xmax && + root->ab->ymin<=item->latitude && item->latitude<root->ab->ymax + ) { + res = quadtree_find_containing_node(root->ab,item); + } else if( + root->ba && + root->ba->xmin<=item->longitude && item->longitude<root->ba->xmax && + root->ba->ymin<=item->latitude && item->latitude<root->ba->ymax + ) { + res = quadtree_find_containing_node(root->ba,item); + } else if( + root->bb && + root->bb->xmin<=item->longitude && item->longitude<root->bb->xmax && + root->bb->ymin<=item->latitude && item->latitude<root->bb->ymax + ) { + res = quadtree_find_containing_node(root->bb,item); + } else { + //this should not happen } } - return res; + return res; } -int quadtree_delete_item(struct quadtree_node* root, struct quadtree_item* item) -{ +int quadtree_delete_item(struct quadtree_node* root, struct quadtree_item* item) { - struct quadtree_node* qn = quadtree_find_containing_node(root,item); - int i, bFound=0; + struct quadtree_node* qn = quadtree_find_containing_node(root,item); + int i, bFound=0; - if(!qn || !qn->node_num) { - return 0; - } + if(!qn || !qn->node_num) { + return 0; + } - for(i=0;i<qn->node_num;++i) { - if( qn->items[i] == item) { - qn->items[i]->deleted=1; - bFound=1; + for(i=0; i<qn->node_num; ++i) { + if( qn->items[i] == item) { + qn->items[i]->deleted=1; + bFound=1; + } } - } - return bFound; + return bFound; } @@ -297,108 +284,103 @@ quadtree_find_nearest(struct quadtree_node* this_, struct quadtree_item* item) { struct quadtree_item*res = NULL; double distance_sq = MAX_DOUBLE; if( ! this_ ) { - return NULL; + return NULL; } - if( this_->is_leaf ) { + if( this_->is_leaf ) { int i; - for(i=0;i<this_->node_num;++i) { + for(i=0; i<this_->node_num; ++i) { double curr_dist_sq = dist_sq(item->longitude,item->latitude,this_->items[i]->longitude,this_->items[i]->latitude); if(curr_dist_sq<distance_sq) { distance_sq = curr_dist_sq; res = this_->items[i]; } } - //go up n levels - if(!res && this_->parent) { - struct quadtree_item*res2 = NULL; - struct quadtree_node* anchestor = this_->parent; - int cnt = 0; - while (anchestor->parent && cnt<4) { - anchestor = anchestor->parent; - ++cnt; - } - res2 = quadtree_find_nearest_flood(anchestor,item,distance_sq,NULL); - if(res2) { - res = res2; - } - } - } else { - if( - this_->aa && - this_->aa->xmin<=item->longitude && item->longitude<this_->aa->xmax && - this_->aa->ymin<=item->latitude && item->latitude<this_->aa->ymax - ) { - res = quadtree_find_nearest(this_->aa,item); - } - else if( - this_->ab && - this_->ab->xmin<=item->longitude && item->longitude<this_->ab->xmax && - this_->ab->ymin<=item->latitude && item->latitude<this_->ab->ymax - ) { - res = quadtree_find_nearest(this_->ab,item); - } - else if( - this_->ba && - this_->ba->xmin<=item->longitude && item->longitude<this_->ba->xmax && - this_->ba->ymin<=item->latitude && item->latitude<this_->ba->ymax - ) { - res = quadtree_find_nearest(this_->ba,item); - } - else if( - this_->bb && - this_->bb->xmin<=item->longitude && item->longitude<this_->bb->xmax && - this_->bb->ymin<=item->latitude && item->latitude<this_->bb->ymax - ) { - res = quadtree_find_nearest(this_->bb,item); - } - else { - if(this_->parent) { - //go up two levels - struct quadtree_node* anchestor = this_->parent; + //go up n levels + if(!res && this_->parent) { + struct quadtree_item*res2 = NULL; + struct quadtree_node* anchestor = this_->parent; int cnt = 0; while (anchestor->parent && cnt<4) { - anchestor = anchestor->parent; - ++cnt; - } - res = quadtree_find_nearest_flood(anchestor,item,distance_sq,NULL); + anchestor = anchestor->parent; + ++cnt; + } + res2 = quadtree_find_nearest_flood(anchestor,item,distance_sq,NULL); + if(res2) { + res = res2; + } + } + } else { + if( + this_->aa && + this_->aa->xmin<=item->longitude && item->longitude<this_->aa->xmax && + this_->aa->ymin<=item->latitude && item->latitude<this_->aa->ymax + ) { + res = quadtree_find_nearest(this_->aa,item); + } else if( + this_->ab && + this_->ab->xmin<=item->longitude && item->longitude<this_->ab->xmax && + this_->ab->ymin<=item->latitude && item->latitude<this_->ab->ymax + ) { + res = quadtree_find_nearest(this_->ab,item); + } else if( + this_->ba && + this_->ba->xmin<=item->longitude && item->longitude<this_->ba->xmax && + this_->ba->ymin<=item->latitude && item->latitude<this_->ba->ymax + ) { + res = quadtree_find_nearest(this_->ba,item); + } else if( + this_->bb && + this_->bb->xmin<=item->longitude && item->longitude<this_->bb->xmax && + this_->bb->ymin<=item->latitude && item->latitude<this_->bb->ymax + ) { + res = quadtree_find_nearest(this_->bb,item); + } else { + if(this_->parent) { + //go up two levels + struct quadtree_node* anchestor = this_->parent; + int cnt = 0; + while (anchestor->parent && cnt<4) { + anchestor = anchestor->parent; + ++cnt; + } + res = quadtree_find_nearest_flood(anchestor,item,distance_sq,NULL); + } } - } } - return res; + return res; } /** - * @brief Free space occupied by deleted unreferenced items. + * @brief Free space occupied by deleted unreferenced items. * @param node pointer to the quadtree node * @param iter Quadtree iteration context. * @return nothing */ -void quadtree_node_drop_garbage(struct quadtree_node* node, struct quadtree_iter *iter) -{ - int i,j; - int node_num=node->node_num; - dbg(lvl_debug,"Processing unreferenced subnode children..."); - for(i=0,j=0;i<node_num;i++) { - if(node->items[i]->deleted && !node->items[i]->ref_count) { - if(iter->item_free) { - (iter->item_free)(iter->item_free_context, node->items[i]); - } else { - g_free(node->items[i]); - } - node->node_num--; - node->items[i]=NULL; - } else { - node->items[j++]=node->items[i]; - } - if(i>j) - node->items[i]=NULL; - } +void quadtree_node_drop_garbage(struct quadtree_node* node, struct quadtree_iter *iter) { + int i,j; + int node_num=node->node_num; + dbg(lvl_debug,"Processing unreferenced subnode children..."); + for(i=0,j=0; i<node_num; i++) { + if(node->items[i]->deleted && !node->items[i]->ref_count) { + if(iter->item_free) { + (iter->item_free)(iter->item_free_context, node->items[i]); + } else { + g_free(node->items[i]); + } + node->node_num--; + node->items[i]=NULL; + } else { + node->items[j++]=node->items[i]; + } + if(i>j) + node->items[i]=NULL; + } } /** - * @brief Add new node to quadtree. + * @brief Add new node to quadtree. * @param this_ pointer to the quadtree (root) node * @param item item to add * @param iter Quadtree iteration context. Can be NULL if no garbage collection is needed. @@ -409,68 +391,68 @@ quadtree_add(struct quadtree_node* this_, struct quadtree_item* item, struct qua if( this_->is_leaf ) { int bSame = 1; int i; - + if(iter) - quadtree_node_drop_garbage(this_, iter); - + quadtree_node_drop_garbage(this_, iter); + if(QUADTREE_NODE_CAPACITY-1 == this_->node_num) { - double lon, lat; - //avoid infinite recursion when all elements have the same coordinate - lon = this_->items[0]->longitude; - lat = this_->items[0]->latitude; - for(i=1;i<this_->node_num;++i) { - if (lon != this_->items[i]->longitude || lat != this_->items[i]->latitude) { - bSame = 0; - break; + double lon, lat; + //avoid infinite recursion when all elements have the same coordinate + lon = this_->items[0]->longitude; + lat = this_->items[0]->latitude; + for(i=1; i<this_->node_num; ++i) { + if (lon != this_->items[i]->longitude || lat != this_->items[i]->latitude) { + bSame = 0; + break; + } + } + if (bSame) { + //FIXME: memleak and items thrown away if more than QUADTREE_NODE_CAPACITY-1 items with same coordinates added. + dbg(lvl_error,"Unable to add another item with same coordinates. Throwing item to the ground. Will leak %p.",item); + return; } - } - if (bSame) { - //FIXME: memleak and items thrown away if more than QUADTREE_NODE_CAPACITY-1 items with same coordinates added. - dbg(lvl_error,"Unable to add another item with same coordinates. Throwing item to the ground. Will leak %p.",item); - return; - } - this_->items[this_->node_num++] = item; - quadtree_split(this_); + this_->items[this_->node_num++] = item; + quadtree_split(this_); } else { - this_->items[this_->node_num++] = item; + this_->items[this_->node_num++] = item; } - } - else { + } else { if( - this_->xmin<=item->longitude && item->longitude<this_->xmin+(this_->xmax-this_->xmin)/2.0 && - this_->ymin<=item->latitude && item->latitude<this_->ymin+(this_->ymax-this_->ymin)/2.0 - ) { - if(!this_->aa) { - this_->aa = quadtree_node_new( this_, this_->xmin, this_->xmin+(this_->xmax-this_->xmin)/2.0 , this_->ymin, this_->ymin+(this_->ymax-this_->ymin)/2.0 ); - } - quadtree_add(this_->aa,item,iter); - } - else if( - this_->xmin+(this_->xmax-this_->xmin)/2.0<=item->longitude && item->longitude<this_->xmax && - this_->ymin<=item->latitude && item->latitude<this_->ymin+(this_->ymax-this_->ymin)/2.0 - ) { - if(!this_->ab) { - this_->ab = quadtree_node_new( this_, this_->xmin+(this_->xmax-this_->xmin)/2.0, this_->xmax , this_->ymin, this_->ymin+(this_->ymax-this_->ymin)/2.0 ); - } - quadtree_add(this_->ab,item,iter); - } - else if( - this_->xmin<=item->longitude && item->longitude<this_->xmin+(this_->xmax-this_->xmin)/2.0 && - this_->ymin+(this_->ymax-this_->ymin)/2.0<=item->latitude && item->latitude<this_->ymax - ) { - if(!this_->ba) { - this_->ba = quadtree_node_new( this_, this_->xmin, this_->xmin+(this_->xmax-this_->xmin)/2.0 , this_->ymin+(this_->ymax-this_->ymin)/2.0 , this_->ymax); - } - quadtree_add(this_->ba,item,iter); - } - else if( - this_->xmin+(this_->xmax-this_->xmin)/2.0<=item->longitude && item->longitude<this_->xmax && - this_->ymin+(this_->ymax-this_->ymin)/2.0<=item->latitude && item->latitude<this_->ymax - ) { - if(!this_->bb) { - this_->bb = quadtree_node_new( this_, this_->xmin+(this_->xmax-this_->xmin)/2.0, this_->xmax , this_->ymin+(this_->ymax-this_->ymin)/2.0 , this_->ymax); - } - quadtree_add(this_->bb,item,iter); + this_->xmin<=item->longitude && item->longitude<this_->xmin+(this_->xmax-this_->xmin)/2.0 && + this_->ymin<=item->latitude && item->latitude<this_->ymin+(this_->ymax-this_->ymin)/2.0 + ) { + if(!this_->aa) { + this_->aa = quadtree_node_new( this_, this_->xmin, this_->xmin+(this_->xmax-this_->xmin)/2.0, this_->ymin, + this_->ymin+(this_->ymax-this_->ymin)/2.0 ); + } + quadtree_add(this_->aa,item,iter); + } else if( + this_->xmin+(this_->xmax-this_->xmin)/2.0<=item->longitude && item->longitude<this_->xmax && + this_->ymin<=item->latitude && item->latitude<this_->ymin+(this_->ymax-this_->ymin)/2.0 + ) { + if(!this_->ab) { + this_->ab = quadtree_node_new( this_, this_->xmin+(this_->xmax-this_->xmin)/2.0, this_->xmax, this_->ymin, + this_->ymin+(this_->ymax-this_->ymin)/2.0 ); + } + quadtree_add(this_->ab,item,iter); + } else if( + this_->xmin<=item->longitude && item->longitude<this_->xmin+(this_->xmax-this_->xmin)/2.0 && + this_->ymin+(this_->ymax-this_->ymin)/2.0<=item->latitude && item->latitude<this_->ymax + ) { + if(!this_->ba) { + this_->ba = quadtree_node_new( this_, this_->xmin, this_->xmin+(this_->xmax-this_->xmin)/2.0, + this_->ymin+(this_->ymax-this_->ymin)/2.0, this_->ymax); + } + quadtree_add(this_->ba,item,iter); + } else if( + this_->xmin+(this_->xmax-this_->xmin)/2.0<=item->longitude && item->longitude<this_->xmax && + this_->ymin+(this_->ymax-this_->ymin)/2.0<=item->latitude && item->latitude<this_->ymax + ) { + if(!this_->bb) { + this_->bb = quadtree_node_new( this_, this_->xmin+(this_->xmax-this_->xmin)/2.0, this_->xmax, + this_->ymin+(this_->ymax-this_->ymin)/2.0, this_->ymax); + } + quadtree_add(this_->bb,item,iter); } } } @@ -479,42 +461,43 @@ void quadtree_split(struct quadtree_node* this_) { int i; this_->is_leaf = 0; - for(i=0;i<this_->node_num;++i) { + for(i=0; i<this_->node_num; ++i) { if( - this_->xmin<=this_->items[i]->longitude && this_->items[i]->longitude<this_->xmin+(this_->xmax-this_->xmin)/2.0 && - this_->ymin<=this_->items[i]->latitude && this_->items[i]->latitude<this_->ymin+(this_->ymax-this_->ymin)/2.0 - ) { - if(!this_->aa) { - this_->aa = quadtree_node_new( this_, this_->xmin, this_->xmin+(this_->xmax-this_->xmin)/2.0 , this_->ymin, this_->ymin+(this_->ymax-this_->ymin)/2.0 ); - } - quadtree_add(this_->aa,this_->items[i],NULL); - } - else if( - this_->xmin+(this_->xmax-this_->xmin)/2.0<=this_->items[i]->longitude && this_->items[i]->longitude<this_->xmax && - this_->ymin<=this_->items[i]->latitude && this_->items[i]->latitude<this_->ymin+(this_->ymax-this_->ymin)/2.0 - ) { - if(!this_->ab) { - this_->ab = quadtree_node_new( this_, this_->xmin+(this_->xmax-this_->xmin)/2.0, this_->xmax , this_->ymin, this_->ymin+(this_->ymax-this_->ymin)/2.0 ); - } - quadtree_add(this_->ab,this_->items[i],NULL); - } - else if( - this_->xmin<=this_->items[i]->longitude && this_->items[i]->longitude<this_->xmin+(this_->xmax-this_->xmin)/2.0 && - this_->ymin+(this_->ymax-this_->ymin)/2.0<=this_->items[i]->latitude && this_->items[i]->latitude<this_->ymax - ) { - if(!this_->ba) { - this_->ba = quadtree_node_new( this_, this_->xmin, this_->xmin+(this_->xmax-this_->xmin)/2.0 , this_->ymin+(this_->ymax-this_->ymin)/2.0 , this_->ymax); - } - quadtree_add(this_->ba,this_->items[i],NULL); - } - else if( - this_->xmin+(this_->xmax-this_->xmin)/2.0<=this_->items[i]->longitude && this_->items[i]->longitude<this_->xmax && - this_->ymin+(this_->ymax-this_->ymin)/2.0<=this_->items[i]->latitude && this_->items[i]->latitude<this_->ymax - ) { - if(!this_->bb) { - this_->bb = quadtree_node_new( this_, this_->xmin+(this_->xmax-this_->xmin)/2.0, this_->xmax , this_->ymin+(this_->ymax-this_->ymin)/2.0 , this_->ymax); - } - quadtree_add(this_->bb,this_->items[i],NULL); + this_->xmin<=this_->items[i]->longitude && this_->items[i]->longitude<this_->xmin+(this_->xmax-this_->xmin)/2.0 && + this_->ymin<=this_->items[i]->latitude && this_->items[i]->latitude<this_->ymin+(this_->ymax-this_->ymin)/2.0 + ) { + if(!this_->aa) { + this_->aa = quadtree_node_new( this_, this_->xmin, this_->xmin+(this_->xmax-this_->xmin)/2.0, this_->ymin, + this_->ymin+(this_->ymax-this_->ymin)/2.0 ); + } + quadtree_add(this_->aa,this_->items[i],NULL); + } else if( + this_->xmin+(this_->xmax-this_->xmin)/2.0<=this_->items[i]->longitude && this_->items[i]->longitude<this_->xmax && + this_->ymin<=this_->items[i]->latitude && this_->items[i]->latitude<this_->ymin+(this_->ymax-this_->ymin)/2.0 + ) { + if(!this_->ab) { + this_->ab = quadtree_node_new( this_, this_->xmin+(this_->xmax-this_->xmin)/2.0, this_->xmax, this_->ymin, + this_->ymin+(this_->ymax-this_->ymin)/2.0 ); + } + quadtree_add(this_->ab,this_->items[i],NULL); + } else if( + this_->xmin<=this_->items[i]->longitude && this_->items[i]->longitude<this_->xmin+(this_->xmax-this_->xmin)/2.0 && + this_->ymin+(this_->ymax-this_->ymin)/2.0<=this_->items[i]->latitude && this_->items[i]->latitude<this_->ymax + ) { + if(!this_->ba) { + this_->ba = quadtree_node_new( this_, this_->xmin, this_->xmin+(this_->xmax-this_->xmin)/2.0, + this_->ymin+(this_->ymax-this_->ymin)/2.0, this_->ymax); + } + quadtree_add(this_->ba,this_->items[i],NULL); + } else if( + this_->xmin+(this_->xmax-this_->xmin)/2.0<=this_->items[i]->longitude && this_->items[i]->longitude<this_->xmax && + this_->ymin+(this_->ymax-this_->ymin)/2.0<=this_->items[i]->latitude && this_->items[i]->latitude<this_->ymax + ) { + if(!this_->bb) { + this_->bb = quadtree_node_new( this_, this_->xmin+(this_->xmax-this_->xmin)/2.0, this_->xmax, + this_->ymin+(this_->ymax-this_->ymin)/2.0, this_->ymax); + } + quadtree_add(this_->bb,this_->items[i],NULL); } this_->items[i]=NULL; } @@ -525,19 +508,19 @@ void quadtree_destroy(struct quadtree_node* this_) { if(this_->aa) { quadtree_destroy(this_->aa); - this_->aa = NULL; + this_->aa = NULL; } if(this_->ab) { quadtree_destroy(this_->ab); - this_->ab = NULL; + this_->ab = NULL; } if(this_->ba) { quadtree_destroy(this_->ba); - this_->ba = NULL; + this_->ba = NULL; } if(this_->bb) { quadtree_destroy(this_->bb); - this_->bb = NULL; + this_->bb = NULL; } free(this_); } @@ -553,32 +536,32 @@ quadtree_destroy(struct quadtree_node* this_) { * @param item_free_context data to be passed as a first parameter to item_free function * @return pointer to the quad tree iteration structure. */ -struct quadtree_iter *quadtree_query(struct quadtree_node *this_, double dXMin, double dXMax, double dYMin, double dYMax,void (*item_free)(void *context, struct quadtree_item *qitem), void *item_free_context) -{ - struct quadtree_iter *ret=g_new0(struct quadtree_iter,1); - struct quadtree_iter_node *n=g_new0(struct quadtree_iter_node,1); - ret->xmin=dXMin; - ret->xmax=dXMax; - ret->ymin=dYMin; - ret->ymax=dYMax; - dbg(lvl_debug,"%f %f %f %f",dXMin,dXMax,dYMin,dYMax) - ret->item_free=item_free; - ret->item_free_context=item_free_context; - n->node=this_; - ret->iter_nodes=g_list_prepend(ret->iter_nodes,n); - n->is_leaf=this_->is_leaf; - if(this_->is_leaf) { - int i; - n->node_num=this_->node_num; - for(i=0;i<n->node_num;i++) { - n->items[i]=this_->items[i]; - n->items[i]->ref_count++; - } - } - - this_->ref_count++; - dbg(lvl_debug,"Query %p ",this_) - return ret; +struct quadtree_iter *quadtree_query(struct quadtree_node *this_, double dXMin, double dXMax, double dYMin, + double dYMax,void (*item_free)(void *context, struct quadtree_item *qitem), void *item_free_context) { + struct quadtree_iter *ret=g_new0(struct quadtree_iter,1); + struct quadtree_iter_node *n=g_new0(struct quadtree_iter_node,1); + ret->xmin=dXMin; + ret->xmax=dXMax; + ret->ymin=dYMin; + ret->ymax=dYMax; + dbg(lvl_debug,"%f %f %f %f",dXMin,dXMax,dYMin,dYMax) + ret->item_free=item_free; + ret->item_free_context=item_free_context; + n->node=this_; + ret->iter_nodes=g_list_prepend(ret->iter_nodes,n); + n->is_leaf=this_->is_leaf; + if(this_->is_leaf) { + int i; + n->node_num=this_->node_num; + for(i=0; i<n->node_num; i++) { + n->items[i]=this_->items[i]; + n->items[i]->ref_count++; + } + } + + this_->ref_count++; + dbg(lvl_debug,"Query %p ",this_) + return ret; } @@ -586,12 +569,11 @@ struct quadtree_iter *quadtree_query(struct quadtree_node *this_, double dXMin, * @brief End iteration. * @param iter Pointer to the quadtree iteration structure. */ -void quadtree_query_free(struct quadtree_iter *iter) -{ - //Get the rest of the data to collect garbage and dereference all the items/nodes - //TODO: No need to iterate the whole tree here. Just dereference nodes/items (if any). - while(quadtree_item_next(iter)); - g_free(iter); +void quadtree_query_free(struct quadtree_iter *iter) { + //Get the rest of the data to collect garbage and dereference all the items/nodes + //TODO: No need to iterate the whole tree here. Just dereference nodes/items (if any). + while(quadtree_item_next(iter)); + g_free(iter); } @@ -599,10 +581,9 @@ void quadtree_query_free(struct quadtree_iter *iter) * @brief Mark current item of iterator for deletion. * @param iter Pointer to the quadtree iteration structure. */ -void quadtree_item_delete(struct quadtree_iter *iter) -{ - if(iter->item) - iter->item->deleted=1; +void quadtree_item_delete(struct quadtree_iter *iter) { + if(iter->item) + iter->item->deleted=1; } /* @@ -610,118 +591,119 @@ void quadtree_item_delete(struct quadtree_iter *iter) * @param iter Pointer to the quadtree iteration structure. * @return pointer to the next item, or NULL if no items are left. */ -struct quadtree_item * quadtree_item_next(struct quadtree_iter *iter) -{ - struct quadtree_iter_node *iter_node; - struct quadtree_node *subnode; - - if(iter->item) { - iter->item->ref_count--; - iter->item=NULL; - } - - while(iter->iter_nodes) { - struct quadtree_node *nodes[4]; - int i; - iter_node=iter->iter_nodes->data; - - if(iter_node->is_leaf) { - /* Try to find undeleted item in the current node */ - dbg(lvl_debug,"find item %p %p ...",iter->iter_nodes,iter->iter_nodes->data); - while(iter_node->item<iter_node->node_num) { - dbg(lvl_debug,"%d %d",iter_node->item,iter_node->items[iter_node->item]->deleted); - if(iter_node->items[iter_node->item]->deleted) { - iter_node->item++; - continue; - } - iter->item=iter_node->items[iter_node->item]; - iter_node->item++; - dbg(lvl_debug,"Returning %p",iter->item); - iter->item->ref_count++; - return iter->item; - } - for(i=0;i<iter_node->node_num;i++) { - iter_node->items[i]->ref_count--; - } - } else { - /* No items left, try to find non-empty subnode */ - nodes[0]=iter_node->node->aa; - nodes[1]=iter_node->node->ab; - nodes[2]=iter_node->node->ba; - nodes[3]=iter_node->node->bb; - - for(subnode=NULL;!subnode && iter_node->subnode<4;iter_node->subnode++) { - i=iter_node->subnode; - if(!nodes[i] || !rects_overlap(nodes[i]->xmin, nodes[i]->ymin, nodes[i]->xmax, nodes[i]->ymax, iter->xmin, iter->ymin, iter->xmax, iter->ymax)) - continue; - dbg(lvl_debug,"%f %f %f %f",nodes[i]->xmin, nodes[i]->xmax, nodes[i]->ymin, nodes[i]->ymax) - subnode=nodes[i]; - } - - if(subnode) { - /* Go one level deeper */ - dbg(lvl_debug,"Go one level deeper..."); - iter_node=g_new0(struct quadtree_iter_node, 1); - iter_node->node=subnode; - iter_node->is_leaf=subnode->is_leaf; - if(iter_node->is_leaf) { - int i; - iter_node->node_num=subnode->node_num; - for(i=0;i<iter_node->node_num;i++) { - iter_node->items[i]=subnode->items[i]; - iter_node->items[i]->ref_count++; - } - } - subnode->ref_count++; - iter->iter_nodes=g_list_prepend(iter->iter_nodes,iter_node); - continue; - } - } - - /* No nodes and items left, fix up current subnode... */ - iter_node=iter->iter_nodes->data; - subnode=iter_node->node; - subnode->ref_count--; - - if(!subnode->aa && !subnode->ab && !subnode->ba && !subnode->bb) - subnode->is_leaf=1; - - /* 1. free deleted unreferenced items */ - quadtree_node_drop_garbage(subnode, iter); - - /* 2. remove empty leaf subnode if it's unreferenced */ - - if(!subnode->ref_count && !subnode->node_num && subnode->is_leaf ) { - dbg(lvl_debug,"Going to delete an empty unreferenced leaf subnode..."); - - if(subnode->parent) { - if(subnode->parent->aa==subnode) { - subnode->parent->aa=NULL; - } else if(subnode->parent->ab==subnode) { - subnode->parent->ab=NULL; - } else if(subnode->parent->ba==subnode) { - subnode->parent->ba=NULL; - } else if(subnode->parent->bb==subnode) { - subnode->parent->bb=NULL; - } else { - dbg(lvl_error,"Found Quadtree structure corruption while trying to free an empty node."); - } - - if(!subnode->parent->aa && !subnode->parent->ab && !subnode->parent->ba && !subnode->parent->bb ) - subnode->parent->is_leaf=1; - g_free(subnode); - } else - dbg(lvl_debug,"Quadtree is empty. NOT deleting the root subnode..."); - - } - - /* Go one step towards root */ - dbg(lvl_info,"Going towards root..."); - g_free(iter->iter_nodes->data); - iter->iter_nodes=g_list_delete_link(iter->iter_nodes,iter->iter_nodes); - } - - iter->item=NULL; - return NULL; +struct quadtree_item * quadtree_item_next(struct quadtree_iter *iter) { + struct quadtree_iter_node *iter_node; + struct quadtree_node *subnode; + + if(iter->item) { + iter->item->ref_count--; + iter->item=NULL; + } + + while(iter->iter_nodes) { + struct quadtree_node *nodes[4]; + int i; + iter_node=iter->iter_nodes->data; + + if(iter_node->is_leaf) { + /* Try to find undeleted item in the current node */ + dbg(lvl_debug,"find item %p %p ...",iter->iter_nodes,iter->iter_nodes->data); + while(iter_node->item<iter_node->node_num) { + dbg(lvl_debug,"%d %d",iter_node->item,iter_node->items[iter_node->item]->deleted); + if(iter_node->items[iter_node->item]->deleted) { + iter_node->item++; + continue; + } + iter->item=iter_node->items[iter_node->item]; + iter_node->item++; + dbg(lvl_debug,"Returning %p",iter->item); + iter->item->ref_count++; + return iter->item; + } + for(i=0; i<iter_node->node_num; i++) { + iter_node->items[i]->ref_count--; + } + } else { + /* No items left, try to find non-empty subnode */ + nodes[0]=iter_node->node->aa; + nodes[1]=iter_node->node->ab; + nodes[2]=iter_node->node->ba; + nodes[3]=iter_node->node->bb; + + for(subnode=NULL; !subnode && iter_node->subnode<4; iter_node->subnode++) { + i=iter_node->subnode; + if(!nodes[i] + || !rects_overlap(nodes[i]->xmin, nodes[i]->ymin, nodes[i]->xmax, nodes[i]->ymax, iter->xmin, iter->ymin, iter->xmax, + iter->ymax)) + continue; + dbg(lvl_debug,"%f %f %f %f",nodes[i]->xmin, nodes[i]->xmax, nodes[i]->ymin, nodes[i]->ymax) + subnode=nodes[i]; + } + + if(subnode) { + /* Go one level deeper */ + dbg(lvl_debug,"Go one level deeper..."); + iter_node=g_new0(struct quadtree_iter_node, 1); + iter_node->node=subnode; + iter_node->is_leaf=subnode->is_leaf; + if(iter_node->is_leaf) { + int i; + iter_node->node_num=subnode->node_num; + for(i=0; i<iter_node->node_num; i++) { + iter_node->items[i]=subnode->items[i]; + iter_node->items[i]->ref_count++; + } + } + subnode->ref_count++; + iter->iter_nodes=g_list_prepend(iter->iter_nodes,iter_node); + continue; + } + } + + /* No nodes and items left, fix up current subnode... */ + iter_node=iter->iter_nodes->data; + subnode=iter_node->node; + subnode->ref_count--; + + if(!subnode->aa && !subnode->ab && !subnode->ba && !subnode->bb) + subnode->is_leaf=1; + + /* 1. free deleted unreferenced items */ + quadtree_node_drop_garbage(subnode, iter); + + /* 2. remove empty leaf subnode if it's unreferenced */ + + if(!subnode->ref_count && !subnode->node_num && subnode->is_leaf ) { + dbg(lvl_debug,"Going to delete an empty unreferenced leaf subnode..."); + + if(subnode->parent) { + if(subnode->parent->aa==subnode) { + subnode->parent->aa=NULL; + } else if(subnode->parent->ab==subnode) { + subnode->parent->ab=NULL; + } else if(subnode->parent->ba==subnode) { + subnode->parent->ba=NULL; + } else if(subnode->parent->bb==subnode) { + subnode->parent->bb=NULL; + } else { + dbg(lvl_error,"Found Quadtree structure corruption while trying to free an empty node."); + } + + if(!subnode->parent->aa && !subnode->parent->ab && !subnode->parent->ba && !subnode->parent->bb ) + subnode->parent->is_leaf=1; + g_free(subnode); + } else + dbg(lvl_debug,"Quadtree is empty. NOT deleting the root subnode..."); + + } + + /* Go one step towards root */ + dbg(lvl_info,"Going towards root..."); + g_free(iter->iter_nodes->data); + iter->iter_nodes=g_list_delete_link(iter->iter_nodes,iter->iter_nodes); + } + + iter->item=NULL; + return NULL; } diff --git a/navit/map/filter/filter.c b/navit/map/filter/filter.c index 78d09e5b9..320164203 100644 --- a/navit/map/filter/filter.c +++ b/navit/map/filter/filter.c @@ -38,398 +38,378 @@ #include "endianess.h" struct filter_entry { - enum item_type first,last; - enum attr_type cond_attr; - char *cond_str; + enum item_type first,last; + enum attr_type cond_attr; + char *cond_str; }; struct filter { - GList *old; - GList *new; + GList *old; + GList *new; }; struct map_priv { - struct map *parent; - GList *filters; + struct map *parent; + GList *filters; }; struct map_rect_priv { - struct map_selection *sel; - struct map_priv *m; - struct map_rect *parent; - struct item item,*parent_item; + struct map_selection *sel; + struct map_priv *m; + struct map_rect *parent; + struct item item,*parent_item; }; struct map_search_priv { - struct map_rect_priv *mr; + struct map_rect_priv *mr; }; static enum item_type -filter_type(struct map_priv *m, struct item *item) -{ - GList *filters=m->filters; - struct filter_entry *entry; - while (filters) { - struct filter *filter=filters->data; - int pos=0,count=0; - GList *old,*new; - old=filter->old; - while (old) { - entry=old->data; - if (item->type >= entry->first && item->type <= entry->last) - break; - pos+=entry->last-entry->first+1; - old=g_list_next(old); - } - if (old && entry && entry->cond_attr != attr_none) { - struct attr attr; - if (entry->cond_attr == attr_id) { - char idstr[64]; - sprintf(idstr,"0x%x 0x%x",item->id_hi,item->id_lo); - if (strcmp(entry->cond_str, idstr)) - old=NULL; - } else if (!item_attr_get(item, entry->cond_attr, &attr)) { - old=NULL; - } else { - char *wildcard=strchr(entry->cond_str,'*'); - int len; - if (!wildcard) - len=strlen(entry->cond_str)+1; - else - len=wildcard-entry->cond_str; - if (strncmp(entry->cond_str, attr.u.str, len)) - old=NULL; - } - item_attr_rewind(item); - } - if (old) { - new=filter->new; - if (!new) - return item->type; - while (new) { - struct filter_entry *entry=new->data; - count+=entry->last-entry->first+1; - new=g_list_next(new); - } - pos%=count; - new=filter->new; - while (new) { - struct filter_entry *entry=new->data; - if (pos <= entry->last-entry->first) - return entry->first+pos; - pos-=entry->last-entry->first+1; - new=g_list_next(new); - } - } - filters=g_list_next(filters); - } - return item->type; +filter_type(struct map_priv *m, struct item *item) { + GList *filters=m->filters; + struct filter_entry *entry; + while (filters) { + struct filter *filter=filters->data; + int pos=0,count=0; + GList *old,*new; + old=filter->old; + while (old) { + entry=old->data; + if (item->type >= entry->first && item->type <= entry->last) + break; + pos+=entry->last-entry->first+1; + old=g_list_next(old); + } + if (old && entry && entry->cond_attr != attr_none) { + struct attr attr; + if (entry->cond_attr == attr_id) { + char idstr[64]; + sprintf(idstr,"0x%x 0x%x",item->id_hi,item->id_lo); + if (strcmp(entry->cond_str, idstr)) + old=NULL; + } else if (!item_attr_get(item, entry->cond_attr, &attr)) { + old=NULL; + } else { + char *wildcard=strchr(entry->cond_str,'*'); + int len; + if (!wildcard) + len=strlen(entry->cond_str)+1; + else + len=wildcard-entry->cond_str; + if (strncmp(entry->cond_str, attr.u.str, len)) + old=NULL; + } + item_attr_rewind(item); + } + if (old) { + new=filter->new; + if (!new) + return item->type; + while (new) { + struct filter_entry *entry=new->data; + count+=entry->last-entry->first+1; + new=g_list_next(new); + } + pos%=count; + new=filter->new; + while (new) { + struct filter_entry *entry=new->data; + if (pos <= entry->last-entry->first) + return entry->first+pos; + pos-=entry->last-entry->first+1; + new=g_list_next(new); + } + } + filters=g_list_next(filters); + } + return item->type; } static void -free_filter_entry(struct filter_entry *filter) -{ - g_free(filter->cond_str); - g_free(filter); +free_filter_entry(struct filter_entry *filter) { + g_free(filter->cond_str); + g_free(filter); } static void -free_filter(struct filter *filter) -{ - g_list_foreach(filter->old, (GFunc)free_filter_entry, NULL); - g_list_free(filter->old); - filter->old=NULL; - g_list_foreach(filter->new, (GFunc)free_filter_entry, NULL); - g_list_free(filter->new); - filter->new=NULL; +free_filter(struct filter *filter) { + g_list_foreach(filter->old, (GFunc)free_filter_entry, NULL); + g_list_free(filter->old); + filter->old=NULL; + g_list_foreach(filter->new, (GFunc)free_filter_entry, NULL); + g_list_free(filter->new); + filter->new=NULL; } static void -free_filters(struct map_priv *m) -{ - g_list_foreach(m->filters, (GFunc)free_filter, NULL); - g_list_free(m->filters); - m->filters=NULL; +free_filters(struct map_priv *m) { + g_list_foreach(m->filters, (GFunc)free_filter, NULL); + g_list_free(m->filters); + m->filters=NULL; } static GList * -parse_filter(char *filter) -{ - GList *ret=NULL; - for (;;) { - char *condition,*range,*next=strchr(filter,','); - struct filter_entry *entry=g_new0(struct filter_entry, 1); - if (next) - *next++='\0'; - condition=strchr(filter,'['); - if (condition) - *condition++='\0'; - range=strchr(filter,'-'); - if (range) - *range++='\0'; - if (!strcmp(filter,"*") && !range) { - entry->first=type_none; - entry->last=type_last; - } else { - entry->first=item_from_name(filter); - if (range) - entry->last=item_from_name(range); - else - entry->last=entry->first; - } - if (condition) { - char *end=strchr(condition,']'); - char *eq=strchr(condition,'='); - if (end && eq && eq < end) { - *end='\0'; - *eq++='\0'; - if (eq[0] == '"' || eq[0] == '\'') { - char *quote=strchr(eq+1,eq[0]); - if (quote) { - eq++; - *quote='\0'; - } - } - entry->cond_attr=attr_from_name(condition); - entry->cond_str=g_strdup(eq); - } - } - ret=g_list_append(ret, entry); - if (!next) - break; - filter=next; - } - return ret; +parse_filter(char *filter) { + GList *ret=NULL; + for (;;) { + char *condition,*range,*next=strchr(filter,','); + struct filter_entry *entry=g_new0(struct filter_entry, 1); + if (next) + *next++='\0'; + condition=strchr(filter,'['); + if (condition) + *condition++='\0'; + range=strchr(filter,'-'); + if (range) + *range++='\0'; + if (!strcmp(filter,"*") && !range) { + entry->first=type_none; + entry->last=type_last; + } else { + entry->first=item_from_name(filter); + if (range) + entry->last=item_from_name(range); + else + entry->last=entry->first; + } + if (condition) { + char *end=strchr(condition,']'); + char *eq=strchr(condition,'='); + if (end && eq && eq < end) { + *end='\0'; + *eq++='\0'; + if (eq[0] == '"' || eq[0] == '\'') { + char *quote=strchr(eq+1,eq[0]); + if (quote) { + eq++; + *quote='\0'; + } + } + entry->cond_attr=attr_from_name(condition); + entry->cond_str=g_strdup(eq); + } + } + ret=g_list_append(ret, entry); + if (!next) + break; + filter=next; + } + return ret; } static void -parse_filters(struct map_priv *m, char *filter) -{ - char *filter_copy=g_strdup(filter); - char *str=filter_copy; - - free_filters(m); - for (;;) { - char *pos,*bracket,*eq,*next=strchr(str,';'); - struct filter *filter=g_new0(struct filter, 1); - if (next) - *next++='\0'; - pos=str; - for (;;) { - eq=strchr(pos,'='); - if (eq) { - bracket=strchr(pos,'['); - if (bracket && bracket < eq) { - bracket=strchr(pos,']'); - if (bracket) - pos=bracket+1; - else { - eq=NULL; - break; - } - } else { - *eq++='\0'; - break; - } - } else - break; - } - filter->old=parse_filter(str); - if (eq) - filter->new=parse_filter(eq); - m->filters=g_list_append(m->filters,filter); - if (!next) - break; - str=next; - } - g_free(filter_copy); +parse_filters(struct map_priv *m, char *filter) { + char *filter_copy=g_strdup(filter); + char *str=filter_copy; + + free_filters(m); + for (;;) { + char *pos,*bracket,*eq,*next=strchr(str,';'); + struct filter *filter=g_new0(struct filter, 1); + if (next) + *next++='\0'; + pos=str; + for (;;) { + eq=strchr(pos,'='); + if (eq) { + bracket=strchr(pos,'['); + if (bracket && bracket < eq) { + bracket=strchr(pos,']'); + if (bracket) + pos=bracket+1; + else { + eq=NULL; + break; + } + } else { + *eq++='\0'; + break; + } + } else + break; + } + filter->old=parse_filter(str); + if (eq) + filter->new=parse_filter(eq); + m->filters=g_list_append(m->filters,filter); + if (!next) + break; + str=next; + } + g_free(filter_copy); } static void -map_filter_coord_rewind(void *priv_data) -{ - struct map_rect_priv *mr=priv_data; - item_coord_rewind(mr->parent_item); +map_filter_coord_rewind(void *priv_data) { + struct map_rect_priv *mr=priv_data; + item_coord_rewind(mr->parent_item); } static int -map_filter_coord_get(void *priv_data, struct coord *c, int count) -{ - struct map_rect_priv *mr=priv_data; - return item_coord_get(mr->parent_item, c, count); +map_filter_coord_get(void *priv_data, struct coord *c, int count) { + struct map_rect_priv *mr=priv_data; + return item_coord_get(mr->parent_item, c, count); } static void -map_filter_attr_rewind(void *priv_data) -{ - struct map_rect_priv *mr=priv_data; - item_attr_rewind(mr->parent_item); +map_filter_attr_rewind(void *priv_data) { + struct map_rect_priv *mr=priv_data; + item_attr_rewind(mr->parent_item); } static int -map_filter_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct map_rect_priv *mr=priv_data; - return item_attr_get(mr->parent_item, attr_type, attr); +map_filter_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct map_rect_priv *mr=priv_data; + return item_attr_get(mr->parent_item, attr_type, attr); } static struct item_methods methods_filter = { - map_filter_coord_rewind, - map_filter_coord_get, - map_filter_attr_rewind, - map_filter_attr_get, + map_filter_coord_rewind, + map_filter_coord_get, + map_filter_attr_rewind, + map_filter_attr_get, }; static struct map_rect_priv * -map_filter_rect_new(struct map_priv *map, struct map_selection *sel) -{ - struct map_rect_priv *mr=NULL; - struct map_rect *parent; - parent=map_rect_new(map->parent, sel); - if (parent) { - mr=g_new0(struct map_rect_priv, 1); - mr->m=map; - mr->sel=sel; - mr->parent=parent; - mr->item.meth=&methods_filter; - mr->item.priv_data=mr; - } - return mr; +map_filter_rect_new(struct map_priv *map, struct map_selection *sel) { + struct map_rect_priv *mr=NULL; + struct map_rect *parent; + parent=map_rect_new(map->parent, sel); + if (parent) { + mr=g_new0(struct map_rect_priv, 1); + mr->m=map; + mr->sel=sel; + mr->parent=parent; + mr->item.meth=&methods_filter; + mr->item.priv_data=mr; + } + return mr; } static void -map_filter_rect_destroy(struct map_rect_priv *mr) -{ - map_rect_destroy(mr->parent); - g_free(mr); +map_filter_rect_destroy(struct map_rect_priv *mr) { + map_rect_destroy(mr->parent); + g_free(mr); } static struct item * -map_filter_rect_get_item(struct map_rect_priv *mr) -{ - mr->parent_item=map_rect_get_item(mr->parent); - if (!mr->parent_item) - return NULL; - mr->item.type=filter_type(mr->m,mr->parent_item); - mr->item.id_lo=mr->parent_item->id_lo; - mr->item.id_hi=mr->parent_item->id_hi; - return &mr->item; +map_filter_rect_get_item(struct map_rect_priv *mr) { + mr->parent_item=map_rect_get_item(mr->parent); + if (!mr->parent_item) + return NULL; + mr->item.type=filter_type(mr->m,mr->parent_item); + mr->item.id_lo=mr->parent_item->id_lo; + mr->item.id_hi=mr->parent_item->id_hi; + return &mr->item; } static struct item * -map_filter_rect_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo) -{ - dbg(lvl_debug,"enter"); - mr->parent_item=map_rect_get_item_byid(mr->parent, id_hi, id_lo); - if (!mr->parent_item) - return NULL; - mr->item.type=filter_type(mr->m,mr->parent_item); - mr->item.id_lo=mr->parent_item->id_lo; - mr->item.id_hi=mr->parent_item->id_hi; - return &mr->item; +map_filter_rect_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo) { + dbg(lvl_debug,"enter"); + mr->parent_item=map_rect_get_item_byid(mr->parent, id_hi, id_lo); + if (!mr->parent_item) + return NULL; + mr->item.type=filter_type(mr->m,mr->parent_item); + mr->item.id_lo=mr->parent_item->id_lo; + mr->item.id_hi=mr->parent_item->id_hi; + return &mr->item; } static struct map_search_priv * -map_filter_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial) -{ - dbg(lvl_debug,"enter"); - return NULL; +map_filter_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial) { + dbg(lvl_debug,"enter"); + return NULL; } static struct item * -map_filter_search_get_item(struct map_search_priv *map_search) -{ - dbg(lvl_debug,"enter"); - return NULL; +map_filter_search_get_item(struct map_search_priv *map_search) { + dbg(lvl_debug,"enter"); + return NULL; } static void -map_filter_search_destroy(struct map_search_priv *ms) -{ - dbg(lvl_debug,"enter"); +map_filter_search_destroy(struct map_search_priv *ms) { + dbg(lvl_debug,"enter"); } static void -map_filter_destroy(struct map_priv *m) -{ - map_destroy(m->parent); - g_free(m); +map_filter_destroy(struct map_priv *m) { + map_destroy(m->parent); + g_free(m); } static int -map_filter_set_attr(struct map_priv *m, struct attr *attr) -{ - switch (attr->type) { - case attr_filter: - parse_filters(m,attr->u.str); - return 1; - default: - return 0; - } +map_filter_set_attr(struct map_priv *m, struct attr *attr) { + switch (attr->type) { + case attr_filter: + parse_filters(m,attr->u.str); + return 1; + default: + return 0; + } } static struct map_methods map_methods_filter = { - projection_mg, - "utf-8", - map_filter_destroy, - map_filter_rect_new, - map_filter_rect_destroy, - map_filter_rect_get_item, - map_filter_rect_get_item_byid, - map_filter_search_new, - map_filter_search_destroy, - map_filter_search_get_item, - NULL, - NULL, - map_filter_set_attr, + projection_mg, + "utf-8", + map_filter_destroy, + map_filter_rect_new, + map_filter_rect_destroy, + map_filter_rect_get_item, + map_filter_rect_get_item_byid, + map_filter_search_new, + map_filter_search_destroy, + map_filter_search_get_item, + NULL, + NULL, + map_filter_set_attr, }; static struct map_priv * -map_filter_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) -{ - struct map_priv *m=NULL; - struct attr **parent_attrs,type,*subtype=attr_search(attrs, NULL, attr_subtype),*filter=attr_search(attrs, NULL, attr_filter); - struct map *map; - int i,j; - if (! subtype || !filter) - return NULL; - i=0; - while (attrs[i]) - i++; - parent_attrs=g_new(struct attr *,i+1); - i=0; - j=0; - while (attrs[i]) { - if (attrs[i]->type != attr_filter && attrs[i]->type != attr_type) { - if (attrs[i]->type == attr_subtype) { - type=*attrs[i]; - type.type = attr_type; - parent_attrs[j]=&type; - } else - parent_attrs[j]=attrs[i]; - j++; - } - i++; - } - parent_attrs[j]=NULL; - *meth=map_methods_filter; - map=map_new(NULL, parent_attrs); - if (map) { - m=g_new0(struct map_priv, 1); - m->parent=map; - parse_filters(m,filter->u.str); - } - g_free(parent_attrs); - return m; +map_filter_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) { + struct map_priv *m=NULL; + struct attr **parent_attrs,type,*subtype=attr_search(attrs, NULL, attr_subtype),*filter=attr_search(attrs, NULL, + attr_filter); + struct map *map; + int i,j; + if (! subtype || !filter) + return NULL; + i=0; + while (attrs[i]) + i++; + parent_attrs=g_new(struct attr *,i+1); + i=0; + j=0; + while (attrs[i]) { + if (attrs[i]->type != attr_filter && attrs[i]->type != attr_type) { + if (attrs[i]->type == attr_subtype) { + type=*attrs[i]; + type.type = attr_type; + parent_attrs[j]=&type; + } else + parent_attrs[j]=attrs[i]; + j++; + } + i++; + } + parent_attrs[j]=NULL; + *meth=map_methods_filter; + map=map_new(NULL, parent_attrs); + if (map) { + m=g_new0(struct map_priv, 1); + m->parent=map; + parse_filters(m,filter->u.str); + } + g_free(parent_attrs); + return m; } void -plugin_init(void) -{ - dbg(lvl_debug,"filter: plugin_init"); - plugin_register_category_map("filter", map_filter_new); +plugin_init(void) { + dbg(lvl_debug,"filter: plugin_init"); + plugin_register_category_map("filter", map_filter_new); } diff --git a/navit/map/garmin/gar2navit.c b/navit/map/garmin/gar2navit.c index 7c4450401..703895b69 100644 --- a/navit/map/garmin/gar2navit.c +++ b/navit/map/garmin/gar2navit.c @@ -12,9 +12,9 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - + Garmin and MapSource are registered trademarks or trademarks of Garmin Ltd. or one of its subsidiaries. @@ -54,165 +54,159 @@ GROUP is #include "gar2navit.h" static int add_def(struct gar2nav_conv *conv, int type, unsigned short minid, - unsigned short maxid, unsigned int group, char *ntype, - char *descr) -{ - enum item_type it; - struct gar2navit *g2n; - dlog(11, "group=%d type=%d routable=%u min=%04X max=%04X ntype=%s descr=%s\n", - group, type, minid, maxid, ntype, descr); - it = item_from_name(ntype); - if (it==type_none) { - dlog(1, "Please define: %s\n", ntype); - } - g2n = calloc(1, sizeof(*g2n)); - if (!g2n) - return -1; - g2n->id = minid; - g2n->maxid = maxid; - g2n->ntype = it; - g2n->descr = strdup(descr); - g2n->group = group; - if (type == 1) { - g2n->next = conv->points; - conv->points = g2n; - } else if (type == 2) { - g2n->next = conv->polylines; - conv->polylines = g2n; - } else if (type == 3) { - g2n->next = conv->polygons; - conv->polygons = g2n; - } - return 0; + unsigned short maxid, unsigned int group, char *ntype, + char *descr) { + enum item_type it; + struct gar2navit *g2n; + dlog(11, "group=%d type=%d routable=%u min=%04X max=%04X ntype=%s descr=%s\n", + group, type, minid, maxid, ntype, descr); + it = item_from_name(ntype); + if (it==type_none) { + dlog(1, "Please define: %s\n", ntype); + } + g2n = calloc(1, sizeof(*g2n)); + if (!g2n) + return -1; + g2n->id = minid; + g2n->maxid = maxid; + g2n->ntype = it; + g2n->descr = strdup(descr); + g2n->group = group; + if (type == 1) { + g2n->next = conv->points; + conv->points = g2n; + } else if (type == 2) { + g2n->next = conv->polylines; + conv->polylines = g2n; + } else if (type == 3) { + g2n->next = conv->polygons; + conv->polygons = g2n; + } + return 0; } -static int load_types_file(char *file, struct gar2nav_conv *conv) -{ - char buf[4096]; - char descr[4096]; - char ntype[4096]; - FILE *fp; - unsigned int minid, maxid, group; - int rc; - int type = -1; - - fp = fopen(file, "r"); - if (!fp) - return -1; - while (fgets(buf, sizeof(buf), fp)) { - if (*buf == '#' || *buf == '\n') - continue; - if (!strncasecmp(buf, "POINT", 5)) { - type = 1; - continue; - } else if (!strncasecmp(buf, "POI", 3)) { - type = 1; - continue; - } else if (!strncasecmp(buf, "POLYLINE", 8)) { - type = 2; - continue; - } else if (!strncasecmp(buf, "POLYGONE", 8)) { - type = 3; - continue; - } - // assume only lines are routable - rc = sscanf(buf, "%d, 0x%04X - 0x%04X = %[^\t , ] , %[^\n]", - &group, &minid, &maxid, ntype, descr); - if (rc != 5) { - maxid = 0; - rc = sscanf(buf, "%d,0x%04X = %[^\t, ], %[^\n]", - &group, &minid, ntype, descr); - if (rc != 4) { - dlog(1, "Invalid line rc=%d:[%s]\n",rc, buf); - dlog(1, "minid=%04X ntype=[%s] des=[%s]\n", - minid, ntype, descr); - continue; - } - } - add_def(conv, type, minid, maxid, group, ntype, descr); - } - fclose(fp); - return 1; +static int load_types_file(char *file, struct gar2nav_conv *conv) { + char buf[4096]; + char descr[4096]; + char ntype[4096]; + FILE *fp; + unsigned int minid, maxid, group; + int rc; + int type = -1; + + fp = fopen(file, "r"); + if (!fp) + return -1; + while (fgets(buf, sizeof(buf), fp)) { + if (*buf == '#' || *buf == '\n') + continue; + if (!strncasecmp(buf, "POINT", 5)) { + type = 1; + continue; + } else if (!strncasecmp(buf, "POI", 3)) { + type = 1; + continue; + } else if (!strncasecmp(buf, "POLYLINE", 8)) { + type = 2; + continue; + } else if (!strncasecmp(buf, "POLYGONE", 8)) { + type = 3; + continue; + } + // assume only lines are routable + rc = sscanf(buf, "%d, 0x%04X - 0x%04X = %[^\t , ] , %[^\n]", + &group, &minid, &maxid, ntype, descr); + if (rc != 5) { + maxid = 0; + rc = sscanf(buf, "%d,0x%04X = %[^\t, ], %[^\n]", + &group, &minid, ntype, descr); + if (rc != 4) { + dlog(1, "Invalid line rc=%d:[%s]\n",rc, buf); + dlog(1, "minid=%04X ntype=[%s] des=[%s]\n", + minid, ntype, descr); + continue; + } + } + add_def(conv, type, minid, maxid, group, ntype, descr); + } + fclose(fp); + return 1; } -struct gar2nav_conv *g2n_conv_load(char *file) -{ - struct gar2nav_conv *c; - int rc; - - c = calloc(1, sizeof(*c)); - if (!c) - return c; - rc = load_types_file(file, c); - if (rc < 0) { - dlog(1, "Failed to load: [%s]\n", file); - free(c); - return NULL; - } - return c; +struct gar2nav_conv *g2n_conv_load(char *file) { + struct gar2nav_conv *c; + int rc; + + c = calloc(1, sizeof(*c)); + if (!c) + return c; + rc = load_types_file(file, c); + if (rc < 0) { + dlog(1, "Failed to load: [%s]\n", file); + free(c); + return NULL; + } + return c; } -enum item_type g2n_get_type(struct gar2nav_conv *c, unsigned int type, unsigned short id) -{ - struct gar2navit *def = NULL; - int group; - group = (type >> G2N_KIND_SHIFT); - type &= ~G2N_KIND_MASK; - if (type == G2N_POINT) - def = c->points; - else if (type == G2N_POLYLINE) - def = c->polylines; - else if (type == G2N_POLYGONE) - def = c->polygons; - else { - dlog(1, "Unknown conversion type:%d\n", type); - return type_none; - } - - if (!def) { - dlog(5, "No conversion data for %d\n", type); - return type_none; - } - - while (def) { - if (def->group == group && - ((!def->maxid && def->id == id) || - (def->id <= id && id <= def->maxid))) - return def->ntype; - def = def->next; - } - dlog(5, "Type[%d]:ID:[%04X] unknown\n", type, id); - return type == G2N_POINT ? type_point_unkn : type_street_unkn; +enum item_type g2n_get_type(struct gar2nav_conv *c, unsigned int type, unsigned short id) { + struct gar2navit *def = NULL; + int group; + group = (type >> G2N_KIND_SHIFT); + type &= ~G2N_KIND_MASK; + if (type == G2N_POINT) + def = c->points; + else if (type == G2N_POLYLINE) + def = c->polylines; + else if (type == G2N_POLYGONE) + def = c->polygons; + else { + dlog(1, "Unknown conversion type:%d\n", type); + return type_none; + } + + if (!def) { + dlog(5, "No conversion data for %d\n", type); + return type_none; + } + + while (def) { + if (def->group == group && + ((!def->maxid && def->id == id) || + (def->id <= id && id <= def->maxid))) + return def->ntype; + def = def->next; + } + dlog(5, "Type[%d]:ID:[%04X] unknown\n", type, id); + return type == G2N_POINT ? type_point_unkn : type_street_unkn; } -char *g2n_get_descr(struct gar2nav_conv *c, int type, unsigned short id) -{ - struct gar2navit *def = NULL; - if (type == G2N_POINT) - def = c->points; - else if (type == G2N_POLYLINE) - def = c->polylines; - else if (type == G2N_POLYGONE) - def = c->polygons; - else { - dlog(1, "Unknown conversion type:%d\n", type); - return NULL; - } - while (def) { - if ((!def->maxid && def->id == id) || - (def->id <= id && id <= def->maxid)) - return def->descr; - def = def->next; - } - dlog(5, "Type[%d]:ID:[%04X] unknown\n", type, id); - return NULL; +char *g2n_get_descr(struct gar2nav_conv *c, int type, unsigned short id) { + struct gar2navit *def = NULL; + if (type == G2N_POINT) + def = c->points; + else if (type == G2N_POLYLINE) + def = c->polylines; + else if (type == G2N_POLYGONE) + def = c->polygons; + else { + dlog(1, "Unknown conversion type:%d\n", type); + return NULL; + } + while (def) { + if ((!def->maxid && def->id == id) || + (def->id <= id && id <= def->maxid)) + return def->descr; + def = def->next; + } + dlog(5, "Type[%d]:ID:[%04X] unknown\n", type, id); + return NULL; } #if 0 -int main(int argc, char **argv) -{ - load_types_file(argv[1], NULL); - return 0; +int main(int argc, char **argv) { + load_types_file(argv[1], NULL); + return 0; } #endif diff --git a/navit/map/garmin/garmin.c b/navit/map/garmin/garmin.c index 4ef32a28e..6bb83be48 100644 --- a/navit/map/garmin/garmin.c +++ b/navit/map/garmin/garmin.c @@ -12,9 +12,9 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - + Garmin and MapSource are registered trademarks or trademarks of Garmin Ltd. or one of its subsidiaries. @@ -50,937 +50,910 @@ static int map_id; struct map_priv { - int id; - char *filename; - struct gar2nav_conv *conv; - struct gar *g; + int id; + char *filename; + struct gar2nav_conv *conv; + struct gar *g; }; struct map_rect_priv { - int id; - struct coord_rect r; - char *label; // FIXME: Register all strings for searches - int limit; - struct map_priv *mpriv; - struct gmap *gmap; - struct gobject *cobj; - struct gobject *objs; - struct item item; - unsigned int last_coord; - void *last_itterated; - struct coord last_c; - void *last_oattr; - unsigned int last_attr; - struct gar_search *search; + int id; + struct coord_rect r; + char *label; // FIXME: Register all strings for searches + int limit; + struct map_priv *mpriv; + struct gmap *gmap; + struct gobject *cobj; + struct gobject *objs; + struct item item; + unsigned int last_coord; + void *last_itterated; + struct coord last_c; + void *last_oattr; + unsigned int last_attr; + struct gar_search *search; }; int garmin_debug = 10; -void -logfn(char *file, int line, int level, char *fmt, ...) -{ - va_list ap; - char fileline[256]; - int sz; - if (level > garmin_debug) - return; - va_start(ap, fmt); - sz = sprintf(fileline, "%s:%d:%d|", file, line, level); - debug_vprintf(0, "", strlen(""), fileline, sz, - 1, fmt, ap); - va_end(ap); +void +logfn(char *file, int line, int level, char *fmt, ...) { + va_list ap; + char fileline[256]; + int sz; + if (level > garmin_debug) + return; + va_start(ap, fmt); + sz = sprintf(fileline, "%s:%d:%d|", file, line, level); + debug_vprintf(0, "", strlen(""), fileline, sz, + 1, fmt, ap); + va_end(ap); } // need a base map and a map struct gscale { - char *label; - float scale; - int bits; + char *label; + float scale; + int bits; }; static struct gscale mapscales[] = { - {"7000 km", 70000.0, 8} - ,{"5000 km", 50000.0, 8} - ,{"3000 km", 30000.0, 9} - ,{"2000 km", 20000.0, 9} - ,{"1500 km", 15000.0, 10} - ,{"1000 km", 10000.0, 10} - ,{"700 km", 7000.0, 11} - ,{"500 km", 5000.0, 11} - ,{"300 km", 3000.0, 13} - ,{"200 km", 2000.0, 13} - ,{"150 km", 1500.0, 13} - ,{"100 km", 1000.0, 14} - ,{"70 km", 700.0, 15} - ,{"50 km", 500.0, 16} - ,{"30 km", 300.0, 16} - ,{"20 km", 200.0, 17} - ,{"15 km", 150.0, 17} - ,{"10 km", 100.0, 18} - ,{"7 km", 70.0, 18} - ,{"5 km", 50.0, 19} - ,{"3 km", 30.0, 19} - ,{"2 km", 20.0, 20} - ,{"1.5 km", 15.0, 22} - ,{"1 km", 10.0, 24} - ,{"700 m", 7.0, 24} - ,{"500 m", 5.0, 24} - ,{"300 m", 3.0, 24} - ,{"200 m", 2.0, 24} - ,{"150 m", 1.5, 24} - ,{"100 m", 1.0, 24} - ,{"70 m", 0.7, 24} - ,{"50 m", 0.5, 24} - ,{"30 m", 0.3, 24} - ,{"20 m", 0.2, 24} - ,{"15 m", 0.1, 24} - ,{"10 m", 0.15, 24} + {"7000 km", 70000.0, 8} + ,{"5000 km", 50000.0, 8} + ,{"3000 km", 30000.0, 9} + ,{"2000 km", 20000.0, 9} + ,{"1500 km", 15000.0, 10} + ,{"1000 km", 10000.0, 10} + ,{"700 km", 7000.0, 11} + ,{"500 km", 5000.0, 11} + ,{"300 km", 3000.0, 13} + ,{"200 km", 2000.0, 13} + ,{"150 km", 1500.0, 13} + ,{"100 km", 1000.0, 14} + ,{"70 km", 700.0, 15} + ,{"50 km", 500.0, 16} + ,{"30 km", 300.0, 16} + ,{"20 km", 200.0, 17} + ,{"15 km", 150.0, 17} + ,{"10 km", 100.0, 18} + ,{"7 km", 70.0, 18} + ,{"5 km", 50.0, 19} + ,{"3 km", 30.0, 19} + ,{"2 km", 20.0, 20} + ,{"1.5 km", 15.0, 22} + ,{"1 km", 10.0, 24} + ,{"700 m", 7.0, 24} + ,{"500 m", 5.0, 24} + ,{"300 m", 3.0, 24} + ,{"200 m", 2.0, 24} + ,{"150 m", 1.5, 24} + ,{"100 m", 1.0, 24} + ,{"70 m", 0.7, 24} + ,{"50 m", 0.5, 24} + ,{"30 m", 0.3, 24} + ,{"20 m", 0.2, 24} + ,{"15 m", 0.1, 24} + ,{"10 m", 0.15, 24} }; -static int -garmin_object_label(struct gobject *o, struct attr *attr) -{ - struct map_rect_priv *mr = o->priv_data; - char *codepage; - char *label; - if (!mr) { - dlog(1, "Error object do not have priv_data!!\n"); - return 0; - } - if (mr->label) { - free(mr->label); - } - label = gar_get_object_lbl(o); - if (label) { - codepage = gar_obj_codepage(o); - if (*codepage != 'a') { - mr->label = g_convert(label, -1,"utf-8",codepage,NULL,NULL,NULL); - free(label); - } else - mr->label = label; - } else { - mr->label = NULL; - return 0; - } - if (mr->label) { - char *cp = mr->label; - /* FIXME Process label and give only the visible part */ - if (*mr->label == '@' || *mr->label == '^') - cp++; - /* FIXME: If zoomlevel is high convert ^ in the string to spaces */ - attr->u.str = cp; - return 1; - } - return 0; +static int +garmin_object_label(struct gobject *o, struct attr *attr) { + struct map_rect_priv *mr = o->priv_data; + char *codepage; + char *label; + if (!mr) { + dlog(1, "Error object do not have priv_data!!\n"); + return 0; + } + if (mr->label) { + free(mr->label); + } + label = gar_get_object_lbl(o); + if (label) { + codepage = gar_obj_codepage(o); + if (*codepage != 'a') { + mr->label = g_convert(label, -1,"utf-8",codepage,NULL,NULL,NULL); + free(label); + } else + mr->label = label; + } else { + mr->label = NULL; + return 0; + } + if (mr->label) { + char *cp = mr->label; + /* FIXME Process label and give only the visible part */ + if (*mr->label == '@' || *mr->label == '^') + cp++; + /* FIXME: If zoomlevel is high convert ^ in the string to spaces */ + attr->u.str = cp; + return 1; + } + return 0; } -static int -garmin_object_debug(struct gobject *o, struct attr *attr) -{ - struct map_rect_priv *mr = o->priv_data; - if (!mr) { - dlog(1, "Error object do not have priv_data!!\n"); - return 0; - } - if (mr->label) - free(mr->label); - mr->label = gar_object_debug_str(o); - if (mr->label) { - attr->u.str = mr->label; - return 1; - } - return 0; +static int +garmin_object_debug(struct gobject *o, struct attr *attr) { + struct map_rect_priv *mr = o->priv_data; + if (!mr) { + dlog(1, "Error object do not have priv_data!!\n"); + return 0; + } + if (mr->label) + free(mr->label); + mr->label = gar_object_debug_str(o); + if (mr->label) { + attr->u.str = mr->label; + return 1; + } + return 0; } static struct map_search_priv * -gmap_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial) -{ - struct map_rect_priv *mr=g_new0(struct map_rect_priv, 1); - struct gar_search *gs; - int rc; - - dlog(1, "Called!\n"); - mr->mpriv=map; - gs = g_new0(struct gar_search,1); - if (!gs) { - dlog(1, "Can not init search \n"); - free(mr); - return NULL; - } - mr->search = gs; - switch (search->type) { - case attr_country_name: - gs->type = GS_COUNTRY; - break; - case attr_town_name: - gs->type = GS_CITY; - break; - case attr_town_postal: - gs->type = GS_ZIP; - break; - case attr_street_name: - gs->type = GS_ROAD; - break; +gmap_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial) { + struct map_rect_priv *mr=g_new0(struct map_rect_priv, 1); + struct gar_search *gs; + int rc; + + dlog(1, "Called!\n"); + mr->mpriv=map; + gs = g_new0(struct gar_search,1); + if (!gs) { + dlog(1, "Can not init search \n"); + free(mr); + return NULL; + } + mr->search = gs; + switch (search->type) { + case attr_country_name: + gs->type = GS_COUNTRY; + break; + case attr_town_name: + gs->type = GS_CITY; + break; + case attr_town_postal: + gs->type = GS_ZIP; + break; + case attr_street_name: + gs->type = GS_ROAD; + break; #if 0 /* someday */ - case attr_region_name: - case attr_intersection: - case attr_housenumber: + case attr_region_name: + case attr_intersection: + case attr_housenumber: #endif - default: - dlog(1, "Don't know how to search for %d\n", search->type); - goto out_err; - } - gs->match = partial ? GM_START : GM_EXACT; - gs->needle = strdup(search->u.str); - dlog(5, "Needle: %s\n", gs->needle); - - mr->gmap = gar_find_subfiles(mr->mpriv->g, gs, GO_GET_SEARCH); - if (!mr->gmap) { - dlog(1, "Can not init search \n"); - goto out_err; - } - rc = gar_get_objects(mr->gmap, 0, gs, &mr->objs, GO_GET_SEARCH); - if (rc < 0) { - dlog(1, "Error loading objects\n"); - goto out_err; - } - mr->cobj = mr->objs; - dlog(4, "Loaded %d objects\n", rc); - return (struct map_search_priv *)mr; + default: + dlog(1, "Don't know how to search for %d\n", search->type); + goto out_err; + } + gs->match = partial ? GM_START : GM_EXACT; + gs->needle = strdup(search->u.str); + dlog(5, "Needle: %s\n", gs->needle); + + mr->gmap = gar_find_subfiles(mr->mpriv->g, gs, GO_GET_SEARCH); + if (!mr->gmap) { + dlog(1, "Can not init search \n"); + goto out_err; + } + rc = gar_get_objects(mr->gmap, 0, gs, &mr->objs, GO_GET_SEARCH); + if (rc < 0) { + dlog(1, "Error loading objects\n"); + goto out_err; + } + mr->cobj = mr->objs; + dlog(4, "Loaded %d objects\n", rc); + return (struct map_search_priv *)mr; out_err: - free(gs); - free(mr); - return NULL; + free(gs); + free(mr); + return NULL; } /* Assumes that only one item will be itterated at time! */ -static void -coord_rewind(void *priv_data) -{ - struct gobject *g = priv_data; - struct map_rect_priv *mr = g->priv_data; - mr->last_coord = 0; +static void +coord_rewind(void *priv_data) { + struct gobject *g = priv_data; + struct map_rect_priv *mr = g->priv_data; + mr->last_coord = 0; }; -static void -attr_rewind(void *priv_data) -{ - struct gobject *g = priv_data; - struct map_rect_priv *mr = g->priv_data; - mr->last_attr = 0; +static void +attr_rewind(void *priv_data) { + struct gobject *g = priv_data; + struct map_rect_priv *mr = g->priv_data; + mr->last_attr = 0; }; -static int -point_coord_get(void *priv_data, struct coord *c, int count) -{ - struct gobject *g = priv_data; - struct map_rect_priv *mr = g->priv_data; - struct gcoord gc; - if (!count) - return 0; - if (g != mr->last_itterated) { - mr->last_itterated = g; - mr->last_coord = 0; - } - - if (mr->last_coord > 0) - return 0; - - gar_get_object_coord(mr->gmap, g, &gc); - c->x = gc.x; - c->y = gc.y; - mr->last_coord++; +static int +point_coord_get(void *priv_data, struct coord *c, int count) { + struct gobject *g = priv_data; + struct map_rect_priv *mr = g->priv_data; + struct gcoord gc; + if (!count) + return 0; + if (g != mr->last_itterated) { + mr->last_itterated = g; + mr->last_coord = 0; + } + + if (mr->last_coord > 0) + return 0; + + gar_get_object_coord(mr->gmap, g, &gc); + c->x = gc.x; + c->y = gc.y; + mr->last_coord++; // dlog(1,"point: x=%d y=%d\n", c->x, c->y); - // dlog(1, "point: x=%f y=%f\n", GARDEG(c->x), GARDEG(c->y)); - return 1; + // dlog(1, "point: x=%f y=%f\n", GARDEG(c->x), GARDEG(c->y)); + return 1; } static int -coord_is_node(void *priv_data) -{ - struct gobject *g = priv_data; - struct map_rect_priv *mr = g->priv_data; +coord_is_node(void *priv_data) { + struct gobject *g = priv_data; + struct map_rect_priv *mr = g->priv_data; - return gar_is_object_dcoord_node(mr->gmap, g, mr->last_coord); + return gar_is_object_dcoord_node(mr->gmap, g, mr->last_coord); } -static int -poly_coord_get(void *priv_data, struct coord *c, int count) -{ - struct gobject *g = priv_data; - struct map_rect_priv *mr = g->priv_data; - int ndeltas = 0, total = 0; - struct gcoord dc; - - if (!count) - return 0; - - if (g != mr->last_itterated) { - mr->last_itterated = g; - mr->last_coord = 0; - } - ndeltas = gar_get_object_deltas(g); - if (mr->last_coord > ndeltas + 1) - return 0; - while (count --) { - if (mr->last_coord == 0) { - gar_get_object_coord(mr->gmap, g, &dc); - mr->last_c.x = dc.x; - mr->last_c.y = dc.y; - } else { - if (!gar_get_object_dcoord(mr->gmap, g, mr->last_coord - 1, &dc)) { - mr->last_coord = ndeltas + 2; - return total; - } - mr->last_c.x += dc.x; - mr->last_c.y += dc.y; - } - c->x = mr->last_c.x; - c->y = mr->last_c.y; - ddlog(1, "poly: x=%f y=%f\n", GARDEG(c->x), GARDEG(c->y)); +static int +poly_coord_get(void *priv_data, struct coord *c, int count) { + struct gobject *g = priv_data; + struct map_rect_priv *mr = g->priv_data; + int ndeltas = 0, total = 0; + struct gcoord dc; + + if (!count) + return 0; + + if (g != mr->last_itterated) { + mr->last_itterated = g; + mr->last_coord = 0; + } + ndeltas = gar_get_object_deltas(g); + if (mr->last_coord > ndeltas + 1) + return 0; + while (count --) { + if (mr->last_coord == 0) { + gar_get_object_coord(mr->gmap, g, &dc); + mr->last_c.x = dc.x; + mr->last_c.y = dc.y; + } else { + if (!gar_get_object_dcoord(mr->gmap, g, mr->last_coord - 1, &dc)) { + mr->last_coord = ndeltas + 2; + return total; + } + mr->last_c.x += dc.x; + mr->last_c.y += dc.y; + } + c->x = mr->last_c.x; + c->y = mr->last_c.y; + ddlog(1, "poly: x=%f y=%f\n", GARDEG(c->x), GARDEG(c->y)); // dlog(1,"poly: x=%d y=%d\n", c->x, c->y); - c++; - total++; - mr->last_coord ++; - } - return total; + c++; + total++; + mr->last_coord ++; + } + return total; } -// for _any we must return one by one -static int -point_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct gobject *g = priv_data; - struct map_rect_priv *mr = g->priv_data; - int rc; - switch (attr_type) { - case attr_any: - if (g != mr->last_oattr) { - mr->last_oattr = g; - mr->last_attr = 0; - } - switch(mr->last_attr) { - case 0: - mr->last_attr++; - attr->type = attr_label; - rc = garmin_object_label(g, attr); - if (rc) - return rc; - case 1: - mr->last_attr++; - attr->type = attr_debug; - rc = garmin_object_debug(g, attr); - if (rc) - return rc; - case 2: - mr->last_attr++; - if (g->type == GO_POLYLINE) { - attr->type = attr_street_name; - rc = garmin_object_label(g, attr); - if (rc) - return rc; - } - case 3: - mr->last_attr++; - attr->type = attr_flags; - attr->u.num = 0; - rc = gar_object_flags(g); - if (rc & F_ONEWAY) - attr->u.num |= AF_ONEWAY; - if (rc & F_SEGMENTED) - attr->u.num |= AF_SEGMENTED; - return 1; - default: - return 0; - } - break; - case attr_label: - attr->type = attr_label; - return garmin_object_label(g, attr); - case attr_town_name: - attr->type = attr_town_name; - return garmin_object_label(g, attr); - case attr_street_name: - attr->type = attr_type; - return garmin_object_label(g, attr); - case attr_street_name_systematic: - /* TODO: Get secondary labels of roads */ - return 0; - case attr_flags: - attr->type = attr_flags; - attr->u.num = 0; - rc = gar_object_flags(g); - if (rc & F_ONEWAY) - attr->u.num |= AF_ONEWAY; - if (rc & F_SEGMENTED) - attr->u.num |= AF_SEGMENTED; - return 1; - default: - dlog(1, "Don't know about attribute %d[%04X]=%s yet\n", attr_type,attr_type, attr_to_name(attr_type)); - } - - return 0; +// for _any we must return one by one +static int +point_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct gobject *g = priv_data; + struct map_rect_priv *mr = g->priv_data; + int rc; + switch (attr_type) { + case attr_any: + if (g != mr->last_oattr) { + mr->last_oattr = g; + mr->last_attr = 0; + } + switch(mr->last_attr) { + case 0: + mr->last_attr++; + attr->type = attr_label; + rc = garmin_object_label(g, attr); + if (rc) + return rc; + case 1: + mr->last_attr++; + attr->type = attr_debug; + rc = garmin_object_debug(g, attr); + if (rc) + return rc; + case 2: + mr->last_attr++; + if (g->type == GO_POLYLINE) { + attr->type = attr_street_name; + rc = garmin_object_label(g, attr); + if (rc) + return rc; + } + case 3: + mr->last_attr++; + attr->type = attr_flags; + attr->u.num = 0; + rc = gar_object_flags(g); + if (rc & F_ONEWAY) + attr->u.num |= AF_ONEWAY; + if (rc & F_SEGMENTED) + attr->u.num |= AF_SEGMENTED; + return 1; + default: + return 0; + } + break; + case attr_label: + attr->type = attr_label; + return garmin_object_label(g, attr); + case attr_town_name: + attr->type = attr_town_name; + return garmin_object_label(g, attr); + case attr_street_name: + attr->type = attr_type; + return garmin_object_label(g, attr); + case attr_street_name_systematic: + /* TODO: Get secondary labels of roads */ + return 0; + case attr_flags: + attr->type = attr_flags; + attr->u.num = 0; + rc = gar_object_flags(g); + if (rc & F_ONEWAY) + attr->u.num |= AF_ONEWAY; + if (rc & F_SEGMENTED) + attr->u.num |= AF_SEGMENTED; + return 1; + default: + dlog(1, "Don't know about attribute %d[%04X]=%s yet\n", attr_type,attr_type, attr_to_name(attr_type)); + } + + return 0; } static struct item_methods methods_garmin_point = { - coord_rewind, - point_coord_get, - attr_rewind, - point_attr_get, + coord_rewind, + point_coord_get, + attr_rewind, + point_attr_get, }; static struct item_methods methods_garmin_poly = { - coord_rewind, - poly_coord_get, - attr_rewind, // point_attr_rewind, - point_attr_get, // poly_attr_get, - coord_is_node, + coord_rewind, + poly_coord_get, + attr_rewind, // point_attr_rewind, + point_attr_get, // poly_attr_get, + coord_is_node, }; static int -search_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct gobject *g = priv_data; - struct map_rect_priv *mr = g->priv_data; - int rc; - switch (attr_type) { - case attr_any: - if (g != mr->last_oattr) { - mr->last_oattr = g; - mr->last_attr = 0; - } - switch(mr->last_attr) { - case 0: - mr->last_attr++; - attr->type = attr_label; - rc = garmin_object_label(g, attr); - if (rc) - return rc; - case 1: - mr->last_attr++; - attr->type = attr_debug; - rc = garmin_object_debug(g, attr); - if (rc) - return rc; - case 2: - mr->last_attr++; - if (g->type == GO_POLYLINE) { - attr->type = attr_street_name; - rc = garmin_object_label(g, attr); - if (rc) - return rc; - } - case 3: - mr->last_attr++; - attr->type = attr_flags; - attr->u.num = 0; - rc = gar_object_flags(g); - if (rc & F_ONEWAY) - attr->u.num |= AF_ONEWAY; - if (rc & F_SEGMENTED) - attr->u.num |= AF_SEGMENTED; - return 1; - default: - return 0; - } - break; - case attr_label: - attr->type = attr_label; - return garmin_object_label(g, attr); - case attr_town_name: - attr->type = attr_town_name; - if (mr->label) - free(mr->label); - mr->label = gar_srch_get_city(g); - attr->u.str = mr->label; - if (attr->u.str) - return 1; - return 0; - case attr_town_id: - rc = gar_srch_get_cityid(g); - if (rc) { - attr->type = attr_town_id; - attr->u.num = rc; - return 1; - } - return 0; - case attr_town_postal: - attr->type = attr_town_postal; - attr->u.str = gar_srch_get_zip(g); - if (attr->u.str) - return 1; - return 0; - case attr_street_name: - attr->type = attr_street_name; - if (mr->label) - free(mr->label); - mr->label = gar_srch_get_roadname(g); - attr->u.str = mr->label; - if (attr->u.str) - return 1; - return 0; - case attr_street_id: - attr->type = attr_street_id; - attr->u.num = gar_srch_get_roadid(g); - if (attr->u.num) - return 1; - return 0; - case attr_flags: - attr->type = attr_flags; - attr->u.num = 0; - rc = gar_object_flags(g); - if (rc & F_ONEWAY) - attr->u.num |= AF_ONEWAY; - if (rc & F_SEGMENTED) - attr->u.num |= AF_SEGMENTED; - return 1; - case attr_country_id: - rc = gar_srch_get_countryid(g); - if (rc) { - attr->type = attr_country_id; - attr->u.num = rc; - return 1; - } - return 0; - case attr_country_name: - attr->type = attr_country_name; - attr->u.str = gar_srch_get_country(g); - if (attr->u.str) - return 1; - return 0; - case attr_district_id: - rc = gar_srch_get_regionid(g); - if (rc) { - attr->type = attr_district_id; - attr->u.num = rc; - return 1; - } - return 0; - case attr_district_name: - attr->type = attr_district_name; - attr->u.str = gar_srch_get_region(g); - if (attr->u.str) - return 1; - return 0; - case attr_town_streets_item: - return 0; - default: - dlog(1, "Don't know about attribute %d[%04X]=%s yet\n", - attr_type,attr_type, attr_to_name(attr_type)); - } - - return 0; +search_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct gobject *g = priv_data; + struct map_rect_priv *mr = g->priv_data; + int rc; + switch (attr_type) { + case attr_any: + if (g != mr->last_oattr) { + mr->last_oattr = g; + mr->last_attr = 0; + } + switch(mr->last_attr) { + case 0: + mr->last_attr++; + attr->type = attr_label; + rc = garmin_object_label(g, attr); + if (rc) + return rc; + case 1: + mr->last_attr++; + attr->type = attr_debug; + rc = garmin_object_debug(g, attr); + if (rc) + return rc; + case 2: + mr->last_attr++; + if (g->type == GO_POLYLINE) { + attr->type = attr_street_name; + rc = garmin_object_label(g, attr); + if (rc) + return rc; + } + case 3: + mr->last_attr++; + attr->type = attr_flags; + attr->u.num = 0; + rc = gar_object_flags(g); + if (rc & F_ONEWAY) + attr->u.num |= AF_ONEWAY; + if (rc & F_SEGMENTED) + attr->u.num |= AF_SEGMENTED; + return 1; + default: + return 0; + } + break; + case attr_label: + attr->type = attr_label; + return garmin_object_label(g, attr); + case attr_town_name: + attr->type = attr_town_name; + if (mr->label) + free(mr->label); + mr->label = gar_srch_get_city(g); + attr->u.str = mr->label; + if (attr->u.str) + return 1; + return 0; + case attr_town_id: + rc = gar_srch_get_cityid(g); + if (rc) { + attr->type = attr_town_id; + attr->u.num = rc; + return 1; + } + return 0; + case attr_town_postal: + attr->type = attr_town_postal; + attr->u.str = gar_srch_get_zip(g); + if (attr->u.str) + return 1; + return 0; + case attr_street_name: + attr->type = attr_street_name; + if (mr->label) + free(mr->label); + mr->label = gar_srch_get_roadname(g); + attr->u.str = mr->label; + if (attr->u.str) + return 1; + return 0; + case attr_street_id: + attr->type = attr_street_id; + attr->u.num = gar_srch_get_roadid(g); + if (attr->u.num) + return 1; + return 0; + case attr_flags: + attr->type = attr_flags; + attr->u.num = 0; + rc = gar_object_flags(g); + if (rc & F_ONEWAY) + attr->u.num |= AF_ONEWAY; + if (rc & F_SEGMENTED) + attr->u.num |= AF_SEGMENTED; + return 1; + case attr_country_id: + rc = gar_srch_get_countryid(g); + if (rc) { + attr->type = attr_country_id; + attr->u.num = rc; + return 1; + } + return 0; + case attr_country_name: + attr->type = attr_country_name; + attr->u.str = gar_srch_get_country(g); + if (attr->u.str) + return 1; + return 0; + case attr_district_id: + rc = gar_srch_get_regionid(g); + if (rc) { + attr->type = attr_district_id; + attr->u.num = rc; + return 1; + } + return 0; + case attr_district_name: + attr->type = attr_district_name; + attr->u.str = gar_srch_get_region(g); + if (attr->u.str) + return 1; + return 0; + case attr_town_streets_item: + return 0; + default: + dlog(1, "Don't know about attribute %d[%04X]=%s yet\n", + attr_type,attr_type, attr_to_name(attr_type)); + } + + return 0; } static int -search_coord_get(void *priv_data, struct coord *c, int count) -{ - struct gobject *g = priv_data; - struct map_rect_priv *mr = g->priv_data; - struct gcoord gc; - if (!count) - return 0; - if (g != mr->last_itterated) { - mr->last_itterated = g; - mr->last_coord = 0; - } - - if (mr->last_coord > 0) - return 0; - - if (gar_get_object_coord(mr->gmap, g, &gc)) { - c->x = gc.x; - c->y = gc.y; - mr->last_coord++; - return 1; - } - return 0; +search_coord_get(void *priv_data, struct coord *c, int count) { + struct gobject *g = priv_data; + struct map_rect_priv *mr = g->priv_data; + struct gcoord gc; + if (!count) + return 0; + if (g != mr->last_itterated) { + mr->last_itterated = g; + mr->last_coord = 0; + } + + if (mr->last_coord > 0) + return 0; + + if (gar_get_object_coord(mr->gmap, g, &gc)) { + c->x = gc.x; + c->y = gc.y; + mr->last_coord++; + return 1; + } + return 0; } static struct item_methods methods_garmin_search = { - coord_rewind, - search_coord_get, - attr_rewind, - search_attr_get, + coord_rewind, + search_coord_get, + attr_rewind, + search_attr_get, }; static struct item * -garmin_poi2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) -{ - if (mr->mpriv->conv) { - int mask = gar_object_group(o) << G2N_KIND_SHIFT; - mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POINT|mask, otype); - } - mr->item.meth = &methods_garmin_point; - return &mr->item; +garmin_poi2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) { + if (mr->mpriv->conv) { + int mask = gar_object_group(o) << G2N_KIND_SHIFT; + mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POINT|mask, otype); + } + mr->item.meth = &methods_garmin_point; + return &mr->item; } static struct item * -garmin_pl2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) -{ - if (mr->mpriv->conv) { - int mask = gar_object_group(o) << G2N_KIND_SHIFT; - mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYLINE|mask, otype); - } - mr->item.meth = &methods_garmin_poly; - return &mr->item; +garmin_pl2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) { + if (mr->mpriv->conv) { + int mask = gar_object_group(o) << G2N_KIND_SHIFT; + mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYLINE|mask, otype); + } + mr->item.meth = &methods_garmin_poly; + return &mr->item; } static struct item * -garmin_pg2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) -{ - if (mr->mpriv->conv) { - int mask = gar_object_group(o) << G2N_KIND_SHIFT; - mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYGONE|mask, otype); - } - mr->item.meth = &methods_garmin_poly; - return &mr->item; +garmin_pg2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) { + if (mr->mpriv->conv) { + int mask = gar_object_group(o) << G2N_KIND_SHIFT; + mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYGONE|mask, otype); + } + mr->item.meth = &methods_garmin_poly; + return &mr->item; } static struct item * -garmin_srch2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) -{ - mr->item.type = type_country_label; - mr->item.meth = &methods_garmin_search; - return &mr->item; +garmin_srch2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) { + mr->item.type = type_country_label; + mr->item.meth = &methods_garmin_search; + return &mr->item; } static struct item * -garmin_obj2item(struct map_rect_priv *mr, struct gobject *o) -{ - unsigned short otype; - otype = gar_obj_type(o); - mr->item.type = type_none; - switch (o->type) { - case GO_POINT: - return garmin_poi2item(mr, o, otype); - case GO_POLYLINE: - return garmin_pl2item(mr, o, otype); - case GO_POLYGON: - return garmin_pg2item(mr, o, otype); - case GO_ROAD: - return garmin_pl2item(mr, o, otype); +garmin_obj2item(struct map_rect_priv *mr, struct gobject *o) { + unsigned short otype; + otype = gar_obj_type(o); + mr->item.type = type_none; + switch (o->type) { + case GO_POINT: + return garmin_poi2item(mr, o, otype); + case GO_POLYLINE: + return garmin_pl2item(mr, o, otype); + case GO_POLYGON: + return garmin_pg2item(mr, o, otype); + case GO_ROAD: + return garmin_pl2item(mr, o, otype); #if 0 - case GO_SEARCH: - return garmin_srch2item(mr, o, otype); + case GO_SEARCH: + return garmin_srch2item(mr, o, otype); #endif - default: - dlog(1, "Unknown garmin object type:%d\n", - o->type); - } - return NULL; + default: + dlog(1, "Unknown garmin object type:%d\n", + o->type); + } + return NULL; } static struct item * -gmap_rect_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo) -{ - struct gobject *o; - o = mr->objs = gar_get_object_by_id(mr->mpriv->g, id_hi, id_lo); - if (!o) { - dlog(1, "Can not find object\n"); - return NULL; - } - - mr->item.id_hi = id_hi; - mr->item.id_lo = id_lo; - mr->item.priv_data = o; - mr->item.type = type_none; - o->priv_data = mr; - if (!garmin_obj2item(mr, o)) - return NULL; - return &mr->item; +gmap_rect_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo) { + struct gobject *o; + o = mr->objs = gar_get_object_by_id(mr->mpriv->g, id_hi, id_lo); + if (!o) { + dlog(1, "Can not find object\n"); + return NULL; + } + + mr->item.id_hi = id_hi; + mr->item.id_lo = id_lo; + mr->item.priv_data = o; + mr->item.type = type_none; + o->priv_data = mr; + if (!garmin_obj2item(mr, o)) + return NULL; + return &mr->item; } static struct item * -gmap_rect_get_item(struct map_rect_priv *mr) -{ - struct gobject *o; - if (!mr->objs) - return NULL; - if (!mr->cobj) - return NULL; - // mr->cobj = mr->objs; - o = mr->cobj; +gmap_rect_get_item(struct map_rect_priv *mr) { + struct gobject *o; + if (!mr->objs) + return NULL; + if (!mr->cobj) + return NULL; + // mr->cobj = mr->objs; + o = mr->cobj; // dlog(1, "gi:o=%p\n", o); - mr->cobj = mr->cobj->next; - if (o) { - mr->item.id_hi = gar_object_mapid(o); - mr->item.id_lo = gar_object_index(o); - mr->item.priv_data = o; - mr->item.type = type_none; - o->priv_data = mr; - if (!garmin_obj2item(mr, o)) - return NULL; - return &mr->item; - } - return NULL; + mr->cobj = mr->cobj->next; + if (o) { + mr->item.id_hi = gar_object_mapid(o); + mr->item.id_lo = gar_object_index(o); + mr->item.priv_data = o; + mr->item.type = type_none; + o->priv_data = mr; + if (!garmin_obj2item(mr, o)) + return NULL; + return &mr->item; + } + return NULL; } #define max(a,b) ((a) > (b) ? (a) : (b)) struct nl2gl_t { - int g; - int bits; - char *descr; + int g; + int bits; + char *descr; }; -struct nl2gl_t nl2gl_1[] = { - { /* 0 */ .g = 12, .descr = "0-120m", }, - { /* 1 */ .g = 11, .descr = "0-120m", }, - { /* 2 */ .g = 10, .descr = "0-120m", }, - { /* 3 */ .g = 9, .descr = "0-120m", }, - { /* 4 */ .g = 8, .descr = "0-120m", }, - { /* 5 */ .g = 7, .descr = "0-120m", }, - { /* 6 */ .g = 6, .descr = "0-120m", }, - { /* 7 */ .g = 5, .descr = "0-120m", }, - { /* 8 */ .g = 4, .descr = "0-120m", }, - { /* 9 */ .g = 4, .descr = "0-120m", }, - { /* 10 */ .g = 3, .descr = "0-120m", }, - { /* 11 */ .g = 3, .descr = "0-120m", }, - { /* 12 */ .g = 2, .descr = "0-120m", }, - { /* 13 */ .g = 2, .descr = "0-120m", }, - { /* 14 */ .g = 2, .descr = "0-120m", }, - { /* 15 */ .g = 1, .descr = "0-120m", }, - { /* 16 */ .g = 1, .descr = "0-120m", }, - { /* 17 */ .g = 1, .descr = "0-120m", }, - { /* 18 */ .g = 0, .descr = "0-120m", }, +struct nl2gl_t nl2gl_1[] = { + { /* 0 */ .g = 12, .descr = "0-120m", }, + { /* 1 */ .g = 11, .descr = "0-120m", }, + { /* 2 */ .g = 10, .descr = "0-120m", }, + { /* 3 */ .g = 9, .descr = "0-120m", }, + { /* 4 */ .g = 8, .descr = "0-120m", }, + { /* 5 */ .g = 7, .descr = "0-120m", }, + { /* 6 */ .g = 6, .descr = "0-120m", }, + { /* 7 */ .g = 5, .descr = "0-120m", }, + { /* 8 */ .g = 4, .descr = "0-120m", }, + { /* 9 */ .g = 4, .descr = "0-120m", }, + { /* 10 */ .g = 3, .descr = "0-120m", }, + { /* 11 */ .g = 3, .descr = "0-120m", }, + { /* 12 */ .g = 2, .descr = "0-120m", }, + { /* 13 */ .g = 2, .descr = "0-120m", }, + { /* 14 */ .g = 2, .descr = "0-120m", }, + { /* 15 */ .g = 1, .descr = "0-120m", }, + { /* 16 */ .g = 1, .descr = "0-120m", }, + { /* 17 */ .g = 1, .descr = "0-120m", }, + { /* 18 */ .g = 0, .descr = "0-120m", }, }; -struct nl2gl_t nl2gl[] = { - { /* 0 */ .g = 9, .descr = "0-120m", }, - { /* 1 */ .g = 9, .descr = "0-120m", }, - { /* 2 */ .g = 8, .descr = "0-120m", }, - { /* 3 */ .g = 8, .descr = "0-120m", }, - { /* 4 */ .g = 7, .descr = "0-120m", }, - { /* 5 */ .g = 7, .descr = "0-120m", }, - { /* 6 */ .g = 6, .descr = "0-120m", }, - { /* 7 */ .g = 6, .descr = "0-120m", }, - { /* 8 */ .g = 5, .descr = "0-120m", }, - { /* 9 */ .g = 5, .descr = "0-120m", }, - { /* 10 */ .g = 4, .descr = "0-120m", }, - { /* 11 */ .g = 4, .descr = "0-120m", }, - { /* 12 */ .g = 3, .descr = "0-120m", }, - { /* 13 */ .g = 3, .descr = "0-120m", }, - { /* 14 */ .g = 2, .descr = "0-120m", }, - { /* 15 */ .g = 2, .descr = "0-120m", }, - { /* 16 */ .g = 1, .descr = "0-120m", }, - { /* 17 */ .g = 1, .descr = "0-120m", }, - { /* 18 */ .g = 0, .descr = "0-120m", }, +struct nl2gl_t nl2gl[] = { + { /* 0 */ .g = 9, .descr = "0-120m", }, + { /* 1 */ .g = 9, .descr = "0-120m", }, + { /* 2 */ .g = 8, .descr = "0-120m", }, + { /* 3 */ .g = 8, .descr = "0-120m", }, + { /* 4 */ .g = 7, .descr = "0-120m", }, + { /* 5 */ .g = 7, .descr = "0-120m", }, + { /* 6 */ .g = 6, .descr = "0-120m", }, + { /* 7 */ .g = 6, .descr = "0-120m", }, + { /* 8 */ .g = 5, .descr = "0-120m", }, + { /* 9 */ .g = 5, .descr = "0-120m", }, + { /* 10 */ .g = 4, .descr = "0-120m", }, + { /* 11 */ .g = 4, .descr = "0-120m", }, + { /* 12 */ .g = 3, .descr = "0-120m", }, + { /* 13 */ .g = 3, .descr = "0-120m", }, + { /* 14 */ .g = 2, .descr = "0-120m", }, + { /* 15 */ .g = 2, .descr = "0-120m", }, + { /* 16 */ .g = 1, .descr = "0-120m", }, + { /* 17 */ .g = 1, .descr = "0-120m", }, + { /* 18 */ .g = 0, .descr = "0-120m", }, }; -static int -get_level(struct map_selection *sel) -{ - return sel->order; +static int +get_level(struct map_selection *sel) { + return sel->order; } static int -garmin_get_selection(struct map_rect_priv *map, struct map_selection *sel) -{ - struct gar_rect r; - struct gmap *gm; - struct gobject **glast = NULL; - int rc; - int sl, el; - int level = 0; // 18; /* max level for maps, overview maps can have bigger - /* levels we do not deal w/ them - */ - int flags = 0; - if (sel && sel->range.min == type_street_0 && sel->range.max == type_ferry) { - // Get all roads - flags = GO_GET_ROUTABLE; - } else if (sel) - flags = GO_GET_SORTED; - - if (sel) { - r.lulat = sel->u.c_rect.lu.y; - r.lulong = sel->u.c_rect.lu.x; - r.rllat = sel->u.c_rect.rl.y; - r.rllong = sel->u.c_rect.rl.x; - level = get_level(sel); +garmin_get_selection(struct map_rect_priv *map, struct map_selection *sel) { + struct gar_rect r; + struct gmap *gm; + struct gobject **glast = NULL; + int rc; + int sl, el; + int level = 0; // 18; /* max level for maps, overview maps can have bigger + /* levels we do not deal w/ them + */ + int flags = 0; + if (sel && sel->range.min == type_street_0 && sel->range.max == type_ferry) { + // Get all roads + flags = GO_GET_ROUTABLE; + } else if (sel) + flags = GO_GET_SORTED; + + if (sel) { + r.lulat = sel->u.c_rect.lu.y; + r.lulong = sel->u.c_rect.lu.x; + r.rllat = sel->u.c_rect.rl.y; + r.rllong = sel->u.c_rect.rl.x; + level = get_level(sel); // level = nl2gl[level].g; - dlog(2, "Looking level=%d for %f %f %f %f\n", - level, r.lulat, r.lulong, r.rllat, r.rllong); - } - gm = gar_find_subfiles(map->mpriv->g, sel ? &r : NULL, flags); - if (!gm) { - if (sel) { - dlog(1, "Can not find map data for the area: %f %f %f %f\n", - r.lulat, r.lulong, r.rllat, r.rllong); - } else { - dlog(1, "Can not find map data\n"); - } - return -1; - } - sl = (18-gm->zoomlevels)/2; - el = sl + gm->zoomlevels; - if (level < sl) - level = sl; - if (level > el) - level = el; - level = level - sl; - level = gm->basebits + level; - dlog(3, "sl=%d el=%d level=%d\n", sl, el, level); - map->gmap = gm; - glast = &map->objs; - while (*glast) { - if ((*glast)->next) { - *glast = (*glast)->next; - } else - break; - } - rc = gar_get_objects(gm, level, sel ? &r : NULL, glast, flags); - if (rc < 0) { - dlog(1, "Error loading objects\n"); - return -1; - } - map->cobj = map->objs; - dlog(2, "Loaded %d objects\n", rc); - return rc; + dlog(2, "Looking level=%d for %f %f %f %f\n", + level, r.lulat, r.lulong, r.rllat, r.rllong); + } + gm = gar_find_subfiles(map->mpriv->g, sel ? &r : NULL, flags); + if (!gm) { + if (sel) { + dlog(1, "Can not find map data for the area: %f %f %f %f\n", + r.lulat, r.lulong, r.rllat, r.rllong); + } else { + dlog(1, "Can not find map data\n"); + } + return -1; + } + sl = (18-gm->zoomlevels)/2; + el = sl + gm->zoomlevels; + if (level < sl) + level = sl; + if (level > el) + level = el; + level = level - sl; + level = gm->basebits + level; + dlog(3, "sl=%d el=%d level=%d\n", sl, el, level); + map->gmap = gm; + glast = &map->objs; + while (*glast) { + if ((*glast)->next) { + *glast = (*glast)->next; + } else + break; + } + rc = gar_get_objects(gm, level, sel ? &r : NULL, glast, flags); + if (rc < 0) { + dlog(1, "Error loading objects\n"); + return -1; + } + map->cobj = map->objs; + dlog(2, "Loaded %d objects\n", rc); + return rc; } // Can not return NULL, navit segfaults static struct map_rect_priv * -gmap_rect_new(struct map_priv *map, struct map_selection *sel) -{ - struct map_selection *ms = sel; - struct map_rect_priv *mr; - - if (!map) - return NULL; - mr = calloc(1, sizeof(*mr)); - if (!mr) - return mr; - mr->mpriv = map; - if (!sel) { - return mr; - } else { - while (ms) { - dlog(2, "order %d\n", ms->order); - if (garmin_get_selection(mr, ms) < 0) { - // free(mr); - // return NULL; - } - ms = ms->next; - } - } - return mr; +gmap_rect_new(struct map_priv *map, struct map_selection *sel) { + struct map_selection *ms = sel; + struct map_rect_priv *mr; + + if (!map) + return NULL; + mr = calloc(1, sizeof(*mr)); + if (!mr) + return mr; + mr->mpriv = map; + if (!sel) { + return mr; + } else { + while (ms) { + dlog(2, "order %d\n", ms->order); + if (garmin_get_selection(mr, ms) < 0) { + // free(mr); + // return NULL; + } + ms = ms->next; + } + } + return mr; } static void -gmap_rect_destroy(struct map_rect_priv *mr) -{ - dlog(11,"destroy maprect\n"); - if (mr->gmap) - gar_free_gmap(mr->gmap); - if (mr->objs) - gar_free_objects(mr->objs); - if (mr->label) - free(mr->label); - free(mr); +gmap_rect_destroy(struct map_rect_priv *mr) { + dlog(11,"destroy maprect\n"); + if (mr->gmap) + gar_free_gmap(mr->gmap); + if (mr->objs) + gar_free_objects(mr->objs); + if (mr->label) + free(mr->label); + free(mr); } -static void -gmap_search_destroy(struct map_search_priv *ms) -{ - gmap_rect_destroy((struct map_rect_priv *)ms); +static void +gmap_search_destroy(struct map_search_priv *ms) { + gmap_rect_destroy((struct map_rect_priv *)ms); } static void -gmap_destroy(struct map_priv *m) -{ - dlog(5, "garmin_map_destroy\n"); - if (m->g) - gar_free(m->g); - if (m->filename) - free(m->filename); - free(m); +gmap_destroy(struct map_priv *m) { + dlog(5, "garmin_map_destroy\n"); + if (m->g) + gar_free(m->g); + if (m->filename) + free(m->filename); + free(m); } static struct map_methods map_methods = { - projection_garmin, - "utf-8", - gmap_destroy, - gmap_rect_new, - gmap_rect_destroy, - gmap_rect_get_item, - gmap_rect_get_item_byid, - gmap_search_new, - gmap_search_destroy, - NULL, + projection_garmin, + "utf-8", + gmap_destroy, + gmap_rect_new, + gmap_rect_destroy, + gmap_rect_get_item, + gmap_rect_get_item_byid, + gmap_search_new, + gmap_search_destroy, + NULL, }; static struct map_priv * -gmap_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) -{ - struct map_priv *m; - struct attr *data; - struct attr *debug; - struct attr *flags; - char buf[PATH_MAX]; - struct stat st; - int dl = 1; - struct gar_config cfg; - int debugmask = 0; - - data=attr_search(attrs, NULL, attr_data); - if (! data) - return NULL; - debug=attr_search(attrs, NULL, attr_debug); - if (debug) { - dl = atoi(debug->u.str); - if (!dl) - dl = 1; - } - flags=attr_search(attrs, NULL, attr_flags); - if (flags) { - debugmask = flags->u.num; - } - m=g_new(struct map_priv, 1); - m->id=++map_id; - m->filename = strdup(data->u.str); - if (!m->filename) { - g_free(m); - return NULL; - } - memset(&cfg, 0, sizeof(struct gar_config)); - cfg.opm = OPM_GPS; - cfg.debuglevel = dl; - cfg.debugmask = debugmask; - garmin_debug = dl; - m->g = gar_init_cfg(NULL, logfn, &cfg); - if (!m->g) { - g_free(m->filename); - g_free(m); - return NULL; - } - // we want the data now, later we can load only what's necessery - if (gar_img_load(m->g, m->filename, 1) < 0) { - gar_free(m->g); - g_free(m->filename); - g_free(m); - return NULL; - } - m->conv = NULL; - snprintf(buf, sizeof(buf), "%s.types", m->filename); - if (!stat(buf, &st)) { - dlog(1, "Loading custom types from %s\n", buf); - m->conv = g2n_conv_load(buf); - } - if (!m->conv) { - dlog(1, "Using builtin types\n"); - m->conv = g2n_default_conv(); - } - if (!m->conv) { - dlog(1, "Failed to load map types\n"); - } - *meth=map_methods; - return m; +gmap_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) { + struct map_priv *m; + struct attr *data; + struct attr *debug; + struct attr *flags; + char buf[PATH_MAX]; + struct stat st; + int dl = 1; + struct gar_config cfg; + int debugmask = 0; + + data=attr_search(attrs, NULL, attr_data); + if (! data) + return NULL; + debug=attr_search(attrs, NULL, attr_debug); + if (debug) { + dl = atoi(debug->u.str); + if (!dl) + dl = 1; + } + flags=attr_search(attrs, NULL, attr_flags); + if (flags) { + debugmask = flags->u.num; + } + m=g_new(struct map_priv, 1); + m->id=++map_id; + m->filename = strdup(data->u.str); + if (!m->filename) { + g_free(m); + return NULL; + } + memset(&cfg, 0, sizeof(struct gar_config)); + cfg.opm = OPM_GPS; + cfg.debuglevel = dl; + cfg.debugmask = debugmask; + garmin_debug = dl; + m->g = gar_init_cfg(NULL, logfn, &cfg); + if (!m->g) { + g_free(m->filename); + g_free(m); + return NULL; + } + // we want the data now, later we can load only what's necessery + if (gar_img_load(m->g, m->filename, 1) < 0) { + gar_free(m->g); + g_free(m->filename); + g_free(m); + return NULL; + } + m->conv = NULL; + snprintf(buf, sizeof(buf), "%s.types", m->filename); + if (!stat(buf, &st)) { + dlog(1, "Loading custom types from %s\n", buf); + m->conv = g2n_conv_load(buf); + } + if (!m->conv) { + dlog(1, "Using builtin types\n"); + m->conv = g2n_default_conv(); + } + if (!m->conv) { + dlog(1, "Failed to load map types\n"); + } + *meth=map_methods; + return m; } void -plugin_init(void) -{ - plugin_register_category_map("garmin", gmap_new); +plugin_init(void) { + plugin_register_category_map("garmin", gmap_new); } diff --git a/navit/map/garmin/gentypes.c b/navit/map/garmin/gentypes.c index 16682a55a..5f7b28687 100644 --- a/navit/map/garmin/gentypes.c +++ b/navit/map/garmin/gentypes.c @@ -12,9 +12,9 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - + Garmin and MapSource are registered trademarks or trademarks of Garmin Ltd. or one of its subsidiaries. @@ -59,90 +59,87 @@ static int add_def(struct gar2nav_conv *conv, int type, unsigned short minid, char *descr) */ -static void print_header(FILE *fp) -{ - fprintf(fp, "// This is autogenerated file -- DO NOT EDIT\n"); - fprintf(fp, "struct gar2nav_conv *g2n_default_conv(void)\n" - "{\n" - "\tstruct gar2nav_conv *conv;\n" - "\n" - "\tconv = calloc(1, sizeof(*conv));\n" - "\tif (!conv)\n" - "\t\treturn conv;\n"); +static void print_header(FILE *fp) { + fprintf(fp, "// This is autogenerated file -- DO NOT EDIT\n"); + fprintf(fp, "struct gar2nav_conv *g2n_default_conv(void)\n" + "{\n" + "\tstruct gar2nav_conv *conv;\n" + "\n" + "\tconv = calloc(1, sizeof(*conv));\n" + "\tif (!conv)\n" + "\t\treturn conv;\n"); } -static int load_types_file(char *file, char *out) -{ - char buf[4096]; - char descr[4096]; - char ntype[4096]; - FILE *fp; - unsigned int minid, maxid, group; - int rc; - int type = -1; - FILE *fpout = stdout; - - fp = fopen(file, "r"); - if (!fp) - return -1; - if (out) { - fpout = fopen(out, "w"); - if (!fpout) - return -1; - } - print_header(fpout); - while (fgets(buf, sizeof(buf), fp)) { - if (*buf == '#' || *buf == '\n') - continue; - if (!strncasecmp(buf, "POINT", 5)) { - type = 1; - continue; - } else if (!strncasecmp(buf, "POI", 3)) { - type = 1; - continue; - } else if (!strncasecmp(buf, "POLYLINE", 8)) { - type = 2; - continue; - } else if (!strncasecmp(buf, "POLYGONE", 8)) { - type = 3; - continue; - } - - rc = sscanf(buf, "%d, 0x%04X - 0x%04X = %[^\t , ] , %[^\n]", - &group, &minid, &maxid, ntype, descr); - if (rc != 5) { - maxid = 0; - rc = sscanf(buf, "%d, 0x%04X = %[^\t, ], %[^\n]", - &group,&minid, ntype, descr); - if (rc != 4) { - dlog(1, "Invalid line rc=%d:[%s]\n",rc, buf); - dlog(1, "minid=%04X ntype=[%s] des=[%s]\n", - minid, ntype, descr); - continue; - } - } - - fprintf(fpout, "\tadd_def(conv, %d, %#.04x, %#.04x, %d, \"%s\", \"%s\");\n", - type, minid, maxid, group, ntype, descr); - } - fprintf(fpout, "\treturn conv;\n"); - fprintf(fpout, "}\n"); - fclose(fp); - if (out) - fclose(fpout); - return 1; +static int load_types_file(char *file, char *out) { + char buf[4096]; + char descr[4096]; + char ntype[4096]; + FILE *fp; + unsigned int minid, maxid, group; + int rc; + int type = -1; + FILE *fpout = stdout; + + fp = fopen(file, "r"); + if (!fp) + return -1; + if (out) { + fpout = fopen(out, "w"); + if (!fpout) + return -1; + } + print_header(fpout); + while (fgets(buf, sizeof(buf), fp)) { + if (*buf == '#' || *buf == '\n') + continue; + if (!strncasecmp(buf, "POINT", 5)) { + type = 1; + continue; + } else if (!strncasecmp(buf, "POI", 3)) { + type = 1; + continue; + } else if (!strncasecmp(buf, "POLYLINE", 8)) { + type = 2; + continue; + } else if (!strncasecmp(buf, "POLYGONE", 8)) { + type = 3; + continue; + } + + rc = sscanf(buf, "%d, 0x%04X - 0x%04X = %[^\t , ] , %[^\n]", + &group, &minid, &maxid, ntype, descr); + if (rc != 5) { + maxid = 0; + rc = sscanf(buf, "%d, 0x%04X = %[^\t, ], %[^\n]", + &group,&minid, ntype, descr); + if (rc != 4) { + dlog(1, "Invalid line rc=%d:[%s]\n",rc, buf); + dlog(1, "minid=%04X ntype=[%s] des=[%s]\n", + minid, ntype, descr); + continue; + } + } + + fprintf(fpout, "\tadd_def(conv, %d, %#.04x, %#.04x, %d, \"%s\", \"%s\");\n", + type, minid, maxid, group, ntype, descr); + } + fprintf(fpout, "\treturn conv;\n"); + fprintf(fpout, "}\n"); + fclose(fp); + if (out) + fclose(fpout); + return 1; } -int main(int argc, char **argv) -{ - if (argc!=3) { - fprintf(stderr, "Usage: %s garmintypes.txt outfile.c\n", - argv[0]); - return -1; - } - if (load_types_file(argv[1], argv[2]) < 0) { - unlink(argv[2]); - return -1; - } - return 0; +int main(int argc, char **argv) { + if (argc!=3) { + fprintf(stderr, "Usage: %s garmintypes.txt outfile.c\n", + argv[0]); + return -1; + } + if (load_types_file(argv[1], argv[2]) < 0) { + unlink(argv[2]); + return -1; + } + return 0; } diff --git a/navit/map/garmin_img/garmin_img.c b/navit/map/garmin_img/garmin_img.c index f7dccf89c..9d6b89e14 100644 --- a/navit/map/garmin_img/garmin_img.c +++ b/navit/map/garmin_img/garmin_img.c @@ -37,8 +37,8 @@ #include "coord.h" struct file { - FILE *f; - int offset; + FILE *f; + int offset; }; @@ -47,1467 +47,1428 @@ int subdiv_next=0x10; static void * -file_read(struct file *f, int offset, int size) -{ - void *ptr; - int ret; - - ptr=calloc(size, 1); - if (! ptr) - return ptr; - fseek(f->f, f->offset+offset, SEEK_SET); - ret=fread(ptr, size, 1, f->f); - if (ret != 1) { - printf("fread %d vs %d offset %d+%d(0x%x)\n", ret, size, f->offset, offset,offset); - g_assert(1==0); - } - return ptr; +file_read(struct file *f, int offset, int size) { + void *ptr; + int ret; + + ptr=calloc(size, 1); + if (! ptr) + return ptr; + fseek(f->f, f->offset+offset, SEEK_SET); + ret=fread(ptr, size, 1, f->f); + if (ret != 1) { + printf("fread %d vs %d offset %d+%d(0x%x)\n", ret, size, f->offset, offset,offset); + g_assert(1==0); + } + return ptr; } static void -file_free(void *ptr) -{ - free(ptr); +file_free(void *ptr) { + free(ptr); } struct offset_len { - int offset; - int length; + int offset; + int length; } __attribute ((packed)); static void -dump_offset_len(struct offset_len *off_len) -{ - printf("offset: 0x%x(%d) length 0x%x(%d)\n", off_len->offset, off_len->offset, off_len->length, off_len->length); +dump_offset_len(struct offset_len *off_len) { + printf("offset: 0x%x(%d) length 0x%x(%d)\n", off_len->offset, off_len->offset, off_len->length, off_len->length); } struct timestamp { - short creation_year; - char creation_month; - char creation_day; - char creation_hour; - char creation_minute; - char creation_second; + short creation_year; + char creation_month; + char creation_day; + char creation_hour; + char creation_minute; + char creation_second; } __attribute__((packed)); struct img_header { - char xor; - char zero1[9]; - char update_month; - char update_year; - char zero2[3]; - char checksum[1]; - char signature[7]; - char unknown1[1]; - char unknown2[2]; - char unknown3[2]; - char unknown4[2]; - char unknown5[2]; - char zero3[25]; - struct timestamp ts; - char unknown6; - char map_file_identifier[7]; - char unknown12; - char map_description1[20]; - short unknown13; - short unknown14; - char e1; - char e2; - char other[413]; - char zero4[512]; - char unknown7; - char unknown8[11]; - int file_offset; - char unknown9; - char unknown10[15]; - char unknown11[480]; + char xor; + char zero1[9]; + char update_month; + char update_year; + char zero2[3]; + char checksum[1]; + char signature[7]; + char unknown1[1]; + char unknown2[2]; + char unknown3[2]; + char unknown4[2]; + char unknown5[2]; + char zero3[25]; + struct timestamp ts; + char unknown6; + char map_file_identifier[7]; + char unknown12; + char map_description1[20]; + short unknown13; + short unknown14; + char e1; + char e2; + char other[413]; + char zero4[512]; + char unknown7; + char unknown8[11]; + int file_offset; + char unknown9; + char unknown10[15]; + char unknown11[480]; } __attribute__((packed)); static void -dump_ts(struct timestamp *ts) -{ - printf("%d-%02d-%02d %02d:%02d:%02d\n", ts->creation_year, ts->creation_month, ts->creation_day, ts->creation_hour, ts->creation_minute, ts->creation_second); +dump_ts(struct timestamp *ts) { + printf("%d-%02d-%02d %02d:%02d:%02d\n", ts->creation_year, ts->creation_month, ts->creation_day, ts->creation_hour, + ts->creation_minute, ts->creation_second); } #if 0 static void -dump_img(struct img_header *img_hdr) -{ - printf("signature: '%s'\n", img_hdr->signature); - printf("creation: "); - dump_ts(&img_hdr->ts); - printf("map_file_identifier: '%s'\n", img_hdr->map_file_identifier); - printf("file_offset: 0x%x\n", img_hdr->file_offset); - printf("e1: 0x%x(%d)\n", img_hdr->e1, img_hdr->e1); - printf("e2: 0x%x(%d)\n", img_hdr->e2, img_hdr->e2); - printf("offset 0x%x\n", (int) &img_hdr->e1 - (int) img_hdr); - printf("size %d\n", sizeof(*img_hdr)); +dump_img(struct img_header *img_hdr) { + printf("signature: '%s'\n", img_hdr->signature); + printf("creation: "); + dump_ts(&img_hdr->ts); + printf("map_file_identifier: '%s'\n", img_hdr->map_file_identifier); + printf("file_offset: 0x%x\n", img_hdr->file_offset); + printf("e1: 0x%x(%d)\n", img_hdr->e1, img_hdr->e1); + printf("e2: 0x%x(%d)\n", img_hdr->e2, img_hdr->e2); + printf("offset 0x%x\n", (int) &img_hdr->e1 - (int) img_hdr); + printf("size %d\n", sizeof(*img_hdr)); } #endif struct fat_block { - char flag; - char filename[8]; - char type[3]; - int size; - char zero1; - char part; - char zero[14]; - unsigned short blocks[240]; + char flag; + char filename[8]; + char type[3]; + int size; + char zero1; + char part; + char zero[14]; + unsigned short blocks[240]; } __attribute__((packed)); #if 0 static void -dump_fat_block(struct fat_block *fat_blk) -{ - int i=0; - char name[9]; - char type[4]; - printf("flag: 0x%x(%d)\n", fat_blk->flag, fat_blk->flag); - strcpy(name, fat_blk->filename); - name[8]='\0'; - strcpy(type, fat_blk->type); - type[3]='\0'; - printf("name: '%s.%s'\n", name, type); - printf("size: 0x%x(%d)\n", fat_blk->size, fat_blk->size); - printf("part: 0x%x(%d)\n", fat_blk->part, fat_blk->part); - printf("blocks: "); - while (i < 240) { - printf("0x%x(%d) ",fat_blk->blocks[i], fat_blk->blocks[i]); - if (fat_blk->blocks[i] == 0xffff) - break; - i++; - } - printf("size: %d\n", sizeof(*fat_blk)); - +dump_fat_block(struct fat_block *fat_blk) { + int i=0; + char name[9]; + char type[4]; + printf("flag: 0x%x(%d)\n", fat_blk->flag, fat_blk->flag); + strcpy(name, fat_blk->filename); + name[8]='\0'; + strcpy(type, fat_blk->type); + type[3]='\0'; + printf("name: '%s.%s'\n", name, type); + printf("size: 0x%x(%d)\n", fat_blk->size, fat_blk->size); + printf("part: 0x%x(%d)\n", fat_blk->part, fat_blk->part); + printf("blocks: "); + while (i < 240) { + printf("0x%x(%d) ",fat_blk->blocks[i], fat_blk->blocks[i]); + if (fat_blk->blocks[i] == 0xffff) + break; + i++; + } + printf("size: %d\n", sizeof(*fat_blk)); + } #endif struct file_header { - short header_len; - char type[10]; - char unknown1; - char unknown2; - struct timestamp ts; + short header_len; + char type[10]; + char unknown1; + char unknown2; + struct timestamp ts; } __attribute__((packed)); static void -dump_file(struct file_header *fil_hdr) -{ - printf("header_len: %d\n", fil_hdr->header_len); - printf("type: '%s'\n", fil_hdr->type); - printf("unknown1: 0x%x(%d)\n", fil_hdr->unknown1, fil_hdr->unknown1); - printf("unknown2: 0x%x(%d)\n", fil_hdr->unknown2, fil_hdr->unknown2); - printf("creation: "); - dump_ts(&fil_hdr->ts); - printf("size %d\n", sizeof(*fil_hdr)); +dump_file(struct file_header *fil_hdr) { + printf("header_len: %d\n", fil_hdr->header_len); + printf("type: '%s'\n", fil_hdr->type); + printf("unknown1: 0x%x(%d)\n", fil_hdr->unknown1, fil_hdr->unknown1); + printf("unknown2: 0x%x(%d)\n", fil_hdr->unknown2, fil_hdr->unknown2); + printf("creation: "); + dump_ts(&fil_hdr->ts); + printf("size %d\n", sizeof(*fil_hdr)); } struct region_header { - struct file_header fil_hdr; - struct offset_len offset_len; + struct file_header fil_hdr; + struct offset_len offset_len; } __attribute__((packed)); #if 0 static void -dump_region(struct region_header *rgn_hdr) -{ - dump_offset_len(&rgn_hdr->offset_len); +dump_region(struct region_header *rgn_hdr) { + dump_offset_len(&rgn_hdr->offset_len); } #endif struct map_priv { - int id; - char *filename; + int id; + char *filename; }; struct map_rect_priv { - struct coord_rect r; - int limit; - - struct file tre; - struct tree_header *tre_hdr; - struct file rgn; - struct region_header *rgn_hdr; - struct file lbl; - struct label_header *lbl_hdr; - char *label; - - int subdiv_level_count; - int subdiv_pos; - char *subdiv; - - int rgn_offset; - int rgn_end; - struct rgn_point *pnt; - struct rgn_poly *ply; - unsigned char *ply_data; - int ply_bitpos; - int ply_bitcount; - int ply_lngbits; - int ply_latbits; - int ply_lng; - int ply_lat; - int ply_lnglimit; - int ply_latlimit; - int ply_lngsign; - int ply_latsign; - struct offset_len rgn_items[4]; - int rgn_type; - - int count; - - FILE *f; - long pos; - char line[256]; - int attr_pos; - enum attr_type attr_last; - char attrs[256]; - char attr[256]; - double lat,lng; - char lat_c,lng_c; - int eoc; - struct map_priv *m; - struct item item; + struct coord_rect r; + int limit; + + struct file tre; + struct tree_header *tre_hdr; + struct file rgn; + struct region_header *rgn_hdr; + struct file lbl; + struct label_header *lbl_hdr; + char *label; + + int subdiv_level_count; + int subdiv_pos; + char *subdiv; + + int rgn_offset; + int rgn_end; + struct rgn_point *pnt; + struct rgn_poly *ply; + unsigned char *ply_data; + int ply_bitpos; + int ply_bitcount; + int ply_lngbits; + int ply_latbits; + int ply_lng; + int ply_lat; + int ply_lnglimit; + int ply_latlimit; + int ply_lngsign; + int ply_latsign; + struct offset_len rgn_items[4]; + int rgn_type; + + int count; + + FILE *f; + long pos; + char line[256]; + int attr_pos; + enum attr_type attr_last; + char attrs[256]; + char attr[256]; + double lat,lng; + char lat_c,lng_c; + int eoc; + struct map_priv *m; + struct item item; }; static int map_id; static int -contains_coord(char *line) -{ - return g_ascii_isdigit(line[0]); +contains_coord(char *line) { + return g_ascii_isdigit(line[0]); } static int debug=1; static int -get_tag(char *line, char *name, int *pos, char *ret) -{ - int len,quoted; - char *p,*e,*n; - - if (debug) - printf("get_tag %s from %s\n", name, line); - if (! name) - return 0; - len=strlen(name); - if (pos) - p=line+*pos; - else - p=line; - for(;;) { - while (*p == ' ') { - p++; - } - if (! *p) - return 0; - n=p; - e=index(p,'='); - if (! e) - return 0; - p=e+1; - quoted=0; - while (*p) { - if (*p == ' ' && !quoted) - break; - if (*p == '"') - quoted=1-quoted; - p++; - } - if (e-n == len && !strncmp(n, name, len)) { - e++; - len=p-e; - if (e[0] == '"') { - e++; - len-=2; - } - strncpy(ret, e, len); - ret[len]='\0'; - if (pos) - *pos=p-line; - return 1; - } - } - return 0; +get_tag(char *line, char *name, int *pos, char *ret) { + int len,quoted; + char *p,*e,*n; + + if (debug) + printf("get_tag %s from %s\n", name, line); + if (! name) + return 0; + len=strlen(name); + if (pos) + p=line+*pos; + else + p=line; + for(;;) { + while (*p == ' ') { + p++; + } + if (! *p) + return 0; + n=p; + e=index(p,'='); + if (! e) + return 0; + p=e+1; + quoted=0; + while (*p) { + if (*p == ' ' && !quoted) + break; + if (*p == '"') + quoted=1-quoted; + p++; + } + if (e-n == len && !strncmp(n, name, len)) { + e++; + len=p-e; + if (e[0] == '"') { + e++; + len-=2; + } + strncpy(ret, e, len); + ret[len]='\0'; + if (pos) + *pos=p-line; + return 1; + } + } + return 0; } static void -get_line(struct map_rect_priv *mr) -{ - mr->pos=ftell(mr->f); - fgets(mr->line, 256, mr->f); +get_line(struct map_rect_priv *mr) { + mr->pos=ftell(mr->f); + fgets(mr->line, 256, mr->f); } static void -map_destroy_garmin_img(struct map_priv *m) -{ - if (debug) - printf("map_destroy_garmin_img\n"); - g_free(m); +map_destroy_garmin_img(struct map_priv *m) { + if (debug) + printf("map_destroy_garmin_img\n"); + g_free(m); } static char * -map_charset_garmin_img(struct map_priv *m) -{ - return "iso8859-1"; +map_charset_garmin_img(struct map_priv *m) { + return "iso8859-1"; } static enum projection -map_projection_garmin_img(struct map_priv *m) -{ - return projection_garmin; +map_projection_garmin_img(struct map_priv *m) { + return projection_garmin; } struct label_data_offset { - struct offset_len offset_len; - char multiplier; - char data; + struct offset_len offset_len; + char multiplier; + char data; } __attribute ((packed)); #if 0 static void -dump_label_data_offset(struct label_data_offset *lbl_dat) -{ - dump_offset_len(&lbl_dat->offset_len); - printf("multiplier 0x%x(%d)\n", lbl_dat->multiplier, lbl_dat->multiplier); - printf("data 0x%x(%d)\n", lbl_dat->data, lbl_dat->data); +dump_label_data_offset(struct label_data_offset *lbl_dat) { + dump_offset_len(&lbl_dat->offset_len); + printf("multiplier 0x%x(%d)\n", lbl_dat->multiplier, lbl_dat->multiplier); + printf("data 0x%x(%d)\n", lbl_dat->data, lbl_dat->data); } #endif struct label_data { - struct offset_len offset_len; - short size; - int zero; + struct offset_len offset_len; + short size; + int zero; } __attribute ((packed)); static void -dump_label_data(struct label_data *lbl_dat) -{ - dump_offset_len(&lbl_dat->offset_len); - printf("size 0x%x(%d)\n", lbl_dat->size, lbl_dat->size); +dump_label_data(struct label_data *lbl_dat) { + dump_offset_len(&lbl_dat->offset_len); + printf("size 0x%x(%d)\n", lbl_dat->size, lbl_dat->size); } struct tree_header { - struct file_header fil_hdr; - char boundary[12]; - struct offset_len level; - struct offset_len subdivision; - struct label_data copyright; - struct offset_len tre7; - short unknown1; - char zero1; - struct label_data polyline; - struct label_data polygon; - struct label_data point; - int mapid; + struct file_header fil_hdr; + char boundary[12]; + struct offset_len level; + struct offset_len subdivision; + struct label_data copyright; + struct offset_len tre7; + short unknown1; + char zero1; + struct label_data polyline; + struct label_data polygon; + struct label_data point; + int mapid; }; static void -dump_tree_header(struct tree_header *tre_hdr) -{ - printf("tree_header:\n"); - dump_file(&tre_hdr->fil_hdr); - printf("level: "); dump_offset_len(&tre_hdr->level); - printf("subdivision: "); dump_offset_len(&tre_hdr->subdivision); - printf("copyright: "); dump_label_data(&tre_hdr->copyright); - printf("polyline: "); dump_label_data(&tre_hdr->polyline); - printf("polygon: "); dump_label_data(&tre_hdr->polygon); - printf("point: "); dump_label_data(&tre_hdr->point); - printf("len: 0x%x(%d)\n", sizeof(*tre_hdr), sizeof(*tre_hdr)); +dump_tree_header(struct tree_header *tre_hdr) { + printf("tree_header:\n"); + dump_file(&tre_hdr->fil_hdr); + printf("level: "); + dump_offset_len(&tre_hdr->level); + printf("subdivision: "); + dump_offset_len(&tre_hdr->subdivision); + printf("copyright: "); + dump_label_data(&tre_hdr->copyright); + printf("polyline: "); + dump_label_data(&tre_hdr->polyline); + printf("polygon: "); + dump_label_data(&tre_hdr->polygon); + printf("point: "); + dump_label_data(&tre_hdr->point); + printf("len: 0x%x(%d)\n", sizeof(*tre_hdr), sizeof(*tre_hdr)); } struct label_header { - struct file_header fil_hdr; - struct label_data_offset label; - struct label_data country; - struct label_data region; - struct label_data city; - struct label_data poi_index; - struct label_data_offset poi_properties; - short zero1; - char zero2; - struct label_data poi_types; - struct label_data zip; - struct label_data hway; - struct label_data exit; - struct label_data hway_data; - int unknown1; - short unknown2; - struct offset_len sort_descriptor; - struct label_data lbl13; - struct label_data lbl14; + struct file_header fil_hdr; + struct label_data_offset label; + struct label_data country; + struct label_data region; + struct label_data city; + struct label_data poi_index; + struct label_data_offset poi_properties; + short zero1; + char zero2; + struct label_data poi_types; + struct label_data zip; + struct label_data hway; + struct label_data exit; + struct label_data hway_data; + int unknown1; + short unknown2; + struct offset_len sort_descriptor; + struct label_data lbl13; + struct label_data lbl14; } __attribute((packed)); #if 0 static void -dump_label(struct label_header *lbl_hdr) -{ - dump_file(&lbl_hdr->fil_hdr); - printf("label:\n"); - dump_label_data_offset(&lbl_hdr->label); - printf("country:\n"); - dump_label_data(&lbl_hdr->country); - printf("region:\n"); - dump_label_data(&lbl_hdr->region); - printf("city:\n"); - dump_label_data(&lbl_hdr->city); - printf("poi_index:\n"); - dump_label_data(&lbl_hdr->poi_index); - printf("poi_properties:\n"); - dump_label_data_offset(&lbl_hdr->poi_properties); - printf("poi_types:\n"); - dump_label_data(&lbl_hdr->poi_types); - printf("zip:\n"); - dump_label_data(&lbl_hdr->zip); - printf("hway:\n"); - dump_label_data(&lbl_hdr->hway); - printf("exit:\n"); - dump_label_data(&lbl_hdr->exit); - printf("hway_data:\n"); - dump_label_data(&lbl_hdr->hway_data); - printf("lbl13:\n"); - dump_label_data(&lbl_hdr->lbl13); - printf("lbl14:\n"); - dump_label_data(&lbl_hdr->lbl14); - printf("len: 0x%x(%d)\n", sizeof(*lbl_hdr), sizeof(*lbl_hdr)); +dump_label(struct label_header *lbl_hdr) { + dump_file(&lbl_hdr->fil_hdr); + printf("label:\n"); + dump_label_data_offset(&lbl_hdr->label); + printf("country:\n"); + dump_label_data(&lbl_hdr->country); + printf("region:\n"); + dump_label_data(&lbl_hdr->region); + printf("city:\n"); + dump_label_data(&lbl_hdr->city); + printf("poi_index:\n"); + dump_label_data(&lbl_hdr->poi_index); + printf("poi_properties:\n"); + dump_label_data_offset(&lbl_hdr->poi_properties); + printf("poi_types:\n"); + dump_label_data(&lbl_hdr->poi_types); + printf("zip:\n"); + dump_label_data(&lbl_hdr->zip); + printf("hway:\n"); + dump_label_data(&lbl_hdr->hway); + printf("exit:\n"); + dump_label_data(&lbl_hdr->exit); + printf("hway_data:\n"); + dump_label_data(&lbl_hdr->hway_data); + printf("lbl13:\n"); + dump_label_data(&lbl_hdr->lbl13); + printf("lbl14:\n"); + dump_label_data(&lbl_hdr->lbl14); + printf("len: 0x%x(%d)\n", sizeof(*lbl_hdr), sizeof(*lbl_hdr)); } #endif struct triple { - unsigned char data[3]; + unsigned char data[3]; } __attribute((packed)); static unsigned int -triple_u(struct triple *t) -{ - return t->data[0] | (t->data[1] << 8) | (t->data[2] << 16); +triple_u(struct triple *t) { + return t->data[0] | (t->data[1] << 8) | (t->data[2] << 16); } static int -triple(struct triple *t) -{ - int ret=t->data[0] | (t->data[1] << 8) | (t->data[2] << 16); - if (ret > 1<<23) - ret=ret-(1<<24); - return ret; +triple(struct triple *t) { + int ret=t->data[0] | (t->data[1] << 8) | (t->data[2] << 16); + if (ret > 1<<23) + ret=ret-(1<<24); + return ret; } static void -dump_triple_u(struct triple *t) -{ - int val=triple_u(t); - printf("0x%x(%d)\n", val, val); +dump_triple_u(struct triple *t) { + int val=triple_u(t); + printf("0x%x(%d)\n", val, val); } struct tcoord { - struct triple lng,lat; + struct triple lng,lat; } __attribute((packed)); static void -dump_tcoord(struct tcoord *t) -{ - printf ("0x%x(%d),0x%x(%d)\n", triple_u(&t->lng), triple_u(&t->lng), triple_u(&t->lat), triple_u(&t->lat)); +dump_tcoord(struct tcoord *t) { + printf ("0x%x(%d),0x%x(%d)\n", triple_u(&t->lng), triple_u(&t->lng), triple_u(&t->lat), triple_u(&t->lat)); } struct level { - unsigned char zoom; - unsigned char bits_per_coord; - unsigned short subdivisions; + unsigned char zoom; + unsigned char bits_per_coord; + unsigned short subdivisions; } __attribute((packed)); static void -dump_level(struct level *lvl) -{ - printf("level:\n"); - printf("\tzoom 0x%x(%d)\n", lvl->zoom, lvl->zoom); - printf("\tbits_per_coord 0x%x(%d)\n", lvl->bits_per_coord, lvl->bits_per_coord); - printf("\tsubdivisions 0x%x(%d)\n", lvl->subdivisions, lvl->subdivisions); +dump_level(struct level *lvl) { + printf("level:\n"); + printf("\tzoom 0x%x(%d)\n", lvl->zoom, lvl->zoom); + printf("\tbits_per_coord 0x%x(%d)\n", lvl->bits_per_coord, lvl->bits_per_coord); + printf("\tsubdivisions 0x%x(%d)\n", lvl->subdivisions, lvl->subdivisions); } struct subdivision { - struct triple rgn_offset; - unsigned char types; - struct tcoord center; - unsigned short width; - unsigned short height; - unsigned short next; + struct triple rgn_offset; + unsigned char types; + struct tcoord center; + unsigned short width; + unsigned short height; + unsigned short next; } __attribute((packed)); static void -dump_subdivision(struct subdivision *sub) -{ - printf("subdivision:\n"); - printf("\trgn_offset: "); dump_triple_u(&sub->rgn_offset); - printf("\ttypes: 0x%x(%d)\n", sub->types, sub->types); - printf("\tcenter: "); dump_tcoord(&sub->center); - printf("\tsize: 0x%x(%d)x0x%x(%d) %s\n",sub->width & 0x7fff, sub->width & 0x7fff, sub->height, sub->height, sub->width & 0x8000 ? "Terminating" : ""); - printf("\tnext: 0x%x(%d)\n",sub->next, sub->next); - - printf("\tlen: 0x%x(%d)\n", sizeof(*sub), sizeof(*sub)); +dump_subdivision(struct subdivision *sub) { + printf("subdivision:\n"); + printf("\trgn_offset: "); + dump_triple_u(&sub->rgn_offset); + printf("\ttypes: 0x%x(%d)\n", sub->types, sub->types); + printf("\tcenter: "); + dump_tcoord(&sub->center); + printf("\tsize: 0x%x(%d)x0x%x(%d) %s\n",sub->width & 0x7fff, sub->width & 0x7fff, sub->height, sub->height, + sub->width & 0x8000 ? "Terminating" : ""); + printf("\tnext: 0x%x(%d)\n",sub->next, sub->next); + + printf("\tlen: 0x%x(%d)\n", sizeof(*sub), sizeof(*sub)); } struct rgn_point { - unsigned char info; - struct triple lbl_offset; - short lng_delta; - short lat_delta; - unsigned char subtype; + unsigned char info; + struct triple lbl_offset; + short lng_delta; + short lat_delta; + unsigned char subtype; } __attribute((packed)); static void -dump_point(struct rgn_point *pnt) -{ - printf("point:\n"); - printf("\tinfo 0x%x(%d)\n", pnt->info, pnt->info); - printf("\tlbl_offset 0x%x(%d)\n", triple_u(&pnt->lbl_offset), triple_u(&pnt->lbl_offset)); - printf("\tlng_delta 0x%x(%d)\n", pnt->lng_delta, pnt->lng_delta); - printf("\tlat_delta 0x%x(%d)\n", pnt->lat_delta, pnt->lat_delta); - printf("\tsubtype 0x%x(%d)\n", pnt->subtype, pnt->subtype); - printf("\tlen: 0x%x(%d)\n", sizeof(*pnt), sizeof(*pnt)); +dump_point(struct rgn_point *pnt) { + printf("point:\n"); + printf("\tinfo 0x%x(%d)\n", pnt->info, pnt->info); + printf("\tlbl_offset 0x%x(%d)\n", triple_u(&pnt->lbl_offset), triple_u(&pnt->lbl_offset)); + printf("\tlng_delta 0x%x(%d)\n", pnt->lng_delta, pnt->lng_delta); + printf("\tlat_delta 0x%x(%d)\n", pnt->lat_delta, pnt->lat_delta); + printf("\tsubtype 0x%x(%d)\n", pnt->subtype, pnt->subtype); + printf("\tlen: 0x%x(%d)\n", sizeof(*pnt), sizeof(*pnt)); } struct rgn_poly { - unsigned char info; - struct triple lbl_offset; - short lng_delta; - short lat_delta; - union { - struct { - unsigned char bitstream_len; - unsigned char bitstream_info; - } __attribute((packed)) p1; - struct { - unsigned short bitstream_len; - unsigned char bitstream_info; - } __attribute((packed)) p2; - } __attribute((packed)) u; + unsigned char info; + struct triple lbl_offset; + short lng_delta; + short lat_delta; + union { + struct { + unsigned char bitstream_len; + unsigned char bitstream_info; + } __attribute((packed)) p1; + struct { + unsigned short bitstream_len; + unsigned char bitstream_info; + } __attribute((packed)) p2; + } __attribute((packed)) u; } __attribute((packed)); static void -dump_poly(struct rgn_poly *ply) -{ - printf("poly:\n"); - printf("\tinfo 0x%x(%d)\n", ply->info, ply->info); - printf("\tlbl_offset 0x%x(%d)\n", triple_u(&ply->lbl_offset), triple_u(&ply->lbl_offset)); - printf("\tlng_delta 0x%x(%d)\n", ply->lng_delta, ply->lng_delta); - printf("\tlat_delta 0x%x(%d)\n", ply->lat_delta, ply->lat_delta); - if (ply->info & 0x80) { - printf("\tbitstream_len 0x%x(%d)\n", ply->u.p2.bitstream_len, ply->u.p2.bitstream_len); - printf("\tbitstream_info 0x%x(%d)\n", ply->u.p2.bitstream_info, ply->u.p2.bitstream_info); - } else { - printf("\tbitstream_len 0x%x(%d)\n", ply->u.p1.bitstream_len, ply->u.p1.bitstream_len); - printf("\tbitstream_info 0x%x(%d)\n", ply->u.p1.bitstream_info, ply->u.p1.bitstream_info); - } - printf("\tlen: 0x%x(%d)\n", sizeof(*ply), sizeof(*ply)); +dump_poly(struct rgn_poly *ply) { + printf("poly:\n"); + printf("\tinfo 0x%x(%d)\n", ply->info, ply->info); + printf("\tlbl_offset 0x%x(%d)\n", triple_u(&ply->lbl_offset), triple_u(&ply->lbl_offset)); + printf("\tlng_delta 0x%x(%d)\n", ply->lng_delta, ply->lng_delta); + printf("\tlat_delta 0x%x(%d)\n", ply->lat_delta, ply->lat_delta); + if (ply->info & 0x80) { + printf("\tbitstream_len 0x%x(%d)\n", ply->u.p2.bitstream_len, ply->u.p2.bitstream_len); + printf("\tbitstream_info 0x%x(%d)\n", ply->u.p2.bitstream_info, ply->u.p2.bitstream_info); + } else { + printf("\tbitstream_len 0x%x(%d)\n", ply->u.p1.bitstream_len, ply->u.p1.bitstream_len); + printf("\tbitstream_info 0x%x(%d)\n", ply->u.p1.bitstream_info, ply->u.p1.bitstream_info); + } + printf("\tlen: 0x%x(%d)\n", sizeof(*ply), sizeof(*ply)); } static void -dump_hex(void *ptr, int len) -{ - unsigned char *c=ptr; - while (len--) { - printf("%02x ", *c++); - } - printf("\n"); +dump_hex(void *ptr, int len) { + unsigned char *c=ptr; + while (len--) { + printf("%02x ", *c++); + } + printf("\n"); } static void -dump_hex_r(void *ptr, int len, int rec) -{ - unsigned char *c=ptr; - int l=rec; - while (len--) { - printf("%02x ", *c++); - if (! --l) { - printf("\n"); - l=rec; - } - } - printf("\n"); +dump_hex_r(void *ptr, int len, int rec) { + unsigned char *c=ptr; + int l=rec; + while (len--) { + printf("%02x ", *c++); + if (! --l) { + printf("\n"); + l=rec; + } + } + printf("\n"); } #if 0 static void -dump_label_offset(struct map_rect_priv *mr, int offset) -{ - void *p; - p=file_read(&mr->lbl, mr->lbl_hdr->label.offset_len.offset+offset, 128); - printf("%s\n", (char *)p); +dump_label_offset(struct map_rect_priv *mr, int offset) { + void *p; + p=file_read(&mr->lbl, mr->lbl_hdr->label.offset_len.offset+offset, 128); + printf("%s\n", (char *)p); } #endif #if 0 static void -dump_region_item(struct subdivision *sub, struct file *rgn, struct map_rect_priv *mr) -{ - int offset,item_offset,i,j; - unsigned short count=0; - unsigned short *offsets[4]; - unsigned short *file_offsets; - struct rgn_point *pnt; - - offset=triple_u(&sub->rgn_offset)+mr->rgn_hdr->offset_len.offset; - file_offsets=file_read(rgn, offset, 90*sizeof(unsigned short)); - printf("0x%x ", offset); dump_hex(file_offsets, 90); - for (i=0 ; i < 4 ; i++) { - printf("i=%d\n", i); - if (sub->types & (0x10 << i)) { - if (count) { - offsets[i]=&file_offsets[count-1]; - } else - offsets[i]=&count; - count++; - } else - offsets[i]=NULL; - - } - count--; - count*=2; - for (i=0 ; i < 4 ; i++) { - printf("i=%d\n", i); - if (offsets[i]) { - printf("offset[%d]=0x%x(%d)\n", i, *offsets[i], *offsets[i]); - switch (i) { - case 0: - printf("point\n"); - break; - case 1: - printf("indexed point\n"); - break; - case 2: - printf("polyline\n"); - break; - case 3: - printf("polygon\n"); - break; - } - item_offset=offset+*offsets[i]; - switch (i) { - case 0: - case 1: - for (j = 0 ; j < 10 ; j++) { - struct coord_geo g; - char buffer[1024]; - double conv=180.0/(1UL<<23); - pnt=file_read(rgn, item_offset, sizeof(*pnt)*20); - // printf("0x%x ", item_offset); dump_hex(pnt, 32); - dump_point(pnt); - g.lng=(triple(&sub->center.lng)+(pnt->lng_delta << shift))*conv; - g.lat=(triple(&sub->center.lat)+(pnt->lat_delta << shift))*conv; - printf("%f %f\n", g.lng, g.lat); - coord_format(g.lat,g.lng,DEGREES_MINUTES_SECONDS, - buffer,sizeof(buffer)); - printf("%s\n", buffer); - dump_label_offset(mr, triple_u(&pnt->lbl_offset)); - if (pnt->info & 0x80) - item_offset+=sizeof(*pnt); - else - item_offset+=sizeof(*pnt)-1; - } - } - } else { - printf("offset[%d] doesn't exist\n", i); - } - } - file_free(file_offsets); +dump_region_item(struct subdivision *sub, struct file *rgn, struct map_rect_priv *mr) { + int offset,item_offset,i,j; + unsigned short count=0; + unsigned short *offsets[4]; + unsigned short *file_offsets; + struct rgn_point *pnt; + + offset=triple_u(&sub->rgn_offset)+mr->rgn_hdr->offset_len.offset; + file_offsets=file_read(rgn, offset, 90*sizeof(unsigned short)); + printf("0x%x ", offset); + dump_hex(file_offsets, 90); + for (i=0 ; i < 4 ; i++) { + printf("i=%d\n", i); + if (sub->types & (0x10 << i)) { + if (count) { + offsets[i]=&file_offsets[count-1]; + } else + offsets[i]=&count; + count++; + } else + offsets[i]=NULL; + + } + count--; + count*=2; + for (i=0 ; i < 4 ; i++) { + printf("i=%d\n", i); + if (offsets[i]) { + printf("offset[%d]=0x%x(%d)\n", i, *offsets[i], *offsets[i]); + switch (i) { + case 0: + printf("point\n"); + break; + case 1: + printf("indexed point\n"); + break; + case 2: + printf("polyline\n"); + break; + case 3: + printf("polygon\n"); + break; + } + item_offset=offset+*offsets[i]; + switch (i) { + case 0: + case 1: + for (j = 0 ; j < 10 ; j++) { + struct coord_geo g; + char buffer[1024]; + double conv=180.0/(1UL<<23); + pnt=file_read(rgn, item_offset, sizeof(*pnt)*20); + // printf("0x%x ", item_offset); dump_hex(pnt, 32); + dump_point(pnt); + g.lng=(triple(&sub->center.lng)+(pnt->lng_delta << shift))*conv; + g.lat=(triple(&sub->center.lat)+(pnt->lat_delta << shift))*conv; + printf("%f %f\n", g.lng, g.lat); + coord_format(g.lat,g.lng,DEGREES_MINUTES_SECONDS, + buffer,sizeof(buffer)); + printf("%s\n", buffer); + dump_label_offset(mr, triple_u(&pnt->lbl_offset)); + if (pnt->info & 0x80) + item_offset+=sizeof(*pnt); + else + item_offset+=sizeof(*pnt)-1; + } + } + } else { + printf("offset[%d] doesn't exist\n", i); + } + } + file_free(file_offsets); } #endif static void -dump_levels(struct map_rect_priv *mr) -{ - int i,offset; - struct level *lvl; - - offset=mr->tre_hdr->level.offset; - for (i = 0 ; i < mr->tre_hdr->level.length/sizeof(*lvl) ; i++) { - lvl=file_read(&mr->tre, offset, sizeof(*lvl)); - dump_level(lvl); - offset+=sizeof(*lvl); - } +dump_levels(struct map_rect_priv *mr) { + int i,offset; + struct level *lvl; + + offset=mr->tre_hdr->level.offset; + for (i = 0 ; i < mr->tre_hdr->level.length/sizeof(*lvl) ; i++) { + lvl=file_read(&mr->tre, offset, sizeof(*lvl)); + dump_level(lvl); + offset+=sizeof(*lvl); + } } #if 0 static void -dump_tree(struct file *f, struct file *rgn, struct map_rect_priv *mr) -{ - struct tree_header *tre_hdr; - struct subdivision *sub; - int i,offset; - - tre_hdr=file_read(f, 0, sizeof(*tre_hdr)); - dump_tree_header(tre_hdr); - offset=tre_hdr->subdivision.offset; - sub=file_read(f, offset, sizeof(*sub)); - dump_subdivision(sub); - offset+=sizeof(*sub); - for (i = 1 ; i < tre_hdr->subdivision.length/sizeof(*sub) ; i++) { - printf("i=%d\n", i); - sub=file_read(f, offset, sizeof(*sub)); - dump_subdivision(sub); - dump_region_item(sub, rgn, mr); - if (sub->width & 0x8000) - break; - offset+=sizeof(*sub); - } - file_free(tre_hdr); +dump_tree(struct file *f, struct file *rgn, struct map_rect_priv *mr) { + struct tree_header *tre_hdr; + struct subdivision *sub; + int i,offset; + + tre_hdr=file_read(f, 0, sizeof(*tre_hdr)); + dump_tree_header(tre_hdr); + offset=tre_hdr->subdivision.offset; + sub=file_read(f, offset, sizeof(*sub)); + dump_subdivision(sub); + offset+=sizeof(*sub); + for (i = 1 ; i < tre_hdr->subdivision.length/sizeof(*sub) ; i++) { + printf("i=%d\n", i); + sub=file_read(f, offset, sizeof(*sub)); + dump_subdivision(sub); + dump_region_item(sub, rgn, mr); + if (sub->width & 0x8000) + break; + offset+=sizeof(*sub); + } + file_free(tre_hdr); } #endif #if 0 static void -dump_labels(struct file *f) -{ - struct label_header *lbl_hdr; - - lbl_hdr=file_read(f, 0, sizeof(*lbl_hdr)); - printf("**labels**\n"); - dump_label(lbl_hdr); - file_free(lbl_hdr); +dump_labels(struct file *f) { + struct label_header *lbl_hdr; + + lbl_hdr=file_read(f, 0, sizeof(*lbl_hdr)); + printf("**labels**\n"); + dump_label(lbl_hdr); + file_free(lbl_hdr); #if 0 - labels=alloca(lbl_hdr.label_length); - file_read(f, lbl_hdr.label_offset, labels, lbl_hdr.label_length); - l=labels; - while (l < labels+lbl_hdr.label_length) { - printf("'%s'(%d)\n", l, strlen(l)); - l+=strlen(l)+1; - } + labels=alloca(lbl_hdr.label_length); + file_read(f, lbl_hdr.label_offset, labels, lbl_hdr.label_length); + l=labels; + while (l < labels+lbl_hdr.label_length) { + printf("'%s'(%d)\n", l, strlen(l)); + l+=strlen(l)+1; + } #endif - + } #endif static void -garmin_img_coord_rewind(void *priv_data) -{ +garmin_img_coord_rewind(void *priv_data) { } static void -parse_line(struct map_rect_priv *mr) -{ - int pos=0; - sscanf(mr->line,"%lf %c %lf %c %n",&mr->lat,&mr->lat_c,&mr->lng,&mr->lng_c,&pos); - if (pos < strlen(mr->line)) { - strcpy(mr->attrs, mr->line+pos); - } +parse_line(struct map_rect_priv *mr) { + int pos=0; + sscanf(mr->line,"%lf %c %lf %c %n",&mr->lat,&mr->lat_c,&mr->lng,&mr->lng_c,&pos); + if (pos < strlen(mr->line)) { + strcpy(mr->attrs, mr->line+pos); + } } static int -get_bits(struct map_rect_priv *mr, int bits) -{ - unsigned long ret; - ret=L(*((unsigned long *)(mr->ply_data+mr->ply_bitpos/8))); - ret >>= (mr->ply_bitpos & 7); - ret &= (1 << bits)-1; - mr->ply_bitpos+=bits; - return ret; +get_bits(struct map_rect_priv *mr, int bits) { + unsigned long ret; + ret=L(*((unsigned long *)(mr->ply_data+mr->ply_bitpos/8))); + ret >>= (mr->ply_bitpos & 7); + ret &= (1 << bits)-1; + mr->ply_bitpos+=bits; + return ret; } static int -garmin_img_coord_get(void *priv_data, struct coord *c, int count) -{ - struct map_rect_priv *mr=priv_data; - struct subdivision *sub=(struct subdivision *)(mr->subdiv+mr->subdiv_pos); - int ret=0; - int debug=0; - if (debug) - printf("garmin_img_coord_get %d\n",count); - if (debug) - dump_subdivision(sub); - while (count--) { - if (mr->rgn_type < 2) { - c->x=triple(&sub->center.lng)+(mr->pnt->lng_delta << shift); - c->y=triple(&sub->center.lat)+(mr->pnt->lat_delta << shift); - } else { - if (! mr->ply_bitpos) { - if (mr->ply->info & 0x80) { - mr->ply_bitcount=mr->ply->u.p2.bitstream_len*8; - mr->ply_lngbits=mr->ply->u.p2.bitstream_info & 0xf; - mr->ply_latbits=mr->ply->u.p2.bitstream_info >> 4; - } else { - mr->ply_bitcount=mr->ply->u.p1.bitstream_len*8; - mr->ply_lngbits=mr->ply->u.p1.bitstream_info & 0xf; - mr->ply_latbits=mr->ply->u.p1.bitstream_info >> 4; - } - if (mr->ply_lngbits <= 9) - mr->ply_lngbits+=2; - if (mr->ply_latbits <= 9) - mr->ply_latbits+=2; - if (! get_bits(mr,1)) { - mr->ply_lngbits+=1; - mr->ply_lngsign=0; - } else - if (get_bits(mr, 1)) - mr->ply_lngsign=-1; - else - mr->ply_lngsign=1; - if (! get_bits(mr,1)) { - mr->ply_latbits+=1; - mr->ply_latsign=0; - } else - if (get_bits(mr, 1)) - mr->ply_latsign=-1; - else - mr->ply_latsign=1; - mr->ply_lnglimit=1 << (mr->ply_lngbits-1); - mr->ply_latlimit=1 << (mr->ply_latbits-1); - mr->ply_lng=mr->ply->lng_delta; - mr->ply_lat=mr->ply->lat_delta; - if (debug) - printf("lngbits %d latbits %d bitcount %d\n", mr->ply_lngbits, mr->ply_latbits, mr->ply_bitcount); - c->x=0; - c->y=0; - } else { - if (mr->ply_bitpos + mr->ply_lngbits + mr->ply_latbits > mr->ply_bitcount) { - if (debug) - printf("out of bits %d + %d + %d >= %d\n", mr->ply_bitpos, mr->ply_lngbits, mr->ply_latbits, mr->ply_bitcount); - return ret; - } - c->x=0; - c->y=0; - int x,y; - for (;;) { - x=get_bits(mr,mr->ply_lngbits); - if (debug) - printf("x %d ", x); - if (mr->ply_lngsign || x != mr->ply_lnglimit) - break; - c->x += x-1; - } - if (mr->ply_lngsign) { - c->x=x*mr->ply_lngsign; - } else { - if (x >= mr->ply_lnglimit) - c->x = x - (mr->ply_lnglimit << 1) - c->x; - else - c->x +=x; - } - for (;;) { - y=get_bits(mr,mr->ply_latbits); - if (debug) - printf("y %d ", y); - if (mr->ply_latsign || y != mr->ply_latlimit) - break; - c->y += y-1; - } - if (mr->ply_latsign) { - c->y=y*mr->ply_latsign; - } else { - if (y >= mr->ply_latlimit) - c->y = y - (mr->ply_latlimit << 1) - c->y; - else - c->y +=y; - } - mr->ply_lng += c->x; - mr->ply_lat += c->y; - } - if (debug) - printf(": x %d y %d\n", c->x, c->y); - - c->x=triple(&sub->center.lng)+(mr->ply_lng << shift); - c->y=triple(&sub->center.lat)+(mr->ply_lat << shift); - } +garmin_img_coord_get(void *priv_data, struct coord *c, int count) { + struct map_rect_priv *mr=priv_data; + struct subdivision *sub=(struct subdivision *)(mr->subdiv+mr->subdiv_pos); + int ret=0; + int debug=0; + if (debug) + printf("garmin_img_coord_get %d\n",count); + if (debug) + dump_subdivision(sub); + while (count--) { + if (mr->rgn_type < 2) { + c->x=triple(&sub->center.lng)+(mr->pnt->lng_delta << shift); + c->y=triple(&sub->center.lat)+(mr->pnt->lat_delta << shift); + } else { + if (! mr->ply_bitpos) { + if (mr->ply->info & 0x80) { + mr->ply_bitcount=mr->ply->u.p2.bitstream_len*8; + mr->ply_lngbits=mr->ply->u.p2.bitstream_info & 0xf; + mr->ply_latbits=mr->ply->u.p2.bitstream_info >> 4; + } else { + mr->ply_bitcount=mr->ply->u.p1.bitstream_len*8; + mr->ply_lngbits=mr->ply->u.p1.bitstream_info & 0xf; + mr->ply_latbits=mr->ply->u.p1.bitstream_info >> 4; + } + if (mr->ply_lngbits <= 9) + mr->ply_lngbits+=2; + if (mr->ply_latbits <= 9) + mr->ply_latbits+=2; + if (! get_bits(mr,1)) { + mr->ply_lngbits+=1; + mr->ply_lngsign=0; + } else if (get_bits(mr, 1)) + mr->ply_lngsign=-1; + else + mr->ply_lngsign=1; + if (! get_bits(mr,1)) { + mr->ply_latbits+=1; + mr->ply_latsign=0; + } else if (get_bits(mr, 1)) + mr->ply_latsign=-1; + else + mr->ply_latsign=1; + mr->ply_lnglimit=1 << (mr->ply_lngbits-1); + mr->ply_latlimit=1 << (mr->ply_latbits-1); + mr->ply_lng=mr->ply->lng_delta; + mr->ply_lat=mr->ply->lat_delta; + if (debug) + printf("lngbits %d latbits %d bitcount %d\n", mr->ply_lngbits, mr->ply_latbits, mr->ply_bitcount); + c->x=0; + c->y=0; + } else { + if (mr->ply_bitpos + mr->ply_lngbits + mr->ply_latbits > mr->ply_bitcount) { + if (debug) + printf("out of bits %d + %d + %d >= %d\n", mr->ply_bitpos, mr->ply_lngbits, mr->ply_latbits, mr->ply_bitcount); + return ret; + } + c->x=0; + c->y=0; + int x,y; + for (;;) { + x=get_bits(mr,mr->ply_lngbits); + if (debug) + printf("x %d ", x); + if (mr->ply_lngsign || x != mr->ply_lnglimit) + break; + c->x += x-1; + } + if (mr->ply_lngsign) { + c->x=x*mr->ply_lngsign; + } else { + if (x >= mr->ply_lnglimit) + c->x = x - (mr->ply_lnglimit << 1) - c->x; + else + c->x +=x; + } + for (;;) { + y=get_bits(mr,mr->ply_latbits); + if (debug) + printf("y %d ", y); + if (mr->ply_latsign || y != mr->ply_latlimit) + break; + c->y += y-1; + } + if (mr->ply_latsign) { + c->y=y*mr->ply_latsign; + } else { + if (y >= mr->ply_latlimit) + c->y = y - (mr->ply_latlimit << 1) - c->y; + else + c->y +=y; + } + mr->ply_lng += c->x; + mr->ply_lat += c->y; + } + if (debug) + printf(": x %d y %d\n", c->x, c->y); + + c->x=triple(&sub->center.lng)+(mr->ply_lng << shift); + c->y=triple(&sub->center.lat)+(mr->ply_lat << shift); + } #if 0 - c->x-=0x6f160; - c->y-=0x181f59; - c->x+=0x168ca1; - c->y+=0x68d815; + c->x-=0x6f160; + c->y-=0x181f59; + c->x+=0x168ca1; + c->y+=0x68d815; #endif - c++; - ret++; - if (mr->rgn_type < 2) - return ret; - } - return ret; + c++; + ret++; + if (mr->rgn_type < 2) + return ret; + } + return ret; } -static char * -get_label_offset(struct map_rect_priv *mr, int offset) -{ - g_assert(offset < mr->lbl_hdr->label.offset_len.length); - return file_read(&mr->lbl, mr->lbl_hdr->label.offset_len.offset+offset, 128); +static char * +get_label_offset(struct map_rect_priv *mr, int offset) { + g_assert(offset < mr->lbl_hdr->label.offset_len.length); + return file_read(&mr->lbl, mr->lbl_hdr->label.offset_len.offset+offset, 128); } static void -garmin_img_attr_rewind(void *priv_data) -{ +garmin_img_attr_rewind(void *priv_data) { } static int -garmin_img_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct map_rect_priv *mr=priv_data; - int debug=0; - - if (debug) - printf("garmin_img_attr_get\n"); - if (attr_type == attr_label) { - if (debug) - printf("garmin_img_attr_get label\n"); - attr->type=attr_type; - if (mr->rgn_type < 2) { - if (mr->label) - file_free(mr->label); - mr->label=get_label_offset(mr, triple_u(&mr->pnt->lbl_offset) & 0x3fffff); - attr->u.str=mr->label; - } else { - attr->u.str=""; - } - return 1; - } - return 0; +garmin_img_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct map_rect_priv *mr=priv_data; + int debug=0; + + if (debug) + printf("garmin_img_attr_get\n"); + if (attr_type == attr_label) { + if (debug) + printf("garmin_img_attr_get label\n"); + attr->type=attr_type; + if (mr->rgn_type < 2) { + if (mr->label) + file_free(mr->label); + mr->label=get_label_offset(mr, triple_u(&mr->pnt->lbl_offset) & 0x3fffff); + attr->u.str=mr->label; + } else { + attr->u.str=""; + } + return 1; + } + return 0; } static struct item_methods methods_garmin_img = { - garmin_img_coord_rewind, - garmin_img_coord_get, - garmin_img_attr_rewind, - garmin_img_attr_get, + garmin_img_coord_rewind, + garmin_img_coord_get, + garmin_img_attr_rewind, + garmin_img_attr_get, }; -static int rgn_next_type(struct map_rect_priv *mr) -{ - while (mr->rgn_type < 3) { - mr->rgn_type++; - if (mr->rgn_items[mr->rgn_type].offset && mr->rgn_items[mr->rgn_type].length != 0) { - mr->rgn_offset=mr->rgn_items[mr->rgn_type].offset; - mr->rgn_end=mr->rgn_offset+mr->rgn_items[mr->rgn_type].length; - return 0; - } - } - return 1; +static int rgn_next_type(struct map_rect_priv *mr) { + while (mr->rgn_type < 3) { + mr->rgn_type++; + if (mr->rgn_items[mr->rgn_type].offset && mr->rgn_items[mr->rgn_type].length != 0) { + mr->rgn_offset=mr->rgn_items[mr->rgn_type].offset; + mr->rgn_end=mr->rgn_offset+mr->rgn_items[mr->rgn_type].length; + return 0; + } + } + return 1; } static int -sub_next(struct map_rect_priv *mr, int next) -{ - int i,offset,first=-1,last=-1,count=-1; - int end; - unsigned short *offsets; - int debug=0; - - if (mr->subdiv_level_count <= 0) - return 1; - if (debug) - printf("%d left\n", mr->subdiv_level_count); - mr->subdiv_level_count--; - +sub_next(struct map_rect_priv *mr, int next) { + int i,offset,first=-1,last=-1,count=-1; + int end; + unsigned short *offsets; + int debug=0; + + if (mr->subdiv_level_count <= 0) + return 1; + if (debug) + printf("%d left\n", mr->subdiv_level_count); + mr->subdiv_level_count--; + #if 0 - if (next && mr->subdiv[mr->subdiv_current].width & 0x8000) - return 1; + if (next && mr->subdiv[mr->subdiv_current].width & 0x8000) + return 1; #endif - if (debug) - dump_hex_r(mr->subdiv+mr->subdiv_pos, 64, 14); - mr->subdiv_pos+=next; - if (debug) - printf("subdiv_pos 0x%x\n", mr->subdiv_pos); - if (mr->subdiv_pos > mr->tre_hdr->subdivision.length) - return 1; - struct subdivision *sub=(struct subdivision *)(mr->subdiv+mr->subdiv_pos); - offset=triple_u(&sub->rgn_offset)+mr->rgn_hdr->offset_len.offset; - if (debug) { - printf("offset=0x%x\n", offset); - dump_subdivision(sub); - } - offsets=file_read(&mr->rgn, offset, 3*sizeof(unsigned short)); - - if (! next) - next=subdiv_next; - if (mr->subdiv_pos+next < mr->tre_hdr->subdivision.length) - end=triple_u(&((struct subdivision *)(mr->subdiv+mr->subdiv_pos+next))->rgn_offset)+mr->rgn_hdr->offset_len.offset; - else - end=mr->rgn_hdr->offset_len.offset+mr->rgn_hdr->offset_len.length; - if (debug) { - dump_subdivision(sub); - dump_hex(offsets, 6); - } - for (i=0 ; i < 4 ; i++) { - if (debug) - printf("i=%d ", i); - if (sub->types & (0x10 << i)) { - if (debug) - printf("+ "); - if (first == -1) { - first=i; - mr->rgn_items[i].offset=offset; - if (debug) - printf("\n"); - } else { - mr->rgn_items[i].offset=offset+offsets[count]; - if (debug) - printf("0x%x\n", offsets[count]); - mr->rgn_items[last].length=mr->rgn_items[i].offset-mr->rgn_items[last].offset; - } - last=i; - count++; - } else { - if (debug) - printf("-\n"); - mr->rgn_items[i].offset=0; - mr->rgn_items[i].length=0; - } - - } - if (first != -1) { - mr->rgn_items[first].offset+=count*2; - mr->rgn_items[first].length-=count*2; - mr->rgn_items[last].length=end-mr->rgn_items[last].offset; - } - if (debug) { - for (i=0 ; i < 4 ; i++) { - printf("%d 0x%x 0x%x\n", i, mr->rgn_items[i].offset, mr->rgn_items[i].length); - } - } - mr->rgn_type=-1; - rgn_next_type(mr); - if (debug) - printf("*** offset 0x%x\n", mr->rgn_offset); - file_free(offsets); - return 0; + if (debug) + dump_hex_r(mr->subdiv+mr->subdiv_pos, 64, 14); + mr->subdiv_pos+=next; + if (debug) + printf("subdiv_pos 0x%x\n", mr->subdiv_pos); + if (mr->subdiv_pos > mr->tre_hdr->subdivision.length) + return 1; + struct subdivision *sub=(struct subdivision *)(mr->subdiv+mr->subdiv_pos); + offset=triple_u(&sub->rgn_offset)+mr->rgn_hdr->offset_len.offset; + if (debug) { + printf("offset=0x%x\n", offset); + dump_subdivision(sub); + } + offsets=file_read(&mr->rgn, offset, 3*sizeof(unsigned short)); + + if (! next) + next=subdiv_next; + if (mr->subdiv_pos+next < mr->tre_hdr->subdivision.length) + end=triple_u(&((struct subdivision *)(mr->subdiv+mr->subdiv_pos+next))->rgn_offset)+mr->rgn_hdr->offset_len.offset; + else + end=mr->rgn_hdr->offset_len.offset+mr->rgn_hdr->offset_len.length; + if (debug) { + dump_subdivision(sub); + dump_hex(offsets, 6); + } + for (i=0 ; i < 4 ; i++) { + if (debug) + printf("i=%d ", i); + if (sub->types & (0x10 << i)) { + if (debug) + printf("+ "); + if (first == -1) { + first=i; + mr->rgn_items[i].offset=offset; + if (debug) + printf("\n"); + } else { + mr->rgn_items[i].offset=offset+offsets[count]; + if (debug) + printf("0x%x\n", offsets[count]); + mr->rgn_items[last].length=mr->rgn_items[i].offset-mr->rgn_items[last].offset; + } + last=i; + count++; + } else { + if (debug) + printf("-\n"); + mr->rgn_items[i].offset=0; + mr->rgn_items[i].length=0; + } + + } + if (first != -1) { + mr->rgn_items[first].offset+=count*2; + mr->rgn_items[first].length-=count*2; + mr->rgn_items[last].length=end-mr->rgn_items[last].offset; + } + if (debug) { + for (i=0 ; i < 4 ; i++) { + printf("%d 0x%x 0x%x\n", i, mr->rgn_items[i].offset, mr->rgn_items[i].length); + } + } + mr->rgn_type=-1; + rgn_next_type(mr); + if (debug) + printf("*** offset 0x%x\n", mr->rgn_offset); + file_free(offsets); + return 0; } int item_count; static struct map_rect_priv * -map_rect_new_garmin_img(struct map_priv *map, struct coord_rect *r, struct layer *layers, int limit) -{ - struct map_rect_priv *mr; - struct img_header img; - - if (debug) - printf("map_rect_new_garmin_img\n"); - mr=g_new0(struct map_rect_priv, 1); - mr->m=map; - if (r) - mr->r=*r; - mr->limit=limit; - mr->item.id_hi=0; - mr->item.id_lo=0; - mr->item.meth=&methods_garmin_img; - mr->item.priv_data=mr; - mr->f=fopen(map->filename, "r"); - - fread(&img, sizeof(img), 1, mr->f); +map_rect_new_garmin_img(struct map_priv *map, struct coord_rect *r, struct layer *layers, int limit) { + struct map_rect_priv *mr; + struct img_header img; + + if (debug) + printf("map_rect_new_garmin_img\n"); + mr=g_new0(struct map_rect_priv, 1); + mr->m=map; + if (r) + mr->r=*r; + mr->limit=limit; + mr->item.id_hi=0; + mr->item.id_lo=0; + mr->item.meth=&methods_garmin_img; + mr->item.priv_data=mr; + mr->f=fopen(map->filename, "r"); + + fread(&img, sizeof(img), 1, mr->f); #if 0 - dump_img(&img); - for (i = 0 ; i < (img.file_offset-sizeof(img))/sizeof(fat_blk) ; i++) { - fread(&fat_blk, sizeof(fat_blk), 1, mr->f); - if (!fat_blk.flag) - break; - dump_fat_block(&fat_blk); - } + dump_img(&img); + for (i = 0 ; i < (img.file_offset-sizeof(img))/sizeof(fat_blk) ; i++) { + fread(&fat_blk, sizeof(fat_blk), 1, mr->f); + if (!fat_blk.flag) + break; + dump_fat_block(&fat_blk); + } #endif - mr->rgn.offset=0xa*2048; - mr->rgn.f=mr->f; - mr->rgn_hdr=file_read(&mr->rgn, 0, sizeof(*mr->rgn_hdr)); + mr->rgn.offset=0xa*2048; + mr->rgn.f=mr->f; + mr->rgn_hdr=file_read(&mr->rgn, 0, sizeof(*mr->rgn_hdr)); - mr->tre.offset=0x62b*2048; - mr->tre.f=mr->f; - mr->tre_hdr=file_read(&mr->tre, 0, sizeof(*mr->tre_hdr)); + mr->tre.offset=0x62b*2048; + mr->tre.f=mr->f; + mr->tre_hdr=file_read(&mr->tre, 0, sizeof(*mr->tre_hdr)); - mr->lbl.offset=0x64a*2048; - mr->lbl.f=mr->f; - mr->lbl_hdr=file_read(&mr->lbl, 0, sizeof(*mr->lbl_hdr)); + mr->lbl.offset=0x64a*2048; + mr->lbl.f=mr->f; + mr->lbl_hdr=file_read(&mr->lbl, 0, sizeof(*mr->lbl_hdr)); - mr->subdiv=file_read(&mr->tre, mr->tre_hdr->subdivision.offset, mr->tre_hdr->subdivision.length); + mr->subdiv=file_read(&mr->tre, mr->tre_hdr->subdivision.offset, mr->tre_hdr->subdivision.length); #if 0 - dump_hex_r(mr->subdiv, mr->tre_hdr->subdivision.length, 16); + dump_hex_r(mr->subdiv, mr->tre_hdr->subdivision.length, 16); #endif - dump_tree_header(mr->tre_hdr); - - dump_levels(mr); - - - printf("limit=%d\n", limit); - if (limit < 3) { - mr->subdiv_pos=0; - mr->subdiv_level_count=1; - shift=11; - } else if (limit < 6) { - mr->subdiv_pos=1*sizeof(struct subdivision); - mr->subdiv_level_count=5; - shift=9; - } else if (limit < 8) { - mr->subdiv_pos=6*sizeof(struct subdivision); - mr->subdiv_level_count=9; - shift=7; - } else if (limit < 10) { - mr->subdiv_pos=15*sizeof(struct subdivision); - mr->subdiv_level_count=143; - shift=5; - } else { - mr->subdiv_pos=158*sizeof(struct subdivision); - mr->subdiv_level_count=4190; - shift=2; - subdiv_next=14; - } + dump_tree_header(mr->tre_hdr); + + dump_levels(mr); + + + printf("limit=%d\n", limit); + if (limit < 3) { + mr->subdiv_pos=0; + mr->subdiv_level_count=1; + shift=11; + } else if (limit < 6) { + mr->subdiv_pos=1*sizeof(struct subdivision); + mr->subdiv_level_count=5; + shift=9; + } else if (limit < 8) { + mr->subdiv_pos=6*sizeof(struct subdivision); + mr->subdiv_level_count=9; + shift=7; + } else if (limit < 10) { + mr->subdiv_pos=15*sizeof(struct subdivision); + mr->subdiv_level_count=143; + shift=5; + } else { + mr->subdiv_pos=158*sizeof(struct subdivision); + mr->subdiv_level_count=4190; + shift=2; + subdiv_next=14; + } #if 0 - mr->rgn_offset=triple_u(&mr->subdiv[mr->subdiv_current].rgn_offset)+mr->rgn_hdr->offset_len.offset+4; - mr->rgn_type=1; - mr->rgn_end=mr->rgn_offset+20*8; + mr->rgn_offset=triple_u(&mr->subdiv[mr->subdiv_current].rgn_offset)+mr->rgn_hdr->offset_len.offset+4; + mr->rgn_type=1; + mr->rgn_end=mr->rgn_offset+20*8; #endif - mr->count=0; - item_count=0; + mr->count=0; + item_count=0; #if 0 - printf("*** offset 0x%x\n", 0x656c-mr->rgn.offset); - printf("*** offset 0x%x\n", mr->rgn_offset); + printf("*** offset 0x%x\n", 0x656c-mr->rgn.offset); + printf("*** offset 0x%x\n", mr->rgn_offset); #endif #if 1 - sub_next(mr, 0); + sub_next(mr, 0); #endif #if 0 - { - struct rgn_point *pnt; - int i; - int offset=0x65cc; - for (i = 0 ; i < 26 ; i++) { - pnt=file_read(&mr->rgn, 0x656c+8*i-mr->rgn.offset, sizeof(*pnt)); - // dump_hex(pnt, sizeof(*pnt)); - dump_point(pnt); - dump_label_offset(mr, triple_u(&pnt->lbl_offset)); - } - } - exit(0); + { + struct rgn_point *pnt; + int i; + int offset=0x65cc; + for (i = 0 ; i < 26 ; i++) { + pnt=file_read(&mr->rgn, 0x656c+8*i-mr->rgn.offset, sizeof(*pnt)); + // dump_hex(pnt, sizeof(*pnt)); + dump_point(pnt); + dump_label_offset(mr, triple_u(&pnt->lbl_offset)); + } + } + exit(0); #endif #if 0 - dump_tree(&mr->tre,&mr->rgn,mr); + dump_tree(&mr->tre,&mr->rgn,mr); #endif #if 0 - f.offset=0x64a*2048; - f.f=mr->f; - dump_labels(&f); + f.offset=0x64a*2048; + f.f=mr->f; + dump_labels(&f); #endif #if 0 - fseek(mr->f, img.file_offset, SEEK_SET); - fread(&fil, sizeof(fil), 1, mr->f); - dump_file(&fil); - fread(&rgn, sizeof(rgn), 1, mr->f); - dump_region(&rgn); - fseek(mr->f, rgn.data_length, SEEK_CUR); - fread(&fil, sizeof(fil), 1, mr->f); - dump_file(&fil); + fseek(mr->f, img.file_offset, SEEK_SET); + fread(&fil, sizeof(fil), 1, mr->f); + dump_file(&fil); + fread(&rgn, sizeof(rgn), 1, mr->f); + dump_region(&rgn); + fseek(mr->f, rgn.data_length, SEEK_CUR); + fread(&fil, sizeof(fil), 1, mr->f); + dump_file(&fil); #endif - return mr; + return mr; } static void -map_rect_destroy_garmin_img(struct map_rect_priv *mr) -{ - fclose(mr->f); - g_free(mr); +map_rect_destroy_garmin_img(struct map_rect_priv *mr) { + fclose(mr->f); + g_free(mr); } static struct item * -map_rect_get_item_garmin_img(struct map_rect_priv *mr) -{ - char *p,type[256]; - int ptype; - int debug=0; - - item_count++; - - if (debug) - printf("map_rect_get_item_garmin_img\n"); - for (;;) { - if (mr->rgn_offset < mr->rgn_end) { - if (debug) - printf("data available\n"); - if (mr->rgn_type >= 2) { - int len; - if (debug) - printf("polyline %d\n", mr->count); - if (mr->ply) - file_free(mr->ply); - mr->ply=file_read(&mr->rgn, mr->rgn_offset, sizeof(*mr->ply)*3); - if(triple_u(&mr->ply->lbl_offset) >= mr->lbl_hdr->label.offset_len.length) { - printf("item_count %d\n", item_count); - dump_poly(mr->ply); - dump_hex(mr->ply, 32); - printf("%d vs %d\n", triple_u(&mr->ply->lbl_offset), mr->lbl_hdr->label.offset_len.length); - } - g_assert(triple_u(&mr->ply->lbl_offset) < mr->lbl_hdr->label.offset_len.length); - if (debug) { - dump_hex(mr->ply, 16); - dump_poly(mr->ply); - } - if (mr->ply_data) - file_free(mr->ply_data); - mr->rgn_offset+=10; - if (mr->ply->info & 0x80) { - mr->rgn_offset++; - len=mr->ply->u.p2.bitstream_len; - } else - len=mr->ply->u.p1.bitstream_len; - - mr->ply_data=file_read(&mr->rgn, mr->rgn_offset, len); - mr->rgn_offset += len; - mr->ply_bitpos=0; - // dump_hex(mr->ply_data, 32); - if (mr->rgn_type == 3) { - switch(mr->ply->info & 0x7f) { - case 0x1: /* large urban area (>200k) */ - mr->item.type=type_town_poly; - break; - case 0xd: /* reservation */ - mr->item.type=type_park_poly; - break; - case 0xe: /* airport runway */ - mr->item.type=type_airport_poly; - break; - case 0x14: /* national park */ - mr->item.type=type_park_poly; - break; - case 0x32: /* sea */ - case 0x3d: /* large lake (77-250km2) */ - case 0x4c: /* intermittend water */ - mr->item.type=type_water_poly; - break; - case 0x4b: /* background */ - continue; - default: - printf("unknown polygon: 0x%x\n", mr->ply->info); - mr->item.type=type_street_3_city; - } - } else { - switch(mr->ply->info & 0x3f) { - case 0x1: /* major highway */ - mr->item.type=type_highway_land; - break; - case 0x2: /* principal highway */ - mr->item.type=type_street_3_land; - break; - case 0x6: /* residental street */ - mr->item.type=type_street_2_land; - break; - case 0x16: /* walkway/trail */ - mr->item.type=type_street_1_land; - break; - case 0x1e: /* international boundary */ - mr->item.type=type_border_country; - break; - case 0x20: /* minor land contour 1/10 */ - mr->item.type=type_height_line_1; - break; - case 0x21: /* major land contour 1/2 */ - mr->item.type=type_height_line_2; - break; - default: - printf("unknown polyline: 0x%x\n", mr->ply->info); - mr->item.type=type_street_3_city; - } - } - return &mr->item; - } - if (mr->pnt) - file_free(mr->pnt); - mr->pnt=file_read(&mr->rgn, mr->rgn_offset, sizeof(*mr->pnt)); - mr->item.type=type_none; - int subtype=mr->pnt->subtype; - if (mr->pnt->lbl_offset.data[2] & 0x80) - mr->rgn_offset+=9; - else { - mr->rgn_offset+=8; - subtype=0; - } - switch(mr->pnt->info) { - case 0x3: /* large city 2-5M */ - mr->item.type=type_town_label_2e6; - break; - case 0xa: /* small city/town 10-20k */ - mr->item.type=type_town_label_1e4; - break; - case 0xd: /* settlement 1-2K */ - mr->item.type=type_town_label_1e3; - break; - case 0x11: /* settlement less 100 */ - mr->item.type=type_town_label_5e1; - break; - case 0x1c: - switch(subtype) { - case 0x01: - mr->item.type=type_poi_wreck; - break; - } - break; - case 0x20: - mr->item.type=type_highway_exit; - break; - case 0x25: - mr->item.type=type_poi_toll_booth; - break; - case 0x2b: - switch(subtype) { - case 0x01: - mr->item.type=type_poi_hotel; - break; - case 0x03: - mr->item.type=type_poi_camp_rv; - break; - } - break; - case 0x2c: - switch(subtype) { - case 0x00: - mr->item.type=type_poi_attraction; - break; - case 0x02: - mr->item.type=type_poi_museum_history; - break; - } - break; - case 0x2e: - mr->item.type=type_poi_shopping; - break; - case 0x2f: - switch(subtype) { - case 0x01: - mr->item.type=type_poi_fuel; - break; - case 0x07: - mr->item.type=type_poi_car_dealer_parts; - break; - case 0x0b: - mr->item.type=type_poi_car_parking; - break; - case 0x15: - mr->item.type=type_poi_public_utilities; - break; - } - break; - case 0x30: - switch(subtype) { - case 0x02: - mr->item.type=type_poi_hospital; - break; - } - break; - case 0x43: - mr->item.type=type_poi_marina; - break; - case 0x46: - mr->item.type=type_poi_bar; - break; - case 0x48: - mr->item.type=type_poi_camping; - break; - case 0x49: - mr->item.type=type_poi_park; - break; - case 0x4a: - mr->item.type=type_poi_picnic; - break; - case 0x59: /* airport */ - mr->item.type=type_poi_airport; - break; - case 0x64: - switch(subtype) { - case 0x1: - mr->item.type=type_poi_bridge; - break; - case 0x2: - mr->item.type=type_poi_building; - break; - case 0x15: - mr->item.type=type_town_ghost; - break; - } - break; - case 0x65: - switch(subtype) { - case 0x0: - mr->item.type=type_poi_water_feature; - break; - case 0xc: - mr->item.type=type_poi_island; - break; - case 0xd: - mr->item.type=type_poi_lake; - break; - } - break; - case 0x66: - switch(subtype) { - case 0x0: - mr->item.type=type_poi_land_feature; - break; - case 0x6: - mr->item.type=type_poi_cape; - break; - case 0x14: - mr->item.type=type_poi_rock; - break; - } - break; - } - if (mr->item.type == type_none) { - printf("unknown point: 0x%x 0x%x\n", mr->pnt->info, mr->pnt->subtype); - dump_point(mr->pnt); - printf("label: %s\n", get_label_offset(mr, triple_u(&mr->pnt->lbl_offset) & 0x3fffff)); - mr->item.type=type_town_label; - } - return &mr->item; - } - if (debug) - printf("out of data for type\n"); - if (rgn_next_type(mr)) { - if (debug) - printf("out of data for region\n"); - if (sub_next(mr, subdiv_next)) { - if (debug) - printf("out of data for subdivision\n"); - return NULL; - } - } - } +map_rect_get_item_garmin_img(struct map_rect_priv *mr) { + char *p,type[256]; + int ptype; + int debug=0; + + item_count++; + + if (debug) + printf("map_rect_get_item_garmin_img\n"); + for (;;) { + if (mr->rgn_offset < mr->rgn_end) { + if (debug) + printf("data available\n"); + if (mr->rgn_type >= 2) { + int len; + if (debug) + printf("polyline %d\n", mr->count); + if (mr->ply) + file_free(mr->ply); + mr->ply=file_read(&mr->rgn, mr->rgn_offset, sizeof(*mr->ply)*3); + if(triple_u(&mr->ply->lbl_offset) >= mr->lbl_hdr->label.offset_len.length) { + printf("item_count %d\n", item_count); + dump_poly(mr->ply); + dump_hex(mr->ply, 32); + printf("%d vs %d\n", triple_u(&mr->ply->lbl_offset), mr->lbl_hdr->label.offset_len.length); + } + g_assert(triple_u(&mr->ply->lbl_offset) < mr->lbl_hdr->label.offset_len.length); + if (debug) { + dump_hex(mr->ply, 16); + dump_poly(mr->ply); + } + if (mr->ply_data) + file_free(mr->ply_data); + mr->rgn_offset+=10; + if (mr->ply->info & 0x80) { + mr->rgn_offset++; + len=mr->ply->u.p2.bitstream_len; + } else + len=mr->ply->u.p1.bitstream_len; + + mr->ply_data=file_read(&mr->rgn, mr->rgn_offset, len); + mr->rgn_offset += len; + mr->ply_bitpos=0; + // dump_hex(mr->ply_data, 32); + if (mr->rgn_type == 3) { + switch(mr->ply->info & 0x7f) { + case 0x1: /* large urban area (>200k) */ + mr->item.type=type_town_poly; + break; + case 0xd: /* reservation */ + mr->item.type=type_park_poly; + break; + case 0xe: /* airport runway */ + mr->item.type=type_airport_poly; + break; + case 0x14: /* national park */ + mr->item.type=type_park_poly; + break; + case 0x32: /* sea */ + case 0x3d: /* large lake (77-250km2) */ + case 0x4c: /* intermittend water */ + mr->item.type=type_water_poly; + break; + case 0x4b: /* background */ + continue; + default: + printf("unknown polygon: 0x%x\n", mr->ply->info); + mr->item.type=type_street_3_city; + } + } else { + switch(mr->ply->info & 0x3f) { + case 0x1: /* major highway */ + mr->item.type=type_highway_land; + break; + case 0x2: /* principal highway */ + mr->item.type=type_street_3_land; + break; + case 0x6: /* residental street */ + mr->item.type=type_street_2_land; + break; + case 0x16: /* walkway/trail */ + mr->item.type=type_street_1_land; + break; + case 0x1e: /* international boundary */ + mr->item.type=type_border_country; + break; + case 0x20: /* minor land contour 1/10 */ + mr->item.type=type_height_line_1; + break; + case 0x21: /* major land contour 1/2 */ + mr->item.type=type_height_line_2; + break; + default: + printf("unknown polyline: 0x%x\n", mr->ply->info); + mr->item.type=type_street_3_city; + } + } + return &mr->item; + } + if (mr->pnt) + file_free(mr->pnt); + mr->pnt=file_read(&mr->rgn, mr->rgn_offset, sizeof(*mr->pnt)); + mr->item.type=type_none; + int subtype=mr->pnt->subtype; + if (mr->pnt->lbl_offset.data[2] & 0x80) + mr->rgn_offset+=9; + else { + mr->rgn_offset+=8; + subtype=0; + } + switch(mr->pnt->info) { + case 0x3: /* large city 2-5M */ + mr->item.type=type_town_label_2e6; + break; + case 0xa: /* small city/town 10-20k */ + mr->item.type=type_town_label_1e4; + break; + case 0xd: /* settlement 1-2K */ + mr->item.type=type_town_label_1e3; + break; + case 0x11: /* settlement less 100 */ + mr->item.type=type_town_label_5e1; + break; + case 0x1c: + switch(subtype) { + case 0x01: + mr->item.type=type_poi_wreck; + break; + } + break; + case 0x20: + mr->item.type=type_highway_exit; + break; + case 0x25: + mr->item.type=type_poi_toll_booth; + break; + case 0x2b: + switch(subtype) { + case 0x01: + mr->item.type=type_poi_hotel; + break; + case 0x03: + mr->item.type=type_poi_camp_rv; + break; + } + break; + case 0x2c: + switch(subtype) { + case 0x00: + mr->item.type=type_poi_attraction; + break; + case 0x02: + mr->item.type=type_poi_museum_history; + break; + } + break; + case 0x2e: + mr->item.type=type_poi_shopping; + break; + case 0x2f: + switch(subtype) { + case 0x01: + mr->item.type=type_poi_fuel; + break; + case 0x07: + mr->item.type=type_poi_car_dealer_parts; + break; + case 0x0b: + mr->item.type=type_poi_car_parking; + break; + case 0x15: + mr->item.type=type_poi_public_utilities; + break; + } + break; + case 0x30: + switch(subtype) { + case 0x02: + mr->item.type=type_poi_hospital; + break; + } + break; + case 0x43: + mr->item.type=type_poi_marina; + break; + case 0x46: + mr->item.type=type_poi_bar; + break; + case 0x48: + mr->item.type=type_poi_camping; + break; + case 0x49: + mr->item.type=type_poi_park; + break; + case 0x4a: + mr->item.type=type_poi_picnic; + break; + case 0x59: /* airport */ + mr->item.type=type_poi_airport; + break; + case 0x64: + switch(subtype) { + case 0x1: + mr->item.type=type_poi_bridge; + break; + case 0x2: + mr->item.type=type_poi_building; + break; + case 0x15: + mr->item.type=type_town_ghost; + break; + } + break; + case 0x65: + switch(subtype) { + case 0x0: + mr->item.type=type_poi_water_feature; + break; + case 0xc: + mr->item.type=type_poi_island; + break; + case 0xd: + mr->item.type=type_poi_lake; + break; + } + break; + case 0x66: + switch(subtype) { + case 0x0: + mr->item.type=type_poi_land_feature; + break; + case 0x6: + mr->item.type=type_poi_cape; + break; + case 0x14: + mr->item.type=type_poi_rock; + break; + } + break; + } + if (mr->item.type == type_none) { + printf("unknown point: 0x%x 0x%x\n", mr->pnt->info, mr->pnt->subtype); + dump_point(mr->pnt); + printf("label: %s\n", get_label_offset(mr, triple_u(&mr->pnt->lbl_offset) & 0x3fffff)); + mr->item.type=type_town_label; + } + return &mr->item; + } + if (debug) + printf("out of data for type\n"); + if (rgn_next_type(mr)) { + if (debug) + printf("out of data for region\n"); + if (sub_next(mr, subdiv_next)) { + if (debug) + printf("out of data for subdivision\n"); + return NULL; + } + } + } } static struct item * -map_rect_get_item_byid_garmin_img(struct map_rect_priv *mr, int id_hi, int id_lo) -{ - fseek(mr->f, id_lo, SEEK_SET); - get_line(mr); - mr->item.id_hi=id_hi; - return map_rect_get_item_garmin_img(mr); +map_rect_get_item_byid_garmin_img(struct map_rect_priv *mr, int id_hi, int id_lo) { + fseek(mr->f, id_lo, SEEK_SET); + get_line(mr); + mr->item.id_hi=id_hi; + return map_rect_get_item_garmin_img(mr); } static struct map_methods map_methods_garmin_img = { - projection_garmin, - "iso8859-1", - map_destroy_garmin_img, - map_charset_garmin_img, - map_projection_garmin_img, - map_rect_new_garmin_img, - map_rect_destroy_garmin_img, - map_rect_get_item_garmin_img, - map_rect_get_item_byid_garmin_img, + projection_garmin, + "iso8859-1", + map_destroy_garmin_img, + map_charset_garmin_img, + map_projection_garmin_img, + map_rect_new_garmin_img, + map_rect_destroy_garmin_img, + map_rect_get_item_garmin_img, + map_rect_get_item_byid_garmin_img, }; static struct map_priv * -map_new_garmin_img(struct map_methods *meth, struct attr **attrs) -{ - struct map_priv *m; - struct attr *data=attr_search(attrs, NULL, attr_data); - if (! data) - return NULL; - - *meth=map_methods_garmin_img; - m=g_new(struct map_priv, 1); - m->id=++map_id; - m->filename=g_strdup(data->u.str); - return m; +map_new_garmin_img(struct map_methods *meth, struct attr **attrs) { + struct map_priv *m; + struct attr *data=attr_search(attrs, NULL, attr_data); + if (! data) + return NULL; + + *meth=map_methods_garmin_img; + m=g_new(struct map_priv, 1); + m->id=++map_id; + m->filename=g_strdup(data->u.str); + return m; } void -plugin_init(void) -{ - plugin_register_category_map("garmin_img", map_new_garmin_img); +plugin_init(void) { + plugin_register_category_map("garmin_img", map_new_garmin_img); } diff --git a/navit/map/mg/block.c b/navit/map/mg/block.c index 747e49b15..008d3f9ec 100644 --- a/navit/map/mg/block.c +++ b/navit/map/mg/block.c @@ -26,260 +26,268 @@ int block_lin_count,block_idx_count,block_active_count,block_mem,block_active_mem; struct block_index_item { - /*unsigned int blocknum; - unsigned int blocks;*/ - unsigned char p[8]; + /*unsigned int blocknum; + unsigned int blocks;*/ + unsigned char p[8]; }; -static inline unsigned int block_index_item_get_blocknum(struct block_index_item * blk) { unsigned char *p = blk->p; return get_u32(&p); } -static inline unsigned int block_index_item_get_blocks(struct block_index_item * blk) { unsigned char *p = blk->p+4; return get_u32(&p); } +static inline unsigned int block_index_item_get_blocknum(struct block_index_item * blk) { + unsigned char *p = blk->p; + return get_u32(&p); +} +static inline unsigned int block_index_item_get_blocks(struct block_index_item * blk) { + unsigned char *p = blk->p+4; + return get_u32(&p); +} struct block_index { -/* unsigned int blocks; - unsigned int size; - unsigned int next; - struct block_index_item list[0];*/ - unsigned char p[12]; + /* unsigned int blocks; + unsigned int size; + unsigned int next; + struct block_index_item list[0];*/ + unsigned char p[12]; }; -static inline unsigned int block_index_get_blocks(struct block_index * blk) { unsigned char *p = blk->p; return get_u32(&p); } -static inline unsigned int block_index_get_size(struct block_index * blk) { unsigned char *p = blk->p+4; return get_u32(&p); } -static inline unsigned int block_index_get_next(struct block_index * blk) { unsigned char *p = blk->p+8; return get_u32(&p); } -static inline struct block_index_item * block_index_get_list(struct block_index * blk) { return (struct block_index_item *)(blk->p+12); } +static inline unsigned int block_index_get_blocks(struct block_index * blk) { + unsigned char *p = blk->p; + return get_u32(&p); +} +static inline unsigned int block_index_get_size(struct block_index * blk) { + unsigned char *p = blk->p+4; + return get_u32(&p); +} +static inline unsigned int block_index_get_next(struct block_index * blk) { + unsigned char *p = blk->p+8; + return get_u32(&p); +} +static inline struct block_index_item * block_index_get_list(struct block_index * blk) { + return (struct block_index_item *)(blk->p+12); +} static struct block * -block_get(unsigned char **p) -{ - struct block *ret=(struct block *)(*p); - *p += sizeof(*ret); - return ret; +block_get(unsigned char **p) { + struct block *ret=(struct block *)(*p); + *p += sizeof(*ret); + return ret; } static struct block * -block_get_byid(struct file *file, int id, unsigned char **p_ret) -{ - struct block_index *blk_idx; - int blk_num,max; +block_get_byid(struct file *file, int id, unsigned char **p_ret) { + struct block_index *blk_idx; + int blk_num,max; - blk_idx=(struct block_index *)(file->begin+0x1000); - max=(block_index_get_size(blk_idx)-sizeof(struct block_index))/sizeof(struct block_index_item); - block_mem+=24; - while (id >= max) { - blk_idx=(struct block_index *)(file->begin+block_index_get_next(blk_idx)*512); - id-=max; - } - blk_num=block_index_item_get_blocknum(&block_index_get_list(blk_idx)[id]); + blk_idx=(struct block_index *)(file->begin+0x1000); + max=(block_index_get_size(blk_idx)-sizeof(struct block_index))/sizeof(struct block_index_item); + block_mem+=24; + while (id >= max) { + blk_idx=(struct block_index *)(file->begin+block_index_get_next(blk_idx)*512); + id-=max; + } + blk_num=block_index_item_get_blocknum(&block_index_get_list(blk_idx)[id]); - *p_ret=file->begin+blk_num*512; - return block_get(p_ret); + *p_ret=file->begin+blk_num*512; + return block_get(p_ret); } int -block_get_byindex(struct file *file, int idx, struct block_priv *blk) -{ - dbg(lvl_debug,"idx=%d", idx); - blk->b=block_get_byid(file, idx, &blk->p); - blk->block_start=(unsigned char *)(blk->b); - blk->p_start=blk->p; - blk->end=blk->block_start+block_get_size(blk->b); +block_get_byindex(struct file *file, int idx, struct block_priv *blk) { + dbg(lvl_debug,"idx=%d", idx); + blk->b=block_get_byid(file, idx, &blk->p); + blk->block_start=(unsigned char *)(blk->b); + blk->p_start=blk->p; + blk->end=blk->block_start+block_get_size(blk->b); - return 1; + return 1; } static void -block_setup_tags(struct map_rect_priv *mr) -{ - int len; - unsigned char *p,*t; - char *str; +block_setup_tags(struct map_rect_priv *mr) { + int len; + unsigned char *p,*t; + char *str; - mr->b.binarytree=0; + mr->b.binarytree=0; - p=mr->file->begin+0x0c; - while (*p) { - str=get_string(&p); - len=get_u32_unal(&p); - t=p; - /* printf("String '%s' len %d\n", str, len); */ - if (! strcmp(str,"FirstBatBlock")) { - /* printf("%ld\n", get_u32_unal(&t)); */ - } else if (! strcmp(str,"MaxBlockSize")) { - /* printf("%ld\n", get_u32_unal(&t)); */ - } else if (! strcmp(str,"FREE_BLOCK_LIST")) { - /* printf("%ld\n", get_u32_unal(&t)); */ - } else if (! strcmp(str,"TotalRect")) { - mr->b.b_rect.lu.x=get_u32_unal(&t); - mr->b.b_rect.lu.y=get_u32_unal(&t); - mr->b.b_rect.rl.x=get_u32_unal(&t); - mr->b.b_rect.rl.y=get_u32_unal(&t); - /* printf("0x%x,0x%x-0x%x,0x%x\n", mr->b.b_rect.lu.x, mr->b.b_rect.lu.y, mr->b.b_rect.rl.x, mr->b.b_rect.rl.y); */ - } else if (! strcmp(str,"Version")) { - /* printf("0x%lx\n", get_u32_unal(&t)); */ - } else if (! strcmp(str,"Categories")) { - /* printf("0x%x\n", get_u16(&t)); */ - } else if (! strcmp(str,"binaryTree")) { - mr->b.binarytree=get_u32_unal(&t); - /* printf("%d\n", mr->b.binarytree); */ - } else if (! strcmp(str,"CategorySets")) { - /* printf("0x%x\n", get_u16(&t)); */ - } else if (! strcmp(str,"Kommentar")) { - /* printf("%s\n", get_string(&t)); */ - } - p+=len; - } + p=mr->file->begin+0x0c; + while (*p) { + str=get_string(&p); + len=get_u32_unal(&p); + t=p; + /* printf("String '%s' len %d\n", str, len); */ + if (! strcmp(str,"FirstBatBlock")) { + /* printf("%ld\n", get_u32_unal(&t)); */ + } else if (! strcmp(str,"MaxBlockSize")) { + /* printf("%ld\n", get_u32_unal(&t)); */ + } else if (! strcmp(str,"FREE_BLOCK_LIST")) { + /* printf("%ld\n", get_u32_unal(&t)); */ + } else if (! strcmp(str,"TotalRect")) { + mr->b.b_rect.lu.x=get_u32_unal(&t); + mr->b.b_rect.lu.y=get_u32_unal(&t); + mr->b.b_rect.rl.x=get_u32_unal(&t); + mr->b.b_rect.rl.y=get_u32_unal(&t); + /* printf("0x%x,0x%x-0x%x,0x%x\n", mr->b.b_rect.lu.x, mr->b.b_rect.lu.y, mr->b.b_rect.rl.x, mr->b.b_rect.rl.y); */ + } else if (! strcmp(str,"Version")) { + /* printf("0x%lx\n", get_u32_unal(&t)); */ + } else if (! strcmp(str,"Categories")) { + /* printf("0x%x\n", get_u16(&t)); */ + } else if (! strcmp(str,"binaryTree")) { + mr->b.binarytree=get_u32_unal(&t); + /* printf("%d\n", mr->b.binarytree); */ + } else if (! strcmp(str,"CategorySets")) { + /* printf("0x%x\n", get_u16(&t)); */ + } else if (! strcmp(str,"Kommentar")) { + /* printf("%s\n", get_string(&t)); */ + } + p+=len; + } } #if 0 static void -block_rect_print(struct coord_rect *r) -{ - printf ("0x%x,0x%x-0x%x,0x%x (0x%x,0x%x)", r->lu.x, r->lu.y, r->rl.x, r->rl.y, r->lu.x/2+r->rl.x/2,r->lu.y/2+r->rl.y/2); +block_rect_print(struct coord_rect *r) { + printf ("0x%x,0x%x-0x%x,0x%x (0x%x,0x%x)", r->lu.x, r->lu.y, r->rl.x, r->rl.y, r->lu.x/2+r->rl.x/2,r->lu.y/2+r->rl.y/2); } #endif static void -block_rect_same(struct coord_rect *r1, struct coord_rect *r2) -{ - dbg_assert(r1->lu.x==r2->lu.x); - dbg_assert(r1->lu.y==r2->lu.y); - dbg_assert(r1->rl.x==r2->rl.x); - dbg_assert(r1->rl.y==r2->rl.y); +block_rect_same(struct coord_rect *r1, struct coord_rect *r2) { + dbg_assert(r1->lu.x==r2->lu.x); + dbg_assert(r1->lu.y==r2->lu.y); + dbg_assert(r1->rl.x==r2->rl.x); + dbg_assert(r1->rl.y==r2->rl.y); } int -block_init(struct map_rect_priv *mr) -{ - mr->b.block_num=-1; - mr->b.bt.b=NULL; - mr->b.bt.next=0; - block_setup_tags(mr); - if (mr->b.binarytree) { - mr->b.bt.next=mr->b.binarytree; - mr->b.bt.p=NULL; - mr->b.bt.block_count=0; - } - if (mr->cur_sel && !coord_rect_overlap(&mr->cur_sel->u.c_rect, &mr->b.b_rect)) - return 0; - return block_next(mr); +block_init(struct map_rect_priv *mr) { + mr->b.block_num=-1; + mr->b.bt.b=NULL; + mr->b.bt.next=0; + block_setup_tags(mr); + if (mr->b.binarytree) { + mr->b.bt.next=mr->b.binarytree; + mr->b.bt.p=NULL; + mr->b.bt.block_count=0; + } + if (mr->cur_sel && !coord_rect_overlap(&mr->cur_sel->u.c_rect, &mr->b.b_rect)) + return 0; + return block_next(mr); } int -block_next_lin(struct map_rect_priv *mr) -{ - struct coord_rect r; - for (;;) { - block_lin_count++; - block_mem+=sizeof(struct block *); - mr->b.block_num++; - if (! mr->b.block_num) - mr->b.p=mr->file->begin+0x2000; - else - mr->b.p=mr->b.block_start+block_get_blocks(mr->b.b)*512; - if (mr->b.p >= mr->file->end) { - dbg(lvl_debug,"end of blocks %p vs %p", mr->b.p, mr->file->end); - return 0; - } - mr->b.block_start=mr->b.p; - mr->b.b=block_get(&mr->b.p); - mr->b.p_start=mr->b.p; - mr->b.end=mr->b.block_start+block_get_size(mr->b.b); - if (block_get_count(mr->b.b) == -1) { - dbg(lvl_warning,"empty blocks"); - return 0; - } - block_get_r(mr->b.b, &r); - if (!mr->cur_sel || coord_rect_overlap(&mr->cur_sel->u.c_rect, &r)) { - block_active_count++; - block_active_mem+=block_get_blocks(mr->b.b)*512-sizeof(struct block *); - dbg(lvl_debug,"block ok"); - return 1; - } - dbg(lvl_info,"block not in cur_sel"); - } +block_next_lin(struct map_rect_priv *mr) { + struct coord_rect r; + for (;;) { + block_lin_count++; + block_mem+=sizeof(struct block *); + mr->b.block_num++; + if (! mr->b.block_num) + mr->b.p=mr->file->begin+0x2000; + else + mr->b.p=mr->b.block_start+block_get_blocks(mr->b.b)*512; + if (mr->b.p >= mr->file->end) { + dbg(lvl_debug,"end of blocks %p vs %p", mr->b.p, mr->file->end); + return 0; + } + mr->b.block_start=mr->b.p; + mr->b.b=block_get(&mr->b.p); + mr->b.p_start=mr->b.p; + mr->b.end=mr->b.block_start+block_get_size(mr->b.b); + if (block_get_count(mr->b.b) == -1) { + dbg(lvl_warning,"empty blocks"); + return 0; + } + block_get_r(mr->b.b, &r); + if (!mr->cur_sel || coord_rect_overlap(&mr->cur_sel->u.c_rect, &r)) { + block_active_count++; + block_active_mem+=block_get_blocks(mr->b.b)*512-sizeof(struct block *); + dbg(lvl_debug,"block ok"); + return 1; + } + dbg(lvl_info,"block not in cur_sel"); + } } int -block_next(struct map_rect_priv *mr) -{ - int blk_num,coord,r_h,r_w; - struct block_bt_priv *bt=&mr->b.bt; - struct coord_rect r; +block_next(struct map_rect_priv *mr) { + int blk_num,coord,r_h,r_w; + struct block_bt_priv *bt=&mr->b.bt; + struct coord_rect r; + + if (!mr->b.binarytree || ! mr->cur_sel) + return block_next_lin(mr); + for (;;) { + if (! bt->p) { + dbg(lvl_debug,"block 0x%x", bt->next); + if (bt->next == -1) + return 0; + bt->b=block_get_byid(mr->file, bt->next, &bt->p); + bt->end=(unsigned char *)mr->b.bt.b+block_get_size(mr->b.bt.b); + bt->next=block_get_next(bt->b); + bt->order=0; + dbg(lvl_debug,"size 0x%x next 0x%x", block_get_size(bt->b), block_get_next(bt->b)); + if (! mr->b.bt.block_count) { + block_get_r(bt->b, &bt->r); + bt->r_curr=bt->r; + coord=get_u32(&mr->b.bt.p); + } else { + bt->p=(unsigned char *)bt->b+0xc; + } + bt->block_count++; + } + while (mr->b.bt.p < mr->b.bt.end) { + block_idx_count++; + blk_num=get_u32(&mr->b.bt.p); + coord=get_u32(&mr->b.bt.p); + block_mem+=8; + dbg(lvl_debug,"%p vs %p coord 0x%x ", mr->b.bt.end, mr->b.bt.p, coord); + dbg(lvl_debug,"block 0x%x", blk_num); - if (!mr->b.binarytree || ! mr->cur_sel) - return block_next_lin(mr); - for (;;) { - if (! bt->p) { - dbg(lvl_debug,"block 0x%x", bt->next); - if (bt->next == -1) - return 0; - bt->b=block_get_byid(mr->file, bt->next, &bt->p); - bt->end=(unsigned char *)mr->b.bt.b+block_get_size(mr->b.bt.b); - bt->next=block_get_next(bt->b); - bt->order=0; - dbg(lvl_debug,"size 0x%x next 0x%x", block_get_size(bt->b), block_get_next(bt->b)); - if (! mr->b.bt.block_count) { - block_get_r(bt->b, &bt->r); - bt->r_curr=bt->r; - coord=get_u32(&mr->b.bt.p); - } else { - bt->p=(unsigned char *)bt->b+0xc; - } - bt->block_count++; - } - while (mr->b.bt.p < mr->b.bt.end) { - block_idx_count++; - blk_num=get_u32(&mr->b.bt.p); - coord=get_u32(&mr->b.bt.p); - block_mem+=8; - dbg(lvl_debug,"%p vs %p coord 0x%x ", mr->b.bt.end, mr->b.bt.p, coord); - dbg(lvl_debug,"block 0x%x", blk_num); - - r_w=bt->r_curr.rl.x-bt->r_curr.lu.x; - r_h=bt->r_curr.lu.y-bt->r_curr.rl.y; - mr->b.b=NULL; - if (blk_num != -1) { - block_mem+=8; - if (coord_rect_overlap(&mr->cur_sel->u.c_rect, &bt->r_curr)) { - mr->b.b=block_get_byid(mr->file, blk_num, &mr->b.p); - mr->b.block_num=blk_num; - dbg_assert(mr->b.b != NULL); - mr->b.block_start=(unsigned char *)(mr->b.b); - mr->b.p_start=mr->b.p; - mr->b.end=mr->b.block_start+block_get_size(mr->b.b); - block_get_r(mr->b.b, &r); - block_rect_same(&r, &bt->r_curr); - } - } - if (coord != -1) { - bt->stack[bt->stackp]=bt->r_curr; - if (r_w > r_h) { - bt->r_curr.rl.x=coord; - bt->stack[bt->stackp].lu.x=coord+1; - } else { - bt->r_curr.lu.y=coord; - bt->stack[bt->stackp].rl.y=coord+1; - } - bt->stackp++; - dbg_assert(bt->stackp < BT_STACK_SIZE); - } else { - if (bt->stackp) { - bt->stackp--; - bt->r_curr=bt->stack[bt->stackp]; - } else { - bt->r_curr=bt->r; - bt->order++; - if (bt->order > 100) - return 0; - } - } - if (mr->b.b) { - block_active_count++; - block_active_mem+=block_get_blocks(mr->b.b)*512; - return 1; - } - } - bt->p=NULL; - } - return 0; + r_w=bt->r_curr.rl.x-bt->r_curr.lu.x; + r_h=bt->r_curr.lu.y-bt->r_curr.rl.y; + mr->b.b=NULL; + if (blk_num != -1) { + block_mem+=8; + if (coord_rect_overlap(&mr->cur_sel->u.c_rect, &bt->r_curr)) { + mr->b.b=block_get_byid(mr->file, blk_num, &mr->b.p); + mr->b.block_num=blk_num; + dbg_assert(mr->b.b != NULL); + mr->b.block_start=(unsigned char *)(mr->b.b); + mr->b.p_start=mr->b.p; + mr->b.end=mr->b.block_start+block_get_size(mr->b.b); + block_get_r(mr->b.b, &r); + block_rect_same(&r, &bt->r_curr); + } + } + if (coord != -1) { + bt->stack[bt->stackp]=bt->r_curr; + if (r_w > r_h) { + bt->r_curr.rl.x=coord; + bt->stack[bt->stackp].lu.x=coord+1; + } else { + bt->r_curr.lu.y=coord; + bt->stack[bt->stackp].rl.y=coord+1; + } + bt->stackp++; + dbg_assert(bt->stackp < BT_STACK_SIZE); + } else { + if (bt->stackp) { + bt->stackp--; + bt->r_curr=bt->stack[bt->stackp]; + } else { + bt->r_curr=bt->r; + bt->order++; + if (bt->order > 100) + return 0; + } + } + if (mr->b.b) { + block_active_count++; + block_active_mem+=block_get_blocks(mr->b.b)*512; + return 1; + } + } + bt->p=NULL; + } + return 0; } diff --git a/navit/map/mg/map.c b/navit/map/mg/map.c index 81d28a8f3..097bf4d06 100644 --- a/navit/map/mg/map.c +++ b/navit/map/mg/map.c @@ -29,585 +29,572 @@ GList *maps; static struct country_isonum { - int country; - int isonum; - int postal_len; - char *postal_prefix; -} country_isonums[]={ - { 1,203}, - { 2,703}, - { 7,674}, - { 11,233}, - { 12,268}, - { 13,428}, - { 14,440}, - { 15,498}, - { 16,643}, - { 17,804}, - { 18,112}, - { 20,818}, - { 30,300}, - { 31,528}, - { 32, 56}, - { 33,250}, - { 34,724}, - { 36,348}, - { 39,380}, - { 40,642}, - { 41,756}, - { 43, 40}, - { 44,826}, - { 45,208}, - { 46,752}, - { 47,578}, - { 48,616}, - { 49,276,5,"D@@"}, - { 50,292}, - { 51,620}, - { 52,442}, - { 53,372}, - { 54,352}, - { 55, 8}, - { 56,470}, - { 57,196}, - { 58,246}, - { 59,100}, - { 61,422}, - { 62, 20}, - { 63,760}, - { 66,682}, - { 71,434}, - { 72,376}, - { 73,275}, - { 75,438}, - { 76,504}, - { 77, 12}, - { 78,788}, - { 81,688}, - { 83,400}, - { 85,191}, - { 86,705}, - { 87, 70}, - { 89,807}, - { 90,792}, - { 93,492}, - { 94, 31}, - { 95, 51}, - { 98,234}, - { 99,732}, - {336,774}, + int country; + int isonum; + int postal_len; + char *postal_prefix; +} country_isonums[]= { + { 1,203}, + { 2,703}, + { 7,674}, + { 11,233}, + { 12,268}, + { 13,428}, + { 14,440}, + { 15,498}, + { 16,643}, + { 17,804}, + { 18,112}, + { 20,818}, + { 30,300}, + { 31,528}, + { 32, 56}, + { 33,250}, + { 34,724}, + { 36,348}, + { 39,380}, + { 40,642}, + { 41,756}, + { 43, 40}, + { 44,826}, + { 45,208}, + { 46,752}, + { 47,578}, + { 48,616}, + { 49,276,5,"D@@"}, + { 50,292}, + { 51,620}, + { 52,442}, + { 53,372}, + { 54,352}, + { 55, 8}, + { 56,470}, + { 57,196}, + { 58,246}, + { 59,100}, + { 61,422}, + { 62, 20}, + { 63,760}, + { 66,682}, + { 71,434}, + { 72,376}, + { 73,275}, + { 75,438}, + { 76,504}, + { 77, 12}, + { 78,788}, + { 81,688}, + { 83,400}, + { 85,191}, + { 86,705}, + { 87, 70}, + { 89,807}, + { 90,792}, + { 93,492}, + { 94, 31}, + { 95, 51}, + { 98,234}, + { 99,732}, + {336,774}, }; struct map_priv * map_new_mg(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl); static int map_id; -static char *file[]={ - [file_border_ply]="border.ply", - [file_bridge_ply]="bridge.ply", - [file_build_ply]="build.ply", - [file_golf_ply]="golf.ply", - [file_height_ply]="height.ply", - [file_natpark_ply]="natpark.ply", - [file_nature_ply]="nature.ply", - [file_other_ply]="other.ply", - [file_rail_ply]="rail.ply", - [file_sea_ply]="sea.ply", - [file_street_bti]="street.bti", - [file_street_str]="street.str", - [file_strname_stn]="strname.stn", - [file_town_twn]="town.twn", - [file_tunnel_ply]="tunnel.ply", - [file_water_ply]="water.ply", - [file_woodland_ply]="woodland.ply", +static char *file[]= { + [file_border_ply]="border.ply", + [file_bridge_ply]="bridge.ply", + [file_build_ply]="build.ply", + [file_golf_ply]="golf.ply", + [file_height_ply]="height.ply", + [file_natpark_ply]="natpark.ply", + [file_nature_ply]="nature.ply", + [file_other_ply]="other.ply", + [file_rail_ply]="rail.ply", + [file_sea_ply]="sea.ply", + [file_street_bti]="street.bti", + [file_street_str]="street.str", + [file_strname_stn]="strname.stn", + [file_town_twn]="town.twn", + [file_tunnel_ply]="tunnel.ply", + [file_water_ply]="water.ply", + [file_woodland_ply]="woodland.ply", }; -int mg_country_from_isonum(int isonum) -{ - int i; - for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) - if (country_isonums[i].isonum == isonum) - return country_isonums[i].country; - return 0; +int mg_country_from_isonum(int isonum) { + int i; + for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) + if (country_isonums[i].isonum == isonum) + return country_isonums[i].country; + return 0; } -int mg_country_to_isonum(int country) -{ - int i; - for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) - if (country_isonums[i].country == country) - return country_isonums[i].isonum; - return 0; +int mg_country_to_isonum(int country) { + int i; + for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) + if (country_isonums[i].country == country) + return country_isonums[i].isonum; + return 0; } -int mg_country_postal_len(int country) -{ - int i; - for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) - if (country_isonums[i].country == country) - return country_isonums[i].postal_len; - return 0; +int mg_country_postal_len(int country) { + int i; + for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) + if (country_isonums[i].country == country) + return country_isonums[i].postal_len; + return 0; } -static char *mg_country_postal_prefix(int isonum) -{ - int i; - for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) - if (country_isonums[i].isonum == isonum) - return country_isonums[i].postal_prefix; - return NULL; +static char *mg_country_postal_prefix(int isonum) { + int i; + for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) + if (country_isonums[i].isonum == isonum) + return country_isonums[i].postal_prefix; + return NULL; } -struct item_range town_ranges[]={ - {type_town_label,type_port_label}, +struct item_range town_ranges[]= { + {type_town_label,type_port_label}, }; -struct item_range street_ranges[]={ - {type_street_nopass,type_street_unkn}, +struct item_range street_ranges[]= { + {type_street_nopass,type_street_unkn}, }; -struct item_range poly_ranges[]={ - {type_border_country,type_water_line}, - {type_street_unkn,type_street_unkn}, - {type_area,type_last}, +struct item_range poly_ranges[]= { + {type_border_country,type_water_line}, + {type_street_unkn,type_street_unkn}, + {type_area,type_last}, }; static int -file_next(struct map_rect_priv *mr) -{ - int debug=0; - - for (;;) { - mr->current_file++; - if (mr->current_file >= file_end) - return 0; - mr->file=mr->m->file[mr->current_file]; - if (! mr->file) - continue; - switch (mr->current_file) { - case file_strname_stn: - continue; - case file_town_twn: - if (mr->cur_sel && !map_selection_contains_item_range(mr->cur_sel, 0, town_ranges, sizeof(town_ranges)/sizeof(struct item_range))) - continue; - break; - case file_street_str: - if (mr->cur_sel && !map_selection_contains_item_range(mr->cur_sel, 0, street_ranges, sizeof(street_ranges)/sizeof(struct item_range))) - continue; - break; - default: - if (mr->cur_sel && !map_selection_contains_item_range(mr->cur_sel, 0, poly_ranges, sizeof(poly_ranges)/sizeof(struct item_range))) - continue; - break; - } - if (debug) - printf("current file: '%s'\n", file[mr->current_file]); - mr->cur_sel=mr->xsel; - if (block_init(mr)) - return 1; - } +file_next(struct map_rect_priv *mr) { + int debug=0; + + for (;;) { + mr->current_file++; + if (mr->current_file >= file_end) + return 0; + mr->file=mr->m->file[mr->current_file]; + if (! mr->file) + continue; + switch (mr->current_file) { + case file_strname_stn: + continue; + case file_town_twn: + if (mr->cur_sel + && !map_selection_contains_item_range(mr->cur_sel, 0, town_ranges, sizeof(town_ranges)/sizeof(struct item_range))) + continue; + break; + case file_street_str: + if (mr->cur_sel + && !map_selection_contains_item_range(mr->cur_sel, 0, street_ranges, sizeof(street_ranges)/sizeof(struct item_range))) + continue; + break; + default: + if (mr->cur_sel + && !map_selection_contains_item_range(mr->cur_sel, 0, poly_ranges, sizeof(poly_ranges)/sizeof(struct item_range))) + continue; + break; + } + if (debug) + printf("current file: '%s'\n", file[mr->current_file]); + mr->cur_sel=mr->xsel; + if (block_init(mr)) + return 1; + } } static void -map_destroy_mg(struct map_priv *m) -{ - int i; - - printf("mg_map_destroy\n"); - for (i = 0 ; i < file_end ; i++) { - if (m->file[i]) - file_destroy(m->file[i]); - } +map_destroy_mg(struct map_priv *m) { + int i; + + printf("mg_map_destroy\n"); + for (i = 0 ; i < file_end ; i++) { + if (m->file[i]) + file_destroy(m->file[i]); + } } extern int block_lin_count,block_idx_count,block_active_count,block_mem,block_active_mem; struct map_rect_priv * -map_rect_new_mg(struct map_priv *map, struct map_selection *sel) -{ - struct map_rect_priv *mr; - int i; - - block_lin_count=0; - block_idx_count=0; - block_active_count=0; - block_mem=0; - block_active_mem=0; - mr=g_new0(struct map_rect_priv, 1); - mr->m=map; - mr->xsel=sel; - mr->current_file=-1; - if (sel && sel->next) - for (i=0 ; i < file_end ; i++) - mr->block_hash[i]=g_hash_table_new(g_int_hash,g_int_equal); - file_next(mr); - return mr; +map_rect_new_mg(struct map_priv *map, struct map_selection *sel) { + struct map_rect_priv *mr; + int i; + + block_lin_count=0; + block_idx_count=0; + block_active_count=0; + block_mem=0; + block_active_mem=0; + mr=g_new0(struct map_rect_priv, 1); + mr->m=map; + mr->xsel=sel; + mr->current_file=-1; + if (sel && sel->next) + for (i=0 ; i < file_end ; i++) + mr->block_hash[i]=g_hash_table_new(g_int_hash,g_int_equal); + file_next(mr); + return mr; } static struct item * -map_rect_get_item_mg(struct map_rect_priv *mr) -{ - for (;;) { - switch (mr->current_file) { - case file_town_twn: - if (town_get(mr, &mr->town, &mr->item)) - return &mr->item; - break; - case file_border_ply: - case file_bridge_ply: - case file_build_ply: - case file_golf_ply: - /* case file_height_ply: */ - case file_natpark_ply: - case file_nature_ply: - case file_other_ply: - case file_rail_ply: - case file_sea_ply: - /* case file_tunnel_ply: */ - case file_water_ply: - case file_woodland_ply: - if (poly_get(mr, &mr->poly, &mr->item)) - return &mr->item; - break; - case file_street_str: - if (street_get(mr, &mr->street, &mr->item)) - return &mr->item; - break; - case file_end: - return NULL; - default: - break; - } - if (block_next(mr)) - continue; - if (mr->cur_sel->next) { - mr->cur_sel=mr->cur_sel->next; - if (block_init(mr)) - continue; - } - if (file_next(mr)) - continue; - dbg(lvl_debug,"lin_count %d idx_count %d active_count %d %d kB (%d kB)", block_lin_count, block_idx_count, block_active_count, (block_mem+block_active_mem)/1024, block_active_mem/1024); - return NULL; - } +map_rect_get_item_mg(struct map_rect_priv *mr) { + for (;;) { + switch (mr->current_file) { + case file_town_twn: + if (town_get(mr, &mr->town, &mr->item)) + return &mr->item; + break; + case file_border_ply: + case file_bridge_ply: + case file_build_ply: + case file_golf_ply: + /* case file_height_ply: */ + case file_natpark_ply: + case file_nature_ply: + case file_other_ply: + case file_rail_ply: + case file_sea_ply: + /* case file_tunnel_ply: */ + case file_water_ply: + case file_woodland_ply: + if (poly_get(mr, &mr->poly, &mr->item)) + return &mr->item; + break; + case file_street_str: + if (street_get(mr, &mr->street, &mr->item)) + return &mr->item; + break; + case file_end: + return NULL; + default: + break; + } + if (block_next(mr)) + continue; + if (mr->cur_sel->next) { + mr->cur_sel=mr->cur_sel->next; + if (block_init(mr)) + continue; + } + if (file_next(mr)) + continue; + dbg(lvl_debug,"lin_count %d idx_count %d active_count %d %d kB (%d kB)", block_lin_count, block_idx_count, + block_active_count, (block_mem+block_active_mem)/1024, block_active_mem/1024); + return NULL; + } } struct item * -map_rect_get_item_byid_mg(struct map_rect_priv *mr, int id_hi, int id_lo) -{ - mr->current_file = (id_hi >> 16) & 0xff; - switch (mr->current_file) { - case file_town_twn: - if (town_get_byid(mr, &mr->town, id_hi, id_lo, &mr->item)) - return &mr->item; - break; - case file_street_str: - if (street_get_byid(mr, &mr->street, id_hi, id_lo, &mr->item)) - return &mr->item; - break; - case file_strname_stn: - if (street_name_get_byid(mr, &mr->street, id_hi, id_lo, &mr->item)) - return &mr->item; - break; - default: - if (poly_get_byid(mr, &mr->poly, id_hi, id_lo, &mr->item)) - return &mr->item; - break; - } - return NULL; +map_rect_get_item_byid_mg(struct map_rect_priv *mr, int id_hi, int id_lo) { + mr->current_file = (id_hi >> 16) & 0xff; + switch (mr->current_file) { + case file_town_twn: + if (town_get_byid(mr, &mr->town, id_hi, id_lo, &mr->item)) + return &mr->item; + break; + case file_street_str: + if (street_get_byid(mr, &mr->street, id_hi, id_lo, &mr->item)) + return &mr->item; + break; + case file_strname_stn: + if (street_name_get_byid(mr, &mr->street, id_hi, id_lo, &mr->item)) + return &mr->item; + break; + default: + if (poly_get_byid(mr, &mr->poly, id_hi, id_lo, &mr->item)) + return &mr->item; + break; + } + return NULL; } void -map_rect_destroy_mg(struct map_rect_priv *mr) -{ - int i; - for (i=0 ; i < file_end ; i++) - if (mr->block_hash[i]) - g_hash_table_destroy(mr->block_hash[i]); - g_free(mr); +map_rect_destroy_mg(struct map_rect_priv *mr) { + int i; + for (i=0 ; i < file_end ; i++) + if (mr->block_hash[i]) + g_hash_table_destroy(mr->block_hash[i]); + g_free(mr); } static char * -map_search_mg_convert_special(char *str) -{ - char *ret,*c=g_malloc(strlen(str)*2+1); - - ret=c; - for (;;) { - switch ((unsigned char)(*str)) { - case 0xc4: - *c++='A'; - break; - case 0xd6: - *c++='O'; - break; - case 0xdc: - *c++='U'; - break; - case 0xdf: - *c++='s'; - *c++='s'; - break; - case 0xe4: - *c++='a'; - break; - case 0xf6: - *c++='o'; - break; - case 0xfc: - *c++='u'; - break; - default: - dbg(lvl_debug,"0x%x", *str); - *c++=*str; - break; - } - if (! *str) - return ret; - str++; - } +map_search_mg_convert_special(char *str) { + char *ret,*c=g_malloc(strlen(str)*2+1); + + ret=c; + for (;;) { + switch ((unsigned char)(*str)) { + case 0xc4: + *c++='A'; + break; + case 0xd6: + *c++='O'; + break; + case 0xdc: + *c++='U'; + break; + case 0xdf: + *c++='s'; + *c++='s'; + break; + case 0xe4: + *c++='a'; + break; + case 0xf6: + *c++='o'; + break; + case 0xfc: + *c++='u'; + break; + default: + dbg(lvl_debug,"0x%x", *str); + *c++=*str; + break; + } + if (! *str) + return ret; + str++; + } } static int -map_search_setup(struct map_rect_priv *mr) -{ - char *prefix; - dbg(lvl_debug,"%s", attr_to_name(mr->search_type)); - switch (mr->search_type) { - case attr_town_postal: - if (mr->search_item.type != type_country_label) { - dbg(lvl_error,"wrong parent type %s", item_to_name(mr->search_item.type)); - return 0; - } - prefix=mg_country_postal_prefix(mr->search_item.id_lo); - if (! prefix) - return 0; - tree_search_init(mr->m->dirname, "town.b1", &mr->ts, 0); - mr->current_file=file_town_twn; - mr->search_str=g_strdup_printf("%s%s",prefix,mr->search_attr->u.str); - dbg(lvl_debug,"search_str='%s'",mr->search_str); - mr->search_country=mg_country_from_isonum(mr->search_item.id_lo); - break; - case attr_town_name: - if (mr->search_item.type != type_country_label) { - dbg(lvl_error,"wrong parent type %s", item_to_name(mr->search_item.type)); - return 0; - } - tree_search_init(mr->m->dirname, "town.b2", &mr->ts, 0x1000); - mr->current_file=file_town_twn; - mr->search_str=map_search_mg_convert_special(mr->search_attr->u.str); - mr->search_country=mg_country_from_isonum(mr->search_item.id_lo); - break; - case attr_district_name: - if (mr->search_item.type != type_country_label) { - dbg(lvl_error,"wrong parent type %s", item_to_name(mr->search_item.type)); - return 0; - } - tree_search_init(mr->m->dirname, "town.b3", &mr->ts, 0x1000); - mr->current_file=file_town_twn; - mr->search_str=map_search_mg_convert_special(mr->search_attr->u.str); - mr->search_country=mg_country_from_isonum(mr->search_item.id_lo); - break; - case attr_street_name: - if (mr->search_item.type != type_town_streets) { - GList *tmp=maps; - struct item *item=NULL; - struct attr attr; - struct map_rect_priv *mr2; - while (tmp) { - mr2=map_rect_new_mg(tmp->data, NULL); - item=map_rect_get_item_byid_mg(mr2, mr->search_item.id_hi, mr->search_item.id_lo); - if (item) - break; - map_rect_destroy_mg(mr2); - tmp=g_list_next(tmp); - } - if (item) { - if (item_attr_get(item, attr_town_streets_item, &attr)) { - mr->search_item=*attr.u.item; - map_rect_destroy_mg(mr2); - } else { - map_rect_destroy_mg(mr2); - return 0; - } - } else { - dbg(lvl_error,"wrong parent type %s %p 0x%x 0x%x", item_to_name(mr->search_item.type), item, mr->search_item.id_hi, mr->search_item.id_lo); - return 0; - } - } - dbg(lvl_debug,"street_assoc=0x%x", mr->search_item.id_lo); - tree_search_init(mr->m->dirname, "strname.b1", &mr->ts, 0); - mr->current_file=file_strname_stn; - mr->search_str=g_strdup(mr->search_attr->u.str); - break; - case attr_house_number: - if (!map_priv_is(mr->search_item.map, mr->m)) - return 0; - if (!housenumber_search_setup(mr)) { - dbg(lvl_error,"failed to search for attr_house_number"); - return 0; - } - break; - default: - dbg(lvl_error,"unknown search %s",attr_to_name(mr->search_type)); - return 0; - } - mr->file=mr->m->file[mr->current_file]; - block_init(mr); - return 1; +map_search_setup(struct map_rect_priv *mr) { + char *prefix; + dbg(lvl_debug,"%s", attr_to_name(mr->search_type)); + switch (mr->search_type) { + case attr_town_postal: + if (mr->search_item.type != type_country_label) { + dbg(lvl_error,"wrong parent type %s", item_to_name(mr->search_item.type)); + return 0; + } + prefix=mg_country_postal_prefix(mr->search_item.id_lo); + if (! prefix) + return 0; + tree_search_init(mr->m->dirname, "town.b1", &mr->ts, 0); + mr->current_file=file_town_twn; + mr->search_str=g_strdup_printf("%s%s",prefix,mr->search_attr->u.str); + dbg(lvl_debug,"search_str='%s'",mr->search_str); + mr->search_country=mg_country_from_isonum(mr->search_item.id_lo); + break; + case attr_town_name: + if (mr->search_item.type != type_country_label) { + dbg(lvl_error,"wrong parent type %s", item_to_name(mr->search_item.type)); + return 0; + } + tree_search_init(mr->m->dirname, "town.b2", &mr->ts, 0x1000); + mr->current_file=file_town_twn; + mr->search_str=map_search_mg_convert_special(mr->search_attr->u.str); + mr->search_country=mg_country_from_isonum(mr->search_item.id_lo); + break; + case attr_district_name: + if (mr->search_item.type != type_country_label) { + dbg(lvl_error,"wrong parent type %s", item_to_name(mr->search_item.type)); + return 0; + } + tree_search_init(mr->m->dirname, "town.b3", &mr->ts, 0x1000); + mr->current_file=file_town_twn; + mr->search_str=map_search_mg_convert_special(mr->search_attr->u.str); + mr->search_country=mg_country_from_isonum(mr->search_item.id_lo); + break; + case attr_street_name: + if (mr->search_item.type != type_town_streets) { + GList *tmp=maps; + struct item *item=NULL; + struct attr attr; + struct map_rect_priv *mr2; + while (tmp) { + mr2=map_rect_new_mg(tmp->data, NULL); + item=map_rect_get_item_byid_mg(mr2, mr->search_item.id_hi, mr->search_item.id_lo); + if (item) + break; + map_rect_destroy_mg(mr2); + tmp=g_list_next(tmp); + } + if (item) { + if (item_attr_get(item, attr_town_streets_item, &attr)) { + mr->search_item=*attr.u.item; + map_rect_destroy_mg(mr2); + } else { + map_rect_destroy_mg(mr2); + return 0; + } + } else { + dbg(lvl_error,"wrong parent type %s %p 0x%x 0x%x", item_to_name(mr->search_item.type), item, mr->search_item.id_hi, + mr->search_item.id_lo); + return 0; + } + } + dbg(lvl_debug,"street_assoc=0x%x", mr->search_item.id_lo); + tree_search_init(mr->m->dirname, "strname.b1", &mr->ts, 0); + mr->current_file=file_strname_stn; + mr->search_str=g_strdup(mr->search_attr->u.str); + break; + case attr_house_number: + if (!map_priv_is(mr->search_item.map, mr->m)) + return 0; + if (!housenumber_search_setup(mr)) { + dbg(lvl_error,"failed to search for attr_house_number"); + return 0; + } + break; + default: + dbg(lvl_error,"unknown search %s",attr_to_name(mr->search_type)); + return 0; + } + mr->file=mr->m->file[mr->current_file]; + block_init(mr); + return 1; } static void map_search_cleanup(struct map_rect_priv *mr); static struct item * map_search_get_item_mg(struct map_search_priv *ms); static struct map_search_priv * -map_search_new_mg(struct map_priv *map, struct item *item, struct attr *search, int partial) -{ - struct map_rect_priv *mr=g_new0(struct map_rect_priv, 1); - dbg(lvl_debug,"searching for %s '%s'", attr_to_name(search->type), search->u.str); - dbg(lvl_debug,"id_lo=0x%x", item->id_lo); - dbg(lvl_debug,"search=%s", search->u.str); - mr->m=map; - mr->search_attr=attr_dup(search); - mr->search_type=search->type; - mr->search_item=*item; - mr->search_partial=partial; - if (search->type == attr_town_or_district_name) { - mr->search_type=attr_town_name; - mr->search_type_next=attr_district_name; - } - if (!map_search_setup(mr)) { - dbg(lvl_warning,"map_search_new_mg failed"); - g_free(mr); - return NULL; - } - mr->search_mr_tmp=map_rect_new_mg(map, NULL); - - return (struct map_search_priv *)mr; +map_search_new_mg(struct map_priv *map, struct item *item, struct attr *search, int partial) { + struct map_rect_priv *mr=g_new0(struct map_rect_priv, 1); + dbg(lvl_debug,"searching for %s '%s'", attr_to_name(search->type), search->u.str); + dbg(lvl_debug,"id_lo=0x%x", item->id_lo); + dbg(lvl_debug,"search=%s", search->u.str); + mr->m=map; + mr->search_attr=attr_dup(search); + mr->search_type=search->type; + mr->search_item=*item; + mr->search_partial=partial; + if (search->type == attr_town_or_district_name) { + mr->search_type=attr_town_name; + mr->search_type_next=attr_district_name; + } + if (!map_search_setup(mr)) { + dbg(lvl_warning,"map_search_new_mg failed"); + g_free(mr); + return NULL; + } + mr->search_mr_tmp=map_rect_new_mg(map, NULL); + + return (struct map_search_priv *)mr; } static void -map_search_cleanup(struct map_rect_priv *mr) -{ - g_free(mr->search_str); - mr->search_str=NULL; - tree_search_free(&mr->ts); - mr->search_linear=0; - mr->search_p=NULL; - mr->search_blk_count=0; - mr->search_blk_off=NULL; - mr->search_block=0; +map_search_cleanup(struct map_rect_priv *mr) { + g_free(mr->search_str); + mr->search_str=NULL; + tree_search_free(&mr->ts); + mr->search_linear=0; + mr->search_p=NULL; + mr->search_blk_count=0; + mr->search_blk_off=NULL; + mr->search_block=0; } static void -map_search_destroy_mg(struct map_search_priv *ms) -{ - struct map_rect_priv *mr=(struct map_rect_priv *)ms; - - dbg(lvl_debug,"mr=%p", mr); - if (! mr) - return; - map_search_cleanup(mr); - if (mr->search_mr_tmp) - map_rect_destroy_mg(mr->search_mr_tmp); - attr_free(mr->search_attr); - g_free(mr); +map_search_destroy_mg(struct map_search_priv *ms) { + struct map_rect_priv *mr=(struct map_rect_priv *)ms; + + dbg(lvl_debug,"mr=%p", mr); + if (! mr) + return; + map_search_cleanup(mr); + if (mr->search_mr_tmp) + map_rect_destroy_mg(mr->search_mr_tmp); + attr_free(mr->search_attr); + g_free(mr); } static struct item * -map_search_get_item_mg(struct map_search_priv *ms) -{ - struct map_rect_priv *mr=(struct map_rect_priv *)ms; - struct item *ret=NULL; - - if (! mr) - return NULL; - switch (mr->search_type) { - case attr_town_postal: - case attr_town_name: - case attr_district_name: - ret=town_search_get_item(mr); - break; - case attr_street_name: - ret=street_search_get_item(mr); - break; - case attr_house_number: - ret=housenumber_search_get_item(mr); - break; - default: - dbg(lvl_error,"unknown search %s",attr_to_name(mr->search_type)); - break; - } - if (!ret && mr->search_type_next != attr_none) { - mr->search_type=mr->search_type_next; - mr->search_type_next=attr_none; - map_search_cleanup(mr); - map_search_setup(mr); - return map_search_get_item_mg(ms); - } - return ret; +map_search_get_item_mg(struct map_search_priv *ms) { + struct map_rect_priv *mr=(struct map_rect_priv *)ms; + struct item *ret=NULL; + + if (! mr) + return NULL; + switch (mr->search_type) { + case attr_town_postal: + case attr_town_name: + case attr_district_name: + ret=town_search_get_item(mr); + break; + case attr_street_name: + ret=street_search_get_item(mr); + break; + case attr_house_number: + ret=housenumber_search_get_item(mr); + break; + default: + dbg(lvl_error,"unknown search %s",attr_to_name(mr->search_type)); + break; + } + if (!ret && mr->search_type_next != attr_none) { + mr->search_type=mr->search_type_next; + mr->search_type_next=attr_none; + map_search_cleanup(mr); + map_search_setup(mr); + return map_search_get_item_mg(ms); + } + return ret; } static struct map_methods map_methods_mg = { - projection_mg, - "iso8859-1", - map_destroy_mg, - map_rect_new_mg, - map_rect_destroy_mg, - map_rect_get_item_mg, - map_rect_get_item_byid_mg, - map_search_new_mg, - map_search_destroy_mg, - map_search_get_item_mg, + projection_mg, + "iso8859-1", + map_destroy_mg, + map_rect_new_mg, + map_rect_destroy_mg, + map_rect_get_item_mg, + map_rect_get_item_byid_mg, + map_search_new_mg, + map_search_destroy_mg, + map_search_get_item_mg, }; struct map_priv * -map_new_mg(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) -{ - struct map_priv *m; - int i,maybe_missing; - struct attr *data=attr_search(attrs, NULL, attr_data); - char *filename; - struct file_wordexp *wexp; - char **wexp_data; - - if (! data) - return NULL; - - wexp=file_wordexp_new(data->u.str); - wexp_data=file_wordexp_get_array(wexp); - - *meth=map_methods_mg; - data=attr_search(attrs, NULL, attr_data); - - m=g_new(struct map_priv, 1); - m->id=++map_id; - m->dirname=g_strdup(wexp_data[0]); - file_wordexp_destroy(wexp); - for (i = 0 ; i < file_end ; i++) { - if (file[i]) { - filename=g_strdup_printf("%s/%s", m->dirname, file[i]); - m->file[i]=file_create_caseinsensitive(filename, 0); - if (! m->file[i]) { - maybe_missing=(i == file_border_ply || i == file_height_ply || i == file_sea_ply); - if (! maybe_missing) - dbg(lvl_error,"Failed to load %s", filename); - } else - file_mmap(m->file[i]); - g_free(filename); - } - } - maps=g_list_append(maps, m); - - return m; +map_new_mg(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) { + struct map_priv *m; + int i,maybe_missing; + struct attr *data=attr_search(attrs, NULL, attr_data); + char *filename; + struct file_wordexp *wexp; + char **wexp_data; + + if (! data) + return NULL; + + wexp=file_wordexp_new(data->u.str); + wexp_data=file_wordexp_get_array(wexp); + + *meth=map_methods_mg; + data=attr_search(attrs, NULL, attr_data); + + m=g_new(struct map_priv, 1); + m->id=++map_id; + m->dirname=g_strdup(wexp_data[0]); + file_wordexp_destroy(wexp); + for (i = 0 ; i < file_end ; i++) { + if (file[i]) { + filename=g_strdup_printf("%s/%s", m->dirname, file[i]); + m->file[i]=file_create_caseinsensitive(filename, 0); + if (! m->file[i]) { + maybe_missing=(i == file_border_ply || i == file_height_ply || i == file_sea_ply); + if (! maybe_missing) + dbg(lvl_error,"Failed to load %s", filename); + } else + file_mmap(m->file[i]); + g_free(filename); + } + } + maps=g_list_append(maps, m); + + return m; } void -plugin_init(void) -{ - plugin_register_category_map("mg", map_new_mg); +plugin_init(void) { + plugin_register_category_map("mg", map_new_mg); } diff --git a/navit/map/mg/poly.c b/navit/map/mg/poly.c index b759301e3..786cf9ed2 100644 --- a/navit/map/mg/poly.c +++ b/navit/map/mg/poly.c @@ -22,244 +22,238 @@ #include "mg.h" static void -poly_coord_rewind(void *priv_data) -{ - struct poly_priv *poly=priv_data; +poly_coord_rewind(void *priv_data) { + struct poly_priv *poly=priv_data; - poly->p=poly->subpoly_start; + poly->p=poly->subpoly_start; } static int -poly_coord_get(void *priv_data, struct coord *c, int count) -{ - struct poly_priv *poly=priv_data; - int ret=0; +poly_coord_get(void *priv_data, struct coord *c, int count) { + struct poly_priv *poly=priv_data; + int ret=0; - while (count--) { - if (poly->p >= poly->subpoly_next) - break; - c->x=get_u32_unal(&poly->p); - c->y=get_u32_unal(&poly->p); - c++; - ret++; - } - return ret; + while (count--) { + if (poly->p >= poly->subpoly_next) + break; + c->x=get_u32_unal(&poly->p); + c->y=get_u32_unal(&poly->p); + c++; + ret++; + } + return ret; } -static void -poly_attr_rewind(void *priv_data) -{ - struct poly_priv *poly=priv_data; +static void +poly_attr_rewind(void *priv_data) { + struct poly_priv *poly=priv_data; - poly->aidx=0; + poly->aidx=0; } static int -poly_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct poly_priv *poly=priv_data; +poly_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct poly_priv *poly=priv_data; - attr->type=attr_type; - switch (attr_type) { - case attr_any: - while (poly->attr_next != attr_none) { - if (poly_attr_get(poly, poly->attr_next, attr)) - return 1; - } - return 0; - case attr_label: - attr->u.str=poly->name; - poly->attr_next=attr_none; - if (attr->u.str[0]) - return 1; - return 0; - default: - return 0; - } - return 1; + attr->type=attr_type; + switch (attr_type) { + case attr_any: + while (poly->attr_next != attr_none) { + if (poly_attr_get(poly, poly->attr_next, attr)) + return 1; + } + return 0; + case attr_label: + attr->u.str=poly->name; + poly->attr_next=attr_none; + if (attr->u.str[0]) + return 1; + return 0; + default: + return 0; + } + return 1; } static struct item_methods poly_meth = { - poly_coord_rewind, - poly_coord_get, - poly_attr_rewind, - poly_attr_get, + poly_coord_rewind, + poly_coord_get, + poly_attr_rewind, + poly_attr_get, }; static void -poly_get_data(struct poly_priv *poly, unsigned char **p) -{ - poly->c[0].x=get_u32_unal(p); - poly->c[0].y=get_u32_unal(p); - poly->c[1].x=get_u32_unal(p); - poly->c[1].y=get_u32_unal(p); - *p+=sizeof(struct coord); - poly->name=(char *)(*p); - while (**p) { - (*p)++; - } - (*p)++; - poly->order=*(*p)++; - poly->type=*(*p)++; - poly->polys=get_u32_unal(p); - poly->count=(unsigned int *)(*p); (*p)+=poly->polys*sizeof(unsigned int); - poly->count_sum=get_u32_unal(p); +poly_get_data(struct poly_priv *poly, unsigned char **p) { + poly->c[0].x=get_u32_unal(p); + poly->c[0].y=get_u32_unal(p); + poly->c[1].x=get_u32_unal(p); + poly->c[1].y=get_u32_unal(p); + *p+=sizeof(struct coord); + poly->name=(char *)(*p); + while (**p) { + (*p)++; + } + (*p)++; + poly->order=*(*p)++; + poly->type=*(*p)++; + poly->polys=get_u32_unal(p); + poly->count=(unsigned int *)(*p); + (*p)+=poly->polys*sizeof(unsigned int); + poly->count_sum=get_u32_unal(p); } int -poly_get(struct map_rect_priv *mr, struct poly_priv *poly, struct item *item) -{ - struct coord_rect r; +poly_get(struct map_rect_priv *mr, struct poly_priv *poly, struct item *item) { + struct coord_rect r; - for (;;) { - if (mr->b.p >= mr->b.end) - return 0; - if (mr->b.p == mr->b.p_start) { - poly->poly_num=0; - poly->subpoly_num=0; - poly->subpoly_num_all=0; - poly->poly_next=mr->b.p; - item->meth=&poly_meth; - } - if (poly->poly_num >= block_get_count(mr->b.b)) - return 0; - if (!poly->subpoly_num) { - mr->b.p=poly->poly_next; - item->id_lo=mr->b.p-mr->file->begin; - poly_get_data(poly, &mr->b.p); - poly->poly_next=mr->b.p+poly->count_sum*sizeof(struct coord); - poly->poly_num++; - r.lu=poly->c[0]; - r.rl=poly->c[1]; - if (mr->cur_sel && (poly->order > mr->cur_sel->order*3 || !coord_rect_overlap(&mr->cur_sel->u.c_rect, &r))) { - poly->subpoly_num_all+=poly->polys; - mr->b.p=poly->poly_next; - continue; - } - switch(poly->type) { - case 0x13: - item->type=type_poly_wood; - break; - case 0x14: - item->type=type_poly_town; - break; - case 0x15: - item->type=type_poly_cemetery; - break; - case 0x16: - item->type=type_poly_building; - break; - case 0x17: - item->type=type_poly_museum; - break; - case 0x19: - item->type=type_poly_place; - break; - case 0x1b: - item->type=type_poly_commercial_center; - break; - case 0x1e: - item->type=type_poly_industry; - break; - case 0x23: - /* FIXME: what is this ?*/ - item->type=type_poly_place; - break; - case 0x24: - item->type=type_poly_car_parking; - break; - case 0x28: - item->type=type_poly_airport; - break; - case 0x29: - item->type=type_poly_station; - break; - case 0x2d: - item->type=type_poly_hospital; - break; - case 0x2e: - item->type=type_poly_hospital; - break; - case 0x2f: - item->type=type_poly_university; - break; - case 0x30: - item->type=type_poly_university; - break; - case 0x32: - item->type=type_poly_park; - break; - case 0x34: - item->type=type_poly_sport; - break; - case 0x35: - item->type=type_poly_sport; - break; - case 0x37: - item->type=type_poly_golf_course; - break; - case 0x38: - item->type=type_poly_national_park; - break; - case 0x39: - item->type=type_poly_nature_park; - break; - case 0x3c: - item->type=type_poly_water; - break; - case 0xbc: - item->type=type_water_line; - break; - case 0xc3: - /* FIXME: what is this ?*/ - item->type=type_border_state; - break; - case 0xc6: - item->type=type_border_country; - break; - case 0xc7: - item->type=type_border_state; - break; - case 0xd0: - item->type=type_rail; - break; - default: - dbg(lvl_error,"Unknown poly type 0x%x '%s' 0x%x,0x%x", poly->type,poly->name,r.lu.x,r.lu.y); - item->type=type_street_unkn; - } - if (!map_selection_contains_item(mr->cur_sel, 0, item->type)) { - poly->subpoly_num_all+=poly->polys; - mr->b.p=poly->poly_next; - continue; - } - } else - mr->b.p=poly->subpoly_next; - dbg(lvl_debug,"%d %d %s", poly->subpoly_num_all, mr->b.block_num, poly->name); - item->id_lo=poly->subpoly_num_all | (mr->b.block_num << 16); - item->id_hi=(mr->current_file << 16); - dbg(lvl_debug,"0x%x 0x%x", item->id_lo, item->id_hi); - poly->subpoly_next=mr->b.p+L(poly->count[poly->subpoly_num])*sizeof(struct coord); - poly->subpoly_num++; - poly->subpoly_num_all++; - if (poly->subpoly_num >= poly->polys) - poly->subpoly_num=0; - poly->subpoly_start=poly->p=mr->b.p; - item->priv_data=poly; - poly->attr_next=attr_label; - return 1; + for (;;) { + if (mr->b.p >= mr->b.end) + return 0; + if (mr->b.p == mr->b.p_start) { + poly->poly_num=0; + poly->subpoly_num=0; + poly->subpoly_num_all=0; + poly->poly_next=mr->b.p; + item->meth=&poly_meth; } + if (poly->poly_num >= block_get_count(mr->b.b)) + return 0; + if (!poly->subpoly_num) { + mr->b.p=poly->poly_next; + item->id_lo=mr->b.p-mr->file->begin; + poly_get_data(poly, &mr->b.p); + poly->poly_next=mr->b.p+poly->count_sum*sizeof(struct coord); + poly->poly_num++; + r.lu=poly->c[0]; + r.rl=poly->c[1]; + if (mr->cur_sel && (poly->order > mr->cur_sel->order*3 || !coord_rect_overlap(&mr->cur_sel->u.c_rect, &r))) { + poly->subpoly_num_all+=poly->polys; + mr->b.p=poly->poly_next; + continue; + } + switch(poly->type) { + case 0x13: + item->type=type_poly_wood; + break; + case 0x14: + item->type=type_poly_town; + break; + case 0x15: + item->type=type_poly_cemetery; + break; + case 0x16: + item->type=type_poly_building; + break; + case 0x17: + item->type=type_poly_museum; + break; + case 0x19: + item->type=type_poly_place; + break; + case 0x1b: + item->type=type_poly_commercial_center; + break; + case 0x1e: + item->type=type_poly_industry; + break; + case 0x23: + /* FIXME: what is this ?*/ + item->type=type_poly_place; + break; + case 0x24: + item->type=type_poly_car_parking; + break; + case 0x28: + item->type=type_poly_airport; + break; + case 0x29: + item->type=type_poly_station; + break; + case 0x2d: + item->type=type_poly_hospital; + break; + case 0x2e: + item->type=type_poly_hospital; + break; + case 0x2f: + item->type=type_poly_university; + break; + case 0x30: + item->type=type_poly_university; + break; + case 0x32: + item->type=type_poly_park; + break; + case 0x34: + item->type=type_poly_sport; + break; + case 0x35: + item->type=type_poly_sport; + break; + case 0x37: + item->type=type_poly_golf_course; + break; + case 0x38: + item->type=type_poly_national_park; + break; + case 0x39: + item->type=type_poly_nature_park; + break; + case 0x3c: + item->type=type_poly_water; + break; + case 0xbc: + item->type=type_water_line; + break; + case 0xc3: + /* FIXME: what is this ?*/ + item->type=type_border_state; + break; + case 0xc6: + item->type=type_border_country; + break; + case 0xc7: + item->type=type_border_state; + break; + case 0xd0: + item->type=type_rail; + break; + default: + dbg(lvl_error,"Unknown poly type 0x%x '%s' 0x%x,0x%x", poly->type,poly->name,r.lu.x,r.lu.y); + item->type=type_street_unkn; + } + if (!map_selection_contains_item(mr->cur_sel, 0, item->type)) { + poly->subpoly_num_all+=poly->polys; + mr->b.p=poly->poly_next; + continue; + } + } else + mr->b.p=poly->subpoly_next; + dbg(lvl_debug,"%d %d %s", poly->subpoly_num_all, mr->b.block_num, poly->name); + item->id_lo=poly->subpoly_num_all | (mr->b.block_num << 16); + item->id_hi=(mr->current_file << 16); + dbg(lvl_debug,"0x%x 0x%x", item->id_lo, item->id_hi); + poly->subpoly_next=mr->b.p+L(poly->count[poly->subpoly_num])*sizeof(struct coord); + poly->subpoly_num++; + poly->subpoly_num_all++; + if (poly->subpoly_num >= poly->polys) + poly->subpoly_num=0; + poly->subpoly_start=poly->p=mr->b.p; + item->priv_data=poly; + poly->attr_next=attr_label; + return 1; + } } int -poly_get_byid(struct map_rect_priv *mr, struct poly_priv *poly, int id_hi, int id_lo, struct item *item) -{ - int count=id_lo & 0xffff; - int ret=0; - block_get_byindex(mr->m->file[mr->current_file], id_lo >> 16, &mr->b); - while (count-- >= 0) { - ret=poly_get(mr, poly, item); - } - return ret; +poly_get_byid(struct map_rect_priv *mr, struct poly_priv *poly, int id_hi, int id_lo, struct item *item) { + int count=id_lo & 0xffff; + int ret=0; + block_get_byindex(mr->m->file[mr->current_file], id_lo >> 16, &mr->b); + while (count-- >= 0) { + ret=poly_get(mr, poly, item); + } + return ret; } diff --git a/navit/map/mg/street.c b/navit/map/mg/street.c index cffd599ae..c997b9f83 100644 --- a/navit/map/mg/street.c +++ b/navit/map/mg/street.c @@ -31,735 +31,715 @@ static void street_name_numbers_get(struct street_name_numbers *name_numbers, un static void street_name_number_get(struct street_name_number *name_number, unsigned char **p); static void -street_name_debug(struct street_name *sn, FILE *out) -{ - struct street_name_numbers nns; - unsigned char *p=sn->aux_data; - unsigned char *end=p+sn->aux_len; - int i; - - while (p < end) { - unsigned char *pn,*pn_end; - struct street_name_number nn; - street_name_numbers_get(&nns, &p); - fprintf(out,"0x%x 0x%x type=town_label label=\"%s(%d):0x%x:%d%s-%d%s\" debug=\"len=0x%x\"",nns.c->x,nns.c->y,sn->name2, sn->segment_count, nns.tag, nns.first.number,nns.first.suffix,nns.last.number,nns.last.suffix,nns.len); - for (i = 0 ; i < sn->segment_count ; i++) { - fprintf(out," debug=\"segment(%d)=0x%x\"",i,sn->segments[i].segid); - } - fprintf(out,"\n"); - pn=nns.aux_data; - pn_end=nns.aux_data+nns.aux_len; - while (pn < pn_end) { - street_name_number_get(&nn, &pn); - fprintf(out,"0x%x 0x%x type=town_label label=\"%s:0x%x:%d%s-%d%s\" debug=\"len=0x%x\"\n", nn.c->x, nn.c->y, sn->name2, nn.tag, nn.first.number, nn.first.suffix, nn.last.number,nn.last.suffix,nn.len); - } - } - fflush(out); +street_name_debug(struct street_name *sn, FILE *out) { + struct street_name_numbers nns; + unsigned char *p=sn->aux_data; + unsigned char *end=p+sn->aux_len; + int i; + + while (p < end) { + unsigned char *pn,*pn_end; + struct street_name_number nn; + street_name_numbers_get(&nns, &p); + fprintf(out,"0x%x 0x%x type=town_label label=\"%s(%d):0x%x:%d%s-%d%s\" debug=\"len=0x%x\"",nns.c->x,nns.c->y,sn->name2, + sn->segment_count, nns.tag, nns.first.number,nns.first.suffix,nns.last.number,nns.last.suffix,nns.len); + for (i = 0 ; i < sn->segment_count ; i++) { + fprintf(out," debug=\"segment(%d)=0x%x\"",i,sn->segments[i].segid); + } + fprintf(out,"\n"); + pn=nns.aux_data; + pn_end=nns.aux_data+nns.aux_len; + while (pn < pn_end) { + street_name_number_get(&nn, &pn); + fprintf(out,"0x%x 0x%x type=town_label label=\"%s:0x%x:%d%s-%d%s\" debug=\"len=0x%x\"\n", nn.c->x, nn.c->y, sn->name2, + nn.tag, nn.first.number, nn.first.suffix, nn.last.number,nn.last.suffix,nn.len); + } + } + fflush(out); } #endif static void -street_name_get(struct street_name *name, unsigned char **p) -{ - unsigned char *start=*p; - name->len=get_u16_unal(p); - name->country=get_u16_unal(p); - name->townassoc=get_u32_unal(p); - name->name1=get_string(p); - name->name2=get_string(p); - name->segment_count=get_u32_unal(p); - name->segments=(struct street_name_segment *)(*p); - (*p)+=(sizeof (struct street_name_segment))*name->segment_count; - name->aux_len=name->len-(*p-start); - name->aux_data=*p; - name->tmp_len=name->aux_len; - name->tmp_data=name->aux_data; - *p=start+name->len; +street_name_get(struct street_name *name, unsigned char **p) { + unsigned char *start=*p; + name->len=get_u16_unal(p); + name->country=get_u16_unal(p); + name->townassoc=get_u32_unal(p); + name->name1=get_string(p); + name->name2=get_string(p); + name->segment_count=get_u32_unal(p); + name->segments=(struct street_name_segment *)(*p); + (*p)+=(sizeof (struct street_name_segment))*name->segment_count; + name->aux_len=name->len-(*p-start); + name->aux_data=*p; + name->tmp_len=name->aux_len; + name->tmp_data=name->aux_data; + *p=start+name->len; } static int -street_name_eod(struct street_name *name) -{ - return (name->tmp_data >= name->aux_data+name->aux_len); +street_name_eod(struct street_name *name) { + return (name->tmp_data >= name->aux_data+name->aux_len); } static void -street_name_numbers_get(struct street_name_numbers *name_numbers, unsigned char **p) -{ - unsigned char *start=*p; - name_numbers->len=get_u16_unal(p); - name_numbers->tag=get_u8(p); - name_numbers->dist=get_u32_unal(p); - name_numbers->country=get_u32_unal(p); - name_numbers->c=coord_get(p); - name_numbers->first.number=get_u16_unal(p); - name_numbers->first.suffix=get_string(p); - name_numbers->last.number=get_u16_unal(p); - name_numbers->last.suffix=get_string(p); - name_numbers->segment_count=get_u32_unal(p); - name_numbers->segments=(struct street_name_segment *)(*p); - (*p)+=sizeof(struct street_name_segment)*name_numbers->segment_count; - name_numbers->aux_len=name_numbers->len-(*p-start); - name_numbers->aux_data=*p; - name_numbers->tmp_len=name_numbers->aux_len; - name_numbers->tmp_data=name_numbers->aux_data; - *p=start+name_numbers->len; +street_name_numbers_get(struct street_name_numbers *name_numbers, unsigned char **p) { + unsigned char *start=*p; + name_numbers->len=get_u16_unal(p); + name_numbers->tag=get_u8(p); + name_numbers->dist=get_u32_unal(p); + name_numbers->country=get_u32_unal(p); + name_numbers->c=coord_get(p); + name_numbers->first.number=get_u16_unal(p); + name_numbers->first.suffix=get_string(p); + name_numbers->last.number=get_u16_unal(p); + name_numbers->last.suffix=get_string(p); + name_numbers->segment_count=get_u32_unal(p); + name_numbers->segments=(struct street_name_segment *)(*p); + (*p)+=sizeof(struct street_name_segment)*name_numbers->segment_count; + name_numbers->aux_len=name_numbers->len-(*p-start); + name_numbers->aux_data=*p; + name_numbers->tmp_len=name_numbers->aux_len; + name_numbers->tmp_data=name_numbers->aux_data; + *p=start+name_numbers->len; } static int -street_name_numbers_eod(struct street_name_numbers *name_numbers) -{ - return (name_numbers->tmp_data >= name_numbers->aux_data+name_numbers->aux_len); +street_name_numbers_eod(struct street_name_numbers *name_numbers) { + return (name_numbers->tmp_data >= name_numbers->aux_data+name_numbers->aux_len); } static void -street_name_number_get(struct street_name_number *name_number, unsigned char **p) -{ - unsigned char *start=*p; - name_number->len=get_u16_unal(p); - name_number->tag=get_u8(p); - name_number->c=coord_get(p); - name_number->first.number=get_u16_unal(p); - name_number->first.suffix=get_string(p); - name_number->last.number=get_u16_unal(p); - name_number->last.suffix=get_string(p); - name_number->segment=(struct street_name_segment *)p; - *p=start+name_number->len; +street_name_number_get(struct street_name_number *name_number, unsigned char **p) { + unsigned char *start=*p; + name_number->len=get_u16_unal(p); + name_number->tag=get_u8(p); + name_number->c=coord_get(p); + name_number->first.number=get_u16_unal(p); + name_number->first.suffix=get_string(p); + name_number->last.number=get_u16_unal(p); + name_number->last.suffix=get_string(p); + name_number->segment=(struct street_name_segment *)p; + *p=start+name_number->len; } static void -street_name_get_by_id(struct street_name *name, struct file *file, unsigned long id) -{ - unsigned char *p; - if (id) { - p=file->begin+id+0x2000; - street_name_get(name, &p); - } -} - -static int street_get_bytes(struct coord_rect *r) -{ - int bytes,dx,dy; - bytes=2; - dx=r->rl.x-r->lu.x; - dy=r->lu.y-r->rl.y; - dbg_assert(dx > 0); - dbg_assert(dy > 0); - if (dx > 32767 || dy > 32767) - bytes=3; - if (dx > 8388608 || dy > 8388608) - bytes=4; - - return bytes; -} - -static int street_get_coord(unsigned char **pos, int bytes, struct coord_rect *ref, struct coord *f) -{ - unsigned char *p; - int x,y,flags=0; - - p=*pos; - x=*p++; - x|=(*p++) << 8; - if (bytes == 2) { - if ( x > 0x7fff) { - x=0x10000-x; - flags=1; - } - } - else if (bytes == 3) { - x|=(*p++) << 16; - if ( x > 0x7fffff) { - x=0x1000000-x; - flags=1; - } - } else { - x|=(*p++) << 16; - x|=(*p++) << 24; - if (x < 0) { - x=-x; - flags=1; - } - } - y=*p++; - y|=(*p++) << 8; - if (bytes == 3) { - y|=(*p++) << 16; - } else if (bytes == 4) { - y|=(*p++) << 16; - y|=(*p++) << 24; - } - if (f) { - f->x=ref->lu.x+x; - f->y=ref->rl.y+y; - dbg(lvl_debug,"0x%x,0x%x + 0x%x,0x%x = 0x%x,0x%x", x, y, ref->lu.x, ref->rl.y, f->x, f->y); - } - *pos=p; - return flags; +street_name_get_by_id(struct street_name *name, struct file *file, unsigned long id) { + unsigned char *p; + if (id) { + p=file->begin+id+0x2000; + street_name_get(name, &p); + } +} + +static int street_get_bytes(struct coord_rect *r) { + int bytes,dx,dy; + bytes=2; + dx=r->rl.x-r->lu.x; + dy=r->lu.y-r->rl.y; + dbg_assert(dx > 0); + dbg_assert(dy > 0); + if (dx > 32767 || dy > 32767) + bytes=3; + if (dx > 8388608 || dy > 8388608) + bytes=4; + + return bytes; +} + +static int street_get_coord(unsigned char **pos, int bytes, struct coord_rect *ref, struct coord *f) { + unsigned char *p; + int x,y,flags=0; + + p=*pos; + x=*p++; + x|=(*p++) << 8; + if (bytes == 2) { + if ( x > 0x7fff) { + x=0x10000-x; + flags=1; + } + } else if (bytes == 3) { + x|=(*p++) << 16; + if ( x > 0x7fffff) { + x=0x1000000-x; + flags=1; + } + } else { + x|=(*p++) << 16; + x|=(*p++) << 24; + if (x < 0) { + x=-x; + flags=1; + } + } + y=*p++; + y|=(*p++) << 8; + if (bytes == 3) { + y|=(*p++) << 16; + } else if (bytes == 4) { + y|=(*p++) << 16; + y|=(*p++) << 24; + } + if (f) { + f->x=ref->lu.x+x; + f->y=ref->rl.y+y; + dbg(lvl_debug,"0x%x,0x%x + 0x%x,0x%x = 0x%x,0x%x", x, y, ref->lu.x, ref->rl.y, f->x, f->y); + } + *pos=p; + return flags; } static void -street_coord_get_begin(unsigned char **p) -{ - struct street_str *str; - - str=(struct street_str *)(*p); - while (street_str_get_segid(str)) { - str++; - } - (*p)=(unsigned char *)str; - (*p)+=4; +street_coord_get_begin(unsigned char **p) { + struct street_str *str; + + str=(struct street_str *)(*p); + while (street_str_get_segid(str)) { + str++; + } + (*p)=(unsigned char *)str; + (*p)+=4; } static void -street_coord_rewind(void *priv_data) -{ - struct street_priv *street=priv_data; +street_coord_rewind(void *priv_data) { + struct street_priv *street=priv_data; - street->p=street->next=NULL; - street->status=street->status_rewind; + street->p=street->next=NULL; + street->status=street->status_rewind; } static int -street_coord_get_helper(struct street_priv *street, struct coord *c) -{ - unsigned char *n; - if (street->p+street->bytes*2 >= street->end) - return 0; - if (street->status >= 4) - return 0; - n=street->p; - if (street_get_coord(&street->p, street->bytes, &street->ref, c)) { - if (street->status) - street->next=n; - street->status+=2; - if (street->status == 5) - return 0; - } - return 1; +street_coord_get_helper(struct street_priv *street, struct coord *c) { + unsigned char *n; + if (street->p+street->bytes*2 >= street->end) + return 0; + if (street->status >= 4) + return 0; + n=street->p; + if (street_get_coord(&street->p, street->bytes, &street->ref, c)) { + if (street->status) + street->next=n; + street->status+=2; + if (street->status == 5) + return 0; + } + return 1; } static int -street_coord_get(void *priv_data, struct coord *c, int count) -{ - struct street_priv *street=priv_data; - int ret=0,i,scount; +street_coord_get(void *priv_data, struct coord *c, int count) { + struct street_priv *street=priv_data; + int ret=0,i,scount; #ifdef DEBUG_COORD_GET - int segid,debug=0; + int segid,debug=0; #endif - if (! street->p && count) { - street->p=street->coord_begin; - scount=street->str-street->str_start; - for (i = 0 ; i < scount ; i++) { - street->status=street_str_get_segid(&street->str[i+1]) >= 0 ? 0:1; - while (street_coord_get_helper(street, c)); - street->p=street->next; - } - street->status_rewind=street->status=street_str_get_segid(&street->str[1]) >= 0 ? 0:1; - } + if (! street->p && count) { + street->p=street->coord_begin; + scount=street->str-street->str_start; + for (i = 0 ; i < scount ; i++) { + street->status=street_str_get_segid(&street->str[i+1]) >= 0 ? 0:1; + while (street_coord_get_helper(street, c)); + street->p=street->next; + } + street->status_rewind=street->status=street_str_get_segid(&street->str[1]) >= 0 ? 0:1; + } #ifdef DEBUG_COORD_GET - segid=street_str_get_segid(&street->str[0]); - if (segid < 0) - segid=-segid; - if (segid == 0x15) - debug=1; - if (debug) { - dbg(lvl_debug,"enter 0x%x",segid); - } + segid=street_str_get_segid(&street->str[0]); + if (segid < 0) + segid=-segid; + if (segid == 0x15) + debug=1; + if (debug) { + dbg(lvl_debug,"enter 0x%x",segid); + } #endif - while (count > 0) { - if (street_coord_get_helper(street, c)) { + while (count > 0) { + if (street_coord_get_helper(street, c)) { #ifdef DEBUG_COORD_GET - if (debug) { - dbg(lvl_debug,"0x%x,0x%x", c->x, c->y); - } + if (debug) { + dbg(lvl_debug,"0x%x,0x%x", c->x, c->y); + } #endif - c++; - ret++; - count--; - } else { - street->more=0; - return ret; - } - } - return ret; + c++; + ret++; + count--; + } else { + street->more=0; + return ret; + } + } + return ret; } - static void -street_attr_rewind(void *priv_data) -{ - /* struct street_priv *street=priv_data; */ +static void +street_attr_rewind(void *priv_data) { + /* struct street_priv *street=priv_data; */ } static int -street_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct street_priv *street=priv_data; - int nameid; - - dbg(lvl_debug,"segid 0x%x", street_str_get_segid(street->str)); - attr->type=attr_type; - switch (attr_type) { - case attr_any: - while (street->attr_next != attr_none) { - if (street_attr_get(street, street->attr_next, attr)) - return 1; - } - return 0; - case attr_label: - street->attr_next=attr_street_name; - nameid=street_str_get_nameid(street->str); - if (! nameid) - return 0; - if (! street->name.len) - street_name_get_by_id(&street->name,street->name_file,nameid); - attr->u.str=street->name.name2; - if (attr->u.str && attr->u.str[0]) - return 1; - attr->u.str=street->name.name1; - if (attr->u.str && attr->u.str[0]) - return 1; - return 0; - case attr_street_name: - street->attr_next=attr_street_name_systematic; - nameid=street_str_get_nameid(street->str); - if (! nameid) - return 0; - if (! street->name.len) - street_name_get_by_id(&street->name,street->name_file,nameid); - attr->u.str=street->name.name2; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_street_name_systematic: - street->attr_next=attr_flags; - nameid=street_str_get_nameid(street->str); - if (! nameid) - return 0; - if (! street->name.len) - street_name_get_by_id(&street->name,street->name_file,nameid); - attr->u.str=street->name.name1; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_flags: - attr->u.num=street->flags; - street->attr_next=attr_country_id; - return 1; - case attr_country_id: - street->attr_next=attr_debug; - nameid=street_str_get_nameid(street->str); - if (! nameid) - return 0; - if (! street->name.len) - street_name_get_by_id(&street->name,street->name_file,nameid); - attr->u.num=mg_country_to_isonum(street->name.country); - return 1; - case attr_debug: - street->attr_next=attr_none; - { - struct street_str *str=street->str; - sprintf(street->debug,"order:0x%x\nsegid:0x%x\nlimit:0x%x\nunknown2:0x%x\nunknown3:0x%x\ntype:0x%x\nnameid:0x%x\ntownassoc:0x%x",street_header_get_order(street->header),street_str_get_segid(str),street_str_get_limit(str),street_str_get_unknown2(str),street_str_get_unknown3(str),street_str_get_type(str),street_str_get_nameid(str), street->name.len ? street->name.townassoc : 0); - attr->u.str=street->debug; - } - return 1; - default: - return 0; - } - return 1; +street_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct street_priv *street=priv_data; + int nameid; + + dbg(lvl_debug,"segid 0x%x", street_str_get_segid(street->str)); + attr->type=attr_type; + switch (attr_type) { + case attr_any: + while (street->attr_next != attr_none) { + if (street_attr_get(street, street->attr_next, attr)) + return 1; + } + return 0; + case attr_label: + street->attr_next=attr_street_name; + nameid=street_str_get_nameid(street->str); + if (! nameid) + return 0; + if (! street->name.len) + street_name_get_by_id(&street->name,street->name_file,nameid); + attr->u.str=street->name.name2; + if (attr->u.str && attr->u.str[0]) + return 1; + attr->u.str=street->name.name1; + if (attr->u.str && attr->u.str[0]) + return 1; + return 0; + case attr_street_name: + street->attr_next=attr_street_name_systematic; + nameid=street_str_get_nameid(street->str); + if (! nameid) + return 0; + if (! street->name.len) + street_name_get_by_id(&street->name,street->name_file,nameid); + attr->u.str=street->name.name2; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_street_name_systematic: + street->attr_next=attr_flags; + nameid=street_str_get_nameid(street->str); + if (! nameid) + return 0; + if (! street->name.len) + street_name_get_by_id(&street->name,street->name_file,nameid); + attr->u.str=street->name.name1; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_flags: + attr->u.num=street->flags; + street->attr_next=attr_country_id; + return 1; + case attr_country_id: + street->attr_next=attr_debug; + nameid=street_str_get_nameid(street->str); + if (! nameid) + return 0; + if (! street->name.len) + street_name_get_by_id(&street->name,street->name_file,nameid); + attr->u.num=mg_country_to_isonum(street->name.country); + return 1; + case attr_debug: + street->attr_next=attr_none; + { + struct street_str *str=street->str; + sprintf(street->debug, + "order:0x%x\nsegid:0x%x\nlimit:0x%x\nunknown2:0x%x\nunknown3:0x%x\ntype:0x%x\nnameid:0x%x\ntownassoc:0x%x", + street_header_get_order(street->header),street_str_get_segid(str),street_str_get_limit(str), + street_str_get_unknown2(str),street_str_get_unknown3(str),street_str_get_type(str),street_str_get_nameid(str), + street->name.len ? street->name.townassoc : 0); + attr->u.str=street->debug; + } + return 1; + default: + return 0; + } + return 1; } static struct item_methods street_meth = { - street_coord_rewind, - street_coord_get, - street_attr_rewind, - street_attr_get, + street_coord_rewind, + street_coord_get, + street_attr_rewind, + street_attr_get, }; static void -street_get_data(struct street_priv *street, unsigned char **p) -{ - street->header=(struct street_header *)(*p); - (*p)+=sizeof(struct street_header); - street->type_count=street_header_get_count(street->header); - street->type=(struct street_type *)(*p); - (*p)+=street->type_count*sizeof(struct street_type); +street_get_data(struct street_priv *street, unsigned char **p) { + street->header=(struct street_header *)(*p); + (*p)+=sizeof(struct street_header); + street->type_count=street_header_get_count(street->header); + street->type=(struct street_type *)(*p); + (*p)+=street->type_count*sizeof(struct street_type); } - /*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 */ -static unsigned char limit[]={0,0,1,1,1,2,2,4,6,6,12,13,14,20,20,20,20,20,20}; +/*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 */ +static unsigned char limit[]= {0,0,1,1,1,2,2,4,6,6,12,13,14,20,20,20,20,20,20}; int -street_get(struct map_rect_priv *mr, struct street_priv *street, struct item *item) -{ - int *flags; - struct coord_rect r; - for (;;) { - while (street->more) { - struct coord c; - street_coord_get(street, &c, 1); - } - if (mr->b.p == mr->b.p_start) { - street_get_data(street, &mr->b.p); - street->name_file=mr->m->file[file_strname_stn]; - if (mr->cur_sel && street_header_get_order(street->header) > limit[mr->cur_sel->order]) - return 0; - street->end=mr->b.end; - block_get_r(mr->b.b, &r); - street->ref=r; - street->bytes=street_get_bytes(&r); - street->str_start=street->str=(struct street_str *)mr->b.p; - street->coord_begin=mr->b.p; - street_coord_get_begin(&street->coord_begin); - street->p=street->coord_begin; - street->type--; - item->meth=&street_meth; - item->priv_data=street; - } else { - street->str++; - street->p=street->next; - } - if (! street_str_get_segid(street->str)) - return 0; - if (street_str_get_segid(street->str) < 0) - street->type++; - street->next=NULL; - street->status_rewind=street->status=street_str_get_segid(&street->str[1]) >= 0 ? 0:1; - item->id_hi=street_type_get_country(street->type) | (mr->current_file << 16); - item->id_lo=street_str_get_segid(street->str) > 0 ? street_str_get_segid(street->str) : -street_str_get_segid(street->str); - switch(street_str_get_type(street->str) & 0x1f) { - case 0xf: /* very small street */ - if (street_str_get_limit(street->str) == 0x33) - item->type=type_street_nopass; - else - item->type=type_street_0; - break; - case 0xd: - item->type=type_ferry; - break; - case 0xc: /* small street */ - item->type=type_street_1_city; - break; - case 0xb: - item->type=type_street_2_city; - break; - case 0xa: - if ((street_str_get_limit(street->str) == 0x03 || street_str_get_limit(street->str) == 0x30) && street_header_get_order(street->header) < 4) - item->type=type_street_4_city; - else - item->type=type_street_3_city; - break; - case 0x9: - if (street_header_get_order(street->header) < 5) - item->type=type_street_4_city; - else if (street_header_get_order(street->header) < 7) - item->type=type_street_2_city; - else - item->type=type_street_1_city; - break; - case 0x8: - item->type=type_street_2_land; - break; - case 0x7: - if ((street_str_get_limit(street->str) == 0x03 || street_str_get_limit(street->str) == 0x30) && street_header_get_order(street->header) < 4) - item->type=type_street_4_city; - else - item->type=type_street_3_land; - break; - case 0x6: - item->type=type_ramp; - break; - case 0x5: - item->type=type_street_4_land; - break; - case 0x4: - item->type=type_street_4_land; - break; - case 0x3: - item->type=type_street_n_lanes; - break; - case 0x2: - item->type=type_highway_city; - break; - case 0x1: - item->type=type_highway_land; - break; - default: - item->type=type_street_unkn; - dbg(lvl_error,"unknown type 0x%x",street_str_get_type(street->str)); - } - flags=item_get_default_flags(item->type); - if (flags) - street->flags=*flags; - else - street->flags=0; - if (street_str_get_type(street->str) & 0x40) { - street->flags|=(street_str_get_limit(street->str) & 0x30) ? AF_ONEWAYREV:0; - street->flags|=(street_str_get_limit(street->str) & 0x03) ? AF_ONEWAY:0; - } else { - street->flags|=(street_str_get_limit(street->str) & 0x30) ? AF_ONEWAY:0; - street->flags|=(street_str_get_limit(street->str) & 0x03) ? AF_ONEWAYREV:0; - } - street->p_rewind=street->p; - street->name.len=0; - street->attr_next=attr_label; - street->more=1; - street->housenumber=1; - street->hn_count=0; - if (!map_selection_contains_item(mr->cur_sel, 0, item->type)) - continue; - item->meth=&street_meth; - item->priv_data=street; - return 1; - } +street_get(struct map_rect_priv *mr, struct street_priv *street, struct item *item) { + int *flags; + struct coord_rect r; + for (;;) { + while (street->more) { + struct coord c; + street_coord_get(street, &c, 1); + } + if (mr->b.p == mr->b.p_start) { + street_get_data(street, &mr->b.p); + street->name_file=mr->m->file[file_strname_stn]; + if (mr->cur_sel && street_header_get_order(street->header) > limit[mr->cur_sel->order]) + return 0; + street->end=mr->b.end; + block_get_r(mr->b.b, &r); + street->ref=r; + street->bytes=street_get_bytes(&r); + street->str_start=street->str=(struct street_str *)mr->b.p; + street->coord_begin=mr->b.p; + street_coord_get_begin(&street->coord_begin); + street->p=street->coord_begin; + street->type--; + item->meth=&street_meth; + item->priv_data=street; + } else { + street->str++; + street->p=street->next; + } + if (! street_str_get_segid(street->str)) + return 0; + if (street_str_get_segid(street->str) < 0) + street->type++; + street->next=NULL; + street->status_rewind=street->status=street_str_get_segid(&street->str[1]) >= 0 ? 0:1; + item->id_hi=street_type_get_country(street->type) | (mr->current_file << 16); + item->id_lo=street_str_get_segid(street->str) > 0 ? street_str_get_segid(street->str) : -street_str_get_segid( + street->str); + switch(street_str_get_type(street->str) & 0x1f) { + case 0xf: /* very small street */ + if (street_str_get_limit(street->str) == 0x33) + item->type=type_street_nopass; + else + item->type=type_street_0; + break; + case 0xd: + item->type=type_ferry; + break; + case 0xc: /* small street */ + item->type=type_street_1_city; + break; + case 0xb: + item->type=type_street_2_city; + break; + case 0xa: + if ((street_str_get_limit(street->str) == 0x03 || street_str_get_limit(street->str) == 0x30) + && street_header_get_order(street->header) < 4) + item->type=type_street_4_city; + else + item->type=type_street_3_city; + break; + case 0x9: + if (street_header_get_order(street->header) < 5) + item->type=type_street_4_city; + else if (street_header_get_order(street->header) < 7) + item->type=type_street_2_city; + else + item->type=type_street_1_city; + break; + case 0x8: + item->type=type_street_2_land; + break; + case 0x7: + if ((street_str_get_limit(street->str) == 0x03 || street_str_get_limit(street->str) == 0x30) + && street_header_get_order(street->header) < 4) + item->type=type_street_4_city; + else + item->type=type_street_3_land; + break; + case 0x6: + item->type=type_ramp; + break; + case 0x5: + item->type=type_street_4_land; + break; + case 0x4: + item->type=type_street_4_land; + break; + case 0x3: + item->type=type_street_n_lanes; + break; + case 0x2: + item->type=type_highway_city; + break; + case 0x1: + item->type=type_highway_land; + break; + default: + item->type=type_street_unkn; + dbg(lvl_error,"unknown type 0x%x",street_str_get_type(street->str)); + } + flags=item_get_default_flags(item->type); + if (flags) + street->flags=*flags; + else + street->flags=0; + if (street_str_get_type(street->str) & 0x40) { + street->flags|=(street_str_get_limit(street->str) & 0x30) ? AF_ONEWAYREV:0; + street->flags|=(street_str_get_limit(street->str) & 0x03) ? AF_ONEWAY:0; + } else { + street->flags|=(street_str_get_limit(street->str) & 0x30) ? AF_ONEWAY:0; + street->flags|=(street_str_get_limit(street->str) & 0x03) ? AF_ONEWAYREV:0; + } + street->p_rewind=street->p; + street->name.len=0; + street->attr_next=attr_label; + street->more=1; + street->housenumber=1; + street->hn_count=0; + if (!map_selection_contains_item(mr->cur_sel, 0, item->type)) + continue; + item->meth=&street_meth; + item->priv_data=street; + return 1; + } } int -street_get_byid(struct map_rect_priv *mr, struct street_priv *street, int id_hi, int id_lo, struct item *item) -{ - int country=id_hi & 0xffff; - int res; - struct coord_rect r; - dbg(lvl_debug,"enter(%p,%p,0x%x,0x%x,%p)", mr, street, id_hi, id_lo, item); - if (! country) - return 0; - if (! tree_search_hv(mr->m->dirname, "street", (id_lo >> 8) | (country << 24), id_lo & 0xff, &res)) - return 0; - dbg(lvl_debug,"res=0x%x (blk=0x%x)", res, res >> 12); - block_get_byindex(mr->m->file[mr->current_file], res >> 12, &mr->b); - street_get_data(street, &mr->b.p); - street->name_file=mr->m->file[file_strname_stn]; - street->end=mr->b.end; - block_get_r(mr->b.b, &r); - street->ref=r; - street->bytes=street_get_bytes(&r); - street->str_start=street->str=(struct street_str *)mr->b.p; - street->coord_begin=mr->b.p; - street_coord_get_begin(&street->coord_begin); - street->p=street->coord_begin; - street->type--; - item->meth=&street_meth; - item->priv_data=street; - street->str+=(res & 0xfff)-1; - dbg(lvl_debug,"segid 0x%x", street_str_get_segid(&street->str[1])); - return street_get(mr, street, item); +street_get_byid(struct map_rect_priv *mr, struct street_priv *street, int id_hi, int id_lo, struct item *item) { + int country=id_hi & 0xffff; + int res; + struct coord_rect r; + dbg(lvl_debug,"enter(%p,%p,0x%x,0x%x,%p)", mr, street, id_hi, id_lo, item); + if (! country) + return 0; + if (! tree_search_hv(mr->m->dirname, "street", (id_lo >> 8) | (country << 24), id_lo & 0xff, &res)) + return 0; + dbg(lvl_debug,"res=0x%x (blk=0x%x)", res, res >> 12); + block_get_byindex(mr->m->file[mr->current_file], res >> 12, &mr->b); + street_get_data(street, &mr->b.p); + street->name_file=mr->m->file[file_strname_stn]; + street->end=mr->b.end; + block_get_r(mr->b.b, &r); + street->ref=r; + street->bytes=street_get_bytes(&r); + street->str_start=street->str=(struct street_str *)mr->b.p; + street->coord_begin=mr->b.p; + street_coord_get_begin(&street->coord_begin); + street->p=street->coord_begin; + street->type--; + item->meth=&street_meth; + item->priv_data=street; + street->str+=(res & 0xfff)-1; + dbg(lvl_debug,"segid 0x%x", street_str_get_segid(&street->str[1])); + return street_get(mr, street, item); } struct street_name_index { - int block; - unsigned short country; - int town_assoc; - char name[0]; + int block; + unsigned short country; + int town_assoc; + char name[0]; } __attribute__((packed)); -static unsigned char -latin1_tolower(unsigned char c) -{ - if (c >= 'A' && c <= 'Z') - return c - 'A' + 'a'; - if (c == 0xc4 || c == 0xc9 || c == 0xd6 || c == 0xdc) - return c+0x20; - return c; +static unsigned char +latin1_tolower(unsigned char c) { + if (c >= 'A' && c <= 'Z') + return c - 'A' + 'a'; + if (c == 0xc4 || c == 0xc9 || c == 0xd6 || c == 0xdc) + return c+0x20; + return c; } static unsigned char -latin1_tolower_ascii(unsigned char c) -{ - unsigned char ret=latin1_tolower(c); - switch (ret) { - case 0xe4: - return 'a'; - case 0xe9: - return 'e'; - case 0xf6: - return 'o'; - case 0xfc: - return 'u'; - default: - if (ret >= 0x80) - dbg(lvl_debug,"ret=0x%x",c); - return ret; - } +latin1_tolower_ascii(unsigned char c) { + unsigned char ret=latin1_tolower(c); + switch (ret) { + case 0xe4: + return 'a'; + case 0xe9: + return 'e'; + case 0xf6: + return 'o'; + case 0xfc: + return 'u'; + default: + if (ret >= 0x80) + dbg(lvl_debug,"ret=0x%x",c); + return ret; + } } static int -strncasecmp_latin1(char *str1, char *str2, int len) -{ - int d; - while (len--) { - d=latin1_tolower((unsigned char)(*str1))-latin1_tolower((unsigned char)(*str2)); - if (d) - return d; - if (! *str1) - return 0; - str1++; - str2++; - } - return 0; +strncasecmp_latin1(char *str1, char *str2, int len) { + int d; + while (len--) { + d=latin1_tolower((unsigned char)(*str1))-latin1_tolower((unsigned char)(*str2)); + if (d) + return d; + if (! *str1) + return 0; + str1++; + str2++; + } + return 0; } static int -strncasecmp_latin1_ascii(char *str1, char *str2, int len) -{ - int d; - while (len--) { - d=latin1_tolower_ascii((unsigned char)(*str1))-latin1_tolower_ascii((unsigned char)(*str2)); - if (d) - return d; - if (! *str1) - return 0; - str1++; - str2++; - } - return 0; +strncasecmp_latin1_ascii(char *str1, char *str2, int len) { + int d; + while (len--) { + d=latin1_tolower_ascii((unsigned char)(*str1))-latin1_tolower_ascii((unsigned char)(*str2)); + if (d) + return d; + if (! *str1) + return 0; + str1++; + str2++; + } + return 0; } static int -street_search_compare_do(struct map_rect_priv *mr, int country, int town_assoc, char *name) -{ - int d,len; - - dbg(lvl_debug,"enter"); - dbg(lvl_debug,"country 0x%x town_assoc 0x%x name '%s'", country, town_assoc, name); - d=(mr->search_item.id_hi & 0xffff)-country; - dbg(lvl_debug,"country %d (%d vs %d)", d, mr->search_item.id_hi & 0xffff, country); - if (!d) { - if (mr->search_item.id_lo == town_assoc ) { - dbg(lvl_debug,"town_assoc match (0x%x)", town_assoc); - len=mr->search_partial ? strlen(mr->search_str):INT_MAX; - d=strncasecmp_latin1(mr->search_str, name, len); - if (!strncasecmp_latin1_ascii(mr->search_str, name, len)) - d=0; - dbg(lvl_debug,"string %d", d); - } else { - if (town_assoc < mr->search_item.id_lo) - d=1; - else - d=-1; - dbg(lvl_debug,"assoc %d 0x%x-0x%x",d, mr->search_item.id_lo, town_assoc); - } - } - dbg(lvl_debug,"d=%d", d); - return d; +street_search_compare_do(struct map_rect_priv *mr, int country, int town_assoc, char *name) { + int d,len; + + dbg(lvl_debug,"enter"); + dbg(lvl_debug,"country 0x%x town_assoc 0x%x name '%s'", country, town_assoc, name); + d=(mr->search_item.id_hi & 0xffff)-country; + dbg(lvl_debug,"country %d (%d vs %d)", d, mr->search_item.id_hi & 0xffff, country); + if (!d) { + if (mr->search_item.id_lo == town_assoc ) { + dbg(lvl_debug,"town_assoc match (0x%x)", town_assoc); + len=mr->search_partial ? strlen(mr->search_str):INT_MAX; + d=strncasecmp_latin1(mr->search_str, name, len); + if (!strncasecmp_latin1_ascii(mr->search_str, name, len)) + d=0; + dbg(lvl_debug,"string %d", d); + } else { + if (town_assoc < mr->search_item.id_lo) + d=1; + else + d=-1; + dbg(lvl_debug,"assoc %d 0x%x-0x%x",d, mr->search_item.id_lo, town_assoc); + } + } + dbg(lvl_debug,"d=%d", d); + return d; } static int -street_search_compare(unsigned char **p, struct map_rect_priv *mr) -{ - struct street_name_index *i; - int ret; - - dbg(lvl_debug,"enter"); - i=(struct street_name_index *)(*p); - *p+=sizeof(*i)+strlen(i->name)+1; - - dbg(lvl_debug,"block 0x%x", i->block); - - ret=street_search_compare_do(mr, i->country, i->town_assoc, i->name); - if (ret <= 0) - mr->search_block=i->block; - return ret; +street_search_compare(unsigned char **p, struct map_rect_priv *mr) { + struct street_name_index *i; + int ret; + + dbg(lvl_debug,"enter"); + i=(struct street_name_index *)(*p); + *p+=sizeof(*i)+strlen(i->name)+1; + + dbg(lvl_debug,"block 0x%x", i->block); + + ret=street_search_compare_do(mr, i->country, i->town_assoc, i->name); + if (ret <= 0) + mr->search_block=i->block; + return ret; } static void -street_name_coord_rewind(void *priv_data) -{ - /* struct street_priv *street=priv_data; */ +street_name_coord_rewind(void *priv_data) { + /* struct street_priv *street=priv_data; */ } static void -street_name_attr_rewind(void *priv_data) -{ - /* struct street_priv *street=priv_data; */ +street_name_attr_rewind(void *priv_data) { + /* struct street_priv *street=priv_data; */ } static int -street_name_coord_get(void *priv_data, struct coord *c, int count) -{ - struct map_rect_priv *mr=priv_data; - struct street_name_numbers snns; - unsigned char *p=mr->street.name.aux_data; - - dbg(lvl_debug,"aux_data=%p", p); - if (count) { - street_name_numbers_get(&snns, &p); - street_name_numbers_get_coord(&snns, c); - return 1; - } - - return 0; +street_name_coord_get(void *priv_data, struct coord *c, int count) { + struct map_rect_priv *mr=priv_data; + struct street_name_numbers snns; + unsigned char *p=mr->street.name.aux_data; + + dbg(lvl_debug,"aux_data=%p", p); + if (count) { + street_name_numbers_get(&snns, &p); + street_name_numbers_get_coord(&snns, c); + return 1; + } + + return 0; } #if 0 static void -debug(struct map_rect_priv *mr) -{ - int i; - struct street_name_numbers nns; - unsigned char *p=mr->street.name.aux_data; - unsigned char *end=p+mr->street.name.aux_len; - printf("len=0x%x\n", mr->street.name.aux_len); - for (i = 0 ; i < mr->street.name.aux_len ; i++) { - printf("%02x ",mr->street.name.aux_data[i]); - } - printf("\n"); - { - while (p < end) { - unsigned char *pn,*pn_end; - struct street_name_number nn; - street_name_numbers_get(&nns, &p); - printf("name_numbers:\n"); - printf(" len 0x%x\n", nns.len); - printf(" tag 0x%x\n", nns.tag); - printf(" dist 0x%x\n", nns.dist); - printf(" country 0x%x\n", nns.country); - printf(" coord 0x%x,0x%x\n", nns.c->x, nns.c->y); - printf(" first %d\n", nns.first.number); - printf(" last %d\n", nns.last.number); - printf(" segment count 0x%x\n", nns.segment_count); - printf(" aux_len 0x%x\n", nns.aux_len); - pn=nns.aux_data; - pn_end=nns.aux_data+nns.aux_len; - while (pn < pn_end) { - printf(" number:\n"); - street_name_number_get(&nn, &pn); - printf(" len 0x%x\n", nn.len); - printf(" tag 0x%x\n", nn.tag); - printf(" coord 0x%x,0x%x\n", nn.c->x, nn.c->y); - printf(" first %d\n", nn.first.number); - printf(" last %d\n", nn.last.number); - } - } - } +debug(struct map_rect_priv *mr) { + int i; + struct street_name_numbers nns; + unsigned char *p=mr->street.name.aux_data; + unsigned char *end=p+mr->street.name.aux_len; + printf("len=0x%x\n", mr->street.name.aux_len); + for (i = 0 ; i < mr->street.name.aux_len ; i++) { + printf("%02x ",mr->street.name.aux_data[i]); + } + printf("\n"); + { + while (p < end) { + unsigned char *pn,*pn_end; + struct street_name_number nn; + street_name_numbers_get(&nns, &p); + printf("name_numbers:\n"); + printf(" len 0x%x\n", nns.len); + printf(" tag 0x%x\n", nns.tag); + printf(" dist 0x%x\n", nns.dist); + printf(" country 0x%x\n", nns.country); + printf(" coord 0x%x,0x%x\n", nns.c->x, nns.c->y); + printf(" first %d\n", nns.first.number); + printf(" last %d\n", nns.last.number); + printf(" segment count 0x%x\n", nns.segment_count); + printf(" aux_len 0x%x\n", nns.aux_len); + pn=nns.aux_data; + pn_end=nns.aux_data+nns.aux_len; + while (pn < pn_end) { + printf(" number:\n"); + street_name_number_get(&nn, &pn); + printf(" len 0x%x\n", nn.len); + printf(" tag 0x%x\n", nn.tag); + printf(" coord 0x%x,0x%x\n", nn.c->x, nn.c->y); + printf(" first %d\n", nn.first.number); + printf(" last %d\n", nn.last.number); + } + } + } } #endif static int -street_name_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct map_rect_priv *mr=priv_data; - - attr->type=attr_type; - switch (attr_type) { - case attr_street_name: - attr->u.str=mr->street.name.name2; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_street_name_systematic: - attr->u.str=mr->street.name.name1; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_town_name: - case attr_district_name: - case attr_postal: - if (!mr->search_item_tmp) - mr->search_item_tmp=map_rect_get_item_byid_mg(mr->search_mr_tmp, mr->street.name_numbers.country | (file_town_twn << 16), mr->street.name_numbers.dist); - if (!mr->search_item_tmp) - return 0; - return item_attr_get(mr->search_item_tmp, attr_type, attr); - default: - dbg(lvl_error,"unknown attr %s",attr_to_name(attr_type)); - return 0; - } +street_name_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct map_rect_priv *mr=priv_data; + + attr->type=attr_type; + switch (attr_type) { + case attr_street_name: + attr->u.str=mr->street.name.name2; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_street_name_systematic: + attr->u.str=mr->street.name.name1; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_town_name: + case attr_district_name: + case attr_postal: + if (!mr->search_item_tmp) + mr->search_item_tmp=map_rect_get_item_byid_mg(mr->search_mr_tmp, + mr->street.name_numbers.country | (file_town_twn << 16), mr->street.name_numbers.dist); + if (!mr->search_item_tmp) + return 0; + return item_attr_get(mr->search_item_tmp, attr_type, attr); + default: + dbg(lvl_error,"unknown attr %s",attr_to_name(attr_type)); + return 0; + } } @@ -767,261 +747,256 @@ street_name_attr_get(void *priv_data, enum attr_type attr_type, struct attr *att static struct item_methods street_name_meth = { - street_name_coord_rewind, - street_name_coord_get, - street_name_attr_rewind, - street_name_attr_get, + street_name_coord_rewind, + street_name_coord_get, + street_name_attr_rewind, + street_name_attr_get, }; int -street_name_get_byid(struct map_rect_priv *mr, struct street_priv *street, int id_hi, int id_lo, struct item *item) -{ - mr->current_file=id_hi >> 16; - street->name_file=mr->m->file[mr->current_file]; - item->type=type_street_name; - item->id_hi=id_hi; - item->id_lo=id_lo; - item->meth=&street_name_meth; - item->map=NULL; - item->priv_data=mr; - mr->b.p=street->name_file->begin+item->id_lo; - dbg(lvl_debug,"last %p map %p file %d begin %p", mr->b.p, mr->m, mr->current_file, mr->m->file[mr->current_file]->begin); - street_name_get(&street->name, &mr->b.p); - return 1; +street_name_get_byid(struct map_rect_priv *mr, struct street_priv *street, int id_hi, int id_lo, struct item *item) { + mr->current_file=id_hi >> 16; + street->name_file=mr->m->file[mr->current_file]; + item->type=type_street_name; + item->id_hi=id_hi; + item->id_lo=id_lo; + item->meth=&street_name_meth; + item->map=NULL; + item->priv_data=mr; + mr->b.p=street->name_file->begin+item->id_lo; + dbg(lvl_debug,"last %p map %p file %d begin %p", mr->b.p, mr->m, mr->current_file, + mr->m->file[mr->current_file]->begin); + street_name_get(&street->name, &mr->b.p); + return 1; } static struct item * -street_search_get_item_street_name(struct map_rect_priv *mr) -{ - int dir=1,leaf; - unsigned char *last; - - dbg(lvl_debug,"enter"); - if (! mr->search_blk_count) { - dbg(lvl_debug,"partial 0x%x '%s' ***", mr->town.street_assoc, mr->search_str); - if (mr->search_linear) - return NULL; - dbg(lvl_debug,"tree_search_next"); - mr->search_block=-1; - while ((leaf=tree_search_next(&mr->ts, &mr->search_p, dir)) != -1) { - dir=street_search_compare(&mr->search_p, mr); - } - dbg(lvl_debug,"dir=%d mr->search_block=0x%x", dir, mr->search_block); - if (mr->search_block == -1) - return NULL; - mr->search_blk_count=1; - block_get_byindex(mr->m->file[file_strname_stn], mr->search_block, &mr->b); - mr->b.p=mr->b.block_start+12; - } - dbg(lvl_debug,"name id %td", mr->b.p-mr->m->file[file_strname_stn]->begin); - if (! mr->search_blk_count) - return NULL; - for (;;) { - if (mr->b.p >= mr->b.end) { - if (!block_next_lin(mr)) { - dbg(lvl_debug,"end of blocks in %p, %p", mr->m->file[file_strname_stn]->begin, mr->m->file[file_strname_stn]->end); - return NULL; - } - mr->b.p=mr->b.block_start+12; - } - while (mr->b.p < mr->b.end) { - last=mr->b.p; - street_name_get(&mr->street.name, &mr->b.p); - dir=street_search_compare_do(mr, mr->street.name.country, mr->street.name.townassoc, mr->street.name.name2); - dbg(lvl_debug,"country 0x%x assoc 0x%x name1 '%s' name2 '%s' dir=%d", mr->street.name.country, mr->street.name.townassoc, mr->street.name.name1, mr->street.name.name2, dir); - if (dir < 0) { - dbg(lvl_debug,"end of data"); - mr->search_blk_count=0; - return NULL; - } - if (!dir) { - dbg(lvl_debug,"result country 0x%x assoc 0x%x name1 '%s' name2 '%s' dir=%d aux_data=%p len=0x%x", mr->street.name.country, mr->street.name.townassoc, mr->street.name.name1, mr->street.name.name2, dir, mr->street.name.aux_data, mr->street.name.aux_len); - mr->item.type = type_street_name; - mr->item.id_hi=(file_strname_stn << 16); - mr->item.id_lo=last-mr->m->file[file_strname_stn]->begin; - dbg(lvl_debug,"id 0x%x 0x%x last %p map %p file %d begin %p", mr->item.id_hi, mr->item.id_lo, last, mr->m, mr->current_file, mr->m->file[mr->current_file]->begin); - mr->item.meth=&street_name_meth; - mr->item.map=NULL; - mr->item.priv_data=mr; - /* debug(mr); */ - dbg(lvl_debug,"last %p",last); - return &mr->item; - } - } - } +street_search_get_item_street_name(struct map_rect_priv *mr) { + int dir=1,leaf; + unsigned char *last; + + dbg(lvl_debug,"enter"); + if (! mr->search_blk_count) { + dbg(lvl_debug,"partial 0x%x '%s' ***", mr->town.street_assoc, mr->search_str); + if (mr->search_linear) + return NULL; + dbg(lvl_debug,"tree_search_next"); + mr->search_block=-1; + while ((leaf=tree_search_next(&mr->ts, &mr->search_p, dir)) != -1) { + dir=street_search_compare(&mr->search_p, mr); + } + dbg(lvl_debug,"dir=%d mr->search_block=0x%x", dir, mr->search_block); + if (mr->search_block == -1) + return NULL; + mr->search_blk_count=1; + block_get_byindex(mr->m->file[file_strname_stn], mr->search_block, &mr->b); + mr->b.p=mr->b.block_start+12; + } + dbg(lvl_debug,"name id %td", mr->b.p-mr->m->file[file_strname_stn]->begin); + if (! mr->search_blk_count) + return NULL; + for (;;) { + if (mr->b.p >= mr->b.end) { + if (!block_next_lin(mr)) { + dbg(lvl_debug,"end of blocks in %p, %p", mr->m->file[file_strname_stn]->begin, mr->m->file[file_strname_stn]->end); + return NULL; + } + mr->b.p=mr->b.block_start+12; + } + while (mr->b.p < mr->b.end) { + last=mr->b.p; + street_name_get(&mr->street.name, &mr->b.p); + dir=street_search_compare_do(mr, mr->street.name.country, mr->street.name.townassoc, mr->street.name.name2); + dbg(lvl_debug,"country 0x%x assoc 0x%x name1 '%s' name2 '%s' dir=%d", mr->street.name.country, + mr->street.name.townassoc, mr->street.name.name1, mr->street.name.name2, dir); + if (dir < 0) { + dbg(lvl_debug,"end of data"); + mr->search_blk_count=0; + return NULL; + } + if (!dir) { + dbg(lvl_debug,"result country 0x%x assoc 0x%x name1 '%s' name2 '%s' dir=%d aux_data=%p len=0x%x", + mr->street.name.country, mr->street.name.townassoc, mr->street.name.name1, mr->street.name.name2, dir, + mr->street.name.aux_data, mr->street.name.aux_len); + mr->item.type = type_street_name; + mr->item.id_hi=(file_strname_stn << 16); + mr->item.id_lo=last-mr->m->file[file_strname_stn]->begin; + dbg(lvl_debug,"id 0x%x 0x%x last %p map %p file %d begin %p", mr->item.id_hi, mr->item.id_lo, last, mr->m, + mr->current_file, mr->m->file[mr->current_file]->begin); + mr->item.meth=&street_name_meth; + mr->item.map=NULL; + mr->item.priv_data=mr; + /* debug(mr); */ + dbg(lvl_debug,"last %p",last); + return &mr->item; + } + } + } } struct item * -street_search_get_item(struct map_rect_priv *mr) -{ - struct item *item; - for (;;) { - if (!mr->street.name.tmp_data || street_name_eod(&mr->street.name)) { - item=street_search_get_item_street_name(mr); - if (!item) - return NULL; - if (!mr->street.name.aux_len) - return item; - } - mr->item.id_hi++; - street_name_numbers_get(&mr->street.name_numbers, &mr->street.name.tmp_data); - mr->search_item_tmp=NULL; - return &mr->item; - } +street_search_get_item(struct map_rect_priv *mr) { + struct item *item; + for (;;) { + if (!mr->street.name.tmp_data || street_name_eod(&mr->street.name)) { + item=street_search_get_item_street_name(mr); + if (!item) + return NULL; + if (!mr->street.name.aux_len) + return item; + } + mr->item.id_hi++; + street_name_numbers_get(&mr->street.name_numbers, &mr->street.name.tmp_data); + mr->search_item_tmp=NULL; + return &mr->item; + } } static int -street_name_numbers_next(struct map_rect_priv *mr) -{ - if (street_name_eod(&mr->street.name)) - return 0; - dbg(lvl_debug,"%p vs %p",mr->street.name.tmp_data, mr->street.name.aux_data); - street_name_numbers_get(&mr->street.name_numbers, &mr->street.name.tmp_data); - return 1; +street_name_numbers_next(struct map_rect_priv *mr) { + if (street_name_eod(&mr->street.name)) + return 0; + dbg(lvl_debug,"%p vs %p",mr->street.name.tmp_data, mr->street.name.aux_data); + street_name_numbers_get(&mr->street.name_numbers, &mr->street.name.tmp_data); + return 1; } static int -street_name_number_next(struct map_rect_priv *mr) -{ - if (street_name_numbers_eod(&mr->street.name_numbers)) - return 0; - street_name_number_get(&mr->street.name_number, &mr->street.name_numbers.tmp_data); - sprintf(mr->street.first_number,"%d%s",mr->street.name_number.first.number,mr->street.name_number.first.suffix); - sprintf(mr->street.last_number,"%d%s",mr->street.name_number.last.number,mr->street.name_number.last.suffix); - mr->street.current_number[0]='\0'; - return 1; +street_name_number_next(struct map_rect_priv *mr) { + if (street_name_numbers_eod(&mr->street.name_numbers)) + return 0; + street_name_number_get(&mr->street.name_number, &mr->street.name_numbers.tmp_data); + sprintf(mr->street.first_number,"%d%s",mr->street.name_number.first.number,mr->street.name_number.first.suffix); + sprintf(mr->street.last_number,"%d%s",mr->street.name_number.last.number,mr->street.name_number.last.suffix); + mr->street.current_number[0]='\0'; + return 1; } static void -housenumber_coord_rewind(void *priv_data) -{ - /* struct street_priv *street=priv_data; */ +housenumber_coord_rewind(void *priv_data) { + /* struct street_priv *street=priv_data; */ } static void -housenumber_attr_rewind(void *priv_data) -{ - /* struct street_priv *street=priv_data; */ +housenumber_attr_rewind(void *priv_data) { + /* struct street_priv *street=priv_data; */ } static int -housenumber_coord_get(void *priv_data, struct coord *c, int count) -{ - return 0; +housenumber_coord_get(void *priv_data, struct coord *c, int count) { + return 0; } static int -housenumber_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct map_rect_priv *mr=priv_data; - attr->type=attr_type; - switch (attr_type) { - case attr_house_number: - attr->u.str=mr->street.current_number; - return 1; - case attr_town_name: - case attr_district_name: - case attr_postal: - if (!mr->search_item_tmp) - mr->search_item_tmp=map_rect_get_item_byid_mg(mr->search_mr_tmp, mr->street.name_numbers.country | (file_town_twn << 16), mr->street.name_numbers.dist); - if (!mr->search_item_tmp) - return 0; - return item_attr_get(mr->search_item_tmp, attr_type, attr); - default: - dbg(lvl_error,"unknown attr %s",attr_to_name(attr_type)); - return 0; - } +housenumber_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct map_rect_priv *mr=priv_data; + attr->type=attr_type; + switch (attr_type) { + case attr_house_number: + attr->u.str=mr->street.current_number; + return 1; + case attr_town_name: + case attr_district_name: + case attr_postal: + if (!mr->search_item_tmp) + mr->search_item_tmp=map_rect_get_item_byid_mg(mr->search_mr_tmp, + mr->street.name_numbers.country | (file_town_twn << 16), mr->street.name_numbers.dist); + if (!mr->search_item_tmp) + return 0; + return item_attr_get(mr->search_item_tmp, attr_type, attr); + default: + dbg(lvl_error,"unknown attr %s",attr_to_name(attr_type)); + return 0; + } } static struct item_methods housenumber_meth = { - housenumber_coord_rewind, - housenumber_coord_get, - housenumber_attr_rewind, - housenumber_attr_get, + housenumber_coord_rewind, + housenumber_coord_get, + housenumber_attr_rewind, + housenumber_attr_get, }; int -housenumber_search_setup(struct map_rect_priv *mr) -{ - dbg(lvl_debug,"enter (0x%x,0x%x)",mr->search_item.id_hi,mr->search_item.id_lo); - int id=mr->search_item.id_hi & 0xff; - mr->current_file=file_strname_stn; - mr->street.name_file=mr->m->file[mr->current_file]; - mr->b.p=mr->street.name_file->begin+mr->search_item.id_lo; - mr->search_str=g_strdup(mr->search_attr->u.str); - dbg(lvl_debug,"last %p",mr->b.p); - street_name_get(&mr->street.name, &mr->b.p); - while (id > 0) { - id--; - dbg(lvl_debug,"loop"); - if (!street_name_numbers_next(mr)) - return 0; - } - mr->item.type=type_house_number; - mr->item.priv_data=mr; - mr->item.id_hi=mr->search_item.id_hi + 0x100; - mr->item.meth=&housenumber_meth; - if (!id) - mr->item.id_hi+=1; - mr->item.id_lo=mr->search_item.id_lo; - dbg(lvl_debug,"getting name_number %p vs %p + %d",mr->street.name_numbers.tmp_data,mr->street.name_numbers.aux_data, mr->street.name_numbers.aux_len); - if (!street_name_number_next(mr)) - return 0; - dbg(lvl_debug,"enter"); - // debug(mr); - return 1; +housenumber_search_setup(struct map_rect_priv *mr) { + dbg(lvl_debug,"enter (0x%x,0x%x)",mr->search_item.id_hi,mr->search_item.id_lo); + int id=mr->search_item.id_hi & 0xff; + mr->current_file=file_strname_stn; + mr->street.name_file=mr->m->file[mr->current_file]; + mr->b.p=mr->street.name_file->begin+mr->search_item.id_lo; + mr->search_str=g_strdup(mr->search_attr->u.str); + dbg(lvl_debug,"last %p",mr->b.p); + street_name_get(&mr->street.name, &mr->b.p); + while (id > 0) { + id--; + dbg(lvl_debug,"loop"); + if (!street_name_numbers_next(mr)) + return 0; + } + mr->item.type=type_house_number; + mr->item.priv_data=mr; + mr->item.id_hi=mr->search_item.id_hi + 0x100; + mr->item.meth=&housenumber_meth; + if (!id) + mr->item.id_hi+=1; + mr->item.id_lo=mr->search_item.id_lo; + dbg(lvl_debug,"getting name_number %p vs %p + %d",mr->street.name_numbers.tmp_data,mr->street.name_numbers.aux_data, + mr->street.name_numbers.aux_len); + if (!street_name_number_next(mr)) + return 0; + dbg(lvl_debug,"enter"); + // debug(mr); + return 1; } static int -house_number_next(char *number, char *first, char *last, int interpolation, int *percentage) -{ - int firstn=atoi(first); - int lastn=atoi(last); - int current,delta,len=lastn-firstn; - if (interpolation) { - len/=2; - } - if (!number[0]) { - strcpy(number,first); - delta=0; - } else { - current=atoi(number)+(interpolation ? 2:1); - if (current > lastn) - return 0; - sprintf(number,"%d",current); - delta=current-firstn; - } - if (percentage) { - if (len) - *percentage=delta*100/len; - else - *percentage=50; - } - return 1; +house_number_next(char *number, char *first, char *last, int interpolation, int *percentage) { + int firstn=atoi(first); + int lastn=atoi(last); + int current,delta,len=lastn-firstn; + if (interpolation) { + len/=2; + } + if (!number[0]) { + strcpy(number,first); + delta=0; + } else { + current=atoi(number)+(interpolation ? 2:1); + if (current > lastn) + return 0; + sprintf(number,"%d",current); + delta=current-firstn; + } + if (percentage) { + if (len) + *percentage=delta*100/len; + else + *percentage=50; + } + return 1; } struct item * -housenumber_search_get_item(struct map_rect_priv *mr) -{ - int d; - dbg(lvl_debug,"enter %s %s",mr->street.first_number,mr->street.last_number); - for (;;) { - if (!house_number_next(mr->street.current_number, mr->street.first_number, mr->street.last_number, 0, NULL)) { - if (!street_name_number_next(mr)) - return NULL; - continue; - } - if (mr->search_partial) - d=strncasecmp(mr->search_str, mr->street.current_number, strlen(mr->search_str)); - else - d=strcasecmp(mr->search_str, mr->street.current_number); - if (!d) { - mr->search_item_tmp=NULL; - return &mr->item; - } - } -} +housenumber_search_get_item(struct map_rect_priv *mr) { + int d; + dbg(lvl_debug,"enter %s %s",mr->street.first_number,mr->street.last_number); + for (;;) { + if (!house_number_next(mr->street.current_number, mr->street.first_number, mr->street.last_number, 0, NULL)) { + if (!street_name_number_next(mr)) + return NULL; + continue; + } + if (mr->search_partial) + d=strncasecmp(mr->search_str, mr->street.current_number, strlen(mr->search_str)); + else + d=strcasecmp(mr->search_str, mr->street.current_number); + if (!d) { + mr->search_item_tmp=NULL; + return &mr->item; + } + } +} diff --git a/navit/map/mg/town.c b/navit/map/mg/town.c index ace353a1d..be50b63e1 100644 --- a/navit/map/mg/town.c +++ b/navit/map/mg/town.c @@ -25,260 +25,252 @@ static void -town_coord_rewind(void *priv_data) -{ - struct town_priv *twn=priv_data; +town_coord_rewind(void *priv_data) { + struct town_priv *twn=priv_data; - twn->cidx=0; + twn->cidx=0; } static int -town_coord_get(void *priv_data, struct coord *c, int count) -{ - struct town_priv *twn=priv_data; +town_coord_get(void *priv_data, struct coord *c, int count) { + struct town_priv *twn=priv_data; - if (twn->cidx || count <= 0) - return 0; - twn->cidx=1; - *c=twn->c; - return 1; + if (twn->cidx || count <= 0) + return 0; + twn->cidx=1; + *c=twn->c; + return 1; } static void -town_attr_rewind(void *priv_data) -{ - struct town_priv *twn=priv_data; +town_attr_rewind(void *priv_data) { + struct town_priv *twn=priv_data; - twn->aidx=0; - twn->attr_next=attr_label; + twn->aidx=0; + twn->attr_next=attr_label; } static int -town_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct town_priv *twn=priv_data; - int len; +town_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct town_priv *twn=priv_data; + int len; - attr->type=attr_type; - switch (attr_type) { - case attr_any: - while (twn->attr_next != attr_none) { - if (town_attr_get(twn, twn->attr_next, attr)) - return 1; - } - return 0; - case attr_label: - attr->u.str=twn->district; - twn->attr_next=attr_town_name; - if (attr->u.str[0]) - return 1; - attr->u.str=twn->name; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_town_name: - attr->u.str=twn->name; - twn->attr_next=attr_town_postal; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_town_postal: - case attr_postal: - strncpy(twn->postal, twn->postal_code1, 32); - attr->u.str=twn->postal; - len=mg_country_postal_len(twn->country); - if (!len) - len=31; - twn->postal[len]='\0'; - twn->attr_next=attr_district_name; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_district_name: - attr->u.str=twn->district; - twn->attr_next=attr_debug; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_town_streets_item: - twn->town_attr_item.type=type_town_streets; - twn->town_attr_item.id_hi=twn->country | (file_town_twn << 16) | 0x10000000; - twn->town_attr_item.id_lo=twn->street_assoc; - attr->u.item=&twn->town_attr_item; - twn->attr_next=attr_debug; - return 1; - case attr_debug: - sprintf(twn->debug, "order %d\nsize %d\nstreet_assoc 0x%x", twn->order, twn->size, twn->street_assoc); - attr->u.str=twn->debug; - twn->attr_next=attr_none; - return 1; - default: - dbg(lvl_warning, "Don't know about attribute %d[%04X]=%s yet", - attr_type, attr_type, attr_to_name(attr_type)); - return 0; - } - return 1; + attr->type=attr_type; + switch (attr_type) { + case attr_any: + while (twn->attr_next != attr_none) { + if (town_attr_get(twn, twn->attr_next, attr)) + return 1; + } + return 0; + case attr_label: + attr->u.str=twn->district; + twn->attr_next=attr_town_name; + if (attr->u.str[0]) + return 1; + attr->u.str=twn->name; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_town_name: + attr->u.str=twn->name; + twn->attr_next=attr_town_postal; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_town_postal: + case attr_postal: + strncpy(twn->postal, twn->postal_code1, 32); + attr->u.str=twn->postal; + len=mg_country_postal_len(twn->country); + if (!len) + len=31; + twn->postal[len]='\0'; + twn->attr_next=attr_district_name; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_district_name: + attr->u.str=twn->district; + twn->attr_next=attr_debug; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_town_streets_item: + twn->town_attr_item.type=type_town_streets; + twn->town_attr_item.id_hi=twn->country | (file_town_twn << 16) | 0x10000000; + twn->town_attr_item.id_lo=twn->street_assoc; + attr->u.item=&twn->town_attr_item; + twn->attr_next=attr_debug; + return 1; + case attr_debug: + sprintf(twn->debug, "order %d\nsize %d\nstreet_assoc 0x%x", twn->order, twn->size, twn->street_assoc); + attr->u.str=twn->debug; + twn->attr_next=attr_none; + return 1; + default: + dbg(lvl_warning, "Don't know about attribute %d[%04X]=%s yet", + attr_type, attr_type, attr_to_name(attr_type)); + return 0; + } + return 1; } static struct item_methods town_meth = { - town_coord_rewind, - town_coord_get, - town_attr_rewind, - town_attr_get, + town_coord_rewind, + town_coord_get, + town_attr_rewind, + town_attr_get, }; static void -town_get_data(struct town_priv *twn, unsigned char **p) -{ - twn->id=get_u32_unal(p); - twn->c.x=get_u32_unal(p); - twn->c.y=get_u32_unal(p); - twn->name=get_string(p); - twn->district=get_string(p); - twn->postal_code1=get_string(p); - twn->order=get_u8(p); /* 1-15 (19) */ - twn->country=get_u16_unal(p); - twn->type=get_u8(p); - twn->unknown2=get_u32_unal(p); - twn->size=get_u8(p); - twn->street_assoc=get_u32_unal(p); - twn->unknown3=get_u8(p); - twn->postal_code2=get_string(p); - twn->unknown4=get_u32_unal(p); +town_get_data(struct town_priv *twn, unsigned char **p) { + twn->id=get_u32_unal(p); + twn->c.x=get_u32_unal(p); + twn->c.y=get_u32_unal(p); + twn->name=get_string(p); + twn->district=get_string(p); + twn->postal_code1=get_string(p); + twn->order=get_u8(p); /* 1-15 (19) */ + twn->country=get_u16_unal(p); + twn->type=get_u8(p); + twn->unknown2=get_u32_unal(p); + twn->size=get_u8(p); + twn->street_assoc=get_u32_unal(p); + twn->unknown3=get_u8(p); + twn->postal_code2=get_string(p); + twn->unknown4=get_u32_unal(p); } - /*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 */ -static unsigned char limit[]={0,1,2,2,4,6,8,10,11,13,14,14,14,20,20,20,20,20,20}; +/*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 */ +static unsigned char limit[]= {0,1,2,2,4,6,8,10,11,13,14,14,14,20,20,20,20,20,20}; -static enum item_type town_item[]={type_town_label_5e1, type_town_label_1e2, type_town_label_2e2, type_town_label_5e2, type_town_label_1e3, type_town_label_1e3, type_town_label_2e3, type_town_label_5e3, type_town_label_1e4, type_town_label_2e4, type_town_label_5e4, type_town_label_1e5, type_town_label_1e5, type_town_label_2e5, type_town_label_5e5, type_town_label_1e6, type_town_label_2e6}; -static enum item_type district_item[]={type_district_label_5e1, type_district_label_1e2, type_district_label_2e2, type_district_label_5e2, type_district_label_1e3, type_district_label_1e3, type_district_label_2e3, type_district_label_5e3, type_district_label_1e4, type_district_label_2e4, type_district_label_5e4, type_district_label_1e5, type_district_label_1e5, type_district_label_2e5, type_district_label_5e5, type_district_label_1e6, type_district_label_2e6}; +static enum item_type town_item[]= {type_town_label_5e1, type_town_label_1e2, type_town_label_2e2, type_town_label_5e2, type_town_label_1e3, type_town_label_1e3, type_town_label_2e3, type_town_label_5e3, type_town_label_1e4, type_town_label_2e4, type_town_label_5e4, type_town_label_1e5, type_town_label_1e5, type_town_label_2e5, type_town_label_5e5, type_town_label_1e6, type_town_label_2e6}; +static enum item_type district_item[]= {type_district_label_5e1, type_district_label_1e2, type_district_label_2e2, type_district_label_5e2, type_district_label_1e3, type_district_label_1e3, type_district_label_2e3, type_district_label_5e3, type_district_label_1e4, type_district_label_2e4, type_district_label_5e4, type_district_label_1e5, type_district_label_1e5, type_district_label_2e5, type_district_label_5e5, type_district_label_1e6, type_district_label_2e6}; int -town_get(struct map_rect_priv *mr, struct town_priv *twn, struct item *item) -{ - int size; - for (;;) { - if (mr->b.p >= mr->b.end) - return 0; - town_get_data(twn, &mr->b.p); - twn->cidx=0; - twn->aidx=0; - twn->attr_next=attr_label; - if (! mr->cur_sel || (twn->order <= limit[mr->cur_sel->order] && coord_rect_contains(&mr->cur_sel->u.c_rect,&twn->c))) { - switch(twn->type) { - case 1: - size=twn->size; - if (size >= sizeof(town_item)/sizeof(enum item_type)) - size=sizeof(town_item)/sizeof(enum item_type)-1; - item->type=town_item[size]; - break; - case 3: - size=twn->size; - if (size == 6 && twn->order < 14) - size++; - if (size == 5 && twn->order < 14) - size+=2; - if (size >= sizeof(district_item)/sizeof(enum item_type)) - size=sizeof(district_item)/sizeof(enum item_type)-1; - item->type=district_item[size]; - break; - case 4: - item->type=type_port_label; - break; - case 9: - item->type=type_highway_exit_label; - break; - default: - printf("unknown town type 0x%x '%s' '%s' 0x%x,0x%x\n", twn->type, twn->name, twn->district, twn->c.x, twn->c.y); - item->type=type_town_label; - } - if (map_selection_contains_item(mr->cur_sel, 0, item->type)) { - item->id_hi=twn->country | (mr->current_file << 16); - item->id_lo=twn->id; - item->priv_data=twn; - item->meth=&town_meth; - return 1; - } - } - } +town_get(struct map_rect_priv *mr, struct town_priv *twn, struct item *item) { + int size; + for (;;) { + if (mr->b.p >= mr->b.end) + return 0; + town_get_data(twn, &mr->b.p); + twn->cidx=0; + twn->aidx=0; + twn->attr_next=attr_label; + if (! mr->cur_sel || (twn->order <= limit[mr->cur_sel->order] && coord_rect_contains(&mr->cur_sel->u.c_rect,&twn->c))) { + switch(twn->type) { + case 1: + size=twn->size; + if (size >= sizeof(town_item)/sizeof(enum item_type)) + size=sizeof(town_item)/sizeof(enum item_type)-1; + item->type=town_item[size]; + break; + case 3: + size=twn->size; + if (size == 6 && twn->order < 14) + size++; + if (size == 5 && twn->order < 14) + size+=2; + if (size >= sizeof(district_item)/sizeof(enum item_type)) + size=sizeof(district_item)/sizeof(enum item_type)-1; + item->type=district_item[size]; + break; + case 4: + item->type=type_port_label; + break; + case 9: + item->type=type_highway_exit_label; + break; + default: + printf("unknown town type 0x%x '%s' '%s' 0x%x,0x%x\n", twn->type, twn->name, twn->district, twn->c.x, twn->c.y); + item->type=type_town_label; + } + if (map_selection_contains_item(mr->cur_sel, 0, item->type)) { + item->id_hi=twn->country | (mr->current_file << 16); + item->id_lo=twn->id; + item->priv_data=twn; + item->meth=&town_meth; + return 1; + } + } + } } int -town_get_byid(struct map_rect_priv *mr, struct town_priv *twn, int id_hi, int id_lo, struct item *item) -{ - int country=id_hi & 0xffff; - int res; - if (!tree_search_hv(mr->m->dirname, "town", (id_lo >> 8) | (country << 24), id_lo & 0xff, &res)) - return 0; - block_get_byindex(mr->m->file[mr->current_file], res >> 16, &mr->b); - mr->b.p=mr->b.block_start+(res & 0xffff); - return town_get(mr, twn, item); +town_get_byid(struct map_rect_priv *mr, struct town_priv *twn, int id_hi, int id_lo, struct item *item) { + int country=id_hi & 0xffff; + int res; + if (!tree_search_hv(mr->m->dirname, "town", (id_lo >> 8) | (country << 24), id_lo & 0xff, &res)) + return 0; + block_get_byindex(mr->m->file[mr->current_file], res >> 16, &mr->b); + mr->b.p=mr->b.block_start+(res & 0xffff); + return town_get(mr, twn, item); } static int -town_search_compare(unsigned char **p, struct map_rect_priv *mr) -{ - int country, d; - char *name; +town_search_compare(unsigned char **p, struct map_rect_priv *mr) { + int country, d; + char *name; - if (mr->search_type == attr_town_postal) { - mr->search_blk_count=1; - mr->search_blk_off=(struct block_offset *)(*p); - *p+=4; - name=get_string(p); - d=0; - } else { - country=get_u16_unal(p); - dbg(lvl_debug,"country 0x%x ", country); - name=get_string(p); - dbg(lvl_debug,"name '%s' ",name); - mr->search_blk_count=get_u32_unal(p); - mr->search_blk_off=(struct block_offset *)(*p); - dbg(lvl_debug,"len %d ", mr->search_blk_count); - (*p)+=mr->search_blk_count*4; - d=mr->search_country-country; - } - if (!d) { - if (mr->search_partial) - d=strncasecmp(mr->search_str, name, strlen(mr->search_str)); - else - d=strcasecmp(mr->search_str, name); - } - dbg(lvl_debug,"%d ",d); - return d; + if (mr->search_type == attr_town_postal) { + mr->search_blk_count=1; + mr->search_blk_off=(struct block_offset *)(*p); + *p+=4; + name=get_string(p); + d=0; + } else { + country=get_u16_unal(p); + dbg(lvl_debug,"country 0x%x ", country); + name=get_string(p); + dbg(lvl_debug,"name '%s' ",name); + mr->search_blk_count=get_u32_unal(p); + mr->search_blk_off=(struct block_offset *)(*p); + dbg(lvl_debug,"len %d ", mr->search_blk_count); + (*p)+=mr->search_blk_count*4; + d=mr->search_country-country; + } + if (!d) { + if (mr->search_partial) + d=strncasecmp(mr->search_str, name, strlen(mr->search_str)); + else + d=strcasecmp(mr->search_str, name); + } + dbg(lvl_debug,"%d ",d); + return d; } struct item * -town_search_get_item(struct map_rect_priv *mr) -{ - int dir=1,leaf; +town_search_get_item(struct map_rect_priv *mr) { + int dir=1,leaf; - if (! mr->search_blk_count) { - dbg(lvl_debug,"partial %d 0x%x '%s' ***", mr->search_partial, mr->search_country, mr->search_str); - if (! mr->search_linear) { - while ((leaf=tree_search_next(&mr->ts, &mr->search_p, dir)) != -1) { - dir=town_search_compare(&mr->search_p, mr); - if (! dir) { - mr->search_linear=1; - mr->search_p=NULL; - break; - } - } - if (! mr->search_linear) { - dbg(lvl_warning,"not found"); - return NULL; - } - } - if (! tree_search_next_lin(&mr->ts, &mr->search_p)) { - dbg(lvl_debug,"linear not found"); - return NULL; - } - if (town_search_compare(&mr->search_p, mr)) { - dbg(lvl_debug,"no match"); - return NULL; - } - dbg(lvl_debug,"found %d blocks",mr->search_blk_count); - } - if (! mr->search_blk_count) - return NULL; - dbg(lvl_debug,"block 0x%x offset 0x%x", block_offset_get_block(mr->search_blk_off), block_offset_get_offset(mr->search_blk_off)); - block_get_byindex(mr->m->file[mr->current_file], block_offset_get_block(mr->search_blk_off), &mr->b); - mr->b.p=mr->b.block_start+block_offset_get_offset(mr->search_blk_off); - town_get(mr, &mr->town, &mr->item); - mr->search_blk_off++; - mr->search_blk_count--; - return &mr->item; + if (! mr->search_blk_count) { + dbg(lvl_debug,"partial %d 0x%x '%s' ***", mr->search_partial, mr->search_country, mr->search_str); + if (! mr->search_linear) { + while ((leaf=tree_search_next(&mr->ts, &mr->search_p, dir)) != -1) { + dir=town_search_compare(&mr->search_p, mr); + if (! dir) { + mr->search_linear=1; + mr->search_p=NULL; + break; + } + } + if (! mr->search_linear) { + dbg(lvl_warning,"not found"); + return NULL; + } + } + if (! tree_search_next_lin(&mr->ts, &mr->search_p)) { + dbg(lvl_debug,"linear not found"); + return NULL; + } + if (town_search_compare(&mr->search_p, mr)) { + dbg(lvl_debug,"no match"); + return NULL; + } + dbg(lvl_debug,"found %d blocks",mr->search_blk_count); + } + if (! mr->search_blk_count) + return NULL; + dbg(lvl_debug,"block 0x%x offset 0x%x", block_offset_get_block(mr->search_blk_off), + block_offset_get_offset(mr->search_blk_off)); + block_get_byindex(mr->m->file[mr->current_file], block_offset_get_block(mr->search_blk_off), &mr->b); + mr->b.p=mr->b.block_start+block_offset_get_offset(mr->search_blk_off); + town_get(mr, &mr->town, &mr->item); + mr->search_blk_off++; + mr->search_blk_count--; + return &mr->item; } diff --git a/navit/map/mg/tree.c b/navit/map/mg/tree.c index 4774cf610..76865dd0f 100644 --- a/navit/map/mg/tree.c +++ b/navit/map/mg/tree.c @@ -23,258 +23,291 @@ #include "mg.h" struct tree_hdr { - /*unsigned int addr; - unsigned int size; - unsigned int low;*/ - unsigned char p[12]; + /*unsigned int addr; + unsigned int size; + unsigned int low;*/ + unsigned char p[12]; }; -static inline unsigned int tree_hdr_get_addr(struct tree_hdr * tree) { unsigned char *p = tree->p; return get_u32(&p); } -static inline unsigned int tree_hdr_get_size(struct tree_hdr * tree) { unsigned char *p = tree->p+4; return get_u32(&p); } -static inline unsigned int tree_hdr_get_low(struct tree_hdr * tree) { unsigned char *p = tree->p+8; return get_u32(&p); } +static inline unsigned int tree_hdr_get_addr(struct tree_hdr * tree) { + unsigned char *p = tree->p; + return get_u32(&p); +} +static inline unsigned int tree_hdr_get_size(struct tree_hdr * tree) { + unsigned char *p = tree->p+4; + return get_u32(&p); +} +static inline unsigned int tree_hdr_get_low(struct tree_hdr * tree) { + unsigned char *p = tree->p+8; + return get_u32(&p); +} struct tree_hdr_h { -/* unsigned int addr; - unsigned int size;*/ - unsigned char p[8]; + /* unsigned int addr; + unsigned int size;*/ + unsigned char p[8]; }; -static inline unsigned int tree_hdr_h_get_addr(struct tree_hdr_h * tree) { unsigned char *p = tree->p; return get_u32(&p); } -static inline unsigned int tree_hdr_h_get_size(struct tree_hdr_h * tree) { unsigned char *p = tree->p+4; return get_u32(&p); } +static inline unsigned int tree_hdr_h_get_addr(struct tree_hdr_h * tree) { + unsigned char *p = tree->p; + return get_u32(&p); +} +static inline unsigned int tree_hdr_h_get_size(struct tree_hdr_h * tree) { + unsigned char *p = tree->p+4; + return get_u32(&p); +} struct tree_leaf_h { -/* unsigned int lower; - unsigned int higher; - unsigned int match; - unsigned int value;*/ - unsigned char p[16]; + /* unsigned int lower; + unsigned int higher; + unsigned int match; + unsigned int value;*/ + unsigned char p[16]; }; -static inline unsigned int tree_leaf_h_get_lower(struct tree_leaf_h * tree) { unsigned char *p = tree->p; return get_u32(&p); } -static inline unsigned int tree_leaf_h_get_higher(struct tree_leaf_h * tree) { unsigned char *p = tree->p+4; return get_u32(&p); } -static inline unsigned int tree_leaf_h_get_match(struct tree_leaf_h * tree) { unsigned char *p = tree->p+8; return get_u32(&p); } -static inline unsigned int tree_leaf_h_get_value(struct tree_leaf_h * tree) { unsigned char *p = tree->p+12; return get_u32(&p); } +static inline unsigned int tree_leaf_h_get_lower(struct tree_leaf_h * tree) { + unsigned char *p = tree->p; + return get_u32(&p); +} +static inline unsigned int tree_leaf_h_get_higher(struct tree_leaf_h * tree) { + unsigned char *p = tree->p+4; + return get_u32(&p); +} +static inline unsigned int tree_leaf_h_get_match(struct tree_leaf_h * tree) { + unsigned char *p = tree->p+8; + return get_u32(&p); +} +static inline unsigned int tree_leaf_h_get_value(struct tree_leaf_h * tree) { + unsigned char *p = tree->p+12; + return get_u32(&p); +} struct tree_hdr_v { - /*unsigned int count; - unsigned int next; - unsigned int unknown;*/ - unsigned char p[12]; + /*unsigned int count; + unsigned int next; + unsigned int unknown;*/ + unsigned char p[12]; }; -static inline unsigned int tree_hdr_v_get_count(struct tree_hdr_v * tree) { unsigned char *p = tree->p; return get_u32_unal(&p); } -static inline unsigned int tree_hdr_v_get_next(struct tree_hdr_v * tree) { unsigned char *p = tree->p+4; return get_u32_unal(&p); } -static inline unsigned int tree_hdr_v_get_unknown(struct tree_hdr_v * tree) { unsigned char *p = tree->p+8; return get_u32_unal(&p); } +static inline unsigned int tree_hdr_v_get_count(struct tree_hdr_v * tree) { + unsigned char *p = tree->p; + return get_u32_unal(&p); +} +static inline unsigned int tree_hdr_v_get_next(struct tree_hdr_v * tree) { + unsigned char *p = tree->p+4; + return get_u32_unal(&p); +} +static inline unsigned int tree_hdr_v_get_unknown(struct tree_hdr_v * tree) { + unsigned char *p = tree->p+8; + return get_u32_unal(&p); +} struct tree_leaf_v { - unsigned char key; - /*int value;*/ - unsigned char p[4]; + unsigned char key; + /*int value;*/ + unsigned char p[4]; } __attribute__((packed)); -static inline int tree_leaf_v_get_value(struct tree_leaf_v * tree) { unsigned char *p = tree->p; return get_u32_unal(&p); } +static inline int tree_leaf_v_get_value(struct tree_leaf_v * tree) { + unsigned char *p = tree->p; + return get_u32_unal(&p); +} static int -tree_search_h(struct file *file, unsigned int search) -{ - unsigned char *p=file->begin,*end; - int last,i=0,value,lower; - struct tree_hdr_h *thdr; - struct tree_leaf_h *tleaf; +tree_search_h(struct file *file, unsigned int search) { + unsigned char *p=file->begin,*end; + int last,i=0,value,lower; + struct tree_hdr_h *thdr; + struct tree_leaf_h *tleaf; - dbg(lvl_debug,"enter"); - while (i++ < 1000) { - thdr=(struct tree_hdr_h *)p; - p+=sizeof(*thdr); - end=p+tree_hdr_h_get_size(thdr); - dbg(lvl_debug,"@%td", p-file->begin); - last=0; - while (p < end) { - tleaf=(struct tree_leaf_h *)p; - p+=sizeof(*tleaf); - dbg(lvl_debug,"low:0x%x high:0x%x match:0x%x val:0x%x search:0x%x", tree_leaf_h_get_lower(tleaf), tree_leaf_h_get_higher(tleaf), tree_leaf_h_get_match(tleaf), tree_leaf_h_get_value(tleaf), search); - value=tree_leaf_h_get_value(tleaf); - if (value == search) - return tree_leaf_h_get_match(tleaf); - if (value > search) { - dbg(lvl_debug,"lower"); - lower=tree_leaf_h_get_lower(tleaf); - if (lower) - last=lower; - break; - } - last=tree_leaf_h_get_higher(tleaf); - } - if (! last || last == -1) - return 0; - p=file->begin+last; - } - return 0; + dbg(lvl_debug,"enter"); + while (i++ < 1000) { + thdr=(struct tree_hdr_h *)p; + p+=sizeof(*thdr); + end=p+tree_hdr_h_get_size(thdr); + dbg(lvl_debug,"@%td", p-file->begin); + last=0; + while (p < end) { + tleaf=(struct tree_leaf_h *)p; + p+=sizeof(*tleaf); + dbg(lvl_debug,"low:0x%x high:0x%x match:0x%x val:0x%x search:0x%x", tree_leaf_h_get_lower(tleaf), + tree_leaf_h_get_higher(tleaf), tree_leaf_h_get_match(tleaf), tree_leaf_h_get_value(tleaf), search); + value=tree_leaf_h_get_value(tleaf); + if (value == search) + return tree_leaf_h_get_match(tleaf); + if (value > search) { + dbg(lvl_debug,"lower"); + lower=tree_leaf_h_get_lower(tleaf); + if (lower) + last=lower; + break; + } + last=tree_leaf_h_get_higher(tleaf); + } + if (! last || last == -1) + return 0; + p=file->begin+last; + } + return 0; } static int -tree_search_v(struct file *file, int offset, int search) -{ - unsigned char *p=file->begin+offset; - int i=0,count,next; - struct tree_hdr_v *thdr; - struct tree_leaf_v *tleaf; - while (i++ < 1000) { - thdr=(struct tree_hdr_v *)p; - p+=sizeof(*thdr); - count=tree_hdr_v_get_count(thdr); - dbg(lvl_debug,"offset=%td count=0x%x", p-file->begin, count); - while (count--) { - tleaf=(struct tree_leaf_v *)p; - p+=sizeof(*tleaf); - dbg(lvl_debug,"0x%x 0x%x", tleaf->key, search); - if (tleaf->key == search) - return tree_leaf_v_get_value(tleaf); - } - next=tree_hdr_v_get_next(thdr); - if (! next) - break; - p=file->begin+next; - } - return 0; +tree_search_v(struct file *file, int offset, int search) { + unsigned char *p=file->begin+offset; + int i=0,count,next; + struct tree_hdr_v *thdr; + struct tree_leaf_v *tleaf; + while (i++ < 1000) { + thdr=(struct tree_hdr_v *)p; + p+=sizeof(*thdr); + count=tree_hdr_v_get_count(thdr); + dbg(lvl_debug,"offset=%td count=0x%x", p-file->begin, count); + while (count--) { + tleaf=(struct tree_leaf_v *)p; + p+=sizeof(*tleaf); + dbg(lvl_debug,"0x%x 0x%x", tleaf->key, search); + if (tleaf->key == search) + return tree_leaf_v_get_value(tleaf); + } + next=tree_hdr_v_get_next(thdr); + if (! next) + break; + p=file->begin+next; + } + return 0; } int -tree_search_hv(char *dirname, char *filename, unsigned int search_h, unsigned int search_v, int *result) -{ - struct file *f_idx_h, *f_idx_v; - char buffer[4096]; - int h,v; +tree_search_hv(char *dirname, char *filename, unsigned int search_h, unsigned int search_v, int *result) { + struct file *f_idx_h, *f_idx_v; + char buffer[4096]; + int h,v; - dbg(lvl_debug,"enter(%s, %s, 0x%x, 0x%x, %p)",dirname, filename, search_h, search_v, result); - sprintf(buffer, "%s/%s.h1", dirname, filename); - f_idx_h=file_create_caseinsensitive(buffer, 0); - if ((!f_idx_h) || (!file_mmap(f_idx_h))) - return 0; - sprintf(buffer, "%s/%s.v1", dirname, filename); - f_idx_v=file_create_caseinsensitive(buffer, 0); - dbg(lvl_debug,"%p %p", f_idx_h, f_idx_v); - if ((!f_idx_v) || (!file_mmap(f_idx_v))) { - file_destroy(f_idx_h); - return 0; - } - if ((h=tree_search_h(f_idx_h, search_h))) { - dbg(lvl_debug,"h=0x%x", h); - if ((v=tree_search_v(f_idx_v, h, search_v))) { - dbg(lvl_debug,"v=0x%x", v); - *result=v; - file_destroy(f_idx_v); - file_destroy(f_idx_h); - dbg(lvl_debug,"return 1"); - return 1; - } - } - file_destroy(f_idx_v); - file_destroy(f_idx_h); - dbg(lvl_debug,"return 0"); - return 0; + dbg(lvl_debug,"enter(%s, %s, 0x%x, 0x%x, %p)",dirname, filename, search_h, search_v, result); + sprintf(buffer, "%s/%s.h1", dirname, filename); + f_idx_h=file_create_caseinsensitive(buffer, 0); + if ((!f_idx_h) || (!file_mmap(f_idx_h))) + return 0; + sprintf(buffer, "%s/%s.v1", dirname, filename); + f_idx_v=file_create_caseinsensitive(buffer, 0); + dbg(lvl_debug,"%p %p", f_idx_h, f_idx_v); + if ((!f_idx_v) || (!file_mmap(f_idx_v))) { + file_destroy(f_idx_h); + return 0; + } + if ((h=tree_search_h(f_idx_h, search_h))) { + dbg(lvl_debug,"h=0x%x", h); + if ((v=tree_search_v(f_idx_v, h, search_v))) { + dbg(lvl_debug,"v=0x%x", v); + *result=v; + file_destroy(f_idx_v); + file_destroy(f_idx_h); + dbg(lvl_debug,"return 1"); + return 1; + } + } + file_destroy(f_idx_v); + file_destroy(f_idx_h); + dbg(lvl_debug,"return 0"); + return 0; } static struct tree_search_node * -tree_search_enter(struct tree_search *ts, int offset) -{ - struct tree_search_node *tsn=&ts->nodes[++ts->curr_node]; - unsigned char *p; - p=ts->f->begin+offset; - tsn->hdr=(struct tree_hdr *)p; - tsn->p=p+sizeof(struct tree_hdr); - tsn->last=tsn->p; - tsn->end=p+tree_hdr_get_size(tsn->hdr); - tsn->low=tree_hdr_get_low(tsn->hdr); - tsn->high=tree_hdr_get_low(tsn->hdr); - dbg(lvl_debug,"pos %td addr 0x%ux size 0x%ux low 0x%ux end %tu", p-ts->f->begin, tree_hdr_get_addr(tsn->hdr), tree_hdr_get_size(tsn->hdr), tree_hdr_get_low(tsn->hdr), tsn->end-ts->f->begin); - return tsn; +tree_search_enter(struct tree_search *ts, int offset) { + struct tree_search_node *tsn=&ts->nodes[++ts->curr_node]; + unsigned char *p; + p=ts->f->begin+offset; + tsn->hdr=(struct tree_hdr *)p; + tsn->p=p+sizeof(struct tree_hdr); + tsn->last=tsn->p; + tsn->end=p+tree_hdr_get_size(tsn->hdr); + tsn->low=tree_hdr_get_low(tsn->hdr); + tsn->high=tree_hdr_get_low(tsn->hdr); + dbg(lvl_debug,"pos %td addr 0x%ux size 0x%ux low 0x%ux end %tu", p-ts->f->begin, tree_hdr_get_addr(tsn->hdr), + tree_hdr_get_size(tsn->hdr), tree_hdr_get_low(tsn->hdr), tsn->end-ts->f->begin); + return tsn; } -int tree_search_next(struct tree_search *ts, unsigned char **p, int dir) -{ - struct tree_search_node *tsn=&ts->nodes[ts->curr_node]; +int tree_search_next(struct tree_search *ts, unsigned char **p, int dir) { + struct tree_search_node *tsn=&ts->nodes[ts->curr_node]; - if (! *p) - *p=tsn->p; - dbg(lvl_debug,"next *p=%p dir=%d", *p, dir); - dbg(lvl_debug,"low1=0x%x high1=0x%x", tsn->low, tsn->high); - if (dir <= 0) { - dbg(lvl_debug,"down 0x%x", tsn->low); - if (tsn->low != 0xffffffff) { - tsn=tree_search_enter(ts, tsn->low); - *p=tsn->p; - tsn->high=get_u32(p); - ts->last_node=ts->curr_node; - dbg(lvl_debug,"saving last2 %d %td", ts->curr_node, tsn->last-ts->f->begin); - dbg(lvl_debug,"high2=0x%x", tsn->high); - return 0; - } - return -1; - } - tsn->low=tsn->high; - tsn->last=*p; - tsn->high=get_u32_unal(p); - dbg(lvl_debug,"saving last3 %d %p", ts->curr_node, tsn->last); - if (*p < tsn->end) - return (tsn->low == 0xffffffff ? 1 : 0); - dbg(lvl_debug,"end reached high=0x%x",tsn->high); - if (tsn->low != 0xffffffff) { - dbg(lvl_debug,"low 0x%x", tsn->low); - tsn=tree_search_enter(ts, tsn->low); - *p=tsn->p; - tsn->high=get_u32_unal(p); - ts->last_node=ts->curr_node; - dbg(lvl_debug,"saving last4 %d %td", ts->curr_node, tsn->last-ts->f->begin); - dbg(lvl_debug,"high4=0x%x", tsn->high); - return 0; - } - return -1; + if (! *p) + *p=tsn->p; + dbg(lvl_debug,"next *p=%p dir=%d", *p, dir); + dbg(lvl_debug,"low1=0x%x high1=0x%x", tsn->low, tsn->high); + if (dir <= 0) { + dbg(lvl_debug,"down 0x%x", tsn->low); + if (tsn->low != 0xffffffff) { + tsn=tree_search_enter(ts, tsn->low); + *p=tsn->p; + tsn->high=get_u32(p); + ts->last_node=ts->curr_node; + dbg(lvl_debug,"saving last2 %d %td", ts->curr_node, tsn->last-ts->f->begin); + dbg(lvl_debug,"high2=0x%x", tsn->high); + return 0; + } + return -1; + } + tsn->low=tsn->high; + tsn->last=*p; + tsn->high=get_u32_unal(p); + dbg(lvl_debug,"saving last3 %d %p", ts->curr_node, tsn->last); + if (*p < tsn->end) + return (tsn->low == 0xffffffff ? 1 : 0); + dbg(lvl_debug,"end reached high=0x%x",tsn->high); + if (tsn->low != 0xffffffff) { + dbg(lvl_debug,"low 0x%x", tsn->low); + tsn=tree_search_enter(ts, tsn->low); + *p=tsn->p; + tsn->high=get_u32_unal(p); + ts->last_node=ts->curr_node; + dbg(lvl_debug,"saving last4 %d %td", ts->curr_node, tsn->last-ts->f->begin); + dbg(lvl_debug,"high4=0x%x", tsn->high); + return 0; + } + return -1; } -int tree_search_next_lin(struct tree_search *ts, unsigned char **p) -{ - struct tree_search_node *tsn=&ts->nodes[ts->curr_node]; - int high; - - dbg(lvl_debug,"pos=%d %td", ts->curr_node, *p-ts->f->begin); - if (*p) - ts->nodes[ts->last_node].last=*p; - *p=tsn->last; - for (;;) { - high=get_u32_unal(p); - if (*p < tsn->end) { - ts->last_node=ts->curr_node; - while (high != 0xffffffff) { - tsn=tree_search_enter(ts, high); - dbg(lvl_debug,"reload %d",ts->curr_node); - high=tsn->low; - } - return 1; - } - dbg(lvl_debug,"eon %d %td %td", ts->curr_node, *p-ts->f->begin, tsn->end-ts->f->begin); - if (! ts->curr_node) - break; - ts->curr_node--; - tsn=&ts->nodes[ts->curr_node]; - *p=tsn->last; - } +int tree_search_next_lin(struct tree_search *ts, unsigned char **p) { + struct tree_search_node *tsn=&ts->nodes[ts->curr_node]; + int high; + + dbg(lvl_debug,"pos=%d %td", ts->curr_node, *p-ts->f->begin); + if (*p) + ts->nodes[ts->last_node].last=*p; + *p=tsn->last; + for (;;) { + high=get_u32_unal(p); + if (*p < tsn->end) { + ts->last_node=ts->curr_node; + while (high != 0xffffffff) { + tsn=tree_search_enter(ts, high); + dbg(lvl_debug,"reload %d",ts->curr_node); + high=tsn->low; + } + return 1; + } + dbg(lvl_debug,"eon %d %td %td", ts->curr_node, *p-ts->f->begin, tsn->end-ts->f->begin); + if (! ts->curr_node) + break; + ts->curr_node--; + tsn=&ts->nodes[ts->curr_node]; + *p=tsn->last; + } - return 0; + return 0; } void -tree_search_init(char *dirname, char *filename, struct tree_search *ts, int offset) -{ - char buffer[4096]; - sprintf(buffer, "%s/%s", dirname, filename); - ts->f=file_create_caseinsensitive(buffer, 0); - ts->curr_node=-1; - if (ts->f) { - file_mmap(ts->f); - tree_search_enter(ts, offset); - } +tree_search_init(char *dirname, char *filename, struct tree_search *ts, int offset) { + char buffer[4096]; + sprintf(buffer, "%s/%s", dirname, filename); + ts->f=file_create_caseinsensitive(buffer, 0); + ts->curr_node=-1; + if (ts->f) { + file_mmap(ts->f); + tree_search_enter(ts, offset); + } } void -tree_search_free(struct tree_search *ts) -{ - if (ts->f) - file_destroy(ts->f); +tree_search_free(struct tree_search *ts) { + if (ts->f) + file_destroy(ts->f); } diff --git a/navit/map/shapefile/shapefile.c b/navit/map/shapefile/shapefile.c index 68c44272d..da818c215 100644 --- a/navit/map/shapefile/shapefile.c +++ b/navit/map/shapefile/shapefile.c @@ -42,647 +42,620 @@ #define IS_POLYGON(x) ((x).nSHPType == SHPT_POLYGON || (x).nSHPType == SHPT_POLYGONZ || (x).nSHPType == SHPT_POLYGONM) struct map_priv { - int id; - char *filename; - char *charset; - SHPHandle hSHP; - DBFHandle hDBF; - int nShapeType, nEntities, nFields; - double adfMinBound[4], adfMaxBound[4]; - struct longest_match *lm; - char *dbfmap_data; - struct coord offset; - enum projection pro; - int flags; + int id; + char *filename; + char *charset; + SHPHandle hSHP; + DBFHandle hDBF; + int nShapeType, nEntities, nFields; + double adfMinBound[4], adfMaxBound[4]; + struct longest_match *lm; + char *dbfmap_data; + struct coord offset; + enum projection pro; + int flags; }; struct map_rect_priv { - struct map_selection *sel; - struct map_priv *m; - struct item item; - int idx; - int cidx,cidx_rewind; - int part,part_rewind; - int aidx; - enum attr_type anext; - SHPObject *psShape; - char *str; - char *line; - int attr_pos; - struct attr *attr; + struct map_selection *sel; + struct map_priv *m; + struct item item; + int idx; + int cidx,cidx_rewind; + int part,part_rewind; + int aidx; + enum attr_type anext; + SHPObject *psShape; + char *str; + char *line; + int attr_pos; + struct attr *attr; }; static void -map_destroy_shapefile(struct map_priv *m) -{ - dbg(lvl_debug,"map_destroy_shapefile"); - g_free(m); +map_destroy_shapefile(struct map_priv *m) { + dbg(lvl_debug,"map_destroy_shapefile"); + g_free(m); } static void -shapefile_coord_rewind(void *priv_data) -{ - struct map_rect_priv *mr=priv_data; - mr->cidx=mr->cidx_rewind; - mr->part=mr->part_rewind; +shapefile_coord_rewind(void *priv_data) { + struct map_rect_priv *mr=priv_data; + mr->cidx=mr->cidx_rewind; + mr->part=mr->part_rewind; } static void -shapefile_coord(struct map_rect_priv *mr, int idx, struct coord *c) -{ - SHPObject *psShape=mr->psShape; - struct coord cs; - struct coord_geo g; - - if (!mr->m->pro) { - g.lng=psShape->padfX[idx]+mr->m->offset.x; - g.lat=psShape->padfY[idx]+mr->m->offset.y; - transform_from_geo(projection_mg, &g, c); - } else { - cs.x=psShape->padfX[idx]+mr->m->offset.x; - cs.y=psShape->padfY[idx]+mr->m->offset.y; - transform_from_to(&cs, mr->m->pro, c, projection_mg); - } +shapefile_coord(struct map_rect_priv *mr, int idx, struct coord *c) { + SHPObject *psShape=mr->psShape; + struct coord cs; + struct coord_geo g; + + if (!mr->m->pro) { + g.lng=psShape->padfX[idx]+mr->m->offset.x; + g.lat=psShape->padfY[idx]+mr->m->offset.y; + transform_from_geo(projection_mg, &g, c); + } else { + cs.x=psShape->padfX[idx]+mr->m->offset.x; + cs.y=psShape->padfY[idx]+mr->m->offset.y; + transform_from_to(&cs, mr->m->pro, c, projection_mg); + } } static int -shapefile_coord_get(void *priv_data, struct coord *c, int count) -{ - struct map_rect_priv *mr=priv_data; - int ret=0; - int idx; - - SHPObject *psShape=mr->psShape; - while (count) { - idx=mr->cidx; - if (idx >= psShape->nVertices) - break; - if (mr->part+1 < psShape->nParts && idx == psShape->panPartStart[mr->part+1]) { - if (IS_POLYGON(*psShape)) { - mr->part++; - shapefile_coord(mr, 0, c); - } else if (IS_ARC(*psShape)) { - break; - } else { - dbg_assert("Neither POLYGON or ARC and has parts" == NULL); - } - } else { - shapefile_coord(mr, idx, c); - mr->cidx++; - } - ret++; - c++; - count--; - } - return ret; +shapefile_coord_get(void *priv_data, struct coord *c, int count) { + struct map_rect_priv *mr=priv_data; + int ret=0; + int idx; + + SHPObject *psShape=mr->psShape; + while (count) { + idx=mr->cidx; + if (idx >= psShape->nVertices) + break; + if (mr->part+1 < psShape->nParts && idx == psShape->panPartStart[mr->part+1]) { + if (IS_POLYGON(*psShape)) { + mr->part++; + shapefile_coord(mr, 0, c); + } else if (IS_ARC(*psShape)) { + break; + } else { + dbg_assert("Neither POLYGON or ARC and has parts" == NULL); + } + } else { + shapefile_coord(mr, idx, c); + mr->cidx++; + } + ret++; + c++; + count--; + } + return ret; } static void -shapefile_attr_rewind(void *priv_data) -{ - struct map_rect_priv *mr=priv_data; - mr->aidx=0; - mr->attr_pos=0; - if (mr->m->flags & 1) - mr->anext=attr_none; - else - mr->anext=attr_debug; +shapefile_attr_rewind(void *priv_data) { + struct map_rect_priv *mr=priv_data; + mr->aidx=0; + mr->attr_pos=0; + if (mr->m->flags & 1) + mr->anext=attr_none; + else + mr->anext=attr_debug; } struct longest_match_list_item { - void *data; - int match_idx_count; - int *match_idx; + void *data; + int match_idx_count; + int *match_idx; }; struct longest_match_list { - GList *longest_match_list_items; + GList *longest_match_list_items; }; struct longest_match { - GHashTable *match_hash; - char *match_present; - int match_present_count; - GList *longest_match_lists; - int longest_match_list_count; + GHashTable *match_hash; + char *match_present; + int match_present_count; + GList *longest_match_lists; + int longest_match_list_count; }; static void -longest_match_add_match(struct longest_match *lm, struct longest_match_list_item *lmi, char *match) -{ - int idx; - if (!(idx=(int)(long)g_hash_table_lookup(lm->match_hash, match))) { - idx=lm->match_present_count++; - lm->match_present=g_renew(char, lm->match_present, lm->match_present_count); - g_hash_table_insert(lm->match_hash, g_strdup(match), (gpointer)(long)idx); - } - lmi->match_idx=g_renew(int, lmi->match_idx, lmi->match_idx_count+1); - lmi->match_idx[lmi->match_idx_count++]=idx; +longest_match_add_match(struct longest_match *lm, struct longest_match_list_item *lmi, char *match) { + int idx; + if (!(idx=(int)(long)g_hash_table_lookup(lm->match_hash, match))) { + idx=lm->match_present_count++; + lm->match_present=g_renew(char, lm->match_present, lm->match_present_count); + g_hash_table_insert(lm->match_hash, g_strdup(match), (gpointer)(long)idx); + } + lmi->match_idx=g_renew(int, lmi->match_idx, lmi->match_idx_count+1); + lmi->match_idx[lmi->match_idx_count++]=idx; } static void -longest_match_item_destroy(struct longest_match_list_item *lmi, long flags) -{ - if (!lmi) - return; - if (flags & 2) { - g_free(lmi->data); - } - g_free(lmi->match_idx); - g_free(lmi); +longest_match_item_destroy(struct longest_match_list_item *lmi, long flags) { + if (!lmi) + return; + if (flags & 2) { + g_free(lmi->data); + } + g_free(lmi->match_idx); + g_free(lmi); } static struct longest_match_list_item * -longest_match_item_new(struct longest_match_list *lml, void *data) -{ - struct longest_match_list_item *ret=g_new0(struct longest_match_list_item,1); - lml->longest_match_list_items=g_list_append(lml->longest_match_list_items, ret); - ret->data=data; +longest_match_item_new(struct longest_match_list *lml, void *data) { + struct longest_match_list_item *ret=g_new0(struct longest_match_list_item,1); + lml->longest_match_list_items=g_list_append(lml->longest_match_list_items, ret); + ret->data=data; - return ret; + return ret; } static struct longest_match_list * -longest_match_list_new(struct longest_match *lm) -{ - struct longest_match_list *ret=g_new0(struct longest_match_list,1); - lm->longest_match_lists=g_list_append(lm->longest_match_lists, ret); - return ret; +longest_match_list_new(struct longest_match *lm) { + struct longest_match_list *ret=g_new0(struct longest_match_list,1); + lm->longest_match_lists=g_list_append(lm->longest_match_lists, ret); + return ret; } static void -longest_match_list_destroy(struct longest_match_list *lml, long flags) -{ - if (!lml) - return; - if (flags & 1) { - g_list_foreach(lml->longest_match_list_items, (GFunc)longest_match_item_destroy, (gpointer)flags); - g_list_free(lml->longest_match_list_items); - } - g_free(lml); +longest_match_list_destroy(struct longest_match_list *lml, long flags) { + if (!lml) + return; + if (flags & 1) { + g_list_foreach(lml->longest_match_list_items, (GFunc)longest_match_item_destroy, (gpointer)flags); + g_list_free(lml->longest_match_list_items); + } + g_free(lml); } static struct longest_match_list * -longest_match_get_list(struct longest_match *lm, int list) -{ - GList *l=lm->longest_match_lists; - while (l && list > 0) { - l=g_list_next(l); - list++; - } - if (l) - return l->data; - return NULL; +longest_match_get_list(struct longest_match *lm, int list) { + GList *l=lm->longest_match_lists; + while (l && list > 0) { + l=g_list_next(l); + list++; + } + if (l) + return l->data; + return NULL; } static struct longest_match * -longest_match_new(void) -{ - struct longest_match *ret=g_new0(struct longest_match,1); - ret->match_hash=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); - ret->match_present_count=1; - return ret; +longest_match_new(void) { + struct longest_match *ret=g_new0(struct longest_match,1); + ret->match_hash=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + ret->match_present_count=1; + return ret; } static void -longest_match_destroy(struct longest_match *lm, long flags) -{ - if (!lm) - return; - if (flags & 1) { - g_list_foreach(lm->longest_match_lists, (GFunc)longest_match_list_destroy, (gpointer)flags); - g_list_free(lm->longest_match_lists); - } - g_hash_table_destroy(lm->match_hash); - g_free(lm->match_present); - g_free(lm); +longest_match_destroy(struct longest_match *lm, long flags) { + if (!lm) + return; + if (flags & 1) { + g_list_foreach(lm->longest_match_lists, (GFunc)longest_match_list_destroy, (gpointer)flags); + g_list_free(lm->longest_match_lists); + } + g_hash_table_destroy(lm->match_hash); + g_free(lm->match_present); + g_free(lm); } static void -longest_match_clear(struct longest_match *lm) -{ - if (lm->match_present) - memset(lm->match_present, 0, lm->match_present_count); +longest_match_clear(struct longest_match *lm) { + if (lm->match_present) + memset(lm->match_present, 0, lm->match_present_count); } static void -longest_match_add_key_value(struct longest_match *lm, char *k, char *v) -{ - char* buffer=g_alloca(strlen(k)+strlen(v)+2); - int idx; +longest_match_add_key_value(struct longest_match *lm, char *k, char *v) { + char* buffer=g_alloca(strlen(k)+strlen(v)+2); + int idx; - strcpy(buffer,"*=*"); - if ((idx=(int)(long)g_hash_table_lookup(lm->match_hash, buffer))) - lm->match_present[idx]=1; + strcpy(buffer,"*=*"); + if ((idx=(int)(long)g_hash_table_lookup(lm->match_hash, buffer))) + lm->match_present[idx]=1; - sprintf(buffer,"%s=*", k); - if ((idx=(int)(long)g_hash_table_lookup(lm->match_hash, buffer))) - lm->match_present[idx]=2; + sprintf(buffer,"%s=*", k); + if ((idx=(int)(long)g_hash_table_lookup(lm->match_hash, buffer))) + lm->match_present[idx]=2; - sprintf(buffer,"*=%s", v); - if ((idx=(int)(long)g_hash_table_lookup(lm->match_hash, buffer))) - lm->match_present[idx]=2; + sprintf(buffer,"*=%s", v); + if ((idx=(int)(long)g_hash_table_lookup(lm->match_hash, buffer))) + lm->match_present[idx]=2; - sprintf(buffer,"%s=%s", k, v); - if ((idx=(int)(long)g_hash_table_lookup(lm->match_hash, buffer))) - lm->match_present[idx]=4; + sprintf(buffer,"%s=%s", k, v); + if ((idx=(int)(long)g_hash_table_lookup(lm->match_hash, buffer))) + lm->match_present[idx]=4; } static int -longest_match_list_find(struct longest_match *lm, struct longest_match_list *lml, void **list, int max_list_len) -{ - int j,longest=0,ret=0,sum,val; - struct longest_match_list_item *curr; - GList *l=lml->longest_match_list_items; - - - while (l) { - sum=0; - curr=l->data; - for (j = 0 ; j < curr->match_idx_count ; j++) { - val=lm->match_present[curr->match_idx[j]]; - if (val) - sum+=val; - else { - sum=-1; - break; - } - } - if (sum > longest) { - longest=sum; - ret=0; - } - if (sum > 0 && sum == longest && ret < max_list_len) - list[ret++]=curr->data; - l=g_list_next(l); - } - return ret; +longest_match_list_find(struct longest_match *lm, struct longest_match_list *lml, void **list, int max_list_len) { + int j,longest=0,ret=0,sum,val; + struct longest_match_list_item *curr; + GList *l=lml->longest_match_list_items; + + + while (l) { + sum=0; + curr=l->data; + for (j = 0 ; j < curr->match_idx_count ; j++) { + val=lm->match_present[curr->match_idx[j]]; + if (val) + sum+=val; + else { + sum=-1; + break; + } + } + if (sum > longest) { + longest=sum; + ret=0; + } + if (sum > 0 && sum == longest && ret < max_list_len) + list[ret++]=curr->data; + l=g_list_next(l); + } + return ret; } static void -build_match(struct longest_match *lm, struct longest_match_list *lml, char *line) -{ - struct longest_match_list_item *lmli; - char *kvl=NULL,*i=NULL,*p,*kv; - dbg(lvl_debug,"line=%s",line); - kvl=line; - p=strchr(line,'\t'); - if (p) { - while (*p == '\t') - *p++='\0'; - i=p; - } - lmli=longest_match_item_new(lml,g_strdup(i)); - while ((kv=strtok(kvl, ","))) { - kvl=NULL; - longest_match_add_match(lm, lmli, kv); - } +build_match(struct longest_match *lm, struct longest_match_list *lml, char *line) { + struct longest_match_list_item *lmli; + char *kvl=NULL,*i=NULL,*p,*kv; + dbg(lvl_debug,"line=%s",line); + kvl=line; + p=strchr(line,'\t'); + if (p) { + while (*p == '\t') + *p++='\0'; + i=p; + } + lmli=longest_match_item_new(lml,g_strdup(i)); + while ((kv=strtok(kvl, ","))) { + kvl=NULL; + longest_match_add_match(lm, lmli, kv); + } } static void -build_matches(struct map_priv *m,char *matches) -{ - char *matches2=g_strdup(matches); - char *l=matches2,*p; - struct longest_match_list *lml; - - m->lm=longest_match_new(); - lml=longest_match_list_new(m->lm); - while (l) { - p=strchr(l,'\n'); - if (p) - *p++='\0'; - if (strlen(l)) - build_match(m->lm,lml,l); - l=p; - } - g_free(matches2); +build_matches(struct map_priv *m,char *matches) { + char *matches2=g_strdup(matches); + char *l=matches2,*p; + struct longest_match_list *lml; + + m->lm=longest_match_new(); + lml=longest_match_list_new(m->lm); + while (l) { + p=strchr(l,'\n'); + if (p) + *p++='\0'; + if (strlen(l)) + build_match(m->lm,lml,l); + l=p; + } + g_free(matches2); } static void -process_fields(struct map_priv *m, int id) -{ - int i; - char szTitle[12],*str; - int nWidth, nDecimals; - - for (i = 0 ; i < m->nFields ; i++) { - - switch (DBFGetFieldInfo(m->hDBF, i, szTitle, &nWidth, &nDecimals )) { - case FTString: - str=g_strdup(DBFReadStringAttribute( m->hDBF, id, i )); - break; - case FTInteger: - str=g_strdup_printf("%d",DBFReadIntegerAttribute( m->hDBF, id, i )); - break; - case FTDouble: - str=g_strdup_printf("%lf",DBFReadDoubleAttribute( m->hDBF, id, i )); - break; - case FTInvalid: - str=NULL; - break; - default: - str=NULL; - } - longest_match_add_key_value(m->lm, szTitle, str); - } +process_fields(struct map_priv *m, int id) { + int i; + char szTitle[12],*str; + int nWidth, nDecimals; + + for (i = 0 ; i < m->nFields ; i++) { + + switch (DBFGetFieldInfo(m->hDBF, i, szTitle, &nWidth, &nDecimals )) { + case FTString: + str=g_strdup(DBFReadStringAttribute( m->hDBF, id, i )); + break; + case FTInteger: + str=g_strdup_printf("%d",DBFReadIntegerAttribute( m->hDBF, id, i )); + break; + case FTDouble: + str=g_strdup_printf("%lf",DBFReadDoubleAttribute( m->hDBF, id, i )); + break; + case FTInvalid: + str=NULL; + break; + default: + str=NULL; + } + longest_match_add_key_value(m->lm, szTitle, str); + } } static int -attr_resolve(struct map_rect_priv *mr, enum attr_type attr_type, struct attr *attr) -{ - char name[1024]; - char value[1024]; - char szTitle[12]; - const char *str; - char *col,*type=NULL; - int i,len, nWidth, nDecimals; - if (!mr->line) - return 0; - if (attr_type != attr_any) - type=attr_to_name(attr_type); - if (attr_from_line(mr->line,type,&mr->attr_pos,value,name)) { - len=strlen(value); - if (value[0] == '$' && value[1] == '{' && value[len-1] == '}') { - int found=0; - value[len-1]='\0'; - col=value+2; - for (i = 0 ; i < mr->m->nFields ; i++) { - if (DBFGetFieldInfo(mr->m->hDBF, i, szTitle, &nWidth, &nDecimals ) == FTString && !strcmp(szTitle,col)) { - str=DBFReadStringAttribute( mr->m->hDBF, mr->item.id_hi, i); - strcpy(value,str); - found=1; - break; - } - } - if (!found) - value[0]='\0'; - } - if (!value[0]) - return -1; - dbg(lvl_debug,"name=%s value=%s",name,value); - attr_free(mr->attr); - mr->attr=attr_new_from_text(name,value); - if (mr->attr) { - *attr=*mr->attr; - return 1; - } - return -1; - } - return 0; +attr_resolve(struct map_rect_priv *mr, enum attr_type attr_type, struct attr *attr) { + char name[1024]; + char value[1024]; + char szTitle[12]; + const char *str; + char *col,*type=NULL; + int i,len, nWidth, nDecimals; + if (!mr->line) + return 0; + if (attr_type != attr_any) + type=attr_to_name(attr_type); + if (attr_from_line(mr->line,type,&mr->attr_pos,value,name)) { + len=strlen(value); + if (value[0] == '$' && value[1] == '{' && value[len-1] == '}') { + int found=0; + value[len-1]='\0'; + col=value+2; + for (i = 0 ; i < mr->m->nFields ; i++) { + if (DBFGetFieldInfo(mr->m->hDBF, i, szTitle, &nWidth, &nDecimals ) == FTString && !strcmp(szTitle,col)) { + str=DBFReadStringAttribute( mr->m->hDBF, mr->item.id_hi, i); + strcpy(value,str); + found=1; + break; + } + } + if (!found) + value[0]='\0'; + } + if (!value[0]) + return -1; + dbg(lvl_debug,"name=%s value=%s",name,value); + attr_free(mr->attr); + mr->attr=attr_new_from_text(name,value); + if (mr->attr) { + *attr=*mr->attr; + return 1; + } + return -1; + } + return 0; } static int -shapefile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct map_rect_priv *mr=priv_data; - struct map_priv *m=mr->m; - char szTitle[12],*pszTypeName, *str; - int code, ret, nWidth, nDecimals; - - attr->type=attr_type; - switch (attr_type) { - case attr_any: - while ((code=attr_resolve(mr, attr_type, attr))) { - if (code == 1) - return 1; - } - while (mr->anext != attr_none) { - ret=shapefile_attr_get(priv_data, mr->anext, attr); - if (ret) - return ret; - } - return 0; - case attr_debug: - if (mr->aidx >= m->nFields) { - mr->anext=attr_none; - return 0; - } - switch (DBFGetFieldInfo(m->hDBF, mr->aidx, szTitle, &nWidth, &nDecimals )) { - case FTString: - pszTypeName = "String"; - str=g_strdup(DBFReadStringAttribute( m->hDBF, mr->item.id_hi, mr->aidx )); - break; - case FTInteger: - pszTypeName = "Integer"; - str=g_strdup_printf("%d",DBFReadIntegerAttribute( m->hDBF, mr->item.id_hi, mr->aidx )); - break; - case FTDouble: - pszTypeName = "Double"; - str=g_strdup_printf("%lf",DBFReadDoubleAttribute( m->hDBF, mr->item.id_hi, mr->aidx )); - break; - case FTInvalid: - pszTypeName = "Invalid"; - str=NULL; - break; - default: - pszTypeName = "Unknown"; - str=NULL; - } - g_free(mr->str); - mr->str=attr->u.str=g_strdup_printf("%s=%s(%s)",szTitle,str,pszTypeName); - g_free(str); - mr->aidx++; - return 1; - default: - return (attr_resolve(mr, attr_type, attr) == 1); - } +shapefile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct map_rect_priv *mr=priv_data; + struct map_priv *m=mr->m; + char szTitle[12],*pszTypeName, *str; + int code, ret, nWidth, nDecimals; + + attr->type=attr_type; + switch (attr_type) { + case attr_any: + while ((code=attr_resolve(mr, attr_type, attr))) { + if (code == 1) + return 1; + } + while (mr->anext != attr_none) { + ret=shapefile_attr_get(priv_data, mr->anext, attr); + if (ret) + return ret; + } + return 0; + case attr_debug: + if (mr->aidx >= m->nFields) { + mr->anext=attr_none; + return 0; + } + switch (DBFGetFieldInfo(m->hDBF, mr->aidx, szTitle, &nWidth, &nDecimals )) { + case FTString: + pszTypeName = "String"; + str=g_strdup(DBFReadStringAttribute( m->hDBF, mr->item.id_hi, mr->aidx )); + break; + case FTInteger: + pszTypeName = "Integer"; + str=g_strdup_printf("%d",DBFReadIntegerAttribute( m->hDBF, mr->item.id_hi, mr->aidx )); + break; + case FTDouble: + pszTypeName = "Double"; + str=g_strdup_printf("%lf",DBFReadDoubleAttribute( m->hDBF, mr->item.id_hi, mr->aidx )); + break; + case FTInvalid: + pszTypeName = "Invalid"; + str=NULL; + break; + default: + pszTypeName = "Unknown"; + str=NULL; + } + g_free(mr->str); + mr->str=attr->u.str=g_strdup_printf("%s=%s(%s)",szTitle,str,pszTypeName); + g_free(str); + mr->aidx++; + return 1; + default: + return (attr_resolve(mr, attr_type, attr) == 1); + } } static struct item_methods methods_shapefile = { - shapefile_coord_rewind, - shapefile_coord_get, - shapefile_attr_rewind, - shapefile_attr_get, + shapefile_coord_rewind, + shapefile_coord_get, + shapefile_attr_rewind, + shapefile_attr_get, }; static struct map_rect_priv * -map_rect_new_shapefile(struct map_priv *map, struct map_selection *sel) -{ - struct map_rect_priv *mr; - char *dbfmapfile=g_strdup_printf("%s.dbfmap", map->filename); - void *data; - struct file *file; - int size; - int changed=0; - if ((file=file_create(dbfmapfile, 0))) { - size=file_size(file); - data=file_data_read_all(file); - if (data) { - if (!map->dbfmap_data || size != strlen(map->dbfmap_data) || strncmp(data,map->dbfmap_data,size)) { - g_free(map->dbfmap_data); - map->dbfmap_data=g_malloc(size+1); - memcpy(map->dbfmap_data, data, size); - map->dbfmap_data[size]='\0'; - changed=1; - } - file_data_free(file, data); - } - file_destroy(file); - } else { - dbg(lvl_error,"Failed to open %s",dbfmapfile); - if (map->dbfmap_data) { - changed=1; - g_free(map->dbfmap_data); - map->dbfmap_data=NULL; - } - } - dbg(lvl_debug,"%s changed %d old %p",dbfmapfile,changed,map->dbfmap_data); - if (changed) { - longest_match_destroy(map->lm,1); - map->lm=NULL; - if (map->dbfmap_data) { - build_matches(map,map->dbfmap_data); - } - } - dbg(lvl_debug,"map_rect_new_shapefile"); - mr=g_new0(struct map_rect_priv, 1); - mr->m=map; - mr->idx=0; - mr->item.id_lo=0; - mr->item.id_hi=0; - mr->item.meth=&methods_shapefile; - mr->item.priv_data=mr; - g_free(dbfmapfile); - return mr; +map_rect_new_shapefile(struct map_priv *map, struct map_selection *sel) { + struct map_rect_priv *mr; + char *dbfmapfile=g_strdup_printf("%s.dbfmap", map->filename); + void *data; + struct file *file; + int size; + int changed=0; + if ((file=file_create(dbfmapfile, 0))) { + size=file_size(file); + data=file_data_read_all(file); + if (data) { + if (!map->dbfmap_data || size != strlen(map->dbfmap_data) || strncmp(data,map->dbfmap_data,size)) { + g_free(map->dbfmap_data); + map->dbfmap_data=g_malloc(size+1); + memcpy(map->dbfmap_data, data, size); + map->dbfmap_data[size]='\0'; + changed=1; + } + file_data_free(file, data); + } + file_destroy(file); + } else { + dbg(lvl_error,"Failed to open %s",dbfmapfile); + if (map->dbfmap_data) { + changed=1; + g_free(map->dbfmap_data); + map->dbfmap_data=NULL; + } + } + dbg(lvl_debug,"%s changed %d old %p",dbfmapfile,changed,map->dbfmap_data); + if (changed) { + longest_match_destroy(map->lm,1); + map->lm=NULL; + if (map->dbfmap_data) { + build_matches(map,map->dbfmap_data); + } + } + dbg(lvl_debug,"map_rect_new_shapefile"); + mr=g_new0(struct map_rect_priv, 1); + mr->m=map; + mr->idx=0; + mr->item.id_lo=0; + mr->item.id_hi=0; + mr->item.meth=&methods_shapefile; + mr->item.priv_data=mr; + g_free(dbfmapfile); + return mr; } static void -map_rect_destroy_shapefile(struct map_rect_priv *mr) -{ - if (mr->psShape) - SHPDestroyObject(mr->psShape); - attr_free(mr->attr); - g_free(mr->str); - g_free(mr); +map_rect_destroy_shapefile(struct map_rect_priv *mr) { + if (mr->psShape) + SHPDestroyObject(mr->psShape); + attr_free(mr->attr); + g_free(mr->str); + g_free(mr); } static struct item * -map_rect_get_item_shapefile(struct map_rect_priv *mr) -{ - struct map_priv *m=mr->m; - void *lines[5]; - struct longest_match_list *lml; - int count; - char type[1024]; - - if (mr->psShape && IS_ARC(*mr->psShape) && mr->part+1 < mr->psShape->nParts) { - mr->part++; - mr->part_rewind=mr->part; - mr->cidx_rewind=mr->psShape->panPartStart[mr->part]; - } else { - if (mr->idx >= m->nEntities) - return NULL; - mr->item.id_hi=mr->idx; - if (mr->psShape) - SHPDestroyObject(mr->psShape); - mr->psShape=SHPReadObject(m->hSHP, mr->idx); - if (mr->psShape->nVertices > 1) - mr->item.type=type_street_unkn; - else - mr->item.type=type_point_unkn; - if (m->lm) { - longest_match_clear(m->lm); - process_fields(m, mr->idx); - - lml=longest_match_get_list(m->lm, 0); - count=longest_match_list_find(m->lm, lml, lines, sizeof(lines)/sizeof(void *)); - if (count) { - mr->line=lines[0]; - if (attr_from_line(mr->line,"type",NULL,type,NULL)) { - dbg(lvl_debug,"type='%s'", type); - mr->item.type=item_from_name(type); - if (mr->item.type == type_none && strcmp(type,"none")) - dbg(lvl_error,"Warning: type '%s' unknown", type); - } else { - dbg(lvl_debug,"failed to get attribute type"); - } - } else - mr->line=NULL; - } - mr->idx++; - mr->part_rewind=0; - mr->cidx_rewind=0; - } - shapefile_coord_rewind(mr); - shapefile_attr_rewind(mr); - return &mr->item; +map_rect_get_item_shapefile(struct map_rect_priv *mr) { + struct map_priv *m=mr->m; + void *lines[5]; + struct longest_match_list *lml; + int count; + char type[1024]; + + if (mr->psShape && IS_ARC(*mr->psShape) && mr->part+1 < mr->psShape->nParts) { + mr->part++; + mr->part_rewind=mr->part; + mr->cidx_rewind=mr->psShape->panPartStart[mr->part]; + } else { + if (mr->idx >= m->nEntities) + return NULL; + mr->item.id_hi=mr->idx; + if (mr->psShape) + SHPDestroyObject(mr->psShape); + mr->psShape=SHPReadObject(m->hSHP, mr->idx); + if (mr->psShape->nVertices > 1) + mr->item.type=type_street_unkn; + else + mr->item.type=type_point_unkn; + if (m->lm) { + longest_match_clear(m->lm); + process_fields(m, mr->idx); + + lml=longest_match_get_list(m->lm, 0); + count=longest_match_list_find(m->lm, lml, lines, sizeof(lines)/sizeof(void *)); + if (count) { + mr->line=lines[0]; + if (attr_from_line(mr->line,"type",NULL,type,NULL)) { + dbg(lvl_debug,"type='%s'", type); + mr->item.type=item_from_name(type); + if (mr->item.type == type_none && strcmp(type,"none")) + dbg(lvl_error,"Warning: type '%s' unknown", type); + } else { + dbg(lvl_debug,"failed to get attribute type"); + } + } else + mr->line=NULL; + } + mr->idx++; + mr->part_rewind=0; + mr->cidx_rewind=0; + } + shapefile_coord_rewind(mr); + shapefile_attr_rewind(mr); + return &mr->item; } static struct item * -map_rect_get_item_byid_shapefile(struct map_rect_priv *mr, int id_hi, int id_lo) -{ - mr->idx=id_hi; - while (id_lo--) { - if (!map_rect_get_item_shapefile(mr)) - return NULL; - } - return map_rect_get_item_shapefile(mr); +map_rect_get_item_byid_shapefile(struct map_rect_priv *mr, int id_hi, int id_lo) { + mr->idx=id_hi; + while (id_lo--) { + if (!map_rect_get_item_shapefile(mr)) + return NULL; + } + return map_rect_get_item_shapefile(mr); } static struct map_methods map_methods_shapefile = { - projection_mg, - "iso8859-1", - map_destroy_shapefile, - map_rect_new_shapefile, - map_rect_destroy_shapefile, - map_rect_get_item_shapefile, - map_rect_get_item_byid_shapefile, + projection_mg, + "iso8859-1", + map_destroy_shapefile, + map_rect_new_shapefile, + map_rect_destroy_shapefile, + map_rect_get_item_shapefile, + map_rect_get_item_byid_shapefile, }; static struct map_priv * -map_new_shapefile(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) -{ - struct map_priv *m; - struct attr *data=attr_search(attrs, NULL, attr_data); - struct attr *charset=attr_search(attrs, NULL, attr_charset); - struct attr *projectionname=attr_search(attrs, NULL, attr_projectionname); - struct attr *flags=attr_search(attrs, NULL, attr_flags); - struct file_wordexp *wexp; - char *wdata; - char **wexp_data; - char *shapefile,*dbffile; - if (! data) - return NULL; - dbg(lvl_debug,"map_new_shapefile %s", data->u.str); - wdata=g_strdup(data->u.str); - wexp=file_wordexp_new(wdata); - wexp_data=file_wordexp_get_array(wexp); - *meth=map_methods_shapefile; - - m=g_new0(struct map_priv, 1); - m->filename=g_strdup(wexp_data[0]); - shapefile=g_strdup_printf("%s.shp", m->filename); - m->hSHP=SHPOpen(shapefile, "rb" ); - SHPGetInfo( m->hSHP, &m->nEntities, &m->nShapeType, m->adfMinBound, m->adfMaxBound ); - g_free(shapefile); - dbffile=g_strdup_printf("%s.dbf", m->filename); - m->hDBF=DBFOpen(dbffile, "rb"); - m->nFields=DBFGetFieldCount(m->hDBF); - g_free(dbffile); - dbg(lvl_debug,"map_new_shapefile %s %s", m->filename, wdata); - if (charset) { - m->charset=g_strdup(charset->u.str); - meth->charset=m->charset; - } - if (projectionname) - m->pro=projection_from_name(projectionname->u.str, &m->offset); - if (flags) - m->flags=flags->u.num; - file_wordexp_destroy(wexp); - return m; +map_new_shapefile(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) { + struct map_priv *m; + struct attr *data=attr_search(attrs, NULL, attr_data); + struct attr *charset=attr_search(attrs, NULL, attr_charset); + struct attr *projectionname=attr_search(attrs, NULL, attr_projectionname); + struct attr *flags=attr_search(attrs, NULL, attr_flags); + struct file_wordexp *wexp; + char *wdata; + char **wexp_data; + char *shapefile,*dbffile; + if (! data) + return NULL; + dbg(lvl_debug,"map_new_shapefile %s", data->u.str); + wdata=g_strdup(data->u.str); + wexp=file_wordexp_new(wdata); + wexp_data=file_wordexp_get_array(wexp); + *meth=map_methods_shapefile; + + m=g_new0(struct map_priv, 1); + m->filename=g_strdup(wexp_data[0]); + shapefile=g_strdup_printf("%s.shp", m->filename); + m->hSHP=SHPOpen(shapefile, "rb" ); + SHPGetInfo( m->hSHP, &m->nEntities, &m->nShapeType, m->adfMinBound, m->adfMaxBound ); + g_free(shapefile); + dbffile=g_strdup_printf("%s.dbf", m->filename); + m->hDBF=DBFOpen(dbffile, "rb"); + m->nFields=DBFGetFieldCount(m->hDBF); + g_free(dbffile); + dbg(lvl_debug,"map_new_shapefile %s %s", m->filename, wdata); + if (charset) { + m->charset=g_strdup(charset->u.str); + meth->charset=m->charset; + } + if (projectionname) + m->pro=projection_from_name(projectionname->u.str, &m->offset); + if (flags) + m->flags=flags->u.num; + file_wordexp_destroy(wexp); + return m; } void -plugin_init(void) -{ - dbg(lvl_debug,"shapefile: plugin_init"); - plugin_register_category_map("shapefile", map_new_shapefile); +plugin_init(void) { + dbg(lvl_debug,"shapefile: plugin_init"); + plugin_register_category_map("shapefile", map_new_shapefile); } /************************************************************************/ @@ -692,7 +665,7 @@ plugin_init(void) static SAFile VSI_SHP_Open( const char *pszFilename, const char *pszAccess ) { - return (SAFile)fopen(pszFilename, pszAccess); + return (SAFile)fopen(pszFilename, pszAccess); } /************************************************************************/ @@ -702,7 +675,7 @@ static SAFile VSI_SHP_Open( const char *pszFilename, const char *pszAccess ) static SAOffset VSI_SHP_Read( void *p, SAOffset size, SAOffset nmemb, SAFile file ) { - return fread(p, size, nmemb, (FILE *)file); + return fread(p, size, nmemb, (FILE *)file); } /************************************************************************/ @@ -712,7 +685,7 @@ static SAOffset VSI_SHP_Read( void *p, SAOffset size, SAOffset nmemb, SAFile fil static SAOffset VSI_SHP_Write( void *p, SAOffset size, SAOffset nmemb, SAFile file ) { - return fwrite(p, size, nmemb, (FILE *)file); + return fwrite(p, size, nmemb, (FILE *)file); } /************************************************************************/ @@ -722,7 +695,7 @@ static SAOffset VSI_SHP_Write( void *p, SAOffset size, SAOffset nmemb, SAFile fi static SAOffset VSI_SHP_Seek( SAFile file, SAOffset offset, int whence ) { - return fseek((FILE *)file, offset, whence); + return fseek((FILE *)file, offset, whence); } /************************************************************************/ @@ -732,14 +705,14 @@ static SAOffset VSI_SHP_Seek( SAFile file, SAOffset offset, int whence ) static SAOffset VSI_SHP_Tell( SAFile file ) { - return ftell((FILE *)file); + return ftell((FILE *)file); } static int VSI_SHP_Flush( SAFile file ) { - return fflush((FILE *)file); + return fflush((FILE *)file); } /************************************************************************/ @@ -749,7 +722,7 @@ static int VSI_SHP_Flush( SAFile file ) static int VSI_SHP_Close( SAFile file ) { - return fclose((FILE *)file); + return fclose((FILE *)file); } /************************************************************************/ @@ -759,7 +732,7 @@ static int VSI_SHP_Close( SAFile file ) static void VSI_SHP_Error( const char *message ) { - dbg(lvl_error,"error:%s", message); + dbg(lvl_error,"error:%s", message); } /************************************************************************/ @@ -769,7 +742,7 @@ static void VSI_SHP_Error( const char *message ) static int VSI_SHP_Remove( const char *pszFilename ) { - return unlink(pszFilename); + return unlink(pszFilename); } /************************************************************************/ diff --git a/navit/map/textfile/textfile.c b/navit/map/textfile/textfile.c index 2dbcc1ab4..ca41ce20d 100644 --- a/navit/map/textfile/textfile.c +++ b/navit/map/textfile/textfile.c @@ -39,361 +39,347 @@ static int map_id; static void -remove_comment_line(char* line){ - if (line[0]==TEXTFILE_COMMENT_CHAR){ - line='\0'; - } +remove_comment_line(char* line) { + if (line[0]==TEXTFILE_COMMENT_CHAR) { + line='\0'; + } } static void -get_line(struct map_rect_priv *mr) -{ - if(mr->f) { - if (!mr->m->is_pipe) - mr->pos=ftell(mr->f); - else - mr->pos+=mr->lastlen; - fgets(mr->line, TEXTFILE_LINE_SIZE, mr->f); - dbg(lvl_debug,"read textfile line: %s", mr->line); - remove_comment_line(mr->line); - mr->lastlen=strlen(mr->line)+1; - if (strlen(mr->line) >= TEXTFILE_LINE_SIZE-1) - dbg(lvl_error, "line too long: %s", mr->line); - } +get_line(struct map_rect_priv *mr) { + if(mr->f) { + if (!mr->m->is_pipe) + mr->pos=ftell(mr->f); + else + mr->pos+=mr->lastlen; + fgets(mr->line, TEXTFILE_LINE_SIZE, mr->f); + dbg(lvl_debug,"read textfile line: %s", mr->line); + remove_comment_line(mr->line); + mr->lastlen=strlen(mr->line)+1; + if (strlen(mr->line) >= TEXTFILE_LINE_SIZE-1) + dbg(lvl_error, "line too long: %s", mr->line); + } } static void -map_destroy_textfile(struct map_priv *m) -{ - g_free(m->filename); - if(m->charset) { - g_free(m->charset); - } - g_free(m); +map_destroy_textfile(struct map_priv *m) { + g_free(m->filename); + if(m->charset) { + g_free(m->charset); + } + g_free(m); } static void -textfile_coord_rewind(void *priv_data) -{ +textfile_coord_rewind(void *priv_data) { } static int -parse_line(struct map_rect_priv *mr, int attr) -{ - int pos; +parse_line(struct map_rect_priv *mr, int attr) { + int pos; - pos=coord_parse(mr->line, projection_mg, &mr->c); - if (pos < strlen(mr->line) && attr) { - strcpy(mr->attrs, mr->line+pos); - } - return pos; + pos=coord_parse(mr->line, projection_mg, &mr->c); + if (pos < strlen(mr->line) && attr) { + strcpy(mr->attrs, mr->line+pos); + } + return pos; } static int -textfile_coord_get(void *priv_data, struct coord *c, int count) -{ - struct map_rect_priv *mr=priv_data; - int ret=0; - dbg(lvl_warning,"enter, count: %d",count); - while (count--) { - if (mr->f && !feof(mr->f) && (!mr->item.id_hi || !mr->eoc) && parse_line(mr, mr->item.id_hi)) { - if (c){ - *c=mr->c; - dbg(lvl_debug,"c=0x%x,0x%x", c->x, c->y); - c++; - } - ret++; - get_line(mr); - if (mr->item.id_hi) - mr->eoc=1; - } else { - mr->more=0; - break; - } - } - return ret; +textfile_coord_get(void *priv_data, struct coord *c, int count) { + struct map_rect_priv *mr=priv_data; + int ret=0; + dbg(lvl_warning,"enter, count: %d",count); + while (count--) { + if (mr->f && !feof(mr->f) && (!mr->item.id_hi || !mr->eoc) && parse_line(mr, mr->item.id_hi)) { + if (c) { + *c=mr->c; + dbg(lvl_debug,"c=0x%x,0x%x", c->x, c->y); + c++; + } + ret++; + get_line(mr); + if (mr->item.id_hi) + mr->eoc=1; + } else { + mr->more=0; + break; + } + } + return ret; } static void -textfile_attr_rewind(void *priv_data) -{ - struct map_rect_priv *mr=priv_data; - mr->attr_pos=0; - mr->attr_last=attr_none; +textfile_attr_rewind(void *priv_data) { + struct map_rect_priv *mr=priv_data; + mr->attr_pos=0; + mr->attr_last=attr_none; } static void -textfile_encode_attr(char *attr_val, enum attr_type attr_type, struct attr *attr) -{ - if (attr_type >= attr_type_int_begin && attr_type <= attr_type_int_end) - attr->u.num=atoi(attr_val); - else - attr->u.str=attr_val; +textfile_encode_attr(char *attr_val, enum attr_type attr_type, struct attr *attr) { + if (attr_type >= attr_type_int_begin && attr_type <= attr_type_int_end) + attr->u.num=atoi(attr_val); + else + attr->u.str=attr_val; } static int -textfile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct map_rect_priv *mr=priv_data; - char *str=NULL; - dbg(lvl_debug,"mr=%p attrs='%s' ", mr, mr->attrs); - if (attr_type != mr->attr_last) { - dbg(lvl_debug,"reset attr_pos"); - mr->attr_pos=0; - mr->attr_last=attr_type; - } - if (attr_type == attr_any) { - dbg(lvl_debug,"attr_any"); - if (attr_from_line(mr->attrs,NULL,&mr->attr_pos,mr->attr, mr->attr_name)) { - attr_type=attr_from_name(mr->attr_name); - dbg(lvl_debug,"found attr '%s' 0x%x", mr->attr_name, attr_type); - attr->type=attr_type; - textfile_encode_attr(mr->attr, attr_type, attr); - return 1; - } - } else { - str=attr_to_name(attr_type); - dbg(lvl_debug,"attr='%s' ",str); - if (attr_from_line(mr->attrs,str,&mr->attr_pos,mr->attr, NULL)) { - textfile_encode_attr(mr->attr, attr_type, attr); - dbg(lvl_debug,"found"); - return 1; - } - } - dbg(lvl_debug,"not found"); - return 0; +textfile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct map_rect_priv *mr=priv_data; + char *str=NULL; + dbg(lvl_debug,"mr=%p attrs='%s' ", mr, mr->attrs); + if (attr_type != mr->attr_last) { + dbg(lvl_debug,"reset attr_pos"); + mr->attr_pos=0; + mr->attr_last=attr_type; + } + if (attr_type == attr_any) { + dbg(lvl_debug,"attr_any"); + if (attr_from_line(mr->attrs,NULL,&mr->attr_pos,mr->attr, mr->attr_name)) { + attr_type=attr_from_name(mr->attr_name); + dbg(lvl_debug,"found attr '%s' 0x%x", mr->attr_name, attr_type); + attr->type=attr_type; + textfile_encode_attr(mr->attr, attr_type, attr); + return 1; + } + } else { + str=attr_to_name(attr_type); + dbg(lvl_debug,"attr='%s' ",str); + if (attr_from_line(mr->attrs,str,&mr->attr_pos,mr->attr, NULL)) { + textfile_encode_attr(mr->attr, attr_type, attr); + dbg(lvl_debug,"found"); + return 1; + } + } + dbg(lvl_debug,"not found"); + return 0; } static struct item_methods methods_textfile = { - textfile_coord_rewind, - textfile_coord_get, - textfile_attr_rewind, - textfile_attr_get, + textfile_coord_rewind, + textfile_coord_get, + textfile_attr_rewind, + textfile_attr_get, }; static struct map_rect_priv * -map_rect_new_textfile(struct map_priv *map, struct map_selection *sel) -{ - struct map_rect_priv *mr; +map_rect_new_textfile(struct map_priv *map, struct map_selection *sel) { + struct map_rect_priv *mr; - dbg(lvl_debug,"enter"); - mr=g_new0(struct map_rect_priv, 1); - mr->m=map; - mr->sel=sel; - if (map->flags & 1) - mr->item.id_hi=1; - else - mr->item.id_hi=0; - mr->item.id_lo=0; - mr->item.meth=&methods_textfile; - mr->item.priv_data=mr; - if (map->is_pipe) { + dbg(lvl_debug,"enter"); + mr=g_new0(struct map_rect_priv, 1); + mr->m=map; + mr->sel=sel; + if (map->flags & 1) + mr->item.id_hi=1; + else + mr->item.id_hi=0; + mr->item.id_lo=0; + mr->item.meth=&methods_textfile; + mr->item.priv_data=mr; + if (map->is_pipe) { #ifdef HAVE_POPEN - char *oargs,*args=g_strdup(map->filename),*sep=" "; - enum layer_type lay; - g_free(mr->args); - while (sel) { - oargs=args; - args=g_strdup_printf("%s 0x%x 0x%x 0x%x 0x%x", oargs, sel->u.c_rect.lu.x, sel->u.c_rect.lu.y, sel->u.c_rect.rl.x, sel->u.c_rect.rl.y); - g_free(oargs); - for (lay=layer_town ; lay < layer_end ; lay++) { - oargs=args; - args=g_strdup_printf("%s%s%d", oargs, sep, sel->order); - g_free(oargs); - sep=","; - } - sel=sel->next; - } - dbg(lvl_debug,"popen args %s", args); - mr->args=args; - mr->f=popen(mr->args, "r"); - mr->pos=0; - mr->lastlen=0; + char *oargs,*args=g_strdup(map->filename),*sep=" "; + enum layer_type lay; + g_free(mr->args); + while (sel) { + oargs=args; + args=g_strdup_printf("%s 0x%x 0x%x 0x%x 0x%x", oargs, sel->u.c_rect.lu.x, sel->u.c_rect.lu.y, sel->u.c_rect.rl.x, + sel->u.c_rect.rl.y); + g_free(oargs); + for (lay=layer_town ; lay < layer_end ; lay++) { + oargs=args; + args=g_strdup_printf("%s%s%d", oargs, sep, sel->order); + g_free(oargs); + sep=","; + } + sel=sel->next; + } + dbg(lvl_debug,"popen args %s", args); + mr->args=args; + mr->f=popen(mr->args, "r"); + mr->pos=0; + mr->lastlen=0; #else - dbg(lvl_error,"unable to work with pipes %s",map->filename); -#endif - } else { - mr->f=fopen(map->filename, "r"); - } - if(!mr->f) { - if (!(errno == ENOENT && map->no_warning_if_map_file_missing)) { - dbg(lvl_error, "error opening textfile %s: %s", map->filename, strerror(errno)); - } - } - get_line(mr); - return mr; + dbg(lvl_error,"unable to work with pipes %s",map->filename); +#endif + } else { + mr->f=fopen(map->filename, "r"); + } + if(!mr->f) { + if (!(errno == ENOENT && map->no_warning_if_map_file_missing)) { + dbg(lvl_error, "error opening textfile %s: %s", map->filename, strerror(errno)); + } + } + get_line(mr); + return mr; } static void -map_rect_destroy_textfile(struct map_rect_priv *mr) -{ - if (mr->f) { - if (mr->m->is_pipe) { +map_rect_destroy_textfile(struct map_rect_priv *mr) { + if (mr->f) { + if (mr->m->is_pipe) { #ifdef HAVE_POPEN - pclose(mr->f); + pclose(mr->f); #endif - } - else { - fclose(mr->f); - } - } - g_free(mr); + } else { + fclose(mr->f); + } + } + g_free(mr); } static struct item * -map_rect_get_item_textfile(struct map_rect_priv *mr) -{ - char *p,type[TEXTFILE_LINE_SIZE]; - dbg(lvl_debug,"map_rect_get_item_textfile id_hi=%d line=%s", mr->item.id_hi, mr->line); - if (!mr->f) { - return NULL; - } - while (mr->more) { - struct coord c; - textfile_coord_get(mr, &c, 1); - } - for(;;) { - if (feof(mr->f)) { - dbg(lvl_debug,"map_rect_get_item_textfile: eof %d",mr->item.id_hi); - if (mr->m->flags & 1) { - if (!mr->item.id_hi) - return NULL; - mr->item.id_hi=0; - } else { - if (mr->item.id_hi) - return NULL; - mr->item.id_hi=1; - } - if (mr->m->is_pipe) { +map_rect_get_item_textfile(struct map_rect_priv *mr) { + char *p,type[TEXTFILE_LINE_SIZE]; + dbg(lvl_debug,"map_rect_get_item_textfile id_hi=%d line=%s", mr->item.id_hi, mr->line); + if (!mr->f) { + return NULL; + } + while (mr->more) { + struct coord c; + textfile_coord_get(mr, &c, 1); + } + for(;;) { + if (feof(mr->f)) { + dbg(lvl_debug,"map_rect_get_item_textfile: eof %d",mr->item.id_hi); + if (mr->m->flags & 1) { + if (!mr->item.id_hi) + return NULL; + mr->item.id_hi=0; + } else { + if (mr->item.id_hi) + return NULL; + mr->item.id_hi=1; + } + if (mr->m->is_pipe) { #ifdef HAVE_POPEN - pclose(mr->f); - mr->f=popen(mr->args, "r"); - mr->pos=0; - mr->lastlen=0; + pclose(mr->f); + mr->f=popen(mr->args, "r"); + mr->pos=0; + mr->lastlen=0; #endif - } else { - fseek(mr->f, 0, SEEK_SET); - clearerr(mr->f); - } - get_line(mr); - } - if ((p=strchr(mr->line,'\n'))) - *p='\0'; - if (mr->item.id_hi) { - mr->attrs[0]='\0'; - if (!parse_line(mr, 1)) { - get_line(mr); - continue; - } - dbg(lvl_debug,"map_rect_get_item_textfile: point found"); - mr->eoc=0; - mr->item.id_lo=mr->pos; - } else { - if (parse_line(mr, 1)) { - get_line(mr); - continue; - } - dbg(lvl_debug,"map_rect_get_item_textfile: line found"); - if (! mr->line[0]) { - get_line(mr); - continue; - } - mr->item.id_lo=mr->pos; - strcpy(mr->attrs, mr->line); - get_line(mr); - dbg(lvl_debug,"mr=%p attrs=%s", mr, mr->attrs); - } - dbg(lvl_debug,"get_attrs %s", mr->attrs); - if (attr_from_line(mr->attrs,"type",NULL,type,NULL)) { - dbg(lvl_debug,"type='%s'", type); - mr->item.type=item_from_name(type); - if (mr->item.type == type_none) - dbg(lvl_error, "Warning: type '%s' unknown", type); - } else { - get_line(mr); - continue; - } - mr->attr_last=attr_none; - mr->more=1; - dbg(lvl_debug,"return attr='%s'", mr->attrs); - return &mr->item; - } + } else { + fseek(mr->f, 0, SEEK_SET); + clearerr(mr->f); + } + get_line(mr); + } + if ((p=strchr(mr->line,'\n'))) + *p='\0'; + if (mr->item.id_hi) { + mr->attrs[0]='\0'; + if (!parse_line(mr, 1)) { + get_line(mr); + continue; + } + dbg(lvl_debug,"map_rect_get_item_textfile: point found"); + mr->eoc=0; + mr->item.id_lo=mr->pos; + } else { + if (parse_line(mr, 1)) { + get_line(mr); + continue; + } + dbg(lvl_debug,"map_rect_get_item_textfile: line found"); + if (! mr->line[0]) { + get_line(mr); + continue; + } + mr->item.id_lo=mr->pos; + strcpy(mr->attrs, mr->line); + get_line(mr); + dbg(lvl_debug,"mr=%p attrs=%s", mr, mr->attrs); + } + dbg(lvl_debug,"get_attrs %s", mr->attrs); + if (attr_from_line(mr->attrs,"type",NULL,type,NULL)) { + dbg(lvl_debug,"type='%s'", type); + mr->item.type=item_from_name(type); + if (mr->item.type == type_none) + dbg(lvl_error, "Warning: type '%s' unknown", type); + } else { + get_line(mr); + continue; + } + mr->attr_last=attr_none; + mr->more=1; + dbg(lvl_debug,"return attr='%s'", mr->attrs); + return &mr->item; + } } static struct item * -map_rect_get_item_byid_textfile(struct map_rect_priv *mr, int id_hi, int id_lo) -{ - if (mr->m->is_pipe) { +map_rect_get_item_byid_textfile(struct map_rect_priv *mr, int id_hi, int id_lo) { + if (mr->m->is_pipe) { #ifndef _MSC_VER - pclose(mr->f); - mr->f=popen(mr->args, "r"); - mr->pos=0; - mr->lastlen=0; + pclose(mr->f); + mr->f=popen(mr->args, "r"); + mr->pos=0; + mr->lastlen=0; #endif /* _MSC_VER */ - } else - fseek(mr->f, id_lo, SEEK_SET); - get_line(mr); - mr->item.id_hi=id_hi; - return map_rect_get_item_textfile(mr); + } else + fseek(mr->f, id_lo, SEEK_SET); + get_line(mr); + mr->item.id_hi=id_hi; + return map_rect_get_item_textfile(mr); } static struct map_methods map_methods_textfile = { - projection_mg, - "utf-8", - map_destroy_textfile, - map_rect_new_textfile, - map_rect_destroy_textfile, - map_rect_get_item_textfile, - map_rect_get_item_byid_textfile, + projection_mg, + "utf-8", + map_destroy_textfile, + map_rect_new_textfile, + map_rect_destroy_textfile, + map_rect_get_item_textfile, + map_rect_get_item_byid_textfile, }; static struct map_priv * -map_new_textfile(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) -{ - struct map_priv *m; - struct attr *data=attr_search(attrs, NULL, attr_data); - struct attr *charset=attr_search(attrs, NULL, attr_charset); - struct attr *flags=attr_search(attrs, NULL, attr_flags); - struct attr *no_warn=attr_search(attrs, NULL, attr_no_warning_if_map_file_missing); - struct file_wordexp *wexp; - int len,is_pipe=0; - char *wdata; - char **wexp_data; - if (! data) - return NULL; - dbg(lvl_debug,"map_new_textfile %s", data->u.str); - wdata=g_strdup(data->u.str); - len=strlen(wdata); - if (len && wdata[len-1] == '|') { - wdata[len-1]='\0'; - is_pipe=1; - } - wexp=file_wordexp_new(wdata); - wexp_data=file_wordexp_get_array(wexp); - *meth=map_methods_textfile; +map_new_textfile(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) { + struct map_priv *m; + struct attr *data=attr_search(attrs, NULL, attr_data); + struct attr *charset=attr_search(attrs, NULL, attr_charset); + struct attr *flags=attr_search(attrs, NULL, attr_flags); + struct attr *no_warn=attr_search(attrs, NULL, attr_no_warning_if_map_file_missing); + struct file_wordexp *wexp; + int len,is_pipe=0; + char *wdata; + char **wexp_data; + if (! data) + return NULL; + dbg(lvl_debug,"map_new_textfile %s", data->u.str); + wdata=g_strdup(data->u.str); + len=strlen(wdata); + if (len && wdata[len-1] == '|') { + wdata[len-1]='\0'; + is_pipe=1; + } + wexp=file_wordexp_new(wdata); + wexp_data=file_wordexp_get_array(wexp); + *meth=map_methods_textfile; - m=g_new0(struct map_priv, 1); - m->id=++map_id; - m->filename=g_strdup(wexp_data[0]); - m->is_pipe=is_pipe; - m->no_warning_if_map_file_missing=(no_warn!=NULL) && (no_warn->u.num); - if (flags) - m->flags=flags->u.num; - dbg(lvl_debug,"map_new_textfile %s %s", m->filename, wdata); - if (charset) { - m->charset=g_strdup(charset->u.str); - meth->charset=m->charset; - } - file_wordexp_destroy(wexp); - g_free(wdata); - return m; + m=g_new0(struct map_priv, 1); + m->id=++map_id; + m->filename=g_strdup(wexp_data[0]); + m->is_pipe=is_pipe; + m->no_warning_if_map_file_missing=(no_warn!=NULL) && (no_warn->u.num); + if (flags) + m->flags=flags->u.num; + dbg(lvl_debug,"map_new_textfile %s %s", m->filename, wdata); + if (charset) { + m->charset=g_strdup(charset->u.str); + meth->charset=m->charset; + } + file_wordexp_destroy(wexp); + g_free(wdata); + return m; } void -plugin_init(void) -{ - dbg(lvl_debug,"textfile: plugin_init"); - plugin_register_category_map("textfile", map_new_textfile); +plugin_init(void) { + dbg(lvl_debug,"textfile: plugin_init"); + plugin_register_category_map("textfile", map_new_textfile); } |