Пример #1
0
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;
}
Пример #2
0
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;
}