support for palette based PNGs, user 'png256' as a format parameter (see updated rundemo.py)
This commit is contained in:
parent
4586586448
commit
58f4431df1
9 changed files with 450 additions and 62 deletions
|
@ -29,6 +29,9 @@ using mapnik::ImageData32;
|
|||
using mapnik::image_view;
|
||||
using mapnik::save_to_file;
|
||||
|
||||
void (*view_to_file1)(std::string const&,std::string const&, image_view<ImageData32> const&) = mapnik::save_to_file;
|
||||
void (*view_to_file2)(std::string const&, image_view<ImageData32> const&) = mapnik::save_to_file;
|
||||
|
||||
void export_image_view()
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
@ -37,5 +40,6 @@ void export_image_view()
|
|||
.def("height",&image_view<ImageData32>::height)
|
||||
;
|
||||
|
||||
//def("save_to_file",save_to_file<image_view<ImageData32> >);
|
||||
def("save_to_file",view_to_file1);
|
||||
def("save_to_file",view_to_file2);
|
||||
}
|
||||
|
|
|
@ -305,7 +305,7 @@ m.zoom_to_box(Envelope(1405120.04127408,-247003.813399447,1706357.31328276,-2509
|
|||
|
||||
# Render two maps, one PNG, one JPEG.
|
||||
|
||||
render_to_file(m, 'demo.png', 'png')
|
||||
render_to_file(m, 'demo.png', 'png256') # save to palette based (max 256 colours) png
|
||||
render_to_file(m, 'demo.jpg', 'jpeg')
|
||||
|
||||
print """\n\nTwo maps have been rendered in the current directory:
|
||||
|
|
|
@ -57,8 +57,10 @@ namespace mapnik
|
|||
virtual ~ImageReader() {}
|
||||
};
|
||||
|
||||
bool register_image_reader(const std::string& type,ImageReader* (*)(const std::string&));
|
||||
MAPNIK_DECL ImageReader* get_image_reader(const std::string& type,const std::string& file);
|
||||
bool register_image_reader(const std::string& type,ImageReader* (*)(const std::string&));
|
||||
MAPNIK_DECL ImageReader* get_image_reader(const std::string& file,const std::string& type);
|
||||
MAPNIK_DECL ImageReader* get_image_reader(const std::string& file);
|
||||
|
||||
}
|
||||
|
||||
#endif //IMAGE_READER_HPP
|
||||
|
|
|
@ -31,8 +31,9 @@ namespace mapnik {
|
|||
template <typename T>
|
||||
class image_view
|
||||
{
|
||||
typedef typename T::pixel_type pixel_type;
|
||||
public:
|
||||
public:
|
||||
typedef typename T::pixel_type pixel_type;
|
||||
|
||||
image_view(unsigned x, unsigned y, unsigned width, unsigned height, T const& data)
|
||||
: x_(x),
|
||||
y_(y),
|
||||
|
|
225
include/mapnik/octree.hpp
Normal file
225
include/mapnik/octree.hpp
Normal file
|
@ -0,0 +1,225 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2006 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
//$Id$
|
||||
|
||||
#ifndef _OCTREE_HPP_
|
||||
#define _OCTREE_HPP_
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
typedef uint8_t byte ;
|
||||
struct rgb
|
||||
{
|
||||
byte r;
|
||||
byte g;
|
||||
byte b;
|
||||
rgb(byte r_, byte b_, byte g_)
|
||||
: r(r_), g(g_), b(b_) {}
|
||||
};
|
||||
|
||||
struct RGBPolicy
|
||||
{
|
||||
const static unsigned MAX_LEVELS = 6;
|
||||
inline static unsigned index_from_level(unsigned level, rgb const& c)
|
||||
{
|
||||
unsigned shift = 7 - level;
|
||||
return (((c.r >> shift) & 1) << 2)
|
||||
| (((c.g >> shift) & 1) << 1)
|
||||
| ((c.b >> shift) & 1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename InsertPolicy = RGBPolicy >
|
||||
class octree : private boost::noncopyable
|
||||
{
|
||||
struct node
|
||||
{
|
||||
node ()
|
||||
: next_node_(0),
|
||||
reds(0),
|
||||
greens(0),
|
||||
blues(0),
|
||||
count(0),
|
||||
index(0)
|
||||
{
|
||||
memset(&children_[0],0,sizeof(children_));
|
||||
}
|
||||
|
||||
~node ()
|
||||
{
|
||||
for (unsigned i = 0;i < 8; ++i) {
|
||||
if (children_[i] != 0) delete children_[i],children_[i]=0;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_leaf() const { return count != 0; }
|
||||
node * children_[8];
|
||||
node * next_node_;
|
||||
unsigned reds;
|
||||
unsigned greens;
|
||||
unsigned blues;
|
||||
unsigned count;
|
||||
uint8_t index;
|
||||
};
|
||||
struct node_cmp
|
||||
{
|
||||
bool operator() ( const node * lhs,const node* rhs ) const
|
||||
{
|
||||
unsigned left_total=0;
|
||||
unsigned right_total=0;
|
||||
for (unsigned i=0; i<8;++i)
|
||||
{
|
||||
if (lhs->children_[i]) left_total+=lhs->children_[i]->count;
|
||||
if (rhs->children_[i]) right_total+=rhs->children_[i]->count;
|
||||
}
|
||||
return lhs > rhs;
|
||||
}
|
||||
};
|
||||
std::set<node*,node_cmp> reducible_[InsertPolicy::MAX_LEVELS];
|
||||
unsigned max_colors_;
|
||||
unsigned colors_;
|
||||
unsigned leaf_level_;
|
||||
|
||||
public:
|
||||
explicit octree(unsigned max_colors=255)
|
||||
: max_colors_(max_colors),
|
||||
colors_(0),
|
||||
leaf_level_(InsertPolicy::MAX_LEVELS),
|
||||
root_(new node())
|
||||
{}
|
||||
|
||||
~octree() { delete root_;}
|
||||
|
||||
void insert(T const& data)
|
||||
{
|
||||
unsigned level = 0;
|
||||
node * cur_node = root_;
|
||||
while (true) {
|
||||
|
||||
if ( cur_node->count > 0 || level == leaf_level_)
|
||||
{
|
||||
cur_node->reds += data.r;
|
||||
cur_node->greens += data.g;
|
||||
cur_node->blues += data.b;
|
||||
cur_node->count += 1;
|
||||
if (cur_node->count == 1) ++colors_;
|
||||
if (colors_ >= max_colors_ - 1)
|
||||
{
|
||||
reduce();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned idx = InsertPolicy::index_from_level(level,data);
|
||||
if (cur_node->children_[idx] == 0) {
|
||||
cur_node->children_[idx] = new node();
|
||||
if (level < leaf_level_-1) {
|
||||
reducible_[level+1].insert(cur_node->children_[idx]);
|
||||
}
|
||||
}
|
||||
cur_node = cur_node->children_[idx];
|
||||
++level;
|
||||
}
|
||||
}
|
||||
int quantize(rgb const& c) const
|
||||
{
|
||||
unsigned level = 0;
|
||||
node * cur_node = root_;
|
||||
while (cur_node)
|
||||
{
|
||||
if (cur_node->count != 0) return cur_node->index;
|
||||
unsigned idx = InsertPolicy::index_from_level(level,c);
|
||||
cur_node = cur_node->children_[idx];
|
||||
++level;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void create_palette(std::vector<rgb> & palette) const
|
||||
{
|
||||
palette.reserve(colors_);
|
||||
create_palette(palette, root_);
|
||||
}
|
||||
private:
|
||||
void reduce()
|
||||
{
|
||||
while (leaf_level_ >0 && reducible_[leaf_level_-1].size() == 0)
|
||||
{
|
||||
--leaf_level_;
|
||||
}
|
||||
|
||||
if (leaf_level_ < 1) return;
|
||||
|
||||
typename std::set<node*,node_cmp>::iterator pos = reducible_[leaf_level_-1].begin();
|
||||
if (pos == reducible_[leaf_level_-1].end()) return;
|
||||
|
||||
node * cur_node = *pos;
|
||||
unsigned num_children = 0;
|
||||
for (unsigned idx=0; idx < 8; ++idx)
|
||||
{
|
||||
if (cur_node->children_[idx] != 0)
|
||||
{
|
||||
++num_children;
|
||||
cur_node->reds += cur_node->children_[idx]->reds;
|
||||
cur_node->greens += cur_node->children_[idx]->greens;
|
||||
cur_node->blues += cur_node->children_[idx]->blues;
|
||||
cur_node->count += cur_node->children_[idx]->count;
|
||||
delete cur_node->children_[idx], cur_node->children_[idx]=0;
|
||||
}
|
||||
}
|
||||
|
||||
reducible_[leaf_level_-1].erase(pos);
|
||||
if (num_children > 0 )
|
||||
{
|
||||
colors_ -= (num_children - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void create_palette(std::vector<rgb> & palette, node * itr) const
|
||||
{
|
||||
if (itr->count != 0)
|
||||
{
|
||||
unsigned count = itr->count;
|
||||
palette.push_back(rgb(uint8_t(itr->reds/float(count)),
|
||||
uint8_t(itr->greens/float(count)),
|
||||
uint8_t(itr->blues/float(count))));
|
||||
itr->index = palette.size() - 1;
|
||||
}
|
||||
for (unsigned i=0; i < 8 ;++i)
|
||||
{
|
||||
if (itr->children_[i] != 0)
|
||||
create_palette(palette, itr->children_[i]);
|
||||
}
|
||||
|
||||
}
|
||||
private:
|
||||
node * root_;
|
||||
};
|
||||
} // namespace mapnik
|
||||
|
||||
#endif /* _OCTREE_HPP_ */
|
|
@ -50,11 +50,16 @@ feature_ptr gdal_featureset::next()
|
|||
GDALRasterBand * grey = 0;
|
||||
for (int i = 0; i < dataset_.GetRasterCount() ;++i)
|
||||
{
|
||||
GDALRasterBand * band = dataset_.GetRasterBand(i+1);
|
||||
GDALRasterBand * band = dataset_.GetRasterBand(i+1);
|
||||
//if (band->GetOverviewCount() > 0)
|
||||
//{
|
||||
// band = band->GetOverview(0);
|
||||
//}
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
int bsx,bsy;
|
||||
band->GetBlockSize(&bsx,&bsy);
|
||||
std::cout << boost::format("Block=%dx%d Type=%s Color=%s \n") % bsx % bsy
|
||||
int bsx,bsy;
|
||||
band->GetBlockSize(&bsx,&bsy);
|
||||
std::cout << boost::format("Block=%dx%d Type=%s Color=%s \n") % bsx % bsy
|
||||
% GDALGetDataTypeName(band->GetRasterDataType())
|
||||
% GDALGetColorInterpretationName(band->GetColorInterpretation());
|
||||
#endif
|
||||
|
@ -77,30 +82,30 @@ feature_ptr gdal_featureset::next()
|
|||
grey = band;
|
||||
break;
|
||||
case GCI_PaletteIndex:
|
||||
{
|
||||
grey = band;
|
||||
GDALColorTable *color_table = band->GetColorTable();
|
||||
{
|
||||
grey = band;
|
||||
GDALColorTable *color_table = band->GetColorTable();
|
||||
|
||||
if ( color_table)
|
||||
{
|
||||
int count = color_table->GetColorEntryCount();
|
||||
if ( color_table)
|
||||
{
|
||||
int count = color_table->GetColorEntryCount();
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::cout << "Color Table count = " << count << "\n";´
|
||||
std::cout << "Color Table count = " << count << "\n";
|
||||
#endif
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
const GDALColorEntry *ce = color_table->GetColorEntry ( i );
|
||||
if (!ce ) continue;
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
const GDALColorEntry *ce = color_table->GetColorEntry ( i );
|
||||
if (!ce ) continue;
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::cout << "color entry RGB (" << ce->c1 <<"," <<ce->c2 << "," << ce->c3 << ")\n";
|
||||
std::cout << "color entry RGB (" << ce->c1 <<"," <<ce->c2 << "," << ce->c3 << ")\n";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GCI_Undefined:
|
||||
grey = band;
|
||||
break;
|
||||
grey = band;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
//$Id: image_reader.cpp 17 2005-03-08 23:58:43Z pavlenko $
|
||||
|
||||
#include <mapnik/image_reader.hpp>
|
||||
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/factory.hpp>
|
||||
|
||||
namespace mapnik
|
||||
|
@ -36,8 +36,14 @@ namespace mapnik
|
|||
return ImageReaderFactory::instance()->register_product(type,fun);
|
||||
}
|
||||
|
||||
ImageReader* get_image_reader(const std::string& type,const std::string& file)
|
||||
ImageReader* get_image_reader(const std::string& filename,const std::string& type)
|
||||
{
|
||||
return ImageReaderFactory::instance()->create_object(type,file);
|
||||
return ImageReaderFactory::instance()->create_object(type,filename);
|
||||
}
|
||||
|
||||
ImageReader* get_image_reader(const std::string& filename)
|
||||
{
|
||||
std::string type = type_from_filename(filename);
|
||||
return ImageReaderFactory::instance()->create_object(filename,type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/memory.hpp>
|
||||
#include <mapnik/image_view.hpp>
|
||||
#include <mapnik/octree.hpp>
|
||||
// jpeg png
|
||||
extern "C"
|
||||
{
|
||||
|
@ -52,6 +53,7 @@ namespace mapnik
|
|||
{
|
||||
//all this should go into image_writer factory
|
||||
if (type=="png") save_as_png(file,image);
|
||||
else if (type == "png256") save_as_png256(file,image);
|
||||
else if (type=="jpeg") save_as_jpeg(file,85,image);
|
||||
}
|
||||
}
|
||||
|
@ -123,6 +125,150 @@ namespace mapnik
|
|||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void reduce_8 (T const& in, ImageData8 & out, octree<rgb> & tree)
|
||||
{
|
||||
unsigned width = in.width();
|
||||
unsigned height = in.height();
|
||||
for (unsigned y = 0; y < height; ++y)
|
||||
{
|
||||
mapnik::ImageData32::pixel_type const * row = in.getRow(y);
|
||||
mapnik::ImageData8::pixel_type * row_out = out.getRow(y);
|
||||
for (unsigned x = 0; x < width; ++x)
|
||||
{
|
||||
unsigned val = row[x];
|
||||
mapnik::rgb c((val)&0xff, (val>>8)&0xff, (val>>16) & 0xff);
|
||||
uint8_t index = tree.quantize(c);
|
||||
row_out[x] = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void reduce_4 (T const& in, ImageData8 & out, octree<rgb> & tree)
|
||||
{
|
||||
unsigned width = in.width();
|
||||
unsigned height = in.height();
|
||||
|
||||
for (unsigned y = 0; y < height; ++y)
|
||||
{
|
||||
mapnik::ImageData32::pixel_type const * row = in.getRow(y);
|
||||
mapnik::ImageData8::pixel_type * row_out = out.getRow(y);
|
||||
|
||||
for (unsigned x = 0; x < width; ++x)
|
||||
{
|
||||
unsigned val = row[x];
|
||||
mapnik::rgb c((val)&0xff, (val>>8)&0xff, (val>>16) & 0xff);
|
||||
uint8_t index = tree.quantize(c);
|
||||
if (x%2 > 0) index = index<<4;
|
||||
row_out[x>>1] |= index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 1-bit but only one color.
|
||||
template <typename T>
|
||||
void reduce_1(T const&, ImageData8 & out, octree<rgb> &)
|
||||
{
|
||||
out.set(0); // only one color!!!
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void save_as_png(T & file, std::vector<mapnik::rgb> & palette,
|
||||
mapnik::ImageData8 const& image,
|
||||
unsigned width,
|
||||
unsigned height,
|
||||
unsigned color_depth)
|
||||
{
|
||||
png_voidp error_ptr=0;
|
||||
png_structp png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
||||
error_ptr,0, 0);
|
||||
|
||||
if (!png_ptr) return;
|
||||
|
||||
// switch on optimization only if supported
|
||||
#if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) && defined(PNG_MMX_CODE_SUPPORTED)
|
||||
png_uint_32 mask, flags;
|
||||
flags = png_get_asm_flags(png_ptr);
|
||||
mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
|
||||
png_set_asm_flags(png_ptr, flags | mask);
|
||||
#endif
|
||||
png_set_filter (png_ptr, 0, PNG_FILTER_NONE);
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr)
|
||||
{
|
||||
png_destroy_write_struct(&png_ptr,(png_infopp)0);
|
||||
return;
|
||||
}
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
{
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
return;
|
||||
}
|
||||
png_set_write_fn (png_ptr, &file, &write_data<T>, &flush_data<T>);
|
||||
|
||||
png_set_IHDR(png_ptr, info_ptr,width,height,color_depth,
|
||||
PNG_COLOR_TYPE_PALETTE,PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
png_set_PLTE(png_ptr,info_ptr,reinterpret_cast<png_color*>(&palette[0]),palette.size());
|
||||
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
for (unsigned i=0;i<height;i++)
|
||||
{
|
||||
png_write_row(png_ptr,(png_bytep)image.getRow(i));
|
||||
}
|
||||
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
}
|
||||
|
||||
template <typename T1,typename T2>
|
||||
void save_as_png256(T1 & file, T2 const& image)
|
||||
{
|
||||
octree<rgb> tree(256);
|
||||
unsigned width = image.width();
|
||||
unsigned height = image.height();
|
||||
for (unsigned y = 0; y < height; ++y)
|
||||
{
|
||||
typename T2::pixel_type const * row = image.getRow(y);
|
||||
for (unsigned x = 0; x < width; ++x)
|
||||
{
|
||||
unsigned val = row[x];
|
||||
tree.insert(mapnik::rgb((val)&0xff, (val>>8)&0xff, (val>>16) & 0xff));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<rgb> palette;
|
||||
tree.create_palette(palette);
|
||||
assert(palette.size() <= 256);
|
||||
|
||||
if (palette.size() > 16 )
|
||||
{
|
||||
// >16 && <=256 colors -> write 8-bit color depth
|
||||
ImageData8 reduced_image(width,height);
|
||||
reduce_8(image,reduced_image,tree);
|
||||
save_as_png(file,palette,reduced_image,width,height,8);
|
||||
}
|
||||
else if (palette.size() == 1)
|
||||
{
|
||||
// 1 color image -> write 1-bit color depth PNG
|
||||
unsigned image_width = (int(0.125*width) + 7)&~7;
|
||||
unsigned image_height = height;
|
||||
ImageData8 reduced_image(image_width,image_height);
|
||||
reduce_1(image,reduced_image,tree);
|
||||
save_as_png(file,palette,reduced_image,width,height,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// <=16 colors -> write 4-bit color depth PNG
|
||||
unsigned image_width = (int(0.5*width) + 3)&~3;
|
||||
unsigned image_height = height;
|
||||
ImageData8 reduced_image(image_width,image_height);
|
||||
reduce_4(image,reduced_image,tree);
|
||||
save_as_png(file,palette,reduced_image,width,height,4);
|
||||
}
|
||||
}
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
|
@ -222,7 +368,7 @@ namespace mapnik
|
|||
template void save_to_file<image_view<ImageData32> > (std::string const&,
|
||||
std::string const&,
|
||||
image_view<ImageData32> const&);
|
||||
|
||||
|
||||
template void save_to_file<image_view<ImageData32> > (std::string const&,
|
||||
image_view<ImageData32> const&);
|
||||
|
||||
|
|
|
@ -29,37 +29,36 @@
|
|||
|
||||
namespace mapnik {
|
||||
|
||||
symbolizer_with_image::symbolizer_with_image(boost::shared_ptr<ImageData32> img) :
|
||||
image_( img ) {}
|
||||
|
||||
symbolizer_with_image::symbolizer_with_image(std::string const& file,
|
||||
std::string const& type, unsigned width,unsigned height)
|
||||
: image_(new ImageData32(width,height)),
|
||||
image_filename_( file )
|
||||
{
|
||||
std::auto_ptr<ImageReader> reader(get_image_reader(type,file));
|
||||
if (reader.get())
|
||||
reader->read(0,0,*image_);
|
||||
}
|
||||
|
||||
|
||||
symbolizer_with_image::symbolizer_with_image( symbolizer_with_image const& rhs)
|
||||
: image_(rhs.image_), image_filename_(rhs.image_filename_) {}
|
||||
|
||||
|
||||
boost::shared_ptr<ImageData32> symbolizer_with_image::get_image() const
|
||||
{
|
||||
return image_;
|
||||
}
|
||||
void symbolizer_with_image::set_image(boost::shared_ptr<ImageData32> symbol)
|
||||
{
|
||||
image_ = symbol;
|
||||
}
|
||||
const std::string & symbolizer_with_image::get_filename() const
|
||||
{
|
||||
return image_filename_;
|
||||
}
|
||||
symbolizer_with_image::symbolizer_with_image(boost::shared_ptr<ImageData32> img) :
|
||||
image_( img ) {}
|
||||
|
||||
symbolizer_with_image::symbolizer_with_image(std::string const& file,
|
||||
std::string const& type, unsigned width,unsigned height)
|
||||
: image_(new ImageData32(width,height)),
|
||||
image_filename_( file )
|
||||
{
|
||||
std::auto_ptr<ImageReader> reader(get_image_reader(type,file));
|
||||
if (reader.get())
|
||||
reader->read(0,0,*image_);
|
||||
}
|
||||
|
||||
symbolizer_with_image::symbolizer_with_image( symbolizer_with_image const& rhs)
|
||||
: image_(rhs.image_), image_filename_(rhs.image_filename_) {}
|
||||
|
||||
|
||||
boost::shared_ptr<ImageData32> symbolizer_with_image::get_image() const
|
||||
{
|
||||
return image_;
|
||||
}
|
||||
void symbolizer_with_image::set_image(boost::shared_ptr<ImageData32> symbol)
|
||||
{
|
||||
image_ = symbol;
|
||||
}
|
||||
const std::string & symbolizer_with_image::get_filename() const
|
||||
{
|
||||
return image_filename_;
|
||||
}
|
||||
|
||||
} // end of namespace mapnik
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue