diff options
author | Ian McIntosh <ian_mcintosh@linuxadvocate.org> | 2005-10-26 00:04:53 +0000 |
---|---|---|
committer | Ian McIntosh <ian_mcintosh@linuxadvocate.org> | 2005-10-26 00:04:53 +0000 |
commit | e122d63d303f3fc298b4083c3bd437c768d48285 (patch) | |
tree | bf0797ebbbcd7eb4afb7c8bc0848d4b2404fe153 | |
parent | 1c7863052b7db8619e30c393802a6bd3db766ad1 (diff) |
Moved list of road suffixes to data file.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | data/road-suffix-list.txt | 41 | ||||
-rw-r--r-- | src/main.c | 4 | ||||
-rw-r--r-- | src/road.c | 57 | ||||
-rw-r--r-- | src/road.h | 6 | ||||
-rw-r--r-- | src/scenemanager.c | 2 | ||||
-rw-r--r-- | src/util.c | 89 | ||||
-rw-r--r-- | src/util.h | 3 |
8 files changed, 191 insertions, 17 deletions
@@ -1,3 +1,9 @@ +2005-10-26 Ian McIntosh <ian_mcintosh@linuxadvocate.org> + + * src/road.c: + * src/util.c: + * data/road-suffix-list.txt: Moved list of road suffixes to data file. + 2005-10-25 Ian McIntosh <ian_mcintosh@linuxadvocate.org> * src/map.c: Switch from gfreelist to g_new and g_free for the list of selected POI (currently not really used). diff --git a/data/road-suffix-list.txt b/data/road-suffix-list.txt new file mode 100644 index 0000000..c49f496 --- /dev/null +++ b/data/road-suffix-list.txt @@ -0,0 +1,41 @@ +# format is: tab separated list with 'Proper Name' then 'Short Name' then alternatives (used only during import) +# lines are numbered starting at 1, with 0 being "no suffix". lines starting with # are ignored. +Road Rd +Street St +Drive Dr +Boulevard Blv Blvd +Avenue Ave Av +Circle Crl Cir +Square Sq +Path Pth +Way Wy +Plaza Plz +Trail Trl +Lane Ln +Crossing Xing +Place Pl +Court Ct +Turnpike Tpke +Terrace Ter +Row Row +Parkway Pky +Bridge Brg +Highway Hwy +Run Run +Pass Pass +Freeway Fwy +Alley Aly +Crescent Cres +Tunnel Tunl +Walk Walk +Terrace Trce +Branch Br +Cove Cv +Bypass Byp +Loop Loop +Spur Spur +Ramp Ramp +Pike Pike +Grade Grd +Route Rte +Arc Arc @@ -32,6 +32,7 @@ #include <gtk/gtk.h> #include "main.h" #include "gui.h" +#include "road.h" #include "db.h" #include "map.h" #include "map_style.h" @@ -141,6 +142,9 @@ gboolean main_init(void) g_free(pszApplicationDir); #endif + g_print("initializing road\n"); + road_init(); + g_print("initializing map styles\n"); map_style_init(); g_print("initializing map\n"); @@ -23,6 +23,31 @@ #include <gtk/gtk.h> #include "road.h" +#include "util.h" + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#define ROAD_SUFFIX_LIST_FILE_NAME ("road-suffix-list.txt") +#define ROAD_SUFFIX_LIST_MIN_WORDS (2) + +struct { + GArray* pRoadNameSuffixArray; // an array of null-terminated vectors (an array of gchar* with the last being NULL) +} g_Road = {0}; + +void road_init() +{ + gchar* pszPath = g_strdup_printf(PACKAGE_SOURCE_DIR"/data/%s", ROAD_SUFFIX_LIST_FILE_NAME); + if(util_load_array_of_string_vectors(pszPath, &(g_Road.pRoadNameSuffixArray), ROAD_SUFFIX_LIST_MIN_WORDS) == FALSE) { + g_free(pszPath); + pszPath = g_strdup_printf(PACKAGE_DATA_DIR"/data/%s", ROAD_SUFFIX_LIST_FILE_NAME); + if(util_load_array_of_string_vectors(pszPath, &(g_Road.pRoadNameSuffixArray), ROAD_SUFFIX_LIST_MIN_WORDS) == FALSE) { + g_error("Unable to load %s", ROAD_SUFFIX_LIST_FILE_NAME); + } + } + g_free(pszPath); +} struct { gchar* pszLong; @@ -158,8 +183,7 @@ struct { {"Tunl", ROAD_SUFFIX_TUNNEL}, {"Walk", ROAD_SUFFIX_WALK}, - {"Walk", ROAD_SUFFIX_WALK}, - + {"Branch", ROAD_SUFFIX_BRANCE}, {"Br", ROAD_SUFFIX_BRANCE}, @@ -193,24 +217,29 @@ struct { const gchar* road_suffix_itoa(gint nSuffixID, ESuffixLength eSuffixLength) { - if(nSuffixID >= ROAD_SUFFIX_FIRST && nSuffixID <= ROAD_SUFFIX_LAST) { - if(eSuffixLength == ROAD_SUFFIX_LENGTH_SHORT) { - return g_RoadNameSuffix[nSuffixID].pszShort; - } - else { - return g_RoadNameSuffix[nSuffixID].pszLong; - } + if(nSuffixID < g_Road.pRoadNameSuffixArray->len) { + //g_debug("looking up suffixID %d", nSuffixID); + gchar** apszWords = g_array_index(g_Road.pRoadNameSuffixArray, gchar**, nSuffixID); + g_assert(eSuffixLength == 0 || eSuffixLength == 1); // we know there are at least 2 words in the array (see call to util_load_name_list) + return apszWords[eSuffixLength]; + } + else { + return ""; } - if(nSuffixID != ROAD_SUFFIX_NONE) return "???"; - return ""; } gboolean road_suffix_atoi(const gchar* pszSuffix, gint* pReturnSuffixID) { + g_assert(pszSuffix != NULL); + g_assert(pReturnSuffixID != NULL); + gint i; - for(i=0 ; i<G_N_ELEMENTS(g_RoadNameSuffixLookup) ; i++) { - if(g_ascii_strcasecmp(pszSuffix, g_RoadNameSuffixLookup[i].pszName) == 0) { - *pReturnSuffixID = g_RoadNameSuffixLookup[i].nID; + for(i=0 ; i<g_Road.pRoadNameSuffixArray->len ; i++) { + gchar** apszWords = g_array_index(g_Road.pRoadNameSuffixArray, gchar**, i); + + // Does this list of words contain the string? + if(util_find_string_in_string_vector(pszSuffix, apszWords, NULL)) { + *pReturnSuffixID = i; return TRUE; } } @@ -26,6 +26,8 @@ #include "map.h" +void road_init(); + typedef struct { GArray* pMapPointsArray; @@ -40,8 +42,8 @@ typedef struct { // ESuffixLength typedef enum { - ROAD_SUFFIX_LENGTH_SHORT, - ROAD_SUFFIX_LENGTH_LONG + ROAD_SUFFIX_LENGTH_LONG, + ROAD_SUFFIX_LENGTH_SHORT } ESuffixLength; enum ERoadNameSuffix { // these can't change once stored in DB diff --git a/src/scenemanager.c b/src/scenemanager.c index 9c91650..33140b9 100644 --- a/src/scenemanager.c +++ b/src/scenemanager.c @@ -22,7 +22,7 @@ */ /* -Goals: +Purpose of scenemanager.c: - Keep text labels and other screen objects from overlapping - Prevent the same text from showing up too often (currently not more than once) */ @@ -21,6 +21,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <gnome-vfs-2.0/libgnomevfs/gnome-vfs.h> + #include "main.h" #include "util.h" @@ -615,3 +617,90 @@ EDirection util_match_border(gint nX, gint nY, gint nWidth, gint nHeight, gint n } return eDirection; } + +// Load a \n separated list of \t separated names as a GArray of gchar* vectors... :) +gboolean util_load_array_of_string_vectors(const gchar* pszPath, GArray** ppReturnArray, gint nMinVectorLength) +{ + g_assert(pszPath != NULL); + g_assert(ppReturnArray != NULL); + g_assert(*ppReturnArray == NULL); // require pointer to NULL pointer + + // + // 1. Load entire file into memory. XXX: Better to load one line at a time? + // + gchar* pszFileContent = NULL; + if(gnome_vfs_read_entire_file(pszPath, NULL, &pszFileContent) != GNOME_VFS_OK) { + return FALSE; + } + + // + // 2. Split into lines. + // + gchar** apszLines = g_strsplit(pszFileContent, "\n", -1); // -1 = no maximum + gint nNumLines = g_strv_length(apszLines); + + // + // 3. Create array and add 0 element + // + GArray* pNewArray = g_array_sized_new(FALSE, FALSE, sizeof(gchar**), nNumLines); + + { + // Make the first nMinVectorLength indexes point to "" and the last NULL + gchar** apszFirst = g_malloc(sizeof(gchar*) * (nMinVectorLength+1)); + gint iVector; + for(iVector=0 ; iVector<nMinVectorLength ; iVector++) { + apszFirst[iVector] = g_strdup(""); // Just so we don't mix allocated and static strings + } + apszFirst[nMinVectorLength] = NULL; + g_array_append_val(pNewArray, apszFirst); + } + + // + // 4. Add one NULL-terminated char* vector per row + // + gint i; + for(i=0 ; i<nNumLines ; i++) { + if(apszLines[i][0] == '\0') { + g_debug("skipping blank line"); + continue; + } + if(apszLines[i][0] == '#') { + g_debug("skipping comment line"); + continue; + } + + gchar** apszWords = g_strsplit(apszLines[i], "\t", -1); + if(g_strv_length(apszWords) < nMinVectorLength) { + g_error("line %d contains fewer than %d words", i+1, nMinVectorLength); + } + g_array_append_val(pNewArray, apszWords); + } + + // + // 5. Cleanup and return. + // + g_strfreev(apszLines); + g_free(pszFileContent); + + *ppReturnArray = pNewArray; + return TRUE; +} + +gboolean util_find_string_in_string_vector(const gchar* pszSearch, const gchar** apszVector, gint* pnReturnIndex) +{ + g_assert(pszSearch != NULL); + g_assert(apszVector != NULL); + + gint i=0; + while(apszVector[i] != NULL) { + if(g_ascii_strcasecmp(pszSearch, apszVector[i]) == 0) { + if(pnReturnIndex != NULL) { + g_assert(*pnReturnIndex == -1); // require either NULL or pointer to (gint)-1 + *pnReturnIndex = i; + } + return TRUE; + } + i++; + } + return FALSE; +} @@ -68,6 +68,9 @@ gboolean util_gtk_window_set_fullscreen(GtkWindow* pWindow, gboolean bFullscreen gboolean util_gtk_range_instant_set_on_value_changing_callback(GtkRange *range, GtkScrollType scroll, gdouble value, gpointer user_data); const gchar* util_gtk_menu_item_get_label_text(GtkMenuItem* pMenuItem); +gboolean util_load_array_of_string_vectors(const gchar* pszPath, GArray** ppReturnArray, gint nMinNamesPerRow); +gboolean util_find_string_in_string_vector(const gchar* pszSearch, const gchar** apszVector, gint* pnReturnIndex); + // if glib < 2.6 #if(!GLIB_CHECK_VERSION(2,6,0)) gint g_strv_length(const gchar** a); |