+ First implementation of OGR(vector) input plugin. Patch from kunitoki. Thanks! Closes #170

This commit is contained in:
Dane Springmeyer 2009-01-28 20:16:31 +00:00
parent f787128459
commit f414843c4f
11 changed files with 620 additions and 7 deletions

View file

@ -19,6 +19,7 @@ Patches
=======
- Andy Allen
- Lucio Asnaghi
- Justin Bronn
- Christopher Brown
- Jon Burgess

View file

@ -14,6 +14,8 @@ For a complete change history, see the SVN log.
Current Version (0.6.0-dev, SVN trunk):
---------------------------------------
- Plugins: Added OGR driver for reading all OGR supported formats (kunitoki) (r836) (#170)
- Python: Made available the scale_denominator property from the map in c++ and python (r793)
- Python: Added ability to resize map and clear all layers and styles from python (r793)

View file

@ -94,11 +94,13 @@ opts.Add(BoolVariable('INTERNAL_LIBAGG', 'Use provided libagg', 'True'))
# Note: cairo, cairomm, and pycairo all optional but configured automatically through pkg-config
# Therefore, we use a single boolean for whether to attempt to build cairo support.
opts.Add(BoolVariable('CAIRO', 'Attempt to build with Cairo rendering support', 'True'))
opts.Add(ListVariable('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster','gdal']))
opts.Add(ListVariable('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster','gdal','ogr']))
opts.Add(PathVariable('PGSQL_INCLUDES', 'Search path for PostgreSQL include files', '/usr/include/postgresql', PathVariable.PathAccept))
opts.Add(PathVariable('PGSQL_LIBS', 'Search path for PostgreSQL library files', '/usr/' + LIBDIR_SCHEMA))
opts.Add(PathVariable('GDAL_INCLUDES', 'Search path for GDAL include files', '/usr/include/gdal', PathVariable.PathAccept))
opts.Add(PathVariable('GDAL_LIBS', 'Search path for GDAL library files', '/usr/' + LIBDIR_SCHEMA))
opts.Add(PathVariable('GDAL_INCLUDES', 'Search path for GDAL include files', '/usr/local/include', PathVariable.PathAccept))
opts.Add(PathVariable('GDAL_LIBS', 'Search path for GDAL library files', '/usr/local/' + LIBDIR_SCHEMA))
opts.Add(PathVariable('OGR_INCLUDES', 'Search path for OGR include files', '/usr/local/include', PathVariable.PathAccept))
opts.Add(PathVariable('OGR_LIBS', 'Search path for OGR library files', '/usr/local/' + LIBDIR_SCHEMA))
# Other variables
opts.Add(PathVariable('PYTHON','Python executable', sys.executable))
@ -237,7 +239,7 @@ else:
# Adding the prerequisite library directories to the include path for
# compiling and the library path for linking, respectively.
for prereq in ('BOOST', 'PNG', 'JPEG', 'TIFF', 'PGSQL', 'PROJ', 'GDAL',):
for prereq in ('BOOST', 'PNG', 'JPEG', 'TIFF', 'PGSQL', 'PROJ', 'GDAL', 'OGR',):
inc_path = env['%s_INCLUDES' % prereq]
lib_path = env['%s_LIBS' % prereq]
uniq_add(env, 'CPPPATH', inc_path)
@ -277,7 +279,7 @@ else:
CXX_LIBSHEADERS = [
['icuuc','unicode/unistr.h',True],
['icudata','unicode/utypes.h' , True],
['gdal', 'gdal_priv.h',False]
['gdal', ['gdal_priv.h', 'ogrsf_frmts.h'],False]
]
@ -426,6 +428,9 @@ else:
if 'gdal' in inputplugins and 'gdal' in env['LIBS']:
SConscript('plugins/input/gdal/SConscript')
if 'ogr' in inputplugins and 'gdal' in env['LIBS']:
SConscript('plugins/input/ogr/SConscript')
if 'gigabase' in inputplugins and 'gigabase_r' in env['LIBS']:
SConscript('plugins/input/gigabase/SConscript')

View file

@ -87,10 +87,14 @@ def Raster(**keywords):
keywords['type'] = 'raster'
return CreateDatasource(keywords)
def Gdal (**keywords):
def Gdal(**keywords):
keywords['type'] = 'gdal'
return CreateDatasource(keywords)
def Ogr(**keywords):
keywords['type'] = 'ogr'
return CreateDatasource(keywords)
#register datasources
from mapnik import DatasourceCache
DatasourceCache.instance().register_datasources('%s' % inputpluginspath)

