applied font fallbacj patch from Beau Gunderson

This commit is contained in:
Artem Pavlenko 2008-06-29 10:40:08 +00:00
parent 81ce983d5f
commit 3275cf9ce6
33 changed files with 786 additions and 465 deletions

View file

@ -45,18 +45,18 @@ opts.Add(PathOption('ICU_INCLUDES', 'Search path for ICU include files', '/usr/i
opts.Add(PathOption('ICU_LIBS','Search path for ICU include files','/usr/' + LIBDIR_SCHEMA))
opts.Add(PathOption('PNG_INCLUDES', 'Search path for libpng include files', '/usr/include'))
opts.Add(PathOption('PNG_LIBS','Search path for libpng include files','/usr/' + LIBDIR_SCHEMA))
opts.Add(PathOption('JPEG_INCLUDES', 'Search path for libjpeg include files', '/usr/include'))
opts.Add(PathOption('JPEG_LIBS', 'Search path for libjpeg library files', '/usr/' + LIBDIR_SCHEMA))
opts.Add(PathOption('JPEG_INCLUDES', 'Search path for libjpeg include files', '/usr/local/include'))
opts.Add(PathOption('JPEG_LIBS', 'Search path for libjpeg library files', '/usr/local/' + LIBDIR_SCHEMA))
opts.Add(PathOption('TIFF_INCLUDES', 'Search path for libtiff include files', '/usr/include'))
opts.Add(PathOption('TIFF_LIBS', 'Search path for libtiff library files', '/usr/' + LIBDIR_SCHEMA))
opts.Add(PathOption('PGSQL_INCLUDES', 'Search path for PostgreSQL include files', '/usr/include'))
opts.Add(PathOption('PGSQL_LIBS', 'Search path for PostgreSQL library files', '/usr/' + LIBDIR_SCHEMA))
opts.Add(PathOption('PROJ_INCLUDES', 'Search path for PROJ.4 include files', '/usr/local/include'))
opts.Add(PathOption('PROJ_LIBS', 'Search path for PROJ.4 library files', '/usr/local/' + LIBDIR_SCHEMA))
opts.Add(PathOption('PROJ_INCLUDES', 'Search path for PROJ.4 include files', '/opt/proj4/include'))
opts.Add(PathOption('PROJ_LIBS', 'Search path for PROJ.4 library files', '/opt/proj4/' + LIBDIR_SCHEMA))
opts.Add(PathOption('GDAL_INCLUDES', 'Search path for GDAL include files', '/usr/include'))
opts.Add(PathOption('GDAL_LIBS', 'Search path for GDAL library files', '/usr/' + LIBDIR_SCHEMA))
opts.Add(PathOption('PYTHON','Python executable', sys.executable))
opts.Add(ListOption('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster','gdal']))
opts.Add(ListOption('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster','gdal','osm']))
opts.Add(ListOption('BINDINGS','Language bindings to build','all',['python']))
opts.Add(BoolOption('DEBUG', 'Compile a debug version of mapnik', 'False'))
opts.Add('DESTDIR', 'The root directory to install into. Useful mainly for binary package building', '/')
@ -154,7 +154,7 @@ CXX_LIBSHEADERS = [
]
BOOST_LIBSHEADERS = [
# ['system', 'boost/system/system_error.hpp', True], # uncomment this on Darwin + boost_1_35
['system', 'boost/system/system_error.hpp', True], # uncomment this on Darwin + boost_1_35
['filesystem', 'boost/filesystem/operations.hpp', True],
['regex', 'boost/regex.hpp', True],
['iostreams','boost/iostreams/device/mapped_file.hpp',True],
@ -178,10 +178,11 @@ if len(env['BOOST_TOOLKIT']):
env['BOOST_APPEND'] = '-%s' % env['BOOST_TOOLKIT']
else:
env['BOOST_APPEND']=''
for count, libinfo in enumerate(BOOST_LIBSHEADERS):
if env['THREADING'] == 'multi' :
if not conf.CheckLibWithHeader('boost_%s%s%s' % (libinfo[0],env['BOOST_APPEND'],thread_suffix), libinfo[1], 'C++') and libinfo[2] :
if not conf.CheckLibWithHeader('boost_%s%s%s' % (libinfo[0],thread_suffix,env['BOOST_APPEND']), libinfo[1], 'C++') and libinfo[2] :
color_print(1,'Could not find header or shared library for boost %s, exiting!' % libinfo[0])
Exit(1)
elif not conf.CheckLibWithHeader('boost_%s%s' % (libinfo[0], env['BOOST_APPEND']), libinfo[1], 'C++') :
@ -203,11 +204,13 @@ SConscript('agg/SConscript')
SConscript('src/SConscript')
# Build shapeindex and remove its dependency from the LIBS
if 'boost_program_options%s%s' % (env['BOOST_APPEND'],thread_suffix) in env['LIBS']:
# if 'boost_program_options%s%s-1_35' % (env['BOOST_APPEND'],thread_suffix) in env['LIBS']:
if 'boost_program_options-mt-1_35' in env['LIBS']:
SConscript('utils/shapeindex/SConscript')
env['LIBS'].remove('boost_program_options%s%s' % (env['BOOST_APPEND'],thread_suffix))
env['LIBS'].remove('boost_program_options-mt-1_35')
# Build the input plug-ins
if 'postgis' in inputplugins and 'pq' in env['LIBS']:
SConscript('plugins/input/postgis/SConscript')
env['LIBS'].remove('pq')
@ -221,8 +224,8 @@ if 'raster' in inputplugins:
if 'gdal' in inputplugins and 'gdal' in env['LIBS']:
SConscript('plugins/input/gdal/SConscript')
if 'gigabase' in inputplugins and 'gigabase_r' in env['LIBS']:
SConscript('plugins/input/gigabase/SConscript')
if 'osm' in inputplugins :
SConscript('plugins/input/osm/SConscript')
# Build the Python bindings.
if 'python' in env['BINDINGS']:

View file

@ -33,7 +33,7 @@
// Provides faster access for massive pixel operations,
// such as blur, image filtering:
#define AGG_RENDERING_BUFFER row_ptr_cache<int8u>
//#define AGG_RENDERING_BUFFER row_ptr_cache<int8u>
//
// Provides cheaper creation and destruction (no mem allocs):
// #define AGG_RENDERING_BUFFER row_accessor<int8u>

View file

@ -40,19 +40,22 @@ if env['PLATFORM'] == 'FreeBSD':
linkflags = ''
libraries = ['mapnik','png','jpeg']
if env['THREADING'] == 'multi':
libraries.append('boost_python%s%s' % (env['BOOST_APPEND'],thread_suffix))
else :
libraries.append('boost_python%s' % env['BOOST_APPEND'])
#libraries.append('boost_python%s%s-1_35' % (env['BOOST_APPEND'],thread_suffix))
libraries.append('boost_python%s-1_35' % (thread_suffix))
#else :
# libraries.append('boost_python%s' % env['BOOST_APPEND'])
if env['PLATFORM'] == 'Darwin':
libraries.append(env['LIBS'])
libraries.append('icuuc')
libraries.append('icudata')
if env['THREADING'] == 'multi':
libraries.append('boost_regex%s%s' % (env['BOOST_APPEND'],thread_suffix))
else :
libraries.append('boost_regex%s' % env['BOOST_APPEND'])
if env['THREADING'] == 'multi':
libraries.append('boost_thread%s%s' % (env['BOOST_APPEND'],thread_suffix))
#if env['THREADING'] == 'multi':
# libraries.append('boost_regex%s%s' % (env['BOOST_APPEND'],thread_suffix))
#else :
# libraries.append('boost_regex%s' % env['BOOST_APPEND'])
#if env['THREADING'] == 'multi':
# libraries.append('boost_thread%s%s' % (env['BOOST_APPEND'],thread_suffix))
if '-DHAVE_PYCAIRO' in env['CXXFLAGS']:
libraries.append([lib for lib in env['LIBS'] if lib.startswith('cairo')])
linkflags = '-F/ -framework Python'

View file

@ -28,6 +28,7 @@
#include <mapnik/datasource_cache.hpp>
#include <mapnik/font_engine_freetype.hpp>
#include <mapnik/agg_renderer.hpp>
#include <mapnik/cairo_renderer.hpp>
#include <mapnik/filter_factory.hpp>
#include <mapnik/color_factory.hpp>
#include <mapnik/image_util.hpp>
@ -52,206 +53,47 @@ int main ( int argc , char** argv)
freetype_engine::register_font(mapnik_dir + "/lib/mapnik/fonts/DejaVuSans.ttf");
Map m(800,600);
m.set_background(color_factory::from_string("white"));
// create styles
mapnik::load_map(m,"/Users/artem/projects/openstreetmap/mapnik/openstreetmap_kleptog.xml");
m.zoomToBox(Envelope<double>(-762470.6985688356,4004842.088052442,-761928.349698612,4005328.834769584));
//Image32 buf(m.getWidth(),m.getHeight());
//agg_renderer<Image32> ren(m,buf);
//ren.apply();
//save_to_file<ImageData32>(buf.data(),"demo.jpg","jpeg");
//save_to_file<ImageData32>(buf.data(),"demo.png","png");
//save_to_file<ImageData32>(buf.data(),"demo256.png","png256");
//std::cout << "Three maps have been rendered in the current directory:\n"
// "- demo.jpg\n"
// "- demo.png\n"
// "- demo256.png\n"
// "Have a look!\n";
// Provinces (polygon)
feature_type_style provpoly_style;
rule_type provpoly_rule_on;
provpoly_rule_on.set_filter(create_filter("[NAME_EN] = 'Ontario'"));
provpoly_rule_on.append(polygon_symbolizer(Color(250, 190, 183)));
provpoly_style.add_rule(provpoly_rule_on);
rule_type provpoly_rule_qc;
provpoly_rule_qc.set_filter(create_filter("[NAME_EN] = 'Quebec'"));
provpoly_rule_qc.append(polygon_symbolizer(Color(217, 235, 203)));
provpoly_style.add_rule(provpoly_rule_qc);
m.insert_style("provinces",provpoly_style);
// Cairo renderer
// Provinces (polyline)
feature_type_style provlines_style;
// Pdf
Cairo::RefPtr<Cairo::PdfSurface> pdf = Cairo::PdfSurface::create("mapnik.pdf",m.getWidth(),m.getHeight());
mapnik::cairo_renderer<Cairo::Surface> cairo1(m, pdf);
cairo1.apply();
// Svg
//Cairo::RefPtr<Cairo::SvgSurface> svg = Cairo::SvgSurface::create("demo.svg",m.getWidth(),m.getHeight());
//mapnik::cairo_renderer<Cairo::Surface> cairo2(m, svg);
//cairo2.apply();
// Png
//Cairo::RefPtr<Cairo::ImageSurface> image = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32,m.getWidth(),m.getHeight());
//mapnik::cairo_renderer<Cairo::Surface> cairo3(m, image);
//cairo3.apply();
stroke provlines_stk (Color(0,0,0),1.0);
provlines_stk.add_dash(8, 4);
provlines_stk.add_dash(2, 2);
provlines_stk.add_dash(2, 2);
//std::string filename = "demo_cairo.png";
//image->write_to_png(filename);
rule_type provlines_rule;
provlines_rule.append(line_symbolizer(provlines_stk));
provlines_style.add_rule(provlines_rule);
// Ps
//Cairo::RefPtr<Cairo::PsSurface> ps = Cairo::PsSurface::create("demo.ps",m.getWidth(),m.getHeight());
//mapnik::cairo_renderer<Cairo::Surface> cairo4(m, ps);
//cairo4.apply();
m.insert_style("provlines",provlines_style);
// Drainage
feature_type_style qcdrain_style;
rule_type qcdrain_rule;
qcdrain_rule.set_filter(create_filter("[HYC] = 8"));
qcdrain_rule.append(polygon_symbolizer(Color(153, 204, 255)));
qcdrain_style.add_rule(qcdrain_rule);
m.insert_style("drainage",qcdrain_style);
// Roads 3 and 4 (The "grey" roads)
feature_type_style roads34_style;
rule_type roads34_rule;
roads34_rule.set_filter(create_filter("[CLASS] = 3 or [CLASS] = 4"));
stroke roads34_rule_stk(Color(171,158,137),2.0);
roads34_rule_stk.set_line_cap(ROUND_CAP);
roads34_rule_stk.set_line_join(ROUND_JOIN);
roads34_rule.append(line_symbolizer(roads34_rule_stk));
roads34_style.add_rule(roads34_rule);
m.insert_style("smallroads",roads34_style);
// Roads 2 (The thin yellow ones)
feature_type_style roads2_style_1;
rule_type roads2_rule_1;
roads2_rule_1.set_filter(create_filter("[CLASS] = 2"));
stroke roads2_rule_stk_1(Color(171,158,137),4.0);
roads2_rule_stk_1.set_line_cap(ROUND_CAP);
roads2_rule_stk_1.set_line_join(ROUND_JOIN);
roads2_rule_1.append(line_symbolizer(roads2_rule_stk_1));
roads2_style_1.add_rule(roads2_rule_1);
m.insert_style("road-border", roads2_style_1);
feature_type_style roads2_style_2;
rule_type roads2_rule_2;
roads2_rule_2.set_filter(create_filter("[CLASS] = 2"));
stroke roads2_rule_stk_2(Color(255,250,115),2.0);
roads2_rule_stk_2.set_line_cap(ROUND_CAP);
roads2_rule_stk_2.set_line_join(ROUND_JOIN);
roads2_rule_2.append(line_symbolizer(roads2_rule_stk_2));
roads2_style_2.add_rule(roads2_rule_2);
m.insert_style("road-fill", roads2_style_2);
// Roads 1 (The big orange ones, the highways)
feature_type_style roads1_style_1;
rule_type roads1_rule_1;
roads1_rule_1.set_filter(create_filter("[CLASS] = 1"));
stroke roads1_rule_stk_1(Color(188,149,28),7.0);
roads1_rule_stk_1.set_line_cap(ROUND_CAP);
roads1_rule_stk_1.set_line_join(ROUND_JOIN);
roads1_rule_1.append(line_symbolizer(roads1_rule_stk_1));
roads1_style_1.add_rule(roads1_rule_1);
m.insert_style("highway-border", roads1_style_1);
feature_type_style roads1_style_2;
rule_type roads1_rule_2;
roads1_rule_2.set_filter(create_filter("[CLASS] = 1"));
stroke roads1_rule_stk_2(Color(242,191,36),5.0);
roads1_rule_stk_2.set_line_cap(ROUND_CAP);
roads1_rule_stk_2.set_line_join(ROUND_JOIN);
roads1_rule_2.append(line_symbolizer(roads1_rule_stk_2));
roads1_style_2.add_rule(roads1_rule_2);
m.insert_style("highway-fill", roads1_style_2);
// Populated Places
feature_type_style popplaces_style;
rule_type popplaces_rule;
text_symbolizer popplaces_text_symbolizer("GEONAME","DejaVu Sans Book",10,Color(0,0,0));
popplaces_text_symbolizer.set_halo_fill(Color(255,255,200));
popplaces_text_symbolizer.set_halo_radius(1);
popplaces_rule.append(popplaces_text_symbolizer);
popplaces_style.add_rule(popplaces_rule);
m.insert_style("popplaces",popplaces_style );
// Layers
// Provincial polygons
{
parameters p;
p["type"]="shape";
p["file"]="../data/boundaries";
Layer lyr("Provinces");
lyr.set_datasource(datasource_cache::instance()->create(p));
lyr.add_style("provinces");
m.addLayer(lyr);
}
// Drainage
{
parameters p;
p["type"]="shape";
p["file"]="../data/qcdrainage";
Layer lyr("Quebec Hydrography");
lyr.set_datasource(datasource_cache::instance()->create(p));
lyr.add_style("drainage");
m.addLayer(lyr);
}
{
parameters p;
p["type"]="shape";
p["file"]="../data/ontdrainage";
Layer lyr("Ontario Hydrography");
lyr.set_datasource(datasource_cache::instance()->create(p));
lyr.add_style("drainage");
m.addLayer(lyr);
}
// Provincial boundaries
{
parameters p;
p["type"]="shape";
p["file"]="../data/boundaries_l";
Layer lyr("Provincial borders");
lyr.set_datasource(datasource_cache::instance()->create(p));
lyr.add_style("provlines");
m.addLayer(lyr);
}
// Roads
{
parameters p;
p["type"]="shape";
p["file"]="../data/roads";
Layer lyr("Roads");
lyr.set_datasource(datasource_cache::instance()->create(p));
lyr.add_style("smallroads");
lyr.add_style("road-border");
lyr.add_style("road-fill");
lyr.add_style("highway-border");
lyr.add_style("highway-fill");
m.addLayer(lyr);
}
// popplaces
{
parameters p;
p["type"]="shape";
p["file"]="../data/popplaces";
p["encoding"] = "latin1";
Layer lyr("Populated Places");
lyr.set_datasource(datasource_cache::instance()->create(p));
lyr.add_style("popplaces");
m.addLayer(lyr);
}
m.zoomToBox(Envelope<double>(1405120.04127408,-247003.813399447,
1706357.31328276,-25098.593149577));
Image32 buf(m.getWidth(),m.getHeight());
agg_renderer<Image32> ren(m,buf);
ren.apply();
save_to_file<ImageData32>(buf.data(),"demo.jpg","jpeg");
save_to_file<ImageData32>(buf.data(),"demo.png","png");
save_to_file<ImageData32>(buf.data(),"demo256.png","png256");
std::cout << "Three maps have been rendered in the current directory:\n"
"- demo.jpg\n"
"- demo.png\n"
"- demo256.png\n"
"Have a look!\n";
}
catch ( const mapnik::config_error & ex )
{

View file

@ -316,6 +316,8 @@ images.append('demo256.png')
im.save('demo.jpg', 'jpeg')
images.append('demo.jpg')
save_map(m,'map.xml')
# Render cairo examples
try:
import cairo

View file

@ -35,8 +35,11 @@ int main( int argc, char **argv )
freetype_engine::register_font("/opt/mapnik/lib/mapnik/fonts/DejaVuSans.ttf");
freetype_engine::register_font("/opt/mapnik/lib/mapnik/fonts/DejaVuSans-Bold.ttf");
freetype_engine::register_font("/opt/mapnik/lib/mapnik/fonts/DejaVuSansMono.ttf");
freetype_engine::register_font("/System/Library/Fonts/Monaco.dfont");
freetype_engine::register_font("/Users/artem/Desktop/japanese.otf");
freetype_engine::register_font("/Users/artem/Desktop/IPAfont00201/ipagp.ttf");
freetype_engine::register_font("/Users/artem/Desktop/IPAfont00201/ipag.ttf");
QApplication app( argc, argv );
MainWindow window;
window.show();

View file

@ -92,7 +92,7 @@ MainWindow::MainWindow()
// slider
connect(slider_,SIGNAL(valueChanged(int)),mapWidget_,SLOT(zoomToLevel(int)));
//
connect(layerTab_,SIGNAL(update_mapwidget()),mapWidget_,SLOT(updateMap()));
connect(layerTab_,SIGNAL(update_mapwidget()),mapWidget_,SLOT(renderMap()));
connect(layerTab_,SIGNAL(layerSelected(int)),
mapWidget_,SLOT(layerSelected(int)));
}

