[mapguide-commits] r1064 - in trunk/MgDev: Common/Foundation/System
Common/MapGuideCommon/Services Common/MapGuideCommon/System
Common/PlatformBase/Services Common/Stylization
Server/src/Common/Manager Server/src/Services/Kml
Server/src/Services/Mapping Server/src/Services/Resource
Server/src/Services/Tile
UnitTest/WebTier/MapAgent/MapAgentForms Web/src/HttpHandler
Web/src/mapviewerjava Web/src/mapviewernet
Web/src/mapviewerphp Web/src/viewerfiles
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Fri Jan 19 19:49:26 EST 2007
Author: trevorwekel
Date: 2007-01-19 19:49:25 -0500 (Fri, 19 Jan 2007)
New Revision: 1064
Added:
trunk/MgDev/Common/Stylization/complex_polygon_gd.cpp
trunk/MgDev/Common/Stylization/complex_polygon_gd.h
trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/gettileimageform2.html
Modified:
trunk/MgDev/Common/Foundation/System/MemoryStreamHelper.cpp
trunk/MgDev/Common/Foundation/System/MemoryStreamHelper.h
trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.cpp
trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.h
trunk/MgDev/Common/MapGuideCommon/Services/Site.cpp
trunk/MgDev/Common/MapGuideCommon/Services/Site.h
trunk/MgDev/Common/MapGuideCommon/Services/SiteConnection.cpp
trunk/MgDev/Common/MapGuideCommon/Services/TileService.h
trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp
trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.h
trunk/MgDev/Common/MapGuideCommon/System/UserInformation.cpp
trunk/MgDev/Common/PlatformBase/Services/ResourceService.cpp
trunk/MgDev/Common/PlatformBase/Services/ResourceService.h
trunk/MgDev/Common/PlatformBase/Services/ServiceRegistry.cpp
trunk/MgDev/Common/Stylization/GDRenderer.cpp
trunk/MgDev/Common/Stylization/GDRenderer.h
trunk/MgDev/Common/Stylization/LabelRendererLocal.cpp
trunk/MgDev/Common/Stylization/Makefile.am
trunk/MgDev/Common/Stylization/Stylization.vcproj
trunk/MgDev/Server/src/Common/Manager/LogManager.cpp
trunk/MgDev/Server/src/Common/Manager/LogManager.h
trunk/MgDev/Server/src/Common/Manager/PermissionManager.cpp
trunk/MgDev/Server/src/Services/Kml/ServerKmlService.cpp
trunk/MgDev/Server/src/Services/Mapping/StylizationUtil.cpp
trunk/MgDev/Server/src/Services/Mapping/StylizationUtil.h
trunk/MgDev/Server/src/Services/Resource/RepositoryManager.h
trunk/MgDev/Server/src/Services/Resource/ResourceDefinitionManager.h
trunk/MgDev/Server/src/Services/Resource/ServerResourceService.cpp
trunk/MgDev/Server/src/Services/Resource/ServerResourceService.h
trunk/MgDev/Server/src/Services/Resource/SessionRepositoryManager.h
trunk/MgDev/Server/src/Services/Resource/SystemRepositoryManager.h
trunk/MgDev/Server/src/Services/Tile/OpGetTile.cpp
trunk/MgDev/Server/src/Services/Tile/ServerTileService.cpp
trunk/MgDev/Server/src/Services/Tile/ServerTileService.h
trunk/MgDev/Server/src/Services/Tile/TileCache.cpp
trunk/MgDev/Server/src/Services/Tile/TileCache.h
trunk/MgDev/Server/src/Services/Tile/TileOperationFactory.cpp
trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/tileserviceapi.html
trunk/MgDev/Web/src/HttpHandler/HttpGetTileImage.cpp
trunk/MgDev/Web/src/HttpHandler/HttpGetTileImage.h
trunk/MgDev/Web/src/HttpHandler/HttpRequestResponseHandler.cpp
trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.cpp
trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.h
trunk/MgDev/Web/src/mapviewerjava/mapframe.jsp
trunk/MgDev/Web/src/mapviewernet/mapframe.aspx
trunk/MgDev/Web/src/mapviewerphp/mapframe.php
trunk/MgDev/Web/src/viewerfiles/ajaxmappane.templ
Log:
MapGuide RFC 11 - Stateless Http GETTILEIMAGE request
Initial submission
Modified: trunk/MgDev/Common/Foundation/System/MemoryStreamHelper.cpp
===================================================================
--- trunk/MgDev/Common/Foundation/System/MemoryStreamHelper.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/Foundation/System/MemoryStreamHelper.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -379,3 +379,12 @@
{
m_curPtrWrite = m_curPtrRead = m_buffer;
}
+
+//////////////////////////////////////////////////////////////////
+///<summary>
+/// Rewind to start of buffer
+///</summary>
+void MgMemoryStreamHelper::Rewind()
+{
+ m_curPtrRead = m_buffer;
+}
Modified: trunk/MgDev/Common/Foundation/System/MemoryStreamHelper.h
===================================================================
--- trunk/MgDev/Common/Foundation/System/MemoryStreamHelper.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/Foundation/System/MemoryStreamHelper.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -155,6 +155,12 @@
///
void Clear();
+ //////////////////////////////////////////////////////////////////
+ /// \brief
+ /// Resets reading to start of buffer
+ ///
+ void Rewind();
+
protected:
void Dispose();
Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -105,7 +105,38 @@
return (MgByteReader*)cmd.GetReturnValue().val.m_obj;
}
+/////////////////////////////////////////////////////////////////
+/// \brief
+/// Returns the specified base map tile for the given map. If a cached tile
+/// image exists it will return it, otherwise the tile is rendered and added
+/// to the cache.
+MgByteReader* MgProxyTileService::GetTile(
+ MgResourceIdentifier* mapDefinition,
+ CREFSTRING baseMapLayerGroupName,
+ INT32 tileColumn,
+ INT32 tileRow,
+ INT32 scaleIndex)
+{
+ MgCommand cmd;
+ cmd.ExecuteCommand(m_connProp, // Connection
+ MgCommand::knObject, // Return type expected
+ MgTileServiceOpId::GetTile, // Command Code
+ 5, // No of arguments
+ Tile_Service, // Service Id
+ 2, // Operation version
+ MgCommand::knObject, mapDefinition, // Argument#1
+ MgCommand::knString, &baseMapLayerGroupName, // Argument#2
+ MgCommand::knInt32, tileColumn, // Argument#3
+ MgCommand::knInt32, tileRow, // Argument#4
+ MgCommand::knInt32, scaleIndex, // Argument#4
+ MgCommand::knNone); // End of arguments
+ SetWarning(cmd.GetWarningObject());
+
+ return (MgByteReader*)cmd.GetReturnValue().val.m_obj;
+}
+
+
/////////////////////////////////////////////////////////////////
/// <summary>
/// Adds the specified base map tile to the cache. If a tile image already
Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -56,6 +56,38 @@
INT32 tileColumn,
INT32 tileRow);
+ /////////////////////////////////////////////////////////////////
+ /// \brief
+ /// Returns the specified base map tile for the given map. If a cached tile
+ /// image exists it will return it, otherwise the tile is rendered and added
+ /// to the cache.
+ ///
+ /// \param mapDefinition
+ /// Input
+ /// Resource identifier for the map definition
+ /// \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 scaleIndex
+ /// Input
+ /// Scale index to render
+ ///
+ /// \return
+ /// A byte reader containing the rendered tile image.
+ ///
+ virtual MgByteReader* GetTile(
+ MgResourceIdentifier* mapDefinition,
+ CREFSTRING baseMapLayerGroupName,
+ INT32 tileColumn,
+ INT32 tileRow,
+ INT32 scaleIndex);
+
//////////////////////////////////////////////////////////////////
/// \brief
/// Clears the entire tile cache for the given map. Tiles for all base
Modified: trunk/MgDev/Common/MapGuideCommon/Services/Site.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/Site.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/MapGuideCommon/Services/Site.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -85,10 +85,23 @@
{
MG_SITE_TRY()
+ Open(userInformation, false);
+
+ MG_SITE_CATCH_AND_THROW(L"MgSite.Open")
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// <summary>
+/// Opens a connection to a Site Server.
+/// </summary>
+
+void MgSite::Open(MgUserInformation* userInformation, bool skipAuthenticate)
+{
+ MG_SITE_TRY()
+
// Authenticate the user.
+ Authenticate(userInformation, NULL, NULL, false, skipAuthenticate);
- Authenticate(userInformation, NULL, NULL, false);
-
MG_SITE_CATCH_AND_THROW(L"MgSite.Open")
}
@@ -103,7 +116,7 @@
// Authenticate the user.
- Authenticate(userInformation, siteInfo, NULL, false);
+ Authenticate(userInformation, siteInfo, NULL, false, false);
MG_SITE_CATCH_AND_THROW(L"MgSite.Open")
}
@@ -1214,9 +1227,11 @@
}
MgStringCollection* MgSite::Authenticate(MgUserInformation* userInformation,
- MgSiteInfo* siteInfo, MgStringCollection* requiredRoles, bool returnAssignedRoles)
+ MgSiteInfo* siteInfo, MgStringCollection* requiredRoles,
+ bool returnAssignedRoles, bool skipAuthenticate)
{
MgCommand cmd;
+ Ptr<MgStringCollection> retval = NULL;
MG_SITE_TRY()
@@ -1236,24 +1251,28 @@
{
m_connProp = siteManager->GetConnectionProperties(userInformation,
MgSiteInfo::Site, true);
- }
+ }
- cmd.ExecuteCommand(m_connProp, // Connection
- MgCommand::knObject, // Return type
- MgSiteOpId::Authenticate, // Command code
- 3, // Number of arguments
- Site_Admin, // Service ID
- 1, // Operation version
- MgCommand::knObject, userInformation, // Argument #1
- MgCommand::knObject, requiredRoles, // Argument #2
- MgCommand::knInt8, (int)returnAssignedRoles, // Argument #3
- MgCommand::knNone);
+ if (!skipAuthenticate)
+ {
+ cmd.ExecuteCommand(m_connProp, // Connection
+ MgCommand::knObject, // Return type
+ MgSiteOpId::Authenticate, // Command code
+ 3, // Number of arguments
+ Site_Admin, // Service ID
+ 1, // Operation version
+ MgCommand::knObject, userInformation, // Argument #1
+ MgCommand::knObject, requiredRoles, // Argument #2
+ MgCommand::knInt8, (int)returnAssignedRoles, // Argument #3
+ MgCommand::knNone);
- SetWarning(cmd.GetWarningObject());
+ SetWarning(cmd.GetWarningObject());
+ retval = (MgStringCollection*) cmd.GetReturnValue().val.m_obj;
+ }
MG_SITE_CATCH_AND_THROW(L"MgSite.Authenticate")
- return (MgStringCollection*)cmd.GetReturnValue().val.m_obj;
+ return retval.Detach();
}
void MgSite::SetWarning(MgWarnings* warning)
Modified: trunk/MgDev/Common/MapGuideCommon/Services/Site.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/Site.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/MapGuideCommon/Services/Site.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -808,8 +808,29 @@
///
MgStringCollection* Authenticate(MgUserInformation* userInformation,
MgSiteInfo* siteInfo,
- MgStringCollection* requiredRoles, bool returnAssignedRoles);
+ MgStringCollection* requiredRoles,
+ bool returnAssignedRoles,
+ bool skipAuthenticate = false);
+ ///////////////////////////////////////////////////////////////////////////////////
+ /// \brief
+ /// Opens a connection to the Site Server.
+ ///
+ /// \param userInformation
+ /// User information to authenticate against
+ ///
+ /// \param skipAuthenticate
+ /// Skip authentication. Used for internal performance speedups.
+ ///
+ /// \return
+ /// Nothing
+ ///
+ /// \exception MgNullArgumentException
+ /// \exception MgAuthenticationFailedException
+ /// \exception MgConnectionFailedException
+ ///
+ void Open(MgUserInformation* userInformation, bool skipAuthenticate);
+
protected:
//////////////////////////////////////////////
Modified: trunk/MgDev/Common/MapGuideCommon/Services/SiteConnection.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/SiteConnection.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/MapGuideCommon/Services/SiteConnection.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -499,7 +499,7 @@
assert(NULL != userInformation.p);
Ptr<MgSite> site = new MgSite();
- site->Open(userInformation);
+ site->Open(userInformation, true);
STRING target = site->RequestServer(serviceType);
Modified: trunk/MgDev/Common/MapGuideCommon/Services/TileService.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/TileService.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/MapGuideCommon/Services/TileService.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -59,6 +59,38 @@
INT32 tileColumn,
INT32 tileRow) = 0;
+ /////////////////////////////////////////////////////////////////
+ /// \brief
+ /// Returns the specified base map tile for the given map. If a cached tile
+ /// image exists it will return it, otherwise the tile is rendered and added
+ /// to the cache.
+ ///
+ /// \param mapDefinition
+ /// Input
+ /// Resource identifier for the map definition
+ /// \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 scaleIndex
+ /// Input
+ /// Scale index to render. Most detailed scale is index 0.
+ ///
+ /// \return
+ /// A byte reader containing the rendered tile image.
+ ///
+ virtual MgByteReader* GetTile(
+ MgResourceIdentifier* mapDefinition,
+ CREFSTRING baseMapLayerGroupName,
+ INT32 tileColumn,
+ INT32 tileRow,
+ INT32 scaleIndex) = 0;
+
//////////////////////////////////////////////////////////////////
/// \brief
/// Clears the entire tile cache for the given map. Tiles for all base
Modified: trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -308,6 +308,10 @@
const STRING MgConfigProperties::TileServicePropertiesSection = L"TileServiceProperties";
const STRING MgConfigProperties::TileServicePropertyTileCachePath = L"TileCachePath";
const STRING MgConfigProperties::DefaultTileServicePropertyTileCachePath = L"Repositories/TileCache/";
+const STRING MgConfigProperties::TileServicePropertyTiledMapCacheSize = L"TiledMapCacheSize";
+const INT32 MgConfigProperties::DefaultTileServicePropertyTiledMapCacheSize = 10;
+const STRING MgConfigProperties::TileServicePropertyRenderOnly = L"RenderOnly";
+const bool MgConfigProperties::DefaultTileServicePropertyRenderOnly = false;
// ******************************************************************
// Access Log Properties
@@ -537,6 +541,8 @@
const MgConfigValidationInfo MgConfigProperties::sm_cviTileServiceProperties[] =
{
{ MgConfigProperties::TileServicePropertyTileCachePath , MgPropertyType::String , MG_CONFIG_MIN_PATH_LENGTH , MG_CONFIG_MAX_PATH_LENGTH , MG_CONFIG_PATH_RESERVED_CHARACTERS },
+ { MgConfigProperties::TileServicePropertyTiledMapCacheSize , MgPropertyType::Int32 , MG_CONFIG_MIN_CACHE_SIZE , MG_CONFIG_MAX_CACHE_SIZE , L"" },
+ { MgConfigProperties::TileServicePropertyRenderOnly , MgPropertyType::Boolean , 0 , 1 , L"" },
{ L"" , 0 , 0.0 , 0.0 , L"" }
};
Modified: trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -396,6 +396,13 @@
static const STRING TileServicePropertyTileCachePath; /// value("TileCachePath")
static const STRING DefaultTileServicePropertyTileCachePath; /// value("Repositories/TileCache/")
+ /// Sets the limit on the number of cached MgMap objects used for tile generation
+ static const STRING TileServicePropertyTiledMapCacheSize; /// value("TiledMapCacheSize")
+ static const INT32 DefaultTileServicePropertyTiledMapCacheSize; /// value(10)
+ static const STRING TileServicePropertyRenderOnly; /// value("RenderOnly")
+ static const bool DefaultTileServicePropertyRenderOnly; /// value(true)
+
+
//////////////////////////////////////////////////////////////////
/// \brief
/// The remaining properties are log properties. For each type of log, there is a "Parameters" property.
Modified: trunk/MgDev/Common/MapGuideCommon/System/UserInformation.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/System/UserInformation.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/MapGuideCommon/System/UserInformation.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -343,9 +343,19 @@
if (!m_username.empty() || !m_password.empty())
{
+ //TODO: Add a general configuration parameter for user info encryption
+ if (1)
+ {
MgCryptographyManager cryptoManager;
credentials = cryptoManager.EncryptCredentials(m_username, m_password);
+ }
+ else
+ {
+ credentials = m_username;
+ credentials.append(L"\t");
+ credentials.append(m_password);
+ }
}
Ptr<MgStreamHelper> helper = stream->GetStreamHelper();
@@ -385,6 +395,9 @@
}
else
{
+ //TODO: Add a general configuration parameter for user info encryption
+ if (1)
+ {
MG_CRYPTOGRAPHY_TRY()
MgCryptographyUtil cryptoUtil;
@@ -397,5 +410,12 @@
MgUtil::MultiByteToWideChar(password, m_password);
MG_CRYPTOGRAPHY_CATCH_AND_THROW(L"MgUserInformation.Deserialize")
+ }
+ else
+ {
+ STRING::size_type sep = credentials.find(L"\t");
+ m_username = credentials.substr(0, sep);
+ m_password = credentials.substr(sep+1);
+ }
}
}
Modified: trunk/MgDev/Common/PlatformBase/Services/ResourceService.cpp
===================================================================
--- trunk/MgDev/Common/PlatformBase/Services/ResourceService.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/PlatformBase/Services/ResourceService.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -192,7 +192,12 @@
throw new MgNotImplementedException(L"MgResourceService.ResourceExists", __LINE__, __WFILE__, NULL, L"", NULL);
}
+bool MgResourceService::HasPermission(MgResourceIdentifier* resource, CREFSTRING permission)
+{
+ throw new MgNotImplementedException(L"MgResourceService.HasPermission", __LINE__, __WFILE__, NULL, L"", NULL);
+}
+
//////////////////////////////////////////////////////////////////
/// \brief
/// Enumerates the unmanaged data
Modified: trunk/MgDev/Common/PlatformBase/Services/ResourceService.h
===================================================================
--- trunk/MgDev/Common/PlatformBase/Services/ResourceService.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/PlatformBase/Services/ResourceService.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -1721,6 +1721,20 @@
INTERNAL_API:
//////////////////////////////////////////////////////////////////
+ /// \brief
+ /// Returns if permission has been granted for a resource
+ /// permission named data for the specified resource.
+ ///
+ /// \param resource
+ /// Resource identifier describing the resource.
+ /// \param permission
+ /// Requested permission for the resource. See MgResourcePermission.
+ ///
+ /// \return
+ /// True if user has requested permission.
+ virtual bool HasPermission(MgResourceIdentifier* resource, CREFSTRING permission);
+
+ //////////////////////////////////////////////////////////////////
/// Enumerations
enum OperationId
{
Modified: trunk/MgDev/Common/PlatformBase/Services/ServiceRegistry.cpp
===================================================================
--- trunk/MgDev/Common/PlatformBase/Services/ServiceRegistry.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/PlatformBase/Services/ServiceRegistry.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -65,7 +65,7 @@
MgService* MgServiceRegistry::CreateService(INT16 serviceType, ServerConnectionType connType)
{
- ServiceRegistry registry = m_serviceCreators[connType];
+ ServiceRegistry& registry = m_serviceCreators[connType];
const ServiceCreatorFunc& func = registry[serviceType];
if (NULL == func)
{
@@ -177,3 +177,4 @@
return true;
}
+
Modified: trunk/MgDev/Common/Stylization/GDRenderer.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/GDRenderer.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/Stylization/GDRenderer.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -60,6 +60,7 @@
#include "RSDWFInputStream.h"
#include "LabelRenderer.h"
#include "LabelRendererLocal.h"
+#include "complex_polygon_gd.h"
#include "SymbolTrans.h"
@@ -159,6 +160,8 @@
m_labeler = new LabelRenderer(this);
else
m_labeler = new LabelRendererLocal(this, tileExtentOffset);
+
+ m_polyrasterizer = new complex_polygon_gd();
}
@@ -173,6 +176,8 @@
delete [] m_wtPointBuffer;
delete m_labeler;
+
+ delete m_polyrasterizer;
}
@@ -430,18 +435,9 @@
gdImageSetTile((gdImagePtr)m_imout, fillpat);
}
- //just a polygon, no need for a contourset
- if (workbuffer->cntr_count() == 1)
- {
- gdImageFilledPolygon((gdImagePtr)m_imout, (gdPoint*)m_wtPointBuffer, workbuffer->point_count(), (fillpat)? gdTiled : gdc);
- }
- else //otherwise make a contour set
- {
- rs_gdImageMultiPolygon((gdImagePtr)m_imout,
- workbuffer->cntrs(), workbuffer->cntr_count(),
- (gdPoint*)m_wtPointBuffer, workbuffer->point_count(),
- (fillpat) ? gdTiled : gdc);
- }
+ //call the new rasterizer
+ m_polyrasterizer->FillPolygon((Point*)m_wtPointBuffer, workbuffer->point_count(), workbuffer->cntrs(), workbuffer->cntr_count(),
+ (fillpat) ? gdTiled : gdc, (gdImagePtr)m_imout);
if (fillpat)
{
Modified: trunk/MgDev/Common/Stylization/GDRenderer.h
===================================================================
--- trunk/MgDev/Common/Stylization/GDRenderer.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/Stylization/GDRenderer.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -39,6 +39,8 @@
struct RS_Font;
+class complex_polygon_gd;
+
class GDRenderer : public Renderer
{
friend class LabelRenderer;
@@ -269,6 +271,9 @@
//remember id of last symbol
RS_MarkerDef m_lastSymbol;
+
+ //polygon rasterizer
+ complex_polygon_gd* m_polyrasterizer;
};
#endif
Modified: trunk/MgDev/Common/Stylization/LabelRendererLocal.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/LabelRendererLocal.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/Stylization/LabelRendererLocal.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -220,17 +220,42 @@
double yoffset = (1.0 - ((int)(1.0/yinc))*yinc) * 0.5;
double xoffset = (1.0 - ((int)(1.0/xinc))*xinc) * 0.5;
+ //parametric clip coordinates used to determine a subset of the
+ //polygon's bounding box which we will attempt to cover with
+ //periodic labels
+ double invheight = 1.0 / b.height();
+ double tilestarty = (rejectBounds.miny - b.miny) * invheight;
+ tilestarty = rs_max(0.0, tilestarty);
+ double tileendy = (rejectBounds.maxy - b.miny) * invheight;
+ tileendy = rs_min(1.0, tileendy);
+
+ double invwidth = 1.0 / b.width();
+ double tilestartx = (rejectBounds.minx - b.minx) * invwidth;
+ tilestartx = rs_max(0.0, tilestartx);
+ double tileendx = (rejectBounds.maxx - b.minx) * invwidth;
+ tileendx = rs_min(1.0, tileendx);
+
+
double ypos = yoffset;
+
+ //move ypos up until we reach a relevant position that is likely to
+ //draw a label that intersects the tile
+ if (tilestarty != 0.0)
+ ypos += ceil((tilestarty - ypos) / yinc) * yinc;
+
bool offset = false;
- //TODO: we should be smarter about the start and end parametric positions
- //instead of looping from around 0 to around 1. If we are far zoomed in
- //on a polygon, those loops can take quite some time to execute
- while (ypos <= 1.0)
+ //loop to add labels
+ while (ypos <= tileendy)
{
double xpos = xoffset + ((offset) ? 0.5 * xinc : 0.0);
- while (xpos <= 1.0)
+ //move to the right until we reach a relevant position that is likely to
+ //draw a label that intersects the tile
+ if (tilestartx != 0.0)
+ xpos += ceil((tilestartx - xpos) / xinc) * xinc;
+
+ while (xpos <= tileendx)
{
//compute mapping space position for label, based on
double posx = b.minx + xpos * b.width();
@@ -238,9 +263,7 @@
//rejection of labels that are far outside the current tile
//and also make sure the point we genrated is inside the polygon
- if (posx <= rejectBounds.maxx && posx >= rejectBounds.minx
- && posy <= rejectBounds.maxy && posy >= rejectBounds.miny
- && Centroid::PointInPolygon(path->points(), 2 * path->point_count(),
+ if (Centroid::PointInPolygon(path->points(), 2 * path->point_count(),
path->cntrs(), path->cntr_count(), posx, posy ))
{
RS_LabelInfo* info = &labels[0]; //assumes one label info passed in
Modified: trunk/MgDev/Common/Stylization/Makefile.am
===================================================================
--- trunk/MgDev/Common/Stylization/Makefile.am 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/Stylization/Makefile.am 2007-01-20 00:49:25 UTC (rev 1064)
@@ -53,7 +53,8 @@
LabelRendererLocal.cpp \
SimpleOverpost.cpp \
RS_ByteData.cpp \
- FontManager.cpp
+ FontManager.cpp \
+ complex_polygon_gd.cpp
noinst_HEADERS = \
@@ -120,7 +121,8 @@
RS_Font.h \
FontManager.h \
SymbolVisitor.h \
- SLDSymbols.h
+ SLDSymbols.h \
+ complex_polygon_gd.h
AM_CXXFLAGS = @CXXFLAGS@ -DDWFTK_BUILD_EXPAT
Modified: trunk/MgDev/Common/Stylization/Stylization.vcproj
===================================================================
--- trunk/MgDev/Common/Stylization/Stylization.vcproj 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/Stylization/Stylization.vcproj 2007-01-20 00:49:25 UTC (rev 1064)
@@ -41,7 +41,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\Oem\DWFTK7.1\develop\global\src;..\..\Oem\DWFTK7.1\develop\global\src\dwf;..\..\Oem\DWFTK7.1\develop\global\src\dwfemap;..\..\Oem\FDO\inc;..\..\Oem\gd\gd;..\MdfModel;..\..\Oem\gd\freetype\include"
+ AdditionalIncludeDirectories="..\..\Oem\DWFTK7.1\develop\global\src;..\..\Oem\DWFTK7.1\develop\global\src\dwf;..\..\Oem\DWFTK7.1\develop\global\src\dwfemap;..\..\Oem\FDO\inc;..\..\Oem\gd\gd;..\MdfModel;..\..\Oem\gd\freetype\include;..\..\Oem\gd\lpng;..\..\Oem\gd\zlib"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;STYLIZATION_EXPORTS;DWFTK_USE_DWFCORE_ZLIB;DWFTK_BUILD_EXPAT;DWFCORE_STATIC;DWFTK_STATIC;WHIP_STATIC_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
MinimalRebuild="true"
ExceptionHandling="2"
@@ -62,10 +62,10 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="FdoCommon.lib Fdo.lib dwfcore_wt.1.1.1.lib dwftk_wt.7.1.1.lib whiptk_wt.7.7.601.lib emaptk_wt.1.0.0.lib MgMdfModeld.lib gd.lib freetype2110_D.lib"
+ AdditionalDependencies="FdoCommon.lib Fdo.lib dwfcore_wt.1.1.1.lib dwftk_wt.7.1.1.lib whiptk_wt.7.7.601.lib emaptk_wt.1.0.0.lib MgMdfModeld.lib gd.lib freetype2110_D.lib user32.lib gdi32.lib shell32.lib libpngd.lib"
OutputFile="$(OutDir)/MgStylizationd.dll"
LinkIncremental="2"
- AdditionalLibraryDirectories="..\..\Oem\DWFTK7.1\develop\global\lib\static\debug\vc8.0;..\..\Oem\FDO\lib;..\..\Oem\gd\build\win32\gd\Debug;..\..\Common\lib\debug;..\..\Oem\gd\freetype\objs"
+ AdditionalLibraryDirectories="..\..\Oem\DWFTK7.1\develop\global\lib\static\debug\vc8.0;..\..\Oem\FDO\lib;..\..\Oem\gd\build\win32\gd\Debug;..\..\Common\lib\debug;..\..\Oem\gd\freetype\objs;..\..\Oem\gd\lpng\projects\visualc8\Win32_LIB_ASM_Debug"
IgnoreDefaultLibraryNames="libcmtd.lib"
DelayLoadDLLs="Fdo.dll;FdoCommon.dll"
GenerateDebugInformation="true"
@@ -129,7 +129,7 @@
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
- AdditionalIncludeDirectories="..\..\Oem\DWFTK7.1\develop\global\src;..\..\Oem\DWFTK7.1\develop\global\src\dwf;..\..\Oem\DWFTK7.1\develop\global\src\dwfemap;..\..\Oem\FDO\inc;..\..\Oem\gd\gd;..\MdfModel;..\..\Oem\gd\freetype\include"
+ AdditionalIncludeDirectories="..\..\Oem\DWFTK7.1\develop\global\src;..\..\Oem\DWFTK7.1\develop\global\src\dwf;..\..\Oem\DWFTK7.1\develop\global\src\dwfemap;..\..\Oem\FDO\inc;..\..\Oem\gd\gd;..\MdfModel;..\..\Oem\gd\freetype\include;..\..\Oem\gd\lpng;..\..\Oem\gd\zlib"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;STYLIZATION_EXPORTS;DWFTK_USE_DWFCORE_ZLIB;DWFTK_BUILD_EXPAT;DWFCORE_STATIC;DWFTK_STATIC;WHIP_STATIC_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
ExceptionHandling="2"
RuntimeLibrary="2"
@@ -148,10 +148,10 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="FdoCommon.lib Fdo.lib dwfcore_wt.1.1.1.lib dwftk_wt.7.1.1.lib whiptk_wt.7.7.601.lib emaptk_wt.1.0.0.lib MgMdfModel.lib gd.lib freetype2110.lib"
+ AdditionalDependencies="FdoCommon.lib Fdo.lib dwfcore_wt.1.1.1.lib dwftk_wt.7.1.1.lib whiptk_wt.7.7.601.lib emaptk_wt.1.0.0.lib MgMdfModel.lib gd.lib freetype2110.lib shell32.lib user32.lib libpng.lib"
OutputFile="$(OutDir)/MgStylization.dll"
LinkIncremental="1"
- AdditionalLibraryDirectories="..\..\Oem\DWFTK7.1\develop\global\lib\static\release\vc8.0;..\..\Oem\FDO\lib;..\..\Oem\gd\build\win32\gd\Release;..\..\Common\lib\Release;..\..\Oem\gd\freetype\objs"
+ AdditionalLibraryDirectories="..\..\Oem\DWFTK7.1\develop\global\lib\static\release\vc8.0;..\..\Oem\FDO\lib;..\..\Oem\gd\build\win32\gd\Release;..\..\Common\lib\Release;..\..\Oem\gd\freetype\objs;..\..\Oem\gd\lpng\projects\visualc8\Win32_LIB_ASM_Release"
IgnoreDefaultLibraryNames="libcmt.lib"
DelayLoadDLLs="Fdo.dll;FdoCommon.dll"
GenerateDebugInformation="true"
@@ -359,6 +359,32 @@
Name="GDRenderer"
>
<File
+ RelativePath=".\complex_polygon_gd.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\complex_polygon_gd.h"
+ >
+ </File>
+ <File
RelativePath=".\FontManager.cpp"
>
</File>
Added: trunk/MgDev/Common/Stylization/complex_polygon_gd.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/complex_polygon_gd.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/Stylization/complex_polygon_gd.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -0,0 +1,355 @@
+
+/* Traian 1/2/2007
+ Polygon fill routines taken from the Graphics Programming Black Book by M. Abrash.
+
+ I (heavily) modified the code as follows:
+ * add support for polygons with multiple contours,
+ * do polygon clipping if parts of the polygon are outside of
+ the screen,
+ * Reduce number of memory allocations by reusing the same
+ buffer for egde lists
+ * function no longer returns an int
+
+ Original code description follows below.
+*/
+
+/* Color-fills an arbitrarily-shaped polygon described by VertexList.
+If the first and last points in VertexList are not the same, the path
+around the polygon is automatically closed. All vertices are offset
+by (XOffset, YOffset). Returns 1 for success, 0 if memory allocation
+failed.
+If the polygon shape is known in advance, speedier processing may be
+enabled by specifying the shape as follows: "convex" - a rubber band
+stretched around the polygon would touch every vertex in order;
+"nonconvex" - the polygon is not self-intersecting, but need not be
+convex; "complex" - the polygon may be self-intersecting, or, indeed,
+any sort of polygon at all. Complex will work for all polygons; convex
+is fastest. Undefined results will occur if convex is specified for a
+nonconvex or complex polygon.
+Define CONVEX_CODE_LINKED if the fast convex polygon filling code from
+Chapter 21 is linked in. Otherwise, convex polygons are
+handled by the complex polygon filling code.
+Nonconvex is handled as complex in this implementation. See text for a
+discussion of faster nonconvex handling
+
+Link with L23-4.C and L23-2.C in Small model.
+Tested with Borland C++ 4.02 by Jim Mischel 12/16/94.
+*/
+
+#include "stdafx.h"
+#include <stdio.h>
+#include <math.h>
+#include <malloc.h>
+#include "complex_polygon_gd.h"
+
+/* Describes a single point (used for a single vertex) */
+struct Point {
+ int X; /* X coordinate */
+ int Y; /* Y coordinate */
+};
+
+/* Describes the beginning and ending X coordinates of a single
+ horizontal line (used only by fast polygon fill code) */
+struct HLine {
+ int XStart; /* X coordinate of leftmost pixel in line */
+ int XEnd; /* X coordinate of rightmost pixel in line */
+};
+/* Describes a Length-long series of horizontal lines, all assumed to
+ be on contiguous scan lines starting at YStart and proceeding
+ downward (used to describe a scan-converted polygon to the
+ low-level hardware-dependent drawing code) (used only by fast
+ polygon fill code) */
+struct HLineList {
+ int Length; /* # of horizontal lines */
+ int YStart; /* Y coordinate of topmost line */
+ struct HLine * HLinePtr; /* pointer to list of horz lines */
+};
+
+#define SWAP(a,b) {temp = a; a = b; b = temp;}
+
+struct EdgeState {
+ struct EdgeState *NextEdge;
+ int X;
+ int StartY;
+ int WholePixelXMove;
+ int XDirection;
+ int ErrorTerm;
+ int ErrorTermAdjUp;
+ int ErrorTermAdjDown;
+ int Count;
+};
+
+complex_polygon_gd::complex_polygon_gd()
+{
+ m_bufEdgeState = NULL;
+ m_nBufEdgeState = 0;
+}
+complex_polygon_gd::~complex_polygon_gd()
+{
+ delete [] m_bufEdgeState;
+}
+
+
+void complex_polygon_gd::FillPolygon(Point * VertexList, int nVerts, int* Contours, int nContours, int Color, gdImagePtr target)
+{
+ struct EdgeState *EdgeTableBuffer;
+ int CurrentY;
+
+ /* It takes a minimum of 3 vertices to cause any pixels to be
+ drawn; reject polygons that are guaranteed to be invisible */
+ if (nVerts < 3)
+ return;
+
+ /* Get enough memory to store the entire edge table */
+ /* TIS -- reuse a buffer owned by the class */
+ if (m_nBufEdgeState < nVerts)
+ {
+ delete [] m_bufEdgeState;
+ m_nBufEdgeState = nVerts;
+ m_bufEdgeState = new EdgeState[m_nBufEdgeState];
+ }
+
+ EdgeTableBuffer = m_bufEdgeState;
+
+ /* Build the global edge table */
+ BuildGET(VertexList, Contours, nContours, EdgeTableBuffer, target->sy - 1);
+
+ if (m_GETPtr) /* true if polygon was not completely clipped out */
+ {
+ /* Scan down through the polygon edges, one scan line at a time,
+ so long as at least one edge remains in either the GET or AET */
+ m_AETPtr = NULL; /* initialize the active edge table to empty */
+ CurrentY = m_GETPtr->StartY; /* start at the top polygon vertex */
+ while (((m_GETPtr != NULL) || (m_AETPtr != NULL))
+ && CurrentY != target->sy)
+ {
+ MoveXSortedToAET(CurrentY); /* update AET for this scan line */
+ ScanOutAET(CurrentY, Color, target); /* draw this scan line from AET */
+ AdvanceAET(); /* advance AET edges 1 scan line */
+ XSortAET(); /* resort on X */
+ CurrentY++; /* advance to the next scan line */
+ }
+ }
+}
+
+/* Creates a GET in the buffer pointed to by NextFreeEdgeStruc from
+the vertex list. Edge endpoints are flipped, if necessary, to
+guarantee all edges go top to bottom. The GET is sorted primarily
+by ascending Y start coordinate, and secondarily by ascending X
+start coordinate within edges with common Y coordinates */
+void complex_polygon_gd::BuildGET(struct Point * VertexList,
+int* Contours, int nContours, struct EdgeState * NextFreeEdgeStruc, int MaxY)
+{
+ int i, StartX, StartY, EndX, EndY, DeltaY, DeltaX, Width, temp, SkipY;
+ struct EdgeState *NewEdgePtr;
+ struct EdgeState *FollowingEdge, **FollowingEdgeLink;
+ struct Point *VertexPtr;
+
+ /* Scan through the vertex list and put all non-0-height edges into
+ the GET, sorted by increasing Y start coordinate */
+ VertexPtr = VertexList; /* point to the vertex list */
+ m_GETPtr = NULL; /* initialize the global edge table to empty */
+
+ int offset = 0;
+ for (int j=0; j<nContours; j++)
+ {
+ for (i = 0; i < Contours[j]; i++) {
+ /* Calculate the edge height and width */
+ StartX = VertexPtr[offset + i].X;
+ StartY = VertexPtr[offset + i].Y;
+ /* The edge runs from the current point to the previous one */
+ if (i == 0) {
+ /* Wrap back around to the end of the list */
+ EndX = VertexPtr[offset + Contours[j]-1].X;
+ EndY = VertexPtr[offset + Contours[j]-1].Y;
+ } else {
+ EndX = VertexPtr[offset + i-1].X;
+ EndY = VertexPtr[offset + i-1].Y;
+ }
+ /* Make sure the edge runs top to bottom */
+ if (StartY > EndY) {
+ SWAP(StartX, EndX);
+ SWAP(StartY, EndY);
+ }
+ /* Skip if this can't ever be an active edge (has 0 height)
+ or if the edge doesn't cross the vertical screen
+ bounds at all */
+
+ if ((DeltaY = EndY - StartY) != 0
+ && (EndY > 0) && (StartY <= MaxY)) {
+ /* Allocate space for this edge's info, and fill in the
+ structure */
+ NewEdgePtr = NextFreeEdgeStruc++;
+ NewEdgePtr->XDirection = /* direction in which X moves */
+ ((DeltaX = EndX - StartX) > 0) ? 1 : -1;
+ Width = abs(DeltaX);
+ NewEdgePtr->X = StartX;
+
+ /* clip stuff that's before beginning of screen
+ We can't just change StartY -- we also need to
+ update the initial conditions for the edge
+ rasterizer
+ */
+
+ /* find how many rows we have to skip */
+ SkipY = (StartY >=0) ? 0 : -StartY;
+ StartY += SkipY;
+ NewEdgePtr->StartY = StartY;
+ NewEdgePtr->Count = DeltaY - SkipY;
+ NewEdgePtr->ErrorTermAdjDown = DeltaY;
+
+ /* set initial rasterization conditions */
+ if (DeltaX >= 0) /* initial error term going L->R */
+ NewEdgePtr->ErrorTerm = 0;
+ else /* initial error term going R->L */
+ NewEdgePtr->ErrorTerm = -DeltaY + 1;
+ if (DeltaY >= Width) { /* Y-major edge */
+ NewEdgePtr->WholePixelXMove = 0;
+ NewEdgePtr->ErrorTermAdjUp = Width;
+ } else { /* X-major edge */
+ NewEdgePtr->WholePixelXMove =
+ (Width / DeltaY) * NewEdgePtr->XDirection;
+ NewEdgePtr->ErrorTermAdjUp = Width % DeltaY;
+ }
+
+ /* update initial conditions only if we have to*/
+ if (SkipY != 0) {
+ int XMove = (SkipY + 1) * NewEdgePtr->WholePixelXMove;
+ int ErrorMove = NewEdgePtr->ErrorTerm + (SkipY + 1) * NewEdgePtr->ErrorTermAdjUp;
+ int ErrorDiv = ErrorMove / NewEdgePtr->ErrorTermAdjDown;
+ int ErrorMod = ErrorMove % NewEdgePtr->ErrorTermAdjDown;
+
+ NewEdgePtr->X += XMove + ErrorDiv * NewEdgePtr->XDirection;
+ StartX = NewEdgePtr->X;
+ NewEdgePtr->ErrorTerm = ErrorMod - NewEdgePtr->ErrorTermAdjDown;
+ }
+
+ /* Link the new edge into the GET so that the edge list is
+ still sorted by Y coordinate, and by X coordinate for all
+ edges with the same Y coordinate */
+ FollowingEdgeLink = &m_GETPtr;
+ for (;;) {
+ FollowingEdge = *FollowingEdgeLink;
+ if ((FollowingEdge == NULL) ||
+ (FollowingEdge->StartY > StartY) ||
+ ((FollowingEdge->StartY == StartY) &&
+ (FollowingEdge->X >= StartX))) {
+ NewEdgePtr->NextEdge = FollowingEdge;
+ *FollowingEdgeLink = NewEdgePtr;
+ break;
+ }
+ FollowingEdgeLink = &FollowingEdge->NextEdge;
+ }
+ }
+ }
+
+ offset += Contours[j];
+ }
+}
+
+/* Sorts all edges currently in the active edge table into ascending
+order of current X coordinates */
+void complex_polygon_gd::XSortAET() {
+ struct EdgeState *CurrentEdge, **CurrentEdgePtr, *TempEdge;
+ int SwapOccurred;
+
+ /* Scan through the AET and swap any adjacent edges for which the
+ second edge is at a lower current X coord than the first edge.
+ Repeat until no further swapping is needed */
+ if (m_AETPtr != NULL) {
+ do {
+ SwapOccurred = 0;
+ CurrentEdgePtr = &m_AETPtr;
+ while ((CurrentEdge = *CurrentEdgePtr)->NextEdge != NULL) {
+ if (CurrentEdge->X > CurrentEdge->NextEdge->X) {
+ /* The second edge has a lower X than the first;
+ swap them in the AET */
+ TempEdge = CurrentEdge->NextEdge->NextEdge;
+ *CurrentEdgePtr = CurrentEdge->NextEdge;
+ CurrentEdge->NextEdge->NextEdge = CurrentEdge;
+ CurrentEdge->NextEdge = TempEdge;
+ SwapOccurred = 1;
+ }
+ CurrentEdgePtr = &(*CurrentEdgePtr)->NextEdge;
+ }
+ } while (SwapOccurred != 0);
+ }
+}
+
+/* Advances each edge in the AET by one scan line.
+Removes edges that have been fully scanned. */
+void complex_polygon_gd::AdvanceAET() {
+ struct EdgeState *CurrentEdge, **CurrentEdgePtr;
+
+ /* Count down and remove or advance each edge in the AET */
+ CurrentEdgePtr = &m_AETPtr;
+ while ((CurrentEdge = *CurrentEdgePtr) != NULL) {
+ /* Count off one scan line for this edge */
+ if ((--(CurrentEdge->Count)) == 0) {
+ /* This edge is finished, so remove it from the AET */
+ *CurrentEdgePtr = CurrentEdge->NextEdge;
+ } else {
+ /* Advance the edge's X coordinate by minimum move */
+ CurrentEdge->X += CurrentEdge->WholePixelXMove;
+ /* Determine whether it's time for X to advance one extra */
+ if ((CurrentEdge->ErrorTerm +=
+ CurrentEdge->ErrorTermAdjUp) > 0) {
+ CurrentEdge->X += CurrentEdge->XDirection;
+ CurrentEdge->ErrorTerm -= CurrentEdge->ErrorTermAdjDown;
+ }
+ CurrentEdgePtr = &CurrentEdge->NextEdge;
+ }
+ }
+}
+
+/* Moves all edges that start at the specified Y coordinate from the
+GET to the AET, maintaining the X sorting of the AET. */
+void complex_polygon_gd::MoveXSortedToAET(int YToMove) {
+ struct EdgeState *AETEdge, **AETEdgePtr, *TempEdge;
+ int CurrentX;
+
+ /* The GET is Y sorted. Any edges that start at the desired Y
+ coordinate will be first in the GET, so we'll move edges from
+ the GET to AET until the first edge left in the GET is no longer
+ at the desired Y coordinate. Also, the GET is X sorted within
+ each Y coordinate, so each successive edge we add to the AET is
+ guaranteed to belong later in the AET than the one just added */
+ AETEdgePtr = &m_AETPtr;
+ while ((m_GETPtr != NULL) && (m_GETPtr->StartY == YToMove)) {
+ CurrentX = m_GETPtr->X;
+ /* Link the new edge into the AET so that the AET is still
+ sorted by X coordinate */
+ for (;;) {
+ AETEdge = *AETEdgePtr;
+ if ((AETEdge == NULL) || (AETEdge->X >= CurrentX)) {
+ TempEdge = m_GETPtr->NextEdge;
+ *AETEdgePtr = m_GETPtr; /* link the edge into the AET */
+ m_GETPtr->NextEdge = AETEdge;
+ AETEdgePtr = &m_GETPtr->NextEdge;
+ m_GETPtr = TempEdge; /* unlink the edge from the GET */
+ break;
+ } else {
+ AETEdgePtr = &AETEdge->NextEdge;
+ }
+ }
+ }
+}
+
+/* Fills the scan line described by the current AET at the specified Y
+coordinate in the specified color, using the odd/even fill rule */
+void complex_polygon_gd::ScanOutAET(int YToScan, int Color, gdImagePtr target) {
+ int LeftX;
+ struct EdgeState *CurrentEdge;
+
+ /* Scan through the AET, drawing line segments as each pair of edge
+ crossings is encountered. The nearest pixel on or to the right
+ of left edges is drawn, and the nearest pixel to the left of but
+ not on right edges is drawn */
+ CurrentEdge = m_AETPtr;
+ while (CurrentEdge != NULL) {
+ LeftX = CurrentEdge->X;
+ CurrentEdge = CurrentEdge->NextEdge;
+ DrawHorizontalLineSeg(YToScan, LeftX, CurrentEdge->X-1, Color, target);
+ CurrentEdge = CurrentEdge->NextEdge;
+ }
+}
Property changes on: trunk/MgDev/Common/Stylization/complex_polygon_gd.cpp
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/MgDev/Common/Stylization/complex_polygon_gd.h
===================================================================
--- trunk/MgDev/Common/Stylization/complex_polygon_gd.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Common/Stylization/complex_polygon_gd.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -0,0 +1,40 @@
+
+#ifndef complex_polygon_gd_H
+#define complex_polygon_gd_H
+
+#include "gd.h"
+
+struct EdgeState;
+struct Point;
+
+class complex_polygon_gd
+{
+public:
+ complex_polygon_gd();
+ ~complex_polygon_gd();
+
+ void FillPolygon(Point * VertexList, int nVerts, int* Contours, int nContours, int Color, gdImagePtr target);
+
+private:
+
+ //This is what you want to implement for your own render target
+ //for all the rest of the code to work with it
+ inline void DrawHorizontalLineSeg(int Y, int StartX, int EndX, int Color, gdImagePtr target)
+ {
+ gdImageLine(target, StartX, Y, EndX, Y, Color);
+ }
+
+ void BuildGET(Point *, int* Contours, int nContours, EdgeState *, int MaxY);
+ void MoveXSortedToAET(int);
+ void ScanOutAET(int, int, gdImagePtr);
+ void AdvanceAET(void);
+ void XSortAET(void);
+
+ /* Pointers to global edge table (GET) and active edge table (AET) */
+ struct EdgeState *m_GETPtr, *m_AETPtr;
+ EdgeState* m_bufEdgeState;
+ size_t m_nBufEdgeState;
+
+};
+
+#endif
Property changes on: trunk/MgDev/Common/Stylization/complex_polygon_gd.h
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: trunk/MgDev/Server/src/Common/Manager/LogManager.cpp
===================================================================
--- trunk/MgDev/Server/src/Common/Manager/LogManager.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Common/Manager/LogManager.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -100,7 +100,8 @@
m_bTraceLogEnabled(false), // Disabled by default
m_bTraceLogHeader(false),
m_TraceLogFileName(MgLogManager::DefaultTraceLogFileName),
- m_pLogThread(NULL)
+ m_pLogThread(NULL),
+ m_writeCount(0)
{
}
@@ -2060,7 +2061,10 @@
MG_LOGMANAGER_TRY()
- if (false == CheckArchiveFrequency(logType, filename))
+ // This is an expensive check, only do it occasionally
+ m_writeCount++;
+ if (0 == (m_writeCount%10) &&
+ false == CheckArchiveFrequency(logType, filename))
{
ArchiveLog(logType);
}
Modified: trunk/MgDev/Server/src/Common/Manager/LogManager.h
===================================================================
--- trunk/MgDev/Server/src/Common/Manager/LogManager.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Common/Manager/LogManager.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -476,6 +476,7 @@
ACE_Recursive_Thread_Mutex m_mutex;
ACE_Thread_Manager m_threadManager;
MgLogThread* m_pLogThread;
+ INT64 m_writeCount;
};
Modified: trunk/MgDev/Server/src/Common/Manager/PermissionManager.cpp
===================================================================
--- trunk/MgDev/Server/src/Common/Manager/PermissionManager.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Common/Manager/PermissionManager.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -20,7 +20,7 @@
ACE_Recursive_Thread_Mutex MgPermissionManager::sm_mutex;
Ptr<MgPermissionCache> MgPermissionManager::sm_permissionCache = new MgPermissionCache;
-INT32 MgPermissionManager::sm_permissionInfoCacheSize = 1000;
+INT32 MgPermissionManager::sm_permissionInfoCacheSize = 0;
time_t MgPermissionManager::sm_cutoffTime = 0;
///----------------------------------------------------------------------------
@@ -36,14 +36,17 @@
m_permissionCache = sm_permissionCache;
- MgConfiguration* configuration = MgConfiguration::GetInstance();
- assert(NULL != configuration);
+ if (sm_permissionInfoCacheSize <= 0)
+ {
+ MgConfiguration* configuration = MgConfiguration::GetInstance();
+ assert(NULL != configuration);
- configuration->GetIntValue(
- MgConfigProperties::ResourceServicePropertiesSection,
- MgConfigProperties::ResourceServicePropertyResourcePermissionCacheSize,
- sm_permissionInfoCacheSize,
- MgConfigProperties::DefaultResourceServicePropertyResourcePermissionCacheSize);
+ configuration->GetIntValue(
+ MgConfigProperties::ResourceServicePropertiesSection,
+ MgConfigProperties::ResourceServicePropertyResourcePermissionCacheSize,
+ sm_permissionInfoCacheSize,
+ MgConfigProperties::DefaultResourceServicePropertyResourcePermissionCacheSize);
+ }
}
///----------------------------------------------------------------------------
Modified: trunk/MgDev/Server/src/Services/Kml/ServerKmlService.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Kml/ServerKmlService.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Services/Kml/ServerKmlService.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -467,7 +467,7 @@
extents->GetLowerLeftCoordinate()->GetY(),
extents->GetUpperRightCoordinate()->GetX(),
extents->GetUpperRightCoordinate()->GetY());
- Ptr<MgFeatureReader> featureReader = MgStylizationUtil::ExecuteFeatureQuery(m_svcFeature, rsExtent, vl, NULL, destCs, layerCs);
+ Ptr<MgFeatureReader> featureReader = MgStylizationUtil::ExecuteFeatureQuery(m_svcFeature, rsExtent, vl, NULL, destCs, layerCs, NULL);
if (featureReader.p)
{
//wrap in an RS_FeatureReader
@@ -891,3 +891,5 @@
}
+
+
Modified: trunk/MgDev/Server/src/Services/Mapping/StylizationUtil.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Mapping/StylizationUtil.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Services/Mapping/StylizationUtil.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -137,7 +137,8 @@
MdfModel::VectorLayerDefinition* vl,
const wchar_t* overrideFilter,
MgCoordinateSystem* mapCs,
- MgCoordinateSystem* layerCs)
+ MgCoordinateSystem* layerCs,
+ TransformCache* cache)
{
#ifdef _DEBUG
long dwStart = GetTickCount();
@@ -156,20 +157,58 @@
if (mapCs && layerCs)
{
- trans = new MgCoordinateSystemTransform(mapCs, layerCs);
+ if (NULL != cache)
+ {
+ trans = cache->GetMgTransform();
+ }
+
+ if (!trans)
+ {
+ trans = new MgCoordinateSystemTransform(mapCs, layerCs);
+ if (NULL != cache)
+ {
+ cache->SetMgTransform(trans);
+ }
+ }
}
- //bounds in mapping space
+
+
+ //start with bounds in mapping space
Ptr<MgCoordinate> ll = new MgCoordinateXY(extent.minx, extent.miny);
Ptr<MgCoordinate> ur = new MgCoordinateXY(extent.maxx, extent.maxy);
- //if we have a valid transform, get the request extent in layer's space
- if (trans)
+ Ptr<MgEnvelope> layerExt;
+
+ //do we have a cached extent?
+ if (NULL != cache)
{
- Ptr<MgEnvelope> mapExt= new MgEnvelope(ll, ur);
+ layerExt = cache->GetEnvelope();
+ }
- //get corresponding bounds in layer space
- Ptr<MgEnvelope> layerExt = trans->Transform(mapExt);
+ if (!layerExt)
+ {
+ //no cached extent
+ //if we have a valid transform, get the request extent in layer's space
+ if (trans)
+ {
+ Ptr<MgEnvelope> mapExt = new MgEnvelope(ll, ur);
+
+ //get corresponding bounds in layer space
+ layerExt = trans->Transform(mapExt);
+
+ ll = layerExt->GetLowerLeftCoordinate();
+ ur = layerExt->GetUpperRightCoordinate();
+
+ if (NULL != cache)
+ {
+ cache->SetEnvelope(layerExt);
+ }
+ }
+ }
+ else
+ {
+ //did have a cached extent, just use it.
ll = layerExt->GetLowerLeftCoordinate();
ur = layerExt->GetUpperRightCoordinate();
}
@@ -410,8 +449,13 @@
printf("\nStylizeLayers() **MAPSTART** Layers: %d\n", layers->GetCount());
#endif
+ // Cache coordinate system transforms for the life of the
+ // stylization operation.
+ TransformCacheMap transformCache;
+
for (int i = layers->GetCount()-1; i >= 0; i--)
{
+ TransformCache* cached = NULL;
MgCSTrans* xformer = NULL;
MdfModel::LayerDefinition* ldf = NULL;
@@ -577,12 +621,29 @@
}
// Create coordinate system transformer
- srcCs = (srcwkt.empty()) ? NULL : csFactory->Create(srcwkt);
-
- if (srcCs.p)
+ if (!srcwkt.empty())
{
- xformer = new MgCSTrans(srcCs, dstCs);
+
+ TransformCacheMap::const_iterator iter = transformCache.find(srcwkt);
+ if (transformCache.end() != iter) cached = (*iter).second;
+ if (NULL != cached)
+ {
+ srcCs = cached->GetCoordSys();
+ xformer = cached->GetTransform();
+ }
+ else
+ {
+ srcCs = csFactory->Create(srcwkt);
+ if (srcCs.p)
+ {
+ xformer = new MgCSTrans(srcCs, dstCs);
+ cached = new TransformCache(xformer, srcCs);
+ transformCache[srcwkt] = cached;
+ }
+ }
+
}
+
}
else
{
@@ -664,7 +725,7 @@
//we are not drawing the actual geometry
if (maxStrokes == 0)
{
- Ptr<MgFeatureReader> rdr = ExecuteFeatureQuery(svcFeature, extent, vl, overrideFilter.c_str(), dstCs, srcCs);
+ Ptr<MgFeatureReader> rdr = ExecuteFeatureQuery(svcFeature, extent, vl, overrideFilter.c_str(), dstCs, srcCs, cached);
if (rdr.p)
{
//wrap the MgFeatureReader in our RSMgFeatureReader wrapper
@@ -700,7 +761,7 @@
syms->Adopt(syms2->GetAt(min(i, syms2->GetCount()-1)));
}
- Ptr<MgFeatureReader> rdr = ExecuteFeatureQuery(svcFeature, extent, vl, overrideFilter.c_str(), dstCs, srcCs);
+ Ptr<MgFeatureReader> rdr = ExecuteFeatureQuery(svcFeature, extent, vl, overrideFilter.c_str(), dstCs, srcCs, cached);
if (rdr.p)
{
//wrap in an RS_FeatureReader
@@ -746,7 +807,7 @@
}
else
{
- Ptr<MgFeatureReader> rdr = ExecuteFeatureQuery(svcFeature, extent, vl, overrideFilter.c_str(), dstCs, srcCs);
+ Ptr<MgFeatureReader> rdr = ExecuteFeatureQuery(svcFeature, extent, vl, overrideFilter.c_str(), dstCs, srcCs, cached);
if (rdr.p)
{
//wrap the MgFeatureReader in our RSMgFeatureReader wrapper
@@ -861,11 +922,26 @@
}
// Create coordinate system transformer
- srcCs = (srcwkt.empty()) ? NULL : csFactory->Create(srcwkt);
-
- if (srcCs.p)
+ if (!srcwkt.empty())
{
- xformer = new MgCSTrans(srcCs, dstCs);
+ TransformCacheMap::const_iterator iter = transformCache.find(srcwkt);
+ if (transformCache.end() != iter) cached = (*iter).second;
+ if (NULL != cached)
+ {
+ srcCs = cached->GetCoordSys();
+ xformer = cached->GetTransform();
+ }
+ else
+ {
+ srcCs = csFactory->Create(srcwkt);
+ if (srcCs.p)
+ {
+ xformer = new MgCSTrans(srcCs, dstCs);
+ cached = new TransformCache(xformer, srcCs);
+ transformCache[srcwkt] = cached;
+ }
+ }
+
}
}
else
@@ -966,9 +1042,23 @@
if (!cs.empty() && cs != dstCs->ToString())
{
- //construct cs transformer if needed
- Ptr<MgCoordinateSystem> srcCs = csFactory->Create(cs);
- xformer = new MgCSTrans(srcCs, dstCs);
+ // Create coordinate system transformer
+ TransformCacheMap::const_iterator iter = transformCache.find(cs);
+ if (transformCache.end() != iter) cached = (*iter).second;
+ if (NULL != cached)
+ {
+ xformer = cached->GetTransform();
+ }
+ else
+ {
+ Ptr<MgCoordinateSystem> srcCs = csFactory->Create(cs);
+ if (srcCs.p)
+ {
+ xformer = new MgCSTrans(srcCs, dstCs);
+ cached = new TransformCache(xformer, srcCs);
+ transformCache[cs] = cached;
+ }
+ }
}
}
@@ -1021,22 +1111,25 @@
#endif
}
- if (xformer)
- {
- delete xformer;
- xformer = NULL;
- }
-
if (ldf)
{
delete ldf;
ldf = NULL;
}
+
}
#ifdef _DEBUG
printf("StylizeLayers() **MAPDONE** Layers: %d Total Time = %6.4f (s)\n\n", layers->GetCount(), (GetTickCount()-dwStart)/1000.0);
#endif
+
+ TransformCacheMap::iterator iter = transformCache.begin();
+ while (transformCache.end() != iter)
+ {
+ delete (*iter).second;
+ (*iter).second = NULL;
+ ++iter;
+ }
}
@@ -1626,3 +1719,46 @@
return NULL;
}
+
+
+MgStylizationUtil::TransformCache::TransformCache(MgCSTrans* transform, MgCoordinateSystem* coordinateSystem)
+: m_xform(transform)
+{
+ m_coordSys = SAFE_ADDREF((MgCoordinateSystem*)coordinateSystem);
+}
+
+MgStylizationUtil::TransformCache::~TransformCache()
+{
+ delete m_xform;
+ m_xform = NULL;
+}
+
+MgCSTrans* MgStylizationUtil::TransformCache::GetTransform()
+{
+ return m_xform;
+}
+
+MgCoordinateSystem* MgStylizationUtil::TransformCache::GetCoordSys()
+{
+ return SAFE_ADDREF((MgCoordinateSystem*) m_coordSys);
+}
+
+void MgStylizationUtil::TransformCache::SetMgTransform(MgCoordinateSystemTransform* mgTransform)
+{
+ m_transform = SAFE_ADDREF((MgCoordinateSystemTransform*) mgTransform);
+}
+
+MgCoordinateSystemTransform* MgStylizationUtil::TransformCache::GetMgTransform()
+{
+ return SAFE_ADDREF((MgCoordinateSystemTransform*) m_transform);
+}
+
+void MgStylizationUtil::TransformCache::SetEnvelope(MgEnvelope* envelope)
+{
+ m_envelope = SAFE_ADDREF((MgEnvelope*) envelope);
+}
+
+MgEnvelope* MgStylizationUtil::TransformCache::GetEnvelope()
+{
+ return SAFE_ADDREF((MgEnvelope*) m_envelope);
+}
Modified: trunk/MgDev/Server/src/Services/Mapping/StylizationUtil.h
===================================================================
--- trunk/MgDev/Server/src/Services/Mapping/StylizationUtil.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Services/Mapping/StylizationUtil.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -32,12 +32,36 @@
class MgStringCollection;
class MgMap;
class MgCoordinateSystem;
+class MgCSTrans;
//Common stylization utility code -- used by both the mapping and rendering services
class MG_SERVER_MAPPING_API MgStylizationUtil
{
public:
+ // Class to cache coordinate systems and transforms during processing. Many layers
+ // will use the same coordinate system so this is an effective way to reduce significant overhead.
+ class TransformCache
+ {
+ public:
+ TransformCache(MgCSTrans* transform, MgCoordinateSystem* coordinateSystem);
+ virtual ~TransformCache();
+ MgCSTrans* GetTransform();
+ MgCoordinateSystem* GetCoordSys();
+ void SetMgTransform(MgCoordinateSystemTransform* mgTransform);
+ MgCoordinateSystemTransform* GetMgTransform();
+ void SetEnvelope(MgEnvelope* extent);
+ MgEnvelope* GetEnvelope();
+
+ private:
+ MgCSTrans* m_xform;
+ Ptr<MgCoordinateSystem> m_coordSys;
+ Ptr<MgCoordinateSystemTransform> m_transform;
+ Ptr<MgEnvelope> m_envelope;
+ };
+
+ typedef std::map<STRING, TransformCache*> TransformCacheMap;
+
static void StylizeLayers(MgResourceService* svcResource,
MgFeatureService* svcFeature,
MgDrawingService* svcDrawing,
@@ -57,7 +81,8 @@
MdfModel::VectorLayerDefinition* vl,
const wchar_t* overrideFilter,
MgCoordinateSystem* mapCs,
- MgCoordinateSystem* layerCs);
+ MgCoordinateSystem* layerCs,
+ TransformCache* cache);
static MgFeatureReader * ExecuteRasterQuery(MgFeatureService* svcFeature,
RS_Bounds& extent,
Modified: trunk/MgDev/Server/src/Services/Resource/RepositoryManager.h
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/RepositoryManager.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Services/Resource/RepositoryManager.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -108,6 +108,9 @@
virtual bool FindResource(MgResourceIdentifier* resource);
+ virtual MgResourceContentManager* GetResourceContentManager() = 0;
+ virtual MgResourceHeaderManager* GetResourceHeaderManager() = 0;
+
protected:
void CreateTransaction();
@@ -115,9 +118,6 @@
virtual void CommitTransaction();
void AbortTransaction();
- virtual MgResourceContentManager* GetResourceContentManager() = 0;
- virtual MgResourceHeaderManager* GetResourceHeaderManager() = 0;
-
virtual void UpdateDateModifiedResourceSet(CREFSTRING resource) {};
virtual void UpdateChangedResourceSet(MgResourceIdentifier& resource) {};
Modified: trunk/MgDev/Server/src/Services/Resource/ResourceDefinitionManager.h
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/ResourceDefinitionManager.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Services/Resource/ResourceDefinitionManager.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -79,6 +79,11 @@
bool FindResource(const string& mbResourcePathname);
bool FindResource(CREFSTRING wcResourcePathname);
+ // Resource Permission related methods
+
+ virtual bool CheckPermission(MgResourceIdentifier& resource,
+ CREFSTRING permission, bool strict = true) = 0;
+
protected:
virtual void ValidateDocument(MgResourceIdentifier& resource,
@@ -107,10 +112,6 @@
void DeleteDocument(XmlDocument& xmlDoc,
XmlUpdateContext& updateContext);
- // Resource Permission related methods
-
- virtual bool CheckPermission(MgResourceIdentifier& resource,
- CREFSTRING permission, bool strict = true) = 0;
virtual bool CheckParentPermission(MgResourceIdentifier& resource,
CREFSTRING permission, bool strict = true) = 0;
Modified: trunk/MgDev/Server/src/Services/Resource/ServerResourceService.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/ServerResourceService.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Services/Resource/ServerResourceService.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -2054,6 +2054,46 @@
///----------------------------------------------------------------------------
/// <summary>
+/// Checks whether or not the current user has the specified permission on the
+/// specified resource.
+/// </summary>
+///----------------------------------------------------------------------------
+
+bool MgServerResourceService::HasPermission(MgResourceIdentifier* resource,
+ CREFSTRING permission)
+{
+ bool retVal = false;
+
+ MG_RESOURCE_SERVICE_TRY()
+
+ MG_LOG_TRACE_ENTRY(L"MgServerResourceService::HasPermission()");
+
+ if (NULL == resource)
+ {
+ throw new MgNullArgumentException(
+ L"MgServerResourceService.HasPermission",
+ __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ auto_ptr<MgApplicationRepositoryManager> repositoryMan(
+ CreateApplicationRepositoryManager(resource));
+ MgResourceContentManager* resourceContentMan =
+ repositoryMan->GetResourceContentManager();
+ ACE_ASSERT(NULL != resourceContentMan);
+
+ MG_RESOURCE_SERVICE_BEGIN_OPERATION(false)
+
+ retVal = resourceContentMan->CheckPermission(*resource, permission);
+
+ MG_RESOURCE_SERVICE_END_OPERATION(sm_maxOpRetries)
+
+ MG_RESOURCE_SERVICE_CATCH_AND_THROW(L"MgServerResourceService.HasPermission")
+
+ return retVal;
+}
+
+///----------------------------------------------------------------------------
+/// <summary>
/// Performs checkpoints for all the repositories.
/// </summary>
///----------------------------------------------------------------------------
Modified: trunk/MgDev/Server/src/Services/Resource/ServerResourceService.h
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/ServerResourceService.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Services/Resource/ServerResourceService.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -156,6 +156,8 @@
// Resource Permission related methods
MgPermissionCache* CreatePermissionCache();
+ virtual bool HasPermission(MgResourceIdentifier* resource,
+ CREFSTRING permission);
// Other internal methods
Modified: trunk/MgDev/Server/src/Services/Resource/SessionRepositoryManager.h
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/SessionRepositoryManager.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Services/Resource/SessionRepositoryManager.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -47,11 +47,11 @@
virtual MgByteReader* EnumerateRepositories();
virtual void DeleteRepository(MgResourceIdentifier* resource);
+ virtual MgResourceHeaderManager* GetResourceHeaderManager();
protected:
virtual MgResourceContentManager* GetResourceContentManager();
- virtual MgResourceHeaderManager* GetResourceHeaderManager();
/// Data Members
Modified: trunk/MgDev/Server/src/Services/Resource/SystemRepositoryManager.h
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/SystemRepositoryManager.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Services/Resource/SystemRepositoryManager.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -47,9 +47,10 @@
virtual MgByteReader* GetResourceContent(
MgResourceIdentifier* resource, CREFSTRING preProcessTags);
+ virtual MgResourceHeaderManager* GetResourceHeaderManager();
+
protected:
- virtual MgResourceHeaderManager* GetResourceHeaderManager();
/// Data Members
Modified: trunk/MgDev/Server/src/Services/Tile/OpGetTile.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/OpGetTile.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Services/Tile/OpGetTile.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -46,7 +46,7 @@
ACE_ASSERT(m_stream != NULL);
- if (4 == m_packet.m_NumArguments)
+ if (4 == m_packet.m_NumArguments && m_packet.m_OperationVersion == 1 )
{
Ptr<MgMap> map = (MgMap*)m_stream->GetObject();
map->SetDelayedLoadResourceService(m_resourceService);
@@ -80,6 +80,44 @@
EndExecution(byteReader);
}
+ else if (5 == m_packet.m_NumArguments && m_packet.m_OperationVersion == 2 )
+ {
+ Ptr<MgResourceIdentifier> mapDefinition = (MgResourceIdentifier*)m_stream->GetObject();
+
+ STRING baseMapLayerGroupName;
+ m_stream->GetString(baseMapLayerGroupName);
+
+ INT32 tileCol = 0;
+ m_stream->GetInt32(tileCol);
+
+ INT32 tileRow = 0;
+ m_stream->GetInt32(tileRow);
+
+ INT32 scale = 0;
+ m_stream->GetInt32(scale);
+
+ BeginExecution();
+
+ MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+ MG_LOG_OPERATION_MESSAGE_ADD_STRING(L"MgResourceIdentifier");
+ 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_STRING(L"tileCol");
+ MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+ MG_LOG_OPERATION_MESSAGE_ADD_STRING(L"tileRow");
+ MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+ MG_LOG_OPERATION_MESSAGE_ADD_DOUBLE(scale);
+ MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+
+ Validate();
+
+ Ptr<MgByteReader> byteReader =
+ m_service->GetTile(mapDefinition, baseMapLayerGroupName, tileCol, tileRow, scale);
+
+
+ EndExecution(byteReader);
+ }
else
{
MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
Modified: trunk/MgDev/Server/src/Services/Tile/ServerTileService.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/ServerTileService.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Services/Tile/ServerTileService.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -20,8 +20,29 @@
IMPLEMENT_CREATE_SERVICE(MgServerTileService)
+ACE_Recursive_Thread_Mutex MgServerTileService::sm_mutex;
+MgServerTileService::MapCache MgServerTileService::sm_mapCache;
+INT32 MgServerTileService::sm_mapCacheSize = -1;
+bool MgServerTileService::sm_renderOnly = false;
+
MgServerTileService::MgServerTileService() : MgTileService()
{
+ if (sm_mapCacheSize < 0)
+ {
+ // initialize the tile cache size
+ MgConfiguration* pConf = MgConfiguration::GetInstance();
+
+ pConf->GetIntValue(MgConfigProperties::TileServicePropertiesSection,
+ MgConfigProperties::TileServicePropertyTiledMapCacheSize,
+ sm_mapCacheSize,
+ MgConfigProperties::DefaultTileServicePropertyTiledMapCacheSize);
+
+ pConf->GetBoolValue(MgConfigProperties::TileServicePropertiesSection,
+ MgConfigProperties::TileServicePropertyRenderOnly,
+ sm_renderOnly,
+ MgConfigProperties::DefaultTileServicePropertyRenderOnly);
+ }
+
m_tileCache = new MgTileCache();
}
@@ -30,7 +51,102 @@
{
}
+MgByteReader* MgServerTileService::GetTile(
+ MgResourceIdentifier* mapDefinition,
+ CREFSTRING baseMapLayerGroupName,
+ INT32 tileColumn,
+ INT32 tileRow,
+ INT32 scaleIndex)
+{
+ Ptr<MgByteReader> ret;
+ MG_TRY()
+
+ if (NULL == mapDefinition || baseMapLayerGroupName.empty())
+ {
+ throw new MgNullArgumentException(
+ L"MgServerTileService.GetTile", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ MgServiceManager* serviceMan = MgServiceManager::GetInstance();
+ assert(NULL != serviceMan);
+
+ // Get the service from service manager
+ Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(
+ serviceMan->RequestService(MgServiceType::ResourceService));
+ assert(resourceService != NULL);
+
+ bool bAllowed = resourceService->HasPermission(mapDefinition, MgResourcePermission::ReadOnly);
+
+ if (!bAllowed)
+ {
+ MG_LOG_AUTHENTICATION_ENTRY(MgResources::PermissionDenied.c_str());
+
+ MgStringCollection arguments;
+ arguments.Add(mapDefinition->ToString());
+
+ throw new MgPermissionDeniedException(
+ L"MgServerTileService.GetTile",
+ __LINE__, __WFILE__, &arguments, L"", NULL);
+ }
+
+ ret = m_tileCache->Get(mapDefinition, scaleIndex, baseMapLayerGroupName, tileColumn, tileRow);
+
+ if (!ret)
+ {
+
+ // Attempt use a cached & serialized MgMap object
+ Ptr<MgMemoryStreamHelper> cachedMap;
+
+ STRING mapString = mapDefinition->ToString();
+
+ Ptr<MgMap> map;
+
+ // Protect the serialized MgMap cache with a mutex. Stream reading is not
+ // thread safe so we need to deserialize the map within the mutex to ensure
+ // that a Rewind() is not called in the middle of a Deserialize()
+ {
+ ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex, NULL));
+ MapCache::const_iterator iter = sm_mapCache.find(mapString);
+ if (sm_mapCache.end() != iter)
+ {
+ cachedMap = SAFE_ADDREF((*iter).second);
+ }
+ else
+ {
+ map = new MgMap();
+ map->Create(resourceService, mapDefinition, mapString);
+ cachedMap = new MgMemoryStreamHelper();
+ Ptr<MgStream> stream = new MgStream(cachedMap);
+ map->Serialize(stream);
+ if (sm_mapCache.size() > sm_mapCacheSize)
+ {
+ ClearMapCache(L"");
+ }
+ sm_mapCache[mapString] = SAFE_ADDREF((MgMemoryStreamHelper*)cachedMap);
+ }
+
+
+ if (!map)
+ {
+ cachedMap->Rewind();
+ Ptr<MgStream> stream = new MgStream(cachedMap);
+ map = new MgMap();
+ map->Deserialize(stream);
+ }
+ }
+
+ double scale = map->GetFiniteDisplayScaleAt(scaleIndex);
+ map->SetViewScale(scale);
+ ret = GetTile(map, baseMapLayerGroupName, tileColumn, tileRow);
+ }
+
+ MG_CATCH_AND_THROW(L"MgServerTileService.GetTile")
+
+ return ret.Detach();
+}
+
+
MgByteReader* MgServerTileService::GetTile(MgMap* map,
CREFSTRING baseMapLayerGroupName,
INT32 tileColumn,
@@ -70,11 +186,14 @@
ret = svcRendering->RenderTile(map, baseMapLayerGroupName, tileColumn, tileRow);
// cache the tile
- SetTile(ret, map, scaleIndex, baseMapLayerGroupName, tileColumn, tileRow);
+ if (!sm_renderOnly)
+ {
+ SetTile(ret, map, scaleIndex, baseMapLayerGroupName, tileColumn, tileRow);
- // rewind the reader since setting the tile advances it to the end
- if (ret)
- ret->Rewind();
+ // rewind the reader since setting the tile advances it to the end
+ if (ret)
+ ret->Rewind();
+ }
}
}
@@ -123,6 +242,9 @@
if (NULL == map)
throw new MgNullArgumentException(L"MgServerTileService.ClearCache", __LINE__, __WFILE__, NULL, L"", NULL);
+ Ptr<MgResourceIdentifier> resourceId = map->GetMapDefinition();
+ ClearMapCache(resourceId->ToString());
+
m_tileCache->Clear(map);
MG_CATCH_AND_THROW(L"MgServerTileService.ClearCache")
@@ -157,6 +279,9 @@
if (mapResId->IsResourceTypeOf(MgResourceType::MapDefinition))
{
+ // clear any cached mgmap objects
+ ClearMapCache(mapResId->ToString());
+
// clear any tile cache associated with this map
m_tileCache->Clear(mapResId);
}
@@ -170,3 +295,28 @@
{
// Do nothing. No connection properties are required for Server-side service objects.
}
+
+void MgServerTileService::ClearMapCache(CREFSTRING mapDefinition)
+{
+ ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex));
+ MapCache::iterator iter = sm_mapCache.end();
+ if (mapDefinition.empty())
+ {
+ for (iter = sm_mapCache.begin(); iter != sm_mapCache.end(); ++iter)
+ {
+ SAFE_RELEASE((*iter).second);
+ (*iter).second = NULL;
+ }
+ sm_mapCache.clear();
+ }
+ else
+ {
+ iter = sm_mapCache.find(mapDefinition);
+ if (sm_mapCache.end() != iter)
+ {
+ SAFE_RELEASE((*iter).second);
+ (*iter).second = NULL;
+ sm_mapCache.erase(iter);
+ }
+ }
+}
Modified: trunk/MgDev/Server/src/Services/Tile/ServerTileService.h
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/ServerTileService.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Services/Tile/ServerTileService.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -35,6 +35,12 @@
INT32 tileColumn,
INT32 tileRow);
+ virtual MgByteReader* GetTile(MgResourceIdentifier* mapDefinition,
+ CREFSTRING baseMapLayerGroupName,
+ INT32 tileColumn,
+ INT32 tileRow,
+ INT32 scaleIndex);
+
virtual void SetTile(MgByteReader* img,
MgMap* map,
INT32 scaleIndex,
@@ -50,8 +56,17 @@
private:
+ void ClearMapCache(CREFSTRING mapName);
+
// member data
Ptr<MgTileCache> m_tileCache;
+
+ typedef std::map<STRING, MgMemoryStreamHelper*> MapCache;
+ static MapCache sm_mapCache;
+ static ACE_Recursive_Thread_Mutex sm_mutex;
+ static INT32 sm_mapCacheSize;
+ static bool sm_renderOnly;
+
};
#endif
Modified: trunk/MgDev/Server/src/Services/Tile/TileCache.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/TileCache.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Services/Tile/TileCache.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -20,23 +20,30 @@
#define PATH_LEN 512
+STRING MgTileCache::m_path = L"";
+
// default constructor
MgTileCache::MgTileCache()
{
- // initialize the tile cache path
- MgConfiguration* pConf = MgConfiguration::GetInstance();
+ //TODO: It is possible to get a double write on m_path here. We need
+ //to investigate general mutex use in this class.
+ if (m_path.empty())
+ {
+ // initialize the tile cache path
+ MgConfiguration* pConf = MgConfiguration::GetInstance();
- pConf->GetStringValue(MgConfigProperties::TileServicePropertiesSection,
- MgConfigProperties::TileServicePropertyTileCachePath,
- m_path,
- MgConfigProperties::DefaultTileServicePropertyTileCachePath);
+ pConf->GetStringValue(MgConfigProperties::TileServicePropertiesSection,
+ MgConfigProperties::TileServicePropertyTileCachePath,
+ m_path,
+ MgConfigProperties::DefaultTileServicePropertyTileCachePath);
- // generate directory location for tile cache
- MgFileUtil::AppendSlashToEndOfPath(m_path);
+ // generate directory location for tile cache
+ MgFileUtil::AppendSlashToEndOfPath(m_path);
- // create directory if it is not already there
- if (!MgFileUtil::PathnameExists(m_path))
- MgFileUtil::CreateDirectory(m_path, false);
+ // create directory if it is not already there
+ if (!MgFileUtil::PathnameExists(m_path))
+ MgFileUtil::CreateDirectory(m_path, false);
+ }
}
@@ -69,7 +76,35 @@
return SAFE_ADDREF(ret.p);
}
+MgByteReader* MgTileCache::Get(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group, int i, int j)
+{
+ // acquire a read lock - this blocks if a writer holds the lock
+ ACE_Read_Guard<ACE_RW_Thread_Mutex> ace_mon(m_mutexRW);
+ Ptr<MgByteReader> ret;
+
+ if (mapDef != NULL)
+ {
+ STRING tilePath = MgTileCache::GetFullPath(mapDef, scaleIndex, group);
+
+ // generate full path to tile file using <row,column> format
+ // TODO: handle case where path is > PATH_LEN
+ wchar_t tmp[PATH_LEN] = { 0 };
+ swprintf(tmp, PATH_LEN, L"%ls/%d_%d.png", tilePath.c_str(), j, i);
+
+ MG_TRY()
+
+ Ptr<MgByteSource> bs = new MgByteSource(tmp, false);
+ bs->SetMimeType(MgMimeType::Png);
+ ret = bs->GetReader();
+
+ MG_CATCH_AND_RELEASE()
+ }
+
+ return SAFE_ADDREF(ret.p);
+}
+
+
// caches a tile for the given map / scale index / group / i / j
void MgTileCache::Set(MgByteReader* img, MgMap* map, int scaleIndex, CREFSTRING group, int i, int j)
{
@@ -192,7 +227,18 @@
return STRING(tmp);
}
+// gets the full path to use with the tile cache for the given map / scale index / group
+STRING MgTileCache::GetFullPath(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group)
+{
+ STRING basePath = MgTileCache::GetBasePath(mapDef);
+ wchar_t tmp[PATH_LEN] = { 0 };
+ swprintf(tmp, PATH_LEN, L"%ls/%d/%ls", basePath.c_str(), scaleIndex, group.c_str());
+
+ return STRING(tmp);
+}
+
+
STRING MgTileCache::CreateFullPath(MgMap* map, int scaleIndex, CREFSTRING group)
{
wchar_t tmp[PATH_LEN] = { 0 };
Modified: trunk/MgDev/Server/src/Services/Tile/TileCache.h
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/TileCache.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Services/Tile/TileCache.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -27,6 +27,7 @@
MgTileCache();
MgByteReader* Get(MgMap* map, int scaleIndex, CREFSTRING group, int i, int j);
+ MgByteReader* Get(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group, int i, int j);
void Set(MgByteReader* img, MgMap* map, int scaleIndex, CREFSTRING group, int i, int j);
void Clear(MgMap* map);
void Clear(MgResourceIdentifier* resId);
@@ -41,10 +42,14 @@
STRING GetBasePath(MgMap* map);
STRING GetBasePath(MgResourceIdentifier* resId);
STRING GetFullPath(MgMap* map, int scaleIndex, CREFSTRING group);
+ STRING GetFullPath(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group);
STRING CreateFullPath(MgMap* map, int scaleIndex, CREFSTRING group);
+ // TODO: Investigate this mutex. It may fail if
+ // we have more than one tile service and could reduce
+ // multi-threaded performance. File locks would be better.
ACE_RW_Thread_Mutex m_mutexRW;
- STRING m_path;
+ static STRING m_path;
};
#endif
Modified: trunk/MgDev/Server/src/Services/Tile/TileOperationFactory.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/TileOperationFactory.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Server/src/Services/Tile/TileOperationFactory.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -65,6 +65,7 @@
switch (operationVersion)
{
case 1:
+ case 2:
handler.reset(new MgOpGetTile());
break;
default:
Added: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/gettileimageform2.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/gettileimageform2.html 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/gettileimageform2.html 2007-01-20 00:49:25 UTC (rev 1064)
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <script type="text/javascript" src="setactiontarget.js" >
+ </script>
+ </head>
+ <body>
+ <form name="input" action="" method="get" ID="Form1">
+ <div nowrap="true">
+ <b>Operation:</b> <input type="text" name="OPERATION" value="GETTILEIMAGE" size="50" ID="Text1">
+ <p>
+ Version: <input type="text" name="VERSION" value="2.0.0" size="10" ID="Text2">
+ <p>
+ Map name: <input type="text" name="MAPDEFINITION" value="Library://Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition" size="100" ID="Text4">
+ <p>
+ BaseMapLayerGroup name: <input type="text" name="BASEMAPLAYERGROUPNAME" value="Base Layer Group" size="100" ID="Text5">
+ <p>
+ Tile column index: <input type="text" name="TILECOL" value="10" size="10" ID="Text6">
+    
+ Tile row index: <input type="text" name="TILEROW" value="10" size="10" ID="Text7">
+ <p>
+ Scale: <input type="text" name="SCALEINDEX" value="1" size="100" ID="Text5">
+ <p>
+ <input type="submit" value="Submit" onclick="SetActionTarget()"> <input type="reset">
+ </div>
+ </form>
+ </body>
+</html>
Property changes on: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/gettileimageform2.html
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/tileserviceapi.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/tileserviceapi.html 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/tileserviceapi.html 2007-01-20 00:49:25 UTC (rev 1064)
@@ -11,6 +11,8 @@
<LI>
<A href="gettileimageform.html" target="showform">GetTileImage</a></LI>
<LI>
+ <A href="gettileimageform2.html" target="showform">GetTileImage R2</a></LI>
+ <LI>
<A href="cleartilecacheform.html" target="showform">ClearTileCache</a></LI>
</UL>
<P> </P>
Modified: trunk/MgDev/Web/src/HttpHandler/HttpGetTileImage.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpGetTileImage.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Web/src/HttpHandler/HttpGetTileImage.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -36,17 +36,56 @@
Ptr<MgHttpRequestParam> params = hRequest->GetRequestParam();
- // Get the map name
- m_mapName = params->GetParameterValue(MgHttpResourceStrings::reqRenderingMapName);
+ STRING version = params->GetParameterValue(MgHttpResourceStrings::reqVersion);
- // Get the baseMapLayerGroup name
- m_baseMapLayerGroupName = params->GetParameterValue(MgHttpResourceStrings::reqRenderingBaseMapLayerGroupName);
+ size_t pos1;
- // Get the tile column index and convert to integer
- m_tileCol = MgUtil::StringToInt32(params->GetParameterValue(MgHttpResourceStrings::reqRenderingTileColumn));
+ pos1 = version.find(L".");
+ if (pos1 != string::npos)
+ {
+ m_version = version.substr(0, pos1);
+ }
+ else
+ {
+ m_version = version;
+ }
- // Get the tile row index and convert to integer
- m_tileRow = MgUtil::StringToInt32(params->GetParameterValue(MgHttpResourceStrings::reqRenderingTileRow));
+ if (m_version == L"1")
+ {
+ // Get the map name
+ m_mapName = params->GetParameterValue(MgHttpResourceStrings::reqRenderingMapName);
+
+ // Get the baseMapLayerGroup name
+ m_baseMapLayerGroupName = params->GetParameterValue(MgHttpResourceStrings::reqRenderingBaseMapLayerGroupName);
+
+ // Get the tile column index and convert to integer
+ m_tileCol = MgUtil::StringToInt32(params->GetParameterValue(MgHttpResourceStrings::reqRenderingTileColumn));
+
+ // Get the tile row index and convert to integer
+ m_tileRow = MgUtil::StringToInt32(params->GetParameterValue(MgHttpResourceStrings::reqRenderingTileRow));
+ }
+ else if (m_version == L"2")
+ {
+ // Get the map name
+ m_mapName = params->GetParameterValue(MgHttpResourceStrings::reqTileMapDefinition);
+
+ // Get the baseMapLayerGroup name
+ m_baseMapLayerGroupName = params->GetParameterValue(MgHttpResourceStrings::reqRenderingBaseMapLayerGroupName);
+
+ // Get the tile column index and convert to integer
+ m_tileCol = MgUtil::StringToInt32(params->GetParameterValue(MgHttpResourceStrings::reqRenderingTileColumn));
+
+ // Get the tile row index and convert to integer
+ m_tileRow = MgUtil::StringToInt32(params->GetParameterValue(MgHttpResourceStrings::reqRenderingTileRow));
+
+ // Get the scale and convert to double
+ m_scale = MgUtil::StringToDouble(params->GetParameterValue(MgHttpResourceStrings::reqRenderingScaleIndex));
+ }
+ else
+ {
+ throw new MgInvalidOperationVersionException(
+ L"MgHttpGetTileImage.MgHttpGetTileImage", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
}
/// <summary>
@@ -75,21 +114,52 @@
__LINE__, __WFILE__, &arguments, L"MgStringEmpty", NULL);
}
- // Get Proxy Resource Service instance
- Ptr<MgResourceService> resourceService = (MgResourceService*)CreateService(MgServiceType::ResourceService);
+ if (m_version == L"1")
+ {
+ // Get Proxy Resource Service instance
+ Ptr<MgResourceService> resourceService = (MgResourceService*)CreateService(MgServiceType::ResourceService);
- // Create MgMap
- Ptr<MgMap> map = new MgMap();
- map->Open(resourceService, m_mapName);
+ // Create MgMap
+ Ptr<MgMap> map = new MgMap();
+ map->Open(resourceService, m_mapName);
- // Get Proxy Tile Service instance
- Ptr<MgTileService> service = (MgTileService*)(CreateService(MgServiceType::TileService));
+ // Get Proxy Tile Service instance
+ Ptr<MgTileService> service = (MgTileService*)(CreateService(MgServiceType::TileService));
- // Call the C++ API
- Ptr<MgByteReader> tileImage = service->GetTile(map, m_baseMapLayerGroupName, m_tileCol, m_tileRow);
+ // Call the C++ API
+ Ptr<MgByteReader> tileImage = service->GetTile(map, m_baseMapLayerGroupName, m_tileCol, m_tileRow);
- // Set the result
- hResult->SetResultObject(tileImage, tileImage->GetMimeType());
+ // Set the result
+ hResult->SetResultObject(tileImage, tileImage->GetMimeType());
+ }
+ else
+ {
+ Ptr<MgResourceIdentifier> resId = new MgResourceIdentifier(m_mapName);
+ // Get Proxy Tile Service instance
+ Ptr<MgTileService> service = (MgTileService*)(CreateService(MgServiceType::TileService));
+
+ // Call the C++ API
+ Ptr<MgByteReader> tileImage = service->GetTile(resId, m_baseMapLayerGroupName, m_tileCol, m_tileRow, m_scale);
+
+ // Set the result
+ hResult->SetResultObject(tileImage, tileImage->GetMimeType());
+ }
+
MG_HTTP_HANDLER_CATCH_AND_THROW_EX(L"MgHttpGetTileImage.Execute")
}
+
+/// <summary>
+/// This method is responsible for checking if
+/// a valid version was given
+/// </summary>
+/// <returns>Returns nothing</returns>
+void MgHttpGetTileImage::ValidateOperationVersion()
+{
+ MG_HTTP_HANDLER_TRY()
+
+ // Operation version validation has been moved to constructor
+
+ MG_HTTP_HANDLER_CATCH_AND_THROW(L"MgHttpGetTileImage.ValidateOperationVersion");
+}
+
Modified: trunk/MgDev/Web/src/HttpHandler/HttpGetTileImage.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpGetTileImage.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Web/src/HttpHandler/HttpGetTileImage.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -51,11 +51,21 @@
/// </returns>
MgRequestClassification GetRequestClassification() { return MgHttpRequestResponseHandler::mrcViewer; }
+protected:
+ /// <summary>
+ /// This method is responsible for checking if
+ /// a valid version was given
+ /// </summary>
+ /// <returns>Returns nothing</returns>
+ virtual void ValidateOperationVersion();
+
private:
STRING m_mapName;
STRING m_baseMapLayerGroupName;
INT32 m_tileCol;
INT32 m_tileRow;
+ STRING m_version;
+ double m_scale;
};
#endif // _FS_GET_TILE_IMAGE_H
Modified: trunk/MgDev/Web/src/HttpHandler/HttpRequestResponseHandler.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpRequestResponseHandler.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Web/src/HttpHandler/HttpRequestResponseHandler.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -126,7 +126,7 @@
m_userInfo->SetClientIp(clientIp);
}
- // And create the site connection, pushing user information into thread local storage
+ // And create the site connection
m_siteConn = new MgSiteConnection();
m_siteConn->Open(m_userInfo);
Modified: trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.cpp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.cpp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -227,6 +227,7 @@
const STRING MgHttpResourceStrings::reqRenderingTileColumn = L"TILECOL";
const STRING MgHttpResourceStrings::reqRenderingTileRow = L"TILEROW";
const STRING MgHttpResourceStrings::reqRenderingPersist = L"PERSIST";
+const STRING MgHttpResourceStrings::reqRenderingScaleIndex = L"SCALEINDEX";
// Rendering Service Operation Requests
const STRING MgHttpResourceStrings::opGetDynamicMapOverlayImage = L"GETDYNAMICMAPOVERLAYIMAGE";
Modified: trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.h 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.h 2007-01-20 00:49:25 UTC (rev 1064)
@@ -165,6 +165,7 @@
static const STRING reqRenderingTileColumn;
static const STRING reqRenderingTileRow;
static const STRING reqRenderingPersist;
+ static const STRING reqRenderingScaleIndex;
// PREDEFINED TILE REQUEST PARAMETERS
static const STRING reqTileMapDefinition;
Modified: trunk/MgDev/Web/src/mapviewerjava/mapframe.jsp
===================================================================
--- trunk/MgDev/Web/src/mapviewerjava/mapframe.jsp 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Web/src/mapviewerjava/mapframe.jsp 2007-01-20 00:49:25 UTC (rev 1064)
@@ -149,6 +149,7 @@
String vpath = GetSurroundVirtualPath(request);
String vals[] = { GetRootVirtualFolder(request) + "/mapagent/mapagent.fcgi",
mapName,
+ mapDefinition,
String.valueOf(infoWidth),
showLegend != 0 ? "true": "false",
showProperties != 0 ? "true": "false",
Modified: trunk/MgDev/Web/src/mapviewernet/mapframe.aspx
===================================================================
--- trunk/MgDev/Web/src/mapviewernet/mapframe.aspx 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Web/src/mapviewernet/mapframe.aspx 2007-01-20 00:49:25 UTC (rev 1064)
@@ -152,6 +152,7 @@
String vpath = GetSurroundVirtualPath(Request);
String[] vals = { GetRootVirtualFolder(Request) + "/mapagent/mapagent.fcgi",
mapName,
+ mapDefinition,
IntToString(infoWidth),
showLegend != 0 ? "true": "false",
showProperties != 0 ? "true": "false",
Modified: trunk/MgDev/Web/src/mapviewerphp/mapframe.php
===================================================================
--- trunk/MgDev/Web/src/mapviewerphp/mapframe.php 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Web/src/mapviewerphp/mapframe.php 2007-01-20 00:49:25 UTC (rev 1064)
@@ -121,6 +121,7 @@
printf ($templ,
GetRootVirtualFolder() . "/mapagent/mapagent.fcgi",
$mapName,
+ $mapDefinition,
$infoWidth,
$showLegend?"true":"false",
$showProperties?"true":"false",
Modified: trunk/MgDev/Web/src/viewerfiles/ajaxmappane.templ
===================================================================
--- trunk/MgDev/Web/src/viewerfiles/ajaxmappane.templ 2007-01-19 19:08:41 UTC (rev 1063)
+++ trunk/MgDev/Web/src/viewerfiles/ajaxmappane.templ 2007-01-20 00:49:25 UTC (rev 1064)
@@ -254,6 +254,7 @@
var minInfoWidth;
var webAgent = '%s';
var mapName = '%s';
+var mapDefinitionName = '%s';
var infoWidth = %s;
var isLegend = %s, legendExpanded = isLegend;
var isProperties = %s, propExpanded = isProperties;
@@ -3065,7 +3066,7 @@
if(cell.loaded == "1")
return 0;
cell.loaded = "1";
- url = webAgent + "?OPERATION=GETTILEIMAGE&VERSION=1.0.0&SESSION=" + sessionId + "&MAPNAME=" + encodeComponent(mapName) + "&BASEMAPLAYERGROUPNAME=" + encodeComponent(baseGroups[k]) + "&TILECOL=" + tilex + "&TILEROW=" + tiley + "&SC=" + sci;
+ url = webAgent + "?OPERATION=GETTILEIMAGE&VERSION=2.0.0&SESSION=" + sessionId + "&MAPDEFINITION=" + encodeComponent(mapDefinitionName) + "&BASEMAPLAYERGROUPNAME=" + encodeComponent(baseGroups[k]) + "&TILECOL=" + tilex + "&TILEROW=" + tiley + "&SCALEINDEX=" + sci;
tag = '<img id="' + (imgId) + '" width=' + TILECX + ' height=' + TILECY + ' border=0 vspace=0 hspace=0 src="' + url + '" style="visibility: hidden; width: 300px; height: 300px;" onload="OnTileLoaded(\'' + imgId + '\')">';
imgId ++;
cell.innerHTML = tag;
More information about the mapguide-commits
mailing list