Share |

Convert GPS coordinates from one map grid to another using Visual C++

Download Eye4Software GPS Toolkit free trial Download the Eye4Software GPS Toolkit fully functional 30 day trial version for free
Browse through the Eye4Software GPS Toolkit for Windows manual Browse through the Eye4Software GPS Toolkit manual

Introduction

The Eye4Software GPS toolkit allows software developers to add GPS functionality to their own programs without the need to have any knowledge on serial communications and GPS protocols like RS-232 and NMEA0183.

The product can be used in many programming environments, such as Visual Basic, Visual C++, Visual Studio.Net, Borland C++ Builder, Borland Delphi and VBA, but also web oriented applications such as ASP, ASP.NET and PHP, and all other programming environments that support ActiveX.

Prerequisites

First you must have Visual C++ and the Eye4Software GPS Component installed on your computer. We will use Visual C++ 6.0 in this document, but all versions from 6.0 and up can be used. You can download the Eye4Software GPS Component here.

Creating the project

Start the Visual C++ IDE, and select the "New" option from the "File" menu. The "New Project" dialog now appears, you can use the dialog to enter the name of your product. Select "Win32 Console Application" if you wish to create a console application, or select the "MFC AppWizard" option to create a project with a GUI.

map projection demo

Copy the include files

In order to declare and create the objects from your Visual C++ application, you need to copy the include files of the ActiveX control to your project directory. You can create an include folder in your project folder where you store these files. These files can be found in the "Samples\Visual C++\Include" folder from the installation directory.

Declare and create the object(s)

Once you copied the include files, you have to declare these files in your source code like this:

#include "include\GpsCtrl.h"
#include "include\GpsConstantsX.h"
#include "include\GpsCtrl_i.c"

You can also include the ".c" file in your project instead of using the #include directive for this file.

The objects can be declared in your code like this:

IGpsProjection      *   pProjection     = NULL;
IGpsDatumParameters *   pDatumSrc       = NULL;
IGpsDatumParameters *   pDatumDst       = NULL;
IGpsGridParameters  *   pGridSrc        = NULL;
IGpsGridParameters  *   pGridDst        = NULL;

You can create the m_pGps instance of the object like this:

CoCreateInstance ( CLSID_GpsProjection, NULL, CLSCTX_INPROC_SERVER, IID_IGpsProjection, ( void ** ) &pProjection );
CoCreateInstance ( CLSID_GpsDatumParameters, NULL, CLSCTX_INPROC_SERVER, IID_IGpsDatumParameters, ( void ** ) &pDatumSrc );
CoCreateInstance ( CLSID_GpsDatumParameters, NULL, CLSCTX_INPROC_SERVER, IID_IGpsDatumParameters, ( void ** ) &pDatumDst );
CoCreateInstance ( CLSID_GpsGridParameters, NULL, CLSCTX_INPROC_SERVER, IID_IGpsGridParameters, ( void ** ) &pGridSrc );
CoCreateInstance ( CLSID_GpsGridParameters, NULL, CLSCTX_INPROC_SERVER, IID_IGpsGridParameters, ( void ** ) &pGridDst );

The pProjection, pGridSrc, pGridDst, pDatumSrc or pDatumDst pointers should not be zero, if this is the case, creation of the instance has failed. In this case please check the following:

  • Is the GpsCtl32.dll or GpsCtl64.dll component copieed and registered on this computer;
  • Did you call CoInitialize () or AfxOleInit () in your project before calling CoCreateInstance ();
  • Did you install the correct DLL for the OS used (x86/x64).

The source code

The following samples show how to perform a map projection transformation using the GPS Toolkit. In this example a position is transformed from WGS84 to British National Grid. For a list of other map grids, please refer to our map grid list.

The first sample uses the simple approach, map grids are loaded from the internal database using the EPSG identification code. This is the recommended approach for user with little or no experience in geodesy.

The seconds sample does not use the internal database, but all parameters are set manually. This allows you to define custom grids or to modify grids loaded from the internal database. For experienced users only.

Simple Grid Conversion

// ConvGrid Visual C++ demo - Eye4Software GPS Toolkit
// This demo shows how to convert a GPS coordinate from one map grid to another.
// For more information on how to use the Eye4Software GPS Toolkit with Visual C++, 
// visit http://www.eye4software.com/products/gpstoolkit/source#vc

////////////////////////////////////////////////////////////////////////////////////////////

#include <windows.h>
#include <comutil.h>
#include <stdio.h>

////////////////////////////////////////////////////////////////////////////////////////////

#include "..\Include\GpsCtrl.h" 

////////////////////////////////////////////////////////////////////////////////////////////

IGpsProjection      *   pProjection     = NULL;

IGpsGridParameters  *   pGridSrc        = NULL;
IGpsGridParameters  *   pGridDst        = NULL;

DOUBLE                  fNorthing       = 0.0;
DOUBLE                  fEasting        = 0.0;

LONG                    lLastError      = 0L;

BSTR                    bstrLastError   = NULL;

////////////////////////////////////////////////////////////////////////////////////////////

int main(int argc, char* argv[])
{
  // Initialize COM
  CoInitialize ( NULL );

  // Create instance of GpsProjection object
  CoCreateInstance ( CLSID_GpsProjection, NULL, CLSCTX_INPROC_SERVER, IID_IGpsProjection, ( void ** ) &pProjection );

  if ( pProjection == NULL )
  {
    printf ( "Failed to create instance of GpsProjection object\n" );
    goto _EndMain;
  }

  // Create instances of the GpsGridParameters object to specify source and destination grid
  CoCreateInstance ( CLSID_GpsGridParameters, NULL, CLSCTX_INPROC_SERVER, IID_IGpsGridParameters, ( void ** ) &pGridSrc );
  CoCreateInstance ( CLSID_GpsGridParameters, NULL, CLSCTX_INPROC_SERVER, IID_IGpsGridParameters, ( void ** ) &pGridDst );

  if ( pGridDst == NULL )
  {
    printf ( "Failed to create instance of GpsgridParameters object\n" );
    goto _EndMain;
  }

  if ( pGridSrc == NULL )
  {
    printf ( "Failed to create instance of GpsgridParameters object\n" );
    goto _EndMain;
  }
    
  // Set Source Grid ( WGS84, Geographic Latitude and Longitude  )
  // The ID for WGS84 is 4326, see 'http://www.eye4software.com/resources/datums' for a full list of supported datums 
  // To convert from another datum or grid, just change the code below (EPSG code)
  // To define your own grid or datum, please have a look at the 'ConvUserGrid' Visual C++ demo.
  pGridSrc->LoadFromId ( 4326 );

  // Set Destination Grid ( British National Grid )
  // The ID for the British National Grid is 27700, see 'http://www.eye4software.com/resources/grids' for a full list of supported grids 
  // To convert to another grid, just change the code below (EPSG code)
  // To define your own grid or datum, please have a look at the 'ConvUserGrid' Visual C++ demo.
  pGridDst->LoadFromId ( 27700 );

  // Set Source Latitude and Longitude in decimal degrees format
  pProjection->put_Latitude       ( 55.400 );
  pProjection->put_Longitude      ( -2.890 );

  // Perform the map projection
  // For reverse operation, just swap the pGridSrc and pGridDst parameters, and use put_Northing and put_Easting to set source coordinates
  pProjection->TransformGrid      ( &variant_t ( ( IDispatch * ) pGridSrc ), &_variant_t ( ( IDispatch * ) pGridDst ) );

  // Get the result of the operation
  pProjection->get_LastError      ( &lLastError );

  // If success, print the result, otherwise display error description:
  if ( lLastError == 0L )
  {
    pProjection->get_Northing   ( &fNorthing );
    pProjection->get_Easting    ( &fEasting  );

    printf ( "(WGS84) 55.4 N, 2.89 W => (British National Grid) Northing = %3.2lf, Easting = %3.2lf\n" , fNorthing, fEasting );
  }
  else
  {
    pProjection->get_LastErrorDescription ( &bstrLastError );

    printf ( "Error occured map projection: %ld (%ls)\n", lLastError, bstrLastError );

    SysFreeString ( bstrLastError );
  }

  printf ( "Ready.\n\n" );

_EndMain:

  if ( pProjection )
  {
    pProjection->Release ();
    pProjection = NULL;
  }

  if ( pGridSrc )
  {
    pGridSrc->Release ();
    pGridSrc = NULL;
  }

  if ( pGridDst )
  {
    pGridDst->Release ();
    pGridDst = NULL;
  }

  return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////

Advanced Grid Conversion

// ConvUserGrid Visual C++ demo - Eye4Software GPS Toolkit
// This demo shows how to convert a coordinate from one (user defined) map grid to another.
// If you only want to use well known map grids, you should have a look at the 'ConvGrid' demo.
// For more information on how to use the Eye4Software GPS Toolkit with Visual C++, 
// visit http://www.eye4software.com/products/gpstoolkit/source#vc

////////////////////////////////////////////////////////////////////////////////////////////

#include <windows.h>
#include <comutil.h>
#include <tchar.h>

////////////////////////////////////////////////////////////////////////////////////////////

#include "..\Include\GpsCtrl.h" 
#include "..\Include\GpsConstantsX.h" 

////////////////////////////////////////////////////////////////////////////////////////////

IGpsProjection      *   pProjection     = NULL;

IGpsDatumParameters *   pDatumSrc       = NULL;
IGpsDatumParameters *   pDatumDst       = NULL;

IGpsGridParameters  *   pGridSrc        = NULL;
IGpsGridParameters  *   pGridDst        = NULL;

DOUBLE                  fNorthing       = 0.0;
DOUBLE                  fEasting        = 0.0;

LONG                    lLastError      = 0L;

BSTR                    bstrLastError   = NULL;

////////////////////////////////////////////////////////////////////////////////////////////

int main(int argc, char* argv[])
{
  // Initialize COM
  CoInitialize ( NULL );

  // Create instance of GpsProjection object
  CoCreateInstance ( CLSID_GpsProjection, NULL, CLSCTX_INPROC_SERVER, IID_IGpsProjection, ( void ** ) &pProjection );

  if ( pProjection == NULL )
  {
    printf ( "Failed to create instance of GpsProjection object\n" );
    goto _EndMain;
  }

  // Create instances of the GpsDatumParameters object to specify source and destination datum
  CoCreateInstance ( CLSID_GpsDatumParameters, NULL, CLSCTX_INPROC_SERVER, IID_IGpsDatumParameters, ( void ** ) &pDatumSrc );
  CoCreateInstance ( CLSID_GpsDatumParameters, NULL, CLSCTX_INPROC_SERVER, IID_IGpsDatumParameters, ( void ** ) &pDatumDst );

  if ( pDatumDst == NULL )
  {
    printf ( "Failed to create instance of GpsDatumParameters object\n" );
    goto _EndMain;
  }

  if ( pDatumSrc == NULL )
  {
    printf ( "Failed to create instance of GpsDatumParameters object\n" );
    goto _EndMain;
  }

  // Create instances of the GpsGridParameters object to specify source and destination grid
  CoCreateInstance ( CLSID_GpsGridParameters, NULL, CLSCTX_INPROC_SERVER, IID_IGpsGridParameters, ( void ** ) &pGridSrc );
  CoCreateInstance ( CLSID_GpsGridParameters, NULL, CLSCTX_INPROC_SERVER, IID_IGpsGridParameters, ( void ** ) &pGridDst );

  if ( pGridDst == NULL )
  {
    printf ( "Failed to create instance of GpsgridParameters object\n" );
    goto _EndMain;
  }

  if ( pGridSrc == NULL )
  {
    printf ( "Failed to create instance of GpsgridParameters object\n" );
    goto _EndMain;
  }

  // Set Source Datum Parameters ( WGS84 )
  pDatumSrc->Clear ();

  // Semi Major Axis of WGS84 ellipsoid
  pDatumSrc->put_Axis             ( 6378137.0 );

  // Inverse Flattening of WGS84 ellipsoid
  pDatumSrc->put_Flattening       ( 298.257223563 );

  // Set Destination Datum Parameters ( OSGB36 )
  pDatumDst->Clear ();

  // Semi Major Axis of Airy 1830 ellipsoid
  pDatumDst->put_Axis             ( 6377563.396 );

  // Inverse Flattening of Airy 1830 ellipsoid
  pDatumDst->put_Flattening       ( 299.3249646 );

  // Set Helmert-7 parameters OSGB36 => WGS84
  pDatumDst->put_TranslationX     (  446.448 );
  pDatumDst->put_TranslationY     ( -125.157 );
  pDatumDst->put_TranslationZ     (  542.060 );

  pDatumDst->put_RotationX        (  0.150 );
  pDatumDst->put_RotationY        (  0.247 );
  pDatumDst->put_RotationZ        (  0.842 );

  pDatumDst->put_ScaleFactor      ( -20.4894 );

  // Set Source Grid properties ( Latitude/Longitude, WGS84 )
  pGridSrc->put_Projection        ( GPS_PROJECTION_NONE );
  pGridSrc->put_Datum             ( &_variant_t ( ( IDispatch * ) pDatumSrc ) );

  // Set Destination Grid properties ( Transverse Mercator, OSGB36, British National Grid )
  pGridDst->put_Projection        ( GPS_PROJECTION_TRANSVERSEMERCATOR );
  pGridDst->put_Datum             ( &_variant_t ( ( IDispatch * ) pDatumDst ) );

  pGridDst->put_FalseEasting      (  400000 );
  pGridDst->put_FalseNorthing     ( -100000 );

  pGridDst->put_OriginLatitude    ( 49.0 );
  pGridDst->put_OriginLongitude   ( -2.0 );

  pGridDst->put_ScaleFactor       ( 0.999601271 );

  // Set Source Latitude and Longitude 
  pProjection->put_Latitude       ( 55.400 );
  pProjection->put_Longitude      ( -2.890 );

  // Perform map projection
  pProjection->TransformGrid      ( &variant_t ( ( IDispatch * ) pGridSrc ), &_variant_t ( ( IDispatch * ) pGridDst ) );

  // Get the result of the operation
  pProjection->get_LastError      ( &lLastError );

  // If success, print the result, otherwise display error description:
  if ( lLastError == 0L )
  {
    pProjection->get_Northing   ( &fNorthing );
    pProjection->get_Easting    ( &fEasting  );

    printf ( "(WGS84) 55.4 N, 2.89 W => (British National Grid) Northing = %3.2lf, Easting = %3.2lf\n" , fNorthing, fEasting );
  }
  else
  {
    pProjection->get_LastErrorDescription ( &bstrLastError );

    printf ( "Error occured map projection: %ld (%ls)\n", lLastError, bstrLastError );

    SysFreeString ( bstrLastError );
  }

  printf ( "Ready.\n\n" );

_EndMain:

  if ( pProjection )
  {
    pProjection->Release ();
    pProjection = NULL;
  }

  if ( pDatumSrc )
  {
    pDatumSrc->Release ();
    pDatumSrc = NULL;
  }

  if ( pDatumDst )
  {
    pDatumDst->Release ();
    pDatumDst = NULL;
  }

  if ( pGridSrc )
  {
    pGridSrc->Release ();
    pGridSrc = NULL;
  }

  if ( pGridDst )
  {
    pGridDst->Release ();
    pGridDst = NULL;
  }

  return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////