Merge branch 'svg-parser-errors' into large_csv

This commit is contained in:
artemp 2015-07-31 11:18:55 +02:00
commit f9bd21eeb5
125 changed files with 3130 additions and 5774 deletions

2
.gitmodules vendored
View file

@ -1,6 +1,8 @@
[submodule "test/data"]
path = test/data
url = https://github.com/mapnik/test-data.git
branch = master
[submodule "test/data-visual"]
path = test/data-visual
url = https://github.com/mapnik/test-data-visual.git
branch = master

View file

@ -6,44 +6,134 @@ Developers: Please commit along with changes.
For a complete change history, see the git log.
## 3.0.1
Released: July 27th, 2015
(Packaged from 28f6f4d)
#### Summary
The 3.0.1 fixes a few bugs in geojson parsing, svg parsing, and rendering. It also avoids a potential hang when using `line-geometry-transform` and includes a speedup for text rendering compared to v3.0.0. It is fully back compatibility with v3.0.0 and everyone is encouraged to upgrade.
- Fixed text placement performance after #2949 (#2963)
- Fixed rendering behavior for `text-minimum-path-length` which regressed in 3.0.0 (#2990)
- Fixed handling of `xml:id` in SVG parsing (#2989)
- Fixed handling of out of range `rx` and `ry` in SVG `rect` (#2991)
- Fixed reporting of envelope from `mapnik::memory_datasource` when new features are added (#2985)
- Fixed parsing of GeoJSON when unknown properties encountered at `FeatureCollection` level (#2983)
- Fixed parsing of GeoJSON when properties contained `{}` (#2964)
- Fixed potential hang due to invalid use of `line-geometry-transform` (6d6cb15)
- Moved unmaintained plugins out of core: `osm`, `occi`, and `rasterlite` (#2980)
## 3.0.0
- Added new and experimental `dot` symbolizer for fast rendering of points
Released: July 7th, 2015
(Packaged from e6891a0)
#### Summary
The 3.0 release is a major milestone for Mapnik and includes many performance and design improvements. The is the first release to provide text shaping using the harfbuzz library. This harfbuzz support unlocks improved rendering and layer for many new languages, particularly SE Asian scripts. The internal storage for working with images and geometries has been made more flexible, faster, and strongly typed. The python bindings that were previously bundled with Mapnik have now been moved to <https://github.com/mapnik/python-mapnik> and are versioned independently.
#### Notice
- Mapnik 3.0.0 requires a compiler capable of `std=c++11`.
- It is highly recommended you use the `clang++` compiler on both OS X and Linux since it has robust c++11 support lower memory requirements.
##### Major Changes
- Improved support for International Text (now uses harfbuzz library for text shaping)
- Uses latest c++11 features for better performance (especially map loading)
- Uses latest C++11 features for better performance (especially map loading)
- Expressions everywhere: all symbolizer properties can now be data driven expressions (with the exception of `face-name` and `fontset-name` on the `TextSymbolizer`).
- Rewritten geometry storage based on `std::vector` (#2739)
- Separate storage of polygon exterior rings and interior rings to allow for more robust clipping of parts.
- Enforces consistent winding order per OGC spec (exterior rings are CCW, interior CW)
- Reduced memory consumption for layers with many points
- Ability to adapt Mapnik geometries to boost::geometry operations (in a zero-copy way)
- Ability to have i/o grammars for json/wkt work on geometries rather than paths for better efficiency and simpler code
- Added new and experimental `dot` symbolizer for fast rendering of points
- New functions supported in expressions: `exp`, `sin`, `cos`, `tan`, `atan`, `abs`.
- New constants supported in expressions: `PI`, `DEG_TO_RAD`, `RAD_TO_DEG`
- Added support for a variety of different grayscale images:
- `mapnik.imageType.null`
- `mapnik.imageType.rgba8`
- `mapnik.imageType.gray8`
- `mapnik.imageType.gray8s`
- `mapnik.imageType.gray16`
- `mapnik.imageType.gray16s`
- `mapnik.imageType.gray32`
- `mapnik.imageType.gray32s`
- `mapnik.imageType.gray32f`
- `mapnik.imageType.gray64`
- `mapnik.imageType.gray64s`
- `mapnik.imageType.gray64f`
- Pattern symbolizers now support SVG input and applying transformations on them dynamically
- Experimental / interface may change: `@variables` can be passed to renderer and evaluated in expressions
- Supports being built with clang++ using `-fvisibility=hidden -flto` for smaller binaries
- Supports being built with Visual Studio 2014 CTP #3
- Shield icons are now pixel snapped for crisp rendering
- `MarkersSymbolizer` now supports `avoid-edges`, `offset`, `geometry-transform`, `simplify` for `line` placement and two new `placement` options called `vertex-last` and `vertex-first` to place a single marker at the end or beginning of a path. Also `clip` is now respected when rendering markers on a LineString
geometry.
- `TextSymbolizer` now supports `smooth`, `simplify`, `halo-opacity`, `halo-comp-op`, and `halo-transform`
- `ShieldSymbolizer` now supports `smooth`, `simplify`, `halo-opacity`, `halo-comp-op`, and `halo-transform`
- The `text-transform` property of `TextSymbolizer` now supports `reverse` value to flip direction of text.
- The `TextSymbolizer` now supports `font-feature-settings` for advanced control over Opentype font rendering (https://developer.mozilla.org/en-US/docs/Web/CSS/font-feature-settings)
- New GroupSymbolizer for applying multiple symbolizers in a single layout
Released ...
(Packaged from ...)
Summary: TODO
- PostGIS: Added support for rendering 3D and 4D geometries (previously silently skipped) (#44)
- AGG renderer: fixed geometry offsetting to work after smoothing to produce more consistent results (#2202)
- AGG renderer: increased `vertex_dist_epsilon` to ensure nearly coincident points are discarded more readily (#2196)
- GDAL plugin: Added back support for user driven `nodata` on rgb(a) images (#2023)
- GDAL plugin
- Now keeps datasets open for the lifetime of the datasource (rather than per featureset)
- Added back support for user driven `nodata` on rgb(a) images (#2023)
- Allowed nodata to override alpha band if set on rgba images (#2023)
- Added `nodata_tolerance` option to set nearby pixels transparent (has similar effect to the `nearblack` program) (#2023)
- At process exit Mapnik core no longer calls `dlclose` on gdal.input (#2716)
- GDAL plugin: Allowed nodata to override alpha band if set on rgba images (#2023)
- TopoJSON plugin
- Now supporting optional `bbox` property on layer
- Fixed support for reporting correct `feature.id()`
- Now supports `inline` string for passing data from memory
- Faster parsing via static initialization of grammars
- Fix crash on invalid arc index
- GDAL plugin: Added `nodata_tolerance` option to set nearby pixels transparent (has similar effect to the `nearblack` program) (#2023)
- GeoJSON plugin
- Now supporting optional `bbox` property on layer
- Fixed support for reporting correct `feature.id()`
- Now supports `inline` string for passing data from memory
- Faster parsing via static initialization of grammars
- Added support for web fonts: .woff format (#2113)
- SQLite plugin
- Fixed support for handling all column types
- CSV Plugin
- Added the ability to pass an `extent` in options
- PostGIS plugin
- Added Async support to - https://github.com/mapnik/mapnik/wiki/PostGIS-Async
- Added support for rendering 3D and 4D geometries (previously silently skipped) (#44)
- Added support for web fonts: `.woff` format (#2113)
- Added missing support for `geometry-transform` in `line-pattern` and `polygon-pattern` symbolizers (#2065)
@ -51,11 +141,9 @@ Summary: TODO
- Upgraded unifont to `unifont-6.3.20131020`
- CSV Plugin: added the ability to pass an `extent` in options
- Fixed crash when rendering to cairo context from python (#2031)
- Moved `label-position-tolerance` from unsigned type to double
- Moved `label-position-tolerance` from `unsigned` type to `double`
- Added support for more seamless blurring by rendering to a larger internal image to avoid edge effects (#1478)
@ -67,8 +155,6 @@ Summary: TODO
- Added `color-to-alpha` `image-filter` to allow for applying alpha in proportion to color similiarity (#2023)
- Added Async support to PostGIS plugin - https://github.com/mapnik/mapnik/wiki/PostGIS-Async
- Fixed alpha handling bug with `comp-op:dst-over` (#1995)
- Fixed alpha handling bug with building-fill-opacity (#2011)
@ -133,6 +219,9 @@ are not set. (#1966)
- Added `scale-hsla` image-filter that allows scaling colors in HSL color space. RGB is converted to HSL (hue-saturation-lightness) and then each value (and the original alpha value) is stretched based on the specified scaling values. An example syntax is `scale-hsla(0,1,0,1,0,1,0,1)` which means no change because the full range will be kept (0 for lowest, 1 for highest). Other examples are: 1) `scale-hsla(0,0,0,1,0,1,0,1)` which would force all colors to be red in hue in the same way `scale-hsla(1,1,0,1,0,1,0,1)` would, 2) `scale-hsla(0,1,1,1,0,1,0,1)` which would cause all colors to become fully saturated, 3) `scale-hsla(0,1,1,1,0,1,.5,1)` which would force no colors to be any more transparent than half, and 4) `scale-hsla(0,1,1,1,0,1,0,.5)` which would force all colors to be at least half transparent. (#1954)
- The `shapeindex` tool now works correctly with point 3d geometry types
## 2.2.0
Released June 3rd, 2013

View file

@ -5,17 +5,23 @@ Mapnik runs on Linux, OS X, Windows, and BSD systems.
To configure and build Mapnik do:
```bash
$ ./configure
$ make
./configure
make
```
To trigger parallel compilation you can pass a JOBS value to make:
```bash
$ JOBS=4 make
JOBS=4 make
```
(Note that compiling Mapnik needs several GBytes of RAM. If you use parallel compilation it needs more.)
Mapnik needs > 2 GB of RAM to build. If you use parallel compilation it needs more.
If you are on a system with less memory make sure you only build with one JOB:
```bash
JOBS=1 make
```
To use a Python interpreter that is not named `python` for your build, do
something like the following instead:
@ -178,4 +184,4 @@ tutorials on how to programmatically use Mapnik.
### Contributers
Read docs/contributing.markdown for resources for getting involved with Mapnik development.
Read docs/contributing.md for resources for getting involved with Mapnik development.

View file

@ -12,6 +12,25 @@ all: mapnik
install:
$(PYTHON) scons/scons.py -j$(JOBS) --config=cache --implicit-cache --max-drift=1 install
release:
export MAPNIK_VERSION=$(shell ./utils/mapnik-config/mapnik-config --version) && \
export TARBALL_NAME="mapnik-v$${MAPNIK_VERSION}" && \
cd /tmp/ && \
rm -rf $${TARBALL_NAME} && \
git clone --depth 1 --branch v$${MAPNIK_VERSION} git@github.com:mapnik/mapnik.git $${TARBALL_NAME} && \
cd $${TARBALL_NAME} && \
git checkout "tags/v$${MAPNIK_VERSION}" && \
git submodule update --depth 1 --init && \
rm -rf test/data/.git && \
rm -rf test/data/.gitignore && \
rm -rf test/data-visual/.git && \
rm -rf test/data-visual/.gitignore && \
rm -rf .git && \
rm -rf .gitignore && \
cd ../ && \
tar cjf $${TARBALL_NAME}.tar.bz2 $${TARBALL_NAME}/ && \
aws s3 cp --acl public-read $${TARBALL_NAME}.tar.bz2 s3://mapnik/dist/v$${MAPNIK_VERSION}/
python:
if [ ! -d ./bindings/python ]; then git clone git@github.com:mapnik/python-mapnik.git --recursive ./bindings/python; else (cd bindings/python && git pull && git submodule update --init); fi;
make

View file

@ -110,14 +110,7 @@ PLUGINS = { # plugins with external dependencies
'pgraster': {'default':True,'path':None,'inc':'libpq-fe.h','lib':'pq','lang':'C'},
'gdal': {'default':True,'path':None,'inc':'gdal_priv.h','lib':'gdal','lang':'C++'},
'ogr': {'default':True,'path':None,'inc':'ogrsf_frmts.h','lib':'gdal','lang':'C++'},
# configured with custom paths, hence 'path': PREFIX/INCLUDES/LIBS
'occi': {'default':False,'path':'OCCI','inc':'occi.h','lib':'clntsh','lang':'C++'},
'sqlite': {'default':True,'path':'SQLITE','inc':'sqlite3.h','lib':'sqlite3','lang':'C'},
'rasterlite': {'default':False,'path':'RASTERLITE','inc':['sqlite3.h','rasterlite.h'],'lib':'rasterlite','lang':'C'},
# todo: osm plugin does also depend on libxml2 (but there is a separate check for that)
'osm': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C'},
# plugins without external dependencies requiring CheckLibWithHeader...
'shape': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
'csv': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
@ -402,7 +395,7 @@ opts.AddVariables(
BoolVariable('FULL_LIB_PATH', 'Embed the full and absolute path to libmapnik when linking ("install_name" on OS X/rpath on Linux)', 'True'),
BoolVariable('ENABLE_SONAME', 'Embed a soname in libmapnik on Linux', 'True'),
EnumVariable('THREADING','Set threading support','multi', ['multi','single']),
EnumVariable('XMLPARSER','Set xml parser','libxml2', ['libxml2','ptree']),
EnumVariable('XMLPARSER','Set xml parser','ptree', ['libxml2','ptree']),
BoolVariable('DEMO', 'Compile demo c++ application', 'True'),
BoolVariable('PGSQL2SQLITE', 'Compile and install a utility to convert postgres tables to sqlite', 'False'),
BoolVariable('SHAPEINDEX', 'Compile and install a utility to generate shapefile indexes in the custom format (.index) Mapnik supports', 'True'),
@ -1273,18 +1266,19 @@ if not preconfigured:
# libxml2 should be optional but is currently not
# https://github.com/mapnik/mapnik/issues/913
if env.get('XML2_LIBS') or env.get('XML2_INCLUDES'):
REQUIRED_LIBSHEADERS.insert(0,['libxml2','libxml/parser.h',True,'C'])
if env.get('XML2_INCLUDES'):
inc_path = env['XML2_INCLUDES']
env.AppendUnique(CPPPATH = fix_path(inc_path))
if env.get('XML2_LIBS'):
lib_path = env['XML2_LIBS']
env.AppendUnique(LIBPATH = fix_path(lib_path))
elif conf.parse_config('XML2_CONFIG',checks='--cflags'):
env['HAS_LIBXML2'] = True
else:
env['MISSING_DEPS'].append('libxml2')
if env.get('XMLPARSER') and env['XMLPARSER'] == 'libxml2':
if env.get('XML2_LIBS') or env.get('XML2_INCLUDES'):
OPTIONAL_LIBSHEADERS.insert(0,['libxml2','libxml/parser.h',True,'C'])
if env.get('XML2_INCLUDES'):
inc_path = env['XML2_INCLUDES']
env.AppendUnique(CPPPATH = fix_path(inc_path))
if env.get('XML2_LIBS'):
lib_path = env['XML2_LIBS']
env.AppendUnique(LIBPATH = fix_path(lib_path))
elif conf.parse_config('XML2_CONFIG',checks='--cflags'):
env['HAS_LIBXML2'] = True
else:
env['MISSING_DEPS'].append('libxml2')
if not env['HOST']:
if conf.CheckHasDlfcn():
@ -1904,6 +1898,8 @@ if not HELP_REQUESTED:
# Build the requested and able-to-be-compiled input plug-ins
GDAL_BUILT = False
OGR_BUILT = False
POSTGIS_BUILT = False
PGRASTER_BUILT = False
for plugin in env['PLUGINS']:
if env['PLUGIN_LINKING'] == 'static' or plugin not in env['REQUESTED_PLUGINS']:
if os.path.exists('plugins/input/%s.input' % plugin):
@ -1913,11 +1909,17 @@ if not HELP_REQUESTED:
if details['lib'] in env['LIBS']:
if env['PLUGIN_LINKING'] == 'shared':
SConscript('plugins/input/%s/build.py' % plugin)
# hack to avoid breaking on plugins with the same dep
if plugin == 'ogr': OGR_BUILT = True
if plugin == 'gdal': GDAL_BUILT = True
if plugin == 'postgis': POSTGIS_BUILT = True
if plugin == 'pgraster': PGRASTER_BUILT = True
if plugin == 'ogr' or plugin == 'gdal':
if GDAL_BUILT and OGR_BUILT:
env['LIBS'].remove(details['lib'])
elif plugin == 'postgis' or plugin == 'pgraster':
if POSTGIS_BUILT and PGRASTER_BUILT:
env['LIBS'].remove(details['lib'])
else:
env['LIBS'].remove(details['lib'])
elif not details['lib']:

View file

@ -46,6 +46,7 @@ benchmarks = [
"test_offset_converter.cpp",
"test_marker_cache.cpp",
"test_quad_tree.cpp",
"test_noop_rendering.cpp",
# "test_numeric_cast_vs_static_cast.cpp",
]
for cpp_test in benchmarks:

View file

@ -29,19 +29,7 @@ namespace benchmark {
image_rgba8 const& dest = util::get<image_rgba8>(desc_any);
image_rgba8 const& src = util::get<image_rgba8>(src_any);
unsigned int width = src.width();
unsigned int height = src.height();
if ((width != dest.width()) || height != dest.height()) return false;
for (unsigned int y = 0; y < height; ++y)
{
const unsigned int* row_from = src.get_row(y);
const unsigned int* row_to = dest.get_row(y);
for (unsigned int x = 0; x < width; ++x)
{
if (row_from[x] != row_to[x]) return false;
}
}
return true;
return compare(dest, src, 0, true) == 0;
}
}

View file

@ -55,5 +55,5 @@ run test_offset_converter 10 1000
--threads 1
./benchmark/out/test_quad_tree \
--iterations 10000 \
--iterations 1000 \
--threads 10

View file

@ -0,0 +1,53 @@
#include "bench_framework.hpp"
#include <mapnik/map.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/load_map.hpp>
#include <mapnik/agg_renderer.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/font_engine_freetype.hpp>
#include <stdexcept>
#include <mapnik/layer.hpp>
#include <mapnik/memory_datasource.hpp>
#include <mapnik/feature_type_style.hpp>
#include <memory>
class test : public benchmark::test_case
{
public:
test(mapnik::parameters const& params)
: test_case(params) {}
bool validate() const
{
return true;
}
bool operator()() const
{
mapnik::Map m(256,256,"+init=epsg:3857");
mapnik::parameters params;
params["type"]="memory";
auto ds = std::make_shared<mapnik::memory_datasource>(params);
// add whitespace to trigger phony "reprojection"
mapnik::layer lay("layer",m.srs() + " ");
lay.set_datasource(ds);
lay.add_style("style");
m.add_layer(lay);
// dummy style to ensure that layer is processed
m.insert_style("style",mapnik::feature_type_style());
// dummy bbox, but "valid" because minx and miny are less
// with an invalid bbox then layer.visible() returns false
// and the initial rendering setup is not run
m.zoom_to_box(mapnik::box2d<double>(-1,-1,0,0));
for (unsigned i=0;i<iterations_;++i)
{
mapnik::image_rgba8 im(256,256);
mapnik::agg_renderer<mapnik::image_rgba8> ren(m,im);
ren.apply();
}
return true;
}
};
BENCHMARK(test,"rendering with reprojection")

View file

@ -60,8 +60,7 @@ function install_mason_deps() {
install freetype 2.5.5 libfreetype &
install harfbuzz 0.9.40 libharfbuzz &
install jpeg_turbo 1.4.0 libjpeg &
install libxml2 2.9.2 libxml2 &
install libpng 1.6.16 libpng &
install libpng 1.6.17 libpng &
install webp 0.4.2 libwebp &
install icu 54.1 &
install proj 4.8.0 libproj &
@ -117,8 +116,6 @@ PG_INCLUDES = '${MASON_LINKED_REL}/include'
PG_LIBS = '${MASON_LINKED_REL}/lib'
FREETYPE_INCLUDES = '${MASON_LINKED_REL}/include/freetype2'
FREETYPE_LIBS = '${MASON_LINKED_REL}/lib'
XML2_INCLUDES = '${MASON_LINKED_REL}/include/libxml2'
XML2_LIBS = '${MASON_LINKED_REL}/lib'
SVG_RENDERER = True
CAIRO_INCLUDES = '${MASON_LINKED_REL}/include'
CAIRO_LIBS = '${MASON_LINKED_REL}/lib'

View file

@ -652,8 +652,8 @@ struct gray16
//--------------------------------------------------------------------
self_type& opacity(double a_)
{
if (a_ < 0) a_ = 0;
else if(a_ > 1) a_ = 1;
if (a_ < 0) a = 0;
else if(a_ > 1) a = 1;
else a = (value_type)uround(a_ * double(base_mask));
return *this;
}

View file

@ -44,6 +44,20 @@ We host our code on github.com/mapnik and encourage anyone interested to fork th
If you just have a question about the code, or a feature you want to discuss then feel free to create a new issue at github.com/mapnik-support.
## Plugins
Mapnik has a plugin interface for reading various geodata formats. Plugins are both viable inside of Mapnik core and also able to be used outside of Mapnik.
Plugins should be developed outside of core except in rare cases when most of the following are met:
- The plugin has no external dependencies or dependencies are easily installed
- The plugin has excellent unit tests
- The plugin has a maintainer willing to support the plugin over time
- Setup and testing of the plugin is easy on travis.ci (see .travis.yml)
Therefore plugins that depend on proprietary, unmaintained, or difficult to test third-party dependencies are not viable for Mapnik core. However they are still likely very valuable for the Mapnik community, so get in touch via https://github.com/mapnik/mapnik-support if we can help you develop your plugin outside of core.
## Code Philosophy

View file

@ -79,8 +79,9 @@ class MAPNIK_DECL gradient
public:
gradient();
gradient(gradient const& other);
gradient& operator=(const gradient& rhs);
gradient(gradient && other);
gradient& operator=(gradient rhs);
bool operator==(gradient const& other) const;
void set_gradient_type(gradient_e grad);
gradient_e get_gradient_type() const;
@ -100,7 +101,7 @@ public:
void get_control_points(double &x1, double &y1, double &x2, double &y2) const;
private:
void swap(const gradient& other) throw();
void swap(gradient& other) throw();
};
}

View file

@ -38,7 +38,7 @@ namespace mapnik
{
//============================================================blender_gray
template<class ColorT> struct blender_gray
template<typename ColorT> struct blender_gray
{
using color_type = ColorT;
using value_type = typename color_type::value_type;
@ -55,7 +55,7 @@ template<class ColorT> struct blender_gray
//=====================================================apply_gamma_dir_gray
template<class ColorT, class GammaLut> class apply_gamma_dir_gray
template<typename ColorT, class GammaLut> class apply_gamma_dir_gray
{
public:
using value_type = typename ColorT::value_type;
@ -74,7 +74,7 @@ private:
//=====================================================apply_gamma_inv_gray
template<class ColorT, class GammaLut> class apply_gamma_inv_gray
template<typename ColorT, class GammaLut> class apply_gamma_inv_gray
{
public:
using value_type = typename ColorT::value_type;
@ -93,7 +93,7 @@ private:
//=================================================pixfmt_alpha_blend_gray
template<class Blender, class RenBuf, unsigned Step=1, unsigned Offset=0>
template<typename Blender, class RenBuf, unsigned Step=1, unsigned Offset=0>
class pixfmt_alpha_blend_gray
{
public:
@ -160,7 +160,7 @@ public:
void attach(rbuf_type& rb) { m_rbuf = &rb; }
//--------------------------------------------------------------------
template<class PixFmt>
template<typename PixFmt>
bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
{
agg::rect_i r(x1, y1, x2, y2);
@ -538,10 +538,10 @@ public:
}
//--------------------------------------------------------------------
template<class Function> void for_each_pixel(Function f)
template <typename Function>
void for_each_pixel(Function f)
{
unsigned y;
for(y = 0; y < height(); ++y)
for(unsigned y = 0; y < height(); ++y)
{
row_data r = m_rbuf->row(y);
if(r.ptr)
@ -562,19 +562,19 @@ public:
}
//--------------------------------------------------------------------
template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
template<typename GammaLut> void apply_gamma_dir(const GammaLut& g)
{
for_each_pixel(apply_gamma_dir_gray<color_type, GammaLut>(g));
}
//--------------------------------------------------------------------
template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
template<typename GammaLut> void apply_gamma_inv(const GammaLut& g)
{
for_each_pixel(apply_gamma_inv_gray<color_type, GammaLut>(g));
}
//--------------------------------------------------------------------
template<class RenBuf2>
template<typename RenBuf2>
void copy_from(const RenBuf2& from,
int xdst, int ydst,
int xsrc, int ysrc,
@ -590,7 +590,7 @@ public:
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
template<typename SrcPixelFormatRenderer>
void blend_from_color(const SrcPixelFormatRenderer& from,
const color_type& color,
int xdst, int ydst,
@ -617,7 +617,7 @@ public:
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
template<typename SrcPixelFormatRenderer>
void blend_from_lut(const SrcPixelFormatRenderer& from,
const color_type* color_lut,
int xdst, int ydst,

View file

@ -254,10 +254,10 @@ void apply_convolution_3x3(Src const& src_view, Dst & dst_view, Filter const& fi
typename Src::x_iterator dst_it = dst_view.row_begin(0);
// top row
for (std::size_t x = 0 ; x < static_cast<std::size_t>(src_view.width()); ++x)
for (std::ptrdiff_t x = 0 ; x < src_view.width(); ++x)
{
(*dst_it)[3] = src_loc[loc11][3]; // Dst.a = Src.a
for (std::size_t i = 0; i < 3; ++i)
for (std::ptrdiff_t i = 0; i < 3; ++i)
{
bits32f p[9];
@ -275,7 +275,7 @@ void apply_convolution_3x3(Src const& src_view, Dst & dst_view, Filter const& fi
p[6] = src_loc[loc02][i];
}
if ( x == static_cast<std::size_t>(src_view.width())-1)
if ( x == (src_view.width())-1)
{
p[5] = p[4];
p[8] = p[7];
@ -296,15 +296,15 @@ void apply_convolution_3x3(Src const& src_view, Dst & dst_view, Filter const& fi
++dst_it;
}
// carrige-return
src_loc += point2<std::ptrdiff_t>(-static_cast<std::size_t>(src_view.width()),1);
src_loc += point2<std::ptrdiff_t>(-src_view.width(),1);
// 1... height-1 rows
for (std::size_t y = 1; y<static_cast<std::size_t>(src_view.height())-1; ++y)
for (std::ptrdiff_t y = 1; y < src_view.height()-1; ++y)
{
for (std::size_t x = 0; x < static_cast<std::size_t>(src_view.width()); ++x)
for (std::ptrdiff_t x = 0; x < src_view.width(); ++x)
{
(*dst_it)[3] = src_loc[loc11][3]; // Dst.a = Src.a
for (std::size_t i = 0; i < 3; ++i)
for (std::ptrdiff_t i = 0; i < 3; ++i)
{
bits32f p[9];
@ -325,7 +325,7 @@ void apply_convolution_3x3(Src const& src_view, Dst & dst_view, Filter const& fi
p[6] = src_loc[loc02][i];
}
if ( x == static_cast<std::size_t>(src_view.width()) - 1)
if ( x == (src_view.width()) - 1)
{
p[2] = p[1];
p[5] = p[4];
@ -343,15 +343,15 @@ void apply_convolution_3x3(Src const& src_view, Dst & dst_view, Filter const& fi
++src_loc.x();
}
// carrige-return
src_loc += point2<std::ptrdiff_t>(-static_cast<std::size_t>(src_view.width()),1);
src_loc += point2<std::ptrdiff_t>(-src_view.width(),1);
}
// bottom row
//src_loc = src_view.xy_at(0,static_cast<std::size_t>(src_view.height())-1);
for (std::size_t x = 0 ; x < static_cast<std::size_t>(src_view.width()); ++x)
//src_loc = src_view.xy_at(0,src_view.height()-1);
for (std::ptrdiff_t x = 0 ; x < src_view.width(); ++x)
{
(*dst_it)[3] = src_loc[loc11][3]; // Dst.a = Src.a
for (std::size_t i = 0; i < 3; ++i)
for (std::ptrdiff_t i = 0; i < 3; ++i)
{
bits32f p[9];
@ -369,7 +369,7 @@ void apply_convolution_3x3(Src const& src_view, Dst & dst_view, Filter const& fi
p[3] = src_loc[loc01][i];
}
if ( x == static_cast<std::size_t>(src_view.width())-1)
if ( x == (src_view.width())-1)
{
p[2] = p[1];
p[5] = p[4];
@ -431,10 +431,10 @@ void apply_filter(Src & src, color_to_alpha const& op)
double cr = static_cast<double>(op.color.red())/255.0;
double cg = static_cast<double>(op.color.green())/255.0;
double cb = static_cast<double>(op.color.blue())/255.0;
for (std::size_t y=0; y<static_cast<std::size_t>(src_view.height()); ++y)
for (std::ptrdiff_t y = 0; y < src_view.height(); ++y)
{
rgba8_view_t::x_iterator src_it = src_view.row_begin(static_cast<long>(y));
for (std::size_t x=0; x<static_cast<std::size_t>(src_view.width()); ++x)
for (std::ptrdiff_t x = 0; x < src_view.width(); ++x)
{
uint8_t & r = get_color(src_it[x], red_t());
uint8_t & g = get_color(src_it[x], green_t());
@ -485,17 +485,17 @@ template <typename Src>
void apply_filter(Src & src, colorize_alpha const& op)
{
using namespace boost::gil;
std::size_t size = op.size();
std::ptrdiff_t size = op.size();
if (op.size() == 1)
{
// no interpolation if only one stop
mapnik::filter::color_stop const& stop = op[0];
mapnik::color const& c = stop.color;
rgba8_view_t src_view = rgba8_view(src);
for (std::size_t y=0; y<static_cast<std::size_t>(src_view.height()); ++y)
for (std::ptrdiff_t y = 0; y < src_view.height(); ++y)
{
rgba8_view_t::x_iterator src_it = src_view.row_begin(static_cast<long>(y));
for (std::size_t x=0; x<static_cast<std::size_t>(src_view.width()); ++x)
for (std::ptrdiff_t x = 0; x < src_view.width(); ++x)
{
uint8_t & r = get_color(src_it[x], red_t());
uint8_t & g = get_color(src_it[x], green_t());
@ -533,10 +533,10 @@ void apply_filter(Src & src, colorize_alpha const& op)
if (grad_lut.build_lut())
{
rgba8_view_t src_view = rgba8_view(src);
for (std::size_t y=0; y<static_cast<std::size_t>(src_view.height()); ++y)
for (std::ptrdiff_t y = 0; y < src_view.height(); ++y)
{
rgba8_view_t::x_iterator src_it = src_view.row_begin(static_cast<long>(y));
for (std::size_t x=0; x<static_cast<std::size_t>(src_view.width()); ++x)
for (std::ptrdiff_t x = 0; x < src_view.width(); ++x)
{
uint8_t & r = get_color(src_it[x], red_t());
uint8_t & g = get_color(src_it[x], green_t());
@ -598,10 +598,10 @@ void apply_filter(Src & src, scale_hsla const& transform)
if (tinting || set_alpha)
{
rgba8_view_t src_view = rgba8_view(src);
for (std::size_t y=0; y<static_cast<std::size_t>(src_view.height()); ++y)
for (std::ptrdiff_t y = 0; y < src_view.height(); ++y)
{
rgba8_view_t::x_iterator src_it = src_view.row_begin(static_cast<long>(y));
for (std::size_t x=0; x<static_cast<std::size_t>(src_view.width()); ++x)
for (std::ptrdiff_t x = 0; x < src_view.width(); ++x)
{
uint8_t & r = get_color(src_it[x], red_t());
uint8_t & g = get_color(src_it[x], green_t());
@ -681,10 +681,10 @@ void apply_filter(Src & src, gray const& /*op*/)
rgba8_view_t src_view = rgba8_view(src);
for (std::size_t y=0; y<static_cast<std::size_t>(src_view.height()); ++y)
for (std::ptrdiff_t y = 0; y < src_view.height(); ++y)
{
rgba8_view_t::x_iterator src_it = src_view.row_begin(static_cast<long>(y));
for (std::size_t x=0; x<static_cast<std::size_t>(src_view.width()); ++x)
for (std::ptrdiff_t x = 0; x < src_view.width(); ++x)
{
// formula taken from boost/gil/color_convert.hpp:rgb_to_luminance
uint8_t & r = get_color(src_it[x], red_t());
@ -699,7 +699,7 @@ void apply_filter(Src & src, gray const& /*op*/)
template <typename Src, typename Dst>
void x_gradient_impl(Src const& src_view, Dst const& dst_view)
{
for (std::size_t y=0; y<static_cast<std::size_t>(src_view.height()); ++y)
for (std::ptrdiff_t y = 0; y < src_view.height(); ++y)
{
typename Src::x_iterator src_it = src_view.row_begin(static_cast<long>(y));
typename Dst::x_iterator dst_it = dst_view.row_begin(static_cast<long>(y));
@ -708,13 +708,13 @@ void x_gradient_impl(Src const& src_view, Dst const& dst_view)
dst_it[0][1] = 128 + (src_it[0][1] - src_it[1][1]) / 2;
dst_it[0][2] = 128 + (src_it[0][2] - src_it[1][2]) / 2;
dst_it[dst_view.width()-1][0] = 128 + (src_it[static_cast<std::size_t>(src_view.width())-2][0] - src_it[static_cast<std::size_t>(src_view.width())-1][0]) / 2;
dst_it[dst_view.width()-1][1] = 128 + (src_it[static_cast<std::size_t>(src_view.width())-2][1] - src_it[static_cast<std::size_t>(src_view.width())-1][1]) / 2;
dst_it[dst_view.width()-1][2] = 128 + (src_it[static_cast<std::size_t>(src_view.width())-2][2] - src_it[static_cast<std::size_t>(src_view.width())-1][2]) / 2;
dst_it[dst_view.width()-1][0] = 128 + (src_it[(src_view.width())-2][0] - src_it[(src_view.width())-1][0]) / 2;
dst_it[dst_view.width()-1][1] = 128 + (src_it[(src_view.width())-2][1] - src_it[(src_view.width())-1][1]) / 2;
dst_it[dst_view.width()-1][2] = 128 + (src_it[(src_view.width())-2][2] - src_it[(src_view.width())-1][2]) / 2;
dst_it[0][3] = dst_it[static_cast<std::size_t>(src_view.width())-1][3] = 255;
dst_it[0][3] = dst_it[(src_view.width())-1][3] = 255;
for (std::size_t x=1; x<static_cast<std::size_t>(src_view.width())-1; ++x)
for (std::ptrdiff_t x = 1; x < src_view.width()-1; ++x)
{
dst_it[x][0] = 128 + (src_it[x-1][0] - src_it[x+1][0]) / 2;
dst_it[x][1] = 128 + (src_it[x-1][1] - src_it[x+1][1]) / 2;
@ -746,10 +746,10 @@ void apply_filter(Src & src, invert const& /*op*/)
rgba8_view_t src_view = rgba8_view(src);
for (std::size_t y=0; y<static_cast<std::size_t>(src_view.height()); ++y)
for (std::ptrdiff_t y = 0; y < src_view.height(); ++y)
{
rgba8_view_t::x_iterator src_it = src_view.row_begin(static_cast<long>(y));
for (std::size_t x=0; x<static_cast<std::size_t>(src_view.width()); ++x)
for (std::ptrdiff_t x = 0; x < src_view.width(); ++x)
{
// we only work with premultiplied source,
// thus all color values must be <= alpha

View file

@ -50,7 +50,6 @@ public:
image(image<null_t> const&) {}
image(image<null_t> &&) noexcept {}
image<null_t>& operator=(image<null_t>) { return *this; }
image<null_t>const& operator=(image<null_t> const& rhs) const { return rhs; }
bool operator==(image<null_t> const&) const { return true; }
bool operator<(image<null_t> const&) const { return false; }

View file

@ -63,10 +63,9 @@ extract_bounding_box_grammar<Iterator, ErrorHandler>::extract_bounding_box_gramm
start = features(_r1)
;
features = iter_pos[_a = _1] >> -(lit('{') >> -lit("\"type\"")
>> lit(':') >> lit("\"FeatureCollection\"")
>> *(lit(',') >> (json.key_value - lit("\"features\"")))
>> lit(',') >> lit("\"features\"")
features = iter_pos[_a = _1] >> -(lit('{')
>> *((json.key_value - lit("\"features\"")) >> lit(','))
>> lit("\"features\"")
>> lit(':'))
>> lit('[') >> (feature(_r1,_a) % lit(',')) >> lit(']')
;
@ -78,6 +77,8 @@ extract_bounding_box_grammar<Iterator, ErrorHandler>::extract_bounding_box_gramm
|
coords[_b = _1]
|
json.string_
|
char_))][push_box(_r1, _r2, _b, _1)]
;

View file

@ -23,13 +23,21 @@
// mapnik
#include <mapnik/json/geometry_generator_grammar.hpp>
#include <mapnik/util/spirit_transform_attribute.hpp>
#include <mapnik/geometry_types.hpp>
// boost
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-local-typedef"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wconversion"
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/fusion/include/at.hpp>
#pragma GCC diagnostic pop
namespace mapnik { namespace json {

View file

@ -212,12 +212,18 @@ public:
void insert(box2d<double> const& box)
{
tree_.insert(label(box), box);
if (tree_.extent().intersects(box))
{
tree_.insert(label(box), box);
}
}
void insert(box2d<double> const& box, mapnik::value_unicode_string const& text)
{
tree_.insert(label(box, text), box);
if (tree_.extent().intersects(box))
{
tree_.insert(label(box, text), box);
}
}
void clear()

View file

@ -56,6 +56,7 @@ private:
datasource::datasource_t type_;
bool bbox_check_;
mutable box2d<double> extent_;
mutable bool dirty_extent_ = true;
};
}

View file

@ -53,7 +53,7 @@ struct offset_converter
, pre_first_(vertex2d::no_init)
, pre_(vertex2d::no_init)
, cur_(vertex2d::no_init)
{}
{}
enum status
{
@ -238,8 +238,8 @@ private:
*/
static void displace(vertex2d & v, double dx, double dy, double a)
{
v.x += dx * std::cos(a) + dy * std::sin(a);
v.y += dx * std::sin(a) - dy * std::cos(a);
v.x += dx * std::cos(a) - dy * std::sin(a);
v.y += dx * std::sin(a) + dy * std::cos(a);
}
/**
@ -247,8 +247,8 @@ private:
*/
void displace(vertex2d & v, double a) const
{
v.x += offset_ * std::sin(a);
v.y -= offset_ * std::cos(a);
v.x -= offset_ * std::sin(a);
v.y += offset_ * std::cos(a);
}
/**
@ -256,8 +256,8 @@ private:
*/
void displace(vertex2d & v, vertex2d const& u, double a) const
{
v.x = u.x + offset_ * std::sin(a);
v.y = u.y - offset_ * std::cos(a);
v.x = u.x - offset_ * std::sin(a);
v.y = u.y + offset_ * std::cos(a);
v.cmd = u.cmd;
}
@ -266,16 +266,27 @@ private:
double sa = offset_ * std::sin(a);
double ca = offset_ * std::cos(a);
double h = std::tan(0.5 * (b - a));
if (h > 1.5)
double hsa = h * sa;
double hca = h * ca;
double abs_offset = std::abs(offset_);
if (hsa > 1.0 * abs_offset)
{
h = 1.5;
hsa = 1.0 * abs_offset;
}
else if (h < -1.5)
else if (hsa < -1.0 * abs_offset)
{
h = -1.5;
hsa = -1.0 * abs_offset;
}
v.x = v.x + sa + h * ca;
v.y = v.y - ca + h * sa;
if (hca > 1.0 * abs_offset)
{
hca = 1.0 * abs_offset;
}
else if (hca < -1.0 * abs_offset)
{
hca = -1.0 * abs_offset;
}
v.x = v.x - sa - hca;
v.y = v.y + ca - hsa;
}
status init_vertices()
@ -288,31 +299,51 @@ private:
vertex2d v1(vertex2d::no_init);
vertex2d v2(vertex2d::no_init);
vertex2d w(vertex2d::no_init);
vertex2d start(vertex2d::no_init);
vertex2d start_v2(vertex2d::no_init);
std::vector<vertex2d> points;
std::vector<vertex2d> close_points;
bool is_polygon = false;
std::size_t cpt = 0;
v0.cmd = geom_.vertex(&v0.x, &v0.y);
v1.x = v0.x;
v1.y = v0.y;
v1.cmd = v0.cmd;
v1 = v0;
// PUSH INITIAL
points.push_back(vertex2d(v0.x, v0.y, v0.cmd));
points.push_back(v0);
if (v0.cmd == SEG_END) // not enough vertices in source
{
return status_ = process;
}
start = v0;
while ((v0.cmd = geom_.vertex(&v0.x, &v0.y)) != SEG_END)
{
points.push_back(vertex2d(v0.x, v0.y, v0.cmd));
if (v0.cmd == SEG_CLOSE)
{
is_polygon = true;
close_points.push_back(vertex2d(v1.x, v1.y, v1.cmd));
auto & prev = points.back();
if (prev.x == start.x && prev.y == start.y)
{
prev.x = v0.x; // hack
prev.y = v0.y;
prev.cmd = SEG_CLOSE; // account for dupes (line_to(move_to) + close_path) in agg poly clipper
std::size_t size = points.size();
if (size > 1) close_points.push_back(points[size - 2]);
else close_points.push_back(prev);
continue;
}
else
{
close_points.push_back(v1);
}
}
v1.x = v0.x;
v1.y = v0.y;
v1.cmd = v0.cmd;
else if (v0.cmd == SEG_MOVETO)
{
start = v0;
}
v1 = v0;
points.push_back(v0);
}
// Push SEG_END
points.push_back(vertex2d(v0.x, v0.y, v0.cmd));
points.push_back(vertex2d(v0.x,v0.y,SEG_END));
std::size_t i = 0;
v1 = points[i++];
v2 = points[i++];
@ -326,17 +357,28 @@ private:
}
double angle_a = 0;
// The vector parts from v1 to v0.
double v_x1x0 = 0;
double v_y1y0 = 0;
// The vector parts from v1 to v2;
double v_x1x2 = v2.x - v1.x;
double v_y1y2 = v2.y - v1.y;
if (is_polygon)
{
double x = v1.x - close_points[cpt].x;
double y = v1.y - close_points[cpt].y;
v_x1x0 = close_points[cpt].x - v1.x;
v_y1y0 = close_points[cpt].y - v1.y;
cpt++;
x = std::abs(x) < std::numeric_limits<double>::epsilon() ? 0 : x;
y = std::abs(y) < std::numeric_limits<double>::epsilon() ? 0 : y;
angle_a = std::atan2(y, x);
angle_a = std::atan2(-v_y1y0, -v_x1x0);
}
double angle_b = std::atan2((v2.y - v1.y), (v2.x - v1.x));
// dot product
double dot;
// determinate
double det;
double angle_b = std::atan2(v_y1y2, v_x1x2);
// Angle between the two vectors
double joint_angle;
double curve_angle;
if (!is_polygon)
{
@ -346,33 +388,28 @@ private:
}
else
{
joint_angle = explement_reflex_angle(angle_b - angle_a);
dot = v_x1x0 * v_x1x2 + v_y1y0 * v_y1y2; // dot product
det = v_x1x0 * v_y1y2 - v_y1y0 * v_x1x2; // determinant
joint_angle = std::atan2(det, dot); // atan2(y, x) or atan2(sin, cos)
if (joint_angle < 0) joint_angle = joint_angle + 2 * M_PI;
joint_angle = std::fmod(joint_angle, 2 * M_PI);
if (offset_ > 0.0)
{
joint_angle = 2 * M_PI - joint_angle;
}
double half_turns = half_turn_segments_ * std::fabs(joint_angle);
int bulge_steps = 0;
if (offset_ < 0.0)
if (std::abs(joint_angle) > M_PI)
{
if (joint_angle > 0.0)
{
joint_angle = joint_angle - 2 * M_PI;
}
else
{
bulge_steps = 1 + static_cast<int>(std::floor(half_turns / M_PI));
}
}
else
{
if (joint_angle < 0.0)
{
joint_angle = joint_angle + 2 * M_PI;
}
else
{
bulge_steps = 1 + static_cast<int>(std::floor(half_turns / M_PI));
}
curve_angle = explement_reflex_angle(angle_b - angle_a);
// Bulge steps should be determined by the inverse of the joint angle.
double half_turns = half_turn_segments_ * std::fabs(curve_angle);
bulge_steps = 1 + static_cast<int>(std::floor(half_turns / M_PI));
}
if (bulge_steps == 0)
{
displace2(v1, angle_a, angle_b);
@ -415,18 +452,15 @@ private:
v1.y = start_.y;
if (cpt < close_points.size())
{
double x = v1.x - close_points[cpt].x;
double y = v1.y - close_points[cpt].y;
x = std::abs(x) < std::numeric_limits<double>::epsilon() ? 0.0 : x;
y = std::abs(y) < std::numeric_limits<double>::epsilon() ? 0.0 : y;
angle_b = std::atan2(y,x);
v_x1x2 = v1.x - close_points[cpt].x;
v_y1y2 = v1.y - close_points[cpt].y;
cpt++;
}
start_v2.x = v2.x;
start_v2.y = v2.y;
}
start_v2.x = v2.x;
start_v2.y = v2.y;
}
if (v2.cmd == SEG_MOVETO)
if (is_polygon && v2.cmd == SEG_MOVETO)
{
start_.x = v2.x;
start_.y = v2.y;
@ -445,34 +479,39 @@ private:
v2.x = start_.x;
v2.y = start_.y;
}
angle_a = angle_b;
angle_b = std::atan2((v2.y - v1.y), (v2.x - v1.x));
joint_angle = explement_reflex_angle(angle_b - angle_a);
double half_turns = half_turn_segments_ * std::fabs(joint_angle);
// Switch the previous vector's direction as the origin has changed
v_x1x0 = -v_x1x2;
v_y1y0 = -v_y1y2;
// Calculate new angle_a
angle_a = std::atan2(v_y1y2, v_x1x2);
// Calculate the new vector
v_x1x2 = v2.x - v1.x;
v_y1y2 = v2.y - v1.y;
// Calculate the new angle_b
angle_b = std::atan2(v_y1y2, v_x1x2);
dot = v_x1x0 * v_x1x2 + v_y1y0 * v_y1y2; // dot product
det = v_x1x0 * v_y1y2 - v_y1y0 * v_x1x2; // determinant
joint_angle = std::atan2(det, dot); // atan2(y, x) or atan2(sin, cos)
if (joint_angle < 0) joint_angle = joint_angle + 2 * M_PI;
joint_angle = std::fmod(joint_angle, 2 * M_PI);
if (offset_ > 0.0)
{
joint_angle = 2 * M_PI - joint_angle;
}
int bulge_steps = 0;
if (offset_ < 0.0)
if (std::abs(joint_angle) > M_PI)
{
if (joint_angle > 0.0)
{
joint_angle = joint_angle - 2 * M_PI;
}
else
{
bulge_steps = 1 + static_cast<int>(std::floor(half_turns / M_PI));
}
}
else
{
if (joint_angle < 0.0)
{
joint_angle = joint_angle + 2 * M_PI;
}
else
{
bulge_steps = 1 + static_cast<int>(std::floor(half_turns / M_PI));
}
curve_angle = explement_reflex_angle(angle_b - angle_a);
// Bulge steps should be determined by the inverse of the joint angle.
double half_turns = half_turn_segments_ * std::fabs(curve_angle);
bulge_steps = 1 + static_cast<int>(std::floor(half_turns / M_PI));
}
#ifdef MAPNIK_LOG
@ -516,10 +555,9 @@ private:
displace(w, v1, angle_a);
w.cmd = SEG_LINETO;
push_vertex(w);
for (int s = 0; ++s < bulge_steps;)
{
displace(w, v1, angle_a + (joint_angle * s) / bulge_steps);
displace(w, v1, angle_a + (curve_angle * s) / bulge_steps);
w.cmd = SEG_LINETO;
push_vertex(w);
}

View file

@ -211,7 +211,7 @@ void render_offset_placements(placements_list const& placements,
pixel_position const& offset,
F render_text) {
for (glyph_positions_ptr glyphs : placements)
for (auto const& glyphs : placements)
{
// move the glyphs to the correct offset
pixel_position base_point = glyphs->get_base_point();

View file

@ -118,9 +118,9 @@ struct render_marker_symbolizer_visitor
if (clip) // optional clip (default: true)
{
geometry::geometry_types type = geometry::geometry_type(feature_.get_geometry());
if (type == geometry::geometry_types::Polygon)
if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
converter.template set<clip_poly_tag>();
else if (type == geometry::geometry_types::LineString)
else if (type == geometry::geometry_types::LineString || type == geometry::geometry_types::MultiLineString)
converter.template set<clip_line_tag>();
}
@ -223,9 +223,9 @@ struct render_marker_symbolizer_visitor
if (clip) // optional clip (default: true)
{
geometry::geometry_types type = geometry::geometry_type(feature_.get_geometry());
if (type == geometry::geometry_types::Polygon)
if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
converter.template set<clip_poly_tag>();
else if (type == geometry::geometry_types::LineString)
else if (type == geometry::geometry_types::LineString || type == geometry::geometry_types::MultiLineString)
converter.template set<clip_line_tag>();
}
converter.template set<transform_tag>(); //always transform

View file

@ -38,15 +38,18 @@ namespace mapnik { namespace svg {
class MAPNIK_DECL svg_parser : private util::noncopyable
{
using error_message_container = std::vector<std::string> ;
public:
explicit svg_parser(svg_converter_type & path);
~svg_parser();
void parse(std::string const& filename);
void parse_from_string(std::string const& svg);
error_message_container const& error_messages() const;
bool parse(std::string const& filename);
bool parse_from_string(std::string const& svg);
svg_converter_type & path_;
bool is_defs_;
std::map<std::string, gradient> gradient_map_;
std::pair<std::string, gradient> temporary_gradient_;
error_message_container error_messages_;
};
}}

View file

@ -2,7 +2,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 Artem Pavlenko
* Copyright (C) 2015 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -20,28 +20,35 @@
*
*****************************************************************************/
#ifndef DATASET_DELIVERER_H
#define DATASET_DELIVERER_H
#ifndef MAPNIK_SVG_PARSER_EXCEPTION_HPP
#define MAPNIK_SVG_PARSER_EXCEPTION_HPP
#include "osm.h"
#include <string>
// mapnik
#include <mapnik/config.hpp>
#include <exception>
using namespace std;
// stl
#include <map>
class dataset_deliverer
namespace mapnik { namespace svg {
class MAPNIK_DECL svg_parser_exception : public std::exception
{
private:
static osm_dataset* dataset;
static std::string last_bbox;
static std::string last_filename;
public:
static osm_dataset *load_from_file(const string&, const string&);
svg_parser_exception(std::string const& message)
: message_(message) {}
static void release()
~svg_parser_exception() throw() {}
virtual const char* what() const throw()
{
delete dataset;
return message_.c_str();
}
private:
std::string message_;
};
#endif // DATASET_DELIVERER_H
}}
#endif // MAPNIK_SVG_PARSER_EXCEPTION_HPP

View file

@ -45,7 +45,7 @@ using namespace agg;
template<class VertexContainer> class path_adapter : util::noncopyable
{
public:
using container_type = VertexContainer ;
using container_type = VertexContainer;
using self_type = path_adapter<VertexContainer>;
//--------------------------------------------------------------------

View file

@ -44,7 +44,7 @@ extern "C"
namespace mapnik
{
class font_face : util::noncopyable
class MAPNIK_DECL font_face : util::noncopyable
{
public:
font_face(FT_Face face);

View file

@ -26,6 +26,7 @@
#include <mapnik/pixel_position.hpp>
#include <mapnik/text/rotation.hpp>
#include <mapnik/marker_cache.hpp>
#include <mapnik/text/glyph_info.hpp>
// agg
#include "agg_trans_affine.h"
@ -37,8 +38,6 @@
namespace mapnik
{
struct glyph_info;
struct glyph_position
{
glyph_position(glyph_info const& _glyph, pixel_position const& _pos, rotation const& _rot)
@ -82,7 +81,6 @@ public:
void set_marker(marker_info_ptr marker, pixel_position const& marker_pos);
marker_info_ptr get_marker() const;
pixel_position const& marker_pos() const;
box2d<double> const & bbox() const;
private:
std::vector<glyph_position> data_;
pixel_position base_point_;
@ -90,7 +88,7 @@ private:
pixel_position marker_pos_;
box2d<double> bbox_;
};
using glyph_positions_ptr = std::shared_ptr<glyph_positions>;
using glyph_positions_ptr = std::unique_ptr<glyph_positions>;
using placements_list = std::list<glyph_positions_ptr>;
}

View file

@ -28,7 +28,9 @@
#include <mapnik/text/text_line.hpp>
#include <mapnik/text/face.hpp>
#include <mapnik/text/font_feature_settings.hpp>
#include <mapnik/text/itemizer.hpp>
#include <mapnik/safe_cast.hpp>
#include <mapnik/font_engine_freetype.hpp>
// stl
#include <list>
@ -38,6 +40,9 @@
#include <harfbuzz/hb.h>
#include <harfbuzz/hb-ft.h>
// icu
#include <unicode/uscript.h>
namespace mapnik
{

View file

@ -27,6 +27,10 @@
#include <mapnik/text/text_properties.hpp>
#include <mapnik/text/text_line.hpp>
#include <mapnik/text/face.hpp>
#include <mapnik/text/font_feature_settings.hpp>
#include <mapnik/text/itemizer.hpp>
#include <mapnik/safe_cast.hpp>
#include <mapnik/font_engine_freetype.hpp>
#include <mapnik/debug.hpp>
// stl
@ -59,12 +63,11 @@ static void shape_text(text_line & line,
UErrorCode err = U_ZERO_ERROR;
mapnik::value_unicode_string shaped;
mapnik::value_unicode_string reordered;
unsigned char_index = 0;
for (auto const& text_item : list)
{
face_set_ptr face_set = font_manager.get_face_set(text_item.format->face_name, text_item.format->fontset);
double size = text_item.format->text_size * scale_factor;
face_set_ptr face_set = font_manager.get_face_set(text_item.format_->face_name, text_item.format_->fontset);
double size = text_item.format_->text_size * scale_factor;
face_set->set_unscaled_character_sizes();
for (auto const& face : *face_set)
{
@ -87,33 +90,35 @@ static void shape_text(text_line & line,
std::size_t num_chars = static_cast<std::size_t>(num_char);
shaped.releaseBuffer(length);
bool shaped_status = true;
double max_glyph_height = 0;
if (U_SUCCESS(err) && (num_chars == length))
{
unsigned char_index = 0;
U_NAMESPACE_QUALIFIER StringCharacterIterator iter(shaped);
for (iter.setToStart(); iter.hasNext();)
{
UChar ch = iter.nextPostInc();
glyph_info tmp;
tmp.glyph_index = FT_Get_Char_Index(face->get_face(), ch);
tmp.offset.clear();
if (tmp.glyph_index == 0)
auto codepoint = FT_Get_Char_Index(face->get_face(), ch);
glyph_info g(codepoint,char_index,text_item.format_);
//g.offset.clear();
if (g.glyph_index == 0)
{
shaped_status = false;
break;
}
if (face->glyph_dimensions(tmp))
if (face->glyph_dimensions(g))
{
tmp.char_index = char_index;
tmp.face = face;
tmp.format = text_item.format;
tmp.scale_multiplier = size / face->get_face()->units_per_EM;
width_map[char_index++] += tmp.advance();
line.add_glyph(tmp, scale_factor);
g.face = face;
g.scale_multiplier = size / face->get_face()->units_per_EM;
double tmp_height = g.height();
if (tmp_height > max_glyph_height) max_glyph_height = tmp_height;
width_map[char_index++] += g.advance();
line.add_glyph(std::move(g), scale_factor);
}
}
}
if (!shaped_status) continue;
line.update_max_char_height(face->get_char_height(size));
line.update_max_char_height(max_glyph_height);
return;
}
}

View file

@ -27,6 +27,7 @@
#include <mapnik/text/evaluated_format_properties_ptr.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/util/noncopyable.hpp>
#include <mapnik/config.hpp>
// stl
#include <string>
@ -41,7 +42,7 @@
namespace mapnik
{
struct text_item : util::noncopyable
struct MAPNIK_DECL text_item : util::noncopyable
{
text_item(unsigned s,
unsigned e,
@ -71,7 +72,7 @@ struct text_item : util::noncopyable
// - format
// - script (http://en.wikipedia.org/wiki/Scripts_in_Unicode)
class text_itemizer
class MAPNIK_DECL text_itemizer : util::noncopyable
{
public:
text_itemizer();

View file

@ -26,7 +26,6 @@
#include <mapnik/box2d.hpp>
#include <mapnik/pixel_position.hpp>
#include <mapnik/text/text_layout.hpp>
#include <mapnik/text/placements/base.hpp>
#include <mapnik/text/glyph_positions.hpp>
#include <mapnik/text/rotation.hpp>
#include <mapnik/util/noncopyable.hpp>
@ -75,7 +74,7 @@ private:
// Checks for collision.
bool collision(box2d<double> const& box, const value_unicode_string &repeat_key, bool line_placement) const;
// Adds marker to glyph_positions and to collision detector. Returns false if there is a collision.
bool add_marker(glyph_positions_ptr glyphs, pixel_position const& pos) const;
bool add_marker(glyph_positions_ptr & glyphs, pixel_position const& pos) const;
// Maps upright==auto, left-only and right-only to left,right to simplify processing.
// angle = angle of at start of line (to estimate best option for upright==auto)
text_upright_e simplify_upright(text_upright_e upright, double angle) const;

View file

@ -19,23 +19,19 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//mapnik
#include <mapnik/debug.hpp>
#include <mapnik/label_collision_detector.hpp>
#include <mapnik/view_transform.hpp>
#include <mapnik/expression_evaluator.hpp>
// mapnik
//#include <mapnik/label_collision_detector.hpp>
//#include <mapnik/view_transform.hpp>
#include <mapnik/text/placement_finder.hpp>
#include <mapnik/text/text_layout.hpp>
#include <mapnik/text/text_properties.hpp>
#include <mapnik/text/glyph_positions.hpp>
//#include <mapnik/text/glyph_positions.hpp>
#include <mapnik/vertex_cache.hpp>
#include <mapnik/tolerance_iterator.hpp>
#include <mapnik/symbolizer_enumerations.hpp>
// agg
#include "agg_conv_clip_polyline.h"
// stl
#include <vector>
#include <memory>
namespace mapnik
{

View file

@ -56,8 +56,8 @@ public:
text_renderer (halo_rasterizer_e rasterizer,
composite_mode_e comp_op = src_over,
composite_mode_e halo_comp_op = src_over,
double scale_factor=1.0,
stroker_ptr stroker=stroker_ptr());
double scale_factor = 1.0,
stroker_ptr stroker = stroker_ptr());
void set_transform(agg::trans_affine const& transform);
void set_halo_transform(agg::trans_affine const& halo_transform);
protected:

View file

@ -17,9 +17,9 @@
#ifndef __SCRPTRUN_H
#define __SCRPTRUN_H
#include "unicode/utypes.h"
#include "unicode/uobject.h"
#include "unicode/uscript.h"
#include <unicode/utypes.h>
#include <unicode/uobject.h>
#include <unicode/uscript.h>
struct ScriptRecord
{

View file

@ -22,10 +22,13 @@
#ifndef SYMBOLIZER_HELPERS_HPP
#define SYMBOLIZER_HELPERS_HPP
//mapnik
// mapnik
#include <mapnik/text/placement_finder.hpp>
#include <mapnik/text/placements/base.hpp>
#include <mapnik/vertex_converters.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/text/glyph_positions.hpp>
#include <mapnik/text/text_properties.hpp>
namespace mapnik {

View file

@ -25,17 +25,17 @@
//stl
#include <vector>
#include <mapnik/util/noncopyable.hpp>
#include <mapnik/config.hpp>
#include <mapnik/text/glyph_info.hpp>
namespace mapnik
{
struct glyph_info;
// This class stores all glyphs of a line in left to right order.
// It can be used for rendering but no text processing (like line breaking)
// should be done!
class text_line : util::noncopyable
class MAPNIK_DECL text_line : util::noncopyable
{
public:
using glyph_vector = std::vector<glyph_info>;
@ -97,6 +97,6 @@ private:
unsigned space_count_;
};
} //namespace mapnik
} // namespace mapnik
#endif // MAPNIK_TEXT_LINE_HPP

View file

@ -32,6 +32,9 @@
// agg
#include <agg_trans_affine.h>
// stl
#include <cmath>
namespace mapnik {
class feature_impl;
@ -149,13 +152,19 @@ struct transform_processor
void operator() (skewX_node const& node)
{
double angle = deg2rad(eval(node.angle_));
auto degrees = std::fmod(eval(node.angle_),90.0);
if (degrees < -89.0) degrees = -89.0;
else if (degrees > 89.0) degrees = 89.0;
auto angle = deg2rad(degrees);
transform_.multiply(agg::trans_affine_skewing(angle, 0.0));
}
void operator() (skewY_node const& node)
{
double angle = deg2rad(eval(node.angle_));
auto degrees = std::fmod(eval(node.angle_),90.0);
if (degrees < -89.0) degrees = -89.0;
else if (degrees > 89.0) degrees = 89.0;
auto angle = deg2rad(degrees);
transform_.multiply(agg::trans_affine_skewing(0.0, angle));
}

View file

@ -24,6 +24,20 @@
#define MAPNIK_UTIL_SPIRIT_TRANSFORM_ATTRIBUTE_HPP
#include <mapnik/geometry.hpp>
#include <mapnik/util/variant.hpp>
#include <vector>
#include <cstdint>
// boost
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-local-typedef"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wconversion"
#include <boost/spirit/include/karma.hpp>
#pragma GCC diagnostic pop
namespace boost { namespace spirit { namespace traits {

View file

@ -29,7 +29,6 @@
// stl
#include <functional>
#include <cassert>
// icu
#include <unicode/unistr.h>
@ -52,7 +51,6 @@ struct value_hasher
std::size_t operator() (value_unicode_string const& val) const
{
assert(val.hashCode() > 0);
return static_cast<std::size_t>(val.hashCode());
}

View file

@ -27,9 +27,9 @@
#define MAPNIK_MAJOR_VERSION 3
#define MAPNIK_MINOR_VERSION 0
#define MAPNIK_PATCH_VERSION 0
#define MAPNIK_PATCH_VERSION 1
// translates to 300000
// translates to 300001
#define MAPNIK_VERSION (MAPNIK_MAJOR_VERSION*100000) + (MAPNIK_MINOR_VERSION*100) + (MAPNIK_PATCH_VERSION)
#ifndef MAPNIK_STRINGIFY

View file

@ -8,6 +8,7 @@ else
fi
export PATH=$(pwd)/utils/nik2img/:${PATH}
export PATH=$(pwd)/utils/mapnik-config/:${PATH}
# mapnik-settings.env is an optional file to store
# environment variables that should be used before

View file

@ -218,7 +218,7 @@ void geojson_datasource::initialise_index(Iterator start, Iterator end)
// parse first feature to extract attributes schema.
// NOTE: this doesn't yield correct answer for geoJSON in general, just an indication
Iterator itr2 = start + geometry_index.first;
Iterator end2 = itr + geometry_index.second;
Iterator end2 = itr2 + geometry_index.second;
mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx,1));
if (!boost::spirit::qi::phrase_parse(itr2, end2, (geojson_datasource_static_feature_grammar)(boost::phoenix::ref(*feature)), space))

View file

@ -1,12 +0,0 @@
#
# To regenerate C++ class declarations & implementations for the Spatial
# object types of your database you should execute OTT in your server !
#
echo "TYPE MDSYS.SDO_POINT_TYPE AS SDOPointType" > spatial_types.typ
echo "TYPE MDSYS.SDO_GEOMETRY AS SDOGeometry" >> spatial_types.typ
ott userid=scott/tiger attraccess=private intype=spatial_types.typ code=cpp \
cppfile=spatial_classeso.cpp hfile=spatial_classesh.h mapfile=spatial_classesm.cpp \
mapfunc=RegisterClasses

View file

@ -1,74 +0,0 @@
#
# This file is part of Mapnik (c++ mapping toolkit)
#
# Copyright (C) 2015 Artem Pavlenko
#
# 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
#
#
Import ('plugin_base')
Import ('env')
PLUGIN_NAME = 'occi'
plugin_env = plugin_base.Clone()
plugin_sources = Split(
"""
%(PLUGIN_NAME)s_types.cpp
%(PLUGIN_NAME)s_datasource.cpp
%(PLUGIN_NAME)s_featureset.cpp
spatial_classesm.cpp
spatial_classeso.cpp
""" % locals()
)
libraries = [ 'clntsh', 'occi' ]
libraries.append('boost_system%s' % env['BOOST_APPEND'])
libraries.append(env['ICU_LIB_NAME'])
if env['PLUGIN_LINKING'] == 'shared':
libraries.append(env['MAPNIK_NAME'])
# libocci.dylib, at least for 11.2 links to libstdc++
# so we defer symbol resolution to runtime in order to
# dodge linking errors like
# Undefined symbols for architecture x86_64:
# "std::string::_Rep::_M_destroy(std::allocator<char> const&)", referenced from:
# RegisterClasses(oracle::occi::Environment*) in spatial_classesm.os
if env['PLATFORM'] == 'Darwin':
plugin_env.Append(LINKFLAGS='-undefined dynamic_lookup')
TARGET = plugin_env.SharedLibrary('../%s' % PLUGIN_NAME,
SHLIBPREFIX='',
SHLIBSUFFIX='.input',
source=plugin_sources,
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' not in COMMAND_LINE_TARGETS:
env.Install(env['MAPNIK_INPUT_PLUGINS_DEST'], TARGET)
env.Alias('install', env['MAPNIK_INPUT_PLUGINS_DEST'])
plugin_obj = {
'LIBS': libraries,
'SOURCES': plugin_sources,
}
Return('plugin_obj')

View file

@ -1,641 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#include "occi_datasource.hpp"
#include "occi_featureset.hpp"
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/boolean.hpp>
#include <mapnik/sql_utils.hpp>
#include <mapnik/timer.hpp>
#include <mapnik/value_types.hpp>
// boost
#include <boost/algorithm/string.hpp>
#include <boost/tokenizer.hpp>
// stl
#include <string>
#include <algorithm>
#include <set>
#include <sstream>
#include <iomanip>
using mapnik::datasource;
using mapnik::parameters;
using mapnik::query;
using mapnik::featureset_ptr;
using mapnik::layer_descriptor;
using mapnik::attribute_descriptor;
using mapnik::datasource_exception;
using mapnik::box2d;
using mapnik::coord2d;
using oracle::occi::Environment;
using oracle::occi::Connection;
using oracle::occi::Statement;
using oracle::occi::ResultSet;
using oracle::occi::MetaData;
using oracle::occi::SQLException;
using oracle::occi::Type;
using oracle::occi::StatelessConnectionPool;
const double occi_datasource::FMAX = std::numeric_limits<double>::max();
const std::string occi_datasource::METADATA_TABLE = "USER_SDO_GEOM_METADATA";
DATASOURCE_PLUGIN(occi_datasource)
occi_datasource::occi_datasource(parameters const& params)
: datasource (params),
type_(datasource::Vector),
fields_(*params.get<std::string>("fields", "*")),
geometry_field_(*params.get<std::string>("geometry_field", "")),
srid_initialized_(false),
extent_initialized_(false),
bbox_token_("!bbox!"),
scale_denom_token_("!scale_denominator!"),
pixel_width_token_("!pixel_width!"),
pixel_height_token_("!pixel_height!"),
desc_(occi_datasource::name(), *params.get<std::string>("encoding", "utf-8")),
use_wkb_(*params.get<mapnik::boolean_type>("use_wkb", false)),
row_limit_(*params.get<mapnik::value_integer>("row_limit", 0)),
row_prefetch_(*params.get<mapnik::value_integer>("row_prefetch", 100)),
pool_(0),
conn_(0)
{
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "occi_datasource::init");
#endif
if (! params.get<std::string>("user")) throw datasource_exception("OCCI Plugin: no <user> specified");
if (! params.get<std::string>("password")) throw datasource_exception("OCCI Plugin: no <password> specified");
if (! params.get<std::string>("host")) throw datasource_exception("OCCI Plugin: no <host> string specified");
boost::optional<std::string> table = params.get<std::string>("table");
if (! table)
{
throw datasource_exception("OCCI Plugin: no <table> parameter specified");
}
else
{
table_ = *table;
}
estimate_extent_ = *params.get<mapnik::boolean_type>("estimate_extent",false);
use_spatial_index_ = *params.get<mapnik::boolean_type>("use_spatial_index",true);
use_connection_pool_ = *params.get<mapnik::boolean_type>("use_connection_pool",true);
boost::optional<std::string> ext = params.get<std::string>("extent");
if (ext) extent_initialized_ = extent_.from_string(*ext);
boost::optional<mapnik::value_integer> srid = params.get<mapnik::value_integer>("srid");
if (srid)
{
srid_ = *srid;
srid_initialized_ = true;
}
// connect to environment
if (use_connection_pool_)
{
try
{
pool_ = occi_environment::instance().create_pool(
*params.get<std::string>("user"),
*params.get<std::string>("password"),
*params.get<std::string>("host"),
*params.get<mapnik::value_integer>("max_size", 5),
*params.get<mapnik::value_integer>("initial_size", 1),
1);
}
catch (SQLException& ex)
{
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
}
}
else
{
try
{
conn_ = occi_environment::instance().create_connection(
*params.get<std::string>("user"),
*params.get<std::string>("password"),
*params.get<std::string>("host"));
}
catch (SQLException& ex)
{
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
}
}
// extract real table name
table_name_ = mapnik::sql_utils::table_from_sql(table_);
// get SRID and/or GEOMETRY_FIELD from metadata table only if we need to
if (! srid_initialized_ || geometry_field_ == "")
{
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "occi_datasource::get_srid_and_geometry_field");
#endif
std::ostringstream s;
s << "SELECT srid, column_name FROM " << METADATA_TABLE << " WHERE";
s << " LOWER(table_name) = LOWER('" << table_name_ << "')";
if (geometry_field_ != "")
{
s << " AND LOWER(column_name) = LOWER('" << geometry_field_ << "')";
}
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
try
{
occi_connection_ptr conn;
if (use_connection_pool_) conn.set_pool(pool_);
else conn.set_connection(conn_, false);
ResultSet* rs = conn.execute_query(s.str());
if (rs && rs->next ())
{
if (! srid_initialized_)
{
srid_ = rs->getInt(1);
srid_initialized_ = true;
}
if (geometry_field_ == "")
{
geometry_field_ = rs->getString(2);
}
}
}
catch (SQLException& ex)
{
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
}
}
// get columns description
{
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "occi_datasource::get_column_description");
#endif
std::ostringstream s;
s << "SELECT " << fields_ << " FROM (" << table_name_ << ") WHERE ROWNUM < 1";
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
try
{
occi_connection_ptr conn;
if (use_connection_pool_) conn.set_pool(pool_);
else conn.set_connection(conn_, false);
ResultSet* rs = conn.execute_query(s.str());
if (rs)
{
std::vector<MetaData> listOfColumns = rs->getColumnListMetaData();
for (unsigned int i = 0; i < listOfColumns.size(); ++i)
{
MetaData columnObj = listOfColumns[i];
std::string fld_name = columnObj.getString(MetaData::ATTR_NAME);
int type_oid = columnObj.getInt(MetaData::ATTR_DATA_TYPE);
/*
int type_code = columnObj.getInt(MetaData::ATTR_TYPECODE);
if (type_code == OCCI_TYPECODE_OBJECT)
{
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Object));
continue;
}
*/
switch (type_oid)
{
case oracle::occi::OCCIBOOL:
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Boolean));
break;
case oracle::occi::OCCIINT:
case oracle::occi::OCCIUNSIGNED_INT:
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer));
break;
case oracle::occi::OCCIFLOAT:
case oracle::occi::OCCIBFLOAT:
case oracle::occi::OCCIDOUBLE:
case oracle::occi::OCCIBDOUBLE:
case oracle::occi::OCCINUMBER:
case oracle::occi::OCCI_SQLT_NUM:
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Double));
break;
case oracle::occi::OCCICHAR:
case oracle::occi::OCCISTRING:
case oracle::occi::OCCI_SQLT_AFC:
case oracle::occi::OCCI_SQLT_AVC:
case oracle::occi::OCCI_SQLT_CHR:
case oracle::occi::OCCI_SQLT_LNG:
case oracle::occi::OCCI_SQLT_LVC:
case oracle::occi::OCCI_SQLT_STR:
case oracle::occi::OCCI_SQLT_VCS:
case oracle::occi::OCCI_SQLT_VNU:
case oracle::occi::OCCI_SQLT_VBI:
case oracle::occi::OCCI_SQLT_VST:
case oracle::occi::OCCIROWID:
case oracle::occi::OCCI_SQLT_RDD:
case oracle::occi::OCCI_SQLT_RID:
case oracle::occi::OCCIDATE:
case oracle::occi::OCCI_SQLT_DAT:
case oracle::occi::OCCI_SQLT_DATE:
case oracle::occi::OCCI_SQLT_TIME:
case oracle::occi::OCCI_SQLT_TIME_TZ:
case oracle::occi::OCCITIMESTAMP:
case oracle::occi::OCCI_SQLT_TIMESTAMP:
case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ:
case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ:
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));
break;
case oracle::occi::OCCIINTERVALDS:
case oracle::occi::OCCIINTERVALYM:
case oracle::occi::OCCI_SQLT_INTERVAL_YM:
case oracle::occi::OCCI_SQLT_INTERVAL_DS:
case oracle::occi::OCCIANYDATA:
case oracle::occi::OCCIBLOB:
case oracle::occi::OCCIBFILE:
case oracle::occi::OCCIBYTES:
case oracle::occi::OCCICLOB:
case oracle::occi::OCCIVECTOR:
case oracle::occi::OCCIMETADATA:
case oracle::occi::OCCIPOBJECT:
case oracle::occi::OCCIREF:
case oracle::occi::OCCIREFANY:
case oracle::occi::OCCISTREAM:
case oracle::occi::OCCICURSOR:
case oracle::occi::OCCI_SQLT_FILE:
case oracle::occi::OCCI_SQLT_CFILE:
case oracle::occi::OCCI_SQLT_REF:
case oracle::occi::OCCI_SQLT_CLOB:
case oracle::occi::OCCI_SQLT_BLOB:
case oracle::occi::OCCI_SQLT_RSET:
MAPNIK_LOG_WARN(occi) << "occi_datasource: Unsupported datatype "
<< occi_enums::resolve_datatype(type_oid)
<< " (type_oid=" << type_oid << ")";
break;
default:
MAPNIK_LOG_WARN(occi) << "occi_datasource: Unknown datatype "
<< "(type_oid=" << type_oid << ")";
break;
}
}
}
}
catch (SQLException& ex)
{
throw datasource_exception(ex.getMessage());
}
}
}
occi_datasource::~occi_datasource()
{
if (use_connection_pool_)
{
if (pool_ != 0)
{
occi_environment::instance().destroy_pool(pool_);
}
}
else
{
if (conn_ != 0)
{
occi_environment::instance().destroy_connection(conn_);
}
}
}
const char * occi_datasource::name()
{
return "occi";
}
mapnik::datasource::datasource_t occi_datasource::type() const
{
return type_;
}
box2d<double> occi_datasource::envelope() const
{
if (extent_initialized_) return extent_;
double lox = 0.0, loy = 0.0, hix = 0.0, hiy = 0.0;
if (estimate_extent_)
{
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "occi_datasource::envelope(estimate_extent)");
#endif
std::ostringstream s;
s << "SELECT MIN(c.x), MIN(c.y), MAX(c.x), MAX(c.y) FROM ";
s << " (SELECT SDO_AGGR_MBR(" << geometry_field_ << ") shape FROM " << table_ << ") a, ";
s << " TABLE(SDO_UTIL.GETVERTICES(a.shape)) c";
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
try
{
occi_connection_ptr conn;
if (use_connection_pool_) conn.set_pool(pool_);
else conn.set_connection(conn_, false);
ResultSet* rs = conn.execute_query(s.str());
if (rs && rs->next())
{
lox = rs->getDouble(1);
loy = rs->getDouble(2);
hix = rs->getDouble(3);
hiy = rs->getDouble(4);
extent_.init(lox, loy, hix, hiy);
extent_initialized_ = true;
}
}
catch (SQLException& ex)
{
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
}
}
else if (use_spatial_index_)
{
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "occi_datasource::envelope(use_spatial_index)");
#endif
std::ostringstream s;
s << "SELECT dim.sdo_lb, dim.sdo_ub FROM ";
s << METADATA_TABLE << " m, TABLE(m.diminfo) dim ";
s << " WHERE LOWER(m.table_name) = LOWER('" << table_name_ << "') AND dim.sdo_dimname = 'X'";
s << " UNION ";
s << "SELECT dim.sdo_lb, dim.sdo_ub FROM ";
s << METADATA_TABLE << " m, TABLE(m.diminfo) dim ";
s << " WHERE LOWER(m.table_name) = LOWER('" << table_name_ << "') AND dim.sdo_dimname = 'Y'";
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
try
{
occi_connection_ptr conn;
if (use_connection_pool_) conn.set_pool(pool_);
else conn.set_connection(conn_, false);
ResultSet* rs = conn.execute_query(s.str());
if (rs)
{
if (rs->next())
{
lox = rs->getDouble(1);
hix = rs->getDouble(2);
}
if (rs->next())
{
loy = rs->getDouble(1);
hiy = rs->getDouble(2);
}
extent_.init(lox, loy, hix, hiy);
extent_initialized_ = true;
}
}
catch (SQLException& ex)
{
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
}
}
if (! extent_initialized_)
{
throw datasource_exception("OCCI Plugin: unable to determine the extent of a <occi> table");
}
return extent_;
}
boost::optional<mapnik::datasource_geometry_t> occi_datasource::get_geometry_type() const
{
return boost::optional<mapnik::datasource_geometry_t>();
}
layer_descriptor occi_datasource::get_descriptor() const
{
return desc_;
}
std::string occi_datasource::sql_bbox(box2d<double> const& env) const
{
std::ostringstream b;
b << std::setprecision(16);
b << "MDSYS.SDO_GEOMETRY(" << SDO_GTYPE_2DPOLYGON << "," << srid_ << ",NULL,";
b << " MDSYS.SDO_ELEM_INFO_ARRAY(1," << SDO_ETYPE_POLYGON << "," << SDO_INTERPRETATION_RECTANGLE << "),";
b << " MDSYS.SDO_ORDINATE_ARRAY(";
b << env.minx() << "," << env.miny() << ", ";
b << env.maxx() << "," << env.maxy() << "))";
return b.str();
}
std::string occi_datasource::populate_tokens(std::string const& sql, double scale_denom, box2d<double> const& env, double pixel_width, double pixel_height) const
{
std::string populated_sql = sql;
if (boost::algorithm::icontains(populated_sql, scale_denom_token_))
{
std::ostringstream ss;
ss << scale_denom;
boost::algorithm::replace_all(populated_sql, scale_denom_token_, ss.str());
}
if (boost::algorithm::icontains(sql, pixel_width_token_))
{
std::ostringstream ss;
ss << pixel_width;
boost::algorithm::replace_all(populated_sql, pixel_width_token_, ss.str());
}
if (boost::algorithm::icontains(sql, pixel_height_token_))
{
std::ostringstream ss;
ss << pixel_height;
boost::algorithm::replace_all(populated_sql, pixel_height_token_, ss.str());
}
if (boost::algorithm::icontains(populated_sql, bbox_token_))
{
boost::algorithm::replace_all(populated_sql, bbox_token_, sql_bbox(env));
}
return populated_sql;
}
featureset_ptr occi_datasource::features(query const& q) const
{
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "occi_datasource::features");
#endif
box2d<double> const& box = q.get_bbox();
const double px_gw = 1.0 / std::get<0>(q.resolution());
const double px_gh = 1.0 / std::get<1>(q.resolution());
const double scale_denom = q.scale_denominator();
std::ostringstream s;
s << "SELECT ";
if (use_wkb_)
{
s << "SDO_UTIL.TO_WKBGEOMETRY(" << geometry_field_ << ")";
}
else
{
s << geometry_field_;
}
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();
mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
for (; pos != end; ++pos)
{
s << ", " << *pos;
ctx->push(*pos);
}
std::string query = populate_tokens(table_, scale_denom, box, px_gw, px_gh);
if (use_spatial_index_)
{
std::ostringstream spatial_sql;
spatial_sql << " WHERE SDO_FILTER(";
spatial_sql << geometry_field_ << "," << sql_bbox(box);
spatial_sql << ", 'querytype = WINDOW') = 'TRUE'";
if (boost::algorithm::ifind_first(query, "WHERE"))
{
boost::algorithm::ireplace_first(query, "WHERE", spatial_sql.str() + " AND ");
}
else if (boost::algorithm::ifind_first(query, table_name_))
{
boost::algorithm::ireplace_first(query, table_name_, table_name_ + " " + spatial_sql.str());
}
else
{
MAPNIK_LOG_WARN(occi) << "occi_datasource: cannot determine where to add the spatial filter declaration";
}
}
s << " FROM " << query;
if (row_limit_ > 0)
{
s << " WHERE ROWNUM < " << row_limit_;
}
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
return std::make_shared<occi_featureset>(pool_,
conn_,
ctx,
s.str(),
desc_.get_encoding(),
use_connection_pool_,
use_wkb_,
row_prefetch_);
}
featureset_ptr occi_datasource::features_at_point(coord2d const& pt, double tol) const
{
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "occi_datasource::features_at_point");
#endif
std::ostringstream s;
s << "SELECT ";
if (use_wkb_)
{
s << "SDO_UTIL.TO_WKBGEOMETRY(" << geometry_field_ << ")";
}
else
{
s << geometry_field_;
}
std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin();
std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end();
mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
while (itr != end)
{
s << ", " << itr->get_name();
ctx->push(itr->get_name());
++itr;
}
box2d<double> box(pt.x - tol, pt.y - tol, pt.x + tol, pt.y + tol);
std::string query = populate_tokens(table_, FMAX, box, 0, 0);
if (use_spatial_index_)
{
std::ostringstream spatial_sql;
spatial_sql << " WHERE SDO_FILTER(";
spatial_sql << geometry_field_ << "," << sql_bbox(box);
spatial_sql << ", 'querytype = WINDOW') = 'TRUE'";
if (boost::algorithm::ifind_first(query, "WHERE"))
{
boost::algorithm::ireplace_first(query, "WHERE", spatial_sql.str() + " AND ");
}
else if (boost::algorithm::ifind_first(query, table_name_))
{
boost::algorithm::ireplace_first(query, table_name_, table_name_ + " " + spatial_sql.str());
}
else
{
MAPNIK_LOG_WARN(occi) << "occi_datasource: Cannot determine where to add the spatial filter declaration";
}
}
s << " FROM " << query;
if (row_limit_ > 0)
{
s << " WHERE ROWNUM < " << row_limit_;
}
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
return std::make_shared<occi_featureset>(pool_,
conn_,
ctx,
s.str(),
desc_.get_encoding(),
use_connection_pool_,
use_wkb_,
row_prefetch_);
}

View file

@ -1,95 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#ifndef OCCI_DATASOURCE_HPP
#define OCCI_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>
#include <mapnik/value_types.hpp>
// boost
#include <boost/optional.hpp>
#include <memory>
// stl
#include <vector>
#include <string>
// oci
#include "occi_types.hpp"
class occi_datasource : public mapnik::datasource
{
public:
occi_datasource(mapnik::parameters const& params);
virtual ~occi_datasource ();
mapnik::datasource::datasource_t type() const;
static const char * name();
mapnik::featureset_ptr features(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const;
mapnik::box2d<double> envelope() const;
boost::optional<mapnik::datasource_geometry_t> get_geometry_type() const;
mapnik::layer_descriptor get_descriptor() const;
private:
std::string sql_bbox(mapnik::box2d<double> const& env) const;
std::string populate_tokens(std::string const& sql,
double scale_denom,
mapnik::box2d<double> const& env,
double pixel_width,
double pixel_height) const;
static const std::string METADATA_TABLE;
static const double FMAX;
mapnik::datasource::datasource_t type_;
std::string table_;
std::string table_name_;
std::string fields_;
std::string geometry_field_;
int srid_;
bool srid_initialized_;
mutable bool extent_initialized_;
mutable mapnik::box2d<double> extent_;
const std::string bbox_token_;
const std::string scale_denom_token_;
const std::string pixel_width_token_;
const std::string pixel_height_token_;
mapnik::layer_descriptor desc_;
bool use_wkb_;
mapnik::value_integer row_limit_;
int row_prefetch_;
oracle::occi::StatelessConnectionPool* pool_;
oracle::occi::Connection* conn_;
bool use_connection_pool_;
bool use_spatial_index_;
bool estimate_extent_;
};
#endif // OCCI_DATASOURCE_HPP

View file

@ -1,516 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
// mapnik
#include <mapnik/global.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/feature_factory.hpp>
#include <mapnik/make_unique.hpp>
// ogr
#include "occi_featureset.hpp"
using mapnik::query;
using mapnik::box2d;
using mapnik::feature_ptr;
using mapnik::geometry_type;
using mapnik::geometry_utils;
using mapnik::transcoder;
using mapnik::datasource_exception;
using mapnik::feature_factory;
using oracle::occi::Connection;
using oracle::occi::Statement;
using oracle::occi::ResultSet;
using oracle::occi::StatelessConnectionPool;
using oracle::occi::MetaData;
using oracle::occi::SQLException;
using oracle::occi::Type;
using oracle::occi::Number;
using oracle::occi::Blob;
occi_featureset::occi_featureset(StatelessConnectionPool* pool,
Connection* conn,
mapnik::context_ptr const& ctx,
std::string const& sqlstring,
std::string const& encoding,
bool use_connection_pool,
bool use_wkb,
unsigned prefetch_rows)
: rs_(nullptr),
tr_(new transcoder(encoding)),
feature_id_(1),
ctx_(ctx),
use_wkb_(use_wkb)
{
if (use_connection_pool)
{
conn_.set_pool(pool);
}
else
{
conn_.set_connection(conn, false);
}
try
{
rs_ = conn_.execute_query(sqlstring, prefetch_rows);
}
catch (SQLException &ex)
{
MAPNIK_LOG_ERROR(occi) << "OCCI Plugin: error processing " << sqlstring << " : " << ex.getMessage();
rs_ = nullptr;
}
}
occi_featureset::~occi_featureset()
{
}
feature_ptr occi_featureset::next()
{
while (rs_ != nullptr && rs_->next() == oracle::occi::ResultSet::DATA_AVAILABLE)
{
feature_ptr feature(feature_factory::create(ctx_, feature_id_));
if (use_wkb_)
{
Blob blob = rs_->getBlob(1);
blob.open(oracle::occi::OCCI_LOB_READONLY);
unsigned int size = blob.length();
if (buffer_.size() < size)
{
buffer_.resize(size);
}
oracle::occi::Stream* instream = blob.getStream(1, 0);
instream->readBuffer(buffer_.data(), size);
blob.closeStream(instream);
blob.close();
if (! geometry_utils::from_wkb(feature->paths(), buffer_.data(), size))
{
continue;
}
}
else
{
const std::unique_ptr<SDOGeometry> geom(dynamic_cast<SDOGeometry*>(rs_->getObject(1)));
if (geom.get())
{
convert_geometry(geom.get(), feature);
}
else
{
continue;
}
}
std::vector<MetaData> listOfColumns = rs_->getColumnListMetaData();
for (unsigned int i = 1; i < listOfColumns.size(); ++i)
{
MetaData columnObj = listOfColumns[i];
std::string fld_name = columnObj.getString(MetaData::ATTR_NAME);
int type_oid = columnObj.getInt(MetaData::ATTR_DATA_TYPE);
/*
int type_code = columnObj.getInt(MetaData::ATTR_TYPECODE);
if (type_code == OCCI_TYPECODE_OBJECT)
{
continue;
}
*/
switch (type_oid)
{
case oracle::occi::OCCIBOOL:
feature->put(fld_name, (rs_->getInt(i + 1) != 0));
break;
case oracle::occi::OCCIINT:
case oracle::occi::OCCIUNSIGNED_INT:
feature->put(fld_name, static_cast<mapnik::value_integer>(rs_->getInt(i + 1)));
break;
case oracle::occi::OCCIFLOAT:
case oracle::occi::OCCIBFLOAT:
feature->put(fld_name, (double)rs_->getFloat(i + 1));
break;
case oracle::occi::OCCIDOUBLE:
case oracle::occi::OCCIBDOUBLE:
case oracle::occi::OCCINUMBER:
case oracle::occi::OCCI_SQLT_NUM:
feature->put(fld_name, rs_->getDouble(i + 1));
break;
case oracle::occi::OCCICHAR:
case oracle::occi::OCCISTRING:
case oracle::occi::OCCI_SQLT_AFC:
case oracle::occi::OCCI_SQLT_AVC:
case oracle::occi::OCCI_SQLT_CHR:
case oracle::occi::OCCI_SQLT_LNG:
case oracle::occi::OCCI_SQLT_LVC:
case oracle::occi::OCCI_SQLT_STR:
case oracle::occi::OCCI_SQLT_VCS:
case oracle::occi::OCCI_SQLT_VNU:
case oracle::occi::OCCI_SQLT_VBI:
case oracle::occi::OCCI_SQLT_VST:
case oracle::occi::OCCIROWID:
case oracle::occi::OCCI_SQLT_RDD:
case oracle::occi::OCCI_SQLT_RID:
case oracle::occi::OCCIDATE:
case oracle::occi::OCCI_SQLT_DAT:
case oracle::occi::OCCI_SQLT_DATE:
case oracle::occi::OCCI_SQLT_TIME:
case oracle::occi::OCCI_SQLT_TIME_TZ:
case oracle::occi::OCCITIMESTAMP:
case oracle::occi::OCCI_SQLT_TIMESTAMP:
case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ:
case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ:
feature->put(fld_name, static_cast<mapnik::value_unicode_string>(tr_->transcode(rs_->getString(i + 1).c_str())));
break;
case oracle::occi::OCCIINTERVALDS:
case oracle::occi::OCCIINTERVALYM:
case oracle::occi::OCCI_SQLT_INTERVAL_YM:
case oracle::occi::OCCI_SQLT_INTERVAL_DS:
case oracle::occi::OCCIANYDATA:
case oracle::occi::OCCIBLOB:
case oracle::occi::OCCIBFILE:
case oracle::occi::OCCIBYTES:
case oracle::occi::OCCICLOB:
case oracle::occi::OCCIVECTOR:
case oracle::occi::OCCIMETADATA:
case oracle::occi::OCCIPOBJECT:
case oracle::occi::OCCIREF:
case oracle::occi::OCCIREFANY:
case oracle::occi::OCCISTREAM:
case oracle::occi::OCCICURSOR:
case oracle::occi::OCCI_SQLT_FILE:
case oracle::occi::OCCI_SQLT_CFILE:
case oracle::occi::OCCI_SQLT_REF:
case oracle::occi::OCCI_SQLT_CLOB:
case oracle::occi::OCCI_SQLT_BLOB:
case oracle::occi::OCCI_SQLT_RSET:
{
MAPNIK_LOG_WARN(occi) << "occi_featureset: Unsupported datatype "
<< occi_enums::resolve_datatype(type_oid)
<< " (type_oid=" << type_oid << ")";
break;
}
default: // shouldn't get here
{
MAPNIK_LOG_WARN(occi) << "occi_featureset: Unknown datatype "
<< "(type_oid=" << type_oid << ")";
break;
}
}
}
++feature_id_;
return feature;
}
return feature_ptr();
}
void occi_featureset::convert_geometry(SDOGeometry* geom, feature_ptr feature)
{
int gtype = (int)geom->getSdo_gtype();
int dimensions = gtype / 1000;
int lrsvalue = (gtype - dimensions * 1000) / 100;
int geomtype = (gtype - dimensions * 1000 - lrsvalue * 100);
const std::vector<Number>& elem_info = geom->getSdo_elem_info();
const std::vector<Number>& ordinates = geom->getSdo_ordinates();
const int ordinates_size = (int)ordinates.size();
switch (geomtype)
{
case SDO_GTYPE_POINT:
{
SDOPointType* sdopoint = geom->getSdo_point();
if (sdopoint && ! sdopoint->isNull())
{
std::unique_ptr<geometry_type> point = std::make_unique<geometry_type>(mapnik::geometry::geometry_types::Point);
point->move_to(sdopoint->getX(), sdopoint->getY());
feature->add_geometry(point.release());
}
}
break;
case SDO_GTYPE_LINE:
{
if (ordinates_size >= dimensions)
{
const bool is_single_geom = true;
const bool is_point_type = false;
convert_ordinates(feature,
mapnik::geometry::geometry_types::LineString,
elem_info,
ordinates,
dimensions,
is_single_geom,
is_point_type);
}
}
break;
case SDO_GTYPE_POLYGON:
{
if (ordinates_size >= dimensions)
{
const bool is_single_geom = true;
const bool is_point_type = false;
convert_ordinates(feature,
mapnik::geometry::geometry_types::Polygon,
elem_info,
ordinates,
dimensions,
is_single_geom,
is_point_type);
}
}
break;
case SDO_GTYPE_MULTIPOINT:
{
if (ordinates_size >= dimensions)
{
const bool is_single_geom = false;
const bool is_point_type = true;
convert_ordinates(feature,
mapnik::geometry::geometry_types::Point,
elem_info,
ordinates,
dimensions,
is_single_geom,
is_point_type);
}
}
break;
case SDO_GTYPE_MULTILINE:
{
if (ordinates_size >= dimensions)
{
const bool is_single_geom = false;
const bool is_point_type = false;
convert_ordinates(feature,
mapnik::geometry::geometry_types::LineString,
elem_info,
ordinates,
dimensions,
is_single_geom,
is_point_type);
}
}
break;
case SDO_GTYPE_MULTIPOLYGON:
{
if (ordinates_size >= dimensions)
{
const bool is_single_geom = false;
const bool is_point_type = false;
convert_ordinates(feature,
mapnik::geometry::geometry_types::Polygon,
elem_info,
ordinates,
dimensions,
is_single_geom,
is_point_type);
}
}
break;
case SDO_GTYPE_COLLECTION:
{
if (ordinates_size >= dimensions)
{
const bool is_single_geom = false;
const bool is_point_type = false;
convert_ordinates(feature,
mapnik::geometry::geometry_types::Polygon,
elem_info,
ordinates,
dimensions,
is_single_geom,
is_point_type);
}
}
break;
case SDO_GTYPE_UNKNOWN:
default:
{
MAPNIK_LOG_WARN(occi) << "occi_featureset: Unknown oracle enum "
<< occi_enums::resolve_gtype(geomtype)
<< "(gtype=" << gtype << ")";
}
break;
}
}
void occi_featureset::convert_ordinates(mapnik::feature_ptr feature,
const mapnik::geometry_type::types& geom_type,
const std::vector<Number>& elem_info,
const std::vector<Number>& ordinates,
const int dimensions,
const bool is_single_geom,
const bool is_point_geom)
{
const int elem_size = elem_info.size();
const int ord_size = ordinates.size();
if (elem_size >= 0)
{
int offset = elem_info[0];
int etype = elem_info[1];
int interp = elem_info[2];
if (! is_single_geom && elem_size > SDO_ELEM_INFO_SIZE)
{
geometry_type* geom = new geometry_type(geom_type);
for (int i = SDO_ELEM_INFO_SIZE; i < elem_size; i+=3)
{
int next_offset = elem_info[i];
int next_etype = elem_info[i + 1];
int next_interp = elem_info[i + 2];
bool is_linear_element = true;
bool is_unknown_etype = false;
mapnik::geometry_type::types gtype = mapnik::geometry::geometry_types::Point;
switch (etype)
{
case SDO_ETYPE_POINT:
if (interp == SDO_INTERPRETATION_POINT) {}
if (interp > SDO_INTERPRETATION_POINT) {}
gtype = mapnik::geometry::geometry_types::Point;
break;
case SDO_ETYPE_LINESTRING:
if (interp == SDO_INTERPRETATION_STRAIGHT) {}
if (interp == SDO_INTERPRETATION_CIRCULAR) {}
gtype = mapnik::geometry::geometry_types::LineString;
break;
case SDO_ETYPE_POLYGON:
case SDO_ETYPE_POLYGON_INTERIOR:
if (interp == SDO_INTERPRETATION_STRAIGHT) {}
if (interp == SDO_INTERPRETATION_CIRCULAR) {}
if (interp == SDO_INTERPRETATION_RECTANGLE) {}
if (interp == SDO_INTERPRETATION_CIRCLE) {}
gtype = mapnik::geometry::geometry_types::Polygon;
break;
case SDO_ETYPE_COMPOUND_LINESTRING:
case SDO_ETYPE_COMPOUND_POLYGON:
case SDO_ETYPE_COMPOUND_POLYGON_INTERIOR:
// interp = next ETYPE to consider
is_linear_element = false;
gtype = mapnik::geometry::geometry_types::Polygon;
break;
case SDO_ETYPE_UNKNOWN: // unknown
default:
is_unknown_etype = true;
break;
}
if (is_unknown_etype)
{
break;
}
if (is_linear_element)
{
if (geom)
{
feature->add_geometry(geom);
}
geom = new geometry_type(gtype);
fill_geometry_type(geom,
offset - 1,
next_offset - 1,
ordinates,
dimensions,
is_point_geom);
}
offset = next_offset;
etype = next_etype;
interp = next_interp;
}
if (geom)
{
feature->add_geometry(geom);
geom = 0;
}
}
else
{
geometry_type * geom = new geometry_type(geom_type);
fill_geometry_type(geom,
offset - 1,
ord_size,
ordinates,
dimensions,
is_point_geom);
feature->add_geometry(geom);
}
}
}
void occi_featureset::fill_geometry_type(geometry_type* geom,
const int real_offset,
const int next_offset,
const std::vector<Number>& ordinates,
const int dimensions,
const bool is_point_geom)
{
geom->move_to((double) ordinates[real_offset], (double) ordinates[real_offset + 1]);
if (is_point_geom)
{
for (int p = real_offset + dimensions; p < next_offset; p += dimensions)
{
geom->move_to((double) ordinates[p], (double) ordinates[p + 1]);
}
}
else
{
for (int p = real_offset + dimensions; p < next_offset; p += dimensions)
{
geom->line_to((double) ordinates[p], (double) ordinates[p + 1]);
}
}
}

View file

@ -1,77 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#ifndef OCCI_FEATURESET_HPP
#define OCCI_FEATURESET_HPP
// mapnik
#include <mapnik/feature.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/unicode.hpp>
// stl
#include <memory>
// oci
#include "occi_types.hpp"
#include <vector>
class occi_featureset : public mapnik::Featureset
{
public:
occi_featureset(oracle::occi::StatelessConnectionPool* pool,
oracle::occi::Connection* conn,
mapnik::context_ptr const& ctx,
std::string const& sqlstring,
std::string const& encoding,
bool use_connection_pool,
bool use_wkb,
unsigned prefetch_rows);
virtual ~occi_featureset();
mapnik::feature_ptr next();
private:
void convert_geometry (SDOGeometry* geom, mapnik::feature_ptr feature);
void convert_ordinates (mapnik::feature_ptr feature,
const mapnik::geometry_type::types& geom_type,
const std::vector<oracle::occi::Number>& elem_info,
const std::vector<oracle::occi::Number>& ordinates,
const int dimensions,
const bool is_single_geom,
const bool is_point_geom);
void fill_geometry_type (mapnik::geometry_type* geom,
const int real_offset,
const int next_offset,
const std::vector<oracle::occi::Number>& ordinates,
const int dimensions,
const bool is_point_geom);
occi_connection_ptr conn_;
oracle::occi::ResultSet* rs_;
const std::unique_ptr<mapnik::transcoder> tr_;
mapnik::value_integer feature_id_;
mapnik::context_ptr ctx_;
bool use_wkb_;
std::vector<char> buffer_;
};
#endif // OCCI_FEATURESET_HPP

View file

@ -1,91 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#include "occi_types.hpp"
std::string occi_enums::resolve_gtype(int gtype)
{
switch (gtype)
{
case SDO_GTYPE_UNKNOWN: return "SDO_GTYPE_UNKNOWN";
case SDO_GTYPE_POINT: return "SDO_GTYPE_POINT";
case SDO_GTYPE_LINE: return "SDO_GTYPE_LINE";
case SDO_GTYPE_POLYGON: return "SDO_GTYPE_POLYGON";
case SDO_GTYPE_MULTIPOINT: return "SDO_GTYPE_MULTIPOINT";
case SDO_GTYPE_MULTILINE: return "SDO_GTYPE_MULTILINE";
case SDO_GTYPE_MULTIPOLYGON: return "SDO_GTYPE_MULTIPOLYGON";
case SDO_GTYPE_COLLECTION: return "SDO_GTYPE_COLLECTION";
default: return "<unknown SDO_GTYPE>";
}
}
std::string occi_enums::resolve_etype(int etype)
{
switch (etype)
{
case SDO_ETYPE_UNKNOWN: return "SDO_ETYPE_UNKNOWN";
case SDO_ETYPE_POINT: return "SDO_ETYPE_POINT";
case SDO_ETYPE_LINESTRING: return "SDO_ETYPE_LINESTRING";
case SDO_ETYPE_POLYGON: return "SDO_ETYPE_POLYGON";
case SDO_ETYPE_POLYGON_INTERIOR: return "SDO_ETYPE_POLYGON_INTERIOR";
case SDO_ETYPE_COMPOUND_LINESTRING: return "SDO_ETYPE_COMPOUND_LINESTRING";
case SDO_ETYPE_COMPOUND_POLYGON: return "SDO_ETYPE_COMPOUND_POLYGON";
case SDO_ETYPE_COMPOUND_POLYGON_INTERIOR: return "SDO_ETYPE_COMPOUND_POLYGON_INTERIOR";
default: return "<unknown SDO_ETYPE>";
}
}
std::string occi_enums::resolve_datatype(int type_id)
{
switch (type_id)
{
case oracle::occi::OCCIINT: return "OCCIINT";
case oracle::occi::OCCIUNSIGNED_INT: return "OCCIUNSIGNED_INT";
case oracle::occi::OCCIFLOAT: return "OCCIFLOAT";
case oracle::occi::OCCIBFLOAT: return "OCCIBFLOAT";
case oracle::occi::OCCIDOUBLE: return "OCCIDOUBLE";
case oracle::occi::OCCIBDOUBLE: return "OCCIBDOUBLE";
case oracle::occi::OCCINUMBER: return "OCCINUMBER";
case oracle::occi::OCCI_SQLT_NUM: return "OCCI_SQLT_NUM";
case oracle::occi::OCCICHAR: return "OCCICHAR";
case oracle::occi::OCCISTRING: return "OCCISTRING";
case oracle::occi::OCCI_SQLT_AFC: return "OCCI_SQLT_AFC";
case oracle::occi::OCCI_SQLT_AVC: return "OCCI_SQLT_AVC";
case oracle::occi::OCCI_SQLT_CHR: return "OCCI_SQLT_CHR";
case oracle::occi::OCCI_SQLT_LVC: return "OCCI_SQLT_LVC";
case oracle::occi::OCCI_SQLT_LNG: return "OCCI_SQLT_LNG";
case oracle::occi::OCCI_SQLT_STR: return "OCCI_SQLT_STR";
case oracle::occi::OCCI_SQLT_VCS: return "OCCI_SQLT_VCS";
case oracle::occi::OCCI_SQLT_VNU: return "OCCI_SQLT_VNU";
case oracle::occi::OCCI_SQLT_VBI: return "OCCI_SQLT_VBI";
case oracle::occi::OCCI_SQLT_VST: return "OCCI_SQLT_VST";
case oracle::occi::OCCI_SQLT_RDD: return "OCCI_SQLT_RDD";
case oracle::occi::OCCIDATE: return "OCCIDATE";
case oracle::occi::OCCITIMESTAMP: return "OCCITIMESTAMP";
case oracle::occi::OCCI_SQLT_DAT: return "OCCI_SQLT_DAT";
case oracle::occi::OCCI_SQLT_TIMESTAMP: return "OCCI_SQLT_TIMESTAMP";
case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ: return "OCCI_SQLT_TIMESTAMP_LTZ";
case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ: return "OCCI_SQLT_TIMESTAMP_TZ";
case oracle::occi::OCCIPOBJECT: return "OCCIPOBJECT";
default: return "<unknown ATTR_DATA_TYPE>";
}
}

View file

@ -1,265 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#ifndef OCCI_TYPES_HPP
#define OCCI_TYPES_HPP
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/util/singleton.hpp>
// occi
#include <occi.h>
// ott generated SDOGeometry classes
#include "spatial_classesh.h"
#include "spatial_classesm.h"
// check for oracle support
#if OCCI_MAJOR_VERSION >= 10 && OCCI_MINOR_VERSION >= 1
// We have at least ORACLE 10g >= 10.2.0.X
#else
#error Only ORACLE 10g >= 10.2.0.X is supported !
#endif
// geometry types definitions
enum
{
SDO_GTYPE_UNKNOWN = 0,
SDO_GTYPE_POINT = 1,
SDO_GTYPE_LINE = 2,
SDO_GTYPE_POLYGON = 3,
SDO_GTYPE_COLLECTION = 4,
SDO_GTYPE_MULTIPOINT = 5,
SDO_GTYPE_MULTILINE = 6,
SDO_GTYPE_MULTIPOLYGON = 7,
SDO_GTYPE_2DPOINT = 2001,
SDO_GTYPE_2DLINE = 2002,
SDO_GTYPE_2DPOLYGON = 2003,
SDO_GTYPE_2DMULTIPOINT = 2005,
SDO_GTYPE_2DMULTILINE = 2006,
SDO_GTYPE_2DMULTIPOLYGON = 2007,
SDO_ELEM_INFO_SIZE = 3,
SDO_ETYPE_UNKNOWN = 0,
SDO_ETYPE_POINT = 1,
SDO_ETYPE_LINESTRING = 2,
SDO_ETYPE_POLYGON = 1003,
SDO_ETYPE_POLYGON_INTERIOR = 2003,
SDO_ETYPE_COMPOUND_LINESTRING = 4,
SDO_ETYPE_COMPOUND_POLYGON = 1005,
SDO_ETYPE_COMPOUND_POLYGON_INTERIOR = 2005,
SDO_INTERPRETATION_POINT = 1,
SDO_INTERPRETATION_RECTANGLE = 3,
SDO_INTERPRETATION_CIRCLE = 4,
SDO_INTERPRETATION_STRAIGHT = 1,
SDO_INTERPRETATION_CIRCULAR = 2
};
class occi_environment : public mapnik::singleton<occi_environment, mapnik::CreateStatic>
{
friend class mapnik::CreateStatic<occi_environment>;
public:
oracle::occi::Environment* get_environment()
{
return env_;
}
oracle::occi::Connection* create_connection(
const std::string& user,
const std::string& password,
const std::string& host)
{
MAPNIK_LOG_DEBUG(occi) << "occi_environment: create_connection";
return env_->createConnection(user, password, host);
}
void destroy_connection(oracle::occi::Connection* conn)
{
env_->terminateConnection(conn);
}
oracle::occi::StatelessConnectionPool* create_pool(
const std::string& user,
const std::string& password,
const std::string& host,
int max_size,
int initial_size,
int incr_size)
{
MAPNIK_LOG_DEBUG(occi) << "occi_environment: create_pool";
return env_->createStatelessConnectionPool(
user,
password,
host,
max_size,
initial_size,
incr_size,
oracle::occi::StatelessConnectionPool::HOMOGENEOUS);
}
void destroy_pool(oracle::occi::StatelessConnectionPool* pool)
{
env_->terminateStatelessConnectionPool(
pool,
oracle::occi::StatelessConnectionPool::SPD_FORCE);
}
private:
occi_environment()
: env_(0)
{
MAPNIK_LOG_DEBUG(occi) << "occi_environment: constructor";
env_ = oracle::occi::Environment::createEnvironment(
(oracle::occi::Environment::Mode)(oracle::occi::Environment::OBJECT
| oracle::occi::Environment::THREADED_MUTEXED));
RegisterClasses(env_);
}
~occi_environment()
{
MAPNIK_LOG_DEBUG(occi) << "occi_environment: destructor";
oracle::occi::Environment::terminateEnvironment(env_);
env_ = 0;
}
oracle::occi::Environment* env_;
};
class occi_connection_ptr
{
public:
explicit occi_connection_ptr()
: pool_(0),
conn_(0),
stmt_(0),
rs_(0),
owns_connection_(false)
{
}
~occi_connection_ptr()
{
close_query(true);
}
void set_pool(oracle::occi::StatelessConnectionPool* pool)
{
close_query(true);
pool_ = pool;
conn_ = pool_->getConnection();
owns_connection_ = true;
}
void set_connection(oracle::occi::Connection* conn, bool owns_connection)
{
close_query(true);
pool_ = 0;
conn_ = conn;
owns_connection_ = owns_connection;
}
oracle::occi::ResultSet* execute_query(std::string const& s, const unsigned prefetch = 0)
{
close_query(false);
MAPNIK_LOG_DEBUG(occi) << "occi_connection_ptr: " << s;
stmt_ = conn_->createStatement(s);
if (prefetch > 0)
{
stmt_->setPrefetchMemorySize(0);
stmt_->setPrefetchRowCount(prefetch);
}
rs_ = stmt_->executeQuery();
return rs_;
}
private:
void close_query(const bool release_connection)
{
if (conn_)
{
if (stmt_)
{
if (rs_)
{
stmt_->closeResultSet(rs_);
rs_ = 0;
}
conn_->terminateStatement(stmt_);
stmt_ = 0;
}
if (release_connection)
{
if (pool_)
{
pool_->releaseConnection(conn_);
}
else
{
if (owns_connection_)
{
occi_environment::instance().destroy_connection(conn_);
}
}
conn_ = 0;
}
}
}
oracle::occi::StatelessConnectionPool* pool_;
oracle::occi::Connection* conn_;
oracle::occi::Statement* stmt_;
oracle::occi::ResultSet* rs_;
bool owns_connection_;
};
class occi_enums
{
public:
static std::string resolve_gtype(int gtype);
static std::string resolve_etype(int etype);
static std::string resolve_datatype(int type_id);
};
#endif // OCCI_TYPES_HPP

View file

@ -1,147 +0,0 @@
#ifndef SPATIAL_CLASSESH_ORACLE
# define SPATIAL_CLASSESH_ORACLE
#ifndef OCCI_ORACLE
# include <occi.h>
#endif
class SDOPointType;
class SDOGeometry;
/************************************************************/
// generated declarations for the SDO_POINT_TYPE object type.
/************************************************************/
class SDOPointType : public oracle::occi::PObject {
private:
oracle::occi::Number X;
oracle::occi::Number Y;
oracle::occi::Number Z;
public:
oracle::occi::Number getX() const;
void setX(const oracle::occi::Number &value);
oracle::occi::Number getY() const;
void setY(const oracle::occi::Number &value);
oracle::occi::Number getZ() const;
void setZ(const oracle::occi::Number &value);
void *operator new(size_t size);
void *operator new(size_t size, const oracle::occi::Connection * sess,
const OCCI_STD_NAMESPACE::string& table);
void *operator new(size_t, void *ctxOCCI_);
void *operator new(size_t size, const oracle::occi::Connection *sess,
const OCCI_STD_NAMESPACE::string &tableName,
const OCCI_STD_NAMESPACE::string &typeName,
const OCCI_STD_NAMESPACE::string &tableSchema,
const OCCI_STD_NAMESPACE::string &typeSchema);
OCCI_STD_NAMESPACE::string getSQLTypeName() const;
void getSQLTypeName(oracle::occi::Environment *env, void **schemaName,
unsigned int &schemaNameLen, void **typeName,
unsigned int &typeNameLen) const;
SDOPointType();
SDOPointType(void *ctxOCCI_) : oracle::occi::PObject (ctxOCCI_) { }
static void *readSQL(void *ctxOCCI_);
virtual void readSQL(oracle::occi::AnyData& streamOCCI_);
static void writeSQL(void *objOCCI_, void *ctxOCCI_);
virtual void writeSQL(oracle::occi::AnyData& streamOCCI_);
~SDOPointType();
};
/************************************************************/
// generated declarations for the SDO_GEOMETRY object type.
/************************************************************/
class SDOGeometry : public oracle::occi::PObject {
private:
oracle::occi::Number SDO_GTYPE;
oracle::occi::Number SDO_SRID;
SDOPointType * SDO_POINT;
OCCI_STD_NAMESPACE::vector< oracle::occi::Number > SDO_ELEM_INFO;
OCCI_STD_NAMESPACE::vector< oracle::occi::Number > SDO_ORDINATES;
public:
oracle::occi::Number getSdo_gtype() const;
void setSdo_gtype(const oracle::occi::Number &value);
oracle::occi::Number getSdo_srid() const;
void setSdo_srid(const oracle::occi::Number &value);
SDOPointType * getSdo_point() const;
void setSdo_point(SDOPointType * value);
OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& getSdo_elem_info();
const OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& getSdo_elem_info() const;
void setSdo_elem_info(const OCCI_STD_NAMESPACE::vector< oracle::occi::Number > &value);
OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& getSdo_ordinates();
const OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& getSdo_ordinates() const;
void setSdo_ordinates(const OCCI_STD_NAMESPACE::vector< oracle::occi::Number > &value);
void *operator new(size_t size);
void *operator new(size_t size, const oracle::occi::Connection * sess,
const OCCI_STD_NAMESPACE::string& table);
void *operator new(size_t, void *ctxOCCI_);
void *operator new(size_t size, const oracle::occi::Connection *sess,
const OCCI_STD_NAMESPACE::string &tableName,
const OCCI_STD_NAMESPACE::string &typeName,
const OCCI_STD_NAMESPACE::string &tableSchema,
const OCCI_STD_NAMESPACE::string &typeSchema);
OCCI_STD_NAMESPACE::string getSQLTypeName() const;
void getSQLTypeName(oracle::occi::Environment *env, void **schemaName,
unsigned int &schemaNameLen, void **typeName,
unsigned int &typeNameLen) const;
SDOGeometry();
SDOGeometry(void *ctxOCCI_) : oracle::occi::PObject (ctxOCCI_) { }
static void *readSQL(void *ctxOCCI_);
virtual void readSQL(oracle::occi::AnyData& streamOCCI_);
static void writeSQL(void *objOCCI_, void *ctxOCCI_);
virtual void writeSQL(oracle::occi::AnyData& streamOCCI_);
~SDOGeometry();
};
#endif

View file

@ -1,11 +0,0 @@
#ifndef SPATIAL_CLASSESM_ORACLE
# include "spatial_classesm.h"
#endif
void RegisterClasses(oracle::occi::Environment* envOCCI_)
{
oracle::occi::Map *mapOCCI_ = envOCCI_->getMap();
mapOCCI_->put("MDSYS.SDO_POINT_TYPE", &SDOPointType::readSQL, &SDOPointType::writeSQL);
mapOCCI_->put("MDSYS.SDO_GEOMETRY", &SDOGeometry::readSQL, &SDOGeometry::writeSQL);
}

View file

@ -1,14 +0,0 @@
#ifndef SPATIAL_CLASSESM_ORACLE
# define SPATIAL_CLASSESM_ORACLE
#ifndef OCCI_ORACLE
# include <occi.h>
#endif
#ifndef SPATIAL_CLASSESH_ORACLE
# include "spatial_classesh.h"
#endif
void RegisterClasses(oracle::occi::Environment* envOCCI_);
#endif

View file

@ -1,312 +0,0 @@
#ifndef SPATIAL_CLASSESH_ORACLE
# include "spatial_classesh.h"
#endif
/*****************************************************************/
// generated method implementations for the SDO_POINT_TYPE object type.
/*****************************************************************/
oracle::occi::Number SDOPointType::getX() const
{
return X;
}
void SDOPointType::setX(const oracle::occi::Number &value)
{
X = value;
}
oracle::occi::Number SDOPointType::getY() const
{
return Y;
}
void SDOPointType::setY(const oracle::occi::Number &value)
{
Y = value;
}
oracle::occi::Number SDOPointType::getZ() const
{
return Z;
}
void SDOPointType::setZ(const oracle::occi::Number &value)
{
Z = value;
}
void *SDOPointType::operator new(size_t size)
{
return oracle::occi::PObject::operator new(size);
}
void *SDOPointType::operator new(size_t size, const oracle::occi::Connection * sess,
const OCCI_STD_NAMESPACE::string& table)
{
return oracle::occi::PObject::operator new(size, sess, table,
(char *) "MDSYS.SDO_POINT_TYPE");
}
void *SDOPointType::operator new(size_t size, void *ctxOCCI_)
{
return oracle::occi::PObject::operator new(size, ctxOCCI_);
}
void *SDOPointType::operator new(size_t size,
const oracle::occi::Connection *sess,
const OCCI_STD_NAMESPACE::string &tableName,
const OCCI_STD_NAMESPACE::string &typeName,
const OCCI_STD_NAMESPACE::string &tableSchema,
const OCCI_STD_NAMESPACE::string &typeSchema)
{
return oracle::occi::PObject::operator new(size, sess, tableName,
typeName, tableSchema, typeSchema);
}
OCCI_STD_NAMESPACE::string SDOPointType::getSQLTypeName() const
{
return OCCI_STD_NAMESPACE::string("MDSYS.SDO_POINT_TYPE");
}
void SDOPointType::getSQLTypeName(oracle::occi::Environment *env, void **schemaName,
unsigned int &schemaNameLen, void **typeName, unsigned int &typeNameLen) const
{
PObject::getSQLTypeName(env, &SDOPointType::readSQL, schemaName,
schemaNameLen, typeName, typeNameLen);
}
SDOPointType::SDOPointType()
{
}
void *SDOPointType::readSQL(void *ctxOCCI_)
{
SDOPointType *objOCCI_ = new(ctxOCCI_) SDOPointType(ctxOCCI_);
oracle::occi::AnyData streamOCCI_(ctxOCCI_);
try
{
if (streamOCCI_.isNull())
objOCCI_->setNull();
else
objOCCI_->readSQL(streamOCCI_);
}
catch (oracle::occi::SQLException& excep)
{
delete objOCCI_;
excep.setErrorCtx(ctxOCCI_);
return (void *)nullptr;
}
return (void *)objOCCI_;
}
void SDOPointType::readSQL(oracle::occi::AnyData& streamOCCI_)
{
X = streamOCCI_.getNumber();
Y = streamOCCI_.getNumber();
Z = streamOCCI_.getNumber();
}
void SDOPointType::writeSQL(void *objectOCCI_, void *ctxOCCI_)
{
SDOPointType *objOCCI_ = (SDOPointType *) objectOCCI_;
oracle::occi::AnyData streamOCCI_(ctxOCCI_);
try
{
if (objOCCI_->isNull())
streamOCCI_.setNull();
else
objOCCI_->writeSQL(streamOCCI_);
}
catch (oracle::occi::SQLException& excep)
{
excep.setErrorCtx(ctxOCCI_);
}
return;
}
void SDOPointType::writeSQL(oracle::occi::AnyData& streamOCCI_)
{
streamOCCI_.setNumber(X);
streamOCCI_.setNumber(Y);
streamOCCI_.setNumber(Z);
}
SDOPointType::~SDOPointType()
{
}
/*****************************************************************/
// generated method implementations for the SDO_GEOMETRY object type.
/*****************************************************************/
oracle::occi::Number SDOGeometry::getSdo_gtype() const
{
return SDO_GTYPE;
}
void SDOGeometry::setSdo_gtype(const oracle::occi::Number &value)
{
SDO_GTYPE = value;
}
oracle::occi::Number SDOGeometry::getSdo_srid() const
{
return SDO_SRID;
}
void SDOGeometry::setSdo_srid(const oracle::occi::Number &value)
{
SDO_SRID = value;
}
SDOPointType * SDOGeometry::getSdo_point() const
{
return SDO_POINT;
}
void SDOGeometry::setSdo_point(SDOPointType * value)
{
SDO_POINT = value;
}
OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& SDOGeometry::getSdo_elem_info()
{
return SDO_ELEM_INFO;
}
const OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& SDOGeometry::getSdo_elem_info() const
{
return SDO_ELEM_INFO;
}
void SDOGeometry::setSdo_elem_info(const OCCI_STD_NAMESPACE::vector< oracle::occi::Number > &value)
{
SDO_ELEM_INFO = value;
}
OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& SDOGeometry::getSdo_ordinates()
{
return SDO_ORDINATES;
}
const OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& SDOGeometry::getSdo_ordinates() const
{
return SDO_ORDINATES;
}
void SDOGeometry::setSdo_ordinates(const OCCI_STD_NAMESPACE::vector< oracle::occi::Number > &value)
{
SDO_ORDINATES = value;
}
void *SDOGeometry::operator new(size_t size)
{
return oracle::occi::PObject::operator new(size);
}
void *SDOGeometry::operator new(size_t size, const oracle::occi::Connection * sess,
const OCCI_STD_NAMESPACE::string& table)
{
return oracle::occi::PObject::operator new(size, sess, table,
(char *) "MDSYS.SDO_GEOMETRY");
}
void *SDOGeometry::operator new(size_t size, void *ctxOCCI_)
{
return oracle::occi::PObject::operator new(size, ctxOCCI_);
}
void *SDOGeometry::operator new(size_t size,
const oracle::occi::Connection *sess,
const OCCI_STD_NAMESPACE::string &tableName,
const OCCI_STD_NAMESPACE::string &typeName,
const OCCI_STD_NAMESPACE::string &tableSchema,
const OCCI_STD_NAMESPACE::string &typeSchema)
{
return oracle::occi::PObject::operator new(size, sess, tableName,
typeName, tableSchema, typeSchema);
}
OCCI_STD_NAMESPACE::string SDOGeometry::getSQLTypeName() const
{
return OCCI_STD_NAMESPACE::string("MDSYS.SDO_GEOMETRY");
}
void SDOGeometry::getSQLTypeName(oracle::occi::Environment *env, void **schemaName,
unsigned int &schemaNameLen, void **typeName, unsigned int &typeNameLen) const
{
PObject::getSQLTypeName(env, &SDOGeometry::readSQL, schemaName,
schemaNameLen, typeName, typeNameLen);
}
SDOGeometry::SDOGeometry()
{
SDO_POINT = (SDOPointType *) 0;
}
void *SDOGeometry::readSQL(void *ctxOCCI_)
{
SDOGeometry *objOCCI_ = new(ctxOCCI_) SDOGeometry(ctxOCCI_);
oracle::occi::AnyData streamOCCI_(ctxOCCI_);
try
{
if (streamOCCI_.isNull())
objOCCI_->setNull();
else
objOCCI_->readSQL(streamOCCI_);
}
catch (oracle::occi::SQLException& excep)
{
delete objOCCI_;
excep.setErrorCtx(ctxOCCI_);
return (void *)nullptr;
}
return (void *)objOCCI_;
}
void SDOGeometry::readSQL(oracle::occi::AnyData& streamOCCI_)
{
SDO_GTYPE = streamOCCI_.getNumber();
SDO_SRID = streamOCCI_.getNumber();
SDO_POINT = (SDOPointType *) streamOCCI_.getObject(&SDOPointType::readSQL);
oracle::occi::getVector(streamOCCI_, SDO_ELEM_INFO);
oracle::occi::getVector(streamOCCI_, SDO_ORDINATES);
}
void SDOGeometry::writeSQL(void *objectOCCI_, void *ctxOCCI_)
{
SDOGeometry *objOCCI_ = (SDOGeometry *) objectOCCI_;
oracle::occi::AnyData streamOCCI_(ctxOCCI_);
try
{
if (objOCCI_->isNull())
streamOCCI_.setNull();
else
objOCCI_->writeSQL(streamOCCI_);
}
catch (oracle::occi::SQLException& excep)
{
excep.setErrorCtx(ctxOCCI_);
}
return;
}
void SDOGeometry::writeSQL(oracle::occi::AnyData& streamOCCI_)
{
streamOCCI_.setNumber(SDO_GTYPE);
streamOCCI_.setNumber(SDO_SRID);
streamOCCI_.setObject(SDO_POINT);
oracle::occi::setVector(streamOCCI_, SDO_ELEM_INFO);
oracle::occi::setVector(streamOCCI_, SDO_ORDINATES);
}
SDOGeometry::~SDOGeometry()
{
delete SDO_POINT;
}

View file

@ -1,4 +0,0 @@
TYPE MDSYS.SDO_POINT_TYPE AS SDOPointType
TYPE MDSYS.SDO_GEOMETRY AS SDOGeometry

View file

@ -1,75 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#include "basiccurl.h"
#include <iostream>
#include <cstring>
CURL_LOAD_DATA* grab_http_response(const char* url)
{
CURL_LOAD_DATA* data;
CURL* curl = curl_easy_init();
if(curl)
{
data = do_grab(curl, url);
curl_easy_cleanup(curl);
return data;
}
return nullptr;
}
CURL_LOAD_DATA* do_grab(CURL* curl,const char* url)
{
CURL_LOAD_DATA* data = (CURL_LOAD_DATA*)malloc(sizeof(CURL_LOAD_DATA));
data->data = nullptr;
data->nbytes = 0;
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, response_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, data);
CURLcode res = curl_easy_perform(curl);
if (res !=0) {
std::clog << "error grabbing data\n";
}
return data;
}
size_t response_callback(void* ptr, size_t size, size_t nmemb, void* d)
{
size_t rsize = size * nmemb;
CURL_LOAD_DATA* data = (CURL_LOAD_DATA*)d;
// fprintf(stderr,"rsize is %d\n", rsize);
data->data = (char*)realloc(data->data, (data->nbytes + rsize) * sizeof(char));
std::memcpy(&(data->data[data->nbytes]), ptr, rsize);
data->nbytes += rsize;
// fprintf(stderr,"data->nbytes is %d\n", data->nbytes);
return rsize;
}

View file

@ -1,40 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 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
*
*****************************************************************************/
#ifndef BASICCURL_H
#define BASICCURL_H
#include <curl/curl.h>
#include <cstdlib>
#include <cstring>
typedef struct
{
char *data;
int nbytes;
} CURL_LOAD_DATA;
CURL_LOAD_DATA *grab_http_response(const char *url);
CURL_LOAD_DATA *do_grab(CURL *curl, const char *url);
size_t response_callback(void *ptr ,size_t size, size_t nmemb, void *data);
#endif // BASICCURL_H

View file

@ -1,69 +0,0 @@
#
# This file is part of Mapnik (c++ mapping toolkit)
#
# Copyright (C) 2015 Artem Pavlenko
#
# 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
#
#
Import ('plugin_base')
Import ('env')
from copy import copy
PLUGIN_NAME = 'osm'
plugin_env = plugin_base.Clone()
plugin_sources = Split(
"""
%(PLUGIN_NAME)s.cpp
%(PLUGIN_NAME)s_datasource.cpp
%(PLUGIN_NAME)s_featureset.cpp
osmparser.cpp
dataset_deliverer.cpp
""" % locals()
)
plugin_env['LIBS'] = []
plugin_env.Append(LIBS='xml2')
# Link Library to Dependencies
libraries = copy(plugin_env['LIBS'])
libraries.append(env['ICU_LIB_NAME'])
libraries.append('boost_system%s' % env['BOOST_APPEND'])
if env['PLUGIN_LINKING'] == 'shared':
libraries.append(env['MAPNIK_NAME'])
TARGET = plugin_env.SharedLibrary('../%s' % PLUGIN_NAME,
SHLIBPREFIX='',
SHLIBSUFFIX='.input',
source=plugin_sources,
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' not in COMMAND_LINE_TARGETS:
env.Install(env['MAPNIK_INPUT_PLUGINS_DEST'], TARGET)
env.Alias('install', env['MAPNIK_INPUT_PLUGINS_DEST'])
plugin_obj = {
'LIBS': libraries,
'SOURCES': plugin_sources,
}
Return('plugin_obj')

View file

@ -1,66 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/util/fs.hpp>
// std
#include <sstream>
#include "dataset_deliverer.h"
osm_dataset * dataset_deliverer::dataset = nullptr;
std::string dataset_deliverer::last_bbox = "";
std::string dataset_deliverer::last_filename = "";
osm_dataset* dataset_deliverer::load_from_file(const string& file, const string& parser)
{
// Only actually load from file if we haven't done so already
if (dataset == nullptr)
{
if (!mapnik::util::exists(file))
{
throw mapnik::datasource_exception("OSM Plugin: '" + file + "' does not exist");
}
dataset = new osm_dataset;
if (dataset->load(file.c_str(), parser) == false)
{
return nullptr;
}
atexit(dataset_deliverer::release);
last_filename = file;
}
else if(file != last_filename)
{
dataset = new osm_dataset;
if (dataset->load(file.c_str(), parser) == false)
{
return nullptr;
}
last_filename = file;
}
return dataset;
}

View file

@ -1,230 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#include "osm.h"
#include "osmparser.h"
#include <mapnik/debug.hpp>
#include <libxml/parser.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstring>
polygon_types osm_way::ptypes;
bool osm_dataset::load(const char* filename,std::string const& parser)
{
if (parser == "libxml2")
{
return osmparser::parse(this, filename);
}
return false;
}
osm_dataset::~osm_dataset()
{
clear();
}
void osm_dataset::clear()
{
MAPNIK_LOG_DEBUG(osm) << "osm_dataset: Clear";
MAPNIK_LOG_DEBUG(osm) << "osm_dataset: -- Deleting ways";
for (unsigned int count = 0; count < ways.size(); ++count)
{
delete ways[count];
ways[count] = nullptr;
}
ways.clear();
MAPNIK_LOG_DEBUG(osm) << "osm_dataset: -- Deleting nodes";
for (unsigned int count = 0; count < nodes.size(); ++count)
{
delete nodes[count];
nodes[count] = nullptr;
}
nodes.clear();
MAPNIK_LOG_DEBUG(osm) << "osm_dataset: Clear done";
}
std::string osm_dataset::to_string()
{
std::string result;
for (unsigned int count = 0; count < nodes.size(); ++count)
{
result += nodes[count]->to_string();
}
for (unsigned int count = 0; count < ways.size(); ++count)
{
result += ways[count]->to_string();
}
return result;
}
bounds osm_dataset::get_bounds()
{
bounds b (-180, -90, 180, 90);
for (unsigned int count = 0; count < nodes.size(); ++count)
{
if(nodes[count]->lon > b.w) b.w = nodes[count]->lon;
if(nodes[count]->lon < b.e) b.e = nodes[count]->lon;
if(nodes[count]->lat > b.s) b.s = nodes[count]->lat;
if(nodes[count]->lat < b.n) b.n = nodes[count]->lat;
}
return b;
}
osm_node* osm_dataset::next_node()
{
if (node_i != nodes.end())
{
return *(node_i++);
}
return nullptr;
}
osm_way* osm_dataset::next_way()
{
if (way_i != ways.end())
{
return *(way_i++);
}
return nullptr;
}
osm_item* osm_dataset::next_item()
{
osm_item* item = nullptr;
if (next_item_mode == Node)
{
item = next_node();
if (item == nullptr)
{
next_item_mode = Way;
rewind_ways();
item = next_way();
}
}
else
{
item = next_way();
}
return item;
}
std::set<std::string> osm_dataset::get_keys()
{
std::set<std::string> keys;
for (unsigned int count = 0; count < nodes.size(); ++count)
{
for (std::map<std::string, std::string>::iterator i = nodes[count]->keyvals.begin();
i != nodes[count]->keyvals.end(); i++)
{
keys.insert(i->first);
}
}
for (unsigned int count = 0; count < ways.size(); ++count)
{
for (std::map<std::string, std::string>::iterator i = ways[count]->keyvals.begin();
i != ways[count]->keyvals.end(); i++)
{
keys.insert(i->first);
}
}
return keys;
}
std::string osm_item::to_string()
{
std::ostringstream strm;
strm << "id=" << id << std::endl << "Keyvals: " << std::endl;
for (std::map<std::string, std::string>::iterator i = keyvals.begin();
i != keyvals.end(); i++)
{
strm << "Key " << i->first << " Value " << i->second << std::endl;
}
return strm.str();
}
std::string osm_node::to_string()
{
std::ostringstream strm;
strm << "Node: " << osm_item::to_string() << " lat=" << lat <<" lon=" <<lon << std::endl;
return strm.str();
}
std::string osm_way::to_string()
{
std::ostringstream strm;
strm << "Way: " << osm_item::to_string() << "Nodes in way:";
for (unsigned int count = 0; count < nodes.size(); ++count)
{
if (nodes[count] != nullptr)
{
strm << nodes[count]->id << " ";
}
}
strm << std::endl;
return strm.str();
}
bounds osm_way::get_bounds()
{
bounds b (-180, -90, 180, 90);
for (unsigned int count = 0; count < nodes.size(); ++count)
{
if(nodes[count]->lon > b.w) b.w = nodes[count]->lon;
if(nodes[count]->lon < b.e) b.e = nodes[count]->lon;
if(nodes[count]->lat > b.s) b.s = nodes[count]->lat;
if(nodes[count]->lat < b.n) b.n = nodes[count]->lat;
}
return b;
}
bool osm_way::is_polygon()
{
for (unsigned int count = 0; count < ptypes.ptypes.size(); ++count)
{
if (keyvals.find(ptypes.ptypes[count].first) != keyvals.end() &&
(ptypes.ptypes[count].second.empty() || keyvals[ptypes.ptypes[count].first] == ptypes.ptypes[count].second))
{
return true;
}
}
return false;
}

View file

@ -1,136 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 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
*
*****************************************************************************/
#ifndef OSM_H
#define OSM_H
#include <mapnik/value_types.hpp>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <utility>
struct bounds
{
double w, s, e, n;
bounds() { w = -180; s = -90; e = 180; n = 90; }
bounds(double w_, double s_, double e_, double n_)
{
this->w = w_;
this->s = s_;
this->e = e_;
this->n = n_;
}
};
class polygon_types
{
public:
std::vector<std::pair<std::string, std::string> > ptypes;
polygon_types()
{
ptypes.push_back(std::pair<std::string, std::string>("water", ""));
ptypes.push_back(std::pair<std::string, std::string>("aeroway", ""));
ptypes.push_back(std::pair<std::string, std::string>("building", ""));
ptypes.push_back(std::pair<std::string, std::string>("natural", "wood"));
ptypes.push_back(std::pair<std::string, std::string>("natural", "water"));
ptypes.push_back(std::pair<std::string, std::string>("natural", "heath"));
ptypes.push_back(std::pair<std::string, std::string>("natural", "marsh"));
ptypes.push_back(std::pair<std::string, std::string>("military", "danger_area"));
ptypes.push_back(std::pair<std::string, std::string>("landuse", "forest"));
ptypes.push_back(std::pair<std::string, std::string>("landuse", "industrial"));
ptypes.push_back(std::pair<std::string, std::string>("leisure", "park"));
ptypes.push_back(std::pair<std::string, std::string>("area", "yes"));
}
};
struct osm_item
{
mapnik::value_integer id;
std::map<std::string, std::string> keyvals;
virtual std::string to_string();
virtual ~osm_item() {}
};
struct osm_node : public osm_item
{
double lat, lon;
std::string to_string();
};
struct osm_way : public osm_item
{
std::vector<osm_node*> nodes;
std::string to_string();
bounds get_bounds();
bool is_polygon();
static polygon_types ptypes;
};
class osm_dataset
{
public:
osm_dataset()
{
node_i = nodes.begin();
way_i = ways.begin();
next_item_mode = Node;
}
osm_dataset(const char* name)
{
node_i = nodes.begin();
way_i = ways.begin();
next_item_mode = Node;
load(name);
}
~osm_dataset();
bool load(const char* name, std::string const& parser = "libxml2");
void clear();
void add_node(osm_node* n) { nodes.push_back(n); }
void add_way(osm_way* w) { ways.push_back(w); }
std::string to_string();
bounds get_bounds();
std::set<std::string> get_keys();
void rewind_nodes() { node_i = nodes.begin(); }
void rewind_ways() { way_i = ways.begin(); }
void rewind() { rewind_nodes(); rewind_ways(); next_item_mode = Node; }
osm_node * next_node();
osm_way * next_way();
osm_item * next_item();
bool current_item_is_node() { return next_item_mode == Node; }
bool current_item_is_way() { return next_item_mode == Way; }
private:
int next_item_mode;
enum { Node, Way };
std::vector<osm_node*>::iterator node_i;
std::vector<osm_way*>::iterator way_i;
std::vector<osm_node*> nodes;
std::vector<osm_way*> ways;
};
#endif // OSM_H

View file

@ -1,159 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
// stl
#include <stdexcept>
#include <set>
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/geom_util.hpp>
#include <mapnik/query.hpp>
#include <mapnik/boolean.hpp>
// boost
#include "osm_datasource.hpp"
#include "osm_featureset.hpp"
#include "dataset_deliverer.h"
#include "osmtagtypes.h"
#include "osmparser.h"
using mapnik::String;
using mapnik::Double;
using mapnik::Integer;
using mapnik::datasource_exception;
using mapnik::filter_in_box;
using mapnik::filter_at_point;
using mapnik::attribute_descriptor;
DATASOURCE_PLUGIN(osm_datasource)
osm_datasource::osm_datasource(const parameters& params)
: datasource (params),
extent_(),
type_(datasource::Vector),
desc_(osm_datasource::name(), *params.get<std::string>("encoding", "utf-8"))
{
osm_data_ = nullptr;
std::string osm_filename = *params.get<std::string>("file", "");
std::string parser = *params.get<std::string>("parser", "libxml2");
std::string url = *params.get<std::string>("url", "");
std::string bbox = *params.get<std::string>("bbox", "");
// load the data
if (url != "" && bbox != "")
{
throw datasource_exception("Error loading from URL is no longer supported (removed in >= Mapnik 2.3.x");
}
else if (osm_filename != "")
{
// if we supplied a filename, load from file
if ((osm_data_ = dataset_deliverer::load_from_file(osm_filename, parser)) == nullptr)
{
std::string s("OSM Plugin: Error loading from file '");
s += osm_filename + "'";
throw datasource_exception(s);
}
}
else
{
throw datasource_exception("OSM Plugin: Neither 'file' nor 'url' and 'bbox' specified");
}
osm_tag_types tagtypes;
tagtypes.add_type("maxspeed", mapnik::Integer);
tagtypes.add_type("z_order", mapnik::Integer);
osm_data_->rewind();
// Need code to get the attributes of all the data
std::set<std::string> keys = osm_data_->get_keys();
// Add the attributes to the datasource descriptor - assume they are
// all of type String
for (auto const& key : keys)
{
desc_.add_descriptor(attribute_descriptor(key, tagtypes.get_type(key)));
}
// Get the bounds of the data and set extent_ accordingly
bounds b = osm_data_->get_bounds();
extent_ = box2d<double>(b.w,b.s,b.e,b.n);
}
osm_datasource::~osm_datasource()
{
// Do not do as is now static variable and cleaned up at exit
//delete osm_data_;
}
const char * osm_datasource::name()
{
return "osm";
}
mapnik::datasource::datasource_t osm_datasource::type() const
{
return type_;
}
layer_descriptor osm_datasource::get_descriptor() const
{
return desc_;
}
featureset_ptr osm_datasource::features(const query& q) const
{
filter_in_box filter(q.get_bbox());
// so we need to filter osm features by bbox here...
return std::make_shared<osm_featureset<filter_in_box> >(filter,
osm_data_,
q.property_names(),
desc_.get_encoding());
}
featureset_ptr osm_datasource::features_at_point(coord2d const& pt, double tol) const
{
filter_at_point filter(pt);
// collect all attribute names
std::set<std::string> names;
for (auto const& elem : desc_.get_descriptors())
{
names.insert(elem.get_name());
}
return std::make_shared<osm_featureset<filter_at_point> >(filter,
osm_data_,
names,
desc_.get_encoding());
}
box2d<double> osm_datasource::envelope() const
{
return extent_;
}
boost::optional<mapnik::datasource_geometry_t> osm_datasource::get_geometry_type() const
{
return boost::optional<mapnik::datasource_geometry_t>(mapnik::datasource_geometry_t::Collection);
}

View file

@ -1,73 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#ifndef OSM_DATASOURCE_HPP
#define OSM_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 <vector>
#include <string>
#include "osm.h"
using mapnik::datasource;
using mapnik::parameters;
using mapnik::query;
using mapnik::featureset_ptr;
using mapnik::layer_descriptor;
using mapnik::coord2d;
using mapnik::box2d;
class osm_datasource : public datasource
{
public:
osm_datasource(const parameters& params);
virtual ~osm_datasource();
mapnik::datasource::datasource_t type() const;
static const char * name();
featureset_ptr features(const query& q) const;
featureset_ptr features_at_point(coord2d const& pt, double tol = 0) const;
box2d<double> envelope() const;
boost::optional<mapnik::datasource_geometry_t> get_geometry_type() const;
layer_descriptor get_descriptor() const;
private:
box2d<double> extent_;
osm_dataset* osm_data_;
mapnik::datasource::datasource_t type_;
layer_descriptor desc_;
};
#endif // OSM_DATASOURCE_HPP

View file

@ -1,132 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
// mapnik
#include <mapnik/make_unique.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_factory.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/geometry_correct.hpp>
#include "osm_featureset.hpp"
using mapnik::feature_ptr;
using mapnik::feature_factory;
template <typename filterT>
osm_featureset<filterT>::osm_featureset(const filterT& filter,
osm_dataset* dataset,
const std::set<std::string>&
attribute_names,
std::string const& encoding)
: filter_(filter),
query_ext_(),
tr_(new transcoder(encoding)),
dataset_ (dataset),
attribute_names_ (attribute_names),
ctx_(std::make_shared<mapnik::context_type>())
{
dataset_->rewind();
}
template <typename filterT>
feature_ptr osm_featureset<filterT>::next()
{
feature_ptr feature;
osm_item* cur_item = dataset_->next_item();
if (!cur_item) return feature_ptr();
if (dataset_->current_item_is_node())
{
feature = feature_factory::create(ctx_, cur_item->id);
double lat = static_cast<osm_node*>(cur_item)->lat;
double lon = static_cast<osm_node*>(cur_item)->lon;
feature->set_geometry(mapnik::geometry::point<double>(lon,lat));
}
else if (dataset_->current_item_is_way())
{
// Loop until we find a feature which passes the filter
while (cur_item)
{
bounds b = static_cast<osm_way*>(cur_item)->get_bounds();
if (filter_.pass(box2d<double>(b.w, b.s, b.e, b.n))
&&
static_cast<osm_way*>(cur_item)->nodes.size()) break;
cur_item = dataset_->next_item();
}
if (!cur_item) return feature_ptr();
feature = feature_factory::create(ctx_, cur_item->id);
if (static_cast<osm_way*>(cur_item)->is_polygon())
{
mapnik::geometry::linear_ring<double> ring;
for (unsigned int count = 0;
count < static_cast<osm_way*>(cur_item)->nodes.size();
count++)
{
ring.add_coord(static_cast<osm_way*>(cur_item)->nodes[count]->lon,
static_cast<osm_way*>(cur_item)->nodes[count]->lat);
}
mapnik::geometry::polygon<double> geom;
geom.set_exterior_ring(std::move(ring));
mapnik::geometry::correct(geom);
feature->set_geometry(std::move(geom));
}
else
{
mapnik::geometry::line_string<double> geom;
for (unsigned int count = 0;
count < static_cast<osm_way*>(cur_item)->nodes.size();
count++)
{
geom.add_coord(static_cast<osm_way*>(cur_item)->nodes[count]->lon,
static_cast<osm_way*>(cur_item)->nodes[count]->lat);
}
feature->set_geometry(std::move(geom));
}
}
else
{
MAPNIK_LOG_ERROR(osm_featureset) << "Current item is neither node nor way.\n";
}
std::set<std::string>::const_iterator itr = attribute_names_.begin();
std::set<std::string>::const_iterator end = attribute_names_.end();
std::map<std::string,std::string>::iterator end_keyvals = cur_item->keyvals.end();
for (; itr != end; itr++)
{
std::map<std::string,std::string>::iterator i = cur_item->keyvals.find(*itr);
if (i != end_keyvals)
{
feature->put_new(i->first, tr_->transcode(i->second.c_str()));
}
}
return feature;
}
template <typename filterT>
osm_featureset<filterT>::~osm_featureset() {}
template class osm_featureset<mapnik::filter_in_box>;
template class osm_featureset<mapnik::filter_at_point>;

View file

@ -1,72 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#ifndef OSM_FS_HH
#define OSM_FS_HH
// stl
#include <set>
// boost
// mapnik
#include <mapnik/geom_util.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/query.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/datasource.hpp>
#include "osm.h"
using mapnik::Featureset;
using mapnik::box2d;
using mapnik::feature_ptr;
using mapnik::transcoder;
template <typename filterT>
class osm_featureset : public Featureset
{
public:
osm_featureset(const filterT& filter,
osm_dataset* dataset,
const std::set<std::string>& attribute_names,
std::string const& encoding);
virtual ~osm_featureset();
feature_ptr next();
private:
filterT filter_;
box2d<double> query_ext_;
const std::unique_ptr<transcoder> tr_;
std::vector<int> attr_ids_;
mutable box2d<double> feature_ext_;
mutable int total_geom_size;
osm_dataset *dataset_;
std::set<std::string> attribute_names_;
mapnik::context_ptr ctx_;
osm_featureset(const osm_featureset&);
const osm_featureset& operator=(const osm_featureset&);
};
#endif // OSM_FS_HH

View file

@ -1,150 +0,0 @@
// much of this is based on osm2pgsql
#include "osmparser.h"
#include "osm.h"
#include <string>
#include <cassert>
#include <mapnik/util/conversions.hpp>
osm_item* osmparser::cur_item=nullptr;
mapnik::value_integer osmparser::curID=0;
bool osmparser::in_node=false, osmparser::in_way=false;
osm_dataset* osmparser::components=nullptr;
std::string osmparser::error="";
std::map<mapnik::value_integer,osm_node*> osmparser::tmp_node_store=std::map<mapnik::value_integer,osm_node*>();
void osmparser::processNode(xmlTextReaderPtr reader)
{
xmlChar *name = xmlTextReaderName(reader);
if(name==nullptr)
name=xmlStrdup(BAD_CAST "--");
switch(xmlTextReaderNodeType(reader))
{
case XML_READER_TYPE_ELEMENT:
startElement(reader,name);
break;
case XML_READER_TYPE_END_ELEMENT:
endElement(name);
}
xmlFree(name);
}
void osmparser::startElement(xmlTextReaderPtr reader, const xmlChar *name)
{
std::string tags;
xmlChar *xid, *xlat, *xlon, *xk, *xv;
if(xmlStrEqual(name,BAD_CAST "node"))
{
curID = 0;
in_node = true;
osm_node *node=new osm_node;
xlat=xmlTextReaderGetAttribute(reader,BAD_CAST "lat");
xlon=xmlTextReaderGetAttribute(reader,BAD_CAST "lon");
xid=xmlTextReaderGetAttribute(reader,BAD_CAST "id");
assert(xlat);
assert(xlon);
assert(xid);
node->lat=atof((char*)xlat);
node->lon=atof((char*)xlon);
mapnik::util::string2int((char *)xid, node->id);
cur_item = node;
tmp_node_store[node->id] = node;
xmlFree(xid);
xmlFree(xlon);
xmlFree(xlat);
}
else if (xmlStrEqual(name,BAD_CAST "way"))
{
curID=0;
in_way = true;
osm_way *way=new osm_way;
xid=xmlTextReaderGetAttribute(reader,BAD_CAST "id");
assert(xid);
mapnik::util::string2int((char *)xid, way->id);
cur_item = way;
xmlFree(xid);
}
else if (xmlStrEqual(name,BAD_CAST "nd"))
{
xid=xmlTextReaderGetAttribute(reader,BAD_CAST "ref");
assert(xid);
mapnik::value_integer ndid;
mapnik::util::string2int((char *)xid, ndid);
if(tmp_node_store.find(ndid)!=tmp_node_store.end())
{
(static_cast<osm_way*>(cur_item))->nodes.push_back
(tmp_node_store[ndid]);
}
xmlFree(xid);
}
else if (xmlStrEqual(name,BAD_CAST "tag"))
{
std::string key="", value="";
xk = xmlTextReaderGetAttribute(reader,BAD_CAST "k");
xv = xmlTextReaderGetAttribute(reader,BAD_CAST "v");
assert(xk);
assert(xv);
cur_item->keyvals[(char*)xk] = (char*)xv;
xmlFree(xk);
xmlFree(xv);
}
if (xmlTextReaderIsEmptyElement(reader))
{
// Fake endElement for empty nodes
endElement(name);
}
}
void osmparser::endElement(const xmlChar* name)
{
if(xmlStrEqual(name,BAD_CAST "node"))
{
in_node = false;
components->add_node(static_cast<osm_node*>(cur_item));
}
else if(xmlStrEqual(name,BAD_CAST "way"))
{
in_way = false;
components->add_way(static_cast<osm_way*>(cur_item));
}
}
bool osmparser::parse(osm_dataset *ds, const char* filename)
{
components=ds;
xmlTextReaderPtr reader = xmlNewTextReaderFilename(filename);
int ret=do_parse(reader);
xmlFreeTextReader(reader);
return (ret==0) ? true:false;
}
bool osmparser::parse(osm_dataset *ds,char* data, int nbytes)
{
// from cocoasamurai.blogspot.com/2008/10/getting-some-xml-love-with-
// libxml2.html, converted from Objective-C to straight C
components=ds;
xmlTextReaderPtr reader = xmlReaderForMemory(data,nbytes,nullptr,nullptr,0);
int ret=do_parse(reader);
xmlFreeTextReader(reader);
return (ret==0) ? true:false;
}
int osmparser::do_parse(xmlTextReaderPtr reader)
{
int ret=-1;
if(reader!=nullptr)
{
ret = xmlTextReaderRead(reader);
while(ret==1)
{
processNode(reader);
ret=xmlTextReaderRead(reader);
}
}
return ret;
}

View file

@ -1,54 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 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
*
*****************************************************************************/
#ifndef OSMPARSER_H
#define OSMPARSER_H
#include <mapnik/value_types.hpp>
#include <libxml/xmlreader.h>
#include <cstdio>
#include <cstdlib>
#include <string>
#include "osm.h"
#include <map>
class osmparser
{
public:
static void processNode(xmlTextReaderPtr reader);
static void startElement(xmlTextReaderPtr reader, const xmlChar* name);
static void endElement(const xmlChar* name);
static bool parse(osm_dataset* ds, const char* filename);
static bool parse(osm_dataset* ds, char* data, int nbytes);
private:
static osm_item *cur_item;
static mapnik::value_integer curID;
static bool in_node, in_way;
static osm_dataset* components;
static std::string error;
static std::map<mapnik::value_integer, osm_node*> tmp_node_store;
static int do_parse(xmlTextReaderPtr);
};
#endif // OSMPARSER_H

View file

@ -1,50 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 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
*
*****************************************************************************/
#ifndef OSMTAGTYPES_H
#define OSMTAGTYPES_H
// osmtagtypes.h
// for finding the types of particular tags
// mapnik
#include <mapnik/feature_layer_desc.hpp>
class osm_tag_types
{
public:
void add_type(std::string tag, mapnik::eAttributeType type)
{
types[tag] = type;
}
mapnik::eAttributeType get_type(std::string tag)
{
std::map<std::string, mapnik::eAttributeType>::iterator i = types.find(tag);
return (i == types.end()) ? mapnik::String : i->second;
}
private:
std::map<std::string, mapnik::eAttributeType> types;
};
#endif // OSMTAGTYPES_H

View file

@ -271,18 +271,30 @@ mapnik::raster_ptr read_grayscale_band(mapnik::box2d<double> const& bbox,
int val;
int nodataval;
uint8_t * data = image.bytes();
int ps = 4; // sizeof(image::pixel_type)
int off;
val = reader(); // nodata value, need to read anyway
nodataval = reader(); // nodata value, need to read anyway
for (int y=0; y<height; ++y) {
for (int x=0; x<width; ++x) {
val = reader();
// Apply harsh type clipping rules ala GDAL
if ( val < 0 ) val = 0;
if ( val > 255 ) val = 255;
// Calculate pixel offset
off = y * width * ps + x * ps;
// Pixel space is RGBA
// Pixel space is RGBA, fill all w/ same value for Grey
data[off+0] = val;
data[off+1] = val;
data[off+2] = val;
// Set the alpha channel for transparent nodata values
// Nodata handling is *manual* at the driver level
if ( hasnodata && val == nodataval ) {
data[off+3] = 0x00; // transparent
} else {
data[off+3] = 0xFF; // opaque
}
}
}
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(bbox, image, 1.0);

View file

@ -1,71 +0,0 @@
#
# This file is part of Mapnik (c++ mapping toolkit)
#
# Copyright (C) 2015 Artem Pavlenko
#
# 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
#
#
Import ('plugin_base')
Import ('env')
PLUGIN_NAME = 'rasterlite'
plugin_env = plugin_base.Clone()
plugin_sources = Split(
"""
%(PLUGIN_NAME)s_datasource.cpp
%(PLUGIN_NAME)s_featureset.cpp
""" % locals()
)
# Link Library to Dependencies
libraries = [env['PLUGINS']['rasterlite']['lib']]
libraries.append(env['ICU_LIB_NAME'])
libraries.append('boost_system%s' % env['BOOST_APPEND'])
if env['RUNTIME_LINK'] == 'static':
libraries.append('geotiff')
libraries.append('spatialite')
libraries.append('sqlite3')
libraries.append('geos_c')
libraries.append('geos')
libraries.append('proj')
libraries.append('z')
if env['PLUGIN_LINKING'] == 'shared':
libraries.append(env['MAPNIK_NAME'])
TARGET = plugin_env.SharedLibrary('../%s' % PLUGIN_NAME,
SHLIBPREFIX='',
SHLIBSUFFIX='.input',
source=plugin_sources,
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' not in COMMAND_LINE_TARGETS:
env.Install(env['MAPNIK_INPUT_PLUGINS_DEST'], TARGET)
env.Alias('install', env['MAPNIK_INPUT_PLUGINS_DEST'])
plugin_obj = {
'LIBS': libraries,
'SOURCES': plugin_sources,
}
Return('plugin_obj')

View file

@ -1,191 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#include "rasterlite_datasource.hpp"
#include "rasterlite_featureset.hpp"
// boost
// mapnik
#include <mapnik/util/fs.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/boolean.hpp>
#include <mapnik/geom_util.hpp>
using mapnik::datasource;
using mapnik::parameters;
DATASOURCE_PLUGIN(rasterlite_datasource)
using mapnik::box2d;
using mapnik::coord2d;
using mapnik::query;
using mapnik::featureset_ptr;
using mapnik::layer_descriptor;
using mapnik::datasource_exception;
/*
* Opens a GDALDataset and returns a pointer to it.
* Caller is responsible for calling GDALClose on it
*/
inline void* rasterlite_datasource::open_dataset() const
{
void* dataset = rasterliteOpen (dataset_name_.c_str(), table_name_.c_str());
if (! dataset)
{
throw datasource_exception("Rasterlite Plugin: Error opening dataset");
}
if (rasterliteIsError (dataset))
{
std::string error (rasterliteGetLastError(dataset));
rasterliteClose (dataset);
throw datasource_exception(error);
}
return dataset;
}
rasterlite_datasource::rasterlite_datasource(parameters const& params)
: datasource(params),
desc_(rasterlite_datasource::name(),"utf-8")
{
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Initializing...";
boost::optional<std::string> file = params.get<std::string>("file");
if (!file) throw datasource_exception("missing <file> parameter");
boost::optional<std::string> table = params.get<std::string>("table");
if (!table) throw datasource_exception("missing <table> parameter");
table_name_ = *table;
boost::optional<std::string> base = params.get<std::string>("base");
if (base)
dataset_name_ = *base + "/" + *file;
else
dataset_name_ = *file;
if (!mapnik::util::exists(dataset_name_)) throw datasource_exception(dataset_name_ + " does not exist");
void *dataset = open_dataset();
double x0, y0, x1, y1;
if (rasterliteGetExtent (dataset, &x0, &y0, &x1, &y1) != RASTERLITE_OK)
{
std::string error (rasterliteGetLastError(dataset));
rasterliteClose (dataset);
throw datasource_exception(error);
}
extent_.init(x0,y0,x1,y1);
#ifdef MAPNIK_LOG
int srid, auth_srid;
const char *auth_name;
const char *ref_sys_name;
const char *proj4text;
int tile_count;
double pixel_x_size, pixel_y_size;
int levels = rasterliteGetLevels (dataset);
if (rasterliteGetSrid(dataset, &srid, &auth_name, &auth_srid, &ref_sys_name, &proj4text) != RASTERLITE_OK)
{
std::string error (rasterliteGetLastError(dataset));
rasterliteClose (dataset);
throw datasource_exception(error);
}
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Data Source=" << rasterliteGetTablePrefix(dataset);
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: SRID=" << srid;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Authority=" << auth_name;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: AuthSRID=" << auth_srid;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: RefSys Name=" << ref_sys_name;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Proj4Text=" << proj4text;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Extent=" << x0 << "," << y0 << " " << x1 << "," << y1 << ")";
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Levels=" << levels;
for (int i = 0; i < levels; i++)
{
if (rasterliteGetResolution(dataset, i, &pixel_x_size, &pixel_y_size, &tile_count) == RASTERLITE_OK)
{
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Level=" << i
<< " x=" << pixel_x_size
<< " y=" << pixel_y_size
<< " tiles=" << tile_count;
}
}
#endif
rasterliteClose(dataset);
}
rasterlite_datasource::~rasterlite_datasource()
{
}
const char * rasterlite_datasource::name()
{
return "rasterlite";
}
mapnik::datasource::datasource_t rasterlite_datasource::type() const
{
return datasource::Raster;
}
box2d<double> rasterlite_datasource::envelope() const
{
return extent_;
}
boost::optional<mapnik::datasource_geometry_t> rasterlite_datasource::get_geometry_type() const
{
return boost::optional<mapnik::datasource_geometry_t>();
}
layer_descriptor rasterlite_datasource::get_descriptor() const
{
return desc_;
}
featureset_ptr rasterlite_datasource::features(query const& q) const
{
rasterlite_query gq = q;
return std::make_shared<rasterlite_featureset>(open_dataset(), gq);
}
featureset_ptr rasterlite_datasource::features_at_point(coord2d const& pt, double tol) const
{
rasterlite_query gq = pt;
return std::make_shared<rasterlite_featureset>(open_dataset(), gq);
}

View file

@ -1,66 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#ifndef RASTERLITE_DATASOURCE_HPP
#define RASTERLITE_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 <vector>
#include <string>
#include "rasterlite_include.hpp"
class rasterlite_datasource : public mapnik::datasource
{
public:
rasterlite_datasource(mapnik::parameters const& params);
virtual ~rasterlite_datasource ();
mapnik::datasource::datasource_t type() const;
static const char * name();
mapnik::featureset_ptr features(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const;
mapnik::box2d<double> envelope() const;
boost::optional<mapnik::datasource_geometry_t> get_geometry_type() const;
mapnik::layer_descriptor get_descriptor() const;
private:
void* open_dataset() const;
mapnik::box2d<double> extent_;
std::string dataset_name_;
std::string table_name_;
mapnik::layer_descriptor desc_;
};
#endif // RASTERLITE_DATASOURCE_HPP

View file

@ -1,136 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#include "rasterlite_featureset.hpp"
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/image.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/query.hpp>
#include <mapnik/raster.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_factory.hpp>
#include <cstring>
using mapnik::coord2d;
using mapnik::box2d;
using mapnik::feature_ptr;
using mapnik::query;
using mapnik::feature_factory;
rasterlite_featureset::rasterlite_featureset(void* dataset,
rasterlite_query q)
: dataset_(dataset),
gquery_(q),
first_(true),
ctx_(std::make_shared<mapnik::context_type>())
{
rasterliteSetBackgroundColor(dataset_, 255, 0, 255);
rasterliteSetTransparentColor(dataset_, 255, 0, 255);
}
rasterlite_featureset::~rasterlite_featureset()
{
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Closing";
rasterliteClose(dataset_);
}
feature_ptr rasterlite_featureset::next()
{
if (first_)
{
first_ = false;
MAPNIK_LOG_DEBUG(gdal) << "rasterlite_featureset: Next feature in Dataset=" << &dataset_;
return mapnik::util::apply_visitor(query_dispatch(*this), gquery_);
}
return feature_ptr();
}
feature_ptr rasterlite_featureset::get_feature(mapnik::query const& q)
{
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Running get_feature";
feature_ptr feature(feature_factory::create(ctx_,1));
double x0, y0, x1, y1;
rasterliteGetExtent (dataset_, &x0, &y0, &x1, &y1);
box2d<double> raster_extent(x0, y0, x1, y1);
box2d<double> intersect = raster_extent.intersect(q.get_bbox());
const int width = static_cast<int>(std::get<0>(q.resolution()) * intersect.width() + 0.5);
const int height = static_cast<int>(std::get<0>(q.resolution()) * intersect.height() + 0.5);
const double pixel_size = (intersect.width() >= intersect.height()) ?
(intersect.width() / (double) width) : (intersect.height() / (double) height);
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Raster extent=" << raster_extent;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: View extent=" << q.get_bbox();
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Intersect extent=" << intersect;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Query resolution=" << std::get<0>(q.resolution()) << "," << std::get<1>(q.resolution());
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Size=" << width << " " << height;
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Pixel Size=" << pixel_size;
if (width > 0 && height > 0)
{
int size = 0;
void* raster = 0;
if (rasterliteGetRawImageByRect(dataset_,
intersect.minx(),
intersect.miny(),
intersect.maxx(),
intersect.maxy(),
pixel_size,
width,
height,
GAIA_RGBA_ARRAY,
&raster,
&size) == RASTERLITE_OK)
{
if (size > 0)
{
mapnik::image_rgba8 image(width,height);
unsigned char* raster_data = static_cast<unsigned char*>(raster);
std::memcpy(image.bytes(), raster_data, size);
feature->set_raster(std::make_shared<mapnik::raster>(intersect, std::move(image), 1.0));
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Done";
}
else
{
MAPNIK_LOG_ERROR(rasterlite) << "Rasterlite Plugin: Error " << rasterliteGetLastError (dataset_);
}
}
return feature;
}
return feature_ptr();
}
feature_ptr rasterlite_featureset::get_feature_at_point(mapnik::coord2d const& pt)
{
return feature_ptr();
}

View file

@ -1,71 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#ifndef RASTERLITE_FEATURESET_HPP
#define RASTERLITE_FEATURESET_HPP
// mapnik
#include <mapnik/feature.hpp>
#include <mapnik/query.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/util/variant.hpp>
#include "rasterlite_include.hpp"
using rasterlite_query = mapnik::util::variant<mapnik::query,mapnik::coord2d>;
class rasterlite_featureset : public mapnik::Featureset
{
struct query_dispatch
{
query_dispatch( rasterlite_featureset & featureset)
: featureset_(featureset) {}
mapnik::feature_ptr operator() (mapnik::query const& q) const
{
return featureset_.get_feature(q);
}
mapnik::feature_ptr operator() (mapnik::coord2d const& p) const
{
return featureset_.get_feature_at_point(p);
}
rasterlite_featureset & featureset_;
};
public:
rasterlite_featureset(void* dataset,
rasterlite_query q);
virtual ~rasterlite_featureset();
mapnik::feature_ptr next();
private:
mapnik::feature_ptr get_feature(mapnik::query const& q);
mapnik::feature_ptr get_feature_at_point(mapnik::coord2d const& p);
void* dataset_;
rasterlite_query gquery_;
bool first_;
mapnik::context_ptr ctx_;
};
#endif // RASTERLITE_FEATURESET_HPP

View file

@ -1,31 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#ifndef RASTERLITE_INCLUDE_HPP
#define RASTERLITE_INCLUDE_HPP
extern "C" {
#include <sqlite3.h>
#include <rasterlite.h>
}
#endif // RASTERLITE_INCLUDE_HPP

View file

@ -32,6 +32,7 @@
#include <mapnik/geom_util.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/pixel_position.hpp>
#include <mapnik/text/glyph_positions.hpp>
#include <mapnik/renderer_common/process_group_symbolizer.hpp>
#include <mapnik/renderer_common/clipping_extent.hpp>
#include <mapnik/svg/svg_renderer_agg.hpp>
@ -120,7 +121,7 @@ struct thunk_renderer<image_rgba8>
render_offset_placements(
thunk.placements_,
offset_,
[&] (glyph_positions_ptr glyphs)
[&] (glyph_positions_ptr const& glyphs)
{
marker_info_ptr mark = glyphs->get_marker();
if (mark)

View file

@ -50,7 +50,6 @@
#include "agg_span_allocator.h"
#include "agg_span_pattern_rgba.h"
#include "agg_renderer_outline_image.h"
#include "agg_conv_clip_polyline.h"
namespace mapnik {

View file

@ -31,6 +31,7 @@
#include <mapnik/vertex_processor.hpp>
#include <mapnik/renderer_common/clipping_extent.hpp>
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
#include <mapnik/geometry_type.hpp>
// agg
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
@ -164,12 +165,19 @@ void agg_renderer<T0,T1>::process(line_symbolizer const& sym,
rasterizer_type ras(ren);
set_join_caps_aa(sym, ras, feature, common_.vars_);
using vertex_converter_type = vertex_converter<clip_line_tag, transform_tag,
using vertex_converter_type = vertex_converter<clip_line_tag, clip_poly_tag, transform_tag,
affine_transform_tag,
simplify_tag, smooth_tag,
offset_transform_tag>;
vertex_converter_type converter(clip_box,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
if (clip)
{
geometry::geometry_types type = geometry::geometry_type(feature.get_geometry());
if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
converter.template set<clip_poly_tag>();
else if (type == geometry::geometry_types::LineString || type == geometry::geometry_types::MultiLineString)
converter.template set<clip_line_tag>();
}
converter.set<transform_tag>(); // always transform
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
converter.set<affine_transform_tag>(); // optional affine transform
@ -183,14 +191,20 @@ void agg_renderer<T0,T1>::process(line_symbolizer const& sym,
}
else
{
using vertex_converter_type = vertex_converter<clip_line_tag, transform_tag,
using vertex_converter_type = vertex_converter<clip_line_tag, clip_poly_tag, transform_tag,
affine_transform_tag,
simplify_tag, smooth_tag,
offset_transform_tag,
dash_tag, stroke_tag>;
vertex_converter_type converter(clip_box, sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
if (clip)
{
geometry::geometry_types type = geometry::geometry_type(feature.get_geometry());
if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
converter.template set<clip_poly_tag>();
else if (type == geometry::geometry_types::LineString || type == geometry::geometry_types::MultiLineString)
converter.template set<clip_line_tag>();
}
converter.set<transform_tag>(); // always transform
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
converter.set<affine_transform_tag>(); // optional affine transform

View file

@ -50,7 +50,6 @@
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_path_storage.h"
#include "agg_conv_clip_polyline.h"
#include "agg_conv_transform.h"

View file

@ -27,6 +27,7 @@
#include <mapnik/text/symbolizer_helpers.hpp>
#include <mapnik/pixel_position.hpp>
#include <mapnik/text/renderer.hpp>
#include <mapnik/text/glyph_positions.hpp>
#include <mapnik/renderer_common/clipping_extent.hpp>
namespace mapnik {
@ -60,7 +61,7 @@ void agg_renderer<T0,T1>::process(shield_symbolizer const& sym,
double opacity = get<double>(sym,keys::opacity, feature, common_.vars_, 1.0);
placements_list const& placements = helper.get();
for (glyph_positions_ptr glyphs : placements)
for (auto const& glyphs : placements)
{
marker_info_ptr mark = glyphs->get_marker();
if (mark)

View file

@ -27,6 +27,7 @@
#include <mapnik/agg_rasterizer.hpp>
#include <mapnik/text/symbolizer_helpers.hpp>
#include <mapnik/text/renderer.hpp>
#include <mapnik/text/glyph_positions.hpp>
#include <mapnik/renderer_common/clipping_extent.hpp>
namespace mapnik {
@ -67,7 +68,7 @@ void agg_renderer<T0,T1>::process(text_symbolizer const& sym,
}
placements_list const& placements = helper.get();
for (glyph_positions_ptr glyphs : placements)
for (auto const& glyphs : placements)
{
ren.render(*glyphs);
}

View file

@ -84,7 +84,8 @@ if '-DHAVE_WEBP' in env['CPPDEFINES']:
lib_env['LIBS'].append('webp')
enabled_imaging_libraries.append('webp_reader.cpp')
lib_env['LIBS'].append('xml2')
if env['XMLPARSER'] == 'libxml2' and env['HAS_LIBXML2']:
lib_env['LIBS'].append('xml2')
if '-DBOOST_REGEX_HAS_ICU' in env['CPPDEFINES']:
lib_env['LIBS'].append('icui18n')

View file

@ -28,8 +28,8 @@
#include <mapnik/text/face.hpp>
#include <cairo-ft.h>
#include <vector>
#include <valarray>
namespace mapnik {
cairo_face::cairo_face(std::shared_ptr<font_library> const& library, face_ptr const& face)
@ -227,17 +227,13 @@ void cairo_context::set_line_width(double width)
void cairo_context::set_dash(dash_array const& dashes, double scale_factor)
{
std::valarray<double> d(dashes.size() * 2);
dash_array::const_iterator itr = dashes.begin();
dash_array::const_iterator end = dashes.end();
std::size_t index = 0;
for (; itr != end; ++itr)
std::vector<double> d;
d.reserve(dashes.size() * 2);
for (auto const& dash : dashes)
{
d[index++] = itr->first * scale_factor;
d[index++] = itr->second * scale_factor;
d.emplace_back(dash.first * scale_factor);
d.emplace_back(dash.second * scale_factor);
}
cairo_set_dash(cairo_.get() , &d[0], static_cast<int>(d.size()), 0/*offset*/);
check_object_status_and_throw_exception(*this);
}

View file

@ -26,6 +26,7 @@
#include <mapnik/marker.hpp>
#include <mapnik/svg/svg_path_adapter.hpp>
#include <mapnik/make_unique.hpp>
#include <mapnik/text/glyph_positions.hpp>
#include <mapnik/cairo/cairo_renderer.hpp>
#include <mapnik/cairo/cairo_render_vector.hpp>
@ -95,7 +96,7 @@ struct thunk_renderer
render_offset_placements(
thunk.placements_,
offset_,
[&] (glyph_positions_ptr glyphs)
[&] (glyph_positions_ptr const& glyphs)
{
marker_info_ptr mark = glyphs->get_marker();
if (mark)

View file

@ -29,6 +29,7 @@
#include <mapnik/vertex_converters.hpp>
#include <mapnik/vertex_processor.hpp>
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
#include <mapnik/geometry_type.hpp>
namespace mapnik
{
@ -82,6 +83,7 @@ void cairo_renderer<T>::process(line_symbolizer const& sym,
clipping_extent.pad(padding);
}
using vertex_converter_type = vertex_converter<clip_line_tag,
clip_poly_tag,
transform_tag,
affine_transform_tag,
simplify_tag, smooth_tag,
@ -89,7 +91,14 @@ void cairo_renderer<T>::process(line_symbolizer const& sym,
vertex_converter_type converter(clipping_extent,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
if (clip)
{
geometry::geometry_types type = geometry::geometry_type(feature.get_geometry());
if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
converter.template set<clip_poly_tag>();
else if (type == geometry::geometry_types::LineString || type == geometry::geometry_types::MultiLineString)
converter.template set<clip_line_tag>();
}
converter.set<transform_tag>(); // always transform
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
converter.set<affine_transform_tag>(); // optional affine transform

View file

@ -27,6 +27,7 @@
#include <mapnik/text/symbolizer_helpers.hpp>
#include <mapnik/pixel_position.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/text/glyph_positions.hpp>
namespace mapnik
{
@ -55,7 +56,7 @@ void cairo_renderer<T>::process(shield_symbolizer const& sym,
double opacity = get<double>(sym,keys::opacity,feature, common_.vars_, 1.0);
placements_list const &placements = helper.get();
for (glyph_positions_ptr glyphs : placements)
for (auto const& glyphs : placements)
{
marker_info_ptr mark = glyphs->get_marker();
if (mark) {
@ -93,7 +94,7 @@ void cairo_renderer<T>::process(text_symbolizer const& sym,
composite_mode_e halo_comp_op = get<composite_mode_e>(sym, keys::halo_comp_op, feature, common_.vars_, src_over);
placements_list const& placements = helper.get();
for (glyph_positions_ptr glyphs : placements)
for (auto const& glyphs : placements)
{
context_.add_text(*glyphs, face_manager_, comp_op, halo_comp_op, common_.scale_factor_);
}

View file

@ -45,7 +45,7 @@ color parse_color(std::string const& str)
}
else
{
throw config_error("Failed to a parse color: \"" + str + "\"");
throw config_error("Failed to parse color: \"" + str + "\"");
}
}

View file

@ -66,13 +66,36 @@ gradient::gradient(gradient const& other)
units_(other.units_),
gradient_type_(other.gradient_type_) {}
gradient & gradient::operator=(const gradient& rhs)
gradient::gradient(gradient && other)
: transform_(std::move(other.transform_)),
x1_(std::move(other.x1_)),
y1_(std::move(other.y1_)),
x2_(std::move(other.x2_)),
y2_(std::move(other.y2_)),
r_(std::move(other.r_)),
stops_(std::move(other.stops_)),
units_(std::move(other.units_)),
gradient_type_(std::move(other.gradient_type_)) {}
gradient & gradient::operator=(gradient rhs)
{
gradient tmp(rhs);
swap(tmp);
swap(rhs);
return *this;
}
bool gradient::operator==(gradient const& other) const
{
return transform_ == other.transform_ &&
x1_ == other.x1_ &&
y1_ == other.y1_ &&
x2_ == other.x2_ &&
y2_ == other.y2_ &&
r_ == other.r_ &&
std::equal(stops_.begin(),stops_.end(), other.stops_.begin()),
units_ == other.units_ &&
gradient_type_ == other.gradient_type_;
}
void gradient::set_gradient_type(gradient_e grad)
{
gradient_type_=grad;
@ -108,7 +131,7 @@ void gradient::add_stop(double offset,mapnik::color const& c)
bool gradient::has_stop() const
{
return ! stops_.empty();
return !stops_.empty();
}
stop_array const& gradient::get_stop_array() const
@ -116,13 +139,17 @@ stop_array const& gradient::get_stop_array() const
return stops_;
}
void gradient::swap(const gradient& other) throw()
void gradient::swap(gradient& other) throw()
{
gradient_type_=other.gradient_type_;
stops_=other.stops_;
units_=other.units_;
transform_=other.transform_;
other.get_control_points(x1_,y1_,x2_,y2_,r_);
std::swap(gradient_type_, other.gradient_type_);
std::swap(stops_, other.stops_);
std::swap(units_, other.units_);
std::swap(transform_, other.transform_);
std::swap(x1_, other.x1_);
std::swap(y1_, other.y1_);
std::swap(x2_, other.x2_);
std::swap(y2_, other.y2_);
std::swap(r_, other.r_);
}
void gradient::set_control_points(double x1, double y1, double x2, double y2, double r)

View file

@ -33,6 +33,7 @@
#include <mapnik/text/placement_finder.hpp>
#include <mapnik/text/symbolizer_helpers.hpp>
#include <mapnik/text/renderer.hpp>
#include <mapnik/text/glyph_positions.hpp>
#include <mapnik/svg/svg_renderer_agg.hpp>
#include <mapnik/svg/svg_storage.hpp>
#include <mapnik/svg/svg_path_adapter.hpp>
@ -129,7 +130,7 @@ struct thunk_renderer
render_offset_placements(
thunk.placements_,
offset_,
[&] (glyph_positions_ptr glyphs)
[&] (glyph_positions_ptr const& glyphs)
{
marker_info_ptr mark = glyphs->get_marker();
if (mark)

View file

@ -31,6 +31,7 @@
#include <mapnik/vertex_converters.hpp>
#include <mapnik/vertex_processor.hpp>
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
#include <mapnik/geometry_type.hpp>
// agg
#include "agg_rasterizer_scanline_aa.h"
#include "agg_renderer_scanline.h"
@ -89,14 +90,21 @@ void grid_renderer<T>::process(line_symbolizer const& sym,
padding *= common_.scale_factor_;
clipping_extent.pad(padding);
}
using vertex_converter_type = vertex_converter<clip_line_tag, transform_tag,
using vertex_converter_type = vertex_converter<clip_line_tag, clip_poly_tag, transform_tag,
affine_transform_tag,
simplify_tag, smooth_tag,
offset_transform_tag,
dash_tag, stroke_tag>;
vertex_converter_type converter(clipping_extent,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
if (clip)
{
geometry::geometry_types type = geometry::geometry_type(feature.get_geometry());
if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
converter.template set<clip_poly_tag>();
else if (type == geometry::geometry_types::LineString || type == geometry::geometry_types::MultiLineString)
converter.template set<clip_line_tag>();
}
converter.set<transform_tag>(); // always transform
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
converter.set<affine_transform_tag>(); // optional affine transform

View file

@ -31,6 +31,7 @@
#include <mapnik/text/symbolizer_helpers.hpp>
#include <mapnik/pixel_position.hpp>
#include <mapnik/text/renderer.hpp>
#include <mapnik/text/glyph_positions.hpp>
// agg
#include "agg_trans_affine.h"
@ -64,7 +65,7 @@ void grid_renderer<T>::process(shield_symbolizer const& sym,
placements_list const& placements = helper.get();
value_integer feature_id = feature.id();
for (glyph_positions_ptr glyphs : placements)
for (auto const& glyphs : placements)
{
marker_info_ptr mark = glyphs->get_marker();
if (mark)

View file

@ -28,6 +28,7 @@
#include <mapnik/text/symbolizer_helpers.hpp>
#include <mapnik/pixel_position.hpp>
#include <mapnik/text/renderer.hpp>
#include <mapnik/text/glyph_positions.hpp>
#include <mapnik/renderer_common/clipping_extent.hpp>
namespace mapnik {
@ -66,7 +67,7 @@ void grid_renderer<T>::process(text_symbolizer const& sym,
placements_list const& placements = helper.get();
value_integer feature_id = feature.id();
for (glyph_positions_ptr glyphs : placements)
for (auto const& glyphs : placements)
{
ren.render(*glyphs, feature_id);
placement_found = true;

View file

@ -34,9 +34,6 @@
#include <mapnik/vertex_cache.hpp>
#include <mapnik/tolerance_iterator.hpp>
//agg
#include "agg_conv_clip_polyline.h"
namespace mapnik { namespace detail {
template <typename Helper>

View file

@ -368,6 +368,13 @@ template MAPNIK_DECL void save_to_file<image_view_any> (image_view_any const&,
std::string const&,
rgba_palette const& palette);
template MAPNIK_DECL std::string save_to_string<image_view_rgba8> (image_view_rgba8 const&,
std::string const&);
template MAPNIK_DECL std::string save_to_string<image_view_rgba8> (image_view_rgba8 const&,
std::string const&,
rgba_palette const& palette);
template MAPNIK_DECL std::string save_to_string<image_view_any> (image_view_any const&,
std::string const&);

View file

@ -175,7 +175,15 @@ std::shared_ptr<mapnik::marker const> marker_cache::find(std::string const& uri,
svg_path_adapter svg_path(stl_storage);
svg_converter_type svg(svg_path, marker_path->attributes());
svg_parser p(svg);
p.parse_from_string(known_svg_string);
if (!p.parse_from_string(known_svg_string))
{
for (auto const& msg : p.error_messages())
{
MAPNIK_LOG_ERROR(marker_cache) << "SVG PARSING ERROR:\"" << msg << "\"";
}
return std::make_shared<mapnik::marker const>(mapnik::marker_null());
}
//svg.arrange_orientations();
double lox,loy,hix,hiy;
svg.bounding_rect(&lox, &loy, &hix, &hiy);
@ -207,7 +215,16 @@ std::shared_ptr<mapnik::marker const> marker_cache::find(std::string const& uri,
svg_path_adapter svg_path(stl_storage);
svg_converter_type svg(svg_path, marker_path->attributes());
svg_parser p(svg);
p.parse(uri);
if (!p.parse(uri))
{
for (auto const& msg : p.error_messages())
{
MAPNIK_LOG_ERROR(marker_cache) << "SVG PARSING ERROR:\"" << msg << "\"";
}
return std::make_shared<mapnik::marker const>(mapnik::marker_null());
}
//svg.arrange_orientations();
double lox,loy,hix,hiy;
svg.bounding_rect(&lox, &loy, &hix, &hiy);

View file

@ -82,6 +82,7 @@ void memory_datasource::push(feature_ptr feature)
// TODO - collect attribute descriptors?
//desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer));
features_.push_back(feature);
dirty_extent_ = true;
}
datasource::datasource_t memory_datasource::type() const
@ -110,10 +111,11 @@ void memory_datasource::set_envelope(box2d<double> const& box)
box2d<double> memory_datasource::envelope() const
{
if (!extent_.valid())
if (!extent_.valid() || dirty_extent_)
{
accumulate_extent func(extent_);
std::for_each(features_.begin(),features_.end(),func);
dirty_extent_ = false;
}
return extent_;
}

File diff suppressed because it is too large Load diff

View file

@ -36,12 +36,12 @@ font_face::font_face(FT_Face face)
bool font_face::set_character_sizes(double size)
{
return !FT_Set_Char_Size(face_,0,(FT_F26Dot6)(size * (1<<6)),0,0);
return (FT_Set_Char_Size(face_,0,(FT_F26Dot6)(size * (1<<6)),0,0) == 0);
}
bool font_face::set_unscaled_character_sizes()
{
return !FT_Set_Char_Size(face_,0,face_->units_per_EM,0,0);
return (FT_Set_Char_Size(face_,0,face_->units_per_EM,0,0) == 0);
}
bool font_face::glyph_dimensions(glyph_info & glyph) const

Some files were not shown because too many files have changed in this diff Show more