00001 //$Header: /home/ben/Mapper/c++/RCS/MapDataDocument_convert_Constraint_group.cpp,v 6.4 2002/07/14 17:25:32 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 <memory>
00034
00035 #include <dom/DOM_Element.hpp>
00036
00037 #include <string>
00038
00039 #include "MapDataDocument.h"
00040 #include "MapperErrorHandler.h"
00041 #include "angle_constraint.h"
00042 #include "assoc.h"
00043 #include "bearing_constraint.h"
00044 #include "constraint.h"
00045 #include "distance_constraint.h"
00046 #include "vector2.h"
00047 #include "through_constraint.h"
00048 #include "vector_constraint.h"
00049
00050
00051
00052 inline double degtorad(
00053 const double d
00054 )
00055 {
00056 return d * M_PI/180.0;
00057 };
00058
00059
00060
00061 void MapDataDocument::convert_Angle(
00062 DOM_Element &elem,
00063 const double default_uncertainty
00064 )
00065 throw(
00066 error::attribute_error
00067 )
00068 {
00069 {//preconditions:
00070 assert( 0 < default_uncertainty );
00071 };
00072 vector2 *at;
00073 vector2 *from;
00074 vector2 *to;
00075 double d;
00076 double uncertainty = default_uncertainty;
00077 {//retrieve attribute values
00078 this->get_attribute( at, elem, "at" );
00079 this->get_attribute( from, elem, "from" );
00080 this->get_attribute( to, elem, "to" );
00081 get_attribute( d, elem, "d" );
00082 if( has_attribute( elem, "uncertainty" ) ){
00083 get_attribute( uncertainty, elem, "uncertainty" );
00084 if( uncertainty <= 0 )
00085 throw error::attribute_error( elem, "not positive", "uncertainty" );
00086 ;
00087 };
00088 };
00089 {//convert units
00090 d = degtorad( d );
00091 uncertainty = degtorad( uncertainty );
00092 };
00093 angle_constraint *a = new angle_constraint( uncertainty, d );
00094 assert( a ); assert( from ); assert( to );
00095 assoc( *a, *at, *from, *to );
00096 this->constraints_.push_back( a );
00097 elem.setUserData( a );
00098 };
00099
00100
00101
00102 void MapDataDocument::convert_Bearing(
00103 DOM_Element &elem, //input
00104 const double default_uncertainty
00105 )
00106 throw(
00107 error::attribute_error
00108 )
00109 {
00110 {//preconditions:
00111 assert( 0 < default_uncertainty );
00112 };
00113 vector2 *from;
00114 vector2 *to;
00115 double d;
00116 double uncertainty;
00117 {//retrieve attribute values
00118 this->get_attribute( from, elem, "from" );
00119 this->get_attribute( to, elem, "to" );
00120 get_attribute( d, elem, "d" );
00121 if( has_attribute( elem, "uncertainty" ) ){
00122 get_attribute( uncertainty, elem, "uncertainty" );
00123 if( uncertainty <= 0 )
00124 throw error::attribute_error( elem, "not positive", "uncertainty" );
00125 ;
00126 }else
00127 uncertainty = default_uncertainty;
00128 ;
00129 };
00130 {//convert units
00131 d = degtorad( d );
00132 uncertainty = degtorad( uncertainty );
00133 };
00134 bearing_constraint *b = new bearing_constraint( uncertainty, d );
00135 assoc( *b, *from, *to );
00136 this->constraints_.push_back( b );
00137 elem.setUserData( b );
00138 }
00139
00140
00141
00142 void MapDataDocument::convert_Distance(
00143 DOM_Element &elem, //input
00144 const double default_uncertainty_0,
00145 const double default_uncertainty_1
00146 )
00147 throw(
00148 error::attribute_error
00149 )
00150 {
00151 {//preconditions:
00152 assert( 0 < default_uncertainty_0 );
00153 assert( 0 <= default_uncertainty_1 );
00154 };
00155 vector2 *from;
00156 vector2 *to;
00157 double d;
00158 double uncertainty;
00159 {//retrieve attribute values
00160 this->get_attribute( from, elem, "from" );
00161 this->get_attribute( to, elem, "to" );
00162 get_attribute( d, elem, "d" );
00163 if( d <= 0 ) throw error::attribute_error( elem, "not positive", "d" );
00164 if( has_attribute( elem, "uncertainty" ) ){
00165 get_attribute( uncertainty, elem, "uncertainty" );
00166 if( uncertainty <= 0 )
00167 throw error::attribute_error(
00168 elem, "not positive", "uncertainty"
00169 );
00170 ;
00171 }else
00172 uncertainty =
00173 default_uncertainty_0 + default_uncertainty_1 * d;
00174 ;
00175 };
00176 distance_constraint *c = new distance_constraint( uncertainty, d );
00177 assoc( *c, *from, *to );
00178 this->constraints_.push_back( c );
00179 elem.setUserData( c );
00180 }
00181
00182
00183
00184 void MapDataDocument::convert_Through(
00185 DOM_Element &elem,
00186 const double default_uncertainty
00187 )
00188 throw(
00189 error::attribute_error
00190 )
00191 {
00192 {//preconditions:
00193 assert( 0 < default_uncertainty );
00194 };
00195 curve *cu;
00196 vector2 *po;
00197 double x = 0.0;
00198 double y = 0.0;
00199 double uncertainty = default_uncertainty;
00200 {//retrieve attribute values
00201 this->get_attribute( cu, elem, "curve" );
00202 this->get_attribute( po, elem, "point" );
00203 if( has_attribute( elem, "x" ) )
00204 get_attribute( x, elem, "x" );
00205 ;
00206 if( has_attribute( elem, "y" ) )
00207 get_attribute( y, elem, "y" );
00208 ;
00209 if( has_attribute( elem, "uncertainty" ) ){
00210 get_attribute( uncertainty, elem, "uncertainty" );
00211 if( uncertainty <= 0 )
00212 throw error::attribute_error(
00213 elem, "not positive", "uncertainty"
00214 );
00215 ;
00216 };
00217 };
00218 through_constraint *tc = new through_constraint(
00219 uncertainty, x, y
00220 );
00221 assert( tc && cu && po );
00222 assoc( *tc, *cu, *po );
00223 this->constraints_.push_back( tc );
00224 elem.setUserData( tc );
00225 }
00226
00227
00228
00229 void MapDataDocument::convert_Vector(
00230 DOM_Element &elem, //input
00231 const double default_uncertainty_0,
00232 const double default_uncertainty_1
00233 )
00234 throw(
00235 error::attribute_error
00236 )
00237 {
00238 {//preconditions:
00239 assert( 0 < default_uncertainty_0 );
00240 assert( 0 <= default_uncertainty_1 );
00241 };
00242 vector2 *from;
00243 vector2 *to;
00244 double x;
00245 double y;
00246 double uncertainty;
00247 {//retrieve attribute values
00248 this->get_attribute( from, elem, "from" );
00249 this->get_attribute( to, elem, "to" );
00250 get_attribute( x, elem, "x" );
00251 get_attribute( y, elem, "y" );
00252 if( has_attribute( elem, "uncertainty" ) ){
00253 get_attribute( uncertainty, elem, "uncertainty" );
00254 if( uncertainty <= 0 )
00255 throw error::attribute_error(
00256 elem, "not positive", "uncertainty"
00257 );
00258 ;
00259 }else{
00260 const double d = hypot( x, y );
00261 uncertainty =
00262 default_uncertainty_0 + default_uncertainty_1 * d;
00263 };
00264 };
00265 vector_constraint *c = new vector_constraint( uncertainty, x, y );
00266 assoc( *c, *from, *to );
00267 this->constraints_.push_back( c );
00268 elem.setUserData( c );
00269 }
00270
00271
00272
00273 void MapDataDocument::convert_Constraint_group(
00274 DOM_Element &elem, //input
00275 MapperErrorHandler &err_handler
00276 )
00277 throw(
00278 error::attribute_error
00279 )
00280 {
00281 double angle_uncertainty;
00282 double length_uncertainty_0;
00283 double length_uncertainty_1;
00284 {//examine attributes
00285 require_attribute( elem, "length-uncertainty" );
00286 get_attribute( angle_uncertainty, elem, "angle-uncertainty" );
00287 const DOMString s( elem.getAttribute(
00288 DOMString( "length-uncertainty" ) )
00289 );
00290 auto_ptr< char > trans( s.transcode() );
00291 char dummy;
00292 int n_read = sscanf(
00293 trans.get(), " %le + %le %% %c",
00294 &length_uncertainty_0, &length_uncertainty_1, &dummy
00295 );
00296 if( n_read == 1 ) //only have constant part
00297 length_uncertainty_1 = 0.0;
00298 else if( n_read != 2 )
00299 throw error::attribute_error(
00300 elem, "unexpected characters", "length-uncertainty"
00301 );
00302 ;
00303 if( length_uncertainty_0 < 0 || length_uncertainty_1 < 0 )
00304 throw error::attribute_error(
00305 elem, "negative value", "length-uncertainty"
00306 );
00307 ;
00308 };
00309 DOM_NodeList children( elem.getChildNodes() );
00310 for( unsigned i = 0; i < children.getLength(); i++ ){
00311 DOM_Node node( children.item(i) );
00312 if( node.getNodeType() != DOM_Node::ELEMENT_NODE ) continue;
00313 DOM_Element &child( static_cast< DOM_Element & >( node ) );
00314 DOMString tag( child.getTagName() );
00315 try{
00316 if( DOMString("Cite").equals( tag ) )
00317 ;//Do nothing
00318 else if( DOMString("Angle").equals( tag ) )
00319 this->convert_Angle( child, angle_uncertainty );
00320 else if( DOMString("Bearing").equals( tag ) )
00321 this->convert_Bearing( child, angle_uncertainty );
00322 else if( DOMString("Distance").equals( tag ) )
00323 this->convert_Distance(
00324 child, length_uncertainty_0, length_uncertainty_1
00325 );
00326 else if( DOMString("Through").equals( tag ) )
00327 this->convert_Through( child, length_uncertainty_0 );
00328 else if( DOMString("Vector").equals( tag ) )
00329 this->convert_Vector(
00330 child, length_uncertainty_0, length_uncertainty_1
00331 );
00332 else{
00333 throw error::element_error( child, "unexpected element" );
00334 };
00335 }catch( error::element_error &e ){
00336 err_handler.error( e );
00337 };
00338 };
00339 }