MapObjects Connection

 

How to do simple projections using C++

So you want to go FROM geographic TO projected?  You still need to define what coordinate system (CS) you are going FROM and where you are going TO. If your data has associated projection information (i.e. a PRJ file for Shape files or projection information if using SDE) then you don't need to define a CS for your layer. If you do need to define a CS then this is how you can do it in C++. These following lines of code are taken and amended from the projection sample. NB. You may also need to apply a geotransformation if the geographic coordinate system for your TARGET projection is different to your geographic coordinate system of your SOURCE.

// The source layer is in geographics therefore define a Geographic Coordinate System,
// here, I'm going to use WGS1984 - your data may be based on a different GCS
CMoGeoCoordSys pGCS;
 
// create a dispatch pointer for it
pGCS.CreateDispatch(TEXT("MapObjects2.GeoCoordSys"));
 
// check to see it 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 - here I'm assuming I have only one layer
CMoLayers m_layers(m_map.GetLayers());
 
// create a VARIANT structure to be hold the integer index for map layers
VARIANT va_index;
VariantInit(&va_index);
va_index.vt = VT_I4; // this is the TYPE (integer) that the VARIANT will hold
va_index.lVal = 0; // this is the integer value
 
// from the maplayers, get the nth layer (0)
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 MO 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 to see 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();
 
// And now set the coordinate systems onto the layer
pLayer.SetCoordinateSystem(vaGCS);
 
// so now we have to define our Projected Coordinate System for our map. This is our target coordinate system
// define a Projected Coordinate System. Here, I'm using 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 to see it 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 systems
vaUTM.pdispVal = utmZone33N.m_lpDispatch;
 
// set the map to use the projected coordinate system
m_map.SetCoordinateSystem(vaUTM);
 
// and recover memory
pGCS.ReleaseDispatch();
utmZone33N.ReleaseDispatch();
 

Back to MapObjects Connection