Merge pull request #2981 from mapnik/unmaintained-plugins

move occi, osm, rasterlite to non-core repo
This commit is contained in:
Dane Springmeyer 2015-07-16 13:07:49 -07:00
commit 461163d883
34 changed files with 0 additions and 4185 deletions

View file

@ -110,14 +110,7 @@ PLUGINS = { # plugins with external dependencies
'pgraster': {'default':True,'path':None,'inc':'libpq-fe.h','lib':'pq','lang':'C'},
'gdal': {'default':True,'path':None,'inc':'gdal_priv.h','lib':'gdal','lang':'C++'},
'ogr': {'default':True,'path':None,'inc':'ogrsf_frmts.h','lib':'gdal','lang':'C++'},
# configured with custom paths, hence 'path': PREFIX/INCLUDES/LIBS
'occi': {'default':False,'path':'OCCI','inc':'occi.h','lib':'clntsh','lang':'C++'},
'sqlite': {'default':True,'path':'SQLITE','inc':'sqlite3.h','lib':'sqlite3','lang':'C'},
'rasterlite': {'default':False,'path':'RASTERLITE','inc':['sqlite3.h','rasterlite.h'],'lib':'rasterlite','lang':'C'},
# todo: osm plugin does also depend on libxml2 (but there is a separate check for that)
'osm': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C'},
# plugins without external dependencies requiring CheckLibWithHeader...
'shape': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
'csv': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},

View file

@ -1,12 +0,0 @@
#
# To regenerate C++ class declarations & implementations for the Spatial
# object types of your database you should execute OTT in your server !
#
echo "TYPE MDSYS.SDO_POINT_TYPE AS SDOPointType" > spatial_types.typ
echo "TYPE MDSYS.SDO_GEOMETRY AS SDOGeometry" >> spatial_types.typ
ott userid=scott/tiger attraccess=private intype=spatial_types.typ code=cpp \
cppfile=spatial_classeso.cpp hfile=spatial_classesh.h mapfile=spatial_classesm.cpp \
mapfunc=RegisterClasses

View file

@ -1,74 +0,0 @@
#
# This file is part of Mapnik (c++ mapping toolkit)
#
# Copyright (C) 2015 Artem Pavlenko
#
# Mapnik 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
#
#
Import ('plugin_base')
Import ('env')
PLUGIN_NAME = 'occi'
plugin_env = plugin_base.Clone()
plugin_sources = Split(
"""
%(PLUGIN_NAME)s_types.cpp
%(PLUGIN_NAME)s_datasource.cpp
%(PLUGIN_NAME)s_featureset.cpp
spatial_classesm.cpp
spatial_classeso.cpp
""" % locals()
)
libraries = [ 'clntsh', 'occi' ]
libraries.append('boost_system%s' % env['BOOST_APPEND'])
libraries.append(env['ICU_LIB_NAME'])
if env['PLUGIN_LINKING'] == 'shared':
libraries.append(env['MAPNIK_NAME'])
# libocci.dylib, at least for 11.2 links to libstdc++
# so we defer symbol resolution to runtime in order to
# dodge linking errors like
# Undefined symbols for architecture x86_64:
# "std::string::_Rep::_M_destroy(std::allocator<char> const&)", referenced from:
# RegisterClasses(oracle::occi::Environment*) in spatial_classesm.os
if env['PLATFORM'] == 'Darwin':
plugin_env.Append(LINKFLAGS='-undefined dynamic_lookup')
TARGET = plugin_env.SharedLibrary('../%s' % PLUGIN_NAME,
SHLIBPREFIX='',
SHLIBSUFFIX='.input',
source=plugin_sources,
LIBS=libraries)
# if the plugin links to libmapnik ensure it is built first
Depends(TARGET, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
if 'uninstall' not in COMMAND_LINE_TARGETS:
env.Install(env['MAPNIK_INPUT_PLUGINS_DEST'], TARGET)
env.Alias('install', env['MAPNIK_INPUT_PLUGINS_DEST'])
plugin_obj = {
'LIBS': libraries,
'SOURCES': plugin_sources,
}
Return('plugin_obj')

View file

@ -1,641 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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 "occi_datasource.hpp"
#include "occi_featureset.hpp"
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/boolean.hpp>
#include <mapnik/sql_utils.hpp>
#include <mapnik/timer.hpp>
#include <mapnik/value_types.hpp>
// boost
#include <boost/algorithm/string.hpp>
#include <boost/tokenizer.hpp>
// stl
#include <string>
#include <algorithm>
#include <set>
#include <sstream>
#include <iomanip>
using mapnik::datasource;
using mapnik::parameters;
using mapnik::query;
using mapnik::featureset_ptr;
using mapnik::layer_descriptor;
using mapnik::attribute_descriptor;
using mapnik::datasource_exception;
using mapnik::box2d;
using mapnik::coord2d;
using oracle::occi::Environment;
using oracle::occi::Connection;
using oracle::occi::Statement;
using oracle::occi::ResultSet;
using oracle::occi::MetaData;
using oracle::occi::SQLException;
using oracle::occi::Type;
using oracle::occi::StatelessConnectionPool;
const double occi_datasource::FMAX = std::numeric_limits<double>::max();
const std::string occi_datasource::METADATA_TABLE = "USER_SDO_GEOM_METADATA";
DATASOURCE_PLUGIN(occi_datasource)
occi_datasource::occi_datasource(parameters const& params)
: 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),
bbox_token_("!bbox!"),
scale_denom_token_("!scale_denominator!"),
pixel_width_token_("!pixel_width!"),
pixel_height_token_("!pixel_height!"),
desc_(occi_datasource::name(), *params.get<std::string>("encoding", "utf-8")),
use_wkb_(*params.get<mapnik::boolean_type>("use_wkb", false)),
row_limit_(*params.get<mapnik::value_integer>("row_limit", 0)),
row_prefetch_(*params.get<mapnik::value_integer>("row_prefetch", 100)),
pool_(0),
conn_(0)
{
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "occi_datasource::init");
#endif
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)
{
throw datasource_exception("OCCI Plugin: no <table> parameter specified");
}
else
{
table_ = *table;
}
estimate_extent_ = *params.get<mapnik::boolean_type>("estimate_extent",false);
use_spatial_index_ = *params.get<mapnik::boolean_type>("use_spatial_index",true);
use_connection_pool_ = *params.get<mapnik::boolean_type>("use_connection_pool",true);
boost::optional<std::string> ext = params.get<std::string>("extent");
if (ext) extent_initialized_ = extent_.from_string(*ext);
boost::optional<mapnik::value_integer> srid = params.get<mapnik::value_integer>("srid");
if (srid)
{
srid_ = *srid;
srid_initialized_ = true;
}
// connect to environment
if (use_connection_pool_)
{
try
{
pool_ = occi_environment::instance().create_pool(
*params.get<std::string>("user"),
*params.get<std::string>("password"),
*params.get<std::string>("host"),
*params.get<mapnik::value_integer>("max_size", 5),
*params.get<mapnik::value_integer>("initial_size", 1),
1);
}
catch (SQLException& ex)
{
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
}
}
else
{
try
{
conn_ = occi_environment::instance().create_connection(
*params.get<std::string>("user"),
*params.get<std::string>("password"),
*params.get<std::string>("host"));
}
catch (SQLException& ex)
{
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
}
}
// extract real table name
table_name_ = mapnik::sql_utils::table_from_sql(table_);
// get SRID and/or GEOMETRY_FIELD from metadata table only if we need to
if (! srid_initialized_ || geometry_field_ == "")
{
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "occi_datasource::get_srid_and_geometry_field");
#endif
std::ostringstream s;
s << "SELECT srid, column_name FROM " << METADATA_TABLE << " WHERE";
s << " LOWER(table_name) = LOWER('" << table_name_ << "')";
if (geometry_field_ != "")
{
s << " AND LOWER(column_name) = LOWER('" << geometry_field_ << "')";
}
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
try
{
occi_connection_ptr conn;
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 ())
{
if (! srid_initialized_)
{
srid_ = rs->getInt(1);
srid_initialized_ = true;
}
if (geometry_field_ == "")
{
geometry_field_ = rs->getString(2);
}
}
}
catch (SQLException& ex)
{
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
}
}
// get columns description
{
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "occi_datasource::get_column_description");
#endif
std::ostringstream s;
s << "SELECT " << fields_ << " FROM (" << table_name_ << ") WHERE ROWNUM < 1";
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
try
{
occi_connection_ptr conn;
if (use_connection_pool_) conn.set_pool(pool_);
else conn.set_connection(conn_, false);
ResultSet* rs = conn.execute_query(s.str());
if (rs)
{
std::vector<MetaData> listOfColumns = rs->getColumnListMetaData();
for (unsigned int i = 0; i < listOfColumns.size(); ++i)
{
MetaData columnObj = listOfColumns[i];
std::string fld_name = columnObj.getString(MetaData::ATTR_NAME);
int type_oid = columnObj.getInt(MetaData::ATTR_DATA_TYPE);
/*
int type_code = columnObj.getInt(MetaData::ATTR_TYPECODE);
if (type_code == OCCI_TYPECODE_OBJECT)
{
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Object));
continue;
}
*/
switch (type_oid)
{
case oracle::occi::OCCIBOOL:
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Boolean));
break;
case oracle::occi::OCCIINT:
case oracle::occi::OCCIUNSIGNED_INT:
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer));
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:
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Double));
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_LNG:
case oracle::occi::OCCI_SQLT_LVC:
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:
case oracle::occi::OCCIROWID:
case oracle::occi::OCCI_SQLT_RDD:
case oracle::occi::OCCI_SQLT_RID:
case oracle::occi::OCCIDATE:
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::OCCITIMESTAMP:
case oracle::occi::OCCI_SQLT_TIMESTAMP:
case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ:
case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ:
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));
break;
case oracle::occi::OCCIINTERVALDS:
case oracle::occi::OCCIINTERVALYM:
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:
MAPNIK_LOG_WARN(occi) << "occi_datasource: Unsupported datatype "
<< occi_enums::resolve_datatype(type_oid)
<< " (type_oid=" << type_oid << ")";
break;
default:
MAPNIK_LOG_WARN(occi) << "occi_datasource: Unknown datatype "
<< "(type_oid=" << type_oid << ")";
break;
}
}
}
}
catch (SQLException& ex)
{
throw datasource_exception(ex.getMessage());
}
}
}
occi_datasource::~occi_datasource()
{
if (use_connection_pool_)
{
if (pool_ != 0)
{
occi_environment::instance().destroy_pool(pool_);
}
}
else
{
if (conn_ != 0)
{
occi_environment::instance().destroy_connection(conn_);
}
}
}
const char * occi_datasource::name()
{
return "occi";
}
mapnik::datasource::datasource_t occi_datasource::type() const
{
return type_;
}
box2d<double> occi_datasource::envelope() const
{
if (extent_initialized_) return extent_;
double lox = 0.0, loy = 0.0, hix = 0.0, hiy = 0.0;
if (estimate_extent_)
{
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "occi_datasource::envelope(estimate_extent)");
#endif
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";
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
try
{
occi_connection_ptr conn;
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())
{
lox = rs->getDouble(1);
loy = rs->getDouble(2);
hix = rs->getDouble(3);
hiy = rs->getDouble(4);
extent_.init(lox, loy, hix, hiy);
extent_initialized_ = true;
}
}
catch (SQLException& ex)
{
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
}
}
else if (use_spatial_index_)
{
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "occi_datasource::envelope(use_spatial_index)");
#endif
std::ostringstream s;
s << "SELECT dim.sdo_lb, dim.sdo_ub FROM ";
s << METADATA_TABLE << " m, TABLE(m.diminfo) dim ";
s << " WHERE LOWER(m.table_name) = LOWER('" << table_name_ << "') AND dim.sdo_dimname = 'X'";
s << " UNION ";
s << "SELECT dim.sdo_lb, dim.sdo_ub FROM ";
s << METADATA_TABLE << " m, TABLE(m.diminfo) dim ";
s << " WHERE LOWER(m.table_name) = LOWER('" << table_name_ << "') AND dim.sdo_dimname = 'Y'";
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
try
{
occi_connection_ptr conn;
if (use_connection_pool_) conn.set_pool(pool_);
else conn.set_connection(conn_, false);
ResultSet* rs = conn.execute_query(s.str());
if (rs)
{
if (rs->next())
{
lox = rs->getDouble(1);
hix = rs->getDouble(2);
}
if (rs->next())
{
loy = rs->getDouble(1);
hiy = rs->getDouble(2);
}
extent_.init(lox, loy, hix, hiy);
extent_initialized_ = true;
}
}
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_;
}
boost::optional<mapnik::datasource_geometry_t> occi_datasource::get_geometry_type() const
{
return boost::optional<mapnik::datasource_geometry_t>();
}
layer_descriptor occi_datasource::get_descriptor() const
{
return desc_;
}
std::string occi_datasource::sql_bbox(box2d<double> const& env) const
{
std::ostringstream b;
b << std::setprecision(16);
b << "MDSYS.SDO_GEOMETRY(" << SDO_GTYPE_2DPOLYGON << "," << srid_ << ",NULL,";
b << " MDSYS.SDO_ELEM_INFO_ARRAY(1," << SDO_ETYPE_POLYGON << "," << SDO_INTERPRETATION_RECTANGLE << "),";
b << " MDSYS.SDO_ORDINATE_ARRAY(";
b << env.minx() << "," << env.miny() << ", ";
b << env.maxx() << "," << env.maxy() << "))";
return b.str();
}
std::string occi_datasource::populate_tokens(std::string const& sql, double scale_denom, box2d<double> const& env, double pixel_width, double pixel_height) const
{
std::string populated_sql = sql;
if (boost::algorithm::icontains(populated_sql, scale_denom_token_))
{
std::ostringstream ss;
ss << scale_denom;
boost::algorithm::replace_all(populated_sql, scale_denom_token_, ss.str());
}
if (boost::algorithm::icontains(sql, pixel_width_token_))
{
std::ostringstream ss;
ss << pixel_width;
boost::algorithm::replace_all(populated_sql, pixel_width_token_, ss.str());
}
if (boost::algorithm::icontains(sql, pixel_height_token_))
{
std::ostringstream ss;
ss << pixel_height;
boost::algorithm::replace_all(populated_sql, pixel_height_token_, ss.str());
}
if (boost::algorithm::icontains(populated_sql, bbox_token_))
{
boost::algorithm::replace_all(populated_sql, bbox_token_, sql_bbox(env));
}
return populated_sql;
}
featureset_ptr occi_datasource::features(query const& q) const
{
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "occi_datasource::features");
#endif
box2d<double> const& box = q.get_bbox();
const double px_gw = 1.0 / std::get<0>(q.resolution());
const double px_gh = 1.0 / std::get<1>(q.resolution());
const double scale_denom = q.scale_denominator();
std::ostringstream s;
s << "SELECT ";
if (use_wkb_)
{
s << "SDO_UTIL.TO_WKBGEOMETRY(" << geometry_field_ << ")";
}
else
{
s << geometry_field_;
}
std::set<std::string> const& props = q.property_names();
std::set<std::string>::const_iterator pos = props.begin();
std::set<std::string>::const_iterator end = props.end();
mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
for (; pos != end; ++pos)
{
s << ", " << *pos;
ctx->push(*pos);
}
std::string query = populate_tokens(table_, scale_denom, box, px_gw, px_gh);
if (use_spatial_index_)
{
std::ostringstream spatial_sql;
spatial_sql << " WHERE SDO_FILTER(";
spatial_sql << geometry_field_ << "," << sql_bbox(box);
spatial_sql << ", 'querytype = WINDOW') = 'TRUE'";
if (boost::algorithm::ifind_first(query, "WHERE"))
{
boost::algorithm::ireplace_first(query, "WHERE", spatial_sql.str() + " AND ");
}
else if (boost::algorithm::ifind_first(query, table_name_))
{
boost::algorithm::ireplace_first(query, table_name_, table_name_ + " " + spatial_sql.str());
}
else
{
MAPNIK_LOG_WARN(occi) << "occi_datasource: cannot determine where to add the spatial filter declaration";
}
}
s << " FROM " << query;
if (row_limit_ > 0)
{
s << " WHERE ROWNUM < " << row_limit_;
}
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
return std::make_shared<occi_featureset>(pool_,
conn_,
ctx,
s.str(),
desc_.get_encoding(),
use_connection_pool_,
use_wkb_,
row_prefetch_);
}
featureset_ptr occi_datasource::features_at_point(coord2d const& pt, double tol) const
{
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "occi_datasource::features_at_point");
#endif
std::ostringstream s;
s << "SELECT ";
if (use_wkb_)
{
s << "SDO_UTIL.TO_WKBGEOMETRY(" << geometry_field_ << ")";
}
else
{
s << geometry_field_;
}
std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin();
std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end();
mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
while (itr != end)
{
s << ", " << itr->get_name();
ctx->push(itr->get_name());
++itr;
}
box2d<double> box(pt.x - tol, pt.y - tol, pt.x + tol, pt.y + tol);
std::string query = populate_tokens(table_, FMAX, box, 0, 0);
if (use_spatial_index_)
{
std::ostringstream spatial_sql;
spatial_sql << " WHERE SDO_FILTER(";
spatial_sql << geometry_field_ << "," << sql_bbox(box);
spatial_sql << ", 'querytype = WINDOW') = 'TRUE'";
if (boost::algorithm::ifind_first(query, "WHERE"))
{
boost::algorithm::ireplace_first(query, "WHERE", spatial_sql.str() + " AND ");
}
else if (boost::algorithm::ifind_first(query, table_name_))
{
boost::algorithm::ireplace_first(query, table_name_, table_name_ + " " + spatial_sql.str());
}
else
{
MAPNIK_LOG_WARN(occi) << "occi_datasource: Cannot determine where to add the spatial filter declaration";
}
}
s << " FROM " << query;
if (row_limit_ > 0)
{
s << " WHERE ROWNUM < " << row_limit_;
}
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
return std::make_shared<occi_featureset>(pool_,
conn_,
ctx,
s.str(),
desc_.get_encoding(),
use_connection_pool_,
use_wkb_,
row_prefetch_);
}

View file

@ -1,95 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef OCCI_DATASOURCE_HPP
#define OCCI_DATASOURCE_HPP
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/value_types.hpp>
// boost
#include <boost/optional.hpp>
#include <memory>
// stl
#include <vector>
#include <string>
// oci
#include "occi_types.hpp"
class occi_datasource : public mapnik::datasource
{
public:
occi_datasource(mapnik::parameters const& params);
virtual ~occi_datasource ();
mapnik::datasource::datasource_t type() const;
static const char * name();
mapnik::featureset_ptr features(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const;
mapnik::box2d<double> envelope() const;
boost::optional<mapnik::datasource_geometry_t> get_geometry_type() const;
mapnik::layer_descriptor get_descriptor() const;
private:
std::string sql_bbox(mapnik::box2d<double> const& env) const;
std::string populate_tokens(std::string const& sql,
double scale_denom,
mapnik::box2d<double> const& env,
double pixel_width,
double pixel_height) const;
static const std::string METADATA_TABLE;
static const double FMAX;
mapnik::datasource::datasource_t type_;
std::string table_;
std::string table_name_;
std::string fields_;
std::string geometry_field_;
int srid_;
bool srid_initialized_;
mutable bool extent_initialized_;
mutable mapnik::box2d<double> extent_;
const std::string bbox_token_;
const std::string scale_denom_token_;
const std::string pixel_width_token_;
const std::string pixel_height_token_;
mapnik::layer_descriptor desc_;
bool use_wkb_;
mapnik::value_integer row_limit_;
int row_prefetch_;
oracle::occi::StatelessConnectionPool* pool_;
oracle::occi::Connection* conn_;
bool use_connection_pool_;
bool use_spatial_index_;
bool estimate_extent_;
};
#endif // OCCI_DATASOURCE_HPP

View file

@ -1,516 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
// mapnik
#include <mapnik/global.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/feature_factory.hpp>
#include <mapnik/make_unique.hpp>
// ogr
#include "occi_featureset.hpp"
using mapnik::query;
using mapnik::box2d;
using mapnik::feature_ptr;
using mapnik::geometry_type;
using mapnik::geometry_utils;
using mapnik::transcoder;
using mapnik::datasource_exception;
using mapnik::feature_factory;
using oracle::occi::Connection;
using oracle::occi::Statement;
using oracle::occi::ResultSet;
using oracle::occi::StatelessConnectionPool;
using oracle::occi::MetaData;
using oracle::occi::SQLException;
using oracle::occi::Type;
using oracle::occi::Number;
using oracle::occi::Blob;
occi_featureset::occi_featureset(StatelessConnectionPool* pool,
Connection* conn,
mapnik::context_ptr const& ctx,
std::string const& sqlstring,
std::string const& encoding,
bool use_connection_pool,
bool use_wkb,
unsigned prefetch_rows)
: rs_(nullptr),
tr_(new transcoder(encoding)),
feature_id_(1),
ctx_(ctx),
use_wkb_(use_wkb)
{
if (use_connection_pool)
{
conn_.set_pool(pool);
}
else
{
conn_.set_connection(conn, false);
}
try
{
rs_ = conn_.execute_query(sqlstring, prefetch_rows);
}
catch (SQLException &ex)
{
MAPNIK_LOG_ERROR(occi) << "OCCI Plugin: error processing " << sqlstring << " : " << ex.getMessage();
rs_ = nullptr;
}
}
occi_featureset::~occi_featureset()
{
}
feature_ptr occi_featureset::next()
{
while (rs_ != nullptr && rs_->next() == oracle::occi::ResultSet::DATA_AVAILABLE)
{
feature_ptr feature(feature_factory::create(ctx_, feature_id_));
if (use_wkb_)
{
Blob blob = rs_->getBlob(1);
blob.open(oracle::occi::OCCI_LOB_READONLY);
unsigned int size = blob.length();
if (buffer_.size() < size)
{
buffer_.resize(size);
}
oracle::occi::Stream* instream = blob.getStream(1, 0);
instream->readBuffer(buffer_.data(), size);
blob.closeStream(instream);
blob.close();
if (! geometry_utils::from_wkb(feature->paths(), buffer_.data(), size))
{
continue;
}
}
else
{
const std::unique_ptr<SDOGeometry> geom(dynamic_cast<SDOGeometry*>(rs_->getObject(1)));
if (geom.get())
{
convert_geometry(geom.get(), feature);
}
else
{
continue;
}
}
std::vector<MetaData> listOfColumns = rs_->getColumnListMetaData();
for (unsigned int i = 1; i < listOfColumns.size(); ++i)
{
MetaData columnObj = listOfColumns[i];
std::string fld_name = columnObj.getString(MetaData::ATTR_NAME);
int type_oid = columnObj.getInt(MetaData::ATTR_DATA_TYPE);
/*
int type_code = columnObj.getInt(MetaData::ATTR_TYPECODE);
if (type_code == OCCI_TYPECODE_OBJECT)
{
continue;
}
*/
switch (type_oid)
{
case oracle::occi::OCCIBOOL:
feature->put(fld_name, (rs_->getInt(i + 1) != 0));
break;
case oracle::occi::OCCIINT:
case oracle::occi::OCCIUNSIGNED_INT:
feature->put(fld_name, static_cast<mapnik::value_integer>(rs_->getInt(i + 1)));
break;
case oracle::occi::OCCIFLOAT:
case oracle::occi::OCCIBFLOAT:
feature->put(fld_name, (double)rs_->getFloat(i + 1));
break;
case oracle::occi::OCCIDOUBLE:
case oracle::occi::OCCIBDOUBLE:
case oracle::occi::OCCINUMBER:
case oracle::occi::OCCI_SQLT_NUM:
feature->put(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_LNG:
case oracle::occi::OCCI_SQLT_LVC:
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:
case oracle::occi::OCCIROWID:
case oracle::occi::OCCI_SQLT_RDD:
case oracle::occi::OCCI_SQLT_RID:
case oracle::occi::OCCIDATE:
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::OCCITIMESTAMP:
case oracle::occi::OCCI_SQLT_TIMESTAMP:
case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ:
case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ:
feature->put(fld_name, static_cast<mapnik::value_unicode_string>(tr_->transcode(rs_->getString(i + 1).c_str())));
break;
case oracle::occi::OCCIINTERVALDS:
case oracle::occi::OCCIINTERVALYM:
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:
{
MAPNIK_LOG_WARN(occi) << "occi_featureset: Unsupported datatype "
<< occi_enums::resolve_datatype(type_oid)
<< " (type_oid=" << type_oid << ")";
break;
}
default: // shouldn't get here
{
MAPNIK_LOG_WARN(occi) << "occi_featureset: Unknown datatype "
<< "(type_oid=" << type_oid << ")";
break;
}
}
}
++feature_id_;
return feature;
}
return feature_ptr();
}
void occi_featureset::convert_geometry(SDOGeometry* geom, feature_ptr feature)
{
int gtype = (int)geom->getSdo_gtype();
int dimensions = gtype / 1000;
int lrsvalue = (gtype - dimensions * 1000) / 100;
int geomtype = (gtype - dimensions * 1000 - lrsvalue * 100);
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();
switch (geomtype)
{
case SDO_GTYPE_POINT:
{
SDOPointType* sdopoint = geom->getSdo_point();
if (sdopoint && ! sdopoint->isNull())
{
std::unique_ptr<geometry_type> point = std::make_unique<geometry_type>(mapnik::geometry::geometry_types::Point);
point->move_to(sdopoint->getX(), sdopoint->getY());
feature->add_geometry(point.release());
}
}
break;
case SDO_GTYPE_LINE:
{
if (ordinates_size >= dimensions)
{
const bool is_single_geom = true;
const bool is_point_type = false;
convert_ordinates(feature,
mapnik::geometry::geometry_types::LineString,
elem_info,
ordinates,
dimensions,
is_single_geom,
is_point_type);
}
}
break;
case SDO_GTYPE_POLYGON:
{
if (ordinates_size >= dimensions)
{
const bool is_single_geom = true;
const bool is_point_type = false;
convert_ordinates(feature,
mapnik::geometry::geometry_types::Polygon,
elem_info,
ordinates,
dimensions,
is_single_geom,
is_point_type);
}
}
break;
case SDO_GTYPE_MULTIPOINT:
{
if (ordinates_size >= dimensions)
{
const bool is_single_geom = false;
const bool is_point_type = true;
convert_ordinates(feature,
mapnik::geometry::geometry_types::Point,
elem_info,
ordinates,
dimensions,
is_single_geom,
is_point_type);
}
}
break;
case SDO_GTYPE_MULTILINE:
{
if (ordinates_size >= dimensions)
{
const bool is_single_geom = false;
const bool is_point_type = false;
convert_ordinates(feature,
mapnik::geometry::geometry_types::LineString,
elem_info,
ordinates,
dimensions,
is_single_geom,
is_point_type);
}
}
break;
case SDO_GTYPE_MULTIPOLYGON:
{
if (ordinates_size >= dimensions)
{
const bool is_single_geom = false;
const bool is_point_type = false;
convert_ordinates(feature,
mapnik::geometry::geometry_types::Polygon,
elem_info,
ordinates,
dimensions,
is_single_geom,
is_point_type);
}
}
break;
case SDO_GTYPE_COLLECTION:
{
if (ordinates_size >= dimensions)
{
const bool is_single_geom = false;
const bool is_point_type = false;
convert_ordinates(feature,
mapnik::geometry::geometry_types::Polygon,
elem_info,
ordinates,
dimensions,
is_single_geom,
is_point_type);
}
}
break;
case SDO_GTYPE_UNKNOWN:
default:
{
MAPNIK_LOG_WARN(occi) << "occi_featureset: Unknown oracle enum "
<< occi_enums::resolve_gtype(geomtype)
<< "(gtype=" << gtype << ")";
}
break;
}
}
void occi_featureset::convert_ordinates(mapnik::feature_ptr feature,
const mapnik::geometry_type::types& 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 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];
if (! is_single_geom && elem_size > SDO_ELEM_INFO_SIZE)
{
geometry_type* geom = new geometry_type(geom_type);
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];
bool is_linear_element = true;
bool is_unknown_etype = false;
mapnik::geometry_type::types gtype = mapnik::geometry::geometry_types::Point;
switch (etype)
{
case SDO_ETYPE_POINT:
if (interp == SDO_INTERPRETATION_POINT) {}
if (interp > SDO_INTERPRETATION_POINT) {}
gtype = mapnik::geometry::geometry_types::Point;
break;
case SDO_ETYPE_LINESTRING:
if (interp == SDO_INTERPRETATION_STRAIGHT) {}
if (interp == SDO_INTERPRETATION_CIRCULAR) {}
gtype = mapnik::geometry::geometry_types::LineString;
break;
case SDO_ETYPE_POLYGON:
case SDO_ETYPE_POLYGON_INTERIOR:
if (interp == SDO_INTERPRETATION_STRAIGHT) {}
if (interp == SDO_INTERPRETATION_CIRCULAR) {}
if (interp == SDO_INTERPRETATION_RECTANGLE) {}
if (interp == SDO_INTERPRETATION_CIRCLE) {}
gtype = mapnik::geometry::geometry_types::Polygon;
break;
case SDO_ETYPE_COMPOUND_LINESTRING:
case SDO_ETYPE_COMPOUND_POLYGON:
case SDO_ETYPE_COMPOUND_POLYGON_INTERIOR:
// interp = next ETYPE to consider
is_linear_element = false;
gtype = mapnik::geometry::geometry_types::Polygon;
break;
case SDO_ETYPE_UNKNOWN: // unknown
default:
is_unknown_etype = true;
break;
}
if (is_unknown_etype)
{
break;
}
if (is_linear_element)
{
if (geom)
{
feature->add_geometry(geom);
}
geom = new geometry_type(gtype);
fill_geometry_type(geom,
offset - 1,
next_offset - 1,
ordinates,
dimensions,
is_point_geom);
}
offset = next_offset;
etype = next_etype;
interp = next_interp;
}
if (geom)
{
feature->add_geometry(geom);
geom = 0;
}
}
else
{
geometry_type * geom = new geometry_type(geom_type);
fill_geometry_type(geom,
offset - 1,
ord_size,
ordinates,
dimensions,
is_point_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)
{
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

@ -1,77 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef OCCI_FEATURESET_HPP
#define OCCI_FEATURESET_HPP
// mapnik
#include <mapnik/feature.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/unicode.hpp>
// stl
#include <memory>
// oci
#include "occi_types.hpp"
#include <vector>
class occi_featureset : public mapnik::Featureset
{
public:
occi_featureset(oracle::occi::StatelessConnectionPool* pool,
oracle::occi::Connection* conn,
mapnik::context_ptr const& ctx,
std::string const& sqlstring,
std::string const& encoding,
bool use_connection_pool,
bool use_wkb,
unsigned prefetch_rows);
virtual ~occi_featureset();
mapnik::feature_ptr next();
private:
void convert_geometry (SDOGeometry* geom, mapnik::feature_ptr feature);
void convert_ordinates (mapnik::feature_ptr feature,
const mapnik::geometry_type::types& 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);
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_;
const std::unique_ptr<mapnik::transcoder> tr_;
mapnik::value_integer feature_id_;
mapnik::context_ptr ctx_;
bool use_wkb_;
std::vector<char> buffer_;
};
#endif // OCCI_FEATURESET_HPP

View file

@ -1,91 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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 "occi_types.hpp"
std::string occi_enums::resolve_gtype(int 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>";
}
}
std::string occi_enums::resolve_etype(int 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>";
}
}
std::string occi_enums::resolve_datatype(int 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_LNG: return "OCCI_SQLT_LNG";
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>";
}
}

View file

@ -1,265 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 Artem Pavlenko
*
* This library is free software, you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY, without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library, if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef OCCI_TYPES_HPP
#define OCCI_TYPES_HPP
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/util/singleton.hpp>
// occi
#include <occi.h>
// 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
// We have at least ORACLE 10g >= 10.2.0.X
#else
#error Only ORACLE 10g >= 10.2.0.X is supported !
#endif
// geometry types definitions
enum
{
SDO_GTYPE_UNKNOWN = 0,
SDO_GTYPE_POINT = 1,
SDO_GTYPE_LINE = 2,
SDO_GTYPE_POLYGON = 3,
SDO_GTYPE_COLLECTION = 4,
SDO_GTYPE_MULTIPOINT = 5,
SDO_GTYPE_MULTILINE = 6,
SDO_GTYPE_MULTIPOLYGON = 7,
SDO_GTYPE_2DPOINT = 2001,
SDO_GTYPE_2DLINE = 2002,
SDO_GTYPE_2DPOLYGON = 2003,
SDO_GTYPE_2DMULTIPOINT = 2005,
SDO_GTYPE_2DMULTILINE = 2006,
SDO_GTYPE_2DMULTIPOLYGON = 2007,
SDO_ELEM_INFO_SIZE = 3,
SDO_ETYPE_UNKNOWN = 0,
SDO_ETYPE_POINT = 1,
SDO_ETYPE_LINESTRING = 2,
SDO_ETYPE_POLYGON = 1003,
SDO_ETYPE_POLYGON_INTERIOR = 2003,
SDO_ETYPE_COMPOUND_LINESTRING = 4,
SDO_ETYPE_COMPOUND_POLYGON = 1005,
SDO_ETYPE_COMPOUND_POLYGON_INTERIOR = 2005,
SDO_INTERPRETATION_POINT = 1,
SDO_INTERPRETATION_RECTANGLE = 3,
SDO_INTERPRETATION_CIRCLE = 4,
SDO_INTERPRETATION_STRAIGHT = 1,
SDO_INTERPRETATION_CIRCULAR = 2
};
class occi_environment : public mapnik::singleton<occi_environment, mapnik::CreateStatic>
{
friend class mapnik::CreateStatic<occi_environment>;
public:
oracle::occi::Environment* get_environment()
{
return env_;
}
oracle::occi::Connection* create_connection(
const std::string& user,
const std::string& password,
const std::string& host)
{
MAPNIK_LOG_DEBUG(occi) << "occi_environment: create_connection";
return env_->createConnection(user, password, host);
}
void destroy_connection(oracle::occi::Connection* conn)
{
env_->terminateConnection(conn);
}
oracle::occi::StatelessConnectionPool* create_pool(
const std::string& user,
const std::string& password,
const std::string& host,
int max_size,
int initial_size,
int incr_size)
{
MAPNIK_LOG_DEBUG(occi) << "occi_environment: create_pool";
return env_->createStatelessConnectionPool(
user,
password,
host,
max_size,
initial_size,
incr_size,
oracle::occi::StatelessConnectionPool::HOMOGENEOUS);
}
void destroy_pool(oracle::occi::StatelessConnectionPool* pool)
{
env_->terminateStatelessConnectionPool(
pool,
oracle::occi::StatelessConnectionPool::SPD_FORCE);
}
private:
occi_environment()
: env_(0)
{
MAPNIK_LOG_DEBUG(occi) << "occi_environment: constructor";
env_ = oracle::occi::Environment::createEnvironment(
(oracle::occi::Environment::Mode)(oracle::occi::Environment::OBJECT
| oracle::occi::Environment::THREADED_MUTEXED));
RegisterClasses(env_);
}
~occi_environment()
{
MAPNIK_LOG_DEBUG(occi) << "occi_environment: destructor";
oracle::occi::Environment::terminateEnvironment(env_);
env_ = 0;
}
oracle::occi::Environment* env_;
};
class occi_connection_ptr
{
public:
explicit occi_connection_ptr()
: pool_(0),
conn_(0),
stmt_(0),
rs_(0),
owns_connection_(false)
{
}
~occi_connection_ptr()
{
close_query(true);
}
void set_pool(oracle::occi::StatelessConnectionPool* pool)
{
close_query(true);
pool_ = pool;
conn_ = pool_->getConnection();
owns_connection_ = true;
}
void set_connection(oracle::occi::Connection* conn, bool owns_connection)
{
close_query(true);
pool_ = 0;
conn_ = conn;
owns_connection_ = owns_connection;
}
oracle::occi::ResultSet* execute_query(std::string const& s, const unsigned prefetch = 0)
{
close_query(false);
MAPNIK_LOG_DEBUG(occi) << "occi_connection_ptr: " << s;
stmt_ = conn_->createStatement(s);
if (prefetch > 0)
{
stmt_->setPrefetchMemorySize(0);
stmt_->setPrefetchRowCount(prefetch);
}
rs_ = stmt_->executeQuery();
return rs_;
}
private:
void close_query(const bool release_connection)
{
if (conn_)
{
if (stmt_)
{
if (rs_)
{
stmt_->closeResultSet(rs_);
rs_ = 0;
}
conn_->terminateStatement(stmt_);
stmt_ = 0;
}
if (release_connection)
{
if (pool_)
{
pool_->releaseConnection(conn_);
}
else
{
if (owns_connection_)
{
occi_environment::instance().destroy_connection(conn_);
}
}
conn_ = 0;
}
}
}
oracle::occi::StatelessConnectionPool* pool_;
oracle::occi::Connection* conn_;
oracle::occi::Statement* stmt_;
oracle::occi::ResultSet* rs_;
bool owns_connection_;
};
class occi_enums
{
public:
static std::string resolve_gtype(int gtype);
static std::string resolve_etype(int etype);
static std::string resolve_datatype(int type_id);
};
#endif // OCCI_TYPES_HPP

