"Fossies" - the Fresh Open Source Software Archive

Member "navit-0.5.6/navit/mapset.c" (6 Mar 2021, 11827 Bytes) of package /linux/privat/navit-0.5.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mapset.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.5.5_vs_0.5.6.

    1 /**
    2  * Navit, a modular navigation system.
    3  * Copyright (C) 2005-2008 Navit Team
    4  *
    5  * This program is free software; you can redistribute it and/or
    6  * modify it under the terms of the GNU General Public License
    7  * version 2 as published by the Free Software Foundation.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not, write to the
   16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   17  * Boston, MA  02110-1301, USA.
   18  */
   19 
   20 /** @file
   21  *
   22  * @brief Contains code used for loading more than one map
   23  *
   24  * The code in this file introduces "mapsets", which are collections of several maps.
   25  * This enables navit to operate on more than one map at once. See map.c / map.h to learn
   26  * how maps are handled.
   27  */
   28 
   29 #include <string.h>
   30 #include <glib.h>
   31 #include <glib/gprintf.h>
   32 #include "debug.h"
   33 #include "item.h"
   34 #include "mapset.h"
   35 #include "projection.h"
   36 #include "map.h"
   37 #include "xmlconfig.h"
   38 
   39 struct mapset {
   40     NAVIT_OBJECT
   41     GList *maps; /**< Linked list of all the maps in the mapset */
   42 };
   43 
   44 struct attr_iter {
   45     GList *last;
   46 };
   47 
   48 /**
   49  * @brief Creates a new, empty mapset
   50  *
   51  * @return The new mapset
   52  */
   53 struct mapset *mapset_new(struct attr *parent, struct attr **attrs) {
   54     struct mapset *ms;
   55 
   56     ms=g_new0(struct mapset, 1);
   57     ms->func=&mapset_func;
   58     navit_object_ref((struct navit_object *)ms);
   59     ms->attrs=attr_list_dup(attrs);
   60 
   61     return ms;
   62 }
   63 
   64 struct mapset *mapset_dup(struct mapset *ms) {
   65     struct mapset *ret=mapset_new(NULL, ms->attrs);
   66     ret->maps=g_list_copy(ms->maps);
   67     return ret;
   68 }
   69 
   70 
   71 struct attr_iter *
   72 mapset_attr_iter_new(void* unused) {
   73     return g_new0(struct attr_iter, 1);
   74 }
   75 
   76 void mapset_attr_iter_destroy(struct attr_iter *iter) {
   77     g_free(iter);
   78 }
   79 
   80 /**
   81  * @brief Adds a map to a mapset
   82  *
   83  * @param ms The mapset to add the map to
   84  * @param m The map to be added
   85  */
   86 int mapset_add_attr(struct mapset *ms, struct attr *attr) {
   87     switch (attr->type) {
   88     case attr_map:
   89         ms->attrs=attr_generic_add_attr(ms->attrs,attr);
   90         ms->maps=g_list_append(ms->maps, attr->u.map);
   91         return 1;
   92     default:
   93         return 0;
   94     }
   95 }
   96 
   97 int mapset_remove_attr(struct mapset *ms, struct attr *attr) {
   98     switch (attr->type) {
   99     case attr_map:
  100         ms->attrs=attr_generic_remove_attr(ms->attrs,attr);
  101         ms->maps=g_list_remove(ms->maps, attr->u.map);
  102         return 1;
  103     default:
  104         return 0;
  105     }
  106 }
  107 
  108 int mapset_get_attr(struct mapset *ms, enum attr_type type, struct attr *attr, struct attr_iter *iter) {
  109     GList *map;
  110     map=ms->maps;
  111     attr->type=type;
  112     switch (type) {
  113     case attr_map:
  114         while (map) {
  115             if (!iter || iter->last == g_list_previous(map)) {
  116                 attr->u.map=map->data;
  117                 if (iter)
  118                     iter->last=map;
  119                 return 1;
  120             }
  121             map=g_list_next(map);
  122         }
  123         break;
  124     default:
  125         break;
  126     }
  127     return 0;
  128 }
  129 
  130 /**
  131  * @brief Destroys a mapset.
  132  *
  133  * This destroys a mapset. Please note that it does not touch the contained maps
  134  * in any way.
  135  *
  136  * @param ms The mapset to be destroyed
  137  */
  138 void mapset_destroy(struct mapset *ms) {
  139     g_list_free(ms->maps);
  140     attr_list_free(ms->attrs);
  141     g_free(ms);
  142 }
  143 
  144 /**
  145  * @brief Handle for a mapset in use
  146  *
  147  * This struct is used for a mapset that is in use. With this it is possible to iterate
  148  * all maps in a mapset.
  149  */
  150 struct mapset_handle {
  151     GList *l;   /**< Pointer to the current (next) map */
  152 };
  153 
  154 /**
  155  * @brief Returns a new handle for a mapset
  156  *
  157  * This returns a new handle for an existing mapset. The new handle points to the first
  158  * map in the set.
  159  *
  160  * @param ms The mapset to get a handle of
  161  * @return The new mapset handle
  162  */
  163 struct mapset_handle *
  164 mapset_open(struct mapset *ms) {
  165     struct mapset_handle *ret=NULL;
  166     if(ms) {
  167         ret=g_new(struct mapset_handle, 1);
  168         ret->l=ms->maps;
  169     }
  170 
  171     return ret;
  172 }
  173 
  174 /**
  175  * @brief Gets the next map from a mapset handle
  176  *
  177  * The `active` argument governs whether (and how) to limit the search to active maps:
  178  *
  179  * Passing 0 causes this function to cycle through all maps, whether active or not.
  180  *
  181  * Passing a value of 2 will return only maps which have the `attr_route_active` attribute set to true.
  182  *
  183  * Passing a value of 3 will return only maps which have the `attr_search_active` attribute set to true.
  184  *
  185  * Passing any other nonzero value will return only maps which have the `attr_active` attribute set to true,
  186  * or not set at all.
  187  *
  188  * @param msh The mapset handle to get the next map of
  189  * @param active Whether to cycle only through active maps (see description)
  190  * @return The next map
  191  */
  192 struct map * mapset_next(struct mapset_handle *msh, int active) {
  193     struct map *ret;
  194     struct attr active_attr;
  195 
  196     for (;;) {
  197         if (!msh || !msh->l)
  198             return NULL;
  199         ret=msh->l->data;
  200         msh->l=g_list_next(msh->l);
  201         if (!active)
  202             return ret;
  203         if (active == 2 && map_get_attr(ret, attr_route_active, &active_attr, NULL)) {
  204             if (active_attr.u.num)
  205                 return ret;
  206             else
  207                 continue;
  208         }
  209         if (active == 3 && map_get_attr(ret, attr_search_active, &active_attr, NULL)) {
  210             if (active_attr.u.num)
  211                 return ret;
  212             else
  213                 continue;
  214         }
  215         if (!map_get_attr(ret, attr_active, &active_attr, NULL))
  216             return ret;
  217         if (active_attr.u.num)
  218             return ret;
  219     }
  220 }
  221 
  222 /**
  223  * @brief Gets a map from the mapset by name
  224  *
  225  * @param ms The map
  226  * @param map_name the map name used by the search
  227  * @return The next map
  228  */
  229 struct map *
  230 mapset_get_map_by_name(struct mapset *ms, const char*map_name) {
  231     struct mapset_handle*msh;
  232     struct map*curr_map;
  233     struct attr map_attr;
  234     if( !ms || !map_name ) {
  235         return NULL;
  236     }
  237     msh=mapset_open(ms);
  238     while ((curr_map=mapset_next(msh, 1))) {
  239         //get map name
  240         if(map_get_attr(curr_map,attr_name, &map_attr,NULL)) {
  241             if( ! strcmp(map_attr.u.str, map_name)) {
  242                 break;
  243             }
  244         }
  245     }
  246     mapset_close(msh);
  247     return curr_map;
  248 }
  249 
  250 /**
  251  * @brief Closes a mapset handle after it is no longer used
  252  *
  253  * @param msh Mapset handle to be closed
  254  */
  255 void mapset_close(struct mapset_handle *msh) {
  256     g_free(msh);
  257 }
  258 
  259 /**
  260  * @brief Holds information about a search in a mapset
  261  *
  262  * This struct holds information about a search (e.g. for a street) in a mapset.
  263  *
  264  * @sa For a more detailed description see the documentation of mapset_search_new().
  265  */
  266 struct mapset_search {
  267     GList *map;                 /**< The list of maps to be searched within */
  268     struct map_search *ms;      /**< A map search struct for the map currently active */
  269     struct item *item;          /**< "Superior" item. */
  270     struct attr *search_attr;   /**< Attribute to be searched for. */
  271     int partial;                /**< Indicates if one would like to have partial matches */
  272     struct mapset *mapset;      /**< reference to current mapset. Set to NULL when all maps are searched */
  273 };
  274 
  275 /**
  276  * @brief Starts a search on a mapset
  277  *
  278  * This function starts a search on a mapset. What attributes one can search for depends on the
  279  * map plugin. See the description of map_search_new() in map.c for details.
  280  *
  281  * If you enable partial matches bear in mind that the search matches only the begin of the
  282  * strings - a search for a street named "street" would match to "streetfoo", but not to
  283  * "somestreet". Search is case insensitive.
  284  *
  285  * The item passed to this function specifies a "superior item" to "search within" - e.g. a town
  286  * in which we want to search for a street, or a country in which to search for a town.
  287  *
  288  * @param ms The mapset that should be searched
  289  * @param item Specifies a superior item to "search within" (see description)
  290  * @param search_attr Attribute specifying what to search for. See description.
  291  * @param partial Set this to true to also have partial matches. See description.
  292  * @return A new mapset search struct for this search
  293  */
  294 struct mapset_search *
  295 mapset_search_new(struct mapset *ms, struct item *item, struct attr *search_attr, int partial) {
  296     struct mapset_search *this;
  297     dbg(lvl_debug,"enter(%p,%p,%p,%d)", ms, item, search_attr, partial);
  298     this=g_new0(struct mapset_search,1);
  299     if(this != NULL && ms!=NULL ) {
  300         this->mapset=ms;
  301         this->item=item;
  302         this->search_attr=search_attr;
  303         this->partial=partial;
  304         return this;
  305     } else {
  306         return NULL;
  307     }
  308 }
  309 
  310 /**
  311  * @brief Returns the next found item from a mapset search
  312  *
  313  * This function returns the next item from a mapset search or NULL if there are no more items found.
  314  * It automatically iterates through all the maps in the mapset. Please note that maps which have the
  315  * attr_active attribute associated with them and set to false are not searched.
  316  *
  317  * @param this The mapset search to return an item from
  318  * @return The next found item or NULL if there are no more items found
  319  */
  320 struct item *
  321 mapset_search_get_item(struct mapset_search *this_) {
  322     struct item *ret=NULL;
  323     struct attr active_attr;
  324     int country_search=this_->search_attr->type >= attr_country_all && this_->search_attr->type <= attr_country_name;
  325 
  326     while ((this_) && (this_->mapset) && (!this_->ms
  327                                           || !(ret=map_search_get_item(this_->ms)))) { /* The current map has no more items to be returned */
  328 
  329         /* Use only the first map from the mapset to search for country codes. */
  330         if (this_->map && country_search)
  331             break;
  332 
  333         for (;;) {
  334             if (!this_->map)
  335                 this_->map=this_->mapset->maps;
  336             else
  337                 this_->map=g_list_next(this_->map);
  338 
  339             if (!this_->map) {
  340                 /* No more maps left, mark this mapset_search as finished */
  341                 this_->mapset=NULL;
  342                 break;
  343             }
  344 
  345             /* Any map can be used for country search, regardless of it's attr_active value */
  346             if(country_search)
  347                 break;
  348 
  349             if (map_get_attr(this_->map->data, attr_search_active, &active_attr, NULL)) {
  350                 if (!active_attr.u.num)
  351                     continue;
  352             }
  353             if (!map_get_attr(this_->map->data, attr_active, &active_attr, NULL))
  354                 break;
  355             if (active_attr.u.num)
  356                 break;
  357         }
  358         if(this_->ms) {
  359             map_search_destroy(this_->ms);
  360             this_->ms=NULL;
  361         }
  362         if (! this_->map)
  363             break;
  364         this_->ms=map_search_new(this_->map->data, this_->item, this_->search_attr, this_->partial);
  365     }
  366     return ret;
  367 }
  368 
  369 /**
  370  * @brief Destroys a mapset search
  371  *
  372  * @param this The mapset search to be destroyed
  373  */
  374 void mapset_search_destroy(struct mapset_search *this_) {
  375     if (this_) {
  376         map_search_destroy(this_->ms);
  377         g_free(this_);
  378     }
  379 }
  380 
  381 struct object_func mapset_func = {
  382     attr_mapset,
  383     (object_func_new)mapset_new,
  384     (object_func_get_attr)mapset_get_attr,
  385     (object_func_iter_new)mapset_attr_iter_new,
  386     (object_func_iter_destroy)mapset_attr_iter_destroy,
  387     (object_func_set_attr)NULL,
  388     (object_func_add_attr)mapset_add_attr,
  389     (object_func_remove_attr)mapset_remove_attr,
  390     (object_func_init)NULL,
  391     (object_func_destroy)mapset_destroy,
  392     (object_func_dup)mapset_dup,
  393     (object_func_ref)navit_object_ref,
  394     (object_func_unref)navit_object_unref,
  395 };
  396 
  397 
  398