Logo Search packages:      
Sourcecode: magics++ version File versions  Download package

EpsGraph.cc

Go to the documentation of this file.
/******************************** LICENSE ********************************

 Copyright 2007 European Centre for Medium-Range Weather Forecasts (ECMWF)

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at 

    http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHvisitor WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.

 ******************************** LICENSE ********************************/

/*! \file EpsGraph.cc
    \brief Implementation of the Template class EpsGraph.
    
    Magics Team - ECMWF 2004
    
    Started: Wed 5-May-2004
    
    Changes:
    
*/



#include "EpsGraph.h"
#include "PointsHandler.h"
#include "DateTime.h"
#include "Text.h"
#include "LegendVisitor.h"

//#include "InteractiveSet.h"

#include <locale>

using namespace magics;

string writeDate(DateTime& date, const string& format)
{
      std::locale loc("");

      ostringstream visitor;
      visitor.imbue(loc);

      const std::time_put<char>& facet = std::use_facet<std::time_put<char> >(loc); 

      tm convert = date;
      facet.put(visitor, visitor, ' ', &convert, format.c_str(), format.c_str()+format.length());    

      return visitor.str();
}

void tick(double min, double max, vector<double>& ticks)
{
      float inc;
      int nb = 7;
      float step;
      float log, ws;

      double wmax = std::max(min, max);
      double wmin = std::min(min, max);
      
  //cvisitor << "min=" << min << " max=" << max << endl;
      
      while (nb < 20)
      {
            step = (wmax-wmin)/nb;
            log = log10(step);
            ws = pow(10., int(log));
            inc = ceil(step/ws)*ws;
            //Log::dev() << "Automatic method ---> increment = " << inc << " ---> try base=" << inc/ws << endl;
                  
            if ( wmax-wmin != inc && (inc/ws == 1 || inc/ws == 2 || inc/ws == 5 || inc/ws == 10) ) {
                  //Log::dev() << "Automatic method ---> increment " << inc << " OK! " << endl;
                  break;
            }
            nb++; 
      }
      
      float first = floor(min/inc) *inc; 
      double val = first > min ? first-inc : first;
        bool last = true;
        while (  last )
      { 
            if (val >= max ) last = false;
            ticks.push_back(val);

            //cvisitor << "val->" << val << endl;
             val+=inc;
      }
}
class EmptyEntry : public LegendEntry
{
public:
      EmptyEntry() : LegendEntry("") {}
    void set(const PaperPoint&, BasicGraphicsObjectContainer&) {}
};

class EpsEntry : public LegendEntry
{
public:
      EpsEntry() : LegendEntry("") {}
      void colour(const Colour& colour) { colour_ = colour; }
      void borderColour(const Colour& colour) { border_colour_ = colour; }
      void font(const MagFont& font) { font_ = font; }
      void set(const PaperPoint& point, BasicGraphicsObjectContainer& visitor)
      {

            double x = point.x();
            double y = point.y() - 0.125 ;

      
            Polyline* box  = new Polyline();
            box->setColour(border_colour_);
            box->setFilled(true);
            box->setShading(new FillShadingProperties());
            box->setFillColour(colour_);
            
        

            double width = 0.15;
            double height = 1.5; 
            double top = y+height;
            double bottom = y-height;
            box->push_back(PaperPoint(x-width, y));
            box->push_back(PaperPoint(x-width, top));
            box->push_back(PaperPoint(x+width, top));
            box->push_back(PaperPoint(x+width, y));
            box->push_back(PaperPoint(x-width, y));
            box->push_back(PaperPoint(x-width, bottom));
            box->push_back(PaperPoint(x+width, bottom));
            box->push_back(PaperPoint(x+width, y));
            box->push_back(PaperPoint(x-width, y));
            visitor.push_back(box);
            Polyline* up  = new Polyline();
            up->setColour(border_colour_);
            (*up).push_back(PaperPoint(x, top+height));
            (*up).push_back(PaperPoint(x, top));
            visitor.push_back(up);
            Polyline* down  = new Polyline();
            down->setColour(border_colour_);
            (*down).push_back(PaperPoint(x, bottom));
            (*down).push_back(PaperPoint(x, bottom-height));
            visitor.push_back(down);
            
            // Now the text...
            Text* max  = new Text();
            max->setText("max");
            max->setFont(font_);          
            max->setJustification(MLEFT);
            (*max).push_back(PaperPoint(x + 1*.2, bottom-height));
            visitor.push_back(max);
            
            Text* min  = new Text();
            min->setText("min");
            min->setFont(font_);
            min->setJustification(MLEFT);       
            (*min).push_back(PaperPoint(x + 1*.2, top+height));
            visitor.push_back(min);
        
       
            Text* seventyfive  = new Text();
            seventyfive->setText("75%");
            seventyfive->setFont(font_);
            seventyfive->setJustification(MLEFT);           
            seventyfive->push_back(PaperPoint(x + 1*0.3, bottom));
            visitor.push_back(seventyfive);
            
            Text* fifty  = new Text();
            fifty->setText("median");
            fifty->setFont(font_);
            fifty->setJustification(MLEFT);
            (*fifty).push_back(PaperPoint(x + 1*0.3, y));
            visitor.push_back(fifty);
            
            Text* twentyfive  = new Text();
            twentyfive->setText("25%");
            twentyfive->setFont(font_);
            twentyfive->setJustification(MLEFT);
            twentyfive->push_back(PaperPoint(x + 1*0.3, top));
            visitor.push_back(twentyfive);
      }
      
protected:
      Polyline*  box_;
      Colour colour_;
      Colour border_colour_;
      MagFont font_;
};


class FullEpsEntry : public EpsEntry
{
public:
      FullEpsEntry() {}

      virtual void set(const PaperPoint& point, BasicGraphicsObjectContainer& visitor)
      {
            

            double x = point.x();
            double y = point.y() ;

            Log::dev() << "FulleEps Entry->  [" << x << ", " << y << "]" << endl;
      
            Polyline* box  = new Polyline();
            box->setColour(border_colour_);
            box->setFilled(true);
            box->setFillColour(colour_);
            box->setShading(new FillShadingProperties());

            double width = 1*0.2;
            double height = 1*0.2; 
            double top1 = y+height;
            double bottom1 = y-height;
            double top2 = y+height+height;
            double bottom2 = y-height-height;
            box->push_back(PaperPoint(x-width, y));
            box->push_back(PaperPoint(x-width, top1));
            box->push_back(PaperPoint(x+(width/2), top1));
            box->push_back(PaperPoint(x+(width/2), top2));
            box->push_back(PaperPoint(x-(width/2), top2));
            box->push_back(PaperPoint(x-(width/2), top1));
            box->push_back(PaperPoint(x+width, top1));
            box->push_back(PaperPoint(x+width, y));
            box->push_back(PaperPoint(x-width, y));
            box->push_back(PaperPoint(x-width, bottom1));
            box->push_back(PaperPoint(x+(width/2), bottom1));
            box->push_back(PaperPoint(x+(width/2), bottom2));
            box->push_back(PaperPoint(x-(width/2), bottom2));
            box->push_back(PaperPoint(x-(width/2), bottom1));
            box->push_back(PaperPoint(x+width, bottom1));
            box->push_back(PaperPoint(x+width, y));
            box->push_back(PaperPoint(x-width, y));
            visitor.push_back(box);
            Polyline* up  = new Polyline();
            up->setColour(border_colour_);
            (*up).push_back(PaperPoint(x, top2+height));
            (*up).push_back(PaperPoint(x, top2));
            visitor.push_back(up);
            Polyline* down  = new Polyline();
            down->setColour(border_colour_);
            (*down).push_back(PaperPoint(x, bottom2));
            (*down).push_back(PaperPoint(x, bottom2-height));
            visitor.push_back(down);
            
            // Now the text...
            Text* max  = new Text();
            max->setText("max");
            max->setFont(font_);
            max->setJustification(MLEFT);
            max->push_back(PaperPoint(x + 0.5, bottom2-height));

            visitor.push_back(max);
            
            Text* min  = new Text();
            min->setText("min");
            min->setFont(font_);
            min->setJustification(MLEFT);
            min->push_back(PaperPoint(x + 1*0.5, top2+height));
            visitor.push_back(min);
        
            Text* ninety  = new Text();
            ninety->setText("90%");
            ninety->setFont(font_);
            ninety->setJustification(MLEFT);
            ninety->push_back(PaperPoint(x + 0.5, bottom2));
            visitor.push_back(ninety);
            
            Text* ten  = new Text();
            ten->setText("10%");
            ten->setFont(font_);
            ten->setJustification(MLEFT);
            ten->push_back(PaperPoint(x + 0.5, top2));
            visitor.push_back(ten);
            
            Text* seventyfive  = new Text();
            seventyfive->setText("75%");
            seventyfive->setFont(font_);
            seventyfive->setJustification(MLEFT);
            seventyfive->push_back(PaperPoint(x + 0.75, bottom1));
            visitor.push_back(seventyfive);
            
            Text* fifty  = new Text();
            fifty->setText("median");
            fifty->setFont(font_);
            fifty->setJustification(MLEFT);
            (*fifty).push_back(PaperPoint(x + 0.75, y));
            visitor.push_back(fifty);
            
            Text* twentyfive  = new Text();
            twentyfive->setText("25%");
            twentyfive->setFont(font_);
            twentyfive->setJustification(MLEFT);
            twentyfive->push_back(PaperPoint(x + 0.75, top1));

            visitor.push_back(twentyfive);
      }
};

class WindRoseEntry : public EpsEntry
{
public:
      WindRoseEntry(const Colour& colour) { colour_ = colour; }

      virtual void set(const PaperPoint& point, BasicGraphicsObjectContainer& visitor)
      {
            

            double x = point.x()-0.5;
            double y = point.y() ;

            Log::dev() << "FulleEps Entry->  [" << x << ", " << y << "]" << endl;
      
            
      MagFont font("sansserif", "normal", 0.25);
      font.colour(Colour("Rgb(0.2, 0.2, 0.2)"));
      
      float start = x;
      
      for ( int i = 0; i != 100; i ++ ) { 
          
            Hsl hsl = colour_.hsl();    
        float light = hsl.light_;        
        hsl.light_ += (0.99 - light)*((100-i)/100.);
      Colour colour(hsl);
            
            Polyline* box  = new Polyline();
            box->setColour(colour);
            box->setFilled(true);
            box->setFillColour(colour);
            box->setShading(new FillShadingProperties());
            
            double width = 0.0225;
            double height = 1*0.25; 
            box->push_back(PaperPoint(start, y));
            box->push_back(PaperPoint(start, y+height));
            box->push_back(PaperPoint(start+width, y+height));
            box->push_back(PaperPoint(start+width, y));
            box->push_back(PaperPoint(start, y));           
            visitor.push_back(box);
            
            start+=width;
            
      }
            
            Polyline* box  = new Polyline();
            box->setColour(border_colour_);
            box->setFilled(false);
            
            
            double height = 1*0.25; 
            box->push_back(PaperPoint(x, y));
            box->push_back(PaperPoint(x, y+height));
            box->push_back(PaperPoint(start, y+height));
            box->push_back(PaperPoint(start, y));
            box->push_back(PaperPoint(x, y));         
            visitor.push_back(box);
            
            // Now the text...
            Text* text  = new Text();
            text->setText("0%");
            text->setFont(font_);
            text->setJustification(MLEFT);
            text->push_back(PaperPoint(x, y-0.2));
            visitor.push_back(text);
            text  = new Text();
            text->setText("25%");
            text->setFont(font_);
            text->setJustification(MLEFT);
            text->push_back(PaperPoint(x+0.5, y-0.2));
            visitor.push_back(text);      
            text  = new Text();
            text->setText("50%");
            text->setFont(font_);
            text->setJustification(MLEFT);
            text->push_back(PaperPoint(x+1, y-0.2));
            visitor.push_back(text);      
            text  = new Text();
            text->setText("75%");
            text->setFont(font_);
            text->setJustification(MLEFT);
            text->push_back(PaperPoint(x+1.5, y-0.2));
            visitor.push_back(text);
            text  = new Text();
            text->setText("100%");
            text->setFont(font_);
            text->setJustification(MLEFT);
            text->push_back(PaperPoint(x+2, y-0.2));
            visitor.push_back(text);            
            
            
            
            
      }
      string text_;
      
};


class WaveRoseEntry : public EpsEntry
{
public:
      WaveRoseEntry(vector<Colour>& colour) { colours_ = colour; }

      virtual void set(const PaperPoint& point, BasicGraphicsObjectContainer& visitor)
      {

            double x = point.x();
            double y = point.y() ;

            Log::dev() << "FulleEps Entry->  [" << x << ", " << y << "]" << endl;
      
            
      MagFont font("sansserif", "normal", 0.25);
      font.colour(Colour("Rgb(0.2, 0.2, 0.2)"));
      
      float start = x;
      
      
      for ( vector<Colour>::const_iterator colour = colours_.begin(); colour != colours_.end(); ++colour) { 
            
            Polyline* box  = new Polyline();
            box->setColour(*colour);
            box->setFilled(true);
            box->setShading(new FillShadingProperties());
            box->setFillColour(*colour);
            double width = 0.4;
            double height = 1*0.25; 
            box->push_back(PaperPoint(start, y));
            box->push_back(PaperPoint(start, y+height));
            box->push_back(PaperPoint(start+width, y+height));
            box->push_back(PaperPoint(start+width, y));
            box->push_back(PaperPoint(start, y));           
            visitor.push_back(box);
            
            start+=width;
            
      }
            
            Polyline* box  = new Polyline();
            box->setColour(border_colour_);
            box->setFilled(false);
            
            double height = 1*0.25; 
            box->push_back(PaperPoint(x, y));
            box->push_back(PaperPoint(x, y+height));
            box->push_back(PaperPoint(start, y+height));
            box->push_back(PaperPoint(start, y));
            box->push_back(PaperPoint(x, y));         
            visitor.push_back(box);
            
            // Now the text...
            Text* text  = new Text();
            text->setText("1");
            text->setFont(font_);
            text->setJustification(MCENTRE);
            text->push_back(PaperPoint(x+0.35, y-0.2));
            visitor.push_back(text);
            
            text  = new Text();
            text->setText("2.5");
            text->setFont(font_);
            text->setJustification(MCENTRE);
            text->push_back(PaperPoint(x+0.8, y-0.2));
            visitor.push_back(text);      

            text  = new Text();
            text->setText("4");
            text->setFont(font_);
            text->setJustification(MCENTRE);
            text->push_back(PaperPoint(x+1.2, y-0.2));
            visitor.push_back(text);      
            
            text  = new Text();
            text->setText("6");
            text->setFont(font_);
            text->setJustification(MCENTRE);
            text->push_back(PaperPoint(x+1.6, y-0.2));
            visitor.push_back(text);
            
            text  = new Text();
            text->setText("9 m");
            text->setFont(font_);
            text->setJustification(MLEFT);
            text->push_back(PaperPoint(x+2.0, y-0.2));
            visitor.push_back(text);            
            
            
            
            
      }
      string text_;
      vector<Colour> colours_;
      
};


class EpsControl : public LegendEntry
{
public:
      EpsControl(double resolution, const string& type) : LegendEntry("") 
      {
            ostringstream title;
            // carefull here this text is depending of the resolution! 
            Log::dev() << "EpsControl=>resolution" << resolution << endl; 
        int km = maground(40000/(2*(resolution+1)+2));  
            title << "EPS Control(" + tostring(km) + " km)";
            title_ = title.str();
      }
      EpsControl(const string& title) : LegendEntry("") 
      {
            
            title_ = title;
      }
      void set(const PaperPoint& point, BasicGraphicsObjectContainer& visitor)
      {
            

            double x = point.x();
            double y = point.y() - 0.125;
            

            Log::dev() << "Legend at Point[" << point.x() << ", " << point.y() << "]" << endl;
      
            Text* text  = new Text();
            text->addText(title_, Colour("red"),  0.3); // should be customisable
            text->setJustification(MLEFT);
            (*text).push_back(PaperPoint(x + 1*0.04, y));
            visitor.push_back(text);
      }
      
protected:
      string title_;
};


class EpsForecast : public LegendEntry
{
public:
      EpsForecast(double resolution, const string& type) : LegendEntry("") 
      {
            Log::dev() << "EpsForecsat=>resolution" << resolution << endl; 
            ostringstream title;
        int km = maground(40000/(2*(2*resolution+1)+2));        
            title << "High Resolution Deterministic(" + tostring(km) + " km)";
            title_ = title.str();
      }
      
      EpsForecast(const string& title) : LegendEntry("") 
            {
                  
                  title_ = title;
            }     
      void set(const PaperPoint& point, BasicGraphicsObjectContainer& visitor)
      {
      
            

            double x = point.x();
            double y = point.y()- 0.125;

            
            Text* text  = new Text();
            text->addText(title_, Colour("blue"),  0.3); // should be customisable
            text->setJustification(MLEFT);
            (*text).push_back(PaperPoint(x + 1*0.04, y));
            visitor.push_back(text);
      }
      
protected:
      string title_;
};


class EpsCalval1 : public LegendEntry
{
public:
      EpsCalval1(double) : LegendEntry("") 
      {
            ostringstream title;
            //title << "T" << (2*resolution)-1 << " OPS";
        title << "CAL/VAL 1";
            title_ = title.str();
      }
            
      void set(const PaperPoint& point, BasicGraphicsObjectContainer& visitor)
      {
            
      
            
      
            double x = point.x();
            double y = point.y()- 0.125;
            Polyline* line  = new Polyline();
            line->setColour(Colour("green"));
            
            line->setLineStyle(M_SOLID);
            line->setThickness(2);
            line->push_back(PaperPoint(x-1*0.025, y));
            line->push_back(PaperPoint(x+1*0.025, y));
            visitor.push_back(line);
            
            Text* text  = new Text();
            text->setText(title_);
            text->setJustification(MLEFT);
            (*text).push_back(PaperPoint(x + 1*0.04, y));
            visitor.push_back(text);
      }
      
protected:
      string title_;
};

class EpsCalval2 : public LegendEntry
{
public:
      EpsCalval2(double) : LegendEntry("") 
      {
            ostringstream title;
            //title << "T" << (2*resolution)-1 << " OPS";
        title << "CAL/VAL 2";
            title_ = title.str();
      }
            
      void set(const PaperPoint& point, BasicGraphicsObjectContainer& visitor)
      {
            
            
            
      
            double x = point.x();
            double y = point.y()- 0.125;
            Polyline* line  = new Polyline();
            line->setColour(Colour("magenta"));
            
            
            line->setThickness(2);
            line->push_back(PaperPoint(x-1*0.025, y));
            line->push_back(PaperPoint(x+1*0.025, y));
            visitor.push_back(line);
            
            Text* text  = new Text();
            text->addText(title_, Colour("blue"),  0.3); // should be customisable
            text->setJustification(MLEFT);
            (*text).push_back(PaperPoint(x + 1*0.04, y));
            visitor.push_back(text);
      }
      
protected:
      string title_;
};


EpsGraph::EpsGraph() : forecast_(false), control_(false), eps_(true)
{
}


EpsGraph::~EpsGraph() 
{}

/*!
 Class information are given to the visitorput-stream.
*/          
void EpsGraph::print(ostream& visitor)  const
{
      visitor << "EpsGraph[";
      visitor << "]";
}



void EpsGraph::operator()(Data<UserPoint>& data, BasicGraphicsObjectContainer& visitor)
{
      
      CustomisedPointsList points; 
      std::set<string> request;
      data.customisedPoints(request, points);
      const Transformation& transformation = visitor.transformation();
      
      
      if (points.empty()) return;
      
      
      Polyline* control  = new Polyline();
      control->setColour(Colour("red"));
      control->setLineStyle(M_DASH);
      control->setThickness(border_thickness_);
      
      Polyline* forecast  = new Polyline();
      forecast->setColour(Colour("blue"));
      forecast->setThickness(border_thickness_);
    
    
   
      
      

      resolution_ = (*points.front())["resolution"];
      Date date((long)(*points.front())["year"], (long)(*points.front())["month"], (long)(*points.front())["day"]);
      Time time((long)(*points.front())["hours"], (long)(*points.front())["minutes"], (long)(*points.front())["seconds"]);
      
      
      
            
            DateTime base(date, time);
            
      
    vector<BasicGraphicsObject*> list, list2;
    
    
    
    if ( points.size() < 2 ) return;
    fullEps_ = false;
    
    Colour colour = *colour_;
    
      for (CustomisedPointsList::const_iterator point = points.begin(); point != points.end(); ++point) {
            resolution_ = (**point)["resolution"];
            
            double x = (**point)["step"] + (**point)["shift"];
            double width = (box_width_ == -1) ? (**point)["width"] : box_width_ * 3600;
            
            if ( (**point)["right"] ) colour = *right_colour_;
            if ( (**point)["left"] )  colour = *left_colour_;
            
            
            double max = ((*point)->find("max") != (*point)->end()) ? (*point)->find("max")->second : (*point)->find("maximum")->second;
            double min = ((*point)->find("min") != (*point)->end()) ? (*point)->find("min")->second : (*point)->find("minimum")->second;

        
            CustomisedPoint::const_iterator ten   = (*point)->find("ten");
        CustomisedPoint::const_iterator ninty = (*point)->find("ninty");
            
        

        if ( (*point)->find("control") != (*point)->end() &&  (**point)["control"]!= 9999.  )
            control->push_back(PaperPoint(x, (**point)["control"]));          
            if ( (*point)->find("forecast") != (*point)->end() &&  (**point)["forecast"] != 9999.)
            forecast->push_back(PaperPoint(x, (**point)["forecast"]));
        if ( (*point)->find("median") == (*point)->end() )  {           
            eps_ = false;  
            continue;
        }
        if (  (**point)["median"] == 9999. ) {              
                   eps_ = false;  
                   continue;
               }
        
       
            Polyline* box  = new Polyline();
            box->setColour(*border_colour_);
            box->setFilled(true);
            box->setThickness(border_thickness_);
            box->setFillColour(colour);
            box->setShading(new FillShadingProperties());
      
        Polyline* median  = new Polyline();
        median->setColour(*median_colour_);
        
        box->push_back(PaperPoint(x-width, (**point)["median"]));
            box->push_back(PaperPoint(x-width, (**point)["seventyfive"]));
        
        if ( ninty != (*point)->end() ) {
            fullEps_ = true;
            box->push_back(PaperPoint(x+(width/2), (**point)["seventyfive"]));
            box->push_back(PaperPoint(x+(width/2), ninty->second) );
            box->push_back(PaperPoint(x-(width/2), ninty->second));
            box->push_back(PaperPoint(x-(width/2), (**point)["seventyfive"]));
            
        }
            box->push_back(PaperPoint(x+width, (**point)["seventyfive"]));
            box->push_back(PaperPoint(x+width, (**point)["median"]));
            box->push_back(PaperPoint(x-width, (**point)["median"]));
            box->push_back(PaperPoint(x-width, (**point)["twentyfive"]));
        if ( ten != (*point)->end() ) {
            box->push_back(PaperPoint(x+(width/2), (**point)["twentyfive"]));
            box->push_back(PaperPoint(x+(width/2), ten->second));
            box->push_back(PaperPoint(x-(width/2), ten->second));
            box->push_back(PaperPoint(x-(width/2), (**point)["twentyfive"]));
            
        }
           
            box->push_back(PaperPoint(x+width, (**point)["twentyfive"]));
            box->push_back(PaperPoint(x+width, (**point)["median"]));
            box->push_back(PaperPoint(x-width, (**point)["median"]));
            median->push_back(PaperPoint(x+width, (**point)["median"]));
            median->push_back(PaperPoint(x-width, (**point)["median"]));
            
            
            Polyline* top  = new Polyline();
            top->setColour(*border_colour_);
            top->setThickness(border_thickness_);
            
           
            (*top).push_back(PaperPoint(x, max > transformation.getMaxY() ? transformation.getMaxY() : max));
            
            if ( ninty != (*point)->end() ) 
            (*top).push_back(PaperPoint(x, ninty->second));
        else 
            (*top).push_back(PaperPoint(x, (**point)["seventyfive"]));
            Polyline* bottom  = new Polyline();
            bottom->setColour(*border_colour_);
            bottom->setThickness(border_thickness_);
            (*bottom).push_back(PaperPoint(x, min));
        if ( ten != (*point)->end() ) 
            (*bottom).push_back(PaperPoint(x, ten->second));
            else 
           (*bottom).push_back(PaperPoint(x, (**point)["twentyfive"]));
            
            if (whisker_) {
            visitor.push_back(box);
                visitor.push_back(top);
                visitor.push_back(bottom);
                visitor.push_back(median);
            }
            
            // find the max! 
            vector<double> ypos;
             for (CustomisedPointsList::const_iterator point = points.begin(); point != points.end(); ++point) {
                        double max = ((*point)->find("max") != (*point)->end()) ? (*point)->find("max")->second : (*point)->find("maximum")->second;
                        double min = ((*point)->find("min") != (*point)->end()) ? (*point)->find("min")->second : (*point)->find("minimum")->second;
                    ypos.push_back(max);
                        ypos.push_back(min);
                        if ( (*point)->find("control") != (*point)->end() )
                              ypos.push_back((**point)["control"]);
                      if ( (*point)->find("forecast") != (*point)->end() )
                            ypos.push_back((**point)["forecast"]);
                
                }
            
                double maxy = *std::max_element(ypos.begin(), ypos.end());
                maxy = ( max_ > int_MIN ) ? max_ : maxy;
                double maxlabel = int_MIN;
                                if (max > maxy) 
                                          maxlabel = max;
                                if (min > maxy) 
                                          maxlabel = min; 
       
       
       if ( max > transformation.getMaxY() ) {
             Text* label = new Text();
             MagFont font(max_font_name_, max_font_style_, max_font_size_);
             font.colour(*max_font_colour_);          
             label->setText(tostring(maground(max)));
             label->setFont(font);
             label->push_back(PaperPoint(x, transformation.getMaxY()*1.05));
             visitor.push_back(label);
       }

             
       }
            
      
      
      if ( !control->empty() && whisker_) {           
            transformation(*control, visitor);
            control_ = true;
      }
      else 
            control_ = false;
      if ( !forecast->empty() && deterministic_) {                            
            transformation(*forecast, visitor);
            forecast_ = true;
      }
      else
            forecast_ = false;
      
      

      
            

}

