Coordinate array conversion and forwarding
Arrays.cpp
// Copyright 2010 ESRI
// 
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
// 
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
// 
// See the use restrictions.
// 


#include <stdio.h>
#include <ArcSDK.h>
#include <olb/esridefensesolutions.h>

#if defined(ESRI_UNIX)
    // implemented in libDefenseSolutionsSDK.so
    void DsInitialize();
#endif

#define ABORT {                                              \
    printf ("abort on line %d of %s\n", __LINE__, __FILE__); \
    shutdown();                                              \
}


// the first macro expands the symbol defined on the command line; the second puts quotes around it
#define EXPANDSTRING(x) STRINGIFY(x)
#define STRINGIFY(x) #x


// shut down arc objects and terminate the application
void shutdown()
{
    IAoInitializePtr ipInit (CLSID_AoInitialize);
    ipInit->Shutdown();
    ::AoUninitialize();
    AoExit (0);
}


int main (int argc, char **argv)
{
    USES_CONVERSION;

    ::AoInitialize (NULL);
#ifdef ESRI_UNIX
    ::DsInitialize();
#endif
    {
        IAoInitializePtr ipInit (CLSID_AoInitialize);
        esriLicenseStatus status;
        ipInit->Initialize (esriLicenseProductCodeEngine, &status);
        if ( status != esriLicenseCheckedOut )
        {
            printf ("Invalid Licensing.\n");
            ::AoUninitialize();
            AoExit (0);
        }
    }
    // use compound statements to ensure destructors are called before AoExit
    {
        // fetch an array of points from a shapefile and convert it to arrays of strings in various formats
        IWorkspaceFactoryPtr           ipWSF            (CLSID_ShapefileWorkspaceFactory);
        IWorkspacePtr                  ipWS;
        IFeatureWorkspacePtr           ipFWS;
        IFeatureClassPtr               ipFC;
        IArrayPtr                      ipPointArray     (CLSID_Array);
        IFeatureCursorPtr              ipFeatureCursor;
        IFeaturePtr                    ipFeature;
        IGeometryPtr                   ipGeometry;
        IPointPtr                      ipPoint;
        IUnknownPtr                    ipUnknown;
        ISpatialReferenceFactoryPtr    ipSRF            (CLSID_SpatialReferenceEnvironment);
        IGeographicCoordinateSystemPtr ipWGS72;
        ICoordinatePtr                 ipCoordMGRS      (CLSID_MGRSCoordinate);
        ICoordinatePtr                 ipCoordDMS       (CLSID_DMSCoordinate);
        ICoordinatePtr                 ipCoordDD        (CLSID_DDCoordinate);
        IStringArrayPtr                ipNormalizedMGRS;
        IStringArrayPtr                ipNormalizedDMS;
        IStringArrayPtr                ipNormalizedDD;
        CComBSTR                       normalizedMGRS;
        CComBSTR                       normalizedDMS;
        CComBSTR                       normalizedDD;
        double                         x, y;
        long                           count            (0);

        // open a point shapefile to get some input data

#if defined(ESRI_UNIX)
        ipWSF->OpenFromFile (CComBSTR(EXPANDSTRING(DATADIRECTORY) "/Samples/data/defensesolutions"), 0, &ipWS);
#elif defined(ESRI_WINDOWS)
        ipWSF->OpenFromFile (L"C:\\Program Files\\ArcGIS\\DeveloperKit10.0\\Samples\\data\\defensesolutions\\", 0, &ipWS);
#endif

        ipFWS = ipWS;
        if ( ! ipFWS ) ABORT;
        ipFWS->OpenFeatureClass (CComBSTR("Cities"), &ipFC);
        if ( ! ipFC ) ABORT;
        ipFC->Search (NULL, VARIANT_FALSE, &ipFeatureCursor);
        if ( ! ipFeatureCursor ) ABORT;
        ipFeatureCursor->NextFeature (&ipFeature);
        while ( ipFeature )
        {
            // load the input data into the array
            ipFeature->get_ShapeCopy (&ipGeometry);
            ipPoint = ipGeometry;
            if ( ipPoint )
            {
                // don't load more than 20 points
                ipPointArray->Add (IUnknownPtr(ipPoint));
                if ( ++count == 20 ) break;
            }
            ipFeatureCursor->NextFeature (&ipFeature);
        }
        if ( count < 1 ) ABORT;

        // set up the output spatial references
        // forwarded coordinates get their input SR from the calling coordinate
        // but we need to have their output SR specified, or else it defaults to WGS 1984
        ipSRF->CreateGeographicCoordinateSystem (esriSRGeoCS_WGS1972, &ipWGS72);
        ipCoordDMS->put_OutputSpatialReference (ipWGS72);
        ipCoordDD->put_OutputSpatialReference (ipWGS72);

        // set MGRS precision to 7 coordinate digits per axis
        ipCoordMGRS->put_Precision (esriCPOneCentimeter);
        ipCoordDMS ->put_Precision (esriCPOneTenThousandthSecond);
        ipCoordDD  ->put_Precision (esriCPOneTenthThousandthDegree);

        // MGRS will be our input device - forward its output to the DMS and DD coverters
        ipCoordMGRS->AddOutputCoordinate (ipCoordDMS);
        ipCoordMGRS->AddOutputCoordinate (ipCoordDD);

        // the following put_PointArray call performs all of the conversion
        ipCoordMGRS->put_PointArray (ipPointArray);
        ipCoordMGRS->get_StringArray (&ipNormalizedMGRS);
        ipCoordDMS ->get_StringArray (&ipNormalizedDMS);
        ipCoordDD  ->get_StringArray (&ipNormalizedDD);
        printf ("(  Longitude,   Latitude)  MGRS                 DMS                             DD\n");
        printf ("--------------------------------------------------------------------------------------------------\n");
        for ( long i = 0; i < count; ++i )
        {
            // display the results
            normalizedMGRS.Empty();
            normalizedDMS .Empty();
            normalizedDD  .Empty();
            ipNormalizedMGRS->get_Element (i, &normalizedMGRS);
            ipNormalizedDMS ->get_Element (i, &normalizedDMS);
            ipNormalizedDD  ->get_Element (i, &normalizedDD);
            ipPointArray    ->get_Element (i, &ipUnknown);
            ipPoint = ipUnknown;
            ipPoint->QueryCoords (&x, &y);
            printf (
                "(%11.6f, %10.6f)  %s  %s  %s\n",
                x, y, OLE2A(normalizedMGRS), OLE2A(normalizedDMS), OLE2A(normalizedDD)
            );
        }
    }
    shutdown();
    return 0;

    // results:
    // (  Longitude,   Latitude)  MGRS                 DMS                             DD
    // --------------------------------------------------------------------------------------------------
    // (-122.316995,  47.588598)  10TET51352747080224  47 35 18.8480N 122 19 01.7360W  47.5886N 122.3171W
    // (-122.309003,  37.727499)  10SEG60891877580586  37 43 38.8746N 122 18 32.9648W  37.7275N 122.3092W
    // (-118.249999,  33.999999)  11SLT84561846286009  33 59 59.8693N 118 15 00.5504W  34.0000N 118.2502W
    // (-117.124999,  32.761501)  11SMS88291802485434  32 45 41.2748N 117 07 30.5504W  32.7615N 117.1252W
    // ( -93.307808,  44.924200)  15TVK75708057457612  44 55 27.0103N 093 18 28.6628W  44.9242N 093.3080W
    // ( -87.641299,  41.826501)  16TDM46744993071188  41 49 35.2884N 087 38 29.2304W  41.8265N 087.6415W
    // ( -83.078897,  42.394301)  17TLG28894199564993  42 23 39.3694N 083 04 44.5832W  42.3943N 083.0791W
    // ( -79.412601,  43.720802)  17TPJ27864354208805  43 43 14.7753N 079 24 45.9176W  43.7208N 079.4128W
    // ( -73.653502,  45.541000)  18TXR05121044393322  45 32 27.4914N 073 39 13.1612W  45.5410N 073.6537W
    // ( -81.727503,  41.390700)  17TMF39178398238526  41 23 26.4041N 081 43 39.5648W  41.3907N 081.7277W
    // ( -79.997102,  40.497199)  17TNE84983648342686  40 29 49.7990N 079 59 50.1212W  40.4972N 079.9973W
    // ( -71.102597,  42.375303)  19TCG26891249358834  42 22 30.9766N 071 06 09.9032W  42.3753N 071.1028W
    // ( -75.218203,  39.927599)  18SVK81354591974425  39 55 39.2381N 075 13 06.0848W  39.9276N 075.2184W
    // ( -76.953802,  38.890902)  18SUJ30550330648428  38 53 27.1272N 076 57 14.2412W  38.8909N 076.9540W
    // ( -90.341997,  38.638899)  15SYC31344898005808  38 38 19.9161N 090 20 31.7432W  38.6389N 090.3422W
    // ( -95.407101,  29.771801)  15RTN67276419592780  29 46 18.3511N 095 24 26.1176W  29.7718N 095.4073W
    // (-100.317003,  25.677399)  14RLP67832194061688  25 40 38.4995N 100 19 01.7648W  25.6774N 100.3172W
    // ( -99.127601,  19.427001)  14QMG86604634808023  19 25 37.0615N 099 07 39.9176W  19.4270N 099.1278W
    // ( -75.591998,   6.241150)  18NVM34512148989871  06 14 27.9930N 075 35 31.7468W  06.2411N 075.5922W
    // ( -66.898301,  10.495999)  19PGM30027386102151  10 29 45.4501N 066 53 54.4376W  10.4960N 066.8985W
}