View file

@ -29,6 +29,7 @@
#include <mapnik/memory_datasource.hpp>
#include "mapwidget.hpp"
#include "info_dialog.hpp"
#include <unicode/unistr.h>
using mapnik::Image32;
using mapnik::Map;
@ -79,6 +80,8 @@ MapWidget::MapWidget(QWidget *parent)
pen_.setWidth(3);
pen_.setCapStyle(Qt::RoundCap);
pen_.setJoinStyle(Qt::RoundJoin);
connect(&thread_, SIGNAL(renderedMap(const QImage &)),
this, SLOT(updateMap(const QImage &)));
}
void MapWidget::setTool(eTool tool)
@ -121,7 +124,7 @@ void MapWidget::resizeEvent(QResizeEvent * ev)
if (map_)
{
map_->resize(ev->size().width(),ev->size().height());
updateMap();
renderMap();
}
}
@ -171,8 +174,9 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
{
if (itr->second.to_string().length() > 0)
{
UnicodeString unicode = itr->second.to_unicode();
info.push_back(QPair<QString,QString>(QString(itr->first.c_str()),
itr->second.to_string().c_str()));
QString((QChar*)unicode.getBuffer(),unicode.length())));
}
}
typedef mapnik::coord_transform2<mapnik::CoordTransform,mapnik::geometry2d> path_type;
@ -223,7 +227,7 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
}
else if (e->button()==Qt::RightButton)
{
//updateMap();
//renderMap();
}
}
@ -251,7 +255,7 @@ void MapWidget::mouseReleaseEvent(QMouseEvent* e)
CoordTransform t(map_->getWidth(),map_->getHeight(),map_->getCurrentExtent());
Envelope<double> box = t.backward(Envelope<double>(start_x_,start_y_,end_x_,end_y_));
map_->zoomToBox(box);
updateMap();
renderMap();
}
}
else if (cur_tool_==Pan)
@ -264,7 +268,7 @@ void MapWidget::mouseReleaseEvent(QMouseEvent* e)
int dx = end_x_ - start_x_;
int dy = end_y_ - start_y_;
map_->pan(cx - dx ,cy - dy);
updateMap();
renderMap();
}
}
}
@ -333,7 +337,7 @@ void MapWidget::zoomToBox(mapnik::Envelope<double> const& bbox)
if (map_)
{
map_->zoomToBox(bbox);
updateMap();
renderMap();
}
}
@ -343,7 +347,7 @@ void MapWidget::defaultView()
{
map_->resize(width(),height());
map_->zoom_all();
updateMap();
renderMap();
}
}
@ -352,7 +356,7 @@ void MapWidget::zoomIn()
if (map_)
{
map_->zoom(0.5);
updateMap();
renderMap();
}
}
@ -361,7 +365,7 @@ void MapWidget::zoomOut()
if (map_)
{
map_->zoom(2.0);
updateMap();
renderMap();
}
}
@ -372,7 +376,7 @@ void MapWidget::panUp()
double cx = 0.5*map_->getWidth();
double cy = 0.5*map_->getHeight();
map_->pan(int(cx),int(cy - cy*0.25));
updateMap();
renderMap();
}
}
@ -383,7 +387,7 @@ void MapWidget::panDown()
double cx = 0.5*map_->getWidth();
double cy = 0.5*map_->getHeight();
map_->pan(int(cx),int(cy + cy*0.25));
updateMap();
renderMap();
}
}
@ -394,7 +398,7 @@ void MapWidget::panLeft()
double cx = 0.5*map_->getWidth();
double cy = 0.5*map_->getHeight();
map_->pan(int(cx - cx * 0.25),int(cy));
updateMap();
renderMap();
}
}
@ -405,7 +409,7 @@ void MapWidget::panRight()
double cx = 0.5*map_->getWidth();
double cy = 0.5*map_->getHeight();
map_->pan(int(cx + cx * 0.25),int(cy));
updateMap();
renderMap();
}
}
@ -428,7 +432,7 @@ void MapWidget::zoomToLevel(int level)
pt.x + 0.5 * width * res,
pt.y + 0.5 * height*res);
map_->zoomToBox(box);
updateMap();
renderMap();
}
}
@ -441,24 +445,19 @@ void MapWidget::export_to_file(unsigned ,unsigned ,std::string const&,std::strin
}
void MapWidget::updateMap()
{
if (map_)
{
unsigned width=map_->getWidth();
unsigned height=map_->getHeight();
Image32 buf(width,height);
mapnik::agg_renderer<Image32> ren(*map_,buf);
ren.apply();
QImage image((uchar*)buf.raw_data(),width,height,QImage::Format_ARGB32);
pix_=QPixmap::fromImage(image.rgbSwapped());
update();
// emit signal to interested widgets
emit mapViewChanged();
std::cout << map_->getCurrentExtent() << "\n";
}
void MapWidget::renderMap()
{
thread_.render(map_);
}
void MapWidget::updateMap(QImage const& image)
{
std::cout << "updateMap called \n";
pix_ = QPixmap::fromImage(image);
update();
// emit signal to interested widgets
emit mapViewChanged();
std::cout << map_->getCurrentExtent() << "\n";
}
boost::shared_ptr<Map> MapWidget::getMap()

View file

@ -31,6 +31,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <mapnik/map.hpp>
#include "renderthread.hpp"
class MapWidget : public QWidget
{
@ -58,6 +59,7 @@ class MapWidget : public QWidget
bool first_;
QPen pen_;
int selectedLayer_;
RenderThread thread_;
public:
MapWidget(QWidget *parent=0);
void setTool(eTool tool);
@ -72,9 +74,10 @@ class MapWidget : public QWidget
void panRight();
void panUp();
void panDown();
void renderMap();
public slots:
void zoomToLevel(int level);
void updateMap();
void updateMap(QImage const&);
void layerSelected(int);
signals:
void mapViewChanged();

View file

@ -5,12 +5,12 @@ CC = g++
TEMPLATE = app
INCLUDEPATH += /opt/mapnik/include
INCLUDEPATH += /opt/boost/include/boost-1_34_1
INCLUDEPATH += /usr/local/include/freetype2
INCLUDEPATH += /opt/boost-trunk/include/boost-1_35
INCLUDEPATH += /usr/X11/include
INCLUDEPATH += .
QMAKE_CXXFLAGS +=' -DDARWIN'
unix:LIBS = -L/opt/mapnik/lib -lmapnik -lfreetype
unix:LIBS = -L/opt/mapnik/lib -L/opt/boost-trunk/lib -L/usr/X11/lib -lmapnik -lfreetype -licuuc -licudata -lboost_regex-mt-1_35 -lboost_filesystem-mt-1_35 -lboost_thread-mt-1_35 -lboost_system-mt-1_35 -lboost_program_options-mt-1_35
# Input
@ -24,7 +24,8 @@ HEADERS += mainwindow.hpp \
layerwidget.hpp \
layerlistmodel.hpp \
layerdelegate.hpp \
styles_model.hpp
styles_model.hpp \
renderthread.hpp
HEADERS += about_dialog.hpp \
info_dialog.hpp \
@ -36,7 +37,8 @@ SOURCES += main.cpp \
layerwidget.cpp \
layerlistmodel.cpp \
layerdelegate.cpp \
styles_model.cpp
styles_model.cpp \
renderthread.cpp
SOURCES += about_dialog.cpp \
info_dialog.cpp \

View file

@ -39,7 +39,7 @@
namespace mapnik {
class rasterizer;
struct rasterizer;
template <typename T>
class MAPNIK_DECL agg_renderer : public feature_style_processor<agg_renderer<T> >,

View file

@ -85,6 +85,64 @@ namespace mapnik {
proj_transform const& prj_trans_;
};
template <typename Transform,typename Geometry>
struct MAPNIK_DECL coord_transform4
{
coord_transform4(Transform const& t,
Geometry const& geom,
proj_transform const& prj_trans)
: t_(t),
geom_(geom),
prj_trans_(prj_trans),
prev_x_(0),
prev_y_(0) {}
unsigned vertex(double * x , double * y) const
{
unsigned command = geom_.vertex(x,y);
double z=0;
prj_trans_.backward(*x,*y,z);
t_.forward(x,y);
if (command == 1)
{
prev_x_ = *x;
prev_y_ = *y;
}
else
{
double dx = *x-prev_x_;
double dy = *y-prev_y_;
double d = dx*dx + dy*dy;
while ( d < 1)
{
command = geom_.vertex(x,y);
prj_trans_.backward(*x,*y,z);
t_.forward(x,y);
if (command == 1) break;
dx = *x-prev_x_;
dy = *y-prev_y_;
d = dx*dx+dy*dy;
}
prev_x_ = *x;
prev_y_ = *y;
}
return command;
}
void rewind (unsigned pos)
{
geom_.rewind(pos);
}
private:
Transform const& t_;
Geometry const& geom_;
proj_transform const& prj_trans_;
mutable double prev_x_;
mutable double prev_y_;
};
template <typename Transform,typename Geometry>
struct MAPNIK_DECL coord_transform3
{

View file

@ -30,6 +30,7 @@
#include <mapnik/ctrans.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/text_path.hpp>
#include <mapnik/font_set.hpp>
// freetype2
extern "C"
@ -61,9 +62,7 @@ namespace mapnik
class font_face : boost::noncopyable
{
public:
typedef std::pair<unsigned,unsigned> dimension_t;
font_face(FT_Face face)
font_face(FT_Face face)
: face_(face) {}
std::string family_name() const
@ -104,122 +103,11 @@ namespace mapnik
return false;
}
dimension_t character_dimensions(const unsigned c)
{
FT_Matrix matrix;
FT_Vector pen;
FT_Error error;
FT_GlyphSlot slot = face_->glyph;
pen.x = 0;
pen.y = 0;
FT_BBox glyph_bbox;
FT_Glyph image;
matrix.xx = (FT_Fixed)( 1 * 0x10000L );
matrix.xy = (FT_Fixed)( 0 * 0x10000L );
matrix.yx = (FT_Fixed)( 0 * 0x10000L );
matrix.yy = (FT_Fixed)( 1 * 0x10000L );
FT_Set_Transform (face_,&matrix,&pen);
FT_UInt glyph_index = FT_Get_Char_Index( face_, c);
error = FT_Load_Glyph (face_,glyph_index,FT_LOAD_NO_HINTING);
if ( error )
return dimension_t(0, 0);
error = FT_Get_Glyph( face_->glyph, &image);
if ( error )
return dimension_t(0, 0);
FT_Glyph_Get_CBox(image,ft_glyph_bbox_pixels, &glyph_bbox);
FT_Done_Glyph(image);
return dimension_t(slot->advance.x >> 6, glyph_bbox.yMax - glyph_bbox.yMin);
}
void get_string_info(string_info & info)
{
unsigned width = 0;
unsigned height = 0;
UErrorCode err = U_ZERO_ERROR;
UnicodeString const& ustr = info.get_string();
const UChar * text = ustr.getBuffer();
UBiDi * bidi = ubidi_openSized(ustr.length(),0,&err);
if (U_SUCCESS(err))
{
ubidi_setPara(bidi,text,ustr.length(), UBIDI_DEFAULT_LTR,0,&err);
if (U_SUCCESS(err))
{
int32_t count = ubidi_countRuns(bidi,&err);
int32_t logicalStart;
int32_t length;
for (int32_t i=0; i< count;++i)
{
if (UBIDI_LTR == ubidi_getVisualRun(bidi,i,&logicalStart,&length))
{
do {
UChar ch = text[logicalStart++];
dimension_t char_dim = character_dimensions(ch);
info.add_info(ch, char_dim.first, char_dim.second);
width += char_dim.first;
height = char_dim.second > height ? char_dim.second : height;
} while (--length > 0);
}
else
{
logicalStart += length;
int32_t j=0,i=length;
UnicodeString arabic;
UChar * buf = arabic.getBuffer(length);
do {
UChar ch = text[--logicalStart];
buf[j++] = ch;
} while (--i > 0);
arabic.releaseBuffer(length);
if ( *arabic.getBuffer() >= 0x0600 && *arabic.getBuffer() <= 0x06ff)
{
UnicodeString shaped;
u_shapeArabic(arabic.getBuffer(),arabic.length(),shaped.getBuffer(arabic.length()),arabic.length(),
U_SHAPE_LETTERS_SHAPE|U_SHAPE_LENGTH_FIXED_SPACES_NEAR|
U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,&err);
shaped.releaseBuffer(arabic.length());
if (U_SUCCESS(err))
{
for (int j=0;j<shaped.length();++j)
{
dimension_t char_dim = character_dimensions(shaped[j]);
info.add_info(shaped[j], char_dim.first, char_dim.second);
width += char_dim.first;
height = char_dim.second > height ? char_dim.second : height;
}
}
}
}
}
}
ubidi_close(bidi);
}
info.set_dimensions(width, height);
}
~font_face()
{
#ifdef MAPNIK_DEBUG
std::clog << "clean up face:" << family_name()<<":" << style_name() << std::endl;
std::clog << "~font_face: Clean up face \"" << family_name()
<< " " << style_name() << "\"" << std::endl;
#endif
FT_Done_Face(face_);
}
@ -228,8 +116,9 @@ namespace mapnik
FT_Face face_;
};
typedef boost::shared_ptr<font_face> face_ptr;
class MAPNIK_DECL freetype_engine // : public mapnik::singleton<freetype_engine,mapnik::CreateStatic>,
typedef boost::shared_ptr<font_face> face_ptr;
class MAPNIK_DECL freetype_engine // : public mapnik::singleton<freetype_engine,mapnik::CreateStatic>,
// private boost::noncopyable
{
// friend class mapnik::CreateStatic<freetype_engine>;
@ -281,6 +170,8 @@ namespace mapnik
template <typename T>
struct text_renderer : private boost::noncopyable
{
typedef std::pair<unsigned,unsigned> dimension_t;
struct glyph_t : boost::noncopyable
{
FT_Glyph image;
@ -291,16 +182,159 @@ namespace mapnik
typedef boost::ptr_vector<glyph_t> glyphs_t;
typedef T pixmap_type;
text_renderer (pixmap_type & pixmap, face_ptr face)
text_renderer (pixmap_type & pixmap, std::vector<face_ptr> faces)
: pixmap_(pixmap),
face_(face),
faces_(faces),
fill_(0,0,0),
halo_fill_(255,255,255),
halo_radius_(0) {}
dimension_t character_dimensions(const unsigned c)
{
FT_Matrix matrix;
FT_Vector pen;
FT_Error error;
pen.x = 0;
pen.y = 0;
FT_BBox glyph_bbox;
FT_Glyph image;
FT_Face face = (*faces_.begin())->get_face();
FT_UInt glyph_index = FT_Get_Char_Index(face, c);
// If there's no glyph_index we loop through the remaining fonts
// in the fontset looking for one.
if (!glyph_index) {
std::vector<face_ptr>::iterator itr = faces_.begin();
std::vector<face_ptr>::iterator end = faces_.end();
++itr; // Skip the first one, we already tried it.
for (; itr != end; ++itr)
{
FT_Face f = (*itr)->get_face();
glyph_index = FT_Get_Char_Index(f, c);
if (glyph_index) {
face = f;
break;
}
}
}
matrix.xx = (FT_Fixed)( 1 * 0x10000L );
matrix.xy = (FT_Fixed)( 0 * 0x10000L );
matrix.yx = (FT_Fixed)( 0 * 0x10000L );
matrix.yy = (FT_Fixed)( 1 * 0x10000L );
FT_Set_Transform(face, &matrix, &pen);
error = FT_Load_Glyph (face, glyph_index, FT_LOAD_NO_HINTING);
if ( error )
return dimension_t(0, 0);
error = FT_Get_Glyph(face->glyph, &image);
if ( error )
return dimension_t(0, 0);
FT_Glyph_Get_CBox(image, ft_glyph_bbox_pixels, &glyph_bbox);
FT_Done_Glyph(image);
unsigned tempx = face->glyph->advance.x >> 6;
unsigned tempy = glyph_bbox.yMax - glyph_bbox.yMin;
//std::clog << "glyph: " << glyph_index << " x: " << tempx << " y: " << tempy << std::endl;
return dimension_t(tempx, tempy);
}
void get_string_info(string_info & info)
{
unsigned width = 0;
unsigned height = 0;
UErrorCode err = U_ZERO_ERROR;
UnicodeString const& ustr = info.get_string();
const UChar * text = ustr.getBuffer();
UBiDi * bidi = ubidi_openSized(ustr.length(),0,&err);
if (U_SUCCESS(err))
{
ubidi_setPara(bidi,text,ustr.length(), UBIDI_DEFAULT_LTR,0,&err);
if (U_SUCCESS(err))
{
int32_t count = ubidi_countRuns(bidi,&err);
int32_t logicalStart;
int32_t length;
for (int32_t i=0; i< count;++i)
{
if (UBIDI_LTR == ubidi_getVisualRun(bidi,i,&logicalStart,&length))
{
do {
UChar ch = text[logicalStart++];
dimension_t char_dim = character_dimensions(ch);
info.add_info(ch, char_dim.first, char_dim.second);
width += char_dim.first;
height = char_dim.second > height ? char_dim.second : height;
} while (--length > 0);
}
else
{
logicalStart += length;
int32_t j=0,i=length;
UnicodeString arabic;
UChar * buf = arabic.getBuffer(length);
do {
UChar ch = text[--logicalStart];
buf[j++] = ch;
} while (--i > 0);
arabic.releaseBuffer(length);
if ( *arabic.getBuffer() >= 0x0600 && *arabic.getBuffer() <= 0x06ff)
{
UnicodeString shaped;
u_shapeArabic(arabic.getBuffer(),arabic.length(),shaped.getBuffer(arabic.length()),arabic.length(),
U_SHAPE_LETTERS_SHAPE|U_SHAPE_LENGTH_FIXED_SPACES_NEAR|
U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,&err);
shaped.releaseBuffer(arabic.length());
if (U_SUCCESS(err))
{
for (int j=0;j<shaped.length();++j)
{
dimension_t char_dim = character_dimensions(shaped[j]);
info.add_info(shaped[j], char_dim.first, char_dim.second);
width += char_dim.first;
height = char_dim.second > height ? char_dim.second : height;
}
}
}
}
}
}
ubidi_close(bidi);
}
info.set_dimensions(width, height);
}
void set_pixel_size(unsigned size)
{
face_->set_pixel_sizes(size);
std::vector<face_ptr>::iterator itr = faces_.begin();
std::vector<face_ptr>::iterator end = faces_.end();
for (; itr != end; ++itr)
{
(*itr)->set_pixel_sizes(size);
}
}
void set_fill(mapnik::Color const& fill)
@ -326,22 +360,25 @@ namespace mapnik
FT_Matrix matrix;
FT_Vector pen;
FT_Error error;
FT_Face face = face_->get_face();
// FT_GlyphSlot slot = face->glyph;
FT_BBox bbox;
bbox.xMin = bbox.yMin = 32000;
bbox.xMax = bbox.yMax = -32000; //hmm??
bbox.xMin = bbox.yMin = 32000; // Initialize these so we can tell if we
bbox.xMax = bbox.yMax = -32000; // properly grew the bbox later
std::vector<face_ptr>::iterator end = faces_.end();
for (int i = 0; i < path->num_nodes(); i++)
{
int c;
double x, y, angle;
path->vertex(&c, &x, &y, &angle);
// std::clog << " prepare_glyph: " << (unsigned char)c << "," << x << "," << y << "," << angle << std::endl;
path->vertex(&c, &x, &y, &angle);
#ifdef MAPNIK_DEBUG
// TODO Enable when we have support for setting verbosity
//std::clog << "prepare_glyphs: " << c << "," << x <<
// "," << y << "," << angle << std::endl;
#endif
FT_BBox glyph_bbox;
FT_Glyph image;
@ -349,23 +386,59 @@ namespace mapnik
pen.x = int(x * 64);
pen.y = int(y * 64);
FT_Face face = (*faces_.begin())->get_face();
FT_UInt glyph_index = FT_Get_Char_Index(face, unsigned(c));
// If there's no glyph_index we loop through the remaining fonts
// in the fontset looking for one.
if (!glyph_index) {
std::vector<face_ptr>::iterator itr = faces_.begin();
++itr; // Skip the first one, we already tried it.
for (; itr != end; ++itr)
{
#ifdef MAPNIK_DEBUG
// TODO Enable when we have support for setting verbosity
//std::clog << "prepare_glyphs: Falling back to font named \""
// << (*itr)->family_name() << " " << (*itr)->style_name()
// << "\"" << std::endl;
#endif
FT_Face f = (*itr)->get_face();
glyph_index = FT_Get_Char_Index(f, unsigned(c));
if (glyph_index) {
face = f;
break;
}
}
#ifdef MAPNIK_DEBUG
// TODO Enable when we have support for setting verbosity
//if (!glyph_index) {
// std::clog << "prepare_glyphs: Failed to fall back, glyph "
// << c << " not found in any font." << std::endl;
//}
#endif
}
matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
FT_Set_Transform (face,&matrix,&pen);
FT_UInt glyph_index = FT_Get_Char_Index( face, unsigned(c));
error = FT_Load_Glyph (face,glyph_index, FT_LOAD_NO_HINTING);
FT_Set_Transform(face, &matrix, &pen);
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_HINTING);
if ( error )
continue;
error = FT_Get_Glyph( face->glyph, &image);
error = FT_Get_Glyph(face->glyph, &image);
if ( error )
continue;
FT_Glyph_Get_CBox(image,ft_glyph_bbox_pixels, &glyph_bbox);
if (glyph_bbox.xMin < bbox.xMin)
bbox.xMin = glyph_bbox.xMin;
@ -375,7 +448,8 @@ namespace mapnik
bbox.xMax = glyph_bbox.xMax;
if (glyph_bbox.yMax > bbox.yMax)
bbox.yMax = glyph_bbox.yMax;
// Check if we properly grew the bbox
if ( bbox.xMin > bbox.xMax )
{
bbox.xMin = 0;
@ -484,7 +558,7 @@ namespace mapnik
}
pixmap_type & pixmap_;
face_ptr face_;
std::vector<face_ptr> faces_;
mapnik::Color fill_;
mapnik::Color halo_fill_;
int halo_radius_;
@ -494,5 +568,4 @@ namespace mapnik
};
}
#endif // FONT_ENGINE_FREETYPE_HPP

View file

@ -0,0 +1,54 @@
/*****************************************************************************
*
* 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 FONT_SET_HPP
#define FONT_SET_HPP
// mapnik
#include <mapnik/config.hpp>
// boost
#include <boost/shared_ptr.hpp>
// stl
#include <string>
#include <vector>
namespace mapnik
{
class MAPNIK_DECL FontSet
{
public:
FontSet();
FontSet(std::string const& name);
FontSet(FontSet const& rhs);
FontSet& operator=(FontSet const& rhs);
std::string const& get_name() const;
void add_face_name(std::string);
std::vector<std::string> const& get_face_names() const;
~FontSet();
private:
std::string name_;
std::vector<std::string> face_names_;
};
}
#endif //FONT_SET_HPP

View file

@ -80,6 +80,7 @@ namespace mapnik {
{
return width_;
}
inline unsigned height() const
{
return height_;
@ -89,15 +90,17 @@ namespace mapnik {
{
return data_.getRow(row + y_) + x_;
}
inline T& data()
{
return data_;
}
inline T const& data() const
{
return data_;
}
private:
unsigned x_;
unsigned y_;

View file

@ -37,6 +37,28 @@ namespace mapnik
{
class MAPNIK_DECL Map
{
public:
enum aspect_fix_mode
{
/* grow the width or height of the specified geo bbox to fill the map size. default behaviour. */
GROW_BBOX,
/* grow the width or height of the map to accomodate the specified geo bbox. */
GROW_CANVAS,
/* shrink the width or height of the specified geo bbox to fill the map size. */
SHRINK_BBOX,
/* shrink the width or height of the map to accomodate the specified geo bbox. */
SHRINK_CANVAS,
/* adjust the width of the specified geo bbox, leave height and map size unchanged */
ADJUST_BBOX_WIDTH,
/* adjust the height of the specified geo bbox, leave width and map size unchanged */
ADJUST_BBOX_HEIGHT,
/* adjust the width of the map, leave height and geo bbox unchanged */
ADJUST_CANVAS_WIDTH,
/* adjust the height of the map, leave width and geo bbox unchanged */
ADJUST_CANVAS_HEIGHT
};
private:
static const unsigned MIN_MAPSIZE=16;
static const unsigned MAX_MAPSIZE=MIN_MAPSIZE<<10;
unsigned width_;
@ -44,10 +66,13 @@ namespace mapnik
std::string srs_;
boost::optional<Color> background_;
std::map<std::string,feature_type_style> styles_;
std::map<std::string,FontSet> fontsets_;
std::vector<Layer> layers_;
Envelope<double> currentExtent_;
aspect_fix_mode aspectFixMode_;
public:
typedef std::map<std::string,feature_type_style>::const_iterator const_style_iterator;
typedef std::map<std::string,feature_type_style>::iterator style_iterator;
@ -129,6 +154,20 @@ namespace mapnik
*/
feature_type_style const& find_style(std::string const& name) const;
/*! \brief Insert a fontset into the map.
* @param name The name of the fontset.
* @param style The fontset to insert.
* @return true If success.
* @return false If failure.
*/
bool insert_fontset(std::string const& name, FontSet const& fontset);
/*! \brief Find a fontset.
* @param name The name of the fontset.
* @return The fontset if found. If not found return the default map fontset.
*/
FontSet const& find_fontset(std::string const& name) const;
/*! \brief Get number of all layers.
*/
size_t layerCount() const;
@ -243,6 +282,10 @@ namespace mapnik
featureset_ptr query_map_point(unsigned index, double x, double y) const;
~Map();
void setAspectFixMode(aspect_fix_mode afm) { aspectFixMode_ = afm; }
bool getAspectFixMode() { return aspectFixMode_; }
private:
void fixAspectRatio();
};

View file

@ -24,6 +24,7 @@
#ifndef _OCTREE_HPP_
#define _OCTREE_HPP_
#include <mapnik/global.hpp>
#include <boost/format.hpp>
#include <boost/utility.hpp>
#include <vector>

View file

@ -80,11 +80,12 @@ namespace mapnik {
PNG_COLOR_TYPE_RGB_ALPHA,PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
png_write_info(png_ptr, info_ptr);
for (unsigned i=0;i<image.height();i++)
{
png_write_row(png_ptr,(png_bytep)image.getRow(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);
}

View file

@ -27,7 +27,8 @@
// mapnik
#include <mapnik/enumeration.hpp>
#include <mapnik/color.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/font_set.hpp>
#include <mapnik/graphics.hpp>
// boost
#include <boost/tuple/tuple.hpp>
#include <boost/shared_ptr.hpp>
@ -49,6 +50,7 @@ namespace mapnik
{
text_symbolizer(std::string const& name,std::string const& face_name,
unsigned size, Color const& fill);
text_symbolizer(std::string const& name, unsigned size, Color const& fill);
text_symbolizer(text_symbolizer const& rhs);
text_symbolizer& operator=(text_symbolizer const& rhs);
std::string const& get_name() const;
@ -66,6 +68,9 @@ namespace mapnik
void set_max_char_angle_delta(double angle);
unsigned get_text_size() const;
std::string const& get_face_name() const;
void set_face_name(std::string face_name);
FontSet const& get_fontset() const;
void set_fontset(FontSet fontset);
Color const& get_fill() const;
void set_halo_fill(Color const& fill);
Color const& get_halo_fill() const;
@ -86,6 +91,7 @@ namespace mapnik
private:
std::string name_;
std::string face_name_;
FontSet fontset_;
unsigned size_;
unsigned text_ratio_;
unsigned wrap_width_;

View file

@ -27,10 +27,12 @@
#include <unicode/unistr.h>
#include <unicode/ucnv.h>
#include <mapnik/config.hpp>
#include <boost/utility.hpp>
#include <string>
namespace mapnik {
class transcoder : private boost::noncopyable
class MAPNIK_DECL transcoder : private boost::noncopyable
{
public:
explicit transcoder (std::string const& encoding);

View file

@ -34,8 +34,9 @@ gdal_src = Split(
libraries = ['gdal' ]
if env['PLATFORM'] == 'Darwin':
libraries.append('mapnik')
libraries.append('icuuc')
libraries.append('icudata')
#libraries.append('icuuc')
#libraries.append('icudata')
libraries.append(env['LIBS'])
gdal_inputdriver = env.SharedLibrary('gdal', source=gdal_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries)

View file

@ -35,10 +35,11 @@ libraries = ['pq']
if env['PLATFORM'] == 'Darwin':
libraries.append('mapnik')
libraries.append('icuuc')
libraries.append('icudata')
if env['THREADING'] == 'multi':
libraries.append('boost_thread%s-mt' % env['BOOST_APPEND'])
#libraries.append('icuuc')
#libraries.append('icudata')
libraries.append(env['LIBS'])
#if env['THREADING'] == 'multi':
# libraries.append('boost_thread%s-mt' % env['BOOST_APPEND'])
postgis_inputdriver = env.SharedLibrary('postgis', source=postgis_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries)

View file

@ -35,8 +35,9 @@ raster_src = Split(
libraries = []
if env['PLATFORM'] == 'Darwin':
libraries.append('mapnik')
libraries.append('icuuc')
libraries.append('icudata')
#libraries.append('icuuc')
#libraries.append('icudata')
libraries.append(env['LIBS'])
raster_inputdriver = env.SharedLibrary('raster', source=raster_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries)

View file

@ -39,15 +39,16 @@ thread_suffix = '-mt'
if env['PLATFORM'] == 'FreeBSD':
thread_suffix = ''
if env['THREADING'] == 'multi':
libraries = ['boost_iostreams%s%s' % (env['BOOST_APPEND'],thread_suffix) ]
else:
libraries = ['boost_iostreams%s' % (env['BOOST_APPEND']) ]
#if env['THREADING'] == 'multi':
# libraries = ['boost_iostreams%s%s' % (env['BOOST_APPEND'],thread_suffix) ]
#else:
# libraries = ['boost_iostreams%s' % (env['BOOST_APPEND']) ]
libraries = []
if env['PLATFORM'] == 'Darwin':
libraries.append('mapnik')
libraries.append('icuuc')
libraries.append('icudata')
libraries.append(env['LIBS'])
shape_inputdriver = env.SharedLibrary('shape', SHLIBSUFFIX='.input', source=shape_src, SHLIBPREFIX='', LIBS = libraries)

View file

@ -36,7 +36,6 @@
using mapnik::transcoder;
using mapnik::Feature;
class mapnik::transcoder;
struct field_descriptor
{

View file

@ -47,6 +47,7 @@ source = Split(
envelope.cpp
filter_factory.cpp
font_engine_freetype.cpp
font_set.cpp
graphics.cpp
image_reader.cpp
image_util.cpp

View file

@ -29,9 +29,12 @@
#include <mapnik/markers_converter.hpp>
#include <mapnik/arrow.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/font_set.hpp>
// agg
#define AGG_RENDERING_BUFFER row_ptr_cache<int8u>
#define AGG_RENDERING_BUFFER row_accessor<int8u>
//row_ptr_cache<int8u>
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
#include "agg_rasterizer_scanline_aa.h"
@ -169,7 +172,7 @@ namespace mapnik
Feature const& feature,
proj_transform const& prj_trans)
{
typedef coord_transform2<CoordTransform,geometry2d> path_type;
typedef coord_transform4<CoordTransform,geometry2d> path_type;
typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
@ -280,7 +283,6 @@ namespace mapnik
frame->move_to(itr->get<0>(),itr->get<1>());
frame->line_to(itr->get<0>(),itr->get<1>()+height);
}
geom.rewind(0);
@ -310,7 +312,6 @@ namespace mapnik
ras_ptr->add_path(roof_path);
ren.color(agg::rgba8(r, g, b, int(255 * sym.get_opacity())));
agg::render_scanlines(*ras_ptr, sl, ren);
}
}
}
@ -321,7 +322,7 @@ namespace mapnik
proj_transform const& prj_trans)
{
typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
typedef coord_transform2<CoordTransform,geometry2d> path_type;
typedef coord_transform4<CoordTransform,geometry2d> path_type;
typedef agg::renderer_outline_aa<ren_base> renderer_oaa;
typedef agg::rasterizer_outline_aa<renderer_oaa> rasterizer_outline_aa;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
@ -460,15 +461,20 @@ namespace mapnik
boost::shared_ptr<ImageData32> const& data = sym.get_image();
if (text.length() > 0 && data)
{
face_ptr face = font_manager_.get_face(sym.get_face_name());
if (face)
std::vector<face_ptr> faces;
faces.push_back(font_manager_.get_face(sym.get_face_name()));
if (faces.size() > 0)
{
text_renderer<mapnik::Image32> ren(pixmap_,face);
text_renderer<mapnik::Image32> ren(pixmap_, faces);
ren.set_pixel_size(sym.get_text_size());
ren.set_fill(sym.get_fill());
string_info info(text);
face->get_string_info(info);
ren.get_string_info(info);
placement_finder<label_collision_detector4> finder(detector_);
@ -669,11 +675,31 @@ namespace mapnik
UnicodeString text = feature[sym.get_name()].to_unicode();
if ( text.length() > 0 )
{
Color const& fill = sym.get_fill();
face_ptr face = font_manager_.get_face(sym.get_face_name());
if (face)
Color const& fill = sym.get_fill();
std::vector<face_ptr> faces;
FontSet fontset = sym.get_fontset();
std::vector<std::string> face_names = fontset.get_face_names();
if (face_names.size() > 0)
{
text_renderer<mapnik::Image32> ren(pixmap_,face);
std::vector<std::string>::iterator itr = face_names.begin();
std::vector<std::string>::iterator end = face_names.end();
for (; itr != end; ++itr)
{
faces.push_back(font_manager_.get_face(*itr));
}
}
else
{
faces.push_back(font_manager_.get_face(sym.get_face_name()));
}
if (faces.size() > 0)
{
text_renderer<mapnik::Image32> ren(pixmap_, faces);
ren.set_pixel_size(sym.get_text_size());
ren.set_fill(fill);
ren.set_halo_fill(sym.get_halo_fill());
@ -682,7 +708,8 @@ namespace mapnik
placement_finder<label_collision_detector4> finder(detector_);
string_info info(text);
face->get_string_info(info);
ren.get_string_info(info);
unsigned num_geom = feature.num_geometries();
for (unsigned i=0;i<num_geom;++i)
{

View file

@ -2,7 +2,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2008 Tom Hughes
* Copyright (C) 2008 Tom Hughes, Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View file

@ -29,6 +29,7 @@
#include <mapnik/layer.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/font_engine_freetype.hpp>
#include <mapnik/font_set.hpp>
#include <mapnik/ptree_helpers.hpp>
#include <mapnik/libxml2_loader.hpp>
@ -66,7 +67,10 @@ namespace mapnik
private:
void parse_style( Map & map, ptree const & sty);
void parse_layer( Map & map, ptree const & lay);
void parse_fontset(Map & map, ptree const & fset);
void parse_font(FontSet & fset, ptree const & f);
void parse_rule( feature_type_style & style, ptree const & r);
void parse_point_symbolizer( rule_type & rule, ptree const & sym);
@ -79,13 +83,14 @@ namespace mapnik
void parse_building_symbolizer( rule_type & rule, ptree const & sym );
void parse_markers_symbolizer( rule_type & rule, ptree const & sym );
void ensure_font_face( const text_symbolizer & text_symbol );
void ensure_font_face( const std::string & face_name );
bool strict_;
std::map<std::string,parameters> datasource_templates_;
freetype_engine font_engine_;
face_manager<freetype_engine> font_manager_;
std::map<std::string,std::string> file_sources_;
std::map<std::string,FontSet> fontsets_;
};
void load_map(Map & map, std::string const& filename, bool strict)
@ -142,9 +147,12 @@ namespace mapnik
}
else if (v.first == "Layer")
{
parse_layer(map, v.second );
}
else if (v.first == "FontSet")
{
parse_fontset(map, v.second);
}
else if (v.first == "FileSource")
{
std::string name = get_attr<string>( v.second, "name");
@ -227,6 +235,71 @@ namespace mapnik
}
}
void map_parser::parse_fontset( Map & map, ptree const & fset )
{
string name("<missing name>");
try
{
name = get_attr<string>(fset, "name");
FontSet fontset(name);
ptree::const_iterator itr = fset.begin();
ptree::const_iterator end = fset.end();
for (; itr != end; ++itr)
{
ptree::value_type const& font_tag = *itr;
if (font_tag.first == "Font")
{
parse_font(fontset, font_tag.second);
}
else if (font_tag.first != "<xmlcomment>" &&
font_tag.first != "<xmlattr>" )
{
throw config_error(std::string("Unknown child node in 'FontSet'.") +
"Expected 'Font' but got '" + font_tag.first + "'");
}
}
map.insert_fontset(name, fontset);
// XXX Hack because map object isn't accessible by text_symbolizer
// when it's parsed
fontsets_.insert(pair<std::string, FontSet>(name, fontset));
} catch (const config_error & ex) {
if ( ! name.empty() ) {
ex.append_context(string("in FontSet '") + name + "'");
}
throw;
}
}
void map_parser::parse_font(FontSet & fset, ptree const & f)
{
std::string face_name;
try
{
face_name = get_attr(f, "face_name", string());
if ( strict_ )
{
ensure_font_face( face_name );
}
}
catch (const config_error & ex)
{
if (!face_name.empty())
{
ex.append_context(string("in Font '") + face_name + "'");
}
throw;
}
fset.add_face_name(face_name);
}
void map_parser::parse_layer( Map & map, ptree const & lay )
{
std::string name;
@ -603,12 +676,39 @@ namespace mapnik
try
{
std::string name = get_attr<string>(sym, "name");
std::string face_name = get_attr<string>(sym, "face_name");
unsigned size = get_attr(sym, "size", 10U );
optional<std::string> face_name =
get_opt_attr<std::string>(sym, "face_name");
optional<std::string> fontset_name =
get_opt_attr<std::string>(sym, "fontset_name");
unsigned size = get_attr(sym, "size", 10U);
Color c = get_attr(sym, "fill", Color(0,0,0));
text_symbolizer text_symbol(name, face_name, size, c);
text_symbolizer text_symbol = text_symbolizer(name, size, c);
if (fontset_name && face_name)
{
throw config_error(std::string("Can't have both face_name and fontset_name"));
}
else if (fontset_name)
{
std::map<std::string,FontSet>::const_iterator itr = fontsets_.find(*fontset_name);
if (itr != fontsets_.end())
{
text_symbol.set_fontset(itr->second);
}
}
else if (face_name)
{
text_symbol.set_face_name(*face_name);
}
else
{
throw config_error(std::string("Must have face_name or fontset_name"));
}
int dx = get_attr(sym, "dx", 0);
int dy = get_attr(sym, "dy", 0);
@ -683,7 +783,7 @@ namespace mapnik
if ( strict_ )
{
ensure_font_face( text_symbol );
ensure_font_face( text_symbol.get_face_name() );
}
rule.append(text_symbol);
@ -913,12 +1013,12 @@ namespace mapnik
}
}
void map_parser::ensure_font_face( const text_symbolizer & text_symbol )
void map_parser::ensure_font_face( const std::string & face_name )
{
if ( ! font_manager_.get_face( text_symbol.get_face_name() ) )
if ( ! font_manager_.get_face( face_name ) )
{
throw config_error("Failed to find font face '" +
text_symbol.get_face_name() + "'");
face_name + "'");
}
}
} // end of namespace mapnik

View file

@ -34,12 +34,14 @@ namespace mapnik
Map::Map()
: width_(400),
height_(400),
srs_("+proj=latlong +datum=WGS84") {}
srs_("+proj=latlong +datum=WGS84"),
aspectFixMode_(GROW_BBOX) {}
Map::Map(int width,int height, std::string const& srs)
: width_(width),
height_(height),
srs_(srs) {}
srs_(srs),
aspectFixMode_(GROW_BBOX) {}
Map::Map(const Map& rhs)
: width_(rhs.width_),
@ -48,6 +50,7 @@ namespace mapnik
background_(rhs.background_),
styles_(rhs.styles_),
layers_(rhs.layers_),
aspectFixMode_(rhs.aspectFixMode_),
currentExtent_(rhs.currentExtent_) {}
Map& Map::operator=(const Map& rhs)
@ -59,6 +62,7 @@ namespace mapnik
background_=rhs.background_;
styles_=rhs.styles_;
layers_=rhs.layers_;
aspectFixMode_=rhs.aspectFixMode_;
return *this;
}
@ -101,7 +105,21 @@ namespace mapnik
{
styles_.erase(name);
}
bool Map::insert_fontset(std::string const& name, FontSet const& fontset)
{
return fontsets_.insert(make_pair(name, fontset)).second;
}
FontSet const& Map::find_fontset(std::string const& name) const
{
std::map<std::string,FontSet>::const_iterator itr = fontsets_.find(name);
if (itr!=fontsets_.end())
return itr->second;
static FontSet default_fontset;
return default_fontset;
}
feature_type_style const& Map::find_style(std::string const& name) const
{
std::map<std::string,feature_type_style>::const_iterator itr = styles_.find(name);
@ -281,15 +299,47 @@ namespace mapnik
{
double ratio1 = (double) width_ / (double) height_;
double ratio2 = currentExtent_.width() / currentExtent_.height();
if (ratio2 > ratio1)
if (ratio1 == ratio2) return;
switch(aspectFixMode_)
{
currentExtent_.height(currentExtent_.width() / ratio1);
case ADJUST_BBOX_HEIGHT:
currentExtent_.height(currentExtent_.width() / ratio1);
break;
case ADJUST_BBOX_WIDTH:
currentExtent_.width(currentExtent_.height() * ratio1);
break;
case ADJUST_CANVAS_HEIGHT:
height_ = int (width_ / ratio2 + 0.5);
break;
case ADJUST_CANVAS_WIDTH:
width_ = int (height_ * ratio2 + 0.5);
break;
case GROW_BBOX:
if (ratio2 > ratio1)
currentExtent_.height(currentExtent_.width() / ratio1);
else
currentExtent_.width(currentExtent_.height() * ratio1);
break;
case SHRINK_BBOX:
if (ratio2 < ratio1)
currentExtent_.height(currentExtent_.width() / ratio1);
else
currentExtent_.width(currentExtent_.height() * ratio1);
break;
case GROW_CANVAS:
if (ratio2 > ratio1)
width_ = (int) (height_ * ratio2 + 0.5);
else
height_ = int (width_ / ratio2 + 0.5);
break;
case SHRINK_CANVAS:
if (ratio2 > ratio1)
height_ = int (width_ / ratio2 + 0.5);
else
width_ = (int) (height_ * ratio2 + 0.5);
break;
}
else if (ratio2 < ratio1)
{
currentExtent_.width(currentExtent_.height() * ratio1);
}
}
const Envelope<double>& Map::getCurrentExtent() const

View file

@ -35,13 +35,35 @@ static const char * label_placement_strings[] = {
""
};
IMPLEMENT_ENUM( mapnik::label_placement_e, label_placement_strings );
namespace mapnik
{
text_symbolizer::text_symbolizer(std::string const& name, std::string const& face_name, unsigned size,Color const& fill)
text_symbolizer::text_symbolizer(std::string const& name, std::string const& face_name, unsigned size, Color const& fill)
: name_(name),
face_name_(face_name),
//fontset_(default_fontset),
size_(size),
text_ratio_(0),
wrap_width_(0),
label_spacing_(0),
label_position_tolerance_(0),
force_odd_labels_(false),
max_char_angle_delta_(0),
fill_(fill),
halo_fill_(Color(255,255,255)),
halo_radius_(0),
label_p_(POINT_PLACEMENT),
anchor_(0.0,0.5),
displacement_(0.0,0.0),
avoid_edges_(false),
minimum_distance_(0.0),
overlap_(false) {}
text_symbolizer::text_symbolizer(std::string const& name, unsigned size, Color const& fill)
: name_(name),
//face_name_(""),
//fontset_(default_fontset),
size_(size),
text_ratio_(0),
wrap_width_(0),
@ -61,6 +83,7 @@ namespace mapnik
text_symbolizer::text_symbolizer(text_symbolizer const& rhs)
: name_(rhs.name_),
face_name_(rhs.face_name_),
fontset_(rhs.fontset_),
size_(rhs.size_),
text_ratio_(rhs.text_ratio_),
wrap_width_(rhs.wrap_width_),
@ -84,6 +107,7 @@ namespace mapnik
return *this;
name_ = other.name_;
face_name_ = other.face_name_;
fontset_ = other.fontset_;
size_ = other.size_;
text_ratio_ = other.text_ratio_;
wrap_width_ = other.wrap_width_;
@ -113,10 +137,25 @@ namespace mapnik
{
return face_name_;
}
void text_symbolizer::set_face_name(std::string face_name)
{
face_name_ = face_name;
}
void text_symbolizer::set_fontset(FontSet fontset)
{
fontset_ = fontset;
}
FontSet const& text_symbolizer::get_fontset() const
{
return fontset_;
}
unsigned text_symbolizer::get_text_ratio() const
{
return text_ratio_;
return text_ratio_;
}
void text_symbolizer::set_text_ratio(unsigned ratio)
@ -126,7 +165,7 @@ namespace mapnik
unsigned text_symbolizer::get_wrap_width() const
{
return wrap_width_;
return wrap_width_;
}
void text_symbolizer::set_wrap_width(unsigned width)

View file

@ -196,7 +196,7 @@ namespace mapnik {
size_t inleft = input.size();
std::wstring output(inleft,0);
size_t outleft = inleft * sizeof(wchar_t);
#if (!defined(OSX_LEOPARD) && defined(DARWIN)) || defined(SUNOS) || defined(FREEBSD)
#if (!defined(OSX_LEOPARD) && defined(DARWIN)) || defined(SUNOS) || defined(FREEBSD) || defined(_WIN32)
const char * in = input.c_str();
#else
char * in = const_cast<char*>(input.data());

View file

@ -41,11 +41,14 @@ source = Split(
headers = ['#plugins/input/shape'] + env['CPPPATH']
boost_program_options = 'boost_program_options%s' % env['BOOST_APPEND']
boost_iostreams = 'boost_iostreams%s' % env['BOOST_APPEND']
if env['THREADING'] == 'multi':
boost_program_options = '%s%s' % (boost_program_options,thread_suffix)
boost_iostreams = '%s%s' % (boost_iostreams,thread_suffix)
#boost_program_options = 'boost_program_options%s' % env['BOOST_APPEND']
#boost_iostreams = 'boost_iostreams%s' % env['BOOST_APPEND']
boost_program_options = 'boost_program_options-mt-1_35'
boost_iostreams = 'boost_iostreams-mt-1_35'
#if env['THREADING'] == 'multi':
# boost_program_options = '%s%s' % (boost_program_options,thread_suffix)
# boost_iostreams = '%s%s' % (boost_iostreams,thread_suffix)
libraries = [boost_program_options,boost_iostreams]
shapeindex = env.Program('shapeindex', source, CPPPATH=headers, LIBS=libraries)