void EpsGraph::visit(LegendVisitor& legend)
{
      
    
      EpsEntry* entry = fullEps_ ? new FullEpsEntry() : new EpsEntry();
      
    entry->colour(*colour_);
      entry->borderColour(*border_colour_);
      
    MagFont font(font_);
    font.style(font_style_);
      font.size(font_size_);
      font.colour(*font_colour_);
      entry->font(font);
      if ( whisker_ && eps_ ) 
        legend.add(entry);
      
     
    if ( control_  )   {
      Log::dev() << "LEGEND-> " << legend_control_text_ << endl;
      if (legend_control_text_.empty() )
            legend.add(new EpsControl(resolution_, legend_resolution_));
      else 
            legend.add(new EpsControl(legend_control_text_));
    }
    if ( forecast_  ) {
      if (legend_forecast_text_.empty() )
          legend.add(new EpsForecast(resolution_, legend_resolution_));
      else 
          legend.add(new EpsForecast(legend_forecast_text_));
    }
      
   
}



void triangle2(const pair<string, float>& direction, CustomisedPoint& point, BasicGraphicsObjectContainer& visitor, double pos, double max)
{

      
      double shift = 3.14*0.125;
      
      Polyline* poly = new Polyline();

      poly->setThickness(2);
      
      double c = 1 - point[direction.first]/200;
      
      ostringstream colour;
      colour << "Rgb(" << c << ", " << c << ", " << c << ")" << endl; 
      
      poly->setFillColour(colour.str());  
      poly->setColour(Colour("Rgb(0.5, 0.5, 0.5)"));
      
      double length = 9*3600;
      double x0 = length;
//    double y0 = 0;
//    double a = length *tan(shift);
//    double b = length *tan(-shift);
      
      double x = x0 * cos(direction.second);
      double y = x0 * sin(direction.second);
      double x1 = x0 * cos(direction.second - shift);
      double y1 = x0 * sin(direction.second - shift);
      double x2 = x0 * cos(direction.second + shift);
      double y2 = x0 * sin(direction.second + shift);
      
      double xs = 0;
      double ys = 0;
      
      if ( point[direction.first] == max) {
            xs = 3*3600 * cos(direction.second);
            ys = 3*3600 * sin(direction.second);
      }
      
      poly->push_back(PaperPoint(pos + xs , ys ));    
      poly->push_back(PaperPoint(pos + xs + x1, ys + y1));
      poly->push_back(PaperPoint(pos + xs + x, ys + y));
      poly->push_back(PaperPoint(pos + xs + x2, ys + y2));
      poly->push_back(PaperPoint(pos + xs, ys));      
      
      poly->setFilled(true);
      poly->setShading(new FillShadingProperties());
      
      visitor.push_back(poly);

    if ( int(point[direction.first]/2) < 5 ) return;
    Text* text = new Text();
      MagFont font("sansserif", "normal", 0.25);
      font.colour(Colour("Rgb(0.2, 0.2, 0.2)"));
      text->setFont(font);
      text->setText( tostring(int(point[direction.first]/2)) );
            
            text->push_back(PaperPoint(pos + 11*3600 * cos(direction.second), 11.5*3600 * sin(direction.second)));
            visitor.push_back(text);
            
    
}

void triangle3(const Colour& colour, const Colour& border, const pair<string, float>& direction, CustomisedPoint& point, BasicGraphicsObjectContainer& visitor, double pos, double max)
{
    
    Hsl hsl = colour.hsl();
    
    float light = hsl.light_;
   
    hsl.light_ += (0.99 - light)*((point["total"]- point[direction.first])/point["total"]);
     
      
      double shift = 3.14*0.125;
      
      Polyline* poly = new Polyline();
      poly->setThickness(1);
      
      
      poly->setFillColour(Colour(hsl));   
      poly->setColour(border);
      
      double length =  (point[direction.first]*(12*3600)/max);
      double x0 = length;
//    double y0 = 0;
//    double a = length *tan(shift);
//    double b = length *tan(-shift);
      
      double x = x0 * cos(direction.second);
      double y = x0 * sin(direction.second);
      double x1 = x0 * cos(direction.second - shift);
      double y1 = x0 * sin(direction.second - shift);
      double x2 = x0 * cos(direction.second + shift);
      double y2 = x0 * sin(direction.second + shift);
      
      double xs = 0;
      double ys = 0;
      
      
      poly->push_back(PaperPoint(pos + xs , ys ));    
      poly->push_back(PaperPoint(pos + xs + x1, ys + y1));
      poly->push_back(PaperPoint(pos + xs + x, ys + y));
      poly->push_back(PaperPoint(pos + xs + x2, ys + y2));
      poly->push_back(PaperPoint(pos + xs, ys));      
      
      poly->setFilled(true);
      poly->setShading(new FillShadingProperties());
      
      visitor.push_back(poly);

    if ( int(point[direction.first]/2) < 5 ) return;
    Text* text = new Text();
      MagFont font("sansserif", "normal", 0.25);
      font.colour(Colour("Rgb(0.2, 0.2, 0.2)"));
      text->setFont(font);
      text->setText( tostring(int(point[direction.first]/2)) );
            
            text->push_back(PaperPoint(pos + 11*3600 * cos(direction.second), 11.5*3600 * sin(direction.second)));
            visitor.push_back(text);
            
    
}

void triangle4(const Colour& colour, const Colour& border, const pair<string, float>& direction, CustomisedPoint& point, BasicGraphicsObjectContainer& visitor, double pos, double max)
{
    
    Hsl hsl = colour.hsl();
    
    float light = hsl.light_;
   
    hsl.light_ += (0.99 - light)*((point["total"]- point[direction.first])/point["total"]);
     
      
      double shift = 3.14*0.125;
      
      Polyline* poly = new Polyline();
      poly->setThickness(1);
      
      
      poly->setFillColour(Colour(hsl));   
      poly->setColour(border);
      
      double r = 12*3600;
      double val = point[direction.first];
      double factor = r*r/max;
      
      
      
      double length =  sqrt(val*factor);
      double x0 = length;
//    double y0 = 0;
//    double a = length *tan(shift);
//    double b = length *tan(-shift);
      
      double x = x0 * cos(direction.second);
      double y = x0 * sin(direction.second);
      double x1 = x0 * cos(direction.second - shift);
      double y1 = x0 * sin(direction.second - shift);
      double x2 = x0 * cos(direction.second + shift);
      double y2 = x0 * sin(direction.second + shift);
      
      double xs = 0;
      double ys = 0;
      
      
      poly->push_back(PaperPoint(pos + xs , ys ));    
      poly->push_back(PaperPoint(pos + xs + x1, ys + y1));
      poly->push_back(PaperPoint(pos + xs + x, ys + y));
      poly->push_back(PaperPoint(pos + xs + x2, ys + y2));
      poly->push_back(PaperPoint(pos + xs, ys));      
      
      poly->setFilled(true);
      poly->setShading(new FillShadingProperties());
      
      visitor.push_back(poly);

    if ( int(point[direction.first]/2) < 5 ) return;
    Text* text = new Text();
      MagFont font("sansserif", "normal", 0.25);
      font.colour(Colour("Rgb(0.2, 0.2, 0.2)"));
      
      text->setText( tostring(int(point[direction.first]/2)) );
      text->setFont(font);
            
            text->push_back(PaperPoint(pos + 11*3600 * cos(direction.second), 11.5*3600 * sin(direction.second)));
            //visitor.push_back(text);
            
    
}




void triangle(const pair<string, float>& direction, CustomisedPoint& point, BasicGraphicsObjectContainer& visitor, double pos, double)
{

      if ( !point[direction.first] ) return; 
      double shift = 3.14*0.125;
      
      //cvisitor << "Triangle---->" << direction.first << "=" << point[direction.first] << " " << scale << endl;
      Polyline* poly = new Polyline();

      poly->setThickness(2);
      poly->setFillColour(Colour("Rgb(0.7, 0.7, 0.7)"));    
            poly->setColour(Colour("Rgb(0.5, 0.5, 0.5)"));
      
      double length = point[direction.first];
      
      if ( length > 100) 
            length = ((3 * length /100 ) + 6 )*3600;
      else 
            if ( length >  50 )
                  length = ((3 *length/50) + 3 ) *3600;
            else
                  length = (6*length/50) *3600;
      
            

      double x0 = length;

      
      double x = x0 * cos(direction.second);
      double y = x0 * sin(direction.second);
      double x1 = x0 * cos(direction.second - shift);
      double y1 = x0 * sin(direction.second - shift);
      double x2 = x0 * cos(direction.second + shift);
      double y2 = x0 * sin(direction.second + shift);
      
      poly->push_back(PaperPoint(pos, 0));      
      poly->push_back(PaperPoint(pos + x1, y1));
      poly->push_back(PaperPoint(pos + x, y));
      poly->push_back(PaperPoint(pos + x2, y2));
      poly->push_back(PaperPoint(pos, 0));      
      
      poly->setFilled(true);
      poly->setShading(new FillShadingProperties());
      
      Polyline* median = new Polyline();
      median->setColour(Colour("black"));
      median->setThickness(1);
      median->push_back(PaperPoint(pos, 0));    
      median->push_back(PaperPoint(pos+x, y));  
      
      
      visitor.push_back(poly);
      
    
}


