- merged strict-xml-branch r530:532 to trunk:
- libxml2 support - strict error handling while parsing XML map files - implemented save_map() - removed some duplicate defaults - all symbolizers with icons share a common base class now
This commit is contained in:
parent
49e6d1d7bf
commit
b2df387a9d
42 changed files with 2482 additions and 811 deletions
14
SConstruct
14
SConstruct
|
@ -27,12 +27,13 @@ if platform.uname()[4] == 'x86_64':
|
||||||
else:
|
else:
|
||||||
LIBDIR_SCHEMA='lib'
|
LIBDIR_SCHEMA='lib'
|
||||||
|
|
||||||
opts = Options()
|
opts = Options('config.py')
|
||||||
opts.Add('PREFIX', 'The install path "prefix"', '/usr/local')
|
opts.Add('PREFIX', 'The install path "prefix"', '/usr/local')
|
||||||
opts.Add(PathOption('BOOST_INCLUDES', 'Search path for boost include files', '/usr/include'))
|
opts.Add(PathOption('BOOST_INCLUDES', 'Search path for boost include files', '/usr/include'))
|
||||||
opts.Add(PathOption('BOOST_LIBS', 'Search path for boost library files', '/usr/' + LIBDIR_SCHEMA))
|
opts.Add(PathOption('BOOST_LIBS', 'Search path for boost library files', '/usr/' + LIBDIR_SCHEMA))
|
||||||
opts.Add('BOOST_TOOLKIT','Specify boost toolkit e.g. gcc41.','',False)
|
opts.Add('BOOST_TOOLKIT','Specify boost toolkit e.g. gcc41.','',False)
|
||||||
opts.Add(('FREETYPE_CONFIG', 'The path to the freetype-config executable.', 'freetype-config'))
|
opts.Add(('FREETYPE_CONFIG', 'The path to the freetype-config executable.', 'freetype-config'))
|
||||||
|
opts.Add(('XML2_CONFIG', 'The path to the xml2-config executable.', 'xml2-config'))
|
||||||
opts.Add(PathOption('FRIBIDI_INCLUDES', 'Search path for fribidi include files', '/usr/include'))
|
opts.Add(PathOption('FRIBIDI_INCLUDES', 'Search path for fribidi include files', '/usr/include'))
|
||||||
opts.Add(PathOption('FRIBIDI_LIBS','Search path for fribidi include files','/usr/' + LIBDIR_SCHEMA))
|
opts.Add(PathOption('FRIBIDI_LIBS','Search path for fribidi include files','/usr/' + LIBDIR_SCHEMA))
|
||||||
opts.Add(PathOption('PNG_INCLUDES', 'Search path for libpng include files', '/usr/include'))
|
opts.Add(PathOption('PNG_INCLUDES', 'Search path for libpng include files', '/usr/include'))
|
||||||
|
@ -56,7 +57,7 @@ opts.Add(BoolOption('DEBUG', 'Compile a debug version of mapnik', 'False'))
|
||||||
opts.Add('DESTDIR', 'The root directory to install into. Useful mainly for binary package building', '/')
|
opts.Add('DESTDIR', 'The root directory to install into. Useful mainly for binary package building', '/')
|
||||||
opts.Add(BoolOption('BIDI', 'BIDI support', 'False'))
|
opts.Add(BoolOption('BIDI', 'BIDI support', 'False'))
|
||||||
opts.Add(EnumOption('THREADING','Set threading support','multi', ['multi','single']))
|
opts.Add(EnumOption('THREADING','Set threading support','multi', ['multi','single']))
|
||||||
opts.Add(EnumOption('XMLPARSER','Set xml parser ','tinyxml', ['tinyxml','spirit']))
|
opts.Add(EnumOption('XMLPARSER','Set xml parser ','tinyxml', ['tinyxml','spirit','libxml2']))
|
||||||
|
|
||||||
env = Environment(ENV=os.environ, options=opts)
|
env = Environment(ENV=os.environ, options=opts)
|
||||||
|
|
||||||
|
@ -105,6 +106,9 @@ if env['BIDI']:
|
||||||
|
|
||||||
if env['XMLPARSER'] == 'tinyxml':
|
if env['XMLPARSER'] == 'tinyxml':
|
||||||
env.Append(CXXFLAGS = '-DBOOST_PROPERTY_TREE_XML_PARSER_TINYXML -DTIXML_USE_STL')
|
env.Append(CXXFLAGS = '-DBOOST_PROPERTY_TREE_XML_PARSER_TINYXML -DTIXML_USE_STL')
|
||||||
|
elif env['XMLPARSER'] == 'libxml2':
|
||||||
|
env.ParseConfig(env['XML2_CONFIG'] + ' --libs --cflags')
|
||||||
|
env.Append(CXXFLAGS = '-DHAVE_LIBXML2');
|
||||||
|
|
||||||
C_LIBSHEADERS = [
|
C_LIBSHEADERS = [
|
||||||
['m', 'math.h', True],
|
['m', 'math.h', True],
|
||||||
|
@ -224,10 +228,12 @@ env = conf.Finish()
|
||||||
if env['PLATFORM'] == 'Darwin': pthread = ''
|
if env['PLATFORM'] == 'Darwin': pthread = ''
|
||||||
else: pthread = '-pthread'
|
else: pthread = '-pthread'
|
||||||
|
|
||||||
|
common_cxx_flags = '-ansi -Wall %s -ftemplate-depth-100 -D%s ' % (pthread, env['PLATFORM'].upper());
|
||||||
|
|
||||||
if env['DEBUG']:
|
if env['DEBUG']:
|
||||||
env.Append(CXXFLAGS = '-ansi -Wall %s -ftemplate-depth-100 -O0 -fno-inline -g -DDEBUG -DMAPNIK_DEBUG -D%s ' % (pthread, env['PLATFORM'].upper()))
|
env.Append(CXXFLAGS = common_cxx_flags + '-O0 -fno-inline -g -DDEBUG -DMAPNIK_DEBUG')
|
||||||
else:
|
else:
|
||||||
env.Append(CXXFLAGS = '-ansi -Wall %s -ftemplate-depth-100 -O2 -finline-functions -Wno-inline -DNDEBUG -D%s' % (pthread,env['PLATFORM'].upper()))
|
env.Append(CXXFLAGS = common_cxx_flags + '-O2 -finline-functions -Wno-inline -DNDEBUG')
|
||||||
|
|
||||||
# Install some free default fonts
|
# Install some free default fonts
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,10 @@ DatasourceCache.instance().register_datasources('%s' % inputpluginspath)
|
||||||
from mapnik import FontEngine
|
from mapnik import FontEngine
|
||||||
from glob import glob
|
from glob import glob
|
||||||
fonts = glob('%s/*.ttf' % fontscollectionpath)
|
fonts = glob('%s/*.ttf' % fontscollectionpath)
|
||||||
map(FontEngine.instance().register_font, fonts)
|
if len( fonts ) == 0:
|
||||||
|
print "### WARNING: No ttf files found in '%s'." % fontscollectionpath
|
||||||
|
else:
|
||||||
|
map(FontEngine.instance().register_font, fonts)
|
||||||
|
|
||||||
#set dlopen flags back to the original
|
#set dlopen flags back to the original
|
||||||
setdlopenflags(flags)
|
setdlopenflags(flags)
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
#include <boost/get_pointer.hpp>
|
#include <boost/get_pointer.hpp>
|
||||||
#include <boost/python/detail/api_placeholder.hpp>
|
#include <boost/python/detail/api_placeholder.hpp>
|
||||||
|
#include <boost/python/exception_translator.hpp>
|
||||||
|
|
||||||
void export_color();
|
void export_color();
|
||||||
void export_coord();
|
void export_coord();
|
||||||
|
@ -58,6 +59,7 @@ void export_projection();
|
||||||
#include <mapnik/agg_renderer.hpp>
|
#include <mapnik/agg_renderer.hpp>
|
||||||
#include <mapnik/graphics.hpp>
|
#include <mapnik/graphics.hpp>
|
||||||
#include <mapnik/load_map.hpp>
|
#include <mapnik/load_map.hpp>
|
||||||
|
#include <mapnik/config_error.hpp>
|
||||||
#include <mapnik/save_map.hpp>
|
#include <mapnik/save_map.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,14 +97,21 @@ double scale_denominator(mapnik::Map const &map, bool geographic)
|
||||||
return mapnik::scale_denominator(map, geographic);
|
return mapnik::scale_denominator(map, geographic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void translator(mapnik::config_error const & ex) {
|
||||||
|
PyErr_SetString(PyExc_UserWarning, ex.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_PYTHON_FUNCTION_OVERLOADS(load_map_overloads, load_map, 2, 3);
|
||||||
|
|
||||||
BOOST_PYTHON_MODULE(_mapnik)
|
BOOST_PYTHON_MODULE(_mapnik)
|
||||||
{
|
{
|
||||||
|
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
|
|
||||||
using mapnik::load_map;
|
using mapnik::load_map;
|
||||||
using mapnik::save_map;
|
using mapnik::save_map;
|
||||||
|
|
||||||
|
register_exception_translator<mapnik::config_error>(translator);
|
||||||
export_query();
|
export_query();
|
||||||
export_feature();
|
export_feature();
|
||||||
export_featureset();
|
export_featureset();
|
||||||
|
@ -137,8 +146,8 @@ BOOST_PYTHON_MODULE(_mapnik)
|
||||||
def("render",&render2);
|
def("render",&render2);
|
||||||
def("scale_denominator", &scale_denominator);
|
def("scale_denominator", &scale_denominator);
|
||||||
|
|
||||||
def("load_map",&load_map,"load Map object from XML");
|
def("load_map", & load_map, load_map_overloads());
|
||||||
def("save_map",&load_map,"sace Map object to XML");
|
def("save_map", & save_map, "save Map object to XML");
|
||||||
|
|
||||||
using mapnik::symbolizer;
|
using mapnik::symbolizer;
|
||||||
class_<symbolizer>("Symbolizer",no_init)
|
class_<symbolizer>("Symbolizer",no_init)
|
||||||
|
|
|
@ -30,12 +30,12 @@ void export_stroke ()
|
||||||
using namespace mapnik;
|
using namespace mapnik;
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
|
|
||||||
enum_<line_cap_e>("line_cap")
|
enum_<line_cap_enum>("line_cap")
|
||||||
.value("BUTT_CAP",BUTT_CAP)
|
.value("BUTT_CAP",BUTT_CAP)
|
||||||
.value("SQUARE_CAP",SQUARE_CAP)
|
.value("SQUARE_CAP",SQUARE_CAP)
|
||||||
.value("ROUND_CAP",ROUND_CAP)
|
.value("ROUND_CAP",ROUND_CAP)
|
||||||
;
|
;
|
||||||
enum_<line_join_e>("line_join")
|
enum_<line_join_enum>("line_join")
|
||||||
.value("MITER_JOIN",MITER_JOIN)
|
.value("MITER_JOIN",MITER_JOIN)
|
||||||
.value("MITER_REVERT_JOIN",MITER_REVERT_JOIN)
|
.value("MITER_REVERT_JOIN",MITER_REVERT_JOIN)
|
||||||
.value("ROUND_JOIN",ROUND_JOIN)
|
.value("ROUND_JOIN",ROUND_JOIN)
|
||||||
|
|
|
@ -32,9 +32,9 @@ void export_text_symbolizer()
|
||||||
using mapnik::text_symbolizer;
|
using mapnik::text_symbolizer;
|
||||||
using mapnik::Color;
|
using mapnik::Color;
|
||||||
|
|
||||||
enum_<mapnik::label_placement_e>("label_placement")
|
enum_<mapnik::label_placement_enum>("label_placement")
|
||||||
.value("LINE_PLACEMENT",mapnik::line_placement)
|
.value("LINE_PLACEMENT",mapnik::LINE_PLACEMENT)
|
||||||
.value("POINT_PLACEMENT",mapnik::point_placement)
|
.value("POINT_PLACEMENT",mapnik::POINT_PLACEMENT)
|
||||||
;
|
;
|
||||||
|
|
||||||
class_<text_symbolizer>("TextSymbolizer",
|
class_<text_symbolizer>("TextSymbolizer",
|
||||||
|
|
|
@ -104,6 +104,11 @@ namespace mapnik {
|
||||||
return abgr_ == other.abgr_;
|
return abgr_ == other.abgr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(Color const& other) const
|
||||||
|
{
|
||||||
|
return abgr_ != other.abgr_;
|
||||||
|
}
|
||||||
|
|
||||||
inline std::string to_string() const
|
inline std::string to_string() const
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
#include <mapnik/css_color_parser.hpp>
|
#include <mapnik/css_color_parser.hpp>
|
||||||
|
#include <mapnik/config_error.hpp>
|
||||||
|
|
||||||
using namespace boost::spirit;
|
using namespace boost::spirit;
|
||||||
|
|
||||||
|
@ -40,8 +41,11 @@ namespace mapnik {
|
||||||
actions<Color> a(color);
|
actions<Color> a(color);
|
||||||
css_color_grammar<actions<Color> > grammar(a);
|
css_color_grammar<actions<Color> > grammar(a);
|
||||||
parse_info<> info = parse(css_color, grammar, space_p);
|
parse_info<> info = parse(css_color, grammar, space_p);
|
||||||
if (info.full) return color;
|
if ( ! info.full) {
|
||||||
return Color(0,0,0);
|
throw config_error(std::string("Failed to parse color value: ") +
|
||||||
|
"Expected a color, but got '" + css_color + "'");
|
||||||
|
}
|
||||||
|
return color;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
color_factory();
|
color_factory();
|
||||||
|
|
47
include/mapnik/config_error.hpp
Normal file
47
include/mapnik/config_error.hpp
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#ifndef MAPNIK_CONFIG_ERROR_INCLUDED
|
||||||
|
#define MAPNIK_CONFIG_ERROR_INCLUDED
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace mapnik {
|
||||||
|
|
||||||
|
class config_error : public std::exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
config_error() {}
|
||||||
|
|
||||||
|
config_error( const std::string & what ) :
|
||||||
|
what_( what )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual ~config_error() throw() {};
|
||||||
|
|
||||||
|
virtual const char * what() const throw()
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
os << what_;
|
||||||
|
if ( ! context_.empty() )
|
||||||
|
{
|
||||||
|
os << std::endl << context_;
|
||||||
|
}
|
||||||
|
os << ".";
|
||||||
|
return os.str().c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void append_context(const std::string & ctx) const
|
||||||
|
{
|
||||||
|
if ( ! context_.empty() )
|
||||||
|
{
|
||||||
|
context_ += " ";
|
||||||
|
}
|
||||||
|
context_ += ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string what_;
|
||||||
|
mutable std::string context_;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MAPNIK_CONFIG_ERROR_INCLUDED
|
|
@ -52,9 +52,9 @@ namespace mapnik {
|
||||||
class MAPNIK_DECL datasource_exception : public std::exception
|
class MAPNIK_DECL datasource_exception : public std::exception
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
const std::string message_;
|
std::string message_;
|
||||||
public:
|
public:
|
||||||
datasource_exception(const std::string& message=std::string())
|
datasource_exception(const std::string& message=std::string("no reason"))
|
||||||
:message_(message) {}
|
:message_(message) {}
|
||||||
|
|
||||||
~datasource_exception() throw() {}
|
~datasource_exception() throw() {}
|
||||||
|
|
291
include/mapnik/enumeration.hpp
Normal file
291
include/mapnik/enumeration.hpp
Normal file
|
@ -0,0 +1,291 @@
|
||||||
|
#ifndef MAPNIK_ENUMERATION_INCLUDED
|
||||||
|
#define MAPNIK_ENUMERATION_INCLUDED
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <bitset>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace mapnik {
|
||||||
|
|
||||||
|
class illegal_enum_value : public std::exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
illegal_enum_value() {}
|
||||||
|
|
||||||
|
illegal_enum_value( const std::string & what ) :
|
||||||
|
what_( what )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual ~illegal_enum_value() throw() {};
|
||||||
|
|
||||||
|
virtual const char * what() const throw()
|
||||||
|
{
|
||||||
|
return what_.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string what_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Slim wrapper for enumerations. It creates a new type from a native enum and
|
||||||
|
* a char pointer array. It almost exactly behaves like a native enumeration
|
||||||
|
* type. It supports string conversion through stream operators. This is usefull
|
||||||
|
* for debugging, serialization/deserialization and also helps with implementing
|
||||||
|
* language bindings. The two convinient macros DEFINE_ENUM() and IMPLEMENT_ENUM()
|
||||||
|
* are provided to help with instanciation.
|
||||||
|
*
|
||||||
|
* @par Limitations:
|
||||||
|
* - The enum must start at zero.
|
||||||
|
* - The enum must be consecutive.
|
||||||
|
* - The enum must be terminated with a special token consisting of the enum's
|
||||||
|
* name plus "_MAX".
|
||||||
|
* - The corresponding char pointer array must be terminated with an empty string.
|
||||||
|
* - The names must only consist of characters and digits (<i>a-z, A-Z, 0-9</i>),
|
||||||
|
* underscores (<i>_</i>) and dashes (<i>-</i>).
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @warning At the moment the verify() method is called during static initialization.
|
||||||
|
* It quits the application with exit code 1 if any error is detected. The other solution
|
||||||
|
* i thought of is to do the checks at compile time (using boost::mpl).
|
||||||
|
*
|
||||||
|
* @par Example:
|
||||||
|
* The following code goes into the header file:
|
||||||
|
* @code
|
||||||
|
* enum fruit_enum {
|
||||||
|
* APPLE,
|
||||||
|
* CHERRY,
|
||||||
|
* BANANA,
|
||||||
|
* PASSION_FRUIT,
|
||||||
|
* fruit_enum_MAX
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* static const char * fruit_strings[] = {
|
||||||
|
* "apple",
|
||||||
|
* "cherry",
|
||||||
|
* "banana",
|
||||||
|
* "passion_fruit",
|
||||||
|
* ""
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* DEFINE_ENUM( fruit, fruit_enum);
|
||||||
|
* @endcode
|
||||||
|
* In the corresponding cpp file do:
|
||||||
|
* @code
|
||||||
|
* IMPLEMENT_ENUM( fruit, fruit_strings );
|
||||||
|
* @endcode
|
||||||
|
* And here is how to use the resulting type Fruit
|
||||||
|
* @code
|
||||||
|
*
|
||||||
|
* int
|
||||||
|
* main(int argc, char * argv[]) {
|
||||||
|
* fruit f(APPLE);
|
||||||
|
* switch ( f ) {
|
||||||
|
* case BANANA:
|
||||||
|
* case APPLE:
|
||||||
|
* cerr << "No thanks. I hate " << f << "s" << endl;
|
||||||
|
* break;
|
||||||
|
* default:
|
||||||
|
* cerr << "Hmmm ... yummy " << f << endl;
|
||||||
|
* break;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* f = CHERRY;
|
||||||
|
*
|
||||||
|
* fruit_enum native_enum = f;
|
||||||
|
*
|
||||||
|
* f.from_string("passion_fruit");
|
||||||
|
*
|
||||||
|
* for (unsigned i = 0; i < fruit::MAX; ++i) {
|
||||||
|
* cerr << i << " = " << fruit::get_string(i) << endl;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* f.from_string("elephant"); // throws illegal_enum_value
|
||||||
|
*
|
||||||
|
* return 0;
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
template <class ENUM, int THE_MAX>
|
||||||
|
class enumeration {
|
||||||
|
public:
|
||||||
|
typedef ENUM Native;
|
||||||
|
enumeration() {};
|
||||||
|
enumeration( ENUM v ) : value_(v) {}
|
||||||
|
enumeration( const enumeration & other ) : value_(other.value_) {}
|
||||||
|
|
||||||
|
/** Assignment operator for native enum values. */
|
||||||
|
void operator=(ENUM v)
|
||||||
|
{
|
||||||
|
value_ = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Assignment operator. */
|
||||||
|
void operator=(const enumeration & other)
|
||||||
|
{
|
||||||
|
value_ = other.value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Conversion operator for native enum values. */
|
||||||
|
operator ENUM() const
|
||||||
|
{
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Max
|
||||||
|
{
|
||||||
|
MAX = THE_MAX
|
||||||
|
};
|
||||||
|
ENUM max() const
|
||||||
|
{
|
||||||
|
return THE_MAX;
|
||||||
|
}
|
||||||
|
/** Converts @p str to an enum.
|
||||||
|
* @throw illegal_enum_value @p str is not a legal identifier.
|
||||||
|
* */
|
||||||
|
void from_string(const std::string & str)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < THE_MAX; ++i)
|
||||||
|
{
|
||||||
|
if (str == our_strings_[i])
|
||||||
|
{
|
||||||
|
value_ = static_cast<ENUM>(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw illegal_enum_value(std::string("Illegal enumeration value '") +
|
||||||
|
str + "' for enum " + our_name_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Parses the input stream @p is for a word consisting of characters and
|
||||||
|
* digits (<i>a-z, A-Z, 0-9</i>) and underscores (<i>_</i>).
|
||||||
|
* The failbit of the stream is set if the word is not a valid identifier.
|
||||||
|
*/
|
||||||
|
std::istream & parse(std::istream & is)
|
||||||
|
{
|
||||||
|
std::string word;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
while ( is.peek() != std::char_traits< char >::eof())
|
||||||
|
{
|
||||||
|
is >> c;
|
||||||
|
if ( isspace(c) && word.empty() )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( isalnum(c) || (c == '_') || c == '-' )
|
||||||
|
{
|
||||||
|
word += c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
is.unget();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
from_string( word );
|
||||||
|
}
|
||||||
|
catch (const illegal_enum_value & ex)
|
||||||
|
{
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the current value as a string identifier. */
|
||||||
|
std::string as_string() const
|
||||||
|
{
|
||||||
|
return our_strings_[value_];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Prints the string identifier to the output stream @p os. */
|
||||||
|
std::ostream & print(std::ostream & os = std::cerr) const
|
||||||
|
{
|
||||||
|
return os << our_strings_[value_];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Static helper function to iterate over valid identifiers. */
|
||||||
|
static const char * get_string(unsigned i)
|
||||||
|
{
|
||||||
|
return our_strings_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Performs some simple checks and quits the application if
|
||||||
|
* any error is detected. Tries to print helpful error messages.
|
||||||
|
*/
|
||||||
|
static bool verify(const char * filename, unsigned line_no)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < THE_MAX; ++i)
|
||||||
|
{
|
||||||
|
if (our_strings_[i] == 0 )
|
||||||
|
{
|
||||||
|
std::cerr << "### FATAL: Not enough strings for enum "
|
||||||
|
<< our_name_ << " defined in file '" << filename
|
||||||
|
<< "' at line " << line_no << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( std::string("") != our_strings_[THE_MAX])
|
||||||
|
{
|
||||||
|
std::cerr << "### FATAL: The string array for enum " << our_name_
|
||||||
|
<< " defined in file '" << filename << "' at line " << line_no
|
||||||
|
<< " has too many items or is not terminated with an "
|
||||||
|
<< "empty string." << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
static const char * get_name()
|
||||||
|
{
|
||||||
|
return our_name_;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
ENUM value_;
|
||||||
|
static const char ** our_strings_ ;
|
||||||
|
static const char * our_name_ ;
|
||||||
|
static bool our_verified_flag_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** ostream operator for enumeration
|
||||||
|
* @relates mapnik::enumeration
|
||||||
|
*/
|
||||||
|
template <class ENUM, int THE_MAX>
|
||||||
|
std::ostream &
|
||||||
|
operator<<(std::ostream & os, const mapnik::enumeration<ENUM, THE_MAX> & e)
|
||||||
|
{
|
||||||
|
e.print( os );
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** istream operator for enumeration
|
||||||
|
* @relates mapnik::enumeration
|
||||||
|
*/
|
||||||
|
template <class ENUM, int THE_MAX>
|
||||||
|
std::istream &
|
||||||
|
operator>>(std::istream & is, mapnik::enumeration<ENUM, THE_MAX> & e)
|
||||||
|
{
|
||||||
|
e.parse( is );
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of namespace
|
||||||
|
|
||||||
|
/** Helper macro. Creates a typedef.
|
||||||
|
* @relates mapnik::enumeration
|
||||||
|
*/
|
||||||
|
#define DEFINE_ENUM( name, e) \
|
||||||
|
typedef mapnik::enumeration<e, e ## _MAX> name;
|
||||||
|
|
||||||
|
/** Helper macro. Runs the verify() method during static initialization.
|
||||||
|
* @relates mapnik::enumeration
|
||||||
|
*/
|
||||||
|
#define IMPLEMENT_ENUM( name, strings ) \
|
||||||
|
template <> const char ** name ::our_strings_ = strings; \
|
||||||
|
template <> const char * name ::our_name_ = #name; \
|
||||||
|
template <> bool name ::our_verified_flag_( name ::verify(__FILE__, __LINE__));
|
||||||
|
|
||||||
|
#endif // MAPNIK_ENUMERATION_INCLUDED
|
|
@ -25,6 +25,7 @@
|
||||||
#ifndef FILTER_FACTORY_HPP
|
#ifndef FILTER_FACTORY_HPP
|
||||||
#define FILTER_FACTORY_HPP
|
#define FILTER_FACTORY_HPP
|
||||||
|
|
||||||
|
#include <mapnik/config_error.hpp>
|
||||||
#include <mapnik/filter_parser.hpp>
|
#include <mapnik/filter_parser.hpp>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
|
@ -41,14 +42,23 @@ namespace mapnik
|
||||||
stack<shared_ptr<expression<FeatureT> > > exps;
|
stack<shared_ptr<expression<FeatureT> > > exps;
|
||||||
filter_grammar<FeatureT> grammar(filters,exps);
|
filter_grammar<FeatureT> grammar(filters,exps);
|
||||||
char const *text = str.c_str();
|
char const *text = str.c_str();
|
||||||
parse_info<> info = parse(text,text+strlen(text),grammar,space_p);
|
parse_info<> info = parse(text, grammar, space_p);
|
||||||
if (info.full && !filters.empty())
|
if ( ! info.full) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Failed to parse filter expression:" << std::endl
|
||||||
|
<< str << std::endl
|
||||||
|
<< "Parsing aborted at '" << info.stop << "'";
|
||||||
|
|
||||||
|
throw config_error( os.str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! filters.empty())
|
||||||
{
|
{
|
||||||
return filters.top();
|
return filters.top();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
clog << "failed at :" << info.stop << "\n";
|
// XXX: do we ever get here? [DS]
|
||||||
return filter_ptr(new none_filter<FeatureT>());
|
return filter_ptr(new none_filter<FeatureT>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
// boost
|
// boost
|
||||||
|
|
||||||
|
//#define BOOST_SPIRIT_DEBUG
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/spirit/core.hpp>
|
#include <boost/spirit/core.hpp>
|
||||||
#include <boost/spirit/symbols.hpp>
|
#include <boost/spirit/symbols.hpp>
|
||||||
|
@ -404,7 +407,7 @@ namespace mapnik
|
||||||
[compose_filter<FeatureT,mapnik::less_than<value> >(self.filters,self.exprs)]
|
[compose_filter<FeatureT,mapnik::less_than<value> >(self.filters,self.exprs)]
|
||||||
| (L"<=" >> expression)
|
| (L"<=" >> expression)
|
||||||
[compose_filter<FeatureT,less_than_or_equal<value> >(self.filters,self.exprs)]
|
[compose_filter<FeatureT,less_than_or_equal<value> >(self.filters,self.exprs)]
|
||||||
| regex );
|
/* | regex */);
|
||||||
|
|
||||||
equation = relation >> *( ( L'=' >> relation)
|
equation = relation >> *( ( L'=' >> relation)
|
||||||
[compose_filter<FeatureT,mapnik::equals<value> >(self.filters,self.exprs)]
|
[compose_filter<FeatureT,mapnik::equals<value> >(self.filters,self.exprs)]
|
||||||
|
@ -417,7 +420,26 @@ namespace mapnik
|
||||||
|
|
||||||
or_expr = and_expr >> *(L"or" >> and_expr)[compose_or_filter<FeatureT>(self.filters)];
|
or_expr = and_expr >> *(L"or" >> and_expr)[compose_or_filter<FeatureT>(self.filters)];
|
||||||
|
|
||||||
filter_statement = or_expr;
|
filter_statement = or_expr >> *(space_p) >> end_p;
|
||||||
|
|
||||||
|
#ifdef BOOST_SPIRIT_DEBUG
|
||||||
|
BOOST_SPIRIT_DEBUG_RULE( factor );
|
||||||
|
BOOST_SPIRIT_DEBUG_RULE( term );
|
||||||
|
BOOST_SPIRIT_DEBUG_RULE( expression );
|
||||||
|
BOOST_SPIRIT_DEBUG_RULE( relation );
|
||||||
|
BOOST_SPIRIT_DEBUG_RULE( equation );
|
||||||
|
BOOST_SPIRIT_DEBUG_RULE( not_expr );
|
||||||
|
BOOST_SPIRIT_DEBUG_RULE( and_expr );
|
||||||
|
BOOST_SPIRIT_DEBUG_RULE( or_expr );
|
||||||
|
|
||||||
|
BOOST_SPIRIT_DEBUG_RULE( filter_statement );
|
||||||
|
BOOST_SPIRIT_DEBUG_RULE( literal );
|
||||||
|
BOOST_SPIRIT_DEBUG_RULE( number );
|
||||||
|
BOOST_SPIRIT_DEBUG_RULE( string_ );
|
||||||
|
BOOST_SPIRIT_DEBUG_RULE( property );
|
||||||
|
BOOST_SPIRIT_DEBUG_RULE( function );
|
||||||
|
BOOST_SPIRIT_DEBUG_RULE( regex );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::spirit::rule<ScannerT> const& start() const
|
boost::spirit::rule<ScannerT> const& start() const
|
||||||
|
@ -444,6 +466,8 @@ namespace mapnik
|
||||||
symbols<string> func1_op;
|
symbols<string> func1_op;
|
||||||
symbols<string> func2_op;
|
symbols<string> func2_op;
|
||||||
symbols<string> spatial_op;
|
symbols<string> spatial_op;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
stack<shared_ptr<filter<FeatureT> > >& filters;
|
stack<shared_ptr<filter<FeatureT> > >& filters;
|
||||||
stack<shared_ptr<expression<FeatureT> > >& exprs;
|
stack<shared_ptr<expression<FeatureT> > >& exprs;
|
||||||
|
|
9
include/mapnik/libxml2_loader.hpp
Normal file
9
include/mapnik/libxml2_loader.hpp
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef LOAD_MAP_XML2_INCLUDED
|
||||||
|
#define LOAD_MAP_XML2_INCLUDED
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
void read_xml2( std::string const & filename, boost::property_tree::ptree & pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // LOAD_MAP_XML2_INCLUDED
|
|
@ -26,19 +26,17 @@
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <mapnik/graphics.hpp>
|
#include <mapnik/graphics.hpp>
|
||||||
|
#include <mapnik/symbolizer.hpp>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
struct MAPNIK_DECL line_pattern_symbolizer
|
struct MAPNIK_DECL line_pattern_symbolizer :
|
||||||
|
public symbolizer_with_image
|
||||||
{
|
{
|
||||||
line_pattern_symbolizer(std::string const& file,
|
line_pattern_symbolizer(std::string const& file,
|
||||||
std::string const& type,
|
std::string const& type,
|
||||||
unsigned width,unsigned height);
|
unsigned width,unsigned height);
|
||||||
|
|
||||||
line_pattern_symbolizer(line_pattern_symbolizer const& rhs);
|
line_pattern_symbolizer(line_pattern_symbolizer const& rhs);
|
||||||
ImageData32 const& get_pattern() const;
|
|
||||||
private:
|
|
||||||
boost::shared_ptr<ImageData32> pattern_;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
MAPNIK_DECL void load_map(Map & map, std::string const& filename);
|
MAPNIK_DECL void load_map(Map & map, std::string const& filename, bool strict = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // LOAD_MAP_HPP
|
#endif // LOAD_MAP_HPP
|
||||||
|
|
|
@ -26,23 +26,22 @@
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <mapnik/graphics.hpp>
|
#include <mapnik/graphics.hpp>
|
||||||
|
#include <mapnik/symbolizer.hpp>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
struct MAPNIK_DECL point_symbolizer
|
struct MAPNIK_DECL point_symbolizer :
|
||||||
|
public symbolizer_with_image
|
||||||
{
|
{
|
||||||
explicit point_symbolizer();
|
explicit point_symbolizer();
|
||||||
point_symbolizer(std::string const& file,
|
point_symbolizer(std::string const& file,
|
||||||
std::string const& type,
|
std::string const& type,
|
||||||
unsigned width,unsigned height);
|
unsigned width,unsigned height);
|
||||||
point_symbolizer(point_symbolizer const& rhs);
|
point_symbolizer(point_symbolizer const& rhs);
|
||||||
void set_data (boost::shared_ptr<ImageData32> symbol);
|
|
||||||
boost::shared_ptr<ImageData32> const& get_data() const;
|
|
||||||
void set_allow_overlap(bool overlap);
|
void set_allow_overlap(bool overlap);
|
||||||
bool get_allow_overlap() const;
|
bool get_allow_overlap() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::shared_ptr<ImageData32> symbol_;
|
|
||||||
bool overlap_;
|
bool overlap_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,12 @@
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <mapnik/graphics.hpp>
|
#include <mapnik/graphics.hpp>
|
||||||
|
#include <mapnik/symbolizer.hpp>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
struct MAPNIK_DECL polygon_pattern_symbolizer
|
struct MAPNIK_DECL polygon_pattern_symbolizer :
|
||||||
|
public symbolizer_with_image
|
||||||
{
|
{
|
||||||
|
|
||||||
polygon_pattern_symbolizer(std::string const& file,
|
polygon_pattern_symbolizer(std::string const& file,
|
||||||
|
@ -37,10 +39,6 @@ namespace mapnik
|
||||||
unsigned width,unsigned height);
|
unsigned width,unsigned height);
|
||||||
|
|
||||||
polygon_pattern_symbolizer(polygon_pattern_symbolizer const& rhs);
|
polygon_pattern_symbolizer(polygon_pattern_symbolizer const& rhs);
|
||||||
|
|
||||||
ImageData32 const& get_pattern() const;
|
|
||||||
private:
|
|
||||||
boost::shared_ptr<ImageData32> pattern_;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
338
include/mapnik/ptree_helpers.hpp
Normal file
338
include/mapnik/ptree_helpers.hpp
Normal file
|
@ -0,0 +1,338 @@
|
||||||
|
#ifndef MAPNIK_CONFIG_HELPERS_INCLUDED
|
||||||
|
#define MAPNIK_CONFIG_HELPERS_INCLUDED
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <boost/property_tree/ptree.hpp>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
#include <mapnik/enumeration.hpp>
|
||||||
|
#include <mapnik/config_error.hpp>
|
||||||
|
#include <mapnik/color_factory.hpp>
|
||||||
|
|
||||||
|
namespace mapnik {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T get(const boost::property_tree::ptree & node, const std::string & name, bool is_attribute,
|
||||||
|
const T & default_value);
|
||||||
|
template <typename T>
|
||||||
|
T get(const boost::property_tree::ptree & node, const std::string & name, bool is_attribute);
|
||||||
|
template <typename T>
|
||||||
|
T get_own(const boost::property_tree::ptree & node, const std::string & name);
|
||||||
|
template <typename T>
|
||||||
|
boost::optional<T> get_optional(const boost::property_tree::ptree & node, const std::string & name,
|
||||||
|
bool is_attribute);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
boost::optional<T> get_opt_attr( const boost::property_tree::ptree & node,
|
||||||
|
const std::string & name)
|
||||||
|
{
|
||||||
|
return get_optional<T>( node, name, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
boost::optional<T> get_opt_child( const boost::property_tree::ptree & node,
|
||||||
|
const std::string & name)
|
||||||
|
{
|
||||||
|
return get_optional<T>( node, name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T get_attr( const boost::property_tree::ptree & node, const std::string & name,
|
||||||
|
const T & default_value )
|
||||||
|
{
|
||||||
|
return get<T>( node, name, true, default_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T get_attr( const boost::property_tree::ptree & node, const std::string & name )
|
||||||
|
{
|
||||||
|
return get<T>( node, name, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T get_css( const boost::property_tree::ptree & node, const std::string & name )
|
||||||
|
{
|
||||||
|
return get_own<T>( node, std::string("CSS parameter '") + name + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Stream input operator for Color values */
|
||||||
|
template <typename charT, typename traits>
|
||||||
|
std::basic_istream<charT, traits> &
|
||||||
|
operator >> ( std::basic_istream<charT, traits> & s, mapnik::Color & c )
|
||||||
|
{
|
||||||
|
std::string word;
|
||||||
|
s >> word;
|
||||||
|
if ( s )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
c = mapnik::color_factory::from_string( word.c_str() );
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
s.setstate( std::ios::failbit );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename charT, typename traits>
|
||||||
|
std::basic_ostream<charT, traits> &
|
||||||
|
operator << ( std::basic_ostream<charT, traits> & s, const mapnik::Color & c )
|
||||||
|
{
|
||||||
|
std::string hex_string( c.to_hex_string() );
|
||||||
|
s << hex_string;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Helper for class bool */
|
||||||
|
class boolean {
|
||||||
|
public:
|
||||||
|
boolean() {}
|
||||||
|
boolean(bool b) : b_(b) {}
|
||||||
|
boolean(const boolean & b) : b_(b.b_) {}
|
||||||
|
|
||||||
|
operator bool() const
|
||||||
|
{
|
||||||
|
return b_;
|
||||||
|
}
|
||||||
|
boolean & operator = (const boolean & other)
|
||||||
|
{
|
||||||
|
b_ = other.b_;
|
||||||
|
return * this;
|
||||||
|
}
|
||||||
|
boolean & operator = (bool other)
|
||||||
|
{
|
||||||
|
b_ = other;
|
||||||
|
return * this;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
bool b_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Special stream input operator for boolean values */
|
||||||
|
template <typename charT, typename traits>
|
||||||
|
std::basic_istream<charT, traits> &
|
||||||
|
operator >> ( std::basic_istream<charT, traits> & s, boolean & b )
|
||||||
|
{
|
||||||
|
std::string word;
|
||||||
|
s >> word;
|
||||||
|
if ( s )
|
||||||
|
{
|
||||||
|
if ( word == "true" || word == "yes" || word == "on" ||
|
||||||
|
word == "1")
|
||||||
|
{
|
||||||
|
b = true;
|
||||||
|
}
|
||||||
|
else if ( word == "false" || word == "no" || word == "off" ||
|
||||||
|
word == "0")
|
||||||
|
{
|
||||||
|
b = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s.setstate( std::ios::failbit );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename charT, typename traits>
|
||||||
|
std::basic_ostream<charT, traits> &
|
||||||
|
operator << ( std::basic_ostream<charT, traits> & s, const boolean & b )
|
||||||
|
{
|
||||||
|
s << ( b ? "true" : "false" );
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void set_attr(boost::property_tree::ptree & pt, const std::string & name, const T & v)
|
||||||
|
{
|
||||||
|
pt.put("<xmlattr>." + name, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
template <>
|
||||||
|
void set_attr<bool>(boost::property_tree::ptree & pt, const std::string & name, const bool & v)
|
||||||
|
{
|
||||||
|
pt.put("<xmlattr>." + name, boolean(v));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
class boolean;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void set_css(boost::property_tree::ptree & pt, const std::string & name, const T & v)
|
||||||
|
{
|
||||||
|
boost::property_tree::ptree & css_node = pt.push_back(
|
||||||
|
boost::property_tree::ptree::value_type("CssParameter",
|
||||||
|
boost::property_tree::ptree()))->second;
|
||||||
|
css_node.put("<xmlattr>.name", name );
|
||||||
|
css_node.put_own( v );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct name_trait
|
||||||
|
{
|
||||||
|
static const char * name()
|
||||||
|
{
|
||||||
|
return "<unknown>";
|
||||||
|
}
|
||||||
|
// missing name_trait for type ...
|
||||||
|
// if you get here you are probably using a new type
|
||||||
|
// in the XML file. Just add a name trait for the new
|
||||||
|
// type below.
|
||||||
|
BOOST_STATIC_ASSERT( sizeof(T) == 0 );
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEFINE_NAME_TRAIT_WITH_NAME( type, type_name ) \
|
||||||
|
template <> \
|
||||||
|
struct name_trait<type> \
|
||||||
|
{ \
|
||||||
|
static const char * name() { return "type " type_name; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEFINE_NAME_TRAIT( type ) \
|
||||||
|
DEFINE_NAME_TRAIT_WITH_NAME( type, #type );
|
||||||
|
|
||||||
|
DEFINE_NAME_TRAIT( double );
|
||||||
|
DEFINE_NAME_TRAIT( float );
|
||||||
|
DEFINE_NAME_TRAIT( unsigned );
|
||||||
|
DEFINE_NAME_TRAIT( boolean );
|
||||||
|
DEFINE_NAME_TRAIT_WITH_NAME( int, "integer" );
|
||||||
|
DEFINE_NAME_TRAIT_WITH_NAME( std::string, "string" );
|
||||||
|
DEFINE_NAME_TRAIT_WITH_NAME( Color, "color" );
|
||||||
|
|
||||||
|
template <typename ENUM, int MAX>
|
||||||
|
struct name_trait< enumeration<ENUM, MAX> >
|
||||||
|
{
|
||||||
|
typedef enumeration<ENUM, MAX> Enum;
|
||||||
|
|
||||||
|
static const char * name()
|
||||||
|
{
|
||||||
|
std::string value_list("one of [");
|
||||||
|
for (unsigned i = 0; i < Enum::MAX; ++i)
|
||||||
|
{
|
||||||
|
value_list += Enum::get_string( i );
|
||||||
|
if ( i + 1 < Enum::MAX ) value_list += ", ";
|
||||||
|
}
|
||||||
|
value_list += "]";
|
||||||
|
|
||||||
|
return value_list.c_str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T get(const boost::property_tree::ptree & node, const std::string & name, bool is_attribute,
|
||||||
|
const T & default_value)
|
||||||
|
{
|
||||||
|
boost::optional<std::string> str;
|
||||||
|
if (is_attribute)
|
||||||
|
{
|
||||||
|
str = node.get_optional<std::string>( std::string("<xmlattr>.") + name );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str = node.get_optional<std::string>(name );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( str ) {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return boost::lexical_cast<T>( * str );
|
||||||
|
}
|
||||||
|
catch (const boost::bad_lexical_cast & ex)
|
||||||
|
{
|
||||||
|
throw config_error(string("Failed to parse ") +
|
||||||
|
(is_attribute ? "attribute" : "child node") + " '" +
|
||||||
|
name + "'. Expected " + name_trait<T>::name() +
|
||||||
|
" but got '" + *str + "'");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return default_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T get(const boost::property_tree::ptree & node, const std::string & name, bool is_attribute)
|
||||||
|
{
|
||||||
|
boost::optional<std::string> str;
|
||||||
|
if (is_attribute)
|
||||||
|
{
|
||||||
|
str = node.get_optional<std::string>( std::string("<xmlattr>.") + name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str = node.get_optional<std::string>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! str ) {
|
||||||
|
throw config_error(string("Required ") +
|
||||||
|
(is_attribute ? "attribute " : "child node ") +
|
||||||
|
"'" + name + "' is missing");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return boost::lexical_cast<T>( *str );
|
||||||
|
}
|
||||||
|
catch (const boost::bad_lexical_cast & ex)
|
||||||
|
{
|
||||||
|
throw config_error(string("Failed to parse ") +
|
||||||
|
(is_attribute ? "attribute" : "child node") + " '" +
|
||||||
|
name + "'. Expected " + name_trait<T>::name() +
|
||||||
|
" but got '" + *str + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T get_own(const boost::property_tree::ptree & node, const std::string & name)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return node.get_own<T>();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
throw config_error(string("Failed to parse ") +
|
||||||
|
name + ". Expected " + name_trait<T>::name() +
|
||||||
|
" but got '" + node.data() + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
boost::optional<T> get_optional(const boost::property_tree::ptree & node, const std::string & name,
|
||||||
|
bool is_attribute)
|
||||||
|
{
|
||||||
|
boost::optional<std::string> str;
|
||||||
|
if (is_attribute)
|
||||||
|
{
|
||||||
|
str = node.get_optional<std::string>( std::string("<xmlattr>.") + name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str = node.get_optional<std::string>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<T> result;
|
||||||
|
if ( str ) {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = boost::lexical_cast<T>( *str );
|
||||||
|
}
|
||||||
|
catch (const boost::bad_lexical_cast & ex)
|
||||||
|
{
|
||||||
|
throw config_error(string("Failed to parse ") +
|
||||||
|
(is_attribute ? "attribute" : "child node") + " '" +
|
||||||
|
name + "'. Expected " + name_trait<T>::name() +
|
||||||
|
" but got '" + *str + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} // end of namespace mapnik
|
||||||
|
|
||||||
|
#endif // MAPNIK_CONFIG_HELPERS_INCLUDED
|
|
@ -25,13 +25,16 @@
|
||||||
#ifndef SHIELD_SYMBOLIZER_HPP
|
#ifndef SHIELD_SYMBOLIZER_HPP
|
||||||
#define SHIELD_SYMBOLIZER_HPP
|
#define SHIELD_SYMBOLIZER_HPP
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
#include <mapnik/graphics.hpp>
|
#include <mapnik/graphics.hpp>
|
||||||
#include <mapnik/text_symbolizer.hpp>
|
#include <mapnik/text_symbolizer.hpp>
|
||||||
|
#include <mapnik/symbolizer.hpp>
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
struct MAPNIK_DECL shield_symbolizer : public text_symbolizer
|
struct MAPNIK_DECL shield_symbolizer : public text_symbolizer,
|
||||||
|
public symbolizer_with_image
|
||||||
{
|
{
|
||||||
shield_symbolizer(std::string const& name,
|
shield_symbolizer(std::string const& name,
|
||||||
std::string const& face_name,
|
std::string const& face_name,
|
||||||
|
@ -41,13 +44,6 @@ namespace mapnik
|
||||||
std::string const& type,
|
std::string const& type,
|
||||||
unsigned width,unsigned height);
|
unsigned width,unsigned height);
|
||||||
|
|
||||||
|
|
||||||
void set_background_image(boost::shared_ptr<ImageData32>);
|
|
||||||
boost::shared_ptr<ImageData32> const& get_background_image() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
boost::shared_ptr<ImageData32> background_image_;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/color.hpp>
|
#include <mapnik/color.hpp>
|
||||||
|
#include <mapnik/enumeration.hpp>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
@ -34,21 +35,31 @@ namespace mapnik
|
||||||
using std::vector;
|
using std::vector;
|
||||||
typedef vector<pair<float,float> > dash_array;
|
typedef vector<pair<float,float> > dash_array;
|
||||||
|
|
||||||
enum line_cap_e
|
// if you add new tokens, don't forget to add them to the corresponding
|
||||||
|
// string array in the cpp file too.
|
||||||
|
enum line_cap_enum
|
||||||
{
|
{
|
||||||
BUTT_CAP,
|
BUTT_CAP,
|
||||||
SQUARE_CAP,
|
SQUARE_CAP,
|
||||||
ROUND_CAP
|
ROUND_CAP,
|
||||||
|
line_cap_enum_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
enum line_join_e
|
DEFINE_ENUM( line_cap_e, line_cap_enum );
|
||||||
|
|
||||||
|
// if you add new tokens, don't forget to add them to the corresponding
|
||||||
|
// string array in the cpp file too.
|
||||||
|
enum line_join_enum
|
||||||
{
|
{
|
||||||
MITER_JOIN,
|
MITER_JOIN,
|
||||||
MITER_REVERT_JOIN,
|
MITER_REVERT_JOIN,
|
||||||
ROUND_JOIN,
|
ROUND_JOIN,
|
||||||
BEVEL_JOIN
|
BEVEL_JOIN,
|
||||||
|
line_join_enum_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DEFINE_ENUM( line_join_e, line_join_enum );
|
||||||
|
|
||||||
class stroke
|
class stroke
|
||||||
{
|
{
|
||||||
Color c_;
|
Color c_;
|
||||||
|
@ -58,112 +69,34 @@ namespace mapnik
|
||||||
line_join_e line_join_;
|
line_join_e line_join_;
|
||||||
dash_array dash_;
|
dash_array dash_;
|
||||||
public:
|
public:
|
||||||
explicit stroke()
|
explicit stroke();
|
||||||
: c_(0,0,0),
|
stroke(Color const& c, float width=1.0);
|
||||||
width_(1.0),
|
stroke(stroke const& other);
|
||||||
opacity_(1.0),
|
stroke& operator=(const stroke& rhs);
|
||||||
line_cap_(BUTT_CAP),
|
|
||||||
line_join_(MITER_JOIN),
|
|
||||||
dash_() {}
|
|
||||||
|
|
||||||
stroke(Color const& c, float width=1.0)
|
void set_color(const Color& c);
|
||||||
: c_(c),
|
|
||||||
width_(width),
|
|
||||||
opacity_(1.0),
|
|
||||||
line_cap_(BUTT_CAP),
|
|
||||||
line_join_(MITER_JOIN),
|
|
||||||
dash_() {}
|
|
||||||
|
|
||||||
stroke(stroke const& other)
|
Color const& get_color() const;
|
||||||
: c_(other.c_),
|
|
||||||
width_(other.width_),
|
|
||||||
opacity_(other.opacity_),
|
|
||||||
line_cap_(other.line_cap_),
|
|
||||||
line_join_(other.line_join_),
|
|
||||||
dash_(other.dash_) {}
|
|
||||||
|
|
||||||
stroke& operator=(const stroke& rhs)
|
float get_width() const;
|
||||||
{
|
void set_width(float w);
|
||||||
stroke tmp(rhs);
|
void set_opacity(float opacity);
|
||||||
swap(tmp);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_color(const Color& c)
|
float get_opacity() const;
|
||||||
{
|
|
||||||
c_=c;
|
|
||||||
}
|
|
||||||
|
|
||||||
Color const& get_color() const
|
void set_line_cap(line_cap_e line_cap);
|
||||||
{
|
line_cap_e get_line_cap() const;
|
||||||
return c_;
|
|
||||||
}
|
|
||||||
|
|
||||||
float get_width() const
|
void set_line_join(line_join_e line_join);
|
||||||
{
|
line_join_e get_line_join() const;
|
||||||
return width_;
|
|
||||||
}
|
|
||||||
void set_width(float w)
|
|
||||||
{
|
|
||||||
width_=w;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_opacity(float opacity)
|
void add_dash(float dash,float gap);
|
||||||
{
|
bool has_dash() const;
|
||||||
if (opacity > 1.0) opacity_=1.0;
|
|
||||||
else if (opacity < 0.0) opacity_=0.0;
|
|
||||||
else opacity_=opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
float get_opacity() const
|
dash_array const& get_dash_array() const;
|
||||||
{
|
|
||||||
return opacity_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_line_cap(line_cap_e line_cap)
|
|
||||||
{
|
|
||||||
line_cap_=line_cap;
|
|
||||||
}
|
|
||||||
|
|
||||||
line_cap_e get_line_cap() const
|
|
||||||
{
|
|
||||||
return line_cap_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_line_join(line_join_e line_join)
|
|
||||||
{
|
|
||||||
line_join_=line_join;
|
|
||||||
}
|
|
||||||
|
|
||||||
line_join_e get_line_join() const
|
|
||||||
{
|
|
||||||
return line_join_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_dash(float dash,float gap)
|
|
||||||
{
|
|
||||||
dash_.push_back(std::make_pair(dash,gap));
|
|
||||||
}
|
|
||||||
bool has_dash() const
|
|
||||||
{
|
|
||||||
return dash_.size()>0 ? true : false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
dash_array const& get_dash_array() const
|
|
||||||
{
|
|
||||||
return dash_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void swap(const stroke& other) throw()
|
void swap(const stroke& other) throw();
|
||||||
{
|
|
||||||
c_=other.c_;
|
|
||||||
width_=other.width_;
|
|
||||||
opacity_=other.opacity_;
|
|
||||||
line_cap_=other.line_cap_;
|
|
||||||
line_join_=other.line_join_;
|
|
||||||
dash_ = other.dash_;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,31 @@
|
||||||
#ifndef SYMBOLIZER_HPP
|
#ifndef SYMBOLIZER_HPP
|
||||||
#define SYMBOLIZER_HPP
|
#define SYMBOLIZER_HPP
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <mapnik/graphics.hpp>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class symbolizer_with_image {
|
||||||
|
public:
|
||||||
|
boost::shared_ptr<ImageData32> get_image() const;
|
||||||
|
const std::string & get_filename() const;
|
||||||
|
void set_image( boost::shared_ptr<ImageData32> symbol);
|
||||||
|
|
||||||
|
virtual ~symbolizer_with_image() {};
|
||||||
|
protected:
|
||||||
|
symbolizer_with_image(boost::shared_ptr<ImageData32> img);
|
||||||
|
symbolizer_with_image(std::string const& file,
|
||||||
|
std::string const& type,
|
||||||
|
unsigned width,unsigned height);
|
||||||
|
|
||||||
|
symbolizer_with_image(symbolizer_with_image const& rhs);
|
||||||
|
|
||||||
|
boost::shared_ptr<ImageData32> image_;
|
||||||
|
std::string image_filename_;
|
||||||
|
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //SYMBOLIZER_HPP
|
#endif //SYMBOLIZER_HPP
|
||||||
|
|
|
@ -30,22 +30,25 @@
|
||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/tuple/tuple.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
// mapnik
|
// mapnik
|
||||||
|
#include <mapnik/enumeration.hpp>
|
||||||
#include <mapnik/color.hpp>
|
#include <mapnik/color.hpp>
|
||||||
#include <mapnik/graphics.hpp>
|
#include <mapnik/graphics.hpp>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
enum label_placement_e {
|
enum label_placement_enum {
|
||||||
point_placement=1,
|
POINT_PLACEMENT,
|
||||||
line_placement=2
|
LINE_PLACEMENT,
|
||||||
|
label_placement_enum_MAX
|
||||||
};
|
};
|
||||||
|
DEFINE_ENUM( label_placement_e, label_placement_enum );
|
||||||
|
|
||||||
typedef boost::tuple<double,double> position;
|
typedef boost::tuple<double,double> position;
|
||||||
|
|
||||||
struct MAPNIK_DECL text_symbolizer
|
struct MAPNIK_DECL text_symbolizer
|
||||||
{
|
{
|
||||||
text_symbolizer(std::string const& name,std::string const& face_name,
|
text_symbolizer(std::string const& name,std::string const& face_name,
|
||||||
unsigned size,Color const& fill);
|
unsigned size, Color const& fill);
|
||||||
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);
|
||||||
std::string const& get_name() const;
|
std::string const& get_name() const;
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#ifndef CONNECTION_HPP
|
#ifndef CONNECTION_HPP
|
||||||
#define CONNECTION_HPP
|
#define CONNECTION_HPP
|
||||||
|
|
||||||
|
#include <mapnik/datasource.hpp>
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "libpq-fe.h"
|
#include "libpq-fe.h"
|
||||||
|
@ -41,10 +43,18 @@ class Connection
|
||||||
Connection(std::string const& connection_str)
|
Connection(std::string const& connection_str)
|
||||||
{
|
{
|
||||||
conn_=PQconnectdb(connection_str.c_str());
|
conn_=PQconnectdb(connection_str.c_str());
|
||||||
if (PQstatus(conn_) == CONNECTION_BAD)
|
if (PQstatus(conn_) != CONNECTION_OK)
|
||||||
{
|
{
|
||||||
std::clog << "connection ["<< connection_str<< "] failed\n"
|
std::string s("PSQL error");
|
||||||
<< PQerrorMessage(conn_)<< std::endl;
|
if (conn_ )
|
||||||
|
{
|
||||||
|
std::string msg = PQerrorMessage( conn_ );
|
||||||
|
if ( ! msg.empty() )
|
||||||
|
{
|
||||||
|
s += ":\n" + msg.substr( 0, msg.size() - 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw mapnik::datasource_exception( s );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ public:
|
||||||
|
|
||||||
T* operator()() const
|
T* operator()() const
|
||||||
{
|
{
|
||||||
return new T(connection_string());
|
return new T(connection_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string id() const
|
inline std::string id() const
|
||||||
|
|
|
@ -46,8 +46,8 @@ source = Split(
|
||||||
image_util.cpp
|
image_util.cpp
|
||||||
layer.cpp
|
layer.cpp
|
||||||
line_pattern_symbolizer.cpp
|
line_pattern_symbolizer.cpp
|
||||||
load_map.cpp
|
|
||||||
map.cpp
|
map.cpp
|
||||||
|
load_map.cpp
|
||||||
memory.cpp
|
memory.cpp
|
||||||
params.cpp
|
params.cpp
|
||||||
placement_finder.cpp
|
placement_finder.cpp
|
||||||
|
@ -65,15 +65,25 @@ source = Split(
|
||||||
distance.cpp
|
distance.cpp
|
||||||
scale_denominator.cpp
|
scale_denominator.cpp
|
||||||
memory_datasource.cpp
|
memory_datasource.cpp
|
||||||
|
stroke.cpp
|
||||||
|
symbolizer.cpp
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
source += Split(
|
|
||||||
"""
|
if env['XMLPARSER'] == 'tinyxml':
|
||||||
../tinyxml/tinystr.cpp
|
source += Split(
|
||||||
../tinyxml/tinyxml.cpp
|
"""
|
||||||
../tinyxml/tinyxmlerror.cpp
|
../tinyxml/tinystr.cpp
|
||||||
../tinyxml/tinyxmlparser.cpp
|
../tinyxml/tinyxml.cpp
|
||||||
""")
|
../tinyxml/tinyxmlerror.cpp
|
||||||
|
../tinyxml/tinyxmlparser.cpp
|
||||||
|
""")
|
||||||
|
elif env['XMLPARSER'] == 'libxml2':
|
||||||
|
source += Split(
|
||||||
|
"""
|
||||||
|
libxml2_loader.cpp
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
mapnik = env.SharedLibrary('mapnik', source, LIBS=libraries, LINKFLAGS=linkflags)
|
mapnik = env.SharedLibrary('mapnik', source, LIBS=libraries, LINKFLAGS=linkflags)
|
||||||
|
|
||||||
|
|
|
@ -218,7 +218,8 @@ namespace mapnik
|
||||||
|
|
||||||
boost::scoped_ptr<geometry2d> roof(new polygon_impl);
|
boost::scoped_ptr<geometry2d> roof(new polygon_impl);
|
||||||
std::deque<segment_t> face_segments;
|
std::deque<segment_t> face_segments;
|
||||||
double x0,y0;
|
double x0(0);
|
||||||
|
double y0(0);
|
||||||
for (unsigned j=0;j<geom.num_points();++j)
|
for (unsigned j=0;j<geom.num_points();++j)
|
||||||
{
|
{
|
||||||
double x,y;
|
double x,y;
|
||||||
|
@ -397,7 +398,7 @@ namespace mapnik
|
||||||
double x;
|
double x;
|
||||||
double y;
|
double y;
|
||||||
double z=0;
|
double z=0;
|
||||||
boost::shared_ptr<ImageData32> const& data = sym.get_data();
|
boost::shared_ptr<ImageData32> const& data = sym.get_image();
|
||||||
if ( data )
|
if ( data )
|
||||||
{
|
{
|
||||||
for (unsigned i=0;i<feature.num_geometries();++i)
|
for (unsigned i=0;i<feature.num_geometries();++i)
|
||||||
|
@ -431,7 +432,7 @@ namespace mapnik
|
||||||
proj_transform const& prj_trans)
|
proj_transform const& prj_trans)
|
||||||
{
|
{
|
||||||
std::wstring text = feature[sym.get_name()].to_unicode();
|
std::wstring text = feature[sym.get_name()].to_unicode();
|
||||||
boost::shared_ptr<ImageData32> const& data = sym.get_background_image();
|
boost::shared_ptr<ImageData32> const& data = sym.get_image();
|
||||||
if (text.length() > 0 && data)
|
if (text.length() > 0 && data)
|
||||||
{
|
{
|
||||||
face_ptr face = font_manager_.get_face(sym.get_face_name());
|
face_ptr face = font_manager_.get_face(sym.get_face_name());
|
||||||
|
@ -487,7 +488,7 @@ namespace mapnik
|
||||||
typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type;
|
typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type;
|
||||||
typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
|
typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
|
||||||
|
|
||||||
ImageData32 const& pat = sym.get_pattern();
|
ImageData32 pat = * sym.get_image();
|
||||||
renderer_base ren_base(pixf_);
|
renderer_base ren_base(pixf_);
|
||||||
agg::pattern_filter_bilinear_rgba8 filter;
|
agg::pattern_filter_bilinear_rgba8 filter;
|
||||||
pattern_source source(pat);
|
pattern_source source(pat);
|
||||||
|
@ -532,7 +533,7 @@ namespace mapnik
|
||||||
ren_base renb(pixf_);
|
ren_base renb(pixf_);
|
||||||
agg::scanline_u8 sl;
|
agg::scanline_u8 sl;
|
||||||
|
|
||||||
ImageData32 const& pattern = sym.get_pattern();
|
ImageData32 const& pattern = * sym.get_image();
|
||||||
unsigned w=pattern.width();
|
unsigned w=pattern.width();
|
||||||
unsigned h=pattern.height();
|
unsigned h=pattern.height();
|
||||||
agg::row_accessor<agg::int8u> pattern_rbuf((agg::int8u*)pattern.getBytes(),w,h,w*4);
|
agg::row_accessor<agg::int8u> pattern_rbuf((agg::int8u*)pattern.getBytes(),w,h,w*4);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/datasource_cache.hpp>
|
#include <mapnik/datasource_cache.hpp>
|
||||||
|
#include <mapnik/config_error.hpp>
|
||||||
// ltdl
|
// ltdl
|
||||||
#include <ltdl.h>
|
#include <ltdl.h>
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ namespace mapnik
|
||||||
|
|
||||||
datasource_cache::datasource_cache()
|
datasource_cache::datasource_cache()
|
||||||
{
|
{
|
||||||
if (lt_dlinit()) throw;
|
if (lt_dlinit()) throw std::runtime_error("lt_dlinit() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource_cache::~datasource_cache()
|
datasource_cache::~datasource_cache()
|
||||||
|
@ -59,47 +60,41 @@ namespace mapnik
|
||||||
|
|
||||||
datasource_ptr datasource_cache::create(const parameters& params)
|
datasource_ptr datasource_cache::create(const parameters& params)
|
||||||
{
|
{
|
||||||
datasource_ptr ds;
|
boost::optional<std::string> type = params.get<std::string>("type");
|
||||||
try
|
if ( ! type)
|
||||||
{
|
{
|
||||||
boost::optional<std::string> type = params.get<std::string>("type");
|
throw config_error(string("Could not create datasource. Required ") +
|
||||||
if (type)
|
"parameter 'type' is missing");
|
||||||
{
|
}
|
||||||
map<string,boost::shared_ptr<PluginInfo> >::iterator itr=plugins_.find(*type);
|
|
||||||
if (itr!=plugins_.end())
|
datasource_ptr ds;
|
||||||
{
|
map<string,boost::shared_ptr<PluginInfo> >::iterator itr=plugins_.find(*type);
|
||||||
if (itr->second->handle())
|
if ( itr == plugins_.end() )
|
||||||
{
|
{
|
||||||
create_ds* create_datasource =
|
throw config_error(string("Could not create datasource. No plugin ") +
|
||||||
(create_ds*) lt_dlsym(itr->second->handle(), "create");
|
"found for type '" + * type + "'");
|
||||||
if (!create_datasource)
|
}
|
||||||
{
|
if ( ! itr->second->handle())
|
||||||
std::clog << "Cannot load symbols: " << lt_dlerror() << std::endl;
|
{
|
||||||
}
|
throw std::runtime_error(string("Cannot load library: ") +
|
||||||
else
|
lt_dlerror());
|
||||||
{
|
}
|
||||||
ds=datasource_ptr(create_datasource(params), datasource_deleter());
|
|
||||||
}
|
create_ds* create_datasource =
|
||||||
}
|
(create_ds*) lt_dlsym(itr->second->handle(), "create");
|
||||||
else
|
|
||||||
{
|
if ( ! create_datasource)
|
||||||
std::clog << "Cannot load library: " << lt_dlerror() << std::endl;
|
{
|
||||||
}
|
throw std::runtime_error(string("Cannot load symbols: ") +
|
||||||
}
|
lt_dlerror());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ds=datasource_ptr(create_datasource(params), datasource_deleter());
|
||||||
|
|
||||||
#ifdef MAPNIK_DEBUG
|
#ifdef MAPNIK_DEBUG
|
||||||
std::clog<<"datasource="<<ds<<" type="<<type<<std::endl;
|
std::clog<<"datasource="<<ds<<" type="<<type<<std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
return ds;
|
||||||
catch (datasource_exception& ex)
|
|
||||||
{
|
|
||||||
std::clog << ex.what() << "\n";
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
std::clog << " exception caught\n";
|
|
||||||
}
|
|
||||||
return ds;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool datasource_cache::insert(const std::string& type,const lt_dlhandle module)
|
bool datasource_cache::insert(const std::string& type,const lt_dlhandle module)
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
|
|
||||||
#include <mapnik/font_engine_freetype.hpp>
|
#include <mapnik/font_engine_freetype.hpp>
|
||||||
|
|
||||||
|
using std::cerr;
|
||||||
|
using std::endl;
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
freetype_engine::freetype_engine()
|
freetype_engine::freetype_engine()
|
||||||
|
@ -30,7 +33,7 @@ namespace mapnik
|
||||||
FT_Error error = FT_Init_FreeType( &library_ );
|
FT_Error error = FT_Init_FreeType( &library_ );
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("can not load FreeType2 library");
|
throw std::runtime_error("Failed to initialize FreeType2 library");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +46,7 @@ namespace mapnik
|
||||||
{
|
{
|
||||||
mutex::scoped_lock lock(mapnik::singleton<freetype_engine,
|
mutex::scoped_lock lock(mapnik::singleton<freetype_engine,
|
||||||
mapnik::CreateStatic>::mutex_);
|
mapnik::CreateStatic>::mutex_);
|
||||||
|
//cerr << "freetype_engine::register_font() '" << file_name << "'" << endl;
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
FT_Error error = FT_New_Face (library_,file_name.c_str(),0,&face);
|
FT_Error error = FT_New_Face (library_,file_name.c_str(),0,&face);
|
||||||
if ( !error )
|
if ( !error )
|
||||||
|
|
180
src/libxml2_loader.cpp
Normal file
180
src/libxml2_loader.cpp
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 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 <libxml/parser.h>
|
||||||
|
#include <libxml/tree.h>
|
||||||
|
#include <libxml/parserInternals.h>
|
||||||
|
|
||||||
|
#include <boost/utility.hpp>
|
||||||
|
#include <boost/property_tree/ptree.hpp>
|
||||||
|
#include <boost/filesystem/operations.hpp>
|
||||||
|
|
||||||
|
#include <mapnik/config_error.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using boost::property_tree::ptree;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
class libxml2_loader : boost::noncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
libxml2_loader() :
|
||||||
|
ctx_( 0 )
|
||||||
|
{
|
||||||
|
LIBXML_TEST_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
~libxml2_loader()
|
||||||
|
{
|
||||||
|
if (ctx_ && ctx_->myDoc)
|
||||||
|
{
|
||||||
|
xmlFreeDoc( ctx_->myDoc );
|
||||||
|
}
|
||||||
|
if (ctx_)
|
||||||
|
{
|
||||||
|
xmlFreeParserCtxt(ctx_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void load( const std::string & filename, ptree & pt )
|
||||||
|
{
|
||||||
|
boost::filesystem::path path(filename);
|
||||||
|
if ( ! boost::filesystem::exists( path ) ) {
|
||||||
|
throw config_error(string("Could not load map file '") +
|
||||||
|
filename + "': File does not exist");
|
||||||
|
}
|
||||||
|
ctx_ = xmlCreateFileParserCtxt( filename.c_str() );
|
||||||
|
|
||||||
|
if ( ! ctx_ )
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to create parser context.");
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx_->replaceEntities = true;
|
||||||
|
ctx_->keepBlanks = false;
|
||||||
|
xmlCtxtUseOptions( ctx_, XML_PARSE_NOERROR | XML_PARSE_NOENT | XML_PARSE_NOBLANKS |
|
||||||
|
XML_PARSE_DTDLOAD);
|
||||||
|
xmlParseDocument( ctx_ );
|
||||||
|
|
||||||
|
if ( ! ctx_->wellFormed )
|
||||||
|
{
|
||||||
|
xmlError * error = xmlCtxtGetLastError( ctx_ );
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "XML document not well formed";
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
os << ": " << std::endl << error->message;
|
||||||
|
// remove CR
|
||||||
|
std::string msg = os.str().substr(0, os.str().size() - 1);
|
||||||
|
config_error ex( msg );
|
||||||
|
|
||||||
|
os.str("");
|
||||||
|
os << "in file '" << error->file << "' at line "
|
||||||
|
<< error->line;
|
||||||
|
|
||||||
|
ex.append_context( os.str() );
|
||||||
|
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if ( ! ctx->valid )
|
||||||
|
{
|
||||||
|
std::clog << "### ERROR: Failed to validate DTD."
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
xmlNode * root( 0 );
|
||||||
|
root = xmlDocGetRootElement( ctx_->myDoc );
|
||||||
|
if ( ! root ) {
|
||||||
|
throw config_error("XML document is empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
populate_tree( root, pt );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void append_attributes( xmlAttr * attributes, ptree & pt)
|
||||||
|
{
|
||||||
|
if (attributes)
|
||||||
|
{
|
||||||
|
ptree::iterator it = pt.push_back( ptree::value_type( "<xmlattr>", ptree() ));
|
||||||
|
ptree & attr_list = it->second;
|
||||||
|
xmlAttr * cur_attr = attributes;
|
||||||
|
for (; cur_attr; cur_attr = cur_attr->next )
|
||||||
|
{
|
||||||
|
ptree::iterator it = attr_list.push_back(
|
||||||
|
ptree::value_type( (char*)cur_attr->name, ptree() ));
|
||||||
|
it->second.put_own( (char*) cur_attr->children->content );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void populate_tree( xmlNode * node, ptree & pt )
|
||||||
|
{
|
||||||
|
xmlNode * cur_node = node;
|
||||||
|
|
||||||
|
for (; cur_node; cur_node = cur_node->next )
|
||||||
|
{
|
||||||
|
switch (cur_node->type)
|
||||||
|
{
|
||||||
|
case XML_ELEMENT_NODE:
|
||||||
|
{
|
||||||
|
ptree::iterator it = pt.push_back( ptree::value_type(
|
||||||
|
(char*)cur_node->name, ptree() ));
|
||||||
|
append_attributes( cur_node->properties, it->second);
|
||||||
|
populate_tree( cur_node->children, it->second );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XML_TEXT_NODE:
|
||||||
|
pt.put_own( (char*) cur_node->content );
|
||||||
|
break;
|
||||||
|
case XML_COMMENT_NODE:
|
||||||
|
{
|
||||||
|
ptree::iterator it = pt.push_back(
|
||||||
|
ptree::value_type( "<xmlcomment>", ptree() ));
|
||||||
|
it->second.put_own( (char*) cur_node->content );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlParserCtxtPtr ctx_;
|
||||||
|
};
|
||||||
|
|
||||||
|
void read_xml2( std::string const & filename, boost::property_tree::ptree & pt)
|
||||||
|
{
|
||||||
|
libxml2_loader loader;
|
||||||
|
loader.load( filename, pt );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of namespace mapnik
|
|
@ -33,25 +33,10 @@ namespace mapnik
|
||||||
line_pattern_symbolizer::line_pattern_symbolizer(std::string const& file,
|
line_pattern_symbolizer::line_pattern_symbolizer(std::string const& file,
|
||||||
std::string const& type,
|
std::string const& type,
|
||||||
unsigned width,unsigned height)
|
unsigned width,unsigned height)
|
||||||
: pattern_(new ImageData32(width,height))
|
: symbolizer_with_image( file, type, width, height )
|
||||||
{
|
{ }
|
||||||
try
|
|
||||||
{
|
|
||||||
std::auto_ptr<ImageReader> reader(get_image_reader(type,file));
|
|
||||||
if (reader.get())
|
|
||||||
reader->read(0,0,*pattern_);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
std::clog << "exception caught..." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
line_pattern_symbolizer::line_pattern_symbolizer(line_pattern_symbolizer const& rhs)
|
line_pattern_symbolizer::line_pattern_symbolizer(line_pattern_symbolizer const& rhs)
|
||||||
: pattern_(rhs.pattern_) {}
|
: symbolizer_with_image(rhs) {}
|
||||||
|
|
||||||
ImageData32 const& line_pattern_symbolizer::get_pattern() const
|
|
||||||
{
|
|
||||||
return *pattern_;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
1240
src/load_map.cpp
1240
src/load_map.cpp
File diff suppressed because it is too large
Load diff
|
@ -70,8 +70,8 @@ namespace mapnik
|
||||||
minimum_distance(sym.get_minimum_distance()),
|
minimum_distance(sym.get_minimum_distance()),
|
||||||
avoid_edges(sym.get_avoid_edges()),
|
avoid_edges(sym.get_avoid_edges()),
|
||||||
has_dimensions(true),
|
has_dimensions(true),
|
||||||
dimensions(std::make_pair(sym.get_background_image()->width(),
|
dimensions(std::make_pair(sym.get_image()->width(),
|
||||||
sym.get_background_image()->height()))
|
sym.get_image()->height()))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,16 +205,16 @@ namespace mapnik
|
||||||
|
|
||||||
double distance = p->get_total_distance();
|
double distance = p->get_total_distance();
|
||||||
|
|
||||||
if (p->label_placement == line_placement && string_width > distance)
|
if (p->label_placement == LINE_PLACEMENT && string_width > distance)
|
||||||
{
|
{
|
||||||
//Empty!
|
//Empty!
|
||||||
return ideal_label_distances;
|
return ideal_label_distances;
|
||||||
}
|
}
|
||||||
|
|
||||||
int num_labels = 0;
|
int num_labels = 0;
|
||||||
if (p->label_spacing && p->label_placement == line_placement)
|
if (p->label_spacing && p->label_placement == LINE_PLACEMENT)
|
||||||
num_labels = static_cast<int> (floor(distance / (p->label_spacing + string_width)));
|
num_labels = static_cast<int> (floor(distance / (p->label_spacing + string_width)));
|
||||||
else if (p->label_spacing && p->label_placement == point_placement)
|
else if (p->label_spacing && p->label_placement == POINT_PLACEMENT)
|
||||||
num_labels = static_cast<int> (floor(distance / p->label_spacing));
|
num_labels = static_cast<int> (floor(distance / p->label_spacing));
|
||||||
|
|
||||||
if (p->force_odd_labels && num_labels%2 == 0)
|
if (p->force_odd_labels && num_labels%2 == 0)
|
||||||
|
@ -225,7 +225,7 @@ namespace mapnik
|
||||||
double ideal_spacing = distance/num_labels;
|
double ideal_spacing = distance/num_labels;
|
||||||
|
|
||||||
double middle; //try draw text centered
|
double middle; //try draw text centered
|
||||||
if (p->label_placement == line_placement)
|
if (p->label_placement == LINE_PLACEMENT)
|
||||||
middle = (distance / 2.0) - (string_width/2.0);
|
middle = (distance / 2.0) - (string_width/2.0);
|
||||||
else // (p->label_placement == point_placement)
|
else // (p->label_placement == point_placement)
|
||||||
middle = distance / 2.0;
|
middle = distance / 2.0;
|
||||||
|
@ -289,9 +289,9 @@ namespace mapnik
|
||||||
}
|
}
|
||||||
p->clear_envelopes();
|
p->clear_envelopes();
|
||||||
// check position +- delta for valid placement
|
// check position +- delta for valid placement
|
||||||
if ((p->label_placement == line_placement &&
|
if ((p->label_placement == LINE_PLACEMENT &&
|
||||||
build_path_follow(p, *itr + (i*s)) ) ||
|
build_path_follow(p, *itr + (i*s)) ) ||
|
||||||
(p->label_placement == point_placement &&
|
(p->label_placement == POINT_PLACEMENT &&
|
||||||
build_path_horizontal(p, *itr + (i*s))) )
|
build_path_horizontal(p, *itr + (i*s))) )
|
||||||
{
|
{
|
||||||
update_detector(p);
|
update_detector(p);
|
||||||
|
|
|
@ -68,15 +68,7 @@ namespace mapnik
|
||||||
bit_depth_(0),
|
bit_depth_(0),
|
||||||
color_type_(0)
|
color_type_(0)
|
||||||
{
|
{
|
||||||
try
|
init();
|
||||||
{
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
catch (const ImageReaderException& e)
|
|
||||||
{
|
|
||||||
std::clog << e.what() << '\n';
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PngReader::~PngReader() {}
|
PngReader::~PngReader() {}
|
||||||
|
|
|
@ -33,48 +33,25 @@
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
point_symbolizer::point_symbolizer()
|
point_symbolizer::point_symbolizer()
|
||||||
: symbol_(new ImageData32(4,4)),
|
: symbolizer_with_image(boost::shared_ptr<ImageData32>(new ImageData32(4,4))),
|
||||||
overlap_(false)
|
overlap_(false)
|
||||||
{
|
{
|
||||||
//default point symbol is black 4x4px square
|
//default point symbol is black 4x4px square
|
||||||
symbol_->set(0xff000000);
|
image_->set(0xff000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
point_symbolizer::point_symbolizer(std::string const& file,
|
point_symbolizer::point_symbolizer(std::string const& file,
|
||||||
std::string const& type,
|
std::string const& type,
|
||||||
unsigned width,unsigned height)
|
unsigned width,unsigned height)
|
||||||
: symbol_(new ImageData32(width,height)),
|
: symbolizer_with_image(file, type, width, height),
|
||||||
overlap_(false)
|
overlap_(false)
|
||||||
{
|
{ }
|
||||||
try
|
|
||||||
{
|
|
||||||
boost::scoped_ptr<ImageReader> reader(get_image_reader(type,file));
|
|
||||||
if (reader.get())
|
|
||||||
{
|
|
||||||
reader->read(0,0,*symbol_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
std::clog<<"exception caught..." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
point_symbolizer::point_symbolizer(point_symbolizer const& rhs)
|
point_symbolizer::point_symbolizer(point_symbolizer const& rhs)
|
||||||
: symbol_(rhs.symbol_),
|
: symbolizer_with_image(rhs),
|
||||||
overlap_(rhs.overlap_)
|
overlap_(rhs.overlap_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void point_symbolizer::set_data( boost::shared_ptr<ImageData32> symbol)
|
|
||||||
{
|
|
||||||
symbol_ = symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::shared_ptr<ImageData32> const& point_symbolizer::get_data() const
|
|
||||||
{
|
|
||||||
return symbol_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void point_symbolizer::set_allow_overlap(bool overlap)
|
void point_symbolizer::set_allow_overlap(bool overlap)
|
||||||
{
|
{
|
||||||
overlap_ = overlap;
|
overlap_ = overlap;
|
||||||
|
|
|
@ -31,24 +31,11 @@ namespace mapnik
|
||||||
polygon_pattern_symbolizer::polygon_pattern_symbolizer(std::string const& file,
|
polygon_pattern_symbolizer::polygon_pattern_symbolizer(std::string const& file,
|
||||||
std::string const& type,
|
std::string const& type,
|
||||||
unsigned width,unsigned height)
|
unsigned width,unsigned height)
|
||||||
: pattern_(new ImageData32(width,height))
|
: symbolizer_with_image( file, type, width, height )
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
std::auto_ptr<ImageReader> reader(get_image_reader(type,file));
|
|
||||||
if (reader.get())
|
|
||||||
reader->read(0,0,*pattern_);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
std::clog << "exception caught...\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
polygon_pattern_symbolizer::polygon_pattern_symbolizer(polygon_pattern_symbolizer const& rhs)
|
polygon_pattern_symbolizer::polygon_pattern_symbolizer(polygon_pattern_symbolizer const& rhs)
|
||||||
: pattern_(rhs.pattern_) {}
|
: symbolizer_with_image(rhs) {}
|
||||||
|
|
||||||
ImageData32 const& polygon_pattern_symbolizer::get_pattern() const
|
|
||||||
{
|
|
||||||
return *pattern_;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
382
src/save_map.cpp
382
src/save_map.cpp
|
@ -26,18 +26,394 @@
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/tokenizer.hpp>
|
#include <boost/tokenizer.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
#include <boost/property_tree/xml_parser.hpp>
|
#include <boost/property_tree/xml_parser.hpp>
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/save_map.hpp>
|
#include <mapnik/save_map.hpp>
|
||||||
|
#include <mapnik/ptree_helpers.hpp>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
void save_map(Map & map, std::string const& filename)
|
using boost::property_tree::ptree;
|
||||||
|
using boost::optional;
|
||||||
|
|
||||||
|
std::string guess_type( const std::string & filename )
|
||||||
|
{
|
||||||
|
std::string::size_type idx = filename.find_last_of(".");
|
||||||
|
if ( idx != std::string::npos ) {
|
||||||
|
return filename.substr( idx + 1 );
|
||||||
|
}
|
||||||
|
return "<unknown>";
|
||||||
|
}
|
||||||
|
class serialize_symbolizer : public boost::static_visitor<>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
serialize_symbolizer( ptree & r ) : rule_(r) {}
|
||||||
|
|
||||||
|
void operator () ( const point_symbolizer & sym )
|
||||||
|
{
|
||||||
|
ptree & sym_node = rule_.push_back(
|
||||||
|
ptree::value_type("PointSymbolizer", ptree()))->second;
|
||||||
|
|
||||||
|
add_image_attributes( sym_node, sym );
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () ( const line_symbolizer & sym )
|
||||||
|
{
|
||||||
|
ptree & sym_node = rule_.push_back(
|
||||||
|
ptree::value_type("LineSymbolizer", ptree()))->second;
|
||||||
|
const stroke & strk = sym.get_stroke();
|
||||||
|
stroke dfl = stroke();
|
||||||
|
|
||||||
|
if ( strk.get_color() != dfl.get_color() )
|
||||||
|
{
|
||||||
|
set_css( sym_node, "stroke", strk.get_color() );
|
||||||
|
}
|
||||||
|
if ( strk.get_width() != dfl.get_width() )
|
||||||
|
{
|
||||||
|
set_css( sym_node, "stroke-width", strk.get_width() );
|
||||||
|
}
|
||||||
|
if ( strk.get_opacity() != dfl.get_opacity() )
|
||||||
|
{
|
||||||
|
set_css( sym_node, "stroke-opacity", strk.get_opacity() );
|
||||||
|
}
|
||||||
|
if ( strk.get_line_join() != dfl.get_line_join() )
|
||||||
|
{
|
||||||
|
set_css( sym_node, "stroke-linejoin", strk.get_line_join() );
|
||||||
|
}
|
||||||
|
if ( strk.get_line_cap() != dfl.get_line_cap() )
|
||||||
|
{
|
||||||
|
set_css( sym_node, "stroke-linecap", strk.get_line_cap() );
|
||||||
|
}
|
||||||
|
if ( ! strk.get_dash_array().empty() )
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
const dash_array & dashes = strk.get_dash_array();
|
||||||
|
for (unsigned i = 0; i < dashes.size(); ++i) {
|
||||||
|
os << dashes[i].first << ", " << dashes[i].second;
|
||||||
|
if ( i + 1 < dashes.size() ) os << ", ";
|
||||||
|
}
|
||||||
|
set_css( sym_node, "stroke-dasharray", os.str() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () ( const line_pattern_symbolizer & sym )
|
||||||
|
{
|
||||||
|
ptree & sym_node = rule_.push_back(
|
||||||
|
ptree::value_type("LinePatternSymbolizer",
|
||||||
|
ptree()))->second;
|
||||||
|
|
||||||
|
add_image_attributes( sym_node, sym );
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () ( const polygon_symbolizer & sym )
|
||||||
|
{
|
||||||
|
ptree & sym_node = rule_.push_back(
|
||||||
|
ptree::value_type("PolygonSymbolizer", ptree()))->second;
|
||||||
|
polygon_symbolizer dfl;
|
||||||
|
|
||||||
|
if ( sym.get_fill() != dfl.get_fill() )
|
||||||
|
{
|
||||||
|
set_css( sym_node, "fill", sym.get_fill() );
|
||||||
|
}
|
||||||
|
if ( sym.get_opacity() != dfl.get_opacity() )
|
||||||
|
{
|
||||||
|
set_css( sym_node, "opacity", sym.get_opacity() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () ( const polygon_pattern_symbolizer & sym )
|
||||||
|
{
|
||||||
|
ptree & sym_node = rule_.push_back(
|
||||||
|
ptree::value_type("PolygonPatternSymbolizer",
|
||||||
|
ptree()))->second;
|
||||||
|
|
||||||
|
add_image_attributes( sym_node, sym );
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () ( const raster_symbolizer & sym )
|
||||||
|
{
|
||||||
|
rule_.push_back(
|
||||||
|
ptree::value_type("RasterSymbolizer", ptree()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () ( const shield_symbolizer & sym )
|
||||||
|
{
|
||||||
|
ptree & sym_node = rule_.push_back(
|
||||||
|
ptree::value_type("ShieldSymbolizer",
|
||||||
|
ptree()))->second;
|
||||||
|
|
||||||
|
add_font_attributes( sym_node, sym);
|
||||||
|
add_image_attributes( sym_node, sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () ( const text_symbolizer & sym )
|
||||||
|
{
|
||||||
|
ptree & sym_node = rule_.push_back(
|
||||||
|
ptree::value_type("TextSymbolizer",
|
||||||
|
ptree()))->second;
|
||||||
|
|
||||||
|
add_font_attributes( sym_node, sym);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () ( const building_symbolizer & sym )
|
||||||
|
{
|
||||||
|
ptree & sym_node = rule_.push_back(
|
||||||
|
ptree::value_type("BuildingSymbolizer", ptree()))->second;
|
||||||
|
building_symbolizer dfl;
|
||||||
|
|
||||||
|
if ( sym.get_fill() != dfl.get_fill() )
|
||||||
|
{
|
||||||
|
set_css( sym_node, "fill", sym.get_fill() );
|
||||||
|
}
|
||||||
|
if ( sym.get_opacity() != dfl.get_opacity() )
|
||||||
|
{
|
||||||
|
set_css( sym_node, "fill-opacity", sym.get_opacity() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
serialize_symbolizer();
|
||||||
|
void add_image_attributes(ptree & node, const symbolizer_with_image & sym)
|
||||||
|
{
|
||||||
|
const std::string & filename = sym.get_filename();
|
||||||
|
if ( ! filename.empty() ) {
|
||||||
|
set_attr( node, "file", filename );
|
||||||
|
set_attr( node, "type", guess_type( filename ) );
|
||||||
|
|
||||||
|
boost::shared_ptr<ImageData32> img = sym.get_image();
|
||||||
|
if ( img )
|
||||||
|
{
|
||||||
|
if ( img->width() > 0)
|
||||||
|
{
|
||||||
|
set_attr( node, "width", img->width() );
|
||||||
|
}
|
||||||
|
if ( img->height() > 0)
|
||||||
|
{
|
||||||
|
set_attr( node, "height", img->height() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void add_font_attributes(ptree & node, const text_symbolizer & sym)
|
||||||
|
{
|
||||||
|
const std::string & name = sym.get_name();
|
||||||
|
if ( ! name.empty() ) {
|
||||||
|
set_attr( node, "name", name );
|
||||||
|
}
|
||||||
|
const std::string & face_name = sym.get_face_name();
|
||||||
|
if ( ! face_name.empty() ) {
|
||||||
|
set_attr( node, "face_name", face_name );
|
||||||
|
}
|
||||||
|
|
||||||
|
set_attr( node, "size", sym.get_text_size() );
|
||||||
|
set_attr( node, "fill", sym.get_fill() );
|
||||||
|
|
||||||
|
// pseudo-default-construct a text_symbolizer. It is used
|
||||||
|
// to avoid printing ofattributes with default values without
|
||||||
|
// repeating the default values here.
|
||||||
|
// maybe add a real, explicit default-ctor?
|
||||||
|
text_symbolizer dfl("<no default>", "<no default>",
|
||||||
|
0, Color(0,0,0) );
|
||||||
|
|
||||||
|
position displacement = sym.get_displacement();
|
||||||
|
if ( displacement.get<0>() != dfl.get_displacement().get<0>() )
|
||||||
|
{
|
||||||
|
set_attr( node, "dx", displacement.get<0>() );
|
||||||
|
}
|
||||||
|
if ( displacement.get<1>() != dfl.get_displacement().get<1>() )
|
||||||
|
{
|
||||||
|
set_attr( node, "dy", displacement.get<1>() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sym.get_label_placement() != dfl.get_label_placement() )
|
||||||
|
{
|
||||||
|
set_attr( node, "placement", sym.get_label_placement() );
|
||||||
|
}
|
||||||
|
if (sym.get_halo_radius() != dfl.get_halo_radius())
|
||||||
|
{
|
||||||
|
set_attr( node, "halo_radius", sym.get_halo_radius() );
|
||||||
|
}
|
||||||
|
const Color & c = sym.get_halo_fill();
|
||||||
|
if ( c != dfl.get_halo_fill() )
|
||||||
|
{
|
||||||
|
set_attr( node, "halo_fill", c );
|
||||||
|
}
|
||||||
|
if (sym.get_text_ratio() != dfl.get_text_ratio() )
|
||||||
|
{
|
||||||
|
set_attr( node, "text_ratio", sym.get_text_ratio() );
|
||||||
|
}
|
||||||
|
if (sym.get_wrap_width() != dfl.get_wrap_width())
|
||||||
|
{
|
||||||
|
set_attr( node, "wrap_width", sym.get_wrap_width() );
|
||||||
|
}
|
||||||
|
if (sym.get_label_spacing() != dfl.get_label_spacing())
|
||||||
|
{
|
||||||
|
set_attr( node, "spacing", sym.get_label_spacing() );
|
||||||
|
}
|
||||||
|
if (sym.get_minimum_distance() != dfl.get_minimum_distance())
|
||||||
|
{
|
||||||
|
set_attr( node, "min_distance", sym.get_minimum_distance() );
|
||||||
|
}
|
||||||
|
if (sym.get_allow_overlap() != dfl.get_allow_overlap() )
|
||||||
|
{
|
||||||
|
set_attr( node, "allow_overlap", sym.get_allow_overlap() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ptree & rule_;
|
||||||
|
};
|
||||||
|
|
||||||
|
void serialize_rule( ptree & style_node, const rule_type & rule)
|
||||||
|
{
|
||||||
|
ptree & rule_node = style_node.push_back(
|
||||||
|
ptree::value_type("Rule", ptree() ))->second;
|
||||||
|
|
||||||
|
rule_type dfl;
|
||||||
|
if ( rule.get_name() != dfl.get_name() )
|
||||||
|
{
|
||||||
|
set_attr(rule_node, "name", rule.get_name());
|
||||||
|
}
|
||||||
|
if ( rule.get_title() != dfl.get_title() )
|
||||||
|
{
|
||||||
|
set_attr(rule_node, "title", rule.get_title());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( rule.has_else_filter() )
|
||||||
|
{
|
||||||
|
rule_node.push_back( ptree::value_type(
|
||||||
|
"ElseFilter", ptree()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// filters are not comparable, so compare strings for now
|
||||||
|
std::string filter = rule.get_filter()->to_string();
|
||||||
|
std::string default_filter = dfl.get_filter()->to_string();
|
||||||
|
if ( filter != default_filter)
|
||||||
|
{
|
||||||
|
rule_node.push_back( ptree::value_type(
|
||||||
|
"Filter", ptree()))->second.put_own( filter );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rule.get_min_scale() != dfl.get_min_scale())
|
||||||
|
{
|
||||||
|
ptree & min_scale = rule_node.push_back( ptree::value_type(
|
||||||
|
"MinScaleDenominator", ptree()))->second;
|
||||||
|
min_scale.put_own( rule.get_min_scale() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rule.get_max_scale() != dfl.get_max_scale() )
|
||||||
|
{
|
||||||
|
ptree & max_scale = rule_node.push_back( ptree::value_type(
|
||||||
|
"MaxScaleDenominator", ptree()))->second;
|
||||||
|
max_scale.put_own( rule.get_max_scale() );
|
||||||
|
}
|
||||||
|
|
||||||
|
symbolizers::const_iterator begin = rule.get_symbolizers().begin();
|
||||||
|
symbolizers::const_iterator end = rule.get_symbolizers().end();
|
||||||
|
serialize_symbolizer serializer( rule_node );
|
||||||
|
std::for_each( begin, end , boost::apply_visitor( serializer ));
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialize_style( ptree & map_node, Map::const_style_iterator style_it )
|
||||||
|
{
|
||||||
|
const feature_type_style & style = style_it->second;
|
||||||
|
const std::string & name = style_it->first;
|
||||||
|
|
||||||
|
ptree & style_node = map_node.push_back(
|
||||||
|
ptree::value_type("Style", ptree()))->second;
|
||||||
|
|
||||||
|
set_attr(style_node, "name", name);
|
||||||
|
|
||||||
|
rules::const_iterator it = style.get_rules().begin();
|
||||||
|
rules::const_iterator end = style.get_rules().end();
|
||||||
|
for (; it != end; ++it)
|
||||||
|
{
|
||||||
|
serialize_rule( style_node, * it );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialize_datasource( ptree & layer_node, datasource_ptr datasource)
|
||||||
|
{
|
||||||
|
ptree & datasource_node = layer_node.push_back(
|
||||||
|
ptree::value_type("Datasource", ptree()))->second;
|
||||||
|
|
||||||
|
parameters::const_iterator it = datasource->params().begin();
|
||||||
|
parameters::const_iterator end = datasource->params().end();
|
||||||
|
for (; it != end; ++it)
|
||||||
|
{
|
||||||
|
boost::property_tree::ptree & param_node = datasource_node.push_back(
|
||||||
|
boost::property_tree::ptree::value_type("Parameter",
|
||||||
|
boost::property_tree::ptree()))->second;
|
||||||
|
param_node.put("<xmlattr>.name", it->first );
|
||||||
|
param_node.put_own( it->second );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialize_layer( ptree & map_node, const Layer & layer )
|
||||||
|
{
|
||||||
|
ptree & layer_node = map_node.push_back(
|
||||||
|
ptree::value_type("Layer", ptree()))->second;
|
||||||
|
if ( layer.name() != "" )
|
||||||
|
{
|
||||||
|
set_attr( layer_node, "name", layer.name() );
|
||||||
|
}
|
||||||
|
if ( layer.srs() != "" )
|
||||||
|
{
|
||||||
|
set_attr( layer_node, "srs", layer.srs() );
|
||||||
|
}
|
||||||
|
set_attr/*<bool>*/( layer_node, "status", layer.isActive() );
|
||||||
|
set_attr/*<bool>*/( layer_node, "clear_label_cache", layer.clear_label_cache() );
|
||||||
|
|
||||||
|
std::vector<std::string> const& style_names = layer.styles();
|
||||||
|
for (unsigned i = 0; i < style_names.size(); ++i)
|
||||||
|
{
|
||||||
|
boost::property_tree::ptree & style_node = layer_node.push_back(
|
||||||
|
boost::property_tree::ptree::value_type("StyleName",
|
||||||
|
boost::property_tree::ptree()))->second;
|
||||||
|
style_node.put_own( style_names[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
datasource_ptr datasource = layer.datasource();
|
||||||
|
if ( datasource )
|
||||||
|
{
|
||||||
|
serialize_datasource( layer_node, datasource );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void save_map(Map const & map, std::string const& filename)
|
||||||
{
|
{
|
||||||
using boost::property_tree::ptree;
|
|
||||||
ptree pt;
|
ptree pt;
|
||||||
// TODO
|
|
||||||
|
ptree & map_node = pt.push_back(ptree::value_type("Map", ptree() ))->second;
|
||||||
|
|
||||||
|
set_attr( map_node, "srs", map.srs() );
|
||||||
|
|
||||||
|
optional<Color> c = map.background();
|
||||||
|
if ( c )
|
||||||
|
{
|
||||||
|
set_attr( map_node, "bgcolor", * c );
|
||||||
|
}
|
||||||
|
|
||||||
|
Map::const_style_iterator it = map.styles().begin();
|
||||||
|
Map::const_style_iterator end = map.styles().end();
|
||||||
|
for (; it != end; ++it)
|
||||||
|
{
|
||||||
|
serialize_style( map_node, it);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Layer> const & layers = map.layers();
|
||||||
|
for (unsigned i = 0; i < layers.size(); ++i )
|
||||||
|
{
|
||||||
|
serialize_layer( map_node, layers[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
write_xml(filename,pt);
|
write_xml(filename,pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,30 +43,8 @@ namespace mapnik
|
||||||
std::string const& type,
|
std::string const& type,
|
||||||
unsigned width,unsigned height)
|
unsigned width,unsigned height)
|
||||||
: text_symbolizer(name, face_name, size, fill),
|
: text_symbolizer(name, face_name, size, fill),
|
||||||
background_image_(new ImageData32(width, height))
|
symbolizer_with_image( file, type, width, height )
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
boost::scoped_ptr<ImageReader> reader(get_image_reader(type,file));
|
|
||||||
if (reader.get())
|
|
||||||
{
|
|
||||||
reader->read(0,0,*background_image_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
std::clog << "exception caught..." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void shield_symbolizer::set_background_image(boost::shared_ptr<ImageData32> background_image)
|
|
||||||
{
|
|
||||||
background_image_ = background_image;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::shared_ptr<ImageData32> const& shield_symbolizer::get_background_image() const
|
|
||||||
{
|
|
||||||
return background_image_;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
153
src/stroke.cpp
Normal file
153
src/stroke.cpp
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/stroke.hpp>
|
||||||
|
|
||||||
|
static const char * line_cap_strings[] = {
|
||||||
|
"butt",
|
||||||
|
"square",
|
||||||
|
"round",
|
||||||
|
""
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_ENUM( mapnik::line_cap_e, line_cap_strings );
|
||||||
|
|
||||||
|
static const char * line_join_strings[] = {
|
||||||
|
"miter",
|
||||||
|
"miter_revert",
|
||||||
|
"round",
|
||||||
|
"bevel",
|
||||||
|
""
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_ENUM( mapnik::line_join_e, line_join_strings );
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
stroke::stroke()
|
||||||
|
: c_(0,0,0),
|
||||||
|
width_(1.0),
|
||||||
|
opacity_(1.0),
|
||||||
|
line_cap_(BUTT_CAP),
|
||||||
|
line_join_(MITER_JOIN),
|
||||||
|
dash_() {}
|
||||||
|
|
||||||
|
stroke::stroke(Color const& c, float width)
|
||||||
|
: c_(c),
|
||||||
|
width_(width),
|
||||||
|
opacity_(1.0),
|
||||||
|
line_cap_(BUTT_CAP),
|
||||||
|
line_join_(MITER_JOIN),
|
||||||
|
dash_() {}
|
||||||
|
|
||||||
|
stroke::stroke(stroke const& other)
|
||||||
|
: c_(other.c_),
|
||||||
|
width_(other.width_),
|
||||||
|
opacity_(other.opacity_),
|
||||||
|
line_cap_(other.line_cap_),
|
||||||
|
line_join_(other.line_join_),
|
||||||
|
dash_(other.dash_) {}
|
||||||
|
|
||||||
|
stroke & stroke::operator=(const stroke& rhs)
|
||||||
|
{
|
||||||
|
stroke tmp(rhs);
|
||||||
|
swap(tmp);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stroke::set_color(const Color& c)
|
||||||
|
{
|
||||||
|
c_=c;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color const& stroke::get_color() const
|
||||||
|
{
|
||||||
|
return c_;
|
||||||
|
}
|
||||||
|
|
||||||
|
float stroke::get_width() const
|
||||||
|
{
|
||||||
|
return width_;
|
||||||
|
}
|
||||||
|
void stroke::set_width(float w)
|
||||||
|
{
|
||||||
|
width_=w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stroke::set_opacity(float opacity)
|
||||||
|
{
|
||||||
|
if (opacity > 1.0) opacity_=1.0;
|
||||||
|
else if (opacity < 0.0) opacity_=0.0;
|
||||||
|
else opacity_=opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
float stroke::get_opacity() const
|
||||||
|
{
|
||||||
|
return opacity_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stroke::set_line_cap(line_cap_e line_cap)
|
||||||
|
{
|
||||||
|
line_cap_=line_cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
line_cap_e stroke::get_line_cap() const
|
||||||
|
{
|
||||||
|
return line_cap_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stroke::set_line_join(line_join_e line_join)
|
||||||
|
{
|
||||||
|
line_join_=line_join;
|
||||||
|
}
|
||||||
|
|
||||||
|
line_join_e stroke::get_line_join() const
|
||||||
|
{
|
||||||
|
return line_join_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stroke::add_dash(float dash,float gap)
|
||||||
|
{
|
||||||
|
dash_.push_back(std::make_pair(dash,gap));
|
||||||
|
}
|
||||||
|
bool stroke::has_dash() const
|
||||||
|
{
|
||||||
|
return ! dash_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
dash_array const& stroke::get_dash_array() const
|
||||||
|
{
|
||||||
|
return dash_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stroke::swap(const stroke& other) throw()
|
||||||
|
{
|
||||||
|
c_=other.c_;
|
||||||
|
width_=other.width_;
|
||||||
|
opacity_=other.opacity_;
|
||||||
|
line_cap_=other.line_cap_;
|
||||||
|
line_join_=other.line_join_;
|
||||||
|
dash_ = other.dash_;
|
||||||
|
}
|
||||||
|
}
|
66
src/symbolizer.cpp
Normal file
66
src/symbolizer.cpp
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
//$Id$
|
||||||
|
|
||||||
|
#include <mapnik/symbolizer.hpp>
|
||||||
|
|
||||||
|
#include <mapnik/image_reader.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace mapnik {
|
||||||
|
|
||||||
|
symbolizer_with_image::symbolizer_with_image(boost::shared_ptr<ImageData32> img) :
|
||||||
|
image_( img ) {}
|
||||||
|
|
||||||
|
symbolizer_with_image::symbolizer_with_image(std::string const& file,
|
||||||
|
std::string const& type, unsigned width,unsigned height)
|
||||||
|
: image_(new ImageData32(width,height)),
|
||||||
|
image_filename_( file )
|
||||||
|
{
|
||||||
|
std::auto_ptr<ImageReader> reader(get_image_reader(type,file));
|
||||||
|
if (reader.get())
|
||||||
|
reader->read(0,0,*image_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
symbolizer_with_image::symbolizer_with_image( symbolizer_with_image const& rhs)
|
||||||
|
: image_(rhs.image_), image_filename_(rhs.image_filename_) {}
|
||||||
|
|
||||||
|
|
||||||
|
boost::shared_ptr<ImageData32> symbolizer_with_image::get_image() const
|
||||||
|
{
|
||||||
|
return image_;
|
||||||
|
}
|
||||||
|
void symbolizer_with_image::set_image(boost::shared_ptr<ImageData32> symbol)
|
||||||
|
{
|
||||||
|
image_ = symbol;
|
||||||
|
}
|
||||||
|
const std::string & symbolizer_with_image::get_filename() const
|
||||||
|
{
|
||||||
|
return image_filename_;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of namespace mapnik
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,14 @@
|
||||||
//mapnik
|
//mapnik
|
||||||
#include <mapnik/text_symbolizer.hpp>
|
#include <mapnik/text_symbolizer.hpp>
|
||||||
|
|
||||||
|
static const char * label_placement_strings[] = {
|
||||||
|
"point",
|
||||||
|
"line",
|
||||||
|
""
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_ENUM( mapnik::label_placement_e, label_placement_strings );
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
text_symbolizer::text_symbolizer(std::string const& name, std::string const& face_name, unsigned size,Color const& fill)
|
text_symbolizer::text_symbolizer(std::string const& name, std::string const& face_name, unsigned size,Color const& fill)
|
||||||
|
@ -44,7 +52,7 @@ namespace mapnik
|
||||||
fill_(fill),
|
fill_(fill),
|
||||||
halo_fill_(Color(255,255,255)),
|
halo_fill_(Color(255,255,255)),
|
||||||
halo_radius_(0),
|
halo_radius_(0),
|
||||||
label_p_(point_placement),
|
label_p_(POINT_PLACEMENT),
|
||||||
anchor_(0.0,0.5),
|
anchor_(0.0,0.5),
|
||||||
displacement_(0.0,0.0),
|
displacement_(0.0,0.0),
|
||||||
avoid_edges_(false),
|
avoid_edges_(false),
|
||||||
|
|
|
@ -88,21 +88,14 @@ namespace mapnik
|
||||||
tile_width_(0),
|
tile_width_(0),
|
||||||
tile_height_(0)
|
tile_height_(0)
|
||||||
{
|
{
|
||||||
try
|
init();
|
||||||
{
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
catch (ImageReaderException& ex)
|
|
||||||
{
|
|
||||||
std::clog<<ex.what()<<std::endl;
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TiffReader::init()
|
void TiffReader::init()
|
||||||
{
|
{
|
||||||
TIFF* tif = load_if_exists(file_name_);
|
// TODO: error handling
|
||||||
|
TIFF* tif = load_if_exists(file_name_);
|
||||||
if (!tif) return;
|
if (!tif) return;
|
||||||
|
|
||||||
char msg[1024];
|
char msg[1024];
|
||||||
|
|
Loading…
Reference in a new issue