Share |

Convert GPS coordinates to UTM using Microsoft Visual C++

Dowload 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

UTM

UTM stands for Universal Transverse Mercator. It is a Transverse Mercator map projection which can be used at any place on the globe. To cover the whole earth, the system is divided into multiple grids, using 60 zones, each covering 6 degrees which is about 800 kilometers in width.

Each zone is defined for both the northern and southern hemisphere. Therefore the zones are called zone 1N - zone 60N for the northern hemisphere and zone 1S - zone 60S for the southern hemisphere.

This document is going to explain, how you can add support for UTM coordinates to your Visual C++ projects.

UTM Zones

The following table describes which UTM zone should be used on any given location on the earth, and its associated UTM parameters:

Zone Longitude Range Hemisphere False Northing False Easting Latitude Origin Longitude Origin Scale Factor
1N 180W - 174W N 0 500000 0 -177 0.9996
1S 180W - 174W S 10000000 500000 0 -177 0.9996
2N 174W - 168W N 0 500000 0 -171 0.9996
2S 174W - 168W S 10000000 500000 0 -171 0.9996
3N 168W - 162W N 0 500000 0 -165 0.9996
3S 168W - 162W S 10000000 500000 0 -165 0.9996
4N 162W - 156W N 0 500000 0 -159 0.9996
4S 162W - 156W S 10000000 500000 0 -159 0.9996
5N 156W - 150W N 0 500000 0 -153 0.9996
5S 156W - 150W S 10000000 500000 0 -153 0.9996
6N 150W - 144W N 0 500000 0 -147 0.9996
6S 150W - 144W S 10000000 500000 0 -147 0.9996
7N 144W - 138W N 0 500000 0 -141 0.9996
7S 144W - 138W S 10000000 500000 0 -141 0.9996
8N 138W - 132W N 0 500000 0 -135 0.9996
8S 138W - 132W S 10000000 500000 0 -135 0.9996
9N 132W - 126W N 0 500000 0 -129 0.9996
9S 132W - 126W S 10000000 500000 0 -129 0.9996
10N 126W - 120W N 0 500000 0 -123 0.9996
10S 126W - 120W S 10000000 500000 0 -123 0.9996
11N 120W - 114W N 0 500000 0 -117 0.9996
11S 120W - 114W S 10000000 500000 0 -117 0.9996
12N 114W - 108W N 0 500000 0 -111 0.9996
12S 114W - 108W S 10000000 500000 0 -111 0.9996
13N 108W - 102W N 0 500000 0 -105 0.9996
13S 108W - 102W S 10000000 500000 0 -105 0.9996
14N 102W - 096W N 0 500000 0 -99 0.9996
14S 102W - 096W S 10000000 500000 0 -99 0.9996
15N 096W - 090W N 0 500000 0 -93 0.9996
15S 096W - 090W S 10000000 500000 0 -93 0.9996
16N 090W - 084W N 0 500000 0 -87 0.9996
16S 090W - 084W S 10000000 500000 0 -87 0.9996
17N 084W - 078W N 0 500000 0 -81 0.9996
17S 084W - 078W S 10000000 500000 0 -81 0.9996
18N 078W - 072W N 0 500000 0 -75 0.9996
18S 078W - 072W S 10000000 500000 0 -75 0.9996
19N 072W - 066W N 0 500000 0 -69 0.9996
19S 072W - 066W S 10000000 500000 0 -69 0.9996
20N 066W - 060W N 0 500000 0 -63 0.9996
20S 066W - 060W S 10000000 500000 0 -63 0.9996
21N 060W - 054W N 0 500000 0 -57 0.9996
21S 060W - 054W S 10000000 500000 0 -57 0.9996
22N 504W - 048W N 0 500000 0 -51 0.9996
22S 054W - 048W S 10000000 500000 0 -51 0.9996
23N 048W - 042W N 0 500000 0 -45 0.9996
23S 048W - 042W S 10000000 500000 0 -45 0.9996
24N 042W - 036W N 0 500000 0 -39 0.9996
24S 042W - 036W S 10000000 500000 0 -39 0.9996
25N 036W - 030W N 0 500000 0 -33 0.9996
25S 036W - 030W S 10000000 500000 0 -33 0.9996
26N 030W - 024W N 0 500000 0 -27 0.9996
26S 030W - 024W S 10000000 500000 0 -27 0.9996
27N 024W - 018W N 0 500000 0 -21 0.9996
27S 024W - 018W S 10000000 500000 0 -21 0.9996
28N 018W - 012W N 0 500000 0 -15 0.9996
28S 018W - 012W S 10000000 500000 0 -15 0.9996
29N 012W - 006W N 0 500000 0 -9 0.9996
29S 012W - 006W S 10000000 500000 0 -9 0.9996
30N 006W - 000W N 0 500000 0 -3 0.9996
30S 006W - 000W S 10000000 500000 0 -3 0.9996
31N 000E - 006E N 0 500000 0 3 0.9996
31S 000E - 006E S 10000000 500000 0 3 0.9996
32N 006E - 012E N 0 500000 0 9 0.9996
32S 006E - 012E S 10000000 500000 0 9 0.9996
33N 012E - 018E N 0 500000 0 15 0.9996
33S 012E - 018E S 10000000 500000 0 15 0.9996
34N 018E - 024E N 0 500000 0 21 0.9996
34S 018E - 024E S 10000000 500000 0 21 0.9996
35N 024E - 030E N 0 500000 0 27 0.9996
35S 024E - 030E S 10000000 500000 0 27 0.9996
36N 030E - 036E N 0 500000 0 33 0.9996
36S 030E - 036E S 10000000 500000 0 33 0.9996
37N 036E - 042E N 0 500000 0 39 0.9996
37S 036E - 042E S 10000000 500000 0 39 0.9996
38N 042E - 048E N 0 500000 0 45 0.9996
38S 042E - 048E S 10000000 500000 0 45 0.9996
39N 048E - 054E N 0 500000 0 51 0.9996
39S 048E - 054E S 10000000 500000 0 51 0.9996
40N 054E - 060E N 0 500000 0 57 0.9996
40S 054E - 060E S 10000000 500000 0 57 0.9996
41N 060E - 066E N 0 500000 0 63 0.9996
41S 060E - 066E S 10000000 500000 0 63 0.9996
42N 066E - 072E N 0 500000 0 69 0.9996
42S 066E - 072E S 10000000 500000 0 69 0.9996
43N 072E - 078E N 0 500000 0 75 0.9996
43S 072E - 078E S 10000000 500000 0 75 0.9996
44N 078E - 084E N 0 500000 0 81 0.9996
44S 078E - 084E S 10000000 500000 0 81 0.9996
45N 084E - 090E N 0 500000 0 87 0.9996
45S 084E - 090E S 10000000 500000 0 87 0.9996
46N 090E - 096E N 0 500000 0 93 0.9996
46S 090E - 096E S 10000000 500000 0 93 0.9996
47N 096E - 102E N 0 500000 0 99 0.9996
47S 096E - 102E S 10000000 500000 0 99 0.9996
48N 102E - 108E N 0 500000 0 105 0.9996
48S 102E - 108E S 10000000 500000 0 105 0.9996
49N 108E - 114E N 0 500000 0 111 0.9996
49S 108E - 114E S 10000000 500000 0 111 0.9996
50N 114E - 120E N 0 500000 0 117 0.9996
50S 114E - 120E S 10000000 500000 0 117 0.9996
51N 120E - 126E N 0 500000 0 123 0.9996
51S 120E - 126E S 10000000 500000 0 123 0.9996
52N 126E - 132E N 0 500000 0 129 0.9996
52S 126E - 132E S 10000000 500000 0 129 0.9996
53N 132E - 138E N 0 500000 0 135 0.9996
53S 132E - 138E S 10000000 500000 0 135 0.9996
54N 138E - 144E N 0 500000 0 141 0.9996
54S 138E - 144E S 10000000 500000 0 141 0.9996
55N 144E - 150E N 0 500000 0 147 0.9996
55S 144E - 150E S 10000000 500000 0 147 0.9996
56N 150E - 156E N 0 500000 0 153 0.9996
56S 150E - 156E S 10000000 500000 0 153 0.9996
57N 156E - 162E N 0 500000 0 159 0.9996
57S 156E - 162E S 10000000 500000 0 159 0.9996
58N 162E - 168E N 0 500000 0 165 0.9996
58S 162E - 168E S 10000000 500000 0 165 0.9996
59N 168E - 174E N 0 500000 0 171 0.9996
59S 168E - 174E S 10000000 500000 0 171 0.9996
60N 174E - 180E N 0 500000 0 177 0.9996
60S 174E - 180E S 10000000 500000 0 177 0.9996

The Eye4Software GPS Toolkit

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\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 *   pDatum          = NULL;

You can create instances of the objects like this:

CoCreateInstance ( CLSID_GpsProjection,      NULL, CLSCTX_INPROC_SERVER, IID_IGpsProjection,     ( void ** ) &pProjection );
CoCreateInstance ( CLSID_GpsDatumParameters, NULL, CLSCTX_INPROC_SERVER, IID_IGpsGridParameters, ( void ** ) &pDatum      );

The pProjection and pDatum should not be zero after the CoCreateInstance calls, 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 source code below demonstrates how to add latitude / longitude to UTM transformation functionality to your program using the GPS Toolkit. In this example a position is transformed from WGS84 to UTM WGS84. Using the 'ToUTM' function, the software will automatically calculate the UTM zone for the given position. To perform a inverse calculation use the 'FromUTM' function.

// ConvUTM Visual C++ demo - Eye4Software GPS Toolkit
// This demo shows how to convert a latitude/longitude coordinate to an UTM grid coordinate.
// 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;
IGpsDatumParameters *   pDatum          = NULL;

DOUBLE                  fNorthing       = 0.0;
DOUBLE                  fEasting        = 0.0;

LONG                    lLastError      = 0L;
LONG                    lZone           = 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 the map datum for UTM
    CoCreateInstance ( CLSID_GpsDatumParameters, NULL, CLSCTX_INPROC_SERVER, IID_IGpsDatumParameters, ( void ** ) &pDatum );

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

    // Set Datum ( WGS84 )
    // The ID for WGS84 is 4326, see 'http://www.eye4software.com/resources/datums' for a full list of supported datums 
    // To use UTM with another map datum, just change the code below (EPSG code)
    pDatum->LoadFromId ( 4326 );

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

    // Perform map projection
    pProjection->ToUTM              ( &variant_t ( ( IDispatch * ) pDatum ) );
	
    // 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  );
        pProjection->get_Zone       ( &lZone     );

        printf ( "(WGS84) 55.4 N, 2.89 W => (UTM Zone %ld)\nNorthing = %3.2lf, Easting = %3.2lf\n" , lZone, fNorthing, fEasting );
    }
    else
    {
        pProjection->get_LastErrorDescription ( &bstrLastError );

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

        SysFreeString ( bstrLastError );
    }

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

_EndMain:

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

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

    return 0;
}

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