View file

@ -1,147 +0,0 @@
#ifndef SPATIAL_CLASSESH_ORACLE
# define SPATIAL_CLASSESH_ORACLE
#ifndef OCCI_ORACLE
# include <occi.h>
#endif
class SDOPointType;
class SDOGeometry;
/************************************************************/
// generated declarations for the SDO_POINT_TYPE object type.
/************************************************************/
class SDOPointType : public oracle::occi::PObject {
private:
oracle::occi::Number X;
oracle::occi::Number Y;
oracle::occi::Number Z;
public:
oracle::occi::Number getX() const;
void setX(const oracle::occi::Number &value);
oracle::occi::Number getY() const;
void setY(const oracle::occi::Number &value);
oracle::occi::Number getZ() const;
void setZ(const oracle::occi::Number &value);
void *operator new(size_t size);
void *operator new(size_t size, const oracle::occi::Connection * sess,
const OCCI_STD_NAMESPACE::string& table);
void *operator new(size_t, void *ctxOCCI_);
void *operator new(size_t size, const oracle::occi::Connection *sess,
const OCCI_STD_NAMESPACE::string &tableName,
const OCCI_STD_NAMESPACE::string &typeName,
const OCCI_STD_NAMESPACE::string &tableSchema,
const OCCI_STD_NAMESPACE::string &typeSchema);
OCCI_STD_NAMESPACE::string getSQLTypeName() const;
void getSQLTypeName(oracle::occi::Environment *env, void **schemaName,
unsigned int &schemaNameLen, void **typeName,
unsigned int &typeNameLen) const;
SDOPointType();
SDOPointType(void *ctxOCCI_) : oracle::occi::PObject (ctxOCCI_) { }
static void *readSQL(void *ctxOCCI_);
virtual void readSQL(oracle::occi::AnyData& streamOCCI_);
static void writeSQL(void *objOCCI_, void *ctxOCCI_);
virtual void writeSQL(oracle::occi::AnyData& streamOCCI_);
~SDOPointType();
};
/************************************************************/
// generated declarations for the SDO_GEOMETRY object type.
/************************************************************/
class SDOGeometry : public oracle::occi::PObject {
private:
oracle::occi::Number SDO_GTYPE;
oracle::occi::Number SDO_SRID;
SDOPointType * SDO_POINT;
OCCI_STD_NAMESPACE::vector< oracle::occi::Number > SDO_ELEM_INFO;
OCCI_STD_NAMESPACE::vector< oracle::occi::Number > SDO_ORDINATES;
public:
oracle::occi::Number getSdo_gtype() const;
void setSdo_gtype(const oracle::occi::Number &value);
oracle::occi::Number getSdo_srid() const;
void setSdo_srid(const oracle::occi::Number &value);
SDOPointType * getSdo_point() const;
void setSdo_point(SDOPointType * value);
OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& getSdo_elem_info();
const OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& getSdo_elem_info() const;
void setSdo_elem_info(const OCCI_STD_NAMESPACE::vector< oracle::occi::Number > &value);
OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& getSdo_ordinates();
const OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& getSdo_ordinates() const;
void setSdo_ordinates(const OCCI_STD_NAMESPACE::vector< oracle::occi::Number > &value);
void *operator new(size_t size);
void *operator new(size_t size, const oracle::occi::Connection * sess,
const OCCI_STD_NAMESPACE::string& table);
void *operator new(size_t, void *ctxOCCI_);
void *operator new(size_t size, const oracle::occi::Connection *sess,
const OCCI_STD_NAMESPACE::string &tableName,
const OCCI_STD_NAMESPACE::string &typeName,
const OCCI_STD_NAMESPACE::string &tableSchema,
const OCCI_STD_NAMESPACE::string &typeSchema);
OCCI_STD_NAMESPACE::string getSQLTypeName() const;
void getSQLTypeName(oracle::occi::Environment *env, void **schemaName,
unsigned int &schemaNameLen, void **typeName,
unsigned int &typeNameLen) const;
SDOGeometry();
SDOGeometry(void *ctxOCCI_) : oracle::occi::PObject (ctxOCCI_) { }
static void *readSQL(void *ctxOCCI_);
virtual void readSQL(oracle::occi::AnyData& streamOCCI_);
static void writeSQL(void *objOCCI_, void *ctxOCCI_);
virtual void writeSQL(oracle::occi::AnyData& streamOCCI_);
~SDOGeometry();
};
#endif

View file

@ -1,11 +0,0 @@
#ifndef SPATIAL_CLASSESM_ORACLE
# include "spatial_classesm.h"
#endif
void RegisterClasses(oracle::occi::Environment* envOCCI_)
{
oracle::occi::Map *mapOCCI_ = envOCCI_->getMap();
mapOCCI_->put("MDSYS.SDO_POINT_TYPE", &SDOPointType::readSQL, &SDOPointType::writeSQL);
mapOCCI_->put("MDSYS.SDO_GEOMETRY", &SDOGeometry::readSQL, &SDOGeometry::writeSQL);
}

View file

@ -1,14 +0,0 @@
#ifndef SPATIAL_CLASSESM_ORACLE
# define SPATIAL_CLASSESM_ORACLE
#ifndef OCCI_ORACLE
# include <occi.h>
#endif
#ifndef SPATIAL_CLASSESH_ORACLE
# include "spatial_classesh.h"
#endif
void RegisterClasses(oracle::occi::Environment* envOCCI_);
#endif

View file

