apply mapnik-0.7.1.mr.raster-position2.diff from mar_rud to close #475
This commit is contained in:
parent
231a273cba
commit
49afe197c3
5 changed files with 181 additions and 100 deletions
|
@ -305,7 +305,7 @@ namespace mapnik {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Image>
|
template <typename Image>
|
||||||
inline void scale_image_bilinear (Image& target,const Image& source)
|
inline void scale_image_bilinear (Image& target,const Image& source, double x_off_f=0, double y_off_f=0)
|
||||||
{
|
{
|
||||||
|
|
||||||
int source_width=source.width();
|
int source_width=source.width();
|
||||||
|
@ -319,28 +319,43 @@ namespace mapnik {
|
||||||
int x=0,y=0,xs=0,ys=0;
|
int x=0,y=0,xs=0,ys=0;
|
||||||
int tw2 = target_width/2;
|
int tw2 = target_width/2;
|
||||||
int th2 = target_height/2;
|
int th2 = target_height/2;
|
||||||
|
int offs_x = int(round((source_width-target_width-x_off_f*2*source_width)/2));
|
||||||
|
int offs_y = int(round((source_height-target_height-y_off_f*2*source_height)/2));
|
||||||
|
unsigned yprt, yprt1, xprt, xprt1;
|
||||||
|
|
||||||
|
//no scaling or subpixel offset
|
||||||
|
if (target_height == source_height && target_width == source_width && offs_x == 0 && offs_y == 0){
|
||||||
|
for (y=0;y<target_height;++y)
|
||||||
|
target.setRow(y,source.getRow(y),target_width);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (y=0;y<target_height;++y)
|
for (y=0;y<target_height;++y)
|
||||||
{
|
{
|
||||||
ys = y*source_height/target_height;
|
ys = (y*source_height+offs_y)/target_height;
|
||||||
int ys1 = ys+1;
|
int ys1 = ys+1;
|
||||||
if (ys1>=source_height)
|
if (ys1>=source_height)
|
||||||
ys1--;
|
ys1--;
|
||||||
unsigned yprt = y*source_height%target_height;
|
if (ys<0)
|
||||||
unsigned yprt1 = target_height-yprt;
|
ys=ys1=0;
|
||||||
|
if (source_height/2<target_height)
|
||||||
|
yprt = (y*source_height+offs_y)%target_height;
|
||||||
|
else
|
||||||
|
yprt = th2;
|
||||||
|
yprt1 = target_height-yprt;
|
||||||
for (x=0;x<target_width;++x)
|
for (x=0;x<target_width;++x)
|
||||||
{
|
{
|
||||||
xs = x*source_width/target_width;
|
xs = (x*source_width+offs_x)/target_width;
|
||||||
if (source_width>=target_width || source_height>=target_height){
|
if (source_width/2<target_width)
|
||||||
target(x,y)=source(xs,ys);
|
xprt = (x*source_width+offs_x)%target_width;
|
||||||
continue;
|
else
|
||||||
}
|
xprt = tw2;
|
||||||
unsigned xprt = x*source_width%target_width;
|
xprt1 = target_width-xprt;
|
||||||
unsigned xprt1 = target_width-xprt;
|
|
||||||
int xs1 = xs+1;
|
int xs1 = xs+1;
|
||||||
if (xs1>=source_width)
|
if (xs1>=source_width)
|
||||||
xs1--;
|
xs1--;
|
||||||
|
if (xs<0)
|
||||||
|
xs=xs1=0;
|
||||||
|
|
||||||
unsigned a = source(xs,ys);
|
unsigned a = source(xs,ys);
|
||||||
unsigned b = source(xs1,ys);
|
unsigned b = source(xs1,ys);
|
||||||
|
@ -377,7 +392,7 @@ namespace mapnik {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Image>
|
template <typename Image>
|
||||||
inline void scale_image_bilinear8 (Image& target,const Image& source)
|
inline void scale_image_bilinear8 (Image& target,const Image& source, double x_off_f=0, double y_off_f=0)
|
||||||
{
|
{
|
||||||
|
|
||||||
int source_width=source.width();
|
int source_width=source.width();
|
||||||
|
@ -391,28 +406,43 @@ namespace mapnik {
|
||||||
int x=0,y=0,xs=0,ys=0;
|
int x=0,y=0,xs=0,ys=0;
|
||||||
int tw2 = target_width/2;
|
int tw2 = target_width/2;
|
||||||
int th2 = target_height/2;
|
int th2 = target_height/2;
|
||||||
|
int offs_x = int(round((source_width-target_width-x_off_f*2*source_width)/2));
|
||||||
|
int offs_y = int(round((source_height-target_height-y_off_f*2*source_height)/2));
|
||||||
|
unsigned yprt, yprt1, xprt, xprt1;
|
||||||
|
|
||||||
|
//no scaling or subpixel offset
|
||||||
|
if (target_height == source_height && target_width == source_width && offs_x == 0 && offs_y == 0){
|
||||||
|
for (y=0;y<target_height;++y)
|
||||||
|
target.setRow(y,source.getRow(y),target_width);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (y=0;y<target_height;++y)
|
for (y=0;y<target_height;++y)
|
||||||
{
|
{
|
||||||
ys = y*source_height/target_height;
|
ys = (y*source_height+offs_y)/target_height;
|
||||||
int ys1 = ys+1;
|
int ys1 = ys+1;
|
||||||
if (ys1>=source_height)
|
if (ys1>=source_height)
|
||||||
ys1--;
|
ys1--;
|
||||||
unsigned yprt = y*source_height%target_height;
|
if (ys<0)
|
||||||
unsigned yprt1 = target_height-yprt;
|
ys=ys1=0;
|
||||||
|
if (source_height/2<target_height)
|
||||||
|
yprt = (y*source_height+offs_y)%target_height;
|
||||||
|
else
|
||||||
|
yprt = th2;
|
||||||
|
yprt1 = target_height-yprt;
|
||||||
for (x=0;x<target_width;++x)
|
for (x=0;x<target_width;++x)
|
||||||
{
|
{
|
||||||
xs = x*source_width/target_width;
|
xs = (x*source_width+offs_x)/target_width;
|
||||||
if (source_width>=target_width || source_height>=target_height){
|
if (source_width/2<target_width)
|
||||||
target(x,y)=source(xs,ys);
|
xprt = (x*source_width+offs_x)%target_width;
|
||||||
continue;
|
else
|
||||||
}
|
xprt = tw2;
|
||||||
unsigned xprt = x*source_width%target_width;
|
xprt1 = target_width-xprt;
|
||||||
unsigned xprt1 = target_width-xprt;
|
|
||||||
int xs1 = xs+1;
|
int xs1 = xs+1;
|
||||||
if (xs1>=source_width)
|
if (xs1>=source_width)
|
||||||
xs1--;
|
xs1--;
|
||||||
|
if (xs<0)
|
||||||
|
xs=xs1=0;
|
||||||
|
|
||||||
unsigned a = source(xs,ys);
|
unsigned a = source(xs,ys);
|
||||||
unsigned b = source(xs1,ys);
|
unsigned b = source(xs1,ys);
|
||||||
|
|
|
@ -104,25 +104,30 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
Envelope<double> intersect = raster_extent.intersect(q.get_bbox());
|
Envelope<double> intersect = raster_extent.intersect(q.get_bbox());
|
||||||
Envelope<double> box = t.forward(intersect);
|
Envelope<double> box = t.forward(intersect);
|
||||||
|
|
||||||
// TODO: error check this further...
|
//select minimum raster containing whole box
|
||||||
float x_off_f = (intersect.minx()-raster_extent.minx()) / fabs(dx);
|
int x_off = static_cast<int>(floor(box.minx()));
|
||||||
float y_off_f = (raster_extent.maxy()-intersect.maxy()) / fabs(dy);
|
int y_off = static_cast<int>(floor(box.miny()));
|
||||||
|
int end_x = static_cast<int>(ceil(box.maxx()));
|
||||||
if (x_off_f < 0)
|
int end_y = static_cast<int>(ceil(box.maxy()));
|
||||||
{
|
//clip to available data
|
||||||
x_off_f = 0;
|
if (x_off < 0)
|
||||||
}
|
x_off = 0;
|
||||||
|
if (y_off < 0)
|
||||||
if (y_off_f < 0)
|
y_off = 0;
|
||||||
{
|
if (end_x > raster_width)
|
||||||
y_off_f = 0;
|
end_x = raster_width;
|
||||||
}
|
if (end_y > raster_height)
|
||||||
|
end_y = raster_height;
|
||||||
int x_off = static_cast<int>(x_off_f);
|
int width = end_x - x_off;
|
||||||
int y_off = static_cast<int>(y_off_f);
|
int height = end_y - y_off;
|
||||||
|
// don't process almost invisible data
|
||||||
int width = int(box.width() + 0.5);
|
if (box.width() < 0.5)
|
||||||
int height = int(box.height() + 0.5);
|
width = 0;
|
||||||
|
if (box.height() < 0.5)
|
||||||
|
height = 0;
|
||||||
|
//calculate actual envelope of returned raster
|
||||||
|
Envelope<double> feature_raster_extent(x_off, y_off, x_off+width, y_off+height);
|
||||||
|
intersect = t.backward(feature_raster_extent);
|
||||||
|
|
||||||
#ifdef MAPNIK_DEBUG
|
#ifdef MAPNIK_DEBUG
|
||||||
std::clog << "GDAL Plugin: Raster extent=" << raster_extent << "\n";
|
std::clog << "GDAL Plugin: Raster extent=" << raster_extent << "\n";
|
||||||
|
|
|
@ -73,9 +73,33 @@ feature_ptr raster_featureset<LookupPolicy>::next()
|
||||||
CoordTransform t(image_width,image_height,extent_,0,0);
|
CoordTransform t(image_width,image_height,extent_,0,0);
|
||||||
Envelope<double> intersect=bbox_.intersect(curIter_->envelope());
|
Envelope<double> intersect=bbox_.intersect(curIter_->envelope());
|
||||||
Envelope<double> ext=t.forward(intersect);
|
Envelope<double> ext=t.forward(intersect);
|
||||||
ImageData32 image(int(ext.width()+0.5),int(ext.height()+0.5));
|
if ( ext.width()>0.5 && ext.height()>0.5 )
|
||||||
reader->read(int(ext.minx()+0.5),int(ext.miny()+0.5),image);
|
{
|
||||||
feature->set_raster(mapnik::raster_ptr(new raster(intersect,image)));
|
//select minimum raster containing whole ext
|
||||||
|
int x_off = static_cast<int>(floor(ext.minx()));
|
||||||
|
int y_off = static_cast<int>(floor(ext.miny()));
|
||||||
|
int end_x = static_cast<int>(ceil(ext.maxx()));
|
||||||
|
int end_y = static_cast<int>(ceil(ext.maxy()));
|
||||||
|
//clip to available data
|
||||||
|
if (x_off < 0)
|
||||||
|
x_off = 0;
|
||||||
|
if (y_off < 0)
|
||||||
|
y_off = 0;
|
||||||
|
if (end_x > image_width)
|
||||||
|
end_x = image_width;
|
||||||
|
if (end_y > image_height)
|
||||||
|
end_y = image_height;
|
||||||
|
int width = end_x - x_off;
|
||||||
|
int height = end_y - y_off;
|
||||||
|
//calculate actual envelope of returned raster
|
||||||
|
Envelope<double> feature_raster_extent(x_off, y_off, x_off+width, y_off+height);
|
||||||
|
intersect = t.backward(feature_raster_extent);
|
||||||
|
|
||||||
|
ImageData32 image(width,height);
|
||||||
|
reader->read(x_off,y_off,image);
|
||||||
|
|
||||||
|
feature->set_raster(mapnik::raster_ptr(new raster(intersect,image)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -714,50 +714,60 @@ namespace mapnik
|
||||||
if (raster)
|
if (raster)
|
||||||
{
|
{
|
||||||
Envelope<double> ext=t_.forward(raster->ext_);
|
Envelope<double> ext=t_.forward(raster->ext_);
|
||||||
ImageData32 target(int(ceil(ext.width())),int(ceil(ext.height())));
|
int start_x = int(round(ext.minx()));
|
||||||
int start_x = int(ext.minx()+0.5);
|
int start_y = int(round(ext.miny()));
|
||||||
int start_y = int(ext.miny()+0.5);
|
int raster_width = int(round(ext.width()));
|
||||||
|
int raster_height = int(round(ext.height()));
|
||||||
|
int end_x = start_x + raster_width;
|
||||||
|
int end_y = start_y + raster_height;
|
||||||
|
double err_offs_x = (ext.minx()-start_x + ext.maxx()-end_x)/2;
|
||||||
|
double err_offs_y = (ext.miny()-start_y + ext.maxy()-end_y)/2;
|
||||||
|
|
||||||
|
if (raster_width > 0 && raster_height > 0)
|
||||||
|
{
|
||||||
|
ImageData32 target(raster_width,raster_height);
|
||||||
|
|
||||||
if (sym.get_scaling() == "fast") {
|
if (sym.get_scaling() == "fast") {
|
||||||
scale_image<ImageData32>(target,raster->data_);
|
scale_image<ImageData32>(target,raster->data_);
|
||||||
} else if (sym.get_scaling() == "bilinear"){
|
} else if (sym.get_scaling() == "bilinear"){
|
||||||
scale_image_bilinear<ImageData32>(target,raster->data_);
|
scale_image_bilinear<ImageData32>(target,raster->data_, err_offs_x, err_offs_y);
|
||||||
} else if (sym.get_scaling() == "bilinear8"){
|
} else if (sym.get_scaling() == "bilinear8"){
|
||||||
scale_image_bilinear8<ImageData32>(target,raster->data_);
|
scale_image_bilinear8<ImageData32>(target,raster->data_, err_offs_x, err_offs_y);
|
||||||
} else {
|
} else {
|
||||||
scale_image<ImageData32>(target,raster->data_);
|
scale_image<ImageData32>(target,raster->data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sym.get_mode() == "normal"){
|
if (sym.get_mode() == "normal"){
|
||||||
if (sym.get_opacity() == 1.0) {
|
if (sym.get_opacity() == 1.0) {
|
||||||
pixmap_.set_rectangle(start_x,start_y,target);
|
pixmap_.set_rectangle(start_x,start_y,target);
|
||||||
} else {
|
} else {
|
||||||
pixmap_.set_rectangle_alpha2(target,start_x,start_y, sym.get_opacity());
|
pixmap_.set_rectangle_alpha2(target,start_x,start_y, sym.get_opacity());
|
||||||
}
|
}
|
||||||
} else if (sym.get_mode() == "grain_merge"){
|
} else if (sym.get_mode() == "grain_merge"){
|
||||||
pixmap_.template merge_rectangle<MergeGrain> (target,start_x,start_y, sym.get_opacity());
|
pixmap_.template merge_rectangle<MergeGrain> (target,start_x,start_y, sym.get_opacity());
|
||||||
} else if (sym.get_mode() == "grain_merge2"){
|
} else if (sym.get_mode() == "grain_merge2"){
|
||||||
pixmap_.template merge_rectangle<MergeGrain2> (target,start_x,start_y, sym.get_opacity());
|
pixmap_.template merge_rectangle<MergeGrain2> (target,start_x,start_y, sym.get_opacity());
|
||||||
} else if (sym.get_mode() == "multiply"){
|
} else if (sym.get_mode() == "multiply"){
|
||||||
pixmap_.template merge_rectangle<Multiply> (target,start_x,start_y, sym.get_opacity());
|
pixmap_.template merge_rectangle<Multiply> (target,start_x,start_y, sym.get_opacity());
|
||||||
} else if (sym.get_mode() == "multiply2"){
|
} else if (sym.get_mode() == "multiply2"){
|
||||||
pixmap_.template merge_rectangle<Multiply2> (target,start_x,start_y, sym.get_opacity());
|
pixmap_.template merge_rectangle<Multiply2> (target,start_x,start_y, sym.get_opacity());
|
||||||
} else if (sym.get_mode() == "divide"){
|
} else if (sym.get_mode() == "divide"){
|
||||||
pixmap_.template merge_rectangle<Divide> (target,start_x,start_y, sym.get_opacity());
|
pixmap_.template merge_rectangle<Divide> (target,start_x,start_y, sym.get_opacity());
|
||||||
} else if (sym.get_mode() == "divide2"){
|
} else if (sym.get_mode() == "divide2"){
|
||||||
pixmap_.template merge_rectangle<Divide2> (target,start_x,start_y, sym.get_opacity());
|
pixmap_.template merge_rectangle<Divide2> (target,start_x,start_y, sym.get_opacity());
|
||||||
} else if (sym.get_mode() == "screen"){
|
} else if (sym.get_mode() == "screen"){
|
||||||
pixmap_.template merge_rectangle<Screen> (target,start_x,start_y, sym.get_opacity());
|
pixmap_.template merge_rectangle<Screen> (target,start_x,start_y, sym.get_opacity());
|
||||||
} else if (sym.get_mode() == "hard_light"){
|
} else if (sym.get_mode() == "hard_light"){
|
||||||
pixmap_.template merge_rectangle<HardLight> (target,start_x,start_y, sym.get_opacity());
|
pixmap_.template merge_rectangle<HardLight> (target,start_x,start_y, sym.get_opacity());
|
||||||
} else {
|
} else {
|
||||||
if (sym.get_opacity() == 1.0){
|
if (sym.get_opacity() == 1.0){
|
||||||
pixmap_.set_rectangle(start_x,start_y,target);
|
pixmap_.set_rectangle(start_x,start_y,target);
|
||||||
} else {
|
} else {
|
||||||
pixmap_.set_rectangle_alpha2(target,start_x,start_y, sym.get_opacity());
|
pixmap_.set_rectangle_alpha2(target,start_x,start_y, sym.get_opacity());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// TODO: other modes? (add,diff,sub,...)
|
||||||
}
|
}
|
||||||
// TODO: other modes? (add,diff,sub,...)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -974,22 +974,34 @@ namespace mapnik
|
||||||
if (raster)
|
if (raster)
|
||||||
{
|
{
|
||||||
Envelope<double> ext = t_.forward(raster->ext_);
|
Envelope<double> ext = t_.forward(raster->ext_);
|
||||||
ImageData32 target(int(ext.width() + 0.5), int(ext.height() + 0.5));
|
int start_x = int(round(ext.minx()));
|
||||||
//TODO -- use cairo matrix transformation for scaling
|
int start_y = int(round(ext.miny()));
|
||||||
if (sym.get_scaling() == "fast"){
|
int raster_width = int(round(ext.width()));
|
||||||
scale_image<ImageData32>(target, raster->data_);
|
int raster_height = int(round(ext.height()));
|
||||||
} else if (sym.get_scaling() == "bilinear"){
|
int end_x = start_x + raster_width;
|
||||||
scale_image_bilinear<ImageData32>(target,raster->data_);
|
int end_y = start_y + raster_height;
|
||||||
} else if (sym.get_scaling() == "bilinear8"){
|
double err_offs_x = (ext.minx()-start_x + ext.maxx()-end_x)/2;
|
||||||
scale_image_bilinear8<ImageData32>(target,raster->data_);
|
double err_offs_y = (ext.miny()-start_y + ext.maxy()-end_y)/2;
|
||||||
} else {
|
|
||||||
scale_image<ImageData32>(target,raster->data_);
|
if (raster_width > 0 && raster_height > 0)
|
||||||
|
{
|
||||||
|
ImageData32 target(raster_width, raster_height);
|
||||||
|
//TODO -- use cairo matrix transformation for scaling
|
||||||
|
if (sym.get_scaling() == "fast"){
|
||||||
|
scale_image<ImageData32>(target, raster->data_);
|
||||||
|
} else if (sym.get_scaling() == "bilinear"){
|
||||||
|
scale_image_bilinear<ImageData32>(target,raster->data_, err_offs_x, err_offs_y);
|
||||||
|
} else if (sym.get_scaling() == "bilinear8"){
|
||||||
|
scale_image_bilinear8<ImageData32>(target,raster->data_, err_offs_x, err_offs_y);
|
||||||
|
} else {
|
||||||
|
scale_image<ImageData32>(target,raster->data_);
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_context context(context_);
|
||||||
|
|
||||||
|
//TODO -- support for advanced image merging
|
||||||
|
context.add_image(start_x, start_y, target, sym.get_opacity());
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_context context(context_);
|
|
||||||
|
|
||||||
//TODO -- support for advanced image merging
|
|
||||||
context.add_image(int(ext.minx()+0.5), int(ext.miny()+0.5), target, sym.get_opacity());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue