GeoTrans_FromGlobalDirection function

Applies To: Implementing a custom GeoTransformer

Performs coordinates transformation used in the process chain starting from global ground (real world) coordinates, converting them into a virtual object’s coordinate system. In this document, we will refer to the direction of this transformation as FromGlobal (also know as “ground to image”). Our convention on defining, for example, a correction is that we correct towards global ground coordinates, which means this function will 'uncorrect'.

GeoTransCore component will forward this call to your implementation whenever coordinates must be transformed by your custom GeoTransformer. This function is the main reason of implementing a GeoTransformer and represents a minimal requirement.


BOOL __stdcall GeoTrans_FromGlobalDirection(

HGeoTrans hInstance, // handle of GeoTransformer instance

const GeoTransData * inData, // pointer to input package

GeoTransData * outData // pointer to output package



extern "C" BOOL __stdcall GeoTrans_FromGlobalDirection(

HGeoTrans hInstance, // handle of GeoTransformer instance

const GeoTransData& inData, // input package

GeoTransData& outData // output package



[in] hInstance

Custom GeoTransformer instance handle. This handle specifies which instance should be used when transforming given coordinates. The given handle value may point to any type of GeoTransformer supported by your implementation. Refer to the documentation of Instance_Create function for details about a handle to a GeoTransformer instance.

HGeoTrans type is defined as a HANDLE in GeoTransCreation namespace.

Note: It is not required to test against NULL the value of the handle, since GeoTransCore component ensures its validity.

[in] inData

A read-only input package that contains coordinates to be transformed. The package is self-descriptive through its dwType member, as documented in GeoTransData structure.

[in,out] outData

An output package that returns the transformed coordinates. Please refer to GeoTransData structure’s documentation for details of a package self-descriptive content.

Note: Do not assume that both input and output packages have the same type. Testing their validity and compatibility should be considered. You may choose to support only a restricted set of package types (lets say, only 3D arrays), but your implementation should not make any assumptions about their types (not even based on human logic, like receiving 3 points in the input package means 3 points can be returned in the output package).

Important: Do not change the type of the output package! Also, if applicable, array dimension must not be changed! The only data that may be changed in this structure represents coordinates. All other members are given by calling components to describe the required output format, as it was previously allocated.

Return Value

Return FALSE when outData package does not contain expected transformed coordinates. Setting an error code with SetLastError function will identify the reason(s) for failure. When the transformation was successful, but some warning(s) should be signaled, set an appropriate code but return TRUE.

Reporting errors and warnings: To learn how to provide descriptions for your custom error and warning codes, please see Error_FormatMessage function documentation. GTM_Errors_Warnings namespace enumerates some recommended codes and descriptions to be supported, from which the following would be set by this function:




Cannot transform in this direction.


Invalid input data.


Invalid output data.


Unsupported input data type.


Unsupported output data type.


Input and output data types are incompatible.


Input and output must have the same data type.


Input and output arrays must have same size.


There are quite a few considerations when implementing this function, but probably the most important of all is that both input and output packages may point to the same buffer of coordinates. Thus, it is essential that your implementation makes a copy of an input coordinate before writing the corresponding output coordinate in case that original value still needs to be used in the computation. Following sample code shows the undesired behavior of replacing the input data when shares the same memory with the output data:

[C / C++]

#include <windows.h>

#include <math.h>

#define M_PI 3.14159265358979323846


void Rotate2dPoints(double angleDegrees,const double * inPoints,double * outPoints,size_t noPoints) {

double angleRadians = angleDegrees * M_PI / 180;

register int idx = noPoints;

while (idx) { --idx;

outPoints[2*idx] = cos(angleRadians) * inPoints[2*idx] - sin(angleRadians) * inPoints[2*idx+1];

/* at this point, value of inPoints[2*idx] is also changed */

outPoints[2*idx+1] = sin(angleRadians) * inPoints[2*idx] + cos(angleRadians) * inPoints[2*idx+1];



int main(int ,char ** ,char ** ) {

double points[4] = {0};

points[0] = points[3] = 1.0;


return 0;


When checking the type of I / O packages given as parameters, only the least significant byte defines the structure of the package (bits 8-31 are reserved for geo-interpretation). This means you should compare only the first byte of dwType member (use dwType & 0xFF) of the GeoTransData structure against the enumerated values defined in GeoTransDataTypes namespace. For your implementation to remain compatible with later versions of the GeoTransCore component, do not try to process undefined package types. Simply set an error code that describes an unsupported argument type and return FALSE.

Multi-threading: Concurrent calls from different threads will expect this implementation to be thread safe.

Exception handling: Careful interpretation of the I / O packages represent the most important task in avoiding exceptions.



32 bit Windows OS


ANSI C / C++ Standard compliant


__stdcall calling convention; by name, undecorated "C" export

Unicode support









This sample was depicted from an implementation of a 2D affine transformation (please note that it completely ignores Z values):


#define ERR_TDP_INVALID(dwFlags,trans_only)\

if (dwFlags & trans_only) {\


return FALSE;\


if (! {\


return FALSE;\


if (! {\


return FALSE;\


#define ERR_TDP_UNSUPPORTED(mask,condition)\

if ((inData.dwType mask) condition) {\


return FALSE;\


if ((outData.dwType mask) condition) {\


return FALSE;\



if ((inData.dwType & 0x6) != (outData.dwType & 0x6)) {\


return FALSE;\


#define ERR_TDP_SIZE()\

if (>MPoints2D.pntNo !=>MPoints2D.pntNo) {\


return FALSE;\



#define GEOTRANS_AFFINE(tp,ip,op)\

double x;\

x = (tp.A1 * ip.X) + (tp.A2 * ip.Y) + tp.A0;\

op.Y = (tp.B1 * ip.X) + (tp.B2 * ip.Y) + tp.B0;\

op.X = x;


BOOL __stdcall Affine::GeoTrans_FromGlobalDirection(

const GeoTransData& inData,

GeoTransData& outData

) {




if (inData.dwType & 0x2) { // arrays given


int iStride = 3-(inData.dwType & 0x1); // Stride2D=2;Stride3D=3

int oStride = 3-(outData.dwType & 0x1); // Stride2D=2;Stride3D=3

register int idx =>MPoints2D.pntNo; // same offset in MPoints3D ;)

double * iXYs = (double*)>MPoints2D.XYs; // same offset in MPoints3D ;)

double * oXYs = (double*)>MPoints2D.XYs; // same offset in MPoints3D ;)

while (idx) { --idx;


iXYs += iStride;

oXYs += oStride;


return TRUE;


VERTEX2D& ip = *&>Point2D;

VERTEX2D& op = *&>Point2D;


return TRUE;



extern "C" BOOL __stdcall GeoTrans_FromGlobalDirection(

HGeoTrans hInstance,

const GeoTransData& inData,

GeoTransData& outData

) {

return ((Affine*)hInstance)->GeoTrans_FromGlobalDirection(inData,outData);


For a detailed example on how to implement this function, please see Custom GeoTransformer VC++ Sample.

Related Topics

See also: Instance_Create, Instance_Discard, GeoTrans_ToGlobalDirection, Error_FormatMessage, GeoTransCreation, GTM_Errors_Warnings, GeoTransDataTypes, GeoTransData