[cairo-commit] roadster/src db.c, 1.7, 1.8 db.h, 1.2, 1.3 import_tiger.c, 1.9, 1.10 search_road.c, 1.7, 1.8

Ian McIntosh commit at pdx.freedesktop.org
Sat Feb 26 01:37:38 PST 2005


Committed by: ian

Update of /cvs/cairo/roadster/src
In directory gabe:/tmp/cvs-serv17679/src

Modified Files:
	db.c db.h import_tiger.c search_road.c 
Log Message:
	* db.c: Added City and State tables and functions to search / add them.
	* import_tiger.c: Extract City, State, and ZIP and save them to DB.  Fix bug in ALL tables where the last row wasn't being imported.
	* search_road.c: Display City, State, and ZIP in results list.


Index: db.c
===================================================================
RCS file: /cvs/cairo/roadster/src/db.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- db.c	26 Feb 2005 04:41:40 -0000	1.7
+++ db.c	26 Feb 2005 09:37:36 -0000	1.8
@@ -23,6 +23,8 @@
 
 #include <mysql.h>
 
+#define HAVE_MYSQL_EMBED
+
 #ifdef HAVE_MYSQL_EMBED
 # include <mysql_embed.h>
 #endif
@@ -299,7 +301,7 @@
 /******************************************************
 ** data inserting
 ******************************************************/
-gboolean db_insert_road(gint nLayerType, gint nAddressLeftStart, gint nAddressLeftEnd, gint nAddressRightStart, gint nAddressRightEnd, GPtrArray* pPointsArray, gint* pReturnID)
+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)
 {
 	g_assert(pReturnID != NULL);
 	if(!db_is_connected()) return FALSE;
@@ -322,11 +324,13 @@
 	gchar azQuery[MAX_SQLBUFFER_LEN];
 	g_snprintf(azQuery, MAX_SQLBUFFER_LEN,
 		"INSERT INTO %s SET TypeID=%d, Coordinates=GeometryFromText('LINESTRING(%s)')"
-		", AddressLeftStart=%d, AddressLeftEnd=%d, AddressRightStart=%d, AddressRightEnd=%d",
-		DB_ROADS_TABLENAME,
-		nLayerType,
-		azCoordinateList,
-		nAddressLeftStart, nAddressLeftEnd, nAddressRightStart, nAddressRightEnd);
+		", AddressLeftStart=%d, AddressLeftEnd=%d, AddressRightStart=%d, AddressRightEnd=%d"
+		", CityLeftID=%d, CityRightID=%d"
+		", ZIPCodeLeft='%s', ZIPCodeRight='%s'",
+		DB_ROADS_TABLENAME, nLayerType, azCoordinateList,
+	    nAddressLeftStart, nAddressLeftEnd, nAddressRightStart, nAddressRightEnd,
+		nCityLeftID, nCityRightID,
+		pszZIPCodeLeft, pszZIPCodeRight);
 
 	if(MYSQL_RESULT_SUCCESS != mysql_query(g_pDB->m_pMySQLConnection, azQuery)) {
 		g_warning("db_insert_road failed: %s (SQL: %s)\n", mysql_error(g_pDB->m_pMySQLConnection), azQuery);
@@ -397,6 +401,120 @@
 	return FALSE;
 }
 
+//
+// insert / select city
+//
+
+// lookup numerical ID of a city by name
+static gboolean db_city_get_id(const gchar* pszName, gint* pnReturnID)
+{
+	gint nReturnID = 0;
+
+	// create SQL for selecting City.ID
+	gchar* pszSafeName = db_make_escaped_string(pszName);
+	gchar* pszSQL = g_strdup_printf("SELECT City.ID FROM City WHERE City.Name='%s';", pszSafeName);
+	db_free_escaped_string(pszSafeName);
+
+	// try query
+	db_resultset_t* pResultSet = NULL;
+	db_row_t aRow;
+	db_query(pszSQL, &pResultSet);
+	g_free(pszSQL);
+	// get result?
+	if(pResultSet) {
+		if((aRow = db_fetch_row(pResultSet)) != NULL) {
+			nReturnID = atoi(aRow[0]);
+		}
+		db_free_result(pResultSet);
+
+		if(nReturnID != 0) {
+			*pnReturnID = nReturnID;
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+gboolean db_insert_city(const gchar* pszName, gint nStateID, gint* pnReturnCityID)
+{
+	gint nCityID = 0;
+
+	// Step 1. Insert into RoadName
+	if(db_city_get_id(pszName, &nCityID) == FALSE) {
+		gchar* pszSafeName = db_make_escaped_string(pszName);
+		gchar* pszSQL = g_strdup_printf("INSERT INTO City SET Name='%s', StateID=%d", pszSafeName, nStateID);
+		db_free_escaped_string(pszSafeName);
+
+		if(db_insert(pszSQL, NULL)) {
+			*pnReturnCityID = db_get_last_insert_id();
+		}
+		g_free(pszSQL);
+	}
+	else {
+		// already exists, use the existing one.
+		*pnReturnCityID = nCityID;
+	}
+	return TRUE;
+}
+
+
+//
+// insert / select state
+//
+// lookup numerical ID of a city by name
+static gboolean db_state_get_id(const gchar* pszName, gint* pnReturnID)
+{
+	gint nReturnID = 0;
+
+	// create SQL for selecting City.ID
+	gchar* pszSafeName = db_make_escaped_string(pszName);
+	gchar* pszSQL = g_strdup_printf("SELECT State.ID FROM State WHERE State.Name='%s';", pszSafeName);
+	db_free_escaped_string(pszSafeName);
+
+	// try query
+	db_resultset_t* pResultSet = NULL;
+	db_row_t aRow;
+	db_query(pszSQL, &pResultSet);
+	g_free(pszSQL);
+	// get result?
+	if(pResultSet) {
+		if((aRow = db_fetch_row(pResultSet)) != NULL) {
+			nReturnID = atoi(aRow[0]);
+		}
+		db_free_result(pResultSet);
+
+		if(nReturnID != 0) {
+			*pnReturnID = nReturnID;
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+gboolean db_insert_state(const gchar* pszName, const gchar* pszCode, gint nCountryID, gint* pnReturnStateID)
+{
+	gint nStateID = 0;
+
+	// Step 1. Insert into RoadName
+	if(db_state_get_id(pszName, &nStateID) == FALSE) {
+		gchar* pszSafeName = db_make_escaped_string(pszName);
+		gchar* pszSafeCode = db_make_escaped_string(pszCode);
+		gchar* pszSQL = g_strdup_printf("INSERT INTO State SET Name='%s', Code='%s', CountryID=%d", pszSafeName, pszSafeCode, nCountryID);
+		db_free_escaped_string(pszSafeName);
+		db_free_escaped_string(pszSafeCode);
+
+		if(db_insert(pszSQL, NULL)) {
+			*pnReturnStateID = db_get_last_insert_id();
+		}
+		g_free(pszSQL);
+	}
+	else {
+		// already exists, use the existing one.
+		*pnReturnStateID = nStateID;
+	}
+	return TRUE;
+}
+
 
 /******************************************************
 ** data loading
@@ -688,6 +806,10 @@
 		" AddressLeftEnd INT2 UNSIGNED NOT NULL,"
 		" AddressRightStart INT2 UNSIGNED NOT NULL,"
 		" AddressRightEnd INT2 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:
@@ -713,6 +835,28 @@
 	    " 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("
+		// a unique ID for the value
+		" ID INT4 UNSIGNED NOT NULL AUTO_INCREMENT,"
+		" StateID INT4 UNSIGNED NOT NULL,"
+		" Name CHAR(60) NOT NULL,"
+		" PRIMARY KEY (ID),"
+		" 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);
+
+	// State
+	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,"		//
+		" PRIMARY KEY (ID),"
+		" INDEX (Name(15)));"	// only index the first X chars of name (who types more than that?)
+	    ,NULL);
+
 	// Location
 	db_query("CREATE TABLE IF NOT EXISTS Location("
 		" ID INT4 UNSIGNED NOT NULL AUTO_INCREMENT,"

Index: db.h
===================================================================
RCS file: /cvs/cairo/roadster/src/db.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- db.h	26 Feb 2005 04:41:40 -0000	1.2
+++ db.h	26 Feb 2005 09:37:36 -0000	1.3
@@ -56,8 +56,6 @@
 // utility
 gboolean db_is_empty(void);
 
-gboolean db_insert_road(gint nLayerType, gint nAddressLeftStart, gint nAddressLeftEnd, gint nAddressRightStart, gint nAddressRightEnd, GPtrArray* pPointsArray, gint* pReturnID);
-
 gboolean db_insert_roadname(gint nRoadID, const gchar* pszName, gint nSuffixID);
 
 //~ gboolean db_create_points_db(const gchar* name);
@@ -84,4 +82,12 @@
 void db_enable_keys(void);
 void db_disable_keys(void);
 
+gboolean db_insert_city(const gchar* pszName, gint nStateID, gint* pnReturnCityID);
+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);
+
 #endif

Index: import_tiger.c
===================================================================
RCS file: /cvs/cairo/roadster/src/import_tiger.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- import_tiger.c	26 Feb 2005 04:41:40 -0000	1.9
+++ import_tiger.c	26 Feb 2005 09:37:36 -0000	1.10
@@ -36,6 +36,7 @@
 #define TIGER_RT2_LINE_LENGTH				(210)
 #define TIGER_RT7_LINE_LENGTH				(76)
 #define TIGER_RT8_LINE_LENGTH				(38)
+#define TIGER_RTc_LINE_LENGTH				(124)
 #define TIGER_RTi_LINE_LENGTH				(129)
 
 #define LINE_LENGTH_MAX						(2000)	// mostly (only?) for the .MET file
@@ -50,6 +51,15 @@
 #define ROWS_PER_PULSE						(18000)		// call import_progress_pulse() after this many rows parsed
 #define CALLBACKS_PER_PULSE					(30)		// call " after this many iterations over hash tables (writing to DB)
 
+typedef struct {
+	gchar* m_pszCode;
+	gchar* m_pszName;
+} state_t;
+
+extern state_t g_aStates[79];
+
+gint g_nStateID = 0;		// this is set during import process
+
 typedef enum {
 	IMPORT_RECORD_OK,
 	IMPORT_RECORD_ERROR,
@@ -67,9 +77,16 @@
 	gint m_nAddressLeftEnd;
 	gint m_nAddressRightStart;
 	gint m_nAddressRightEnd;
+
+	gint m_nZIPCodeLeft;
+	gint m_nZIPCodeRight;
+
 	char m_achName[TIGER_CHAIN_NAME_LEN + 1];
 	gint m_nRoadNameSuffixID;
 
+	gint m_nFIPS55Left;
+	gint m_nFIPS55Right;
+
 	gint m_nCountyIDLeft;	// if left and right are in diff counties, we've found a boundary line!
 	gint m_nCountyIDRight;
 } tiger_record_rt1_t;
@@ -109,14 +126,14 @@
 
 	GHashTable* m_pTableRT1;
 	GHashTable* m_pTableRT2;
-	GHashTable* m_pTableRTi;
 	GHashTable* m_pTableRT7;
 	GHashTable* m_pTableRT8;
+	GHashTable* m_pTableRTi;
+	GHashTable* m_pTableRTc;
 
 	GPtrArray* m_pBoundaryRT1s;
 } tiger_import_process_t;
 
-// indexed by POLYID
 typedef struct tiger_record_rti
 {
 	// store a list of TLIDs for a polygonID
@@ -124,6 +141,17 @@
 	GPtrArray* m_pRT1LinksArray;
 } tiger_record_rti_t;
 
+#define TIGER_CITY_NAME_LEN 	(60)
+#define TIGER_FIPS55_LEN		(5)
+typedef struct tiger_record_rtc
+{
+	// store a list of city names
+	gint m_nFIPS55;	// index
+	char m_achName[TIGER_CITY_NAME_LEN + 1];	// note the +1!!
+	gint m_nCityID;								// a database ID, stored here after it is inserted
+} tiger_record_rtc_t;
+
+
 static gboolean import_tiger_read_lat(gint8* pBuffer, gdouble* pValue)
 {
 	// 0,1,2,3
@@ -432,7 +460,7 @@
 static gboolean import_tiger_parse_table_1(gchar* pBuffer, gint nLength, GHashTable* pTable, GPtrArray* pBoundaryRT1s)
 {
 	gint i;
-	for(i=0 ; i<(nLength-TIGER_RT1_LINE_LENGTH) ; i+=TIGER_RT1_LINE_LENGTH) {
+	for(i=0 ; i<=(nLength-TIGER_RT1_LINE_LENGTH) ; i+=TIGER_RT1_LINE_LENGTH) {
 		if((i%ROWS_PER_PULSE) == 0) importwindow_progress_pulse();
 
 		gchar* pLine = &pBuffer[i];
@@ -450,10 +478,18 @@
 		import_tiger_read_address(&pLine[81-1], 11, &pRecord->m_nAddressRightStart);
 		import_tiger_read_address(&pLine[92-1], 11, &pRecord->m_nAddressRightEnd);
 
+		// columns 107-111 and 112-116 are zip codes
+		import_tiger_read_int(&pLine[107-1], 5, &pRecord->m_nZIPCodeLeft);
+		import_tiger_read_int(&pLine[112-1], 5, &pRecord->m_nZIPCodeRight);
+
 		// columns 6 to 15 is the TLID -
 		import_tiger_read_int(&pLine[6-1], TIGER_TLID_LENGTH, &pRecord->m_nTLID);
 		import_tiger_read_string(&pLine[20-1], TIGER_CHAIN_NAME_LEN, &pRecord->m_achName[0]);
 
+		// columns 141-145 and 146-150 are FIPS55 codes which link this road to a city
+		import_tiger_read_int(&pLine[141-1], TIGER_FIPS55_LEN, &pRecord->m_nFIPS55Left);
+		import_tiger_read_int(&pLine[146-1], TIGER_FIPS55_LEN, &pRecord->m_nFIPS55Right);
+
 		// Read suffix name and convert it to an integer
 		gchar achType[5];
 		import_tiger_read_string(&pLine[50-1], 4, &achType[0]);
@@ -494,7 +530,7 @@
 static gboolean import_tiger_parse_table_2(gint8* pBuffer, gint nLength, GHashTable *pTable)
 {
 	gint i;
-	for(i=0 ; i<(nLength-TIGER_RT2_LINE_LENGTH) ; i+=TIGER_RT2_LINE_LENGTH) {
+	for(i=0 ; i<=(nLength-TIGER_RT2_LINE_LENGTH) ; i+=TIGER_RT2_LINE_LENGTH) {
 		if((i%ROWS_PER_PULSE) == 0) importwindow_progress_pulse();
 
 		gchar* pLine = &pBuffer[i];
@@ -537,7 +573,7 @@
 static gboolean import_tiger_parse_table_7(gint8* pBuffer, gint nLength, GHashTable *pTable)
 {
 	gint i;
-	for(i=0 ; i<(nLength-TIGER_RT7_LINE_LENGTH) ; i+=TIGER_RT7_LINE_LENGTH) {
+	for(i=0 ; i<=(nLength-TIGER_RT7_LINE_LENGTH) ; i+=TIGER_RT7_LINE_LENGTH) {
 		if((i%ROWS_PER_PULSE) == 0) importwindow_progress_pulse();
 
 		gchar* pLine = &pBuffer[i];
@@ -571,7 +607,7 @@
 static gboolean import_tiger_parse_table_8(gint8* pBuffer, gint nLength, GHashTable *pTable)
 {
 	gint i;
-	for(i=0 ; i<(nLength-TIGER_RT8_LINE_LENGTH) ; i+=TIGER_RT8_LINE_LENGTH) {
+	for(i=0 ; i<=(nLength-TIGER_RT8_LINE_LENGTH) ; i+=TIGER_RT8_LINE_LENGTH) {
 		if((i%ROWS_PER_PULSE) == 0) importwindow_progress_pulse();
 
 		gchar* pLine = &pBuffer[i];
@@ -593,6 +629,33 @@
 	return TRUE;
 }
 
+static gboolean import_tiger_parse_table_c(gint8* pBuffer, gint nLength, GHashTable *pTable)
+{
+	gint i;
+	for(i=0 ; i<=(nLength-TIGER_RTc_LINE_LENGTH) ; i+=TIGER_RTc_LINE_LENGTH) {
+		if((i%ROWS_PER_PULSE) == 0) importwindow_progress_pulse();
+
+		gchar* pLine = &pBuffer[i];
+
+		// We only want Entity Type M (??)
+		char chEntityType = pLine[25-1];
+		if(chEntityType != 'M') continue;
+
+		tiger_record_rtc_t* pRecord;
+		pRecord = g_new0(tiger_record_rtc_t, 1);
+
+		// columns 15 to 19 is the FIPS number (links roads to cities)
+		import_tiger_read_int(&pLine[15-1], TIGER_FIPS55_LEN, &pRecord->m_nFIPS55);
+		import_tiger_read_string(&pLine[63-1], TIGER_CITY_NAME_LEN, &pRecord->m_achName[0]);
+		
+g_print("record c: FIPS55=%d NAME=%s\n", pRecord->m_nFIPS55, pRecord->m_achName);
+
+		// add to table
+		g_hash_table_insert(pTable, &pRecord->m_nFIPS55, pRecord);
+	}
+	return TRUE;
+}
+
 
 static gboolean import_tiger_parse_table_i(gint8* pBuffer, gint nLength, GHashTable *pTable)
 {
@@ -600,7 +663,7 @@
 	// Gather RTi records (chainID,TZID-A,TZID-B) and index them by POLYGON ID in the given hash table
 	//
 	gint i;
-	for(i=0 ; i<(nLength-TIGER_RTi_LINE_LENGTH) ; i+=TIGER_RTi_LINE_LENGTH) {
+	for(i=0 ; i<=(nLength-TIGER_RTi_LINE_LENGTH) ; i+=TIGER_RTi_LINE_LENGTH) {
 		gchar* pLine = &pBuffer[i];
 
 		gint nTLID;
@@ -610,24 +673,24 @@
 
 		// 11-20 is the TLID
 		import_tiger_read_int(&pLine[11-1], TIGER_TLID_LENGTH, &nTLID);
+		
 		// 46-55 is left polygon id
 		import_tiger_read_int(&pLine[46-1], TIGER_POLYID_LENGTH, &nLeftPolygonID);
-		// 61-70 is left polygon id
+		// 61-70 is right polygon id
 		import_tiger_read_int(&pLine[61-1], TIGER_POLYID_LENGTH, &nRightPolygonID);
 
-		// zero-cell for start point is 21-30
+		// 21-30 is zero-cell for start point
 		gint nZeroCellA;
 		import_tiger_read_int(&pLine[21-1], TIGER_ZEROCELL_LENGTH, &nZeroCellA);
-
-		// zero-cell for end point is 31-40
+		// 31-40 is zero-cell for end point
 		gint nZeroCellB;
 		import_tiger_read_int(&pLine[31-1], TIGER_ZEROCELL_LENGTH, &nZeroCellB);
 
-		if(nZeroCellA == nZeroCellB) {
-			// we can't link this with anything..?
-			//g_print("nZeroCellA == nZeroCellB\n");
-			continue;
-		}
+//         if(nZeroCellA == nZeroCellB) {
+//             // we can't link this with anything..?
+//             //g_print("nZeroCellA == nZeroCellB\n");
+//             continue;
+//         }
 
 		if(nLeftPolygonID != 0) {
 			// is there an existing RTi for this POLYID?
@@ -702,15 +765,49 @@
 	}
 	g_ptr_array_add(pTempPointsArray, &pRecordRT1->m_PointB);
 
+	// use RT1's FIPS code to lookup related RTc record, which contains a CityID
+	gint nCityLeftID=0;
+	gint nCityRightID=0;
+
+	tiger_record_rtc_t* pRecordRTc;
+
+	// lookup left CityID, if the FIPS is valid
+	if(pRecordRT1->m_nFIPS55Left != 0) {
+		pRecordRTc = g_hash_table_lookup(pImportProcess->m_pTableRTc, &pRecordRT1->m_nFIPS55Left);
+		if(pRecordRTc) {
+			nCityLeftID = pRecordRTc->m_nCityID;
+		}
+		else {
+			g_warning("couldn't lookup CityID by FIPS %d for road %s\n", pRecordRT1->m_nFIPS55Left, pRecordRT1->m_achName);
+		}
+	}
+
+	// lookup right CityID, if the FIPS is valid
+	if(pRecordRT1->m_nFIPS55Right != 0) {
+		pRecordRTc = g_hash_table_lookup(pImportProcess->m_pTableRTc, &pRecordRT1->m_nFIPS55Right);
+		if(pRecordRTc) {
+			nCityRightID = pRecordRTc->m_nCityID;
+		}
+		else {
+			g_warning("couldn't lookup city ID by FIPS %d for road %s\n", pRecordRT1->m_nFIPS55Right, pRecordRT1->m_achName);
+		}
+	}
+
 	// insert, then free temp array
 	if(pRecordRT1->m_nRecordType != LAYER_NONE) {
+		gchar azZIPCodeLeft[6];
+		g_snprintf(azZIPCodeLeft, 6, "%05d", pRecordRT1->m_nZIPCodeLeft);
+		gchar azZIPCodeRight[6];
+		g_snprintf(azZIPCodeRight, 6, "%05d", pRecordRT1->m_nZIPCodeRight);
+
 		gint nRoadID;
-		
 		db_insert_road(pRecordRT1->m_nRecordType,
 			pRecordRT1->m_nAddressLeftStart,
 			pRecordRT1->m_nAddressLeftEnd,
 			pRecordRT1->m_nAddressRightStart,
 			pRecordRT1->m_nAddressRightEnd,
+			nCityLeftID, nCityRightID,
+			azZIPCodeLeft, azZIPCodeRight,
 			pTempPointsArray, &nRoadID);
 		if(pRecordRT1->m_achName[0] != '\0') {
 			//printf("inserting road name %s\n", pRecordRT1->m_achName);
@@ -761,6 +858,18 @@
 	}
 }
 
+static void callback_save_rtc_cities(gpointer key, gpointer value, gpointer user_data)
+{
+	tiger_record_rtc_t* pRecordRTc = (tiger_record_rtc_t*)value;
+	g_assert(pRecordRTc != NULL);
+
+	gint nCityID = 0;
+	if(!db_insert_city(pRecordRTc->m_achName, g_nStateID, &nCityID)) {
+		g_warning("insert city %s failed\n", pRecordRTc->m_achName);
+	}
+	pRecordRTc->m_nCityID = nCityID;
+}
+
 static void callback_save_rti_polygons(gpointer key, gpointer value, gpointer user_data)
 {
 	static int nCallCount=0; nCallCount++;
@@ -876,11 +985,19 @@
 			g_print("Found a polygon that doesn't loop %s\n", pRecordRT7->m_achName);
 		}
 
+		// XXX: looking up a city for a polygon?  unimplemented.
+		gint nCityLeftID = 0;
+		gchar* pszZIPCodeLeft = "";
+		gint nCityRightID = 0;
+		gchar* pszZIPCodeRight = "";
+
 		// insert record
 		if(pRecordRT7->m_nRecordType != LAYER_NONE) {
 			gint nRoadID;
 			db_insert_road(pRecordRT7->m_nRecordType,
 				0,0,0,0,
+				nCityLeftID, nCityRightID,
+				pszZIPCodeLeft, pszZIPCodeRight,
 				pTempPointsArray, &nRoadID);
 
 			if(pRecordRT7->m_achName[0] != '\0') {
@@ -906,7 +1023,7 @@
 //
 //
 static gboolean import_tiger_from_directory(const gchar* pszDirectoryPath, gint nTigerSetNumber);
-static gboolean import_tiger_from_buffers(gint8* pBufferMET, gint nLengthMET, gint8* pBufferRT1, gint nLengthRT1, gint8* pBufferRT2, gint nLengthRT2,	gint8* pBufferRT7, gint nLengthRT7,	gint8* pBufferRT8, gint nLengthRT8, gint8* pBufferRTi, gint nLengthRTi);
+static gboolean import_tiger_from_buffers(gint8* pBufferMET, gint nLengthMET, gint8* pBufferRT1, gint nLengthRT1, gint8* pBufferRT2, gint nLengthRT2,	gint8* pBufferRT7, gint nLengthRT7,	gint8* pBufferRT8, gint nLengthRT8, gint8* pBufferRTc, gint nLengthRTc, gint8* pBufferRTi, gint nLengthRTi);
 
 gboolean import_tiger_from_uri(const gchar* pszURI, gint nTigerSetNumber)
 {
@@ -930,7 +1047,7 @@
 	//
 	// Create unzip command line
 	//
-	gchar* pszCommandLine = g_strdup_printf("unzip -qq -o -j %s -d %s -x *RT4 *RT5 *RT6 *RTA *RTC *RTE *RTH *RTP *RTR *RTT *RTS *RTZ", pszLocalFilePath, pszTempDir);
+	gchar* pszCommandLine = g_strdup_printf("unzip -qq -o -j %s -d %s -x *RT4 *RT5 *RT6 *RTA *RTE *RTH *RTP *RTR *RTT *RTS *RTZ", pszLocalFilePath, pszTempDir);
 	// NOTE: to use other TIGER file types, remove them from the 'exclude' list (-x)
 	// -qq = be very quiet (no output)
 	// -o = overwrite files without prompting
@@ -971,9 +1088,9 @@
 
 	gchar* pszFilePath;
 
-	gchar* apszExtensions[6] = {"MET", "RT1", "RT2", "RT7", "RT8", "RTI"};	
-	gint8* apBuffers[6] = {0};
-	gint nSizes[6] = {0};
+	gchar* apszExtensions[7] = {"MET", "RT1", "RT2", "RT7", "RT8", "RTC", "RTI"};	
+	gint8* apBuffers[NUM_ELEMS(apszExtensions)] = {0};
+	gint nSizes[NUM_ELEMS(apszExtensions)] = {0};
 
 	// open, read, and delete (unlink) each file
 	gint i;
@@ -989,8 +1106,14 @@
 
 	// did we read all files?
 	if(bSuccess) {
-		g_assert(NUM_ELEMS(apszExtensions) == 6);
-		bSuccess = import_tiger_from_buffers(apBuffers[0], nSizes[0], apBuffers[1], nSizes[1], apBuffers[2], nSizes[2], apBuffers[3], nSizes[3], apBuffers[4], nSizes[4], apBuffers[5], nSizes[5]);
+		gint nStateID = (nTigerSetNumber / 1000);	// int division (eg. turn 25017 into 25)
+		if(nStateID < NUM_ELEMS(g_aStates)) {
+			gint nCountryID = 1;	// USA is #1 *gag*
+			db_insert_state(g_aStates[nStateID].m_pszName, g_aStates[nStateID].m_pszCode, nCountryID, &g_nStateID);
+		}
+
+		g_assert(NUM_ELEMS(apszExtensions) == 7);
+		bSuccess = import_tiger_from_buffers(apBuffers[0], nSizes[0], apBuffers[1], nSizes[1], apBuffers[2], nSizes[2], apBuffers[3], nSizes[3], apBuffers[4], nSizes[4], apBuffers[5], nSizes[5], apBuffers[6], nSizes[6]);
 	}
 	for(i=0 ; i<NUM_ELEMS(apszExtensions) ; i++) {
 		g_free(apBuffers[i]); // can be null
@@ -1004,6 +1127,7 @@
 	gint8* pBufferRT2, gint nLengthRT2,
 	gint8* pBufferRT7, gint nLengthRT7,
 	gint8* pBufferRT8, gint nLengthRT8,
+	gint8* pBufferRTc, gint nLengthRTc,
 	gint8* pBufferRTi, gint nLengthRTi)
 {
 	//	g_hash_table_lookup
@@ -1061,6 +1185,11 @@
 	importwindow_log_append(".");
 	importwindow_progress_pulse();
 
+	g_print("parsing RTc\n");
+	importProcess.m_pTableRTc = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
+	import_tiger_parse_table_c(pBufferRTc, nLengthRTc, importProcess.m_pTableRTc);
+	g_print("RTc: %d records\n", g_hash_table_size(importProcess.m_pTableRTc));
+
 	g_print("parsing RTi\n");
 	importProcess.m_pTableRTi = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
 	import_tiger_parse_table_i(pBufferRTi, nLengthRTi, importProcess.m_pTableRTi);
@@ -1069,15 +1198,32 @@
 	importwindow_log_append(".");
 	importwindow_progress_pulse();
 
-	// Now stitch them together
+	//
+	// Insert cities first
+	//
+	g_print("iterating over RTc cities...\n");
+	g_hash_table_foreach(importProcess.m_pTableRTc, callback_save_rtc_cities, &importProcess);
+	g_print("done.\n");
+	
+	importwindow_log_append(".");
+	importwindow_progress_pulse();
+
+	//
+	// Stitch and insert polygons
+	//
 	g_print("iterating over RTi polygons...\n");
 	g_hash_table_foreach(importProcess.m_pTableRTi, callback_save_rti_polygons, &importProcess);
+	g_print("done.\n");
 
 	importwindow_log_append(".");
 	importwindow_progress_pulse();
 
+	//
+	// Roads
+	//
 	g_print("iterating over RT1 chains...\n");
 	g_hash_table_foreach(importProcess.m_pTableRT1, callback_save_rt1_chains, &importProcess);
+	g_print("done.\n");
 	
 	importwindow_log_append(".");
 	importwindow_progress_pulse();
@@ -1089,6 +1235,7 @@
 	g_hash_table_destroy(importProcess.m_pTableRT2);
 	g_hash_table_destroy(importProcess.m_pTableRT7);
 	g_hash_table_destroy(importProcess.m_pTableRT8);
+	g_hash_table_destroy(importProcess.m_pTableRTc);
 	g_hash_table_destroy(importProcess.m_pTableRTi);
 	g_free(importProcess.m_pszFileDescription);
 
@@ -1109,3 +1256,72 @@
 }
 #endif
 
+state_t g_aStates[79] = {
+			{"", 	""},	// NOTE: these are in the proper order to line up with the TIGER data's FIPS code.  don't mess with them. :)
+/* 1 */		{"AL", 	"Alabama"},
+/* 2 */		{"AK", 	"Alaska"},
+/* 3 */		{"", 	""},	// unused
+/* 4 */		{"AZ", 	"Arizona"},
+/* 5 */		{"AR", 	"Arkansas"},
+/* 6 */		{"CA", 	"California"},
+/* 7 */		{"", 	""},
+/* 8 */		{"CO", 	"Colorado"},
+/* 9 */		{"CT", 	"Connecticut"},
+/* 10 */	{"DE", 	"Delaware"},
+/* 11 */	{"DC", 	"District of Columbia"},
+/* 12 */	{"FL", 	"Florida"},
+/* 13 */	{"GA", 	"Georgia"},
+/* 14 */	{"", 	""},
+/* 15 */	{"HI", 	"Hawaii"},
+/* 16 */	{"ID", 	"Idaho"},
+/* 17 */	{"IL", 	"Illinois"},
+/* 18 */	{"IN", 	"Indiana"},
+/* 19 */	{"IA", 	"Iowa"},
+/* 20 */	{"KS", 	"Kansas"},
+/* 21 */	{"KY", 	"Kentucky"},
+/* 22 */	{"LA", 	"Louisiana"},
+/* 23 */	{"ME", 	"Maine"},
+/* 24 */	{"MD", 	"Maryland"},
+/* 25 */	{"MA", 	"Massachusetts"},
+/* 26 */	{"MI", 	"Michigan"},
+/* 27 */	{"MN", 	"Minnesota"},
+/* 28 */	{"MS", 	"Mississippi"},
+/* 29 */	{"MO", 	"Missouri"},
+/* 30 */	{"MT", 	"Montana"},
+/* 31 */	{"NE", 	"Nebraska"},
+/* 32 */	{"NV", 	"Nevade"},
+/* 33 */	{"NH", 	"New Hampshire"},
+/* 34 */	{"NJ", 	"New Jersey"},
+/* 35 */	{"NM", 	"New Mexico"},
+/* 36 */	{"NY", 	"New York"},
+/* 37 */	{"NC", 	"North Carolina"},
+/* 38 */	{"ND", 	"North Dakota"},
+/* 39 */	{"OH", 	"Ohio"},
+/* 40 */	{"OK", 	"Oklahoma"},
+/* 41 */	{"OR", 	"Oregon"},
+/* 42 */	{"PA", 	"Pennsylvania"},
+/* 43 */	{"", 	""},
+/* 44 */	{"RI", 	"Rhode Island"},
+/* 45 */	{"SC", 	"South Carolina"},
+/* 46 */	{"SD", 	"South Dakota"},
+/* 47 */	{"TN", 	"Tennessee"},
+/* 48 */	{"TX", 	"Texas"},
+/* 49 */	{"UT", 	"Utah"},
+/* 50 */	{"VT", 	"Vermont"},
+/* 51 */	{"VA", 	"Virginia"},
+/* 52 */	{"", 	""},
+/* 53 */	{"WA", 	"Washington"},
+/* 54 */	{"WV", 	"West Virginia"},
+/* 55 */	{"WI", 	"Wisconsin"},
+/* 56 */	{"WY", 	"Wyoming"},
+/* 57-59 */	{"", 	""},{"", 	""},{"", 	""},
+/* 60 */	{"AS", 	"American Samoa"},
+/* 61-65 */	{"", 	""},{"", 	""},{"", 	""},{"", 	""},{"", 	""},
+/* 66 */	{"GU", 	"Guam"},
+/* 67-68 */	{"", 	""}, {"", 	""},
+/* 69 */	{"MP", 	"Northern Mariana Islands"},
+/* 70-71 */	{"", 	""},{"", 	""},
+/* 72 */	{"PR", 	"Puerto Rico"},
+/* 73-77 */	{"", 	""},{"", 	""},{"", 	""},{"", 	""},{"", 	""},
+/* 78 */	{"VI", 	"Virgin Islands"},
+};

Index: search_road.c
===================================================================
RCS file: /cvs/cairo/roadster/src/search_road.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- search_road.c	26 Feb 2005 04:41:40 -0000	1.7
+++ search_road.c	26 Feb 2005 09:37:36 -0000	1.8
@@ -64,8 +64,7 @@
 void search_road_on_cleaned_sentence(const gchar* pszCleanedSentence);
 void search_road_on_words(gchar** aWords, gint nWordCount);
 void search_road_on_roadsearch_struct(const roadsearch_t* pRoadSearch);
-void search_road_filter_result(const gchar* pszRoadName, gint nRoadNumber, gint nRoadSuffixID, gint nAddressLeftStart, gint nAddressLeftEnd, gint nAddressRightStart, gint nAddressRightEnd, pointstring_t* pPointString);
-
+void search_road_filter_result(const gchar* pszRoadName, gint nRoadNumber, gint nRoadSuffixID, gint nAddressLeftStart, gint nAddressLeftEnd, gint nAddressRightStart, gint nAddressRightEnd, const gchar* pszCityNameLeft, const gchar* pszCityNameRight, const gchar* pszStateNameLeft, const gchar* pszStateNameRight, const gchar* pszZIPLeft, const gchar* pszZIPRight, pointstring_t* pPointString);
 
 // functions
 
@@ -189,10 +188,17 @@
 	g_print("pRoadSearch->m_pszRoadName = %s, pszSafeRoadName = %s\n", pRoadSearch->m_pszRoadName, pszSafeRoadName);
 
 	g_snprintf(azQuery, MAX_QUERY,
-		"SELECT Road.ID, RoadName.Name, RoadName.SuffixID, AsText(Road.Coordinates), Road.AddressLeftStart, Road.AddressLeftEnd, Road.AddressRightStart, Road.AddressRightEnd"
+		"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"
 		" 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 (Road_RoadName.RoadID=Road.ID %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)"
+		// 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 RoadName.Name='%s'"
 		" AND Road.ID IS NOT NULL"	// don't include rows where the Road didn't match
@@ -219,6 +225,23 @@
 		// get result rows!
 		gint nCount = 0;		
 		while((aRow = mysql_fetch_row(pResultSet))) {
+			// [0] Road.ID
+			// [1] RoadName.Name
+			// [2] RoadName.SuffixID
+			// [3] AsText(Road.Coordinates),
+			// [4] Road.AddressLeftStart,
+			// [5] Road.AddressLeftEnd
+			// [6] Road.AddressRightStart
+			// [7] Road.AddressRightEnd,
+			// [8] CityLeft.Name,
+			// [9] CityRight.Name
+
+			// [10] StateLeft.Name,
+			// [11] StateRight.Name
+
+			// [12] ZIPLeft
+			// [13] ZIPRight
+
 			nCount++;
 			if(nCount <= SEARCH_RESULT_COUNT_LIMIT) {
 				pointstring_t* pPointString = NULL;
@@ -226,7 +249,7 @@
 				db_parse_pointstring(aRow[3], pPointString, point_alloc);
 
 //	g_print("raw: %s\n", aRow[3]);
-				search_road_filter_result(aRow[1], pRoadSearch->m_nNumber, atoi(aRow[2]), atoi(aRow[4]), atoi(aRow[5]), atoi(aRow[6]), atoi(aRow[7]), pPointString);
+				search_road_filter_result(aRow[1], pRoadSearch->m_nNumber, atoi(aRow[2]), atoi(aRow[4]), atoi(aRow[5]), atoi(aRow[6]), atoi(aRow[7]), aRow[8], aRow[9], aRow[10], aRow[11], aRow[12], aRow[13], pPointString);
 //	g_print("%03d: Road.ID='%s' RoadName.Name='%s', Suffix=%s, L:%s-%s, R:%s-%s\n", nCount, aRow[0], aRow[1], aRow[3], aRow[4], aRow[5], aRow[6], aRow[7]);
 				pointstring_free(pPointString);
 			}
@@ -344,17 +367,37 @@
 #endif /* ROADSTER_DEAD_CODE */
 
 #define BUFFER_SIZE 200
-void search_road_filter_result(const gchar* pszRoadName, gint nRoadNumber, gint nRoadSuffixID, gint nAddressLeftStart, gint nAddressLeftEnd, gint nAddressRightStart, gint nAddressRightEnd, pointstring_t* pPointString)
+void search_road_filter_result(
+		const gchar* pszRoadName, gint nRoadNumber, gint nRoadSuffixID,
+		gint nAddressLeftStart, gint nAddressLeftEnd,
+		gint nAddressRightStart, gint nAddressRightEnd,
+		const gchar* pszCityNameLeft, const gchar* pszCityNameRight,
+		const gchar* pszStateNameLeft, const gchar* pszStateNameRight,
+		const gchar* pszZIPLeft, const gchar* pszZIPRight,
+		
+		pointstring_t* pPointString)
 {
 	gint nRoadID = 0;
 	gchar azBuffer[BUFFER_SIZE];
 
 	mappoint_t ptAddress = {0};
-	gchar* pszCity = "City";
-	gchar* pszState = "ST";
-	gchar* pszZIP = "00000";
 
-	gchar* pszCityStateZip = g_strdup_printf("%s, %s, %s", pszCity, pszState, pszZIP);
+//     pszStateNameLeft = "(st)";
+//     pszStateNameRight = "(st)";
+
+	// set City, State, Zip text to be used for each side of the road "City, State, ZIP"
+	gchar* pszCSZLeft = g_strdup_printf("%s%s%s%s%s",
+										(pszCityNameLeft != NULL) ? pszCityNameLeft : "",
+										(pszStateNameLeft != NULL) ? ", " : "",
+										(pszStateNameLeft != NULL) ? pszStateNameLeft : "",
+										(strcmp(pszZIPLeft, "00000") == 0) ? "" : ", ",
+										(strcmp(pszZIPLeft, "00000") == 0) ? "" : pszZIPLeft);
+	gchar* pszCSZRight = g_strdup_printf("%s%s%s%s%s",
+										 (pszCityNameRight != NULL) ? pszCityNameRight : "",
+										 (pszStateNameRight != NULL) ? ", " : "",
+										 (pszStateNameRight != NULL) ? pszStateNameRight : "",
+										 (strcmp(pszZIPRight, "00000") == 0) ? "" : ", ",
+										 (strcmp(pszZIPRight, "00000") == 0) ? "" : pszZIPRight);
 
 	if(nRoadNumber == ROADSEARCH_NUMBER_NONE) {
 		// Right in the center
@@ -365,27 +408,27 @@
 
 		if(nAddressRightStart == 0 && nAddressRightEnd == 0) {
 			// show no numbers if they're both 0
-			g_snprintf(azBuffer, BUFFER_SIZE, "%s %s\n%s", pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_TYPE_LONG), pszCityStateZip);
+			g_snprintf(azBuffer, BUFFER_SIZE, "%s %s\n%s", pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_TYPE_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_TYPE_LONG), pszCityStateZip);
+			g_snprintf(azBuffer, BUFFER_SIZE, "(%d-%d) %s %s\n%s", nAddressRightStart, nAddressRightEnd, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_TYPE_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_TYPE_LONG), pszCityStateZip);
+			g_snprintf(azBuffer, BUFFER_SIZE, "(%d-%d) %s %s\n%s", nAddressRightEnd, nAddressRightStart, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_TYPE_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_TYPE_LONG), pszCityStateZip);
+			g_snprintf(azBuffer, BUFFER_SIZE, "%s %s\n%s", pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_TYPE_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_TYPE_LONG), pszCityStateZip);
+			g_snprintf(azBuffer, BUFFER_SIZE, "(%d-%d) %s %s\n%s", nAddressLeftStart, nAddressLeftEnd, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_TYPE_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_TYPE_LONG), pszCityStateZip);
+			g_snprintf(azBuffer, BUFFER_SIZE, "(%d-%d) %s %s\n%s", nAddressLeftEnd, nAddressLeftStart, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_TYPE_LONG), pszCSZLeft);
 		}
 		searchwindow_add_result(nRoadID, azBuffer, &ptAddress);		
 	}
@@ -411,7 +454,7 @@
 					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_TYPE_LONG), pszCityStateZip);
