[mapguide-commits] r9500 - in sandbox/jng/tiling_v2: Common/MapGuideCommon/Services Server/src/PostBuild Server/src/Services/Rendering Server/src/Services/Tile Server/src/UnitTesting UnitTest/TestData/TileService

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Fri May 3 05:33:01 PDT 2019


Author: jng
Date: 2019-05-03 05:33:01 -0700 (Fri, 03 May 2019)
New Revision: 9500

Added:
   sandbox/jng/tiling_v2/UnitTest/TestData/TileService/UT_BaseMap_Metatiled.tsd
   sandbox/jng/tiling_v2/UnitTest/TestData/TileService/UT_XYZ_Metatiled.tsd
Modified:
   sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/TileDefs.h
   sandbox/jng/tiling_v2/Server/src/PostBuild/PostBuild.mak
   sandbox/jng/tiling_v2/Server/src/Services/Rendering/ImageProcessor.h
   sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.h
   sandbox/jng/tiling_v2/Server/src/Services/Tile/ServerTileService.cpp
   sandbox/jng/tiling_v2/Server/src/Services/Tile/ServerTileService.h
   sandbox/jng/tiling_v2/Server/src/Services/Tile/ServerTileService.vcxproj
   sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefault.cpp
   sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefault.h
   sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefaultProvider.cpp
   sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefaultProvider.h
   sandbox/jng/tiling_v2/Server/src/UnitTesting/TestTileService.cpp
   sandbox/jng/tiling_v2/Server/src/UnitTesting/TestTileService.h
Log:
Initial attempt to retrofit metatiling into the tile service using the default tile set provider. Unit test added to exercise metatile rendering via GetTile on a enabled tile set definition.

Modified: sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/TileDefs.h
===================================================================
--- sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/TileDefs.h	2019-04-26 08:49:04 UTC (rev 9499)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/TileDefs.h	2019-05-03 12:33:01 UTC (rev 9500)
@@ -70,4 +70,6 @@
 #define MG_TILE_PROVIDER_COMMON_PARAM_METATILEFACTOR     L"MetaTileFactor"
 #define MG_TILE_PROVIDER_COMMON_PARAM_METATILELOCKMETHOD L"MetaTileLockMethod"
 
+#define MG_METATILE_MAX_FACTOR 8
+
 #endif

Modified: sandbox/jng/tiling_v2/Server/src/PostBuild/PostBuild.mak
===================================================================
--- sandbox/jng/tiling_v2/Server/src/PostBuild/PostBuild.mak	2019-04-26 08:49:04 UTC (rev 9499)
+++ sandbox/jng/tiling_v2/Server/src/PostBuild/PostBuild.mak	2019-05-03 12:33:01 UTC (rev 9500)
@@ -166,6 +166,8 @@
         ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
         ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
         ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+        ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd \
+        ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd \
         ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
         ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
         ..\..\bin\UnitTestFiles\UT_Parcels.fs \
@@ -443,6 +445,8 @@
         ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
         ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
         ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+        ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd \
+        ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd \
         ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
         ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
         ..\..\bin\UnitTestFiles\UT_Parcels.fs \
@@ -720,6 +724,8 @@
           ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
           ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
           ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+          ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd \
+          ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd \
           ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
           ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
           ..\..\bin\UnitTestFiles\UT_Parcels.fs \
@@ -997,6 +1003,8 @@
           ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
           ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
           ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+          ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd \
+          ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd \
           ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
           ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
           ..\..\bin\UnitTestFiles\UT_Parcels.fs \
@@ -1146,7 +1154,9 @@
     if EXIST ..\..\bin\UnitTestFiles\TEST.sdf                       del /F ..\..\bin\UnitTestFiles\TEST.sdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
-    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                        del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                     del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd       del /F ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd           del /F ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd
     if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
@@ -1292,6 +1302,8 @@
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
     if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                     del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd       del /F ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd           del /F ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd
     if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
@@ -1437,6 +1449,8 @@
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
     if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                     del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd       del /F ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd           del /F ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd
     if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
@@ -1580,6 +1594,8 @@
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
     if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                     del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd       del /F ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd           del /F ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd
     if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
@@ -1850,6 +1866,8 @@
         ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
         ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
         ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+        ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd \
+        ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd \
         ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
         ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
         ..\..\bin\UnitTestFiles\UT_Parcels.fs \
@@ -2120,6 +2138,8 @@
         ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
         ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
         ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+        ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd \
+        ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd \
         ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
         ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
         ..\..\bin\UnitTestFiles\UT_Parcels.fs \
@@ -2390,6 +2410,8 @@
           ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
           ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
           ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+          ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd \
+          ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd \
           ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
           ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
           ..\..\bin\UnitTestFiles\UT_Parcels.fs \
@@ -2660,6 +2682,8 @@
           ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
           ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
           ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+          ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd \
+          ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd \
           ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
           ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
           ..\..\bin\UnitTestFiles\UT_Parcels.fs \
@@ -2802,7 +2826,9 @@
     if EXIST ..\..\bin\UnitTestFiles\TEST.sdf                       del /F ..\..\bin\UnitTestFiles\TEST.sdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
-    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                        del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                     del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd       del /F ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd           del /F ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd
     if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
@@ -2940,7 +2966,9 @@
     if EXIST ..\..\bin\UnitTestFiles\TEST.sdf                       del /F ..\..\bin\UnitTestFiles\TEST.sdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
-    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                        del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                     del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd       del /F ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd           del /F ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd
     if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
@@ -3078,7 +3106,9 @@
     if EXIST ..\..\bin\UnitTestFiles\TEST.sdf                       del /F ..\..\bin\UnitTestFiles\TEST.sdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
-    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                        del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                     del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd       del /F ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd           del /F ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd
     if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
@@ -3214,7 +3244,9 @@
     if EXIST ..\..\bin\UnitTestFiles\TEST.sdf                       del /F ..\..\bin\UnitTestFiles\TEST.sdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
-    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                        del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                     del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd       del /F ..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd           del /F ..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd
     if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
@@ -3363,6 +3395,8 @@
 "..\..\..\UnitTest\TestData\TileService\UT_BaseMap.mdf" :
 "..\..\..\UnitTest\TestData\TileService\UT_BaseMap.tsd" :
 "..\..\..\UnitTest\TestData\TileService\UT_XYZ.tsd" :
+"..\..\..\UnitTest\TestData\TileService\UT_BaseMap_Metatiled.tsd" :
+"..\..\..\UnitTest\TestData\TileService\UT_XYZ_Metatiled.tsd" :
 "..\..\..\UnitTest\TestData\TileService\UT_LinkedTileSet.mdf" :
 "..\..\..\UnitTest\TestData\TileService\UT_StylizationFuncs.mdf" :
 "..\..\..\UnitTest\TestData\TileService\UT_Parcels.fs" :
@@ -3631,6 +3665,14 @@
     if NOT EXIST ..\..\bin\UnitTestFiles\nul mkdir ..\..\bin\UnitTestFiles
     if EXIST "..\..\..\UnitTest\TestData\TileService\UT_XYZ.tsd" xcopy /r /d /y "..\..\..\UnitTest\TestData\TileService\UT_XYZ.tsd" ..\..\bin\UnitTestFiles\
 
+..\..\bin\UnitTestFiles\UT_BaseMap_Metatiled.tsd : "..\..\..\UnitTest\TestData\TileService\UT_BaseMap_Metatiled.tsd"
+    if NOT EXIST ..\..\bin\UnitTestFiles\nul mkdir ..\..\bin\UnitTestFiles
+    if EXIST "..\..\..\UnitTest\TestData\TileService\UT_BaseMap_Metatiled.tsd" xcopy /r /d /y "..\..\..\UnitTest\TestData\TileService\UT_BaseMap_Metatiled.tsd" ..\..\bin\UnitTestFiles\
+
+..\..\bin\UnitTestFiles\UT_XYZ_Metatiled.tsd : "..\..\..\UnitTest\TestData\TileService\UT_XYZ_Metatiled.tsd"
+    if NOT EXIST ..\..\bin\UnitTestFiles\nul mkdir ..\..\bin\UnitTestFiles
+    if EXIST "..\..\..\UnitTest\TestData\TileService\UT_XYZ_Metatiled.tsd" xcopy /r /d /y "..\..\..\UnitTest\TestData\TileService\UT_XYZ_Metatiled.tsd" ..\..\bin\UnitTestFiles\
+
 ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf : "..\..\..\UnitTest\TestData\TileService\UT_LinkedTileSet.mdf"
     if NOT EXIST ..\..\bin\UnitTestFiles\nul mkdir ..\..\bin\UnitTestFiles
     if EXIST "..\..\..\UnitTest\TestData\TileService\UT_LinkedTileSet.mdf" xcopy /r /d /y "..\..\..\UnitTest\TestData\TileService\UT_LinkedTileSet.mdf" ..\..\bin\UnitTestFiles\

Modified: sandbox/jng/tiling_v2/Server/src/Services/Rendering/ImageProcessor.h
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/ImageProcessor.h	2019-04-26 08:49:04 UTC (rev 9499)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/ImageProcessor.h	2019-05-03 12:33:01 UTC (rev 9500)
@@ -18,6 +18,8 @@
 #ifndef MGIMAGEPROCESSOR_H
 #define MGIMAGEPROCESSOR_H
 
+class RS_Color;
+class Renderer;
 class SE_Renderer;
 
 class MgIRendererFactory

Modified: sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.h
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.h	2019-04-26 08:49:04 UTC (rev 9499)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.h	2019-05-03 12:33:01 UTC (rev 9500)
@@ -21,6 +21,7 @@
 #include "ServerRenderingDllExport.h"
 #include "ImageProcessor.h"
 
+struct RS_Bounds;
 class SE_Renderer;
 class FeatureInfoRenderer;
 class MgFeatureInformation;

Modified: sandbox/jng/tiling_v2/Server/src/Services/Tile/ServerTileService.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Tile/ServerTileService.cpp	2019-04-26 08:49:04 UTC (rev 9499)
+++ sandbox/jng/tiling_v2/Server/src/Services/Tile/ServerTileService.cpp	2019-05-03 12:33:01 UTC (rev 9500)
@@ -26,13 +26,17 @@
 MgServerTileService::MgServerTileService() : MgTileService()
 {
     MgTileCacheDefault::Initialize();
+
+    MgConfiguration* pConf = MgConfiguration::GetInstance();
+    pConf->GetStringValue(MgConfigProperties::GeneralPropertiesSection,
+        MgConfigProperties::GeneralPropertyRenderer,
+        m_rendererName,
+        MgConfigProperties::DefaultGeneralPropertyRenderer);
 }
 
 MgServerTileService::~MgServerTileService()
-{
+{ }
 
-}
-
 MgByteReader* MgServerTileService::GetTile(
     MgMap* map,
     CREFSTRING baseMapLayerGroupName,
@@ -589,7 +593,7 @@
             path = MgTileParameters::tileCachePath;
         }
 
-        cache = new MgTileCacheDefaultProvider(tileSetId, path, width, height, format, bRenderOnly, tileExtentOffset, metaTileFactor, metaTileLockMethod);
+        cache = new MgTileCacheDefaultProvider(tileSetId, path, width, height, format, bRenderOnly, tileExtentOffset, m_rendererName, metaTileFactor, metaTileLockMethod);
     }
     else if (provider == MG_TILE_PROVIDER_XYZ)
     {

Modified: sandbox/jng/tiling_v2/Server/src/Services/Tile/ServerTileService.h
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Tile/ServerTileService.h	2019-04-26 08:49:04 UTC (rev 9499)
+++ sandbox/jng/tiling_v2/Server/src/Services/Tile/ServerTileService.h	2019-05-03 12:33:01 UTC (rev 9500)
@@ -78,6 +78,8 @@
 private:
     MgTileCache* GetTileCache(MgResourceIdentifier* resource);
     MgTileCache* GetTileCache(MgResourceIdentifier* tileSetId, MdfModel::TileSetDefinition* tileset);
+
+    STRING m_rendererName;
 };
 
 #endif

Modified: sandbox/jng/tiling_v2/Server/src/Services/Tile/ServerTileService.vcxproj
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Tile/ServerTileService.vcxproj	2019-04-26 08:49:04 UTC (rev 9499)
+++ sandbox/jng/tiling_v2/Server/src/Services/Tile/ServerTileService.vcxproj	2019-05-03 12:33:01 UTC (rev 9500)
@@ -94,7 +94,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\MdfParser;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\dbxml\xerces-c-src\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\MdfParser;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Rendering;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\dbxml\xerces-c-src\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MG_SERVER_TILE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -120,7 +120,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\MdfParser;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\dbxml\xerces-c-src\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\MdfParser;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Rendering;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\dbxml\xerces-c-src\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MG_SERVER_TILE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -146,7 +146,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
-      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\MdfParser;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\dbxml\xerces-c-src\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\MdfParser;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Rendering;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\dbxml\xerces-c-src\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MG_SERVER_TILE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
@@ -173,7 +173,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
-      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\MdfParser;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\dbxml\xerces-c-src\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\MdfParser;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Rendering;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\dbxml\xerces-c-src\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MG_SERVER_TILE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
@@ -336,6 +336,10 @@
       <Project>{adbf25e2-c629-4832-b315-f12abde05632}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\Rendering\ServerRenderingService.vcxproj">
+      <Project>{561F38EE-E22F-481A-8EFB-DC0AA25B4C20}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

Modified: sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefault.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefault.cpp	2019-04-26 08:49:04 UTC (rev 9499)
+++ sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefault.cpp	2019-05-03 12:33:01 UTC (rev 9500)
@@ -218,8 +218,6 @@
     while (NULL == ret)
     {
         // Attempt use a cached & serialized MgMap object
-        Ptr<MgMemoryStreamHelper> cachedMap;
-        STRING mapString = resource->ToString();
         Ptr<MgMap> map;
 
         // Protect the serialized MgMap cache with a mutex.  Stream reading is not
@@ -264,32 +262,7 @@
             {
                 ACE_OS::fclose(lockFile);
             }
-
-            MapCache::const_iterator iter = sm_mapCache.find(mapString);
-            if (sm_mapCache.end() != iter)
-            {
-                cachedMap = SAFE_ADDREF((*iter).second);
-                cachedMap->Rewind();
-                Ptr<MgStream> stream = new MgStream(cachedMap);
-                map = new MgMap();
-                map->Deserialize(stream);
-            }
-            else
-            {
-                Ptr<MgSiteConnection> siteConn = new MgSiteConnection();
-                Ptr<MgUserInformation> userInfo = MgUserInformation::GetCurrentUserInfo();
-                siteConn->Open(userInfo);
-                map = new MgMap(siteConn);
-                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);
-                if ((INT32)sm_mapCache.size() >= sm_mapCacheSize)
-                {
-                    ClearMapCache(L"");
-                }
-                sm_mapCache[mapString] = SAFE_ADDREF((MgMemoryStreamHelper*)cachedMap);
-            }
+            GetMapFromDefinition(resource, scaleIndex, map, false /* Allow MgMap to be created from any tile provider if resource is tile set */);
         }   // end of mutex scope
 
         //Some tile providers (eg. XYZ) may not work with pre-defined scale lists, so the scale index doesn't
@@ -931,3 +904,43 @@
 
     return sm_mapCache.empty();
 }
+
+///////////////////////////////////////////////////////////////////////////////
+/// helper to retrieve map
+///////////////////////////////////////////////////////////////////////////////
+void MgTileCacheDefault::GetMapFromDefinition(MgResourceIdentifier* mapDefinition, INT32 scaleIndex, Ptr<MgMap> &map, bool bStrictCreate)
+{
+    // Attempt use a cached & serialized MgMap object
+    Ptr<MgMemoryStreamHelper> cachedMap;
+    STRING mapString = mapDefinition->ToString();
+
+    MapCache::const_iterator iter = sm_mapCache.find(mapString);
+    if (sm_mapCache.end() != iter)
+    {
+        cachedMap = SAFE_ADDREF((*iter).second);
+        cachedMap->Rewind();
+        Ptr<MgStream> stream = new MgStream(cachedMap);
+        map = new MgMap();
+        map->Deserialize(stream);
+    }
+    else
+    {
+        // get the service from our helper method
+        Ptr<MgResourceService> resourceService = GetResourceServiceForMapDef(mapDefinition, L"MgTileCacheDefault.GetMapFromDefinition");
+        Ptr<MgSiteConnection> siteConn = new MgSiteConnection();
+        siteConn->Open(MgUserInformation::GetCurrentUserInfo());
+        map = new MgMap(siteConn);
+        map->Create(resourceService, mapDefinition, mapString, bStrictCreate);
+        cachedMap = new MgMemoryStreamHelper();
+        Ptr<MgStream> stream = new MgStream(cachedMap);
+        map->Serialize(stream);
+        if ((INT32)sm_mapCache.size() >= sm_mapCacheSize)
+        {
+            ClearMapCache(L"");
+        }
+        sm_mapCache[mapString] = SAFE_ADDREF((MgMemoryStreamHelper*)cachedMap);
+    }
+
+    double scale = map->GetFiniteDisplayScaleAt(scaleIndex);
+    map->SetViewScale(scale);
+}
\ No newline at end of file

Modified: sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefault.h
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefault.h	2019-04-26 08:49:04 UTC (rev 9499)
+++ sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefault.h	2019-05-03 12:33:01 UTC (rev 9500)
@@ -79,6 +79,16 @@
     void Set(MgByteReader* img, CREFSTRING path);
     MgByteReader* Get(CREFSTRING path);
 
+    void GetMapFromDefinition(MgResourceIdentifier* mapDefinition, INT32 scaleIndex, Ptr<MgMap> &map, bool bStrictCreate = true);
+
+    bool DetectTileLockFile(CREFSTRING lockPathname);
+
+    void GeneratePathNames(int scaleIndex,
+        CREFSTRING group, int tileColumn, int tileRow,
+        STRING& tilePathname, STRING& lockPathname, bool createFullPath);
+
+    STRING CreateFullPath(int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
+
 private:
     MgByteReader* GetTileForMap(CREFSTRING baseMapLayerGroupName,
                                 INT32 tileColumn,
@@ -85,14 +95,7 @@
                                 INT32 tileRow,
                                 INT32 scaleIndex);
 
-    void GeneratePathNames(int scaleIndex,
-        CREFSTRING group, int tileColumn, int tileRow,
-        STRING& tilePathname, STRING& lockPathname, bool createFullPath);
-
     STRING GetFullPath(int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
-    
-    STRING CreateFullPath(int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
-
     STRING GetScaleIndexFolder(int scaleIndex);
     STRING GetRowFolder(int tileRow);
     STRING GetColumnFolder(int tileColumn);
@@ -101,7 +104,6 @@
     STRING GetTileIndexString(int tileIndex, int tilesPerFolder);
 
     MgResourceService* GetResourceServiceForMapDef(MgResourceIdentifier* mapDefinition, CREFSTRING funcName);
-    bool DetectTileLockFile(CREFSTRING lockPathname);
 
     Ptr<MgResourceIdentifier> m_resourceId;
     Ptr<MgMap> m_map;

Modified: sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefaultProvider.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefaultProvider.cpp	2019-04-26 08:49:04 UTC (rev 9499)
+++ sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefaultProvider.cpp	2019-05-03 12:33:01 UTC (rev 9500)
@@ -17,16 +17,22 @@
 
 #include "MapGuideCommon.h"
 #include "TileCacheDefaultProvider.h"
+#include "ServerRenderingService.h"
 
+std::map<STRING, ACE_Condition<ACE_Recursive_Thread_Mutex>*> MgTileCacheDefaultProvider::sm_lockMap;
+ACE_Recursive_Thread_Mutex MgTileCacheDefaultProvider::sm_MetaTileMutex;
+ACE_Recursive_Thread_Mutex MgTileCacheDefaultProvider::sm_tileMutex;
+
 MgTileCacheDefaultProvider::MgTileCacheDefaultProvider(MgResourceIdentifier* tileSetId,
-                                                       CREFSTRING path,
-                                                       INT32 tileWidth,
-                                                       INT32 tileHeight,
-                                                       CREFSTRING format,
-                                                       bool bRenderOnly,
-                                                       double tileExtentOffset,
-                                                       INT32 metaTileFactor,
-                                                       INT32 metaTileLockMethod)
+    CREFSTRING path,
+    INT32 tileWidth,
+    INT32 tileHeight,
+    CREFSTRING format,
+    bool bRenderOnly,
+    double tileExtentOffset,
+    CREFSTRING rendererName,
+    INT32 metaTileFactor,
+    INT32 metaTileLockMethod)
 {
     m_tilesetId = SAFE_ADDREF(tileSetId);
     m_path = path;
@@ -35,6 +41,7 @@
     m_format = format;
     m_renderOnly = bRenderOnly;
     m_tileExtentOffset = tileExtentOffset;
+    m_rendererName = rendererName;
     m_metaTileFactor = metaTileFactor;
     m_metaTileLockMethod = metaTileLockMethod;
 }
@@ -45,17 +52,20 @@
 }
 
 MgByteReader* MgTileCacheDefaultProvider::GetTile(CREFSTRING baseMapLayerGroupName,
-                                                  INT32 tileColumn,
-                                                  INT32 tileRow,
-                                                  INT32 scaleIndex)
+    INT32 tileColumn,
+    INT32 tileRow,
+    INT32 scaleIndex)
 {
     Ptr<MgByteReader> ret;
     MG_TRY()
 
-    ret = GetTileForResource(m_tilesetId, baseMapLayerGroupName, tileColumn, tileRow, scaleIndex);
+        if (m_metaTileFactor > 1)
+            ret = GetMetatileForResource(m_tilesetId, baseMapLayerGroupName, tileColumn, tileRow, scaleIndex);
+        else
+            ret = GetTileForResource(m_tilesetId, baseMapLayerGroupName, tileColumn, tileRow, scaleIndex);
 
     MG_CATCH_AND_THROW(L"MgTileCacheDefaultProvider.GetTile")
-    return ret.Detach();
+        return ret.Detach();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -67,10 +77,10 @@
 
     // get a rendering service instance
     MgServiceManager* serviceMan = MgServiceManager::GetInstance();
-    assert(NULL != serviceMan);
+    _ASSERT(NULL != serviceMan);
     Ptr<MgRenderingService> svcRendering = dynamic_cast<MgRenderingService*>(
         serviceMan->RequestService(MgServiceType::RenderingService));
-    assert(NULL != svcRendering);
+    _ASSERT(NULL != svcRendering);
 
     if (svcRendering != NULL)
     {
@@ -111,4 +121,387 @@
 STRING MgTileCacheDefaultProvider::GetBasePath()
 {
     return GetBasePathFromResourceId(m_tilesetId, m_path);
+}
+
+MgByteReader* MgTileCacheDefaultProvider::GetMetatileForResource(MgResourceIdentifier* resource,
+    CREFSTRING baseMapLayerGroupName,
+    INT32 tileColumn,
+    INT32 tileRow,
+    INT32 scaleIndex)
+{
+    // Must have a renderer name set
+    _ASSERT(!m_rendererName.empty());
+
+    Ptr<MgByteReader> returnedSubtile;
+    FILE* lockFile = NULL;
+    STRING tilePathname, lockPathname;
+    // metatiling vars
+    FILE* subTileLockFile[MG_METATILE_MAX_FACTOR][MG_METATILE_MAX_FACTOR];
+    STRING subTileLockPathname[MG_METATILE_MAX_FACTOR][MG_METATILE_MAX_FACTOR], subTilePathname[MG_METATILE_MAX_FACTOR][MG_METATILE_MAX_FACTOR];
+    STRING metaTileLockPathname, metaTilePathname;
+    int maxX = -1, maxY = -1, subTileX = -1, subTileY = -1, metaTileColumn = -1, metaTileRow = -1;
+    bool cacheHit = false;
+
+    MG_TRY()
+
+        // Generate tile and lock pathnames for later use
+        //m_tileCache->GeneratePathnames(mapDefinition, scaleIndex, baseMapLayerGroupName,
+        //    tileColumn, tileRow, tilePathname, lockPathname, false);
+        GeneratePathNames(scaleIndex, baseMapLayerGroupName, tileColumn, tileRow, tilePathname, lockPathname, false);
+
+    subTileX = subTileY = 0;
+    metaTileColumn = tileColumn;
+    metaTileRow = tileRow;
+
+    /*
+    ////// compute additional names and control variables to deal with meta tiles:
+    // a meta tile is m_metaTileFactor^2 larger than the requested subtile so there are less tiles computed per map
+    // the metatile coords are computed from original coords modulo metatilesize
+    // e.g. with metatile=2 4 tiles (0,0)(0,1)(1,0)(1,1) get mapped to metatile(0,0)
+    subTileX = abs(tileColumn % m_metaTileFactor);
+    subTileY = abs(tileRow % m_metaTileFactor);
+    // determine left top corner of metaTile having m_metaTileFactor**2 subtiles
+    metaTileColumn = tileColumn - subTileX;
+    metaTileRow = tileRow - subTileY;
+    */
+    maxX = maxY = m_metaTileFactor;  // init control vars
+    //// iterate subtiles and create all pathnames of the created tiles
+    for (int y = 0; y < maxY; y++)    // subtile rows
+    {
+        for (int x = 0; x < maxX; x++)    // subtile columns
+        {   // Generate tile and lock pathnames (locknames are not used)
+            subTileLockFile[x][y] = NULL;
+            //m_tileCache->GeneratePathnames(mapDefinition, scaleIndex, baseMapLayerGroupName,
+            //    metaTileColumn + x, metaTileRow + y, subTilePathname[x][y], subTileLockPathname[x][y], false);
+
+            GeneratePathNames(scaleIndex, baseMapLayerGroupName,
+                metaTileColumn + x, metaTileRow + y, subTilePathname[x][y], subTileLockPathname[x][y], false);
+        }
+    }
+
+    // Generate tile and lock pathnames for meta tile in the larger grid mod xx 
+    //m_tileCache->GeneratePathnames(mapDefinition, scaleIndex, baseMapLayerGroupName,
+    //    metaTileColumn, metaTileRow, metaTilePathname, metaTileLockPathname, false);
+    GeneratePathNames(scaleIndex, baseMapLayerGroupName,
+        metaTileColumn, metaTileRow, metaTilePathname, metaTileLockPathname, false);
+
+    // m_metaTileLockMethod == 0 is using 1 remapped metalockfile for all subtiles
+    // m_metaTileLockMethod > 0 is using 1 an ace condition mapped by metatilename
+    if (m_metaTileLockMethod)
+    {
+#ifdef _DEBUG
+        {
+            std::wstringstream text;
+            text << L"(" << ACE_OS::thr_self() << L") METATILE: " << "WaitForLock("
+                << tileRow << L", " << tileColumn << L") (" << metaTilePathname << L")\n";
+            ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+        }
+#endif
+        WaitForLock(metaTilePathname);
+    }
+    else // this is the same locking strategie as with single tiles but using one mapped metatile locking all subtile requests
+    {
+        bool fileExist = DetectTileLockFile(metaTileLockPathname);
+        if (fileExist)
+        {   // TODO: Handle the exception by displaying a tile with an error message?
+            MgFileUtil::DeleteFile(metaTileLockPathname, true);
+#ifdef _DEBUG
+            std::wstringstream text;
+            text << L"(" << ACE_OS::thr_self() << L") METATILE: " << (fileExist ? L"DeletedDanglingLockfile(" : L"NoLockfile(")
+                << metaTileRow << L", " << metaTileColumn << L") " << metaTileLockPathname << L")\n";
+            ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+#endif
+        }
+    }
+    // try getting the tile from the cache first time
+    cacheHit = returnedSubtile = Get(tilePathname);
+#ifdef _DEBUG
+    std::wstringstream text;
+    text << L"(" << ACE_OS::thr_self() << (cacheHit ? L") CACHEHIT" : L") CACHEMISS") << L": GetTile("
+        << tileRow << L", " << tileColumn << L") " << tilePathname << L"\n";
+    ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+#endif
+    // if the reader is NULL then the tile wasn't in the cache and we need to generate it
+    while (NULL == returnedSubtile) // while for if to be able to use break to skip to end;
+    {
+        Ptr<MgMap> map;
+
+        // Protect the serialized MgMap cache with a mutex.  Stream reading is not
+        // thread safe so we need to deserialize the map within the mutex to ensure
+        // that a Rewind() is not called in the middle of a Deserialize().
+        // Lockfile test and creation is in same protected scope.
+        { // ------------------------ Locking Context
+            // Attempt to get the mapcache mutex .
+            ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, ace_mon, sm_MetaTileMutex, NULL));
+            if (m_metaTileLockMethod)
+            {
+                // we DONT need the second lock test here in a signal/wait algorithm
+    //          m_tileCache->WaitForLock(metaTilePathname);
+            }
+            else
+            {
+                if (DetectTileLockFile(metaTileLockPathname)) //
+                {
+                    MgStringCollection arguments;
+                    arguments.Add(metaTileLockPathname);
+                    throw new MgFileIoException(L"MgServerTileService.GetTile",
+                        __LINE__, __WFILE__, &arguments, L"MgUnableToLockMetaTileFile", NULL);
+                }
+            }
+
+            // try getting the tile from the cache second time ???????????????????????????????????????????
+            cacheHit = returnedSubtile = Get(tilePathname);
+
+            if (NULL != returnedSubtile)
+            {
+#ifdef _DEBUG
+                std::wstringstream text;
+                text << L"(" << ACE_OS::thr_self() << L") CACHEHIT2: GetTile(" << tileRow << L", " << tileColumn << L") " << tilePathname << L"\n";
+                ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+#endif        
+                break;  /////////////////////////////////// tile was in tileCache .. done.
+            }
+            else {
+#ifdef _DEBUG
+                std::wstringstream text;
+                text << L"(" << ACE_OS::thr_self() << L") CACHEMISS2: GetTile(" << tileRow << L", " << tileColumn << L") " << tilePathname << L"\n";
+                ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+#endif
+            }
+            // Create the directory structure all subtiles!
+            for (int y = 0; y < maxY; y++)    // rows
+            {
+                for (int x = 0; x < maxX; x++)    // columns
+                {
+                    //m_tileCache->CreateFullPath(mapDefinition, scaleIndex, baseMapLayerGroupName, 
+                    //    metaTileColumn + x, metaTileRow + y);
+                    CreateFullPath(scaleIndex, baseMapLayerGroupName, metaTileColumn + x, metaTileRow + y);
+                }
+            }
+            // ==================================================  LOCKING
+            if (m_metaTileLockMethod)
+            {
+                LockTile(metaTilePathname);    // ace lock once per metatile
+            }
+            else
+            {
+                // Create the lock file 
+                lockFile = ACE_OS::fopen(MG_WCHAR_TO_TCHAR(metaTileLockPathname), ACE_TEXT("wb"));
+
+                if (NULL == lockFile)
+                {
+                    MgStringCollection arguments;
+                    arguments.Add(metaTileLockPathname);
+                    throw new MgFileIoException(L"MgServerTileService.GetTile",
+                        __LINE__, __WFILE__, &arguments, L"MgUnableToCreateLockFile", NULL);
+                }
+                else
+                {
+                    ACE_OS::fclose(lockFile); // and close it right away.
+#ifdef _DEBUG
+                    std::wstringstream text;
+                    text << L"(" << ACE_OS::thr_self() << L") METATILE: CreatedLockfile(" << metaTileRow << L", " << metaTileColumn << L") "
+                        << metaTileLockPathname << L")\n";
+                    ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+#endif
+                }
+            }
+            //=========================================================================
+            GetMapFromDefinition(resource, scaleIndex, map, false);
+        }   // end of mutex scope
+
+        // Render the larger meta tile but do not cache it yet! (m_metaTileFactor [prohibits caching in GetTile)
+        STRING metaTileName = L"META" + metaTilePathname;
+#ifdef _DEBUG
+        std::wstringstream text;
+        text << L"(" << ACE_OS::thr_self() << L") METATILE: RenderMetaTile(" << metaTileRow << L", " << metaTileColumn << L") " << metaTileName << " using map 0x" << map << L"\n";
+        ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+#endif
+        // Get a server-side rendering Service only...
+        MgServiceManager* serviceMan = MgServiceManager::GetInstance();
+        _ASSERT(NULL != serviceMan);
+        Ptr<MgServerRenderingService> svcRendering = dynamic_cast<MgServerRenderingService*>(
+            serviceMan->RequestService(MgServiceType::RenderingService));
+
+        // Bail if no server-side impl exists (we can't use proxy impl)
+        if (NULL == svcRendering)
+        {
+            throw new MgServiceNotAvailableException(L"MgTileCacheDefaultProvider.GetMetatileForResource", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+
+        //Ptr<MgByteReader> metaTileBitMap = GetTile(metaTileName, map, scaleIndex, baseMapLayerGroupName, metaTileColumn, metaTileRow);
+        INT32 tileDpi = map->GetDisplayDpi();
+        Ptr<MgMetatile> metaTile = svcRendering->RenderMetatile(map, baseMapLayerGroupName, metaTileColumn, metaTileRow, m_tileWidth, m_tileHeight, tileDpi, m_format, m_tileExtentOffset, m_metaTileFactor);
+#ifdef _DEBUG
+        Ptr<MgByteReader> mtContent = metaTile->GetImage();
+        INT32 metaTileLen = mtContent->GetLength();
+#endif
+        // splitup the meta tiles
+        for (int y = 0; y < maxY; y++)    // rows
+        {
+            for (int x = 0; x < maxX; x++)    // columns
+            {
+                // Collect the subtile from the metatile
+                Ptr<MgByteReader> img = MgImageProcessor::RenderTileFromMetaTile(map, metaTile, m_rendererName, svcRendering, x, y);
+#ifdef _DEBUG
+                INT32 tileLen = img->GetLength();
+#endif          
+                if ((subTileX == x) && (subTileY == y))
+                    returnedSubtile = img;       // keep pointer for subtile which has triggered the metatile in the current thread
+                _ASSERT(x < maxX && y < maxY);
+#ifdef _DEBUG
+                std::wstringstream text;    // streams for more compact debug statements
+                text << L"(" << ACE_OS::thr_self();
+                text << L") RenderTileFromMetaTile dim:" << m_tileWidth << L"x" << m_tileHeight;
+                text << L" format:" << m_format << L" subTile(" << x << L"," << y;
+                text << L") metaTile(" << metaTileRow << L"," << metaTileColumn << L") " << metaTilePathname.c_str() << L"\n";
+                ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+#endif
+                Set(img, subTilePathname[x][y]);   // store all subtiles in tile cache
+
+                // rewind the reader since setting the tile advances it to the end
+                if (img)
+                {
+                    img->Rewind();
+                }
+#ifdef _DEBUG
+                {
+                    std::wstringstream text;
+                    text << L"(" << ACE_OS::thr_self() << L") METATILE: " << (img ? L"SetTile" : L"NoTileReturned");
+                    text << "FromMetaTile(" << tileRow << L", " << tileColumn << L") ";
+                    text << subTilePathname[x][y] << L" S(" << x << L", " << y << L")\n";
+                    ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+                }
+#endif
+            }
+        }
+        break;
+    }   // end of gettile loop end MgMap scope
+
+    MG_CATCH(L"MgServerTileService.GetTile")
+
+        // remove all lockfiles or conditions
+        if (m_metaTileLockMethod)
+        {
+            ClearLock(metaTilePathname);
+        }
+        else
+        {
+            if (NULL != lockFile)
+            {
+                MgFileUtil::DeleteFile(metaTileLockPathname, false);
+                {
+#ifdef _DEBUG
+                    std::wstringstream text;
+                    text << L"(" << ACE_OS::thr_self() << L") METATILE: DeletedLockfile(" << metaTileRow << L", " << metaTileColumn << L") "
+                        << metaTileLockPathname << L"\n";
+                    ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+#endif
+                }
+            }
+        }
+
+    MG_THROW()
+
+        if (!cacheHit)
+        {
+#ifdef _DEBUG
+            std::wstringstream text;
+            text << L"(" << ACE_OS::thr_self() << L") Rendered: GetTILE(" << tileRow << L", " << tileColumn << L") "
+                << L" S(" << subTileX << L", " << subTileY << L") (" << tilePathname << L")\n";
+            ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+#endif
+        }
+
+    return returnedSubtile.Detach();
+}
+
+void MgTileCacheDefaultProvider::WaitForLock(CREFSTRING tilePathname)
+{
+    // protect test of lockmap entry with a guard
+    ACE_Condition<ACE_Recursive_Thread_Mutex> *tileLock = 0;
+    // look for lock and wait if found
+    ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sm_tileMutex));
+    if (tileLock = sm_lockMap[tilePathname])
+    {   // lock has been found
+#ifdef _DEBUG
+        std::wstringstream text;
+        text << L"(" << ACE_OS::thr_self() << L") METATILE: WaitForLock1("
+            << tilePathname << L")\n";
+        ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+#endif
+        //                ACE_Time_Value waitTime(METATILEWAIT);
+        int ret = tileLock->wait();    // returns -1 if timed out which is not supposed to happen
+        if (-1 == ret) // so the wait might never come back!!! and the thread gets cleaned out by the service manager
+        {
+#ifdef _DEBUG
+            std::wstringstream text;
+            text << L"(" << ACE_OS::thr_self() << L") METATILE: WaitForLockTimedOut1(" << tilePathname << L")\n";
+            ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+#endif
+            MgStringCollection arguments;
+            arguments.Add(tilePathname);
+            throw new MgFileIoException(L"MgServerTileService.GetTile",
+                __LINE__, __WFILE__, &arguments, L"MgWaitForLockTimedOut", NULL);
+        }
+#ifdef _DEBUG
+        {
+            std::wstringstream text;
+            text << L"(" << ACE_OS::thr_self() << L") METATILE: LockReleased(" << tilePathname << L")\n";
+            ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+        }
+#endif
+    }
+}
+
+void MgTileCacheDefaultProvider::ClearLock(CREFSTRING tilePathname)
+{
+    try
+    {   // synchronize access to map
+        ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sm_tileMutex));
+        ACE_Condition<ACE_Recursive_Thread_Mutex> *lock = sm_lockMap[tilePathname];
+        if (lock)
+        {
+            int result = lock->broadcast();    // notify waiters of finished tile
+#ifdef _DEBUG
+            std::wstringstream text;
+            text << L"(" << ACE_OS::thr_self() << L") METATILE: Broadcast(" << tilePathname
+                << L") returns: " << result << L"\n";
+            ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+#endif
+            sm_lockMap.erase(tilePathname); // erase only existing lock: this destroys the ace condition
+        }
+        else
+        {
+#ifdef _DEBUG
+            std::wstringstream text;
+            text << L"(" << ACE_OS::thr_self() << L") METATILE: NoLockFor(" << tilePathname << L")\n";
+            ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+#endif
+        }
+    }
+    catch (MgException* e)
+    {
+#ifdef _DEBUG
+        std::wstringstream text;
+        text << L"(" << ACE_OS::thr_self() << L") METATILE: Broadcastcrash (" << tilePathname
+            << L")\n" << e->GetExceptionMessage() << L")\n";
+        ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+#endif
+        throw e;
+    }
+}
+
+void MgTileCacheDefaultProvider::LockTile(CREFSTRING tilePathname)
+{
+    // create ace condition for this tile as we are going to make it
+    ACE_Condition<ACE_Recursive_Thread_Mutex> *tileLock = new ACE_Condition<ACE_Recursive_Thread_Mutex>(sm_tileMutex);
+    // keep reference to lock (ace condition) in our map
+    sm_lockMap[tilePathname] = tileLock;
+
+#ifdef _DEBUG
+    std::wstringstream text;
+    text << L"(" << ACE_OS::thr_self() << L") METATILE: CreateLock(" << tilePathname << L"\n";
+    ACE_DEBUG((LM_DEBUG, text.str().c_str()));
+#endif
 }
\ No newline at end of file

Modified: sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefaultProvider.h
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefaultProvider.h	2019-04-26 08:49:04 UTC (rev 9499)
+++ sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefaultProvider.h	2019-05-03 12:33:01 UTC (rev 9500)
@@ -29,6 +29,7 @@
                                CREFSTRING format,
                                bool bRenderOnly,
                                double tileExtentOffset,
+                               CREFSTRING rendererName,
                                INT32 metaTileFactor,
                                INT32 metaTileLockMethod);
     virtual ~MgTileCacheDefaultProvider();
@@ -55,6 +56,23 @@
     virtual STRING GetBasePath();
 
 private:
+    // ---------------- Begin Metatile stuff --------------------- //
+    MgByteReader* GetMetatileForResource(MgResourceIdentifier* resource,
+                                         CREFSTRING baseMapLayerGroupName,
+                                         INT32 tileColumn,
+                                         INT32 tileRow,
+                                         INT32 scaleIndex);
+
+    // use a memory based locking scheme
+    static std::map<STRING, ACE_Condition<ACE_Recursive_Thread_Mutex>*> sm_lockMap;
+    static ACE_Recursive_Thread_Mutex sm_MetaTileMutex;
+    static ACE_Recursive_Thread_Mutex sm_tileMutex;
+    void WaitForLock(CREFSTRING tilePathname);
+    void ClearLock(CREFSTRING tilePathname);
+    void LockTile(CREFSTRING tilePathname);
+
+    // ------------------- End Metatile stuff -------------------- //
+
     Ptr<MgResourceIdentifier> m_tilesetId;
     STRING m_path;
     INT32 m_tileWidth;
@@ -62,6 +80,7 @@
     STRING m_format;
     bool m_renderOnly;
     double m_tileExtentOffset;
+    STRING m_rendererName;
     INT32 m_metaTileFactor;
     INT32 m_metaTileLockMethod;
 };

Modified: sandbox/jng/tiling_v2/Server/src/UnitTesting/TestTileService.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/UnitTesting/TestTileService.cpp	2019-04-26 08:49:04 UTC (rev 9499)
+++ sandbox/jng/tiling_v2/Server/src/UnitTesting/TestTileService.cpp	2019-05-03 12:33:01 UTC (rev 9500)
@@ -23,6 +23,7 @@
 #include "ServerSiteService.h"
 #include "../Common/Manager/FdoConnectionManager.h"
 #include "FoundationDefs.h"
+#include "ServerRenderingService.h"
 #define PATH_LEN 512
 
 // determines the number of requests to make, as a factor of the number of tiles
@@ -138,6 +139,16 @@
         Ptr<MgByteReader> tsdrdr2 = tsdsrc2->GetReader();
         m_svcResource->SetResource(tilesetres2, tsdrdr2, NULL);
 
+        Ptr<MgResourceIdentifier> tilesetres3 = new MgResourceIdentifier(L"Library://UnitTests/TileSets/Sheboygan_Metatiled.TileSetDefinition");
+        Ptr<MgByteSource> tsdsrc3 = new MgByteSource(L"../UnitTestFiles/UT_BaseMap_Metatiled.tsd", false);
+        Ptr<MgByteReader> tsdrdr3 = tsdsrc3->GetReader();
+        m_svcResource->SetResource(tilesetres3, tsdrdr3, NULL);
+
+        Ptr<MgResourceIdentifier> tilesetres4 = new MgResourceIdentifier(L"Library://UnitTests/TileSets/XYZ_Metatiled.TileSetDefinition");
+        Ptr<MgByteSource> tsdsrc4 = new MgByteSource(L"../UnitTestFiles/UT_XYZ_Metatiled.tsd", false);
+        Ptr<MgByteReader> tsdrdr4 = tsdsrc4->GetReader();
+        m_svcResource->SetResource(tilesetres4, tsdrdr4, NULL);
+
         // publish the layer definitions
         Ptr<MgResourceIdentifier> ldfres1 = new MgResourceIdentifier(L"Library://UnitTests/Layers/RoadCenterLines.LayerDefinition");
         Ptr<MgByteSource> ldfsrc1 = new MgByteSource(L"../UnitTestFiles/UT_RoadCenterLines.ldf", false);
@@ -185,6 +196,7 @@
 
         // set up temporary directory for tile images
         MgFileUtil::CreateDirectory(L"./temp_tiles", false);
+        MgFileUtil::CreateDirectory(L"../UnitTestFiles/TileCaches", false);
     }
     catch (MgException* e)
     {
@@ -222,6 +234,15 @@
         Ptr<MgResourceIdentifier> tilesetres1 = new MgResourceIdentifier(L"Library://UnitTests/TileSets/Sheboygan.TileSetDefinition");
         m_svcResource->DeleteResource(tilesetres1);
 
+        Ptr<MgResourceIdentifier> tilesetres2 = new MgResourceIdentifier(L"Library://UnitTests/TileSets/XYZ.TileSetDefinition");
+        m_svcResource->DeleteResource(tilesetres2);
+
+        Ptr<MgResourceIdentifier> tilesetres3 = new MgResourceIdentifier(L"Library://UnitTests/TileSets/Sheboygan_Metatiled.TileSetDefinition");
+        m_svcResource->DeleteResource(tilesetres3);
+
+        Ptr<MgResourceIdentifier> tilesetres4 = new MgResourceIdentifier(L"Library://UnitTests/TileSets/XYZ_Metatiled.TileSetDefinition");
+        m_svcResource->DeleteResource(tilesetres4);
+
         // delete the layer definitions
         Ptr<MgResourceIdentifier> ldfres1 = new MgResourceIdentifier(L"Library://UnitTests/Layers/RoadCenterLines.LayerDefinition");
         m_svcResource->DeleteResource(ldfres1);
@@ -1720,6 +1741,88 @@
     }
 }
 
