1.added projection transformation support based on proj4 (new dependency!!!)

Map and Layer objects both have a new parameter 'srs', initialized to "+proj=latlong +datum=WGS84" by default. 
    
  Basic usage (Python):
    p = Projection("+proj=merc +datum=WGS84")
    point = p.forward(Coord(-2,51))
    ...        
2.reflected arithmetic operators for Envelope/Coord into Python
3.altered return policies for python objects
4.modified build system to require proj4 lib and headers
This commit is contained in:
Artem Pavlenko 2006-10-16 13:44:52 +00:00
parent 52033ad4e8
commit bb235fa316
24 changed files with 670 additions and 167 deletions

View file

@ -45,7 +45,6 @@ opts.Add(PathOption('PROJ_LIBS', 'Search path for PROJ.4 include files', '/usr/l
opts.Add(PathOption('PYTHON','Python executable', sys.executable)) opts.Add(PathOption('PYTHON','Python executable', sys.executable))
opts.Add(ListOption('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster'])) opts.Add(ListOption('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster']))
opts.Add(ListOption('BINDINGS','Language bindings to build','all',['python'])) opts.Add(ListOption('BINDINGS','Language bindings to build','all',['python']))
opts.Add('DEBUG', 'Compile a debug version of mapnik', '') opts.Add('DEBUG', 'Compile a debug version of mapnik', '')
env = Environment(ENV=os.environ, options=opts) env = Environment(ENV=os.environ, options=opts)
@ -59,14 +58,24 @@ conf = Configure(env)
env['CPPPATH'] = ['#agg/include', '#include', '#'] env['CPPPATH'] = ['#agg/include', '#include', '#']
for path in [env['BOOST_INCLUDES'], env['PNG_INCLUDES'], env['JPEG_INCLUDES'], env['TIFF_INCLUDES'], env['PGSQL_INCLUDES'], env['PROJ_INCLUDES']]: for path in [env['BOOST_INCLUDES'],
env['PNG_INCLUDES'],
env['JPEG_INCLUDES'],
env['TIFF_INCLUDES'],
env['PGSQL_INCLUDES'],
env['PROJ_INCLUDES']]:
if path not in env['CPPPATH']: env['CPPPATH'].append(path) if path not in env['CPPPATH']: env['CPPPATH'].append(path)
env['LIBPATH'] = ['#agg', '#src'] env['LIBPATH'] = ['#agg', '#src']
for path in [env['BOOST_LIBS'], env['PNG_LIBS'], env['JPEG_LIBS'], env['TIFF_LIBS'], env['PGSQL_LIBS'], env['PROJ_LIBS']]: for path in [env['BOOST_LIBS'],
env['PNG_LIBS'],
env['JPEG_LIBS'],
env['TIFF_LIBS'],
env['PGSQL_LIBS'],
env['PROJ_LIBS']]:
if path not in env['LIBPATH']: env['LIBPATH'].append(path) if path not in env['LIBPATH']: env['LIBPATH'].append(path)
env.ParseConfig(env['FREETYPE_CONFIG'] + ' --libs --cflags') env.ParseConfig(env['FREETYPE_CONFIG'] + ' --libs --cflags')
C_LIBSHEADERS = [ C_LIBSHEADERS = [
@ -76,8 +85,8 @@ C_LIBSHEADERS = [
['tiff', 'tiff.h', True], ['tiff', 'tiff.h', True],
['z', 'zlib.h', True], ['z', 'zlib.h', True],
['jpeg', ['stdio.h', 'jpeglib.h'], True], ['jpeg', ['stdio.h', 'jpeglib.h'], True],
['pq', 'libpq-fe.h', False], ['proj', 'proj_api.h', True],
['proj', 'proj_api.h', False] ['pq', 'libpq-fe.h', False]
] ]
BOOST_LIBSHEADERS = [ BOOST_LIBSHEADERS = [
@ -130,10 +139,7 @@ if 'python' in env['BINDINGS']:
SConscript('bindings/python/SConscript') SConscript('bindings/python/SConscript')
if 'proj' in env['LIBS']:
SConscript('bindings/python/pyprojection/SConscript')
env['LIBS'].remove('proj')
env = conf.Finish() env = conf.Finish()
# Setup the c++ args for our own codebase # Setup the c++ args for our own codebase

View file

@ -21,4 +21,4 @@ import glob
Import('env') Import('env')
env.StaticLibrary('agg', glob.glob('./src/' + '*.cpp'), LIBS=[], CPPPATH='./include', CXXFLAGS='-O3 -fPIC ') env.StaticLibrary('agg', glob.glob('./src/' + '*.cpp'), LIBS=[], CPPPATH='./include', CXXFLAGS='-O3 -fPIC -DNDEBUG')

View file

@ -55,10 +55,16 @@ class _Coord(Coord,_injector):
return 'Coord(%s,%s)' % (self.x, self.y) return 'Coord(%s,%s)' % (self.x, self.y)
class _Envelope(Envelope,_injector): class _Envelope(Envelope,_injector):
def __repr__(self): def __repr__(self):
return 'Envelope(%s,%s,%s,%s)' % \ return 'Envelope(%s,%s,%s,%s)' % \
(self.minx,self.miny,self.maxx,self.maxy) (self.minx,self.miny,self.maxx,self.maxy)
class _Projection(Projection,_injector):
def forward(self,pt):
return forward(pt,self)
def inverse(self,pt):
return inverse(pt,self)
def Datasource (**keywords): def Datasource (**keywords):
return CreateDatasource(keywords) return CreateDatasource(keywords)

View file

@ -0,0 +1,45 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//$Id$
#include <boost/python.hpp>
#include <mapnik/coord.hpp>
void export_coord()
{
using namespace boost::python;
using mapnik::coord;
class_<coord<double,2> >("Coord",init<double,double>())
.def_readwrite("x", &coord<double,2>::x)
.def_readwrite("y", &coord<double,2>::y)
.def(self == self) // __eq__
.def(self + self) // __add__
.def(self + float())
.def(float() + self)
.def(self - self) // __sub__
.def(self - float())
.def(self * float()) //__mult__
.def(float() * self)
.def(self / float()) // __div__
;
}

View file

@ -0,0 +1,68 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//$Id$
#include <boost/python.hpp>
#include <mapnik/envelope.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/datasource_cache.hpp>
namespace
{
//user-friendly wrapper that uses Python dictionary
using namespace boost::python;
boost::shared_ptr<mapnik::datasource> create_datasource(const dict& d)
{
mapnik::parameters params;
boost::python::list keys=d.keys();
for (int i=0; i<len(keys); ++i)
{
std::string key = extract<std::string>(keys[i]);
object obj = d[key];
extract<std::string> ex(obj);
if (ex.check())
{
params[key] = ex();
}
}
return mapnik::datasource_cache::create(params);
}
}
void export_datasource()
{
using namespace boost::python;
using mapnik::datasource;
class_<datasource,boost::shared_ptr<datasource>,
boost::noncopyable>("Datasource",no_init)
.def("envelope",&datasource::envelope,
return_value_policy<copy_const_reference>())
.def("features",&datasource::features)
.def("params",&datasource::params,return_value_policy<copy_const_reference>(),
"The configuration parameters of the data source. "
"These vary depending on the type of data source.")
;
def("CreateDatasource",&create_datasource);
}

View file

@ -85,7 +85,12 @@ void export_envelope()
.def("intersects",intersects_p1) .def("intersects",intersects_p1)
.def("intersects",intersects_p2) .def("intersects",intersects_p2)
.def("intersects",intersects_p3) .def("intersects",intersects_p3)
.def(self == self) .def(self == self) // __eq__
.def(self + self) // __add__
.def(self - self) // __sub__
.def(self * float()) // __mult__
.def(float() * self)
.def(self / float()) // __div__
.def_pickle(envelope_pickle_suite()) .def_pickle(envelope_pickle_suite())
; ;
} }

View file

@ -37,22 +37,27 @@ void export_layer()
.def(vector_indexing_suite<std::vector<std::string>,true >()) .def(vector_indexing_suite<std::vector<std::string>,true >())
; ;
class_<Layer>("Layer","A map layer.", init<std::string const&>()) class_<Layer>("Layer", "A map layer.", init<std::string const&,optional<std::string const&> >())
.add_property("name", .add_property("name",
make_function(&Layer::name, return_value_policy<reference_existing_object>()), make_function(&Layer::name, return_value_policy<copy_const_reference>()),
&Layer::set_name, &Layer::set_name,
"Get/Set the name of the layer.") "Get/Set the name of the layer.")
.add_property("title", .add_property("title",
make_function(&Layer::title, return_value_policy<reference_existing_object>()), make_function(&Layer::title, return_value_policy<copy_const_reference>()),
&Layer::set_title, &Layer::set_title,
"Get/Set the title of the layer.") "Get/Set the title of the layer.")
.add_property("abstract", .add_property("abstract",
make_function(&Layer::abstract,return_value_policy<reference_existing_object>()), make_function(&Layer::abstract,return_value_policy<copy_const_reference>()),
&Layer::set_abstract, &Layer::set_abstract,
"Get/Set the abstract of the layer.") "Get/Set the abstract of the layer.")
.add_property("src",
make_function(&Layer::srs,return_value_policy<copy_const_reference>()),
&Layer::set_srs,
"Get/Set the SRS of the layer.")
.add_property("minzoom", .add_property("minzoom",
&Layer::getMinZoom, &Layer::getMinZoom,
&Layer::setMinZoom) &Layer::setMinZoom)

View file

@ -38,7 +38,7 @@ void export_line_symbolizer()
.def(init<Color const& ,float>()) .def(init<Color const& ,float>())
.add_property("stroke",make_function .add_property("stroke",make_function
(&line_symbolizer::get_stroke, (&line_symbolizer::get_stroke,
return_value_policy<reference_existing_object>()), return_value_policy<copy_const_reference>()),
&line_symbolizer::set_stroke) &line_symbolizer::set_stroke)
; ;
} }

View file

@ -40,7 +40,7 @@ struct map_pickle_suite : boost::python::pickle_suite
static boost::python::tuple static boost::python::tuple
getinitargs(const Map& m) getinitargs(const Map& m)
{ {
return boost::python::make_tuple(m.getWidth(),m.getHeight(),m.srid()); return boost::python::make_tuple(m.getWidth(),m.getHeight(),m.srs());
} }
static boost::python::tuple static boost::python::tuple
@ -85,10 +85,11 @@ void export_map()
.def(vector_indexing_suite<std::vector<Layer> >()) .def(vector_indexing_suite<std::vector<Layer> >())
; ;
class_<Map>("Map","The map object.",init<int,int,boost::python::optional<int> >()) class_<Map>("Map","The map object.",init<int,int,optional<std::string const&> >())
.add_property("width",&Map::getWidth,"The width of the map image.") .add_property("width",&Map::getWidth,"The width of the map image.")
.add_property("height",&Map::getHeight,"The height of the map image.") .add_property("height",&Map::getHeight,"The height of the map image.")
.add_property("srid",&Map::srid) .add_property("srs",make_function(&Map::srs,return_value_policy<copy_const_reference>()),
&Map::set_srs,"Spatial reference in proj4 format e.g. \"+proj=latlong +datum=WGS84\"")
.add_property("background",make_function .add_property("background",make_function
(&Map::getBackground,return_value_policy<copy_const_reference>()), (&Map::getBackground,return_value_policy<copy_const_reference>()),
&Map::setBackground, "The background color of the map.") &Map::setBackground, "The background color of the map.")
@ -102,6 +103,7 @@ void export_map()
.def("zoom_to_box",&Map::zoomToBox, "Set the geographical extent of the map.") .def("zoom_to_box",&Map::zoomToBox, "Set the geographical extent of the map.")
.def("pan",&Map::pan) .def("pan",&Map::pan)
.def("zoom",&Map::zoom) .def("zoom",&Map::zoom)
.def("zoom_all",&Map::zoom_all)
.def("pan_and_zoom",&Map::pan_and_zoom) .def("pan_and_zoom",&Map::pan_and_zoom)
.def("append_style",&Map::insert_style) .def("append_style",&Map::insert_style)
.def("remove_style",&Map::remove_style) .def("remove_style",&Map::remove_style)

View file

