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 <mapnik/envelope.hpp>
00030 #include <mapnik/datasource.hpp>
00031 #include <mapnik/layer.hpp>
00032 #include <mapnik/map.hpp>
00033 #include <mapnik/attribute_collector.hpp>
00034 #include <mapnik/utils.hpp>
00035 #include <mapnik/projection.hpp>
00036 #include <mapnik/scale_denominator.hpp>
00037
00038 #include <boost/progress.hpp>
00039
00040 #include <vector>
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 << "proj_init_error:" << 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 projection proj1(lay.srs());
00114 proj_transform prj_trans(proj0,proj1);
00115
00116 Envelope<double> layer_ext = lay.envelope();
00117 double lx0 = layer_ext.minx();
00118 double ly0 = layer_ext.miny();
00119 double lz0 = 0.0;
00120 double lx1 = layer_ext.maxx();
00121 double ly1 = layer_ext.maxy();
00122 double lz1 = 0.0;
00123
00124 prj_trans.backward(lx0,ly0,lz0);
00125 prj_trans.backward(lx1,ly1,lz1);
00126
00127 lx0 = std::max(ext.minx(),lx0);
00128 ly0 = std::max(ext.miny(),ly0);
00129 lx1 = std::min(ext.maxx(),lx1);
00130 ly1 = std::min(ext.maxy(),ly1);
00131
00132 prj_trans.forward(lx0,ly0,lz0);
00133 prj_trans.forward(lx1,ly1,lz1);
00134 Envelope<double> bbox(lx0,ly0,lx1,ly1);
00135 double resolution = m_.getWidth()/bbox.width();
00136 query q(bbox,resolution);
00137
00138 std::vector<std::string> const& style_names = lay.styles();
00139 std::vector<std::string>::const_iterator stylesIter = style_names.begin();
00140 std::vector<std::string>::const_iterator stylesEnd = style_names.end();
00141 for (;stylesIter != stylesEnd; ++stylesIter)
00142 {
00143 std::set<std::string> names;
00144 attribute_collector<Feature> collector(names);
00145 std::vector<rule_type*> if_rules;
00146 std::vector<rule_type*> else_rules;
00147
00148 bool active_rules=false;
00149 feature_type_style const& style=m_.find_style(*stylesIter);
00150 const std::vector<rule_type>& rules=style.get_rules();
00151 std::vector<rule_type>::const_iterator ruleIter=rules.begin();
00152 std::vector<rule_type>::const_iterator ruleEnd=rules.end();
00153
00154 for (;ruleIter!=ruleEnd;++ruleIter)
00155 {
00156 if (ruleIter->active(scale_denom))
00157 {
00158 active_rules=true;
00159 ruleIter->accept(collector);
00160
00161 if (ruleIter->has_else_filter())
00162 {
00163 else_rules.push_back(const_cast<rule_type*>(&(*ruleIter)));
00164 }
00165 else
00166 {
00167 if_rules.push_back(const_cast<rule_type*>(&(*ruleIter)));
00168 }
00169 }
00170 }
00171 std::set<std::string>::const_iterator namesIter=names.begin();
00172 std::set<std::string>::const_iterator namesEnd =names.end();
00173
00174
00175 for (;namesIter!=namesEnd;++namesIter)
00176 {
00177 q.add_property_name(*namesIter);
00178 }
00179 if (active_rules)
00180 {
00181 featureset_ptr fs=ds->features(q);
00182 if (fs)
00183 {
00184 feature_ptr feature;
00185 while ((feature = fs->next()))
00186 {
00187 bool do_else=true;
00188 std::vector<rule_type*>::const_iterator itr=if_rules.begin();
00189 std::vector<rule_type*>::const_iterator end=if_rules.end();
00190 for (;itr != end;++itr)
00191 {
00192 filter_ptr const& filter=(*itr)->get_filter();
00193 if (filter->pass(*feature))
00194 {
00195 do_else=false;
00196 const symbolizers& symbols = (*itr)->get_symbolizers();
00197 symbolizers::const_iterator symIter=symbols.begin();
00198 symbolizers::const_iterator symEnd =symbols.end();
00199 for (;symIter != symEnd;++symIter)
00200 {
00201 boost::apply_visitor
00202 (symbol_dispatch(p,*feature,prj_trans),*symIter);
00203 }
00204 }
00205 }
00206 if (do_else)
00207 {
00208
00209 std::vector<rule_type*>::const_iterator itr=
00210 else_rules.begin();
00211 std::vector<rule_type*>::const_iterator end=
00212 else_rules.end();
00213 for (;itr != end;++itr)
00214 {
00215 const symbolizers& symbols = (*itr)->get_symbolizers();
00216 symbolizers::const_iterator symIter= symbols.begin();
00217 symbolizers::const_iterator symEnd = symbols.end();
00218
00219 for (;symIter!=symEnd;++symIter)
00220 {
00221 boost::apply_visitor
00222 (symbol_dispatch(p,*feature,prj_trans),*symIter);
00223 }
00224 }
00225 }
00226 }
00227 }
00228 }
00229 }
00230 }
00231 p.end_layer_processing(lay);
00232 }
00233 Map const& m_;
00234 };
00235 }
00236
00237 #endif //FEATURE_STYLE_PROCESSOR_HPP