[mapguide-commits] r4405 - in sandbox/rfc60/MgDev/Common: CoordinateSystem Foundation Foundation/Exception Foundation/System Geometry Geometry/CoordinateSystem Geometry/Spatial MapGuideCommon/MapLayer MapGuideCommon/Services MapGuideCommon/System PlatformBase/Services Renderers Stylization

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed Dec 9 17:21:35 EST 2009


Author: uvlite
Date: 2009-12-09 17:21:34 -0500 (Wed, 09 Dec 2009)
New Revision: 4405

Added:
   sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysEnvVariable.h
   sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsMajorRegion.cpp
   sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsMajorRegion.h
   sandbox/rfc60/MgDev/Common/Foundation/Exception/GridDensityException.cpp
   sandbox/rfc60/MgDev/Common/Foundation/Exception/GridDensityException.h
   sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemMgrsGridSquarePosition.h
Modified:
   sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysCatalog.cpp
   sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGridGeneric.cpp
   sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGridGeneric.h
   sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGrids.cpp
   sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGrids.h
   sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrs.cpp
   sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrs.h
   sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsZone.cpp
   sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsZone.h
   sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysOneGrid.cpp
   sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysOneGrid.h
   sandbox/rfc60/MgDev/Common/Foundation/Foundation.h
   sandbox/rfc60/MgDev/Common/Foundation/Foundation.vcproj
   sandbox/rfc60/MgDev/Common/Foundation/FoundationBuild.cpp
   sandbox/rfc60/MgDev/Common/Foundation/Makefile.am
   sandbox/rfc60/MgDev/Common/Foundation/System/FoundationClassId.h
   sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemCommon.h
   sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemErrorCode.h
   sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemGrids.h
   sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemMgrs.h
   sandbox/rfc60/MgDev/Common/Geometry/Geometry.vcproj
   sandbox/rfc60/MgDev/Common/Geometry/GeometryCommon.h
   sandbox/rfc60/MgDev/Common/Geometry/Makefile.am
   sandbox/rfc60/MgDev/Common/Geometry/Spatial/SpatialUtility.cpp
   sandbox/rfc60/MgDev/Common/MapGuideCommon/MapLayer/Layer.cpp
   sandbox/rfc60/MgDev/Common/MapGuideCommon/Services/ProxyResourceService.cpp
   sandbox/rfc60/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp
   sandbox/rfc60/MgDev/Common/MapGuideCommon/System/ConfigProperties.h
   sandbox/rfc60/MgDev/Common/PlatformBase/Services/FeatureReader.cpp
   sandbox/rfc60/MgDev/Common/Renderers/KmlRenderer.cpp
   sandbox/rfc60/MgDev/Common/Stylization/ExpressionFunctionIf.cpp
   sandbox/rfc60/MgDev/Common/Stylization/SE_PositioningAlgorithms.cpp
   sandbox/rfc60/MgDev/Common/Stylization/SE_RenderProxies.h
   sandbox/rfc60/MgDev/Common/Stylization/SE_Renderer.cpp
   sandbox/rfc60/MgDev/Common/Stylization/SE_StyleVisitor.cpp
   sandbox/rfc60/MgDev/Common/Stylization/SE_SymbolDefProxies.cpp
   sandbox/rfc60/MgDev/Common/Stylization/SE_SymbolDefProxies.h
   sandbox/rfc60/MgDev/Common/Stylization/StylizationEngine.cpp
Log:
RFC60 merged Common from trunk to sandbox 

Modified: sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysCatalog.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysCatalog.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysCatalog.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -54,6 +54,10 @@
 #undef GetMessage
 #endif
 
+#ifndef _WIN32
+#include "CoordSysEnvVariable.h"
+#endif
+
 //Global variables needed from Mentor
 extern "C"
 {
@@ -224,7 +228,7 @@
     if (sDir.empty())
     {
         bResult = true;
-        sDir = L"/opt/Autodesk/mapguideenterprise2010/share/gis/coordsys";  // NOXLATE
+        sDir = LINUX_COORD_PATH;
     }
 
 #endif

Copied: sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysEnvVariable.h (from rev 4398, trunk/MgDev/Common/CoordinateSystem/CoordSysEnvVariable.h)
===================================================================
--- sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysEnvVariable.h	                        (rev 0)
+++ sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysEnvVariable.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -0,0 +1,11 @@
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+#define LINUX_COORD_PATH    L"/usr/local/mapguideopensource/share/gis/coordsys";  // NOXLATE
\ No newline at end of file

Modified: sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGridGeneric.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGridGeneric.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGridGeneric.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -26,10 +26,17 @@
 
 using namespace CSLibrary;
 
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+const INT32 CCoordinateSystemGridGeneric::m_GridLineExceptionLevelK   =  50000000L;     //   50MB
+const INT32 CCoordinateSystemGridGeneric::m_GridRegionExceptionLevelK =  30000000L;      //  30MB
+const INT32 CCoordinateSystemGridGeneric::m_GridTickExceptionLevelK   =  20000000L;      //  20MB
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 CCoordinateSystemGridGeneric::CCoordinateSystemGridGeneric(bool bSetExceptionsOn)
                             :
                        m_bExceptionsOn (bSetExceptionsOn),
+                       m_GridLineExceptionLevel   (m_GridLineExceptionLevelK),
+                       m_GridRegionExceptionLevel (m_GridRegionExceptionLevelK),
+                       m_GridTickExceptionLevel   (m_GridTickExceptionLevelK),
                        m_nLastError    (0),
                        m_pCsSource     (),
                        m_pCsTarget     (),
@@ -42,6 +49,9 @@
                                                            bool bSetExceptionsOn)
                             :
                        m_bExceptionsOn (bSetExceptionsOn),
+                       m_GridLineExceptionLevel   (m_GridLineExceptionLevelK),
+                       m_GridRegionExceptionLevel (m_GridRegionExceptionLevelK),
+                       m_GridTickExceptionLevel   (m_GridTickExceptionLevelK),
                        m_nLastError    (0),
                        m_pCsSource     (),
                        m_pCsTarget     (),
@@ -66,6 +76,8 @@
 {
     m_FrameBoundary = SAFE_ADDREF (pFrameBoundary);
     m_TheGrid = new CCoordinateSystemOneGrid (m_FrameBoundary,m_pCsSource,m_pCsTarget);
+    m_TheGrid->SetGridLineExceptionLevel (m_GridLineExceptionLevel);
+    m_TheGrid->SetGridTickExceptionLevel (m_GridTickExceptionLevel);
 }
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 MgCoordinateSystemGridBoundary* CCoordinateSystemGridGeneric::GetBoundary(void)
@@ -97,13 +109,90 @@
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 double CCoordinateSystemGridGeneric::GetConvergenceAngle (MgCoordinate* location)
 {
-    return 0.0;
+    double longitude;
+    double latitude;
+    double convergence;
+
+    longitude = location->GetX ();
+    latitude  = location->GetY ();
+    convergence = m_pCsTarget->GetConvergence (longitude,latitude);
+    return convergence;
 }
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 double CCoordinateSystemGridGeneric::GetProjectiveGridScale (MgCoordinate* location)
 {
-    return 1.0;
+    double longitude;
+    double latitude;
+    double scale;
+
+    longitude = location->GetX ();
+    latitude  = location->GetY ();
+    scale = m_pCsTarget->GetScale (longitude,latitude);
+    return scale;
 }
+INT32 CCoordinateSystemGridGeneric::ApproxGridLineMemoryUsage (MgCoordinateSystemGridSpecification* specification)
+{
+    INT32 memoryUse (-1);
+
+    if (m_FrameBoundary != 0)
+    {
+        memoryUse = m_TheGrid->ApproxGridLineMemoryUsage (specification);
+    }
+    return memoryUse;
+}
+INT32 CCoordinateSystemGridGeneric::ApproxGridRegionMemoryUsage (MgCoordinateSystemGridSpecification* specification)
+{
+    INT32 memoryUse;
+    
+    memoryUse = (m_FrameBoundary != 0) ? 0 : -1;
+    return memoryUse;
+}
+INT32 CCoordinateSystemGridGeneric::ApproxGridTickMemoryUsage (MgCoordinateSystemGridSpecification* specification)
+{
+    INT32 memoryUse (-1);
+
+    if (m_FrameBoundary != 0)
+    {
+        memoryUse = m_TheGrid->ApproxGridTickMemoryUsage (specification);
+    }
+    return memoryUse;
+}
+INT32 CCoordinateSystemGridGeneric::SetGridLineExceptionLevel (INT32 memoryUseMax)
+{
+    INT32 rtnValue = m_GridLineExceptionLevel;
+    if (memoryUseMax > 0)
+    {
+        m_GridLineExceptionLevel = memoryUseMax;
+        if (m_TheGrid != 0)
+        {
+            m_TheGrid->SetGridLineExceptionLevel (m_GridLineExceptionLevel);
+        }
+    }
+    return rtnValue;
+}
+INT32 CCoordinateSystemGridGeneric::SetGridRegionExceptionLevel (INT32 memoryUseMax)
+{
+    INT32 rtnValue = m_GridRegionExceptionLevel;
+    if (memoryUseMax > 0)
+    {
+        m_GridRegionExceptionLevel = memoryUseMax;
+    }
+    return rtnValue;
+}
+INT32 CCoordinateSystemGridGeneric::SetGridTickExceptionLevel (INT32 memoryUseMax)
+{
+    INT32 rtnValue = m_GridTickExceptionLevel;
+    if (memoryUseMax > 0)
+    {
+        m_GridTickExceptionLevel = memoryUseMax;
+        if (m_TheGrid != 0)
+        {
+            m_TheGrid->SetGridTickExceptionLevel (m_GridTickExceptionLevel);
+        }
+    }
+    return rtnValue;
+}
+
 INT32 CCoordinateSystemGridGeneric::GetLastError()
 {
     return m_nLastError;

Modified: sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGridGeneric.h
===================================================================
--- sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGridGeneric.h	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGridGeneric.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -25,6 +25,9 @@
 
 class CCoordinateSystemGridGeneric : public MgCoordinateSystemGridGeneric
 {
+    static const INT32 m_GridLineExceptionLevelK;
+    static const INT32 m_GridRegionExceptionLevelK;
+    static const INT32 m_GridTickExceptionLevelK;
 public:
     CCoordinateSystemGridGeneric(bool bSetExceptionsOn);
     CCoordinateSystemGridGeneric(MgCoordinateSystem* pSourceCs,MgCoordinateSystem* pTargetCs,bool bSetExceptionsOn);
@@ -40,6 +43,14 @@
     double GetConvergenceAngle (MgCoordinate* location);
     double GetProjectiveGridScale (MgCoordinate* location);
 
+    INT32 ApproxGridLineMemoryUsage (MgCoordinateSystemGridSpecification* specification);
+    INT32 ApproxGridRegionMemoryUsage (MgCoordinateSystemGridSpecification* specification);
+    INT32 ApproxGridTickMemoryUsage (MgCoordinateSystemGridSpecification* specification);
+
+    INT32 SetGridLineExceptionLevel (INT32 memoryUseMax);
+    INT32 SetGridRegionExceptionLevel (INT32 memoryUseMax);
+    INT32 SetGridTickExceptionLevel (INT32 memoryUseMax);
+
     INT32 GetLastError();
     void ResetLastError();
     bool AreExceptionsOn();
@@ -49,8 +60,15 @@
     //from MgDisposable
     void Dispose();
 
-    // Data Memebrs
+    // Data Memebers -- The m_GridRegionExcpetionLevel member is not really
+    // applicable to generic grids.  However, since the ApproxGridRegionMemoryUsage
+    // and SetGridRegionExceptionLevel functions are pure virtual functions in the
+    // interface, the functions need to exist.  So, for now we _pretend_ that
+    // the 'Region' memory limits are applicable to generic grids.
     bool m_bExceptionsOn;
+    INT32 m_GridLineExceptionLevel;
+    INT32 m_GridRegionExceptionLevel;
+    INT32 m_GridTickExceptionLevel;
     INT32 m_nLastError;
     Ptr<MgCoordinateSystem> m_pCsSource;
     Ptr<MgCoordinateSystem> m_pCsTarget;

Modified: sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGrids.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGrids.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGrids.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -30,6 +30,16 @@
 
 using namespace CSLibrary;
 
+#if !defined (_DEBUG)
+    // Include heap overhead estimated at 12 bytes in release mode.
+    static const INT32 kMgHeapOverhead = 12;
+    static const INT32 kMgSizeOfCoordinateXY = sizeof (MgCoordinateXY) + kMgHeapOverhead;
+#else
+    // Include heap overhead estimated at 36 bytes in release mode.
+    static const INT32 kMgHeapOverhead = 36;
+    static const INT32 kMgSizeOfCoordinateXY = sizeof (MgCoordinateXY) + kMgHeapOverhead;
+#endif
+
 //=============================================================================
 // CCoordinateSystemGridSpecification -- Assembly which contains all grid
 //                                       parameter values.
@@ -50,7 +60,8 @@
                                                                                 m_TickEastingIncrement  (0),
                                                                                 m_TickNorthingIncrement (0),
                                                                                 m_UnitType              (MgCoordinateSystemUnitType::Linear),
-                                                                                m_UnitCode              (MgCoordinateSystemUnitCode::Meter)
+                                                                                m_UnitCode              (MgCoordinateSystemUnitCode::Meter),
+                                                                                m_MaxCurvePoints        (0)
 {
 }
 CCoordinateSystemGridSpecification::CCoordinateSystemGridSpecification (const CCoordinateSystemGridSpecification& source)
@@ -63,7 +74,8 @@
                                                                         m_TickEastingIncrement  (source.m_TickEastingIncrement),
                                                                         m_TickNorthingIncrement (source.m_TickNorthingIncrement),
                                                                         m_UnitType              (source.m_UnitType),
-                                                                        m_UnitCode              (source.m_UnitCode)
+                                                                        m_UnitCode              (source.m_UnitCode),
+                                                                        m_MaxCurvePoints        (source.m_MaxCurvePoints)
 {
 }
 CCoordinateSystemGridSpecification::~CCoordinateSystemGridSpecification (void)
@@ -82,6 +94,7 @@
         m_TickNorthingIncrement = rhs.m_TickNorthingIncrement;
         m_UnitType              = rhs.m_UnitType;
         m_UnitCode              = rhs.m_UnitCode;
+        m_MaxCurvePoints        = rhs.m_MaxCurvePoints;
     }
     return *this;
 }
@@ -117,6 +130,14 @@
 {
     return m_UnitCode;
 }
+double CCoordinateSystemGridSpecification::GetCurvePrecision(void)
+{
+    return m_CurvePrecision;
+}
+INT32 CCoordinateSystemGridSpecification::GetMaxCurvePoints(void)
+{
+    return m_MaxCurvePoints;
+}
 bool CCoordinateSystemGridSpecification::IsSameAs(MgCoordinateSystemGridSpecification* specification)
 {
     bool areTheSame (false);
@@ -138,10 +159,6 @@
 
     return areTheSame;
 }
-double CCoordinateSystemGridSpecification::GetCurvePrecision(void)
-{
-    return m_CurvePrecision;
-}
 
 void CCoordinateSystemGridSpecification::SetGridBase(double eastingBase,double northingBase)
 {
@@ -177,6 +194,10 @@
 {
     m_CurvePrecision = curvePrecision;
 }
+void CCoordinateSystemGridSpecification::SetMaxCurvePoints (INT32 maxCurvePoints)
+{
+    m_CurvePrecision = maxCurvePoints;
+}
 // The following functions are identical to the published version, with the
 // exception that the values returned are always converted to the units requested
 // by the resultUnitCode argument.
@@ -258,6 +279,25 @@
     precisionInCsUnits = precisionInMeters * csUnitConversion;
     return precisionInCsUnits;
 }
+double CCoordinateSystemGridSpecification::GetCurvePrecision (MgCoordinateSystemGridBoundary* gridBoundary,
+                                                              MgCoordinateSystem* gridCS)
+{
+    double precisionInCsUnits;
+
+    precisionInCsUnits = GetCurvePrecision (gridCS);
+    return precisionInCsUnits;
+}
+double CCoordinateSystemGridSpecification::GetMaxCurvePoints (MgCoordinateSystemGridBoundary* frameBoundary,
+                                                              MgCoordinateSystem* frameCS)
+{
+    INT32 maxPoints (511);
+
+    if (m_MaxCurvePoints > 0)
+    {
+        maxPoints = m_MaxCurvePoints;
+    }
+    return maxPoints;
+}
 bool CCoordinateSystemGridSpecification::IsConsistent ()
 {
     bool ok (false);
@@ -630,6 +670,28 @@
 {
     return SAFE_ADDREF(m_LineSegments.p);
 }
+INT32 CCoordinateSystemGridLine::GetMemoryUsage ()
+{
+    INT32 lineIndex;
+    INT32 lineCount;
+    INT32 memoryUse = sizeof (CCoordinateSystemGridLine) + kMgHeapOverhead;
+
+    lineCount = m_LineSegments->GetCount ();
+    for (lineIndex = 0;lineIndex < lineCount;lineIndex += 1)
+    {
+        Ptr<MgLineString> lineStringPtr = m_LineSegments->GetItem (lineIndex);
+        if (lineStringPtr != 0)
+        {
+            memoryUse += sizeof (MgLineString) + kMgHeapOverhead;
+            Ptr<MgCoordinateIterator> pointItr = lineStringPtr->GetCoordinates ();
+            while (pointItr->MoveNext ())
+            {
+                memoryUse += kMgSizeOfCoordinateXY;
+            }
+        }
+    }
+    return memoryUse;
+}
 void CCoordinateSystemGridLine::SetSegmentCollection (MgLineStringCollection* segmentCollection)
 {
     m_LineSegments = SAFE_ADDREF (segmentCollection);
@@ -752,7 +814,26 @@
 {
     return SAFE_ADDREF(m_WestLine.p);
 }
+INT32 CCoordinateSystemGridRegion::GetMemoryUsage ()
+{
+    INT32 memoryUse;
 
+    memoryUse  = sizeof (CCoordinateSystemGridRegion) + kMgHeapOverhead;
+    memoryUse += sizeof (STRING);
+    memoryUse += m_RegionLabel.capacity () * sizeof (wchar_t);
+    memoryUse += kMgSizeOfCoordinateXY;
+    memoryUse += PolygonMemoryUse (m_RegionBoundary.p);
+    memoryUse += LineStringCollectionMemoryUse (m_SouthLine.p);
+    memoryUse += LineStringCollectionMemoryUse (m_EastLine.p);
+    memoryUse += LineStringCollectionMemoryUse (m_NorthLine.p);
+    memoryUse += LineStringCollectionMemoryUse (m_WestLine.p);
+
+    // Testing has shown the above calculation to be about 20% low.
+    // This is assumed to be because collections have a capacity and a useage,
+    // and while we measure usage above, we can't measure capacity.
+    memoryUse += memoryUse / 5;
+    return memoryUse;
+}
 void CCoordinateSystemGridRegion::SetRegionBoundary (MgPolygon* boundary)
 {
     m_RegionBoundary = SAFE_ADDREF (boundary);
@@ -777,6 +858,50 @@
 {
     delete this;
 }
+INT32 CCoordinateSystemGridRegion::PolygonMemoryUse (MgPolygon* polygon)
+{
+    // While MgPolygon objects support holes, there are no holes in a Region
+    // (so far anyway); so we only evaluate the exterior ring.
+
+    INT32 memoryUse;
+
+    memoryUse = sizeof (MgPolygon) + kMgHeapOverhead;
+    if (polygon != 0)
+    {
+        Ptr<MgCoordinateIterator> pointItr = polygon->GetCoordinates ();
+        while (pointItr->MoveNext ())
+        {
+            memoryUse += kMgSizeOfCoordinateXY;
+        }
+    }
+    return memoryUse;
+}
+INT32 CCoordinateSystemGridRegion::LineStringCollectionMemoryUse (MgLineStringCollection* lineCollection)
+{
+    INT32 memoryUse (0);
+    INT32 lineCount;
+    INT32 lineIndex;
+
+    if (lineCollection != 0)
+    {
+        memoryUse += sizeof (MgLineStringCollection) + kMgHeapOverhead;
+        lineCount = lineCollection->GetCount ();
+        for (lineIndex = 0;lineIndex < lineCount;lineIndex += 1)
+        {
+            Ptr<MgLineString> lineStringPtr = lineCollection->GetItem (lineIndex);
+            if (lineStringPtr != 0)
+            {
+                memoryUse += sizeof (MgLineString) + kMgHeapOverhead;
+                Ptr<MgCoordinateIterator> pointItr = lineStringPtr->GetCoordinates ();
+                while (pointItr->MoveNext ())
+                {
+                    memoryUse += kMgSizeOfCoordinateXY;
+                }
+            }
+        }
+    }
+    return memoryUse;
+}
 //=============================================================================
 // CCoordinateSystemGridTick -- Defines the location of a grid tick mark.
 //
@@ -840,6 +965,12 @@
 {
     return SAFE_ADDREF(m_Direction.p);
 }
+INT32 CCoordinateSystemGridTick::GetMemoryUsage ()
+{
+    INT32 memoryUse = sizeof (CCoordinateSystemGridTick) + kMgHeapOverhead;
+    memoryUse += (kMgSizeOfCoordinateXY + kMgSizeOfCoordinateXY);
+    return memoryUse;
+}
 void CCoordinateSystemGridTick::Dispose ()
 {
     delete this;
@@ -850,11 +981,14 @@
 // appear first in ascending order by grid value (easting in this case);
 // followed by grid vertical lines in ascending order by grid value (northing
 // in this case).
-CCoordinateSystemGridLineCollection::CCoordinateSystemGridLineCollection (void)
+CCoordinateSystemGridLineCollection::CCoordinateSystemGridLineCollection (INT32 gridLineExceptionLevel)
                                         :
                                      MgCoordinateSystemGridLineCollection (),
+                                     m_MemoryUse                          (),
+                                     m_GridLineExceptionLevel             (gridLineExceptionLevel),
                                      m_GridLineCollection ()
 {
+    m_MemoryUse = sizeof (MgCoordinateSystemGridLineCollection) + sizeof (MgDisposableCollection);
     m_GridLineCollection = new MgDisposableCollection();
 }
 CCoordinateSystemGridLineCollection::~CCoordinateSystemGridLineCollection(void)
@@ -904,23 +1038,68 @@
 }
 void CCoordinateSystemGridLineCollection::RemoveAt (INT32 index)
 {
+    INT32 memoryUse (0);
+
     // The MgDisposableCollection object checks the index argument, and throws if appropriate.
     // The MgDisposableCollection object performs the "SAFE_RELEASE" operation.
+
+    if (index >= 0 && index < GetCount ())
+    {
+        // We don't want an invalid index exception thrown from this GetItem,
+        // we leave that to the RemoveAt function.  Also, this releases the
+        // pointer we get before the exception is thrown.
+        Ptr<MgCoordinateSystemGridLine> gridLinePtr = GetItem (index);
+        if (gridLinePtr != 0)
+        {
+            memoryUse = gridLinePtr->GetMemoryUsage ();
+        }
+    }
     m_GridLineCollection->RemoveAt (index);
+    m_MemoryUse -= memoryUse;
 }
 void CCoordinateSystemGridLineCollection::Clear()
 {
     // The MgDisposableCollection object performs the "SAFE_RELEASE" operation.
     m_GridLineCollection->Clear ();
+    m_MemoryUse = sizeof (MgCoordinateSystemGridLineCollection) + sizeof (MgDisposableCollection);
 }
 void CCoordinateSystemGridLineCollection::SetItem (INT32 index,MgCoordinateSystemGridLine* value)
 {
-    // The MgDisposableCollection object checks the index argument, and throws if appropriate.
-    // The MgDisposableCollection object performs the "SAFE_RELEASE" & "SAFE_ADDREF" operations.
+    INT32 memoryUse (0);
+
+    memoryUse = value->GetMemoryUsage ();
+    if (index >= 0 && index < GetCount ())
+    {
+        Ptr<MgCoordinateSystemGridLine> oldGridLine = GetItem (index);
+        if (oldGridLine != 0)
+        {
+            memoryUse -= oldGridLine->GetMemoryUsage ();
+        }
+    }
+    if ((m_MemoryUse + memoryUse) < m_GridLineExceptionLevel)
+    {
     m_GridLineCollection->SetItem (index,value);
 }
+    else
+    {
+        throw new MgGridDensityException(L"CCoordinateSystemGridLineCollection.SetItem", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+}
 void CCoordinateSystemGridLineCollection::Add (MgCoordinateSystemGridLine* value)
 {
+    INT32 memoryUse;
+
+    memoryUse = value->GetMemoryUsage ();
+    if ((memoryUse + m_MemoryUse) < m_GridLineExceptionLevel)
+    {
+        m_GridLineCollection->Add (value);
+        m_MemoryUse += memoryUse;
+    }
+    else
+    {
+        throw new MgGridDensityException(L"CCoordinateSystemGridLineCollection.Add", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
     // The MgDIsposableCollection object does the "SAFE_ADDREF" operation.
     m_GridLineCollection->Add (value);
 }
@@ -928,19 +1107,39 @@
 {
     INT32 index;
     INT32 toAddCount;
+    INT32 maxValue;
+    INT32 memoryUse;
     Ptr<MgCoordinateSystemGridLine> aGridLine;
     
+    maxValue = m_GridLineExceptionLevel - m_MemoryUse;
+    memoryUse = aGridLineCollection->GetMemoryUsage ();
+    if (memoryUse > maxValue)
+    {
+        throw new MgGridDensityException(L"CCoordinateSystemGridLineCollection.AddCollection", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
     MG_TRY ()
         toAddCount = aGridLineCollection->GetCount ();
         for (index = 0;index < toAddCount;index += 1)
         {
             aGridLine = aGridLineCollection->GetItem (index);
-            // This Add refers to the "this" object.
-            m_GridLineCollection->Add (aGridLine);
+            this->Add (aGridLine);
         }
-    MG_CATCH_AND_THROW(L"CCoordinateSystemGridLineCollection::IndexOf")
+    MG_CATCH_AND_THROW(L"CCoordinateSystemGridLineCollection::AddCollection")
     return;
 }
+INT32 CCoordinateSystemGridLineCollection::SetGridLineExceptionLevel (INT32 memoryUseMax)
+{
+    INT32 rtnValue = m_GridLineExceptionLevel;
+    if (memoryUseMax > 0L)
+    {
+        m_GridLineExceptionLevel = memoryUseMax;
+    }
+    return rtnValue;
+}
+INT32 CCoordinateSystemGridLineCollection::GetMemoryUsage (void)
+{
+    return m_MemoryUse;
+}
 void CCoordinateSystemGridLineCollection::Dispose(void)
 {
     delete this;
@@ -949,11 +1148,14 @@
 //=============================================================================
 // A CCoordinateSystemGridRegionCollection is collection of
 // CCoordinateSystemGridRegion objects.
-CCoordinateSystemGridRegionCollection::CCoordinateSystemGridRegionCollection ()
+CCoordinateSystemGridRegionCollection::CCoordinateSystemGridRegionCollection (INT32 gridRegionExceptionLevel)
                                          :
                                        MgCoordinateSystemGridRegionCollection (),
+                                       m_MemoryUse                            (),
+                                       m_GridRegionExceptionLevel             (gridRegionExceptionLevel),
                                        m_GridRegionCollection ()
 {
+    m_MemoryUse = sizeof (CCoordinateSystemGridRegionCollection) + sizeof (MgDisposableCollection);
     m_GridRegionCollection = new MgDisposableCollection();
 }
 CCoordinateSystemGridRegionCollection::~CCoordinateSystemGridRegionCollection (void)
@@ -974,42 +1176,107 @@
 }
 void CCoordinateSystemGridRegionCollection::RemoveAt (INT32 index)
 {
+    INT32 memoryUse (0);
+
     // The MgDisposableCollection object checks the index argument, and throws if appropriate.
     // The MgDisposableCollection object performs the "SAFE_RELEASE" operation.
+
+    if (index >= 0 && index < GetCount ())
+    {
+        // We don't want an invalid index exception thrown from this GetItem,
+        // we leave that to the RemoveAt function.  Also, this releases the
+        // pointer we get before the exception is thrown.
+        Ptr<MgCoordinateSystemGridRegion> gridRegionPtr = GetItem (index);
+        if (gridRegionPtr != 0)
+        {
+            memoryUse = gridRegionPtr->GetMemoryUsage ();
+        }
+    }
     m_GridRegionCollection->RemoveAt (index);
+    m_MemoryUse -= memoryUse;
 }
 void CCoordinateSystemGridRegionCollection::Clear()
 {
     m_GridRegionCollection->Clear ();
+    m_MemoryUse = sizeof (CCoordinateSystemGridRegionCollection) + sizeof (MgDisposableCollection);
 }
 void CCoordinateSystemGridRegionCollection::SetItem (INT32 index, MgCoordinateSystemGridRegion* value)
 {
-    // The MgDisposableCollection object checks the index argument, and throws if appropriate.
-    // The MgDisposableCollection object performs the "SAFE_RELEASE" & "SAFE_ADDREF" operations.
+    INT32 memoryUse;
+
+    memoryUse = value->GetMemoryUsage ();
+    if (index >= 0 && index < GetCount ())
+    {
+        Ptr<MgCoordinateSystemGridRegion> currentPtr = GetItem (index);
+        if (currentPtr != 0)
+        {
+            memoryUse -= currentPtr->GetMemoryUsage ();
+        }
+    }
+    if ((m_MemoryUse + memoryUse) < m_GridRegionExceptionLevel)
+    {
     m_GridRegionCollection->SetItem (index,value);
+        m_MemoryUse += memoryUse;
 }
+    else
+    {
+        throw new MgGridDensityException(L"CCoordinateSystemGridRegionCollection.SetItem", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+}
 void CCoordinateSystemGridRegionCollection::Add (MgCoordinateSystemGridRegion* value)
 {
-    // The MgDisposableCollection object performs the "SAFE_ADDREF" operation.
+    INT32 memoryUse;
+
+    memoryUse = value->GetMemoryUsage ();
+    if ((memoryUse + m_MemoryUse) < m_GridRegionExceptionLevel)
+    {
     m_GridRegionCollection->Add (value);
+        m_MemoryUse += memoryUse;
 }
+    else
+    {
+        throw new MgGridDensityException(L"CCoordinateSystemGridRegionCollection.Add", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+}
 void CCoordinateSystemGridRegionCollection::AddCollection (MgCoordinateSystemGridRegionCollection* aGridRegionCollection)
 {
     INT32 index;
     INT32 toAddCount;
+    INT32 memoryUse;
+    INT32 maxValue;
     Ptr<MgCoordinateSystemGridRegion> aGridRegion;
     
+    maxValue = m_GridRegionExceptionLevel - m_MemoryUse;
+    memoryUse = aGridRegionCollection->GetMemoryUsage ();
+    if (memoryUse > maxValue)
+    {
+        throw new MgGridDensityException(L"CCoordinateSystemGridRegionCollection.AddCollection", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
     MG_TRY ()
+        
         toAddCount = aGridRegionCollection->GetCount ();
         for (index = 0;index < toAddCount;index += 1)
         {
             aGridRegion = aGridRegionCollection->GetItem (index);
             // This Add refers to the "this" object.
-            m_GridRegionCollection->Add (aGridRegion);
+            this->Add (aGridRegion);
         }
     MG_CATCH_AND_THROW(L"CCoordinateSystemGridRegionCollection::AddCollection")
     return;
 }
+INT32 CCoordinateSystemGridRegionCollection::SetGridRegionExceptionLevel (INT32 memoryUseMax)
+{
+    INT32 rtnValue = m_GridRegionExceptionLevel;
+    if (memoryUseMax > 0L)
+    {
+        m_GridRegionExceptionLevel = memoryUseMax;
+    }
+    return rtnValue;
+}
+INT32 CCoordinateSystemGridRegionCollection::GetMemoryUsage (void)
+{
+    return m_MemoryUse;
+}
 void CCoordinateSystemGridRegionCollection::Dispose (void)
 {
     // Destructor deletes the contents of the collection.
@@ -1021,11 +1288,14 @@
 // CCoordinateSystemGridTick objects.  CCoordinateSystemGridTickCollection
 // objects will contain MgCoordinateSystemGridTick objects for the entire
 // boundary or for an individual grid line.
-CCoordinateSystemGridTickCollection::CCoordinateSystemGridTickCollection (void)
+CCoordinateSystemGridTickCollection::CCoordinateSystemGridTickCollection (INT32 gridTickExceptionLevel)
                                         :
                                      MgCoordinateSystemGridTickCollection (),
+                                     m_MemoryUse                          (),
+                                     m_GridTickExceptionLevel             (gridTickExceptionLevel),
                                      m_GridTickCollection ()
 {
+    m_MemoryUse = sizeof (CCoordinateSystemGridTickCollection) + sizeof (MgDisposableCollection);
     m_GridTickCollection = new MgDisposableCollection();
 }
 CCoordinateSystemGridTickCollection::~CCoordinateSystemGridTickCollection (void)
@@ -1044,36 +1314,106 @@
 }
 void CCoordinateSystemGridTickCollection::RemoveAt (INT32 index)
 {
+    INT32 memoryUse (0);
+
+    // The MgDisposableCollection object checks the index argument, and throws if appropriate.
+    // The MgDisposableCollection object performs the "SAFE_RELEASE" operation.
+
+    if (index >= 0 && index < GetCount ())
+    {
+        // We don't want an invalid index exception thrown from this GetItem,
+        // we leave that to the RemoveAt function.  Also, this releases the
+        // pointer we get before the exception is thrown.
+        Ptr<MgCoordinateSystemGridTick> gridTickPtr = GetItem (index);
+        if (gridTickPtr != 0)
+        {
+            memoryUse = gridTickPtr->GetMemoryUsage ();
+        }
+    }
     m_GridTickCollection->RemoveAt (index);
+    m_MemoryUse -= memoryUse;
 }
 void CCoordinateSystemGridTickCollection::Clear()
 {
     m_GridTickCollection->Clear ();
+    m_MemoryUse = sizeof (CCoordinateSystemGridTickCollection) + sizeof (MgDisposableCollection);
 }
 void CCoordinateSystemGridTickCollection::SetItem (INT32 index, MgCoordinateSystemGridTick* value)
 {
+    INT32 memoryUse;
+
+    memoryUse = value->GetMemoryUsage ();
+    if (index >= 0 && index < GetCount ())
+    {
+        Ptr<MgCoordinateSystemGridTick> currentPtr = GetItem (index);
+        if (currentPtr != 0)
+        {
+            memoryUse -= currentPtr->GetMemoryUsage ();
+        }
+    }
+    if ((m_MemoryUse + memoryUse) < m_GridTickExceptionLevel)
+    {
     m_GridTickCollection->SetItem (index,value);
+        m_MemoryUse += memoryUse;
 }
+    else
+    {
+        throw new MgGridDensityException(L"CCoordinateSystemGridTickCollection.SetItem", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+}
 void CCoordinateSystemGridTickCollection::Add (MgCoordinateSystemGridTick* value)
 {
+    INT32 memoryUse;
+
+    memoryUse = value->GetMemoryUsage ();
+    if ((memoryUse + m_MemoryUse) < m_GridTickExceptionLevel)
+    {
     m_GridTickCollection->Add (value);
+        m_MemoryUse += memoryUse;
 }
+    else
+    {
+        throw new MgGridDensityException(L"CCoordinateSystemGridTickCollection.Add", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+}
 void CCoordinateSystemGridTickCollection::AddCollection (MgCoordinateSystemGridTickCollection* aGridTickCollection)
 {
     INT32 index;
     INT32 toAddCount;
+    INT32 maxValue;
+    INT32 memoryUse;
     Ptr<MgCoordinateSystemGridTick> aGridTick;
     
+    maxValue = m_GridTickExceptionLevel - m_MemoryUse;
+    memoryUse = aGridTickCollection->GetMemoryUsage ();
+    if (memoryUse > maxValue)
+    {
+        throw new MgGridDensityException(L"CCoordinateSystemGridTickCollection.AddCollection", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
     MG_TRY ()
         toAddCount = aGridTickCollection->GetCount ();
         for (index = 0;index < toAddCount;index += 1)
         {
             aGridTick = aGridTickCollection->GetItem (index);
-            m_GridTickCollection->Add (aGridTick);
+            this->Add (aGridTick);
         }
     MG_CATCH_AND_THROW(L"CCoordinateSystemGridTickCollection::AddCollection")
     return;
 }
+INT32 CCoordinateSystemGridTickCollection::SetGridTickExceptionLevel (INT32 memoryUseMax)
+{
+    INT32 rtnValue = m_GridTickExceptionLevel;
+    if (memoryUseMax > 0L)
+    {
+        m_GridTickExceptionLevel = memoryUseMax;
+    }
+    return rtnValue;
+}
+INT32 CCoordinateSystemGridTickCollection::GetMemoryUsage ()
+{
+    return m_MemoryUse;
+}
 void CCoordinateSystemGridTickCollection::Dispose (void)
 {
     delete this;

Modified: sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGrids.h
===================================================================
--- sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGrids.h	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysGrids.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -43,12 +43,14 @@
     INT32 GetUnitCode(void);
     bool IsSameAs(MgCoordinateSystemGridSpecification* specification);
     double GetCurvePrecision(void);
+    INT32 GetMaxCurvePoints(void);
 
     void SetGridBase(double eastingBase,double northingBase);
     void SetGridIncrement(double eastingIncrement,double northingIncrement);
     void SetTickIncrements(double eastingIncrement,double northingIncrement);
     void SetUnits (INT32 unitCode,INT32 unitType = MgCoordinateSystemUnitType::Linear);
     void SetCurvePrecision (double curvePrecision);
+    void SetMaxCurvePoints (INT32 maxCurvePoints);
 
     // The following function identically to the published version, with the
     // exception that the value returned is always converted to the units
@@ -60,10 +62,15 @@
     double GetTickEastingIncrement (INT32 resultUnitCode);
     double GetTickNorthingIncrement (INT32 resultUnitCode);
 
-    // This ufnction will generate a suitable value if the host application
+    // These functions will generate a suitable value if the host application
     // left the curve precision unspecified.
     double GetCurvePrecision(MgCoordinateSystem* gridCS);
+    double GetCurvePrecision(MgCoordinateSystemGridBoundary* gridBoundary,MgCoordinateSystem* gridCS);
 
+    // This function will generate a suitable value if the host application
+    // left the max curve points unspecified.
+    double GetMaxCurvePoints (MgCoordinateSystemGridBoundary* frameBoundary,MgCoordinateSystem* frameCS);
+
     // The following is used by the CoordinateSystemFactory object to verify
     // that all of the information provided to it is consistent with the
     // requirements of the object.
@@ -83,6 +90,7 @@
     double m_TickNorthingIncrement;
     INT32 m_UnitType;
     INT32 m_UnitCode;
+    INT32 m_MaxCurvePoints;
 };
 
 //=============================================================================
@@ -208,7 +216,7 @@
     ////////////////////////////////////////////////////////////////////////////
     /// \brief
     /// Returns the internal grid boundary, in the form of an MgPolygon object,
-    /// after the boundary hbas been converted using the provided coordinate
+    /// after the boundary has been converted using the provided coordinate
     /// system transform.
     /// \param transform
     /// The transformation used to convert the grid boundary.
@@ -240,8 +248,8 @@
     /// proper clipping of a line string which enters and leaves the grid
     /// boundary more than once.  The algorithm is <b>slow</b> as it is written
     /// to handle arbitrary polygons.  The algoirthm is designed to support
-    /// concave polygons, but this has not bee tested.  Interior rings in the
-    /// internal polygon object are ignored at this time.
+    /// concave polygons, but this has not been tested.  Interior rings in the
+    /// internal polygon object are ignored.
     MgLineStringCollection* ClipLineString (MgLineString* lineString) const;
 
 protected:
@@ -277,6 +285,7 @@
     INT32 GetCount (void);
     MgLineString* GetSegment (INT32 index);
     MgLineStringCollection* GetSegmentCollection (void);
+    INT32 GetMemoryUsage (void);
 
     void SetGridOrientation (INT32 orientation);
     void SetRealValue (double realValue);
@@ -318,6 +327,7 @@
     MgLineStringCollection* GetEastLine (void);
     MgLineStringCollection* GetNorthLine (void);
     MgLineStringCollection* GetWestLine (void);
+    INT32 GetMemoryUsage (void);
 
     void SetRegionBoundary (MgPolygon* boundary);
     void SetSouthLine (MgLineStringCollection* southLine);
@@ -335,7 +345,10 @@
     Ptr<MgLineStringCollection> m_NorthLine;
     Ptr<MgLineStringCollection> m_WestLine;
 
-private:            // Not implemented
+private:
+    INT32 PolygonMemoryUse (MgPolygon* polygon);
+    INT32 LineStringCollectionMemoryUse (MgLineStringCollection* lineCollection);
+    // Not implemented
     CCoordinateSystemGridRegion (void);
     CCoordinateSystemGridRegion (const CCoordinateSystemGridRegion& source);
 };
@@ -361,6 +374,7 @@
     double GetValue (void);
     MgCoordinate* GetPosition (void);
     MgCoordinate* GetDirectionVector (void);
+    INT32 GetMemoryUsage (void);
 
 protected:
     void Dispose (void);
@@ -385,7 +399,7 @@
 class CCoordinateSystemGridLineCollection : public MgCoordinateSystemGridLineCollection
 {
 public:
-    CCoordinateSystemGridLineCollection (void);
+    CCoordinateSystemGridLineCollection (INT32 gridLineExceptionLevel);
     ~CCoordinateSystemGridLineCollection(void);
 
     INT32 GetCount () const;
@@ -397,10 +411,17 @@
     void SetItem (INT32 index,MgCoordinateSystemGridLine* value);
     void Add (MgCoordinateSystemGridLine* value);
     void AddCollection (MgCoordinateSystemGridLineCollection* aGridLineCollection);
+    INT32 SetGridLineExceptionLevel (INT32 memoryUseMax);
+    INT32 GetMemoryUsage (void);
+
 protected:
     void Dispose(void);
+    INT32 m_MemoryUse;
+    INT32 m_GridLineExceptionLevel;
     Ptr<MgDisposableCollection> m_GridLineCollection;
+
 private:
+    // Not Implemented
     CCoordinateSystemGridLineCollection (const CCoordinateSystemGridLineCollection& source);
     CCoordinateSystemGridLineCollection& operator= (const CCoordinateSystemGridLineCollection& rhs);
 };
@@ -411,7 +432,7 @@
 class CCoordinateSystemGridRegionCollection : public MgCoordinateSystemGridRegionCollection
 {
 public:
-    CCoordinateSystemGridRegionCollection (void);
+    CCoordinateSystemGridRegionCollection (INT32 gridRegionExceptionLevel);
     ~CCoordinateSystemGridRegionCollection (void);
 
     INT32 GetCount () const;
@@ -422,11 +443,17 @@
     void SetItem (INT32 index, MgCoordinateSystemGridRegion* value);
     void Add (MgCoordinateSystemGridRegion* value);
     void AddCollection (MgCoordinateSystemGridRegionCollection* aGridRegionCollection);
+    INT32 SetGridRegionExceptionLevel (INT32 memoryUseMax);
+    INT32 GetMemoryUsage (void);
 
 protected:
     void Dispose (void);
+    INT32 m_MemoryUse;
+    INT32 m_GridRegionExceptionLevel;
     Ptr<MgDisposableCollection> m_GridRegionCollection;
+
 private:
+    // Not Implemented
     CCoordinateSystemGridRegionCollection (const CCoordinateSystemGridRegionCollection& source);
     CCoordinateSystemGridRegionCollection& operator= (const CCoordinateSystemGridRegionCollection& rhs);
 };
@@ -439,7 +466,7 @@
 class CCoordinateSystemGridTickCollection : public MgCoordinateSystemGridTickCollection 
 {
 public:
-    CCoordinateSystemGridTickCollection (void);
+    CCoordinateSystemGridTickCollection (INT32 gridLineExceptionLevel);
     ~CCoordinateSystemGridTickCollection (void);
 
     INT32 GetCount () const;
@@ -449,12 +476,17 @@
     void SetItem (INT32 index, MgCoordinateSystemGridTick* value);
     void Add (MgCoordinateSystemGridTick* value);
     void AddCollection (MgCoordinateSystemGridTickCollection* aGridTickCollection);
+    INT32 SetGridTickExceptionLevel (INT32 memoryUseMax);
+    INT32 GetMemoryUsage (void);
 
 protected:
     void Dispose (void);
+    INT32 m_MemoryUse;
+    INT32 m_GridTickExceptionLevel;
     Ptr<MgDisposableCollection> m_GridTickCollection;
 
 private:
+    // Not Implemented
     CCoordinateSystemGridTickCollection (const CCoordinateSystemGridTickCollection& source);
     CCoordinateSystemGridTickCollection& operator= (const CCoordinateSystemGridTickCollection& rhs);  
 };

Modified: sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrs.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrs.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrs.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -27,6 +27,10 @@
 
 using namespace CSLibrary;
 
+const INT32 CCoordinateSystemMgrs::m_GridLineExceptionLevelK   = 40000000L;    // 40MB
+const INT32 CCoordinateSystemMgrs::m_GridRegionExceptionLevelK = 60000000L;    // 60MB
+const INT32 CCoordinateSystemMgrs::m_GridTickExceptionLevelK   = 20000000L;    // 20MB
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
 // Static constants.
 const CCoordinateSystemMgrs::CCoordinateSystemMgrsSeries CCoordinateSystemMgrs::MgrsSeriesNormal [6] =
@@ -65,6 +69,9 @@
                        m_nLetteringScheme(nLetteringScheme),
                        m_bExceptionsOn (bSetExceptionsOn),
                        m_bUseFrameDatum (false),
+                       m_GridLineExceptionLevel   (m_GridLineExceptionLevelK),
+                       m_GridRegionExceptionLevel (m_GridRegionExceptionLevelK),
+                       m_GridTickExceptionLevel   (m_GridTickExceptionLevelK),
                        m_nLastError (0),
                        m_pCsTarget (),
                        m_pCsMgrs (NULL),
@@ -81,6 +88,9 @@
                        m_nLetteringScheme(nLetteringScheme),
                        m_bExceptionsOn (bSetExceptionsOn),
                        m_bUseFrameDatum (false),
+                       m_GridLineExceptionLevel   (m_GridLineExceptionLevelK),
+                       m_GridRegionExceptionLevel (m_GridRegionExceptionLevelK),
+                       m_GridTickExceptionLevel   (m_GridTickExceptionLevelK),
                        m_nLastError (0),
                        m_pCsTarget (),
                        m_pCsMgrs (NULL),
@@ -225,7 +235,7 @@
 
     //if exception mode is on and excetion is thrown internally we exit anyway
     //so safe to return sMgrs here and not test the m_bExceptionsOn value
-    //m_nLastError is already set if a failure occured and m_bExceptionsOn=false
+    //m_nLastError is already set if a failure occurred and m_bExceptionsOn=false
     return sMgrs;
 }
 
@@ -237,15 +247,22 @@
 
     //if exception mode is on and excetion is thrown internally we exit anyway
     //so safe to return sMgrs here and not test the m_bExceptionsOn value
-    //m_nLastError is already set if a failure occured and m_bExceptionsOn=false
+    //m_nLastError is already set if a failure occurred and m_bExceptionsOn=false
     return sMgrs;
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 MgCoordinate* CCoordinateSystemMgrs::ConvertToLonLat(CREFSTRING sMgrs)
 {
+    MgCoordinate* lonLat;
+    lonLat = ConvertToLonLat(sMgrs,MgCoordinateSystemMgrsGridSquarePosition::Center);
+    return lonLat;
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+MgCoordinate* CCoordinateSystemMgrs::ConvertToLonLat(CREFSTRING sMgrs, INT32 grdSqrPosition)
+{
     double dLongitude, dLatitude;
-    INT32 nResult=ConvertToLonLat(sMgrs, dLongitude, dLatitude);
+    INT32 nResult=ConvertToLonLat(sMgrs, dLongitude, dLatitude, grdSqrPosition);
     if (MgCoordinateSystemErrorCode::Ok==nResult)
     {
         MgCoordinate* pLonLat=new MgCoordinateXY(dLongitude, dLatitude);
@@ -269,7 +286,7 @@
 
     //if exception mode is on and excetion is thrown internally we exit anyway
     //so safe to return NULL here and not test the m_bExceptionsOn value
-    //m_nLastError is already set if a failure occured and m_bExceptionsOn=false
+    //m_nLastError is already set if a failure occurred and m_bExceptionsOn=false
     return NULL;
 }
 
@@ -371,10 +388,13 @@
     INT32 index;
     INT32 unitType;
     INT32 zoneCount;
+    INT32 zoneExceptionLevel;
     Ptr<CCoordinateSystemMgrsZone> mgrsZoneGrid;
     Ptr<MgCoordinateSystemGridLineCollection> aGridLineCollection;
     Ptr<CCoordinateSystemGridLineCollection> theGridLineCollection;
 
+    MgCoordinateSystemFactory factory;
+
     if (m_GridBoundary == 0)
     {
         // Proceeding without a grid boundary will cause a crash.
@@ -383,39 +403,46 @@
     }
 
     MG_TRY ()
-        theGridLineCollection = new CCoordinateSystemGridLineCollection ();
+        theGridLineCollection = new CCoordinateSystemGridLineCollection (m_GridLineExceptionLevel);
+
+        // Determine the grid type.
         unitType = specification->GetUnitType();
         specIsGrid = (unitType ==  MgCoordinateSystemUnitType::Linear);
-        if (specIsGrid)
-        {
-            // The specification calls for a grid.
+        
+        // Process each zone in our zone collection.  Originally, we thought
+        // we could just call the GetGridLines function of the OneGrid
+        // base class, but there are just too many special cases to deal with.
+        // So, rather than kludge a bunch of special stuff into OneGrid and
+        // compromise its generality, we have our own functions in this MGRS
+        // specific object which duplicates much of the functionality of the
+        // OneGrid objoect.
             zoneCount = m_ZoneCollection->GetCount ();
             for (index = 0;index < zoneCount;index += 1)
             {
+            zoneExceptionLevel = m_GridLineExceptionLevel - theGridLineCollection->GetMemoryUsage ();
                 mgrsZoneGrid = m_ZoneCollection->GetItem (index);
-                aGridLineCollection = mgrsZoneGrid->GetGridLines (specification);
-                theGridLineCollection->AddCollection (aGridLineCollection);
+            if (specIsGrid)
+            {
+                // The specification calls for a grid.  The following function
+                // is smart enough to deal with the special nature of zones
+                // 31 through 37 at the higher northern latitudes.
+                aGridLineCollection = mgrsZoneGrid->GetGridLines (m_GridBoundary,specification,zoneExceptionLevel);
             }
-        }
         else
         {
-            // The specification calls for a graticule.
-            if (m_GraticuleUtm)
-            {
-                aGridLineCollection = m_GraticuleUtm->GetGridLines (specification);
-                theGridLineCollection->AddCollection (aGridLineCollection);
+                // The specification calls for a graticule  This object is
+                // smart enough to deal with band X (which is 12 degrees high)
+                // and the special nature of zones 31 through 37 at the higher
+                // northern latitudes.
+                aGridLineCollection = mgrsZoneGrid->GetGraticuleLines (m_GridBoundary,specification,zoneExceptionLevel);
             }
-            if (m_GraticuleUpsNorth)
+            if (aGridLineCollection != 0)
             {
-                aGridLineCollection = m_GraticuleUpsNorth->GetGridLines (specification);
+                // Add whatever we got to the collection we are accumulating.
                 theGridLineCollection->AddCollection (aGridLineCollection);
+                aGridLineCollection = 0;
             }
-            if (m_GraticuleUpsSouth)
-            {
-                aGridLineCollection = m_GraticuleUpsSouth->GetGridLines (specification);
-                theGridLineCollection->AddCollection (aGridLineCollection);
             }
-        }
     MG_CATCH_AND_THROW(L"MgCoordinateSystemMgrs::GetGridLines")
     return static_cast<MgCoordinateSystemGridLineCollection*>(theGridLineCollection.Detach());
 }
@@ -424,6 +451,7 @@
 {
     INT32 index;
     INT32 zoneCount;
+    INT32 zoneExceptionLevel;
     Ptr<CCoordinateSystemMgrsZone> mgrsZoneGrid;
     Ptr<CCoordinateSystemGridRegionCollection> theGridRegionCollection;
 
@@ -435,13 +463,14 @@
     }
 
     MG_TRY ()
-        theGridRegionCollection = new CCoordinateSystemGridRegionCollection ();
+        theGridRegionCollection = new CCoordinateSystemGridRegionCollection (m_GridRegionExceptionLevel);
         zoneCount = m_ZoneCollection->GetCount ();
         for (index = 0;index < zoneCount;index += 1)
         {
+            zoneExceptionLevel = m_GridRegionExceptionLevel - theGridRegionCollection->GetMemoryUsage ();
             mgrsZoneGrid = m_ZoneCollection->GetItem (index);
             Ptr<MgCoordinateSystemGridRegionCollection> aGridRegionCollection;
-            aGridRegionCollection = mgrsZoneGrid->GetGridRegions (m_GridBoundary,specification);
+            aGridRegionCollection = mgrsZoneGrid->GetGridRegions (m_GridBoundary,specification,zoneExceptionLevel);
             theGridRegionCollection->AddCollection (aGridRegionCollection);
         }
     MG_CATCH_AND_THROW(L"MgCoordinateSystemMgrs::GetGridRegions")
@@ -467,7 +496,7 @@
     }
 
     MG_TRY ()
-        theGridTickCollection = new CCoordinateSystemGridTickCollection ();
+        theGridTickCollection = new CCoordinateSystemGridTickCollection (m_GridTickExceptionLevel);
         unitType = specification->GetUnitType();
         specIsGrid = (unitType ==  MgCoordinateSystemUnitType::Linear);
         if (specIsGrid)
@@ -516,6 +545,100 @@
     return 1.0;
 }
 
+INT32 CCoordinateSystemMgrs::ApproxGridLineMemoryUsage (MgCoordinateSystemGridSpecification* specification)
+{
+    INT32 index;
+    INT32 zoneCount;
+    INT32 memoryGuess (-1);
+
+    if (m_GridBoundary != 0)
+    {
+        memoryGuess = 0;
+        zoneCount = m_ZoneCollection->GetCount ();
+        for (index = 0;index < zoneCount;index += 1)
+        {
+            Ptr<CCoordinateSystemMgrsZone> mgrsZoneGrid = m_ZoneCollection->GetItem (index);
+            memoryGuess += mgrsZoneGrid->ApproxGridLineMemoryUsage (specification);
+        }
+    }
+    return memoryGuess;
+}
+INT32 CCoordinateSystemMgrs::ApproxGridRegionMemoryUsage (MgCoordinateSystemGridSpecification* specification)
+{
+    INT32 index;
+    INT32 zoneCount;
+    INT32 memoryUse;
+    INT32 maxValue;
+    INT32 memoryGuess (-1);
+
+    if (m_GridBoundary != 0)
+    {
+        memoryGuess = 0;
+        zoneCount = m_ZoneCollection->GetCount ();
+        for (index = 0;index < zoneCount;index += 1)
+        {
+            Ptr<CCoordinateSystemMgrsZone> mgrsZoneGrid = m_ZoneCollection->GetItem (index);
+            memoryUse = mgrsZoneGrid->ApproxGridRegionMemoryUsage (specification);
+            maxValue = 0x7FFF0000 - memoryGuess;
+            if (memoryUse < maxValue)
+            {
+                memoryGuess += memoryUse;
+            }
+            else
+            {
+                memoryGuess = 0x7FFFFFFF;
+                break;
+            }
+        }
+    }
+    return memoryGuess;
+}
+INT32 CCoordinateSystemMgrs::ApproxGridTickMemoryUsage (MgCoordinateSystemGridSpecification* specification)
+{
+    INT32 index;
+    INT32 zoneCount;
+    INT32 memoryGuess (-1);
+
+    if (m_GridBoundary != 0)
+    {
+        memoryGuess = 0;
+        zoneCount = m_ZoneCollection->GetCount ();
+        for (index = 0;index < zoneCount;index += 1)
+        {
+            Ptr<CCoordinateSystemMgrsZone> mgrsZoneGrid = m_ZoneCollection->GetItem (index);
+            memoryGuess += mgrsZoneGrid->ApproxGridTickMemoryUsage (specification);
+        }
+    }
+    return memoryGuess;
+}
+INT32 CCoordinateSystemMgrs::SetGridLineExceptionLevel (INT32 memoryUseMax)
+{
+    INT32 rtnValue = m_GridLineExceptionLevel;
+    if (memoryUseMax > 0L)
+    {
+        m_GridLineExceptionLevel = memoryUseMax;
+    }
+    return rtnValue;
+}
+INT32 CCoordinateSystemMgrs::SetGridRegionExceptionLevel (INT32 memoryUseMax)
+{
+    INT32 rtnValue = m_GridRegionExceptionLevel;
+    if (memoryUseMax > 0L)
+    {
+        m_GridRegionExceptionLevel = memoryUseMax;
+    }
+    return rtnValue;
+}
+INT32 CCoordinateSystemMgrs::SetGridTickExceptionLevel (INT32 memoryUseMax)
+{
+    INT32 rtnValue = m_GridTickExceptionLevel;
+    if (memoryUseMax > 0L)
+    {
+        m_GridTickExceptionLevel = memoryUseMax;
+    }
+    return rtnValue;
+}
+
 //INTERNAL_API
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 INT32 CCoordinateSystemMgrs::ConvertFromLonLat(double dLongitude, double dLatitude, INT32 nPrecision, REFSTRING sMgrs)
@@ -596,10 +719,16 @@
     //no need to check the dimension of the MgCoordinate as we only care about X and Y
     return ConvertFromLonLat(pLonLat->GetX(), pLonLat->GetY(), nPrecision, sMgrs);
 }
-
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 INT32 CCoordinateSystemMgrs::ConvertToLonLat(CREFSTRING sMgrs, MgCoordinate* pLonLat)
 {
+    INT32 nResult;
+    nResult = ConvertToLonLat(sMgrs,pLonLat,MgCoordinateSystemMgrsGridSquarePosition::Center);
+    return nResult;
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+INT32 CCoordinateSystemMgrs::ConvertToLonLat(CREFSTRING sMgrs, MgCoordinate* pLonLat, INT32 grdSqrPosition)
+{
     if (!pLonLat)
     {
         if (m_bExceptionsOn)
@@ -616,7 +745,7 @@
     //no need to check the dimension of the MgCoordinate as we only care about X and Y
     double dLongitude=pLonLat->GetX();
     double dLatitude=pLonLat->GetY();
-    INT32 nResult=ConvertToLonLat(sMgrs, dLongitude, dLatitude);
+    INT32 nResult=ConvertToLonLat(sMgrs, dLongitude, dLatitude, grdSqrPosition);
     if (nResult==MgCoordinateSystemErrorCode::Ok)
     {
         pLonLat->SetX(dLongitude);
@@ -624,10 +753,16 @@
     }
     return nResult;
 }
-
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 INT32 CCoordinateSystemMgrs::ConvertToLonLat(CREFSTRING sMgrs, double& dLongitude, double& dLatitude)
 {
+    INT32 nResult;
+    nResult = ConvertToLonLat(sMgrs,dLongitude,dLatitude,MgCoordinateSystemMgrsGridSquarePosition::Center);
+    return nResult;
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+INT32 CCoordinateSystemMgrs::ConvertToLonLat(CREFSTRING sMgrs, double& dLongitude, double& dLatitude, INT32 grdSqrPosition)
+{
     if (!m_pCsMgrs)
     {
         if (m_bExceptionsOn)
@@ -641,6 +776,20 @@
         }
     }
 
+    if (grdSqrPosition <= MgCoordinateSystemMgrsGridSquarePosition::None ||
+        grdSqrPosition >= MgCoordinateSystemMgrsGridSquarePosition::Unknown)
+    {
+        if (m_bExceptionsOn)
+        {
+            throw new MgInvalidArgumentException(L"MgCoordinateSystemMgrs.ConvertToLonLat", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        else
+        {
+            m_nLastError=MgCoordinateSystemErrorCode::InvalidArgument;
+            return m_nLastError;
+        }
+    }
+
     //Convert to a char*
     char *pMgrs = Convert_Wide_To_Ascii(sMgrs.c_str()); //need to delete[] pStr
     if (NULL == pMgrs)
@@ -657,7 +806,7 @@
     }
 
     double latLng [2];
-    int nResult=CScalcLlFromMgrs (m_pCsMgrs, latLng, pMgrs);
+    int nResult=CScalcLlFromMgrsEx (m_pCsMgrs, latLng, pMgrs, grdSqrPosition);
 
     //Free the converted string
     delete [] pMgrs;
@@ -706,6 +855,9 @@
                                                                                   MgCoordinateSystem* frameCRS,
                                                                                   bool useFrameDatum)
 {
+    bool northPole (false);
+    bool southPole (false);
+
     INT32 zoneNbr;
     INT32 zoneMin;
     INT32 zoneMax;
@@ -713,8 +865,10 @@
 
     double cm;                      // central meridian
     double eastLimit, westLimit;    // limits of a UTM zone
-    double eastMin, eastMax;        // frame boundary extrema in 'LL84' (or 'LL')
-    double northMin, northMax;      // frame boundary extrema in 'LL84' (or 'LL')
+    double lngMin, lngMax;          // frame boundary extrema in 'LL84' (or 'LL')
+    double latMin, latMax;          // frame boundary extrema in 'LL84' (or 'LL')
+    double eastMin, eastMax;        // frame boundary extrema in frame CRS
+    double northMin, northMax;      // frame boundary extrema in frame CRS
 
     Ptr<MgPolygon> pPolygon;
     Ptr<MgPolygon> pPolygonIntersection;
@@ -758,26 +912,99 @@
         m_GraticuleUpsNorth = 0;
         m_GraticuleUpsSouth = 0;
 
+        // Get the min/max of the frame in frame coordinates.
+        frameBoundary->GetBoundaryExtents (eastMin,eastMax,northMin,northMax);
+
         // Convert the polygon portion of the Grid Boundary object to long/lat
         // coordinates and extract the min/max from the resulting polygon.
         llCRS = csFactory->CreateFromCode (useFrameDatum ? L"LL" : L"LL84");
         toLlTransform = csFactory->GetTransform(frameCRS,llCRS);
+        toLlTransform->IgnoreDatumShiftWarning (true);
+        toLlTransform->IgnoreOutsideDomainWarning (true);
         toFrameTransform = csFactory->GetTransform(llCRS,frameCRS);
+        toFrameTransform->IgnoreDatumShiftWarning (true);
+        toFrameTransform->IgnoreOutsideDomainWarning (true);
         pPolygon = frameBoundary->GetBoundary (toLlTransform,1.0E-05);
         llBoundary = csFactory->GridBoundary (pPolygon);
-        llBoundary->GetBoundaryExtents (eastMin,eastMax,northMin,northMax);
+        llBoundary->GetBoundaryExtents (lngMin,lngMax,latMin,latMax);
 
+        // The llBoundary object has been created using rectangular techniques.
+        // Since the earth is spherical, in certain rare cases the resulting
+        // extents can exclude either (or both, presumably) pole when inclusion
+        // is appropriate.  We try to deal with that issue here.  We use this
+        // technique only for projections which we believe can properly
+        // represent a pole for defensive purposes.
+
+        if (CanDoPoles (frameCRS))
+        {
+            // Use the toFrameXform object to convert the north pole to the frame
+            // coordinate system.  If the conversion is successful, and the result
+            // resides within the original cartesian frame boundary, we add the
+            // north pole to the extents generated by the GetBoundaryExtents
+            // function call.
+            if (latMax > 0.0)
+            {
+                Ptr<MgCoordinate> poleTest = new MgCoordinateXY (0.0,90.0);
+                poleTest = toFrameTransform->Transform (poleTest);
+                if (poleTest->GetX () >= eastMin  && poleTest->GetX () <= eastMax &&
+                    poleTest->GetY () >= northMin && poleTest->GetY () <= northMax)
+                {
+                    northPole = true;
+                }
+            }
+            if (latMin < 0.0)
+            {
+                Ptr<MgCoordinate> poleTest = new MgCoordinateXY (0.0,-90.0);
+                poleTest = toFrameTransform->Transform (poleTest);
+                if (poleTest->GetX () >= eastMin  && poleTest->GetX () <= eastMax &&
+                    poleTest->GetY () >= northMin && poleTest->GetY () <= northMax)
+                {
+                    southPole = true;
+                }
+            }
+        }
+
         // Use the latitude min/max to extract the UTM/UPS zones as necessary.
-        if (northMin < -80.0)
+        if (latMin < -80.0 || southPole)
         {
             // There is a portion of the frame boundary in the south polar region.
             zoneNbr = -61;
-            pSouthwest->SetX (eastMin);
-            pSouthwest->SetY (northMin);
-            pNortheast->SetX (eastMax);
+
+            pPolygon = 0;
+            if (southPole)
+            {
+                // The south pole is included within the provided frame boundary.
+                // In this case, the rectangular technique used above would
+                // produce a closed polygon which will look like a circular pie
+                // with an infitessiammly smal slice in it.  This slice drives
+                // the clipper crazy.  So, we need to develop a simple
+                // circular closed boundary around, but not including the
+                // pole.
+
+                // Since we need to do the same thing for the northern pole as
+                // well, we have a function that will do that for us.  THis
+                // function will fail if the underlying frame CRS is not
+                // suitable for polar aspects.
+                pPolygon = ParallelPolygon (toFrameTransform,-80.0,720);
+            }
+            if (!pPolygon)
+            {
+                // The south pole is not within the frame boundary, the
+                // generation of a circular boundary representing a parallel
+                // failed, or the frame CRS is incapabale of representing
+                // the pole.  Therefore, we have to use the standard rectangular
+                // boundary technique and hope for the best.  This should work
+                // fine if the region does not actually include the pole, and
+                // the results should be decent in other cases.
+                pSouthwest->SetX (lngMin);
+                pSouthwest->SetY (latMin);
+                pNortheast->SetX (lngMax);
             pNortheast->SetY (-80.0);
             llBoundary = csFactory->GridBoundary (pSouthwest,pNortheast);
             pPolygon = llBoundary->GetBoundary (toFrameTransform,1.0);
+            }
+            if (pPolygon)
+            {
             Ptr<MgPolygon> pPolygonTemp = frameBoundary->GetBoundary ();
             pPolygonIntersection = dynamic_cast<MgPolygon*>(pPolygon->Intersection (pPolygonTemp));
             if (pPolygonIntersection != 0)
@@ -790,16 +1017,29 @@
             m_GraticuleUpsSouth = new CCoordinateSystemOneGrid (reducedFrameBoundary,llCRS,frameCRS);
         }
         }
-        if (northMax > 84.0)
+        }
+        if (latMax > 84.0 || northPole)
         {
             // There is a portion of the frame boundary in the north polar region.
             zoneNbr = 61;
-            pSouthwest->SetX (eastMin);
+
+            // Same as for the south pole, sans the laborious comments.
+            pPolygon = 0;
+            if (northPole)
+            {
+                pPolygon = ParallelPolygon (toFrameTransform,84.0,720);
+            }
+            if (pPolygon == 0)
+            {
+                pSouthwest->SetX (lngMin);
             pSouthwest->SetY (84.0);
-            pNortheast->SetX (eastMax);
-            pNortheast->SetY (northMax);
+                pNortheast->SetX (lngMax);
+                pNortheast->SetY (latMax);
             llBoundary = csFactory->GridBoundary (pSouthwest,pNortheast);
             pPolygon = llBoundary->GetBoundary (toFrameTransform,1.0);
+            }
+            if (pPolygon != 0)
+            {
             Ptr<MgPolygon> pPolygonTemp = frameBoundary->GetBoundary ();
             pPolygonIntersection = dynamic_cast<MgPolygon*>(pPolygon->Intersection (pPolygonTemp));
             if (pPolygonIntersection != 0)
@@ -812,17 +1052,18 @@
             m_GraticuleUpsNorth = new CCoordinateSystemOneGrid (reducedFrameBoundary,llCRS,frameCRS);
         }
         }
-        if (northMax > -80.0 && northMin < 84.0)
+        }
+        if (latMax > -80.0 && latMin < 84.0)
         {
             // A portion of the frame boundary is in the region covered by the
             // normal (i.e. non-polar) UTM zones.  Determine the particular UTM
             // zones we need to generate.
-            tmpInt32 = static_cast <INT32>(floor (eastMin));
+            tmpInt32 = static_cast <INT32>(floor (lngMin));
             zoneMin = ((tmpInt32 + 180) / 6) + 1;
-            tmpInt32 = static_cast <INT32>(ceil (eastMax));
+            tmpInt32 = static_cast <INT32>(ceil (lngMax));
             zoneMax = ((tmpInt32 + 180) / 6) + 1;
 
-            if (northMax > 0.0)
+            if (latMax > 0.0)
             {
                 // There are some northern zones.
 
@@ -831,8 +1072,8 @@
                 // provided frame boundary.  The north/south portions
                 // are the same for each zone, so we do that once here outside
                 // the loop.
-                pSouthwest->SetY ((northMin <  0.0) ?  0.0 : northMin);
-                pNortheast->SetY ((northMax > 84.0) ? 84.0 : northMax);
+                pSouthwest->SetY ((latMin <  0.0) ?  0.0 : latMin);
+                pNortheast->SetY ((latMax > 84.0) ? 84.0 : latMax);
 
                 // OK, generate a CCoordinateSystemMgrsZone object for each
                 // UTM zone which intersects the frame boundary provided.
@@ -848,8 +1089,8 @@
                     eastLimit = cm + 3.0;
 
                     // 2> Apply the extents of the provided frame boundary.
-                    if (westLimit < eastMin) westLimit = eastMin;
-                    if (eastLimit > eastMax) eastLimit = eastMax;
+                    if (westLimit < lngMin) westLimit = lngMin;
+                    if (eastLimit > lngMax) eastLimit = lngMax;
 
                     // 3> Create, in terms of LL coordinates, the frame
                     //    boundary as is appropriate for this particular zone.
@@ -870,19 +1111,19 @@
                  }
             }
             }
-            if (northMin < 0.0)
+            if (latMin < 0.0)
             {
                 // Pretty much the same as the northern zones processed
                 // above, but without the laborious comments.
-                pSouthwest->SetY ((northMin < -80.0) ? -80.0 : northMin);
-                pNortheast->SetY ((northMax >   0.0) ?   0.0 : northMax);
+                pSouthwest->SetY ((latMin < -80.0) ? -80.0 : latMin);
+                pNortheast->SetY ((latMax >   0.0) ?   0.0 : latMax);
                 for (zoneNbr = zoneMin;zoneNbr <= zoneMax;zoneNbr += 1)
                 {
                     cm = static_cast<double>((zoneNbr * 6) - 183);
                     westLimit = cm - 3.0;
                     eastLimit = cm + 3.0;
-                    if (westLimit < eastMin) westLimit = eastMin;
-                    if (eastLimit > eastMax) eastLimit = eastMax;
+                    if (westLimit < lngMin) westLimit = lngMin;
+                    if (eastLimit > lngMax) eastLimit = lngMax;
                     pSouthwest->SetX (westLimit);
                     pNortheast->SetX (eastLimit);
 
@@ -901,10 +1142,10 @@
 
             // Need a CCoordinateSystemOneGrid object which can produce the 6 x 8 graticule
             // for the entire regon.
-            pSouthwest->SetX (eastMin);
-            pNortheast->SetX (eastMax);
-            pSouthwest->SetY ((northMin < -80.0) ? -80.0 : northMin);
-            pNortheast->SetY ((northMax >  84.0) ?  84.0 : northMax);
+            pSouthwest->SetX (lngMin);
+            pNortheast->SetX (lngMax);
+            pSouthwest->SetY ((latMin < -80.0) ? -80.0 : latMin);
+            pNortheast->SetY ((latMax >  84.0) ?  84.0 : latMax);
             llBoundary = csFactory->GridBoundary (pSouthwest,pNortheast);
             pPolygon = llBoundary->GetBoundary (toFrameTransform,1.0);
             Ptr<MgPolygon> pPolygonTemp = frameBoundary->GetBoundary ();
@@ -930,12 +1171,14 @@
     squareDesignation [0] = L'?';
     squareDesignation [1] = L'?';
     squareDesignation [2] = L'\0';
+    squareDesignation [3] = L'\0';
 
+    iEasting  = static_cast<INT32>(easting);
+    iNorthing = static_cast<INT32>(northing);
+
     // For now we assume there is no difference between the northern and southern hemisphere.
     if (utmZoneNbr != 0 && abs(utmZoneNbr) <= 60)
     {
-        iEasting  = static_cast<INT32>(easting);
-        iNorthing = static_cast<INT32>(northing);
         if (iEasting < 100000) iEasting = 100000;
         if (iEasting > 1000000) iEasting = 1000000;
         if (iNorthing < 0) iNorthing = 0;
@@ -946,7 +1189,6 @@
         northIndex = static_cast<INT32>(iNorthing) / 100000;
         if (eastIndex < 9 && northIndex < 21)
         {
-//          seriesIndex = abs (utmZoneNbr) % 6 - 1;                 //BOGUS:: This does not work!!!!!
             seriesIndex = (abs (utmZoneNbr) - 1) % 6;
             if (letteringScheme == MgCoordinateSystemMgrsLetteringScheme::Alternative)
             {
@@ -960,6 +1202,31 @@
             }
         }
     }
+    else if (utmZoneNbr == 61)
+    {
+        // North UPS region
+        eastIndex = (iEasting / 100000) - 13;
+        northIndex = (iNorthing / 100000) - 13;
+        if (eastIndex >= 0  && eastIndex  <= 13 &&
+            northIndex >= 0 && northIndex <= 13)
+        {
+            squareDesignation [0] = MgrsSeriesPolarNorth [0][eastIndex];
+            squareDesignation [1] = MgrsSeriesPolarNorth [1][northIndex];
+        }
+    }
+    else if (utmZoneNbr == -61)
+    {
+        // South UPS region
+        eastIndex = (iEasting / 100000) - 8;
+        northIndex = (iNorthing / 100000) - 8;
+        if (eastIndex >= 0  && eastIndex  <= 19 &&
+            northIndex >= 0 && northIndex <= 19)
+        {
+            squareDesignation [0] = MgrsSeriesPolarSouth [0][eastIndex];
+            squareDesignation [1] = MgrsSeriesPolarSouth [1][northIndex];
+        }
+    }
+
     STRING designation (squareDesignation);
     return designation;
 }
@@ -1034,4 +1301,114 @@
     }
     return designationLetter;
 }
+
+// TODO:  This function probably should be a member of some other object, as
+// its product is of value outside the realm of MGRS.
+MgPolygon* CCoordinateSystemMgrs::ParallelPolygon (MgCoordinateSystemTransform* transformation,double latitude,
+                                                                                               INT32 pointCount)
+{
+    bool ok (true);
+    INT32 index;
+    INT32 status;
+
+    double deltaLng;
+    double currentLng;
+
+    Ptr<MgCoordinate> llPoint;
+    Ptr<MgCoordinate> xyPoint;
+    Ptr<MgCoordinate> firstPoint;
+    Ptr<MgCoordinateCollection> xyCollection;
+    Ptr<MgLinearRing> linearRing;
+    Ptr<MgPolygon> polyPtr;
+    MgPolygon* result;
+
+    result = 0;
+    if (pointCount < 3 || pointCount > 2048)
+    {
+        pointCount = 720;
+    }
+    deltaLng = 360.0 / static_cast<double>(pointCount);
+
+    currentLng = -180.0;
+    xyCollection = new MgCoordinateCollection ();
+    llPoint = new MgCoordinateXY (currentLng,latitude);
+    for (index = 0;ok && (index < pointCount);index += 1)
+    {
+        llPoint->SetX (currentLng);
+        xyPoint = transformation->Transform (llPoint);
+        status = transformation->GetLastTransformStatus ();
+        ok = status == MgCoordinateSystemTransform::TransformOk;
+        if (ok)
+        {
+            xyCollection->Add (xyPoint);
+            if (index == 0)
+            {
+                firstPoint = SAFE_ADDREF (xyPoint.p);
+            }
+        }
+        currentLng += deltaLng;
+    }
+
+    if (ok)
+    {
+        // Close the linear ring for sure.
+        xyCollection->Add (firstPoint);
+
+        linearRing = new MgLinearRing (xyCollection);
+        polyPtr = new MgPolygon (linearRing,0);
+        result = polyPtr.Detach ();
+    }
+    return result;
+}
+bool CCoordinateSystemMgrs::CanDoPoles (MgCoordinateSystem* frameCRS)
+{
+    // MENTOR_MAINTENANCE --> a new projection may need to be added to this list.
+    static INT32 polarCapable [] =
+    {
+        MgCoordinateSystemProjectionCode::Tm,
+        MgCoordinateSystemProjectionCode::Trmrs,
+        MgCoordinateSystemProjectionCode::Trmeraf,
+        MgCoordinateSystemProjectionCode::Sotrm,
+        MgCoordinateSystemProjectionCode::Alber,
+        MgCoordinateSystemProjectionCode::Azede,
+        MgCoordinateSystemProjectionCode::Azmea,
+        MgCoordinateSystemProjectionCode::Azmed,
+        MgCoordinateSystemProjectionCode::Cassini,
+        MgCoordinateSystemProjectionCode::Edcnc,
+        MgCoordinateSystemProjectionCode::GaussK,
+        MgCoordinateSystemProjectionCode::Hom1uv,
+        MgCoordinateSystemProjectionCode::Hom2uv,
+        MgCoordinateSystemProjectionCode::Hom1xy,
+        MgCoordinateSystemProjectionCode::Hom2xy,
+        MgCoordinateSystemProjectionCode::Krovak,
+        MgCoordinateSystemProjectionCode::Rskew,
+        MgCoordinateSystemProjectionCode::Rskewc,
+        MgCoordinateSystemProjectionCode::Rskewo,
+        MgCoordinateSystemProjectionCode::Lm1sp,
+        MgCoordinateSystemProjectionCode::Lm2sp,
+        MgCoordinateSystemProjectionCode::Lmblg,
+        MgCoordinateSystemProjectionCode::Lmbrtaf,
+        MgCoordinateSystemProjectionCode::Lmtan,
+        MgCoordinateSystemProjectionCode::Mstero,
+        MgCoordinateSystemProjectionCode::Obqcyl,
+        MgCoordinateSystemProjectionCode::Plycn,
+        MgCoordinateSystemProjectionCode::Pstro,
+        MgCoordinateSystemProjectionCode::Pstrosl,
+        MgCoordinateSystemProjectionCode::Unknown
+    };
+
+    bool canDoPoles (false);
+    INT32 index;
+    
+    INT32 prjCode = frameCRS->GetProjectionCode ();
+    for (index = 0;polarCapable [index] != MgCoordinateSystemProjectionCode::Unknown;index += 1)
+    {
+        if (prjCode == polarCapable [index])
+        {
+            canDoPoles = true;
+            break;
+        }
+    }
+    return canDoPoles;
+}
 //End of file.

Modified: sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrs.h
===================================================================
--- sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrs.h	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrs.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -29,6 +29,10 @@
 	wchar_t northing [21];
     };
 
+    static const INT32 m_GridLineExceptionLevelK;
+    static const INT32 m_GridRegionExceptionLevelK;
+    static const INT32 m_GridTickExceptionLevelK;
+
 public:
     // Static Constants, Variables (hopefully not), and Functions.
     static const CCoordinateSystemMgrsSeries MgrsSeriesNormal [6];
@@ -66,6 +70,7 @@
     STRING ConvertFromLonLat(double dLongitude, double dLatitude, INT32 nPrecision);
     STRING ConvertFromLonLat(MgCoordinate* pLonLat, INT32 nPrecision);
     MgCoordinate* ConvertToLonLat(CREFSTRING sMgrs);
+    MgCoordinate* ConvertToLonLat(CREFSTRING sMgrs, INT32 grdSqrPosition);
     INT8 GetLetteringScheme();
 
     INT32 GetSpecializationType ();
@@ -78,6 +83,14 @@
     double GetConvergenceAngle (MgCoordinate* location);
     double GetProjectiveGridScale (MgCoordinate* location);
 
+    INT32 ApproxGridLineMemoryUsage (MgCoordinateSystemGridSpecification* specification);
+    INT32 ApproxGridRegionMemoryUsage (MgCoordinateSystemGridSpecification* specification);
+    INT32 ApproxGridTickMemoryUsage (MgCoordinateSystemGridSpecification* specification);
+
+    INT32 SetGridLineExceptionLevel (INT32 memoryUseMax);
+    INT32 SetGridRegionExceptionLevel (INT32 memoryUseMax);
+    INT32 SetGridTickExceptionLevel (INT32 memoryUseMax);
+
     INT32 GetLastError();
     void ResetLastError();
     bool AreExceptionsOn();
@@ -88,6 +101,8 @@
     INT32 ConvertFromLonLat(MgCoordinate* pLonLat, INT32 nPrecision, REFSTRING sMgrs);
     INT32 ConvertToLonLat(CREFSTRING sMgrs, MgCoordinate* pLonLat);
     INT32 ConvertToLonLat(CREFSTRING sMgrs, double& dLongitude, double& dLatitude);
+    INT32 ConvertToLonLat(CREFSTRING sMgrs, MgCoordinate* pLonLat, INT32 grdSqrPosition);
+    INT32 ConvertToLonLat(CREFSTRING sMgrs, double& dLongitude, double& dLatitude, INT32 grdSqrPosition);
 
 protected:          // Still INTERNAL API only.
     // Given a frame/viewport boundary, and the coordinate system thereof,
@@ -104,11 +119,17 @@
 
 private:
     short GetBesselFromLetteringScheme(INT8 nLetteringScheme);
+    MgPolygon* ParallelPolygon (MgCoordinateSystemTransform* transformation,double latitude,
+                                                                            INT32 pointCount);
+    bool CanDoPoles (MgCoordinateSystem* frameCRS);
 
 protected:
     INT8 m_nLetteringScheme;
     bool m_bExceptionsOn;
     bool m_bUseFrameDatum;
+    INT32 m_GridLineExceptionLevel;
+    INT32 m_GridRegionExceptionLevel;
+    INT32 m_GridTickExceptionLevel;
     INT32 m_nLastError;
     Ptr<MgCoordinateSystem> m_pCsTarget;
     struct cs_Mgrs_* m_pCsMgrs;

Copied: sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsMajorRegion.cpp (from rev 4398, trunk/MgDev/Common/CoordinateSystem/CoordSysMgrsMajorRegion.cpp)
===================================================================
--- sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsMajorRegion.cpp	                        (rev 0)
+++ sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsMajorRegion.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -0,0 +1,307 @@
+//
+//  Copyright (C) 2004-2009 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#include "GeometryCommon.h"
+#include "CoordSysCommon.h"
+#include "CoordSysUtil.h"
+#include "CriticalSection.h"
+
+#include "CoordSys.h"
+#include "CoordSysGrids.h"
+#include "CoordSysOneGrid.h"
+#include "CoordSysMgrsZone.h"
+#include "CoordSysMgrs.h"
+#include "CoordSysMgrsMajorRegion.h"
+
+using namespace CSLibrary;
+
+//=============================================================================
+// CCoordinateSystemMgrsMajorRegion
+CCoordinateSystemMgrsMajorRegion::CCoordinateSystemMgrsMajorRegion (INT32 utmZoneNbr,INT32 bandIndex)
+                                                                        :
+                                                                    m_IsValid         (false),
+                                                                    m_Designation     (),
+                                                                    m_UtmZoneNbr      (utmZoneNbr),
+                                                                    m_MgrsBandIndex   (bandIndex),
+                                                                    m_CentralMeridian (),
+                                                                    m_WestLng         (),
+                                                                    m_SouthLat        (),
+                                                                    m_EastLng         (),
+                                                                    m_NorthLat        ()
+{
+    INT32 zoneNbr;
+    wchar_t gridZoneLetter;
+    wchar_t wcBufr [128];
+
+    // This constructor should not be used for the polar regions.
+    zoneNbr = abs (m_UtmZoneNbr);
+    if ((zoneNbr > 0) && (zoneNbr <= 60) && (bandIndex >= 2) && (bandIndex < 22))
+    {
+        m_IsValid = true;
+
+        // Do the normal thing which is all we need to do 90% of the time.
+        zoneNbr = abs (m_UtmZoneNbr);
+        m_CentralMeridian = static_cast<double>(-183 + (zoneNbr * 6));
+        m_WestLng = m_CentralMeridian - 3.0;
+        m_EastLng = m_CentralMeridian + 3.0;
+
+        gridZoneLetter = CCoordinateSystemMgrs::GridZoneDesignationLetter (bandIndex);
+        swprintf (wcBufr,128,L"%d%c",zoneNbr,gridZoneLetter);
+        STRING designation (wcBufr);
+        m_Designation = designation;
+
+        // -2 gets us past the 'A' and 'B' for the south polar region.
+        m_SouthLat = static_cast<double>(-80 + ((bandIndex - 2) * 8));
+        m_NorthLat = m_SouthLat + 8.0;
+
+        if (bandIndex == 21)
+        {
+            m_NorthLat = m_SouthLat + 12.0;
+            if (m_UtmZoneNbr == 32 || m_UtmZoneNbr == 34 || m_UtmZoneNbr == 36)
+            {
+                m_IsValid = false;
+            }
+            else
+            {
+                // There are two zones which are 9 degrees wide, and two that are
+                // 12 degrees wide in this band.
+                if (m_UtmZoneNbr == 31)
+                {
+                    m_WestLng = m_CentralMeridian - 3.0;
+                    m_EastLng = m_CentralMeridian + 6.0;
+                }
+                else if (m_UtmZoneNbr == 33 || m_UtmZoneNbr == 35)
+                {
+                    m_WestLng = m_CentralMeridian - 6.0;
+                    m_EastLng = m_CentralMeridian + 6.0;
+                }
+                else if (m_UtmZoneNbr == 37)
+                {
+                    m_WestLng = m_CentralMeridian - 6.0;
+                    m_EastLng = m_CentralMeridian + 3.0;
+                }
+            }
+        }
+        else if (bandIndex == 19)
+        {        
+            if (m_UtmZoneNbr == 31)
+            {
+                m_WestLng = m_CentralMeridian - 3.0;
+                m_EastLng = m_CentralMeridian;
+            }
+            else if (m_UtmZoneNbr == 32)
+            {
+                m_WestLng = m_CentralMeridian - 6.0;
+                m_EastLng = m_CentralMeridian + 3.0;
+            }
+        }
+    }
+}
+// The following constructor is for polar regions.
+//CCoordinateSystemMgrsMajorRegion (INT32 utmZoneNbr,double centralMeridian,INT32 latIndex);
+CCoordinateSystemMgrsMajorRegion::~CCoordinateSystemMgrsMajorRegion (void)
+{
+}
+bool CCoordinateSystemMgrsMajorRegion::IsValid (void)
+{
+    return m_IsValid;
+}
+STRING CCoordinateSystemMgrsMajorRegion::GetDesignation (void)
+{
+    return m_Designation;
+}
+INT32 CCoordinateSystemMgrsMajorRegion::GetUtmZoneNbr (void)
+{
+    return m_UtmZoneNbr;
+}
+INT32 CCoordinateSystemMgrsMajorRegion::GetMgrsBandINdex (void)
+{
+    return m_MgrsBandIndex;
+}
+double CCoordinateSystemMgrsMajorRegion::GetCentralMeridian (void)
+{
+    return m_CentralMeridian;
+}
+double CCoordinateSystemMgrsMajorRegion::GetWestEdgeLng (void)
+{
+    return m_WestLng;
+}
+double CCoordinateSystemMgrsMajorRegion::GetSouthEdgeLat (void)
+{
+    return m_SouthLat;
+}
+double CCoordinateSystemMgrsMajorRegion::GetEastEdgeLng (void)
+{
+    return m_EastLng;
+}
+double CCoordinateSystemMgrsMajorRegion::GetNorthEdgeLat (void)
+{
+    return m_NorthLat;
+}
+void CCoordinateSystemMgrsMajorRegion::Dispose (void)
+{
+    delete this;
+}
+///////////////////////////////////////////////////////////////////////////////
+CCoordinateSystemMgrsMajorRegionCollection::CCoordinateSystemMgrsMajorRegionCollection (void)
+                                                    :
+                                                 MgGuardDisposable       (),
+                                                 m_MajorRegionCollection ()
+{
+    m_MajorRegionCollection = new MgDisposableCollection();
+}
+CCoordinateSystemMgrsMajorRegionCollection::CCoordinateSystemMgrsMajorRegionCollection (INT32 utmZoneNbr,double minLat,double maxLat)
+                                                                                            :
+                                                                                        MgGuardDisposable       (),
+                                                                                        m_NorthPolar            (false),
+                                                                                        m_SouthPolar            (false),
+                                                                                        m_MajorRegionCollection ()
+{
+    INT32 bandIndex;
+    INT32 intMinLat;
+    INT32 intMaxLat;
+    INT32 southernBandIndex;
+    INT32 northernBandIndex;
+
+    double delta;
+
+    // NOTE:  This is a constructor.
+    m_MajorRegionCollection = new MgDisposableCollection();
+
+    // Determine the band index of the southernmost region in the latitude range.
+    if (minLat < -80.0)
+    {
+        // Southern limit includes the south UPS region.
+        m_SouthPolar = true;
+        intMinLat = -90;
+        southernBandIndex = 0;
+    }
+    else if (minLat >= -80.0 && minLat < 72.0)
+    {
+        // Southern limit is in the normal UTM zone area where regions are 8 degrees
+        // of latitude.
+        delta = fabs(fmod (minLat,8.0));
+        intMinLat = static_cast<INT32>(minLat - ((minLat >= 0.0) ? delta : (8.0 - delta)));
+        // +2 two here accounts for the A & B regions of the south pole.
+        southernBandIndex = ((intMinLat + 80) / 8) + 2;
+    }
+    else if (minLat >= 72.0 && minLat <= 84.0)
+    {
+        // The southern limit is in Band X which is the one zone which is 12 degrees
+        // of latitude high.
+        intMinLat = 72;
+        southernBandIndex = 21;
+    }
+    else if (minLat > 84.0)
+    {
+        // The southern limit is in the north UPS regions (i.e. YZ).
+        m_NorthPolar = true;   
+        intMinLat = 84;
+        southernBandIndex = 22;
+    }
+
+    // Determine the bandindex of the northernmost region in the latitude range.
+    if (maxLat < -80.0)
+    {
+        // Northern limit is in the southern UPS region.
+        m_SouthPolar = true;
+        intMaxLat = 80;
+        northernBandIndex = 1;
+    }
+    else if (maxLat >= -80.0 && maxLat <= 72.0)
+    {
+        // Northern limit is in area of normal UTM zones where regions are 8 degrees
+        // of latitude high.
+        delta = fabs(fmod (maxLat,8.0));
+        intMaxLat = static_cast<INT32>(maxLat + ((maxLat >= 0.0) ? (8.0 - delta) : delta));
+        northernBandIndex = ((intMaxLat + 80) / 8) + 2;
+    }
+    else if (maxLat > 72.0 && maxLat <= 84.0)
+    {
+        // Northern limit is in band X, the region which is 12 degrees high.
+        intMaxLat = 84;
+        northernBandIndex = 21;
+    }
+    else if (maxLat > 84.0)
+    {
+        m_NorthPolar = true;
+        intMaxLat = 90;
+        northernBandIndex = 22;
+    }
+
+    // This function does not return the polar regions, as it is likely that doing
+    // in this function which UTM zone specific will cause several duplicates.  So
+    // we filter the polar band out.
+    if (southernBandIndex <  2) southernBandIndex =  2;
+    if (northernBandIndex > 21) northernBandIndex = 21;
+
+    // OK, generate the regions which interect (even to the smallest degree) the
+    // the latitude limits we were provided.
+    if (southernBandIndex <= northernBandIndex)
+    {
+        for (bandIndex = southernBandIndex;bandIndex <= northernBandIndex;bandIndex += 1)
+        {
+            Ptr<CCoordinateSystemMgrsMajorRegion> rgnPtr = new CCoordinateSystemMgrsMajorRegion (utmZoneNbr,bandIndex);
+            if (rgnPtr->IsValid ())
+            {
+                m_MajorRegionCollection->Add (rgnPtr);
+            }
+        }
+    }
+}
+bool CCoordinateSystemMgrsMajorRegionCollection::IncludesSouthPolarRegion (void)
+{
+    return m_SouthPolar;
+}
+bool CCoordinateSystemMgrsMajorRegionCollection::IncludesNorthPolarRegion (void)
+{
+    return m_NorthPolar;
+}
+CCoordinateSystemMgrsMajorRegionCollection::~CCoordinateSystemMgrsMajorRegionCollection (void)
+{
+    m_MajorRegionCollection->Clear ();
+}
+INT32 CCoordinateSystemMgrsMajorRegionCollection::GetCount () const
+{
+    INT32 itemCount = m_MajorRegionCollection->GetCount ();
+    return itemCount;
+}
+CCoordinateSystemMgrsMajorRegion* CCoordinateSystemMgrsMajorRegionCollection::GetItem (INT32 index) const
+{
+    CCoordinateSystemMgrsMajorRegion *itemPtr = static_cast<CCoordinateSystemMgrsMajorRegion*>(m_MajorRegionCollection->GetItem (index));
+    return itemPtr;
+}
+void CCoordinateSystemMgrsMajorRegionCollection::RemoveAt (INT32 index)
+{
+    m_MajorRegionCollection->RemoveAt (index);
+}
+void CCoordinateSystemMgrsMajorRegionCollection::Clear()
+{
+    m_MajorRegionCollection->Clear ();
+}
+void CCoordinateSystemMgrsMajorRegionCollection::SetItem (INT32 index, CCoordinateSystemMgrsMajorRegion* value)
+{
+    m_MajorRegionCollection->SetItem (index,value);
+}
+void CCoordinateSystemMgrsMajorRegionCollection::Add (CCoordinateSystemMgrsMajorRegion* value)
+{
+    m_MajorRegionCollection->Add (value);
+}
+void CCoordinateSystemMgrsMajorRegionCollection::Dispose (void)
+{
+    delete this;
+}

Copied: sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsMajorRegion.h (from rev 4398, trunk/MgDev/Common/CoordinateSystem/CoordSysMgrsMajorRegion.h)
===================================================================
--- sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsMajorRegion.h	                        (rev 0)
+++ sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsMajorRegion.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -0,0 +1,116 @@
+//
+//  Copyright (C) 2004-2009 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef _CCOORDINATESYSTEMMGRSMAJORTREGION_H_
+#define _CCOORDINATESYSTEMMGRSMAHJORREGION_H_
+
+namespace CSLibrary
+{
+
+// All region, major and minor, are rectangular in their native coordinates:
+// Lat/Long for the major regions and UTM coordinates for minor regions.  We
+// have this helper object for the major regions as there screwy things go on
+// at the northern extent.  Specifically, band X is actually 12 degrees
+// high, zones 31 thru 37 in band X are screwy, and in band V zones 31 and 32
+// are screwy.  We intend to use this object so that there is only one copy of
+// the code necessary to deal with all this screwy-ness.
+//
+// Essentially, given a grid boundary in terms of lat/long min/max, we generate
+// a collection of these objects which represents the regions which intersect
+// the geographic region provided.  Then, as need dictate, MGRS graticule lines
+// and/or Grid Regions are manufactured from the the resulting collection.
+//
+// A lot of busy work, but required to get this done right.
+
+class CCoordinateSystemMgrsMajorRegion : public MgGuardDisposable
+{
+public:
+    CCoordinateSystemMgrsMajorRegion (INT32 utmZoneNbr,INT32 bandIndex);
+
+    // This constructor is used for polar regions.  The central meridian
+    // paremeter is the central longitude of the view port as seen from the
+    // the equator and is used to determine what portion of the polar
+    // graticules are considered east/west/south/north lines.  This
+    // becomes very important for labeling purposes.
+    CCoordinateSystemMgrsMajorRegion (INT32 utmZoneNbr,double centralMeridian,INT32 latIndex);
+    ~CCoordinateSystemMgrsMajorRegion (void);
+
+    bool IsValid (void);
+    STRING GetDesignation (void);
+    INT32 GetUtmZoneNbr (void);
+    INT32 GetMgrsBandINdex (void);
+    double GetCentralMeridian (void);
+    double GetWestEdgeLng (void);
+    double GetSouthEdgeLat (void);
+    double GetEastEdgeLng (void);
+    double GetNorthEdgeLat (void);
+
+protected:
+    void Dispose (void);
+
+private:
+    bool m_IsValid;             // Set to false for non-existent regions
+    STRING m_Designation;       // MGRS major region designation.
+    INT32 m_UtmZoneNbr;         // positive is north, negative south, 61 polar, 0 == invalid.
+    INT32 m_MgrsBandIndex;      // 'A' thru 'Z', sans 'I' and 'O', zero based
+    double m_CentralMeridian;   // in degrees, east longitude positive.
+    double m_WestLng;           // longitude of western edge of the region, degrees positive east
+    double m_SouthLat;          // latitude of the southern edge of the region, degrees positive north
+    double m_EastLng;           // longitude of eastern edge of the region, degrees positive east
+    double m_NorthLat;          // latitude of the southern edge of the region, degrees positive north
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Not implemented
+    CCoordinateSystemMgrsMajorRegion (const CCoordinateSystemMgrsMajorRegion& source);
+    CCoordinateSystemMgrsMajorRegion& operator= (const CCoordinateSystemMgrsMajorRegion& rhs);
+};
+
+// The following is a collection of the above.  The magic here, of course,
+// is that the constructor of this object builds the entire collection.
+class CCoordinateSystemMgrsMajorRegionCollection : public MgGuardDisposable
+{
+public:
+    CCoordinateSystemMgrsMajorRegionCollection (void);
+    CCoordinateSystemMgrsMajorRegionCollection (INT32 utmZoneNbr,double minLat,double maxLat);
+    ~CCoordinateSystemMgrsMajorRegionCollection (void);
+
+    bool IncludesSouthPolarRegion (void);
+    bool IncludesNorthPolarRegion (void);
+    INT32 GetCount () const;
+    CCoordinateSystemMgrsMajorRegion* GetItem (INT32 index) const;
+    void RemoveAt (INT32 index);
+    void Clear();
+    void SetItem (INT32 index, CCoordinateSystemMgrsMajorRegion* value);
+    void Add (CCoordinateSystemMgrsMajorRegion* value);
+
+protected:
+    void Dispose (void);
+
+private:
+    // Data Members
+    bool m_SouthPolar;
+    bool m_NorthPolar;
+    Ptr<MgDisposableCollection> m_MajorRegionCollection;
+
+    // Member functions not implemented.
+    CCoordinateSystemMgrsMajorRegionCollection  (const CCoordinateSystemMgrsMajorRegionCollection & source);
+    CCoordinateSystemMgrsMajorRegionCollection& operator= (const CCoordinateSystemMgrsMajorRegionCollection & rhs);
+};
+
+}       // CSLibrary namespace
+
+#endif  // _CCOORDINATESYSTEMMGRSMAJORTREGION_H_

Modified: sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsZone.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsZone.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsZone.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -24,10 +24,21 @@
 #include "CoordSysGrids.h"
 #include "CoordSysOneGrid.h"
 #include "CoordSysMgrsZone.h"
-#include "CoordSysMgrs.h"       //for CCoordinateSystemMgrs
+#include "CoordSysMgrs.h"
+#include "CoordSysMgrsMajorRegion.h"
 
 using namespace CSLibrary;
 
+#if !defined (_DEBUG)
+    // Include heap overhead estimated at 12 bytes in release mode.
+    static const INT32 kMgHeapOverhead = 12;
+    static const INT32 kMgSizeOfCoordinateXY = sizeof (MgCoordinateXY) + kMgHeapOverhead;
+#else
+    // Include heap overhead estimated at 36 bytes in release mode.
+    static const INT32 kMgHeapOverhead = 36;
+    static const INT32 kMgSizeOfCoordinateXY = sizeof (MgCoordinateXY) + kMgHeapOverhead;
+#endif
+
 CCoordinateSystemMgrsZone::CCoordinateSystemMgrsZone (MgCoordinateSystemGridBoundary* frameBoundary,
                                                       INT32 utmZoneNbr,
                                                       bool useFrameDatum,
@@ -36,28 +47,305 @@
                                                         :
                                                       CCoordinateSystemOneGrid (),
                                                       m_UtmZone                (utmZoneNbr),
-                                                      m_LetteringScheme        (letteringScheme),
-                                                      m_RegionCollection       ()
+                                                      m_LetteringScheme        (letteringScheme)
 {
     MgCoordinateSystemFactory csFactory;
     Ptr<MgCoordinateSystem> utmZoneCRS;
-    m_RegionCollection = new CCoordinateSystemGridRegionCollection ();
 
     STRING utmZoneCode = CCoordinateSystemMgrs::ZoneNbrToUtmCs (m_UtmZone);
     utmZoneCRS = csFactory.CreateFromCode (utmZoneCode);
+
     SetUp (frameBoundary,utmZoneCRS,frameCRS);
-    
     SetUserID (m_UtmZone);
 }
 CCoordinateSystemMgrsZone::~CCoordinateSystemMgrsZone (void)
 {
 }
 CCoordinateSystemGridRegionCollection* CCoordinateSystemMgrsZone::GetGridRegions (MgCoordinateSystemGridBoundary* frameBoundary,
-                                                                                  MgCoordinateSystemGridSpecification* specification)
+                                                                                  MgCoordinateSystemGridSpecification* specification,
+                                                                                  INT32 exceptionLvl)
 {
-    BuildRegionCollection (frameBoundary,specification);
-    return SAFE_ADDREF(m_RegionCollection.p);
+    Ptr<CCoordinateSystemGridRegionCollection> regionCollection;
+
+    MG_TRY ()
+        regionCollection = BuildRegionCollection (frameBoundary,specification,exceptionLvl);
+    MG_CATCH_AND_THROW(L"MgCoordinateSystemMgrsZone::GetGridRegions")
+    return SAFE_ADDREF(regionCollection.p);
 }
+CCoordinateSystemGridLineCollection* CCoordinateSystemMgrsZone::GetGridLines (MgCoordinateSystemGridBoundary* frameBoundary,
+                                                                              MgCoordinateSystemGridSpecification* specification,
+                                                                              INT32 exceptionLvl)
+{
+    // For now, we just call the generic OneGrid grid line function.
+    // Later on we might need to add some special logic for zones 31
+    // through 37 in the higher northern longitudes.
+    MgCoordinateSystemGridLineCollection* gridLines = CCoordinateSystemOneGrid::GetGridLines (specification);
+    return dynamic_cast<CCoordinateSystemGridLineCollection*>(gridLines);
+}
+CCoordinateSystemGridLineCollection* CCoordinateSystemMgrsZone::GetGraticuleLines (MgCoordinateSystemGridBoundary* frameBoundary,
+                                                                                   MgCoordinateSystemGridSpecification* specification,
+                                                                                   INT32 exceptionLvl)
+{
+    const INT32 maxPoints = 512;
+
+    INT32 index;
+    INT32 regionCount;
+    double value;
+    double precision;
+    double lngMin, lngMax;
+    double latMin,latMax;
+    STRING designation;
+   
+    Ptr<MgCoordinateXY> fromPoint;
+    Ptr<MgCoordinateXY> toPoint;
+    Ptr<MgCoordinateSystem> llCRS;
+    Ptr<MgCoordinateSystem> frameCRS;
+    Ptr<MgCoordinateSystemTransform> toFrameTransform;
+    Ptr<CCoordinateSystemMgrsMajorRegion> regionPtr;
+    Ptr<CCoordinateSystemMgrsMajorRegionCollection> regionCollection;
+    Ptr<MgLineStringCollection> lineStrCollectionPtr;
+    Ptr<CCoordinateSystemMgrsZoneCollection> mjrZoneCollection;
+    Ptr<MgLineString> lineString;
+    Ptr<MgLineStringCollection> lineStringCollection;
+    Ptr<CCoordinateSystemGridLine> gridLine;
+
+    MgCoordinateSystemFactory csFactory;
+
+    Ptr<CCoordinateSystemGridLineCollection> gridLineCollection = new CCoordinateSystemGridLineCollection (exceptionLvl);
+
+    MG_TRY ()
+        fromPoint = new MgCoordinateXY ();
+        toPoint = new MgCoordinateXY ();
+        CCoordinateSystemGridSpecification* mySpecPtr = dynamic_cast<CCoordinateSystemGridSpecification*>(specification);
+        precision = mySpecPtr->GetCurvePrecision (m_GridCRS);
+
+        // To be are successful, we'll need a Transform which will convert
+        // 'LL' to the frame coordinate system.
+        llCRS = csFactory.CreateFromCode (L"LL");
+        frameCRS = GetFrameCRS ();
+        toFrameTransform = csFactory.GetTransform(llCRS,frameCRS);
+
+        // Major regions are solely a function of the extents of the grid in
+        // terms of geographic coordinates.  So, we extract the extents of this
+        // grid in geographic coordinate form, and work from there.
+        GetGeographicExtents (lngMin,lngMax,latMin,latMax);
+        
+        regionCollection = new CCoordinateSystemMgrsMajorRegionCollection (m_UtmZone,latMin,latMax);
+        if (regionCollection != 0)
+        {
+            // Draw the east/west lines, i.e. the lines of constant latitude.
+            regionCount = regionCollection->GetCount ();
+            for (index = 0;index < regionCount;index += 1)
+            {
+                // We have a region.
+                regionPtr = regionCollection->GetItem (index);
+                value = regionPtr->GetSouthEdgeLat ();
+                fromPoint->SetX (regionPtr->GetWestEdgeLng ());
+                fromPoint->SetY (value);
+                toPoint->SetX (regionPtr->GetEastEdgeLng ());
+                toPoint->SetY (value);
+                lineString = toFrameTransform->GridLine (fromPoint,toPoint,precision,m_MaxCurvePoints);
+
+                // Clip the line to the frame boundary.  The grid line may
+                // actually leave, and then re-enter, the grid boundary, so the
+                // result can be a multi-line string.
+                lineStringCollection = frameBoundary->ClipLineString (lineString);
+                if (lineStringCollection)
+                {
+                    // Construct the Grid Line object and add it to the grid
+                    // line collection object.
+                    gridLine = new CCoordinateSystemGridLine (MgCoordinateSystemGridOrientation::NorthSouth,value);
+                    gridLine->SetSegmentCollection (lineStringCollection);
+                    gridLineCollection->Add (gridLine);
+                }
+                if (index == (regionCount - 1))
+                {
+                    value = regionPtr->GetNorthEdgeLat ();
+                    fromPoint->SetX (regionPtr->GetWestEdgeLng ());
+                    fromPoint->SetY (value);
+                    toPoint->SetX (regionPtr->GetEastEdgeLng ());
+                    toPoint->SetY (value);
+                    lineString = toFrameTransform->GridLine (fromPoint,toPoint,precision,m_MaxCurvePoints);
+
+                    // Clip the line to the frame boundary.
+                    lineStringCollection = frameBoundary->ClipLineString (lineString);
+                    if (lineStringCollection)
+                    {
+                        // Construct the Grid Line object and add it to the grid
+                        // line collection object.
+                        gridLine = new CCoordinateSystemGridLine (MgCoordinateSystemGridOrientation::NorthSouth,value);
+                        gridLine->SetSegmentCollection (lineStringCollection);
+                        gridLineCollection->Add (gridLine);
+                    }
+                }
+            }
+
+            // Draw the western north/south lines, i.e. the lines of constant
+            // longitude.
+            regionCount = regionCollection->GetCount ();
+            for (index = 0;index < regionCount;index += 1)
+            {
+                // We have a region.
+                regionPtr = regionCollection->GetItem (index);
+                value = regionPtr->GetWestEdgeLng ();
+                fromPoint->SetX (value);
+                fromPoint->SetY (regionPtr->GetSouthEdgeLat ());
+                toPoint->SetX (value);
+                toPoint->SetY (regionPtr->GetNorthEdgeLat ());
+                lineString = toFrameTransform->GridLine (fromPoint,toPoint,precision,m_MaxCurvePoints);
+
+                // Clip the line to the frame boundary.
+                lineStringCollection = frameBoundary->ClipLineString (lineString);
+                if (lineStringCollection)
+                {
+                    // Construct the Grid Line object and add it to the grid
+                    // line collection object.
+                    gridLine = new CCoordinateSystemGridLine (MgCoordinateSystemGridOrientation::EastWest,value);
+                    gridLine->SetSegmentCollection (lineStringCollection);
+                    gridLineCollection->Add (gridLine);
+                }
+            }
+
+            // Draw the north/south lines, i.e. the lines of constant longitude.
+            regionCount = regionCollection->GetCount ();
+            for (index = 0;index < regionCount;index += 1)
+            {
+                // We have a region.
+                regionPtr = regionCollection->GetItem (index);
+                value = regionPtr->GetEastEdgeLng ();
+                fromPoint->SetX (value);
+                fromPoint->SetY (regionPtr->GetSouthEdgeLat ());
+                toPoint->SetX (value);
+                toPoint->SetY (regionPtr->GetNorthEdgeLat ());
+                lineString = toFrameTransform->GridLine (fromPoint,toPoint,precision,m_MaxCurvePoints);
+
+                // Clip the line to the frame boundary.  The grid line may
+                // actually leave, and then re-enter, the grid boundary, so the
+                // result can be a multi-line string.
+                lineStringCollection = frameBoundary->ClipLineString (lineString);
+                if (lineStringCollection)
+                {
+                    // Construct the Grid Line object and add it to the grid
+                    // line collection object.
+                    gridLine = new CCoordinateSystemGridLine (MgCoordinateSystemGridOrientation::EastWest,value);
+                    gridLine->SetSegmentCollection (lineStringCollection);
+                    gridLineCollection->Add (gridLine);
+                }
+            }
+        }
+    MG_CATCH_AND_THROW(L"MgCoordinateSystemMgrsZone::GetGraticuleLines")
+   return gridLineCollection.Detach ();
+}
+INT32 CCoordinateSystemMgrsZone::ApproxGridRegionMemoryUsage (MgCoordinateSystemGridSpecification* specification)
+{
+    INT32 regionSize;
+    INT32 regionCount;
+    INT32 maxRegions;
+    INT32 memoryGuess (0);
+
+    // Estimate the size of a major region object.  Eventually, should include
+    // MaxPoints and CurvePrecision from the specification object.  For now, we
+    // make some guesses based on the coordinate systems involved.
+    if (GridFrameCrsAreTheSame ())
+    {
+        // Here, for now, we assume that there are 4 lines at two points a piece, plus
+        // a polygon with 5 points.  In this case, several of these points are the
+        // same actual object in memory; so we reduce the point count by (an arbirtrary
+        // value) 3.
+        regionSize = sizeof (CCoordinateSystemGridRegion) + sizeof (MgPolygon) +
+                                                            sizeof (MgLineString) * 4 +
+                                                            kMgSizeOfCoordinateXY * 10;
+    }
+    else
+    {
+        // Here, for now, we assume that there are 4 lines at 511 points a piece, plus
+        // a polygon with (4 * 511) points; 4088 points altogether.
+        regionSize = sizeof (CCoordinateSystemGridRegion) + sizeof (MgPolygon) +
+                                                            sizeof (MgLineString) * 4 +
+                                                            kMgSizeOfCoordinateXY * 4088;
+    }
+    maxRegions = 0x7FFF0000 / regionSize;
+
+    MG_TRY ()
+        if (specification->GetUnitType () == MgCoordinateSystemUnitType::Angular)
+        {
+            double eastingIncrement = specification->GetEastingIncrement (MgCoordinateSystemUnitCode::Degree);
+            double northingIncrement = specification->GetNorthingIncrement (MgCoordinateSystemUnitCode::Degree);
+            if (MgMathUtility::DblCmp (eastingIncrement,6.0) &&
+                MgMathUtility::DblCmp (northingIncrement,8.0))
+            {
+                double lngMin,lngMax;
+                double latMin,latMax;
+                Ptr<CCoordinateSystemMgrsMajorRegionCollection> mjrRegionCollection;
+
+                // Determine the number of regions included in the boundary.
+                GetGeographicExtents (lngMin,lngMax,latMin,latMax);
+                mjrRegionCollection = new CCoordinateSystemMgrsMajorRegionCollection (m_UtmZone,latMin,latMax);
+                regionCount = mjrRegionCollection->GetCount ();
+
+                // Make a guess at the amount of memory required.
+                if (regionCount < maxRegions)
+                {
+                    memoryGuess = regionSize * regionCount;
+                }
+                else
+                {
+                    // Who knows what MAXINT will be in various environments.  We know
+                    // that memoryGuess is an INT32, so we use our own hard coded value.
+                    memoryGuess = 0x7FFFFFFF;
+                }
+            }
+        }
+        else if (specification->GetUnitType () == MgCoordinateSystemUnitType::Linear)
+        {
+            double eastingIncrement = specification->GetEastingIncrement (MgCoordinateSystemUnitCode::Meter);
+            double northingIncrement = specification->GetNorthingIncrement (MgCoordinateSystemUnitCode::Meter);
+            if (MgMathUtility::DblCmp (eastingIncrement,100000.0) &&
+                MgMathUtility::DblCmp (northingIncrement,100000.0))
+            {
+                INT32 beginEast, endEast;
+                INT32 beginNorth, endNorth;
+
+                double delta;
+                double curvePrecision;
+                double  eastMin, eastMax;
+                double northMin, northMax;
+
+                curvePrecision = 1.0;
+                // Estimate the number of minor regions.
+                GetGridExtents (eastMin,eastMax,northMin,northMax,curvePrecision);
+ 
+                delta = fabs (fmod (eastMin,100000.0));
+                beginEast = static_cast<INT32>(eastMin - ((eastMin >= 0.0) ? delta : (100000.0 - delta)));
+                delta = fabs (fmod (eastMax,100000.0));
+                endEast = static_cast<INT32>(eastMax + ((eastMax >= 0.0) ? (100000.0 - delta) : -delta));
+
+                delta = fabs (fmod (northMin,100000.0));
+                beginNorth = static_cast<INT32>(northMin - ((northMin >= 0.0) ? delta : (100000.0 - delta)));
+                delta = fabs (fmod (northMax,100000.0));
+                endNorth = static_cast<INT32>(northMax + ((northMax >= 0.0) ? (100000.0 - delta) : -delta));
+
+                INT32 verticalCount   = (endNorth - beginNorth) / 100000;
+                INT32 horizontalCount = (endEast - beginEast) / 100000;
+                regionCount = horizontalCount * verticalCount;
+
+                // Make a guess at the amount of memory required.
+                if (regionCount < maxRegions)
+                {
+                    memoryGuess = regionSize * regionCount;
+                }
+                else
+                {
+                    // Who knows what MAXINT will be in various environments.  We know
+                    // that memoryGuess is an INT32, so we use our own hard coded value.
+                    memoryGuess = 0x7FFFFFFF;
+                }
+            }
+        }
+    MG_CATCH_AND_THROW(L"MgCoordinateSystemMgrsZone::ApproxGridRegionMemoryUsage")
+
+    return memoryGuess;
+}
 INT32 CCoordinateSystemMgrsZone::GetUtmZoneNbr (void)
 {
     // m_UtmZoneNbr is positive for northern hemisphere, negative for the
@@ -65,15 +353,18 @@
     // is the uninitialized/unknown/error value.
     return m_UtmZone;
 }
-void CCoordinateSystemMgrsZone::BuildRegionCollection (MgCoordinateSystemGridBoundary* frameBoundary,
-                                                       MgCoordinateSystemGridSpecification* specification)
+CCoordinateSystemGridRegionCollection* CCoordinateSystemMgrsZone::BuildRegionCollection (MgCoordinateSystemGridBoundary* frameBoundary,
+                                                                                         MgCoordinateSystemGridSpecification* specification,
+                                                                                         INT32 exceptionLvl)
 {
     double curvePrecision;
     double eastingIncrement;
     double northingIncrement;
+    Ptr<CCoordinateSystemGridRegionCollection> regionCollection;
 
+    MG_TRY ()
+        regionCollection = new CCoordinateSystemGridRegionCollection (exceptionLvl);
     curvePrecision = specification->GetCurvePrecision ();
-
     if (specification->GetUnitType () == MgCoordinateSystemUnitType::Angular)
     {
         eastingIncrement = specification->GetEastingIncrement (MgCoordinateSystemUnitCode::Degree);
@@ -81,7 +372,7 @@
         if (MgMathUtility::DblCmp (eastingIncrement,6.0) &&
             MgMathUtility::DblCmp (northingIncrement,8.0))
         {
-            BuildMajorRegions (frameBoundary,curvePrecision);
+                BuildMajorRegions (regionCollection,frameBoundary,curvePrecision);
         }
     }
     else if (specification->GetUnitType () == MgCoordinateSystemUnitType::Linear)
@@ -91,24 +382,22 @@
         if (MgMathUtility::DblCmp (eastingIncrement,100000.0) &&
             MgMathUtility::DblCmp (northingIncrement,100000.0))
         {
-            BuildMinorRegions (frameBoundary,curvePrecision);
+                BuildMinorRegions (regionCollection,frameBoundary,curvePrecision);
         }
     }
+    MG_CATCH_AND_THROW(L"MgCoordinateSystemMgrsZone::GetGraticuleLines")
+    return regionCollection.Detach ();
 }
-void CCoordinateSystemMgrsZone::BuildMajorRegions (MgCoordinateSystemGridBoundary* frameBoundary,double curvePrecision)
+void CCoordinateSystemMgrsZone::BuildMajorRegions (CCoordinateSystemGridRegionCollection* regionCollection,
+                                                   MgCoordinateSystemGridBoundary* frameBoundary,
+                                                   double curvePrecision)
 {
     const INT32 maxPoints = 512;
 
-    wchar_t gridZoneLetter;
-    INT32 utmZoneNbr;
-    INT32 gridZoneIndex;
-    INT32 latIdx, firstLat, lastLat;
-    double delta;
-    double centralMeridian;
+    INT32 index;
     double lngMin, lngMax;
     double latMin,latMax;
     STRING designation;
-    wchar_t wcBufr [128];
  
     Ptr<MgCoordinate> southwest;
     Ptr<MgCoordinate> northeast;
@@ -117,6 +406,8 @@
     Ptr<MgCoordinateSystemTransform> toFrameTransform;
     Ptr<CCoordinateSystemGridBoundary> rgnBoundary;
     Ptr<CCoordinateSystemGridRegion> pMjrRegion;
+    Ptr<CCoordinateSystemMgrsMajorRegion> regionPtr;
+    Ptr<CCoordinateSystemMgrsMajorRegionCollection> mjrRegionCollection;
 
     MgCoordinateSystemFactory csFactory;
 
@@ -135,127 +426,28 @@
         // grid in geographic coordinate form, and work from there.
         GetGeographicExtents (lngMin,lngMax,latMin,latMax);
 
-        if ((m_UtmZone) != 0 && (abs (m_UtmZone) <= 60))
+        mjrRegionCollection = new CCoordinateSystemMgrsMajorRegionCollection (m_UtmZone,latMin,latMax);
+        if (mjrRegionCollection != 0)
         {
-            // Here for a normal (i.e. non-polar) UTM zone.  Use some asserts
-            // to verify the assumption here that the boundary for this zone
-            // does not extend into the polar regions.
-            assert (latMin >= -80.0);
-            assert (latMax <=  84.0);
-
-            // The grid boundary may have been shrunk to the limits of the frame
-            // boundary, so we'll recompute the appropriate minLng and maxLng from
-            // the utmZoneNbr data member.
-            utmZoneNbr = abs (m_UtmZone);
-            centralMeridian = static_cast<double>(-183 + (utmZoneNbr * 6));
-            lngMin = centralMeridian - 3.0;
-            lngMax = centralMeridian + 3.0;
-
-            // Need to account for the fact that the frame boundary may cross
-            // an MGRS Grid Zone Designation boundary (i.e. the 8 degree chunks
-            // of latitude).  Thus, there may be more than just one major region.
-            delta = fabs (fmod (latMin,8.0));
-            firstLat = static_cast<INT32>(latMin - ((latMin >= 0.0) ? delta : (8.0 - delta)));
-            delta = fabs (fmod (latMax,8.0));
-            lastLat = static_cast<INT32>(latMax + ((latMax >= 0.0) ? (8.0 - delta) : -delta));
-
-            // While the normal UTM zones extend up to 84 degrees
-            // north latitude, the northernmost band (Band X) is
-            // 12 degrees high (72 to 84 degrees latitude).  So there
-            // is no band beginning at 80.
-            if (lastLat > 80)
+            INT32 mjrRegionCount = mjrRegionCollection->GetCount ();
+            for (index = 0;index < mjrRegionCount;index += 1)
             {
-                lastLat = 80;
-            }
-
-            for (latIdx = firstLat;latIdx < lastLat;latIdx += 8)
-            {
-                // Calculate the envelope of the normal UTM zone.
-                latMin = static_cast<double>(latIdx);
-                latMax = latMin + 8.0;
-                southwest->SetX (lngMin);
-                southwest->SetY (latMin);
-                northeast->SetX (lngMax);
-                northeast->SetY (latMax);
-
-                // Band X (72 thru 84 north latitude includes 12 degrees of
-                // latitude.  Also, in this band, zones 32, 34, and 36 do not exist.
-                // and zones 31, 33, 35, and 37 have non-standard widths.  We
-                // adjust for all that now.
-                if (latIdx == 72)
-                {
-                    if (m_UtmZone == 32 || m_UtmZone == 34 || m_UtmZone == 36)
-                    {
-                        // These are regions which do not exist.
-                        continue;
-                    }
-
-                    // For all other regions in this band, the "height" is
-                    // 12 degrees.
-                    latMin = static_cast<double>(latIdx);
-                    latMax = latMin + 12.0;
-
-                    // There are two zones which are 9 degrees wide, and two that are
-                    // 12 degrees wide in this band.
-                    if (m_UtmZone == 31)
-                    {
-                        lngMin = centralMeridian - 3.0;
-                        lngMax = centralMeridian + 6.0;
-                    }
-                    else if (m_UtmZone == 33 || m_UtmZone == 35)
-                    {
-                        lngMin = centralMeridian - 6.0;
-                        lngMax = centralMeridian + 6.0;
-                    }
-                    else if (m_UtmZone == 37)
-                    {
-                        lngMin = centralMeridian - 6.0;
-                        lngMax = centralMeridian + 3.0;
-                    }
-                    southwest->SetX (lngMin);
-                    southwest->SetY (latMin);
-                    northeast->SetX (lngMax);
-                    northeast->SetY (latMax);
-                }
-
-                // One more kludge.  The following is necessary for a specific
-                // region south east of Norway.
-                if ((latIdx == 56) && (m_UtmZone == 31 || m_UtmZone == 32))
-                {
-                    if (m_UtmZone == 31)
-                    {
-                        lngMin = centralMeridian - 3.0;
-                        lngMax = centralMeridian;
-                    }
-                    else if (m_UtmZone == 32)
-                    {
-                        lngMin = centralMeridian - 6.0;
-                        lngMax = centralMeridian + 3.0;
-                    }
-                    southwest->SetX (lngMin);
-                    southwest->SetY (latMin);
-                    northeast->SetX (lngMax);
-                    northeast->SetY (latMax);
-                }
-
-                // We have the polygon, we need the designation.
-                gridZoneIndex = CCoordinateSystemMgrs::GridZoneDesignationIndex (latMin + 1.0,centralMeridian);
-                gridZoneLetter = CCoordinateSystemMgrs::GridZoneDesignationLetter (gridZoneIndex);
-                swprintf (wcBufr,128,L"%d%c",utmZoneNbr,gridZoneLetter);
-                STRING designation (wcBufr);
-                if (!designation.empty ())
-                {
-                // Construct the region object and add it to the region collection.
+                // We have a region.
+                regionPtr = mjrRegionCollection->GetItem (index);
+                southwest->SetX (regionPtr->GetWestEdgeLng ());
+                southwest->SetY (regionPtr->GetSouthEdgeLat ());
+                northeast->SetX (regionPtr->GetEastEdgeLng ());
+                northeast->SetY (regionPtr->GetNorthEdgeLat ());
+                designation = regionPtr->GetDesignation ();
                     pMjrRegion = new CCoordinateSystemGridRegion (designation,frameBoundary,
                                                                               toFrameTransform,
                                                                               southwest,
                                                                               northeast,
                                                                               curvePrecision,
                                                                               maxPoints);
-                m_RegionCollection->Add (pMjrRegion);
+                regionCollection->Add (pMjrRegion);
             }
         }
-        }
         else if (m_UtmZone == 61)
         {
             //TODO: need to generate regions for the north polar region.
@@ -266,7 +458,9 @@
         }
     MG_CATCH_AND_THROW(L"MgCoordinateSystemOneGrid::BuildMajorRegions")
 }
-void CCoordinateSystemMgrsZone::BuildMinorRegions (MgCoordinateSystemGridBoundary* frameBoundary,double curvePrecision)
+void CCoordinateSystemMgrsZone::BuildMinorRegions (CCoordinateSystemGridRegionCollection* regionCollection,
+                                                   MgCoordinateSystemGridBoundary* frameBoundary,
+                                                   double curvePrecision)
 {
     const INT32 maxPoints = 512;
 
@@ -338,7 +532,7 @@
                                                                               northeast,
                                                                               curvePrecision,
                                                                               maxPoints);
-                m_RegionCollection->Add (pMnrRegion);
+                    regionCollection->Add (pMnrRegion);
             }
         }
         }

Modified: sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsZone.h
===================================================================
--- sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsZone.h	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysMgrsZone.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -53,16 +53,29 @@
                                INT8 letteringScheme);
     ~CCoordinateSystemMgrsZone (void);
 
+    CCoordinateSystemGridLineCollection* GetGridLines (MgCoordinateSystemGridBoundary* frameBoundary,
+                                                       MgCoordinateSystemGridSpecification* specification,
+                                                       INT32 exceptionLvl);
+    CCoordinateSystemGridLineCollection* GetGraticuleLines (MgCoordinateSystemGridBoundary* frameBoundary,
+                                                            MgCoordinateSystemGridSpecification* specification,
+                                                            INT32 exceptionLvl);
     CCoordinateSystemGridRegionCollection* GetGridRegions (MgCoordinateSystemGridBoundary* frameBoundary,
-                                                           MgCoordinateSystemGridSpecification* specification);
+                                                           MgCoordinateSystemGridSpecification* specification,
+                                                           INT32 exceptionLvl);
+    INT32 ApproxGridRegionMemoryUsage (MgCoordinateSystemGridSpecification* specification);
     INT32 GetUtmZoneNbr (void);
  
 protected:
-    void BuildRegionCollection (MgCoordinateSystemGridBoundary* frameBoundary,
-                                MgCoordinateSystemGridSpecification* specification);
+    CCoordinateSystemGridRegionCollection* BuildRegionCollection (MgCoordinateSystemGridBoundary* frameBoundary,
+                                                                  MgCoordinateSystemGridSpecification* specification,
+                                                                  INT32 exceptionLvl);
 private:
-    void BuildMajorRegions (MgCoordinateSystemGridBoundary* frameBoundary,double boundaryPrecision);
-    void BuildMinorRegions (MgCoordinateSystemGridBoundary* frameBoundary,double boundaryPrecision);
+    void BuildMajorRegions (CCoordinateSystemGridRegionCollection* regionCollection,
+                            MgCoordinateSystemGridBoundary* frameBoundary,
+                            double boundaryPrecision);
+    void BuildMinorRegions (CCoordinateSystemGridRegionCollection* regionCollection,
+                            MgCoordinateSystemGridBoundary* frameBoundary,
+                            double boundaryPrecision);
     ///////////////////////////////////////////////////////////////////////////
     // Data members
     // m_UtmZoneNbr is positive for northern hemisphere, negative for the
@@ -70,7 +83,7 @@
     // Zero is the uninitialized/unknown/error value.
     INT32 m_UtmZone;
     INT8 m_LetteringScheme;
-    Ptr<CCoordinateSystemGridRegionCollection> m_RegionCollection;
+//    Ptr<CCoordinateSystemGridRegionCollection> m_RegionCollection;
 
     // Not implemented
     CCoordinateSystemMgrsZone (const CCoordinateSystemMgrsZone& source);
@@ -105,100 +118,3 @@
 } // End of namespace
 
 #endif //_CCOORDINATESYSTEMMGRSZONE_H_
-//
-//  Copyright (C) 2004-2009 by Autodesk, Inc.
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of version 2.1 of the GNU Lesser
-//  General Public License as published by the Free Software Foundation.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-
-#ifndef _CCOORDINATESYSTEMMGRSZONE_H_
-#define _CCOORDINATESYSTEMMGRSZONE_H_
-
-namespace CSLibrary
-{
-
-//=============================================================================
-// MGRS grids can cross UTM zone boundaries, which means that an MGRS grid may
-// consist of multiple generic grids.  Thus, we have an object named
-// CCoordinateSystemMgrsZone which represents a single zone of a multiple
-// zone MGRS grid.  The higher level CCoordinateSystemMgrs object carries a
-// collection of these objects.
-//
-// In this object:
-// * UtmZone is an integer value indicating the UTM zone where positive means
-//   northern hemisphere, negative means southern hemisphere, and 61 means
-//   a polr region (i.e. UPS).  Zero indicates not set yet or invalid.
-// * GridCsCode is the key name of the grid coordinate system which will be
-//   used to generate the grid.  This definition will be datum dependent.
-// * ZoneBoundary starts off being an envelope of the entire UTM zone, and
-//   is eventually reduced to be that portion of the Viewport boundary which
-//   is covered by this grid object.
-// * If useFrameDatum is true, the Grid coordinate system will be adjusted
-//   to use the datum of the provided frame coordinate system.  Otherwise,
-//   the Grid datum is hardcoded to WGS84.
-class CCoordinateSystemMgrsZone : public CCoordinateSystemOneGrid
-{
-public:
-    //
-    CCoordinateSystemMgrsZone (MgCoordinateSystemGridBoundary* frameBoundary,
-                               INT32 utmZoneNbr,
-                               bool useFrameDatum,
-                               MgCoordinateSystem* frameCS,
-                               INT8 letteringScheme);
-    ~CCoordinateSystemMgrsZone (void);
-
-    CCoordinateSystemGridRegionCollection* GetGridRegions (MgCoordinateSystemGridSpecification* specification);
-protected:
-    void BuildRegionCollection (MgCoordinateSystemGridSpecification* specification);
-private:
-    void BuildMajorRegions (double boundaryPrecision);
-    void BuildMinorRegions (double boundaryPrecision);
-    // Data members
-    INT32 m_UtmZone;
-    INT8 m_LetteringScheme;
-    Ptr<CCoordinateSystemGridRegionCollection> m_RegionCollection;
-
-    // Not implemented
-    CCoordinateSystemMgrsZone (const CCoordinateSystemMgrsZone& source);
-    CCoordinateSystemMgrsZone& operator= (const CCoordinateSystemMgrsZone& rhs);
-};
-
-class CCoordinateSystemMgrsZoneCollection : public MgGuardDisposable
-{
-public:
-    CCoordinateSystemMgrsZoneCollection (void);
-    ~CCoordinateSystemMgrsZoneCollection (void);
-
-    INT32 GetCount () const;
-    CCoordinateSystemMgrsZone* GetItem (INT32 index) const;
-    void RemoveAt (INT32 index);
-    void Clear();
-    void SetItem (INT32 index, CCoordinateSystemMgrsZone* value);
-    void Add (CCoordinateSystemMgrsZone* value);
-
-protected:
-    void Dispose (void);
-
-private:
-    // Data Members
-    Ptr<MgDisposableCollection> m_OneGridCollection;
-
-    // Member functions not implemented.
-    CCoordinateSystemMgrsZoneCollection  (const CCoordinateSystemMgrsZoneCollection & source);
-    CCoordinateSystemMgrsZoneCollection& operator= (const CCoordinateSystemMgrsZoneCollection & rhs);
-};
-
-} // End of namespace
-
-#endif //_CCOORDINATESYSTEMMGRSZONE_H_

Modified: sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysOneGrid.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysOneGrid.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysOneGrid.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -21,19 +21,36 @@
 #include "CriticalSection.h"
 
 #include "CoordSys.h"
+#include "CoordSysMathComparator.h"
 #include "CoordSysTransform.h"              //for CCoordinateSystemTransform
 #include "CoordSysGrids.h"
 #include "CoordSysOneGrid.h"
 
 using namespace CSLibrary;
 
+#if !defined (_DEBUG)
+    // Include heap overhead estimated at 12 bytes in release mode.
+    static const INT32 kMgHeapOverhead = 12;
+    static const INT32 kMgSizeOfCoordinateXY = sizeof (MgCoordinateXY) + kMgHeapOverhead;
+#else
+    // Include heap overhead estimated at 36 bytes in release mode.
+    static const INT32 kMgHeapOverhead = 36;
+    static const INT32 kMgSizeOfCoordinateXY = sizeof (MgCoordinateXY) + kMgHeapOverhead;
+#endif
+
 //=============================================================================
 // CCoordinateSystemOneGrid
 const INT32 CCoordinateSystemOneGrid::MaxCurvePoints = 511;
+const INT32 CCoordinateSystemOneGrid::m_GridLineExceptionLevelK = 50000000L;   // 50MB
+const INT32 CCoordinateSystemOneGrid::m_GridTickExceptionLevelK = 20000000L;   // 20MB
+
 CCoordinateSystemOneGrid::CCoordinateSystemOneGrid () : MgGuardDisposable   (),
+                                                        m_GridFrameCrsSame       (false),
                                                         m_UserID            (0),
                                                         m_MaxCurvePoints    (MaxCurvePoints),
                                                         m_Label             (),
+                                                        m_GridLineExceptionLevel (m_GridLineExceptionLevelK),
+                                                        m_GridTickExceptionLevel (m_GridTickExceptionLevelK),
                                                         m_GridCRS           (),
                                                         m_FrameCRS          (),
                                                         m_ToFrameXform      (),
@@ -49,9 +66,12 @@
                                                     MgCoordinateSystem* frameCRS)
                                                         :
                                                     MgGuardDisposable   (),
+                                                    m_GridFrameCrsSame       (false),
                                                     m_UserID            (0),
                                                     m_MaxCurvePoints    (MaxCurvePoints),
                                                     m_Label             (),
+                                                    m_GridLineExceptionLevel (m_GridLineExceptionLevelK),
+                                                    m_GridTickExceptionLevel (m_GridTickExceptionLevelK),
                                                     m_GridCRS           (),
                                                     m_FrameCRS          (),
                                                     m_ToFrameXform      (),
@@ -74,13 +94,27 @@
                                       MgCoordinateSystem* frameCRS)
 {
     MgCoordinateSystemFactory csFactory;
+    CCoordinateSystemMathComparator csMathComparator;
 
     m_FrameBoundary = SAFE_ADDREF (frameBoundary);
     m_GridCRS = SAFE_ADDREF (gridCRS);
     m_FrameCRS = SAFE_ADDREF (frameCRS);
+
     m_ToFrameXform = csFactory.GetTransform (m_GridCRS,m_FrameCRS);
+    m_ToFrameXform->IgnoreDatumShiftWarning (true);
+    m_ToFrameXform->IgnoreOutsideDomainWarning (true);
+
     m_ToGridXform = csFactory.GetTransform (m_FrameCRS,m_GridCRS);
+    m_ToGridXform->IgnoreDatumShiftWarning (true);
+    m_ToGridXform->IgnoreOutsideDomainWarning (true);
+
+    m_GridFrameCrsSame = csMathComparator.Same (gridCRS,frameCRS);
+
 }
+bool CCoordinateSystemOneGrid::GridFrameCrsAreTheSame ()
+{
+    return m_GridFrameCrsSame;
+}
 bool CCoordinateSystemOneGrid::IsGeographic (void)
 {
     bool isGeographic;
@@ -132,7 +166,7 @@
     Ptr<MgLineStringCollection> lineStringCollection;
     Ptr<CCoordinateSystemGridLine> gridLine;
 
-    Ptr<CCoordinateSystemGridLineCollection> gridLineCollection = new CCoordinateSystemGridLineCollection ();
+    Ptr<CCoordinateSystemGridLineCollection> gridLineCollection = new CCoordinateSystemGridLineCollection (m_GridLineExceptionLevel);
 
     MG_TRY()
         gridCrsUnitCode = m_GridCRS->GetUnitCode ();
@@ -146,7 +180,7 @@
         // value has been changed, reproduce the m_GridBoundary
         // member from the m_FrameBoundary member.  At this point, we
         // need the curve precision value in Grid system units.
-        precision = mySpecPtr->GetCurvePrecision ();
+        precision = mySpecPtr->GetCurvePrecision (m_GridCRS);
         GenerateGridBoundary (precision);
 
         // Get the extents of the frame boundary, and then convert them to
@@ -202,8 +236,8 @@
             lineString = m_ToFrameXform->GridLine (fromPnt,toPnt,precision,m_MaxCurvePoints);
 
             // Clip the line to the frame boundary.  The grid line may
-            // actually leave, and then reenter, the grid boundary, so the
-            // result can be a multi-line sting.
+            // actually leave, and then re-enter, the grid boundary, so the
+            // result can be a multi-line string.
             lineStringCollection = m_FrameBoundary->ClipLineString (lineString);
             if (lineStringCollection)
             {
@@ -215,7 +249,7 @@
             }
         }
 
-        // Second loop, the south/north lines, starting at the western edge
+        // Second loop, the south/north lines, starting at the western edged
         // proceeding to the east.
         increment = mySpecPtr->GetEastingIncrement (gridCrsUnitCode);
         for (value = eastMin;value <= eastMax;value += increment)
@@ -275,7 +309,7 @@
         gridCrsUnitCode = m_GridCRS->GetUnitCode ();
 
         CCoordinateSystemGridSpecification* mySpecPtr = dynamic_cast<CCoordinateSystemGridSpecification*>(specs);
-        tickCollection = new CCoordinateSystemGridTickCollection ();
+        tickCollection = new CCoordinateSystemGridTickCollection (m_GridTickExceptionLevel);
 
         // Get the grid extents.
         curvePrecision = mySpecPtr->GetCurvePrecision();
@@ -391,6 +425,112 @@
     MG_CATCH_AND_THROW(L"MgCoordinateSystemOneGrid::GetGridLines")
     return tickCollection.Detach ();
 }
+
+INT32 CCoordinateSystemOneGrid::ApproxGridLineMemoryUsage (MgCoordinateSystemGridSpecification* specification)
+{
+    INT32 memoryUse (5000000);
+    INT32 lineSize;
+    INT32 lineCount;
+    INT32 gridCrsUnitCode;
+
+    double delta;
+    double increment;
+    double precision;
+    double eastMin, eastMax;
+    double northMin, northMax;
+
+    // We'll compute the number of grid lines which can be expected given the
+    // provided specification.  For now, we just make a guess at the size of
+    // each line based on the coordinate systems involved.
+    if (m_GridFrameCrsSame)
+    {
+        lineSize = sizeof (CCoordinateSystemGridLine) + sizeof (MgLineStringCollection) + 
+                                                        sizeof (MgLineString) +
+                                                        kMgSizeOfCoordinateXY * 2;
+    }
+    else
+    {
+        lineSize = sizeof (CCoordinateSystemGridLine) + sizeof (MgLineStringCollection) + 
+                                                        sizeof (MgLineString) * 2 +
+                                                        kMgSizeOfCoordinateXY * 511;
+    }
+
+    // TODO --> The folowing 40 or so lines of code are a cut and paste from
+    // the line generator code above.  This should be placed in a separate function
+    // to eliminate duplicate code.  For now, we jkust want to see how well all
+    // of this memory management stuff works.
+    MG_TRY ()
+        gridCrsUnitCode = m_GridCRS->GetUnitCode ();
+        CCoordinateSystemGridSpecification* mySpecPtr = dynamic_cast<CCoordinateSystemGridSpecification*>(specification);
+        precision = mySpecPtr->GetCurvePrecision (m_GridCRS);
+        // The following does not generate a boundary if it has already been
+        // generated.
+        GenerateGridBoundary (precision);
+
+        // Compute the range of the grid line generation.
+        m_GridBoundary->GetBoundaryExtents (eastMin,eastMax,northMin,northMax);
+        
+        // Expand the range to include all grid values at the extents.
+        increment = mySpecPtr->GetEastingIncrement(gridCrsUnitCode);
+        delta = fabs(fmod (eastMin,increment));
+        eastMin -= (eastMin >= 0.0) ? delta : (increment - delta);
+        delta = fabs(fmod (eastMax,increment));
+        eastMax += (eastMax >= 0.0) ? (increment - delta) : delta;
+ 
+        increment = mySpecPtr->GetNorthingIncrement(gridCrsUnitCode);
+        delta = fabs(fmod (northMin,increment));
+        northMin -= (northMin >= 0.0) ? delta : (increment - delta);
+        delta = fabs(fmod (northMax,increment));
+        northMax += (northMax >= 0.0) ? (increment - delta) : delta;
+
+        // Adjust for the base.  Again, we always enlarge, never shrink.
+        if (mySpecPtr->GetEastingBase () > 0.0)
+        {
+            increment = mySpecPtr->GetEastingIncrement (gridCrsUnitCode);
+            delta = fmod (mySpecPtr->GetEastingBase(gridCrsUnitCode),increment);
+            eastMin  += delta - increment;
+            eastMax  += delta + increment;
+        }
+        if (mySpecPtr->GetNorthingBase () > 0.0)
+        {
+            increment = mySpecPtr->GetNorthingIncrement (gridCrsUnitCode);
+            delta = fmod (mySpecPtr->GetNorthingBase(gridCrsUnitCode),increment);
+            northMin  += delta - increment;
+            northMax  += delta + increment;
+        }
+
+        // Compute the number of grid line objects we will need to create.
+        increment = mySpecPtr->GetEastingIncrement(gridCrsUnitCode);
+        lineCount = static_cast<INT32>(fabs (eastMax - eastMin) / increment);
+        increment = mySpecPtr->GetNorthingIncrement(gridCrsUnitCode);
+        lineCount += static_cast<INT32>(fabs (northMax - northMin) / increment);
+        memoryUse = lineCount * lineSize;
+    MG_CATCH_AND_RELEASE()
+    return memoryUse;
+}
+INT32 CCoordinateSystemOneGrid::ApproxGridTickMemoryUsage (MgCoordinateSystemGridSpecification* specification)
+{
+    return 10000;
+}
+
+INT32 CCoordinateSystemOneGrid::SetGridLineExceptionLevel (INT32 memoryUseMax)
+{
+    INT32 rtnValue = m_GridLineExceptionLevel;
+    if (memoryUseMax > 0L)
+    {
+        m_GridLineExceptionLevel = memoryUseMax;
+    }
+    return rtnValue;
+}
+INT32 CCoordinateSystemOneGrid::SetGridTickExceptionLevel (INT32 memoryUseMax)
+{
+    INT32 rtnValue = m_GridTickExceptionLevel;
+    if (memoryUseMax > 0L)
+    {
+        m_GridTickExceptionLevel = memoryUseMax;
+    }
+    return rtnValue;
+}
 MgCoordinateSystemGridBoundary* CCoordinateSystemOneGrid::GetFrameBoundary (void)
 {
     return SAFE_ADDREF (m_FrameBoundary.p);
@@ -442,6 +582,8 @@
     MG_TRY ()
         llCRS = csFactory.CreateFromCode (L"LL");
         llTransform = csFactory.GetTransform(m_FrameCRS,llCRS);
+        llTransform->IgnoreDatumShiftWarning (true);
+        llTransform->IgnoreOutsideDomainWarning (true);
         pPolygon = m_FrameBoundary->GetBoundary (llTransform,precision);
         llBoundary = csFactory.GridBoundary (pPolygon);
         llBoundary->GetBoundaryExtents (longMin,longMax,latMin,latMax);

Modified: sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysOneGrid.h
===================================================================
--- sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysOneGrid.h	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/CoordinateSystem/CoordSysOneGrid.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -40,6 +40,8 @@
 
 class CCoordinateSystemOneGrid : public MgGuardDisposable
 {
+    static const INT32 m_GridLineExceptionLevelK;
+    static const INT32 m_GridTickExceptionLevelK;
 public:
     static const INT32 MaxCurvePoints;
     CCoordinateSystemOneGrid (void);
@@ -54,6 +56,7 @@
 
     // Returns true if the grid coordinate system is geographic; use this to
     // determine if this is a graticule (as opposed to a grid).
+    bool GridFrameCrsAreTheSame ();
     bool IsGeographic (void);
     INT32 GetUserID (void);
     STRING GetLabel (void);
@@ -65,6 +68,12 @@
     MgCoordinateSystemGridLineCollection* GetGridLines (MgCoordinateSystemGridSpecification* specs);
     CCoordinateSystemGridTickCollection* GetBoundaryTicks (MgCoordinateSystemGridSpecification* specs);
 
+    INT32 ApproxGridLineMemoryUsage (MgCoordinateSystemGridSpecification* specification);
+    INT32 ApproxGridTickMemoryUsage (MgCoordinateSystemGridSpecification* specification);
+
+    INT32 SetGridLineExceptionLevel (INT32 memoryUseMax);
+    INT32 SetGridTickExceptionLevel (INT32 memoryUseMax);
+
 protected:
     MgCoordinateSystemGridBoundary* GetFrameBoundary (void);
     MgCoordinateSystem* GetFrameCRS (void);
@@ -76,9 +85,12 @@
     void GetGridExtents (double& eastMin,double& eastMax,double& northMin,double& northMax,double precision = 0.25);
     void Dispose (void);
 
+    bool m_GridFrameCrsSame;
     INT32 m_UserID;                                      // For user convenience (i.e. UTM zone)
     INT32 m_MaxCurvePoints;
     STRING m_Label;                                      // For user conveinence (i.e. MGRS)
+    INT32 m_GridLineExceptionLevel;
+    INT32 m_GridTickExceptionLevel;
     Ptr<MgCoordinateSystem> m_GridCRS;                   // The grid coordinate system
     Ptr<MgCoordinateSystem> m_FrameCRS;                  // The frame coordinate system
     Ptr<MgCoordinateSystemTransform> m_ToFrameXform;     // Converts grid coordinates to frame coordinates

Copied: sandbox/rfc60/MgDev/Common/Foundation/Exception/GridDensityException.cpp (from rev 4398, trunk/MgDev/Common/Foundation/Exception/GridDensityException.cpp)
===================================================================
--- sandbox/rfc60/MgDev/Common/Foundation/Exception/GridDensityException.cpp	                        (rev 0)
+++ sandbox/rfc60/MgDev/Common/Foundation/Exception/GridDensityException.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -0,0 +1,40 @@
+//
+//  Copyright (C) 2004-2009 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#include "Foundation.h"
+
+IMPLEMENT_EXCEPTION_DEFAULTS(MgGridDensityException, MgApplicationException)
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Construct a MgGridDensityException object.
+///
+MgGridDensityException::MgGridDensityException(CREFSTRING methodName,
+    INT32 lineNumber, CREFSTRING fileName, MgStringCollection* whatArguments,
+    CREFSTRING whyMessageId, MgStringCollection* whyArguments) throw() :
+    MgApplicationException(methodName, lineNumber, fileName,
+        whatArguments, whyMessageId, whyArguments)
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Destruct the MgGridDensityException object.
+///
+MgGridDensityException::~MgGridDensityException() throw()
+{
+}

Copied: sandbox/rfc60/MgDev/Common/Foundation/Exception/GridDensityException.h (from rev 4398, trunk/MgDev/Common/Foundation/Exception/GridDensityException.h)
===================================================================
--- sandbox/rfc60/MgDev/Common/Foundation/Exception/GridDensityException.h	                        (rev 0)
+++ sandbox/rfc60/MgDev/Common/Foundation/Exception/GridDensityException.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -0,0 +1,71 @@
+//
+//  Copyright (C) 2004-2009 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+/// \ingroup Exceptions_Module
+
+#ifndef MG_GRID_DENSITY_EXCEPTION_H_
+#define MG_GRID_DENSITY_EXCEPTION_H_
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Thrown when an error occurs in a date/time routine.
+///
+class MG_FOUNDATION_API MgGridDensityException : public MgApplicationException
+{
+    DECLARE_CLASSNAME(MgGridDensityException)
+
+EXTERNAL_API:
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Construct a MgGridDensityException object.
+    ///
+    /// \param methodName
+    /// Name of the method where the exception occurred.
+    /// \param lineNumber
+    /// Line number where the exception occurred.
+    /// \param fileName
+    /// File name where the exception occurred.
+    /// \param whatArguments
+    /// Collection of arguments used to format the message that describes what the exception is.
+    /// \param whyMessageId
+    /// ID of the message that describes why the exception occurs.
+    /// \param whyArguments
+    /// Collection of arguments used to format the message that describes why the exception occurs.
+    /// \param thirdPartyMessage
+    /// Exception message from the third party component
+    ///
+    MgGridDensityException(CREFSTRING methodName, INT32 lineNumber,
+        CREFSTRING fileName, MgStringCollection* whatArguments,
+        CREFSTRING whyMessageId, MgStringCollection* whyArguments) throw();
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Destruct the MgGridDensityException object.
+    ///
+    virtual ~MgGridDensityException() throw();
+
+INTERNAL_API:
+
+    DECLARE_EXCEPTION_DEFAULTS(MgGridDensityException)
+
+CLASS_ID:
+
+    static const INT32 m_cls_id = Foundation_Exception_MgGridDensityException;
+};
+
+#endif

Modified: sandbox/rfc60/MgDev/Common/Foundation/Foundation.h
===================================================================
--- sandbox/rfc60/MgDev/Common/Foundation/Foundation.h	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Foundation/Foundation.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -147,6 +147,7 @@
 #include "Exception/DuplicateObjectException.h"
 #include "Exception/EncryptionException.h"
 #include "Exception/FileNotFoundException.h"
+#include "Exception/GridDensityException.h"
 #include "Exception/IndexOutOfRangeException.h"
 #include "Exception/InvalidArgumentException.h"
 #include "Exception/InvalidCastException.h"

Modified: sandbox/rfc60/MgDev/Common/Foundation/Foundation.vcproj
===================================================================
--- sandbox/rfc60/MgDev/Common/Foundation/Foundation.vcproj	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Foundation/Foundation.vcproj	2009-12-09 22:21:34 UTC (rev 4405)
@@ -1073,6 +1073,46 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Exception\GridDensityException.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\Exception\GridDensityException.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Exception\IndexOutOfRangeException.cpp"
 				>
 				<FileConfiguration

Modified: sandbox/rfc60/MgDev/Common/Foundation/FoundationBuild.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/Foundation/FoundationBuild.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Foundation/FoundationBuild.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -52,6 +52,7 @@
 #include "Exception/Exception.cpp"
 #include "Exception/FileIoException.cpp"
 #include "Exception/FileNotFoundException.cpp"
+#include "Exception/GridDensityException.cpp"
 #include "Exception/IndexOutOfRangeException.cpp"
 #include "Exception/InvalidArgumentException.cpp"
 #include "Exception/InvalidCastException.cpp"

Modified: sandbox/rfc60/MgDev/Common/Foundation/Makefile.am
===================================================================
--- sandbox/rfc60/MgDev/Common/Foundation/Makefile.am	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Foundation/Makefile.am	2009-12-09 22:21:34 UTC (rev 4405)
@@ -41,6 +41,7 @@
   Exception/Exception.cpp \
   Exception/FileIoException.cpp \
   Exception/FileNotFoundException.cpp \
+  Exception/GridDensityException.cpp \
   Exception/IndexOutOfRangeException.cpp \
   Exception/InvalidArgumentException.cpp \
   Exception/InvalidCastException.cpp \
@@ -144,6 +145,7 @@
   Exception/ExceptionDefs.h \
   Exception/FileIoException.h \
   Exception/FileNotFoundException.h \
+  Exception/GridDensityException.h \
   Exception/IndexOutOfRangeException.h \
   Exception/InvalidArgumentException.h \
   Exception/InvalidCastException.h \

Modified: sandbox/rfc60/MgDev/Common/Foundation/System/FoundationClassId.h
===================================================================
--- sandbox/rfc60/MgDev/Common/Foundation/System/FoundationClassId.h	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Foundation/System/FoundationClassId.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -94,6 +94,7 @@
 #define Foundation_Exception_MgUnderflowException                               FOUNDATION_EXCEPTION_ID+48
 #define Foundation_Exception_MgXmlException                                     FOUNDATION_EXCEPTION_ID+49
 #define Foundation_Exception_MgXmlParserException                               FOUNDATION_EXCEPTION_ID+50
+#define Foundation_Exception_MgGridDensityException                             FOUNDATION_EXCEPTION_ID+51
 
 // Foundation Property
 

Modified: sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemCommon.h
===================================================================
--- sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemCommon.h	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemCommon.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -52,6 +52,7 @@
 #include "CoordinateSystemProjectionFormatType.h"           //for MgCoordinateSystemProjectionFormatType
 #include "CoordinateSystemProjectionParameterType.h"        //for MgCoordinateSystemProjectionParameterType
 #include "CoordinateSystemErrorCode.h"                      //for MgCoordinateSystemErrorCode
+#include "CoordinateSystemMgrsGridSquarePosition.h"         //for MgCoordinateSystemMgrsGridSquarePosition
 #include "CoordinateSystemMgrs.h"                           //for MgCoordinateSystemMgrs
 #include "CoordinateSystemMgrsLetteringScheme.h"            //for MgCoordinateSystemMgrsLetteringScheme
 

Modified: sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemErrorCode.h
===================================================================
--- sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemErrorCode.h	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemErrorCode.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -92,6 +92,7 @@
     static const INT32 InitializationFailed = 1002;
     static const INT32 ConversionFailed     = 1003;
     static const INT32 NullArgument         = 1004;
+    static const INT32 InvalidArgument      = 1005;
 };
 /// \}
 

Modified: sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemGrids.h
===================================================================
--- sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemGrids.h	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemGrids.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -460,6 +460,39 @@
 
     ///////////////////////////////////////////////////////////////////////////
     /// \brief
+    /// Sets the maximum number of points to generate for a complex curve
+    /// approximation.
+    ///
+    /// <!-- Syntax in .Net, Java, and PHP -->
+    /// \htmlinclude DotNetSyntaxTop.html
+    /// virtual void SetMaxCurvePoints (double curvePrecision);
+    /// \htmlinclude SyntaxBottom.html
+    /// \htmlinclude JavaSyntaxTop.html
+    /// virtual void SetMaxCurvePoints (double curvePrecision);
+    /// \htmlinclude SyntaxBottom.html
+    /// \htmlinclude PHPSyntaxTop.html
+    /// virtual void SetMaxCurvePoints (double curvePrecision);
+    /// \htmlinclude SyntaxBottom.html
+    ///
+    /// \param maxCurvePoints (INT32)
+    /// The desired maximum number of points to be generated for a complex
+    /// curve approximation.  Default is 511.
+    ///
+    /// \remarks
+    /// Generating a grid line of one coordinate system in the model space
+    /// based on another coordinate system requires that an approximation
+    /// of the complex curve be generated by a series of straight line
+    /// segments.  Use this value to limit the number of points generated
+    /// to a specific value.  The traditional, and default, value is 511.
+    /// Large values will significantly increase memeory usage and reduce
+    /// performance.  Using a smaller value is an easy way to reduce
+    /// memory consumption.
+    ///
+    virtual void SetMaxCurvePoints (INT32 maxCurvePoints) = 0;
+
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
     /// Checks the internal contents of the object for consistency.
     ///
     /// <!-- Syntax in .Net, Java, and PHP -->
@@ -696,6 +729,26 @@
     virtual double GetConvergenceAngle (MgCoordinate* location) = 0;
     virtual double GetProjectiveGridScale (MgCoordinate* location) = 0;
 
+    // The following may be used to determine if a specific grid generation
+    // should be attempted.  The returned values are approximate and is in bytes.
+    // The proposed grid boundary for the grid object hosting this interface must
+    // set prior to calling this function.  Failure to do so will cause a -1
+    // return value.
+    virtual INT32 ApproxGridLineMemoryUsage (MgCoordinateSystemGridSpecification* specification) = 0;
+    virtual INT32 ApproxGridRegionMemoryUsage (MgCoordinateSystemGridSpecification* specification) = 0;
+    virtual INT32 ApproxGridTickMemoryUsage (MgCoordinateSystemGridSpecification* specification) = 0;
+
+    // Each grid object establishes a hard coded value and will throw an exception
+    // before generating a grid which, accordinag to the grid object estimates, will
+    // cause memory usage to exceed the hard coded value.  Use the following functions
+    // to modify the threshold for the exception.  Such modification remains in effect
+    // only within the existence of the modified object.
+    // These functions return the previous value and make no changes if the argument
+    // value is less than 10MB.  The memoryUseMax argument is always in bytes.
+    virtual INT32 SetGridLineExceptionLevel (INT32 memoryUseMax) = 0;
+    virtual INT32 SetGridRegionExceptionLevel (INT32 memoryUseMax) = 0;
+    virtual INT32 SetGridTickExceptionLevel (INT32 memoryUseMax) = 0;
+
     virtual INT32 GetLastError() = 0;
     virtual void ResetLastError()= 0;
     virtual bool AreExceptionsOn() = 0;
@@ -723,6 +776,7 @@
     virtual MgLineStringCollection* GetSegmentCollection(void)= 0;
     virtual void SetSegmentCollection (MgLineStringCollection* segmentCollection) = 0;
 INTERNAL_API:
+    virtual INT32 GetMemoryUsage (void) = 0;
 protected:
     INT32 GetClassId(){return m_cls_id;};
 CLASS_ID:
@@ -750,6 +804,7 @@
     virtual MgLineStringCollection* GetWestLine (void) = 0;
 
 INTERNAL_API:
+    virtual INT32 GetMemoryUsage (void) = 0;
 protected:
     INT32 GetClassId(){return m_cls_id;};
 CLASS_ID:
@@ -773,6 +828,7 @@
     virtual MgCoordinate* GetPosition () = 0;
     virtual MgCoordinate* GetDirectionVector () = 0;
 INTERNAL_API:
+    virtual INT32 GetMemoryUsage (void) = 0;
 protected:
     INT32 GetClassId(){return m_cls_id;};
 CLASS_ID:
@@ -797,6 +853,7 @@
     virtual void SetItem (INT32 index, MgCoordinateSystemGridLine* value)=0;
     virtual void Add (MgCoordinateSystemGridLine* value)=0;
     virtual void AddCollection (MgCoordinateSystemGridLineCollection* aGridLineCollection)=0;
+    virtual INT32 GetMemoryUsage (void) = 0;
 
 protected:
     INT32 GetClassId(){return m_cls_id;};
@@ -817,6 +874,8 @@
 INTERNAL_API:
     virtual void SetItem (INT32 index, MgCoordinateSystemGridRegion* value)=0;
     virtual void Add (MgCoordinateSystemGridRegion* value)=0;
+    virtual INT32 GetMemoryUsage (void) = 0;
+
 protected:
     INT32 GetClassId(){return m_cls_id;};
 CLASS_ID:
@@ -838,6 +897,8 @@
 INTERNAL_API:
     virtual void SetItem (INT32 index, MgCoordinateSystemGridTick* value)=0;
     virtual void Add (MgCoordinateSystemGridTick* value)=0;
+    virtual INT32 GetMemoryUsage (void) = 0;
+
 protected:
     INT32 GetClassId(){return m_cls_id;};
 CLASS_ID:

Modified: sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemMgrs.h
===================================================================
--- sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemMgrs.h	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemMgrs.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -76,11 +76,25 @@
     /// The MGRS string to be converted.
     /// /returns
     /// The geographic coordinates of the location identified by the provided
-    /// MGRS string.
+    /// MGRS string (center of the grid sqaure).
     virtual MgCoordinate* ConvertToLonLat(CREFSTRING sMgrs)=0;
 
     ///////////////////////////////////////////////////////////////////////////
     /// /brief
+    /// Converts an MGRS string to geographic coordinates.
+    /// /param sMgrs
+    /// The MGRS string to be converted.
+    /// /param grdSqrPosition
+    /// A value from the MgCoordinateSystemMgrsGridSquarePosition enumeration
+    /// which indicates the position within the grid sqaure referenced by
+    /// the sMgrs argumjent which is to be returned.
+    /// /returns
+    /// The geographic coordinates of the location identified by the provided
+    /// MGRS string.
+    virtual MgCoordinate* ConvertToLonLat(CREFSTRING sMgrs, INT32 grdSqrPosition)=0;
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// /brief
     /// Returns a value as defined by the MgCoordinateSystemMgrsLetteringScheme
     /// object indicating which lettering scheme is currently active.
     /// /returns
@@ -92,7 +106,7 @@
     //section that reads/writes MGRS coordinates
     virtual INT32 ConvertFromLonLat(double dLongitude, double dLatitude, INT32 nPrecision, REFSTRING sMgrs)=0;
     virtual INT32 ConvertFromLonLat(MgCoordinate* pLonLat, INT32 nPrecision, REFSTRING sMgrs)=0;
-    virtual INT32 ConvertToLonLat(CREFSTRING sMgrs, MgCoordinate* pLonLat)=0;
+    virtual INT32 ConvertToLonLat(CREFSTRING sMgrs, MgCoordinate* pLonLat, INT32 grdSqrPosition)=0;
 
 protected:
     INT32 GetClassId(){return m_cls_id;};

Copied: sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemMgrsGridSquarePosition.h (from rev 4398, trunk/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemMgrsGridSquarePosition.h)
===================================================================
--- sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemMgrsGridSquarePosition.h	                        (rev 0)
+++ sandbox/rfc60/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemMgrsGridSquarePosition.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -0,0 +1,83 @@
+//
+//  Copyright (C) 2004-2009 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef _MGCOORDINATESYSTEMMGRSGRIDSQUAREPOSITION_H_
+#define _MGCOORDINATESYSTEMMGRSGRIDSQUAREPOSITION_H_
+
+///////////////////////////////////////////////////////////////////////////////
+///<summary>
+/// MgCoordinateSystemMgrsGridSquarePosition defines enumerated values used to
+/// specify the the location desired relative to the subject MGRS grid sqaure
+/// when evaluating an MGRS string.
+///
+/// Note that the values used in this enumeration match those used by the
+// CS-MAP interface.
+///</summary>
+class MG_GEOMETRY_API MgCoordinateSystemMgrsGridSquarePosition
+{
+    // MENTOR_MAINTENANCE --> These enumeration values are assumed to be the
+    // same as those used by CS-MAP.
+public:
+    ///////////////////////////////////////////////////////////////////////////
+    ///<summary>
+    /// Specifies the grid square position is not set as yet.
+    ///</summary>
+    static const INT32 None = 0;
+    ///<summary>
+    /// Specifies the center of the grid square; the default previous to this
+    /// reivison (Dec 2009).
+    ///</summary>
+    static const INT32 Center = 1;
+    ///<summary>
+    /// Specifies the southwest corner of the MGRS grid square.
+    ///</summary>
+    static const INT32 SouthWest = 2;
+    ///<summary>
+    /// Specifies the midpoint of the western edge of the MGRS grid square.
+    ///</summary>
+    static const INT32 West = 3;
+    ///<summary>
+    /// Specifies the northwest corner of the MGRS grid square.
+    ///</summary>
+    static const INT32 NorthWest = 4;
+    ///<summary>
+    /// Specifies the midpoint of the northern edge of the MGRS grid square.
+    ///</summary>
+    static const INT32 North = 5;
+    ///<summary>
+    /// Specifies the southwest corner of the MGRS grid square.
+    ///</summary>
+    static const INT32 NorthEast = 6;
+    ///<summary>
+    /// Specifies the midpoint of the eastern edge of the MGRS grid square.
+    ///</summary>
+    static const INT32 East = 7;
+    ///<summary>
+    /// Specifies the southeast corner of the MGRS grid square.
+    ///</summary>
+    static const INT32 SouthEast = 8;
+    ///<summary>
+    /// Specifies the midpoint of the southern edge of the MGRS grid square.
+    ///</summary>
+    static const INT32 South = 9;
+    ///<summary>
+    /// Specifies an error return value, end of table, or other abnormal situation.
+    ///</summary>
+    static const INT32 Unknown = 10;
+};
+
+#endif //_MGCOORDINATESYSTEMMGRSGRIDSQUAREPOSITION_H_

Modified: sandbox/rfc60/MgDev/Common/Geometry/Geometry.vcproj
===================================================================
--- sandbox/rfc60/MgDev/Common/Geometry/Geometry.vcproj	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Geometry/Geometry.vcproj	2009-12-09 22:21:34 UTC (rev 4405)
@@ -2929,10 +2929,6 @@
 				>
 			</File>
 			<File
-				RelativePath="..\CoordinateSystem\CoordSysMgrsGridScale.h"
-				>
-			</File>
-			<File
 				RelativePath="..\CoordinateSystem\CoordSysMgrsZone.cpp"
 				>
 			</File>
@@ -3302,6 +3298,10 @@
 			>
 		</File>
 		<File
+			RelativePath=".\CoordinateSystem\CoordinateSystemMgrsGridSquarePosition.h"
+			>
+		</File>
+		<File
 			RelativePath=".\CoordinateXY.cpp"
 			>
 			<FileConfiguration
@@ -3462,6 +3462,14 @@
 			>
 		</File>
 		<File
+			RelativePath="..\CoordinateSystem\CoordSysMgrsMajorRegion.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\CoordinateSystem\CoordSysMgrsMajorRegion.h"
+			>
+		</File>
+		<File
 			RelativePath="..\CoordinateSystem\CoordSysWktFailureCache.cpp"
 			>
 		</File>

Modified: sandbox/rfc60/MgDev/Common/Geometry/GeometryCommon.h
===================================================================
--- sandbox/rfc60/MgDev/Common/Geometry/GeometryCommon.h	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Geometry/GeometryCommon.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -145,6 +145,7 @@
 #include "CoordinateSystem/CoordinateSystemGridGeneric.h"                   //for MgCoordinateSystemGridGeneric
 #include "CoordinateSystem/CoordinateSystemMgrsGridLevel.h"                 //for MgCoordinateSystemMgrsGridLevel
 #include "CoordinateSystem/CoordinateSystemMgrsLetteringScheme.h"           //for MgCoordinateSystemMgrsLetteringScheme
+#include "CoordinateSystem/CoordinateSystemMgrsGridSquarePosition.h"        //for MgCoordinateSystemMgrsGridSquarePosition
 #include "CoordinateSystem/CoordinateSystemMgrs.h"                          //for MgCoordinateSystemMgrs
 #include "CoordinateSystem/CoordinateSystemFactory.h"
 

Modified: sandbox/rfc60/MgDev/Common/Geometry/Makefile.am
===================================================================
--- sandbox/rfc60/MgDev/Common/Geometry/Makefile.am	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Geometry/Makefile.am	2009-12-09 22:21:34 UTC (rev 4405)
@@ -38,6 +38,7 @@
   ../CoordinateSystem/CoordSysGrids.cpp \
   ../CoordinateSystem/CoordSysMgrsZone.cpp \
   ../CoordinateSystem/CoordSysMgrs.cpp \
+  ../CoordinateSystem/CoordSysMgrsMajorRegion.cpp \
   ../CoordinateSystem/CoordSysOneGrid.cpp
 
 include_SOURCES = \
@@ -173,6 +174,7 @@
   ../CoordinateSystem/CoordSysGrids.cpp \
   ../CoordinateSystem/CoordSysMgrsZone.cpp \
   ../CoordinateSystem/CoordSysMgrs.cpp \
+  ../CoordinateSystem/CoordSysMgrsMajorRegion.cpp \
   ../CoordinateSystem/CoordSysOneGrid.cpp
 
 noinst_HEADERS = $(include_SOURCES) \
@@ -325,6 +327,7 @@
   CoordinateSystem/CoordinateSystemGrids.h \
   CoordinateSystem/CoordinateSystemGridGeneric.h \
   CoordinateSystem/CoordinateSystemMgrsGridLevel.h \
+  CoordinateSystem/CoordinateSystemMgrsGridSquarePosition.h \
   CoordinateSystem/CoordinateSystemMgrsLetteringScheme.h \
   CoordinateSystem/CoordinateSystemMgrs.h \
   Exception/CoordinateSystemComputationFailedException.h \
@@ -385,7 +388,9 @@
   ../CoordinateSystem/CoordSysGrids.h \
   ../CoordinateSystem/CoordSysMgrsZone.h \
   ../CoordinateSystem/CoordSysMgrs.h \
-  ../CoordinateSystem/CoordSysOneGrid.h
+  ../CoordinateSystem/CoordSysMgrsMajorRegion.h \
+  ../CoordinateSystem/CoordSysOneGrid.h\
+  ../CoordinateSystem/CoordSysEnvVariable.h
 
 INCLUDES = \
   -I../Security \

Modified: sandbox/rfc60/MgDev/Common/Geometry/Spatial/SpatialUtility.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/Geometry/Spatial/SpatialUtility.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Geometry/Spatial/SpatialUtility.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -528,7 +528,9 @@
                                                                   MgCoordinate* seg2From,
                                                                   MgCoordinate* seg2To)
 {
-    INT32 status (-7);          // until we know different.
+    bool preciseFrom;
+    bool preciseTo;
+    INT32 status (-1);          // until we know different.
 
     double delX1, delY1;
     double delX2, delY2;
@@ -574,13 +576,14 @@
         if (fabs (delX1) > fabs (delY1))
         {
             // Segment one is more horizontal than vertical. We will use the X
-            // value to test if the resulting point is on the segment.  Notice
-            // that an interscetion point which resides (relatively) precisely
-            // on the 'to' point is not considered to be on the segment.
+            // value to test if the resulting point is on the segment.
+            preciseFrom = MgMathUtility::DblCmp (result->GetX(),seg1From->GetX());
+            preciseTo = MgMathUtility::DblCmp (result->GetX(),seg1To->GetX());
             if (delX1 >= 0.0)
             {
                 // X increases from the 'from' point to the 'to' point.
-                if (result->GetX() > seg1From->GetX() && result->GetX() <= seg1To->GetX())
+                if ((result->GetX() >= seg1From->GetX() || preciseFrom) &&
+                    (result->GetX() <= seg1To->GetX()  || preciseTo))
                 {
                     status |= 1;
                 }
@@ -588,20 +591,32 @@
             else
             {
                 // X decreases from the 'from' point to the 'to' point.
-                if (result->GetX() < seg1From->GetX() && result->GetX() >= seg1To->GetX())
+                if ((result->GetX() <= seg1From->GetX() || preciseFrom) &&
+                    (result->GetX() >= seg1To->GetX()   || preciseTo)) 
                 {
                     status |= 1;
                 }
             }
+            if (preciseFrom)
+            {
+                status |= 4;
         }
+            if (preciseTo)
+            {
+                status |= 8;
+            }
+        }
         else
         {
-            // First segment is more verical than horizontal. We will use the y
+            // First segment is more vertical than horizontal. We will use the Y
             // value to test if the resulting point is on the segment.
+            preciseFrom = MgMathUtility::DblCmp (result->GetY(),seg1From->GetY());
+            preciseTo = MgMathUtility::DblCmp (result->GetY(),seg1To->GetY());
             if (delY1 >= 0.0)
             {
                 // Y increases from the 'from' point to the 'to' point.
-                if (result->GetY() > seg1From->GetY() && result->GetY() <= seg1To->GetY())
+                if ((result->GetY() >= seg1From->GetY() || preciseFrom) &&
+                    (result->GetY() <= seg1To->GetY()   || preciseTo))
                 {
                     status |= 1;
                 }
@@ -609,49 +624,82 @@
             else
             {
                 // Y increases from the 'from' point to the 'to' point.
-                if (result->GetY() < seg1From->GetY() && result->GetY() >= seg1To->GetY())
+                if ((result->GetY() <= seg1From->GetY() || preciseFrom) &&
+                    (result->GetY() >= seg1To->GetY()   || preciseTo))
                 {
                     status |= 1;
                 }
             }
+            if (preciseFrom)
+            {
+                status |= 4;
         }
+            if (preciseTo)
+            {
+                status |= 8;
+            }
+        }
 
         // Same stuff with the second segment, sans comments.
         if (fabs (delX2) > fabs (delY2))
         {
+            preciseFrom = MgMathUtility::DblCmp (result->GetX(),seg2From->GetX());
+            preciseTo = MgMathUtility::DblCmp (result->GetX(),seg2To->GetX());
             if (delX2 >= 0.0)
             {
-                if (result->GetX() > seg2From->GetX() && result->GetX() <= seg2To->GetX())
+                if ((result->GetX() >= seg2From->GetX() || preciseFrom) &&
+                    (result->GetX() <= seg2To->GetX()   || preciseTo))
                 {
                     status |= 2;
                 }
             }
             else
             {
-                if (result->GetX() < seg2From->GetX() && result->GetX() >= seg2To->GetX())
+                if ((result->GetX() <= seg2From->GetX() || preciseFrom) &&
+                    (result->GetX() >= seg2To->GetX()   || preciseTo))
                 {
                     status |= 2;
                 }
             }
+            if (preciseFrom)
+            {
+                status |= 16;
         }
+            if (preciseTo)
+            {
+                status |= 32;
+            }
+        }
         else
         {
+            preciseFrom = MgMathUtility::DblCmp (result->GetY(),seg2From->GetY());
+            preciseTo = MgMathUtility::DblCmp (result->GetY(),seg2To->GetY());
             if (delY2 >= 0.0)
             {
-                if (result->GetY() > seg2From->GetY() && result->GetY() <= seg2To->GetY())
+                if ((result->GetY() >= seg2From->GetY() || preciseFrom) &&
+                    (result->GetY() <= seg2To->GetY()   || preciseTo))
                 {
                     status |= 2;
                 }
             }
             else
             {
-                if (result->GetY() < seg2From->GetY() && result->GetY() >= seg2To->GetY())
+                if ((result->GetY() <= seg2From->GetY() || preciseFrom) &&
+                    (result->GetY() >= seg2To->GetY()   || preciseTo))
                 {
                     status |= 2;
                 }
             }
+            if (preciseFrom)
+            {
+                status |= 16;
         }
+            if (preciseTo)
+            {
+                status |= 32;
     }
+        }
+    }
     return status;
 }
 
@@ -695,11 +743,21 @@
         polyFrom = polyTo;
         polyTo = polyItr->GetCurrent ();
         status = SegmentIntersection (intersection,polyFrom,polyTo,segFrom,segTo);
-        if (status == 3)
+        
+        // If the intersection is precisely on the 'From' point of the polygon segment,
+        // we're not interested.  It will show up again when that point becomes a
+        // 'To' point on the polygon.
+        if ((status & 4) == 4)
         {
-            // We have an intersection of interest to us.  We need to add a
-            // point which will still be on the heap when we are done, so we
-            // definitely do not want to add the intersection point.
+            continue;
+        }
+        if ((status & 3) == 3)
+        {
+            // We have an intersection of interest to us.  That is, an intersection
+            // point which resides on both lines, but not presisely on the 'From"
+            // point of the polygon segment.  We need to add a point which will still
+            // be on the heap when we are done, so we definitely do not want to add
+            // the intersection point.
             Ptr<MgCoordinate> newPoint = new MgCoordinateXY (intersection->GetX(),intersection->GetY());
             insertIndex = AddToCoordinateCollection (coordinateCollection,newPoint,segFrom);
             if (insertIndex != 0)

Modified: sandbox/rfc60/MgDev/Common/MapGuideCommon/MapLayer/Layer.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/MapGuideCommon/MapLayer/Layer.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/MapGuideCommon/MapLayer/Layer.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -178,6 +178,7 @@
     }
     helper->WriteString(m_featureSourceId);
     helper->WriteString(m_featureName);
+    helper->WriteString(m_filter);
     helper->WriteString(m_schemaName);
     helper->WriteString(m_geometry);
 
@@ -227,6 +228,7 @@
 
     helper->GetString(m_featureSourceId);
     helper->GetString(m_featureName);
+    helper->GetString(m_filter);
     helper->GetString(m_schemaName);
     helper->GetString(m_geometry);
 

Modified: sandbox/rfc60/MgDev/Common/MapGuideCommon/Services/ProxyResourceService.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/MapGuideCommon/Services/ProxyResourceService.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/MapGuideCommon/Services/ProxyResourceService.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -617,7 +617,7 @@
         MgResourceService::opIdGetResourceContents,     // Command Code
         2,                                              // Count of arguments
         Resource_Service,                               // Service Id
-        BUILD_VERSION(1,0,0),                           // Operation version
+        BUILD_VERSION(2,2,0),                           // Operation version
         MgCommand::knObject, resources,                 // Argument#1
         MgCommand::knObject, preProcessTags,            // Argument#2
         MgCommand::knNone);                             // End of argument

Modified: sandbox/rfc60/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -258,6 +258,8 @@
 const INT32  MgConfigProperties::DefaultFeatureServicePropertyDataConnectionTimerInterval   = 60;
 const STRING MgConfigProperties::FeatureServicePropertyJoinQueryBatchSize                   = L"JoinQueryBatchSize";
 const INT32  MgConfigProperties::DefaultFeatureServicePropertyJoinQueryBatchSize            = 100;
+const STRING MgConfigProperties::FeatureServicePropertyDataConnectionUseLimit               = L"DataConnectionUseLimit";
+const STRING MgConfigProperties::DefaultFeatureServicePropertyDataConnectionUseLimit        = L"";
 const STRING MgConfigProperties::FeatureServicePropertyDataTransactionTimeout               = L"DataTransactionTimeout";
 const INT32  MgConfigProperties::DefaultFeatureServicePropertyDataTransactionTimeout        = 360;
 const STRING MgConfigProperties::FeatureServicePropertyDataTransactionTimerInterval         = L"DataTransactionTimerInterval";
@@ -570,6 +572,7 @@
     { MgConfigProperties::FeatureServicePropertyDataConnectionTimeout               , MgPropertyType::Int32     , MG_CONFIG_MIN_TIMEOUT                 , MG_CONFIG_MAX_TIMEOUT                 , L""                                       },
     { MgConfigProperties::FeatureServicePropertyDataConnectionTimerInterval         , MgPropertyType::Int32     , MG_CONFIG_MIN_TIMER_INTERVAL          , MG_CONFIG_MAX_TIMER_INTERVAL          , L""                                       },
     { MgConfigProperties::FeatureServicePropertyJoinQueryBatchSize                  , MgPropertyType::Int32     , MG_CONFIG_MIN_JOIN_QUERY_BATCH_SIZE   , MG_CONFIG_MAX_JOIN_QUERY_BATCH_SIZE   , L""                                       },
+    { MgConfigProperties::FeatureServicePropertyDataConnectionUseLimit              , MgPropertyType::String    , MG_CONFIG_MIN_FS_CP_EXCLUDED_LENGTH   , MG_CONFIG_MAX_FS_CP_EXCLUDED_LENGTH   , L""                                       },
     { MgConfigProperties::FeatureServicePropertyDataTransactionTimeout              , MgPropertyType::Int32     , MG_CONFIG_MIN_TIMEOUT                 , MG_CONFIG_MAX_TIMEOUT                 , L""                                       },
     { MgConfigProperties::FeatureServicePropertyDataTransactionTimerInterval        , MgPropertyType::Int32     , MG_CONFIG_MIN_TIMER_INTERVAL          , MG_CONFIG_MAX_TIMER_INTERVAL          , L""                                       },
     { L""                                                                           , 0                         , 0.0                                   , 0.0                                   , L""                                       }

Modified: sandbox/rfc60/MgDev/Common/MapGuideCommon/System/ConfigProperties.h
===================================================================
--- sandbox/rfc60/MgDev/Common/MapGuideCommon/System/ConfigProperties.h	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/MapGuideCommon/System/ConfigProperties.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -311,6 +311,10 @@
     static const STRING FeatureServicePropertyJoinQueryBatchSize;               /// value("JoinQueryBatchSize")
     static const INT32 DefaultFeatureServicePropertyJoinQueryBatchSize;         /// value(100)
 
+    /// Sets the number of uses for a FDO connection for a specific provider before it is released
+    static const STRING FeatureServicePropertyDataConnectionUseLimit;         /// value("DataConnectionUseLimit")
+    static const STRING DefaultFeatureServicePropertyDataConnectionUseLimit;  /// value("")
+
     /// Sets the maximum amount of time (in seconds) for an idle FDO transaction before the transaction is dropped
     static const STRING FeatureServicePropertyDataTransactionTimeout;            /// value("DataTransactionTimeout")
     static const INT32 DefaultFeatureServicePropertyDataTransactionTimeout;      /// value(360)

Modified: sandbox/rfc60/MgDev/Common/PlatformBase/Services/FeatureReader.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/PlatformBase/Services/FeatureReader.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/PlatformBase/Services/FeatureReader.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -68,8 +68,17 @@
     Ptr<MgPropertyDefinitionCollection> propDefCol = classDef->GetProperties();
     CHECKNULL((MgPropertyDefinitionCollection*)propDefCol, L"MgFeatureReader.GetPropertyIndex");
 
-    return propDefCol->IndexOf(propertyName);
+    INT32 index = propDefCol->IndexOf(propertyName);
+    if (-1 != index)
+    {
+        return index;
 }
+    else
+    {
+        throw new MgObjectNotFoundException(L"MgFeatureReader.GetPropertyIndex", __LINE__, __WFILE__, NULL, L"", NULL);
+        return -1; // to suppress compiler warning.
+    }
+}
 
 //////////////////////////////////////////////////////////////////
 /// <summary>

Modified: sandbox/rfc60/MgDev/Common/Renderers/KmlRenderer.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/Renderers/KmlRenderer.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Renderers/KmlRenderer.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -764,7 +764,7 @@
     RS_FillStyle fs;
     RS_MarkerDef mdef(RS_MarkerType_Marker, 1.0, 1.0, 0.5, 0.5, 0.0, RS_Units_Device, SLDType_Square, L"", L"", fs);
 
-    ProcessMarker(ctx->geometry, mdef, !style->addToExclusionRegions, bounds);
+    ProcessMarker(ctx->geometry, mdef, !style->addToExclusionRegion, bounds);
 }
 
 

Modified: sandbox/rfc60/MgDev/Common/Stylization/ExpressionFunctionIf.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/Stylization/ExpressionFunctionIf.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Stylization/ExpressionFunctionIf.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -146,10 +146,14 @@
                     FdoPtr<FdoFilter> filter = FdoFilter::Parse(condString);
                     condition = m_engine->ProcessFilter(filter);
                 }
-                catch (FdoException*) { } // value remains false
+                catch (FdoException* e)
+                {
+                    e->Release();
+                    // value remains false
             }
         }
     }
+    }
 
     // return the literal indicated by the condition
     return condition? literalValues->GetItem(1) : literalValues->GetItem(2);

Modified: sandbox/rfc60/MgDev/Common/Stylization/SE_PositioningAlgorithms.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/Stylization/SE_PositioningAlgorithms.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Stylization/SE_PositioningAlgorithms.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -473,7 +473,8 @@
         SE_RenderText* rt = (SE_RenderText*)rstyle->symbol[0];
 
         RS_LabelInfo info(0.0, 0.0, 0.0, 0.0, RS_Units_Device, rt->tdef);
-        return se_renderer->ProcessLabelGroup(&info, 1, rt->content, RS_OverpostType_AllFit, rstyle->addToExclusionRegions, geometry, 0.5);
+        RS_OverpostType overpostType = rstyle->checkExclusionRegion? RS_OverpostType_AllFit : RS_OverpostType_All;
+        return se_renderer->ProcessLabelGroup(&info, 1, rt->content, overpostType, rstyle->addToExclusionRegion, geometry, 0.5);
     }
 
     se_renderer->ProcessLineLabels(geometry, (SE_RenderLineStyle*)rstyle);
@@ -716,14 +717,15 @@
                         SE_RenderStyle* clonedStyle = se_renderer->CloneRenderStyle(rlStyle);
 
                         SE_LabelInfo info(symxf.x2, symxf.y2, RS_Units_Device, angleRad, clonedStyle);
-                        se_renderer->ProcessSELabelGroup(&info, 1, RS_OverpostType_AllFit, rlStyle->addToExclusionRegions, geometry);
+                        RS_OverpostType overpostType = rlStyle->checkExclusionRegion? RS_OverpostType_AllFit : RS_OverpostType_All;
+                        se_renderer->ProcessSELabelGroup(&info, 1, overpostType, rlStyle->addToExclusionRegion, geometry);
                     }
                     else
                     {
                         se_renderer->DrawSymbol(symbolVectors[shieldIndex], symxf, angleRad);
 
                         // TODO: if this is ever needed ...
-//                      if (rlStyle->addToExclusionRegions)
+//                      if (rlStyle->addToExclusionRegion)
 //                          se_renderer->AddExclusionRegion(style, symxf, 0.0);
                     }
 

Modified: sandbox/rfc60/MgDev/Common/Stylization/SE_RenderProxies.h
===================================================================
--- sandbox/rfc60/MgDev/Common/Stylization/SE_RenderProxies.h	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Stylization/SE_RenderProxies.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -173,8 +173,8 @@
         : type(stype),
           renderPass(0),
           drawLast(false),
-          checkExclusionRegions(false),
-          addToExclusionRegions(false)
+          checkExclusionRegion(false),
+          addToExclusionRegion(false)
     {
         bounds[0].x = bounds[3].x = +DBL_MAX;
         bounds[1].x = bounds[2].x = -DBL_MAX;
@@ -218,8 +218,8 @@
     int renderPass;
 
     bool drawLast;
-    bool checkExclusionRegions;
-    bool addToExclusionRegions;
+    bool checkExclusionRegion;
+    bool addToExclusionRegion;
 };
 
 

Modified: sandbox/rfc60/MgDev/Common/Stylization/SE_Renderer.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/Stylization/SE_Renderer.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Stylization/SE_Renderer.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -214,7 +214,7 @@
         if (style->drawLast)
             AddLabel(featGeom, style, xform, angleRad);
         else
-            DrawSymbol(style->symbol, xform, angleRad, style->addToExclusionRegions);
+            DrawSymbol(style->symbol, xform, angleRad, style->addToExclusionRegion);
     }
 
     if (bounds)
@@ -371,7 +371,7 @@
     {
         xform = xformbase;
         xform.translate(pos->x, pos->y);
-        DrawSymbol(style->symbol, xform, baserot, style->addToExclusionRegions);
+        DrawSymbol(style->symbol, xform, baserot, style->addToExclusionRegion);
     }
 
     LineBufferPool::FreeLineBuffer(m_pPool, spLB.release());
@@ -488,7 +488,8 @@
     SE_RenderStyle* clonedStyle = CloneRenderStyle(style);
 
     SE_LabelInfo info(xform.x2, xform.y2, RS_Units_Device, angleRad, clonedStyle);
-    ProcessSELabelGroup(&info, 1, RS_OverpostType_AllFit, style->addToExclusionRegions, geom);
+    RS_OverpostType overpostType = style->checkExclusionRegion? RS_OverpostType_AllFit : RS_OverpostType_All;
+    ProcessSELabelGroup(&info, 1, overpostType, style->addToExclusionRegion, geom);
 }
 
 
@@ -566,8 +567,8 @@
 
     // copy all the common properties
     memcpy(ret->bounds, symbol->bounds, sizeof(ret->bounds));
-    ret->addToExclusionRegions = symbol->addToExclusionRegions;
-    ret->checkExclusionRegions = symbol->checkExclusionRegions;
+    ret->addToExclusionRegion = symbol->addToExclusionRegion;
+    ret->checkExclusionRegion = symbol->checkExclusionRegion;
     ret->drawLast              = symbol->drawLast;
     ret->renderPass            = symbol->renderPass;
 
@@ -1201,7 +1202,7 @@
 
                             // only draw symbols at the interior points
                             if (numDrawn > 0 && numDrawn < numSymbols-1)
-                                DrawSymbol(style->symbol, symxf, angleRad, style->addToExclusionRegions);
+                                DrawSymbol(style->symbol, symxf, angleRad, style->addToExclusionRegion);
 
                             // handle the centerline path at the group's end - only
                             // need to do this if we have at least one interior symbol
@@ -1633,7 +1634,7 @@
                             if (style->drawLast)
                                 AddLabel(geometry, style, symxf, angleRad);
                             else
-                                DrawSymbol(style->symbol, symxf, angleRad, style->addToExclusionRegions);
+                                DrawSymbol(style->symbol, symxf, angleRad, style->addToExclusionRegion);
                         }
 
                         ++numDrawn;

Modified: sandbox/rfc60/MgDev/Common/Stylization/SE_StyleVisitor.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/Stylization/SE_StyleVisitor.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Stylization/SE_StyleVisitor.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -847,8 +847,8 @@
         ParseStringExpression(instance->GetPositioningAlgorithm(), m_symbolInstance->positioningAlgorithm, SymbolInstance::sPositioningAlgorithmDefault, SymbolInstance::sPositioningAlgorithmValues);
 
         ParseBooleanExpression(instance->GetDrawLast(), m_symbolInstance->drawLast, false);
-        ParseBooleanExpression(instance->GetAddToExclusionRegion(), m_symbolInstance->addToExclusionRegions, false);
-        ParseBooleanExpression(instance->GetCheckExclusionRegion(), m_symbolInstance->checkExclusionRegions, false);
+        ParseBooleanExpression(instance->GetAddToExclusionRegion(), m_symbolInstance->addToExclusionRegion, false);
+        ParseBooleanExpression(instance->GetCheckExclusionRegion(), m_symbolInstance->checkExclusionRegion, false);
 
         ParseDoubleExpression(instance->GetScaleX(), m_symbolInstance->scale[0], 1.0);
         ParseDoubleExpression(instance->GetScaleY(), m_symbolInstance->scale[1], 1.0);

Modified: sandbox/rfc60/MgDev/Common/Stylization/SE_SymbolDefProxies.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/Stylization/SE_SymbolDefProxies.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Stylization/SE_SymbolDefProxies.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -892,7 +892,7 @@
         if (rplist.size() == 1
             && rplist[0]->type == SE_RenderPrimitive_Polyline
             && !style->drawLast
-            && !style->addToExclusionRegions)
+            && !style->addToExclusionRegion)
         {
             SE_RenderPolyline* rp = (SE_RenderPolyline*)rplist[0];
             LineBuffer* lb = rp->geometry->xf_buffer();
@@ -1004,7 +1004,7 @@
         if (rplist.size() == 1
             && rplist[0]->type == SE_RenderPrimitive_Polygon
             && !style->drawLast
-            && !style->addToExclusionRegions)
+            && !style->addToExclusionRegion)
         {
             SE_RenderPolygon* rp = (SE_RenderPolygon*)rplist[0];
             LineBuffer* lb = rp->geometry->xf_buffer();

Modified: sandbox/rfc60/MgDev/Common/Stylization/SE_SymbolDefProxies.h
===================================================================
--- sandbox/rfc60/MgDev/Common/Stylization/SE_SymbolDefProxies.h	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Stylization/SE_SymbolDefProxies.h	2009-12-09 22:21:34 UTC (rev 4405)
@@ -262,8 +262,8 @@
     MdfModel::SizeContext sizeContext;
     MdfModel::SymbolInstance::GeometryContext geomContext;
     SE_Boolean drawLast;
-    SE_Boolean checkExclusionRegions;
-    SE_Boolean addToExclusionRegions;
+    SE_Boolean checkExclusionRegion;
+    SE_Boolean addToExclusionRegion;
     SE_String positioningAlgorithm;
     SE_Integer renderPass;
 

Modified: sandbox/rfc60/MgDev/Common/Stylization/StylizationEngine.cpp
===================================================================
--- sandbox/rfc60/MgDev/Common/Stylization/StylizationEngine.cpp	2009-12-09 21:38:53 UTC (rev 4404)
+++ sandbox/rfc60/MgDev/Common/Stylization/StylizationEngine.cpp	2009-12-09 22:21:34 UTC (rev 4405)
@@ -649,8 +649,8 @@
                 }
 
                 // TODO: why are these in the symbol instance?
-                style->rstyle->addToExclusionRegions = sym->addToExclusionRegions.evaluate(exec);
-                style->rstyle->checkExclusionRegions = sym->checkExclusionRegions.evaluate(exec);
+                style->rstyle->addToExclusionRegion = sym->addToExclusionRegion.evaluate(exec);
+                style->rstyle->checkExclusionRegion = sym->checkExclusionRegion.evaluate(exec);
                 style->rstyle->drawLast = sym->drawLast.evaluate(exec);
 
                 const wchar_t* positioningAlgo = sym->positioningAlgorithm.evaluate(exec);



More information about the mapguide-commits mailing list