There are two patches that allow duplicate data to be added using osm2pgsql as shown by these two messages:
http://lists.openstreetmap.org/pipermail/dev/2008-August/011547.html http://lists.openstreetmap.org/pipermail/dev/2010-January/018291.html The first of these is now included in SVN (and in fact has been for a long time) but the second one is not. In the second message there is the suggestion that this should be made a command line option but it has never been implemented as such. To scratch my own itch I have created a patch that adds a command line option that can enable these two patches or default to them not enabled. My own personal need is to import great_britain.osm and then add ireland.osm both using data from geofabrik. Either file can be imported on its own and the only duplicate data comes from the tiny overlap of the two data sets. With this patch I can run osm2pgsql twice, the first of which is fast because there is no duplicate data to worry about and the second of which is fast because although there is duplicate data there are not as many objects in the second file. With this command line option it is faster to import now than it was with both patches applied. osm2pgsql --create [...] great_britain.osm osm2pgsql --append --allow-dups [...] ireland.osm
Index: output.h =================================================================== --- output.h (revision 27196) +++ output.h (working copy) @@ -27,6 +27,7 @@ int scale; /* scale for converting coordinates to fixed point */ int projection; /* SRS of projection */ int append; /* Append to existing data */ + int allow_dups; /* Allow duplicate data */ int slim; /* In slim mode */ int cache; /* Memory usable for cache in MB */ struct middle_t *mid; /* Mid storage to use */ Index: osm2pgsql.c =================================================================== --- osm2pgsql.c (revision 27196) +++ osm2pgsql.c (working copy) @@ -127,6 +127,8 @@ printf("\nOptions:\n"); printf(" -a|--append\t\tAdd the OSM file into the database without removing\n"); printf(" \t\texisting data.\n"); + printf(" -A|--allow-dups\tDuplicate data is accepted by deleting the existing\n"); + printf(" \t\tnode/way/relation before adding each new one.\n"); printf(" -b|--bbox\t\tApply a bounding box filter on the imported data\n"); printf(" \t\tMust be specified as: minlon,minlat,maxlon,maxlat\n"); printf(" \t\te.g. --bbox -0.5,51.25,0.5,51.75\n"); @@ -300,6 +302,7 @@ int main(int argc, char *argv[]) { int append=0; + int allow_dups=0; int create=0; int slim=0; int sanitize=0; @@ -341,6 +344,7 @@ int c, option_index = 0; static struct option long_options[] = { {"append", 0, 0, 'a'}, + {"allow-dups",0,0, 'A'}, {"bbox", 1, 0, 'b'}, {"create", 0, 0, 'c'}, {"database", 1, 0, 'd'}, @@ -384,6 +388,7 @@ switch (c) { case 'a': append=1; break; + case 'A': allow_dups=1; break; case 'b': osmdata.bbox=optarg; break; case 'c': create=1; break; case 'v': verbose=1; break; @@ -485,6 +490,7 @@ options.conninfo = conninfo; options.prefix = prefix; options.append = append; + options.allow_dups = allow_dups; options.slim = slim; options.projection = project_getprojinfo()->srs; options.scale = (projection==PROJ_LATLONG)?10000000:100; @@ -515,6 +521,8 @@ exit(EXIT_FAILURE); } + osmdata.allow_dups=options.allow_dups; + if (strcmp("auto", input_reader) != 0) { if (strcmp("libxml2", input_reader) == 0) { streamFile = &streamFileXML2; Index: osmtypes.h =================================================================== --- osmtypes.h (revision 27196) +++ osmtypes.h (working copy) @@ -42,6 +42,7 @@ filetypes_t filetype; actions_t action; int extra_attributes; + int allow_dups; // Bounding box to filter imported data const char *bbox; Index: parse-primitive.c =================================================================== --- parse-primitive.c (revision 27196) +++ parse-primitive.c (working copy) @@ -111,7 +111,12 @@ actions_t new_action = ACTION_NONE; char *action = extractAttribute(token, tokens, "action"); if( action == NULL ) - new_action = ACTION_CREATE; + { + if(osmdata->allow_dups) + new_action = ACTION_MODIFY; + else + new_action = ACTION_CREATE; + } else if( strcmp((char *)action, "modify") == 0 ) new_action = ACTION_MODIFY; else if( strcmp((char *)action, "delete") == 0 ) @@ -136,7 +141,11 @@ if (!strcmp(name, "osm")) { osmdata->filetype = FILETYPE_OSM; - osmdata->action = ACTION_CREATE; + + if(osmdata->allow_dups) + osmdata->action = ACTION_MODIFY; + else + osmdata->action = ACTION_CREATE; } else if (!strcmp(name, "osmChange")) { @@ -280,7 +289,10 @@ realloc_members(osmdata); } else if (!strcmp(name, "add") || !strcmp(name, "create")) { - osmdata->action = ACTION_MODIFY; // Turns all creates into modifies, makes it resiliant against inconsistant snapshots. + if(osmdata->allow_dups) + osmdata->action = ACTION_MODIFY; + else + osmdata->action = ACTION_CREATE; } else if (!strcmp(name, "modify")) { osmdata->action = ACTION_MODIFY; } else if (!strcmp(name, "delete")) { Index: parse-xml2.c =================================================================== --- parse-xml2.c (revision 27196) +++ parse-xml2.c (working copy) @@ -50,7 +50,12 @@ actions_t new_action = ACTION_NONE; xmlChar *action = xmlTextReaderGetAttribute( reader, BAD_CAST "action" ); if( action == NULL ) - new_action = ACTION_CREATE; + { + if(osmdata->allow_dups) + new_action = ACTION_MODIFY; + else + new_action = ACTION_CREATE; + } else if( strcmp((char *)action, "modify") == 0 ) new_action = ACTION_MODIFY; else if( strcmp((char *)action, "delete") == 0 ) @@ -73,7 +78,11 @@ if (xmlStrEqual(name, BAD_CAST "osm")) { osmdata->filetype = FILETYPE_OSM; - osmdata->action = ACTION_CREATE; + + if(osmdata->allow_dups) + osmdata->action = ACTION_MODIFY; + else + osmdata->action = ACTION_CREATE; } else if (xmlStrEqual(name, BAD_CAST "osmChange")) { @@ -205,7 +214,10 @@ xmlFree(xtype); } else if (xmlStrEqual(name, BAD_CAST "add") || xmlStrEqual(name, BAD_CAST "create")) { - osmdata->action = ACTION_MODIFY; // Turns all creates into modifies, makes it resiliant against inconsistant snapshots. + if(osmdata->allow_dups) + osmdata->action = ACTION_MODIFY; + else + osmdata->action = ACTION_CREATE; } else if (xmlStrEqual(name, BAD_CAST "modify")) { osmdata->action = ACTION_MODIFY; } else if (xmlStrEqual(name, BAD_CAST "delete")) {
Note: This patch was created against osm2pgsql-intarray since I use Postgres 8.3 which isn't supported by the newer osm2pgsql but I would imagine that it should apply against both. -- Andrew. ---------------------------------------------------------------------- Andrew M. Bishop a...@gedanken.demon.co.uk http://www.gedanken.org.uk/mapping/
_______________________________________________ dev mailing list dev@openstreetmap.org http://lists.openstreetmap.org/listinfo/dev