Merge branch 'master' into mapnik-geometry
This commit is contained in:
commit
317e9c497f
21 changed files with 251 additions and 77 deletions
|
@ -52,6 +52,7 @@ Mapnik is written by Artem Pavlenko with contributions from:
|
||||||
* Igor Podolskiy
|
* Igor Podolskiy
|
||||||
* Reid Priedhorsky
|
* Reid Priedhorsky
|
||||||
* Brian Quinion
|
* Brian Quinion
|
||||||
|
* Even Rouault
|
||||||
* Marcin Rudowski
|
* Marcin Rudowski
|
||||||
* Sandro Santilli
|
* Sandro Santilli
|
||||||
* Christopher Schmidt
|
* Christopher Schmidt
|
||||||
|
|
|
@ -1283,6 +1283,7 @@ if not preconfigured:
|
||||||
else:
|
else:
|
||||||
env['MISSING_DEPS'].append('libxml2')
|
env['MISSING_DEPS'].append('libxml2')
|
||||||
|
|
||||||
|
if not env['HOST']:
|
||||||
if conf.CheckHasDlfcn():
|
if conf.CheckHasDlfcn():
|
||||||
env.Append(CPPDEFINES = '-DMAPNIK_HAS_DLCFN')
|
env.Append(CPPDEFINES = '-DMAPNIK_HAS_DLCFN')
|
||||||
else:
|
else:
|
||||||
|
@ -1340,7 +1341,7 @@ if not preconfigured:
|
||||||
conf.prioritize_paths(silent=True)
|
conf.prioritize_paths(silent=True)
|
||||||
|
|
||||||
# test for C++11 support, which is required
|
# test for C++11 support, which is required
|
||||||
if not conf.supports_cxx11():
|
if not env['HOST'] and not conf.supports_cxx11():
|
||||||
color_print(1,"C++ compiler does not support C++11 standard (-std=c++11), which is required. Please upgrade your compiler to at least g++ 4.7 (ideally 4.8)")
|
color_print(1,"C++ compiler does not support C++11 standard (-std=c++11), which is required. Please upgrade your compiler to at least g++ 4.7 (ideally 4.8)")
|
||||||
Exit(1)
|
Exit(1)
|
||||||
|
|
||||||
|
@ -1361,7 +1362,7 @@ if not preconfigured:
|
||||||
env['MISSING_DEPS'].append(env['ICU_LIB_NAME'])
|
env['MISSING_DEPS'].append(env['ICU_LIB_NAME'])
|
||||||
elif libname == 'harfbuzz':
|
elif libname == 'harfbuzz':
|
||||||
if not conf.harfbuzz_version():
|
if not conf.harfbuzz_version():
|
||||||
env['MISSING_DEPS'].append('harfbuzz-min-version')
|
env['SKIPPED_DEPS'].append('harfbuzz-min-version')
|
||||||
|
|
||||||
if env['BIGINT']:
|
if env['BIGINT']:
|
||||||
env.Append(CPPDEFINES = '-DBIGINT')
|
env.Append(CPPDEFINES = '-DBIGINT')
|
||||||
|
|
|
@ -222,6 +222,11 @@ void set_pixel_int(mapnik::image_any & im, unsigned x, unsigned y, int val)
|
||||||
mapnik::set_pixel(im, x, y, val);
|
mapnik::set_pixel(im, x, y, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned get_type(mapnik::image_any & im)
|
||||||
|
{
|
||||||
|
return im.get_dtype();
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<image_any> open_from_file(std::string const& filename)
|
std::shared_ptr<image_any> open_from_file(std::string const& filename)
|
||||||
{
|
{
|
||||||
boost::optional<std::string> type = type_from_filename(filename);
|
boost::optional<std::string> type = type_from_filename(filename);
|
||||||
|
@ -441,6 +446,7 @@ void export_image()
|
||||||
arg("y"),
|
arg("y"),
|
||||||
arg("get_color")=false
|
arg("get_color")=false
|
||||||
))
|
))
|
||||||
|
.def("get_type",&get_type)
|
||||||
.def("clear",&clear)
|
.def("clear",&clear)
|
||||||
//TODO(haoyu) The method name 'tostring' might be confusing since they actually return bytes in Python 3
|
//TODO(haoyu) The method name 'tostring' might be confusing since they actually return bytes in Python 3
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,7 @@ class image
|
||||||
public:
|
public:
|
||||||
using pixel = T;
|
using pixel = T;
|
||||||
using pixel_type = typename T::type;
|
using pixel_type = typename T::type;
|
||||||
|
static const image_dtype dtype = T::id;
|
||||||
static constexpr std::size_t pixel_size = sizeof(pixel_type);
|
static constexpr std::size_t pixel_size = sizeof(pixel_type);
|
||||||
private:
|
private:
|
||||||
detail::image_dimensions<max_size> dimensions_;
|
detail::image_dimensions<max_size> dimensions_;
|
||||||
|
@ -313,6 +314,11 @@ public:
|
||||||
{
|
{
|
||||||
return painted_;
|
return painted_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline image_dtype get_dtype() const
|
||||||
|
{
|
||||||
|
return dtype;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using image_rgba8 = image<rgba8_t>;
|
using image_rgba8 = image<rgba8_t>;
|
||||||
|
@ -327,22 +333,6 @@ using image_gray64 = image<gray64_t>;
|
||||||
using image_gray64s = image<gray64s_t>;
|
using image_gray64s = image<gray64s_t>;
|
||||||
using image_gray64f = image<gray64f_t>;
|
using image_gray64f = image<gray64f_t>;
|
||||||
|
|
||||||
enum image_dtype : std::uint8_t
|
|
||||||
{
|
|
||||||
image_dtype_rgba8 = 0,
|
|
||||||
image_dtype_gray8,
|
|
||||||
image_dtype_gray8s,
|
|
||||||
image_dtype_gray16,
|
|
||||||
image_dtype_gray16s,
|
|
||||||
image_dtype_gray32,
|
|
||||||
image_dtype_gray32s,
|
|
||||||
image_dtype_gray32f,
|
|
||||||
image_dtype_gray64,
|
|
||||||
image_dtype_gray64s,
|
|
||||||
image_dtype_gray64f,
|
|
||||||
image_dtype_null
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end ns
|
} // end ns
|
||||||
|
|
||||||
#endif // MAPNIK_IMAGE_DATA_HPP
|
#endif // MAPNIK_IMAGE_DATA_HPP
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace mapnik {
|
||||||
struct image_null
|
struct image_null
|
||||||
{
|
{
|
||||||
using pixel_type = uint8_t;
|
using pixel_type = uint8_t;
|
||||||
|
static const image_dtype dtype = image_dtype_null;
|
||||||
unsigned char const* getBytes() const { return nullptr; }
|
unsigned char const* getBytes() const { return nullptr; }
|
||||||
unsigned char* getBytes() { return nullptr;}
|
unsigned char* getBytes() { return nullptr;}
|
||||||
unsigned getSize() const { return 0; }
|
unsigned getSize() const { return 0; }
|
||||||
|
@ -40,6 +41,7 @@ struct image_null
|
||||||
bool painted() const { return false; }
|
bool painted() const { return false; }
|
||||||
double get_offset() const { return 0.0; }
|
double get_offset() const { return 0.0; }
|
||||||
void set_offset(double) {}
|
void set_offset(double) {}
|
||||||
|
image_dtype get_dtype() const { return dtype; }
|
||||||
double get_scaling() const { return 1.0; }
|
double get_scaling() const { return 1.0; }
|
||||||
void set_scaling(double) {}
|
void set_scaling(double) {}
|
||||||
bool get_premultiplied() const { return false; }
|
bool get_premultiplied() const { return false; }
|
||||||
|
@ -88,6 +90,15 @@ struct get_bytes_visitor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct get_dtype_visitor
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
image_dtype operator()(T & data)
|
||||||
|
{
|
||||||
|
return data.get_dtype();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct get_bytes_visitor_const
|
struct get_bytes_visitor_const
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -263,6 +274,11 @@ struct image_any : image_base
|
||||||
return util::apply_visitor(detail::get_scaling_visitor(),*this);
|
return util::apply_visitor(detail::get_scaling_visitor(),*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
image_dtype get_dtype() const
|
||||||
|
{
|
||||||
|
return util::apply_visitor(detail::get_dtype_visitor(),*this);
|
||||||
|
}
|
||||||
|
|
||||||
void set_offset(double val)
|
void set_offset(double val)
|
||||||
{
|
{
|
||||||
util::apply_visitor(detail::set_offset_visitor(val),*this);
|
util::apply_visitor(detail::set_offset_visitor(val),*this);
|
||||||
|
@ -306,6 +322,7 @@ inline image_any create_image_any(int width,
|
||||||
case image_dtype_null:
|
case image_dtype_null:
|
||||||
return image_any(std::move(image_null()));
|
return image_any(std::move(image_null()));
|
||||||
case image_dtype_rgba8:
|
case image_dtype_rgba8:
|
||||||
|
case IMAGE_DTYPE_MAX:
|
||||||
default:
|
default:
|
||||||
return image_any(std::move(image_rgba8(width, height, initialize, premultiplied, painted)));
|
return image_any(std::move(image_rgba8(width, height, initialize, premultiplied, painted)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ class image_view
|
||||||
public:
|
public:
|
||||||
using pixel = typename T::pixel;
|
using pixel = typename T::pixel;
|
||||||
using pixel_type = typename T::pixel_type;
|
using pixel_type = typename T::pixel_type;
|
||||||
|
static const image_dtype dtype = T::dtype;
|
||||||
static constexpr std::size_t pixel_size = sizeof(pixel_type);
|
static constexpr std::size_t pixel_size = sizeof(pixel_type);
|
||||||
|
|
||||||
image_view(unsigned x, unsigned y, unsigned width, unsigned height, T const& data)
|
image_view(unsigned x, unsigned y, unsigned width, unsigned height, T const& data)
|
||||||
|
@ -42,8 +43,8 @@ public:
|
||||||
height_(height),
|
height_(height),
|
||||||
data_(data)
|
data_(data)
|
||||||
{
|
{
|
||||||
if (x_ >= data_.width()) x_=data_.width()-1;
|
if (x_ >= data_.width() && data_.width() > 0) x_ = data_.width() - 1;
|
||||||
if (y_ >= data_.height()) y_=data_.height()-1;
|
if (y_ >= data_.height() && data.height() > 0) y_ = data_.height() - 1;
|
||||||
if (x_ + width_ > data_.width()) width_ = data_.width() - x_;
|
if (x_ + width_ > data_.width()) width_ = data_.width() - x_;
|
||||||
if (y_ + height_ > data_.height()) height_ = data_.height() - y_;
|
if (y_ + height_ > data_.height()) height_ = data_.height() - y_;
|
||||||
}
|
}
|
||||||
|
@ -132,6 +133,11 @@ public:
|
||||||
return data_.get_scaling();
|
return data_.get_scaling();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline image_dtype get_dtype() const
|
||||||
|
{
|
||||||
|
return dtype;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned x_;
|
unsigned x_;
|
||||||
unsigned y_;
|
unsigned y_;
|
||||||
|
|
|
@ -69,6 +69,15 @@ struct get_view_size_visitor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct get_view_dtype_visitor
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
image_dtype operator()(T const& data) const
|
||||||
|
{
|
||||||
|
return data.get_dtype();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct get_view_row_size_visitor
|
struct get_view_row_size_visitor
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -148,6 +157,11 @@ struct image_view_any : image_view_base
|
||||||
{
|
{
|
||||||
return util::apply_visitor(detail::get_view_scaling_visitor(),*this);
|
return util::apply_visitor(detail::get_view_scaling_visitor(),*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
image_dtype get_dtype() const
|
||||||
|
{
|
||||||
|
return util::apply_visitor(detail::get_view_dtype_visitor(),*this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,16 +25,36 @@
|
||||||
|
|
||||||
#include <mapnik/global.hpp>
|
#include <mapnik/global.hpp>
|
||||||
|
|
||||||
struct rgba8_t { using type = std::uint32_t; };
|
namespace mapnik {
|
||||||
struct gray8_t { using type = std::uint8_t; };
|
|
||||||
struct gray8s_t { using type = std::int8_t; };
|
|
||||||
struct gray16_t { using type = std::uint16_t; };
|
|
||||||
struct gray16s_t { using type = std::int16_t; };
|
|
||||||
struct gray32_t { using type = std::uint32_t; };
|
|
||||||
struct gray32s_t { using type = std::int32_t; };
|
|
||||||
struct gray32f_t { using type = float; };
|
|
||||||
struct gray64_t { using type = std::uint64_t; };
|
|
||||||
struct gray64s_t { using type = std::int64_t; };
|
|
||||||
struct gray64f_t { using type = double; };
|
|
||||||
|
|
||||||
|
enum image_dtype : std::uint8_t
|
||||||
|
{
|
||||||
|
image_dtype_rgba8 = 0,
|
||||||
|
image_dtype_gray8,
|
||||||
|
image_dtype_gray8s,
|
||||||
|
image_dtype_gray16,
|
||||||
|
image_dtype_gray16s,
|
||||||
|
image_dtype_gray32,
|
||||||
|
image_dtype_gray32s,
|
||||||
|
image_dtype_gray32f,
|
||||||
|
image_dtype_gray64,
|
||||||
|
image_dtype_gray64s,
|
||||||
|
image_dtype_gray64f,
|
||||||
|
image_dtype_null,
|
||||||
|
IMAGE_DTYPE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rgba8_t { using type = std::uint32_t; static const image_dtype id = image_dtype_rgba8; };
|
||||||
|
struct gray8_t { using type = std::uint8_t; static const image_dtype id = image_dtype_gray8; };
|
||||||
|
struct gray8s_t { using type = std::int8_t; static const image_dtype id = image_dtype_gray8s; };
|
||||||
|
struct gray16_t { using type = std::uint16_t; static const image_dtype id = image_dtype_gray16; };
|
||||||
|
struct gray16s_t { using type = std::int16_t; static const image_dtype id = image_dtype_gray16s; };
|
||||||
|
struct gray32_t { using type = std::uint32_t; static const image_dtype id = image_dtype_gray32; };
|
||||||
|
struct gray32s_t { using type = std::int32_t; static const image_dtype id = image_dtype_gray32s; };
|
||||||
|
struct gray32f_t { using type = float; static const image_dtype id = image_dtype_gray32f; };
|
||||||
|
struct gray64_t { using type = std::uint64_t; static const image_dtype id = image_dtype_gray64; };
|
||||||
|
struct gray64s_t { using type = std::int64_t; static const image_dtype id = image_dtype_gray64s; };
|
||||||
|
struct gray64f_t { using type = double; static const image_dtype id = image_dtype_gray64f; };
|
||||||
|
|
||||||
|
} // end ns
|
||||||
#endif // MAPNIK_PIXEL_TYPES_HPP
|
#endif // MAPNIK_PIXEL_TYPES_HPP
|
||||||
|
|
|
@ -176,18 +176,19 @@ geojson_datasource::geojson_datasource(parameters const& params)
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
using base_iterator_type = char const*;
|
using base_iterator_type = char const*;
|
||||||
const mapnik::transcoder tr("utf8");
|
const mapnik::transcoder geojson_datasource_static_tr("utf8");
|
||||||
const mapnik::json::feature_collection_grammar<base_iterator_type,mapnik::feature_impl> fc_grammar(tr);
|
const mapnik::json::feature_collection_grammar<base_iterator_type,mapnik::feature_impl> geojson_datasource_static_fc_grammar(geojson_datasource_static_tr);
|
||||||
|
const mapnik::json::feature_grammar<base_iterator_type, mapnik::feature_impl> geojson_datasource_static_feature_grammar(geojson_datasource_static_tr);
|
||||||
|
const mapnik::json::extract_bounding_box_grammar<base_iterator_type> geojson_datasource_static_bbox_grammar;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
void geojson_datasource::initialise_index(Iterator start, Iterator end)
|
void geojson_datasource::initialise_index(Iterator start, Iterator end)
|
||||||
{
|
{
|
||||||
mapnik::json::boxes boxes;
|
mapnik::json::boxes boxes;
|
||||||
mapnik::json::extract_bounding_box_grammar<Iterator> bbox_grammar;
|
|
||||||
boost::spirit::ascii::space_type space;
|
boost::spirit::ascii::space_type space;
|
||||||
Iterator itr = start;
|
Iterator itr = start;
|
||||||
if (!boost::spirit::qi::phrase_parse(itr, end, (bbox_grammar)(boost::phoenix::ref(boxes)) , space))
|
if (!boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_bbox_grammar)(boost::phoenix::ref(boxes)) , space))
|
||||||
{
|
{
|
||||||
throw mapnik::datasource_exception("GeoJSON Plugin: could not parse: '" + filename_ + "'");
|
throw mapnik::datasource_exception("GeoJSON Plugin: could not parse: '" + filename_ + "'");
|
||||||
}
|
}
|
||||||
|
@ -207,10 +208,8 @@ void geojson_datasource::initialise_index(Iterator start, Iterator end)
|
||||||
Iterator end = itr + geometry_index.second;
|
Iterator end = itr + geometry_index.second;
|
||||||
mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
|
mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
|
||||||
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx,1));
|
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx,1));
|
||||||
static const mapnik::transcoder tr("utf8");
|
|
||||||
static const mapnik::json::feature_grammar<Iterator, mapnik::feature_impl> grammar(tr);
|
|
||||||
boost::spirit::ascii::space_type space;
|
boost::spirit::ascii::space_type space;
|
||||||
if (!boost::spirit::qi::phrase_parse(itr, end, (grammar)(boost::phoenix::ref(*feature)), space))
|
if (!boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_feature_grammar)(boost::phoenix::ref(*feature)), space))
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to parse geojson feature");
|
throw std::runtime_error("Failed to parse geojson feature");
|
||||||
}
|
}
|
||||||
|
@ -237,7 +236,7 @@ void geojson_datasource::parse_geojson(Iterator start, Iterator end)
|
||||||
|
|
||||||
mapnik::json::default_feature_callback callback(features_);
|
mapnik::json::default_feature_callback callback(features_);
|
||||||
|
|
||||||
bool result = boost::spirit::qi::phrase_parse(start, end, (fc_grammar)
|
bool result = boost::spirit::qi::phrase_parse(start, end, (geojson_datasource_static_fc_grammar)
|
||||||
(boost::phoenix::ref(ctx),boost::phoenix::ref(start_id), boost::phoenix::ref(callback)),
|
(boost::phoenix::ref(ctx),boost::phoenix::ref(start_id), boost::phoenix::ref(callback)),
|
||||||
space);
|
space);
|
||||||
if (!result)
|
if (!result)
|
||||||
|
|
|
@ -58,7 +58,7 @@ public:
|
||||||
{
|
{
|
||||||
std::string err_msg = "Postgis Plugin: ";
|
std::string err_msg = "Postgis Plugin: ";
|
||||||
err_msg += status();
|
err_msg += status();
|
||||||
err_msg += "\nConnection string: '";
|
err_msg += "Connection string: '";
|
||||||
err_msg += connection_str;
|
err_msg += connection_str;
|
||||||
err_msg += "'\n";
|
err_msg += "'\n";
|
||||||
MAPNIK_LOG_DEBUG(postgis) << "postgis_connection: creation failed, closing connection - " << this;
|
MAPNIK_LOG_DEBUG(postgis) << "postgis_connection: creation failed, closing connection - " << this;
|
||||||
|
@ -71,7 +71,7 @@ public:
|
||||||
if ( ! ok ) {
|
if ( ! ok ) {
|
||||||
std::string err_msg = "Postgis Plugin: ";
|
std::string err_msg = "Postgis Plugin: ";
|
||||||
err_msg += status();
|
err_msg += status();
|
||||||
err_msg += "\nConnection string: '";
|
err_msg += "Connection string: '";
|
||||||
err_msg += connection_str;
|
err_msg += connection_str;
|
||||||
err_msg += "'\n";
|
err_msg += "'\n";
|
||||||
close();
|
close();
|
||||||
|
@ -127,7 +127,7 @@ public:
|
||||||
{
|
{
|
||||||
std::string err_msg = "Postgis Plugin: ";
|
std::string err_msg = "Postgis Plugin: ";
|
||||||
err_msg += status();
|
err_msg += status();
|
||||||
err_msg += "\nin executeQuery Full sql was: '";
|
err_msg += "in executeQuery Full sql was: '";
|
||||||
err_msg += sql;
|
err_msg += sql;
|
||||||
err_msg += "'\n";
|
err_msg += "'\n";
|
||||||
if ( result ) PQclear(result);
|
if ( result ) PQclear(result);
|
||||||
|
@ -142,12 +142,19 @@ public:
|
||||||
std::string status;
|
std::string status;
|
||||||
if (conn_)
|
if (conn_)
|
||||||
{
|
{
|
||||||
if ( isOK() ) return PQerrorMessage(conn_);
|
char * err_msg = PQerrorMessage(conn_);
|
||||||
else return "Bad connection";
|
if (err_msg == nullptr)
|
||||||
|
{
|
||||||
|
status = "Bad connection\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
status = "Uninitialized connection";
|
status = std::string(err_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = "Uninitialized connection\n";
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -167,7 +174,7 @@ public:
|
||||||
{
|
{
|
||||||
std::string err_msg = "Postgis Plugin: ";
|
std::string err_msg = "Postgis Plugin: ";
|
||||||
err_msg += status();
|
err_msg += status();
|
||||||
err_msg += "\nin executeAsyncQuery Full sql was: '";
|
err_msg += "in executeAsyncQuery Full sql was: '";
|
||||||
err_msg += sql;
|
err_msg += sql;
|
||||||
err_msg += "'\n";
|
err_msg += "'\n";
|
||||||
clearAsyncResult(PQgetResult(conn_));
|
clearAsyncResult(PQgetResult(conn_));
|
||||||
|
@ -191,7 +198,7 @@ public:
|
||||||
{
|
{
|
||||||
std::string err_msg = "Postgis Plugin: ";
|
std::string err_msg = "Postgis Plugin: ";
|
||||||
err_msg += status();
|
err_msg += status();
|
||||||
err_msg += "\nin getNextAsyncResult";
|
err_msg += "in getNextAsyncResult";
|
||||||
clearAsyncResult(result);
|
clearAsyncResult(result);
|
||||||
// We need to guarde against losing the connection
|
// We need to guarde against losing the connection
|
||||||
// (i.e db restart) so here we invalidate the full connection
|
// (i.e db restart) so here we invalidate the full connection
|
||||||
|
@ -208,7 +215,7 @@ public:
|
||||||
{
|
{
|
||||||
std::string err_msg = "Postgis Plugin: ";
|
std::string err_msg = "Postgis Plugin: ";
|
||||||
err_msg += status();
|
err_msg += status();
|
||||||
err_msg += "\nin getAsyncResult";
|
err_msg += "in getAsyncResult";
|
||||||
clearAsyncResult(result);
|
clearAsyncResult(result);
|
||||||
// We need to be guarded against losing the connection
|
// We need to be guarded against losing the connection
|
||||||
// (i.e db restart), we invalidate the full connection
|
// (i.e db restart), we invalidate the full connection
|
||||||
|
|
|
@ -159,6 +159,10 @@ postgis_datasource::postgis_datasource(parameters const& params)
|
||||||
geometry_table_ = geometry_table_.substr(0);
|
geometry_table_ = geometry_table_.substr(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: geometry_table_ how should ideally be a table name, but
|
||||||
|
// there are known edge cases where this will break down and
|
||||||
|
// geometry_table_ may even be empty: https://github.com/mapnik/mapnik/issues/2718
|
||||||
|
|
||||||
// If we do not know both the geometry_field and the srid
|
// If we do not know both the geometry_field and the srid
|
||||||
// then first attempt to fetch the geometry name from a geometry_columns entry.
|
// then first attempt to fetch the geometry name from a geometry_columns entry.
|
||||||
// This will return no records if we are querying a bogus table returned
|
// This will return no records if we are querying a bogus table returned
|
||||||
|
@ -166,7 +170,7 @@ postgis_datasource::postgis_datasource(parameters const& params)
|
||||||
// the table parameter references a table, view, or subselect not
|
// the table parameter references a table, view, or subselect not
|
||||||
// registered in the geometry columns.
|
// registered in the geometry columns.
|
||||||
geometryColumn_ = geometry_field_;
|
geometryColumn_ = geometry_field_;
|
||||||
if (geometryColumn_.empty() || srid_ == 0)
|
if (!geometry_table_.empty() && (geometryColumn_.empty() || srid_ == 0))
|
||||||
{
|
{
|
||||||
#ifdef MAPNIK_STATS
|
#ifdef MAPNIK_STATS
|
||||||
mapnik::progress_timer __stats2__(std::clog, "postgis_datasource::init(get_srid_and_geometry_column)");
|
mapnik::progress_timer __stats2__(std::clog, "postgis_datasource::init(get_srid_and_geometry_column)");
|
||||||
|
@ -227,8 +231,16 @@ postgis_datasource::postgis_datasource(parameters const& params)
|
||||||
{
|
{
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
|
|
||||||
s << "SELECT ST_SRID(\"" << geometryColumn_ << "\") AS srid FROM "
|
s << "SELECT ST_SRID(\"" << geometryColumn_ << "\") AS srid FROM ";
|
||||||
<< populate_tokens(geometry_table_) << " WHERE \"" << geometryColumn_ << "\" IS NOT NULL LIMIT 1;";
|
if (!geometry_table_.empty())
|
||||||
|
{
|
||||||
|
s << geometry_table_;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s << populate_tokens(table_);
|
||||||
|
}
|
||||||
|
s << " WHERE \"" << geometryColumn_ << "\" IS NOT NULL LIMIT 1;";
|
||||||
|
|
||||||
shared_ptr<ResultSet> rs = conn->executeQuery(s.str());
|
shared_ptr<ResultSet> rs = conn->executeQuery(s.str());
|
||||||
if (rs->next())
|
if (rs->next())
|
||||||
|
|
|
@ -251,7 +251,7 @@ if env['PLUGIN_LINKING'] == 'static':
|
||||||
lib_env.AppendUnique(CPPPATH='../plugins/')
|
lib_env.AppendUnique(CPPPATH='../plugins/')
|
||||||
for plugin in env['REQUESTED_PLUGINS']:
|
for plugin in env['REQUESTED_PLUGINS']:
|
||||||
details = env['PLUGINS'][plugin]
|
details = env['PLUGINS'][plugin]
|
||||||
if details['lib'] in env['LIBS'] or not details['lib']:
|
if not details['lib'] or details['lib'] in env['LIBS']:
|
||||||
plugin_env = SConscript('../plugins/input/%s/build.py' % plugin)
|
plugin_env = SConscript('../plugins/input/%s/build.py' % plugin)
|
||||||
if not plugin_env:
|
if not plugin_env:
|
||||||
print("Notice: no 'plugin_env' variable found for plugin: '%s'" % plugin)
|
print("Notice: no 'plugin_env' variable found for plugin: '%s'" % plugin)
|
||||||
|
|
|
@ -40,8 +40,24 @@ expression_ptr parse_expression(std::string const& str)
|
||||||
auto node = std::make_shared<expr_node>();
|
auto node = std::make_shared<expr_node>();
|
||||||
std::string::const_iterator itr = str.begin();
|
std::string::const_iterator itr = str.begin();
|
||||||
std::string::const_iterator end = str.end();
|
std::string::const_iterator end = str.end();
|
||||||
try {
|
bool r = false;
|
||||||
bool r = boost::spirit::qi::phrase_parse(itr, end, g, space, *node);
|
try
|
||||||
|
{
|
||||||
|
r = boost::spirit::qi::phrase_parse(itr, end, g, space, *node);
|
||||||
|
}
|
||||||
|
catch (std::exception const& ex)
|
||||||
|
{
|
||||||
|
if (std::string("boost::spirit::qi::expectation_failure") == std::string(ex.what()))
|
||||||
|
{
|
||||||
|
// no need to show "boost::spirit::qi::expectation_failure" which is a std::runtime_error
|
||||||
|
throw config_error("Failed to parse expression: \"" + str + "\"");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// show "Could not initialize ICU resources" from boost::regex which is a std::runtime_error
|
||||||
|
throw config_error(std::string(ex.what()) + " for expression: \"" + str + "\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
if (r && itr == end)
|
if (r && itr == end)
|
||||||
{
|
{
|
||||||
return node;
|
return node;
|
||||||
|
@ -51,11 +67,6 @@ expression_ptr parse_expression(std::string const& str)
|
||||||
throw config_error("Failed to parse expression: \"" + str + "\"");
|
throw config_error("Failed to parse expression: \"" + str + "\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception const&) // boost::spirit::qi::expectation_failure
|
|
||||||
{
|
|
||||||
throw config_error("Failed to parse expression: \"" + str + "\"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,9 +93,19 @@ struct visitor_image_copy_so
|
||||||
}
|
}
|
||||||
|
|
||||||
T0 operator() (T0 const& src)
|
T0 operator() (T0 const& src)
|
||||||
|
{
|
||||||
|
if (offset_ == src.get_offset() && scaling_ == src.get_scaling())
|
||||||
{
|
{
|
||||||
return T0(src);
|
return T0(src);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
T0 dst(src);
|
||||||
|
dst.set_scaling(scaling_);
|
||||||
|
dst.set_offset(offset_);
|
||||||
|
return T0(std::move(dst));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
T0 operator() (T1 const& src)
|
T0 operator() (T1 const& src)
|
||||||
|
@ -340,6 +350,10 @@ MAPNIK_DECL image_any image_copy(image_any const& data, image_dtype type, double
|
||||||
return image_any(std::move(image_copy<image_gray64f>(data, offset, scaling)));
|
return image_any(std::move(image_copy<image_gray64f>(data, offset, scaling)));
|
||||||
case image_dtype_null:
|
case image_dtype_null:
|
||||||
throw std::runtime_error("Can not cast a null image");
|
throw std::runtime_error("Can not cast a null image");
|
||||||
|
case IMAGE_DTYPE_MAX:
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Can not cast unknown type");
|
||||||
|
|
||||||
}
|
}
|
||||||
throw std::runtime_error("Unknown image type passed");
|
throw std::runtime_error("Unknown image type passed");
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,11 +46,24 @@ jpeg_saver::jpeg_saver(std::ostream & stream, std::string const& t):
|
||||||
stream_(stream), t_(t) {}
|
stream_(stream), t_(t) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void process_rgba8_jpeg(T const& image, std::string const& t, std::ostream & stream)
|
void process_rgba8_jpeg(T const& image, std::string const& type, std::ostream & stream)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_JPEG)
|
#if defined(HAVE_JPEG)
|
||||||
int quality = 85;
|
int quality = 85;
|
||||||
std::string val = t.substr(4);
|
//std::string val = type.substr(4);
|
||||||
|
if (type != "jpeg")
|
||||||
|
{
|
||||||
|
boost::char_separator<char> sep(":");
|
||||||
|
boost::tokenizer< boost::char_separator<char> > tokens(type, sep);
|
||||||
|
for (auto const& t : tokens)
|
||||||
|
{
|
||||||
|
if (t == "jpeg")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (boost::algorithm::starts_with(t, "quality="))
|
||||||
|
{
|
||||||
|
std::string val = t.substr(8);
|
||||||
if (!val.empty())
|
if (!val.empty())
|
||||||
{
|
{
|
||||||
if (!mapnik::util::string2int(val,quality) || quality < 0 || quality > 100)
|
if (!mapnik::util::string2int(val,quality) || quality < 0 || quality > 100)
|
||||||
|
@ -58,6 +71,9 @@ void process_rgba8_jpeg(T const& image, std::string const& t, std::ostream & str
|
||||||
throw ImageWriterException("invalid jpeg quality: '" + val + "'");
|
throw ImageWriterException("invalid jpeg quality: '" + val + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
save_as_jpeg(stream, quality, image);
|
save_as_jpeg(stream, quality, image);
|
||||||
#else
|
#else
|
||||||
throw ImageWriterException("jpeg output is not enabled in your build of Mapnik");
|
throw ImageWriterException("jpeg output is not enabled in your build of Mapnik");
|
||||||
|
|
|
@ -3,6 +3,12 @@
|
||||||
"objects": {
|
"objects": {
|
||||||
"escaped": {
|
"escaped": {
|
||||||
"type": "GeometryCollection",
|
"type": "GeometryCollection",
|
||||||
|
"bbox": [
|
||||||
|
-180,
|
||||||
|
-90,
|
||||||
|
180,
|
||||||
|
90
|
||||||
|
],
|
||||||
"geometries": [
|
"geometries": [
|
||||||
{
|
{
|
||||||
"type": "Point",
|
"type": "Point",
|
||||||
|
|
|
@ -10,6 +10,12 @@ def setup():
|
||||||
# from another directory we need to chdir()
|
# from another directory we need to chdir()
|
||||||
os.chdir(execution_path('.'))
|
os.chdir(execution_path('.'))
|
||||||
|
|
||||||
|
def test_type():
|
||||||
|
im = mapnik.Image(256, 256)
|
||||||
|
eq_(im.get_type(), mapnik.ImageType.rgba8)
|
||||||
|
im = mapnik.Image(256, 256, mapnik.ImageType.gray8)
|
||||||
|
eq_(im.get_type(), mapnik.ImageType.gray8)
|
||||||
|
|
||||||
def test_image_premultiply():
|
def test_image_premultiply():
|
||||||
im = mapnik.Image(256,256)
|
im = mapnik.Image(256,256)
|
||||||
eq_(im.premultiplied(),False)
|
eq_(im.premultiplied(),False)
|
||||||
|
|
|
@ -53,7 +53,7 @@ def test_can_parse_xml_with_deprecated_properties():
|
||||||
except RuntimeError, e:
|
except RuntimeError, e:
|
||||||
# only test datasources that we have installed
|
# only test datasources that we have installed
|
||||||
if not 'Could not create datasource' in str(e) \
|
if not 'Could not create datasource' in str(e) \
|
||||||
and not 'Bad connection' in str(e):
|
and not 'could not connect' in str(e):
|
||||||
failures.append('Failed to load valid map %s (%s)' % (filename,e))
|
failures.append('Failed to load valid map %s (%s)' % (filename,e))
|
||||||
eq_(len(failures),0,'\n'+'\n'.join(failures))
|
eq_(len(failures),0,'\n'+'\n'.join(failures))
|
||||||
mapnik.logger.set_severity(default_logging_severity)
|
mapnik.logger.set_severity(default_logging_severity)
|
||||||
|
@ -73,7 +73,7 @@ def test_good_files():
|
||||||
except RuntimeError, e:
|
except RuntimeError, e:
|
||||||
# only test datasources that we have installed
|
# only test datasources that we have installed
|
||||||
if not 'Could not create datasource' in str(e) \
|
if not 'Could not create datasource' in str(e) \
|
||||||
and not 'Bad connection' in str(e):
|
and not 'could not connect' in str(e):
|
||||||
failures.append('Failed to load valid map %s (%s)' % (filename,e))
|
failures.append('Failed to load valid map %s (%s)' % (filename,e))
|
||||||
eq_(len(failures),0,'\n'+'\n'.join(failures))
|
eq_(len(failures),0,'\n'+'\n'.join(failures))
|
||||||
|
|
||||||
|
|
|
@ -283,6 +283,16 @@ if 'postgis' in mapnik.DatasourceCache.plugin_names() \
|
||||||
eq_(meta['encoding'],u'UTF8')
|
eq_(meta['encoding'],u'UTF8')
|
||||||
eq_(meta['geometry_type'],mapnik.DataGeometryType.Polygon)
|
eq_(meta['geometry_type'],mapnik.DataGeometryType.Polygon)
|
||||||
|
|
||||||
|
def test_bad_connection():
|
||||||
|
try:
|
||||||
|
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,
|
||||||
|
table='test',
|
||||||
|
max_size=20,
|
||||||
|
geometry_field='geom',
|
||||||
|
user="rolethatdoesnotexist")
|
||||||
|
except Exception, e:
|
||||||
|
assert 'role "rolethatdoesnotexist" does not exist' in str(e)
|
||||||
|
|
||||||
def test_empty_db():
|
def test_empty_db():
|
||||||
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='empty')
|
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='empty')
|
||||||
fs = ds.featureset()
|
fs = ds.featureset()
|
||||||
|
@ -844,7 +854,8 @@ if 'postgis' in mapnik.DatasourceCache.plugin_names() \
|
||||||
fs = ds_bad.featureset()
|
fs = ds_bad.featureset()
|
||||||
for feature in fs:
|
for feature in fs:
|
||||||
pass
|
pass
|
||||||
except RuntimeError:
|
except RuntimeError, e:
|
||||||
|
assert 'invalid input syntax for integer' in str(e)
|
||||||
failed = True
|
failed = True
|
||||||
|
|
||||||
eq_(failed,True)
|
eq_(failed,True)
|
||||||
|
@ -907,7 +918,8 @@ if 'postgis' in mapnik.DatasourceCache.plugin_names() \
|
||||||
mapnik.render_to_file(map1,'/tmp/mapnik-postgis-test-map1.png', 'png')
|
mapnik.render_to_file(map1,'/tmp/mapnik-postgis-test-map1.png', 'png')
|
||||||
# Test must fail if error was not raised just above
|
# Test must fail if error was not raised just above
|
||||||
eq_(False,True)
|
eq_(False,True)
|
||||||
except RuntimeError:
|
except RuntimeError, e:
|
||||||
|
assert 'invalid input syntax for integer' in str(e)
|
||||||
pass
|
pass
|
||||||
# This used to raise an exception before correction of issue 2042
|
# This used to raise an exception before correction of issue 2042
|
||||||
mapnik.render_to_file(map2,'/tmp/mapnik-postgis-test-map2.png', 'png')
|
mapnik.render_to_file(map2,'/tmp/mapnik-postgis-test-map2.png', 'png')
|
||||||
|
@ -1158,6 +1170,42 @@ if 'postgis' in mapnik.DatasourceCache.plugin_names() \
|
||||||
eq_(meta.get('key_field'),"gid")
|
eq_(meta.get('key_field'),"gid")
|
||||||
eq_(meta['geometry_type'],None)
|
eq_(meta['geometry_type'],None)
|
||||||
|
|
||||||
|
# currently needs manual `geometry_table` passed
|
||||||
|
# to avoid misparse of `geometry_table`
|
||||||
|
# in the future ideally this would not need manual `geometry_table`
|
||||||
|
# https://github.com/mapnik/mapnik/issues/2718
|
||||||
|
# currently `bogus` would be picked automatically for geometry_table
|
||||||
|
def test_broken_parsing_of_comments():
|
||||||
|
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='''
|
||||||
|
(select * FROM test) AS data
|
||||||
|
-- select this from bogus''',
|
||||||
|
geometry_table='test')
|
||||||
|
fs = ds.featureset()
|
||||||
|
for id in range(1,5):
|
||||||
|
eq_(fs.next().id(),id)
|
||||||
|
|
||||||
|
meta = ds.describe()
|
||||||
|
eq_(meta['srid'],4326)
|
||||||
|
eq_(meta['geometry_type'],mapnik.DataGeometryType.Collection)
|
||||||
|
|
||||||
|
# same
|
||||||
|
# to avoid misparse of `geometry_table`
|
||||||
|
# in the future ideally this would not need manual `geometry_table`
|
||||||
|
# https://github.com/mapnik/mapnik/issues/2718
|
||||||
|
# currently nothing would be picked automatically for geometry_table
|
||||||
|
def test_broken_parsing_of_comments():
|
||||||
|
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='''
|
||||||
|
(select * FROM test) AS data
|
||||||
|
-- select this from bogus.''',
|
||||||
|
geometry_table='test')
|
||||||
|
fs = ds.featureset()
|
||||||
|
for id in range(1,5):
|
||||||
|
eq_(fs.next().id(),id)
|
||||||
|
|
||||||
|
meta = ds.describe()
|
||||||
|
eq_(meta['srid'],4326)
|
||||||
|
eq_(meta['geometry_type'],mapnik.DataGeometryType.Collection)
|
||||||
|
|
||||||
|
|
||||||
atexit.register(postgis_takedown)
|
atexit.register(postgis_takedown)
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ def compare_map(xml):
|
||||||
except RuntimeError, e:
|
except RuntimeError, e:
|
||||||
# only test datasources that we have installed
|
# only test datasources that we have installed
|
||||||
if not 'Could not create datasource' in str(e) \
|
if not 'Could not create datasource' in str(e) \
|
||||||
and not 'Bad connection' in str(e):
|
and not 'could not connect' in str(e):
|
||||||
raise RuntimeError(str(e))
|
raise RuntimeError(str(e))
|
||||||
return
|
return
|
||||||
(handle, test_map) = tempfile.mkstemp(suffix='.xml', prefix='mapnik-temp-map1-')
|
(handle, test_map) = tempfile.mkstemp(suffix='.xml', prefix='mapnik-temp-map1-')
|
||||||
|
|
|
@ -214,7 +214,7 @@ def render(filename, config, scale_factor, reporting):
|
||||||
return
|
return
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
if 'Could not create datasource' in str(e) \
|
if 'Could not create datasource' in str(e) \
|
||||||
or 'Bad connection' in str(e):
|
or 'could not connect' in str(e):
|
||||||
return m
|
return m
|
||||||
reporting.other_error(filename, repr(e))
|
reporting.other_error(filename, repr(e))
|
||||||
return m
|
return m
|
||||||
|
|
Loading…
Reference in a new issue