[cairo-commit] roadster/src db.c, 1.12, 1.13 db.h, 1.7,
1.8 import_tiger.c, 1.11, 1.12 locationset.c, 1.5,
1.6 mainwindow.c, 1.21, 1.22 map.c, 1.19,
1.20 map_draw_cairo.c, 1.7, 1.8 scenemanager.c, 1.7,
1.8 scenemanager.h, 1.4, 1.5 search_road.c, 1.13, 1.14
Ian McIntosh
commit at pdx.freedesktop.org
Wed Mar 9 22:12:05 PST 2005
Committed by: ian
Update of /cvs/cairo/roadster/src
In directory gabe:/tmp/cvs-serv5990/src
Modified Files:
db.c db.h import_tiger.c locationset.c mainwindow.c map.c
map_draw_cairo.c scenemanager.c scenemanager.h search_road.c
Log Message:
* src/search_road.c:
* src/import_tiger.c:
* src/db.c: Removed Road_RoadName joiner table. Roads can have only one name now (we never used this feature).
* src/db.c: Removed warning for failed inserts (really should only avoid printing warnings for duplicates on unique keys). Removed db_parse_point() that used MySQL's text format (no replacement yet but it's not used). Removed some dead code.
* src/mainwindow.c: Don't draw twice on zoom in/out.
* src/map.c: Pulled font selection up a level, so it's done once per layer. Added a demo of the scenemanager code (a square drawn on the map that text avoids!). Tweaked scales for the zoom levels.
* src/map_draw_cairo.c: Added a simpler line labeler for single-segment roads (we need to profile it to see if it's worth using). Curved text is temporarily turned off because it doesn't use the scenemanager yet. All gfloats to gdoubles.
* src/scenemanager.c: Added scenemanager_can_draw_rectangle().
Index: db.c
===================================================================
RCS file: /cvs/cairo/roadster/src/db.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- db.c 4 Mar 2005 02:27:29 -0000 1.12
+++ db.c 10 Mar 2005 06:12:03 -0000 1.13
@@ -55,41 +55,71 @@
db_connection_t* g_pDB = NULL;
-gboolean db_query(const gchar* pszSQL, db_resultset_t** ppResultSet)
+/******************************************************
+** Init and deinit of database module
+******************************************************/
+
+// call once on program start-up
+void db_init()
{
- g_assert(pszSQL != NULL);
- if(g_pDB == NULL) return FALSE;
+// g_pDBMutex = g_mutex_new();
- 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;
+#ifdef HAVE_MYSQL_EMBED
+ gchar* pszDataDir = g_strdup_printf("%s/.roadster/data", g_get_home_dir());
+ gchar* pszSetDataDirCommand = g_strdup_printf("--datadir=%s", pszDataDir);
+
+ // Create directory if it doesn't exist
+ if(GNOME_VFS_OK != gnome_vfs_make_directory(pszDataDir, 0700)) {
+ // no big deal, probably already exists (should we check?)
}
- // get result?
- if(ppResultSet != NULL) {
- *ppResultSet = (db_resultset_t*)MYSQL_GET_RESULT(g_pDB->m_pMySQLConnection);
+ gchar* apszServerOptions[] = {
+ "", // program name -- unused
+ "--skip-innodb", // don't bother with table types we don't use
+ "--skip-bdb", //
+
+// "--query_cache_type=1",
+// "--query_cache_size=40MB",
+
+// "--flush", // seems like a good idea since users can quickly kill the app/daemon
+ pszSetDataDirCommand
+ };
+
+ // Initialize the embedded server
+ // NOTE: if not linked with libmysqld, this call will do nothing (but will succeed)
+ if(mysql_server_init(NUM_ELEMS(apszServerOptions), apszServerOptions, NULL) != 0) {
+ return;
}
- return TRUE;
+ g_free(pszDataDir);
+ g_free(pszSetDataDirCommand);
+#endif
}
-static gboolean db_insert(const gchar* pszSQL, gint* pnReturnRowsInserted)
+// call once on program shut-down
+void db_deinit()
+{
+#ifdef HAVE_MYSQL_EMBED
+ // Close embedded server if present
+ mysql_server_end();
+#endif
+}
+
+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) {
+ gint nResult = mysql_query(g_pDB->m_pMySQLConnection, pszSQL);
+ if(nResult != MYSQL_RESULT_SUCCESS) {
g_warning("db_query: %s (SQL: %s)\n", mysql_error(g_pDB->m_pMySQLConnection), pszSQL);
return FALSE;
}
- my_ulonglong uCount = mysql_affected_rows(g_pDB->m_pMySQLConnection);
- if(uCount > 0) {
- if(pnReturnRowsInserted != NULL) {
- *pnReturnRowsInserted = uCount;
- }
- return TRUE;
+ // get result?
+ if(ppResultSet != NULL) {
+ *ppResultSet = (db_resultset_t*)MYSQL_GET_RESULT(g_pDB->m_pMySQLConnection);
}
- return FALSE;
+ return TRUE;
}
db_row_t db_fetch_row(db_resultset_t* pResultSet)
@@ -109,9 +139,38 @@
}
/******************************************************
-** database utility functions
+** Connection creation and destruction
******************************************************/
+// initiate a new connection to server
+gboolean db_connect(const gchar* pzHost, const gchar* pzUserName, const gchar* pzPassword, const gchar* pzDatabase)
+{
+ // create a MySQL connection context
+ MYSQL *pMySQLConnection = mysql_init(NULL);
+ g_return_val_if_fail(pMySQLConnection != NULL, FALSE);
+
+ // attempt a MySQL connection
+ if(mysql_real_connect(pMySQLConnection, pzHost, pzUserName, pzPassword, pzDatabase, 0, NULL, 0) == FALSE) {
+ g_warning("mysql_real_connect failed: %s\n", mysql_error(pMySQLConnection));
+ return FALSE;
+ }
+// db_enable_keys(); // just in case
+
+ // on success, alloc our connection struct and fill it
+ db_connection_t* pNewConnection = g_new0(db_connection_t, 1);
+ pNewConnection->m_pMySQLConnection = pMySQLConnection;
+ pNewConnection->m_pzHost = g_strdup(pzHost);
+ pNewConnection->m_pzUserName = g_strdup(pzUserName);
+ pNewConnection->m_pzPassword = g_strdup(pzPassword);
+ pNewConnection->m_pzDatabase = g_strdup(pzDatabase);
+
+ g_assert(g_pDB == NULL);
+ g_pDB = pNewConnection;
+
+ // just in case (this could mess with multi-user databases)
+ return TRUE;
+}
+
static gboolean db_is_connected(void)
{
// 'mysql_ping' will also attempt a re-connect if necessary
@@ -128,6 +187,11 @@
return mysql_get_host_info(g_pDB->m_pMySQLConnection);
}
+
+/******************************************************
+** database utility functions
+******************************************************/
+
// call db_free_escaped_string() on returned string
gchar* db_make_escaped_string(const gchar* pszString)
{
@@ -176,87 +240,30 @@
}
/******************************************************
-** Init and deinit of database module
-******************************************************/
-
-// 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);
-
- // Create directory if it doesn't exist
- if(GNOME_VFS_OK != gnome_vfs_make_directory(pszDataDir, 0700)) {
- // no big deal, probably already exists (should we check?)
- }
-
- gchar* apszServerOptions[] = {
- "", // program name -- unused
- "--skip-innodb", // don't bother with table types we don't use
- "--skip-bdb", //
-// "--flush", // seems like a good idea since users can quickly kill the app/daemon
- pszSetDataDirCommand
- };
-
- // Initialize the embedded server
- // NOTE: if not linked with libmysqld, this call will do nothing (but will succeed)
- if(mysql_server_init(NUM_ELEMS(apszServerOptions), apszServerOptions, NULL) != 0) {
- return;
- }
- g_free(pszDataDir);
- g_free(pszSetDataDirCommand);
-#endif
-}
-
-// call once on program shut-down
-void db_deinit()
-{
-#ifdef HAVE_MYSQL_EMBED
- // Close embedded server if present
- mysql_server_end();
-#endif
-}
-
-/******************************************************
-** Connection creation and destruction
+** data inserting
******************************************************/
-// initiate a new connection to server
-gboolean db_connect(const gchar* pzHost, const gchar* pzUserName, const gchar* pzPassword, const gchar* pzDatabase)
+static gboolean db_insert(const gchar* pszSQL, gint* pnReturnRowsInserted)
{
- // create a MySQL connection context
- MYSQL *pMySQLConnection = mysql_init(NULL);
- g_return_val_if_fail(pMySQLConnection != NULL, FALSE);
+ g_assert(pszSQL != NULL);
+ if(g_pDB == NULL) return FALSE;
- // attempt a MySQL connection
- if(mysql_real_connect(pMySQLConnection, pzHost, pzUserName, pzPassword, pzDatabase, 0, NULL, 0) == FALSE) {
- g_warning("mysql_real_connect failed: %s\n", mysql_error(pMySQLConnection));
+ 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;
}
-// db_enable_keys(); // just in case
-
- // on success, alloc our connection struct and fill it
- db_connection_t* pNewConnection = g_new0(db_connection_t, 1);
- pNewConnection->m_pMySQLConnection = pMySQLConnection;
- pNewConnection->m_pzHost = g_strdup(pzHost);
- pNewConnection->m_pzUserName = g_strdup(pzUserName);
- pNewConnection->m_pzPassword = g_strdup(pzPassword);
- pNewConnection->m_pzDatabase = g_strdup(pzDatabase);
- g_assert(g_pDB == NULL);
- g_pDB = pNewConnection;
-
- // just in case (this could mess with multi-user databases)
- return TRUE;
+ my_ulonglong uCount = mysql_affected_rows(g_pDB->m_pMySQLConnection);
+ if(uCount > 0) {
+ if(pnReturnRowsInserted != NULL) {
+ *pnReturnRowsInserted = uCount;
+ }
+ return TRUE;
+ }
+ return FALSE;
}
-/******************************************************
-** data inserting
-******************************************************/
-gboolean db_insert_road(gint nLayerType, gint nAddressLeftStart, gint nAddressLeftEnd, gint nAddressRightStart, gint nAddressRightEnd, gint nCityLeftID, gint nCityRightID, const gchar* pszZIPCodeLeft, const gchar* pszZIPCodeRight, GPtrArray* pPointsArray, gint* pReturnID)
+gboolean db_insert_road(gint nRoadNameID, gint nLayerType, gint nAddressLeftStart, gint nAddressLeftEnd, gint nAddressRightStart, gint nAddressRightEnd, gint nCityLeftID, gint nCityRightID, const gchar* pszZIPCodeLeft, const gchar* pszZIPCodeRight, GPtrArray* pPointsArray, gint* pReturnID)
{
g_assert(pReturnID != NULL);
if(!db_is_connected()) return FALSE;
@@ -278,11 +285,11 @@
gchar azQuery[MAX_SQLBUFFER_LEN];
g_snprintf(azQuery, MAX_SQLBUFFER_LEN,
- "INSERT INTO %s SET TypeID=%d, Coordinates=GeometryFromText('LINESTRING(%s)')"
+ "INSERT INTO %s SET RoadNameID=%d, TypeID=%d, Coordinates=GeometryFromText('LINESTRING(%s)')"
", AddressLeftStart=%d, AddressLeftEnd=%d, AddressRightStart=%d, AddressRightEnd=%d"
", CityLeftID=%d, CityRightID=%d"
", ZIPCodeLeft='%s', ZIPCodeRight='%s'",
- DB_ROADS_TABLENAME, nLayerType, azCoordinateList,
+ DB_ROADS_TABLENAME, nRoadNameID, nLayerType, azCoordinateList,
nAddressLeftStart, nAddressLeftEnd, nAddressRightStart, nAddressRightEnd,
nCityLeftID, nCityRightID,
pszZIPCodeLeft, pszZIPCodeRight);
@@ -296,6 +303,10 @@
return TRUE;
}
+/******************************************************
+**
+******************************************************/
+
static gboolean db_roadname_get_id(const gchar* pszName, gint nSuffixID, gint* pnReturnID)
{
gint nReturnID = 0;
@@ -310,6 +321,7 @@
db_row_t aRow;
db_query(pszSQL, &pResultSet);
g_free(pszSQL);
+
// get result?
if(pResultSet) {
if((aRow = db_fetch_row(pResultSet)) != NULL) {
@@ -325,9 +337,10 @@
return FALSE;
}
-gboolean db_insert_roadname(gint nRoadID, const gchar* pszName, gint nSuffixID)
+gboolean db_insert_roadname(const gchar* pszName, gint nSuffixID, gint* pnReturnID)
{
gint nRoadNameID = 0;
+
// Step 1. Insert into RoadName
if(db_roadname_get_id(pszName, nSuffixID, &nRoadNameID) == FALSE) {
gchar* pszSafeName = db_make_escaped_string(pszName);
@@ -339,19 +352,12 @@
}
g_free(pszSQL);
}
-
- // Step 2. Insert connector into Road_RoadName
+
if(nRoadNameID != 0) {
- gchar* pszSQL = g_strdup_printf("INSERT INTO Road_RoadName SET RoadID='%d', RoadNameID='%d'",
- nRoadID, nRoadNameID);
- if(db_insert(pszSQL, NULL)) {
- g_free(pszSQL);
- return TRUE;
- }
- else {
- g_free(pszSQL);
- return FALSE;
+ if(pnReturnID != NULL) {
+ *pnReturnID = nRoadNameID;
}
+ return TRUE;
}
return FALSE;
}
@@ -471,31 +477,6 @@
return TRUE;
}
-void db_parse_point(const gchar* pszText, mappoint_t* pPoint)
-{
- const gchar* p;
-
- p = pszText;
-
- if(p[0] == 'P') { //g_str_has_prefix(p, "POINT")) {
- // format is "POINT(1.2345 -5.4321)"
-
- p += (6); // move past "POINT("
- pPoint->m_fLatitude = g_ascii_strtod(p, (gchar**)&p);
-
- // space between coordinates
- g_return_if_fail(*p == ' ');
- p++;
-
- pPoint->m_fLongitude = g_ascii_strtod(p, (gchar**)&p);
- g_return_if_fail(*p == ')');
- g_return_if_fail(*(p+1) == '\0');
- }
- else {
- g_assert_not_reached();
- }
-}
-
#define WKB_POINT 1 // only two we care about
#define WKB_LINESTRING 2
@@ -533,19 +514,26 @@
db_query("CREATE TABLE IF NOT EXISTS Road("
" ID INT4 UNSIGNED NOT NULL AUTO_INCREMENT,"
" TypeID INT1 UNSIGNED NOT NULL,"
+
+ " RoadNameID INT4 UNSIGNED NOT NULL,"
+
" AddressLeftStart INT2 UNSIGNED NOT NULL,"
" AddressLeftEnd INT2 UNSIGNED NOT NULL,"
" AddressRightStart INT2 UNSIGNED NOT NULL,"
" AddressRightEnd INT2 UNSIGNED NOT NULL,"
- " CityLeftID INT4 UNSIGNED NOT NULL,"
+
+ " CityLeftID INT4 UNSIGNED NOT NULL,"
" CityRightID INT4 UNSIGNED NOT NULL,"
+
" ZIPCodeLeft CHAR(6) NOT NULL,"
" ZIPCodeRight CHAR(6) NOT NULL,"
+
" Coordinates point NOT NULL,"
-
+
// lots of indexes:
" PRIMARY KEY (ID),"
- " INDEX(TypeID),"
+ " INDEX(TypeID),"
+ " INDEX(RoadNameID)," // to get roads when we've matched a RoadName
" INDEX(AddressLeftStart, AddressLeftEnd),"
" INDEX(AddressRightStart, AddressRightEnd),"
" SPATIAL KEY (Coordinates));", NULL);
@@ -559,12 +547,12 @@
" UNIQUE KEY (Name(15), SuffixID));", NULL);
// Road_RoadName
- db_query("CREATE TABLE IF NOT EXISTS Road_RoadName("
- " RoadID INT4 UNSIGNED NOT NULL,"
- " RoadNameID INT4 UNSIGNED NOT NULL,"
-
- " PRIMARY KEY (RoadID, RoadNameID)," // allows search on (RoadID,RoadName) and just (RoadID)
- " INDEX(RoadNameID));", NULL); // allows search the other way, going from a Name to a RoadID
+// db_query("CREATE TABLE IF NOT EXISTS Road_RoadName("
+// " RoadID INT4 UNSIGNED NOT NULL,"
+// " RoadNameID INT4 UNSIGNED NOT NULL,"
+//
+// " PRIMARY KEY (RoadID, RoadNameID)," // allows search on (RoadID,RoadName) and just (RoadID)
+// " INDEX(RoadNameID));", NULL); // allows search the other way, going from a Name to a RoadID
// City
db_query("CREATE TABLE IF NOT EXISTS City("
@@ -573,7 +561,7 @@
" StateID INT4 UNSIGNED NOT NULL,"
" Name CHAR(60) NOT NULL,"
" PRIMARY KEY (ID),"
- " INDEX (StateID)," // for finding all cities by state (needed?)
+ " INDEX (StateID)," // for finding all cities by state (needed?)
" INDEX (Name(15)));" // only index the first X chars of name (who types more than that?) (are city names ever 60 chars anyway?? TIGER think so)
,NULL);
@@ -581,9 +569,9 @@
db_query("CREATE TABLE IF NOT EXISTS State("
// a unique ID for the value
" ID INT4 UNSIGNED NOT NULL AUTO_INCREMENT,"
- " Name CHAR(40) NOT NULL,"
- " Code CHAR(3) NOT NULL," //
- " CountryID INT4 NOT NULL," //
+ " Name CHAR(40) NOT NULL,"
+ " Code CHAR(3) NOT NULL,"
+ " CountryID INT4 NOT NULL,"
" PRIMARY KEY (ID),"
" INDEX (Name(15)));" // only index the first X chars of name (who types more than that?)
,NULL);
@@ -614,7 +602,7 @@
" AttributeNameID INT4 UNSIGNED NOT NULL,"
// the actual value, a text blob
" Value TEXT NOT NULL,"
- " PRIMARY KEY (ID)," // for fast deletes (needed only if POIs can have multiple values per name)
+ " PRIMARY KEY (ID)," // for fast updates/deletes (needed only if POIs can have multiple values per name)
" INDEX (LocationID)," // for searching values for a given POI
" FULLTEXT(Value));", NULL);
@@ -710,99 +698,6 @@
else return 0;
}
-gboolean db_load_geometry(db_connection_t* pConnection, maprect_t* pRect, layer_t* pLayers, gint nNumLayers) //, geometryset_t* pGeometrySet)
-{
- TIMER_BEGIN(mytimer, "BEGIN DB LOAD");
-
-// g_return_val_if_fail(pGeometrySet != NULL, FALSE);
- gint nZoomLevel = map_get_zoomlevel();
-
- if(!db_is_connected(pConnection)) return FALSE;
-
- gchar* pszTable = DB_ROADS_TABLENAME; // use a hardcoded table name for now
-
- // 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 azQuery[MAX_SQLBUFFER_LEN];
- g_snprintf(azQuery, MAX_SQLBUFFER_LEN,
- "SELECT ID, TypeID, AsText(Coordinates) FROM %s WHERE"
- " TypeID IN (%s) AND" //
- " MBRIntersects(GeomFromText('Polygon((%f %f,%f %f,%f %f,%f %f,%f %f))'), Coordinates)",
- pszTable,
- azLayerNumberList,
- (nZoomLevel >= 9) ? 2 : 0,
- 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
- );
- TIMER_SHOW(mytimer, "after SQL generation");
-g_print("sql: %s\n", azQuery);
- mysql_query(pConnection->m_pMySQLConnection, azQuery);
- TIMER_SHOW(mytimer, "after query");
-
- MYSQL_RES* pResultSet = MYSQL_GET_RESULT(pConnection->m_pMySQLConnection);
- guint32 uRowCount = 0;
-
- MYSQL_ROW aRow;
- 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 = mysql_fetch_row(pResultSet))) {
- uRowCount++;
-
- // aRow[0] is ID
- // aRow[1] is TypeID
- // aRow[2] is Coordinates in mysql's text format
- //g_print("data: %s, %s, %s\n", aRow[0], aRow[1], aRow[2]);
-
- 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;
- }
-
- // add it to layer
- geometryset_add_from_mysql_geometry(pLayers[nTypeID].m_pGeometrySet, aRow[2]);
- } // end while loop on rows
- g_print(" -- got %d rows\n", uRowCount);
- TIMER_SHOW(mytimer, "after rows retrieved");
-
- mysql_free_result(pResultSet);
- TIMER_SHOW(mytimer, "after free results");
- TIMER_END(mytimer, "END DB LOAD");
-
- return TRUE;
- }
- else {
- g_print(" no rows\n");
- return FALSE;
- }
-}
-
void db_parse_pointstring(const gchar* pszText, pointstring_t* pPointString, gboolean (*callback_get_point)(mappoint_t**))
{
// parse string and add points to the string
@@ -848,29 +743,5 @@
g_assert_not_reached();
}
}
-
-GMutex* g_pDBMutex = NULL;
-
-void db_lock(void)
-{
- g_mutex_lock(g_pDBMutex);
-}
-
-void db_unlock(void)
-{
- g_mutex_unlock(g_pDBMutex);
-}
-
-void db_begin_thread(void)
-{
- mysql_thread_init();
-}
-
-void db_end_thread(void)
-{
- mysql_thread_end();
-}
-
*/
#endif
-
Index: db.h
===================================================================
RCS file: /cvs/cairo/roadster/src/db.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- db.h 4 Mar 2005 02:27:29 -0000 1.7
+++ db.h 10 Mar 2005 06:12:03 -0000 1.8
@@ -56,7 +56,7 @@
// utility
gboolean db_is_empty(void);
-gboolean db_insert_roadname(gint nRoadID, const gchar* pszName, gint nSuffixID);
+gboolean db_insert_roadname(const gchar* pszName, gint nSuffixID, gint* pnReturnID);
//~ gboolean db_create_points_db(const gchar* name);
@@ -87,7 +87,7 @@
void db_disable_keys(void);
gboolean db_insert_city(const gchar* pszName, gint nStateID, gint* pnReturnCityID);
-gboolean db_insert_road(gint nLayerType,
+gboolean db_insert_road(gint nRoadNameID, gint nLayerType,
gint nAddressLeftStart, gint nAddressLeftEnd,
gint nAddressRightStart, gint nAddressRightEnd,
gint nCityLeftID, gint nCityRightID,
Index: import_tiger.c
===================================================================
RCS file: /cvs/cairo/roadster/src/import_tiger.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- import_tiger.c 1 Mar 2005 19:48:21 -0000 1.11
+++ import_tiger.c 10 Mar 2005 06:12:03 -0000 1.12
@@ -801,8 +801,15 @@
gchar azZIPCodeRight[6];
g_snprintf(azZIPCodeRight, 6, "%05d", pRecordRT1->m_nZIPCodeRight);
+ gint nRoadNameID = 0;
+ if(pRecordRT1->m_achName[0] != '\0') {
+ //printf("inserting road name %s\n", pRecordRT1->m_achName);
+ db_insert_roadname(pRecordRT1->m_achName, pRecordRT1->m_nRoadNameSuffixID, &nRoadNameID);
+ }
+
gint nRoadID;
- db_insert_road(pRecordRT1->m_nRecordType,
+ db_insert_road(nRoadNameID,
+ pRecordRT1->m_nRecordType,
pRecordRT1->m_nAddressLeftStart,
pRecordRT1->m_nAddressLeftEnd,
pRecordRT1->m_nAddressRightStart,
@@ -810,10 +817,6 @@
nCityLeftID, nCityRightID,
azZIPCodeLeft, azZIPCodeRight,
pTempPointsArray, &nRoadID);
- if(pRecordRT1->m_achName[0] != '\0') {
- //printf("inserting road name %s\n", pRecordRT1->m_achName);
- db_insert_roadname(nRoadID, pRecordRT1->m_achName, pRecordRT1->m_nRoadNameSuffixID);
- }
}
g_ptr_array_free(pTempPointsArray, FALSE);
}
@@ -994,17 +997,21 @@
// insert record
if(pRecordRT7->m_nRecordType != LAYER_NONE) {
+ gint nRoadNameID = 0;
+ if(pRecordRT7->m_achName[0] != '\0') {
+ //g_printf("inserting area name %s\n", pRecordRT7->m_achName);
+ db_insert_roadname(pRecordRT7->m_achName, 0, &nRoadNameID);
+ }
+
gint nRoadID;
- db_insert_road(pRecordRT7->m_nRecordType,
+ db_insert_road(
+ nRoadNameID,
+ pRecordRT7->m_nRecordType,
0,0,0,0,
nCityLeftID, nCityRightID,
pszZIPCodeLeft, pszZIPCodeRight,
pTempPointsArray, &nRoadID);
- if(pRecordRT7->m_achName[0] != '\0') {
- //g_printf("inserting area name %s\n", pRecordRT7->m_achName);
- db_insert_roadname(nRoadID, pRecordRT7->m_achName, 0);
- }
}
}
g_ptr_array_free(pTempPointsArray, FALSE);
Index: locationset.c
===================================================================
RCS file: /cvs/cairo/roadster/src/locationset.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- locationset.c 8 Mar 2005 18:40:50 -0000 1.5
+++ locationset.c 10 Mar 2005 06:12:03 -0000 1.6
@@ -226,7 +226,10 @@
location_t* pNewLocation = NULL;
if(location_new(&pNewLocation)) {
pNewLocation->m_nID = nLocationID;
- db_parse_point(aRow[2], &pNewLocation->m_Coordinates);
+
+ g_assert_not_reached();
+ // XXX: need to write this using MySQL WKB format
+ // db_parse_point(aRow[2], &pNewLocation->m_Coordinates);
g_ptr_array_add(pLocationSet->m_pLocationsArray, pNewLocation);
}
}
Index: mainwindow.c
===================================================================
RCS file: /cvs/cairo/roadster/src/mainwindow.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- mainwindow.c 8 Mar 2005 18:40:50 -0000 1.21
+++ mainwindow.c 10 Mar 2005 06:12:03 -0000 1.22
@@ -26,6 +26,7 @@
#endif
#include <gtk/gtk.h>
+#include <gtk/gtksignal.h>
#include "search_road.h"
#include "gui.h"
@@ -55,10 +56,10 @@
#define PROGRAM_COPYRIGHT "Copyright (c) 2005 Ian McIntosh"
#define PROGRAM_DESCRIPTION "Mapping for everyone!"
-#define DRAW_PRETTY_TIMEOUT_MS (110) // how long after stopping various movements should we redraw in high-quality mode
+#define DRAW_PRETTY_TIMEOUT_MS (180) // how long after stopping various movements should we redraw in high-quality mode
#define SCROLL_TIMEOUT_MS (100) // how often (in MS) to move (SHORTER THAN ABOVE TIME)
#define SCROLL_DISTANCE_IN_PIXELS (100) // how far to move every (above) MS
-#define BORDER_SCROLL_CLICK_TARGET_SIZE (17) // the size of the click target (distance from edge of map view) to begin scrolling
+#define BORDER_SCROLL_CLICK_TARGET_SIZE (20) // the size of the click target (distance from edge of map view) to begin scrolling
// Layerlist columns
#define LAYERLIST_COLUMN_ENABLED (0)
@@ -550,23 +551,33 @@
//
void mainwindow_set_zoomlevel(gint nZoomLevel)
{
+ // set zoomlevel scale but prevent it from calling handler (mainwindow_on_zoomscale_value_changed)
+ g_signal_handlers_block_by_func(g_MainWindow.m_pZoomScale, mainwindow_on_zoomscale_value_changed, NULL);
gtk_range_set_value(GTK_RANGE(g_MainWindow.m_pZoomScale), nZoomLevel);
+ g_signal_handlers_unblock_by_func(g_MainWindow.m_pZoomScale, mainwindow_on_zoomscale_value_changed, NULL);
}
static void zoom_in_one(void)
{
+ // tell the map
map_set_zoomlevel(g_MainWindow.m_pMap, map_get_zoomlevel(g_MainWindow.m_pMap) + 1);
+ // tell the GUI
+ mainwindow_set_zoomlevel(map_get_zoomlevel(g_MainWindow.m_pMap));
- gtk_range_set_value(GTK_RANGE(g_MainWindow.m_pZoomScale), map_get_zoomlevel(g_MainWindow.m_pMap));
+ // NOTE: doesn't trigger an actual redraw
}
static void zoom_out_one(void)
{
map_set_zoomlevel(g_MainWindow.m_pMap, map_get_zoomlevel(g_MainWindow.m_pMap) - 1 );
+ mainwindow_set_zoomlevel(map_get_zoomlevel(g_MainWindow.m_pMap));
- gtk_range_set_value(GTK_RANGE(g_MainWindow.m_pZoomScale), map_get_zoomlevel(g_MainWindow.m_pMap));
+ // NOTE: doesn't trigger an actual redraw
}
+//
+//
+//
static void gui_set_tool(EToolType eTool)
{
g_MainWindow.m_eSelectedTool = eTool;
@@ -614,11 +625,13 @@
void mainwindow_on_zoomin_activate(GtkMenuItem *menuitem, gpointer user_data)
{
zoom_in_one();
+ mainwindow_draw_map(DRAWFLAG_ALL);
}
void mainwindow_on_zoomout_activate(GtkMenuItem *menuitem, gpointer user_data)
{
zoom_out_one();
+ mainwindow_draw_map(DRAWFLAG_ALL);
}
void mainwindow_on_fullscreenmenuitem_activate(GtkMenuItem *menuitem, gpointer user_data)
@@ -785,8 +798,6 @@
gint nWidth = GTK_WIDGET(g_MainWindow.m_pDrawingArea)->allocation.width;
gint nHeight = GTK_WIDGET(g_MainWindow.m_pDrawingArea)->allocation.height;
-
- EDirection eScrollDirection = match_border(nX, nY, nWidth, nHeight, BORDER_SCROLL_CLICK_TARGET_SIZE);
if(g_MainWindow.m_bMouseDragging) {
g_MainWindow.m_bMouseDragMovement = TRUE;
@@ -814,6 +825,8 @@
else if(g_MainWindow.m_bScrolling) {
// just set the cursor the window
+ EDirection eScrollDirection = match_border(nX, nY, nWidth, nHeight, BORDER_SCROLL_CLICK_TARGET_SIZE);
+
if(g_MainWindow.m_eScrollDirection != eScrollDirection) {
// update cursor
GdkCursor* pCursor = gdk_cursor_new(g_aDirectionCursors[eScrollDirection].m_nCursor);
@@ -830,6 +843,8 @@
}
}
else {
+ EDirection eScrollDirection = match_border(nX, nY, nWidth, nHeight, BORDER_SCROLL_CLICK_TARGET_SIZE);
+
// just set cursor based on what we're hovering over
GdkCursor* pCursor = gdk_cursor_new(g_aDirectionCursors[eScrollDirection].m_nCursor);
gdk_window_set_cursor(GTK_WIDGET(g_MainWindow.m_pDrawingArea)->window, pCursor);
Index: map.c
===================================================================
RCS file: /cvs/cairo/roadster/src/map.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- map.c 7 Mar 2005 05:30:10 -0000 1.19
+++ map.c 10 Mar 2005 06:12:03 -0000 1.20
@@ -64,8 +64,8 @@
{ 400000, ""}, // 3
{ 200000, ""}, // 4
{ 100000, ""}, // 5
- { 50000, ""}, // 6
- { 25000, ""}, // 7
+ { 40000, ""}, // 6
+ { 20000, ""}, // 7
{ 10000, ""}, // 8
{ 4000, ""}, // 9
@@ -182,6 +182,10 @@
gint nRenderMode = RENDERMODE_FAST;
+ // XXX test
+ GdkRectangle rect = {200,200,100,100};
+ scenemanager_claim_rectangle(pMap->m_pSceneManager, &rect);
+
if(nRenderMode == RENDERMODE_FAST) {
if(nDrawFlags & DRAWFLAG_GEOMETRY) {
map_draw_gdk(pMap, pRenderMetrics, pMap->m_pPixmap, DRAWFLAG_GEOMETRY);
@@ -193,6 +197,11 @@
else { // nRenderMode == RENDERMODE_PRETTY
map_draw_cairo(pMap, pRenderMetrics, pMap->m_pPixmap, nDrawFlags);
}
+
+ // XXX test
+ gdk_draw_rectangle(pMap->m_pPixmap, pMap->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)],
+ FALSE, 200,200, 100, 100);
+
gtk_widget_queue_draw(pMap->m_pTargetWidget);
}
@@ -471,8 +480,8 @@
gchar* pszSQL = g_strdup_printf(
"SELECT Road.ID, Road.TypeID, AsBinary(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)"
+ // " LEFT JOIN Road_RoadName ON (Road.ID=Road_RoadName.RoadID)"
+ " LEFT JOIN RoadName ON (Road.RoadNameID=RoadName.ID)"
" WHERE"
// " TypeID IN (%s) AND"
" MBRIntersects(GeomFromText('Polygon((%f %f,%f %f,%f %f,%f %f,%f %f))'), Coordinates)",
@@ -536,7 +545,7 @@
g_ptr_array_add(
pMap->m_apLayerData[nTypeID]->m_pPointStringsArray, pNewPointString);
} // end while loop on rows
- // g_print("[%d rows]\n", uRowCount);
+ g_print("[%d rows]\n", uRowCount);
TIMER_SHOW(mytimer, "after rows retrieved");
db_free_result(pResultSet);
Index: map_draw_cairo.c
===================================================================
RCS file: /cvs/cairo/roadster/src/map_draw_cairo.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- map_draw_cairo.c 9 Mar 2005 07:32:49 -0000 1.7
+++ map_draw_cairo.c 10 Mar 2005 06:12:03 -0000 1.8
@@ -21,6 +21,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+//#define ENABLE_TIMING
+
#define RENDERING_THREAD_YIELD // do nothing
#define HACK_AROUND_CAIRO_LINE_CAP_BUG // enable to ensure roads have rounded caps if the style dictates
@@ -152,17 +154,160 @@
gdouble m_fScore;
} labelposition_t;
+static void map_draw_cairo_line_label_one_segment(map_t* pMap, cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rendermetrics_t* pRenderMetrics, pointstring_t* pPointString, gdouble fLineWidth, const gchar* pszLabel)
+{
+// gdouble fFontSize = pLabelStyle->m_afFontSizeAtZoomLevel[pRenderMetrics->m_nZoomLevel-1];
+// if(fFontSize == 0) return;
+
+ // get permission to draw this label
+ if(FALSE == scenemanager_can_draw_label_at(pMap->m_pSceneManager, pszLabel, NULL)) {
+ return;
+ }
+
+ mappoint_t* pMapPoint1 = g_ptr_array_index(pPointString->m_pPointsArray, 0);
+ mappoint_t* pMapPoint2 = g_ptr_array_index(pPointString->m_pPointsArray, 1);
+
+ // swap first and second points such that the line goes left-to-right
+ if(pMapPoint2->m_fLongitude < pMapPoint1->m_fLongitude) {
+ mappoint_t* pTmp = pMapPoint1; pMapPoint1 = pMapPoint2; pMapPoint2 = pTmp;
+ }
+
+ gdouble fX1 = SCALE_X(pRenderMetrics, pMapPoint1->m_fLongitude);
+ gdouble fY1 = SCALE_Y(pRenderMetrics, pMapPoint1->m_fLatitude);
+ gdouble fX2 = SCALE_X(pRenderMetrics, pMapPoint2->m_fLongitude);
+ gdouble fY2 = SCALE_Y(pRenderMetrics, pMapPoint2->m_fLatitude);
+
+ // exclude and road that starts or ends outside drawable window (sacrifice a little quality for speed)
+ if(fX1 < 0 || fX2 < 0 || fY1 < 0 || fY2 < 0 || fX1 > pRenderMetrics->m_nWindowWidth || fX2 > pRenderMetrics->m_nWindowWidth || fY1 > pRenderMetrics->m_nWindowHeight || fY2 > pRenderMetrics->m_nWindowHeight) {
+ return;
+ }
+
+ gdouble fRise = fY2 - fY1;
+ gdouble fRun = fX2 - fX1;
+ gdouble fLineLengthSquared = (fRun*fRun) + (fRise*fRise);
+
+ gchar* pszFontFamily = ROAD_FONT;
+
+ cairo_save(pCairo);
+// cairo_select_font(pCairo, pszFontFamily, 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);
+ cairo_font_extents_t font_extents;
+ cairo_current_font_extents(pCairo, &font_extents);
+
+ // text too big for line?
+// if(extents.width > fLineLength) {
+ if((extents.width * extents.width) > fLineLengthSquared) {
+ cairo_restore(pCairo);
+ return;
+ }
+ gdouble fLineLength = sqrt(fLineLengthSquared);
+
+ gdouble fTotalPadding = fLineLength - extents.width;
+
+ // Normalize (make length = 1.0) by dividing by line length
+ // This makes a line with length 1 from the origin (0,0)
+ gdouble fNormalizedX = fRun / fLineLength;
+ gdouble fNormalizedY = fRise / fLineLength;
+
+ // NOTE: ***Swap the X and Y*** and normalize (make length = 1.0) by dividing by line length
+ // This makes a perpendicular line with length 1 from the origin (0,0)
+ gdouble fPerpendicularNormalizedX = fRise / fLineLength;
+ gdouble fPerpendicularNormalizedY = -(fRun / fLineLength);
+
+ // various places to try, in order
+ gdouble afPercentagesOfPadding[] = {0.5, 0.25, 0.75, 0.0, 1.0};
+ gint i;
+ for(i=0 ; i<NUM_ELEMS(afPercentagesOfPadding) ; i++) {
+ // try the next point along the line
+ gdouble fFrontPadding = fTotalPadding * afPercentagesOfPadding[i];
+
+ // align it on the line
+ // (front padding) |-text-| (back padding)
+ gdouble fDrawX = fX1 + (fNormalizedX * fFrontPadding);
+ gdouble fDrawY = fY1 + (fNormalizedY * fFrontPadding);
+
+ // center text vertically by shifting down by half of height
+ fDrawX -= (fPerpendicularNormalizedX * font_extents.ascent/2);
+ fDrawY -= (fPerpendicularNormalizedY * font_extents.ascent/2);
+
+ GdkPoint aBoundingPolygon[4];
+ // 0 is bottom left point
+ aBoundingPolygon[0].x = fDrawX;
+ aBoundingPolygon[0].y = fDrawY;
+ // 1 is upper left point
+ aBoundingPolygon[1].x = fDrawX + (fPerpendicularNormalizedX * font_extents.ascent);
+ aBoundingPolygon[1].y = fDrawY + (fPerpendicularNormalizedY * font_extents.ascent);
+ // 2 is upper right point
+ aBoundingPolygon[2].x = aBoundingPolygon[1].x + (fNormalizedX * extents.width);
+ aBoundingPolygon[2].y = aBoundingPolygon[1].y + (fNormalizedY * extents.width);
+ // 2 is lower right point
+ aBoundingPolygon[3].x = fDrawX + (fNormalizedX * extents.width);
+ aBoundingPolygon[3].y = fDrawY + (fNormalizedY * extents.width);
+
+ if(FALSE == scenemanager_can_draw_polygon(pMap->m_pSceneManager, aBoundingPolygon, 4)) {
+ continue;
+ }
+
+ // do this after the padding calculation to possibly save some CPU cycles
+ gdouble fAngleInRadians = atan(fRise / fRun);
+ if(fRun < 0.0) fAngleInRadians += M_PI;
+
+ cairo_save(pCairo);
+ cairo_move_to(pCairo, fDrawX, fDrawY);
+ cairo_set_rgb_color(pCairo, 0.0,0.0,0.0);
+ cairo_set_alpha(pCairo, 1.0);
+ cairo_rotate(pCairo, fAngleInRadians);
+
+ gdouble fHaloSize = pLabelStyle->m_afHaloAtZoomLevel[pRenderMetrics->m_nZoomLevel-1];
+ if(fHaloSize >= 0) {
+ cairo_save(pCairo);
+ cairo_text_path(pCairo, pszLabel);
+ cairo_set_line_width(pCairo, fHaloSize);
+ cairo_set_rgb_color(pCairo, 1.0,1.0,1.0);
+ cairo_set_line_join(pCairo, CAIRO_LINE_JOIN_BEVEL);
+ //cairo_set_miter_limit(pCairo, 0.1);
+ cairo_stroke(pCairo);
+ cairo_restore(pCairo);
+ }
+ cairo_show_text(pCairo, pszLabel);
+ cairo_restore(pCairo);
+
+ // claim the space this took up and the label (so it won't be drawn twice)
+ scenemanager_claim_label(pMap->m_pSceneManager, pszLabel);
+ scenemanager_claim_polygon(pMap->m_pSceneManager, aBoundingPolygon, 4);
+
+ // success
+ break;
+ }
+ cairo_restore(pCairo);
+}
+
static void map_draw_cairo_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;
- if(pPointString->m_pPointsArray->len > ROAD_MAX_SEGMENTS) {
+ // pass off single segments to a specialized function
+ if(pPointString->m_pPointsArray->len == 2) {
+ map_draw_cairo_line_label_one_segment(pMap, pCairo, pLabelStyle, pRenderMetrics, pPointString, fLineWidth, pszLabel);
+ return;
+ }
+
+ // XXX
+ return;
+
+ if(pPointString->m_pPointsArray->len > ROAD_MAX_SEGMENTS) {
g_warning("not drawing label for road '%s' with > %d segments.\n", pszLabel, ROAD_MAX_SEGMENTS);
return;
}
- gfloat fFontSize = pLabelStyle->m_afFontSizeAtZoomLevel[pRenderMetrics->m_nZoomLevel-1];
- if(fFontSize == 0) return;
+// gdouble fFontSize = pLabelStyle->m_afFontSizeAtZoomLevel[pRenderMetrics->m_nZoomLevel-1];
+// if(fFontSize == 0) return;
if(!scenemanager_can_draw_label_at(pMap->m_pSceneManager, pszLabel, NULL)) {
//g_print("dup label: %s\n", pszLabel);
@@ -172,10 +317,10 @@
gchar* pszFontFamily = ROAD_FONT;
cairo_save(pCairo);
- cairo_select_font(pCairo, pszFontFamily, CAIRO_FONT_SLANT_NORMAL,
- pLabelStyle->m_abBoldAtZoomLevel[pRenderMetrics->m_nZoomLevel-1] ?
- CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL);
- cairo_scale_font(pCairo, fFontSize);
+// cairo_select_font(pCairo, pszFontFamily, 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;
@@ -521,14 +666,28 @@
cairo_text_extents(pCairo, pszLabel, &extents);
// is the text too big for the polygon?
- if((extents.width > (fPolygonWidth * 1.5)) || (extents.height > (fPolygonHeight * 1.5))) {
- cairo_restore(pCairo);
- return;
- }
+// if((extents.width > (fPolygonWidth * 1.5)) || (extents.height > (fPolygonHeight * 1.5))) {
+// cairo_restore(pCairo);
+// return;
+// }
fDrawX -= (extents.width / 2);
fDrawY += (extents.height / 2);
+ // check permission with scenemanager
+ GdkRectangle rcLabelOutline;
+ rcLabelOutline.x = (gint)fDrawX;
+ rcLabelOutline.width = extents.width;
+ rcLabelOutline.y = ((gint)fDrawY) - extents.height;
+ rcLabelOutline.height = extents.height;
+ if(FALSE == scenemanager_can_draw_rectangle(pMap->m_pSceneManager, &rcLabelOutline)) {
+// g_print("not drawing %s (blocked!)\n", pszLabel);
+ cairo_restore(pCairo);
+ return;
+ }
+ // claim it! Now no one else will text draw here.
+ scenemanager_claim_rectangle(pMap->m_pSceneManager, &rcLabelOutline);
+
// g_print("drawing at %f,%f\n", fDrawX, fDrawY);
cairo_move_to(pCairo, fDrawX, fDrawY);
@@ -586,7 +745,7 @@
void map_draw_cairo_layer_points(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pLocationsArray)
{
- gfloat fRadius = map_degrees_to_pixels(pMap, 0.0007, map_get_zoomlevel(pMap));
+ gdouble fRadius = map_degrees_to_pixels(pMap, 0.0007, map_get_zoomlevel(pMap));
gboolean bAddition = FALSE;
cairo_save(pCairo);
@@ -789,6 +948,16 @@
{
gint i;
gdouble fLineWidth = pSubLayerStyle->m_afLineWidths[pRenderMetrics->m_nZoomLevel-1];
+ if(fLineWidth == 0) return;
+
+ gchar* pszFontFamily = ROAD_FONT;
+
+ // set font for whole layer
+ cairo_save(pCairo);
+ cairo_select_font(pCairo, pszFontFamily, CAIRO_FONT_SLANT_NORMAL,
+ pLabelStyle->m_abBoldAtZoomLevel[pRenderMetrics->m_nZoomLevel-1] ?
+ CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_scale_font(pCairo, pLabelStyle->m_afFontSizeAtZoomLevel[pRenderMetrics->m_nZoomLevel-1]);
for(i=0 ; i<pPointStringsArray->len ; i++) {
RENDERING_THREAD_YIELD;
@@ -798,6 +967,7 @@
map_draw_cairo_line_label(pMap, pCairo, pLabelStyle, pRenderMetrics, pPointString, fLineWidth, pPointString->m_pszName);
}
}
+ cairo_restore(pCairo);
}
void map_draw_cairo_layer_polygon_labels(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pPointStringsArray, sublayerstyle_t* pSubLayerStyle, textlabelstyle_t* pLabelStyle)
Index: scenemanager.c
===================================================================
RCS file: /cvs/cairo/roadster/src/scenemanager.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- scenemanager.c 8 Mar 2005 18:40:50 -0000 1.7
+++ scenemanager.c 10 Mar 2005 06:12:03 -0000 1.8
@@ -74,6 +74,18 @@
return bOK;
}
+gboolean scenemanager_can_draw_rectangle(scenemanager_t* pSceneManager, GdkRectangle* pRect)
+{
+ GdkRegion* pNewRegion = gdk_region_rectangle(pRect);
+
+ // Set pNewRegion to the intersection of it and the 'taken region'
+ gdk_region_intersect(pNewRegion, pSceneManager->m_pTakenRegion);
+ gboolean bOK = gdk_region_empty(pNewRegion); // it's ok to draw here if the intersection is empty
+ gdk_region_destroy(pNewRegion);
+
+ return bOK;
+}
+
void scenemanager_claim_label(scenemanager_t* pSceneManager, const gchar* pszLabel)
{
g_assert(pSceneManager != NULL);
Index: scenemanager.h
===================================================================
RCS file: /cvs/cairo/roadster/src/scenemanager.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- scenemanager.h 8 Mar 2005 18:40:50 -0000 1.4
+++ scenemanager.h 10 Mar 2005 06:12:03 -0000 1.5
@@ -35,6 +35,7 @@
gboolean scenemanager_can_draw_label_at(scenemanager_t* pSceneManager, const gchar* pszLabel, GdkPoint* pScreenLocation);
gboolean scenemanager_can_draw_polygon(scenemanager_t* pSceneManager, GdkPoint *pPoints, gint nNumPoints);
+gboolean scenemanager_can_draw_rectangle(scenemanager_t* pSceneManager, GdkRectangle* pRect);
void scenemanager_claim_label(scenemanager_t* pSceneManager, const gchar* pszLabel);
void scenemanager_claim_polygon(scenemanager_t* pSceneManager, GdkPoint *pPoints, gint nNumPoints);
void scenemanager_claim_rectangle(scenemanager_t* pSceneManager, GdkRectangle* pRect);
Index: search_road.c
===================================================================
RCS file: /cvs/cairo/roadster/src/search_road.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- search_road.c 7 Mar 2005 05:30:10 -0000 1.13
+++ search_road.c 10 Mar 2005 06:12:03 -0000 1.14
@@ -276,7 +276,9 @@
gchar* pszZIPClause;
if(pRoadSearch->m_pszZIPCode != NULL) {
- pszZIPClause = g_strdup_printf(" AND (Road.ZIPCodeLeft='%s' OR Road.ZIPCodeRight='%s')", pRoadSearch->m_pszZIPCode, pRoadSearch->m_pszZIPCode);
+ gchar* pszSafeZIP = db_make_escaped_string(pRoadSearch->m_pszZIPCode);
+ pszZIPClause = g_strdup_printf(" AND (Road.ZIPCodeLeft='%s' OR Road.ZIPCodeRight='%s')", pszSafeZIP, pszSafeZIP);
+ db_free_escaped_string(pszSafeZIP);
}
else {
pszZIPClause = g_strdup("");
@@ -323,8 +325,7 @@
"SELECT Road.ID, RoadName.Name, RoadName.SuffixID, AsBinary(Road.Coordinates), Road.AddressLeftStart, Road.AddressLeftEnd, Road.AddressRightStart, Road.AddressRightEnd, CityLeft.Name, CityRight.Name"
", StateLeft.Code, StateRight.Code, Road.ZIPCodeLeft, Road.ZIPCodeRight"
" FROM RoadName"
- " LEFT JOIN Road_RoadName ON (RoadName.ID=Road_RoadName.RoadNameID)"
- " LEFT JOIN Road ON (Road_RoadName.RoadID=Road.ID%s)" // address # clause
+ " LEFT JOIN Road ON (RoadName.ID=Road.RoadNameID%s)" // address # clause
// left side
" LEFT JOIN City AS CityLeft ON (Road.CityLeftID=CityLeft.ID)"
" LEFT JOIN State AS StateLeft ON (CityLeft.StateID=StateLeft.ID)"
More information about the cairo-commit
mailing list