SRM C API 4.0 to 4.1 Migration Guide

SRM SDK Release 4.1.4

July 1, 2011



  1. Introduction
  2. Differences
    1. Header Files
    2. SRF Template Instantiation
    3. Coordinate Instantiation
    4. Direction Instantiation
    5. Orientation Instantiation
    6. Standard SRF Instantiation
    7. SRF Set Member Instantiation
    8. Coordinate and SRF Destruction
    9. Coordinate SRF Change
    10. Retrieve Coordinate Values
  3. Sample Application
  4. Related Links

Introduction

This document provides a brief introduction to the changes to the 4.0 SRM C SDK. In general, the API was modified to be more object-oriented with the SRFs, coordinates, directions, and orientations implemented as pseudo-objects that need to be instantiated and destroyed, and with each of the object classes implementing a specific set of methods. As with version 4.0, only SRFs can instantiate the coordinate, direction and orientation class objects.

Differences

This section describes the main differences between the SRM C 4.0 and SRM C 4.1 APIs.

Header Files

The header file for the SRM C API was renamed from "srm_level_0.h" to "srm.h".

In 4.0
 #include "srm_level_0.h"
In 4.1
 #include "srm.h"

SRF Template Instantiation

  1. The generic type "SRM_SRF" in 4.0 was replaced by 26 specialized class types in 4.1. There is one SRF class type for every one of the 26 SRF templates defined in SRM, with each one of them being a data structure containing a "state" pointer and a "methods" pointer.
  2. There are 26 specific functions to instantiate each one of the SRF Templates. For example, the method "SRM_CD_Create" instantiates a Celestiodetic SRF Template.
  3. Upon the instantiation of a SRF Template class, its "state" and "methods" fields are initialized so that its methods could be subsequently invoked until when the object is destroyed. The initialized "methods" field points to a list of suitable operations for that SRF Template class. In all SRF methods, the first parameter of a method is always the SRF template instance itself.
  4. The Reference Transformation (RT) code replaces the HSR code in 4.0.
  5. The ORM and RT codes are part of the SRF template instantiation method signature. There could be other parameters for the SRF Template instantiation when necessary, such is the case with the Transverse Mercator (TM) SRF.
In 4.0
 SRM_SRF cd_srf;
 SRM_ORM_Parameters cd_params;

 cd_params.orm_code = SRM_ORM_WGS_1984;
 cd_params.hsr_code = SRM_HSR_WGS_1984_IDENTITY;

 if( SRM_CreateSRF_CD( cd_params,
                       &cd_srf ) != SRM_STAT_CODE_SUCCESS )
     fprintf( stderr, "Failed to create CD SRF\n" );
In 4.1
 SRM_Celestiodetic cd_srf;

 if( SRM_CD_Create( SRM_ORMCOD_WGS_1984,
		    SRM_RTCOD_WGS_1984_IDENTITY,
		    &cd_srf ) != SRM_STATCOD_SUCCESS )
     fprintf( stderr, "Failed to create CD SRF\n" );

Coordinate Instantiation

  1. The generic 3D coordinate "SRM_Coordinate3D" type replaces the specific 3D coordinate types (e.g., SRM_CD_3D_Coordinate) in 4.0. There are also other types for 2D and Surface coordinates in 4.1.
  2. The coordinate component values in 4.1 are part of the coordinate instantiation method signature. It is no longer necessary to declare a specific coordinate information structure prior to coordinate instantiation.
  3. There is a generic coordinate instantiation method "CreateCoordinate3D" to create all 3D coordinates in 4.1.
  4. Upon instantiating a coordinate, any of the methods in its "methods" list can be invoked.
  5. The order of the coordinate component values in the instantiation method signature follows the order in the definition of the coordinates.
  6. In 4.1, the first parameter of a method is always the instantiated SRF template, passed in by reference.
In 4.0
 SRM_Coordinate cd_coord;
 SRM_CD_3D_Coordinate cd_coord_info;

 cd_coord_info.longitude = 0.0;
 cd_coord_info.latitude = 0.785398163397;
 cd_coord_info.ellipsoidal_height = 0.0;

 if( SRM_CreateCoordinateCD_3D( cd_srf,
                                &cd_coord_info,
                                &cd_coord ) != SRM_STAT_CODE_SUCCESS )
     fprintf( stderr, "Failed to create CD coordinate\n" );
In 4.1
 SRM_Coordinate3D cd_coord;

 if (cd_srf.methods->CreateCoordinate3D(&cd_srf,
				         0.0,            /* longitude */
				         0.785398163397, /* latitude */
				         0.0,            /* ellipsoidal height */
					 &cd_coord ) != SRM_STATCOD_SUCCESS )
     fprintf( stderr, "Failed to create CD coordinate\n" );

Direction Instantiation

  1. The "Direction" type in 4.0 was replaced by the "SRM_Direction" type in 4.1.
  2. The Direction component values are part of the method parameter in 4.1. There is no longer a need to use a vector[3] array to instantiate a direction object.
In 4.0
 Direction cd_dir;

 SRM_Long_Float vector[3] = { 1.0, 0.0, 0.0 };

 if (SRM_CreateDirection( cd_srf,
                          cd_ref_coord,
                          vector,
                          &cd_dir) != SRM_STAT_CODE_SUCCESS)
     fprintf( stderr, "Failed to create CD direction\n" );
In 4.1
 SRM_Direction cd_dir;

 if (cd_srf.methods->CreateDirection(&cd_srf,
			   	      &cd_ref_coord,
				      1.0, 0.0, 0.0,
				      &cd_dir) != SRM_STATCOD_SUCCESS)
     fprintf( stderr, "Failed to create CD Direction\n" );

Orientation Instantiation

  1. The "Orientation" type in 4.0 was replaced by the "SRM_Orientation" type in 4.1.
  2. There is a new "SRM_Matrix_3x3" type in 4.1 for expressing the 3x3 orientation matrix.
In 4.0
 Orientation cd_ori;

 SRM_Long_Float ident_mat[3][3] = { {1.0, 0.0, 0.0},
                                    {0.0, 1.0, 0.0},
                                    {0.0, 0.0, 1.0} };

 if (SRM_CreateOrientation( cd_srf,
                            cd_ref_coord,
                            ident_mat,
                            &cd_ori ) != SRM_STAT_CODE_SUCCESS )
     fprintf( stderr, "Failed to create CD Orientation\n" );
In 4.1
 SRM_Orientation cd_ori;

 SRM_Matrix_3x3 ident_mat = { {1.0, 0.0, 0.0},
                              {0.0, 1.0, 0.0},
                              {0.0, 0.0, 1.0} };

 if (cd_srf.methods->CreateOrientation(&cd_srf,
					&cd_ref_coord,
					ident_mat,
					&cd_ori) != SRM_STATCOD_SUCCESS)
     fprintf( stderr, "Failed to create CD Orientation\n" );