void EpsWind::operator()(Data<UserPoint>& data, BasicGraphicsObjectContainer& visitor)
{ 
      CustomisedPointsList points; 
      std::set<string> request;
      data.customisedPoints(request, points);
      if (points.empty()) return;
      

      

      
      Date date((long)(*points.front())["year"], (long)(*points.front())["month"], (long)(*points.front())["day"]);
      Time time((long)(*points.front())["hours"], (long)(*points.front())["minutes"], (long)(*points.front())["seconds"]);
      DateTime base(date, time);

      
    
      
      
      map<string, float> directions;
      if ( magCompare(convention_, "oceanographic" ) ) {
            directions["east"] = 0 + 3.14;
            directions["nord"] = 3.14 * 0.5 +3.14;
            directions["nord_east"] = 3.14*0.25  +3.14;
            directions["nord_west"] = 3.14*0.75 +3.14;
            directions["south"] = 3.14*1.5 +3.14;
            directions["south_east"] = 3.14*1.75 +3.14;
            directions["south_west"] = 3.14*1.25 +3.14;
            directions["west"] = 3.14 +3.14;
      }
      else {
            directions["east"] = 0;
            directions["nord"] = 3.14 * 0.5;
            directions["nord_east"] = 3.14*0.25;
            directions["nord_west"] = 3.14*0.75;
            directions["south"] = 3.14*1.5;
            directions["south_east"] = 3.14*1.75;
            directions["south_west"] = 3.14*1.25;
            directions["west"] = 3.14;
      }
      
      for (CustomisedPointsList::const_iterator point = points.begin(); point != points.end(); ++point) {         
            double total = 0;
            for ( map<string, float>::const_iterator direction = directions.begin(); direction != directions.end(); ++direction) {
                  
                  if ( (*point)->find(direction->first) == (*point)->end() ) {
                        vector<string> classification;
                        classification.push_back("one");
                        classification.push_back("two");
                        classification.push_back("three");
                        classification.push_back("four");
                        classification.push_back("five");
                        classification.push_back("six");
                        double val = 0;
                        for ( vector<string>::const_iterator key = classification.begin(); key != classification.end(); ++key) {
                              CustomisedPoint::const_iterator value = (*point)->find(direction->first + "_" + *key);
                              if ( value != (*point)->end() ) 
                                    val += ( value->second == 9999.) ? 0 :  value->second;
                        }                 
                        (**point)[direction->first] = val;
                        
                        
                  }
                  total += (**point)[direction->first];
            }
            (**point)["total"] = total;
            
            
            //InteractiveSet* iset = new InteractiveSet();
            //iset->addAction("onmouseover", new InteractiveMagnify(4));
            vector<double> values;
            double scale = 0; 
          
            
    
            for ( map<string, float>::const_iterator direction = directions.begin(); direction != directions.end(); ++direction)
                  values.push_back((**point)[direction->first]);
                  
            double ms = *std::max_element(values.begin(), values.end());
            double x = (**point)["step"] + (**point)["shift"];
      
            
                  Polyline* grid = new Polyline();
                  grid->setColour(Colour("grey"));
                  grid->setThickness(2);
                  grid->setLineStyle(M_DOT);          
                  scale = 200;
                  double l100 = 12*3600;
                  for (float angle = 0; angle <= 2; angle+=0.1)   
                        grid->push_back(PaperPoint(x +(l100 * cos(3.14*angle)) , l100 * sin(3.14*angle)));                          
                  //iset->push_back(grid);
                  
            
            


            visitor.push_back(grid);
            
            
            
      
            for ( map<string, float>::const_iterator direction = directions.begin(); direction != directions.end(); ++direction)
                        triangle4(*colour_, *border_colour_, *direction, **point, visitor, x, ms);
            
      }
      

}

void EpsWave::visit(LegendVisitor& legend)
{
      MagFont font("sansserif", "normal", 0.25);
      font.colour(Colour("Rgb(0.2, 0.2, 0.2)"));
      vector<Colour> colours;
      colours.push_back(Colour("greenish_blue"));
      colours.push_back(Colour("yellow_green"));
      colours.push_back(Colour("greenish_yellow"));
      colours.push_back(Colour("orangish_yellow"));
      colours.push_back(Colour("yellowish_orange"));
      colours.push_back(Colour("reddish_orange"));
      
      WaveRoseEntry* wave = new WaveRoseEntry(colours);
      wave->borderColour(Colour("grey"));       
      wave->font(font);
            
      legend.add(wave);
}

void EpsWind::visit(LegendVisitor& legend)
{
      
      MagFont font("sansserif", "normal", 0.25);
      font.colour(Colour("Rgb(0.2, 0.2, 0.2)"));
      
       WindRoseEntry* wind = new WindRoseEntry(*colour_);
            
            
            
            
            wind->borderColour(*border_colour_);            
            wind->font(font);
            
            legend.add(wind);
    
}
void EpsWind::print(ostream&) const
{
}
void EpsWave::print(ostream&) const
{
}

void triangle5(const pair<string, float>& direction, CustomisedPoint& point, BasicGraphicsObjectContainer& visitor, double pos, double max)
{
      
      vector<Colour> colours;
      colours.push_back(Colour("greenish_blue"));
      colours.push_back(Colour("yellow_green"));
      colours.push_back(Colour("greenish_yellow"));
      colours.push_back(Colour("orangish_yellow"));
      colours.push_back(Colour("yellowish_orange"));
      colours.push_back(Colour("reddish_orange"));
      
      vector<string> forces;
      forces.push_back(direction.first + "_one");
      forces.push_back(direction.first + "_two");
      forces.push_back(direction.first + "_three");
      forces.push_back(direction.first + "_four");
      forces.push_back(direction.first + "_five");
      forces.push_back(direction.first + "_six");
      double total = 0;
      Polyline* poly;
      vector<Colour>::iterator colour = colours.begin();
      Colour border("grey");
      
      double r = 12*3600;
      double factor = r*r/max;
      
      double previous = 0;
      double shift = 3.14*0.125;
      
      for (vector<string>::const_iterator force = forces.begin(); force != forces.end(); ++ force) {
            double count =  point[*force];
            if ( !count ) {
                  colour++; 
                  continue;
            }
            
          poly = new Polyline();
          poly->setThickness(1);
            poly->setFillColour(*colour); 
          poly->setColour(border);
            
            total += count;       
            double length =  sqrt(total*factor);
            double x0 = length;
            
      
            double x = x0 * cos(direction.second);
            double y = x0 * sin(direction.second);
            double x1 = x0 * cos(direction.second - shift);
            double y1 = x0 * sin(direction.second - shift);
            double x2 = x0 * cos(direction.second + shift);
            double y2 = x0 * sin(direction.second + shift);
         
          double px = previous * cos(direction.second);
            double py = previous * sin(direction.second);
            double px1 = previous * cos(direction.second - shift);
            double py1 = previous * sin(direction.second - shift);
            double px2 = previous * cos(direction.second + shift);
            double py2 = previous * sin(direction.second + shift);
            
            previous = x0;
        colour++;
      
          
      
            poly->push_back(PaperPoint(pos + px1 , py1 ));  
            poly->push_back(PaperPoint(pos + x1,  y1));
            poly->push_back(PaperPoint(pos + x,  y));
            poly->push_back(PaperPoint(pos +  x2,  y2));
            poly->push_back(PaperPoint(pos + px2, py2));
            poly->push_back(PaperPoint(pos + px, py));      
            poly->push_back(PaperPoint(pos + px1, py1));    
      
            poly->setFilled(true);
            poly->setShading(new FillShadingProperties());
      
            visitor.push_back(poly);
      }
      
      

        
      
}

