Add support for dynamic filename in metawriters.

This commit is contained in:
Hermann Kraus 2010-07-25 22:41:18 +00:00
parent 3c01120c53
commit 87fd78f313
7 changed files with 106 additions and 57 deletions

View file

@ -93,7 +93,7 @@ public:
for (;metaItr!=metaItrEnd; ++metaItr)
{
metaItr->second->start();
metaItr->second->start(m_.metawriter_output_properties);
}
try

View file

@ -420,7 +420,7 @@ public:
/*!
* @brief Get a metawriter property.
*/
std::string get_metawriter_property(std::string name); /*TODO: const */
std::string get_metawriter_property(std::string name) const;
private:
void fixAspectRatio();

View file

@ -40,6 +40,18 @@
namespace mapnik {
class metawriter_property_map
{
public:
metawriter_property_map() {}
UnicodeString const& operator[](std::string const& key) const;
UnicodeString& operator[](std::string const& key) {return m_[key];}
private:
std::map<std::string, UnicodeString> m_;
UnicodeString not_found_;
};
/** All properties to be output by a metawriter. */
class metawriter_properties : public std::set<std::string>
{
@ -67,7 +79,7 @@ class metawriter
proj_transform const& prj_trans,
CoordTransform const &t,
metawriter_properties const& properties = metawriter_properties())=0;
virtual void start() {};
virtual void start(metawriter_property_map const& properties) {};
virtual void stop() {};
protected:
metawriter_properties dflt_properties_;

View file

@ -26,28 +26,46 @@
// Mapnik
#include <mapnik/metawriter.hpp>
#include <mapnik/parse_path.hpp>
// STL
#include <ostream>
#include <fstream>
namespace mapnik {
/** JSON writer. */
class metawriter_json : public metawriter, private boost::noncopyable
/** Write JSON data to a stream object. */
class metawriter_json_stream : public metawriter, private boost::noncopyable
{
public:
metawriter_json(metawriter_properties dflt_properties, std::string fn);
metawriter_json(metawriter_properties dflt_properties, std::ostream);
~metawriter_json();
virtual void add_box(box2d<double> box, Feature const &feature,
proj_transform const& prj_trans,
CoordTransform const& t,
metawriter_properties const& properties);
virtual void start();
virtual void stop();
private:
std::ostream *f;
std::string fn_;
int count;
public:
metawriter_json_stream(metawriter_properties dflt_properties);
virtual void add_box(box2d<double> box, Feature const &feature,
proj_transform const& prj_trans,
CoordTransform const& t,
metawriter_properties const& properties);
virtual void start(metawriter_property_map const& properties);
virtual void stop();
void set_stream(std::ostream *f) { f_ = f; }
private:
std::ostream *f_;
int count;
};
/** JSON writer. */
class metawriter_json : public metawriter_json_stream
{
public:
metawriter_json(metawriter_properties dflt_properties, path_expression_ptr fn);
~metawriter_json();
virtual void start(metawriter_property_map const& properties);
virtual void stop();
private:
path_expression_ptr fn_;
std::fstream f_;
};
};

View file

@ -363,7 +363,7 @@ void map_parser::parse_metawriter(Map & map, ptree const & pt)
if (type == "json") {
string file = get_attr<string>(pt, "file");
optional<string> properties = get_opt_attr<string>(pt, "default-output");
writer = metawriter_ptr(new metawriter_json(properties, file));
writer = metawriter_ptr(new metawriter_json(properties, parse_path(file)));
} else {
throw config_error(string("Unknown type '") + type + "'");
}

View file

@ -614,7 +614,7 @@ void Map::set_metawriter_property(std::string name, std::string value)
metawriter_output_properties[name] = UnicodeString::fromUTF8(value);
}
std::string Map::get_metawriter_property(std::string name)
std::string Map::get_metawriter_property(std::string name) const
{
std::string result;
to_utf8(metawriter_output_properties[name], result);

View file

@ -32,48 +32,34 @@
// STL
#include <iomanip>
#include <cstdio>
#include <fstream>
namespace mapnik {
metawriter_json::metawriter_json(metawriter_properties dflt_properties, std::string fn)
: metawriter(dflt_properties), fn_(fn), count(0)
UnicodeString const& metawriter_property_map::operator[](std::string const& key) const
{
std::map<std::string, UnicodeString>::const_iterator it;
it = m_.find(key);
if (it != m_.end()) return not_found_;
return (*it).second;
}
metawriter_json::~metawriter_json()
void metawriter_json_stream::start(metawriter_property_map const& properties)
{
stop();
assert(f_);
*f_ << "{ \"type\": \"FeatureCollection\", \"features\": [\n";
}
void metawriter_json::start()
void metawriter_json_stream::stop()
{
if (!fn_.empty())
{
if (f)
{
std::cerr << "ERROR: GeoJSON metawriter is already active!\n";
return;
}
f = new std::fstream(fn_.c_str(), std::fstream::out | std::fstream::trunc);
if (f->fail()) perror((std::string("Failed to open file ") + fn_).c_str());
}
assert(f);
*f << "{ \"type\": \"FeatureCollection\", \"features\": [\n";
}
void metawriter_json::stop()
{
if (f) *f << " ] }\n";
if (f && !fn_.empty())
{
dynamic_cast<std::fstream *>(f)->close();
f = 0;
if (f_) {
*f_ << " ] }\n";
}
}
void metawriter_json::add_box(box2d<double> box, Feature const &feature,
metawriter_json_stream::metawriter_json_stream(metawriter_properties dflt_properties)
: metawriter(dflt_properties), count(0) {}
void metawriter_json_stream::add_box(box2d<double> box, Feature const &feature,
proj_transform const& prj_trans, CoordTransform const &t,
const metawriter_properties& properties)
{
@ -85,7 +71,7 @@ void metawriter_json::add_box(box2d<double> box, Feature const &feature,
if (props.empty())
{
std::cerr << "WARNING: No expression available for GeoJSON metawriter.\n";
std::cerr << "WARNING: No properties available for GeoJSON metawriter.\n";
}
/* Coordinate transform in renderer:
@ -112,8 +98,8 @@ void metawriter_json::add_box(box2d<double> box, Feature const &feature,
double maxx = box.maxx();
double maxy = box.maxy();
if (count++) *f << ",\n";
*f << std::fixed << std::setprecision(8) << "{ \"type\": \"Feature\",\n \"geometry\": { \"type\": \"Polygon\",\n \"coordinates\": [ [ [" <<
if (count++) *f_ << ",\n";
*f_ << std::fixed << std::setprecision(8) << "{ \"type\": \"Feature\",\n \"geometry\": { \"type\": \"Polygon\",\n \"coordinates\": [ [ [" <<
minx << ", " << miny << "], [" <<
maxx << ", " << miny << "], [" <<
maxx << ", " << maxy << "], [" <<
@ -130,13 +116,46 @@ void metawriter_json::add_box(box2d<double> box, Feature const &feature,
//Property found
text = boost::replace_all_copy(boost::replace_all_copy(itr->second.to_string(), "\\", "\\\\"), "\"", "\\\"");
}
if (i++) *f << ",";
*f << "\n \"" << p << "\":\"" << text << "\"";
if (i++) *f_ << ",";
*f_ << "\n \"" << p << "\":\"" << text << "\"";
}
*f << "\n} }";
*f_ << "\n} }";
}
/********************************************************************************************/
metawriter_json::metawriter_json(metawriter_properties dflt_properties, path_expression_ptr fn)
: metawriter_json_stream(dflt_properties), fn_(fn) {}
metawriter_json::~metawriter_json()
{
stop();
}
void metawriter_json::start(metawriter_property_map const& properties)
{
std::string filename =
path_processor<metawriter_property_map>::evaluate(*fn_, properties);
#ifdef MAPNIK_DEBUG
std::clog << "Metawriter JSON: filename=" << filename << "\n";
#endif
f_.open(filename.c_str(), std::fstream::out | std::fstream::trunc);
if (f_.fail()) perror((std::string("Metawriter JSON: Failed to open file ") + filename).c_str());
set_stream(&f_);
metawriter_json_stream::start(properties);
}
void metawriter_json::stop()
{
metawriter_json_stream::stop();
if (f_.is_open()) f_.close();
}
metawriter_properties::metawriter_properties(boost::optional<std::string> str)
{
if (str) {