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:
parent
52033ad4e8
commit
bb235fa316
24 changed files with 670 additions and 167 deletions
22
SConstruct
22
SConstruct
|
@ -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(ListOption('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster']))
|
||||
opts.Add(ListOption('BINDINGS','Language bindings to build','all',['python']))
|
||||
|
||||
opts.Add('DEBUG', 'Compile a debug version of mapnik', '')
|
||||
|
||||
env = Environment(ENV=os.environ, options=opts)
|
||||
|
@ -59,12 +58,22 @@ conf = Configure(env)
|
|||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
env.ParseConfig(env['FREETYPE_CONFIG'] + ' --libs --cflags')
|
||||
|
@ -76,8 +85,8 @@ C_LIBSHEADERS = [
|
|||
['tiff', 'tiff.h', True],
|
||||
['z', 'zlib.h', True],
|
||||
['jpeg', ['stdio.h', 'jpeglib.h'], True],
|
||||
['pq', 'libpq-fe.h', False],
|
||||
['proj', 'proj_api.h', False]
|
||||
['proj', 'proj_api.h', True],
|
||||
['pq', 'libpq-fe.h', False]
|
||||
]
|
||||
|
||||
BOOST_LIBSHEADERS = [
|
||||
|
@ -130,9 +139,6 @@ if 'python' in env['BINDINGS']:
|
|||
|
||||
SConscript('bindings/python/SConscript')
|
||||
|
||||
if 'proj' in env['LIBS']:
|
||||
SConscript('bindings/python/pyprojection/SConscript')
|
||||
env['LIBS'].remove('proj')
|
||||
|
||||
env = conf.Finish()
|
||||
|
||||
|
|
|
@ -21,4 +21,4 @@ import glob
|
|||
|
||||
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')
|
||||
|
|
|
@ -59,6 +59,12 @@ class _Envelope(Envelope,_injector):
|
|||
return 'Envelope(%s,%s,%s,%s)' % \
|
||||
(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):
|
||||
return CreateDatasource(keywords)
|
||||
|
||||
|
|
45
bindings/python/mapnik_coord.cpp
Normal file
45
bindings/python/mapnik_coord.cpp
Normal 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__
|
||||
;
|
||||
|
||||
}
|
68
bindings/python/mapnik_datasource.cpp
Normal file
68
bindings/python/mapnik_datasource.cpp
Normal 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);
|
||||
}
|
|
@ -85,7 +85,12 @@ void export_envelope()
|
|||
.def("intersects",intersects_p1)
|
||||
.def("intersects",intersects_p2)
|
||||
.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())
|
||||
;
|
||||
}
|
||||
|
|
|
@ -37,22 +37,27 @@ void export_layer()
|
|||
.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",
|
||||
make_function(&Layer::name, return_value_policy<reference_existing_object>()),
|
||||
make_function(&Layer::name, return_value_policy<copy_const_reference>()),
|
||||
&Layer::set_name,
|
||||
"Get/Set the name of the layer.")
|
||||
|
||||
.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,
|
||||
"Get/Set the title of the layer.")
|
||||
|
||||
.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,
|
||||
"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",
|
||||
&Layer::getMinZoom,
|
||||
&Layer::setMinZoom)
|
||||
|
|
|
@ -38,7 +38,7 @@ void export_line_symbolizer()
|
|||
.def(init<Color const& ,float>())
|
||||
.add_property("stroke",make_function
|
||||
(&line_symbolizer::get_stroke,
|
||||
return_value_policy<reference_existing_object>()),
|
||||
return_value_policy<copy_const_reference>()),
|
||||
&line_symbolizer::set_stroke)
|
||||
;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ struct map_pickle_suite : boost::python::pickle_suite
|
|||
static boost::python::tuple
|
||||
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
|
||||
|
@ -85,10 +85,11 @@ void export_map()
|
|||
.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("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
|
||||
(&Map::getBackground,return_value_policy<copy_const_reference>()),
|
||||
&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("pan",&Map::pan)
|
||||
.def("zoom",&Map::zoom)
|
||||
.def("zoom_all",&Map::zoom_all)
|
||||
.def("pan_and_zoom",&Map::pan_and_zoom)
|
||||
.def("append_style",&Map::insert_style)
|
||||
.def("remove_style",&Map::remove_style)
|
||||
|
|
|
@ -35,7 +35,7 @@ void export_polygon_symbolizer()
|
|||
.def(init<Color const&>("TODO"))
|
||||
.add_property("fill",make_function
|
||||
(&polygon_symbolizer::get_fill,
|
||||
return_value_policy<reference_existing_object>()),
|
||||
return_value_policy<copy_const_reference>()),
|
||||
&polygon_symbolizer::set_fill)
|
||||
.add_property("fill_opacity",
|
||||
&polygon_symbolizer::get_opacity,
|
||||
|
|
64
bindings/python/mapnik_projection.cpp
Normal file
64
bindings/python/mapnik_projection.cpp
Normal 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);
|
||||
|
||||
}
|
|
@ -26,6 +26,7 @@
|
|||
#include <boost/python/detail/api_placeholder.hpp>
|
||||
|
||||
void export_color();
|
||||
void export_coord();
|
||||
void export_layer();
|
||||
void export_parameters();
|
||||
void export_envelope();
|
||||
|
@ -37,6 +38,7 @@ void export_filter();
|
|||
void export_rule();
|
||||
void export_style();
|
||||
void export_stroke();
|
||||
void export_datasource();
|
||||
void export_datasource_cache();
|
||||
void export_point_symbolizer();
|
||||
void export_line_symbolizer();
|
||||
|
@ -46,6 +48,7 @@ void export_polygon_pattern_symbolizer();
|
|||
void export_raster_symbolizer();
|
||||
void export_text_symbolizer();
|
||||
void export_font_engine();
|
||||
void export_projection();
|
||||
|
||||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
|
@ -70,28 +73,6 @@ void render(const mapnik::Map& map,mapnik::Image32& image)
|
|||
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)
|
||||
{
|
||||
|
@ -109,18 +90,7 @@ BOOST_PYTHON_MODULE(_mapnik)
|
|||
class_<Featureset,featureset_ptr,boost::noncopyable>("FeatureSet",no_init)
|
||||
;
|
||||
|
||||
class_<datasource,boost::shared_ptr<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_datasource();
|
||||
export_parameters();
|
||||
export_color();
|
||||
export_envelope();
|
||||
|
@ -139,12 +109,8 @@ BOOST_PYTHON_MODULE(_mapnik)
|
|||
export_raster_symbolizer();
|
||||
export_text_symbolizer();
|
||||
export_font_engine();
|
||||
|
||||
class_<coord<double,2> >("Coord",init<double,double>())
|
||||
.def_readwrite("x", &coord<double,2>::x)
|
||||
.def_readwrite("y", &coord<double,2>::y)
|
||||
;
|
||||
|
||||
export_projection();
|
||||
export_coord();
|
||||
export_map();
|
||||
|
||||
def("render_to_file",&render_to_file);
|
||||
|
|
|
@ -45,7 +45,7 @@ void export_stroke ()
|
|||
class_<stroke>("Stroke",init<>())
|
||||
.def(init<Color,float>())
|
||||
.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)
|
||||
.add_property("width",&stroke::get_width,&stroke::set_width)
|
||||
.add_property("opacity",&stroke::get_opacity,&stroke::set_opacity)
|
||||
|
|
|
@ -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
|
||||
# reserved in Python! :)
|
||||
|
||||
m = Map(800,600)
|
||||
m = Map(800,600,"+proj=latlong")
|
||||
|
||||
# Set its background colour. More on colours later ...
|
||||
|
||||
|
|
|
@ -45,13 +45,27 @@ namespace mapnik {
|
|||
void end_map_processing(Map const& map);
|
||||
void start_layer_processing(Layer const& lay);
|
||||
void end_layer_processing(Layer const& lay);
|
||||
void process(point_symbolizer const& sym,Feature const& feature);
|
||||
void process(line_symbolizer const& sym,Feature const& feature);
|
||||
void process(line_pattern_symbolizer const& sym,Feature const& feature);
|
||||
void process(polygon_symbolizer const& sym,Feature const& feature);
|
||||
void process(polygon_pattern_symbolizer const& sym,Feature const& feature);
|
||||
void process(raster_symbolizer const& sym,Feature const& feature);
|
||||
void process(text_symbolizer const& sym,Feature const& feature);
|
||||
void process(point_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans);
|
||||
void process(line_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans);
|
||||
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:
|
||||
T & pixmap_;
|
||||
CoordTransform t_;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <mapnik/envelope.hpp>
|
||||
#include <mapnik/coord_array.hpp>
|
||||
#include <mapnik/projection.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
typedef coord_array<coord2d> CoordinateArray;
|
||||
|
@ -54,6 +55,37 @@ namespace mapnik {
|
|||
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
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/attribute_collector.hpp>
|
||||
#include <mapnik/utils.hpp>
|
||||
#include <mapnik/projection.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
@ -44,17 +45,22 @@ namespace mapnik
|
|||
{
|
||||
struct symbol_dispatch : public boost::static_visitor<>
|
||||
{
|
||||
symbol_dispatch (Processor & output,Feature const& f)
|
||||
: output_(output),f_(f) {}
|
||||
symbol_dispatch (Processor & output,
|
||||
Feature const& f,
|
||||
proj_transform const& prj_trans)
|
||||
: output_(output),
|
||||
f_(f),
|
||||
prj_trans_(prj_trans) {}
|
||||
|
||||
template <typename T>
|
||||
void operator () (T const& sym) const
|
||||
{
|
||||
output_.process(sym,f_);
|
||||
output_.process(sym,f_,prj_trans_);
|
||||
}
|
||||
|
||||
Processor & output_;
|
||||
Feature const& f_;
|
||||
proj_transform const& prj_trans_;
|
||||
};
|
||||
public:
|
||||
feature_style_processor(Map const& m)
|
||||
|
@ -63,37 +69,65 @@ namespace mapnik
|
|||
void apply()
|
||||
{
|
||||
boost::progress_timer t;
|
||||
|
||||
Processor & p = static_cast<Processor&>(*this);
|
||||
|
||||
p.start_map_processing(m_);
|
||||
|
||||
std::vector<Layer>::const_iterator itr = m_.layers().begin();
|
||||
std::vector<Layer>::const_iterator end = m_.layers().end();
|
||||
|
||||
try
|
||||
{
|
||||
projection proj(m_.srs()); // map projection
|
||||
|
||||
while (itr != end)
|
||||
{
|
||||
if (itr->isVisible(m_.scale()) &&
|
||||
itr->envelope().intersects(m_.getCurrentExtent()))
|
||||
if (itr->isVisible(m_.scale()))// &&
|
||||
//itr->envelope().intersects(m_.getCurrentExtent())) TODO
|
||||
{
|
||||
apply_to_layer(*itr,p);
|
||||
apply_to_layer(*itr, p, proj);
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
catch (proj_init_error& ex)
|
||||
{
|
||||
std::clog << ex.what() << "\n";
|
||||
}
|
||||
|
||||
p.end_map_processing(m_);
|
||||
}
|
||||
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);
|
||||
boost::shared_ptr<datasource> ds=lay.datasource();
|
||||
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();
|
||||
|
||||
std::vector<std::string> const& style_names = lay.styles();
|
||||
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;
|
||||
attribute_collector<Feature> collector(names);
|
||||
|
@ -104,11 +138,13 @@ namespace mapnik
|
|||
|
||||
feature_type_style const& style=m_.find_style(*stylesIter++);
|
||||
|
||||
query q(bbox); //BBOX query
|
||||
|
||||
const std::vector<rule_type>& rules=style.get_rules();
|
||||
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))
|
||||
{
|
||||
|
@ -127,8 +163,10 @@ namespace mapnik
|
|||
++ruleIter;
|
||||
}
|
||||
std::set<std::string>::const_iterator namesIter=names.begin();
|
||||
std::set<std::string>::const_iterator namesEnd =names.end();
|
||||
|
||||
// push all property names
|
||||
while (namesIter!=names.end())
|
||||
while (namesIter!=namesEnd)
|
||||
{
|
||||
q.add_property_name(*namesIter);
|
||||
++namesIter;
|
||||
|
@ -143,7 +181,8 @@ namespace mapnik
|
|||
{
|
||||
bool do_else=true;
|
||||
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();
|
||||
if (filter->pass(*feature))
|
||||
|
@ -151,10 +190,11 @@ namespace mapnik
|
|||
do_else=false;
|
||||
const symbolizers& symbols = (*itr)->get_symbolizers();
|
||||
symbolizers::const_iterator symIter=symbols.begin();
|
||||
while (symIter!=symbols.end())
|
||||
symbolizers::const_iterator symEnd =symbols.end();
|
||||
while (symIter != symEnd)
|
||||
{
|
||||
boost::apply_visitor
|
||||
(symbol_dispatch(p,*feature),*symIter++);
|
||||
(symbol_dispatch(p,*feature,prj_trans),*symIter++);
|
||||
}
|
||||
}
|
||||
++itr;
|
||||
|
@ -164,14 +204,19 @@ namespace mapnik
|
|||
//else filter
|
||||
std::vector<rule_type*>::const_iterator itr=
|
||||
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();
|
||||
symbolizers::const_iterator symIter= symbols.begin();
|
||||
while (symIter!=symbols.end())
|
||||
symbolizers::const_iterator symEnd = symbols.end();
|
||||
|
||||
while (symIter!=symEnd)
|
||||
{
|
||||
boost::apply_visitor
|
||||
(symbol_dispatch(p,*feature),*symIter++);
|
||||
(symbol_dispatch(p,*feature,prj_trans),
|
||||
*symIter++);
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
|
@ -180,10 +225,10 @@ namespace mapnik
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
p.end_layer_processing(lay);
|
||||
}
|
||||
|
||||
Map const& m_;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@ namespace mapnik
|
|||
std::string name_;
|
||||
std::string title_;
|
||||
std::string abstract_;
|
||||
std::string srs_;
|
||||
|
||||
double minZoom_;
|
||||
double maxZoom_;
|
||||
bool active_;
|
||||
|
@ -49,7 +51,7 @@ namespace mapnik
|
|||
mutable std::vector<boost::shared_ptr<Feature> > selection_;
|
||||
|
||||
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& operator=(Layer const& l);
|
||||
bool operator==(Layer const& other) const;
|
||||
|
@ -59,6 +61,8 @@ namespace mapnik
|
|||
const std::string& title() const;
|
||||
void set_abstract(std::string const& abstract);
|
||||
const std::string& abstract() const;
|
||||
void set_srs(std::string const& srs);
|
||||
std::string const& srs() const;
|
||||
void add_style(std::string const& stylename);
|
||||
std::vector<std::string> const& styles() const;
|
||||
void selection_style(const std::string& name);
|
||||
|
|
|
@ -36,18 +36,17 @@ namespace mapnik
|
|||
static const unsigned MAX_MAPSIZE=2048;
|
||||
unsigned width_;
|
||||
unsigned height_;
|
||||
int srid_;
|
||||
std::string srs_;
|
||||
Color background_;
|
||||
std::map<std::string,feature_type_style> styles_;
|
||||
std::vector<Layer> layers_;
|
||||
Envelope<double> currentExtent_;
|
||||
|
||||
public:
|
||||
|
||||
typedef std::map<std::string,feature_type_style>::const_iterator style_iterator;
|
||||
|
||||
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& operator=(const Map& rhs);
|
||||
style_iterator begin_styles() const;
|
||||
|
@ -67,7 +66,8 @@ namespace mapnik
|
|||
void setWidth(unsigned width);
|
||||
void setHeight(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);
|
||||
const Color& getBackground() const;
|
||||
void zoom(double zoom);
|
||||
|
|
174
include/mapnik/projection.hpp
Normal file
174
include/mapnik/projection.hpp
Normal 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
|
|
@ -126,9 +126,11 @@ namespace mapnik
|
|||
}
|
||||
|
||||
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_scanline_aa_solid<ren_base> renderer;
|
||||
|
||||
|
@ -139,7 +141,7 @@ namespace mapnik
|
|||
{
|
||||
unsigned width = pixmap_.width();
|
||||
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::pixfmt_rgba32 pixf(buf);
|
||||
ren_base renb(pixf);
|
||||
|
@ -147,7 +149,6 @@ namespace mapnik
|
|||
unsigned r=fill_.red();
|
||||
unsigned g=fill_.green();
|
||||
unsigned b=fill_.blue();
|
||||
//unsigned a=fill_.alpha();
|
||||
renderer ren(renb);
|
||||
|
||||
agg::rasterizer_scanline_aa<> ras;
|
||||
|
@ -160,10 +161,12 @@ namespace mapnik
|
|||
}
|
||||
|
||||
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 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::rasterizer_outline_aa<renderer_oaa> rasterizer_outline_aa;
|
||||
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
|
||||
|
@ -171,7 +174,7 @@ namespace mapnik
|
|||
geometry_ptr const& geom=feature.get_geometry();
|
||||
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(),
|
||||
pixmap_.width(),
|
||||
pixmap_.height(),
|
||||
|
@ -277,17 +280,21 @@ namespace mapnik
|
|||
}
|
||||
|
||||
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();
|
||||
if (geom)
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
double z=0;
|
||||
boost::shared_ptr<ImageData32> const& data = sym.get_data();
|
||||
if ( data )
|
||||
{
|
||||
geom->label_position(&x,&y);
|
||||
prj_trans.backward(x,y,z);
|
||||
t_.forward(&x,&y);
|
||||
int w = data->width();
|
||||
int h = data->height();
|
||||
|
@ -307,9 +314,11 @@ namespace mapnik
|
|||
}
|
||||
|
||||
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::renderer_base<agg::pixfmt_rgba32> renderer_base;
|
||||
typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type;
|
||||
|
@ -321,7 +330,7 @@ namespace mapnik
|
|||
unsigned width = pixmap_.width();
|
||||
unsigned height = pixmap_.height();
|
||||
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::pixfmt_rgba32 pixf(buf);
|
||||
renderer_base ren_base(pixf);
|
||||
|
@ -336,9 +345,11 @@ namespace mapnik
|
|||
}
|
||||
|
||||
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::wrap_mode_repeat wrap_x_type;
|
||||
typedef agg::wrap_mode_repeat wrap_y_type;
|
||||
|
@ -358,7 +369,7 @@ namespace mapnik
|
|||
|
||||
unsigned width = pixmap_.width();
|
||||
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::pixfmt_rgba32 pixf(buf);
|
||||
|
@ -389,7 +400,9 @@ namespace mapnik
|
|||
}
|
||||
|
||||
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
|
||||
// used for type dispatching, but we can have some fancy raster
|
||||
|
@ -405,9 +418,11 @@ namespace mapnik
|
|||
}
|
||||
|
||||
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();
|
||||
if (geom)
|
||||
{
|
||||
|
@ -416,7 +431,7 @@ namespace mapnik
|
|||
geom->num_points() > 1)
|
||||
{
|
||||
|
||||
path_type path(t_,*geom);
|
||||
path_type path(t_,*geom,prj_trans);
|
||||
double x0,y0,x1,y1;
|
||||
path.vertex(&x0,&y0);
|
||||
path.vertex(&x1,&y1);
|
||||
|
|
|
@ -38,10 +38,11 @@ using boost::shared_ptr;
|
|||
|
||||
namespace mapnik
|
||||
{
|
||||
Layer::Layer(std::string const& name)
|
||||
Layer::Layer(std::string const& name, std::string const& srs)
|
||||
: name_(name),
|
||||
title_(""),
|
||||
abstract_(""),
|
||||
srs_(srs),
|
||||
minZoom_(0),
|
||||
maxZoom_(std::numeric_limits<double>::max()),
|
||||
active_(true),
|
||||
|
@ -53,6 +54,7 @@ namespace mapnik
|
|||
: name_(rhs.name_),
|
||||
title_(rhs.title_),
|
||||
abstract_(rhs.abstract_),
|
||||
srs_(rhs.srs_),
|
||||
minZoom_(rhs.minZoom_),
|
||||
maxZoom_(rhs.maxZoom_),
|
||||
active_(rhs.active_),
|
||||
|
@ -119,6 +121,16 @@ namespace mapnik
|
|||
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)
|
||||
{
|
||||
styles_.push_back(stylename);
|
||||
|
|
|
@ -47,19 +47,24 @@ namespace mapnik
|
|||
{
|
||||
using boost::property_tree::ptree;
|
||||
ptree pt;
|
||||
|
||||
read_xml(filename,pt);
|
||||
|
||||
boost::optional<std::string> bgcolor =
|
||||
pt.get_optional<std::string>("Map.<xmlattr>.bgcolor");
|
||||
|
||||
if (bgcolor)
|
||||
{
|
||||
Color bg = color_factory::from_string(bgcolor->c_str());
|
||||
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 end = pt.get_child("Map").end();
|
||||
|
||||
for (; itr != end; ++itr)
|
||||
{
|
||||
ptree::value_type const& v = *itr;
|
||||
|
@ -284,18 +289,19 @@ namespace mapnik
|
|||
else if (v.first == "Layer")
|
||||
{
|
||||
|
||||
std::string name = v.second.get<std::string>("<xmlattr>.name","");
|
||||
Layer lyr(name);
|
||||
std::string name = v.second.get<std::string>("<xmlattr>.name","Unnamed");
|
||||
std::string srs = v.second.get<std::string>("<xmlattr>.srs","+proj=latlong +datum=WGS84");
|
||||
|
||||
Layer lyr(name, srs);
|
||||
|
||||
boost::optional<std::string> status =
|
||||
v.second.get<std::string>("<xmlattr>.status");
|
||||
v.second.get_optional<std::string>("<xmlattr>.status");
|
||||
|
||||
if (status && *status == "off")
|
||||
{
|
||||
lyr.setActive(false);
|
||||
}
|
||||
|
||||
|
||||
ptree::const_iterator itr2 = v.second.begin();
|
||||
ptree::const_iterator end2 = v.second.end();
|
||||
|
||||
|
|
62
src/map.cpp
62
src/map.cpp
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <mapnik/style.hpp>
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/projection.hpp>
|
||||
#include <mapnik/layer.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
|
||||
|
@ -32,17 +33,18 @@ namespace mapnik
|
|||
Map::Map()
|
||||
: width_(400),
|
||||
height_(400),
|
||||
srid_(-1) {}
|
||||
Map::Map(int width,int height,int srid)
|
||||
srs_("+proj=latlong +datum=WGS84") {}
|
||||
|
||||
Map::Map(int width,int height, std::string const& srs)
|
||||
: width_(width),
|
||||
height_(height),
|
||||
srid_(srid),
|
||||
srs_(srs),
|
||||
background_(Color(255,255,255)) {}
|
||||
|
||||
Map::Map(const Map& rhs)
|
||||
: width_(rhs.width_),
|
||||
height_(rhs.height_),
|
||||
srid_(rhs.srid_),
|
||||
srs_(rhs.srs_),
|
||||
background_(rhs.background_),
|
||||
styles_(rhs.styles_),
|
||||
layers_(rhs.layers_),
|
||||
|
@ -53,12 +55,13 @@ namespace mapnik
|
|||
if (this==&rhs) return *this;
|
||||
width_=rhs.width_;
|
||||
height_=rhs.height_;
|
||||
srid_=rhs.srid_;
|
||||
srs_=rhs.srs_;
|
||||
background_=rhs.background_;
|
||||
styles_=rhs.styles_;
|
||||
layers_=rhs.layers_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Map::style_iterator Map::begin_styles() const
|
||||
{
|
||||
return styles_.begin();
|
||||
|
@ -80,8 +83,7 @@ namespace mapnik
|
|||
|
||||
feature_type_style const& Map::find_style(std::string const& name) const
|
||||
{
|
||||
std::map<std::string,feature_type_style>::const_iterator itr
|
||||
= styles_.find(name);
|
||||
std::map<std::string,feature_type_style>::const_iterator itr = styles_.find(name);
|
||||
if (itr!=styles_.end())
|
||||
return itr->second;
|
||||
static feature_type_style default_style;
|
||||
|
@ -118,7 +120,6 @@ namespace mapnik
|
|||
return layers_[index];
|
||||
}
|
||||
|
||||
|
||||
std::vector<Layer> const& Map::layers() const
|
||||
{
|
||||
return layers_;
|
||||
|
@ -151,6 +152,7 @@ namespace mapnik
|
|||
fixAspectRatio();
|
||||
}
|
||||
}
|
||||
|
||||
void Map::resize(unsigned width,unsigned height)
|
||||
{
|
||||
if (width >= MIN_MAPSIZE && width <= MAX_MAPSIZE &&
|
||||
|
@ -162,9 +164,14 @@ 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)
|
||||
|
@ -191,24 +198,51 @@ namespace mapnik
|
|||
|
||||
void Map::zoom_all()
|
||||
{
|
||||
std::vector<Layer>::const_iterator itr = layers_.begin();
|
||||
try
|
||||
{
|
||||
projection proj0(srs_);
|
||||
Envelope<double> ext;
|
||||
bool first = true;
|
||||
while (itr != layers_.end())
|
||||
std::vector<Layer>::const_iterator itr = layers_.begin();
|
||||
std::vector<Layer>::const_iterator end = layers_.end();
|
||||
while (itr != end)
|
||||
{
|
||||
std::string const& layer_srs = itr->srs();
|
||||
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 = itr->envelope();
|
||||
ext = layerExt2;
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ext.expand_to_include(itr->envelope());
|
||||
ext.expand_to_include(layerExt2);
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
zoomToBox(ext);
|
||||
}
|
||||
catch (proj_init_error & ex)
|
||||
{
|
||||
std::clog << ex.what() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
void Map::zoomToBox(const Envelope<double> &box)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue