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

Reply via email to