Index: pgsql.c =================================================================== --- pgsql.c (revision 27851) +++ pgsql.c (working copy) @@ -11,7 +11,8 @@ void escape(char *out, int len, const char *in) { /* Apply escaping of TEXT COPY data - Escape: backslash itself, newline, carriage return, and the current delimiter character (tab) + Escape: backslash itself, newline, carriage return, current delimiter character (tab), + and the single quote file:///usr/share/doc/postgresql-8.1.8/html/sql-copy.html */ int count = 0; @@ -29,6 +30,7 @@ case '\r': *out++ = '\\'; *out++ = '\r'; count+= 2; break; case '\t': *out++ = '\\'; *out++ = '\t'; count+= 2; break; // case 11: *out++ = '\\'; *out++ = '\v'; count+= 2; break; + case '\'': *out++ = '\\'; *out++ = '\''; count+= 2; break; default: *out++ = *in; count++; break; } in++; Index: output-pgsql.c =================================================================== --- output-pgsql.c (revision 27851) +++ output-pgsql.c (working copy) @@ -121,6 +121,7 @@ static int pgsql_delete_way_from_output(osmid_t osm_id); static int pgsql_delete_relation_from_output(osmid_t osm_id); static int pgsql_process_relation(osmid_t id, struct member *members, int member_count, struct keyval *tags, int exists); +static void pgsql_pause_copy(struct s_table *table); void read_style_file( const char *filename ) { @@ -406,8 +407,51 @@ updateItem(tags, "name", out); } +/* returns 1 if key is exported, -1 if key is deleted, 0 otherwise */ +static int key_is_in_export_list(char *key, enum OsmType list) +{ + for (int i = 0; i < exportListCount[list]; ++i) { + if (! strcmp(key, exportList[list][i].name)) { + if (exportList[list][i].flags & FLAG_DELETE) + return -1; + else + return 1; + } + } + return 0; +} +/* Attach the tags to the ways generated out of the member relations unless + they are already present */ +static void transfer_master_tags(struct keyval *tags, osmid_t member) +{ + struct keyval *p = tags->next; + char value[128]; + if (tags == NULL) + return; + pgsql_pause_copy(&tables[t_line]); + + while (p != tags) { + if (strcmp(p->key, "type") && strcmp(p->key, "route_master")) { + + int export_flag = key_is_in_export_list(p->key, OSMTYPE_WAY); + escape (value, 127, p->value); + + if (export_flag == 1) { + pgsql_exec(tables[t_line].sql_conn, PGRES_COMMAND_OK, + "UPDATE %s SET %s = \'%s\' WHERE %s IS NULL AND osm_id = -%d ;\n", + tables[t_line].name, p->key, value, p->key, member); + } else if (export_flag == 0) { + pgsql_exec(tables[t_line].sql_conn, PGRES_COMMAND_OK, + "UPDATE %s SET tags = tags || (\'%s\'=>\'%s\') WHERE NOT tags ? \'%s\' AND osm_id = -%d ;\n", + tables[t_line].name, p->key, value, p->key, member); + } + } + p = p->next; + } +} + static void pgsql_out_cleanup(void) { int i; @@ -1614,15 +1658,26 @@ for( i=0; imid->ways_get( members[i].id, &(xtags[count]), &(xnodes[count]), &(xcount[count]) ) ) + if( members[i].type == OSMTYPE_WAY ) + { + if( Options->mid->ways_get( members[i].id, &(xtags[count]), &(xnodes[count]), &(xcount[count]) ) ) + continue; + + xid[count] = members[i].id; + xrole[count] = members[i].role; + count++; + } + /* attach tags from a route_master (except those classifying it as a master) + to the ways generated out of the member relations */ + else if( ( members[i].type == OSMTYPE_RELATION ) && ( !strcmp( getItem(tags, "type"), "route_master" ) ) ) + { + transfer_master_tags( tags, members[i].id ); continue; - xid[count] = members[i].id; - xrole[count] = members[i].role; - count++; + } } xnodes[count] = NULL; xcount[count] = 0;