+				g_snprintf(azBuffer, BUFFER_SIZE, "%d %s %s\n%s", nRoadNumber, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_TYPE_LONG), pszCSZLeft);
 				searchwindow_add_result(nRoadID, azBuffer, &ptAddress);				
 			}
 			else if(nRoadNumber >= nAddressLeftEnd && nRoadNumber <= nAddressLeftStart) {
@@ -427,7 +470,7 @@
 					// 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_TYPE_LONG), pszCityStateZip);
+				g_snprintf(azBuffer, BUFFER_SIZE, "%d %s %s\n%s", nRoadNumber, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_TYPE_LONG), pszCSZLeft);
 				searchwindow_add_result(nRoadID, azBuffer, &ptAddress);
 			}
 		}
@@ -448,7 +491,7 @@
 					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_TYPE_LONG), pszCityStateZip);
+				g_snprintf(azBuffer, BUFFER_SIZE, "%d %s %s\n%s", nRoadNumber, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_TYPE_LONG), pszCSZRight);
 				searchwindow_add_result(nRoadID, azBuffer, &ptAddress);				
 			}
 			else if(nRoadNumber >= nAddressRightEnd && nRoadNumber <= nAddressRightStart) {
@@ -464,10 +507,11 @@
 					// 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_TYPE_LONG), pszCityStateZip);
+				g_snprintf(azBuffer, BUFFER_SIZE, "%d %s %s\n%s", nRoadNumber, pszRoadName, map_road_suffix_itoa(nRoadSuffixID, SUFFIX_TYPE_LONG), pszCSZRight);
 				searchwindow_add_result(nRoadID, azBuffer, &ptAddress);				
 			}
 		}
 	}
-	g_free(pszCityStateZip);
+	g_free(pszCSZLeft);
+	g_free(pszCSZRight);
 }




More information about the cairo-commit mailing list