English

How To: Project in MapObjects using C++

Summary

If you need to project your data from geographic to another system, you may need to define the coordinate system you are going from and the one you are going to.

You don't need to define a coordinate system if your data has associated projection information (a .prj file for shapefiles, or projection information if using SDE).

In the event that you need to define a coordinate system, you can do it in C++. The following code shows how you can do this.

You may also need to apply geotransformation, if the geographic coordinate system for your target projection is different than the coordinate system of your source.

Procedure

This code is a modification of the projection sample.


Code:
// The source layer is in geographics therefore define a Geographic
// Coordinate System, this code uses WGS1984.
// Your data may be based on a different GCS CMoGeoCoordSys pGCS.

// Create a dispatch pointer for it
pGCS.CreateDispatch(TEXT("MapObjects2.GeoCoordSys"));

// Check if the previous step was successful
if (!LPDISPATCH(pGCS)) AfxMessageBox("Dispatch Pointer NOT created");

// Assume all is OK and set the projection type
pGCS.SetType(moGeoCS_WGS1984);

// Get all the map layers - This code assumes only one layer
CMoLayers m_layers(m_map.GetLayers());

// Create a VARIANT structure to hold the integer index for map layers
VARIANT va_index;
VariantInit(&va_index);
va_index.vt = VT_I4; // This is the TYPE (integer) the VARIANT will hold
va_index.lVal = 0; // This is the integer value

// Get the nth layer (0) from the maplayers
CMoMapLayer pLayer(m_layers.Item(va_index));

// Reset the VARIANT to 1 for the next layer etc.
// If applicable, each layer must be told where it is coming FROM.
// Not all might be geographic, some might be projected.
// It doesn't matter. So long as you define where they are
// coming from. MapObjects will project or re-project
// to the TARGET coordinate system. va_index.lVal = 1;

// Now another VARIANT to handle dispatch pointers from the GCS
// coordinate system
VARIANT vaGCS;
VariantInit(&vaGCS);
vaEast.vt = VT_DISPATCH;

// Set the VARIANTs to the dispatch pointer for the
// geographic coordinate systems
vaGCS.pdispVal = pGCS.m_lpDispatch;

// These lines check if a layer already has a coordinate system set.
// If so, the dispatch pointer for the layers coordinate system
// is Released, otherwise we'd get a memory leak. If the map
// was not using one of these two coordinate systems,
// we'd have to do a similar test for the map.
IDispatch* tempDisp;
tempDisp = pLayer.GetCoordinateSystem().pdispVal;
if (tempDisp != NULL) tempDisp->Release();

// Set the coordinate systems onto the layer
pLayer.SetCoordinateSystem(vaGCS);

// Now we have to define our Projected Coordinate System for our map.
// This is our target coordinate system define a Projected Coordinate
// System. Here, the code uses UTM grid zone 33N. Your desired
// TARGET projection might be different.
CMoProjCoordSys utmZone33N;

// Create a dispatch pointer for it
utmZone33N.CreateDispatch(TEXT("MapObjects2.ProjCoordSys"));

// Check if the previous step was successful
if (!LPDISPATCH(utmZone33N)) AfxMessageBox("Dispatch Pointer NOT created");

// Assume all is OK and set the projection type
utmZone33N.SetType(moProjCS_WGS1984UTM_33N);
VARIANT vaUTM;
VariantInit(&vaUTM);
vaWest.vt = VT_DISPATCH;

// Set the VARIANTs to the dispatch pointer for the
// projected coordinate ystems
vaUTM.pdispVal = utmZone33N.m_lpDispatch;

// Set the map to use the projected coordinate system
m_map.SetCoordinateSystem(vaUTM);

// Recover memory
pGCS.ReleaseDispatch();
utmZone33N.ReleaseDispatch();