merge and adapt to new features work
This commit is contained in:
commit
95bef08977
195 changed files with 3925 additions and 4341 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -7,6 +7,7 @@
|
|||
*.a
|
||||
*.dylib
|
||||
plugins/input/*.input
|
||||
plugins/input/templates/*.input
|
||||
demo/c++/rundemo
|
||||
bindings/python/mapnik/paths.py
|
||||
config.cache
|
||||
|
|
|
@ -14,6 +14,8 @@ For a complete change history, see the SVN log.
|
|||
Mapnik 2.1.0
|
||||
------------
|
||||
|
||||
- Removed PointDatasource - use more robust MemoryDatasource instead (#1032)
|
||||
|
||||
- SQLite - Added support for !intersects! token in sql subselects (#809) allow custom positioning of rtree spatial filter.
|
||||
|
||||
- New CSV plugin - reads tabular files - autodetecting geo columns, newlines, and delimiters. Uses in-memory featureset for fast rendering and is not designed for large files (#902)
|
||||
|
|
|
@ -247,44 +247,6 @@ class _Datasource(Datasource,_injector):
|
|||
query.add_property_name(fld)
|
||||
return self.features(query)
|
||||
|
||||
class _DeprecatedFeatureProperties(object):
|
||||
|
||||
def __init__(self, feature):
|
||||
self._feature = feature
|
||||
|
||||
def __getitem__(self, name):
|
||||
warnings.warn("indexing feature.properties is deprecated, index the "
|
||||
"feature object itself for the same effect", DeprecationWarning, 2)
|
||||
return self._feature[name]
|
||||
|
||||
def __iter__(self):
|
||||
warnings.warn("iterating feature.properties is deprecated, iterate the "
|
||||
"feature object itself for the same effect", DeprecationWarning, 2)
|
||||
return iter(self._feature)
|
||||
|
||||
class _Feature(Feature, _injector):
|
||||
"""
|
||||
A Feature.
|
||||
|
||||
TODO: docs
|
||||
"""
|
||||
@property
|
||||
def properties(self):
|
||||
return _DeprecatedFeatureProperties(self)
|
||||
|
||||
@property
|
||||
def attributes(self):
|
||||
#XXX Returns a copy! changes to it won't affect feat.'s attrs.
|
||||
# maybe deprecate?
|
||||
return dict(self)
|
||||
|
||||
def __init__(self, id, wkt=None, **properties):
|
||||
Feature._c___init__(self, id)
|
||||
if wkt is not None:
|
||||
self.add_geometries_from_wkt(wkt)
|
||||
for k, v in properties.iteritems():
|
||||
self[k] = v
|
||||
|
||||
class _Color(Color,_injector):
|
||||
def __repr__(self):
|
||||
return "Color(R=%d,G=%d,B=%d,A=%d)" % (self.r,self.g,self.b,self.a)
|
||||
|
@ -649,7 +611,6 @@ __all__ = [
|
|||
'FontEngine',
|
||||
'FontSet',
|
||||
'Geometry2d',
|
||||
'GlyphSymbolizer',
|
||||
'Image',
|
||||
'ImageView',
|
||||
'Grid',
|
||||
|
@ -664,7 +625,6 @@ __all__ = [
|
|||
'Path',
|
||||
'Parameter',
|
||||
'Parameters',
|
||||
'PointDatasource',
|
||||
'PointSymbolizer',
|
||||
'PolygonPatternSymbolizer',
|
||||
'PolygonSymbolizer',
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
|
||||
|
||||
using mapnik::datasource;
|
||||
using mapnik::point_datasource;
|
||||
using mapnik::memory_datasource;
|
||||
using mapnik::layer_descriptor;
|
||||
using mapnik::attribute_descriptor;
|
||||
|
@ -197,11 +196,6 @@ void export_datasource()
|
|||
|
||||
def("CreateDatasource",&create_datasource);
|
||||
|
||||
class_<point_datasource, bases<datasource>, boost::noncopyable>("PointDatasource", init<>())
|
||||
.def("add_point",&point_datasource::add_point)
|
||||
;
|
||||
|
||||
|
||||
class_<memory_datasource, bases<datasource>, boost::noncopyable>("MemoryDatasource", init<>())
|
||||
.def("add_feature",&memory_datasource::push,
|
||||
"Adds a Feature:\n"
|
||||
|
|
|
@ -22,26 +22,35 @@
|
|||
//$Id$
|
||||
|
||||
// boost
|
||||
|
||||
#include <boost/python/suite/indexing/indexing_suite.hpp>
|
||||
//#include <boost/python/suite/indexing/map_indexing_suite.hpp>
|
||||
|
||||
#include <boost/python/iterator.hpp>
|
||||
#include <boost/python/call_method.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
#include <boost/python/to_python_converter.hpp>
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/feature_kv_iterator.hpp>
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/wkb.hpp>
|
||||
#include <mapnik/wkt/wkt_factory.hpp>
|
||||
|
||||
mapnik::geometry_type & (mapnik::Feature::*get_geom1)(unsigned) = &mapnik::Feature::get_geometry;
|
||||
|
||||
namespace {
|
||||
|
||||
using mapnik::Feature;
|
||||
using mapnik::geometry_utils;
|
||||
using mapnik::from_wkt;
|
||||
using mapnik::context_type;
|
||||
using mapnik::context_ptr;
|
||||
using mapnik::feature_kv_iterator;
|
||||
|
||||
mapnik::geometry_type const& (mapnik::Feature::*get_geometry_by_const_ref)(unsigned) const = &mapnik::Feature::get_geometry;
|
||||
boost::ptr_vector<mapnik::geometry_type> const& (mapnik::Feature::*get_paths_by_const_ref)() const = &mapnik::Feature::paths;
|
||||
|
||||
void feature_add_geometries_from_wkb(Feature &feature, std::string wkb)
|
||||
{
|
||||
|
@ -54,152 +63,36 @@ void feature_add_geometries_from_wkt(Feature &feature, std::string wkt)
|
|||
if (!result) throw std::runtime_error("Failed to parse WKT");
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
mapnik::value __getitem__(Feature const& feature, std::string const& name)
|
||||
{
|
||||
return feature.get(name);
|
||||
}
|
||||
|
||||
namespace boost { namespace python {
|
||||
mapnik::value __getitem2__(Feature const& feature, std::size_t index)
|
||||
{
|
||||
return feature.get(index);
|
||||
}
|
||||
|
||||
// Forward declaration
|
||||
template <class Container, bool NoProxy, class DerivedPolicies>
|
||||
class map_indexing_suite2;
|
||||
void __setitem__(Feature & feature, std::string const& name, mapnik::value const& val)
|
||||
{
|
||||
feature.put_new(name,val);
|
||||
}
|
||||
|
||||
namespace detail
|
||||
boost::python::dict attributes(Feature const& f)
|
||||
{
|
||||
boost::python::dict attributes;
|
||||
feature_kv_iterator itr = f.begin();
|
||||
feature_kv_iterator end = f.end();
|
||||
|
||||
for ( ;itr!=end; ++itr)
|
||||
{
|
||||
template <class Container, bool NoProxy>
|
||||
class final_map_derived_policies
|
||||
: public map_indexing_suite2<Container,
|
||||
NoProxy, final_map_derived_policies<Container, NoProxy> > {};
|
||||
attributes[boost::get<0>(*itr)] = boost::get<1>(*itr);
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
template <class Container,bool NoProxy = false,
|
||||
class DerivedPolicies = detail::final_map_derived_policies<Container, NoProxy> >
|
||||
class map_indexing_suite2
|
||||
: public indexing_suite<
|
||||
Container
|
||||
, DerivedPolicies
|
||||
, NoProxy
|
||||
, true
|
||||
, typename Container::value_type::second_type
|
||||
, typename Container::key_type
|
||||
, typename Container::key_type
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef typename Container::value_type::second_type data_type;
|
||||
typedef typename Container::key_type key_type;
|
||||
typedef typename Container::key_type index_type;
|
||||
typedef typename Container::size_type size_type;
|
||||
typedef typename Container::difference_type difference_type;
|
||||
|
||||
template <class Class>
|
||||
static void
|
||||
extension_def(Class& cl)
|
||||
{
|
||||
cl
|
||||
.def("get", &get)
|
||||
;
|
||||
}
|
||||
|
||||
static data_type&
|
||||
get_item(Container& container, index_type i_)
|
||||
{
|
||||
typename Container::iterator i = container.props().find(i_);
|
||||
if (i == container.end())
|
||||
{
|
||||
PyErr_SetString(PyExc_KeyError, i_.c_str());
|
||||
throw_error_already_set();
|
||||
}
|
||||
// will be auto-converted to proper python type by `mapnik_value_to_python`
|
||||
return i->second;
|
||||
}
|
||||
|
||||
static data_type
|
||||
get(Container& container, index_type i_)
|
||||
{
|
||||
typename Container::iterator i = container.props().find(i_);
|
||||
if (i != container.end())
|
||||
{
|
||||
// will be auto-converted to proper python type by `mapnik_value_to_python`
|
||||
return i->second;
|
||||
}
|
||||
return mapnik::value_null();
|
||||
}
|
||||
|
||||
static void
|
||||
set_item(Container& container, index_type i, data_type const& v)
|
||||
{
|
||||
container[i] = v;
|
||||
}
|
||||
|
||||
static void
|
||||
delete_item(Container& container, index_type i)
|
||||
{
|
||||
container.props().erase(i);
|
||||
}
|
||||
|
||||
static size_t
|
||||
size(Container& container)
|
||||
{
|
||||
return container.props().size();
|
||||
}
|
||||
|
||||
static bool
|
||||
contains(Container& container, key_type const& key)
|
||||
{
|
||||
return container.props().find(key) != container.end();
|
||||
}
|
||||
|
||||
static bool
|
||||
compare_index(Container& container, index_type a, index_type b)
|
||||
{
|
||||
return container.props().key_comp()(a, b);
|
||||
}
|
||||
|
||||
static index_type
|
||||
convert_index(Container& /*container*/, PyObject* i_)
|
||||
{
|
||||
extract<key_type const&> i(i_);
|
||||
if (i.check())
|
||||
{
|
||||
return i();
|
||||
}
|
||||
else
|
||||
{
|
||||
extract<key_type> i(i_);
|
||||
if (i.check())
|
||||
return i();
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Invalid index type");
|
||||
throw_error_already_set();
|
||||
return index_type();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct std_pair_to_tuple
|
||||
{
|
||||
static PyObject* convert(std::pair<T1, T2> const& p)
|
||||
{
|
||||
return boost::python::incref(
|
||||
boost::python::make_tuple(p.first, p.second).ptr());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct std_pair_to_python_converter
|
||||
{
|
||||
std_pair_to_python_converter()
|
||||
{
|
||||
boost::python::to_python_converter<
|
||||
std::pair<T1, T2>,
|
||||
std_pair_to_tuple<T1, T2> >();
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
} // end anonymous namespace
|
||||
|
||||
struct UnicodeString_from_python_str
|
||||
{
|
||||
|
@ -260,27 +153,36 @@ void export_feature()
|
|||
using namespace boost::python;
|
||||
using mapnik::Feature;
|
||||
|
||||
// Python to mapnik::value converters
|
||||
implicitly_convertible<int,mapnik::value>();
|
||||
implicitly_convertible<double,mapnik::value>();
|
||||
implicitly_convertible<UnicodeString,mapnik::value>();
|
||||
implicitly_convertible<bool,mapnik::value>();
|
||||
|
||||
std_pair_to_python_converter<std::string const,mapnik::value>();
|
||||
|
||||
UnicodeString_from_python_str();
|
||||
|
||||
|
||||
class_<context_type,context_ptr,boost::noncopyable>
|
||||
("Context",init<>("Default ctor."))
|
||||
.def("push", &context_type::push)
|
||||
;
|
||||
|
||||
class_<Feature,boost::shared_ptr<Feature>,
|
||||
boost::noncopyable>("Feature",init<int>("Default ctor."))
|
||||
boost::noncopyable>("Feature",init<context_ptr,int>("Default ctor."))
|
||||
.def("id",&Feature::id)
|
||||
.def("__str__",&Feature::to_string)
|
||||
.def("add_geometries_from_wkb", &feature_add_geometries_from_wkb)
|
||||
.def("add_geometries_from_wkt", &feature_add_geometries_from_wkt)
|
||||
//.def("add_geometry", add_geometry)
|
||||
//.def("num_geometries",&Feature::num_geometries)
|
||||
//.def("get_geometry", make_function(get_geom1,return_value_policy<reference_existing_object>()))
|
||||
.def("geometries",make_function(&Feature::paths,return_value_policy<reference_existing_object>()))
|
||||
.def("add_geometry", &Feature::add_geometry)
|
||||
.def("num_geometries",&Feature::num_geometries)
|
||||
.def("get_geometry", make_function(get_geometry_by_const_ref,return_value_policy<reference_existing_object>()))
|
||||
.def("geometries",make_function(get_paths_by_const_ref,return_value_policy<reference_existing_object>()))
|
||||
.def("envelope", &Feature::envelope)
|
||||
.def(map_indexing_suite2<Feature, true >())
|
||||
.def("iteritems",iterator<Feature> ())
|
||||
// TODO define more mapnik::Feature methods
|
||||
.def("has_key", &Feature::has_key)
|
||||
.add_property("attributes",&attributes)
|
||||
.def("__setitem__",&__setitem__)
|
||||
.def("__getitem__",&__getitem__)
|
||||
.def("__getitem__",&__getitem2__)
|
||||
.def("__len__", &Feature::size)
|
||||
.def("context",&Feature::context)
|
||||
;
|
||||
}
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
#include <boost/python.hpp>
|
||||
|
||||
#include <mapnik/glyph_symbolizer.hpp>
|
||||
#include "mapnik_enumeration.hpp"
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
using mapnik::glyph_symbolizer;
|
||||
using mapnik::position;
|
||||
using mapnik::enumeration_;
|
||||
using mapnik::angle_mode_e;
|
||||
using mapnik::AZIMUTH;
|
||||
using mapnik::TRIGONOMETRIC;
|
||||
using namespace boost::python;
|
||||
|
||||
namespace {
|
||||
using namespace boost::python;
|
||||
|
||||
tuple get_displacement(const glyph_symbolizer& s)
|
||||
{
|
||||
boost::tuple<double,double> pos = s.get_displacement();
|
||||
return boost::python::make_tuple(boost::get<0>(pos),boost::get<1>(pos));
|
||||
}
|
||||
|
||||
void set_displacement(glyph_symbolizer & s, boost::python::tuple arg)
|
||||
{
|
||||
s.set_displacement(extract<double>(arg[0]),extract<double>(arg[1]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void export_glyph_symbolizer()
|
||||
{
|
||||
enumeration_<angle_mode_e>("angle_mode")
|
||||
.value("AZIMUTH", AZIMUTH)
|
||||
.value("TRIGONOMETRIC", TRIGONOMETRIC)
|
||||
;
|
||||
|
||||
class_<glyph_symbolizer>("GlyphSymbolizer",
|
||||
init<std::string,mapnik::expression_ptr>())
|
||||
.add_property("face_name",
|
||||
make_function(&glyph_symbolizer::get_face_name,
|
||||
return_value_policy<copy_const_reference>()),
|
||||
&glyph_symbolizer::set_face_name,
|
||||
"Get/Set the name of the font face (eg:\"DejaVu Sans "
|
||||
"Book\") which contains the glyph"
|
||||
)
|
||||
.add_property("char",
|
||||
&glyph_symbolizer::get_char,
|
||||
&glyph_symbolizer::set_char,
|
||||
"Get/Set the char expression. The char is the unicode "
|
||||
"character indexing the glyph in the font referred by "
|
||||
"face_name."
|
||||
)
|
||||
.add_property("allow_overlap",
|
||||
&glyph_symbolizer::get_allow_overlap,
|
||||
&glyph_symbolizer::set_allow_overlap,
|
||||
"Get/Set the flag which controls if glyphs should "
|
||||
"overlap any symbols previously rendered"
|
||||
)
|
||||
.add_property("avoid_edges",
|
||||
&glyph_symbolizer::get_avoid_edges,
|
||||
&glyph_symbolizer::set_avoid_edges,
|
||||
"Get/Set the flag which controls if glyphs should be "
|
||||
"partially drawn beside the edge of a tile."
|
||||
)
|
||||
.add_property("displacement",
|
||||
&get_displacement,
|
||||
&set_displacement)
|
||||
|
||||
.add_property("halo_fill",
|
||||
make_function(&glyph_symbolizer::get_halo_fill,
|
||||
return_value_policy<copy_const_reference>()),
|
||||
&glyph_symbolizer::set_halo_fill)
|
||||
|
||||
.add_property("halo_radius",
|
||||
&glyph_symbolizer::get_halo_radius,
|
||||
&glyph_symbolizer::set_halo_radius)
|
||||
|
||||
.add_property("size",
|
||||
&glyph_symbolizer::get_size,
|
||||
&glyph_symbolizer::set_size,
|
||||
"Get/Set the size expression used to size the glyph."
|
||||
)
|
||||
|
||||
.add_property("angle",
|
||||
&glyph_symbolizer::get_angle,
|
||||
&glyph_symbolizer::set_angle,
|
||||
"Get/Set the angle expression used to rotate the glyph "
|
||||
"along its center."
|
||||
)
|
||||
.add_property("angle_mode",
|
||||
&glyph_symbolizer::get_angle_mode,
|
||||
&glyph_symbolizer::set_angle_mode,
|
||||
"Get/Set the angle_mode property. This controls how the "
|
||||
"angle is interpreted. Valid values are AZIMUTH and "
|
||||
"TRIGONOMETRIC."
|
||||
)
|
||||
.add_property("value",
|
||||
&glyph_symbolizer::get_value,
|
||||
&glyph_symbolizer::set_value,
|
||||
"Get/set the value expression which will be used to "
|
||||
"retrieve a a value for the colorizer to use to choose "
|
||||
"a color."
|
||||
)
|
||||
.add_property("color",
|
||||
&glyph_symbolizer::get_color,
|
||||
&glyph_symbolizer::set_color,
|
||||
"Get/Set the color expression used to color the glyph. "
|
||||
"(See also the 'colorizer' attribute)"
|
||||
|
||||
)
|
||||
.add_property("colorizer",
|
||||
&glyph_symbolizer::get_colorizer,
|
||||
&glyph_symbolizer::set_colorizer,
|
||||
"Get/Set the RasterColorizer used to color the glyph "
|
||||
"depending on the 'value' expression (which must be "
|
||||
"defined).\n"
|
||||
"Only needed if no explicit color is provided"
|
||||
)
|
||||
;
|
||||
}
|
|
@ -43,11 +43,14 @@ static boost::shared_ptr<mapnik::rgba_palette> make_palette( const std::string&
|
|||
void export_palette ()
|
||||
{
|
||||
using namespace boost::python;
|
||||
class_<boost::shared_ptr<mapnik::rgba_palette> >("Palette",no_init)
|
||||
/*, init<std::string,std::string>(
|
||||
( arg("palette"), arg("type")),
|
||||
"Creates a new color palette from a file\n"
|
||||
)*/
|
||||
.def( "__init__", boost::python::make_constructor(make_palette))
|
||||
|
||||
class_<mapnik::rgba_palette,
|
||||
boost::shared_ptr<mapnik::rgba_palette>,
|
||||
boost::noncopyable >("Palette",no_init)
|
||||
//, init<std::string,std::string>(
|
||||
// ( arg("palette"), arg("type")),
|
||||
// "Creates a new color palette from a file\n"
|
||||
// )
|
||||
.def( "__init__", boost::python::make_constructor(make_palette))
|
||||
;
|
||||
}
|
||||
|
|
|
@ -66,7 +66,6 @@ void export_projection();
|
|||
void export_proj_transform();
|
||||
void export_view_transform();
|
||||
void export_raster_colorizer();
|
||||
void export_glyph_symbolizer();
|
||||
void export_inmem_metawriter();
|
||||
void export_label_collision_detector();
|
||||
|
||||
|
@ -84,6 +83,7 @@ void export_label_collision_detector();
|
|||
#include <mapnik/scale_denominator.hpp>
|
||||
#include <mapnik/value_error.hpp>
|
||||
#include <mapnik/save_map.hpp>
|
||||
#include <mapnik/scale_denominator.hpp>
|
||||
#include "python_grid_utils.hpp"
|
||||
#include "mapnik_value_converter.hpp"
|
||||
#include "python_optional.hpp"
|
||||
|
@ -434,7 +434,6 @@ BOOST_PYTHON_MODULE(_mapnik)
|
|||
export_coord();
|
||||
export_map();
|
||||
export_raster_colorizer();
|
||||
export_glyph_symbolizer();
|
||||
export_inmem_metawriter();
|
||||
export_label_collision_detector();
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@ using mapnik::shield_symbolizer;
|
|||
using mapnik::text_symbolizer;
|
||||
using mapnik::building_symbolizer;
|
||||
using mapnik::markers_symbolizer;
|
||||
using mapnik::glyph_symbolizer;
|
||||
using mapnik::symbolizer;
|
||||
using mapnik::to_expression_string;
|
||||
|
||||
|
@ -162,7 +161,6 @@ void export_rule()
|
|||
implicitly_convertible<raster_symbolizer,symbolizer>();
|
||||
implicitly_convertible<shield_symbolizer,symbolizer>();
|
||||
implicitly_convertible<text_symbolizer,symbolizer>();
|
||||
implicitly_convertible<glyph_symbolizer,symbolizer>();
|
||||
implicitly_convertible<markers_symbolizer,symbolizer>();
|
||||
|
||||
class_<rule::symbolizers>("Symbolizers",init<>("TODO"))
|
||||
|
|
|
@ -64,17 +64,6 @@ void set_text_displacement(shield_symbolizer & t, boost::python::tuple arg)
|
|||
t.set_displacement(extract<double>(arg[0]),extract<double>(arg[1]));
|
||||
}
|
||||
|
||||
tuple get_anchor(const shield_symbolizer& t)
|
||||
{
|
||||
boost::tuple<double,double> pos = t.get_anchor();
|
||||
return boost::python::make_tuple(boost::get<0>(pos),boost::get<1>(pos));
|
||||
}
|
||||
|
||||
void set_anchor(shield_symbolizer & t, boost::python::tuple arg)
|
||||
{
|
||||
t.set_anchor(extract<double>(arg[0]),extract<double>(arg[1]));
|
||||
}
|
||||
|
||||
const std::string get_filename(shield_symbolizer const& t)
|
||||
{
|
||||
return path_processor_type::to_string(*t.get_filename());
|
||||
|
@ -137,9 +126,6 @@ void export_shield_symbolizer()
|
|||
path_expression_ptr>("TODO")
|
||||
)
|
||||
//.def_pickle(shield_symbolizer_pickle_suite())
|
||||
.add_property("anchor",
|
||||
&get_anchor,
|
||||
&set_anchor)
|
||||
.add_property("allow_overlap",
|
||||
&shield_symbolizer::get_allow_overlap,
|
||||
&shield_symbolizer::set_allow_overlap,
|
||||
|
|
|
@ -39,7 +39,6 @@ using mapnik::shield_symbolizer;
|
|||
using mapnik::text_symbolizer;
|
||||
using mapnik::building_symbolizer;
|
||||
using mapnik::markers_symbolizer;
|
||||
using mapnik::glyph_symbolizer;
|
||||
|
||||
struct get_symbolizer_type : public boost::static_visitor<std::string>
|
||||
{
|
||||
|
@ -95,12 +94,6 @@ public:
|
|||
{
|
||||
return "markers";
|
||||
}
|
||||
|
||||
std::string operator () ( const glyph_symbolizer & /*sym*/ )
|
||||
{
|
||||
return "glyph";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
std::string get_symbol_type(const symbolizer& symbol)
|
||||
|
@ -160,11 +153,6 @@ const markers_symbolizer& markers_( const symbolizer& symbol )
|
|||
return boost::get<markers_symbolizer>(symbol);
|
||||
}
|
||||
|
||||
const glyph_symbolizer& glyph_( const symbolizer& symbol )
|
||||
{
|
||||
return boost::get<glyph_symbolizer>(symbol);
|
||||
}
|
||||
|
||||
void export_symbolizer()
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
@ -202,10 +190,6 @@ void export_symbolizer()
|
|||
|
||||
.def("markers",markers_,
|
||||
return_value_policy<copy_const_reference>())
|
||||
|
||||
.def("glyph",glyph_,
|
||||
return_value_policy<copy_const_reference>())
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,17 +48,6 @@ void set_text_displacement(text_symbolizer & t, boost::python::tuple arg)
|
|||
t.set_displacement(extract<double>(arg[0]),extract<double>(arg[1]));
|
||||
}
|
||||
|
||||
tuple get_anchor(const text_symbolizer& t)
|
||||
{
|
||||
position pos = t.get_anchor();
|
||||
return boost::python::make_tuple(boost::get<0>(pos),boost::get<1>(pos));
|
||||
}
|
||||
|
||||
void set_anchor(text_symbolizer & t, boost::python::tuple arg)
|
||||
{
|
||||
t.set_anchor(extract<double>(arg[0]),extract<double>(arg[1]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct text_symbolizer_pickle_suite : boost::python::pickle_suite
|
||||
|
@ -76,7 +65,6 @@ struct text_symbolizer_pickle_suite : boost::python::pickle_suite
|
|||
getstate(const text_symbolizer& t)
|
||||
{
|
||||
boost::python::tuple disp = get_text_displacement(t);
|
||||
boost::python::tuple anchor = get_anchor(t);
|
||||
|
||||
// so we do not exceed max args accepted by make_tuple,
|
||||
// lets put the increasing list of parameters in a list
|
||||
|
@ -95,7 +83,7 @@ struct text_symbolizer_pickle_suite : boost::python::pickle_suite
|
|||
return boost::python::make_tuple(disp,t.get_label_placement(),
|
||||
t.get_vertical_alignment(),t.get_halo_radius(),t.get_halo_fill(),t.get_text_ratio(),
|
||||
t.get_wrap_width(),t.get_label_spacing(),t.get_minimum_distance(),t.get_allow_overlap(),
|
||||
anchor,t.get_force_odd_labels(),t.get_max_char_angle_delta(),extras
|
||||
t.get_force_odd_labels(),t.get_max_char_angle_delta(),extras
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -136,15 +124,10 @@ struct text_symbolizer_pickle_suite : boost::python::pickle_suite
|
|||
|
||||
t.set_allow_overlap(extract<bool>(state[9]));
|
||||
|
||||
tuple anch = extract<tuple>(state[10]);
|
||||
double x = extract<double>(anch[0]);
|
||||
double y = extract<double>(anch[1]);
|
||||
t.set_anchor(x,y);
|
||||
t.set_force_odd_labels(extract<bool>(state[10]));
|
||||
|
||||
t.set_force_odd_labels(extract<bool>(state[11]));
|
||||
|
||||
t.set_max_char_angle_delta(extract<double>(state[12]));
|
||||
list extras = extract<list>(state[13]);
|
||||
t.set_max_char_angle_delta(extract<double>(state[11]));
|
||||
list extras = extract<list>(state[12]);
|
||||
t.set_wrap_char_from_string(extract<std::string>(extras[0]));
|
||||
t.set_line_spacing(extract<unsigned>(extras[1]));
|
||||
t.set_character_spacing(extract<unsigned>(extras[2]));
|
||||
|
@ -180,6 +163,7 @@ void export_text_symbolizer()
|
|||
.value("LEFT",H_LEFT)
|
||||
.value("MIDDLE",H_MIDDLE)
|
||||
.value("RIGHT",H_RIGHT)
|
||||
.value("AUTO",H_AUTO)
|
||||
;
|
||||
|
||||
enumeration_<justify_alignment_e>("justify_alignment")
|
||||
|
@ -211,9 +195,6 @@ void export_text_symbolizer()
|
|||
*/
|
||||
|
||||
//.def_pickle(text_symbolizer_pickle_suite())
|
||||
.add_property("anchor",
|
||||
&get_anchor,
|
||||
&set_anchor)
|
||||
.add_property("allow_overlap",
|
||||
&text_symbolizer::get_allow_overlap,
|
||||
&text_symbolizer::set_allow_overlap,
|
||||
|
|
|
@ -368,6 +368,18 @@ if HAS_PYCAIRO_MODULE and mapnik.has_pycairo():
|
|||
images_.append('demo.ps')
|
||||
postscript_surface.finish()
|
||||
|
||||
image_surface = cairo.ImageSurface(cairo.FORMAT_RGB24, m.width, m.height)
|
||||
mapnik.render(m, image_surface)
|
||||
image_surface.write_to_png('demo_cairo_rgb24.png')
|
||||
images_.append('demo_cairo_argb24.png')
|
||||
image_surface.finish()
|
||||
|
||||
image_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, m.width, m.height)
|
||||
mapnik.render(m, image_surface)
|
||||
image_surface.write_to_png('demo_cairo_argb32.png')
|
||||
images_.append('demo_cairo_argb32.png')
|
||||
image_surface.finish()
|
||||
|
||||
else:
|
||||
print '\n\nPycairo not available...',
|
||||
if mapnik.has_cairo():
|
||||
|
@ -379,9 +391,9 @@ else:
|
|||
images_.append('demo.ps')
|
||||
mapnik.render_to_file(m,'demo.svg')
|
||||
images_.append('demo.svg')
|
||||
mapnik.render_to_file(m,'demo_cairo_rgb.png','RGB24')
|
||||
mapnik.render_to_file(m,'demo_cairo_rgb24.png','RGB24')
|
||||
images_.append('demo_cairo_rgb.png')
|
||||
mapnik.render_to_file(m,'demo_cairo_argb.png','ARGB32')
|
||||
mapnik.render_to_file(m,'demo_cairo_argb32.png','ARGB32')
|
||||
images_.append('demo_cairo_argb.png')
|
||||
|
||||
print "\n\n", len(images_), "maps have been rendered in the current directory:"
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <mapnik/scale_denominator.hpp>
|
||||
#include <mapnik/ctrans.hpp>
|
||||
#include <mapnik/memory_datasource.hpp>
|
||||
#include <mapnik/feature_kv_iterator.hpp>
|
||||
#include "mapwidget.hpp"
|
||||
#include "info_dialog.hpp"
|
||||
|
||||
|
@ -42,6 +43,7 @@ using mapnik::geometry_ptr;
|
|||
using mapnik::CoordTransform;
|
||||
using mapnik::projection;
|
||||
using mapnik::scale_denominator;
|
||||
using mapnik::feature_kv_iterator;
|
||||
|
||||
double scales [] = {279541132.014,
|
||||
139770566.007,
|
||||
|
@ -170,17 +172,17 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
|
|||
feature_ptr feat = fs->next();
|
||||
if (feat)
|
||||
{
|
||||
std::map<std::string,mapnik::value> const& props = feat->props();
|
||||
std::map<std::string,mapnik::value>::const_iterator itr=props.begin();
|
||||
for (; itr!=props.end();++itr)
|
||||
{
|
||||
if (itr->second.to_string().length() > 0)
|
||||
{
|
||||
info.push_back(QPair<QString,QString>(QString(itr->first.c_str()),
|
||||
itr->second.to_string().c_str()));
|
||||
}
|
||||
}
|
||||
typedef mapnik::coord_transform2<mapnik::CoordTransform,mapnik::geometry_type> path_type;
|
||||
|
||||
feature_kv_iterator itr(*feat,true);
|
||||
feature_kv_iterator end(*feat);
|
||||
|
||||
for ( ;itr!=end; ++itr)
|
||||
{
|
||||
info.push_back(QPair<QString,QString>(QString(boost::get<0>(*itr).c_str()),
|
||||
boost::get<1>(*itr).to_string().c_str()));
|
||||
}
|
||||
|
||||
typedef mapnik::coord_transform2<mapnik::CoordTransform,mapnik::geometry_type> path_type;
|
||||
|
||||
for (unsigned i=0; i<feat->num_geometries();++i)
|
||||
{
|
||||
|
|
24
docs/textrendering.gv
Normal file
24
docs/textrendering.gv
Normal file
|
@ -0,0 +1,24 @@
|
|||
#process with: dot textrendering.gv -Tpng > textrendering.png
|
||||
digraph textrendering {
|
||||
# Classes without important virtual members: Round
|
||||
# Classes with important virtual members: Rect
|
||||
# Pointers [style=dashed]
|
||||
# Red: function is called
|
||||
text_placements[shape=box]
|
||||
text_placement_info[shape=box]
|
||||
Renderer
|
||||
|
||||
TextSymbolizer -> text_placements [label="placement_options_", style=dashed]
|
||||
text_placements -> text_symbolizer_properties [label="properties"]
|
||||
text_placements -> text_placement_info [label="get_placement_info()", style=dashed]
|
||||
text_placement_info -> text_symbolizer_properties [label="properties"]
|
||||
text_placement_info -> text_path [label="placements", style=dashed]
|
||||
text_placement_info -> text_placement_info [label="next()"]
|
||||
text_symbolizer_properties -> text_processor [label="processor"]
|
||||
text_processor -> processed_text [label="process()", style=dashed]
|
||||
processed_text -> string_info [label="get_string_info()"]
|
||||
text_path -> Renderer [color=red, label="used by"]
|
||||
Renderer -> text_placement_info [color=red, label="init()"]
|
||||
Renderer -> processed_text [color=red, label="initializes"]
|
||||
|
||||
}
|
|
@ -101,10 +101,7 @@ public:
|
|||
proj_transform const& prj_trans);
|
||||
void process(markers_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans);
|
||||
void process(glyph_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans);
|
||||
proj_transform const& prj_trans);
|
||||
inline bool process(rule::symbolizers const& /*syms*/,
|
||||
Feature const& /*feature*/,
|
||||
proj_transform const& /*prj_trans*/)
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
|
||||
namespace mapnik {
|
||||
|
||||
static mapnik::value _null_value;
|
||||
|
||||
struct attribute
|
||||
{
|
||||
std::string name_;
|
||||
|
@ -39,16 +37,11 @@ struct attribute
|
|||
: name_(name) {}
|
||||
|
||||
template <typename V ,typename F>
|
||||
V value(F const& f) const
|
||||
V const& value(F const& f) const
|
||||
{
|
||||
typedef typename F::const_iterator const_iterator;
|
||||
const_iterator itr = f.find(name_);
|
||||
if (itr != f.end())
|
||||
{
|
||||
return itr->second;
|
||||
}
|
||||
return _null_value;
|
||||
return f.get(name_);
|
||||
}
|
||||
|
||||
std::string const& name() const { return name_;}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -24,16 +24,11 @@
|
|||
#define MAPNIK_ATTRIBUTE_COLLECTOR_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
#include <mapnik/rule.hpp>
|
||||
#include <mapnik/path_expression_grammar.hpp>
|
||||
#include <mapnik/parse_path.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
|
||||
// stl
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
|
@ -93,18 +88,12 @@ struct symbolizer_attributes : public boost::static_visitor<>
|
|||
|
||||
void operator () (text_symbolizer const& sym)
|
||||
{
|
||||
expression_ptr const& name_expr = sym.get_name();
|
||||
if (name_expr)
|
||||
std::set<expression_ptr>::const_iterator it;
|
||||
std::set<expression_ptr> expressions = sym.get_placement_options()->get_all_expressions();
|
||||
expression_attributes f_attr(names_);
|
||||
for (it=expressions.begin(); it != expressions.end(); it++)
|
||||
{
|
||||
expression_attributes f_attr(names_);
|
||||
boost::apply_visitor(f_attr,*name_expr);
|
||||
}
|
||||
|
||||
expression_ptr const& orientation_expr = sym.get_orientation();
|
||||
if (orientation_expr)
|
||||
{
|
||||
expression_attributes f_attr(names_);
|
||||
boost::apply_visitor(f_attr,*orientation_expr);
|
||||
if (*it) boost::apply_visitor(f_attr, **it);
|
||||
}
|
||||
collect_metawriter(sym);
|
||||
}
|
||||
|
@ -152,11 +141,12 @@ struct symbolizer_attributes : public boost::static_visitor<>
|
|||
|
||||
void operator () (shield_symbolizer const& sym)
|
||||
{
|
||||
expression_ptr const& name_expr = sym.get_name();
|
||||
if (name_expr)
|
||||
std::set<expression_ptr>::const_iterator it;
|
||||
std::set<expression_ptr> expressions = sym.get_placement_options()->get_all_expressions();
|
||||
expression_attributes f_attr(names_);
|
||||
for (it=expressions.begin(); it != expressions.end(); it++)
|
||||
{
|
||||
expression_attributes name_attr(names_);
|
||||
boost::apply_visitor(name_attr,*name_expr);
|
||||
if (*it) boost::apply_visitor(f_attr, **it);
|
||||
}
|
||||
|
||||
path_expression_ptr const& filename_expr = sym.get_filename();
|
||||
|
@ -167,45 +157,6 @@ struct symbolizer_attributes : public boost::static_visitor<>
|
|||
collect_metawriter(sym);
|
||||
}
|
||||
|
||||
void operator () (glyph_symbolizer const& sym)
|
||||
{
|
||||
expression_ptr const& char_expr = sym.get_char();
|
||||
if (char_expr)
|
||||
{
|
||||
expression_attributes f_attr(names_);
|
||||
boost::apply_visitor(f_attr,*char_expr);
|
||||
}
|
||||
|
||||
expression_ptr const& angle_expr = sym.get_angle();
|
||||
if (angle_expr)
|
||||
{
|
||||
expression_attributes f_attr(names_);
|
||||
boost::apply_visitor(f_attr,*angle_expr);
|
||||
}
|
||||
|
||||
expression_ptr const& value_expr = sym.get_value();
|
||||
if (value_expr)
|
||||
{
|
||||
expression_attributes f_attr(names_);
|
||||
boost::apply_visitor(f_attr,*value_expr);
|
||||
}
|
||||
|
||||
expression_ptr const& size_expr = sym.get_size();
|
||||
if (size_expr)
|
||||
{
|
||||
expression_attributes f_attr(names_);
|
||||
boost::apply_visitor(f_attr,*size_expr);
|
||||
}
|
||||
|
||||
expression_ptr const& color_expr = sym.get_color();
|
||||
if (color_expr)
|
||||
{
|
||||
expression_attributes f_attr(names_);
|
||||
boost::apply_visitor(f_attr,*color_expr);
|
||||
}
|
||||
collect_metawriter(sym);
|
||||
}
|
||||
|
||||
void operator () (markers_symbolizer const& sym)
|
||||
{
|
||||
collect_metawriter(sym);
|
||||
|
|
|
@ -20,34 +20,34 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAPNIK_LABEL_PLACEMENT_HPP
|
||||
#define MAPNIK_LABEL_PLACEMENT_HPP
|
||||
#ifndef MAPNIK_BUILDING_SYMBOLIZER_HPP
|
||||
#define MAPNIK_BUILDING_SYMBOLIZER_HPP
|
||||
|
||||
namespace mapnik
|
||||
// mapnik
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
#include <mapnik/filter_factory.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
struct point_
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
point_()
|
||||
: x(0),y(0) {}
|
||||
point_(double x_,double y_)
|
||||
: x(x_),y(y_) {}
|
||||
};
|
||||
|
||||
class label_placement
|
||||
|
||||
struct MAPNIK_DECL building_symbolizer : public symbolizer_base
|
||||
{
|
||||
building_symbolizer();
|
||||
building_symbolizer(color const& fill, expression_ptr height);
|
||||
color const& get_fill() const;
|
||||
void set_fill(color const& fill);
|
||||
expression_ptr height() const;
|
||||
void set_height(expression_ptr height);
|
||||
void set_opacity(double opacity);
|
||||
double get_opacity() const;
|
||||
|
||||
private:
|
||||
point_ anchor_;
|
||||
point_ displacement_;
|
||||
double rotation_;
|
||||
public:
|
||||
label_placement()
|
||||
: anchor_(),
|
||||
displacement_(),
|
||||
rotation_(0.0) {}
|
||||
|
||||
};
|
||||
color fill_;
|
||||
expression_ptr height_;
|
||||
double opacity_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // MAPNIK_LABEL_PLACEMENT_HPP
|
||||
|
||||
#endif // MAPNIK_BUILDING_SYMBOLIZER_HPP
|
|
@ -111,9 +111,6 @@ public:
|
|||
void process(markers_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans);
|
||||
void process(glyph_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans);
|
||||
inline bool process(rule::symbolizers const& /*syms*/,
|
||||
Feature const& /*feature*/,
|
||||
proj_transform const& /*prj_trans*/)
|
||||
|
|
|
@ -19,23 +19,34 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
//$Id$
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/grid/grid_renderer.hpp>
|
||||
#include <iostream>
|
||||
#ifndef CHAR_INFO_HPP
|
||||
#define CHAR_INFO_HPP
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
struct char_properties;
|
||||
|
||||
template <typename T>
|
||||
void grid_renderer<T>::process(glyph_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
std::clog << "grid_renderer does not yet support glyph_symbolizer\n";
|
||||
}
|
||||
class char_info {
|
||||
public:
|
||||
char_info(unsigned c_, double width_, double ymax_, double ymin_, double line_height_)
|
||||
: c(c_), width(width_), line_height(line_height_), ymin(ymin_), ymax(ymax_)
|
||||
{
|
||||
}
|
||||
char_info()
|
||||
: c(0), width(0), line_height(0), ymin(0), ymax(0)
|
||||
{
|
||||
}
|
||||
|
||||
template void grid_renderer<grid>::process(glyph_symbolizer const&,
|
||||
Feature const&,
|
||||
proj_transform const&);
|
||||
unsigned c;
|
||||
double width;
|
||||
double line_height;
|
||||
double ymin;
|
||||
double ymax;
|
||||
double avg_height;
|
||||
char_properties *format;
|
||||
double height() const { return ymax-ymin; }
|
||||
};
|
||||
}
|
||||
#endif
|
|
@ -43,7 +43,7 @@ namespace mapnik {
|
|||
|
||||
typedef MAPNIK_DECL boost::shared_ptr<Feature> feature_ptr;
|
||||
|
||||
struct MAPNIK_DECL Featureset
|
||||
struct MAPNIK_DECL Featureset : private boost::noncopyable
|
||||
{
|
||||
virtual feature_ptr next()=0;
|
||||
virtual ~Featureset() {};
|
||||
|
|
|
@ -148,6 +148,8 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
|
|||
using qi::lit;
|
||||
using qi::int_;
|
||||
using qi::double_;
|
||||
using qi::hex;
|
||||
using qi::omit;
|
||||
using standard_wide::char_;
|
||||
|
||||
expr = logical_expr.alias();
|
||||
|
@ -223,14 +225,23 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
|
|||
| '(' >> expr [_val = _1 ] >> ')'
|
||||
;
|
||||
|
||||
|
||||
unesc_char.add("\\a", '\a')("\\b", '\b')("\\f", '\f')("\\n", '\n')
|
||||
("\\r", '\r')("\\t", '\t')("\\v", '\v')("\\\\", '\\')
|
||||
("\\\'", '\'')("\\\"", '\"')
|
||||
;
|
||||
|
||||
ustring %= omit[quote_char[_a = _1]]
|
||||
>> *(unesc_char | "\\x" >> hex | (char_ - lit(_a)))
|
||||
>> lit(_a);
|
||||
|
||||
quote_char %= char_('\'') | char_('"');
|
||||
|
||||
#if BOOST_VERSION > 104200
|
||||
ustring %= '\'' >> no_skip[*~char_('\'')] >> '\'';
|
||||
attr %= '[' >> no_skip[+~char_(']')] >> ']';
|
||||
#else
|
||||
ustring %= '\'' >> lexeme[*(char_-'\'')] >> '\'';
|
||||
attr %= '[' >> lexeme[+(char_ - ']')] >> ']';
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
|
||||
|
@ -250,7 +261,9 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
|
|||
qi::rule<Iterator, std::string() > regex_match_expr;
|
||||
qi::rule<Iterator, expr_node(expr_node), qi::locals<std::string,std::string>, space_type> regex_replace_expr;
|
||||
qi::rule<Iterator, std::string() , space_type> attr;
|
||||
qi::rule<Iterator, std::string() > ustring;
|
||||
qi::rule<Iterator, std::string(), qi::locals<char> > ustring;
|
||||
qi::symbols<char const, char const> unesc_char;
|
||||
qi::rule<Iterator, char() > quote_char;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <mapnik/value.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/raster.hpp>
|
||||
|
||||
#include <mapnik/feature_kv_iterator.hpp>
|
||||
// boost
|
||||
#include <boost/version.hpp>
|
||||
#if BOOST_VERSION >= 104000
|
||||
|
@ -37,49 +37,153 @@
|
|||
#endif
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace mapnik {
|
||||
typedef boost::shared_ptr<raster> raster_ptr;
|
||||
typedef boost::associative_property_map<
|
||||
std::map<std::string,value
|
||||
> > properties;
|
||||
|
||||
template <typename T1,typename T2>
|
||||
struct feature : public properties,
|
||||
private boost::noncopyable
|
||||
|
||||
typedef boost::shared_ptr<raster> raster_ptr;
|
||||
|
||||
class feature_impl;
|
||||
|
||||
template <typename T>
|
||||
class context : private boost::noncopyable,
|
||||
public boost::associative_property_map<T>
|
||||
|
||||
{
|
||||
friend class feature_impl;
|
||||
public:
|
||||
typedef T1 geometry_type;
|
||||
typedef T2 raster_type;
|
||||
typedef std::map<std::string,value>::value_type value_type;
|
||||
typedef std::map<std::string,value>::size_type size_type;
|
||||
typedef std::map<std::string,value>::difference_type difference_type;
|
||||
|
||||
private:
|
||||
int id_;
|
||||
boost::ptr_vector<geometry_type> geom_cont_;
|
||||
raster_type raster_;
|
||||
std::map<std::string,value> props_;
|
||||
public:
|
||||
typedef std::map<std::string,value>::iterator iterator;
|
||||
typedef std::map<std::string,value>::const_iterator const_iterator;
|
||||
explicit feature(int id)
|
||||
: properties(props_),
|
||||
id_(id),
|
||||
geom_cont_(),
|
||||
raster_() {}
|
||||
|
||||
int id() const
|
||||
typedef T map_type;
|
||||
typedef typename boost::associative_property_map<map_type> base_type;
|
||||
typedef typename map_type::value_type value_type;
|
||||
typedef typename map_type::key_type key_type;
|
||||
typedef typename map_type::size_type size_type;
|
||||
typedef typename map_type::difference_type difference_type;
|
||||
typedef typename map_type::iterator iterator;
|
||||
typedef typename map_type::const_iterator const_iterator;
|
||||
|
||||
context()
|
||||
: base_type(mapping_) {}
|
||||
|
||||
size_type push(key_type const& name)
|
||||
{
|
||||
return id_;
|
||||
size_type index = mapping_.size();
|
||||
mapping_.insert(std::make_pair(name, index));
|
||||
return index;
|
||||
}
|
||||
|
||||
size_type size() const { return mapping_.size(); }
|
||||
const_iterator begin() const { return mapping_.begin();}
|
||||
const_iterator end() const { return mapping_.end();}
|
||||
|
||||
private:
|
||||
map_type mapping_;
|
||||
};
|
||||
|
||||
typedef context<std::map<std::string,std::size_t> > context_type;
|
||||
typedef boost::shared_ptr<context_type> context_ptr;
|
||||
|
||||
class feature_impl : private boost::noncopyable
|
||||
{
|
||||
friend class feature_kv_iterator;
|
||||
public:
|
||||
|
||||
typedef mapnik::value value_type;
|
||||
typedef std::vector<value_type> cont_type;
|
||||
typedef feature_kv_iterator iterator;
|
||||
|
||||
feature_impl(context_ptr const& ctx, int id)
|
||||
: id_(id),
|
||||
ctx_(ctx),
|
||||
data_(ctx_->mapping_.size())
|
||||
{}
|
||||
|
||||
inline int id() const { return id_;}
|
||||
|
||||
inline void set_id(int id) { id_ = id;}
|
||||
|
||||
template <typename T>
|
||||
void put(context_type::key_type const& key, T const& val)
|
||||
{
|
||||
put(key,value(val));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void put_new(context_type::key_type const& key, T const& val)
|
||||
{
|
||||
put_new(key,value(val));
|
||||
}
|
||||
|
||||
|
||||
void put(context_type::key_type const& key, value const& val)
|
||||
{
|
||||
context_type::map_type::const_iterator itr = ctx_->mapping_.find(key);
|
||||
if (itr != ctx_->mapping_.end()
|
||||
&& itr->second < data_.size())
|
||||
{
|
||||
data_[itr->second] = val;
|
||||
}
|
||||
else
|
||||
throw std::out_of_range("Key doesn't exist");
|
||||
}
|
||||
|
||||
void set_id(int id)
|
||||
|
||||
void put_new(context_type::key_type const& key, value const& val)
|
||||
{
|
||||
id_ = id;
|
||||
context_type::map_type::const_iterator itr = ctx_->mapping_.find(key);
|
||||
if (itr != ctx_->mapping_.end()
|
||||
&& itr->second < data_.size())
|
||||
{
|
||||
data_[itr->second] = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
cont_type::size_type index = ctx_->push(key);
|
||||
data_.push_back(val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool has_key(context_type::key_type const& key) const
|
||||
{
|
||||
return (ctx_->mapping_.find(key) != ctx_->mapping_.end());
|
||||
}
|
||||
|
||||
value_type const& get(context_type::key_type const& key) const
|
||||
{
|
||||
context_type::map_type::const_iterator itr = ctx_->mapping_.find(key);
|
||||
if (itr != ctx_->mapping_.end()
|
||||
&& itr->second < data_.size())
|
||||
{
|
||||
return data_[itr->second];
|
||||
}
|
||||
throw std::out_of_range("Key doesn't exist");
|
||||
}
|
||||
|
||||
value_type const& get(std::size_t index) const
|
||||
{
|
||||
if (index < data_.size())
|
||||
return data_[index];
|
||||
throw std::out_of_range("Index out of range");
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
{
|
||||
return data_.size();
|
||||
}
|
||||
|
||||
context_ptr context()
|
||||
{
|
||||
return ctx_;
|
||||
}
|
||||
|
||||
boost::ptr_vector<geometry_type> const& paths() const
|
||||
{
|
||||
return geom_cont_;
|
||||
}
|
||||
|
||||
boost::ptr_vector<geometry_type> & paths()
|
||||
|
@ -87,10 +191,9 @@ public:
|
|||
return geom_cont_;
|
||||
}
|
||||
|
||||
|
||||
void add_geometry(geometry_type * geom)
|
||||
{
|
||||
geom_cont_.push_back(geom);
|
||||
geom_cont_.push_back(geom);
|
||||
}
|
||||
|
||||
unsigned num_geometries() const
|
||||
|
@ -107,7 +210,7 @@ public:
|
|||
{
|
||||
return geom_cont_[index];
|
||||
}
|
||||
|
||||
|
||||
box2d<double> envelope() const
|
||||
{
|
||||
box2d<double> result;
|
||||
|
@ -125,75 +228,59 @@ public:
|
|||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const raster_type& get_raster() const
|
||||
}
|
||||
|
||||
const raster_ptr& get_raster() const
|
||||
{
|
||||
return raster_;
|
||||
}
|
||||
|
||||
void set_raster(raster_type const& raster)
|
||||
{
|
||||
raster_=raster;
|
||||
}
|
||||
|
||||
std::map<std::string,value> const& props() const
|
||||
{
|
||||
return props_;
|
||||
}
|
||||
|
||||
std::map<std::string,value>& props()
|
||||
{
|
||||
return props_;
|
||||
}
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return props_.begin();
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return props_.end();
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return props_.begin();
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return props_.end();
|
||||
}
|
||||
|
||||
const_iterator find(std::string const& key) const
|
||||
void set_raster(raster_ptr const& raster)
|
||||
{
|
||||
return props_.find(key);
|
||||
raster_ = raster;
|
||||
}
|
||||
|
||||
feature_kv_iterator begin() const
|
||||
{
|
||||
return feature_kv_iterator(*this,true);
|
||||
}
|
||||
|
||||
feature_kv_iterator end() const
|
||||
{
|
||||
return feature_kv_iterator(*this);
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "feature "
|
||||
<< id_ << " (" << std::endl;
|
||||
for (std::map<std::string,value>::const_iterator itr=props_.begin();
|
||||
itr != props_.end();++itr)
|
||||
ss << "Feature (" << std::endl;
|
||||
context_type::map_type::const_iterator itr = ctx_->mapping_.begin();
|
||||
context_type::map_type::const_iterator end = ctx_->mapping_.end();
|
||||
for ( ;itr!=end; ++itr)
|
||||
{
|
||||
ss << " " << itr->first << ":" << itr->second << std::endl;
|
||||
ss << " " << itr->first << ":" << data_[itr->second] << std::endl;
|
||||
}
|
||||
ss << ")" << std::endl;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
int id_;
|
||||
context_ptr ctx_;
|
||||
boost::ptr_vector<geometry_type> geom_cont_;
|
||||
raster_ptr raster_;
|
||||
cont_type data_;
|
||||
};
|
||||
|
||||
|
||||
typedef feature<geometry_type,raster_ptr> Feature;
|
||||
|
||||
inline std::ostream& operator<< (std::ostream & out,Feature const& f)
|
||||
inline std::ostream& operator<< (std::ostream & out,feature_impl const& f)
|
||||
{
|
||||
out << f.to_string();
|
||||
return out;
|
||||
}
|
||||
|
||||
typedef feature_impl Feature;
|
||||
|
||||
}
|
||||
|
||||
#endif // MAPNIK_FEATURE_HPP
|
||||
|
|
|
@ -34,11 +34,11 @@ namespace mapnik
|
|||
{
|
||||
struct feature_factory
|
||||
{
|
||||
static boost::shared_ptr<Feature> create (int fid)
|
||||
static boost::shared_ptr<Feature> create (context_ptr const& ctx, int fid)
|
||||
{
|
||||
//return boost::allocate_shared<Feature>(boost::pool_allocator<Feature>(),fid);
|
||||
//return boost::allocate_shared<Feature>(boost::fast_pool_allocator<Feature>(),fid);
|
||||
return boost::make_shared<Feature>(fid);
|
||||
return boost::make_shared<Feature>(ctx,fid);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
63
include/mapnik/feature_kv_iterator.hpp
Normal file
63
include/mapnik/feature_kv_iterator.hpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2012 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAPNIK_FEATURE_KV_ITERATOR_HPP
|
||||
#define MAPNIK_FEATURE_KV_ITERATOR_HPP
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
|
||||
#include <map>
|
||||
//#include <mapnik/feature.hpp>
|
||||
#include <mapnik/value.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
class feature_impl;
|
||||
|
||||
class feature_kv_iterator :
|
||||
public boost::iterator_facade<feature_kv_iterator,
|
||||
boost::tuple<std::string , value> const,
|
||||
boost::forward_traversal_tag>
|
||||
{
|
||||
public:
|
||||
typedef boost::tuple<std::string,value> value_type;
|
||||
|
||||
feature_kv_iterator (feature_impl const& f, bool begin = false);
|
||||
private:
|
||||
friend class boost::iterator_core_access;
|
||||
void increment();
|
||||
|
||||
bool equal( feature_kv_iterator const& other) const;
|
||||
|
||||
value_type const& dereference() const;
|
||||
|
||||
feature_impl const& f_;
|
||||
std::map<std::string,std::size_t>::const_iterator itr_;
|
||||
mutable value_type kv_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // MAPNIK_FEATURE_KV_ITERATOR_HPP
|
||||
|
|
@ -145,13 +145,6 @@ private:
|
|||
class MAPNIK_DECL font_face_set : private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
class dimension_t {
|
||||
public:
|
||||
dimension_t(unsigned width_, int ymax_, int ymin_) : width(width_), height(ymax_-ymin_), ymin(ymin_) {}
|
||||
unsigned width, height;
|
||||
int ymin;
|
||||
};
|
||||
|
||||
font_face_set(void)
|
||||
: faces_() {}
|
||||
|
||||
|
@ -179,9 +172,9 @@ public:
|
|||
return boost::make_shared<font_glyph>(*faces_.begin(), 0);
|
||||
}
|
||||
|
||||
dimension_t character_dimensions(const unsigned c);
|
||||
char_info character_dimensions(const unsigned c);
|
||||
|
||||
void get_string_info(string_info & info);
|
||||
void get_string_info(string_info & info, UnicodeString const& ustr, char_properties *format);
|
||||
|
||||
void set_pixel_sizes(unsigned size)
|
||||
{
|
||||
|
@ -200,7 +193,7 @@ public:
|
|||
}
|
||||
private:
|
||||
std::vector<face_ptr> faces_;
|
||||
std::map<unsigned, dimension_t> dimension_cache_;
|
||||
std::map<unsigned, char_info> dimension_cache_;
|
||||
};
|
||||
|
||||
// FT_Stroker wrapper
|
||||
|
@ -313,6 +306,18 @@ public:
|
|||
return face_set;
|
||||
}
|
||||
|
||||
face_set_ptr get_face_set(std::string const& name, font_set const& fset)
|
||||
{
|
||||
if (fset.size() > 0)
|
||||
{
|
||||
return get_face_set(fset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return get_face_set(name);
|
||||
}
|
||||
}
|
||||
|
||||
stroker_ptr get_stroker()
|
||||
{
|
||||
return stroker_;
|
||||
|
@ -330,247 +335,21 @@ struct text_renderer : private boost::noncopyable
|
|||
struct glyph_t : boost::noncopyable
|
||||
{
|
||||
FT_Glyph image;
|
||||
glyph_t(FT_Glyph image_) : image(image_) {}
|
||||
char_properties *properties;
|
||||
glyph_t(FT_Glyph image_, char_properties *properties_) : image(image_), properties(properties_) {}
|
||||
~glyph_t () { FT_Done_Glyph(image);}
|
||||
};
|
||||
|
||||
typedef boost::ptr_vector<glyph_t> glyphs_t;
|
||||
typedef T pixmap_type;
|
||||
|
||||
text_renderer (pixmap_type & pixmap, face_set_ptr faces, stroker & s)
|
||||
: pixmap_(pixmap),
|
||||
faces_(faces),
|
||||
stroker_(s),
|
||||
fill_(0,0,0),
|
||||
halo_fill_(255,255,255),
|
||||
halo_radius_(0.0),
|
||||
opacity_(1.0) {}
|
||||
text_renderer (pixmap_type & pixmap, face_manager<freetype_engine> &font_manager_, stroker & s);
|
||||
box2d<double> prepare_glyphs(text_path *path);
|
||||
void render(double x0, double y0);
|
||||
void render_id(int feature_id,double x0, double y0, double min_radius=1.0);
|
||||
|
||||
|
||||
void set_pixel_size(unsigned size)
|
||||
{
|
||||
faces_->set_pixel_sizes(size);
|
||||
}
|
||||
|
||||
void set_character_size(float size)
|
||||
{
|
||||
faces_->set_character_sizes(size);
|
||||
}
|
||||
|
||||
void set_fill(mapnik::color const& fill)
|
||||
{
|
||||
fill_=fill;
|
||||
}
|
||||
|
||||
void set_halo_fill(mapnik::color const& halo)
|
||||
{
|
||||
halo_fill_=halo;
|
||||
}
|
||||
|
||||
void set_halo_radius( double radius=1.0)
|
||||
{
|
||||
halo_radius_=radius;
|
||||
}
|
||||
|
||||
void set_opacity( double opacity=1.0)
|
||||
{
|
||||
opacity_=opacity;
|
||||
}
|
||||
|
||||
box2d<double> prepare_glyphs(text_path *path)
|
||||
{
|
||||
//clear glyphs
|
||||
glyphs_.clear();
|
||||
|
||||
FT_Matrix matrix;
|
||||
FT_Vector pen;
|
||||
FT_Error error;
|
||||
|
||||
FT_BBox bbox;
|
||||
bbox.xMin = bbox.yMin = 32000; // Initialize these so we can tell if we
|
||||
bbox.xMax = bbox.yMax = -32000; // properly grew the bbox later
|
||||
|
||||
for (int i = 0; i < path->num_nodes(); i++)
|
||||
{
|
||||
int c;
|
||||
double x, y, angle;
|
||||
|
||||
path->vertex(&c, &x, &y, &angle);
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
// TODO Enable when we have support for setting verbosity
|
||||
//std::clog << "prepare_glyphs: " << c << "," << x <<
|
||||
// "," << y << "," << angle << std::endl;
|
||||
#endif
|
||||
|
||||
FT_BBox glyph_bbox;
|
||||
FT_Glyph image;
|
||||
|
||||
pen.x = int(x * 64);
|
||||
pen.y = int(y * 64);
|
||||
|
||||
glyph_ptr glyph = faces_->get_glyph(unsigned(c));
|
||||
FT_Face face = glyph->get_face()->get_face();
|
||||
|
||||
matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
|
||||
matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
|
||||
matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
|
||||
matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
|
||||
|
||||
FT_Set_Transform(face, &matrix, &pen);
|
||||
|
||||
error = FT_Load_Glyph(face, glyph->get_index(), FT_LOAD_NO_HINTING);
|
||||
if ( error )
|
||||
continue;
|
||||
|
||||
error = FT_Get_Glyph(face->glyph, &image);
|
||||
if ( error )
|
||||
continue;
|
||||
|
||||
FT_Glyph_Get_CBox(image,ft_glyph_bbox_pixels, &glyph_bbox);
|
||||
if (glyph_bbox.xMin < bbox.xMin)
|
||||
bbox.xMin = glyph_bbox.xMin;
|
||||
if (glyph_bbox.yMin < bbox.yMin)
|
||||
bbox.yMin = glyph_bbox.yMin;
|
||||
if (glyph_bbox.xMax > bbox.xMax)
|
||||
bbox.xMax = glyph_bbox.xMax;
|
||||
if (glyph_bbox.yMax > bbox.yMax)
|
||||
bbox.yMax = glyph_bbox.yMax;
|
||||
|
||||
// Check if we properly grew the bbox
|
||||
if ( bbox.xMin > bbox.xMax )
|
||||
{
|
||||
bbox.xMin = 0;
|
||||
bbox.yMin = 0;
|
||||
bbox.xMax = 0;
|
||||
bbox.yMax = 0;
|
||||
}
|
||||
|
||||
// take ownership of the glyph
|
||||
glyphs_.push_back(new glyph_t(image));
|
||||
}
|
||||
|
||||
return box2d<double>(bbox.xMin, bbox.yMin, bbox.xMax, bbox.yMax);
|
||||
}
|
||||
|
||||
void render(double x0, double y0)
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Vector start;
|
||||
unsigned height = pixmap_.height();
|
||||
|
||||
start.x = static_cast<FT_Pos>(x0 * (1 << 6));
|
||||
start.y = static_cast<FT_Pos>((height - y0) * (1 << 6));
|
||||
|
||||
// now render transformed glyphs
|
||||
typename glyphs_t::iterator pos;
|
||||
|
||||
//make sure we've got reasonable values.
|
||||
if (halo_radius_ > 0.0 && halo_radius_ < 1024.0)
|
||||
{
|
||||
stroker_.init(halo_radius_);
|
||||
for ( pos = glyphs_.begin(); pos != glyphs_.end();++pos)
|
||||
{
|
||||
FT_Glyph g;
|
||||
error = FT_Glyph_Copy(pos->image, &g);
|
||||
if (!error)
|
||||
{
|
||||
FT_Glyph_Transform(g,0,&start);
|
||||
FT_Glyph_Stroke(&g,stroker_.get(),1);
|
||||
error = FT_Glyph_To_Bitmap( &g,FT_RENDER_MODE_NORMAL,0,1);
|
||||
if ( ! error )
|
||||
{
|
||||
|
||||
FT_BitmapGlyph bit = (FT_BitmapGlyph)g;
|
||||
render_bitmap(&bit->bitmap, halo_fill_.rgba(),
|
||||
bit->left,
|
||||
height - bit->top);
|
||||
}
|
||||
}
|
||||
FT_Done_Glyph(g);
|
||||
}
|
||||
}
|
||||
//render actual text
|
||||
for ( pos = glyphs_.begin(); pos != glyphs_.end();++pos)
|
||||
{
|
||||
|
||||
FT_Glyph_Transform(pos->image,0,&start);
|
||||
|
||||
error = FT_Glyph_To_Bitmap( &(pos->image),FT_RENDER_MODE_NORMAL,0,1);
|
||||
if ( ! error )
|
||||
{
|
||||
|
||||
FT_BitmapGlyph bit = (FT_BitmapGlyph)pos->image;
|
||||
render_bitmap(&bit->bitmap, fill_.rgba(),
|
||||
bit->left,
|
||||
height - bit->top);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void render_id(int feature_id,double x0, double y0, double min_radius=1.0)
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Vector start;
|
||||
unsigned height = pixmap_.height();
|
||||
|
||||
start.x = static_cast<FT_Pos>(x0 * (1 << 6));
|
||||
start.y = static_cast<FT_Pos>((height - y0) * (1 << 6));
|
||||
|
||||
// now render transformed glyphs
|
||||
typename glyphs_t::iterator pos;
|
||||
|
||||
stroker_.init(std::max(halo_radius_,min_radius));
|
||||
for ( pos = glyphs_.begin(); pos != glyphs_.end();++pos)
|
||||
{
|
||||
FT_Glyph g;
|
||||
error = FT_Glyph_Copy(pos->image, &g);
|
||||
if (!error)
|
||||
{
|
||||
FT_Glyph_Transform(g,0,&start);
|
||||
FT_Glyph_Stroke(&g,stroker_.get(),1);
|
||||
error = FT_Glyph_To_Bitmap( &g,FT_RENDER_MODE_NORMAL,0,1);
|
||||
//error = FT_Glyph_To_Bitmap( &g,FT_RENDER_MODE_MONO,0,1);
|
||||
if ( ! error )
|
||||
{
|
||||
|
||||
FT_BitmapGlyph bit = (FT_BitmapGlyph)g;
|
||||
render_bitmap_id(&bit->bitmap, feature_id,
|
||||
bit->left,
|
||||
height - bit->top);
|
||||
}
|
||||
}
|
||||
FT_Done_Glyph(g);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// unused currently, stroker is the new method for drawing halos
|
||||
/*
|
||||
void render_halo(FT_Bitmap *bitmap,unsigned rgba,int x,int y,int radius)
|
||||
{
|
||||
int x_max=x+bitmap->width;
|
||||
int y_max=y+bitmap->rows;
|
||||
int i,p,j,q;
|
||||
|
||||
for (i=x,p=0;i<x_max;++i,++p)
|
||||
{
|
||||
for (j=y,q=0;j<y_max;++j,++q)
|
||||
{
|
||||
int gray = bitmap->buffer[q*bitmap->width+p];
|
||||
if (gray)
|
||||
{
|
||||
for (int n=-halo_radius_; n <=halo_radius_; ++n)
|
||||
for (int m=-halo_radius_;m <= halo_radius_; ++m)
|
||||
pixmap_.blendPixel2(i+m,j+n,rgba,gray,opacity_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void render_bitmap(FT_Bitmap *bitmap,unsigned rgba,int x,int y)
|
||||
void render_bitmap(FT_Bitmap *bitmap, unsigned rgba, int x, int y, double opacity)
|
||||
{
|
||||
int x_max=x+bitmap->width;
|
||||
int y_max=y+bitmap->rows;
|
||||
|
@ -583,7 +362,7 @@ private:
|
|||
int gray=bitmap->buffer[q*bitmap->width+p];
|
||||
if (gray)
|
||||
{
|
||||
pixmap_.blendPixel2(i,j,rgba,gray,opacity_);
|
||||
pixmap_.blendPixel2(i, j, rgba, gray, opacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -610,14 +389,11 @@ private:
|
|||
}
|
||||
|
||||
pixmap_type & pixmap_;
|
||||
face_set_ptr faces_;
|
||||
face_manager<freetype_engine> &font_manager_;
|
||||
stroker & stroker_;
|
||||
color fill_;
|
||||
color halo_fill_;
|
||||
double halo_radius_;
|
||||
glyphs_t glyphs_;
|
||||
double opacity_;
|
||||
};
|
||||
typedef face_manager<freetype_engine> face_manager_freetype;
|
||||
}
|
||||
|
||||
#endif // MAPNIK_FONT_ENGINE_FREETYPE_HPP
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
namespace mapnik {
|
||||
|
||||
enum eGeomType {
|
||||
Unknown = 0,
|
||||
Point = 1,
|
||||
LineString = 2,
|
||||
Polygon = 3
|
||||
|
@ -53,6 +54,11 @@ private:
|
|||
mutable unsigned itr_;
|
||||
public:
|
||||
|
||||
geometry()
|
||||
: type_(Unknown),
|
||||
itr_(0)
|
||||
{}
|
||||
|
||||
explicit geometry(eGeomType type)
|
||||
: type_(type),
|
||||
itr_(0)
|
||||
|
@ -62,7 +68,12 @@ public:
|
|||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
|
||||
void set_type(eGeomType type)
|
||||
{
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
container_type const& data() const
|
||||
{
|
||||
return cont_;
|
||||
|
|
|
@ -1,215 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAPNIK_GLYPH_SYMBOLIZER_HPP
|
||||
#define MAPNIK_GLYPH_SYMBOLIZER_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/enumeration.hpp>
|
||||
#include <mapnik/raster_colorizer.hpp>
|
||||
#include <mapnik/filter_factory.hpp>
|
||||
#include <mapnik/text_path.hpp>
|
||||
#include <mapnik/font_engine_freetype.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
typedef boost::tuple<double,double> position;
|
||||
|
||||
enum angle_mode_enum {
|
||||
AZIMUTH,
|
||||
TRIGONOMETRIC,
|
||||
angle_mode_enum_MAX
|
||||
};
|
||||
|
||||
DEFINE_ENUM(angle_mode_e, angle_mode_enum);
|
||||
|
||||
struct MAPNIK_DECL glyph_symbolizer : public symbolizer_base
|
||||
{
|
||||
glyph_symbolizer(std::string face_name, expression_ptr c)
|
||||
: symbolizer_base(),
|
||||
face_name_(face_name),
|
||||
char_(c),
|
||||
angle_(),
|
||||
value_(),
|
||||
size_(),
|
||||
color_(),
|
||||
colorizer_(),
|
||||
allow_overlap_(false),
|
||||
avoid_edges_(false),
|
||||
displacement_(0.0, 0.0),
|
||||
halo_fill_(color(255,255,255)),
|
||||
halo_radius_(0),
|
||||
angle_mode_(TRIGONOMETRIC) {}
|
||||
|
||||
std::string const& get_face_name() const
|
||||
{
|
||||
return face_name_;
|
||||
}
|
||||
void set_face_name(std::string face_name)
|
||||
{
|
||||
face_name_ = face_name;
|
||||
}
|
||||
|
||||
expression_ptr get_char() const
|
||||
{
|
||||
return char_;
|
||||
}
|
||||
void set_char(expression_ptr c)
|
||||
{
|
||||
char_ = c;
|
||||
}
|
||||
|
||||
bool get_allow_overlap() const
|
||||
{
|
||||
return allow_overlap_;
|
||||
}
|
||||
void set_allow_overlap(bool allow_overlap)
|
||||
{
|
||||
allow_overlap_ = allow_overlap;
|
||||
}
|
||||
|
||||
bool get_avoid_edges() const
|
||||
{
|
||||
return avoid_edges_;
|
||||
}
|
||||
void set_avoid_edges(bool avoid_edges)
|
||||
{
|
||||
avoid_edges_ = avoid_edges;
|
||||
}
|
||||
|
||||
void set_displacement(double x, double y)
|
||||
{
|
||||
displacement_ = boost::make_tuple(x,y);
|
||||
}
|
||||
position const& get_displacement() const
|
||||
{
|
||||
return displacement_;
|
||||
}
|
||||
|
||||
void set_halo_fill(color const& fill)
|
||||
{
|
||||
halo_fill_ = fill;
|
||||
}
|
||||
color const& get_halo_fill() const
|
||||
{
|
||||
return halo_fill_;
|
||||
}
|
||||
|
||||
void set_halo_radius(unsigned radius)
|
||||
{
|
||||
halo_radius_ = radius;
|
||||
}
|
||||
|
||||
unsigned get_halo_radius() const
|
||||
{
|
||||
return halo_radius_;
|
||||
}
|
||||
|
||||
expression_ptr get_angle() const
|
||||
{
|
||||
return angle_;
|
||||
}
|
||||
void set_angle(expression_ptr angle)
|
||||
{
|
||||
angle_ = angle;
|
||||
}
|
||||
|
||||
expression_ptr get_value() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
void set_value(expression_ptr value)
|
||||
{
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
expression_ptr get_size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
void set_size(expression_ptr size)
|
||||
{
|
||||
size_ = size;
|
||||
}
|
||||
|
||||
expression_ptr get_color() const
|
||||
{
|
||||
return color_;
|
||||
}
|
||||
void set_color(expression_ptr color)
|
||||
{
|
||||
color_ = color;
|
||||
}
|
||||
|
||||
raster_colorizer_ptr get_colorizer() const
|
||||
{
|
||||
return colorizer_;
|
||||
}
|
||||
void set_colorizer(raster_colorizer_ptr const& colorizer)
|
||||
{
|
||||
colorizer_ = colorizer;
|
||||
}
|
||||
void set_angle_mode(angle_mode_e angle_mode)
|
||||
{
|
||||
angle_mode_ = angle_mode;
|
||||
}
|
||||
angle_mode_e get_angle_mode() const
|
||||
{
|
||||
return angle_mode_;
|
||||
}
|
||||
|
||||
|
||||
text_path_ptr get_text_path(face_set_ptr const& faces,
|
||||
Feature const& feature) const;
|
||||
UnicodeString eval_char(Feature const& feature) const;
|
||||
double eval_angle(Feature const& feature) const;
|
||||
unsigned eval_size(Feature const& feature) const;
|
||||
color eval_color(Feature const& feature) const;
|
||||
|
||||
|
||||
private:
|
||||
std::string face_name_;
|
||||
expression_ptr char_;
|
||||
expression_ptr angle_;
|
||||
expression_ptr value_;
|
||||
expression_ptr size_;
|
||||
expression_ptr color_;
|
||||
raster_colorizer_ptr colorizer_;
|
||||
bool allow_overlap_;
|
||||
bool avoid_edges_;
|
||||
position displacement_;
|
||||
color halo_fill_;
|
||||
unsigned halo_radius_;
|
||||
angle_mode_e angle_mode_;
|
||||
};
|
||||
|
||||
} // end mapnik namespace
|
||||
|
||||
#endif // MAPNIK_GLYPH_SYMBOLIZER_HPP
|
|
@ -24,7 +24,6 @@
|
|||
#define MAPNIK_GRID_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/grid/grid_view.hpp>
|
||||
|
@ -111,8 +110,10 @@ public:
|
|||
|
||||
inline void add_feature(mapnik::Feature const& feature)
|
||||
{
|
||||
|
||||
|
||||
// copies feature props
|
||||
// FIXME
|
||||
/*
|
||||
std::map<std::string,value> fprops = feature.props();
|
||||
lookup_type lookup_value;
|
||||
if (key_ == id_name_)
|
||||
|
@ -154,6 +155,7 @@ public:
|
|||
{
|
||||
std::clog << "### Warning: key '" << key_ << "' was blank for " << feature << "\n";
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
inline void add_property_name(std::string const& name)
|
||||
|
|
|
@ -98,9 +98,6 @@ public:
|
|||
void process(markers_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans);
|
||||
void process(glyph_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans);
|
||||
inline bool process(rule::symbolizers const& /*syms*/,
|
||||
Feature const& /*feature*/,
|
||||
proj_transform const& /*prj_trans*/)
|
||||
|
|
|
@ -27,8 +27,11 @@
|
|||
|
||||
#include <mapnik/global.hpp>
|
||||
|
||||
#include <ostream>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <stdio.h>
|
||||
#include <jpeglib.h>
|
||||
}
|
||||
|
||||
|
|
|
@ -23,10 +23,6 @@
|
|||
#ifndef MAPNIK_LOAD_MAP_HPP
|
||||
#define MAPNIK_LOAD_MAP_HPP
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.hpp>
|
||||
#endif
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/map.hpp>
|
||||
|
||||
|
|
|
@ -23,10 +23,6 @@
|
|||
#ifndef MAPNIK_MAP_HPP
|
||||
#define MAPNIK_MAP_HPP
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.hpp>
|
||||
#endif
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/enumeration.hpp>
|
||||
#include <mapnik/feature_type_style.hpp>
|
||||
|
|
|
@ -73,19 +73,6 @@ private:
|
|||
mapnik::layer_descriptor desc_;
|
||||
};
|
||||
|
||||
// This class implements a simple way of displaying point-based data
|
||||
// TODO -- possible redesign, move into separate file
|
||||
//
|
||||
|
||||
class MAPNIK_DECL point_datasource : public memory_datasource {
|
||||
public:
|
||||
point_datasource() :
|
||||
feature_id_(1) {}
|
||||
void add_point(double x, double y, const char* key, const char* value);
|
||||
|
||||
private:
|
||||
int feature_id_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MAPNIK_MEMORY_DATASOURCE_HPP
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
namespace mapnik {
|
||||
|
||||
struct placement;
|
||||
class text_placement_info;
|
||||
|
||||
/** Implementation of std::map that also returns const& for operator[]. */
|
||||
class metawriter_property_map
|
||||
|
@ -61,6 +61,11 @@ public:
|
|||
{
|
||||
return m_.end();
|
||||
}
|
||||
|
||||
UnicodeString const& get(std::string const& key) const
|
||||
{
|
||||
return (*this)[key];
|
||||
}
|
||||
private:
|
||||
property_map m_;
|
||||
UnicodeString not_found_;
|
||||
|
@ -98,8 +103,8 @@ public:
|
|||
virtual void add_box(box2d<double> const& box, Feature const& feature,
|
||||
CoordTransform const& t,
|
||||
metawriter_properties const& properties)=0;
|
||||
virtual void add_text(placement const& placement,
|
||||
face_set_ptr face,
|
||||
virtual void add_text(text_placement_info const& placement,
|
||||
face_manager_freetype &font_manager,
|
||||
Feature const& feature,
|
||||
CoordTransform const& t,
|
||||
metawriter_properties const& properties)=0;
|
||||
|
|
|
@ -65,8 +65,8 @@ public:
|
|||
virtual void add_box(box2d<double> const& box, Feature const& feature,
|
||||
CoordTransform const& t,
|
||||
metawriter_properties const& properties);
|
||||
virtual void add_text(placement const& p,
|
||||
face_set_ptr face,
|
||||
virtual void add_text(text_placement_info const& p,
|
||||
face_manager_freetype &font_manager,
|
||||
Feature const& feature,
|
||||
CoordTransform const& t,
|
||||
metawriter_properties const& properties);
|
||||
|
|
|
@ -45,8 +45,8 @@ public:
|
|||
virtual void add_box(box2d<double> const& box, Feature const& feature,
|
||||
CoordTransform const& t,
|
||||
metawriter_properties const& properties);
|
||||
virtual void add_text(placement const& p,
|
||||
face_set_ptr face,
|
||||
virtual void add_text(text_placement_info const& p,
|
||||
face_manager_freetype &font_manager,
|
||||
Feature const& feature,
|
||||
CoordTransform const& t,
|
||||
metawriter_properties const& properties);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <deque>
|
||||
#include <algorithm>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
|
|
|
@ -23,86 +23,34 @@
|
|||
#ifndef MAPNIK_PLACEMENT_FINDER_HPP
|
||||
#define MAPNIK_PLACEMENT_FINDER_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/ctrans.hpp>
|
||||
#include <mapnik/label_collision_detector.hpp>
|
||||
#include <mapnik/text_symbolizer.hpp>
|
||||
#include <mapnik/shield_symbolizer.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/text_path.hpp>
|
||||
#include <mapnik/text_placements.hpp>
|
||||
|
||||
// stl
|
||||
#include <queue>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
typedef text_path placement_element;
|
||||
|
||||
struct placement : boost::noncopyable
|
||||
{
|
||||
placement(string_info & info_, shield_symbolizer const& sym, double scale_factor, unsigned w, unsigned h, bool has_dimensions_= false);
|
||||
|
||||
placement(string_info & info_, text_symbolizer const& sym, double scale_factor);
|
||||
|
||||
~placement();
|
||||
|
||||
string_info & info; // should only be used for finding placement. doesn't necessarily match placements.vertex() values
|
||||
|
||||
double scale_factor_;
|
||||
label_placement_e label_placement;
|
||||
|
||||
std::queue< box2d<double> > envelopes;
|
||||
|
||||
//output
|
||||
boost::ptr_vector<placement_element> placements;
|
||||
|
||||
int wrap_width;
|
||||
bool wrap_before; // wraps text at wrap_char immediately before current word
|
||||
unsigned char wrap_char;
|
||||
int text_ratio;
|
||||
|
||||
int label_spacing; // distance between repeated labels on a single geometry
|
||||
unsigned label_position_tolerance; //distance the label can be moved on the line to fit, if 0 the default is used
|
||||
bool force_odd_labels; //Always try render an odd amount of labels
|
||||
|
||||
double max_char_angle_delta;
|
||||
double minimum_distance;
|
||||
double minimum_padding;
|
||||
double minimum_path_length;
|
||||
bool avoid_edges;
|
||||
bool has_dimensions;
|
||||
bool allow_overlap;
|
||||
std::pair<double, double> dimensions;
|
||||
bool collect_extents;
|
||||
box2d<double> extents;
|
||||
|
||||
// additional boxes attached to the text labels which must also be
|
||||
// placed in order for the text placement to succeed. e.g: shields.
|
||||
std::vector<box2d<double> > additional_boxes;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename DetectorT>
|
||||
class placement_finder : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
placement_finder(DetectorT & detector);
|
||||
placement_finder(DetectorT & detector, box2d<double> const& extent);
|
||||
placement_finder(text_placement_info &p, string_info &info, DetectorT & detector);
|
||||
placement_finder(text_placement_info &p, string_info &info, DetectorT & detector, box2d<double> const& extent);
|
||||
|
||||
//Try place a single label at the given point
|
||||
void find_point_placement(placement & p, text_placement_info_ptr po, double pos_x, double pos_y, double angle=0.0, unsigned line_spacing=0, unsigned character_spacing=0);
|
||||
void find_point_placement(double pos_x, double pos_y, double angle=0.0);
|
||||
|
||||
//Iterate over the given path, placing point labels with respect to label_spacing
|
||||
template <typename T>
|
||||
void find_point_placements(placement & p, text_placement_info_ptr po, T & path);
|
||||
void find_point_placements(T & path);
|
||||
|
||||
//Iterate over the given path, placing line-following labels with respect to label_spacing
|
||||
template <typename T>
|
||||
void find_line_placements(placement & p, text_placement_info_ptr po, T & path);
|
||||
void find_line_placements(T & path);
|
||||
|
||||
void update_detector(placement & p);
|
||||
//Find placement, automatically select point or line placement
|
||||
void find_placement(double angle, geometry_type const& geom, CoordTransform const& t, proj_transform const& prj_trans);
|
||||
|
||||
void update_detector();
|
||||
|
||||
void clear();
|
||||
|
||||
|
@ -117,15 +65,14 @@ private:
|
|||
// otherwise it will autodetect the orientation.
|
||||
// If >= 50% of the characters end up upside down, it will be retried the other way.
|
||||
// RETURN: 1/-1 depending which way up the string ends up being.
|
||||
std::auto_ptr<placement_element> get_placement_offset(placement & p,
|
||||
const std::vector<vertex2d> & path_positions,
|
||||
std::auto_ptr<placement_element> get_placement_offset(const std::vector<vertex2d> & path_positions,
|
||||
const std::vector<double> & path_distances,
|
||||
int & orientation, unsigned index, double distance);
|
||||
|
||||
///Tests wether the given placement_element be placed without a collision
|
||||
// Returns true if it can
|
||||
// NOTE: This edits p.envelopes so it can be used afterwards (you must clear it otherwise)
|
||||
bool test_placement(placement & p, const std::auto_ptr<placement_element> & current_placement, const int & orientation);
|
||||
bool test_placement(const std::auto_ptr<placement_element> & current_placement, const int & orientation);
|
||||
|
||||
///Does a line-circle intersect calculation
|
||||
// NOTE: Follow the strict pre conditions
|
||||
|
@ -137,14 +84,26 @@ private:
|
|||
const double &x1, const double &y1, const double &x2, const double &y2,
|
||||
double &ix, double &iy);
|
||||
|
||||
void find_line_breaks();
|
||||
void init_string_size();
|
||||
void init_alignment();
|
||||
void adjust_position(placement_element *current_placement, double label_x, double label_y);
|
||||
|
||||
///General Internals
|
||||
|
||||
|
||||
|
||||
DetectorT & detector_;
|
||||
box2d<double> const& dimensions_;
|
||||
string_info &info_;
|
||||
text_symbolizer_properties &p;
|
||||
text_placement_info π
|
||||
double string_width_;
|
||||
double string_height_;
|
||||
double first_line_space_;
|
||||
vertical_alignment_e valign_;
|
||||
horizontal_alignment_e halign_;
|
||||
std::vector<unsigned> line_breaks_;
|
||||
std::vector<std::pair<double, double> > line_sizes_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // MAPNIK_PLACEMENT_FINDER_HPP
|
||||
|
|
|
@ -29,61 +29,22 @@
|
|||
#include <mapnik/filter_factory.hpp>
|
||||
#include <mapnik/enumeration.hpp>
|
||||
#include <mapnik/gamma_method.hpp>
|
||||
// stl
|
||||
#include <string>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
struct MAPNIK_DECL polygon_symbolizer : public symbolizer_base
|
||||
{
|
||||
polygon_symbolizer()
|
||||
: symbolizer_base(),
|
||||
fill_(color(128,128,128)),
|
||||
opacity_(1.0),
|
||||
gamma_(1.0),
|
||||
gamma_method_(GAMMA_POWER) {}
|
||||
|
||||
polygon_symbolizer(color const& fill)
|
||||
: symbolizer_base(),
|
||||
fill_(fill),
|
||||
opacity_(1.0),
|
||||
gamma_(1.0),
|
||||
gamma_method_(GAMMA_POWER) {}
|
||||
|
||||
color const& get_fill() const
|
||||
{
|
||||
return fill_;
|
||||
}
|
||||
|
||||
void set_fill(color const& fill)
|
||||
{
|
||||
fill_ = fill;
|
||||
}
|
||||
void set_opacity(double opacity)
|
||||
{
|
||||
opacity_ = opacity;
|
||||
}
|
||||
double get_opacity() const
|
||||
{
|
||||
return opacity_;
|
||||
}
|
||||
void set_gamma(double gamma)
|
||||
{
|
||||
gamma_ = gamma;
|
||||
}
|
||||
double get_gamma() const
|
||||
{
|
||||
return gamma_;
|
||||
}
|
||||
void set_gamma_method(gamma_method_e gamma_method)
|
||||
{
|
||||
gamma_method_ = gamma_method;
|
||||
}
|
||||
gamma_method_e get_gamma_method() const
|
||||
{
|
||||
return gamma_method_;
|
||||
}
|
||||
polygon_symbolizer();
|
||||
polygon_symbolizer(color const& fill);
|
||||
color const& get_fill() const;
|
||||
void set_fill(color const& fill);
|
||||
void set_opacity(double opacity);
|
||||
double get_opacity() const;
|
||||
void set_gamma(double gamma);
|
||||
double get_gamma() const;
|
||||
void set_gamma_method(gamma_method_e gamma_method);
|
||||
gamma_method_e get_gamma_method() const;
|
||||
|
||||
private:
|
||||
color fill_;
|
||||
|
@ -91,50 +52,7 @@ private:
|
|||
double gamma_;
|
||||
gamma_method_e gamma_method_;
|
||||
};
|
||||
|
||||
struct MAPNIK_DECL building_symbolizer : public symbolizer_base
|
||||
{
|
||||
explicit building_symbolizer()
|
||||
: symbolizer_base(),
|
||||
fill_(color(128,128,128)),
|
||||
opacity_(1.0)
|
||||
{}
|
||||
|
||||
building_symbolizer(color const& fill, expression_ptr height)
|
||||
: symbolizer_base(),
|
||||
fill_(fill),
|
||||
height_(height),
|
||||
opacity_(1.0) {}
|
||||
|
||||
color const& get_fill() const
|
||||
{
|
||||
return fill_;
|
||||
}
|
||||
void set_fill(color const& fill)
|
||||
{
|
||||
fill_ = fill;
|
||||
}
|
||||
expression_ptr height() const
|
||||
{
|
||||
return height_;
|
||||
}
|
||||
void set_height(expression_ptr height)
|
||||
{
|
||||
height_=height;
|
||||
}
|
||||
void set_opacity(double opacity)
|
||||
{
|
||||
opacity_ = opacity;
|
||||
}
|
||||
double get_opacity() const
|
||||
{
|
||||
return opacity_;
|
||||
}
|
||||
private:
|
||||
color fill_;
|
||||
expression_ptr height_;
|
||||
double opacity_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // MAPNIK_POLYGON_SYMBOLIZER_HPP
|
||||
|
|
|
@ -258,7 +258,7 @@ T get(const boost::property_tree::ptree & node, const std::string & name, bool i
|
|||
}
|
||||
else
|
||||
{
|
||||
str = node.get_optional<std::string>(name );
|
||||
str = node.get_optional<std::string>(name+".<xmltext>");
|
||||
}
|
||||
|
||||
if ( str ) {
|
||||
|
@ -289,7 +289,7 @@ inline color get(boost::property_tree::ptree const& node, std::string const& nam
|
|||
}
|
||||
else
|
||||
{
|
||||
str = node.get_optional<std::string>(name );
|
||||
str = node.get_optional<std::string>(name+".<xmltext>");
|
||||
}
|
||||
|
||||
if ( str )
|
||||
|
@ -322,7 +322,7 @@ T get(const boost::property_tree::ptree & node, const std::string & name, bool i
|
|||
}
|
||||
else
|
||||
{
|
||||
str = node.get_optional<std::string>(name);
|
||||
str = node.get_optional<std::string>(name+".<xmltext>");
|
||||
}
|
||||
|
||||
if ( ! str ) {
|
||||
|
@ -348,7 +348,18 @@ T get_value(const boost::property_tree::ptree & node, const std::string & name)
|
|||
{
|
||||
try
|
||||
{
|
||||
return node.get_value<T>();
|
||||
/* NOTE: get_child works as long as there is only one child with that name.
|
||||
If this function is used this used this condition must always be satisfied.
|
||||
*/
|
||||
return node.get_child("<xmltext>").get_value<T>();
|
||||
}
|
||||
catch (boost::property_tree::ptree_bad_path)
|
||||
{
|
||||
/* If the XML parser did not find any non-empty data element the is no
|
||||
<xmltext> node. But we don't want to fail here but simply return a
|
||||
default constructed value of the requested type.
|
||||
*/
|
||||
return T();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
@ -369,7 +380,7 @@ boost::optional<T> get_optional(const boost::property_tree::ptree & node, const
|
|||
}
|
||||
else
|
||||
{
|
||||
str = node.get_optional<std::string>(name);
|
||||
str = node.get_optional<std::string>(name+".<xmltext>");
|
||||
}
|
||||
|
||||
boost::optional<T> result;
|
||||
|
@ -403,7 +414,7 @@ inline boost::optional<color> get_optional(const boost::property_tree::ptree & n
|
|||
}
|
||||
else
|
||||
{
|
||||
str = node.get_optional<std::string>(name);
|
||||
str = node.get_optional<std::string>(name+".<xmltext>");
|
||||
}
|
||||
|
||||
boost::optional<color> result;
|
||||
|
|
|
@ -74,10 +74,13 @@ public:
|
|||
//! \param[in] value The stop value
|
||||
//! \param[in] mode The stop mode
|
||||
//! \param[in] color The stop color
|
||||
colorizer_stop(const float value = 0, const colorizer_mode mode = COLORIZER_INHERIT, const color& _color = color(0,0,0,0), const std::string& label="");
|
||||
colorizer_stop(float value = 0,
|
||||
colorizer_mode mode = COLORIZER_INHERIT,
|
||||
color const& _color = color(0,0,0,0),
|
||||
std::string const& label="");
|
||||
|
||||
//! \brief Copy constructor
|
||||
colorizer_stop(const colorizer_stop& stop);
|
||||
colorizer_stop(colorizer_stop const& stop);
|
||||
|
||||
//! \brief Destructor
|
||||
~colorizer_stop();
|
||||
|
@ -85,39 +88,39 @@ public:
|
|||
|
||||
//! \brief Set the stop value
|
||||
//! \param[in] value The stop value
|
||||
inline void set_value(const float value) { value_ = value; };
|
||||
inline void set_value(float value) { value_ = value; };
|
||||
|
||||
//! \brief Get the stop value
|
||||
//! \return The stop value
|
||||
inline float get_value(void) const {return value_; };
|
||||
inline float get_value() const {return value_; };
|
||||
|
||||
|
||||
//! \brief Set the stop mode
|
||||
//! \param[in] mode The stop mode
|
||||
inline void set_mode(const colorizer_mode mode) { mode_ = mode; };
|
||||
inline void set_mode_enum(const colorizer_mode_enum mode) { set_mode(mode); };
|
||||
inline void set_mode(colorizer_mode mode) { mode_ = mode; };
|
||||
inline void set_mode_enum(colorizer_mode_enum mode) { set_mode(mode); };
|
||||
|
||||
//! \brief Get the stop mode
|
||||
//! \return The stop mode
|
||||
inline colorizer_mode get_mode(void) const { return mode_; };
|
||||
inline colorizer_mode_enum get_mode_enum(void) const { return get_mode(); };
|
||||
inline colorizer_mode get_mode() const { return mode_; };
|
||||
inline colorizer_mode_enum get_mode_enum() const { return get_mode(); };
|
||||
|
||||
|
||||
//! \brief set the stop color
|
||||
//! \param[in] the stop color
|
||||
inline void set_color(const color& _color) { color_ = _color; };
|
||||
inline void set_color(color const& _color) { color_ = _color; };
|
||||
|
||||
//! \brief get the stop color
|
||||
//! \return The stop color
|
||||
inline const color& get_color(void) const {return color_; };
|
||||
inline color const& get_color() const {return color_; };
|
||||
|
||||
//! \brief set the stop label
|
||||
//! \param[in] the stop label
|
||||
inline void set_label(const std::string& label) { label_ = label; };
|
||||
inline void set_label(std::string const& label) { label_ = label; };
|
||||
|
||||
//! \brief get the stop label
|
||||
//! \return The stop label
|
||||
inline const std::string& get_label(void) const {return label_; };
|
||||
inline std::string const& get_label() const {return label_; };
|
||||
|
||||
|
||||
//! \brief Equality operator
|
||||
|
@ -140,10 +143,11 @@ typedef std::vector<colorizer_stop> colorizer_stops;
|
|||
|
||||
|
||||
//! \brief Class representing the raster colorizer
|
||||
class MAPNIK_DECL raster_colorizer {
|
||||
class MAPNIK_DECL raster_colorizer
|
||||
{
|
||||
public:
|
||||
//! \brief Constructor
|
||||
raster_colorizer(colorizer_mode mode = COLORIZER_LINEAR, const color& _color = color(0,0,0,0));
|
||||
raster_colorizer(colorizer_mode mode = COLORIZER_LINEAR, color const& _color = color(0,0,0,0));
|
||||
|
||||
//! \brief Destructor
|
||||
~raster_colorizer();
|
||||
|
@ -153,28 +157,33 @@ public:
|
|||
//!
|
||||
//! This can not be set as INHERIT, if you do, LINEAR will be used instead.
|
||||
//! \param[in] mode The default mode
|
||||
void set_default_mode(const colorizer_mode mode) { default_mode_ = (mode == COLORIZER_INHERIT) ? COLORIZER_LINEAR:(colorizer_mode_enum)mode; };
|
||||
void set_default_mode_enum(const colorizer_mode_enum mode) { set_default_mode(mode); };
|
||||
|
||||
void set_default_mode(colorizer_mode mode)
|
||||
{
|
||||
default_mode_ = (mode == COLORIZER_INHERIT) ? COLORIZER_LINEAR:(colorizer_mode_enum)mode;
|
||||
};
|
||||
|
||||
void set_default_mode_enum(colorizer_mode_enum mode) { set_default_mode(mode); };
|
||||
|
||||
//! \brief Get the default mode
|
||||
//! \return The default mode
|
||||
colorizer_mode get_default_mode(void) const {return default_mode_; };
|
||||
colorizer_mode_enum get_default_mode_enum(void) const {return get_default_mode(); };
|
||||
colorizer_mode get_default_mode() const {return default_mode_; };
|
||||
colorizer_mode_enum get_default_mode_enum() const {return get_default_mode(); };
|
||||
|
||||
//! \brief Set the default color
|
||||
//! \param[in] color The default color
|
||||
void set_default_color(const color& color) { default_color_ = color; };
|
||||
void set_default_color(color const& color) { default_color_ = color; };
|
||||
|
||||
//! \brief Get the default color
|
||||
//! \return The default color
|
||||
const color& get_default_color(void) const {return default_color_; };
|
||||
color const& get_default_color() const {return default_color_; };
|
||||
|
||||
|
||||
//! \brief Add a stop
|
||||
//!
|
||||
//! \param[in] stop The stop to add
|
||||
//! \return True if added, false if error
|
||||
bool add_stop(const colorizer_stop & stop);
|
||||
bool add_stop(colorizer_stop const& stop);
|
||||
|
||||
//! \brief Set the list of stops
|
||||
//! \param[in] stops The list of stops
|
||||
|
@ -182,16 +191,16 @@ public:
|
|||
|
||||
//! \brief Get the list of stops
|
||||
//! \return The list of stops
|
||||
const colorizer_stops& get_stops(void) const {return stops_; };
|
||||
colorizer_stops const& get_stops() const {return stops_; };
|
||||
|
||||
|
||||
//! \brief Colorize a raster
|
||||
//!
|
||||
//! \param[in, out] raster A raster stored in float32 single channel format, which gets colorized in place.
|
||||
//! \param[in] properties belonging to the feature, used to find 'NODATA' information if available
|
||||
void colorize(raster_ptr const& raster,const std::map<std::string,value> &Props) const;
|
||||
|
||||
//! \param[in] feature used to find 'NODATA' information if available
|
||||
void colorize(raster_ptr const& raster, Feature const& f) const;
|
||||
|
||||
|
||||
//! \brief Perform the translation of input to output
|
||||
//!
|
||||
//! \param[in] value Input value
|
||||
|
@ -205,7 +214,7 @@ public:
|
|||
|
||||
//! \brief Get the epsilon value for exact mode
|
||||
//! \return The epsilon value
|
||||
inline float get_epsilon(void) const { return epsilon_; };
|
||||
inline float get_epsilon() const { return epsilon_; };
|
||||
|
||||
private:
|
||||
colorizer_stops stops_; //!< The vector of stops
|
||||
|
|
|
@ -23,7 +23,8 @@
|
|||
#ifndef MAPNIK_RULE_HPP
|
||||
#define MAPNIK_RULE_HPP
|
||||
|
||||
// mapnik
|
||||
// mapni
|
||||
#include <mapnik/building_symbolizer.hpp>
|
||||
#include <mapnik/line_symbolizer.hpp>
|
||||
#include <mapnik/line_pattern_symbolizer.hpp>
|
||||
#include <mapnik/polygon_symbolizer.hpp>
|
||||
|
@ -33,7 +34,6 @@
|
|||
#include <mapnik/shield_symbolizer.hpp>
|
||||
#include <mapnik/text_symbolizer.hpp>
|
||||
#include <mapnik/markers_symbolizer.hpp>
|
||||
#include <mapnik/glyph_symbolizer.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/filter_factory.hpp>
|
||||
#include <mapnik/expression_string.hpp>
|
||||
|
@ -108,11 +108,6 @@ inline bool operator==(markers_symbolizer const& lhs,
|
|||
return (&lhs == &rhs);
|
||||
}
|
||||
|
||||
inline bool operator==(glyph_symbolizer const& lhs,
|
||||
glyph_symbolizer const& rhs)
|
||||
{
|
||||
return (&lhs == &rhs);
|
||||
}
|
||||
typedef boost::variant<point_symbolizer,
|
||||
line_symbolizer,
|
||||
line_pattern_symbolizer,
|
||||
|
@ -122,8 +117,7 @@ typedef boost::variant<point_symbolizer,
|
|||
shield_symbolizer,
|
||||
text_symbolizer,
|
||||
building_symbolizer,
|
||||
markers_symbolizer,
|
||||
glyph_symbolizer> symbolizer;
|
||||
markers_symbolizer> symbolizer;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@ namespace mapnik
|
|||
struct MAPNIK_DECL shield_symbolizer : public text_symbolizer,
|
||||
public symbolizer_with_image
|
||||
{
|
||||
shield_symbolizer(text_placements_ptr placements = text_placements_ptr(
|
||||
boost::make_shared<text_placements_dummy>()));
|
||||
shield_symbolizer(expression_ptr name,
|
||||
std::string const& face_name,
|
||||
float size,
|
||||
|
|
|
@ -83,9 +83,6 @@ namespace mapnik
|
|||
void process(markers_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans);
|
||||
void process(glyph_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans);
|
||||
|
||||
/*!
|
||||
* @brief Overload that process the whole set of symbolizers of a rule.
|
||||
|
|
|
@ -96,10 +96,10 @@ public:
|
|||
void set_opacity(float opacity);
|
||||
float get_opacity() const;
|
||||
protected:
|
||||
symbolizer_with_image(path_expression_ptr filename);
|
||||
symbolizer_with_image(path_expression_ptr filename = path_expression_ptr());
|
||||
symbolizer_with_image(symbolizer_with_image const& rhs);
|
||||
path_expression_ptr image_filename_;
|
||||
float opacity_;
|
||||
float image_opacity_;
|
||||
transform_type matrix_;
|
||||
};
|
||||
}
|
||||
|
|
185
include/mapnik/symbolizer_helpers.hpp
Normal file
185
include/mapnik/symbolizer_helpers.hpp
Normal file
|
@ -0,0 +1,185 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2012 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef SYMBOLIZER_HELPERS_HPP
|
||||
#define SYMBOLIZER_HELPERS_HPP
|
||||
|
||||
#include <mapnik/text_symbolizer.hpp>
|
||||
#include <mapnik/text_processing.hpp>
|
||||
#include <mapnik/placement_finder.hpp>
|
||||
#include <mapnik/expression_evaluator.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
|
||||
struct greater_bbox_comp
|
||||
{
|
||||
bool operator() (geometry_type const* g0, geometry_type const* g1) const
|
||||
{
|
||||
box2d<double> b0 = g0->envelope();
|
||||
box2d<double> b1 = g1->envelope();
|
||||
return b0.width()*b0.height() > b1.width()*b1.height();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename FaceManagerT, typename DetectorT>
|
||||
class text_symbolizer_helper
|
||||
{
|
||||
public:
|
||||
text_symbolizer_helper(unsigned width,
|
||||
unsigned height,
|
||||
double scale_factor,
|
||||
CoordTransform const &t,
|
||||
FaceManagerT &font_manager,
|
||||
DetectorT &detector) :
|
||||
width_(width),
|
||||
height_(height),
|
||||
scale_factor_(scale_factor),
|
||||
t_(t),
|
||||
font_manager_(font_manager),
|
||||
detector_(detector),
|
||||
text_()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
text_placement_info_ptr get_placement(text_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans);
|
||||
private:
|
||||
bool initialize_geometries(std::vector<geometry_type*> & geometries_to_process,
|
||||
text_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans);
|
||||
|
||||
unsigned width_;
|
||||
unsigned height_;
|
||||
double scale_factor_;
|
||||
CoordTransform const &t_;
|
||||
FaceManagerT &font_manager_;
|
||||
DetectorT &detector_;
|
||||
boost::shared_ptr<processed_text> text_; /*TODO: Use shared pointers for text placement so we don't need to keep a reference here! */
|
||||
};
|
||||
|
||||
|
||||
template <typename FaceManagerT, typename DetectorT>
|
||||
text_placement_info_ptr text_symbolizer_helper<FaceManagerT, DetectorT>::get_placement(
|
||||
text_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
|
||||
unsigned num_geom = feature.num_geometries();
|
||||
if (!num_geom) return text_placement_info_ptr(); //Nothing to do
|
||||
|
||||
std::vector<geometry_type*> geometries_to_process;
|
||||
|
||||
if (!initialize_geometries(geometries_to_process,sym, feature, prj_trans))
|
||||
return text_placement_info_ptr();
|
||||
|
||||
text_ = boost::shared_ptr<processed_text>(new processed_text(font_manager_, scale_factor_));
|
||||
metawriter_with_properties writer = sym.get_metawriter();
|
||||
|
||||
box2d<double> dims(0, 0, width_, height_);
|
||||
|
||||
text_placement_info_ptr placement = sym.get_placement_options()->get_placement_info();
|
||||
placement->init(scale_factor_, width_, height_);
|
||||
if (writer.first)
|
||||
placement->collect_extents = true;
|
||||
|
||||
|
||||
|
||||
while (placement->next())
|
||||
{
|
||||
text_processor &processor = placement->properties.processor;
|
||||
text_symbolizer_properties const& p = placement->properties;
|
||||
/* TODO: Simplify this. */
|
||||
text_->clear();
|
||||
processor.process(*text_, feature);
|
||||
string_info &info = text_->get_string_info();
|
||||
/* END TODO */
|
||||
// text rotation
|
||||
double angle = 0.0;
|
||||
if (p.orientation)
|
||||
{
|
||||
angle = boost::apply_visitor(evaluate<Feature,value_type>(feature),*(p.orientation)).to_double();
|
||||
}
|
||||
placement_finder<DetectorT> finder(*placement, info, detector_, dims);
|
||||
|
||||
BOOST_FOREACH( geometry_type * geom, geometries_to_process )
|
||||
{
|
||||
finder.find_placement(angle, *geom, t_, prj_trans);
|
||||
//if (!placement->placements.size())
|
||||
// continue;
|
||||
//if (writer.first) writer.first->add_text(*placement, font_manager_, feature, t_, writer.second);
|
||||
//return placement;
|
||||
}
|
||||
return placement;
|
||||
}
|
||||
return text_placement_info_ptr();
|
||||
}
|
||||
|
||||
template <typename FaceManagerT, typename DetectorT>
|
||||
bool text_symbolizer_helper<FaceManagerT, DetectorT>::initialize_geometries(
|
||||
std::vector<geometry_type*> & geometries_to_process,
|
||||
text_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
unsigned num_geom = feature.num_geometries();
|
||||
|
||||
for (unsigned i=0; i<num_geom; ++i)
|
||||
{
|
||||
geometry_type const& geom = feature.get_geometry(i);
|
||||
|
||||
// don't bother with empty geometries
|
||||
if (geom.num_points() == 0) continue;
|
||||
|
||||
if ((geom.type() == Polygon) && sym.get_minimum_path_length() > 0)
|
||||
{
|
||||
// TODO - find less costly method than fetching full envelope
|
||||
box2d<double> gbox = t_.forward(geom.envelope(),prj_trans);
|
||||
if (gbox.width() < sym.get_minimum_path_length())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// TODO - calculate length here as well
|
||||
geometries_to_process.push_back(const_cast<geometry_type*>(&geom));
|
||||
}
|
||||
|
||||
std::sort(geometries_to_process.begin(), geometries_to_process.end(), greater_bbox_comp());
|
||||
|
||||
if (!geometries_to_process.size() > 0)
|
||||
{
|
||||
// early return to avoid significant overhead of rendering setup
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
#endif // SYMBOLIZER_HELPERS_HPP
|
|
@ -23,6 +23,12 @@
|
|||
#ifndef MAPNIK_TEXT_PATH_HPP
|
||||
#define MAPNIK_TEXT_PATH_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/char_info.hpp>
|
||||
|
||||
//stl
|
||||
#include <vector>
|
||||
|
||||
// boost
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
@ -32,41 +38,39 @@
|
|||
|
||||
namespace mapnik
|
||||
{
|
||||
struct character_info
|
||||
{
|
||||
int character;
|
||||
double width, height;
|
||||
|
||||
character_info() : character(0), width(0), height(0) {}
|
||||
character_info(int c_, double width_, double height_) : character(c_), width(width_), height(height_) {}
|
||||
~character_info() {}
|
||||
|
||||
character_info(const character_info &ci)
|
||||
: character(ci.character), width(ci.width), height(ci.height)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class string_info : private boost::noncopyable
|
||||
{
|
||||
protected:
|
||||
typedef boost::ptr_vector<character_info> characters_t;
|
||||
typedef std::vector<char_info> characters_t;
|
||||
characters_t characters_;
|
||||
UnicodeString const& text_;
|
||||
double width_;
|
||||
double height_;
|
||||
UnicodeString text_;
|
||||
bool is_rtl;
|
||||
public:
|
||||
string_info(UnicodeString const& text)
|
||||
: text_(text),
|
||||
width_(0),
|
||||
height_(0),
|
||||
is_rtl(false) {}
|
||||
|
||||
void add_info(int c, double width, double height)
|
||||
: characters_(),
|
||||
text_(text),
|
||||
is_rtl(false)
|
||||
{
|
||||
characters_.push_back(new character_info(c, width, height));
|
||||
|
||||
}
|
||||
|
||||
string_info()
|
||||
: characters_(),
|
||||
text_(),
|
||||
is_rtl(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void add_info(char_info const& info)
|
||||
{
|
||||
characters_.push_back(info);
|
||||
}
|
||||
|
||||
void add_text(UnicodeString text)
|
||||
{
|
||||
text_ += text;
|
||||
}
|
||||
|
||||
unsigned num_characters() const
|
||||
|
@ -74,29 +78,25 @@ public:
|
|||
return characters_.size();
|
||||
}
|
||||
|
||||
void set_rtl(bool value) {is_rtl = value;}
|
||||
bool get_rtl() const {return is_rtl;}
|
||||
void set_rtl(bool value)
|
||||
{
|
||||
is_rtl = value;
|
||||
}
|
||||
|
||||
bool get_rtl() const
|
||||
{
|
||||
return is_rtl;
|
||||
}
|
||||
|
||||
character_info at(unsigned i) const
|
||||
char_info const& at(unsigned i) const
|
||||
{
|
||||
return characters_[i];
|
||||
}
|
||||
|
||||
character_info operator[](unsigned i) const
|
||||
char_info const& operator[](unsigned i) const
|
||||
{
|
||||
return at(i);
|
||||
}
|
||||
|
||||
void set_dimensions(double width, double height)
|
||||
{
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
}
|
||||
|
||||
std::pair<double, double> get_dimensions() const
|
||||
{
|
||||
return std::pair<double, double>(width_, height_);
|
||||
}
|
||||
|
||||
UnicodeString const& get_string() const
|
||||
{
|
||||
|
@ -108,69 +108,84 @@ public:
|
|||
UChar break_char = '\n';
|
||||
return (text_.indexOf(break_char) >= 0);
|
||||
}
|
||||
|
||||
/** Resets object to initial state. */
|
||||
void clear(void)
|
||||
{
|
||||
text_ = "";
|
||||
characters_.clear();
|
||||
}
|
||||
};
|
||||
|
||||
struct text_path : boost::noncopyable
|
||||
|
||||
/** List of all characters and their positions and formats for a placement. */
|
||||
class text_path : boost::noncopyable
|
||||
{
|
||||
struct character_node
|
||||
{
|
||||
int c;
|
||||
double x, y, angle;
|
||||
char_properties *format;
|
||||
|
||||
character_node(int c_, double x_, double y_, double angle_)
|
||||
: c(c_), x(x_), y(y_), angle(angle_) {}
|
||||
character_node(int c_, double x_, double y_, double angle_, char_properties *format_)
|
||||
: c(c_), x(x_), y(y_), angle(angle_), format(format_) {}
|
||||
~character_node() {}
|
||||
|
||||
void vertex(int *c_, double *x_, double *y_, double *angle_)
|
||||
void vertex(int *c_, double *x_, double *y_, double *angle_, char_properties **format_)
|
||||
{
|
||||
*c_ = c;
|
||||
*x_ = x;
|
||||
*y_ = y;
|
||||
*angle_ = angle;
|
||||
*format_ = format;
|
||||
}
|
||||
};
|
||||
|
||||
int itr_;
|
||||
public:
|
||||
typedef std::vector<character_node> character_nodes_t;
|
||||
character_nodes_t nodes_;
|
||||
double starting_x;
|
||||
double starting_y;
|
||||
character_nodes_t nodes_;
|
||||
int itr_;
|
||||
|
||||
std::pair<unsigned,unsigned> string_dimensions;
|
||||
// std::pair<unsigned,unsigned> string_dimensions;
|
||||
|
||||
text_path()
|
||||
: starting_x(0),
|
||||
starting_y(0),
|
||||
itr_(0) {}
|
||||
|
||||
//text_path(text_path const& other) :
|
||||
// itr_(0),
|
||||
// nodes_(other.nodes_),
|
||||
// string_dimensions(other.string_dimensions)
|
||||
//{}
|
||||
: itr_(0),
|
||||
starting_x(0),
|
||||
starting_y(0)
|
||||
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
~text_path() {}
|
||||
|
||||
void add_node(int c, double x, double y, double angle)
|
||||
/** Adds a new char to the list. */
|
||||
void add_node(int c, double x, double y, double angle, char_properties *format)
|
||||
{
|
||||
nodes_.push_back(character_node(c, x, y, angle));
|
||||
nodes_.push_back(character_node(c, x, y, angle, format));
|
||||
}
|
||||
|
||||
void vertex(int *c, double *x, double *y, double *angle)
|
||||
/** Return node. Always returns a new node. Has no way to report that there are no more nodes. */
|
||||
void vertex(int *c, double *x, double *y, double *angle, char_properties **format)
|
||||
{
|
||||
nodes_[itr_++].vertex(c, x, y, angle);
|
||||
nodes_[itr_++].vertex(c, x, y, angle, format);
|
||||
}
|
||||
|
||||
/** Start again at first node. */
|
||||
void rewind()
|
||||
{
|
||||
itr_ = 0;
|
||||
}
|
||||
|
||||
/** Number of nodes. */
|
||||
int num_nodes() const
|
||||
{
|
||||
return nodes_.size();
|
||||
}
|
||||
|
||||
/** Delete all nodes. */
|
||||
void clear()
|
||||
{
|
||||
nodes_.clear();
|
||||
|
|
|
@ -24,20 +24,30 @@
|
|||
#define MAPNIK_TEXT_PLACEMENTS_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/enumeration.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/font_set.hpp>
|
||||
#include <mapnik/text_path.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/text_processing.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
|
||||
// boost
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
class text_placements;
|
||||
|
||||
typedef text_path placement_element;
|
||||
|
||||
typedef boost::tuple<double,double> position;
|
||||
|
||||
enum label_placement_enum {
|
||||
|
@ -82,80 +92,140 @@ enum justify_alignment
|
|||
|
||||
DEFINE_ENUM( justify_alignment_e, justify_alignment );
|
||||
|
||||
enum text_transform
|
||||
/** Contains all text symbolizer properties which are not directly related to text formating. */
|
||||
struct text_symbolizer_properties
|
||||
{
|
||||
NONE = 0,
|
||||
UPPERCASE,
|
||||
LOWERCASE,
|
||||
CAPITALIZE,
|
||||
text_transform_MAX
|
||||
};
|
||||
text_symbolizer_properties();
|
||||
/** Load all values and also the ```processor``` object from XML ptree. */
|
||||
void set_values_from_xml(boost::property_tree::ptree const &sym, std::map<std::string,font_set> const & fontsets);
|
||||
/** Save all values to XML ptree (but does not create a new parent node!). */
|
||||
void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, text_symbolizer_properties const &dfl=text_symbolizer_properties()) const;
|
||||
|
||||
DEFINE_ENUM( text_transform_e, text_transform );
|
||||
|
||||
class text_placements;
|
||||
|
||||
class text_placement_info : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
text_placement_info(text_placements const* parent);
|
||||
/** Get next placement.
|
||||
* This function is also called before the first placement is tried. */
|
||||
virtual bool next()=0;
|
||||
/** Get next placement position.
|
||||
* This function is also called before the first position is used.
|
||||
* Each class has to return at least one position!
|
||||
* If this functions returns false the placement data should be considered invalid!
|
||||
*/
|
||||
virtual bool next_position_only()=0;
|
||||
virtual ~text_placement_info() {}
|
||||
|
||||
/* NOTE: Values are public and non-virtual to avoid any performance problems. */
|
||||
//Per symbolizer options
|
||||
expression_ptr orientation;
|
||||
position displacement;
|
||||
float text_size;
|
||||
label_placement_e label_placement;
|
||||
horizontal_alignment_e halign;
|
||||
justify_alignment_e jalign;
|
||||
vertical_alignment_e valign;
|
||||
/** distance between repeated labels on a single geometry */
|
||||
unsigned label_spacing;
|
||||
/** distance the label can be moved on the line to fit, if 0 the default is used */
|
||||
unsigned label_position_tolerance;
|
||||
bool avoid_edges;
|
||||
double minimum_distance;
|
||||
double minimum_padding;
|
||||
double minimum_path_length;
|
||||
double max_char_angle_delta;
|
||||
/** Always try render an odd amount of labels */
|
||||
bool force_odd_labels;
|
||||
bool allow_overlap;
|
||||
unsigned text_ratio;
|
||||
unsigned wrap_width;
|
||||
/** Contains everything related to text formating */
|
||||
text_processor processor;
|
||||
};
|
||||
|
||||
|
||||
/** Generate a possible placement and store results of placement_finder.
|
||||
* This placement has first to be tested by placement_finder to verify it
|
||||
* can actually be used.
|
||||
*/
|
||||
class text_placement_info : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
/** Constructor. Takes the parent text_placements object as a parameter
|
||||
* to read defaults from it. */
|
||||
text_placement_info(text_placements const* parent);
|
||||
/** Get next placement.
|
||||
* This function is also called before the first placement is tried.
|
||||
* Each class has to return at least one position!
|
||||
* If this functions returns false the placement data should be
|
||||
* considered invalid!
|
||||
*/
|
||||
virtual bool next()=0;
|
||||
virtual ~text_placement_info() {}
|
||||
/** Initialize values used by placement finder. Only has to be done once
|
||||
* per object.
|
||||
*/
|
||||
void init(double scale_factor_,
|
||||
unsigned w = 0, unsigned h = 0, bool has_dimensions_ = false);
|
||||
|
||||
/** Properties actually used by placement finder and renderer. Values in
|
||||
* here are modified each time next() is called. */
|
||||
text_symbolizer_properties properties;
|
||||
|
||||
/** Scale factor used by the renderer. */
|
||||
double scale_factor;
|
||||
/* TODO: Don't know what this is used for. */
|
||||
bool has_dimensions;
|
||||
/* TODO: Don't know what this is used for. */
|
||||
std::pair<double, double> dimensions;
|
||||
/** Set scale factor. */
|
||||
void set_scale_factor(double factor) { scale_factor = factor; }
|
||||
/** Get scale factor. */
|
||||
double get_scale_factor() { return scale_factor; }
|
||||
/** Get label spacing taking the scale factor into account. */
|
||||
double get_actual_label_spacing() { return scale_factor * properties.label_spacing; }
|
||||
/** Get minimum distance taking the scale factor into account. */
|
||||
double get_actual_minimum_distance() { return scale_factor * properties.minimum_distance; }
|
||||
/** Get minimum padding taking the scale factor into account. */
|
||||
double get_actual_minimum_padding() { return scale_factor * properties.minimum_padding; }
|
||||
|
||||
/** Collect a bounding box of all texts placed. */
|
||||
bool collect_extents;
|
||||
//Output by placement finder
|
||||
/** Bounding box of all texts placed. */
|
||||
box2d<double> extents;
|
||||
/* TODO */
|
||||
std::queue< box2d<double> > envelopes;
|
||||
/* TODO */
|
||||
boost::ptr_vector<placement_element> placements;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<text_placement_info> text_placement_info_ptr;
|
||||
|
||||
/** This object handles the management of all TextSymbolizer properties. It can
|
||||
* be used as a base class for own objects which implement new processing
|
||||
* semantics. Basically this class just makes sure a pointer of the right
|
||||
* class is returned by the get_placement_info call.
|
||||
*/
|
||||
class text_placements
|
||||
{
|
||||
public:
|
||||
text_placements() :
|
||||
text_size_(10), halign_(H_MIDDLE), jalign_(J_MIDDLE), valign_(V_MIDDLE) {}
|
||||
text_placements();
|
||||
/** Get a text_placement_info object to use in rendering.
|
||||
* The returned object creates a list of settings which is
|
||||
* used to try to find a placement and stores all
|
||||
* information that is generated by
|
||||
* the placement finder.
|
||||
*
|
||||
* This function usually is implemented as
|
||||
* text_placement_info_ptr text_placements_XXX::get_placement_info() const
|
||||
* {
|
||||
* return text_placement_info_ptr(new text_placement_info_XXX(this));
|
||||
* }
|
||||
*/
|
||||
virtual text_placement_info_ptr get_placement_info() const =0;
|
||||
/** Get a list of all expressions used in any placement.
|
||||
* This function is used to collect attributes.
|
||||
*/
|
||||
virtual std::set<expression_ptr> get_all_expressions();
|
||||
|
||||
virtual void set_default_text_size(float size) { text_size_ = size; }
|
||||
float get_default_text_size() const { return text_size_; }
|
||||
|
||||
virtual void set_default_displacement(position const& displacement) { displacement_ = displacement;}
|
||||
position const& get_default_displacement() { return displacement_; }
|
||||
|
||||
virtual void set_default_halign(horizontal_alignment_e const& align) { halign_ = align;}
|
||||
horizontal_alignment_e const& get_default_halign() { return halign_; }
|
||||
|
||||
virtual void set_default_jalign(justify_alignment_e const& align) { jalign_ = align;}
|
||||
justify_alignment_e const& get_default_jalign() { return jalign_; }
|
||||
|
||||
virtual void set_default_valign(vertical_alignment_e const& align) { valign_ = align;}
|
||||
vertical_alignment_e const& get_default_valign() { return valign_; }
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~text_placements() {}
|
||||
protected:
|
||||
float text_size_;
|
||||
position displacement_;
|
||||
horizontal_alignment_e halign_;
|
||||
justify_alignment_e jalign_;
|
||||
vertical_alignment_e valign_;
|
||||
friend class text_placement_info;
|
||||
|
||||
/** List of all properties used as the default for the subclasses. */
|
||||
text_symbolizer_properties properties;
|
||||
};
|
||||
|
||||
/** Pointer to object of class text_placements */
|
||||
typedef boost::shared_ptr<text_placements> text_placements_ptr;
|
||||
|
||||
|
||||
class text_placements_info_dummy;
|
||||
|
||||
/** Dummy placement algorithm. Always takes the default value. */
|
||||
class MAPNIK_DECL text_placements_dummy: public text_placements
|
||||
{
|
||||
public:
|
||||
|
@ -163,20 +233,20 @@ public:
|
|||
friend class text_placement_info_dummy;
|
||||
};
|
||||
|
||||
/** Placement info object for dummy placement algorithm. Always takes the default value. */
|
||||
class MAPNIK_DECL text_placement_info_dummy : public text_placement_info
|
||||
{
|
||||
public:
|
||||
text_placement_info_dummy(text_placements_dummy const* parent) : text_placement_info(parent),
|
||||
state(0), position_state(0), parent_(parent) {}
|
||||
state(0), parent_(parent) {}
|
||||
bool next();
|
||||
bool next_position_only();
|
||||
private:
|
||||
unsigned state;
|
||||
unsigned position_state;
|
||||
text_placements_dummy const* parent_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
#endif // MAPNIK_TEXT_PLACEMENTS_HPP
|
||||
|
|
61
include/mapnik/text_placements_list.hpp
Normal file
61
include/mapnik/text_placements_list.hpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2011 Hermann Kraus
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef TEXT_PLACEMENTS_LIST_HPP
|
||||
#define TEXT_PLACEMENTS_LIST_HPP
|
||||
#include <mapnik/text_placements.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
class text_placement_info_list;
|
||||
|
||||
|
||||
/** Tries a list of placements. */
|
||||
class text_placements_list: public text_placements
|
||||
{
|
||||
public:
|
||||
text_placements_list();
|
||||
text_placement_info_ptr get_placement_info() const;
|
||||
virtual std::set<expression_ptr> get_all_expressions();
|
||||
text_symbolizer_properties & add();
|
||||
text_symbolizer_properties & get(unsigned i);
|
||||
unsigned size() const;
|
||||
private:
|
||||
std::vector<text_symbolizer_properties> list_;
|
||||
friend class text_placement_info_list;
|
||||
};
|
||||
|
||||
/** List placement strategy.
|
||||
* See parent class for documentation of each function. */
|
||||
class text_placement_info_list : public text_placement_info
|
||||
{
|
||||
public:
|
||||
text_placement_info_list(text_placements_list const* parent) :
|
||||
text_placement_info(parent), state(0), parent_(parent) {}
|
||||
bool next();
|
||||
private:
|
||||
unsigned state;
|
||||
text_placements_list const* parent_;
|
||||
};
|
||||
|
||||
|
||||
} //namespace
|
||||
#endif
|
|
@ -51,6 +51,7 @@ public:
|
|||
text_placements_simple(std::string positions);
|
||||
text_placement_info_ptr get_placement_info() const;
|
||||
void set_positions(std::string positions);
|
||||
std::string const& get_positions() const;
|
||||
private:
|
||||
std::string positions_;
|
||||
std::vector<directions_t> direction_;
|
||||
|
@ -66,8 +67,8 @@ public:
|
|||
text_placement_info_simple(text_placements_simple const* parent) :
|
||||
text_placement_info(parent), state(0), position_state(0), parent_(parent) {}
|
||||
bool next();
|
||||
protected:
|
||||
bool next_position_only();
|
||||
private:
|
||||
unsigned state;
|
||||
unsigned position_state;
|
||||
text_placements_simple const* parent_;
|
||||
|
|
134
include/mapnik/text_processing.hpp
Normal file
134
include/mapnik/text_processing.hpp
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef MAPNIK_TEXT_PROCESSING_HPP
|
||||
#define MAPNIK_TEXT_PROCESSING_HPP
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/ctrans.hpp>
|
||||
#include <mapnik/label_collision_detector.hpp>
|
||||
#include <mapnik/font_engine_freetype.hpp>
|
||||
#include <mapnik/text_path.hpp>
|
||||
#include <mapnik/enumeration.hpp>
|
||||
#include <mapnik/filter_factory.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
enum text_transform
|
||||
{
|
||||
NONE = 0,
|
||||
UPPERCASE,
|
||||
LOWERCASE,
|
||||
CAPITALIZE,
|
||||
text_transform_MAX
|
||||
};
|
||||
|
||||
DEFINE_ENUM( text_transform_e, text_transform );
|
||||
|
||||
struct char_properties
|
||||
{
|
||||
char_properties();
|
||||
/** Construct object from XML. */
|
||||
void set_values_from_xml(boost::property_tree::ptree const &sym, std::map<std::string,font_set> const & fontsets);
|
||||
/** Write object to XML ptree. */
|
||||
void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, char_properties const &dfl=char_properties()) const;
|
||||
std::string face_name;
|
||||
font_set fontset;
|
||||
float text_size;
|
||||
double character_spacing;
|
||||
double line_spacing; //Largest total height (fontsize+line_spacing) per line is chosen
|
||||
double text_opacity;
|
||||
bool wrap_before;
|
||||
unsigned wrap_char;
|
||||
text_transform_e text_transform; //Per expression
|
||||
color fill;
|
||||
color halo_fill;
|
||||
double halo_radius;
|
||||
};
|
||||
|
||||
class processed_expression
|
||||
{
|
||||
public:
|
||||
processed_expression(char_properties const& properties, UnicodeString const& text) :
|
||||
p(properties), str(text) {}
|
||||
char_properties p;
|
||||
UnicodeString str;
|
||||
};
|
||||
|
||||
class processed_text
|
||||
{
|
||||
public:
|
||||
processed_text(face_manager<freetype_engine> & font_manager, double scale_factor);
|
||||
void push_back(processed_expression const& exp);
|
||||
unsigned size() const { return expr_list_.size(); }
|
||||
unsigned empty() const { return expr_list_.empty(); }
|
||||
void clear();
|
||||
typedef std::list<processed_expression> expression_list;
|
||||
expression_list::const_iterator begin();
|
||||
expression_list::const_iterator end();
|
||||
string_info &get_string_info();
|
||||
private:
|
||||
expression_list expr_list_;
|
||||
face_manager<freetype_engine> & font_manager_;
|
||||
double scale_factor_;
|
||||
string_info info_;
|
||||
};
|
||||
|
||||
class abstract_token;
|
||||
|
||||
/** Stores formating information and uses this to produce formated text for a given feature. */
|
||||
class text_processor
|
||||
{
|
||||
public:
|
||||
text_processor();
|
||||
/** Construct object from XML. */
|
||||
void from_xml(boost::property_tree::ptree const& pt, std::map<std::string,font_set> const &fontsets);
|
||||
/** Write object to XML ptree. */
|
||||
void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, text_processor const& dfl) const;
|
||||
|
||||
/** Takes a feature and produces formated text as output.
|
||||
* The output object has to be created by the caller and passed in for thread safety.
|
||||
*/
|
||||
void process(processed_text &output, Feature const& feature);
|
||||
/** Automatically create processing instructions for a single expression. */
|
||||
void set_old_style_expression(expression_ptr expr);
|
||||
/** Add a new formating token. */
|
||||
void push_back(abstract_token *token);
|
||||
/** Get a list of all expressions used in any placement. This function is used to collect attributes. */
|
||||
std::set<expression_ptr> get_all_expressions() const;
|
||||
/** Default values for char_properties. */
|
||||
char_properties defaults;
|
||||
protected:
|
||||
void from_xml_recursive(boost::property_tree::ptree const& pt, std::map<std::string,font_set> const &fontsets);
|
||||
private:
|
||||
std::list<abstract_token *> list_;
|
||||
bool clear_on_write; //Clear list once
|
||||
};
|
||||
|
||||
} /* namespace */
|
||||
|
||||
#endif
|
|
@ -26,8 +26,6 @@
|
|||
// mapnik
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/font_set.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/filter_factory.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
#include <mapnik/text_placements.hpp>
|
||||
|
||||
|
@ -38,6 +36,13 @@
|
|||
// stl
|
||||
#include <string>
|
||||
|
||||
// Warning disabled for the moment
|
||||
#if (0 && __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
#define func_deprecated __attribute__ ((deprecated))
|
||||
#else
|
||||
#define func_deprecated
|
||||
#endif
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
|
@ -45,6 +50,7 @@ struct MAPNIK_DECL text_symbolizer : public symbolizer_base
|
|||
{
|
||||
// Note - we do not use boost::make_shared below as VC2008 and VC2010 are
|
||||
// not able to compile make_shared used within a constructor
|
||||
text_symbolizer(text_placements_ptr placements = text_placements_ptr(new text_placements_dummy));
|
||||
text_symbolizer(expression_ptr name, std::string const& face_name,
|
||||
float size, color const& fill,
|
||||
text_placements_ptr placements = text_placements_ptr(new text_placements_dummy)
|
||||
|
@ -54,103 +60,75 @@ struct MAPNIK_DECL text_symbolizer : public symbolizer_base
|
|||
);
|
||||
text_symbolizer(text_symbolizer const& rhs);
|
||||
text_symbolizer& operator=(text_symbolizer const& rhs);
|
||||
expression_ptr get_name() const;
|
||||
expression_ptr get_name() const func_deprecated;
|
||||
void set_name(expression_ptr expr);
|
||||
|
||||
expression_ptr get_orientation() const; // orienation (rotation angle atm)
|
||||
expression_ptr get_orientation() const func_deprecated; // orienation (rotation angle atm)
|
||||
void set_orientation(expression_ptr expr);
|
||||
|
||||
unsigned get_text_ratio() const; // target ratio for text bounding box in pixels
|
||||
unsigned get_text_ratio() const func_deprecated; // target ratio for text bounding box in pixels
|
||||
void set_text_ratio(unsigned ratio);
|
||||
unsigned get_wrap_width() const; // width to wrap text at, or trigger ratio
|
||||
unsigned get_wrap_width() const func_deprecated; // width to wrap text at, or trigger ratio
|
||||
void set_wrap_width(unsigned ratio);
|
||||
unsigned char get_wrap_char() const; // character used to wrap lines
|
||||
std::string get_wrap_char_string() const; // character used to wrap lines as std::string
|
||||
unsigned char get_wrap_char() const func_deprecated; // character used to wrap lines
|
||||
std::string get_wrap_char_string() const func_deprecated; // character used to wrap lines as std::string
|
||||
void set_wrap_char(unsigned char character);
|
||||
void set_wrap_char_from_string(std::string const& character);
|
||||
text_transform_e get_text_transform() const; // text conversion on strings before display
|
||||
text_transform_e get_text_transform() const func_deprecated; // text conversion on strings before display
|
||||
void set_text_transform(text_transform_e convert);
|
||||
unsigned get_line_spacing() const; // spacing between lines of text
|
||||
unsigned get_line_spacing() const func_deprecated; // spacing between lines of text
|
||||
void set_line_spacing(unsigned spacing);
|
||||
unsigned get_character_spacing() const; // spacing between characters in text
|
||||
unsigned get_character_spacing() const func_deprecated; // spacing between characters in text
|
||||
void set_character_spacing(unsigned spacing);
|
||||
unsigned get_label_spacing() const; // spacing between repeated labels on lines
|
||||
unsigned get_label_spacing() const func_deprecated; // spacing between repeated labels on lines
|
||||
void set_label_spacing(unsigned spacing);
|
||||
unsigned get_label_position_tolerance() const; //distance the label can be moved on the line to fit, if 0 the default is used
|
||||
unsigned get_label_position_tolerance() const func_deprecated; //distance the label can be moved on the line to fit, if 0 the default is used
|
||||
void set_label_position_tolerance(unsigned tolerance);
|
||||
bool get_force_odd_labels() const; // try render an odd amount of labels
|
||||
bool get_force_odd_labels() const func_deprecated; // try render an odd amount of labels
|
||||
void set_force_odd_labels(bool force);
|
||||
double get_max_char_angle_delta() const; // maximum change in angle between adjacent characters
|
||||
double get_max_char_angle_delta() const func_deprecated; // maximum change in angle between adjacent characters
|
||||
void set_max_char_angle_delta(double angle);
|
||||
float get_text_size() const;
|
||||
float get_text_size() const func_deprecated;
|
||||
void set_text_size(float size);
|
||||
std::string const& get_face_name() const;
|
||||
std::string const& get_face_name() const func_deprecated;
|
||||
void set_face_name(std::string face_name);
|
||||
font_set const& get_fontset() const;
|
||||
font_set const& get_fontset() const func_deprecated;
|
||||
void set_fontset(font_set const& fset);
|
||||
color const& get_fill() const;
|
||||
color const& get_fill() const func_deprecated;
|
||||
void set_fill(color const& fill);
|
||||
void set_halo_fill(color const& fill);
|
||||
color const& get_halo_fill() const;
|
||||
color const& get_halo_fill() const func_deprecated;
|
||||
void set_halo_radius(double radius);
|
||||
double get_halo_radius() const;
|
||||
double get_halo_radius() const func_deprecated;
|
||||
void set_label_placement(label_placement_e label_p);
|
||||
label_placement_e get_label_placement() const;
|
||||
label_placement_e get_label_placement() const func_deprecated;
|
||||
void set_vertical_alignment(vertical_alignment_e valign);
|
||||
vertical_alignment_e get_vertical_alignment() const;
|
||||
void set_anchor(double x, double y);
|
||||
position const& get_anchor() const;
|
||||
vertical_alignment_e get_vertical_alignment() const func_deprecated;
|
||||
void set_displacement(double x, double y);
|
||||
void set_displacement(position const& p);
|
||||
position const& get_displacement() const;
|
||||
position const& get_displacement() const func_deprecated;
|
||||
void set_avoid_edges(bool avoid);
|
||||
bool get_avoid_edges() const;
|
||||
bool get_avoid_edges() const func_deprecated;
|
||||
void set_minimum_distance(double distance);
|
||||
double get_minimum_distance() const;
|
||||
double get_minimum_distance() const func_deprecated;
|
||||
void set_minimum_padding(double distance);
|
||||
double get_minimum_padding() const;
|
||||
double get_minimum_padding() const func_deprecated;
|
||||
void set_minimum_path_length(double size);
|
||||
double get_minimum_path_length() const;
|
||||
double get_minimum_path_length() const func_deprecated;
|
||||
void set_allow_overlap(bool overlap);
|
||||
bool get_allow_overlap() const;
|
||||
bool get_allow_overlap() const func_deprecated;
|
||||
void set_text_opacity(double opacity);
|
||||
double get_text_opacity() const;
|
||||
bool get_wrap_before() const; // wrap text at wrap_char immediately before current work
|
||||
double get_text_opacity() const func_deprecated;
|
||||
void set_wrap_before(bool wrap_before);
|
||||
bool get_wrap_before() const func_deprecated; // wrap text at wrap_char immediately before current work
|
||||
void set_horizontal_alignment(horizontal_alignment_e valign);
|
||||
horizontal_alignment_e get_horizontal_alignment() const;
|
||||
horizontal_alignment_e get_horizontal_alignment() const func_deprecated;
|
||||
void set_justify_alignment(justify_alignment_e valign);
|
||||
justify_alignment_e get_justify_alignment() const;
|
||||
justify_alignment_e get_justify_alignment() const func_deprecated;
|
||||
text_placements_ptr get_placement_options() const;
|
||||
void set_placement_options(text_placements_ptr placement_options);
|
||||
|
||||
private:
|
||||
expression_ptr name_;
|
||||
expression_ptr orientation_;
|
||||
std::string face_name_;
|
||||
font_set fontset_;
|
||||
unsigned text_ratio_;
|
||||
unsigned wrap_width_;
|
||||
unsigned char wrap_char_;
|
||||
text_transform_e text_transform_;
|
||||
unsigned line_spacing_;
|
||||
unsigned character_spacing_;
|
||||
unsigned label_spacing_;
|
||||
unsigned label_position_tolerance_;
|
||||
bool force_odd_labels_;
|
||||
double max_char_angle_delta_;
|
||||
color fill_;
|
||||
color halo_fill_;
|
||||
double halo_radius_;
|
||||
label_placement_e label_p_;
|
||||
position anchor_;
|
||||
bool avoid_edges_;
|
||||
double minimum_distance_;
|
||||
double minimum_padding_;
|
||||
double minimum_path_length_;
|
||||
bool overlap_;
|
||||
double text_opacity_;
|
||||
bool wrap_before_;
|
||||
text_placements_ptr placement_options_;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -389,7 +389,14 @@ void csv_datasource::parse_csv(T& stream,
|
|||
|
||||
int feature_count(1);
|
||||
bool extent_initialized = false;
|
||||
unsigned num_headers = headers_.size();
|
||||
std::size_t num_headers = headers_.size();
|
||||
|
||||
ctx_ = boost::make_shared<mapnik::context_type>();
|
||||
for (std::size_t i = 0; i < headers_.size(); ++i)
|
||||
{
|
||||
ctx_->push(headers_[i]);
|
||||
}
|
||||
|
||||
mapnik::transcoder tr(desc_.get_encoding());
|
||||
|
||||
while (std::getline(stream,csv_line,newline))
|
||||
|
@ -435,7 +442,7 @@ void csv_datasource::parse_csv(T& stream,
|
|||
}
|
||||
}
|
||||
|
||||
mapnik::feature_ptr feature(mapnik::feature_factory::create(feature_count));
|
||||
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_count));
|
||||
double x(0);
|
||||
double y(0);
|
||||
bool parsed_x = false;
|
||||
|
@ -451,9 +458,7 @@ void csv_datasource::parse_csv(T& stream,
|
|||
std::string value;
|
||||
if (beg == tok.end())
|
||||
{
|
||||
UnicodeString ustr = tr.transcode(value.c_str());
|
||||
boost::put(*feature,fld_name,ustr);
|
||||
// boost::put(*feature,fld_name,mapnik::value_null());
|
||||
feature->put(fld_name,tr.transcode(value.c_str()));
|
||||
null_geom = true;
|
||||
if (feature_count == 1)
|
||||
{
|
||||
|
@ -633,8 +638,7 @@ void csv_datasource::parse_csv(T& stream,
|
|||
(value_length > 20) ||
|
||||
(value_length > 1 && !has_dot && value[0] == '0'))
|
||||
{
|
||||
UnicodeString ustr = tr.transcode(value.c_str());
|
||||
boost::put(*feature,fld_name,ustr);
|
||||
feature->put(fld_name,tr.transcode(value.c_str()));
|
||||
if (feature_count == 1)
|
||||
{
|
||||
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String));
|
||||
|
@ -650,7 +654,7 @@ void csv_datasource::parse_csv(T& stream,
|
|||
{
|
||||
if (has_dot)
|
||||
{
|
||||
boost::put(*feature,fld_name,float_val);
|
||||
feature->put(fld_name,float_val);
|
||||
if (feature_count == 1)
|
||||
{
|
||||
desc_.add_descriptor(
|
||||
|
@ -660,8 +664,7 @@ void csv_datasource::parse_csv(T& stream,
|
|||
}
|
||||
else
|
||||
{
|
||||
int val = static_cast<int>(float_val);
|
||||
boost::put(*feature,fld_name,val);
|
||||
feature->put(fld_name,static_cast<int>(float_val));
|
||||
if (feature_count == 1)
|
||||
{
|
||||
desc_.add_descriptor(
|
||||
|
@ -673,8 +676,7 @@ void csv_datasource::parse_csv(T& stream,
|
|||
else
|
||||
{
|
||||
// fallback to normal string
|
||||
UnicodeString ustr = tr.transcode(value.c_str());
|
||||
boost::put(*feature,fld_name,ustr);
|
||||
feature->put(fld_name,tr.transcode(value.c_str()));
|
||||
if (feature_count == 1)
|
||||
{
|
||||
desc_.add_descriptor(
|
||||
|
@ -686,8 +688,7 @@ void csv_datasource::parse_csv(T& stream,
|
|||
else
|
||||
{
|
||||
// fallback to normal string
|
||||
UnicodeString ustr = tr.transcode(value.c_str());
|
||||
boost::put(*feature,fld_name,ustr);
|
||||
feature->put(fld_name,tr.transcode(value.c_str()));
|
||||
if (feature_count == 1)
|
||||
{
|
||||
desc_.add_descriptor(
|
||||
|
@ -889,7 +890,7 @@ mapnik::featureset_ptr csv_datasource::features(mapnik::query const& q) const
|
|||
while (pos != attribute_names.end())
|
||||
{
|
||||
bool found_name = false;
|
||||
for (int i = 0; i < headers_.size(); ++i)
|
||||
for (std::size_t i = 0; i < headers_.size(); ++i)
|
||||
{
|
||||
if (headers_[i] == *pos)
|
||||
{
|
||||
|
|
|
@ -41,6 +41,7 @@ private:
|
|||
mutable bool strict_;
|
||||
mutable bool quiet_;
|
||||
mutable double filesize_max_;
|
||||
mutable mapnik::context_ptr ctx_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ gdal_featureset::gdal_featureset(GDALDataset& dataset,
|
|||
double dy,
|
||||
double filter_factor)
|
||||
: dataset_(dataset),
|
||||
ctx_(boost::make_shared<mapnik::context_type>()),
|
||||
band_(band),
|
||||
gquery_(q),
|
||||
raster_extent_(extent),
|
||||
|
@ -66,6 +67,8 @@ gdal_featureset::gdal_featureset(GDALDataset& dataset,
|
|||
filter_factor_(filter_factor),
|
||||
first_(true)
|
||||
{
|
||||
ctx_->push("value");
|
||||
ctx_->push("NODATA");
|
||||
}
|
||||
|
||||
gdal_featureset::~gdal_featureset()
|
||||
|
@ -106,14 +109,14 @@ feature_ptr gdal_featureset::next()
|
|||
|
||||
feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||
{
|
||||
feature_ptr feature(feature_factory::create(1));
|
||||
|
||||
feature_ptr feature = feature_factory::create(ctx_,1);
|
||||
|
||||
GDALRasterBand * red = 0;
|
||||
GDALRasterBand * green = 0;
|
||||
GDALRasterBand * blue = 0;
|
||||
GDALRasterBand * alpha = 0;
|
||||
GDALRasterBand * grey = 0;
|
||||
|
||||
|
||||
/*
|
||||
double tr[6];
|
||||
dataset_.GetGeoTransform(tr);
|
||||
|
@ -244,10 +247,10 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
|||
imageData, image.width(), image.height(),
|
||||
GDT_Float32, 0, 0);
|
||||
|
||||
feature->set_raster(mapnik::raster_ptr(boost::make_shared<mapnik::raster>(intersect,image)));
|
||||
feature->set_raster(boost::make_shared<mapnik::raster>(intersect,image));
|
||||
if (hasNoData)
|
||||
{
|
||||
feature->props()["NODATA"] = nodata;
|
||||
feature->put("NODATA",nodata);
|
||||
}
|
||||
}
|
||||
else // working with all bands
|
||||
|
@ -487,12 +490,12 @@ feature_ptr gdal_featureset::get_feature_at_point(mapnik::coord2d const& pt)
|
|||
|
||||
if (! hasNoData || value != nodata)
|
||||
{
|
||||
// construct feature
|
||||
feature_ptr feature(new Feature(1));
|
||||
// construct feature
|
||||
feature_ptr feature = feature_factory::create(ctx_,1);
|
||||
geometry_type * point = new geometry_type(mapnik::Point);
|
||||
point->move_to(pt.x, pt.y);
|
||||
feature->add_geometry(point);
|
||||
(*feature)["value"] = value;
|
||||
feature->put("value",value);
|
||||
return feature;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define GDAL_FEATURESET_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/datasource.hpp>
|
||||
|
||||
// boost
|
||||
|
@ -56,6 +57,7 @@ private:
|
|||
void get_overview_meta(GDALRasterBand * band);
|
||||
#endif
|
||||
GDALDataset & dataset_;
|
||||
mapnik::context_ptr ctx_;
|
||||
int band_;
|
||||
gdal_query gquery_;
|
||||
mapnik::box2d<double> raster_extent_;
|
||||
|
|
|
@ -60,8 +60,10 @@ geos_featureset::geos_featureset(GEOSGeometry* geometry,
|
|||
identifier_(identifier),
|
||||
field_(field),
|
||||
field_name_(field_name),
|
||||
already_rendered_(false)
|
||||
already_rendered_(false),
|
||||
ctx_(boost::make_shared<mapnik::context_type>())
|
||||
{
|
||||
ctx_->push(field_name);
|
||||
}
|
||||
|
||||
geos_featureset::~geos_featureset()
|
||||
|
@ -114,14 +116,14 @@ feature_ptr geos_featureset::next()
|
|||
geos_wkb_ptr wkb(geometry_);
|
||||
if (wkb.is_valid())
|
||||
{
|
||||
feature_ptr feature(feature_factory::create(identifier_));
|
||||
feature_ptr feature(feature_factory::create(ctx_,identifier_));
|
||||
|
||||
geometry_utils::from_wkb(feature->paths(),
|
||||
wkb.data(),
|
||||
wkb.size());
|
||||
if (field_ != "")
|
||||
{
|
||||
boost::put(*feature, field_name_, tr_->transcode(field_.c_str()));
|
||||
feature->put(field_name_, tr_->transcode(field_.c_str()));
|
||||
}
|
||||
|
||||
return feature;
|
||||
|
|
|
@ -56,6 +56,7 @@ private:
|
|||
std::string field_;
|
||||
std::string field_name_;
|
||||
bool already_rendered_;
|
||||
mapnik::context_ptr ctx_;
|
||||
|
||||
geos_featureset(const geos_featureset&);
|
||||
const geos_featureset& operator=(const geos_featureset&);
|
||||
|
|
|
@ -40,15 +40,17 @@ using mapnik::geometry_utils;
|
|||
using mapnik::transcoder;
|
||||
using mapnik::feature_factory;
|
||||
|
||||
kismet_featureset::kismet_featureset(const std::list<kismet_network_data>& knd_list,
|
||||
kismet_featureset::kismet_featureset(std::list<kismet_network_data> const& knd_list,
|
||||
std::string const& srs,
|
||||
std::string const& encoding)
|
||||
: knd_list_(knd_list),
|
||||
tr_(new transcoder(encoding)),
|
||||
feature_id_(1),
|
||||
knd_list_it(knd_list_.begin()),
|
||||
source_(srs)
|
||||
source_(srs),
|
||||
ctx_(boost::make_shared<mapnik::context_type>())
|
||||
{
|
||||
ctx_->push("internet_access");
|
||||
}
|
||||
|
||||
kismet_featureset::~kismet_featureset()
|
||||
|
@ -76,14 +78,14 @@ feature_ptr kismet_featureset::next()
|
|||
value = "wlan_crypted";
|
||||
}
|
||||
|
||||
feature_ptr feature(feature_factory::create(feature_id_));
|
||||
feature_ptr feature(feature_factory::create(ctx_,feature_id_));
|
||||
++feature_id_;
|
||||
|
||||
geometry_type* pt = new geometry_type(mapnik::Point);
|
||||
pt->move_to(knd.bestlon(), knd.bestlat());
|
||||
feature->add_geometry(pt);
|
||||
|
||||
boost::put(*feature, key, tr_->transcode(value.c_str()));
|
||||
feature->put(key, tr_->transcode(value.c_str()));
|
||||
|
||||
++knd_list_it;
|
||||
|
||||
|
|
|
@ -40,19 +40,20 @@
|
|||
class kismet_featureset : public mapnik::Featureset
|
||||
{
|
||||
public:
|
||||
kismet_featureset(const std::list<kismet_network_data>& knd_list,
|
||||
kismet_featureset(std::list<kismet_network_data> const& knd_list,
|
||||
std::string const& srs,
|
||||
std::string const& encoding);
|
||||
virtual ~kismet_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
|
||||
private:
|
||||
const std::list<kismet_network_data>& knd_list_;
|
||||
std::list<kismet_network_data> const& knd_list_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
mapnik::wkbFormat format_;
|
||||
int feature_id_;
|
||||
std::list<kismet_network_data>::const_iterator knd_list_it;
|
||||
mapnik::projection source_;
|
||||
mapnik::context_ptr ctx_;
|
||||
};
|
||||
|
||||
#endif // KISMET_FEATURESET_HPP
|
||||
|
|
|
@ -500,10 +500,11 @@ featureset_ptr occi_datasource::features(query const& q) const
|
|||
std::set<std::string> const& props = q.property_names();
|
||||
std::set<std::string>::const_iterator pos = props.begin();
|
||||
std::set<std::string>::const_iterator end = props.end();
|
||||
while (pos != end)
|
||||
mapnik::context_ptr ctx = boost::make_shared<mapnik::context_type>();
|
||||
for ( ;pos != end;++pos)
|
||||
{
|
||||
s << ", " << *pos;
|
||||
++pos;
|
||||
ctx->push(*pos);
|
||||
}
|
||||
|
||||
s << " FROM ";
|
||||
|
@ -565,11 +566,11 @@ featureset_ptr occi_datasource::features(query const& q) const
|
|||
|
||||
return boost::make_shared<occi_featureset>(pool_,
|
||||
conn_,
|
||||
ctx,
|
||||
s.str(),
|
||||
desc_.get_encoding(),
|
||||
use_connection_pool_,
|
||||
row_prefetch_,
|
||||
props.size());
|
||||
row_prefetch_);
|
||||
}
|
||||
|
||||
featureset_ptr occi_datasource::features_at_point(coord2d const& pt) const
|
||||
|
@ -580,12 +581,12 @@ featureset_ptr occi_datasource::features_at_point(coord2d const& pt) const
|
|||
s << "SELECT " << geometry_field_;
|
||||
std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin();
|
||||
std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end();
|
||||
unsigned size = 0;
|
||||
mapnik::context_ptr ctx = boost::make_shared<mapnik::context_type>();
|
||||
while (itr != end)
|
||||
{
|
||||
s << ", " << itr->get_name();
|
||||
ctx->push(itr->get_name());
|
||||
++itr;
|
||||
++size;
|
||||
}
|
||||
|
||||
s << " FROM ";
|
||||
|
@ -646,9 +647,9 @@ featureset_ptr occi_datasource::features_at_point(coord2d const& pt) const
|
|||
|
||||
return boost::make_shared<occi_featureset>(pool_,
|
||||
conn_,
|
||||
ctx,
|
||||
s.str(),
|
||||
desc_.get_encoding(),
|
||||
use_connection_pool_,
|
||||
row_prefetch_,
|
||||
size);
|
||||
row_prefetch_);
|
||||
}
|
||||
|
|
|
@ -57,14 +57,14 @@ using oracle::occi::Blob;
|
|||
|
||||
occi_featureset::occi_featureset(StatelessConnectionPool* pool,
|
||||
Connection* conn,
|
||||
mapnik::context_ptr const& ctx,
|
||||
std::string const& sqlstring,
|
||||
std::string const& encoding,
|
||||
bool use_connection_pool,
|
||||
unsigned prefetch_rows,
|
||||
unsigned num_attrs)
|
||||
unsigned prefetch_rows)
|
||||
: tr_(new transcoder(encoding)),
|
||||
num_attrs_(num_attrs),
|
||||
feature_id_(1)
|
||||
feature_id_(1),
|
||||
ctx_(ctx)
|
||||
{
|
||||
if (use_connection_pool)
|
||||
{
|
||||
|
@ -93,7 +93,7 @@ feature_ptr occi_featureset::next()
|
|||
{
|
||||
if (rs_ && rs_->next())
|
||||
{
|
||||
feature_ptr feature(feature_factory::create(feature_id_));
|
||||
feature_ptr feature(feature_factory::create(ctx_,feature_id_));
|
||||
++feature_id_;
|
||||
|
||||
boost::scoped_ptr<SDOGeometry> geom(dynamic_cast<SDOGeometry*>(rs_->getObject(1)));
|
||||
|
@ -125,7 +125,7 @@ feature_ptr occi_featureset::next()
|
|||
case oracle::occi::OCCIINT:
|
||||
case oracle::occi::OCCIUNSIGNED_INT:
|
||||
case oracle::occi::OCCIROWID:
|
||||
boost::put(*feature,fld_name,rs_->getInt (i + 1));
|
||||
feature->put(fld_name,rs_->getInt (i + 1));
|
||||
break;
|
||||
case oracle::occi::OCCIFLOAT:
|
||||
case oracle::occi::OCCIBFLOAT:
|
||||
|
@ -133,7 +133,7 @@ feature_ptr occi_featureset::next()
|
|||
case oracle::occi::OCCIBDOUBLE:
|
||||
case oracle::occi::OCCINUMBER:
|
||||
case oracle::occi::OCCI_SQLT_NUM:
|
||||
boost::put(*feature,fld_name,rs_->getDouble (i + 1));
|
||||
feature->put(fld_name,rs_->getDouble (i + 1));
|
||||
break;
|
||||
case oracle::occi::OCCICHAR:
|
||||
case oracle::occi::OCCISTRING:
|
||||
|
@ -147,7 +147,7 @@ feature_ptr occi_featureset::next()
|
|||
case oracle::occi::OCCI_SQLT_VNU:
|
||||
case oracle::occi::OCCI_SQLT_VBI:
|
||||
case oracle::occi::OCCI_SQLT_VST:
|
||||
boost::put(*feature,fld_name,(UnicodeString) tr_->transcode (rs_->getString (i + 1).c_str()));
|
||||
feature->put(fld_name,(UnicodeString) tr_->transcode (rs_->getString (i + 1).c_str()));
|
||||
break;
|
||||
case oracle::occi::OCCIDATE:
|
||||
case oracle::occi::OCCITIMESTAMP:
|
||||
|
|
|
@ -40,11 +40,11 @@ class occi_featureset : public mapnik::Featureset
|
|||
public:
|
||||
occi_featureset(oracle::occi::StatelessConnectionPool* pool,
|
||||
oracle::occi::Connection* conn,
|
||||
mapnik::context_ptr const& ctx,
|
||||
std::string const& sqlstring,
|
||||
std::string const& encoding,
|
||||
bool use_connection_pool,
|
||||
unsigned prefetch_rows,
|
||||
unsigned num_attrs);
|
||||
unsigned prefetch_rows);
|
||||
virtual ~occi_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
|
||||
|
@ -68,8 +68,8 @@ private:
|
|||
oracle::occi::ResultSet* rs_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
const char* fidcolumn_;
|
||||
unsigned num_attrs_;
|
||||
mutable int feature_id_;
|
||||
mapnik::context_ptr ctx_;
|
||||
};
|
||||
|
||||
#endif // OCCI_FEATURESET_HPP
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
// boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
using mapnik::datasource;
|
||||
using mapnik::parameters;
|
||||
|
@ -434,56 +435,70 @@ std::map<std::string, mapnik::parameters> ogr_datasource::get_statistics() cons
|
|||
return stats_;
|
||||
}
|
||||
|
||||
void validate_attribute_names(query const& q, std::vector<attribute_descriptor> const& names )
|
||||
{
|
||||
std::set<std::string> const& attribute_names = q.property_names();
|
||||
std::set<std::string>::const_iterator pos = attribute_names.begin();
|
||||
std::set<std::string>::const_iterator end_names = attribute_names.end();
|
||||
|
||||
for ( ;pos != end_names; ++pos)
|
||||
{
|
||||
bool found_name = false;
|
||||
|
||||
std::vector<attribute_descriptor>::const_iterator itr = names.begin();
|
||||
std::vector<attribute_descriptor>::const_iterator end = names.end();
|
||||
|
||||
for (; itr!=end; ++itr)
|
||||
{
|
||||
if (itr->get_name() == *pos)
|
||||
{
|
||||
found_name = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found_name)
|
||||
{
|
||||
std::ostringstream s;
|
||||
std::vector<attribute_descriptor>::const_iterator itr = names.begin();
|
||||
std::vector<attribute_descriptor>::const_iterator end = names.end();
|
||||
s << "OGR Plugin: no attribute '" << *pos << "'. Valid attributes are: ";
|
||||
for ( ;itr!=end;++itr)
|
||||
{
|
||||
s << itr->get_name() << std::endl;
|
||||
}
|
||||
throw mapnik::datasource_exception(s.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
featureset_ptr ogr_datasource::features(query const& q) const
|
||||
{
|
||||
if (! is_bound_) bind();
|
||||
|
||||
if (dataset_ && layer_.is_valid())
|
||||
{
|
||||
// First we validate query fields: https://github.com/mapnik/mapnik/issues/792
|
||||
// First we validate query fields: https://github.com/mapnik/mapnik/issues/792
|
||||
|
||||
std::vector<attribute_descriptor> const& desc_ar = desc_.get_descriptors();
|
||||
std::vector<attribute_descriptor>::const_iterator it = desc_ar.begin();
|
||||
// feature context (schema)
|
||||
mapnik::context_ptr ctx = boost::make_shared<mapnik::context_type>();
|
||||
|
||||
std::vector<attribute_descriptor>::const_iterator itr = desc_ar.begin();
|
||||
std::vector<attribute_descriptor>::const_iterator end = desc_ar.end();
|
||||
std::vector<std::string> known_fields;
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
known_fields.push_back(it->get_name());
|
||||
}
|
||||
|
||||
const std::set<std::string>& attribute_names = q.property_names();
|
||||
std::set<std::string>::const_iterator pos = attribute_names.begin();
|
||||
while (pos != attribute_names.end())
|
||||
{
|
||||
bool found_name = false;
|
||||
for (int i = 0; i < known_fields.size(); ++i)
|
||||
{
|
||||
if (known_fields[i] == *pos)
|
||||
{
|
||||
found_name = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found_name)
|
||||
{
|
||||
std::ostringstream s;
|
||||
|
||||
s << "OGR Plugin: no attribute '" << *pos << "'. Valid attributes are: "
|
||||
<< boost::algorithm::join(known_fields, ",") << ".";
|
||||
|
||||
throw mapnik::datasource_exception(s.str());
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (; itr!=end; ++itr) ctx->push(itr->get_name()); // TODO only push query attributes
|
||||
|
||||
validate_attribute_names(q, desc_ar);
|
||||
|
||||
OGRLayer* layer = layer_.layer();
|
||||
|
||||
if (indexed_)
|
||||
{
|
||||
filter_in_box filter(q.get_bbox());
|
||||
|
||||
return featureset_ptr(new ogr_index_featureset<filter_in_box>(*dataset_,
|
||||
return featureset_ptr(new ogr_index_featureset<filter_in_box>(ctx,
|
||||
*dataset_,
|
||||
*layer,
|
||||
filter,
|
||||
index_name_,
|
||||
|
@ -492,7 +507,8 @@ featureset_ptr ogr_datasource::features(query const& q) const
|
|||
}
|
||||
else
|
||||
{
|
||||
return featureset_ptr(new ogr_featureset (*dataset_,
|
||||
return featureset_ptr(new ogr_featureset (ctx,
|
||||
*dataset_,
|
||||
*layer,
|
||||
q.get_bbox(),
|
||||
desc_.get_encoding()
|
||||
|
@ -509,13 +525,22 @@ featureset_ptr ogr_datasource::features_at_point(coord2d const& pt) const
|
|||
|
||||
if (dataset_ && layer_.is_valid())
|
||||
{
|
||||
std::vector<attribute_descriptor> const& desc_ar = desc_.get_descriptors();
|
||||
// feature context (schema)
|
||||
mapnik::context_ptr ctx = boost::make_shared<mapnik::context_type>();
|
||||
|
||||
std::vector<attribute_descriptor>::const_iterator itr = desc_ar.begin();
|
||||
std::vector<attribute_descriptor>::const_iterator end = desc_ar.end();
|
||||
for (; itr!=end; ++itr) ctx->push(itr->get_name());
|
||||
|
||||
OGRLayer* layer = layer_.layer();
|
||||
|
||||
|
||||
if (indexed_)
|
||||
{
|
||||
filter_at_point filter(pt);
|
||||
|
||||
return featureset_ptr(new ogr_index_featureset<filter_at_point> (*dataset_,
|
||||
|
||||
return featureset_ptr(new ogr_index_featureset<filter_at_point> (ctx,
|
||||
*dataset_,
|
||||
*layer,
|
||||
filter,
|
||||
index_name_,
|
||||
|
@ -528,7 +553,8 @@ featureset_ptr ogr_datasource::features_at_point(coord2d const& pt) const
|
|||
point.setX (pt.x);
|
||||
point.setY (pt.y);
|
||||
|
||||
return featureset_ptr(new ogr_featureset (*dataset_,
|
||||
return featureset_ptr(new ogr_featureset (ctx,
|
||||
*dataset_,
|
||||
*layer,
|
||||
point,
|
||||
desc_.get_encoding()
|
||||
|
|
|
@ -46,25 +46,30 @@ using mapnik::transcoder;
|
|||
using mapnik::feature_factory;
|
||||
|
||||
|
||||
ogr_featureset::ogr_featureset(OGRDataSource & dataset,
|
||||
ogr_featureset::ogr_featureset(mapnik::context_ptr const & ctx,
|
||||
OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
OGRGeometry & extent,
|
||||
const std::string& encoding)
|
||||
: dataset_(dataset),
|
||||
std::string const& encoding)
|
||||
: ctx_(ctx),
|
||||
dataset_(dataset),
|
||||
layer_(layer),
|
||||
layerdef_(layer.GetLayerDefn()),
|
||||
tr_(new transcoder(encoding)),
|
||||
fidcolumn_(layer_.GetFIDColumn ()),
|
||||
count_(0)
|
||||
|
||||
{
|
||||
layer_.SetSpatialFilter (&extent);
|
||||
}
|
||||
|
||||
ogr_featureset::ogr_featureset(OGRDataSource & dataset,
|
||||
ogr_featureset::ogr_featureset(mapnik::context_ptr const& ctx,
|
||||
OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
const mapnik::box2d<double> & extent,
|
||||
const std::string& encoding)
|
||||
: dataset_(dataset),
|
||||
mapnik::box2d<double> const& extent,
|
||||
std::string const& encoding)
|
||||
: ctx_(ctx),
|
||||
dataset_(dataset),
|
||||
layer_(layer),
|
||||
layerdef_(layer.GetLayerDefn()),
|
||||
tr_(new transcoder(encoding)),
|
||||
|
@ -90,7 +95,7 @@ feature_ptr ogr_featureset::next()
|
|||
// ogr feature ids start at 0, so add one to stay
|
||||
// consistent with other mapnik datasources that start at 1
|
||||
const int feature_id = ((*feat)->GetFID() + 1);
|
||||
feature_ptr feature(feature_factory::create(feature_id));
|
||||
feature_ptr feature(feature_factory::create(ctx_,feature_id));
|
||||
|
||||
OGRGeometry* geom = (*feat)->GetGeometryRef();
|
||||
if (geom && ! geom->IsEmpty())
|
||||
|
@ -117,13 +122,13 @@ feature_ptr ogr_featureset::next()
|
|||
{
|
||||
case OFTInteger:
|
||||
{
|
||||
boost::put(*feature, fld_name, (*feat)->GetFieldAsInteger(i));
|
||||
feature->put( fld_name, (*feat)->GetFieldAsInteger(i));
|
||||
break;
|
||||
}
|
||||
|
||||
case OFTReal:
|
||||
{
|
||||
boost::put(*feature, fld_name, (*feat)->GetFieldAsDouble(i));
|
||||
feature->put( fld_name, (*feat)->GetFieldAsDouble(i));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -131,7 +136,7 @@ feature_ptr ogr_featureset::next()
|
|||
case OFTWideString: // deprecated !
|
||||
{
|
||||
UnicodeString ustr = tr_->transcode((*feat)->GetFieldAsString(i));
|
||||
boost::put(*feature, fld_name, ustr);
|
||||
feature->put( fld_name, ustr);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -151,7 +156,7 @@ feature_ptr ogr_featureset::next()
|
|||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unhandled type_oid=" << type_oid << std::endl;
|
||||
#endif
|
||||
//boost::put(*feature,name,feat->GetFieldAsBinary (i, size));
|
||||
//feature->put(name,feat->GetFieldAsBinary (i, size));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,28 +37,30 @@
|
|||
class ogr_featureset : public mapnik::Featureset
|
||||
{
|
||||
public:
|
||||
ogr_featureset(OGRDataSource & dataset,
|
||||
ogr_featureset(mapnik::context_ptr const& ctx,
|
||||
OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
OGRGeometry & extent,
|
||||
const std::string& encoding);
|
||||
std::string const& encoding);
|
||||
|
||||
ogr_featureset(OGRDataSource & dataset,
|
||||
ogr_featureset(mapnik::context_ptr const& ctx,
|
||||
OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
const mapnik::box2d<double> & extent,
|
||||
const std::string& encoding);
|
||||
mapnik::box2d<double> const& extent,
|
||||
std::string const& encoding);
|
||||
|
||||
virtual ~ogr_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
|
||||
private:
|
||||
ogr_featureset(const ogr_featureset&);
|
||||
const ogr_featureset& operator=(const ogr_featureset&);
|
||||
|
||||
mapnik::context_ptr ctx_;
|
||||
OGRDataSource& dataset_;
|
||||
OGRLayer& layer_;
|
||||
OGRFeatureDefn* layerdef_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
const char* fidcolumn_;
|
||||
mutable int count_;
|
||||
|
||||
};
|
||||
|
||||
#endif // OGR_FEATURESET_HPP
|
||||
|
|
|
@ -52,12 +52,14 @@ using mapnik::transcoder;
|
|||
using mapnik::feature_factory;
|
||||
|
||||
template <typename filterT>
|
||||
ogr_index_featureset<filterT>::ogr_index_featureset(OGRDataSource & dataset,
|
||||
ogr_index_featureset<filterT>::ogr_index_featureset(mapnik::context_ptr const & ctx,
|
||||
OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
const filterT& filter,
|
||||
const std::string& index_file,
|
||||
const std::string& encoding)
|
||||
: dataset_(dataset),
|
||||
filterT const& filter,
|
||||
std::string const& index_file,
|
||||
std::string const& encoding)
|
||||
: ctx_(ctx),
|
||||
dataset_(dataset),
|
||||
layer_(layer),
|
||||
layerdef_(layer.GetLayerDefn()),
|
||||
filter_(filter),
|
||||
|
@ -101,7 +103,7 @@ feature_ptr ogr_index_featureset<filterT>::next()
|
|||
// ogr feature ids start at 0, so add one to stay
|
||||
// consistent with other mapnik datasources that start at 1
|
||||
int feature_id = ((*feat)->GetFID() + 1);
|
||||
feature_ptr feature(feature_factory::create(feature_id));
|
||||
feature_ptr feature(feature_factory::create(ctx_,feature_id));
|
||||
|
||||
OGRGeometry* geom=(*feat)->GetGeometryRef();
|
||||
if (geom && !geom->IsEmpty())
|
||||
|
@ -126,13 +128,13 @@ feature_ptr ogr_index_featureset<filterT>::next()
|
|||
{
|
||||
case OFTInteger:
|
||||
{
|
||||
boost::put(*feature,fld_name,(*feat)->GetFieldAsInteger (i));
|
||||
feature->put(fld_name,(*feat)->GetFieldAsInteger (i));
|
||||
break;
|
||||
}
|
||||
|
||||
case OFTReal:
|
||||
{
|
||||
boost::put(*feature,fld_name,(*feat)->GetFieldAsDouble (i));
|
||||
feature->put(fld_name,(*feat)->GetFieldAsDouble (i));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -140,7 +142,7 @@ feature_ptr ogr_index_featureset<filterT>::next()
|
|||
case OFTWideString: // deprecated !
|
||||
{
|
||||
UnicodeString ustr = tr_->transcode((*feat)->GetFieldAsString (i));
|
||||
boost::put(*feature,fld_name,ustr);
|
||||
feature->put(fld_name,ustr);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -160,7 +162,7 @@ feature_ptr ogr_index_featureset<filterT>::next()
|
|||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unhandled type_oid=" << type_oid << std::endl;
|
||||
#endif
|
||||
//boost::put(*feature,name,feat->GetFieldAsBinary (i, size));
|
||||
//feature->put(name,feat->GetFieldAsBinary (i, size));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,18 +32,18 @@ template <typename filterT>
|
|||
class ogr_index_featureset : public mapnik::Featureset
|
||||
{
|
||||
public:
|
||||
ogr_index_featureset(OGRDataSource& dataset,
|
||||
ogr_index_featureset(mapnik::context_ptr const& ctx,
|
||||
OGRDataSource& dataset,
|
||||
OGRLayer& layer,
|
||||
const filterT& filter,
|
||||
const std::string& index_file,
|
||||
const std::string& encoding);
|
||||
filterT const& filter,
|
||||
std::string const& index_file,
|
||||
std::string const& encoding);
|
||||
|
||||
virtual ~ogr_index_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
|
||||
private:
|
||||
ogr_index_featureset(const ogr_index_featureset&);
|
||||
ogr_index_featureset& operator=(const ogr_index_featureset&);
|
||||
|
||||
mapnik::context_ptr ctx_;
|
||||
OGRDataSource& dataset_;
|
||||
OGRLayer& layer_;
|
||||
OGRFeatureDefn* layerdef_;
|
||||
|
@ -52,6 +52,7 @@ private:
|
|||
std::vector<int>::iterator itr_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
const char* fidcolumn_;
|
||||
|
||||
};
|
||||
|
||||
#endif // OGR_INDEX_FEATURESET_HPP
|
||||
|
|
|
@ -46,7 +46,8 @@ osm_featureset<filterT>::osm_featureset(const filterT& filter,
|
|||
tr_(new transcoder(encoding)),
|
||||
feature_id_(1),
|
||||
dataset_ (dataset),
|
||||
attribute_names_ (attribute_names)
|
||||
attribute_names_ (attribute_names),
|
||||
ctx_(boost::make_shared<mapnik::context>())
|
||||
{
|
||||
dataset_->rewind();
|
||||
}
|
||||
|
@ -62,7 +63,7 @@ feature_ptr osm_featureset<filterT>::next()
|
|||
{
|
||||
if (dataset_->current_item_is_node())
|
||||
{
|
||||
feature = feature_factory::create(feature_id_);
|
||||
feature = feature_factory::create(ctx_,feature_id_);
|
||||
++feature_id_;
|
||||
double lat = static_cast<osm_node*>(cur_item)->lat;
|
||||
double lon = static_cast<osm_node*>(cur_item)->lon;
|
||||
|
@ -90,7 +91,7 @@ feature_ptr osm_featureset<filterT>::next()
|
|||
{
|
||||
if (static_cast<osm_way*>(cur_item)->nodes.size())
|
||||
{
|
||||
feature = feature_factory::create(feature_id_);
|
||||
feature = feature_factory::create(ctx_,feature_id_);
|
||||
++feature_id_;
|
||||
geometry_type* geom;
|
||||
if (static_cast<osm_way*>(cur_item)->is_polygon())
|
||||
|
@ -131,7 +132,7 @@ feature_ptr osm_featureset<filterT>::next()
|
|||
// only add if in the specified set of attribute names
|
||||
if (attribute_names_.find(i->first) != attribute_names_.end())
|
||||
{
|
||||
(*feature)[i->first] = tr_->transcode(i->second.c_str());
|
||||
feature->put(i->first,tr_->transcode(i->second.c_str()));
|
||||
}
|
||||
|
||||
i++;
|
||||
|
|
|
@ -63,6 +63,7 @@ private:
|
|||
mutable int feature_id_;
|
||||
osm_dataset *dataset_;
|
||||
std::set<std::string> attribute_names_;
|
||||
mapnik::context_ptr ctx_;
|
||||
// no copying
|
||||
osm_featureset(const osm_featureset&);
|
||||
const osm_featureset& operator=(const osm_featureset&);
|
||||
|
|
|
@ -70,6 +70,7 @@ public:
|
|||
{
|
||||
s << "unable to connect to postgres server";
|
||||
}
|
||||
s << "\n" << connection_str;
|
||||
throw mapnik::datasource_exception( s.str() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -503,7 +503,7 @@ featureset_ptr postgis_datasource::features(const query& q) const
|
|||
s_error << geometry_table_ << "'.";
|
||||
throw mapnik::datasource_exception(s_error.str());
|
||||
}
|
||||
|
||||
|
||||
std::ostringstream s;
|
||||
s << "SELECT ST_AsBinary(\"" << geometryColumn_ << "\") AS geom";
|
||||
|
||||
|
@ -513,10 +513,13 @@ featureset_ptr postgis_datasource::features(const query& q) const
|
|||
std::set<std::string> const& props=q.property_names();
|
||||
std::set<std::string>::const_iterator pos=props.begin();
|
||||
std::set<std::string>::const_iterator end=props.end();
|
||||
while (pos != end)
|
||||
|
||||
mapnik::context_ptr ctx = boost::make_shared<mapnik::context_type>();
|
||||
|
||||
for ( ;pos != end;++pos)
|
||||
{
|
||||
mapnik::sql_utils::quote_attr(s,*pos);
|
||||
++pos;
|
||||
ctx->push(*pos);
|
||||
}
|
||||
|
||||
std::string table_with_bbox = populate_tokens(table_,scale_denom,box);
|
||||
|
@ -531,7 +534,7 @@ featureset_ptr postgis_datasource::features(const query& q) const
|
|||
unsigned num_attr = props.size();
|
||||
if (!key_field_.empty())
|
||||
++num_attr;
|
||||
return boost::make_shared<postgis_featureset>(rs,desc_.get_encoding(), !key_field_.empty(),num_attr);
|
||||
return boost::make_shared<postgis_featureset>(rs, ctx, desc_.get_encoding(), !key_field_.empty());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -579,14 +582,15 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt) const
|
|||
if (!key_field_.empty())
|
||||
mapnik::sql_utils::quote_attr(s,key_field_);
|
||||
|
||||
mapnik::context_ptr ctx = boost::make_shared<mapnik::context_type>();
|
||||
|
||||
std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin();
|
||||
std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end();
|
||||
unsigned size=0;
|
||||
while (itr != end)
|
||||
|
||||
for ( ; itr != end; ++itr)
|
||||
{
|
||||
mapnik::sql_utils::quote_attr(s,itr->get_name());
|
||||
++itr;
|
||||
++size;
|
||||
ctx->push(itr->get_name());
|
||||
}
|
||||
|
||||
box2d<double> box(pt.x,pt.y,pt.x,pt.y);
|
||||
|
@ -599,7 +603,7 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt) const
|
|||
}
|
||||
|
||||
boost::shared_ptr<IResultSet> rs = get_resultset(conn, s.str());
|
||||
return boost::make_shared<postgis_featureset>(rs,desc_.get_encoding(), !key_field_.empty(),size);
|
||||
return boost::make_shared<postgis_featureset>(rs, ctx, desc_.get_encoding(), !key_field_.empty());
|
||||
}
|
||||
}
|
||||
return featureset_ptr();
|
||||
|
|
|
@ -46,13 +46,14 @@ using mapnik::geometry_type;
|
|||
using mapnik::byte;
|
||||
using mapnik::geometry_utils;
|
||||
using mapnik::feature_factory;
|
||||
using mapnik::context_ptr;
|
||||
|
||||
postgis_featureset::postgis_featureset(boost::shared_ptr<IResultSet> const& rs,
|
||||
context_ptr const& ctx,
|
||||
std::string const& encoding,
|
||||
bool key_field=false,
|
||||
unsigned num_attrs=0)
|
||||
bool key_field)
|
||||
: rs_(rs),
|
||||
num_attrs_(num_attrs),
|
||||
ctx_(ctx),
|
||||
tr_(new transcoder(encoding)),
|
||||
totalGeomSize_(0),
|
||||
feature_id_(1),
|
||||
|
@ -86,15 +87,15 @@ feature_ptr postgis_featureset::next()
|
|||
{
|
||||
val = int4net(buf);
|
||||
}
|
||||
feature = feature_factory::create(val);
|
||||
feature = feature_factory::create(ctx_, val);
|
||||
// TODO - extend feature class to know
|
||||
// that its id is also an attribute to avoid
|
||||
// this duplication
|
||||
boost::put(*feature,name,val);
|
||||
feature->put(name,val);
|
||||
++pos;
|
||||
} else {
|
||||
// fallback to auto-incrementing id
|
||||
feature = feature_factory::create(feature_id_);
|
||||
feature = feature_factory::create(ctx_,feature_id_);
|
||||
++feature_id_;
|
||||
}
|
||||
|
||||
|
@ -104,59 +105,59 @@ feature_ptr postgis_featureset::next()
|
|||
geometry_utils::from_wkb(feature->paths(), data, size);
|
||||
totalGeomSize_+=size;
|
||||
|
||||
for ( ;pos<num_attrs_+1;++pos)
|
||||
int num_attrs = ctx_->size() + 1;
|
||||
for ( ; pos < num_attrs; ++pos)
|
||||
{
|
||||
std::string name = rs_->getFieldName(pos);
|
||||
|
||||
|
||||
if (rs_->isNull(pos))
|
||||
{
|
||||
boost::put(*feature,name,mapnik::value_null());
|
||||
feature->put(name,mapnik::value_null());
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* buf = rs_->getValue(pos);
|
||||
int oid = rs_->getTypeOID(pos);
|
||||
|
||||
|
||||
if (oid==16) //bool
|
||||
{
|
||||
boost::put(*feature,name,buf[0] != 0);
|
||||
feature->put(name,(buf[0] != 0));
|
||||
}
|
||||
else if (oid==23) //int4
|
||||
{
|
||||
int val = int4net(buf);
|
||||
boost::put(*feature,name,val);
|
||||
feature->put(name,val);
|
||||
}
|
||||
else if (oid==21) //int2
|
||||
{
|
||||
int val = int2net(buf);
|
||||
boost::put(*feature,name,val);
|
||||
feature->put(name,val);
|
||||
}
|
||||
else if (oid==20) //int8/BigInt
|
||||
{
|
||||
int val = int8net(buf);
|
||||
boost::put(*feature,name,val);
|
||||
feature->put(name,val);
|
||||
}
|
||||
else if (oid == 700) // float4
|
||||
{
|
||||
float val;
|
||||
float4net(val,buf);
|
||||
boost::put(*feature,name,val);
|
||||
feature->put(name,val);
|
||||
}
|
||||
else if (oid == 701) // float8
|
||||
{
|
||||
double val;
|
||||
float8net(val,buf);
|
||||
boost::put(*feature,name,val);
|
||||
feature->put(name,val);
|
||||
}
|
||||
else if (oid==25 || oid==1043) // text or varchar
|
||||
{
|
||||
UnicodeString ustr = tr_->transcode(buf);
|
||||
boost::put(*feature,name,ustr);
|
||||
feature->put(name,tr_->transcode(buf));
|
||||
}
|
||||
else if (oid==1042)
|
||||
{
|
||||
UnicodeString ustr = tr_->transcode(trim_copy(std::string(buf)).c_str()); // bpchar
|
||||
boost::put(*feature,name,ustr);
|
||||
// bpchar
|
||||
feature->put(name,tr_->transcode(trim_copy(std::string(buf)).c_str()));
|
||||
}
|
||||
else if (oid == 1700) // numeric
|
||||
{
|
||||
|
@ -164,7 +165,7 @@ feature_ptr postgis_featureset::next()
|
|||
try
|
||||
{
|
||||
double val = boost::lexical_cast<double>(str);
|
||||
boost::put(*feature,name,val);
|
||||
feature->put(name,val);
|
||||
}
|
||||
catch (boost::bad_lexical_cast & ex)
|
||||
{
|
||||
|
|
|
@ -37,6 +37,7 @@ using mapnik::Featureset;
|
|||
using mapnik::box2d;
|
||||
using mapnik::feature_ptr;
|
||||
using mapnik::transcoder;
|
||||
using mapnik::context_ptr;
|
||||
|
||||
class IResultSet;
|
||||
|
||||
|
@ -44,21 +45,18 @@ class postgis_featureset : public mapnik::Featureset
|
|||
{
|
||||
private:
|
||||
boost::shared_ptr<IResultSet> rs_;
|
||||
unsigned num_attrs_;
|
||||
context_ptr ctx_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
int totalGeomSize_;
|
||||
int feature_id_;
|
||||
bool key_field_;
|
||||
public:
|
||||
postgis_featureset(boost::shared_ptr<IResultSet> const& rs,
|
||||
context_ptr const& ctx,
|
||||
std::string const& encoding,
|
||||
bool key_field,
|
||||
unsigned num_attrs);
|
||||
mapnik::feature_ptr next();
|
||||
bool key_field = false);
|
||||
feature_ptr next();
|
||||
~postgis_featureset();
|
||||
private:
|
||||
postgis_featureset(const postgis_featureset&);
|
||||
const postgis_featureset& operator=(const postgis_featureset&);
|
||||
};
|
||||
|
||||
#endif // POSTGIS_FEATURESET_HPP
|
||||
|
|
|
@ -50,6 +50,7 @@ raster_featureset<LookupPolicy>::raster_featureset(LookupPolicy const& policy,
|
|||
curIter_(policy_.begin()),
|
||||
endIter_(policy_.end())
|
||||
{
|
||||
ctx_ = boost::make_shared<mapnik::context_type>();
|
||||
}
|
||||
|
||||
template <typename LookupPolicy>
|
||||
|
@ -62,9 +63,8 @@ feature_ptr raster_featureset<LookupPolicy>::next()
|
|||
{
|
||||
if (curIter_ != endIter_)
|
||||
{
|
||||
feature_ptr feature(feature_factory::create(feature_id_));
|
||||
++feature_id_;
|
||||
|
||||
feature_ptr feature(feature_factory::create(ctx_,feature_id_++));
|
||||
|
||||
try
|
||||
{
|
||||
std::auto_ptr<image_reader> reader(mapnik::get_image_reader(curIter_->file(),curIter_->format()));
|
||||
|
|
|
@ -310,6 +310,7 @@ class raster_featureset : public mapnik::Featureset
|
|||
typedef typename LookupPolicy::const_iterator iterator_type;
|
||||
LookupPolicy policy_;
|
||||
int feature_id_;
|
||||
mapnik::context_ptr ctx_;
|
||||
mapnik::box2d<double> extent_;
|
||||
mapnik::box2d<double> bbox_;
|
||||
iterator_type curIter_;
|
||||
|
|
|
@ -34,6 +34,7 @@ shape_src = Split(
|
|||
shape_featureset.cpp
|
||||
shape_index_featureset.cpp
|
||||
shape_io.cpp
|
||||
shape_utils.cpp
|
||||
"""
|
||||
)
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ const field_descriptor& dbf_file::descriptor(int col) const
|
|||
}
|
||||
|
||||
|
||||
void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, Feature const& f) const throw()
|
||||
void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, Feature & f) const throw()
|
||||
{
|
||||
using namespace boost::spirit;
|
||||
|
||||
|
@ -139,7 +139,7 @@ void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, Feature cons
|
|||
// FIXME - avoid constructing std::string on stack
|
||||
std::string str(record_+fields_[col].offset_,fields_[col].length_);
|
||||
boost::trim(str);
|
||||
f[name] = tr.transcode(str.c_str());
|
||||
f.put(name,tr.transcode(str.c_str()));
|
||||
break;
|
||||
}
|
||||
case 'N':
|
||||
|
@ -148,7 +148,7 @@ void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, Feature cons
|
|||
|
||||
if (record_[fields_[col].offset_] == '*')
|
||||
{
|
||||
boost::put(f,name,0);
|
||||
f.put(name,0);
|
||||
break;
|
||||
}
|
||||
if ( fields_[col].dec_>0 )
|
||||
|
@ -157,7 +157,7 @@ void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, Feature cons
|
|||
const char *itr = record_+fields_[col].offset_;
|
||||
const char *end = itr + fields_[col].length_;
|
||||
qi::phrase_parse(itr,end,double_,ascii::space,val);
|
||||
boost::put(f,name,val);
|
||||
f.put(name,val);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -165,7 +165,7 @@ void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, Feature cons
|
|||
const char *itr = record_+fields_[col].offset_;
|
||||
const char *end = itr + fields_[col].length_;
|
||||
qi::phrase_parse(itr,end,int_,ascii::space,val);
|
||||
boost::put(f,name,val);
|
||||
f.put(name,val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ public:
|
|||
field_descriptor const& descriptor(int col) const;
|
||||
void move_to(int index);
|
||||
std::string string_value(int col) const;
|
||||
void add_attribute(int col, transcoder const& tr, Feature const& f) const throw();
|
||||
void add_attribute(int col, transcoder const& tr, Feature & f) const throw();
|
||||
private:
|
||||
void read_header();
|
||||
int read_short();
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
|
@ -27,65 +26,31 @@
|
|||
// mapnik
|
||||
#include <mapnik/feature_factory.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include "shape_featureset.hpp"
|
||||
#include "shape_utils.hpp"
|
||||
|
||||
using mapnik::geometry_type;
|
||||
using mapnik::feature_factory;
|
||||
|
||||
using mapnik::context_ptr;
|
||||
|
||||
template <typename filterT>
|
||||
shape_featureset<filterT>::shape_featureset(const filterT& filter,
|
||||
const std::string& shape_name,
|
||||
const std::set<std::string>& attribute_names,
|
||||
shape_featureset<filterT>::shape_featureset(filterT const& filter,
|
||||
std::string const& shape_name,
|
||||
std::set<std::string> const& attribute_names,
|
||||
std::string const& encoding,
|
||||
long file_length,
|
||||
int row_limit)
|
||||
: filter_(filter),
|
||||
//shape_type_(shape_io::shape_null),
|
||||
shape_(shape_name, false),
|
||||
query_ext_(),
|
||||
tr_(new transcoder(encoding)),
|
||||
file_length_(file_length),
|
||||
count_(0),
|
||||
row_limit_(row_limit)
|
||||
row_limit_(row_limit),
|
||||
count_(0)
|
||||
{
|
||||
ctx_ = boost::make_shared<mapnik::context_type>();
|
||||
shape_.shp().skip(100);
|
||||
|
||||
//attributes
|
||||
typename std::set<std::string>::const_iterator pos = attribute_names.begin();
|
||||
while (pos != attribute_names.end())
|
||||
{
|
||||
bool found_name = false;
|
||||
for (int i = 0; i < shape_.dbf().num_fields(); ++i)
|
||||
{
|
||||
if (shape_.dbf().descriptor(i).name_ == *pos)
|
||||
{
|
||||
attr_ids_.push_back(i);
|
||||
found_name = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found_name)
|
||||
{
|
||||
std::ostringstream s;
|
||||
|
||||
s << "no attribute '" << *pos << "' in '"
|
||||
<< shape_name << "'. Valid attributes are: ";
|
||||
|
||||
std::vector<std::string> list;
|
||||
for (int i = 0; i < shape_.dbf().num_fields(); ++i)
|
||||
{
|
||||
list.push_back(shape_.dbf().descriptor(i).name_);
|
||||
}
|
||||
s << boost::algorithm::join(list, ",") << ".";
|
||||
|
||||
throw mapnik::datasource_exception("Shape Plugin: " + s.str());
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
setup_attributes(ctx_, attribute_names, shape_name, shape_,attr_ids_);
|
||||
}
|
||||
|
||||
template <typename filterT>
|
||||
|
@ -115,7 +80,7 @@ feature_ptr shape_featureset<filterT>::next()
|
|||
if (pos < std::streampos(file_length_ * 2))
|
||||
{
|
||||
int type = shape_.type();
|
||||
feature_ptr feature(feature_factory::create(shape_.id_));
|
||||
feature_ptr feature(feature_factory::create(ctx_, shape_.id_));
|
||||
|
||||
if (type == shape_io::shape_point)
|
||||
{
|
||||
|
@ -266,7 +231,7 @@ feature_ptr shape_featureset<filterT>::next()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: https://github.com/mapnik/mapnik/issues/1020
|
||||
feature->set_id(shape_.id_);
|
||||
if (attr_ids_.size())
|
||||
{
|
||||
|
|
|
@ -31,41 +31,36 @@
|
|||
|
||||
//boost
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
using mapnik::Featureset;
|
||||
using mapnik::box2d;
|
||||
using mapnik::feature_ptr;
|
||||
using mapnik::transcoder;
|
||||
using mapnik::context_ptr;
|
||||
|
||||
template <typename filterT>
|
||||
class shape_featureset : public Featureset
|
||||
{
|
||||
filterT filter_;
|
||||
//int shape_type_;
|
||||
context_ptr ctx_;
|
||||
shape_io shape_;
|
||||
box2d<double> query_ext_;
|
||||
boost::scoped_ptr<transcoder> tr_;
|
||||
long file_length_;
|
||||
std::vector<int> attr_ids_;
|
||||
mutable box2d<double> feature_ext_;
|
||||
mutable int total_geom_size;
|
||||
mutable int count_;
|
||||
const int row_limit_;
|
||||
|
||||
mutable int count_;
|
||||
|
||||
public:
|
||||
shape_featureset(const filterT& filter,
|
||||
const std::string& shape_file,
|
||||
const std::set<std::string>& attribute_names,
|
||||
shape_featureset(filterT const& filter,
|
||||
std::string const& shape_file,
|
||||
std::set<std::string> const& attribute_names,
|
||||
std::string const& encoding,
|
||||
long file_length,
|
||||
int row_limit);
|
||||
virtual ~shape_featureset();
|
||||
feature_ptr next();
|
||||
|
||||
private:
|
||||
shape_featureset(const shape_featureset&);
|
||||
const shape_featureset& operator=(const shape_featureset&);
|
||||
|
||||
};
|
||||
|
||||
#endif //SHAPE_FEATURESET_HPP
|
||||
|
|
|
@ -31,26 +31,28 @@
|
|||
#include <boost/interprocess/streams/bufferstream.hpp>
|
||||
|
||||
#include "shape_index_featureset.hpp"
|
||||
#include "shape_utils.hpp"
|
||||
|
||||
using mapnik::feature_factory;
|
||||
using mapnik::geometry_type;
|
||||
|
||||
template <typename filterT>
|
||||
shape_index_featureset<filterT>::shape_index_featureset(const filterT& filter,
|
||||
shape_index_featureset<filterT>::shape_index_featureset(filterT const& filter,
|
||||
shape_io& shape,
|
||||
const std::set<std::string>& attribute_names,
|
||||
std::set<std::string> const& attribute_names,
|
||||
std::string const& encoding,
|
||||
std::string const& shape_name,
|
||||
int row_limit)
|
||||
: filter_(filter),
|
||||
//shape_type_(0),
|
||||
shape_(shape),
|
||||
tr_(new transcoder(encoding)),
|
||||
count_(0),
|
||||
row_limit_(row_limit)
|
||||
row_limit_(row_limit),
|
||||
count_(0)
|
||||
{
|
||||
ctx_ = boost::make_shared<mapnik::context_type>();
|
||||
shape_.shp().skip(100);
|
||||
|
||||
setup_attributes(ctx_, attribute_names, shape_name, shape_,attr_ids_);
|
||||
|
||||
boost::shared_ptr<shape_file> index = shape_.index();
|
||||
if (index)
|
||||
{
|
||||
|
@ -63,46 +65,12 @@ shape_index_featureset<filterT>::shape_index_featureset(const filterT& filter,
|
|||
}
|
||||
|
||||
std::sort(ids_.begin(), ids_.end());
|
||||
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "Shape Plugin: query size=" << ids_.size() << std::endl;
|
||||
#endif
|
||||
|
||||
itr_ = ids_.begin();
|
||||
|
||||
// deal with attributes
|
||||
std::set<std::string>::const_iterator pos = attribute_names.begin();
|
||||
while (pos != attribute_names.end())
|
||||
{
|
||||
bool found_name = false;
|
||||
for (int i = 0; i < shape_.dbf().num_fields(); ++i)
|
||||
{
|
||||
if (shape_.dbf().descriptor(i).name_ == *pos)
|
||||
{
|
||||
attr_ids_.insert(i);
|
||||
found_name = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found_name)
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << "no attribute '" << *pos << "' in '" << shape_name << "'. Valid attributes are: ";
|
||||
|
||||
std::vector<std::string> list;
|
||||
for (int i = 0; i < shape_.dbf().num_fields(); ++i)
|
||||
{
|
||||
list.push_back(shape_.dbf().descriptor(i).name_);
|
||||
}
|
||||
|
||||
s << boost::algorithm::join(list, ",") << ".";
|
||||
|
||||
throw mapnik::datasource_exception("Shape Plugin: " + s.str());
|
||||
}
|
||||
|
||||
++pos;
|
||||
}
|
||||
|
||||
itr_ = ids_.begin();
|
||||
}
|
||||
|
||||
template <typename filterT>
|
||||
|
@ -119,7 +87,7 @@ feature_ptr shape_index_featureset<filterT>::next()
|
|||
shape_.move_to(pos);
|
||||
|
||||
int type = shape_.type();
|
||||
feature_ptr feature(feature_factory::create(shape_.id_));
|
||||
feature_ptr feature(feature_factory::create(ctx_,shape_.id_));
|
||||
if (type == shape_io::shape_point)
|
||||
{
|
||||
double x = shape_.shp().read_double();
|
||||
|
@ -210,13 +178,13 @@ feature_ptr shape_index_featureset<filterT>::next()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME
|
||||
feature->set_id(shape_.id_);
|
||||
if (attr_ids_.size())
|
||||
{
|
||||
shape_.dbf().move_to(shape_.id_);
|
||||
std::set<int>::const_iterator itr = attr_ids_.begin();
|
||||
std::set<int>::const_iterator end = attr_ids_.end();
|
||||
std::vector<int>::const_iterator itr = attr_ids_.begin();
|
||||
std::vector<int>::const_iterator end = attr_ids_.end();
|
||||
try
|
||||
{
|
||||
for (; itr!=end; ++itr)
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
// boost
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#include "shape_datasource.hpp"
|
||||
#include "shape_io.hpp"
|
||||
|
@ -39,35 +40,33 @@
|
|||
using mapnik::Featureset;
|
||||
using mapnik::box2d;
|
||||
using mapnik::feature_ptr;
|
||||
using mapnik::context_ptr;
|
||||
|
||||
template <typename filterT>
|
||||
class shape_index_featureset : public Featureset
|
||||
class shape_index_featureset : public Featureset
|
||||
{
|
||||
public:
|
||||
shape_index_featureset(const filterT& filter,
|
||||
shape_io& shape,
|
||||
const std::set<std::string>& attribute_names,
|
||||
shape_index_featureset(filterT const& filter,
|
||||
shape_io & shape,
|
||||
std::set<std::string> const& attribute_names,
|
||||
std::string const& encoding,
|
||||
std::string const& shape_name,
|
||||
int row_limit);
|
||||
|
||||
virtual ~shape_index_featureset();
|
||||
|
||||
feature_ptr next();
|
||||
|
||||
private:
|
||||
filterT filter_;
|
||||
//int shape_type_;
|
||||
context_ptr ctx_;
|
||||
shape_io & shape_;
|
||||
boost::scoped_ptr<transcoder> tr_;
|
||||
std::vector<int> ids_;
|
||||
std::vector<int>::iterator itr_;
|
||||
std::set<int> attr_ids_;
|
||||
mutable box2d<double> feature_ext_;
|
||||
mutable int total_geom_size;
|
||||
mutable int count_;
|
||||
std::vector<int> attr_ids_;
|
||||
const int row_limit_;
|
||||
//no copying
|
||||
shape_index_featureset(const shape_index_featureset&);
|
||||
shape_index_featureset& operator=(const shape_index_featureset&);
|
||||
mutable int count_;
|
||||
};
|
||||
|
||||
#endif // SHAPE_INDEX_FEATURESET_HPP
|
||||
|
|
|
@ -94,13 +94,6 @@ shape_file& shape_io::shp()
|
|||
return shp_;
|
||||
}
|
||||
|
||||
#if 0
|
||||
shape_file& shape_io::shx()
|
||||
{
|
||||
return shx_;
|
||||
}
|
||||
#endif
|
||||
|
||||
dbf_file& shape_io::dbf()
|
||||
{
|
||||
return dbf_;
|
||||
|
|
73
plugins/input/shape/shape_utils.cpp
Normal file
73
plugins/input/shape/shape_utils.cpp
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include "shape_utils.hpp"
|
||||
|
||||
// boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
// stl
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
void setup_attributes(mapnik::context_ptr const& ctx,
|
||||
std::set<std::string> const& names,
|
||||
std::string const& shape_name,
|
||||
shape_io & shape,
|
||||
std::vector<int> & attr_ids)
|
||||
{
|
||||
std::set<std::string>::const_iterator pos = names.begin();
|
||||
std::set<std::string>::const_iterator end = names.end();
|
||||
for ( ;pos !=end; ++pos)
|
||||
{
|
||||
bool found_name = false;
|
||||
for (int i = 0; i < shape.dbf().num_fields(); ++i)
|
||||
{
|
||||
if (shape.dbf().descriptor(i).name_ == *pos)
|
||||
{
|
||||
ctx->push(*pos);
|
||||
attr_ids.push_back(i);
|
||||
found_name = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found_name)
|
||||
{
|
||||
std::ostringstream s;
|
||||
|
||||
s << "no attribute '" << *pos << "' in '"
|
||||
<< shape_name << "'. Valid attributes are: ";
|
||||
|
||||
std::vector<std::string> list;
|
||||
for (int i = 0; i < shape.dbf().num_fields(); ++i)
|
||||
{
|
||||
list.push_back(shape.dbf().descriptor(i).name_);
|
||||
}
|
||||
s << boost::algorithm::join(list, ",") << ".";
|
||||
|
||||
throw mapnik::datasource_exception("Shape Plugin: " + s.str());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,22 +19,22 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
//$Id$
|
||||
|
||||
#ifndef SHAPE_UTILS_HPP
|
||||
#define SHAPE_UTILS_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/svg_renderer.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include "shape_io.hpp"
|
||||
// stl
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
template <typename T>
|
||||
void svg_renderer<T>::process(glyph_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
// nothing yet.
|
||||
}
|
||||
void setup_attributes(mapnik::context_ptr const& ctx,
|
||||
std::set<std::string> const& names,
|
||||
std::string const& shape_name,
|
||||
shape_io & shape,
|
||||
std::vector<int> & attr_ids);
|
||||
|
||||
template void svg_renderer<std::ostream_iterator<char> >::process(glyph_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans);
|
||||
}
|
||||
#endif // SHAPE_UTILS_HPP
|
|
@ -553,19 +553,24 @@ featureset_ptr sqlite_datasource::features(query const& q) const
|
|||
mapnik::box2d<double> const& e = q.get_bbox();
|
||||
|
||||
std::ostringstream s;
|
||||
mapnik::context_ptr ctx = boost::make_shared<mapnik::context_type>();
|
||||
|
||||
s << "SELECT " << geometry_field_;
|
||||
if (!key_field_.empty())
|
||||
{
|
||||
s << "," << key_field_;
|
||||
ctx->push(key_field_);
|
||||
}
|
||||
std::set<std::string> const& props = q.property_names();
|
||||
std::set<std::string>::const_iterator pos = props.begin();
|
||||
std::set<std::string>::const_iterator end = props.end();
|
||||
while (pos != end)
|
||||
|
||||
for ( ;pos != end;++pos)
|
||||
{
|
||||
// TODO - should we restrict duplicate key query?
|
||||
//if (*pos != key_field_)
|
||||
s << ",[" << *pos << "]";
|
||||
++pos;
|
||||
ctx->push(*pos);
|
||||
}
|
||||
|
||||
s << " FROM ";
|
||||
|
@ -607,6 +612,7 @@ featureset_ptr sqlite_datasource::features(query const& q) const
|
|||
boost::shared_ptr<sqlite_resultset> rs(dataset_->execute_query(s.str()));
|
||||
|
||||
return boost::make_shared<sqlite_featureset>(rs,
|
||||
ctx,
|
||||
desc_.get_encoding(),
|
||||
format_,
|
||||
using_subquery_);
|
||||
|
@ -625,20 +631,26 @@ featureset_ptr sqlite_datasource::features_at_point(coord2d const& pt) const
|
|||
mapnik::box2d<double> const e(pt.x, pt.y, pt.x, pt.y);
|
||||
|
||||
std::ostringstream s;
|
||||
mapnik::context_ptr ctx = boost::make_shared<mapnik::context_type>();
|
||||
|
||||
s << "SELECT " << geometry_field_;
|
||||
if (!key_field_.empty())
|
||||
{
|
||||
s << "," << key_field_;
|
||||
ctx->push(key_field_);
|
||||
}
|
||||
|
||||
std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin();
|
||||
std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end();
|
||||
while (itr != end)
|
||||
|
||||
for ( ; itr != end; ++itr)
|
||||
{
|
||||
std::string fld_name = itr->get_name();
|
||||
if (fld_name != key_field_)
|
||||
{
|
||||
s << ",[" << itr->get_name() << "]";
|
||||
ctx->push(itr->get_name());
|
||||
}
|
||||
|
||||
++itr;
|
||||
}
|
||||
|
||||
s << " FROM ";
|
||||
|
@ -680,6 +692,7 @@ featureset_ptr sqlite_datasource::features_at_point(coord2d const& pt) const
|
|||
boost::shared_ptr<sqlite_resultset> rs(dataset_->execute_query(s.str()));
|
||||
|
||||
return boost::make_shared<sqlite_featureset>(rs,
|
||||
ctx,
|
||||
desc_.get_encoding(),
|
||||
format_,
|
||||
using_subquery_);
|
||||
|
|
|
@ -45,13 +45,15 @@ using mapnik::transcoder;
|
|||
using mapnik::feature_factory;
|
||||
|
||||
sqlite_featureset::sqlite_featureset(boost::shared_ptr<sqlite_resultset> rs,
|
||||
mapnik::context_ptr const& ctx,
|
||||
std::string const& encoding,
|
||||
mapnik::wkbFormat format,
|
||||
bool using_subquery)
|
||||
: rs_(rs),
|
||||
tr_(new transcoder(encoding)),
|
||||
format_(format),
|
||||
using_subquery_(using_subquery)
|
||||
using_subquery_(using_subquery),
|
||||
ctx_(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -70,9 +72,7 @@ feature_ptr sqlite_featureset::next()
|
|||
return feature_ptr();
|
||||
}
|
||||
|
||||
int feature_id = rs_->column_integer(1);
|
||||
|
||||
feature_ptr feature(feature_factory::create(feature_id));
|
||||
feature_ptr feature(feature_factory::create(ctx_,rs_->column_integer(1)));
|
||||
geometry_utils::from_wkb(feature->paths(), data, size, format_);
|
||||
|
||||
for (int i = 2; i < rs_->column_count(); ++i)
|
||||
|
@ -95,13 +95,13 @@ feature_ptr sqlite_featureset::next()
|
|||
{
|
||||
case SQLITE_INTEGER:
|
||||
{
|
||||
boost::put(*feature, fld_name_str, rs_->column_integer(i));
|
||||
feature->put(fld_name_str, rs_->column_integer(i));
|
||||
break;
|
||||
}
|
||||
|
||||
case SQLITE_FLOAT:
|
||||
{
|
||||
boost::put(*feature, fld_name_str, rs_->column_double(i));
|
||||
feature->put(fld_name_str, rs_->column_double(i));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -110,13 +110,13 @@ feature_ptr sqlite_featureset::next()
|
|||
int text_size;
|
||||
const char * data = rs_->column_text(i, text_size);
|
||||
UnicodeString ustr = tr_->transcode(data, text_size);
|
||||
boost::put(*feature, fld_name_str, ustr);
|
||||
feature->put(fld_name_str, ustr);
|
||||
break;
|
||||
}
|
||||
|
||||
case SQLITE_NULL:
|
||||
{
|
||||
boost::put(*feature, fld_name_str, mapnik::value_null());
|
||||
feature->put(fld_name_str, mapnik::value_null());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ class sqlite_featureset : public mapnik::Featureset
|
|||
{
|
||||
public:
|
||||
sqlite_featureset(boost::shared_ptr<sqlite_resultset> rs,
|
||||
mapnik::context_ptr const& ctx,
|
||||
std::string const& encoding,
|
||||
mapnik::wkbFormat format,
|
||||
bool using_subquery);
|
||||
|
@ -51,6 +52,7 @@ private:
|
|||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
mapnik::wkbFormat format_;
|
||||
bool using_subquery_;
|
||||
mapnik::context_ptr ctx_;
|
||||
};
|
||||
|
||||
#endif // MAPNIK_SQLITE_FEATURESET_HPP
|
||||
|
|
|
@ -12,7 +12,7 @@ using mapnik::parameters;
|
|||
DATASOURCE_PLUGIN(hello_datasource)
|
||||
|
||||
hello_datasource::hello_datasource(parameters const& params, bool bind)
|
||||
: datasource(params)
|
||||
: datasource(params),
|
||||
desc_(*params_.get<std::string>("type"), *params_.get<std::string>("encoding","utf-8")),
|
||||
extent_()
|
||||
{
|
||||
|
@ -33,10 +33,6 @@ void hello_datasource::bind() const
|
|||
// see http://spatialreference.org/ref/epsg/4326/ for more details
|
||||
extent_.init(-180,-90,180,90);
|
||||
|
||||
// declare that this datasource is going to provide points
|
||||
// options are point,polygon,linestring, and collection
|
||||
desc_.set_geometry_type("point");
|
||||
|
||||
is_bound_ = true;
|
||||
}
|
||||
|
||||
|
@ -64,7 +60,7 @@ mapnik::box2d<double> hello_datasource::envelope() const
|
|||
|
||||
boost::optional<mapnik::datasource::geometry_t> hello_datasource::get_geometry_type() const
|
||||
{
|
||||
boost::optional<mapnik::datasource::geometry_t>(mapnik::datasource::Point);
|
||||
return mapnik::datasource::Point;
|
||||
}
|
||||
|
||||
mapnik::layer_descriptor hello_datasource::get_descriptor() const
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
hello_featureset::hello_featureset(mapnik::box2d<double> const& box, std::string const& encoding)
|
||||
: box_(box),
|
||||
feature_id_(1),
|
||||
tr_(new mapnik::transcoder(encoding)) { }
|
||||
tr_(new mapnik::transcoder(encoding)),
|
||||
ctx_(boost::make_shared<mapnik::context_type>()) { }
|
||||
|
||||
hello_featureset::~hello_featureset() { }
|
||||
|
||||
|
@ -16,14 +17,14 @@ mapnik::feature_ptr hello_featureset::next()
|
|||
if (feature_id_ == 1)
|
||||
{
|
||||
// create a new feature
|
||||
mapnik::feature_ptr feature(mapnik::feature_factory::create(feature_id_));
|
||||
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_));
|
||||
|
||||
// increment the count so that we only return one feature
|
||||
++feature_id_;
|
||||
|
||||
// create an attribute pair of key:value
|
||||
UnicodeString ustr = tr_->transcode("hello world!");
|
||||
boost::put(*feature,"key",ustr);
|
||||
feature->put("key",ustr);
|
||||
|
||||
// we need a geometry to display so just for fun here
|
||||
// we take the center of the bbox that was used to query
|
||||
|
|
|
@ -25,6 +25,7 @@ private:
|
|||
mapnik::box2d<double> const& box_;
|
||||
mutable int feature_id_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
mapnik::context_ptr ctx_;
|
||||
};
|
||||
|
||||
#endif // HELLO_FEATURESET_HPP
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <mapnik/font_set.hpp>
|
||||
#include <mapnik/parse_path.hpp>
|
||||
#include <mapnik/text_path.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/svg/svg_converter.hpp>
|
||||
#include <mapnik/svg/svg_renderer.hpp>
|
||||
#include <mapnik/svg/svg_path_adapter.hpp>
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
//$Id$
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
|
||||
// agg
|
||||
#include "agg_basics.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
#include "agg_pixfmt_rgba.h"
|
||||
#include "agg_rasterizer_scanline_aa.h"
|
||||
#include "agg_scanline_u.h"
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
template <typename T>
|
||||
void agg_renderer<T>::process(glyph_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
face_set_ptr faces = font_manager_.get_face_set(sym.get_face_name());
|
||||
stroker_ptr strk = font_manager_.get_stroker();
|
||||
if (faces->size() > 0 && strk)
|
||||
{
|
||||
// Get x and y from geometry and translate to pixmap coords.
|
||||
double x, y, z=0.0;
|
||||
feature.get_geometry(0).label_position(&x, &y);
|
||||
prj_trans.backward(x,y,z);
|
||||
t_.forward(&x, &y);
|
||||
|
||||
text_renderer<T> ren(pixmap_, faces, *strk);
|
||||
|
||||
// set fill and halo colors
|
||||
color fill = sym.eval_color(feature);
|
||||
ren.set_fill(fill);
|
||||
if (fill != color("transparent")) {
|
||||
ren.set_halo_fill(sym.get_halo_fill());
|
||||
ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);
|
||||
}
|
||||
|
||||
// set font size
|
||||
float size = sym.eval_size(feature);
|
||||
ren.set_character_size(size * scale_factor_);
|
||||
faces->set_character_sizes(size * scale_factor_);
|
||||
|
||||
// Get and render text path
|
||||
//
|
||||
text_path_ptr path = sym.get_text_path(faces, feature);
|
||||
// apply displacement
|
||||
position pos = sym.get_displacement();
|
||||
double dx = boost::get<0>(pos);
|
||||
double dy = boost::get<1>(pos);
|
||||
path->starting_x = x = x+dx;
|
||||
path->starting_y = y = y+dy;
|
||||
|
||||
// Prepare glyphs to set internal state and calculate the marker's
|
||||
// final box so we can check for a valid placement
|
||||
box2d<double> dim = ren.prepare_glyphs(path.get());
|
||||
box2d<double> ext(x-dim.width()/2, y-dim.height()/2, x+dim.width()/2, y+dim.height()/2);
|
||||
if ((sym.get_allow_overlap() || detector_->has_placement(ext)) &&
|
||||
(!sym.get_avoid_edges() || detector_->extent().contains(ext)))
|
||||
{
|
||||
// Placement is valid, render glyph and update detector.
|
||||
ren.render(x, y);
|
||||
detector_->insert(ext);
|
||||
metawriter_with_properties writer = sym.get_metawriter();
|
||||
if (writer.first) writer.first->add_box(ext, feature, t_, writer.second);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw config_error(
|
||||
"Unable to find specified font face in GlyphSymbolizer"
|
||||
);
|
||||
}
|
||||
}
|
||||
template void agg_renderer<image_32>::process(glyph_symbolizer const&,
|
||||
Feature const&,
|
||||
proj_transform const&);
|
||||
}
|
|
@ -27,6 +27,7 @@
|
|||
#include <mapnik/agg_pattern_source.hpp>
|
||||
#include <mapnik/expression_evaluator.hpp>
|
||||
#include <mapnik/marker_cache.hpp>
|
||||
#include <mapnik/line_pattern_symbolizer.hpp>
|
||||
|
||||
// agg
|
||||
#include "agg_basics.h"
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
// mapnik
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/line_symbolizer.hpp>
|
||||
|
||||
// agg
|
||||
#include "agg_basics.h"
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <mapnik/svg/svg_path_adapter.hpp>
|
||||
#include <mapnik/markers_placement.hpp>
|
||||
#include <mapnik/arrow.hpp>
|
||||
#include <mapnik/markers_symbolizer.hpp>
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
// mapnik
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/polygon_symbolizer.hpp>
|
||||
|
||||
// agg
|
||||
#include "agg_basics.h"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue