+ modify WKT parser to work with ptr_vector<geometry_type>
+ fix memory leaks in wkt_grammar + add support for GEOMETRYCOLLECTION
This commit is contained in:
parent
7468c95084
commit
53b50c871c
3 changed files with 118 additions and 44 deletions
|
@ -25,10 +25,11 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <mapnik/geometry.hpp>
|
#include <mapnik/geometry.hpp>
|
||||||
|
#include <boost/ptr_container/ptr_vector.hpp>
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
std::pair<bool,geometry_type*> from_wkt(std::string const& wkt);
|
bool from_wkt(std::string const& wkt, boost::ptr_vector<geometry_type> & paths);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,88 +70,162 @@ struct cleanup
|
||||||
template <typename T0>
|
template <typename T0>
|
||||||
void operator() (T0 & path) const
|
void operator() (T0 & path) const
|
||||||
{
|
{
|
||||||
if (path) delete path,path=0;
|
if (path) delete path,path=0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
struct wkt_grammar : qi::grammar<Iterator, geometry_type*(), ascii::space_type>
|
struct wkt_grammar : qi::grammar<Iterator, boost::ptr_vector<mapnik::geometry_type>() , ascii::space_type>
|
||||||
{
|
{
|
||||||
wkt_grammar()
|
wkt_grammar()
|
||||||
: wkt_grammar::base_type(start)
|
: wkt_grammar::base_type(geometry_tagged_text)
|
||||||
{
|
{
|
||||||
using qi::_1;
|
|
||||||
using qi::_2;
|
|
||||||
using qi::_val;
|
|
||||||
using qi::no_case;
|
using qi::no_case;
|
||||||
|
using boost::phoenix::push_back;
|
||||||
|
|
||||||
start %= point | linestring | polygon | multipoint | multilinestring | multipolygon | eps[cleanup_(_val)][_pass = false];
|
geometry_tagged_text = point_tagged_text
|
||||||
|
| linestring_tagged_text
|
||||||
|
| polygon_tagged_text
|
||||||
|
| multipoint_tagged_text
|
||||||
|
| multilinestring_tagged_text
|
||||||
|
| multipolygon_tagged_text
|
||||||
|
;
|
||||||
|
|
||||||
// <point tagged text> ::= point <point text>
|
// <point tagged text> ::= point <point text>
|
||||||
point = no_case[lit("POINT")] [ _val = new_<geometry_type>(Point) ]
|
point_tagged_text = no_case[lit("POINT")] [ _a = new_<geometry_type>(Point) ]
|
||||||
>> (empty_set | lit('(') >> coord(SEG_MOVETO,_val) >> lit(')'));
|
>> ( point_text(_a) [push_back(_val,_a)]
|
||||||
|
| eps[cleanup_(_a)][_pass = false])
|
||||||
|
;
|
||||||
|
|
||||||
|
// <point text> ::= <empty set> | <left paren> <point> <right paren>
|
||||||
|
point_text = (lit("(") >> point(SEG_MOVETO,_r1) >> lit(')'))
|
||||||
|
| empty_set
|
||||||
|
;
|
||||||
|
|
||||||
// <linestring tagged text> ::= linestring <linestring text>
|
// <linestring tagged text> ::= linestring <linestring text>
|
||||||
linestring = no_case[lit("LINESTRING")] [ _val = new_<geometry_type>(LineString) ] >> (empty_set | points(_val));
|
linestring_tagged_text = no_case[lit("LINESTRING")] [ _a = new_<geometry_type>(LineString) ]
|
||||||
|
>> (linestring_text(_a)[push_back(_val,_a)]
|
||||||
|
| eps[cleanup_(_a)][_pass = false])
|
||||||
|
;
|
||||||
|
|
||||||
|
// <linestring text> ::= <empty set> | <left paren> <point> {<comma> <point>}* <right paren>
|
||||||
|
linestring_text = points(_r1) | empty_set
|
||||||
|
;
|
||||||
|
|
||||||
// <polygon tagged text> ::= polygon <polygon text>
|
// <polygon tagged text> ::= polygon <polygon text>
|
||||||
polygon = no_case[lit("POLYGON")] [ _val = new_<geometry_type>(Polygon) ] >>
|
polygon_tagged_text = no_case[lit("POLYGON")] [ _a = new_<geometry_type>(Polygon) ]
|
||||||
(empty_set | lit('(') >> points(_val) % lit(',') >> lit(')'));
|
>> ( polygon_text(_a)[push_back(_val,_a)]
|
||||||
|
| eps[cleanup_(_a)][_pass = false])
|
||||||
|
;
|
||||||
|
|
||||||
// multi point
|
// <polygon text> ::= <empty set> | <left paren> <linestring text> {<comma> <linestring text>}* <right paren>
|
||||||
multipoint = no_case[lit("MULTIPOINT")] [ _val = new_<geometry_type>(MultiPoint) ]
|
polygon_text = (lit('(') >> linestring_text(_r1) % lit(',') >> lit(')')) | empty_set;
|
||||||
>> (empty_set | lit('(') >> coord(SEG_MOVETO,_val) % lit(',') >> ')');
|
|
||||||
|
|
||||||
// multi linestring
|
|
||||||
multilinestring = no_case[lit("MULTILINESTRING")] [ _val = new_<geometry_type>(MultiLineString) ]>>
|
|
||||||
(empty_set | lit('(') >> points(_val) % lit(',') >> ')');
|
|
||||||
|
|
||||||
// multi polygon
|
//<multipoint tagged text> ::= multipoint <multipoint text>
|
||||||
multipolygon = no_case[lit("MULTIPOLYGON")] [ _val = new_<geometry_type>(MultiPolygon)] >>
|
multipoint_tagged_text = no_case[lit("MULTIPOINT")]
|
||||||
(empty_set | lit('(') >> (lit('(') >>
|
>> multipoint_text
|
||||||
points(_val) % ',' >> ')') % ',' >> ')');
|
;
|
||||||
|
|
||||||
|
// <multipoint text> ::= <empty set> | <left paren> <point text> {<comma> <point text>}* <right paren>
|
||||||
|
multipoint_text = (lit('(')
|
||||||
|
>> ((eps[_a = new_<geometry_type>(Point)]
|
||||||
|
>> (point_text(_a) | empty_set) [push_back(_val,_a)]
|
||||||
|
| eps[cleanup_(_a)][_pass = false]) % lit(','))
|
||||||
|
>> lit(')')) | empty_set
|
||||||
|
;
|
||||||
|
|
||||||
|
// <multilinestring tagged text> ::= multilinestring <multilinestring text>
|
||||||
|
multilinestring_tagged_text = no_case[lit("MULTILINESTRING")]
|
||||||
|
>> multilinestring_text ;
|
||||||
|
|
||||||
|
// <multilinestring text> ::= <empty set> | <left paren> <linestring text> {<comma> <linestring text>}* <right paren>
|
||||||
|
multilinestring_text = (lit('(')
|
||||||
|
>> ((eps[_a = new_<geometry_type>(LineString)]
|
||||||
|
>> ( points(_a)[push_back(_val,_a)]
|
||||||
|
| eps[cleanup_(_a)][_pass = false]))
|
||||||
|
% lit(','))
|
||||||
|
>> lit(')')) | empty_set;
|
||||||
|
|
||||||
|
// <multipolygon tagged text> ::= multipolygon <multipolygon text>
|
||||||
|
multipolygon_tagged_text = no_case[lit("MULTIPOLYGON")]
|
||||||
|
>> multipolygon_text ;
|
||||||
|
|
||||||
|
// <multipolygon text> ::= <empty set> | <left paren> <polygon text> {<comma> <polygon text>}* <right paren>
|
||||||
|
|
||||||
|
multipolygon_text = (lit('(')
|
||||||
|
>> ((eps[_a = new_<geometry_type>(Polygon)]
|
||||||
|
>> ( polygon_text(_a)[push_back(_val,_a)]
|
||||||
|
| eps[cleanup_(_a)][_pass = false]))
|
||||||
|
% lit(','))
|
||||||
|
>> lit(')')) | empty_set;
|
||||||
|
|
||||||
// points
|
// points
|
||||||
points = lit('(')[_a = SEG_MOVETO] >> coord (_a,_r1) % lit(',') [_a = SEG_LINETO] >> ')';
|
points = lit('(')[_a = SEG_MOVETO] >> point (_a,_r1) % lit(',') [_a = SEG_LINETO] >> lit(')');
|
||||||
coord = (double_ >> double_) [push_vertex_(_r1,_r2,_1,_2)];
|
// point
|
||||||
|
point = (double_ >> double_) [push_vertex_(_r1,_r2,_1,_2)];
|
||||||
|
|
||||||
// <empty set>
|
// <empty set>
|
||||||
empty_set = no_case[lit("EMPTY")];
|
empty_set = no_case[lit("EMPTY")];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// start
|
||||||
|
qi::rule<Iterator,boost::ptr_vector<geometry_type>(),ascii::space_type> geometry_tagged_text;
|
||||||
|
|
||||||
qi::rule<Iterator,geometry_type*(),ascii::space_type> start;
|
qi::rule<Iterator,qi::locals<geometry_type*>,boost::ptr_vector<geometry_type>(),ascii::space_type> point_tagged_text;
|
||||||
qi::rule<Iterator,geometry_type*(),ascii::space_type> point;
|
qi::rule<Iterator,qi::locals<geometry_type*>,boost::ptr_vector<geometry_type>(),ascii::space_type> linestring_tagged_text;
|
||||||
qi::rule<Iterator,geometry_type*(),ascii::space_type> multipoint;
|
qi::rule<Iterator,qi::locals<geometry_type*>,boost::ptr_vector<geometry_type>(),ascii::space_type> polygon_tagged_text;
|
||||||
qi::rule<Iterator,geometry_type*(),ascii::space_type> linestring;
|
qi::rule<Iterator,boost::ptr_vector<geometry_type>(),ascii::space_type> multipoint_tagged_text;
|
||||||
qi::rule<Iterator,geometry_type*(),ascii::space_type> multilinestring;
|
qi::rule<Iterator,boost::ptr_vector<geometry_type>(),ascii::space_type> multilinestring_tagged_text;
|
||||||
qi::rule<Iterator,geometry_type*(),ascii::space_type> polygon;
|
qi::rule<Iterator,boost::ptr_vector<geometry_type>(),ascii::space_type> multipolygon_tagged_text;
|
||||||
qi::rule<Iterator,geometry_type*(),ascii::space_type> multipolygon;
|
//
|
||||||
qi::rule<Iterator,void(CommandType,geometry_type*),ascii::space_type> coord;
|
qi::rule<Iterator,void(geometry_type*),ascii::space_type> point_text;
|
||||||
|
qi::rule<Iterator,void(geometry_type*),ascii::space_type> linestring_text;
|
||||||
|
qi::rule<Iterator,void(geometry_type*),ascii::space_type> polygon_text;
|
||||||
|
qi::rule<Iterator, qi::locals<geometry_type*>, boost::ptr_vector<geometry_type>(),ascii::space_type> multipoint_text;
|
||||||
|
qi::rule<Iterator, qi::locals<geometry_type*>, boost::ptr_vector<geometry_type>(),ascii::space_type> multilinestring_text;
|
||||||
|
qi::rule<Iterator, qi::locals<geometry_type*>, boost::ptr_vector<geometry_type>(),ascii::space_type> multipolygon_text;
|
||||||
|
//
|
||||||
|
qi::rule<Iterator,void(CommandType,geometry_type*),ascii::space_type> point;
|
||||||
qi::rule<Iterator,qi::locals<CommandType>,void(geometry_type*),ascii::space_type> points;
|
qi::rule<Iterator,qi::locals<CommandType>,void(geometry_type*),ascii::space_type> points;
|
||||||
qi::rule<Iterator,ascii::space_type> empty_set;
|
qi::rule<Iterator,ascii::space_type> empty_set;
|
||||||
boost::phoenix::function<push_vertex> push_vertex_;
|
boost::phoenix::function<push_vertex> push_vertex_;
|
||||||
boost::phoenix::function<cleanup> cleanup_;
|
boost::phoenix::function<cleanup> cleanup_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
struct wkt_collection_grammar : qi::grammar<Iterator, boost::ptr_vector<geometry_type>(), ascii::space_type>
|
struct wkt_collection_grammar : qi::grammar<Iterator, boost::ptr_vector<mapnik::geometry_type>(), ascii::space_type>
|
||||||
{
|
{
|
||||||
wkt_collection_grammar()
|
wkt_collection_grammar()
|
||||||
: wkt_collection_grammar::base_type(start)
|
: wkt_collection_grammar::base_type(start)
|
||||||
{
|
{
|
||||||
using qi::_1;
|
using qi::_1;
|
||||||
using qi::_val;
|
using qi::_val;
|
||||||
using qi::no_case;
|
using qi::no_case;
|
||||||
using boost::phoenix::push_back;
|
using boost::phoenix::push_back;
|
||||||
start = wkt [push_back(_val,_1)] | no_case[lit("GEOMETRYCOLLECTION")]
|
start = wkt | no_case[lit("GEOMETRYCOLLECTION")]
|
||||||
>> (lit("(") >> *wkt[push_back(_val,_1)] % lit(",") >> lit(")"));
|
>> (lit("(") >> wkt % lit(",") >> lit(")"));
|
||||||
}
|
}
|
||||||
|
|
||||||
qi::rule<Iterator,boost::ptr_vector<geometry_type>(),ascii::space_type> start;
|
qi::rule<Iterator,boost::ptr_vector<mapnik::geometry_type>(),ascii::space_type> start;
|
||||||
wkt_grammar<Iterator> wkt;
|
wkt_grammar<Iterator> wkt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
struct wkt_stream_grammar : qi::grammar<Iterator, boost::ptr_vector<mapnik::geometry_type>(), ascii::space_type>
|
||||||
|
{
|
||||||
|
wkt_stream_grammar()
|
||||||
|
: wkt_stream_grammar::base_type(start)
|
||||||
|
{
|
||||||
|
start = *wkt_collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
qi::rule<Iterator,boost::ptr_vector<mapnik::geometry_type>(),ascii::space_type> start;
|
||||||
|
wkt_collection_grammar<Iterator> wkt_collection;
|
||||||
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#endif // MAPNIK_WKT_GRAMMAR_HPP
|
#endif // MAPNIK_WKT_GRAMMAR_HPP
|
||||||
|
|
|
@ -20,24 +20,23 @@
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
// mapnik
|
||||||
#include <mapnik/wkt/wkt_factory.hpp>
|
#include <mapnik/wkt/wkt_factory.hpp>
|
||||||
#include <mapnik/wkt/wkt_grammar.hpp>
|
#include <mapnik/wkt/wkt_grammar.hpp>
|
||||||
|
// stl
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
std::pair<bool,geometry_type*> from_wkt(std::string const& wkt)
|
bool from_wkt(std::string const& wkt, boost::ptr_vector<geometry_type> & paths)
|
||||||
{
|
{
|
||||||
using namespace boost::spirit;
|
using namespace boost::spirit;
|
||||||
typedef std::string::const_iterator iterator_type;
|
typedef std::string::const_iterator iterator_type;
|
||||||
iterator_type first = wkt.begin();
|
iterator_type first = wkt.begin();
|
||||||
iterator_type last = wkt.end();
|
iterator_type last = wkt.end();
|
||||||
geometry_type * path = 0;
|
mapnik::wkt::wkt_collection_grammar<iterator_type> grammar;
|
||||||
mapnik::wkt::wkt_grammar<iterator_type> grammar;
|
return qi::phrase_parse(first, last, grammar, ascii::space, paths);
|
||||||
bool result = qi::phrase_parse(first, last, grammar, ascii::space,path);
|
|
||||||
return std::make_pair(result, path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue