Merge branch 'master' of github.com:mapnik/mapnik
This commit is contained in:
commit
eb81e72522
51 changed files with 2216 additions and 1328 deletions
|
@ -410,6 +410,13 @@ def Raster(**keywords):
|
|||
|
||||
Optional keyword arguments:
|
||||
base -- path prefix (default None)
|
||||
multi -- whether the image is in tiles on disk (default False)
|
||||
|
||||
Multi-tiled keyword arguments:
|
||||
x_width -- virtual image number of tiles in X direction (required)
|
||||
y_width -- virtual image number of tiles in Y direction (required)
|
||||
tile_size -- if an image is in tiles, how large are the tiles (default 256)
|
||||
tile_stride -- if an image is in tiles, what's the increment between rows/cols (default 1)
|
||||
|
||||
>>> from mapnik import Raster, Layer
|
||||
>>> raster = Raster(base='/home/mapnik/data',file='elevation.tif',lox=-122.8,loy=48.5,hix=-122.7,hiy=48.6)
|
||||
|
|
|
@ -78,7 +78,6 @@ void export_geometry()
|
|||
.def("envelope",&geometry_type::envelope)
|
||||
// .def("__str__",&geometry_type::to_string)
|
||||
.def("type",&geometry_type::type)
|
||||
.def("area",&geometry_type::area)
|
||||
// TODO add other geometry_type methods
|
||||
;
|
||||
|
||||
|
|
123
bindings/python/mapnik_label_collision_detector.cpp
Normal file
123
bindings/python/mapnik_label_collision_detector.cpp
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
#include <mapnik/label_collision_detector.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
|
||||
#include <list>
|
||||
|
||||
using mapnik::label_collision_detector4;
|
||||
using mapnik::box2d;
|
||||
using mapnik::Map;
|
||||
using boost::make_shared;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
boost::shared_ptr<label_collision_detector4>
|
||||
create_label_collision_detector_from_extent(box2d<double> const &extent)
|
||||
{
|
||||
return make_shared<label_collision_detector4>(extent);
|
||||
}
|
||||
|
||||
boost::shared_ptr<label_collision_detector4>
|
||||
create_label_collision_detector_from_map(Map const &m)
|
||||
{
|
||||
double buffer = m.buffer_size();
|
||||
box2d<double> extent(-buffer, -buffer, m.width() + buffer, m.height() + buffer);
|
||||
return make_shared<label_collision_detector4>(extent);
|
||||
}
|
||||
|
||||
boost::python::list
|
||||
make_label_boxes(boost::shared_ptr<label_collision_detector4> det)
|
||||
{
|
||||
boost::python::list boxes;
|
||||
|
||||
for (label_collision_detector4::query_iterator jtr = det->begin();
|
||||
jtr != det->end(); ++jtr)
|
||||
{
|
||||
boxes.append<box2d<double> >(jtr->box);
|
||||
}
|
||||
|
||||
return boxes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void export_label_collision_detector()
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
||||
// for overload resolution
|
||||
void (label_collision_detector4::*insert_box)(box2d<double> const &) = &label_collision_detector4::insert;
|
||||
|
||||
class_<label_collision_detector4, boost::shared_ptr<label_collision_detector4>, boost::noncopyable>
|
||||
("LabelCollisionDetector",
|
||||
"Object to detect collisions between labels, used in the rendering process.",
|
||||
no_init)
|
||||
|
||||
.def("__init__", make_constructor(create_label_collision_detector_from_extent),
|
||||
"Creates an empty collision detection object with a given extent. Note "
|
||||
"that the constructor from Map objects is a sensible default and usually "
|
||||
"what you want to do.\n"
|
||||
"\n"
|
||||
"Example:\n"
|
||||
">>> m = Map(size_x, size_y)\n"
|
||||
">>> buf_sz = m.buffer_size\n"
|
||||
">>> extent = mapnik.Box2d(-buf_sz, -buf_sz, m.width + buf_sz, m.height + buf_sz)\n"
|
||||
">>> detector = mapnik.LabelCollisionDetector(extent)")
|
||||
|
||||
.def("__init__", make_constructor(create_label_collision_detector_from_map),
|
||||
"Creates an empty collision detection object matching the given Map object. "
|
||||
"The created detector will have the same size, including the buffer, as the "
|
||||
"map object. This is usually what you want to do.\n"
|
||||
"\n"
|
||||
"Example:\n"
|
||||
">>> m = Map(size_x, size_y)\n"
|
||||
">>> detector = mapnik.LabelCollisionDetector(m)")
|
||||
|
||||
.def("extent", &label_collision_detector4::extent, return_value_policy<copy_const_reference>(),
|
||||
"Returns the total extent (bounding box) of all labels inside the detector.\n"
|
||||
"\n"
|
||||
"Example:\n"
|
||||
">>> detector.extent()\n"
|
||||
"Box2d(573.252589209,494.789179821,584.261023823,496.83610261)")
|
||||
|
||||
.def("boxes", &make_label_boxes,
|
||||
"Returns a list of all the label boxes inside the detector.")
|
||||
|
||||
.def("insert", insert_box,
|
||||
"Insert a 2d box into the collision detector. This can be used to ensure that "
|
||||
"some space is left clear on the map for later overdrawing, for example by "
|
||||
"non-Mapnik processes.\n"
|
||||
"\n"
|
||||
"Example:\n"
|
||||
">>> m = Map(size_x, size_y)\n"
|
||||
">>> detector = mapnik.LabelCollisionDetector(m)"
|
||||
">>> detector.insert(mapnik.Box2d(196, 254, 291, 389))")
|
||||
;
|
||||
}
|
|
@ -66,6 +66,7 @@ void export_view_transform();
|
|||
void export_raster_colorizer();
|
||||
void export_glyph_symbolizer();
|
||||
void export_inmem_metawriter();
|
||||
void export_label_collision_detector();
|
||||
|
||||
#include <mapnik/version.hpp>
|
||||
#include <mapnik/value_error.hpp>
|
||||
|
@ -120,6 +121,28 @@ void render(const mapnik::Map& map,
|
|||
Py_END_ALLOW_THREADS
|
||||
}
|
||||
|
||||
void render_with_detector(
|
||||
const mapnik::Map &map,
|
||||
mapnik::image_32 &image,
|
||||
boost::shared_ptr<mapnik::label_collision_detector4> detector,
|
||||
double scale_factor = 1.0,
|
||||
unsigned offset_x = 0u,
|
||||
unsigned offset_y = 0u)
|
||||
{
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
try
|
||||
{
|
||||
mapnik::agg_renderer<mapnik::image_32> ren(map,image,detector);
|
||||
ren.apply();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Py_BLOCK_THREADS
|
||||
throw;
|
||||
}
|
||||
Py_END_ALLOW_THREADS
|
||||
}
|
||||
|
||||
void render_layer2(const mapnik::Map& map,
|
||||
mapnik::image_32& image,
|
||||
unsigned layer_idx)
|
||||
|
@ -374,6 +397,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS(load_map_string_overloads, load_map_string, 2, 4
|
|||
BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_overloads, save_map, 2, 3)
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_to_string_overloads, save_map_to_string, 1, 2)
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS(render_overloads, render, 2, 5)
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS(render_with_detector_overloads, render_with_detector, 3, 6)
|
||||
|
||||
BOOST_PYTHON_MODULE(_mapnik2)
|
||||
{
|
||||
|
@ -427,6 +451,7 @@ BOOST_PYTHON_MODULE(_mapnik2)
|
|||
export_raster_colorizer();
|
||||
export_glyph_symbolizer();
|
||||
export_inmem_metawriter();
|
||||
export_label_collision_detector();
|
||||
|
||||
def("render_grid",&render_grid,
|
||||
( arg("map"),
|
||||
|
@ -503,6 +528,19 @@ BOOST_PYTHON_MODULE(_mapnik2)
|
|||
"\n"
|
||||
));
|
||||
|
||||
def("render_with_detector", &render_with_detector, render_with_detector_overloads(
|
||||
"\n"
|
||||
"Render Map to an AGG image_32 using a pre-constructed detector.\n"
|
||||
"\n"
|
||||
"Usage:\n"
|
||||
">>> from mapnik import Map, Image, LabelCollisionDetector, render_with_detector, load_map\n"
|
||||
">>> m = Map(256,256)\n"
|
||||
">>> load_map(m,'mapfile.xml')\n"
|
||||
">>> im = Image(m.width,m.height)\n"
|
||||
">>> detector = LabelCollisionDetector(m)\n"
|
||||
">>> render_with_detector(m, im, detector)\n"
|
||||
));
|
||||
|
||||
def("render_layer", &render_layer2,
|
||||
(arg("map"),arg("image"),args("layer"))
|
||||
);
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
// boost
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
// FIXME
|
||||
// forward declare so that
|
||||
|
@ -61,7 +62,11 @@ class MAPNIK_DECL agg_renderer : public feature_style_processor<agg_renderer<T>
|
|||
{
|
||||
|
||||
public:
|
||||
// create with default, empty placement detector
|
||||
agg_renderer(Map const& m, T & pixmap, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
||||
// create with external placement detector, possibly non-empty
|
||||
agg_renderer(Map const &m, T & pixmap, boost::shared_ptr<label_collision_detector4> detector,
|
||||
double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
||||
~agg_renderer();
|
||||
void start_map_processing(Map const& map);
|
||||
void end_map_processing(Map const& map);
|
||||
|
@ -122,8 +127,10 @@ private:
|
|||
CoordTransform t_;
|
||||
freetype_engine font_engine_;
|
||||
face_manager<freetype_engine> font_manager_;
|
||||
label_collision_detector4 detector_;
|
||||
boost::shared_ptr<label_collision_detector4> detector_;
|
||||
boost::scoped_ptr<rasterizer> ras_ptr;
|
||||
|
||||
void setup(Map const &m);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2006 Artem Pavlenko
|
||||
|
@ -19,91 +19,92 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//$Id: ctrans.hpp 39 2005-04-10 20:39:53Z pavlenko $
|
||||
//$Id$
|
||||
|
||||
#ifndef CTRANS_HPP
|
||||
#define CTRANS_HPP
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/vertex.hpp>
|
||||
#include <mapnik/coord_array.hpp>
|
||||
#include <mapnik/proj_transform.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
// boost
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
|
||||
// stl
|
||||
#include <algorithm>
|
||||
|
||||
const double pi = boost::math::constants::pi<double>();
|
||||
const double pi_by_2 = pi/2.0;
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
typedef coord_array<coord2d> CoordinateArray;
|
||||
|
||||
template <typename Transform,typename Geometry>
|
||||
|
||||
|
||||
template <typename Transform, typename Geometry>
|
||||
struct MAPNIK_DECL coord_transform
|
||||
{
|
||||
coord_transform(Transform const& t, Geometry& geom)
|
||||
: t_(t), geom_(geom) {}
|
||||
|
||||
unsigned vertex(double *x , double *y) const
|
||||
|
||||
unsigned vertex(double *x, double *y) const
|
||||
{
|
||||
unsigned command = geom_.vertex(x,y);
|
||||
t_.forward(x,y);
|
||||
unsigned command = geom_.vertex(x, y);
|
||||
t_.forward(x, y);
|
||||
return command;
|
||||
}
|
||||
|
||||
void rewind (unsigned pos)
|
||||
|
||||
void rewind(unsigned pos)
|
||||
{
|
||||
geom_.rewind(pos);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
Transform const& t_;
|
||||
Geometry& geom_;
|
||||
};
|
||||
|
||||
template <typename Transform,typename Geometry>
|
||||
|
||||
template <typename Transform, typename Geometry>
|
||||
struct MAPNIK_DECL coord_transform2
|
||||
{
|
||||
typedef std::size_t size_type;
|
||||
typedef typename Geometry::value_type value_type;
|
||||
|
||||
coord_transform2(Transform const& t,
|
||||
Geometry const& geom,
|
||||
coord_transform2(Transform const& t,
|
||||
Geometry const& geom,
|
||||
proj_transform const& prj_trans)
|
||||
: t_(t),
|
||||
geom_(geom),
|
||||
: t_(t),
|
||||
geom_(geom),
|
||||
prj_trans_(prj_trans) {}
|
||||
|
||||
unsigned vertex(double * x , double * y) const
|
||||
|
||||
unsigned vertex(double *x, double *y) const
|
||||
{
|
||||
unsigned command(SEG_MOVETO);
|
||||
unsigned command = SEG_MOVETO;
|
||||
bool ok = false;
|
||||
bool skipped_points = false;
|
||||
while (!ok)
|
||||
double z = 0;
|
||||
while (!ok && command != SEG_END)
|
||||
{
|
||||
command = geom_.vertex(x,y);
|
||||
double z=0;
|
||||
ok = prj_trans_.backward(*x,*y,z);
|
||||
command = geom_.vertex(x, y);
|
||||
ok = prj_trans_.backward(*x, *y, z);
|
||||
if (!ok) {
|
||||
skipped_points = true;
|
||||
}
|
||||
ok = ok || (command == SEG_END);
|
||||
}
|
||||
if (skipped_points && (command == SEG_LINETO))
|
||||
{
|
||||
command = SEG_MOVETO;
|
||||
}
|
||||
t_.forward(x,y);
|
||||
t_.forward(x, y);
|
||||
return command;
|
||||
}
|
||||
|
||||
/*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)
|
||||
void rewind(unsigned pos)
|
||||
{
|
||||
geom_.rewind(pos);
|
||||
}
|
||||
|
@ -112,42 +113,42 @@ struct MAPNIK_DECL coord_transform2
|
|||
{
|
||||
return geom_;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
Transform const& t_;
|
||||
Geometry const& geom_;
|
||||
proj_transform const& prj_trans_;
|
||||
};
|
||||
|
||||
|
||||
template <typename Transform,typename Geometry>
|
||||
|
||||
template <typename Transform, typename Geometry>
|
||||
struct MAPNIK_DECL coord_transform3
|
||||
{
|
||||
coord_transform3(Transform const& t,
|
||||
Geometry const& geom,
|
||||
coord_transform3(Transform const& t,
|
||||
Geometry const& geom,
|
||||
proj_transform const& prj_trans,
|
||||
int dx, int dy)
|
||||
: t_(t),
|
||||
geom_(geom),
|
||||
: t_(t),
|
||||
geom_(geom),
|
||||
prj_trans_(prj_trans),
|
||||
dx_(dx), dy_(dy) {}
|
||||
|
||||
unsigned vertex(double * x , double * y) const
|
||||
|
||||
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);
|
||||
*x+=dx_;
|
||||
*y+=dy_;
|
||||
unsigned command = geom_.vertex(x, y);
|
||||
double z = 0;
|
||||
prj_trans_.backward(*x, *y, z);
|
||||
t_.forward(x, y);
|
||||
*x += dx_;
|
||||
*y += dy_;
|
||||
return command;
|
||||
}
|
||||
|
||||
void rewind (unsigned pos)
|
||||
|
||||
void rewind(unsigned pos)
|
||||
{
|
||||
geom_.rewind(pos);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
Transform const& t_;
|
||||
Geometry const& geom_;
|
||||
|
@ -155,7 +156,226 @@ private:
|
|||
int dx_;
|
||||
int dy_;
|
||||
};
|
||||
|
||||
|
||||
// TODO - expose this and make chainable
|
||||
template <typename Transform,typename Geometry>
|
||||
struct MAPNIK_DECL coord_transform_parallel
|
||||
{
|
||||
typedef std::size_t size_type;
|
||||
typedef typename Geometry::value_type value_type;
|
||||
|
||||
coord_transform_parallel(Transform const& t,
|
||||
Geometry const& geom,
|
||||
proj_transform const& prj_trans )
|
||||
: t_(t),
|
||||
geom_(geom),
|
||||
prj_trans_(prj_trans),
|
||||
offset_(0.0),
|
||||
threshold_(10),
|
||||
m_status(initial) {}
|
||||
|
||||
enum status
|
||||
{
|
||||
initial,
|
||||
start,
|
||||
first,
|
||||
process,
|
||||
last_vertex,
|
||||
angle_joint,
|
||||
end
|
||||
};
|
||||
|
||||
double get_offset() const
|
||||
{
|
||||
return offset_;
|
||||
}
|
||||
|
||||
void set_offset(double offset)
|
||||
{
|
||||
offset_ = offset;
|
||||
}
|
||||
|
||||
unsigned int get_threshold() const
|
||||
{
|
||||
return threshold_;
|
||||
}
|
||||
|
||||
void set_threshold(unsigned int t)
|
||||
{
|
||||
threshold_ = t;
|
||||
}
|
||||
|
||||
unsigned vertex(double * x , double * y)
|
||||
{
|
||||
double z=0;
|
||||
|
||||
if (offset_==0.0)
|
||||
{
|
||||
unsigned command = geom_.vertex(x,y);
|
||||
prj_trans_.backward(*x,*y,z);
|
||||
t_.forward(x,y);
|
||||
return command;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(true){
|
||||
switch(m_status)
|
||||
{
|
||||
case end:
|
||||
return SEG_END;
|
||||
break;
|
||||
case initial:
|
||||
m_pre_cmd = geom_.vertex(x,y);
|
||||
prj_trans_.backward(*x,*y,z);
|
||||
t_.forward(x,y);
|
||||
m_pre_x = *x;
|
||||
m_pre_y = *y;
|
||||
//m_status = (m_pre_cmd!=SEG_END)?start:end; //
|
||||
case start:
|
||||
m_cur_cmd = geom_.vertex(&m_cur_x, &m_cur_y);
|
||||
prj_trans_.backward(m_cur_x,m_cur_y,z);
|
||||
t_.forward(&m_cur_x,&m_cur_y);
|
||||
case first:
|
||||
angle_a = atan2((m_pre_y-m_cur_y),(m_pre_x-m_cur_x));
|
||||
dx_pre = cos(angle_a + pi_by_2);
|
||||
dy_pre = sin(angle_a + pi_by_2);
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "offsetting line by: " << offset_ << "\n";
|
||||
std::clog << "initial dx=" << (dx_pre * offset_) << " dy=" << (dy_pre * offset_) << "\n";
|
||||
#endif
|
||||
*x = m_pre_x + (dx_pre * offset_);
|
||||
*y = m_pre_y + (dy_pre * offset_);
|
||||
m_status = process;
|
||||
return SEG_MOVETO;
|
||||
case process:
|
||||
switch(m_cur_cmd)
|
||||
{
|
||||
case SEG_LINETO:
|
||||
m_next_cmd = geom_.vertex(&m_next_x, &m_next_y);
|
||||
prj_trans_.backward(m_next_x,m_next_y,z);
|
||||
t_.forward(&m_next_x,&m_next_y);
|
||||
switch(m_next_cmd)
|
||||
{
|
||||
case SEG_LINETO:
|
||||
m_status = angle_joint;
|
||||
break;
|
||||
default:
|
||||
m_status = last_vertex;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SEG_END:
|
||||
m_status = end;
|
||||
return SEG_END;
|
||||
}
|
||||
break;
|
||||
case last_vertex:
|
||||
dx_curr = cos(angle_a + pi_by_2);
|
||||
dy_curr = sin(angle_a + pi_by_2);
|
||||
*x = m_cur_x + (dx_curr * offset_);
|
||||
*y = m_cur_y + (dy_curr * offset_);
|
||||
m_status = end;
|
||||
return m_cur_cmd;
|
||||
case angle_joint:
|
||||
angle_b = atan2((m_cur_y-m_next_y),(m_cur_x-m_next_x));
|
||||
h = tan((angle_b - angle_a)/2.0);
|
||||
|
||||
if (fabs(h) < threshold_)
|
||||
{
|
||||
dx_curr = cos(angle_a + pi_by_2);
|
||||
dy_curr = sin(angle_a + pi_by_2);
|
||||
*x = m_cur_x + (dx_curr * offset_) - h * (dy_curr * offset_);
|
||||
*y = m_cur_y + (dy_curr * offset_) + h * (dx_curr * offset_);
|
||||
}
|
||||
else // skip sharp spikes
|
||||
{
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
dx_curr = cos(angle_a + pi_by_2);
|
||||
dy_curr = sin(angle_a + pi_by_2);
|
||||
sin_curve = dx_curr*dy_pre-dy_curr*dx_pre;
|
||||
std::clog << "angle a: " << angle_a << "\n";
|
||||
std::clog << "angle b: " << angle_b << "\n";
|
||||
std::clog << "h: " << h << "\n";
|
||||
std::clog << "sin_curve: " << sin_curve << "\n";
|
||||
#endif
|
||||
m_status = process;
|
||||
break;
|
||||
}
|
||||
|
||||
// alternate sharp spike fix, but suboptimal...
|
||||
|
||||
/*
|
||||
sin_curve = dx_curr*dy_pre-dy_curr*dx_pre;
|
||||
cos_curve = -dx_pre*dx_curr-dy_pre*dy_curr;
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "sin_curve value: " << sin_curve << "\n";
|
||||
#endif
|
||||
if(sin_curve > -0.3 && sin_curve < 0.3) {
|
||||
angle_b = atan2((m_cur_y-m_next_y),(m_cur_x-m_next_x));
|
||||
h = tan((angle_b - angle_a)/2.0);
|
||||
*x = m_cur_x + (dx_curr * offset_) - h * (dy_curr * offset_);
|
||||
*y = m_cur_y + (dy_curr * offset_) + h * (dx_curr * offset_);
|
||||
} else {
|
||||
if (angle_b - angle_a > 0)
|
||||
h = -1.0*(1.0+cos_curve)/sin_curve;
|
||||
else
|
||||
h = (1.0+cos_curve)/sin_curve;
|
||||
*x = m_cur_x + (dx_curr + base_shift*dy_curr)*offset_;
|
||||
*y = m_cur_y + (dy_curr - base_shift*dx_curr)*offset_;
|
||||
}
|
||||
*/
|
||||
|
||||
m_pre_x = *x;
|
||||
m_pre_x = *y;
|
||||
m_cur_x = m_next_x;
|
||||
m_cur_y = m_next_y;
|
||||
angle_a = angle_b;
|
||||
m_pre_cmd = m_cur_cmd;
|
||||
m_cur_cmd = m_next_cmd;
|
||||
m_status = process;
|
||||
return m_pre_cmd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rewind (unsigned pos)
|
||||
{
|
||||
geom_.rewind(pos);
|
||||
m_status = initial;
|
||||
}
|
||||
|
||||
private:
|
||||
Transform const& t_;
|
||||
Geometry const& geom_;
|
||||
proj_transform const& prj_trans_;
|
||||
int offset_;
|
||||
unsigned int threshold_;
|
||||
status m_status;
|
||||
double dx_pre;
|
||||
double dy_pre;
|
||||
double dx_curr;
|
||||
double dy_curr;
|
||||
double sin_curve;
|
||||
double cos_curve;
|
||||
double angle_a;
|
||||
double angle_b;
|
||||
double h;
|
||||
unsigned m_pre_cmd;
|
||||
double m_pre_x;
|
||||
double m_pre_y;
|
||||
unsigned m_cur_cmd;
|
||||
double m_cur_x;
|
||||
double m_cur_y;
|
||||
unsigned m_next_cmd;
|
||||
double m_next_x;
|
||||
double m_next_y;
|
||||
};
|
||||
|
||||
|
||||
class CoordTransform
|
||||
{
|
||||
private:
|
||||
|
@ -166,71 +386,74 @@ private:
|
|||
box2d<double> extent_;
|
||||
double offset_x_;
|
||||
double offset_y_;
|
||||
|
||||
public:
|
||||
CoordTransform(int width,int height,const box2d<double>& extent,
|
||||
CoordTransform(int width, int height, const box2d<double>& extent,
|
||||
double offset_x = 0, double offset_y = 0)
|
||||
:width_(width),height_(height),extent_(extent),offset_x_(offset_x),offset_y_(offset_y)
|
||||
: width_(width), height_(height), extent_(extent),
|
||||
offset_x_(offset_x), offset_y_(offset_y)
|
||||
{
|
||||
sx_ = (double(width_))/extent_.width();
|
||||
sy_ = (double(height_))/extent_.height();
|
||||
sx_ = static_cast<double>(width_) / extent_.width();
|
||||
sy_ = static_cast<double>(height_) / extent_.height();
|
||||
}
|
||||
|
||||
|
||||
inline int width() const
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
|
||||
|
||||
inline int height() const
|
||||
{
|
||||
return height_;
|
||||
}
|
||||
|
||||
|
||||
inline double scale_x() const
|
||||
{
|
||||
return sx_;
|
||||
}
|
||||
|
||||
|
||||
inline double scale_y() const
|
||||
{
|
||||
return sy_;
|
||||
}
|
||||
|
||||
inline void forward(double * x, double * y) const
|
||||
|
||||
inline void forward(double *x, double *y) const
|
||||
{
|
||||
*x = (*x - extent_.minx()) * sx_ - offset_x_;
|
||||
*y = (extent_.maxy() - *y) * sy_ - offset_y_;
|
||||
}
|
||||
|
||||
inline void backward(double * x, double * y) const
|
||||
|
||||
inline void backward(double *x, double *y) const
|
||||
{
|
||||
*x = extent_.minx() + (*x + offset_x_)/sx_;
|
||||
*y = extent_.maxy() - (*y + offset_y_)/sy_;
|
||||
*x = extent_.minx() + (*x + offset_x_) / sx_;
|
||||
*y = extent_.maxy() - (*y + offset_y_) / sy_;
|
||||
}
|
||||
|
||||
|
||||
inline coord2d& forward(coord2d& c) const
|
||||
{
|
||||
forward(&c.x,&c.y);
|
||||
return c;
|
||||
}
|
||||
|
||||
inline coord2d& backward(coord2d& c) const
|
||||
{
|
||||
backward(&c.x,&c.y);
|
||||
forward(&c.x, &c.y);
|
||||
return c;
|
||||
}
|
||||
|
||||
inline box2d<double> forward(const box2d<double>& e,proj_transform const& prj_trans) const
|
||||
inline coord2d& backward(coord2d& c) const
|
||||
{
|
||||
backward(&c.x, &c.y);
|
||||
return c;
|
||||
}
|
||||
|
||||
inline box2d<double> forward(const box2d<double>& e,
|
||||
proj_transform const& prj_trans) const
|
||||
{
|
||||
double x0 = e.minx();
|
||||
double y0 = e.miny();
|
||||
double x1 = e.maxx();
|
||||
double y1 = e.maxy();
|
||||
double z = 0.0;
|
||||
prj_trans.backward(x0,y0,z);
|
||||
forward(&x0,&y0);
|
||||
prj_trans.backward(x1,y1,z);
|
||||
forward(&x1,&y1);
|
||||
return box2d<double>(x0,y0,x1,y1);
|
||||
prj_trans.backward(x0, y0, z);
|
||||
forward(&x0, &y0);
|
||||
prj_trans.backward(x1, y1, z);
|
||||
forward(&x1, &y1);
|
||||
return box2d<double>(x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
inline box2d<double> forward(const box2d<double>& e) const
|
||||
|
@ -239,23 +462,24 @@ public:
|
|||
double y0 = e.miny();
|
||||
double x1 = e.maxx();
|
||||
double y1 = e.maxy();
|
||||
forward(&x0,&y0);
|
||||
forward(&x1,&y1);
|
||||
return box2d<double>(x0,y0,x1,y1);
|
||||
forward(&x0, &y0);
|
||||
forward(&x1, &y1);
|
||||
return box2d<double>(x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
inline box2d<double> backward(const box2d<double>& e,proj_transform const& prj_trans) const
|
||||
inline box2d<double> backward(const box2d<double>& e,
|
||||
proj_transform const& prj_trans) const
|
||||
{
|
||||
double x0 = e.minx();
|
||||
double y0 = e.miny();
|
||||
double x1 = e.maxx();
|
||||
double y1 = e.maxy();
|
||||
double z = 0.0;
|
||||
backward(&x0,&y0);
|
||||
prj_trans.forward(x0,y0,z);
|
||||
backward(&x1,&y1);
|
||||
prj_trans.forward(x1,y1,z);
|
||||
return box2d<double>(x0,y0,x1,y1);
|
||||
backward(&x0, &y0);
|
||||
prj_trans.forward(x0, y0, z);
|
||||
backward(&x1, &y1);
|
||||
prj_trans.forward(x1, y1, z);
|
||||
return box2d<double>(x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
inline box2d<double> backward(const box2d<double>& e) const
|
||||
|
@ -264,28 +488,29 @@ public:
|
|||
double y0 = e.miny();
|
||||
double x1 = e.maxx();
|
||||
double y1 = e.maxy();
|
||||
backward(&x0,&y0);
|
||||
backward(&x1,&y1);
|
||||
return box2d<double>(x0,y0,x1,y1);
|
||||
backward(&x0, &y0);
|
||||
backward(&x1, &y1);
|
||||
return box2d<double>(x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
inline CoordinateArray& forward(CoordinateArray& coords) const
|
||||
{
|
||||
for (unsigned i=0;i<coords.size();++i)
|
||||
for (unsigned i = 0; i < coords.size(); ++i)
|
||||
{
|
||||
forward(coords[i]);
|
||||
}
|
||||
return coords;
|
||||
}
|
||||
|
||||
|
||||
inline CoordinateArray& backward(CoordinateArray& coords) const
|
||||
{
|
||||
for (unsigned i=0;i<coords.size();++i)
|
||||
for (unsigned i = 0; i < coords.size(); ++i)
|
||||
{
|
||||
backward(coords[i]);
|
||||
}
|
||||
return coords;
|
||||
}
|
||||
|
||||
inline box2d<double> const& extent() const
|
||||
{
|
||||
return extent_;
|
||||
|
|
|
@ -68,27 +68,7 @@ public:
|
|||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
double area() const
|
||||
{
|
||||
double sum = 0.0;
|
||||
double x(0);
|
||||
double y(0);
|
||||
rewind(0);
|
||||
double xs = x;
|
||||
double ys = y;
|
||||
for (unsigned i=0;i<num_points();++i)
|
||||
{
|
||||
double x0(0);
|
||||
double y0(0);
|
||||
vertex(&x0,&y0);
|
||||
sum += x * y0 - y * x0;
|
||||
x = x0;
|
||||
y = y0;
|
||||
}
|
||||
return (sum + x * ys - y * xs) * 0.5;
|
||||
}
|
||||
|
||||
|
||||
box2d<double> envelope() const
|
||||
{
|
||||
box2d<double> result;
|
||||
|
|
|
@ -69,7 +69,7 @@ class label_collision_detector2 : boost::noncopyable
|
|||
typedef quad_tree<box2d<double> > tree_t;
|
||||
tree_t tree_;
|
||||
public:
|
||||
|
||||
|
||||
explicit label_collision_detector2(box2d<double> const& extent)
|
||||
: tree_(extent) {}
|
||||
|
||||
|
@ -138,6 +138,7 @@ public:
|
|||
//quad tree based label collission detector so labels dont appear within a given distance
|
||||
class label_collision_detector4 : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
struct label
|
||||
{
|
||||
label(box2d<double> const& b) : box(b) {}
|
||||
|
@ -146,11 +147,13 @@ class label_collision_detector4 : boost::noncopyable
|
|||
box2d<double> box;
|
||||
UnicodeString text;
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
typedef quad_tree< label > tree_t;
|
||||
tree_t tree_;
|
||||
|
||||
public:
|
||||
typedef tree_t::query_iterator query_iterator;
|
||||
|
||||
explicit label_collision_detector4(box2d<double> const& extent)
|
||||
: tree_(extent) {}
|
||||
|
@ -224,6 +227,9 @@ public:
|
|||
{
|
||||
return tree_.extent();
|
||||
}
|
||||
|
||||
query_iterator begin() { return tree_.query_in_box(extent()); }
|
||||
query_iterator end() { return tree_.query_end(); }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -45,7 +45,7 @@ using mapnik::datasource_exception;
|
|||
* Opens a GDALDataset and returns a pointer to it.
|
||||
* Caller is responsible for calling GDALClose on it
|
||||
*/
|
||||
inline GDALDataset *gdal_datasource::open_dataset() const
|
||||
inline GDALDataset* gdal_datasource::open_dataset() const
|
||||
{
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
|
@ -55,21 +55,28 @@ inline GDALDataset *gdal_datasource::open_dataset() const
|
|||
GDALDataset *dataset;
|
||||
#if GDAL_VERSION_NUM >= 1600
|
||||
if (shared_dataset_)
|
||||
dataset = reinterpret_cast<GDALDataset*>(GDALOpenShared((dataset_name_).c_str(),GA_ReadOnly));
|
||||
{
|
||||
dataset = reinterpret_cast<GDALDataset*>(GDALOpenShared((dataset_name_).c_str(), GA_ReadOnly));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
dataset = reinterpret_cast<GDALDataset*>(GDALOpen((dataset_name_).c_str(),GA_ReadOnly));
|
||||
{
|
||||
dataset = reinterpret_cast<GDALDataset*>(GDALOpen((dataset_name_).c_str(), GA_ReadOnly));
|
||||
}
|
||||
|
||||
if (! dataset)
|
||||
{
|
||||
throw datasource_exception(CPLGetLastErrorMsg());
|
||||
}
|
||||
|
||||
if (! dataset) throw datasource_exception(CPLGetLastErrorMsg());
|
||||
return dataset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
gdal_datasource::gdal_datasource(parameters const& params, bool bind)
|
||||
: datasource(params),
|
||||
desc_(*params.get<std::string>("type"),"utf-8"),
|
||||
filter_factor_(*params_.get<double>("filter_factor",0.0))
|
||||
: datasource(params),
|
||||
desc_(*params.get<std::string>("type"), "utf-8"),
|
||||
filter_factor_(*params_.get<double>("filter_factor", 0.0))
|
||||
{
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "GDAL Plugin: Initializing..." << std::endl;
|
||||
|
@ -78,13 +85,17 @@ gdal_datasource::gdal_datasource(parameters const& params, bool bind)
|
|||
GDALAllRegister();
|
||||
|
||||
boost::optional<std::string> file = params.get<std::string>("file");
|
||||
if (!file) throw datasource_exception("missing <file> parameter");
|
||||
if (! file) throw datasource_exception("missing <file> parameter");
|
||||
|
||||
boost::optional<std::string> base = params_.get<std::string>("base");
|
||||
if (base)
|
||||
{
|
||||
dataset_name_ = *base + "/" + *file;
|
||||
}
|
||||
else
|
||||
{
|
||||
dataset_name_ = *file;
|
||||
}
|
||||
|
||||
if (bind)
|
||||
{
|
||||
|
@ -96,7 +107,7 @@ void gdal_datasource::bind() const
|
|||
{
|
||||
if (is_bound_) return;
|
||||
|
||||
shared_dataset_ = *params_.get<mapnik::boolean>("shared",false);
|
||||
shared_dataset_ = *params_.get<mapnik::boolean>("shared", false);
|
||||
band_ = *params_.get<int>("band", -1);
|
||||
|
||||
GDALDataset *dataset = open_dataset();
|
||||
|
@ -105,7 +116,6 @@ void gdal_datasource::bind() const
|
|||
width_ = dataset->GetRasterXSize();
|
||||
height_ = dataset->GetRasterYSize();
|
||||
|
||||
|
||||
double tr[6];
|
||||
bool bbox_override = false;
|
||||
boost::optional<std::string> bbox_s = params_.get<std::string>("bbox");
|
||||
|
@ -114,8 +124,9 @@ void gdal_datasource::bind() const
|
|||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "GDAL Plugin: bbox parameter=" << *bbox_s << std::endl;
|
||||
#endif
|
||||
|
||||
bbox_override = extent_.from_string(*bbox_s);
|
||||
if (!bbox_override)
|
||||
if (! bbox_override)
|
||||
{
|
||||
throw datasource_exception("GDAL Plugin: bbox parameter '" + *bbox_s + "' invalid");
|
||||
}
|
||||
|
@ -141,7 +152,7 @@ void gdal_datasource::bind() const
|
|||
<< tr[4] << "," << tr[5] << std::endl;
|
||||
#endif
|
||||
|
||||
if (tr[2] !=0 || tr[4] != 0)
|
||||
if (tr[2] != 0 || tr[4] != 0)
|
||||
{
|
||||
throw datasource_exception("GDAL Plugin: only 'north up' images are supported");
|
||||
}
|
||||
|
@ -149,7 +160,7 @@ void gdal_datasource::bind() const
|
|||
dx_ = tr[1];
|
||||
dy_ = tr[5];
|
||||
|
||||
if (!bbox_override)
|
||||
if (! bbox_override)
|
||||
{
|
||||
double x0 = tr[0];
|
||||
double y0 = tr[3];
|
||||
|
@ -164,8 +175,9 @@ void gdal_datasource::bind() const
|
|||
double y1 = tr[3] + (width_) * tr[4]; // maxy
|
||||
*/
|
||||
|
||||
extent_.init(x0,y0,x1,y1);
|
||||
extent_.init(x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
GDALClose(dataset);
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
|
@ -192,7 +204,7 @@ std::string gdal_datasource::name()
|
|||
|
||||
box2d<double> gdal_datasource::envelope() const
|
||||
{
|
||||
if (!is_bound_) bind();
|
||||
if (! is_bound_) bind();
|
||||
|
||||
return extent_;
|
||||
}
|
||||
|
@ -204,18 +216,38 @@ layer_descriptor gdal_datasource::get_descriptor() const
|
|||
|
||||
featureset_ptr gdal_datasource::features(query const& q) const
|
||||
{
|
||||
if (!is_bound_) bind();
|
||||
if (! is_bound_) bind();
|
||||
|
||||
gdal_query gq = q;
|
||||
|
||||
// TODO - move to boost::make_shared, but must reduce # of args to <= 9
|
||||
return featureset_ptr(new gdal_featureset(*open_dataset(), band_, gq, extent_, width_, height_, nbands_, dx_, dy_, filter_factor_));
|
||||
return featureset_ptr(new gdal_featureset(*open_dataset(),
|
||||
band_,
|
||||
gq,
|
||||
extent_,
|
||||
width_,
|
||||
height_,
|
||||
nbands_,
|
||||
dx_,
|
||||
dy_,
|
||||
filter_factor_));
|
||||
}
|
||||
|
||||
featureset_ptr gdal_datasource::features_at_point(coord2d const& pt) const
|
||||
{
|
||||
if (!is_bound_) bind();
|
||||
if (! is_bound_) bind();
|
||||
|
||||
gdal_query gq = pt;
|
||||
return featureset_ptr(new gdal_featureset(*open_dataset(), band_, gq, extent_, width_, height_, nbands_, dx_, dy_, filter_factor_));
|
||||
}
|
||||
|
||||
// TODO - move to boost::make_shared, but must reduce # of args to <= 9
|
||||
return featureset_ptr(new gdal_featureset(*open_dataset(),
|
||||
band_,
|
||||
gq,
|
||||
extent_,
|
||||
width_,
|
||||
height_,
|
||||
nbands_,
|
||||
dx_,
|
||||
dy_,
|
||||
filter_factor_));
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -35,29 +35,29 @@
|
|||
|
||||
class gdal_datasource : public mapnik::datasource
|
||||
{
|
||||
public:
|
||||
gdal_datasource(mapnik::parameters const& params, bool bind=true);
|
||||
virtual ~gdal_datasource ();
|
||||
int type() const;
|
||||
static std::string name();
|
||||
mapnik::featureset_ptr features( mapnik::query const& q) const;
|
||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||
mapnik::box2d<double> envelope() const;
|
||||
mapnik::layer_descriptor get_descriptor() const;
|
||||
void bind() const;
|
||||
private:
|
||||
mutable mapnik::box2d<double> extent_;
|
||||
std::string dataset_name_;
|
||||
mutable int band_;
|
||||
mapnik::layer_descriptor desc_;
|
||||
mutable unsigned width_;
|
||||
mutable unsigned height_;
|
||||
mutable double dx_;
|
||||
mutable double dy_;
|
||||
mutable int nbands_;
|
||||
mutable bool shared_dataset_;
|
||||
double filter_factor_;
|
||||
inline GDALDataset *open_dataset() const;
|
||||
public:
|
||||
gdal_datasource(mapnik::parameters const& params, bool bind = true);
|
||||
virtual ~gdal_datasource();
|
||||
int type() const;
|
||||
static std::string name();
|
||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||
mapnik::box2d<double> envelope() const;
|
||||
mapnik::layer_descriptor get_descriptor() const;
|
||||
void bind() const;
|
||||
private:
|
||||
mutable mapnik::box2d<double> extent_;
|
||||
std::string dataset_name_;
|
||||
mutable int band_;
|
||||
mapnik::layer_descriptor desc_;
|
||||
mutable unsigned width_;
|
||||
mutable unsigned height_;
|
||||
mutable double dx_;
|
||||
mutable double dy_;
|
||||
mutable int nbands_;
|
||||
mutable bool shared_dataset_;
|
||||
double filter_factor_;
|
||||
inline GDALDataset* open_dataset() const;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -41,20 +41,27 @@ using mapnik::datasource_exception;
|
|||
using mapnik::feature_factory;
|
||||
|
||||
|
||||
gdal_featureset::gdal_featureset(GDALDataset & dataset, int band, gdal_query q,
|
||||
mapnik::box2d<double> extent, double width, double height, int nbands,
|
||||
double dx, double dy, double filter_factor)
|
||||
: dataset_(dataset),
|
||||
band_(band),
|
||||
gquery_(q),
|
||||
raster_extent_(extent),
|
||||
raster_width_(width),
|
||||
raster_height_(height),
|
||||
dx_(dx),
|
||||
dy_(dy),
|
||||
nbands_(nbands),
|
||||
filter_factor_(filter_factor),
|
||||
first_(true)
|
||||
gdal_featureset::gdal_featureset(GDALDataset& dataset,
|
||||
int band,
|
||||
gdal_query q,
|
||||
mapnik::box2d<double> extent,
|
||||
double width,
|
||||
double height,
|
||||
int nbands,
|
||||
double dx,
|
||||
double dy,
|
||||
double filter_factor)
|
||||
: dataset_(dataset),
|
||||
band_(band),
|
||||
gquery_(q),
|
||||
raster_extent_(extent),
|
||||
raster_width_(width),
|
||||
raster_height_(height),
|
||||
dx_(dx),
|
||||
dy_(dy),
|
||||
nbands_(nbands),
|
||||
filter_factor_(filter_factor),
|
||||
first_(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -63,6 +70,7 @@ gdal_featureset::~gdal_featureset()
|
|||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "GDAL Plugin: closing dataset = " << &dataset_ << std::endl;
|
||||
#endif
|
||||
|
||||
GDALClose(&dataset_);
|
||||
}
|
||||
|
||||
|
@ -76,11 +84,15 @@ feature_ptr gdal_featureset::next()
|
|||
#endif
|
||||
|
||||
query *q = boost::get<query>(&gquery_);
|
||||
if(q) {
|
||||
if (q)
|
||||
{
|
||||
return get_feature(*q);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
coord2d *p = boost::get<coord2d>(&gquery_);
|
||||
if(p) {
|
||||
if (p)
|
||||
{
|
||||
return get_feature_at_point(*p);
|
||||
}
|
||||
}
|
||||
|
@ -108,40 +120,60 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
|||
std::clog << "dx_: " << dx_ << " dx: " << dx << " dy_: " << dy_ << "dy: " << dy << "\n";
|
||||
*/
|
||||
|
||||
CoordTransform t(raster_width_,raster_height_,raster_extent_,0,0);
|
||||
CoordTransform t(raster_width_, raster_height_, raster_extent_, 0, 0);
|
||||
box2d<double> intersect = raster_extent_.intersect(q.get_bbox());
|
||||
box2d<double> box = t.forward(intersect);
|
||||
|
||||
//size of resized output pixel in source image domain
|
||||
double margin_x = 1.0/(fabs(dx_)*boost::get<0>(q.resolution()));
|
||||
double margin_y = 1.0/(fabs(dy_)*boost::get<1>(q.resolution()));
|
||||
double margin_x = 1.0 / (fabs(dx_) * boost::get<0>(q.resolution()));
|
||||
double margin_y = 1.0 / (fabs(dy_) * boost::get<1>(q.resolution()));
|
||||
if (margin_x < 1)
|
||||
{
|
||||
margin_x = 1.0;
|
||||
}
|
||||
if (margin_y < 1)
|
||||
{
|
||||
margin_y = 1.0;
|
||||
}
|
||||
|
||||
//select minimum raster containing whole box
|
||||
int x_off = rint(box.minx() - margin_x);
|
||||
int y_off = rint(box.miny() - margin_y);
|
||||
int end_x = rint(box.maxx() + margin_x);
|
||||
int end_y = rint(box.maxy() + margin_y);
|
||||
|
||||
//clip to available data
|
||||
if (x_off < 0)
|
||||
{
|
||||
x_off = 0;
|
||||
}
|
||||
if (y_off < 0)
|
||||
{
|
||||
y_off = 0;
|
||||
}
|
||||
if (end_x > (int)raster_width_)
|
||||
{
|
||||
end_x = raster_width_;
|
||||
}
|
||||
if (end_y > (int)raster_height_)
|
||||
{
|
||||
end_y = raster_height_;
|
||||
}
|
||||
int width = end_x - x_off;
|
||||
int height = end_y - y_off;
|
||||
|
||||
// don't process almost invisible data
|
||||
if (box.width() < 0.5)
|
||||
{
|
||||
width = 0;
|
||||
}
|
||||
if (box.height() < 0.5)
|
||||
{
|
||||
height = 0;
|
||||
}
|
||||
|
||||
//calculate actual box2d of returned raster
|
||||
box2d<double> feature_raster_extent(x_off, y_off, x_off+width, y_off+height);
|
||||
box2d<double> feature_raster_extent(x_off, y_off, x_off + width, y_off + height);
|
||||
intersect = t.backward(feature_raster_extent);
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
|
@ -197,9 +229,11 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
|||
if (band_ > 0) // we are querying a single band
|
||||
{
|
||||
if (band_ > nbands_)
|
||||
{
|
||||
throw datasource_exception((boost::format("GDAL Plugin: '%d' is an invalid band, dataset only has '%d' bands\n") % band_ % nbands_).str());
|
||||
}
|
||||
|
||||
float *imageData = (float*)image.getBytes();
|
||||
float* imageData = (float*)image.getBytes();
|
||||
GDALRasterBand * band = dataset_.GetRasterBand(band_);
|
||||
int hasNoData;
|
||||
double nodata = band->GetNoDataValue(&hasNoData);
|
||||
|
@ -209,17 +243,18 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
|||
|
||||
feature->set_raster(mapnik::raster_ptr(boost::make_shared<mapnik::raster>(intersect,image)));
|
||||
if (hasNoData)
|
||||
feature->props()["NODATA"]=nodata;
|
||||
{
|
||||
feature->props()["NODATA"] = nodata;
|
||||
}
|
||||
}
|
||||
|
||||
else // working with all bands
|
||||
{
|
||||
for (int i = 0; i < nbands_; ++i)
|
||||
{
|
||||
GDALRasterBand * band = dataset_.GetRasterBand(i+1);
|
||||
GDALRasterBand * band = dataset_.GetRasterBand(i + 1);
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
get_overview_meta(band);
|
||||
get_overview_meta(band);
|
||||
#endif
|
||||
|
||||
GDALColorInterp color_interp = band->GetColorInterpretation();
|
||||
|
@ -263,7 +298,7 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
|||
#endif
|
||||
GDALColorTable *color_table = band->GetColorTable();
|
||||
|
||||
if ( color_table)
|
||||
if (color_table)
|
||||
{
|
||||
int count = color_table->GetColorEntryCount();
|
||||
#ifdef MAPNIK_DEBUG
|
||||
|
@ -303,33 +338,36 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
|||
float nodata = red->GetNoDataValue(&hasNoData);
|
||||
GDALColorTable *color_table = red->GetColorTable();
|
||||
|
||||
if (!alpha && hasNoData && !color_table)
|
||||
if (! alpha && hasNoData && ! color_table)
|
||||
{
|
||||
// first read the data in and create an alpha channel from the nodata values
|
||||
float *imageData = (float*)image.getBytes();
|
||||
float* imageData = (float*)image.getBytes();
|
||||
red->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||
imageData, image.width(), image.height(),
|
||||
GDT_Float32, 0, 0);
|
||||
imageData, image.width(), image.height(),
|
||||
GDT_Float32, 0, 0);
|
||||
|
||||
int len = image.width() * image.height();
|
||||
|
||||
for (int i=0; i<len; ++i)
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
if (nodata == imageData[i])
|
||||
*reinterpret_cast<unsigned *> (&imageData[i]) = 0;
|
||||
{
|
||||
*reinterpret_cast<unsigned *>(&imageData[i]) = 0;
|
||||
}
|
||||
else
|
||||
*reinterpret_cast<unsigned *> (&imageData[i]) = 0xFFFFFFFF;
|
||||
{
|
||||
*reinterpret_cast<unsigned *>(&imageData[i]) = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
red->RasterIO(GF_Read,x_off,y_off,width,height,image.getBytes() + 0,
|
||||
image.width(),image.height(),GDT_Byte,4,4*image.width());
|
||||
green->RasterIO(GF_Read,x_off,y_off,width,height,image.getBytes() + 1,
|
||||
image.width(),image.height(),GDT_Byte,4,4*image.width());
|
||||
blue->RasterIO(GF_Read,x_off,y_off,width,height,image.getBytes() + 2,
|
||||
image.width(),image.height(),GDT_Byte,4,4*image.width());
|
||||
|
||||
red->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 0,
|
||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
||||
green->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 1,
|
||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
||||
blue->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 2,
|
||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
||||
}
|
||||
else if (grey)
|
||||
{
|
||||
|
@ -338,36 +376,40 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
|||
#endif
|
||||
int hasNoData;
|
||||
float nodata = grey->GetNoDataValue(&hasNoData);
|
||||
GDALColorTable *color_table = grey->GetColorTable();
|
||||
GDALColorTable* color_table = grey->GetColorTable();
|
||||
|
||||
if (hasNoData && !color_table)
|
||||
if (hasNoData && ! color_table)
|
||||
{
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "\tno data value for layer: " << nodata << std::endl;
|
||||
#endif
|
||||
// first read the data in and create an alpha channel from the nodata values
|
||||
float *imageData = (float*)image.getBytes();
|
||||
float* imageData = (float*)image.getBytes();
|
||||
grey->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||
imageData, image.width(), image.height(),
|
||||
GDT_Float32, 0, 0);
|
||||
imageData, image.width(), image.height(),
|
||||
GDT_Float32, 0, 0);
|
||||
|
||||
int len = image.width() * image.height();
|
||||
|
||||
for (int i=0; i<len; ++i)
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
if (nodata == imageData[i])
|
||||
*reinterpret_cast<unsigned *> (&imageData[i]) = 0;
|
||||
{
|
||||
*reinterpret_cast<unsigned *>(&imageData[i]) = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*reinterpret_cast<unsigned *> (&imageData[i]) = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
grey->RasterIO(GF_Read,x_off,y_off,width,height,image.getBytes() + 0,
|
||||
image.width(),image.height(),GDT_Byte, 4, 4 * image.width());
|
||||
grey->RasterIO(GF_Read,x_off,y_off,width,height,image.getBytes() + 1,
|
||||
image.width(),image.height(),GDT_Byte, 4, 4 * image.width());
|
||||
grey->RasterIO(GF_Read,x_off,y_off,width,height,image.getBytes() + 2,
|
||||
image.width(),image.height(),GDT_Byte, 4, 4 * image.width());
|
||||
grey->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 0,
|
||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
||||
grey->RasterIO(GF_Read,x_off, y_off, width, height, image.getBytes() + 1,
|
||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
||||
grey->RasterIO(GF_Read,x_off, y_off, width, height, image.getBytes() + 2,
|
||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
||||
|
||||
if (color_table)
|
||||
{
|
||||
|
@ -380,8 +422,9 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
|||
for (unsigned x = 0; x < image.width(); ++x)
|
||||
{
|
||||
unsigned value = row[x] & 0xff;
|
||||
const GDALColorEntry *ce = color_table->GetColorEntry ( value );
|
||||
if (ce ){
|
||||
const GDALColorEntry *ce = color_table->GetColorEntry(value);
|
||||
if (ce )
|
||||
{
|
||||
// TODO - big endian support
|
||||
row[x] = (ce->c4 << 24)| (ce->c3 << 16) | (ce->c2 << 8) | (ce->c1) ;
|
||||
}
|
||||
|
@ -395,11 +438,11 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
|||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "GDAL Plugin: processing alpha band..." << std::endl;
|
||||
#endif
|
||||
alpha->RasterIO(GF_Read,x_off,y_off,width,height,image.getBytes() + 3,
|
||||
image.width(),image.height(),GDT_Byte,4,4*image.width());
|
||||
alpha->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 3,
|
||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
||||
}
|
||||
|
||||
feature->set_raster(mapnik::raster_ptr(new mapnik::raster(intersect,image)));
|
||||
feature->set_raster(mapnik::raster_ptr(new mapnik::raster(intersect, image)));
|
||||
}
|
||||
return feature;
|
||||
}
|
||||
|
@ -418,7 +461,7 @@ feature_ptr gdal_featureset::get_feature_at_point(mapnik::coord2d const& pt)
|
|||
double gt[6];
|
||||
dataset_.GetGeoTransform(gt);
|
||||
|
||||
double det = gt[1]*gt[5] - gt[2]*gt[4];
|
||||
double det = gt[1] * gt[5] - gt[2] * gt[4];
|
||||
// subtract half a pixel width & height because gdal coord reference
|
||||
// is the top-left corner of a pixel, not the center.
|
||||
double X = pt.x - gt[0] - gt[1]/2;
|
||||
|
@ -433,7 +476,7 @@ feature_ptr gdal_featureset::get_feature_at_point(mapnik::coord2d const& pt)
|
|||
std::clog << boost::format("GDAL Plugin: pt.x=%f pt.y=%f") % pt.x % pt.y << std::endl;
|
||||
std::clog << boost::format("GDAL Plugin: x=%f y=%f") % x % y << std::endl;
|
||||
#endif
|
||||
GDALRasterBand * band = dataset_.GetRasterBand(band_);
|
||||
GDALRasterBand* band = dataset_.GetRasterBand(band_);
|
||||
int hasNoData;
|
||||
double nodata = band->GetNoDataValue(&hasNoData);
|
||||
double value;
|
||||
|
@ -455,7 +498,7 @@ feature_ptr gdal_featureset::get_feature_at_point(mapnik::coord2d const& pt)
|
|||
}
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
void gdal_featureset::get_overview_meta(GDALRasterBand * band)
|
||||
void gdal_featureset::get_overview_meta(GDALRasterBand* band)
|
||||
{
|
||||
int band_overviews = band->GetOverviewCount();
|
||||
if (band_overviews > 0)
|
||||
|
@ -464,7 +507,7 @@ void gdal_featureset::get_overview_meta(GDALRasterBand * band)
|
|||
|
||||
for (int b = 0; b < band_overviews; b++)
|
||||
{
|
||||
GDALRasterBand * overview = band->GetOverview (b);
|
||||
GDALRasterBand * overview = band->GetOverview(b);
|
||||
std::clog << boost::format("GDAL Plugin: Overview=%d Width=%d Height=%d")
|
||||
% b % overview->GetXSize() % overview->GetYSize() << std::endl;
|
||||
}
|
||||
|
@ -476,7 +519,7 @@ void gdal_featureset::get_overview_meta(GDALRasterBand * band)
|
|||
|
||||
int bsx,bsy;
|
||||
double scale;
|
||||
band->GetBlockSize(&bsx,&bsy);
|
||||
band->GetBlockSize(&bsx, &bsy);
|
||||
scale = band->GetScale();
|
||||
|
||||
std::clog << boost::format("GDAL Plugin: Block=%dx%d Scale=%f Type=%s Color=%s") % bsx % bsy % scale
|
||||
|
@ -484,4 +527,3 @@ void gdal_featureset::get_overview_meta(GDALRasterBand * band)
|
|||
% GDALGetColorInterpretationName(band->GetColorInterpretation()) << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -33,33 +33,40 @@
|
|||
class GDALDataset;
|
||||
class GDALRasterBand;
|
||||
|
||||
typedef boost::variant<mapnik::query,mapnik::coord2d> gdal_query;
|
||||
typedef boost::variant<mapnik::query, mapnik::coord2d> gdal_query;
|
||||
|
||||
class gdal_featureset : public mapnik::Featureset
|
||||
{
|
||||
public:
|
||||
gdal_featureset(GDALDataset & dataset, int band, gdal_query q,
|
||||
mapnik::box2d<double> extent, double width, double height, int nbands,
|
||||
double dx, double dy, double filter_factor);
|
||||
virtual ~gdal_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
private:
|
||||
mapnik::feature_ptr get_feature(mapnik::query const& q);
|
||||
mapnik::feature_ptr get_feature_at_point(mapnik::coord2d const& p);
|
||||
public:
|
||||
gdal_featureset(GDALDataset& dataset,
|
||||
int band,
|
||||
gdal_query q,
|
||||
mapnik::box2d<double> extent,
|
||||
double width,
|
||||
double height,
|
||||
int nbands,
|
||||
double dx,
|
||||
double dy,
|
||||
double filter_factor);
|
||||
virtual ~gdal_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
private:
|
||||
mapnik::feature_ptr get_feature(mapnik::query const& q);
|
||||
mapnik::feature_ptr get_feature_at_point(mapnik::coord2d const& p);
|
||||
#ifdef MAPNIK_DEBUG
|
||||
void get_overview_meta(GDALRasterBand * band);
|
||||
void get_overview_meta(GDALRasterBand * band);
|
||||
#endif
|
||||
GDALDataset & dataset_;
|
||||
int band_;
|
||||
gdal_query gquery_;
|
||||
mapnik::box2d<double> raster_extent_;
|
||||
unsigned raster_width_;
|
||||
unsigned raster_height_;
|
||||
double dx_;
|
||||
double dy_;
|
||||
int nbands_;
|
||||
double filter_factor_;
|
||||
bool first_;
|
||||
GDALDataset & dataset_;
|
||||
int band_;
|
||||
gdal_query gquery_;
|
||||
mapnik::box2d<double> raster_extent_;
|
||||
unsigned raster_width_;
|
||||
unsigned raster_height_;
|
||||
double dx_;
|
||||
double dy_;
|
||||
int nbands_;
|
||||
double filter_factor_;
|
||||
bool first_;
|
||||
};
|
||||
|
||||
#endif // GDAL_FEATURESET_HPP
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -22,15 +22,15 @@
|
|||
// $Id$
|
||||
|
||||
// network
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
|
@ -72,26 +72,42 @@ std::list<kismet_network_data> knd_list;
|
|||
const unsigned int queue_size = 20;
|
||||
|
||||
kismet_datasource::kismet_datasource(parameters const& params, bool bind)
|
||||
: datasource(params),
|
||||
extent_(),
|
||||
extent_initialized_(false),
|
||||
type_(datasource::Vector),
|
||||
desc_(*params.get<std::string>("type"), *params.get<std::string>("encoding","utf-8"))
|
||||
: datasource(params),
|
||||
extent_(),
|
||||
extent_initialized_(false),
|
||||
type_(datasource::Vector),
|
||||
srs_("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"),
|
||||
desc_(*params.get<std::string>("type"), *params.get<std::string>("encoding","utf-8"))
|
||||
{
|
||||
boost::optional<std::string> host = params_.get<std::string>("host");
|
||||
if (host) {
|
||||
if (host)
|
||||
{
|
||||
host_ = *host;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
throw datasource_exception("Kismet Plugin: missing <host> parameter");
|
||||
}
|
||||
|
||||
boost::optional<unsigned int> port = params_.get<unsigned int>("port", 2501);
|
||||
if (port) port_ = *port;
|
||||
if (port)
|
||||
{
|
||||
port_ = *port;
|
||||
}
|
||||
|
||||
boost::optional<std::string> srs = params_.get<std::string>("srs");
|
||||
if (srs)
|
||||
{
|
||||
srs_ = *srs;
|
||||
}
|
||||
|
||||
boost::optional<std::string> ext = params_.get<std::string>("extent");
|
||||
if (ext) extent_initialized_ = extent_.from_string(*ext);
|
||||
if (ext)
|
||||
{
|
||||
extent_initialized_ = extent_.from_string(*ext);
|
||||
}
|
||||
|
||||
kismet_thread.reset (new boost::thread (boost::bind (&kismet_datasource::run, this, host_, port_)));
|
||||
kismet_thread.reset(new boost::thread(boost::bind(&kismet_datasource::run, this, host_, port_)));
|
||||
|
||||
if (bind)
|
||||
{
|
||||
|
@ -122,7 +138,7 @@ int kismet_datasource::type() const
|
|||
|
||||
box2d<double> kismet_datasource::envelope() const
|
||||
{
|
||||
if (!is_bound_) bind();
|
||||
if (! is_bound_) bind();
|
||||
return extent_;
|
||||
}
|
||||
|
||||
|
@ -133,15 +149,17 @@ layer_descriptor kismet_datasource::get_descriptor() const
|
|||
|
||||
featureset_ptr kismet_datasource::features(query const& q) const
|
||||
{
|
||||
if (!is_bound_) bind();
|
||||
if (! is_bound_) bind();
|
||||
|
||||
//cout << "kismet_datasource::features()" << endl;
|
||||
// std::clog << "kismet_datasource::features()" << endl;
|
||||
|
||||
// TODO: use box2d to filter bbox before adding to featureset_ptr
|
||||
//mapnik::box2d<double> const& e = q.get_bbox();
|
||||
// mapnik::box2d<double> const& e = q.get_bbox();
|
||||
|
||||
boost::mutex::scoped_lock lock(knd_list_mutex);
|
||||
return boost::make_shared<kismet_featureset>(knd_list, desc_.get_encoding());
|
||||
return boost::make_shared<kismet_featureset>(knd_list,
|
||||
srs_,
|
||||
desc_.get_encoding());
|
||||
|
||||
// TODO: if illegal:
|
||||
// return featureset_ptr();
|
||||
|
@ -149,14 +167,14 @@ featureset_ptr kismet_datasource::features(query const& q) const
|
|||
|
||||
featureset_ptr kismet_datasource::features_at_point(coord2d const& pt) const
|
||||
{
|
||||
if (!is_bound_) bind();
|
||||
if (! is_bound_) bind();
|
||||
|
||||
//cout << "kismet_datasource::features_at_point()" << endl;
|
||||
// std::clog << "kismet_datasource::features_at_point()" << endl;
|
||||
|
||||
return featureset_ptr();
|
||||
}
|
||||
|
||||
void kismet_datasource::run (const std::string &ip_host, const unsigned int port)
|
||||
void kismet_datasource::run(const std::string& ip_host, const unsigned int port)
|
||||
{
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "Kismet Plugin: enter run" << std::endl;
|
||||
|
@ -169,18 +187,18 @@ void kismet_datasource::run (const std::string &ip_host, const unsigned int port
|
|||
char buffer[MAX_TCP_BUFFER]; // TCP data send from kismet_server
|
||||
std::string command;
|
||||
|
||||
if (inet_aton(ip_host.c_str (), &inadr))
|
||||
if (inet_aton(ip_host.c_str(), &inadr))
|
||||
{
|
||||
host = gethostbyaddr((char *) &inadr, sizeof(inadr), AF_INET);
|
||||
host = gethostbyaddr((char*)&inadr, sizeof(inadr), AF_INET);
|
||||
}
|
||||
else
|
||||
{
|
||||
host = gethostbyname(ip_host.c_str ());
|
||||
host = gethostbyname(ip_host.c_str());
|
||||
}
|
||||
|
||||
if (host == NULL)
|
||||
{
|
||||
herror ("Kismet Plugin: Error while searching host");
|
||||
std::cerr << "Kismet Plugin: error while searching host" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -188,13 +206,13 @@ void kismet_datasource::run (const std::string &ip_host, const unsigned int port
|
|||
sock_addr.sin_port = htons(port);
|
||||
memcpy(&sock_addr.sin_addr, host->h_addr_list[0], sizeof(sock_addr.sin_addr));
|
||||
|
||||
if ( (sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
|
||||
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
std::cerr << "Kismet Plugin: error while creating socket" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (connect(sockfd, (struct sockaddr *) &sock_addr, sizeof(sock_addr)))
|
||||
if (connect(sockfd, (struct sockaddr*) &sock_addr, sizeof(sock_addr)))
|
||||
{
|
||||
std::cerr << "KISMET Plugin: Error while connecting" << std::endl;
|
||||
return;
|
||||
|
@ -202,9 +220,10 @@ void kismet_datasource::run (const std::string &ip_host, const unsigned int port
|
|||
|
||||
command = "!1 ENABLE NETWORK ssid,bssid,wep,bestlat,bestlon\n";
|
||||
|
||||
if (write(sockfd, command.c_str (), command.length ()) != (signed) command.length ())
|
||||
if (write(sockfd, command.c_str(), command.length()) != (signed)command.length())
|
||||
{
|
||||
std::cerr << "KISMET Plugin: Error sending command to " << ip_host << std::endl;
|
||||
|
||||
close(sockfd);
|
||||
return;
|
||||
}
|
||||
|
@ -219,10 +238,10 @@ void kismet_datasource::run (const std::string &ip_host, const unsigned int port
|
|||
// assert is called. Needs to be analyzed!
|
||||
while ((n = read(sockfd, buffer, sizeof(buffer))) > 0)
|
||||
{
|
||||
assert (n < MAX_TCP_BUFFER);
|
||||
assert(n < MAX_TCP_BUFFER);
|
||||
|
||||
buffer[n] = '\0';
|
||||
std::string bufferObj (buffer); // TCP data send from kismet_server as STL string
|
||||
std::string bufferObj(buffer); // TCP data send from kismet_server as STL string
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "Kismet Plugin: buffer_obj=" << bufferObj << "[END]" << std::endl;
|
||||
|
@ -233,10 +252,10 @@ void kismet_datasource::run (const std::string &ip_host, const unsigned int port
|
|||
std::string kismet_line; // contains a line from kismet_server
|
||||
do
|
||||
{
|
||||
found = bufferObj.find ('\n', search_start);
|
||||
found = bufferObj.find('\n', search_start);
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
kismet_line.assign (bufferObj, search_start, found - search_start);
|
||||
kismet_line.assign(bufferObj, search_start, found - search_start);
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "Kismet Plugin: line=" << kismet_line << " [ENDL]" << std::endl;
|
||||
|
@ -245,7 +264,7 @@ void kismet_datasource::run (const std::string &ip_host, const unsigned int port
|
|||
int param_number = 5; // the number of parameters to parse
|
||||
|
||||
// Attention: string length specified to the constant!
|
||||
if (sscanf (kismet_line.c_str (),
|
||||
if (sscanf (kismet_line.c_str(),
|
||||
KISMET_COMMAND,
|
||||
ssid,
|
||||
bssid,
|
||||
|
@ -255,20 +274,20 @@ void kismet_datasource::run (const std::string &ip_host, const unsigned int port
|
|||
{
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "Kismet Plugin: ssid=" << ssid << ", bssid=" << bssid
|
||||
<< ", crypt=" << crypt << ", bestlat=" << bestlat << ", bestlon=" << bestlon << std::endl;
|
||||
<< ", crypt=" << crypt << ", bestlat=" << bestlat << ", bestlon=" << bestlon << std::endl;
|
||||
#endif
|
||||
|
||||
kismet_network_data knd (ssid, bssid, bestlat, bestlon, crypt);
|
||||
kismet_network_data knd(ssid, bssid, bestlat, bestlon, crypt);
|
||||
|
||||
boost::mutex::scoped_lock lock(knd_list_mutex);
|
||||
|
||||
// the queue only grows to a max size
|
||||
if (knd_list.size () >= queue_size)
|
||||
{
|
||||
knd_list.pop_front ();
|
||||
knd_list.pop_front();
|
||||
}
|
||||
|
||||
knd_list.push_back (knd);
|
||||
knd_list.push_back(knd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -43,27 +43,28 @@
|
|||
|
||||
class kismet_datasource : public mapnik::datasource
|
||||
{
|
||||
public:
|
||||
kismet_datasource(mapnik::parameters const& params, bool bind=true);
|
||||
virtual ~kismet_datasource ();
|
||||
int type() const;
|
||||
static std::string name();
|
||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||
mapnik::box2d<double> envelope() const;
|
||||
mapnik::layer_descriptor get_descriptor() const;
|
||||
void bind() const;
|
||||
private:
|
||||
void run (const std::string &host, const unsigned int port);
|
||||
public:
|
||||
kismet_datasource(mapnik::parameters const& params, bool bind = true);
|
||||
virtual ~kismet_datasource ();
|
||||
int type() const;
|
||||
static std::string name();
|
||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||
mapnik::box2d<double> envelope() const;
|
||||
mapnik::layer_descriptor get_descriptor() const;
|
||||
void bind() const;
|
||||
|
||||
mapnik::box2d<double> extent_;
|
||||
bool extent_initialized_;
|
||||
std::string host_;
|
||||
unsigned int port_;
|
||||
int type_;
|
||||
mapnik::layer_descriptor desc_;
|
||||
boost::shared_ptr<boost::thread> kismet_thread;
|
||||
private:
|
||||
void run (const std::string& host, const unsigned int port);
|
||||
|
||||
mapnik::box2d<double> extent_;
|
||||
bool extent_initialized_;
|
||||
std::string host_;
|
||||
unsigned int port_;
|
||||
int type_;
|
||||
std::string srs_;
|
||||
mapnik::layer_descriptor desc_;
|
||||
boost::shared_ptr<boost::thread> kismet_thread;
|
||||
};
|
||||
|
||||
|
||||
#endif // KISMET_DATASOURCE_HPP
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -41,13 +41,14 @@ using mapnik::geometry_utils;
|
|||
using mapnik::transcoder;
|
||||
using mapnik::feature_factory;
|
||||
|
||||
kismet_featureset::kismet_featureset(const std::list<kismet_network_data> &knd_list,
|
||||
kismet_featureset::kismet_featureset(const std::list<kismet_network_data>& knd_list,
|
||||
std::string const& srs,
|
||||
std::string const& encoding)
|
||||
: knd_list_(knd_list),
|
||||
tr_(new transcoder(encoding)),
|
||||
feature_id_(1),
|
||||
knd_list_it(knd_list_.begin ()),
|
||||
source_("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
|
||||
knd_list_it(knd_list_.begin()),
|
||||
source_(srs)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -63,11 +64,11 @@ feature_ptr kismet_featureset::next()
|
|||
const std::string key = "internet_access";
|
||||
|
||||
std::string value;
|
||||
if (knd.crypt_ == crypt_none)
|
||||
if (knd.crypt() == crypt_none)
|
||||
{
|
||||
value = "wlan_uncrypted";
|
||||
}
|
||||
else if (knd.crypt_ == crypt_wep)
|
||||
else if (knd.crypt() == crypt_wep)
|
||||
{
|
||||
value = "wlan_wep";
|
||||
}
|
||||
|
@ -80,7 +81,7 @@ feature_ptr kismet_featureset::next()
|
|||
++feature_id_;
|
||||
|
||||
geometry_type* pt = new geometry_type(mapnik::Point);
|
||||
pt->move_to(knd.bestlon_, knd.bestlat_);
|
||||
pt->move_to(knd.bestlon(), knd.bestlat());
|
||||
feature->add_geometry(pt);
|
||||
|
||||
boost::put(*feature, key, tr_->transcode(value.c_str()));
|
||||
|
@ -92,4 +93,3 @@ feature_ptr kismet_featureset::next()
|
|||
|
||||
return feature_ptr();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -40,20 +40,21 @@
|
|||
|
||||
class kismet_featureset : public mapnik::Featureset
|
||||
{
|
||||
public:
|
||||
kismet_featureset(const std::list<kismet_network_data> &knd_list,
|
||||
std::string const& encoding);
|
||||
virtual ~kismet_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
|
||||
private:
|
||||
const std::list<kismet_network_data> &knd_list_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
mapnik::wkbFormat format_;
|
||||
bool multiple_geometries_;
|
||||
int feature_id_;
|
||||
std::list<kismet_network_data>::const_iterator knd_list_it;
|
||||
mapnik::projection source_;
|
||||
public:
|
||||
kismet_featureset(const std::list<kismet_network_data>& knd_list,
|
||||
std::string const& srs,
|
||||
std::string const& encoding);
|
||||
virtual ~kismet_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
|
||||
private:
|
||||
const std::list<kismet_network_data>& knd_list_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
mapnik::wkbFormat format_;
|
||||
bool multiple_geometries_;
|
||||
int feature_id_;
|
||||
std::list<kismet_network_data>::const_iterator knd_list_it;
|
||||
mapnik::projection source_;
|
||||
};
|
||||
|
||||
#endif // KISMET_FEATURESET_HPP
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -57,21 +57,56 @@ enum crypt_type
|
|||
|
||||
class kismet_network_data
|
||||
{
|
||||
public:
|
||||
kismet_network_data() : bestlat_(0), bestlon_(0), crypt_ (crypt_none) {}
|
||||
kismet_network_data(std::string ssid, std::string bssid,
|
||||
double bestlat, double bestlon, int crypt) :
|
||||
ssid_(ssid), bssid_(bssid),
|
||||
bestlat_(bestlat), bestlon_(bestlon),
|
||||
crypt_ (crypt)
|
||||
{}
|
||||
|
||||
std::string ssid_;
|
||||
std::string bssid_;
|
||||
double bestlat_;
|
||||
double bestlon_;
|
||||
int crypt_;
|
||||
public:
|
||||
kismet_network_data()
|
||||
: bestlat_(0), bestlon_(0), crypt_(crypt_none)
|
||||
{
|
||||
}
|
||||
|
||||
kismet_network_data(std::string ssid,
|
||||
std::string bssid,
|
||||
double bestlat,
|
||||
double bestlon,
|
||||
int crypt)
|
||||
: ssid_(ssid),
|
||||
bssid_(bssid),
|
||||
bestlat_(bestlat),
|
||||
bestlon_(bestlon),
|
||||
crypt_(crypt)
|
||||
{
|
||||
}
|
||||
|
||||
const std::string& ssid() const
|
||||
{
|
||||
return ssid_;
|
||||
}
|
||||
|
||||
const std::string& bssid() const
|
||||
{
|
||||
return bssid_;
|
||||
}
|
||||
|
||||
double bestlat() const
|
||||
{
|
||||
return bestlat_;
|
||||
}
|
||||
|
||||
double bestlon() const
|
||||
{
|
||||
return bestlon_;
|
||||
}
|
||||
|
||||
int crypt() const
|
||||
{
|
||||
return crypt_;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string ssid_;
|
||||
std::string bssid_;
|
||||
double bestlat_;
|
||||
double bestlon_;
|
||||
int crypt_;
|
||||
};
|
||||
|
||||
#endif //KISMET_TYPES_HPP
|
||||
|
||||
#endif // KISMET_TYPES_HPP
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -63,30 +63,29 @@ using oracle::occi::SQLException;
|
|||
using oracle::occi::Type;
|
||||
using oracle::occi::StatelessConnectionPool;
|
||||
|
||||
const std::string occi_datasource::METADATA_TABLE="USER_SDO_GEOM_METADATA";
|
||||
const std::string occi_datasource::METADATA_TABLE = "USER_SDO_GEOM_METADATA";
|
||||
|
||||
DATASOURCE_PLUGIN(occi_datasource)
|
||||
|
||||
|
||||
occi_datasource::occi_datasource(parameters const& params, bool bind)
|
||||
: datasource (params),
|
||||
type_(datasource::Vector),
|
||||
fields_(*params_.get<std::string>("fields","*")),
|
||||
geometry_field_(*params_.get<std::string>("geometry_field","")),
|
||||
srid_initialized_(false),
|
||||
extent_initialized_(false),
|
||||
desc_(*params_.get<std::string>("type"), *params_.get<std::string>("encoding","utf-8")),
|
||||
row_limit_(*params_.get<int>("row_limit",0)),
|
||||
row_prefetch_(*params_.get<int>("row_prefetch",100)),
|
||||
pool_(0),
|
||||
conn_(0)
|
||||
: datasource (params),
|
||||
type_(datasource::Vector),
|
||||
fields_(*params_.get<std::string>("fields", "*")),
|
||||
geometry_field_(*params_.get<std::string>("geometry_field", "")),
|
||||
srid_initialized_(false),
|
||||
extent_initialized_(false),
|
||||
desc_(*params_.get<std::string>("type"), *params_.get<std::string>("encoding", "utf-8")),
|
||||
row_limit_(*params_.get<int>("row_limit", 0)),
|
||||
row_prefetch_(*params_.get<int>("row_prefetch", 100)),
|
||||
pool_(0),
|
||||
conn_(0)
|
||||
{
|
||||
if (! params_.get<std::string>("user")) throw datasource_exception("OCCI Plugin: no <user> specified");
|
||||
if (! params_.get<std::string>("password")) throw datasource_exception("OCCI Plugin: no <password> specified");
|
||||
if (! params_.get<std::string>("host")) throw datasource_exception("OCCI Plugin: no <host> string specified");
|
||||
|
||||
boost::optional<std::string> table = params_.get<std::string>("table");
|
||||
if (!table)
|
||||
if (! table)
|
||||
{
|
||||
throw datasource_exception("OCCI Plugin: no <table> parameter specified");
|
||||
}
|
||||
|
@ -124,12 +123,16 @@ occi_datasource::~occi_datasource()
|
|||
if (use_connection_pool_)
|
||||
{
|
||||
if (pool_ != 0)
|
||||
env->terminateStatelessConnectionPool (pool_, StatelessConnectionPool::SPD_FORCE);
|
||||
{
|
||||
env->terminateStatelessConnectionPool(pool_, StatelessConnectionPool::SPD_FORCE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (conn_ != 0)
|
||||
{
|
||||
env->terminateConnection(conn_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -149,12 +152,12 @@ void occi_datasource::bind() const
|
|||
*params_.get<std::string>("user"),
|
||||
*params_.get<std::string>("password"),
|
||||
*params_.get<std::string>("host"),
|
||||
*params_.get<int>("max_size",10),
|
||||
*params_.get<int>("initial_size",1),
|
||||
*params_.get<int>("max_size", 10),
|
||||
*params_.get<int>("initial_size", 1),
|
||||
1,
|
||||
StatelessConnectionPool::HOMOGENEOUS);
|
||||
}
|
||||
catch (SQLException &ex)
|
||||
catch (SQLException& ex)
|
||||
{
|
||||
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
|
||||
}
|
||||
|
@ -170,7 +173,7 @@ void occi_datasource::bind() const
|
|||
*params_.get<std::string>("password"),
|
||||
*params_.get<std::string>("host"));
|
||||
}
|
||||
catch (SQLException &ex)
|
||||
catch (SQLException& ex)
|
||||
{
|
||||
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
|
||||
}
|
||||
|
@ -186,7 +189,9 @@ void occi_datasource::bind() const
|
|||
s << " LOWER(table_name) = LOWER('" << table_name << "')";
|
||||
|
||||
if (geometry_field_ != "")
|
||||
{
|
||||
s << " AND LOWER(column_name) = LOWER('" << geometry_field_ << "')";
|
||||
}
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OCCI Plugin: " << s.str() << std::endl;
|
||||
|
@ -198,7 +203,7 @@ void occi_datasource::bind() const
|
|||
if (use_connection_pool_) conn.set_pool(pool_);
|
||||
else conn.set_connection(conn_, false);
|
||||
|
||||
ResultSet* rs = conn.execute_query (s.str());
|
||||
ResultSet* rs = conn.execute_query(s.str());
|
||||
if (rs && rs->next ())
|
||||
{
|
||||
if (! srid_initialized_)
|
||||
|
@ -213,7 +218,7 @@ void occi_datasource::bind() const
|
|||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException &ex)
|
||||
catch (SQLException& ex)
|
||||
{
|
||||
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
|
||||
}
|
||||
|
@ -234,7 +239,7 @@ void occi_datasource::bind() const
|
|||
if (use_connection_pool_) conn.set_pool(pool_);
|
||||
else conn.set_connection(conn_, false);
|
||||
|
||||
ResultSet* rs = conn.execute_query (s.str());
|
||||
ResultSet* rs = conn.execute_query(s.str());
|
||||
if (rs)
|
||||
{
|
||||
std::vector<MetaData> listOfColumns = rs->getColumnListMetaData();
|
||||
|
@ -317,20 +322,22 @@ void occi_datasource::bind() const
|
|||
case oracle::occi::OCCI_SQLT_BLOB:
|
||||
case oracle::occi::OCCI_SQLT_RSET:
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OCCI Plugin: unsupported datatype " << occi_enums::resolve_datatype(type_oid)
|
||||
<< " (type_oid=" << type_oid << ")" << std::endl;
|
||||
std::clog << "OCCI Plugin: unsupported datatype "
|
||||
<< occi_enums::resolve_datatype(type_oid)
|
||||
<< " (type_oid=" << type_oid << ")" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OCCI Plugin: unknown datatype (type_oid=" << type_oid << ")" << std::endl;
|
||||
std::clog << "OCCI Plugin: unknown datatype "
|
||||
<< "(type_oid=" << type_oid << ")" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException &ex)
|
||||
catch (SQLException& ex)
|
||||
{
|
||||
throw datasource_exception(ex.getMessage());
|
||||
}
|
||||
|
@ -352,11 +359,12 @@ int occi_datasource::type() const
|
|||
box2d<double> occi_datasource::envelope() const
|
||||
{
|
||||
if (extent_initialized_) return extent_;
|
||||
if (!is_bound_) bind();
|
||||
if (! is_bound_) bind();
|
||||
|
||||
double lox = 0.0, loy = 0.0, hix = 0.0, hiy = 0.0;
|
||||
|
||||
boost::optional<mapnik::boolean> estimate_extent = params_.get<mapnik::boolean>("estimate_extent",false);
|
||||
boost::optional<mapnik::boolean> estimate_extent =
|
||||
params_.get<mapnik::boolean>("estimate_extent",false);
|
||||
|
||||
if (estimate_extent && *estimate_extent)
|
||||
{
|
||||
|
@ -375,8 +383,8 @@ box2d<double> occi_datasource::envelope() const
|
|||
if (use_connection_pool_) conn.set_pool(pool_);
|
||||
else conn.set_connection(conn_, false);
|
||||
|
||||
ResultSet* rs = conn.execute_query (s.str());
|
||||
if (rs && rs->next ())
|
||||
ResultSet* rs = conn.execute_query(s.str());
|
||||
if (rs && rs->next())
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -384,16 +392,16 @@ box2d<double> occi_datasource::envelope() const
|
|||
loy = lexical_cast<double>(rs->getDouble(2));
|
||||
hix = lexical_cast<double>(rs->getDouble(3));
|
||||
hiy = lexical_cast<double>(rs->getDouble(4));
|
||||
extent_.init (lox,loy,hix,hiy);
|
||||
extent_.init(lox, loy, hix, hiy);
|
||||
extent_initialized_ = true;
|
||||
}
|
||||
catch (bad_lexical_cast &ex)
|
||||
catch (bad_lexical_cast& ex)
|
||||
{
|
||||
std::clog << "OCCI Plugin: " << ex.what() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException &ex)
|
||||
catch (SQLException& ex)
|
||||
{
|
||||
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
|
||||
}
|
||||
|
@ -421,63 +429,65 @@ box2d<double> occi_datasource::envelope() const
|
|||
if (use_connection_pool_) conn.set_pool(pool_);
|
||||
else conn.set_connection(conn_, false);
|
||||
|
||||
ResultSet* rs = conn.execute_query (s.str());
|
||||
ResultSet* rs = conn.execute_query(s.str());
|
||||
if (rs)
|
||||
{
|
||||
if (rs->next ())
|
||||
if (rs->next())
|
||||
{
|
||||
try
|
||||
{
|
||||
lox = lexical_cast<double>(rs->getDouble(1));
|
||||
hix = lexical_cast<double>(rs->getDouble(2));
|
||||
}
|
||||
catch (bad_lexical_cast &ex)
|
||||
catch (bad_lexical_cast& ex)
|
||||
{
|
||||
std::clog << "OCCI Plugin: " << ex.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (rs->next ())
|
||||
if (rs->next())
|
||||
{
|
||||
try
|
||||
{
|
||||
loy = lexical_cast<double>(rs->getDouble(1));
|
||||
hiy = lexical_cast<double>(rs->getDouble(2));
|
||||
}
|
||||
catch (bad_lexical_cast &ex)
|
||||
catch (bad_lexical_cast& ex)
|
||||
{
|
||||
std::clog << "OCCI Plugin: " << ex.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
extent_.init (lox,loy,hix,hiy);
|
||||
extent_.init(lox, loy, hix, hiy);
|
||||
extent_initialized_ = true;
|
||||
}
|
||||
}
|
||||
catch (SQLException &ex)
|
||||
catch (SQLException& ex)
|
||||
{
|
||||
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (! extent_initialized_)
|
||||
{
|
||||
throw datasource_exception("OCCI Plugin: unable to determine the extent of a <occi> table");
|
||||
}
|
||||
|
||||
return extent_;
|
||||
}
|
||||
|
||||
layer_descriptor occi_datasource::get_descriptor() const
|
||||
{
|
||||
if (!is_bound_) bind();
|
||||
if (! is_bound_) bind();
|
||||
|
||||
return desc_;
|
||||
}
|
||||
|
||||
featureset_ptr occi_datasource::features(query const& q) const
|
||||
{
|
||||
if (!is_bound_) bind();
|
||||
if (! is_bound_) bind();
|
||||
|
||||
box2d<double> const& box=q.get_bbox();
|
||||
box2d<double> const& box = q.get_bbox();
|
||||
|
||||
std::ostringstream s;
|
||||
s << "SELECT " << geometry_field_;
|
||||
|
@ -492,7 +502,7 @@ featureset_ptr occi_datasource::features(query const& q) const
|
|||
|
||||
s << " FROM ";
|
||||
|
||||
std::string query (table_);
|
||||
std::string query(table_);
|
||||
std::string table_name = mapnik::table_from_sql(query);
|
||||
|
||||
if (use_spatial_index_)
|
||||
|
@ -549,24 +559,24 @@ featureset_ptr occi_datasource::features(query const& q) const
|
|||
#endif
|
||||
|
||||
return boost::make_shared<occi_featureset>(pool_,
|
||||
conn_,
|
||||
s.str(),
|
||||
desc_.get_encoding(),
|
||||
multiple_geometries_,
|
||||
use_connection_pool_,
|
||||
row_prefetch_,
|
||||
props.size());
|
||||
conn_,
|
||||
s.str(),
|
||||
desc_.get_encoding(),
|
||||
multiple_geometries_,
|
||||
use_connection_pool_,
|
||||
row_prefetch_,
|
||||
props.size());
|
||||
}
|
||||
|
||||
featureset_ptr occi_datasource::features_at_point(coord2d const& pt) const
|
||||
{
|
||||
if (!is_bound_) bind();
|
||||
if (! is_bound_) bind();
|
||||
|
||||
std::ostringstream s;
|
||||
s << "SELECT " << geometry_field_;
|
||||
std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin();
|
||||
std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end();
|
||||
unsigned size=0;
|
||||
unsigned size = 0;
|
||||
while (itr != end)
|
||||
{
|
||||
s << ", " << itr->get_name();
|
||||
|
@ -576,7 +586,7 @@ featureset_ptr occi_datasource::features_at_point(coord2d const& pt) const
|
|||
|
||||
s << " FROM ";
|
||||
|
||||
std::string query (table_);
|
||||
std::string query(table_);
|
||||
std::string table_name = mapnik::table_from_sql(query);
|
||||
|
||||
if (use_spatial_index_)
|
||||
|
@ -593,7 +603,7 @@ featureset_ptr occi_datasource::features_at_point(coord2d const& pt) const
|
|||
{
|
||||
boost::algorithm::ireplace_first(query, "WHERE", spatial_sql.str() + " AND ");
|
||||
}
|
||||
else if (boost::algorithm::ifind_first(query,table_name))
|
||||
else if (boost::algorithm::ifind_first(query, table_name))
|
||||
{
|
||||
boost::algorithm::ireplace_first(query, table_name, table_name + " " + spatial_sql.str());
|
||||
}
|
||||
|
@ -632,12 +642,11 @@ featureset_ptr occi_datasource::features_at_point(coord2d const& pt) const
|
|||
#endif
|
||||
|
||||
return boost::make_shared<occi_featureset>(pool_,
|
||||
conn_,
|
||||
s.str(),
|
||||
desc_.get_encoding(),
|
||||
multiple_geometries_,
|
||||
use_connection_pool_,
|
||||
row_prefetch_,
|
||||
size);
|
||||
conn_,
|
||||
s.str(),
|
||||
desc_.get_encoding(),
|
||||
multiple_geometries_,
|
||||
use_connection_pool_,
|
||||
row_prefetch_,
|
||||
size);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -38,35 +38,35 @@
|
|||
|
||||
class occi_datasource : public mapnik::datasource
|
||||
{
|
||||
public:
|
||||
occi_datasource(mapnik::parameters const& params, bool bind=true);
|
||||
virtual ~occi_datasource ();
|
||||
int type() const;
|
||||
static std::string name();
|
||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||
mapnik::box2d<double> envelope() const;
|
||||
mapnik::layer_descriptor get_descriptor() const;
|
||||
void bind() const;
|
||||
private:
|
||||
int type_;
|
||||
mutable std::string table_;
|
||||
mutable std::string fields_;
|
||||
mutable std::string geometry_field_;
|
||||
mutable int srid_;
|
||||
mutable bool srid_initialized_;
|
||||
mutable bool extent_initialized_;
|
||||
mutable mapnik::box2d<double> extent_;
|
||||
mutable mapnik::layer_descriptor desc_;
|
||||
int row_limit_;
|
||||
int row_prefetch_;
|
||||
mutable oracle::occi::StatelessConnectionPool* pool_;
|
||||
mutable oracle::occi::Connection* conn_;
|
||||
bool use_connection_pool_;
|
||||
bool multiple_geometries_;
|
||||
bool use_spatial_index_;
|
||||
static const std::string METADATA_TABLE;
|
||||
public:
|
||||
occi_datasource(mapnik::parameters const& params, bool bind = true);
|
||||
virtual ~occi_datasource ();
|
||||
int type() const;
|
||||
static std::string name();
|
||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||
mapnik::box2d<double> envelope() const;
|
||||
mapnik::layer_descriptor get_descriptor() const;
|
||||
void bind() const;
|
||||
|
||||
private:
|
||||
int type_;
|
||||
mutable std::string table_;
|
||||
mutable std::string fields_;
|
||||
mutable std::string geometry_field_;
|
||||
mutable int srid_;
|
||||
mutable bool srid_initialized_;
|
||||
mutable bool extent_initialized_;
|
||||
mutable mapnik::box2d<double> extent_;
|
||||
mutable mapnik::layer_descriptor desc_;
|
||||
int row_limit_;
|
||||
int row_prefetch_;
|
||||
mutable oracle::occi::StatelessConnectionPool* pool_;
|
||||
mutable oracle::occi::Connection* conn_;
|
||||
bool use_connection_pool_;
|
||||
bool multiple_geometries_;
|
||||
bool use_spatial_index_;
|
||||
static const std::string METADATA_TABLE;
|
||||
};
|
||||
|
||||
|
||||
#endif // OCCI_DATASOURCE_HPP
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -64,19 +64,23 @@ occi_featureset::occi_featureset(StatelessConnectionPool* pool,
|
|||
bool use_connection_pool,
|
||||
unsigned prefetch_rows,
|
||||
unsigned num_attrs)
|
||||
: tr_(new transcoder(encoding)),
|
||||
multiple_geometries_(multiple_geometries),
|
||||
num_attrs_(num_attrs),
|
||||
feature_id_(1)
|
||||
: tr_(new transcoder(encoding)),
|
||||
multiple_geometries_(multiple_geometries),
|
||||
num_attrs_(num_attrs),
|
||||
feature_id_(1)
|
||||
{
|
||||
if (use_connection_pool)
|
||||
{
|
||||
conn_.set_pool(pool);
|
||||
}
|
||||
else
|
||||
{
|
||||
conn_.set_connection(conn, false);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
rs_ = conn_.execute_query (sqlstring, prefetch_rows);
|
||||
rs_ = conn_.execute_query(sqlstring, prefetch_rows);
|
||||
}
|
||||
catch (SQLException &ex)
|
||||
{
|
||||
|
@ -95,10 +99,10 @@ feature_ptr occi_featureset::next()
|
|||
feature_ptr feature(feature_factory::create(feature_id_));
|
||||
++feature_id_;
|
||||
|
||||
boost::scoped_ptr<SDOGeometry> geom (dynamic_cast<SDOGeometry*> (rs_->getObject(1)));
|
||||
boost::scoped_ptr<SDOGeometry> geom(dynamic_cast<SDOGeometry*>(rs_->getObject(1)));
|
||||
if (geom.get())
|
||||
{
|
||||
convert_geometry (geom.get(), feature, multiple_geometries_);
|
||||
convert_geometry(geom.get(), feature, multiple_geometries_);
|
||||
}
|
||||
|
||||
std::vector<MetaData> listOfColumns = rs_->getColumnListMetaData();
|
||||
|
@ -120,75 +124,77 @@ feature_ptr occi_featureset::next()
|
|||
|
||||
switch (type_oid)
|
||||
{
|
||||
case oracle::occi::OCCIBOOL:
|
||||
case oracle::occi::OCCIINT:
|
||||
case oracle::occi::OCCIUNSIGNED_INT:
|
||||
case oracle::occi::OCCIROWID:
|
||||
boost::put(*feature,fld_name,rs_->getInt (i + 1));
|
||||
break;
|
||||
case oracle::occi::OCCIFLOAT:
|
||||
case oracle::occi::OCCIBFLOAT:
|
||||
case oracle::occi::OCCIDOUBLE:
|
||||
case oracle::occi::OCCIBDOUBLE:
|
||||
case oracle::occi::OCCINUMBER:
|
||||
case oracle::occi::OCCI_SQLT_NUM:
|
||||
boost::put(*feature,fld_name,rs_->getDouble (i + 1));
|
||||
break;
|
||||
case oracle::occi::OCCICHAR:
|
||||
case oracle::occi::OCCISTRING:
|
||||
case oracle::occi::OCCI_SQLT_AFC:
|
||||
case oracle::occi::OCCI_SQLT_AVC:
|
||||
case oracle::occi::OCCI_SQLT_CHR:
|
||||
case oracle::occi::OCCI_SQLT_LVC:
|
||||
case oracle::occi::OCCI_SQLT_RDD:
|
||||
case oracle::occi::OCCI_SQLT_STR:
|
||||
case oracle::occi::OCCI_SQLT_VCS:
|
||||
case oracle::occi::OCCI_SQLT_VNU:
|
||||
case oracle::occi::OCCI_SQLT_VBI:
|
||||
case oracle::occi::OCCI_SQLT_VST:
|
||||
boost::put(*feature,fld_name,(UnicodeString) tr_->transcode (rs_->getString (i + 1).c_str()));
|
||||
break;
|
||||
case oracle::occi::OCCIDATE:
|
||||
case oracle::occi::OCCITIMESTAMP:
|
||||
case oracle::occi::OCCIINTERVALDS:
|
||||
case oracle::occi::OCCIINTERVALYM:
|
||||
case oracle::occi::OCCI_SQLT_DAT:
|
||||
case oracle::occi::OCCI_SQLT_DATE:
|
||||
case oracle::occi::OCCI_SQLT_TIME:
|
||||
case oracle::occi::OCCI_SQLT_TIME_TZ:
|
||||
case oracle::occi::OCCI_SQLT_TIMESTAMP:
|
||||
case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ:
|
||||
case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ:
|
||||
case oracle::occi::OCCI_SQLT_INTERVAL_YM:
|
||||
case oracle::occi::OCCI_SQLT_INTERVAL_DS:
|
||||
case oracle::occi::OCCIANYDATA:
|
||||
case oracle::occi::OCCIBLOB:
|
||||
case oracle::occi::OCCIBFILE:
|
||||
case oracle::occi::OCCIBYTES:
|
||||
case oracle::occi::OCCICLOB:
|
||||
case oracle::occi::OCCIVECTOR:
|
||||
case oracle::occi::OCCIMETADATA:
|
||||
case oracle::occi::OCCIPOBJECT:
|
||||
case oracle::occi::OCCIREF:
|
||||
case oracle::occi::OCCIREFANY:
|
||||
case oracle::occi::OCCISTREAM:
|
||||
case oracle::occi::OCCICURSOR:
|
||||
case oracle::occi::OCCI_SQLT_FILE:
|
||||
case oracle::occi::OCCI_SQLT_CFILE:
|
||||
case oracle::occi::OCCI_SQLT_REF:
|
||||
case oracle::occi::OCCI_SQLT_CLOB:
|
||||
case oracle::occi::OCCI_SQLT_BLOB:
|
||||
case oracle::occi::OCCI_SQLT_RSET:
|
||||
case oracle::occi::OCCIBOOL:
|
||||
case oracle::occi::OCCIINT:
|
||||
case oracle::occi::OCCIUNSIGNED_INT:
|
||||
case oracle::occi::OCCIROWID:
|
||||
boost::put(*feature,fld_name,rs_->getInt (i + 1));
|
||||
break;
|
||||
case oracle::occi::OCCIFLOAT:
|
||||
case oracle::occi::OCCIBFLOAT:
|
||||
case oracle::occi::OCCIDOUBLE:
|
||||
case oracle::occi::OCCIBDOUBLE:
|
||||
case oracle::occi::OCCINUMBER:
|
||||
case oracle::occi::OCCI_SQLT_NUM:
|
||||
boost::put(*feature,fld_name,rs_->getDouble (i + 1));
|
||||
break;
|
||||
case oracle::occi::OCCICHAR:
|
||||
case oracle::occi::OCCISTRING:
|
||||
case oracle::occi::OCCI_SQLT_AFC:
|
||||
case oracle::occi::OCCI_SQLT_AVC:
|
||||
case oracle::occi::OCCI_SQLT_CHR:
|
||||
case oracle::occi::OCCI_SQLT_LVC:
|
||||
case oracle::occi::OCCI_SQLT_RDD:
|
||||
case oracle::occi::OCCI_SQLT_STR:
|
||||
case oracle::occi::OCCI_SQLT_VCS:
|
||||
case oracle::occi::OCCI_SQLT_VNU:
|
||||
case oracle::occi::OCCI_SQLT_VBI:
|
||||
case oracle::occi::OCCI_SQLT_VST:
|
||||
boost::put(*feature,fld_name,(UnicodeString) tr_->transcode (rs_->getString (i + 1).c_str()));
|
||||
break;
|
||||
case oracle::occi::OCCIDATE:
|
||||
case oracle::occi::OCCITIMESTAMP:
|
||||
case oracle::occi::OCCIINTERVALDS:
|
||||
case oracle::occi::OCCIINTERVALYM:
|
||||
case oracle::occi::OCCI_SQLT_DAT:
|
||||
case oracle::occi::OCCI_SQLT_DATE:
|
||||
case oracle::occi::OCCI_SQLT_TIME:
|
||||
case oracle::occi::OCCI_SQLT_TIME_TZ:
|
||||
case oracle::occi::OCCI_SQLT_TIMESTAMP:
|
||||
case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ:
|
||||
case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ:
|
||||
case oracle::occi::OCCI_SQLT_INTERVAL_YM:
|
||||
case oracle::occi::OCCI_SQLT_INTERVAL_DS:
|
||||
case oracle::occi::OCCIANYDATA:
|
||||
case oracle::occi::OCCIBLOB:
|
||||
case oracle::occi::OCCIBFILE:
|
||||
case oracle::occi::OCCIBYTES:
|
||||
case oracle::occi::OCCICLOB:
|
||||
case oracle::occi::OCCIVECTOR:
|
||||
case oracle::occi::OCCIMETADATA:
|
||||
case oracle::occi::OCCIPOBJECT:
|
||||
case oracle::occi::OCCIREF:
|
||||
case oracle::occi::OCCIREFANY:
|
||||
case oracle::occi::OCCISTREAM:
|
||||
case oracle::occi::OCCICURSOR:
|
||||
case oracle::occi::OCCI_SQLT_FILE:
|
||||
case oracle::occi::OCCI_SQLT_CFILE:
|
||||
case oracle::occi::OCCI_SQLT_REF:
|
||||
case oracle::occi::OCCI_SQLT_CLOB:
|
||||
case oracle::occi::OCCI_SQLT_BLOB:
|
||||
case oracle::occi::OCCI_SQLT_RSET:
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OCCI Plugin: unsupported datatype " << occi_enums::resolve_datatype(type_oid)
|
||||
<< " (type_oid=" << type_oid << ")" << std::endl;
|
||||
std::clog << "OCCI Plugin: unsupported datatype "
|
||||
<< occi_enums::resolve_datatype(type_oid)
|
||||
<< " (type_oid=" << type_oid << ")" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
default: // shouldn't get here
|
||||
break;
|
||||
default: // shouldn't get here
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OCCI Plugin: unknown datatype (type_oid=" << type_oid << ")" << std::endl;
|
||||
std::clog << "OCCI Plugin: unknown datatype "
|
||||
<< "(type_oid=" << type_oid << ")" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,30 +205,30 @@ feature_ptr occi_featureset::next()
|
|||
}
|
||||
|
||||
|
||||
void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature, bool multiple_geometries)
|
||||
void occi_featureset::convert_geometry(SDOGeometry* geom, feature_ptr feature, bool multiple_geometries)
|
||||
{
|
||||
int gtype = (int) geom->getSdo_gtype();
|
||||
int gtype = (int)geom->getSdo_gtype();
|
||||
int dimensions = gtype / 1000;
|
||||
int lrsvalue = (gtype - dimensions * 1000) / 100;
|
||||
int geomtype = (gtype - dimensions * 1000 - lrsvalue * 100);
|
||||
|
||||
#if 0
|
||||
clog << "-----------Geometry Object ------------" << endl;
|
||||
clog << "SDO GTYPE = " << gtype << endl;
|
||||
clog << "SDO DIMENSIONS = " << dimensions << endl;
|
||||
clog << "SDO LRS = " << lrsvalue << endl;
|
||||
clog << "SDO GEOMETRY TYPE = " << geomtype << endl;
|
||||
std::clog << "-----------Geometry Object ------------" << std::endl;
|
||||
std::clog << "SDO GTYPE = " << gtype << std::endl;
|
||||
std::clog << "SDO DIMENSIONS = " << dimensions << std::endl;
|
||||
std::clog << "SDO LRS = " << lrsvalue << std::endl;
|
||||
std::clog << "SDO GEOMETRY TYPE = " << geomtype << std::endl;
|
||||
|
||||
Number sdo_srid = geom->getSdo_srid();
|
||||
if (sdo_srid.isNull())
|
||||
clog << "SDO SRID = " << "Null" << endl;
|
||||
std::clog << "SDO SRID = " << "Null" << std::endl;
|
||||
else
|
||||
clog << "SDO SRID = " << (int) sdo_srid << endl;
|
||||
std::clog << "SDO SRID = " << (int)sdo_srid << std::endl;
|
||||
#endif
|
||||
|
||||
const std::vector<Number>& elem_info = geom->getSdo_elem_info();
|
||||
const std::vector<Number>& ordinates = geom->getSdo_ordinates();
|
||||
const int ordinates_size = (int) ordinates.size();
|
||||
const int ordinates_size = (int)ordinates.size();
|
||||
|
||||
switch (geomtype)
|
||||
{
|
||||
|
@ -232,8 +238,8 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature,
|
|||
if (sdopoint && ! sdopoint->isNull())
|
||||
{
|
||||
geometry_type* point = new geometry_type(mapnik::Point);
|
||||
point->move_to (sdopoint->getX(), sdopoint->getY());
|
||||
feature->add_geometry (point);
|
||||
point->move_to(sdopoint->getX(), sdopoint->getY());
|
||||
feature->add_geometry(point);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -245,14 +251,14 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature,
|
|||
const bool is_point_type = false;
|
||||
const bool multiple_geoms = false;
|
||||
|
||||
convert_ordinates (feature,
|
||||
mapnik::LineString,
|
||||
elem_info,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_single_geom,
|
||||
is_point_type,
|
||||
multiple_geoms);
|
||||
convert_ordinates(feature,
|
||||
mapnik::LineString,
|
||||
elem_info,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_single_geom,
|
||||
is_point_type,
|
||||
multiple_geoms);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -264,14 +270,14 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature,
|
|||
const bool is_point_type = false;
|
||||
const bool multiple_geoms = false;
|
||||
|
||||
convert_ordinates (feature,
|
||||
mapnik::Polygon,
|
||||
elem_info,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_single_geom,
|
||||
is_point_type,
|
||||
multiple_geoms);
|
||||
convert_ordinates(feature,
|
||||
mapnik::Polygon,
|
||||
elem_info,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_single_geom,
|
||||
is_point_type,
|
||||
multiple_geoms);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -286,14 +292,14 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature,
|
|||
// Todo - force using true as multiple_geometries until we have proper multipoint handling
|
||||
// http://trac.mapnik.org/ticket/458
|
||||
|
||||
convert_ordinates (feature,
|
||||
mapnik::Point,
|
||||
elem_info,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_single_geom,
|
||||
is_point_type,
|
||||
multiple_geoms);
|
||||
convert_ordinates(feature,
|
||||
mapnik::Point,
|
||||
elem_info,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_single_geom,
|
||||
is_point_type,
|
||||
multiple_geoms);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -304,16 +310,15 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature,
|
|||
const bool is_single_geom = false;
|
||||
const bool is_point_type = false;
|
||||
|
||||
convert_ordinates (feature,
|
||||
mapnik::LineString,
|
||||
elem_info,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_single_geom,
|
||||
is_point_type,
|
||||
multiple_geometries);
|
||||
convert_ordinates(feature,
|
||||
mapnik::LineString,
|
||||
elem_info,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_single_geom,
|
||||
is_point_type,
|
||||
multiple_geometries);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case SDO_GTYPE_MULTIPOLYGON:
|
||||
|
@ -323,14 +328,14 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature,
|
|||
const bool is_single_geom = false;
|
||||
const bool is_point_type = false;
|
||||
|
||||
convert_ordinates (feature,
|
||||
mapnik::Polygon,
|
||||
elem_info,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_single_geom,
|
||||
is_point_type,
|
||||
multiple_geometries);
|
||||
convert_ordinates(feature,
|
||||
mapnik::Polygon,
|
||||
elem_info,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_single_geom,
|
||||
is_point_type,
|
||||
multiple_geometries);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -342,55 +347,56 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature,
|
|||
const bool is_single_geom = false;
|
||||
const bool is_point_type = false;
|
||||
|
||||
convert_ordinates (feature,
|
||||
mapnik::Polygon,
|
||||
elem_info,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_single_geom,
|
||||
is_point_type,
|
||||
multiple_geometries);
|
||||
convert_ordinates(feature,
|
||||
mapnik::Polygon,
|
||||
elem_info,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_single_geom,
|
||||
is_point_type,
|
||||
multiple_geometries);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDO_GTYPE_UNKNOWN:
|
||||
default:
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OCCI Plugin: unknown <occi> " << occi_enums::resolve_gtype(geomtype)
|
||||
<< "(gtype=" << gtype << ")" << std::endl;
|
||||
std::clog << "OCCI Plugin: unknown <occi> "
|
||||
<< occi_enums::resolve_gtype(geomtype)
|
||||
<< "(gtype=" << gtype << ")" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void occi_featureset::convert_ordinates (mapnik::feature_ptr feature,
|
||||
const mapnik::eGeomType& geom_type,
|
||||
const std::vector<Number>& elem_info,
|
||||
const std::vector<Number>& ordinates,
|
||||
const int dimensions,
|
||||
const bool is_single_geom,
|
||||
const bool is_point_geom,
|
||||
const bool multiple_geometries)
|
||||
void occi_featureset::convert_ordinates(mapnik::feature_ptr feature,
|
||||
const mapnik::eGeomType& geom_type,
|
||||
const std::vector<Number>& elem_info,
|
||||
const std::vector<Number>& ordinates,
|
||||
const int dimensions,
|
||||
const bool is_single_geom,
|
||||
const bool is_point_geom,
|
||||
const bool multiple_geometries)
|
||||
{
|
||||
const int elem_size = elem_info.size();
|
||||
const int ord_size = ordinates.size();
|
||||
|
||||
if (elem_size >= 0)
|
||||
{
|
||||
int offset = elem_info [0];
|
||||
int etype = elem_info [1];
|
||||
int interp = elem_info [2];
|
||||
int offset = elem_info[0];
|
||||
int etype = elem_info[1];
|
||||
int interp = elem_info[2];
|
||||
|
||||
if (! is_single_geom && elem_size > SDO_ELEM_INFO_SIZE)
|
||||
{
|
||||
geometry_type* geom = multiple_geometries ? 0 : new geometry_type(geom_type);
|
||||
if (geom) geom->set_capacity (ord_size);
|
||||
if (geom) geom->set_capacity(ord_size);
|
||||
|
||||
for (int i = SDO_ELEM_INFO_SIZE; i < elem_size; i+=3)
|
||||
{
|
||||
int next_offset = elem_info [i];
|
||||
int next_etype = elem_info [i + 1];
|
||||
int next_interp = elem_info [i + 2];
|
||||
int next_offset = elem_info[i];
|
||||
int next_etype = elem_info[i + 1];
|
||||
int next_interp = elem_info[i + 2];
|
||||
bool is_linear_element = true;
|
||||
bool is_unknown_etype = false;
|
||||
mapnik::eGeomType gtype = mapnik::Point;
|
||||
|
@ -398,14 +404,14 @@ void occi_featureset::convert_ordinates (mapnik::feature_ptr feature,
|
|||
switch (etype)
|
||||
{
|
||||
case SDO_ETYPE_POINT:
|
||||
if (interp == SDO_INTERPRETATION_POINT) {}
|
||||
if (interp > SDO_INTERPRETATION_POINT) {}
|
||||
if (interp == SDO_INTERPRETATION_POINT) {}
|
||||
if (interp > SDO_INTERPRETATION_POINT) {}
|
||||
gtype = mapnik::Point;
|
||||
break;
|
||||
|
||||
case SDO_ETYPE_LINESTRING:
|
||||
if (interp == SDO_INTERPRETATION_STRAIGHT) {}
|
||||
if (interp == SDO_INTERPRETATION_CIRCULAR) {}
|
||||
if (interp == SDO_INTERPRETATION_STRAIGHT) {}
|
||||
if (interp == SDO_INTERPRETATION_CIRCULAR) {}
|
||||
gtype = mapnik::LineString;
|
||||
break;
|
||||
|
||||
|
@ -433,25 +439,29 @@ void occi_featureset::convert_ordinates (mapnik::feature_ptr feature,
|
|||
}
|
||||
|
||||
if (is_unknown_etype)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_linear_element)
|
||||
{
|
||||
if (multiple_geometries)
|
||||
{
|
||||
if (geom)
|
||||
feature->add_geometry (geom);
|
||||
{
|
||||
feature->add_geometry(geom);
|
||||
}
|
||||
|
||||
geom = new geometry_type(gtype);
|
||||
geom->set_capacity ((next_offset - 1) - (offset - 1 - dimensions));
|
||||
geom->set_capacity((next_offset - 1) - (offset - 1 - dimensions));
|
||||
}
|
||||
|
||||
fill_geometry_type (geom,
|
||||
offset - 1,
|
||||
next_offset - 1,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_point_geom);
|
||||
fill_geometry_type(geom,
|
||||
offset - 1,
|
||||
next_offset - 1,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_point_geom);
|
||||
}
|
||||
|
||||
offset = next_offset;
|
||||
|
@ -461,45 +471,48 @@ void occi_featureset::convert_ordinates (mapnik::feature_ptr feature,
|
|||
|
||||
if (geom)
|
||||
{
|
||||
feature->add_geometry (geom);
|
||||
feature->add_geometry(geom);
|
||||
geom = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry_type * geom = new geometry_type(geom_type);
|
||||
geom->set_capacity (ord_size);
|
||||
geom->set_capacity(ord_size);
|
||||
|
||||
fill_geometry_type (geom,
|
||||
offset - 1,
|
||||
ord_size,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_point_geom);
|
||||
fill_geometry_type(geom,
|
||||
offset - 1,
|
||||
ord_size,
|
||||
ordinates,
|
||||
dimensions,
|
||||
is_point_geom);
|
||||
|
||||
feature->add_geometry (geom);
|
||||
feature->add_geometry(geom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void occi_featureset::fill_geometry_type (geometry_type * geom,
|
||||
const int real_offset,
|
||||
const int next_offset,
|
||||
const std::vector<Number>& ordinates,
|
||||
const int dimensions,
|
||||
const bool is_point_geom)
|
||||
void occi_featureset::fill_geometry_type(geometry_type* geom,
|
||||
const int real_offset,
|
||||
const int next_offset,
|
||||
const std::vector<Number>& ordinates,
|
||||
const int dimensions,
|
||||
const bool is_point_geom)
|
||||
{
|
||||
geom->move_to ((double) ordinates[real_offset], (double) ordinates[real_offset + 1]);
|
||||
geom->move_to((double) ordinates[real_offset], (double) ordinates[real_offset + 1]);
|
||||
|
||||
if (is_point_geom)
|
||||
{
|
||||
for (int p = real_offset + dimensions; p < next_offset; p += dimensions)
|
||||
geom->move_to ((double) ordinates[p], (double) ordinates[p + 1]);
|
||||
{
|
||||
geom->move_to((double) ordinates[p], (double) ordinates[p + 1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int p = real_offset + dimensions; p < next_offset; p += dimensions)
|
||||
geom->line_to ((double) ordinates[p], (double) ordinates[p + 1]);
|
||||
{
|
||||
geom->line_to((double) ordinates[p], (double) ordinates[p + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -38,40 +38,42 @@
|
|||
|
||||
class occi_featureset : public mapnik::Featureset
|
||||
{
|
||||
public:
|
||||
occi_featureset(oracle::occi::StatelessConnectionPool* pool,
|
||||
oracle::occi::Connection* conn,
|
||||
std::string const& sqlstring,
|
||||
std::string const& encoding,
|
||||
bool multiple_geometries,
|
||||
bool use_connection_pool,
|
||||
unsigned prefetch_rows,
|
||||
unsigned num_attrs);
|
||||
virtual ~occi_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
private:
|
||||
void convert_geometry (SDOGeometry* geom, mapnik::feature_ptr feature, bool multiple_geometries);
|
||||
void convert_ordinates (mapnik::feature_ptr feature,
|
||||
const mapnik::eGeomType& geom_type,
|
||||
const std::vector<oracle::occi::Number>& elem_info,
|
||||
const std::vector<oracle::occi::Number>& ordinates,
|
||||
const int dimensions,
|
||||
const bool is_single_geom,
|
||||
const bool is_point_geom,
|
||||
const bool multiple_geometries);
|
||||
void fill_geometry_type (mapnik::geometry_type * geom,
|
||||
const int real_offset,
|
||||
const int next_offset,
|
||||
const std::vector<oracle::occi::Number>& ordinates,
|
||||
const int dimensions,
|
||||
const bool is_point_geom);
|
||||
occi_connection_ptr conn_;
|
||||
oracle::occi::ResultSet* rs_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
const char* fidcolumn_;
|
||||
bool multiple_geometries_;
|
||||
unsigned num_attrs_;
|
||||
mutable int feature_id_;
|
||||
public:
|
||||
occi_featureset(oracle::occi::StatelessConnectionPool* pool,
|
||||
oracle::occi::Connection* conn,
|
||||
std::string const& sqlstring,
|
||||
std::string const& encoding,
|
||||
bool multiple_geometries,
|
||||
bool use_connection_pool,
|
||||
unsigned prefetch_rows,
|
||||
unsigned num_attrs);
|
||||
virtual ~occi_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
|
||||
private:
|
||||
void convert_geometry (SDOGeometry* geom, mapnik::feature_ptr feature, bool multiple_geometries);
|
||||
void convert_ordinates (mapnik::feature_ptr feature,
|
||||
const mapnik::eGeomType& geom_type,
|
||||
const std::vector<oracle::occi::Number>& elem_info,
|
||||
const std::vector<oracle::occi::Number>& ordinates,
|
||||
const int dimensions,
|
||||
const bool is_single_geom,
|
||||
const bool is_point_geom,
|
||||
const bool multiple_geometries);
|
||||
void fill_geometry_type (mapnik::geometry_type* geom,
|
||||
const int real_offset,
|
||||
const int next_offset,
|
||||
const std::vector<oracle::occi::Number>& ordinates,
|
||||
const int dimensions,
|
||||
const bool is_point_geom);
|
||||
|
||||
occi_connection_ptr conn_;
|
||||
oracle::occi::ResultSet* rs_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
const char* fidcolumn_;
|
||||
bool multiple_geometries_;
|
||||
unsigned num_attrs_;
|
||||
mutable int feature_id_;
|
||||
};
|
||||
|
||||
#endif // OCCI_FEATURESET_HPP
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software, you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -25,71 +25,69 @@
|
|||
|
||||
oracle::occi::Environment* occi_environment::env_ = 0;
|
||||
|
||||
|
||||
std::string occi_enums::resolve_gtype(int gtype)
|
||||
{
|
||||
switch(gtype)
|
||||
switch (gtype)
|
||||
{
|
||||
case SDO_GTYPE_UNKNOWN: return "SDO_GTYPE_UNKNOWN";
|
||||
case SDO_GTYPE_POINT: return "SDO_GTYPE_POINT";
|
||||
case SDO_GTYPE_LINE: return "SDO_GTYPE_LINE";
|
||||
case SDO_GTYPE_POLYGON: return "SDO_GTYPE_POLYGON";
|
||||
case SDO_GTYPE_MULTIPOINT: return "SDO_GTYPE_MULTIPOINT";
|
||||
case SDO_GTYPE_MULTILINE: return "SDO_GTYPE_MULTILINE";
|
||||
case SDO_GTYPE_MULTIPOLYGON: return "SDO_GTYPE_MULTIPOLYGON";
|
||||
case SDO_GTYPE_COLLECTION: return "SDO_GTYPE_COLLECTION";
|
||||
default: return "<unknown SDO_GTYPE>";
|
||||
case SDO_GTYPE_UNKNOWN: return "SDO_GTYPE_UNKNOWN";
|
||||
case SDO_GTYPE_POINT: return "SDO_GTYPE_POINT";
|
||||
case SDO_GTYPE_LINE: return "SDO_GTYPE_LINE";
|
||||
case SDO_GTYPE_POLYGON: return "SDO_GTYPE_POLYGON";
|
||||
case SDO_GTYPE_MULTIPOINT: return "SDO_GTYPE_MULTIPOINT";
|
||||
case SDO_GTYPE_MULTILINE: return "SDO_GTYPE_MULTILINE";
|
||||
case SDO_GTYPE_MULTIPOLYGON: return "SDO_GTYPE_MULTIPOLYGON";
|
||||
case SDO_GTYPE_COLLECTION: return "SDO_GTYPE_COLLECTION";
|
||||
default: return "<unknown SDO_GTYPE>";
|
||||
}
|
||||
}
|
||||
|
||||
std::string occi_enums::resolve_etype(int etype)
|
||||
{
|
||||
switch(etype)
|
||||
switch (etype)
|
||||
{
|
||||
case SDO_ETYPE_UNKNOWN: return "SDO_ETYPE_UNKNOWN";
|
||||
case SDO_ETYPE_POINT: return "SDO_ETYPE_POINT";
|
||||
case SDO_ETYPE_LINESTRING: return "SDO_ETYPE_LINESTRING";
|
||||
case SDO_ETYPE_POLYGON: return "SDO_ETYPE_POLYGON";
|
||||
case SDO_ETYPE_POLYGON_INTERIOR: return "SDO_ETYPE_POLYGON_INTERIOR";
|
||||
case SDO_ETYPE_COMPOUND_LINESTRING: return "SDO_ETYPE_COMPOUND_LINESTRING";
|
||||
case SDO_ETYPE_COMPOUND_POLYGON: return "SDO_ETYPE_COMPOUND_POLYGON";
|
||||
case SDO_ETYPE_COMPOUND_POLYGON_INTERIOR: return "SDO_ETYPE_COMPOUND_POLYGON_INTERIOR";
|
||||
default: return "<unknown SDO_ETYPE>";
|
||||
case SDO_ETYPE_UNKNOWN: return "SDO_ETYPE_UNKNOWN";
|
||||
case SDO_ETYPE_POINT: return "SDO_ETYPE_POINT";
|
||||
case SDO_ETYPE_LINESTRING: return "SDO_ETYPE_LINESTRING";
|
||||
case SDO_ETYPE_POLYGON: return "SDO_ETYPE_POLYGON";
|
||||
case SDO_ETYPE_POLYGON_INTERIOR: return "SDO_ETYPE_POLYGON_INTERIOR";
|
||||
case SDO_ETYPE_COMPOUND_LINESTRING: return "SDO_ETYPE_COMPOUND_LINESTRING";
|
||||
case SDO_ETYPE_COMPOUND_POLYGON: return "SDO_ETYPE_COMPOUND_POLYGON";
|
||||
case SDO_ETYPE_COMPOUND_POLYGON_INTERIOR: return "SDO_ETYPE_COMPOUND_POLYGON_INTERIOR";
|
||||
default: return "<unknown SDO_ETYPE>";
|
||||
}
|
||||
}
|
||||
|
||||
std::string occi_enums::resolve_datatype(int type_id)
|
||||
{
|
||||
switch(type_id)
|
||||
switch (type_id)
|
||||
{
|
||||
case oracle::occi::OCCIINT: return "OCCIINT";
|
||||
case oracle::occi::OCCIUNSIGNED_INT: return "OCCIUNSIGNED_INT";
|
||||
case oracle::occi::OCCIFLOAT: return "OCCIFLOAT";
|
||||
case oracle::occi::OCCIBFLOAT: return "OCCIBFLOAT";
|
||||
case oracle::occi::OCCIDOUBLE: return "OCCIDOUBLE";
|
||||
case oracle::occi::OCCIBDOUBLE: return "OCCIBDOUBLE";
|
||||
case oracle::occi::OCCINUMBER: return "OCCINUMBER";
|
||||
case oracle::occi::OCCI_SQLT_NUM: return "OCCI_SQLT_NUM";
|
||||
case oracle::occi::OCCICHAR: return "OCCICHAR";
|
||||
case oracle::occi::OCCISTRING: return "OCCISTRING";
|
||||
case oracle::occi::OCCI_SQLT_AFC: return "OCCI_SQLT_AFC";
|
||||
case oracle::occi::OCCI_SQLT_AVC: return "OCCI_SQLT_AVC";
|
||||
case oracle::occi::OCCI_SQLT_CHR: return "OCCI_SQLT_CHR";
|
||||
case oracle::occi::OCCI_SQLT_LVC: return "OCCI_SQLT_LVC";
|
||||
case oracle::occi::OCCI_SQLT_STR: return "OCCI_SQLT_STR";
|
||||
case oracle::occi::OCCI_SQLT_VCS: return "OCCI_SQLT_VCS";
|
||||
case oracle::occi::OCCI_SQLT_VNU: return "OCCI_SQLT_VNU";
|
||||
case oracle::occi::OCCI_SQLT_VBI: return "OCCI_SQLT_VBI";
|
||||
case oracle::occi::OCCI_SQLT_VST: return "OCCI_SQLT_VST";
|
||||
case oracle::occi::OCCI_SQLT_RDD: return "OCCI_SQLT_RDD";
|
||||
case oracle::occi::OCCIDATE: return "OCCIDATE";
|
||||
case oracle::occi::OCCITIMESTAMP: return "OCCITIMESTAMP";
|
||||
case oracle::occi::OCCI_SQLT_DAT: return "OCCI_SQLT_DAT";
|
||||
case oracle::occi::OCCI_SQLT_TIMESTAMP: return "OCCI_SQLT_TIMESTAMP";
|
||||
case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ: return "OCCI_SQLT_TIMESTAMP_LTZ";
|
||||
case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ: return "OCCI_SQLT_TIMESTAMP_TZ";
|
||||
case oracle::occi::OCCIPOBJECT: return "OCCIPOBJECT";
|
||||
default: return "<unknown ATTR_DATA_TYPE>";
|
||||
case oracle::occi::OCCIINT: return "OCCIINT";
|
||||
case oracle::occi::OCCIUNSIGNED_INT: return "OCCIUNSIGNED_INT";
|
||||
case oracle::occi::OCCIFLOAT: return "OCCIFLOAT";
|
||||
case oracle::occi::OCCIBFLOAT: return "OCCIBFLOAT";
|
||||
case oracle::occi::OCCIDOUBLE: return "OCCIDOUBLE";
|
||||
case oracle::occi::OCCIBDOUBLE: return "OCCIBDOUBLE";
|
||||
case oracle::occi::OCCINUMBER: return "OCCINUMBER";
|
||||
case oracle::occi::OCCI_SQLT_NUM: return "OCCI_SQLT_NUM";
|
||||
case oracle::occi::OCCICHAR: return "OCCICHAR";
|
||||
case oracle::occi::OCCISTRING: return "OCCISTRING";
|
||||
case oracle::occi::OCCI_SQLT_AFC: return "OCCI_SQLT_AFC";
|
||||
case oracle::occi::OCCI_SQLT_AVC: return "OCCI_SQLT_AVC";
|
||||
case oracle::occi::OCCI_SQLT_CHR: return "OCCI_SQLT_CHR";
|
||||
case oracle::occi::OCCI_SQLT_LVC: return "OCCI_SQLT_LVC";
|
||||
case oracle::occi::OCCI_SQLT_STR: return "OCCI_SQLT_STR";
|
||||
case oracle::occi::OCCI_SQLT_VCS: return "OCCI_SQLT_VCS";
|
||||
case oracle::occi::OCCI_SQLT_VNU: return "OCCI_SQLT_VNU";
|
||||
case oracle::occi::OCCI_SQLT_VBI: return "OCCI_SQLT_VBI";
|
||||
case oracle::occi::OCCI_SQLT_VST: return "OCCI_SQLT_VST";
|
||||
case oracle::occi::OCCI_SQLT_RDD: return "OCCI_SQLT_RDD";
|
||||
case oracle::occi::OCCIDATE: return "OCCIDATE";
|
||||
case oracle::occi::OCCITIMESTAMP: return "OCCITIMESTAMP";
|
||||
case oracle::occi::OCCI_SQLT_DAT: return "OCCI_SQLT_DAT";
|
||||
case oracle::occi::OCCI_SQLT_TIMESTAMP: return "OCCI_SQLT_TIMESTAMP";
|
||||
case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ: return "OCCI_SQLT_TIMESTAMP_LTZ";
|
||||
case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ: return "OCCI_SQLT_TIMESTAMP_TZ";
|
||||
case oracle::occi::OCCIPOBJECT: return "OCCIPOBJECT";
|
||||
default: return "<unknown ATTR_DATA_TYPE>";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software, you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -41,7 +41,6 @@
|
|||
#error Only ORACLE 10g >= 10.2.0.X is supported !
|
||||
#endif
|
||||
|
||||
|
||||
// geometry types definitions
|
||||
enum
|
||||
{
|
||||
|
@ -79,14 +78,13 @@ enum
|
|||
SDO_INTERPRETATION_CIRCULAR = 2
|
||||
};
|
||||
|
||||
|
||||
class occi_environment : public mapnik::singleton<occi_environment,mapnik::CreateStatic>
|
||||
class occi_environment : public mapnik::singleton<occi_environment, mapnik::CreateStatic>
|
||||
{
|
||||
friend class mapnik::CreateStatic<occi_environment>;
|
||||
|
||||
public:
|
||||
|
||||
static oracle::occi::Environment* get_environment ()
|
||||
static oracle::occi::Environment* get_environment()
|
||||
{
|
||||
if (env_ == 0)
|
||||
{
|
||||
|
@ -94,11 +92,11 @@ public:
|
|||
std::clog << "OCCI Plugin: occi_environment constructor" << std::endl;
|
||||
#endif
|
||||
|
||||
int mode = oracle::occi::Environment::OBJECT
|
||||
| oracle::occi::Environment::THREADED_MUTEXED;
|
||||
const int mode = oracle::occi::Environment::OBJECT
|
||||
| oracle::occi::Environment::THREADED_MUTEXED;
|
||||
|
||||
env_ = oracle::occi::Environment::createEnvironment ((oracle::occi::Environment::Mode) mode);
|
||||
RegisterClasses (env_);
|
||||
env_ = oracle::occi::Environment::createEnvironment((oracle::occi::Environment::Mode) mode);
|
||||
RegisterClasses(env_);
|
||||
}
|
||||
|
||||
return env_;
|
||||
|
@ -118,7 +116,7 @@ private:
|
|||
std::clog << "OCCI Plugin: occi_environment destructor" << std::endl;
|
||||
#endif
|
||||
|
||||
oracle::occi::Environment::terminateEnvironment (env_);
|
||||
oracle::occi::Environment::terminateEnvironment(env_);
|
||||
env_ = 0;
|
||||
}
|
||||
}
|
||||
|
@ -126,28 +124,27 @@ private:
|
|||
static oracle::occi::Environment* env_;
|
||||
};
|
||||
|
||||
|
||||
class occi_connection_ptr
|
||||
{
|
||||
public:
|
||||
explicit occi_connection_ptr ()
|
||||
: env_ (occi_environment::get_environment()),
|
||||
pool_ (0),
|
||||
conn_ (0),
|
||||
stmt_ (0),
|
||||
rs_ (0),
|
||||
owns_connection_ (false)
|
||||
explicit occi_connection_ptr()
|
||||
: env_(occi_environment::get_environment()),
|
||||
pool_(0),
|
||||
conn_(0),
|
||||
stmt_(0),
|
||||
rs_(0),
|
||||
owns_connection_(false)
|
||||
{
|
||||
}
|
||||
|
||||
~occi_connection_ptr ()
|
||||
~occi_connection_ptr()
|
||||
{
|
||||
close_query (true);
|
||||
close_query(true);
|
||||
}
|
||||
|
||||
void set_pool(oracle::occi::StatelessConnectionPool* pool)
|
||||
{
|
||||
close_query (true);
|
||||
close_query(true);
|
||||
|
||||
pool_ = pool;
|
||||
conn_ = pool_->getConnection();
|
||||
|
@ -156,26 +153,26 @@ public:
|
|||
|
||||
void set_connection(oracle::occi::Connection* conn, bool owns_connection)
|
||||
{
|
||||
close_query (true);
|
||||
close_query(true);
|
||||
|
||||
pool_ = 0;
|
||||
conn_ = conn;
|
||||
owns_connection_ = owns_connection;
|
||||
}
|
||||
|
||||
oracle::occi::ResultSet* execute_query (const std::string& s, const unsigned prefetch = 0)
|
||||
oracle::occi::ResultSet* execute_query(const std::string& s, const unsigned prefetch = 0)
|
||||
{
|
||||
close_query (false);
|
||||
close_query(false);
|
||||
|
||||
stmt_ = conn_->createStatement (s);
|
||||
stmt_ = conn_->createStatement(s);
|
||||
|
||||
if (prefetch > 0)
|
||||
{
|
||||
stmt_->setPrefetchMemorySize (0);
|
||||
stmt_->setPrefetchRowCount (prefetch);
|
||||
stmt_->setPrefetchMemorySize(0);
|
||||
stmt_->setPrefetchRowCount(prefetch);
|
||||
}
|
||||
|
||||
rs_ = stmt_->executeQuery ();
|
||||
rs_ = stmt_->executeQuery();
|
||||
|
||||
return rs_;
|
||||
}
|
||||
|
@ -186,8 +183,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
void close_query (const bool release_connection)
|
||||
void close_query(const bool release_connection)
|
||||
{
|
||||
if (conn_)
|
||||
{
|
||||
|
@ -195,11 +191,11 @@ private:
|
|||
{
|
||||
if (rs_)
|
||||
{
|
||||
stmt_->closeResultSet (rs_);
|
||||
stmt_->closeResultSet(rs_);
|
||||
rs_ = 0;
|
||||
}
|
||||
|
||||
conn_->terminateStatement (stmt_);
|
||||
conn_->terminateStatement(stmt_);
|
||||
stmt_ = 0;
|
||||
}
|
||||
|
||||
|
@ -207,7 +203,7 @@ private:
|
|||
{
|
||||
if (pool_)
|
||||
{
|
||||
pool_->releaseConnection (conn_);
|
||||
pool_->releaseConnection(conn_);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -230,7 +226,6 @@ private:
|
|||
bool owns_connection_;
|
||||
};
|
||||
|
||||
|
||||
class occi_enums
|
||||
{
|
||||
public:
|
||||
|
@ -240,5 +235,4 @@ public:
|
|||
static std::string resolve_datatype(int type_id);
|
||||
};
|
||||
|
||||
|
||||
#endif // OCCI_TYPES_HPP
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -36,235 +36,246 @@ using mapnik::feature_ptr;
|
|||
using mapnik::geometry_utils;
|
||||
using mapnik::geometry_type;
|
||||
|
||||
void ogr_converter::convert_geometry (OGRGeometry* geom, feature_ptr feature, bool multiple_geometries)
|
||||
void ogr_converter::convert_geometry(OGRGeometry* geom, feature_ptr feature, bool multiple_geometries)
|
||||
{
|
||||
switch (wkbFlatten (geom->getGeometryType()))
|
||||
{
|
||||
case wkbPoint:
|
||||
convert_point (static_cast<OGRPoint*>(geom), feature);
|
||||
break;
|
||||
case wkbLineString:
|
||||
convert_linestring (static_cast<OGRLineString*>(geom), feature);
|
||||
break;
|
||||
case wkbPolygon:
|
||||
convert_polygon (static_cast<OGRPolygon*>(geom), feature);
|
||||
break;
|
||||
case wkbMultiPoint:
|
||||
if (multiple_geometries)
|
||||
convert_multipoint_2 (static_cast<OGRMultiPoint*>(geom), feature);
|
||||
else
|
||||
// Todo - using convert_multipoint_2 until we have proper multipoint handling in convert_multipoint
|
||||
// http://trac.mapnik.org/ticket/458
|
||||
//convert_multipoint (static_cast<OGRMultiPoint*>(geom), feature);
|
||||
convert_multipoint_2 (static_cast<OGRMultiPoint*>(geom), feature);
|
||||
break;
|
||||
case wkbMultiLineString:
|
||||
if (multiple_geometries)
|
||||
convert_multilinestring_2 (static_cast<OGRMultiLineString*>(geom), feature);
|
||||
else
|
||||
convert_multilinestring (static_cast<OGRMultiLineString*>(geom), feature);
|
||||
|
||||
break;
|
||||
case wkbMultiPolygon:
|
||||
if (multiple_geometries)
|
||||
convert_multipolygon_2 (static_cast<OGRMultiPolygon*>(geom), feature);
|
||||
else
|
||||
convert_multipolygon (static_cast<OGRMultiPolygon*>(geom), feature);
|
||||
break;
|
||||
case wkbGeometryCollection:
|
||||
convert_collection (static_cast<OGRGeometryCollection*>(geom), feature, multiple_geometries);
|
||||
break;
|
||||
case wkbLinearRing:
|
||||
convert_linestring (static_cast<OGRLinearRing*>(geom), feature);
|
||||
break;
|
||||
case wkbNone:
|
||||
case wkbUnknown:
|
||||
default:
|
||||
switch (wkbFlatten(geom->getGeometryType()))
|
||||
{
|
||||
case wkbPoint:
|
||||
convert_point(static_cast<OGRPoint*>(geom), feature);
|
||||
break;
|
||||
case wkbLineString:
|
||||
convert_linestring(static_cast<OGRLineString*>(geom), feature);
|
||||
break;
|
||||
case wkbPolygon:
|
||||
convert_polygon(static_cast<OGRPolygon*>(geom), feature);
|
||||
break;
|
||||
case wkbMultiPoint:
|
||||
if (multiple_geometries)
|
||||
{
|
||||
convert_multipoint_2(static_cast<OGRMultiPoint*>(geom), feature);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Todo - using convert_multipoint_2 until we have proper multipoint handling in convert_multipoint
|
||||
// http://trac.mapnik.org/ticket/458
|
||||
//convert_multipoint(static_cast<OGRMultiPoint*>(geom), feature);
|
||||
convert_multipoint_2(static_cast<OGRMultiPoint*>(geom), feature);
|
||||
}
|
||||
break;
|
||||
case wkbMultiLineString:
|
||||
if (multiple_geometries)
|
||||
{
|
||||
convert_multilinestring_2(static_cast<OGRMultiLineString*>(geom), feature);
|
||||
}
|
||||
else
|
||||
{
|
||||
convert_multilinestring(static_cast<OGRMultiLineString*>(geom), feature);
|
||||
}
|
||||
break;
|
||||
case wkbMultiPolygon:
|
||||
if (multiple_geometries)
|
||||
{
|
||||
convert_multipolygon_2(static_cast<OGRMultiPolygon*>(geom), feature);
|
||||
}
|
||||
else
|
||||
{
|
||||
convert_multipolygon(static_cast<OGRMultiPolygon*>(geom), feature);
|
||||
}
|
||||
break;
|
||||
case wkbGeometryCollection:
|
||||
convert_collection(static_cast<OGRGeometryCollection*>(geom), feature, multiple_geometries);
|
||||
break;
|
||||
case wkbLinearRing:
|
||||
convert_linestring(static_cast<OGRLinearRing*>(geom), feature);
|
||||
break;
|
||||
case wkbNone:
|
||||
case wkbUnknown:
|
||||
default:
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unknown <ogr> geometry_type=" << wkbFlatten (geom->getGeometryType()) << std::endl;
|
||||
std::clog << "OGR Plugin: unknown <ogr> geometry_type="
|
||||
<< wkbFlatten(geom->getGeometryType()) << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ogr_converter::convert_point (OGRPoint* geom, feature_ptr feature)
|
||||
void ogr_converter::convert_point(OGRPoint* geom, feature_ptr feature)
|
||||
{
|
||||
geometry_type * point = new geometry_type(mapnik::Point);
|
||||
point->move_to (geom->getX(), geom->getY());
|
||||
feature->add_geometry (point);
|
||||
point->move_to(geom->getX(), geom->getY());
|
||||
feature->add_geometry(point);
|
||||
}
|
||||
|
||||
void ogr_converter::convert_linestring (OGRLineString* geom, feature_ptr feature)
|
||||
void ogr_converter::convert_linestring(OGRLineString* geom, feature_ptr feature)
|
||||
{
|
||||
int num_points = geom->getNumPoints ();
|
||||
geometry_type * line = new geometry_type(mapnik::LineString);
|
||||
line->set_capacity (num_points);
|
||||
line->move_to (geom->getX (0), geom->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
int num_points = geom->getNumPoints();
|
||||
geometry_type* line = new geometry_type(mapnik::LineString);
|
||||
line->set_capacity(num_points);
|
||||
line->move_to(geom->getX(0), geom->getY(0));
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
{
|
||||
line->line_to (geom->getX (i), geom->getY (i));
|
||||
line->line_to (geom->getX(i), geom->getY(i));
|
||||
}
|
||||
feature->add_geometry (line);
|
||||
feature->add_geometry(line);
|
||||
}
|
||||
|
||||
void ogr_converter::convert_polygon (OGRPolygon* geom, feature_ptr feature)
|
||||
void ogr_converter::convert_polygon(OGRPolygon* geom, feature_ptr feature)
|
||||
{
|
||||
OGRLinearRing* exterior = geom->getExteriorRing ();
|
||||
int num_points = exterior->getNumPoints ();
|
||||
int num_interior = geom->getNumInteriorRings ();
|
||||
OGRLinearRing* exterior = geom->getExteriorRing();
|
||||
int num_points = exterior->getNumPoints();
|
||||
int num_interior = geom->getNumInteriorRings();
|
||||
int capacity = 0;
|
||||
for (int r=0;r<num_interior;r++)
|
||||
for (int r = 0; r < num_interior; r++)
|
||||
{
|
||||
OGRLinearRing* interior = geom->getInteriorRing (r);
|
||||
capacity += interior->getNumPoints ();
|
||||
OGRLinearRing* interior = geom->getInteriorRing(r);
|
||||
capacity += interior->getNumPoints();
|
||||
}
|
||||
|
||||
geometry_type * poly = new geometry_type(mapnik::Polygon);
|
||||
poly->set_capacity (num_points + capacity);
|
||||
poly->move_to (exterior->getX (0), exterior->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
geometry_type* poly = new geometry_type(mapnik::Polygon);
|
||||
poly->set_capacity(num_points + capacity);
|
||||
poly->move_to(exterior->getX(0), exterior->getY(0));
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
{
|
||||
poly->line_to (exterior->getX (i), exterior->getY (i));
|
||||
poly->line_to(exterior->getX(i), exterior->getY(i));
|
||||
}
|
||||
for (int r=0;r<num_interior;r++)
|
||||
for (int r = 0; r < num_interior; r++)
|
||||
{
|
||||
OGRLinearRing* interior = geom->getInteriorRing (r);
|
||||
num_points = interior->getNumPoints ();
|
||||
poly->move_to(interior->getX (0), interior->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
OGRLinearRing* interior = geom->getInteriorRing(r);
|
||||
num_points = interior->getNumPoints();
|
||||
poly->move_to(interior->getX(0), interior->getY(0));
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
{
|
||||
poly->line_to(interior->getX (i), interior->getY (i));
|
||||
poly->line_to(interior->getX(i), interior->getY(i));
|
||||
}
|
||||
}
|
||||
feature->add_geometry (poly);
|
||||
feature->add_geometry(poly);
|
||||
}
|
||||
|
||||
void ogr_converter::convert_multipoint (OGRMultiPoint* geom, feature_ptr feature)
|
||||
void ogr_converter::convert_multipoint(OGRMultiPoint* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
geometry_type * point = new geometry_type(mapnik::Point);
|
||||
int num_geometries = geom->getNumGeometries();
|
||||
geometry_type* point = new geometry_type(mapnik::Point);
|
||||
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
for (int i = 0; i < num_geometries; i++)
|
||||
{
|
||||
OGRPoint* ogrpoint = static_cast<OGRPoint*>(geom->getGeometryRef (i));
|
||||
point->move_to (ogrpoint->getX(), ogrpoint->getY());
|
||||
OGRPoint* ogrpoint = static_cast<OGRPoint*>(geom->getGeometryRef(i));
|
||||
point->move_to(ogrpoint->getX(), ogrpoint->getY());
|
||||
//Todo - need to accept multiple points per mapnik::Point
|
||||
}
|
||||
|
||||
// Todo - this only gets last point
|
||||
feature->add_geometry (point);
|
||||
feature->add_geometry(point);
|
||||
}
|
||||
|
||||
void ogr_converter::convert_multipoint_2 (OGRMultiPoint* geom, feature_ptr feature)
|
||||
void ogr_converter::convert_multipoint_2(OGRMultiPoint* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
int num_geometries = geom->getNumGeometries();
|
||||
for (int i = 0; i < num_geometries; i++)
|
||||
{
|
||||
convert_point (static_cast<OGRPoint*>(geom->getGeometryRef (i)), feature);
|
||||
convert_point(static_cast<OGRPoint*>(geom->getGeometryRef(i)), feature);
|
||||
}
|
||||
}
|
||||
|
||||
void ogr_converter::convert_multilinestring (OGRMultiLineString* geom, feature_ptr feature)
|
||||
void ogr_converter::convert_multilinestring(OGRMultiLineString* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
int num_geometries = geom->getNumGeometries();
|
||||
|
||||
int num_points = 0;
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
for (int i = 0; i < num_geometries; i++)
|
||||
{
|
||||
OGRLineString* ls = static_cast<OGRLineString*>(geom->getGeometryRef (i));
|
||||
num_points += ls->getNumPoints ();
|
||||
OGRLineString* ls = static_cast<OGRLineString*>(geom->getGeometryRef(i));
|
||||
num_points += ls->getNumPoints();
|
||||
}
|
||||
|
||||
geometry_type * line = new geometry_type(mapnik::LineString);
|
||||
line->set_capacity (num_points);
|
||||
geometry_type* line = new geometry_type(mapnik::LineString);
|
||||
line->set_capacity(num_points);
|
||||
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
for (int i = 0; i < num_geometries; i++)
|
||||
{
|
||||
OGRLineString* ls = static_cast<OGRLineString*>(geom->getGeometryRef (i));
|
||||
num_points = ls->getNumPoints ();
|
||||
line->move_to (ls->getX (0), ls->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
OGRLineString* ls = static_cast<OGRLineString*>(geom->getGeometryRef(i));
|
||||
num_points = ls->getNumPoints();
|
||||
line->move_to(ls->getX(0), ls->getY(0));
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
{
|
||||
line->line_to (ls->getX (i), ls->getY (i));
|
||||
line->line_to(ls->getX(i), ls->getY(i));
|
||||
}
|
||||
}
|
||||
|
||||
feature->add_geometry (line);
|
||||
feature->add_geometry(line);
|
||||
}
|
||||
|
||||
void ogr_converter::convert_multilinestring_2 (OGRMultiLineString* geom, feature_ptr feature)
|
||||
void ogr_converter::convert_multilinestring_2(OGRMultiLineString* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
int num_geometries = geom->getNumGeometries();
|
||||
for (int i = 0; i < num_geometries; i++)
|
||||
{
|
||||
convert_linestring (static_cast<OGRLineString*>(geom->getGeometryRef (i)), feature);
|
||||
convert_linestring(static_cast<OGRLineString*>(geom->getGeometryRef(i)), feature);
|
||||
}
|
||||
}
|
||||
|
||||
void ogr_converter::convert_multipolygon (OGRMultiPolygon* geom, feature_ptr feature)
|
||||
void ogr_converter::convert_multipolygon(OGRMultiPolygon* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
int num_geometries = geom->getNumGeometries();
|
||||
|
||||
int capacity = 0;
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
for (int i = 0; i < num_geometries; i++)
|
||||
{
|
||||
OGRPolygon* p = static_cast<OGRPolygon*>(geom->getGeometryRef (i));
|
||||
OGRLinearRing* exterior = p->getExteriorRing ();
|
||||
capacity += exterior->getNumPoints ();
|
||||
for (int r=0;r<p->getNumInteriorRings ();r++)
|
||||
OGRPolygon* p = static_cast<OGRPolygon*>(geom->getGeometryRef(i));
|
||||
OGRLinearRing* exterior = p->getExteriorRing();
|
||||
capacity += exterior->getNumPoints();
|
||||
for (int r = 0; r < p->getNumInteriorRings(); r++)
|
||||
{
|
||||
OGRLinearRing* interior = p->getInteriorRing (r);
|
||||
capacity += interior->getNumPoints ();
|
||||
OGRLinearRing* interior = p->getInteriorRing(r);
|
||||
capacity += interior->getNumPoints();
|
||||
}
|
||||
}
|
||||
|
||||
geometry_type * poly = new geometry_type(mapnik::Polygon);
|
||||
poly->set_capacity (capacity);
|
||||
geometry_type* poly = new geometry_type(mapnik::Polygon);
|
||||
poly->set_capacity(capacity);
|
||||
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
for (int i = 0; i < num_geometries; i++)
|
||||
{
|
||||
OGRPolygon* p = static_cast<OGRPolygon*>(geom->getGeometryRef (i));
|
||||
OGRLinearRing* exterior = p->getExteriorRing ();
|
||||
int num_points = exterior->getNumPoints ();
|
||||
int num_interior = p->getNumInteriorRings ();
|
||||
poly->move_to (exterior->getX (0), exterior->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
OGRPolygon* p = static_cast<OGRPolygon*>(geom->getGeometryRef(i));
|
||||
OGRLinearRing* exterior = p->getExteriorRing();
|
||||
int num_points = exterior->getNumPoints();
|
||||
int num_interior = p->getNumInteriorRings();
|
||||
poly->move_to(exterior->getX(0), exterior->getY(0));
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
{
|
||||
poly->line_to (exterior->getX (i), exterior->getY (i));
|
||||
poly->line_to(exterior->getX(i), exterior->getY(i));
|
||||
}
|
||||
for (int r=0;r<num_interior;r++)
|
||||
for (int r = 0; r < num_interior; r++)
|
||||
{
|
||||
OGRLinearRing* interior = p->getInteriorRing (r);
|
||||
num_points = interior->getNumPoints ();
|
||||
poly->move_to(interior->getX (0), interior->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
OGRLinearRing* interior = p->getInteriorRing(r);
|
||||
num_points = interior->getNumPoints();
|
||||
poly->move_to(interior->getX(0), interior->getY(0));
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
{
|
||||
poly->line_to(interior->getX (i), interior->getY (i));
|
||||
poly->line_to(interior->getX(i), interior->getY(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
feature->add_geometry (poly);
|
||||
feature->add_geometry(poly);
|
||||
}
|
||||
|
||||
void ogr_converter::convert_multipolygon_2 (OGRMultiPolygon* geom, feature_ptr feature)
|
||||
void ogr_converter::convert_multipolygon_2(OGRMultiPolygon* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
int num_geometries = geom->getNumGeometries();
|
||||
for (int i = 0; i < num_geometries; i++)
|
||||
{
|
||||
convert_polygon (static_cast<OGRPolygon*>(geom->getGeometryRef (i)), feature);
|
||||
convert_polygon(static_cast<OGRPolygon*>(geom->getGeometryRef(i)), feature);
|
||||
}
|
||||
}
|
||||
|
||||
void ogr_converter::convert_collection (OGRGeometryCollection* geom, feature_ptr feature, bool multiple_geometries)
|
||||
void ogr_converter::convert_collection(OGRGeometryCollection* geom, feature_ptr feature, bool multiple_geometries)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
int num_geometries = geom->getNumGeometries();
|
||||
for (int i = 0; i < num_geometries; i++)
|
||||
{
|
||||
OGRGeometry* g = geom->getGeometryRef (i);
|
||||
OGRGeometry* g = geom->getGeometryRef(i);
|
||||
if (g != NULL)
|
||||
{
|
||||
convert_geometry (g, feature, multiple_geometries);
|
||||
convert_geometry(g, feature, multiple_geometries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -32,19 +32,19 @@
|
|||
|
||||
class ogr_converter
|
||||
{
|
||||
public:
|
||||
public:
|
||||
|
||||
static void convert_geometry (OGRGeometry* geom, mapnik::feature_ptr feature, bool multiple_geometries);
|
||||
static void convert_collection (OGRGeometryCollection* geom, mapnik::feature_ptr feature, bool multiple_geometries);
|
||||
static void convert_point (OGRPoint* geom, mapnik::feature_ptr feature);
|
||||
static void convert_linestring (OGRLineString* geom, mapnik::feature_ptr feature);
|
||||
static void convert_polygon (OGRPolygon* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multipoint (OGRMultiPoint* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multipoint_2 (OGRMultiPoint* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multilinestring (OGRMultiLineString* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multilinestring_2 (OGRMultiLineString* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multipolygon (OGRMultiPolygon* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multipolygon_2 (OGRMultiPolygon* geom, mapnik::feature_ptr feature);
|
||||
static void convert_geometry (OGRGeometry* geom, mapnik::feature_ptr feature, bool multiple_geometries);
|
||||
static void convert_collection (OGRGeometryCollection* geom, mapnik::feature_ptr feature, bool multiple_geometries);
|
||||
static void convert_point (OGRPoint* geom, mapnik::feature_ptr feature);
|
||||
static void convert_linestring (OGRLineString* geom, mapnik::feature_ptr feature);
|
||||
static void convert_polygon (OGRPolygon* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multipoint (OGRMultiPoint* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multipoint_2 (OGRMultiPoint* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multilinestring (OGRMultiLineString* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multilinestring_2 (OGRMultiLineString* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multipolygon (OGRMultiPolygon* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multipolygon_2 (OGRMultiPolygon* geom, mapnik::feature_ptr feature);
|
||||
};
|
||||
|
||||
#endif // OGR_FEATURESET_HPP
|
||||
#endif // OGR_CONVERTER_HPP
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -53,35 +53,42 @@ using mapnik::filter_at_point;
|
|||
|
||||
|
||||
ogr_datasource::ogr_datasource(parameters const& params, bool bind)
|
||||
: datasource(params),
|
||||
extent_(),
|
||||
type_(datasource::Vector),
|
||||
desc_(*params.get<std::string>("type"), *params.get<std::string>("encoding","utf-8")),
|
||||
indexed_(false)
|
||||
: datasource(params),
|
||||
extent_(),
|
||||
type_(datasource::Vector),
|
||||
desc_(*params.get<std::string>("type"), *params.get<std::string>("encoding","utf-8")),
|
||||
indexed_(false)
|
||||
{
|
||||
boost::optional<std::string> file = params.get<std::string>("file");
|
||||
boost::optional<std::string> string = params.get<std::string>("string");
|
||||
if (!file && !string) throw datasource_exception("missing <file> or <string> parameter");
|
||||
boost::optional<std::string> file = params.get<std::string>("file");
|
||||
boost::optional<std::string> string = params.get<std::string>("string");
|
||||
if (! file && ! string)
|
||||
{
|
||||
throw datasource_exception("missing <file> or <string> parameter");
|
||||
}
|
||||
|
||||
multiple_geometries_ = *params.get<mapnik::boolean>("multiple_geometries",false);
|
||||
multiple_geometries_ = *params.get<mapnik::boolean>("multiple_geometries",false);
|
||||
|
||||
if (string)
|
||||
{
|
||||
if (string)
|
||||
{
|
||||
dataset_name_ = *string;
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::optional<std::string> base = params.get<std::string>("base");
|
||||
if (base)
|
||||
dataset_name_ = *base + "/" + *file;
|
||||
else
|
||||
dataset_name_ = *file;
|
||||
}
|
||||
|
||||
if (bind)
|
||||
{
|
||||
this->bind();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::optional<std::string> base = params.get<std::string>("base");
|
||||
if (base)
|
||||
{
|
||||
dataset_name_ = *base + "/" + *file;
|
||||
}
|
||||
else
|
||||
{
|
||||
dataset_name_ = *file;
|
||||
}
|
||||
}
|
||||
|
||||
if (bind)
|
||||
{
|
||||
this->bind();
|
||||
}
|
||||
}
|
||||
|
||||
ogr_datasource::~ogr_datasource()
|
||||
|
@ -94,236 +101,265 @@ ogr_datasource::~ogr_datasource()
|
|||
|
||||
void ogr_datasource::bind() const
|
||||
{
|
||||
if (is_bound_) return;
|
||||
if (is_bound_) return;
|
||||
|
||||
// initialize ogr formats
|
||||
OGRRegisterAll();
|
||||
|
||||
// open ogr driver
|
||||
dataset_ = OGRSFDriverRegistrar::Open ((dataset_name_).c_str(), FALSE);
|
||||
if (!dataset_)
|
||||
{
|
||||
std::string err = CPLGetLastErrorMsg();
|
||||
if( err.size() == 0 ) {
|
||||
throw datasource_exception("OGR Plugin: connection failed: " + dataset_name_ + " was not found or is not a supported format");
|
||||
} else {
|
||||
throw datasource_exception("OGR Plugin: " + err);
|
||||
}
|
||||
}
|
||||
// initialize ogr formats
|
||||
OGRRegisterAll();
|
||||
|
||||
// initialize layer
|
||||
|
||||
boost::optional<std::string> layer_by_name = params_.get<std::string>("layer");
|
||||
boost::optional<unsigned> layer_by_index = params_.get<unsigned>("layer_by_index");
|
||||
|
||||
if (layer_by_name && layer_by_index)
|
||||
throw datasource_exception("OGR Plugin: you can only select an ogr layer by name ('layer' parameter) or by number ('layer_by_index' parameter), do not supply both parameters" );
|
||||
// open ogr driver
|
||||
dataset_ = OGRSFDriverRegistrar::Open((dataset_name_).c_str(), FALSE);
|
||||
if (! dataset_)
|
||||
{
|
||||
const std::string err = CPLGetLastErrorMsg();
|
||||
if (err.size() == 0)
|
||||
{
|
||||
throw datasource_exception("OGR Plugin: connection failed: " + dataset_name_ + " was not found or is not a supported format");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw datasource_exception("OGR Plugin: " + err);
|
||||
}
|
||||
}
|
||||
|
||||
if (layer_by_name)
|
||||
{
|
||||
layerName_ = *layer_by_name;
|
||||
layer_ = dataset_->GetLayerByName (layerName_.c_str());
|
||||
}
|
||||
else if (layer_by_index)
|
||||
{
|
||||
unsigned num_layers = dataset_->GetLayerCount();
|
||||
if (*layer_by_index >= num_layers)
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << "OGR Plugin: only ";
|
||||
s << num_layers;
|
||||
s << " layer(s) exist, cannot find layer by index '" << *layer_by_index << "'";
|
||||
|
||||
throw datasource_exception(s.str());
|
||||
}
|
||||
OGRLayer *ogr_layer = dataset_->GetLayer(*layer_by_index);
|
||||
if (ogr_layer)
|
||||
{
|
||||
OGRFeatureDefn* def = ogr_layer->GetLayerDefn();
|
||||
if (def != 0) {
|
||||
layerName_ = def->GetName();
|
||||
layer_ = ogr_layer;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << "OGR Plugin: missing <layer> or <layer_by_index> parameter, available layers are: ";
|
||||
unsigned num_layers = dataset_->GetLayerCount();
|
||||
bool found = false;
|
||||
for (unsigned i = 0; i < num_layers; ++i )
|
||||
{
|
||||
OGRLayer *ogr_layer = dataset_->GetLayer(i);
|
||||
OGRFeatureDefn* def = ogr_layer->GetLayerDefn();
|
||||
if (def != 0) {
|
||||
found = true;
|
||||
s << " '" << def->GetName() << "' ";
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
s << "None (no layers were found in dataset)";
|
||||
}
|
||||
throw datasource_exception(s.str());
|
||||
}
|
||||
// initialize layer
|
||||
|
||||
if (!layer_)
|
||||
{
|
||||
std::string s("OGR Plugin: ");
|
||||
if (layer_by_name) s += "cannot find layer by name '" + *layer_by_name;
|
||||
else if (layer_by_index) s += "cannot find layer by index number '" + *layer_by_index;
|
||||
s += "' in dataset '" + dataset_name_ + "'";
|
||||
throw datasource_exception(s);
|
||||
}
|
||||
|
||||
// initialize envelope
|
||||
OGREnvelope envelope;
|
||||
layer_->GetExtent (&envelope);
|
||||
extent_.init (envelope.MinX, envelope.MinY, envelope.MaxX, envelope.MaxY);
|
||||
boost::optional<std::string> layer_by_name = params_.get<std::string>("layer");
|
||||
boost::optional<unsigned> layer_by_index = params_.get<unsigned>("layer_by_index");
|
||||
|
||||
// scan for index file
|
||||
// TODO - layer names don't match dataset name, so this will break for
|
||||
// any layer types of ogr than shapefiles, etc
|
||||
// fix here and in ogrindex
|
||||
size_t breakpoint = dataset_name_.find_last_of (".");
|
||||
if (breakpoint == std::string::npos) breakpoint = dataset_name_.length();
|
||||
index_name_ = dataset_name_.substr(0, breakpoint) + ".ogrindex";
|
||||
std::ifstream index_file (index_name_.c_str(), std::ios::in | std::ios::binary);
|
||||
if (index_file)
|
||||
{
|
||||
indexed_=true;
|
||||
index_file.close();
|
||||
}
|
||||
// enable this warning once the ogrindex tool is a bit more stable/mature
|
||||
//else
|
||||
/*{
|
||||
std::clog << "### Notice: no ogrindex file found for " + dataset_name_ + ", use the 'ogrindex' program to build an index for faster rendering\n";
|
||||
}*/
|
||||
if (layer_by_name && layer_by_index)
|
||||
{
|
||||
throw datasource_exception("OGR Plugin: you can only select an ogr layer by name ('layer' parameter) or by number ('layer_by_index' parameter), do not supply both parameters" );
|
||||
}
|
||||
|
||||
// deal with attributes descriptions
|
||||
OGRFeatureDefn* def = layer_->GetLayerDefn ();
|
||||
if (def != 0)
|
||||
{
|
||||
int fld_count = def->GetFieldCount ();
|
||||
for (int i = 0; i < fld_count; i++)
|
||||
{
|
||||
OGRFieldDefn* fld = def->GetFieldDefn (i);
|
||||
if (layer_by_name)
|
||||
{
|
||||
layerName_ = *layer_by_name;
|
||||
layer_ = dataset_->GetLayerByName(layerName_.c_str());
|
||||
}
|
||||
else if (layer_by_index)
|
||||
{
|
||||
const unsigned num_layers = dataset_->GetLayerCount();
|
||||
if (*layer_by_index >= num_layers)
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << "OGR Plugin: only ";
|
||||
s << num_layers;
|
||||
s << " layer(s) exist, cannot find layer by index '" << *layer_by_index << "'";
|
||||
|
||||
std::string fld_name = fld->GetNameRef ();
|
||||
OGRFieldType type_oid = fld->GetType ();
|
||||
throw datasource_exception(s.str());
|
||||
}
|
||||
|
||||
switch (type_oid)
|
||||
{
|
||||
case OFTInteger:
|
||||
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer));
|
||||
break;
|
||||
OGRLayer* ogr_layer = dataset_->GetLayer(*layer_by_index);
|
||||
if (ogr_layer)
|
||||
{
|
||||
OGRFeatureDefn* def = ogr_layer->GetLayerDefn();
|
||||
if (def != 0)
|
||||
{
|
||||
layerName_ = def->GetName();
|
||||
layer_ = ogr_layer;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << "OGR Plugin: missing <layer> or <layer_by_index> parameter, available layers are: ";
|
||||
|
||||
case OFTReal:
|
||||
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Double));
|
||||
break;
|
||||
|
||||
case OFTString:
|
||||
case OFTWideString: // deprecated
|
||||
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));
|
||||
break;
|
||||
|
||||
case OFTBinary:
|
||||
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Object));
|
||||
break;
|
||||
unsigned num_layers = dataset_->GetLayerCount();
|
||||
bool layer_found = false;
|
||||
for (unsigned i = 0; i < num_layers; ++i )
|
||||
{
|
||||
OGRLayer* ogr_layer = dataset_->GetLayer(i);
|
||||
OGRFeatureDefn* ogr_layer_def = ogr_layer->GetLayerDefn();
|
||||
if (ogr_layer_def != 0)
|
||||
{
|
||||
layer_found = true;
|
||||
s << " '" << ogr_layer_def->GetName() << "' ";
|
||||
}
|
||||
}
|
||||
|
||||
case OFTIntegerList:
|
||||
case OFTRealList:
|
||||
case OFTStringList:
|
||||
case OFTWideStringList: // deprecated !
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unhandled type_oid=" << type_oid << std::endl;
|
||||
if (! layer_found)
|
||||
{
|
||||
s << "None (no layers were found in dataset)";
|
||||
}
|
||||
|
||||
throw datasource_exception(s.str());
|
||||
}
|
||||
|
||||
if (! layer_)
|
||||
{
|
||||
std::string s("OGR Plugin: ");
|
||||
|
||||
if (layer_by_name)
|
||||
{
|
||||
s += "cannot find layer by name '" + *layer_by_name;
|
||||
}
|
||||
else if (layer_by_index)
|
||||
{
|
||||
s += "cannot find layer by index number '" + *layer_by_index;
|
||||
}
|
||||
|
||||
s += "' in dataset '" + dataset_name_ + "'";
|
||||
|
||||
throw datasource_exception(s);
|
||||
}
|
||||
|
||||
// initialize envelope
|
||||
OGREnvelope envelope;
|
||||
layer_->GetExtent(&envelope);
|
||||
extent_.init(envelope.MinX, envelope.MinY, envelope.MaxX, envelope.MaxY);
|
||||
|
||||
// scan for index file
|
||||
// TODO - layer names don't match dataset name, so this will break for
|
||||
// any layer types of ogr than shapefiles, etc
|
||||
// fix here and in ogrindex
|
||||
size_t breakpoint = dataset_name_.find_last_of(".");
|
||||
if (breakpoint == std::string::npos)
|
||||
{
|
||||
breakpoint = dataset_name_.length();
|
||||
}
|
||||
index_name_ = dataset_name_.substr(0, breakpoint) + ".ogrindex";
|
||||
|
||||
std::ifstream index_file (index_name_.c_str(), std::ios::in | std::ios::binary);
|
||||
if (index_file)
|
||||
{
|
||||
indexed_ = true;
|
||||
index_file.close();
|
||||
}
|
||||
#if 0
|
||||
// TODO - enable this warning once the ogrindex tool is a bit more stable/mature
|
||||
else
|
||||
{
|
||||
std::clog << "### Notice: no ogrindex file found for " << dataset_name_
|
||||
<< ", use the 'ogrindex' program to build an index for faster rendering"
|
||||
<< std::endl;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OFTDate:
|
||||
case OFTTime:
|
||||
case OFTDateTime: // unhandled !
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unhandled type_oid=" << type_oid << std::endl;
|
||||
#endif
|
||||
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Object));
|
||||
break;
|
||||
// deal with attributes descriptions
|
||||
OGRFeatureDefn* def = layer_->GetLayerDefn();
|
||||
if (def != 0)
|
||||
{
|
||||
const int fld_count = def->GetFieldCount();
|
||||
for (int i = 0; i < fld_count; i++)
|
||||
{
|
||||
OGRFieldDefn* fld = def->GetFieldDefn(i);
|
||||
|
||||
default: // unknown
|
||||
const std::string fld_name = fld->GetNameRef();
|
||||
const OGRFieldType type_oid = fld->GetType();
|
||||
|
||||
switch (type_oid)
|
||||
{
|
||||
case OFTInteger:
|
||||
desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Integer));
|
||||
break;
|
||||
|
||||
case OFTReal:
|
||||
desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Double));
|
||||
break;
|
||||
|
||||
case OFTString:
|
||||
case OFTWideString: // deprecated
|
||||
desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::String));
|
||||
break;
|
||||
|
||||
case OFTBinary:
|
||||
desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Object));
|
||||
break;
|
||||
|
||||
case OFTIntegerList:
|
||||
case OFTRealList:
|
||||
case OFTStringList:
|
||||
case OFTWideStringList: // deprecated !
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unknown type_oid=" << type_oid << std::endl;
|
||||
std::clog << "OGR Plugin: unhandled type_oid=" << type_oid << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is_bound_ = true;
|
||||
break;
|
||||
|
||||
case OFTDate:
|
||||
case OFTTime:
|
||||
case OFTDateTime: // unhandled !
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unhandled type_oid=" << type_oid << std::endl;
|
||||
#endif
|
||||
desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Object));
|
||||
break;
|
||||
|
||||
default: // unknown
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unknown type_oid=" << type_oid << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is_bound_ = true;
|
||||
}
|
||||
|
||||
std::string ogr_datasource::name()
|
||||
{
|
||||
return "ogr";
|
||||
return "ogr";
|
||||
}
|
||||
|
||||
int ogr_datasource::type() const
|
||||
{
|
||||
return type_;
|
||||
return type_;
|
||||
}
|
||||
|
||||
box2d<double> ogr_datasource::envelope() const
|
||||
{
|
||||
if (!is_bound_) bind();
|
||||
return extent_;
|
||||
if (! is_bound_) bind();
|
||||
return extent_;
|
||||
}
|
||||
|
||||
layer_descriptor ogr_datasource::get_descriptor() const
|
||||
{
|
||||
if (!is_bound_) bind();
|
||||
return desc_;
|
||||
if (! is_bound_) bind();
|
||||
return desc_;
|
||||
}
|
||||
|
||||
featureset_ptr ogr_datasource::features(query const& q) const
|
||||
{
|
||||
if (!is_bound_) bind();
|
||||
if (! is_bound_) bind();
|
||||
|
||||
if (dataset_ && layer_)
|
||||
{
|
||||
|
||||
if (dataset_ && layer_)
|
||||
{
|
||||
#if 0
|
||||
// TODO - actually filter fields!
|
||||
// http://trac.osgeo.org/gdal/wiki/rfc29_desired_fields
|
||||
// http://trac.osgeo.org/gdal/wiki/rfc28_sqlfunc
|
||||
#if 0
|
||||
|
||||
std::ostringstream s;
|
||||
|
||||
s << "select ";
|
||||
std::set<std::string> const& props=q.property_names();
|
||||
std::set<std::string>::const_iterator pos=props.begin();
|
||||
std::set<std::string>::const_iterator end=props.end();
|
||||
std::set<std::string> const& props = q.property_names();
|
||||
std::set<std::string>::const_iterator pos = props.begin();
|
||||
std::set<std::string>::const_iterator end = props.end();
|
||||
while (pos != end)
|
||||
{
|
||||
s <<",\""<<*pos<<"\"";
|
||||
s << ",\"" << *pos << "\"";
|
||||
++pos;
|
||||
}
|
||||
s << " from " << layerName_ ;
|
||||
|
||||
// execute existing SQL
|
||||
OGRLayer* layer = dataset_->ExecuteSQL (s.str(), poly);
|
||||
OGRLayer* layer = dataset_->ExecuteSQL(s.str(), poly);
|
||||
|
||||
// layer must be freed
|
||||
dataset_->ReleaseResultSet (layer);
|
||||
dataset_->ReleaseResultSet(layer);
|
||||
#endif
|
||||
|
||||
if (indexed_)
|
||||
{
|
||||
filter_in_box filter(q.get_bbox());
|
||||
|
||||
return featureset_ptr(new ogr_index_featureset<filter_in_box> (*dataset_,
|
||||
*layer_,
|
||||
filter,
|
||||
index_name_,
|
||||
desc_.get_encoding(),
|
||||
multiple_geometries_));
|
||||
return featureset_ptr(new ogr_index_featureset<filter_in_box>(*dataset_,
|
||||
*layer_,
|
||||
filter,
|
||||
index_name_,
|
||||
desc_.get_encoding(),
|
||||
multiple_geometries_));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -333,16 +369,16 @@ featureset_ptr ogr_datasource::features(query const& q) const
|
|||
desc_.get_encoding(),
|
||||
multiple_geometries_));
|
||||
}
|
||||
}
|
||||
return featureset_ptr();
|
||||
}
|
||||
return featureset_ptr();
|
||||
}
|
||||
|
||||
featureset_ptr ogr_datasource::features_at_point(coord2d const& pt) const
|
||||
{
|
||||
if (!is_bound_) bind();
|
||||
if (!is_bound_) bind();
|
||||
|
||||
if (dataset_ && layer_)
|
||||
{
|
||||
if (dataset_ && layer_)
|
||||
{
|
||||
if (indexed_)
|
||||
{
|
||||
filter_at_point filter(pt);
|
||||
|
@ -366,7 +402,6 @@ featureset_ptr ogr_datasource::features_at_point(coord2d const& pt) const
|
|||
desc_.get_encoding(),
|
||||
multiple_geometries_));
|
||||
}
|
||||
}
|
||||
return featureset_ptr();
|
||||
}
|
||||
return featureset_ptr();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -37,28 +37,29 @@
|
|||
|
||||
class ogr_datasource : public mapnik::datasource
|
||||
{
|
||||
public:
|
||||
ogr_datasource(mapnik::parameters const& params, bool bind=true);
|
||||
virtual ~ogr_datasource ();
|
||||
int type() const;
|
||||
static std::string name();
|
||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||
mapnik::box2d<double> envelope() const;
|
||||
mapnik::layer_descriptor get_descriptor() const;
|
||||
void bind() const;
|
||||
private:
|
||||
mutable mapnik::box2d<double> extent_;
|
||||
int type_;
|
||||
std::string dataset_name_;
|
||||
mutable std::string index_name_;
|
||||
mutable OGRDataSource* dataset_;
|
||||
mutable OGRLayer* layer_;
|
||||
mutable std::string layerName_;
|
||||
mutable mapnik::layer_descriptor desc_;
|
||||
bool multiple_geometries_;
|
||||
mutable bool indexed_;
|
||||
public:
|
||||
ogr_datasource(mapnik::parameters const& params, bool bind=true);
|
||||
virtual ~ogr_datasource ();
|
||||
|
||||
int type() const;
|
||||
static std::string name();
|
||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||
mapnik::box2d<double> envelope() const;
|
||||
mapnik::layer_descriptor get_descriptor() const;
|
||||
void bind() const;
|
||||
|
||||
private:
|
||||
mutable mapnik::box2d<double> extent_;
|
||||
int type_;
|
||||
std::string dataset_name_;
|
||||
mutable std::string index_name_;
|
||||
mutable OGRDataSource* dataset_;
|
||||
mutable OGRLayer* layer_;
|
||||
mutable std::string layerName_;
|
||||
mutable mapnik::layer_descriptor desc_;
|
||||
bool multiple_geometries_;
|
||||
mutable bool indexed_;
|
||||
};
|
||||
|
||||
|
||||
#endif // OGR_DATASOURCE_HPP
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -51,4 +51,3 @@ private:
|
|||
};
|
||||
|
||||
#endif // OGR_FEATURE_PTR_HPP
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -51,13 +51,13 @@ ogr_featureset::ogr_featureset(OGRDataSource & dataset,
|
|||
OGRGeometry & extent,
|
||||
const std::string& encoding,
|
||||
const bool multiple_geometries)
|
||||
: dataset_(dataset),
|
||||
layer_(layer),
|
||||
layerdef_(layer.GetLayerDefn()),
|
||||
tr_(new transcoder(encoding)),
|
||||
fidcolumn_(layer_.GetFIDColumn ()),
|
||||
multiple_geometries_(multiple_geometries),
|
||||
count_(0)
|
||||
: dataset_(dataset),
|
||||
layer_(layer),
|
||||
layerdef_(layer.GetLayerDefn()),
|
||||
tr_(new transcoder(encoding)),
|
||||
fidcolumn_(layer_.GetFIDColumn ()),
|
||||
multiple_geometries_(multiple_geometries),
|
||||
count_(0)
|
||||
{
|
||||
layer_.SetSpatialFilter (&extent);
|
||||
}
|
||||
|
@ -67,13 +67,13 @@ ogr_featureset::ogr_featureset(OGRDataSource & dataset,
|
|||
const mapnik::box2d<double> & extent,
|
||||
const std::string& encoding,
|
||||
const bool multiple_geometries)
|
||||
: dataset_(dataset),
|
||||
layer_(layer),
|
||||
layerdef_(layer.GetLayerDefn()),
|
||||
tr_(new transcoder(encoding)),
|
||||
fidcolumn_(layer_.GetFIDColumn()),
|
||||
multiple_geometries_(multiple_geometries),
|
||||
count_(0)
|
||||
: dataset_(dataset),
|
||||
layer_(layer),
|
||||
layerdef_(layer.GetLayerDefn()),
|
||||
tr_(new transcoder(encoding)),
|
||||
fidcolumn_(layer_.GetFIDColumn()),
|
||||
multiple_geometries_(multiple_geometries),
|
||||
count_(0)
|
||||
{
|
||||
layer_.SetSpatialFilterRect (extent.minx(),
|
||||
extent.miny(),
|
||||
|
@ -81,27 +81,31 @@ ogr_featureset::ogr_featureset(OGRDataSource & dataset,
|
|||
extent.maxy());
|
||||
}
|
||||
|
||||
ogr_featureset::~ogr_featureset() {}
|
||||
ogr_featureset::~ogr_featureset()
|
||||
{
|
||||
}
|
||||
|
||||
feature_ptr ogr_featureset::next()
|
||||
{
|
||||
ogr_feature_ptr feat (layer_.GetNextFeature());
|
||||
|
||||
if ((*feat) != NULL)
|
||||
{
|
||||
// ogr feature ids start at 0, so add one to stay
|
||||
// consistent with other mapnik datasources that start at 1
|
||||
int feature_id = ((*feat)->GetFID() + 1);
|
||||
const int feature_id = ((*feat)->GetFID() + 1);
|
||||
feature_ptr feature(feature_factory::create(feature_id));
|
||||
|
||||
OGRGeometry* geom=(*feat)->GetGeometryRef();
|
||||
if (geom && !geom->IsEmpty())
|
||||
OGRGeometry* geom = (*feat)->GetGeometryRef();
|
||||
if (geom && ! geom->IsEmpty())
|
||||
{
|
||||
ogr_converter::convert_geometry (geom, feature, multiple_geometries_);
|
||||
ogr_converter::convert_geometry(geom, feature, multiple_geometries_);
|
||||
}
|
||||
#ifdef MAPNIK_DEBUG
|
||||
else
|
||||
{
|
||||
std::clog << "### Warning: feature with null geometry: " << (*feat)->GetFID() << "\n";
|
||||
std::clog << "OGR Plugin: feature with null geometry: "
|
||||
<< (*feat)->GetFID() << std::endl;
|
||||
}
|
||||
#endif
|
||||
++count_;
|
||||
|
@ -109,30 +113,30 @@ feature_ptr ogr_featureset::next()
|
|||
int fld_count = layerdef_->GetFieldCount();
|
||||
for (int i = 0; i < fld_count; i++)
|
||||
{
|
||||
OGRFieldDefn* fld = layerdef_->GetFieldDefn (i);
|
||||
OGRFieldType type_oid = fld->GetType ();
|
||||
std::string fld_name = fld->GetNameRef ();
|
||||
OGRFieldDefn* fld = layerdef_->GetFieldDefn(i);
|
||||
const OGRFieldType type_oid = fld->GetType();
|
||||
const std::string fld_name = fld->GetNameRef();
|
||||
|
||||
switch (type_oid)
|
||||
{
|
||||
case OFTInteger:
|
||||
{
|
||||
boost::put(*feature,fld_name,(*feat)->GetFieldAsInteger (i));
|
||||
break;
|
||||
boost::put(*feature, fld_name, (*feat)->GetFieldAsInteger(i));
|
||||
break;
|
||||
}
|
||||
|
||||
case OFTReal:
|
||||
{
|
||||
boost::put(*feature,fld_name,(*feat)->GetFieldAsDouble (i));
|
||||
break;
|
||||
boost::put(*feature, fld_name, (*feat)->GetFieldAsDouble(i));
|
||||
break;
|
||||
}
|
||||
|
||||
case OFTString:
|
||||
case OFTWideString: // deprecated !
|
||||
{
|
||||
UnicodeString ustr = tr_->transcode((*feat)->GetFieldAsString (i));
|
||||
boost::put(*feature,fld_name,ustr);
|
||||
break;
|
||||
UnicodeString ustr = tr_->transcode((*feat)->GetFieldAsString(i));
|
||||
boost::put(*feature, fld_name, ustr);
|
||||
break;
|
||||
}
|
||||
|
||||
case OFTIntegerList:
|
||||
|
@ -140,37 +144,37 @@ feature_ptr ogr_featureset::next()
|
|||
case OFTStringList:
|
||||
case OFTWideStringList: // deprecated !
|
||||
{
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unhandled type_oid=" << type_oid << std::endl;
|
||||
#endif
|
||||
break;
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unhandled type_oid=" << type_oid << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case OFTBinary:
|
||||
{
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unhandled type_oid=" << type_oid << std::endl;
|
||||
#endif
|
||||
//boost::put(*feature,name,feat->GetFieldAsBinary (i, size));
|
||||
break;
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unhandled type_oid=" << type_oid << std::endl;
|
||||
#endif
|
||||
//boost::put(*feature,name,feat->GetFieldAsBinary (i, size));
|
||||
break;
|
||||
}
|
||||
|
||||
case OFTDate:
|
||||
case OFTTime:
|
||||
case OFTDateTime: // unhandled !
|
||||
{
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unhandled type_oid=" << type_oid << std::endl;
|
||||
#endif
|
||||
break;
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unhandled type_oid=" << type_oid << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
default: // unknown
|
||||
{
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unknown type_oid=" << type_oid << std::endl;
|
||||
#endif
|
||||
break;
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "OGR Plugin: unknown type_oid=" << type_oid << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -182,4 +186,3 @@ feature_ptr ogr_featureset::next()
|
|||
#endif
|
||||
return feature_ptr();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -37,30 +37,32 @@
|
|||
|
||||
class ogr_featureset : public mapnik::Featureset
|
||||
{
|
||||
OGRDataSource & dataset_;
|
||||
OGRLayer & layer_;
|
||||
OGRFeatureDefn * layerdef_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
const char* fidcolumn_;
|
||||
bool multiple_geometries_;
|
||||
mutable int count_;
|
||||
public:
|
||||
ogr_featureset(OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
OGRGeometry & extent,
|
||||
const std::string& encoding,
|
||||
const bool multiple_geometries);
|
||||
public:
|
||||
ogr_featureset(OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
OGRGeometry & extent,
|
||||
const std::string& encoding,
|
||||
const bool multiple_geometries);
|
||||
|
||||
ogr_featureset(OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
const mapnik::box2d<double> & extent,
|
||||
const std::string& encoding,
|
||||
const bool multiple_geometries);
|
||||
virtual ~ogr_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
private:
|
||||
ogr_featureset(const ogr_featureset&);
|
||||
const ogr_featureset& operator=(const ogr_featureset&);
|
||||
ogr_featureset(OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
const mapnik::box2d<double> & extent,
|
||||
const std::string& encoding,
|
||||
const bool multiple_geometries);
|
||||
virtual ~ogr_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
|
||||
private:
|
||||
ogr_featureset(const ogr_featureset&);
|
||||
const ogr_featureset& operator=(const ogr_featureset&);
|
||||
|
||||
OGRDataSource& dataset_;
|
||||
OGRLayer& layer_;
|
||||
OGRFeatureDefn* layerdef_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
const char* fidcolumn_;
|
||||
bool multiple_geometries_;
|
||||
mutable int count_;
|
||||
};
|
||||
|
||||
#endif // OGR_FEATURESET_HPP
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2006 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -37,18 +37,18 @@ template <typename filterT, typename IStream = std::ifstream>
|
|||
class ogr_index
|
||||
{
|
||||
public:
|
||||
static void query(const filterT& filter, IStream& file,std::vector<int>& pos);
|
||||
static void query(const filterT& filter, IStream& file, std::vector<int>& pos);
|
||||
private:
|
||||
ogr_index();
|
||||
~ogr_index();
|
||||
ogr_index(const ogr_index&);
|
||||
ogr_index& operator=(const ogr_index&);
|
||||
static int read_ndr_integer(IStream & in);
|
||||
static void read_envelope(IStream & in,box2d<double> &envelope);
|
||||
static void query_node(const filterT& filter,IStream & in,std::vector<int>& pos);
|
||||
static int read_ndr_integer(IStream& in);
|
||||
static void read_envelope(IStream& in, box2d<double>& envelope);
|
||||
static void query_node(const filterT& filter, IStream& in, std::vector<int>& pos);
|
||||
};
|
||||
|
||||
template <typename filterT,typename IStream>
|
||||
template <typename filterT, typename IStream>
|
||||
void ogr_index<filterT, IStream>::query(const filterT& filter,IStream & file,std::vector<int>& pos)
|
||||
{
|
||||
file.seekg(16,std::ios::beg);
|
||||
|
@ -56,50 +56,49 @@ void ogr_index<filterT, IStream>::query(const filterT& filter,IStream & file,std
|
|||
}
|
||||
|
||||
template <typename filterT, typename IStream>
|
||||
void ogr_index<filterT,IStream>::query_node(const filterT& filter,IStream & file,std::vector<int>& ids)
|
||||
void ogr_index<filterT,IStream>::query_node(const filterT& filter, IStream& file, std::vector<int>& ids)
|
||||
{
|
||||
int offset=read_ndr_integer(file);
|
||||
const int offset = read_ndr_integer(file);
|
||||
|
||||
box2d<double> node_ext;
|
||||
read_envelope(file,node_ext);
|
||||
read_envelope(file, node_ext);
|
||||
|
||||
int num_shapes=read_ndr_integer(file);
|
||||
const int num_shapes = read_ndr_integer(file);
|
||||
|
||||
if (!filter.pass(node_ext))
|
||||
if (! filter.pass(node_ext))
|
||||
{
|
||||
file.seekg(offset+num_shapes*4+4,std::ios::cur);
|
||||
file.seekg(offset + num_shapes * 4 + 4, std::ios::cur);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=0;i<num_shapes;++i)
|
||||
for (int i = 0; i < num_shapes; ++i)
|
||||
{
|
||||
int id=read_ndr_integer(file);
|
||||
const int id = read_ndr_integer(file);
|
||||
ids.push_back(id);
|
||||
}
|
||||
|
||||
int children=read_ndr_integer(file);
|
||||
const int children = read_ndr_integer(file);
|
||||
|
||||
for (int j=0;j<children;++j)
|
||||
for (int j = 0; j < children; ++j)
|
||||
{
|
||||
query_node(filter,file,ids);
|
||||
query_node(filter, file, ids);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename filterT,typename IStream>
|
||||
int ogr_index<filterT,IStream>::read_ndr_integer(IStream & file)
|
||||
template <typename filterT, typename IStream>
|
||||
int ogr_index<filterT,IStream>::read_ndr_integer(IStream& file)
|
||||
{
|
||||
char b[4];
|
||||
file.read(b,4);
|
||||
return (b[0]&0xff) | (b[1]&0xff)<<8 | (b[2]&0xff)<<16 | (b[3]&0xff)<<24;
|
||||
file.read(b, 4);
|
||||
return (b[0] & 0xff) | (b[1] & 0xff) << 8 | (b[2] & 0xff) << 16 | (b[3] & 0xff) << 24;
|
||||
}
|
||||
|
||||
|
||||
template <typename filterT,typename IStream>
|
||||
void ogr_index<filterT,IStream>::read_envelope(IStream & file,box2d<double>& envelope)
|
||||
template <typename filterT, typename IStream>
|
||||
void ogr_index<filterT, IStream>::read_envelope(IStream& file, box2d<double>& envelope)
|
||||
{
|
||||
file.read(reinterpret_cast<char*>(&envelope),sizeof(envelope));
|
||||
file.read(reinterpret_cast<char*>(&envelope), sizeof(envelope));
|
||||
}
|
||||
|
||||
|
||||
#endif //SHP_INDEX_HH
|
||||
#endif // OGR_INDEX_HH
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 Artem Pavlenko
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -32,29 +32,29 @@
|
|||
template <typename filterT>
|
||||
class ogr_index_featureset : public mapnik::Featureset
|
||||
{
|
||||
OGRDataSource & dataset_;
|
||||
OGRLayer & layer_;
|
||||
OGRFeatureDefn * layerdef_;
|
||||
filterT filter_;
|
||||
std::vector<int> ids_;
|
||||
std::vector<int>::iterator itr_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
const char* fidcolumn_;
|
||||
bool multiple_geometries_;
|
||||
public:
|
||||
ogr_index_featureset(OGRDataSource& dataset,
|
||||
OGRLayer& layer,
|
||||
const filterT& filter,
|
||||
const std::string& index_file,
|
||||
const std::string& encoding,
|
||||
const bool multiple_geometries);
|
||||
virtual ~ogr_index_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
|
||||
public:
|
||||
ogr_index_featureset(OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
const filterT& filter,
|
||||
const std::string& index_file,
|
||||
const std::string& encoding,
|
||||
const bool multiple_geometries);
|
||||
virtual ~ogr_index_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
private:
|
||||
//no copying
|
||||
ogr_index_featureset(const ogr_index_featureset&);
|
||||
ogr_index_featureset& operator=(const ogr_index_featureset&);
|
||||
private:
|
||||
ogr_index_featureset(const ogr_index_featureset&);
|
||||
ogr_index_featureset& operator=(const ogr_index_featureset&);
|
||||
|
||||
OGRDataSource& dataset_;
|
||||
OGRLayer& layer_;
|
||||
OGRFeatureDefn* layerdef_;
|
||||
filterT filter_;
|
||||
std::vector<int> ids_;
|
||||
std::vector<int>::iterator itr_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
const char* fidcolumn_;
|
||||
bool multiple_geometries_;
|
||||
};
|
||||
|
||||
#endif // OGR_FEATURESET_HPP
|
||||
#endif // OGR_INDEX_FEATURESET_HPP
|
||||
|
|
|
@ -65,6 +65,10 @@ raster_datasource::raster_datasource(const parameters& params, bool bind)
|
|||
else
|
||||
filename_ = *file;
|
||||
|
||||
multi_tiles_ = *params_.get<bool>("multi", false);
|
||||
tile_size_ = *params_.get<unsigned>("tile_size", 256);
|
||||
tile_stride_ = *params_.get<unsigned>("tile_stride", 1);
|
||||
|
||||
format_=*params_.get<std::string>("format","tiff");
|
||||
|
||||
boost::optional<double> lox = params_.get<double>("lox");
|
||||
|
@ -96,33 +100,50 @@ void raster_datasource::bind() const
|
|||
{
|
||||
if (is_bound_) return;
|
||||
|
||||
if (! boost::filesystem::exists(filename_))
|
||||
throw datasource_exception("Raster Plugin: " + filename_ + " does not exist");
|
||||
|
||||
try
|
||||
{
|
||||
std::auto_ptr<image_reader> reader(mapnik::get_image_reader(filename_, format_));
|
||||
if (reader.get())
|
||||
{
|
||||
width_ = reader->width();
|
||||
height_ = reader->height();
|
||||
if (multi_tiles_)
|
||||
{
|
||||
boost::optional<unsigned> x_width = params_.get<unsigned>("x_width");
|
||||
boost::optional<unsigned> y_width = params_.get<unsigned>("y_width");
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "Raster Plugin: RASTER SIZE(" << width_ << "," << height_ << ")" << std::endl;
|
||||
#endif
|
||||
}
|
||||
if (!x_width)
|
||||
throw datasource_exception("Raster Plugin: x-width parameter not supplied for multi-tiled data source.");
|
||||
|
||||
if (!y_width)
|
||||
throw datasource_exception("Raster Plugin: y-width parameter not supplied for multi-tiled data source.");
|
||||
|
||||
width_ = x_width.get() * tile_size_;
|
||||
height_ = y_width.get() * tile_size_;
|
||||
}
|
||||
catch (mapnik::image_reader_exception const& ex)
|
||||
else
|
||||
{
|
||||
std::cerr << "Raster Plugin: image reader exception caught: " << ex.what() << std::endl;
|
||||
throw;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cerr << "Raster Plugin: exception caught" << std::endl;
|
||||
throw;
|
||||
if (! boost::filesystem::exists(filename_))
|
||||
throw datasource_exception("Raster Plugin: " + filename_ + " does not exist");
|
||||
|
||||
try
|
||||
{
|
||||
std::auto_ptr<image_reader> reader(mapnik::get_image_reader(filename_, format_));
|
||||
if (reader.get())
|
||||
{
|
||||
width_ = reader->width();
|
||||
height_ = reader->height();
|
||||
}
|
||||
}
|
||||
catch (mapnik::image_reader_exception const& ex)
|
||||
{
|
||||
std::cerr << "Raster Plugin: image reader exception caught: " << ex.what() << std::endl;
|
||||
throw;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cerr << "Raster Plugin: exception caught" << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "Raster Plugin: RASTER SIZE(" << width_ << "," << height_ << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
is_bound_ = true;
|
||||
}
|
||||
|
||||
|
@ -165,7 +186,16 @@ featureset_ptr raster_datasource::features(query const& q) const
|
|||
std::clog << "Raster Plugin: BOX SIZE(" << width << " " << height << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
if (width * height > 512*512)
|
||||
if (multi_tiles_)
|
||||
{
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "Raster Plugin: MULTI-TILED policy" << std::endl;
|
||||
#endif
|
||||
|
||||
tiled_multi_file_policy policy(filename_, format_, tile_size_, extent_, q.get_bbox(), width_, height_, tile_stride_);
|
||||
return boost::make_shared<raster_featureset<tiled_multi_file_policy> >(policy, extent_, q);
|
||||
}
|
||||
else if (width * height > 512*512)
|
||||
{
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "Raster Plugin: TILED policy" << std::endl;
|
||||
|
|
|
@ -37,6 +37,9 @@ class raster_datasource : public mapnik::datasource
|
|||
std::string format_;
|
||||
mapnik::box2d<double> extent_;
|
||||
bool extent_initialized_;
|
||||
bool multi_tiles_;
|
||||
unsigned tile_size_;
|
||||
unsigned tile_stride_;
|
||||
mutable unsigned width_;
|
||||
mutable unsigned height_;
|
||||
public:
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "raster_featureset.hpp"
|
||||
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
using mapnik::query;
|
||||
using mapnik::CoordTransform;
|
||||
|
@ -67,16 +68,18 @@ feature_ptr raster_featureset<LookupPolicy>::next()
|
|||
std::clog << "Raster Plugin: READER = " << curIter_->format() << " " << curIter_->file()
|
||||
<< " size(" << curIter_->width() << "," << curIter_->height() << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
if (reader.get())
|
||||
{
|
||||
int image_width=reader->width();
|
||||
int image_height=reader->height();
|
||||
int image_width = policy_.img_width(reader->width());
|
||||
int image_height = policy_.img_height(reader->height());
|
||||
|
||||
if (image_width>0 && image_height>0)
|
||||
{
|
||||
CoordTransform t(image_width,image_height,extent_,0,0);
|
||||
box2d<double> intersect=bbox_.intersect(curIter_->envelope());
|
||||
box2d<double> ext=t.forward(intersect);
|
||||
box2d<double> rem=policy_.transform(ext);
|
||||
if ( ext.width()>0.5 && ext.height()>0.5 )
|
||||
{
|
||||
//select minimum raster containing whole ext
|
||||
|
@ -96,7 +99,8 @@ feature_ptr raster_featureset<LookupPolicy>::next()
|
|||
int width = end_x - x_off;
|
||||
int height = end_y - y_off;
|
||||
//calculate actual box2d of returned raster
|
||||
box2d<double> feature_raster_extent(x_off, y_off, x_off+width, y_off+height);
|
||||
box2d<double> feature_raster_extent(rem.minx() + x_off, rem.miny() + y_off,
|
||||
rem.maxx() + x_off + width, rem.maxy() + y_off + height);
|
||||
intersect = t.backward(feature_raster_extent);
|
||||
|
||||
image_data_32 image(width,height);
|
||||
|
@ -121,5 +125,20 @@ feature_ptr raster_featureset<LookupPolicy>::next()
|
|||
return feature_ptr();
|
||||
}
|
||||
|
||||
std::string
|
||||
tiled_multi_file_policy::interpolate(std::string const &pattern, int x, int y) const
|
||||
{
|
||||
// TODO: make from some sort of configurable interpolation
|
||||
int tms_y = tile_stride_ * ((image_height_ / tile_size_) - y - 1);
|
||||
int tms_x = tile_stride_ * x;
|
||||
std::string xs = (boost::format("%03d/%03d/%03d") % (tms_x / 1000000) % ((tms_x / 1000) % 1000) % (tms_x % 1000)).str();
|
||||
std::string ys = (boost::format("%03d/%03d/%03d") % (tms_y / 1000000) % ((tms_y / 1000) % 1000) % (tms_y % 1000)).str();
|
||||
std::string rv(pattern);
|
||||
boost::algorithm::replace_all(rv, "${x}", xs);
|
||||
boost::algorithm::replace_all(rv, "${y}", ys);
|
||||
return rv;
|
||||
}
|
||||
|
||||
template class raster_featureset<single_file_policy>;
|
||||
template class raster_featureset<tiled_file_policy>;
|
||||
template class raster_featureset<tiled_multi_file_policy>;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
// boost
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
class single_file_policy
|
||||
{
|
||||
|
@ -95,6 +95,21 @@ public:
|
|||
{
|
||||
return const_iterator();
|
||||
}
|
||||
|
||||
inline int img_width(int reader_width) const
|
||||
{
|
||||
return reader_width;
|
||||
}
|
||||
|
||||
inline int img_height(int reader_height) const
|
||||
{
|
||||
return reader_height;
|
||||
}
|
||||
|
||||
inline box2d<double> transform(box2d<double> &) const
|
||||
{
|
||||
return box2d<double>(0, 0, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
class tiled_file_policy
|
||||
|
@ -154,11 +169,125 @@ public:
|
|||
return infos_.end();
|
||||
}
|
||||
|
||||
inline int img_width(int reader_width) const
|
||||
{
|
||||
return reader_width;
|
||||
}
|
||||
|
||||
inline int img_height(int reader_height) const
|
||||
{
|
||||
return reader_height;
|
||||
}
|
||||
|
||||
inline box2d<double> transform(box2d<double> &) const
|
||||
{
|
||||
return box2d<double>(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::vector<raster_info> infos_;
|
||||
};
|
||||
|
||||
class tiled_multi_file_policy
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::vector<raster_info>::const_iterator const_iterator;
|
||||
|
||||
tiled_multi_file_policy(std::string const& file_pattern, std::string const& format, unsigned tile_size,
|
||||
box2d<double> extent, box2d<double> bbox,unsigned width, unsigned height,
|
||||
unsigned tile_stride)
|
||||
: image_width_(width), image_height_(height), tile_size_(tile_size), tile_stride_(tile_stride)
|
||||
{
|
||||
|
||||
double lox = extent.minx();
|
||||
double loy = extent.miny();
|
||||
|
||||
int max_x = int(std::ceil(double(width)/double(tile_size)));
|
||||
int max_y = int(std::ceil(double(height)/double(tile_size)));
|
||||
|
||||
double pixel_x = extent.width()/double(width);
|
||||
double pixel_y = extent.height()/double(height);
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "Raster Plugin: PIXEL SIZE("<< pixel_x << "," << pixel_y << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
// intersection of query with extent => new query
|
||||
box2d<double> e = bbox.intersect(extent);
|
||||
|
||||
const int x_min = int(std::floor((e.minx() - lox) / (tile_size * pixel_x)));
|
||||
const int y_min = int(std::floor((e.miny() - loy) / (tile_size * pixel_y)));
|
||||
const int x_max = int(std::ceil((e.maxx() - lox) / (tile_size * pixel_x)));
|
||||
const int y_max = int(std::ceil((e.maxy() - loy) / (tile_size * pixel_y)));
|
||||
|
||||
for (int x = x_min ; x < x_max ; ++x)
|
||||
{
|
||||
for (int y = y_min ; y < y_max ; ++y)
|
||||
{
|
||||
// x0, y0, x1, y1 => projection-space image coordinates.
|
||||
double x0 = lox + x*tile_size*pixel_x;
|
||||
double y0 = loy + y*tile_size*pixel_y;
|
||||
double x1 = x0 + tile_size*pixel_x;
|
||||
double y1 = y0 + tile_size*pixel_y;
|
||||
|
||||
// check if it intersects the query
|
||||
if (e.intersects(box2d<double>(x0,y0,x1,y1)))
|
||||
{
|
||||
// tile_box => intersection of tile with query in projection-space.
|
||||
box2d<double> tile_box = e.intersect(box2d<double>(x0,y0,x1,y1));
|
||||
std::string file = interpolate(file_pattern, x, y);
|
||||
raster_info info(file,format,tile_box,tile_size,tile_size);
|
||||
infos_.push_back(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "Raster Plugin: INFO SIZE=" << infos_.size() << " " << file_pattern << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
const_iterator begin()
|
||||
{
|
||||
return infos_.begin();
|
||||
}
|
||||
|
||||
const_iterator end()
|
||||
{
|
||||
return infos_.end();
|
||||
}
|
||||
|
||||
inline int img_width(int) const
|
||||
{
|
||||
return image_width_;
|
||||
}
|
||||
|
||||
inline int img_height(int) const
|
||||
{
|
||||
return image_height_;
|
||||
}
|
||||
|
||||
inline box2d<double> transform(box2d<double> &box) const
|
||||
{
|
||||
int x_offset = int(std::floor(box.minx() / tile_size_));
|
||||
int y_offset = int(std::floor(box.miny() / tile_size_));
|
||||
box2d<double> rem(x_offset * tile_size_, y_offset * tile_size_,
|
||||
x_offset * tile_size_, y_offset * tile_size_);
|
||||
box.init(box.minx() - rem.minx(),
|
||||
box.miny() - rem.miny(),
|
||||
box.maxx() - rem.maxx(),
|
||||
box.maxy() - rem.maxy());
|
||||
return rem;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::string interpolate(std::string const &pattern, int x, int y) const;
|
||||
|
||||
unsigned int image_width_, image_height_, tile_size_, tile_stride_;
|
||||
std::vector<raster_info> infos_;
|
||||
};
|
||||
|
||||
template <typename LookupPolicy>
|
||||
class raster_featureset : public mapnik::Featureset
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
// boost
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
// sqlite
|
||||
extern "C" {
|
||||
|
@ -45,13 +46,11 @@ class sqlite_utils
|
|||
{
|
||||
public:
|
||||
|
||||
static void dequote(std::string& s)
|
||||
static void dequote(std::string & z)
|
||||
{
|
||||
if (s[0] == '[' || s[0] == '\'' || s[0] == '"' || s[0] == '`')
|
||||
{
|
||||
s = s.substr(1, s.length() - 1);
|
||||
}
|
||||
boost::algorithm::trim_if(z,boost::algorithm::is_any_of("[]'\"`"));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
|
||||
// boost
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
// stl
|
||||
#ifdef MAPNIK_DEBUG
|
||||
|
@ -121,8 +121,31 @@ agg_renderer<T>::agg_renderer(Map const& m, T & pixmap, double scale_factor, uns
|
|||
t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y),
|
||||
font_engine_(),
|
||||
font_manager_(font_engine_),
|
||||
detector_(box2d<double>(-m.buffer_size(), -m.buffer_size(), m.width() + m.buffer_size() ,m.height() + m.buffer_size())),
|
||||
detector_(boost::make_shared<label_collision_detector4>(box2d<double>(-m.buffer_size(), -m.buffer_size(), m.width() + m.buffer_size() ,m.height() + m.buffer_size()))),
|
||||
ras_ptr(new rasterizer)
|
||||
{
|
||||
setup(m);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
agg_renderer<T>::agg_renderer(Map const& m, T & pixmap, boost::shared_ptr<label_collision_detector4> detector,
|
||||
double scale_factor, unsigned offset_x, unsigned offset_y)
|
||||
: feature_style_processor<agg_renderer>(m, scale_factor),
|
||||
pixmap_(pixmap),
|
||||
width_(pixmap_.width()),
|
||||
height_(pixmap_.height()),
|
||||
scale_factor_(scale_factor),
|
||||
t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y),
|
||||
font_engine_(),
|
||||
font_manager_(font_engine_),
|
||||
detector_(detector),
|
||||
ras_ptr(new rasterizer)
|
||||
{
|
||||
setup(m);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void agg_renderer<T>::setup(Map const &m)
|
||||
{
|
||||
boost::optional<color> const& bg = m.background();
|
||||
if (bg) pixmap_.set_background(*bg);
|
||||
|
@ -189,7 +212,7 @@ void agg_renderer<T>::start_layer_processing(layer const& lay)
|
|||
#endif
|
||||
if (lay.clear_label_cache())
|
||||
{
|
||||
detector_.clear();
|
||||
detector_->clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,12 +77,12 @@ void agg_renderer<T>::process(glyph_symbolizer const& sym,
|
|||
// final box so we can check for a valid placement
|
||||
box2d<double> dim = ren.prepare_glyphs(path.get());
|
||||
box2d<double> ext(x-dim.width()/2, y-dim.height()/2, x+dim.width()/2, y+dim.height()/2);
|
||||
if ((sym.get_allow_overlap() || detector_.has_placement(ext)) &&
|
||||
(!sym.get_avoid_edges() || detector_.extent().contains(ext)))
|
||||
if ((sym.get_allow_overlap() || detector_->has_placement(ext)) &&
|
||||
(!sym.get_avoid_edges() || detector_->extent().contains(ext)))
|
||||
{
|
||||
// Placement is valid, render glyph and update detector.
|
||||
ren.render(x, y);
|
||||
detector_.insert(ext);
|
||||
detector_->insert(ext);
|
||||
metawriter_with_properties writer = sym.get_metawriter();
|
||||
if (writer.first) writer.first->add_box(ext, feature, t_, writer.second);
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
|||
}
|
||||
|
||||
path_type path(t_,geom,prj_trans);
|
||||
markers_placement<path_type, label_collision_detector4> placement(path, extent, detector_,
|
||||
markers_placement<path_type, label_collision_detector4> placement(path, extent, *detector_,
|
||||
sym.get_spacing() * scale_factor_,
|
||||
sym.get_max_error(),
|
||||
sym.get_allow_overlap());
|
||||
|
@ -194,7 +194,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
|||
box2d<double> label_ext (px, py, px + dx +1, py + dy +1);
|
||||
|
||||
if (sym.get_allow_overlap() ||
|
||||
detector_.has_placement(label_ext))
|
||||
detector_->has_placement(label_ext))
|
||||
{
|
||||
agg::ellipse c(x, y, w, h);
|
||||
marker.concat_path(c);
|
||||
|
@ -215,7 +215,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
|||
ren.color(agg::rgba8(s_r, s_g, s_b, int(s_a*stroke_.get_opacity())));
|
||||
agg::render_scanlines(*ras_ptr, sl_line, ren);
|
||||
}
|
||||
detector_.insert(label_ext);
|
||||
detector_->insert(label_ext);
|
||||
if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
|||
marker.concat_path(arrow_);
|
||||
|
||||
path_type path(t_,geom,prj_trans);
|
||||
markers_placement<path_type, label_collision_detector4> placement(path, extent, detector_,
|
||||
markers_placement<path_type, label_collision_detector4> placement(path, extent, *detector_,
|
||||
sym.get_spacing() * scale_factor_,
|
||||
sym.get_max_error(),
|
||||
sym.get_allow_overlap());
|
||||
|
|
|
@ -99,13 +99,13 @@ void agg_renderer<T>::process(point_symbolizer const& sym,
|
|||
label_ext.re_center(x,y);
|
||||
|
||||
if (sym.get_allow_overlap() ||
|
||||
detector_.has_placement(label_ext))
|
||||
detector_->has_placement(label_ext))
|
||||
{
|
||||
|
||||
render_marker(floor(x - 0.5 * w),floor(y - 0.5 * h) ,**marker,tr, sym.get_opacity());
|
||||
|
||||
if (!sym.get_ignore_placement())
|
||||
detector_.insert(label_ext);
|
||||
detector_->insert(label_ext);
|
||||
metawriter_with_properties writer = sym.get_metawriter();
|
||||
if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ void agg_renderer<T>::process(shield_symbolizer const& sym,
|
|||
ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);
|
||||
ren.set_opacity(sym.get_text_opacity());
|
||||
|
||||
placement_finder<label_collision_detector4> finder(detector_);
|
||||
placement_finder<label_collision_detector4> finder(*detector_);
|
||||
|
||||
string_info info(text);
|
||||
|
||||
|
@ -210,13 +210,13 @@ void agg_renderer<T>::process(shield_symbolizer const& sym,
|
|||
label_ext.re_center(label_x,label_y);
|
||||
}
|
||||
|
||||
if ( sym.get_allow_overlap() || detector_.has_placement(label_ext) )
|
||||
if ( sym.get_allow_overlap() || detector_->has_placement(label_ext) )
|
||||
{
|
||||
render_marker(px,py,**marker,tr,sym.get_opacity());
|
||||
|
||||
box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[0]);
|
||||
ren.render(x,y);
|
||||
detector_.insert(label_ext);
|
||||
detector_->insert(label_ext);
|
||||
finder.update_detector(text_placement);
|
||||
if (writer.first) {
|
||||
writer.first->add_box(label_ext, feature, t_, writer.second);
|
||||
|
|
|
@ -110,7 +110,7 @@ void agg_renderer<T>::process(text_symbolizer const& sym,
|
|||
ren.set_opacity(sym.get_text_opacity());
|
||||
|
||||
box2d<double> dims(0,0,width_,height_);
|
||||
placement_finder<label_collision_detector4> finder(detector_,dims);
|
||||
placement_finder<label_collision_detector4> finder(*detector_,dims);
|
||||
|
||||
string_info info(text);
|
||||
|
||||
|
|
BIN
tests/data/raster_tiles/000/000/000/000/000/000.tif
Normal file
BIN
tests/data/raster_tiles/000/000/000/000/000/000.tif
Normal file
Binary file not shown.
BIN
tests/data/raster_tiles/000/000/000/000/000/001.tif
Normal file
BIN
tests/data/raster_tiles/000/000/000/000/000/001.tif
Normal file
Binary file not shown.
BIN
tests/data/raster_tiles/000/000/001/000/000/000.tif
Normal file
BIN
tests/data/raster_tiles/000/000/001/000/000/000.tif
Normal file
Binary file not shown.
BIN
tests/data/raster_tiles/000/000/001/000/000/001.tif
Normal file
BIN
tests/data/raster_tiles/000/000/001/000/000/001.tif
Normal file
Binary file not shown.
|
@ -18,10 +18,6 @@ class FeatureTest(unittest.TestCase):
|
|||
f = self.makeOne(1, 'POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))', foo="bar")
|
||||
self.failUnlessEqual(f['foo'], 'bar')
|
||||
self.failUnlessEqual(f.envelope(),Box2d(10.0,10.0,45.0,45.0))
|
||||
area = 0.0
|
||||
for g in f.geometries():
|
||||
area += g.area()
|
||||
self.failUnlessEqual(area,-450.0)
|
||||
|
||||
def test_set_get_properties(self):
|
||||
f = self.makeOne(1)
|
||||
|
|
70
tests/python_tests/multi_tile_raster_test.py
Normal file
70
tests/python_tests/multi_tile_raster_test.py
Normal file
|
@ -0,0 +1,70 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from nose.tools import *
|
||||
from utilities import execution_path, save_data, contains_word
|
||||
|
||||
import os, mapnik2
|
||||
|
||||
def setup():
|
||||
# All of the paths used are relative, if we run the tests
|
||||
# from another directory we need to chdir()
|
||||
os.chdir(execution_path('.'))
|
||||
|
||||
def test_multi_tile_policy():
|
||||
srs = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'
|
||||
lyr = mapnik2.Layer('raster')
|
||||
lyr.datasource = mapnik2.Raster(
|
||||
file = '../data/raster_tiles/${x}/${y}.tif',
|
||||
lox = -180,
|
||||
loy = -90,
|
||||
hix = 180,
|
||||
hiy = 90,
|
||||
multi = 1,
|
||||
tile_size = 256,
|
||||
x_width = 2,
|
||||
y_width = 2
|
||||
)
|
||||
lyr.srs = srs
|
||||
_map = mapnik2.Map(256, 256, srs)
|
||||
style = mapnik2.Style()
|
||||
rule = mapnik2.Rule()
|
||||
sym = mapnik2.RasterSymbolizer()
|
||||
rule.symbols.append(sym)
|
||||
style.rules.append(rule)
|
||||
_map.append_style('foo', style)
|
||||
lyr.styles.append('foo')
|
||||
_map.layers.append(lyr)
|
||||
_map.zoom_to_box(lyr.envelope())
|
||||
|
||||
im = mapnik2.Image(_map.width, _map.height)
|
||||
mapnik2.render(_map, im)
|
||||
|
||||
save_data('test_multi_tile_policy.png', im.tostring('png'))
|
||||
|
||||
# test green chunk
|
||||
assert im.view(0,64,1,1).tostring() == '\x00\xff\x00\xff'
|
||||
assert im.view(127,64,1,1).tostring() == '\x00\xff\x00\xff'
|
||||
assert im.view(0,127,1,1).tostring() == '\x00\xff\x00\xff'
|
||||
assert im.view(127,127,1,1).tostring() == '\x00\xff\x00\xff'
|
||||
|
||||
# test blue chunk
|
||||
assert im.view(128,64,1,1).tostring() == '\x00\x00\xff\xff'
|
||||
assert im.view(255,64,1,1).tostring() == '\x00\x00\xff\xff'
|
||||
assert im.view(128,127,1,1).tostring() == '\x00\x00\xff\xff'
|
||||
assert im.view(255,127,1,1).tostring() == '\x00\x00\xff\xff'
|
||||
|
||||
# test red chunk
|
||||
assert im.view(0,128,1,1).tostring() == '\xff\x00\x00\xff'
|
||||
assert im.view(127,128,1,1).tostring() == '\xff\x00\x00\xff'
|
||||
assert im.view(0,191,1,1).tostring() == '\xff\x00\x00\xff'
|
||||
assert im.view(127,191,1,1).tostring() == '\xff\x00\x00\xff'
|
||||
|
||||
# test magenta chunk
|
||||
assert im.view(128,128,1,1).tostring() == '\xff\x00\xff\xff'
|
||||
assert im.view(255,128,1,1).tostring() == '\xff\x00\xff\xff'
|
||||
assert im.view(128,191,1,1).tostring() == '\xff\x00\xff\xff'
|
||||
assert im.view(255,191,1,1).tostring() == '\xff\x00\xff\xff'
|
||||
|
||||
if __name__ == "__main__":
|
||||
setup()
|
||||
[eval(run)() for run in dir() if 'test_' in run]
|
|
@ -58,6 +58,37 @@ def test_attachdb_with_explicit_index():
|
|||
'insert into scratch.myindex values (1,-7799225.5,-7778571.0,1393264.125,1417719.375)\n'
|
||||
)
|
||||
|
||||
def test_dequoting_of_subqueries():
|
||||
# The point table and index is in the qgis_spatiallite.sqlite
|
||||
# database. If either is not found, then this fails
|
||||
ds = mapnik2.SQLite(file='../data/sqlite/world.sqlite',
|
||||
table='world_merc',
|
||||
)
|
||||
fs = ds.featureset()
|
||||
feature = fs.next()
|
||||
eq_(feature['OGC_FID'],1)
|
||||
eq_(feature['fips'],u'AC')
|
||||
|
||||
# TODO:
|
||||
# select * from world_merc fails
|
||||
# as rowid is dropped
|
||||
ds = mapnik2.SQLite(file='../data/sqlite/world.sqlite',
|
||||
table='(select *,rowid from world_merc)',
|
||||
)
|
||||
fs = ds.featureset()
|
||||
feature = fs.next()
|
||||
print feature
|
||||
eq_(feature['OGC_FID'],1)
|
||||
eq_(feature['fips'],u'AC')
|
||||
|
||||
ds = mapnik2.SQLite(file='../data/sqlite/world.sqlite',
|
||||
table='(select GEOMETRY,OGC_FID as rowid,fips from world_merc)',
|
||||
)
|
||||
fs = ds.featureset()
|
||||
feature = fs.next()
|
||||
print feature
|
||||
eq_(feature['rowid'],1)
|
||||
eq_(feature['fips'],u'AC')
|
||||
|
||||
if __name__ == "__main__":
|
||||
setup()
|
||||
|
|
|
@ -69,8 +69,8 @@ SOURCES += \
|
|||
$$PWD/../plugins/input/osm/osm_featureset.cpp \
|
||||
$$PWD/../plugins/input/osm/osm_datasource.cpp \
|
||||
$$PWD/../plugins/input/osm/render.cpp \
|
||||
$$PWD/../plugins/input/postgis/postgis.cpp \
|
||||
$$PWD/../plugins/input/postgis/postgisfs.cpp \
|
||||
$$PWD/../plugins/input/postgis/postgis_datasource.cpp \
|
||||
$$PWD/../plugins/input/postgis/postgis_featureset.cpp \
|
||||
$$PWD/../plugins/input/raster/raster_info.cpp \
|
||||
$$PWD/../plugins/input/raster/raster_featureset.cpp \
|
||||
$$PWD/../plugins/input/raster/raster_datasource.cpp \
|
||||
|
|
Loading…
Add table
Reference in a new issue