Merge branch 'master' of github.com:mapnik/mapnik

This commit is contained in:
kunitoki 2011-10-22 02:24:39 +02:00
commit 8877c681c4
94 changed files with 1432 additions and 428 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
*~
*.o *.o
*.pyc *.pyc
*.os *.os

View file

@ -110,6 +110,50 @@ Mapnik 2.0.0
- Implement MarkersSymbolizer in Cairo render and improve the markers placement finder. (#553) - Implement MarkersSymbolizer in Cairo render and improve the markers placement finder. (#553)
Mapnik 0.7.2 Release
--------------------
- Added forward compatibility for Mapnik 2.0 XML syntax (https://trac.mapnik.org/wiki/Mapnik2/Changes)
- Build fixes to ensure boost_threads are not used unless THREADING=multi build option is used
- Fixes for the clang compiler
- Support for latest libpng (>= 1.5.x) (r2999)
- Fixes to the postgres pool
- Fix for correct transparency levels in png256/png8 output (#540)
- Various build system fixes, especially for gcc compiler on open solaris.
- When plugins are not found, report the searched directories (#568)
- Improved font loading support (#559)
- Fix to shapeindex for allowing indexing of directory of shapefiles like `shapeindex dir/*shp`
- Fixed handling of null and multipatch shapes in shapefile driver - avoiding inf loop (#573)
- Fixed raster alpha blending (#589,#674)
- Enhanced support for faster reprojection if proj >= 4.8 is used (#575)
- Allow for late-binding of datasources (#622)
- Fix to OSM plugin to avoid over-caching of data (#542)
- Various fixes to sqlite, ogr, and occi driver backported from trunk.
- Ensured that '\n' triggers linebreaks in text rendering (#584)
- Support for boost filesystem v3
- Fixes to cairo renderer to avoid missing images (r2526)
- Fixed reading of label_position_tolerance on text_symbolizer and height for building_symbolizer
Mapnik 0.7.0 Release Mapnik 0.7.0 Release
-------------------- --------------------

View file

@ -102,9 +102,8 @@ PLUGINS = { # plugins with external dependencies
# plugins without external dependencies requiring CheckLibWithHeader... # plugins without external dependencies requiring CheckLibWithHeader...
'shape': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, 'shape': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
'csv': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'}, 'csv': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
'raster': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, 'raster': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
'csv': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'},
'kismet': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'}, 'kismet': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'},
} }
@ -526,19 +525,13 @@ if sys.platform == "win32":
color_print(4,'\nWelcome to Mapnik...\n') color_print(4,'\nWelcome to Mapnik...\n')
color_print(1,'*'*45)
color_print(1,'You are compiling Mapnik trunk (aka Mapnik2)')
color_print(1,'See important details at:\nhttp://trac.mapnik.org/wiki/Mapnik2')
color_print(1,('*'*45)+'\n')
#### Custom Configure Checks ### #### Custom Configure Checks ###
def prioritize_paths(context,silent=True): def prioritize_paths(context,silent=True):
env = context.env env = context.env
prefs = env['LINK_PRIORITY'].split(',') prefs = env['LINK_PRIORITY'].split(',')
if not silent: if not silent:
context.Message( 'Sorting lib and inc compiler paths by priority... %s' % ','.join(prefs) ) context.Message( 'Sorting lib and inc compiler paths...')
env['LIBPATH'] = sort_paths(env['LIBPATH'],prefs) env['LIBPATH'] = sort_paths(env['LIBPATH'],prefs)
env['CPPPATH'] = sort_paths(env['CPPPATH'],prefs) env['CPPPATH'] = sort_paths(env['CPPPATH'],prefs)
if silent: if silent:
@ -839,10 +832,10 @@ int main()
major, minor = map(int,result.split('.')) major, minor = map(int,result.split('.'))
if major >= 4 and minor >= 0: if major >= 4 and minor >= 0:
color_print(4,'\nFound icu version... %s\n' % result) color_print(4,'found: icu %s' % result)
return True return True
color_print(1,'\nFound insufficient icu version... %s\n' % result) color_print(1,'\nFound insufficient icu version... %s' % result)
return False return False
def boost_regex_has_icu(context): def boost_regex_has_icu(context):
@ -937,7 +930,7 @@ if not preconfigured:
opts.files.append(conf) opts.files.append(conf)
color_print(4,"SCons CONFIG found: '%s', variables will be inherited..." % conf) color_print(4,"SCons CONFIG found: '%s', variables will be inherited..." % conf)
optfile = file(conf) optfile = file(conf)
print optfile.read().replace("\n", " ").replace("'","").replace(" = ","=") #print optfile.read().replace("\n", " ").replace("'","").replace(" = ","=")
optfile.close() optfile.close()
elif not conf == SCONS_LOCAL_CONFIG: elif not conf == SCONS_LOCAL_CONFIG:
@ -1305,21 +1298,29 @@ if not preconfigured:
env['HAS_CAIRO'] = False env['HAS_CAIRO'] = False
env['SKIPPED_DEPS'].append('cairomm-version') env['SKIPPED_DEPS'].append('cairomm-version')
else: else:
print 'Checking for cairo/cairomm lib and include paths... ',
cmd = 'pkg-config --libs --cflags cairomm-1.0' cmd = 'pkg-config --libs --cflags cairomm-1.0'
if env['RUNTIME_LINK'] == 'static': if env['RUNTIME_LINK'] == 'static':
cmd += ' --static' cmd += ' --static'
cairo_env = env.Clone() cairo_env = env.Clone()
cairo_env.ParseConfig(cmd) try:
for lib in cairo_env['LIBS']: cairo_env.ParseConfig(cmd)
if not lib in env['LIBS']: for lib in cairo_env['LIBS']:
env["CAIROMM_LINKFLAGS"].append(lib) if not lib in env['LIBS']:
for lpath in cairo_env['LIBPATH']: env["CAIROMM_LINKFLAGS"].append(lib)
if not lpath in env['LIBPATH']: for lpath in cairo_env['LIBPATH']:
env["CAIROMM_LIBPATHS"].append(lpath) if not lpath in env['LIBPATH']:
for inc in cairo_env['CPPPATH']: env["CAIROMM_LIBPATHS"].append(lpath)
if not inc in env['CPPPATH']: for inc in cairo_env['CPPPATH']:
env["CAIROMM_CPPPATHS"].append(inc) if not inc in env['CPPPATH']:
env['HAS_CAIRO'] = True env["CAIROMM_CPPPATHS"].append(inc)
env['HAS_CAIRO'] = True
print 'yes'
except OSError,e:
color_print(1,'no')
env['SKIPPED_DEPS'].append('cairo')
env['SKIPPED_DEPS'].append('cairomm')
color_print(1,'pkg-config reported: %s' % e)
else: else:
color_print(4,'Not building with cairo support, pass CAIRO=True to enable') color_print(4,'Not building with cairo support, pass CAIRO=True to enable')
@ -1433,7 +1434,7 @@ if not preconfigured:
if env['DEBUG']: if env['DEBUG']:
env.Append(CXXFLAGS = gcc_cxx_flags + '-O0 -fno-inline %s' % debug_flags) env.Append(CXXFLAGS = gcc_cxx_flags + '-O0 -fno-inline %s' % debug_flags)
else: else:
env.Append(CXXFLAGS = gcc_cxx_flags + '-O%s -finline-functions -Wno-inline %s' % (env['OPTIMIZATION'],ndebug_flags)) env.Append(CXXFLAGS = gcc_cxx_flags + '-O%s -finline-functions -Wno-inline -Wno-parentheses -Wno-char-subscripts %s' % (env['OPTIMIZATION'],ndebug_flags))
if 'python' in env['BINDINGS']: if 'python' in env['BINDINGS']:
if not os.access(env['PYTHON'], os.X_OK): if not os.access(env['PYTHON'], os.X_OK):
@ -1548,7 +1549,7 @@ if not preconfigured:
except: pass except: pass
if 'configure' in command_line_args: if 'configure' in command_line_args:
color_print(4,'\n*Configure complete*\nNow run "python scons/scons.py" to build or "python scons/scons.py install" to install') color_print(4,'\nConfigure completed: run `make` to build or `make install`')
if not HELP_REQUESTED: if not HELP_REQUESTED:
Exit(0) Exit(0)

View file

@ -410,6 +410,13 @@ def Raster(**keywords):
Optional keyword arguments: Optional keyword arguments:
base -- path prefix (default None) base -- path prefix (default None)
multi -- whether the image is in tiles on disk (default False)
Multi-tiled keyword arguments:
x_width -- virtual image number of tiles in X direction (required)
y_width -- virtual image number of tiles in Y direction (required)
tile_size -- if an image is in tiles, how large are the tiles (default 256)
tile_stride -- if an image is in tiles, what's the increment between rows/cols (default 1)
>>> from mapnik import Raster, Layer >>> from mapnik import Raster, Layer
>>> raster = Raster(base='/home/mapnik/data',file='elevation.tif',lox=-122.8,loy=48.5,hix=-122.7,hiy=48.6) >>> raster = Raster(base='/home/mapnik/data',file='elevation.tif',lox=-122.8,loy=48.5,hix=-122.7,hiy=48.6)

View file

@ -264,7 +264,6 @@ void export_envelope()
.def(self == self) // __eq__ .def(self == self) // __eq__
.def(self != self) // __neq__ .def(self != self) // __neq__
.def(self + self) // __add__ .def(self + self) // __add__
//.def(self - self) // __sub__
.def(self * float()) // __mult__ .def(self * float()) // __mult__
.def(float() * self) .def(float() * self)
.def(self / float()) // __div__ .def(self / float()) // __div__

View file

@ -49,7 +49,7 @@ geometry_type const& getitem_impl(path_type & p, int key)
void from_wkt_impl(path_type& p, std::string const& wkt) void from_wkt_impl(path_type& p, std::string const& wkt)
{ {
bool result = mapnik::from_wkt(wkt, p); bool result = mapnik::from_wkt(wkt , p);
if (!result) throw std::runtime_error("Failed to parse WKT"); if (!result) throw std::runtime_error("Failed to parse WKT");
} }
@ -78,7 +78,6 @@ void export_geometry()
.def("envelope",&geometry_type::envelope) .def("envelope",&geometry_type::envelope)
// .def("__str__",&geometry_type::to_string) // .def("__str__",&geometry_type::to_string)
.def("type",&geometry_type::type) .def("type",&geometry_type::type)
.def("area",&geometry_type::area)
// TODO add other geometry_type methods // TODO add other geometry_type methods
; ;

View file

@ -46,7 +46,7 @@ void export_grid()
"Grid", "Grid",
"This class represents a feature hitgrid.", "This class represents a feature hitgrid.",
init<int,int,std::string,unsigned>( init<int,int,std::string,unsigned>(
( arg("width"),arg("height"),arg("key")="__id__",arg("resolution")=1 ), ( boost::python::arg("width"), boost::python::arg("height"),boost::python::arg("key")="__id__", boost::python::arg("resolution")=1 ),
"Create a mapnik.Grid object\n" "Create a mapnik.Grid object\n"
)) ))
.def("painted",&painted) .def("painted",&painted)
@ -54,7 +54,7 @@ void export_grid()
.def("height",&mapnik::grid::height) .def("height",&mapnik::grid::height)
.def("view",&mapnik::grid::get_view) .def("view",&mapnik::grid::get_view)
.def("encode",encode, .def("encode",encode,
( arg("encoding")="utf",arg("features")=true,arg("resolution")=4 ), ( boost::python::arg("encoding")="utf", boost::python::arg("features")=true,boost::python::arg("resolution")=4 ),
"Encode the grid as as optimized json\n" "Encode the grid as as optimized json\n"
) )
.add_property("key", .add_property("key",

View file

@ -45,8 +45,8 @@ void export_grid_view()
.def("width",&mapnik::grid_view::width) .def("width",&mapnik::grid_view::width)
.def("height",&mapnik::grid_view::height) .def("height",&mapnik::grid_view::height)
.def("encode",encode, .def("encode",encode,
( arg("encoding")="utf",arg("add_features")=true,arg("resolution")=4 ), ( boost::python::arg("encoding")="utf",boost::python::arg("add_features")=true,boost::python::arg("resolution")=4 ),
"Encode the grid as as optimized json\n" "Encode the grid as as optimized json\n"
) )
; ;
} }

View file

@ -35,7 +35,7 @@ using mapnik::metawriter_inmem_ptr;
namespace { namespace {
std::map<std::string, mapnik::value>::const_iterator std::map<std::string, mapnik::value>::const_iterator
mapnik_value_map_begin(const std::map<std::string, mapnik::value> &m) { mapnik_value_map_begin(const std::map<std::string, mapnik::value> &m) {
return m.begin(); return m.begin();
} }
std::map<std::string, mapnik::value>::const_iterator std::map<std::string, mapnik::value>::const_iterator

View file

@ -0,0 +1,123 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 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
*
*****************************************************************************/
#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/make_shared.hpp>
#include <mapnik/label_collision_detector.hpp>
#include <mapnik/map.hpp>
#include <list>
using mapnik::label_collision_detector4;
using mapnik::box2d;
using mapnik::Map;
using boost::make_shared;
namespace
{
boost::shared_ptr<label_collision_detector4>
create_label_collision_detector_from_extent(box2d<double> const &extent)
{
return make_shared<label_collision_detector4>(extent);
}
boost::shared_ptr<label_collision_detector4>
create_label_collision_detector_from_map(Map const &m)
{
double buffer = m.buffer_size();
box2d<double> extent(-buffer, -buffer, m.width() + buffer, m.height() + buffer);
return make_shared<label_collision_detector4>(extent);
}
boost::python::list
make_label_boxes(boost::shared_ptr<label_collision_detector4> det)
{
boost::python::list boxes;
for (label_collision_detector4::query_iterator jtr = det->begin();
jtr != det->end(); ++jtr)
{
boxes.append<box2d<double> >(jtr->box);
}
return boxes;
}
}
void export_label_collision_detector()
{
using namespace boost::python;
// for overload resolution
void (label_collision_detector4::*insert_box)(box2d<double> const &) = &label_collision_detector4::insert;
class_<label_collision_detector4, boost::shared_ptr<label_collision_detector4>, boost::noncopyable>
("LabelCollisionDetector",
"Object to detect collisions between labels, used in the rendering process.",
no_init)
.def("__init__", make_constructor(create_label_collision_detector_from_extent),
"Creates an empty collision detection object with a given extent. Note "
"that the constructor from Map objects is a sensible default and usually "
"what you want to do.\n"
"\n"
"Example:\n"
">>> m = Map(size_x, size_y)\n"
">>> buf_sz = m.buffer_size\n"
">>> extent = mapnik.Box2d(-buf_sz, -buf_sz, m.width + buf_sz, m.height + buf_sz)\n"
">>> detector = mapnik.LabelCollisionDetector(extent)")
.def("__init__", make_constructor(create_label_collision_detector_from_map),
"Creates an empty collision detection object matching the given Map object. "
"The created detector will have the same size, including the buffer, as the "
"map object. This is usually what you want to do.\n"
"\n"
"Example:\n"
">>> m = Map(size_x, size_y)\n"
">>> detector = mapnik.LabelCollisionDetector(m)")
.def("extent", &label_collision_detector4::extent, return_value_policy<copy_const_reference>(),
"Returns the total extent (bounding box) of all labels inside the detector.\n"
"\n"
"Example:\n"
">>> detector.extent()\n"
"Box2d(573.252589209,494.789179821,584.261023823,496.83610261)")
.def("boxes", &make_label_boxes,
"Returns a list of all the label boxes inside the detector.")
.def("insert", insert_box,
"Insert a 2d box into the collision detector. This can be used to ensure that "
"some space is left clear on the map for later overdrawing, for example by "
"non-Mapnik processes.\n"
"\n"
"Example:\n"
">>> m = Map(size_x, size_y)\n"
">>> detector = mapnik.LabelCollisionDetector(m)"
">>> detector.insert(mapnik.Box2d(196, 254, 291, 389))")
;
}

View file

@ -66,6 +66,7 @@ void export_view_transform();
void export_raster_colorizer(); void export_raster_colorizer();
void export_glyph_symbolizer(); void export_glyph_symbolizer();
void export_inmem_metawriter(); void export_inmem_metawriter();
void export_label_collision_detector();
#include <mapnik/version.hpp> #include <mapnik/version.hpp>
#include <mapnik/value_error.hpp> #include <mapnik/value_error.hpp>
@ -120,6 +121,28 @@ void render(const mapnik::Map& map,
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
} }
void render_with_detector(
const mapnik::Map &map,
mapnik::image_32 &image,
boost::shared_ptr<mapnik::label_collision_detector4> detector,
double scale_factor = 1.0,
unsigned offset_x = 0u,
unsigned offset_y = 0u)
{
Py_BEGIN_ALLOW_THREADS
try
{
mapnik::agg_renderer<mapnik::image_32> ren(map,image,detector);
ren.apply();
}
catch (...)
{
Py_BLOCK_THREADS
throw;
}
Py_END_ALLOW_THREADS
}
void render_layer2(const mapnik::Map& map, void render_layer2(const mapnik::Map& map,
mapnik::image_32& image, mapnik::image_32& image,
unsigned layer_idx) unsigned layer_idx)
@ -374,6 +397,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS(load_map_string_overloads, load_map_string, 2, 4
BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_overloads, save_map, 2, 3) BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_overloads, save_map, 2, 3)
BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_to_string_overloads, save_map_to_string, 1, 2) BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_to_string_overloads, save_map_to_string, 1, 2)
BOOST_PYTHON_FUNCTION_OVERLOADS(render_overloads, render, 2, 5) BOOST_PYTHON_FUNCTION_OVERLOADS(render_overloads, render, 2, 5)
BOOST_PYTHON_FUNCTION_OVERLOADS(render_with_detector_overloads, render_with_detector, 3, 6)
BOOST_PYTHON_MODULE(_mapnik2) BOOST_PYTHON_MODULE(_mapnik2)
{ {
@ -427,6 +451,7 @@ BOOST_PYTHON_MODULE(_mapnik2)
export_raster_colorizer(); export_raster_colorizer();
export_glyph_symbolizer(); export_glyph_symbolizer();
export_inmem_metawriter(); export_inmem_metawriter();
export_label_collision_detector();
def("render_grid",&render_grid, def("render_grid",&render_grid,
( arg("map"), ( arg("map"),
@ -503,6 +528,19 @@ BOOST_PYTHON_MODULE(_mapnik2)
"\n" "\n"
)); ));
def("render_with_detector", &render_with_detector, render_with_detector_overloads(
"\n"
"Render Map to an AGG image_32 using a pre-constructed detector.\n"
"\n"
"Usage:\n"
">>> from mapnik import Map, Image, LabelCollisionDetector, render_with_detector, load_map\n"
">>> m = Map(256,256)\n"
">>> load_map(m,'mapfile.xml')\n"
">>> im = Image(m.width,m.height)\n"
">>> detector = LabelCollisionDetector(m)\n"
">>> render_with_detector(m, im, detector)\n"
));
def("render_layer", &render_layer2, def("render_layer", &render_layer2,
(arg("map"),arg("image"),args("layer")) (arg("map"),arg("image"),args("layer"))
); );

View file

@ -148,8 +148,8 @@ struct rule_pickle_suite : boost::python::pickle_suite
extract_symbolizer serializer( r ); extract_symbolizer serializer( r );
for (int i=0;i<len(syms);++i) for (int i=0;i<len(syms);++i)
{ {
symbolizer symbol = extract<symbolizer>(syms[i]); //symbolizer symbol = extract<symbolizer>(syms[i]);
boost::apply_visitor( serializer, symbol ); //boost::apply_visitor( serializer, symbol );
} }
} }

View file

@ -43,7 +43,7 @@ template <class T>
void set_svg_transform(T& symbolizer, std::string const& transform_wkt) void set_svg_transform(T& symbolizer, std::string const& transform_wkt)
{ {
agg::trans_affine tr; agg::trans_affine tr;
if (!mapnik::svg::parse_transform(transform_wkt, tr)) if (!mapnik::svg::parse_transform(transform_wkt.c_str(), tr))
{ {
std::stringstream ss; std::stringstream ss;
ss << "Could not parse transform from '" << transform_wkt << "', expected string like: 'matrix(1, 0, 0, 1, 0, 0)'"; ss << "Could not parse transform from '" << transform_wkt << "', expected string like: 'matrix(1, 0, 0, 1, 0, 0)'";

View file

@ -50,12 +50,12 @@ static void grid2utf(T const& grid_type,
typename T::key_type::const_iterator key_pos; typename T::key_type::const_iterator key_pos;
typename T::feature_key_type::const_iterator feature_pos; typename T::feature_key_type::const_iterator feature_pos;
// start counting at utf8 codepoint 32, aka space character // start counting at utf8 codepoint 32, aka space character
uint16_t codepoint = 32; boost::uint16_t codepoint = 32;
unsigned array_size = data.width(); unsigned array_size = data.width();
for (unsigned y = 0; y < data.height(); ++y) for (unsigned y = 0; y < data.height(); ++y)
{ {
uint16_t idx = 0; boost::uint16_t idx = 0;
boost::scoped_array<Py_UNICODE> line(new Py_UNICODE[array_size]); boost::scoped_array<Py_UNICODE> line(new Py_UNICODE[array_size]);
typename T::value_type const* row = data.getRow(y); typename T::value_type const* row = data.getRow(y);
for (unsigned x = 0; x < data.width(); ++x) for (unsigned x = 0; x < data.width(); ++x)
@ -103,13 +103,13 @@ static void grid2utf(T const& grid_type,
typename T::key_type::const_iterator key_pos; typename T::key_type::const_iterator key_pos;
typename T::feature_key_type::const_iterator feature_pos; typename T::feature_key_type::const_iterator feature_pos;
// start counting at utf8 codepoint 32, aka space character // start counting at utf8 codepoint 32, aka space character
uint16_t codepoint = 32; boost::uint16_t codepoint = 32;
// TODO - use double? // TODO - use double?
unsigned array_size = static_cast<unsigned int>(grid_type.width()/resolution); unsigned array_size = static_cast<unsigned int>(grid_type.width()/resolution);
for (unsigned y = 0; y < grid_type.height(); y=y+resolution) for (unsigned y = 0; y < grid_type.height(); y=y+resolution)
{ {
uint16_t idx = 0; boost::uint16_t idx = 0;
boost::scoped_array<Py_UNICODE> line(new Py_UNICODE[array_size]); boost::scoped_array<Py_UNICODE> line(new Py_UNICODE[array_size]);
mapnik::grid::value_type const* row = grid_type.getRow(y); mapnik::grid::value_type const* row = grid_type.getRow(y);
for (unsigned x = 0; x < grid_type.width(); x=x+resolution) for (unsigned x = 0; x < grid_type.width(); x=x+resolution)

View file

@ -40,6 +40,7 @@
// boost // boost
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
// FIXME // FIXME
// forward declare so that // forward declare so that
@ -61,7 +62,11 @@ class MAPNIK_DECL agg_renderer : public feature_style_processor<agg_renderer<T>
{ {
public: public:
// create with default, empty placement detector
agg_renderer(Map const& m, T & pixmap, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0); agg_renderer(Map const& m, T & pixmap, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
// create with external placement detector, possibly non-empty
agg_renderer(Map const &m, T & pixmap, boost::shared_ptr<label_collision_detector4> detector,
double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
~agg_renderer(); ~agg_renderer();
void start_map_processing(Map const& map); void start_map_processing(Map const& map);
void end_map_processing(Map const& map); void end_map_processing(Map const& map);
@ -122,8 +127,10 @@ private:
CoordTransform t_; CoordTransform t_;
freetype_engine font_engine_; freetype_engine font_engine_;
face_manager<freetype_engine> font_manager_; face_manager<freetype_engine> font_manager_;
label_collision_detector4 detector_; boost::shared_ptr<label_collision_detector4> detector_;
boost::scoped_ptr<rasterizer> ras_ptr; boost::scoped_ptr<rasterizer> ras_ptr;
void setup(Map const &m);
}; };
} }

View file

@ -41,9 +41,8 @@ namespace mapnik {
template <typename T> class MAPNIK_DECL box2d template <typename T> class MAPNIK_DECL box2d
: boost::equality_comparable<box2d<T> , : boost::equality_comparable<box2d<T> ,
boost::addable<box2d<T>, boost::addable<box2d<T>,
boost::subtractable<box2d<T>, boost::dividable2<box2d<T>, T,
boost::dividable2<box2d<T>, T, boost::multipliable2<box2d<T>, T > > > >
boost::multipliable2<box2d<T>, T > > > > >
{ {
public: public:
typedef box2d<T> box2d_type; typedef box2d<T> box2d_type;
@ -86,7 +85,6 @@ public:
// define some operators // define some operators
box2d_type& operator+=(box2d_type const& other); box2d_type& operator+=(box2d_type const& other);
box2d_type& operator-=(box2d_type const& other);
box2d_type& operator*=(T); box2d_type& operator*=(T);
box2d_type& operator/=(T); box2d_type& operator/=(T);
T operator[](int index) const; T operator[](int index) const;

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2006 Artem Pavlenko * Copyright (C) 2006 Artem Pavlenko
@ -19,8 +19,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
//$Id: ctrans.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef CTRANS_HPP #ifndef CTRANS_HPP
#define CTRANS_HPP #define CTRANS_HPP
@ -32,78 +31,72 @@
#include <mapnik/coord_array.hpp> #include <mapnik/coord_array.hpp>
#include <mapnik/proj_transform.hpp> #include <mapnik/proj_transform.hpp>
namespace mapnik { namespace mapnik
{
typedef coord_array<coord2d> CoordinateArray; typedef coord_array<coord2d> CoordinateArray;
template <typename Transform,typename Geometry>
template <typename Transform, typename Geometry>
struct MAPNIK_DECL coord_transform struct MAPNIK_DECL coord_transform
{ {
coord_transform(Transform const& t, Geometry& geom) coord_transform(Transform const& t, Geometry& geom)
: t_(t), geom_(geom) {} : t_(t), geom_(geom) {}
unsigned vertex(double *x , double *y) const unsigned vertex(double *x, double *y) const
{ {
unsigned command = geom_.vertex(x,y); unsigned command = geom_.vertex(x, y);
t_.forward(x,y); t_.forward(x, y);
return command; return command;
} }
void rewind (unsigned pos) void rewind(unsigned pos)
{ {
geom_.rewind(pos); geom_.rewind(pos);
} }
private: private:
Transform const& t_; Transform const& t_;
Geometry& geom_; Geometry& geom_;
}; };
template <typename Transform,typename Geometry>
template <typename Transform, typename Geometry>
struct MAPNIK_DECL coord_transform2 struct MAPNIK_DECL coord_transform2
{ {
typedef std::size_t size_type; typedef std::size_t size_type;
typedef typename Geometry::value_type value_type; typedef typename Geometry::value_type value_type;
coord_transform2(Transform const& t, coord_transform2(Transform const& t,
Geometry const& geom, Geometry const& geom,
proj_transform const& prj_trans) proj_transform const& prj_trans)
: t_(t), : t_(t),
geom_(geom), geom_(geom),
prj_trans_(prj_trans) {} prj_trans_(prj_trans) {}
unsigned vertex(double * x , double * y) const unsigned vertex(double *x, double *y) const
{ {
unsigned command(SEG_MOVETO); unsigned command = SEG_MOVETO;
bool ok = false; bool ok = false;
bool skipped_points = false; bool skipped_points = false;
while (!ok) double z = 0;
while (!ok && command != SEG_END)
{ {
command = geom_.vertex(x,y); command = geom_.vertex(x, y);
double z=0; ok = prj_trans_.backward(*x, *y, z);
ok = prj_trans_.backward(*x,*y,z);
if (!ok) { if (!ok) {
skipped_points = true; skipped_points = true;
} }
ok = ok || (command == SEG_END);
} }
if (skipped_points && (command == SEG_LINETO)) if (skipped_points && (command == SEG_LINETO))
{ {
command = SEG_MOVETO; command = SEG_MOVETO;
} }
t_.forward(x,y); t_.forward(x, y);
return command; return command;
} }
/*unsigned vertex(double * x , double * y) const void rewind(unsigned pos)
{
unsigned command = geom_.vertex(x,y);
double z=0;
prj_trans_.backward(*x,*y,z);
t_.forward(x,y);
return command;
}*/
void rewind (unsigned pos)
{ {
geom_.rewind(pos); geom_.rewind(pos);
} }
@ -112,42 +105,42 @@ struct MAPNIK_DECL coord_transform2
{ {
return geom_; return geom_;
} }
private: private:
Transform const& t_; Transform const& t_;
Geometry const& geom_; Geometry const& geom_;
proj_transform const& prj_trans_; proj_transform const& prj_trans_;
}; };
template <typename Transform,typename Geometry> template <typename Transform, typename Geometry>
struct MAPNIK_DECL coord_transform3 struct MAPNIK_DECL coord_transform3
{ {
coord_transform3(Transform const& t, coord_transform3(Transform const& t,
Geometry const& geom, Geometry const& geom,
proj_transform const& prj_trans, proj_transform const& prj_trans,
int dx, int dy) int dx, int dy)
: t_(t), : t_(t),
geom_(geom), geom_(geom),
prj_trans_(prj_trans), prj_trans_(prj_trans),
dx_(dx), dy_(dy) {} dx_(dx), dy_(dy) {}
unsigned vertex(double * x , double * y) const unsigned vertex(double *x, double *y) const
{ {
unsigned command = geom_.vertex(x,y); unsigned command = geom_.vertex(x, y);
double z=0; double z = 0;
prj_trans_.backward(*x,*y,z); prj_trans_.backward(*x, *y, z);
t_.forward(x,y); t_.forward(x, y);
*x+=dx_; *x += dx_;
*y+=dy_; *y += dy_;
return command; return command;
} }
void rewind (unsigned pos) void rewind(unsigned pos)
{ {
geom_.rewind(pos); geom_.rewind(pos);
} }
private: private:
Transform const& t_; Transform const& t_;
Geometry const& geom_; Geometry const& geom_;
@ -155,7 +148,8 @@ private:
int dx_; int dx_;
int dy_; int dy_;
}; };
class CoordTransform class CoordTransform
{ {
private: private:
@ -166,71 +160,74 @@ private:
box2d<double> extent_; box2d<double> extent_;
double offset_x_; double offset_x_;
double offset_y_; double offset_y_;
public: public:
CoordTransform(int width,int height,const box2d<double>& extent, CoordTransform(int width, int height, const box2d<double>& extent,
double offset_x = 0, double offset_y = 0) double offset_x = 0, double offset_y = 0)
:width_(width),height_(height),extent_(extent),offset_x_(offset_x),offset_y_(offset_y) : width_(width), height_(height), extent_(extent),
offset_x_(offset_x), offset_y_(offset_y)
{ {
sx_ = (double(width_))/extent_.width(); sx_ = static_cast<double>(width_) / extent_.width();
sy_ = (double(height_))/extent_.height(); sy_ = static_cast<double>(height_) / extent_.height();
} }
inline int width() const inline int width() const
{ {
return width_; return width_;
} }
inline int height() const inline int height() const
{ {
return height_; return height_;
} }
inline double scale_x() const inline double scale_x() const
{ {
return sx_; return sx_;
} }
inline double scale_y() const inline double scale_y() const
{ {
return sy_; return sy_;
} }
inline void forward(double * x, double * y) const inline void forward(double *x, double *y) const
{ {
*x = (*x - extent_.minx()) * sx_ - offset_x_; *x = (*x - extent_.minx()) * sx_ - offset_x_;
*y = (extent_.maxy() - *y) * sy_ - offset_y_; *y = (extent_.maxy() - *y) * sy_ - offset_y_;
} }
inline void backward(double * x, double * y) const inline void backward(double *x, double *y) const
{ {
*x = extent_.minx() + (*x + offset_x_)/sx_; *x = extent_.minx() + (*x + offset_x_) / sx_;
*y = extent_.maxy() - (*y + offset_y_)/sy_; *y = extent_.maxy() - (*y + offset_y_) / sy_;
} }
inline coord2d& forward(coord2d& c) const inline coord2d& forward(coord2d& c) const
{ {
forward(&c.x,&c.y); forward(&c.x, &c.y);
return c;
}
inline coord2d& backward(coord2d& c) const
{
backward(&c.x,&c.y);
return c; return c;
} }
inline box2d<double> forward(const box2d<double>& e,proj_transform const& prj_trans) const inline coord2d& backward(coord2d& c) const
{
backward(&c.x, &c.y);
return c;
}
inline box2d<double> forward(const box2d<double>& e,
proj_transform const& prj_trans) const
{ {
double x0 = e.minx(); double x0 = e.minx();
double y0 = e.miny(); double y0 = e.miny();
double x1 = e.maxx(); double x1 = e.maxx();
double y1 = e.maxy(); double y1 = e.maxy();
double z = 0.0; double z = 0.0;
prj_trans.backward(x0,y0,z); prj_trans.backward(x0, y0, z);
forward(&x0,&y0); forward(&x0, &y0);
prj_trans.backward(x1,y1,z); prj_trans.backward(x1, y1, z);
forward(&x1,&y1); forward(&x1, &y1);
return box2d<double>(x0,y0,x1,y1); return box2d<double>(x0, y0, x1, y1);
} }
inline box2d<double> forward(const box2d<double>& e) const inline box2d<double> forward(const box2d<double>& e) const
@ -239,23 +236,24 @@ public:
double y0 = e.miny(); double y0 = e.miny();
double x1 = e.maxx(); double x1 = e.maxx();
double y1 = e.maxy(); double y1 = e.maxy();
forward(&x0,&y0); forward(&x0, &y0);
forward(&x1,&y1); forward(&x1, &y1);
return box2d<double>(x0,y0,x1,y1); return box2d<double>(x0, y0, x1, y1);
} }
inline box2d<double> backward(const box2d<double>& e,proj_transform const& prj_trans) const inline box2d<double> backward(const box2d<double>& e,
proj_transform const& prj_trans) const
{ {
double x0 = e.minx(); double x0 = e.minx();
double y0 = e.miny(); double y0 = e.miny();
double x1 = e.maxx(); double x1 = e.maxx();
double y1 = e.maxy(); double y1 = e.maxy();
double z = 0.0; double z = 0.0;
backward(&x0,&y0); backward(&x0, &y0);
prj_trans.forward(x0,y0,z); prj_trans.forward(x0, y0, z);
backward(&x1,&y1); backward(&x1, &y1);
prj_trans.forward(x1,y1,z); prj_trans.forward(x1, y1, z);
return box2d<double>(x0,y0,x1,y1); return box2d<double>(x0, y0, x1, y1);
} }
inline box2d<double> backward(const box2d<double>& e) const inline box2d<double> backward(const box2d<double>& e) const
@ -264,28 +262,29 @@ public:
double y0 = e.miny(); double y0 = e.miny();
double x1 = e.maxx(); double x1 = e.maxx();
double y1 = e.maxy(); double y1 = e.maxy();
backward(&x0,&y0); backward(&x0, &y0);
backward(&x1,&y1); backward(&x1, &y1);
return box2d<double>(x0,y0,x1,y1); return box2d<double>(x0, y0, x1, y1);
} }
inline CoordinateArray& forward(CoordinateArray& coords) const inline CoordinateArray& forward(CoordinateArray& coords) const
{ {
for (unsigned i=0;i<coords.size();++i) for (unsigned i = 0; i < coords.size(); ++i)
{ {
forward(coords[i]); forward(coords[i]);
} }
return coords; return coords;
} }
inline CoordinateArray& backward(CoordinateArray& coords) const inline CoordinateArray& backward(CoordinateArray& coords) const
{ {
for (unsigned i=0;i<coords.size();++i) for (unsigned i = 0; i < coords.size(); ++i)
{ {
backward(coords[i]); backward(coords[i]);
} }
return coords; return coords;
} }
inline box2d<double> const& extent() const inline box2d<double> const& extent() const
{ {
return extent_; return extent_;

View file

@ -50,6 +50,7 @@
namespace mapnik namespace mapnik
{ {
using namespace boost;
namespace qi = boost::spirit::qi; namespace qi = boost::spirit::qi;
namespace standard_wide = boost::spirit::standard_wide; namespace standard_wide = boost::spirit::standard_wide;
using standard_wide::space_type; using standard_wide::space_type;
@ -217,7 +218,7 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
| lit("false") [_val = false] | lit("false") [_val = false]
| lit("null") [_val = value_null() ] | lit("null") [_val = value_null() ]
| ustring [_val = unicode_(_1) ] | ustring [_val = unicode_(_1) ]
| attr [_val = construct<attribute>( _1 ) ] | attr [_val = construct<mapnik::attribute>( _1 ) ]
| '(' >> expr [_val = _1 ] >> ')' | '(' >> expr [_val = _1 ] >> ')'
; ;

View file

@ -43,7 +43,7 @@ enum filter_mode_enum {
DEFINE_ENUM( filter_mode_e, filter_mode_enum ); DEFINE_ENUM( filter_mode_e, filter_mode_enum );
typedef std::vector<rule> rules; typedef std::vector<rule> rules;
class feature_type_style class MAPNIK_DECL feature_type_style
{ {
private: private:
rules rules_; rules rules_;

View file

@ -200,7 +200,7 @@ public:
void init(double radius) void init(double radius)
{ {
FT_Stroker_Set(s_,radius * (1<<6), FT_Stroker_Set(s_, (FT_Fixed) radius * (1<<6),
FT_STROKER_LINECAP_ROUND, FT_STROKER_LINECAP_ROUND,
FT_STROKER_LINEJOIN_ROUND, FT_STROKER_LINEJOIN_ROUND,
0); 0);

View file

@ -68,27 +68,7 @@ public:
{ {
return type_; return type_;
} }
double area() const
{
double sum = 0.0;
double x(0);
double y(0);
rewind(0);
double xs = x;
double ys = y;
for (unsigned i=0;i<num_points();++i)
{
double x0(0);
double y0(0);
vertex(&x0,&y0);
sum += x * y0 - y * x0;
x = x0;
y = y0;
}
return (sum + x * ys - y * xs) * 0.5;
}
box2d<double> envelope() const box2d<double> envelope() const
{ {
box2d<double> result; box2d<double> result;

View file

@ -166,8 +166,21 @@ inline int rint( double val)
{ {
return int(floor(val + 0.5)); return int(floor(val + 0.5));
} }
inline double round (double val)
{
return floor(val);
}
#define _USE_MATH_DEFINES
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#endif #endif
} }
#endif //GLOBAL_HPP #endif //GLOBAL_HPP

View file

@ -24,6 +24,7 @@
#define MAPNIK_GRID_HPP #define MAPNIK_GRID_HPP
// mapnik // mapnik
#include <mapnik/config.hpp>
#include <mapnik/image_data.hpp> #include <mapnik/image_data.hpp>
#include <mapnik/box2d.hpp> #include <mapnik/box2d.hpp>
#include <mapnik/grid/grid_view.hpp> #include <mapnik/grid/grid_view.hpp>
@ -31,6 +32,9 @@
#include <mapnik/value.hpp> #include <mapnik/value.hpp>
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
// boost
#include <boost/cstdint.hpp>
// stl // stl
#include <map> #include <map>
#include <set> #include <set>
@ -95,17 +99,17 @@ public:
~hit_grid() {} ~hit_grid() {}
void painted(bool painted) inline void painted(bool painted)
{ {
painted_ = painted; painted_ = painted;
} }
bool painted() const inline bool painted() const
{ {
return painted_; return painted_;
} }
void add_feature(mapnik::Feature const& feature) inline void add_feature(mapnik::Feature const& feature)
{ {
// copies feature props // copies feature props
@ -152,12 +156,12 @@ public:
} }
} }
void add_property_name(std::string const& name) inline void add_property_name(std::string const& name)
{ {
names_.insert(name); names_.insert(name);
} }
std::set<std::string> property_names() const inline std::set<std::string> const& property_names() const
{ {
return names_; return names_;
} }
@ -275,7 +279,7 @@ public:
inline void blendPixel(value_type feature_id,int x,int y,unsigned int rgba1,int t) inline void blendPixel(value_type feature_id,int x,int y,unsigned int rgba1,int t)
{ {
blendPixel2(x,y,rgba1,t,1.0); // do not change opacity blendPixel2(feature_id ,x,y,rgba1,t,1.0); // do not change opacity
} }
inline void blendPixel2(value_type feature_id,int x,int y,unsigned int rgba1,int t,double opacity) inline void blendPixel2(value_type feature_id,int x,int y,unsigned int rgba1,int t,double opacity)
@ -331,7 +335,7 @@ public:
}; };
typedef hit_grid<uint16_t> grid; typedef MAPNIK_DECL hit_grid<boost::uint16_t> grid;
} }
#endif //MAPNIK_GRID_HPP #endif //MAPNIK_GRID_HPP

View file

@ -30,6 +30,8 @@
#include <mapnik/global.hpp> #include <mapnik/global.hpp>
#include <mapnik/value.hpp> #include <mapnik/value.hpp>
// boost
#include <boost/cstdint.hpp>
// stl // stl
#include <map> #include <map>
#include <set> #include <set>
@ -188,7 +190,7 @@ private:
feature_type const& features_; feature_type const& features_;
}; };
typedef hit_grid_view<mapnik::ImageData<uint16_t> > grid_view; typedef hit_grid_view<mapnik::ImageData<boost::uint16_t> > grid_view;
} }

View file

@ -434,7 +434,7 @@ private:
} }
tries=0; tries=0;
// ignore leaves and also nodes with small mean error and not excessive number of pixels // ignore leaves and also nodes with small mean error and not excessive number of pixels
if ((cur_node->reduce_cost / cur_node->pixel_count + 1) * std::log(long(cur_node->pixel_count)) > 15 if ((cur_node->reduce_cost / cur_node->pixel_count + 1) * std::log(double(cur_node->pixel_count)) > 15
&& cur_node->children_count > 0) && cur_node->children_count > 0)
{ {
colors_--; colors_--;

View file

@ -255,6 +255,8 @@ inline MAPNIK_DECL std::string save_to_string(image_32 const& image,
return save_to_string<image_data_32>(image.data(), type, palette); return save_to_string<image_data_32>(image.data(), type, palette);
} }
///////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER #ifdef _MSC_VER
template MAPNIK_DECL void save_to_file<image_data_32>(image_data_32 const&, template MAPNIK_DECL void save_to_file<image_data_32>(image_data_32 const&,
std::string const&, std::string const&,
@ -263,18 +265,31 @@ template MAPNIK_DECL void save_to_file<image_data_32>(image_data_32 const&,
template MAPNIK_DECL void save_to_file<image_data_32>(image_data_32 const&, template MAPNIK_DECL void save_to_file<image_data_32>(image_data_32 const&,
std::string const&, std::string const&,
rgba_palette const&); rgba_palette const&);
template MAPNIK_DECL std::string save_to_string<image_data_32>(image_data_32 const&,
std::string const&, template MAPNIK_DECL void save_to_file<image_data_32>(image_data_32 const&,
rgba_palette const&); std::string const&);
template MAPNIK_DECL void save_to_file<image_view<image_data_32> > (image_view<image_data_32> const&, template MAPNIK_DECL void save_to_file<image_view<image_data_32> > (image_view<image_data_32> const&,
std::string const&, std::string const&,
std::string const&, std::string const&,
rgba_palette const&); rgba_palette const&);
template MAPNIK_DECL void save_to_file<image_view<image_data_32> > (image_view<image_data_32> const&,
std::string const&,
std::string const&);
template MAPNIK_DECL void save_to_file<image_view<image_data_32> > (image_view<image_data_32> const&, template MAPNIK_DECL void save_to_file<image_view<image_data_32> > (image_view<image_data_32> const&,
std::string const&, std::string const&,
rgba_palette const&); rgba_palette const&);
template MAPNIK_DECL void save_to_file<image_view<image_data_32> > (image_view<image_data_32> const&,
std::string const&);
template MAPNIK_DECL std::string save_to_string<image_data_32>(image_data_32 const&,
std::string const&,
rgba_palette const&);
template MAPNIK_DECL std::string save_to_string<image_view<image_data_32> > (image_view<image_data_32> const&, template MAPNIK_DECL std::string save_to_string<image_view<image_data_32> > (image_view<image_data_32> const&,
std::string const&, std::string const&,

View file

@ -69,7 +69,7 @@ class label_collision_detector2 : boost::noncopyable
typedef quad_tree<box2d<double> > tree_t; typedef quad_tree<box2d<double> > tree_t;
tree_t tree_; tree_t tree_;
public: public:
explicit label_collision_detector2(box2d<double> const& extent) explicit label_collision_detector2(box2d<double> const& extent)
: tree_(extent) {} : tree_(extent) {}
@ -138,6 +138,7 @@ public:
//quad tree based label collission detector so labels dont appear within a given distance //quad tree based label collission detector so labels dont appear within a given distance
class label_collision_detector4 : boost::noncopyable class label_collision_detector4 : boost::noncopyable
{ {
public:
struct label struct label
{ {
label(box2d<double> const& b) : box(b) {} label(box2d<double> const& b) : box(b) {}
@ -146,11 +147,13 @@ class label_collision_detector4 : boost::noncopyable
box2d<double> box; box2d<double> box;
UnicodeString text; UnicodeString text;
}; };
private:
typedef quad_tree< label > tree_t; typedef quad_tree< label > tree_t;
tree_t tree_; tree_t tree_;
public: public:
typedef tree_t::query_iterator query_iterator;
explicit label_collision_detector4(box2d<double> const& extent) explicit label_collision_detector4(box2d<double> const& extent)
: tree_(extent) {} : tree_(extent) {}
@ -224,6 +227,9 @@ public:
{ {
return tree_.extent(); return tree_.extent();
} }
query_iterator begin() { return tree_.query_in_box(extent()); }
query_iterator end() { return tree_.query_end(); }
}; };
} }

View file

@ -25,6 +25,7 @@
#define METAWRITER_INMEM_HPP #define METAWRITER_INMEM_HPP
// mapnik // mapnik
#include <mapnik/config.hpp>
#include <mapnik/metawriter.hpp> #include <mapnik/metawriter.hpp>
// boost // boost
@ -50,7 +51,7 @@ namespace mapnik {
* very common in the rendered image will increase memory usage, especially if * very common in the rendered image will increase memory usage, especially if
* many attributes are also kept. * many attributes are also kept.
*/ */
class metawriter_inmem class MAPNIK_DECL metawriter_inmem
: public metawriter, private boost::noncopyable { : public metawriter, private boost::noncopyable {
public: public:
/** /**
@ -59,8 +60,8 @@ public:
* then the name attribute of rendered features referencing this metawriter * then the name attribute of rendered features referencing this metawriter
* will be kept in memory. * will be kept in memory.
*/ */
metawriter_inmem(metawriter_properties dflt_properties); metawriter_inmem(metawriter_properties dflt_properties);
~metawriter_inmem(); ~metawriter_inmem();
virtual void add_box(box2d<double> const& box, Feature const& feature, virtual void add_box(box2d<double> const& box, Feature const& feature,
CoordTransform const& t, CoordTransform const& t,
@ -87,7 +88,7 @@ public:
* are the intersection of the features' properties and the "kept" * are the intersection of the features' properties and the "kept"
* properties of the metawriter. * properties of the metawriter.
*/ */
struct meta_instance { struct MAPNIK_DECL meta_instance {
box2d<double> box; box2d<double> box;
std::map<std::string, value> properties; std::map<std::string, value> properties;
}; };

View file

@ -26,6 +26,7 @@
// mapnik // mapnik
#include <mapnik/config.hpp>
#include <mapnik/global.hpp> #include <mapnik/global.hpp>
#include <mapnik/config_error.hpp> #include <mapnik/config_error.hpp>
@ -124,7 +125,7 @@ struct rgba
typedef boost::unordered_map<unsigned, unsigned> rgba_hash_table; typedef boost::unordered_map<unsigned, unsigned> rgba_hash_table;
class rgba_palette : private boost::noncopyable { class MAPNIK_DECL rgba_palette : private boost::noncopyable {
public: public:
enum palette_type { PALETTE_RGBA = 0, PALETTE_RGB = 1, PALETTE_ACT = 2 }; enum palette_type { PALETTE_RGBA = 0, PALETTE_RGB = 1, PALETTE_ACT = 2 };

View file

@ -24,6 +24,7 @@
#define MAPNIK_PARSE_PATH_HPP #define MAPNIK_PARSE_PATH_HPP
// mapnik // mapnik
#include <mapnik/config.hpp>
#include <mapnik/attribute.hpp> #include <mapnik/attribute.hpp>
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
#include <mapnik/value.hpp> #include <mapnik/value.hpp>
@ -41,7 +42,7 @@ typedef boost::variant<std::string, attribute> path_component;
typedef std::vector<path_component> path_expression; typedef std::vector<path_component> path_expression;
typedef boost::shared_ptr<path_expression> path_expression_ptr; typedef boost::shared_ptr<path_expression> path_expression_ptr;
path_expression_ptr parse_path(std::string const & str); MAPNIK_DECL path_expression_ptr parse_path(std::string const & str);
template <typename T> template <typename T>
struct path_processor struct path_processor

View file

@ -51,7 +51,7 @@
namespace mapnik namespace mapnik
{ {
using namespace boost;
namespace qi = boost::spirit::qi; namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix; namespace phoenix = boost::phoenix;
namespace standard_wide = boost::spirit::standard_wide; namespace standard_wide = boost::spirit::standard_wide;
@ -79,7 +79,7 @@ struct path_expression_grammar : qi::grammar<Iterator, std::vector<path_componen
* ( * (
str [ push_back(_val, _1)] str [ push_back(_val, _1)]
| |
( '[' >> attr [ push_back(_val, construct<attribute>( _1 )) ] >> ']') ( '[' >> attr [ push_back(_val, construct<mapnik::attribute>( _1 )) ] >> ']')
) )
; ;

View file

@ -68,7 +68,7 @@ enum colorizer_mode_enum
DEFINE_ENUM( colorizer_mode, colorizer_mode_enum ); DEFINE_ENUM( colorizer_mode, colorizer_mode_enum );
//! \brief Structure to represent a stop position. //! \brief Structure to represent a stop position.
class colorizer_stop { class MAPNIK_DECL colorizer_stop {
public: public:
//! \brief Constructor //! \brief Constructor
@ -142,7 +142,7 @@ typedef std::vector<colorizer_stop> colorizer_stops;
//! \brief Class representing the raster colorizer //! \brief Class representing the raster colorizer
class raster_colorizer { class MAPNIK_DECL raster_colorizer {
public: public:
//! \brief Constructor //! \brief Constructor
raster_colorizer(colorizer_mode mode = COLORIZER_LINEAR, const color& _color = color(0,0,0,0)); raster_colorizer(colorizer_mode mode = COLORIZER_LINEAR, const color& _color = color(0,0,0,0));

View file

@ -23,11 +23,15 @@
#ifndef SVG_COMMANDS_HPP #ifndef SVG_COMMANDS_HPP
#define SVG_COMMANDS_HPP #define SVG_COMMANDS_HPP
// mapnik
#include <mapnik/global.hpp>
//
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_function.hpp> #include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_core.hpp> #include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp> #include <boost/spirit/include/phoenix_operator.hpp>
namespace mapnik { namespace svg { namespace mapnik { namespace svg {
using namespace boost::fusion; using namespace boost::fusion;

View file

@ -23,6 +23,7 @@
#ifndef SVG_PATH_PARSER_HPP #ifndef SVG_PATH_PARSER_HPP
#define SVG_PATH_PARSER_HPP #define SVG_PATH_PARSER_HPP
#include <mapnik/config.hpp>
#include <string> #include <string>
namespace mapnik { namespace svg { namespace mapnik { namespace svg {
@ -34,10 +35,10 @@ template <typename PathType>
bool parse_points(const char * wkt, PathType & p); bool parse_points(const char * wkt, PathType & p);
template <typename TransformType> template <typename TransformType>
bool parse_transform(const char * wkt, TransformType & tr); bool MAPNIK_DECL parse_transform(const char * wkt, TransformType & tr);
template <typename TransformType> //template <typename TransformType>
bool parse_transform(std::string const& wkt, TransformType & tr); //bool MAPNIK_DECL parse_transform(std::string const& wkt, TransformType & tr);
}} }}

View file

@ -25,7 +25,8 @@
#ifndef SVG_TRANSFORM_GRAMMAR_HPP #ifndef SVG_TRANSFORM_GRAMMAR_HPP
#define SVG_TRANSFORM_GRAMMAR_HPP #define SVG_TRANSFORM_GRAMMAR_HPP
// mapnik
#include <mapnik/global.hpp>
// agg // agg
#include <agg_trans_affine.h> #include <agg_trans_affine.h>
// spirit // spirit
@ -35,7 +36,6 @@
#include <boost/spirit/include/phoenix_operator.hpp> #include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/home/phoenix/object/construct.hpp> #include <boost/spirit/home/phoenix/object/construct.hpp>
namespace mapnik { namespace svg { namespace mapnik { namespace svg {
using namespace boost::spirit; using namespace boost::spirit;

View file

@ -23,6 +23,7 @@
#define TEXT_PLACEMENTS_HPP #define TEXT_PLACEMENTS_HPP
//mapnik //mapnik
#include <mapnik/config.hpp>
#include <mapnik/enumeration.hpp> #include <mapnik/enumeration.hpp>
//stl //stl
@ -154,14 +155,14 @@ typedef boost::shared_ptr<text_placements> text_placements_ptr;
class text_placements_info_dummy; class text_placements_info_dummy;
class text_placements_dummy: public text_placements class MAPNIK_DECL text_placements_dummy: public text_placements
{ {
public: public:
text_placement_info_ptr get_placement_info() const; text_placement_info_ptr get_placement_info() const;
friend class text_placement_info_dummy; friend class text_placement_info_dummy;
}; };
class text_placement_info_dummy : public text_placement_info class MAPNIK_DECL text_placement_info_dummy : public text_placement_info
{ {
public: public:
text_placement_info_dummy(text_placements_dummy const* parent) : text_placement_info(parent), text_placement_info_dummy(text_placements_dummy const* parent) : text_placement_info(parent),

View file

@ -47,12 +47,10 @@ struct MAPNIK_DECL text_symbolizer : public symbolizer_base
{ {
text_symbolizer(expression_ptr name, std::string const& face_name, text_symbolizer(expression_ptr name, std::string const& face_name,
unsigned size, color const& fill, unsigned size, color const& fill,
text_placements_ptr placements = text_placements_ptr( text_placements_ptr placements = boost::make_shared<text_placements_dummy>()
boost::make_shared<text_placements_dummy>())
); );
text_symbolizer(expression_ptr name, unsigned size, color const& fill, text_symbolizer(expression_ptr name, unsigned size, color const& fill,
text_placements_ptr placements = text_placements_ptr( text_placements_ptr placements = boost::make_shared<text_placements_dummy>()
boost::make_shared<text_placements_dummy>())
); );
text_symbolizer(text_symbolizer const& rhs); text_symbolizer(text_symbolizer const& rhs);
text_symbolizer& operator=(text_symbolizer const& rhs); text_symbolizer& operator=(text_symbolizer const& rhs);

View file

@ -25,9 +25,12 @@
#define VALUE_HPP #define VALUE_HPP
// mapnik // mapnik
#include <mapnik/global.hpp>
#include <mapnik/unicode.hpp> #include <mapnik/unicode.hpp>
#include <mapnik/config_error.hpp> #include <mapnik/config_error.hpp>
// boost // boost
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include <boost/scoped_array.hpp> #include <boost/scoped_array.hpp>
#include <boost/concept_check.hpp> #include <boost/concept_check.hpp>
@ -49,9 +52,9 @@ inline void to_utf8(UnicodeString const& input, std::string & target)
{ {
if (input.length() == 0) return; if (input.length() == 0) return;
const int32_t BUF_SIZE = 256; const int BUF_SIZE = 256;
char buf [BUF_SIZE]; char buf [BUF_SIZE];
int32_t len; int len;
UErrorCode err = U_ZERO_ERROR; UErrorCode err = U_ZERO_ERROR;
u_strToUTF8(buf, BUF_SIZE, &len, input.getBuffer(), input.length(), &err); u_strToUTF8(buf, BUF_SIZE, &len, input.getBuffer(), input.length(), &err);
@ -106,10 +109,9 @@ struct equals
bool operator() (value_null, value_null) const bool operator() (value_null, value_null) const
{ {
// this changed from false to true - see http://trac.mapnik.org/ticket/794 // this changed from false to true - https://github.com/mapnik/mapnik/issues/794
return true; return true;
} }
}; };
struct not_equals struct not_equals
@ -145,21 +147,21 @@ struct not_equals
bool operator() (value_null, value_null) const bool operator() (value_null, value_null) const
{ {
// TODO - needs review http://trac.mapnik.org/ticket/794 // TODO - needs review - https://github.com/mapnik/mapnik/issues/794
return false; return false;
} }
template <typename T> template <typename T>
bool operator() (value_null, const T &) const bool operator() (value_null, const T &) const
{ {
// TODO - needs review http://trac.mapnik.org/ticket/794 // TODO - needs review - https://github.com/mapnik/mapnik/issues/794
return false; return false;
} }
template <typename T> template <typename T>
bool operator() (const T &, value_null) const bool operator() (const T &, value_null) const
{ {
// TODO - needs review http://trac.mapnik.org/ticket/794 // TODO - needs review - https://github.com/mapnik/mapnik/issues/794
return false; return false;
} }
}; };
@ -533,7 +535,7 @@ struct to_bool : public boost::static_visitor<bool>
template <typename T> template <typename T>
bool operator() (T val) const bool operator() (T val) const
{ {
return bool(val); return val > 0 ? true : false;
} }
}; };

View file

@ -23,13 +23,16 @@
#ifndef MAPNIK_WKT_FACTORY_HPP #ifndef MAPNIK_WKT_FACTORY_HPP
#define MAPNIK_WKT_FACTORY_HPP #define MAPNIK_WKT_FACTORY_HPP
#include <string> // mapnik
#include <mapnik/config.hpp>
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_vector.hpp>
// stl
#include <string>
namespace mapnik { namespace mapnik {
bool from_wkt(std::string const& wkt, boost::ptr_vector<geometry_type> & paths); MAPNIK_DECL bool from_wkt(std::string const& wkt, boost::ptr_vector<geometry_type> & paths);
} }

View file

@ -115,7 +115,6 @@ void csv_datasource::bind() const
parse_csv(in,escape_, separator_, quote_); parse_csv(in,escape_, separator_, quote_);
in.close(); in.close();
} }
is_bound_ = true; is_bound_ = true;
} }
@ -125,10 +124,11 @@ void csv_datasource::parse_csv(T& stream,
std::string const& separator, std::string const& separator,
std::string const& quote) const std::string const& quote) const
{ {
stream.seekg (0, std::ios::end);
int file_length_ = stream.tellg();
if (filesize_max_ > 0) if (filesize_max_ > 0)
{ {
stream.seekg (0, std::ios::end);
int file_length_ = stream.tellg();
double file_mb = static_cast<double>(file_length_)/1048576; double file_mb = static_cast<double>(file_length_)/1048576;
// throw if this is an unreasonably large file to read into memory // throw if this is an unreasonably large file to read into memory
@ -140,35 +140,49 @@ void csv_datasource::parse_csv(T& stream,
<< " to render this data (set 'filesize_max=0' to disable this restriction if you have lots of memory)"; << " to render this data (set 'filesize_max=0' to disable this restriction if you have lots of memory)";
throw mapnik::datasource_exception(s.str()); throw mapnik::datasource_exception(s.str());
} }
// set back to start
stream.seekg (0, std::ios::beg);
} }
char newline; // set back to start
std::string csv_line; stream.seekg (0, std::ios::beg);
// autodetect newlines // autodetect newlines
bool found_break = false; char newline = '\n';
if (std::getline(stream,csv_line,'\n')) int newline_count = 0;
int carriage_count = 0;
for(std::size_t idx = 0; idx < file_length_; idx++)
{ {
found_break = true; char c = static_cast<char>(stream.get());
newline = '\n'; if (c == '\n')
{
++newline_count;
}
else if (c == '\r')
{
++carriage_count;
}
// read at least 2000 bytes before testing
if (idx == file_length_-1 || idx > 4000)
{
if (newline_count > carriage_count)
{
break;
}
else if (carriage_count > newline_count)
{
newline = '\r';
break;
}
}
} }
else if (std::getline(stream,csv_line,'\r'))
{
found_break = true;
newline = '\r';
}
else
{
throw mapnik::datasource_exception("CSV Plugin: could not detect any line breaks in this csv (http://en.wikipedia.org/wiki/Newline)\n");
}
// set back to start // set back to start
stream.seekg (0, std::ios::beg); stream.seekg (0, std::ios::beg);
// if user has not passed separator manuall // get first line
std::string csv_line;
std::getline(stream,csv_line,newline);
// if user has not passed a separator manually
// then attempt to detect by reading first line // then attempt to detect by reading first line
std::string sep = boost::trim_copy(separator); std::string sep = boost::trim_copy(separator);
if (sep.empty()) if (sep.empty())
@ -189,6 +203,9 @@ void csv_datasource::parse_csv(T& stream,
} }
} }
} }
// set back to start
stream.seekg (0, std::ios::beg);
typedef boost::escaped_list_separator<char> escape_type; typedef boost::escaped_list_separator<char> escape_type;
@ -239,12 +256,17 @@ void csv_datasource::parse_csv(T& stream,
wkt_idx = idx; wkt_idx = idx;
has_wkt_field = true; has_wkt_field = true;
} }
if (lower_val == "x" || (lower_val.find("longitude") != std::string::npos)) if (lower_val == "x"
|| lower_val == "lon"
|| lower_val == "long"
|| (lower_val.find("longitude") != std::string::npos))
{ {
lon_idx = idx; lon_idx = idx;
has_lon_field = true; has_lon_field = true;
} }
if (lower_val == "y" || (lower_val.find("latitude") != std::string::npos)) if (lower_val == "y"
|| lower_val == "lat"
|| (lower_val.find("latitude") != std::string::npos))
{ {
lat_idx = idx; lat_idx = idx;
has_lat_field = true; has_lat_field = true;
@ -293,12 +315,17 @@ void csv_datasource::parse_csv(T& stream,
wkt_idx = idx; wkt_idx = idx;
has_wkt_field = true; has_wkt_field = true;
} }
if (lower_val == "x" || (lower_val.find("longitude") != std::string::npos)) if (lower_val == "x"
|| lower_val == "lon"
|| lower_val == "long"
|| (lower_val.find("longitude") != std::string::npos))
{ {
lon_idx = idx; lon_idx = idx;
has_lon_field = true; has_lon_field = true;
} }
if (lower_val == "y" || (lower_val.find("latitude") != std::string::npos)) if (lower_val == "y"
|| lower_val == "lat"
|| (lower_val.find("latitude") != std::string::npos))
{ {
lat_idx = idx; lat_idx = idx;
has_lat_field = true; has_lat_field = true;
@ -322,7 +349,7 @@ void csv_datasource::parse_csv(T& stream,
if (!has_wkt_field && (!has_lon_field || !has_lat_field) ) if (!has_wkt_field && (!has_lon_field || !has_lat_field) )
{ {
std::ostringstream s; std::ostringstream s;
s << "CSV Plugin: could not detect column headers with the name of 'wkt' or lat/lon - this is required for reading geometry data"; s << "CSV Plugin: could not detect column headers with the name of wkt ,x/y, or latitude/longitude - this is required for reading geometry data";
throw mapnik::datasource_exception(s.str()); throw mapnik::datasource_exception(s.str());
} }
@ -373,7 +400,6 @@ void csv_datasource::parse_csv(T& stream,
bool parsed_x = false; bool parsed_x = false;
bool parsed_y = false; bool parsed_y = false;
bool parsed_wkt = false; bool parsed_wkt = false;
bool first_feature = true;
bool skip = false; bool skip = false;
bool null_geom = false; bool null_geom = false;
std::vector<std::string> collected; std::vector<std::string> collected;
@ -433,7 +459,20 @@ void csv_datasource::parse_csv(T& stream,
} }
else else
{ {
std::clog << "could not parse: " << value << "\n"; std::ostringstream s;
s << "CSV Plugin: expected well known text geometry: could not parse row "
<< line_number
<< ",column "
<< i << " - found: '"
<< value << "'";
if (strict_)
{
throw mapnik::datasource_exception(s.str());
}
else
{
if (!quiet_) std::clog << s.str() << "\n";
}
} }
} }
else else
@ -538,11 +577,16 @@ void csv_datasource::parse_csv(T& stream,
boost::put(*feature,fld_name,mapnik::value_null()); boost::put(*feature,fld_name,mapnik::value_null());
} }
// only true strings are this long // only true strings are this long
else if (value_length > 20) else if (value_length > 20
// TODO - clean up this messiness which is here temporarily
// to protect against the improperly working spirit parsing below
|| value.find(",") != std::string::npos
|| value.find(":") != std::string::npos
|| (std::count(value.begin(), value.end(), '-') > 1))
{ {
UnicodeString ustr = tr.transcode(value.c_str()); UnicodeString ustr = tr.transcode(value.c_str());
boost::put(*feature,fld_name,ustr); boost::put(*feature,fld_name,ustr);
if (first_feature) if (!feature_count)
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String)); desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String));
} }
@ -557,14 +601,14 @@ void csv_datasource::parse_csv(T& stream,
if (value.find(".") != std::string::npos) if (value.find(".") != std::string::npos)
{ {
boost::put(*feature,fld_name,float_val); boost::put(*feature,fld_name,float_val);
if (first_feature) if (!feature_count)
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::Double)); desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::Double));
} }
else else
{ {
int val = static_cast<int>(float_val); int val = static_cast<int>(float_val);
boost::put(*feature,fld_name,val); boost::put(*feature,fld_name,val);
if (first_feature) if (!feature_count)
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::Integer)); desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::Integer));
} }
} }
@ -573,22 +617,23 @@ void csv_datasource::parse_csv(T& stream,
// fallback to normal string // fallback to normal string
UnicodeString ustr = tr.transcode(value.c_str()); UnicodeString ustr = tr.transcode(value.c_str());
boost::put(*feature,fld_name,ustr); boost::put(*feature,fld_name,ustr);
if (first_feature) if (!feature_count)
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String)); desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String));
} }
} }
else else
{ {
if (value == "true") std::string value_lower = boost::algorithm::to_lower_copy(value);
if (value_lower == "true")
{ {
boost::put(*feature,fld_name,true); boost::put(*feature,fld_name,true);
if (first_feature) if (!feature_count)
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::Boolean)); desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::Boolean));
} }
else if(value == "false") else if(value_lower == "false")
{ {
boost::put(*feature,fld_name,false); boost::put(*feature,fld_name,false);
if (first_feature) if (!feature_count)
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::Boolean)); desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::Boolean));
} }
else else
@ -596,14 +641,12 @@ void csv_datasource::parse_csv(T& stream,
// fallback to normal string // fallback to normal string
UnicodeString ustr = tr.transcode(value.c_str()); UnicodeString ustr = tr.transcode(value.c_str());
boost::put(*feature,fld_name,ustr); boost::put(*feature,fld_name,ustr);
if (first_feature) if (!feature_count)
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String)); desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String));
} }
} }
} }
first_feature = false;
if (skip) if (skip)
{ {
++line_number; ++line_number;

View file

@ -241,14 +241,18 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature,
{ {
if (ordinates_size >= dimensions) if (ordinates_size >= dimensions)
{ {
const bool is_single_geom = true;
const bool is_point_type = false;
const bool multiple_geoms = false;
convert_ordinates (feature, convert_ordinates (feature,
mapnik::LineString, mapnik::LineString,
elem_info, elem_info,
ordinates, ordinates,
dimensions, dimensions,
true, // is_single_geom is_single_geom,
false, // is_point_type is_point_type,
false); // multiple_geometries multiple_geoms);
} }
} }
break; break;
@ -256,14 +260,18 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature,
{ {
if (ordinates_size >= dimensions) if (ordinates_size >= dimensions)
{ {
const bool is_single_geom = true;
const bool is_point_type = false;
const bool multiple_geoms = false;
convert_ordinates (feature, convert_ordinates (feature,
mapnik::Polygon, mapnik::Polygon,
elem_info, elem_info,
ordinates, ordinates,
dimensions, dimensions,
true, // is_single_geom is_single_geom,
false, // is_point_type is_point_type,
false); // multiple_geometries multiple_geoms);
} }
} }
break; break;
@ -273,6 +281,7 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature,
{ {
const bool is_single_geom = false; const bool is_single_geom = false;
const bool is_point_type = true; const bool is_point_type = true;
const bool multiple_geoms = true;
// Todo - force using true as multiple_geometries until we have proper multipoint handling // Todo - force using true as multiple_geometries until we have proper multipoint handling
// http://trac.mapnik.org/ticket/458 // http://trac.mapnik.org/ticket/458
@ -282,9 +291,9 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature,
elem_info, elem_info,
ordinates, ordinates,
dimensions, dimensions,
false, // is_single_geom is_single_geom,
true, // is_point_type is_point_type,
true); // multiple_geometries multiple_geoms);
} }
} }
break; break;
@ -292,13 +301,16 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature,
{ {
if (ordinates_size >= dimensions) if (ordinates_size >= dimensions)
{ {
const bool is_single_geom = false;
const bool is_point_type = false;
convert_ordinates (feature, convert_ordinates (feature,
mapnik::LineString, mapnik::LineString,
elem_info, elem_info,
ordinates, ordinates,
dimensions, dimensions,
false, // is_single_geom is_single_geom,
false, // is_point_type is_point_type,
multiple_geometries); multiple_geometries);
} }
@ -308,13 +320,16 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature,
{ {
if (ordinates_size >= dimensions) if (ordinates_size >= dimensions)
{ {
const bool is_single_geom = false;
const bool is_point_type = false;
convert_ordinates (feature, convert_ordinates (feature,
mapnik::Polygon, mapnik::Polygon,
elem_info, elem_info,
ordinates, ordinates,
dimensions, dimensions,
false, // is_single_geom is_single_geom,
false, // is_point_type is_point_type,
multiple_geometries); multiple_geometries);
} }
@ -332,8 +347,8 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature,
elem_info, elem_info,
ordinates, ordinates,
dimensions, dimensions,
false, // is_single_geom, is_single_geom,
false, // is_point_type is_point_type,
multiple_geometries); multiple_geometries);
} }
} }

View file

@ -65,6 +65,10 @@ raster_datasource::raster_datasource(const parameters& params, bool bind)
else else
filename_ = *file; filename_ = *file;
multi_tiles_ = *params_.get<bool>("multi", false);
tile_size_ = *params_.get<unsigned>("tile_size", 256);
tile_stride_ = *params_.get<unsigned>("tile_stride", 1);
format_=*params_.get<std::string>("format","tiff"); format_=*params_.get<std::string>("format","tiff");
boost::optional<double> lox = params_.get<double>("lox"); boost::optional<double> lox = params_.get<double>("lox");
@ -96,33 +100,50 @@ void raster_datasource::bind() const
{ {
if (is_bound_) return; if (is_bound_) return;
if (! boost::filesystem::exists(filename_)) if (multi_tiles_)
throw datasource_exception("Raster Plugin: " + filename_ + " does not exist"); {
boost::optional<unsigned> x_width = params_.get<unsigned>("x_width");
try boost::optional<unsigned> y_width = params_.get<unsigned>("y_width");
{
std::auto_ptr<image_reader> reader(mapnik::get_image_reader(filename_, format_));
if (reader.get())
{
width_ = reader->width();
height_ = reader->height();
#ifdef MAPNIK_DEBUG if (!x_width)
std::clog << "Raster Plugin: RASTER SIZE(" << width_ << "," << height_ << ")" << std::endl; throw datasource_exception("Raster Plugin: x-width parameter not supplied for multi-tiled data source.");
#endif
} if (!y_width)
throw datasource_exception("Raster Plugin: y-width parameter not supplied for multi-tiled data source.");
width_ = x_width.get() * tile_size_;
height_ = y_width.get() * tile_size_;
} }
catch (mapnik::image_reader_exception const& ex) else
{ {
std::cerr << "Raster Plugin: image reader exception caught: " << ex.what() << std::endl; if (! boost::filesystem::exists(filename_))
throw; throw datasource_exception("Raster Plugin: " + filename_ + " does not exist");
}
catch (...) try
{ {
std::cerr << "Raster Plugin: exception caught" << std::endl; std::auto_ptr<image_reader> reader(mapnik::get_image_reader(filename_, format_));
throw; if (reader.get())
{
width_ = reader->width();
height_ = reader->height();
}
}
catch (mapnik::image_reader_exception const& ex)
{
std::cerr << "Raster Plugin: image reader exception caught: " << ex.what() << std::endl;
throw;
}
catch (...)
{
std::cerr << "Raster Plugin: exception caught" << std::endl;
throw;
}
} }
#ifdef MAPNIK_DEBUG
std::clog << "Raster Plugin: RASTER SIZE(" << width_ << "," << height_ << ")" << std::endl;
#endif
is_bound_ = true; is_bound_ = true;
} }
@ -165,7 +186,16 @@ featureset_ptr raster_datasource::features(query const& q) const
std::clog << "Raster Plugin: BOX SIZE(" << width << " " << height << ")" << std::endl; std::clog << "Raster Plugin: BOX SIZE(" << width << " " << height << ")" << std::endl;
#endif #endif
if (width * height > 512*512) if (multi_tiles_)
{
#ifdef MAPNIK_DEBUG
std::clog << "Raster Plugin: MULTI-TILED policy" << std::endl;
#endif
tiled_multi_file_policy policy(filename_, format_, tile_size_, extent_, q.get_bbox(), width_, height_, tile_stride_);
return boost::make_shared<raster_featureset<tiled_multi_file_policy> >(policy, extent_, q);
}
else if (width * height > 512*512)
{ {
#ifdef MAPNIK_DEBUG #ifdef MAPNIK_DEBUG
std::clog << "Raster Plugin: TILED policy" << std::endl; std::clog << "Raster Plugin: TILED policy" << std::endl;

View file

@ -37,6 +37,9 @@ class raster_datasource : public mapnik::datasource
std::string format_; std::string format_;
mapnik::box2d<double> extent_; mapnik::box2d<double> extent_;
bool extent_initialized_; bool extent_initialized_;
bool multi_tiles_;
unsigned tile_size_;
unsigned tile_stride_;
mutable unsigned width_; mutable unsigned width_;
mutable unsigned height_; mutable unsigned height_;
public: public:

View file

@ -27,6 +27,7 @@
#include "raster_featureset.hpp" #include "raster_featureset.hpp"
#include <boost/algorithm/string/replace.hpp>
using mapnik::query; using mapnik::query;
using mapnik::CoordTransform; using mapnik::CoordTransform;
@ -67,16 +68,18 @@ feature_ptr raster_featureset<LookupPolicy>::next()
std::clog << "Raster Plugin: READER = " << curIter_->format() << " " << curIter_->file() std::clog << "Raster Plugin: READER = " << curIter_->format() << " " << curIter_->file()
<< " size(" << curIter_->width() << "," << curIter_->height() << ")" << std::endl; << " size(" << curIter_->width() << "," << curIter_->height() << ")" << std::endl;
#endif #endif
if (reader.get()) if (reader.get())
{ {
int image_width=reader->width(); int image_width = policy_.img_width(reader->width());
int image_height=reader->height(); int image_height = policy_.img_height(reader->height());
if (image_width>0 && image_height>0) if (image_width>0 && image_height>0)
{ {
CoordTransform t(image_width,image_height,extent_,0,0); CoordTransform t(image_width,image_height,extent_,0,0);
box2d<double> intersect=bbox_.intersect(curIter_->envelope()); box2d<double> intersect=bbox_.intersect(curIter_->envelope());
box2d<double> ext=t.forward(intersect); box2d<double> ext=t.forward(intersect);
box2d<double> rem=policy_.transform(ext);
if ( ext.width()>0.5 && ext.height()>0.5 ) if ( ext.width()>0.5 && ext.height()>0.5 )
{ {
//select minimum raster containing whole ext //select minimum raster containing whole ext
@ -96,7 +99,8 @@ feature_ptr raster_featureset<LookupPolicy>::next()
int width = end_x - x_off; int width = end_x - x_off;
int height = end_y - y_off; int height = end_y - y_off;
//calculate actual box2d of returned raster //calculate actual box2d of returned raster
box2d<double> feature_raster_extent(x_off, y_off, x_off+width, y_off+height); box2d<double> feature_raster_extent(rem.minx() + x_off, rem.miny() + y_off,
rem.maxx() + x_off + width, rem.maxy() + y_off + height);
intersect = t.backward(feature_raster_extent); intersect = t.backward(feature_raster_extent);
image_data_32 image(width,height); image_data_32 image(width,height);
@ -121,5 +125,20 @@ feature_ptr raster_featureset<LookupPolicy>::next()
return feature_ptr(); return feature_ptr();
} }
std::string
tiled_multi_file_policy::interpolate(std::string const &pattern, int x, int y) const
{
// TODO: make from some sort of configurable interpolation
int tms_y = tile_stride_ * ((image_height_ / tile_size_) - y - 1);
int tms_x = tile_stride_ * x;
std::string xs = (boost::format("%03d/%03d/%03d") % (tms_x / 1000000) % ((tms_x / 1000) % 1000) % (tms_x % 1000)).str();
std::string ys = (boost::format("%03d/%03d/%03d") % (tms_y / 1000000) % ((tms_y / 1000) % 1000) % (tms_y % 1000)).str();
std::string rv(pattern);
boost::algorithm::replace_all(rv, "${x}", xs);
boost::algorithm::replace_all(rv, "${y}", ys);
return rv;
}
template class raster_featureset<single_file_policy>; template class raster_featureset<single_file_policy>;
template class raster_featureset<tiled_file_policy>; template class raster_featureset<tiled_file_policy>;
template class raster_featureset<tiled_multi_file_policy>;

View file

@ -29,7 +29,7 @@
// boost // boost
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/format.hpp>
class single_file_policy class single_file_policy
{ {
@ -95,6 +95,21 @@ public:
{ {
return const_iterator(); return const_iterator();
} }
inline int img_width(int reader_width) const
{
return reader_width;
}
inline int img_height(int reader_height) const
{
return reader_height;
}
inline box2d<double> transform(box2d<double> &) const
{
return box2d<double>(0, 0, 0, 0);
}
}; };
class tiled_file_policy class tiled_file_policy
@ -154,11 +169,125 @@ public:
return infos_.end(); return infos_.end();
} }
inline int img_width(int reader_width) const
{
return reader_width;
}
inline int img_height(int reader_height) const
{
return reader_height;
}
inline box2d<double> transform(box2d<double> &) const
{
return box2d<double>(0, 0, 0, 0);
}
private: private:
std::vector<raster_info> infos_; std::vector<raster_info> infos_;
}; };
class tiled_multi_file_policy
{
public:
typedef std::vector<raster_info>::const_iterator const_iterator;
tiled_multi_file_policy(std::string const& file_pattern, std::string const& format, unsigned tile_size,
box2d<double> extent, box2d<double> bbox,unsigned width, unsigned height,
unsigned tile_stride)
: image_width_(width), image_height_(height), tile_size_(tile_size), tile_stride_(tile_stride)
{
double lox = extent.minx();
double loy = extent.miny();
int max_x = int(std::ceil(double(width)/double(tile_size)));
int max_y = int(std::ceil(double(height)/double(tile_size)));
double pixel_x = extent.width()/double(width);
double pixel_y = extent.height()/double(height);
#ifdef MAPNIK_DEBUG
std::clog << "Raster Plugin: PIXEL SIZE("<< pixel_x << "," << pixel_y << ")" << std::endl;
#endif
// intersection of query with extent => new query
box2d<double> e = bbox.intersect(extent);
const int x_min = int(std::floor((e.minx() - lox) / (tile_size * pixel_x)));
const int y_min = int(std::floor((e.miny() - loy) / (tile_size * pixel_y)));
const int x_max = int(std::ceil((e.maxx() - lox) / (tile_size * pixel_x)));
const int y_max = int(std::ceil((e.maxy() - loy) / (tile_size * pixel_y)));
for (int x = x_min ; x < x_max ; ++x)
{
for (int y = y_min ; y < y_max ; ++y)
{
// x0, y0, x1, y1 => projection-space image coordinates.
double x0 = lox + x*tile_size*pixel_x;
double y0 = loy + y*tile_size*pixel_y;
double x1 = x0 + tile_size*pixel_x;
double y1 = y0 + tile_size*pixel_y;
// check if it intersects the query
if (e.intersects(box2d<double>(x0,y0,x1,y1)))
{
// tile_box => intersection of tile with query in projection-space.
box2d<double> tile_box = e.intersect(box2d<double>(x0,y0,x1,y1));
std::string file = interpolate(file_pattern, x, y);
raster_info info(file,format,tile_box,tile_size,tile_size);
infos_.push_back(info);
}
}
}
#ifdef MAPNIK_DEBUG
std::clog << "Raster Plugin: INFO SIZE=" << infos_.size() << " " << file_pattern << std::endl;
#endif
}
const_iterator begin()
{
return infos_.begin();
}
const_iterator end()
{
return infos_.end();
}
inline int img_width(int) const
{
return image_width_;
}
inline int img_height(int) const
{
return image_height_;
}
inline box2d<double> transform(box2d<double> &box) const
{
int x_offset = int(std::floor(box.minx() / tile_size_));
int y_offset = int(std::floor(box.miny() / tile_size_));
box2d<double> rem(x_offset * tile_size_, y_offset * tile_size_,
x_offset * tile_size_, y_offset * tile_size_);
box.init(box.minx() - rem.minx(),
box.miny() - rem.miny(),
box.maxx() - rem.maxx(),
box.maxy() - rem.maxy());
return rem;
}
private:
std::string interpolate(std::string const &pattern, int x, int y) const;
unsigned int image_width_, image_height_, tile_size_, tile_stride_;
std::vector<raster_info> infos_;
};
template <typename LookupPolicy> template <typename LookupPolicy>
class raster_featureset : public mapnik::Featureset class raster_featureset : public mapnik::Featureset

View file

@ -32,6 +32,7 @@
// boost // boost
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/algorithm/string.hpp>
// sqlite // sqlite
extern "C" { extern "C" {
@ -45,13 +46,11 @@ class sqlite_utils
{ {
public: public:
static void dequote(std::string& s) static void dequote(std::string & z)
{ {
if (s[0] == '[' || s[0] == '\'' || s[0] == '"' || s[0] == '`') boost::algorithm::trim_if(z,boost::algorithm::is_any_of("[]'\"`"));
{
s = s.substr(1, s.length() - 1);
}
} }
}; };
@ -135,9 +134,8 @@ public:
const char* column_text (int col, int& len) const char* column_text (int col, int& len)
{ {
const char* text = (const char*) sqlite3_column_text (stmt_, col);
len = sqlite3_column_bytes (stmt_, col); len = sqlite3_column_bytes (stmt_, col);
return text; return (const char*) sqlite3_column_text (stmt_, col);
} }
const char* column_text (int col) const char* column_text (int col)
@ -147,9 +145,8 @@ public:
const void* column_blob (int col, int& bytes) const void* column_blob (int col, int& bytes)
{ {
const char* blob = (const char*) sqlite3_column_blob (stmt_, col);
bytes = sqlite3_column_bytes (stmt_, col); bytes = sqlite3_column_bytes (stmt_, col);
return blob; return (const char*) sqlite3_column_blob (stmt_, col);
} }
sqlite3_stmt* get_statement() sqlite3_stmt* get_statement()

View file

@ -73,7 +73,7 @@
// boost // boost
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/make_shared.hpp>
// stl // stl
#ifdef MAPNIK_DEBUG #ifdef MAPNIK_DEBUG
@ -121,8 +121,31 @@ agg_renderer<T>::agg_renderer(Map const& m, T & pixmap, double scale_factor, uns
t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y), t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y),
font_engine_(), font_engine_(),
font_manager_(font_engine_), font_manager_(font_engine_),
detector_(box2d<double>(-m.buffer_size(), -m.buffer_size(), m.width() + m.buffer_size() ,m.height() + m.buffer_size())), detector_(boost::make_shared<label_collision_detector4>(box2d<double>(-m.buffer_size(), -m.buffer_size(), m.width() + m.buffer_size() ,m.height() + m.buffer_size()))),
ras_ptr(new rasterizer) ras_ptr(new rasterizer)
{
setup(m);
}
template <typename T>
agg_renderer<T>::agg_renderer(Map const& m, T & pixmap, boost::shared_ptr<label_collision_detector4> detector,
double scale_factor, unsigned offset_x, unsigned offset_y)
: feature_style_processor<agg_renderer>(m, scale_factor),
pixmap_(pixmap),
width_(pixmap_.width()),
height_(pixmap_.height()),
scale_factor_(scale_factor),
t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y),
font_engine_(),
font_manager_(font_engine_),
detector_(detector),
ras_ptr(new rasterizer)
{
setup(m);
}
template <typename T>
void agg_renderer<T>::setup(Map const &m)
{ {
boost::optional<color> const& bg = m.background(); boost::optional<color> const& bg = m.background();
if (bg) pixmap_.set_background(*bg); if (bg) pixmap_.set_background(*bg);
@ -189,7 +212,7 @@ void agg_renderer<T>::start_layer_processing(layer const& lay)
#endif #endif
if (lay.clear_label_cache()) if (lay.clear_label_cache())
{ {
detector_.clear(); detector_->clear();
} }
} }

View file

@ -77,12 +77,12 @@ void agg_renderer<T>::process(glyph_symbolizer const& sym,
// final box so we can check for a valid placement // final box so we can check for a valid placement
box2d<double> dim = ren.prepare_glyphs(path.get()); box2d<double> dim = ren.prepare_glyphs(path.get());
box2d<double> ext(x-dim.width()/2, y-dim.height()/2, x+dim.width()/2, y+dim.height()/2); box2d<double> ext(x-dim.width()/2, y-dim.height()/2, x+dim.width()/2, y+dim.height()/2);
if ((sym.get_allow_overlap() || detector_.has_placement(ext)) && if ((sym.get_allow_overlap() || detector_->has_placement(ext)) &&
(!sym.get_avoid_edges() || detector_.extent().contains(ext))) (!sym.get_avoid_edges() || detector_->extent().contains(ext)))
{ {
// Placement is valid, render glyph and update detector. // Placement is valid, render glyph and update detector.
ren.render(x, y); ren.render(x, y);
detector_.insert(ext); detector_->insert(ext);
metawriter_with_properties writer = sym.get_metawriter(); metawriter_with_properties writer = sym.get_metawriter();
if (writer.first) writer.first->add_box(ext, feature, t_, writer.second); if (writer.first) writer.first->add_box(ext, feature, t_, writer.second);
} }

View file

@ -109,7 +109,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
} }
path_type path(t_,geom,prj_trans); path_type path(t_,geom,prj_trans);
markers_placement<path_type, label_collision_detector4> placement(path, extent, detector_, markers_placement<path_type, label_collision_detector4> placement(path, extent, *detector_,
sym.get_spacing() * scale_factor_, sym.get_spacing() * scale_factor_,
sym.get_max_error(), sym.get_max_error(),
sym.get_allow_overlap()); sym.get_allow_overlap());
@ -194,7 +194,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
box2d<double> label_ext (px, py, px + dx +1, py + dy +1); box2d<double> label_ext (px, py, px + dx +1, py + dy +1);
if (sym.get_allow_overlap() || if (sym.get_allow_overlap() ||
detector_.has_placement(label_ext)) detector_->has_placement(label_ext))
{ {
agg::ellipse c(x, y, w, h); agg::ellipse c(x, y, w, h);
marker.concat_path(c); marker.concat_path(c);
@ -215,7 +215,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
ren.color(agg::rgba8(s_r, s_g, s_b, int(s_a*stroke_.get_opacity()))); ren.color(agg::rgba8(s_r, s_g, s_b, int(s_a*stroke_.get_opacity())));
agg::render_scanlines(*ras_ptr, sl_line, ren); agg::render_scanlines(*ras_ptr, sl_line, ren);
} }
detector_.insert(label_ext); detector_->insert(label_ext);
if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second); if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
} }
} }
@ -226,7 +226,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
marker.concat_path(arrow_); marker.concat_path(arrow_);
path_type path(t_,geom,prj_trans); path_type path(t_,geom,prj_trans);
markers_placement<path_type, label_collision_detector4> placement(path, extent, detector_, markers_placement<path_type, label_collision_detector4> placement(path, extent, *detector_,
sym.get_spacing() * scale_factor_, sym.get_spacing() * scale_factor_,
sym.get_max_error(), sym.get_max_error(),
sym.get_allow_overlap()); sym.get_allow_overlap());

View file

@ -99,13 +99,13 @@ void agg_renderer<T>::process(point_symbolizer const& sym,
label_ext.re_center(x,y); label_ext.re_center(x,y);
if (sym.get_allow_overlap() || if (sym.get_allow_overlap() ||
detector_.has_placement(label_ext)) detector_->has_placement(label_ext))
{ {
render_marker(floor(x - 0.5 * w),floor(y - 0.5 * h) ,**marker,tr, sym.get_opacity()); render_marker(floor(x - 0.5 * w),floor(y - 0.5 * h) ,**marker,tr, sym.get_opacity());
if (!sym.get_ignore_placement()) if (!sym.get_ignore_placement())
detector_.insert(label_ext); detector_->insert(label_ext);
metawriter_with_properties writer = sym.get_metawriter(); metawriter_with_properties writer = sym.get_metawriter();
if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second); if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
} }

View file

@ -135,7 +135,7 @@ void agg_renderer<T>::process(shield_symbolizer const& sym,
ren.set_halo_radius(sym.get_halo_radius() * scale_factor_); ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);
ren.set_opacity(sym.get_text_opacity()); ren.set_opacity(sym.get_text_opacity());
placement_finder<label_collision_detector4> finder(detector_); placement_finder<label_collision_detector4> finder(*detector_);
string_info info(text); string_info info(text);
@ -210,13 +210,13 @@ void agg_renderer<T>::process(shield_symbolizer const& sym,
label_ext.re_center(label_x,label_y); label_ext.re_center(label_x,label_y);
} }
if ( sym.get_allow_overlap() || detector_.has_placement(label_ext) ) if ( sym.get_allow_overlap() || detector_->has_placement(label_ext) )
{ {
render_marker(px,py,**marker,tr,sym.get_opacity()); render_marker(px,py,**marker,tr,sym.get_opacity());
box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[0]); box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[0]);
ren.render(x,y); ren.render(x,y);
detector_.insert(label_ext); detector_->insert(label_ext);
finder.update_detector(text_placement); finder.update_detector(text_placement);
if (writer.first) { if (writer.first) {
writer.first->add_box(label_ext, feature, t_, writer.second); writer.first->add_box(label_ext, feature, t_, writer.second);

View file

@ -110,7 +110,7 @@ void agg_renderer<T>::process(text_symbolizer const& sym,
ren.set_opacity(sym.get_text_opacity()); ren.set_opacity(sym.get_text_opacity());
box2d<double> dims(0,0,width_,height_); box2d<double> dims(0,0,width_,height_);
placement_finder<label_collision_detector4> finder(detector_,dims); placement_finder<label_collision_detector4> finder(*detector_,dims);
string_info info(text); string_info info(text);

View file

@ -384,14 +384,6 @@ box2d<T>& box2d<T>::operator+=(box2d<T> const& other)
return *this; return *this;
} }
/*
template <typename T>
box2d<T>& box2d<T>::operator-=(box2d<T> const& other)
{
// not sure what to do here. intersect?
return *this;
}
*/
template <typename T> template <typename T>
box2d<T>& box2d<T>::operator*=(T t) box2d<T>& box2d<T>::operator*=(T t)

View file

@ -173,5 +173,7 @@ void grid_renderer<T>::render_marker(Feature const& feature, unsigned int step,
pixmap_.add_feature(feature); pixmap_.add_feature(feature);
} }
template class hit_grid<boost::uint16_t>;
template class grid_renderer<grid>; template class grid_renderer<grid>;
} }

View file

@ -896,7 +896,7 @@ void map_parser::parse_point_symbolizer( rule & rule, ptree const & sym )
if (transform_wkt) if (transform_wkt)
{ {
agg::trans_affine tr; agg::trans_affine tr;
if (!mapnik::svg::parse_transform(*transform_wkt,tr)) if (!mapnik::svg::parse_transform((*transform_wkt).c_str(),tr))
{ {
std::stringstream ss; std::stringstream ss;
ss << "Could not parse transform from '" << transform_wkt ss << "Could not parse transform from '" << transform_wkt
@ -1025,7 +1025,7 @@ void map_parser::parse_markers_symbolizer( rule & rule, ptree const & sym )
if (transform_wkt) if (transform_wkt)
{ {
agg::trans_affine tr; agg::trans_affine tr;
if (!mapnik::svg::parse_transform(*transform_wkt,tr)) if (!mapnik::svg::parse_transform((*transform_wkt).c_str(),tr))
{ {
std::stringstream ss; std::stringstream ss;
ss << "Could not parse transform from '" << transform_wkt ss << "Could not parse transform from '" << transform_wkt
@ -1671,7 +1671,7 @@ void map_parser::parse_shield_symbolizer( rule & rule, ptree const & sym )
if (transform_wkt) if (transform_wkt)
{ {
agg::trans_affine tr; agg::trans_affine tr;
if (!mapnik::svg::parse_transform(*transform_wkt,tr)) if (!mapnik::svg::parse_transform((*transform_wkt).c_str(),tr))
{ {
std::stringstream ss; std::stringstream ss;
ss << "Could not parse transform from '" << transform_wkt << "', expected string like: 'matrix(1, 0, 0, 1, 0, 0)'"; ss << "Could not parse transform from '" << transform_wkt << "', expected string like: 'matrix(1, 0, 0, 1, 0, 0)'";

View file

@ -23,6 +23,7 @@
//$Id$ //$Id$
// mapnik // mapnik
#include <mapnik/global.hpp>
#include <mapnik/proj_transform.hpp> #include <mapnik/proj_transform.hpp>
#include <mapnik/coord.hpp> #include <mapnik/coord.hpp>
#include <mapnik/utils.hpp> #include <mapnik/utils.hpp>

View file

@ -118,12 +118,15 @@ void raster_colorizer::colorize(raster_ptr const& raster,const std::map<std::str
bool hasNoData = false; bool hasNoData = false;
float noDataValue = 0; float noDataValue = 0;
if (Props.count("NODATA")>0) const std::map<std::string,value>::const_iterator fi = Props.find("NODATA");
if (fi != Props.end())
//if (Props.count("NODATA")>0)
{ {
hasNoData = true; hasNoData = true;
noDataValue = Props.at("NODATA").to_double(); //noDataValue = Props.at("NODATA").to_double();
noDataValue = fi->second.to_double();
} }
for (int i=0; i<len; ++i) for (int i=0; i<len; ++i)
{ {
// the GDAL plugin reads single bands as floats // the GDAL plugin reads single bands as floats

View file

@ -42,6 +42,7 @@ bool parse_transform(const char * wkt, TransformType & p)
return qi::phrase_parse(first, last, g, skip_type()); return qi::phrase_parse(first, last, g, skip_type());
} }
/*
template <typename TransformType> template <typename TransformType>
bool parse_transform(std::string const& wkt, TransformType & p) bool parse_transform(std::string const& wkt, TransformType & p)
{ {
@ -53,8 +54,9 @@ bool parse_transform(std::string const& wkt, TransformType & p)
iterator_type last = wkt.end(); iterator_type last = wkt.end();
return qi::phrase_parse(first, last, g, skip_type()); return qi::phrase_parse(first, last, g, skip_type());
} }
*/
template bool parse_transform<agg::trans_affine>(const char*, agg::trans_affine&); template MAPNIK_DECL bool parse_transform<agg::trans_affine>(const char*, agg::trans_affine&);
template bool parse_transform<agg::trans_affine>(std::string const& , agg::trans_affine&); //template bool parse_transform<agg::trans_affine>(std::string const& , agg::trans_affine&);
}} }}

View file

@ -168,8 +168,8 @@ void text_placements_simple::set_positions(std::string positions)
std::string::iterator first = positions.begin(), last = positions.end(); std::string::iterator first = positions.begin(), last = positions.end();
qi::phrase_parse(first, last, qi::phrase_parse(first, last,
(direction_name[push_back(ref(direction_), _1)] % ',') >> *(',' >> qi::int_[push_back(ref(text_sizes_), _1)]), (direction_name[push_back(phoenix::ref(direction_), _1)] % ',') >> *(',' >> qi::int_[push_back(phoenix::ref(text_sizes_), _1)]),
space space
); );
if (first != last) { if (first != last) {
std::cerr << "WARNING: Could not parse text_placement_simple placement string ('" << positions << "').\n"; std::cerr << "WARNING: Could not parse text_placement_simple placement string ('" << positions << "').\n";

View file

@ -29,6 +29,7 @@
// boost // boost
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/format.hpp>
namespace mapnik namespace mapnik
{ {
@ -56,9 +57,16 @@ public:
wkbMultiPoint=4, wkbMultiPoint=4,
wkbMultiLineString=5, wkbMultiLineString=5,
wkbMultiPolygon=6, wkbMultiPolygon=6,
wkbGeometryCollection=7 wkbGeometryCollection=7,
wkbPointZ=1001,
wkbLineStringZ=1002,
wkbPolygonZ=1003,
wkbMultiPointZ=1004,
wkbMultiLineStringZ=1005,
wkbMultiPolygonZ=1006,
wkbGeometryCollectionZ=1007
}; };
wkb_reader(const char* wkb,unsigned size, wkbFormat format) wkb_reader(const char* wkb,unsigned size, wkbFormat format)
: wkb_(wkb), : wkb_(wkb),
size_(size), size_(size),
@ -68,10 +76,9 @@ public:
// try to determine WKB format automatically // try to determine WKB format automatically
if (format_ == wkbAuto) if (format_ == wkbAuto)
{ {
if (size > 38 if (size >= 44
&& wkb_[0] == 0x00 && (unsigned char)(wkb_[0]) == (unsigned char)(0x00)
&& (wkb_[1] == 0x00 || wkb_[1] == 0x01) && (unsigned char)(wkb_[38]) == (unsigned char)(0x7C))
&& wkb_[38] == 0x7C)
{ {
format_ = wkbSpatiaLite; format_ = wkbSpatiaLite;
} }
@ -86,19 +93,25 @@ public:
case wkbSpatiaLite: case wkbSpatiaLite:
byteOrder_ = (wkbByteOrder) wkb_[1]; byteOrder_ = (wkbByteOrder) wkb_[1];
pos_ = 39; pos_ = 39;
#ifdef MAPNIK_DEBUG_WKB
std::clog << "wkb_reader: format is wkbSpatiaLite" << std::endl;
#endif
break; break;
case wkbGeneric: case wkbGeneric:
default: default:
byteOrder_ = (wkbByteOrder) wkb_[0]; byteOrder_ = (wkbByteOrder) wkb_[0];
pos_ = 1; pos_ = 1;
#ifdef MAPNIK_DEBUG_WKB
std::clog << "wkb_reader: format is wkbGeneric" << std::endl;
#endif
break; break;
} }
#ifndef MAPNIK_BIG_ENDIAN #ifndef MAPNIK_BIG_ENDIAN
needSwap_=byteOrder_?wkbXDR:wkbNDR; needSwap_ = byteOrder_ ? wkbXDR : wkbNDR;
#else #else
needSwap_=byteOrder_?wkbNDR:wkbXDR; needSwap_ = byteOrder_ ? wkbNDR : wkbXDR;
#endif #endif
} }
@ -106,7 +119,13 @@ public:
void read_multi(boost::ptr_vector<geometry_type> & paths) void read_multi(boost::ptr_vector<geometry_type> & paths)
{ {
int type=read_integer(); int type = read_integer();
#ifdef MAPNIK_DEBUG_WKB
std::clog << "wkb_reader: read_multi "
<< wkb_geometry_type_string(type) << " " << type << std::endl;
#endif
switch (type) switch (type)
{ {
case wkbPoint: case wkbPoint:
@ -130,6 +149,27 @@ public:
case wkbGeometryCollection: case wkbGeometryCollection:
read_collection(paths); read_collection(paths);
break; break;
case wkbPointZ:
read_point_xyz(paths);
break;
case wkbLineStringZ:
read_linestring_xyz(paths);
break;
case wkbPolygonZ:
read_polygon_xyz(paths);
break;
case wkbMultiPointZ:
read_multipoint_xyz(paths);
break;
case wkbMultiLineStringZ:
read_multilinestring_xyz(paths);
break;
case wkbMultiPolygonZ:
read_multipolygon_xyz(paths);
break;
case wkbGeometryCollectionZ:
read_collection(paths);
break;
default: default:
break; break;
} }
@ -137,7 +177,12 @@ public:
void read(boost::ptr_vector<geometry_type> & paths) void read(boost::ptr_vector<geometry_type> & paths)
{ {
int type=read_integer(); int type = read_integer();
#ifdef MAPNIK_DEBUG_WKB
std::clog << "wkb_reader: read " << wkb_geometry_type_string(type) << " " << type << std::endl;
#endif
switch (type) switch (type)
{ {
case wkbPoint: case wkbPoint:
@ -161,6 +206,27 @@ public:
case wkbGeometryCollection: case wkbGeometryCollection:
read_collection_2(paths); read_collection_2(paths);
break; break;
case wkbPointZ:
read_point_xyz(paths);
break;
case wkbLineStringZ:
read_linestring_xyz(paths);
break;
case wkbPolygonZ:
read_polygon_xyz(paths);
break;
case wkbMultiPointZ:
read_multipoint_xyz_2(paths);
break;
case wkbMultiLineStringZ:
read_multilinestring_xyz_2(paths);
break;
case wkbMultiPolygonZ:
read_multipolygon_xyz_2(paths);
break;
case wkbGeometryCollectionZ:
read_collection_2(paths);
break;
default: default:
break; break;
} }
@ -173,13 +239,13 @@ private:
boost::int32_t n; boost::int32_t n;
if (needSwap_) if (needSwap_)
{ {
read_int32_xdr(wkb_+pos_,n); read_int32_xdr(wkb_ + pos_, n);
} }
else else
{ {
read_int32_ndr(wkb_+pos_,n); read_int32_ndr(wkb_ + pos_, n);
} }
pos_+=4; pos_ += 4;
return n; return n;
} }
@ -195,127 +261,236 @@ private:
{ {
read_double_ndr(wkb_ + pos_, d); read_double_ndr(wkb_ + pos_, d);
} }
pos_+=8; pos_ += 8;
return d; return d;
} }
void read_coords(CoordinateArray& ar) void read_coords(CoordinateArray& ar)
{ {
int size=sizeof(coord<double,2>)*ar.size(); if (! needSwap_)
if (!needSwap_)
{ {
std::memcpy(&ar[0],wkb_+pos_,size); for (unsigned i = 0; i < ar.size(); ++i)
pos_+=size; {
read_double_ndr(wkb_ + pos_, ar[i].x);
read_double_ndr(wkb_ + pos_ + 8, ar[i].y);
pos_ += 16; // skip XY
}
} }
else else
{ {
for (unsigned i=0;i<ar.size();++i) for (unsigned i=0;i<ar.size();++i)
{ {
read_double_xdr(wkb_ + pos_,ar[i].x); read_double_xdr(wkb_ + pos_, ar[i].x);
read_double_xdr(wkb_ + pos_ + 8,ar[i].y); read_double_xdr(wkb_ + pos_ + 8, ar[i].y);
pos_ += 16; pos_ += 16; // skip XY
} }
} }
} }
void read_coords_xyz(CoordinateArray& ar)
{
if (! needSwap_)
{
for (unsigned i = 0; i < ar.size(); ++i)
{
read_double_ndr(wkb_ + pos_, ar[i].x);
read_double_ndr(wkb_ + pos_ + 8, ar[i].y);
pos_ += 24; // skip XYZ
}
}
else
{
for (unsigned i = 0; i < ar.size(); ++i)
{
read_double_xdr(wkb_ + pos_, ar[i].x);
read_double_xdr(wkb_ + pos_ + 8, ar[i].y);
pos_ += 24; // skip XYZ
}
}
}
void read_point(boost::ptr_vector<geometry_type> & paths) void read_point(boost::ptr_vector<geometry_type> & paths)
{ {
geometry_type * pt = new geometry_type(Point); geometry_type* pt = new geometry_type(Point);
double x = read_double(); double x = read_double();
double y = read_double(); double y = read_double();
pt->move_to(x,y); pt->move_to(x, y);
paths.push_back(pt); paths.push_back(pt);
} }
void read_multipoint(boost::ptr_vector<geometry_type> & paths) void read_multipoint(boost::ptr_vector<geometry_type> & paths)
{ {
int num_points = read_integer(); int num_points = read_integer();
for (int i=0;i<num_points;++i) for (int i = 0; i < num_points; ++i)
{ {
pos_+=5; pos_ += 5;
read_point(paths); read_point(paths);
} }
} }
void read_multipoint_2(boost::ptr_vector<geometry_type> & paths) void read_multipoint_2(boost::ptr_vector<geometry_type> & paths)
{ {
geometry_type * pt = new geometry_type(MultiPoint); geometry_type* pt = new geometry_type(MultiPoint);
int num_points = read_integer(); int num_points = read_integer();
for (int i=0;i<num_points;++i) for (int i = 0; i < num_points; ++i)
{ {
pos_+=5; pos_ += 5;
double x = read_double(); double x = read_double();
double y = read_double(); double y = read_double();
pt->move_to(x,y); pt->move_to(x, y);
} }
paths.push_back(pt); paths.push_back(pt);
} }
void read_point_xyz(boost::ptr_vector<geometry_type> & paths)
{
geometry_type* pt = new geometry_type(Point);
double x = read_double();
double y = read_double();
pos_ += 8; // double z = read_double();
pt->move_to(x, y);
paths.push_back(pt);
}
void read_multipoint_xyz(boost::ptr_vector<geometry_type> & paths)
{
int num_points = read_integer();
for (int i = 0; i < num_points; ++i)
{
pos_ += 5;
read_point_xyz(paths);
}
}
void read_multipoint_xyz_2(boost::ptr_vector<geometry_type> & paths)
{
geometry_type* pt = new geometry_type(MultiPoint);
int num_points = read_integer();
for (int i = 0; i < num_points; ++i)
{
pos_ += 5;
double x = read_double();
double y = read_double();
pos_ += 8; // double z = read_double();
pt->move_to(x, y);
}
paths.push_back(pt);
}
void read_linestring(boost::ptr_vector<geometry_type> & paths) void read_linestring(boost::ptr_vector<geometry_type> & paths)
{ {
geometry_type * line = new geometry_type(LineString); geometry_type* line = new geometry_type(LineString);
int num_points=read_integer(); int num_points = read_integer();
CoordinateArray ar(num_points); CoordinateArray ar(num_points);
read_coords(ar); read_coords(ar);
line->set_capacity(num_points); line->set_capacity(num_points);
line->move_to(ar[0].x,ar[0].y); line->move_to(ar[0].x, ar[0].y);
for (int i=1;i<num_points;++i) for (int i = 1; i < num_points; ++i)
{ {
line->line_to(ar[i].x,ar[i].y); line->line_to(ar[i].x, ar[i].y);
} }
paths.push_back(line); paths.push_back(line);
} }
void read_multilinestring(boost::ptr_vector<geometry_type> & paths) void read_multilinestring(boost::ptr_vector<geometry_type> & paths)
{ {
int num_lines=read_integer(); int num_lines = read_integer();
for (int i=0;i<num_lines;++i) for (int i = 0; i < num_lines; ++i)
{ {
pos_+=5; pos_ += 5;
read_linestring(paths); read_linestring(paths);
} }
} }
void read_multilinestring_2(boost::ptr_vector<geometry_type> & paths) void read_multilinestring_2(boost::ptr_vector<geometry_type> & paths)
{ {
geometry_type * line = new geometry_type(MultiLineString); geometry_type* line = new geometry_type(MultiLineString);
int num_lines=read_integer(); int num_lines = read_integer();
unsigned capacity = 0; unsigned capacity = 0;
for (int i=0;i<num_lines;++i) for (int i = 0; i < num_lines; ++i)
{ {
pos_+=5; pos_ += 5;
int num_points=read_integer(); int num_points = read_integer();
capacity+=num_points; capacity += num_points;
CoordinateArray ar(num_points); CoordinateArray ar(num_points);
read_coords(ar); read_coords(ar);
line->set_capacity(capacity); line->set_capacity(capacity);
line->move_to(ar[0].x,ar[0].y); line->move_to(ar[0].x, ar[0].y);
for (int j=1;j<num_points;++j) for (int j = 1; j < num_points; ++j)
{ {
line->line_to(ar[j].x,ar[j].y); line->line_to(ar[j].x, ar[j].y);
} }
} }
paths.push_back(line); paths.push_back(line);
} }
void read_linestring_xyz(boost::ptr_vector<geometry_type> & paths)
{
geometry_type* line = new geometry_type(LineString);
int num_points = read_integer();
CoordinateArray ar(num_points);
read_coords_xyz(ar);
line->set_capacity(num_points);
line->move_to(ar[0].x, ar[0].y);
for (int i = 1; i < num_points; ++i)
{
line->line_to(ar[i].x, ar[i].y);
}
paths.push_back(line);
}
void read_multilinestring_xyz(boost::ptr_vector<geometry_type> & paths)
{
int num_lines = read_integer();
for (int i = 0; i < num_lines; ++i)
{
pos_ += 5;
read_linestring_xyz(paths);
}
}
void read_multilinestring_xyz_2(boost::ptr_vector<geometry_type> & paths)
{
geometry_type* line = new geometry_type(MultiLineString);
int num_lines = read_integer();
unsigned capacity = 0;
for (int i = 0; i < num_lines; ++i)
{
pos_ += 5;
int num_points = read_integer();
capacity += num_points;
CoordinateArray ar(num_points);
read_coords_xyz(ar);
line->set_capacity(capacity);
line->move_to(ar[0].x, ar[0].y);
for (int j = 1; j < num_points; ++j)
{
line->line_to(ar[j].x, ar[j].y);
}
}
paths.push_back(line);
}
void read_polygon(boost::ptr_vector<geometry_type> & paths) void read_polygon(boost::ptr_vector<geometry_type> & paths)
{ {
geometry_type * poly = new geometry_type(Polygon); geometry_type* poly = new geometry_type(Polygon);
int num_rings=read_integer(); int num_rings = read_integer();
unsigned capacity = 0; unsigned capacity = 0;
for (int i=0;i<num_rings;++i) for (int i = 0; i < num_rings; ++i)
{ {
int num_points=read_integer(); int num_points = read_integer();
capacity+=num_points; capacity += num_points;
CoordinateArray ar(num_points); CoordinateArray ar(num_points);
read_coords(ar); read_coords(ar);
poly->set_capacity(capacity); poly->set_capacity(capacity);
poly->move_to(ar[0].x,ar[0].y); poly->move_to(ar[0].x, ar[0].y);
for (int j=1;j<num_points;++j) for (int j = 1; j < num_points; ++j)
{ {
poly->line_to(ar[j].x,ar[j].y); poly->line_to(ar[j].x, ar[j].y);
} }
} }
paths.push_back(poly); paths.push_back(poly);
@ -323,60 +498,148 @@ private:
void read_multipolygon(boost::ptr_vector<geometry_type> & paths) void read_multipolygon(boost::ptr_vector<geometry_type> & paths)
{ {
int num_polys=read_integer(); int num_polys = read_integer();
for (int i=0;i<num_polys;++i) for (int i = 0; i < num_polys; ++i)
{ {
pos_+=5; pos_ += 5;
read_polygon(paths); read_polygon(paths);
} }
} }
void read_multipolygon_2(boost::ptr_vector<geometry_type> & paths) void read_multipolygon_2(boost::ptr_vector<geometry_type> & paths)
{ {
geometry_type * poly = new geometry_type(MultiPolygon); geometry_type* poly = new geometry_type(MultiPolygon);
int num_polys=read_integer(); int num_polys = read_integer();
unsigned capacity = 0; unsigned capacity = 0;
for (int i=0;i<num_polys;++i) for (int i = 0; i < num_polys; ++i)
{ {
pos_+=5; pos_ += 5;
int num_rings=read_integer(); int num_rings = read_integer();
for (int r=0;r<num_rings;++r) for (int r = 0; r < num_rings; ++r)
{ {
int num_points=read_integer(); int num_points = read_integer();
capacity += num_points; capacity += num_points;
CoordinateArray ar(num_points); CoordinateArray ar(num_points);
read_coords(ar); read_coords(ar);
poly->set_capacity(capacity); poly->set_capacity(capacity);
poly->move_to(ar[0].x,ar[0].y); poly->move_to(ar[0].x, ar[0].y);
for (int j=1;j<num_points;++j) for (int j = 1; j < num_points; ++j)
{ {
poly->line_to(ar[j].x,ar[j].y); poly->line_to(ar[j].x, ar[j].y);
} }
poly->line_to(ar[0].x,ar[0].y); poly->line_to(ar[0].x, ar[0].y);
} }
} }
paths.push_back(poly); paths.push_back(poly);
} }
void read_polygon_xyz(boost::ptr_vector<geometry_type> & paths)
{
geometry_type* poly = new geometry_type(Polygon);
int num_rings = read_integer();
unsigned capacity = 0;
for (int i = 0; i < num_rings; ++i)
{
int num_points = read_integer();
capacity += num_points;
CoordinateArray ar(num_points);
read_coords_xyz(ar);
poly->set_capacity(capacity);
poly->move_to(ar[0].x, ar[0].y);
for (int j = 1; j < num_points; ++j)
{
poly->line_to(ar[j].x, ar[j].y);
}
}
paths.push_back(poly);
}
void read_multipolygon_xyz(boost::ptr_vector<geometry_type> & paths)
{
int num_polys = read_integer();
for (int i = 0; i < num_polys; ++i)
{
pos_ += 5;
read_polygon_xyz(paths);
}
}
void read_multipolygon_xyz_2(boost::ptr_vector<geometry_type> & paths)
{
geometry_type* poly = new geometry_type(MultiPolygon);
int num_polys = read_integer();
unsigned capacity = 0;
for (int i = 0; i < num_polys; ++i)
{
pos_ += 5;
int num_rings = read_integer();
for (int r = 0; r < num_rings; ++r)
{
int num_points = read_integer();
capacity += num_points;
CoordinateArray ar(num_points);
read_coords_xyz(ar);
poly->set_capacity(capacity);
poly->move_to(ar[0].x, ar[0].y);
for (int j = 1; j < num_points; ++j)
{
poly->line_to(ar[j].x, ar[j].y);
}
poly->line_to(ar[0].x, ar[0].y);
}
}
paths.push_back(poly);
}
void read_collection(boost::ptr_vector<geometry_type> & paths) void read_collection(boost::ptr_vector<geometry_type> & paths)
{ {
int num_geometries=read_integer(); int num_geometries = read_integer();
for (int i=0;i<num_geometries;++i) for (int i = 0; i < num_geometries; ++i)
{ {
pos_+=1; // skip byte order pos_ += 1; // skip byte order
read(paths); read(paths);
} }
} }
void read_collection_2(boost::ptr_vector<geometry_type> & paths) void read_collection_2(boost::ptr_vector<geometry_type> & paths)
{ {
int num_geometries=read_integer(); int num_geometries = read_integer();
for (int i=0;i<num_geometries;++i) for (int i = 0; i < num_geometries; ++i)
{ {
pos_+=1; // skip byte order pos_ += 1; // skip byte order
read_multi(paths); read_multi(paths);
} }
} }
#ifdef MAPNIK_DEBUG_WKB
std::string wkb_geometry_type_string(int type)
{
std::stringstream s;
switch (type)
{
case wkbPoint: s << "wkbPoint"; break;
case wkbLineString: s << "wkbLineString"; break;
case wkbPolygon: s << "wkbPolygon"; break;
case wkbMultiPoint: s << "wkbMultiPoint"; break;
case wkbMultiLineString: s << "wkbMultiLineString"; break;
case wkbMultiPolygon: s << "wkbMultiPolygon"; break;
case wkbGeometryCollection: s << "wkbGeometryCollection"; break;
case wkbPointZ: s << "wkbPointZ"; break;
case wkbLineStringZ: s << "wkbLineStringZ"; break;
case wkbPolygonZ: s << "wkbPolygonZ"; break;
case wkbMultiPointZ: s << "wkbMultiPointZ"; break;
case wkbMultiLineStringZ: s << "wkbMultiLineStringZ"; break;
case wkbMultiPolygonZ: s << "wkbMultiPolygonZ"; break;
case wkbGeometryCollectionZ: s << "wkbGeometryCollectionZ"; break;
default: s << "wkbUknown"; break;
}
return s.str();
}
#endif
}; };
void geometry_utils::from_wkb (boost::ptr_vector<geometry_type>& paths, void geometry_utils::from_wkb (boost::ptr_vector<geometry_type>& paths,
@ -385,10 +648,14 @@ void geometry_utils::from_wkb (boost::ptr_vector<geometry_type>& paths,
bool multiple_geometries, bool multiple_geometries,
wkbFormat format) wkbFormat format)
{ {
wkb_reader reader(wkb,size,format); wkb_reader reader(wkb, size, format);
if (multiple_geometries) if (multiple_geometries)
{
return reader.read_multi(paths); return reader.read_multi(paths);
}
else else
{
return reader.read(paths); return reader.read(paths);
}
} }
} }

View file

@ -0,0 +1,9 @@
x,y,name
0,0,a
0,0,b
1 x y name
2 0 0 a
3 0 0 b

View file

@ -0,0 +1,5 @@
x,y,text,date,integer,boolean,float,time,datetime,empty_column
0,0,a b,1971-01-01,40,True,1.0,04:14:00,1971-01-01T04:14:00,
0,0,c d,1948-01-01,63,True,1.27,14:57:13,1948-01-01T14:57:13,
0,0,e f,1920-01-01,164,False,41800000.01,00:00:00,1920-01-01T00:00:00,
0,0,This row has empties,,,,,,,
1 x y text date integer boolean float time datetime empty_column
2 0 0 a b 1971-01-01 40 True 1.0 04:14:00 1971-01-01T04:14:00
3 0 0 c d 1948-01-01 63 True 1.27 14:57:13 1948-01-01T14:57:13
4 0 0 e f 1920-01-01 164 False 41800000.01 00:00:00 1920-01-01T00:00:00
5 0 0 This row has empties

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,3 @@
x,y,z
-122a,48b,bogus
-122,48,fine
1 x y z
2 -122a 48b bogus
3 -122 48 fine

View file

@ -0,0 +1,2 @@
wkt,name
"POINT (a b)",one
1 wkt name
2 POINT (a b) one

View file

@ -0,0 +1,2 @@
x y name
-122, 48, hello
1 x y name
2 -122, 48, hello

View file

@ -0,0 +1,2 @@
a,b,c,d,e,f,g
1,2,3,4,5,6,7
1 a b c d e f g
2 1 2 3 4 5 6 7

View file

@ -0,0 +1 @@
-122,48,place
1 -122 48 place

View file

@ -0,0 +1,4 @@
x,y,name
0,0,a/a
1,4,b/b
10,2.5,c/c
1 x y name
2 0 0 a/a
3 1 4 b/b
4 10 2.5 c/c

View file

@ -0,0 +1,2 @@
latitude,longitude
0,0
1 latitude longitude
2 0 0

View file

@ -0,0 +1,2 @@
this_is_longitude_yo,this_is_latitude_yo
0,0
1 this_is_longitude_yo this_is_latitude_yo
2 0 0

View file

@ -0,0 +1,2 @@
lon,lat
0,0
1 lon lat
2 0 0

View file

@ -0,0 +1,2 @@
long,lat
0,0
1 long lat
2 0 0

View file

@ -0,0 +1 @@
x,y,z 1,10,0
1 x y z 1 10 0

3
tests/data/csv/tabs.tsv Normal file
View file

@ -0,0 +1,3 @@
x y name
-122 48 hello
0 0 "null island"
1 x y name
2 -122 48 hello
3 0 0 null island

View file

@ -0,0 +1,2 @@
x, y,z
-122 , 48,0
1 x y z
2 -122 48 0

View file

@ -0,0 +1,11 @@
geonameid name asciiname alternatenames latitude longitude feature_class feature_code country_code cc2 admin1 admin2 admin3 admin4 population elevation gtopo3 timezone mod_date
725712 Vratsa Vratsa Vraca,Vratca,Vratsa,Vrattsa,Vratza,Wraza,Враца 43.21 23.5625 P PPLA BG 64 VRC10 64941 341 Europe/Sofia 2011-10-10
725816 Sveti Vlas Sveti Vlas Manasturkioy,Manastŭrkioy,Monasturkioy,Monastŭrkioy,Saint Vlas,Sveti Vlas,Sveti-Vlas,Sweti Wlas,Vlas,Влас,Свети-Влас 42.7136 27.75867 P PPL BG BG 39 BGS15 BGS15-02 3875 50 -9999 Europe/Sofia 2010-03-07
725905 Vidin Vidin Vidin,Vidine,Widin,wydyn,Видин,ویدین 43.99 22.8725 P PPLA BG 63 VID09 54409 35 Europe/Sofia 2011-10-10
725924 Vetrino Vetrino Asya-Tepe,Jasi Tepe,Vetrino,Vyetreno,Vyetrino,Wetrino,Yasa-Tepe,Yase-Tepe,Yasu-Tepe,Yasă-Tepe,Yasŭ-Tepe,Ветрино 43.31667 27.43333 P PPL BG BG 61 VAR08 1368 223 Europe/Sofia 2011-10-10
725935 Vetovo Vetovo Vetova,Vetovo,Vjetevo,Vyetovo,Wetowo,Ветово 43.7 26.26667 P PPL BG 53 RSE05 5175 184 Europe/Sofia 2007-04-05
725967 Venets Venets K'okledzha,K'oklyudzha,K'okyudzha,Kiokhudza,Kiokhudža,Kokedzha,Kokledzha,Koklyudzha,Kokyudzha,Venec,Venets,Vyenets,Wenez,Венец 43.55 26.93333 P PPL BG BG 54 SHU07 1450 334 Europe/Sofia 2011-10-10
725988 Velingrad Velingrad Velingrad,Велинград 42.02724 23.99569 P PPL BG 48 PAZ08 24036 745 Europe/Sofia 2010-05-28
725993 Veliko Tŭrnovo Veliko Turnovo Tarnovo,Tarnowo,Ternovo,Tirnovo,Trnova,Trnovo,Turnovo,Tărnovo,Tărnowo,Tŭrnovo,Veliko T\"rnovo,Veliko Tarnovo,Veliko Tărnovo,Weliko Tarnowo,Weliko Tyrnowo,vu~erikotarunovu~o,Велико Търново,ヴェリコタルノヴォ 43.08124 25.62904 P PPLA BG 62 VTR04 66217 162 Europe/Sofia 2007-07-01
726050 Varna Varna Barna,Odessos,Odessus,Stalin,Varna,Warna,farna,varna,vu~aruna,wa er na,wrnh,Βάρνα,Варна,ורנה,فارنا,ვარნა,ヴァルナ,瓦爾納 43.21667 27.91667 P PPLA BG 61 VAR06 312770 95 Europe/Sofia 2011-10-10
726114 Ugŭrchin Ugurchin Ugarchin,Ugarcin,Ugartschin,Ugarčin,Ugirkin,Ugrchin,Ugrcin,Ugrčin,Ugurchin,Ugurcin,Ugürčin,Ugărchin,Ugărtschin,Угърчин 43.1 24.41667 P PPL BG 46 LOV36 2965 298 Europe/Sofia 2007-04-05
Can't render this file because it contains an unexpected character in line 9 and column 129.

View file

View file

@ -0,0 +1,3 @@
x,y,z
-122a,48b,bogus
-122,48,fine
1 x y z
2 -122a 48b bogus
3 -122 48 fine

View file

@ -0,0 +1,2 @@
x,y,z
0,0,0
1 x y z
2 0 0 0

9
tests/data/csv/wkt.csv Normal file
View file

@ -0,0 +1,9 @@
type,WKT
point, "POINT (30 10)"
linestring, "LINESTRING (30 10, 10 30, 40 40)"
polygon, "POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))"
polygon, "POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))"
multipoint, "MULTIPOINT ((10 40), (40 30), (20 20), (30 10))"
multilinestring, "MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))"
multipolygon, "MULTIPOLYGON (((30 20, 10 40, 45 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))"
multipolygon, "MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),((20 35, 45 20, 30 5, 10 10, 10 30, 20 35),(30 20, 20 25, 20 15, 30 20)))"
1 type WKT
2 point POINT (30 10)
3 linestring LINESTRING (30 10, 10 30, 40 40)
4 polygon POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))
5 polygon POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))
6 multipoint MULTIPOINT ((10 40), (40 30), (20 20), (30 10))
7 multilinestring MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))
8 multipolygon MULTIPOLYGON (((30 20, 10 40, 45 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))
9 multipolygon MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),((20 35, 45 20, 30 5, 10 10, 10 30, 20 35),(30 20, 20 25, 20 15, 30 20)))

2
tests/data/csv/x_y.csv Normal file
View file

@ -0,0 +1,2 @@
x,y
0,0
1 x y
2 0 0

View file

@ -22,7 +22,7 @@
<Layer name="point" srs="+init=epsg:4326"> <Layer name="point" srs="+init=epsg:4326">
<StyleName>1</StyleName> <StyleName>1</StyleName>
<Datasource> <Datasource>
<Parameter name="file">../csv/points.vrt</Parameter> <Parameter name="file">../vrt/points.vrt</Parameter>
<Parameter name="layer_by_index">0</Parameter> <Parameter name="layer_by_index">0</Parameter>
<Parameter name="type">ogr</Parameter> <Parameter name="type">ogr</Parameter>
</Datasource> </Datasource>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,8 @@
<OGRVRTDataSource>
<OGRVRTLayer name="points">
<SrcDataSource relativeToVRT="1">../csv/points.csv</SrcDataSource>
<GeometryType>wkbPoint</GeometryType>
<LayerSRS>WGS84</LayerSRS>
<GeometryField encoding="PointFromColumns" x="x" y="y"/>
</OGRVRTLayer>
</OGRVRTDataSource>

View file

@ -18,10 +18,6 @@ class FeatureTest(unittest.TestCase):
f = self.makeOne(1, 'POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))', foo="bar") f = self.makeOne(1, 'POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))', foo="bar")
self.failUnlessEqual(f['foo'], 'bar') self.failUnlessEqual(f['foo'], 'bar')
self.failUnlessEqual(f.envelope(),Box2d(10.0,10.0,45.0,45.0)) self.failUnlessEqual(f.envelope(),Box2d(10.0,10.0,45.0,45.0))
area = 0.0
for g in f.geometries():
area += g.area()
self.failUnlessEqual(area,-450.0)
def test_set_get_properties(self): def test_set_get_properties(self):
f = self.makeOne(1) f = self.makeOne(1)

View file

@ -0,0 +1,70 @@
#!/usr/bin/env python
from nose.tools import *
from utilities import execution_path, save_data, contains_word
import os, mapnik2
def setup():
# All of the paths used are relative, if we run the tests
# from another directory we need to chdir()
os.chdir(execution_path('.'))
def test_multi_tile_policy():
srs = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'
lyr = mapnik2.Layer('raster')
lyr.datasource = mapnik2.Raster(
file = '../data/raster_tiles/${x}/${y}.tif',
lox = -180,
loy = -90,
hix = 180,
hiy = 90,
multi = 1,
tile_size = 256,
x_width = 2,
y_width = 2
)
lyr.srs = srs
_map = mapnik2.Map(256, 256, srs)
style = mapnik2.Style()
rule = mapnik2.Rule()
sym = mapnik2.RasterSymbolizer()
rule.symbols.append(sym)
style.rules.append(rule)
_map.append_style('foo', style)
lyr.styles.append('foo')
_map.layers.append(lyr)
_map.zoom_to_box(lyr.envelope())
im = mapnik2.Image(_map.width, _map.height)
mapnik2.render(_map, im)
save_data('test_multi_tile_policy.png', im.tostring('png'))
# test green chunk
assert im.view(0,64,1,1).tostring() == '\x00\xff\x00\xff'
assert im.view(127,64,1,1).tostring() == '\x00\xff\x00\xff'
assert im.view(0,127,1,1).tostring() == '\x00\xff\x00\xff'
assert im.view(127,127,1,1).tostring() == '\x00\xff\x00\xff'
# test blue chunk
assert im.view(128,64,1,1).tostring() == '\x00\x00\xff\xff'
assert im.view(255,64,1,1).tostring() == '\x00\x00\xff\xff'
assert im.view(128,127,1,1).tostring() == '\x00\x00\xff\xff'
assert im.view(255,127,1,1).tostring() == '\x00\x00\xff\xff'
# test red chunk
assert im.view(0,128,1,1).tostring() == '\xff\x00\x00\xff'
assert im.view(127,128,1,1).tostring() == '\xff\x00\x00\xff'
assert im.view(0,191,1,1).tostring() == '\xff\x00\x00\xff'
assert im.view(127,191,1,1).tostring() == '\xff\x00\x00\xff'
# test magenta chunk
assert im.view(128,128,1,1).tostring() == '\xff\x00\xff\xff'
assert im.view(255,128,1,1).tostring() == '\xff\x00\xff\xff'
assert im.view(128,191,1,1).tostring() == '\xff\x00\xff\xff'
assert im.view(255,191,1,1).tostring() == '\xff\x00\xff\xff'
if __name__ == "__main__":
setup()
[eval(run)() for run in dir() if 'test_' in run]

View file

@ -58,6 +58,37 @@ def test_attachdb_with_explicit_index():
'insert into scratch.myindex values (1,-7799225.5,-7778571.0,1393264.125,1417719.375)\n' 'insert into scratch.myindex values (1,-7799225.5,-7778571.0,1393264.125,1417719.375)\n'
) )
def test_dequoting_of_subqueries():
# The point table and index is in the qgis_spatiallite.sqlite
# database. If either is not found, then this fails
ds = mapnik2.SQLite(file='../data/sqlite/world.sqlite',
table='world_merc',
)
fs = ds.featureset()
feature = fs.next()
eq_(feature['OGC_FID'],1)
eq_(feature['fips'],u'AC')
# TODO:
# select * from world_merc fails
# as rowid is dropped
ds = mapnik2.SQLite(file='../data/sqlite/world.sqlite',
table='(select *,rowid from world_merc)',
)
fs = ds.featureset()
feature = fs.next()
print feature
eq_(feature['OGC_FID'],1)
eq_(feature['fips'],u'AC')
ds = mapnik2.SQLite(file='../data/sqlite/world.sqlite',
table='(select GEOMETRY,OGC_FID as rowid,fips from world_merc)',
)
fs = ds.featureset()
feature = fs.next()
print feature
eq_(feature['rowid'],1)
eq_(feature['fips'],u'AC')
if __name__ == "__main__": if __name__ == "__main__":
setup() setup()

49
workspace/bindings.pri Normal file
View file

@ -0,0 +1,49 @@
HEADERS += \
$$PWD/../bindings/python/mapnik_enumeration.hpp \
$$PWD/../bindings/python/mapnik_svg.hpp \
$$PWD/../bindings/python/mapnik_value_converter.hpp \
$$PWD/../bindings/python/python_grid_utils.hpp \
$$PWD/../bindings/python/python_optional.hpp
SOURCES += \
$$PWD/../bindings/python/mapnik_color.cpp \
$$PWD/../bindings/python/mapnik_coord.cpp \
$$PWD/../bindings/python/mapnik_datasource.cpp \
$$PWD/../bindings/python/mapnik_datasource_cache.cpp \
$$PWD/../bindings/python/mapnik_envelope.cpp \
$$PWD/../bindings/python/mapnik_expression.cpp \
$$PWD/../bindings/python/mapnik_feature.cpp \
$$PWD/../bindings/python/mapnik_featureset.cpp \
$$PWD/../bindings/python/mapnik_font_engine.cpp \
$$PWD/../bindings/python/mapnik_geometry.cpp \
$$PWD/../bindings/python/mapnik_glyph_symbolizer.cpp \
$$PWD/../bindings/python/mapnik_grid.cpp \
$$PWD/../bindings/python/mapnik_grid_view.cpp \
$$PWD/../bindings/python/mapnik_image.cpp \
$$PWD/../bindings/python/mapnik_image_view.cpp \
$$PWD/../bindings/python/mapnik_inmem_metawriter.cpp \
$$PWD/../bindings/python/mapnik_layer.cpp \
$$PWD/../bindings/python/mapnik_line_pattern_symbolizer.cpp \
$$PWD/../bindings/python/mapnik_line_symbolizer.cpp \
$$PWD/../bindings/python/mapnik_map.cpp \
$$PWD/../bindings/python/mapnik_markers_symbolizer.cpp \
$$PWD/../bindings/python/mapnik_palette.cpp \
$$PWD/../bindings/python/mapnik_parameters.cpp \
$$PWD/../bindings/python/mapnik_point_symbolizer.cpp \
$$PWD/../bindings/python/mapnik_polygon_pattern_symbolizer.cpp \
$$PWD/../bindings/python/mapnik_polygon_symbolizer.cpp \
$$PWD/../bindings/python/mapnik_proj_transform.cpp \
$$PWD/../bindings/python/mapnik_projection.cpp \
$$PWD/../bindings/python/mapnik_python.cpp \
$$PWD/../bindings/python/mapnik_query.cpp \
$$PWD/../bindings/python/mapnik_raster_colorizer.cpp \
$$PWD/../bindings/python/mapnik_raster_symbolizer.cpp \
$$PWD/../bindings/python/mapnik_rule.cpp \
$$PWD/../bindings/python/mapnik_shield_symbolizer.cpp \
$$PWD/../bindings/python/mapnik_stroke.cpp \
$$PWD/../bindings/python/mapnik_style.cpp \
$$PWD/../bindings/python/mapnik_symbolizer.cpp \
$$PWD/../bindings/python/mapnik_text_symbolizer.cpp \
$$PWD/../bindings/python/mapnik_view_transform.cpp \
$$PWD/../bindings/python/python_cairo.cpp

View file

@ -201,8 +201,13 @@ SOURCES += \
../src/unicode.cpp \ ../src/unicode.cpp \
../src/warp.cpp \ ../src/warp.cpp \
../src/wkb.cpp ../src/wkb.cpp
OTHER_FILES += \
../SConstruct \
../config.py
include(plugins.pri) include(plugins.pri)
include(bindings.pri)
unix { unix {
DEFINES += LINUX=1 DEFINES += LINUX=1