00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef FEATURE_STYLE_PROCESSOR_HPP
00026 #define FEATURE_STYLE_PROCESSOR_HPP
00027
00028
00029 #include <vector>
00030
00031 #include <boost/progress.hpp>
00032
00033 #include <mapnik/envelope.hpp>
00034 #include <mapnik/datasource.hpp>
00035 #include <mapnik/layer.hpp>
00036 #include <mapnik/map.hpp>
00037 #include <mapnik/attribute_collector.hpp>
00038 #include <mapnik/utils.hpp>
00039 #include <mapnik/projection.hpp>
00040 #include <mapnik/scale_denominator.hpp>
00041
00042 namespace mapnik
00043 {
00044 template <typename Processor>
00045 class feature_style_processor
00046 {
00047 struct symbol_dispatch : public boost::static_visitor<>
00048 {
00049 symbol_dispatch (Processor & output,
00050 Feature const& f,
00051 proj_transform const& prj_trans)
00052 : output_(output),
00053 f_(f),
00054 prj_trans_(prj_trans) {}
00055
00056 template <typename T>
00057 void operator () (T const& sym) const
00058 {
00059 output_.process(sym,f_,prj_trans_);
00060 }
00061
00062 Processor & output_;
00063 Feature const& f_;
00064 proj_transform const& prj_trans_;
00065 };
00066 public:
00067 feature_style_processor(Map const& m)
00068 : m_(m) {}
00069
00070 void apply()
00071 {
00072 #ifdef MAPNIK_DEBUG
00073 boost::progress_timer t(std::clog);
00074 #endif
00075 Processor & p = static_cast<Processor&>(*this);
00076 p.start_map_processing(m_);
00077
00078 try
00079 {
00080 projection proj(m_.srs());
00081 double scale_denom = scale_denominator(m_,proj.is_geographic());
00082 #ifdef MAPNIK_DEBUG
00083 std::clog << "scale denominator = " << scale_denom << "\n";
00084 #endif
00085 std::vector<Layer>::const_iterator itr = m_.layers().begin();
00086 std::vector<Layer>::const_iterator end = m_.layers().end();
00087
00088 while (itr != end)
00089 {
00090 if (itr->isVisible(scale_denom))
00091 {
00092 apply_to_layer(*itr, p, proj, scale_denom);
00093 }
00094 ++itr;
00095 }
00096 }
00097 catch (proj_init_error& ex)
00098 {
00099 std::clog << ex.what() << "\n";
00100 }
00101
00102 p.end_map_processing(m_);
00103 }
00104 private:
00105 void apply_to_layer(Layer const& lay, Processor & p,
00106 projection const& proj0,double scale_denom)
00107 {
00108 p.start_layer_processing(lay);
00109 boost::shared_ptr<datasource> ds=lay.datasource();
00110 if (ds)
00111 {
00112 Envelope<double> const& ext=m_.getCurrentExtent();
00113
00114 projection proj1(lay.srs());
00115 proj_transform prj_trans(proj0,proj1);
00116
00117 double x0 = ext.minx();
00118 double y0 = ext.miny();
00119 double z0 = 0.0;
00120 double x1 = ext.maxx();
00121 double y1 = ext.maxy();
00122 double z1 = 0.0;
00123 prj_trans.forward(x0,y0,z0);
00124 prj_trans.forward(x1,y1,z1);
00125 Envelope<double> bbox(x0,y0,x1,y1);
00126 #ifdef MAPNIK_DEBUG
00127 std::clog << bbox << "\n";
00128 #endif
00129 std::vector<std::string> const& style_names = lay.styles();
00130 std::vector<std::string>::const_iterator stylesIter = style_names.begin();
00131 std::vector<std::string>::const_iterator stylesEnd = style_names.end();
00132
00133 while (stylesIter != stylesEnd)
00134 {
00135 std::set<std::string> names;
00136 attribute_collector<Feature> collector(names);
00137 std::vector<rule_type*> if_rules;
00138 std::vector<rule_type*> else_rules;
00139
00140 bool active_rules=false;
00141
00142 feature_type_style const& style=m_.find_style(*stylesIter++);
00143
00144 query q(bbox);
00145
00146 const std::vector<rule_type>& rules=style.get_rules();
00147 std::vector<rule_type>::const_iterator ruleIter=rules.begin();
00148 std::vector<rule_type>::const_iterator ruleEnd=rules.end();
00149
00150 while (ruleIter!=ruleEnd)
00151 {
00152 if (ruleIter->active(scale_denom))
00153 {
00154 active_rules=true;
00155 ruleIter->accept(collector);
00156
00157 if (ruleIter->has_else_filter())
00158 {
00159 else_rules.push_back(const_cast<rule_type*>(&(*ruleIter)));
00160 }
00161 else
00162 {
00163 if_rules.push_back(const_cast<rule_type*>(&(*ruleIter)));
00164 }
00165 }
00166 ++ruleIter;
00167 }
00168 std::set<std::string>::const_iterator namesIter=names.begin();
00169 std::set<std::string>::const_iterator namesEnd =names.end();
00170
00171
00172 while (namesIter!=namesEnd)
00173 {
00174 q.add_property_name(*namesIter);
00175 ++namesIter;
00176 }
00177 if (active_rules)
00178 {
00179 featureset_ptr fs=ds->features(q);
00180 if (fs)
00181 {
00182 feature_ptr feature;
00183 while ((feature = fs->next()))
00184 {
00185 bool do_else=true;
00186 std::vector<rule_type*>::const_iterator itr=if_rules.begin();
00187 std::vector<rule_type*>::const_iterator end=if_rules.end();
00188 while (itr != end)
00189 {
00190 filter_ptr const& filter=(*itr)->get_filter();
00191 if (filter->pass(*feature))
00192 {
00193 do_else=false;
00194 const symbolizers& symbols = (*itr)->get_symbolizers();
00195 symbolizers::const_iterator symIter=symbols.begin();
00196 symbolizers::const_iterator symEnd =symbols.end();
00197 while (symIter != symEnd)
00198 {
00199 boost::apply_visitor
00200 (symbol_dispatch(p,*feature,prj_trans),*symIter++);
00201 }
00202 }
00203 ++itr;
00204 }
00205 if (do_else)
00206 {
00207
00208 std::vector<rule_type*>::const_iterator itr=
00209 else_rules.begin();
00210 std::vector<rule_type*>::const_iterator end=
00211 else_rules.end();
00212 while (itr != end)
00213 {
00214 const symbolizers& symbols = (*itr)->get_symbolizers();
00215 symbolizers::const_iterator symIter= symbols.begin();
00216 symbolizers::const_iterator symEnd = symbols.end();
00217
00218 while (symIter!=symEnd)
00219 {
00220 boost::apply_visitor
00221 (symbol_dispatch(p,*feature,prj_trans),
00222 *symIter++);
00223 }
00224 ++itr;
00225 }
00226 }
00227 }
00228 }
00229 }
00230 }
00231
00232 }
00233 p.end_layer_processing(lay);
00234 }
00235 Map const& m_;
00236 };
00237 }
00238
00239 #endif //FEATURE_STYLE_PROCESSOR_HPP