Changeset 693

Show
Ignore:
Timestamp:
04/12/08 11:22:27 (9 months ago)
Author:
tom
Message:

Revert previous fix for #89 and add a new improved fix that enhances the
value class to have a proper null type and do comparisions SQL style so
that null is neither equal nor not equal to other things.

Location:
trunk
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • trunk/bindings/python/mapnik_feature.cpp

    r650 r693  
    4747            { 
    4848               return ::PyUnicode_FromWideChar((wchar_t*)s.getBuffer(),implicit_cast<ssize_t>(s.length())); 
     49            } 
     50             
     51            PyObject * operator() (mapnik::value_null const& s) const 
     52            { 
     53               return NULL; 
    4954            } 
    5055      }; 
  • trunk/include/mapnik/feature.hpp

    r692 r693  
    121121         } 
    122122           
    123          bool exists(const std::string &k) const 
    124          { 
    125             return props_.find(k) != props_.end(); 
    126          } 
    127  
    128123         std::string to_string() const 
    129124         { 
  • trunk/include/mapnik/value.hpp

    r660 r693  
    4040namespace mapnik  { 
    4141    
    42    typedef boost::variant<bool,int,double,UnicodeString> value_base; 
     42   struct value_null 
     43   { 
     44   }; 
     45    
     46   typedef boost::variant<value_null,bool,int,double,UnicodeString> value_base; 
    4347    
    4448   namespace impl { 
     
    4751      { 
    4852            template <typename T, typename U> 
    49             bool operator() (const T &, const U & ) const 
     53            bool operator() (const T &, const U &) const 
    5054            { 
    5155               return false; 
     
    7377               return  lhs == rhs; 
    7478            } 
     79 
     80            bool operator() (value_null, value_null) const 
     81            { 
     82               return false; 
     83            } 
    7584      }; 
    7685       
     86      struct not_equals 
     87         : public boost::static_visitor<bool> 
     88      { 
     89            template <typename T, typename U> 
     90            bool operator() (const T &, const U &) const 
     91            { 
     92               return true; 
     93            } 
     94         
     95            template <typename T> 
     96            bool operator() (T lhs, T rhs) const 
     97            { 
     98               return lhs != rhs; 
     99            } 
     100             
     101            bool operator() (int lhs, double rhs) const 
     102            { 
     103               return  lhs != rhs; 
     104            } 
     105         
     106            bool operator() (double lhs, int rhs) const 
     107            { 
     108               return  lhs != rhs; 
     109            } 
     110         
     111            bool operator() (UnicodeString const& lhs,  
     112                             UnicodeString const& rhs) const 
     113            { 
     114               return  lhs != rhs; 
     115            } 
     116 
     117            bool operator() (value_null, value_null) const 
     118            { 
     119               return false; 
     120            } 
     121 
     122            template <typename T> 
     123            bool operator() (value_null, const T &) const 
     124            { 
     125               return false; 
     126            } 
     127 
     128            template <typename T> 
     129            bool operator() (const T &, value_null) const 
     130            { 
     131               return false; 
     132            } 
     133      }; 
     134 
    77135      struct greater_than 
    78136         : public boost::static_visitor<bool> 
    79137      { 
    80138            template <typename T, typename U> 
    81             bool operator()( const T &, const U & ) const 
    82             { 
    83                return false; 
    84             } 
    85          
    86             template <typename T> 
    87             bool operator()( T lhs, T rhs ) const 
     139            bool operator()(const T &, const U &) const 
     140            { 
     141               return false; 
     142            } 
     143         
     144            template <typename T> 
     145            bool operator()(T lhs, T rhs) const 
    88146            { 
    89147               return lhs > rhs; 
     
    103161            { 
    104162               return  lhs > rhs; 
     163            } 
     164 
     165            bool operator() (value_null, value_null) const 
     166            { 
     167               return false; 
    105168            } 
    106169      }; 
     
    110173      {  
    111174            template <typename T, typename U> 
    112             bool operator()( const T &, const U & ) const 
     175            bool operator()(const T &, const U &) const 
    113176            { 
    114177               return false; 
     
    131194            } 
    132195         
    133             bool operator() (UnicodeString const& lhs, UnicodeString const& rhs ) const 
     196            bool operator() (UnicodeString const& lhs, UnicodeString const& rhs) const 
    134197            { 
    135198               return lhs >= rhs; 
     199            } 
     200 
     201            bool operator() (value_null, value_null) const 
     202            { 
     203               return false; 
    136204            } 
    137205      }; 
     
    141209      {  
    142210            template <typename T, typename U> 
    143             bool operator()( const T &, const U & ) const 
    144             { 
    145                return false; 
    146             } 
    147          
    148             template <typename T> 
    149             bool operator()( T  lhs,T rhs) const 
     211            bool operator()(const T &, const U &) const 
     212            { 
     213               return false; 
     214            } 
     215         
     216            template <typename T> 
     217            bool operator()(T lhs, T rhs) const 
    150218            { 
    151219               return lhs < rhs; 
     
    162230            } 
    163231         
    164             bool operator()( UnicodeString const& lhs,  
    165                              UnicodeString const& rhs ) const 
     232            bool operator()(UnicodeString const& lhs,  
     233                            UnicodeString const& rhs ) const 
    166234            { 
    167235               return lhs < rhs; 
     236            } 
     237 
     238            bool operator() (value_null, value_null) const 
     239            { 
     240               return false; 
    168241            } 
    169242      }; 
     
    173246      {  
    174247            template <typename T, typename U> 
    175             bool operator()( const T &, const U & ) const 
    176             { 
    177                return false; 
    178             } 
    179          
    180             template <typename T> 
    181             bool operator()(T lhs, T rhs ) const 
     248            bool operator()(const T &, const U &) const 
     249            { 
     250               return false; 
     251            } 
     252         
     253            template <typename T> 
     254            bool operator()(T lhs, T rhs) const 
    182255            { 
    183256               return lhs <= rhs; 
     
    195268         
    196269            template <typename T> 
    197             bool operator()( UnicodeString const& lhs,  
    198                              UnicodeString const& rhs ) const 
     270            bool operator()(UnicodeString const& lhs,  
     271                            UnicodeString const& rhs ) const 
    199272            { 
    200273               return lhs <= rhs; 
     274            } 
     275 
     276            bool operator() (value_null, value_null) const 
     277            { 
     278               return false; 
    201279            } 
    202280      }; 
     
    387465               return ss.str(); 
    388466            } 
    389       }; 
     467             
     468            std::string operator() (value_null const& val) const 
     469            { 
     470               return ""; 
     471            } 
     472       }; 
    390473 
    391474      struct to_unicode : public boost::static_visitor<UnicodeString> 
     
    411494               out << std::setprecision(16) << val; 
    412495               return UnicodeString(out.str().c_str()); 
     496            } 
     497             
     498            UnicodeString operator() (value_null const& val) const 
     499            { 
     500               return UnicodeString(""); 
    413501            } 
    414502      }; 
     
    456544               return ss.str(); 
    457545            } 
     546 
     547            std::string operator() (value_null const& val) const 
     548            { 
     549               return "null"; 
     550            } 
    458551      }; 
    459552   } 
    460      
     553 
    461554   class value 
    462555   { 
     
    469562      public: 
    470563         value () 
    471             : base_(0) {} 
     564            : base_(value_null()) {} 
    472565         
    473566         template <typename T> value(T _val_) 
     
    481574         bool operator!=(value const& other) const 
    482575         { 
    483             return !(boost::apply_visitor(impl::equals(),base_,other.base_)); 
     576            return boost::apply_visitor(impl::not_equals(),base_,other.base_); 
    484577         } 
    485578         
  • trunk/src/agg_renderer.cpp

    r692 r693  
    457457   { 
    458458      typedef  coord_transform2<CoordTransform,geometry2d> path_type; 
    459       if (feature.exists(sym.get_name())) 
    460       { 
    461          UnicodeString text = feature[sym.get_name()].to_unicode(); 
    462          boost::shared_ptr<ImageData32> const& data = sym.get_image(); 
    463          if (text.length() > 0 && data) 
    464          { 
    465             face_ptr face = font_manager_.get_face(sym.get_face_name()); 
    466             if (face) 
     459      UnicodeString text = feature[sym.get_name()].to_unicode(); 
     460      boost::shared_ptr<ImageData32> const& data = sym.get_image(); 
     461      if (text.length() > 0 && data) 
     462      { 
     463         face_ptr face = font_manager_.get_face(sym.get_face_name()); 
     464         if (face) 
     465         { 
     466            text_renderer<mapnik::Image32> ren(pixmap_,face); 
     467            ren.set_pixel_size(sym.get_text_size()); 
     468            ren.set_fill(sym.get_fill()); 
     469             
     470            string_info info(text); 
     471            face->get_string_info(info); 
     472             
     473            placement_finder<label_collision_detector4> finder(detector_); 
     474             
     475            unsigned num_geom = feature.num_geometries(); 
     476            for (unsigned i=0;i<num_geom;++i) 
    467477            { 
    468                text_renderer<mapnik::Image32> ren(pixmap_,face); 
    469                ren.set_pixel_size(sym.get_text_size()); 
    470                ren.set_fill(sym.get_fill()); 
    471              
    472                string_info info(text); 
    473                face->get_string_info(info); 
    474              
    475                placement_finder<label_collision_detector4> finder(detector_); 
    476              
    477                unsigned num_geom = feature.num_geometries(); 
    478                for (unsigned i=0;i<num_geom;++i) 
    479                { 
    480                   geometry2d const& geom = feature.get_geometry(i); 
    481                   if (geom.num_points() > 0) // don't bother with empty geometries 
    482                   { 
    483                      path_type path(t_,geom,prj_trans); 
    484                      placement text_placement(info, sym); 
    485                      text_placement.avoid_edges = sym.get_avoid_edges(); 
    486                      finder.find_point_placements<path_type>(text_placement,path); 
     478               geometry2d const& geom = feature.get_geometry(i); 
     479               if (geom.num_points() > 0) // don't bother with empty geometries  
     480               {     
     481                  path_type path(t_,geom,prj_trans); 
     482                  placement text_placement(info, sym); 
     483                  text_placement.avoid_edges = sym.get_avoid_edges(); 
     484                  finder.find_point_placements<path_type>(text_placement,path); 
    487485                   
    488                      for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii) 
    489                      { 
    490                         int w = data->width(); 
    491                         int h = data->height(); 
     486                  for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii) 
     487                  {  
     488                     int w = data->width(); 
     489                     int h = data->height(); 
    492490                      
    493                         double x = text_placement.placements[ii].starting_x; 
    494                         double y = text_placement.placements[ii].starting_y; 
     491                     double x = text_placement.placements[ii].starting_x; 
     492                     double y = text_placement.placements[ii].starting_y; 
    495493                      
    496                         int px=int(x - (w/2)); 
    497                         int py=int(y - (h/2)); 
     494                     int px=int(x - (w/2)); 
     495                     int py=int(y - (h/2)); 
    498496                      
    499                         pixmap_.set_rectangle_alpha(px,py,*data); 
     497                     pixmap_.set_rectangle_alpha(px,py,*data); 
    500498                      
    501                         Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]); 
     499                     Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]); 
    502500                         
    503                         ren.render(x,y); 
    504                      } 
     501                     ren.render(x,y); 
    505502                  } 
    506503               } 
     
    669666   { 
    670667      typedef  coord_transform2<CoordTransform,geometry2d> path_type; 
    671  
    672       if (feature.exists(sym.get_name())) 
    673       { 
    674          UnicodeString text = feature[sym.get_name()].to_unicode(); 
    675          if ( text.length() > 0 ) 
    676          { 
    677             Color const& fill  = sym.get_fill(); 
    678             face_ptr face = font_manager_.get_face(sym.get_face_name()); 
    679             if (face) 
     668       
     669      UnicodeString text = feature[sym.get_name()].to_unicode(); 
     670      if ( text.length() > 0 ) 
     671      { 
     672         Color const& fill  = sym.get_fill(); 
     673         face_ptr face = font_manager_.get_face(sym.get_face_name()); 
     674         if (face) 
     675         { 
     676            text_renderer<mapnik::Image32> ren(pixmap_,face); 
     677            ren.set_pixel_size(sym.get_text_size()); 
     678            ren.set_fill(fill); 
     679            ren.set_halo_fill(sym.get_halo_fill()); 
     680            ren.set_halo_radius(sym.get_halo_radius()); 
     681            
     682            placement_finder<label_collision_detector4> finder(detector_); 
     683            
     684            string_info info(text); 
     685            face->get_string_info(info); 
     686            unsigned num_geom = feature.num_geometries(); 
     687            for (unsigned i=0;i<num_geom;++i) 
    680688            { 
    681                text_renderer<mapnik::Image32> ren(pixmap_,face); 
    682                ren.set_pixel_size(sym.get_text_size()); 
    683                ren.set_fill(fill); 
    684                ren.set_halo_fill(sym.get_halo_fill()); 
    685                ren.set_halo_radius(sym.get_halo_radius()); 
    686             
    687                placement_finder<label_collision_detector4> finder(detector_); 
    688             
    689                string_info info(text); 
    690                face->get_string_info(info); 
    691                unsigned num_geom = feature.num_geometries(); 
    692                for (unsigned i=0;i<num_geom;++i) 
     689               geometry2d const& geom = feature.get_geometry(i); 
     690               if (geom.num_points() > 0) // don't bother with empty geometries  
    693691               { 
    694                   geometry2d const& geom = feature.get_geometry(i); 
    695                   if (geom.num_points() > 0) // don't bother with empty geometries 
     692                  path_type path(t_,geom,prj_trans); 
     693                  placement text_placement(info,sym);   
     694                  if (sym.get_label_placement() == POINT_PLACEMENT)  
    696695                  { 
    697                      path_type path(t_,geom,prj_trans); 
    698                      placement text_placement(info,sym); 
    699                      if (sym.get_label_placement() == POINT_PLACEMENT) 
    700                      { 
    701                         double label_x, label_y, z=0.0; 
    702                         geom.label_position(&label_x, &label_y); 
    703                         prj_trans.backward(label_x,label_y, z); 
    704                         t_.forward(&label_x,&label_y); 
    705                         finder.find_point_placement(text_placement,label_x,label_y); 
    706                      } 
    707                      else //LINE_PLACEMENT 
    708                      { 
    709                         finder.find_line_placements<path_type>(text_placement,path); 
    710                      } 
     696                     double label_x, label_y, z=0.0; 
     697                     geom.label_position(&label_x, &label_y); 
     698                     prj_trans.backward(label_x,label_y, z); 
     699                     t_.forward(&label_x,&label_y); 
     700                     finder.find_point_placement(text_placement,label_x,label_y); 
     701                  } 
     702                  else //LINE_PLACEMENT 
     703                  { 
     704                     finder.find_line_placements<path_type>(text_placement,path); 
     705                  } 
    711706                   
    712                      for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ii) 
    713                      { 
    714                         double x = text_placement.placements[ii].starting_x; 
    715                         double y = text_placement.placements[ii].starting_y; 
    716                         Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]); 
    717                         ren.render(x,y); 
    718                      } 
     707                  for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ii) 
     708                  { 
     709                     double x = text_placement.placements[ii].starting_x; 
     710                     double y = text_placement.placements[ii].starting_y; 
     711                     Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]); 
     712                     ren.render(x,y); 
    719713                  } 
    720714               } 
    721             } 
    722             else 
    723             { 
    724                throw config_error("Unable to find specified font face '" + sym.get_face_name() + "'"); 
    725             } 
     715            }   
     716         } 
     717         else 
     718         { 
     719            throw config_error("Unable to find specified font face '" + sym.get_face_name() + "'"); 
    726720         } 
    727721      } 
  • trunk/src/cairo_renderer.cpp

    r692 r693  
    751751      typedef coord_transform2<CoordTransform,geometry2d> path_type; 
    752752 
    753       if (feature.exists(sym.get_name())) 
    754       { 
    755          UnicodeString text = feature[sym.get_name()].to_unicode(); 
    756          boost::shared_ptr<ImageData32> const& data = sym.get_image(); 
    757  
    758          if (text.length() > 0 && data) 
    759          { 
    760             cairo_face_ptr face = face_manager_.get_face(sym.get_face_name()); 
    761  
    762             if (face) 
    763             { 
    764                cairo_context context(context_); 
    765  
    766                context.set_font_face(face); 
    767  
    768                string_info info(text); 
    769  
    770                face->get_string_info(sym.get_text_size(), info); 
    771  
    772                placement_finder<label_collision_detector4> finder(detector_); 
    773  
    774                for (unsigned i = 0; i < feature.num_geometries(); ++i) 
    775                { 
    776                   geometry2d const& geom = feature.get_geometry(i); 
    777  
    778                   if (geom.num_points() > 0) // don't bother with empty geometries 
     753      UnicodeString text = feature[sym.get_name()].to_unicode(); 
     754      boost::shared_ptr<ImageData32> const& data = sym.get_image(); 
     755 
     756      if (text.length() > 0 && data) 
     757      { 
     758         cairo_face_ptr face = face_manager_.get_face(sym.get_face_name()); 
     759 
     760         if (face) 
     761         { 
     762            cairo_context context(context_); 
     763 
     764            context.set_font_face(face); 
     765 
     766            string_info info(text); 
     767 
     768            face->get_string_info(sym.get_text_size(), info); 
     769 
     770            placement_finder<label_collision_detector4> finder(detector_); 
     771 
     772            for (unsigned i = 0; i < feature.num_geometries(); ++i) 
     773            { 
     774               geometry2d const& geom = feature.get_geometry(i); 
     775 
     776               if (geom.num_points() > 0) // don't bother with empty geometries 
     777               { 
     778                  path_type path(t_, geom, prj_trans); 
     779                  placement text_placement(info, sym); 
     780 
     781                  text_placement.avoid_edges = sym.get_avoid_edges(); 
     782                  finder.find_point_placements<path_type>(text_placement, path); 
     783 
     784                  for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii) 
    779785                  { 
    780                      path_type path(t_, geom, prj_trans); 
    781                      placement text_placement(info, sym); 
    782  
    783                      text_placement.avoid_edges = sym.get_avoid_edges(); 
    784                      finder.find_point_placements<path_type>(text_placement, path); 
    785  
    786                      for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii) 
    787                      { 
    788                         double shield_x = text_placement.placements[ii].starting_x - data->width() / 2; 
    789                         double shield_y = text_placement.placements[ii].starting_y - data->height() / 2; 
    790  
    791                         context.add_image(shield_x, shield_y, *data); 
    792                         context.add_text(sym, text_placement.placements[ii], face); 
    793                      } 
     786                     double shield_x = text_placement.placements[ii].starting_x - data->width() / 2; 
     787                     double shield_y = text_placement.placements[ii].starting_y - data->height() / 2; 
     788 
     789                     context.add_image(shield_x, shield_y, *data); 
     790                     context.add_text(sym, text_placement.placements[ii], face); 
    794791                  } 
    795792               } 
     
    928925      typedef coord_transform2<CoordTransform,geometry2d> path_type; 
    929926 
    930       if (feature.exists(sym.get_name())) 
    931       { 
    932          UnicodeString text = feature[sym.get_name()].to_unicode(); 
    933  
    934          if (text.length() > 0) 
    935          { 
    936             cairo_face_ptr face = face_manager_.get_face(sym.get_face_name()); 
    937  
    938             if (face) 
    939             { 
    940                cairo_context context(context_); 
    941  
    942                context.set_font_face(face); 
    943  
    944                string_info info(text); 
    945  
    946                face->get_string_info(sym.get_text_size(), info); 
    947  
    948                placement_finder<label_collision_detector4> finder(detector_); 
    949  
    950                for (unsigned i = 0; i < feature.num_geometries(); ++i) 
    951                { 
    952                   geometry2d const& geom = feature.get_geometry(i); 
    953  
    954                   if (geom.num_points() > 0) // don't bother with empty geometries 
     927      UnicodeString text = feature[sym.get_name()].to_unicode(); 
     928 
     929      if (text.length() > 0) 
     930      { 
     931         cairo_face_ptr face = face_manager_.get_face(sym.get_face_name()); 
     932 
     933         if (face) 
     934         { 
     935            cairo_context context(context_); 
     936 
     937            context.set_font_face(face); 
     938 
     939            string_info info(text); 
     940 
     941            face->get_string_info(sym.get_text_size(), info); 
     942 
     943            placement_finder<label_collision_detector4> finder(detector_); 
     944 
     945      &n