[mapguide-commits] r9496 - in sandbox/jng/tiling_v2: Common/MapGuideCommon/Services Common/Renderers Server/src/Services/Rendering Server/src/UnitTesting
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Thu Apr 25 03:09:05 PDT 2019
Author: jng
Date: 2019-04-25 03:09:05 -0700 (Thu, 25 Apr 2019)
New Revision: 9496
Added:
sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderMetatileXYZ.cpp
sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderMetatileXYZ.h
Modified:
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/RenderingService.h
sandbox/jng/tiling_v2/Common/Renderers/AGGRenderer.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/UnitTesting/TestRenderingService.cpp
sandbox/jng/tiling_v2/Server/src/UnitTesting/TestRenderingService.h
Log:
Implement the XYZ metatile rendering primitive with unit tests.
Modified: sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/ProxyRenderingService.cpp
===================================================================
--- sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/ProxyRenderingService.cpp 2019-04-25 07:15:43 UTC (rev 9495)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/ProxyRenderingService.cpp 2019-04-25 10:09:05 UTC (rev 9496)
@@ -1368,4 +1368,38 @@
SetWarning(cmd.GetWarningObject());
return (MgMetatile*)cmd.GetReturnValue().val.m_obj;
+}
+
+MgMetatile* MgProxyRenderingService::RenderMetatileXYZ(
+ MgMap* map,
+ CREFSTRING baseMapLayerGroupName,
+ INT32 x,
+ INT32 y,
+ INT32 z,
+ INT32 dpi,
+ CREFSTRING tileImageFormat,
+ double tileExtentOffset,
+ INT32 metaTilingFactor)
+{
+ MgCommand cmd;
+ cmd.ExecuteCommand(m_connProp, // Connection
+ MgCommand::knObject, // Return type expected
+ MgRenderingServiceOpId::RenderTileXYZ2, // Command Code
+ 9, // 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, x, // Argument#3
+ MgCommand::knInt32, y, // Argument#4
+ MgCommand::knInt32, z, // Argument#5
+ MgCommand::knInt32, dpi, // Argument#6
+ MgCommand::knString, &tileImageFormat, // Argument#7
+ MgCommand::knDouble, tileExtentOffset, // Argument#8
+ MgCommand::knInt32, metaTilingFactor, // Argument#9
+ 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-25 07:15:43 UTC (rev 9495)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/ProxyRenderingService.h 2019-04-25 10:09:05 UTC (rev 9496)
@@ -1140,13 +1140,21 @@
/// Input
/// Specifies the image format of the tile. See \link MgImageFormats \endlink
/// \param tileExtentOffset
+ /// Input
/// 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
+ /// multiplied by the given ratio, 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.
+ /// \param metaTilingFactor
+ /// Input
+ /// The meta-tiling factor. If less than or equal to 1, no meta-tiling is done and the returned meta-tile can be extracted
+ /// as the orignally requested tile image. If greater than 1, a tile that is m times bigger than the requested tile is rendered
+ /// (where m is the specified tiling factor) and the raw image frame buffer of this meta-tile is returned instead.
///
/// \return
- /// A byte reader containing the rendered tile image.
+ /// A meta-tile with sufficient information for the consumer to properly sub-divide this back into sub-tiles of the
+ /// originally requested size.
///
+ /// \since 3.3
virtual MgMetatile* RenderMetatile(
MgMap* map,
CREFSTRING baseMapLayerGroupName,
@@ -1159,6 +1167,60 @@
double tileExtentOffset,
INT32 metaTilingFactor);
+ /////////////////////////////////////////////////////////////////
+ /// \brief
+ /// Returns the specified map tile for the given map. Tile structure is
+ /// based on the XYZ tiling scheme used by Google Maps, OpenStreetMap, and
+ /// others
+ ///
+ /// \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 x
+ /// Input
+ /// Specifies the row index of the tile to return.
+ /// \param y
+ /// Input
+ /// Specifies the column index of the tile to return.
+ /// \param z
+ /// Input
+ /// Specifies the zoom level of the tile to return.
+ /// \param dpi
+ /// Input
+ /// Specifies the dpi of the tile to return.
+ /// \param tileImageFormat
+ /// Input
+ /// Specifies the image format of the tile to return.
+ /// \param tileExtentOffset
+ /// Input
+ /// 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 ratio, 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.
+ /// \param metaTilingFactor
+ /// Input
+ /// The meta-tiling factor. If less than or equal to 1, no meta-tiling is done and the returned meta-tile can be extracted
+ /// as the orignally requested tile image. If greater than 1, a tile that is m times bigger than the requested tile is rendered
+ /// (where m is the specified tiling factor) and the raw image frame buffer of this meta-tile is returned instead.
+ ///
+ /// \return
+ /// A meta-tile with sufficient information for the consumer to properly sub-divide this back into sub-tiles of the
+ /// originally requested size.
+ ///
+ /// \since 3.3
+ virtual MgMetatile* RenderMetatileXYZ(
+ MgMap* map,
+ CREFSTRING baseMapLayerGroupName,
+ INT32 x,
+ INT32 y,
+ INT32 z,
+ INT32 dpi,
+ CREFSTRING tileImageFormat,
+ double tileExtentOffset,
+ INT32 metaTilingFactor);
+
protected:
//////////////////////////////////////////////////////////////////
Modified: sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/RenderingService.h
===================================================================
--- sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/RenderingService.h 2019-04-25 07:15:43 UTC (rev 9495)
+++ sandbox/jng/tiling_v2/Common/MapGuideCommon/Services/RenderingService.h 2019-04-25 10:09:05 UTC (rev 9496)
@@ -1153,12 +1153,19 @@
/// Input
/// Specifies the image format of the tile. See \link MgImageFormats \endlink
/// \param tileExtentOffset
+ /// Input
/// 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
+ /// multiplied by the given ratio, 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.
+ /// \param metaTilingFactor
+ /// Input
+ /// The meta-tiling factor. If less than or equal to 1, no meta-tiling is done and the returned meta-tile can be extracted
+ /// as the orignally requested tile image. If greater than 1, a tile that is m times bigger than the requested tile is rendered
+ /// (where m is the specified tiling factor) and the raw image frame buffer of this meta-tile is returned instead.
///
/// \return
- /// A byte reader containing the rendered tile image.
+ /// A meta-tile with sufficient information for the consumer to properly sub-divide this back into sub-tiles of the
+ /// originally requested size.
///
/// \since 3.3
virtual MgMetatile* RenderMetatile(
@@ -1171,8 +1178,62 @@
INT32 tileDpi,
CREFSTRING tileImageFormat,
double tileExtentOffset,
- INT32 metaTileFactor) = 0;
+ INT32 metaTilingFactor) = 0;
+ /////////////////////////////////////////////////////////////////
+ /// \brief
+ /// Returns the specified map tile for the given map. Tile structure is
+ /// based on the XYZ tiling scheme used by Google Maps, OpenStreetMap, and
+ /// others
+ ///
+ /// \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 x
+ /// Input
+ /// Specifies the row index of the tile to return.
+ /// \param y
+ /// Input
+ /// Specifies the column index of the tile to return.
+ /// \param z
+ /// Input
+ /// Specifies the zoom level of the tile to return.
+ /// \param dpi
+ /// Input
+ /// Specifies the dpi of the tile to return.
+ /// \param tileImageFormat
+ /// Input
+ /// Specifies the image format of the tile to return.
+ /// \param tileExtentOffset
+ /// Input
+ /// 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 ratio, 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.
+ /// \param metaTilingFactor
+ /// Input
+ /// The meta-tiling factor. If less than or equal to 1, no meta-tiling is done and the returned meta-tile can be extracted
+ /// as the orignally requested tile image. If greater than 1, a tile that is m times bigger than the requested tile is rendered
+ /// (where m is the specified tiling factor) and the raw image frame buffer of this meta-tile is returned instead.
+ ///
+ /// \return
+ /// A meta-tile with sufficient information for the consumer to properly sub-divide this back into sub-tiles of the
+ /// originally requested size.
+ ///
+ /// \since 3.3
+ virtual MgMetatile* RenderMetatileXYZ(
+ MgMap* map,
+ CREFSTRING baseMapLayerGroupName,
+ INT32 x,
+ INT32 y,
+ INT32 z,
+ INT32 dpi,
+ CREFSTRING tileImageFormat,
+ double tileExtentOffset,
+ INT32 metaTilingFactor) = 0;
+
protected:
/////////////////////////////////////////////////////////////////
Modified: sandbox/jng/tiling_v2/Common/Renderers/AGGRenderer.cpp
===================================================================
--- sandbox/jng/tiling_v2/Common/Renderers/AGGRenderer.cpp 2019-04-25 07:15:43 UTC (rev 9495)
+++ sandbox/jng/tiling_v2/Common/Renderers/AGGRenderer.cpp 2019-04-25 10:09:05 UTC (rev 9496)
@@ -268,6 +268,11 @@
{
// if (imagebuffer == NULL) // this musnt happen
// return NULL;
+
+ // TODO: For extent-based tiles like XYZ, it means our framebuffer represents a non-square
+ // tile, which technically means we're wasting allocated memory on pixels that aren't being
+ // stored for such cases, but this being the first cut implementation, we're being extremely
+ // conservative here. If there is indeed wasted space. So be it.
int imagebufferByteSize = width * height * 4; // multiply 32 bit pixel by 4 bytes
return new RS_ByteData((unsigned char*)m_rows, imagebufferByteSize);
}
Added: sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderMetatileXYZ.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderMetatileXYZ.cpp (rev 0)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderMetatileXYZ.cpp 2019-04-25 10:09:05 UTC (rev 9496)
@@ -0,0 +1,126 @@
+//
+// 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 "OpRenderMetatileXYZ.h"
+#include "LogManager.h"
+
+MgOpRenderMetatileXYZ::MgOpRenderMetatileXYZ()
+{
+}
+
+MgOpRenderMetatileXYZ::~MgOpRenderMetatileXYZ()
+{
+}
+
+void MgOpRenderMetatileXYZ::Execute()
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT(" (%t) MgOpRenderMetatileXYZ::Execute()\n")));
+
+ MG_LOG_OPERATION_MESSAGE(L"MgOpRenderMetatileXYZ");
+
+ MG_TRY()
+
+ MG_LOG_OPERATION_MESSAGE_INIT(m_packet.m_OperationVersion, m_packet.m_NumArguments);
+
+ ACE_ASSERT(m_stream != NULL);
+
+ if (8 == 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 x = 0;
+ m_stream->GetInt32(x);
+
+ INT32 y = 0;
+ m_stream->GetInt32(y);
+
+ INT32 z = 0;
+ m_stream->GetInt32(z);
+
+ INT32 tileDpi = 0;
+ m_stream->GetInt32(tileDpi);
+
+ STRING tileImageFormat;
+ m_stream->GetString(tileImageFormat);
+
+ double tileExtentOffset = 0.0;
+ m_stream->GetDouble(tileExtentOffset);
+
+ INT32 metaTilingFactor = 0;
+ m_stream->GetInt32(metaTilingFactor);
+
+ 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(x);
+ MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+ MG_LOG_OPERATION_MESSAGE_ADD_INT32(y);
+ MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+ MG_LOG_OPERATION_MESSAGE_ADD_INT32(z);
+ 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(metaTilingFactor);
+ MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+
+ Validate();
+
+ Ptr<MgMetatile> metaTile = m_service->RenderMetatileXYZ(map, baseMapLayerGroupName, x, y, z, tileDpi, tileImageFormat, tileExtentOffset, metaTilingFactor);
+
+ EndExecution(metaTile);
+ }
+ else
+ {
+ MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+ MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+ }
+
+ if (!m_argsRead)
+ {
+ throw new MgOperationProcessingException(L"MgOpRenderMetatileXYZ.Execute",
+ __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ // Successful operation
+ MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
+
+ MG_CATCH(L"MgOpRenderMetatileXYZ.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/OpRenderMetatileXYZ.h
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderMetatileXYZ.h (rev 0)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/OpRenderMetatileXYZ.h 2019-04-25 10:09:05 UTC (rev 9496)
@@ -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_XYZ_H
+#define MG_OP_RENDER_METATILE_XYZ_H
+
+#include "RenderingOperation.h"
+
+class MgOpRenderMetatileXYZ : public MgRenderingOperation
+{
+public:
+ MgOpRenderMetatileXYZ();
+ virtual ~MgOpRenderMetatileXYZ();
+
+public:
+ virtual void Execute();
+};
+
+#endif
\ No newline at end of file
Modified: sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.cpp 2019-04-25 07:15:43 UTC (rev 9495)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.cpp 2019-04-25 10:09:05 UTC (rev 9496)
@@ -513,18 +513,37 @@
ByteSourceMemoryImpl* source = dynamic_cast<ByteSourceMemoryImpl*>(bs->GetSourceImpl());
assert(source);
assert(bs->GetMimeType() == MgMimeType::Meta);
- int size = (int)source->GetLength();
+ INT32 size = (INT32)source->GetLength();
// some checking: the complete meta tile of 32b pixels should be in the framebuffer handed over
- int expectedSize = 4 * (metaTileFactor * origTileWidth)
+ INT32 expectedSize = 4 * (metaTileFactor * origTileWidth)
* (metaTileFactor * origTileHeight);
assert(size == expectedSize);
+ INT32 scaledTileWidth = origTileWidth;
+ INT32 scaledTileHeight = origTileHeight;
+
+ // For extent-driven tile rendering like XYZ, the raw image frame buffer of the tile may not actually
+ // be square which means the meta-tile itself would not be square, so when we sub-divide we must make
+ // sure to not sub-divide by the original width/height, but by its *proportially scaled* width/height,
+ // which we then pass it down to AGGRenderer::Save() to write the buffer back up to the originally
+ // requested size, scaling as appropriate.
+ if (metaTileFactor > 1)
+ {
+ scaledTileWidth = (INT32)(metaTile->GetWidth() / metaTileFactor);
+ scaledTileHeight = (INT32)(metaTile->GetHeight() / metaTileFactor);
+
+ // This may be the same or may be less, but it can't be more!
+ _ASSERT(scaledTileWidth <= origTileWidth);
+ _ASSERT(scaledTileHeight <= origTileHeight);
+ }
+
// 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));
+ // Must create renderer under the scaled width/height and not original
+ auto_ptr<SE_Renderer> dr(CreateRenderer(scaledTileWidth, scaledTileHeight, bgColor, true));
RS_ColorVector tileColorPalette;
if (m_rendererName == L"AGG" && hasColorMap(origTileFormat))
{
@@ -542,18 +561,18 @@
// 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));
+ auto_ptr<MgByte> subTileBytes(new MgByte((unsigned char*)new unsigned int[scaledTileWidth * scaledTileHeight],
+ scaledTileWidth * scaledTileHeight * 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
+ for (int y = 0; y < scaledTileHeight; y++) // rows
+ for (int x = 0; x < scaledTileWidth; 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
+ + y * scaledTileWidth) // target address in subtile
+ = *(framebuf + (x + (subTileX * scaledTileWidth)) // X address in meta tile
+ + (y + (subTileY * scaledTileHeight)) // Y address in meta tile
+ * scaledTileWidth * 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);
@@ -2436,74 +2455,15 @@
MG_TRY()
- CHECKARGUMENTNULL(map, L"MgServerRenderingService.RenderTileXYZ");
- CHECKARGUMENTEMPTYSTRING(baseMapLayerGroupName, L"MgServerRenderingService.RenderTileXYZ");
-
- // 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);
+ INT32 metaTilingFactor = 0;
+ Ptr<MgMetatile> metaTile = RenderMetatileXYZ(map, baseMapLayerGroupName, x, y, z, dpi, tileImageFormat, tileExtentOffset, metaTilingFactor);
- throw new MgInvalidArgumentException(L"MgServerRenderingService.RenderTileXYZ",
- __LINE__, __WFILE__, &arguments, L"MgMapLayerGroupNameNotFound", NULL);
- }
+ _ASSERT(metaTile->GetRequestedWidth() == XYZ_TILE_WIDTH);
+ _ASSERT(metaTile->GetRequestedHeight() == XYZ_TILE_HEIGHT);
+ _ASSERT(metaTile->GetMetaTilingFactor() <= 1);
- //Set the dpi
- map->SetDisplayDpi(dpi);
+ ret = metaTile->GetImage();
- int width = XYZ_TILE_WIDTH;
- int height = XYZ_TILE_HEIGHT;
-
- // Inlining same logic from RenderTile() overload below as we want the same logic, but we want to pass scale
- // instead of scale index
- RS_Bounds extent;
- ComputeXYZTileExtents(map, x, y, z, extent);
-
- // use the map's background color, but always make it fully transparent
- RS_Color bgColor;
- StylizationUtil::ParseColor(map->GetBackgroundColor(), bgColor);
- bgColor.alpha() = 0;
-
- INT32 drawWidth = width;
- INT32 drawHeight = height;
- double scale = 0.0;
- ComputeScaledDimensions(extent, width, height, dpi, map->GetMetersPerUnit(), drawWidth, drawHeight, scale);
-
- //printf("XYZ(%d, %d, %d) -> [%f, %f] [%f, %f] at %f -- (w: %d, h: %d, mpu: %f)\n", x, y, z, mcsMinX, mcsMinY, mcsMaxX, mcsMaxY, scale, width, height, map->GetMetersPerUnit());
-
- // 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(drawWidth, drawHeight, bgColor, false, true, tileExtentOffset));
-
- // create a temporary collection containing all the layers for the base group
- Ptr<MgLayerCollection> layers = map->GetLayers();
- Ptr<MgReadOnlyLayerCollection> roLayers = new MgReadOnlyLayerCollection();
- for (int i=0; i<layers->GetCount(); i++)
- {
- Ptr<MgLayerBase> layer = layers->GetItem(i);
- Ptr<MgLayerGroup> parentGroup = layer->GetGroup();
- if (parentGroup == baseGroup)
- roLayers->Add(layer);
- }
-
- // of course the group has to also be visible
- bool groupVisible = baseGroup->GetVisible();
- baseGroup->SetVisible(true);
-
- // call the internal helper API to do all the stylization overhead work
- ret = RenderMapInternal(map, NULL, roLayers, dr.get(), drawWidth, drawHeight, width, height, tileImageFormat, scale, extent, true, true, false, NULL);
-
- // restore the base group's visibility
- baseGroup->SetVisible(groupVisible);
-
MG_CATCH_AND_THROW(L"MgServerRenderingService.RenderTileXYZ")
return ret.Detach();
@@ -2621,4 +2581,105 @@
MG_CATCH_AND_THROW(L"MgServerRenderingService.RenderMetatile")
return ret.Detach();
+}
+
+MgMetatile* MgServerRenderingService::RenderMetatileXYZ(MgMap* map,
+ CREFSTRING baseMapLayerGroupName,
+ INT32 x,
+ INT32 y,
+ INT32 z,
+ INT32 dpi,
+ CREFSTRING tileImageFormat,
+ double tileExtentOffset,
+ INT32 metaTilingFactor)
+{
+ Ptr<MgMetatile> ret;
+
+ MG_TRY()
+
+ CHECKARGUMENTNULL(map, L"MgServerRenderingService.RenderMetatileXYZ");
+ CHECKARGUMENTEMPTYSTRING(baseMapLayerGroupName, L"MgServerRenderingService.RenderMetatileXYZ");
+
+ // 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.RenderMetatileXYZ",
+ __LINE__, __WFILE__, &arguments, L"MgMapLayerGroupNameNotFound", NULL);
+ }
+
+ //Set the dpi
+ map->SetDisplayDpi(dpi);
+
+ // Inlining same logic from RenderTile() overload below as we want the same logic, but we want to pass scale
+ // instead of scale index
+ RS_Bounds extent;
+ ComputeXYZTileExtents(map, x, y, z, extent);
+
+ // If meta-tiling, request bounds for:
+ // (x, y, z) -> (x + (tm - 1), y + (tm - 1), z)
+ // And combine the resulting bounds
+ if (metaTilingFactor > 1)
+ {
+ RS_Bounds extent2;
+ INT32 endX = x + (metaTilingFactor - 1);
+ INT32 endY = y + (metaTilingFactor - 1);
+ ComputeXYZTileExtents(map, endX, endY, z, extent2);
+
+ extent.add_bounds(extent2);
+ }
+
+ // use the map's background color, but always make it fully transparent
+ RS_Color bgColor;
+ StylizationUtil::ParseColor(map->GetBackgroundColor(), bgColor);
+ bgColor.alpha() = 0;
+
+ INT32 width = XYZ_TILE_WIDTH * std::max(metaTilingFactor, 1);
+ INT32 height = XYZ_TILE_HEIGHT * std::max(metaTilingFactor, 1);
+ INT32 drawWidth = width;
+ INT32 drawHeight = height;
+ double scale = 0.0;
+ ComputeScaledDimensions(extent, width, height, dpi, map->GetMetersPerUnit(), drawWidth, drawHeight, scale);
+
+ //printf("XYZ(%d, %d, %d) -> [%f, %f] [%f, %f] at %f -- (w: %d, h: %d, mpu: %f)\n", x, y, z, mcsMinX, mcsMinY, mcsMaxX, mcsMaxY, scale, width, height, map->GetMetersPerUnit());
+
+ // sanity check - number of image pixels cannot exceed MAX_PIXELS
+ if (drawWidth * drawHeight > MAX_PIXELS)
+ throw new MgOutOfRangeException(L"MgServerRenderingService.RenderMetatileXYZ", __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(drawWidth, drawHeight, bgColor, false, true, tileExtentOffset));
+
+ // create a temporary collection containing all the layers for the base group
+ Ptr<MgLayerCollection> layers = map->GetLayers();
+ Ptr<MgReadOnlyLayerCollection> roLayers = new MgReadOnlyLayerCollection();
+ for (int i=0; i<layers->GetCount(); i++)
+ {
+ Ptr<MgLayerBase> layer = layers->GetItem(i);
+ Ptr<MgLayerGroup> parentGroup = layer->GetGroup();
+ if (parentGroup == baseGroup)
+ roLayers->Add(layer);
+ }
+
+ // of course the group has to also be visible
+ bool groupVisible = baseGroup->GetVisible();
+ baseGroup->SetVisible(true);
+
+ // call the internal helper API to do all the stylization overhead work
+ STRING format = (metaTilingFactor > 1) ? MgImageFormats::Meta : tileImageFormat;
+ Ptr<MgByteReader> tile = RenderMapInternal(map, NULL, roLayers, dr.get(), drawWidth, drawHeight, width, height, format, scale, extent, true, true, false, NULL);
+ ret = new MgMetatile(tile, drawWidth, drawHeight, XYZ_TILE_WIDTH, XYZ_TILE_HEIGHT, tileImageFormat, metaTilingFactor);
+
+ // restore the base group's visibility
+ baseGroup->SetVisible(groupVisible);
+
+ MG_CATCH_AND_THROW(L"MgServerRenderingService.RenderMetatileXYZ")
+
+ 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-25 07:15:43 UTC (rev 9495)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.h 2019-04-25 10:09:05 UTC (rev 9496)
@@ -273,6 +273,16 @@
double tileExtentOffset,
INT32 metaTilingFactor);
+ virtual MgMetatile* RenderMetatileXYZ(MgMap* map,
+ CREFSTRING baseMapLayerGroupName,
+ INT32 x,
+ INT32 y,
+ INT32 z,
+ INT32 dpi,
+ CREFSTRING tileImageFormat,
+ double tileExtentOffset,
+ INT32 metaTilingFactor);
+
MgByteReader* RenderTileFromMetaTile(MgMap* map, MgMetatile* metaTile, INT32 subTileX, INT32 subTileY);
private:
Modified: sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.vcxproj
===================================================================
--- sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.vcxproj 2019-04-25 07:15:43 UTC (rev 9495)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.vcxproj 2019-04-25 10:09:05 UTC (rev 9496)
@@ -234,6 +234,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
+ <ClCompile Include="OpRenderMetatileXYZ.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>
@@ -303,6 +309,7 @@
<ClInclude Include="OpRenderMap.h" />
<ClInclude Include="OpRenderMapLegend.h" />
<ClInclude Include="OpRenderMetatile.h" />
+ <ClInclude Include="OpRenderMetatileXYZ.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-25 07:15:43 UTC (rev 9495)
+++ sandbox/jng/tiling_v2/Server/src/Services/Rendering/ServerRenderingService.vcxproj.filters 2019-04-25 10:09:05 UTC (rev 9496)
@@ -45,6 +45,9 @@
<ClCompile Include="OpRenderMetatile.cpp">
<Filter>Ops</Filter>
</ClCompile>
+ <ClCompile Include="OpRenderMetatileXYZ.cpp">
+ <Filter>Ops</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="OpQueryFeatureProperties.h">
@@ -86,6 +89,9 @@
<ClInclude Include="OpRenderMetatile.h">
<Filter>Ops</Filter>
</ClInclude>
+ <ClInclude Include="OpRenderMetatileXYZ.h">
+ <Filter>Ops</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ServerRenderingService.rc" />
Modified: sandbox/jng/tiling_v2/Server/src/UnitTesting/TestRenderingService.cpp
===================================================================
--- sandbox/jng/tiling_v2/Server/src/UnitTesting/TestRenderingService.cpp 2019-04-25 07:15:43 UTC (rev 9495)
+++ sandbox/jng/tiling_v2/Server/src/UnitTesting/TestRenderingService.cpp 2019-04-25 10:09:05 UTC (rev 9496)
@@ -1762,6 +1762,51 @@
}
}
+void TestRenderingService::TestCase_RenderXYZMetatile(CREFSTRING imageFormat, CREFSTRING extension)
+{
+ try
+ {
+ Ptr<MgMap> map = CreateTestTiledMap();
+ map->SetViewScale(12500.0);
+ Ptr<MgByteReader> tile_16798_23891_baseline = m_svcRendering->RenderTileXYZ(map, L"BaseLayers", 16798, 23891, 16, MgTileParameters::tileDPI, imageFormat);
+ Ptr<MgByteReader> tile_16799_23891_baseline = m_svcRendering->RenderTileXYZ(map, L"BaseLayers", 16799, 23891, 16, MgTileParameters::tileDPI, imageFormat);
+ Ptr<MgByteReader> tile_16798_23892_baseline = m_svcRendering->RenderTileXYZ(map, L"BaseLayers", 16798, 23892, 16, MgTileParameters::tileDPI, imageFormat);
+ Ptr<MgByteReader> tile_16799_23892_baseline = m_svcRendering->RenderTileXYZ(map, L"BaseLayers", 16799, 23892, 16, MgTileParameters::tileDPI, imageFormat);
+
+ tile_16798_23891_baseline->ToFile(GetPath(L"../UnitTestFiles/RenderTileXYZ_16798_23891_16_Baseline", imageFormat, extension));
+ tile_16799_23891_baseline->ToFile(GetPath(L"../UnitTestFiles/RenderTileXYZ_16799_23891_16_Baseline", imageFormat, extension));
+ tile_16798_23892_baseline->ToFile(GetPath(L"../UnitTestFiles/RenderTileXYZ_16798_23892_16_Baseline", imageFormat, extension));
+ tile_16799_23892_baseline->ToFile(GetPath(L"../UnitTestFiles/RenderTileXYZ_16799_23892_16_Baseline", imageFormat, extension));
+
+ //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<MgMetatile> metaTile = renderSvc->RenderMetatileXYZ(map, L"BaseLayers", 16798, 23891, 16, MgTileParameters::tileDPI, imageFormat, MgConfigProperties::DefaultRenderingServicePropertyTileExtentOffset, metaTileFactor);
+ //metaTile->ToFile(L"../UnitTestFiles/RenderTileXYZ_Metatile at 16798_23891_16.png");
+ //CPPUNIT_ASSERT(metaTile->IsRewindable());
+ //metaTile->Rewind();
+
+ Ptr<MgByteReader> tile_16798_23891 = renderSvc->RenderTileFromMetaTile(map, metaTile, 0, 0);
+ Ptr<MgByteReader> tile_16799_23891 = renderSvc->RenderTileFromMetaTile(map, metaTile, 1, 0);
+ Ptr<MgByteReader> tile_16798_23892 = renderSvc->RenderTileFromMetaTile(map, metaTile, 0, 1);
+ Ptr<MgByteReader> tile_16799_23892 = renderSvc->RenderTileFromMetaTile(map, metaTile, 1, 1);
+
+ tile_16798_23891->ToFile(GetPath(L"../UnitTestFiles/RenderTileXYZ_16798_23891_16_Metatiled", imageFormat, extension));
+ tile_16799_23891->ToFile(GetPath(L"../UnitTestFiles/RenderTileXYZ_16799_23891_16_Metatiled", imageFormat, extension));
+ tile_16798_23892->ToFile(GetPath(L"../UnitTestFiles/RenderTileXYZ_16798_23892_16_Metatiled", imageFormat, extension));
+ tile_16799_23892->ToFile(GetPath(L"../UnitTestFiles/RenderTileXYZ_16799_23892_16_Metatiled", imageFormat, extension));
+ }
+ 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-25 07:15:43 UTC (rev 9495)
+++ sandbox/jng/tiling_v2/Server/src/UnitTesting/TestRenderingService.h 2019-04-25 10:09:05 UTC (rev 9496)
@@ -25,6 +25,11 @@
CPPUNIT_TEST_SUITE(TestRenderingService);
CPPUNIT_TEST(TestStart); // This must be the very first unit test
+ CPPUNIT_TEST(TestCase_RenderXYZMetatilePNG);
+ CPPUNIT_TEST(TestCase_RenderXYZMetatilePNG8);
+ CPPUNIT_TEST(TestCase_RenderXYZMetatileJPG);
+ CPPUNIT_TEST(TestCase_RenderXYZMetatileGIF);
+
CPPUNIT_TEST(TestCase_RenderMetatilePNG);
CPPUNIT_TEST(TestCase_RenderMetatilePNG8);
CPPUNIT_TEST(TestCase_RenderMetatileJPG);
@@ -164,6 +169,7 @@
void TestCase_QueryFeatures();
void TestCase_RenderMetatile(CREFSTRING imageFormat, CREFSTRING extension);
+ void TestCase_RenderXYZMetatile(CREFSTRING imageFormat, CREFSTRING extension);
void TestCase_RenderTile(CREFSTRING imageFormat, CREFSTRING extension);
void TestCase_RenderTileXYZ(CREFSTRING imageFormat, CREFSTRING extension);
@@ -312,6 +318,11 @@
void TestCase_RenderMetatileJPG() { TestCase_RenderMetatile(L"JPG", L"jpg"); }
void TestCase_RenderMetatileGIF() { TestCase_RenderMetatile(L"GIF", L"gif"); }
+ void TestCase_RenderXYZMetatilePNG() { TestCase_RenderXYZMetatile(L"PNG", L"png"); }
+ void TestCase_RenderXYZMetatilePNG8() { TestCase_RenderXYZMetatile(L"PNG8", L"png"); }
+ void TestCase_RenderXYZMetatileJPG() { TestCase_RenderXYZMetatile(L"JPG", L"jpg"); }
+ void TestCase_RenderXYZMetatileGIF() { TestCase_RenderXYZMetatile(L"GIF", L"gif"); }
+
private:
MgMap* CreateTestMap();
MgMap* CreateTestTiledMap();
More information about the mapguide-commits
mailing list