@ -35,7 +35,7 @@ void export_polygon_symbolizer()
.def(init<Color const&>("TODO")) .def(init<Color const&>("TODO"))
.add_property("fill",make_function .add_property("fill",make_function
(&polygon_symbolizer::get_fill, (&polygon_symbolizer::get_fill,
return_value_policy<reference_existing_object>()), return_value_policy<copy_const_reference>()),
&polygon_symbolizer::set_fill) &polygon_symbolizer::set_fill)
.add_property("fill_opacity", .add_property("fill_opacity",
&polygon_symbolizer::get_opacity, &polygon_symbolizer::get_opacity,

View file

@ -0,0 +1,64 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//$Id$
#include <boost/python.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/projection.hpp>
namespace {
mapnik::coord2d forward(mapnik::coord2d const& pt,
mapnik::projection const& prj)
{
double x = pt.x;
double y = pt.y;
prj.forward(x,y);
return mapnik::coord2d(x,y);
}
mapnik::coord2d inverse(mapnik::coord2d const& pt,
mapnik::projection const& prj)
{
double x = pt.x;
double y = pt.y;
prj.inverse(x,y);
return mapnik::coord2d(x,y);
}
}
void export_projection ()
{
using namespace boost::python;
using mapnik::projection;
class_<projection>("Projection", init<optional<std::string const&> >())
.def ("forward",&projection::forward)
.def ("inverse",&projection::inverse)
.def ("params", make_function(&projection::params,
return_value_policy<copy_const_reference>()))
;
def("forward",&forward);
def("inverse",&inverse);
}

View file

@ -26,6 +26,7 @@
#include <boost/python/detail/api_placeholder.hpp> #include <boost/python/detail/api_placeholder.hpp>
void export_color(); void export_color();
void export_coord();
void export_layer(); void export_layer();
void export_parameters(); void export_parameters();
void export_envelope(); void export_envelope();
@ -37,6 +38,7 @@ void export_filter();
void export_rule(); void export_rule();
void export_style(); void export_style();
void export_stroke(); void export_stroke();
void export_datasource();
void export_datasource_cache(); void export_datasource_cache();
void export_point_symbolizer(); void export_point_symbolizer();
void export_line_symbolizer(); void export_line_symbolizer();
@ -46,6 +48,7 @@ void export_polygon_pattern_symbolizer();
void export_raster_symbolizer(); void export_raster_symbolizer();
void export_text_symbolizer(); void export_text_symbolizer();
void export_font_engine(); void export_font_engine();
void export_projection();
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
#include <mapnik/agg_renderer.hpp> #include <mapnik/agg_renderer.hpp>
@ -70,28 +73,6 @@ void render(const mapnik::Map& map,mapnik::Image32& image)
ren.apply(); ren.apply();
} }
namespace
{
//user-friendly wrapper that uses Python dictionary
using namespace boost::python;
boost::shared_ptr<mapnik::datasource> create_datasource(const dict& d)
{
mapnik::parameters params;
boost::python::list keys=d.keys();
for (int i=0; i<len(keys); ++i)
{
std::string key = extract<std::string>(keys[i]);
object obj = d[key];
extract<std::string> ex(obj);
if (ex.check())
{
params[key] = ex();
}
}
return mapnik::datasource_cache::create(params);
}
}
BOOST_PYTHON_MODULE(_mapnik) BOOST_PYTHON_MODULE(_mapnik)
{ {
@ -109,18 +90,7 @@ BOOST_PYTHON_MODULE(_mapnik)
class_<Featureset,featureset_ptr,boost::noncopyable>("FeatureSet",no_init) class_<Featureset,featureset_ptr,boost::noncopyable>("FeatureSet",no_init)
; ;
class_<datasource,boost::shared_ptr<datasource>, export_datasource();
boost::noncopyable>("Datasource",no_init)
.def("envelope",&datasource::envelope,
return_value_policy<reference_existing_object>())
.def("features",&datasource::features)
.def("params",&datasource::params,return_value_policy<reference_existing_object>(),
"The configuration parameters of the data source. "
"These vary depending on the type of data source.")
;
def("CreateDatasource",&create_datasource);
export_parameters(); export_parameters();
export_color(); export_color();
export_envelope(); export_envelope();
@ -139,12 +109,8 @@ BOOST_PYTHON_MODULE(_mapnik)
export_raster_symbolizer(); export_raster_symbolizer();
export_text_symbolizer(); export_text_symbolizer();
export_font_engine(); export_font_engine();
export_projection();
class_<coord<double,2> >("Coord",init<double,double>()) export_coord();
.def_readwrite("x", &coord<double,2>::x)
.def_readwrite("y", &coord<double,2>::y)
;
export_map(); export_map();
def("render_to_file",&render_to_file); def("render_to_file",&render_to_file);

View file

@ -45,7 +45,7 @@ void export_stroke ()
class_<stroke>("Stroke",init<>()) class_<stroke>("Stroke",init<>())
.def(init<Color,float>()) .def(init<Color,float>())
.add_property("color",make_function .add_property("color",make_function
(&stroke::get_color,return_value_policy<reference_existing_object>()), (&stroke::get_color,return_value_policy<copy_const_reference>()),
&stroke::set_color) &stroke::set_color)
.add_property("width",&stroke::get_width,&stroke::set_width) .add_property("width",&stroke::get_width,&stroke::set_width)
.add_property("opacity",&stroke::get_opacity,&stroke::set_opacity) .add_property("opacity",&stroke::get_opacity,&stroke::set_opacity)

View file

@ -30,7 +30,7 @@ installed successfully before running this script.\n\n'
# Instanciate a map, giving it a width and height. Remember: the word "map" is # Instanciate a map, giving it a width and height. Remember: the word "map" is
# reserved in Python! :) # reserved in Python! :)
m = Map(800,600) m = Map(800,600,"+proj=latlong")
# Set its background colour. More on colours later ... # Set its background colour. More on colours later ...

View file

@ -45,13 +45,27 @@ namespace mapnik {
void end_map_processing(Map const& map); void end_map_processing(Map const& map);
void start_layer_processing(Layer const& lay); void start_layer_processing(Layer const& lay);
void end_layer_processing(Layer const& lay); void end_layer_processing(Layer const& lay);
void process(point_symbolizer const& sym,Feature const& feature); void process(point_symbolizer const& sym,
void process(line_symbolizer const& sym,Feature const& feature); Feature const& feature,
void process(line_pattern_symbolizer const& sym,Feature const& feature); proj_transform const& prj_trans);
void process(polygon_symbolizer const& sym,Feature const& feature); void process(line_symbolizer const& sym,
void process(polygon_pattern_symbolizer const& sym,Feature const& feature); Feature const& feature,
void process(raster_symbolizer const& sym,Feature const& feature); proj_transform const& prj_trans);
void process(text_symbolizer const& sym,Feature const& feature); void process(line_pattern_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
void process(polygon_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
void process(polygon_pattern_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
void process(raster_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
void process(text_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
private: private:
T & pixmap_; T & pixmap_;
CoordTransform t_; CoordTransform t_;

View file

@ -27,6 +27,7 @@
#include <mapnik/envelope.hpp> #include <mapnik/envelope.hpp>
#include <mapnik/coord_array.hpp> #include <mapnik/coord_array.hpp>
#include <mapnik/projection.hpp>
namespace mapnik { namespace mapnik {
typedef coord_array<coord2d> CoordinateArray; typedef coord_array<coord2d> CoordinateArray;
@ -53,7 +54,38 @@ namespace mapnik {
Transform const& t_; Transform const& t_;
Geometry& geom_; Geometry& geom_;
}; };
template <typename Transform,typename Geometry>
struct MAPNIK_DECL coord_transform2
{
coord_transform2(Transform const& t,
Geometry& geom,
proj_transform const& prj_trans)
: t_(t),
geom_(geom),
prj_trans_(prj_trans) {}
unsigned vertex(double * x , double * y) const
{
unsigned command = geom_.vertex(x,y);
double z=0;
prj_trans_.backward(*x,*y,z);
t_.forward(x,y);
return command;
}
void rewind (unsigned pos)
{
geom_.rewind(pos);
}
private:
Transform const& t_;
Geometry& geom_;
proj_transform const& prj_trans_;
};
class CoordTransform class CoordTransform
{ {
private: private:

View file

@ -36,6 +36,7 @@
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
#include <mapnik/attribute_collector.hpp> #include <mapnik/attribute_collector.hpp>
#include <mapnik/utils.hpp> #include <mapnik/utils.hpp>
#include <mapnik/projection.hpp>
namespace mapnik namespace mapnik
{ {
@ -44,17 +45,22 @@ namespace mapnik
{ {
struct symbol_dispatch : public boost::static_visitor<> struct symbol_dispatch : public boost::static_visitor<>
{ {
symbol_dispatch (Processor & output,Feature const& f) symbol_dispatch (Processor & output,
: output_(output),f_(f) {} Feature const& f,
proj_transform const& prj_trans)
: output_(output),
f_(f),
prj_trans_(prj_trans) {}
template <typename T> template <typename T>
void operator () (T const& sym) const void operator () (T const& sym) const
{ {
output_.process(sym,f_); output_.process(sym,f_,prj_trans_);
} }
Processor & output_; Processor & output_;
Feature const& f_; Feature const& f_;
proj_transform const& prj_trans_;
}; };
public: public:
feature_style_processor(Map const& m) feature_style_processor(Map const& m)
@ -63,52 +69,82 @@ namespace mapnik
void apply() void apply()
{ {
boost::progress_timer t; boost::progress_timer t;
Processor & p = static_cast<Processor&>(*this); Processor & p = static_cast<Processor&>(*this);
p.start_map_processing(m_); p.start_map_processing(m_);
std::vector<Layer>::const_iterator itr = m_.layers().begin(); std::vector<Layer>::const_iterator itr = m_.layers().begin();
std::vector<Layer>::const_iterator end = m_.layers().end(); std::vector<Layer>::const_iterator end = m_.layers().end();
while (itr != end)
{
if (itr->isVisible(m_.scale()) &&
itr->envelope().intersects(m_.getCurrentExtent()))
{
apply_to_layer(*itr,p);
}
++itr;
}
try
{
projection proj(m_.srs()); // map projection
while (itr != end)
{
if (itr->isVisible(m_.scale()))// &&
//itr->envelope().intersects(m_.getCurrentExtent())) TODO
{
apply_to_layer(*itr, p, proj);
}
++itr;
}
}
catch (proj_init_error& ex)
{
std::clog << ex.what() << "\n";
}
p.end_map_processing(m_); p.end_map_processing(m_);
} }
private: private:
void apply_to_layer(Layer const& lay,Processor & p) void apply_to_layer(Layer const& lay, Processor & p, projection const& proj0)
{ {
p.start_layer_processing(lay); p.start_layer_processing(lay);
boost::shared_ptr<datasource> ds=lay.datasource(); boost::shared_ptr<datasource> ds=lay.datasource();
if (ds) if (ds)
{ {
Envelope<double> const& bbox=m_.getCurrentExtent(); Envelope<double> const& ext=m_.getCurrentExtent();
projection proj1(lay.srs());
proj_transform prj_trans(proj0,proj1);
double x0 = ext.minx();
double y0 = ext.miny();
double z0 = 0.0;
double x1 = ext.maxx();
double y1 = ext.maxy();
double z1 = 0.0;
prj_trans.forward(x0,y0,z0);
prj_trans.forward(x1,y1,z1);
Envelope<double> bbox(x0,y0,x1,y1);
std::clog << bbox << "\n";
double scale = m_.scale(); double scale = m_.scale();
std::vector<std::string> const& style_names = lay.styles(); std::vector<std::string> const& style_names = lay.styles();
std::vector<std::string>::const_iterator stylesIter = style_names.begin(); std::vector<std::string>::const_iterator stylesIter = style_names.begin();
while (stylesIter != style_names.end()) std::vector<std::string>::const_iterator stylesEnd = style_names.end();
while (stylesIter != stylesEnd)
{ {
std::set<std::string> names; std::set<std::string> names;
attribute_collector<Feature> collector(names); attribute_collector<Feature> collector(names);
std::vector<rule_type*> if_rules; std::vector<rule_type*> if_rules;
std::vector<rule_type*> else_rules; std::vector<rule_type*> else_rules;
bool active_rules=false; bool active_rules=false;
feature_type_style const& style=m_.find_style(*stylesIter++); feature_type_style const& style=m_.find_style(*stylesIter++);
query q(bbox); //BBOX query
const std::vector<rule_type>& rules=style.get_rules(); const std::vector<rule_type>& rules=style.get_rules();
std::vector<rule_type>::const_iterator ruleIter=rules.begin(); std::vector<rule_type>::const_iterator ruleIter=rules.begin();
std::vector<rule_type>::const_iterator ruleEnd=rules.end();
query q(bbox); //BBOX query
while (ruleIter!=rules.end()) while (ruleIter!=ruleEnd)
{ {
if (ruleIter->active(scale)) if (ruleIter->active(scale))
{ {
@ -127,8 +163,10 @@ namespace mapnik
++ruleIter; ++ruleIter;
} }
std::set<std::string>::const_iterator namesIter=names.begin(); std::set<std::string>::const_iterator namesIter=names.begin();
std::set<std::string>::const_iterator namesEnd =names.end();
// push all property names // push all property names
while (namesIter!=names.end()) while (namesIter!=namesEnd)
{ {
q.add_property_name(*namesIter); q.add_property_name(*namesIter);
++namesIter; ++namesIter;
@ -143,7 +181,8 @@ namespace mapnik
{ {
bool do_else=true; bool do_else=true;
std::vector<rule_type*>::const_iterator itr=if_rules.begin(); std::vector<rule_type*>::const_iterator itr=if_rules.begin();
while (itr!=if_rules.end()) std::vector<rule_type*>::const_iterator end=if_rules.end();
while (itr != end)
{ {
filter_ptr const& filter=(*itr)->get_filter(); filter_ptr const& filter=(*itr)->get_filter();
if (filter->pass(*feature)) if (filter->pass(*feature))
@ -151,10 +190,11 @@ namespace mapnik
do_else=false; do_else=false;
const symbolizers& symbols = (*itr)->get_symbolizers(); const symbolizers& symbols = (*itr)->get_symbolizers();
symbolizers::const_iterator symIter=symbols.begin(); symbolizers::const_iterator symIter=symbols.begin();
while (symIter!=symbols.end()) symbolizers::const_iterator symEnd =symbols.end();
while (symIter != symEnd)
{ {
boost::apply_visitor boost::apply_visitor
(symbol_dispatch(p,*feature),*symIter++); (symbol_dispatch(p,*feature,prj_trans),*symIter++);
} }
} }
++itr; ++itr;
@ -164,14 +204,19 @@ namespace mapnik
//else filter //else filter
std::vector<rule_type*>::const_iterator itr= std::vector<rule_type*>::const_iterator itr=
else_rules.begin(); else_rules.begin();
while (itr != else_rules.end()) std::vector<rule_type*>::const_iterator end=
else_rules.end();
while (itr != end)
{ {
const symbolizers& symbols = (*itr)->get_symbolizers(); const symbolizers& symbols = (*itr)->get_symbolizers();
symbolizers::const_iterator symIter=symbols.begin(); symbolizers::const_iterator symIter= symbols.begin();
while (symIter!=symbols.end()) symbolizers::const_iterator symEnd = symbols.end();
while (symIter!=symEnd)
{ {
boost::apply_visitor boost::apply_visitor
(symbol_dispatch(p,*feature),*symIter++); (symbol_dispatch(p,*feature,prj_trans),
*symIter++);
} }
++itr; ++itr;
} }
@ -180,10 +225,10 @@ namespace mapnik
} }
} }
} }
} }
p.end_layer_processing(lay); p.end_layer_processing(lay);
} }
Map const& m_; Map const& m_;
}; };
} }

View file

@ -38,6 +38,8 @@ namespace mapnik
std::string name_; std::string name_;
std::string title_; std::string title_;
std::string abstract_; std::string abstract_;
std::string srs_;
double minZoom_; double minZoom_;
double maxZoom_; double maxZoom_;
bool active_; bool active_;
@ -49,7 +51,7 @@ namespace mapnik
mutable std::vector<boost::shared_ptr<Feature> > selection_; mutable std::vector<boost::shared_ptr<Feature> > selection_;
public: public:
explicit Layer(std::string const& name); explicit Layer(std::string const& name, std::string const& srs="+proj=latlong +datum=WGS84");
Layer(Layer const& l); Layer(Layer const& l);
Layer& operator=(Layer const& l); Layer& operator=(Layer const& l);
bool operator==(Layer const& other) const; bool operator==(Layer const& other) const;
@ -59,6 +61,8 @@ namespace mapnik
const std::string& title() const; const std::string& title() const;
void set_abstract(std::string const& abstract); void set_abstract(std::string const& abstract);
const std::string& abstract() const; const std::string& abstract() const;
void set_srs(std::string const& srs);
std::string const& srs() const;
void add_style(std::string const& stylename); void add_style(std::string const& stylename);
std::vector<std::string> const& styles() const; std::vector<std::string> const& styles() const;
void selection_style(const std::string& name); void selection_style(const std::string& name);

View file

@ -36,18 +36,17 @@ namespace mapnik
static const unsigned MAX_MAPSIZE=2048; static const unsigned MAX_MAPSIZE=2048;
unsigned width_; unsigned width_;
unsigned height_; unsigned height_;
int srid_; std::string srs_;
Color background_; Color background_;
std::map<std::string,feature_type_style> styles_; std::map<std::string,feature_type_style> styles_;
std::vector<Layer> layers_; std::vector<Layer> layers_;
Envelope<double> currentExtent_; Envelope<double> currentExtent_;
public: public:
typedef std::map<std::string,feature_type_style>::const_iterator style_iterator; typedef std::map<std::string,feature_type_style>::const_iterator style_iterator;
Map(); Map();
Map(int width,int height,int srid=-1); Map(int width, int height, std::string const& srs="+proj=latlong +datum=WGS84");
Map(const Map& rhs); Map(const Map& rhs);
Map& operator=(const Map& rhs); Map& operator=(const Map& rhs);
style_iterator begin_styles() const; style_iterator begin_styles() const;
@ -67,7 +66,8 @@ namespace mapnik
void setWidth(unsigned width); void setWidth(unsigned width);
void setHeight(unsigned height); void setHeight(unsigned height);
void resize(unsigned width,unsigned height); void resize(unsigned width,unsigned height);
int srid() const; std::string const& srs() const;
void set_srs(std::string const& srs);
void setBackground(const Color& c); void setBackground(const Color& c);
const Color& getBackground() const; const Color& getBackground() const;
void zoom(double zoom); void zoom(double zoom);

View file

@ -0,0 +1,174 @@
#ifndef PROJECTION_HPP
#define PROJECTION_HPP
#include <string>
#include <iostream>
#include <stdexcept>
#include <boost/utility.hpp>
#include <mapnik/envelope.hpp>
#include <proj_api.h>
namespace mapnik
{
class proj_init_error : public std::runtime_error
{
public:
proj_init_error(std::string const& params)
: std::runtime_error("failed to initialize projection with:" + params) {}
};
class projection
{
friend class proj_transform;
public:
explicit projection(std::string params = "+proj=latlong +ellps=WGS84")
: params_(params)
{
init(); //
}
projection(projection const& rhs)
: params_(rhs.params_)
{
init(); //
}
projection& operator=(projection const& rhs)
{
projection tmp(rhs);
swap(tmp);
return *this;
}
bool is_initialized() const
{
return proj_ ? true : false;
}
std::string const& params() const
{
return params_;
}
void forward(double & x, double &y ) const
{
projUV p;
p.u = x * DEG_TO_RAD;
p.v = y * DEG_TO_RAD;
p = pj_fwd(p,proj_);
x = p.u;
y = p.v;
}
void inverse(double & x,double & y) const
{
projUV p;
p.u = x;
p.v = y;
p = pj_inv(p,proj_);
x = RAD_TO_DEG * p.u;
y = RAD_TO_DEG * p.v;
}
~projection()
{
if (proj_) pj_free(proj_);
}
private:
void init()
{
proj_=pj_init_plus(params_.c_str());
if (!proj_) throw proj_init_error(params_);
}
void swap (projection& rhs)
{
std::swap(params_,rhs.params_);
init ();
}
private:
std::string params_;
projPJ proj_;
};
class proj_transform : private boost::noncopyable
{
public:
proj_transform(projection const& source,
projection const& dest)
: source_(source),
dest_(dest)
{
is_source_latlong_ = pj_is_latlong(source_.proj_);
is_dest_latlong_ = pj_is_latlong(dest_.proj_);
}
bool forward (double & x, double & y , double & z) const
{
if (is_source_latlong_)
{
x *= DEG_TO_RAD;
y *= DEG_TO_RAD;
}
if (pj_transform( source_.proj_, dest_.proj_, 1,
0, &x,&y,&z) != 0)
{
return false;
}
if (is_dest_latlong_)
{
x *= RAD_TO_DEG;
y *= RAD_TO_DEG;
}
return true;
}
bool forward (Envelope<double> & ext) const
{
if (is_source_latlong_)
{
ext = ext.intersect(Envelope<double>(-180,-90,180,90));
}
// TODO
return true;
}
bool backward (double & x, double & y , double & z) const
{
if (is_dest_latlong_)
{
x *= DEG_TO_RAD;
y *= DEG_TO_RAD;
}
if (pj_transform( dest_.proj_, source_.proj_, 1,
0, &x,&y,&z) != 0)
{
return false;
}
if (is_source_latlong_)
{
x *= RAD_TO_DEG;
y *= RAD_TO_DEG;
}
return true;
}
private:
projection const& source_;
projection const& dest_;
bool is_source_latlong_;
bool is_dest_latlong_;
};
}
#endif //PROJECTION_HPP

View file

@ -126,9 +126,11 @@ namespace mapnik
} }
template <typename T> template <typename T>
void agg_renderer<T>::process(polygon_symbolizer const& sym,Feature const& feature) void agg_renderer<T>::process(polygon_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans)
{ {
typedef coord_transform<CoordTransform,geometry_type> path_type; typedef coord_transform2<CoordTransform,geometry_type> path_type;
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base; typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer; typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
@ -139,7 +141,7 @@ namespace mapnik
{ {
unsigned width = pixmap_.width(); unsigned width = pixmap_.width();
unsigned height = pixmap_.height(); unsigned height = pixmap_.height();
path_type path(t_,*geom); path_type path(t_,*geom,prj_trans);
agg::row_ptr_cache<agg::int8u> buf(pixmap_.raw_data(),width,height,width * 4); agg::row_ptr_cache<agg::int8u> buf(pixmap_.raw_data(),width,height,width * 4);
agg::pixfmt_rgba32 pixf(buf); agg::pixfmt_rgba32 pixf(buf);
ren_base renb(pixf); ren_base renb(pixf);
@ -147,9 +149,8 @@ namespace mapnik
unsigned r=fill_.red(); unsigned r=fill_.red();
unsigned g=fill_.green(); unsigned g=fill_.green();
unsigned b=fill_.blue(); unsigned b=fill_.blue();
//unsigned a=fill_.alpha();
renderer ren(renb); renderer ren(renb);
agg::rasterizer_scanline_aa<> ras; agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl; agg::scanline_u8 sl;
ras.clip_box(0,0,width,height); ras.clip_box(0,0,width,height);
@ -160,10 +161,12 @@ namespace mapnik
} }
template <typename T> template <typename T>
void agg_renderer<T>::process(line_symbolizer const& sym,Feature const& feature) void agg_renderer<T>::process(line_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans)
{ {
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base; typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
typedef coord_transform<CoordTransform,geometry_type> path_type; typedef coord_transform2<CoordTransform,geometry_type> path_type;
typedef agg::renderer_outline_aa<ren_base> renderer_oaa; typedef agg::renderer_outline_aa<ren_base> renderer_oaa;
typedef agg::rasterizer_outline_aa<renderer_oaa> rasterizer_outline_aa; typedef agg::rasterizer_outline_aa<renderer_oaa> rasterizer_outline_aa;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer; typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
@ -171,7 +174,7 @@ namespace mapnik
geometry_ptr const& geom=feature.get_geometry(); geometry_ptr const& geom=feature.get_geometry();
if (geom && geom->num_points() > 1) if (geom && geom->num_points() > 1)
{ {
path_type path(t_,*geom); path_type path(t_,*geom,prj_trans);
agg::row_ptr_cache<agg::int8u> buf(pixmap_.raw_data(), agg::row_ptr_cache<agg::int8u> buf(pixmap_.raw_data(),
pixmap_.width(), pixmap_.width(),
pixmap_.height(), pixmap_.height(),
@ -277,17 +280,21 @@ namespace mapnik
} }
template <typename T> template <typename T>
void agg_renderer<T>::process(point_symbolizer const& sym,Feature const& feature) void agg_renderer<T>::process(point_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans)
{ {
geometry_ptr const& geom=feature.get_geometry(); geometry_ptr const& geom=feature.get_geometry();
if (geom) if (geom)
{ {
double x; double x;
double y; double y;
double z=0;
boost::shared_ptr<ImageData32> const& data = sym.get_data(); boost::shared_ptr<ImageData32> const& data = sym.get_data();
if ( data ) if ( data )
{ {
geom->label_position(&x,&y); geom->label_position(&x,&y);
prj_trans.backward(x,y,z);
t_.forward(&x,&y); t_.forward(&x,&y);
int w = data->width(); int w = data->width();
int h = data->height(); int h = data->height();
@ -307,9 +314,11 @@ namespace mapnik
} }
template <typename T> template <typename T>
void agg_renderer<T>::process(line_pattern_symbolizer const& sym,Feature const& feature) void agg_renderer<T>::process(line_pattern_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans)
{ {
typedef coord_transform<CoordTransform,geometry_type> path_type; typedef coord_transform2<CoordTransform,geometry_type> path_type;
typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type; typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type;
typedef agg::renderer_base<agg::pixfmt_rgba32> renderer_base; typedef agg::renderer_base<agg::pixfmt_rgba32> renderer_base;
typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type; typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type;
@ -321,7 +330,7 @@ namespace mapnik
unsigned width = pixmap_.width(); unsigned width = pixmap_.width();
unsigned height = pixmap_.height(); unsigned height = pixmap_.height();
ImageData32 const& pat = sym.get_pattern(); ImageData32 const& pat = sym.get_pattern();
path_type path(t_,*geom); path_type path(t_,*geom,prj_trans);
agg::row_ptr_cache<agg::int8u> buf(pixmap_.raw_data(), width, height,width*4); agg::row_ptr_cache<agg::int8u> buf(pixmap_.raw_data(), width, height,width*4);
agg::pixfmt_rgba32 pixf(buf); agg::pixfmt_rgba32 pixf(buf);
renderer_base ren_base(pixf); renderer_base ren_base(pixf);
@ -336,9 +345,11 @@ namespace mapnik
} }
template <typename T> template <typename T>
void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym,Feature const& feature) void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans)
{ {
typedef coord_transform<CoordTransform,geometry_type> path_type; typedef coord_transform2<CoordTransform,geometry_type> path_type;
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base; typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
typedef agg::wrap_mode_repeat wrap_x_type; typedef agg::wrap_mode_repeat wrap_x_type;
typedef agg::wrap_mode_repeat wrap_y_type; typedef agg::wrap_mode_repeat wrap_y_type;
@ -358,7 +369,7 @@ namespace mapnik
unsigned width = pixmap_.width(); unsigned width = pixmap_.width();
unsigned height = pixmap_.height(); unsigned height = pixmap_.height();
path_type path(t_,*geom); path_type path(t_,*geom,prj_trans);
agg::row_ptr_cache<agg::int8u> buf(pixmap_.raw_data(),width,height,width * 4); agg::row_ptr_cache<agg::int8u> buf(pixmap_.raw_data(),width,height,width * 4);
agg::pixfmt_rgba32 pixf(buf); agg::pixfmt_rgba32 pixf(buf);
@ -389,7 +400,9 @@ namespace mapnik
} }
template <typename T> template <typename T>
void agg_renderer<T>::process(raster_symbolizer const& ,Feature const& feature) void agg_renderer<T>::process(raster_symbolizer const&,
Feature const& feature,
proj_transform const& prj_trans)
{ {
// TODO -- at the moment raster_symbolizer is an empty class // TODO -- at the moment raster_symbolizer is an empty class
// used for type dispatching, but we can have some fancy raster // used for type dispatching, but we can have some fancy raster
@ -405,9 +418,11 @@ namespace mapnik
} }
template <typename T> template <typename T>
void agg_renderer<T>::process(text_symbolizer const& sym ,Feature const& feature) void agg_renderer<T>::process(text_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans)
{ {
typedef coord_transform<CoordTransform,geometry_type> path_type; typedef coord_transform2<CoordTransform,geometry_type> path_type;
geometry_ptr const& geom=feature.get_geometry(); geometry_ptr const& geom=feature.get_geometry();
if (geom) if (geom)
{ {
@ -416,7 +431,7 @@ namespace mapnik
geom->num_points() > 1) geom->num_points() > 1)
{ {
path_type path(t_,*geom); path_type path(t_,*geom,prj_trans);
double x0,y0,x1,y1; double x0,y0,x1,y1;
path.vertex(&x0,&y0); path.vertex(&x0,&y0);
path.vertex(&x1,&y1); path.vertex(&x1,&y1);

View file

@ -38,10 +38,11 @@ using boost::shared_ptr;
namespace mapnik namespace mapnik
{ {
Layer::Layer(std::string const& name) Layer::Layer(std::string const& name, std::string const& srs)
: name_(name), : name_(name),
title_(""), title_(""),
abstract_(""), abstract_(""),
srs_(srs),
minZoom_(0), minZoom_(0),
maxZoom_(std::numeric_limits<double>::max()), maxZoom_(std::numeric_limits<double>::max()),
active_(true), active_(true),
@ -53,6 +54,7 @@ namespace mapnik
: name_(rhs.name_), : name_(rhs.name_),
title_(rhs.title_), title_(rhs.title_),
abstract_(rhs.abstract_), abstract_(rhs.abstract_),
srs_(rhs.srs_),
minZoom_(rhs.minZoom_), minZoom_(rhs.minZoom_),
maxZoom_(rhs.maxZoom_), maxZoom_(rhs.maxZoom_),
active_(rhs.active_), active_(rhs.active_),
@ -119,11 +121,21 @@ namespace mapnik
return abstract_; return abstract_;
} }
void Layer::set_srs(std::string const& srs)
{
srs_ = srs;
}
std::string const& Layer::srs() const
{
return srs_;
}
void Layer::add_style(std::string const& stylename) void Layer::add_style(std::string const& stylename)
{ {
styles_.push_back(stylename); styles_.push_back(stylename);
} }
std::vector<std::string> const& Layer::styles() const std::vector<std::string> const& Layer::styles() const
{ {
return styles_; return styles_;

View file

@ -47,19 +47,24 @@ namespace mapnik
{ {
using boost::property_tree::ptree; using boost::property_tree::ptree;
ptree pt; ptree pt;
read_xml(filename,pt); read_xml(filename,pt);
boost::optional<std::string> bgcolor = boost::optional<std::string> bgcolor =
pt.get_optional<std::string>("Map.<xmlattr>.bgcolor"); pt.get_optional<std::string>("Map.<xmlattr>.bgcolor");
if ( bgcolor)
if (bgcolor)
{ {
Color bg = color_factory::from_string(bgcolor->c_str()); Color bg = color_factory::from_string(bgcolor->c_str());
map.setBackground(bg); map.setBackground(bg);
} }
std::string srs = pt.get<std::string>("Map.<xmlattr>.srs",
"+proj=latlong +datum=WGS84");
map.set_srs(srs);
ptree::const_iterator itr = pt.get_child("Map").begin(); ptree::const_iterator itr = pt.get_child("Map").begin();
ptree::const_iterator end = pt.get_child("Map").end(); ptree::const_iterator end = pt.get_child("Map").end();
for (; itr != end; ++itr) for (; itr != end; ++itr)
{ {
ptree::value_type const& v = *itr; ptree::value_type const& v = *itr;
@ -284,18 +289,19 @@ namespace mapnik
else if (v.first == "Layer") else if (v.first == "Layer")
{ {
std::string name = v.second.get<std::string>("<xmlattr>.name",""); std::string name = v.second.get<std::string>("<xmlattr>.name","Unnamed");
Layer lyr(name); std::string srs = v.second.get<std::string>("<xmlattr>.srs","+proj=latlong +datum=WGS84");
Layer lyr(name, srs);
boost::optional<std::string> status = boost::optional<std::string> status =
v.second.get<std::string>("<xmlattr>.status"); v.second.get_optional<std::string>("<xmlattr>.status");
if (status && *status == "off") if (status && *status == "off")
{ {
lyr.setActive(false); lyr.setActive(false);
} }
ptree::const_iterator itr2 = v.second.begin(); ptree::const_iterator itr2 = v.second.begin();
ptree::const_iterator end2 = v.second.end(); ptree::const_iterator end2 = v.second.end();

View file

@ -24,6 +24,7 @@
#include <mapnik/style.hpp> #include <mapnik/style.hpp>
#include <mapnik/datasource.hpp> #include <mapnik/datasource.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/layer.hpp> #include <mapnik/layer.hpp>
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
@ -32,17 +33,18 @@ namespace mapnik
Map::Map() Map::Map()
: width_(400), : width_(400),
height_(400), height_(400),
srid_(-1) {} srs_("+proj=latlong +datum=WGS84") {}
Map::Map(int width,int height,int srid)
Map::Map(int width,int height, std::string const& srs)
: width_(width), : width_(width),
height_(height), height_(height),
srid_(srid), srs_(srs),
background_(Color(255,255,255)) {} background_(Color(255,255,255)) {}
Map::Map(const Map& rhs) Map::Map(const Map& rhs)
: width_(rhs.width_), : width_(rhs.width_),
height_(rhs.height_), height_(rhs.height_),
srid_(rhs.srid_), srs_(rhs.srs_),
background_(rhs.background_), background_(rhs.background_),
styles_(rhs.styles_), styles_(rhs.styles_),
layers_(rhs.layers_), layers_(rhs.layers_),
@ -53,12 +55,13 @@ namespace mapnik
if (this==&rhs) return *this; if (this==&rhs) return *this;
width_=rhs.width_; width_=rhs.width_;
height_=rhs.height_; height_=rhs.height_;
srid_=rhs.srid_; srs_=rhs.srs_;
background_=rhs.background_; background_=rhs.background_;
styles_=rhs.styles_; styles_=rhs.styles_;
layers_=rhs.layers_; layers_=rhs.layers_;
return *this; return *this;
} }
Map::style_iterator Map::begin_styles() const Map::style_iterator Map::begin_styles() const
{ {
return styles_.begin(); return styles_.begin();
@ -78,10 +81,9 @@ namespace mapnik
styles_.erase(name); styles_.erase(name);
} }
feature_type_style const& Map::find_style(std::string const& name) const feature_type_style const& Map::find_style(std::string const& name) const
{ {
std::map<std::string,feature_type_style>::const_iterator itr std::map<std::string,feature_type_style>::const_iterator itr = styles_.find(name);
= styles_.find(name);
if (itr!=styles_.end()) if (itr!=styles_.end())
return itr->second; return itr->second;
static feature_type_style default_style; static feature_type_style default_style;
@ -118,7 +120,6 @@ namespace mapnik
return layers_[index]; return layers_[index];
} }
std::vector<Layer> const& Map::layers() const std::vector<Layer> const& Map::layers() const
{ {
return layers_; return layers_;
@ -151,6 +152,7 @@ namespace mapnik
fixAspectRatio(); fixAspectRatio();
} }
} }
void Map::resize(unsigned width,unsigned height) void Map::resize(unsigned width,unsigned height)
{ {
if (width >= MIN_MAPSIZE && width <= MAX_MAPSIZE && if (width >= MIN_MAPSIZE && width <= MAX_MAPSIZE &&
@ -162,11 +164,16 @@ namespace mapnik
} }
} }
int Map::srid() const std::string const& Map::srs() const
{ {
return srid_; return srs_;
} }
void Map::set_srs(std::string const& srs)
{
srs_ = srs;
}
void Map::setBackground(const Color& c) void Map::setBackground(const Color& c)
{ {
background_=c; background_=c;
@ -176,7 +183,7 @@ namespace mapnik
{ {
return background_; return background_;
} }
void Map::zoom(double factor) void Map::zoom(double factor)
{ {
coord2d center = currentExtent_.center(); coord2d center = currentExtent_.center();
@ -191,23 +198,50 @@ namespace mapnik
void Map::zoom_all() void Map::zoom_all()
{ {
std::vector<Layer>::const_iterator itr = layers_.begin(); try
Envelope<double> ext;
bool first = true;
while (itr != layers_.end())
{ {
if (first) projection proj0(srs_);
Envelope<double> ext;
bool first = true;
std::vector<Layer>::const_iterator itr = layers_.begin();
std::vector<Layer>::const_iterator end = layers_.end();
while (itr != end)
{ {
ext = itr->envelope(); std::string const& layer_srs = itr->srs();
first = false; projection proj1(layer_srs);
proj_transform prj_trans(proj0,proj1);
Envelope<double> layerExt = itr->envelope();
double x0 = layerExt.minx();
double y0 = layerExt.miny();
double z0 = 0.0;
double x1 = layerExt.maxx();
double y1 = layerExt.maxy();
double z1 = 0.0;
prj_trans.backward(x0,y0,z0);
prj_trans.backward(x1,y1,z1);
Envelope<double> layerExt2(x0,y0,x1,y1);
std::clog << " layer1 - > " << layerExt << "\n";
std::clog << " layer2 - > " << layerExt2 << "\n";
if (first)
{
ext = layerExt2;
first = false;
}
else
{
ext.expand_to_include(layerExt2);
}
++itr;
} }
else zoomToBox(ext);
{ }
ext.expand_to_include(itr->envelope()); catch (proj_init_error & ex)
} {
++itr; std::clog << ex.what() << '\n';
} }
zoomToBox(ext);
} }
void Map::zoomToBox(const Envelope<double> &box) void Map::zoomToBox(const Envelope<double> &box)