void EpsWave::operator()(Data<UserPoint>& data, BasicGraphicsObjectContainer& visitor)
{ 
      CustomisedPointsList points; 
      std::set<string> request;
      data.customisedPoints(request, points);
      if (points.empty()) return;
      

      vector<double> xpos;
      

      
      Date date((long)(*points.front())["year"], (long)(*points.front())["month"], (long)(*points.front())["day"]);
      Time time((long)(*points.front())["hours"], (long)(*points.front())["minutes"], (long)(*points.front())["seconds"]);
      DateTime base(date, time);

       for (CustomisedPointsList::const_iterator point = points.begin(); point != points.end(); ++point) {        
            xpos.push_back((**point)["last"]);          
    }
    
      
      
      map<string, float> directions;
      //if ( magCompare(convention_, "oceanographic" ) ) {
            directions["east"] = 0 + 3.14;
            directions["nord"] = 3.14 * 0.5 +3.14;
            directions["nord_east"] = 3.14*0.25  +3.14;
            directions["nord_west"] = 3.14*0.75 +3.14;
            directions["south"] = 3.14*1.5 +3.14;
            directions["south_east"] = 3.14*1.75 +3.14;
            directions["south_west"] = 3.14*1.25 +3.14;
            directions["west"] = 3.14 +3.14;
//    }
//    else {
//          directions["east"] = 0;
//          directions["nord"] = 3.14 * 0.5;
//          directions["nord_east"] = 3.14*0.25;
//          directions["nord_west"] = 3.14*0.75;
//          directions["svisitorh"] = 3.14*1.5;
//          directions["svisitorh_east"] = 3.14*1.75;
//          directions["svisitorh_west"] = 3.14*1.25;
//          directions["west"] = 3.14;
//    }
      
      for (CustomisedPointsList::const_iterator point = points.begin(); point != points.end(); ++point) {         
            double total = 0;
            for ( map<string, float>::const_iterator direction = directions.begin(); direction != directions.end(); ++direction) {
                  
                  if ( (*point)->find(direction->first) == (*point)->end() ) {
                        vector<string> classification;
                        classification.push_back("one");
                        classification.push_back("two");
                        classification.push_back("three");
                        classification.push_back("four");
                        classification.push_back("five");
                        classification.push_back("six");
                        double val = 0;
                        for ( vector<string>::const_iterator key = classification.begin(); key != classification.end(); ++key) {
                              CustomisedPoint::const_iterator value = (*point)->find(direction->first + "_" + *key);
                              if ( value != (*point)->end() ) 
                                    val += (value->second == 9999) ? 0 : value->second;
                        }                 
                        (**point)[direction->first] = val;
                        
                  }
                  total += (**point)[direction->first];
            }
            (**point)["total"] = (total) ? total : 50;
            
            
            //InteractiveSet* iset = new InteractiveSet();
            //iset->addAction("onmouseover", new InteractiveMagnify(4));
            vector<double> values;
            double scale = 0; 
          
            
    
            for ( map<string, float>::const_iterator direction = directions.begin(); direction != directions.end(); ++direction)
                  values.push_back((**point)[direction->first]);
                  
            double ms = *std::max_element(values.begin(), values.end());
            double x = (**point)["step"] + (**point)["shift"];
      
            
                  Polyline* grid = new Polyline();
                  grid->setColour(Colour("grey"));
                  grid->setThickness(2);
                  grid->setLineStyle(M_DOT);          
                  scale = 200;
                  double l100 = 12*3600;
                  for (float angle = 0; angle <= 2; angle+=0.1)   
                        grid->push_back(PaperPoint(x +(l100 * cos(3.14*angle)) , l100 * sin(3.14*angle)));                          
                        visitor.push_back(grid);
                  
      
            

            //visitor.push_back(iset);
            
            
            if (total == 0) continue;
      
            for ( map<string, float>::const_iterator direction = directions.begin(); direction != directions.end(); ++direction)
                  {
                        triangle5(*direction, **point, visitor, x, ms);
                  }
      }
      

}




EfiGraph::EfiGraph() 
{
}

EfiGraph::~EfiGraph()
{
}
void EfiGraph::operator()(Data<UserPoint>& data, BasicGraphicsObjectContainer& visitor)
{

      
        
      CustomisedPointsList points; 
      std::set<string> request;
      data.customisedPoints(request, points);
      
      //cvisitor << "EfiGraph::preparePlot(Data<PaperPoint>& data, visitor&)" << endl;
      
      if (points.empty()) return;
      
      vector<string>::iterator icolour = colour_.begin();
    // First make sure that we have enough colour/style/thicknes
    
    while (style_.size() < colour_.size()) 
        style_.push_back("solid");
    while (thickness_.size() < colour_.size()) 
        thickness_.push_back(2);    
    
      
      
    // First set some defaults!
      



    
      
      
      Polyline* efi  = new Polyline();
          efi->setColour(*clim_colour_);
          efi->setLineStyle(clim_style_);
          efi->setThickness(clim_thickness_);
          vector<double> clim;
            for (CustomisedPointsList::const_iterator point = points.begin(); point != points.end(); ++point) {         
                  
                  vector<double> steps;
                  for ( int i = 0; i <=100; i++) {              
                        ostringstream key;
                        key << "clim_" << i;
                        map<string, double>::const_iterator step = (*point)->find(key.str());
                        if (step != (*point)->end() ) {
                    //Log::dev() << key.str() << ":" << step->second << "-->" << i << endl;
                              efi->push_back(PaperPoint(step->second, i));
                              clim.push_back(step->second);
                }
                  }                 
            
            }
            
            visitor.push_back(efi);
            const Transformation& transformation = visitor.transformation();
            
            Polyline* box = new Polyline();
            box->setColour(Colour("navy"));
            box->setFilled(true);      
            box->setFillColour(Colour("white"));      
                  
            FillShadingProperties* shading = new FillShadingProperties();          

            box->setShading(shading);
            
            double w = 1.5*( transformation.getMaxX() - transformation.getMinX() )/ visitor.absoluteWidth();
            
            box->push_back(PaperPoint(transformation.getMaxX(), 43));
            box->push_back(PaperPoint(transformation.getMaxX()-w, 43));
            box->push_back(PaperPoint(transformation.getMaxX()-w, 57));
            box->push_back(PaperPoint(transformation.getMaxX(), 57));
            box->push_back(PaperPoint(transformation.getMaxX(), 43));
            
            
            
            Text* mint = new Text();
            mint->setJustification(MLEFT);            
            mint->push_back(PaperPoint(transformation.getMaxX()-(w*.95), 46));
            
            Text* maxt = new Text();
            maxt->push_back(PaperPoint(transformation.getMaxX()-(w*0.95), 52));
            maxt->setJustification(MLEFT);
            
            if ( !clim.empty() ) {
                  vector<double>::const_iterator min = std::min_element(clim.begin(), clim.end());
                  vector<double>::const_iterator max = std::max_element(clim.begin(), clim.end());
                  maxt->addText("Max: " +  tostring(maground(*max)) , Colour("navy"), 0.3);
                  mint->addText("Min : " +  tostring(maground(*min)) , Colour("navy"), 0.3);
            }
            else {
                  maxt->addText("Max: ?" , Colour("navy"), 0.3);
                  mint->addText( "Min : ?", Colour("navy"), 0.3);
            }
        
            
      vector<string>::iterator style = style_.begin();
      vector<int>::iterator thickness = thickness_.begin();
   
      vector<BasicGraphicsObject*> sorter;
      int step = 1;
    while ( icolour != colour_.end() ) {
      Colour colour(*icolour);
      
      
    
      
      Polyline* efi  = new Polyline();
          efi->setColour(colour);
          efi->setLineStyle(Translator<string, LineStyle>()(*style));
          efi->setThickness(*thickness);
          ++thickness;
        ++style;
            for (CustomisedPointsList::const_iterator point = points.begin(); point != points.end(); ++point) {         
                  
                  vector<double> steps;
                  for ( int i = 0; i <=100; i++) {              
                        ostringstream key;
                        key << step << "_" << i;
                        map<string, double>::const_iterator step = (*point)->find(key.str());
                        if (step != (*point)->end() ) {
                    //Log::dev() << key.str() << ":" << step->second << "-->" << i << endl;
                              efi->push_back(PaperPoint(step->second, i));
                }
                  }                 
            
            }
            
            if ( !efi->empty() ) {        
                  sorter.push_back(efi);
                  usedColours_.push_back(*icolour);
            }
            else 
                  delete efi;
            legend_.push_back(data.legend());
      
            // go to next step!
                ++icolour;
                step++;
            }
    
    // Here we revert the curve to have the fisrt plotted last! 
        for ( vector<BasicGraphicsObject*>::reverse_iterator object = sorter.rbegin(); object != sorter.rend(); ++object) 
            visitor.push_back(*object);
            
        visitor.push_back(box);
            visitor.push_back(mint);
            visitor.push_back(maxt);

}


void EfiGraph::visit(LegendVisitor& legend)

{

      
      vector<string>::iterator style = style_.begin();
      vector<int>::iterator thickness = thickness_.begin();
    
    Polyline* efi  = new Polyline();
            efi->setColour(*clim_colour_);
            efi->setLineStyle(clim_style_);
            efi->setThickness(clim_thickness_);
            LineEntry* entry = new LineEntry("", efi);
            
            legend.add(entry);    
      for (vector<string>::iterator colour = usedColours_.begin(); colour != usedColours_.end(); ++colour) {
            Polyline* efi  = new Polyline();
            efi->setColour(Colour(*colour));
            
       
        efi->setLineStyle(Translator<string, LineStyle>()(*style));
            efi->setThickness(*thickness);
            LineEntry* entry = new LineEntry("", efi);
            entry->setTextPosition(-0.07);
            legend.add(entry);
        ++thickness;
        ++style;
      }
      

}

void EpsShade::operator()(Data<UserPoint>& data, BasicGraphicsObjectContainer& visitor)
{
      CustomisedPointsList points; 
      std::set<string> request;
      data.customisedPoints(request, points);
      
      if (points.empty()) return;

    
      Polyline* first  = new Polyline();  
      first->setLineStyle(line_style_);
      first->setThickness(line_thickness_);
      first->setFilled(true);
      first->setShading(new FillShadingProperties());
    
    Polyline* firstmin = first->getNew();
    Polyline* firstmax = first->getNew();
    
    Colour cmin = Colour("sky");
    Colour cmax = Colour("RGB(1.0, 0.222, 0.222)");
    
    Polyline* second  = new Polyline();
      
      second->setLineStyle(line_style_);
      second->setThickness(line_thickness_);
      second->setFilled(true);
      second->setShading(new FillShadingProperties());
      Polyline* secondmin = second->getNew();
    Polyline* secondmax = second->getNew();
    
    
      Polyline* median  = new Polyline();
      median->setLineStyle(line_style_);
      median->setThickness(line_thickness_);
    
    Polyline* medianmin = median->getNew();
    Polyline* medianmax = median->getNew();
   
      Polyline* backtop  = new Polyline();
      //backtop->setLineStyle(M_DASH);
      backtop->setThickness(2);
    backtop->setColour(*colour_);
    Polyline* backtopmin = backtop->getNew();
    Polyline* backtopmax = backtop->getNew();
    backtopmin->setColour(cmin);
    backtopmax->setColour(cmax);
   
    Polyline* backbottom  = new Polyline();
      //backbottom->setLineStyle(M_DOT);
      backbottom->setThickness(2);
    backbottom->setColour(*colour_);
    
    Polyline* backbottommin = backbottom->getNew();
    Polyline* backbottommax = backbottom->getNew();
    
    backbottommin->setColour(cmin);
    backbottommax->setColour(cmax);
    
    Hsl hsl = colour_->hsl();  
    Hsl hslmin = cmin.hsl(); 
    Hsl hslmax = cmax.hsl(); 
    
    float step = (0.9 - hsl.light_)/3.;
    median->setColour(Colour(hsl));
    medianmin->setColour(Colour(hslmin));
    medianmax->setColour(Colour(hslmax));
    
    hsl.light_ += 2*step;     
    hslmin.light_ += 2*step; 
    hslmax.light_ += 2*step; 
    second->setFillColour(Colour(hsl));
    second->setColour(Colour(hsl));
    secondmin->setFillColour(Colour(hslmin));
    secondmin->setColour(Colour(hslmin));
    secondmax->setFillColour(Colour(hslmax));
    secondmax->setColour(Colour(hslmax));
    
    hsl.light_ += step;
    hslmin.light_ += step; 
    hslmax.light_ += step; 
    first->setFillColour(Colour(hsl));   
    first->setColour(Colour(hsl));
    firstmin->setFillColour(Colour(hslmin));   
    firstmin->setColour(Colour(hslmin));
    firstmax->setFillColour(Colour(hslmax));   
    firstmax->setColour(Colour(hslmax));
    
      
      Date date((long)(*points.front())["year"], (long)(*points.front())["month"], (long)(*points.front())["day"]);
      Time time((long)(*points.front())["hours"], (long)(*points.front())["minutes"], (long)(*points.front())["seconds"]);
      
      
      
            
      DateTime base(date, time);

   
    
    
    
    
      vector<PaperPoint> ten, tenmin, tenmax;
      vector<PaperPoint> ninty, nintymin, nintymax;;
      vector<PaperPoint> twentyfive, twentyfivemin, twentyfivemax;
      vector<PaperPoint> seventyfive, seventyfivemin, seventyfivemax;
    vector<PaperPoint> one, onemin, onemax;
      vector<PaperPoint> ninetynine, ninetyninemin, ninetyninemax;
    
    
    
      for (CustomisedPointsList::const_iterator point = points.begin(); point != points.end(); ++point) {
            
            double x = (**point)["step"];
            
        
            
            CustomisedPoint::const_iterator y1 = (*point)->find("1");       
            CustomisedPoint::const_iterator y10 = (*point)->find("10");
        CustomisedPoint::const_iterator y90 = (*point)->find("90");
        CustomisedPoint::const_iterator y99 = (*point)->find("99");  
            CustomisedPoint::const_iterator y50 = (*point)->find("50");
            CustomisedPoint::const_iterator y25 = (*point)->find("25");
            CustomisedPoint::const_iterator y75 = (*point)->find("75");
        if ( (**point)["tmin"] ) {        
            tenmin.push_back(PaperPoint(x, y10->second));
                nintymin.push_back(PaperPoint(x, y90->second));
                twentyfivemin.push_back(PaperPoint(x, y25->second));
                seventyfivemin.push_back(PaperPoint(x, y75->second));
                medianmin->push_back(PaperPoint(x, y50->second));
            onemin.push_back(PaperPoint(x, y1->second));
            ninetyninemin.push_back(PaperPoint(x, y99->second));
        }
        else if ( (**point)["tmax"] ) {
            tenmax.push_back(PaperPoint(x, y10->second));
                nintymax.push_back(PaperPoint(x, y90->second));
                twentyfivemax.push_back(PaperPoint(x, y25->second));
                seventyfivemax.push_back(PaperPoint(x, y75->second));
                medianmax->push_back(PaperPoint(x, y50->second));
            onemax.push_back(PaperPoint(x, y1->second));
            ninetyninemax.push_back(PaperPoint(x, y99->second));
        }
        else {
            ten.push_back(PaperPoint(x, y10->second));
                ninty.push_back(PaperPoint(x, y90->second));
                twentyfive.push_back(PaperPoint(x, y25->second));
                seventyfive.push_back(PaperPoint(x, y75->second));
                median->push_back(PaperPoint(x, y50->second));
            one.push_back(PaperPoint(x, y1->second));
            ninetynine.push_back(PaperPoint(x, y99->second));
        }
     }
        
     
      
     for (vector<PaperPoint>::iterator point = one.begin(); point != one.end(); ++point) 
      backbottom->push_back(*point); 
     for (vector<PaperPoint>::reverse_iterator point = ninetynine.rbegin(); point != ninetynine.rend(); ++point)
      backtop->push_back(*point);
     for (vector<PaperPoint>::iterator point = ten.begin(); point != ten.end(); ++point)
      first->push_back(*point);
     for (vector<PaperPoint>::reverse_iterator point = ninty.rbegin(); point != ninty.rend(); ++point)
      first->push_back(*point);     
     if ( !first->empty() )
        first->push_back(first->front());      
       for (vector<PaperPoint>::iterator point = twentyfive.begin(); point != twentyfive.end(); ++point)
      second->push_back(*point);
     for (vector<PaperPoint>::reverse_iterator point = seventyfive.rbegin(); point != seventyfive.rend(); ++point)
      second->push_back(*point);          
     if ( !second->empty() )
        second->push_back(second->front());
     
     for (vector<PaperPoint>::iterator point = onemin.begin(); point != onemin.end(); ++point) 
      backbottommin->push_back(*point); 
     for (vector<PaperPoint>::reverse_iterator point = ninetyninemin.rbegin(); point != ninetyninemin.rend(); ++point)
      backtopmin->push_back(*point);
     for (vector<PaperPoint>::iterator point = tenmin.begin(); point != tenmin.end(); ++point)
      firstmin->push_back(*point);
     for (vector<PaperPoint>::reverse_iterator point = nintymin.rbegin(); point != nintymin.rend(); ++point)
      firstmin->push_back(*point);     
     if ( !firstmin->empty() ) 
        firstmin->push_back(firstmin->front());      
       for (vector<PaperPoint>::iterator point = twentyfivemin.begin(); point != twentyfivemin.end(); ++point)
      secondmin->push_back(*point);
     for (vector<PaperPoint>::reverse_iterator point = seventyfivemin.rbegin(); point != seventyfivemin.rend(); ++point)
      secondmin->push_back(*point);       
     if ( !secondmin->empty() )
        secondmin->push_back(secondmin->front());
     
     for (vector<PaperPoint>::iterator point = onemax.begin(); point != onemax.end(); ++point) 
      backbottommax->push_back(*point); 
     for (vector<PaperPoint>::reverse_iterator point = ninetyninemax.rbegin(); point != ninetyninemax.rend(); ++point)
      backtopmax->push_back(*point);
     for (vector<PaperPoint>::iterator point = tenmax.begin(); point != tenmax.end(); ++point)
      firstmax->push_back(*point);
     for (vector<PaperPoint>::reverse_iterator point = nintymax.rbegin(); point != nintymax.rend(); ++point)
      firstmax->push_back(*point);     
     if ( !firstmax->empty() ) 
        firstmax->push_back(firstmax->front());      
       for (vector<PaperPoint>::iterator point = twentyfivemax.begin(); point != twentyfivemax.end(); ++point)
      secondmax->push_back(*point);
     for (vector<PaperPoint>::reverse_iterator point = seventyfivemax.rbegin(); point != seventyfivemax.rend(); ++point)
      secondmax->push_back(*point);       
     if ( !secondmax->empty() ) 
        secondmax->push_back(secondmax->front());
     
   
   
    if ( !first->empty() ) visitor.push_back(first);
      if ( !second->empty() ) visitor.push_back(second);
      
    if ( !firstmin->empty() ) visitor.push_back(firstmin);
      if ( !secondmin->empty() ) visitor.push_back(secondmin);
    
      
    if ( !firstmax->empty() ) visitor.push_back(firstmax);
      if ( !secondmax->empty() ) visitor.push_back(secondmax);
    
      if ( !median->empty() ) visitor.push_back(median);
    if ( !medianmin->empty() ) visitor.push_back(medianmin);
    if ( !medianmax->empty() ) visitor.push_back(medianmax);
    
    if ( !backbottom->empty() ) visitor.push_back(backbottom);
    if ( !backtop->empty() ) visitor.push_back(backtop);
    if ( !backbottommin->empty() ) visitor.push_back(backbottommin);
    if ( !backtopmin->empty() ) visitor.push_back(backtopmin);
    if ( !backbottommax->empty() ) visitor.push_back(backbottommax);
    if ( !backtopmax->empty() ) visitor.push_back(backtopmax);
    
      
}
class EpsShadeEntry : public LegendEntry
{
public:
      EpsShadeEntry() : LegendEntry("") 
      {
            
      }
            
      void set(const PaperPoint& point, BasicGraphicsObjectContainer& visitor)
      {
        if (!first_) return;
            
        first_ = false;
        double x = point.x();
            double y = point.y();
        
      
        double height1=0.6;
        double height2=0.4;
        double height3=0.2;
        double width = 0.4;
        double xtext= x+0.7;
        
        
            
      
            
        Colour colour("grey");
        Polyline* median  = new Polyline();
            median->setColour(colour);          
            median->setLineStyle(M_SOLID);
            median->setThickness(4);
            median->push_back(PaperPoint(x-width, y));
            median->push_back(PaperPoint(x+width, y));
        
        Polyline* top  = new Polyline();
            top->setColour(colour);       
            top->setLineStyle(M_DASH);
            top->setThickness(2);
            top->push_back(PaperPoint(x-width, y+height1));
            top->push_back(PaperPoint(x+width, y+height1));
        
        Polyline* bottom  = new Polyline();
            bottom->setColour(colour);          
            bottom->setLineStyle(M_DASH);
            bottom->setThickness(2);
        bottom->push_back(PaperPoint(x-width, y-height1));
            bottom->push_back(PaperPoint(x+width, y-height1));
        
        Hsl hsl = colour.hsl();
        float step = (0.9 - hsl.light_)/3.;
        
       
        hsl.light_ += 2*step;
        
        Polyline* second  = new Polyline();       
          second->setFilled(true);
          second->setShading(new FillShadingProperties());
        second->setFillColour(Colour(hsl));
        second->setColour(Colour(hsl));
        second->push_back(PaperPoint(x-width, y-height3));
            second->push_back(PaperPoint(x+width, y-height3));
        second->push_back(PaperPoint(x+width, y+height3));
            second->push_back(PaperPoint(x-width, y+height3));
        
        hsl.light_ += step;
        
        Polyline* first  = new Polyline();       
          first->setFilled(true);
          first->setShading(new FillShadingProperties());
        first->setFillColour(Colour(hsl));
        first->setColour(Colour(hsl));
        first->push_back(PaperPoint(x-width, y-height2));
            first->push_back(PaperPoint(x+width, y-height2));
        first->push_back(PaperPoint(x+width, y+height2));
            first->push_back(PaperPoint(x-width, y+height2));
        
    
    
      
         
   
      
            
        visitor.push_back(first);
        visitor.push_back(second);
        
            visitor.push_back(top);
        visitor.push_back(bottom);
            visitor.push_back(median);
        
        Text* text  = new Text();
            text->setText("M-Climate");
        text->setFont(font_);
            
            text->push_back(PaperPoint(x+0.4, y-0.8));
            visitor.push_back(text);
        
        Text* text99  = new Text();
            text99->setText("99%");
            text99->setFont(font_);
            text99->setJustification(MLEFT);
            text99->push_back(PaperPoint(xtext, y-height1));
            visitor.push_back(text99);  
        
        Text* text90  = new Text();
            text90->setText("90%");
            text90->setFont(font_);
            text90->setJustification(MLEFT);
            text90->push_back(PaperPoint(xtext, y-height2));
            visitor.push_back(text90);
        
        Text* text75  = new Text();
            text75->setText("75%");
            text75->setFont(font_);
            text75->setJustification(MLEFT);
            text75->push_back(PaperPoint(xtext, y-height3));
            visitor.push_back(text75);
        
            Text* text50  = new Text();
            text50->setText("median");
            text50->setFont(font_);
            text50->setJustification(MLEFT);
            text50->push_back(PaperPoint(xtext, y));
            visitor.push_back(text50);
        
        Text* text25  = new Text();
            text25->setText("25%");
            text25->setFont(font_);
            
            text25->setJustification(MLEFT);
            text25->push_back(PaperPoint(xtext, y+height3));
            visitor.push_back(text25);
        
        Text* text10  = new Text();
            text10->setText("10%");
            text10->setFont(font_);
      
            text10->setJustification(MLEFT);
            text10->push_back(PaperPoint(xtext, y+height2));
            visitor.push_back(text10);
        
        Text* text1  = new Text();
            text1->setText("1%");
        text1->setFont(font_);
      
            text1->setJustification(MLEFT);
            text1->push_back(PaperPoint(xtext, y+height1));
            visitor.push_back(text1);
      
      }
    
    MagFont font_;
      
protected:
      static bool first_;
};

bool EpsShadeEntry::first_ = true;

void EpsShade::visit(LegendVisitor& legend)
{
    EpsShadeEntry *entry = new EpsShadeEntry();
    entry->font_ = MagFont("sansserif");
    entry->font_.size(0.25);
    entry->font_.colour(Colour("Rgb(0.2, 0.2, 0.2)"));
    legend.add(entry);
}

EpsShade::EpsShade()
{
}

EpsShade::~EpsShade()
{
}

bool alldigit(const string& name)
{
      for (string::const_iterator c = name.begin(); c != name.end(); ++c)
            if ( !isdigit(*c) ) return false;
      return true;
} 

void EpsDirection::operator()(Data<UserPoint>& data, BasicGraphicsObjectContainer& visitor)
{
    CustomisedPointsList points; 
      std::set<string> request;
      data.customisedPoints(request, points);
      if (points.empty()) return;
            
      Date date((long)(*points.front())["year"], (long)(*points.front())["month"], (long)(*points.front())["day"]);
      Time time((long)(*points.front())["hours"], (long)(*points.front())["minutes"], (long)(*points.front())["seconds"]);
      DateTime base(date, time);
      
      
      for (CustomisedPointsList::const_iterator point = points.begin(); point != points.end(); ++point) {         
      
        
            
            
            
            //InteractiveSet* iset = new InteractiveSet();
            //iset->addAction("onmouseover", new InteractiveMagnify(4));
                  
                  
            
                double x = (**point)["step"] + (**point)["shift"];
                
                if ( (**point)[keyword_] == 9999 ) continue;
                
              double angle = ((2*3.14) - (((**point)[keyword_]-90)/180) * 3.14) + 3.14;
            
                  Polyline* grid = new Polyline();
                  grid->setColour(*line_colour_);
                  grid->setThickness(line_thickness_);
                  grid->setLineStyle(line_style_);          
                  
                  double l100 = 12*3600;
            grid->push_back(PaperPoint(x +(l100 * cos(angle)) , l100 * sin(angle)));      
            
            grid->push_back(PaperPoint(x, 0));  
                  
                              
                  visitor.push_back(grid); //iset->push_back(grid);
                  
            
            

            

            //visitor.push_back(iset);
            
            
            
            
      }
      
}

void EpsPlume::operator()(Data<UserPoint>& data, BasicGraphicsObjectContainer& visitor)
{
      
      CustomisedPointsList points; 
      std::set<string> request;
      data.customisedPoints(request, points);
      
      
      if (points.empty()) return;
      
      
      
      
   
            

      map<string, Polyline* > lines;
      Polyline* control  = new Polyline();
      control->setColour(*control_line_colour_);
    control->setThickness(control_line_thickness_);
    control->setLineStyle(control_line_style_);
      
    Polyline* forecast  = new Polyline();
      forecast->setColour(*forecast_line_colour_);
        forecast->setThickness(forecast_line_thickness_);
        forecast->setLineStyle(forecast_line_style_);
      
     
      for (CustomisedPointsList::const_iterator point = points.begin(); point != points.end(); ++point) {
            
            double x = (**point)["step"] + (**point)["shift"];
      
           
      
        for ( map<string, double>::const_iterator value = (*point)->begin(); value != (*point)->end(); ++value) {
            if ( alldigit(value->first) ) {
                  map<string, Polyline* >::iterator  iline = lines.find(value->first);
                  if ( iline == lines.end() ) {
                        Polyline* line  = new Polyline();
                              line->setColour(*line_colour_);
                        line->setThickness(line_thickness_);
                              line->setLineStyle(line_style_);
                              lines[value->first] = line;
                              iline = lines.find(value->first);
                  }
                  (iline->second)->push_back(PaperPoint(x, value->second));
                  
            }
            
            if ( value->first == "forecast" ) 
                  forecast->push_back(PaperPoint(x, value->second));
            if ( value->first == "control" ) 
                  control->push_back(PaperPoint(x, value->second));
            
        }
        
       
      
      }
      
       for ( map<string, Polyline* >::const_iterator line = lines.begin(); line != lines.end(); ++line) {
                  visitor.push_back(line->second);
        }
       visitor.push_back(control);
       visitor.push_back(forecast);
}    
       
      

Generated by  Doxygen 1.6.0   Back to index