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

XmlMagics.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,
 WITHOUT 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 XmlMagics.cc
    \brief Implementation of the Template class XmlMagics.
    \author Graphics Section, ECMWF

    Started: Apr-2007

*/

#include "magics_ecmwf_log.h"
#include "XmlMagics.h"
#include "XmlReader.h"
#include "Exception.h"
#include "Timer.h"

#include "RootSceneNode.h"
#include "SceneNode.h"
#include "ViewNode.h"
#include "Coastlines.h"
#include "BinaryObject.h"

#include "TaylorGrid.h"
#include "GribDecoder.h"
#include "NetcdfDecoder.h"
#include "VisualAction.h"
#include "XYList.h"
#include "LandgramDecoder.h"
#include "LandgramBox.h"
#include "ImagePlotting.h"
#include "SymbolPlotting.h"
#include "Contour.h"
#include "Wind.h"
#include "Histogram.h"
#include "DataConverter.h"
#include "LegendVisitor.h"
#include "TextVisitor.h"

#include "UserPoint.h"
#include "GeoPoint.h"
#include "Axis.h"
#include "MatrixTestDecoder.h"

#include "SimplePolylineInput.h"
#include "SimplePolylineVisualiser.h"

#include "MetaData.h"
#include "ThreadNode.h"


#ifdef MAGICS_SPOT
#include "EpsGraph.h"
#include "EpsgramDecoder.h"
#include "ClassicMtgDecoder.h"
#include "MetgramGraph.h"
#endif

using namespace magics;

XmlMagics::XmlMagics() : root_(0),
      gribloop_(0), 
      geographical_(true), 
      driversToSet_(true)
{
      if(getEnvVariable("MAGPLUS_HOME").empty())
      {
            Log::error() << "FATAL ERROR: $MAGPLUS_HOME has to be defined!!!"<< "\n";
            exit(0);
      }

      writeLog("magml");

      actions_["magics"] = &XmlMagics::magics;
      actions_["page"] = &XmlMagics::page;
      
      actions_["binary"] = &XmlMagics::binary;

      actions_["text"] = &XmlMagics::text;
      actions_["map"] = &XmlMagics::map;
      actions_["matrix"] = &XmlMagics::matrix;
      actions_["cartesian"] = &XmlMagics::cartesian;
      actions_["taylor"] = &XmlMagics::cartesian;
      actions_["cylindrical"] = &XmlMagics::geographical;
      actions_["polar_stereographic"] = &XmlMagics::geographical;

      actions_["horizontal_axis"] = &XmlMagics::horizontalAxis;
      actions_["vertical_axis"] = &XmlMagics::verticalAxis;
      actions_["coastlines"] = &XmlMagics::coastlines;
      actions_["taylorgrid"] = &XmlMagics::taylor;

      actions_["grib"] = &XmlMagics::grib;
      actions_["netcdf"] = &XmlMagics::netcdf;

      actions_["odb"] = &XmlMagics::oda;
      actions_["xyinput"] = &XmlMagics::xyinput;
      actions_["landgram"] = &XmlMagics::landgram;

      actions_["wind"] = &XmlMagics::wind;
      actions_["image"] = &XmlMagics::image;
      actions_["symbol"] = &XmlMagics::symbol;  
      actions_["contour"] = &XmlMagics::contour;
      actions_["histogram"] = &XmlMagics::histogram;
      actions_["landgrambox"] = &XmlMagics::landgrambox;
      actions_["legend"] = &XmlMagics::legend;
      actions_["meta"] = &XmlMagics::metadata;

      actions_["drivers"] = &XmlMagics::driver;

      actions_["plot"] = &XmlMagics::layer;
      actions_["geopoints"] = &XmlMagics::geopoints;
      actions_["efigraph"] = &XmlMagics::efigraph;
      actions_["efigram"] = &XmlMagics::efigram;

      actions_["metgraph"] = &XmlMagics::metgraph;
      actions_["metgram"] = &XmlMagics::metgram;

      actions_["gribloop"] = &XmlMagics::gribloop;

      actions_["epsxml"] = &XmlMagics::epsxml;
      actions_["epsbufr"] = &XmlMagics::epsbufr;
      actions_["epsgraph"] = &XmlMagics::epsgraph;
      actions_["epsgram"] = &XmlMagics::epsgram;
      actions_["epswind"] = &XmlMagics::epswind;
      actions_["epswave"] = &XmlMagics::epswave;
      actions_["epsshade"] = &XmlMagics::epsshading;
      actions_["epsplume"] = &XmlMagics::epsplume;
      actions_["epsdirection"] = &XmlMagics::epsdirection;

      actions_["mapgen"] = &XmlMagics::mapgen;
      actions_["graph"] = &XmlMagics::graph;

      actions_["polyline_input"] = &XmlMagics::polyinput;
      actions_["polyline"] = &XmlMagics::polyline;

      actions_["layer"] = &XmlMagics::split;
      actions_["thread"] = &XmlMagics::thread;
}


XmlMagics::~XmlMagics() 
{
}
 
/*!
 Class information are given to the output-stream.
*/          
void XmlMagics::print(ostream& out)  const
{
      out << "XmlMagics[";
      out << "]";
}

void XmlMagics::execute(XmlTree& tree) 
{
      try {
            tree.visit(*this);
      }
      catch (MagicsException& e) {
            Log::debug() << e.what() << endl;
      }

      if ( driversToSet_ ) 
            output_.set(drivers_);

      assert(root_);

      root_->execute();

      if ( root_->scalingFactor() != 1)  
            drivers_.setOutputWidth(root_->scalingFactor());


      drivers_.setDriversWidth(root_->absoluteWidth());
      drivers_.setDriversHeight(root_->absoluteHeight());

      { 
            Timer timer("drivers", "rendering of the graphical tree");
            drivers_.openDrivers();
            drivers_.dispatch(root_->root());

            drivers_.closeDrivers();
      }

      MetaDataVisitor::collect();
      //root_->metadata(meta);
      /* later 
            std::map<string, string>::const_iterator filename = meta.find("filename");
            if ( filename != meta.end() && !filename->second.empty()) {
                  ofstream file (filename->second.c_str());
            
                  for (std::map<string, string>::const_iterator d = meta.begin(); d != meta.end(); ++d) {
                        if ( d != filename ) 
                      file << d->first << " = " << d->second << "; " << endl;
              }
            }
      */
      output_.clear();
      //ParameterManager::release();
      delete root_;
      root_ = 0;
}

void XmlMagics::execute(const string& file, std::map<string, string>& )
{
      XmlReader parser(true);
      XmlTree tree;     
      ParameterManager::set(string("layout"), string("magml")); 
      try {
            parser.interpret(file, &tree);            
            execute(tree);
      }
      catch (MagicsException& e) {
            Log::debug() << e.what() << endl;
      }
}

void XmlMagics::display(const string& file)
{
      XmlReader parser(true);
      XmlTree tree;     

      try {
            parser.interpret(file, &tree);            
            tree.visit(*this);
      }
      catch (MagicsException& e) {
                  Log::debug() << e.what() << endl;
      }
      
      if ( driversToSet_ ) 
            output_.set(drivers_);

      assert(root_);
      root_->getReady();
      drivers_.setDriversWidth(root_->absoluteWidth());
      drivers_.setDriversHeight(root_->absoluteHeight());
      
      root_->execute();
      drivers_.openDrivers();
      drivers_.dispatch(root_->root());

      drivers_.closeDrivers();
}
      
void XmlMagics::visit(const XmlNode& node)
{
      std::map<string, Action>::iterator action = actions_.find(node.name());

      if ( action == actions_.end() )
      {
            Log::dev() << " MagML - ignoring tag: " << node.name()<< endl;
            return;
      }
      (this->*action->second)(node);
}

void XmlMagics::magics(const XmlNode& node)
{
      float version_ = 3.0;
      Log::debug() << " You are using the " << fixed << setprecision(1) << version_ << " version of the magml interpreter\n";
      string version = node.getAttribute("version");
      if ( version.empty() )
      {
            Log::error() << " No version defined in your magml file" << endl;
            Log::error() << " Compatibilty issue : check your magml file and add a version number" << endl;
            return;
      }
      float v;
      std::stringstream sv(version);
      sv >> v;
      if ( v < version_ )
      {
            Log::error() << " The version defined in the file is " << fixed << setprecision(1) << v << endl;
            Log::error() << " Compatibilty issue : check your magml file and update the version number " << endl;
            return;
      }
      string method = node.getAttribute("method") ;
      
      root_ =  ( method == "wrep" ) ? new  WrepRootSceneNode() : new  XmlRootSceneNode();
      
      
      push(root_);
      root_->set(node);
      root_->getReady();
      node.visit(*this);
}

//class OpenGLHelper
//{
//public:
//    OpenGLHelper();
//    ~OpenGlHelper() {}
//protected:
//
//};

//OpenGLHelper::OpenGLHelper()
//{
//    Log::dev()<< " Create Motif Window! " << endl;
//}
//



void XmlMagics::driver(const XmlNode& node)
{
      for ( XmlNode::ElementIterator driver = node.firstElement(); driver != node.lastElement(); ++driver) {
//          if (*node.firstElement())->name() ) 
//                new OpenGLhelper();
            
            output_.set(**driver, drivers_);
      }
      driversToSet_ = false;
}


void XmlMagics::split(const XmlNode& node)
{
/*
      LayerNode* layer = new LayerNode();
      layer->set(node);
      top()->push_back(layer);
      push(layer);
      node.visit(*this);
      pop();
*/
      node.visit(*this);
}


void XmlMagics::thread(const XmlNode& )
{
/* later
      ThreadNode* thread = new ThreadNode();
      thread->set(node);
      top()->push_back(thread);
      push(thread);
      node.visit(*this);
      pop();
*/
}

void XmlMagics::metadata(const XmlNode& node)
{
      MetaDataVisitor* meta = new MetaDataVisitor();
      meta->set(node);
      top()->push_back(meta);
}



void XmlMagics::page(const XmlNode& node)
{
      XmlSceneNode* page = new XmlSceneNode();

      page->set(node);
      top()->insert(page);
      push(page);
      node.visit(*this);
      pop();
}

void XmlMagics::legend(const XmlNode& node)
{
      LegendVisitor* legend = new XmlLegendVisitor();
      legend->set(node);
      top()->legend(legend);  
      node.visit(*this);
}

void XmlMagics::text(const XmlNode& node)
{
      XmlTextVisitor* text = new XmlTextVisitor();
      text->set(node);
      top()->text(text);
      
      node.visit(*this);
}

void XmlMagics::map(const XmlNode& node)
{
      XmlViewNode* view = new XmlViewNode();
      view->set(node);
      BasicSceneObject* parent = top()->insert(view);
      if (parent != top() ) {
            pop();
            push(parent);
      }

      push(view);
      node.visit(*this);
      pop();
}

void XmlMagics::binary(const XmlNode& node)
{     
      BinaryObject* binary = new BinaryObject();
      binary->set(node);
      top()->push_back(binary);
}

void XmlMagics::coastlines(const XmlNode& node)
{     
      Coastlines* coast = new Coastlines();
      coast->set(node);
      top()->push_back(coast);
}

void XmlMagics::taylor(const XmlNode& node)
{     
      TaylorGrid* grid = new TaylorGrid();
      grid->set(node);
      top()->push_back(grid);
}

void XmlMagics::horizontalAxis(const XmlNode& node)
{     
      HorizontalAxis* axis = new HorizontalAxis();
      axis->set(node);
      top()->push_back(axis);
}

void XmlMagics::verticalAxis(const XmlNode& node)
{     
      VerticalAxis* axis = new VerticalAxis();
      axis->set(node);
      top()->push_back(axis);
}

void XmlMagics::cartesian(const XmlNode&)
{     
      geographical_ = false;
}



void XmlMagics::geographical(const XmlNode&)
{     
      geographical_ = true;
}

void XmlMagics::layer(const XmlNode& node)
{
      if ( geographical_ )
      {
            VisualAction<GeoPoint>* action = new VisualAction<GeoPoint>();
            action->set(node);
            top()->push_back(action);
            push(action);     
      }
      else {
            VisualAction<UserPoint>* action = new VisualAction<UserPoint>();
            action->set(node);
            top()->push_back(action);
            push(action);
      }

      node.visit(*this);
      pop();
}


GribDecoder* grib_handler;

void XmlMagics::gribloop(const XmlNode& node)
{
      if ( gribloop_) delete gribloop_;
      gribloop_ = new GribLoop();
      gribloop_->set(node);

      actions_["grib"] = &XmlMagics::gribinloop;
      actions_["layer"] = &XmlMagics::splitinloop;

      while ( gribloop_->hasMore() ) {
            node.visit(*this);
      }
}

void XmlMagics::splitinloop(const XmlNode& ) 
{
      /* later!
      assert(gribloop_);

      LayerNode* layer = new LayerNode();
      layer->set(node);
      gribloop_->set(*layer);
      top()->push_back(layer);
      push(layer);
      this->layer(node);
      pop();
      */
}

void XmlMagics::gribinloop(const XmlNode&)
{     
      assert(gribloop_);
      top()->data(gribloop_->current());
}


void XmlMagics::grib(const XmlNode& node)
{
      GribDecoder* grib = new GribDecoder();
      grib->set(node);
      if (geographical_) {
            top()->data(grib);
      }
      else {
            top()->data(new DataConverter(grib));
      }
}

#include "GeoPointsDecoder.h"
void XmlMagics::geopoints(const XmlNode& node)
{     
      GeoPointsDecoder* geo = new GeoPointsDecoder();
      geo->set(node);
      top()->data(geo);
}

#include "MapGenDecoder.h"
void XmlMagics::mapgen(const XmlNode& node)
{     
      MapGenDecoder<UserPoint>* mapgen = new MapGenDecoder<UserPoint>();
      mapgen->set(node);
      top()->data(mapgen);
}

void XmlMagics::xyinput(const XmlNode& node)
{     
      if (geographical_) {
                  XYList<GeoPoint>* list = new XYList<GeoPoint>();
                  list->set(node);
                  top()->data(list);
      }
      else {
                  XYList<UserPoint>* list = new XYList<UserPoint>();
                  list->set(node);
                  top()->data(list);
      }
}

void XmlMagics::landgram(const XmlNode& node)
{     
      LandgramDecoder* list = new LandgramDecoder();
      list->set(node);
      top()->data(list);
}

void XmlMagics::landgrambox(const XmlNode& node)
{     
      LandgramBox* box = new LandgramBox();
      box->set(node);
      top()->visdef(box);
}

#include "GraphPlotting.h"
void XmlMagics::graph(const XmlNode& node)
{     
      GraphPlotting* graph =  new GraphPlotting();
      graph->set(node);
      top()->visdef(graph);
}

void XmlMagics::histogram(const XmlNode& node)
{
      Histogram* histogram =  new Histogram();
      histogram->set(node);
      top()->visdef(histogram);
}


/***************************************************************************

    O D B / O D A

***************************************************************************/



void XmlMagics::odb(const XmlNode& )
{
}
#include "OdaDecoder.h"

void XmlMagics::oda(const XmlNode& node)
{
#ifdef MAGICS_ODB

      OdaDecoder* oda = new OdaDecoder();
      oda->set(node);
    top()->data(oda);
#else 
      Log::warning() << "ODB support is NOT enabled! (Forgotten -lMagPlusODB ?)\n";
#endif

}

/* ********************************************************************* */


void XmlMagics::efigram(const XmlNode& node)
{     
#ifdef MAGICS_SPOT
      EfigramDecoder* efi = new EfigramDecoder();
      efi->set(node);
      top()->data(efi);
#endif
}

void XmlMagics::efigraph(const XmlNode& node)
{     
#ifdef MAGICS_SPOT
      EfiGraph* efi = new EfiGraph();
      efi->set(node);
      top()->visdef(efi);
#endif
}

void XmlMagics::epsplume(const XmlNode& node)
{     
#ifdef MAGICS_SPOT
      EpsPlume* plume = new EpsPlume();
      plume->set(node);
      top()->visdef(plume);
#endif
}

void XmlMagics::epsdirection(const XmlNode& node)
{     
#ifdef MAGICS_SPOT
      EpsDirection* direction = new EpsDirection();
      direction->set(node);
      top()->visdef(direction);
#endif
}


void XmlMagics::metgram(const XmlNode& node)
{     
#ifdef MAGICS_SPOT
      ClassicMtgDecoder* metgram = new ClassicMtgDecoder();
      metgram->set(node);
      top()->data(metgram);
#endif
}
void XmlMagics::metgraph(const XmlNode& node)
{     
#ifdef MAGICS_SPOT
      MetgramGraph* metgraph = new MetgramGraph();
      metgraph->set(node);
      top()->visdef(metgraph);
#endif
}


void XmlMagics::epsgram(const XmlNode& node)
{     
#ifdef MAGICS_SPOT
      EpsgramDecoder* eps = new EpsgramDecoder();
      eps->set(node);
      top()->data(eps);
#endif
}
void XmlMagics::epsxml(const XmlNode& node)
{     
#ifdef MAGICS_SPOT
      EpsXmlInput* eps = new EpsXmlInput();
      eps->set(node);
      top()->data(eps);
#endif
}
#ifdef MAGICS_BUFR
#include "EpsBufr.h"
#endif

void XmlMagics::epsbufr(const XmlNode& node)
{     
#ifdef MAGICS_BUFR
      EpsBufr* eps = new EpsBufr();
      eps->set(node);
      top()->data(eps);
#endif
}
void XmlMagics::epsgraph(const XmlNode& node)
{     
#ifdef MAGICS_SPOT
      EpsGraph* epsgraph = new EpsGraph();
      epsgraph->set(node);
      top()->visdef(epsgraph);
#endif
}
void XmlMagics::epswave(const XmlNode& node)
{     
#ifdef MAGICS_SPOT
      EpsWave* eps = new EpsWave();
      eps->set(node);
      top()->visdef(eps);
#endif
}

void XmlMagics::epswind(const XmlNode& node)
{     
#ifdef MAGICS_SPOT
      EpsWind* epswind = new EpsWind();
      epswind->set(node);
      top()->visdef(epswind);
#endif
}

void XmlMagics::epsshading(const XmlNode& node)
{     
#ifdef MAGICS_SPOT
      EpsShade* eps = new EpsShade();
      eps->set(node);
      top()->visdef(eps);
#endif
}


void XmlMagics::netcdf(const XmlNode& node)
{     
      if ( geographical_ ) {
            NetcdfDecoder<GeoPoint>* netcdf = new NetcdfDecoder<GeoPoint>();
            netcdf->set(node);
            top()->data(netcdf);
      }
      else {
            NetcdfDecoder<UserPoint>* netcdf = new NetcdfDecoder<UserPoint>();
            netcdf->set(node);
            top()->data(netcdf);
      }
}

#include "InputMatrix.h"

void XmlMagics::matrix(const XmlNode& node)
{     
            //MatrixTestDecoder* matrix = new MatrixTestDecoder();
            //matrix->set(node);
            if ( geographical_ ) {
                  InputMatrix<GeoPoint>* data =  new InputMatrix<GeoPoint>();
                  data->set(node);
                  top()->data(data);
            }
            else {
                  InputMatrix<UserPoint>* data =  new InputMatrix<UserPoint>();
                  data->set(node);
                  top()->data(data);
            }
}

void XmlMagics::polyinput(const XmlNode& node)
{
      SimplePolylineInput* input = new SimplePolylineInput();
      input->set(node);
      top()->data(input);
}

void XmlMagics::polyline(const XmlNode& node)
{
            SimplePolylineVisualiser* poly =  new SimplePolylineVisualiser();
            poly->set(node);
            top()->visdef(poly);
}



void  XmlMagics::symbol(const XmlNode& node)
{     
      if ( geographical_ ) {
            SymbolPlotting<GeoPoint>* symbol =  new SymbolPlotting<GeoPoint>();
            symbol->set(node);
            top()->visdef(symbol);
      }
      else {
            SymbolPlotting<UserPoint>* symbol =  new SymbolPlotting<UserPoint>();
            symbol->set(node);
            top()->visdef(symbol);
      }
}


void XmlMagics::contour(const XmlNode& node)
{     
      
      if ( geographical_ ) {
            Contour<GeoPoint>* contour =  new Contour<GeoPoint>();
            contour->set(node);
            top()->visdef(contour);
      }
      else {
            Contour<UserPoint>* contour =  new Contour<UserPoint>();
            contour->set(node);
            top()->visdef(contour);
      }
}


void XmlMagics::image(const XmlNode& node)
{     

      if ( geographical_ ) {
            ImagePlotting<GeoPoint>* image =  new ImagePlotting<GeoPoint>();
            image->set(node);
            top()->visdef(image);
      }
      else {
            ImagePlotting<UserPoint>* image =  new ImagePlotting<UserPoint>();
            image->set(node);
            top()->visdef(image);
      }

}

void XmlMagics::wind(const XmlNode& node)
{     
      if ( geographical_ ) {
            Wind<GeoPoint>* wind =  new Wind<GeoPoint>();
            wind->set(node);
            top()->visdef(wind);
      }
      else {
            Log::warning() << " wind not yet implemented for cartesian system" << endl;
      }
      if ( gribloop_ ) gribloop_->next();
}

Generated by  Doxygen 1.6.0   Back to index