[mapguide-commits] r8190 - in sandbox/jng/tiling: Common/MapGuideCommon Common/MapGuideCommon/Exception Common/MapGuideCommon/MapLayer Common/MapGuideCommon/Resources Common/MapGuideCommon/System Common/MdfModel Common/MdfParser Common/Schema Doc/samples Doc/samples/xyz Server/src/Services/Rendering Server/src/Services/Tile Server/src/UnitTesting UnitTest/TestData/TileService

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Mon Jun 9 15:32:07 PDT 2014


Author: jng
Date: 2014-06-09 15:32:06 -0700 (Mon, 09 Jun 2014)
New Revision: 8190

Added:
   sandbox/jng/tiling/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.cpp
   sandbox/jng/tiling/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.h
   sandbox/jng/tiling/Doc/samples/xyz/
   sandbox/jng/tiling/Doc/samples/xyz/index.html
Modified:
   sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommon.h
   sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommon.vcxproj
   sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommon.vcxproj.filters
   sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommonBuild.cpp
   sandbox/jng/tiling/Common/MapGuideCommon/MapLayer/Map.cpp
   sandbox/jng/tiling/Common/MapGuideCommon/MapLayer/Map.h
   sandbox/jng/tiling/Common/MapGuideCommon/Resources/mapguide_en.res
   sandbox/jng/tiling/Common/MapGuideCommon/System/MapGuideCommonClassId.h
   sandbox/jng/tiling/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp
   sandbox/jng/tiling/Common/MdfModel/TileSetDefinition.cpp
   sandbox/jng/tiling/Common/MdfModel/TileSetDefinition.h
   sandbox/jng/tiling/Common/MdfModel/TileStoreParameters.cpp
   sandbox/jng/tiling/Common/MdfModel/TileStoreParameters.h
   sandbox/jng/tiling/Common/MdfParser/IOTileSetDefinition.cpp
   sandbox/jng/tiling/Common/MdfParser/IOTileStoreParameters.cpp
   sandbox/jng/tiling/Common/MdfParser/SAX2Parser.cpp
   sandbox/jng/tiling/Common/Schema/TileSetDefinition-3.0.0.xsd
   sandbox/jng/tiling/Doc/samples/samples.php
   sandbox/jng/tiling/Server/src/Services/Rendering/ServerRenderingService.cpp
   sandbox/jng/tiling/Server/src/Services/Tile/ServerTileService.cpp
   sandbox/jng/tiling/Server/src/Services/Tile/ServerTileService.vcxproj
   sandbox/jng/tiling/Server/src/Services/Tile/ServerTileService.vcxproj.filters
   sandbox/jng/tiling/Server/src/Services/Tile/ServerTileServiceBuild.cpp
   sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefault.cpp
   sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefault.h
   sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefaultProvider.cpp
   sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefaultProvider.h
   sandbox/jng/tiling/Server/src/UnitTesting/TestMdfModel.cpp
   sandbox/jng/tiling/UnitTest/TestData/TileService/UT_BaseMap.tsd
Log:
Add support for XYZ tile provider in the Tile Set Definition. In the process of adding XYZ tile provider support it has been discovered that some of the schema elements in the current TileSetDefinition schema do not make any sense in an XYZ context.

As a result, such elements have been repurposed as provider-specific parameters. However this has resulted in a little bit of ugliness:

 * MgMap's coordinate system and finite scale extraction logic is now hardcoded against these 2 tile providers as the CoordinateSystem and FiniteDisplayScale elements no longer exist. MdfModel test has been updated to match the new TileSetDefinition structure.
 * MgMap::Create() now has a strict parameter which is true when invoked through the published API and false otherwise. When strict is true, an MgUnsupportedTileProviderException is thrown when attempting to create a MgMap from a tile set or a map definition that links to a tile set that uses a non-default tile provider. For tile rendering, it will invoke MgMap::Create() with strict = false

We can live with a bit of hardcoding for now. If we do want to formally have an externally pluggable tile provider system in the vein of FDO in the future, that's when we'll need to probably introduce some new Tile Service APIs to return this Coordinate System and finite scale information and delegate this logic to the specific tile provider instead of hard-coding this logic into MgMap which we currently do.

Finally, a new OpenLayers XYZ sample is included that demonstrates the XYZ layer support through this new tile provider.

Added: sandbox/jng/tiling/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.cpp
===================================================================
--- sandbox/jng/tiling/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.cpp	                        (rev 0)
+++ sandbox/jng/tiling/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.cpp	2014-06-09 22:32:06 UTC (rev 8190)
@@ -0,0 +1,40 @@
+//
+//  Copyright (C) 2004-2014 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 "MapGuideCommon.h"
+
+IMPLEMENT_EXCEPTION_DEFAULTS(MgUnsupportedTileProviderException, MgApplicationException)
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Construct a MgUnsupportedTileProviderException object.
+///
+MgUnsupportedTileProviderException::MgUnsupportedTileProviderException(CREFSTRING methodName,
+    INT32 lineNumber, CREFSTRING fileName, MgStringCollection* whatArguments,
+    CREFSTRING whyMessageId, MgStringCollection* whyArguments) throw() :
+    MgApplicationException(methodName, lineNumber, fileName,
+        whatArguments, whyMessageId, whyArguments)
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Destruct the object.
+///
+MgUnsupportedTileProviderException::~MgUnsupportedTileProviderException() throw()
+{
+}

Added: sandbox/jng/tiling/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.h
===================================================================
--- sandbox/jng/tiling/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.h	                        (rev 0)
+++ sandbox/jng/tiling/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.h	2014-06-09 22:32:06 UTC (rev 8190)
@@ -0,0 +1,70 @@
+//
+//  Copyright (C) 2004-2014 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 MG_UNSUPPORTED_TILE_PROVIDER_EXCEPTION_H_
+#define MG_UNSUPPORTED_TILE_PROVIDER_EXCEPTION_H_
+
+/// \ingroup Exceptions_Module
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Thrown when a new MgMap is created from a Map Definition that references a Tile Set Definition
+/// that uses an unsupported tile provider
+///
+class MG_MAPGUIDE_API MgUnsupportedTileProviderException : public MgApplicationException
+{
+    DECLARE_CLASSNAME(MgUnsupportedTileProviderException)
+
+EXTERNAL_API:
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Construct a MgUnsupportedTileProviderException 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.
+    ///
+    MgUnsupportedTileProviderException(CREFSTRING methodName, INT32 lineNumber,
+        CREFSTRING fileName, MgStringCollection* whatArguments,
+        CREFSTRING whyMessageId, MgStringCollection* whyArguments) throw();
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Destructor for a MgUnsupportedTileProviderException object.
+    ///
+    virtual ~MgUnsupportedTileProviderException() throw();
+
+INTERNAL_API:
+
+    DECLARE_EXCEPTION_DEFAULTS(MgUnsupportedTileProviderException)
+
+CLASS_ID:
+
+    static const INT32 m_cls_id = MapGuide_Exception_MgUnsupportedTileProviderException;
+};
+
+#endif

Modified: sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommon.h
===================================================================
--- sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommon.h	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommon.h	2014-06-09 22:32:06 UTC (rev 8190)
@@ -117,6 +117,7 @@
 #include "Exception/StylizeLayerFailedException.h"
 #include "Exception/UnauthorizedAccessException.h"
 #include "Exception/UnknownTileProviderException.h"
+#include "Exception/UnsupportedTileProviderException.h"
 #include "Exception/UnsupportedProviderThreadModelException.h"
 #include "Exception/UriFormatException.h"
 

Modified: sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommon.vcxproj
===================================================================
--- sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommon.vcxproj	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommon.vcxproj	2014-06-09 22:32:06 UTC (rev 8190)
@@ -204,6 +204,12 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="Exception\UnsupportedTileProviderException.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="MapLayer\Layer.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -946,6 +952,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Exception\UnknownTileProviderException.h" />
+    <ClInclude Include="Exception\UnsupportedTileProviderException.h" />
     <ClInclude Include="MapLayer\Layer.h" />
     <ClInclude Include="MapLayer\Map.h" />
     <ClInclude Include="MapLayer\Selection.h" />

Modified: sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommon.vcxproj.filters
===================================================================
--- sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommon.vcxproj.filters	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommon.vcxproj.filters	2014-06-09 22:32:06 UTC (rev 8190)
@@ -397,6 +397,7 @@
     <ClCompile Include="Exception\UnknownTileProviderException.cpp">
       <Filter>Exception</Filter>
     </ClCompile>
+    <ClCompile Include="Exception\UnsupportedTileProviderException.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="MapLayer\Layer.h">
@@ -775,6 +776,7 @@
     <ClInclude Include="Exception\UnknownTileProviderException.h">
       <Filter>Exception</Filter>
     </ClInclude>
+    <ClInclude Include="Exception\UnsupportedTileProviderException.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="MapGuideCommon.rc" />

Modified: sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommonBuild.cpp
===================================================================
--- sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommonBuild.cpp	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MapGuideCommon/MapGuideCommonBuild.cpp	2014-06-09 22:32:06 UTC (rev 8190)
@@ -73,6 +73,7 @@
 #include  "Exception/StylizeLayerFailedException.cpp"
 #include  "Exception/UnauthorizedAccessException.cpp"
 #include  "Exception/UnknownTileProviderException.cpp"
+#include  "Exception/UnsupportedTileProviderException.cpp"
 #include  "Exception/UnsupportedProviderThreadModelException.cpp"
 #include  "Exception/UriFormatException.cpp"
 #include  "MapLayer/Layer.cpp"

Modified: sandbox/jng/tiling/Common/MapGuideCommon/MapLayer/Map.cpp
===================================================================
--- sandbox/jng/tiling/Common/MapGuideCommon/MapLayer/Map.cpp	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MapGuideCommon/MapLayer/Map.cpp	2014-06-09 22:32:06 UTC (rev 8190)
@@ -113,12 +113,17 @@
 //
 void MgMap::Create(MgResourceService* resourceService, MgResourceIdentifier* resource, CREFSTRING mapName)
 {
+    Create(resourceService, resource, mapName, true);
+}
+
+void MgMap::Create(MgResourceService* resourceService, MgResourceIdentifier* resource, CREFSTRING mapName, bool strict)
+{
     MG_TRY()
 
     if (resource->GetResourceType() == MgResourceType::MapDefinition)
         CreateFromMapDefinition(resourceService, resource, mapName);
     else if (resource->GetResourceType() == MgResourceType::TileSetDefinition)
-        CreateFromTileSet(resourceService, resource, mapName);
+        CreateFromTileSet(resourceService, resource, mapName, strict);
     else
         throw new MgInvalidResourceTypeException(L"MgMap.Create", __LINE__, __WFILE__, NULL, L"", NULL);
 
@@ -200,14 +205,14 @@
         tdef.reset(parser.DetachTileSetDefinition());
         assert(tdef.get() != NULL);
 
-        m_srs = tdef->GetCoordinateSystem();
+        m_srs = GetCoordinateSystemFromTileSet(tdef.get(), true);
 
         //If tile CS is not the same as map def CS, then the bounds of the map def need to be transformed
         if (m_srs != mdef->GetCoordinateSystem())
         {
             Ptr<MgCoordinateSystemFactory> csFactory = new MgCoordinateSystemFactory();
             Ptr<MgCoordinateSystem> mapCs = csFactory->Create(mdef->GetCoordinateSystem());
-            Ptr<MgCoordinateSystem> tileCs = csFactory->Create(tdef->GetCoordinateSystem());
+            Ptr<MgCoordinateSystem> tileCs = csFactory->Create(m_srs);
             Ptr<MgCoordinateSystemTransform> trans = csFactory->GetTransform(mapCs, tileCs);
 
             const Box2D& extent = mdef->GetExtents();
@@ -501,17 +506,15 @@
 
     // build the sorted list of finite display scales
     SORTEDSCALES sortedScales;
-    DisplayScaleCollection* displayScales = NULL;
+    MdfModel::DisplayScaleCollection* displayScales = NULL;
+    MdfModel::DisplayScaleCollection dispScalesFromTDef;
     if (NULL != tdef.get())
-        displayScales = tdef->GetFiniteDisplayScales();
-    else
-        displayScales = mdef->GetFiniteDisplayScales();
-    if (displayScales)
     {
-        for(int i = 0; i < displayScales->GetCount(); i++)
+        FINITESCALES fScales;
+        GetFiniteDisplayScalesFromTileSet(tdef.get(), fScales, true);
+        for (FINITESCALES::iterator it = fScales.begin(); it != fScales.end(); it++)
         {
-            DisplayScale* displayScale = displayScales->GetAt(i);
-            double scale = displayScale->GetValue();
+            double scale = *it;
 
             // skip non-positive scales
             if (scale <= 0.0)
@@ -526,7 +529,31 @@
             sortedScales.insert(SORTEDSCALES::value_type(scale, scale));
         }
     }
+    else
+    {
+        displayScales = mdef->GetFiniteDisplayScales();
+        if (displayScales)
+        {
+            for(int i = 0; i < displayScales->GetCount(); i++)
+            {
+                DisplayScale* displayScale = displayScales->GetAt(i);
+                double scale = displayScale->GetValue();
 
+                // skip non-positive scales
+                if (scale <= 0.0)
+                    continue;
+
+                // skip duplicate scales
+                SORTEDSCALES::iterator iter = sortedScales.find(scale);
+                if (iter != sortedScales.end())
+                    continue;
+
+                // insert the scale (automatically sorted in ascending order)
+                sortedScales.insert(SORTEDSCALES::value_type(scale, scale));
+            }
+        }
+    }
+
     // load the sorted scales into the vector
     for (SORTEDSCALES::iterator sIter = sortedScales.begin(); sIter != sortedScales.end(); ++sIter)
         m_finiteDisplayScales.push_back(sIter->second);
@@ -539,7 +566,7 @@
     MG_CATCH_AND_THROW(L"MgMap.CreateFromMapDefinition")
 }
 
-void MgMap::CreateFromTileSet(MgResourceService* resourceService, MgResourceIdentifier* tileSetDefId, CREFSTRING mapName)
+void MgMap::CreateFromTileSet(MgResourceService* resourceService, MgResourceIdentifier* tileSetDefId, CREFSTRING mapName, bool strict)
 {
     MG_TRY()
 
@@ -589,7 +616,7 @@
     Ptr<MgCoordinate> coordCenter = gf.CreateCoordinateXY(extent.GetMinX() + (extent.GetMaxX() - extent.GetMinX()) / 2,
                                                           extent.GetMinY() + (extent.GetMaxY() - extent.GetMinY()) / 2);
     m_center = gf.CreatePoint(coordCenter);
-    m_srs = tdef->GetCoordinateSystem();
+    m_srs = GetCoordinateSystemFromTileSet(tdef.get(), strict);
 
     //Calculate the meter per unit for the given coordinate system
     m_metersPerUnit = 1.0; // assume a default value
@@ -714,13 +741,13 @@
 
     // build the sorted list of finite display scales
     SORTEDSCALES sortedScales;
-    DisplayScaleCollection* displayScales = tdef->GetFiniteDisplayScales();
-    if (displayScales)
+    FINITESCALES displayScales;
+    GetFiniteDisplayScalesFromTileSet(tdef.get(), displayScales, strict);
+    if (displayScales.size() > 0)
     {
-        for(int i = 0; i < displayScales->GetCount(); i++)
+        for (FINITESCALES::iterator it = displayScales.begin(); it != displayScales.end(); it++)
         {
-            DisplayScale* displayScale = displayScales->GetAt(i);
-            double scale = displayScale->GetValue();
+            double scale = *it;
 
             // skip non-positive scales
             if (scale <= 0.0)
@@ -748,6 +775,73 @@
     MG_CATCH_AND_THROW(L"MgMap.CreateFromTileSet")
 }
 
+STRING MgMap::GetCoordinateSystemFromTileSet(MdfModel::TileSetDefinition* tileset, bool strict)
+{
+    //Yes, this is hard-coded against specific providers. Revisit if we do want
+    //to FDO-ize this tile provider concept.
+
+    MdfModel::TileStoreParameters* storeParams = tileset->GetTileStoreParameters();
+    if (storeParams->GetTileProvider() == L"Default") //NOXLATE
+    {
+        MdfModel::NameStringPairCollection* parameters = storeParams->GetParameters();
+        for (INT32 i = 0; i < parameters->GetCount(); i++)
+        {
+            MdfModel::NameStringPair* nsp = parameters->GetAt(i);
+            if (nsp->GetName() == L"CoordinateSystem") //NOXLATE
+            {
+                return nsp->GetValue();
+            }
+        }
+    }
+    else if (storeParams->GetTileProvider() == L"XYZ") //NOXLATE
+    {
+        //XYZ is always LL84
+        Ptr<MgCoordinateSystemFactory> csFactory = new MgCoordinateSystemFactory();
+        return csFactory->ConvertCoordinateSystemCodeToWkt(L"LL84"); //NOXLATE
+    }
+    if (strict)
+    {
+        MgStringCollection args;
+        args.Add(storeParams->GetTileProvider());
+        throw new MgUnsupportedTileProviderException(L"MgMap.GetCoordinateSystemFromTileSet", __LINE__, __WFILE__, &args, L"", NULL);
+    }
+    else
+    {
+        return L"";
+    }
+}
+
+void MgMap::GetFiniteDisplayScalesFromTileSet(MdfModel::TileSetDefinition* tileset, FINITESCALES& scales, bool strict)
+{
+    //Yes, this is hard-coded against specific providers. Revisit if we do want
+    //to FDO-ize this tile provider concept.
+
+    MdfModel::TileStoreParameters* storeParams = tileset->GetTileStoreParameters();
+    if (storeParams->GetTileProvider() == L"Default") //NOXLATE
+    {
+        MdfModel::NameStringPairCollection* parameters = storeParams->GetParameters();
+        for (INT32 i = 0; i < parameters->GetCount(); i++)
+        {
+            MdfModel::NameStringPair* nsp = parameters->GetAt(i);
+            if (nsp->GetName() == L"FiniteScaleList") //NOXLATE
+            {
+                Ptr<MgStringCollection> values = MgStringCollection::ParseCollection(nsp->GetValue(), L","); //NOXLATE
+                for (INT32 i = 0; i < values->GetCount(); i++)
+                {
+                    double val = MgUtil::StringToDouble(values->GetItem(i));
+                    scales.push_back(val);
+                }
+            }
+        }
+    }
+    else if (strict)
+    {
+        MgStringCollection args;
+        args.Add(storeParams->GetTileProvider());
+        throw new MgUnsupportedTileProviderException(L"MgMap.GetFiniteDisplayScalesFromTileSet", __LINE__, __WFILE__, &args, L"", NULL);
+    }
+}
+
 //////////////////////////////////////////////////////////////
 // Call down to base class implementation.  Ptr<> seems to be
 // messing this up.  Weird

Modified: sandbox/jng/tiling/Common/MapGuideCommon/MapLayer/Map.h
===================================================================
--- sandbox/jng/tiling/Common/MapGuideCommon/MapLayer/Map.h	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MapGuideCommon/MapLayer/Map.h	2014-06-09 22:32:06 UTC (rev 8190)
@@ -29,6 +29,11 @@
 class MgSiteConnection;
 template class MG_MAPGUIDE_API Ptr<MgMap>;
 
+namespace MdfModel
+{
+    class TileSetDefinition;
+}
+
 #ifdef _WIN32
 #undef CreateService
 #endif
@@ -622,6 +627,8 @@
     ///
     virtual void SetWatermarkUsage(INT32 watermarkUsage);
 
+    virtual void Create(MgResourceService* resourceService, MgResourceIdentifier* mapDefinition, CREFSTRING mapName, bool strict);
+
 protected:
 
     //////////////////////////////////////////////////////////////////
@@ -665,8 +672,11 @@
 
 private:
     void CreateFromMapDefinition(MgResourceService* resourceService, MgResourceIdentifier* resource, CREFSTRING mapName);
-    void CreateFromTileSet(MgResourceService* resourceService, MgResourceIdentifier* resource, CREFSTRING mapName);
+    void CreateFromTileSet(MgResourceService* resourceService, MgResourceIdentifier* resource, CREFSTRING mapName, bool strict);
 
+    STRING GetCoordinateSystemFromTileSet(MdfModel::TileSetDefinition* tileset, bool strict);
+    void GetFiniteDisplayScalesFromTileSet(MdfModel::TileSetDefinition* tileset, FINITESCALES& scales, bool strict);
+
     // Version for serialization
     static const int m_serializeVersion = (4<<16) + 0;
     static STRING m_layerGroupTag;

Modified: sandbox/jng/tiling/Common/MapGuideCommon/Resources/mapguide_en.res
===================================================================
--- sandbox/jng/tiling/Common/MapGuideCommon/Resources/mapguide_en.res	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MapGuideCommon/Resources/mapguide_en.res	2014-06-09 22:32:06 UTC (rev 8190)
@@ -428,7 +428,15 @@
 [TileService]
 MgTileProvider_Default_DisplayName                     = Default Tile Provider
 MgTileProvider_Default_Description                     = Default tile access provided by MapGuide. Supports MapGuide-managed tile path or user-defined path
-MgTileProvider_Default_Property_TilePath_LocalizedName = Tile Path
+MgTileProvider_XYZ_DisplayName                         = XYZ Tile Provider
+MgTileProvider_XYZ_Description                         = XYZ tile access provided by MapGuide. Grid scheme is compatible with Google Maps and Open Street Map. Rendered tiles are 256x256. Layers must be convertible from lat/lon coordinates. Under this scheme, Row = X, Column = Y, Scale = Z for accessing tiles. Supports MapGuide-managed tile path or user-defined path
+MgTileProvider_Common_Property_TilePath_LocalizedName  = Tile Path
+MgTileProvider_Common_Property_TileWidth_LocalizedName = Tile Width
+MgTileProvider_Common_Property_TileHeight_LocalizedName = Tile Height
+MgTileProvider_Common_Property_TileFormat_LocalizedName = Tile Format
+MgTileProvider_Common_Property_RenderOnly_LocalizedName = Render Tiles Only (do not cache)
+MgTileProvider_Common_Property_CoordinateSystem_LocalizedName = Coordinate System
+MgTileProvider_Common_Property_FiniteScaleList_LocalizedName = Finite Display Scale List
 
 # *****************************************************************************
 # S T Y L I Z A T I O N

Modified: sandbox/jng/tiling/Common/MapGuideCommon/System/MapGuideCommonClassId.h
===================================================================
--- sandbox/jng/tiling/Common/MapGuideCommon/System/MapGuideCommonClassId.h	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MapGuideCommon/System/MapGuideCommonClassId.h	2014-06-09 22:32:06 UTC (rev 8190)
@@ -90,6 +90,7 @@
 #define MapGuide_Exception_MgAllProviderConnectionsUsedException        MAPGUIDE_EXCEPTION_ID+54
 #define MapGuide_Exception_MgRasterTransformationNotSupportedException  MAPGUIDE_EXCEPTION_ID+55
 #define MapGuide_Exception_MgUnknownTileProviderException               MAPGUIDE_EXCEPTION_ID+56
+#define MapGuide_Exception_MgUnsupportedTileProviderException           MAPGUIDE_EXCEPTION_ID+57
 
 
 // MapLayer API

Modified: sandbox/jng/tiling/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp
===================================================================
--- sandbox/jng/tiling/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp	2014-06-09 22:32:06 UTC (rev 8190)
@@ -88,6 +88,8 @@
     EXCEPTION_CLASS_CREATOR(MgSessionExpiredException)
     EXCEPTION_CLASS_CREATOR(MgSessionNotFoundException)
     EXCEPTION_CLASS_CREATOR(MgUnauthorizedAccessException)
+    EXCEPTION_CLASS_CREATOR(MgUnknownTileProviderException)
+    EXCEPTION_CLASS_CREATOR(MgUnsupportedTileProviderException)
     EXCEPTION_CLASS_CREATOR(MgUnsupportedProviderThreadModelException)
     EXCEPTION_CLASS_CREATOR(MgUriFormatException)
 

Modified: sandbox/jng/tiling/Common/MdfModel/TileSetDefinition.cpp
===================================================================
--- sandbox/jng/tiling/Common/MdfModel/TileSetDefinition.cpp	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MdfModel/TileSetDefinition.cpp	2014-06-09 22:32:06 UTC (rev 8190)
@@ -18,9 +18,8 @@
 #include "TileSetDefinition.h"
 
 // Construction, destruction, initialization.
-TileSetDefinition::TileSetDefinition(const MdfString& strCoordinateSystem)
-    : m_strCoordSys(strCoordinateSystem),
-      m_boxExtents(0.0, 0.0)
+TileSetDefinition::TileSetDefinition()
+    : m_boxExtents(0.0, 0.0)
 {
 
 }
@@ -37,18 +36,6 @@
     return &this->m_parameters;
 }
 
-// Property : CoordinateSystem
-// The WKT string that represents the coordinate system for the MapDefinition.
-const MdfString& TileSetDefinition::GetCoordinateSystem() const
-{
-    return this->m_strCoordSys;
-}
-
-void TileSetDefinition::SetCoordinateSystem(const MdfString& strCoordinateSystem)
-{
-    this->m_strCoordSys = strCoordinateSystem;
-}
-
 // Property : Extents
 // The extents to be used by the MapDefinition
 const Box2D& TileSetDefinition::GetExtents() const
@@ -61,13 +48,6 @@
     this->m_boxExtents = boxExtents;
 }
 
-// Property : FiniteDisplayScales
-// The scales that the base map tiles can be displayed at
-DisplayScaleCollection* TileSetDefinition::GetFiniteDisplayScales()
-{
-    return &this->m_finiteDisplayScales;
-}
-
 // Property : BaseMapLayerGroups
 // The base map groups; used to define tiles for the HTML viewer.
 BaseMapLayerGroupCollection* TileSetDefinition::GetBaseMapLayerGroups()

Modified: sandbox/jng/tiling/Common/MdfModel/TileSetDefinition.h
===================================================================
--- sandbox/jng/tiling/Common/MdfModel/TileSetDefinition.h	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MdfModel/TileSetDefinition.h	2014-06-09 22:32:06 UTC (rev 8190)
@@ -30,27 +30,18 @@
     {
     public:
         // Construction, destruction, initialization.
-        TileSetDefinition(const MdfString& strCoordinateSystem);
+        TileSetDefinition();
         virtual ~TileSetDefinition();
 
         // Property: TileStoreParameters
         // Defines the parameters to access the tile cache
         TileStoreParameters* GetTileStoreParameters();
 
-        // Property : CoordinateSystem
-        // The WKT string that represents the coordinate system for the MapDefinition.
-        const MdfString& GetCoordinateSystem() const;
-        void SetCoordinateSystem(const MdfString& strCoordinateSystem);
-
         // Property : Extents
         // The extents to be used by the MapDefinition
         const Box2D& GetExtents() const;
         void SetExtents(const Box2D& boxExtents);
 
-        // Property : FiniteDisplayScales
-        // The scales that the base map tiles can be displayed at
-        DisplayScaleCollection* GetFiniteDisplayScales();
-
         // Property : BaseMapLayerGroups
         // The base map groups; used to define tiles for the HTML viewer.
         BaseMapLayerGroupCollection* GetBaseMapLayerGroups();
@@ -63,9 +54,7 @@
         // Data members
         // See corresponding properties for descriptions
         TileStoreParameters m_parameters;
-        MdfString m_strCoordSys;
         Box2D m_boxExtents;
-        DisplayScaleCollection m_finiteDisplayScales;
         BaseMapLayerGroupCollection m_baseMapLayerGroups;
     };
 

Modified: sandbox/jng/tiling/Common/MdfModel/TileStoreParameters.cpp
===================================================================
--- sandbox/jng/tiling/Common/MdfModel/TileStoreParameters.cpp	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MdfModel/TileStoreParameters.cpp	2014-06-09 22:32:06 UTC (rev 8190)
@@ -46,37 +46,4 @@
 void TileStoreParameters::SetTileProvider(const MdfString &provider)
 {
     this->m_provider = provider;
-}
-
-// Property : TileWidth
-int TileStoreParameters::GetTileWidth() const
-{
-    return this->m_width;
-}
-
-void TileStoreParameters::SetTileWidth(const int &width)
-{
-    this->m_width = width;
-}
-
-// Property : TileHeight
-int TileStoreParameters::GetTileHeight() const
-{
-    return this->m_height;
-}
-
-void TileStoreParameters::SetTileHeight(const int &height)
-{
-    this->m_height = height;
-}
-
-// Property : Format
-const MdfString& TileStoreParameters::GetFormat() const
-{
-    return this->m_format;
-}
-
-void TileStoreParameters::SetFormat(const MdfString &format)
-{
-    this->m_format = format;
 }
\ No newline at end of file

Modified: sandbox/jng/tiling/Common/MdfModel/TileStoreParameters.h
===================================================================
--- sandbox/jng/tiling/Common/MdfModel/TileStoreParameters.h	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MdfModel/TileStoreParameters.h	2014-06-09 22:32:06 UTC (rev 8190)
@@ -37,18 +37,6 @@
         const MdfString& GetTileProvider() const;
         void SetTileProvider(const MdfString &provider);
 
-        // Property : TileWidth
-        int GetTileWidth() const;
-        void SetTileWidth(const int &width);
-
-        // Property : TileHeight
-        int GetTileHeight() const;
-        void SetTileHeight(const int &height);
-
-        // Property : Format
-        const MdfString& GetFormat() const;
-        void SetFormat(const MdfString &format);
-
     private:
 
         // Hidden copy constructor and assignment operator.

Modified: sandbox/jng/tiling/Common/MdfParser/IOTileSetDefinition.cpp
===================================================================
--- sandbox/jng/tiling/Common/MdfParser/IOTileSetDefinition.cpp	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MdfParser/IOTileSetDefinition.cpp	2014-06-09 22:32:06 UTC (rev 8190)
@@ -100,17 +100,7 @@
 
 void IOTileSetDefinition::ElementChars(const wchar_t* ch)
 {
-    switch (this->m_currElemId)
-    {
-    case eCoordinateSystem:
-        this->m_tileset->SetCoordinateSystem(ch);
-        break;
 
-    case eFiniteDisplayScale:
-        double val = wstrToDouble(ch);
-        this->m_tileset->GetFiniteDisplayScales()->Adopt(new DisplayScale(val));
-        break;
-    }
 }
 
 
@@ -156,23 +146,9 @@
     // Property: TileStoreParameters
     IOTileStoreParameters::Write(fd, tileset->GetTileStoreParameters(), version, tab);
 
-    // Property: CoordinateSystem
-    fd << tab.tab() << startStr(sCoordinateSystem);
-    fd << EncodeString(tileset->GetCoordinateSystem());
-    fd << endStr(sCoordinateSystem) << std::endl;
-
     // Property: Extents
     IOExtra::WriteBox2D(fd, tileset->GetExtents(), false, version, tab);
 
-    // Property: FiniteDisplayScales
-    DisplayScaleCollection* finiteDisplayScales = tileset->GetFiniteDisplayScales();
-    for (int i=0; i<finiteDisplayScales->GetCount(); ++i)
-    {
-        fd << tab.tab() << "<FiniteDisplayScale>"; // NOXLATE
-        fd << DoubleToStr((static_cast<DisplayScale*>(finiteDisplayScales->GetAt(i)))->GetValue());
-        fd << "</FiniteDisplayScale>" << std::endl; // NOXLATE
-    }
-
     // Property: BaseMapLayerGroups
     BaseMapLayerGroupCollection* baseMapGroups = tileset->GetBaseMapLayerGroups();
     for (int i=0; i<baseMapGroups->GetCount(); ++i)

Modified: sandbox/jng/tiling/Common/MdfParser/IOTileStoreParameters.cpp
===================================================================
--- sandbox/jng/tiling/Common/MdfParser/IOTileStoreParameters.cpp	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MdfParser/IOTileStoreParameters.cpp	2014-06-09 22:32:06 UTC (rev 8190)
@@ -62,20 +62,6 @@
     {
         this->m_params->SetTileProvider(ch);
     }
-    else if (this->m_currElemName == L"TileWidth") // NOXLATE
-    {
-        int val = wstrToInt(ch);
-        this->m_params->SetTileWidth(val);
-    }
-    else if (this->m_currElemName == L"TileHeight") // NOXLATE
-    {
-        int val = wstrToInt(ch);
-        this->m_params->SetTileHeight(val);
-    }
-    else if (this->m_currElemName == L"Format") // NOXLATE
-    {
-        this->m_params->SetFormat(ch);
-    }
 }
 
 void IOTileStoreParameters::EndElement(const wchar_t* name, HandlerStack* handlerStack)
@@ -99,21 +85,6 @@
     fd << EncodeString(params->GetTileProvider());
     fd << endStr("TileProvider") << std::endl; //NOXLATE
 
-    // Property: TileWidth
-    fd << tab.tab() << startStr("TileWidth"); //NOXLATE
-    fd << IntToStr(params->GetTileWidth());
-    fd << endStr("TileWidth") << std::endl; //NOXLATE
-
-    // Property: TileHeight
-    fd << tab.tab() << startStr("TileHeight"); //NOXLATE
-    fd << IntToStr(params->GetTileHeight());
-    fd << endStr("TileHeight") << std::endl; //NOXLATE
-
-    // Property: Format
-    fd << tab.tab() << startStr("Format"); //NOXLATE
-    fd << EncodeString(params->GetFormat());
-    fd << endStr("Format") << std::endl; //NOXLATE
-
     // Property: Parameters
     for (int i=0; i<params->GetParameters()->GetCount(); ++i)
         IONameStringPair::Write(fd, "Parameter", params->GetParameters()->GetAt(i), version, tab); //NOXLATE

Modified: sandbox/jng/tiling/Common/MdfParser/SAX2Parser.cpp
===================================================================
--- sandbox/jng/tiling/Common/MdfParser/SAX2Parser.cpp	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/MdfParser/SAX2Parser.cpp	2014-06-09 22:32:06 UTC (rev 8190)
@@ -686,7 +686,7 @@
             SetTileSetDefinitionVersion(attributes);
 
             _ASSERT(m_map == NULL); // otherwise we leak
-            m_tileset = new TileSetDefinition(L"");
+            m_tileset = new TileSetDefinition();
             IOTileSetDefinition* IO = new IOTileSetDefinition(m_tileset, m_version);
             m_handlerStack->push(IO);
             IO->StartElement(str.c_str(), m_handlerStack);

Modified: sandbox/jng/tiling/Common/Schema/TileSetDefinition-3.0.0.xsd
===================================================================
--- sandbox/jng/tiling/Common/Schema/TileSetDefinition-3.0.0.xsd	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Common/Schema/TileSetDefinition-3.0.0.xsd	2014-06-09 22:32:06 UTC (rev 8190)
@@ -9,24 +9,14 @@
       <xs:sequence>
         <xs:element name="TileStoreParameters" type="TileStoreParametersType">
            <xs:annotation>
-            <xs:documentation>Defines the parameters to access the tile cache</xs:documentation>
+            <xs:documentation>Defines the parameters to access and describe the tile cache</xs:documentation>
           </xs:annotation>
         </xs:element>
-        <xs:element name="CoordinateSystem" type="xs:string">
-          <xs:annotation>
-            <xs:documentation>The coordinate system as WKT used by the TileSetDefinition</xs:documentation>
-          </xs:annotation>
-        </xs:element>
         <xs:element name="Extents" type="Box2DType">
           <xs:annotation>
             <xs:documentation>A bounding box around the area of the tile cache</xs:documentation>
           </xs:annotation>
         </xs:element>
-        <xs:element name="FiniteDisplayScale" type="xs:double" maxOccurs="unbounded">
-          <xs:annotation>
-            <xs:documentation>The display scales that the base map layers will have tiles available. Applies to the HTML viewer.</xs:documentation>
-          </xs:annotation>
-        </xs:element>
         <xs:element name="BaseMapLayerGroup" type="BaseMapLayerGroupCommonType" minOccurs="1" maxOccurs="unbounded">
           <xs:annotation>
             <xs:documentation>A group of layers that is used to compose a tiled layer in the HTML viewer</xs:documentation>
@@ -45,21 +35,6 @@
           <xs:documentation>The tile image provider</xs:documentation>
         </xs:annotation>
       </xs:element>
-      <xs:element name="TileWidth" type="xs:integer">
-        <xs:annotation>
-          <xs:documentation>The width of tile images in this tile cache</xs:documentation>
-        </xs:annotation>
-      </xs:element>
-      <xs:element name="TileHeight" type="xs:integer">
-        <xs:annotation>
-          <xs:documentation>The height of tile images in this tile cache</xs:documentation>
-        </xs:annotation>
-      </xs:element>
-      <xs:element name="Format" type="xs:string">
-        <xs:annotation>
-          <xs:documentation>The format of tiles in this tile cache</xs:documentation>
-        </xs:annotation>
-      </xs:element>
       <xs:element name="Parameter" type="NameValuePairType" minOccurs="0" maxOccurs="unbounded">
         <xs:annotation>
           <xs:documentation>Collection of name value pairs for connecting to the tile image provider</xs:documentation>

Modified: sandbox/jng/tiling/Doc/samples/samples.php
===================================================================
--- sandbox/jng/tiling/Doc/samples/samples.php	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Doc/samples/samples.php	2014-06-09 22:32:06 UTC (rev 8190)
@@ -119,9 +119,10 @@
                     <li><a href="ol2samples/selection/index.html">Basic Sheboygan un-tiled map example with selection</a></li>
                     <li><a href="ol2samples/mixed/index.html">Basic Sheboygan mixed map (tiled and untiled) example</a></li>
                     <li><a href="ol2samples/commercial/index.html">Sheboygan map with Google/OSM layers</a></li>
+                    <li><a href="ol2samples/xyz/index.html">Sheboygan map as XYZ layer</a></li>
                 </ul>
                 <? } ?>
             <? } ?>
         </div>
     </body>
-</html>
\ No newline at end of file
+</html>

Added: sandbox/jng/tiling/Doc/samples/xyz/index.html
===================================================================
--- sandbox/jng/tiling/Doc/samples/xyz/index.html	                        (rev 0)
+++ sandbox/jng/tiling/Doc/samples/xyz/index.html	2014-06-09 22:32:06 UTC (rev 8190)
@@ -0,0 +1,50 @@
+<html>
+    <head>
+        <title>Sheboygan map as XYZ layer</title>
+        <link rel="stylesheet" href="../assets/theme/default/style.css" />
+        <style type="text/css">
+            body { font-family: Verdana; font-size: 0.9em; }
+            #error { color: red; }
+            #wrap { width: 900; }
+            #map { width: 400; height: 300; float: left; }
+            .olControlMousePosition { background: #ffff66; font-size: 0.6em !important; padding: 2px; }
+        </style>
+        <script type="text/javascript" src="../assets/jquery-1.10.2.min.js"></script>
+        <script type="text/javascript" src="../assets/OpenLayers.js"></script>
+        <script type="text/javascript">
+
+        $(document).ready(function() {
+            OpenLayers.Control.DragPan.prototype.enableKinetic = false;
+
+            var layerExtent = new OpenLayers.Bounds( -9770571.93250815, 5416573.69002144, -9755615.48593707, 5436091.17493748 );
+            var map = new OpenLayers.Map('map', {
+                theme: null,
+                'restrictedExtent': layerExtent,
+                controls: [
+                    new OpenLayers.Control.Navigation(),
+                    new OpenLayers.Control.Attribution(),
+                    new OpenLayers.Control.Zoom(),
+                    new OpenLayers.Control.ScaleLine(),
+                    new OpenLayers.Control.MousePosition()
+                ]
+            });
+            var layer = new OpenLayers.Layer.XYZ( "XYZ Layer From MapGuide",
+                    "../../mapagent/mapagent.fcgi?OPERATION=GETTILEIMAGE&VERSION=1.2.0&CLIENTAGENT=OpenLayers&MAPDEFINITION=Library://Samples/Sheboygan/TileSets/XYZ.TileSetDefinition&BASEMAPLAYERGROUPNAME=Base+Layer+Group&TILECOL=${y}&TILEROW=${x}&SCALEINDEX=${z}",
+                    {sphericalMercator: true} );
+            map.addLayer(layer);
+            map.zoomToExtent(map.restrictedExtent);
+        });
+
+        </script>
+    </head>
+    <body>
+        <p>This example demonstrates a Map Definition being consumed as an XYZ layer via the MapGuide Tile Set Definition.</p>
+        <p>Sample not loading? <a href="../data/load.php">Check that the required resources have been loaded</a></p>
+        <div id="error">
+        </div>
+        <div id="wrap">
+            <div id="map">
+            </div>
+        </div>
+    </body>
+</html>

Modified: sandbox/jng/tiling/Server/src/Services/Rendering/ServerRenderingService.cpp
===================================================================
--- sandbox/jng/tiling/Server/src/Services/Rendering/ServerRenderingService.cpp	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Server/src/Services/Rendering/ServerRenderingService.cpp	2014-06-09 22:32:06 UTC (rev 8190)
@@ -331,8 +331,6 @@
     // get map extent that corresponds to tile extent
     RS_Bounds extent(mcsMinX, mcsMinY, mcsMaxX, mcsMaxY);
 
-    //printf("XYZ(%d, %d, %d) -> [%f, %f] [%f, %f]\n", x, y, z, mcsMinX, mcsMinY, mcsMaxX, mcsMaxY);
-
     // use the map's background color, but always make it fully transparent
     RS_Color bgColor;
     StylizationUtil::ParseColor(map->GetBackgroundColor(), bgColor);
@@ -390,6 +388,8 @@
             drawWidth = width;
     }
 
+    //printf("XYZ(%d, %d, %d) -> [%f, %f] [%f, %f] at %f -- (w: %d, h: %d, mpu: %f)\n", x, y, z, mcsMinX, mcsMinY, mcsMaxX, mcsMaxY, scale, width, height, map->GetMetersPerUnit());
+
     // sanity check - number of image pixels cannot exceed MAX_PIXELS
     if (drawWidth * drawHeight > MAX_PIXELS)
         throw new MgOutOfRangeException(L"MgServerRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgInvalidImageSizeTooBig", NULL);
@@ -417,6 +417,7 @@
     ret = RenderMapInternal(map, NULL, roLayers, dr.get(), drawWidth, drawHeight, width, height, tileImageFormat, scale, extent, true, true, false);
 
     // restore the base group's visibility
+    baseGroup->SetVisible(groupVisible);
 
     MG_CATCH_AND_THROW(L"MgServerRenderingService.RenderTileXYZ")
 

Modified: sandbox/jng/tiling/Server/src/Services/Tile/ServerTileService.cpp
===================================================================
--- sandbox/jng/tiling/Server/src/Services/Tile/ServerTileService.cpp	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Server/src/Services/Tile/ServerTileService.cpp	2014-06-09 22:32:06 UTC (rev 8190)
@@ -24,7 +24,14 @@
 IMPLEMENT_CREATE_SERVICE(MgServerTileService)
 
 #define TILE_PROVIDER_DEFAULT L"Default"
-#define TILE_PROVIDER_DEFAULT_PARAM_TILEPATH L"TilePath"
+#define TILE_PROVIDER_XYZ L"XYZ"
+#define TILE_PROVIDER_COMMON_PARAM_TILEPATH         L"TilePath"
+#define TILE_PROVIDER_COMMON_PARAM_TILEWIDTH        L"TileWidth"
+#define TILE_PROVIDER_COMMON_PARAM_TILEHEIGHT       L"TileHeight"
+#define TILE_PROVIDER_COMMON_PARAM_TILEFORMAT       L"TileFormat"
+#define TILE_PROVIDER_COMMON_PARAM_RENDERONLY       L"RenderOnly"
+#define TILE_PROVIDER_COMMON_PARAM_COORDINATESYSTEM L"CoordinateSystem"
+#define TILE_PROVIDER_COMMON_PARAM_FINITESCALELIST  L"FiniteScaleList"
 
 MgServerTileService::MgServerTileService() : MgTileService()
 {
@@ -169,47 +176,247 @@
 
     std::string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
     xml.append("<TileProviderList>\n");
-    xml.append("<TileProvider>\n");
-    xml.append("<Name>");
-    std::string mbName;
-    STRING wName = TILE_PROVIDER_DEFAULT;
-    MgUtil::WideCharToMultiByte(wName, mbName);
-    xml.append(mbName);
-    xml.append("</Name>\n");
-    xml.append("<DisplayName>");
-    std::string mbDisplayName;
-    STRING wDisplayName = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Default_DisplayName");
-    MgUtil::WideCharToMultiByte(wDisplayName, mbDisplayName);
-    xml.append(mbDisplayName);
-    xml.append("</DisplayName>\n");
-    xml.append("<Description>");
-    std::string mbDescription;
-    STRING wDescription = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Default_Description");
-    MgUtil::WideCharToMultiByte(wDescription, mbDescription);
-    xml.append(mbDescription);
-    xml.append("</Description>\n");
-    xml.append("<ConnectionProperties>\n");
-    xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"true\">\n");
-    xml.append("<Name>");
-    std::string mbTilePath;
-    STRING wTilePath = TILE_PROVIDER_DEFAULT_PARAM_TILEPATH;
-    MgUtil::WideCharToMultiByte(wTilePath, mbTilePath);
-    xml.append(mbTilePath);
-    xml.append("</Name>\n");
-    xml.append("<LocalizedName>");
-    std::string mbLocName;
-    STRING wLocName = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Default_Property_TilePath_LocalizedName");
-    MgUtil::WideCharToMultiByte(wLocName, mbLocName);
-    xml.append(mbLocName);
-    xml.append("</LocalizedName>\n");
-    xml.append("<DefaultValue>");
-    std::string mbDefaultTag;
-    MgUtil::WideCharToMultiByte(MgResourceTag::TileCachePath, mbDefaultTag);
-    xml.append(mbDefaultTag);
-    xml.append("</DefaultValue>\n");
-    xml.append("</ConnectionProperty>\n");
-    xml.append("</ConnectionProperties>\n");
-    xml.append("</TileProvider>\n");
+
+    //Default Tile Provider
+    {
+        xml.append("<TileProvider>\n");
+        xml.append("<Name>");
+        std::string mbName;
+        MgUtil::WideCharToMultiByte(TILE_PROVIDER_DEFAULT, mbName);
+        xml.append(mbName);
+        xml.append("</Name>\n");
+        xml.append("<DisplayName>");
+        std::string mbDisplayName;
+        STRING wDisplayName = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Default_DisplayName");
+        MgUtil::WideCharToMultiByte(wDisplayName, mbDisplayName);
+        xml.append(mbDisplayName);
+        xml.append("</DisplayName>\n");
+        xml.append("<Description>");
+        std::string mbDescription;
+        STRING wDescription = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Default_Description");
+        MgUtil::WideCharToMultiByte(wDescription, mbDescription);
+        xml.append(mbDescription);
+        xml.append("</Description>\n");
+        xml.append("<ConnectionProperties>\n");
+    
+        //Property: TilePath
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbTilePath;
+        MgUtil::WideCharToMultiByte(TILE_PROVIDER_COMMON_PARAM_TILEPATH, mbTilePath);
+        xml.append(mbTilePath);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocName;
+        STRING wLocName = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_TilePath_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocName, mbLocName);
+        xml.append(mbLocName);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue>");
+        std::string mbDefaultTag;
+        MgUtil::WideCharToMultiByte(MgResourceTag::TileCachePath, mbDefaultTag);
+        xml.append(mbDefaultTag);
+        xml.append("</DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
+    
+        //Property: TileWidth
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbTileWidth;
+        MgUtil::WideCharToMultiByte(TILE_PROVIDER_COMMON_PARAM_TILEWIDTH, mbTileWidth);
+        xml.append(mbTileWidth);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocTileWidth;
+        STRING wLocTileWidth = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_TileWidth_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocTileWidth, mbLocTileWidth);
+        xml.append(mbLocTileWidth);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue>");
+        std::string mbDefaultTileWidth;
+        MgUtil::Int32ToString(MgConfigProperties::DefaultTileServicePropertyTileSizeX, mbDefaultTileWidth);
+        xml.append(mbDefaultTileWidth);
+        xml.append("</DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
+
+        //Property: TileHeight
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbTileHeight;
+        MgUtil::WideCharToMultiByte(TILE_PROVIDER_COMMON_PARAM_TILEHEIGHT, mbTileHeight);
+        xml.append(mbTileHeight);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocTileHeight;
+        STRING wLocTileHeight = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_TileHeight_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocTileHeight, mbLocTileHeight);
+        xml.append(mbLocTileHeight);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue>");
+        std::string mbDefaultTileHeight;
+        MgUtil::Int32ToString(MgConfigProperties::DefaultTileServicePropertyTileSizeY, mbDefaultTileHeight);
+        xml.append(mbDefaultTileHeight);
+        xml.append("</DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
+
+        //Property: TileFormat
+        xml.append("<ConnectionProperty Enumerable=\"true\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbTileFormat;
+        MgUtil::WideCharToMultiByte(TILE_PROVIDER_COMMON_PARAM_TILEFORMAT, mbTileFormat);
+        xml.append(mbTileFormat);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocTileFormat;
+        STRING wLocTileFormat = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_TileFormat_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocTileFormat, mbLocTileFormat);
+        xml.append(mbLocTileFormat);
+        xml.append("</LocalizedName>\n");
+        //Image formats supported by our tile service
+        xml.append("<DefaultValue>PNG</DefaultValue>\n");
+        xml.append("<Value>PNG</Value>");
+        xml.append("<Value>PNG8</Value>");
+        xml.append("<Value>JPG</Value>");
+        xml.append("<Value>GIF</Value>");
+
+        xml.append("</ConnectionProperty>\n");
+
+        //Property: RenderOnly
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"false\">\n");
+        xml.append("<Name>");
+        std::string mbRenderOnly;
+        MgUtil::WideCharToMultiByte(TILE_PROVIDER_COMMON_PARAM_RENDERONLY, mbRenderOnly);
+        xml.append(mbRenderOnly);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocRenderOnly;
+        STRING wLocRenderOnly = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_RenderOnly_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocRenderOnly, mbLocRenderOnly);
+        xml.append(mbLocRenderOnly);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue>false</DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
+
+        //Property: CoordinateSystem
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbCoordSys;
+        MgUtil::WideCharToMultiByte(TILE_PROVIDER_COMMON_PARAM_COORDINATESYSTEM, mbCoordSys);
+        xml.append(mbCoordSys);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocCoordSys;
+        STRING wLocCoordSys = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_CoordinateSystem_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocCoordSys, mbLocCoordSys);
+        xml.append(mbLocCoordSys);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue></DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
+
+        //Property: FiniteScaleList
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbFiniteScaleList;
+        MgUtil::WideCharToMultiByte(TILE_PROVIDER_COMMON_PARAM_FINITESCALELIST, mbFiniteScaleList);
+        xml.append(mbFiniteScaleList);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocFiniteScaleList;
+        STRING wLocFiniteScaleList = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_FiniteScaleList_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocFiniteScaleList, mbLocFiniteScaleList);
+        xml.append(mbLocFiniteScaleList);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue></DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
+
+        xml.append("</ConnectionProperties>\n");
+        xml.append("</TileProvider>\n");
+    }
+    //XYZ Tile Provider
+    {
+        xml.append("<TileProvider>\n");
+        xml.append("<Name>");
+        std::string mbName;
+        STRING wName = TILE_PROVIDER_XYZ;
+        MgUtil::WideCharToMultiByte(wName, mbName);
+        xml.append(mbName);
+        xml.append("</Name>\n");
+        xml.append("<DisplayName>");
+        std::string mbDisplayName;
+        STRING wDisplayName = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Default_DisplayName");
+        MgUtil::WideCharToMultiByte(wDisplayName, mbDisplayName);
+        xml.append(mbDisplayName);
+        xml.append("</DisplayName>\n");
+        xml.append("<Description>");
+        std::string mbDescription;
+        STRING wDescription = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Default_Description");
+        MgUtil::WideCharToMultiByte(wDescription, mbDescription);
+        xml.append(mbDescription);
+        xml.append("</Description>\n");
+        xml.append("<ConnectionProperties>\n");
+    
+        //Property: TilePath
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbTilePath;
+        MgUtil::WideCharToMultiByte(TILE_PROVIDER_COMMON_PARAM_TILEPATH, mbTilePath);
+        xml.append(mbTilePath);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocName;
+        STRING wLocName = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_TilePath_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocName, mbLocName);
+        xml.append(mbLocName);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue>");
+        std::string mbDefaultTag;
+        MgUtil::WideCharToMultiByte(MgResourceTag::TileCachePath, mbDefaultTag);
+        xml.append(mbDefaultTag);
+        xml.append("</DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
+
+        //Property: TileFormat
+        xml.append("<ConnectionProperty Enumerable=\"true\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbTileFormat;
+        MgUtil::WideCharToMultiByte(TILE_PROVIDER_COMMON_PARAM_TILEFORMAT, mbTileFormat);
+        xml.append(mbTileFormat);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocTileFormat;
+        STRING wLocTileFormat = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_TileFormat_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocTileFormat, mbLocTileFormat);
+        xml.append(mbLocTileFormat);
+        xml.append("</LocalizedName>\n");
+        //Image formats supported by our tile service
+        xml.append("<DefaultValue>PNG</DefaultValue>\n");
+        xml.append("<Value>PNG</Value>");
+        xml.append("<Value>PNG8</Value>");
+        xml.append("<Value>JPG</Value>");
+        xml.append("<Value>GIF</Value>");
+
+        xml.append("</ConnectionProperty>\n");
+
+        //Property: RenderOnly
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"false\">\n");
+        xml.append("<Name>");
+        std::string mbRenderOnly;
+        MgUtil::WideCharToMultiByte(TILE_PROVIDER_COMMON_PARAM_RENDERONLY, mbRenderOnly);
+        xml.append(mbRenderOnly);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocRenderOnly;
+        STRING wLocRenderOnly = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_RenderOnly_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocRenderOnly, mbLocRenderOnly);
+        xml.append(mbLocRenderOnly);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue>false</DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
+
+        xml.append("</ConnectionProperties>\n");
+        xml.append("</TileProvider>\n");
+    }
+
     xml.append("</TileProviderList>");
 
     Ptr<MgByteSource> source = new MgByteSource((BYTE_ARRAY_IN)xml.c_str(), (INT32)xml.length());
@@ -310,14 +517,34 @@
     if (provider == TILE_PROVIDER_DEFAULT)
     {
         MdfModel::NameStringPairCollection* parameters = tilesetParams->GetParameters();
+        INT32 width = 300;
+        INT32 height = 300;
+        STRING format = L"PNG";
         STRING path;
+        bool bRenderOnly = false;
         for (INT32 i = 0; i < parameters->GetCount(); i++)
         {
             MdfModel::NameStringPair* pair = parameters->GetAt(i);
-            if (pair->GetName() == TILE_PROVIDER_DEFAULT_PARAM_TILEPATH)
+            if (pair->GetName() == TILE_PROVIDER_COMMON_PARAM_TILEPATH)
             {
                 path = pair->GetValue();
             }
+            else if (pair->GetName() == TILE_PROVIDER_COMMON_PARAM_TILEWIDTH)
+            {
+                width = MgUtil::StringToInt32(pair->GetValue());
+            }
+            else if (pair->GetName() == TILE_PROVIDER_COMMON_PARAM_TILEHEIGHT)
+            {
+                height = MgUtil::StringToInt32(pair->GetValue());
+            }
+            else if (pair->GetName() == TILE_PROVIDER_COMMON_PARAM_TILEFORMAT)
+            {
+                format = pair->GetValue();
+            }
+            else if (pair->GetName() == TILE_PROVIDER_COMMON_PARAM_RENDERONLY)
+            {
+                bRenderOnly = MgUtil::StringToBoolean(pair->GetValue());
+            }
         }
 
         //If we find the cache path substitution tag, replace it with the default path from the configuration
@@ -326,8 +553,39 @@
             path = MgTileParameters::tileCachePath;
         }
 
-        cache = new MgTileCacheDefaultProvider(tileSetId, path, tilesetParams->GetTileWidth(), tilesetParams->GetTileHeight(), tilesetParams->GetFormat());
+        cache = new MgTileCacheDefaultProvider(tileSetId, path, width, height, format, bRenderOnly);
     }
+    else if (provider == TILE_PROVIDER_XYZ)
+    {
+        MdfModel::NameStringPairCollection* parameters = tilesetParams->GetParameters();
+        STRING format = L"PNG";
+        STRING path;
+        bool bRenderOnly = false;
+        for (INT32 i = 0; i < parameters->GetCount(); i++)
+        {
+            MdfModel::NameStringPair* pair = parameters->GetAt(i);
+            if (pair->GetName() == TILE_PROVIDER_COMMON_PARAM_TILEPATH)
+            {
+                path = pair->GetValue();
+            }
+            else if (pair->GetName() == TILE_PROVIDER_COMMON_PARAM_TILEFORMAT)
+            {
+                format = pair->GetValue();
+            }
+            else if (pair->GetName() == TILE_PROVIDER_COMMON_PARAM_RENDERONLY)
+            {
+                bRenderOnly = MgUtil::StringToBoolean(pair->GetValue());
+            }
+        }
+
+        //If we find the cache path substitution tag, replace it with the default path from the configuration
+        if (path == MgResourceTag::TileCachePath)
+        {
+            path = MgTileParameters::tileCachePath;
+        }
+
+        cache = new MgTileCacheXYZProvider(tileSetId, path, format, bRenderOnly);
+    }
     else 
     {
         MgStringCollection arguments;

Modified: sandbox/jng/tiling/Server/src/Services/Tile/ServerTileService.vcxproj
===================================================================
--- sandbox/jng/tiling/Server/src/Services/Tile/ServerTileService.vcxproj	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Server/src/Services/Tile/ServerTileService.vcxproj	2014-06-09 22:32:06 UTC (rev 8190)
@@ -246,6 +246,12 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="TileCacheXYZProvider.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="TileOperation.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -293,6 +299,7 @@
     <ClInclude Include="OpSetTile.h" />
     <ClInclude Include="TileCacheDefault.h" />
     <ClInclude Include="TileCacheDefaultProvider.h" />
+    <ClInclude Include="TileCacheXYZProvider.h" />
     <ClInclude Include="TileOperation.h" />
     <ClInclude Include="TileOperationFactory.h" />
     <ClInclude Include="ServerTileDllExport.h" />

Modified: sandbox/jng/tiling/Server/src/Services/Tile/ServerTileService.vcxproj.filters
===================================================================
--- sandbox/jng/tiling/Server/src/Services/Tile/ServerTileService.vcxproj.filters	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Server/src/Services/Tile/ServerTileService.vcxproj.filters	2014-06-09 22:32:06 UTC (rev 8190)
@@ -37,6 +37,7 @@
     <ClCompile Include="OpGetTileProviders.cpp">
       <Filter>Ops</Filter>
     </ClCompile>
+    <ClCompile Include="TileCacheXYZProvider.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="OpClearCache.h">
@@ -70,6 +71,7 @@
     <ClInclude Include="OpGetTileProviders.h">
       <Filter>Ops</Filter>
     </ClInclude>
+    <ClInclude Include="TileCacheXYZProvider.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="ServerTileService.rc" />

Modified: sandbox/jng/tiling/Server/src/Services/Tile/ServerTileServiceBuild.cpp
===================================================================
--- sandbox/jng/tiling/Server/src/Services/Tile/ServerTileServiceBuild.cpp	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Server/src/Services/Tile/ServerTileServiceBuild.cpp	2014-06-09 22:32:06 UTC (rev 8190)
@@ -27,6 +27,7 @@
 #include "TileCache.cpp"
 #include "TileCacheDefault.cpp"
 #include "TileCacheDefaultProvider.cpp"
+#include "TileCacheXYZProvider.cpp"
 #include "TileOperation.cpp"
 #include "TileOperationFactory.cpp"
 #include "TileServiceHandler.cpp"

Modified: sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefault.cpp
===================================================================
--- sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefault.cpp	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefault.cpp	2014-06-09 22:32:06 UTC (rev 8190)
@@ -283,7 +283,7 @@
                 Ptr<MgUserInformation> userInfo = MgUserInformation::GetCurrentUserInfo();
                 siteConn->Open(userInfo);
                 map = new MgMap(siteConn);
-                map->Create(resourceService, resource, mapString);
+                map->Create(resourceService, resource, mapString, false /* Allow MgMap to be created from any tile provider if resource is tile set */);
                 cachedMap = new MgMemoryStreamHelper();
                 Ptr<MgStream> stream = new MgStream(cachedMap);
                 map->Serialize(stream);
@@ -295,8 +295,14 @@
             }
         }   // end of mutex scope
 
-        double scale = map->GetFiniteDisplayScaleAt(scaleIndex);
-        map->SetViewScale(scale);
+        //Some tile providers (eg. XYZ) may not work with pre-defined scale lists, so the scale index doesn't
+        //resolve to some position in a finite scale list (that won't exist for XYZ), but rather it is part of 
+        //some formula used to determine the appropriate scale
+        if (map->GetFiniteDisplayScaleCount() > 0)
+        {
+            double scale = map->GetFiniteDisplayScaleAt(scaleIndex);
+            map->SetViewScale(scale);
+        }
 
         // Render the tile and cache it.
         ret = RenderAndCacheTile(tilePathname, map, scaleIndex, baseMapLayerGroupName, tileColumn, tileRow);
@@ -418,7 +424,7 @@
     return ret.Detach();
 }
 
-                                                ///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
 // render a tile and store it in the cache
 MgByteReader* MgTileCacheDefault::RenderAndCacheTile(CREFSTRING tilePathname, MgMap* map, INT32 scaleIndex,
     CREFSTRING baseMapLayerGroupName, INT32 tileColumn, INT32 tileRow)

Modified: sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefault.h
===================================================================
--- sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefault.h	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefault.h	2014-06-09 22:32:06 UTC (rev 8190)
@@ -63,6 +63,8 @@
     virtual STRING GetFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
     virtual STRING CreateFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
 
+    virtual MgByteReader* RenderAndCacheTile(CREFSTRING tilePathname, MgMap* map, INT32 scaleIndex, CREFSTRING baseMapLayerGroupName, INT32 tileColumn, INT32 tileRow);
+
     MgByteReader* GetTileForResource(MgResourceIdentifier* resource,
                                      CREFSTRING baseMapLayerGroupName,
                                      INT32 tileColumn,
@@ -71,17 +73,15 @@
 
     STRING GetBasePathFromResourceId(MgResourceIdentifier* resId, CREFSTRING rootPath);
 
+    void Set(MgByteReader* img, CREFSTRING path);
+    MgByteReader* Get(CREFSTRING path);
+
 private:
     MgByteReader* GetTileForMap(CREFSTRING baseMapLayerGroupName,
                                 INT32 tileColumn,
                                 INT32 tileRow,
                                 INT32 scaleIndex);
 
-    MgByteReader* RenderAndCacheTile(CREFSTRING tilePathname, MgMap* map, INT32 scaleIndex, CREFSTRING baseMapLayerGroupName, INT32 tileColumn, INT32 tileRow);
-
-    void Set(MgByteReader* img, CREFSTRING path);
-    MgByteReader* Get(CREFSTRING path);
-
     void GeneratePathNames(int scaleIndex,
         CREFSTRING group, int tileColumn, int tileRow,
         STRING& tilePathname, STRING& lockPathname, bool createFullPath);

Modified: sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefaultProvider.cpp
===================================================================
--- sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefaultProvider.cpp	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefaultProvider.cpp	2014-06-09 22:32:06 UTC (rev 8190)
@@ -18,13 +18,14 @@
 #include "MapGuideCommon.h"
 #include "TileCacheDefaultProvider.h"
 
-MgTileCacheDefaultProvider::MgTileCacheDefaultProvider(MgResourceIdentifier* tileSetId, CREFSTRING path, INT32 tileWidth, INT32 tileHeight, CREFSTRING format)
+MgTileCacheDefaultProvider::MgTileCacheDefaultProvider(MgResourceIdentifier* tileSetId, CREFSTRING path, INT32 tileWidth, INT32 tileHeight, CREFSTRING format, bool bRenderOnly)
 {
     m_tilesetId = SAFE_ADDREF(tileSetId);
     m_path = path;
     m_tileWidth = tileWidth;
     m_tileHeight = tileHeight;
     m_format = format;
+    m_renderOnly = bRenderOnly;
 }
 
 MgTileCacheDefaultProvider::~MgTileCacheDefaultProvider()
@@ -46,6 +47,41 @@
     return ret.Detach();
 }
 
+///////////////////////////////////////////////////////////////////////////////
+// render a tile and store it in the cache
+MgByteReader* MgTileCacheDefaultProvider::RenderAndCacheTile(CREFSTRING tilePathname, MgMap* map, INT32 scaleIndex,
+    CREFSTRING baseMapLayerGroupName, INT32 tileColumn, INT32 tileRow)
+{
+    Ptr<MgByteReader> img;
+
+    // get a rendering service instance
+    MgServiceManager* serviceMan = MgServiceManager::GetInstance();
+    assert(NULL != serviceMan);
+    Ptr<MgRenderingService> svcRendering = dynamic_cast<MgRenderingService*>(
+        serviceMan->RequestService(MgServiceType::RenderingService));
+    assert(NULL != svcRendering);
+
+    if (svcRendering != NULL)
+    {
+        // generate the tile
+        img = svcRendering->RenderTile(map, baseMapLayerGroupName, tileColumn, tileRow, GetDefaultTileSizeX(), GetDefaultTileSizeY(), map->GetDisplayDpi(), GetTileFormat());
+
+        // cache the tile
+        if (!m_renderOnly)
+        {
+            Set(img, tilePathname);
+
+            // rewind the reader since setting the tile advances it to the end
+            if (img)
+            {
+                img->Rewind();
+            }
+        }
+    }
+
+    return img.Detach();
+}
+
 INT32 MgTileCacheDefaultProvider::GetDefaultTileSizeX()
 {
     return m_tileWidth;

Modified: sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefaultProvider.h
===================================================================
--- sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefaultProvider.h	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefaultProvider.h	2014-06-09 22:32:06 UTC (rev 8190)
@@ -22,7 +22,7 @@
 class MG_SERVER_TILE_API MgTileCacheDefaultProvider : public MgTileCacheDefault
 {
 public:
-    MgTileCacheDefaultProvider(MgResourceIdentifier* tileSetId, CREFSTRING path, INT32 tileWidth, INT32 tileHeight, CREFSTRING format);
+    MgTileCacheDefaultProvider(MgResourceIdentifier* tileSetId, CREFSTRING path, INT32 tileWidth, INT32 tileHeight, CREFSTRING format, bool bRenderOnly);
     virtual ~MgTileCacheDefaultProvider();
 
     virtual MgByteReader* GetTile(CREFSTRING baseMapLayerGroupName,
@@ -30,6 +30,8 @@
                                   INT32 tileRow,
                                   INT32 scaleIndex);
 
+    virtual MgByteReader* RenderAndCacheTile(CREFSTRING tilePathname, MgMap* map, INT32 scaleIndex, CREFSTRING baseMapLayerGroupName, INT32 tileColumn, INT32 tileRow);
+
     virtual INT32 GetDefaultTileSizeX();
 
     virtual INT32 GetDefaultTileSizeY();
@@ -50,6 +52,7 @@
     INT32 m_tileWidth;
     INT32 m_tileHeight;
     STRING m_format;
+    bool m_renderOnly;
 };
 
 #endif
\ No newline at end of file

Modified: sandbox/jng/tiling/Server/src/UnitTesting/TestMdfModel.cpp
===================================================================
--- sandbox/jng/tiling/Server/src/UnitTesting/TestMdfModel.cpp	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/Server/src/UnitTesting/TestMdfModel.cpp	2014-06-09 22:32:06 UTC (rev 8190)
@@ -888,28 +888,66 @@
         MdfModel::TileStoreParameters* tilesetParams = tileset->GetTileStoreParameters();
         CPPUNIT_ASSERT(NULL != tilesetParams);
         CPPUNIT_ASSERT(L"Default" == tilesetParams->GetTileProvider());
-        CPPUNIT_ASSERT(256 == tilesetParams->GetTileWidth());
-        CPPUNIT_ASSERT(256 == tilesetParams->GetTileHeight());
-        CPPUNIT_ASSERT(L"PNG" == tilesetParams->GetFormat());
 
+        STRING path;
+        INT32 width;
+        INT32 height;
+        STRING format;
+        FINITESCALES scales;
+
+        MdfModel::NameStringPairCollection* parameters = tilesetParams->GetParameters();
+        for (INT32 i = 0; i < parameters->GetCount(); i++)
+        {
+            MdfModel::NameStringPair* pair = parameters->GetAt(i);
+            if (pair->GetName() == L"TilePath")
+            {
+                path = pair->GetValue();
+            }
+            else if (pair->GetName() == L"TileWidth")
+            {
+                width = MgUtil::StringToInt32(pair->GetValue());
+            }
+            else if (pair->GetName() == L"TileHeight")
+            {
+                height = MgUtil::StringToInt32(pair->GetValue());
+            }
+            else if (pair->GetName() == L"TileFormat")
+            {
+                format = pair->GetValue();
+            }
+            else if (pair->GetName() == L"FiniteScaleList") //NOXLATE
+            {
+                Ptr<MgStringCollection> values = MgStringCollection::ParseCollection(pair->GetValue(), L","); //NOXLATE
+                for (INT32 i = 0; i < values->GetCount(); i++)
+                {
+                    double val = MgUtil::StringToDouble(values->GetItem(i));
+                    scales.push_back(val);
+                }
+            }
+        }
+
+        CPPUNIT_ASSERT(256 == width);
+        CPPUNIT_ASSERT(256 == height);
+        CPPUNIT_ASSERT(L"PNG" == format);
+        CPPUNIT_ASSERT(MgResourceTag::TileCachePath == path);
+
         const MdfModel::Box2D& extents = tileset->GetExtents();
         CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.79786601383196, extents.GetMinX(), 0.00000000000001);
         CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.686857862181,   extents.GetMinY(), 0.000000000001);
         CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.66452777186925, extents.GetMaxX(), 0.00000000000001);
         CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.8037962206133,  extents.GetMaxY(), 0.0000000000001);
 
-        MdfModel::DisplayScaleCollection* scales = tileset->GetFiniteDisplayScales();
-        CPPUNIT_ASSERT(10 == scales->GetCount());
-        CPPUNIT_ASSERT(200000 == scales->GetAt(0)->GetValue());
-        CPPUNIT_ASSERT(100000 == scales->GetAt(1)->GetValue());
-        CPPUNIT_ASSERT(50000 == scales->GetAt(2)->GetValue());
-        CPPUNIT_ASSERT(25000 == scales->GetAt(3)->GetValue());
-        CPPUNIT_ASSERT(12500 == scales->GetAt(4)->GetValue());
-        CPPUNIT_ASSERT(6250 == scales->GetAt(5)->GetValue());
-        CPPUNIT_ASSERT(3125 == scales->GetAt(6)->GetValue());
-        CPPUNIT_ASSERT(1562.5 == scales->GetAt(7)->GetValue());
-        CPPUNIT_ASSERT(781.25 == scales->GetAt(8)->GetValue());
-        CPPUNIT_ASSERT(390.625 == scales->GetAt(9)->GetValue());
+        CPPUNIT_ASSERT(10 == scales.size());
+        CPPUNIT_ASSERT(200000 == scales.at(0));
+        CPPUNIT_ASSERT(100000 == scales.at(1));
+        CPPUNIT_ASSERT(50000 == scales.at(2));
+        CPPUNIT_ASSERT(25000 == scales.at(3));
+        CPPUNIT_ASSERT(12500 == scales.at(4));
+        CPPUNIT_ASSERT(6250 == scales.at(5));
+        CPPUNIT_ASSERT(3125 == scales.at(6));
+        CPPUNIT_ASSERT(1562.5 == scales.at(7));
+        CPPUNIT_ASSERT(781.25 == scales.at(8));
+        CPPUNIT_ASSERT(390.625 == scales.at(9));
 
         MdfModel::BaseMapLayerGroupCollection* groups = tileset->GetBaseMapLayerGroups();
         CPPUNIT_ASSERT(1 == groups->GetCount());

Modified: sandbox/jng/tiling/UnitTest/TestData/TileService/UT_BaseMap.tsd
===================================================================
--- sandbox/jng/tiling/UnitTest/TestData/TileService/UT_BaseMap.tsd	2014-06-09 15:08:22 UTC (rev 8189)
+++ sandbox/jng/tiling/UnitTest/TestData/TileService/UT_BaseMap.tsd	2014-06-09 22:32:06 UTC (rev 8190)
@@ -2,31 +2,37 @@
 <TileSetDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="TileSetDefinition-3.0.0.xsd">
   <TileStoreParameters>
     <TileProvider>Default</TileProvider>
-    <TileWidth>256</TileWidth>
-    <TileHeight>256</TileHeight>
-    <Format>PNG</Format>
     <Parameter>
       <Name>TilePath</Name>
       <Value>%MG_TILE_CACHE_PATH%</Value>
     </Parameter>
+    <Parameter>
+      <Name>TileWidth</Name>
+      <Value>256</Value>
+    </Parameter>
+    <Parameter>
+      <Name>TileHeight</Name>
+      <Value>256</Value>
+    </Parameter>
+    <Parameter>
+      <Name>TileFormat</Name>
+      <Value>PNG</Value>
+    </Parameter>
+    <Parameter>
+      <Name>FiniteScaleList</Name>
+      <Value>200000,100000,50000,25000,12500,6250,3125,1562.5,781.25,390.625</Value>
+    </Parameter>
+    <Parameter>
+      <Name>CoordinateSystem</Name>
+      <Value>GEOGCS["LL84",DATUM["WGS 84",SPHEROID["WGS 84",6378137,298.25722293287],TOWGS84[0,0,0,0,0,0,0]],PRIMEM["Greenwich",0],UNIT["Degrees",0.01745329252]]</Value>
+    </Parameter>
   </TileStoreParameters>
-  <CoordinateSystem>GEOGCS["LL84",DATUM["WGS 84",SPHEROID["WGS 84",6378137,298.25722293287],TOWGS84[0,0,0,0,0,0,0]],PRIMEM["Greenwich",0],UNIT["Degrees",0.01745329252]]</CoordinateSystem>
   <Extents>
     <MinX>-87.79786601383196</MinX>
     <MaxX>-87.66452777186925</MaxX>
     <MinY>43.6868578621819</MinY>
     <MaxY>43.8037962206133</MaxY>
   </Extents>
-  <FiniteDisplayScale>200000</FiniteDisplayScale>
-  <FiniteDisplayScale>100000</FiniteDisplayScale>
-  <FiniteDisplayScale>50000</FiniteDisplayScale>
-  <FiniteDisplayScale>25000</FiniteDisplayScale>
-  <FiniteDisplayScale>12500</FiniteDisplayScale>
-  <FiniteDisplayScale>6250</FiniteDisplayScale>
-  <FiniteDisplayScale>3125</FiniteDisplayScale>
-  <FiniteDisplayScale>1562.5</FiniteDisplayScale>
-  <FiniteDisplayScale>781.25</FiniteDisplayScale>
-  <FiniteDisplayScale>390.625</FiniteDisplayScale>
   <BaseMapLayerGroup>
     <Name>BaseLayers</Name>
     <Visible>true</Visible>



More information about the mapguide-commits mailing list