+void TestTileService::TestCase_GetMetatileSingle()
+{
+    try
+    {
+        INT32 col = 30;
+        INT32 row = 31;
+        INT32 scale = 3;
+
+        Ptr<MgByteReader> tile;
+        Ptr<MgResourceIdentifier> tsId;
+
+        tsId = new MgResourceIdentifier(L"Library://UnitTests/TileSets/Sheboygan.TileSetDefinition");
+        m_svcTile->ClearCache(tsId);
+        tile = m_svcTile->GetTile(tsId, L"BaseLayers", col, row, scale);
+        tile->ToFile(L"../UnitTestFiles/GetMetatileSingle_Baseline.png");
+
+        Ptr<MgMap> map = CreateMapLinked(L"MetaTileBaseline");
+        map->SetViewScale(3125);
+        Ptr<MgServerRenderingService> renderSvc = dynamic_cast<MgServerRenderingService*>(m_siteConnection->CreateService(MgServiceType::RenderingService));
+        CPPUNIT_ASSERT(NULL != renderSvc);
+
+        MgFileUtil::CreateDirectory(L"../UnitTestFiles/GetMetatileSingle_Baseline");
+
+        INT32 metaTileFactor = 4;
+        Ptr<MgMetatile> metaTile = renderSvc->RenderMetatile(map, L"BaseLayers", col, row, MgTileParameters::tileWidth, MgTileParameters::tileHeight, MgTileParameters::tileDPI, MgImageFormats::Png, MgConfigProperties::DefaultRenderingServicePropertyTileExtentOffset, metaTileFactor);
+        Ptr<MgByteReader> mtContent = metaTile->GetImage();
+        INT32 metaTileLen = mtContent->GetLength();
+        for (INT32 x = 0; x < metaTile->GetMetaTilingFactor(); x++)
+        {
+            for (INT32 y = 0; y < metaTile->GetMetaTilingFactor(); y++)
+            {
+                Ptr<MgByteReader> img = MgImageProcessor::RenderTileFromMetaTile(map, metaTile, L"AGG", renderSvc, x, y);
+                INT32 tileLen = img->GetLength();
+                STRING fileName = L"../UnitTestFiles/GetMetatileSingle_Baseline/";
+                STRING s;
+                MgUtil::Int32ToString(y, s);
+                fileName += s;
+                fileName += L"y_";
+                MgUtil::Int32ToString(x, s);
+                fileName += s;
+                fileName += L"x.png";
+                img->ToFile(fileName);
+            }
+        }
+
+        tsId = new MgResourceIdentifier(L"Library://UnitTests/TileSets/Sheboygan_Metatiled.TileSetDefinition");
+        m_svcTile->ClearCache(tsId);
+        tile = m_svcTile->GetTile(tsId, L"BaseLayers", col, row, scale);
+        tile->ToFile(L"../UnitTestFiles/GetMetatileSingle.png");
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+void TestTileService::TestCase_GetMetatileXYZSingle()
+{
+    try
+    {
+        Ptr<MgResourceIdentifier> tsId = new MgResourceIdentifier(L"Library://UnitTests/TileSets/XYZ_Metatiled.TileSetDefinition");
+        m_svcTile->ClearCache(tsId);
+        Ptr<MgByteReader> tile = m_svcTile->GetTile(tsId, L"BaseLayers", 16795, 23890, 16);
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
 ////////////////////////////////////////////////////////////////
 /// Helpers
 ////////////////////////////////////////////////////////////////

Modified: sandbox/jng/tiling_v2/Server/src/UnitTesting/TestTileService.h
===================================================================
--- sandbox/jng/tiling_v2/Server/src/UnitTesting/TestTileService.h	2019-04-26 08:49:04 UTC (rev 9499)
+++ sandbox/jng/tiling_v2/Server/src/UnitTesting/TestTileService.h	2019-05-03 12:33:01 UTC (rev 9500)
@@ -24,6 +24,10 @@
 {
     CPPUNIT_TEST_SUITE(TestTileService);
     CPPUNIT_TEST(TestStart); // This must be the very first unit test
+    
+    CPPUNIT_TEST(TestCase_GetMetatileSingle);
+    //CPPUNIT_TEST(TestCase_GetMetatileXYZSingle);
+    /*
     CPPUNIT_TEST(TestCase_GetTileProviders);
     CPPUNIT_TEST(TestCase_MgMap_Inline);
     CPPUNIT_TEST(TestCase_MgMap_Linked);
@@ -32,6 +36,8 @@
     CPPUNIT_TEST(TestCase_MgMapFromXYZTileSetLoose);
     CPPUNIT_TEST(TestCase_MgMapFromTileSet);
     CPPUNIT_TEST(TestCase_GetTile);
+    
+
     CPPUNIT_TEST(TestCase_SetTile);
     CPPUNIT_TEST(TestCase_GetSetTile);
     CPPUNIT_TEST(TestCase_ClearCache);
@@ -38,6 +44,7 @@
     CPPUNIT_TEST(TestCase_GetTileLinked);
     CPPUNIT_TEST(TestCase_GetTileXYZ);
     CPPUNIT_TEST(TestCase_ClearCacheLinked);
+    */
     CPPUNIT_TEST(TestEnd); // This must be the very last unit test
     CPPUNIT_TEST_SUITE_END();
 
@@ -65,6 +72,9 @@
     void TestCase_GetTileLinked();
     void TestCase_ClearCacheLinked();
 
+    void TestCase_GetMetatileSingle();
+    void TestCase_GetMetatileXYZSingle();
+
 private:
     MgMap* CreateMap(CREFSTRING mapName = L"");
     MgMap* CreateMapLinked(CREFSTRING mapName = L"");

Added: sandbox/jng/tiling_v2/UnitTest/TestData/TileService/UT_BaseMap_Metatiled.tsd
===================================================================
--- sandbox/jng/tiling_v2/UnitTest/TestData/TileService/UT_BaseMap_Metatiled.tsd	                        (rev 0)
+++ sandbox/jng/tiling_v2/UnitTest/TestData/TileService/UT_BaseMap_Metatiled.tsd	2019-05-03 12:33:01 UTC (rev 9500)
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TileSetDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="TileSetDefinition-3.0.0.xsd">
+  <TileStoreParameters>
+    <TileProvider>Default</TileProvider>
+    <Parameter>
+      <Name>TilePath</Name>
+      <Value>../UnitTestFiles/TileCaches/UT_BaseMap_Metatiledf</Value>
+    </Parameter>
+    <Parameter>
+      <Name>TileWidth</Name>
+      <Value>300</Value>
+    </Parameter>
+    <Parameter>
+      <Name>TileHeight</Name>
+      <Value>300</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>MetaTileFactor</Name>
+      <Value>4</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>
+  <Extents>
+    <MinX>-87.79786601383196</MinX>
+    <MaxX>-87.66452777186925</MaxX>
+    <MinY>43.6868578621819</MinY>
+    <MaxY>43.8037962206133</MaxY>
+  </Extents>
+  <BaseMapLayerGroup>
+    <Name>BaseLayers</Name>
+    <Visible>true</Visible>
+    <ShowInLegend>true</ShowInLegend>
+    <ExpandInLegend>true</ExpandInLegend>
+    <LegendLabel>Base Layers</LegendLabel>
+    <BaseMapLayer>
+      <Name>Parcels</Name>
+      <ResourceId>Library://UnitTests/Layers/Parcels.LayerDefinition</ResourceId>
+      <Selectable>true</Selectable>
+      <ShowInLegend>true</ShowInLegend>
+      <LegendLabel>Parcels</LegendLabel>
+      <ExpandInLegend>false</ExpandInLegend>
+    </BaseMapLayer>
+    <BaseMapLayer>
+      <Name>VotingDistricts</Name>
+      <ResourceId>Library://UnitTests/Layers/VotingDistricts.LayerDefinition</ResourceId>
+      <Selectable>true</Selectable>
+      <ShowInLegend>true</ShowInLegend>
+      <LegendLabel>Voting Districts</LegendLabel>
+      <ExpandInLegend>false</ExpandInLegend>
+    </BaseMapLayer>
+  </BaseMapLayerGroup>
+</TileSetDefinition>

Added: sandbox/jng/tiling_v2/UnitTest/TestData/TileService/UT_XYZ_Metatiled.tsd
===================================================================
--- sandbox/jng/tiling_v2/UnitTest/TestData/TileService/UT_XYZ_Metatiled.tsd	                        (rev 0)
+++ sandbox/jng/tiling_v2/UnitTest/TestData/TileService/UT_XYZ_Metatiled.tsd	2019-05-03 12:33:01 UTC (rev 9500)
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TileSetDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="TileSetDefinition-3.0.0.xsd">
+  <TileStoreParameters>
+    <TileProvider>XYZ</TileProvider>
+    <Parameter>
+      <Name>TilePath</Name>
+      <Value>../UnitTestFiles/TileCaches/UT_XYZ_Metatiled</Value>
+    </Parameter>
+    <Parameter>
+      <Name>TileFormat</Name>
+      <Value>PNG</Value>
+    </Parameter>
+    <Parameter>
+      <Name>MetaTileFactor</Name>
+      <Value>4</Value>
+    </Parameter>
+  </TileStoreParameters>
+  <Extents>
+    <MinX>-87.79786601383196</MinX>
+    <MaxX>-87.66452777186925</MaxX>
+    <MinY>43.6868578621819</MinY>
+    <MaxY>43.8037962206133</MaxY>
+  </Extents>
+  <BaseMapLayerGroup>
+    <Name>BaseLayers</Name>
+    <Visible>true</Visible>
+    <ShowInLegend>true</ShowInLegend>
+    <ExpandInLegend>true</ExpandInLegend>
+    <LegendLabel>Base Layers</LegendLabel>
+    <BaseMapLayer>
+      <Name>Parcels</Name>
+      <ResourceId>Library://UnitTests/Layers/Parcels.LayerDefinition</ResourceId>
+      <Selectable>true</Selectable>
+      <ShowInLegend>true</ShowInLegend>
+      <LegendLabel>Parcels</LegendLabel>
+      <ExpandInLegend>false</ExpandInLegend>
+    </BaseMapLayer>
+    <BaseMapLayer>
+      <Name>VotingDistricts</Name>
+      <ResourceId>Library://UnitTests/Layers/VotingDistricts.LayerDefinition</ResourceId>
+      <Selectable>true</Selectable>
+      <ShowInLegend>true</ShowInLegend>
+      <LegendLabel>Voting Districts</LegendLabel>
+      <ExpandInLegend>false</ExpandInLegend>
+    </BaseMapLayer>
+  </BaseMapLayerGroup>
+</TileSetDefinition>



More information about the mapguide-commits mailing list