@ -1,312 +0,0 @@
#ifndef SPATIAL_CLASSESH_ORACLE
# include "spatial_classesh.h"
#endif
/*****************************************************************/
// generated method implementations for the SDO_POINT_TYPE object type.
/*****************************************************************/
oracle::occi::Number SDOPointType::getX() const
{
return X;
}
void SDOPointType::setX(const oracle::occi::Number &value)
{
X = value;
}
oracle::occi::Number SDOPointType::getY() const
{
return Y;
}
void SDOPointType::setY(const oracle::occi::Number &value)
{
Y = value;
}
oracle::occi::Number SDOPointType::getZ() const
{
return Z;
}
void SDOPointType::setZ(const oracle::occi::Number &value)
{
Z = value;
}
void *SDOPointType::operator new(size_t size)
{
return oracle::occi::PObject::operator new(size);
}
void *SDOPointType::operator new(size_t size, const oracle::occi::Connection * sess,
const OCCI_STD_NAMESPACE::string& table)
{
return oracle::occi::PObject::operator new(size, sess, table,
(char *) "MDSYS.SDO_POINT_TYPE");
}
void *SDOPointType::operator new(size_t size, void *ctxOCCI_)
{
return oracle::occi::PObject::operator new(size, ctxOCCI_);
}
void *SDOPointType::operator new(size_t size,
const oracle::occi::Connection *sess,
const OCCI_STD_NAMESPACE::string &tableName,
const OCCI_STD_NAMESPACE::string &typeName,
const OCCI_STD_NAMESPACE::string &tableSchema,
const OCCI_STD_NAMESPACE::string &typeSchema)
{
return oracle::occi::PObject::operator new(size, sess, tableName,
typeName, tableSchema, typeSchema);
}
OCCI_STD_NAMESPACE::string SDOPointType::getSQLTypeName() const
{
return OCCI_STD_NAMESPACE::string("MDSYS.SDO_POINT_TYPE");
}
void SDOPointType::getSQLTypeName(oracle::occi::Environment *env, void **schemaName,
unsigned int &schemaNameLen, void **typeName, unsigned int &typeNameLen) const
{
PObject::getSQLTypeName(env, &SDOPointType::readSQL, schemaName,
schemaNameLen, typeName, typeNameLen);
}
SDOPointType::SDOPointType()
{
}
void *SDOPointType::readSQL(void *ctxOCCI_)
{
SDOPointType *objOCCI_ = new(ctxOCCI_) SDOPointType(ctxOCCI_);
oracle::occi::AnyData streamOCCI_(ctxOCCI_);
try
{
if (streamOCCI_.isNull())
objOCCI_->setNull();
else
objOCCI_->readSQL(streamOCCI_);
}
catch (oracle::occi::SQLException& excep)
{
delete objOCCI_;
excep.setErrorCtx(ctxOCCI_);
return (void *)nullptr;
}
return (void *)objOCCI_;
}
void SDOPointType::readSQL(oracle::occi::AnyData& streamOCCI_)
{
X = streamOCCI_.getNumber();
Y = streamOCCI_.getNumber();
Z = streamOCCI_.getNumber();
}
void SDOPointType::writeSQL(void *objectOCCI_, void *ctxOCCI_)
{
SDOPointType *objOCCI_ = (SDOPointType *) objectOCCI_;
oracle::occi::AnyData streamOCCI_(ctxOCCI_);
try
{
if (objOCCI_->isNull())
streamOCCI_.setNull();
else
objOCCI_->writeSQL(streamOCCI_);
}
catch (oracle::occi::SQLException& excep)
{
excep.setErrorCtx(ctxOCCI_);
}
return;
}
void SDOPointType::writeSQL(oracle::occi::AnyData& streamOCCI_)
{
streamOCCI_.setNumber(X);
streamOCCI_.setNumber(Y);
streamOCCI_.setNumber(Z);
}
SDOPointType::~SDOPointType()
{
}
/*****************************************************************/
// generated method implementations for the SDO_GEOMETRY object type.
/*****************************************************************/
oracle::occi::Number SDOGeometry::getSdo_gtype() const
{
return SDO_GTYPE;
}
void SDOGeometry::setSdo_gtype(const oracle::occi::Number &value)
{
SDO_GTYPE = value;
}
oracle::occi::Number SDOGeometry::getSdo_srid() const
{
return SDO_SRID;
}
void SDOGeometry::setSdo_srid(const oracle::occi::Number &value)
{
SDO_SRID = value;
}
SDOPointType * SDOGeometry::getSdo_point() const
{
return SDO_POINT;
}
void SDOGeometry::setSdo_point(SDOPointType * value)
{
SDO_POINT = value;
}
OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& SDOGeometry::getSdo_elem_info()
{
return SDO_ELEM_INFO;
}
const OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& SDOGeometry::getSdo_elem_info() const
{
return SDO_ELEM_INFO;
}
void SDOGeometry::setSdo_elem_info(const OCCI_STD_NAMESPACE::vector< oracle::occi::Number > &value)
{
SDO_ELEM_INFO = value;
}
OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& SDOGeometry::getSdo_ordinates()
{
return SDO_ORDINATES;
}
const OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& SDOGeometry::getSdo_ordinates() const
{
return SDO_ORDINATES;
}
void SDOGeometry::setSdo_ordinates(const OCCI_STD_NAMESPACE::vector< oracle::occi::Number > &value)
{
SDO_ORDINATES = value;
}
void *SDOGeometry::operator new(size_t size)
{
return oracle::occi::PObject::operator new(size);
}
void *SDOGeometry::operator new(size_t size, const oracle::occi::Connection * sess,
const OCCI_STD_NAMESPACE::string& table)
{
return oracle::occi::PObject::operator new(size, sess, table,
(char *) "MDSYS.SDO_GEOMETRY");
}
void *SDOGeometry::operator new(size_t size, void *ctxOCCI_)
{
return oracle::occi::PObject::operator new(size, ctxOCCI_);
}
void *SDOGeometry::operator new(size_t size,
const oracle::occi::Connection *sess,
const OCCI_STD_NAMESPACE::string &tableName,
const OCCI_STD_NAMESPACE::string &typeName,
const OCCI_STD_NAMESPACE::string &tableSchema,
const OCCI_STD_NAMESPACE::string &typeSchema)
{
return oracle::occi::PObject::operator new(size, sess, tableName,
typeName, tableSchema, typeSchema);
}
OCCI_STD_NAMESPACE::string SDOGeometry::getSQLTypeName() const
{
return OCCI_STD_NAMESPACE::string("MDSYS.SDO_GEOMETRY");
}
void SDOGeometry::getSQLTypeName(oracle::occi::Environment *env, void **schemaName,
unsigned int &schemaNameLen, void **typeName, unsigned int &typeNameLen) const
{
PObject::getSQLTypeName(env, &SDOGeometry::readSQL, schemaName,
schemaNameLen, typeName, typeNameLen);
}
SDOGeometry::SDOGeometry()
{
SDO_POINT = (SDOPointType *) 0;
}
void *SDOGeometry::readSQL(void *ctxOCCI_)
{
SDOGeometry *objOCCI_ = new(ctxOCCI_) SDOGeometry(ctxOCCI_);
oracle::occi::AnyData streamOCCI_(ctxOCCI_);
try
{
if (streamOCCI_.isNull())
objOCCI_->setNull();
else
objOCCI_->readSQL(streamOCCI_);
}
catch (oracle::occi::SQLException& excep)
{
delete objOCCI_;
excep.setErrorCtx(ctxOCCI_);
return (void *)nullptr;
}
return (void *)objOCCI_;
}
void SDOGeometry::readSQL(oracle::occi::AnyData& streamOCCI_)
{
SDO_GTYPE = streamOCCI_.getNumber();
SDO_SRID = streamOCCI_.getNumber();
SDO_POINT = (SDOPointType *) streamOCCI_.getObject(&SDOPointType::readSQL);
oracle::occi::getVector(streamOCCI_, SDO_ELEM_INFO);
oracle::occi::getVector(streamOCCI_, SDO_ORDINATES);
}
void SDOGeometry::writeSQL(void *objectOCCI_, void *ctxOCCI_)
{
SDOGeometry *objOCCI_ = (SDOGeometry *) objectOCCI_;
oracle::occi::AnyData streamOCCI_(ctxOCCI_);
try
{
if (objOCCI_->isNull())
streamOCCI_.setNull();
else
objOCCI_->writeSQL(streamOCCI_);
}
catch (oracle::occi::SQLException& excep)
{
excep.setErrorCtx(ctxOCCI_);
}
return;
}
void SDOGeometry::writeSQL(oracle::occi::AnyData& streamOCCI_)
{
streamOCCI_.setNumber(SDO_GTYPE);
streamOCCI_.setNumber(SDO_SRID);
streamOCCI_.setObject(SDO_POINT);
oracle::occi::setVector(streamOCCI_, SDO_ELEM_INFO);
oracle::occi::setVector(streamOCCI_, SDO_ORDINATES);
}
SDOGeometry::~SDOGeometry()
{
delete SDO_POINT;
}

View file

@ -1,4 +0,0 @@
TYPE MDSYS.SDO_POINT_TYPE AS SDOPointType
TYPE MDSYS.SDO_GEOMETRY AS SDOGeometry

View file

@ -1,75 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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 "basiccurl.h"
#include <iostream>
#include <cstring>
CURL_LOAD_DATA* grab_http_response(const char* url)
{
CURL_LOAD_DATA* data;
CURL* curl = curl_easy_init();
if(curl)
{
data = do_grab(curl, url);
curl_easy_cleanup(curl);
return data;
}
return nullptr;
}
CURL_LOAD_DATA* do_grab(CURL* curl,const char* url)
{
CURL_LOAD_DATA* data = (CURL_LOAD_DATA*)malloc(sizeof(CURL_LOAD_DATA));
data->data = nullptr;
data->nbytes = 0;
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, response_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, data);
CURLcode res = curl_easy_perform(curl);
if (res !=0) {
std::clog << "error grabbing data\n";
}
return data;
}
size_t response_callback(void* ptr, size_t size, size_t nmemb, void* d)
{
size_t rsize = size * nmemb;
CURL_LOAD_DATA* data = (CURL_LOAD_DATA*)d;
// fprintf(stderr,"rsize is %d\n", rsize);
data->data = (char*)realloc(data->data, (data->nbytes + rsize) * sizeof(char));
std::memcpy(&(data->data[data->nbytes]), ptr, rsize);
data->nbytes += rsize;
// fprintf(stderr,"data->nbytes is %d\n", data->nbytes);
return rsize;
}

View file

@ -1,40 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef BASICCURL_H
#define BASICCURL_H
#include <curl/curl.h>
#include <cstdlib>
#include <cstring>
typedef struct
{
char *data;
int nbytes;
} CURL_LOAD_DATA;
CURL_LOAD_DATA *grab_http_response(const char *url);
CURL_LOAD_DATA *do_grab(CURL *curl, const char *url);
size_t response_callback(void *ptr ,size_t size, size_t nmemb, void *data);
#endif // BASICCURL_H

View file

