From 7d2f492ef28425e40002c893658a2f581741eafb Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Mon, 9 Feb 2009 19:43:57 +0000 Subject: [PATCH] + sqlite-input-plugin.patch (kunitoki) + wkb-sqlite.patch (kunitoki) + very preliminary spatial index support (idx__) --- SConstruct | 5 +- include/mapnik/wkb.hpp | 7 +- plugins/input/sqlite/Makefile.am | 24 ++ plugins/input/sqlite/SConscript | 43 ++++ plugins/input/sqlite/sqlite_datasource.cpp | 260 +++++++++++++++++++++ plugins/input/sqlite/sqlite_datasource.hpp | 62 +++++ plugins/input/sqlite/sqlite_featureset.cpp | 122 ++++++++++ plugins/input/sqlite/sqlite_featureset.hpp | 54 +++++ plugins/input/sqlite/sqlite_types.hpp | 251 ++++++++++++++++++++ src/wkb.cpp | 23 +- 10 files changed, 843 insertions(+), 8 deletions(-) create mode 100644 plugins/input/sqlite/Makefile.am create mode 100644 plugins/input/sqlite/SConscript create mode 100644 plugins/input/sqlite/sqlite_datasource.cpp create mode 100644 plugins/input/sqlite/sqlite_datasource.hpp create mode 100644 plugins/input/sqlite/sqlite_featureset.cpp create mode 100644 plugins/input/sqlite/sqlite_featureset.hpp create mode 100644 plugins/input/sqlite/sqlite_types.hpp diff --git a/SConstruct b/SConstruct index dd68a13c3..e4a28334e 100644 --- a/SConstruct +++ b/SConstruct @@ -81,6 +81,7 @@ PLUGINS = { # plugins with external dependencies 'gdal': {'default':False,'path':'GDAL','inc':'gdal_priv.h','lib':'gdal','cxx':True}, 'ogr': {'default':False,'path':'OGR','inc':'ogrsf_frmts.h','lib':'gdal','cxx':True}, 'occi': {'default':False,'path':'OCCI','inc':'occi.h','lib':'ociei','cxx':True}, + 'sqlite': {'default':False,'path':'SQLITE','inc':'sqlite3.h','lib':'sqlite3','cxx':False}, # plugins without external dependencies 'shape': {'default':True,'path':None,'inc':None,'lib':None,'cxx':True}, @@ -151,6 +152,8 @@ opts.Add(PathVariable('OGR_INCLUDES', 'Search path for OGR include files', '/usr opts.Add(PathVariable('OGR_LIBS', 'Search path for OGR library files', '/usr/local/' + LIBDIR_SCHEMA)) opts.Add(PathVariable('OCCI_INCLUDES', 'Search path for OCCI include files', '/usr/lib/oracle/10.2.0.3/client/include/', PathVariable.PathAccept)) opts.Add(PathVariable('OCCI_LIBS', 'Search path for OCCI library files', '/usr/lib/oracle/10.2.0.3/client/'+ LIBDIR_SCHEMA, PathVariable.PathAccept)) +opts.Add(PathVariable('SQLITE_INCLUDES', 'Search path for SQLITE include files', '/usr/include/', PathVariable.PathAccept)) +opts.Add(PathVariable('SQLITE_LIBS', 'Search path for SQLITE library files', '/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept)) # Other variables opts.Add(PathVariable('PYTHON','Full path to Python executable used to build bindings', sys.executable)) @@ -608,7 +611,7 @@ else: if env['DEBUG']: env.Append(CXXFLAGS = gcc_cxx_flags + '-O0 -fno-inline %s' % debug_flags) else: - env.Append(CXXFLAGS = gcc_cxx_flags + '-O%s -finline-functions -Wno-inline %s' % (env['OPTIMIZATION'],ndebug_flags)) + env.Append(CXXFLAGS = gcc_cxx_flags + '-fast -finline-functions -Wno-inline %s' % (ndebug_flags)) SConscript('fonts/SConscript') diff --git a/include/mapnik/wkb.hpp b/include/mapnik/wkb.hpp index ac07a3ccd..4cdfb4b99 100644 --- a/include/mapnik/wkb.hpp +++ b/include/mapnik/wkb.hpp @@ -33,7 +33,12 @@ namespace mapnik class MAPNIK_DECL geometry_utils { public: - static void from_wkb(Feature & feature,const char* wkb, unsigned size, bool multiple_geometries = false); + + static void from_wkb (Feature & feature, + const char* wkb, + unsigned size, + bool multiple_geometries = false, + bool sqlite_format = false); private: geometry_utils(); geometry_utils(geometry_utils const&); diff --git a/plugins/input/sqlite/Makefile.am b/plugins/input/sqlite/Makefile.am new file mode 100644 index 000000000..fc542dd59 --- /dev/null +++ b/plugins/input/sqlite/Makefile.am @@ -0,0 +1,24 @@ +if HAVE_SQLITE + +pkglib_LTLIBRARIES = \ + sqlite.la + +sqlite_la_SOURCES = \ + sqlite_datasource.cpp\ + sqlite_featureset.cpp + +sqlite_la_LIBADD = \ + ${SQLITE_LDFLAGS} + +sqlite_la_CXXFLAGS = \ + ${SQLITE_CFLAGS} \ + -I../../../include + +sqlite_la_LDFLAGS = \ + -module \ + -avoid-version \ + -shrext .input + +endif + +## File created by the gnome-build tools diff --git a/plugins/input/sqlite/SConscript b/plugins/input/sqlite/SConscript new file mode 100644 index 000000000..f00c9a8f7 --- /dev/null +++ b/plugins/input/sqlite/SConscript @@ -0,0 +1,43 @@ +# +# This file is part of Mapnik (c++ mapping toolkit) +# +# Copyright (C) 2007 Artem Pavlenko, Jean-Francois Doyon +# +# 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 +# +# $Id$ + +Import ('env') + +prefix = env['PREFIX'] +install_prefix = env['DESTDIR'] + '/' + prefix + +sqlite_src = Split( + """ + sqlite_datasource.cpp + sqlite_featureset.cpp + """ + ) + +libraries = [ 'sqlite3' ] +if env['PLATFORM'] == 'Darwin': + libraries.append('mapnik') + libraries.append('icuuc') + libraries.append('icudata') + +sqlite_inputdriver = env.SharedLibrary('sqlite', source=sqlite_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries) + +env.Install(install_prefix + '/' + env['LIBDIR_SCHEMA'] + '/mapnik/input', sqlite_inputdriver) +env.Alias('install', install_prefix + '/' + env['LIBDIR_SCHEMA'] + '/mapnik/input') diff --git a/plugins/input/sqlite/sqlite_datasource.cpp b/plugins/input/sqlite/sqlite_datasource.cpp new file mode 100644 index 000000000..03f99b94a --- /dev/null +++ b/plugins/input/sqlite/sqlite_datasource.cpp @@ -0,0 +1,260 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2007 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 + * + *****************************************************************************/ +// $Id$ + +#include "sqlite_datasource.hpp" +#include "sqlite_featureset.hpp" + +// mapnik +#include + +// boost +#include +#include +#include + +using std::clog; +using std::endl; + +using boost::lexical_cast; +using boost::bad_lexical_cast; + +using mapnik::datasource; +using mapnik::parameters; + +DATASOURCE_PLUGIN(sqlite_datasource) + +using mapnik::Envelope; +using mapnik::coord2d; +using mapnik::query; +using mapnik::featureset_ptr; +using mapnik::layer_descriptor; +using mapnik::attribute_descriptor; +using mapnik::datasource_exception; + + +sqlite_datasource::sqlite_datasource(parameters const& params) + : datasource(params), + extent_(), + extent_initialized_(false), + type_(datasource::Vector), + table_(*params.get("table","")), + geometry_field_(*params.get("geometry_field","geom")), + geocatalog_(*params.get("geometry_catalog","geocatalog")), + desc_(*params.get("type"), *params.get("encoding","utf-8")) +{ + boost::optional file = params.get("file"); + if (!file) throw datasource_exception("missing paramater"); + + multiple_geometries_ = *params_.get("multiple_geometries",false); + + dataset_ = new sqlite_connection (*file); + + boost::optional ext = params_.get("extent"); + if (ext) + { + boost::char_separator sep(","); + boost::tokenizer > tok(*ext,sep); + unsigned i = 0; + bool success = false; + double d[4]; + for (boost::tokenizer >::iterator beg=tok.begin(); + beg!=tok.end();++beg) + { + try + { + d[i] = boost::lexical_cast(*beg); + } + catch (boost::bad_lexical_cast & ex) + { + std::clog << ex.what() << "\n"; + break; + } + if (i==3) + { + success = true; + break; + } + ++i; + } + + if (success) + { + extent_.init(d[0],d[1],d[2],d[3]); + extent_initialized_ = true; + } + } + +#if 0 + { + std::ostringstream s; + s << "select minx, miny, maxx, maxy from " << geocatalog_; + s << " where lower(table_name) = lower('" << table_ << "')"; + boost::shared_ptr rs = dataset_->execute_query (s.str()); + if (rs->is_valid () && rs->step_next()) + { + double minx = rs->column_double (0); + double miny = rs->column_double (1); + double maxx = rs->column_double (2); + double maxy = rs->column_double (3); + + extent_.init (minx,miny,maxx,maxy); + } + } +#endif + + { + std::ostringstream s; + s << "select * from " << table_ << " limit 1"; + boost::shared_ptr rs = dataset_->execute_query (s.str()); + if (rs->is_valid () && rs->step_next()) + { + /* + XXX - This is problematic, if we don't have at least a row, + we cannot determine the right columns types and names + as all column_type are SQLITE_NULL + */ + + for (int i = 0; i < rs->column_count (); ++i) + { + const int type_oid = rs->column_type (i); + const char* fld_name = rs->column_name (i); + switch (type_oid) + { + case SQLITE_INTEGER: +#ifdef MAPNIK_DEBUG + clog << fld_name << " integer" << endl; +#endif + desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer)); + break; + + case SQLITE_FLOAT: +#ifdef MAPNIK_DEBUG + clog << fld_name << " double" << endl; +#endif + desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Double)); + break; + + case SQLITE_TEXT: +#ifdef MAPNIK_DEBUG + clog << fld_name << " text" << endl; +#endif + desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String)); + break; + + case SQLITE_NULL: + case SQLITE_BLOB: + break; + + default: +#ifdef MAPNIK_DEBUG + clog << "unknown type_oid="< sqlite_datasource::envelope() const +{ + return extent_; +} + +layer_descriptor sqlite_datasource::get_descriptor() const +{ + return desc_; +} + +featureset_ptr sqlite_datasource::features(query const& q) const +{ + if (dataset_) + { + + mapnik::Envelope const& e = q.get_bbox(); +#if 0 + layer_->SetSpatialFilterRect (query_extent.minx(), + query_extent.miny(), + query_extent.maxx(), + query_extent.maxy()); +#endif + + std::ostringstream s; + s << "select " << geometry_field_ << ",PK_UID"; + std::set const& props = q.property_names(); + std::set::const_iterator pos = props.begin(); + std::set::const_iterator end = props.end(); + while (pos != end) + { + s << "," << *pos << ""; + ++pos; + } + s << " from " << table_ << "," << "idx_" << table_ << "_" << geometry_field_; + s << " where " << table_<<".PK_UID="<< "idx_" << table_ << "_" << geometry_field_ << ".pkid" ; + s << " and xmax>=" << e.minx() << " and xmin<=" << e.maxx() ; + s << " and ymax>=" << e.miny() << " and ymin<=" << e.maxy() ; + + std::cerr << s.str() << "\n"; + boost::shared_ptr rs = dataset_->execute_query (s.str()); + + return featureset_ptr (new sqlite_featureset(rs, desc_.get_encoding(), multiple_geometries_)); + } + + return featureset_ptr(); +} + +featureset_ptr sqlite_datasource::features_at_point(coord2d const& pt) const +{ +#if 0 + if (dataset_ && layer_) + { + OGRPoint point; + point.setX (pt.x); + point.setY (pt.y); + + layer_->SetSpatialFilter (&point); + + return featureset_ptr(new ogr_featureset(*dataset_, *layer_, desc_.get_encoding(), multiple_geometries_)); + } +#endif + + return featureset_ptr(); +} + diff --git a/plugins/input/sqlite/sqlite_datasource.hpp b/plugins/input/sqlite/sqlite_datasource.hpp new file mode 100644 index 000000000..14780d643 --- /dev/null +++ b/plugins/input/sqlite/sqlite_datasource.hpp @@ -0,0 +1,62 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2007 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 + * + *****************************************************************************/ +//$Id$ + +#ifndef SQLITE_DATASOURCE_HPP +#define SQLITE_DATASOURCE_HPP + +// mapnik +#include +#include +#include + +// boost +#include +#include + +// sqlite +#include "sqlite_types.hpp" + +class sqlite_datasource : public mapnik::datasource +{ + public: + sqlite_datasource(mapnik::parameters const& params); + virtual ~sqlite_datasource (); + int type() const; + static std::string name(); + mapnik::featureset_ptr features(mapnik::query const& q) const; + mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; + mapnik::Envelope envelope() const; + mapnik::layer_descriptor get_descriptor() const; + private: + static const std::string name_; + mapnik::Envelope extent_; + mutable bool extent_initialized_; + int type_; + sqlite_connection* dataset_; + std::string table_, geometry_field_, geocatalog_; + mapnik::layer_descriptor desc_; + bool multiple_geometries_; +}; + + +#endif // SQLITE_DATASOURCE_HPP diff --git a/plugins/input/sqlite/sqlite_featureset.cpp b/plugins/input/sqlite/sqlite_featureset.cpp new file mode 100644 index 000000000..754f555e0 --- /dev/null +++ b/plugins/input/sqlite/sqlite_featureset.cpp @@ -0,0 +1,122 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2007 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 + * + *****************************************************************************/ +//$Id$ + +#include +#include +#include +#include +#include +#include +#include +#include + +// ogr +#include "sqlite_featureset.hpp" + +using std::clog; +using std::endl; + +using mapnik::query; +using mapnik::Envelope; +using mapnik::CoordTransform; +using mapnik::Feature; +using mapnik::feature_ptr; +using mapnik::point_impl; +using mapnik::line_string_impl; +using mapnik::polygon_impl; +using mapnik::geometry2d; +using mapnik::geometry_utils; +using mapnik::transcoder; + +sqlite_featureset::sqlite_featureset(boost::shared_ptr rs, + std::string const& encoding, + bool multiple_geometries) + : rs_(rs), + tr_(new transcoder(encoding)), + multiple_geometries_(multiple_geometries), + count_(0) +{ +} + +sqlite_featureset::~sqlite_featureset() {} + +feature_ptr sqlite_featureset::next() +{ + if (rs_->is_valid () && rs_->step_next ()) + { + feature_ptr feature(new Feature(count_)); + +#ifdef MAPNIK_DEBUG + clog << "feature_oid=" << count_ << endl; +#endif + + int size; + const char* data = (const char *) rs_->column_blob (0, size); + geometry_utils::from_wkb(*feature,data,size,multiple_geometries_,true); + + for (int i = 1; i < rs_->column_count (); ++i) + { + const int type_oid = rs_->column_type (i); + const char* fld_name = rs_->column_name (i); + + switch (type_oid) + { + case SQLITE_INTEGER: + { + boost::put(*feature,fld_name,rs_->column_integer (i)); + break; + } + + case SQLITE_FLOAT: + { + boost::put(*feature,fld_name,rs_->column_double (i)); + break; + } + + case SQLITE_TEXT: + { + UnicodeString ustr = tr_->transcode (rs_->column_text (i)); + boost::put(*feature,fld_name,ustr); + break; + } + + case SQLITE_BLOB: + case SQLITE_NULL: + break; + + default: +#ifdef MAPNIK_DEBUG + clog << "unhandled type_oid=" << type_oid << endl; +#endif + break; + } + } + + count_++; + + return feature; + } + + return feature_ptr(); +} + diff --git a/plugins/input/sqlite/sqlite_featureset.hpp b/plugins/input/sqlite/sqlite_featureset.hpp new file mode 100644 index 000000000..f22f371a8 --- /dev/null +++ b/plugins/input/sqlite/sqlite_featureset.hpp @@ -0,0 +1,54 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2007 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 + * + *****************************************************************************/ +//$Id$ + +#ifndef SQLITE_FEATURESET_HPP +#define SQLITE_FEATURESET_HPP + +// mapnik +#include +#include + +// boost +#include +#include + +// sqlite +#include "sqlite_types.hpp" + + +class sqlite_featureset : public mapnik::Featureset +{ + public: + sqlite_featureset(boost::shared_ptr rs, + std::string const& encoding, + bool multiple_geometries); + virtual ~sqlite_featureset(); + mapnik::feature_ptr next(); + private: + boost::shared_ptr rs_; + boost::scoped_ptr tr_; + bool multiple_geometries_; + mutable int count_; +}; + +#endif // SQLITE_FEATURESET_HPP diff --git a/plugins/input/sqlite/sqlite_types.hpp b/plugins/input/sqlite/sqlite_types.hpp new file mode 100644 index 000000000..260630a80 --- /dev/null +++ b/plugins/input/sqlite/sqlite_types.hpp @@ -0,0 +1,251 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2007 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 + * + *****************************************************************************/ +//$Id$ + +#ifndef SQLITE_TYPES_HPP +#define SQLITE_TYPES_HPP + +// mapnik +#include + +// boost +#include + +// sqlite +extern "C" { + #include +} + + +class sqlite_resultset +{ +public: + + sqlite_resultset (sqlite3_stmt* stmt) + : stmt_(stmt) + { + } + + ~sqlite_resultset () + { + if (stmt_) + sqlite3_finalize (stmt_); + } + + bool is_valid () + { + return stmt_ != 0; + } + + bool step_next () + { + return (sqlite3_step (stmt_) == SQLITE_ROW); + } + + int column_count () + { + return sqlite3_column_count (stmt_); + } + + int column_type (int col) + { + return sqlite3_column_type (stmt_, col); + } + + const char* column_name (int col) + { + return sqlite3_column_name (stmt_, col); + } + + bool column_isnull (int col) + { + return sqlite3_column_type (stmt_, col) == SQLITE_NULL; + } + + int column_integer (int col) + { + return sqlite3_column_int (stmt_, col); + } + + double column_double (int col) + { + return sqlite3_column_double (stmt_, col); + } + + const char* column_text (int col) + { + return (const char*) sqlite3_column_text (stmt_, col); + } + + const void* column_blob (int col, int& bytes) + { + bytes = sqlite3_column_bytes (stmt_, col); + + return sqlite3_column_blob (stmt_, col); + } + + sqlite3_stmt* get_statement() + { + return stmt_; + } + +private: + + sqlite3_stmt* stmt_; +}; + + + +class sqlite_connection +{ +public: + + typedef int (*sqlite_query_callback) (void*, int, char**, char**); + + sqlite_connection (const std::string& file) + : db_(0) + { + if (sqlite3_open (file.c_str(), &db_)) + throw mapnik::datasource_exception (sqlite3_errmsg (db_)); + } + + ~sqlite_connection () + { + if (db_) + sqlite3_close (db_); + } + + int execute_query_callback (const std::string& sql, sqlite_query_callback callback) + { + char* error_message = 0; + + int rc = sqlite3_exec (db_, sql.c_str(), callback, 0, &error_message); + if (rc != SQLITE_OK) + { + sqlite3_free (error_message); + } + + return rc; + } + + boost::shared_ptr execute_query (const std::string& sql) + { + sqlite3_stmt* stmt = 0; + + int rc = sqlite3_prepare_v2 (db_, sql.c_str(), -1, &stmt, 0); + if (rc != SQLITE_OK) + { + } + + return boost::shared_ptr (new sqlite_resultset (stmt)); + } + +#if 0 + std::vector get_table_columns (const std::string& sql) + { + char** result; + char* error_message = 0; + int nrow, ncol; + std::vector head; + + int rc = sqlite3_exec (db_, sql.c_str(), &result, &nrow, &ncol, &error_message); + if (rc == SQLITE_OK) + { + for (int i = 0; i < ncol; ++i) + head.push_back (result[i]); +// for (int i = 0; i < ncol * nrow; ++i) +// vdata.push_back(result[ncol+i]); + } + + sqlite3_free_table(result); + + return head; + } +#endif + + sqlite3* operator*() + { + return db_; + } + +private: + + sqlite3* db_; +}; + + + +#if 0 + +static int callback (void *not_used, int argc, char **argv, char** column_name) +{ + not_used = 0; + for (int i = 0; i < argc; i++) + { + std::cout << column_name[i] << " = " << (argv[i] ? argv[i] : "NULL") << std::endl; + } + return 0; +} + +static int print_col (sqlite_resultset& rs, int col) +{ + switch (rs.column_type (col)) + { + case SQLITE_INTEGER: + std::cout << "INTEGER: " << rs.column_integer (col) << std::endl; + break; + case SQLITE_FLOAT: + std::cout << "FLOAT: " << rs.column_double (col) << std::endl; + break; + case SQLITE_TEXT: + std::cout << "TEXT: " << rs.column_text (col) << std::endl; + break; + case SQLITE_BLOB: + { + std::cout << "BLOB: "; + + int size; + const char * data = (const char *) rs.column_blob (col, size); + + for (int i = 0; i < size; i++) + { + std::cout << data [i] << " "; + } + + std::cout << std::endl; + + break; + } + case SQLITE_NULL: + std::cout << "Null " << std::endl; + break; + default: + std::cout << " *Cannot determine SQLITE TYPE* col=" << col << std::endl; + } + + return 0; +} + +#endif + +#endif //SQLITE_TYPES_HPP + diff --git a/src/wkb.cpp b/src/wkb.cpp index f774a5040..c0f37aa68 100644 --- a/src/wkb.cpp +++ b/src/wkb.cpp @@ -41,6 +41,8 @@ namespace mapnik unsigned pos_; wkbByteOrder byteOrder_; bool needSwap_; + bool sqliteFormat_; + public: enum wkbGeometryType { @@ -53,14 +55,23 @@ namespace mapnik wkbGeometryCollection=7 }; - wkb_reader(const char* wkb,unsigned size) + wkb_reader(const char* wkb,unsigned size,bool sqliteFormat = false) : wkb_(wkb), size_(size), pos_(0), - byteOrder_((wkbByteOrder)wkb_[0]) + sqliteFormat_(sqliteFormat) { - ++pos_; - + if (sqliteFormat) + { + byteOrder_ = (wkbByteOrder) wkb_[1]; + pos_ = 39; + } + else + { + byteOrder_ = (wkbByteOrder) wkb_[0]; + ++pos_; + } + #ifndef WORDS_BIGENDIAN needSwap_=byteOrder_?wkbXDR:wkbNDR; #else @@ -340,9 +351,9 @@ namespace mapnik } }; - void geometry_utils::from_wkb(Feature & feature,const char* wkb, unsigned size, bool multiple_geometries) + void geometry_utils::from_wkb(Feature & feature,const char* wkb, unsigned size, bool multiple_geometries, bool sqlite_format) { - wkb_reader reader(wkb,size); + wkb_reader reader(wkb,size,sqlite_format); if (multiple_geometries) return reader.read_multi(feature); else