Standard SRF Instantiation

  1. The "SRM_Object_Reference" type replaces the "SRM_SRF" type as the output parameter for the instantiated standard SRF. The "SRM_Object_Reference" is essentially a generic pointer to the actual SRF Template class instantiated in this operation. For example, the British National Grid Airy SRF is an instance of Transverse Mercator (TM) SRF Template.
  2. The Reference Transformation (RT) parameter was added to the 4.1 SRM_CreateStandardSRF method to allow user-selected RTs. Please see SRM C API Users' Guide for information on suitable RTs.
  3. To invoke a method of an instantiated standard SRF, it needs to be type-cast to its intrinsic SRF Template class type (see the SRM C API Users' Guide) before it can access the methods in its method list. For example, the syntax for an instantiated BNG SRF to invoke its CreateCoordinate3D method would be:
    ((SRM_TransverseMercator*)bng_srf)->methods->CreateCoordinate3D(...);
In 4.0
 SRM_SRF bng_srf;

 if (SRM_CreateStandardSRF( SRM_SRF_BRITISH_NATIONAL_GRID,
                            &bng_srf ) != SRM_STAT_CODE_SUCCESS )
     fprintf( stderr, "Failed creating BRITISH NATIONAL GRID SRF\n" );
In 4.1
 SRM_Object_Reference bng_srf;

 if (SRM_CreateStandardSRF( SRM_SRFCOD_BRITISH_NATIONAL_GRID_AIRY,
                            SRM_RTCOD_OSGB_1936_3_MEAN_SOLUTION,
                            &bng_srf ) != SRM_STATCOD_SUCCESS )
     fprintf( stderr, "Failed creating BRITISH NATIONAL GRID AIRY SRF\n" );

SRF Set Member Instantiation

  1. The "SRM_Object_Reference" type replaces the "SRM_SRF" type as the output parameter for the instantiated SRF Set member. The "SRM_Object_Reference" is essentially a generic pointer to the actual SRF Template class instantiated in this operation. For example, an Universal Transverse Mercator (UTM) SRF Set member is an instance of Transverse Mercator (TM) SRF Template.
  2. The ORM and RT are individually included as part of the method signature replacing the 4.0 "SRM_ORM_Parameters" type.
  3. There is a new "SRM_SRFS_Code_Info" type in 4.1 that specifies both the SRF Set code and its corresponding member code as a tagged union. That type is part of the method signature in 4.1 replacing the first two parameters ( SRM_SRFS_Code and SRM_SRFS_Member_Code ) of the method in 4.0
  4. To invoke a method of an instantiated SRF Set member, it needs to be type-cast to its intrinsic SRF Template class type (see the SRM C API Users' Guide) before it can access the methods in its method list. For example, the syntax for an instantiated UTM Northern Zone 12 SRF to invoke its CreateCoordinate3D method would be:
    ((SRM_TransverseMercator*)utm_n12_srf)->methods->CreateCoordinate3D(...);
In 4.0
 SRM_SRF utm12_srf;
 SRM_ORM_Parameters utm_params;

 cd_params.orm_code = SRM_ORM_WGS_1984;
 cd_params.hsr_code = SRM_HSR_WGS_1984_IDENTITY;

 if (SRM_CreateSRFSetMember( SRM_SRFS_UNIVERSAL_TRANSVERSE_MERCATOR,
                             SRM_SSM_UTM_ZONE_12_NORTHERN_HEMISPHERE,
                             utm_params,
                             &utm12_srf ) != SRM_STAT_CODE_SUCCESS )
     fprintf( stderr, "Failed creating UNIVERSAL TRANSVERSE MERCATOR zone 12\n" );
In 4.1
 SRM_Object_Reference utm12_srf;
 SRM_SRFS_Code_Info utm12_code_info;

 utm12_code_info.srfs_code = SRM_SRFSCOD_UNIVERSAL_TRANSVERSE_MERCATOR;
 utm12_code_info.value.srfsm_ups = SRM_SRFSMUTMCOD_ZONE_12_NORTHERN_HEMISPHERE;

 if (SRM_CreateSRFSetMember( utm12_code_info,
                             SRM_ORMCOD_WGS_1984,
                             SRM_RTCOD_WGS_1984_IDENTITY,
                             &utm12_srf ) != SRM_STATCOD_SUCCESS )
     fprintf( stderr, "Failed creating UNIVERSAL TRANSVERSE MERCATOR zone 12\n" );

Coordinate and SRF Destruction

  1. The generic "SRM_FreeCoordinate" function was replaced by the destructor methods for 2D, 3D, and Surface coordinates. For example, the destructor method for a 3D coordinate is "DestroyCoordinate3D".
  2. The "Destroy" method replaces the "SRM_FreeSRF" function as the destructor method for the SRFs.
In 4.0
 SRM_FreeCoordinate( cd_coord );

 SRM_FreeSRF( cd_srf );
In 4.1
 cd_srf.methods->DestroyCoordinate3D( &cd_srf,
                                      &cd_coord );

 cd_srf.methods->Destroy( &cd_srf );

Coordinate SRF Change

  1. The order of the parameters for the ChangeCoordinate3DSRF method has changed. The order in 4.1 is target stf, source srf, source coordinate, target coordinate, and valid region.
  2. In 4.1, both source and target coordinates must be instantiated before they can be used in a method invocation.
In 4.0
 if (SRM_ChangeCoordinateSRF( cd_srf,
                              cd_coord,
                              cc_srf,
                              &cc_coord,
                              &valid_region ) != SRM_STAT_CODE_SUCCESS )
     fprintf( stderr, "SRM_ChangeCoordinateSRF failed\n" );
In 4.1
 if (cc_srf.methods->ChangeCoordinate3DSRF( &cc_srf,
                                             &cd_srf,
                                             &cd_coord,
                                             &cc_coord,
                                             &val_region ) != SRM_STATCOD_SUCCESS )
      fprintf( stderr, "SRM_ChangeCoordinateSRF failed\n" );

Retrieve Coordinate Values

  1. The specific method for retrieving 3D coordinate component values in 4.0 (e.g., SRM_GetCoordinateEuclidean_3D) were replaced by the generic "GetCoordinate3DValues" method to retrieve all 3D coordinate component values. There are also specific methods to retrieve 2D and surface coordinate component values.
  2. The specific data structure types in 4.0 used for coordinate values retrieval were replaced by the three ordinate out parameters in the "GetCoordinate3DValues" method.
  3. The order of the coordinate component values follows the order in the definition of the coordinates. For example, for the Celestiocentric 3D coordinate, the retrieved values for "ord1", "ord2", and "ord3" would correspond to "u", "v", and "w" respectively.
In 4.0
 SRM_CC_3D_Coordinate cc_coord_info;

 if (SRM_GetCoordinateEuclidean_3D( cc_coord,
                                    &cc_coord_info ) != SRM_STAT_CODE_SUCCESS )
     fprintf( stderr, "Failed to get CC coordinate information\n" );
 else
     printf( "[ %f, %f, %f ]\n", cc_coord_info.u, cc_coord_info.v, cc_coord_info.w );
In 4.1
 SRM_Long_Float ord1,ord2,ord3;

 if ( cc_srf.methods->GetCoordinate3DValues( &cc_srf,
                                             &cc_coord,
                                             &ord1,
                                             &ord2,
                                             &ord3 ) != SRM_STATCOD_SUCCESS )
       fprintf( stderr, "Failed getting the CC coordinate values\n" );
 else
       printf( "[ %f, %f, %f ]\n", ord1, ord2, ord3 );

Sample Application

This section shows a sample SRM application that converts a coordinate from a Celestiodetic (CD) SRF to a Celestiocentric (CC) SRF using SRM C 4.0 and SRM C 4.1 APIs.

SRM C 4.0 - Sample SRM Access
#include <stdio.h>
#include <string.h>

/* Header file for the SRM C API */
#include "srm_level_0.h"

int main
(
    int argc,
    char* argv[]
)
{
    /* Declare generic SRF handles for CC and CD. */
    SRM_SRF cc_srf;
    SRM_SRF cd_srf;

    /* Declare SRF parameter structures for CC and CD. */
    SRM_ORM_Parameters cc_params;
    SRM_ORM_Parameters cd_params;

    /* Declare generic coordinate handles for CC and CD. */
    SRM_Coordinate cd_coord = NULL;
    SRM_Coordinate cc_coord = NULL;

    /* Declare coordinate component value structures. */
    SRM_CD_3D_Coordinate cd_coord_info;
    SRM_Euclidean_3D_Coordinate cc_coord_info;

    printf( "Running SRM Sample test program...\n" );

    /* Initialize the CC and CD SRF parameters with ORM and HSR values set to WGS 1984. */
    cc_params.orm_code = SRM_ORM_WGS_1984;
    cc_params.hsr_code = SRM_HSR_WGS_1984_IDENTITY;
    cd_params.orm_code = SRM_ORM_WGS_1984;
    cd_params.hsr_code = SRM_HSR_WGS_1984_IDENTITY;

    /* Instantiate the CC SRF using the initialized CC parameter structure. */
    if (SRM_CreateSRF_CC( cc_params, &cc_srf ) != SRM_STAT_CODE_SUCCESS )
    {
        fprintf( stderr, "Failed to create CC SRF\n" );
    }

    /* Instantiate the CD using the initialized CD parameter structure. */
    else if (SRM_CreateSRF_CD( cd_params, &cd_srf ) != SRM_STAT_CODE_SUCCESS )
    {
        fprintf( stderr, "Failed to create CD SRF\n" );
        /* Free the instantiated CC SRF is failed to instantiate the CD SRF */
        SRM_FreeSRF( cc_srf );
    }
    else
    {
        /* Initialize the coordinate component value structure for the CD coordinate. */
        cd_coord_info.longitude = 0.0;
        cd_coord_info.latitude = 0.785398163397;
        cd_coord_info.ellipsoidal_height = 0.0;

        /* Create the CD coordinate using the initialized CD coordinate component value structure. */
        if (SRM_CreateCoordinateCD_3D( cd_srf, &cd_coord_info, &cd_coord ) != SRM_STAT_CODE_SUCCESS )
        {
            fprintf( stderr, "Failed to create CD coordinate\n" );
        }
        else
        {
            /* Perform the change SRF operation from the source SRF (CD) to the target SRF (CC). */
            if (SRM_ChangeCoordinateSRF( cd_srf, cd_coord, cc_srf, &cc_coord, NULL ) != SRM_STAT_CODE_SUCCESS )
            {
                fprintf( stderr, "SRM_ChangeCoordinateSRF failed\n" );
            }
            else
            {
                /* Get the resulting CC coordinate component values */
                if (SRM_GetCoordinateEuclidean_3D( cc_coord, &cc_coord_info ) != SRM_STAT_CODE_SUCCESS )
                {
                    fprintf( stderr, "Failed to get CC coordinate information\n" );
                }
                else
                {
                    /* Display the CC Coordinate component values. */
                    printf( "[ %f, %f, %f ]\n", cc_coord_info.u, cc_coord_info.v, cc_coord_info.w );
                }
                /* Release memory for the CC coordinate. */
                SRM_FreeCoordinate( cc_coord );
            }
            /* Release memory for the CD coordinate. */
            SRM_FreeCoordinate( cd_coord );
        }
        /* Release memory for the CC and CD SRFs. */
        SRM_FreeSRF( cd_srf );
        SRM_FreeSRF( cc_srf );
    }
    return 0;
}

SRM C 4.1 - Sample SRM Access
#include <stdio.h>
#include <string.h>

/* Header file for the SRM C API */
#include "srm.h"

int main
(
 int argc,
 char* argv[]
 )
{
  SRM_Coordinate_Valid_Region val_region;

  /* Declare specific SRF handles for CC and CD. */
  SRM_Celestiocentric cc_srf;
  SRM_Celestiodetic   cd_srf;

  /* Declare generic 3D coordinate handles for CC and CD. */
  SRM_Coordinate3D    cc_coord;
  SRM_Coordinate3D    cd_coord;

  SRM_Long_Float      ord1,ord2,ord3;

  printf( "Running SRM Sample test program...\n" );

  /* Instantiate the CD SRF with the WGS 1984 ORM and RT parameters. */
  if ( SRM_CD_Create( SRM_ORMCOD_WGS_1984,
                      SRM_RTCOD_WGS_1984_IDENTITY,
                      &cd_srf ) != SRM_STATCOD_SUCCESS )
    fprintf( stderr, "Failed to create CD SRF\n" );

  /* Instantiate the CC SRF with the WGS 1984 ORM and RT parameters. */
  else
    {
      if ( SRM_CC_Create( SRM_ORMCOD_WGS_1984,
                          SRM_RTCOD_WGS_1984_IDENTITY,
                          &cc_srf ) != SRM_STATCOD_SUCCESS )
        fprintf( stderr, "Failed to create CC SRF\n" );

      else
      {
          /* Create the CD coordinate using the initial coordinate component values. */
          /* The CreateCoordinate3D() method is a method of the SRM_Celestiodetic SRF. */
          if ( cd_srf.methods->CreateCoordinate3D( &cd_srf,
                                                   0.0,
                                                   0.785398163397,
                                                   0.0,
                                                   &cd_coord ) != SRM_STATCOD_SUCCESS )
            fprintf( stderr, "Failed to create CD coordinate\n" );
          else
          {
              /* Create the CC coordinate using the initial coordinate component values. */
              /* The CreateCoordinate3D() method is a method of the SRM_Celestiocentric SRF. */
              if ( cc_srf.methods->CreateCoordinate3D( &cc_srf,
                                                       0.0,
                                                       0.0,
                                                       0.0,
                                                       &cc_coord ) != SRM_STATCOD_SUCCESS )
                  fprintf( stderr, "Failed to create CC coordinate\n" );
              else
              {
                  /* Perform the change SRF operation from the source SRF (CD) to the target SRF (CC). */
                  /* The ChangeCoordinate3DSRF() method is a method of the SRM_Celestiocentric SRF. */
                  /* The change SRF method must always be called by the target SRF, CC in this case. */
                  if ( cc_srf.methods->ChangeCoordinate3DSRF( &cc_srf,
                                                              &cd_srf,
                                                              &cd_coord,
                                                              &cc_coord,
                                                              &val_region ) != SRM_STATCOD_SUCCESS )
                    fprintf( stderr, "SRM_ChangeCoordinateSRF failed\n" );
                  else
                  {
                      /* Get the resulting CC coordinate component values */
                      /* The GetCoordinate3DValues() method is a method of the SRM_Celestiocentric SRF. */
                      if ( cc_srf.methods->GetCoordinate3DValues( &cc_srf,
                                                                  &cc_coord,
                                                                  &ord1,
                                                                  &ord2,
                                                                  &ord3 ) != SRM_STATCOD_SUCCESS )
                        fprintf( stderr, "Failed getting the CC coordinate values\n" );
                      else

                        /* Display the CC Coordinate component values */
                        printf("[ %lf, %lf, %lf ]\n\n", ord1, ord2, ord3 );
                    }

                  /* Release memory for the CC coordinate. */
                  /* The DestroyCoordinate3D() method is a method of the SRM_Celestiocentric SRF. */
                  cc_srf.methods->DestroyCoordinate3D(&cc_srf,
                                                      &cc_coord);        
                }

              /* Release memory for the CD coordinate. */
              /* The DestroyCoordinate3D() method is a method of the SRM_Celestiodetic SRF. */
              cd_srf.methods->DestroyCoordinate3D(&cd_srf,
                                                  &cd_coord);        
            }

          /* Release memory for the CC SRF. */
          /* The Destroy() method is a method of the SRM_Celestiocentric SRF. */
          cc_srf.methods->Destroy(&cc_srf);        
        }

      /* Release memory for the CD SRF. */
      /* The Destroy() method is a method of the SRM_Celestiodetic SRF. */
      cd_srf.methods->Destroy(&cd_srf);
    }
    return 0;
}

Related Links

  1. The ISO 18042-4 - SRM C Language Binding specification.
  2. The SEDRIS website has relevant information on SRM and other SEDRIS technologies.
  3. The SRM C API Users' Guide describes the main concepts used in SRM and related examples.
  4. The SRM C API describes the SRM C API.

Copyright © 2011 SEDRIS