+ sqlite-input-plugin.patch (kunitoki)

+ wkb-sqlite.patch (kunitoki)
+ very preliminary spatial index support (idx_<tablename>_<geometry_field>)
This commit is contained in:
Artem Pavlenko 2009-02-09 19:43:57 +00:00
parent 5ac5522f4b
commit 7d2f492ef2
10 changed files with 843 additions and 8 deletions

View file

@ -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')

View file

@ -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&);

View file

@ -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

View file

@ -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')

View file

@ -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 <mapnik/ptree_helpers.hpp>
// boost
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
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<std::string>("table","")),
geometry_field_(*params.get<std::string>("geometry_field","geom")),
geocatalog_(*params.get<std::string>("geometry_catalog","geocatalog")),
desc_(*params.get<std::string>("type"), *params.get<std::string>("encoding","utf-8"))
{
boost::optional<std::string> file = params.get<std::string>("file");
if (!file) throw datasource_exception("missing <file> paramater");
multiple_geometries_ = *params_.get<mapnik::boolean>("multiple_geometries",false);
dataset_ = new sqlite_connection (*file);
boost::optional<std::string> ext = params_.get<std::string>("extent");
if (ext)
{
boost::char_separator<char> sep(",");
boost::tokenizer<boost::char_separator<char> > tok(*ext,sep);
unsigned i = 0;
bool success = false;
double d[4];
for (boost::tokenizer<boost::char_separator<char> >::iterator beg=tok.begin();
beg!=tok.end();++beg)
{
try
{
d[i] = boost::lexical_cast<double>(*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<sqlite_resultset> 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<sqlite_resultset> 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="<<type_oid<<endl;
#endif
break;
}
}
}
}
}
sqlite_datasource::~sqlite_datasource()
{
delete dataset_;
}
std::string const sqlite_datasource::name_="sqlite";
std::string sqlite_datasource::name()
{
return name_;
}
int sqlite_datasource::type() const
{
return type_;
}
Envelope<double> 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<double> 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<std::string> const& props = q.property_names();
std::set<std::string>::const_iterator pos = props.begin();
std::set<std::string>::const_iterator end = props.end();
while (pos != end)
{
s << "," << *pos << "";
++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<sqlite_resultset> 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();
}

View file

@ -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 <mapnik/datasource.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
// 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<double> envelope() const;
mapnik::layer_descriptor get_descriptor() const;
private:
static const std::string name_;
mapnik::Envelope<double> 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

View file

@ -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 <mapnik/global.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/envelope.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/unicode.hpp>
// 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<sqlite_resultset> 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();
}

View file

@ -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 <mapnik/datasource.hpp>
#include <mapnik/unicode.hpp>
// boost
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
// sqlite
#include "sqlite_types.hpp"
class sqlite_featureset : public mapnik::Featureset
{
public:
sqlite_featureset(boost::shared_ptr<sqlite_resultset> rs,
std::string const& encoding,
bool multiple_geometries);
virtual ~sqlite_featureset();
mapnik::feature_ptr next();
private:
boost::shared_ptr<sqlite_resultset> rs_;
boost::scoped_ptr<mapnik::transcoder> tr_;
bool multiple_geometries_;
mutable int count_;
};
#endif // SQLITE_FEATURESET_HPP

View file

@ -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 <mapnik/datasource.hpp>
// boost
#include <boost/shared_ptr.hpp>
// sqlite
extern "C" {
#include <sqlite3.h>
}
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<sqlite_resultset> 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<sqlite_resultset> (new sqlite_resultset (stmt));
}
#if 0
std::vector<std::string> get_table_columns (const std::string& sql)
{
char** result;
char* error_message = 0;
int nrow, ncol;
std::vector<std::string> 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

View file

@ -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