[mapguide-commits] r8175 - sandbox/jng/tiling/Server/src/Services/Rendering

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Fri May 30 00:00:17 PDT 2014


Author: jng
Date: 2014-05-30 00:00:17 -0700 (Fri, 30 May 2014)
New Revision: 8175

Modified:
   sandbox/jng/tiling/Server/src/Services/Rendering/ServerRenderingService.cpp
Log:
Apply scaling logic (same logic used in RenderMap overloads that take MgEnvelope) for XYZ-rendered tiles.

Modified: sandbox/jng/tiling/Server/src/Services/Rendering/ServerRenderingService.cpp
===================================================================
--- sandbox/jng/tiling/Server/src/Services/Rendering/ServerRenderingService.cpp	2014-05-29 16:06:16 UTC (rev 8174)
+++ sandbox/jng/tiling/Server/src/Services/Rendering/ServerRenderingService.cpp	2014-05-30 07:00:17 UTC (rev 8175)
@@ -289,6 +289,9 @@
     //Set the dpi
     map->SetDisplayDpi(dpi);
 
+    int width = XYZ_TILE_WIDTH;
+    int height = XYZ_TILE_HEIGHT;
+
     //XYZ to lat/lon math. From this we can convert to the bounds in the map's CS
     //
     //Source: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
@@ -324,18 +327,12 @@
 
     // Inlining same logic from RenderTile() overload below as we want the same logic, but we want to pass scale
     // instead of scale index
-    double scale = 0.0;
-    double metersPerPixel = 0.0254 / dpi;
-    double mcsW = mcsMaxX - mcsMinX;
-    double mcsH = mcsMaxY - mcsMinY;
-    if (XYZ_TILE_HEIGHT * mcsW > XYZ_TILE_WIDTH * mcsH)
-        scale = mcsW * map->GetMetersPerUnit() / (XYZ_TILE_WIDTH * metersPerPixel); // width-limited
-    else
-        scale = mcsH * map->GetMetersPerUnit() / (XYZ_TILE_HEIGHT * metersPerPixel); // height-limited
 
     // get map extent that corresponds to tile extent
     RS_Bounds extent(mcsMinX, mcsMinY, mcsMaxX, mcsMaxY);
 
+    //printf("XYZ(%d, %d, %d) -> [%f, %f] [%f, %f]\n", x, y, z, mcsMinX, mcsMinY, mcsMaxX, mcsMaxY);
+
     // use the map's background color, but always make it fully transparent
     RS_Color bgColor;
     StylizationUtil::ParseColor(map->GetBackgroundColor(), bgColor);
@@ -350,10 +347,56 @@
                           MgConfigProperties::DefaultRenderingServicePropertyTileExtentOffset);
     if (tileExtentOffset < 0.0)
         tileExtentOffset = MgConfigProperties::DefaultRenderingServicePropertyTileExtentOffset;
+    
+    // Image scaling logic ripped verbatim from RenderMap() overload that takes MgEnvelope
+    //
+    // If we need to scale the image (because of request for non-square
+    // pixels) we will need to draw at one image size and then save at
+    // another scaled size.  Here we will compute the correct map scale
+    // and render size for a requested extent and image size.
+    double screenAR = (double)width / (double)height;
+    double mapAR = extent.width() / extent.height();
 
+    int drawWidth = width;
+    int drawHeight = height;
+    double scale = 0.0;
+
+    if (mapAR >= screenAR)
+    {
+        scale = extent.width() * map->GetMetersPerUnit() / METERS_PER_INCH * (double)dpi / (double)width;
+
+        // we based map scale on the image width, so adjust rendering
+        // height to match the map aspect ratio
+        drawHeight = (int)(width / mapAR);
+
+        // ignore small perturbations in order to avoid rescaling the
+        // end image in cases where the rescaling of width is less than
+        // a pixel or so
+        if (abs(drawHeight - height) <= 1)
+            drawHeight = height;
+    }
+    else
+    {
+        scale = extent.height() * map->GetMetersPerUnit() / METERS_PER_INCH * (double)dpi / (double)height;
+
+        // we based map scale on the image height, so adjust rendering
+        // height to match the map aspect ratio
+        drawWidth = (int)(height * mapAR);
+
+        // ignore small perturbations, in order to avoid rescaling the
+        // end image in cases where the rescaling of width is less than
+        // a pixel or so
+        if (abs(drawWidth - width) <= 1)
+            drawWidth = width;
+    }
+
+    // sanity check - number of image pixels cannot exceed MAX_PIXELS
+    if (drawWidth * drawHeight > MAX_PIXELS)
+        throw new MgOutOfRangeException(L"MgServerRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgInvalidImageSizeTooBig", NULL);
+
     // initialize the renderer (set clipping to false so that we label
     // the unclipped geometry)
-    auto_ptr<SE_Renderer> dr(CreateRenderer(XYZ_TILE_WIDTH, XYZ_TILE_HEIGHT, bgColor, false, true, tileExtentOffset));
+    auto_ptr<SE_Renderer> dr(CreateRenderer(drawWidth, drawHeight, bgColor, false, true, tileExtentOffset));
 
     // create a temporary collection containing all the layers for the base group
     Ptr<MgLayerCollection> layers = map->GetLayers();
@@ -371,7 +414,7 @@
     baseGroup->SetVisible(true);
 
     // call the internal helper API to do all the stylization overhead work
-    ret = RenderMapInternal(map, NULL, roLayers, dr.get(), XYZ_TILE_WIDTH, XYZ_TILE_HEIGHT, XYZ_TILE_WIDTH, XYZ_TILE_HEIGHT, tileImageFormat, scale, extent, true, true, false);
+    ret = RenderMapInternal(map, NULL, roLayers, dr.get(), drawWidth, drawHeight, width, height, tileImageFormat, scale, extent, true, true, false);
 
     // restore the base group's visibility
 



More information about the mapguide-commits mailing list