Geodesy MapControl
Geodesy.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 "Geodesy.h"

void Geodesy::setupUi(QDialog *Dialog)
{
    mainDlg = Dialog;
    Dialog->setObjectName(QString::fromUtf8("Dialog"));

    Dialog->resize(QSize(778, 640).expandedTo(Dialog->minimumSizeHint()));
    GeoPolyline = new QGroupBox(Dialog);
    GeoPolyline->setObjectName(QString::fromUtf8("GeoPolyline"));
    GeoPolyline->setGeometry(QRect(10, 400, 381, 231));
    comboBox = new QComboBox(GeoPolyline);
    comboBox->setObjectName(QString::fromUtf8("comboBox"));
    comboBox->setGeometry(QRect(90, 20, 151, 29));
    comboBox->addItem("Geodesic");
    comboBox->addItem("Great Circle");
    comboBox->addItem("Rhumb Line");

    label = new QLabel(GeoPolyline);
    label->setObjectName(QString::fromUtf8("label"));
    label->setGeometry(QRect(10, 20, 37, 30));
    label_6 = new QLabel(GeoPolyline);
    label_6->setObjectName(QString::fromUtf8("label_6"));
    label_6->setGeometry(QRect(120, 50, 21, 21));
    label_7 = new QLabel(GeoPolyline);
    label_7->setObjectName(QString::fromUtf8("label_7"));
    label_7->setGeometry(QRect(180, 50, 31, 21));
    lineEdit_5 = new QLineEdit(GeoPolyline);
    lineEdit_5->setObjectName(QString::fromUtf8("lineEdit_5"));
    lineEdit_5->setGeometry(QRect(170, 70, 71, 29));
    lineEdit_6 = new QLineEdit(GeoPolyline);
    lineEdit_6->setObjectName(QString::fromUtf8("lineEdit_6"));
    lineEdit_6->setGeometry(QRect(170, 110, 71, 29));
    label_2 = new QLabel(GeoPolyline);
    label_2->setObjectName(QString::fromUtf8("label_2"));
    label_2->setGeometry(QRect(10, 70, 61, 21));
    label_3 = new QLabel(GeoPolyline);
    label_3->setObjectName(QString::fromUtf8("label_3"));
    label_3->setGeometry(QRect(10, 110, 54, 21));
    label_4 = new QLabel(GeoPolyline);
    label_4->setObjectName(QString::fromUtf8("label_4"));
    label_4->setGeometry(QRect(10, 150, 54, 21));
    label_5 = new QLabel(GeoPolyline);
    label_5->setObjectName(QString::fromUtf8("label_5"));
    label_5->setGeometry(QRect(10, 190, 54, 21));
    lineEdit = new QLineEdit(GeoPolyline);
    lineEdit->setObjectName(QString::fromUtf8("lineEdit"));
    lineEdit->setGeometry(QRect(80, 70, 71, 29));
    lineEdit_2 = new QLineEdit(GeoPolyline);
    lineEdit_2->setObjectName(QString::fromUtf8("lineEdit_2"));
    lineEdit_2->setGeometry(QRect(80, 110, 71, 29));
    pushButton = new QPushButton(GeoPolyline);
    pushButton->setObjectName(QString::fromUtf8("pushButton"));
    pushButton->setGeometry(QRect(260, 70, 111, 41));
    pushButton_2 = new QPushButton(GeoPolyline);
    pushButton_2->setObjectName(QString::fromUtf8("pushButton_2"));
    pushButton_2->setGeometry(QRect(260, 110, 111, 41));
    label_8 = new QLabel(GeoPolyline);
    label_8->setObjectName(QString::fromUtf8("label_8"));
    label_8->setGeometry(QRect(250, 150, 54, 21));
    lineEdit_3 = new QLineEdit(GeoPolyline);
    lineEdit_3->setObjectName(QString::fromUtf8("lineEdit_3"));
    lineEdit_3->setGeometry(QRect(80, 150, 161, 29));
    lineEdit_3->setReadOnly(true);

    label_9 = new QLabel(GeoPolyline);
    label_9->setObjectName(QString::fromUtf8("label_9"));
    label_9->setGeometry(QRect(250, 190, 54, 21));
    lineEdit_4 = new QLineEdit(GeoPolyline);
    lineEdit_4->setObjectName(QString::fromUtf8("lineEdit_4"));
    lineEdit_4->setGeometry(QRect(80, 190, 161, 29));
    lineEdit_4->setReadOnly(true);

    GeoEllipse = new QGroupBox(Dialog);
    GeoEllipse->setObjectName(QString::fromUtf8("GeoEllipse"));
    GeoEllipse->setGeometry(QRect(400, 400, 361, 231));
    label_12 = new QLabel(GeoEllipse);
    label_12->setObjectName(QString::fromUtf8("label_12"));
    label_12->setGeometry(QRect(20, 110, 54, 21));
    label_13 = new QLabel(GeoEllipse);
    label_13->setObjectName(QString::fromUtf8("label_13"));
    label_13->setGeometry(QRect(20, 150, 54, 21));
    label_14 = new QLabel(GeoEllipse);
    label_14->setObjectName(QString::fromUtf8("label_14"));
    label_14->setGeometry(QRect(20, 190, 54, 21));
    label_10 = new QLabel(GeoEllipse);
    label_10->setObjectName(QString::fromUtf8("label_10"));
    label_10->setGeometry(QRect(10, 30, 81, 21));
    label_11 = new QLabel(GeoEllipse);
    label_11->setObjectName(QString::fromUtf8("label_11"));
    label_11->setGeometry(QRect(80, 70, 16, 21));
    lineEdit_7 = new QLineEdit(GeoEllipse);
    lineEdit_7->setObjectName(QString::fromUtf8("lineEdit_7"));
    lineEdit_7->setGeometry(QRect(100, 30, 91, 29));
    lineEdit_8 = new QLineEdit(GeoEllipse);
    lineEdit_8->setObjectName(QString::fromUtf8("lineEdit_8"));
    lineEdit_8->setGeometry(QRect(100, 70, 91, 29));
    lineEdit_9 = new QLineEdit(GeoEllipse);
    lineEdit_9->setObjectName(QString::fromUtf8("lineEdit_9"));
    lineEdit_9->setGeometry(QRect(100, 110, 91, 29));
    lineEdit_10 = new QLineEdit(GeoEllipse);
    lineEdit_10->setObjectName(QString::fromUtf8("lineEdit_10"));
    lineEdit_10->setGeometry(QRect(100, 150, 91, 29));
    lineEdit_11 = new QLineEdit(GeoEllipse);
    lineEdit_11->setObjectName(QString::fromUtf8("lineEdit_11"));
    lineEdit_11->setGeometry(QRect(100, 190, 91, 29));
    pushButton_3 = new QPushButton(GeoEllipse);
    pushButton_3->setObjectName(QString::fromUtf8("pushButton_3"));
    pushButton_3->setGeometry(QRect(230, 20, 121, 41));
    pushButton_4 = new QPushButton(GeoEllipse);
    pushButton_4->setObjectName(QString::fromUtf8("pushButton_4"));
    pushButton_4->setGeometry(QRect(230, 60, 121, 41));
    pushButton_5 = new QPushButton(GeoEllipse);
    pushButton_5->setObjectName(QString::fromUtf8("pushButton_5"));
    pushButton_5->setGeometry(QRect(230, 100, 121, 41));
    label_18 = new QLabel(GeoEllipse);
    label_18->setObjectName(QString::fromUtf8("label_18"));
    label_18->setGeometry(QRect(200, 30, 21, 21));
    label_19 = new QLabel(GeoEllipse);
    label_19->setObjectName(QString::fromUtf8("label_19"));
    label_19->setGeometry(QRect(200, 70, 21, 21));
    label_15 = new QLabel(GeoEllipse);
    label_15->setObjectName(QString::fromUtf8("label_15"));
    label_15->setGeometry(QRect(200, 110, 21, 21));
    label_16 = new QLabel(GeoEllipse);
    label_16->setObjectName(QString::fromUtf8("label_16"));
    label_16->setGeometry(QRect(200, 150, 21, 21));
    label_17 = new QLabel(GeoEllipse);
    label_17->setObjectName(QString::fromUtf8("label_17"));
    label_17->setGeometry(QRect(200, 190, 54, 21));
    retranslateUi(Dialog);

    addGISControls(Dialog);

    connect(pushButton, SIGNAL( clicked() ), this, SLOT ( drawGeoline() ) );
    connect(pushButton_2, SIGNAL( clicked() ), this, SLOT ( clearLineFields() ) );
    connect(pushButton_3, SIGNAL( clicked() ), this, SLOT ( drawGeoEllipse() ) );
    connect(pushButton_4, SIGNAL( clicked() ), this, SLOT ( drawKeyPoints() ) );
    connect(pushButton_5, SIGNAL( clicked() ), this, SLOT ( clearEllipseFields() ) );

    QMetaObject::connectSlotsByName(Dialog);
    } // setupUi

    void Geodesy::retranslateUi(QDialog *Dialog)
    {
    Dialog->setWindowTitle(QApplication::translate("Dialog", "Geodesy Sample", 0, QApplication::UnicodeUTF8));
    GeoPolyline->setTitle(QApplication::translate("Dialog", "Geo Polyline", 0, QApplication::UnicodeUTF8));
    label->setText(QApplication::translate("Dialog", "Type", 0, QApplication::UnicodeUTF8));
    label_6->setText(QApplication::translate("Dialog", "X", 0, QApplication::UnicodeUTF8));
    label_7->setText(QApplication::translate("Dialog", "Y", 0, QApplication::UnicodeUTF8));
    label_2->setText(QApplication::translate("Dialog", "Start Point", 0, QApplication::UnicodeUTF8));
    label_3->setText(QApplication::translate("Dialog", "End Point", 0, QApplication::UnicodeUTF8));
    label_4->setText(QApplication::translate("Dialog", "Distance", 0, QApplication::UnicodeUTF8));
    label_5->setText(QApplication::translate("Dialog", "Azimuth", 0, QApplication::UnicodeUTF8));
    pushButton->setText(QApplication::translate("Dialog", "Draw GeoLine", 0, QApplication::UnicodeUTF8));
    pushButton_2->setText(QApplication::translate("Dialog", "Clear Fields", 0, QApplication::UnicodeUTF8));
    label_8->setText(QApplication::translate("Dialog", "km", 0, QApplication::UnicodeUTF8));
    label_9->setText(QApplication::translate("Dialog", "deg", 0, QApplication::UnicodeUTF8));
    GeoEllipse->setTitle(QApplication::translate("Dialog", "Geo Ellipse", 0, QApplication::UnicodeUTF8));
    label_12->setText(QApplication::translate("Dialog", "X Axis", 0, QApplication::UnicodeUTF8));
    label_13->setText(QApplication::translate("Dialog", "Y Axis", 0, QApplication::UnicodeUTF8));
    label_14->setText(QApplication::translate("Dialog", "Rotation", 0, QApplication::UnicodeUTF8));
    label_10->setText(QApplication::translate("Dialog", "Center Point X", 0, QApplication::UnicodeUTF8));
    label_11->setText(QApplication::translate("Dialog", "Y", 0, QApplication::UnicodeUTF8));
    pushButton_3->setText(QApplication::translate("Dialog", "Draw GeoEllipse", 0, QApplication::UnicodeUTF8));
    pushButton_4->setText(QApplication::translate("Dialog", "Draw Key Points", 0, QApplication::UnicodeUTF8));
    pushButton_5->setText(QApplication::translate("Dialog", "Clear Fields", 0, QApplication::UnicodeUTF8));
    label_18->setText(QApplication::translate("Dialog", "deg", 0, QApplication::UnicodeUTF8));
    label_19->setText(QApplication::translate("Dialog", "deg", 0, QApplication::UnicodeUTF8));
    label_15->setText(QApplication::translate("Dialog", "km", 0, QApplication::UnicodeUTF8));
    label_16->setText(QApplication::translate("Dialog", "km"
"", 0, QApplication::UnicodeUTF8));
    label_17->setText(QApplication::translate("Dialog", "deg", 0, QApplication::UnicodeUTF8));
    Q_UNUSED(Dialog);
    } // retranslateUi

    void Geodesy::addGISControls(QDialog* Dialog)
    {
    vbox = new QWidget(Dialog);
    vbox->setObjectName(QString::fromUtf8("main_vbox"));
    vbox->setGeometry(QRect(1, 1, 770, 400));

    layout = new QVBoxLayout;

    tlb = new QAxCtl(AoPROGID_ToolbarControl, NULL, "Toolbar Control");
    split = new QSplitter(NULL);


    layout->addWidget(tlb);
    layout->addWidget(split);

    vbox->setLayout(layout);

    tlb->setMinimumHeight(30);
    tlb->setMaximumHeight(30);

    toc = new QAxCtl(AoPROGID_TOCControl, split, "TOC Control");
    toc->setMaximumWidth(150);
    map = new QAxCtl(AoPROGID_MapControl, split, "Map Control");

    HRESULT hr = tlb->getInterface((IUnknown **)&m_ipToolbarControl);
    hr = toc->getInterface((IUnknown **)&m_ipTOCControl);
    hr = map->getInterface((IUnknown **)&m_ipMapControl);

    if (m_ipToolbarControl != 0)
            m_ipToolbarControl->SetBuddyControl(m_ipMapControl);
    if (m_ipTOCControl != 0)
            m_ipTOCControl->SetBuddyControl(m_ipMapControl);

   addToolbarItems(m_ipToolbarControl);

    IEventListenerHelperPtr ipMapControlEvent2Helper;
    MapControlEvents* mapEvents = new MapControlEvents();
    ipMapControlEvent2Helper.CreateInstance(CLSID_MapControlEvents2Listener);
    ipMapControlEvent2Helper->Startup(static_cast<IMapControlEvents2Helper*> (mapEvents));
    ipMapControlEvent2Helper->AdviseEvents(m_ipMapControl, NULL);

    }

 void Geodesy::addToolbarItems(IToolbarControl* pToolbar)
  {
    CComVariant varTool;
    long itemindex;

    if (!pToolbar)
      return;

   varTool = L"esriControlCommands.ControlsOpenDocCommand";
    pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
        esriCommandStyleIconOnly, &itemindex);

    varTool = L"esriControlCommands.ControlsMapZoomInTool";
    pToolbar->AddItem(varTool, 0, -1, VARIANT_TRUE, 0,
        esriCommandStyleIconOnly, &itemindex);
    varTool = L"esriControlCommands.ControlsMapZoomOutTool";
    pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
        esriCommandStyleIconOnly, &itemindex);
    varTool = L"esriControlCommands.ControlsMapZoomInFixedCommand";
    pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
        esriCommandStyleIconOnly, &itemindex);
    varTool = L"esriControlCommands.ControlsMapZoomOutFixedCommand";
    pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
        esriCommandStyleIconOnly, &itemindex);
    varTool = L"esriControlCommands.ControlsMapPanTool";
    pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
        esriCommandStyleIconOnly, &itemindex);
    varTool = L"esriControlCommands.ControlsMapFullExtentCommand";
    pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
        esriCommandStyleIconOnly, &itemindex);
    varTool = L"esriControlCommands.ControlsMapZoomToLastExtentBackCommand";
    pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
        esriCommandStyleIconOnly, &itemindex);
    varTool = L"esriControlCommands.ControlsMapZoomToLastExtentForwardCommand";
    pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
        esriCommandStyleIconOnly, &itemindex);
    varTool = L"esriControlCommands.ControlsSelectFeaturesTool";
    pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
        esriCommandStyleIconOnly, &itemindex);
    varTool = L"esriControlCommands.ControlsSelectTool";
    pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
        esriCommandStyleIconOnly, &itemindex);
  }

  void Geodesy::drawGeoline()
  {
    //define variables to store polyline input values
    double xx1, yy1, xx2, yy2;
    bool inputOk = validatePolylineInputs(&xx1, &yy1, &xx2, &yy2);
    if(!inputOk)
    {
        return;
    }

    /*
     Create GeoPolyline and MeasurementTool
     The measurement tool will be used to calculate the distance
     and azimuth of the GeoPolyline based on the start and end point
     coordinates defined in the X and Y fields.
    */
    IGeoPolylinePtr ipPolyline(CLSID_GeoPolyline);
    IMeasurementToolPtr ipMeasurement(CLSID_MeasurementTool);

    //set the measurement tool's spatial reference
    ISpatialReferencePtr ipSpatialRef;
    ISpatialReferenceFactory2Ptr ipSpatialFactory(CLSID_SpatialReferenceEnvironment);
    ipSpatialFactory->CreateSpatialReference(esriSRGeoCS_WGS1984, &ipSpatialRef);
    ipMeasurement->putref_SpecialSpatialReference(ipSpatialRef);

    /*
    Set start and end points for the measurement tool calculation
    and the polyline from which the GeoPolyline is derived. The points
    are created based on the decimal degree coordinates input into
    the Start Point and End Point edit boxes
    */
    IPointPtr ipStartPoint(CLSID_Point);
    IPointPtr ipEndPoint(CLSID_Point);
    ipStartPoint->PutCoords(xx1, yy1);
    ipEndPoint->PutCoords(xx2, yy2);

    /*
    Calculate the distance and azimuth of the GeoPolyline using the
    ConstructByPoints method on the measurement tool. These values
    will be displayed in the Distance and Azimuth text boxes
    */
    ipMeasurement->ConstructByPoints(ipStartPoint, ipEndPoint);

    /*
     Get the GeoPolyline type from the ComboBox and set it as
     the type for both the measurement tool and the GeoPolyline.
     The options are Geodesic, Great Circle, and Rhumb Line.
    */

    cjmtkSGType eSGType = cjmtkSGTUnknown;
    int lineType = comboBox->currentIndex();
    if(lineType == 1)
    {
        eSGType = cjmtkSGTGreatCircle;
    }
    else if(lineType == 2)
    {
        eSGType = cjmtkSGTRhumbLine;
    }
    else
    {
        eSGType = cjmtkSGTGeodesic;
    }
    ipPolyline->put_SpecialGeolineType(eSGType);
    ipMeasurement->put_SpecialGeolineType(eSGType);

    //Create the simple polyline which is the basis for the
    //geometry of the GeoPolyline
    IPolylinePtr ipLine(CLSID_Polyline);
    ipLine->put_FromPoint(ipStartPoint);
    ipLine->put_ToPoint(ipEndPoint);
    ipLine->Project(ipSpatialRef);

    /*
    Set the base geometry of the geopolyline to the polyline created
    from the start and end point coordinates defined in the X and Y fields.
    Specify the number of vertices by which to densify the GeoPolyline as
    a percentage of the total distance of the line. In this case a vertex
    will be placed at every 1% of the line's total distance.
    */
    ipPolyline->put_Polyline(ipLine);
    ipPolyline->put_MaxPercent(0.01);
    ipPolyline->put_UsePercent(VARIANT_TRUE);

    //create the IElement to be rendered as a GeoPolylineElement and
    //set its geometry to the GeoPolyline geometry
    IElementPtr ipGeoLineElement(CLSID_GeoPolylineElement);
    IGeometryPtr ipGeom = ipPolyline;
    ipGeoLineElement->put_Geometry(ipGeom);

    //QI to ILineElement to set the symbology of the GeoPolylineElement graphic
    ILineElementPtr ipLineElement = ipGeoLineElement;

    //define the color for the line symbol
    IRgbColorPtr ipRgb(CLSID_RgbColor);
    ipRgb->put_Red(255);
    ipRgb->put_Green(0);
    ipRgb->put_Blue(0);

        IArrowMarkerSymbolPtr ipMarker(CLSID_ArrowMarkerSymbol);
    ipMarker->put_Size(14);
    ipMarker->put_Color(ipRgb);
    ipMarker->put_XOffset(1);

    //define the simple line decoration element and add the marker symbol to it
    ISimpleLineDecorationElementPtr ipSimpleLineDecoElement(CLSID_SimpleLineDecorationElement);
    ipSimpleLineDecoElement->put_MarkerSymbol(IMarkerSymbolPtr(ipMarker));
    ipSimpleLineDecoElement->AddPosition(1.0);

    //set the simple line decoration element to the line decoration element
    ILineDecorationElementPtr ipLineDecoElement = ipSimpleLineDecoElement;

    //add the line decoration element to the line decoration
    ILineDecorationPtr ipLineDeco(CLSID_LineDecoration);
    ipLineDeco->AddElement(ipLineDecoElement);

    //define the cartographic line symbol properties
    ICartographicLineSymbolPtr ipCartoLineSymbol(CLSID_CartographicLineSymbol);
    ipCartoLineSymbol->put_Color(ipRgb);
    ipCartoLineSymbol->put_Width(1.5);

    //set the cartographic line symbol and the line decoration to the line properties
    ILinePropertiesPtr ipLineProps = ipCartoLineSymbol;
    ipLineProps->putref_LineDecoration(ipLineDeco);

    ISymbolPtr ipSym = ipLineProps;

    ILineSymbolPtr ipLineSym = ipSym;
    ipLineElement->put_Symbol(ipLineSym);

    //draw the GeoPolyline graphic.
    drawElement(ipGeoLineElement);

    //get distance and round off to 6 decimal places
    double dist;
    ipMeasurement->get_Distance(&dist);
    dist = dist/1000.0;

    char st[36];
    sprintf(st, "%12.6f", dist);
    lineEdit_3->setText(st);

    //get angle and round off to 6 decimal places
    double azm;
    ipMeasurement->get_Angle(&azm);
    char st1[36];
    sprintf(st1, "%12.6f", azm);
    lineEdit_4->setText(st1);
    return;
  }
  void Geodesy::clearLineFields()
  {
    lineEdit->setText("");
    lineEdit_2->setText("");
    lineEdit_3->setText("");
    lineEdit_4->setText("");
    lineEdit_5->setText("");
    lineEdit_6->setText("");
    clearGraphics();
  }
  void Geodesy::drawGeoEllipse()
  {
    //Create GeoEllipse
    bool ellipseOk = createGeoEllipse();
    if(!ellipseOk)
    {
        return;
    }

    //make green color
    IRgbColorPtr ipRgb(CLSID_RgbColor);
    ipRgb->put_Red(0);
    ipRgb->put_Green(255);
    ipRgb->put_Blue(0);

    //make fill color null
    IColorPtr ipNullColor(CLSID_RgbColor);
    ipNullColor->put_NullColor(VARIANT_TRUE);

    //create the line symbol for the polygon outline
    ILineSymbolPtr ipLineSym(CLSID_SimpleLineSymbol);
    ipLineSym->put_Color(ipRgb);
    ipLineSym->put_Width(2);

    //create the fill symbol
    IFillSymbolPtr ipFillSym(CLSID_SimpleFillSymbol);
    ipFillSym->put_Outline(ipLineSym);
    ipFillSym->put_Color(ipNullColor);

    //create the IElement to be rendered as a GeoEllipseElement and
    //set its geometry to the GeoEllipse geometry
    IElementPtr ipGeoEllipseElement(CLSID_GeoEllipseElement);

    IGeometryPtr ipGeoEllipse = m_ipGeoEllipse;
    ipGeoEllipseElement->put_Geometry(ipGeoEllipse);

    //QI to IFillShapeElement to set the symbology of the GeoEllipse graphic
    IFillShapeElementPtr ipFillShape = ipGeoEllipseElement;
    ipFillShape->put_Symbol(ipFillSym);

    //draw the GeoEllipse graphic
    drawElement(ipGeoEllipseElement);

  }
  void Geodesy::drawKeyPoints()
  {
    bool ellipseOk = createGeoEllipse();

    if(!ellipseOk)
    {
        return;
    }

    //make green color
    IRgbColorPtr ipRgb(CLSID_RgbColor);
    ipRgb->put_Red(0);
        ipRgb->put_Green(255);
    ipRgb->put_Blue(0);

    //make fill color null
    IColorPtr ipNullColor(CLSID_RgbColor);
    ipNullColor->put_NullColor(VARIANT_TRUE);

    //create the line symbol for the polygon outline
    ILineSymbolPtr ipLineSym(CLSID_SimpleLineSymbol);
    ipLineSym->put_Color(ipRgb);
    ipLineSym->put_Width(1.5);

    IHashLineSymbolPtr ipHashLineSym(CLSID_HashLineSymbol);
    ipHashLineSym->putref_HashSymbol(ipLineSym);

    //create the fill symbol
    IFillSymbolPtr ipFillSym(CLSID_SimpleFillSymbol);
    ipFillSym->put_Outline(ipHashLineSym);
    ipFillSym->put_Color(ipNullColor);

    IElementPtr ipKeyPointElement(CLSID_PolygonElement);
    ipKeyPointElement->put_Geometry(m_ipKeyPointPoly);

    //QI to IFillShapeElement to set the symbology of the key points polygon graphic
    IFillShapeElementPtr ipFillShapeElement = ipKeyPointElement;
    ipFillShapeElement->put_Symbol(ipFillSym);

    //draw the key points polygon graphic
    drawElement(ipKeyPointElement);

  }
  void Geodesy::clearEllipseFields()
  {
    lineEdit_7->setText("");
    lineEdit_8->setText("");
    lineEdit_9->setText("");
    lineEdit_10->setText("");
    lineEdit_11->setText("");
    clearGraphics();
  }

  void Geodesy::clearGraphics()
  {
    //Clear all graphic elements from the map control
    IActiveViewPtr ipActiveView;
    m_ipMapControl->get_ActiveView(&ipActiveView);
    IGraphicsContainerPtr ipContainer;
    ipActiveView->get_GraphicsContainer(&ipContainer);
    ipContainer->DeleteAllElements();
    ipActiveView->Refresh();
  }

 bool Geodesy::createGeoEllipse()
  {
    //these variables store ellipse properties
    double xx1, yy1, xAxis, yAxis, rot;
    //make sure the input values are valid
    bool isOK = validateEllipseInputs(&xx1, &yy1, &xAxis, &yAxis, &rot);
    if(!isOK){
        return false;
    }

    //create a point object for geoellipse center point
    IPointPtr ipPoint(CLSID_Point);
    ipPoint->PutCoords(xx1,yy1);

    //create GeoEllipse object
    IGeoEllipsePtr ipGeoEllipse(CLSID_GeoEllipse);

    //set its spatial reference as WGS84
    ISpatialReferencePtr ipSpatialRef;
    ISpatialReferenceFactory2Ptr ipSpatialFactory(CLSID_SpatialReferenceEnvironment);
    ipSpatialFactory->CreateSpatialReference(esriSRGeoCS_WGS1984, &ipSpatialRef);
    ipGeoEllipse->putref_BaseSpatialReference(ipSpatialRef);

    //set the lengths in meters
    ipGeoEllipse->put_AxisX(xAxis*1000);
    ipGeoEllipse->put_AxisY(yAxis*1000);

    //set the origin of the geoellipse
    ipGeoEllipse->put_Origin(ipPoint);

    //define the amount of rotation, in degrees from
    //zero (north), of the geoellipse Y axis
    ipGeoEllipse->put_Rotation(rot);

    //set the number of vertices to be used in the creation
    //of the polygon representation of the geoellipse
    ipGeoEllipse->put_GeoEllipsePointCount(100);

    //define the key points polygon, which is a polygon connecting the end
    //points of the geoellipse X and Y axes
    ipGeoEllipse->get_KeyPoints(&m_ipKeyPointPoly);
    m_ipGeoEllipse = ipGeoEllipse;
    return true;
  }
  bool Geodesy::validateEllipseInputs(double* centerX, double* centerY, double* xAxis, double* yAxis, double* rotation)
  {
    QString str = lineEdit_7->text();
    if(!String_To_Double(str, centerX))
    {
        QMessageBox::critical(mainDlg, "Missing Value", "Please enter a valid center X value.");
        return false;
        }
    str = lineEdit_8->text();
    if(!String_To_Double(str, centerY))
    {
        QMessageBox::critical(mainDlg, "Missing Value", "Please enter a valid center Y value.");
        return false;
        }
    str = lineEdit_9->text();
    if(!String_To_Double(str, xAxis))
    {
        QMessageBox::critical(mainDlg, "Missing Value", "Please enter a valid X Axis value.");
        return false;
        }
    str = lineEdit_10->text();
    if(!String_To_Double(str, yAxis))
    {
        QMessageBox::critical(mainDlg, "Missing Value", "Please enter a valid Y Axis value.");
        return false;
        }
    str = lineEdit_11->text();
    if(!String_To_Double(str, rotation))
    {
        QMessageBox::critical(mainDlg, "Missing Value", "Please enter a valid rotation value.");
        return false;
        }
  }

  bool Geodesy::validatePolylineInputs(double* startX, double* startY, double* endX, double* endY)
  {


    QString str = lineEdit->text();
    if(!String_To_Double(str, startX))
    {
        QMessageBox::critical(mainDlg, "Missing Value", "Please enter a valid start X value.");
        return false;
        }
    str = lineEdit_5->text();
    if(!String_To_Double(str, startY))
    {
        QMessageBox::critical(mainDlg, "Missing Value", "Please enter a valid start Y value.");
        return false;
        }
    str = lineEdit_2->text();
    if(!String_To_Double(str, endX))
    {
        QMessageBox::critical(mainDlg, "Missing Value", "Please enter a valid end X value.");
        return false;
        }
    str = lineEdit_6->text();
    if(!String_To_Double(str, endY))
    {
        QMessageBox::critical(mainDlg, "Missing Value", "Please enter a valid end Y value.");
        return false;
        }


    return true;

  }
  bool Geodesy::String_To_Double(QString strVal, double* dblVal)
  {
    bool isOk = false;
    strVal = strVal.trimmed();
        if(strVal.size() <= 0)
        {
        return false;
    }
    else
    {
        double d = strVal.toDouble(&isOk);
        if(isOk == false)
        {
            return false;
        }
                else
        {
            *dblVal = d;
        }

    }
       return true;

  }
  void Geodesy::drawElement(IElement* ipElement)
  {
    //get ActiveView from MapControl
    IActiveViewPtr ipActiveView;
    m_ipMapControl->get_ActiveView(&ipActiveView);

    //get the GraphicsContainer and add element
    IGraphicsContainerPtr ipContainer;
    ipActiveView->get_GraphicsContainer(&ipContainer);
    ipContainer->AddElement(ipElement, 0);

    //refresh view to draw the added element
    ipActiveView->Refresh();
  }