summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog25
-rw-r--r--data/roadster.glade40
-rw-r--r--src/Makefile.am4
-rw-r--r--src/db.c22
-rw-r--r--src/db.h3
-rw-r--r--src/geometryset.c232
-rw-r--r--src/geometryset.h48
-rw-r--r--src/glyph.c14
-rw-r--r--src/gotowindow.c2
-rw-r--r--src/import_tiger.c3
-rw-r--r--src/layers.c66
-rw-r--r--src/layers.h42
-rw-r--r--src/main.c24
-rw-r--r--src/mainwindow.c155
-rw-r--r--src/mainwindow.h3
-rw-r--r--src/map.c807
-rw-r--r--src/map.h153
-rw-r--r--src/road.c221
-rw-r--r--src/road.h84
-rw-r--r--src/scenemanager.c52
-rw-r--r--src/scenemanager.h20
-rw-r--r--src/search.c10
-rw-r--r--src/search_location.c5
-rw-r--r--src/search_road.c54
-rw-r--r--src/searchwindow.c4
-rw-r--r--src/util.h2
26 files changed, 1067 insertions, 1028 deletions
diff --git a/ChangeLog b/ChangeLog
index 3bd5159..2bd6048 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,16 +1,37 @@
+2005-03-01 Ian McIntosh <ian_mcintosh@linuxadvocate.org>
+
+ * road.c:
+ * road.h: Added with code removed from map module.
+ * geometryset.c:
+ * geometryset.h: Removed.
+ * map.c: Moved static data to road.c. Removed global map object and moved to allocated map object (all map_* functions take a map pointer now). Trying to switch to threaded rendering (currently disabled).
+ * db.c: Added support for locking.
+ * mainwindow.c: Now owns an allocated map object. Switched from single-click to double-click to move around.
+ * gotowindow.c: Talk to mainwindow only, not map.
+ * layers.c: Don't store loaded map data in the layers settings structure. (Stored in map object now.)
+ * main.c: Changed main_init() to return boolean.
+ * scenemanager.c: Removed global data, switched to allocated (a scenemanager is owned by a map).
+ * search.c: Can now deal with search strings containing newlines and other whitespace junk.
+ * search_road.c: Perform exact-match for street names of 3 or fewer chars for speed and results quality.
+
2005-02-28 Nathan Fredrickson <nathan@silverorange.com>
* README: Update dependency list.
* configure.ac: Re-add -lmygcc. Clean up.
2005-02-28 Nathan Fredrickson <nathan@silverorange.com>
* main.c: Make main_init() return a value.
- * mainwindow.c: Add missing prototype.
+ * mainwindow.c: Add missing prototype.
* configure.ac: Add pkgconfig check for libsvg and libsvg-cairo.
* src/Makefile.am: Remove the hacky inclusion of libsvg-cairo.
2005-02-27 Ian McIntosh <ian_mcintosh@linuxadvocate.org>
- * configure.ac: Added libsvg-cairo as dependency. (Not quite correct. Nate will fix it.:)
+ * glyph.c:
+ * glyph.h: Added.
+
+2005-02-27 Ian McIntosh <ian_mcintosh@linuxadvocate.org>
+
+ * configure.ac: Added libsvg-cairo as dependency. (Not quite correct? Nate will fix it.:)
* Makefile.am: Added glyph.c.
* datasetwindow.c: Removed Import button.
* db.c: Removed debugging comments. City with the same name are no longer shared between states.
diff --git a/data/roadster.glade b/data/roadster.glade
index 32bbc7a..13aabcd 100644
--- a/data/roadster.glade
+++ b/data/roadster.glade
@@ -335,44 +335,6 @@
</child>
<child>
- <widget class="GtkToolItem" id="toolitem17">
- <property name="visible">True</property>
- <property name="visible_horizontal">True</property>
- <property name="visible_vertical">True</property>
- <property name="is_important">False</property>
-
- <child>
- <widget class="GtkToolButton" id="gotobutton">
- <property name="label" translatable="yes"></property>
- <property name="use_underline">True</property>
- <property name="stock_id">gtk-jump-to</property>
- <property name="visible_horizontal">True</property>
- <property name="visible_vertical">True</property>
- <property name="is_important">False</property>
- <signal name="clicked" handler="on_gotobutton_clicked" last_modification_time="Thu, 09 Sep 2004 20:11:08 GMT"/>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkSeparatorToolItem" id="separatortoolitem2">
- <property name="sensitive">False</property>
- <property name="draw">True</property>
- <property name="visible_horizontal">True</property>
- <property name="visible_vertical">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">False</property>
- </packing>
- </child>
-
- <child>
<widget class="GtkToolItem" id="toolitem20">
<property name="visible">True</property>
<property name="visible_horizontal">True</property>
@@ -489,7 +451,7 @@
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">True</property>
- <property name="width_chars">28</property>
+ <property name="width_chars">23</property>
</widget>
</child>
</widget>
diff --git a/src/Makefile.am b/src/Makefile.am
index 18069b9..9e66cac 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,7 +23,6 @@ roadster_SOURCES = \
mainwindow.c\
gotowindow.c\
map.c\
- geometryset.c\
layers.c\
import.c\
import_tiger.c\
@@ -42,7 +41,8 @@ roadster_SOURCES = \
point.c\
pointstring.c\
track.c\
- glyph.c
+ glyph.c\
+ road.c
roadster_LDADD = \
$(GNOME_LIBS) \
diff --git a/src/db.c b/src/db.c
index f0b2d45..fcad609 100644
--- a/src/db.c
+++ b/src/db.c
@@ -37,7 +37,6 @@
#include "db.h"
#include "mainwindow.h"
-#include "geometryset.h"
#include "util.h"
#include "layers.h"
#include "locationset.h"
@@ -54,12 +53,23 @@
#define MYSQL_GET_RESULT(x) mysql_store_result((x))
db_connection_t* g_pDB = NULL;
+GMutex* g_pDBMutex = NULL;
+
+void db_lock(void)
+{
+ g_mutex_lock(g_pDBMutex);
+}
+
+void db_unlock(void)
+{
+ g_mutex_unlock(g_pDBMutex);
+}
gboolean db_query(const gchar* pszSQL, db_resultset_t** ppResultSet)
{
g_assert(pszSQL != NULL);
if(g_pDB == NULL) return FALSE;
-
+
if(mysql_query(g_pDB->m_pMySQLConnection, pszSQL) != MYSQL_RESULT_SUCCESS) {
g_warning("db_query: %s (SQL: %s)\n", mysql_error(g_pDB->m_pMySQLConnection), pszSQL);
return FALSE;
@@ -67,7 +77,7 @@ gboolean db_query(const gchar* pszSQL, db_resultset_t** ppResultSet)
// get result?
if(ppResultSet != NULL) {
- *ppResultSet = (db_resultset_t*)MYSQL_GET_RESULT(g_pDB->m_pMySQLConnection);
+ *ppResultSet = (db_resultset_t*)MYSQL_GET_RESULT(g_pDB->m_pMySQLConnection);
}
return TRUE;
}
@@ -76,7 +86,7 @@ static gboolean db_insert(const gchar* pszSQL, gint* pnReturnRowsInserted)
{
g_assert(pszSQL != NULL);
if(g_pDB == NULL) return FALSE;
-
+
if(mysql_query(g_pDB->m_pMySQLConnection, pszSQL) != MYSQL_RESULT_SUCCESS) {
g_warning("db_query: %s (SQL: %s)\n", mysql_error(g_pDB->m_pMySQLConnection), pszSQL);
return FALSE;
@@ -182,6 +192,8 @@ gboolean db_is_empty()
// call once on program start-up
void db_init()
{
+ g_pDBMutex = g_mutex_new();
+
#ifdef HAVE_MYSQL_EMBED
gchar* pszDataDir = g_strdup_printf("%s/.roadster/data", g_get_home_dir());
gchar* pszSetDataDirCommand = g_strdup_printf("--datadir=%s", pszDataDir);
@@ -572,7 +584,7 @@ void db_create_tables()
" Name VARCHAR(30) NOT NULL,"
" SuffixID INT1 UNSIGNED NOT NULL,"
" PRIMARY KEY (ID),"
- " UNIQUE KEY (Name(30), SuffixID));", NULL);
+ " UNIQUE KEY (Name(15), SuffixID));", NULL);
// Road_RoadName
db_query("CREATE TABLE IF NOT EXISTS Road_RoadName("
diff --git a/src/db.h b/src/db.h
index 95628ba..fcbe22e 100644
--- a/src/db.h
+++ b/src/db.h
@@ -93,4 +93,7 @@ gboolean db_insert_road(gint nLayerType,
gboolean db_city_get_id(const gchar* pszName, gint nStateID, gint* pnReturnID);
gboolean db_state_get_id(const gchar* pszName, gint* pnReturnID);
+void db_lock(void);
+void db_unlock(void);
+
#endif
diff --git a/src/geometryset.c b/src/geometryset.c
deleted file mode 100644
index 706dfa7..0000000
--- a/src/geometryset.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/***************************************************************************
- * geometryset.c
- *
- * Copyright 2005 Ian McIntosh
- * ian_mcintosh@linuxadvocate.org
- ****************************************************************************/
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*
- A GeometrySet holds an array of geometry objects (used for roads, railroads and parks right now)
-*/
-
-#include <gtk/gtk.h>
-#include <string.h>
-#include <stdlib.h>
-#include "geometryset.h"
-#include "map.h"
-#include "util.h"
-#include "point.h"
-#include "pointstring.h"
-#include "db.h"
-#include "layers.h"
-
-
-/*******************************************************
-** construction / destruction
-*******************************************************/
-gboolean geometryset_new(geometryset_t** ppGeometrySet)
-{
- g_return_val_if_fail(ppGeometrySet != NULL, FALSE);
- g_return_val_if_fail(*ppGeometrySet == NULL, FALSE); // must be a pointer to a NULL pointer
-
- // create geometryset
- geometryset_t* pNew = g_new0(geometryset_t, 1);
-
- // initialize it
- pNew->m_pPointStringsArray = g_ptr_array_sized_new(20);
- g_return_val_if_fail(pNew->m_pPointStringsArray != NULL, FALSE);
-
- *ppGeometrySet = pNew;
- return TRUE;
-}
-
-// free all shapes
-void geometryset_clear(geometryset_t* pGeometrySet)
-{
- int i;
-
- // Free each pointstring
- for(i = (pGeometrySet->m_pPointStringsArray->len - 1) ; i>=0 ; i--) {
- pointstring_t* pPointString = g_ptr_array_remove_index_fast(pGeometrySet->m_pPointStringsArray, i);
- pointstring_free(pPointString);
- }
-}
-
-void geometryset_free(geometryset_t* pGeometrySet)
-{
- g_assert("FALSE"); // not used/tested/written yet
-
- g_return_if_fail(pGeometrySet != NULL);
- g_return_if_fail(pGeometrySet->m_pPointStringsArray != NULL);
-
- // Empty it first...
- geometryset_clear(pGeometrySet);
-
- g_assert(pGeometrySet->m_pPointStringsArray->len == 0);
-
- // Free the data structures themselves
- g_ptr_array_free(pGeometrySet->m_pPointStringsArray, FALSE); // FALSE means don't delete items
- pGeometrySet->m_pPointStringsArray = NULL;
-}
-
-gboolean geometryset_load_geometry(maprect_t* pRect)
-{
- g_return_val_if_fail(pRect != NULL, FALSE);
-
- db_resultset_t* pResultSet = NULL;
- db_row_t aRow;
-
- gint nZoomLevel = map_get_zoomlevel();
-
- TIMER_BEGIN(mytimer, "BEGIN Geometry LOAD");
-
- // HACKY: make a list of layer IDs "2,3,5,6"
- gchar azLayerNumberList[200] = {0};
- gint nActiveLayerCount = 0;
- gint i;
- for(i=LAYER_FIRST ; i <= LAYER_LAST ;i++) {
- if(g_aLayers[i].m_Style.m_aSubLayers[0].m_afLineWidths[nZoomLevel-1] != 0.0 ||
- g_aLayers[i].m_Style.m_aSubLayers[1].m_afLineWidths[nZoomLevel-1] != 0.0)
- {
- gchar azLayerNumber[10];
-
- if(nActiveLayerCount > 0) g_snprintf(azLayerNumber, 10, ",%d", i);
- else g_snprintf(azLayerNumber, 10, "%d", i);
-
- g_strlcat(azLayerNumberList, azLayerNumber, 200);
- nActiveLayerCount++;
- }
- }
- if(nActiveLayerCount == 0) {
- g_print("no visible layers!\n");
- layers_clear();
- return TRUE;
- }
-
- // generate SQL
- gchar* pszSQL = g_strdup_printf(
- "SELECT Road.ID, Road.TypeID, AsText(Road.Coordinates), RoadName.Name, RoadName.SuffixID"
- " FROM Road "
- " LEFT JOIN Road_RoadName ON (Road.ID=Road_RoadName.RoadID)"
- " LEFT JOIN RoadName ON (Road_RoadName.RoadNameID=RoadName.ID)"
- " WHERE"
- " TypeID IN (%s) AND"
- " MBRIntersects(GeomFromText('Polygon((%f %f,%f %f,%f %f,%f %f,%f %f))'), Coordinates)",
- azLayerNumberList,
- pRect->m_A.m_fLatitude, pRect->m_A.m_fLongitude, // upper left
- pRect->m_A.m_fLatitude, pRect->m_B.m_fLongitude, // upper right
- pRect->m_B.m_fLatitude, pRect->m_B.m_fLongitude, // bottom right
- pRect->m_B.m_fLatitude, pRect->m_A.m_fLongitude, // bottom left
- pRect->m_A.m_fLatitude, pRect->m_A.m_fLongitude // upper left again
- );
- //g_print("sql: %s\n", pszSQL);
-
- db_query(pszSQL, &pResultSet);
- g_free(pszSQL);
-
- TIMER_SHOW(mytimer, "after query");
-
- guint32 uRowCount = 0;
- if(pResultSet) {
- // HACK: empty out old data, since we don't know how to merge yet
- layers_clear();
- TIMER_SHOW(mytimer, "after clear layers");
- while((aRow = db_fetch_row(pResultSet))) {
- uRowCount++;
-
- // aRow[0] is ID
- // aRow[1] is TypeID
- // aRow[2] is Coordinates in mysql's text format
- // aRow[3] is road name
- // aRow[4] is road name suffix id
-// g_print("data: %s, %s, %s, %s, %s\n", aRow[0], aRow[1], aRow[2], aRow[3], aRow[4]);
-
- // Get layer type that this belongs on
- gint nTypeID = atoi(aRow[1]);
- if(nTypeID < LAYER_FIRST || nTypeID > LAYER_LAST) {
- g_warning("geometry record '%s' has bad type '%s'\n", aRow[0], aRow[1]);
- continue;
- }
-
- // Extract points
- pointstring_t* pNewPointString = NULL;
- if(!pointstring_alloc(&pNewPointString)) {
- g_warning("out of memory loading pointstrings\n");
- continue;
- }
- db_parse_pointstring(aRow[2], pNewPointString, point_alloc);
-
- // Build name by adding suffix, if one is present
- gchar azFullName[100] = "";
-
- // does it have a name?
- if(aRow[3] != NULL && aRow[4] != NULL) {
- gint nSuffixID = atoi(aRow[4]);
- const gchar* pszSuffix = map_road_suffix_itoa(nSuffixID, SUFFIX_LENGTH_SHORT);
- g_snprintf(azFullName, 100, "%s%s%s",
- aRow[3], (pszSuffix[0] != '\0') ? " " : "", pszSuffix);
- }
- pNewPointString->m_pszName = g_strdup(azFullName);
-
- // Add this item to layer's list of pointstrings
- g_ptr_array_add(g_aLayers[nTypeID].m_pGeometrySet->m_pPointStringsArray, pNewPointString);
- } // end while loop on rows
- g_print("[%d rows]\n", uRowCount);
- TIMER_SHOW(mytimer, "after rows retrieved");
-
- db_free_result(pResultSet);
- TIMER_SHOW(mytimer, "after free results");
- TIMER_END(mytimer, "END Geometry LOAD");
-
- return TRUE;
- }
- else {
- g_print(" no rows\n");
- return FALSE;
- }
-}
-
-#ifdef ROADSTER_DEAD_CODE
-/*******************************************************
-** Debug functions
-*******************************************************/
-/*
-void geometryset_debug_print(geometryset_t* pGeometrySet)
-{
- if(pGeometrySet->m_pPointStringsArray == NULL) {
- g_print("m_pPointStringsArray is NULL\n");
- }
- else {
- g_print("pointstring list (%d items):\n", pGeometrySet->m_pPointStringsArray->len);
- int i;
- for(i=0 ; i<pGeometrySet->m_pPointStringsArray->len ; i++) {
- pointstring_t* pPointString = g_ptr_array_index(pGeometrySet->m_pPointStringsArray, i);
-
- g_print("- string (%d items): ", pPointString->m_pPointsArray->len);
- int j;
- for(j=0 ; j<pPointString->m_pPointsArray->len ; j++) {
- mappoint_t* pPoint = g_ptr_array_index(pPointString->m_pPointsArray, j);
- g_print("(%.5f,%.5f), ", pPoint->m_fLatitude, pPoint->m_fLongitude);
- }
- g_print("\n");
- }
- }
-}
-*/
-#endif
diff --git a/src/geometryset.h b/src/geometryset.h
deleted file mode 100644
index 6de9920..0000000
--- a/src/geometryset.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/***************************************************************************
- * geometryset.h
- *
- * Copyright 2005 Ian McIntosh
- * ian_mcintosh@linuxadvocate.org
- ****************************************************************************/
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GEOMETRYSET_H__
-#define __GEOMETRYSET_H__
-
-// a geometry set holds all the geometry for a layer
-typedef struct geometryset {
- GPtrArray* m_pPointStringsArray;
-} geometryset_t;
-
-#include "map.h"
-
-void geometryset_init(void);
-void geometryset_free(geometryset_t* pGeometrySet);
-void geometryset_clear(geometryset_t* pGeometrySet);
-
-gboolean geometryset_new(geometryset_t** ppGeometrySet);
-
-//gboolean geometryset_util_new_point(mappoint_t** ppPoint);
-//gboolean geometryset_util_new_pointstring(pointstring_t** ppPointString);
-//void geometryset_util_free_pointstring(pointstring_t* pPointString);
-
-gboolean geometryset_load_geometry(maprect_t* pRect);
-
-//void geometryset_debug_print(geometryset_t* pGeometrySet);
-
-#endif
diff --git a/src/glyph.c b/src/glyph.c
index 08451f1..fa4abf1 100644
--- a/src/glyph.c
+++ b/src/glyph.c
@@ -42,7 +42,7 @@ struct {
void glyph_init(void)
{
g_Glyph.m_pGlyphArray = g_ptr_array_new();
- g_ptr_array_add(g_Glyph.m_pGlyphArray, NULL); // index 0 is taken!
+ g_ptr_array_add(g_Glyph.m_pGlyphArray, NULL); // index 0 is taken! (it's the "no glyph" value)
}
gint glyph_load(const gchar* pszPath)
@@ -85,17 +85,17 @@ static gboolean glyph_lookup(gint nGlyphHandle, glyph_t** ppReturnGlyph)
void glyph_draw_centered(cairo_t* pCairo, gint nGlyphHandle, gdouble fX, gdouble fY)
{
+ if(nGlyphHandle == 0) return;
+
glyph_t* pGlyph = NULL;
if(!glyph_lookup(nGlyphHandle, &pGlyph)) {
- // use a default glyph?
- return;
+ g_assert_not_reached();
}
cairo_save(pCairo);
-// cairo_scale(pCairo, 2, 2);
- cairo_set_alpha(pCairo, 0.5);
- cairo_translate(pCairo, (fX - (pGlyph->m_nWidth/2)), (fY - (pGlyph->m_nHeight/2)));
- svg_cairo_render(pGlyph->m_pCairoSVG, pCairo);
+ cairo_set_alpha(pCairo, 0.5);
+ cairo_translate(pCairo, (fX - (pGlyph->m_nWidth/2)), (fY - (pGlyph->m_nHeight/2)));
+ svg_cairo_render(pGlyph->m_pCairoSVG, pCairo);
cairo_restore(pCairo);
}
diff --git a/src/gotowindow.c b/src/gotowindow.c
index cd1c050..dd441d6 100644
--- a/src/gotowindow.c
+++ b/src/gotowindow.c
@@ -153,7 +153,7 @@ static gboolean gotowindow_go(void)
// TODO: error checking for 0 (meaning either bad text "3a21" or "000" etc.
- map_set_centerpoint(&pt);
+ mainwindow_set_centerpoint(&pt);
mainwindow_draw_map();
mainwindow_statusbar_update_position();
return TRUE;
diff --git a/src/import_tiger.c b/src/import_tiger.c
index ca0a3e2..260d473 100644
--- a/src/import_tiger.c
+++ b/src/import_tiger.c
@@ -31,6 +31,7 @@
#include "util.h"
#include "import_tiger.h"
#include "importwindow.h"
+#include "road.h"
#define TIGER_RT1_LINE_LENGTH (230)
#define TIGER_RT2_LINE_LENGTH (210)
@@ -494,7 +495,7 @@ static gboolean import_tiger_parse_table_1(gchar* pBuffer, gint nLength, GHashTa
gchar achType[5];
import_tiger_read_string(&pLine[50-1], 4, &achType[0]);
// g_print("%30s is type %s\n", pRecord->m_achName, achType);
- map_road_suffix_atoi(achType, &pRecord->m_nRoadNameSuffixID);
+ road_suffix_atoi(achType, &pRecord->m_nRoadNameSuffixID);
if(achType[0] != '\0' && pRecord->m_nRoadNameSuffixID == ROAD_SUFFIX_NONE) {
g_print("type '%s' couldn't be looked up\n", achType);
diff --git a/src/layers.c b/src/layers.c
index dc2a420..c5dddfa 100644
--- a/src/layers.c
+++ b/src/layers.c
@@ -43,8 +43,8 @@ layer_t g_aLayers[NUM_LAYERS + 1] = {
{{0,0,0,0,0,0,0,0,0,0}, /* font size */
{0,0,0,0,0,0,0,0,0,0}, /* bold */
{0,0,0,0,0,0,0,0,0,0}, /* halo */
- {0,0,0,0}},
- NULL},
+ {0,0,0,0}}
+ },
/* 1 */ {LAYER_MINORSTREET, "Minor Roads",
{{
@@ -53,11 +53,11 @@ layer_t g_aLayers[NUM_LAYERS + 1] = {
{{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.5, 10.0, 16.0,32.0}, {255/255.0, 251/255.0, 255/255.0, 1.00}, 0, CAIRO_LINE_JOIN_MITER, CAIRO_LINE_CAP_ROUND}
}},
- {{0,0,0,0,0,0,0,10,18,32}, /* font size */
+ {{0,0,0,0,0,0,0,10,14,32}, /* font size */
{0,0,0,0,0,0,0,0,0,0}, /* bold */
{0,0,0,0,0,0,0,0,0,0}, /* halo */
- {0,0,0,0}},
- NULL},
+ {0,0,0,0}}
+ },
/* 2 */ {LAYER_MAJORSTREET, "Major Roads",
{{
@@ -68,8 +68,8 @@ layer_t g_aLayers[NUM_LAYERS + 1] = {
{{0,0,0,0,0,8,10,12,20,34}, /* font size */
{0,0,0,0,0,0,0,0,1,1}, /* bold */
{0,0,0,0,0,0,0,0,0,0}, /* halo */
- {0,0,0,0}},
- NULL},
+ {0,0,0,0}}
+ },
/* 3 */ {LAYER_MINORHIGHWAY, "Minor Highways",
{{
@@ -80,8 +80,8 @@ layer_t g_aLayers[NUM_LAYERS + 1] = {
{{0,0,0,0,0,6,12,16,18,26}, /* font size */
{0,0,0,0,0,0,1,1,1,1}, /* bold */
{0,0,0,0,0,0,0,0,0,0}, /* halo */
- {0,0,0,0}},
- NULL},
+ {0,0,0,0}}
+ },
/* 4 */ {LAYER_MINORHIGHWAY_RAMP, "Minor Highway Ramps",
{{
@@ -92,8 +92,8 @@ layer_t g_aLayers[NUM_LAYERS + 1] = {
{{0,0,0,0,0,0,0,0,0,0}, /* font size */
{0,0,0,0,0,0,0,0,0,0}, /* bold */
{0,0,0,0,0,0,0,0,0,0}, /* halo */
- {0,0,0,0}},
- NULL},
+ {0,0,0,0}}
+ },
/* 5 */ {LAYER_MAJORHIGHWAY, "Major Highways",
{{
@@ -104,8 +104,8 @@ layer_t g_aLayers[NUM_LAYERS + 1] = {
{{0,0,0,0,0,6,8,10,16,26}, /* font size */
{0,0,0,0,0,0,1,1,1,1}, /* bold */
{0,0,0,0,0,0,0,0,0,0}, /* halo */
- {0,0,0,0}},
- NULL},
+ {0,0,0,0}}
+ },
/* 6 */ {LAYER_MAJORHIGHWAY_RAMP, "Major Highway Ramps",
{{
@@ -116,8 +116,8 @@ layer_t g_aLayers[NUM_LAYERS + 1] = {
{{0,0,0,0,0,0,0,0,0,0}, /* font size */
{0,0,0,0,0,0,0,0,0,0}, /* bold */
{0,0,0,0,0,0,0,0,0,0}, /* halo */
- {0,0,0,0}},
- NULL},
+ {0,0,0,0}}
+ },
/* 7 */ {LAYER_RAILROAD, "Railroads",
{{
@@ -128,8 +128,8 @@ layer_t g_aLayers[NUM_LAYERS + 1] = {
{{0,0,0,0,0,0,10,10,10,10}, /* font size */
{0,0,0,0,0,0,0,0,0,0}, /* bold */
{0,0,0,0,0,0,4,4,4,4}, /* halo */
- {0,0,0,0}},
- NULL},
+ {0,0,0,0}}
+ },
/* 8 */ {LAYER_PARK, "Parks",
{{
@@ -140,8 +140,8 @@ layer_t g_aLayers[NUM_LAYERS + 1] = {
{{0,0,0,0,0,0,10,12,12,14}, /* font size */
{0,0,0,0,0,0,1,1,1,1}, /* bold */
{0,0,0,0,0,0,3,3,3,3}, /* halo */
- {0.1,0.1,0.1, 1.0}},
- NULL},
+ {0.1,0.1,0.1, 1.0}}
+ },
/* 9 */{LAYER_RIVER, "Rivers",
{{
@@ -152,8 +152,8 @@ layer_t g_aLayers[NUM_LAYERS + 1] = {
{{0,0,0,0,0,0,10,12,12,14}, /* font size */
{0,0,0,0,0,0,1,1,1,1}, /* bold */
{0,0,0,0,0,0,3,3,3,3}, /* halo */
- {128/255.0, 158/255.0, 180/255.0, 1.0}},
- NULL},
+ {128/255.0, 158/255.0, 180/255.0, 1.0}}
+ },
/* 10 */{LAYER_LAKE, "Lakes",
{{
@@ -164,8 +164,8 @@ layer_t g_aLayers[NUM_LAYERS + 1] = {
{{0,0,0,0,0,0,10,12,12,14}, /* font size */
{0,0,0,0,0,0,1,1,1,1}, /* bold */
{0,0,0,0,0,0,3,3,3,3}, /* halo */
- {0.1,0.1,0.1, 1.0}},
- NULL},
+ {0.1,0.1,0.1, 1.0}}
+ },
/* 11 */{LAYER_MISC_AREA, "Misc Areas",
{{
@@ -176,22 +176,6 @@ layer_t g_aLayers[NUM_LAYERS + 1] = {
{{0,0,0,0,0,0,10,12,12,14}, /* font size */
{0,0,0,0,0,0,1,1,1,1}, /* bold */
{0,0,0,0,0,0,3,3,3,3}, /* halo */
- {0.25,0.25,0.25,1.0}},
- NULL},
+ {0.25,0.25,0.25,1.0}}
+ },
};
-
-void layers_init()
-{
- gint i;
- for(i=LAYER_FIRST ; i<=LAYER_LAST ; i++) {
- geometryset_new(&(g_aLayers[i].m_pGeometrySet));
- }
-}
-
-void layers_clear()
-{
- gint i;
- for(i=LAYER_FIRST ; i<=LAYER_LAST ; i++) {
- geometryset_clear(g_aLayers[i].m_pGeometrySet);
- }
-}
diff --git a/src/layers.h b/src/layers.h
index 2cc06af..7c92013 100644
--- a/src/layers.h
+++ b/src/layers.h
@@ -21,11 +21,10 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#ifndef _LAYERS_H
-#define _LAYERS_H
+#ifndef _LAYERS_H_
+#define _LAYERS_H_
#include <gtk/gtk.h>
-#include "geometryset.h"
#ifdef __cplusplus
extern "C"
@@ -34,23 +33,25 @@ extern "C"
#define LAYER_NONE (0)
-#define LAYER_MINORSTREET (1)
-#define LAYER_MAJORSTREET (2)
-#define LAYER_MINORHIGHWAY (3)
-#define LAYER_MINORHIGHWAY_RAMP (4)
-#define LAYER_MAJORHIGHWAY (5) // used?
-#define LAYER_MAJORHIGHWAY_RAMP (6) // used?
-#define LAYER_RAILROAD (7)
+#define LAYER_MINORSTREET (1)
+#define LAYER_MAJORSTREET (2)
+#define LAYER_MINORHIGHWAY (3)
+#define LAYER_MINORHIGHWAY_RAMP (4)
+#define LAYER_MAJORHIGHWAY (5) // used?
+#define LAYER_MAJORHIGHWAY_RAMP (6) // used?
+#define LAYER_RAILROAD (7)
#define LAYER_PARK (8)
#define LAYER_RIVER (9)
#define LAYER_LAKE (10)
-#define LAYER_MISC_AREA (11)
+#define LAYER_MISC_AREA (11)
#define NUM_LAYERS (11)
-
+
#define LAYER_FIRST (1)
#define LAYER_LAST (11)
+#include "map.h"
+
typedef struct color {
gfloat m_fRed;
gfloat m_fGreen;
@@ -74,21 +75,12 @@ typedef struct sublayerstyle {
gint m_nCapStyle;
} sublayerstyle_t;
- //~ gint m_nMinZoomLevel;
- //~ gdouble m_fTopLineWidthPercent;
- //~ gdouble m_afLineWidths[10];
- //~ color_t m_clrLowDetail;
- //~ color_t m_clrFill;
- //~ color_t m_clrOutline;
- //~ gint m_nDashStyle; // index into dashes table
-
typedef struct textlabelstyle {
gdouble m_afFontSizeAtZoomLevel[MAX_ZOOM_LEVEL];
gint m_abBoldAtZoomLevel[MAX_ZOOM_LEVEL]; // 0s or 1s
gint m_afHaloAtZoomLevel[MAX_ZOOM_LEVEL]; // stroke width
color_t m_clrColor;
// font family...
- // font style...
} textlabelstyle_t;
// defines the look of a layer
@@ -100,17 +92,13 @@ typedef struct layer {
gint nLayerIndex;
gchar* m_pszName;
layerstyle_t m_Style;
- textlabelstyle_t m_TextLabelStyle;
- geometryset_t* m_pGeometrySet;
+ textlabelstyle_t m_TextLabelStyle;
} layer_t;
extern layer_t g_aLayers[NUM_LAYERS+1];
-void layers_init(void);
-void layers_clear(void);
-
#ifdef __cplusplus
}
#endif
-#endif /* _LAYERS_H */
+#endif /* _LAYERS_H_ */
diff --git a/src/main.c b/src/main.c
index 57fc9c6..718c7a9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -28,7 +28,6 @@
#include <gnome.h>
#include "gui.h"
#include "db.h"
-#include "geometryset.h"
#include "mainwindow.h"
#include "map.h"
#include "import.h"
@@ -39,7 +38,7 @@
#include "pointstring.h"
#include "track.h"
-static int main_init(void);
+static gboolean main_init(void);
static void main_deinit(void);
int main (int argc, char *argv[])
@@ -52,21 +51,23 @@ int main (int argc, char *argv[])
#endif
gnome_init(PACKAGE, VERSION, argc, argv);
- ret = main_init();
-
- if (ret)
- return ret;
+ if(!main_init()) {
+ return 1;
+ }
gui_run();
main_deinit(); // usually doesn't get here
return 0;
}
-int main_init(void)
+gboolean main_init(void)
{
+ // Initialize GLib thread system
+ // g_thread_init(NULL);
+
if(!gnome_vfs_init()) {
g_warning("gnome_vfs_init failed\n");
- return 1;
+ return FALSE;
}
gchar* pszApplicationDir = g_strdup_printf("%s/.roadster", g_get_home_dir());
if(GNOME_VFS_OK != gnome_vfs_make_directory(pszApplicationDir, 0700)) {
@@ -84,18 +85,19 @@ int main_init(void)
track_init();
g_print("initializing glyphs\n");
glyph_init();
+ g_print("initializing map\n");
+ map_init();
g_print("initializing scenemanager\n");
scenemanager_init();
//geometryset_init();
+
g_print("initializing locationsets\n");
locationset_init();
g_print("initializing gpsclient\n");
gpsclient_init();
g_print("initializing gui\n");
gui_init();
- g_print("initializing layers\n");
- layers_init();
g_print("initializing db\n");
db_init();
@@ -107,7 +109,7 @@ int main_init(void)
g_print("initialization complete\n");
- return 0;
+ return TRUE;
}
static void main_deinit(void)
diff --git a/src/mainwindow.c b/src/mainwindow.c
index 28b071c..7928ece 100644
--- a/src/mainwindow.c
+++ b/src/mainwindow.c
@@ -59,9 +59,8 @@
#define LAYERLIST_COLUMN_NAME (1)
// Limits
-#define MAX_SEARCH_TEXT_LENGTH (100)
-
-#define SPEED_LABEL_FORMAT ("<span font_desc='32'>%.0f</span>")
+#define MAX_SEARCH_TEXT_LENGTH (100)
+#define SPEED_LABEL_FORMAT ("<span font_desc='32'>%.0f</span>")
// Settings
#define TIMER_GPS_REDRAW_INTERVAL_MS (2500) // lower this (to 1?) when it's faster to redraw track
@@ -105,17 +104,16 @@ struct {
GtkImage* m_pStatusbarGPSIcon;
GtkWidget *m_pSidebox;
-
// Sidebar
-
+
// "Draw" Sidebar
GtkTreeView* m_pLayersListTreeView;
GtkTreeView* m_pLocationSetsTreeView;
-
+
// "GPS" sidebar
GtkLabel* m_pSpeedLabel;
GtkProgressBar* m_pGPSSignalStrengthProgressBar;
-
+
// Statusbar
GtkVBox* m_pStatusbar;
GtkLabel* m_pPositionLabel;
@@ -128,14 +126,16 @@ struct {
// Drawing area
// GtkWidget* m_pDrawWidget;
GtkDrawingArea* m_pDrawingArea;
- GdkPixmap* m_pOffscreenPixmap;
-
+
+ map_t* m_pMap;
+
EToolType m_eSelectedTool;
gint m_nCurrentGPSPath;
gint m_nGPSLocationGlyph;
} g_MainWindow = {0};
+
// Data
toolsettings_t g_Tools[] = {
{"Pointer Tool", {GDK_LEFT_PTR, NULL}},
@@ -220,6 +220,9 @@ void mainwindow_init(GladeXML* pGladeXML)
// create drawing area
g_MainWindow.m_pDrawingArea = GTK_DRAWING_AREA(gtk_drawing_area_new());
+ g_print("creating map\n");
+ map_new(&g_MainWindow.m_pMap, GTK_WIDGET(g_MainWindow.m_pDrawingArea));
+
// add signal handlers to drawing area
gtk_widget_add_events(GTK_WIDGET(g_MainWindow.m_pDrawingArea), GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
g_signal_connect(G_OBJECT(g_MainWindow.m_pDrawingArea), "expose_event", G_CALLBACK(mainwindow_on_expose_event), NULL);
@@ -292,18 +295,18 @@ void mainwindow_init(GladeXML* pGladeXML)
mainwindow_load_locationset_list();
/* add some data to the layers list */
- GtkTreeIter iter;
-
- int i;
- for(i=LAYER_FIRST ; i<=LAYER_LAST ; i++) {
- gboolean bEnabled = TRUE;
-
- gtk_list_store_append(GTK_LIST_STORE(pLayersListStore), &iter);
- gtk_list_store_set(GTK_LIST_STORE(pLayersListStore), &iter,
- LAYERLIST_COLUMN_ENABLED, bEnabled,
- LAYERLIST_COLUMN_NAME, g_aLayers[i].m_pszName,
- -1);
- }
+// GtkTreeIter iter;
+//
+// int i;
+// for(i=LAYER_FIRST ; i<=LAYER_LAST ; i++) {
+// gboolean bEnabled = TRUE;
+//
+// gtk_list_store_append(GTK_LIST_STORE(pLayersListStore), &iter);
+// gtk_list_store_set(GTK_LIST_STORE(pLayersListStore), &iter,
+// LAYERLIST_COLUMN_ENABLED, bEnabled,
+// LAYERLIST_COLUMN_NAME, g_aLayers[i].m_pszName,
+// -1);
+// }
g_timeout_add(TIMER_GPS_REDRAW_INTERVAL_MS,
(GSourceFunc)mainwindow_callback_on_gps_redraw_timeout,
@@ -393,7 +396,7 @@ gboolean mainwindow_get_statusbar_visible(void)
void mainwindow_statusbar_update_zoomscale(void)
{
char buf[200];
- guint32 uZoomLevelScale = map_get_zoomlevel_scale();
+ guint32 uZoomLevelScale = map_get_zoomlevel_scale(g_MainWindow.m_pMap);
snprintf(buf, 199, "1:%d", uZoomLevelScale);
mainwindow_set_statusbar_zoomscale(buf);
@@ -403,7 +406,7 @@ void mainwindow_statusbar_update_position(void)
{
char buf[200];
mappoint_t pt;
- map_get_centerpoint(&pt);
+ map_get_centerpoint(g_MainWindow.m_pMap, &pt);
g_snprintf(buf, 200, "Lat: %.5f, Lon: %.5f", pt.m_fLatitude, pt.m_fLongitude);
mainwindow_set_statusbar_position(buf);
}
@@ -517,7 +520,7 @@ void on_zoomscale_value_changed(GtkRange *range, gpointer user_data)
gint16 nValue = (gint16)fValue;
gtk_range_set_value(range, (gdouble)nValue);
- map_set_zoomlevel(nValue);
+ map_set_zoomlevel(g_MainWindow.m_pMap, nValue);
mainwindow_statusbar_update_zoomscale();
mainwindow_draw_map();
@@ -528,16 +531,16 @@ void on_zoomscale_value_changed(GtkRange *range, gpointer user_data)
//
static void zoom_in_one(void)
{
- map_set_zoomlevel( map_get_zoomlevel() + 1);
+ map_set_zoomlevel(g_MainWindow.m_pMap, map_get_zoomlevel(g_MainWindow.m_pMap) + 1);
- gtk_range_set_value(GTK_RANGE(g_MainWindow.m_pZoomScale), map_get_zoomlevel());
+ gtk_range_set_value(GTK_RANGE(g_MainWindow.m_pZoomScale), map_get_zoomlevel(g_MainWindow.m_pMap));
}
static void zoom_out_one(void)
{
- map_set_zoomlevel( map_get_zoomlevel() - 1 );
+ map_set_zoomlevel(g_MainWindow.m_pMap, map_get_zoomlevel(g_MainWindow.m_pMap) - 1 );
- gtk_range_set_value(GTK_RANGE(g_MainWindow.m_pZoomScale), map_get_zoomlevel());
+ gtk_range_set_value(GTK_RANGE(g_MainWindow.m_pZoomScale), map_get_zoomlevel(g_MainWindow.m_pMap));
}
static void gui_set_tool(EToolType eTool)
@@ -614,10 +617,10 @@ void mainwindow_on_gotomenuitem_activate(GtkMenuItem *menuitem, gpointer user_da
gotowindow_show();
}
-void on_gotobutton_clicked(GtkToolButton *toolbutton, gpointer user_data)
-{
- gotowindow_show();
-}
+// void on_gotobutton_clicked(GtkToolButton *toolbutton, gpointer user_data)
+// {
+// gotowindow_show();
+// }
static gboolean mainwindow_on_mouse_button_click(GtkWidget* w, GdkEventButton *event)
{
@@ -626,14 +629,14 @@ static gboolean mainwindow_on_mouse_button_click(GtkWidget* w, GdkEventButton *e
gdk_window_get_pointer(w->window, &nX, &nY, NULL);
- // Left-click
- if(event->button == 1 && event->type == GDK_BUTTON_PRESS) {
+ // Left double-click
+ if(event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
if(g_MainWindow.m_eSelectedTool == kToolZoom) {
- map_center_on_windowpoint(nX, nY);
+ map_center_on_windowpoint(g_MainWindow.m_pMap, nX, nY);
zoom_in_one();
}
else if(g_MainWindow.m_eSelectedTool == kToolPointer) {
- map_center_on_windowpoint(nX, nY);
+ map_center_on_windowpoint(g_MainWindow.m_pMap, nX, nY);
}
else {
g_assert(FALSE);
@@ -642,16 +645,16 @@ static gboolean mainwindow_on_mouse_button_click(GtkWidget* w, GdkEventButton *e
mainwindow_statusbar_update_position();
}
// Right-click?
- else if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
- {
- // Save click location for use by callback
- g_MainWindow.m_ptClickLocation.m_nX = nX;
- g_MainWindow.m_ptClickLocation.m_nY = nY;
-
- // Show popup!
- gtk_menu_popup(g_MainWindow.m_pMapPopupMenu, NULL, NULL, NULL, NULL, event->button, event->time);
- return TRUE;
- }
+// else if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
+// {
+// // Save click location for use by callback
+// g_MainWindow.m_ptClickLocation.m_nX = nX;
+// g_MainWindow.m_ptClickLocation.m_nY = nY;
+//
+// // Show popup!
+// gtk_menu_popup(g_MainWindow.m_pMapPopupMenu, NULL, NULL, NULL, NULL, event->button, event->time);
+// return TRUE;
+// }
// map_redraw_if_needed();
return TRUE;
}
@@ -714,53 +717,27 @@ void on_toolbutton_clicked(GtkToolButton *toolbutton, gpointer user_data)
void mainwindow_draw_map(void)
{
-// g_print("mainwindow_draw_map()\n");
-
- void* pBusy = mainwindow_set_busy();
-
- Display* dpy;
- Drawable drawable;
-
- dpy = gdk_x11_drawable_get_xdisplay(g_MainWindow.m_pOffscreenPixmap);
- drawable = gdk_x11_drawable_get_xid(g_MainWindow.m_pOffscreenPixmap);
-
- cairo_t *pCairoInstance;
- pCairoInstance = cairo_create ();
- // draw on an off-screen buffer
- cairo_set_target_drawable(pCairoInstance, dpy, drawable);
- map_draw(pCairoInstance);
-
- pointstring_t* pTrackPointString = track_get_pointstring(g_MainWindow.m_nCurrentGPSPath);
- if(pTrackPointString) {
- map_draw_gps_trail(pCairoInstance, pTrackPointString);
- }
-
- // glyph_draw_centered(pCairoInstance, g_MainWindow.m_nGPSLocationGlyph, 200, 200);
- cairo_destroy(pCairoInstance);
-
- gtk_widget_queue_draw(GTK_WIDGET(g_MainWindow.m_pDrawingArea));
-
- mainwindow_set_not_busy(&pBusy);
+ map_draw_thread_begin(g_MainWindow.m_pMap, GTK_WIDGET(g_MainWindow.m_pDrawingArea));
}
static gint mainwindow_on_configure_event(GtkWidget *pDrawingArea, GdkEventConfigure *event)
{
// Create a new backing pixmap of the appropriate size
- if(g_MainWindow.m_pOffscreenPixmap != NULL) {
- gdk_pixmap_unref(g_MainWindow.m_pOffscreenPixmap);
- }
- g_MainWindow.m_pOffscreenPixmap = gdk_pixmap_new(
- GTK_WIDGET(g_MainWindow.m_pDrawingArea)->window,
- GTK_WIDGET(g_MainWindow.m_pDrawingArea)->allocation.width,
- GTK_WIDGET(g_MainWindow.m_pDrawingArea)->allocation.height,
- -1);
+// if(g_MainWindow.m_pOffscreenPixmap != NULL) {
+// gdk_pixmap_unref(g_MainWindow.m_pOffscreenPixmap);
+// }
+// g_MainWindow.m_pOffscreenPixmap = gdk_pixmap_new(
+// GTK_WIDGET(g_MainWindow.m_pDrawingArea)->window,
+// GTK_WIDGET(g_MainWindow.m_pDrawingArea)->allocation.width,
+// GTK_WIDGET(g_MainWindow.m_pDrawingArea)->allocation.height,
+// -1);
// tell the map how big to draw
dimensions_t dim;
dim.m_uWidth = GTK_WIDGET(g_MainWindow.m_pDrawingArea)->allocation.width;
dim.m_uHeight = GTK_WIDGET(g_MainWindow.m_pDrawingArea)->allocation.height;
- map_set_dimensions(&dim);
+ map_set_dimensions(g_MainWindow.m_pMap, &dim);
mainwindow_draw_map();
return TRUE;
@@ -769,23 +746,26 @@ static gint mainwindow_on_configure_event(GtkWidget *pDrawingArea, GdkEventConfi
static gboolean mainwindow_on_expose_event(GtkWidget *pDrawingArea, GdkEventExpose *event, gpointer data)
{
// g_print("mainwindow_on_expose_event(x=%d,y=%d,w=%d,h=%d)\n", event->area.x, event->area.y, event->area.width, event->area.height);
+ GdkPixmap* pMapPixmap = map_get_pixmap(g_MainWindow.m_pMap);
// Copy relevant portion of off-screen bitmap to window
// TIMER_BEGIN(mytimer, "BEGIN EXPOSE");
gdk_draw_pixmap(GTK_WIDGET(g_MainWindow.m_pDrawingArea)->window,
GTK_WIDGET(g_MainWindow.m_pDrawingArea)->style->fg_gc[GTK_WIDGET_STATE(g_MainWindow.m_pDrawingArea)],
- g_MainWindow.m_pOffscreenPixmap,
+ pMapPixmap,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
// TIMER_END(mytimer, "END EXPOSE");
+
+ map_release_pixmap(g_MainWindow.m_pMap);
return FALSE;
}
void mainwindow_on_addpointmenuitem_activate(GtkWidget *_unused, gpointer* __unused)
{
mappoint_t point;
- map_windowpoint_to_mappoint(&g_MainWindow.m_ptClickLocation, &point);
+ map_windowpoint_to_mappoint(g_MainWindow.m_pMap, &g_MainWindow.m_ptClickLocation, &point);
gint nLocationSetID = 1;
gint nNewLocationID;
@@ -804,7 +784,7 @@ static gboolean mainwindow_callback_on_gps_redraw_timeout(gpointer __unused)
// NOTE: we're setting tooltips on the image's
GtkWidget* pWidget = gtk_widget_get_parent(GTK_WIDGET(g_MainWindow.m_pStatusbarGPSIcon));
- gpsdata_t* pData = gpsclient_getdata();
+ const gpsdata_t* pData = gpsclient_getdata();
if(pData->m_eStatus == GPS_STATUS_LIVE) {
if(g_MainWindow.m_nCurrentGPSPath == 0) {
@@ -871,7 +851,10 @@ static gboolean mainwindow_callback_on_gps_redraw_timeout(gpointer __unused)
return TRUE;
}
-
+void mainwindow_set_centerpoint(mappoint_t* pPoint)
+{
+ map_set_centerpoint(g_MainWindow.m_pMap, pPoint);
+}
#ifdef ROADSTER_DEAD_CODE
diff --git a/src/mainwindow.h b/src/mainwindow.h
index f917a54..94dd183 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -25,6 +25,7 @@
#define _MAINWINDOW_H
#include <glade/glade.h>
+#include "map.h"
#ifdef __cplusplus
extern "C"
@@ -93,6 +94,8 @@ void mainwindow_on_gotomenuitem_activate(GtkMenuItem *menuitem, gpointer use
void mainwindow_on_addpointmenuitem_activate(GtkWidget *_unused, gpointer* __unused);
void mainwindow_on_datasetmenuitem_activate(GtkWidget *pWidget, gpointer* p);
+void mainwindow_set_centerpoint(mappoint_t* pPoint);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/map.c b/src/map.c
index f607c20..1ce1e2e 100644
--- a/src/map.c
+++ b/src/map.c
@@ -33,271 +33,54 @@
#include "gui.h"
#include "map.h"
-#include "geometryset.h"
#include "mainwindow.h"
#include "util.h"
#include "db.h"
+#include "road.h"
+#include "point.h"
#include "layers.h"
#include "locationset.h"
#include "scenemanager.h"
-struct {
- mappoint_t m_MapCenter; // XXX
- dimensions_t m_MapDimensions; // XXX
- guint16 m_uZoomLevel; // XXX
- gboolean m_bRedrawNeeded;
-} g_Map =
-{
- {0.0,0.0}, // starting position
- {0,0}, // map dimensions
- 7, // starting zoomlevel
- TRUE
-};
-
// ADD:
// 'Mal' - ?
// 'Trce - Trace
-struct {
- gchar* m_pszLong;
- gchar* m_pszShort;
-} g_RoadNameSuffix[] = {
- {"",""},
- {"Road", "Rd"},
- {"Street", "St"},
- {"Drive", "Dr"},
- {"Boulevard", "Bvd"},
- {"Avenue", "Ave"},
- {"Circle", "Crl"},
- {"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"},
-};
-
-struct {
- gchar* m_pszName;
- gint m_nID;
-} g_RoadNameSuffixLookup[] = {
- {"Rd", ROAD_SUFFIX_ROAD},
- {"Road", ROAD_SUFFIX_ROAD},
-
- {"St", ROAD_SUFFIX_STREET},
- {"Street", ROAD_SUFFIX_STREET},
-
- {"Dr", ROAD_SUFFIX_DRIVE},
- {"Drive", ROAD_SUFFIX_DRIVE},
-
- {"Blv", ROAD_SUFFIX_BOULEVARD},
- {"Blvd", ROAD_SUFFIX_BOULEVARD},
- {"Boulevard", ROAD_SUFFIX_BOULEVARD},
-
- {"Av", ROAD_SUFFIX_AVENUE},
- {"Ave", ROAD_SUFFIX_AVENUE},
- {"Avenue", ROAD_SUFFIX_AVENUE},
-
- {"Cir", ROAD_SUFFIX_CIRCLE},
- {"Crl", ROAD_SUFFIX_CIRCLE},
- {"Circle", ROAD_SUFFIX_CIRCLE},
-
- {"Sq", ROAD_SUFFIX_SQUARE},
- {"Square", ROAD_SUFFIX_SQUARE},
-
- {"Pl", ROAD_SUFFIX_PLACE},
- {"Place", ROAD_SUFFIX_PLACE},
-
- {"Xing", ROAD_SUFFIX_CROSSING},
- {"Crossing", ROAD_SUFFIX_CROSSING},
-
- {"Ct", ROAD_SUFFIX_COURT},
- {"Court", ROAD_SUFFIX_COURT},
-
- {"Tpke", ROAD_SUFFIX_TURNPIKE},
- {"Turnpike", ROAD_SUFFIX_TURNPIKE},
-
- {"Ter", ROAD_SUFFIX_TERRACE},
- {"Terrace", ROAD_SUFFIX_TERRACE},
-
- {"Row", ROAD_SUFFIX_ROW},
-
- {"Pth", ROAD_SUFFIX_PATH},
- {"Path", ROAD_SUFFIX_PATH},
-
- {"Wy", ROAD_SUFFIX_WAY},
- {"Way", ROAD_SUFFIX_WAY},
-
- {"Plz", ROAD_SUFFIX_PLAZA},
- {"Plaza", ROAD_SUFFIX_PLAZA},
-
- {"Trl", ROAD_SUFFIX_TRAIL},
- {"Trail", ROAD_SUFFIX_TRAIL},
-
- {"Ln", ROAD_SUFFIX_LANE},
- {"Lane", ROAD_SUFFIX_LANE},
-
- {"Pky", ROAD_SUFFIX_PARKWAY},
- {"Parkway", ROAD_SUFFIX_PARKWAY},
-
- {"Brg", ROAD_SUFFIX_BRIDGE},
- {"Bridge", ROAD_SUFFIX_BRIDGE},
-
- {"Hwy", ROAD_SUFFIX_HIGHWAY},
- {"Highway", ROAD_SUFFIX_HIGHWAY},
-
- {"Run", ROAD_SUFFIX_RUN},
-
- {"Pass", ROAD_SUFFIX_PASS},
-
- {"Freeway", ROAD_SUFFIX_FREEWAY},
- {"Fwy", ROAD_SUFFIX_FREEWAY},
-
- {"Alley", ROAD_SUFFIX_ALLEY},
- {"Aly", ROAD_SUFFIX_ALLEY},
-
- {"Crescent", ROAD_SUFFIX_CRESCENT},
- {"Cres", ROAD_SUFFIX_CRESCENT},
-
- {"Tunnel", ROAD_SUFFIX_TUNNEL},
- {"Tunl", ROAD_SUFFIX_TUNNEL},
-
- {"Walk", ROAD_SUFFIX_WALK},
- {"Walk", ROAD_SUFFIX_WALK},
-
- {"Branch", ROAD_SUFFIX_BRANCE},
- {"Br", ROAD_SUFFIX_BRANCE},
-
- {"Cove", ROAD_SUFFIX_COVE},
- {"Cv", ROAD_SUFFIX_COVE},
-
- {"Bypass", ROAD_SUFFIX_BYPASS},
- {"Byp", ROAD_SUFFIX_BYPASS},
-
- {"Loop", ROAD_SUFFIX_LOOP},
-
- {"Spur", ROAD_SUFFIX_SPUR},
-
- {"Ramp", ROAD_SUFFIX_RAMP},
-
- {"Pike", ROAD_SUFFIX_PIKE},
-
- {"Grade", ROAD_SUFFIX_GRADE},
- {"Grd", ROAD_SUFFIX_GRADE},
-
- {"Route", ROAD_SUFFIX_ROUTE},
- {"Rte", ROAD_SUFFIX_ROUTE},
-
- {"Arc", ROAD_SUFFIX_ARC},
-
-};
-
#define SCALE_X(p, x) ((((x) - (p)->m_rWorldBoundingBox.m_A.m_fLongitude) / (p)->m_fScreenLongitude) * (p)->m_nWindowWidth)
#define SCALE_Y(p, y) ((p)->m_nWindowHeight - ((((y) - (p)->m_rWorldBoundingBox.m_A.m_fLatitude) / (p)->m_fScreenLatitude) * (p)->m_nWindowHeight))
-typedef enum {
- kSublayerBottom,
- kSublayerTop,
-} ESubLayer;
-
-#define MIN_LINE_LENGTH_FOR_LABEL (40)
-#define LABEL_PIXELS_ABOVE_LINE (2)
-#define LABEL_PIXEL_RELIEF_INSIDE_LINE (2) // when drawing a label inside a line, only do so if we would have at least this much blank space above+below the text
-
-//void map_draw_layer_railroad(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, sublayerstyle_t* pSubLayerStyle);
-
-// For road names: Bitstream Vera Sans Mono ?
-
-#define INCHES_PER_METER (39.37007)
-
-#define MIN_ZOOMLEVEL (1)
-#define MAX_ZOOMLEVEL (10)
-#define NUM_ZOOMLEVELS (10)
-
-#define WORLD_CIRCUMFERENCE_IN_METERS (40076000)
-#define WORLD_METERS_PER_DEGREE (WORLD_CIRCUMFERENCE_IN_METERS / 360.0)
-#define WORLD_METERS_TO_DEGREES(x) ((x) / WORLD_METERS_PER_DEGREE)
-#define WORLD_DEGREES_TO_METERS(x) ((x) * WORLD_METERS_PER_DEGREE)
-#define KILOMETERS_PER_METER (1000)
-#define WORLD_KILOMETERS_TO_DEGREES(x) ((x * KILOMETERS_PER_METER) / WORLD_METERS_PER_DEGREE)
-
-#define WORLD_CIRCUMFERENCE_IN_FEET (131482939.8324)
-#define WORLD_FEET_PER_DEGREE (WORLD_CIRCUMFERENCE_IN_FEET / 360.0)
-#define WORLD_FEET_TO_DEGREES(X) ((X) / WORLD_FEET_PER_DEGREE)
-#define FEET_PER_MILE (5280)
-#define WORLD_MILES_TO_DEGREES(x) ((x * FEET_PER_MILE) / WORLD_FEET_PER_DEGREE)
-
-// Earth is slightly egg shaped so there are infinite radius measurements:
-
-// at poles: ?
-// average: 6,371,010
-// at equator: 6,378,136 meters
-
-#define RADIUS_OF_WORLD_IN_METERS (6371010)
-
-#define DEG2RAD(x) ((x) * (M_PI / 180.0))
-#define RAD2DEG(x) ((x) * (180.0 / M_PI))
-
-
/* Prototypes */
-static void map_draw_layer_polygons(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, geometryset_t* pGeometry, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle);
-static void map_draw_layer_lines(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, geometryset_t* pGeometry, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle);
-static void map_draw_layer_line_labels(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, geometryset_t* pGeometry, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle);
-static void map_draw_layer_polygon_labels(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, geometryset_t* pGeometry, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle);
-static void map_draw_polygon_label(cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rendermetrics_t* pRenderMetrics, pointstring_t* pPointString, const gchar* pszLabel);
-static void map_draw_layer_points(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pLocationsArray);
-static void map_draw_crosshair(cairo_t* pCairo, rendermetrics_t* pRenderMetrics);
+static void map_draw_layer_polygons(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pPointStringsArray, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle);
+static void map_draw_layer_lines(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pPointStringsArray, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle);
+static void map_draw_layer_line_labels(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pPointStringsArray, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle);
+static void map_draw_layer_polygon_labels(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pPointStringsArray, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle);
+static void map_draw_polygon_label(map_t* pMap, cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rendermetrics_t* pRenderMetrics, pointstring_t* pPointString, const gchar* pszLabel);
+static void map_draw_layer_points(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pLocationsArray);
+static void map_draw_crosshair(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics);
+static gboolean map_data_load(map_t* pMap, maprect_t* pRect);
+static void map_data_clear(map_t* pMap);
// Each zoomlevel has a scale and an optional name (name isn't used for anything)
zoomlevel_t g_sZoomLevels[NUM_ZOOMLEVELS+1] = {
- {1,"undefined"}, // no zoom level 0
-
- { 1600000, ""}, // 1
- { 800000, ""}, // 2
- { 400000, ""}, // 3
- { 200000, ""}, // 4
- { 100000, ""}, // 5
- { 50000, ""}, // 6
- { 25000, ""}, // 7
- { 10000, ""}, // 8
- { 4000, ""}, // 9
- { 1800, ""}, //10
+ {1,"undefined"}, // no zoom level 0
+
+ { 1600000, ""}, // 1
+ { 800000, ""}, // 2
+ { 400000, ""}, // 3
+ { 200000, ""}, // 4
+ { 100000, ""}, // 5
+ { 50000, ""}, // 6
+ { 25000, ""}, // 7
+ { 10000, ""}, // 8
+ { 4000, ""}, // 9
+ { 1800, ""}, // 10
};
struct {
gint nLayer;
gint nSubLayer;
- void (*pFunc)(cairo_t*, rendermetrics_t*, geometryset_t*, sublayerstyle_t*, textlabelstyle_t*);
+ void (*pFunc)(map_t*, cairo_t*, rendermetrics_t*, GPtrArray*, sublayerstyle_t*, textlabelstyle_t*);
} layerdraworder[] = {
{LAYER_MISC_AREA, 0, map_draw_layer_polygons},
@@ -337,28 +120,151 @@ struct {
};
// ========================================================
+// Init
+// ========================================================
+
+// init the module
+void map_init(void)
+{
+}
+
+
+gboolean map_new(map_t** ppMap, GtkWidget* pTargetWidget)
+{
+ g_assert(ppMap != NULL);
+ g_assert(*ppMap == NULL); // must be a pointer to null pointer
+
+ // create a new map struct
+ map_t* pMap = g_new0(map_t, 1);
+
+ pMap->m_pDataMutex = g_mutex_new();
+ pMap->m_pPixmapMutex = g_mutex_new();
+
+ pMap->m_pTargetWidget = pTargetWidget;
+
+ scenemanager_new(&(pMap->m_pSceneManager));
+ g_assert(pMap->m_pSceneManager);
+
+ pMap->m_uZoomLevel = 7;
+
+ // init containers for geometry data
+ gint i;
+ for(i=0 ; i<NUM_ELEMS(pMap->m_apLayerData) ; i++) {
+ maplayer_data_t* pLayer = g_new0(maplayer_data_t, 1);
+ pLayer->m_pPointStringsArray = g_ptr_array_new();
+ pMap->m_apLayerData[i] = pLayer;
+ }
+
+ // save it
+ *ppMap = pMap;
+ return TRUE;
+}
+
+// pointstring_t* pTrackPointString = track_get_pointstring(g_MainWindow.m_nCurrentGPSPath);
+// if(pTrackPointString) {
+// map_draw_gps_trail(pCairoInstance, pTrackPointString);
+// }
+
+gpointer map_draw_thread(gpointer);
+
+void map_draw_thread_begin(map_t* pMap, GtkWidget* pTargetWidget)
+{
+// g_thread_create(map_draw_thread, pMap, FALSE, NULL);
+ map_draw_thread(pMap);
+}
+
+gpointer map_draw_thread(gpointer pData)
+{
+//g_print("THREAD: begin\n");
+ map_t* pMap = (map_t*)pData;
+ g_assert(pMap != NULL);
+
+ db_lock();
+ g_mutex_lock(pMap->m_pDataMutex);
+
+ // create pixel buffer of appropriate size
+ GdkPixmap* pPixmapTemp = gdk_pixmap_new(pMap->m_pTargetWidget->window, pMap->m_MapDimensions.m_uWidth, pMap->m_MapDimensions.m_uHeight, -1);
+ g_assert(pPixmapTemp);
+
+ Display* dpy;
+ Drawable drawable;
+ dpy = gdk_x11_drawable_get_xdisplay(pPixmapTemp);
+ drawable = gdk_x11_drawable_get_xid(pPixmapTemp);
+
+ cairo_t* pCairo = cairo_create ();
+//g_print("THREAD: cairo created\n");
+
+ // draw on the off-screen buffer
+ cairo_set_target_drawable(pCairo, dpy, drawable);
+//g_print("THREAD: drawing...\n");
+ map_draw(pMap, pCairo);
+//g_print("THREAD: destroying cairo...\n");
+ cairo_destroy(pCairo);
+
+ // Copy final image to (pMap->m_pPixmap)
+//g_print("THREAD: copying pixmap\n");
+ g_mutex_lock(pMap->m_pPixmapMutex);
+
+ gdk_draw_pixmap(pMap->m_pPixmap,
+ pMap->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)],
+ pPixmapTemp,
+ 0, 0,
+ 0, 0,
+ pMap->m_MapDimensions.m_uWidth, pMap->m_MapDimensions.m_uWidth);
+
+ gdk_pixmap_unref(pPixmapTemp);
+
+ g_mutex_unlock(pMap->m_pDataMutex);
+ g_mutex_unlock(pMap->m_pPixmapMutex);
+ db_unlock();
+
+//g_print("THREAD: done drawing\n");
+
+ gtk_widget_queue_draw(pMap->m_pTargetWidget);
+}
+
+// ========================================================
+// Get and release the map image
+// ========================================================
+
+GdkPixmap* map_get_pixmap(map_t* pMap)
+{
+ g_mutex_lock(pMap->m_pPixmapMutex);
+ return pMap->m_pPixmap;
+}
+
+void map_release_pixmap(map_t* pMap)
+{
+ g_mutex_unlock(pMap->m_pPixmapMutex);
+}
+
+
+// ========================================================
// Get/Set Functions
// ========================================================
-void map_set_zoomlevel(guint16 uZoomLevel)
+void map_set_zoomlevel(map_t* pMap, guint16 uZoomLevel)
{
+ g_mutex_lock(pMap->m_pDataMutex);
+
if(uZoomLevel > MAX_ZOOMLEVEL) uZoomLevel = MAX_ZOOMLEVEL;
else if(uZoomLevel < MIN_ZOOMLEVEL) uZoomLevel = MIN_ZOOMLEVEL;
- if(uZoomLevel != g_Map.m_uZoomLevel) {
- g_Map.m_uZoomLevel = uZoomLevel;
- map_set_redraw_needed(TRUE);
+ if(uZoomLevel != pMap->m_uZoomLevel) {
+ pMap->m_uZoomLevel = uZoomLevel;
+// map_set_redraw_needed(TRUE);
}
+ g_mutex_unlock(pMap->m_pDataMutex);
}
-guint16 map_get_zoomlevel()
+guint16 map_get_zoomlevel(map_t* pMap)
{
- return g_Map.m_uZoomLevel; // between MIN_ZOOMLEVEL and MAX_ZOOMLEVEL
+ return pMap->m_uZoomLevel; // between MIN_ZOOMLEVEL and MAX_ZOOMLEVEL
}
-guint32 map_get_zoomlevel_scale()
+guint32 map_get_zoomlevel_scale(map_t* pMap)
{
- return g_sZoomLevels[g_Map.m_uZoomLevel].m_uScale; // returns "5000" for 1:5000 scale
+ return g_sZoomLevels[pMap->m_uZoomLevel].m_uScale; // returns "5000" for 1:5000 scale
}
// ========================================================
@@ -372,7 +278,7 @@ gchar* g_aDistanceUnitNames[] = {
"Kilometers",
};
-gdouble map_distance_in_units_to_degrees(gdouble fDistance, gint nDistanceUnit)
+gdouble map_distance_in_units_to_degrees(map_t* pMap, gdouble fDistance, gint nDistanceUnit)
{
switch(nDistanceUnit) {
case UNIT_FEET:
@@ -390,7 +296,7 @@ gdouble map_distance_in_units_to_degrees(gdouble fDistance, gint nDistanceUnit)
}
// convert pixels to a span of degrees
-static double map_pixels_to_degrees(gint16 nPixels, guint16 uZoomLevel)
+static double map_pixels_to_degrees(map_t* pMap, gint16 nPixels, guint16 uZoomLevel)
{
double fMonitorPixelsPerInch = 85 + 1/3;
double fPixelsPerMeter = fMonitorPixelsPerInch * INCHES_PER_METER;
@@ -403,7 +309,7 @@ static double map_pixels_to_degrees(gint16 nPixels, guint16 uZoomLevel)
return WORLD_METERS_TO_DEGREES(fMetersOfWorld);
}
-static double map_degrees_to_pixels(gdouble fDegrees, guint16 uZoomLevel)
+static double map_degrees_to_pixels(map_t* pMap, gdouble fDegrees, guint16 uZoomLevel)
{
double fMonitorPixelsPerInch = 85 + 1/3;
@@ -413,144 +319,113 @@ static double map_degrees_to_pixels(gdouble fDegrees, guint16 uZoomLevel)
return fResultInPixels;
}
-void map_windowpoint_to_mappoint(screenpoint_t* pScreenPoint, mappoint_t* pMapPoint)
+void map_windowpoint_to_mappoint(map_t* pMap, screenpoint_t* pScreenPoint, mappoint_t* pMapPoint)
{
// Calculate the # of pixels away from the center point the click was
- gint16 nPixelDeltaX = (gint)(pScreenPoint->m_nX) - (g_Map.m_MapDimensions.m_uWidth / 2);
- gint16 nPixelDeltaY = (gint)(pScreenPoint->m_nY) - (g_Map.m_MapDimensions.m_uHeight / 2);
+ gint16 nPixelDeltaX = (gint)(pScreenPoint->m_nX) - (pMap->m_MapDimensions.m_uWidth / 2);
+ gint16 nPixelDeltaY = (gint)(pScreenPoint->m_nY) - (pMap->m_MapDimensions.m_uHeight / 2);
// Convert pixels to world coordinates
- pMapPoint->m_fLongitude = g_Map.m_MapCenter.m_fLongitude + map_pixels_to_degrees(nPixelDeltaX, g_Map.m_uZoomLevel);
+ pMapPoint->m_fLongitude = pMap->m_MapCenter.m_fLongitude + map_pixels_to_degrees(pMap, nPixelDeltaX, pMap->m_uZoomLevel);
// reverse the X, clicking above
- pMapPoint->m_fLatitude = g_Map.m_MapCenter.m_fLatitude - map_pixels_to_degrees(nPixelDeltaY, g_Map.m_uZoomLevel);
+ pMapPoint->m_fLatitude = pMap->m_MapCenter.m_fLatitude - map_pixels_to_degrees(pMap, nPixelDeltaY, pMap->m_uZoomLevel);
}
// Call this to pan around the map
-void map_center_on_windowpoint(guint16 uX, guint16 uY)
+void map_center_on_windowpoint(map_t* pMap, guint16 uX, guint16 uY)
{
// Calculate the # of pixels away from the center point the click was
- gint16 nPixelDeltaX = uX - (g_Map.m_MapDimensions.m_uWidth / 2);
- gint16 nPixelDeltaY = uY - (g_Map.m_MapDimensions.m_uHeight / 2);
+ gint16 nPixelDeltaX = uX - (pMap->m_MapDimensions.m_uWidth / 2);
+ gint16 nPixelDeltaY = uY - (pMap->m_MapDimensions.m_uHeight / 2);
// Convert pixels to world coordinates
- double fWorldDeltaX = map_pixels_to_degrees(nPixelDeltaX, g_Map.m_uZoomLevel);
+ double fWorldDeltaX = map_pixels_to_degrees(pMap, nPixelDeltaX, pMap->m_uZoomLevel);
// reverse the X, clicking above
- double fWorldDeltaY = -map_pixels_to_degrees(nPixelDeltaY, g_Map.m_uZoomLevel);
+ double fWorldDeltaY = -map_pixels_to_degrees(pMap, nPixelDeltaY, pMap->m_uZoomLevel);
// g_message("panning %d,%d pixels (%.10f,%.10f world coords)\n", nPixelDeltaX, nPixelDeltaY, fWorldDeltaX, fWorldDeltaY);
mappoint_t pt;
- pt.m_fLatitude = g_Map.m_MapCenter.m_fLatitude + fWorldDeltaY;
- pt.m_fLongitude = g_Map.m_MapCenter.m_fLongitude + fWorldDeltaX;
- map_set_centerpoint(&pt);
+ pt.m_fLatitude = pMap->m_MapCenter.m_fLatitude + fWorldDeltaY;
+ pt.m_fLongitude = pMap->m_MapCenter.m_fLongitude + fWorldDeltaX;
+ map_set_centerpoint(pMap, &pt);
}
-void map_set_centerpoint(const mappoint_t* pPoint)
+void map_set_centerpoint(map_t* pMap, const mappoint_t* pPoint)
{
g_assert(pPoint != NULL);
- g_Map.m_MapCenter.m_fLatitude = pPoint->m_fLatitude;
- g_Map.m_MapCenter.m_fLongitude = pPoint->m_fLongitude;
+ pMap->m_MapCenter.m_fLatitude = pPoint->m_fLatitude;
+ pMap->m_MapCenter.m_fLongitude = pPoint->m_fLongitude;
- map_set_redraw_needed(TRUE);
+// map_set_redraw_needed(TRUE);
}
-void map_get_centerpoint(mappoint_t* pReturnPoint)
+void map_get_centerpoint(map_t* pMap, mappoint_t* pReturnPoint)
{
g_assert(pReturnPoint != NULL);
- pReturnPoint->m_fLatitude = g_Map.m_MapCenter.m_fLatitude;
- pReturnPoint->m_fLongitude = g_Map.m_MapCenter.m_fLongitude;
+ pReturnPoint->m_fLatitude = pMap->m_MapCenter.m_fLatitude;
+ pReturnPoint->m_fLongitude = pMap->m_MapCenter.m_fLongitude;
}
//
-void map_set_dimensions(const dimensions_t* pDimensions)
+void map_set_dimensions(map_t* pMap, const dimensions_t* pDimensions)
{
g_assert(pDimensions != NULL);
- g_Map.m_MapDimensions.m_uWidth = pDimensions->m_uWidth;
- g_Map.m_MapDimensions.m_uHeight = pDimensions->m_uHeight;
-}
+ g_mutex_lock(pMap->m_pDataMutex);
+ g_mutex_lock(pMap->m_pPixmapMutex);
-#if ROADSTER_DEAD_CODE
-static double map_get_distance_in_meters(mappoint_t* pA, mappoint_t* pB)
-{
- g_assert_not_reached(); // unused/tested
+ pMap->m_MapDimensions.m_uWidth = pDimensions->m_uWidth;
+ pMap->m_MapDimensions.m_uHeight = pDimensions->m_uHeight;
- // This functions calculates the length of the arc of the "greatcircle" that goes through
- // the two points A and B and whos center is the center of the sphere, O.
-
- // When we multiply this angle (in radians) by the radius, we get the length of the arc.
-
- // NOTE: This algorithm wrongly assumes that Earth is a perfect sphere.
- // It is actually slightly egg shaped. But it's good enough.
-
- // All trig functions expect arguments in radians.
- double fLonA_Rad = DEG2RAD(pA->m_fLongitude);
- double fLonB_Rad = DEG2RAD(pB->m_fLongitude);
- double fLatA_Rad = DEG2RAD(pA->m_fLatitude);
- double fLatB_Rad = DEG2RAD(pB->m_fLatitude);
-
- // Step 1. Calculate AOB (in radians).
- // An explanation of this equation is at http://mathforum.org/library/drmath/view/51722.html
- double fAOB_Rad = acos((cos(fLatA_Rad) * cos(fLatB_Rad) * cos(fLonB_Rad - fLonA_Rad)) + (sin(fLatA_Rad) * sin(fLatB_Rad)));
-
- // Step 2. Multiply the angle by the radius of the sphere to get arc length.
- return fAOB_Rad * RADIUS_OF_WORLD_IN_METERS;
-}
-#endif /* ROADSTER_DEAD_CODE */
-
-// ========================================================
-// Redraw
-// ========================================================
-
-void map_set_redraw_needed(gboolean bNeeded)
-{
- g_Map.m_bRedrawNeeded = bNeeded;
-}
-
-gboolean map_get_redraw_needed()
-{
- return g_Map.m_bRedrawNeeded;
+ pMap->m_pPixmap = gdk_pixmap_new(
+ pMap->m_pTargetWidget->window,
+ pMap->m_MapDimensions.m_uWidth, pMap->m_MapDimensions.m_uHeight,
+ -1);
+
+ g_mutex_unlock(pMap->m_pPixmapMutex);
+ g_mutex_unlock(pMap->m_pDataMutex);
}
// ========================================================
// Draw Functions
// ========================================================
-void map_get_render_metrics(rendermetrics_t* pMetrics)
+void map_get_render_metrics(map_t* pMap, rendermetrics_t* pMetrics)
{
g_assert(pMetrics != NULL);
//
// Set up renderMetrics array
//
- pMetrics->m_nZoomLevel = map_get_zoomlevel();
- pMetrics->m_nWindowWidth = g_Map.m_MapDimensions.m_uWidth;
- pMetrics->m_nWindowHeight = g_Map.m_MapDimensions.m_uHeight;
+ pMetrics->m_nZoomLevel = map_get_zoomlevel(pMap);
+ pMetrics->m_nWindowWidth = pMap->m_MapDimensions.m_uWidth;
+ pMetrics->m_nWindowHeight = pMap->m_MapDimensions.m_uHeight;
// Calculate how many world degrees we'll be drawing
- pMetrics->m_fScreenLatitude = map_pixels_to_degrees(g_Map.m_MapDimensions.m_uHeight, pMetrics->m_nZoomLevel);
- pMetrics->m_fScreenLongitude = map_pixels_to_degrees(g_Map.m_MapDimensions.m_uWidth, pMetrics->m_nZoomLevel);
+ pMetrics->m_fScreenLatitude = map_pixels_to_degrees(pMap, pMap->m_MapDimensions.m_uHeight, pMetrics->m_nZoomLevel);
+ pMetrics->m_fScreenLongitude = map_pixels_to_degrees(pMap, pMap->m_MapDimensions.m_uWidth, pMetrics->m_nZoomLevel);
// The world bounding box (expressed in lat/lon) of the data we will be drawing
- pMetrics->m_rWorldBoundingBox.m_A.m_fLongitude = g_Map.m_MapCenter.m_fLongitude - pMetrics->m_fScreenLongitude/2;
- pMetrics->m_rWorldBoundingBox.m_A.m_fLatitude = g_Map.m_MapCenter.m_fLatitude - pMetrics->m_fScreenLatitude/2;
- pMetrics->m_rWorldBoundingBox.m_B.m_fLongitude = g_Map.m_MapCenter.m_fLongitude + pMetrics->m_fScreenLongitude/2;
- pMetrics->m_rWorldBoundingBox.m_B.m_fLatitude = g_Map.m_MapCenter.m_fLatitude + pMetrics->m_fScreenLatitude/2;
+ pMetrics->m_rWorldBoundingBox.m_A.m_fLongitude = pMap->m_MapCenter.m_fLongitude - pMetrics->m_fScreenLongitude/2;
+ pMetrics->m_rWorldBoundingBox.m_A.m_fLatitude = pMap->m_MapCenter.m_fLatitude - pMetrics->m_fScreenLatitude/2;
+ pMetrics->m_rWorldBoundingBox.m_B.m_fLongitude = pMap->m_MapCenter.m_fLongitude + pMetrics->m_fScreenLongitude/2;
+ pMetrics->m_rWorldBoundingBox.m_B.m_fLatitude = pMap->m_MapCenter.m_fLatitude + pMetrics->m_fScreenLatitude/2;
}
-static void map_draw_background(cairo_t *pCairo)
+static void map_draw_background(map_t* pMap, cairo_t *pCairo)
{
cairo_save(pCairo);
cairo_set_rgb_color(pCairo, 247/255.0, 235/255.0, 230/255.0);
- cairo_rectangle(pCairo, 0, 0, g_Map.m_MapDimensions.m_uWidth, g_Map.m_MapDimensions.m_uHeight);
+ cairo_rectangle(pCairo, 0, 0, pMap->m_MapDimensions.m_uWidth, pMap->m_MapDimensions.m_uHeight);
cairo_fill(pCairo);
cairo_restore(pCairo);
}
// EXPERIMENTAL TEXT RENDERING
-static void map_draw_line_label(cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rendermetrics_t* pRenderMetrics, pointstring_t* pPointString, gdouble fLineWidth, const gchar* pszLabel)
+static void map_draw_line_label(map_t* pMap, cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rendermetrics_t* pRenderMetrics, pointstring_t* pPointString, gdouble fLineWidth, const gchar* pszLabel)
{
if(pPointString->m_pPointsArray->len < 2) return;
@@ -560,7 +435,7 @@ static void map_draw_line_label(cairo_t *pCairo, textlabelstyle_t* pLabelStyle,
gfloat fFontSize = pLabelStyle->m_afFontSizeAtZoomLevel[pRenderMetrics->m_nZoomLevel-1];
if(fFontSize == 0) return;
- if(!scenemanager_can_draw_label(pszLabel)) {
+ if(!scenemanager_can_draw_label(pMap->m_pSceneManager, pszLabel)) {
//g_print("dup label: %s\n", pszLabel);
return;
}
@@ -795,10 +670,10 @@ static void map_draw_line_label(cairo_t *pCairo, textlabelstyle_t* pLabelStyle,
}
cairo_restore(pCairo);
- scenemanager_label_drawn(pszLabel);
+ scenemanager_label_drawn(pMap->m_pSceneManager, pszLabel);
}
-void map_draw_polygon_label(cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rendermetrics_t* pRenderMetrics, pointstring_t* pPointString, const gchar* pszLabel)
+void map_draw_polygon_label(map_t* pMap, cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rendermetrics_t* pRenderMetrics, pointstring_t* pPointString, const gchar* pszLabel)
{
if(pPointString->m_pPointsArray->len < 3) return;
@@ -808,7 +683,7 @@ void map_draw_polygon_label(cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rend
gdouble fAlpha = pLabelStyle->m_clrColor.m_fAlpha;
if(fAlpha == 0.0) return;
- if(!scenemanager_can_draw_label(pszLabel)) {
+ if(!scenemanager_can_draw_label(pMap->m_pSceneManager, pszLabel)) {
//g_print("dup label: %s\n", pszLabel);
return;
}
@@ -816,7 +691,6 @@ void map_draw_polygon_label(cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rend
gdouble fTotalX = 0.0;
gdouble fTotalY = 0.0;
-
gdouble fMaxX = -G_MAXDOUBLE; // init to the worst possible value so first point will override
gdouble fMaxY = -G_MAXDOUBLE;
gdouble fMinX = G_MAXDOUBLE;
@@ -858,7 +732,7 @@ void map_draw_polygon_label(cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rend
CAIRO_FONT_SLANT_NORMAL,
pLabelStyle->m_abBoldAtZoomLevel[pRenderMetrics->m_nZoomLevel-1] ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL);
cairo_scale_font(pCairo, fFontSize);
-
+
// Get total width of string
cairo_text_extents_t extents;
cairo_text_extents(pCairo, pszLabel, &extents);
@@ -891,23 +765,23 @@ void map_draw_polygon_label(cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rend
}
cairo_fill(pCairo);
cairo_restore(pCairo);
-
- scenemanager_label_drawn(pszLabel);
+
+ scenemanager_label_drawn(pMap->m_pSceneManager, pszLabel);
}
-void map_draw(cairo_t *pCairo)
+void map_draw(map_t* pMap, cairo_t *pCairo)
{
rendermetrics_t renderMetrics = {0};
- map_get_render_metrics(&renderMetrics);
+ map_get_render_metrics(pMap, &renderMetrics);
rendermetrics_t* pRenderMetrics = &renderMetrics;
- scenemanager_clear();
+ scenemanager_clear(pMap->m_pSceneManager);
//
// Load geometry
//
TIMER_BEGIN(loadtimer, "--- BEGIN ALL DB LOAD");
- geometryset_load_geometry(&(pRenderMetrics->m_rWorldBoundingBox));
+ map_data_load(pMap, &(pRenderMetrics->m_rWorldBoundingBox));
locationset_load_locations(&(pRenderMetrics->m_rWorldBoundingBox));
TIMER_END(loadtimer, "--- END ALL DB LOAD");
@@ -918,22 +792,24 @@ void map_draw(cairo_t *pCairo)
//
TIMER_BEGIN(maptimer, "BEGIN RENDER MAP");
cairo_save(pCairo);
- map_draw_background(pCairo);
+ map_draw_background(pMap, pCairo);
cairo_set_fill_rule(pCairo, CAIRO_FILL_RULE_WINDING);
cairo_scale_font(pCairo, 18.00);
// Render Layers
- gint iLayerDraw;
- for(iLayerDraw=0 ; iLayerDraw<NUM_ELEMS(layerdraworder) ; iLayerDraw++) {
+ gint i;
+ for(i=0 ; i<NUM_ELEMS(layerdraworder) ; i++) {
//g_print("drawing %d\n", layerdraworder[iLayerDraw].nLayer);
- layerdraworder[iLayerDraw].pFunc(
- pCairo,
- pRenderMetrics,
- /* geometry */ g_aLayers[layerdraworder[iLayerDraw].nLayer].m_pGeometrySet,
- /* style */ &g_aLayers[layerdraworder[iLayerDraw].nLayer].m_Style.m_aSubLayers[layerdraworder[iLayerDraw].nSubLayer],
- &g_aLayers[layerdraworder[iLayerDraw].nLayer].m_TextLabelStyle
- );
+ gint nLayer = layerdraworder[i].nLayer;
+ gint nSubLayer = layerdraworder[i].nSubLayer;
+
+ layerdraworder[i].pFunc(pMap, pCairo,
+ pRenderMetrics,
+ /* geometry */ pMap->m_apLayerData[nLayer]->m_pPointStringsArray,
+ /* style */ &g_aLayers[nLayer].m_Style.m_aSubLayers[nSubLayer],
+ &g_aLayers[nLayer].m_TextLabelStyle
+ );
}
TIMER_END(maptimer, "END RENDER MAP");
@@ -942,23 +818,23 @@ void map_draw(cairo_t *pCairo)
gint iLocationSet;
for(iLocationSet=0 ; iLocationSet<pLocationSets->len ; iLocationSet++) {
locationset_t* pLocationSet = g_ptr_array_index(pLocationSets, iLocationSet);
- map_draw_layer_points(pCairo, pRenderMetrics, pLocationSet->m_pLocationsArray);
+ map_draw_layer_points(pMap, pCairo, pRenderMetrics, pLocationSet->m_pLocationsArray);
}
TIMER_END(loctimer, "END RENDER LOCATIONS");
- map_draw_crosshair(pCairo, pRenderMetrics);
+ map_draw_crosshair(pMap, pCairo, pRenderMetrics);
cairo_restore(pCairo);
// We don't need another redraw until something changes
- map_set_redraw_needed(FALSE);
+// map_set_redraw_needed(FALSE);
}
#define CROSSHAIR_LINE_RELIEF (6)
#define CROSSHAIR_LINE_LENGTH (12)
#define CROSSHAIR_CIRCLE_RADIUS (12)
-static void map_draw_crosshair(cairo_t* pCairo, rendermetrics_t* pRenderMetrics)
+static void map_draw_crosshair(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics)
{
cairo_save(pCairo);
cairo_set_line_width(pCairo, 1.0);
@@ -984,9 +860,9 @@ static void map_draw_crosshair(cairo_t* pCairo, rendermetrics_t* pRenderMetrics)
cairo_restore(pCairo);
}
-void map_draw_layer_points(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pLocationsArray)
+void map_draw_layer_points(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pLocationsArray)
{
- gfloat fRadius = map_degrees_to_pixels(0.0007, map_get_zoomlevel());
+ gfloat fRadius = map_degrees_to_pixels(pMap, 0.0007, map_get_zoomlevel(pMap));
gboolean bAddition = FALSE;
cairo_save(pCairo);
@@ -1026,7 +902,7 @@ void map_draw_layer_points(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPt
cairo_restore(pCairo);
}
-void map_draw_layer_polygons(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, geometryset_t* pGeometry, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle)
+void map_draw_layer_polygons(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pPointStringsArray, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle)
{
mappoint_t* pPoint;
pointstring_t* pPointString;
@@ -1046,8 +922,8 @@ void map_draw_layer_polygons(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, g
// cairo_set_dash(pCairo, g_aDashStyles[pSubLayerStyle->m_nDashStyle].m_pfList, g_aDashStyles[pSubLayerStyle->m_nDashStyle].m_nCount, 0.0);
gint iString;
- for(iString=0 ; iString<pGeometry->m_pPointStringsArray->len ; iString++) {
- pPointString = g_ptr_array_index(pGeometry->m_pPointStringsArray, iString);
+ for(iString=0 ; iString<pPointStringsArray->len ; iString++) {
+ pPointString = g_ptr_array_index(pPointStringsArray, iString);
if(pPointString->m_pPointsArray->len >= 3) {
pPoint = g_ptr_array_index(pPointString->m_pPointsArray, 0);
@@ -1097,7 +973,7 @@ void map_draw_layer_polygons(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, g
cairo_fill(pCairo);
}
-void map_draw_layer_lines(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, geometryset_t* pGeometry, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle)
+void map_draw_layer_lines(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pPointStringsArray, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle)
{
mappoint_t* pPoint;
pointstring_t* pPointString;
@@ -1115,7 +991,7 @@ void map_draw_layer_lines(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, geom
gdouble fTolerance;
if(fLineWidth >= 6.0) {
- fTolerance = 0.5;
+ fTolerance = 0.6;
}
else {
if(nCapStyle == CAIRO_LINE_CAP_ROUND) {
@@ -1142,8 +1018,8 @@ void map_draw_layer_lines(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, geom
cairo_set_alpha(pCairo, pSubLayerStyle->m_clrColor.m_fAlpha);
cairo_set_line_width(pCairo, fLineWidth);
- for(iString=0 ; iString<pGeometry->m_pPointStringsArray->len ; iString++) {
- pPointString = g_ptr_array_index(pGeometry->m_pPointStringsArray, iString);
+ for(iString=0 ; iString<pPointStringsArray->len ; iString++) {
+ pPointString = g_ptr_array_index(pPointStringsArray, iString);
if(pPointString->m_pPointsArray->len >= 2) {
pPoint = g_ptr_array_index(pPointString->m_pPointsArray, 0);
@@ -1171,35 +1047,35 @@ void map_draw_layer_lines(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, geom
cairo_restore(pCairo);
}
-void map_draw_layer_line_labels(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, geometryset_t* pGeometry, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle)
+void map_draw_layer_line_labels(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pPointStringsArray, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle)
{
gint i;
gdouble fLineWidth = pSubLayerStyle->m_afLineWidths[pRenderMetrics->m_nZoomLevel-1];
- for(i=0 ; i<pGeometry->m_pPointStringsArray->len ; i++) {
- pointstring_t* pPointString = g_ptr_array_index(pGeometry->m_pPointStringsArray, i);
+ for(i=0 ; i<pPointStringsArray->len ; i++) {
+ pointstring_t* pPointString = g_ptr_array_index(pPointStringsArray, i);
if(pPointString->m_pszName[0] != '\0') {
- map_draw_line_label(pCairo, pLabelStyle, pRenderMetrics, pPointString, fLineWidth, pPointString->m_pszName);
+ map_draw_line_label(pMap, pCairo, pLabelStyle, pRenderMetrics, pPointString, fLineWidth, pPointString->m_pszName);
}
}
}
-void map_draw_layer_polygon_labels(cairo_t* pCairo, rendermetrics_t* pRenderMetrics, geometryset_t* pGeometry, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle)
+void map_draw_layer_polygon_labels(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pPointStringsArray, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle)
{
gint i;
- for(i=0 ; i<pGeometry->m_pPointStringsArray->len ; i++) {
- pointstring_t* pPointString = g_ptr_array_index(pGeometry->m_pPointStringsArray, i);
+ for(i=0 ; i<pPointStringsArray->len ; i++) {
+ pointstring_t* pPointString = g_ptr_array_index(pPointStringsArray, i);
if(pPointString->m_pszName[0] != '\0') {
- map_draw_polygon_label(pCairo, pLabelStyle, pRenderMetrics, pPointString, pPointString->m_pszName);
+ map_draw_polygon_label(pMap, pCairo, pLabelStyle, pRenderMetrics, pPointString, pPointString->m_pszName);
}
}
}
-void map_draw_gps_trail(cairo_t* pCairo, pointstring_t* pPointString)
+void map_draw_gps_trail(map_t* pMap, cairo_t* pCairo, pointstring_t* pPointString)
{
rendermetrics_t renderMetrics = {0};
- map_get_render_metrics(&renderMetrics);
+ map_get_render_metrics(pMap, &renderMetrics);
rendermetrics_t* pRenderMetrics = &renderMetrics;
if(pPointString->m_pPointsArray->len > 2) {
@@ -1225,32 +1101,177 @@ void map_draw_gps_trail(cairo_t* pCairo, pointstring_t* pPointString)
}
}
-// ========================================================
-// Road Direction / Suffix conversions
-// ========================================================
-
-const gchar* map_road_suffix_itoa(gint nSuffixID, ESuffixLength eSuffixLength)
+static gboolean map_data_load(map_t* pMap, maprect_t* pRect)
{
- if(nSuffixID >= ROAD_SUFFIX_FIRST && nSuffixID <= ROAD_SUFFIX_LAST) {
- if(eSuffixLength == SUFFIX_LENGTH_SHORT) {
- return g_RoadNameSuffix[nSuffixID].m_pszShort;
- }
- else {
- return g_RoadNameSuffix[nSuffixID].m_pszLong;
+ g_return_val_if_fail(pRect != NULL, FALSE);
+
+ db_resultset_t* pResultSet = NULL;
+ db_row_t aRow;
+
+ gint nZoomLevel = map_get_zoomlevel(pMap);
+
+ map_data_clear(pMap);
+
+ TIMER_BEGIN(mytimer, "BEGIN Geometry LOAD");
+
+ // HACKY: make a list of layer IDs "2,3,5,6"
+ gchar azLayerNumberList[200] = {0};
+ gint nActiveLayerCount = 0;
+ gint i;
+ for(i=LAYER_FIRST ; i <= LAYER_LAST ;i++) {
+ if(g_aLayers[i].m_Style.m_aSubLayers[0].m_afLineWidths[nZoomLevel-1] != 0.0 ||
+ g_aLayers[i].m_Style.m_aSubLayers[1].m_afLineWidths[nZoomLevel-1] != 0.0)
+ {
+ gchar azLayerNumber[10];
+
+ if(nActiveLayerCount > 0) g_snprintf(azLayerNumber, 10, ",%d", i);
+ else g_snprintf(azLayerNumber, 10, "%d", i);
+
+ g_strlcat(azLayerNumberList, azLayerNumber, 200);
+ nActiveLayerCount++;
}
}
- if(nSuffixID != ROAD_SUFFIX_NONE) return "???";
- return "";
+ if(nActiveLayerCount == 0) {
+ g_print("no visible layers!\n");
+ return TRUE;
+ }
+
+ // generate SQL
+ gchar* pszSQL = g_strdup_printf(
+ "SELECT Road.ID, Road.TypeID, AsText(Road.Coordinates), RoadName.Name, RoadName.SuffixID"
+ " FROM Road "
+ " LEFT JOIN Road_RoadName ON (Road.ID=Road_RoadName.RoadID)"
+ " LEFT JOIN RoadName ON (Road_RoadName.RoadNameID=RoadName.ID)"
+ " WHERE"
+ " TypeID IN (%s) AND"
+ " MBRIntersects(GeomFromText('Polygon((%f %f,%f %f,%f %f,%f %f,%f %f))'), Coordinates)",
+ azLayerNumberList,
+ pRect->m_A.m_fLatitude, pRect->m_A.m_fLongitude, // upper left
+ pRect->m_A.m_fLatitude, pRect->m_B.m_fLongitude, // upper right
+ pRect->m_B.m_fLatitude, pRect->m_B.m_fLongitude, // bottom right
+ pRect->m_B.m_fLatitude, pRect->m_A.m_fLongitude, // bottom left
+ pRect->m_A.m_fLatitude, pRect->m_A.m_fLongitude // upper left again
+ );
+ //g_print("sql: %s\n", pszSQL);
+
+ db_query(pszSQL, &pResultSet);
+ g_free(pszSQL);
+
+ TIMER_SHOW(mytimer, "after query");
+
+ guint32 uRowCount = 0;
+ if(pResultSet) {
+ TIMER_SHOW(mytimer, "after clear layers");
+ while((aRow = db_fetch_row(pResultSet))) {
+ uRowCount++;
+
+ // aRow[0] is ID
+ // aRow[1] is TypeID
+ // aRow[2] is Coordinates in mysql's text format
+ // aRow[3] is road name
+ // aRow[4] is road name suffix id
+// g_print("data: %s, %s, %s, %s, %s\n", aRow[0], aRow[1], aRow[2], aRow[3], aRow[4]);
+
+ // Get layer type that this belongs on
+ gint nTypeID = atoi(aRow[1]);
+ if(nTypeID < LAYER_FIRST || nTypeID > LAYER_LAST) {
+ g_warning("geometry record '%s' has bad type '%s'\n", aRow[0], aRow[1]);
+ continue;
+ }
+
+ // Extract points
+ pointstring_t* pNewPointString = NULL;
+ if(!pointstring_alloc(&pNewPointString)) {
+ g_warning("out of memory loading pointstrings\n");
+ continue;
+ }
+ db_parse_pointstring(aRow[2], pNewPointString, point_alloc);
+
+ // Build name by adding suffix, if one is present
+ gchar azFullName[100] = "";
+
+ // does it have a name?
+ if(aRow[3] != NULL && aRow[4] != NULL) {
+ gint nSuffixID = atoi(aRow[4]);
+ const gchar* pszSuffix = road_suffix_itoa(nSuffixID, ROAD_SUFFIX_LENGTH_SHORT);
+ g_snprintf(azFullName, 100, "%s%s%s",
+ aRow[3], (pszSuffix[0] != '\0') ? " " : "", pszSuffix);
+ }
+ pNewPointString->m_pszName = g_strdup(azFullName);
+
+ // Add this item to layer's list of pointstrings
+ g_ptr_array_add(
+ pMap->m_apLayerData[nTypeID]->m_pPointStringsArray, pNewPointString);
+ } // end while loop on rows
+ g_print("[%d rows]\n", uRowCount);
+ TIMER_SHOW(mytimer, "after rows retrieved");
+
+ db_free_result(pResultSet);
+ TIMER_SHOW(mytimer, "after free results");
+ TIMER_END(mytimer, "END Geometry LOAD");
+
+ return TRUE;
+ }
+ else {
+ g_print(" no rows\n");
+ return FALSE;
+ }
}
-gboolean map_road_suffix_atoi(const gchar* pszSuffix, gint* pReturnSuffixID)
+static void map_data_clear(map_t* pMap)
{
- gint i;
- for(i=0 ; i<NUM_ELEMS(g_RoadNameSuffixLookup) ; i++) {
- if(g_ascii_strcasecmp(pszSuffix, g_RoadNameSuffixLookup[i].m_pszName) == 0) {
- *pReturnSuffixID = g_RoadNameSuffixLookup[i].m_nID;
- return TRUE;
+ gint i,j;
+ for(i=0 ; i<NUM_ELEMS(pMap->m_apLayerData) ; i++) {
+ maplayer_data_t* pLayerData = pMap->m_apLayerData[i];
+
+ // Free each pointstring
+ for(j = (pLayerData->m_pPointStringsArray->len - 1) ; j>=0 ; j--) {
+ pointstring_t* pPointString = g_ptr_array_remove_index_fast(pLayerData->m_pPointStringsArray, j);
+ pointstring_free(pPointString);
}
}
- return FALSE;
}
+
+
+#if ROADSTER_DEAD_CODE
+static double map_get_distance_in_meters(mappoint_t* pA, mappoint_t* pB)
+{
+ g_assert_not_reached(); // unused/tested
+
+ // This functions calculates the length of the arc of the "greatcircle" that goes through
+ // the two points A and B and whos center is the center of the sphere, O.
+
+ // When we multiply this angle (in radians) by the radius, we get the length of the arc.
+
+ // NOTE: This algorithm wrongly assumes that Earth is a perfect sphere.
+ // It is actually slightly egg shaped. But it's good enough.
+
+ // All trig functions expect arguments in radians.
+ double fLonA_Rad = DEG2RAD(pA->m_fLongitude);
+ double fLonB_Rad = DEG2RAD(pB->m_fLongitude);
+ double fLatA_Rad = DEG2RAD(pA->m_fLatitude);
+ double fLatB_Rad = DEG2RAD(pB->m_fLatitude);
+
+ // Step 1. Calculate AOB (in radians).
+ // An explanation of this equation is at http://mathforum.org/library/drmath/view/51722.html
+ double fAOB_Rad = acos((cos(fLatA_Rad) * cos(fLatB_Rad) * cos(fLonB_Rad - fLonA_Rad)) + (sin(fLatA_Rad) * sin(fLatB_Rad)));
+
+ // Step 2. Multiply the angle by the radius of the sphere to get arc length.
+ return fAOB_Rad * RADIUS_OF_WORLD_IN_METERS;
+}
+
+// ========================================================
+// Redraw
+// ========================================================
+
+void map_set_redraw_needed(gboolean bNeeded)
+{
+ pMap->m_bRedrawNeeded = bNeeded;
+}
+
+gboolean map_get_redraw_needed()
+{
+ return pMap->m_bRedrawNeeded;
+}
+#endif /* ROADSTER_DEAD_CODE */
+
diff --git a/src/map.h b/src/map.h
index 3c8b78f..312a780 100644
--- a/src/map.h
+++ b/src/map.h
@@ -26,11 +26,55 @@
#include <cairo.h>
+typedef enum {
+ kSublayerBottom,
+ kSublayerTop,
+} ESubLayer;
+
+#define MIN_LINE_LENGTH_FOR_LABEL (40)
+#define LABEL_PIXELS_ABOVE_LINE (2)
+#define LABEL_PIXEL_RELIEF_INSIDE_LINE (2) // when drawing a label inside a line, only do so if we would have at least this much blank space above+below the text
+
+// For road names: Bitstream Vera Sans Mono ?
+
+#define INCHES_PER_METER (39.37007)
+
+#define MIN_ZOOMLEVEL (1)
+#define MAX_ZOOMLEVEL (10)
+#define NUM_ZOOMLEVELS (10)
+
+#define WORLD_CIRCUMFERENCE_IN_METERS (40076000)
+#define WORLD_METERS_PER_DEGREE (WORLD_CIRCUMFERENCE_IN_METERS / 360.0)
+#define WORLD_METERS_TO_DEGREES(x) ((x) / WORLD_METERS_PER_DEGREE)
+#define WORLD_DEGREES_TO_METERS(x) ((x) * WORLD_METERS_PER_DEGREE)
+#define KILOMETERS_PER_METER (1000)
+#define WORLD_KILOMETERS_TO_DEGREES(x) ((x * KILOMETERS_PER_METER) / WORLD_METERS_PER_DEGREE)
+
+#define WORLD_CIRCUMFERENCE_IN_FEET (131482939.8324)
+#define WORLD_FEET_PER_DEGREE (WORLD_CIRCUMFERENCE_IN_FEET / 360.0)
+#define WORLD_FEET_TO_DEGREES(X) ((X) / WORLD_FEET_PER_DEGREE)
+#define FEET_PER_MILE (5280)
+#define WORLD_MILES_TO_DEGREES(x) ((x * FEET_PER_MILE) / WORLD_FEET_PER_DEGREE)
+
+// Earth is slightly egg shaped so there are infinite radius measurements:
+
+// at poles: ?
+// average: 6,371,010
+// at equator: 6,378,136 meters
+
+#define RADIUS_OF_WORLD_IN_METERS (6371010)
+
+#define DEG2RAD(x) ((x) * (M_PI / 180.0))
+#define RAD2DEG(x) ((x) * (180.0 / M_PI))
+
struct GtkWidget;
#define MIN_ZOOM_LEVEL 1
#define MAX_ZOOM_LEVEL 10
+#include "layers.h"
+#include "scenemanager.h"
+
// World space
typedef struct mappoint {
gdouble m_fLatitude;
@@ -65,7 +109,6 @@ typedef struct zoomlevel {
extern zoomlevel_t g_sZoomLevels[];
-
typedef enum {
UNIT_FIRST=0,
UNIT_FEET=0,
@@ -79,54 +122,6 @@ typedef enum {
extern gchar* g_aDistanceUnitNames[];
-enum ERoadNameSuffix { // these can't change once stored in DB
- ROAD_SUFFIX_FIRST = 0,
- ROAD_SUFFIX_NONE = 0,
-
- ROAD_SUFFIX_ROAD = 1,
- ROAD_SUFFIX_STREET,
- ROAD_SUFFIX_DRIVE,
- ROAD_SUFFIX_BOULEVARD, // blvd
- ROAD_SUFFIX_AVENUE,
- ROAD_SUFFIX_CIRCLE,
- ROAD_SUFFIX_SQUARE,
- ROAD_SUFFIX_PATH,
- ROAD_SUFFIX_WAY,
- ROAD_SUFFIX_PLAZA,
- ROAD_SUFFIX_TRAIL,
- ROAD_SUFFIX_LANE,
- ROAD_SUFFIX_CROSSING,
- ROAD_SUFFIX_PLACE,
- ROAD_SUFFIX_COURT,
- ROAD_SUFFIX_TURNPIKE,
- ROAD_SUFFIX_TERRACE,
- ROAD_SUFFIX_ROW,
- ROAD_SUFFIX_PARKWAY,
-
- ROAD_SUFFIX_BRIDGE,
- ROAD_SUFFIX_HIGHWAY,
- ROAD_SUFFIX_RUN,
- ROAD_SUFFIX_PASS,
-
- ROAD_SUFFIX_FREEWAY,
- ROAD_SUFFIX_ALLEY,
- ROAD_SUFFIX_CRESCENT,
- ROAD_SUFFIX_TUNNEL,
- ROAD_SUFFIX_WALK,
- ROAD_SUFFIX_BRANCE,
- ROAD_SUFFIX_COVE,
- ROAD_SUFFIX_BYPASS,
- ROAD_SUFFIX_LOOP,
- ROAD_SUFFIX_SPUR,
- ROAD_SUFFIX_RAMP,
- ROAD_SUFFIX_PIKE,
- ROAD_SUFFIX_GRADE,
- ROAD_SUFFIX_ROUTE,
- ROAD_SUFFIX_ARC,
-
- ROAD_SUFFIX_LAST = ROAD_SUFFIX_ARC
-};
-
typedef struct {
gint m_nZoomLevel;
gdouble m_fScreenLatitude;
@@ -136,38 +131,58 @@ typedef struct {
gint m_nWindowHeight;
} rendermetrics_t;
-// ESuffixLength
-typedef enum {
- SUFFIX_LENGTH_SHORT,
- SUFFIX_LENGTH_LONG
-} ESuffixLength;
+typedef struct {
+ GPtrArray* m_pPointStringsArray; // this should probably change to an array of 'roads'
+} maplayer_data_t;
+
+typedef struct {
+ // Mutex and the data it controls (always lock before reading/writing)
+ GMutex* m_pDataMutex;
+ mappoint_t m_MapCenter;
+ dimensions_t m_MapDimensions;
+ guint16 m_uZoomLevel;
+ maplayer_data_t* m_apLayerData[ NUM_LAYERS + 1 ];
+ GtkWidget* m_pTargetWidget;
+ scenemanager_t* m_pSceneManager;
+
+ // Mutex and the data it controls (always lock before reading/writing)
+ GMutex* m_pPixmapMutex;
+ GdkPixmap* m_pPixmap;
+} map_t;
+
-void map_draw(cairo_t *cr);
+void map_init(void);
+gboolean map_new(map_t** ppMap, GtkWidget* pTargetWidget);
-const gchar* map_road_suffix_itoa(gint nSuffixID, ESuffixLength eSuffixLength);
-gboolean map_road_suffix_atoi(const gchar* pszSuffix, gint* pReturnSuffixID);
// Gets and Sets
-guint16 map_get_zoomlevel(void);
-guint32 map_get_zoomlevel_scale(void);
-void map_set_zoomlevel(guint16 uZoomLevel);
+guint16 map_get_zoomlevel(map_t* pMap);
+guint32 map_get_zoomlevel_scale(map_t* pMap);
+void map_set_zoomlevel(map_t* pMap, guint16 uZoomLevel);
//void map_get_render_metrics(rendermetrics_t* pMetrics);
-void map_set_redraw_needed(gboolean bNeeded);
-gboolean map_get_redraw_needed(void);
+void map_set_redraw_needed(map_t* pMap, gboolean bNeeded);
+gboolean map_get_redraw_needed(map_t* pMap);
-guint32 map_get_scale(void);
+guint32 map_get_scale(map_t* pMap);
-void map_set_centerpoint(const mappoint_t* pPoint);
-void map_get_centerpoint(mappoint_t* pReturnPoint);
-void map_set_dimensions(const dimensions_t* pDimensions);
+void map_set_centerpoint(map_t* pMap, const mappoint_t* pPoint);
+void map_get_centerpoint(map_t* pMap, mappoint_t* pReturnPoint);
+void map_set_dimensions(map_t* pMap, const dimensions_t* pDimensions);
// Conversions
-void map_windowpoint_to_mappoint(screenpoint_t* pScreenPoint, mappoint_t* pMapPoint);
-gdouble map_distance_in_units_to_degrees(gdouble fDistance, gint nDistanceUnit);
+void map_windowpoint_to_mappoint(map_t* pMap, screenpoint_t* pScreenPoint, mappoint_t* pMapPoint);
+gdouble map_distance_in_units_to_degrees(map_t* pMap, gdouble fDistance, gint nDistanceUnit);
// remove this!
-void map_center_on_windowpoint(guint16 uX, guint16 uY);
+void map_center_on_windowpoint(map_t* pMap, guint16 uX, guint16 uY);
+
+
+GdkPixmap* map_get_pixmap(map_t* pMap);
+void map_release_pixmap(map_t* pMap);
+void map_draw_thread_begin(map_t* pMap, GtkWidget* pTargetWidget);
+
+void map_draw(map_t* pMap, cairo_t *cr);
#endif
diff --git a/src/road.c b/src/road.c
new file mode 100644
index 0000000..4eb16c7
--- /dev/null
+++ b/src/road.c
@@ -0,0 +1,221 @@
+/***************************************************************************
+ * road.c
+ *
+ * Copyright 2005 Ian McIntosh
+ * ian_mcintosh@linuxadvocate.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gnome.h>
+#include "road.h"
+#include "util.h"
+
+struct {
+ gchar* m_pszLong;
+ gchar* m_pszShort;
+} g_RoadNameSuffix[] = {
+ {"",""},
+ {"Road", "Rd"},
+ {"Street", "St"},
+ {"Drive", "Dr"},
+ {"Boulevard", "Bvd"},
+ {"Avenue", "Ave"},
+ {"Circle", "Crl"},
+ {"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"},
+};
+
+struct {
+ gchar* m_pszName;
+ gint m_nID;
+} g_RoadNameSuffixLookup[] = {
+ {"Rd", ROAD_SUFFIX_ROAD},
+ {"Road", ROAD_SUFFIX_ROAD},
+
+ {"St", ROAD_SUFFIX_STREET},
+ {"Street", ROAD_SUFFIX_STREET},
+
+ {"Dr", ROAD_SUFFIX_DRIVE},
+ {"Drive", ROAD_SUFFIX_DRIVE},
+
+ {"Blv", ROAD_SUFFIX_BOULEVARD},
+ {"Blvd", ROAD_SUFFIX_BOULEVARD},
+ {"Boulevard", ROAD_SUFFIX_BOULEVARD},
+
+ {"Av", ROAD_SUFFIX_AVENUE},
+ {"Ave", ROAD_SUFFIX_AVENUE},
+ {"Avenue", ROAD_SUFFIX_AVENUE},
+
+ {"Cir", ROAD_SUFFIX_CIRCLE},
+ {"Crl", ROAD_SUFFIX_CIRCLE},
+ {"Circle", ROAD_SUFFIX_CIRCLE},
+
+ {"Sq", ROAD_SUFFIX_SQUARE},
+ {"Square", ROAD_SUFFIX_SQUARE},
+
+ {"Pl", ROAD_SUFFIX_PLACE},
+ {"Place", ROAD_SUFFIX_PLACE},
+
+ {"Xing", ROAD_SUFFIX_CROSSING},
+ {"Crossing", ROAD_SUFFIX_CROSSING},
+
+ {"Ct", ROAD_SUFFIX_COURT},
+ {"Court", ROAD_SUFFIX_COURT},
+
+ {"Tpke", ROAD_SUFFIX_TURNPIKE},
+ {"Turnpike", ROAD_SUFFIX_TURNPIKE},
+
+ {"Ter", ROAD_SUFFIX_TERRACE},
+ {"Terrace", ROAD_SUFFIX_TERRACE},
+
+ {"Row", ROAD_SUFFIX_ROW},
+
+ {"Pth", ROAD_SUFFIX_PATH},
+ {"Path", ROAD_SUFFIX_PATH},
+
+ {"Wy", ROAD_SUFFIX_WAY},
+ {"Way", ROAD_SUFFIX_WAY},
+
+ {"Plz", ROAD_SUFFIX_PLAZA},
+ {"Plaza", ROAD_SUFFIX_PLAZA},
+
+ {"Trl", ROAD_SUFFIX_TRAIL},
+ {"Trail", ROAD_SUFFIX_TRAIL},
+
+ {"Ln", ROAD_SUFFIX_LANE},
+ {"Lane", ROAD_SUFFIX_LANE},
+
+ {"Pky", ROAD_SUFFIX_PARKWAY},
+ {"Parkway", ROAD_SUFFIX_PARKWAY},
+
+ {"Brg", ROAD_SUFFIX_BRIDGE},
+ {"Bridge", ROAD_SUFFIX_BRIDGE},
+
+ {"Hwy", ROAD_SUFFIX_HIGHWAY},
+ {"Highway", ROAD_SUFFIX_HIGHWAY},
+
+ {"Run", ROAD_SUFFIX_RUN},
+
+ {"Pass", ROAD_SUFFIX_PASS},
+
+ {"Freeway", ROAD_SUFFIX_FREEWAY},
+ {"Fwy", ROAD_SUFFIX_FREEWAY},
+
+ {"Alley", ROAD_SUFFIX_ALLEY},
+ {"Aly", ROAD_SUFFIX_ALLEY},
+
+ {"Crescent", ROAD_SUFFIX_CRESCENT},
+ {"Cres", ROAD_SUFFIX_CRESCENT},
+
+ {"Tunnel", ROAD_SUFFIX_TUNNEL},
+ {"Tunl", ROAD_SUFFIX_TUNNEL},
+
+ {"Walk", ROAD_SUFFIX_WALK},
+ {"Walk", ROAD_SUFFIX_WALK},
+
+ {"Branch", ROAD_SUFFIX_BRANCE},
+ {"Br", ROAD_SUFFIX_BRANCE},
+
+ {"Cove", ROAD_SUFFIX_COVE},
+ {"Cv", ROAD_SUFFIX_COVE},
+
+ {"Bypass", ROAD_SUFFIX_BYPASS},
+ {"Byp", ROAD_SUFFIX_BYPASS},
+
+ {"Loop", ROAD_SUFFIX_LOOP},
+
+ {"Spur", ROAD_SUFFIX_SPUR},
+
+ {"Ramp", ROAD_SUFFIX_RAMP},
+
+ {"Pike", ROAD_SUFFIX_PIKE},
+
+ {"Grade", ROAD_SUFFIX_GRADE},
+ {"Grd", ROAD_SUFFIX_GRADE},
+
+ {"Route", ROAD_SUFFIX_ROUTE},
+ {"Rte", ROAD_SUFFIX_ROUTE},
+
+ {"Arc", ROAD_SUFFIX_ARC},
+
+};
+
+
+// ========================================================
+// Road Direction / Suffix conversions
+// ========================================================
+
+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].m_pszShort;
+ }
+ else {
+ return g_RoadNameSuffix[nSuffixID].m_pszLong;
+ }
+ }
+ if(nSuffixID != ROAD_SUFFIX_NONE) return "???";
+ return "";
+}
+
+gboolean road_suffix_atoi(const gchar* pszSuffix, gint* pReturnSuffixID)
+{
+ gint i;
+ for(i=0 ; i<NUM_ELEMS(g_RoadNameSuffixLookup) ; i++) {
+ if(g_ascii_strcasecmp(pszSuffix, g_RoadNameSuffixLookup[i].m_pszName) == 0) {
+ *pReturnSuffixID = g_RoadNameSuffixLookup[i].m_nID;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
diff --git a/src/road.h b/src/road.h
new file mode 100644
index 0000000..4b1d6e0
--- /dev/null
+++ b/src/road.h
@@ -0,0 +1,84 @@
+/***************************************************************************
+ * road.h
+ *
+ * Copyright 2005 Ian McIntosh
+ * ian_mcintosh@linuxadvocate.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _ROAD_H_
+#define _ROAD_H_
+
+// ESuffixLength
+typedef enum {
+ ROAD_SUFFIX_LENGTH_SHORT,
+ ROAD_SUFFIX_LENGTH_LONG
+} ESuffixLength;
+
+enum ERoadNameSuffix { // these can't change once stored in DB
+ ROAD_SUFFIX_FIRST = 0,
+ ROAD_SUFFIX_NONE = 0,
+
+ ROAD_SUFFIX_ROAD = 1,
+ ROAD_SUFFIX_STREET,
+ ROAD_SUFFIX_DRIVE,
+ ROAD_SUFFIX_BOULEVARD, // blvd
+ ROAD_SUFFIX_AVENUE,
+ ROAD_SUFFIX_CIRCLE,
+ ROAD_SUFFIX_SQUARE,
+ ROAD_SUFFIX_PATH,
+ ROAD_SUFFIX_WAY,
+ ROAD_SUFFIX_PLAZA,
+ ROAD_SUFFIX_TRAIL,
+ ROAD_SUFFIX_LANE,
+ ROAD_SUFFIX_CROSSING,
+ ROAD_SUFFIX_PLACE,
+ ROAD_SUFFIX_COURT,
+ ROAD_SUFFIX_TURNPIKE,
+ ROAD_SUFFIX_TERRACE,
+ ROAD_SUFFIX_ROW,
+ ROAD_SUFFIX_PARKWAY,
+
+ ROAD_SUFFIX_BRIDGE,
+ ROAD_SUFFIX_HIGHWAY,
+ ROAD_SUFFIX_RUN,
+ ROAD_SUFFIX_PASS,
+
+ ROAD_SUFFIX_FREEWAY,
+ ROAD_SUFFIX_ALLEY,
+ ROAD_SUFFIX_CRESCENT,
+ ROAD_SUFFIX_TUNNEL,
+ ROAD_SUFFIX_WALK,
+ ROAD_SUFFIX_BRANCE,
+ ROAD_SUFFIX_COVE,
+ ROAD_SUFFIX_BYPASS,
+ ROAD_SUFFIX_LOOP,
+ ROAD_SUFFIX_SPUR,
+ ROAD_SUFFIX_RAMP,
+ ROAD_SUFFIX_PIKE,
+ ROAD_SUFFIX_GRADE,
+ ROAD_SUFFIX_ROUTE,
+ ROAD_SUFFIX_ARC,
+
+ ROAD_SUFFIX_LAST = ROAD_SUFFIX_ARC
+};
+
+const gchar* road_suffix_itoa(gint nSuffixID, ESuffixLength eSuffixLength);
+gboolean road_suffix_atoi(const gchar* pszSuffix, gint* pReturnSuffixID);
+
+#endif
diff --git a/src/scenemanager.c b/src/scenemanager.c
index d700277..549644b 100644
--- a/src/scenemanager.c
+++ b/src/scenemanager.c
@@ -22,7 +22,6 @@
*/
#include <gtk/gtk.h>
-#include "geometryset.h"
#include "scenemanager.h"
/*
@@ -36,57 +35,50 @@ Goals:
// gchar* m_pszLabel;
// } roadlabel_t;
-struct {
- GPtrArray* m_p;
- GHashTable* m_pLabelHash;
-} g_SceneManager;
-
void scenemanager_init(void)
{
- g_SceneManager.m_pLabelHash = g_hash_table_new(g_str_hash, g_str_equal);
}
-gboolean scenemanager_can_draw_label(const gchar* pszLabel)
+void scenemanager_new(scenemanager_t** ppReturn)
+{
+ scenemanager_t* pNew = g_new0(scenemanager_t, 1);
+ pNew->m_pLabelHash = g_hash_table_new(g_str_hash, g_str_equal);
+ *ppReturn = pNew;
+}
+
+gboolean scenemanager_can_draw_label(scenemanager_t* pSceneManager, const gchar* pszLabel)
{
+ g_assert(pSceneManager != NULL);
+
gpointer pKey;
gpointer pValue;
// can draw if it doesn't exist in table
- gboolean bOK = (g_hash_table_lookup_extended(g_SceneManager.m_pLabelHash,
- pszLabel,
- &pKey, &pValue) == FALSE);
+ gboolean bOK = (g_hash_table_lookup_extended(pSceneManager->m_pLabelHash,
+ pszLabel, &pKey, &pValue) == FALSE);
// g_print("permission for %s: %s\n", pszLabel, bOK ? "YES" : "NO");
return bOK;
}
-void scenemanager_label_drawn(const gchar* pszLabel)
+void scenemanager_label_drawn(scenemanager_t* pSceneManager, const gchar* pszLabel)
{
+ g_assert(pSceneManager != NULL);
// g_print("drawn! %s\n", pszLabel);
- g_hash_table_insert(g_SceneManager.m_pLabelHash, pszLabel, NULL);
+ g_hash_table_insert(pSceneManager->m_pLabelHash, pszLabel, NULL);
}
-void scenemanager_clear(void)
+void scenemanager_clear(scenemanager_t* pSceneManager)
{
- g_hash_table_destroy(g_SceneManager.m_pLabelHash);
+ g_assert(pSceneManager != NULL);
- scenemanager_init();
+ g_hash_table_destroy(pSceneManager->m_pLabelHash);
+ pSceneManager->m_pLabelHash = g_hash_table_new(g_str_hash, g_str_equal);
}
#if ROADSTER_DEAD_CODE
-static void scenemanager_add_label_line(geometryset_t* pGeometry, gchar* pszLabel)
-{
-
-}
-
-static void scenemanager_add_label_polygon(geometryset_t* pGeometry, gchar* pszLabel)
-{
-
-}
-
-static void scenemanager_draw(void)
-{
-
-}
+static void scenemanager_add_label_line(geometryset_t* pGeometry, gchar* pszLabel) {}
+static void scenemanager_add_label_polygon(geometryset_t* pGeometry, gchar* pszLabel) {}
+static void scenemanager_draw(void) {}
#endif /* ROADSTER_DEAD_CODE */
diff --git a/src/scenemanager.h b/src/scenemanager.h
index ac4c6ca..ebbe929 100644
--- a/src/scenemanager.h
+++ b/src/scenemanager.h
@@ -21,8 +21,22 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+#ifndef _SCENEMANAGER_H_
+#define _SCENEMANAGER_H_
+
+//#include <gnome.h>
+
+typedef struct scenemanager {
+ GPtrArray* m_p;
+ GHashTable* m_pLabelHash;
+} scenemanager_t;
+
void scenemanager_init(void);
-gboolean scenemanager_can_draw_label(const gchar* pszLabel);
-void scenemanager_label_drawn(const gchar* pszLabel);
-void scenemanager_clear(void);
+void scenemanager_new(scenemanager_t** ppReturn);
+
+gboolean scenemanager_can_draw_label(scenemanager_t* pSceneManager, const gchar* pszLabel);
+void scenemanager_label_drawn(scenemanager_t* pSceneManager, const gchar* pszLabel);
+void scenemanager_clear(scenemanager_t* pSceneManager);
+
+#endif
diff --git a/src/search.c b/src/search.c
index 56a4780..c943baf 100644
--- a/src/search.c
+++ b/src/search.c
@@ -20,7 +20,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-
+
#include <gtk/gtk.h>
#include "search.h"
@@ -34,20 +34,20 @@ void search_clean_string(gchar* p)
gchar* pWriter = p;
// skip white
- while(*pReader == ' ') {
+ while(g_ascii_isspace(*pReader)) {
pReader++;
}
// remove double spaces
while(*pReader != '\0') {
- if(*pReader == ' ') {
- if(*(pReader+1) == ' ' || *(pReader+1) == '\0') {
+ if(g_ascii_isspace(*pReader)) {
+ if(g_ascii_isspace(*(pReader+1)) || *(pReader+1) == '\0') {
// don't copy this character (space) if the next one is a space also
// or if it's the last character
}
else {
// yes, copy this space
- *pWriter = *pReader;
+ *pWriter = ' '; // this also turns newlines etc. into spaces
pWriter++;
}
}
diff --git a/src/search_location.c b/src/search_location.c
index baf1852..c37342e 100644
--- a/src/search_location.c
+++ b/src/search_location.c
@@ -47,6 +47,8 @@ void search_location_filter_result(gint nLocationID);
void search_location_execute(const gchar* pszSentence, gint nLocationSetID, gfloat fDistance, gint nDistanceUnit)
{
+ return;
+/*
g_print("pszSentence = %s, nLocationSetID = %d, fDistance = %f, nDistanceUnit=%d\n", pszSentence, nLocationSetID, fDistance, nDistanceUnit);
TIMER_BEGIN(search, "\n\n****************************\nSEARCH BEGIN");
@@ -62,8 +64,10 @@ void search_location_execute(const gchar* pszSentence, gint nLocationSetID, gflo
g_free(locationsearch.m_pszCleanedSentence);
TIMER_END(search, "SEARCH END");
+*/
}
+/*
void search_location_on_cleaned_sentence(locationsearch_t* pLocationSearch)
{
// Create an array of the words
@@ -172,3 +176,4 @@ void search_location_filter_result(gint nLocationID)
searchwindow_add_result(0, p, &pt);
g_free(p);
}
+*/
diff --git a/src/search_road.c b/src/search_road.c
index 59339d5..84950a3 100644
--- a/src/search_road.c
+++ b/src/search_road.c
@@ -27,25 +27,26 @@
#include "db.h"
#include "util.h"
-//#include "geometryset.h"
#include "pointstring.h"
#include "point.h"
#include "searchwindow.h"
#include "search.h"
#include "search_road.h"
+#include "road.h"
typedef struct {
gint m_nNumber; // house number eg. 51
gchar* m_pszRoadName; // road name eg. "Washington"
gint m_nCityID; //
gint m_nStateID;
- gint m_pszZIPCode;
+ gchar* m_pszZIPCode;
gint m_nSuffixID; // a number representing eg. Ave
} roadsearch_t;
-#define ROADSEARCH_NUMBER_NONE (-1)
-#define SEARCH_RESULT_COUNT_LIMIT (200) // how many rows to get from DB
-#define MAX_QUERY (4000)
+#define ROADSEARCH_NUMBER_NONE (-1)
+#define SEARCH_RESULT_COUNT_LIMIT (200) // how many rows to get from DB
+#define MAX_QUERY (4000)
+#define ROAD_MIN_LENGTH_FOR_WILDCARD_SEARCH (3)
// if glib < 2.6
#if ((GLIB_MAJOR_VERSION < 2) || ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION < 6)))
@@ -223,7 +224,7 @@ void search_road_on_words(gchar** aWords, gint nWordCount)
if(nRemainingWordCount >= 2) {
gint nSuffixID;
- if(map_road_suffix_atoi(aWords[iLast], &nSuffixID)) {
+ if(road_suffix_atoi(aWords[iLast], &nSuffixID)) {
// matched
roadsearch.m_nSuffixID = nSuffixID;
iLast--;
@@ -309,6 +310,14 @@ void search_road_on_roadsearch_struct(const roadsearch_t* pRoadSearch)
gchar* pszSafeRoadName = db_make_escaped_string(pRoadSearch->m_pszRoadName);
g_print("pRoadSearch->m_pszRoadName = %s, pszSafeRoadName = %s\n", pRoadSearch->m_pszRoadName, pszSafeRoadName);
+ gchar* pszRoadNameCondition;
+ if(strlen(pRoadSearch->m_pszRoadName) < ROAD_MIN_LENGTH_FOR_WILDCARD_SEARCH) {
+ pszRoadNameCondition = g_strdup_printf("RoadName.Name='%s'", pszSafeRoadName);
+ }
+ else {
+ pszRoadNameCondition = g_strdup_printf("RoadName.Name LIKE '%s%%'", pszSafeRoadName);
+ }
+
g_snprintf(azQuery, MAX_QUERY,
"SELECT Road.ID, RoadName.Name, RoadName.SuffixID, AsText(Road.Coordinates), Road.AddressLeftStart, Road.AddressLeftEnd, Road.AddressRightStart, Road.AddressRightEnd, CityLeft.Name, CityRight.Name"
", StateLeft.Code, StateRight.Code, Road.ZIPCodeLeft, Road.ZIPCodeRight"
@@ -321,18 +330,18 @@ void search_road_on_roadsearch_struct(const roadsearch_t* pRoadSearch)
// right side
" LEFT JOIN City AS CityRight ON (Road.CityRightID=CityRight.ID)"
" LEFT JOIN State AS StateRight ON (CityRight.StateID=StateRight.ID)"
- " WHERE RoadName.Name LIKE '%s%%'"
+ " WHERE %s"
// " WHERE RoadName.Name='%s'"
" AND Road.ID IS NOT NULL" // don't include rows where the Road didn't match
// begin clauses
"%s"
"%s"
- "%s"
- "%s"
-// " ORDER BY RoadName.Name"
+ "%s"
+ "%s"
" LIMIT %d;",
pszAddressClause,
- pszSafeRoadName,
+
+ pszRoadNameCondition,
// clauses
pszSuffixClause,
@@ -344,6 +353,7 @@ void search_road_on_roadsearch_struct(const roadsearch_t* pRoadSearch)
// free strings
db_free_escaped_string(pszSafeRoadName);
g_free(pszAddressClause);
+ g_free(pszRoadNameCondition);
g_free(pszSuffixClause);
g_free(pszZIPClause);
g_free(pszCityClause);
@@ -552,35 +562,35 @@ void search_road_filter_result(
// show no numbers if they're both 0
g_snprintf(azBuffer, BUFFER_SIZE, "%s %s\n%s",
pszRoadName,
- map_road_suffix_itoa(nRoadSuffixID, SUFFIX_LENGTH_LONG),
+ road_suffix_itoa(nRoadSuffixID, ROAD_SUFFIX_LENGTH_LONG),
pszCSZRight);
}
else if(nAddressRightStart < nAddressRightEnd) {
- g_snprintf(azBuffer, BUFFER_SIZE, "%d-%d %s %s\n%s", nAddressRightStart, nAddressRightEnd, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_LENGTH_LONG), pszCSZRight);
+ g_snprintf(azBuffer, BUFFER_SIZE, "%d-%d %s %s\n%s", nAddressRightStart, nAddressRightEnd, pszRoadName, road_suffix_itoa(nRoadSuffixID, ROAD_SUFFIX_LENGTH_LONG), pszCSZRight);
}
else {
// reverse start/end for the dear user :)
- g_snprintf(azBuffer, BUFFER_SIZE, "%d-%d %s %s\n%s", nAddressRightEnd, nAddressRightStart, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_LENGTH_LONG), pszCSZRight);
+ g_snprintf(azBuffer, BUFFER_SIZE, "%d-%d %s %s\n%s", nAddressRightEnd, nAddressRightStart, pszRoadName, road_suffix_itoa(nRoadSuffixID, ROAD_SUFFIX_LENGTH_LONG), pszCSZRight);
}
searchwindow_add_result(nRoadID, azBuffer, &ptAddress);
// do left side, same as right side (see above)
if(nAddressLeftStart == 0 && nAddressLeftEnd == 0) {
- g_snprintf(azBuffer, BUFFER_SIZE, "%s %s\n%s", pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_LENGTH_LONG), pszCSZLeft);
+ g_snprintf(azBuffer, BUFFER_SIZE, "%s %s\n%s", pszRoadName, road_suffix_itoa(nRoadSuffixID, ROAD_SUFFIX_LENGTH_LONG), pszCSZLeft);
}
else if(nAddressLeftStart < nAddressLeftEnd) {
- g_snprintf(azBuffer, BUFFER_SIZE, "%d-%d %s %s\n%s", nAddressLeftStart, nAddressLeftEnd, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_LENGTH_LONG), pszCSZLeft);
+ g_snprintf(azBuffer, BUFFER_SIZE, "%d-%d %s %s\n%s", nAddressLeftStart, nAddressLeftEnd, pszRoadName, road_suffix_itoa(nRoadSuffixID, ROAD_SUFFIX_LENGTH_LONG), pszCSZLeft);
}
else {
// swap address to keep smaller number to the left
- g_snprintf(azBuffer, BUFFER_SIZE, "%d-%d %s %s\n%s", nAddressLeftEnd, nAddressLeftStart, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_LENGTH_LONG), pszCSZLeft);
+ g_snprintf(azBuffer, BUFFER_SIZE, "%d-%d %s %s\n%s", nAddressLeftEnd, nAddressLeftStart, pszRoadName, road_suffix_itoa(nRoadSuffixID, ROAD_SUFFIX_LENGTH_LONG), pszCSZLeft);
}
searchwindow_add_result(nRoadID, azBuffer, &ptAddress);
}
else { // else the search had a road number
// NOTE: we have to filter out results like "97-157" when searching for "124" because it's
// on the wrong side of the road.
-//g_snprintf(azBuffer, BUFFER_SIZE, "%d %s %s", nRoadNumber, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_LENGTH_LONG));
+//g_snprintf(azBuffer, BUFFER_SIZE, "%d %s %s", nRoadNumber, pszRoadName, road_suffix_itoa(nRoadSuffixID, ROAD_SUFFIX_LENGTH_LONG));
// check left side of street
// NOTE: if search was for an even, at least one (and hopefully both) of the range should be even
@@ -599,7 +609,7 @@ void search_road_filter_result(
gfloat fPercent = (gfloat)(nRoadNumber - nAddressLeftStart) / (gfloat)nRange;
pointstring_walk_percentage(pPointString, fPercent, ROADSIDE_LEFT, &ptAddress);
}
- g_snprintf(azBuffer, BUFFER_SIZE, "%d %s %s\n%s", nRoadNumber, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_LENGTH_LONG), pszCSZLeft);
+ g_snprintf(azBuffer, BUFFER_SIZE, "%d %s %s\n%s", nRoadNumber, pszRoadName, road_suffix_itoa(nRoadSuffixID, ROAD_SUFFIX_LENGTH_LONG), pszCSZLeft);
searchwindow_add_result(nRoadID, azBuffer, &ptAddress);
}
else if(nRoadNumber >= nAddressLeftEnd && nRoadNumber <= nAddressLeftStart) {
@@ -615,7 +625,7 @@ void search_road_filter_result(
// flip percent (23 becomes 77, etc.)
pointstring_walk_percentage(pPointString, (100.0 - fPercent), ROADSIDE_RIGHT, &ptAddress);
}
- g_snprintf(azBuffer, BUFFER_SIZE, "%d %s %s\n%s", nRoadNumber, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_LENGTH_LONG), pszCSZLeft);
+ g_snprintf(azBuffer, BUFFER_SIZE, "%d %s %s\n%s", nRoadNumber, pszRoadName, road_suffix_itoa(nRoadSuffixID, ROAD_SUFFIX_LENGTH_LONG), pszCSZLeft);
searchwindow_add_result(nRoadID, azBuffer, &ptAddress);
}
}
@@ -636,7 +646,7 @@ void search_road_filter_result(
gfloat fPercent = (gfloat)(nRoadNumber - nAddressRightStart) / (gfloat)nRange;
pointstring_walk_percentage(pPointString, fPercent, ROADSIDE_RIGHT, &ptAddress);
}
- g_snprintf(azBuffer, BUFFER_SIZE, "%d %s %s\n%s", nRoadNumber, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_LENGTH_LONG), pszCSZRight);
+ g_snprintf(azBuffer, BUFFER_SIZE, "%d %s %s\n%s", nRoadNumber, pszRoadName, road_suffix_itoa(nRoadSuffixID, ROAD_SUFFIX_LENGTH_LONG), pszCSZRight);
searchwindow_add_result(nRoadID, azBuffer, &ptAddress);
}
else if(nRoadNumber >= nAddressRightEnd && nRoadNumber <= nAddressRightStart) {
@@ -652,7 +662,7 @@ void search_road_filter_result(
// flip percent (23 becomes 77, etc.)
pointstring_walk_percentage(pPointString, (100.0 - fPercent), ROADSIDE_LEFT, &ptAddress);
}
- g_snprintf(azBuffer, BUFFER_SIZE, "%d %s %s\n%s", nRoadNumber, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_LENGTH_LONG), pszCSZRight);
+ g_snprintf(azBuffer, BUFFER_SIZE, "%d %s %s\n%s", nRoadNumber, pszRoadName, road_suffix_itoa(nRoadSuffixID, ROAD_SUFFIX_LENGTH_LONG), pszCSZRight);
searchwindow_add_result(nRoadID, azBuffer, &ptAddress);
}
}
diff --git a/src/searchwindow.c b/src/searchwindow.c
index bfcb778..5661093 100644
--- a/src/searchwindow.c
+++ b/src/searchwindow.c
@@ -264,9 +264,7 @@ void searchwindow_go_to_selected_result(void)
RESULTLIST_LONGITUDE, &pt.m_fLongitude,
-1);
- g_print("%f,%f\n", pt.m_fLatitude, pt.m_fLongitude);
-
- map_set_centerpoint(&pt);
+ mainwindow_set_centerpoint(&pt);
mainwindow_draw_map();
mainwindow_statusbar_update_position();
// g_print("yay: %s\n", pszText);
diff --git a/src/util.h b/src/util.h
index abe3ef1..46bfaff 100644
--- a/src/util.h
+++ b/src/util.h
@@ -30,7 +30,7 @@
void util_random_color(void* pColor);
-#if 0
+#if 1
#define TIMER_BEGIN(name, str) GTimer* name = g_timer_new(); g_print("\n%s (%f)\n", str, g_timer_elapsed(name, NULL))
#define TIMER_SHOW(name, str) g_print(" %s (%f)\n", str, g_timer_elapsed(name, NULL))
#define TIMER_END(name, str) g_print("%s (%f)\n", str, g_timer_elapsed(name, NULL)); g_timer_destroy(name); name = NULL