Merge branch 'svg-parser-errors' into large_csv
This commit is contained in:
commit
f9bd21eeb5
125 changed files with 3130 additions and 5774 deletions
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -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
|
127
CHANGELOG.md
127
CHANGELOG.md
|
@ -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
|
||||
|
|
16
INSTALL.md
16
INSTALL.md
|
@ -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.
|
||||
|
|
19
Makefile
19
Makefile
|
@ -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
|
||||
|
|
42
SConstruct
42
SConstruct
|
@ -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']:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,5 +55,5 @@ run test_offset_converter 10 1000
|
|||
--threads 1
|
||||
|
||||
./benchmark/out/test_quad_tree \
|
||||
--iterations 10000 \
|
||||
--iterations 1000 \
|
||||
--threads 10
|
||||
|
|
53
benchmark/test_noop_rendering.cpp
Normal file
53
benchmark/test_noop_rendering.cpp
Normal 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")
|
|
@ -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'
|
||||
|
|
4
deps/agg/include/agg_color_gray.h
vendored
4
deps/agg/include/agg_color_gray.h
vendored
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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)]
|
||||
;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -56,6 +56,7 @@ private:
|
|||
datasource::datasource_t type_;
|
||||
bool bbox_check_;
|
||||
mutable box2d<double> extent_;
|
||||
mutable bool dirty_extent_ = true;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
||||
}}
|
||||
|
|
|
@ -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
|
|
@ -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>;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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')
|
|
@ -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_);
|
||||
}
|
|
@ -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
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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>";
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
TYPE MDSYS.SDO_POINT_TYPE AS SDOPointType
|
||||
TYPE MDSYS.SDO_GEOMETRY AS SDOGeometry
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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')
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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>;
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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')
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_);
|
||||
}
|
||||
|
|
|
@ -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 + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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&);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
@ -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
Loading…
Reference in a new issue