void middle_pgsql_t::ways_set(osmid_t way_id, const idlist_t &nds, const taglist_t &tags) { copy_buffer.reserve(nds.size() * 10 + tags.size() * 24 + 64); bool copy = way_table->copyMode; char delim = copy ? '\t' : '\0'; // Three params: id, nodes, tags */ const char *paramValues[4] = { copy_buffer.c_str(), }; copy_buffer = std::to_string(way_id); copy_buffer += delim; paramValues[1] = paramValues[0] + copy_buffer.size(); buffer_store_nodes(nds); copy_buffer += delim; if (tags.size() == 0) { paramValues[2] = nullptr; copy_buffer += "\\N"; } else { paramValues[2] = paramValues[0] + copy_buffer.size(); buffer_store_tags(tags, copy); } if (copy) { copy_buffer += '\n'; pgsql_CopyData(__FUNCTION__, way_table->sql_conn, copy_buffer); } else { buffer_correct_params(paramValues, 3); pgsql_execPrepared(way_table->sql_conn, "insert_way", 3, (const char * const *)paramValues, PGRES_COMMAND_OK); } }
void middle_pgsql_t::local_nodes_set(osmid_t id, double lat, double lon, const taglist_t &tags) { copy_buffer.reserve(tags.size() * 24 + 64); bool copy = node_table->copyMode; char delim = copy ? '\t' : '\0'; const char *paramValues[4] = { copy_buffer.c_str(), }; copy_buffer = std::to_string(id); copy_buffer += delim; #ifdef FIXED_POINT ramNode n(lon, lat); paramValues[1] = paramValues[0] + copy_buffer.size(); copy_buffer += std::to_string(n.int_lat()); copy_buffer += delim; paramValues[2] = paramValues[0] + copy_buffer.size(); copy_buffer += std::to_string(n.int_lon()); copy_buffer += delim; #else paramValues[1] = paramValues[0] + copy_buffer.size(); copy_buffer += std::to_string(lat); copy_buffer += delim; paramValues[2] = paramValues[0] + copy_buffer.size(); copy_buffer += std::to_string(lon); copy_buffer += delim; #endif if (tags.size() == 0) { paramValues[3] = nullptr; copy_buffer += "\\N"; } else { paramValues[3] = paramValues[0] + copy_buffer.size(); buffer_store_tags(tags, copy); } if (copy) { copy_buffer += '\n'; pgsql_CopyData(__FUNCTION__, node_table->sql_conn, copy_buffer); } else { buffer_correct_params(paramValues, 4); pgsql_execPrepared(node_table->sql_conn, "insert_node", 4, (const char * const *)paramValues, PGRES_COMMAND_OK); } }
void table_t::write_tags_column(const taglist_t &tags, std::string& values, const std::vector<bool> &used) { //iterate through the list of tags, first one is always null bool added = false; for (size_t i = 0; i < tags.size(); ++i) { const tag_t& xtag = tags[i]; //skip z_order tag and keys which have their own column if (used[i] || ("z_order" == xtag.key)) continue; //hstore ASCII representation looks like "key"=>"value" if(added) values.push_back(','); escape4hstore(xtag.key.c_str(), values); values.append("=>"); escape4hstore(xtag.value.c_str(), values); //we did at least one so we need commas from here on out added = true; } //finish the hstore column by placing a TAB into the data stream values.push_back('\t'); }
/* COPY planet_osm (osm_id, name, place, landuse, leisure, "natural", man_made, waterway, highway, railway, amenity, tourism, learning, bu ilding, bridge, layer, way) FROM stdin; 198497 Bedford Road \N \N \N \N \N \N residential \N \N \N \N \N \N \N 0102000020E610000004000000452BF702B342D5BF1C60E63BF8DF49406B9C4D470037D5BF5471E316F3DF4940DFA815A6EF35D5BF9AE95E27F5DF4940B41EB E4C1421D5BF24D06053E7DF4940 212696 Oswald Road \N \N \N \N \N \N minor \N \N \N \N \N \N \N 0102000020E610000004000000467D923B6C22D5BFA359D93EE4DF4940B3976DA7AD11D5BF84BBB376DBDF4940997FF44D9A06D5BF4223D8B8FEDF49404D158C4AEA04D 5BF5BB39597FCDF4940 */ int output_pgsql_t::pgsql_out_way(osmid_t id, taglist_t &outtags, const nodelist_t &nodes, int polygon, int roads) { /* Split long ways after around 1 degree or 100km */ double split_at; if (m_options.projection->target_latlon()) split_at = 1; else split_at = 100 * 1000; char tmp[32]; auto wkbs = builder.get_wkb_split(nodes, polygon, split_at); for (const auto& wkb: wkbs) { /* FIXME: there should be a better way to detect polygons */ if (wkb.is_polygon()) { expire.from_nodes_poly(nodes, id); if ((wkb.area > 0.0) && m_enable_way_area) { snprintf(tmp, sizeof(tmp), "%g", wkb.area); outtags.push_override(tag_t("way_area", tmp)); } m_tables[t_poly]->write_row(id, outtags, wkb.geom); } else { expire.from_nodes_line(nodes); m_tables[t_line]->write_row(id, outtags, wkb.geom); if (roads) m_tables[t_roads]->write_row(id, outtags, wkb.geom); } } return 0; }
/* COPY planet_osm (osm_id, name, place, landuse, leisure, "natural", man_made, waterway, highway, railway, amenity, tourism, learning, bu ilding, bridge, layer, way) FROM stdin; 198497 Bedford Road \N \N \N \N \N \N residential \N \N \N \N \N \N \N 0102000020E610000004000000452BF702B342D5BF1C60E63BF8DF49406B9C4D470037D5BF5471E316F3DF4940DFA815A6EF35D5BF9AE95E27F5DF4940B41EB E4C1421D5BF24D06053E7DF4940 212696 Oswald Road \N \N \N \N \N \N minor \N \N \N \N \N \N \N 0102000020E610000004000000467D923B6C22D5BFA359D93EE4DF4940B3976DA7AD11D5BF84BBB376DBDF4940997FF44D9A06D5BF4223D8B8FEDF49404D158C4AEA04D 5BF5BB39597FCDF4940 */ int output_pgsql_t::pgsql_out_way(osmid_t id, taglist_t &outtags, const nodelist_t &nodes, int polygon, int roads) { /* Split long ways after around 1 degree or 100km */ double split_at; if (m_options.projection->get_proj_id() == PROJ_LATLONG) split_at = 1; else split_at = 100 * 1000; tag_t *areatag = 0; auto wkbs = builder.get_wkb_split(nodes, polygon, split_at); for (const auto& wkb: wkbs) { /* FIXME: there should be a better way to detect polygons */ if (wkb.is_polygon()) { expire->from_nodes_poly(nodes, id); if ((wkb.area > 0.0) && m_enable_way_area) { char tmp[32]; snprintf(tmp, sizeof(tmp), "%g", wkb.area); if (!areatag) { outtags.push_dedupe(tag_t("way_area", tmp)); areatag = outtags.find("way_area"); } else areatag->value = tmp; } m_tables[t_poly]->write_row(id, outtags, wkb.geom); } else { expire->from_nodes_line(nodes); m_tables[t_line]->write_row(id, outtags, wkb.geom); if (roads) m_tables[t_roads]->write_row(id, outtags, wkb.geom); } } return 0; }
/* write an hstore column to the database */ void table_t::write_hstore_columns(const taglist_t &tags, std::string& values) { //iterate over all configured hstore columns in the options for(hstores_t::const_iterator hstore_column = hstore_columns.begin(); hstore_column != hstore_columns.end(); ++hstore_column) { bool added = false; //iterate through the list of tags, first one is always null for (taglist_t::const_iterator xtags = tags.begin(); xtags != tags.end(); ++xtags) { //check if the tag's key starts with the name of the hstore column if(xtags->key.compare(0, hstore_column->size(), *hstore_column) == 0) { //generate the short key name, somehow pointer arithmetic works against the key string... const char* shortkey = xtags->key.c_str() + hstore_column->size(); //and pack the shortkey with its value into the hstore //hstore ASCII representation looks like "key"=>"value" if(added) values.push_back(','); escape4hstore(shortkey, values); values.append("=>"); escape4hstore(xtags->value.c_str(), values); //we did at least one so we need commas from here on out added = true; } } //if you found not matching tags write a NUL if(!added) values.append("\\N"); //finish the column off with a tab values.push_back('\t'); } }
int output_pgsql_t::relation_add(osmid_t id, const memberlist_t &members, const taglist_t &tags) { const std::string *type = tags.get("type"); /* Must have a type field or we ignore it */ if (!type) return 0; /* Only a limited subset of type= is supported, ignore other */ if ( (*type != "route") && (*type != "multipolygon") && (*type != "boundary")) return 0; return pgsql_process_relation(id, members, tags, 0); }
void table_t::write_row(const osmid_t id, const taglist_t &tags, const std::string &geom) { //add the osm id buffer.append((single_fmt % id).str()); buffer.push_back('\t'); // used to remember which columns have been written out already. std::vector<bool> used; if (hstore_mode != HSTORE_NONE) used.assign(tags.size(), false); //get the regular columns' values write_columns(tags, buffer, hstore_mode == HSTORE_NORM?&used:nullptr); //get the hstore columns' values write_hstore_columns(tags, buffer); //get the key value pairs for the tags column if (hstore_mode != HSTORE_NONE) write_tags_column(tags, buffer, used); //give the geometry an srid buffer.append("SRID="); buffer.append(srid); buffer.push_back(';'); //add the geometry buffer.append(geom); //we need \n because we are copying from stdin buffer.push_back('\n'); //tell the db we are copying if for some reason we arent already if (!copyMode) { pgsql_exec_simple(sql_conn, PGRES_COPY_IN, copystr); copyMode = true; } //send all the data to postgres if(buffer.length() > BUFFER_SEND_SIZE) { pgsql_CopyData(name.c_str(), sql_conn, buffer); buffer.clear(); } }
void table_t::write_columns(const taglist_t &tags, string& values, std::vector<bool> *used) { //for each column for(columns_t::const_iterator column = columns.begin(); column != columns.end(); ++column) { int idx; if ((idx = tags.indexof(column->first)) >= 0) { escape_type(tags[idx].value, column->second, values); //remember we already used this one so we cant use again later in the hstore column if (used) (*used)[idx] = true; } else values.append("\\N"); values.push_back('\t'); } }
void place_tag_processor::process_tags(const taglist_t &tags) { bool placeadmin = false; bool placehouse = false; bool placebuilding = false; const tag_t *place = 0; const tag_t *junction = 0; const tag_t *landuse = 0; bool isnamed = false; bool isinterpolation = false; const std::string *house_nr = 0; const std::string *conscr_nr = 0; const std::string *street_nr = 0; clear(); src = &tags; for (const auto& item: tags) { if (boost::ends_with(item.key, "source")) { // ignore } else if (item.key == "name:prefix" || item.key == "name:botanical" || boost::ends_with(item.key, "wikidata")) { extratags.push_back(&item); } else if (item.key == "ref" || item.key == "int_ref" || item.key == "nat_ref" || item.key == "reg_ref" || item.key == "loc_ref" || item.key == "old_ref" || item.key == "iata" || item.key == "icao" || item.key == "operator" || item.key == "pcode" || boost::starts_with(item.key, "pcode:")) { names.push_back(&item); } else if (item.key == "name" || boost::starts_with(item.key, "name:") || item.key == "int_name" || boost::starts_with(item.key, "int_name:") || item.key == "nat_name" || boost::starts_with(item.key, "nat_name:") || item.key == "reg_name" || boost::starts_with(item.key, "reg_name:") || item.key == "loc_name" || boost::starts_with(item.key, "loc_name:") || item.key == "old_name" || boost::starts_with(item.key, "old_name:") || item.key == "alt_name" || boost::starts_with(item.key, "alt_name:") || boost::starts_with(item.key, "alt_name_") || item.key == "official_name" || boost::starts_with(item.key, "official_name:") || item.key == "place_name" || boost::starts_with(item.key, "place_name:") || item.key == "short_name" || boost::starts_with(item.key, "short_name:") || item.key == "brand") { names.push_back(&item); isnamed = true; } else if (item.key == "addr:housename") { names.push_back(&item); placehouse = true; } else if (item.key == "emergency") { if (item.value != "fire_hydrant" && item.value != "yes" && item.value != "no") places.push_back(item); } else if (item.key == "tourism" || item.key == "historic" || item.key == "military") { if (item.value != "no" && item.value != "yes") places.push_back(item); } else if (item.key == "natural") { if (item.value != "no" && item.value != "yes" && item.value != "coastline") places.push_back(item); } else if (item.key == "landuse") { if (item.value == "cemetry") places.push_back(item); else landuse = &item; } else if (item.key == "highway") { if (item.value == "footway") { auto *footway = tags.get("footway"); if (footway == nullptr || *footway != "sidewalk") places.push_back(item); } else if (item.value != "no" && item.value != "turning_circle" && item.value != "mini_roundabout" && item.value != "noexit" && item.value != "crossing") places.push_back(item); } else if (item.key == "railway") { if (item.value != "level_crossing" && item.value != "no") places.push_back(item); } else if (item.key == "man_made") { if (item.value != "survey_point" && item.value != "cutline") places.push_back(item); } else if (item.key == "aerialway") { if (item.value != "pylon" && item.value != "no") places.push_back(item); } else if (item.key == "boundary") { if (item.value == "administrative") placeadmin = true; places.push_back(item); } else if (item.key == "aeroway" || item.key == "amenity" || item.key == "boundary" || item.key == "bridge" || item.key == "craft" || item.key == "leisure" || item.key == "office" || item.key == "shop" || item.key == "tunnel" || item.key == "mountain_pass") { if (item.value != "no") { places.push_back(item); } } else if (item.key == "waterway") { if (item.value != "riverbank") places.push_back(item); } else if (item.key == "place") { place = &item; } else if (item.key == "junction") { junction = &item; } else if (item.key == "addr:interpolation") { housenumber.clear(); escape(item.value, housenumber); isinterpolation = true; } else if (item.key == "addr:housenumber") { house_nr = &item.value; placehouse = true; } else if (item.key == "addr:conscriptionnumber") { conscr_nr = &item.value; placehouse = true; } else if (item.key == "addr:streetnumber") { street_nr = &item.value; placehouse = true; } else if (item.key == "addr:street") { street = &item.value; } else if (item.key == "addr:place") { addr_place = &item.value; } else if (item.key == "postal_code" || item.key == "postcode" || item.key == "addr:postcode" || item.key == "tiger:zip_left" || item.key == "tiger:zip_right") { if (!postcode) postcode = &item.value; } else if (item.key == "country_code" || item.key == "ISO3166-1" || item.key == "is_in:country_code" || item.key == "addr:country" || item.key == "addr:country_code") { if (item.value.length() == 2) countrycode = &item.value; } else if (boost::starts_with(item.key, "addr:") || item.key == "is_in" || boost::starts_with(item.key, "is_in:") || item.key == "tiger:county") { address.push_back(&item); } else if (item.key == "admin_level") { admin_level = atoi(item.value.c_str()); if (admin_level <= 0 || admin_level > 100) admin_level = 100; } else if (item.key == "tracktype" || item.key == "traffic_calming" || item.key == "service" || item.key == "cuisine" || item.key == "capital" || item.key == "dispensing" || item.key == "religion" || item.key == "denomination" || item.key == "sport" || item.key == "internet_access" || item.key == "lanes" || item.key == "surface" || item.key == "smoothness" || item.key == "width" || item.key == "est_width" || item.key == "incline" || item.key == "opening_hours" || item.key == "collection_times" || item.key == "service_times" || item.key == "disused" || item.key == "wheelchair" || item.key == "sac_scale" || item.key == "trail_visibility" || item.key == "mtb:scale" || item.key == "mtb:description" || item.key == "wood" || item.key == "drive_through" || item.key == "drive_in" || item.key == "access" || item.key == "vehicle" || item.key == "bicyle" || item.key == "foot" || item.key == "goods" || item.key == "hgv" || item.key == "motor_vehicle" || item.key == "motor_car" || boost::starts_with(item.key, "access:") || boost::starts_with(item.key, "contact:") || boost::starts_with(item.key, "drink:") || item.key == "oneway" || item.key == "date_on" || item.key == "date_off" || item.key == "day_on" || item.key == "day_off" || item.key == "hour_on" || item.key == "hour_off" || item.key == "maxweight" || item.key == "maxheight" || item.key == "maxspeed" || item.key == "fee" || item.key == "toll" || boost::starts_with(item.key, "toll:") || item.key == "charge" || item.key == "population" || item.key == "description" || item.key == "image" || item.key == "attribution" || item.key == "fax" || item.key == "email" || item.key == "url" || item.key == "website" || item.key == "phone" || item.key == "real_ale" || item.key == "smoking" || item.key == "food" || item.key == "camera" || item.key == "brewery" || item.key == "locality" || item.key == "wikipedia" || boost::starts_with(item.key, "wikipedia:")) { extratags.push_back(&item); } else if (item.key == "building") { placebuilding = true; } } // skip some tags, if they don't have a proper name (ref doesn't count) if (!isnamed) { if (!places.empty()) places.erase(std::remove_if(places.begin(), places.end(), UnnamedPredicate()), places.end()); } if (isinterpolation) places.push_back(tag_t("place", "houses")); if (place) { if (isinterpolation || (placeadmin && place ->value != "island" && place ->value != "islet")) extratags.push_back(place); else places.push_back(*place); } if (isnamed && places.empty()) { if (junction) places.push_back(*junction); else if (landuse) places.push_back(*landuse); } if (places.empty()) { if (placebuilding && (!names.empty() || placehouse || postcode)) { places.push_back(tag_t("building", "yes")); } else if (placehouse) { places.push_back(tag_t("place", "house")); } else if (postcode) { places.push_back(tag_t("place", "postcode")); } } // housenumbers if (!isinterpolation) { if (street_nr && conscr_nr) { housenumber.clear(); escape(*conscr_nr, housenumber); housenumber.append("/"); escape(*street_nr, housenumber); } else if (conscr_nr) { housenumber.clear(); escape(*conscr_nr, housenumber); } else if (street_nr) { housenumber.clear(); escape(*street_nr, housenumber); } else if (house_nr) { housenumber.clear(); escape(*house_nr, housenumber); } } }
int output_gazetteer_t::process_relation(osmid_t id, const memberlist_t &members, const taglist_t &tags) { const std::string *type = tags.get("type"); if (!type) { delete_unused_full('R', id); return 0; } int cmp_waterway = type->compare("waterway"); if (*type == "associatedStreet" || !(*type == "boundary" || *type == "multipolygon" || !cmp_waterway)) { delete_unused_full('R', id); return 0; } places.process_tags(tags); if (m_options.append) delete_unused_classes('R', id); /* Are we interested in this item? */ if (!places.has_data()) return 0; /* get the boundary path (ways) */ idlist_t xid2; for (const auto& member: members) { /* only interested in ways */ if (member.type == OSMTYPE_WAY) xid2.push_back(member.id); } if (xid2.empty()) { if (m_options.append) delete_unused_full('R', id); return 0; } multitaglist_t xtags; multinodelist_t xnodes; idlist_t xid; m_mid->ways_get_list(xid2, xid, xtags, xnodes); if (cmp_waterway) { auto geoms = builder.build_both(xnodes, 1, 1, 1000000, id); for (const auto& geom: geoms) { if (geom.is_polygon()) { places.copy_out('R', id, geom.geom, buffer); flush_place_buffer(); } else { /* add_polygon_error('R', id, "boundary", "adminitrative", &names, countrycode, wkt); */ } } } else { /* waterways result in multilinestrings */ auto geom = builder.build_multilines(xnodes, id); if (geom.valid()) { places.copy_out('R', id, geom.geom, buffer); flush_place_buffer(); } } return 0; }
void middle_pgsql_t::relations_set(osmid_t id, const memberlist_t &members, const taglist_t &tags) { taglist_t member_list; char buf[64]; idlist_t all_parts, node_parts, way_parts, rel_parts; all_parts.reserve(members.size()); node_parts.reserve(members.size()); way_parts.reserve(members.size()); rel_parts.reserve(members.size()); for (memberlist_t::const_iterator it = members.begin(); it != members.end(); ++it) { char type = 0; switch (it->type) { case OSMTYPE_NODE: node_parts.push_back(it->id); type = 'n'; break; case OSMTYPE_WAY: way_parts.push_back(it->id); type = 'w'; break; case OSMTYPE_RELATION: rel_parts.push_back(it->id); type = 'r'; break; default: fprintf(stderr, "Internal error: Unknown member type %d\n", it->type); util::exit_nicely(); } sprintf( buf, "%c%" PRIdOSMID, type, it->id ); member_list.push_back(tag_t(buf, it->role)); } all_parts.insert(all_parts.end(), node_parts.begin(), node_parts.end()); all_parts.insert(all_parts.end(), way_parts.begin(), way_parts.end()); all_parts.insert(all_parts.end(), rel_parts.begin(), rel_parts.end()); copy_buffer.reserve(all_parts.size() * 10 + member_list.size() * 24 + tags.size() * 24 + 64); // Params: id, way_off, rel_off, parts, members, tags */ const char *paramValues[6] = { copy_buffer.c_str(), }; bool copy = rel_table->copyMode; char delim = copy ? '\t' : '\0'; copy_buffer = std::to_string(id); copy_buffer+= delim; paramValues[1] = paramValues[0] + copy_buffer.size(); copy_buffer += std::to_string(node_parts.size()); copy_buffer+= delim; paramValues[2] = paramValues[0] + copy_buffer.size(); copy_buffer += std::to_string(node_parts.size() + way_parts.size()); copy_buffer+= delim; paramValues[3] = paramValues[0] + copy_buffer.size(); buffer_store_nodes(all_parts); copy_buffer+= delim; if (member_list.size() == 0) { paramValues[4] = nullptr; copy_buffer += "\\N"; } else { paramValues[4] = paramValues[0] + copy_buffer.size(); buffer_store_tags(member_list, copy); } copy_buffer+= delim; if (tags.size() == 0) { paramValues[5] = nullptr; copy_buffer += "\\N"; } else { paramValues[5] = paramValues[0] + copy_buffer.size(); buffer_store_tags(tags, copy); } if (copy) { copy_buffer+= '\n'; pgsql_CopyData(__FUNCTION__, rel_table->sql_conn, copy_buffer); } else { buffer_correct_params(paramValues, 6); pgsql_execPrepared(rel_table->sql_conn, "insert_rel", 6, (const char * const *)paramValues, PGRES_COMMAND_OK); } }
unsigned lua_tagtransform_t::filter_rel_member_tags( taglist_t const &rel_tags, multitaglist_t const &members_tags, rolelist_t const &member_roles, int *member_superseded, int *make_boundary, int *make_polygon, int *roads, export_list const &, taglist_t &out_tags, bool) { lua_getglobal(L, m_rel_mem_func.c_str()); lua_newtable(L); /* relations key value table */ for (const auto &rel_tag : rel_tags) { lua_pushstring(L, rel_tag.key.c_str()); lua_pushstring(L, rel_tag.value.c_str()); lua_rawset(L, -3); } lua_newtable(L); /* member tags table */ int idx = 1; for (const auto &member_tags : members_tags) { lua_pushnumber(L, idx++); lua_newtable(L); /* member key value table */ for (const auto &member_tag : member_tags) { lua_pushstring(L, member_tag.key.c_str()); lua_pushstring(L, member_tag.value.c_str()); lua_rawset(L, -3); } lua_rawset(L, -3); } lua_newtable(L); /* member roles table */ for (size_t i = 0; i < member_roles.size(); i++) { lua_pushnumber(L, i + 1); lua_pushstring(L, member_roles[i]); lua_rawset(L, -3); } lua_pushnumber(L, member_roles.size()); if (lua_pcall(L, 4, 6, 0)) { fprintf( stderr, "Failed to execute lua function for relation tag processing: %s\n", lua_tostring(L, -1)); /* lua function failed */ return 1; } *roads = (int)lua_tointeger(L, -1); lua_pop(L, 1); *make_polygon = (int)lua_tointeger(L, -1); lua_pop(L, 1); *make_boundary = (int)lua_tointeger(L, -1); lua_pop(L, 1); lua_pushnil(L); for (size_t i = 0; i < members_tags.size(); i++) { if (lua_next(L, -2)) { member_superseded[i] = (int)lua_tointeger(L, -1); lua_pop(L, 1); } else { fprintf(stderr, "Failed to read member_superseded from lua function\n"); } } lua_pop(L, 2); lua_pushnil(L); while (lua_next(L, -2) != 0) { const char *key = lua_tostring(L, -2); const char *value = lua_tostring(L, -1); out_tags.push_back(tag_t(key, value)); lua_pop(L, 1); } lua_pop(L, 1); unsigned filter = (unsigned)lua_tointeger(L, -1); lua_pop(L, 1); return filter; }
bool lua_tagtransform_t::filter_tags(osmium::OSMObject const &o, int *polygon, int *roads, export_list const &, taglist_t &out_tags, bool) { switch (o.type()) { case osmium::item_type::node: lua_getglobal(L, m_node_func.c_str()); break; case osmium::item_type::way: lua_getglobal(L, m_way_func.c_str()); break; case osmium::item_type::relation: lua_getglobal(L, m_rel_func.c_str()); break; default: throw std::runtime_error("Unknown OSM type"); } lua_newtable(L); /* key value table */ lua_Integer sz = 0; for (auto const &t : o.tags()) { lua_pushstring(L, t.key()); lua_pushstring(L, t.value()); lua_rawset(L, -3); ++sz; } if (m_extra_attributes && o.version() > 0) { taglist_t tags; tags.add_attributes(o); for (auto const &t : tags) { lua_pushstring(L, t.key.c_str()); lua_pushstring(L, t.value.c_str()); lua_rawset(L, -3); } sz += tags.size(); } lua_pushinteger(L, sz); if (lua_pcall(L, 2, (o.type() == osmium::item_type::way) ? 4 : 2, 0)) { fprintf(stderr, "Failed to execute lua function for basic tag processing: %s\n", lua_tostring(L, -1)); /* lua function failed */ return 1; } if (o.type() == osmium::item_type::way) { if (roads) { *roads = (int)lua_tointeger(L, -1); } lua_pop(L, 1); if (polygon) { *polygon = (int)lua_tointeger(L, -1); } lua_pop(L, 1); } lua_pushnil(L); while (lua_next(L, -2) != 0) { const char *key = lua_tostring(L, -2); const char *value = lua_tostring(L, -1); out_tags.emplace_back(key, value); lua_pop(L, 1); } bool filter = lua_tointeger(L, -2); lua_pop(L, 2); return filter; }
int output_gazetteer_t::process_relation(osmid_t id, const memberlist_t &members, const taglist_t &tags) { const std::string *type = tags.get("type"); if (!type) { delete_unused_full('R', id); return 0; } int cmp_waterway = type->compare("waterway"); if (*type == "associatedStreet" || !(*type == "boundary" || *type == "multipolygon" || !cmp_waterway)) { delete_unused_full('R', id); return 0; } places.process_tags(tags); if (m_options.append) delete_unused_classes('R', id); /* Are we interested in this item? */ if (!places.has_data()) return 0; /* get the boundary path (ways) */ idlist_t xid2; for (memberlist_t::const_iterator it = members.begin(); it != members.end(); ++it) { /* only interested in ways */ if (it->type == OSMTYPE_WAY) xid2.push_back(it->id); } if (xid2.empty()) { if (m_options.append) delete_unused_full('R', id); return 0; } multitaglist_t xtags; multinodelist_t xnodes; idlist_t xid; m_mid->ways_get_list(xid2, xid, xtags, xnodes); if (cmp_waterway) { geometry_builder::maybe_wkts_t wkts = builder.build_both(xnodes, 1, 1, 1000000, id); for (const auto& wkt: *wkts) { if (boost::starts_with(wkt.geom, "POLYGON") || boost::starts_with(wkt.geom, "MULTIPOLYGON")) { places.copy_out('R', id, wkt.geom, buffer); flush_place_buffer(); } else { /* add_polygon_error('R', id, "boundary", "adminitrative", &names, countrycode, wkt); */ } } } else { /* waterways result in multilinestrings */ geometry_builder::maybe_wkt_t wkt = builder.build_multilines(xnodes, id); if ((wkt->geom).length() > 0) { places.copy_out('R', id, wkt->geom, buffer); flush_place_buffer(); } } return 0; }
unsigned tagtransform::lua_filter_rel_member_tags(const taglist_t &rel_tags, const multitaglist_t &member_tags, const rolelist_t &member_roles, int *member_superseeded, int *make_boundary, int *make_polygon, int *roads, taglist_t &out_tags) { lua_getglobal(L, m_rel_mem_func.c_str()); lua_newtable(L); /* relations key value table */ for (taglist_t::const_iterator it = rel_tags.begin(); it != rel_tags.end(); ++it) { lua_pushstring(L, it->key.c_str()); lua_pushstring(L, it->value.c_str()); lua_rawset(L, -3); } lua_newtable(L); /* member tags table */ int idx = 1; for (multitaglist_t::const_iterator list = member_tags.begin(); list != member_tags.end(); ++list) { lua_pushnumber(L, idx++); lua_newtable(L); /* member key value table */ for (taglist_t::const_iterator it = list->begin(); it != list->end(); ++it) { lua_pushstring(L, it->key.c_str()); lua_pushstring(L, it->value.c_str()); lua_rawset(L, -3); } lua_rawset(L, -3); } lua_newtable(L); /* member roles table */ for (size_t i = 0; i < member_roles.size(); i++) { lua_pushnumber(L, i + 1); lua_pushstring(L, member_roles[i]->c_str()); lua_rawset(L, -3); } lua_pushnumber(L, member_roles.size()); if (lua_pcall(L,4,6,0)) { fprintf(stderr, "Failed to execute lua function for relation tag processing: %s\n", lua_tostring(L, -1)); /* lua function failed */ return 1; } *roads = lua_tointeger(L, -1); lua_pop(L,1); *make_polygon = lua_tointeger(L, -1); lua_pop(L,1); *make_boundary = lua_tointeger(L,-1); lua_pop(L,1); lua_pushnil(L); for (size_t i = 0; i < member_tags.size(); i++) { if (lua_next(L,-2)) { member_superseeded[i] = lua_tointeger(L,-1); lua_pop(L,1); } else { fprintf(stderr, "Failed to read member_superseeded from lua function\n"); } } lua_pop(L,2); lua_pushnil(L); while (lua_next(L,-2) != 0) { const char *key = lua_tostring(L,-2); const char *value = lua_tostring(L,-1); out_tags.push_back(tag(key, value)); lua_pop(L,1); } lua_pop(L,1); int filter = lua_tointeger(L, -1); lua_pop(L,1); return filter; }
unsigned tagtransform::lua_filter_basic_tags(OsmType type, const taglist_t &tags, int *polygon, int *roads, taglist_t &out_tags) { #ifdef HAVE_LUA switch (type) { case OSMTYPE_NODE: { lua_getglobal(L, m_node_func.c_str()); break; } case OSMTYPE_WAY: { lua_getglobal(L, m_way_func.c_str()); break; } case OSMTYPE_RELATION: { lua_getglobal(L, m_rel_func.c_str()); break; } } lua_newtable(L); /* key value table */ for (taglist_t::const_iterator it = tags.begin(); it != tags.end(); ++it) { lua_pushstring(L, it->key.c_str()); lua_pushstring(L, it->value.c_str()); lua_rawset(L, -3); } lua_pushinteger(L, tags.size()); if (lua_pcall(L,2,type == OSMTYPE_WAY ? 4 : 2,0)) { fprintf(stderr, "Failed to execute lua function for basic tag processing: %s\n", lua_tostring(L, -1)); /* lua function failed */ return 1; } if (type == OSMTYPE_WAY) { assert(roads); *roads = lua_tointeger(L, -1); lua_pop(L,1); assert(polygon); *polygon = lua_tointeger(L, -1); lua_pop(L,1); } lua_pushnil(L); while (lua_next(L,-2) != 0) { const char *key = lua_tostring(L,-2); const char *value = lua_tostring(L,-1); out_tags.push_back(tag(key, value)); lua_pop(L,1); } int filter = lua_tointeger(L, -2); lua_pop(L,2); return filter; #else return 1; #endif }
/* Go through the given tags and determine the union of flags. Also remove * any tags from the list that we don't know about */ unsigned int tagtransform::c_filter_basic_tags(OsmType type, const taglist_t &tags, int *polygon, int *roads, const export_list &exlist, taglist_t &out_tags, bool strict) { //assume we dont like this set of tags int filter = 1; int flags = 0; int add_area_tag = 0; OsmType export_type; if (type == OSMTYPE_RELATION) { export_type = OSMTYPE_WAY; } else { export_type = type; } const std::vector<taginfo> &infos = exlist.get(export_type); /* We used to only go far enough to determine if it's a polygon or not, but now we go through and filter stuff we don't need pop each tag off and keep it in the temp list if we like it */ for (taglist_t::const_iterator item = tags.begin(); item != tags.end(); ++item) { //if we want to do more than the export list says if(!strict) { if (type == OSMTYPE_RELATION && "type" == item->key) { out_tags.push_back(*item); filter = 0; continue; } /* Allow named islands to appear as polygons */ if ("natural" == item->key && "coastline" == item->value) { add_area_tag = 1; /* Discard natural=coastline tags (we render these from a shapefile instead) */ if (!options->keep_coastlines) { continue; } } } //go through the actual tags found on the item and keep the ones in the export list size_t i = 0; for (; i < infos.size(); i++) { const taginfo &info = infos[i]; if (wildMatch(info.name.c_str(), item->key.c_str())) { if (info.flags & FLAG_DELETE) { break; } filter = 0; flags |= info.flags; out_tags.push_back(*item); break; } } // if we didn't find any tags that we wanted to export // and we aren't strictly adhering to the list if (i == infos.size() && !strict) { if (options->hstore_mode != HSTORE_NONE) { /* with hstore, copy all tags... */ out_tags.push_back(*item); /* ... but if hstore_match_only is set then don't take this as a reason for keeping the object */ if (!options->hstore_match_only && "osm_uid" != item->key && "osm_user" != item->key && "osm_timestamp" != item->key && "osm_version" != item->key && "osm_changeset" != item->key) filter = 0; } else if (options->hstore_columns.size() > 0) { /* does this column match any of the hstore column prefixes? */ size_t j = 0; for(; j < options->hstore_columns.size(); ++j) { size_t pos = item->key.find(options->hstore_columns[j]); if (pos == 0) { out_tags.push_back(*item); /* ... but if hstore_match_only is set then don't take this as a reason for keeping the object */ if (!options->hstore_match_only && "osm_uid" != item->key && "osm_user" != item->key && "osm_timestamp" != item->key && "osm_version" != item->key && "osm_changeset" != item->key) filter = 0; break; } } } } } if (polygon) { if (add_area_tag) { /* If we need to force this as a polygon, append an area tag */ out_tags.push_dedupe(tag("area", "yes")); *polygon = 1; } else { *polygon = tags.get_bool("area", flags & FLAG_POLYGON); } } if (roads && !filter && (type == OSMTYPE_WAY)) { add_z_order(out_tags, roads); } return filter; }