Reduce merge conflicts with master
This commit is contained in:
commit
488af4055d
49 changed files with 2676 additions and 1663 deletions
|
@ -83,7 +83,7 @@ script:
|
||||||
- if [[ ${COVERAGE} != true ]]; then
|
- if [[ ${COVERAGE} != true ]]; then
|
||||||
make bench;
|
make bench;
|
||||||
fi
|
fi
|
||||||
- if [[ ${TEST_RESULT} != 0 ]]; then exit $TEST_RESULT ; fi;
|
- if [[ ${TEST_RESULT:-0} != 0 ]]; then exit $TEST_RESULT ; fi;
|
||||||
- if [[ ${MASON_PUBLISH} == true ]]; then
|
- if [[ ${MASON_PUBLISH} == true ]]; then
|
||||||
./mason_latest.sh build;
|
./mason_latest.sh build;
|
||||||
./mason_latest.sh link;
|
./mason_latest.sh link;
|
||||||
|
|
|
@ -294,6 +294,7 @@ opts.AddVariables(
|
||||||
# Note: setting DEBUG=True will override any custom OPTIMIZATION level
|
# Note: setting DEBUG=True will override any custom OPTIMIZATION level
|
||||||
BoolVariable('DEBUG', 'Compile a debug version of Mapnik', 'False'),
|
BoolVariable('DEBUG', 'Compile a debug version of Mapnik', 'False'),
|
||||||
BoolVariable('DEBUG_UNDEFINED', 'Compile a version of Mapnik using clang/llvm undefined behavior asserts', 'False'),
|
BoolVariable('DEBUG_UNDEFINED', 'Compile a version of Mapnik using clang/llvm undefined behavior asserts', 'False'),
|
||||||
|
BoolVariable('DEBUG_SANITIZE', 'Compile a version of Mapnik using clang/llvm address sanitation', 'False'),
|
||||||
ListVariable('INPUT_PLUGINS','Input drivers to include',DEFAULT_PLUGINS,PLUGINS.keys()),
|
ListVariable('INPUT_PLUGINS','Input drivers to include',DEFAULT_PLUGINS,PLUGINS.keys()),
|
||||||
('WARNING_CXXFLAGS', 'Compiler flags you can set to reduce warning levels which are placed after -Wall.', ''),
|
('WARNING_CXXFLAGS', 'Compiler flags you can set to reduce warning levels which are placed after -Wall.', ''),
|
||||||
|
|
||||||
|
@ -1799,6 +1800,11 @@ if not preconfigured:
|
||||||
if env['DEBUG_UNDEFINED']:
|
if env['DEBUG_UNDEFINED']:
|
||||||
env.Append(CXXFLAGS = '-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -ftrapv -fwrapv')
|
env.Append(CXXFLAGS = '-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -ftrapv -fwrapv')
|
||||||
|
|
||||||
|
if env['DEBUG_SANITIZE']:
|
||||||
|
env.Append(CXXFLAGS = ['-fsanitize=address'])
|
||||||
|
env.Append(LINKFLAGS = ['-fsanitize=address'])
|
||||||
|
|
||||||
|
|
||||||
# if requested, sort LIBPATH and CPPPATH one last time before saving...
|
# if requested, sort LIBPATH and CPPPATH one last time before saving...
|
||||||
if env['PRIORITIZE_LINKING']:
|
if env['PRIORITIZE_LINKING']:
|
||||||
conf.prioritize_paths(silent=True)
|
conf.prioritize_paths(silent=True)
|
||||||
|
|
|
@ -90,16 +90,16 @@ struct evaluate
|
||||||
return geom.value<value_type,feature_type>(feature_);
|
return geom.value<value_type,feature_type>(feature_);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type operator() (binary_node<tags::logical_and> const & x) const
|
value_type operator() (binary_node<tags::logical_and> const& x) const
|
||||||
{
|
{
|
||||||
return (util::apply_visitor(*this, x.left).to_bool())
|
return (util::apply_visitor(*this, x.left).to_bool())
|
||||||
&& (util::apply_visitor(*this, x.right).to_bool());
|
&& (util::apply_visitor(*this, x.right).to_bool());
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type operator() (binary_node<tags::logical_or> const & x) const
|
value_type operator() (binary_node<tags::logical_or> const& x) const
|
||||||
{
|
{
|
||||||
return (util::apply_visitor(*this,x.left).to_bool())
|
return (util::apply_visitor(*this, x.left).to_bool())
|
||||||
|| (util::apply_visitor(*this,x.right).to_bool());
|
|| (util::apply_visitor(*this, x.right).to_bool());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Tag>
|
template <typename Tag>
|
||||||
|
|
|
@ -72,6 +72,12 @@ struct geometry_envelope
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void operator() (mapnik::geometry::linear_ring<T> const& ring) const
|
||||||
|
{
|
||||||
|
(*this)(static_cast<mapnik::geometry::line_string<T> const&>(ring));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void operator() (mapnik::geometry::polygon<T> const& poly) const
|
void operator() (mapnik::geometry::polygon<T> const& poly) const
|
||||||
{
|
{
|
||||||
|
@ -149,4 +155,3 @@ mapnik::box2d<double> envelope(T const& geom)
|
||||||
|
|
||||||
} // end ns geometry
|
} // end ns geometry
|
||||||
} // end ns mapnik
|
} // end ns mapnik
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ geometry_empty reproject_internal(geometry_empty const&, proj_transform const&,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
point<T> reproject_internal(point<T> const & p, proj_transform const& proj_trans, unsigned int & n_err)
|
point<T> reproject_internal(point<T> const& p, proj_transform const& proj_trans, unsigned int & n_err)
|
||||||
{
|
{
|
||||||
point<T> new_p(p);
|
point<T> new_p(p);
|
||||||
if (!proj_trans.forward(new_p))
|
if (!proj_trans.forward(new_p))
|
||||||
|
@ -47,7 +47,7 @@ point<T> reproject_internal(point<T> const & p, proj_transform const& proj_trans
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
line_string<T> reproject_internal(line_string<T> const & ls, proj_transform const& proj_trans, unsigned int & n_err)
|
line_string<T> reproject_internal(line_string<T> const& ls, proj_transform const& proj_trans, unsigned int & n_err)
|
||||||
{
|
{
|
||||||
line_string<T> new_ls(ls);
|
line_string<T> new_ls(ls);
|
||||||
unsigned int err = proj_trans.forward(new_ls);
|
unsigned int err = proj_trans.forward(new_ls);
|
||||||
|
@ -59,7 +59,7 @@ line_string<T> reproject_internal(line_string<T> const & ls, proj_transform cons
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
polygon<T> reproject_internal(polygon<T> const & poly, proj_transform const& proj_trans, unsigned int & n_err)
|
polygon<T> reproject_internal(polygon<T> const& poly, proj_transform const& proj_trans, unsigned int & n_err)
|
||||||
{
|
{
|
||||||
polygon<T> new_poly;
|
polygon<T> new_poly;
|
||||||
linear_ring<T> new_ext(poly.exterior_ring);
|
linear_ring<T> new_ext(poly.exterior_ring);
|
||||||
|
@ -171,7 +171,8 @@ geometry_collection<T> reproject_internal(geometry_collection<T> const & c, proj
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct geom_reproj_copy_visitor {
|
struct geom_reproj_copy_visitor
|
||||||
|
{
|
||||||
|
|
||||||
geom_reproj_copy_visitor(proj_transform const & proj_trans, unsigned int & n_err)
|
geom_reproj_copy_visitor(proj_transform const & proj_trans, unsigned int & n_err)
|
||||||
: proj_trans_(proj_trans),
|
: proj_trans_(proj_trans),
|
||||||
|
|
|
@ -1,82 +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 MAPNIK_GEOMETRY_UNIQUE_HPP
|
|
||||||
#define MAPNIK_GEOMETRY_UNIQUE_HPP
|
|
||||||
|
|
||||||
#include <mapnik/geometry.hpp>
|
|
||||||
#include <mapnik/geometry_adapters.hpp>
|
|
||||||
#include <boost/geometry/algorithms/unique.hpp>
|
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace mapnik { namespace geometry {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
struct geometry_unique
|
|
||||||
{
|
|
||||||
using result_type = void;
|
|
||||||
|
|
||||||
result_type operator() (geometry & geom) const
|
|
||||||
{
|
|
||||||
mapnik::util::apply_visitor(*this, geom);
|
|
||||||
}
|
|
||||||
|
|
||||||
result_type operator() (geometry_collection & collection) const
|
|
||||||
{
|
|
||||||
for (auto & geom : collection)
|
|
||||||
{
|
|
||||||
(*this)(geom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result_type operator() (line_string & line) const
|
|
||||||
{
|
|
||||||
boost::geometry::unique(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
result_type operator() (polygon & poly) const
|
|
||||||
{
|
|
||||||
boost::geometry::unique(poly);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
result_type operator() (T & geom) const
|
|
||||||
{
|
|
||||||
// no-op
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename GeomType>
|
|
||||||
inline void unique(GeomType & geom)
|
|
||||||
{
|
|
||||||
static_assert(!std::is_const<GeomType>::value,"mapnik::geometry::unique on const& is invalid");
|
|
||||||
detail::geometry_unique()(geom);
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif // MAPNIK_GEOMETRY_UNIQUE_HPP
|
|
|
@ -23,16 +23,17 @@
|
||||||
#ifndef MAPNIK_IMAGE_FILITER_GRAMMAR_HPP
|
#ifndef MAPNIK_IMAGE_FILITER_GRAMMAR_HPP
|
||||||
#define MAPNIK_IMAGE_FILITER_GRAMMAR_HPP
|
#define MAPNIK_IMAGE_FILITER_GRAMMAR_HPP
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
#include <mapnik/css_color_grammar.hpp>
|
||||||
|
#include <mapnik/color.hpp>
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
#include <boost/spirit/include/qi.hpp>
|
#include <boost/spirit/include/qi.hpp>
|
||||||
#include <boost/fusion/include/adapt_struct.hpp>
|
#include <boost/fusion/include/adapt_struct.hpp>
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
// mapnik
|
|
||||||
#include <mapnik/css_color_grammar.hpp>
|
|
||||||
#include <mapnik/color.hpp>
|
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
|
#include <mapnik/image.hpp>
|
||||||
#include <mapnik/pixel_types.hpp>
|
#include <mapnik/pixel_types.hpp>
|
||||||
|
|
||||||
//stl
|
//stl
|
||||||
|
|
|
@ -24,7 +24,9 @@
|
||||||
#define MAPNIK_IMAGE_SCALING_TRAITS_HPP
|
#define MAPNIK_IMAGE_SCALING_TRAITS_HPP
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/span_image_filter.h>
|
#include <mapnik/image.hpp>
|
||||||
|
#include <mapnik/image_scaling.hpp>
|
||||||
|
#include <mapnik/span_image_filter.hpp>
|
||||||
|
|
||||||
// agg
|
// agg
|
||||||
#include "agg_image_accessors.h"
|
#include "agg_image_accessors.h"
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#ifndef MAPNIK_IMAGE_UTIL_JPEG_HPP
|
#ifndef MAPNIK_IMAGE_UTIL_JPEG_HPP
|
||||||
#define MAPNIK_IMAGE_UTIL_JPEG_HPP
|
#define MAPNIK_IMAGE_UTIL_JPEG_HPP
|
||||||
|
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#ifndef MAPNIK_IMAGE_UTIL_PNG_HPP
|
#ifndef MAPNIK_IMAGE_UTIL_PNG_HPP
|
||||||
#define MAPNIK_IMAGE_UTIL_PNG_HPP
|
#define MAPNIK_IMAGE_UTIL_PNG_HPP
|
||||||
|
|
||||||
|
#include <mapnik/palette.hpp>
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#ifndef MAPNIK_IMAGE_VIEW_NULL_HPP
|
#ifndef MAPNIK_IMAGE_VIEW_NULL_HPP
|
||||||
#define MAPNIK_IMAGE_VIEW_NULL_HPP
|
#define MAPNIK_IMAGE_VIEW_NULL_HPP
|
||||||
|
|
||||||
#include <mapnik/image.hpp>
|
#include <mapnik/image_view.hpp>
|
||||||
|
|
||||||
//stl
|
//stl
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
|
@ -63,10 +63,10 @@ struct set_position_impl
|
||||||
struct push_position_impl
|
struct push_position_impl
|
||||||
{
|
{
|
||||||
using result_type = void;
|
using result_type = void;
|
||||||
template <typename T0,typename T1>
|
template <typename T0, typename T1>
|
||||||
result_type operator() (T0 & coords, T1 const& pos) const
|
result_type operator() (T0 & coords, T1 const& pos) const
|
||||||
{
|
{
|
||||||
if (pos) coords.push_back(*pos);
|
if (pos) coords.emplace_back(*pos);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
#include <mapnik/util/singleton.hpp>
|
#include <mapnik/util/singleton.hpp>
|
||||||
#include <mapnik/util/noncopyable.hpp>
|
#include <mapnik/util/noncopyable.hpp>
|
||||||
|
|
||||||
// boost
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
|
|
@ -179,12 +179,7 @@ public:
|
||||||
"Values stored in quad-tree must be standard layout types to allow serialisation");
|
"Values stored in quad-tree must be standard layout types to allow serialisation");
|
||||||
char header[16];
|
char header[16];
|
||||||
std::memset(header,0,16);
|
std::memset(header,0,16);
|
||||||
header[0]='m';
|
std::strcpy(header,"mapnik-index");
|
||||||
header[1]='a';
|
|
||||||
header[2]='p';
|
|
||||||
header[3]='n';
|
|
||||||
header[4]='i';
|
|
||||||
header[5]='k';
|
|
||||||
out.write(header,16);
|
out.write(header,16);
|
||||||
write_node(out,root_);
|
write_node(out,root_);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include "agg_span_image_filter_gray.h"
|
#include "agg_span_image_filter_gray.h"
|
||||||
#include "agg_span_image_filter_rgba.h"
|
#include "agg_span_image_filter_rgba.h"
|
||||||
|
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
|
@ -79,8 +79,7 @@ struct path_attributes
|
||||||
even_odd_flag(false),
|
even_odd_flag(false),
|
||||||
visibility_flag(true),
|
visibility_flag(true),
|
||||||
display_flag(true)
|
display_flag(true)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
// Copy constructor
|
// Copy constructor
|
||||||
path_attributes(path_attributes const& attr)
|
path_attributes(path_attributes const& attr)
|
||||||
|
|
|
@ -73,46 +73,29 @@ namespace mapnik { namespace svg {
|
||||||
>> *(-lit(',') >> coord [ line_to_(_1,_a) ] ); // *line_to
|
>> *(-lit(',') >> coord [ line_to_(_1,_a) ] ); // *line_to
|
||||||
|
|
||||||
H = (lit('H')[_a = false] | lit('h')[_a = true])
|
H = (lit('H')[_a = false] | lit('h')[_a = true])
|
||||||
>> +double_[ hline_to_(_1,_a) ] ; // +hline_to
|
>> (double_[ hline_to_(_1,_a) ] % -lit(',')) ; // +hline_to
|
||||||
|
|
||||||
V = (lit('V')[_a = false] | lit('v')[_a = true])
|
V = (lit('V')[_a = false] | lit('v')[_a = true])
|
||||||
>> +double_ [ vline_to_(_1,_a) ]; // +vline_to
|
>> (double_ [ vline_to_(_1,_a) ] % -lit(',')); // +vline_to
|
||||||
|
|
||||||
L = (lit('L')[_a = false] | lit('l')[_a = true])
|
L = (lit('L')[_a = false] | lit('l')[_a = true])
|
||||||
>> +coord [ line_to_(_1,_a) ]; // +line_to
|
>> (coord [ line_to_(_1,_a) ] % -lit(',')); // +line_to
|
||||||
|
|
||||||
C = (lit('C')[_a = false] | lit('c')[_a = true])
|
C = (lit('C')[_a = false] | lit('c')[_a = true])
|
||||||
>> +(coord
|
>> ((coord >> -lit(',') >> coord >> -lit(',') >> coord) [ curve4_(_1,_2,_3,_a) ] % -lit(',')); // +curve4
|
||||||
>> -lit(',')
|
|
||||||
>> coord
|
|
||||||
>> -lit(',')
|
|
||||||
>> coord) [ curve4_(_1,_2,_3,_a) ]; // +curve4
|
|
||||||
|
|
||||||
S = (lit('S')[_a = false] | lit('s')[_a = true])
|
S = (lit('S')[_a = false] | lit('s')[_a = true])
|
||||||
>> +(coord
|
>> ((coord >> -lit(',') >> coord) [ curve4_smooth_(_1,_2,_a) ] % -lit(',')); // +curve4_smooth (smooth curveto)
|
||||||
>> -lit(',')
|
|
||||||
>> coord) [ curve4_smooth_(_1,_2,_a) ]; // +curve4_smooth (smooth curveto)
|
|
||||||
|
|
||||||
Q = (lit('Q')[_a = false] | lit('q')[_a = true])
|
Q = (lit('Q')[_a = false] | lit('q')[_a = true])
|
||||||
>> +(coord
|
>> ((coord >> -lit(',') >> coord) [ curve3_(_1,_2,_a) ] % -lit(',')); // +curve3 (quadratic-bezier-curveto)
|
||||||
>> -lit(',')
|
|
||||||
>> coord) [ curve3_(_1,_2,_a) ]; // +curve3 (quadratic-bezier-curveto)
|
|
||||||
|
|
||||||
T = (lit('T')[_a = false] | lit('t')[_a = true])
|
T = (lit('T')[_a = false] | lit('t')[_a = true])
|
||||||
>> +(coord ) [ curve3_smooth_(_1,_a) ]; // +curve3_smooth (smooth-quadratic-bezier-curveto)
|
>> ((coord ) [ curve3_smooth_(_1,_a) ] % -lit(',')); // +curve3_smooth (smooth-quadratic-bezier-curveto)
|
||||||
|
|
||||||
A = (lit('A')[_a = false] | lit('a')[_a = true])
|
A = (lit('A')[_a = false] | lit('a')[_a = true])
|
||||||
>> +(coord
|
>> ((coord >> -lit(',') >> double_ >> -lit(',')
|
||||||
>> -lit(',')
|
>> int_ >> -lit(',') >> int_ >> -lit(',') >> coord) [arc_to_(_1,_2,_3,_4,_5,_a)] % -lit(',')); // arc_to;
|
||||||
>> double_
|
|
||||||
>> -lit(',')
|
|
||||||
>> int_
|
|
||||||
>> -lit(',')
|
|
||||||
>> int_
|
|
||||||
>> -lit(',')
|
|
||||||
>> coord) [arc_to_(_1,_2,_3,_4,_5,_a)]; // arc_to;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Z = no_case[lit('z')] [close_()]; // close path
|
Z = no_case[lit('z')] [close_()]; // close path
|
||||||
|
|
||||||
|
|
|
@ -60,12 +60,10 @@
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
namespace svg {
|
namespace svg {
|
||||||
|
|
||||||
|
// Arbitrary linear gradient specified by two control points. Gradient
|
||||||
|
// value is taken as the normalised distance along the line segment
|
||||||
|
// represented by the two points.
|
||||||
|
|
||||||
/**
|
|
||||||
* Arbitrary linear gradient specified by two control points. Gradient
|
|
||||||
* value is taken as the normalised distance along the line segment
|
|
||||||
* represented by the two points.
|
|
||||||
*/
|
|
||||||
class linear_gradient_from_segment
|
class linear_gradient_from_segment
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -105,14 +103,14 @@ template <typename VertexSource, typename AttributeSource, typename ScanlineRend
|
||||||
class svg_renderer_agg : util::noncopyable
|
class svg_renderer_agg : util::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using curved_type = agg::conv_curve<VertexSource> ;
|
using curved_type = agg::conv_curve<VertexSource>;
|
||||||
using curved_stroked_type = agg::conv_stroke<curved_type> ;
|
using curved_stroked_type = agg::conv_stroke<curved_type>;
|
||||||
using curved_stroked_trans_type = agg::conv_transform<curved_stroked_type>;
|
using curved_stroked_trans_type = agg::conv_transform<curved_stroked_type>;
|
||||||
using curved_trans_type = agg::conv_transform<curved_type> ;
|
using curved_trans_type = agg::conv_transform<curved_type>;
|
||||||
using curved_trans_contour_type = agg::conv_contour<curved_trans_type> ;
|
using curved_trans_contour_type = agg::conv_contour<curved_trans_type>;
|
||||||
using renderer_base = agg::renderer_base<PixelFormat> ;
|
using renderer_base = agg::renderer_base<PixelFormat>;
|
||||||
using vertex_source_type = VertexSource ;
|
using vertex_source_type = VertexSource;
|
||||||
using attribute_source_type = AttributeSource ;
|
using attribute_source_type = AttributeSource;
|
||||||
|
|
||||||
svg_renderer_agg(VertexSource & source, AttributeSource const& attributes)
|
svg_renderer_agg(VertexSource & source, AttributeSource const& attributes)
|
||||||
: source_(source),
|
: source_(source),
|
||||||
|
@ -191,11 +189,11 @@ public:
|
||||||
|
|
||||||
// scale everything up since agg turns things into integers a bit too soon
|
// scale everything up since agg turns things into integers a bit too soon
|
||||||
int scaleup=255;
|
int scaleup=255;
|
||||||
radius*=scaleup;
|
radius *= scaleup;
|
||||||
x1*=scaleup;
|
x1 *= scaleup;
|
||||||
y1*=scaleup;
|
y1 *= scaleup;
|
||||||
x2*=scaleup;
|
x2 *= scaleup;
|
||||||
y2*=scaleup;
|
y2 *= scaleup;
|
||||||
|
|
||||||
transform.scale(scaleup,scaleup);
|
transform.scale(scaleup,scaleup);
|
||||||
interpolator_type span_interpolator(transform);
|
interpolator_type span_interpolator(transform);
|
||||||
|
@ -217,10 +215,10 @@ public:
|
||||||
color_func_type>;
|
color_func_type>;
|
||||||
// scale everything up since agg turns things into integers a bit too soon
|
// scale everything up since agg turns things into integers a bit too soon
|
||||||
int scaleup=255;
|
int scaleup=255;
|
||||||
x1*=scaleup;
|
x1 *= scaleup;
|
||||||
y1*=scaleup;
|
y1 *= scaleup;
|
||||||
x2*=scaleup;
|
x2 *= scaleup;
|
||||||
y2*=scaleup;
|
y2 *= scaleup;
|
||||||
|
|
||||||
transform.scale(scaleup,scaleup);
|
transform.scale(scaleup,scaleup);
|
||||||
|
|
||||||
|
@ -288,7 +286,8 @@ public:
|
||||||
|
|
||||||
if(attr.fill_gradient.get_gradient_type() != NO_GRADIENT)
|
if(attr.fill_gradient.get_gradient_type() != NO_GRADIENT)
|
||||||
{
|
{
|
||||||
render_gradient(ras, sl, ren, attr.fill_gradient, transform, attr.fill_opacity * attr.opacity * opacity, symbol_bbox, curved_trans, attr.index);
|
render_gradient(ras, sl, ren, attr.fill_gradient, transform,
|
||||||
|
attr.fill_opacity * attr.opacity * opacity, symbol_bbox, curved_trans, attr.index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -324,7 +323,8 @@ public:
|
||||||
|
|
||||||
if(attr.stroke_gradient.get_gradient_type() != NO_GRADIENT)
|
if(attr.stroke_gradient.get_gradient_type() != NO_GRADIENT)
|
||||||
{
|
{
|
||||||
render_gradient(ras, sl, ren, attr.stroke_gradient, transform, attr.stroke_opacity * attr.opacity * opacity, symbol_bbox, curved_trans, attr.index);
|
render_gradient(ras, sl, ren, attr.stroke_gradient, transform,
|
||||||
|
attr.stroke_opacity * attr.opacity * opacity, symbol_bbox, curved_trans, attr.index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -317,12 +317,8 @@ struct evaluate_expression_wrapper<mapnik::dash_array>
|
||||||
mapnik::value_type val = util::apply_visitor(mapnik::evaluate<T2,mapnik::value_type,T3>(feature,vars), expr);
|
mapnik::value_type val = util::apply_visitor(mapnik::evaluate<T2,mapnik::value_type,T3>(feature,vars), expr);
|
||||||
if (val.is_null()) return dash_array();
|
if (val.is_null()) return dash_array();
|
||||||
dash_array dash;
|
dash_array dash;
|
||||||
std::vector<double> buf;
|
|
||||||
std::string str = val.to_string();
|
std::string str = val.to_string();
|
||||||
if (util::parse_dasharray(str,buf))
|
util::parse_dasharray(str,dash);
|
||||||
{
|
|
||||||
util::add_dashes(buf,dash);
|
|
||||||
}
|
|
||||||
return dash;
|
return dash;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,7 +24,12 @@
|
||||||
#define MAPNIK_SYMBOLIZER_DEFAULT_VALUES_HPP
|
#define MAPNIK_SYMBOLIZER_DEFAULT_VALUES_HPP
|
||||||
|
|
||||||
#include <mapnik/symbolizer_keys.hpp>
|
#include <mapnik/symbolizer_keys.hpp>
|
||||||
|
#include <mapnik/symbolizer_enumerations.hpp>
|
||||||
|
#include <mapnik/image_compositing.hpp>
|
||||||
|
#include <mapnik/image_scaling.hpp>
|
||||||
|
#include <mapnik/simplify.hpp>
|
||||||
#include <mapnik/color.hpp>
|
#include <mapnik/color.hpp>
|
||||||
|
#include <mapnik/value_types.hpp>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -404,9 +404,8 @@ struct set_symbolizer_property_impl<Symbolizer,dash_array,false>
|
||||||
boost::optional<std::string> str = node.get_opt_attr<std::string>(name);
|
boost::optional<std::string> str = node.get_opt_attr<std::string>(name);
|
||||||
if (str)
|
if (str)
|
||||||
{
|
{
|
||||||
std::vector<double> buf;
|
|
||||||
dash_array dash;
|
dash_array dash;
|
||||||
if (util::parse_dasharray(*str,buf) && util::add_dashes(buf,dash))
|
if (util::parse_dasharray(*str,dash))
|
||||||
{
|
{
|
||||||
put(sym,key,dash);
|
put(sym,key,dash);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,32 +23,13 @@
|
||||||
#ifndef MAPNIK_UTIL_DASHARRAY_PARSER_HPP
|
#ifndef MAPNIK_UTIL_DASHARRAY_PARSER_HPP
|
||||||
#define MAPNIK_UTIL_DASHARRAY_PARSER_HPP
|
#define MAPNIK_UTIL_DASHARRAY_PARSER_HPP
|
||||||
|
|
||||||
|
#include <mapnik/symbolizer_base.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace mapnik { namespace util {
|
namespace mapnik { namespace util {
|
||||||
|
|
||||||
bool parse_dasharray(std::string const& value, std::vector<double>& dasharray);
|
bool parse_dasharray(std::string const& value, dash_array & dash);
|
||||||
|
|
||||||
inline bool add_dashes(std::vector<double> & buf, std::vector<std::pair<double,double> > & dash)
|
|
||||||
{
|
|
||||||
if (buf.empty()) return false;
|
|
||||||
size_t size = buf.size();
|
|
||||||
if (size % 2 == 1)
|
|
||||||
{
|
|
||||||
buf.insert(buf.end(),buf.begin(),buf.end());
|
|
||||||
}
|
|
||||||
std::vector<double>::const_iterator pos = buf.begin();
|
|
||||||
while (pos != buf.end())
|
|
||||||
{
|
|
||||||
if (*pos > 0.0 || *(pos+1) > 0.0) // avoid both dash and gap eq 0.0
|
|
||||||
{
|
|
||||||
dash.emplace_back(*pos,*(pos + 1));
|
|
||||||
}
|
|
||||||
pos +=2;
|
|
||||||
}
|
|
||||||
return !buf.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <mapnik/geom_util.hpp>
|
#include <mapnik/geom_util.hpp>
|
||||||
// stl
|
// stl
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
using mapnik::box2d;
|
using mapnik::box2d;
|
||||||
using mapnik::query;
|
using mapnik::query;
|
||||||
|
@ -44,7 +45,6 @@ public:
|
||||||
static box2d<double> bounding_box( InputStream& in );
|
static box2d<double> bounding_box( InputStream& in );
|
||||||
static void query_first_n(Filter const& filter, InputStream & in, std::vector<Value>& pos, std::size_t count);
|
static void query_first_n(Filter const& filter, InputStream & in, std::vector<Value>& pos, std::size_t count);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
spatial_index();
|
spatial_index();
|
||||||
~spatial_index();
|
~spatial_index();
|
||||||
spatial_index(spatial_index const&);
|
spatial_index(spatial_index const&);
|
||||||
|
@ -53,12 +53,23 @@ private:
|
||||||
static void read_envelope(InputStream& in, box2d<double>& envelope);
|
static void read_envelope(InputStream& in, box2d<double>& envelope);
|
||||||
static void query_node(Filter const& filter, InputStream& in, std::vector<Value> & results);
|
static void query_node(Filter const& filter, InputStream& in, std::vector<Value> & results);
|
||||||
static void query_first_n_impl(Filter const& filter, InputStream& in, std::vector<Value> & results, std::size_t count);
|
static void query_first_n_impl(Filter const& filter, InputStream& in, std::vector<Value> & results, std::size_t count);
|
||||||
|
static bool check_header(InputStream& in);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Value, typename Filter, typename InputStream>
|
||||||
|
bool spatial_index<Value, Filter, InputStream>::check_header(InputStream& in)
|
||||||
|
{
|
||||||
|
static_assert(std::is_standard_layout<Value>::value, "Values stored in quad-tree must be standard layout type");
|
||||||
|
char header[17]; // mapnik-index
|
||||||
|
std::memset(header, 0, 17);
|
||||||
|
in.read(header,16);
|
||||||
|
return (std::strncmp(header, "mapnik-index",12) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Value, typename Filter, typename InputStream>
|
template <typename Value, typename Filter, typename InputStream>
|
||||||
box2d<double> spatial_index<Value, Filter, InputStream>::bounding_box(InputStream& in)
|
box2d<double> spatial_index<Value, Filter, InputStream>::bounding_box(InputStream& in)
|
||||||
{
|
{
|
||||||
static_assert(std::is_standard_layout<Value>::value, "Values stored in quad-tree must be standard layout type");
|
if (!check_header(in)) throw std::runtime_error("Invalid index file");
|
||||||
in.seekg(16 + 4, std::ios::beg);
|
in.seekg(16 + 4, std::ios::beg);
|
||||||
box2d<double> box;
|
box2d<double> box;
|
||||||
read_envelope(in, box);
|
read_envelope(in, box);
|
||||||
|
@ -69,7 +80,7 @@ box2d<double> spatial_index<Value, Filter, InputStream>::bounding_box(InputStrea
|
||||||
template <typename Value, typename Filter, typename InputStream>
|
template <typename Value, typename Filter, typename InputStream>
|
||||||
void spatial_index<Value, Filter, InputStream>::query(Filter const& filter, InputStream& in, std::vector<Value>& results)
|
void spatial_index<Value, Filter, InputStream>::query(Filter const& filter, InputStream& in, std::vector<Value>& results)
|
||||||
{
|
{
|
||||||
static_assert(std::is_standard_layout<Value>::value, "Values stored in quad-tree must be standard layout types");
|
if (!check_header(in)) throw std::runtime_error("Invalid index file");
|
||||||
in.seekg(16, std::ios::beg);
|
in.seekg(16, std::ios::beg);
|
||||||
query_node(filter, in, results);
|
query_node(filter, in, results);
|
||||||
}
|
}
|
||||||
|
@ -104,7 +115,7 @@ void spatial_index<Value, Filter, InputStream>::query_node(Filter const& filter,
|
||||||
template <typename Value, typename Filter, typename InputStream>
|
template <typename Value, typename Filter, typename InputStream>
|
||||||
void spatial_index<Value, Filter, InputStream>::query_first_n(Filter const& filter, InputStream& in, std::vector<Value>& results, std::size_t count)
|
void spatial_index<Value, Filter, InputStream>::query_first_n(Filter const& filter, InputStream& in, std::vector<Value>& results, std::size_t count)
|
||||||
{
|
{
|
||||||
static_assert(std::is_standard_layout<Value>::value, "Values stored in quad-tree must be standard layout types");
|
if (!check_header(in)) throw std::runtime_error("Invalid index file");
|
||||||
in.seekg(16, std::ios::beg);
|
in.seekg(16, std::ios::beg);
|
||||||
query_first_n_impl(filter, in, results, count);
|
query_first_n_impl(filter, in, results, count);
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,29 +283,20 @@ namespace detail {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct unwrapper
|
struct unwrapper
|
||||||
{
|
{
|
||||||
T const& operator() (T const& obj) const
|
static T const& apply_const(T const& obj) {return obj;}
|
||||||
{
|
static T& apply(T & obj) {return obj;}
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator() (T & obj) const
|
|
||||||
{
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct unwrapper<recursive_wrapper<T>>
|
struct unwrapper<recursive_wrapper<T>>
|
||||||
{
|
{
|
||||||
auto operator() (recursive_wrapper<T> const& obj) const
|
static auto apply_const(recursive_wrapper<T> const& obj)
|
||||||
-> typename recursive_wrapper<T>::type const&
|
-> typename recursive_wrapper<T>::type const&
|
||||||
{
|
{
|
||||||
return obj.get();
|
return obj.get();
|
||||||
}
|
}
|
||||||
|
static auto apply(recursive_wrapper<T> & obj)
|
||||||
auto operator() (recursive_wrapper<T> & obj) const
|
-> typename recursive_wrapper<T>::type&
|
||||||
-> typename recursive_wrapper<T>::type &
|
|
||||||
{
|
{
|
||||||
return obj.get();
|
return obj.get();
|
||||||
}
|
}
|
||||||
|
@ -314,8 +305,13 @@ struct unwrapper<recursive_wrapper<T>>
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct unwrapper<std::reference_wrapper<T>>
|
struct unwrapper<std::reference_wrapper<T>>
|
||||||
{
|
{
|
||||||
auto operator() (std::reference_wrapper<T> const& obj) const
|
static auto apply_const(std::reference_wrapper<T> const& obj)
|
||||||
-> typename recursive_wrapper<T>::type const&
|
-> typename std::reference_wrapper<T>::type const&
|
||||||
|
{
|
||||||
|
return obj.get();
|
||||||
|
}
|
||||||
|
static auto apply(std::reference_wrapper<T> & obj)
|
||||||
|
-> typename std::reference_wrapper<T>::type&
|
||||||
{
|
{
|
||||||
return obj.get();
|
return obj.get();
|
||||||
}
|
}
|
||||||
|
@ -332,7 +328,7 @@ struct dispatcher<F, V, R, T, Types...>
|
||||||
{
|
{
|
||||||
if (v.get_type_index() == sizeof...(Types))
|
if (v.get_type_index() == sizeof...(Types))
|
||||||
{
|
{
|
||||||
return f(unwrapper<T>()(v. template get<T>()));
|
return f(unwrapper<T>::apply_const(v. template get<T>()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -344,7 +340,7 @@ struct dispatcher<F, V, R, T, Types...>
|
||||||
{
|
{
|
||||||
if (v.get_type_index() == sizeof...(Types))
|
if (v.get_type_index() == sizeof...(Types))
|
||||||
{
|
{
|
||||||
return f(unwrapper<T>()(v. template get<T>()));
|
return f(unwrapper<T>::apply(v. template get<T>()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -380,8 +376,8 @@ struct binary_dispatcher_rhs<F, V, R, T0, T1, Types...>
|
||||||
{
|
{
|
||||||
if (rhs.get_type_index() == sizeof...(Types)) // call binary functor
|
if (rhs.get_type_index() == sizeof...(Types)) // call binary functor
|
||||||
{
|
{
|
||||||
return f(unwrapper<T0>()(lhs. template get<T0>()),
|
return f(unwrapper<T0>::apply_const(lhs. template get<T0>()),
|
||||||
unwrapper<T1>()(rhs. template get<T1>()));
|
unwrapper<T1>::apply_const(rhs. template get<T1>()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -393,8 +389,8 @@ struct binary_dispatcher_rhs<F, V, R, T0, T1, Types...>
|
||||||
{
|
{
|
||||||
if (rhs.get_type_index() == sizeof...(Types)) // call binary functor
|
if (rhs.get_type_index() == sizeof...(Types)) // call binary functor
|
||||||
{
|
{
|
||||||
return f(unwrapper<T0>()(lhs. template get<T0>()),
|
return f(unwrapper<T0>::apply(lhs. template get<T0>()),
|
||||||
unwrapper<T1>()(rhs. template get<T1>()));
|
unwrapper<T1>::apply(rhs. template get<T1>()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -430,7 +426,8 @@ struct binary_dispatcher_lhs<F, V, R, T0, T1, Types...>
|
||||||
{
|
{
|
||||||
if (lhs.get_type_index() == sizeof...(Types)) // call binary functor
|
if (lhs.get_type_index() == sizeof...(Types)) // call binary functor
|
||||||
{
|
{
|
||||||
return f(lhs. template get<T1>(), rhs. template get<T0>());
|
return f(unwrapper<T1>::apply_const(lhs. template get<T1>()),
|
||||||
|
unwrapper<T0>::apply_const(rhs. template get<T0>()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -442,7 +439,8 @@ struct binary_dispatcher_lhs<F, V, R, T0, T1, Types...>
|
||||||
{
|
{
|
||||||
if (lhs.get_type_index() == sizeof...(Types)) // call binary functor
|
if (lhs.get_type_index() == sizeof...(Types)) // call binary functor
|
||||||
{
|
{
|
||||||
return f(lhs. template get<T1>(), rhs. template get<T0>());
|
return f(unwrapper<T1>::apply(lhs. template get<T1>()),
|
||||||
|
unwrapper<T0>::apply(rhs. template get<T0>()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -480,7 +478,8 @@ struct binary_dispatcher<F, V, R, T, Types...>
|
||||||
{
|
{
|
||||||
if (v0.get_type_index() == v1.get_type_index())
|
if (v0.get_type_index() == v1.get_type_index())
|
||||||
{
|
{
|
||||||
return f(v0. template get<T>(), v1. template get<T>()); // call binary functor
|
return f(unwrapper<T>::apply_const(v0. template get<T>()),
|
||||||
|
unwrapper<T>::apply_const(v1. template get<T>())); // call binary functor
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -500,7 +499,8 @@ struct binary_dispatcher<F, V, R, T, Types...>
|
||||||
{
|
{
|
||||||
if (v0.get_type_index() == v1.get_type_index())
|
if (v0.get_type_index() == v1.get_type_index())
|
||||||
{
|
{
|
||||||
return f(v0. template get<T>(), v1. template get<T>()); // call binary functor
|
return f(unwrapper<T>::apply(v0. template get<T>()),
|
||||||
|
unwrapper<T>::apply(v1. template get<T>())); // call binary functor
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,8 +60,7 @@ if env['PLUGIN_LINKING'] == 'shared':
|
||||||
SHLIBPREFIX='',
|
SHLIBPREFIX='',
|
||||||
SHLIBSUFFIX='.input',
|
SHLIBSUFFIX='.input',
|
||||||
source=plugin_sources,
|
source=plugin_sources,
|
||||||
LIBS=libraries,
|
LIBS=libraries)
|
||||||
LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
|
||||||
|
|
||||||
# if the plugin links to libmapnik ensure it is built first
|
# if the plugin links to libmapnik ensure it is built first
|
||||||
Depends(TARGET, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
|
Depends(TARGET, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||||
|
|
|
@ -63,12 +63,13 @@ shape_index_featureset<filterT>::shape_index_featureset(filterT const& filter,
|
||||||
if (index)
|
if (index)
|
||||||
{
|
{
|
||||||
#if defined(MAPNIK_MEMORY_MAPPED_FILE)
|
#if defined(MAPNIK_MEMORY_MAPPED_FILE)
|
||||||
mapnik::util::spatial_index<int, filterT,boost::interprocess::ibufferstream>::query(filter, index->file(), offsets_);
|
mapnik::util::spatial_index<mapnik::detail::node, filterT,boost::interprocess::ibufferstream>::query(filter, index->file(), offsets_);
|
||||||
#else
|
#else
|
||||||
mapnik::util::spatial_index<int, filterT, std::ifstream>::query(filter, index->file(), offsets_);
|
mapnik::util::spatial_index<mapnik::detail::node, filterT, std::ifstream>::query(filter, index->file(), offsets_);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
std::sort(offsets_.begin(), offsets_.end());
|
std::sort(offsets_.begin(), offsets_.end(), [](mapnik::detail::node const& n0, mapnik::detail::node const& n1)
|
||||||
|
{return n0.offset != n1.offset ? n0.offset < n1.offset : n0.start < n1.start;});
|
||||||
MAPNIK_LOG_DEBUG(shape) << "shape_index_featureset: Query size=" << offsets_.size();
|
MAPNIK_LOG_DEBUG(shape) << "shape_index_featureset: Query size=" << offsets_.size();
|
||||||
itr_ = offsets_.begin();
|
itr_ = offsets_.begin();
|
||||||
}
|
}
|
||||||
|
@ -83,7 +84,15 @@ feature_ptr shape_index_featureset<filterT>::next()
|
||||||
|
|
||||||
while ( itr_ != offsets_.end())
|
while ( itr_ != offsets_.end())
|
||||||
{
|
{
|
||||||
shape_ptr_->move_to(*itr_++);
|
int offset = itr_->offset;
|
||||||
|
shape_ptr_->move_to(offset);
|
||||||
|
std::vector<std::pair<int,int>> parts;
|
||||||
|
while (itr_->offset == offset && itr_ != offsets_.end())
|
||||||
|
{
|
||||||
|
if (itr_->start!= -1) parts.emplace_back(itr_->start, itr_->end);
|
||||||
|
++itr_;
|
||||||
|
}
|
||||||
|
//std::cerr << "PARTS SIZE=" << parts.size() <<" offset=" << offset << std::endl;
|
||||||
mapnik::value_integer feature_id = shape_ptr_->id();
|
mapnik::value_integer feature_id = shape_ptr_->id();
|
||||||
shape_file::record_type record(shape_ptr_->reclength_ * 2);
|
shape_file::record_type record(shape_ptr_->reclength_ * 2);
|
||||||
shape_ptr_->shp().read_record(record);
|
shape_ptr_->shp().read_record(record);
|
||||||
|
@ -124,7 +133,8 @@ feature_ptr shape_index_featureset<filterT>::next()
|
||||||
{
|
{
|
||||||
shape_io::read_bbox(record, feature_bbox_);
|
shape_io::read_bbox(record, feature_bbox_);
|
||||||
if (!filter_.pass(feature_bbox_)) continue;
|
if (!filter_.pass(feature_bbox_)) continue;
|
||||||
feature->set_geometry(shape_io::read_polyline(record));
|
if (parts.size() < 2) feature->set_geometry(shape_io::read_polyline(record));
|
||||||
|
else feature->set_geometry(shape_io::read_polyline_parts(record, parts));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case shape_io::shape_polygon:
|
case shape_io::shape_polygon:
|
||||||
|
@ -133,7 +143,8 @@ feature_ptr shape_index_featureset<filterT>::next()
|
||||||
{
|
{
|
||||||
shape_io::read_bbox(record, feature_bbox_);
|
shape_io::read_bbox(record, feature_bbox_);
|
||||||
if (!filter_.pass(feature_bbox_)) continue;
|
if (!filter_.pass(feature_bbox_)) continue;
|
||||||
feature->set_geometry(shape_io::read_polygon(record));
|
if (parts.size() < 2) feature->set_geometry(shape_io::read_polygon(record));
|
||||||
|
else feature->set_geometry(shape_io::read_polygon_parts(record, parts));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default :
|
default :
|
||||||
|
|
|
@ -45,6 +45,21 @@ using mapnik::box2d;
|
||||||
using mapnik::feature_ptr;
|
using mapnik::feature_ptr;
|
||||||
using mapnik::context_ptr;
|
using mapnik::context_ptr;
|
||||||
|
|
||||||
|
namespace mapnik { namespace detail
|
||||||
|
{
|
||||||
|
struct node
|
||||||
|
{
|
||||||
|
node() = default;
|
||||||
|
node(int offset_, int start_, int end_)
|
||||||
|
: offset(offset_),
|
||||||
|
start(start_),
|
||||||
|
end(end_) {}
|
||||||
|
int offset;
|
||||||
|
int start;
|
||||||
|
int end;
|
||||||
|
};
|
||||||
|
}} // ns
|
||||||
|
|
||||||
template <typename filterT>
|
template <typename filterT>
|
||||||
class shape_index_featureset : public Featureset
|
class shape_index_featureset : public Featureset
|
||||||
{
|
{
|
||||||
|
@ -63,8 +78,8 @@ private:
|
||||||
context_ptr ctx_;
|
context_ptr ctx_;
|
||||||
std::unique_ptr<shape_io> shape_ptr_;
|
std::unique_ptr<shape_io> shape_ptr_;
|
||||||
const std::unique_ptr<mapnik::transcoder> tr_;
|
const std::unique_ptr<mapnik::transcoder> tr_;
|
||||||
std::vector<int> offsets_;
|
std::vector<mapnik::detail::node> offsets_;
|
||||||
std::vector<int>::iterator itr_;
|
std::vector<mapnik::detail::node>::iterator itr_;
|
||||||
std::vector<int> attr_ids_;
|
std::vector<int> attr_ids_;
|
||||||
mapnik::value_integer row_limit_;
|
mapnik::value_integer row_limit_;
|
||||||
mutable int count_;
|
mutable int count_;
|
||||||
|
|
|
@ -125,6 +125,7 @@ mapnik::geometry::geometry<double> shape_io::read_polyline(shape_file::record_ty
|
||||||
std::for_each(parts.begin(), parts.end(), [&](int & part) { part = record.read_ndr_integer();});
|
std::for_each(parts.begin(), parts.end(), [&](int & part) { part = record.read_ndr_integer();});
|
||||||
int start, end;
|
int start, end;
|
||||||
mapnik::geometry::multi_line_string<double> multi_line;
|
mapnik::geometry::multi_line_string<double> multi_line;
|
||||||
|
multi_line.reserve(num_parts);
|
||||||
for (int k = 0; k < num_parts; ++k)
|
for (int k = 0; k < num_parts; ++k)
|
||||||
{
|
{
|
||||||
start = parts[k];
|
start = parts[k];
|
||||||
|
@ -152,6 +153,34 @@ mapnik::geometry::geometry<double> shape_io::read_polyline(shape_file::record_ty
|
||||||
return geom;
|
return geom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mapnik::geometry::geometry<double> shape_io::read_polyline_parts(shape_file::record_type & record, std::vector<std::pair<int, int>> const& parts)
|
||||||
|
{
|
||||||
|
mapnik::geometry::geometry<double> geom; // default empty
|
||||||
|
int total_num_parts = record.read_ndr_integer();
|
||||||
|
int num_parts = parts.size();
|
||||||
|
mapnik::geometry::multi_line_string<double> multi_line;
|
||||||
|
multi_line.reserve(num_parts);
|
||||||
|
for (int k = 0; k < num_parts; ++k)
|
||||||
|
{
|
||||||
|
int start = parts[k].first;
|
||||||
|
int end = parts[k].second;
|
||||||
|
unsigned pos = 4 + 32 + 8 + 4 * total_num_parts + start * 16;
|
||||||
|
record.set_pos(pos);
|
||||||
|
|
||||||
|
mapnik::geometry::line_string<double> line;
|
||||||
|
line.reserve(end - start);
|
||||||
|
for (int j = start; j < end; ++j)
|
||||||
|
{
|
||||||
|
double x = record.read_double();
|
||||||
|
double y = record.read_double();
|
||||||
|
line.emplace_back(x, y);
|
||||||
|
}
|
||||||
|
multi_line.push_back(std::move(line));
|
||||||
|
}
|
||||||
|
geom = std::move(multi_line);
|
||||||
|
return geom;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
mapnik::geometry::geometry<double> shape_io::read_polygon(shape_file::record_type & record)
|
mapnik::geometry::geometry<double> shape_io::read_polygon(shape_file::record_type & record)
|
||||||
{
|
{
|
||||||
|
@ -207,3 +236,53 @@ mapnik::geometry::geometry<double> shape_io::read_polygon(shape_file::record_typ
|
||||||
mapnik::geometry::correct(geom);
|
mapnik::geometry::correct(geom);
|
||||||
return geom;
|
return geom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mapnik::geometry::geometry<double> shape_io::read_polygon_parts(shape_file::record_type & record, std::vector<std::pair<int,int>> const& parts)
|
||||||
|
{
|
||||||
|
mapnik::geometry::geometry<double> geom; // default empty
|
||||||
|
int total_num_parts = record.read_ndr_integer();
|
||||||
|
mapnik::geometry::polygon<double> poly;
|
||||||
|
mapnik::geometry::multi_polygon<double> multi_poly;
|
||||||
|
int num_parts = parts.size();
|
||||||
|
for (int k = 0; k < num_parts; ++k)
|
||||||
|
{
|
||||||
|
int start = parts[k].first;
|
||||||
|
int end = parts[k].second;
|
||||||
|
unsigned pos = 4 + 32 + 8 + 4 * total_num_parts + start * 16;
|
||||||
|
record.set_pos(pos);
|
||||||
|
mapnik::geometry::linear_ring<double> ring;
|
||||||
|
ring.reserve(end - start);
|
||||||
|
for (int j = start; j < end; ++j)
|
||||||
|
{
|
||||||
|
double x = record.read_double();
|
||||||
|
double y = record.read_double();
|
||||||
|
ring.emplace_back(x, y);
|
||||||
|
}
|
||||||
|
if (k == 0)
|
||||||
|
{
|
||||||
|
poly.set_exterior_ring(std::move(ring));
|
||||||
|
}
|
||||||
|
else if (mapnik::util::is_clockwise(ring))
|
||||||
|
{
|
||||||
|
multi_poly.emplace_back(std::move(poly));
|
||||||
|
poly.interior_rings.clear();
|
||||||
|
poly.set_exterior_ring(std::move(ring));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
poly.add_hole(std::move(ring));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multi_poly.size() > 0) // multi
|
||||||
|
{
|
||||||
|
multi_poly.emplace_back(std::move(poly));
|
||||||
|
geom = std::move(multi_poly);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
geom = std::move(poly);
|
||||||
|
}
|
||||||
|
mapnik::geometry::correct(geom);
|
||||||
|
return geom;
|
||||||
|
}
|
||||||
|
|
|
@ -80,6 +80,8 @@ public:
|
||||||
static void read_bbox(shape_file::record_type & record, mapnik::box2d<double> & bbox);
|
static void read_bbox(shape_file::record_type & record, mapnik::box2d<double> & bbox);
|
||||||
static mapnik::geometry::geometry<double> read_polyline(shape_file::record_type & record);
|
static mapnik::geometry::geometry<double> read_polyline(shape_file::record_type & record);
|
||||||
static mapnik::geometry::geometry<double> read_polygon(shape_file::record_type & record);
|
static mapnik::geometry::geometry<double> read_polygon(shape_file::record_type & record);
|
||||||
|
static mapnik::geometry::geometry<double> read_polyline_parts(shape_file::record_type & record,std::vector<std::pair<int,int>> const& parts);
|
||||||
|
static mapnik::geometry::geometry<double> read_polygon_parts(shape_file::record_type & record, std::vector<std::pair<int,int>> const& parts);
|
||||||
|
|
||||||
shapeType type_;
|
shapeType type_;
|
||||||
shape_file shp_;
|
shape_file shp_;
|
||||||
|
|
|
@ -105,6 +105,11 @@ struct shape_record
|
||||||
pos += n;
|
pos += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_pos(unsigned pos_)
|
||||||
|
{
|
||||||
|
pos = pos_;
|
||||||
|
}
|
||||||
|
|
||||||
int read_ndr_integer()
|
int read_ndr_integer()
|
||||||
{
|
{
|
||||||
std::int32_t val;
|
std::int32_t val;
|
||||||
|
|
57
scripts/appveyor-system-info.ps1
Normal file
57
scripts/appveyor-system-info.ps1
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
$PSVersionTable
|
||||||
|
$PSVersionTable.PSVersion
|
||||||
|
|
||||||
|
$SystemManaged = Get-WmiObject -Class Win32_ComputerSystem | % {$_.AutomaticManagedPagefile}
|
||||||
|
$total_physicalmem = gwmi Win32_ComputerSystem | % {[Math]::round($_.TotalPhysicalMemory/1MB,0)}
|
||||||
|
$physical_mem = get-ciminstance -class 'cim_physicalmemory' | % { $_.Capacity/1024/1024}
|
||||||
|
|
||||||
|
$PF =gwmi Win32_PageFileUsage
|
||||||
|
$PageFileLocation = $PF.Name;
|
||||||
|
$PageFileSize = $PF.AllocatedBaseSize
|
||||||
|
|
||||||
|
Write-Host "physical memory : "$physical_mem
|
||||||
|
Write-Host "total physical memory : "$total_physicalmem
|
||||||
|
Write-Host "page file system managed : "$SystemManaged
|
||||||
|
Write-Host "page file location : "$PageFileLocation
|
||||||
|
Write-Host "page file size : "$PageFileSize
|
||||||
|
Write-Host "InitialSize : "${CurrentPageFile}.InitialSize
|
||||||
|
Write-Host "MaximumSize : "$CurrentPageFile.MaximumSize
|
||||||
|
|
||||||
|
if($env:APPVEYOR -eq "true"){
|
||||||
|
Write-Host !!!!!!! on AppVeyor: changing page file settings !!!!!!!!!!
|
||||||
|
#disable automatically managed page file settings
|
||||||
|
$c = Get-WmiObject Win32_computersystem -EnableAllPrivileges
|
||||||
|
if($c.AutomaticManagedPagefile){
|
||||||
|
Write-Host disabling managed page file settings
|
||||||
|
$c.AutomaticManagedPagefile = $false
|
||||||
|
$c.Put() | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_page_size=18000
|
||||||
|
$CurrentPageFile = Get-WmiObject -Class Win32_PageFileSetting
|
||||||
|
if($CurrentPageFile.InitialSize -ne $new_page_size){
|
||||||
|
Write-Host "setting new page file size to $new_page_size"
|
||||||
|
$CurrentPageFile.InitialSize=$new_page_size
|
||||||
|
$CurrentPageFile.MaximumSize=$new_page_size
|
||||||
|
$CurrentPageFile.Put() | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "new ------------ "
|
||||||
|
Write-Host "system managed:" (Get-WmiObject -Class Win32_ComputerSystem | % {$_.AutomaticManagedPagefile})
|
||||||
|
Write-Host "page file size:" (gwmi Win32_PageFileUsage).AllocatedBaseSize
|
||||||
|
Write-Host "InitialSize: "${CurrentPageFile}.InitialSize
|
||||||
|
Write-Host "MaximumSize: "$CurrentPageFile.MaximumSize
|
||||||
|
} else {
|
||||||
|
Write-Host not on AppVeyor, leaving page file as is
|
||||||
|
}
|
||||||
|
|
||||||
|
#list drives
|
||||||
|
Get-WmiObject -Class Win32_LogicalDisk |
|
||||||
|
Where-Object {$_.DriveType -ne 5} |
|
||||||
|
Sort-Object -Property Name |
|
||||||
|
Select-Object Name, VolumeName, FileSystem, Description, VolumeDirty, `
|
||||||
|
@{"Label"="DiskSize(GB)";"Expression"={"{0:N}" -f ($_.Size/1GB) -as [float]}}, `
|
||||||
|
@{"Label"="FreeSpace(GB)";"Expression"={"{0:N}" -f ($_.FreeSpace/1GB) -as [float]}}, `
|
||||||
|
@{"Label"="%Free";"Expression"={"{0:N}" -f ($_.FreeSpace/$_.Size*100) -as [float]}} |
|
||||||
|
Format-Table -AutoSize
|
||||||
|
|
|
@ -5,8 +5,9 @@ SET EL=0
|
||||||
ECHO =========== %~f0 ===========
|
ECHO =========== %~f0 ===========
|
||||||
|
|
||||||
ECHO NUMBER_OF_PROCESSORS^: %NUMBER_OF_PROCESSORS%
|
ECHO NUMBER_OF_PROCESSORS^: %NUMBER_OF_PROCESSORS%
|
||||||
ECHO RAM [MB]^:
|
powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force
|
||||||
powershell "get-ciminstance -class 'cim_physicalmemory' | %% { $_.Capacity/1024/1024}"
|
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
powershell .\scripts\appveyor-system-info.ps1
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
|
||||||
::only build on AppVeyor, if explicitly stated
|
::only build on AppVeyor, if explicitly stated
|
||||||
|
@ -27,27 +28,6 @@ ECHO ========
|
||||||
SET PATH=C:\Python27;%PATH%
|
SET PATH=C:\Python27;%PATH%
|
||||||
SET PATH=C:\Program Files\7-Zip;%PATH%
|
SET PATH=C:\Program Files\7-Zip;%PATH%
|
||||||
|
|
||||||
:: *nix style find command comes with git:
|
|
||||||
ECHO checking for unix style 'find'
|
|
||||||
find %USERPROFILE% -name "*.blabla"
|
|
||||||
IF %ERRORLEVEL% EQU 0 GOTO NIX_FIND_FOUND
|
|
||||||
|
|
||||||
IF DEFINED GIT_INSTALL_ROOT SET TEMP_GIT_DIR=%GIT_INSTALL_ROOT%&& GOTO TEST_FIND_AGAIN
|
|
||||||
IF EXIST "C:\Program Files (x86)\Git" SET TEMP_GIT_DIR=C:\Program Files (x86)\Git&& GOTO TEST_FIND_AGAIN
|
|
||||||
IF EXIST "C:\Program Files\Git" SET TEMP_GIT_DIR=C:\Program Files\Git&& GOTO TEST_FIND_AGAIN
|
|
||||||
|
|
||||||
:TEST_FIND_AGAIN
|
|
||||||
SET PATH=%TEMP_GIT_DIR%\bin;%PATH%
|
|
||||||
SET PATH=%TEMP_GIT_DIR%\usr\bin;%PATH%
|
|
||||||
ECHO %PATH%
|
|
||||||
::check again
|
|
||||||
find %USERPROFILE% -name "*.blabla"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 (ECHO unix style find not found && GOTO ERROR)
|
|
||||||
|
|
||||||
|
|
||||||
:NIX_FIND_FOUND
|
|
||||||
ECHO find was found
|
|
||||||
|
|
||||||
::cloning mapnik-gyp
|
::cloning mapnik-gyp
|
||||||
if EXIST mapnik-gyp ECHO mapnik-gyp already cloned && GOTO MAPNIK_GYP_ALREADY_HERE
|
if EXIST mapnik-gyp ECHO mapnik-gyp already cloned && GOTO MAPNIK_GYP_ALREADY_HERE
|
||||||
CALL git clone https://github.com/mapnik/mapnik-gyp.git
|
CALL git clone https://github.com/mapnik/mapnik-gyp.git
|
||||||
|
|
|
@ -8,14 +8,45 @@ SET APPVEYOR_REPO_COMMIT_MESSAGE=this is a [build appveyor] test
|
||||||
SET APPVEYOR=true
|
SET APPVEYOR=true
|
||||||
::comment this to get complete AppVeyor behaviour
|
::comment this to get complete AppVeyor behaviour
|
||||||
SET LOCAL_BUILD_DONT_SKIP_TESTS=true
|
SET LOCAL_BUILD_DONT_SKIP_TESTS=true
|
||||||
|
|
||||||
SET MAPNIK_GIT=3.0.5
|
|
||||||
SET BOOST_VERSION=59
|
|
||||||
SET FASTBUILD=1
|
SET FASTBUILD=1
|
||||||
|
|
||||||
|
FOR /F "tokens=1 usebackq" %%i in (`powershell .\scripts\parse-appveyor-yml.ps1`) DO SET BOOST_VERSION=%%i
|
||||||
|
ECHO BOOST_VERSION found in appveyor.yml^: %BOOST_VERSION%
|
||||||
|
IF "%BOOST_VERSION%"=="0" ECHO BOOST_VERSION not valid && SET ERRORLEVEL=1 && GOTO ERROR
|
||||||
|
|
||||||
|
|
||||||
|
:: OVERRIDE PARAMETERS >>>>>>>>
|
||||||
|
:NEXT-ARG
|
||||||
|
|
||||||
|
IF '%1'=='' GOTO ARGS-DONE
|
||||||
|
ECHO setting %1
|
||||||
|
SET %1
|
||||||
|
SHIFT
|
||||||
|
GOTO NEXT-ARG
|
||||||
|
|
||||||
|
:ARGS-DONE
|
||||||
|
::<<<<< OVERRIDE PARAMETERS
|
||||||
|
|
||||||
|
|
||||||
SET configuration=Release
|
SET configuration=Release
|
||||||
SET msvs_toolset=14
|
SET msvs_toolset=14
|
||||||
SET platform=x64
|
SET platform=x64
|
||||||
SET APPVEYOR_BUILD_FOLDER=%CD%
|
SET APPVEYOR_BUILD_FOLDER=%CD%
|
||||||
|
|
||||||
|
IF NOT EXIST bindings\python git clone https://github.com/mapnik/python-mapnik.git bindings/python
|
||||||
|
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
|
||||||
|
CD bindings\python & IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
git fetch & IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
git pull & IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
CD ..\.. & IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
|
||||||
|
ECHO pulling test data
|
||||||
|
CALL git submodule update --init
|
||||||
|
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
ECHO pulling test data, DONE
|
||||||
|
|
||||||
|
SET TIME_START_LOCAL_BUILD=%TIME%
|
||||||
CALL scripts\build-appveyor.bat
|
CALL scripts\build-appveyor.bat
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
|
||||||
|
@ -28,5 +59,7 @@ SET EL=%ERRORLEVEL%
|
||||||
|
|
||||||
:DONE
|
:DONE
|
||||||
ECHO =========== DONE %~f0 ===========
|
ECHO =========== DONE %~f0 ===========
|
||||||
|
ECHO build started^: %TIME_START_LOCAL_BUILD%
|
||||||
|
ECHO build finished^: %TIME%
|
||||||
|
|
||||||
EXIT /b %EL%
|
EXIT /b %EL%
|
||||||
|
|
7
scripts/parse-appveyor-yml.ps1
Normal file
7
scripts/parse-appveyor-yml.ps1
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
$boost_version='0'
|
||||||
|
Get-Content .\appveyor.yml |
|
||||||
|
foreach {
|
||||||
|
if ($_ -match "BOOST_VERSION: "){ $boost_version = $_.split()[-1] }
|
||||||
|
}
|
||||||
|
Write-Host $boost_version
|
9
scripts/time-header
Executable file
9
scripts/time-header
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
CXXFLAGS="$(./utils/mapnik-config/mapnik-config --cflags)"
|
||||||
|
CXX="$(./utils/mapnik-config/mapnik-config --cxx)"
|
||||||
|
echo "Time taken to compile '$(basename $1)':"
|
||||||
|
time ${CXX} $1 -I./test -I./deps/agg/include -Ideps -I./include $CXXFLAGS -o /tmp/header.out
|
|
@ -36,7 +36,29 @@ namespace mapnik {
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
|
|
||||||
bool parse_dasharray(std::string const& value, std::vector<double>& dasharray)
|
namespace {
|
||||||
|
inline bool setup_dashes(std::vector<double> & buf, dash_array & dash)
|
||||||
|
{
|
||||||
|
if (buf.empty()) return false;
|
||||||
|
size_t size = buf.size();
|
||||||
|
if (size % 2 == 1)
|
||||||
|
{
|
||||||
|
buf.insert(buf.end(),buf.begin(),buf.end());
|
||||||
|
}
|
||||||
|
std::vector<double>::const_iterator pos = buf.begin();
|
||||||
|
while (pos != buf.end())
|
||||||
|
{
|
||||||
|
if (*pos > 0.0 || *(pos+1) > 0.0) // avoid both dash and gap eq 0.0
|
||||||
|
{
|
||||||
|
dash.emplace_back(*pos,*(pos + 1));
|
||||||
|
}
|
||||||
|
pos +=2;
|
||||||
|
}
|
||||||
|
return !buf.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parse_dasharray(std::string const& value, dash_array & dash)
|
||||||
{
|
{
|
||||||
using namespace boost::spirit;
|
using namespace boost::spirit;
|
||||||
qi::double_type double_;
|
qi::double_type double_;
|
||||||
|
@ -49,18 +71,19 @@ bool parse_dasharray(std::string const& value, std::vector<double>& dasharray)
|
||||||
// dasharray ::= (length | percentage) (comma-wsp dasharray)?
|
// dasharray ::= (length | percentage) (comma-wsp dasharray)?
|
||||||
// no support for 'percentage' as viewport is unknown at load_map
|
// no support for 'percentage' as viewport is unknown at load_map
|
||||||
//
|
//
|
||||||
|
std::vector<double> buf;
|
||||||
auto first = value.begin();
|
auto first = value.begin();
|
||||||
auto last = value.end();
|
auto last = value.end();
|
||||||
bool r = qi::phrase_parse(first, last,
|
bool r = qi::phrase_parse(first, last,
|
||||||
(double_[boost::phoenix::push_back(boost::phoenix::ref(dasharray), _1)] %
|
(double_[boost::phoenix::push_back(boost::phoenix::ref(buf), _1)] %
|
||||||
no_skip[char_(", ")]
|
no_skip[char_(", ")]
|
||||||
| lit("none")),
|
| lit("none")),
|
||||||
space);
|
space);
|
||||||
if (first != last)
|
if (r && first == last)
|
||||||
{
|
{
|
||||||
return false;
|
return setup_dashes(buf, dash);
|
||||||
}
|
}
|
||||||
return r;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace util
|
} // end namespace util
|
||||||
|
|
|
@ -31,6 +31,7 @@ template MAPNIK_DECL mapnik::box2d<double> envelope(mapnik::base_symbolizer_help
|
||||||
template MAPNIK_DECL mapnik::box2d<double> envelope(geometry_empty const& geom);
|
template MAPNIK_DECL mapnik::box2d<double> envelope(geometry_empty const& geom);
|
||||||
template MAPNIK_DECL mapnik::box2d<double> envelope(point<double> const& geom);
|
template MAPNIK_DECL mapnik::box2d<double> envelope(point<double> const& geom);
|
||||||
template MAPNIK_DECL mapnik::box2d<double> envelope(line_string<double> const& geom);
|
template MAPNIK_DECL mapnik::box2d<double> envelope(line_string<double> const& geom);
|
||||||
|
template MAPNIK_DECL mapnik::box2d<double> envelope(linear_ring<double> const& geom);
|
||||||
template MAPNIK_DECL mapnik::box2d<double> envelope(polygon<double> const& geom);
|
template MAPNIK_DECL mapnik::box2d<double> envelope(polygon<double> const& geom);
|
||||||
template MAPNIK_DECL mapnik::box2d<double> envelope(multi_point<double> const& geom);
|
template MAPNIK_DECL mapnik::box2d<double> envelope(multi_point<double> const& geom);
|
||||||
template MAPNIK_DECL mapnik::box2d<double> envelope(multi_line_string<double> const& geom);
|
template MAPNIK_DECL mapnik::box2d<double> envelope(multi_line_string<double> const& geom);
|
||||||
|
@ -40,6 +41,7 @@ template MAPNIK_DECL mapnik::box2d<double> envelope(geometry_collection<double>
|
||||||
template MAPNIK_DECL mapnik::box2d<double> envelope(geometry<std::int64_t> const& geom);
|
template MAPNIK_DECL mapnik::box2d<double> envelope(geometry<std::int64_t> const& geom);
|
||||||
template MAPNIK_DECL mapnik::box2d<double> envelope(point<std::int64_t> const& geom);
|
template MAPNIK_DECL mapnik::box2d<double> envelope(point<std::int64_t> const& geom);
|
||||||
template MAPNIK_DECL mapnik::box2d<double> envelope(line_string<std::int64_t> const& geom);
|
template MAPNIK_DECL mapnik::box2d<double> envelope(line_string<std::int64_t> const& geom);
|
||||||
|
template MAPNIK_DECL mapnik::box2d<double> envelope(linear_ring<std::int64_t> const& geom);
|
||||||
template MAPNIK_DECL mapnik::box2d<double> envelope(polygon<std::int64_t> const& geom);
|
template MAPNIK_DECL mapnik::box2d<double> envelope(polygon<std::int64_t> const& geom);
|
||||||
template MAPNIK_DECL mapnik::box2d<double> envelope(multi_point<std::int64_t> const& geom);
|
template MAPNIK_DECL mapnik::box2d<double> envelope(multi_point<std::int64_t> const& geom);
|
||||||
template MAPNIK_DECL mapnik::box2d<double> envelope(multi_line_string<std::int64_t> const& geom);
|
template MAPNIK_DECL mapnik::box2d<double> envelope(multi_line_string<std::int64_t> const& geom);
|
||||||
|
|
|
@ -44,9 +44,9 @@ namespace mapnik { namespace svg {
|
||||||
svg_path_grammar<iterator_type,skip_type,PathType> g(p);
|
svg_path_grammar<iterator_type,skip_type,PathType> g(p);
|
||||||
iterator_type first = wkt;
|
iterator_type first = wkt;
|
||||||
iterator_type last = wkt + std::strlen(wkt);
|
iterator_type last = wkt + std::strlen(wkt);
|
||||||
return qi::phrase_parse(first, last, g, skip_type());
|
bool status = qi::phrase_parse(first, last, g, skip_type());
|
||||||
|
return (status && (first == last));
|
||||||
}
|
}
|
||||||
|
|
||||||
template bool parse_path<svg_converter_type>(const char*, svg_converter_type&);
|
template bool parse_path<svg_converter_type>(const char*, svg_converter_type&);
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -598,13 +598,9 @@ image_any tiff_reader<T>::read(unsigned x, unsigned y, unsigned width, unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void tiff_reader<T>::read_generic(std::size_t, std::size_t, image_rgba8& image)
|
void tiff_reader<T>::read_generic(std::size_t, std::size_t, image_rgba8&)
|
||||||
{
|
{
|
||||||
TIFF* tif = open(stream_);
|
throw std::runtime_error("tiff_reader: TODO - tiff is not stripped or tiled");
|
||||||
if (tif)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("tiff_reader: TODO - tiff is not stripped or tiled");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
2968
test/catch.hpp
2968
test/catch.hpp
File diff suppressed because it is too large
Load diff
|
@ -1 +1 @@
|
||||||
Subproject commit 972b039bfc5a5e189f68852c22df717a30c1adf7
|
Subproject commit af88691110b39c75f97140ab4b608b258e53ad51
|
|
@ -68,6 +68,10 @@ mapnik::datasource_ptr get_csv_ds(std::string const& file_name, bool strict = tr
|
||||||
mapnik::parameters params;
|
mapnik::parameters params;
|
||||||
params["type"] = std::string("csv");
|
params["type"] = std::string("csv");
|
||||||
params["file"] = file_name;
|
params["file"] = file_name;
|
||||||
|
if (!base.empty())
|
||||||
|
{
|
||||||
|
params["base"] = base;
|
||||||
|
}
|
||||||
params["strict"] = mapnik::value_bool(strict);
|
params["strict"] = mapnik::value_bool(strict);
|
||||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||||
// require a non-null pointer returned
|
// require a non-null pointer returned
|
||||||
|
@ -80,7 +84,7 @@ int create_disk_index(std::string const& filename, bool silent = true)
|
||||||
std::string cmd;
|
std::string cmd;
|
||||||
if (std::getenv("DYLD_LIBRARY_PATH") != nullptr)
|
if (std::getenv("DYLD_LIBRARY_PATH") != nullptr)
|
||||||
{
|
{
|
||||||
cmd += std::string("export DYLD_LIBRARY_PATH=") + std::getenv("DYLD_LIBRARY_PATH") + " && ";
|
cmd += std::string("DYLD_LIBRARY_PATH=") + std::getenv("DYLD_LIBRARY_PATH") + " ";
|
||||||
}
|
}
|
||||||
cmd += "mapnik-index " + filename;
|
cmd += "mapnik-index " + filename;
|
||||||
if (silent)
|
if (silent)
|
||||||
|
@ -288,7 +292,7 @@ TEST_CASE("csv") {
|
||||||
INFO(ret_posix);
|
INFO(ret_posix);
|
||||||
CHECK(mapnik::util::exists(filepath + ".index"));
|
CHECK(mapnik::util::exists(filepath + ".index"));
|
||||||
}
|
}
|
||||||
auto ds = get_csv_ds(filepath,true,base);
|
auto ds = get_csv_ds(filename,true,base);
|
||||||
CHECK(ds->type() == mapnik::datasource::datasource_t::Vector);
|
CHECK(ds->type() == mapnik::datasource::datasource_t::Vector);
|
||||||
auto fields = ds->get_descriptor().get_descriptors();
|
auto fields = ds->get_descriptor().get_descriptors();
|
||||||
require_field_names(fields, {"Precinct", "Phone", "Address", "City", "geo_longitude", "geo_latitude", "geo_accuracy"});
|
require_field_names(fields, {"Precinct", "Phone", "Address", "City", "geo_longitude", "geo_latitude", "geo_accuracy"});
|
||||||
|
|
|
@ -66,7 +66,7 @@ int create_disk_index(std::string const& filename, bool silent = true)
|
||||||
std::string cmd;
|
std::string cmd;
|
||||||
if (std::getenv("DYLD_LIBRARY_PATH") != nullptr)
|
if (std::getenv("DYLD_LIBRARY_PATH") != nullptr)
|
||||||
{
|
{
|
||||||
cmd += std::string("export DYLD_LIBRARY_PATH=") + std::getenv("DYLD_LIBRARY_PATH") + " && ";
|
cmd += std::string("DYLD_LIBRARY_PATH=") + std::getenv("DYLD_LIBRARY_PATH") + " ";
|
||||||
}
|
}
|
||||||
cmd += "mapnik-index " + filename;
|
cmd += "mapnik-index " + filename;
|
||||||
if (silent)
|
if (silent)
|
||||||
|
|
|
@ -35,263 +35,260 @@ clang++ -o test-postgis -g -I./test/ test/unit/run.cpp test/unit/datasource/post
|
||||||
|
|
||||||
#include <boost/optional/optional_io.hpp>
|
#include <boost/optional/optional_io.hpp>
|
||||||
|
|
||||||
namespace postgistest {
|
int run(std::string const& command, bool okay_to_fail = false)
|
||||||
|
{
|
||||||
int run(std::string const& command, bool okay_to_fail = false)
|
std::string cmd;
|
||||||
|
if (std::getenv("DYLD_LIBRARY_PATH") != nullptr)
|
||||||
|
{
|
||||||
|
cmd += std::string("DYLD_LIBRARY_PATH=") + std::getenv("DYLD_LIBRARY_PATH") + " && ";
|
||||||
|
}
|
||||||
|
cmd += command;
|
||||||
|
// silence output unless MAPNIK_TEST_DEBUG is defined
|
||||||
|
if (std::getenv("MAPNIK_TEST_DEBUG") == nullptr)
|
||||||
{
|
{
|
||||||
std::string cmd;
|
|
||||||
if (std::getenv("DYLD_LIBRARY_PATH") != nullptr)
|
|
||||||
{
|
|
||||||
cmd += std::string("export DYLD_LIBRARY_PATH=") + std::getenv("DYLD_LIBRARY_PATH") + " && ";
|
|
||||||
}
|
|
||||||
cmd += command;
|
|
||||||
// silence output unless MAPNIK_TEST_DEBUG is defined
|
|
||||||
if (std::getenv("MAPNIK_TEST_DEBUG") == nullptr)
|
|
||||||
{
|
|
||||||
#ifndef _WINDOWS
|
#ifndef _WINDOWS
|
||||||
cmd += " 2>/dev/null";
|
cmd += " 2>/dev/null";
|
||||||
#else
|
#else
|
||||||
cmd += " 2> nul";
|
cmd += " 2> nul";
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::clog << "Running " << cmd << "\n";
|
|
||||||
}
|
|
||||||
bool worked = (std::system(cmd.c_str()) == 0);
|
|
||||||
if (okay_to_fail == true) return true;
|
|
||||||
return worked;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
std::string dbname("mapnik-tmp-postgis-test-db");
|
{
|
||||||
|
std::clog << "Running " << cmd << "\n";
|
||||||
TEST_CASE("postgis") {
|
|
||||||
|
|
||||||
SECTION("Postgis data initialization")
|
|
||||||
{
|
|
||||||
//don't add 'true' here, to get error message, when drop fails. If it works nothing is output
|
|
||||||
REQUIRE(run("dropdb --if-exists " + dbname));
|
|
||||||
REQUIRE(run("createdb -T template_postgis " + dbname));
|
|
||||||
//REQUIRE(run("createdb " + dbname));
|
|
||||||
// Breaks when raster support is missing (unfortunately this is common)
|
|
||||||
//REQUIRE(run("psql -c 'CREATE EXTENSION postgis;' " + dbname, true));
|
|
||||||
REQUIRE(run("psql -q -f ./test/data/sql/postgis-create-db-and-tables.sql " + dbname));
|
|
||||||
}
|
|
||||||
|
|
||||||
mapnik::parameters params;
|
|
||||||
params["type"] = "postgis";
|
|
||||||
params["dbname"] = dbname;
|
|
||||||
|
|
||||||
SECTION("Postgis should throw without 'table' parameter")
|
|
||||||
{
|
|
||||||
CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Postgis should throw with 'max_async_connection' greater than 'max_size'")
|
|
||||||
{
|
|
||||||
params["table"] = "test";
|
|
||||||
params["max_async_connection"] = "2";
|
|
||||||
params["max_size"] = "1";
|
|
||||||
CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Postgis should throw with invalid metadata query")
|
|
||||||
{
|
|
||||||
params["table"] = "does_not_exist";
|
|
||||||
CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Postgis should throw with invalid key field")
|
|
||||||
{
|
|
||||||
params["table"] = "test_invalid_id";
|
|
||||||
params["key_field"] = "id";
|
|
||||||
CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Postgis should throw with multicolumn primary key")
|
|
||||||
{
|
|
||||||
params["table"] = "test_invalid_multi_col_pk";
|
|
||||||
params["autodetect_key_field"] = "true";
|
|
||||||
CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Postgis should throw without geom column")
|
|
||||||
{
|
|
||||||
params["table"] = "test_no_geom_col";
|
|
||||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
|
||||||
REQUIRE(ds != nullptr);
|
|
||||||
CHECK_THROWS(all_features(ds));
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Postgis should throw with invalid credentials")
|
|
||||||
{
|
|
||||||
params["table"] = "test";
|
|
||||||
params["user"] = "not_a_valid_user";
|
|
||||||
params["password"] = "not_a_valid_pwd";
|
|
||||||
CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Postgis initialize dataset with persist_connection, schema, extent, geometry field, autodectect key field, simplify_geometries, row_limit")
|
|
||||||
{
|
|
||||||
params["persist_connection"] = "false";
|
|
||||||
params["table"] = "public.test";
|
|
||||||
params["geometry_field"] = "geom";
|
|
||||||
params["autodetect_key_field"] = "true";
|
|
||||||
params["extent"] = "-1 -1, -1 2, 4 3, 3 -1, -1 -1";
|
|
||||||
params["simplify_geometries"] = "true";
|
|
||||||
params["row_limit"] = "1";
|
|
||||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Postgis dataset geometry type")
|
|
||||||
{
|
|
||||||
params["table"] = "(SELECT * FROM test WHERE gid=1) as data";
|
|
||||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
|
||||||
REQUIRE(ds != nullptr);
|
|
||||||
CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Postgis query field names")
|
|
||||||
{
|
|
||||||
params["table"] = "test";
|
|
||||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
|
||||||
REQUIRE(ds != nullptr);
|
|
||||||
REQUIRE(ds->type() == mapnik::datasource::datasource_t::Vector);
|
|
||||||
auto fields = ds->get_descriptor().get_descriptors();
|
|
||||||
require_field_names(fields, { "gid", "colbigint", "col_text", "col-char", "col+bool", "colnumeric", "colsmallint", "colfloat4", "colfloat8", "colcharacter" });
|
|
||||||
require_field_types(fields, { mapnik::Integer, mapnik::Integer, mapnik::String, mapnik::String, mapnik::Boolean, mapnik::Double, mapnik::Integer, mapnik::Double, mapnik::Double, mapnik::String });
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Postgis iterate features")
|
|
||||||
{
|
|
||||||
params["table"] = "test";
|
|
||||||
params["key_field"] = "gid";
|
|
||||||
params["max_async_connection"] = "2";
|
|
||||||
//params["cursor_size"] = "2";
|
|
||||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
|
||||||
REQUIRE(ds != nullptr);
|
|
||||||
|
|
||||||
auto featureset = ds->features_at_point(mapnik::coord2d(1, 1));
|
|
||||||
mapnik::feature_ptr feature;
|
|
||||||
while ((bool(feature = featureset->next()))) {
|
|
||||||
REQUIRE(feature->get(2).to_string() == feature->get("col_text").to_string());
|
|
||||||
REQUIRE(feature->get(4).to_bool() == feature->get("col+bool").to_bool());
|
|
||||||
REQUIRE(feature->get(5).to_double() == feature->get("colnumeric").to_double());
|
|
||||||
REQUIRE(feature->get(5).to_string() == feature->get("colnumeric").to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
featureset = all_features(ds);
|
|
||||||
feature = featureset->next();
|
|
||||||
//deactivate char tests for now: not yet implemented.
|
|
||||||
//add at postgis_datasource.cpp:423
|
|
||||||
//case 18: // char
|
|
||||||
//REQUIRE("A" == feature->get("col-char").to_string());
|
|
||||||
feature = featureset->next();
|
|
||||||
//REQUIRE("B" == feature->get("col-char").to_string());
|
|
||||||
feature = featureset->next();
|
|
||||||
REQUIRE(false == feature->get("col+bool").to_bool());
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Postgis cursorresultest")
|
|
||||||
{
|
|
||||||
params["table"] = "(SELECT * FROM test) as data";
|
|
||||||
params["cursor_size"] = "2";
|
|
||||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
|
||||||
REQUIRE(ds != nullptr);
|
|
||||||
auto featureset = all_features(ds);
|
|
||||||
CHECK(count_features(featureset) == 8);
|
|
||||||
|
|
||||||
featureset = all_features(ds);
|
|
||||||
mapnik::feature_ptr feature;
|
|
||||||
while (bool(feature = featureset->next())) {
|
|
||||||
CHECK(feature->size() == 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
featureset = all_features(ds);
|
|
||||||
require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::Point);
|
|
||||||
require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::Point);
|
|
||||||
require_geometry(featureset->next(), 2, mapnik::geometry::geometry_types::MultiPoint);
|
|
||||||
require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::LineString);
|
|
||||||
require_geometry(featureset->next(), 2, mapnik::geometry::geometry_types::MultiLineString);
|
|
||||||
require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::Polygon);
|
|
||||||
require_geometry(featureset->next(), 2, mapnik::geometry::geometry_types::MultiPolygon);
|
|
||||||
require_geometry(featureset->next(), 3, mapnik::geometry::geometry_types::GeometryCollection);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Postgis bbox query")
|
|
||||||
{
|
|
||||||
params["table"] = "(SELECT * FROM public.test) as data WHERE geom && !bbox!";
|
|
||||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
|
||||||
REQUIRE(ds != nullptr);
|
|
||||||
mapnik::box2d<double> ext = ds->envelope();
|
|
||||||
CAPTURE(ext);
|
|
||||||
INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
|
|
||||||
REQUIRE(ext.minx() == -2);
|
|
||||||
REQUIRE(ext.miny() == -2);
|
|
||||||
REQUIRE(ext.maxx() == 5);
|
|
||||||
REQUIRE(ext.maxy() == 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Postgis query extent: full dataset")
|
|
||||||
{
|
|
||||||
//include schema to increase coverage
|
|
||||||
params["table"] = "(SELECT * FROM public.test) as data";
|
|
||||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
|
||||||
REQUIRE(ds != nullptr);
|
|
||||||
mapnik::box2d<double> ext = ds->envelope();
|
|
||||||
CAPTURE(ext);
|
|
||||||
INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
|
|
||||||
REQUIRE(ext.minx() == -2);
|
|
||||||
REQUIRE(ext.miny() == -2);
|
|
||||||
REQUIRE(ext.maxx() == 5);
|
|
||||||
REQUIRE(ext.maxy() == 4);
|
|
||||||
}
|
|
||||||
/* deactivated for merging: still investigating a proper fix
|
|
||||||
SECTION("Postgis query extent from subquery")
|
|
||||||
{
|
|
||||||
params["table"] = "(SELECT * FROM test where gid=4) as data";
|
|
||||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
|
||||||
REQUIRE(ds != nullptr);
|
|
||||||
mapnik::box2d<double> ext = ds->envelope();
|
|
||||||
CAPTURE(ext);
|
|
||||||
INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
|
|
||||||
REQUIRE(ext.minx() == 0);
|
|
||||||
REQUIRE(ext.miny() == 0);
|
|
||||||
REQUIRE(ext.maxx() == 1);
|
|
||||||
REQUIRE(ext.maxy() == 2);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
SECTION("Postgis query extent: from subquery with 'extent_from_subquery=true'")
|
|
||||||
{
|
|
||||||
params["table"] = "(SELECT * FROM test where gid=4) as data";
|
|
||||||
params["extent_from_subquery"] = "true";
|
|
||||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
|
||||||
REQUIRE(ds != nullptr);
|
|
||||||
mapnik::box2d<double> ext = ds->envelope();
|
|
||||||
CAPTURE(ext);
|
|
||||||
INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
|
|
||||||
REQUIRE(ext.minx() == 0);
|
|
||||||
REQUIRE(ext.miny() == 0);
|
|
||||||
REQUIRE(ext.maxx() == 1);
|
|
||||||
REQUIRE(ext.maxy() == 2);
|
|
||||||
}
|
|
||||||
/* deactivated for merging: still investigating a proper fix
|
|
||||||
SECTION("Postgis query extent: subset with 'extent_from_subquery=true' and 'scale_denominator'")
|
|
||||||
{
|
|
||||||
// !!!! postgis-vt-util::z() returns 'null' when 'scale_denominator > 600000000'
|
|
||||||
// https://github.com/mapbox/postgis-vt-util/blob/559f073877696a6bfea41baf3e1065f9cf4d18d1/postgis-vt-util.sql#L615-L617
|
|
||||||
params["table"] = "(SELECT * FROM test where gid=4 AND z(!scale_denominator!) BETWEEN 0 AND 22) as data";
|
|
||||||
params["extent_from_subquery"] = "true";
|
|
||||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
|
||||||
REQUIRE(ds != nullptr);
|
|
||||||
mapnik::box2d<double> ext = ds->envelope();
|
|
||||||
CAPTURE(ext);
|
|
||||||
INFO("" << std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
|
|
||||||
REQUIRE(ext.minx() == 0);
|
|
||||||
REQUIRE(ext.miny() == 0);
|
|
||||||
REQUIRE(ext.maxx() == 1);
|
|
||||||
REQUIRE(ext.maxy() == 2);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
bool worked = (std::system(cmd.c_str()) == 0);
|
||||||
|
if (okay_to_fail == true) return true;
|
||||||
|
return worked;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string dbname("mapnik-tmp-postgis-test-db");
|
||||||
|
|
||||||
|
TEST_CASE("postgis") {
|
||||||
|
|
||||||
|
SECTION("Postgis data initialization")
|
||||||
|
{
|
||||||
|
//don't add 'true' here, to get error message, when drop fails. If it works nothing is output
|
||||||
|
REQUIRE(run("dropdb --if-exists " + dbname));
|
||||||
|
REQUIRE(run("createdb -T template_postgis " + dbname));
|
||||||
|
//REQUIRE(run("createdb " + dbname));
|
||||||
|
// Breaks when raster support is missing (unfortunately this is common)
|
||||||
|
//REQUIRE(run("psql -c 'CREATE EXTENSION postgis;' " + dbname, true));
|
||||||
|
REQUIRE(run("psql -q -f ./test/data/sql/postgis-create-db-and-tables.sql " + dbname));
|
||||||
|
}
|
||||||
|
|
||||||
|
mapnik::parameters params;
|
||||||
|
params["type"] = "postgis";
|
||||||
|
params["dbname"] = dbname;
|
||||||
|
|
||||||
|
SECTION("Postgis should throw without 'table' parameter")
|
||||||
|
{
|
||||||
|
CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Postgis should throw with 'max_async_connection' greater than 'max_size'")
|
||||||
|
{
|
||||||
|
params["table"] = "test";
|
||||||
|
params["max_async_connection"] = "2";
|
||||||
|
params["max_size"] = "1";
|
||||||
|
CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Postgis should throw with invalid metadata query")
|
||||||
|
{
|
||||||
|
params["table"] = "does_not_exist";
|
||||||
|
CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Postgis should throw with invalid key field")
|
||||||
|
{
|
||||||
|
params["table"] = "test_invalid_id";
|
||||||
|
params["key_field"] = "id";
|
||||||
|
CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Postgis should throw with multicolumn primary key")
|
||||||
|
{
|
||||||
|
params["table"] = "test_invalid_multi_col_pk";
|
||||||
|
params["autodetect_key_field"] = "true";
|
||||||
|
CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Postgis should throw without geom column")
|
||||||
|
{
|
||||||
|
params["table"] = "test_no_geom_col";
|
||||||
|
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||||
|
REQUIRE(ds != nullptr);
|
||||||
|
CHECK_THROWS(all_features(ds));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Postgis should throw with invalid credentials")
|
||||||
|
{
|
||||||
|
params["table"] = "test";
|
||||||
|
params["user"] = "not_a_valid_user";
|
||||||
|
params["password"] = "not_a_valid_pwd";
|
||||||
|
CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Postgis initialize dataset with persist_connection, schema, extent, geometry field, autodectect key field, simplify_geometries, row_limit")
|
||||||
|
{
|
||||||
|
params["persist_connection"] = "false";
|
||||||
|
params["table"] = "public.test";
|
||||||
|
params["geometry_field"] = "geom";
|
||||||
|
params["autodetect_key_field"] = "true";
|
||||||
|
params["extent"] = "-1 -1, -1 2, 4 3, 3 -1, -1 -1";
|
||||||
|
params["simplify_geometries"] = "true";
|
||||||
|
params["row_limit"] = "1";
|
||||||
|
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Postgis dataset geometry type")
|
||||||
|
{
|
||||||
|
params["table"] = "(SELECT * FROM test WHERE gid=1) as data";
|
||||||
|
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||||
|
REQUIRE(ds != nullptr);
|
||||||
|
CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Postgis query field names")
|
||||||
|
{
|
||||||
|
params["table"] = "test";
|
||||||
|
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||||
|
REQUIRE(ds != nullptr);
|
||||||
|
REQUIRE(ds->type() == mapnik::datasource::datasource_t::Vector);
|
||||||
|
auto fields = ds->get_descriptor().get_descriptors();
|
||||||
|
require_field_names(fields, { "gid", "colbigint", "col_text", "col-char", "col+bool", "colnumeric", "colsmallint", "colfloat4", "colfloat8", "colcharacter" });
|
||||||
|
require_field_types(fields, { mapnik::Integer, mapnik::Integer, mapnik::String, mapnik::String, mapnik::Boolean, mapnik::Double, mapnik::Integer, mapnik::Double, mapnik::Double, mapnik::String });
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Postgis iterate features")
|
||||||
|
{
|
||||||
|
params["table"] = "test";
|
||||||
|
params["key_field"] = "gid";
|
||||||
|
params["max_async_connection"] = "2";
|
||||||
|
//params["cursor_size"] = "2";
|
||||||
|
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||||
|
REQUIRE(ds != nullptr);
|
||||||
|
|
||||||
|
auto featureset = ds->features_at_point(mapnik::coord2d(1, 1));
|
||||||
|
mapnik::feature_ptr feature;
|
||||||
|
while ((bool(feature = featureset->next()))) {
|
||||||
|
REQUIRE(feature->get(2).to_string() == feature->get("col_text").to_string());
|
||||||
|
REQUIRE(feature->get(4).to_bool() == feature->get("col+bool").to_bool());
|
||||||
|
REQUIRE(feature->get(5).to_double() == feature->get("colnumeric").to_double());
|
||||||
|
REQUIRE(feature->get(5).to_string() == feature->get("colnumeric").to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
featureset = all_features(ds);
|
||||||
|
feature = featureset->next();
|
||||||
|
//deactivate char tests for now: not yet implemented.
|
||||||
|
//add at postgis_datasource.cpp:423
|
||||||
|
//case 18: // char
|
||||||
|
//REQUIRE("A" == feature->get("col-char").to_string());
|
||||||
|
feature = featureset->next();
|
||||||
|
//REQUIRE("B" == feature->get("col-char").to_string());
|
||||||
|
feature = featureset->next();
|
||||||
|
REQUIRE(false == feature->get("col+bool").to_bool());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Postgis cursorresultest")
|
||||||
|
{
|
||||||
|
params["table"] = "(SELECT * FROM test) as data";
|
||||||
|
params["cursor_size"] = "2";
|
||||||
|
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||||
|
REQUIRE(ds != nullptr);
|
||||||
|
auto featureset = all_features(ds);
|
||||||
|
CHECK(count_features(featureset) == 8);
|
||||||
|
|
||||||
|
featureset = all_features(ds);
|
||||||
|
mapnik::feature_ptr feature;
|
||||||
|
while (bool(feature = featureset->next())) {
|
||||||
|
CHECK(feature->size() == 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
featureset = all_features(ds);
|
||||||
|
require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::Point);
|
||||||
|
require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::Point);
|
||||||
|
require_geometry(featureset->next(), 2, mapnik::geometry::geometry_types::MultiPoint);
|
||||||
|
require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::LineString);
|
||||||
|
require_geometry(featureset->next(), 2, mapnik::geometry::geometry_types::MultiLineString);
|
||||||
|
require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::Polygon);
|
||||||
|
require_geometry(featureset->next(), 2, mapnik::geometry::geometry_types::MultiPolygon);
|
||||||
|
require_geometry(featureset->next(), 3, mapnik::geometry::geometry_types::GeometryCollection);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Postgis bbox query")
|
||||||
|
{
|
||||||
|
params["table"] = "(SELECT * FROM public.test) as data WHERE geom && !bbox!";
|
||||||
|
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||||
|
REQUIRE(ds != nullptr);
|
||||||
|
mapnik::box2d<double> ext = ds->envelope();
|
||||||
|
CAPTURE(ext);
|
||||||
|
INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
|
||||||
|
REQUIRE(ext.minx() == -2);
|
||||||
|
REQUIRE(ext.miny() == -2);
|
||||||
|
REQUIRE(ext.maxx() == 5);
|
||||||
|
REQUIRE(ext.maxy() == 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Postgis query extent: full dataset")
|
||||||
|
{
|
||||||
|
//include schema to increase coverage
|
||||||
|
params["table"] = "(SELECT * FROM public.test) as data";
|
||||||
|
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||||
|
REQUIRE(ds != nullptr);
|
||||||
|
mapnik::box2d<double> ext = ds->envelope();
|
||||||
|
CAPTURE(ext);
|
||||||
|
INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
|
||||||
|
REQUIRE(ext.minx() == -2);
|
||||||
|
REQUIRE(ext.miny() == -2);
|
||||||
|
REQUIRE(ext.maxx() == 5);
|
||||||
|
REQUIRE(ext.maxy() == 4);
|
||||||
|
}
|
||||||
|
/* deactivated for merging: still investigating a proper fix
|
||||||
|
SECTION("Postgis query extent from subquery")
|
||||||
|
{
|
||||||
|
params["table"] = "(SELECT * FROM test where gid=4) as data";
|
||||||
|
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||||
|
REQUIRE(ds != nullptr);
|
||||||
|
mapnik::box2d<double> ext = ds->envelope();
|
||||||
|
CAPTURE(ext);
|
||||||
|
INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
|
||||||
|
REQUIRE(ext.minx() == 0);
|
||||||
|
REQUIRE(ext.miny() == 0);
|
||||||
|
REQUIRE(ext.maxx() == 1);
|
||||||
|
REQUIRE(ext.maxy() == 2);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
SECTION("Postgis query extent: from subquery with 'extent_from_subquery=true'")
|
||||||
|
{
|
||||||
|
params["table"] = "(SELECT * FROM test where gid=4) as data";
|
||||||
|
params["extent_from_subquery"] = "true";
|
||||||
|
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||||
|
REQUIRE(ds != nullptr);
|
||||||
|
mapnik::box2d<double> ext = ds->envelope();
|
||||||
|
CAPTURE(ext);
|
||||||
|
INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
|
||||||
|
REQUIRE(ext.minx() == 0);
|
||||||
|
REQUIRE(ext.miny() == 0);
|
||||||
|
REQUIRE(ext.maxx() == 1);
|
||||||
|
REQUIRE(ext.maxy() == 2);
|
||||||
|
}
|
||||||
|
/* deactivated for merging: still investigating a proper fix
|
||||||
|
SECTION("Postgis query extent: subset with 'extent_from_subquery=true' and 'scale_denominator'")
|
||||||
|
{
|
||||||
|
// !!!! postgis-vt-util::z() returns 'null' when 'scale_denominator > 600000000'
|
||||||
|
// https://github.com/mapbox/postgis-vt-util/blob/559f073877696a6bfea41baf3e1065f9cf4d18d1/postgis-vt-util.sql#L615-L617
|
||||||
|
params["table"] = "(SELECT * FROM test where gid=4 AND z(!scale_denominator!) BETWEEN 0 AND 22) as data";
|
||||||
|
params["extent_from_subquery"] = "true";
|
||||||
|
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||||
|
REQUIRE(ds != nullptr);
|
||||||
|
mapnik::box2d<double> ext = ds->envelope();
|
||||||
|
CAPTURE(ext);
|
||||||
|
INFO("" << std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
|
||||||
|
REQUIRE(ext.minx() == 0);
|
||||||
|
REQUIRE(ext.miny() == 0);
|
||||||
|
REQUIRE(ext.maxx() == 1);
|
||||||
|
REQUIRE(ext.maxy() == 2);
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
|
@ -58,14 +58,17 @@ std::size_t count_shapefile_features(std::string const& filename)
|
||||||
return feature_count;
|
return feature_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int create_shapefile_index(std::string const& filename, bool silent = true)
|
int create_shapefile_index(std::string const& filename, bool index_parts, bool silent = true)
|
||||||
{
|
{
|
||||||
std::string cmd;
|
std::string cmd;
|
||||||
if (std::getenv("DYLD_LIBRARY_PATH") != nullptr)
|
if (std::getenv("DYLD_LIBRARY_PATH") != nullptr)
|
||||||
{
|
{
|
||||||
cmd += std::string("export DYLD_LIBRARY_PATH=") + std::getenv("DYLD_LIBRARY_PATH") + " && ";
|
cmd += std::string("DYLD_LIBRARY_PATH=") + std::getenv("DYLD_LIBRARY_PATH") + " ";
|
||||||
}
|
}
|
||||||
cmd += "shapeindex " + filename;
|
|
||||||
|
cmd += "shapeindex";
|
||||||
|
if (index_parts) cmd+= " --index-parts ";
|
||||||
|
cmd += filename;
|
||||||
if (silent)
|
if (silent)
|
||||||
{
|
{
|
||||||
#ifndef _WINDOWS
|
#ifndef _WINDOWS
|
||||||
|
@ -90,28 +93,31 @@ TEST_CASE("shapeindex")
|
||||||
{
|
{
|
||||||
if (boost::iends_with(path,".shp"))
|
if (boost::iends_with(path,".shp"))
|
||||||
{
|
{
|
||||||
std::string index_path = path.substr(0, path.rfind(".")) + ".index";
|
for (bool index_parts : {false, true} )
|
||||||
// remove *.index if present
|
|
||||||
if (mapnik::util::exists(index_path))
|
|
||||||
{
|
{
|
||||||
mapnik::util::remove(index_path);
|
std::string index_path = path.substr(0, path.rfind(".")) + ".index";
|
||||||
}
|
// remove *.index if present
|
||||||
// count features
|
if (mapnik::util::exists(index_path))
|
||||||
std::size_t feature_count = count_shapefile_features(path);
|
{
|
||||||
// create *.index
|
mapnik::util::remove(index_path);
|
||||||
create_shapefile_index(path);
|
}
|
||||||
if (feature_count == 0)
|
// count features
|
||||||
{
|
std::size_t feature_count = count_shapefile_features(path);
|
||||||
REQUIRE(!mapnik::util::exists(index_path)); // index won't be created if there's no features
|
// create *.index
|
||||||
}
|
create_shapefile_index(path, index_parts);
|
||||||
// count features
|
if (feature_count == 0)
|
||||||
std::size_t feature_count_indexed = count_shapefile_features(path);
|
{
|
||||||
// ensure number of features are the same
|
REQUIRE(!mapnik::util::exists(index_path)); // index won't be created if there's no features
|
||||||
REQUIRE(feature_count == feature_count_indexed);
|
}
|
||||||
// remove *.index if present
|
// count features
|
||||||
if (mapnik::util::exists(index_path))
|
std::size_t feature_count_indexed = count_shapefile_features(path);
|
||||||
{
|
// ensure number of features are the same
|
||||||
mapnik::util::remove(index_path);
|
REQUIRE(feature_count == feature_count_indexed);
|
||||||
|
// remove *.index if present
|
||||||
|
if (mapnik::util::exists(index_path))
|
||||||
|
{
|
||||||
|
mapnik::util::remove(index_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,73 @@
|
||||||
#define CATCH_CONFIG_RUNNER
|
#define CATCH_CONFIG_RUNNER
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <mapnik/util/fs.hpp>
|
||||||
#include <mapnik/datasource_cache.hpp>
|
#include <mapnik/datasource_cache.hpp>
|
||||||
|
#include <boost/filesystem/convenience.hpp>
|
||||||
|
|
||||||
#include "cleanup.hpp" // run_cleanup()
|
#include "cleanup.hpp" // run_cleanup()
|
||||||
|
|
||||||
|
std::string plugin_path;
|
||||||
|
|
||||||
|
inline void set_plugin_path(Catch::ConfigData&, std::string const& _plugin_path ) {
|
||||||
|
plugin_path = _plugin_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string working_dir;
|
||||||
|
|
||||||
|
inline void set_working_dir(Catch::ConfigData&, std::string const& _working_dir ) {
|
||||||
|
working_dir = _working_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main (int argc, char* const argv[])
|
int main (int argc, char* const argv[])
|
||||||
{
|
{
|
||||||
mapnik::datasource_cache::instance().register_datasources("plugins/input/");
|
Catch::Session session;
|
||||||
|
|
||||||
int result = Catch::Session().run( argc, argv );
|
auto & cli = session.cli();
|
||||||
|
|
||||||
|
cli["-p"]["--plugins"]
|
||||||
|
.describe("path to mapnik plugins")
|
||||||
|
.bind(&set_plugin_path, "plugins");
|
||||||
|
|
||||||
|
cli["-C"]["--working-directory"]
|
||||||
|
.describe("change working directory")
|
||||||
|
.bind(&set_working_dir, "working directory");
|
||||||
|
|
||||||
|
int result = session.applyCommandLine(argc, argv);
|
||||||
|
|
||||||
|
if (!plugin_path.empty())
|
||||||
|
{
|
||||||
|
if (!mapnik::util::exists(plugin_path))
|
||||||
|
{
|
||||||
|
std::clog << "Could not find " << plugin_path << "\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
mapnik::datasource_cache::instance().register_datasources(plugin_path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mapnik::datasource_cache::instance().register_datasources("plugins/input/");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!working_dir.empty())
|
||||||
|
{
|
||||||
|
if (!mapnik::util::exists(working_dir))
|
||||||
|
{
|
||||||
|
std::clog << "Could not find " << working_dir << "\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
boost::filesystem::current_path(working_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
result = session.run();
|
||||||
|
}
|
||||||
|
|
||||||
testing::run_cleanup();
|
testing::run_cleanup();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,7 +150,8 @@ result_list runner::test_all(report_type & report) const
|
||||||
|
|
||||||
result_list runner::test(std::vector<std::string> const & style_names, report_type & report) const
|
result_list runner::test(std::vector<std::string> const & style_names, report_type & report) const
|
||||||
{
|
{
|
||||||
std::vector<runner::path_type> files(style_names.size());
|
std::vector<runner::path_type> files;
|
||||||
|
files.reserve(style_names.size());
|
||||||
std::transform(style_names.begin(), style_names.end(), std::back_inserter(files),
|
std::transform(style_names.begin(), style_names.end(), std::back_inserter(files),
|
||||||
[&](runner::path_type const & name)
|
[&](runner::path_type const & name)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,9 +26,10 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <mapnik/util/fs.hpp>
|
#include <mapnik/util/fs.hpp>
|
||||||
#include <mapnik/quad_tree.hpp>
|
#include <mapnik/quad_tree.hpp>
|
||||||
|
#include <mapnik/geometry_envelope.hpp>
|
||||||
#include "shapefile.hpp"
|
#include "shapefile.hpp"
|
||||||
#include "shape_io.hpp"
|
#include "shape_io.hpp"
|
||||||
|
#include "shape_index_featureset.hpp"
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
@ -44,8 +45,9 @@ int main (int argc,char** argv)
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
bool verbose=false;
|
bool verbose=false;
|
||||||
unsigned int depth=DEFAULT_DEPTH;
|
bool index_parts = false;
|
||||||
double ratio=DEFAULT_RATIO;
|
unsigned int depth = DEFAULT_DEPTH;
|
||||||
|
double ratio = DEFAULT_RATIO;
|
||||||
std::vector<std::string> shape_files;
|
std::vector<std::string> shape_files;
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -54,6 +56,7 @@ int main (int argc,char** argv)
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "produce usage message")
|
("help,h", "produce usage message")
|
||||||
("version,V","print version string")
|
("version,V","print version string")
|
||||||
|
("index-parts","index individual shape parts (default: no)")
|
||||||
("verbose,v","verbose output")
|
("verbose,v","verbose output")
|
||||||
("depth,d", po::value<unsigned int>(), "max tree depth\n(default 8)")
|
("depth,d", po::value<unsigned int>(), "max tree depth\n(default 8)")
|
||||||
("ratio,r",po::value<double>(),"split ratio (default 0.55)")
|
("ratio,r",po::value<double>(),"split ratio (default 0.55)")
|
||||||
|
@ -81,6 +84,10 @@ int main (int argc,char** argv)
|
||||||
{
|
{
|
||||||
verbose = true;
|
verbose = true;
|
||||||
}
|
}
|
||||||
|
if (vm.count("index-parts"))
|
||||||
|
{
|
||||||
|
index_parts = true;
|
||||||
|
}
|
||||||
if (vm.count("depth"))
|
if (vm.count("depth"))
|
||||||
{
|
{
|
||||||
depth = vm["depth"].as<unsigned int>();
|
depth = vm["depth"].as<unsigned int>();
|
||||||
|
@ -159,7 +166,7 @@ int main (int argc,char** argv)
|
||||||
|
|
||||||
int pos = 50;
|
int pos = 50;
|
||||||
shx.seek(pos * 2);
|
shx.seek(pos * 2);
|
||||||
mapnik::quad_tree<int> tree(extent, depth, ratio);
|
mapnik::quad_tree<mapnik::detail::node> tree(extent, depth, ratio);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
if (shape_type != shape_io::shape_null)
|
if (shape_type != shape_io::shape_null)
|
||||||
|
@ -188,17 +195,56 @@ int main (int argc,char** argv)
|
||||||
double y=shp.read_double();
|
double y=shp.read_double();
|
||||||
item_ext=box2d<double>(x,y,x,y);
|
item_ext=box2d<double>(x,y,x,y);
|
||||||
}
|
}
|
||||||
|
else if (index_parts &&
|
||||||
|
(shape_type == shape_io::shape_polygon || shape_type == shape_io::shape_polygonm || shape_type == shape_io::shape_polygonz
|
||||||
|
|| shape_type == shape_io::shape_polyline || shape_type == shape_io::shape_polylinem || shape_type == shape_io::shape_polylinez))
|
||||||
|
{
|
||||||
|
shp.read_envelope(item_ext);
|
||||||
|
int num_parts = shp.read_ndr_integer();
|
||||||
|
int num_points = shp.read_ndr_integer();
|
||||||
|
std::vector<int> parts;
|
||||||
|
parts.resize(num_parts);
|
||||||
|
std::for_each(parts.begin(), parts.end(), [&](int & part) { part = shp.read_ndr_integer();});
|
||||||
|
for (int k = 0; k < num_parts; ++k)
|
||||||
|
{
|
||||||
|
int start = parts[k];
|
||||||
|
int end;
|
||||||
|
if (k == num_parts - 1) end = num_points;
|
||||||
|
else end = parts[k + 1];
|
||||||
|
|
||||||
|
mapnik::geometry::linear_ring<double> ring;
|
||||||
|
ring.reserve(end - start);
|
||||||
|
for (int j = start; j < end; ++j)
|
||||||
|
{
|
||||||
|
double x = shp.read_double();
|
||||||
|
double y = shp.read_double();
|
||||||
|
ring.emplace_back(x, y);
|
||||||
|
}
|
||||||
|
item_ext = mapnik::geometry::envelope(ring);
|
||||||
|
if (item_ext.valid())
|
||||||
|
{
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
std::clog << "record number " << record_number << " box=" << item_ext << std::endl;
|
||||||
|
}
|
||||||
|
tree.insert(mapnik::detail::node(offset * 2, start, end),item_ext);
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item_ext = mapnik::box2d<double>(); //invalid
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shp.read_envelope(item_ext);
|
shp.read_envelope(item_ext);
|
||||||
}
|
}
|
||||||
if (verbose)
|
|
||||||
{
|
|
||||||
std::clog << "record number " << record_number << " box=" << item_ext << std::endl;
|
|
||||||
}
|
|
||||||
if (item_ext.valid())
|
if (item_ext.valid())
|
||||||
{
|
{
|
||||||
tree.insert(offset * 2,item_ext);
|
if (verbose)
|
||||||
|
{
|
||||||
|
std::clog << "record number " << record_number << " box=" << item_ext << std::endl;
|
||||||
|
}
|
||||||
|
tree.insert(mapnik::detail::node(offset * 2,-1,0),item_ext);
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue