Lines 38-48
Link Here
|
38 |
#include <boost/spirit/include/phoenix_fusion.hpp> |
38 |
#include <boost/spirit/include/phoenix_fusion.hpp> |
39 |
#include <boost/spirit/include/phoenix_function.hpp> |
39 |
#include <boost/spirit/include/phoenix_function.hpp> |
40 |
#include <boost/spirit/include/phoenix_statement.hpp> |
40 |
#include <boost/spirit/include/phoenix_statement.hpp> |
41 |
#include <boost/fusion/include/boost_tuple.hpp> |
41 |
#include <boost/fusion/adapted/boost_tuple.hpp> |
42 |
#include <boost/math/special_functions/trunc.hpp> // trunc to avoid needing C++11 |
42 |
#include <boost/math/special_functions/trunc.hpp> // for vc++ and android whose c++11 libs lack std::trunct |
43 |
|
|
|
44 |
|
45 |
//#define BOOST_SPIRIT_USE_PHOENIX_V3 1 |
46 |
|
43 |
|
47 |
namespace boost { namespace spirit { namespace traits { |
44 |
namespace boost { namespace spirit { namespace traits { |
48 |
|
45 |
|
Lines 61-66
namespace phoenix = boost::phoenix;
Link Here
|
61 |
|
58 |
|
62 |
namespace { |
59 |
namespace { |
63 |
|
60 |
|
|
|
61 |
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3 |
62 |
struct get_type |
63 |
{ |
64 |
typedef int result_type; |
65 |
result_type operator() (geometry_type const& geom) const |
66 |
{ |
67 |
return static_cast<int>(geom.type()); |
68 |
} |
69 |
}; |
70 |
|
71 |
struct get_first |
72 |
{ |
73 |
typedef geometry_type::value_type const result_type; |
74 |
result_type operator() (geometry_type const& geom) const |
75 |
{ |
76 |
geometry_type::value_type coord; |
77 |
boost::get<0>(coord) = geom.vertex(0,&boost::get<1>(coord),&boost::get<2>(coord)); |
78 |
return coord; |
79 |
} |
80 |
}; |
81 |
|
82 |
struct multi_geometry_type |
83 |
{ |
84 |
typedef boost::tuple<unsigned,bool> result_type; |
85 |
result_type operator() (geometry_container const& geom) const |
86 |
{ |
87 |
unsigned type = 0u; |
88 |
bool collection = false; |
89 |
|
90 |
geometry_container::const_iterator itr = geom.begin(); |
91 |
geometry_container::const_iterator end = geom.end(); |
92 |
|
93 |
for ( ; itr != end; ++itr) |
94 |
{ |
95 |
if (type != 0u && itr->type() != type) |
96 |
{ |
97 |
collection = true; |
98 |
break; |
99 |
} |
100 |
type = itr->type(); |
101 |
} |
102 |
if (geom.size() > 1) type +=3; |
103 |
return boost::tuple<unsigned,bool>(type, collection); |
104 |
} |
105 |
}; |
106 |
|
107 |
struct not_empty |
108 |
{ |
109 |
typedef bool result_type; |
110 |
result_type operator() (geometry_container const& cont) const |
111 |
{ |
112 |
geometry_container::const_iterator itr = cont.begin(); |
113 |
geometry_container::const_iterator end = cont.end(); |
114 |
for ( ; itr != end; ++itr) |
115 |
{ |
116 |
if (itr->size() > 0) return true; |
117 |
} |
118 |
return false; |
119 |
} |
120 |
}; |
121 |
|
122 |
#else |
64 |
struct get_type |
123 |
struct get_type |
65 |
{ |
124 |
{ |
66 |
template <typename T> |
125 |
template <typename T> |
Lines 100-106
struct multi_geometry_type
Link Here
|
100 |
|
159 |
|
101 |
for ( ; itr != end; ++itr) |
160 |
for ( ; itr != end; ++itr) |
102 |
{ |
161 |
{ |
103 |
if (type != 0u && itr->type() != type) |
162 |
if (type != 0u && static_cast<unsigned>(itr->type()) != type) |
104 |
{ |
163 |
{ |
105 |
collection = true; |
164 |
collection = true; |
106 |
break; |
165 |
break; |
Lines 113-118
struct multi_geometry_type
Link Here
|
113 |
}; |
172 |
}; |
114 |
|
173 |
|
115 |
|
174 |
|
|
|
175 |
struct not_empty |
176 |
{ |
177 |
template <typename T> |
178 |
struct result { typedef bool type; }; |
179 |
|
180 |
bool operator() (geometry_container const& cont) const |
181 |
{ |
182 |
geometry_container::const_iterator itr = cont.begin(); |
183 |
geometry_container::const_iterator end = cont.end(); |
184 |
|
185 |
for (; itr!=end; ++itr) |
186 |
{ |
187 |
if (itr->size() > 0) return true; |
188 |
} |
189 |
return false; |
190 |
} |
191 |
}; |
192 |
|
193 |
|
194 |
#endif |
195 |
|
196 |
|
116 |
template <typename T> |
197 |
template <typename T> |
117 |
struct json_coordinate_policy : karma::real_policies<T> |
198 |
struct json_coordinate_policy : karma::real_policies<T> |
118 |
{ |
199 |
{ |
Lines 123-129
struct json_coordinate_policy : karma::real_policies<T>
Link Here
|
123 |
{ |
204 |
{ |
124 |
if (n == 0.0) return 0; |
205 |
if (n == 0.0) return 0; |
125 |
using namespace boost::spirit; |
206 |
using namespace boost::spirit; |
126 |
return static_cast<unsigned>(15 - boost::math::trunc(log10(traits::get_absolute_value(n)))); |
207 |
return static_cast<unsigned>(14 - boost::math::trunc(log10(traits::get_absolute_value(n)))); |
127 |
} |
208 |
} |
128 |
|
209 |
|
129 |
template <typename OutputIterator> |
210 |
template <typename OutputIterator> |
Lines 135-141
struct json_coordinate_policy : karma::real_policies<T>
Link Here
|
135 |
|
216 |
|
136 |
template <typename OutputIterator> |
217 |
template <typename OutputIterator> |
137 |
static bool fraction_part(OutputIterator& sink, T n |
218 |
static bool fraction_part(OutputIterator& sink, T n |
138 |
, unsigned adjprec, unsigned precision) |
219 |
, unsigned adjprec, unsigned precision) |
139 |
{ |
220 |
{ |
140 |
if (n == 0) return true; |
221 |
if (n == 0) return true; |
141 |
return base_type::fraction_part(sink, n, adjprec, precision); |
222 |
return base_type::fraction_part(sink, n, adjprec, precision); |
Lines 153-158
struct geometry_generator_grammar :
Link Here
|
153 |
: geometry_generator_grammar::base_type(coordinates) |
234 |
: geometry_generator_grammar::base_type(coordinates) |
154 |
{ |
235 |
{ |
155 |
using boost::spirit::karma::uint_; |
236 |
using boost::spirit::karma::uint_; |
|
|
237 |
using boost::spirit::bool_; |
156 |
using boost::spirit::karma::_val; |
238 |
using boost::spirit::karma::_val; |
157 |
using boost::spirit::karma::_1; |
239 |
using boost::spirit::karma::_1; |
158 |
using boost::spirit::karma::lit; |
240 |
using boost::spirit::karma::lit; |
Lines 182-196
struct geometry_generator_grammar :
Link Here
|
182 |
point_coord = &uint_ |
264 |
point_coord = &uint_ |
183 |
<< lit('[') |
265 |
<< lit('[') |
184 |
<< coord_type << lit(',') << coord_type |
266 |
<< coord_type << lit(',') << coord_type |
185 |
<< lit("]") |
267 |
<< lit(']') |
186 |
; |
268 |
; |
187 |
|
269 |
|
188 |
polygon_coord %= ( &uint_(mapnik::SEG_MOVETO) << eps[_r1 += 1] |
270 |
polygon_coord %= ( &uint_(mapnik::SEG_MOVETO) << eps[_r1 += 1] |
189 |
<< karma::string[ if_ (_r1 > 1) [_1 = "],["] |
271 |
<< karma::string[ if_ (_r1 > 1u) [_1 = "],["] |
190 |
.else_[_1 = '[' ]] | &uint_ << lit(',')) |
272 |
.else_[_1 = '[' ]] |
191 |
<< lit('[') << coord_type |
273 |
| |
192 |
<< lit(',') |
274 |
&uint_(mapnik::SEG_LINETO) |
193 |
<< coord_type << lit(']') |
275 |
<< lit(',')) << lit('[') << coord_type << lit(',') << coord_type << lit(']') |
194 |
; |
276 |
; |
195 |
|
277 |
|
196 |
coords2 %= *polygon_coord(_a) |
278 |
coords2 %= *polygon_coord(_a) |
Lines 205-211
struct geometry_generator_grammar :
Link Here
|
205 |
karma::rule<OutputIterator, geometry_type const& ()> point; |
287 |
karma::rule<OutputIterator, geometry_type const& ()> point; |
206 |
karma::rule<OutputIterator, geometry_type const& ()> linestring; |
288 |
karma::rule<OutputIterator, geometry_type const& ()> linestring; |
207 |
karma::rule<OutputIterator, geometry_type const& ()> polygon; |
289 |
karma::rule<OutputIterator, geometry_type const& ()> polygon; |
208 |
|
|
|
209 |
karma::rule<OutputIterator, geometry_type const& ()> coords; |
290 |
karma::rule<OutputIterator, geometry_type const& ()> coords; |
210 |
karma::rule<OutputIterator, karma::locals<unsigned>, geometry_type const& ()> coords2; |
291 |
karma::rule<OutputIterator, karma::locals<unsigned>, geometry_type const& ()> coords2; |
211 |
karma::rule<OutputIterator, geometry_type::value_type ()> point_coord; |
292 |
karma::rule<OutputIterator, geometry_type::value_type ()> point_coord; |
Lines 235-240
struct multi_geometry_generator_grammar :
Link Here
|
235 |
using boost::spirit::karma::_1; |
316 |
using boost::spirit::karma::_1; |
236 |
using boost::spirit::karma::_a; |
317 |
using boost::spirit::karma::_a; |
237 |
using boost::spirit::karma::_r1; |
318 |
using boost::spirit::karma::_r1; |
|
|
319 |
using boost::spirit::bool_; |
238 |
|
320 |
|
239 |
geometry_types.add |
321 |
geometry_types.add |
240 |
(mapnik::Point,"\"Point\"") |
322 |
(mapnik::Point,"\"Point\"") |
Lines 245-251
struct multi_geometry_generator_grammar :
Link Here
|
245 |
(mapnik::Polygon + 3,"\"MultiPolygon\"") |
327 |
(mapnik::Polygon + 3,"\"MultiPolygon\"") |
246 |
; |
328 |
; |
247 |
|
329 |
|
248 |
start %= ( eps(phoenix::at_c<1>(_a))[_a = _multi_type(_val)] |
330 |
start %= ( eps(phoenix::at_c<1>(_a))[_a = multi_type_(_val)] |
249 |
<< lit("{\"type\":\"GeometryCollection\",\"geometries\":[") |
331 |
<< lit("{\"type\":\"GeometryCollection\",\"geometries\":[") |
250 |
<< geometry_collection << lit("]}") |
332 |
<< geometry_collection << lit("]}") |
251 |
| |
333 |
| |
Lines 255-267
struct multi_geometry_generator_grammar :
Link Here
|
255 |
geometry_collection = -(geometry2 % lit(',')) |
337 |
geometry_collection = -(geometry2 % lit(',')) |
256 |
; |
338 |
; |
257 |
|
339 |
|
258 |
geometry = (lit("{\"type\":") |
340 |
geometry = ( &bool_(true)[_1 = not_empty_(_val)] << lit("{\"type\":") |
259 |
<< geometry_types[_1 = phoenix::at_c<0>(_a)][_a = _multi_type(_val)] |
341 |
<< geometry_types[_1 = phoenix::at_c<0>(_a)][_a = multi_type_(_val)] |
260 |
<< lit(",\"coordinates\":") |
342 |
<< lit(",\"coordinates\":") |
261 |
<< karma::string[ if_ (phoenix::at_c<0>(_a) > 3) [_1 = '[']] |
343 |
<< karma::string[ phoenix::if_ (phoenix::at_c<0>(_a) > 3u) [_1 = '['].else_[_1 = ""]] |
262 |
<< coordinates |
344 |
<< coordinates |
263 |
<< karma::string[ if_ (phoenix::at_c<0>(_a) > 3) [_1 = ']']] |
345 |
<< karma::string[ phoenix::if_ (phoenix::at_c<0>(_a) > 3u) [_1 = ']'].else_[_1 = ""]] |
264 |
<< lit('}')) | lit("null") |
346 |
<< lit('}')) | lit("null") |
265 |
; |
347 |
; |
266 |
|
348 |
|
267 |
geometry2 = lit("{\"type\":") |
349 |
geometry2 = lit("{\"type\":") |
Lines 287-294
struct multi_geometry_generator_grammar :
Link Here
|
287 |
karma::rule<OutputIterator, geometry_container const&()> coordinates; |
369 |
karma::rule<OutputIterator, geometry_container const&()> coordinates; |
288 |
geometry_generator_grammar<OutputIterator> path; |
370 |
geometry_generator_grammar<OutputIterator> path; |
289 |
// phoenix |
371 |
// phoenix |
290 |
phoenix::function<multi_geometry_type> _multi_type; |
372 |
phoenix::function<multi_geometry_type> multi_type_; |
291 |
phoenix::function<get_type > type_; |
373 |
phoenix::function<get_type > type_; |
|
|
374 |
phoenix::function<not_empty> not_empty_; |
292 |
// symbols table |
375 |
// symbols table |
293 |
karma::symbols<unsigned, char const*> geometry_types; |
376 |
karma::symbols<unsigned, char const*> geometry_types; |
294 |
}; |
377 |
}; |