[mapguide-commits] r7489 - sandbox/jng/createruntimemap/Web/src/HttpHandler
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Fri May 10 06:50:13 PDT 2013
Author: jng
Date: 2013-05-10 06:50:13 -0700 (Fri, 10 May 2013)
New Revision: 7489
Modified:
sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpCreateRuntimeMap.cpp
sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpCreateRuntimeMap.h
sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpResourceStrings.cpp
sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpResourceStrings.h
Log:
This submission contains the following changes:
- Use 2.6.0 for operation version
- Support a REQUESTEDFEATURES bitmask. The idea being depending on the bits set, the user may get back extra information about the map (and its layers/groups) in the response. If this mask is not set, the response is minimal enough to create a basic OpenLayers map from. This bitmask allows for scalability in our response, with the idea of replicating (and hopefully replacing) the functionality of LoadMap.php/LoadScaleRanges.php in Fusion if all the bits are set. The bits available are:
- 1: Includes the layer/group structure
- 2: Includes vector layer icons as inline base64 images (still work to do here. Only the scale ranges are outputted at the moment). Does nothing if the layer/group structure bit value is not set.
- 4: Includes feature source information for each layer. Does nothing if the layer/group structure bit value is not set.
Modified: sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpCreateRuntimeMap.cpp
===================================================================
--- sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpCreateRuntimeMap.cpp 2013-05-09 13:41:59 UTC (rev 7488)
+++ sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpCreateRuntimeMap.cpp 2013-05-10 13:50:13 UTC (rev 7489)
@@ -17,7 +17,12 @@
#include "HttpHandler.h"
#include "HttpCreateRuntimeMap.h"
+#include "VectorLayerDefinition.h"
+#define REQUEST_LAYER_STRUCTURE 1 /* Request layer and group structure */
+#define REQUEST_LAYER_ICONS 2 /* Request layer scale and icon information */
+#define REQUEST_LAYER_FEATURE_SOURCE 4 /* Request information about a layer's feature source */
+
HTTP_IMPLEMENT_CREATE_OBJECT(MgHttpCreateRuntimeMap)
/// <summary>
@@ -36,6 +41,12 @@
Ptr<MgHttpRequestParam> params = hRequest->GetRequestParam();
m_mapDefinition = params->GetParameterValue(MgHttpResourceStrings::reqMappingMapDefinition);
+ STRING mask = params->GetParameterValue(MgHttpResourceStrings::reqMappingRequestedFeatures);
+ if (mask.empty())
+ m_requestDataMask = 0;
+ else
+ m_requestDataMask = MgUtil::StringToInt32(mask);
+ m_iconLimitPerScaleRange = 25;
}
/// <summary>
@@ -101,6 +112,8 @@
sel->Save(resourceService, mapName);
map->Save(resourceService, mapStateId);
+ //TODO: Possible future caching opportunity?
+
std::string xml;
xml.append("<RuntimeMap>\n");
// ------------------------------ Site Version ----------------------------------//
@@ -163,96 +176,98 @@
xml.append("<Extents>\n");
xml.append(sExtents);
xml.append("</Extents>");
- // ------------------------------ Groups ---------------------------------- //
- xml.append("<Groups>\n");
- Ptr<MgLayerGroupCollection> groups = map->GetLayerGroups();
- for (INT32 i = 0; i < groups->GetCount(); i++)
+ // ---------------------- Optional things if requested -------------------- //
+ LayerDefinitionMap layerDefinitionMap;
+ if ((m_requestDataMask & REQUEST_LAYER_STRUCTURE) == REQUEST_LAYER_STRUCTURE)
{
- Ptr<MgLayerGroup> group = groups->GetItem(i);
- //We'll deal with you later
- if (group->GetLayerGroupType() == MgLayerGroupType::BaseMap)
- continue;
+ //Build our LayerDefinition map for code below that requires it
+ if ((m_requestDataMask & REQUEST_LAYER_ICONS) == REQUEST_LAYER_ICONS)
+ {
+ Ptr<MgResourceService> resourceService = (MgResourceService*)CreateService(MgServiceType::ResourceService);
+ Ptr<MgStringCollection> layerIds = new MgStringCollection();
+ Ptr<MgLayerCollection> layers = map->GetLayers();
+ for (INT32 i = 0; i < layers->GetCount(); i++)
+ {
+ Ptr<MgLayerBase> layer = layers->GetItem(i);
+ Ptr<MgResourceIdentifier> ldfId = layer->GetLayerDefinition();
+ layerIds->Add(ldfId->ToString());
+ }
- xml.append("<Group>\n");
- xml.append("<Name>");
- xml.append(MgUtil::WideCharToMultiByte(group->GetName()));
- xml.append("</Name>\n");
- xml.append("<LegendLabel>");
- xml.append(MgUtil::WideCharToMultiByte(group->GetLegendLabel()));
- xml.append("</LegendLabel>\n");
- xml.append("<ObjectId>");
- xml.append(MgUtil::WideCharToMultiByte(group->GetObjectId()));
- xml.append("</ObjectId>\n");
- xml.append("<DisplayInLegend>");
- xml.append(group->GetDisplayInLegend() ? "true" : "false");
- xml.append("</DisplayInLegend>\n");
- xml.append("<ExpandInLegend>");
- xml.append(group->GetExpandInLegend() ? "true" : "false");
- xml.append("</ExpandInLegend>\n");
- xml.append("<Visible>");
- xml.append(group->GetVisible() ? "true" : "false");
- xml.append("</Visible>\n");
- xml.append("<ActuallyVisible>");
- xml.append(group->IsVisible() ? "true" : "false");
- xml.append("</ActuallyVisible>\n");
- Ptr<MgLayerGroup> parent = group->GetGroup();
- if (NULL != parent.p)
+ Ptr<MgStringCollection> layerContents = resourceService->GetResourceContents(layerIds, NULL);
+ for (INT32 i = 0; i < layerIds->GetCount(); i++)
+ {
+ STRING ldfId = layerIds->GetItem(i);
+ STRING content = layerContents->GetItem(i);
+ layerDefinitionMap[ldfId] = MgLayerBase::GetLayerDefinition(content);
+ }
+ }
+
+ // ----------- Some pre-processing before we do groups/layers ------------- //
+ Ptr<MgLayerGroupCollection> groups = map->GetLayerGroups();
+ Ptr<MgLayerCollection> layers = map->GetLayers();
+ for (INT32 i = 0; i < groups->GetCount(); i++)
{
- xml.append("<ParentGroupId>");
- xml.append(MgUtil::WideCharToMultiByte(parent->GetObjectId()));
- xml.append("</ParentGroupId>\n");
+ Ptr<MgLayerGroup> grp = groups->GetItem(i);
+ STRING grpName = grp->GetName();
+ Ptr<MgLayerGroup> parent = grp->GetGroup();
+ if (NULL == parent.p)
+ {
+ m_topLevelGroups.push_back(grp->GetName());
+ }
+ else
+ {
+ STRING parentName = parent->GetName();
+ if (m_groupParentMap.find(parentName) == m_groupParentMap.end())
+ {
+ m_groupParentMap[parentName] = GroupNameList();
+ }
+ m_groupParentMap[parentName].push_back(grpName);
+ }
}
- xml.append("</Group>");
- }
- xml.append("</Groups>");
- // ------------------------------ Layers ---------------------------------- //
- xml.append("<Layers>\n");
- Ptr<MgLayerCollection> layers = map->GetLayers();
- for (INT32 i = 0; i < layers->GetCount(); i++)
- {
- Ptr<MgLayerBase> layer = layers->GetItem(i);
- Ptr<MgLayerGroup> parent = layer->GetGroup();
- //We'll deal with you later
- if (NULL != parent.p && parent->GetLayerGroupType() == MgLayerGroupType::BaseMap)
- continue;
+ for (INT32 i = 0; i < layers->GetCount(); i++)
+ {
+ Ptr<MgLayerBase> layer = layers->GetItem(i);
+ STRING layerName = layer->GetName();
+ Ptr<MgLayerGroup> parent = layer->GetGroup();
+ if (NULL == parent.p)
+ {
+ m_topLevelLayers.push_back(layerName);
+ }
+ else
+ {
+ STRING parentName = parent->GetName();
+ if (m_layerParentMap.find(parentName) == m_layerParentMap.end())
+ {
+ m_layerParentMap[parentName] = LayerNameList();
+ }
+ m_layerParentMap[parentName].push_back(layerName);
+ }
+ }
+ // ------------------------------ Groups ---------------------------------- //
+ for (GroupNameList::iterator it = m_topLevelGroups.begin(); it != m_topLevelGroups.end(); it++)
+ {
+ STRING groupName = (*it);
+ Ptr<MgLayerGroup> group = groups->GetItem(groupName);
+ CreateGroupItem(group, xml, layers, groups, layerDefinitionMap);
+ }
- xml.append("<Layer>\n");
- xml.append("<Name>");
- xml.append(MgUtil::WideCharToMultiByte(layer->GetName()));
- xml.append("</Name>\n");
- xml.append("<LegendLabel>");
- xml.append(MgUtil::WideCharToMultiByte(layer->GetLegendLabel()));
- xml.append("</LegendLabel>\n");
- xml.append("<ObjectId>");
- xml.append(MgUtil::WideCharToMultiByte(layer->GetObjectId()));
- xml.append("</ObjectId>\n");
- xml.append("<DisplayInLegend>");
- xml.append(layer->GetDisplayInLegend() ? "true" : "false");
- xml.append("</DisplayInLegend>\n");
- xml.append("<ExpandInLegend>");
- xml.append(layer->GetExpandInLegend() ? "true" : "false");
- xml.append("</ExpandInLegend>\n");
- xml.append("<Visible>");
- xml.append(layer->GetVisible() ? "true" : "false");
- xml.append("</Visible>\n");
- xml.append("<ActuallyVisible>");
- xml.append(layer->IsVisible() ? "true" : "false");
- xml.append("</ActuallyVisible>\n");
- if (NULL != parent.p)
+ for (LayerNameList::iterator it = m_topLevelLayers.begin(); it != m_topLevelLayers.end(); it++)
{
- xml.append("<ParentGroupId>");
- xml.append(MgUtil::WideCharToMultiByte(parent->GetObjectId()));
- xml.append("</ParentGroupId>\n");
+ STRING layerName = (*it);
+ Ptr<MgLayerBase> layer = layers->GetItem(layerName);
+ CreateLayerItem(layer, xml, layers, layerDefinitionMap);
}
- xml.append("</Layer>");
}
- xml.append("</Layers>");
- // ------------------------------ Tiled Groups ---------------------------------- //
- xml.append("<BaseMapGroups>\n");
- xml.append("</BaseMapGroups>");
-
xml.append("</RuntimeMap>");
+ //Cleanup our LayerDefinition pointers
+ for (LayerDefinitionMap::iterator it = layerDefinitionMap.begin(); it != layerDefinitionMap.end(); it++)
+ {
+ MdfModel::LayerDefinition* ldf = it->second;
+ delete ldf;
+ }
+ layerDefinitionMap.clear();
+
Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)xml.c_str(), (INT32)xml.length());
byteSource->SetMimeType(MgMimeType::Xml);
byteReader = byteSource->GetReader();
@@ -260,4 +275,169 @@
MG_HTTP_HANDLER_CATCH_AND_THROW(L"MgHttpCreateRuntimeMap.BuildRuntimeMapXml")
return byteReader.Detach();
-}
\ No newline at end of file
+}
+
+void MgHttpCreateRuntimeMap::CreateGroupItem(MgLayerGroup* group, std::string& xml, MgLayerCollection* layers, MgLayerGroupCollection* groups, const LayerDefinitionMap& layerDefMap)
+{
+ MG_HTTP_HANDLER_TRY()
+
+ STRING groupName = group->GetName();
+ xml.append("<Group>\n");
+ xml.append("<Name>");
+ xml.append(MgUtil::WideCharToMultiByte(groupName));
+ xml.append("</Name>\n");
+ xml.append("<LegendLabel>");
+ xml.append(MgUtil::WideCharToMultiByte(group->GetLegendLabel()));
+ xml.append("</LegendLabel>\n");
+ xml.append("<ObjectId>");
+ xml.append(MgUtil::WideCharToMultiByte(group->GetObjectId()));
+ xml.append("</ObjectId>\n");
+ xml.append("<DisplayInLegend>");
+ xml.append(group->GetDisplayInLegend() ? "true" : "false");
+ xml.append("</DisplayInLegend>\n");
+ xml.append("<ExpandInLegend>");
+ xml.append(group->GetExpandInLegend() ? "true" : "false");
+ xml.append("</ExpandInLegend>\n");
+ xml.append("<Visible>");
+ xml.append(group->GetVisible() ? "true" : "false");
+ xml.append("</Visible>\n");
+ xml.append("<ActuallyVisible>");
+ xml.append(group->IsVisible() ? "true" : "false");
+ xml.append("</ActuallyVisible>\n");
+ if (m_groupParentMap.find(groupName) != m_groupParentMap.end())
+ {
+ GroupNameList childGroups = m_groupParentMap[groupName];
+ for (GroupNameList::iterator it = childGroups.begin(); it != childGroups.end(); it++)
+ {
+ STRING childGroupName = (*it);
+ Ptr<MgLayerGroup> childGroup = groups->GetItem(childGroupName);
+ //Yes, we're using recursion. Stack overflow would probably only happen
+ //if we have a map with several thousand level deep group hierarchy. So
+ //for all intents and purposes: We're safe.
+ CreateGroupItem(childGroup, xml, layers, groups, layerDefMap);
+ }
+ }
+ if (m_layerParentMap.find(groupName) != m_layerParentMap.end())
+ {
+ LayerNameList childLayers = m_layerParentMap[groupName];
+ for (LayerNameList::iterator it = childLayers.begin(); it != childLayers.end(); it++)
+ {
+ STRING childLayerName = (*it);
+ Ptr<MgLayerBase> childLayer = layers->GetItem(childLayerName);
+ CreateLayerItem(childLayer, xml, layers, layerDefMap);
+ }
+ }
+ xml.append("</Group>");
+
+ MG_HTTP_HANDLER_CATCH_AND_THROW(L"MgHttpCreateRuntimeMap.CreateGroupItem")
+}
+
+void MgHttpCreateRuntimeMap::CreateLayerItem(MgLayerBase* layer, std::string& xml, MgLayerCollection* layers, const LayerDefinitionMap& layerDefMap)
+{
+ MG_HTTP_HANDLER_TRY()
+
+ xml.append("<Layer>\n");
+ xml.append("<Type>");
+ std::string sLayerType;
+ MgUtil::Int32ToString(layer->GetLayerType(), sLayerType);
+ xml.append(sLayerType);
+ xml.append("</Type>\n");
+ xml.append("<LayerDefinition>");
+ Ptr<MgResourceIdentifier> layerDefId = layer->GetLayerDefinition();
+ STRING ldfId = layerDefId->ToString();
+ xml.append(MgUtil::WideCharToMultiByte(ldfId));
+ xml.append("</LayerDefinition>\n");
+ xml.append("<Name>");
+ xml.append(MgUtil::WideCharToMultiByte(layer->GetName()));
+ xml.append("</Name>\n");
+ xml.append("<LegendLabel>");
+ xml.append(MgUtil::WideCharToMultiByte(layer->GetLegendLabel()));
+ xml.append("</LegendLabel>\n");
+ xml.append("<ObjectId>");
+ xml.append(MgUtil::WideCharToMultiByte(layer->GetObjectId()));
+ xml.append("</ObjectId>\n");
+ xml.append("<DisplayInLegend>");
+ xml.append(layer->GetDisplayInLegend() ? "true" : "false");
+ xml.append("</DisplayInLegend>\n");
+ xml.append("<ExpandInLegend>");
+ xml.append(layer->GetExpandInLegend() ? "true" : "false");
+ xml.append("</ExpandInLegend>\n");
+ xml.append("<Visible>");
+ xml.append(layer->GetVisible() ? "true" : "false");
+ xml.append("</Visible>\n");
+ xml.append("<ActuallyVisible>");
+ xml.append(layer->IsVisible() ? "true" : "false");
+ xml.append("</ActuallyVisible>\n");
+ // ----------------------- Optional things if requested ------------------------- //
+ if ((m_requestDataMask & REQUEST_LAYER_FEATURE_SOURCE) == REQUEST_LAYER_FEATURE_SOURCE)
+ {
+ xml.append("<FeatureSource>\n");
+ xml.append("<ResourceId>");
+ xml.append(MgUtil::WideCharToMultiByte(layer->GetFeatureSourceId()));
+ xml.append("</ResourceId>\n");
+ xml.append("<ClassName>");
+ xml.append(MgUtil::WideCharToMultiByte(layer->GetFeatureClassName()));
+ xml.append("</ClassName>\n");
+ xml.append("<Geometry>");
+ xml.append(MgUtil::WideCharToMultiByte(layer->GetFeatureGeometryName()));
+ xml.append("</Geometry>\n");
+ xml.append("</FeatureSource>\n");
+ }
+ if ((m_requestDataMask & REQUEST_LAYER_ICONS) == REQUEST_LAYER_ICONS)
+ {
+ //Our layer def map is already populated if this mask was set
+ if (layerDefMap.find(ldfId) != layerDefMap.end())
+ {
+ MdfModel::VectorLayerDefinition* vl = dynamic_cast<MdfModel::VectorLayerDefinition*>(layerDefMap.at(ldfId));
+ if (NULL != vl)
+ {
+ MdfModel::VectorScaleRangeCollection* vsrs = vl->GetScaleRanges();
+ for (INT32 i = 0; i < vsrs->GetCount(); i++)
+ {
+ MdfModel::VectorScaleRange* vsr = vsrs->GetAt(i);
+ xml.append("<ScaleRange>\n");
+ xml.append("<MinScale>");
+ std::string sMinScale;
+ MgUtil::DoubleToString(vsr->GetMinScale(), sMinScale);
+ xml.append(sMinScale);
+ xml.append("</MinScale>\n");
+ xml.append("<MaxScale>");
+ std::string sMaxScale;
+ MgUtil::DoubleToString(vsr->GetMaxScale(), sMaxScale);
+ xml.append(sMaxScale);
+ xml.append("</MaxScale>\n");
+ xml.append("</ScaleRange>\n");
+ }
+ }
+ else
+ {
+ xml.append("<ScaleRange/>");
+ }
+ }
+ else
+ xml.append("<ScaleRange/>");
+ }
+ xml.append("</Layer>");
+
+ MG_HTTP_HANDLER_CATCH_AND_THROW(L"MgHttpCreateRuntimeMap.CreateLayerItem")
+}
+
+/// <summary>
+/// This method is responsible for checking if
+/// a valid version was given
+/// </summary>
+/// <returns>Returns nothing</returns>
+void MgHttpCreateRuntimeMap::ValidateOperationVersion()
+{
+ MG_HTTP_HANDLER_TRY()
+
+ // There are multiple supported versions
+ INT32 version = m_userInfo->GetApiVersion();
+ if (version != MG_API_VERSION(2,6,0))
+ {
+ throw new MgInvalidOperationVersionException(
+ L"MgHttpCreateRuntimeMap.ValidateOperationVersion", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ MG_HTTP_HANDLER_CATCH_AND_THROW(L"MgHttpCreateRuntimeMap.ValidateOperationVersion");
+}
Modified: sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpCreateRuntimeMap.h
===================================================================
--- sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpCreateRuntimeMap.h 2013-05-09 13:41:59 UTC (rev 7488)
+++ sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpCreateRuntimeMap.h 2013-05-10 13:50:13 UTC (rev 7489)
@@ -18,6 +18,12 @@
#ifndef _HTTP_CREATE_RUNTIME_MAP_
#define _HTTP_CREATE_RUNTIME_MAP_
+typedef std::map<STRING, MdfModel::LayerDefinition*> LayerDefinitionMap;
+typedef std::list<STRING> LayerNameList;
+typedef std::list<STRING> GroupNameList;
+typedef std::map<STRING, LayerNameList> LayerParentMap;
+typedef std::map<STRING, GroupNameList> GroupParentMap;
+
class MgHttpCreateRuntimeMap : public MgHttpRequestResponseHandler
{
HTTP_DECLARE_CREATE_OBJECT()
@@ -51,10 +57,26 @@
/// </returns>
MgRequestClassification GetRequestClassification() { return MgHttpRequestResponseHandler::mrcViewer; }
+ /// <summary>
+ /// This method is responsible for checking if
+ /// a valid version was given
+ /// </summary>
+ /// <returns>Returns nothing</returns>
+ virtual void ValidateOperationVersion();
+
private:
MgByteReader* BuildRuntimeMapXml(MgResourceIdentifier* mdfId, CREFSTRING mapName);
+ void CreateGroupItem(MgLayerGroup* group, std::string& xml, MgLayerCollection* layers, MgLayerGroupCollection* groups, const LayerDefinitionMap& layerDefMap);
+ void CreateLayerItem(MgLayerBase* layer, std::string& xml, MgLayerCollection* layers, const LayerDefinitionMap& layerDefMap);
STRING m_mapDefinition;
+ INT32 m_requestDataMask;
+ INT32 m_iconLimitPerScaleRange;
+
+ LayerParentMap m_layerParentMap;
+ GroupParentMap m_groupParentMap;
+ LayerNameList m_topLevelLayers;
+ GroupNameList m_topLevelGroups;
};
#endif // _HTTP_CREATE_RUNTIME_MAP_
Modified: sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpResourceStrings.cpp
===================================================================
--- sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpResourceStrings.cpp 2013-05-09 13:41:59 UTC (rev 7488)
+++ sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpResourceStrings.cpp 2013-05-10 13:50:13 UTC (rev 7489)
@@ -217,6 +217,7 @@
const STRING MgHttpResourceStrings::reqMappingFormat = L"FORMAT";
const STRING MgHttpResourceStrings::reqMappingType = L"TYPE";
const STRING MgHttpResourceStrings::reqMappingThemeCategory = L"THEMECATEGORY";
+const STRING MgHttpResourceStrings::reqMappingRequestedFeatures = L"REQUESTEDFEATURES";
// Predefined Rendering Service Request Parameters
const STRING MgHttpResourceStrings::reqRenderingMapDefinition = L"MAPDEFINITION";
Modified: sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpResourceStrings.h
===================================================================
--- sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpResourceStrings.h 2013-05-09 13:41:59 UTC (rev 7488)
+++ sandbox/jng/createruntimemap/Web/src/HttpHandler/HttpResourceStrings.h 2013-05-10 13:50:13 UTC (rev 7489)
@@ -153,6 +153,7 @@
static const STRING reqMappingFormat;
static const STRING reqMappingType;
static const STRING reqMappingThemeCategory;
+ static const STRING reqMappingRequestedFeatures;
// PREDEFINED RENDERING REQUEST PARAMETERS
static const STRING reqRenderingMapDefinition;
More information about the mapguide-commits
mailing list