@ -1,69 +0,0 @@
#
# This file is part of Mapnik (c++ mapping toolkit)
#
# Copyright (C) 2015 Artem Pavlenko
#
# Mapnik 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
#
#
Import ('plugin_base')
Import ('env')
from copy import copy
PLUGIN_NAME = 'osm'
plugin_env = plugin_base.Clone()
plugin_sources = Split(
"""
%(PLUGIN_NAME)s.cpp
%(PLUGIN_NAME)s_datasource.cpp
%(PLUGIN_NAME)s_featureset.cpp
osmparser.cpp
dataset_deliverer.cpp
""" % locals()
)
plugin_env['LIBS'] = []
plugin_env.Append(LIBS='xml2')
# Link Library to Dependencies
libraries = copy(plugin_env['LIBS'])
libraries.append(env['ICU_LIB_NAME'])
libraries.append('boost_system%s' % env['BOOST_APPEND'])
if env['PLUGIN_LINKING'] == 'shared':
libraries.append(env['MAPNIK_NAME'])
TARGET = plugin_env.SharedLibrary('../%s' % PLUGIN_NAME,
SHLIBPREFIX='',
SHLIBSUFFIX='.input',
source=plugin_sources,
LIBS=libraries)
# if the plugin links to libmapnik ensure it is built first
Depends(TARGET, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
if 'uninstall' not in COMMAND_LINE_TARGETS:
env.Install(env['MAPNIK_INPUT_PLUGINS_DEST'], TARGET)
env.Alias('install', env['MAPNIK_INPUT_PLUGINS_DEST'])
plugin_obj = {
'LIBS': libraries,
'SOURCES': plugin_sources,
}
Return('plugin_obj')

View file

@ -1,66 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/util/fs.hpp>
// std
#include <sstream>
#include "dataset_deliverer.h"
osm_dataset * dataset_deliverer::dataset = nullptr;
std::string dataset_deliverer::last_bbox = "";
std::string dataset_deliverer::last_filename = "";
osm_dataset* dataset_deliverer::load_from_file(const string& file, const string& parser)
{
// Only actually load from file if we haven't done so already
if (dataset == nullptr)
{
if (!mapnik::util::exists(file))
{
throw mapnik::datasource_exception("OSM Plugin: '" + file + "' does not exist");
}
dataset = new osm_dataset;
if (dataset->load(file.c_str(), parser) == false)
{
return nullptr;
}
atexit(dataset_deliverer::release);
last_filename = file;
}
else if(file != last_filename)
{
dataset = new osm_dataset;
if (dataset->load(file.c_str(), parser) == false)
{
return nullptr;
}
last_filename = file;
}
return dataset;
}

View file

@ -1,47 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef DATASET_DELIVERER_H
#define DATASET_DELIVERER_H
#include "osm.h"
#include <string>
using namespace std;
class dataset_deliverer
{
private:
static osm_dataset* dataset;
static std::string last_bbox;
static std::string last_filename;
public:
static osm_dataset *load_from_file(const string&, const string&);
static void release()
{
delete dataset;
}
};
#endif // DATASET_DELIVERER_H

View file

@ -1,230 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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 "osm.h"
#include "osmparser.h"
#include <mapnik/debug.hpp>
#include <libxml/parser.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstring>
polygon_types osm_way::ptypes;
bool osm_dataset::load(const char* filename,std::string const& parser)
{
if (parser == "libxml2")
{
return osmparser::parse(this, filename);
}
return false;
}
osm_dataset::~osm_dataset()
{
clear();
}
void osm_dataset::clear()
{
MAPNIK_LOG_DEBUG(osm) << "osm_dataset: Clear";
MAPNIK_LOG_DEBUG(osm) << "osm_dataset: -- Deleting ways";
for (unsigned int count = 0; count < ways.size(); ++count)
{
delete ways[count];
ways[count] = nullptr;
}
ways.clear();
MAPNIK_LOG_DEBUG(osm) << "osm_dataset: -- Deleting nodes";
for (unsigned int count = 0; count < nodes.size(); ++count)
{
delete nodes[count];
nodes[count] = nullptr;
}
nodes.clear();
MAPNIK_LOG_DEBUG(osm) << "osm_dataset: Clear done";
}
std::string osm_dataset::to_string()
{
std::string result;
for (unsigned int count = 0; count < nodes.size(); ++count)
{
result += nodes[count]->to_string();
}
for (unsigned int count = 0; count < ways.size(); ++count)
{
result += ways[count]->to_string();
}
return result;
}
bounds osm_dataset::get_bounds()
{
bounds b (-180, -90, 180, 90);
for (unsigned int count = 0; count < nodes.size(); ++count)
{
if(nodes[count]->lon > b.w) b.w = nodes[count]->lon;
if(nodes[count]->lon < b.e) b.e = nodes[count]->lon;
if(nodes[count]->lat > b.s) b.s = nodes[count]->lat;
if(nodes[count]->lat < b.n) b.n = nodes[count]->lat;
}
return b;
}
osm_node* osm_dataset::next_node()
{
if (node_i != nodes.end())
{
return *(node_i++);
}
return nullptr;
}
osm_way* osm_dataset::next_way()
{
if (way_i != ways.end())
{
return *(way_i++);
}
return nullptr;
}
osm_item* osm_dataset::next_item()
{
osm_item* item = nullptr;
if (next_item_mode == Node)
{
item = next_node();
if (item == nullptr)
{
next_item_mode = Way;
rewind_ways();
item = next_way();
}
}
else
{
item = next_way();
}
return item;
}
std::set<std::string> osm_dataset::get_keys()
{
std::set<std::string> keys;
for (unsigned int count = 0; count < nodes.size(); ++count)
{
for (std::map<std::string, std::string>::iterator i = nodes[count]->keyvals.begin();
i != nodes[count]->keyvals.end(); i++)
{
keys.insert(i->first);
}
}
for (unsigned int count = 0; count < ways.size(); ++count)
{
for (std::map<std::string, std::string>::iterator i = ways[count]->keyvals.begin();
i != ways[count]->keyvals.end(); i++)
{
keys.insert(i->first);
}
}
return keys;
}
std::string osm_item::to_string()
{
std::ostringstream strm;
strm << "id=" << id << std::endl << "Keyvals: " << std::endl;
for (std::map<std::string, std::string>::iterator i = keyvals.begin();
i != keyvals.end(); i++)
{
strm << "Key " << i->first << " Value " << i->second << std::endl;
}
return strm.str();
}
std::string osm_node::to_string()
{
std::ostringstream strm;
strm << "Node: " << osm_item::to_string() << " lat=" << lat <<" lon=" <<lon << std::endl;
return strm.str();
}
std::string osm_way::to_string()
{
std::ostringstream strm;
strm << "Way: " << osm_item::to_string() << "Nodes in way:";
for (unsigned int count = 0; count < nodes.size(); ++count)
{
if (nodes[count] != nullptr)
{
strm << nodes[count]->id << " ";
}
}
strm << std::endl;
return strm.str();
}
bounds osm_way::get_bounds()
{
bounds b (-180, -90, 180, 90);
for (unsigned int count = 0; count < nodes.size(); ++count)
{
if(nodes[count]->lon > b.w) b.w = nodes[count]->lon;
if(nodes[count]->lon < b.e) b.e = nodes[count]->lon;
if(nodes[count]->lat > b.s) b.s = nodes[count]->lat;
if(nodes[count]->lat < b.n) b.n = nodes[count]->lat;
}
return b;
}
bool osm_way::is_polygon()
{
for (unsigned int count = 0; count < ptypes.ptypes.size(); ++count)
{
if (keyvals.find(ptypes.ptypes[count].first) != keyvals.end() &&
(ptypes.ptypes[count].second.empty() || keyvals[ptypes.ptypes[count].first] == ptypes.ptypes[count].second))
{
return true;
}
}
return false;
}

View file

@ -1,136 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef OSM_H
#define OSM_H
#include <mapnik/value_types.hpp>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <utility>
struct bounds
{
double w, s, e, n;
bounds() { w = -180; s = -90; e = 180; n = 90; }
bounds(double w_, double s_, double e_, double n_)
{
this->w = w_;
this->s = s_;
this->e = e_;
this->n = n_;
}
};
class polygon_types
{
public:
std::vector<std::pair<std::string, std::string> > ptypes;
polygon_types()
{
ptypes.push_back(std::pair<std::string, std::string>("water", ""));
ptypes.push_back(std::pair<std::string, std::string>("aeroway", ""));
ptypes.push_back(std::pair<std::string, std::string>("building", ""));
ptypes.push_back(std::pair<std::string, std::string>("natural", "wood"));
ptypes.push_back(std::pair<std::string, std::string>("natural", "water"));
ptypes.push_back(std::pair<std::string, std::string>("natural", "heath"));
ptypes.push_back(std::pair<std::string, std::string>("natural", "marsh"));
ptypes.push_back(std::pair<std::string, std::string>("military", "danger_area"));
ptypes.push_back(std::pair<std::string, std::string>("landuse", "forest"));
ptypes.push_back(std::pair<std::string, std::string>("landuse", "industrial"));
ptypes.push_back(std::pair<std::string, std::string>("leisure", "park"));
ptypes.push_back(std::pair<std::string, std::string>("area", "yes"));
}
};
struct osm_item
{
mapnik::value_integer id;
std::map<std::string, std::string> keyvals;
virtual std::string to_string();
virtual ~osm_item() {}
};
struct osm_node : public osm_item
{
double lat, lon;
std::string to_string();
};
struct osm_way : public osm_item
{
std::vector<osm_node*> nodes;
std::string to_string();
bounds get_bounds();
bool is_polygon();
static polygon_types ptypes;
};
class osm_dataset
{
public:
osm_dataset()
{
node_i = nodes.begin();
way_i = ways.begin();
next_item_mode = Node;
}
osm_dataset(const char* name)
{
node_i = nodes.begin();
way_i = ways.begin();
next_item_mode = Node;
load(name);
}
~osm_dataset();
bool load(const char* name, std::string const& parser = "libxml2");
void clear();
void add_node(osm_node* n) { nodes.push_back(n); }
void add_way(osm_way* w) { ways.push_back(w); }
std::string to_string();
bounds get_bounds();
std::set<std::string> get_keys();
void rewind_nodes() { node_i = nodes.begin(); }
void rewind_ways() { way_i = ways.begin(); }
void rewind() { rewind_nodes(); rewind_ways(); next_item_mode = Node; }
osm_node * next_node();
osm_way * next_way();
osm_item * next_item();
bool current_item_is_node() { return next_item_mode == Node; }
bool current_item_is_way() { return next_item_mode == Way; }
private:
int next_item_mode;
enum { Node, Way };
std::vector<osm_node*>::iterator node_i;
std::vector<osm_way*>::iterator way_i;
std::vector<osm_node*> nodes;
std::vector<osm_way*> ways;
};
#endif // OSM_H

View file

@ -1,159 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
// stl
#include <stdexcept>
#include <set>
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/geom_util.hpp>
#include <mapnik/query.hpp>
#include <mapnik/boolean.hpp>
// boost
#include "osm_datasource.hpp"
#include "osm_featureset.hpp"
#include "dataset_deliverer.h"
#include "osmtagtypes.h"
#include "osmparser.h"
using mapnik::String;
using mapnik::Double;
using mapnik::Integer;
using mapnik::datasource_exception;
using mapnik::filter_in_box;
using mapnik::filter_at_point;
using mapnik::attribute_descriptor;
DATASOURCE_PLUGIN(osm_datasource)
osm_datasource::osm_datasource(const parameters& params)
: datasource (params),
extent_(),
type_(datasource::Vector),
desc_(osm_datasource::name(), *params.get<std::string>("encoding", "utf-8"))
{
osm_data_ = nullptr;
std::string osm_filename = *params.get<std::string>("file", "");
std::string parser = *params.get<std::string>("parser", "libxml2");
std::string url = *params.get<std::string>("url", "");
std::string bbox = *params.get<std::string>("bbox", "");
// load the data
if (url != "" && bbox != "")
{
throw datasource_exception("Error loading from URL is no longer supported (removed in >= Mapnik 2.3.x");
}
else if (osm_filename != "")
{
// if we supplied a filename, load from file
if ((osm_data_ = dataset_deliverer::load_from_file(osm_filename, parser)) == nullptr)
{
std::string s("OSM Plugin: Error loading from file '");
s += osm_filename + "'";
throw datasource_exception(s);
}
}
else
{
throw datasource_exception("OSM Plugin: Neither 'file' nor 'url' and 'bbox' specified");
}
osm_tag_types tagtypes;
tagtypes.add_type("maxspeed", mapnik::Integer);
tagtypes.add_type("z_order", mapnik::Integer);
osm_data_->rewind();
// Need code to get the attributes of all the data
std::set<std::string> keys = osm_data_->get_keys();
// Add the attributes to the datasource descriptor - assume they are
// all of type String
for (auto const& key : keys)
{
desc_.add_descriptor(attribute_descriptor(key, tagtypes.get_type(key)));
}
// Get the bounds of the data and set extent_ accordingly
bounds b = osm_data_->get_bounds();
extent_ = box2d<double>(b.w,b.s,b.e,b.n);
}
osm_datasource::~osm_datasource()
{
// Do not do as is now static variable and cleaned up at exit
//delete osm_data_;
}
const char * osm_datasource::name()
{
return "osm";
}
mapnik::datasource::datasource_t osm_datasource::type() const
{
return type_;
}
layer_descriptor osm_datasource::get_descriptor() const
{
return desc_;
}
featureset_ptr osm_datasource::features(const query& q) const
{
filter_in_box filter(q.get_bbox());
// so we need to filter osm features by bbox here...
return std::make_shared<osm_featureset<filter_in_box> >(filter,
osm_data_,
q.property_names(),
desc_.get_encoding());
}
featureset_ptr osm_datasource::features_at_point(coord2d const& pt, double tol) const
{
filter_at_point filter(pt);
// collect all attribute names
std::set<std::string> names;
for (auto const& elem : desc_.get_descriptors())
{
names.insert(elem.get_name());
}
return std::make_shared<osm_featureset<filter_at_point> >(filter,
osm_data_,
names,
desc_.get_encoding());
}
box2d<double> osm_datasource::envelope() const
{
return extent_;
}
boost::optional<mapnik::datasource_geometry_t> osm_datasource::get_geometry_type() const
{
return boost::optional<mapnik::datasource_geometry_t>(mapnik::datasource_geometry_t::Collection);
}

View file

@ -1,73 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef OSM_DATASOURCE_HPP
#define OSM_DATASOURCE_HPP
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost
#include <boost/optional.hpp>
#include <memory>
// stl
#include <vector>
#include <string>
#include "osm.h"
using mapnik::datasource;
using mapnik::parameters;
using mapnik::query;
using mapnik::featureset_ptr;
using mapnik::layer_descriptor;
using mapnik::coord2d;
using mapnik::box2d;
class osm_datasource : public datasource
{
public:
osm_datasource(const parameters& params);
virtual ~osm_datasource();
mapnik::datasource::datasource_t type() const;
static const char * name();
featureset_ptr features(const query& q) const;
featureset_ptr features_at_point(coord2d const& pt, double tol = 0) const;
box2d<double> envelope() const;
boost::optional<mapnik::datasource_geometry_t> get_geometry_type() const;
layer_descriptor get_descriptor() const;
private:
box2d<double> extent_;
osm_dataset* osm_data_;
mapnik::datasource::datasource_t type_;
layer_descriptor desc_;
};
#endif // OSM_DATASOURCE_HPP

View file

@ -1,132 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
// mapnik
#include <mapnik/make_unique.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_factory.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/geometry_correct.hpp>
#include "osm_featureset.hpp"
using mapnik::feature_ptr;
using mapnik::feature_factory;
template <typename filterT>
osm_featureset<filterT>::osm_featureset(const filterT& filter,
osm_dataset* dataset,
const std::set<std::string>&
attribute_names,
std::string const& encoding)
: filter_(filter),
query_ext_(),
tr_(new transcoder(encoding)),
dataset_ (dataset),
attribute_names_ (attribute_names),
ctx_(std::make_shared<mapnik::context_type>())
{
dataset_->rewind();
}
template <typename filterT>
feature_ptr osm_featureset<filterT>::next()
{
feature_ptr feature;
osm_item* cur_item = dataset_->next_item();
if (!cur_item) return feature_ptr();
if (dataset_->current_item_is_node())
{
feature = feature_factory::create(ctx_, cur_item->id);
double lat = static_cast<osm_node*>(cur_item)->lat;
double lon = static_cast<osm_node*>(cur_item)->lon;
feature->set_geometry(mapnik::geometry::point<double>(lon,lat));
}
else if (dataset_->current_item_is_way())
{
// Loop until we find a feature which passes the filter
while (cur_item)
{
bounds b = static_cast<osm_way*>(cur_item)->get_bounds();
if (filter_.pass(box2d<double>(b.w, b.s, b.e, b.n))
&&
static_cast<osm_way*>(cur_item)->nodes.size()) break;
cur_item = dataset_->next_item();
}
if (!cur_item) return feature_ptr();
feature = feature_factory::create(ctx_, cur_item->id);
if (static_cast<osm_way*>(cur_item)->is_polygon())
{
mapnik::geometry::linear_ring<double> ring;
for (unsigned int count = 0;
count < static_cast<osm_way*>(cur_item)->nodes.size();
count++)
{
ring.add_coord(static_cast<osm_way*>(cur_item)->nodes[count]->lon,
static_cast<osm_way*>(cur_item)->nodes[count]->lat);
}
mapnik::geometry::polygon<double> geom;
geom.set_exterior_ring(std::move(ring));
mapnik::geometry::correct(geom);
feature->set_geometry(std::move(geom));
}
else
{
mapnik::geometry::line_string<double> geom;
for (unsigned int count = 0;
count < static_cast<osm_way*>(cur_item)->nodes.size();
count++)
{
geom.add_coord(static_cast<osm_way*>(cur_item)->nodes[count]->lon,
static_cast<osm_way*>(cur_item)->nodes[count]->lat);
}
feature->set_geometry(std::move(geom));
}
}
else
{
MAPNIK_LOG_ERROR(osm_featureset) << "Current item is neither node nor way.\n";
}
std::set<std::string>::const_iterator itr = attribute_names_.begin();
std::set<std::string>::const_iterator end = attribute_names_.end();
std::map<std::string,std::string>::iterator end_keyvals = cur_item->keyvals.end();
for (; itr != end; itr++)
{
std::map<std::string,std::string>::iterator i = cur_item->keyvals.find(*itr);
if (i != end_keyvals)
{
feature->put_new(i->first, tr_->transcode(i->second.c_str()));
}
}
return feature;
}
template <typename filterT>
osm_featureset<filterT>::~osm_featureset() {}
template class osm_featureset<mapnik::filter_in_box>;
template class osm_featureset<mapnik::filter_at_point>;

View file

@ -1,72 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef OSM_FS_HH
#define OSM_FS_HH
// stl
#include <set>
// boost
// mapnik
#include <mapnik/geom_util.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/query.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/datasource.hpp>
#include "osm.h"
using mapnik::Featureset;
using mapnik::box2d;
using mapnik::feature_ptr;
using mapnik::transcoder;
template <typename filterT>
class osm_featureset : public Featureset
{
public:
osm_featureset(const filterT& filter,
osm_dataset* dataset,
const std::set<std::string>& attribute_names,
std::string const& encoding);
virtual ~osm_featureset();
feature_ptr next();
private:
filterT filter_;
box2d<double> query_ext_;
const std::unique_ptr<transcoder> tr_;
std::vector<int> attr_ids_;
mutable box2d<double> feature_ext_;
mutable int total_geom_size;
osm_dataset *dataset_;
std::set<std::string> attribute_names_;
mapnik::context_ptr ctx_;
osm_featureset(const osm_featureset&);
const osm_featureset& operator=(const osm_featureset&);
};
#endif // OSM_FS_HH

View file

@ -1,150 +0,0 @@
// much of this is based on osm2pgsql
#include "osmparser.h"
#include "osm.h"
#include <string>
#include <cassert>
#include <mapnik/util/conversions.hpp>
osm_item* osmparser::cur_item=nullptr;
mapnik::value_integer osmparser::curID=0;
bool osmparser::in_node=false, osmparser::in_way=false;
osm_dataset* osmparser::components=nullptr;
std::string osmparser::error="";
std::map<mapnik::value_integer,osm_node*> osmparser::tmp_node_store=std::map<mapnik::value_integer,osm_node*>();
void osmparser::processNode(xmlTextReaderPtr reader)
{
xmlChar *name = xmlTextReaderName(reader);
if(name==nullptr)
name=xmlStrdup(BAD_CAST "--");
switch(xmlTextReaderNodeType(reader))
{
case XML_READER_TYPE_ELEMENT:
startElement(reader,name);
break;
case XML_READER_TYPE_END_ELEMENT:
endElement(name);
}
xmlFree(name);
}
void osmparser::startElement(xmlTextReaderPtr reader, const xmlChar *name)
{
std::string tags;
xmlChar *xid, *xlat, *xlon, *xk, *xv;
if(xmlStrEqual(name,BAD_CAST "node"))
{
curID = 0;
in_node = true;
osm_node *node=new osm_node;
xlat=xmlTextReaderGetAttribute(reader,BAD_CAST "lat");
xlon=xmlTextReaderGetAttribute(reader,BAD_CAST "lon");
xid=xmlTextReaderGetAttribute(reader,BAD_CAST "id");
assert(xlat);
assert(xlon);
assert(xid);
node->lat=atof((char*)xlat);
node->lon=atof((char*)xlon);
mapnik::util::string2int((char *)xid, node->id);
cur_item = node;
tmp_node_store[node->id] = node;
xmlFree(xid);
xmlFree(xlon);
xmlFree(xlat);
}
else if (xmlStrEqual(name,BAD_CAST "way"))
{
curID=0;
in_way = true;
osm_way *way=new osm_way;
xid=xmlTextReaderGetAttribute(reader,BAD_CAST "id");
assert(xid);
mapnik::util::string2int((char *)xid, way->id);
cur_item = way;
xmlFree(xid);
}
else if (xmlStrEqual(name,BAD_CAST "nd"))
{
xid=xmlTextReaderGetAttribute(reader,BAD_CAST "ref");
assert(xid);
mapnik::value_integer ndid;
mapnik::util::string2int((char *)xid, ndid);
if(tmp_node_store.find(ndid)!=tmp_node_store.end())
{
(static_cast<osm_way*>(cur_item))->nodes.push_back
(tmp_node_store[ndid]);
}
xmlFree(xid);
}
else if (xmlStrEqual(name,BAD_CAST "tag"))
{
std::string key="", value="";
xk = xmlTextReaderGetAttribute(reader,BAD_CAST "k");
xv = xmlTextReaderGetAttribute(reader,BAD_CAST "v");
assert(xk);
assert(xv);
cur_item->keyvals[(char*)xk] = (char*)xv;
xmlFree(xk);
xmlFree(xv);
}
if (xmlTextReaderIsEmptyElement(reader))
{
// Fake endElement for empty nodes
endElement(name);
}
}
void osmparser::endElement(const xmlChar* name)
{
if(xmlStrEqual(name,BAD_CAST "node"))
{
in_node = false;
components->add_node(static_cast<osm_node*>(cur_item));
}
else if(xmlStrEqual(name,BAD_CAST "way"))
{
in_way = false;
components->add_way(static_cast<osm_way*>(cur_item));
}
}
bool osmparser::parse(osm_dataset *ds, const char* filename)
{
components=ds;
xmlTextReaderPtr reader = xmlNewTextReaderFilename(filename);
int ret=do_parse(reader);
xmlFreeTextReader(reader);
return (ret==0) ? true:false;
}
bool osmparser::parse(osm_dataset *ds,char* data, int nbytes)
{
// from cocoasamurai.blogspot.com/2008/10/getting-some-xml-love-with-
// libxml2.html, converted from Objective-C to straight C
components=ds;
xmlTextReaderPtr reader = xmlReaderForMemory(data,nbytes,nullptr,nullptr,0);
int ret=do_parse(reader);
xmlFreeTextReader(reader);
return (ret==0) ? true:false;
}
int osmparser::do_parse(xmlTextReaderPtr reader)
{
int ret=-1;
if(reader!=nullptr)
{
ret = xmlTextReaderRead(reader);
while(ret==1)
{
processNode(reader);
ret=xmlTextReaderRead(reader);
}
}
return ret;
}

View file

@ -1,54 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef OSMPARSER_H
#define OSMPARSER_H
#include <mapnik/value_types.hpp>
#include <libxml/xmlreader.h>
#include <cstdio>
#include <cstdlib>
#include <string>
#include "osm.h"
#include <map>
class osmparser
{
public:
static void processNode(xmlTextReaderPtr reader);
static void startElement(xmlTextReaderPtr reader, const xmlChar* name);
static void endElement(const xmlChar* name);
static bool parse(osm_dataset* ds, const char* filename);
static bool parse(osm_dataset* ds, char* data, int nbytes);
private:
static osm_item *cur_item;
static mapnik::value_integer curID;
static bool in_node, in_way;
static osm_dataset* components;
static std::string error;
static std::map<mapnik::value_integer, osm_node*> tmp_node_store;
static int do_parse(xmlTextReaderPtr);
};
#endif // OSMPARSER_H

View file

@ -1,50 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef OSMTAGTYPES_H
#define OSMTAGTYPES_H
// osmtagtypes.h
// for finding the types of particular tags
// mapnik
#include <mapnik/feature_layer_desc.hpp>
class osm_tag_types
{
public:
void add_type(std::string tag, mapnik::eAttributeType type)
{
types[tag] = type;
}
mapnik::eAttributeType get_type(std::string tag)
{
std::map<std::string, mapnik::eAttributeType>::iterator i = types.find(tag);
return (i == types.end()) ? mapnik::String : i->second;
}
private:
std::map<std::string, mapnik::eAttributeType> types;
};
#endif // OSMTAGTYPES_H

View file

@ -1,71 +0,0 @@
#
# This file is part of Mapnik (c++ mapping toolkit)
#
# Copyright (C) 2015 Artem Pavlenko
#
# Mapnik 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
#
#
Import ('plugin_base')
Import ('env')
PLUGIN_NAME = 'rasterlite'
plugin_env = plugin_base.Clone()
plugin_sources = Split(
"""
%(PLUGIN_NAME)s_datasource.cpp
%(PLUGIN_NAME)s_featureset.cpp
""" % locals()
)
# Link Library to Dependencies
libraries = [env['PLUGINS']['rasterlite']['lib']]
libraries.append(env['ICU_LIB_NAME'])
libraries.append('boost_system%s' % env['BOOST_APPEND'])
if env['RUNTIME_LINK'] == 'static':
libraries.append('geotiff')
libraries.append('spatialite')
libraries.append('sqlite3')
libraries.append('geos_c')
libraries.append('geos')
libraries.append('proj')
libraries.append('z')
if env['PLUGIN_LINKING'] == 'shared':
libraries.append(env['MAPNIK_NAME'])
TARGET = plugin_env.SharedLibrary('../%s' % PLUGIN_NAME,
SHLIBPREFIX='',
SHLIBSUFFIX='.input',
source=plugin_sources,
LIBS=libraries)
# if the plugin links to libmapnik ensure it is built first
Depends(TARGET, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
if 'uninstall' not in COMMAND_LINE_TARGETS:
env.Install(env['MAPNIK_INPUT_PLUGINS_DEST'], TARGET)
env.Alias('install', env['MAPNIK_INPUT_PLUGINS_DEST'])
plugin_obj = {
'LIBS': libraries,
'SOURCES': plugin_sources,
}
Return('plugin_obj')

View file

@ -1,191 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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 "rasterlite_datasource.hpp"
#include "rasterlite_featureset.hpp"
// boost
// mapnik
#include <mapnik/util/fs.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/boolean.hpp>
#include <mapnik/geom_util.hpp>
using mapnik::datasource;
using mapnik::parameters;
DATASOURCE_PLUGIN(rasterlite_datasource)
using mapnik::box2d;
using mapnik::coord2d;
using mapnik::query;
using mapnik::featureset_ptr;
using mapnik::layer_descriptor;
using mapnik::datasource_exception;
/*
* Opens a GDALDataset and returns a pointer to it.
* Caller is responsible for calling GDALClose on it
*/
inline void* rasterlite_datasource::open_dataset() const
{
void* dataset = rasterliteOpen (dataset_name_.c_str(), table_name_.c_str());
if (! dataset)
{
throw datasource_exception("Rasterlite Plugin: Error opening dataset");
}
if (rasterliteIsError (dataset))
{
std::string error (rasterliteGetLastError(dataset));
rasterliteClose (dataset);
throw datasource_exception(error);
}
return dataset;
}
rasterlite_datasource::rasterlite_datasource(parameters const& params)
: datasource(params),
desc_(rasterlite_datasource::name(),"utf-8")
{
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Initializing...";
boost::optional<std::string> file = params.get<std::string>("file");
if (!file) throw datasource_exception("missing <file> parameter");
boost::optional<std::string> table = params.get<std::string>("table");
if (!table) throw datasource_exception("missing <table> parameter");
table_name_ = *table;
boost::optional<std::string> base = params.get<std::string>("base");
if (base)
dataset_name_ = *base + "/" + *file;
else
dataset_name_ = *file;
if (!mapnik::util::exists(dataset_name_)) throw datasource_exception(dataset_name_ + " does not exist");
void *dataset = open_dataset();
double x0, y0, x1, y1;
if (rasterliteGetExtent (dataset, &x0, &y0, &x1, &y1) != RASTERLITE_OK)
{
std::string error (rasterliteGetLastError(dataset));
rasterliteClose (dataset);
throw datasource_exception(error);
}
extent_.init(x0,y0,x1,y1);
#ifdef MAPNIK_LOG
int srid, auth_srid;
const char *auth_name;
const char *ref_sys_name;
const char *proj4text;
int tile_count;
double pixel_x_size, pixel_y_size;
int levels = rasterliteGetLevels (dataset);
if (rasterliteGetSrid(dataset, &srid, &auth_name, &auth_srid, &ref_sys_name, &proj4text) != RASTERLITE_OK)
{
std::string error (rasterliteGetLastError(dataset));
rasterliteClose (dataset);
throw datasource_exception(error);
}
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Data Source=" << rasterliteGetTablePrefix(dataset);
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: SRID=" << srid;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Authority=" << auth_name;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: AuthSRID=" << auth_srid;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: RefSys Name=" << ref_sys_name;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Proj4Text=" << proj4text;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Extent=" << x0 << "," << y0 << " " << x1 << "," << y1 << ")";
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Levels=" << levels;
for (int i = 0; i < levels; i++)
{
if (rasterliteGetResolution(dataset, i, &pixel_x_size, &pixel_y_size, &tile_count) == RASTERLITE_OK)
{
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Level=" << i
<< " x=" << pixel_x_size
<< " y=" << pixel_y_size
<< " tiles=" << tile_count;
}
}
#endif
rasterliteClose(dataset);
}
rasterlite_datasource::~rasterlite_datasource()
{
}
const char * rasterlite_datasource::name()
{
return "rasterlite";
}
mapnik::datasource::datasource_t rasterlite_datasource::type() const
{
return datasource::Raster;
}
box2d<double> rasterlite_datasource::envelope() const
{
return extent_;
}
boost::optional<mapnik::datasource_geometry_t> rasterlite_datasource::get_geometry_type() const
{
return boost::optional<mapnik::datasource_geometry_t>();
}
layer_descriptor rasterlite_datasource::get_descriptor() const
{
return desc_;
}
featureset_ptr rasterlite_datasource::features(query const& q) const
{
rasterlite_query gq = q;
return std::make_shared<rasterlite_featureset>(open_dataset(), gq);
}
featureset_ptr rasterlite_datasource::features_at_point(coord2d const& pt, double tol) const
{
rasterlite_query gq = pt;
return std::make_shared<rasterlite_featureset>(open_dataset(), gq);
}

View file

@ -1,66 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef RASTERLITE_DATASOURCE_HPP
#define RASTERLITE_DATASOURCE_HPP
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost
#include <boost/optional.hpp>
#include <memory>
// stl
#include <vector>
#include <string>
#include "rasterlite_include.hpp"
class rasterlite_datasource : public mapnik::datasource
{
public:
rasterlite_datasource(mapnik::parameters const& params);
virtual ~rasterlite_datasource ();
mapnik::datasource::datasource_t type() const;
static const char * name();
mapnik::featureset_ptr features(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const;
mapnik::box2d<double> envelope() const;
boost::optional<mapnik::datasource_geometry_t> get_geometry_type() const;
mapnik::layer_descriptor get_descriptor() const;
private:
void* open_dataset() const;
mapnik::box2d<double> extent_;
std::string dataset_name_;
std::string table_name_;
mapnik::layer_descriptor desc_;
};
#endif // RASTERLITE_DATASOURCE_HPP

View file

@ -1,136 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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 "rasterlite_featureset.hpp"
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/image.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/query.hpp>
#include <mapnik/raster.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_factory.hpp>
#include <cstring>
using mapnik::coord2d;
using mapnik::box2d;
using mapnik::feature_ptr;
using mapnik::query;
using mapnik::feature_factory;
rasterlite_featureset::rasterlite_featureset(void* dataset,
rasterlite_query q)
: dataset_(dataset),
gquery_(q),
first_(true),
ctx_(std::make_shared<mapnik::context_type>())
{
rasterliteSetBackgroundColor(dataset_, 255, 0, 255);
rasterliteSetTransparentColor(dataset_, 255, 0, 255);
}
rasterlite_featureset::~rasterlite_featureset()
{
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Closing";
rasterliteClose(dataset_);
}
feature_ptr rasterlite_featureset::next()
{
if (first_)
{
first_ = false;
MAPNIK_LOG_DEBUG(gdal) << "rasterlite_featureset: Next feature in Dataset=" << &dataset_;
return mapnik::util::apply_visitor(query_dispatch(*this), gquery_);
}
return feature_ptr();
}
feature_ptr rasterlite_featureset::get_feature(mapnik::query const& q)
{
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Running get_feature";
feature_ptr feature(feature_factory::create(ctx_,1));
double x0, y0, x1, y1;
rasterliteGetExtent (dataset_, &x0, &y0, &x1, &y1);
box2d<double> raster_extent(x0, y0, x1, y1);
box2d<double> intersect = raster_extent.intersect(q.get_bbox());
const int width = static_cast<int>(std::get<0>(q.resolution()) * intersect.width() + 0.5);
const int height = static_cast<int>(std::get<0>(q.resolution()) * intersect.height() + 0.5);
const double pixel_size = (intersect.width() >= intersect.height()) ?
(intersect.width() / (double) width) : (intersect.height() / (double) height);
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Raster extent=" << raster_extent;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: View extent=" << q.get_bbox();
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Intersect extent=" << intersect;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Query resolution=" << std::get<0>(q.resolution()) << "," << std::get<1>(q.resolution());
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Size=" << width << " " << height;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Pixel Size=" << pixel_size;
if (width > 0 && height > 0)
{
int size = 0;
void* raster = 0;
if (rasterliteGetRawImageByRect(dataset_,
intersect.minx(),
intersect.miny(),
intersect.maxx(),
intersect.maxy(),
pixel_size,
width,
height,
GAIA_RGBA_ARRAY,
&raster,
&size) == RASTERLITE_OK)
{
if (size > 0)
{
mapnik::image_rgba8 image(width,height);
unsigned char* raster_data = static_cast<unsigned char*>(raster);
std::memcpy(image.bytes(), raster_data, size);
feature->set_raster(std::make_shared<mapnik::raster>(intersect, std::move(image), 1.0));
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Done";
}
else
{
MAPNIK_LOG_ERROR(rasterlite) << "Rasterlite Plugin: Error " << rasterliteGetLastError (dataset_);
}
}
return feature;
}
return feature_ptr();
}
feature_ptr rasterlite_featureset::get_feature_at_point(mapnik::coord2d const& pt)
{
return feature_ptr();
}

View file

@ -1,71 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef RASTERLITE_FEATURESET_HPP
#define RASTERLITE_FEATURESET_HPP
// mapnik
#include <mapnik/feature.hpp>
#include <mapnik/query.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/util/variant.hpp>
#include "rasterlite_include.hpp"
using rasterlite_query = mapnik::util::variant<mapnik::query,mapnik::coord2d>;
class rasterlite_featureset : public mapnik::Featureset
{
struct query_dispatch
{
query_dispatch( rasterlite_featureset & featureset)
: featureset_(featureset) {}
mapnik::feature_ptr operator() (mapnik::query const& q) const
{
return featureset_.get_feature(q);
}
mapnik::feature_ptr operator() (mapnik::coord2d const& p) const
{
return featureset_.get_feature_at_point(p);
}
rasterlite_featureset & featureset_;
};
public:
rasterlite_featureset(void* dataset,
rasterlite_query q);
virtual ~rasterlite_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);
void* dataset_;
rasterlite_query gquery_;
bool first_;
mapnik::context_ptr ctx_;
};
#endif // RASTERLITE_FEATURESET_HPP

View file

@ -1,31 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef RASTERLITE_INCLUDE_HPP
#define RASTERLITE_INCLUDE_HPP
extern "C" {
#include <sqlite3.h>
#include <rasterlite.h>
}
#endif // RASTERLITE_INCLUDE_HPP