Main Page   Namespace List   Class Hierarchy   Compound List   File List   Header Files   Sources   Namespace Members   Compound Members   File Members  

MapDataDocument_convert.cpp

00001 //$Header: /home/ben/Mapper/c++/RCS/MapDataDocument_convert.cpp,v 6.25 2002/07/09 22:50:52 ben Exp $
00002 // Copyright Benedict Adamson 2002.
00003 // This file is part of Mapper.
00004 
00005 // Mapper is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or
00008 // (at your option) any later version.
00009 
00010 // Mapper is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 
00015 // You should have received a copy of the GNU General Public License
00016 // along with Mapper; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00030 #include <cstdio>
00031 #include <cstdlib>
00032 #include <cstring>
00033 #include <map>
00034 #include <memory>
00035 
00036 #include <dom/DOM_Attr.hpp>
00037 #include <dom/DOM_DOMException.hpp>
00038 #include <dom/DOM_Element.hpp>
00039 #include <dom/DOM_Document.hpp>
00040 #include <dom/DOM_Node.hpp>
00041 
00042 #include <string>
00043 
00044 #include "MapDataDocument.h"
00045 #include "MapperErrorHandler.h"
00046 #include "curve.h"
00047 #include "curve_segment.h"
00048 #include "vector2.h"
00049 
00050 
00051 
00052 void MapDataDocument::convert_Curve(
00053    DOM_Element &elem, //input
00054    MapperErrorHandler &err_handler
00055    )
00056    throw(
00057       error::attribute_error
00058       )
00059 {
00060    string id;
00061    vector2 *from;
00062    vector2 *to;
00063    {//retrieve attribute values
00064       get_attribute( id, elem, "id" );
00065       this->get_attribute( from, elem, "from" );
00066       this->get_attribute( to, elem, "to" );
00067    };
00068    curve *c = new curve;
00069    c->param.push_back( from );
00070    c->param.push_back( to );
00071    this->curves_[id] = c;
00072    elem.setUserData( c );
00073    {//set the parameters, from Coord children
00074       DOM_NodeList children(
00075          elem.getElementsByTagName( DOMString("Coord" ) )
00076          );
00077       const unsigned n = children.getLength();
00078       assert( c->param.size() == 2 );
00079       c->param.reserve( n ); //optimisation
00080       for( unsigned i = 0; i < n; i++ ){
00081          DOM_Node node( children.item(i) );
00082          assert( node.getNodeType() == DOM_Node::ELEMENT_NODE );
00083          DOM_Element &child( static_cast< DOM_Element & >( node ) );
00084          try{
00085             vector2 position( this->random_position() );
00086             if( has_attribute( child, "x" ) )
00087                get_attribute( position.x, child, "x" );
00088             ;
00089             if( has_attribute( child, "y" ) )
00090                get_attribute( position.y, child, "y" );
00091             ;
00092             vector2 *p = new vector2( position );
00093             child.setUserData( p );
00094             c->param.push_back( p );
00095          }catch( error::attribute_error &e ){
00096             err_handler.error( e );
00097          };
00098       };
00099    };
00100 }
00101 
00102 
00103 
00104 void MapDataDocument::convert_Fixed_point(
00105    DOM_Element &elem //input
00106    )
00107    throw(
00108       error::attribute_error
00109       )
00110 {
00111    string point_name;
00112    double x;
00113    double y;
00114    {//retrieve attribute values
00115       get_attribute( point_name, elem, "point" );
00116       get_attribute( x, elem, "x" );
00117       get_attribute( y, elem, "y" );
00118    };
00119    map< string, vector2 * >::iterator i =
00120       this->named_points_.find( point_name );
00121    if( i == this->named_points_.end() )
00122       throw error::attribute_error( elem, "point not found", "point" );
00123    ;
00124    vector2 *p = (*i).second;
00125    assert( p );
00126    this->fixed_points_.insert( p );
00127    p->x = x;
00128    p->y = y;
00129    elem.setUserData( p );
00130 }
00131 
00132 
00133 void MapDataDocument::convert_Point(
00134    DOM_Element &elem //input
00135    )
00136    throw(
00137       error::attribute_error
00138       )
00139 {
00140    string id;
00141    vector2 position( this->random_position() );
00142    {//retrieve attribute values
00143       get_attribute( id, elem, "id" );
00144       if( has_attribute( elem, "x" ) )
00145          get_attribute( position.x, elem, "x" );
00146       ;
00147       if( has_attribute( elem, "y" ) )
00148          get_attribute( position.y, elem, "y" );
00149       ;
00150    };
00151    vector2 *p = new vector2( position );
00152    this->named_points_[id] = p;
00153    elem.setUserData( p );
00154 }
00155 
00156 
00157 
00158 void MapDataDocument::convert_Point_alias(
00159    DOM_Element &elem //input
00160    )
00161    throw(
00162       error::attribute_error
00163       )
00164 {
00165    string id;
00166    vector2 *p;
00167    {//retrieve attribute values
00168       get_attribute( id, elem, "id" );
00169       if( this->named_points_.count( id ) ){
00170          throw error::attribute_error( elem, "already the id of a point", "id" );
00171       };
00172       this->get_attribute( p, elem, "point" );
00173       assert( p );
00174    };
00175    this->named_points_[id] = p;
00176 }
00177    
00178 
00179 
00180 void MapDataDocument::convert_pointrefs(
00181    DOM_Element &elem, //input
00182    const char *tag,
00183    MapperErrorHandler &err_handler
00184    )
00185 {
00186    DOM_NodeList children(
00187       elem.getElementsByTagName( DOMString(tag) )
00188       );
00189    for( unsigned i = 0; i < children.getLength(); i++ ){
00190       DOM_Node node( children.item(i) );
00191       if( node.getNodeType() != DOM_Node::ELEMENT_NODE ) continue;
00192       DOM_Element &child( static_cast< DOM_Element & >( node ) );
00193       try{
00194          vector2 *p;
00195          this->get_attribute( p, child, "point" );
00196          child.setUserData( p );
00197       }catch( error::attribute_error &e ){
00198          err_handler.error( e );
00199       };
00200    };
00201 }
00202 
00203 
00204 
00205 void MapDataDocument::convert_Curve_segments(
00206    DOM_Element &elem, //input
00207    MapperErrorHandler &err_handler
00208    )
00209 {
00210    DOM_NodeList children(
00211       elem.getElementsByTagName( DOMString("Curve-segment") )
00212       );
00213    for( unsigned i = 0; i < children.getLength(); i++ ){
00214       DOM_Node node( children.item(i) );
00215       DOM_Element &child( static_cast< DOM_Element & >( node ) );
00216       try{
00217          curve *c;
00218          vector2 *from;
00219          vector2 *to;
00220          this->get_attribute( c, child, "curve" );
00221          this->get_attribute( to, child, "point" );
00222          {//determine the from point
00223             from = 0;
00224             DOM_Node f = child.getPreviousSibling();
00225             while( !from && !f.isNull() ){
00226                if( f.getNodeType() == DOM_Node::ELEMENT_NODE ){
00227                   DOM_Element &sib( static_cast< DOM_Element & >( f ) );
00228                   DOMString tag( sib.getTagName() );
00229                   if( DOMString("Node").equals( tag ) ||
00230                       DOMString("Line-segment").equals( tag ) ||
00231                       DOMString("Curve-segment").equals( tag ) )
00232                      this->get_attribute( from, sib, "point" );
00233                   ;
00234                };
00235                if( !from )
00236                   f = f.getPreviousSibling(); //next
00237                ;
00238             };
00239          };
00240          if( c && from && to ){
00241             curve_segment *s = new curve_segment(  c, from, to );
00242             child.setUserData( s );
00243          };
00244       }catch( error::attribute_error &e ){
00245          err_handler.error( e );
00246       };
00247    };
00248 }
00249 
00250 
00251 
00252 void MapDataDocument::convert(
00253    MapperErrorHandler &err_handler //input
00254    )
00255 {
00256    DOM_Element root( this->doc.getDocumentElement() );
00257    {//set default values for the attributes of the root tag
00258       this->precision = 6U;
00259       this->origin_ = vector2(0,1);
00260       this->width_ = 1.0;
00261       this->height_ = 1.0;
00262    };
00263    try{//process the attributes of the root tag
00264       {//get attributes
00265          if( has_attribute( root, "precision" ) ){
00266             get_attribute( this->precision, root, "precision" );
00267          };
00268          if( has_attribute( root, "width" ) ){
00269             get_attribute( this->width_, root, "width" );
00270          };
00271          if( has_attribute( root, "height" ) ){
00272             get_attribute( this->height_, root, "height" );
00273          };
00274          if( has_attribute( root, "x" ) ){
00275             get_attribute( this->origin_.x, root, "x" );
00276          };
00277          if( has_attribute( root, "y" ) ){
00278             get_attribute( this->origin_.y, root, "y" );
00279          };
00280       };
00281       {//check attribute values
00282          if( this->width_ <= 0 )
00283             throw error::attribute_error( root, "negative value", "width" );
00284          ;
00285          if( this->height_ <= 0 )
00286             throw error::attribute_error( root, "negative value", "height" );
00287          ;
00288       };
00289    }catch( error::attribute_error &e ){
00290       err_handler.error( e );
00291    };
00292    
00293    DOM_NodeList children( root.getChildNodes() );
00294    for( unsigned i = 0; i < children.getLength(); i++ ){
00295       DOM_Node node( children.item(i) );
00296       if( node.getNodeType() != DOM_Node::ELEMENT_NODE ) continue;
00297       DOM_Element &elem( static_cast< DOM_Element & >( node ) );
00298       DOMString tag( elem.getTagName() );
00299       try{
00300          if(       DOMString("Area-feature").equals( tag ) ){
00301             this->convert_pointrefs( elem, "Node", err_handler  );
00302             this->convert_pointrefs( elem, "Line-segment", err_handler );
00303             this->convert_Curve_segments( elem, err_handler );
00304          }else if( DOMString("Constraint-group").equals( tag ) )
00305             this->convert_Constraint_group( elem, err_handler );
00306          else if(  DOMString("Curve").equals( tag ) )
00307             this->convert_Curve( elem, err_handler );
00308          else if(  DOMString("Fixed-point").equals( tag ) )
00309             this->convert_Fixed_point( elem );
00310          else if(  DOMString("Linear-feature").equals( tag ) ){
00311             this->convert_pointrefs( elem, "Node", err_handler );
00312             this->convert_pointrefs( elem, "Line-segment", err_handler );
00313             this->convert_Curve_segments( elem, err_handler );
00314          }else if( DOMString("Tracing").equals( tag ) )
00315             this->convert_Tracing( elem, err_handler );
00316          else if(  DOMString("Point").equals( tag ) )
00317             this->convert_Point( elem );
00318          else if(  DOMString("Point-alias").equals( tag ) )
00319             this->convert_Point_alias( elem );
00320          else if(  DOMString("Point-feature").equals( tag ) )
00321             this->convert_pointrefs( elem, "Node", err_handler );
00322          else if(  DOMString("Units").equals( tag ) ){
00323             DOMString angle_attr( elem.getAttribute( DOMString( "angle" ) ) );
00324             if( !DOMString("degrees").equals( angle_attr ) )
00325                throw error::attribute_error( elem, "unrecognised units", "angle" );
00326             //In a future version, could amend to parse different values.
00327             ;
00328          }else{
00329             throw error::element_error( elem, "unexpected element" );
00330          };
00331       }catch( error::element_error &e ){
00332          err_handler.error( e );
00333       };
00334    };
00335 }
00336 
00337 
00338 
00339 vector2 MapDataDocument::random_position(void) const
00340 {
00341    static const double f = 1.0/(double)RAND_MAX;
00342    return vector2(
00343       this->origin_.x + this->width_ * ((double)rand()) * f,
00344       this->origin_.y - this->height_ * ((double)rand()) * f
00345       );
00346 }

Generated at Sun Jul 14 20:38:09 2002 for Mapper by doxygen 1.0.0 written by Dimitri van Heesch, © 1997-1999