public DmsLocation Convert(DecimalLocation decimalLocation)
        {
            if (decimalLocation == null)
            {
                return(null);
            }

            return(new DmsLocation
            {
                Latitude = new DmsPoint
                {
                    Degrees = ExtractDegrees(decimalLocation.Latitude),
                    Minutes = ExtractMinutes(decimalLocation.Latitude),
                    Seconds = ExtractSeconds(decimalLocation.Latitude),
                    Type = PointType.Lat
                },
                Longitude = new DmsPoint
                {
                    Degrees = ExtractDegrees(decimalLocation.Longitude),
                    Minutes = ExtractMinutes(decimalLocation.Longitude),
                    Seconds = ExtractSeconds(decimalLocation.Longitude),
                    Type = PointType.Lon
                }
            });
        }
        /// <summary>
        /// place the real GEO map underlay
        /// </summary>
        /// <param name="centerPt"></param>
        /// <param name="sourceMapCorners"></param>
        private void buildGEOImage(MapPointCls centerPt, MapPointCls[] sourceMapCorners)
        {
            var doc = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;

            if (doc == null)
            {
                return;
            }
            var db = doc.Database;
            var ed = doc.Editor;

            double ModelCenterX = HardCoded.ModelCenterX;
            double ModelCenterY = HardCoded.ModelCenterY;


            //GEO location data of the corners
            //the source are two points. calculate the other two points
            //convert them to string

            string[]     oMapCorners = new string[4];
            GEOConverter oGeoC       = new GEOConverter();

            //left top
            DecimalLocation decimalLocation = new DecimalLocation
            {
                Latitude  = (decimal)sourceMapCorners[0].latitude,
                Longitude = (decimal)sourceMapCorners[0].longitude
            };
            DmsLocation dmsLocation = oGeoC.Convert(decimalLocation);

            oMapCorners[0] = dmsLocation.ToString();

            //right top
            decimalLocation = new DecimalLocation
            {
                Latitude  = (decimal)sourceMapCorners[0].latitude,
                Longitude = (decimal)sourceMapCorners[1].longitude
            };
            dmsLocation    = oGeoC.Convert(decimalLocation);
            oMapCorners[1] = dmsLocation.ToString();

            //right bottom
            decimalLocation = new DecimalLocation
            {
                Latitude  = (decimal)sourceMapCorners[1].latitude,
                Longitude = (decimal)sourceMapCorners[1].longitude
            };
            dmsLocation    = oGeoC.Convert(decimalLocation);
            oMapCorners[2] = dmsLocation.ToString();

            //left bottom
            decimalLocation = new DecimalLocation
            {
                Latitude  = (decimal)sourceMapCorners[1].latitude,
                Longitude = (decimal)sourceMapCorners[0].longitude
            };
            dmsLocation    = oGeoC.Convert(decimalLocation);
            oMapCorners[3] = dmsLocation.ToString();


            //hard coded data of corners position in DWG
            CommonPointCls[] oDWGCorners = oHard_Coded_Data.GetDWGCorner();


            //create the text one by one
            using (Transaction acTrans = db.TransactionManager.StartTransaction())
            {
                BlockTable       acBlkTable = acTrans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = acTrans.GetObject(acBlkTable[BlockTableRecord.ModelSpace],
                                                                OpenMode.ForWrite) as BlockTableRecord;

                //place the position of each text
                for (int i = 0; i < oDWGCorners.Count <CommonPointCls>(); i++)
                {
                    DBText dt = new DBText();
                    dt.TextString = oMapCorners[i];

                    switch (i)
                    {
                    case 0:
                        //left top
                        dt.Justify  = AttachmentPoint.BottomMid;
                        dt.Rotation = 45;
                        break;

                    case 1:
                        //right top
                        dt.Justify  = AttachmentPoint.BottomMid;
                        dt.Rotation = -45;
                        break;

                    case 2:
                        //right bottom
                        dt.Justify  = AttachmentPoint.TopMid;
                        dt.Rotation = 45;
                        break;

                    case 3:
                        //left bottom
                        dt.Justify  = AttachmentPoint.TopMid;
                        dt.Rotation = -45;
                        break;
                    }

                    //align with the corner position
                    dt.AlignmentPoint = new Point3d(oDWGCorners[i].x, oDWGCorners[i].y, oDWGCorners[i].z);
                    dt.TransformBy(ed.CurrentUserCoordinateSystem);
                    dt.Color = Autodesk.AutoCAD.Colors.Color.FromRgb(0, 255, 255);

                    modelSpace.AppendEntity(dt);
                    acTrans.AddNewlyCreatedDBObject(dt, true);
                }

                acTrans.Commit();
            }

            //!!!
            return;

            //embed map underlay. not working with Design Automation

            // from
            //http://through-the-interface.typepad.com/through_the_interface/2014/06/attaching-geo-location-data-to-an-autocad-drawing-using-net.html
            try
            {
                var gdId = db.GeoDataObject;
                //if a map data is available
                //will not happen with current drawing template
            }
            catch
            {
                //no GEO data

                var msId = SymbolUtilityServices.GetBlockModelSpaceId(db);

                var data = new GeoLocationData();
                data.BlockTableRecordId = msId;
                data.PostToDb();

                // We're going to define our geolocation in terms of
                // latitude/longitude using the Mercator projection
                // http://en.wikipedia.org/wiki/Mercator_projection

                data.CoordinateSystem  = "WORLD-MERCATOR";
                data.TypeOfCoordinates = TypeOfCoordinates.CoordinateTypeLocal;

                //the two lines will cause GEOMapImage fail! strange!
                //data.HorizontalUnits = UnitsValue.Millimeters;
                //data.VerticalUnits = UnitsValue.Millimeters;

                var geoPt = new Point3d(centerPt.longitude, centerPt.latitude, 0);

                // Transform from a geographic to a modelspace point
                // and add the information to our geolocation data
                var wcsPt = data.TransformFromLonLatAlt(geoPt);
                data.DesignPoint    = new Point3d(ModelCenterX, ModelCenterY, 0);
                data.ReferencePoint = wcsPt;
                data.ScaleFactor    = 7; //? useful?

                ed.Command("_.GEOMAP", "_ROAD");


                // then create the map image
                //createMapImage(data);
            }
        }