[mapguide-commits] r9492 - in sandbox/jng/tiling_v2/Server/src: Services/Rendering Services/Tile UnitTesting

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Mon Apr 22 21:04:25 PDT 2019


Author: jng
Date: 2019-04-22 21:04:25 -0700 (Mon, 22 Apr 2019)
New Revision: 9492

Modified:
   sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderTile.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/Tile/TileCacheDefaultProvider.cpp
   sandbox/jng/tiling_v2/Server/src/UnitTesting/TestRenderingService.cpp
   sandbox/jng/tiling_v2/Server/src/UnitTesting/TestRenderingService.h
Log:
Port across the core metatile rendering primitives from RFC90 sandbox. Add unit test to dump out rendered sub-metatiles to compare against original rendered tiles at the same coordinates.

Modified: sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderTile.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderTile.cpp	2019-04-15 11:39:50 UTC (rev 9491)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderTile.cpp	2019-04-23 04:04:25 UTC (rev 9492)
@@ -148,7 +148,7 @@
 
         EndExecution(byteReader);
     }
-    else if (9 == m_packet.m_NumArguments)
+    else if (10 == m_packet.m_NumArguments)
     {
         Ptr<MgMap> map = (MgMap*)m_stream->GetObject();
         Ptr<MgResourceIdentifier> resource = map->GetResourceId();
@@ -178,6 +178,9 @@
         double tileExtentOffset = 0.0;
         m_stream->GetDouble(tileExtentOffset);
 
+        INT32 metaTileFactor = 0;
+        m_stream->GetInt32(metaTileFactor);
+
         BeginExecution();
 
         MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
@@ -198,12 +201,14 @@
         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);
+            m_service->RenderTile(map, baseMapLayerGroupName, tileCol, tileRow, tileWidth, tileHeight, tileDpi, tileImageFormat, tileExtentOffset, metaTileFactor);
 
         EndExecution(byteReader);
     }

Modified: sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.cpp	2019-04-15 11:39:50 UTC (rev 9491)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.cpp	2019-04-23 04:04:25 UTC (rev 9492)
@@ -191,7 +191,7 @@
 
     MG_TRY()
 
-    ret = RenderTile(map, baseMapLayerGroupName, tileColumn, tileRow, tileWidth, tileHeight, tileDpi, tileImageFormat, tileExtentOffset);
+    ret = RenderTile(map, baseMapLayerGroupName, tileColumn, tileRow, tileWidth, tileHeight, tileDpi, tileImageFormat, tileExtentOffset, 0 /* MT factor = 1 -> render at original size */);
 
     MG_CATCH_AND_THROW(L"MgServerRenderingService.RenderTile")
 
@@ -535,7 +535,63 @@
     return ret.Detach();
 }
 
+///////////////////////////////////////////////////////////////////////////////
+// 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)
+{
+    MgByteSource* bs = metaTileBitMap->GetByteSource();
+    // upcast to bytesource Impl to access bytearray member
+    ByteSourceMemoryImpl* source = dynamic_cast<ByteSourceMemoryImpl*>(bs->GetSourceImpl());
+    assert(source);
+    assert(bs->GetMimeType() == MgMimeType::Meta);
+    int size = (int)source->GetLength();
 
+    // some checking: the complete meta tile of 32b pixels should be in the framebuffer handed over
+    int expectedSize = 4 * (metaTileFactor * origTileWidth)
+                         * (metaTileFactor * origTileHeight);
+    assert(size == expectedSize);
+
+    // use the map's background color, but always make it fully transparent
+    RS_Color bgColor;
+    StylizationUtil::ParseColor(map->GetBackgroundColor(), bgColor);
+    bgColor.alpha() = 0;
+    auto_ptr<SE_Renderer> dr(CreateRenderer(origTileWidth, origTileHeight, bgColor, true));
+    RS_ColorVector tileColorPalette;
+    if (m_rendererName == L"AGG" && hasColorMap(origTileFormat))
+    {
+        MgMappingUtil::ParseColorStrings(&tileColorPalette, map);
+    }
+
+    // now copy tile from meta framebuffer to new one...
+    // use unsigned int pointer arithmetic for pixels!
+    //MgByte* byteBuffer = source->Bytes();     // here we access the bytearray inside the bytesource
+    MgByte* byteBuffer = source->BytesNoAddRef();
+    assert(size == byteBuffer->GetLength());  // double check the buffer size
+
+    // get pointer to the framebuffer containing the metatile 
+    unsigned int *framebuf = (unsigned int*)byteBuffer->Bytes();
+
+    // allocate subtile buffer to copy new framebuf with changed dimensions
+    // place buffer in allocated MgByte auto_ptr object for destruction at end of scope
+    auto_ptr<MgByte> subTileBytes(new MgByte((unsigned char*)new unsigned int[origTileWidth * origTileHeight],
+        origTileWidth * origTileHeight * sizeof(int), MgByte::New));
+    // get the pointer to the internal target buffer
+    unsigned int* subTileBuf = (unsigned int*)subTileBytes->Bytes();
+    for (int y = 0; y < origTileHeight; y++)    // rows
+        for (int x = 0; x < origTileWidth; x++)    // columns innerloop
+        {  // this copies the 32bit pixels from the meta tile framebuffer to the subtile framebuffer
+            *(subTileBuf + x
+                + y * origTileWidth)                 // target address in subtile
+                = *(framebuf + (x + (subTileX * origTileWidth))   // X address in meta tile
+                    + (y + (subTileY * origTileHeight))  // Y address in meta tile
+                    * origTileWidth * metaTileFactor);  // use width of metaTile here
+        }
+    // then call the image renderer to convert the framebuffer bitmap into the desired image format
+    return CreateImage(map, dr.get(), origTileWidth, origTileHeight, origTileFormat, NULL, subTileBuf);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // default arg bKeepSelection = true
 MgByteReader* MgServerRenderingService::RenderDynamicOverlay(MgMap* map,
@@ -2299,7 +2355,8 @@
                                                            INT32 saveWidth,
                                                            INT32 saveHeight,
                                                            CREFSTRING format,
-                                                           ProfileRenderMapResult* pPRMResult)
+                                                           ProfileRenderMapResult* pPRMResult,
+                                                           unsigned int* frameBuffer)
 {
     if(NULL != pPRMResult)
     {
@@ -2338,24 +2395,32 @@
         // call the image renderer to create the image
         if (wcscmp(m_rendererName.c_str(), L"AGG") == 0)
         {
-            //-------------------------------------------------------
-            /// RFC60 code to correct colormaps by UV
-            //-------------------------------------------------------
-            // We examine the expressions collected from xml definitions of all layers.
-            // The map object has a list from all color entries found in the most recent
-            // layer stylization.
-            // * TODO - currently they are interpreted as ffffffff 32-bit RGBA string values
-            // * adding expresssions and other interpretations should be done in ParseColorStrings
-            // * the color Palette for the renderer is a vector<RS_Color>
-            if (hasColorMap(format))
+            if (format == MgImageFormats::Meta)  // we dont use the colorPalette here for meta tiling
+            {                       // as this call only returns the framebuffer
+                data.reset(((AGGRenderer*)dr)->Save(format, saveWidth, saveHeight, NULL, NULL));
+                // copy the framebuffer into the reader, RenderTileFromMetatile is taking it from there
+            }
+            else
             {
-                RS_ColorVector tileColorPalette;
-                MgMappingUtil::ParseColorStrings(&tileColorPalette, map);
-//              printf("<<<<<<<<<<<<<<<<<<<<< MgServerRenderingService::ColorPalette->size(): %d\n", tileColorPalette.size());
-                data.reset(((AGGRenderer*)dr)->Save(format, saveWidth, saveHeight, &tileColorPalette));
+                //-------------------------------------------------------
+                /// RFC60 code to correct colormaps by UV
+                //-------------------------------------------------------
+                // We examine the expressions collected from xml definitions of all layers.
+                // The map object has a list from all color entries found in the most recent
+                // layer stylization.
+                // * TODO - currently they are interpreted as ffffffff 32-bit RGBA string values
+                // * adding expresssions and other interpretations should be done in ParseColorStrings
+                // * the color Palette for the renderer is a vector<RS_Color>
+                if (hasColorMap(format))
+                {
+                    RS_ColorVector tileColorPalette;
+                    MgMappingUtil::ParseColorStrings(&tileColorPalette, map);
+                    //              printf("<<<<<<<<<<<<<<<<<<<<< MgServerRenderingService::ColorPalette->size(): %d\n", tileColorPalette.size());
+                    data.reset(((AGGRenderer*)dr)->Save(format, saveWidth, saveHeight, &tileColorPalette, frameBuffer));
+                }
+                else
+                    data.reset(((AGGRenderer*)dr)->Save(format, saveWidth, saveHeight, NULL, frameBuffer));
             }
-            else
-                data.reset(((AGGRenderer*)dr)->Save(format, saveWidth, saveHeight, NULL));
         }
         else
             data.reset(((GDRenderer*)dr)->Save(format, saveWidth, saveHeight));
@@ -2379,6 +2444,8 @@
             bs->SetMimeType(MgMimeType::Png);
         else if (format == MgImageFormats::Tiff)
             bs->SetMimeType(MgMimeType::Tiff);
+        else if (format == MgImageFormats::Meta)         // add a mimetype for our metatile
+            bs->SetMimeType(MgMimeType::Meta);
     }
     else
         throw new MgNullReferenceException(L"MgServerRenderingService.CreateImage", __LINE__, __WFILE__, NULL, L"MgNoDataFromRenderer", NULL);
@@ -2404,7 +2471,8 @@
                                                    INT32 tileHeight,
                                                    INT32 tileDpi,
                                                    CREFSTRING tileImageFormat,
-                                                   double tileExtentOffset)
+                                                   double tileExtentOffset,
+                                                   INT32 metaTileFactor)
 {
     Ptr<MgByteReader> ret;
 
@@ -2445,27 +2513,14 @@
     // upper left corner of the map extent
     // ------------------------------------------------------
 
-    Ptr<MgEnvelope> mapExtent = map->GetMapExtent();
-    Ptr<MgCoordinate> pt00 = mapExtent->GetLowerLeftCoordinate();
-    Ptr<MgCoordinate> pt11 = mapExtent->GetUpperRightCoordinate();
-    double mapMinX = rs_min(pt00->GetX(), pt11->GetX());
-    double mapMaxX = rs_max(pt00->GetX(), pt11->GetX());
-    double mapMinY = rs_min(pt00->GetY(), pt11->GetY());
-    double mapMaxY = rs_max(pt00->GetY(), pt11->GetY());
+    double tileMinX, tileMaxX, tileMinY, tileMaxY;
+    map->GetTileCoords(std::max(metaTileFactor, 1), tileColumn, tileRow, tileDpi, tileWidth, tileHeight, tileMinX, tileMaxX, tileMinY, tileMaxY);
 
-    double metersPerUnit  = map->GetMetersPerUnit();
-    double metersPerPixel = METERS_PER_INCH / tileDpi;
-    double tileWidthMCS   = (double)tileWidth  * metersPerPixel * scale / metersPerUnit;
-    double tileHeightMCS  = (double)tileHeight * metersPerPixel * scale / metersPerUnit;
-
-    double tileMinX = mapMinX + (double)(tileColumn  ) * tileWidthMCS;  // left edge
-    double tileMaxX = mapMinX + (double)(tileColumn+1) * tileWidthMCS;  // right edge
-    double tileMinY = mapMaxY - (double)(tileRow   +1) * tileHeightMCS; // bottom edge
-    double tileMaxY = mapMaxY - (double)(tileRow     ) * tileHeightMCS; // top edge
-
     // make the call to render the tile
-    ret = RenderTileInternal(map, baseGroup, scaleIndex, tileWidth, tileHeight, scale,
-                             tileMinX, tileMaxX, tileMinY, tileMaxY, tileImageFormat,
+    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")

Modified: sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.h
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.h	2019-04-15 11:39:50 UTC (rev 9491)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.h	2019-04-23 04:04:25 UTC (rev 9492)
@@ -64,7 +64,8 @@
                                      INT32 tileHeight,
                                      INT32 tileDpi,
                                      CREFSTRING tileImageFormat,
-                                     double tileExtentOffset);
+                                     double tileExtentOffset,
+                                     INT32 metaTileFactor);
 
     virtual MgByteReader* RenderTileXYZ(MgMap* map,
                                         CREFSTRING baseMapLayerGroupName,
@@ -262,6 +263,10 @@
                                         bool bIncludeFeatureBBOX,
                                         bool bIncludeGeometry);
 
+    MgByteReader* RenderTileFromMetaTile(MgMap* map, MgByteReader* metaTileBitMap, CREFSTRING origTileFormat,
+                                         INT32 origTileWidth, INT32 origTileHeight, 
+                                         INT32 metaTileFactor, INT32 subTileX, INT32 subTileY);
+
 private:
     static void ComputeXYZTileExtents(MgMap* map, INT32 x, INT32 y, INT32 z, RS_Bounds& extent);
     // used for tile generation
@@ -363,7 +368,8 @@
                               INT32 saveWidth,
                               INT32 saveHeight,
                               CREFSTRING format,
-                              ProfileRenderMapResult* pPRMResult);
+                              ProfileRenderMapResult* pPRMResult,
+                              unsigned int* frameBuffer = NULL);
 
     // member data
     Ptr<MgFeatureService> m_svcFeature;

Modified: sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefaultProvider.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefaultProvider.cpp	2019-04-15 11:39:50 UTC (rev 9491)
+++ sandbox/jng/tiling_v2/Server/src/Services/Tile/TileCacheDefaultProvider.cpp	2019-04-23 04:04:25 UTC (rev 9492)
@@ -65,7 +65,7 @@
     if (svcRendering != NULL)
     {
         // generate the tile
-        img = svcRendering->RenderTile(map, baseMapLayerGroupName, tileColumn, tileRow, GetDefaultTileSizeX(), GetDefaultTileSizeY(), map->GetDisplayDpi(), GetTileFormat(), m_tileExtentOffset);
+        img = svcRendering->RenderTile(map, baseMapLayerGroupName, tileColumn, tileRow, GetDefaultTileSizeX(), GetDefaultTileSizeY(), map->GetDisplayDpi(), GetTileFormat(), m_tileExtentOffset, 0);
 
         // 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-15 11:39:50 UTC (rev 9491)
+++ sandbox/jng/tiling_v2/Server/src/UnitTesting/TestRenderingService.cpp	2019-04-23 04:04:25 UTC (rev 9492)
@@ -24,6 +24,9 @@
 //#include "GDRenderer.h"
 //#include "AGGRenderer.h"
 #include "FoundationDefs.h"
+#include "SE_Renderer.h"
+#include "ServerRenderingService.h"
+
 const STRING TEST_LOCALE = L"en";
 
 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(TestRenderingService, "TestRenderingService");
@@ -1737,6 +1740,43 @@
     }
 }
 
+void TestRenderingService::TestCase_RenderMetatile()
+{
+    try
+    {
+        Ptr<MgMap> map = CreateTestTiledMap();
+        map->SetViewScale(12500.0);
+
+        //This should be a server impl
+        MgServerRenderingService* renderSvc = dynamic_cast<MgServerRenderingService*>(m_svcRendering.p);
+        CPPUNIT_ASSERT(NULL != renderSvc);
+
+        // 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, MgImageFormats::Png, 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, MgImageFormats::Png, MgTileParameters::tileWidth, MgTileParameters::tileHeight, 2, 0, 0);
+        Ptr<MgByteReader> tile4_7 = renderSvc->RenderTileFromMetaTile(map, metaTile, MgImageFormats::Png, MgTileParameters::tileWidth, MgTileParameters::tileHeight, 2, 0, 1);
+        Ptr<MgByteReader> tile5_6 = renderSvc->RenderTileFromMetaTile(map, metaTile, MgImageFormats::Png, MgTileParameters::tileWidth, MgTileParameters::tileHeight, 2, 1, 0);
+        Ptr<MgByteReader> tile5_7 = renderSvc->RenderTileFromMetaTile(map, metaTile, MgImageFormats::Png, MgTileParameters::tileWidth, MgTileParameters::tileHeight, 2, 1, 1);
+
+
+        tile4_6->ToFile(L"../UnitTestFiles/RenderTile_4_6_Metatiled.png");
+        tile4_7->ToFile(L"../UnitTestFiles/RenderTile_4_7_Metatiled.png");
+        tile5_6->ToFile(L"../UnitTestFiles/RenderTile_5_6_Metatiled.png");
+        tile5_7->ToFile(L"../UnitTestFiles/RenderTile_5_7_Metatiled.png");
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+}
+
 void TestRenderingService::TestCase_RenderTile(CREFSTRING imageFormat, CREFSTRING extension)
 {
     try

Modified: sandbox/jng/tiling_v2/Server/src/UnitTesting/TestRenderingService.h
===================================================================
--- sandbox/jng/tiling_v2/Server/src/UnitTesting/TestRenderingService.h	2019-04-15 11:39:50 UTC (rev 9491)
+++ sandbox/jng/tiling_v2/Server/src/UnitTesting/TestRenderingService.h	2019-04-23 04:04:25 UTC (rev 9492)
@@ -26,7 +26,8 @@
     CPPUNIT_TEST(TestStart); // This must be the very first unit test
 
     CPPUNIT_TEST(TestCase_RenderTileBaseline);
-
+    CPPUNIT_TEST(TestCase_RenderMetatile);
+    
     CPPUNIT_TEST(TestCase_StylizationFunctionsPNG);
 
     CPPUNIT_TEST(TestCase_SymbologyPointsPNG);
@@ -145,7 +146,6 @@
     CPPUNIT_TEST(TestCase_RenderTileXYZ_JPG);
 
     CPPUNIT_TEST(TestCase_QueryFeatures);
-
     //CPPUNIT_TEST(TestCase_RendererPerformance);
 
     CPPUNIT_TEST(TestEnd); // This must be the very last unit test
@@ -162,6 +162,7 @@
 
     void TestCase_QueryFeatures();
     void TestCase_RenderTileBaseline();
+    void TestCase_RenderMetatile();
     void TestCase_RenderTile(CREFSTRING imageFormat, CREFSTRING extension);
     void TestCase_RenderTileXYZ(CREFSTRING imageFormat, CREFSTRING extension);
 



More information about the mapguide-commits mailing list