[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