Changeset 660

Show
Ignore:
Timestamp:
02/27/08 13:50:59 (9 months ago)
Author:
tom
Message:

Add support for boolean values in filters, and reading of boolean
values from PostGIS data sources.

Location:
trunk
Files:
1 added
4 modified

Legend:

Unmodified
Added
Removed
  • trunk/include/mapnik/expression.hpp

    r650 r660  
    4646    { 
    4747    public: 
     48        literal(bool val) 
     49            : expression<FeatureT>(), 
     50              value_(val) {} 
    4851        literal(int val) 
    4952            : expression<FeatureT>(), 
  • trunk/include/mapnik/filter_parser.hpp

    r659 r660  
    3434#include <mapnik/filter.hpp> 
    3535#include <mapnik/regex_filter.hpp> 
     36#include <mapnik/boolean_filter.hpp> 
    3637#include <mapnik/logical.hpp> 
    3738 
     
    6061   using std::clog; 
    6162   using std::stack; 
     63 
     64    template <typename FeatureT> 
     65    struct push_boolean 
     66    { 
     67        push_boolean(stack<shared_ptr<expression<FeatureT> > >& exprs) 
     68            : exprs_(exprs) {} 
     69         
     70        void operator() (std::string const& val) const 
     71        { 
     72            if (val == "true") 
     73                exprs_.push(shared_ptr<expression<FeatureT> > 
     74                            ( new literal<FeatureT>(true))); 
     75            else if (val == "false") 
     76                exprs_.push(shared_ptr<expression<FeatureT> > 
     77                            ( new literal<FeatureT>(false))); 
     78        } 
     79        stack<shared_ptr<expression<FeatureT> > >& exprs_; 
     80    }; 
    6281 
    6382   template <typename FeatureT> 
     
    204223         stack<shared_ptr<expression<FeatureT> > >& exprs_; 
    205224   }; 
    206      
     225       
     226   template <typename FeatureT> 
     227   struct compose_boolean_filter 
     228   { 
     229         compose_boolean_filter(stack<shared_ptr<filter<FeatureT> > >& filters, 
     230                                stack<shared_ptr<expression<FeatureT> > >& exprs) 
     231            : filters_(filters),exprs_(exprs) {} 
     232 
     233         template <typename Iter> 
     234         void operator() (Iter,Iter) const 
     235         { 
     236            if (exprs_.size()>=1) 
     237            { 
     238               shared_ptr<expression<FeatureT> > exp = exprs_.top(); 
     239               exprs_.pop(); 
     240               if (exp) 
     241               { 
     242                  filters_.push(shared_ptr<filter<FeatureT> >(new boolean_filter<FeatureT>(*exp))); 
     243               } 
     244            } 
     245         } 
     246         stack<shared_ptr<filter<FeatureT> > >& filters_; 
     247         stack<shared_ptr<expression<FeatureT> > >& exprs_; 
     248   }; 
     249 
    207250   template <typename FeatureT> 
    208251   struct compose_and_filter 
     
    298341                  spatial_op = "Equals","Disjoint","Touches","Within","Overlaps", 
    299342                     "Crosses","Intersects","Contains","DWithin","Beyond","BBOX"; 
    300                    
     343                  boolean_const = "true","false"; 
     344 
    301345                  chset_t BaseChar (L"\x41-\x5A\x61-\x7A\xC0-\xD6\xD8-\xF6\xF8-\xFF\x100-\x131\x134-\x13E" 
    302346                                    L"\x141-\x148\x14A-\x17E\x180-\x1C3\x1CD-\x1F0\x1F4-\x1F5\x1FA-\x217" 
     
    369413                     | CombiningChar  
    370414                     | Extender; 
    371                                  
     415                         
     416                  boolean = boolean_const [push_boolean<FeatureT>(self.exprs)]; 
     417         
    372418                  number = strict_real_p [push_real<FeatureT>(self.exprs)]  
    373419                     | int_p [push_integer<FeatureT>(self.exprs)]; 
     
    376422                                     [push_string<FeatureT>(self.exprs,self.tr)], 
    377423                                     L'\''); 
    378                  
     424 
    379425                  property = L'[' >> ( (Letter | L'_' | L':')  
    380426                                       >> *NameChar )[push_property<FeatureT>(self.exprs)] >> L']'; 
    381427                 
    382                   literal = number | string_ | property; 
     428                  literal = boolean | number | string_ | property; 
    383429                 
    384430                  function = literal | ( func1_op >> L'('>> literal >> L')') |  
     
    416462                                            [compose_filter<FeatureT,not_equals<value> >(self.filters,self.exprs)]); 
    417463 
    418                   not_expr = equation | *(str_p(L"not") >> equation)[compose_not_filter<FeatureT>(self.filters)]; 
     464                  cond_expr = equation | (expression)[compose_boolean_filter<FeatureT>(self.filters,self.exprs)]; 
     465 
     466                  not_expr = cond_expr | *(str_p(L"not") >> cond_expr)[compose_not_filter<FeatureT>(self.filters)]; 
    419467 
    420468                  and_expr = not_expr >> *(L"and" >> not_expr)[compose_and_filter<FeatureT>(self.filters)]; 
     
    430478                  BOOST_SPIRIT_DEBUG_RULE( relation ); 
    431479                  BOOST_SPIRIT_DEBUG_RULE( equation ); 
     480                  BOOST_SPIRIT_DEBUG_RULE( cond_expr ); 
    432481                  BOOST_SPIRIT_DEBUG_RULE( not_expr ); 
    433482                  BOOST_SPIRIT_DEBUG_RULE( and_expr ); 
     
    436485                  BOOST_SPIRIT_DEBUG_RULE( filter_statement );    
    437486                  BOOST_SPIRIT_DEBUG_RULE( literal ); 
     487                  BOOST_SPIRIT_DEBUG_RULE( boolean ); 
    438488                  BOOST_SPIRIT_DEBUG_RULE( number ); 
    439489                  BOOST_SPIRIT_DEBUG_RULE( string_ ); 
     
    454504               boost::spirit::rule<ScannerT> relation; 
    455505               boost::spirit::rule<ScannerT> equation; 
     506               boost::spirit::rule<ScannerT> cond_expr; 
    456507               boost::spirit::rule<ScannerT> not_expr; 
    457508               boost::spirit::rule<ScannerT> and_expr; 
     
    460511               boost::spirit::rule<ScannerT> filter_statement;    
    461512               boost::spirit::rule<ScannerT> literal; 
     513               boost::spirit::rule<ScannerT> boolean; 
    462514               boost::spirit::rule<ScannerT> number; 
    463515               boost::spirit::rule<ScannerT> string_; 
     
    468520               symbols<string> func2_op; 
    469521               symbols<string> spatial_op; 
     522               symbols<string> boolean_const; 
    470523 
    471524 
  • trunk/include/mapnik/value.hpp

    r650 r660  
    2727// mapnik 
    2828#include <mapnik/unicode.hpp> 
     29#include <mapnik/config_error.hpp> 
    2930// boost 
    3031#include <boost/variant.hpp> 
     
    3940namespace mapnik  { 
    4041    
    41    typedef boost::variant<int,double,UnicodeString> value_base; 
     42   typedef boost::variant<bool,int,double,UnicodeString> value_base; 
    4243    
    4344   namespace impl { 
     
    329330            } 
    330331      }; 
    331      
     332         
     333      struct to_bool : public boost::static_visitor<bool> 
     334      { 
     335                 
     336            template <typename T> 
     337            bool operator() (T val) const 
     338            { 
     339               throw config_error("Boolean value expected"); 
     340            } 
     341 
     342            bool operator() (bool val) const 
     343            { 
     344               return val; 
     345            } 
     346      }; 
     347 
    332348      struct to_string : public boost::static_visitor<std::string> 
    333349      { 
     
    493509         } 
    494510 
     511         bool to_bool() const 
     512         { 
     513            return boost::apply_visitor(impl::to_bool(),base_); 
     514         } 
     515 
    495516         std::string to_expression_string() const 
    496517         { 
  • trunk/plugins/input/postgis/postgisfs.cpp

    r657 r660  
    112112              int oid = rs_->getTypeOID(pos); 
    113113            
    114               if (oid==23) //int4 
     114              if (oid==16) //bool 
     115              { 
     116                 boost::put(*feature,name,buf[0] != 0); 
     117              } 
     118              else if (oid==23) //int4 
    115119              { 
    116120                 int val = int4net(buf);