- 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:
|
||||
LIBDIR_SCHEMA='lib'
|
||||
|
||||
opts = Options()
|
||||
opts = Options('config.py')
|
||||
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_LIBS', 'Search path for boost library files', '/usr/' + LIBDIR_SCHEMA))
|
||||
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(('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_LIBS','Search path for fribidi include files','/usr/' + LIBDIR_SCHEMA))
|
||||
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(BoolOption('BIDI', 'BIDI support', 'False'))
|
||||
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)
|
||||
|
||||
|
@ -105,6 +106,9 @@ if env['BIDI']:
|
|||
|
||||
if env['XMLPARSER'] == 'tinyxml':
|
||||
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 = [
|
||||
['m', 'math.h', True],
|
||||
|
@ -224,10 +228,12 @@ env = conf.Finish()
|
|||
if env['PLATFORM'] == 'Darwin': pthread = ''
|
||||
else: pthread = '-pthread'
|
||||
|
||||
common_cxx_flags = '-ansi -Wall %s -ftemplate-depth-100 -D%s ' % (pthread, env['PLATFORM'].upper());
|
||||
|
||||
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:
|
||||
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
|
||||
|
||||
|
|
|
@ -90,7 +90,10 @@ DatasourceCache.instance().register_datasources('%s' % inputpluginspath)
|
|||
from mapnik import FontEngine
|
||||
from glob import glob
|
||||
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
|
||||
setdlopenflags(flags)
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <boost/python.hpp>
|
||||
#include <boost/get_pointer.hpp>
|
||||
#include <boost/python/detail/api_placeholder.hpp>
|
||||
#include <boost/python/exception_translator.hpp>
|
||||
|
||||
void export_color();
|
||||
void export_coord();
|
||||
|
@ -58,6 +59,7 @@ void export_projection();
|
|||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/load_map.hpp>
|
||||
#include <mapnik/config_error.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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
using mapnik::load_map;
|
||||
using mapnik::save_map;
|
||||
|
||||
|
||||
register_exception_translator<mapnik::config_error>(translator);
|
||||
export_query();
|
||||
export_feature();
|
||||
export_featureset();
|
||||
|
@ -137,8 +146,8 @@ BOOST_PYTHON_MODULE(_mapnik)
|
|||
def("render",&render2);
|
||||
def("scale_denominator", &scale_denominator);
|
||||
|
||||
def("load_map",&load_map,"load Map object from XML");
|
||||
def("save_map",&load_map,"sace Map object to XML");
|
||||
def("load_map", & load_map, load_map_overloads());
|
||||
def("save_map", & save_map, "save Map object to XML");
|
||||
|
||||
using mapnik::symbolizer;
|
||||
class_<symbolizer>("Symbolizer",no_init)
|
||||
|
|
|
@ -30,12 +30,12 @@ void export_stroke ()
|
|||
using namespace mapnik;
|
||||
using namespace boost::python;
|
||||
|
||||
enum_<line_cap_e>("line_cap")
|
||||
enum_<line_cap_enum>("line_cap")
|
||||
.value("BUTT_CAP",BUTT_CAP)
|
||||
.value("SQUARE_CAP",SQUARE_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_REVERT_JOIN",MITER_REVERT_JOIN)
|
||||
.value("ROUND_JOIN",ROUND_JOIN)
|
||||
|
|
|
@ -32,9 +32,9 @@ void export_text_symbolizer()
|
|||
using mapnik::text_symbolizer;
|
||||
using mapnik::Color;
|
||||
|
||||
enum_<mapnik::label_placement_e>("label_placement")
|
||||
.value("LINE_PLACEMENT",mapnik::line_placement)
|
||||
.value("POINT_PLACEMENT",mapnik::point_placement)
|
||||
enum_<mapnik::label_placement_enum>("label_placement")
|
||||
.value("LINE_PLACEMENT",mapnik::LINE_PLACEMENT)
|
||||
.value("POINT_PLACEMENT",mapnik::POINT_PLACEMENT)
|
||||
;
|
||||
|
||||
class_<text_symbolizer>("TextSymbolizer",
|
||||
|
|
|
@ -104,6 +104,11 @@ namespace mapnik {
|
|||
return abgr_ == other.abgr_;
|
||||
}
|
||||
|
||||
inline bool operator!=(Color const& other) const
|
||||
{
|
||||
return abgr_ != other.abgr_;
|
||||
}
|
||||
|
||||
inline std::string to_string() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/css_color_parser.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
using namespace boost::spirit;
|
||||
|
||||
|
@ -40,8 +41,11 @@ namespace mapnik {
|
|||
actions<Color> a(color);
|
||||
css_color_grammar<actions<Color> > grammar(a);
|
||||
parse_info<> info = parse(css_color, grammar, space_p);
|
||||
if (info.full) return color;
|
||||
return Color(0,0,0);
|
||||
if ( ! info.full) {
|
||||
throw config_error(std::string("Failed to parse color value: ") +
|
||||
"Expected a color, but got '" + css_color + "'");
|
||||
}
|
||||
return color;
|
||||
}
|
||||
private:
|
||||
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
|
||||
{
|
||||
private:
|
||||
const std::string message_;
|
||||
std::string message_;
|
||||
public:
|
||||
datasource_exception(const std::string& message=std::string())
|
||||
datasource_exception(const std::string& message=std::string("no reason"))
|
||||
:message_(message) {}
|
||||
|
||||
~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
|
||||
#define FILTER_FACTORY_HPP
|
||||
|
||||
#include <mapnik/config_error.hpp>
|
||||
#include <mapnik/filter_parser.hpp>
|
||||
|
||||
namespace mapnik
|
||||
|
@ -41,14 +42,23 @@ namespace mapnik
|
|||
stack<shared_ptr<expression<FeatureT> > > exps;
|
||||
filter_grammar<FeatureT> grammar(filters,exps);
|
||||
char const *text = str.c_str();
|
||||
parse_info<> info = parse(text,text+strlen(text),grammar,space_p);
|
||||
if (info.full && !filters.empty())
|
||||
parse_info<> info = parse(text, grammar, space_p);
|
||||
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();
|
||||
}
|
||||
else
|
||||
{
|
||||
clog << "failed at :" << info.stop << "\n";
|
||||
// XXX: do we ever get here? [DS]
|
||||
return filter_ptr(new none_filter<FeatureT>());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
#include <stack>
|
||||
#include <iostream>
|
||||
// boost
|
||||
|
||||
//#define BOOST_SPIRIT_DEBUG
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/spirit/core.hpp>
|
||||
#include <boost/spirit/symbols.hpp>
|
||||
|
@ -404,7 +407,7 @@ namespace mapnik
|
|||
[compose_filter<FeatureT,mapnik::less_than<value> >(self.filters,self.exprs)]
|
||||
| (L"<=" >> expression)
|
||||
[compose_filter<FeatureT,less_than_or_equal<value> >(self.filters,self.exprs)]
|
||||
| regex );
|
||||
/* | regex */);
|
||||
|
||||
equation = relation >> *( ( L'=' >> relation)
|
||||
[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)];
|
||||
|
||||
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
|
||||
|
@ -444,6 +466,8 @@ namespace mapnik
|
|||
symbols<string> func1_op;
|
||||
symbols<string> func2_op;
|
||||
symbols<string> spatial_op;
|
||||
|
||||
|
||||
};
|
||||
stack<shared_ptr<filter<FeatureT> > >& filters;
|
||||
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 <mapnik/graphics.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
|
||||
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,
|
||||
std::string const& type,
|
||||
unsigned width,unsigned height);
|
||||
|
||||
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
|
||||
{
|
||||
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
|
||||
|
|
|
@ -199,7 +199,7 @@ namespace mapnik
|
|||
* @param c Background color.
|
||||
*/
|
||||
void set_background(const Color& c);
|
||||
|
||||
|
||||
/*! \brief Get the map background color
|
||||
* @return Background color as boost::optional
|
||||
* object
|
||||
|
|
|
@ -26,23 +26,22 @@
|
|||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
struct MAPNIK_DECL point_symbolizer
|
||||
struct MAPNIK_DECL point_symbolizer :
|
||||
public symbolizer_with_image
|
||||
{
|
||||
explicit point_symbolizer();
|
||||
point_symbolizer(std::string const& file,
|
||||
std::string const& type,
|
||||
unsigned width,unsigned height);
|
||||
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);
|
||||
bool get_allow_overlap() const;
|
||||
|
||||
private:
|
||||
boost::shared_ptr<ImageData32> symbol_;
|
||||
bool overlap_;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -26,10 +26,12 @@
|
|||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
|
||||
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,
|
||||
|
@ -37,10 +39,6 @@ namespace mapnik
|
|||
unsigned width,unsigned height);
|
||||
|
||||
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
|
||||
#define SHIELD_SYMBOLIZER_HPP
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/text_symbolizer.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
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,
|
||||
std::string const& face_name,
|
||||
|
@ -41,13 +44,6 @@ namespace mapnik
|
|||
std::string const& type,
|
||||
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>
|
||||
// mapnik
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/enumeration.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
@ -34,20 +35,30 @@ namespace mapnik
|
|||
using std::vector;
|
||||
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,
|
||||
SQUARE_CAP,
|
||||
ROUND_CAP
|
||||
ROUND_CAP,
|
||||
line_cap_enum_MAX
|
||||
};
|
||||
|
||||
DEFINE_ENUM( line_cap_e, line_cap_enum );
|
||||
|
||||
enum line_join_e
|
||||
// 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_REVERT_JOIN,
|
||||
ROUND_JOIN,
|
||||
BEVEL_JOIN
|
||||
BEVEL_JOIN,
|
||||
line_join_enum_MAX
|
||||
};
|
||||
|
||||
DEFINE_ENUM( line_join_e, line_join_enum );
|
||||
|
||||
class stroke
|
||||
{
|
||||
|
@ -58,112 +69,34 @@ namespace mapnik
|
|||
line_join_e line_join_;
|
||||
dash_array dash_;
|
||||
public:
|
||||
explicit stroke()
|
||||
: c_(0,0,0),
|
||||
width_(1.0),
|
||||
opacity_(1.0),
|
||||
line_cap_(BUTT_CAP),
|
||||
line_join_(MITER_JOIN),
|
||||
dash_() {}
|
||||
|
||||
stroke(Color const& c, float width=1.0)
|
||||
: c_(c),
|
||||
width_(width),
|
||||
opacity_(1.0),
|
||||
line_cap_(BUTT_CAP),
|
||||
line_join_(MITER_JOIN),
|
||||
dash_() {}
|
||||
explicit stroke();
|
||||
stroke(Color const& c, float width=1.0);
|
||||
stroke(stroke const& other);
|
||||
stroke& operator=(const stroke& rhs);
|
||||
|
||||
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& operator=(const stroke& rhs)
|
||||
{
|
||||
stroke tmp(rhs);
|
||||
swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
void set_color(const Color& c);
|
||||
|
||||
Color const& get_color() const;
|
||||
|
||||
float get_width() const;
|
||||
void set_width(float w);
|
||||
void set_opacity(float opacity);
|
||||
|
||||
void set_color(const Color& c)
|
||||
{
|
||||
c_=c;
|
||||
}
|
||||
float get_opacity() const;
|
||||
|
||||
Color const& get_color() const
|
||||
{
|
||||
return c_;
|
||||
}
|
||||
void set_line_cap(line_cap_e line_cap);
|
||||
line_cap_e get_line_cap() const;
|
||||
|
||||
float get_width() const
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
void set_width(float w)
|
||||
{
|
||||
width_=w;
|
||||
}
|
||||
|
||||
void set_opacity(float opacity)
|
||||
{
|
||||
if (opacity > 1.0) opacity_=1.0;
|
||||
else if (opacity < 0.0) opacity_=0.0;
|
||||
else opacity_=opacity;
|
||||
}
|
||||
|
||||
float get_opacity() const
|
||||
{
|
||||
return opacity_;
|
||||
}
|
||||
void set_line_join(line_join_e line_join);
|
||||
line_join_e get_line_join() const;
|
||||
|
||||
void set_line_cap(line_cap_e line_cap)
|
||||
{
|
||||
line_cap_=line_cap;
|
||||
}
|
||||
|
||||
line_cap_e get_line_cap() const
|
||||
{
|
||||
return line_cap_;
|
||||
}
|
||||
void add_dash(float dash,float gap);
|
||||
bool has_dash() const;
|
||||
|
||||
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_;
|
||||
}
|
||||
dash_array const& get_dash_array() const;
|
||||
|
||||
private:
|
||||
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_;
|
||||
}
|
||||
void swap(const stroke& other) throw();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,31 @@
|
|||
#ifndef SYMBOLIZER_HPP
|
||||
#define SYMBOLIZER_HPP
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
|
||||
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
|
||||
|
|
|
@ -30,22 +30,25 @@
|
|||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
// mapnik
|
||||
#include <mapnik/enumeration.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
enum label_placement_e {
|
||||
point_placement=1,
|
||||
line_placement=2
|
||||
enum label_placement_enum {
|
||||
POINT_PLACEMENT,
|
||||
LINE_PLACEMENT,
|
||||
label_placement_enum_MAX
|
||||
};
|
||||
DEFINE_ENUM( label_placement_e, label_placement_enum );
|
||||
|
||||
typedef boost::tuple<double,double> position;
|
||||
|
||||
struct MAPNIK_DECL text_symbolizer
|
||||
{
|
||||
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& operator=(text_symbolizer const& rhs);
|
||||
std::string const& get_name() const;
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#ifndef CONNECTION_HPP
|
||||
#define CONNECTION_HPP
|
||||
|
||||
#include <mapnik/datasource.hpp>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "libpq-fe.h"
|
||||
|
@ -41,10 +43,18 @@ class Connection
|
|||
Connection(std::string const& connection_str)
|
||||
{
|
||||
conn_=PQconnectdb(connection_str.c_str());
|
||||
if (PQstatus(conn_) == CONNECTION_BAD)
|
||||
if (PQstatus(conn_) != CONNECTION_OK)
|
||||
{
|
||||
std::clog << "connection ["<< connection_str<< "] failed\n"
|
||||
<< PQerrorMessage(conn_)<< std::endl;
|
||||
std::string s("PSQL error");
|
||||
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
|
||||
{
|
||||
return new T(connection_string());
|
||||
return new T(connection_string());
|
||||
}
|
||||
|
||||
inline std::string id() const
|
||||
|
|
|
@ -46,8 +46,8 @@ source = Split(
|
|||
image_util.cpp
|
||||
layer.cpp
|
||||
line_pattern_symbolizer.cpp
|
||||
load_map.cpp
|
||||
map.cpp
|
||||
load_map.cpp
|
||||
memory.cpp
|
||||
params.cpp
|
||||
placement_finder.cpp
|
||||
|
@ -65,15 +65,25 @@ source = Split(
|
|||
distance.cpp
|
||||
scale_denominator.cpp
|
||||
memory_datasource.cpp
|
||||
stroke.cpp
|
||||
symbolizer.cpp
|
||||
"""
|
||||
)
|
||||
source += Split(
|
||||
"""
|
||||
../tinyxml/tinystr.cpp
|
||||
../tinyxml/tinyxml.cpp
|
||||
../tinyxml/tinyxmlerror.cpp
|
||||
../tinyxml/tinyxmlparser.cpp
|
||||
""")
|
||||
|
||||
if env['XMLPARSER'] == 'tinyxml':
|
||||
source += Split(
|
||||
"""
|
||||
../tinyxml/tinystr.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)
|
||||
|
||||
|
|
|
@ -218,7 +218,8 @@ namespace mapnik
|
|||
|
||||
boost::scoped_ptr<geometry2d> roof(new polygon_impl);
|
||||
std::deque<segment_t> face_segments;
|
||||
double x0,y0;
|
||||
double x0(0);
|
||||
double y0(0);
|
||||
for (unsigned j=0;j<geom.num_points();++j)
|
||||
{
|
||||
double x,y;
|
||||
|
@ -397,7 +398,7 @@ namespace mapnik
|
|||
double x;
|
||||
double y;
|
||||
double z=0;
|
||||
boost::shared_ptr<ImageData32> const& data = sym.get_data();
|
||||
boost::shared_ptr<ImageData32> const& data = sym.get_image();
|
||||
if ( data )
|
||||
{
|
||||
for (unsigned i=0;i<feature.num_geometries();++i)
|
||||
|
@ -431,7 +432,7 @@ namespace mapnik
|
|||
proj_transform const& prj_trans)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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::rasterizer_outline_aa<renderer_type> rasterizer_type;
|
||||
|
||||
ImageData32 const& pat = sym.get_pattern();
|
||||
ImageData32 pat = * sym.get_image();
|
||||
renderer_base ren_base(pixf_);
|
||||
agg::pattern_filter_bilinear_rgba8 filter;
|
||||
pattern_source source(pat);
|
||||
|
@ -532,7 +533,7 @@ namespace mapnik
|
|||
ren_base renb(pixf_);
|
||||
agg::scanline_u8 sl;
|
||||
|
||||
ImageData32 const& pattern = sym.get_pattern();
|
||||
ImageData32 const& pattern = * sym.get_image();
|
||||
unsigned w=pattern.width();
|
||||
unsigned h=pattern.height();
|
||||
agg::row_accessor<agg::int8u> pattern_rbuf((agg::int8u*)pattern.getBytes(),w,h,w*4);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <boost/algorithm/string.hpp>
|
||||
// mapnik
|
||||
#include <mapnik/datasource_cache.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
// ltdl
|
||||
#include <ltdl.h>
|
||||
|
||||
|
@ -46,7 +47,7 @@ namespace mapnik
|
|||
|
||||
datasource_cache::datasource_cache()
|
||||
{
|
||||
if (lt_dlinit()) throw;
|
||||
if (lt_dlinit()) throw std::runtime_error("lt_dlinit() failed");
|
||||
}
|
||||
|
||||
datasource_cache::~datasource_cache()
|
||||
|
@ -57,49 +58,43 @@ namespace mapnik
|
|||
std::map<string,boost::shared_ptr<PluginInfo> > datasource_cache::plugins_;
|
||||
bool datasource_cache::registered_=false;
|
||||
|
||||
datasource_ptr datasource_cache::create(const parameters& params)
|
||||
datasource_ptr datasource_cache::create(const parameters& params)
|
||||
{
|
||||
datasource_ptr ds;
|
||||
try
|
||||
{
|
||||
boost::optional<std::string> type = params.get<std::string>("type");
|
||||
if (type)
|
||||
{
|
||||
map<string,boost::shared_ptr<PluginInfo> >::iterator itr=plugins_.find(*type);
|
||||
if (itr!=plugins_.end())
|
||||
{
|
||||
if (itr->second->handle())
|
||||
{
|
||||
create_ds* create_datasource =
|
||||
(create_ds*) lt_dlsym(itr->second->handle(), "create");
|
||||
if (!create_datasource)
|
||||
{
|
||||
std::clog << "Cannot load symbols: " << lt_dlerror() << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
ds=datasource_ptr(create_datasource(params), datasource_deleter());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::clog << "Cannot load library: " << lt_dlerror() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
boost::optional<std::string> type = params.get<std::string>("type");
|
||||
if ( ! type)
|
||||
{
|
||||
throw config_error(string("Could not create datasource. Required ") +
|
||||
"parameter 'type' is missing");
|
||||
}
|
||||
|
||||
datasource_ptr ds;
|
||||
map<string,boost::shared_ptr<PluginInfo> >::iterator itr=plugins_.find(*type);
|
||||
if ( itr == plugins_.end() )
|
||||
{
|
||||
throw config_error(string("Could not create datasource. No plugin ") +
|
||||
"found for type '" + * type + "'");
|
||||
}
|
||||
if ( ! itr->second->handle())
|
||||
{
|
||||
throw std::runtime_error(string("Cannot load library: ") +
|
||||
lt_dlerror());
|
||||
}
|
||||
|
||||
create_ds* create_datasource =
|
||||
(create_ds*) lt_dlsym(itr->second->handle(), "create");
|
||||
|
||||
if ( ! create_datasource)
|
||||
{
|
||||
throw std::runtime_error(string("Cannot load symbols: ") +
|
||||
lt_dlerror());
|
||||
}
|
||||
|
||||
ds=datasource_ptr(create_datasource(params), datasource_deleter());
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog<<"datasource="<<ds<<" type="<<type<<std::endl;
|
||||
std::clog<<"datasource="<<ds<<" type="<<type<<std::endl;
|
||||
#endif
|
||||
}
|
||||
catch (datasource_exception& ex)
|
||||
{
|
||||
std::clog << ex.what() << "\n";
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::clog << " exception caught\n";
|
||||
}
|
||||
return ds;
|
||||
return ds;
|
||||
}
|
||||
|
||||
bool datasource_cache::insert(const std::string& type,const lt_dlhandle module)
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
|
||||
#include <mapnik/font_engine_freetype.hpp>
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
freetype_engine::freetype_engine()
|
||||
|
@ -30,7 +33,7 @@ namespace mapnik
|
|||
FT_Error error = FT_Init_FreeType( &library_ );
|
||||
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,
|
||||
mapnik::CreateStatic>::mutex_);
|
||||
//cerr << "freetype_engine::register_font() '" << file_name << "'" << endl;
|
||||
FT_Face face;
|
||||
FT_Error error = FT_New_Face (library_,file_name.c_str(),0,&face);
|
||||
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,
|
||||
std::string const& type,
|
||||
unsigned width,unsigned height)
|
||||
: pattern_(new ImageData32(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;
|
||||
}
|
||||
}
|
||||
: symbolizer_with_image( file, type, width, height )
|
||||
{ }
|
||||
|
||||
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_;
|
||||
}
|
||||
}
|
||||
|
|
1224
src/load_map.cpp
1224
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()),
|
||||
avoid_edges(sym.get_avoid_edges()),
|
||||
has_dimensions(true),
|
||||
dimensions(std::make_pair(sym.get_background_image()->width(),
|
||||
sym.get_background_image()->height()))
|
||||
dimensions(std::make_pair(sym.get_image()->width(),
|
||||
sym.get_image()->height()))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -205,16 +205,16 @@ namespace mapnik
|
|||
|
||||
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!
|
||||
return ideal_label_distances;
|
||||
}
|
||||
|
||||
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)));
|
||||
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));
|
||||
|
||||
if (p->force_odd_labels && num_labels%2 == 0)
|
||||
|
@ -225,7 +225,7 @@ namespace mapnik
|
|||
double ideal_spacing = distance/num_labels;
|
||||
|
||||
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);
|
||||
else // (p->label_placement == point_placement)
|
||||
middle = distance / 2.0;
|
||||
|
@ -289,9 +289,9 @@ namespace mapnik
|
|||
}
|
||||
p->clear_envelopes();
|
||||
// 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)) ) ||
|
||||
(p->label_placement == point_placement &&
|
||||
(p->label_placement == POINT_PLACEMENT &&
|
||||
build_path_horizontal(p, *itr + (i*s))) )
|
||||
{
|
||||
update_detector(p);
|
||||
|
|
|
@ -68,15 +68,7 @@ namespace mapnik
|
|||
bit_depth_(0),
|
||||
color_type_(0)
|
||||
{
|
||||
try
|
||||
{
|
||||
init();
|
||||
}
|
||||
catch (const ImageReaderException& e)
|
||||
{
|
||||
std::clog << e.what() << '\n';
|
||||
throw;
|
||||
}
|
||||
init();
|
||||
}
|
||||
|
||||
PngReader::~PngReader() {}
|
||||
|
|
|
@ -33,48 +33,25 @@
|
|||
namespace mapnik
|
||||
{
|
||||
point_symbolizer::point_symbolizer()
|
||||
: symbol_(new ImageData32(4,4)),
|
||||
: symbolizer_with_image(boost::shared_ptr<ImageData32>(new ImageData32(4,4))),
|
||||
overlap_(false)
|
||||
{
|
||||
//default point symbol is black 4x4px square
|
||||
symbol_->set(0xff000000);
|
||||
image_->set(0xff000000);
|
||||
}
|
||||
|
||||
point_symbolizer::point_symbolizer(std::string const& file,
|
||||
std::string const& type,
|
||||
unsigned width,unsigned height)
|
||||
: symbol_(new ImageData32(width,height)),
|
||||
: symbolizer_with_image(file, type, width, height),
|
||||
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)
|
||||
: symbol_(rhs.symbol_),
|
||||
: symbolizer_with_image(rhs),
|
||||
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)
|
||||
{
|
||||
overlap_ = overlap;
|
||||
|
|
|
@ -31,24 +31,11 @@ namespace mapnik
|
|||
polygon_pattern_symbolizer::polygon_pattern_symbolizer(std::string const& file,
|
||||
std::string const& type,
|
||||
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)
|
||||
: 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/lexical_cast.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/xml_parser.hpp>
|
||||
// mapnik
|
||||
#include <mapnik/save_map.hpp>
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
|
||||
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;
|
||||
// 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -43,30 +43,8 @@ namespace mapnik
|
|||
std::string const& type,
|
||||
unsigned width,unsigned height)
|
||||
: 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
|
||||
#include <mapnik/text_symbolizer.hpp>
|
||||
|
||||
static const char * label_placement_strings[] = {
|
||||
"point",
|
||||
"line",
|
||||
""
|
||||
};
|
||||
|
||||
IMPLEMENT_ENUM( mapnik::label_placement_e, label_placement_strings );
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
text_symbolizer::text_symbolizer(std::string const& name, std::string const& face_name, unsigned size,Color const& fill)
|
||||
|
@ -44,7 +52,7 @@ namespace mapnik
|
|||
fill_(fill),
|
||||
halo_fill_(Color(255,255,255)),
|
||||
halo_radius_(0),
|
||||
label_p_(point_placement),
|
||||
label_p_(POINT_PLACEMENT),
|
||||
anchor_(0.0,0.5),
|
||||
displacement_(0.0,0.0),
|
||||
avoid_edges_(false),
|
||||
|
|
|
@ -88,21 +88,14 @@ namespace mapnik
|
|||
tile_width_(0),
|
||||
tile_height_(0)
|
||||
{
|
||||
try
|
||||
{
|
||||
init();
|
||||
}
|
||||
catch (ImageReaderException& ex)
|
||||
{
|
||||
std::clog<<ex.what()<<std::endl;
|
||||
throw;
|
||||
}
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
void TiffReader::init()
|
||||
{
|
||||
TIFF* tif = load_if_exists(file_name_);
|
||||
// TODO: error handling
|
||||
TIFF* tif = load_if_exists(file_name_);
|
||||
if (!tif) return;
|
||||
|
||||
char msg[1024];
|
||||
|
|
Loading…
Reference in a new issue