vdatum *parse_vdatum_def ( input_string_def *is, ref_frame *(*getrf)(const char *code, int loadref ), vdatum *(*gethrs)(const char *code, int loadref ) ) { char hrscode[CRDSYS_CODE_LEN+1]; char hrsname[CRDSYS_NAME_LEN+1]; char basecode[CRDSYS_CODE_LEN+1]; char geoidname[MAX_FILENAME_LEN+1]; const char *geoidfile; double offset; int isgeoid; int isgrid; vdatum *hrs = 0; ref_frame *baserf = 0; vdatum *basehrs = 0; vdatum_func *hrf = 0; int sts; sts = OK; isgeoid = 0; isgrid = 0; READ_STRING( "code",hrscode,CRDSYS_CODE_LEN ); READ_STRING( "name",hrsname,CRDSYS_NAME_LEN ); READ_STRING( "base height surface code",basecode,CRDSYS_CODE_LEN ); if( test_next_string_field(is,"geoid") ) { isgeoid=1; isgrid=1; READ_STRING("geoid name",geoidname,MAX_FILENAME_LEN); } else if( test_next_string_field(is,"grid") ) { isgrid=1; READ_STRING("offset grid name",geoidname,MAX_FILENAME_LEN); } else { /* Skip optional string "offset" - as originally implemented with * offset assumed and just a float value */ test_next_string_field(is, "offset"); READ_DOUBLE("offset",&offset); } if( isgrid ) { geoidfile = find_relative_file( is->sourcename, geoidname, ".grd" ); if( ! geoidfile ) { char errmess[255]; sprintf(errmess,"Cannot locate geoid file %.120s for vertical datum %.20s", geoidname,hrscode); report_string_error( is, INVALID_DATA, errmess ); sts = INVALID_DATA; } else { hrf=create_grid_vdatum_func( geoidfile, isgeoid ); } } else { hrf=create_offset_vdatum_func( offset ); } if( sts == OK ) { if( isgeoid && getrf ) { baserf=getrf(basecode,1); if( ! baserf ) { char errmess[255]; sprintf(errmess,"Cannot load reference datum %.20s for vertical datum %.20s", basecode,hrscode); report_string_error( is, INVALID_DATA, errmess ); sts = INVALID_DATA; } } else if( gethrs ) { basehrs=gethrs(basecode,1); if( ! basehrs ) { char errmess[255]; sprintf(errmess,"Cannot load underlying vertical datum %.20s for %.20s", basecode,hrscode); report_string_error( is, INVALID_DATA, errmess ); sts = INVALID_DATA; } else { vdatum *base=basehrs; while( base ) { if( _stricmp(base->code,hrscode) == 0 ) { char errmess[80+CRDSYS_CODE_LEN]; strcpy( errmess, "Vertical datum "); strcat( errmess, hrscode ); strcat( errmess, " has a cyclic dependency"); report_string_error( is, INVALID_DATA, errmess ); sts = INVALID_DATA; break; } base=base->basehrs; } } } } if( sts == OK ) { hrs=create_vdatum( hrscode, hrsname, basehrs, baserf, hrf ); if( ! hrs ) { char errmess[80+CRDSYS_CODE_LEN]; strcpy( errmess, "Cannot create vertical datum "); strcat( errmess, hrscode ); report_string_error( is, INVALID_DATA, errmess ); sts=INVALID_DATA; } } if( ! hrs ) { if( basehrs ) delete_vdatum( basehrs ); if( baserf ) delete_ref_frame( baserf ); if( hrf ) delete_vdatum_func( hrf ); } return hrs; }
coordsys *parse_coordsys_def ( input_string_def *is, ref_frame *(*getrf)(const char *code )) { char cscode[CRDSYS_CODE_LEN+1]; char csname[CRDSYS_NAME_LEN+1]; char rfcode[CRDSYS_CODE_LEN+1]; char typecode[CRDSYS_CODE_LEN+1]; int cstype = CSTP_CARTESIAN; ref_frame *rf = NULL; projection *prj = NULL; coordsys *cs = NULL; char got_range; double range[4]; char *bad = ""; int sts = OK; long loc; READ_STRING( "Coordinate system code",cscode,CRDSYS_CODE_LEN); READ_STRING( "Coordinate system name",csname,CRDSYS_NAME_LEN); loc = get_string_loc( is ); READ_STRING( "Reference frame code", rfcode, CRDSYS_CODE_LEN); if( sts == OK ) { if( _stricmp( rfcode, "REF_FRAME" ) != 0 ) { set_string_loc( is , loc ); rf = parse_ref_frame_def( is, 0, 1 ); if( !rf ) return NULL; } else { READ_STRING( "Reference frame code",rfcode,CRDSYS_CODE_LEN); rf = NULL; } } READ_STRING( "Coordinate system type",typecode,CRDSYS_CODE_LEN); if( sts == OK ) { if( _stricmp( typecode, "GEOCENTRIC" ) == 0 ) { cstype = CSTP_CARTESIAN; } else if( _stricmp( typecode, "GEODETIC" ) == 0 ) { cstype = CSTP_GEODETIC; } else if( _stricmp( typecode, "PROJECTION" ) == 0 ) { cstype = CSTP_PROJECTION; } else { sts = INVALID_DATA; } } if( sts == OK && cstype == CSTP_PROJECTION ) { prj = parse_projection_def( is ); if( !prj ) { if( rf ) delete_ref_frame( rf ); return NULL; } } else { prj = NULL; } got_range = 0; if( sts == OK ) { loc = get_string_loc( is ); READ_STRING( "", typecode, CRDSYS_CODE_LEN ); if( sts != OK || _stricmp(typecode,"RANGE") != 0 ) { set_string_loc( is, loc ); sts = OK; } else { READ_DOUBLE( "valid range", &range[0]); READ_DOUBLE( "valid range", &range[1]); READ_DOUBLE( "valid range", &range[2]); READ_DOUBLE( "valid range", &range[3]); got_range = sts == OK; } } if( sts == OK ) { char test[32]; sts = next_string_field( is, test, 32-1 ) == NO_MORE_DATA ? OK : TOO_MUCH_DATA; if( sts != OK ) { char errmsg[100+CRDSYS_CODE_LEN]; sprintf(errmsg,"Extraneous data \"%s\" in definition of crdsys \"%s\"", test,cscode); report_string_error(is,sts,errmsg); } } if( sts == OK && !rf ) { if( getrf ) rf = (*getrf)(rfcode); if( !rf ) { char errmess[80]; strcpy(errmess,"Cannot load reference frame "); strcat(errmess,rfcode); report_string_error(is,INVALID_DATA,errmess); sts = MISSING_DATA; } } else if( sts != OK ) { char errmess[80]; if( sts == MISSING_DATA ) { strcpy( errmess, bad); strcat( errmess, " is missing" ); } else { strcpy( errmess, "Invalid value for " ); strcat( errmess, bad ); } report_string_error( is, sts, errmess ); } if( sts != OK ) { if( prj ) delete_projection( prj ); if( rf ) delete_ref_frame( rf ); return NULL; } cs = create_coordsys( cscode, csname, cstype, rf, prj ); if( !cs ) return NULL; if( got_range ) define_coordsys_range( cs, range[0], range[1], range[2], range[3] ); return cs; }