8 #include <libxml/xmlstring.h>
9 #include <libxml/xmlreader.h>
10 #include <libxml/hash.h>
12 #include "nominatim.h"
16 typedef enum { FILETYPE_NONE, FILETYPE_STRUCTUREDV0P1 } filetypes_t;
17 typedef enum { FILEMODE_NONE, FILEMODE_ADD, FILEMODE_UPDATE, FILEMODE_DELETE } filemodes_t;
19 #define MAX_FEATUREADDRESS 5000
20 #define MAX_FEATURENAMES 10000
21 #define MAX_FEATUREEXTRATAGS 10000
22 #define MAX_FEATURENAMESTRING 1000000
23 #define MAX_FEATUREEXTRATAGSTRING 500000
25 struct feature_address
50 xmlChar * rankAddress;
52 xmlChar * countryCode;
53 xmlChar * parentPlaceID;
57 xmlChar * houseNumber;
61 int fileType = FILETYPE_NONE;
62 int fileMode = FILEMODE_ADD;
64 struct feature_address featureAddress[MAX_FEATUREADDRESS];
65 struct feature_tag featureName[MAX_FEATURENAMES];
66 struct feature_tag featureExtraTag[MAX_FEATUREEXTRATAGS];
67 struct feature feature;
68 int featureAddressLines = 0;
69 int featureNameLines = 0;
70 int featureExtraTagLines = 0;
72 xmlHashTablePtr partionTableTagsHash;
73 xmlHashTablePtr partionTableTagsHashDelete;
74 char featureNameString[MAX_FEATURENAMESTRING];
75 char featureExtraTagString[MAX_FEATUREEXTRATAGSTRING];
79 void StartElement(xmlTextReaderPtr reader, const xmlChar *name)
85 if (fileType == FILETYPE_NONE)
87 // Potential to handle other file types in the future / versions
88 if (xmlStrEqual(name, BAD_CAST "osmStructured"))
90 value = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "version");
91 version = strtof(value, NULL);
94 if (version == (float)0.1)
96 fileType = FILETYPE_STRUCTUREDV0P1;
97 fileMode = FILEMODE_ADD;
101 fprintf( stderr, "Unknown osmStructured version %f (%s)\n", version, value );
107 fprintf( stderr, "Unknown XML document type: %s\n", name );
113 if (xmlStrEqual(name, BAD_CAST "add"))
115 fileMode = FILEMODE_ADD;
118 if (xmlStrEqual(name, BAD_CAST "update"))
120 fileMode = FILEMODE_UPDATE;
123 if (xmlStrEqual(name, BAD_CAST "delete"))
125 fileMode = FILEMODE_DELETE;
128 if (fileMode == FILEMODE_NONE)
130 fprintf( stderr, "Unknown import mode in: %s\n", name );
134 if (xmlStrEqual(name, BAD_CAST "feature"))
136 feature.placeID = xmlTextReaderGetAttribute(reader, BAD_CAST "place_id");
137 feature.type = xmlTextReaderGetAttribute(reader, BAD_CAST "type");
138 feature.id = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
139 feature.key = xmlTextReaderGetAttribute(reader, BAD_CAST "key");
140 feature.value = xmlTextReaderGetAttribute(reader, BAD_CAST "value");
141 feature.rankAddress = xmlTextReaderGetAttribute(reader, BAD_CAST "rank");
142 feature.rankSearch = xmlTextReaderGetAttribute(reader, BAD_CAST "importance");
144 feature.parentPlaceID = xmlTextReaderGetAttribute(reader, BAD_CAST "parent_place_id");
146 if (strlen(feature.parentPlaceID) == 0)
148 xmlFree(feature.parentPlaceID);
149 feature.parentPlaceID = NULL;
152 feature.parentType = xmlTextReaderGetAttribute(reader, BAD_CAST "parent_type");
153 feature.parentID = xmlTextReaderGetAttribute(reader, BAD_CAST "parent_id");
155 feature.countryCode = NULL;
156 feature.adminLevel = NULL;
157 feature.houseNumber = NULL;
158 feature.geometry = NULL;
159 featureAddressLines = 0;
160 featureNameLines = 0;
161 featureExtraTagLines = 0;
165 if (xmlStrEqual(name, BAD_CAST "names")) return;
166 if (xmlStrEqual(name, BAD_CAST "name"))
168 if (featureNameLines < MAX_FEATURENAMES)
170 featureName[featureNameLines].type = xmlTextReaderGetAttribute(reader, BAD_CAST "type");
171 featureName[featureNameLines].value = xmlTextReaderReadString(reader);
176 fprintf( stderr, "Too many name elements (%s%s)\n", feature.type, feature.id);
181 if (xmlStrEqual(name, BAD_CAST "tags")) return;
182 if (xmlStrEqual(name, BAD_CAST "tag"))
184 if (featureExtraTagLines < MAX_FEATUREEXTRATAGS)
186 featureExtraTag[featureExtraTagLines].type = xmlTextReaderGetAttribute(reader, BAD_CAST "type");
187 featureExtraTag[featureExtraTagLines].value = xmlTextReaderReadString(reader);
188 featureExtraTagLines++;
192 fprintf( stderr, "Too many extra tag elements (%s%s)\n", feature.type, feature.id);
197 if (xmlStrEqual(name, BAD_CAST "osmGeometry"))
199 feature.geometry = xmlTextReaderReadString(reader);
202 if (xmlStrEqual(name, BAD_CAST "adminLevel"))
204 feature.adminLevel = xmlTextReaderReadString(reader);
207 if (xmlStrEqual(name, BAD_CAST "countryCode"))
209 feature.countryCode = xmlTextReaderReadString(reader);
212 if (xmlStrEqual(name, BAD_CAST "houseNumber"))
214 feature.houseNumber = xmlTextReaderReadString(reader);
217 if (xmlStrEqual(name, BAD_CAST "address"))
219 featureAddressLines = 0;
223 if (xmlStrEqual(name, BAD_CAST "continent"))
227 else if (xmlStrEqual(name, BAD_CAST "sea"))
231 else if (xmlStrEqual(name, BAD_CAST "country"))
235 else if (xmlStrEqual(name, BAD_CAST "state"))
239 else if (xmlStrEqual(name, BAD_CAST "county"))
243 else if (xmlStrEqual(name, BAD_CAST "city"))
247 else if (xmlStrEqual(name, BAD_CAST "town"))
251 else if (xmlStrEqual(name, BAD_CAST "village"))
255 else if (xmlStrEqual(name, BAD_CAST "unknown"))
259 else if (xmlStrEqual(name, BAD_CAST "suburb"))
263 else if (xmlStrEqual(name, BAD_CAST "postcode"))
267 else if (xmlStrEqual(name, BAD_CAST "neighborhood"))
271 else if (xmlStrEqual(name, BAD_CAST "street"))
275 else if (xmlStrEqual(name, BAD_CAST "access"))
279 else if (xmlStrEqual(name, BAD_CAST "building"))
283 else if (xmlStrEqual(name, BAD_CAST "other"))
289 if (featureAddressLines < MAX_FEATUREADDRESS)
291 value = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "rank");
294 fprintf( stderr, "Address element missing rank\n");
297 featureAddress[featureAddressLines].rankAddress = atoi(value);
300 value = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "isaddress");
303 fprintf( stderr, "Address element missing rank\n");
306 if (*value == 't') strcpy(featureAddress[featureAddressLines].isAddress, "t");
307 else strcpy(featureAddress[featureAddressLines].isAddress, "f");
310 featureAddress[featureAddressLines].type = xmlTextReaderGetAttribute(reader, BAD_CAST "type");
311 featureAddress[featureAddressLines].id = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
312 featureAddress[featureAddressLines].key = xmlTextReaderGetAttribute(reader, BAD_CAST "key");
313 featureAddress[featureAddressLines].value = xmlTextReaderGetAttribute(reader, BAD_CAST "value");
314 featureAddress[featureAddressLines].distance = xmlTextReaderGetAttribute(reader, BAD_CAST "distance");
316 featureAddressLines++;
320 fprintf( stderr, "Too many address elements (%s%s)\n", feature.type, feature.id);
326 fprintf(stderr, "%s: Unknown element name: %s\n", __FUNCTION__, name);
329 void EndElement(xmlTextReaderPtr reader, const xmlChar *name)
332 const char * paramValues[14];
334 char * partionQueryName;
335 int i, namePos, lineTypeLen, lineValueLen;
337 if (xmlStrEqual(name, BAD_CAST "feature"))
340 if (featureCount % 1000 == 0) printf("feature %i(k)\n", featureCount/1000);
342 if (fileMode == FILEMODE_ADD)
344 resPlaceID = PQexecPrepared(conn, "get_new_place_id", 0, NULL, NULL, NULL, 0);
345 if (PQresultStatus(resPlaceID) != PGRES_TUPLES_OK)
347 fprintf(stderr, "get_place_id: INSERT failed: %s", PQerrorMessage(conn));
354 paramValues[0] = (const char *)feature.type;
355 paramValues[1] = (const char *)feature.id;
356 paramValues[2] = (const char *)feature.key;
357 paramValues[3] = (const char *)feature.value;
358 resPlaceID = PQexecPrepared(conn, "get_new_place_id", 4, paramValues, NULL, NULL, 0);
359 if (PQresultStatus(resPlaceID) != PGRES_TUPLES_OK)
361 fprintf(stderr, "index_placex: INSERT failed: %s", PQerrorMessage(conn));
367 place_id = (char *)feature.placeID;
369 if (fileMode == FILEMODE_UPDATE || fileMode == FILEMODE_DELETE || fileMode == FILEMODE_ADD)
371 paramValues[0] = (const char *)place_id;
372 if (verbose) fprintf(stderr, "placex_delete: %s\n", paramValues[0]);
373 res = PQexecPrepared(conn, "placex_delete", 1, paramValues, NULL, NULL, 0);
374 if (PQresultStatus(res) != PGRES_COMMAND_OK)
376 fprintf(stderr, "placex_delete: DELETE failed: %s", PQerrorMessage(conn));
382 if (verbose) fprintf(stderr, "search_name_delete: %s\n", paramValues[0]);
383 res = PQexecPrepared(conn, "search_name_delete", 1, paramValues, NULL, NULL, 0);
384 if (PQresultStatus(res) != PGRES_COMMAND_OK)
386 fprintf(stderr, "search_name_delete: DELETE failed: %s", PQerrorMessage(conn));
392 if (verbose) fprintf(stderr, "place_addressline_delete: %s\n", paramValues[0]);
393 res = PQexecPrepared(conn, "place_addressline_delete", 1, paramValues, NULL, NULL, 0);
394 if (PQresultStatus(res) != PGRES_COMMAND_OK)
396 fprintf(stderr, "place_addressline_delete: DELETE failed: %s", PQerrorMessage(conn));
402 partionQueryName = xmlHashLookup2(partionTableTagsHashDelete, feature.key, feature.value);
403 if (partionQueryName)
405 res = PQexecPrepared(conn, partionQueryName, 1, paramValues, NULL, NULL, 0);
406 if (PQresultStatus(res) != PGRES_COMMAND_OK)
408 fprintf(stderr, "%s: DELETE failed: %s", partionQueryName, PQerrorMessage(conn));
416 if (fileMode == FILEMODE_UPDATE || fileMode == FILEMODE_ADD)
418 // Insert into placex
419 paramValues[0] = (const char *)place_id;
420 paramValues[1] = (const char *)feature.type;
421 paramValues[2] = (const char *)feature.id;
422 paramValues[3] = (const char *)feature.key;
423 paramValues[4] = (const char *)feature.value;
425 featureNameString[0] = 0;
426 if (featureNameLines)
431 for (i = 0; i < featureNameLines; i++)
433 lineTypeLen = (int)strlen((char *) featureName[i].type);
434 lineValueLen = (int)strlen((char *) featureName[i].value);
435 if (namePos+lineTypeLen+lineValueLen+7 > MAX_FEATURENAMESTRING)
437 fprintf(stderr, "feature name too long: %s", (const char *)featureName[i].value);
440 if (namePos) strcpy(featureNameString+(namePos++), ",");
441 strcpy(featureNameString+(namePos++), "\"");
442 strcpy(featureNameString+namePos, (char*) featureName[i].type);
443 namePos += lineTypeLen;
444 strcpy(featureNameString+namePos, "\"=>\"");
446 strcpy(featureNameString+namePos, (char *) featureName[i].value);
447 namePos += lineValueLen;
448 strcpy(featureNameString+(namePos++), "\"");
450 xmlFree(featureName[i].type);
451 xmlFree(featureName[i].value);
454 paramValues[5] = (const char *)featureNameString;
456 paramValues[6] = (const char *)feature.countryCode;
458 featureExtraTagString[0] = 0;
459 if (featureExtraTagLines)
464 for (i = 0; i < featureExtraTagLines; i++)
466 lineTypeLen = strlen((char *) featureExtraTag[i].type);
467 lineValueLen = strlen((char *) featureExtraTag[i].value);
468 if (namePos+lineTypeLen+lineValueLen+7 > MAX_FEATUREEXTRATAGSTRING)
470 fprintf(stderr, "feature extra tag too long: %s", (const char *)featureExtraTag[i].value);
473 if (namePos) strcpy(featureExtraTagString+(namePos++),",");
474 strcpy(featureExtraTagString+(namePos++), "\"");
475 strcpy(featureExtraTagString+namePos, (char *) featureExtraTag[i].type);
476 namePos += lineTypeLen;
477 strcpy(featureExtraTagString+namePos, "\"=>\"");
479 strcpy(featureExtraTagString+namePos, (char *) featureExtraTag[i].value);
480 namePos += lineValueLen;
481 strcpy(featureExtraTagString+(namePos++), "\"");
483 xmlFree(featureExtraTag[i].type);
484 xmlFree(featureExtraTag[i].value);
487 paramValues[7] = (const char *)featureExtraTagString;
489 if (strlen(feature.parentPlaceID) == 0)
490 paramValues[8] = "0";
492 paramValues[8] = (const char *)feature.parentPlaceID;
494 paramValues[9] = (const char *)feature.adminLevel;
495 paramValues[10] = (const char *)feature.houseNumber;
496 paramValues[11] = (const char *)feature.rankAddress;
497 paramValues[12] = (const char *)feature.rankSearch;
498 paramValues[13] = (const char *)feature.geometry;
499 if (strlen(paramValues[3]) && strlen(paramValues[13]))
501 if (verbose) fprintf(stderr, "placex_insert: %s\n", paramValues[0]);
502 res = PQexecPrepared(conn, "placex_insert", 14, paramValues, NULL, NULL, 0);
503 if (PQresultStatus(res) != PGRES_COMMAND_OK)
505 fprintf(stderr, "index_placex: INSERT failed: %s", PQerrorMessage(conn));
506 fprintf(stderr, "index_placex: INSERT failed: %s %s %s", paramValues[0], paramValues[1], paramValues[2]);
513 for (i = 0; i < featureAddressLines; i++)
515 // insert into place_address
516 paramValues[0] = (const char *)place_id;
517 paramValues[1] = (const char *)featureAddress[i].distance;
518 if (paramValues[1] == NULL || strlen(paramValues[1]) == 0) paramValues[1] = "0";
519 paramValues[2] = (const char *)featureAddress[i].type;
520 paramValues[3] = (const char *)featureAddress[i].id;
521 paramValues[4] = (const char *)featureAddress[i].key;
522 paramValues[5] = (const char *)featureAddress[i].value;
523 paramValues[6] = (const char *)featureAddress[i].isAddress;
524 if (verbose) fprintf(stderr, "placex_insert: %s %s\n", paramValues[2], paramValues[3]);
525 res = PQexecPrepared(conn, "place_addressline_insert", 7, paramValues, NULL, NULL, 0);
526 if (PQresultStatus(res) != PGRES_COMMAND_OK)
528 fprintf(stderr, "place_addressline_insert: INSERT failed: %s", PQerrorMessage(conn));
529 fprintf(stderr, "(%s,%s,%s,%s,%s,%s,%s)",paramValues[0],paramValues[1],paramValues[2],paramValues[3],paramValues[4],paramValues[5],paramValues[6]);
535 xmlFree(featureAddress[i].type);
536 xmlFree(featureAddress[i].id);
537 xmlFree(featureAddress[i].key);
538 xmlFree(featureAddress[i].value);
539 xmlFree(featureAddress[i].distance);
542 if (featureNameLines)
544 if (strlen(feature.parentPlaceID) > 0 && featureAddressLines == 0)
546 paramValues[0] = (const char *)place_id;
547 paramValues[1] = feature.parentPlaceID;
548 if (verbose) fprintf(stderr, "search_name_from_parent_insert: INSERT %s %s\n", paramValues[0], paramValues[1]);
549 res = PQexecPrepared(conn, "search_name_from_parent_insert", 2, paramValues, NULL, NULL, 0);
550 if (PQresultStatus(res) != PGRES_COMMAND_OK)
552 fprintf(stderr, "search_name_from_parent_insert: INSERT failed: %s", PQerrorMessage(conn));
560 paramValues[0] = (const char *)place_id;
561 if (verbose) fprintf(stderr, "search_name_insert: INSERT %s\n", paramValues[0]);
562 res = PQexecPrepared(conn, "search_name_insert", 1, paramValues, NULL, NULL, 0);
563 if (PQresultStatus(res) != PGRES_COMMAND_OK)
565 fprintf(stderr, "search_name_insert: INSERT failed: %s", PQerrorMessage(conn));
573 partionQueryName = xmlHashLookup2(partionTableTagsHash, feature.key, feature.value);
574 if (partionQueryName)
576 // insert into partition table
577 paramValues[0] = (const char *)place_id;
578 paramValues[1] = (const char *)feature.geometry;
579 res = PQexecPrepared(conn, partionQueryName, 2, paramValues, NULL, NULL, 0);
580 if (PQresultStatus(res) != PGRES_COMMAND_OK)
582 fprintf(stderr, "%s: INSERT failed: %s", partionQueryName, PQerrorMessage(conn));
592 for (i = 0; i < featureAddressLines; i++)
594 xmlFree(featureAddress[i].type);
595 xmlFree(featureAddress[i].id);
596 xmlFree(featureAddress[i].key);
597 xmlFree(featureAddress[i].value);
598 xmlFree(featureAddress[i].distance);
602 xmlFree(feature.placeID);
603 xmlFree(feature.type);
605 xmlFree(feature.key);
606 xmlFree(feature.value);
607 xmlFree(feature.rankAddress);
608 xmlFree(feature.rankSearch);
609 if (feature.countryCode) xmlFree(feature.countryCode);
610 if (feature.parentPlaceID) xmlFree(feature.parentPlaceID);
611 if (feature.parentType) xmlFree(feature.parentType);
612 if (feature.parentID) xmlFree(feature.parentID);
613 // if (feature.name) xmlFree(feature.name);
614 if (feature.adminLevel) xmlFree(feature.adminLevel);
615 if (feature.houseNumber) xmlFree(feature.houseNumber);
616 if (feature.geometry) xmlFree(feature.geometry);
618 // PQclear(resPlaceID);
622 static void processNode(xmlTextReaderPtr reader)
625 name = xmlTextReaderName(reader);
628 name = xmlStrdup(BAD_CAST "--");
631 switch (xmlTextReaderNodeType(reader))
633 case XML_READER_TYPE_ELEMENT:
634 StartElement(reader, name);
635 if (xmlTextReaderIsEmptyElement(reader))
636 EndElement(reader, name); /* No end_element for self closing tags! */
638 case XML_READER_TYPE_END_ELEMENT:
639 EndElement(reader, name);
641 case XML_READER_TYPE_TEXT:
642 case XML_READER_TYPE_CDATA:
643 case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
647 fprintf(stderr, "Unknown node type %d\n", xmlTextReaderNodeType(reader));
654 int nominatim_import(const char *conninfo, const char *partionTagsFilename, const char *filename)
656 xmlTextReaderPtr reader;
659 FILE * partionTagsFile;
660 char * partionQueryName;
661 char partionQuerySQL[1024];
663 conn = PQconnectdb(conninfo);
664 if (PQstatus(conn) != CONNECTION_OK)
666 fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(conn));
670 partionTableTagsHash = xmlHashCreate(200);
671 partionTableTagsHashDelete = xmlHashCreate(200);
673 partionTagsFile = fopen(partionTagsFilename, "rt");
674 if (!partionTagsFile)
676 fprintf(stderr, "Unable to read partition tags file: %s\n", partionTagsFilename);
680 char buffer[1024], osmkey[256], osmvalue[256];
682 while (fgets(buffer, sizeof(buffer), partionTagsFile) != NULL)
684 fields = sscanf( buffer, "%23s %63s", osmkey, osmvalue );
686 if ( fields <= 0 ) continue;
690 fprintf( stderr, "Error partition file\n");
693 partionQueryName = malloc(strlen("partition_insert_")+strlen(osmkey)+strlen(osmvalue)+2);
694 strcpy(partionQueryName, "partition_insert_");
695 strcat(partionQueryName, osmkey);
696 strcat(partionQueryName, "_");
697 strcat(partionQueryName, osmvalue);
699 strcpy(partionQuerySQL, "insert into place_classtype_");
700 strcat(partionQuerySQL, osmkey);
701 strcat(partionQuerySQL, "_");
702 strcat(partionQuerySQL, osmvalue);
703 strcat(partionQuerySQL, " (place_id, centroid) values ($1, ST_Centroid(st_setsrid($2, 4326)))");
705 res = PQprepare(conn, partionQueryName, partionQuerySQL, 2, NULL);
706 if (PQresultStatus(res) != PGRES_COMMAND_OK)
708 fprintf(stderr, "Failed to prepare %s: %s\n", partionQueryName, PQerrorMessage(conn));
712 xmlHashAddEntry2(partionTableTagsHash, BAD_CAST osmkey, BAD_CAST osmvalue, BAD_CAST partionQueryName);
714 partionQueryName = malloc(strlen("partition_delete_")+strlen(osmkey)+strlen(osmvalue)+2);
715 strcpy(partionQueryName, "partition_delete_");
716 strcat(partionQueryName, osmkey);
717 strcat(partionQueryName, "_");
718 strcat(partionQueryName, osmvalue);
720 strcpy(partionQuerySQL, "delete from place_classtype_");
721 strcat(partionQuerySQL, osmkey);
722 strcat(partionQuerySQL, "_");
723 strcat(partionQuerySQL, osmvalue);
724 strcat(partionQuerySQL, " where place_id = $1::integer");
726 res = PQprepare(conn, partionQueryName, partionQuerySQL, 1, NULL);
727 if (PQresultStatus(res) != PGRES_COMMAND_OK)
729 fprintf(stderr, "Failed to prepare %s: %s\n", partionQueryName, PQerrorMessage(conn));
733 xmlHashAddEntry2(partionTableTagsHashDelete, BAD_CAST osmkey, BAD_CAST osmvalue, BAD_CAST partionQueryName);
736 res = PQprepare(conn, "get_new_place_id",
737 "select nextval('seq_place')",
739 if (PQresultStatus(res) != PGRES_COMMAND_OK)
741 fprintf(stderr, "Failed to prepare get_new_place_id: %s\n", PQerrorMessage(conn));
745 res = PQprepare(conn, "get_place_id",
746 "select place_id from placex where osm_type = $1 and osm_id = $2 and class = $3 and type = $4",
748 if (PQresultStatus(res) != PGRES_COMMAND_OK)
750 fprintf(stderr, "Failed to prepare get_place_id: %s\n", PQerrorMessage(conn));
754 res = PQprepare(conn, "placex_insert",
755 "insert into placex (place_id,osm_type,osm_id,class,type,name,country_code,extratags,parent_place_id,admin_level,housenumber,rank_address,rank_search,geometry) "
756 "values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, st_setsrid($14, 4326))",
758 if (PQresultStatus(res) != PGRES_COMMAND_OK)
760 fprintf(stderr, "Failed to prepare placex_insert: %s\n", PQerrorMessage(conn));
764 res = PQprepare(conn, "search_name_insert",
765 "insert into search_name (place_id, search_rank, address_rank, country_code, name_vector, nameaddress_vector, centroid) "
766 "select place_id, rank_search, rank_address, country_code, make_keywords(name), "
767 "(select uniq(sort(array_agg(parent_search_name.name_vector))) from search_name as parent_search_name where place_id in "
768 "(select distinct address_place_id from place_addressline where place_addressline.place_id = $1 limit 1000)"
769 "), st_centroid(geometry) from placex "
770 "where place_id = $1",
773 if (PQresultStatus(res) != PGRES_COMMAND_OK)
775 fprintf(stderr, "Failed to prepare search_name_insert: %s\n", PQerrorMessage(conn));
779 res = PQprepare(conn, "search_name_from_parent_insert",
780 "insert into search_name (place_id, search_rank, address_rank, country_code, name_vector, nameaddress_vector, centroid) "
781 "select place_id, rank_search, rank_address, country_code, make_keywords(name), "
782 "(select uniq(sort(name_vector+nameaddress_vector)) from search_name as parent_search_name "
783 "where parent_search_name.place_id = $2 ), st_centroid(geometry) from placex "
784 "where place_id = $1",
786 if (PQresultStatus(res) != PGRES_COMMAND_OK)
788 fprintf(stderr, "Failed to prepare search_name_insert: %s\n", PQerrorMessage(conn));
792 res = PQprepare(conn, "place_addressline_insert",
793 "insert into place_addressline (place_id, address_place_id, fromarea, isaddress, distance, cached_rank_address) "
794 "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",
796 if (PQresultStatus(res) != PGRES_COMMAND_OK)
798 fprintf(stderr, "Failed to prepare place_addressline_insert: %s\n", PQerrorMessage(conn));
802 res = PQprepare(conn, "placex_delete",
803 "delete from placex where place_id = $1",
805 if (PQresultStatus(res) != PGRES_COMMAND_OK)
807 fprintf(stderr, "Failed to prepare placex_delete: %s\n", PQerrorMessage(conn));
811 res = PQprepare(conn, "search_name_delete",
812 "delete from search_name where place_id = $1",
814 if (PQresultStatus(res) != PGRES_COMMAND_OK)
816 fprintf(stderr, "Failed to prepare search_name_delete: %s\n", PQerrorMessage(conn));
820 res = PQprepare(conn, "place_addressline_delete",
821 "delete from place_addressline where place_id = $1",
823 if (PQresultStatus(res) != PGRES_COMMAND_OK)
825 fprintf(stderr, "Failed to prepare place_addressline_delete: %s\n", PQerrorMessage(conn));
831 reader = inputUTF8(filename);
835 fprintf(stderr, "Unable to open %s\n", filename);
839 ret = xmlTextReaderRead(reader);
843 ret = xmlTextReaderRead(reader);
847 fprintf(stderr, "%s : failed to parse\n", filename);
851 xmlFreeTextReader(reader);
852 xmlHashFree(partionTableTagsHash, NULL);
853 xmlHashFree(partionTableTagsHashDelete, NULL);