ensure all plugins report best guess at top level geometry_type using new descriptor attribute
This commit is contained in:
parent
967652efb6
commit
975afebd87
10 changed files with 301 additions and 16 deletions
|
@ -13,6 +13,7 @@
|
||||||
#include <mapnik/geometry.hpp>
|
#include <mapnik/geometry.hpp>
|
||||||
#include <mapnik/memory_featureset.hpp>
|
#include <mapnik/memory_featureset.hpp>
|
||||||
#include <mapnik/wkt/wkt_factory.hpp>
|
#include <mapnik/wkt/wkt_factory.hpp>
|
||||||
|
#include <mapnik/util/geometry_to_type_str.hpp>
|
||||||
#include <mapnik/ptree_helpers.hpp> // mapnik::boolean
|
#include <mapnik/ptree_helpers.hpp> // mapnik::boolean
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
|
@ -830,6 +831,24 @@ void csv_datasource::parse_csv(T& stream,
|
||||||
{
|
{
|
||||||
if (!quiet_) std::clog << "CSV Plugin: could not parse any lines of data\n";
|
if (!quiet_) std::clog << "CSV Plugin: could not parse any lines of data\n";
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string g_type("");
|
||||||
|
std::string prev_type("");
|
||||||
|
boost::ptr_vector<mapnik::geometry_type> paths;
|
||||||
|
unsigned num_features = features_.size();
|
||||||
|
for (int i = 0; i < num_features; ++i)
|
||||||
|
{
|
||||||
|
mapnik::util::to_type_str(features_[i]->paths(),g_type);
|
||||||
|
if (!prev_type.empty() && g_type != prev_type)
|
||||||
|
{
|
||||||
|
g_type = "collection";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev_type = g_type;
|
||||||
|
}
|
||||||
|
desc_.set_geometry_type(g_type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string csv_datasource::name()
|
std::string csv_datasource::name()
|
||||||
|
|
|
@ -212,6 +212,31 @@ void geos_datasource::bind() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get geometry type
|
||||||
|
const int type = GEOSGeomTypeId(*geometry_);
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case GEOS_POINT:
|
||||||
|
case GEOS_MULTIPOINT:
|
||||||
|
desc_.set_geometry_type("point");
|
||||||
|
break;
|
||||||
|
case GEOS_LINESTRING:
|
||||||
|
case GEOS_LINEARRING:
|
||||||
|
case GEOS_MULTILINESTRING:
|
||||||
|
desc_.set_geometry_type("linestring");
|
||||||
|
break;
|
||||||
|
case GEOS_POLYGON:
|
||||||
|
case GEOS_MULTIPOLYGON:
|
||||||
|
desc_.set_geometry_type("polygon");
|
||||||
|
break;
|
||||||
|
case GEOS_GEOMETRYCOLLECTION:
|
||||||
|
desc_.set_geometry_type("collection");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (! extent_initialized_)
|
if (! extent_initialized_)
|
||||||
{
|
{
|
||||||
throw datasource_exception("GEOS Plugin: cannot determine extent for <wkt> geometry");
|
throw datasource_exception("GEOS Plugin: cannot determine extent for <wkt> geometry");
|
||||||
|
|
|
@ -119,6 +119,8 @@ void kismet_datasource::bind() const
|
||||||
{
|
{
|
||||||
if (is_bound_) return;
|
if (is_bound_) return;
|
||||||
|
|
||||||
|
desc_.set_geometry_type("point");
|
||||||
|
|
||||||
is_bound_ = true;
|
is_bound_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ private:
|
||||||
unsigned int port_;
|
unsigned int port_;
|
||||||
int type_;
|
int type_;
|
||||||
std::string srs_;
|
std::string srs_;
|
||||||
mapnik::layer_descriptor desc_;
|
mutable mapnik::layer_descriptor desc_;
|
||||||
boost::shared_ptr<boost::thread> kismet_thread;
|
boost::shared_ptr<boost::thread> kismet_thread;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "ogr_datasource.hpp"
|
#include "ogr_datasource.hpp"
|
||||||
#include "ogr_featureset.hpp"
|
#include "ogr_featureset.hpp"
|
||||||
#include "ogr_index_featureset.hpp"
|
#include "ogr_index_featureset.hpp"
|
||||||
|
#include "ogr_feature_ptr.hpp"
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/ptree_helpers.hpp>
|
#include <mapnik/ptree_helpers.hpp>
|
||||||
|
@ -265,6 +266,70 @@ void ogr_datasource::bind() const
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// get geometry type
|
||||||
|
// NOTE: wkbFlatten macro in ogr flattens 2.5d types into base 2d type
|
||||||
|
switch (wkbFlatten(layer->GetGeomType()))
|
||||||
|
{
|
||||||
|
case wkbPoint:
|
||||||
|
case wkbMultiPoint:
|
||||||
|
desc_.set_geometry_type("point");
|
||||||
|
break;
|
||||||
|
case wkbLinearRing:
|
||||||
|
case wkbLineString:
|
||||||
|
case wkbMultiLineString:
|
||||||
|
desc_.set_geometry_type("linestring");
|
||||||
|
break;
|
||||||
|
case wkbPolygon:
|
||||||
|
case wkbMultiPolygon:
|
||||||
|
desc_.set_geometry_type("polygon");
|
||||||
|
break;
|
||||||
|
case wkbGeometryCollection:
|
||||||
|
desc_.set_geometry_type("collection");
|
||||||
|
break;
|
||||||
|
case wkbNone:
|
||||||
|
case wkbUnknown:
|
||||||
|
{
|
||||||
|
// fallback to inspecting first actual geometry
|
||||||
|
// TODO - csv and shapefile inspect first 4 features
|
||||||
|
if (dataset_ && layer_.is_valid())
|
||||||
|
{
|
||||||
|
OGRLayer* layer = layer_.layer();
|
||||||
|
ogr_feature_ptr feat(layer->GetNextFeature());
|
||||||
|
if ((*feat) != NULL)
|
||||||
|
{
|
||||||
|
OGRGeometry* geom = (*feat)->GetGeometryRef();
|
||||||
|
if (geom && ! geom->IsEmpty())
|
||||||
|
{
|
||||||
|
switch (wkbFlatten(geom->getGeometryType()))
|
||||||
|
{
|
||||||
|
case wkbPoint:
|
||||||
|
case wkbMultiPoint:
|
||||||
|
desc_.set_geometry_type("point");
|
||||||
|
break;
|
||||||
|
case wkbLinearRing:
|
||||||
|
case wkbLineString:
|
||||||
|
case wkbMultiLineString:
|
||||||
|
desc_.set_geometry_type("linestring");
|
||||||
|
break;
|
||||||
|
case wkbPolygon:
|
||||||
|
case wkbMultiPolygon:
|
||||||
|
desc_.set_geometry_type("polygon");
|
||||||
|
break;
|
||||||
|
case wkbGeometryCollection:
|
||||||
|
desc_.set_geometry_type("collection");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// deal with attributes descriptions
|
// deal with attributes descriptions
|
||||||
OGRFeatureDefn* def = layer->GetLayerDefn();
|
OGRFeatureDefn* def = layer->GetLayerDefn();
|
||||||
if (def != 0)
|
if (def != 0)
|
||||||
|
|
|
@ -123,6 +123,9 @@ void osm_datasource::bind() const
|
||||||
extent_ = box2d<double>(b.w, b.s, b.e, b.n);
|
extent_ = box2d<double>(b.w, b.s, b.e, b.n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// osm data is most likely a collection of geometry types
|
||||||
|
desc_.set_geometry_type("collection");
|
||||||
|
|
||||||
is_bound_ = true;
|
is_bound_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include <mapnik/global.hpp>
|
#include <mapnik/global.hpp>
|
||||||
#include <mapnik/ptree_helpers.hpp>
|
#include <mapnik/ptree_helpers.hpp>
|
||||||
#include <mapnik/sql_utils.hpp>
|
#include <mapnik/sql_utils.hpp>
|
||||||
|
#include <mapnik/util/geometry_to_type_str.hpp>
|
||||||
|
#include <mapnik/wkb.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
@ -106,6 +108,8 @@ void postgis_datasource::bind() const
|
||||||
ConnectionManager *mgr=ConnectionManager::instance();
|
ConnectionManager *mgr=ConnectionManager::instance();
|
||||||
mgr->registerPool(creator_, *initial_size, *max_size);
|
mgr->registerPool(creator_, *initial_size, *max_size);
|
||||||
|
|
||||||
|
std::string g_type;
|
||||||
|
|
||||||
shared_ptr<Pool<Connection,ConnectionCreator> > pool=mgr->getPool(creator_.id());
|
shared_ptr<Pool<Connection,ConnectionCreator> > pool=mgr->getPool(creator_.id());
|
||||||
if (pool)
|
if (pool)
|
||||||
{
|
{
|
||||||
|
@ -113,8 +117,6 @@ void postgis_datasource::bind() const
|
||||||
if (conn && conn->isOK())
|
if (conn && conn->isOK())
|
||||||
{
|
{
|
||||||
|
|
||||||
is_bound_ = true;
|
|
||||||
|
|
||||||
PoolGuard<shared_ptr<Connection>,
|
PoolGuard<shared_ptr<Connection>,
|
||||||
shared_ptr<Pool<Connection,ConnectionCreator> > > guard(conn,pool);
|
shared_ptr<Pool<Connection,ConnectionCreator> > > guard(conn,pool);
|
||||||
|
|
||||||
|
@ -145,7 +147,7 @@ void postgis_datasource::bind() const
|
||||||
if (!geometryColumn_.length() > 0 || srid_ == 0)
|
if (!geometryColumn_.length() > 0 || srid_ == 0)
|
||||||
{
|
{
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
s << "SELECT f_geometry_column, srid FROM ";
|
s << "SELECT f_geometry_column, srid, lower(type) as type FROM ";
|
||||||
s << GEOMETRY_COLUMNS <<" WHERE f_table_name='" << mapnik::sql_utils::unquote_double(geometry_table_) <<"'";
|
s << GEOMETRY_COLUMNS <<" WHERE f_table_name='" << mapnik::sql_utils::unquote_double(geometry_table_) <<"'";
|
||||||
|
|
||||||
if (schema_.length() > 0)
|
if (schema_.length() > 0)
|
||||||
|
@ -161,7 +163,7 @@ void postgis_datasource::bind() const
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
shared_ptr<ResultSet> rs=conn->executeQuery(s.str());
|
shared_ptr<ResultSet> rs = conn->executeQuery(s.str());
|
||||||
if (rs->next())
|
if (rs->next())
|
||||||
{
|
{
|
||||||
geometryColumn_ = rs->getValue("f_geometry_column");
|
geometryColumn_ = rs->getValue("f_geometry_column");
|
||||||
|
@ -177,6 +179,25 @@ void postgis_datasource::bind() const
|
||||||
std::clog << "Postgis Plugin: SRID=" << rs->getValue("srid") << " " << ex.what() << std::endl;
|
std::clog << "Postgis Plugin: SRID=" << rs->getValue("srid") << " " << ex.what() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_type = rs->getValue("type");
|
||||||
|
if (boost::algorithm::contains(g_type,"line"))
|
||||||
|
{
|
||||||
|
g_type = "linestring";
|
||||||
|
}
|
||||||
|
else if (boost::algorithm::contains(g_type,"point"))
|
||||||
|
{
|
||||||
|
g_type = "point";
|
||||||
|
}
|
||||||
|
else if (boost::algorithm::contains(g_type,"polygon"))
|
||||||
|
{
|
||||||
|
g_type = "polygon";
|
||||||
|
}
|
||||||
|
else // geometry
|
||||||
|
{
|
||||||
|
g_type = "collection";
|
||||||
|
}
|
||||||
|
desc_.set_geometry_type(g_type);
|
||||||
}
|
}
|
||||||
rs->close();
|
rs->close();
|
||||||
|
|
||||||
|
@ -196,7 +217,7 @@ void postgis_datasource::bind() const
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
shared_ptr<ResultSet> rs=conn->executeQuery(s.str());
|
shared_ptr<ResultSet> rs = conn->executeQuery(s.str());
|
||||||
if (rs->next())
|
if (rs->next())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -238,7 +259,7 @@ void postgis_datasource::bind() const
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
shared_ptr<ResultSet> rs=conn->executeQuery(s.str());
|
shared_ptr<ResultSet> rs = conn->executeQuery(s.str());
|
||||||
int count = rs->getNumFields();
|
int count = rs->getNumFields();
|
||||||
bool found_key_field = false;
|
bool found_key_field = false;
|
||||||
for (int i=0;i<count;++i)
|
for (int i=0;i<count;++i)
|
||||||
|
@ -326,7 +347,55 @@ void postgis_datasource::bind() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rs->close();
|
rs->close();
|
||||||
|
|
||||||
|
// fallback to querying first several features
|
||||||
|
if (g_type.empty() && !geometryColumn_.empty())
|
||||||
|
{
|
||||||
|
s.str("");
|
||||||
|
std::string g_type("");
|
||||||
|
std::string prev_type("");
|
||||||
|
s << "SELECT ST_GeometryType(\"" << geometryColumn_ << "\") AS geom"
|
||||||
|
<< " FROM " << populate_tokens(table_);
|
||||||
|
if (row_limit_ > 0 && row_limit_ < 5) {
|
||||||
|
s << " LIMIT " << row_limit_;
|
||||||
|
} else {
|
||||||
|
s << " LIMIT 5";
|
||||||
|
}
|
||||||
|
shared_ptr<ResultSet> rs = conn->executeQuery(s.str());
|
||||||
|
while (rs->next() && !rs->isNull(0))
|
||||||
|
{
|
||||||
|
const char *data = rs->getValue(0);
|
||||||
|
if (boost::algorithm::icontains(data,"line"))
|
||||||
|
{
|
||||||
|
g_type = "linestring";
|
||||||
|
}
|
||||||
|
else if (boost::algorithm::icontains(data,"point"))
|
||||||
|
{
|
||||||
|
g_type = "point";
|
||||||
|
}
|
||||||
|
else if (boost::algorithm::icontains(data,"polygon"))
|
||||||
|
{
|
||||||
|
g_type = "polygon";
|
||||||
|
}
|
||||||
|
else // geometry
|
||||||
|
{
|
||||||
|
g_type = "collection";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!prev_type.empty() && g_type != prev_type)
|
||||||
|
{
|
||||||
|
g_type = "collection";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev_type = g_type;
|
||||||
|
}
|
||||||
|
desc_.set_geometry_type(g_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
is_bound_ = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,6 +185,35 @@ void shape_datasource::init(shape_io& shape) const
|
||||||
int shape_type = shape.shp().read_ndr_integer();
|
int shape_type = shape.shp().read_ndr_integer();
|
||||||
if (shape_type == shape_io::shape_multipatch)
|
if (shape_type == shape_io::shape_multipatch)
|
||||||
throw datasource_exception("Shape Plugin: shapefile multipatch type is not supported");
|
throw datasource_exception("Shape Plugin: shapefile multipatch type is not supported");
|
||||||
|
switch (shape_type)
|
||||||
|
{
|
||||||
|
case shape_io::shape_point:
|
||||||
|
case shape_io::shape_pointm:
|
||||||
|
case shape_io::shape_pointz:
|
||||||
|
case shape_io::shape_multipoint:
|
||||||
|
case shape_io::shape_multipointm:
|
||||||
|
case shape_io::shape_multipointz:
|
||||||
|
{
|
||||||
|
desc_.set_geometry_type("point");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case shape_io::shape_polyline:
|
||||||
|
case shape_io::shape_polylinem:
|
||||||
|
case shape_io::shape_polylinez:
|
||||||
|
{
|
||||||
|
desc_.set_geometry_type("linestring");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case shape_io::shape_polygon:
|
||||||
|
case shape_io::shape_polygonm:
|
||||||
|
case shape_io::shape_polygonz:
|
||||||
|
{
|
||||||
|
desc_.set_geometry_type("polygon");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
shape.shp().read_envelope(extent_);
|
shape.shp().read_envelope(extent_);
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/ptree_helpers.hpp>
|
#include <mapnik/ptree_helpers.hpp>
|
||||||
#include <mapnik/sql_utils.hpp>
|
#include <mapnik/sql_utils.hpp>
|
||||||
|
#include <mapnik/util/geometry_to_type_str.hpp>
|
||||||
|
#include <mapnik/wkb.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
@ -69,16 +71,12 @@ sqlite_datasource::sqlite_datasource(parameters const& params, bool bind)
|
||||||
/* TODO
|
/* TODO
|
||||||
- throw if no primary key but spatial index is present?
|
- throw if no primary key but spatial index is present?
|
||||||
- remove auto-indexing
|
- remove auto-indexing
|
||||||
|
- if spatialite - leverage more of the metadata for geometry type detection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
boost::optional<std::string> file = params_.get<std::string>("file");
|
boost::optional<std::string> file = params_.get<std::string>("file");
|
||||||
if (! file) throw datasource_exception("Sqlite Plugin: missing <file> parameter");
|
if (! file) throw datasource_exception("Sqlite Plugin: missing <file> parameter");
|
||||||
|
|
||||||
if (table_.empty())
|
|
||||||
{
|
|
||||||
throw mapnik::datasource_exception("Sqlite Plugin: missing <table> parameter");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bind)
|
if (bind)
|
||||||
{
|
{
|
||||||
this->bind();
|
this->bind();
|
||||||
|
@ -147,6 +145,44 @@ void sqlite_datasource::bind() const
|
||||||
init_statements_.push_back(*initdb);
|
init_statements_.push_back(*initdb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// now actually create the connection and start executing setup sql
|
||||||
|
dataset_ = boost::make_shared<sqlite_connection>(dataset_name_);
|
||||||
|
|
||||||
|
boost::optional<unsigned> table_by_index = params_.get<unsigned>("table_by_index");
|
||||||
|
|
||||||
|
int passed_parameters = 0;
|
||||||
|
passed_parameters += params_.get<std::string>("table") ? 1 : 0;
|
||||||
|
passed_parameters += table_by_index ? 1 : 0;
|
||||||
|
|
||||||
|
if (passed_parameters > 1)
|
||||||
|
{
|
||||||
|
throw datasource_exception("SQLite Plugin: you can only select an by name "
|
||||||
|
"('table' parameter), by number ('table_by_index' parameter), "
|
||||||
|
"do not supply 2 or more of them at the same time" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (table_by_index)
|
||||||
|
{
|
||||||
|
std::vector<std::string> tables;
|
||||||
|
sqlite_utils::get_tables(dataset_,tables);
|
||||||
|
if (*table_by_index >= tables.size())
|
||||||
|
{
|
||||||
|
std::ostringstream s;
|
||||||
|
s << "SQLite Plugin: only "
|
||||||
|
<< tables.size()
|
||||||
|
<< " table(s) exist, cannot find table by index '" << *table_by_index << "'";
|
||||||
|
|
||||||
|
throw datasource_exception(s.str());
|
||||||
|
}
|
||||||
|
table_ = tables[*table_by_index];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (table_.empty())
|
||||||
|
{
|
||||||
|
throw mapnik::datasource_exception("Sqlite Plugin: missing <table> parameter");
|
||||||
|
}
|
||||||
|
|
||||||
if (geometry_table_.empty())
|
if (geometry_table_.empty())
|
||||||
{
|
{
|
||||||
geometry_table_ = mapnik::sql_utils::table_from_sql(table_);
|
geometry_table_ = mapnik::sql_utils::table_from_sql(table_);
|
||||||
|
@ -169,9 +205,6 @@ void sqlite_datasource::bind() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// now actually create the connection and start executing setup sql
|
|
||||||
dataset_ = boost::make_shared<sqlite_connection>(dataset_name_);
|
|
||||||
|
|
||||||
// Execute init_statements_
|
// Execute init_statements_
|
||||||
for (std::vector<std::string>::const_iterator iter = init_statements_.begin();
|
for (std::vector<std::string>::const_iterator iter = init_statements_.begin();
|
||||||
iter != init_statements_.end(); ++iter)
|
iter != init_statements_.end(); ++iter)
|
||||||
|
@ -188,7 +221,11 @@ void sqlite_datasource::bind() const
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
std::string query = populate_tokens(table_);
|
std::string query = populate_tokens(table_);
|
||||||
s << "SELECT " << fields_ << " FROM (" << query << ") LIMIT 1";
|
s << "SELECT " << fields_ << " FROM (" << query << ") LIMIT 1";
|
||||||
found_types_via_subquery = sqlite_utils::detect_types_from_subquery(s.str(),geometry_field_,desc_,dataset_);
|
found_types_via_subquery = sqlite_utils::detect_types_from_subquery(
|
||||||
|
s.str(),
|
||||||
|
geometry_field_,
|
||||||
|
desc_,
|
||||||
|
dataset_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - consider removing this
|
// TODO - consider removing this
|
||||||
|
@ -328,6 +365,38 @@ void sqlite_datasource::bind() const
|
||||||
throw datasource_exception(s.str());
|
throw datasource_exception(s.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// finally, get geometry type by querying first feature
|
||||||
|
std::ostringstream s;
|
||||||
|
std::string g_type("");
|
||||||
|
std::string prev_type("");
|
||||||
|
boost::ptr_vector<mapnik::geometry_type> paths;
|
||||||
|
|
||||||
|
s << "SELECT " << geometry_field_ << " FROM " << geometry_table_;
|
||||||
|
if (row_limit_ > 0 && row_limit_ < 5) {
|
||||||
|
s << " LIMIT " << row_limit_;
|
||||||
|
} else {
|
||||||
|
s << " LIMIT 5";
|
||||||
|
}
|
||||||
|
boost::shared_ptr<sqlite_resultset> rs = dataset_->execute_query(s.str());
|
||||||
|
while (rs->is_valid() && rs->step_next())
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
const char* data = (const char*) rs->column_blob(0, size);
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
mapnik::geometry_utils::from_wkb(paths, data, size, mapnik::wkbAuto);
|
||||||
|
mapnik::util::to_type_str(paths,g_type);
|
||||||
|
if (!prev_type.empty() && g_type != prev_type)
|
||||||
|
{
|
||||||
|
g_type = "collection";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev_type = g_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
desc_.set_geometry_type(g_type);
|
||||||
|
|
||||||
is_bound_ = true;
|
is_bound_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,10 @@ void hello_datasource::bind() const
|
||||||
// see http://spatialreference.org/ref/epsg/4326/ for more details
|
// see http://spatialreference.org/ref/epsg/4326/ for more details
|
||||||
extent_.init(-180,-90,180,90);
|
extent_.init(-180,-90,180,90);
|
||||||
|
|
||||||
|
// declare that this datasource is going to provide points
|
||||||
|
// options are point,polygon,linestring, and collection
|
||||||
|
desc_.set_geometry_type("point");
|
||||||
|
|
||||||
is_bound_ = true;
|
is_bound_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue