[mapguide-commits] r9495 - in sandbox/jng/tiling_v2: Common/MapGuideCommon Common/MapGuideCommon/Services Common/MapGuideCommon/System Server/src/Services/Rendering Server/src/Services/Tile Server/src/UnitTesting

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Thu Apr 25 00:15:43 PDT 2019


Author: jng
Date: 2019-04-25 00:15:43 -0700 (Thu, 25 Apr 2019)
New Revision: 9495

Added:
   sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/Metatile.cpp
   sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/Metatile.h
   sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderMetatile.cpp
   sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderMetatile.h
Modified:
   sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommon.h
   sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommon.vcxproj
   sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommon.vcxproj.filters
   sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommonBuild.cpp
   sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/ProxyRenderingService.cpp
   sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/ProxyRenderingService.h
   sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/RenderingDefs.h
   sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/RenderingService.h
   sandbox/jng/tiling_v2/Common/MapGuideCommon/System/MapGuideCommonClassId.h
   sandbox/jng/tiling_v2/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp
   sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderTile.cpp
   sandbox/jng/tiling_v2/Server/src/Services/Rendering/RenderingOperationFactory.cpp
   sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.cpp
   sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.h
   sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.vcxproj
   sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.vcxproj.filters
   sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingServiceBuild.cpp
   sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefaultProvider.cpp
   sandbox/jng/tiling_v2/Server/src/UnitTesting/TestRenderingService.cpp
Log:
Introduce a new MgMetatile class that encapsulates a meta-tile and all information needed to properly sub-divide it back to tiles of the originally requested size.

Refactor the current metatile rendering primitive to return a MgMetatile instead and have the meta-tile slicing method take a MgMetatile instead.

Modified: sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommon.h
===================================================================
--- sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommon.h	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommon.h	2019-04-25 07:15:43 UTC (rev 9495)
@@ -145,6 +145,7 @@
 #include "Services/MapPlot.h"
 #include "Services/MapPlotCollection.h"
 #include "Services/MapPlotInstruction.h"
+#include "Services/Metatile.h"
 #include "Services/FeatureInformation.h"
 #include "Services/MappingDefs.h"
 #include "Services/MappingService.h"

Modified: sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommon.vcxproj
===================================================================
--- sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommon.vcxproj	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommon.vcxproj	2019-04-25 07:15:43 UTC (rev 9495)
@@ -684,6 +684,12 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="Services\Metatile.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="Services\PackageStatusInformation.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -1033,6 +1039,7 @@
     <ClInclude Include="Services\MapPlot.h" />
     <ClInclude Include="Services\MapPlotCollection.h" />
     <ClInclude Include="Services\MapPlotInstruction.h" />
+    <ClInclude Include="Services\Metatile.h" />
     <ClInclude Include="Services\PackageStatusInformation.h" />
     <ClInclude Include="Services\PlotSpecification.h" />
     <ClInclude Include="Services\PrintLayout.h" />

Modified: sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommon.vcxproj.filters
===================================================================
--- sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommon.vcxproj.filters	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommon.vcxproj.filters	2019-04-25 07:15:43 UTC (rev 9495)
@@ -400,6 +400,9 @@
     <ClCompile Include="Exception\UnsupportedTileProviderException.cpp">
       <Filter>Exception</Filter>
     </ClCompile>
+    <ClCompile Include="Services\Metatile.cpp">
+      <Filter>Services</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="MapLayer\Layer.h">
@@ -781,6 +784,9 @@
     <ClInclude Include="Exception\UnsupportedTileProviderException.h">
       <Filter>Exception</Filter>
     </ClInclude>
+    <ClInclude Include="Services\Metatile.h">
+      <Filter>Services</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="MapGuideCommon.rc" />

Modified: sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommonBuild.cpp
===================================================================
--- sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommonBuild.cpp	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/MapGuideCommonBuild.cpp	2019-04-25 07:15:43 UTC (rev 9495)
@@ -96,6 +96,7 @@
 #include  "Services/MappingService.cpp"
 #include  "Services/MapPlot.cpp"
 #include  "Services/MapPlotCollection.cpp"
+#include  "Services/Metatile.cpp"
 #include  "Services/PackageStatusInformation.cpp"
 #include  "Services/PlotSpecification.cpp"
 #include  "Services/PrintLayout.cpp"

Added: sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/Metatile.cpp
===================================================================
--- sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/Metatile.cpp	                        (rev 0)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/Metatile.cpp	2019-04-25 07:15:43 UTC (rev 9495)
@@ -0,0 +1,95 @@
+//
+//  Copyright (C) 2004-2019 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"
+#include "Metatile.h"
+
+MG_IMPL_DYNCREATE(MgMetatile)
+
+MgMetatile::MgMetatile() 
+    : m_width(0), m_height(0), m_metaTilingFactor(0), m_requestedWidth(0), m_requestedHeight(0)
+{
+
+}
+
+MgMetatile::MgMetatile(MgByteReader* image, INT32 width, INT32 height, INT32 requestedWidth, INT32 requestedHeight, CREFSTRING imageFormat, INT32 metaTilingFactor)
+    : m_width(width), m_height(height), m_requestedWidth(requestedWidth), m_requestedHeight(requestedHeight), m_imageFormat(imageFormat), m_metaTilingFactor(metaTilingFactor)
+{
+    m_image = SAFE_ADDREF(image);
+}
+
+MgMetatile::~MgMetatile()
+{
+    m_image = NULL;
+}
+
+MgByteReader* MgMetatile::GetImage()
+{
+    return SAFE_ADDREF(m_image.p);
+}
+
+INT32 MgMetatile::GetRequestedWidth()
+{
+    return m_requestedWidth;
+}
+
+INT32 MgMetatile::GetRequestedHeight()
+{
+    return m_requestedHeight;
+}
+
+INT32 MgMetatile::GetWidth()
+{
+    return m_width;
+}
+
+INT32 MgMetatile::GetHeight()
+{
+    return m_height;
+}
+
+STRING MgMetatile::GetTileImageFormat()
+{
+    return m_imageFormat;
+}
+
+INT32 MgMetatile::GetMetaTilingFactor()
+{
+    return m_metaTilingFactor;
+}
+
+void MgMetatile::Serialize(MgStream * stream)
+{
+    stream->WriteInt32(m_requestedWidth);
+    stream->WriteInt32(m_requestedHeight);
+    stream->WriteInt32(m_width);
+    stream->WriteInt32(m_height);
+    stream->WriteInt32(m_metaTilingFactor);
+    stream->WriteString(m_imageFormat);
+    stream->WriteObject(m_image);
+}
+
+void MgMetatile::Deserialize(MgStream * stream)
+{
+    stream->GetInt32(m_requestedWidth);
+    stream->GetInt32(m_requestedHeight);
+    stream->GetInt32(m_width);
+    stream->GetInt32(m_height);
+    stream->GetInt32(m_metaTilingFactor);
+    stream->GetString(m_imageFormat);
+    m_image = static_cast<MgByteReader*>(stream->GetObject());
+}

Added: sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/Metatile.h
===================================================================
--- sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/Metatile.h	                        (rev 0)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/Metatile.h	2019-04-25 07:15:43 UTC (rev 9495)
@@ -0,0 +1,123 @@
+//
+//  Copyright (C) 2004-2019 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 METATILE_H
+#define METATILE_H
+
+/// \cond INTERNAL
+/////////////////////////////////////////////////////////////////
+/// \brief
+/// Defines a raw image frame buffer from the result of a meta-tile
+/// rendering operation
+///
+/// \since 3.3
+class MG_MAPGUIDE_API MgMetatile : public MgSerializable
+{
+    MG_DECL_DYNCREATE()
+    DECLARE_CLASSNAME(MgMetatile)
+
+EXTERNAL_API:
+
+    /// \brief
+    /// Gets the meta-tile content. If no meta-tiling is performed, this is the tile image. Otherwise,
+    /// it is the raw image frame buffer (for sub-dividing into originally requested tile images)
+    MgByteReader* GetImage();
+
+    /// \brief
+    /// Gets the originally requested width of this tile
+    INT32 GetRequestedWidth();
+
+    /// \brief
+    /// Gets the originally requested height of this tile
+    INT32 GetRequestedHeight();
+
+    /// \brief
+    /// Gets the width of this metatile
+    INT32 GetWidth();
+
+    /// \brief
+    /// Gets the height of this metatile
+    
+    INT32 GetHeight();
+
+    /// \brief
+    /// Gets the meta-tiling factor.
+    INT32 GetMetaTilingFactor();
+
+    /// \brief
+    /// Gets the originally requested tile image format
+    STRING GetTileImageFormat();
+
+protected:
+
+    /// \brief
+    /// Dispose this object.
+    ///
+    /// \return
+    /// Returns nothing
+    ///
+    virtual void Dispose()
+    {
+        delete this;
+    }
+
+    /// \brief
+    /// Get the unique identifier for the class
+    ///
+    /// \return
+    /// Class Identifider.
+    ///
+    virtual INT32 GetClassId() { return m_cls_id; }
+
+CLASS_ID:
+    static const INT32 m_cls_id = MapGuide_RenderingService_Metatile;
+
+INTERNAL_API:
+    MgMetatile();
+    MgMetatile(MgByteReader* image, INT32 width, INT32 height, INT32 requestedWidth, INT32 requestedHeight, CREFSTRING imageFormat, INT32 metaTilingFactor);
+    virtual ~MgMetatile();
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Serialize data to a stream
+    ///
+    /// \param stream
+    /// Stream
+    ///
+    virtual void Serialize(MgStream* stream);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Deserialize data from a stream
+    ///
+    /// \param stream
+    /// Stream
+    ///
+    virtual void Deserialize(MgStream* stream);
+
+private:
+    Ptr<MgByteReader> m_image;
+    INT32 m_width;
+    INT32 m_height;
+    INT32 m_requestedWidth;
+    INT32 m_requestedHeight;
+    INT32 m_metaTilingFactor;
+    STRING m_imageFormat;
+};
+/// \endcond
+
+#endif
\ No newline at end of file

Modified: sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/ProxyRenderingService.cpp
===================================================================
--- sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/ProxyRenderingService.cpp	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/ProxyRenderingService.cpp	2019-04-25 07:15:43 UTC (rev 9495)
@@ -148,14 +148,13 @@
     INT32 tileHeight,
     INT32 tileDpi,
     CREFSTRING tileImageFormat,
-    double tileExtentOffset,
-    INT32 metaTileFactor)
+    double tileExtentOffset)
 {
     MgCommand cmd;
     cmd.ExecuteCommand(m_connProp,                                      // Connection
         MgCommand::knObject,                            // Return type expected
         MgRenderingServiceOpId::RenderTile2,            // Command Code
-        10,                                              // No of arguments
+        9,                                              // No of arguments
         Rendering_Service,                              // Service Id
         BUILD_VERSION(3, 3, 0),                         // Operation version
         MgCommand::knObject, map,                       // Argument#1
@@ -167,7 +166,6 @@
         MgCommand::knInt32, tileDpi,                    // Argument#7
         MgCommand::knString, &tileImageFormat,          // Argument#8
         MgCommand::knDouble, tileExtentOffset,          // Argument#9
-        MgCommand::knInt32, metaTileFactor,             // Argument#10
         MgCommand::knNone);                             // End of arguments
 
     SetWarning(cmd.GetWarningObject());
@@ -1334,4 +1332,40 @@
     SetWarning(cmd.GetWarningObject());
 
     return (MgByteReader*)cmd.GetReturnValue().val.m_obj;
+}
+
+MgMetatile* MgProxyRenderingService::RenderMetatile(
+    MgMap* map,
+    CREFSTRING baseMapLayerGroupName,
+    INT32 tileColumn,
+    INT32 tileRow,
+    INT32 tileWidth,
+    INT32 tileHeight,
+    INT32 tileDpi,
+    CREFSTRING tileImageFormat,
+    double tileExtentOffset,
+    INT32 metaTilingFactor)
+{
+    MgCommand cmd;
+    cmd.ExecuteCommand(m_connProp,                                      // Connection
+        MgCommand::knObject,                            // Return type expected
+        MgRenderingServiceOpId::RenderMetatile,         // Command Code
+        10,                                             // No of arguments
+        Rendering_Service,                              // Service Id
+        BUILD_VERSION(3, 3, 0),                         // Operation version
+        MgCommand::knObject, map,                       // Argument#1
+        MgCommand::knString, &baseMapLayerGroupName,    // Argument#2
+        MgCommand::knInt32, tileColumn,                 // Argument#3
+        MgCommand::knInt32, tileRow,                    // Argument#4
+        MgCommand::knInt32, tileWidth,                  // Argument#5
+        MgCommand::knInt32, tileHeight,                 // Argument#6
+        MgCommand::knInt32, tileDpi,                    // Argument#7
+        MgCommand::knString, &tileImageFormat,          // Argument#8
+        MgCommand::knDouble, tileExtentOffset,          // Argument#9
+        MgCommand::knInt32, metaTilingFactor,           // Argument#10
+        MgCommand::knNone);                             // End of arguments
+
+    SetWarning(cmd.GetWarningObject());
+
+    return (MgMetatile*)cmd.GetReturnValue().val.m_obj;
 }
\ No newline at end of file

Modified: sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/ProxyRenderingService.h
===================================================================
--- sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/ProxyRenderingService.h	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/ProxyRenderingService.h	2019-04-25 07:15:43 UTC (rev 9495)
@@ -157,8 +157,7 @@
         INT32 tileHeight,
         INT32 tileDpi,
         CREFSTRING tileImageFormat,
-        double tileExtentOffset,
-        INT32 metaTileFactor);
+        double tileExtentOffset);
 
     /////////////////////////////////////////////////////////////////
     /// \brief
@@ -1105,6 +1104,61 @@
         bool bIncludeFeatureBBOX,
         bool bIncludeGeometry);
 
+    /////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Returns the specified base map tile for the given map.
+    ///
+    /// \remarks
+    /// This method only renders the given tile. No tile caching is performed
+    /// by this method. To render and cache the tile, use the 
+    /// \link MgTileService::GetTile GetTile \endlink method instead. However,
+    /// using that method will use default tile width/height/dpi/format specified
+    /// in your MapGuide Server configuration
+    ///
+    /// \param map
+    /// Input
+    /// map object containing current state of map.
+    /// \param baseMapLayerGroupName
+    /// Input
+    /// Specifies the name of the baseMapLayerGroup for which to render the tile.
+    /// \param tileColumn
+    /// Input
+    /// Specifies the column index of the tile to return.
+    /// \param tileRow
+    /// Input
+    /// Specifies the row index of the tile to return.
+    /// \param tileWidth
+    /// Input
+    /// Specifies the width of the tile to return.
+    /// \param tileHeight
+    /// Input
+    /// Specifies the height of the tile to return.
+    /// \param tileDpi
+    /// Input
+    /// Specifies the dpi the tile to return.
+    /// \param tileImageFormat
+    /// Input
+    /// Specifies the image format of the tile. See \link MgImageFormats \endlink
+    /// \param tileExtentOffset
+    /// Specifies the ratio by which the tile to be rendered should be "buffered out". The tile will be rendered at the specified width
+    /// multiplied by the given ration, which will be cropped back to the original requested size after rendering. This is to improve
+    /// label placement on rendered tiles by giving extra "breathing space" to label placement algorithms.
+    ///
+    /// \return
+    /// A byte reader containing the rendered tile image.
+    ///
+    virtual MgMetatile* RenderMetatile(
+        MgMap* map,
+        CREFSTRING baseMapLayerGroupName,
+        INT32 tileColumn,
+        INT32 tileRow,
+        INT32 tileWidth,
+        INT32 tileHeight,
+        INT32 tileDpi,
+        CREFSTRING tileImageFormat,
+        double tileExtentOffset,
+        INT32 metaTilingFactor);
+
 protected:
 
     //////////////////////////////////////////////////////////////////

Modified: sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/RenderingDefs.h
===================================================================
--- sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/RenderingDefs.h	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/RenderingDefs.h	2019-04-25 07:15:43 UTC (rev 9495)
@@ -47,6 +47,7 @@
     static const int RenderMap7                 = 0x1111E913;
     static const int RenderTileUTFGrid          = 0x1111E914;
     static const int QueryFeatureProperties3    = 0x1111E915;
+    static const int RenderMetatile             = 0x1111E916;
 };
 /// \endcond
 

Modified: sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/RenderingService.h
===================================================================
--- sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/RenderingService.h	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/RenderingService.h	2019-04-25 07:15:43 UTC (rev 9495)
@@ -162,6 +162,7 @@
     /// \return
     /// A byte reader containing the rendered tile image.
     ///
+    /// \since 3.3
     virtual MgByteReader* RenderTile(
         MgMap* map,
         CREFSTRING baseMapLayerGroupName,
@@ -171,8 +172,7 @@
         INT32 tileHeight,
         INT32 tileDpi,
         CREFSTRING tileImageFormat,
-        double tileExtentOffset,
-        INT32 metaTileFactor) = 0;
+        double tileExtentOffset) = 0;
 
     /////////////////////////////////////////////////////////////////
     /// \brief
@@ -1117,6 +1117,62 @@
         bool bIncludeFeatureBBOX,
         bool bIncludeGeometry) = 0;
 
+    /////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Returns the specified base map tile for the given map.
+    ///
+    /// \remarks
+    /// This method only renders the given tile. No tile caching is performed
+    /// by this method. To render and cache the tile, use the 
+    /// \link MgTileService::GetTile GetTile \endlink method instead. However,
+    /// using that method will use default tile width/height/dpi/format specified
+    /// in your MapGuide Server configuration
+    ///
+    /// \param map
+    /// Input
+    /// map object containing current state of map.
+    /// \param baseMapLayerGroupName
+    /// Input
+    /// Specifies the name of the baseMapLayerGroup for which to render the tile.
+    /// \param tileColumn
+    /// Input
+    /// Specifies the column index of the tile to return.
+    /// \param tileRow
+    /// Input
+    /// Specifies the row index of the tile to return.
+    /// \param tileWidth
+    /// Input
+    /// Specifies the width of the tile to return.
+    /// \param tileHeight
+    /// Input
+    /// Specifies the height of the tile to return.
+    /// \param tileDpi
+    /// Input
+    /// Specifies the dpi the tile to return.
+    /// \param tileImageFormat
+    /// Input
+    /// Specifies the image format of the tile. See \link MgImageFormats \endlink
+    /// \param tileExtentOffset
+    /// Specifies the ratio by which the tile to be rendered should be "buffered out". The tile will be rendered at the specified width
+    /// multiplied by the given ration, which will be cropped back to the original requested size after rendering. This is to improve
+    /// label placement on rendered tiles by giving extra "breathing space" to label placement algorithms.
+    ///
+    /// \return
+    /// A byte reader containing the rendered tile image.
+    ///
+    /// \since 3.3
+    virtual MgMetatile* RenderMetatile(
+        MgMap* map,
+        CREFSTRING baseMapLayerGroupName,
+        INT32 tileColumn,
+        INT32 tileRow,
+        INT32 tileWidth,
+        INT32 tileHeight,
+        INT32 tileDpi,
+        CREFSTRING tileImageFormat,
+        double tileExtentOffset,
+        INT32 metaTileFactor) = 0;
+
 protected:
 
     /////////////////////////////////////////////////////////////////

Modified: sandbox/jng/tiling_v2/Common/MapGuideCommon/System/MapGuideCommonClassId.h
===================================================================
--- sandbox/jng/tiling_v2/Common/MapGuideCommon/System/MapGuideCommonClassId.h	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/System/MapGuideCommonClassId.h	2019-04-25 07:15:43 UTC (rev 9495)
@@ -130,6 +130,7 @@
 #define MapGuide_RenderingService_RenderingService                  MAPGUIDE_RENDERINGSERVICE_ID+0
 #define MapGuide_RenderingService_FeatureInformation                MAPGUIDE_RENDERINGSERVICE_ID+1
 #define MapGuide_RenderingService_RenderingOptions                  MAPGUIDE_RENDERINGSERVICE_ID+2
+#define MapGuide_RenderingService_Metatile                          MAPGUIDE_RENDERINGSERVICE_ID+3
 
 // Resource Service
 #define MapGuide_ResourceService_ResourceService                    MAPGUIDE_RESOURCESERVICE_ID+0

Modified: sandbox/jng/tiling_v2/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp
===================================================================
--- sandbox/jng/tiling_v2/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp	2019-04-25 07:15:43 UTC (rev 9495)
@@ -111,6 +111,7 @@
     fact->Register(MapGuide_MappingService_MapPlotCollection, MgMapPlotCollection::CreateObject);
     fact->Register(MapGuide_RenderingService_FeatureInformation, MgFeatureInformation::CreateObject);
     fact->Register(MapGuide_RenderingService_RenderingOptions, MgRenderingOptions::CreateObject);
+    fact->Register(MapGuide_RenderingService_Metatile, MgMetatile::CreateObject);
     fact->Register(PlatformBase_FeatureService_FeatureTransaction, MgProxyFeatureTransaction::CreateObject);
     fact->Register(MapGuide_Service_SqlResult, MgSqlResult::CreateObject);
 

Added: sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderMetatile.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderMetatile.cpp	                        (rev 0)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderMetatile.cpp	2019-04-25 07:15:43 UTC (rev 9495)
@@ -0,0 +1,131 @@
+//
+//  Copyright (C) 2004-2019 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 "OpRenderMetatile.h"
+#include "LogManager.h"
+
+MgOpRenderMetatile::MgOpRenderMetatile()
+{
+}
+
+MgOpRenderMetatile::~MgOpRenderMetatile()
+{
+}
+
+void MgOpRenderMetatile::Execute()
+{
+    ACE_DEBUG((LM_DEBUG, ACE_TEXT("  (%t) MgOpRenderMetatile::Execute()\n")));
+
+    MG_LOG_OPERATION_MESSAGE(L"MgOpRenderMetatile");
+
+    MG_TRY()
+
+    MG_LOG_OPERATION_MESSAGE_INIT(m_packet.m_OperationVersion, m_packet.m_NumArguments);
+
+    ACE_ASSERT(m_stream != NULL);
+
+    if (10 == m_packet.m_NumArguments)
+    {
+        Ptr<MgMap> map = (MgMap*)m_stream->GetObject();
+        Ptr<MgResourceIdentifier> resource = map->GetResourceId();
+        map->SetDelayedLoadResourceService(m_resourceService);
+
+        STRING baseMapLayerGroupName;
+        m_stream->GetString(baseMapLayerGroupName);
+
+        INT32 tileCol = 0;
+        m_stream->GetInt32(tileCol);
+
+        INT32 tileRow = 0;
+        m_stream->GetInt32(tileRow);
+
+        INT32 tileWidth = 0;
+        m_stream->GetInt32(tileWidth);
+
+        INT32 tileHeight = 0;
+        m_stream->GetInt32(tileHeight);
+
+        INT32 tileDpi = 0;
+        m_stream->GetInt32(tileDpi);
+
+        STRING tileImageFormat;
+        m_stream->GetString(tileImageFormat);
+
+        double tileExtentOffset = 0.0;
+        m_stream->GetDouble(tileExtentOffset);
+
+        INT32 metaTileFactor = 0;
+        m_stream->GetInt32(metaTileFactor);
+
+        BeginExecution();
+
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING((NULL == resource) ? L"MgResourceIdentifier" : resource->ToString().c_str());
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(baseMapLayerGroupName.c_str());
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(tileCol);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(tileRow);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(tileWidth);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(tileHeight);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(tileDpi);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(tileImageFormat.c_str());
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_DOUBLE(tileExtentOffset);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(metaTileFactor);
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+
+        Validate();
+
+        Ptr<MgMetatile> metaTile = m_service->RenderMetatile(map, baseMapLayerGroupName, tileCol, tileRow, tileWidth, tileHeight, tileDpi, tileImageFormat, tileExtentOffset, metaTileFactor);
+
+        EndExecution(metaTile);
+    }
+    else
+    {
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+    }
+
+    if (!m_argsRead)
+    {
+        throw new MgOperationProcessingException(L"MgOpRenderMetatile.Execute",
+            __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    // Successful operation
+    MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
+
+    MG_CATCH(L"MgOpRenderMetatile.Execute")
+
+    if (mgException != NULL)
+    {
+        // Failed operation
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Failure.c_str());
+    }
+
+    // Add access log entry for operation
+    MG_LOG_OPERATION_MESSAGE_ACCESS_ENTRY();
+
+    MG_THROW()
+}

Added: sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderMetatile.h
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderMetatile.h	                        (rev 0)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderMetatile.h	2019-04-25 07:15:43 UTC (rev 9495)
@@ -0,0 +1,32 @@
+//
+//  Copyright (C) 2004-2019 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_OP_RENDER_METATILE_H
+#define MG_OP_RENDER_METATILE_H
+
+#include "RenderingOperation.h"
+
+class MgOpRenderMetatile : public MgRenderingOperation
+{
+public:
+    MgOpRenderMetatile();
+    virtual ~MgOpRenderMetatile();
+
+public:
+    virtual void Execute();
+};
+
+#endif
\ No newline at end of file

Modified: sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderTile.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderTile.cpp	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderTile.cpp	2019-04-25 07:15:43 UTC (rev 9495)
@@ -148,7 +148,7 @@
 
         EndExecution(byteReader);
     }
-    else if (10 == m_packet.m_NumArguments)
+    else if (9 == m_packet.m_NumArguments)
     {
         Ptr<MgMap> map = (MgMap*)m_stream->GetObject();
         Ptr<MgResourceIdentifier> resource = map->GetResourceId();
@@ -178,9 +178,6 @@
         double tileExtentOffset = 0.0;
         m_stream->GetDouble(tileExtentOffset);
 
-        INT32 metaTileFactor = 0;
-        m_stream->GetInt32(metaTileFactor);
-
         BeginExecution();
 
         MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
@@ -201,14 +198,12 @@
         MG_LOG_OPERATION_MESSAGE_ADD_STRING(tileImageFormat.c_str());
         MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
         MG_LOG_OPERATION_MESSAGE_ADD_DOUBLE(tileExtentOffset);
-        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
-        MG_LOG_OPERATION_MESSAGE_ADD_INT32(metaTileFactor);
         MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
 
         Validate();
 
         Ptr<MgByteReader> byteReader =
-            m_service->RenderTile(map, baseMapLayerGroupName, tileCol, tileRow, tileWidth, tileHeight, tileDpi, tileImageFormat, tileExtentOffset, metaTileFactor);
+            m_service->RenderTile(map, baseMapLayerGroupName, tileCol, tileRow, tileWidth, tileHeight, tileDpi, tileImageFormat, tileExtentOffset);
 
         EndExecution(byteReader);
     }

Modified: sandbox/jng/tiling_v2/Server/src/Services/Rendering/RenderingOperationFactory.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/RenderingOperationFactory.cpp	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/RenderingOperationFactory.cpp	2019-04-25 07:15:43 UTC (rev 9495)
@@ -108,6 +108,17 @@
                 L"MgRenderingOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
         }
         break;
+    case MgRenderingServiceOpId::RenderMetatile:
+        switch (VERSION_NO_PHASE(operationVersion))
+        {
+        case VERSION_SUPPORTED(3, 3):
+            handler.reset(new MgOpRenderMetatile());
+            break;
+        default:
+            throw new MgInvalidOperationVersionException(
+                L"MgRenderingOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        break;
     case MgRenderingServiceOpId::RenderTileUTFGrid:
         switch (VERSION_NO_PHASE(operationVersion))
         {

Modified: sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.cpp	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.cpp	2019-04-25 07:15:43 UTC (rev 9495)
@@ -191,7 +191,7 @@
 
     MG_TRY()
 
-    ret = RenderTile(map, baseMapLayerGroupName, tileColumn, tileRow, tileWidth, tileHeight, tileDpi, tileImageFormat, tileExtentOffset, 0 /* MT factor = 1 -> render at original size */);
+    ret = RenderTile(map, baseMapLayerGroupName, tileColumn, tileRow, tileWidth, tileHeight, tileDpi, tileImageFormat, tileExtentOffset);
 
     MG_CATCH_AND_THROW(L"MgServerRenderingService.RenderTile")
 
@@ -500,11 +500,15 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 // gets called with a bitmap in the bytereader to be split up into metatile^2 images
-MgByteReader* MgServerRenderingService::RenderTileFromMetaTile(MgMap* map, MgByteReader* metaTileBitMap, CREFSTRING origTileFormat,
-                                                               INT32 origTileWidth, INT32 origTileHeight,
-                                                               INT32 metaTileFactor, INT32 subTileX, INT32 subTileY)
+MgByteReader* MgServerRenderingService::RenderTileFromMetaTile(MgMap* map, MgMetatile* metaTile, INT32 subTileX, INT32 subTileY)
 {
-    MgByteSource* bs = metaTileBitMap->GetByteSource();
+    Ptr<MgByteReader> image = metaTile->GetImage();
+    INT32 metaTileFactor = metaTile->GetMetaTilingFactor();
+    INT32 origTileWidth = metaTile->GetRequestedWidth();
+    INT32 origTileHeight = metaTile->GetRequestedHeight();
+    STRING origTileFormat = metaTile->GetTileImageFormat();
+
+    MgByteSource* bs = image->GetByteSource();
     // upcast to bytesource Impl to access bytearray member
     ByteSourceMemoryImpl* source = dynamic_cast<ByteSourceMemoryImpl*>(bs->GetSourceImpl());
     assert(source);
@@ -2399,58 +2403,21 @@
                                                    INT32 tileHeight,
                                                    INT32 tileDpi,
                                                    CREFSTRING tileImageFormat,
-                                                   double tileExtentOffset,
-                                                   INT32 metaTileFactor)
+                                                   double tileExtentOffset)
 {
     Ptr<MgByteReader> ret;
 
     MG_TRY()
 
-    CHECKARGUMENTNULL(map, L"MgServerRenderingService.RenderTile");
-    CHECKARGUMENTEMPTYSTRING(baseMapLayerGroupName, L"MgServerRenderingService.RenderTile");
+    INT32 metaTilingFactor = 0;
+    Ptr<MgMetatile> metaTile = RenderMetatile(map, baseMapLayerGroupName, tileColumn, tileRow, tileWidth, tileHeight, tileDpi, tileImageFormat, tileExtentOffset, metaTilingFactor);
 
-    // find the finite display scale closest to the requested map scale
-    double scale = map->GetViewScale();
-    INT32 scaleIndex = map->FindNearestFiniteDisplayScaleIndex(scale);
+    _ASSERT(metaTile->GetRequestedWidth() == tileWidth);
+    _ASSERT(metaTile->GetRequestedHeight() == tileHeight);
+    _ASSERT(metaTile->GetMetaTilingFactor() <= 1);
 
-    // if we don't find a nearest scale then something is wrong with the map
-    if (scaleIndex < 0)
-        throw new MgInvalidMapDefinitionException(L"MgServerRenderingService.RenderTile", __LINE__, __WFILE__, NULL, L"", NULL);
+    ret = metaTile->GetImage();
 
-    // get the layer group associated with the name
-    Ptr<MgLayerGroupCollection> layerGroups = map->GetLayerGroups();
-    Ptr<MgLayerGroup> baseGroup = layerGroups->GetItem(baseMapLayerGroupName);
-    if (baseGroup == NULL)
-    {
-        MgStringCollection arguments;
-        arguments.Add(L"2");
-        arguments.Add(baseMapLayerGroupName);
-
-        throw new MgInvalidArgumentException(L"MgServerRenderingService.RenderTile",
-            __LINE__, __WFILE__, &arguments, L"MgMapLayerGroupNameNotFound", NULL);
-    }
-
-    // get the scale at which to render the tile
-    scale = map->GetFiniteDisplayScaleAt(scaleIndex);
-
-    // ensure the tile DPI is set on the map
-    map->SetDisplayDpi(tileDpi);
-
-    // ------------------------------------------------------
-    // the upper left corner of tile (0,0) corresponds to the
-    // upper left corner of the map extent
-    // ------------------------------------------------------
-
-    double tileMinX, tileMaxX, tileMinY, tileMaxY;
-    map->GetTileCoords(std::max(metaTileFactor, 1), tileColumn, tileRow, tileDpi, tileWidth, tileHeight, tileMinX, tileMaxX, tileMinY, tileMaxY);
-
-    // make the call to render the tile
-    ret = RenderTileInternal(map, baseGroup, scaleIndex, 
-                             tileWidth * std::max(metaTileFactor, 1), tileHeight * std::max(metaTileFactor, 1),
-                             scale, tileMinX, tileMaxX, tileMinY, tileMaxY, 
-                             (metaTileFactor > 1 ? MgImageFormats::Meta : tileImageFormat),
-                             tileExtentOffset);
-
     MG_CATCH_AND_THROW(L"MgServerRenderingService.RenderTile")
 
     return ret.Detach();
@@ -2585,4 +2552,73 @@
         if (abs(drawWidth - width) <= 1)
             drawWidth = width;
     }
+}
+
+
+MgMetatile* MgServerRenderingService::RenderMetatile(MgMap* map,
+                                                     CREFSTRING baseMapLayerGroupName,
+                                                     INT32 tileColumn,
+                                                     INT32 tileRow,
+                                                     INT32 tileWidth,
+                                                     INT32 tileHeight,
+                                                     INT32 tileDpi,
+                                                     CREFSTRING tileImageFormat,
+                                                     double tileExtentOffset,
+                                                     INT32 metaTileFactor)
+{
+    Ptr<MgMetatile> ret;
+
+    MG_TRY()
+
+    CHECKARGUMENTNULL(map, L"MgServerRenderingService.RenderMetatile");
+    CHECKARGUMENTEMPTYSTRING(baseMapLayerGroupName, L"MgServerRenderingService.RenderMetatile");
+
+    // find the finite display scale closest to the requested map scale
+    double scale = map->GetViewScale();
+    INT32 scaleIndex = map->FindNearestFiniteDisplayScaleIndex(scale);
+
+    // if we don't find a nearest scale then something is wrong with the map
+    if (scaleIndex < 0)
+        throw new MgInvalidMapDefinitionException(L"MgServerRenderingService.RenderMetatile", __LINE__, __WFILE__, NULL, L"", NULL);
+
+    // get the layer group associated with the name
+    Ptr<MgLayerGroupCollection> layerGroups = map->GetLayerGroups();
+    Ptr<MgLayerGroup> baseGroup = layerGroups->GetItem(baseMapLayerGroupName);
+    if (baseGroup == NULL)
+    {
+        MgStringCollection arguments;
+        arguments.Add(L"2");
+        arguments.Add(baseMapLayerGroupName);
+
+        throw new MgInvalidArgumentException(L"MgServerRenderingService.RenderMetatile",
+            __LINE__, __WFILE__, &arguments, L"MgMapLayerGroupNameNotFound", NULL);
+    }
+
+    // get the scale at which to render the tile
+    scale = map->GetFiniteDisplayScaleAt(scaleIndex);
+
+    // ensure the tile DPI is set on the map
+    map->SetDisplayDpi(tileDpi);
+
+    // ------------------------------------------------------
+    // the upper left corner of tile (0,0) corresponds to the
+    // upper left corner of the map extent
+    // ------------------------------------------------------
+
+    double tileMinX, tileMaxX, tileMinY, tileMaxY;
+    map->GetTileCoords(std::max(metaTileFactor, 1), tileColumn, tileRow, tileDpi, tileWidth, tileHeight, tileMinX, tileMaxX, tileMinY, tileMaxY);
+
+    // make the call to render the tile
+    INT32 tw = tileWidth * std::max(metaTileFactor, 1);
+    INT32 th = tileHeight * std::max(metaTileFactor, 1);
+    STRING tformat = (metaTileFactor > 1 ? MgImageFormats::Meta : tileImageFormat);
+    Ptr<MgByteReader> tile = RenderTileInternal(map, baseGroup, scaleIndex, tw, th,
+                                                scale, tileMinX, tileMaxX, tileMinY, tileMaxY, 
+                                                tformat, tileExtentOffset);
+
+    ret = new MgMetatile(tile, tw, th, tileWidth, tileHeight, tileImageFormat, metaTileFactor);
+
+    MG_CATCH_AND_THROW(L"MgServerRenderingService.RenderMetatile")
+
+    return ret.Detach();
 }
\ No newline at end of file

Modified: sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.h
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.h	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.h	2019-04-25 07:15:43 UTC (rev 9495)
@@ -64,8 +64,7 @@
                                      INT32 tileHeight,
                                      INT32 tileDpi,
                                      CREFSTRING tileImageFormat,
-                                     double tileExtentOffset,
-                                     INT32 metaTileFactor);
+                                     double tileExtentOffset);
 
     virtual MgByteReader* RenderTileXYZ(MgMap* map,
                                         CREFSTRING baseMapLayerGroupName,
@@ -263,10 +262,19 @@
                                         bool bIncludeFeatureBBOX,
                                         bool bIncludeGeometry);
 
-    MgByteReader* RenderTileFromMetaTile(MgMap* map, MgByteReader* metaTileBitMap, CREFSTRING origTileFormat,
-                                         INT32 origTileWidth, INT32 origTileHeight, 
-                                         INT32 metaTileFactor, INT32 subTileX, INT32 subTileY);
+    virtual MgMetatile* RenderMetatile(MgMap* map,
+                                       CREFSTRING baseMapLayerGroupName,
+                                       INT32 tileColumn,
+                                       INT32 tileRow,
+                                       INT32 tileWidth,
+                                       INT32 tileHeight,
+                                       INT32 tileDpi,
+                                       CREFSTRING tileImageFormat,
+                                       double tileExtentOffset,
+                                       INT32 metaTilingFactor);
 
+    MgByteReader* RenderTileFromMetaTile(MgMap* map, MgMetatile* metaTile, INT32 subTileX, INT32 subTileY);
+
 private:
     static void ComputeScaledDimensions(RS_Bounds& extent, INT32 width, INT32 height, INT32 dpi,
                                         double metersPerUnit, INT32& drawWidth, INT32& drawHeight, double& scale);

Modified: sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.vcxproj
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.vcxproj	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.vcxproj	2019-04-25 07:15:43 UTC (rev 9495)
@@ -228,6 +228,12 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="OpRenderMetatile.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="OpRenderTile.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -296,6 +302,7 @@
     <ClInclude Include="OpRenderDynamicOverlay.h" />
     <ClInclude Include="OpRenderMap.h" />
     <ClInclude Include="OpRenderMapLegend.h" />
+    <ClInclude Include="OpRenderMetatile.h" />
     <ClInclude Include="OpRenderTile.h" />
     <ClInclude Include="OpRenderTileXYZ.h" />
     <ClInclude Include="OpRenderTileUTFGrid.h" />

Modified: sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.vcxproj.filters
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.vcxproj.filters	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.vcxproj.filters	2019-04-25 07:15:43 UTC (rev 9495)
@@ -42,6 +42,9 @@
     <ClCompile Include="OpRenderTileUTFGrid.cpp">
       <Filter>Ops</Filter>
     </ClCompile>
+    <ClCompile Include="OpRenderMetatile.cpp">
+      <Filter>Ops</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="OpQueryFeatureProperties.h">
@@ -80,6 +83,9 @@
     <ClInclude Include="OpRenderTileUTFGrid.h">
       <Filter>Ops</Filter>
     </ClInclude>
+    <ClInclude Include="OpRenderMetatile.h">
+      <Filter>Ops</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="ServerRenderingService.rc" />

Modified: sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingServiceBuild.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingServiceBuild.cpp	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingServiceBuild.cpp	2019-04-25 07:15:43 UTC (rev 9495)
@@ -23,6 +23,7 @@
 #include "OpRenderDynamicOverlay.cpp"
 #include "OpRenderMap.cpp"
 #include "OpRenderMapLegend.cpp"
+#include "OpRenderMetatile.cpp"
 #include "OpRenderTile.cpp"
 #include "OpRenderTileXYZ.cpp"
 #include "OpRenderTileUTFGrid.cpp"

Modified: sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefaultProvider.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefaultProvider.cpp	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefaultProvider.cpp	2019-04-25 07:15:43 UTC (rev 9495)
@@ -65,7 +65,7 @@
     if (svcRendering != NULL)
     {
         // generate the tile
-        img = svcRendering->RenderTile(map, baseMapLayerGroupName, tileColumn, tileRow, GetDefaultTileSizeX(), GetDefaultTileSizeY(), map->GetDisplayDpi(), GetTileFormat(), m_tileExtentOffset, 0);
+        img = svcRendering->RenderTile(map, baseMapLayerGroupName, tileColumn, tileRow, GetDefaultTileSizeX(), GetDefaultTileSizeY(), map->GetDisplayDpi(), GetTileFormat(), m_tileExtentOffset);
 
         // cache the tile
         if (!m_renderOnly)

Modified: sandbox/jng/tiling_v2/Server/src/UnitTesting/TestRenderingService.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/UnitTesting/TestRenderingService.cpp	2019-04-24 03:20:38 UTC (rev 9494)
+++ sandbox/jng/tiling_v2/Server/src/UnitTesting/TestRenderingService.cpp	2019-04-25 07:15:43 UTC (rev 9495)
@@ -1738,15 +1738,15 @@
 
         // Render a 2x2 metatile which should cover the same tiles as the baseline test.
         INT32 metaTileFactor = 2;
-        Ptr<MgByteReader> metaTile = renderSvc->RenderTile(map, L"BaseLayers", 4, 6, MgTileParameters::tileWidth, MgTileParameters::tileHeight, MgTileParameters::tileDPI, imageFormat, MgConfigProperties::DefaultRenderingServicePropertyTileExtentOffset, metaTileFactor);
+        Ptr<MgMetatile> metaTile = renderSvc->RenderMetatile(map, L"BaseLayers", 4, 6, MgTileParameters::tileWidth, MgTileParameters::tileHeight, MgTileParameters::tileDPI, imageFormat, MgConfigProperties::DefaultRenderingServicePropertyTileExtentOffset, metaTileFactor);
         //metaTile->ToFile(L"../UnitTestFiles/RenderTile_Metatile at 4_6.png");
         //CPPUNIT_ASSERT(metaTile->IsRewindable());
         //metaTile->Rewind();
         
-        Ptr<MgByteReader> tile4_6 = renderSvc->RenderTileFromMetaTile(map, metaTile, imageFormat, MgTileParameters::tileWidth, MgTileParameters::tileHeight, 2, 0, 0);
-        Ptr<MgByteReader> tile4_7 = renderSvc->RenderTileFromMetaTile(map, metaTile, imageFormat, MgTileParameters::tileWidth, MgTileParameters::tileHeight, 2, 0, 1);
-        Ptr<MgByteReader> tile5_6 = renderSvc->RenderTileFromMetaTile(map, metaTile, imageFormat, MgTileParameters::tileWidth, MgTileParameters::tileHeight, 2, 1, 0);
-        Ptr<MgByteReader> tile5_7 = renderSvc->RenderTileFromMetaTile(map, metaTile, imageFormat, MgTileParameters::tileWidth, MgTileParameters::tileHeight, 2, 1, 1);
+        Ptr<MgByteReader> tile4_6 = renderSvc->RenderTileFromMetaTile(map, metaTile, 0, 0);
+        Ptr<MgByteReader> tile4_7 = renderSvc->RenderTileFromMetaTile(map, metaTile, 0, 1);
+        Ptr<MgByteReader> tile5_6 = renderSvc->RenderTileFromMetaTile(map, metaTile, 1, 0);
+        Ptr<MgByteReader> tile5_7 = renderSvc->RenderTileFromMetaTile(map, metaTile, 1, 1);
 
 
         tile4_6->ToFile(GetPath(L"../UnitTestFiles/RenderTile_4_6_Metatiled", imageFormat, extension));



More information about the mapguide-commits mailing list