hello world plugin is now standalone at https://github.com/mapnik/hello-world-input-plugin - refs #2790
This commit is contained in:
parent
493e1d8362
commit
41ad16f4d7
11 changed files with 1 additions and 504 deletions
14
SConstruct
14
SConstruct
|
@ -411,7 +411,6 @@ opts.AddVariables(
|
||||||
BoolVariable('SVG2PNG', 'Compile and install a utility to generate render an svg file to a png on the command line', 'False'),
|
BoolVariable('SVG2PNG', 'Compile and install a utility to generate render an svg file to a png on the command line', 'False'),
|
||||||
BoolVariable('NIK2IMG', 'Compile and install a utility to generate render a map to an image', 'True'),
|
BoolVariable('NIK2IMG', 'Compile and install a utility to generate render a map to an image', 'True'),
|
||||||
BoolVariable('COLOR_PRINT', 'Print build status information in color', 'True'),
|
BoolVariable('COLOR_PRINT', 'Print build status information in color', 'True'),
|
||||||
BoolVariable('SAMPLE_INPUT_PLUGINS', 'Compile and install sample plugins', 'False'),
|
|
||||||
BoolVariable('BIGINT', 'Compile support for 64-bit integers in mapnik::value', 'True'),
|
BoolVariable('BIGINT', 'Compile support for 64-bit integers in mapnik::value', 'True'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -452,7 +451,6 @@ pickle_store = [# Scons internal variables
|
||||||
'HAS_PYCAIRO',
|
'HAS_PYCAIRO',
|
||||||
'PYCAIRO_PATHS',
|
'PYCAIRO_PATHS',
|
||||||
'HAS_LIBXML2',
|
'HAS_LIBXML2',
|
||||||
'SAMPLE_INPUT_PLUGINS',
|
|
||||||
'PKG_CONFIG_PATH',
|
'PKG_CONFIG_PATH',
|
||||||
'PATH',
|
'PATH',
|
||||||
'PATH_REMOVE',
|
'PATH_REMOVE',
|
||||||
|
@ -1965,15 +1963,3 @@ if not HELP_REQUESTED:
|
||||||
|
|
||||||
# write the viewer.ini file
|
# write the viewer.ini file
|
||||||
SConscript('demo/viewer/build.py')
|
SConscript('demo/viewer/build.py')
|
||||||
|
|
||||||
# if requested, build the sample input plugins
|
|
||||||
if env['SAMPLE_INPUT_PLUGINS']:
|
|
||||||
SConscript('plugins/input/templates/helloworld/build.py')
|
|
||||||
else:
|
|
||||||
if 'install' in COMMAND_LINE_TARGETS:
|
|
||||||
plugin_path = os.path.join(env['MAPNIK_INPUT_PLUGINS_DEST'],'hello.input')
|
|
||||||
if os.path.exists(plugin_path):
|
|
||||||
color_print(4,"Notice: removing out of date plugin: '%s'" % plugin_path)
|
|
||||||
os.unlink(plugin_path)
|
|
||||||
if os.path.exists('plugins/input/templates/hello.input'):
|
|
||||||
os.unlink('plugins/input/templates/hello.input')
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
## template plugins
|
|
||||||
|
|
||||||
Directory to hold sample plugin templates.
|
|
||||||
|
|
||||||
These are NOT intended to be used except for testing by developers.
|
|
||||||
|
|
||||||
Build these plugins with the Mapnik build system:
|
|
||||||
|
|
||||||
./configure SAMPLE_INPUT_PLUGINS=True
|
|
||||||
make install
|
|
||||||
|
|
||||||
Or develop them locally using the `Makefile` provided.
|
|
||||||
|
|
||||||
Only an ultra-simple hello world is available currently,
|
|
||||||
but planned are example plugins templates for file-based
|
|
||||||
and sql-based datasources.
|
|
|
@ -1,30 +0,0 @@
|
||||||
# To use clang, run: make CXX=clang++
|
|
||||||
|
|
||||||
CXXFLAGS = $(shell mapnik-config --cflags) -fPIC
|
|
||||||
|
|
||||||
LIBS = $(shell mapnik-config --libs --ldflags --dep-libs)
|
|
||||||
|
|
||||||
SRC = $(wildcard *.cpp)
|
|
||||||
|
|
||||||
OBJ = $(SRC:.cpp=.o)
|
|
||||||
|
|
||||||
BIN = hello.input
|
|
||||||
|
|
||||||
all : $(SRC) $(BIN)
|
|
||||||
|
|
||||||
$(BIN) : $(OBJ)
|
|
||||||
$(CXX) -shared $(OBJ) $(LIBS) -o $@
|
|
||||||
|
|
||||||
.cpp.o :
|
|
||||||
$(CXX) -c $(CXXFLAGS) $< -o $@
|
|
||||||
|
|
||||||
.PHONY : clean
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(OBJ)
|
|
||||||
rm -f $(BIN)
|
|
||||||
|
|
||||||
deploy : all
|
|
||||||
cp hello.input $(shell mapnik-config --input-plugins)
|
|
||||||
|
|
||||||
install: all deploy
|
|
|
@ -1,40 +0,0 @@
|
||||||
## hello world plugin
|
|
||||||
|
|
||||||
This is a very simple sample plugin. It is designed to help developers
|
|
||||||
see the skeletal basics needed to achieve a functional datasource plugin.
|
|
||||||
|
|
||||||
It is not a model plugin of best practices as much as a model of the bare
|
|
||||||
minimum you need to have a working plugin that returns a single feature.
|
|
||||||
|
|
||||||
Code comments attempt to highlight which code is mandatory, which is
|
|
||||||
simply recommended, and which is purely fluff used to get the plugin to
|
|
||||||
actually show some data.
|
|
||||||
|
|
||||||
When added to a map it provides a single point geometry representing
|
|
||||||
the center of any query. This means that it should place a point in
|
|
||||||
the middle of any map tile and display a "hello world!" label if used like:
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Map srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" background-color="white">
|
|
||||||
<Style name="style">
|
|
||||||
<Rule>
|
|
||||||
<PointSymbolizer />
|
|
||||||
<TextSymbolizer name="[key]" face_name="DejaVu Sans Book" size="10" dx="5" dy="5"/>
|
|
||||||
</Rule>
|
|
||||||
</Style>
|
|
||||||
<Layer name="test" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
|
|
||||||
<StyleName>style</StyleName>
|
|
||||||
<Datasource>
|
|
||||||
<Parameter name="type">hello</Parameter>
|
|
||||||
</Datasource>
|
|
||||||
</Layer>
|
|
||||||
</Map>
|
|
||||||
```
|
|
||||||
|
|
||||||
Or used in python like:
|
|
||||||
|
|
||||||
```
|
|
||||||
import mapnik
|
|
||||||
ds = mapnik.Datasource(type="hello")
|
|
||||||
```
|
|
|
@ -1,86 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
# Mapnik uses the build tool SCons.
|
|
||||||
|
|
||||||
# This python file is run to compile a plugin
|
|
||||||
# It must be called from the main 'SConstruct' file like:
|
|
||||||
|
|
||||||
# SConscript('path/to/this/file.py')
|
|
||||||
|
|
||||||
# see docs at: http://www.scons.org/wiki/SConscript()
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Here we pull from the SCons environment exported from the main instance
|
|
||||||
Import ('plugin_base')
|
|
||||||
Import ('env')
|
|
||||||
|
|
||||||
# Give this plugin a name
|
|
||||||
# here this happens to be the same as the directory
|
|
||||||
PLUGIN_NAME = 'hello'
|
|
||||||
|
|
||||||
# the below install details are also pulled from the
|
|
||||||
# main SConstruct file where configuration happens
|
|
||||||
|
|
||||||
# clone the environment here
|
|
||||||
# so that if we modify the env it in this file
|
|
||||||
# those changes to not pollute other builds later on...
|
|
||||||
plugin_env = plugin_base.Clone()
|
|
||||||
|
|
||||||
# Add the cpp files that need to be compiled
|
|
||||||
plugin_sources = Split(
|
|
||||||
"""
|
|
||||||
%(PLUGIN_NAME)s_datasource.cpp
|
|
||||||
%(PLUGIN_NAME)s_featureset.cpp
|
|
||||||
""" % locals()
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add any external libraries this plugin should
|
|
||||||
# directly link to
|
|
||||||
libraries = [ '' ] # eg 'libfoo'
|
|
||||||
|
|
||||||
libraries.append('boost_system%s' % env['BOOST_APPEND'])
|
|
||||||
# link libicuuc, but ICU_LIB_NAME is used custom builds of icu can
|
|
||||||
# have different library names like osx which offers /usr/lib/libicucore.dylib
|
|
||||||
libraries.append(env['ICU_LIB_NAME'])
|
|
||||||
|
|
||||||
# this is valid if we are building an external plugin as shared library
|
|
||||||
if env['PLUGIN_LINKING'] == 'shared':
|
|
||||||
# plugins can go anywhere, and be registered in custom locations by Mapnik
|
|
||||||
# but the standard location is '/usr/local/lib/mapnik/input'
|
|
||||||
install_dest = env['MAPNIK_INPUT_PLUGINS_DEST']
|
|
||||||
|
|
||||||
# only link mapnik if we are build an external shared object
|
|
||||||
libraries.append(env['MAPNIK_NAME'])
|
|
||||||
|
|
||||||
TARGET = plugin_env.SharedLibrary(
|
|
||||||
# the name of the target to build, eg 'sqlite.input'
|
|
||||||
'../%s' % PLUGIN_NAME,
|
|
||||||
# prefix - normally none used
|
|
||||||
SHLIBPREFIX='',
|
|
||||||
# extension, mapnik expects '.input'
|
|
||||||
SHLIBSUFFIX='.input',
|
|
||||||
# list of source files to compile
|
|
||||||
source=plugin_sources,
|
|
||||||
# libraries to link to
|
|
||||||
LIBS=libraries
|
|
||||||
)
|
|
||||||
|
|
||||||
# if the plugin links to libmapnik ensure it is built first
|
|
||||||
Depends(TARGET, env.subst('../../../../src/%s' % env['MAPNIK_LIB_NAME']))
|
|
||||||
|
|
||||||
# if 'uninstall' is not passed on the command line
|
|
||||||
# then we actually create the install targets that
|
|
||||||
# scons will install if 'install' is passed as an arg
|
|
||||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
|
||||||
env.Install(install_dest, TARGET)
|
|
||||||
env.Alias('install', install_dest)
|
|
||||||
|
|
||||||
# Return the plugin building options to scons
|
|
||||||
# This is used when statically linking the plugin with mapnik)
|
|
||||||
plugin_obj = {
|
|
||||||
'LIBS': libraries,
|
|
||||||
'SOURCES': plugin_sources,
|
|
||||||
}
|
|
||||||
|
|
||||||
Return('plugin_obj')
|
|
|
@ -1,76 +0,0 @@
|
||||||
// file plugin
|
|
||||||
#include "hello_datasource.hpp"
|
|
||||||
#include "hello_featureset.hpp"
|
|
||||||
|
|
||||||
// boost
|
|
||||||
|
|
||||||
|
|
||||||
using mapnik::datasource;
|
|
||||||
using mapnik::parameters;
|
|
||||||
|
|
||||||
DATASOURCE_PLUGIN(hello_datasource)
|
|
||||||
|
|
||||||
hello_datasource::hello_datasource(parameters const& params)
|
|
||||||
: datasource(params),
|
|
||||||
desc_(hello_datasource::name(), *params.get<std::string>("encoding","utf-8")),
|
|
||||||
extent_()
|
|
||||||
{
|
|
||||||
this->init(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hello_datasource::init(mapnik::parameters const& params)
|
|
||||||
{
|
|
||||||
// every datasource must have some way of reporting its extent
|
|
||||||
// in this case we are not actually reading from any data so for fun
|
|
||||||
// let's just create a world extent in Mapnik's default srs:
|
|
||||||
// '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs' (equivalent to +init=epsg:4326)
|
|
||||||
// see http://spatialreference.org/ref/epsg/4326/ for more details
|
|
||||||
extent_.init(-180,-90,180,90);
|
|
||||||
}
|
|
||||||
|
|
||||||
hello_datasource::~hello_datasource() { }
|
|
||||||
|
|
||||||
// This name must match the plugin filename, eg 'hello.input'
|
|
||||||
const char * hello_datasource::name()
|
|
||||||
{
|
|
||||||
return "hello";
|
|
||||||
}
|
|
||||||
|
|
||||||
mapnik::datasource::datasource_t hello_datasource::type() const
|
|
||||||
{
|
|
||||||
return datasource::Vector;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapnik::box2d<double> hello_datasource::envelope() const
|
|
||||||
{
|
|
||||||
return extent_;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::optional<mapnik::datasource_geometry_t> hello_datasource::get_geometry_type() const
|
|
||||||
{
|
|
||||||
return mapnik::datasource_geometry_t::Point;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapnik::layer_descriptor hello_datasource::get_descriptor() const
|
|
||||||
{
|
|
||||||
return desc_;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapnik::featureset_ptr hello_datasource::features(mapnik::query const& q) const
|
|
||||||
{
|
|
||||||
// if the query box intersects our world extent then query for features
|
|
||||||
if (extent_.intersects(q.get_bbox()))
|
|
||||||
{
|
|
||||||
return std::make_shared<hello_featureset>(q.get_bbox(),desc_.get_encoding());
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise return an empty featureset pointer
|
|
||||||
return mapnik::featureset_ptr();
|
|
||||||
}
|
|
||||||
|
|
||||||
mapnik::featureset_ptr hello_datasource::features_at_point(mapnik::coord2d const& pt, double tol) const
|
|
||||||
{
|
|
||||||
// features_at_point is rarely used - only by custom applications,
|
|
||||||
// so for this sample plugin let's do nothing...
|
|
||||||
return mapnik::featureset_ptr();
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
#ifndef FILE_DATASOURCE_HPP
|
|
||||||
#define FILE_DATASOURCE_HPP
|
|
||||||
|
|
||||||
// mapnik
|
|
||||||
#include <mapnik/datasource.hpp>
|
|
||||||
#include <mapnik/params.hpp>
|
|
||||||
#include <mapnik/query.hpp>
|
|
||||||
#include <mapnik/feature.hpp>
|
|
||||||
#include <mapnik/box2d.hpp>
|
|
||||||
#include <mapnik/coord.hpp>
|
|
||||||
#include <mapnik/feature_layer_desc.hpp>
|
|
||||||
|
|
||||||
// boost
|
|
||||||
#include <boost/optional.hpp>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
// stl
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class hello_datasource : public mapnik::datasource
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// constructor
|
|
||||||
// arguments must not change
|
|
||||||
hello_datasource(mapnik::parameters const& params);
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
virtual ~hello_datasource ();
|
|
||||||
|
|
||||||
// mandatory: type of the plugin, used to match at runtime
|
|
||||||
mapnik::datasource::datasource_t type() const;
|
|
||||||
|
|
||||||
// mandatory: name of the plugin
|
|
||||||
static const char * name();
|
|
||||||
|
|
||||||
// mandatory: function to query features by box2d
|
|
||||||
// this is called when rendering, specifically in feature_style_processor.hpp
|
|
||||||
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
|
||||||
|
|
||||||
// mandatory: function to query features by point (coord2d)
|
|
||||||
// not used by rendering, but available to calling applications
|
|
||||||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const;
|
|
||||||
|
|
||||||
// mandatory: return the box2d of the datasource
|
|
||||||
// called during rendering to determine if the layer should be processed
|
|
||||||
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
|
|
||||||
mapnik::layer_descriptor get_descriptor() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// recommended - do intialization in a so-named init function
|
|
||||||
// to reduce code in constructor
|
|
||||||
void init(mapnik::parameters const& params);
|
|
||||||
// recommended naming convention of datasource members:
|
|
||||||
// name_, type_, extent_, and desc_
|
|
||||||
static const std::string name_;
|
|
||||||
mapnik::layer_descriptor desc_;
|
|
||||||
mapnik::box2d<double> extent_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // FILE_DATASOURCE_HPP
|
|
|
@ -1,69 +0,0 @@
|
||||||
// mapnik
|
|
||||||
#include <mapnik/feature_factory.hpp>
|
|
||||||
#include <mapnik/value_types.hpp>
|
|
||||||
|
|
||||||
// boost
|
|
||||||
|
|
||||||
#include "hello_featureset.hpp"
|
|
||||||
|
|
||||||
hello_featureset::hello_featureset(mapnik::box2d<double> const& box, std::string const& encoding)
|
|
||||||
: box_(box),
|
|
||||||
feature_id_(1),
|
|
||||||
tr_(new mapnik::transcoder(encoding)),
|
|
||||||
ctx_(std::make_shared<mapnik::context_type>())
|
|
||||||
{
|
|
||||||
// add known field names to attributes schema
|
|
||||||
ctx_->push("key");
|
|
||||||
}
|
|
||||||
|
|
||||||
hello_featureset::~hello_featureset() { }
|
|
||||||
|
|
||||||
mapnik::feature_ptr hello_featureset::next()
|
|
||||||
{
|
|
||||||
if (feature_id_ == 1)
|
|
||||||
{
|
|
||||||
// create a new feature
|
|
||||||
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_));
|
|
||||||
|
|
||||||
// increment the count
|
|
||||||
++feature_id_;
|
|
||||||
|
|
||||||
// create an attribute pair of key:value
|
|
||||||
feature->put("key",tr_->transcode("hello world point!"));
|
|
||||||
|
|
||||||
// take the center of the bbox that was used to query
|
|
||||||
// to dynamically generate a fake point
|
|
||||||
mapnik::coord2d center = box_.center();
|
|
||||||
|
|
||||||
// create a new point geometry
|
|
||||||
feature->set_geometry(mapnik::geometry::point<double>(center.x,center.y));
|
|
||||||
|
|
||||||
// return the feature!
|
|
||||||
return feature;
|
|
||||||
}
|
|
||||||
else if (feature_id_ == 2)
|
|
||||||
{
|
|
||||||
// create a second feature
|
|
||||||
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_));
|
|
||||||
|
|
||||||
// increment the count
|
|
||||||
++feature_id_;
|
|
||||||
|
|
||||||
// create an attribute pair of key:value
|
|
||||||
feature->put("key",tr_->transcode("hello world line!"));
|
|
||||||
|
|
||||||
// take the outer ring of the bbox that was used to query
|
|
||||||
// to dynamically generate a fake line
|
|
||||||
mapnik::geometry::line_string<double> line;
|
|
||||||
line.reserve(4);
|
|
||||||
line.add_coord(box_.minx(),box_.maxy());
|
|
||||||
line.add_coord(box_.maxx(),box_.maxy());
|
|
||||||
line.add_coord(box_.maxx(),box_.miny());
|
|
||||||
line.add_coord(box_.minx(),box_.miny());
|
|
||||||
feature->set_geometry(std::move(line));
|
|
||||||
return feature;
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise return an empty feature
|
|
||||||
return mapnik::feature_ptr();
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
#ifndef HELLO_FEATURESET_HPP
|
|
||||||
#define HELLO_FEATURESET_HPP
|
|
||||||
|
|
||||||
// mapnik
|
|
||||||
#include <mapnik/datasource.hpp>
|
|
||||||
#include <mapnik/feature.hpp>
|
|
||||||
#include <mapnik/unicode.hpp>
|
|
||||||
|
|
||||||
// boost
|
|
||||||
// needed for wrapping the transcoder
|
|
||||||
|
|
||||||
class hello_featureset : public mapnik::Featureset
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// this constructor can have any arguments you need
|
|
||||||
hello_featureset(mapnik::box2d<double> const& box, std::string const& encoding);
|
|
||||||
|
|
||||||
// desctructor
|
|
||||||
virtual ~hello_featureset();
|
|
||||||
|
|
||||||
// mandatory: you must expose a next() method, called when rendering
|
|
||||||
mapnik::feature_ptr next();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// members are up to you, but these are recommended
|
|
||||||
mapnik::box2d<double> box_;
|
|
||||||
mapnik::value_integer feature_id_;
|
|
||||||
const std::unique_ptr<mapnik::transcoder> tr_;
|
|
||||||
mapnik::context_ptr ctx_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // HELLO_FEATURESET_HPP
|
|
|
@ -1,19 +0,0 @@
|
||||||
<Map srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" background-color="white" minimum-version="0.7.2">
|
|
||||||
<Style name="style">
|
|
||||||
<Rule>
|
|
||||||
<PointSymbolizer/>
|
|
||||||
<!-- the hello world sample hardcodes 'key' as the hypothetical field name -->
|
|
||||||
<TextSymbolizer name="[key]" size="10" dx="5" dy="5" face-name="DejaVu Sans Book"/>
|
|
||||||
<LineSymbolizer stroke="green" stroke-width="3"/>
|
|
||||||
</Rule>
|
|
||||||
</Style>
|
|
||||||
<!-- this example only works in EPSG:4326 -->
|
|
||||||
<Layer name="test" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
|
|
||||||
<StyleName>style</StyleName>
|
|
||||||
<Datasource>
|
|
||||||
<!-- here we create a 'hello' type datasource which simply
|
|
||||||
displays a point in the middle of the world's boundin box -->
|
|
||||||
<Parameter name="type">hello</Parameter>
|
|
||||||
</Datasource>
|
|
||||||
</Layer>
|
|
||||||
</Map>
|
|
|
@ -1,55 +0,0 @@
|
||||||
#include "catch.hpp"
|
|
||||||
|
|
||||||
#include <mapnik/datasource_cache.hpp>
|
|
||||||
#include <mapnik/datasource.hpp>
|
|
||||||
#include <mapnik/util/fs.hpp>
|
|
||||||
|
|
||||||
TEST_CASE("datasources") {
|
|
||||||
|
|
||||||
SECTION("hello world") {
|
|
||||||
|
|
||||||
std::string plugin("./plugins/input/templates/hello.input");
|
|
||||||
if (mapnik::util::exists(plugin))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mapnik::datasource_cache::instance().register_datasource(plugin);
|
|
||||||
mapnik::parameters p;
|
|
||||||
p["type"]="hello";
|
|
||||||
mapnik::datasource_ptr ds = mapnik::datasource_cache::instance().create(p);
|
|
||||||
mapnik::box2d<double> bbox = ds->envelope();
|
|
||||||
mapnik::query q(bbox);
|
|
||||||
mapnik::featureset_ptr fs = ds->features(q);
|
|
||||||
REQUIRE( fs != mapnik::featureset_ptr() );
|
|
||||||
mapnik::feature_ptr feat1 = fs->next();
|
|
||||||
REQUIRE( feat1 != mapnik::feature_ptr() );
|
|
||||||
mapnik::feature_ptr feat2 = fs->next();
|
|
||||||
REQUIRE( feat2 != mapnik::feature_ptr() );
|
|
||||||
REQUIRE( fs->next() == mapnik::feature_ptr() );
|
|
||||||
REQUIRE( feat1->id() == static_cast<mapnik::value_integer>(1) );
|
|
||||||
REQUIRE( feat2->id() == static_cast<mapnik::value_integer>(2) );
|
|
||||||
auto const& geom1 = feat1->get_geometry();
|
|
||||||
REQUIRE( geom1.is<mapnik::geometry::point<double> >() );
|
|
||||||
auto const& point = mapnik::util::get<mapnik::geometry::point<double> >(geom1);
|
|
||||||
REQUIRE( point.x == bbox.center().x );
|
|
||||||
REQUIRE( point.y == bbox.center().y );
|
|
||||||
auto const& geom2 = feat2->get_geometry();
|
|
||||||
REQUIRE( geom2.is<mapnik::geometry::line_string<double> >() );
|
|
||||||
auto const& line = mapnik::util::get<mapnik::geometry::line_string<double> >(geom2);
|
|
||||||
REQUIRE( line.size() == 4 );
|
|
||||||
REQUIRE( line[0].x == bbox.minx() );
|
|
||||||
REQUIRE( line[0].y == bbox.maxy() );
|
|
||||||
}
|
|
||||||
catch (std::exception const& ex)
|
|
||||||
{
|
|
||||||
FAIL(ex.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WARN( std::string("could not register ") + plugin );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue