+ occi-input-plugin-3.patch (kunitoki)

This commit is contained in:
Artem Pavlenko 2009-02-05 11:17:27 +00:00
parent c3ff9c842d
commit 425dea32a4
6 changed files with 196 additions and 58 deletions

View file

@ -26,6 +26,7 @@ install_prefix = env['DESTDIR'] + '/' + prefix
occi_src = Split(
"""
occi_types.cpp
occi_datasource.cpp
occi_featureset.cpp
spatial_classesm.cpp
@ -33,7 +34,7 @@ occi_src = Split(
"""
)
libraries = [ 'occi','ociei' ]
libraries = [ 'occi', 'ociei' ]
if env['PLATFORM'] == 'Darwin':
libraries.append('mapnik')
libraries.append('icuuc')

View file

@ -42,6 +42,9 @@ using std::clog;
using std::endl;
using std::vector;
using boost::lexical_cast;
using boost::bad_lexical_cast;
using mapnik::datasource;
using mapnik::parameters;
using mapnik::query;
@ -70,7 +73,8 @@ occi_datasource::occi_datasource(parameters const& params)
geometry_field_(*params.get<std::string>("geometry_field","")),
type_(datasource::Vector),
extent_initialized_(false),
desc_(*params.get<std::string>("type"),"utf-8")
desc_(*params.get<std::string>("type"),"utf-8"),
pool_(0)
{
boost::optional<int> initial_size = params_.get<int>("inital_size",1);
boost::optional<int> max_size = params_.get<int>("max_size",10);
@ -114,10 +118,9 @@ occi_datasource::occi_datasource(parameters const& params)
// connect to environment
try
{
env_ = Environment::createEnvironment ((Environment::Mode) Environment::OBJECT); // Environment::THREADED_MUTEXED
RegisterClasses (env_);
Environment* env = occi_environment::get_environment();
pool_ = env_->createStatelessConnectionPool(
pool_ = env->createStatelessConnectionPool(
*params.get<std::string>("user"),
*params.get<std::string>("password"),
*params.get<std::string>("host"),
@ -225,38 +228,69 @@ occi_datasource::occi_datasource(parameters const& params)
occi_datasource::~occi_datasource()
{
if (env_)
{
env_->terminateStatelessConnectionPool (pool_);
Environment::terminateEnvironment (env_);
}
Environment* env = occi_environment::get_environment();
env->terminateStatelessConnectionPool (pool_);
}
std::string const occi_datasource::name_="occi";
std::string occi_datasource::name()
{
return name_;
return name_;
}
int occi_datasource::type() const
{
return type_;
return type_;
}
Envelope<double> occi_datasource::envelope() const
{
return extent_;
if (extent_initialized_) return extent_;
occi_connection_ptr conn (pool_);
std::ostringstream s;
s << "select min(c.x), min(c.y), max(c.x), max(c.y) from ";
s << " (select sdo_aggr_mbr(" << geometry_field_ << ") shape from " << table_ << ") a, ";
s << " table (sdo_util.getvertices(a.shape)) c";
try
{
ResultSet* rs = conn.execute_query (s.str());
if (rs && rs->next ())
{
try
{
double lox = lexical_cast<double>(rs->getDouble(1));
double loy = lexical_cast<double>(rs->getDouble(2));
double hix = lexical_cast<double>(rs->getDouble(3));
double hiy = lexical_cast<double>(rs->getDouble(4));
extent_.init (lox,loy,hix,hiy);
extent_initialized_ = true;
}
catch (bad_lexical_cast &ex)
{
clog << ex.what() << endl;
}
}
}
catch (SQLException &ex)
{
throw datasource_exception(ex.getMessage());
}
return extent_;
}
layer_descriptor occi_datasource::get_descriptor() const
{
return desc_;
return desc_;
}
featureset_ptr occi_datasource::features(query const& q) const
{
if (env_ && pool_)
if (pool_)
{
Envelope<double> const& box=q.get_bbox();
@ -290,6 +324,40 @@ featureset_ptr occi_datasource::features(query const& q) const
featureset_ptr occi_datasource::features_at_point(coord2d const& pt) const
{
return featureset_ptr();
if (pool_)
{
std::ostringstream s;
s << "select " << geometry_field_ << " as geom";
std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin();
std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end();
unsigned size=0;
while (itr != end)
{
s <<",\""<< itr->get_name() << "\"";
++itr;
++size;
}
s << " from " << table_<<" where "<<geometryColumn_<<" && setSRID('BOX3D(";
s << std::setprecision(16);
s << pt.x << " " << pt.y << ",";
s << pt.x << " " << pt.y << ")'::box3d,"<<srid_<<")";
s << " from " << table_ << " where sdo_filter(" << geometry_field_ << ",";
s << " mdsys.sdo_geometry(" << SDO_GTYPE_2DPOINT << "," << srid_ << ",NULL,";
s << " mdsys.sdo_elem_info_array(1," << SDO_ETYPE_POINT << "," << SDO_INTERPRETATION_POINT << "),";
s << " mdsys.sdo_ordinate_array(";
s << std::setprecision(16);
s << pt.x << "," << pt.y << ")), 'querytype=WINDOW') = 'TRUE'";
#ifdef MAPNIK_DEBUG
clog << s.str() << endl;
#endif
return featureset_ptr(new occi_featureset(pool_,s.str(),desc_.get_encoding(),multiple_geometries_,size));
}
return featureset_ptr();
}

View file

@ -59,7 +59,6 @@ class occi_datasource : public mapnik::datasource
mutable bool extent_initialized_;
mutable mapnik::Envelope<double> extent_;
mapnik::layer_descriptor desc_;
oracle::occi::Environment* env_;
oracle::occi::StatelessConnectionPool* pool_;
bool multiple_geometries_;
static const std::string name_;

View file

@ -35,7 +35,6 @@
using std::clog;
using std::endl;
using std::vector;
using mapnik::query;
using mapnik::Envelope;
@ -90,13 +89,13 @@ feature_ptr occi_featureset::next()
{
feature_ptr feature(new Feature(count_));
boost::shared_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);
}
vector<MetaData> listOfColumns = rs_->getColumnListMetaData();
std::vector<MetaData> listOfColumns = rs_->getColumnListMetaData();
for (unsigned int i=1;i<listOfColumns.size();++i)
{
@ -253,8 +252,8 @@ void occi_featureset::convert_point (SDOGeometry* geom, feature_ptr feature, int
void occi_featureset::convert_linestring (SDOGeometry* geom, feature_ptr feature, int dimensions)
{
const vector<Number>& elem_info = geom->getSdo_elem_info();
const vector<Number>& ordinates = geom->getSdo_ordinates();
const std::vector<Number>& elem_info = geom->getSdo_elem_info();
const std::vector<Number>& ordinates = geom->getSdo_ordinates();
int ord_size = ordinates.size();
if (ord_size >= dimensions)
@ -262,7 +261,7 @@ void occi_featureset::convert_linestring (SDOGeometry* geom, feature_ptr feature
geometry2d * line = new line_string_impl;
line->set_capacity (ord_size);
fill_geometry2d (line, dimensions, elem_info, ordinates, false);
fill_geometry2d (line, elem_info, ordinates, dimensions, false);
feature->add_geometry (line);
}
@ -270,8 +269,8 @@ void occi_featureset::convert_linestring (SDOGeometry* geom, feature_ptr feature
void occi_featureset::convert_polygon (SDOGeometry* geom, feature_ptr feature, int dimensions)
{
const vector<Number>& elem_info = geom->getSdo_elem_info();
const vector<Number>& ordinates = geom->getSdo_ordinates();
const std::vector<Number>& elem_info = geom->getSdo_elem_info();
const std::vector<Number>& ordinates = geom->getSdo_ordinates();
int ord_size = ordinates.size();
if (ord_size >= dimensions)
@ -279,7 +278,7 @@ void occi_featureset::convert_polygon (SDOGeometry* geom, feature_ptr feature, i
geometry2d * poly = new polygon_impl;
poly->set_capacity (ord_size);
fill_geometry2d (poly, dimensions, elem_info, ordinates, false);
fill_geometry2d (poly, elem_info, ordinates, dimensions, false);
feature->add_geometry (poly);
}
@ -287,15 +286,15 @@ void occi_featureset::convert_polygon (SDOGeometry* geom, feature_ptr feature, i
void occi_featureset::convert_multipoint (SDOGeometry* geom, feature_ptr feature, int dimensions)
{
const vector<Number>& elem_info = geom->getSdo_elem_info();
const vector<Number>& ordinates = geom->getSdo_ordinates();
const std::vector<Number>& elem_info = geom->getSdo_elem_info();
const std::vector<Number>& ordinates = geom->getSdo_ordinates();
int ord_size = ordinates.size();
if (ord_size >= dimensions)
{
geometry2d * point = new point_impl;
fill_geometry2d (point, dimensions, elem_info, ordinates, true);
fill_geometry2d (point, elem_info, ordinates, dimensions, true);
feature->add_geometry (point);
}
@ -314,8 +313,8 @@ void occi_featureset::convert_multipoint_2 (SDOGeometry* geom, feature_ptr featu
void occi_featureset::convert_multilinestring (SDOGeometry* geom, feature_ptr feature, int dimensions)
{
const vector<Number>& elem_info = geom->getSdo_elem_info();
const vector<Number>& ordinates = geom->getSdo_ordinates();
const std::vector<Number>& elem_info = geom->getSdo_elem_info();
const std::vector<Number>& ordinates = geom->getSdo_ordinates();
int ord_size = ordinates.size();
if (ord_size >= dimensions)
@ -323,7 +322,7 @@ void occi_featureset::convert_multilinestring (SDOGeometry* geom, feature_ptr fe
geometry2d * line = new line_string_impl;
line->set_capacity (ord_size);
fill_geometry2d (line, dimensions, elem_info, ordinates, false);
fill_geometry2d (line, elem_info, ordinates, dimensions, false);
feature->add_geometry (line);
}
@ -342,8 +341,8 @@ void occi_featureset::convert_multilinestring_2 (SDOGeometry* geom, feature_ptr
void occi_featureset::convert_multipolygon (SDOGeometry* geom, feature_ptr feature, int dimensions)
{
const vector<Number>& elem_info = geom->getSdo_elem_info();
const vector<Number>& ordinates = geom->getSdo_ordinates();
const std::vector<Number>& elem_info = geom->getSdo_elem_info();
const std::vector<Number>& ordinates = geom->getSdo_ordinates();
int ord_size = ordinates.size();
if (ord_size >= dimensions)
@ -351,7 +350,7 @@ void occi_featureset::convert_multipolygon (SDOGeometry* geom, feature_ptr featu
geometry2d * poly = new polygon_impl;
poly->set_capacity (ord_size);
fill_geometry2d (poly, dimensions, elem_info, ordinates, false);
fill_geometry2d (poly, elem_info, ordinates, dimensions, false);
feature->add_geometry (poly);
}
@ -384,9 +383,9 @@ void occi_featureset::convert_collection (SDOGeometry* geom, feature_ptr feature
*/
void occi_featureset::fill_geometry2d (geometry2d * geom,
const std::vector<Number>& elem_info,
const std::vector<Number>& ordinates,
const int dimensions,
const vector<Number>& elem_info,
const vector<Number>& ordinates,
const bool is_point_geom)
{
int elem_size = elem_info.size();
@ -447,14 +446,12 @@ void occi_featureset::fill_geometry2d (geometry2d * geom,
if (is_linear_element)
{
geom->move_to ((double) ordinates[offset - 1], (double) ordinates[offset]);
if (is_point_geom)
for (int p = offset + 1; p < next_offset; p += dimensions)
geom->move_to ((double) ordinates[p], (double) ordinates[p + 1]);
else
for (int p = offset + 1; p < next_offset; p += dimensions)
geom->line_to ((double) ordinates[p], (double) ordinates[p + 1]);
fill_geometry2d (geom,
offset - 1,
next_offset - 1,
ordinates,
dimensions,
is_point_geom);
}
offset = next_offset;
@ -464,16 +461,30 @@ void occi_featureset::fill_geometry2d (geometry2d * geom,
}
else
{
geom->move_to ((double) ordinates[offset - 1], (double) ordinates[offset]);
if (is_point_geom)
for (int p = dimensions; p < ord_size; p += dimensions)
geom->move_to ((double) ordinates[p], (double) ordinates[p + 1]);
else
for (int p = dimensions; p < ord_size; p += dimensions)
geom->line_to ((double) ordinates[p], (double) ordinates[p + 1]);
fill_geometry2d (geom,
offset - 1,
ord_size,
ordinates,
dimensions,
is_point_geom);
}
}
}
void occi_featureset::fill_geometry2d (geometry2d * 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]);
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]);
else
for (int p = real_offset + dimensions; p < next_offset; p += dimensions)
geom->line_to ((double) ordinates[p], (double) ordinates[p + 1]);
}

View file

@ -58,9 +58,15 @@ class occi_featureset : public mapnik::Featureset
//void convert_multipolygon_2 (SDOGeometry* geom, mapnik::feature_ptr feature, int dims);
//void convert_collection (SDOGeometry* geom, mapnik::feature_ptr feature, int dims);
void fill_geometry2d (mapnik::geometry2d * geom,
const int dimensions,
const std::vector<oracle::occi::Number>& elem_info,
const std::vector<oracle::occi::Number>& ordinates,
const int dimensions,
const bool is_point_geom);
void fill_geometry2d (mapnik::geometry2d * 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_;

View file

@ -24,21 +24,27 @@
#ifndef OCCI_TYPES_HPP
#define OCCI_TYPES_HPP
// main OCCI include
// mapnik
#include <mapnik/utils.hpp>
// occi
#include <occi.h>
// OTT generated SDOGeometry classes
// ott generated SDOGeometry classes
#include "spatial_classesh.h"
#include "spatial_classesm.h"
// check for oracle support
#if OCCI_MAJOR_VERSION == 10 && OCCI_MINOR_VERSION >= 1
// Support ORACLE 10g (>= 10.2.0.X)
// Only ORACLE 10g (>= 10.2.0.X) is supported !
#else
#error Only ORACLE 10g (>= 10.2.0.X) is supported !
#error Only ORACLE 10g (>= 10.2.0.X) is supported !
#endif
#define SDO_GEOMETRY_METADATA_TABLE "ALL_SDO_GEOM_METADATA"
enum
{
SDO_GTYPE_UNKNOWN = 0,
@ -76,6 +82,53 @@ enum
};
class occi_environment : public mapnik::singleton<occi_environment,mapnik::CreateStatic>
{
friend class mapnik::CreateStatic<occi_environment>;
public:
static oracle::occi::Environment* get_environment ()
{
if (env_ == 0)
{
#ifdef MAPNIK_DEBUG
std::clog << "occi_environment constructor" << std::endl;
#endif
int mode = oracle::occi::Environment::OBJECT
| oracle::occi::Environment::THREADED_MUTEXED;
env_ = oracle::occi::Environment::createEnvironment ((oracle::occi::Environment::Mode) mode);
RegisterClasses (env_);
}
return env_;
}
private:
occi_environment()
{
}
~occi_environment()
{
if (env_)
{
#ifdef MAPNIK_DEBUG
std::clog << "occi_environment destructor" << std::endl;
#endif
oracle::occi::Environment::terminateEnvironment (env_);
env_ = 0;
}
}
static oracle::occi::Environment* env_;
};
class occi_connection_ptr
{
public: