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 MARKERS_CONVERTER_HPP
00026 #define MARKERS_CONVERTER_HPP
00027
00028 #include "agg_basics.h"
00029 #include "agg_trans_affine.h"
00030 #include <boost/utility.hpp>
00031
00032 namespace mapnik {
00033 template <typename Locator, typename Shape, typename Detector>
00034 class markers_converter : boost::noncopyable
00035 {
00036 public:
00037 markers_converter(Locator & locator,Shape & shape, Detector & detector);
00038 void rewind(unsigned path_id);
00039 unsigned vertex(double * x, double * y);
00040 private:
00041 enum status_e
00042 {
00043 initial,
00044 markers,
00045 polygon,
00046 stop
00047 };
00048
00049 Locator & locator_;
00050 Shape & shape_;
00051 Detector & detector_;
00052 status_e status_;
00053 agg::trans_affine transform_;
00054 agg::trans_affine mtx_;
00055 unsigned num_markers_;
00056 unsigned marker_;
00057 };
00058
00059 template <typename Locator,typename Shape,typename Detector>
00060 markers_converter<Locator,Shape,Detector>::markers_converter(Locator & locator,Shape & shape,
00061 Detector & detector)
00062 : locator_(locator),
00063 shape_(shape),
00064 detector_(detector),
00065 status_(initial),
00066 num_markers_(1),
00067 marker_(0) {}
00068
00069 template <typename Locator, typename Shape,typename Detector>
00070 void markers_converter<Locator,Shape,Detector>::rewind(unsigned path_id)
00071 {
00072 status_ = initial;
00073 marker_ = 0;
00074 num_markers_ = 1;
00075 }
00076
00077 template <typename Locator, typename Shape, typename Detector>
00078 unsigned markers_converter<Locator,Shape,Detector>::vertex( double * x, double * y)
00079 {
00080 unsigned cmd = agg::path_cmd_move_to;
00081
00082 double x1, y1, x2, y2;
00083 while (!agg::is_stop(cmd))
00084 {
00085 switch (status_)
00086 {
00087 case initial:
00088 if (num_markers_ == 0 )
00089 {
00090 cmd = agg::path_cmd_stop;
00091 break;
00092 }
00093 locator_.rewind(marker_++);
00094 status_ = markers;
00095 num_markers_ = 0;
00096 break;
00097 case markers:
00098 {
00099 unsigned cmd1;
00100 while (agg::is_move_to(cmd1 = locator_.vertex(&x1,&y1)));
00101 if (agg::is_stop(cmd1))
00102 {
00103 status_ = stop;
00104 break;
00105 }
00106 unsigned cmd2 = locator_.vertex(&x2,&y2);
00107 if (agg::is_stop(cmd2))
00108 {
00109 status_ = stop;
00110 break;
00111 }
00112
00113
00114 ++num_markers_;
00115 double dx = x2 - x1;
00116 double dy = y2 - y1;
00117 double d = ::sqrt(dx * dx + dy * dy);
00118 Envelope<double> ext = shape_.extent();
00119 if (d > ext.width())
00120 {
00121 mtx_ = transform_;
00122 mtx_ *= agg::trans_affine_rotation(::atan2(dy,dx));
00123 double marker_x = x1 + dx * 0.5;
00124 double marker_y = y1 + dy * 0.5;
00125
00126 mtx_ *= agg::trans_affine_translation(marker_x,marker_y);
00127
00128 double minx = ext.minx();
00129 double miny = ext.miny();
00130 double maxx = ext.maxx();
00131 double maxy = ext.maxy();
00132 mtx_.transform(&minx,&miny);
00133 mtx_.transform(&maxx,&maxy);
00134
00135 Envelope<double> e0(minx,miny,maxx,maxy);
00136
00137 if (detector_.has_placement(e0))
00138 {
00139 shape_.rewind(0);
00140 status_ = polygon;
00141 detector_.insert(ext);
00142 }
00143 }
00144
00145 break;
00146 }
00147 case polygon:
00148 cmd = shape_.vertex(x,y);
00149 if (agg::is_stop(cmd))
00150 {
00151 cmd = agg::path_cmd_move_to;
00152 status_ = markers;
00153 break;
00154 }
00155 mtx_.transform(x,y);
00156 return cmd;
00157 case stop:
00158 cmd = agg::path_cmd_stop;
00159 break;
00160 }
00161 }
00162 return cmd;
00163 }
00164 }
00165
00166 #endif // MARKERS_CONVERTER_HPP