Merge pull request #1021 from mapnik/geometry_type_descriptor
Add Geometry type descriptor
This commit is contained in:
commit
9407991be4
47 changed files with 4919 additions and 160 deletions
|
@ -233,9 +233,6 @@ class _Projection(Projection,_injector):
|
||||||
|
|
||||||
class _Datasource(Datasource,_injector):
|
class _Datasource(Datasource,_injector):
|
||||||
|
|
||||||
def describe(self):
|
|
||||||
return Describe(self)
|
|
||||||
|
|
||||||
def all_features(self,fields=None):
|
def all_features(self,fields=None):
|
||||||
query = Query(self.envelope())
|
query = Query(self.envelope())
|
||||||
attributes = fields or self.fields()
|
attributes = fields or self.fields()
|
||||||
|
@ -710,7 +707,6 @@ __all__ = [
|
||||||
'SQLite',
|
'SQLite',
|
||||||
'Osm',
|
'Osm',
|
||||||
'Kismet',
|
'Kismet',
|
||||||
'Describe',
|
|
||||||
# version and environment
|
# version and environment
|
||||||
'mapnik_version_string',
|
'mapnik_version_string',
|
||||||
'mapnik_version',
|
'mapnik_version',
|
||||||
|
|
|
@ -82,30 +82,15 @@ boost::shared_ptr<mapnik::datasource> create_datasource(const dict& d)
|
||||||
return mapnik::datasource_cache::create(params, bind);
|
return mapnik::datasource_cache::create(params, bind);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string describe(boost::shared_ptr<mapnik::datasource> const& ds)
|
boost::python::dict describe(boost::shared_ptr<mapnik::datasource> const& ds)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
boost::python::dict description;
|
||||||
if (ds)
|
mapnik::layer_descriptor ld = ds->get_descriptor();
|
||||||
{
|
description["type"] = ds->type();
|
||||||
ss << ds->get_descriptor() << "\n";
|
description["name"] = ld.get_name();
|
||||||
}
|
description["geometry_type"] = ds->get_geometry_type();
|
||||||
else
|
description["encoding"] = ld.get_encoding();
|
||||||
{
|
return description;
|
||||||
ss << "Null\n";
|
|
||||||
}
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string encoding(boost::shared_ptr<mapnik::datasource> const& ds)
|
|
||||||
{
|
|
||||||
layer_descriptor ld = ds->get_descriptor();
|
|
||||||
return ld.get_encoding();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name(boost::shared_ptr<mapnik::datasource> const& ds)
|
|
||||||
{
|
|
||||||
layer_descriptor ld = ds->get_descriptor();
|
|
||||||
return ld.get_name();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::python::list fields(boost::shared_ptr<mapnik::datasource> const& ds)
|
boost::python::list fields(boost::shared_ptr<mapnik::datasource> const& ds)
|
||||||
|
@ -163,23 +148,34 @@ void export_datasource()
|
||||||
{
|
{
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
|
|
||||||
|
enum_<mapnik::datasource::datasource_t>("DataType")
|
||||||
|
.value("Vector",mapnik::datasource::Vector)
|
||||||
|
.value("Raster",mapnik::datasource::Raster)
|
||||||
|
;
|
||||||
|
|
||||||
|
enum_<mapnik::datasource::geometry_t>("DataGeometryType")
|
||||||
|
.value("Point",mapnik::datasource::Point)
|
||||||
|
.value("LineString",mapnik::datasource::LineString)
|
||||||
|
.value("Polygon",mapnik::datasource::Polygon)
|
||||||
|
.value("Collection",mapnik::datasource::Collection)
|
||||||
|
;
|
||||||
|
|
||||||
class_<datasource,boost::shared_ptr<datasource>,
|
class_<datasource,boost::shared_ptr<datasource>,
|
||||||
boost::noncopyable>("Datasource",no_init)
|
boost::noncopyable>("Datasource",no_init)
|
||||||
|
.def("type",&datasource::type)
|
||||||
|
.def("geometry_type",&datasource::get_geometry_type)
|
||||||
|
.def("describe",&describe)
|
||||||
.def("envelope",&datasource::envelope)
|
.def("envelope",&datasource::envelope)
|
||||||
.def("descriptor",&datasource::get_descriptor) //todo
|
|
||||||
.def("features",&datasource::features)
|
.def("features",&datasource::features)
|
||||||
.def("bind",&datasource::bind)
|
.def("bind",&datasource::bind)
|
||||||
.def("fields",&fields)
|
.def("fields",&fields)
|
||||||
.def("field_types",&field_types)
|
.def("field_types",&field_types)
|
||||||
.def("encoding",&encoding) //todo expose as property
|
|
||||||
.def("name",&name)
|
|
||||||
.def("features_at_point",&datasource::features_at_point)
|
.def("features_at_point",&datasource::features_at_point)
|
||||||
.def("params",&datasource::params,return_value_policy<copy_const_reference>(),
|
.def("params",&datasource::params,return_value_policy<copy_const_reference>(),
|
||||||
"The configuration parameters of the data source. "
|
"The configuration parameters of the data source. "
|
||||||
"These vary depending on the type of data source.")
|
"These vary depending on the type of data source.")
|
||||||
;
|
;
|
||||||
|
|
||||||
def("Describe",&describe);
|
|
||||||
def("CreateDatasource",&create_datasource);
|
def("CreateDatasource",&create_datasource);
|
||||||
|
|
||||||
class_<point_datasource, bases<datasource>, boost::noncopyable>("PointDatasource", init<>())
|
class_<point_datasource, bases<datasource>, boost::noncopyable>("PointDatasource", init<>())
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
#include <mapnik/metawriter_inmem.hpp>
|
#include <mapnik/metawriter_inmem.hpp>
|
||||||
#include <mapnik/util/deepcopy.hpp>
|
#include <mapnik/util/deepcopy.hpp>
|
||||||
#include "mapnik_enumeration.hpp"
|
#include "mapnik_enumeration.hpp"
|
||||||
#include "python_optional.hpp"
|
|
||||||
|
|
||||||
using mapnik::color;
|
using mapnik::color;
|
||||||
using mapnik::coord;
|
using mapnik::coord;
|
||||||
|
@ -213,8 +212,6 @@ void export_map()
|
||||||
.value("ADJUST_CANVAS_HEIGHT", mapnik::Map::ADJUST_CANVAS_HEIGHT)
|
.value("ADJUST_CANVAS_HEIGHT", mapnik::Map::ADJUST_CANVAS_HEIGHT)
|
||||||
;
|
;
|
||||||
|
|
||||||
python_optional<mapnik::color> ();
|
|
||||||
python_optional<mapnik::box2d<double> > ();
|
|
||||||
class_<std::vector<layer> >("Layers")
|
class_<std::vector<layer> >("Layers")
|
||||||
.def(vector_indexing_suite<std::vector<layer> >())
|
.def(vector_indexing_suite<std::vector<layer> >())
|
||||||
;
|
;
|
||||||
|
|
|
@ -85,6 +85,7 @@ void export_label_collision_detector();
|
||||||
#include <mapnik/save_map.hpp>
|
#include <mapnik/save_map.hpp>
|
||||||
#include "python_grid_utils.hpp"
|
#include "python_grid_utils.hpp"
|
||||||
#include "mapnik_value_converter.hpp"
|
#include "mapnik_value_converter.hpp"
|
||||||
|
#include "python_optional.hpp"
|
||||||
|
|
||||||
#if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)
|
#if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)
|
||||||
#include <pycairo.h>
|
#include <pycairo.h>
|
||||||
|
@ -630,6 +631,9 @@ BOOST_PYTHON_MODULE(_mapnik)
|
||||||
def("has_cairo", &has_cairo, "Get cairo library status");
|
def("has_cairo", &has_cairo, "Get cairo library status");
|
||||||
def("has_pycairo", &has_pycairo, "Get pycairo module status");
|
def("has_pycairo", &has_pycairo, "Get pycairo module status");
|
||||||
|
|
||||||
|
python_optional<mapnik::color> ();
|
||||||
|
python_optional<mapnik::box2d<double> > ();
|
||||||
|
python_optional<mapnik::datasource::geometry_t> ();
|
||||||
register_ptr_to_python<mapnik::expression_ptr>();
|
register_ptr_to_python<mapnik::expression_ptr>();
|
||||||
register_ptr_to_python<mapnik::path_expression_ptr>();
|
register_ptr_to_python<mapnik::path_expression_ptr>();
|
||||||
to_python_converter<mapnik::value_holder,mapnik_param_to_python>();
|
to_python_converter<mapnik::value_holder,mapnik_param_to_python>();
|
||||||
|
|
|
@ -74,6 +74,13 @@ public:
|
||||||
Raster
|
Raster
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum geometry_t {
|
||||||
|
Point = 1,
|
||||||
|
LineString = 2,
|
||||||
|
Polygon = 3,
|
||||||
|
Collection = 4
|
||||||
|
};
|
||||||
|
|
||||||
datasource (parameters const& params)
|
datasource (parameters const& params)
|
||||||
: params_(params),
|
: params_(params),
|
||||||
is_bound_(false)
|
is_bound_(false)
|
||||||
|
@ -95,7 +102,7 @@ public:
|
||||||
* @brief Get the type of the datasource
|
* @brief Get the type of the datasource
|
||||||
* @return The type of the datasource (Vector or Raster)
|
* @return The type of the datasource (Vector or Raster)
|
||||||
*/
|
*/
|
||||||
virtual int type() const=0;
|
virtual datasource_t type() const=0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Connect to the datasource
|
* @brief Connect to the datasource
|
||||||
|
@ -105,6 +112,7 @@ public:
|
||||||
virtual featureset_ptr features(const query& q) const=0;
|
virtual featureset_ptr features(const query& q) const=0;
|
||||||
virtual featureset_ptr features_at_point(coord2d const& pt) const=0;
|
virtual featureset_ptr features_at_point(coord2d const& pt) const=0;
|
||||||
virtual box2d<double> envelope() const=0;
|
virtual box2d<double> envelope() const=0;
|
||||||
|
virtual boost::optional<geometry_t> get_geometry_type() const=0;
|
||||||
virtual layer_descriptor get_descriptor() const=0;
|
virtual layer_descriptor get_descriptor() const=0;
|
||||||
virtual ~datasource() {};
|
virtual ~datasource() {};
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -92,14 +92,13 @@ inline std::basic_ostream<charT,traits>&
|
||||||
operator << (std::basic_ostream<charT,traits>& out,
|
operator << (std::basic_ostream<charT,traits>& out,
|
||||||
layer_descriptor const& ld)
|
layer_descriptor const& ld)
|
||||||
{
|
{
|
||||||
out << "name=" << ld.get_name() << "\n";
|
out << "name: " << ld.get_name() << "\n";
|
||||||
out << "encoding=" << ld.get_encoding() << "\n";
|
out << "encoding: " << ld.get_encoding() << "\n";
|
||||||
std::vector<attribute_descriptor> const& desc_ar = ld.get_descriptors();
|
std::vector<attribute_descriptor> const& desc_ar = ld.get_descriptors();
|
||||||
std::vector<attribute_descriptor>::const_iterator pos = desc_ar.begin();
|
std::vector<attribute_descriptor>::const_iterator pos = desc_ar.begin();
|
||||||
while (pos != desc_ar.end())
|
while (pos != desc_ar.end())
|
||||||
{
|
{
|
||||||
out << *pos++ << "\n";
|
out << *pos++ << "\n";
|
||||||
|
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,10 +39,11 @@ public:
|
||||||
memory_datasource();
|
memory_datasource();
|
||||||
virtual ~memory_datasource();
|
virtual ~memory_datasource();
|
||||||
void push(feature_ptr feature);
|
void push(feature_ptr feature);
|
||||||
int type() const;
|
datasource::datasource_t type() const;
|
||||||
featureset_ptr features(const query& q) const;
|
featureset_ptr features(const query& q) const;
|
||||||
featureset_ptr features_at_point(coord2d const& pt) const;
|
featureset_ptr features_at_point(coord2d const& pt) const;
|
||||||
box2d<double> envelope() const;
|
box2d<double> envelope() const;
|
||||||
|
boost::optional<geometry_t> get_geometry_type() const;
|
||||||
layer_descriptor get_descriptor() const;
|
layer_descriptor get_descriptor() const;
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -60,7 +61,6 @@ public:
|
||||||
point_datasource() :
|
point_datasource() :
|
||||||
feature_id_(1) {}
|
feature_id_(1) {}
|
||||||
void add_point(double x, double y, const char* key, const char* value);
|
void add_point(double x, double y, const char* key, const char* value);
|
||||||
inline int type() const { return datasource::Vector; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int feature_id_;
|
int feature_id_;
|
||||||
|
|
|
@ -39,8 +39,8 @@
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
typedef boost::variant<value_null,int,double,std::string> value_holder;
|
typedef boost::variant<value_null,int,double,std::string> value_holder;
|
||||||
typedef std::pair<const std::string, value_holder> parameter;
|
typedef std::pair<std::string, value_holder> parameter;
|
||||||
typedef std::map<const std::string, value_holder> param_map;
|
typedef std::map<std::string, value_holder> param_map;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct value_extractor_visitor : public boost::static_visitor<>
|
struct value_extractor_visitor : public boost::static_visitor<>
|
||||||
|
|
66
include/mapnik/util/geometry_to_ds_type.hpp
Normal file
66
include/mapnik/util/geometry_to_ds_type.hpp
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 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 MAPNIK_GEOMETRY_TO_DS_TYPE
|
||||||
|
#define MAPNIK_GEOMETRY_TO_DS_TYPE
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/global.hpp>
|
||||||
|
#include <mapnik/geometry.hpp>
|
||||||
|
#include <mapnik/datasource.hpp>
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
namespace mapnik { namespace util {
|
||||||
|
|
||||||
|
void to_ds_type(mapnik::geometry_container const& paths,
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> & result)
|
||||||
|
{
|
||||||
|
if (paths.size() == 1)
|
||||||
|
{
|
||||||
|
result.reset(static_cast<mapnik::datasource::geometry_t>(paths.front().type()));
|
||||||
|
}
|
||||||
|
else if (paths.size() > 1)
|
||||||
|
{
|
||||||
|
int multi_type = 0;
|
||||||
|
geometry_container::const_iterator itr = paths.begin();
|
||||||
|
geometry_container::const_iterator end = paths.end();
|
||||||
|
for ( ; itr!=end; ++itr)
|
||||||
|
{
|
||||||
|
int type = static_cast<int>(itr->type());
|
||||||
|
if (multi_type > 0 && multi_type != type)
|
||||||
|
{
|
||||||
|
result.reset(datasource::Collection);
|
||||||
|
}
|
||||||
|
multi_type = type;
|
||||||
|
result.reset(static_cast<mapnik::datasource::geometry_t>(type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // MAPNIK_GEOMETRY_TO_DS_TYPE
|
|
@ -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_ds_type.hpp>
|
||||||
#include <mapnik/ptree_helpers.hpp> // mapnik::boolean
|
#include <mapnik/ptree_helpers.hpp> // mapnik::boolean
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
|
@ -837,7 +838,7 @@ std::string csv_datasource::name()
|
||||||
return "csv";
|
return "csv";
|
||||||
}
|
}
|
||||||
|
|
||||||
int csv_datasource::type() const
|
datasource::datasource_t csv_datasource::type() const
|
||||||
{
|
{
|
||||||
return datasource::Vector;
|
return datasource::Vector;
|
||||||
}
|
}
|
||||||
|
@ -849,6 +850,29 @@ mapnik::box2d<double> csv_datasource::envelope() const
|
||||||
return extent_;
|
return extent_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> csv_datasource::get_geometry_type() const
|
||||||
|
{
|
||||||
|
if (! is_bound_) bind();
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> result;
|
||||||
|
int multi_type = 0;
|
||||||
|
unsigned num_features = features_.size();
|
||||||
|
for (int i = 0; i < num_features && i < 5; ++i)
|
||||||
|
{
|
||||||
|
mapnik::util::to_ds_type(features_[i]->paths(),result);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
int type = static_cast<int>(*result);
|
||||||
|
if (multi_type > 0 && multi_type != type)
|
||||||
|
{
|
||||||
|
result.reset(mapnik::datasource::Collection);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
multi_type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
mapnik::layer_descriptor csv_datasource::get_descriptor() const
|
mapnik::layer_descriptor csv_datasource::get_descriptor() const
|
||||||
{
|
{
|
||||||
if (!is_bound_) bind();
|
if (!is_bound_) bind();
|
||||||
|
|
|
@ -12,11 +12,12 @@ class csv_datasource : public mapnik::datasource
|
||||||
public:
|
public:
|
||||||
csv_datasource(mapnik::parameters const& params, bool bind=true);
|
csv_datasource(mapnik::parameters const& params, bool bind=true);
|
||||||
virtual ~csv_datasource ();
|
virtual ~csv_datasource ();
|
||||||
int type() const;
|
mapnik::datasource::datasource_t type() const;
|
||||||
static std::string name();
|
static std::string name();
|
||||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||||
mapnik::box2d<double> envelope() const;
|
mapnik::box2d<double> envelope() const;
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||||
mapnik::layer_descriptor get_descriptor() const;
|
mapnik::layer_descriptor get_descriptor() const;
|
||||||
void bind() const;
|
void bind() const;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -197,7 +197,7 @@ gdal_datasource::~gdal_datasource()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int gdal_datasource::type() const
|
datasource::datasource_t gdal_datasource::type() const
|
||||||
{
|
{
|
||||||
return datasource::Raster;
|
return datasource::Raster;
|
||||||
}
|
}
|
||||||
|
@ -214,6 +214,11 @@ box2d<double> gdal_datasource::envelope() const
|
||||||
return extent_;
|
return extent_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> gdal_datasource::get_geometry_type() const
|
||||||
|
{
|
||||||
|
return boost::optional<mapnik::datasource::geometry_t>();
|
||||||
|
}
|
||||||
|
|
||||||
layer_descriptor gdal_datasource::get_descriptor() const
|
layer_descriptor gdal_datasource::get_descriptor() const
|
||||||
{
|
{
|
||||||
return desc_;
|
return desc_;
|
||||||
|
|
|
@ -37,11 +37,12 @@ class gdal_datasource : public mapnik::datasource
|
||||||
public:
|
public:
|
||||||
gdal_datasource(mapnik::parameters const& params, bool bind = true);
|
gdal_datasource(mapnik::parameters const& params, bool bind = true);
|
||||||
virtual ~gdal_datasource();
|
virtual ~gdal_datasource();
|
||||||
int type() const;
|
mapnik::datasource::datasource_t type() const;
|
||||||
static std::string name();
|
static std::string name();
|
||||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||||
mapnik::box2d<double> envelope() const;
|
mapnik::box2d<double> envelope() const;
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||||
mapnik::layer_descriptor get_descriptor() const;
|
mapnik::layer_descriptor get_descriptor() const;
|
||||||
void bind() const;
|
void bind() const;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -225,7 +225,7 @@ std::string geos_datasource::name()
|
||||||
return "geos";
|
return "geos";
|
||||||
}
|
}
|
||||||
|
|
||||||
int geos_datasource::type() const
|
mapnik::datasource::datasource_t geos_datasource::type() const
|
||||||
{
|
{
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
@ -237,6 +237,38 @@ box2d<double> geos_datasource::envelope() const
|
||||||
return extent_;
|
return extent_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> geos_datasource::get_geometry_type() const
|
||||||
|
{
|
||||||
|
if (! is_bound_) bind();
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> result;
|
||||||
|
|
||||||
|
// get geometry type
|
||||||
|
const int type = GEOSGeomTypeId(*geometry_);
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case GEOS_POINT:
|
||||||
|
case GEOS_MULTIPOINT:
|
||||||
|
result.reset(mapnik::datasource::Point);
|
||||||
|
break;
|
||||||
|
case GEOS_LINESTRING:
|
||||||
|
case GEOS_LINEARRING:
|
||||||
|
case GEOS_MULTILINESTRING:
|
||||||
|
result.reset(mapnik::datasource::LineString);
|
||||||
|
break;
|
||||||
|
case GEOS_POLYGON:
|
||||||
|
case GEOS_MULTIPOLYGON:
|
||||||
|
result.reset(mapnik::datasource::Polygon);
|
||||||
|
break;
|
||||||
|
case GEOS_GEOMETRYCOLLECTION:
|
||||||
|
result.reset(mapnik::datasource::Collection);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
layer_descriptor geos_datasource::get_descriptor() const
|
layer_descriptor geos_datasource::get_descriptor() const
|
||||||
{
|
{
|
||||||
if (! is_bound_) bind();
|
if (! is_bound_) bind();
|
||||||
|
|
|
@ -38,18 +38,19 @@ class geos_datasource : public mapnik::datasource
|
||||||
public:
|
public:
|
||||||
geos_datasource(mapnik::parameters const& params, bool bind = true);
|
geos_datasource(mapnik::parameters const& params, bool bind = true);
|
||||||
virtual ~geos_datasource ();
|
virtual ~geos_datasource ();
|
||||||
int type() const;
|
mapnik::datasource::datasource_t type() const;
|
||||||
static std::string name();
|
static std::string name();
|
||||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||||
mapnik::box2d<double> envelope() const;
|
mapnik::box2d<double> envelope() const;
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||||
mapnik::layer_descriptor get_descriptor() const;
|
mapnik::layer_descriptor get_descriptor() const;
|
||||||
void bind() const;
|
void bind() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable mapnik::box2d<double> extent_;
|
mutable mapnik::box2d<double> extent_;
|
||||||
mutable bool extent_initialized_;
|
mutable bool extent_initialized_;
|
||||||
int type_;
|
mapnik::datasource::datasource_t type_;
|
||||||
mutable mapnik::layer_descriptor desc_;
|
mutable mapnik::layer_descriptor desc_;
|
||||||
mutable geos_feature_ptr geometry_;
|
mutable geos_feature_ptr geometry_;
|
||||||
mutable std::string geometry_data_;
|
mutable std::string geometry_data_;
|
||||||
|
|
|
@ -131,7 +131,7 @@ std::string kismet_datasource::name()
|
||||||
return "kismet";
|
return "kismet";
|
||||||
}
|
}
|
||||||
|
|
||||||
int kismet_datasource::type() const
|
mapnik::datasource::datasource_t kismet_datasource::type() const
|
||||||
{
|
{
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
@ -142,6 +142,11 @@ box2d<double> kismet_datasource::envelope() const
|
||||||
return extent_;
|
return extent_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> kismet_datasource::get_geometry_type() const
|
||||||
|
{
|
||||||
|
return boost::optional<mapnik::datasource::geometry_t>(mapnik::datasource::Point);
|
||||||
|
}
|
||||||
|
|
||||||
layer_descriptor kismet_datasource::get_descriptor() const
|
layer_descriptor kismet_datasource::get_descriptor() const
|
||||||
{
|
{
|
||||||
return desc_;
|
return desc_;
|
||||||
|
|
|
@ -45,11 +45,12 @@ class kismet_datasource : public mapnik::datasource
|
||||||
public:
|
public:
|
||||||
kismet_datasource(mapnik::parameters const& params, bool bind = true);
|
kismet_datasource(mapnik::parameters const& params, bool bind = true);
|
||||||
virtual ~kismet_datasource ();
|
virtual ~kismet_datasource ();
|
||||||
int type() const;
|
datasource::datasource_t type() const;
|
||||||
static std::string name();
|
static std::string name();
|
||||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||||
mapnik::box2d<double> envelope() const;
|
mapnik::box2d<double> envelope() const;
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||||
mapnik::layer_descriptor get_descriptor() const;
|
mapnik::layer_descriptor get_descriptor() const;
|
||||||
void bind() const;
|
void bind() const;
|
||||||
|
|
||||||
|
@ -60,9 +61,9 @@ private:
|
||||||
bool extent_initialized_;
|
bool extent_initialized_;
|
||||||
std::string host_;
|
std::string host_;
|
||||||
unsigned int port_;
|
unsigned int port_;
|
||||||
int type_;
|
mapnik::datasource::datasource_t 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -351,7 +351,7 @@ std::string occi_datasource::name()
|
||||||
return "occi";
|
return "occi";
|
||||||
}
|
}
|
||||||
|
|
||||||
int occi_datasource::type() const
|
mapnik::datasource::datasource_t occi_datasource::type() const
|
||||||
{
|
{
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
@ -474,6 +474,14 @@ box2d<double> occi_datasource::envelope() const
|
||||||
return extent_;
|
return extent_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> occi_datasource::get_geometry_type() const
|
||||||
|
{
|
||||||
|
// FIXME
|
||||||
|
//if (! is_bound_) bind();
|
||||||
|
return boost::optional<mapnik::datasource::geometry_t>();
|
||||||
|
}
|
||||||
|
|
||||||
layer_descriptor occi_datasource::get_descriptor() const
|
layer_descriptor occi_datasource::get_descriptor() const
|
||||||
{
|
{
|
||||||
if (! is_bound_) bind();
|
if (! is_bound_) bind();
|
||||||
|
|
|
@ -40,16 +40,17 @@ class occi_datasource : public mapnik::datasource
|
||||||
public:
|
public:
|
||||||
occi_datasource(mapnik::parameters const& params, bool bind = true);
|
occi_datasource(mapnik::parameters const& params, bool bind = true);
|
||||||
virtual ~occi_datasource ();
|
virtual ~occi_datasource ();
|
||||||
int type() const;
|
mapnik::datasource::datasource_t type() const;
|
||||||
static std::string name();
|
static std::string name();
|
||||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||||
mapnik::box2d<double> envelope() const;
|
mapnik::box2d<double> envelope() const;
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||||
mapnik::layer_descriptor get_descriptor() const;
|
mapnik::layer_descriptor get_descriptor() const;
|
||||||
void bind() const;
|
void bind() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int type_;
|
mapnik::datasource::datasource_t type_;
|
||||||
mutable std::string table_;
|
mutable std::string table_;
|
||||||
mutable std::string table_name_;
|
mutable std::string table_name_;
|
||||||
mutable std::string fields_;
|
mutable std::string fields_;
|
||||||
|
|
|
@ -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>
|
||||||
|
@ -331,7 +332,7 @@ std::string ogr_datasource::name()
|
||||||
return "ogr";
|
return "ogr";
|
||||||
}
|
}
|
||||||
|
|
||||||
int ogr_datasource::type() const
|
mapnik::datasource::datasource_t ogr_datasource::type() const
|
||||||
{
|
{
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
@ -342,6 +343,79 @@ box2d<double> ogr_datasource::envelope() const
|
||||||
return extent_;
|
return extent_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> ogr_datasource::get_geometry_type() const
|
||||||
|
{
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> result;
|
||||||
|
if (dataset_ && layer_.is_valid())
|
||||||
|
{
|
||||||
|
OGRLayer* layer = layer_.layer();
|
||||||
|
// NOTE: wkbFlatten macro in ogr flattens 2.5d types into base 2d type
|
||||||
|
switch (wkbFlatten(layer->GetGeomType()))
|
||||||
|
{
|
||||||
|
case wkbPoint:
|
||||||
|
case wkbMultiPoint:
|
||||||
|
result.reset(mapnik::datasource::Point);
|
||||||
|
break;
|
||||||
|
case wkbLinearRing:
|
||||||
|
case wkbLineString:
|
||||||
|
case wkbMultiLineString:
|
||||||
|
result.reset(mapnik::datasource::LineString);
|
||||||
|
break;
|
||||||
|
case wkbPolygon:
|
||||||
|
case wkbMultiPolygon:
|
||||||
|
result.reset(mapnik::datasource::Polygon);
|
||||||
|
break;
|
||||||
|
case wkbGeometryCollection:
|
||||||
|
result.reset(mapnik::datasource::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:
|
||||||
|
result.reset(mapnik::datasource::Point);
|
||||||
|
break;
|
||||||
|
case wkbLinearRing:
|
||||||
|
case wkbLineString:
|
||||||
|
case wkbMultiLineString:
|
||||||
|
result.reset(mapnik::datasource::LineString);
|
||||||
|
break;
|
||||||
|
case wkbPolygon:
|
||||||
|
case wkbMultiPolygon:
|
||||||
|
result.reset(mapnik::datasource::Polygon);
|
||||||
|
break;
|
||||||
|
case wkbGeometryCollection:
|
||||||
|
result.reset(mapnik::datasource::Collection);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
layer_descriptor ogr_datasource::get_descriptor() const
|
layer_descriptor ogr_datasource::get_descriptor() const
|
||||||
{
|
{
|
||||||
if (! is_bound_) bind();
|
if (! is_bound_) bind();
|
||||||
|
|
|
@ -41,17 +41,18 @@ class ogr_datasource : public mapnik::datasource
|
||||||
public:
|
public:
|
||||||
ogr_datasource(mapnik::parameters const& params, bool bind=true);
|
ogr_datasource(mapnik::parameters const& params, bool bind=true);
|
||||||
virtual ~ogr_datasource ();
|
virtual ~ogr_datasource ();
|
||||||
int type() const;
|
mapnik::datasource::datasource_t type() const;
|
||||||
static std::string name();
|
static std::string name();
|
||||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||||
mapnik::box2d<double> envelope() const;
|
mapnik::box2d<double> envelope() const;
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||||
mapnik::layer_descriptor get_descriptor() const;
|
mapnik::layer_descriptor get_descriptor() const;
|
||||||
void bind() const;
|
void bind() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable mapnik::box2d<double> extent_;
|
mutable mapnik::box2d<double> extent_;
|
||||||
int type_;
|
mapnik::datasource::datasource_t type_;
|
||||||
std::string dataset_name_;
|
std::string dataset_name_;
|
||||||
mutable std::string index_name_;
|
mutable std::string index_name_;
|
||||||
mutable OGRDataSource* dataset_;
|
mutable OGRDataSource* dataset_;
|
||||||
|
|
|
@ -137,7 +137,7 @@ std::string osm_datasource::name()
|
||||||
return "osm";
|
return "osm";
|
||||||
}
|
}
|
||||||
|
|
||||||
int osm_datasource::type() const
|
mapnik::datasource::datasource_t osm_datasource::type() const
|
||||||
{
|
{
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
@ -189,3 +189,9 @@ box2d<double> osm_datasource::envelope() const
|
||||||
|
|
||||||
return extent_;
|
return extent_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> osm_datasource::get_geometry_type() const
|
||||||
|
{
|
||||||
|
if (! is_bound_) bind();
|
||||||
|
return boost::optional<mapnik::datasource::geometry_t>(mapnik::datasource::Collection);
|
||||||
|
}
|
|
@ -42,17 +42,18 @@ class osm_datasource : public datasource
|
||||||
public:
|
public:
|
||||||
osm_datasource(const parameters& params, bool bind = true);
|
osm_datasource(const parameters& params, bool bind = true);
|
||||||
virtual ~osm_datasource();
|
virtual ~osm_datasource();
|
||||||
int type() const;
|
mapnik::datasource::datasource_t type() const;
|
||||||
featureset_ptr features(const query& q) const;
|
featureset_ptr features(const query& q) const;
|
||||||
featureset_ptr features_at_point(coord2d const& pt) const;
|
featureset_ptr features_at_point(coord2d const& pt) const;
|
||||||
box2d<double> envelope() const;
|
box2d<double> envelope() const;
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||||
layer_descriptor get_descriptor() const;
|
layer_descriptor get_descriptor() const;
|
||||||
static std::string name();
|
static std::string name();
|
||||||
void bind() const;
|
void bind() const;
|
||||||
private:
|
private:
|
||||||
mutable box2d<double> extent_;
|
mutable box2d<double> extent_;
|
||||||
mutable osm_dataset* osm_data_;
|
mutable osm_dataset* osm_data_;
|
||||||
int type_;
|
mapnik::datasource::datasource_t type_;
|
||||||
mutable layer_descriptor desc_;
|
mutable layer_descriptor desc_;
|
||||||
// no copying
|
// no copying
|
||||||
osm_datasource(const osm_datasource&);
|
osm_datasource(const osm_datasource&);
|
||||||
|
|
|
@ -106,6 +106,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 +115,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,14 +145,20 @@ 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 FROM "
|
||||||
s << GEOMETRY_COLUMNS <<" WHERE f_table_name='" << mapnik::sql_utils::unquote_double(geometry_table_) <<"'";
|
<< GEOMETRY_COLUMNS <<" WHERE f_table_name='"
|
||||||
|
<< mapnik::sql_utils::unquote_double(geometry_table_)
|
||||||
|
<< "'";
|
||||||
|
|
||||||
if (schema_.length() > 0)
|
if (schema_.length() > 0)
|
||||||
s << " AND f_table_schema='" << mapnik::sql_utils::unquote_double(schema_) << "'";
|
s << " AND f_table_schema='"
|
||||||
|
<< mapnik::sql_utils::unquote_double(schema_)
|
||||||
|
<< "'";
|
||||||
|
|
||||||
if (geometry_field_.length() > 0)
|
if (geometry_field_.length() > 0)
|
||||||
s << " AND f_geometry_column='" << mapnik::sql_utils::unquote_double(geometry_field_) << "'";
|
s << " AND f_geometry_column='"
|
||||||
|
<< mapnik::sql_utils::unquote_double(geometry_field_)
|
||||||
|
<< "'";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (show_queries_)
|
if (show_queries_)
|
||||||
|
@ -326,7 +332,11 @@ void postgis_datasource::bind() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rs->close();
|
rs->close();
|
||||||
|
|
||||||
|
is_bound_ = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,7 +346,7 @@ std::string postgis_datasource::name()
|
||||||
return "postgis";
|
return "postgis";
|
||||||
}
|
}
|
||||||
|
|
||||||
int postgis_datasource::type() const
|
mapnik::datasource::datasource_t postgis_datasource::type() const
|
||||||
{
|
{
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
@ -686,6 +696,118 @@ box2d<double> postgis_datasource::envelope() const
|
||||||
return extent_;
|
return extent_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> postgis_datasource::get_geometry_type() const
|
||||||
|
{
|
||||||
|
if (! is_bound_) bind();
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> result;
|
||||||
|
|
||||||
|
ConnectionManager *mgr=ConnectionManager::instance();
|
||||||
|
shared_ptr<Pool<Connection,ConnectionCreator> > pool=mgr->getPool(creator_.id());
|
||||||
|
if (pool)
|
||||||
|
{
|
||||||
|
shared_ptr<Connection> conn = pool->borrowObject();
|
||||||
|
if (conn && conn->isOK())
|
||||||
|
{
|
||||||
|
PoolGuard<shared_ptr<Connection>,shared_ptr<Pool<Connection,ConnectionCreator> > > guard(conn,pool);
|
||||||
|
|
||||||
|
std::ostringstream s;
|
||||||
|
std::string g_type;
|
||||||
|
|
||||||
|
s << "SELECT lower(type) as type FROM "
|
||||||
|
<< GEOMETRY_COLUMNS <<" WHERE f_table_name='"
|
||||||
|
<< mapnik::sql_utils::unquote_double(geometry_table_)
|
||||||
|
<< "'";
|
||||||
|
|
||||||
|
if (schema_.length() > 0)
|
||||||
|
s << " AND f_table_schema='"
|
||||||
|
<< mapnik::sql_utils::unquote_double(schema_)
|
||||||
|
<< "'";
|
||||||
|
|
||||||
|
if (geometry_field_.length() > 0)
|
||||||
|
s << " AND f_geometry_column='"
|
||||||
|
<< mapnik::sql_utils::unquote_double(geometry_field_)
|
||||||
|
<< "'";
|
||||||
|
|
||||||
|
shared_ptr<ResultSet> rs = conn->executeQuery(s.str());
|
||||||
|
if (rs->next())
|
||||||
|
{
|
||||||
|
g_type = rs->getValue("type");
|
||||||
|
if (boost::algorithm::contains(g_type,"line"))
|
||||||
|
{
|
||||||
|
result.reset(mapnik::datasource::LineString);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else if (boost::algorithm::contains(g_type,"point"))
|
||||||
|
{
|
||||||
|
result.reset(mapnik::datasource::Point);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else if (boost::algorithm::contains(g_type,"polygon"))
|
||||||
|
{
|
||||||
|
result.reset(mapnik::datasource::Polygon);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else // geometry
|
||||||
|
{
|
||||||
|
result.reset(mapnik::datasource::Collection);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback to querying first several features
|
||||||
|
if (g_type.empty() && !geometryColumn_.empty())
|
||||||
|
{
|
||||||
|
s.str("");
|
||||||
|
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";
|
||||||
|
result.reset(mapnik::datasource::LineString);
|
||||||
|
}
|
||||||
|
else if (boost::algorithm::icontains(data,"point"))
|
||||||
|
{
|
||||||
|
g_type = "point";
|
||||||
|
result.reset(mapnik::datasource::Point);
|
||||||
|
}
|
||||||
|
else if (boost::algorithm::icontains(data,"polygon"))
|
||||||
|
{
|
||||||
|
g_type = "polygon";
|
||||||
|
result.reset(mapnik::datasource::Polygon);
|
||||||
|
}
|
||||||
|
else // geometry
|
||||||
|
{
|
||||||
|
result.reset(mapnik::datasource::Collection);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (!prev_type.empty() && g_type != prev_type)
|
||||||
|
{
|
||||||
|
result.reset(mapnik::datasource::Collection);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
prev_type = g_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
postgis_datasource::~postgis_datasource()
|
postgis_datasource::~postgis_datasource()
|
||||||
{
|
{
|
||||||
if (is_bound_ && !persist_connection_)
|
if (is_bound_ && !persist_connection_)
|
||||||
|
|
|
@ -63,7 +63,7 @@ class postgis_datasource : public datasource
|
||||||
const int cursor_fetch_size_;
|
const int cursor_fetch_size_;
|
||||||
const int row_limit_;
|
const int row_limit_;
|
||||||
mutable std::string geometryColumn_;
|
mutable std::string geometryColumn_;
|
||||||
int type_;
|
mapnik::datasource::datasource_t type_;
|
||||||
mutable int srid_;
|
mutable int srid_;
|
||||||
mutable bool extent_initialized_;
|
mutable bool extent_initialized_;
|
||||||
mutable mapnik::box2d<double> extent_;
|
mutable mapnik::box2d<double> extent_;
|
||||||
|
@ -79,10 +79,11 @@ class postgis_datasource : public datasource
|
||||||
//bool show_queries_;
|
//bool show_queries_;
|
||||||
public:
|
public:
|
||||||
static std::string name();
|
static std::string name();
|
||||||
int type() const;
|
mapnik::datasource::datasource_t type() const;
|
||||||
featureset_ptr features(const query& q) const;
|
featureset_ptr features(const query& q) const;
|
||||||
featureset_ptr features_at_point(coord2d const& pt) const;
|
featureset_ptr features_at_point(coord2d const& pt) const;
|
||||||
mapnik::box2d<double> envelope() const;
|
mapnik::box2d<double> envelope() const;
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||||
layer_descriptor get_descriptor() const;
|
layer_descriptor get_descriptor() const;
|
||||||
postgis_datasource(const parameters ¶ms, bool bind=true);
|
postgis_datasource(const parameters ¶ms, bool bind=true);
|
||||||
~postgis_datasource();
|
~postgis_datasource();
|
||||||
|
|
|
@ -159,7 +159,7 @@ raster_datasource::~raster_datasource()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int raster_datasource::type() const
|
mapnik::datasource::datasource_t raster_datasource::type() const
|
||||||
{
|
{
|
||||||
return datasource::Raster;
|
return datasource::Raster;
|
||||||
}
|
}
|
||||||
|
@ -174,6 +174,11 @@ mapnik::box2d<double> raster_datasource::envelope() const
|
||||||
return extent_;
|
return extent_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> raster_datasource::get_geometry_type() const
|
||||||
|
{
|
||||||
|
return boost::optional<mapnik::datasource::geometry_t>();
|
||||||
|
}
|
||||||
|
|
||||||
layer_descriptor raster_datasource::get_descriptor() const
|
layer_descriptor raster_datasource::get_descriptor() const
|
||||||
{
|
{
|
||||||
return desc_;
|
return desc_;
|
||||||
|
|
|
@ -33,11 +33,12 @@ class raster_datasource : public mapnik::datasource
|
||||||
public:
|
public:
|
||||||
raster_datasource(const mapnik::parameters& params, bool bind=true);
|
raster_datasource(const mapnik::parameters& params, bool bind=true);
|
||||||
virtual ~raster_datasource();
|
virtual ~raster_datasource();
|
||||||
int type() const;
|
datasource::datasource_t type() const;
|
||||||
static std::string name();
|
static std::string name();
|
||||||
mapnik::featureset_ptr features(const mapnik::query& q) const;
|
mapnik::featureset_ptr features(const mapnik::query& q) const;
|
||||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||||
mapnik::box2d<double> envelope() const;
|
mapnik::box2d<double> envelope() const;
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||||
mapnik::layer_descriptor get_descriptor() const;
|
mapnik::layer_descriptor get_descriptor() const;
|
||||||
void bind() const;
|
void bind() const;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -36,7 +36,7 @@ class rasterlite_datasource : public mapnik::datasource
|
||||||
public:
|
public:
|
||||||
rasterlite_datasource(mapnik::parameters const& params, bool bind = true);
|
rasterlite_datasource(mapnik::parameters const& params, bool bind = true);
|
||||||
virtual ~rasterlite_datasource ();
|
virtual ~rasterlite_datasource ();
|
||||||
int type() const;
|
mapnik::datasource::datasource_t type() const;
|
||||||
static std::string name();
|
static std::string name();
|
||||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||||
|
|
|
@ -182,8 +182,8 @@ void shape_datasource::init(shape_io& shape) const
|
||||||
throw datasource_exception("Shape Plugin: " + (boost::format("invalid version number: %d") % version).str());
|
throw datasource_exception("Shape Plugin: " + (boost::format("invalid version number: %d") % version).str());
|
||||||
}
|
}
|
||||||
|
|
||||||
int shape_type = shape.shp().read_ndr_integer();
|
shape_type_ = static_cast<shape_io::shapeType>(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");
|
||||||
|
|
||||||
shape.shp().read_envelope(extent_);
|
shape.shp().read_envelope(extent_);
|
||||||
|
@ -229,7 +229,7 @@ std::string shape_datasource::name()
|
||||||
return "shape";
|
return "shape";
|
||||||
}
|
}
|
||||||
|
|
||||||
int shape_datasource::type() const
|
datasource::datasource_t shape_datasource::type() const
|
||||||
{
|
{
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
@ -314,3 +314,39 @@ box2d<double> shape_datasource::envelope() const
|
||||||
|
|
||||||
return extent_;
|
return extent_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> shape_datasource::get_geometry_type() const
|
||||||
|
{
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> result;
|
||||||
|
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:
|
||||||
|
{
|
||||||
|
result.reset(mapnik::datasource::Point);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case shape_io::shape_polyline:
|
||||||
|
case shape_io::shape_polylinem:
|
||||||
|
case shape_io::shape_polylinez:
|
||||||
|
{
|
||||||
|
result.reset(mapnik::datasource::LineString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case shape_io::shape_polygon:
|
||||||
|
case shape_io::shape_polygonm:
|
||||||
|
case shape_io::shape_polygonz:
|
||||||
|
{
|
||||||
|
result.reset(mapnik::datasource::Polygon);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,11 +45,12 @@ public:
|
||||||
shape_datasource(const parameters ¶ms, bool bind=true);
|
shape_datasource(const parameters ¶ms, bool bind=true);
|
||||||
virtual ~shape_datasource();
|
virtual ~shape_datasource();
|
||||||
|
|
||||||
int type() const;
|
datasource::datasource_t type() const;
|
||||||
static std::string name();
|
static std::string name();
|
||||||
featureset_ptr features(const query& q) const;
|
featureset_ptr features(const query& q) const;
|
||||||
featureset_ptr features_at_point(coord2d const& pt) const;
|
featureset_ptr features_at_point(coord2d const& pt) const;
|
||||||
box2d<double> envelope() const;
|
box2d<double> envelope() const;
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||||
layer_descriptor get_descriptor() const;
|
layer_descriptor get_descriptor() const;
|
||||||
void bind() const;
|
void bind() const;
|
||||||
private:
|
private:
|
||||||
|
@ -57,9 +58,10 @@ private:
|
||||||
shape_datasource& operator=(const shape_datasource&);
|
shape_datasource& operator=(const shape_datasource&);
|
||||||
void init(shape_io& shape) const;
|
void init(shape_io& shape) const;
|
||||||
private:
|
private:
|
||||||
int type_;
|
datasource::datasource_t type_;
|
||||||
std::string shape_name_;
|
std::string shape_name_;
|
||||||
mutable boost::shared_ptr<shape_io> shape_;
|
mutable boost::shared_ptr<shape_io> shape_;
|
||||||
|
mutable shape_io::shapeType shape_type_;
|
||||||
mutable long file_length_;
|
mutable long file_length_;
|
||||||
mutable box2d<double> extent_;
|
mutable box2d<double> extent_;
|
||||||
mutable bool indexed_;
|
mutable bool indexed_;
|
||||||
|
|
|
@ -71,7 +71,7 @@ void shape_io::move_to(int pos)
|
||||||
shp_.seek(pos);
|
shp_.seek(pos);
|
||||||
id_ = shp_.read_xdr_integer();
|
id_ = shp_.read_xdr_integer();
|
||||||
reclength_ = shp_.read_xdr_integer();
|
reclength_ = shp_.read_xdr_integer();
|
||||||
type_ = shp_.read_ndr_integer();
|
type_ = static_cast<shape_io::shapeType>(shp_.read_ndr_integer());
|
||||||
|
|
||||||
if (type_ != shape_null && type_ != shape_point && type_ != shape_pointm && type_ != shape_pointz)
|
if (type_ != shape_null && type_ != shape_point && type_ != shape_pointm && type_ != shape_pointz)
|
||||||
{
|
{
|
||||||
|
@ -79,7 +79,7 @@ void shape_io::move_to(int pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int shape_io::type() const
|
shape_io::shapeType shape_io::type() const
|
||||||
{
|
{
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/geometry.hpp>
|
#include <mapnik/geometry.hpp>
|
||||||
|
#include <mapnik/datasource.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
@ -71,11 +73,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void move_to(int id);
|
void move_to(int id);
|
||||||
int type() const;
|
shapeType type() const;
|
||||||
const box2d<double>& current_extent() const;
|
const box2d<double>& current_extent() const;
|
||||||
void read_polyline(mapnik::geometry_container & geom);
|
void read_polyline(mapnik::geometry_container & geom);
|
||||||
void read_polygon(mapnik::geometry_container & geom);
|
void read_polygon(mapnik::geometry_container & geom);
|
||||||
unsigned type_;
|
shapeType type_;
|
||||||
shape_file shp_;
|
shape_file shp_;
|
||||||
dbf_file dbf_;
|
dbf_file dbf_;
|
||||||
boost::shared_ptr<shape_file> index_;
|
boost::shared_ptr<shape_file> index_;
|
||||||
|
|
|
@ -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_ds_type.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,7 @@ void sqlite_datasource::bind() const
|
||||||
throw datasource_exception(s.str());
|
throw datasource_exception(s.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is_bound_ = true;
|
is_bound_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,7 +472,7 @@ std::string sqlite_datasource::name()
|
||||||
return "sqlite";
|
return "sqlite";
|
||||||
}
|
}
|
||||||
|
|
||||||
int sqlite_datasource::type() const
|
mapnik::datasource::datasource_t sqlite_datasource::type() const
|
||||||
{
|
{
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
@ -446,6 +484,53 @@ box2d<double> sqlite_datasource::envelope() const
|
||||||
return extent_;
|
return extent_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> sqlite_datasource::get_geometry_type() const
|
||||||
|
{
|
||||||
|
if (! is_bound_) bind();
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> result;
|
||||||
|
|
||||||
|
if (dataset_)
|
||||||
|
{
|
||||||
|
// finally, get geometry type by querying first feature
|
||||||
|
std::ostringstream s;
|
||||||
|
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());
|
||||||
|
int multi_type = 0;
|
||||||
|
while (rs->is_valid() && rs->step_next())
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
const char* data = (const char*) rs->column_blob(0, size);
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
boost::ptr_vector<mapnik::geometry_type> paths;
|
||||||
|
mapnik::geometry_utils::from_wkb(paths, data, size, mapnik::wkbAuto);
|
||||||
|
mapnik::util::to_ds_type(paths,result);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
int type = static_cast<int>(*result);
|
||||||
|
if (multi_type > 0 && multi_type != type)
|
||||||
|
{
|
||||||
|
result.reset(mapnik::datasource::Collection);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
multi_type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
layer_descriptor sqlite_datasource::get_descriptor() const
|
layer_descriptor sqlite_datasource::get_descriptor() const
|
||||||
{
|
{
|
||||||
if (! is_bound_) bind();
|
if (! is_bound_) bind();
|
||||||
|
|
|
@ -42,11 +42,12 @@ class sqlite_datasource : public mapnik::datasource
|
||||||
public:
|
public:
|
||||||
sqlite_datasource(mapnik::parameters const& params, bool bind = true);
|
sqlite_datasource(mapnik::parameters const& params, bool bind = true);
|
||||||
virtual ~sqlite_datasource ();
|
virtual ~sqlite_datasource ();
|
||||||
int type() const;
|
datasource::datasource_t type() const;
|
||||||
static std::string name();
|
static std::string name();
|
||||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||||
mapnik::box2d<double> envelope() const;
|
mapnik::box2d<double> envelope() const;
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||||
mapnik::layer_descriptor get_descriptor() const;
|
mapnik::layer_descriptor get_descriptor() const;
|
||||||
void bind() const;
|
void bind() const;
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ private:
|
||||||
|
|
||||||
mutable mapnik::box2d<double> extent_;
|
mutable mapnik::box2d<double> extent_;
|
||||||
mutable bool extent_initialized_;
|
mutable bool extent_initialized_;
|
||||||
int type_;
|
mapnik::datasource::datasource_t type_;
|
||||||
mutable std::string dataset_name_;
|
mutable std::string dataset_name_;
|
||||||
mutable boost::shared_ptr<sqlite_connection> dataset_;
|
mutable boost::shared_ptr<sqlite_connection> dataset_;
|
||||||
mutable std::string table_;
|
mutable std::string table_;
|
||||||
|
|
|
@ -12,8 +12,7 @@ using mapnik::parameters;
|
||||||
DATASOURCE_PLUGIN(hello_datasource)
|
DATASOURCE_PLUGIN(hello_datasource)
|
||||||
|
|
||||||
hello_datasource::hello_datasource(parameters const& params, bool bind)
|
hello_datasource::hello_datasource(parameters const& params, bool bind)
|
||||||
: datasource(params),
|
: datasource(params)
|
||||||
type_(datasource::Vector),
|
|
||||||
desc_(*params_.get<std::string>("type"), *params_.get<std::string>("encoding","utf-8")),
|
desc_(*params_.get<std::string>("type"), *params_.get<std::string>("encoding","utf-8")),
|
||||||
extent_()
|
extent_()
|
||||||
{
|
{
|
||||||
|
@ -34,6 +33,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,9 +50,9 @@ std::string hello_datasource::name()
|
||||||
return name_;
|
return name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hello_datasource::type() const
|
mapnik::datasource::datasource_t hello_datasource::type() const
|
||||||
{
|
{
|
||||||
return type_;
|
return datasource::Vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapnik::box2d<double> hello_datasource::envelope() const
|
mapnik::box2d<double> hello_datasource::envelope() const
|
||||||
|
@ -59,6 +62,11 @@ mapnik::box2d<double> hello_datasource::envelope() const
|
||||||
return extent_;
|
return extent_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> hello_datasource::get_geometry_type() const
|
||||||
|
{
|
||||||
|
boost::optional<mapnik::datasource::geometry_t>(mapnik::datasource::Point);
|
||||||
|
}
|
||||||
|
|
||||||
mapnik::layer_descriptor hello_datasource::get_descriptor() const
|
mapnik::layer_descriptor hello_datasource::get_descriptor() const
|
||||||
{
|
{
|
||||||
if (!is_bound_) bind();
|
if (!is_bound_) bind();
|
||||||
|
|
|
@ -15,7 +15,7 @@ public:
|
||||||
virtual ~hello_datasource ();
|
virtual ~hello_datasource ();
|
||||||
|
|
||||||
// mandatory: type of the plugin, used to match at runtime
|
// mandatory: type of the plugin, used to match at runtime
|
||||||
int type() const;
|
mapnik::datasource::datasource_t type() const;
|
||||||
|
|
||||||
// mandatory: name of the plugin
|
// mandatory: name of the plugin
|
||||||
static std::string name();
|
static std::string name();
|
||||||
|
@ -32,6 +32,9 @@ public:
|
||||||
// called during rendering to determine if the layer should be processed
|
// called during rendering to determine if the layer should be processed
|
||||||
mapnik::box2d<double> envelope() const;
|
mapnik::box2d<double> envelope() const;
|
||||||
|
|
||||||
|
// mandatory: optionally return the overal geometry type of the datasource
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||||
|
|
||||||
// mandatory: return the layer descriptor
|
// mandatory: return the layer descriptor
|
||||||
mapnik::layer_descriptor get_descriptor() const;
|
mapnik::layer_descriptor get_descriptor() const;
|
||||||
|
|
||||||
|
@ -42,7 +45,6 @@ private:
|
||||||
// recommended naming convention of datasource members:
|
// recommended naming convention of datasource members:
|
||||||
// name_, type_, extent_, and desc_
|
// name_, type_, extent_, and desc_
|
||||||
static const std::string name_;
|
static const std::string name_;
|
||||||
int type_;
|
|
||||||
mutable mapnik::layer_descriptor desc_;
|
mutable mapnik::layer_descriptor desc_;
|
||||||
mutable mapnik::box2d<double> extent_;
|
mutable mapnik::box2d<double> extent_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -143,6 +143,7 @@ void datasource_cache::register_datasources(const std::string& str)
|
||||||
mapnik::CreateStatic>::mutex_);
|
mapnik::CreateStatic>::mutex_);
|
||||||
#endif
|
#endif
|
||||||
boost::filesystem::path path(str);
|
boost::filesystem::path path(str);
|
||||||
|
// TODO - only push unique paths
|
||||||
plugin_directories_.push_back(str);
|
plugin_directories_.push_back(str);
|
||||||
boost::filesystem::directory_iterator end_itr;
|
boost::filesystem::directory_iterator end_itr;
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ void memory_datasource::push(feature_ptr feature)
|
||||||
features_.push_back(feature);
|
features_.push_back(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
int memory_datasource::type() const
|
datasource::datasource_t memory_datasource::type() const
|
||||||
{
|
{
|
||||||
return datasource::Vector;
|
return datasource::Vector;
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,12 @@ box2d<double> memory_datasource::envelope() const
|
||||||
return ext;
|
return ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<datasource::geometry_t> memory_datasource::get_geometry_type() const
|
||||||
|
{
|
||||||
|
// TODO - detect this?
|
||||||
|
return datasource::Collection;
|
||||||
|
}
|
||||||
|
|
||||||
layer_descriptor memory_datasource::get_descriptor() const
|
layer_descriptor memory_datasource::get_descriptor() const
|
||||||
{
|
{
|
||||||
return desc_;
|
return desc_;
|
||||||
|
@ -118,7 +124,7 @@ void point_datasource::add_point(double x, double y, const char* key, const char
|
||||||
{
|
{
|
||||||
feature_ptr feature(feature_factory::create(feature_id_));
|
feature_ptr feature(feature_factory::create(feature_id_));
|
||||||
++feature_id_;
|
++feature_id_;
|
||||||
geometry_type * pt = new geometry_type(Point);
|
geometry_type * pt = new geometry_type(mapnik::Point);
|
||||||
pt->move_to(x,y);
|
pt->move_to(x,y);
|
||||||
feature->add_geometry(pt);
|
feature->add_geometry(pt);
|
||||||
transcoder tr("utf-8");
|
transcoder tr("utf-8");
|
||||||
|
|
4178
tests/data/csv/10m-land.csv
Normal file
4178
tests/data/csv/10m-land.csv
Normal file
File diff suppressed because one or more lines are too long
3
tests/data/csv/line_wkt.csv
Normal file
3
tests/data/csv/line_wkt.csv
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
type,WKT
|
||||||
|
linestring, "LINESTRING (30 10, 10 30, 40 40)"
|
||||||
|
multilinestring, "MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))"
|
|
5
tests/data/csv/multi_poly_wkt.csv
Normal file
5
tests/data/csv/multi_poly_wkt.csv
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
type,WKT
|
||||||
|
polygon, "POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))"
|
||||||
|
polygon, "POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))"
|
||||||
|
multipolygon, "MULTIPOLYGON (((30 20, 10 40, 45 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))"
|
||||||
|
multipolygon, "MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),((20 35, 45 20, 30 5, 10 10, 10 30, 20 35),(30 20, 20 25, 20 15, 30 20)))"
|
|
3
tests/data/csv/point_wkt.csv
Normal file
3
tests/data/csv/point_wkt.csv
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
type,WKT
|
||||||
|
point, "POINT (30 10)"
|
||||||
|
multipoint, "MULTIPOINT ((10 40), (40 30), (20 20), (30 10))"
|
|
3
tests/data/csv/poly_wkt.csv
Normal file
3
tests/data/csv/poly_wkt.csv
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
type,WKT
|
||||||
|
polygon, "POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))"
|
||||||
|
polygon, "POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))"
|
|
|
@ -54,12 +54,14 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
attr = {'City': u'New York, NY', 'geo_accuracy': u'house', 'Phone': u'(212) 334-0711', 'Address': u'19 Elizabeth Street', 'Precinct': u'5th Precinct', 'geo_longitude': -70, 'geo_latitude': 40}
|
attr = {'City': u'New York, NY', 'geo_accuracy': u'house', 'Phone': u'(212) 334-0711', 'Address': u'19 Elizabeth Street', 'Precinct': u'5th Precinct', 'geo_longitude': -70, 'geo_latitude': 40}
|
||||||
eq_(feat.attributes,attr)
|
eq_(feat.attributes,attr)
|
||||||
eq_(len(ds.all_features()),2)
|
eq_(len(ds.all_features()),2)
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
def test_skipping_blank_rows(**kwargs):
|
def test_skipping_blank_rows(**kwargs):
|
||||||
ds = get_csv_ds('blank_rows.csv')
|
ds = get_csv_ds('blank_rows.csv')
|
||||||
eq_(ds.fields(),['x','y','name'])
|
eq_(ds.fields(),['x','y','name'])
|
||||||
eq_(ds.field_types(),['int','int','str'])
|
eq_(ds.field_types(),['int','int','str'])
|
||||||
eq_(len(ds.all_features()),2)
|
eq_(len(ds.all_features()),2)
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
def test_empty_rows(**kwargs):
|
def test_empty_rows(**kwargs):
|
||||||
ds = get_csv_ds('empty_rows.csv')
|
ds = get_csv_ds('empty_rows.csv')
|
||||||
|
@ -75,6 +77,7 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
eq_(len(feat),10)
|
eq_(len(feat),10)
|
||||||
eq_(feat['empty_column'],u'')
|
eq_(feat['empty_column'],u'')
|
||||||
feat = fs.next()
|
feat = fs.next()
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
def test_slashes(**kwargs):
|
def test_slashes(**kwargs):
|
||||||
ds = get_csv_ds('has_attributes_with_slashes.csv')
|
ds = get_csv_ds('has_attributes_with_slashes.csv')
|
||||||
|
@ -83,6 +86,7 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
eq_(fs[0].attributes,{'x':0,'y':0,'name':u'a/a'})
|
eq_(fs[0].attributes,{'x':0,'y':0,'name':u'a/a'})
|
||||||
eq_(fs[1].attributes,{'x':1,'y':4,'name':u'b/b'})
|
eq_(fs[1].attributes,{'x':1,'y':4,'name':u'b/b'})
|
||||||
eq_(fs[2].attributes,{'x':10,'y':2.5,'name':u'c/c'})
|
eq_(fs[2].attributes,{'x':10,'y':2.5,'name':u'c/c'})
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
def test_wkt_field(**kwargs):
|
def test_wkt_field(**kwargs):
|
||||||
ds = get_csv_ds('wkt.csv')
|
ds = get_csv_ds('wkt.csv')
|
||||||
|
@ -92,24 +96,25 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
fs = ds.all_features()
|
fs = ds.all_features()
|
||||||
#import pdb;pdb.set_trace()
|
#import pdb;pdb.set_trace()
|
||||||
eq_(len(fs[0].geometries()),1)
|
eq_(len(fs[0].geometries()),1)
|
||||||
eq_(fs[0].geometries()[0].type(),mapnik.GeometryType.Point)
|
eq_(fs[0].geometries()[0].type(),mapnik.DataGeometryType.Point)
|
||||||
eq_(len(fs[1].geometries()),1)
|
eq_(len(fs[1].geometries()),1)
|
||||||
eq_(fs[1].geometries()[0].type(),mapnik.GeometryType.LineString)
|
eq_(fs[1].geometries()[0].type(),mapnik.DataGeometryType.LineString)
|
||||||
eq_(len(fs[2].geometries()),1)
|
eq_(len(fs[2].geometries()),1)
|
||||||
eq_(fs[2].geometries()[0].type(),mapnik.GeometryType.Polygon)
|
eq_(fs[2].geometries()[0].type(),mapnik.DataGeometryType.Polygon)
|
||||||
eq_(len(fs[3].geometries()),1) # one geometry, two parts
|
eq_(len(fs[3].geometries()),1) # one geometry, two parts
|
||||||
eq_(fs[3].geometries()[0].type(),mapnik.GeometryType.Polygon)
|
eq_(fs[3].geometries()[0].type(),mapnik.DataGeometryType.Polygon)
|
||||||
# tests assuming we want to flatten geometries
|
# tests assuming we want to flatten geometries
|
||||||
# ideally we should not have to:
|
# ideally we should not have to:
|
||||||
# https://github.com/mapnik/mapnik/issues?labels=multigeom+robustness&sort=created&direction=desc&state=open&page=1
|
# https://github.com/mapnik/mapnik/issues?labels=multigeom+robustness&sort=created&direction=desc&state=open&page=1
|
||||||
eq_(len(fs[4].geometries()),4)
|
eq_(len(fs[4].geometries()),4)
|
||||||
eq_(fs[4].geometries()[0].type(),mapnik.GeometryType.Point)
|
eq_(fs[4].geometries()[0].type(),mapnik.DataGeometryType.Point)
|
||||||
eq_(len(fs[5].geometries()),2)
|
eq_(len(fs[5].geometries()),2)
|
||||||
eq_(fs[5].geometries()[0].type(),mapnik.GeometryType.LineString)
|
eq_(fs[5].geometries()[0].type(),mapnik.DataGeometryType.LineString)
|
||||||
eq_(len(fs[6].geometries()),2)
|
eq_(len(fs[6].geometries()),2)
|
||||||
eq_(fs[6].geometries()[0].type(),mapnik.GeometryType.Polygon)
|
eq_(fs[6].geometries()[0].type(),mapnik.DataGeometryType.Polygon)
|
||||||
eq_(len(fs[7].geometries()),2)
|
eq_(len(fs[7].geometries()),2)
|
||||||
eq_(fs[7].geometries()[0].type(),mapnik.GeometryType.Polygon)
|
eq_(fs[7].geometries()[0].type(),mapnik.DataGeometryType.Polygon)
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Collection, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
|
|
||||||
def test_handling_of_missing_header(**kwargs):
|
def test_handling_of_missing_header(**kwargs):
|
||||||
|
@ -119,6 +124,7 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
fs = ds.featureset()
|
fs = ds.featureset()
|
||||||
feat = fs.next()
|
feat = fs.next()
|
||||||
eq_(feat['_4'],'missing')
|
eq_(feat['_4'],'missing')
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
def test_handling_of_headers_that_are_numbers(**kwargs):
|
def test_handling_of_headers_that_are_numbers(**kwargs):
|
||||||
ds = get_csv_ds('numbers_for_headers.csv')
|
ds = get_csv_ds('numbers_for_headers.csv')
|
||||||
|
@ -144,6 +150,7 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
eq_(fs[2]['label'],"0,5")
|
eq_(fs[2]['label'],"0,5")
|
||||||
eq_(fs[3]['label'],"5,0")
|
eq_(fs[3]['label'],"5,0")
|
||||||
eq_(fs[4]['label'],"2.5,2.5")
|
eq_(fs[4]['label'],"2.5,2.5")
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
def test_windows_newlines(**kwargs):
|
def test_windows_newlines(**kwargs):
|
||||||
ds = get_csv_ds('windows_newlines.csv')
|
ds = get_csv_ds('windows_newlines.csv')
|
||||||
|
@ -155,6 +162,7 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
eq_(feat['x'],1)
|
eq_(feat['x'],1)
|
||||||
eq_(feat['y'],10)
|
eq_(feat['y'],10)
|
||||||
eq_(feat['z'],9999.9999)
|
eq_(feat['z'],9999.9999)
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
def test_mac_newlines(**kwargs):
|
def test_mac_newlines(**kwargs):
|
||||||
ds = get_csv_ds('windows_newlines.csv')
|
ds = get_csv_ds('windows_newlines.csv')
|
||||||
|
@ -166,6 +174,7 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
eq_(feat['x'],1)
|
eq_(feat['x'],1)
|
||||||
eq_(feat['y'],10)
|
eq_(feat['y'],10)
|
||||||
eq_(feat['z'],9999.9999)
|
eq_(feat['z'],9999.9999)
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
def test_tabs(**kwargs):
|
def test_tabs(**kwargs):
|
||||||
ds = get_csv_ds('tabs_in_csv.csv')
|
ds = get_csv_ds('tabs_in_csv.csv')
|
||||||
|
@ -176,6 +185,7 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
eq_(feat['x'],-122)
|
eq_(feat['x'],-122)
|
||||||
eq_(feat['y'],48)
|
eq_(feat['y'],48)
|
||||||
eq_(feat['z'],0)
|
eq_(feat['z'],0)
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
def test_separator_pipes(**kwargs):
|
def test_separator_pipes(**kwargs):
|
||||||
ds = get_csv_ds('pipe_delimiters.csv')
|
ds = get_csv_ds('pipe_delimiters.csv')
|
||||||
|
@ -186,6 +196,7 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
eq_(feat['x'],0)
|
eq_(feat['x'],0)
|
||||||
eq_(feat['y'],0)
|
eq_(feat['y'],0)
|
||||||
eq_(feat['z'],'hello')
|
eq_(feat['z'],'hello')
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
def test_separator_semicolon(**kwargs):
|
def test_separator_semicolon(**kwargs):
|
||||||
ds = get_csv_ds('semicolon_delimiters.csv')
|
ds = get_csv_ds('semicolon_delimiters.csv')
|
||||||
|
@ -196,6 +207,7 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
eq_(feat['x'],0)
|
eq_(feat['x'],0)
|
||||||
eq_(feat['y'],0)
|
eq_(feat['y'],0)
|
||||||
eq_(feat['z'],'hello')
|
eq_(feat['z'],'hello')
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
def test_that_null_and_bool_keywords_are_empty_strings(**kwargs):
|
def test_that_null_and_bool_keywords_are_empty_strings(**kwargs):
|
||||||
ds = get_csv_ds('nulls_and_booleans_as_strings.csv')
|
ds = get_csv_ds('nulls_and_booleans_as_strings.csv')
|
||||||
|
@ -213,6 +225,7 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
eq_(feat['y'],0)
|
eq_(feat['y'],0)
|
||||||
eq_(feat['null'],'')
|
eq_(feat['null'],'')
|
||||||
eq_(feat['boolean'],'false')
|
eq_(feat['boolean'],'false')
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
@raises(RuntimeError)
|
@raises(RuntimeError)
|
||||||
def test_that_nonexistant_query_field_throws(**kwargs):
|
def test_that_nonexistant_query_field_throws(**kwargs):
|
||||||
|
@ -226,6 +239,7 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
# also add an invalid one, triggering throw
|
# also add an invalid one, triggering throw
|
||||||
query.add_property_name('bogus')
|
query.add_property_name('bogus')
|
||||||
fs = ds.features(query)
|
fs = ds.features(query)
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
def test_that_leading_zeros_mean_strings(**kwargs):
|
def test_that_leading_zeros_mean_strings(**kwargs):
|
||||||
ds = get_csv_ds('leading_zeros.csv')
|
ds = get_csv_ds('leading_zeros.csv')
|
||||||
|
@ -245,6 +259,17 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
eq_(feat['x'],0)
|
eq_(feat['x'],0)
|
||||||
eq_(feat['y'],0)
|
eq_(feat['y'],0)
|
||||||
eq_(feat['fips'],'005')
|
eq_(feat['fips'],'005')
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
|
def test_advanced_geometry_detection(**kwargs):
|
||||||
|
ds = get_csv_ds('point_wkt.csv')
|
||||||
|
eq_(ds.describe()['geometry_type'],mapnik.DataGeometryType.Point)
|
||||||
|
ds = get_csv_ds('poly_wkt.csv')
|
||||||
|
eq_(ds.describe()['geometry_type'],mapnik.DataGeometryType.Polygon)
|
||||||
|
ds = get_csv_ds('multi_poly_wkt.csv')
|
||||||
|
eq_(ds.describe()['geometry_type'],mapnik.DataGeometryType.Polygon)
|
||||||
|
ds = get_csv_ds('line_wkt.csv')
|
||||||
|
eq_(ds.describe()['geometry_type'],mapnik.DataGeometryType.LineString)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
setup()
|
setup()
|
||||||
|
|
|
@ -15,65 +15,68 @@ def test_that_datasources_exist():
|
||||||
print '***NOTICE*** - no datasource plugins have been loaded'
|
print '***NOTICE*** - no datasource plugins have been loaded'
|
||||||
|
|
||||||
def test_field_listing():
|
def test_field_listing():
|
||||||
lyr = mapnik.Layer('test')
|
|
||||||
if 'shape' in mapnik.DatasourceCache.instance().plugin_names():
|
if 'shape' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
lyr.datasource = mapnik.Shapefile(file='../data/shp/poly.shp')
|
ds = mapnik.Shapefile(file='../data/shp/poly.shp')
|
||||||
fields = lyr.datasource.fields()
|
fields = ds.fields()
|
||||||
eq_(fields, ['AREA', 'EAS_ID', 'PRFEDEA'])
|
eq_(fields, ['AREA', 'EAS_ID', 'PRFEDEA'])
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Polygon, 'type': mapnik.DataType.Vector, 'name': 'shape', 'encoding': 'utf-8'})
|
||||||
|
|
||||||
def test_total_feature_count_shp():
|
def test_total_feature_count_shp():
|
||||||
lyr = mapnik.Layer('test')
|
|
||||||
if 'shape' in mapnik.DatasourceCache.instance().plugin_names():
|
if 'shape' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
lyr.datasource = mapnik.Shapefile(file='../data/shp/poly.shp')
|
ds = mapnik.Shapefile(file='../data/shp/poly.shp')
|
||||||
features = lyr.datasource.all_features()
|
features = ds.all_features()
|
||||||
num_feats = len(features)
|
num_feats = len(features)
|
||||||
eq_(num_feats, 10)
|
eq_(num_feats, 10)
|
||||||
|
|
||||||
def test_total_feature_count_json():
|
def test_total_feature_count_json():
|
||||||
lyr = mapnik.Layer('test')
|
|
||||||
if 'ogr' in mapnik.DatasourceCache.instance().plugin_names():
|
if 'ogr' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
lyr.datasource = mapnik.Ogr(file='../data/json/points.json',layer_by_index=0)
|
ds = mapnik.Ogr(file='../data/json/points.json',layer_by_index=0)
|
||||||
features = lyr.datasource.all_features()
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'ogr', 'encoding': 'utf-8'})
|
||||||
|
features = ds.all_features()
|
||||||
num_feats = len(features)
|
num_feats = len(features)
|
||||||
eq_(num_feats, 5)
|
eq_(num_feats, 5)
|
||||||
|
|
||||||
|
def test_sqlite_reading():
|
||||||
|
if 'sqlite' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
|
ds = mapnik.SQLite(file='../data/sqlite/world.sqlite',table_by_index=0)
|
||||||
|
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Polygon, 'type': mapnik.DataType.Vector, 'name': 'sqlite', 'encoding': 'utf-8'})
|
||||||
|
features = ds.all_features()
|
||||||
|
num_feats = len(features)
|
||||||
|
eq_(num_feats, 245)
|
||||||
|
|
||||||
def test_reading_json_from_string():
|
def test_reading_json_from_string():
|
||||||
json = open('../data/json/points.json','r').read()
|
json = open('../data/json/points.json','r').read()
|
||||||
lyr = mapnik.Layer('test')
|
|
||||||
if 'ogr' in mapnik.DatasourceCache.instance().plugin_names():
|
if 'ogr' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
lyr.datasource = mapnik.Ogr(file=json,layer_by_index=0)
|
ds = mapnik.Ogr(file=json,layer_by_index=0)
|
||||||
features = lyr.datasource.all_features()
|
features = ds.all_features()
|
||||||
num_feats = len(features)
|
num_feats = len(features)
|
||||||
eq_(num_feats, 5)
|
eq_(num_feats, 5)
|
||||||
|
|
||||||
def test_feature_envelope():
|
def test_feature_envelope():
|
||||||
lyr = mapnik.Layer('test')
|
|
||||||
if 'shape' in mapnik.DatasourceCache.instance().plugin_names():
|
if 'shape' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
lyr.datasource = mapnik.Shapefile(file='../data/shp/poly.shp')
|
ds = mapnik.Shapefile(file='../data/shp/poly.shp')
|
||||||
features = lyr.datasource.all_features()
|
features = ds.all_features()
|
||||||
for feat in features:
|
for feat in features:
|
||||||
env = feat.envelope()
|
env = feat.envelope()
|
||||||
contains = lyr.envelope().contains(env)
|
contains = ds.envelope().contains(env)
|
||||||
eq_(contains, True)
|
eq_(contains, True)
|
||||||
intersects = lyr.envelope().contains(env)
|
intersects = ds.envelope().contains(env)
|
||||||
eq_(intersects, True)
|
eq_(intersects, True)
|
||||||
|
|
||||||
def test_feature_attributes():
|
def test_feature_attributes():
|
||||||
lyr = mapnik.Layer('test')
|
|
||||||
if 'shape' in mapnik.DatasourceCache.instance().plugin_names():
|
if 'shape' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
lyr.datasource = mapnik.Shapefile(file='../data/shp/poly.shp')
|
ds = mapnik.Shapefile(file='../data/shp/poly.shp')
|
||||||
features = lyr.datasource.all_features()
|
features = ds.all_features()
|
||||||
feat = features[0]
|
feat = features[0]
|
||||||
attrs = {'PRFEDEA': u'35043411', 'EAS_ID': 168, 'AREA': 215229.266}
|
attrs = {'PRFEDEA': u'35043411', 'EAS_ID': 168, 'AREA': 215229.266}
|
||||||
eq_(feat.attributes, attrs)
|
eq_(feat.attributes, attrs)
|
||||||
eq_(lyr.datasource.fields(),['AREA', 'EAS_ID', 'PRFEDEA'])
|
eq_(ds.fields(),['AREA', 'EAS_ID', 'PRFEDEA'])
|
||||||
eq_(lyr.datasource.field_types(),['float','int','str'])
|
eq_(ds.field_types(),['float','int','str'])
|
||||||
|
|
||||||
def test_ogr_layer_by_sql():
|
def test_ogr_layer_by_sql():
|
||||||
lyr = mapnik.Layer('test')
|
|
||||||
if 'ogr' in mapnik.DatasourceCache.instance().plugin_names():
|
if 'ogr' in mapnik.DatasourceCache.instance().plugin_names():
|
||||||
lyr.datasource = mapnik.Ogr(file='../data/shp/poly.shp', layer_by_sql='SELECT * FROM poly WHERE EAS_ID = 168')
|
ds = mapnik.Ogr(file='../data/shp/poly.shp', layer_by_sql='SELECT * FROM poly WHERE EAS_ID = 168')
|
||||||
features = lyr.datasource.all_features()
|
features = ds.all_features()
|
||||||
num_feats = len(features)
|
num_feats = len(features)
|
||||||
eq_(num_feats, 1)
|
eq_(num_feats, 1)
|
||||||
|
|
||||||
|
|
|
@ -58,8 +58,8 @@ def test_adding_datasource_to_layer():
|
||||||
m.layers[0].datasource = ds
|
m.layers[0].datasource = ds
|
||||||
|
|
||||||
# now ensure it is attached
|
# now ensure it is attached
|
||||||
eq_(m.layers[0].datasource.name(),"shape")
|
eq_(m.layers[0].datasource.describe()['name'],"shape")
|
||||||
eq_(lyr.datasource.name(),"shape")
|
eq_(lyr.datasource.describe()['name'],"shape")
|
||||||
|
|
||||||
# and since we have now added a shapefile in spherical mercator, adjust the projection
|
# and since we have now added a shapefile in spherical mercator, adjust the projection
|
||||||
lyr.srs = '+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs'
|
lyr.srs = '+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs'
|
||||||
|
|
|
@ -20,7 +20,7 @@ def call(cmd,silent=False):
|
||||||
stdin, stderr = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
|
stdin, stderr = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
|
||||||
if not stderr:
|
if not stderr:
|
||||||
return stdin.strip()
|
return stdin.strip()
|
||||||
elif not silent:
|
elif not silent and not 'NOTICE' in stderr:
|
||||||
raise RuntimeError(stderr.strip())
|
raise RuntimeError(stderr.strip())
|
||||||
|
|
||||||
def psql_can_connect():
|
def psql_can_connect():
|
||||||
|
@ -63,12 +63,23 @@ def createdb_and_dropdb_on_path():
|
||||||
print 'Notice: skipping postgis tests (createdb/dropdb)'
|
print 'Notice: skipping postgis tests (createdb/dropdb)'
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
insert_sql = """
|
||||||
|
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||||
|
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;POINT(-2 2)'));
|
||||||
|
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;MULTIPOINT(2 1,1 2)'));
|
||||||
|
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;LINESTRING(0 0,1 1,1 2)'));
|
||||||
|
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;MULTILINESTRING((1 0,0 1,3 2),(3 2,5 4))'));
|
||||||
|
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))'));
|
||||||
|
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;MULTIPOLYGON(((1 1,3 1,3 3,1 3,1 1),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))'));
|
||||||
|
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;GEOMETRYCOLLECTION(POLYGON((1 1, 2 1, 2 2, 1 2,1 1)),POINT(2 3),LINESTRING(2 3,3 4))'));
|
||||||
|
"""
|
||||||
|
|
||||||
def postgis_setup():
|
def postgis_setup():
|
||||||
call('dropdb %s' % MAPNIK_TEST_DBNAME,silent=True)
|
call('dropdb %s' % MAPNIK_TEST_DBNAME,silent=True)
|
||||||
call('createdb -T %s %s' % (POSTGIS_TEMPLATE_DBNAME,MAPNIK_TEST_DBNAME),silent=False)
|
call('createdb -T %s %s' % (POSTGIS_TEMPLATE_DBNAME,MAPNIK_TEST_DBNAME),silent=False)
|
||||||
call('shp2pgsql -s 3857 -g geom -W LATIN1 %s world_merc | psql -q %s' % (SHAPEFILE,MAPNIK_TEST_DBNAME), silent=True)
|
call('shp2pgsql -s 3857 -g geom -W LATIN1 %s world_merc | psql -q %s' % (SHAPEFILE,MAPNIK_TEST_DBNAME), silent=True)
|
||||||
call('''psql %s -c "CREATE TABLE \"empty\" (key serial);SELECT AddGeometryColumn('','empty','geom','-1','GEOMETRY',4);"''' % MAPNIK_TEST_DBNAME,silent=True)
|
call('''psql -q %s -c "CREATE TABLE \"empty\" (key serial);SELECT AddGeometryColumn('','empty','geom','-1','GEOMETRY',4);"''' % MAPNIK_TEST_DBNAME,silent=False)
|
||||||
|
call('''psql -q %s -c "create table test(gid serial PRIMARY KEY, geom geometry);%s"''' % (MAPNIK_TEST_DBNAME,insert_sql),silent=False)
|
||||||
def postgis_takedown():
|
def postgis_takedown():
|
||||||
pass
|
pass
|
||||||
# fails as the db is in use: https://github.com/mapnik/mapnik/issues/960
|
# fails as the db is in use: https://github.com/mapnik/mapnik/issues/960
|
||||||
|
@ -98,6 +109,7 @@ if 'postgis' in mapnik.DatasourceCache.instance().plugin_names() \
|
||||||
eq_(feature['subregion'],29)
|
eq_(feature['subregion'],29)
|
||||||
eq_(feature['lon'],-61.783)
|
eq_(feature['lon'],-61.783)
|
||||||
eq_(feature['lat'],17.078)
|
eq_(feature['lat'],17.078)
|
||||||
|
eq_(ds.describe()['geometry_type'],mapnik.DataGeometryType.Polygon)
|
||||||
|
|
||||||
def test_subquery():
|
def test_subquery():
|
||||||
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='(select * from world_merc) as w')
|
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='(select * from world_merc) as w')
|
||||||
|
@ -115,6 +127,7 @@ if 'postgis' in mapnik.DatasourceCache.instance().plugin_names() \
|
||||||
eq_(feature['subregion'],29)
|
eq_(feature['subregion'],29)
|
||||||
eq_(feature['lon'],-61.783)
|
eq_(feature['lon'],-61.783)
|
||||||
eq_(feature['lat'],17.078)
|
eq_(feature['lat'],17.078)
|
||||||
|
eq_(ds.describe()['geometry_type'],mapnik.DataGeometryType.Polygon)
|
||||||
|
|
||||||
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='(select gid,geom,fips as _fips from world_merc) as w')
|
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='(select gid,geom,fips as _fips from world_merc) as w')
|
||||||
fs = ds.featureset()
|
fs = ds.featureset()
|
||||||
|
@ -122,12 +135,39 @@ if 'postgis' in mapnik.DatasourceCache.instance().plugin_names() \
|
||||||
eq_(feature['gid'],1)
|
eq_(feature['gid'],1)
|
||||||
eq_(feature['_fips'],u'AC')
|
eq_(feature['_fips'],u'AC')
|
||||||
eq_(len(feature),2)
|
eq_(len(feature),2)
|
||||||
|
eq_(ds.describe()['geometry_type'],mapnik.DataGeometryType.Polygon)
|
||||||
|
|
||||||
def test_empty_db():
|
def test_empty_db():
|
||||||
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='empty')
|
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='empty')
|
||||||
fs = ds.featureset()
|
fs = ds.featureset()
|
||||||
feature = fs.next()
|
feature = fs.next()
|
||||||
eq_(feature,None)
|
eq_(feature,None)
|
||||||
|
eq_(ds.describe()['geometry_type'],mapnik.DataGeometryType.Collection)
|
||||||
|
|
||||||
|
def test_geometry_detection():
|
||||||
|
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='test',
|
||||||
|
geometry_field='geom')
|
||||||
|
eq_(ds.describe()['geometry_type'],mapnik.DataGeometryType.Collection)
|
||||||
|
|
||||||
|
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='test',
|
||||||
|
geometry_field='geom',
|
||||||
|
row_limit=1)
|
||||||
|
eq_(ds.describe()['geometry_type'],mapnik.DataGeometryType.Point)
|
||||||
|
|
||||||
|
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='test',
|
||||||
|
geometry_field='geom',
|
||||||
|
row_limit=2)
|
||||||
|
eq_(ds.describe()['geometry_type'],mapnik.DataGeometryType.Point)
|
||||||
|
|
||||||
|
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='test',
|
||||||
|
geometry_field='geom',
|
||||||
|
row_limit=3)
|
||||||
|
eq_(ds.describe()['geometry_type'],mapnik.DataGeometryType.Point)
|
||||||
|
|
||||||
|
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='test',
|
||||||
|
geometry_field='geom',
|
||||||
|
row_limit=4)
|
||||||
|
eq_(ds.describe()['geometry_type'],mapnik.DataGeometryType.Collection)
|
||||||
|
|
||||||
@raises(RuntimeError)
|
@raises(RuntimeError)
|
||||||
def test_that_nonexistant_query_field_throws(**kwargs):
|
def test_that_nonexistant_query_field_throws(**kwargs):
|
||||||
|
|
Loading…
Reference in a new issue