View file

@ -1,6 +1,7 @@
SUBDIRS = \
postgis\
ogr \
gdal \
raster \
shape \

View file

@ -0,0 +1,24 @@
if HAVE_OGR
pkglib_LTLIBRARIES = \
ogr.la
ogr_la_SOURCES = \
ogr_datasource.cpp\
ogr_featureset.cpp
ogr_la_LIBADD = \
${OGR_LDFLAGS}
ogr_la_CXXFLAGS = \
${OGR_CFLAGS} \
-I../../../include
ogr_la_LDFLAGS = \
-module \
-avoid-version \
-shrext .input
endif
## File created by the gnome-build tools

View file

@ -0,0 +1,43 @@
#
# This file is part of Mapnik (c++ mapping toolkit)
#
# Copyright (C) 2007 Artem Pavlenko, Jean-Francois Doyon
#
# Mapnik is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# $Id$
Import ('env')
prefix = env['PREFIX']
install_prefix = env['DESTDIR'] + '/' + prefix
ogr_src = Split(
"""
ogr_datasource.cpp
ogr_featureset.cpp
"""
)
libraries = [ 'gdal' ]
if env['PLATFORM'] == 'Darwin':
libraries.append('mapnik')
libraries.append('icuuc')
libraries.append('icudata')
ogr_inputdriver = env.SharedLibrary('ogr', source=ogr_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries)
env.Install(install_prefix + '/' + env['LIBDIR_SCHEMA'] + '/mapnik/input', ogr_inputdriver)
env.Alias('install', install_prefix + '/' + env['LIBDIR_SCHEMA'] + '/mapnik/input')

View file

@ -0,0 +1,216 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2007 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
// $Id$
#include "ogr_datasource.hpp"
#include "ogr_featureset.hpp"
using std::clog;
using std::endl;
using mapnik::datasource;
using mapnik::parameters;
DATASOURCE_PLUGIN(ogr_datasource)
using mapnik::Envelope;
using mapnik::coord2d;
using mapnik::query;
using mapnik::featureset_ptr;
using mapnik::layer_descriptor;
using mapnik::attribute_descriptor;
using mapnik::datasource_exception;
ogr_datasource::ogr_datasource(parameters const& params)
: datasource(params),
extent_(),
desc_(*params.get<std::string>("type"),"utf-8")
{
OGRRegisterAll();
boost::optional<std::string> file = params.get<std::string>("file");
if (!file) throw datasource_exception("missing <file> paramater");
boost::optional<std::string> layer = params.get<std::string>("layer");
if (!layer) throw datasource_exception("missing <layer> paramater");
dataset_ = OGRSFDriverRegistrar::Open ((*file).c_str(), FALSE);
if (!dataset_) throw datasource_exception(CPLGetLastErrorMsg());
#if 0
double x0 = -std::numeric_limits<float>::max(),
y0 = -std::numeric_limits<float>::max(),
x1 = std::numeric_limits<float>::max(),
y1 = std::numeric_limits<float>::max();
for (int i = 0; i < dataset_->GetLayerCount (); i++)
{
OGRLayer* layer = dataset_->GetLayer (i);
layer->GetExtent (&envelope);
x0 = std::min (envelope.MinX, x0);
y0 = std::min (envelope.MinY, y0);
x1 = std::max (envelope.MaxX, x1);
y1 = std::max (envelope.MaxY, y1);
}
#endif
layer_ = dataset_->GetLayerByName ((*layer).c_str());
if (! layer_) throw datasource_exception("cannot find <layer> in dataset");
OGREnvelope envelope;
layer_->GetExtent (&envelope);
extent_.init (envelope.MinX, envelope.MinY, envelope.MaxX, envelope.MaxY);
OGRFeatureDefn* def = layer_->GetLayerDefn ();
if (def != 0)
{
for (int i = 0; i < def->GetFieldCount (); i++)
{
OGRFieldDefn* fld = def->GetFieldDefn (i);
std_string fld_name = fld->GetNameRef ();
OGRFieldType type_oid = fld->GetType ();
switch (type_oid)
{
case OFTInteger:
// case OFTIntegerList:
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer));
break;
case OFTReal:
//case OFTRealList:
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Double));
break;
case OFTString:
//case OFTStringList:
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));
break;
case OFTBinary:
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Object));
break;
case OFTDate:
case OFTTime:
case OFTDateTime: // unhandled !
#ifdef MAPNIK_DEBUG
clog << "unhandled type_oid="<<type_oid<<endl;
#endif
break;
case OFTWideString:
case OFTWideStringList: // deprecated !
#ifdef MAPNIK_DEBUG
clog << "deprecated type_oid="<<type_oid<<endl;
#endif
break;
default: // unknown
#ifdef MAPNIK_DEBUG
clog << "unknown type_oid="<<type_oid<<endl;
#endif
break;
}
}
}
}
ogr_datasource::~ogr_datasource()
{
OGRDataSource::DestroyDataSource (dataset_);
}
std::string const ogr_datasource::name_="ogr";
std::string ogr_datasource::name()
{
return name_;
}
int ogr_datasource::type() const
{
return datasource::Raster;
}
Envelope<double> ogr_datasource::envelope() const
{
return extent_;
}
layer_descriptor ogr_datasource::get_descriptor() const
{
return desc_;
}
featureset_ptr ogr_datasource::features(query const& q) const
{
if (dataset_ && layer_)
{
mapnik::Envelope<double> const& query_extent = q.get_bbox();
OGRLinearRing ring;
ring.addPoint (query_extent.minx(), query_extent.miny());
ring.addPoint (query_extent.maxx(), query_extent.miny());
ring.addPoint (query_extent.maxx(), query_extent.maxy());
ring.addPoint (query_extent.minx(), query_extent.maxy());
OGRPolygon* boxPoly = new OGRPolygon();
boxPoly->addRing (&ring);
boxPoly->closeRings();
#if 0
std::ostringstream s;
s << "select ";
std::set<std::string> const& props=q.property_names();
std::set<std::string>::const_iterator pos=props.begin();
std::set<std::string>::const_iterator end=props.end();
while (pos != end)
{
s <<",\""<<*pos<<"\"";
++pos;
}
s << " from " << table_<<" where "<<geometryColumn_<<" && setSRID('BOX3D(";
s << std::setprecision(16);
s << box.minx() << " " << box.miny() << ",";
s << box.maxx() << " " << box.maxy() << ")'::box3d,"<<srid_<<")";
OGRLayer * dataset_->ExecuteSQL(const char *pszSQLCommand,
OGRGeometry *poSpatialFilter,
const char *pszDialect );
#endif
return featureset_ptr(new ogr_featureset(*dataset_, *layer_, boxPoly, false));
}
return featureset_ptr();
}
featureset_ptr ogr_datasource::features_at_point(coord2d const& pt) const
{
return featureset_ptr();
}

