Esempio n. 1
0
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);
    }
}
Esempio n. 2
0
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);
    }
}
Esempio n. 3
0
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');
}
Esempio n. 4
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->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;
}
Esempio n. 5
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;
}
Esempio n. 6
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');
    }
}
Esempio n. 7
0
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);
}
Esempio n. 8
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();
    }
}
Esempio n. 9
0
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');
    }
}
Esempio n. 10
0
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);
        }
    }

}
Esempio n. 11
0
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;
}
Esempio n. 12
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);
    }
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
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;
}
Esempio n. 16
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;
}
Esempio n. 17
0
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
}
Esempio n. 18
0
/* 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;
}