forked from hans/Nominatim
clean up formatting
This commit is contained in:
@@ -22,16 +22,16 @@ void nominatim_export(int rank_min, int rank_max, const char *conninfo, const ch
|
||||
{
|
||||
xmlTextWriterPtr writer;
|
||||
|
||||
int rankTotalDone;
|
||||
int rankTotalDone;
|
||||
|
||||
PGconn *conn;
|
||||
PGresult * res;
|
||||
PGresult * resSectors;
|
||||
PGresult * resPlaces;
|
||||
PGconn *conn;
|
||||
PGresult * res;
|
||||
PGresult * resSectors;
|
||||
PGresult * resPlaces;
|
||||
|
||||
int rank;
|
||||
int i;
|
||||
int iSector;
|
||||
int rank;
|
||||
int i;
|
||||
int iSector;
|
||||
int tuples;
|
||||
|
||||
const char *paramValues[2];
|
||||
@@ -43,35 +43,36 @@ void nominatim_export(int rank_min, int rank_max, const char *conninfo, const ch
|
||||
|
||||
Oid pg_prepare_params[2];
|
||||
|
||||
conn = PQconnectdb(conninfo);
|
||||
if (PQstatus(conn) != CONNECTION_OK) {
|
||||
conn = PQconnectdb(conninfo);
|
||||
if (PQstatus(conn) != CONNECTION_OK)
|
||||
{
|
||||
fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT4;
|
||||
res = PQprepare(conn, "index_sectors",
|
||||
"select geometry_sector,count(*) from placex where rank_search = $1 and indexed_status = 0 group by geometry_sector order by geometry_sector",
|
||||
1, pg_prepare_params);
|
||||
"select geometry_sector,count(*) from placex where rank_search = $1 and indexed_status = 0 group by geometry_sector order by geometry_sector",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK) exit(EXIT_FAILURE);
|
||||
PQclear(res);
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT4;
|
||||
pg_prepare_params[1] = PG_OID_INT4;
|
||||
res = PQprepare(conn, "index_sector_places",
|
||||
"select place_id from placex where rank_search = $1 and geometry_sector = $2",
|
||||
2, pg_prepare_params);
|
||||
"select place_id from placex where rank_search = $1 and geometry_sector = $2",
|
||||
2, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK) exit(EXIT_FAILURE);
|
||||
PQclear(res);
|
||||
|
||||
nominatim_exportCreatePreparedQueries(conn);
|
||||
|
||||
// Create the output file
|
||||
writer = nominatim_exportXMLStart(structuredoutputfile);
|
||||
// Create the output file
|
||||
writer = nominatim_exportXMLStart(structuredoutputfile);
|
||||
|
||||
for (rank = rank_min; rank <= rank_max; rank++)
|
||||
{
|
||||
printf("Starting rank %d\n", rank);
|
||||
printf("Starting rank %d\n", rank);
|
||||
|
||||
paramRank = PGint32(rank);
|
||||
paramValues[0] = (char *)¶mRank;
|
||||
@@ -84,56 +85,56 @@ void nominatim_export(int rank_min, int rank_max, const char *conninfo, const ch
|
||||
PQclear(resSectors);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (PQftype(resSectors, 0) != PG_OID_INT4)
|
||||
{
|
||||
if (PQftype(resSectors, 0) != PG_OID_INT4)
|
||||
{
|
||||
fprintf(stderr, "Sector value has unexpected type\n");
|
||||
PQclear(resSectors);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (PQftype(resSectors, 1) != PG_OID_INT8)
|
||||
{
|
||||
}
|
||||
if (PQftype(resSectors, 1) != PG_OID_INT8)
|
||||
{
|
||||
fprintf(stderr, "Sector value has unexpected type\n");
|
||||
PQclear(resSectors);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
rankTotalDone = 0;
|
||||
for (iSector = 0; iSector < PQntuples(resSectors); iSector++)
|
||||
{
|
||||
sector = PGint32(*((uint32_t *)PQgetvalue(resSectors, iSector, 0)));
|
||||
rankTotalDone = 0;
|
||||
for (iSector = 0; iSector < PQntuples(resSectors); iSector++)
|
||||
{
|
||||
sector = PGint32(*((uint32_t *)PQgetvalue(resSectors, iSector, 0)));
|
||||
|
||||
// Get all the place_id's for this sector
|
||||
paramRank = PGint32(rank);
|
||||
paramValues[0] = (char *)¶mRank;
|
||||
paramLengths[0] = sizeof(paramRank);
|
||||
paramFormats[0] = 1;
|
||||
paramSector = PGint32(sector);
|
||||
paramValues[1] = (char *)¶mSector;
|
||||
paramLengths[1] = sizeof(paramSector);
|
||||
paramFormats[1] = 1;
|
||||
resPlaces = PQexecPrepared(conn, "index_sector_places", 2, paramValues, paramLengths, paramFormats, 1);
|
||||
if (PQresultStatus(resPlaces) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "index_sector_places: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resPlaces);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (PQftype(resPlaces, 0) != PG_OID_INT4)
|
||||
{
|
||||
fprintf(stderr, "Place_id value has unexpected type\n");
|
||||
PQclear(resPlaces);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// Get all the place_id's for this sector
|
||||
paramRank = PGint32(rank);
|
||||
paramValues[0] = (char *)¶mRank;
|
||||
paramLengths[0] = sizeof(paramRank);
|
||||
paramFormats[0] = 1;
|
||||
paramSector = PGint32(sector);
|
||||
paramValues[1] = (char *)¶mSector;
|
||||
paramLengths[1] = sizeof(paramSector);
|
||||
paramFormats[1] = 1;
|
||||
resPlaces = PQexecPrepared(conn, "index_sector_places", 2, paramValues, paramLengths, paramFormats, 1);
|
||||
if (PQresultStatus(resPlaces) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "index_sector_places: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resPlaces);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (PQftype(resPlaces, 0) != PG_OID_INT4)
|
||||
{
|
||||
fprintf(stderr, "Place_id value has unexpected type\n");
|
||||
PQclear(resPlaces);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
tuples = PQntuples(resPlaces);
|
||||
for(i = 0; i < tuples; i++)
|
||||
{
|
||||
nominatim_exportPlace(PGint32(*((uint32_t *)PQgetvalue(resPlaces, i, 0))), conn, writer, NULL);
|
||||
rankTotalDone++;
|
||||
if (rankTotalDone%1000 == 0) printf("Done %i (k)\n", rankTotalDone/1000);
|
||||
}
|
||||
tuples = PQntuples(resPlaces);
|
||||
for (i = 0; i < tuples; i++)
|
||||
{
|
||||
nominatim_exportPlace(PGint32(*((uint32_t *)PQgetvalue(resPlaces, i, 0))), conn, writer, NULL);
|
||||
rankTotalDone++;
|
||||
if (rankTotalDone%1000 == 0) printf("Done %i (k)\n", rankTotalDone/1000);
|
||||
}
|
||||
PQclear(resPlaces);
|
||||
}
|
||||
}
|
||||
PQclear(resSectors);
|
||||
}
|
||||
|
||||
@@ -145,50 +146,50 @@ void nominatim_export(int rank_min, int rank_max, const char *conninfo, const ch
|
||||
void nominatim_exportCreatePreparedQueries(PGconn * conn)
|
||||
{
|
||||
Oid pg_prepare_params[2];
|
||||
PGresult * res;
|
||||
PGresult * res;
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT8;
|
||||
res = PQprepare(conn, "placex_details",
|
||||
"select osm_type, osm_id, class, type, name, housenumber, country_code, ST_AsText(geometry), admin_level, rank_address, rank_search from placex where place_id = $1",
|
||||
1, pg_prepare_params);
|
||||
"select osm_type, osm_id, class, type, name, housenumber, country_code, ST_AsText(geometry), admin_level, rank_address, rank_search from placex where place_id = $1",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Error preparing placex_details: %s", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
fprintf(stderr, "Error preparing placex_details: %s", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT8;
|
||||
res = PQprepare(conn, "placex_address",
|
||||
"select osm_type,osm_id,class,type,distance,cached_rank_address,isaddress from place_addressline join placex on (address_place_id = placex.place_id) where place_addressline.place_id = $1 and address_place_id != place_addressline.place_id order by cached_rank_address asc",
|
||||
1, pg_prepare_params);
|
||||
"select osm_type,osm_id,class,type,distance,cached_rank_address,isaddress from place_addressline join placex on (address_place_id = placex.place_id) where place_addressline.place_id = $1 and address_place_id != place_addressline.place_id order by cached_rank_address asc",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Error preparing placex_address: %s", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
fprintf(stderr, "Error preparing placex_address: %s", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT8;
|
||||
res = PQprepare(conn, "placex_names",
|
||||
"select (each(name)).key,(each(name)).value from (select name from placex where place_id = $1) as x",
|
||||
1, pg_prepare_params);
|
||||
"select (each(name)).key,(each(name)).value from (select name from placex where place_id = $1) as x",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Error preparing placex_names: %s", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
fprintf(stderr, "Error preparing placex_names: %s", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT8;
|
||||
res = PQprepare(conn, "placex_extratags",
|
||||
"select (each(extratags)).key,(each(extratags)).value from (select extratags from placex where place_id = $1) as x",
|
||||
1, pg_prepare_params);
|
||||
"select (each(extratags)).key,(each(extratags)).value from (select extratags from placex where place_id = $1) as x",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Error preparing placex_extratags: %s", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
fprintf(stderr, "Error preparing placex_extratags: %s", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
@@ -197,36 +198,36 @@ xmlTextWriterPtr nominatim_exportXMLStart(const char *structuredoutputfile)
|
||||
xmlTextWriterPtr writer;
|
||||
|
||||
writer = xmlNewTextWriterFilename(structuredoutputfile, 0);
|
||||
if (writer==NULL)
|
||||
{
|
||||
fprintf(stderr, "Unable to open %s\n", structuredoutputfile);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
xmlTextWriterSetIndent(writer, 1);
|
||||
if (writer==NULL)
|
||||
{
|
||||
fprintf(stderr, "Unable to open %s\n", structuredoutputfile);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
xmlTextWriterSetIndent(writer, 1);
|
||||
if (xmlTextWriterStartDocument(writer, NULL, "UTF8", NULL) < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterStartDocument failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
fprintf(stderr, "xmlTextWriterStartDocument failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (xmlTextWriterStartElement(writer, BAD_CAST "osmStructured") < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterStartElement failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
fprintf(stderr, "xmlTextWriterStartElement failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (xmlTextWriterWriteAttribute(writer, BAD_CAST "version", BAD_CAST "0.1") < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterWriteAttribute failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
fprintf(stderr, "xmlTextWriterWriteAttribute failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (xmlTextWriterWriteAttribute(writer, BAD_CAST "generator", BAD_CAST "Nominatim") < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterWriteAttribute failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
fprintf(stderr, "xmlTextWriterWriteAttribute failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (xmlTextWriterStartElement(writer, BAD_CAST "add") < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterStartElement failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
fprintf(stderr, "xmlTextWriterStartElement failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return writer;
|
||||
@@ -234,22 +235,22 @@ xmlTextWriterPtr nominatim_exportXMLStart(const char *structuredoutputfile)
|
||||
|
||||
void nominatim_exportXMLEnd(xmlTextWriterPtr writer)
|
||||
{
|
||||
// End <add>
|
||||
// End <add>
|
||||
if (xmlTextWriterEndElement(writer) < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterEndElement failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
fprintf(stderr, "xmlTextWriterEndElement failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// End <osmStructured>
|
||||
// End <osmStructured>
|
||||
if (xmlTextWriterEndElement(writer) < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterEndElement failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
fprintf(stderr, "xmlTextWriterEndElement failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (xmlTextWriterEndDocument(writer) < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterEndDocument failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
fprintf(stderr, "xmlTextWriterEndDocument failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
xmlFreeTextWriter(writer);
|
||||
}
|
||||
@@ -259,12 +260,12 @@ void nominatim_exportXMLEnd(xmlTextWriterPtr writer)
|
||||
*/
|
||||
void nominatim_exportPlace(uint64_t place_id, PGconn * conn, xmlTextWriterPtr writer, pthread_mutex_t * writer_mutex)
|
||||
{
|
||||
PGresult * res;
|
||||
PGresult * resNames;
|
||||
PGresult * resAddress;
|
||||
PGresult * resExtraTags;
|
||||
PGresult * res;
|
||||
PGresult * resNames;
|
||||
PGresult * resAddress;
|
||||
PGresult * resExtraTags;
|
||||
|
||||
int i;
|
||||
int i;
|
||||
|
||||
const char * paramValues[1];
|
||||
int paramLengths[1];
|
||||
@@ -272,190 +273,190 @@ void nominatim_exportPlace(uint64_t place_id, PGconn * conn, xmlTextWriterPtr wr
|
||||
uint64_t paramPlaceID;
|
||||
|
||||
|
||||
paramPlaceID = PGint64(place_id);
|
||||
paramPlaceID = PGint64(place_id);
|
||||
paramValues[0] = (char *)¶mPlaceID;
|
||||
paramLengths[0] = sizeof(paramPlaceID);
|
||||
paramFormats[0] = 1;
|
||||
|
||||
res = PQexecPrepared(conn, "placex_details", 1, paramValues, paramLengths, paramFormats, 0);
|
||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "placex_details: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "placex_details: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
resNames = PQexecPrepared(conn, "placex_names", 1, paramValues, paramLengths, paramFormats, 0);
|
||||
if (PQresultStatus(resNames) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "placex_names: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resNames);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
resNames = PQexecPrepared(conn, "placex_names", 1, paramValues, paramLengths, paramFormats, 0);
|
||||
if (PQresultStatus(resNames) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "placex_names: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resNames);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
resAddress = PQexecPrepared(conn, "placex_address", 1, paramValues, paramLengths, paramFormats, 0);
|
||||
if (PQresultStatus(resAddress) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "placex_address: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resAddress);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
resAddress = PQexecPrepared(conn, "placex_address", 1, paramValues, paramLengths, paramFormats, 0);
|
||||
if (PQresultStatus(resAddress) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "placex_address: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resAddress);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
resExtraTags = PQexecPrepared(conn, "placex_extratags", 1, paramValues, paramLengths, paramFormats, 0);
|
||||
if (PQresultStatus(resExtraTags) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "placex_extratags: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resExtraTags);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
resExtraTags = PQexecPrepared(conn, "placex_extratags", 1, paramValues, paramLengths, paramFormats, 0);
|
||||
if (PQresultStatus(resExtraTags) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "placex_extratags: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resExtraTags);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (writer_mutex) pthread_mutex_lock( writer_mutex );
|
||||
if (writer_mutex) pthread_mutex_lock( writer_mutex );
|
||||
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "feature");
|
||||
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "place_id", "%li", place_id);
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST PQgetvalue(res, 0, 0));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "id", BAD_CAST PQgetvalue(res, 0, 1));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "key", BAD_CAST PQgetvalue(res, 0, 2));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "value", BAD_CAST PQgetvalue(res, 0, 3));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "rank", BAD_CAST PQgetvalue(res, 0, 9));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "importance", BAD_CAST PQgetvalue(res, 0, 10));
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "feature");
|
||||
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "place_id", "%li", place_id);
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST PQgetvalue(res, 0, 0));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "id", BAD_CAST PQgetvalue(res, 0, 1));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "key", BAD_CAST PQgetvalue(res, 0, 2));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "value", BAD_CAST PQgetvalue(res, 0, 3));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "rank", BAD_CAST PQgetvalue(res, 0, 9));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "importance", BAD_CAST PQgetvalue(res, 0, 10));
|
||||
|
||||
if (PQntuples(resNames))
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "names");
|
||||
if (PQntuples(resNames))
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "names");
|
||||
|
||||
for(i = 0; i < PQntuples(resNames); i++)
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "name");
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST PQgetvalue(resNames, i, 0));
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(resNames, i, 1));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
for (i = 0; i < PQntuples(resNames); i++)
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "name");
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST PQgetvalue(resNames, i, 0));
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(resNames, i, 1));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
if (PQgetvalue(res, 0, 5) && strlen(PQgetvalue(res, 0, 5)))
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "houseNumber");
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(res, 0, 5));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
if (PQgetvalue(res, 0, 5) && strlen(PQgetvalue(res, 0, 5)))
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "houseNumber");
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(res, 0, 5));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
if (PQgetvalue(res, 0, 8) && strlen(PQgetvalue(res, 0, 8)))
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "adminLevel");
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(res, 0, 8));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
if (PQgetvalue(res, 0, 8) && strlen(PQgetvalue(res, 0, 8)))
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "adminLevel");
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(res, 0, 8));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
if (PQgetvalue(res, 0, 6) && strlen(PQgetvalue(res, 0, 6)))
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "countryCode");
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(res, 0, 6));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
if (PQgetvalue(res, 0, 6) && strlen(PQgetvalue(res, 0, 6)))
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "countryCode");
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(res, 0, 6));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
if (PQntuples(resAddress) > 0)
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "address");
|
||||
for(i = 0; i < PQntuples(resAddress); i++)
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST getRankLabel(atoi(PQgetvalue(resAddress, i, 5))));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "rank", BAD_CAST PQgetvalue(resAddress, i, 5));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST PQgetvalue(resAddress, i, 0));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "id", BAD_CAST PQgetvalue(resAddress, i, 1));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "key", BAD_CAST PQgetvalue(resAddress, i, 2));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "value", BAD_CAST PQgetvalue(resAddress, i, 3));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "distance", BAD_CAST PQgetvalue(resAddress, i, 4));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "isaddress", BAD_CAST PQgetvalue(resAddress, i, 6));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
if (PQntuples(resAddress) > 0)
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "address");
|
||||
for (i = 0; i < PQntuples(resAddress); i++)
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST getRankLabel(atoi(PQgetvalue(resAddress, i, 5))));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "rank", BAD_CAST PQgetvalue(resAddress, i, 5));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST PQgetvalue(resAddress, i, 0));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "id", BAD_CAST PQgetvalue(resAddress, i, 1));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "key", BAD_CAST PQgetvalue(resAddress, i, 2));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "value", BAD_CAST PQgetvalue(resAddress, i, 3));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "distance", BAD_CAST PQgetvalue(resAddress, i, 4));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "isaddress", BAD_CAST PQgetvalue(resAddress, i, 6));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
if (PQntuples(resExtraTags))
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "tags");
|
||||
if (PQntuples(resExtraTags))
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "tags");
|
||||
|
||||
for(i = 0; i < PQntuples(resExtraTags); i++)
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "tag");
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST PQgetvalue(resExtraTags, i, 0));
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(resExtraTags, i, 1));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
for (i = 0; i < PQntuples(resExtraTags); i++)
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "tag");
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST PQgetvalue(resExtraTags, i, 0));
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(resExtraTags, i, 1));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "osmGeometry");
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(res, 0, 7));
|
||||
xmlTextWriterEndElement(writer);
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "osmGeometry");
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(res, 0, 7));
|
||||
xmlTextWriterEndElement(writer);
|
||||
|
||||
xmlTextWriterEndElement(writer); // </feature>
|
||||
xmlTextWriterEndElement(writer); // </feature>
|
||||
|
||||
if (writer_mutex) pthread_mutex_unlock( writer_mutex );
|
||||
if (writer_mutex) pthread_mutex_unlock( writer_mutex );
|
||||
|
||||
PQclear(res);
|
||||
PQclear(resNames);
|
||||
PQclear(resAddress);
|
||||
PQclear(res);
|
||||
PQclear(resNames);
|
||||
PQclear(resAddress);
|
||||
}
|
||||
|
||||
const char * getRankLabel(int rank)
|
||||
{
|
||||
switch(rank)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
return "continent";
|
||||
case 2:
|
||||
case 3:
|
||||
return "sea";
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
return "country";
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
return "state";
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
return "county";
|
||||
case 16:
|
||||
return "city";
|
||||
case 17:
|
||||
return "town";
|
||||
case 18:
|
||||
return "village";
|
||||
case 19:
|
||||
return "unknown";
|
||||
case 20:
|
||||
return "suburb";
|
||||
case 21:
|
||||
return "postcode";
|
||||
case 22:
|
||||
return "neighborhood";
|
||||
case 23:
|
||||
return "postcode";
|
||||
case 24:
|
||||
return "unknown";
|
||||
case 25:
|
||||
return "postcode";
|
||||
case 26:
|
||||
return "street";
|
||||
case 27:
|
||||
return "access";
|
||||
case 28:
|
||||
return "building";
|
||||
case 29:
|
||||
default:
|
||||
return "other";
|
||||
}
|
||||
switch (rank)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
return "continent";
|
||||
case 2:
|
||||
case 3:
|
||||
return "sea";
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
return "country";
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
return "state";
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
return "county";
|
||||
case 16:
|
||||
return "city";
|
||||
case 17:
|
||||
return "town";
|
||||
case 18:
|
||||
return "village";
|
||||
case 19:
|
||||
return "unknown";
|
||||
case 20:
|
||||
return "suburb";
|
||||
case 21:
|
||||
return "postcode";
|
||||
case 22:
|
||||
return "neighborhood";
|
||||
case 23:
|
||||
return "postcode";
|
||||
case 24:
|
||||
return "unknown";
|
||||
case 25:
|
||||
return "postcode";
|
||||
case 26:
|
||||
return "street";
|
||||
case 27:
|
||||
return "access";
|
||||
case 28:
|
||||
return "building";
|
||||
case 29:
|
||||
default:
|
||||
return "other";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,34 +22,37 @@ typedef enum { FILEMODE_NONE, FILEMODE_ADD, FILEMODE_UPDATE, FILEMODE_DELETE } f
|
||||
#define MAX_FEATURENAMESTRING 100000
|
||||
#define MAX_FEATUREEXTRATAGSTRING 50000
|
||||
|
||||
struct feature_address {
|
||||
int place_id;
|
||||
int rankAddress;
|
||||
char isAddress[2];
|
||||
xmlChar * type;
|
||||
xmlChar * id;
|
||||
xmlChar * key;
|
||||
xmlChar * value;
|
||||
xmlChar * distance;
|
||||
struct feature_address
|
||||
{
|
||||
int place_id;
|
||||
int rankAddress;
|
||||
char isAddress[2];
|
||||
xmlChar * type;
|
||||
xmlChar * id;
|
||||
xmlChar * key;
|
||||
xmlChar * value;
|
||||
xmlChar * distance;
|
||||
};
|
||||
|
||||
struct feature_tag {
|
||||
xmlChar * type;
|
||||
xmlChar * value;
|
||||
struct feature_tag
|
||||
{
|
||||
xmlChar * type;
|
||||
xmlChar * value;
|
||||
};
|
||||
|
||||
struct feature {
|
||||
int placeID;
|
||||
xmlChar * type;
|
||||
xmlChar * id;
|
||||
xmlChar * key;
|
||||
xmlChar * value;
|
||||
xmlChar * rankAddress;
|
||||
xmlChar * rankSearch;
|
||||
xmlChar * countryCode;
|
||||
xmlChar * adminLevel;
|
||||
xmlChar * houseNumber;
|
||||
xmlChar * geometry;
|
||||
struct feature
|
||||
{
|
||||
int placeID;
|
||||
xmlChar * type;
|
||||
xmlChar * id;
|
||||
xmlChar * key;
|
||||
xmlChar * value;
|
||||
xmlChar * rankAddress;
|
||||
xmlChar * rankSearch;
|
||||
xmlChar * countryCode;
|
||||
xmlChar * adminLevel;
|
||||
xmlChar * houseNumber;
|
||||
xmlChar * geometry;
|
||||
} feature;
|
||||
|
||||
int fileType = FILETYPE_NONE;
|
||||
@@ -75,23 +78,23 @@ void StartElement(xmlTextReaderPtr reader, const xmlChar *name)
|
||||
|
||||
if (fileType == FILETYPE_NONE)
|
||||
{
|
||||
// Potential to handle other file types in the future / versions
|
||||
// Potential to handle other file types in the future / versions
|
||||
if (xmlStrEqual(name, BAD_CAST "osmStructured"))
|
||||
{
|
||||
value = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "version");
|
||||
version = strtof(value, NULL);
|
||||
xmlFree(value);
|
||||
value = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "version");
|
||||
version = strtof(value, NULL);
|
||||
xmlFree(value);
|
||||
|
||||
if (version == (float)0.1)
|
||||
{
|
||||
fileType = FILETYPE_STRUCTUREDV0P1;
|
||||
fileMode = FILEMODE_ADD;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (version == (float)0.1)
|
||||
{
|
||||
fileType = FILETYPE_STRUCTUREDV0P1;
|
||||
fileMode = FILEMODE_ADD;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "Unknown osmStructured version %f\n", version );
|
||||
exit_nicely();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -103,18 +106,18 @@ void StartElement(xmlTextReaderPtr reader, const xmlChar *name)
|
||||
|
||||
if (xmlStrEqual(name, BAD_CAST "add"))
|
||||
{
|
||||
fileMode = FILEMODE_ADD;
|
||||
return;
|
||||
fileMode = FILEMODE_ADD;
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "update"))
|
||||
{
|
||||
fileMode = FILEMODE_UPDATE;
|
||||
return;
|
||||
fileMode = FILEMODE_UPDATE;
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "delete"))
|
||||
{
|
||||
fileMode = FILEMODE_DELETE;
|
||||
return;
|
||||
fileMode = FILEMODE_DELETE;
|
||||
return;
|
||||
}
|
||||
if (fileMode == FILEMODE_NONE)
|
||||
{
|
||||
@@ -124,72 +127,72 @@ void StartElement(xmlTextReaderPtr reader, const xmlChar *name)
|
||||
|
||||
if (xmlStrEqual(name, BAD_CAST "feature"))
|
||||
{
|
||||
feature.type = xmlTextReaderGetAttribute(reader, BAD_CAST "type");
|
||||
feature.id = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
|
||||
feature.key = xmlTextReaderGetAttribute(reader, BAD_CAST "key");
|
||||
feature.value = xmlTextReaderGetAttribute(reader, BAD_CAST "value");
|
||||
feature.rankAddress = xmlTextReaderGetAttribute(reader, BAD_CAST "rank");
|
||||
feature.rankSearch = xmlTextReaderGetAttribute(reader, BAD_CAST "importance");
|
||||
feature.type = xmlTextReaderGetAttribute(reader, BAD_CAST "type");
|
||||
feature.id = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
|
||||
feature.key = xmlTextReaderGetAttribute(reader, BAD_CAST "key");
|
||||
feature.value = xmlTextReaderGetAttribute(reader, BAD_CAST "value");
|
||||
feature.rankAddress = xmlTextReaderGetAttribute(reader, BAD_CAST "rank");
|
||||
feature.rankSearch = xmlTextReaderGetAttribute(reader, BAD_CAST "importance");
|
||||
|
||||
feature.countryCode = NULL;
|
||||
feature.adminLevel = NULL;
|
||||
feature.houseNumber = NULL;
|
||||
feature.geometry = NULL;
|
||||
featureAddressLines = 0;
|
||||
featureNameLines = 0;
|
||||
feature.countryCode = NULL;
|
||||
feature.adminLevel = NULL;
|
||||
feature.houseNumber = NULL;
|
||||
feature.geometry = NULL;
|
||||
featureAddressLines = 0;
|
||||
featureNameLines = 0;
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "names")) return;
|
||||
if (xmlStrEqual(name, BAD_CAST "name"))
|
||||
{
|
||||
featureName[featureNameLines].type = xmlTextReaderGetAttribute(reader, BAD_CAST "type");
|
||||
featureName[featureNameLines].value = xmlTextReaderReadString(reader);
|
||||
featureNameLines++;
|
||||
if (featureNameLines >= MAX_FEATURENAMES)
|
||||
{
|
||||
featureName[featureNameLines].type = xmlTextReaderGetAttribute(reader, BAD_CAST "type");
|
||||
featureName[featureNameLines].value = xmlTextReaderReadString(reader);
|
||||
featureNameLines++;
|
||||
if (featureNameLines >= MAX_FEATURENAMES)
|
||||
{
|
||||
fprintf( stderr, "Too many name elements\n");
|
||||
exit_nicely();
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "tags")) return;
|
||||
if (xmlStrEqual(name, BAD_CAST "tag"))
|
||||
{
|
||||
featureExtraTag[featureExtraTagLines].type = xmlTextReaderGetAttribute(reader, BAD_CAST "type");
|
||||
featureExtraTag[featureExtraTagLines].value = xmlTextReaderReadString(reader);
|
||||
featureExtraTagLines++;
|
||||
if (featureExtraTagLines >= MAX_FEATUREEXTRATAGS)
|
||||
{
|
||||
featureExtraTag[featureExtraTagLines].type = xmlTextReaderGetAttribute(reader, BAD_CAST "type");
|
||||
featureExtraTag[featureExtraTagLines].value = xmlTextReaderReadString(reader);
|
||||
featureExtraTagLines++;
|
||||
if (featureExtraTagLines >= MAX_FEATUREEXTRATAGS)
|
||||
{
|
||||
fprintf( stderr, "Too many extra tag elements\n");
|
||||
exit_nicely();
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "osmGeometry"))
|
||||
{
|
||||
feature.geometry = xmlTextReaderReadString(reader);
|
||||
return;
|
||||
feature.geometry = xmlTextReaderReadString(reader);
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "adminLevel"))
|
||||
{
|
||||
feature.adminLevel = xmlTextReaderReadString(reader);
|
||||
return;
|
||||
feature.adminLevel = xmlTextReaderReadString(reader);
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "countryCode"))
|
||||
{
|
||||
feature.countryCode = xmlTextReaderReadString(reader);
|
||||
return;
|
||||
feature.countryCode = xmlTextReaderReadString(reader);
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "houseNumber"))
|
||||
{
|
||||
feature.houseNumber = xmlTextReaderReadString(reader);
|
||||
return;
|
||||
feature.houseNumber = xmlTextReaderReadString(reader);
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "address"))
|
||||
{
|
||||
featureAddressLines = 0;
|
||||
return;
|
||||
featureAddressLines = 0;
|
||||
return;
|
||||
}
|
||||
isAddressLine = 0;
|
||||
if (xmlStrEqual(name, BAD_CAST "continent"))
|
||||
@@ -258,66 +261,66 @@ void StartElement(xmlTextReaderPtr reader, const xmlChar *name)
|
||||
}
|
||||
if (isAddressLine)
|
||||
{
|
||||
value = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "rank");
|
||||
if (!value)
|
||||
{
|
||||
value = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "rank");
|
||||
if (!value)
|
||||
{
|
||||
fprintf( stderr, "Address element missing rank\n");
|
||||
exit_nicely();
|
||||
}
|
||||
featureAddress[featureAddressLines].rankAddress = atoi(value);
|
||||
xmlFree(value);
|
||||
}
|
||||
featureAddress[featureAddressLines].rankAddress = atoi(value);
|
||||
xmlFree(value);
|
||||
|
||||
value = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "isaddress");
|
||||
if (!value)
|
||||
{
|
||||
value = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "isaddress");
|
||||
if (!value)
|
||||
{
|
||||
fprintf( stderr, "Address element missing rank\n");
|
||||
exit_nicely();
|
||||
}
|
||||
if (*value == 't') strcpy(featureAddress[featureAddressLines].isAddress, "t");
|
||||
else strcpy(featureAddress[featureAddressLines].isAddress, "f");
|
||||
xmlFree(value);
|
||||
}
|
||||
if (*value == 't') strcpy(featureAddress[featureAddressLines].isAddress, "t");
|
||||
else strcpy(featureAddress[featureAddressLines].isAddress, "f");
|
||||
xmlFree(value);
|
||||
|
||||
featureAddress[featureAddressLines].type = xmlTextReaderGetAttribute(reader, BAD_CAST "type");
|
||||
featureAddress[featureAddressLines].id = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
|
||||
featureAddress[featureAddressLines].key = xmlTextReaderGetAttribute(reader, BAD_CAST "key");
|
||||
featureAddress[featureAddressLines].value = xmlTextReaderGetAttribute(reader, BAD_CAST "value");
|
||||
featureAddress[featureAddressLines].distance = xmlTextReaderGetAttribute(reader, BAD_CAST "distance");
|
||||
featureAddress[featureAddressLines].type = xmlTextReaderGetAttribute(reader, BAD_CAST "type");
|
||||
featureAddress[featureAddressLines].id = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
|
||||
featureAddress[featureAddressLines].key = xmlTextReaderGetAttribute(reader, BAD_CAST "key");
|
||||
featureAddress[featureAddressLines].value = xmlTextReaderGetAttribute(reader, BAD_CAST "value");
|
||||
featureAddress[featureAddressLines].distance = xmlTextReaderGetAttribute(reader, BAD_CAST "distance");
|
||||
|
||||
featureAddressLines++;
|
||||
if (featureAddressLines >= MAX_FEATUREADDRESS)
|
||||
{
|
||||
featureAddressLines++;
|
||||
if (featureAddressLines >= MAX_FEATUREADDRESS)
|
||||
{
|
||||
fprintf( stderr, "Too many address elements\n");
|
||||
exit_nicely();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "%s: Unknown element name: %s\n", __FUNCTION__, name);
|
||||
}
|
||||
|
||||
void EndElement(xmlTextReaderPtr reader, const xmlChar *name)
|
||||
{
|
||||
PGresult * res;
|
||||
PGresult * resPlaceID;
|
||||
PGresult * res;
|
||||
PGresult * resPlaceID;
|
||||
const char * paramValues[11];
|
||||
char * place_id;
|
||||
char * partionQueryName;
|
||||
int i, namePos, lineTypeLen, lineValueLen;
|
||||
int i, namePos, lineTypeLen, lineValueLen;
|
||||
|
||||
if (xmlStrEqual(name, BAD_CAST "feature"))
|
||||
{
|
||||
featureCount++;
|
||||
if (featureCount % 1000 == 0) printf("feature %i(k)\n", featureCount/1000);
|
||||
{
|
||||
featureCount++;
|
||||
if (featureCount % 1000 == 0) printf("feature %i(k)\n", featureCount/1000);
|
||||
|
||||
if (fileMode == FILEMODE_ADD)
|
||||
{
|
||||
resPlaceID = PQexecPrepared(conn, "get_new_place_id", 0, NULL, NULL, NULL, 0);
|
||||
if (PQresultStatus(resPlaceID) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "get_place_id: INSERT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resPlaceID);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
resPlaceID = PQexecPrepared(conn, "get_new_place_id", 0, NULL, NULL, NULL, 0);
|
||||
if (PQresultStatus(resPlaceID) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "get_place_id: INSERT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resPlaceID);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -333,7 +336,7 @@ void EndElement(xmlTextReaderPtr reader, const xmlChar *name)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
place_id = PQgetvalue(resPlaceID, 0, 0);
|
||||
place_id = PQgetvalue(resPlaceID, 0, 0);
|
||||
|
||||
if (fileMode == FILEMODE_UPDATE || fileMode == FILEMODE_DELETE)
|
||||
{
|
||||
@@ -368,195 +371,195 @@ void EndElement(xmlTextReaderPtr reader, const xmlChar *name)
|
||||
|
||||
if (fileMode == FILEMODE_UPDATE || fileMode == FILEMODE_ADD)
|
||||
{
|
||||
// Insert into placex
|
||||
paramValues[0] = (const char *)place_id;
|
||||
paramValues[1] = (const char *)feature.type;
|
||||
paramValues[2] = (const char *)feature.id;
|
||||
paramValues[3] = (const char *)feature.key;
|
||||
paramValues[4] = (const char *)feature.value;
|
||||
// Insert into placex
|
||||
paramValues[0] = (const char *)place_id;
|
||||
paramValues[1] = (const char *)feature.type;
|
||||
paramValues[2] = (const char *)feature.id;
|
||||
paramValues[3] = (const char *)feature.key;
|
||||
paramValues[4] = (const char *)feature.value;
|
||||
|
||||
featureNameString[0] = 0;
|
||||
if (featureNameLines)
|
||||
{
|
||||
namePos = 0;
|
||||
lineTypeLen = 0;
|
||||
lineValueLen = 0;
|
||||
for(i = 0; i < featureNameLines; i++)
|
||||
{
|
||||
lineTypeLen = strlen(BAD_CAST featureName[i].type);
|
||||
lineValueLen = strlen(BAD_CAST featureName[i].value);
|
||||
if (namePos+lineTypeLen+lineValueLen+7 > MAX_FEATURENAMESTRING)
|
||||
{
|
||||
fprintf(stderr, "feature name too long: %s", (const char *)featureName[i].value);
|
||||
break;
|
||||
}
|
||||
if (namePos) strcpy(featureNameString+(namePos++), ",");
|
||||
strcpy(featureNameString+(namePos++), "\"");
|
||||
strcpy(featureNameString+namePos, BAD_CAST featureName[i].type);
|
||||
namePos += lineTypeLen;
|
||||
strcpy(featureNameString+namePos, "\"=>\"");
|
||||
namePos += 4;
|
||||
strcpy(featureNameString+namePos, BAD_CAST featureName[i].value);
|
||||
namePos += lineValueLen;
|
||||
strcpy(featureNameString+(namePos++), "\"");
|
||||
}
|
||||
}
|
||||
paramValues[5] = (const char *)featureNameString;
|
||||
featureNameString[0] = 0;
|
||||
if (featureNameLines)
|
||||
{
|
||||
namePos = 0;
|
||||
lineTypeLen = 0;
|
||||
lineValueLen = 0;
|
||||
for (i = 0; i < featureNameLines; i++)
|
||||
{
|
||||
lineTypeLen = strlen(BAD_CAST featureName[i].type);
|
||||
lineValueLen = strlen(BAD_CAST featureName[i].value);
|
||||
if (namePos+lineTypeLen+lineValueLen+7 > MAX_FEATURENAMESTRING)
|
||||
{
|
||||
fprintf(stderr, "feature name too long: %s", (const char *)featureName[i].value);
|
||||
break;
|
||||
}
|
||||
if (namePos) strcpy(featureNameString+(namePos++), ",");
|
||||
strcpy(featureNameString+(namePos++), "\"");
|
||||
strcpy(featureNameString+namePos, BAD_CAST featureName[i].type);
|
||||
namePos += lineTypeLen;
|
||||
strcpy(featureNameString+namePos, "\"=>\"");
|
||||
namePos += 4;
|
||||
strcpy(featureNameString+namePos, BAD_CAST featureName[i].value);
|
||||
namePos += lineValueLen;
|
||||
strcpy(featureNameString+(namePos++), "\"");
|
||||
}
|
||||
}
|
||||
paramValues[5] = (const char *)featureNameString;
|
||||
|
||||
featureExtraTagString[0] = 0;
|
||||
if (featureExtraTagLines)
|
||||
{
|
||||
namePos = 0;
|
||||
lineTypeLen = 0;
|
||||
lineValueLen = 0;
|
||||
for(i = 0; i < featureExtraTagLines; i++)
|
||||
{
|
||||
lineTypeLen = strlen(BAD_CAST featureExtraTag[i].type);
|
||||
lineValueLen = strlen(BAD_CAST featureExtraTag[i].value);
|
||||
if (namePos+lineTypeLen+lineValueLen+7 > MAX_FEATUREEXTRATAGSTRING)
|
||||
{
|
||||
fprintf(stderr, "feature extra tag too long: %s", (const char *)featureExtraTag[i].value);
|
||||
break;
|
||||
}
|
||||
if (namePos) strcpy(featureExtraTagString+(namePos++),",");
|
||||
strcpy(featureExtraTagString+(namePos++), "\"");
|
||||
strcpy(featureExtraTagString+namePos, BAD_CAST featureExtraTag[i].type);
|
||||
namePos += lineTypeLen;
|
||||
strcpy(featureExtraTagString+namePos, "\"=>\"");
|
||||
namePos += 4;
|
||||
strcpy(featureExtraTagString+namePos, BAD_CAST featureExtraTag[i].value);
|
||||
namePos += lineValueLen;
|
||||
strcpy(featureExtraTagString+(namePos++), "\"");
|
||||
}
|
||||
}
|
||||
paramValues[6] = (const char *)featureExtraTagString;
|
||||
featureExtraTagString[0] = 0;
|
||||
if (featureExtraTagLines)
|
||||
{
|
||||
namePos = 0;
|
||||
lineTypeLen = 0;
|
||||
lineValueLen = 0;
|
||||
for (i = 0; i < featureExtraTagLines; i++)
|
||||
{
|
||||
lineTypeLen = strlen(BAD_CAST featureExtraTag[i].type);
|
||||
lineValueLen = strlen(BAD_CAST featureExtraTag[i].value);
|
||||
if (namePos+lineTypeLen+lineValueLen+7 > MAX_FEATUREEXTRATAGSTRING)
|
||||
{
|
||||
fprintf(stderr, "feature extra tag too long: %s", (const char *)featureExtraTag[i].value);
|
||||
break;
|
||||
}
|
||||
if (namePos) strcpy(featureExtraTagString+(namePos++),",");
|
||||
strcpy(featureExtraTagString+(namePos++), "\"");
|
||||
strcpy(featureExtraTagString+namePos, BAD_CAST featureExtraTag[i].type);
|
||||
namePos += lineTypeLen;
|
||||
strcpy(featureExtraTagString+namePos, "\"=>\"");
|
||||
namePos += 4;
|
||||
strcpy(featureExtraTagString+namePos, BAD_CAST featureExtraTag[i].value);
|
||||
namePos += lineValueLen;
|
||||
strcpy(featureExtraTagString+(namePos++), "\"");
|
||||
}
|
||||
}
|
||||
paramValues[6] = (const char *)featureExtraTagString;
|
||||
|
||||
paramValues[7] = (const char *)feature.adminLevel;
|
||||
paramValues[8] = (const char *)feature.houseNumber;
|
||||
paramValues[9] = (const char *)feature.rankAddress;
|
||||
paramValues[10] = (const char *)feature.rankSearch;
|
||||
paramValues[11] = (const char *)feature.geometry;
|
||||
res = PQexecPrepared(conn, "placex_insert", 12, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "index_placex: INSERT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
paramValues[7] = (const char *)feature.adminLevel;
|
||||
paramValues[8] = (const char *)feature.houseNumber;
|
||||
paramValues[9] = (const char *)feature.rankAddress;
|
||||
paramValues[10] = (const char *)feature.rankSearch;
|
||||
paramValues[11] = (const char *)feature.geometry;
|
||||
res = PQexecPrepared(conn, "placex_insert", 12, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "index_placex: INSERT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
for(i = 0; i < featureAddressLines; i++)
|
||||
{
|
||||
// insert into place_address
|
||||
paramValues[0] = (const char *)place_id;
|
||||
paramValues[1] = (const char *)featureAddress[i].distance;
|
||||
paramValues[2] = (const char *)featureAddress[i].type;
|
||||
paramValues[3] = (const char *)featureAddress[i].id;
|
||||
paramValues[4] = (const char *)featureAddress[i].key;
|
||||
paramValues[5] = (const char *)featureAddress[i].value;
|
||||
paramValues[6] = (const char *)featureAddress[i].isAddress;
|
||||
res = PQexecPrepared(conn, "place_addressline_insert", 7, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "place_addressline_insert: INSERT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
for (i = 0; i < featureAddressLines; i++)
|
||||
{
|
||||
// insert into place_address
|
||||
paramValues[0] = (const char *)place_id;
|
||||
paramValues[1] = (const char *)featureAddress[i].distance;
|
||||
paramValues[2] = (const char *)featureAddress[i].type;
|
||||
paramValues[3] = (const char *)featureAddress[i].id;
|
||||
paramValues[4] = (const char *)featureAddress[i].key;
|
||||
paramValues[5] = (const char *)featureAddress[i].value;
|
||||
paramValues[6] = (const char *)featureAddress[i].isAddress;
|
||||
res = PQexecPrepared(conn, "place_addressline_insert", 7, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "place_addressline_insert: INSERT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
xmlFree(featureAddress[i].type);
|
||||
xmlFree(featureAddress[i].id);
|
||||
xmlFree(featureAddress[i].key);
|
||||
xmlFree(featureAddress[i].value);
|
||||
xmlFree(featureAddress[i].distance);
|
||||
}
|
||||
xmlFree(featureAddress[i].type);
|
||||
xmlFree(featureAddress[i].id);
|
||||
xmlFree(featureAddress[i].key);
|
||||
xmlFree(featureAddress[i].value);
|
||||
xmlFree(featureAddress[i].distance);
|
||||
}
|
||||
|
||||
if (featureNameLines)
|
||||
{
|
||||
paramValues[0] = (const char *)place_id;
|
||||
res = PQexecPrepared(conn, "search_name_insert", 1, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "search_name_insert: INSERT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
}
|
||||
if (featureNameLines)
|
||||
{
|
||||
paramValues[0] = (const char *)place_id;
|
||||
res = PQexecPrepared(conn, "search_name_insert", 1, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "search_name_insert: INSERT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
partionQueryName = xmlHashLookup2(partionTableTagsHash, feature.key, feature.value);
|
||||
if (partionQueryName)
|
||||
{
|
||||
// insert into partition table
|
||||
paramValues[0] = (const char *)place_id;
|
||||
paramValues[1] = (const char *)feature.geometry;
|
||||
res = PQexecPrepared(conn, partionQueryName, 2, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "%s: INSERT failed: %s", partionQueryName, PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
partionQueryName = xmlHashLookup2(partionTableTagsHash, feature.key, feature.value);
|
||||
if (partionQueryName)
|
||||
{
|
||||
// insert into partition table
|
||||
paramValues[0] = (const char *)place_id;
|
||||
paramValues[1] = (const char *)feature.geometry;
|
||||
res = PQexecPrepared(conn, partionQueryName, 2, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "%s: INSERT failed: %s", partionQueryName, PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0; i < featureAddressLines; i++)
|
||||
{
|
||||
xmlFree(featureAddress[i].type);
|
||||
xmlFree(featureAddress[i].id);
|
||||
xmlFree(featureAddress[i].key);
|
||||
xmlFree(featureAddress[i].value);
|
||||
xmlFree(featureAddress[i].distance);
|
||||
}
|
||||
for (i = 0; i < featureAddressLines; i++)
|
||||
{
|
||||
xmlFree(featureAddress[i].type);
|
||||
xmlFree(featureAddress[i].id);
|
||||
xmlFree(featureAddress[i].key);
|
||||
xmlFree(featureAddress[i].value);
|
||||
xmlFree(featureAddress[i].distance);
|
||||
}
|
||||
}
|
||||
|
||||
xmlFree(feature.type);
|
||||
xmlFree(feature.id);
|
||||
xmlFree(feature.key);
|
||||
xmlFree(feature.value);
|
||||
xmlFree(feature.rankAddress);
|
||||
xmlFree(feature.rankSearch);
|
||||
xmlFree(feature.type);
|
||||
xmlFree(feature.id);
|
||||
xmlFree(feature.key);
|
||||
xmlFree(feature.value);
|
||||
xmlFree(feature.rankAddress);
|
||||
xmlFree(feature.rankSearch);
|
||||
// if (feature.name) xmlFree(feature.name);
|
||||
if (feature.countryCode) xmlFree(feature.countryCode);
|
||||
if (feature.adminLevel) xmlFree(feature.adminLevel);
|
||||
if (feature.houseNumber) xmlFree(feature.houseNumber);
|
||||
if (feature.geometry) xmlFree(feature.geometry);
|
||||
if (feature.countryCode) xmlFree(feature.countryCode);
|
||||
if (feature.adminLevel) xmlFree(feature.adminLevel);
|
||||
if (feature.houseNumber) xmlFree(feature.houseNumber);
|
||||
if (feature.geometry) xmlFree(feature.geometry);
|
||||
|
||||
PQclear(resPlaceID);
|
||||
}
|
||||
PQclear(resPlaceID);
|
||||
}
|
||||
}
|
||||
|
||||
static void processNode(xmlTextReaderPtr reader)
|
||||
{
|
||||
xmlChar *name;
|
||||
xmlChar *name;
|
||||
name = xmlTextReaderName(reader);
|
||||
if (name == NULL)
|
||||
{
|
||||
name = xmlStrdup(BAD_CAST "--");
|
||||
}
|
||||
|
||||
switch(xmlTextReaderNodeType(reader))
|
||||
switch (xmlTextReaderNodeType(reader))
|
||||
{
|
||||
case XML_READER_TYPE_ELEMENT:
|
||||
StartElement(reader, name);
|
||||
if (xmlTextReaderIsEmptyElement(reader))
|
||||
EndElement(reader, name); /* No end_element for self closing tags! */
|
||||
break;
|
||||
case XML_READER_TYPE_END_ELEMENT:
|
||||
EndElement(reader, name);
|
||||
break;
|
||||
case XML_READER_TYPE_TEXT:
|
||||
case XML_READER_TYPE_CDATA:
|
||||
case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
|
||||
/* Ignore */
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown node type %d\n", xmlTextReaderNodeType(reader));
|
||||
break;
|
||||
case XML_READER_TYPE_ELEMENT:
|
||||
StartElement(reader, name);
|
||||
if (xmlTextReaderIsEmptyElement(reader))
|
||||
EndElement(reader, name); /* No end_element for self closing tags! */
|
||||
break;
|
||||
case XML_READER_TYPE_END_ELEMENT:
|
||||
EndElement(reader, name);
|
||||
break;
|
||||
case XML_READER_TYPE_TEXT:
|
||||
case XML_READER_TYPE_CDATA:
|
||||
case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
|
||||
/* Ignore */
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown node type %d\n", xmlTextReaderNodeType(reader));
|
||||
break;
|
||||
}
|
||||
|
||||
xmlFree(name);
|
||||
@@ -566,139 +569,139 @@ int nominatim_import(const char *conninfo, const char *partionTagsFilename, cons
|
||||
{
|
||||
xmlTextReaderPtr reader;
|
||||
int ret = 0;
|
||||
PGresult * res;
|
||||
FILE * partionTagsFile;
|
||||
char * partionQueryName;
|
||||
PGresult * res;
|
||||
FILE * partionTagsFile;
|
||||
char * partionQueryName;
|
||||
char partionQuerySQL[1024];
|
||||
|
||||
conn = PQconnectdb(conninfo);
|
||||
conn = PQconnectdb(conninfo);
|
||||
if (PQstatus(conn) != CONNECTION_OK)
|
||||
{
|
||||
fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
partionTableTagsHash = xmlHashCreate(200);
|
||||
partionTableTagsHash = xmlHashCreate(200);
|
||||
|
||||
partionTagsFile = fopen(partionTagsFilename, "rt");
|
||||
if (!partionTagsFile)
|
||||
partionTagsFile = fopen(partionTagsFilename, "rt");
|
||||
if (!partionTagsFile)
|
||||
{
|
||||
fprintf(stderr, "Unable to read partition tags file: %s\n", partionTagsFilename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
char buffer[1024], osmkey[256], osmvalue[256];
|
||||
int fields;
|
||||
while(fgets(buffer, sizeof(buffer), partionTagsFile) != NULL)
|
||||
{
|
||||
fields = sscanf( buffer, "%23s %63s", osmkey, osmvalue );
|
||||
char buffer[1024], osmkey[256], osmvalue[256];
|
||||
int fields;
|
||||
while (fgets(buffer, sizeof(buffer), partionTagsFile) != NULL)
|
||||
{
|
||||
fields = sscanf( buffer, "%23s %63s", osmkey, osmvalue );
|
||||
|
||||
if( fields <= 0 ) continue;
|
||||
if ( fields <= 0 ) continue;
|
||||
|
||||
if( fields != 2 )
|
||||
{
|
||||
fprintf( stderr, "Error partition file\n");
|
||||
exit_nicely();
|
||||
}
|
||||
partionQueryName = malloc(strlen("partition_insert_")+strlen(osmkey)+strlen(osmvalue)+2);
|
||||
strcpy(partionQueryName, "partition_insert_");
|
||||
strcat(partionQueryName, osmkey);
|
||||
strcat(partionQueryName, "_");
|
||||
strcat(partionQueryName, osmvalue);
|
||||
if ( fields != 2 )
|
||||
{
|
||||
fprintf( stderr, "Error partition file\n");
|
||||
exit_nicely();
|
||||
}
|
||||
partionQueryName = malloc(strlen("partition_insert_")+strlen(osmkey)+strlen(osmvalue)+2);
|
||||
strcpy(partionQueryName, "partition_insert_");
|
||||
strcat(partionQueryName, osmkey);
|
||||
strcat(partionQueryName, "_");
|
||||
strcat(partionQueryName, osmvalue);
|
||||
|
||||
strcpy(partionQuerySQL, "insert into place_classtype_");
|
||||
strcat(partionQuerySQL, osmkey);
|
||||
strcat(partionQuerySQL, "_");
|
||||
strcat(partionQuerySQL, osmvalue);
|
||||
strcat(partionQuerySQL, " (place_id, centroid) values ($1, ST_Centroid(st_setsrid($2, 4326)))");
|
||||
strcpy(partionQuerySQL, "insert into place_classtype_");
|
||||
strcat(partionQuerySQL, osmkey);
|
||||
strcat(partionQuerySQL, "_");
|
||||
strcat(partionQuerySQL, osmvalue);
|
||||
strcat(partionQuerySQL, " (place_id, centroid) values ($1, ST_Centroid(st_setsrid($2, 4326)))");
|
||||
|
||||
res = PQprepare(conn, partionQueryName, partionQuerySQL, 2, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare %s: %s\n", partionQueryName, PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
res = PQprepare(conn, partionQueryName, partionQuerySQL, 2, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare %s: %s\n", partionQueryName, PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
xmlHashAddEntry2(partionTableTagsHash, BAD_CAST osmkey, BAD_CAST osmvalue, BAD_CAST partionQueryName);
|
||||
}
|
||||
xmlHashAddEntry2(partionTableTagsHash, BAD_CAST osmkey, BAD_CAST osmvalue, BAD_CAST partionQueryName);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "get_new_place_id",
|
||||
"select nextval('seq_place')",
|
||||
0, NULL);
|
||||
"select nextval('seq_place')",
|
||||
0, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare get_new_place_id: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "get_place_id",
|
||||
"select place_id from placex where osm_type = $1 and osm_id = $2 and class = $3 and type = $4",
|
||||
4, NULL);
|
||||
"select place_id from placex where osm_type = $1 and osm_id = $2 and class = $3 and type = $4",
|
||||
4, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare get_place_id: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "placex_insert",
|
||||
"insert into placex (place_id,osm_type,osm_id,class,type,name,extratags,admin_level,housenumber,rank_address,rank_search,geometry) "
|
||||
"values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, st_setsrid($12, 4326))",
|
||||
12, NULL);
|
||||
"insert into placex (place_id,osm_type,osm_id,class,type,name,extratags,admin_level,housenumber,rank_address,rank_search,geometry) "
|
||||
"values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, st_setsrid($12, 4326))",
|
||||
12, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare placex_insert: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "search_name_insert",
|
||||
"insert into search_name (place_id, search_rank, address_rank, country_code, name_vector, nameaddress_vector, centroid) "
|
||||
"select place_id, rank_address, rank_search, country_code, make_keywords(name), "
|
||||
"(select uniq(sort(array_agg(name_vector))) from place_addressline join search_name on "
|
||||
"(address_place_id = search_name.place_id) where place_addressline.place_id = $1 ), st_centroid(geometry) from placex "
|
||||
"where place_id = $1",
|
||||
1, NULL);
|
||||
"insert into search_name (place_id, search_rank, address_rank, country_code, name_vector, nameaddress_vector, centroid) "
|
||||
"select place_id, rank_address, rank_search, country_code, make_keywords(name), "
|
||||
"(select uniq(sort(array_agg(name_vector))) from place_addressline join search_name on "
|
||||
"(address_place_id = search_name.place_id) where place_addressline.place_id = $1 ), st_centroid(geometry) from placex "
|
||||
"where place_id = $1",
|
||||
1, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare search_name_insert: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "place_addressline_insert",
|
||||
"insert into place_addressline (place_id, address_place_id, fromarea, isaddress, distance, cached_rank_address) "
|
||||
"select $1, place_id, false, $7, $2, rank_address from placex where osm_type = $3 and osm_id = $4 and class = $5 and type = $6",
|
||||
7, NULL);
|
||||
"insert into place_addressline (place_id, address_place_id, fromarea, isaddress, distance, cached_rank_address) "
|
||||
"select $1, place_id, false, $7, $2, rank_address from placex where osm_type = $3 and osm_id = $4 and class = $5 and type = $6",
|
||||
7, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare place_addressline_insert: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "placex_delete",
|
||||
"delete from placex where place_id = $1",
|
||||
1, NULL);
|
||||
"delete from placex where place_id = $1",
|
||||
1, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare placex_delete: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "search_name_delete",
|
||||
"delete from search_name where place_id = $1",
|
||||
1, NULL);
|
||||
"delete from search_name where place_id = $1",
|
||||
1, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare search_name_delete: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "place_addressline_delete",
|
||||
"delete from place_addressline where place_id = $1",
|
||||
1, NULL);
|
||||
"delete from place_addressline where place_id = $1",
|
||||
1, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare place_addressline_delete: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
featureCount = 0;
|
||||
|
||||
@@ -713,16 +716,17 @@ int nominatim_import(const char *conninfo, const char *partionTagsFilename, cons
|
||||
ret = xmlTextReaderRead(reader);
|
||||
while (ret == 1)
|
||||
{
|
||||
processNode(reader);
|
||||
ret = xmlTextReaderRead(reader);
|
||||
processNode(reader);
|
||||
ret = xmlTextReaderRead(reader);
|
||||
}
|
||||
if (ret != 0)
|
||||
{
|
||||
fprintf(stderr, "%s : failed to parse\n", filename);
|
||||
return ret;
|
||||
}
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "%s : failed to parse\n", filename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmlFreeTextReader(reader);
|
||||
xmlHashFree(partionTableTagsHash, NULL);
|
||||
xmlFreeTextReader(reader);
|
||||
xmlHashFree(partionTableTagsHash, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -21,25 +21,25 @@ extern int verbose;
|
||||
|
||||
void nominatim_index(int rank_min, int rank_max, int num_threads, const char *conninfo, const char *structuredoutputfile)
|
||||
{
|
||||
struct index_thread_data * thread_data;
|
||||
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
int tuples, count, sleepcount;
|
||||
struct index_thread_data * thread_data;
|
||||
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
int tuples, count, sleepcount;
|
||||
|
||||
time_t rankStartTime;
|
||||
int rankTotalTuples;
|
||||
int rankCountTuples;
|
||||
float rankPerSecond;
|
||||
time_t rankStartTime;
|
||||
int rankTotalTuples;
|
||||
int rankCountTuples;
|
||||
float rankPerSecond;
|
||||
|
||||
PGconn *conn;
|
||||
PGresult * res;
|
||||
PGresult * resSectors;
|
||||
PGresult * resPlaces;
|
||||
PGresult * resNULL;
|
||||
PGconn *conn;
|
||||
PGresult * res;
|
||||
PGresult * resSectors;
|
||||
PGresult * resPlaces;
|
||||
PGresult * resNULL;
|
||||
|
||||
int rank;
|
||||
int i;
|
||||
int iSector;
|
||||
int iResult;
|
||||
int rank;
|
||||
int i;
|
||||
int iSector;
|
||||
int iResult;
|
||||
|
||||
const char *paramValues[2];
|
||||
int paramLengths[2];
|
||||
@@ -49,20 +49,21 @@ void nominatim_index(int rank_min, int rank_max, int num_threads, const char *co
|
||||
uint32_t sector;
|
||||
|
||||
xmlTextWriterPtr writer;
|
||||
pthread_mutex_t writer_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_mutex_t writer_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
Oid pg_prepare_params[2];
|
||||
|
||||
conn = PQconnectdb(conninfo);
|
||||
if (PQstatus(conn) != CONNECTION_OK) {
|
||||
if (PQstatus(conn) != CONNECTION_OK)
|
||||
{
|
||||
fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT4;
|
||||
res = PQprepare(conn, "index_sectors",
|
||||
"select geometry_sector,count(*) from placex where rank_search = $1 and indexed_status > 0 group by geometry_sector order by geometry_sector",
|
||||
1, pg_prepare_params);
|
||||
"select geometry_sector,count(*) from placex where rank_search = $1 and indexed_status > 0 group by geometry_sector order by geometry_sector",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed preparing index_sectors: %s\n", PQerrorMessage(conn));
|
||||
@@ -72,8 +73,8 @@ void nominatim_index(int rank_min, int rank_max, int num_threads, const char *co
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT4;
|
||||
res = PQprepare(conn, "index_nosectors",
|
||||
"select 0::integer,count(*) from placex where rank_search = $1 and indexed_status > 0",
|
||||
1, pg_prepare_params);
|
||||
"select 0::integer,count(*) from placex where rank_search = $1 and indexed_status > 0",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed preparing index_sectors: %s\n", PQerrorMessage(conn));
|
||||
@@ -84,8 +85,8 @@ void nominatim_index(int rank_min, int rank_max, int num_threads, const char *co
|
||||
pg_prepare_params[0] = PG_OID_INT4;
|
||||
pg_prepare_params[1] = PG_OID_INT4;
|
||||
res = PQprepare(conn, "index_sector_places",
|
||||
"select place_id from placex where rank_search = $1 and geometry_sector = $2 and indexed_status > 0",
|
||||
2, pg_prepare_params);
|
||||
"select place_id from placex where rank_search = $1 and geometry_sector = $2 and indexed_status > 0",
|
||||
2, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed preparing index_sector_places: %s\n", PQerrorMessage(conn));
|
||||
@@ -95,8 +96,8 @@ void nominatim_index(int rank_min, int rank_max, int num_threads, const char *co
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT4;
|
||||
res = PQprepare(conn, "index_nosector_places",
|
||||
"select place_id from placex where rank_search = $1 and indexed_status > 0 order by geometry_sector",
|
||||
1, pg_prepare_params);
|
||||
"select place_id from placex where rank_search = $1 and indexed_status > 0 order by geometry_sector",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed preparing index_nosector_places: %s\n", PQerrorMessage(conn));
|
||||
@@ -106,230 +107,231 @@ void nominatim_index(int rank_min, int rank_max, int num_threads, const char *co
|
||||
|
||||
// Build the data for each thread
|
||||
thread_data = (struct index_thread_data *)malloc(sizeof(struct index_thread_data)*num_threads);
|
||||
for (i = 0; i < num_threads; i++)
|
||||
{
|
||||
thread_data[i].conn = PQconnectdb(conninfo);
|
||||
if (PQstatus(thread_data[i].conn) != CONNECTION_OK) {
|
||||
fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(thread_data[i].conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (i = 0; i < num_threads; i++)
|
||||
{
|
||||
thread_data[i].conn = PQconnectdb(conninfo);
|
||||
if (PQstatus(thread_data[i].conn) != CONNECTION_OK)
|
||||
{
|
||||
fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(thread_data[i].conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT4;
|
||||
res = PQprepare(thread_data[i].conn, "index_placex",
|
||||
"update placex set indexed_status = 0 where place_id = $1",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed preparing index_placex: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
pg_prepare_params[0] = PG_OID_INT4;
|
||||
res = PQprepare(thread_data[i].conn, "index_placex",
|
||||
"update placex set indexed_status = 0 where place_id = $1",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed preparing index_placex: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
res = PQexec(thread_data[i].conn, "set enable_seqscan = false");
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed disabling sequential scan: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
res = PQexec(thread_data[i].conn, "set enable_seqscan = false");
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed disabling sequential scan: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
nominatim_exportCreatePreparedQueries(thread_data[i].conn);
|
||||
}
|
||||
nominatim_exportCreatePreparedQueries(thread_data[i].conn);
|
||||
}
|
||||
|
||||
// Create the output file
|
||||
writer = NULL;
|
||||
if (structuredoutputfile)
|
||||
{
|
||||
writer = nominatim_exportXMLStart(structuredoutputfile);
|
||||
}
|
||||
// Create the output file
|
||||
writer = NULL;
|
||||
if (structuredoutputfile)
|
||||
{
|
||||
writer = nominatim_exportXMLStart(structuredoutputfile);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Starting indexing rank (%i to %i) using %i treads\n", rank_min, rank_max, num_threads);
|
||||
|
||||
for (rank = rank_min; rank <= rank_max; rank++)
|
||||
{
|
||||
printf("Starting rank %d\n", rank);
|
||||
rankCountTuples = 0;
|
||||
rankPerSecond = 0;
|
||||
printf("Starting rank %d\n", rank);
|
||||
rankCountTuples = 0;
|
||||
rankPerSecond = 0;
|
||||
|
||||
paramRank = PGint32(rank);
|
||||
paramValues[0] = (char *)¶mRank;
|
||||
paramLengths[0] = sizeof(paramRank);
|
||||
paramFormats[0] = 1;
|
||||
if (rank < 16)
|
||||
resSectors = PQexecPrepared(conn, "index_nosectors", 1, paramValues, paramLengths, paramFormats, 1);
|
||||
else
|
||||
resSectors = PQexecPrepared(conn, "index_sectors", 1, paramValues, paramLengths, paramFormats, 1);
|
||||
if (rank < 16)
|
||||
resSectors = PQexecPrepared(conn, "index_nosectors", 1, paramValues, paramLengths, paramFormats, 1);
|
||||
else
|
||||
resSectors = PQexecPrepared(conn, "index_sectors", 1, paramValues, paramLengths, paramFormats, 1);
|
||||
if (PQresultStatus(resSectors) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "index_sectors: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resSectors);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (PQftype(resSectors, 0) != PG_OID_INT4)
|
||||
{
|
||||
if (PQftype(resSectors, 0) != PG_OID_INT4)
|
||||
{
|
||||
fprintf(stderr, "Sector value has unexpected type\n");
|
||||
PQclear(resSectors);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (PQftype(resSectors, 1) != PG_OID_INT8)
|
||||
{
|
||||
}
|
||||
if (PQftype(resSectors, 1) != PG_OID_INT8)
|
||||
{
|
||||
fprintf(stderr, "Sector value has unexpected type\n");
|
||||
PQclear(resSectors);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
rankTotalTuples = 0;
|
||||
for (iSector = 0; iSector < PQntuples(resSectors); iSector++)
|
||||
{
|
||||
rankTotalTuples += PGint64(*((uint64_t *)PQgetvalue(resSectors, iSector, 1)));
|
||||
}
|
||||
rankTotalTuples = 0;
|
||||
for (iSector = 0; iSector < PQntuples(resSectors); iSector++)
|
||||
{
|
||||
rankTotalTuples += PGint64(*((uint64_t *)PQgetvalue(resSectors, iSector, 1)));
|
||||
}
|
||||
|
||||
rankStartTime = time(0);
|
||||
for (iSector = 0; iSector <= PQntuples(resSectors); iSector++)
|
||||
{
|
||||
if (iSector > 0)
|
||||
{
|
||||
resPlaces = PQgetResult(conn);
|
||||
if (PQresultStatus(resPlaces) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "index_sector_places: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resPlaces);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (PQftype(resPlaces, 0) != PG_OID_INT4)
|
||||
{
|
||||
fprintf(stderr, "Place_id value has unexpected type\n");
|
||||
PQclear(resPlaces);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
resNULL = PQgetResult(conn);
|
||||
if (resNULL != NULL)
|
||||
{
|
||||
fprintf(stderr, "Unexpected non-null response\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
rankStartTime = time(0);
|
||||
for (iSector = 0; iSector <= PQntuples(resSectors); iSector++)
|
||||
{
|
||||
if (iSector > 0)
|
||||
{
|
||||
resPlaces = PQgetResult(conn);
|
||||
if (PQresultStatus(resPlaces) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "index_sector_places: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resPlaces);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (PQftype(resPlaces, 0) != PG_OID_INT4)
|
||||
{
|
||||
fprintf(stderr, "Place_id value has unexpected type\n");
|
||||
PQclear(resPlaces);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
resNULL = PQgetResult(conn);
|
||||
if (resNULL != NULL)
|
||||
{
|
||||
fprintf(stderr, "Unexpected non-null response\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (iSector < PQntuples(resSectors))
|
||||
{
|
||||
sector = PGint32(*((uint32_t *)PQgetvalue(resSectors, iSector, 0)));
|
||||
//printf("\n Starting sector %d size %ld\n", sector, PGint64(*((uint64_t *)PQgetvalue(resSectors, iSector, 1))));
|
||||
if (iSector < PQntuples(resSectors))
|
||||
{
|
||||
sector = PGint32(*((uint32_t *)PQgetvalue(resSectors, iSector, 0)));
|
||||
//printf("\n Starting sector %d size %ld\n", sector, PGint64(*((uint64_t *)PQgetvalue(resSectors, iSector, 1))));
|
||||
|
||||
// Get all the place_id's for this sector
|
||||
paramRank = PGint32(rank);
|
||||
paramValues[0] = (char *)¶mRank;
|
||||
paramLengths[0] = sizeof(paramRank);
|
||||
paramFormats[0] = 1;
|
||||
paramSector = PGint32(sector);
|
||||
paramValues[1] = (char *)¶mSector;
|
||||
paramLengths[1] = sizeof(paramSector);
|
||||
paramFormats[1] = 1;
|
||||
if (rank < 16)
|
||||
iResult = PQsendQueryPrepared(conn, "index_nosector_places", 1, paramValues, paramLengths, paramFormats, 1);
|
||||
else
|
||||
iResult = PQsendQueryPrepared(conn, "index_sector_places", 2, paramValues, paramLengths, paramFormats, 1);
|
||||
if (!iResult)
|
||||
{
|
||||
fprintf(stderr, "index_sector_places: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resPlaces);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
// Get all the place_id's for this sector
|
||||
paramRank = PGint32(rank);
|
||||
paramValues[0] = (char *)¶mRank;
|
||||
paramLengths[0] = sizeof(paramRank);
|
||||
paramFormats[0] = 1;
|
||||
paramSector = PGint32(sector);
|
||||
paramValues[1] = (char *)¶mSector;
|
||||
paramLengths[1] = sizeof(paramSector);
|
||||
paramFormats[1] = 1;
|
||||
if (rank < 16)
|
||||
iResult = PQsendQueryPrepared(conn, "index_nosector_places", 1, paramValues, paramLengths, paramFormats, 1);
|
||||
else
|
||||
iResult = PQsendQueryPrepared(conn, "index_sector_places", 2, paramValues, paramLengths, paramFormats, 1);
|
||||
if (!iResult)
|
||||
{
|
||||
fprintf(stderr, "index_sector_places: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resPlaces);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (iSector > 0)
|
||||
{
|
||||
count = 0;
|
||||
rankPerSecond = 0;
|
||||
tuples = PQntuples(resPlaces);
|
||||
if (iSector > 0)
|
||||
{
|
||||
count = 0;
|
||||
rankPerSecond = 0;
|
||||
tuples = PQntuples(resPlaces);
|
||||
|
||||
if (tuples > 0)
|
||||
{
|
||||
// Spawn threads
|
||||
for (i = 0; i < num_threads; i++)
|
||||
{
|
||||
thread_data[i].res = resPlaces;
|
||||
thread_data[i].tuples = tuples;
|
||||
thread_data[i].count = &count;
|
||||
thread_data[i].count_mutex = &count_mutex;
|
||||
thread_data[i].writer = writer;
|
||||
thread_data[i].writer_mutex = &writer_mutex;
|
||||
pthread_create(&thread_data[i].thread, NULL, &nominatim_indexThread, (void *)&thread_data[i]);
|
||||
}
|
||||
if (tuples > 0)
|
||||
{
|
||||
// Spawn threads
|
||||
for (i = 0; i < num_threads; i++)
|
||||
{
|
||||
thread_data[i].res = resPlaces;
|
||||
thread_data[i].tuples = tuples;
|
||||
thread_data[i].count = &count;
|
||||
thread_data[i].count_mutex = &count_mutex;
|
||||
thread_data[i].writer = writer;
|
||||
thread_data[i].writer_mutex = &writer_mutex;
|
||||
pthread_create(&thread_data[i].thread, NULL, &nominatim_indexThread, (void *)&thread_data[i]);
|
||||
}
|
||||
|
||||
// Monitor threads to give user feedback
|
||||
sleepcount = 0;
|
||||
while(count < tuples)
|
||||
{
|
||||
usleep(1000);
|
||||
// Monitor threads to give user feedback
|
||||
sleepcount = 0;
|
||||
while (count < tuples)
|
||||
{
|
||||
usleep(1000);
|
||||
|
||||
// Aim for one update per second
|
||||
if (sleepcount++ > 500)
|
||||
{
|
||||
rankPerSecond = ((float)rankCountTuples + (float)count) / MAX(difftime(time(0), rankStartTime),1);
|
||||
printf(" Done %i in %i @ %f per second - Rank %i ETA (seconds): %f\n", (rankCountTuples + count), (int)(difftime(time(0), rankStartTime)), rankPerSecond, rank, ((float)(rankTotalTuples - (rankCountTuples + count)))/rankPerSecond);
|
||||
sleepcount = 0;
|
||||
}
|
||||
}
|
||||
// Aim for one update per second
|
||||
if (sleepcount++ > 500)
|
||||
{
|
||||
rankPerSecond = ((float)rankCountTuples + (float)count) / MAX(difftime(time(0), rankStartTime),1);
|
||||
printf(" Done %i in %i @ %f per second - Rank %i ETA (seconds): %f\n", (rankCountTuples + count), (int)(difftime(time(0), rankStartTime)), rankPerSecond, rank, ((float)(rankTotalTuples - (rankCountTuples + count)))/rankPerSecond);
|
||||
sleepcount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for everything to finish
|
||||
for (i = 0; i < num_threads; i++)
|
||||
{
|
||||
pthread_join(thread_data[i].thread, NULL);
|
||||
}
|
||||
// Wait for everything to finish
|
||||
for (i = 0; i < num_threads; i++)
|
||||
{
|
||||
pthread_join(thread_data[i].thread, NULL);
|
||||
}
|
||||
|
||||
rankCountTuples += tuples;
|
||||
}
|
||||
rankCountTuples += tuples;
|
||||
}
|
||||
|
||||
// Finished sector
|
||||
rankPerSecond = (float)rankCountTuples / MAX(difftime(time(0), rankStartTime),1);
|
||||
printf(" Done %i in %i @ %f per second - ETA (seconds): %f\n", rankCountTuples, (int)(difftime(time(0), rankStartTime)), rankPerSecond, ((float)(rankTotalTuples - rankCountTuples))/rankPerSecond);
|
||||
// Finished sector
|
||||
rankPerSecond = (float)rankCountTuples / MAX(difftime(time(0), rankStartTime),1);
|
||||
printf(" Done %i in %i @ %f per second - ETA (seconds): %f\n", rankCountTuples, (int)(difftime(time(0), rankStartTime)), rankPerSecond, ((float)(rankTotalTuples - rankCountTuples))/rankPerSecond);
|
||||
|
||||
PQclear(resPlaces);
|
||||
}
|
||||
}
|
||||
PQclear(resPlaces);
|
||||
}
|
||||
}
|
||||
// Finished rank
|
||||
printf("\r Done %i in %i @ %f per second - FINISHED \n\n", rankCountTuples, (int)(difftime(time(0), rankStartTime)), rankPerSecond);
|
||||
printf("\r Done %i in %i @ %f per second - FINISHED \n\n", rankCountTuples, (int)(difftime(time(0), rankStartTime)), rankPerSecond);
|
||||
|
||||
PQclear(resSectors);
|
||||
}
|
||||
|
||||
if (writer)
|
||||
{
|
||||
nominatim_exportXMLEnd(writer);
|
||||
nominatim_exportXMLEnd(writer);
|
||||
}
|
||||
}
|
||||
|
||||
void *nominatim_indexThread(void * thread_data_in)
|
||||
{
|
||||
struct index_thread_data * thread_data = (struct index_thread_data * )thread_data_in;
|
||||
struct index_thread_data * thread_data = (struct index_thread_data * )thread_data_in;
|
||||
|
||||
PGresult *res;
|
||||
PGresult *res;
|
||||
|
||||
const char *paramValues[1];
|
||||
int paramLengths[1];
|
||||
int paramFormats[1];
|
||||
uint32_t paramPlaceID;
|
||||
uint32_t place_id;
|
||||
time_t updateStartTime;
|
||||
time_t updateStartTime;
|
||||
|
||||
while(1)
|
||||
{
|
||||
pthread_mutex_lock( thread_data->count_mutex );
|
||||
if (*(thread_data->count) >= thread_data->tuples)
|
||||
{
|
||||
pthread_mutex_unlock( thread_data->count_mutex );
|
||||
break;
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
pthread_mutex_lock( thread_data->count_mutex );
|
||||
if (*(thread_data->count) >= thread_data->tuples)
|
||||
{
|
||||
pthread_mutex_unlock( thread_data->count_mutex );
|
||||
break;
|
||||
}
|
||||
|
||||
place_id = PGint32(*((uint32_t *)PQgetvalue(thread_data->res, *thread_data->count, 0)));
|
||||
(*thread_data->count)++;
|
||||
place_id = PGint32(*((uint32_t *)PQgetvalue(thread_data->res, *thread_data->count, 0)));
|
||||
(*thread_data->count)++;
|
||||
|
||||
pthread_mutex_unlock( thread_data->count_mutex );
|
||||
pthread_mutex_unlock( thread_data->count_mutex );
|
||||
|
||||
if (verbose) printf(" Processing place_id %d\n", place_id);
|
||||
|
||||
updateStartTime = time(0);
|
||||
paramPlaceID = PGint32(place_id);
|
||||
if (verbose) printf(" Processing place_id %d\n", place_id);
|
||||
|
||||
updateStartTime = time(0);
|
||||
paramPlaceID = PGint32(place_id);
|
||||
paramValues[0] = (char *)¶mPlaceID;
|
||||
paramLengths[0] = sizeof(paramPlaceID);
|
||||
paramFormats[0] = 1;
|
||||
@@ -341,13 +343,13 @@ void *nominatim_indexThread(void * thread_data_in)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
if (difftime(time(0), updateStartTime) > 1) printf(" Slow place_id %d\n", place_id);
|
||||
if (difftime(time(0), updateStartTime) > 1) printf(" Slow place_id %d\n", place_id);
|
||||
|
||||
if (thread_data->writer)
|
||||
{
|
||||
nominatim_exportPlace(place_id, thread_data->conn, thread_data->writer, thread_data->writer_mutex);
|
||||
nominatim_exportPlace(place_id, thread_data->conn, thread_data->writer, thread_data->writer_mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -4,15 +4,16 @@
|
||||
#include <libxml/encoding.h>
|
||||
#include <libxml/xmlwriter.h>
|
||||
|
||||
struct index_thread_data{
|
||||
pthread_t thread;
|
||||
PGconn * conn;
|
||||
PGresult * res;
|
||||
int tuples;
|
||||
int * count;
|
||||
pthread_mutex_t * count_mutex;
|
||||
xmlTextWriterPtr writer;
|
||||
pthread_mutex_t * writer_mutex;
|
||||
struct index_thread_data
|
||||
{
|
||||
pthread_t thread;
|
||||
PGconn * conn;
|
||||
PGresult * res;
|
||||
int tuples;
|
||||
int * count;
|
||||
pthread_mutex_t * count_mutex;
|
||||
xmlTextWriterPtr writer;
|
||||
pthread_mutex_t * writer_mutex;
|
||||
};
|
||||
void nominatim_index(int rank_min, int rank_max, int num_threads, const char *conninfo, const char *structuredoutputfile);
|
||||
void *nominatim_indexThread(void * thread_data_in);
|
||||
|
||||
@@ -19,44 +19,46 @@
|
||||
|
||||
#include "input.h"
|
||||
|
||||
struct Input {
|
||||
char *name;
|
||||
enum { plainFile, gzipFile, bzip2File } type;
|
||||
void *fileHandle;
|
||||
// needed by bzip2 when decompressing from multiple streams. other
|
||||
// decompressors must ignore it.
|
||||
FILE *systemHandle;
|
||||
int eof;
|
||||
char buf[4096];
|
||||
int buf_ptr, buf_fill;
|
||||
struct Input
|
||||
{
|
||||
char *name;
|
||||
enum { plainFile, gzipFile, bzip2File } type;
|
||||
void *fileHandle;
|
||||
// needed by bzip2 when decompressing from multiple streams. other
|
||||
// decompressors must ignore it.
|
||||
FILE *systemHandle;
|
||||
int eof;
|
||||
char buf[4096];
|
||||
int buf_ptr, buf_fill;
|
||||
};
|
||||
|
||||
// tries to re-open the bz stream at the next stream start.
|
||||
// returns 0 on success, -1 on failure.
|
||||
int bzReOpen(struct Input *ctx, int *error) {
|
||||
// for copying out the last unused part of the block which
|
||||
// has an EOS token in it. needed for re-initialising the
|
||||
// next stream.
|
||||
unsigned char unused[BZ_MAX_UNUSED];
|
||||
void *unused_tmp_ptr = NULL;
|
||||
int nUnused, i;
|
||||
int bzReOpen(struct Input *ctx, int *error)
|
||||
{
|
||||
// for copying out the last unused part of the block which
|
||||
// has an EOS token in it. needed for re-initialising the
|
||||
// next stream.
|
||||
unsigned char unused[BZ_MAX_UNUSED];
|
||||
void *unused_tmp_ptr = NULL;
|
||||
int nUnused, i;
|
||||
|
||||
BZ2_bzReadGetUnused(error, (BZFILE *)(ctx->fileHandle), &unused_tmp_ptr, &nUnused);
|
||||
if (*error != BZ_OK) return -1;
|
||||
|
||||
// when bzReadClose is called the unused buffer is deallocated,
|
||||
// so it needs to be copied somewhere safe first.
|
||||
for (i = 0; i < nUnused; ++i)
|
||||
unused[i] = ((unsigned char *)unused_tmp_ptr)[i];
|
||||
|
||||
BZ2_bzReadClose(error, (BZFILE *)(ctx->fileHandle));
|
||||
if (*error != BZ_OK) return -1;
|
||||
BZ2_bzReadGetUnused(error, (BZFILE *)(ctx->fileHandle), &unused_tmp_ptr, &nUnused);
|
||||
if (*error != BZ_OK) return -1;
|
||||
|
||||
// reassign the file handle
|
||||
ctx->fileHandle = BZ2_bzReadOpen(error, ctx->systemHandle, 0, 0, unused, nUnused);
|
||||
if (ctx->fileHandle == NULL || *error != BZ_OK) return -1;
|
||||
// when bzReadClose is called the unused buffer is deallocated,
|
||||
// so it needs to be copied somewhere safe first.
|
||||
for (i = 0; i < nUnused; ++i)
|
||||
unused[i] = ((unsigned char *)unused_tmp_ptr)[i];
|
||||
|
||||
return 0;
|
||||
BZ2_bzReadClose(error, (BZFILE *)(ctx->fileHandle));
|
||||
if (*error != BZ_OK) return -1;
|
||||
|
||||
// reassign the file handle
|
||||
ctx->fileHandle = BZ2_bzReadOpen(error, ctx->systemHandle, 0, 0, unused, nUnused);
|
||||
if (ctx->fileHandle == NULL || *error != BZ_OK) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int readFile(void *context, char * buffer, int len)
|
||||
@@ -67,36 +69,40 @@ int readFile(void *context, char * buffer, int len)
|
||||
|
||||
if (ctx->eof || (len == 0))
|
||||
return 0;
|
||||
|
||||
switch(ctx->type) {
|
||||
case plainFile:
|
||||
l = read(*(int *)f, buffer, len);
|
||||
if (l <= 0) ctx->eof = 1;
|
||||
break;
|
||||
case gzipFile:
|
||||
l = gzread((gzFile)f, buffer, len);
|
||||
if (l <= 0) ctx->eof = 1;
|
||||
break;
|
||||
case bzip2File:
|
||||
l = BZ2_bzRead(&error, (BZFILE *)f, buffer, len);
|
||||
|
||||
// error codes BZ_OK and BZ_STREAM_END are both "OK", but the stream
|
||||
// end means the reader needs to be reset from the original handle.
|
||||
if (error != BZ_OK) {
|
||||
// for stream errors, try re-opening the stream before admitting defeat.
|
||||
if (error != BZ_STREAM_END || bzReOpen(ctx, &error) != 0) {
|
||||
l = 0;
|
||||
ctx->eof = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Bad file type\n");
|
||||
break;
|
||||
switch (ctx->type)
|
||||
{
|
||||
case plainFile:
|
||||
l = read(*(int *)f, buffer, len);
|
||||
if (l <= 0) ctx->eof = 1;
|
||||
break;
|
||||
case gzipFile:
|
||||
l = gzread((gzFile)f, buffer, len);
|
||||
if (l <= 0) ctx->eof = 1;
|
||||
break;
|
||||
case bzip2File:
|
||||
l = BZ2_bzRead(&error, (BZFILE *)f, buffer, len);
|
||||
|
||||
// error codes BZ_OK and BZ_STREAM_END are both "OK", but the stream
|
||||
// end means the reader needs to be reset from the original handle.
|
||||
if (error != BZ_OK)
|
||||
{
|
||||
// for stream errors, try re-opening the stream before admitting defeat.
|
||||
if (error != BZ_STREAM_END || bzReOpen(ctx, &error) != 0)
|
||||
{
|
||||
l = 0;
|
||||
ctx->eof = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Bad file type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (l < 0) {
|
||||
fprintf(stderr, "File reader received error %d (%d)\n", l, error);
|
||||
if (l < 0)
|
||||
{
|
||||
fprintf(stderr, "File reader received error %d (%d)\n", l, error);
|
||||
l = 0;
|
||||
}
|
||||
|
||||
@@ -107,12 +113,14 @@ char inputGetChar(void *context)
|
||||
{
|
||||
struct Input *ctx = context;
|
||||
|
||||
if (ctx->buf_ptr == ctx->buf_fill) {
|
||||
if (ctx->buf_ptr == ctx->buf_fill)
|
||||
{
|
||||
ctx->buf_fill = readFile(context, &ctx->buf[0], sizeof(ctx->buf));
|
||||
ctx->buf_ptr = 0;
|
||||
if (ctx->buf_fill == 0)
|
||||
return 0;
|
||||
if (ctx->buf_fill < 0) {
|
||||
if (ctx->buf_fill < 0)
|
||||
{
|
||||
perror("Error while reading file");
|
||||
exit(1);
|
||||
}
|
||||
@@ -138,32 +146,43 @@ void *inputOpen(const char *name)
|
||||
|
||||
ctx->name = strdup(name);
|
||||
|
||||
if (ext && !strcmp(ext, ".gz")) {
|
||||
if (ext && !strcmp(ext, ".gz"))
|
||||
{
|
||||
ctx->fileHandle = (void *)gzopen(name, "rb");
|
||||
ctx->type = gzipFile;
|
||||
} else if (ext && !strcmp(ext, ".bz2")) {
|
||||
int error = 0;
|
||||
ctx->systemHandle = fopen(name, "rb");
|
||||
if (!ctx->systemHandle) {
|
||||
fprintf(stderr, "error while opening file %s\n", name);
|
||||
exit(10);
|
||||
}
|
||||
}
|
||||
else if (ext && !strcmp(ext, ".bz2"))
|
||||
{
|
||||
int error = 0;
|
||||
ctx->systemHandle = fopen(name, "rb");
|
||||
if (!ctx->systemHandle)
|
||||
{
|
||||
fprintf(stderr, "error while opening file %s\n", name);
|
||||
exit(10);
|
||||
}
|
||||
|
||||
ctx->fileHandle = (void *)BZ2_bzReadOpen(&error, ctx->systemHandle, 0, 0, NULL, 0);
|
||||
ctx->type = bzip2File;
|
||||
|
||||
} else {
|
||||
ctx->fileHandle = (void *)BZ2_bzReadOpen(&error, ctx->systemHandle, 0, 0, NULL, 0);
|
||||
ctx->type = bzip2File;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
int *pfd = malloc(sizeof(pfd));
|
||||
if (pfd) {
|
||||
if (!strcmp(name, "-")) {
|
||||
if (pfd)
|
||||
{
|
||||
if (!strcmp(name, "-"))
|
||||
{
|
||||
*pfd = STDIN_FILENO;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
int flags = O_RDONLY;
|
||||
#ifdef O_LARGEFILE
|
||||
flags |= O_LARGEFILE;
|
||||
#endif
|
||||
*pfd = open(name, flags);
|
||||
if (*pfd < 0) {
|
||||
if (*pfd < 0)
|
||||
{
|
||||
free(pfd);
|
||||
pfd = NULL;
|
||||
}
|
||||
@@ -172,7 +191,8 @@ void *inputOpen(const char *name)
|
||||
ctx->fileHandle = (void *)pfd;
|
||||
ctx->type = plainFile;
|
||||
}
|
||||
if (!ctx->fileHandle) {
|
||||
if (!ctx->fileHandle)
|
||||
{
|
||||
fprintf(stderr, "error while opening file %s\n", name);
|
||||
exit(10);
|
||||
}
|
||||
@@ -186,20 +206,21 @@ int inputClose(void *context)
|
||||
struct Input *ctx = context;
|
||||
void *f = ctx->fileHandle;
|
||||
|
||||
switch(ctx->type) {
|
||||
case plainFile:
|
||||
close(*(int *)f);
|
||||
free(f);
|
||||
break;
|
||||
case gzipFile:
|
||||
gzclose((gzFile)f);
|
||||
break;
|
||||
case bzip2File:
|
||||
BZ2_bzclose((BZFILE *)f);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Bad file type\n");
|
||||
break;
|
||||
switch (ctx->type)
|
||||
{
|
||||
case plainFile:
|
||||
close(*(int *)f);
|
||||
free(f);
|
||||
break;
|
||||
case gzipFile:
|
||||
gzclose((gzFile)f);
|
||||
break;
|
||||
case bzip2File:
|
||||
BZ2_bzclose((BZFILE *)f);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Bad file type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
free(ctx->name);
|
||||
@@ -211,7 +232,8 @@ xmlTextReaderPtr inputUTF8(const char *name)
|
||||
{
|
||||
void *ctx = inputOpen(name);
|
||||
|
||||
if (!ctx) {
|
||||
if (!ctx)
|
||||
{
|
||||
fprintf(stderr, "Input reader create failed for: %s\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,8 @@ static void long_usage(char *arg0)
|
||||
fprintf(stderr, " -v|--verbose\t\tVerbose output.\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (sizeof(int*) == 4) {
|
||||
if (sizeof(int*) == 4)
|
||||
{
|
||||
fprintf(stderr, "\n\nYou are running this on 32bit system - this will not work\n");
|
||||
}
|
||||
}
|
||||
@@ -112,9 +113,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
fprintf(stderr, "nominatim SVN version %s\n\n", VERSION);
|
||||
|
||||
while (1) {
|
||||
while (1)
|
||||
{
|
||||
int c, option_index = 0;
|
||||
static struct option long_options[] = {
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"help", 0, 0, 'h'},
|
||||
|
||||
{"verbose", 0, 0, 'v'},
|
||||
@@ -140,55 +143,86 @@ int main(int argc, char *argv[])
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'v': verbose=1; break;
|
||||
case 'd': db=optarg; break;
|
||||
case 'U': username=optarg; break;
|
||||
case 'W': pass_prompt=1; break;
|
||||
case 'H': host=optarg; break;
|
||||
case 'P': port=optarg; break;
|
||||
case 'h': long_usage_bool=1; break;
|
||||
case 'i': index=1; break;
|
||||
case 'e': export=1; break;
|
||||
case 'I': import=1; break;
|
||||
case 't': threads=atoi(optarg); break;
|
||||
case 'F': file=optarg; break;
|
||||
case 'T': tagsfile=optarg; break;
|
||||
case '?':
|
||||
default:
|
||||
short_usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
switch (c)
|
||||
{
|
||||
case 'v':
|
||||
verbose=1;
|
||||
break;
|
||||
case 'd':
|
||||
db=optarg;
|
||||
break;
|
||||
case 'U':
|
||||
username=optarg;
|
||||
break;
|
||||
case 'W':
|
||||
pass_prompt=1;
|
||||
break;
|
||||
case 'H':
|
||||
host=optarg;
|
||||
break;
|
||||
case 'P':
|
||||
port=optarg;
|
||||
break;
|
||||
case 'h':
|
||||
long_usage_bool=1;
|
||||
break;
|
||||
case 'i':
|
||||
index=1;
|
||||
break;
|
||||
case 'e':
|
||||
export=1;
|
||||
break;
|
||||
case 'I':
|
||||
import=1;
|
||||
break;
|
||||
case 't':
|
||||
threads=atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
file=optarg;
|
||||
break;
|
||||
case 'T':
|
||||
tagsfile=optarg;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
short_usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (long_usage_bool) {
|
||||
if (long_usage_bool)
|
||||
{
|
||||
long_usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (threads < 1) threads = 1;
|
||||
|
||||
/*
|
||||
if (argc == optind) { // No non-switch arguments
|
||||
short_usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
*/
|
||||
if (index && import) {
|
||||
/*
|
||||
if (argc == optind) { // No non-switch arguments
|
||||
short_usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
*/
|
||||
if (index && import)
|
||||
{
|
||||
fprintf(stderr, "Error: --index and --import options can not be used on the same database!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (pass_prompt)
|
||||
password = simple_prompt("Password:", 100, 0);
|
||||
else {
|
||||
else
|
||||
{
|
||||
password = getenv("PGPASS");
|
||||
}
|
||||
|
||||
// Test the database connection
|
||||
conninfo = build_conninfo(db, username, password, host, port);
|
||||
conn = PQconnectdb(conninfo);
|
||||
if (PQstatus(conn) != CONNECTION_OK) {
|
||||
if (PQstatus(conn) != CONNECTION_OK)
|
||||
{
|
||||
fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -196,7 +230,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (!index && !export && !import)
|
||||
{
|
||||
fprintf(stderr, "Please select index, export or import.\n");
|
||||
fprintf(stderr, "Please select index, export or import.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (index) nominatim_index(0, 30, threads, conninfo, file);
|
||||
|
||||
@@ -4,24 +4,25 @@
|
||||
#define MAX(x,y) (x > y?x:y)
|
||||
#define MIN(x,y) (x < y?x:y)
|
||||
|
||||
struct output_options {
|
||||
const char *conninfo; /* Connection info string */
|
||||
const char *prefix; /* prefix for table names */
|
||||
int scale; /* scale for converting coordinates to fixed point */
|
||||
int projection; /* SRS of projection */
|
||||
int append; /* Append to existing data */
|
||||
int slim; /* In slim mode */
|
||||
int cache; /* Memory usable for cache in MB */
|
||||
struct middle_t *mid; /* Mid storage to use */
|
||||
const char *tblsindex; /* Pg Tablespace to store indexes */
|
||||
const char *style; /* style file to use */
|
||||
int expire_tiles_zoom; /* Zoom level for tile expiry list */
|
||||
int expire_tiles_zoom_min; /* Minimum zoom level for tile expiry list */
|
||||
const char *expire_tiles_filename; /* File name to output expired tiles list to */
|
||||
int enable_hstore; /* add an additional hstore column with objects key/value pairs */
|
||||
int enable_multi; /* Output multi-geometries intead of several simple geometries */
|
||||
char** hstore_columns; /* list of columns that should be written into their own hstore column */
|
||||
int n_hstore_columns; /* number of hstore columns */
|
||||
struct output_options
|
||||
{
|
||||
const char *conninfo; /* Connection info string */
|
||||
const char *prefix; /* prefix for table names */
|
||||
int scale; /* scale for converting coordinates to fixed point */
|
||||
int projection; /* SRS of projection */
|
||||
int append; /* Append to existing data */
|
||||
int slim; /* In slim mode */
|
||||
int cache; /* Memory usable for cache in MB */
|
||||
struct middle_t *mid; /* Mid storage to use */
|
||||
const char *tblsindex; /* Pg Tablespace to store indexes */
|
||||
const char *style; /* style file to use */
|
||||
int expire_tiles_zoom; /* Zoom level for tile expiry list */
|
||||
int expire_tiles_zoom_min; /* Minimum zoom level for tile expiry list */
|
||||
const char *expire_tiles_filename; /* File name to output expired tiles list to */
|
||||
int enable_hstore; /* add an additional hstore column with objects key/value pairs */
|
||||
int enable_multi; /* Output multi-geometries intead of several simple geometries */
|
||||
char** hstore_columns; /* list of columns that should be written into their own hstore column */
|
||||
int n_hstore_columns; /* number of hstore columns */
|
||||
};
|
||||
|
||||
void exit_nicely(void);
|
||||
|
||||
@@ -12,22 +12,26 @@ const char *build_conninfo(const char *db, const char *username, const char *pas
|
||||
strcat(conninfo, db);
|
||||
strcat(conninfo, "'");
|
||||
|
||||
if (username) {
|
||||
if (username)
|
||||
{
|
||||
strcat(conninfo, " user='");
|
||||
strcat(conninfo, username);
|
||||
strcat(conninfo, "'");
|
||||
}
|
||||
if (password) {
|
||||
if (password)
|
||||
{
|
||||
strcat(conninfo, " password='");
|
||||
strcat(conninfo, password);
|
||||
strcat(conninfo, "'");
|
||||
}
|
||||
if (host) {
|
||||
if (host)
|
||||
{
|
||||
strcat(conninfo, " host='");
|
||||
strcat(conninfo, host);
|
||||
strcat(conninfo, "'");
|
||||
}
|
||||
if (port) {
|
||||
if (port)
|
||||
{
|
||||
strcat(conninfo, " port='");
|
||||
strcat(conninfo, port);
|
||||
strcat(conninfo, "'");
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* $PostgreSQL: pgsql/src/port/sprompt.c,v 1.18 2006/10/04 00:30:14 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
*
|
||||
* PostgreSQL Database Management System
|
||||
* (formerly known as Postgres, then as Postgres95)
|
||||
*
|
||||
@@ -76,124 +76,125 @@ extern char *simple_prompt(const char *prompt, int maxlen, int echo);
|
||||
char *
|
||||
simple_prompt(const char *prompt, int maxlen, int echo)
|
||||
{
|
||||
int length;
|
||||
char *destination;
|
||||
FILE *termin,
|
||||
*termout;
|
||||
int length;
|
||||
char *destination;
|
||||
FILE *termin,
|
||||
*termout;
|
||||
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
struct termios t_orig,
|
||||
t;
|
||||
struct termios t_orig,
|
||||
t;
|
||||
#else
|
||||
#ifdef WIN32
|
||||
HANDLE t = NULL;
|
||||
LPDWORD t_orig = NULL;
|
||||
HANDLE t = NULL;
|
||||
LPDWORD t_orig = NULL;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
destination = (char *) malloc(maxlen + 1);
|
||||
if (!destination)
|
||||
return NULL;
|
||||
destination = (char *) malloc(maxlen + 1);
|
||||
if (!destination)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Do not try to collapse these into one "w+" mode file. Doesn't work on
|
||||
* some platforms (eg, HPUX 10.20).
|
||||
*/
|
||||
termin = fopen(DEVTTY, "r");
|
||||
termout = fopen(DEVTTY, "w");
|
||||
if (!termin || !termout
|
||||
/*
|
||||
* Do not try to collapse these into one "w+" mode file. Doesn't work on
|
||||
* some platforms (eg, HPUX 10.20).
|
||||
*/
|
||||
termin = fopen(DEVTTY, "r");
|
||||
termout = fopen(DEVTTY, "w");
|
||||
if (!termin || !termout
|
||||
#ifdef WIN32
|
||||
/* See DEVTTY comment for msys */
|
||||
|| (getenv("OSTYPE") && strcmp(getenv("OSTYPE"), "msys") == 0)
|
||||
/* See DEVTTY comment for msys */
|
||||
|| (getenv("OSTYPE") && strcmp(getenv("OSTYPE"), "msys") == 0)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (termin)
|
||||
fclose(termin);
|
||||
if (termout)
|
||||
fclose(termout);
|
||||
termin = stdin;
|
||||
termout = stderr;
|
||||
}
|
||||
)
|
||||
{
|
||||
if (termin)
|
||||
fclose(termin);
|
||||
if (termout)
|
||||
fclose(termout);
|
||||
termin = stdin;
|
||||
termout = stderr;
|
||||
}
|
||||
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
if (!echo)
|
||||
{
|
||||
tcgetattr(fileno(termin), &t);
|
||||
t_orig = t;
|
||||
t.c_lflag &= ~ECHO;
|
||||
tcsetattr(fileno(termin), TCSAFLUSH, &t);
|
||||
}
|
||||
if (!echo)
|
||||
{
|
||||
tcgetattr(fileno(termin), &t);
|
||||
t_orig = t;
|
||||
t.c_lflag &= ~ECHO;
|
||||
tcsetattr(fileno(termin), TCSAFLUSH, &t);
|
||||
}
|
||||
#else
|
||||
#ifdef WIN32
|
||||
if (!echo)
|
||||
{
|
||||
/* get a new handle to turn echo off */
|
||||
t_orig = (LPDWORD) malloc(sizeof(DWORD));
|
||||
t = GetStdHandle(STD_INPUT_HANDLE);
|
||||
if (!echo)
|
||||
{
|
||||
/* get a new handle to turn echo off */
|
||||
t_orig = (LPDWORD) malloc(sizeof(DWORD));
|
||||
t = GetStdHandle(STD_INPUT_HANDLE);
|
||||
|
||||
/* save the old configuration first */
|
||||
GetConsoleMode(t, t_orig);
|
||||
/* save the old configuration first */
|
||||
GetConsoleMode(t, t_orig);
|
||||
|
||||
/* set to the new mode */
|
||||
SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
|
||||
}
|
||||
/* set to the new mode */
|
||||
SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (prompt)
|
||||
{
|
||||
fputs(prompt, termout);
|
||||
fflush(termout);
|
||||
}
|
||||
if (prompt)
|
||||
{
|
||||
fputs(prompt, termout);
|
||||
fflush(termout);
|
||||
}
|
||||
|
||||
if (fgets(destination, maxlen + 1, termin) == NULL)
|
||||
destination[0] = '\0';
|
||||
if (fgets(destination, maxlen + 1, termin) == NULL)
|
||||
destination[0] = '\0';
|
||||
|
||||
length = strlen(destination);
|
||||
if (length > 0 && destination[length - 1] != '\n')
|
||||
{
|
||||
/* eat rest of the line */
|
||||
char buf[128];
|
||||
int buflen;
|
||||
length = strlen(destination);
|
||||
if (length > 0 && destination[length - 1] != '\n')
|
||||
{
|
||||
/* eat rest of the line */
|
||||
char buf[128];
|
||||
int buflen;
|
||||
|
||||
do
|
||||
{
|
||||
if (fgets(buf, sizeof(buf), termin) == NULL)
|
||||
break;
|
||||
buflen = strlen(buf);
|
||||
} while (buflen > 0 && buf[buflen - 1] != '\n');
|
||||
}
|
||||
do
|
||||
{
|
||||
if (fgets(buf, sizeof(buf), termin) == NULL)
|
||||
break;
|
||||
buflen = strlen(buf);
|
||||
}
|
||||
while (buflen > 0 && buf[buflen - 1] != '\n');
|
||||
}
|
||||
|
||||
if (length > 0 && destination[length - 1] == '\n')
|
||||
/* remove trailing newline */
|
||||
destination[length - 1] = '\0';
|
||||
if (length > 0 && destination[length - 1] == '\n')
|
||||
/* remove trailing newline */
|
||||
destination[length - 1] = '\0';
|
||||
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
if (!echo)
|
||||
{
|
||||
tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
|
||||
fputs("\n", termout);
|
||||
fflush(termout);
|
||||
}
|
||||
if (!echo)
|
||||
{
|
||||
tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
|
||||
fputs("\n", termout);
|
||||
fflush(termout);
|
||||
}
|
||||
#else
|
||||
#ifdef WIN32
|
||||
if (!echo)
|
||||
{
|
||||
/* reset to the original console mode */
|
||||
SetConsoleMode(t, *t_orig);
|
||||
fputs("\n", termout);
|
||||
fflush(termout);
|
||||
free(t_orig);
|
||||
}
|
||||
if (!echo)
|
||||
{
|
||||
/* reset to the original console mode */
|
||||
SetConsoleMode(t, *t_orig);
|
||||
fputs("\n", termout);
|
||||
fflush(termout);
|
||||
free(t_orig);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (termin != stdin)
|
||||
{
|
||||
fclose(termin);
|
||||
fclose(termout);
|
||||
}
|
||||
if (termin != stdin)
|
||||
{
|
||||
fclose(termin);
|
||||
fclose(termout);
|
||||
}
|
||||
|
||||
return destination;
|
||||
return destination;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user