[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