Skip to content

Commit

Permalink
Tag filter refactoring and added functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
joto committed Oct 1, 2012
1 parent d392f20 commit 9bace0f
Show file tree
Hide file tree
Showing 9 changed files with 506 additions and 61 deletions.
22 changes: 13 additions & 9 deletions examples/osmium_to_postgis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
This is an example tool that loads OSM data into a PostGIS
database with hstore tags column using the OGR library.
The database must have the HSTORE and POSTGIS extentions
loaded.
*/

/*
Expand Down Expand Up @@ -38,25 +41,26 @@ You should have received a copy of the Licenses along with Osmium. If not, see
#define OSMIUM_WITH_XML_INPUT

#include <osmium.hpp>
#include <osmium/osm/tag_filter.hpp>
#include <osmium/osm/tag_list_to_string.hpp>
#include <osmium/utils/filter_and_accumulate.hpp>
#include <osmium/tags/key_filter.hpp>
#include <osmium/tags/to_string.hpp>
#include <osmium/geometry/point.hpp>
#include <osmium/geometry/ogr.hpp>

class MyOGRHandler : public Osmium::Handler::Base {

OGRDataSource* m_data_source;
OGRLayer* m_layer_point;
Osmium::OSM::TagKeyFilterOp m_filter;
Osmium::OSM::TagToHstoreStringOp m_tohstore;
Osmium::Tags::KeyFilter m_filter;
Osmium::Tags::TagToHStoreStringOp m_tohstore;

public:

MyOGRHandler(const std::string& filename) :
m_data_source(NULL),
m_layer_point(NULL),
m_filter(),
m_tohstore(Osmium::OSM::TagToHstoreStringOp()) {
m_filter(true),
m_tohstore() {
OGRRegisterAll();

OGRSFDriver* driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName("PostgreSQL");
Expand All @@ -83,8 +87,8 @@ class MyOGRHandler : public Osmium::Handler::Base {
// using transactions make this much faster than without
m_layer_point->StartTransaction();

m_filter.add("created_by");
m_filter.add("odbl");
m_filter.add(false, "created_by");
m_filter.add(false, "odbl");
}

~MyOGRHandler() {
Expand All @@ -96,7 +100,7 @@ class MyOGRHandler : public Osmium::Handler::Base {
if (!node->tags().empty()) {
std::string tags;

Osmium::OSM::tags_filter_and_accumulate(node->tags(), m_filter, &tags, m_tohstore);
Osmium::filter_and_accumulate(node->tags(), m_filter, tags, m_tohstore);

if (!tags.empty()) {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef OSMIUM_OSM_TAG_FILTER_HPP
#define OSMIUM_OSM_TAG_FILTER_HPP
#ifndef OSMIUM_TAGS_KEY_FILTER_HPP
#define OSMIUM_TAGS_KEY_FILTER_HPP

/*
Expand All @@ -23,7 +23,6 @@ You should have received a copy of the Licenses along with Osmium. If not, see
*/

#include <functional>
#include <numeric>
#include <vector>
#include <boost/foreach.hpp>
#include <boost/iterator/filter_iterator.hpp>
Expand All @@ -33,48 +32,51 @@ You should have received a copy of the Licenses along with Osmium. If not, see

namespace Osmium {

namespace OSM {
namespace Tags {

class TagKeyFilterOp : public std::unary_function<const Osmium::OSM::Tag&, bool> {
class KeyFilter : public std::unary_function<const Osmium::OSM::Tag&, bool> {

struct rule_t {
bool result;
std::string key;

rule_t(bool r, const char* k) :
result(r),
key(k) {
}

};

std::vector<rule_t> m_rules;
bool m_default_result;

public:

TagKeyFilterOp() :
m_keys() {
typedef boost::filter_iterator<KeyFilter, Osmium::OSM::TagList::const_iterator> iterator;

KeyFilter(bool default_result) :
m_rules(),
m_default_result(default_result) {
}

TagKeyFilterOp& add(const char* key) {
m_keys.push_back(key);
KeyFilter& add(bool result, const char* key) {
m_rules.push_back(rule_t(result, key));
return *this;
}

bool operator()(const Osmium::OSM::Tag& tag) const {
BOOST_FOREACH(const std::string& key, m_keys) {
if (key == tag.key()) {
return false;
BOOST_FOREACH(const rule_t& rule, m_rules) {
if (tag.key() == rule.key) {
return rule.result;
}
}
return true;
return m_default_result;
}

private:

std::vector<std::string> m_keys;

};

typedef boost::filter_iterator<TagKeyFilterOp, TagList::const_iterator> TagKeyFilterOpIterator;

template <class T>
inline void tags_filter_and_accumulate(const TagList& tags, TagKeyFilterOp& filter, std::string* stringptr, T convert) {
TagKeyFilterOpIterator fi_begin(filter, tags.begin(), tags.end());
TagKeyFilterOpIterator fi_end(filter, tags.end(), tags.end());

std::accumulate(fi_begin, fi_end, stringptr, convert);
}

} // namespace OSM
} // namespace Tags

} // namespace Osmium

#endif // OSMIUM_OSM_TAG_FILTER_HPP
#endif // OSMIUM_TAGS_KEY_FILTER_HPP
84 changes: 84 additions & 0 deletions include/osmium/tags/key_value_filter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#ifndef OSMIUM_TAGS_KEY_VALUE_FILTER_HPP
#define OSMIUM_TAGS_KEY_VALUE_FILTER_HPP

/*
Copyright 2012 Jochen Topf <[email protected]> and others (see README).
This file is part of Osmium (https://github.com/joto/osmium).
Osmium is free software: you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License or (at your option) the GNU
General Public License as published by the Free Software Foundation, either
version 3 of the Licenses, or (at your option) any later version.
Osmium is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License and the GNU
General Public License for more details.
You should have received a copy of the Licenses along with Osmium. If not, see
<http://www.gnu.org/licenses/>.
*/

#include <functional>
#include <vector>
#include <boost/foreach.hpp>
#include <boost/iterator/filter_iterator.hpp>

#include <osmium/osm/tag.hpp>
#include <osmium/osm/tag_list.hpp>

namespace Osmium {

namespace Tags {

class KeyValueFilter : public std::unary_function<const Osmium::OSM::Tag&, bool> {

struct rule_t {
bool result;
std::string key;
std::string value;

rule_t(bool r, const char* k, const char* v) :
result(r),
key(k),
value(v ? v : "") {
}

};

std::vector<rule_t> m_rules;
bool m_default_result;

public:

typedef boost::filter_iterator<KeyValueFilter, Osmium::OSM::TagList::const_iterator> iterator;

KeyValueFilter(bool default_result) :
m_rules(),
m_default_result(default_result) {
}

KeyValueFilter& add(bool result, const char* key, const char* value = NULL) {
m_rules.push_back(rule_t(result, key, value));
return *this;
}

bool operator()(const Osmium::OSM::Tag& tag) const {
BOOST_FOREACH(const rule_t &rule, m_rules) {
if (tag.key() == rule.key && (rule.value.empty() || tag.value() == rule.value)) {
return rule.result;
}
}
return m_default_result;
}

};

} // namespace Tags

} // namespace Osmium

#endif // OSMIUM_TAGS_KEY_VALUE_FILTER_HPP
90 changes: 90 additions & 0 deletions include/osmium/tags/regex_filter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#ifndef OSMIUM_TAGS_REGEX_FILTER_HPP
#define OSMIUM_TAGS_REGEX_FILTER_HPP

/*
Copyright 2012 Jochen Topf <[email protected]> and others (see README).
This file is part of Osmium (https://github.com/joto/osmium).
Osmium is free software: you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License or (at your option) the GNU
General Public License as published by the Free Software Foundation, either
version 3 of the Licenses, or (at your option) any later version.
Osmium is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License and the GNU
General Public License for more details.
You should have received a copy of the Licenses along with Osmium. If not, see
<http://www.gnu.org/licenses/>.
*/

#define OSMIUM_LINK_WITH_LIBS_GEOS -lboost_regex

#include <functional>
#include <vector>
#include <boost/foreach.hpp>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/regex.hpp>

#include <osmium/osm/tag.hpp>
#include <osmium/osm/tag_list.hpp>

namespace Osmium {

namespace Tags {

class RegexFilter : public std::unary_function<const Osmium::OSM::Tag&, bool> {

struct rule_t {
bool result;
boost::regex key;
boost::regex value;

rule_t(bool r, const char* k, const char* v) :
result(r),
key(k),
value() {
if (v) {
value = v;
}
}

};

std::vector<rule_t> m_rules;
bool m_default_result;

public:

typedef boost::filter_iterator<RegexFilter, Osmium::OSM::TagList::const_iterator> iterator;

RegexFilter(bool default_result) :
m_rules(),
m_default_result(default_result) {
}

RegexFilter& add(bool result, const char* key, const char* value = NULL) {
m_rules.push_back(rule_t(result, key, value));
return *this;
}

bool operator()(const Osmium::OSM::Tag& tag) const {
BOOST_FOREACH(const rule_t &rule, m_rules) {
if (boost::regex_match(tag.key(), rule.key) && (rule.value.empty() || boost::regex_match(tag.value(), rule.value))) {
return rule.result;
}
}
return m_default_result;
}

};

} // namespace Tags

} // namespace Osmium

#endif // OSMIUM_TAGS_REGEX_FILTER_HPP
Loading

0 comments on commit 9bace0f

Please sign in to comment.