View file

@ -0,0 +1,60 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2007 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//$Id$
#ifndef OGR_DATASOURCE_HPP
#define OGR_DATASOURCE_HPP
#include <mapnik/datasource.hpp>
#include <boost/shared_ptr.hpp>
#include <ogrsf_frmts.h>
using mapnik::datasource;
using mapnik::parameters;
using mapnik::query;
using mapnik::coord2d;
using mapnik::featureset_ptr;
using mapnik::layer_descriptor;
using mapnik::Envelope;
class ogr_datasource : public datasource
{
public:
ogr_datasource(parameters const& params);
virtual ~ogr_datasource ();
int type() const;
static std::string name();
featureset_ptr features(query const& q) const;
featureset_ptr features_at_point(coord2d const& pt) const;
Envelope<double> envelope() const;
layer_descriptor get_descriptor() const;
private:
static const std::string name_;
Envelope<double> extent_;
OGRDataSource* dataset_;
OGRLayer* layer_;
layer_descriptor desc_;
};
#endif // OGR_DATASOURCE_HPP

View file

@ -0,0 +1,206 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2007 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//$Id$
#include <mapnik/global.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/envelope.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/unicode.hpp>
#include "ogr_featureset.hpp"
#include <ogrsf_frmts.h>
using std::clog;
using std::endl;
using mapnik::query;
using mapnik::Envelope;
using mapnik::Feature;
using mapnik::feature_ptr;
using mapnik::geometry_utils;
using mapnik::CoordTransform;
ogr_featureset::ogr_featureset(OGRDataSource & dataset,
OGRLayer & layer,
OGRPolygon * extent,
bool multiple_geometries)
: dataset_(dataset),
layer_(layer),
extent_(extent),
fidcolumn_(layer_.GetFIDColumn ()),
multiple_geometries_(multiple_geometries)
{
layer_.SetSpatialFilter (extent_);
layer_.ResetReading ();
}
ogr_featureset::~ogr_featureset() {}
feature_ptr ogr_featureset::next()
{
OGRFeature* feat = layer_.GetNextFeature();
if (feat != NULL)
{
OGRGeometry* geom=feat->GetGeometryRef();
if (geom != NULL)
{
long fid=feat->GetFID();
int size=geom->WkbSize ();
feature_ptr feature(new Feature(fid));
// XXX: here we can improve allocation
char data[size];
geom->exportToWkb ((OGRwkbByteOrder) endian(), reinterpret_cast<unsigned char*>(&data[0]));
geometry_utils::from_wkb(*feature,&data[0],size,multiple_geometries_);
OGRFeatureDefn* def = layer_.GetLayerDefn();
for (int i = 0; i < def->GetFieldCount(); i++)
{
OGRFieldDefn* fld = def->GetFieldDefn (i);
OGRFieldType type_oid = fld->GetType ();
std_string name = fld->GetNameRef ();
switch (type_oid)
{
case OFTInteger:
// case OFTIntegerList: // TODO
boost::put(*feature,name,feat->GetFieldAsInteger (i));
break;
case OFTReal:
//case OFTRealList: // TODO
boost::put(*feature,name,feat->GetFieldAsDouble (i));
break;
case OFTString:
//case OFTStringList: // TODO
boost::put(*feature,name,feat->GetFieldAsString (i));
break;
case OFTBinary:
#if 0
boost::put(*feature,name,feat->GetFieldAsBinary (i, size));
#endif
break;
case OFTDate:
case OFTTime:
case OFTDateTime: // unhandled !
#ifdef MAPNIK_DEBUG
clog << "unhandled type_oid="<<type_oid<<endl;
#endif
break;
case OFTWideString:
case OFTWideStringList: // deprecated !
#ifdef MAPNIK_DEBUG
//boost::put(*feature,name,tr_->transcode(feat->GetFieldAsString (i)));
clog << "deprecated type_oid="<<type_oid<<endl;
#endif
break;
default: // unknown
#ifdef MAPNIK_DEBUG
clog << "unknown type_oid="<<type_oid<<endl;
#endif
break;
}
}
OGRFeature::DestroyFeature (feat);
return feature;
}
OGRFeature::DestroyFeature (feat);
}
return feature_ptr();
}
int ogr_featureset::endian()
{
const int t = 1;
return (*(char*)&t == 0) ? wkbXDR : wkbNDR;
}
/*
OGRGeometry* geom = feat->GetGeometryRef();
if (geom != NULL)
{
switch (wkbFlatten (geom->getGeometryType()))
{
case wkbPoint: {
OGRPoint *poPoint = (OGRPoint *) geom;
printf( "%.3f,%3.f\n", poPoint->getX(), poPoint->getY() );
break;
}
case wkbLineString: {
OGRLineString *poLineString = (OGRLineString *) geom;
break;
}
case wkbPolygon: {
OGRPolygon *poPolygon = (OGRPolygon *) geom;
break;
}
case wkbMultiPoint: {
OGRMultiPoint *poMultiPoint = (OGRMultiPoint *) geom;
break;
}
case wkbMultiLineString: {
OGRMultiLineString *poMultiLineString = (OGRMultiLineString *) geom;
break;
}
case wkbMultiPolygon: {
OGRMultiPolygon *poMultiPolygon = (OGRMultiPolygon *) geom;
break;
}
case wkbGeometryCollection: {
OGRGeometryCollection *poGeometryCollection = (OGRGeometryCollection *) geom;
break;
}
case wkbLinearRing: {
OGRLinearRing *poLinearRing = (OGRLinearRing *) geom;
break;
}
case wkbPoint25D:
case wkbLineString25D:
case wkbPolygon25D:
case wkbMultiPoint25D:
case wkbMultiLineString25D:
case wkbMultiPolygon25D:
case wkbGeometryCollection25D: {
break;
}
case wkbNone:
case wkbUnknown:
default: {
break;
}
}
}
*/

View file

@ -0,0 +1,51 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2007 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//$Id$
#ifndef OGR_FEATURESET_HPP
#define OGR_FEATURESET_HPP
#include <mapnik/datasource.hpp>
class OGRDataSource;
class OGRLayer;
class OGRPolygon;
class ogr_featureset : public mapnik::Featureset
{
public:
ogr_featureset(OGRDataSource & dataset,
OGRLayer & layer,
OGRPolygon * extent,
bool multiple_geometries);
virtual ~ogr_featureset();
mapnik::feature_ptr next();
private:
int endian();
OGRDataSource & dataset_;
OGRLayer & layer_;
OGRPolygon * extent_;
const char* fidcolumn_;
bool multiple_geometries_;
};
#endif // OGR_FEATURESET_HPP