Put checks in to verify that rows from postgres are sorted by ID.
[planetdump.git] / output_osm.c
index afb2b15..180d7c5 100644 (file)
@@ -1,10 +1,14 @@
-#include "output_osm.h"
 #include <string.h>
 #include <assert.h>
+#include <ctype.h>
+#include <inttypes.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
 
+#include "output_osm.h"
+
 #define INDENT "  "
 
 #ifdef USE_ICONV
@@ -66,8 +70,15 @@ const char *xmlescape(const char *in)
         } else if (*in == '"') {
             strcpy(&escape_tmp[len], "&quot;");
             len += strlen("&quot;");
-        } else if ((*in >= 0) && (*in < 32)) {
+        } else if ((*in == 9) || (*in == 10) || (*in == 13)) {
             len+=sprintf(&escape_tmp[len], "&#%d;", *in);
+        } else if ((*in >= 0) && (*in < 32)) {
+           /* These characters are not valid in XML output
+            * http://www.w3.org/TR/REC-xml/#NT-Char
+            * (tab, newline, carriage return are handled above)
+            */
+            escape_tmp[len] = '?';
+            len++;
         } else {
             escape_tmp[len] = *in;
             len++;
@@ -92,11 +103,11 @@ void osm_tags(struct keyval *tags)
    resetList(tags);
 }
 
-void osm_changeset(int id, const char *user, const char *created_at, const char *closed_at, 
+void osm_changeset(int64_t id, const char *user, const char *created_at, const char *closed_at, 
            int num_changes, int has_bbox, 
                   long double min_lat, long double max_lat, long double min_lon, long double max_lon, 
                   int open, struct keyval *tags) {
-  printf(INDENT "<changeset id=\"%d\" created_at=\"%s\" num_changes=\"%d\" ", id, created_at, num_changes);
+  printf(INDENT "<changeset id=\"%"PRId64"\" created_at=\"%s\" num_changes=\"%d\" ", id, created_at, num_changes);
   if (open) {
     printf("open=\"true\" ");
   } else {
@@ -116,27 +127,27 @@ void osm_changeset(int id, const char *user, const char *created_at, const char
   }
 }
 
-void osm_node(int id, long double lat, long double lon, struct keyval *tags, const char *ts, const char *user, int version, int changeset)
+void osm_node(int64_t id, long double lat, long double lon, struct keyval *tags, const char *ts, const char *user, int version, int changeset)
 {
   if (listHasData(tags)) {
-    printf(INDENT "<node id=\"%d\" lat=\"%.7Lf\" lon=\"%.7Lf\" "
+    printf(INDENT "<node id=\"%"PRId64"\" lat=\"%.7Lf\" lon=\"%.7Lf\" "
           "timestamp=\"%s\" version=\"%d\" changeset=\"%d\"%s>\n", 
           id, lat, lon, ts, version, changeset, user);
     osm_tags(tags);
     printf(INDENT "</node>\n");
   } else {
-    printf(INDENT "<node id=\"%d\" lat=\"%.7Lf\" lon=\"%.7Lf\" "
+    printf(INDENT "<node id=\"%"PRId64"\" lat=\"%.7Lf\" lon=\"%.7Lf\" "
           "timestamp=\"%s\" version=\"%d\" changeset=\"%d\"%s/>\n", 
           id, lat, lon, ts, version, changeset, user);
   }
 }
 
-void osm_way(int id, struct keyval *nodes, struct keyval *tags, const char *ts, const char *user, int version, int changeset)
+void osm_way(int64_t id, struct keyval *nodes, struct keyval *tags, const char *ts, const char *user, int version, int changeset)
 {
   struct keyval *p;
   
   if (listHasData(tags) || listHasData(nodes)) {
-    printf(INDENT "<way id=\"%d\" timestamp=\"%s\" version=\"%d\" changeset=\"%d\"%s>\n", id, ts, version, changeset, user);
+    printf(INDENT "<way id=\"%"PRId64"\" timestamp=\"%s\" version=\"%d\" changeset=\"%d\"%s>\n", id, ts, version, changeset, user);
     while ((p = popItem(nodes)) != NULL) {
       printf(INDENT INDENT "<nd ref=\"%s\" />\n", p->value);
       freeItem(p);
@@ -144,16 +155,16 @@ void osm_way(int id, struct keyval *nodes, struct keyval *tags, const char *ts,
     osm_tags(tags);
     printf(INDENT "</way>\n");
   } else {
-    printf(INDENT "<way id=\"%d\" timestamp=\"%s\" version=\"%d\" changeset=\"%d\"%s/>\n", id, ts, version, changeset, user);
+    printf(INDENT "<way id=\"%"PRId64"\" timestamp=\"%s\" version=\"%d\" changeset=\"%d\"%s/>\n", id, ts, version, changeset, user);
   }
 }
 
-void osm_relation(int id, struct keyval *members, struct keyval *roles, struct keyval *tags, const char *ts, const char *user, int version, int changeset)
+void osm_relation(int64_t id, struct keyval *members, struct keyval *roles, struct keyval *tags, const char *ts, const char *user, int version, int changeset)
 {
   struct keyval *p, *q;
   
   if (listHasData(tags) || listHasData(members)) {
-    printf(INDENT "<relation id=\"%d\" timestamp=\"%s\" version=\"%d\" changeset=\"%d\"%s>\n", id, ts, version, changeset, user);
+    printf(INDENT "<relation id=\"%"PRId64"\" timestamp=\"%s\" version=\"%d\" changeset=\"%d\"%s>\n", id, ts, version, changeset, user);
     while (((p = popItem(members)) != NULL) && ((q = popItem(roles)) != NULL)) {
       char *m_type = p->key;
       char *i; 
@@ -167,7 +178,7 @@ void osm_relation(int id, struct keyval *members, struct keyval *roles, struct k
     osm_tags(tags);
     printf(INDENT "</relation>\n");
   } else {
-    printf(INDENT "<relation id=\"%d\" timestamp=\"%s\" version=\"%d\" changeset=\"%d\"%s/>\n", id, ts, version, changeset, user);
+    printf(INDENT "<relation id=\"%"PRId64"\" timestamp=\"%s\" version=\"%d\" changeset=\"%d\"%s/>\n", id, ts, version, changeset, user);
   }
 }
 
@@ -196,7 +207,10 @@ void osm_header() {
 
   printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
   printf("<osm version=\"0.6\" generator=\"OpenStreetMap planet.c\" "
-        "timestamp=\"%s\">\n", timestamp);
+        "copyright=\"OpenStreetMap and contributors\" "
+         "attribution=\"http://www.openstreetmap.org/copyright/\" "
+         "license=\"http://opendatacommons.org/licenses/odbl/1.0/\" "
+         "timestamp=\"%s\">\n", timestamp);
   printf(INDENT "<bound box=\"-90,-180,90,180\" "
         "origin=\"http://www.openstreetmap.org/api/0.6\" />\n");
 }