Compare commits
11 commits
master
...
cpaulik-gd
Author | SHA1 | Date | |
---|---|---|---|
|
acdd512c71 | ||
|
c543cd13ca | ||
|
a47c7496b9 | ||
|
0420c21a22 | ||
|
82d7bfaac3 | ||
|
b956b2c38f | ||
|
a044560bfe | ||
|
06ed4d9ac6 | ||
|
95b8801ea3 | ||
|
1e175e3dd4 | ||
|
bcaa0dd799 |
9 changed files with 118 additions and 150 deletions
|
@ -30,6 +30,7 @@ For a complete change history, see the git log.
|
||||||
|
|
||||||
#### Plugins
|
#### Plugins
|
||||||
|
|
||||||
|
- GDAL: Use GDAL for overview selection and resampling instead of trying to do it in mapnik ([#3966](https://github.com/mapnik/mapnik/issues/3966))
|
||||||
- GDAL: fixed several issues with overviews ([#3912](https://github.com/mapnik/mapnik/issues/3912))
|
- GDAL: fixed several issues with overviews ([#3912](https://github.com/mapnik/mapnik/issues/3912))
|
||||||
- PostGIS: changed syntax for user `@variable` interpolation to `!@variable!` ([#3618](https://github.com/mapnik/mapnik/issues/3618))
|
- PostGIS: changed syntax for user `@variable` interpolation to `!@variable!` ([#3618](https://github.com/mapnik/mapnik/issues/3618))
|
||||||
- PGraster: added variable interpolation like in PostGIS plugin ([#3618](https://github.com/mapnik/mapnik/issues/3618))
|
- PGraster: added variable interpolation like in PostGIS plugin ([#3618](https://github.com/mapnik/mapnik/issues/3618))
|
||||||
|
|
|
@ -161,8 +161,10 @@ private:
|
||||||
struct symbolizer_attributes
|
struct symbolizer_attributes
|
||||||
{
|
{
|
||||||
symbolizer_attributes(std::set<std::string>& names,
|
symbolizer_attributes(std::set<std::string>& names,
|
||||||
double & filter_factor)
|
double & filter_factor,
|
||||||
|
scaling_method_e & method_)
|
||||||
: filter_factor_(filter_factor),
|
: filter_factor_(filter_factor),
|
||||||
|
method_(method_),
|
||||||
f_attrs_(names),
|
f_attrs_(names),
|
||||||
g_attrs_(names, true) {}
|
g_attrs_(names, true) {}
|
||||||
|
|
||||||
|
@ -190,8 +192,13 @@ struct symbolizer_attributes
|
||||||
filter_factor_ = 2;
|
filter_factor_ = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<scaling_method_e> scaling_method = get_optional<scaling_method_e>(sym, keys::scaling);
|
||||||
|
method_ = scaling_method.get_value_or(SCALING_NEAR);
|
||||||
|
|
||||||
for (auto const& prop : sym.properties)
|
for (auto const& prop : sym.properties)
|
||||||
{
|
{
|
||||||
|
|
||||||
util::apply_visitor(f_attrs_, prop.second);
|
util::apply_visitor(f_attrs_, prop.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,6 +210,7 @@ struct symbolizer_attributes
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double & filter_factor_;
|
double & filter_factor_;
|
||||||
|
scaling_method_e & method_;
|
||||||
extract_attribute_names<std::set<std::string> > f_attrs_;
|
extract_attribute_names<std::set<std::string> > f_attrs_;
|
||||||
group_attribute_collector g_attrs_;
|
group_attribute_collector g_attrs_;
|
||||||
};
|
};
|
||||||
|
@ -213,18 +221,21 @@ class attribute_collector : public util::noncopyable
|
||||||
private:
|
private:
|
||||||
std::set<std::string> & names_;
|
std::set<std::string> & names_;
|
||||||
double filter_factor_;
|
double filter_factor_;
|
||||||
|
scaling_method_e method_;
|
||||||
expression_attributes<std::set<std::string> > f_attr;
|
expression_attributes<std::set<std::string> > f_attr;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
attribute_collector(std::set<std::string>& names)
|
attribute_collector(std::set<std::string>& names)
|
||||||
: names_(names),
|
: names_(names),
|
||||||
filter_factor_(1.0),
|
filter_factor_(1.0),
|
||||||
|
method_(SCALING_NEAR),
|
||||||
f_attr(names) {}
|
f_attr(names) {}
|
||||||
template <typename RuleType>
|
template <typename RuleType>
|
||||||
void operator() (RuleType const& r)
|
void operator() (RuleType const& r)
|
||||||
{
|
{
|
||||||
typename RuleType::symbolizers const& symbols = r.get_symbolizers();
|
typename RuleType::symbolizers const& symbols = r.get_symbolizers();
|
||||||
symbolizer_attributes s_attr(names_,filter_factor_);
|
symbolizer_attributes s_attr(names_,filter_factor_,method_);
|
||||||
|
|
||||||
for (auto const& sym : symbols)
|
for (auto const& sym : symbols)
|
||||||
{
|
{
|
||||||
util::apply_visitor(std::ref(s_attr), sym);
|
util::apply_visitor(std::ref(s_attr), sym);
|
||||||
|
@ -238,6 +249,11 @@ public:
|
||||||
{
|
{
|
||||||
return filter_factor_;
|
return filter_factor_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scaling_method_e get_scaling_method() const
|
||||||
|
{
|
||||||
|
return method_;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -432,6 +432,7 @@ void feature_style_processor<Processor>::prepare_layer(layer_rendering_material
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
q.set_filter_factor(collector.get_filter_factor());
|
q.set_filter_factor(collector.get_filter_factor());
|
||||||
|
q.set_scaling_method(collector.get_scaling_method());
|
||||||
|
|
||||||
// Also query the group by attribute
|
// Also query the group by attribute
|
||||||
std::string const& group_by = lay.group_by();
|
std::string const& group_by = lay.group_by();
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
//mapnik
|
//mapnik
|
||||||
#include <mapnik/geometry/box2d.hpp>
|
#include <mapnik/geometry/box2d.hpp>
|
||||||
#include <mapnik/attribute.hpp>
|
#include <mapnik/attribute.hpp>
|
||||||
|
#include <mapnik/image_scaling.hpp>
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -47,6 +48,7 @@ public:
|
||||||
resolution_(_resolution),
|
resolution_(_resolution),
|
||||||
scale_denominator_(_scale_denominator),
|
scale_denominator_(_scale_denominator),
|
||||||
filter_factor_(1.0),
|
filter_factor_(1.0),
|
||||||
|
scaling_method_(SCALING_NEAR),
|
||||||
unbuffered_bbox_(unbuffered_bbox),
|
unbuffered_bbox_(unbuffered_bbox),
|
||||||
names_(),
|
names_(),
|
||||||
vars_()
|
vars_()
|
||||||
|
@ -59,6 +61,7 @@ public:
|
||||||
resolution_(_resolution),
|
resolution_(_resolution),
|
||||||
scale_denominator_(_scale_denominator),
|
scale_denominator_(_scale_denominator),
|
||||||
filter_factor_(1.0),
|
filter_factor_(1.0),
|
||||||
|
scaling_method_(SCALING_NEAR),
|
||||||
unbuffered_bbox_(bbox),
|
unbuffered_bbox_(bbox),
|
||||||
names_(),
|
names_(),
|
||||||
vars_()
|
vars_()
|
||||||
|
@ -69,6 +72,7 @@ public:
|
||||||
resolution_(resolution_type(1.0,1.0)),
|
resolution_(resolution_type(1.0,1.0)),
|
||||||
scale_denominator_(1.0),
|
scale_denominator_(1.0),
|
||||||
filter_factor_(1.0),
|
filter_factor_(1.0),
|
||||||
|
scaling_method_(SCALING_NEAR),
|
||||||
unbuffered_bbox_(bbox),
|
unbuffered_bbox_(bbox),
|
||||||
names_(),
|
names_(),
|
||||||
vars_()
|
vars_()
|
||||||
|
@ -79,6 +83,7 @@ public:
|
||||||
resolution_(other.resolution_),
|
resolution_(other.resolution_),
|
||||||
scale_denominator_(other.scale_denominator_),
|
scale_denominator_(other.scale_denominator_),
|
||||||
filter_factor_(other.filter_factor_),
|
filter_factor_(other.filter_factor_),
|
||||||
|
scaling_method_(other.scaling_method_),
|
||||||
unbuffered_bbox_(other.unbuffered_bbox_),
|
unbuffered_bbox_(other.unbuffered_bbox_),
|
||||||
names_(other.names_),
|
names_(other.names_),
|
||||||
vars_(other.vars_)
|
vars_(other.vars_)
|
||||||
|
@ -91,6 +96,7 @@ public:
|
||||||
resolution_=other.resolution_;
|
resolution_=other.resolution_;
|
||||||
scale_denominator_=other.scale_denominator_;
|
scale_denominator_=other.scale_denominator_;
|
||||||
filter_factor_=other.filter_factor_;
|
filter_factor_=other.filter_factor_;
|
||||||
|
scaling_method_=other.scaling_method_;
|
||||||
unbuffered_bbox_=other.unbuffered_bbox_;
|
unbuffered_bbox_=other.unbuffered_bbox_;
|
||||||
names_=other.names_;
|
names_=other.names_;
|
||||||
vars_=other.vars_;
|
vars_=other.vars_;
|
||||||
|
@ -137,6 +143,16 @@ public:
|
||||||
filter_factor_ = factor;
|
filter_factor_ = factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scaling_method_e get_scaling_method() const
|
||||||
|
{
|
||||||
|
return scaling_method_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_scaling_method(scaling_method_e method)
|
||||||
|
{
|
||||||
|
scaling_method_ = method;
|
||||||
|
}
|
||||||
|
|
||||||
void add_property_name(std::string const& name)
|
void add_property_name(std::string const& name)
|
||||||
{
|
{
|
||||||
names_.insert(name);
|
names_.insert(name);
|
||||||
|
@ -162,6 +178,7 @@ private:
|
||||||
resolution_type resolution_;
|
resolution_type resolution_;
|
||||||
double scale_denominator_;
|
double scale_denominator_;
|
||||||
double filter_factor_;
|
double filter_factor_;
|
||||||
|
scaling_method_e scaling_method_;
|
||||||
box2d<double> unbuffered_bbox_;
|
box2d<double> unbuffered_bbox_;
|
||||||
std::set<std::string> names_;
|
std::set<std::string> names_;
|
||||||
attributes vars_;
|
attributes vars_;
|
||||||
|
|
|
@ -84,13 +84,6 @@ gdal_datasource::gdal_datasource(parameters const& params)
|
||||||
|
|
||||||
shared_dataset_ = *params.get<mapnik::boolean_type>("shared", false);
|
shared_dataset_ = *params.get<mapnik::boolean_type>("shared", false);
|
||||||
band_ = *params.get<mapnik::value_integer>("band", -1);
|
band_ = *params.get<mapnik::value_integer>("band", -1);
|
||||||
|
|
||||||
// Maximum memory limitation for image will be simply based on the maximum
|
|
||||||
// area we allow for an image. The true memory footprint therefore will vary based
|
|
||||||
// on the type of imagery that exists. This is not the maximum size of an image
|
|
||||||
// on disk but rather the maximum size we will load into mapnik from GDAL.
|
|
||||||
// max_im_area based on 50 mb limit for RGBA
|
|
||||||
max_image_area_ = *params.get<mapnik::value_integer>("max_image_area", (50*1024*1024) / 4);
|
|
||||||
|
|
||||||
#if GDAL_VERSION_NUM >= 1600
|
#if GDAL_VERSION_NUM >= 1600
|
||||||
if (shared_dataset_)
|
if (shared_dataset_)
|
||||||
|
@ -244,8 +237,7 @@ featureset_ptr gdal_datasource::features(query const& q) const
|
||||||
dx_,
|
dx_,
|
||||||
dy_,
|
dy_,
|
||||||
nodata_value_,
|
nodata_value_,
|
||||||
nodata_tolerance_,
|
nodata_tolerance_);
|
||||||
max_image_area_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
featureset_ptr gdal_datasource::features_at_point(coord2d const& pt, double tol) const
|
featureset_ptr gdal_datasource::features_at_point(coord2d const& pt, double tol) const
|
||||||
|
@ -264,6 +256,5 @@ featureset_ptr gdal_datasource::features_at_point(coord2d const& pt, double tol)
|
||||||
dx_,
|
dx_,
|
||||||
dy_,
|
dy_,
|
||||||
nodata_value_,
|
nodata_value_,
|
||||||
nodata_tolerance_,
|
nodata_tolerance_);
|
||||||
max_image_area_);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,6 @@ private:
|
||||||
bool shared_dataset_;
|
bool shared_dataset_;
|
||||||
boost::optional<double> nodata_value_;
|
boost::optional<double> nodata_value_;
|
||||||
double nodata_tolerance_;
|
double nodata_tolerance_;
|
||||||
int64_t max_image_area_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GDAL_DATASOURCE_HPP
|
#endif // GDAL_DATASOURCE_HPP
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/datasource.hpp>
|
#include <mapnik/datasource.hpp>
|
||||||
|
#include <boost/optional/optional_io.hpp>
|
||||||
|
#include <mapnik/image_scaling.hpp>
|
||||||
#include <mapnik/global.hpp>
|
#include <mapnik/global.hpp>
|
||||||
#include <mapnik/debug.hpp>
|
#include <mapnik/debug.hpp>
|
||||||
#include <mapnik/image.hpp>
|
#include <mapnik/image.hpp>
|
||||||
|
@ -79,6 +81,7 @@ void get_overview_meta(GDALRasterBand* band)
|
||||||
}
|
}
|
||||||
} // anonymous ns
|
} // anonymous ns
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gdal_featureset::gdal_featureset(GDALDataset& dataset,
|
gdal_featureset::gdal_featureset(GDALDataset& dataset,
|
||||||
int band,
|
int band,
|
||||||
gdal_query q,
|
gdal_query q,
|
||||||
|
@ -89,8 +92,7 @@ gdal_featureset::gdal_featureset(GDALDataset& dataset,
|
||||||
double dx,
|
double dx,
|
||||||
double dy,
|
double dy,
|
||||||
boost::optional<double> const& nodata,
|
boost::optional<double> const& nodata,
|
||||||
double nodata_tolerance,
|
double nodata_tolerance)
|
||||||
int64_t max_image_area)
|
|
||||||
: dataset_(dataset),
|
: dataset_(dataset),
|
||||||
ctx_(std::make_shared<mapnik::context_type>()),
|
ctx_(std::make_shared<mapnik::context_type>()),
|
||||||
band_(band),
|
band_(band),
|
||||||
|
@ -103,7 +105,6 @@ gdal_featureset::gdal_featureset(GDALDataset& dataset,
|
||||||
nbands_(nbands),
|
nbands_(nbands),
|
||||||
nodata_value_(nodata),
|
nodata_value_(nodata),
|
||||||
nodata_tolerance_(nodata_tolerance),
|
nodata_tolerance_(nodata_tolerance),
|
||||||
max_image_area_(max_image_area),
|
|
||||||
first_(true)
|
first_(true)
|
||||||
{
|
{
|
||||||
ctx_->push("nodata");
|
ctx_->push("nodata");
|
||||||
|
@ -113,6 +114,35 @@ gdal_featureset::~gdal_featureset()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GDALRIOResampleAlg gdal_featureset::get_gdal_resample_alg(mapnik::scaling_method_e mapnik_scaling_method)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (mapnik_scaling_method)
|
||||||
|
{
|
||||||
|
case mapnik::SCALING_NEAR: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL Nearest Neighbor resampling"; return GRIORA_NearestNeighbour;
|
||||||
|
case mapnik::SCALING_BILINEAR: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL Bilinear resampling"; return GRIORA_Bilinear;
|
||||||
|
case mapnik::SCALING_BICUBIC: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL Cubic resampling"; return GRIORA_Cubic;
|
||||||
|
case mapnik::SCALING_SPLINE16: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL CubicSpline resampling"; return GRIORA_CubicSpline;
|
||||||
|
case mapnik::SCALING_SPLINE36: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL CubicSpline resampling"; return GRIORA_CubicSpline;
|
||||||
|
case mapnik::SCALING_HANNING: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL Gauss resampling"; return GRIORA_Gauss;
|
||||||
|
case mapnik::SCALING_HAMMING: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL Gauss resampling"; return GRIORA_Gauss;
|
||||||
|
case mapnik::SCALING_HERMITE: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL Cubic resampling"; return GRIORA_Cubic;
|
||||||
|
case mapnik::SCALING_KAISER: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL Lanczos resampling"; return GRIORA_Lanczos;
|
||||||
|
case mapnik::SCALING_QUADRIC: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL Lanczos resampling"; return GRIORA_Lanczos;
|
||||||
|
case mapnik::SCALING_CATROM: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL Cubic resampling"; return GRIORA_Cubic;
|
||||||
|
case mapnik::SCALING_GAUSSIAN: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL Gauss resampling"; return GRIORA_Gauss;
|
||||||
|
case mapnik::SCALING_BESSEL: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL Lanczos resampling"; return GRIORA_Lanczos;
|
||||||
|
case mapnik::SCALING_MITCHELL: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL Cubic resampling"; return GRIORA_Cubic;
|
||||||
|
case mapnik::SCALING_SINC: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL Lanczos resampling"; return GRIORA_Lanczos;
|
||||||
|
case mapnik::SCALING_LANCZOS: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL Lanczos resampling"; return GRIORA_Lanczos;
|
||||||
|
case mapnik::SCALING_BLACKMAN: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Using GDAL Lanczos resampling"; return GRIORA_Lanczos;
|
||||||
|
}
|
||||||
|
|
||||||
|
MAPNIK_LOG_WARN(gdal) << "No valid resampling method found using Nearest Neighbor";
|
||||||
|
return GRIORA_NearestNeighbour;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
feature_ptr gdal_featureset::next()
|
feature_ptr gdal_featureset::next()
|
||||||
{
|
{
|
||||||
if (first_)
|
if (first_)
|
||||||
|
@ -124,33 +154,6 @@ feature_ptr gdal_featureset::next()
|
||||||
return feature_ptr();
|
return feature_ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void gdal_featureset::find_best_overview(int bandNumber,
|
|
||||||
int ideal_width,
|
|
||||||
int ideal_height,
|
|
||||||
int & current_width,
|
|
||||||
int & current_height) const
|
|
||||||
{
|
|
||||||
GDALRasterBand * band = dataset_.GetRasterBand(bandNumber);
|
|
||||||
int band_overviews = band->GetOverviewCount();
|
|
||||||
if (band_overviews > 0)
|
|
||||||
{
|
|
||||||
for (int b = 0; b < band_overviews; b++)
|
|
||||||
{
|
|
||||||
GDALRasterBand * overview = band->GetOverview(b);
|
|
||||||
int overview_width = overview->GetXSize();
|
|
||||||
int overview_height = overview->GetYSize();
|
|
||||||
if ((overview_width < current_width ||
|
|
||||||
overview_height < current_height) &&
|
|
||||||
ideal_width <= overview_width &&
|
|
||||||
ideal_height <= overview_height)
|
|
||||||
{
|
|
||||||
current_width = overview_width;
|
|
||||||
current_height = overview_height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
{
|
{
|
||||||
feature_ptr feature = feature_factory::create(ctx_,1);
|
feature_ptr feature = feature_factory::create(ctx_,1);
|
||||||
|
@ -225,94 +228,26 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
int width = end_x - x_off;
|
int width = end_x - x_off;
|
||||||
int height = end_y - y_off;
|
int height = end_y - y_off;
|
||||||
|
|
||||||
// In many cases we want GDAL to simply return the exact image so we
|
|
||||||
// can handle resampling internally in mapnik. In other cases such as
|
|
||||||
// when overviews exist or when the image allocated might be too large
|
|
||||||
// we want to utilize some resampling in GDAL instead.
|
|
||||||
int im_height = height;
|
|
||||||
int im_width = width;
|
|
||||||
double im_offset_x = x_off;
|
double im_offset_x = x_off;
|
||||||
double im_offset_y = y_off;
|
double im_offset_y = y_off;
|
||||||
int current_width = static_cast<int>(raster_width_);
|
|
||||||
int current_height = static_cast<int>(raster_height_);
|
|
||||||
|
|
||||||
// loop through overviews -- snap up in resolution to closest overview
|
// resolution is 1 / requested pixel size
|
||||||
// if necessary we find an image size that most resembles
|
|
||||||
// the resolution of our output image.
|
|
||||||
const double width_res = std::get<0>(q.resolution());
|
const double width_res = std::get<0>(q.resolution());
|
||||||
const double height_res = std::get<1>(q.resolution());
|
const double height_res = std::get<1>(q.resolution());
|
||||||
const int ideal_raster_width = static_cast<int>(
|
int im_width = int(width_res * intersect.width() + 0.5);
|
||||||
std::floor(raster_extent_.width() *
|
int im_height = int(height_res * intersect.height() + 0.5);
|
||||||
width_res * filter_factor) + .5);
|
|
||||||
const int ideal_raster_height = static_cast<int>(
|
|
||||||
std::floor(raster_extent_.height() *
|
|
||||||
height_res * filter_factor) + .5);
|
|
||||||
|
|
||||||
if (band_ > 0 && band_ < nbands_)
|
// no upsampling in gdal
|
||||||
{
|
if (im_width > width)
|
||||||
find_best_overview(band_,
|
{im_width=width;}
|
||||||
ideal_raster_width,
|
if (im_height > height)
|
||||||
ideal_raster_height,
|
{im_height=height;}
|
||||||
current_width,
|
|
||||||
current_height);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i = 0; i < nbands_; ++i)
|
|
||||||
{
|
|
||||||
find_best_overview(i + 1,
|
|
||||||
ideal_raster_width,
|
|
||||||
ideal_raster_height,
|
|
||||||
current_width,
|
|
||||||
current_height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current_width != (int)raster_width_ ||
|
|
||||||
current_height != (int)raster_height_)
|
|
||||||
{
|
|
||||||
if (current_width != (int)raster_width_)
|
|
||||||
{
|
|
||||||
double ratio = (double)current_width / (double)raster_width_;
|
|
||||||
im_offset_x = std::floor(ratio * im_offset_x);
|
|
||||||
im_width = static_cast<int>(std::ceil(ratio * im_width));
|
|
||||||
}
|
|
||||||
if (current_height != (int)raster_height_)
|
|
||||||
{
|
|
||||||
double ratio = (double)current_height / (double)raster_height_;
|
|
||||||
im_offset_y = std::floor(ratio * im_offset_y);
|
|
||||||
im_height = static_cast<int>(std::ceil(ratio * im_height));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t im_area = (int64_t)im_width * (int64_t)im_height;
|
|
||||||
if (im_area > max_image_area_)
|
|
||||||
{
|
|
||||||
int adjusted_width = static_cast<int>(std::round(std::sqrt(max_image_area_ * ((double)im_width / (double)im_height))));
|
|
||||||
int adjusted_height = static_cast<int>(std::round(std::sqrt(max_image_area_ * ((double)im_height / (double)im_width))));
|
|
||||||
if (adjusted_width < 1)
|
|
||||||
{
|
|
||||||
adjusted_width = 1;
|
|
||||||
}
|
|
||||||
if (adjusted_height < 1)
|
|
||||||
{
|
|
||||||
adjusted_height = 1;
|
|
||||||
}
|
|
||||||
double ratio_x = (double)adjusted_width / (double)im_width;
|
|
||||||
double ratio_y = (double)adjusted_height / (double)im_height;
|
|
||||||
im_offset_x = ratio_x * im_offset_x;
|
|
||||||
im_offset_y = ratio_y * im_offset_y;
|
|
||||||
im_width = adjusted_width;
|
|
||||||
im_height = adjusted_height;
|
|
||||||
current_width = static_cast<int>(std::floor((ratio_x * current_width) + 0.5));
|
|
||||||
current_height = static_cast<int>(std::floor((ratio_y * current_height) + 0.5));
|
|
||||||
}
|
|
||||||
|
|
||||||
//calculate actual box2d of returned raster
|
//calculate actual box2d of returned raster
|
||||||
view_transform t2(current_width, current_height, raster_extent_, 0, 0);
|
box2d<double> feature_raster_extent(x_off, y_off, x_off + width, y_off + height);
|
||||||
box2d<double> feature_raster_extent(im_offset_x, im_offset_y, im_offset_x + im_width, im_offset_y + im_height);
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Feature Raster extent=" << feature_raster_extent;
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Feature Raster extent=" << feature_raster_extent;
|
||||||
feature_raster_extent = t2.backward(feature_raster_extent);
|
feature_raster_extent = t.backward(feature_raster_extent);
|
||||||
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Raster extent=" << raster_extent_;
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Raster extent=" << raster_extent_;
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Feature Raster extent=" << feature_raster_extent;
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Feature Raster extent=" << feature_raster_extent;
|
||||||
|
@ -324,9 +259,13 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
if (width > 0 && height > 0)
|
if (width > 0 && height > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Requested Image Size=(" << width << "," << height << ")";
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Requested Size from gdal=(" << width << "," << height << ")";
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Image Size=(" << im_width << "," << im_height << ")";
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Internal Image Size=(" << im_width << "," << im_height << ")";
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Reading band=" << band_;
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Reading band=" << band_;
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: requested resampling method=" << scaling_method_to_string(q.get_scaling_method());
|
||||||
|
GDALRasterIOExtraArg psExtraArg;
|
||||||
|
INIT_RASTERIO_EXTRA_ARG(psExtraArg);
|
||||||
|
psExtraArg.eResampleAlg = get_gdal_resample_alg(q.get_scaling_method());
|
||||||
if (band_ > 0) // we are querying a single band
|
if (band_ > 0) // we are querying a single band
|
||||||
{
|
{
|
||||||
GDALRasterBand * band = dataset_.GetRasterBand(band_);
|
GDALRasterBand * band = dataset_.GetRasterBand(band_);
|
||||||
|
@ -346,7 +285,7 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
||||||
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||||
image.data(), image.width(), image.height(),
|
image.data(), image.width(), image.height(),
|
||||||
GDT_Byte, 0, 0);
|
GDT_Byte, 0, 0, &psExtraArg);
|
||||||
if (raster_io_error == CE_Failure)
|
if (raster_io_error == CE_Failure)
|
||||||
{
|
{
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
@ -366,7 +305,7 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
||||||
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||||
image.data(), image.width(), image.height(),
|
image.data(), image.width(), image.height(),
|
||||||
GDT_Float32, 0, 0);
|
GDT_Float32, 0, 0, &psExtraArg);
|
||||||
if (raster_io_error == CE_Failure)
|
if (raster_io_error == CE_Failure)
|
||||||
{
|
{
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
@ -385,7 +324,7 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
||||||
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||||
image.data(), image.width(), image.height(),
|
image.data(), image.width(), image.height(),
|
||||||
GDT_UInt16, 0, 0);
|
GDT_UInt16, 0, 0, &psExtraArg);
|
||||||
if (raster_io_error == CE_Failure)
|
if (raster_io_error == CE_Failure)
|
||||||
{
|
{
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
@ -424,7 +363,7 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
||||||
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||||
image.data(), image.width(), image.height(),
|
image.data(), image.width(), image.height(),
|
||||||
GDT_Int16, 0, 0);
|
GDT_Int16, 0, 0, &psExtraArg);
|
||||||
if (raster_io_error == CE_Failure)
|
if (raster_io_error == CE_Failure)
|
||||||
{
|
{
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
@ -533,7 +472,7 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
float* imageData = (float*)image.bytes();
|
float* imageData = (float*)image.bytes();
|
||||||
raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height,
|
raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||||
imageData, image.width(), image.height(),
|
imageData, image.width(), image.height(),
|
||||||
GDT_Float32, 0, 0);
|
GDT_Float32, 0, 0, &psExtraArg);
|
||||||
if (raster_io_error == CE_Failure) {
|
if (raster_io_error == CE_Failure) {
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
}
|
}
|
||||||
|
@ -564,7 +503,7 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
image.bytes(),
|
image.bytes(),
|
||||||
image.width(), image.height(), GDT_Byte,
|
image.width(), image.height(), GDT_Byte,
|
||||||
nBandsToRead, nullptr,
|
nBandsToRead, nullptr,
|
||||||
4, 4 * image.width(), 1);
|
4, 4 * image.width(), 1, &psExtraArg);
|
||||||
if (raster_io_error == CE_Failure) {
|
if (raster_io_error == CE_Failure) {
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
}
|
}
|
||||||
|
@ -572,17 +511,20 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 0,
|
raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 0,
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width(),
|
||||||
|
&psExtraArg);
|
||||||
if (raster_io_error == CE_Failure) {
|
if (raster_io_error == CE_Failure) {
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
}
|
}
|
||||||
raster_io_error = green->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 1,
|
raster_io_error = green->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 1,
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width(),
|
||||||
|
&psExtraArg);
|
||||||
if (raster_io_error == CE_Failure) {
|
if (raster_io_error == CE_Failure) {
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
}
|
}
|
||||||
raster_io_error = blue->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 2,
|
raster_io_error = blue->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 2,
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width(),
|
||||||
|
&psExtraArg);
|
||||||
if (raster_io_error == CE_Failure) {
|
if (raster_io_error == CE_Failure) {
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
}
|
}
|
||||||
|
@ -622,7 +564,7 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
float* imageData = (float*)image.bytes();
|
float* imageData = (float*)image.bytes();
|
||||||
raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height,
|
raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||||
imageData, image.width(), image.height(),
|
imageData, image.width(), image.height(),
|
||||||
GDT_Float32, 0, 0);
|
GDT_Float32, 0, 0, &psExtraArg);
|
||||||
if (raster_io_error == CE_Failure)
|
if (raster_io_error == CE_Failure)
|
||||||
{
|
{
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
@ -642,21 +584,24 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
}
|
}
|
||||||
|
|
||||||
raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 0,
|
raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 0,
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width(),
|
||||||
|
&psExtraArg);
|
||||||
if (raster_io_error == CE_Failure)
|
if (raster_io_error == CE_Failure)
|
||||||
{
|
{
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
}
|
}
|
||||||
|
|
||||||
raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.bytes() + 1,
|
raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.bytes() + 1,
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width(),
|
||||||
|
&psExtraArg);
|
||||||
if (raster_io_error == CE_Failure)
|
if (raster_io_error == CE_Failure)
|
||||||
{
|
{
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
}
|
}
|
||||||
|
|
||||||
raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.bytes() + 2,
|
raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.bytes() + 2,
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width(),
|
||||||
|
&psExtraArg);
|
||||||
|
|
||||||
if (raster_io_error == CE_Failure)
|
if (raster_io_error == CE_Failure)
|
||||||
{
|
{
|
||||||
|
@ -693,7 +638,8 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
if (!raster_has_nodata || (red && green && blue))
|
if (!raster_has_nodata || (red && green && blue))
|
||||||
{
|
{
|
||||||
raster_io_error = alpha->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 3,
|
raster_io_error = alpha->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 3,
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width(),
|
||||||
|
&psExtraArg);
|
||||||
if (raster_io_error == CE_Failure) {
|
if (raster_io_error == CE_Failure) {
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
}
|
}
|
||||||
|
@ -718,7 +664,8 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
if (!raster_has_nodata)
|
if (!raster_has_nodata)
|
||||||
{
|
{
|
||||||
raster_io_error = mask->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 3,
|
raster_io_error = mask->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 3,
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width(),
|
||||||
|
&psExtraArg);
|
||||||
if (raster_io_error == CE_Failure) {
|
if (raster_io_error == CE_Failure) {
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
// boost
|
// boost
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
// gdal
|
||||||
|
#include <gdal_priv.h>
|
||||||
|
|
||||||
class GDALDataset;
|
class GDALDataset;
|
||||||
class GDALRasterBand;
|
class GDALRasterBand;
|
||||||
|
|
||||||
|
@ -66,20 +69,14 @@ public:
|
||||||
double dx,
|
double dx,
|
||||||
double dy,
|
double dy,
|
||||||
boost::optional<double> const& nodata,
|
boost::optional<double> const& nodata,
|
||||||
double nodata_tolerance,
|
double nodata_tolerance);
|
||||||
int64_t max_image_area);
|
|
||||||
virtual ~gdal_featureset();
|
virtual ~gdal_featureset();
|
||||||
mapnik::feature_ptr next();
|
mapnik::feature_ptr next();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void find_best_overview(int bandNumber,
|
|
||||||
int ideal_width,
|
|
||||||
int ideal_height,
|
|
||||||
int & current_width,
|
|
||||||
int & current_height) const;
|
|
||||||
|
|
||||||
mapnik::feature_ptr get_feature(mapnik::query const& q);
|
mapnik::feature_ptr get_feature(mapnik::query const& q);
|
||||||
mapnik::feature_ptr get_feature_at_point(mapnik::coord2d const& p);
|
mapnik::feature_ptr get_feature_at_point(mapnik::coord2d const& p);
|
||||||
|
GDALRIOResampleAlg get_gdal_resample_alg(mapnik::scaling_method_e mapnik_scaling_method);
|
||||||
GDALDataset & dataset_;
|
GDALDataset & dataset_;
|
||||||
mapnik::context_ptr ctx_;
|
mapnik::context_ptr ctx_;
|
||||||
int band_;
|
int band_;
|
||||||
|
@ -92,7 +89,6 @@ private:
|
||||||
int nbands_;
|
int nbands_;
|
||||||
boost::optional<double> nodata_value_;
|
boost::optional<double> nodata_value_;
|
||||||
double nodata_tolerance_;
|
double nodata_tolerance_;
|
||||||
int64_t max_image_area_;
|
|
||||||
bool first_;
|
bool first_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit bacfd251da550fa82ea56f6710dc6f85431480c2
|
Subproject commit 018ee7b6f129145fd6bab9ea987ccfa6d8028f1e
|
Loading…
Reference in a new issue