[mapguide-commits] r7470 - in sandbox/jng/queryfeatures_v2: Common/MapGuideCommon/Controller Common/MapGuideCommon/Services Server/src/Services/Rendering Server/src/UnitTesting Web/src/HttpHandler
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Fri May 3 13:30:42 PDT 2013
Author: jng
Date: 2013-05-03 13:30:42 -0700 (Fri, 03 May 2013)
New Revision: 7470
Modified:
sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Controller/HtmlController.cpp
sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Controller/HtmlController.h
sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/ProxyRenderingService.cpp
sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/ProxyRenderingService.h
sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/RenderingDefs.h
sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/RenderingService.cpp
sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/RenderingService.h
sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/FeaturePropRenderer.cpp
sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/FeaturePropRenderer.h
sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/OpQueryFeatureProperties.cpp
sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/RenderingOperationFactory.cpp
sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/ServerRenderingService.cpp
sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/ServerRenderingService.h
sandbox/jng/queryfeatures_v2/Server/src/UnitTesting/TestRenderingService.cpp
sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpQueryMapFeatures.cpp
sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpQueryMapFeatures.h
sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpResourceStrings.cpp
sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpResourceStrings.h
Log:
This submission contains the following changes:
- Add a new overload of QueryFeatureProperties to MgRenderingService with an extra parameter (bIncludeFeatureBBOX). If true, each feature will have an extra _MgFeatureBoundingBox property which contains the bounds of the feature (computed from the FeaturePropRenderer)
- Add a new overload of QueryMapFeatures to MgHtmlController, with the following extra parameters:
- requestData: A bitmask indicating what parts of the QueryMapFeatures response we would like
- selectionColor: The color of the inline selection if requested in the requestData bitmask
- selectionFormat: The image format of the inline selection if requested in the requestData bitmask
- Update TestRenderingService::TestCase_QueryFeatures() to actually dump the MgFeatureInformation result to file for manual inspection.
Modified: sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Controller/HtmlController.cpp
===================================================================
--- sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Controller/HtmlController.cpp 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Controller/HtmlController.cpp 2013-05-03 20:30:42 UTC (rev 7470)
@@ -16,7 +16,13 @@
//
#include "MapGuideCommon.h"
+#include "Base64.h"
+#define REQUEST_ATTRIBUTES 1
+#define REQUEST_INLINE_SELECTION 2
+#define REQUEST_TOOLTIP 4
+#define REQUEST_HYPERLINK 8
+
//////////////////////////////////////////////////////////////////
// Construct a MgHtmlController object
//
@@ -216,6 +222,175 @@
}
//////////////////////////////////////////////////////////////////
+// Processes a QueryMapFeatures request from the Viewer
+//
+MgByteReader* MgHtmlController::QueryMapFeatures(
+ CREFSTRING mapName,
+ MgStringCollection* layerNames,
+ MgGeometry* selectionGeometry,
+ INT32 selectionVariant,
+ CREFSTRING featureFilter,
+ INT32 maxFeatures,
+ bool persist,
+ INT32 layerAttributeFilter,
+ INT32 requestData,
+ CREFSTRING selectionColor,
+ CREFSTRING selectionFormat)
+{
+ Ptr<MgByteReader> result;
+ Ptr<MgFeatureInformation> featureInfo;
+ Ptr<MgBatchPropertyCollection> attributes;
+ Ptr<MgByteReader> inlineSelectionImg;
+ Ptr<MgSelection> newSelection;
+
+ // Create a Resource Service instance
+ Ptr<MgResourceService> resourceService = (MgResourceService*)GetService(MgServiceType::ResourceService);
+
+ // Create MgMap
+ Ptr<MgMap> map = new MgMap();
+ map->Open(resourceService, mapName);
+
+ // Make sure we clear any track changes - these are not applicable for AJAX.
+ Ptr<MgNamedCollection> changeLists = map->GetChangeLists();
+ if (changeLists->GetCount() > 0)
+ {
+ map->ClearChanges();
+ map->Save(resourceService);
+ }
+
+ // Create Proxy Rendering Service instance
+ Ptr<MgRenderingService> service = (MgRenderingService*)(GetService(MgServiceType::RenderingService));
+
+ //Any of these bits requires a QueryFeatures() call
+ if (((requestData & REQUEST_INLINE_SELECTION) == REQUEST_INLINE_SELECTION) ||
+ ((requestData & REQUEST_TOOLTIP) == REQUEST_TOOLTIP) ||
+ ((requestData & REQUEST_HYPERLINK) == REQUEST_HYPERLINK))
+ {
+ // Call the C++ API
+ featureInfo = service->QueryFeatures(map, layerNames, selectionGeometry,
+ selectionVariant, featureFilter, maxFeatures, layerAttributeFilter);
+ }
+
+ if (persist)
+ {
+ //save the selection set in the session repository
+ Ptr<MgSelection> selection;
+ if (NULL != featureInfo.p)
+ selection = featureInfo->GetSelection();
+ if(!selection)
+ selection = new MgSelection(map);
+ selection->Save(resourceService, mapName);
+ newSelection = SAFE_ADDREF(selection.p);
+ }
+
+ // Render an image of this selection if requested
+ if (((requestData & REQUEST_INLINE_SELECTION) == REQUEST_INLINE_SELECTION) && NULL != newSelection.p)
+ {
+ try
+ {
+ Ptr<MgColor> selColor = new MgColor(selectionColor);
+ Ptr<MgRenderingOptions> renderOpts = new MgRenderingOptions(selectionFormat, MgRenderingOptions::RenderLayers | MgRenderingOptions::RenderSelection | MgRenderingOptions::KeepSelection, selColor);
+ inlineSelectionImg = service->RenderDynamicOverlay(map, newSelection, renderOpts);
+ }
+ catch (MgException* ex)
+ {
+ SAFE_RELEASE(ex);
+ }
+ }
+
+ if ((requestData & REQUEST_ATTRIBUTES) == REQUEST_ATTRIBUTES)
+ {
+ attributes = service->QueryFeatureProperties(map, layerNames, selectionGeometry, selectionVariant, L"", -1, layerAttributeFilter, true);
+ }
+
+ result = CollectQueryMapFeaturesResult(requestData, featureInfo, newSelection, attributes, inlineSelectionImg);
+
+ // Return XML
+ return result.Detach();
+}
+
+MgByteReader* MgHtmlController::CollectQueryMapFeaturesResult(INT32 requestData,
+ MgFeatureInformation* featInfo,
+ MgSelection* selectionSet,
+ MgBatchPropertyCollection* attributes,
+ MgByteReader* inlineSelection)
+{
+ STRING xml;
+ STRING tooltip;
+ STRING hyperlink;
+ STRING xmlSelection = selectionSet? selectionSet->ToXml(false): L"";
+
+ if (NULL != featInfo)
+ {
+ tooltip = featInfo->GetTooltip();
+ hyperlink = featInfo->GetHyperlink();
+ }
+
+ // TODO: define a schema for this XML
+ xml.append(L"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<FeatureInformation>\n");
+
+ size_t len = xmlSelection.length();
+ if(len > 0)
+ {
+ xml.reserve(len + 2048);
+ xml.append(xmlSelection);
+ }
+ else
+ {
+ xml.reserve(2048);
+ xml.append(L"<FeatureSet />\n");
+ }
+
+ if (((requestData & REQUEST_TOOLTIP) == REQUEST_TOOLTIP) && !tooltip.empty())
+ {
+ xml.append(L"<Tooltip>");
+ xml.append(MgUtil::ReplaceEscapeCharInXml(tooltip));
+ xml.append(L"</Tooltip>\n");
+ }
+ else
+ xml.append(L"<Tooltip />\n");
+
+ if (((requestData & REQUEST_HYPERLINK) == REQUEST_HYPERLINK) && !hyperlink.empty())
+ {
+ xml.append(L"<Hyperlink>");
+ xml.append(MgUtil::ReplaceEscapeCharInXml(hyperlink));
+ xml.append(L"</Hyperlink>\n");
+ }
+ else
+ xml.append(L"<Hyperlink />\n");
+
+ if (((requestData & REQUEST_INLINE_SELECTION) == REQUEST_INLINE_SELECTION) && NULL != inlineSelection)
+ {
+ xml.append(L"<InlineSelectionImage>\n");
+ Ptr<MgByteSink> imgSink = new MgByteSink(inlineSelection);
+ Ptr<MgByte> imgBuffer = imgSink->ToBuffer();
+ string b64;
+ b64.resize(len, '\0');
+ Base64::Encode((char*)b64.c_str(), (const unsigned char*)imgBuffer->Bytes(), imgBuffer->GetLength());
+ STRING wb64 = MgUtil::MultiByteToWideChar(b64);
+ xml.append(L"</InlineSelectionImage>\n");
+ }
+ else
+ xml.append(L"<InlineSelectionImage />\n");
+
+ if (((requestData & REQUEST_ATTRIBUTES) == REQUEST_ATTRIBUTES) && NULL != attributes)
+ {
+ xml.append(L"<Attributes>\n");
+ Ptr<MgByteReader> attrXml = attributes->ToXml();
+ xml.append(attrXml->ToString());
+ xml.append(L"</Attributes>\n");
+ }
+ else
+ xml.append(L"<Attributes />\n");
+
+ xml.append(L"</FeatureInformation>\n");
+
+ string xmlDoc = MgUtil::WideCharToMultiByte(xml);
+ STRING mimeType = L"text/xml";
+ return MgUtil::GetByteReader(xmlDoc, &mimeType);
+}
+
+//////////////////////////////////////////////////////////////////
// Generates JavaScript code that can be embedded in an HTML response
// to a non-viewer initiated web application request. The returned code
// forces a synchronization of the client-side view with any changes made to the Map Model.
Modified: sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Controller/HtmlController.h
===================================================================
--- sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Controller/HtmlController.h 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Controller/HtmlController.h 2013-05-03 20:30:42 UTC (rev 7470)
@@ -112,7 +112,7 @@
//////////////////////////////////////////////////////////////////
/// \brief
- /// Processes a DescribeMapFeatures request from the Viewer
+ /// Processes a QueryMapFeatures request from the Viewer
///
/// \param mapName
/// Name of the map
@@ -142,6 +142,39 @@
//////////////////////////////////////////////////////////////////
/// \brief
+ /// Processes a QueryMapFeatures request from the Viewer
+ ///
+ /// \param mapName
+ /// Name of the map
+ /// \param layer
+ /// Layer for which to provide feature descriptions
+ /// \param selectionGeometry
+ /// Geometry defining which features to select
+ /// \param selectionVariant
+ /// Specifies how features are selected
+ /// \param maxFeatures
+ /// Max number of feature descriptions to return
+ /// \param persist
+ /// Indicates if the returned selection set should be persisted in the session repository
+ ///
+ /// \return
+ /// A byte reader containing the feature info
+ ///
+ MgByteReader* QueryMapFeatures(
+ CREFSTRING mapName,
+ MgStringCollection* layerNames,
+ MgGeometry* selectionGeometry,
+ INT32 selectionVariant,
+ CREFSTRING featureFilter,
+ INT32 maxFeatures,
+ bool persist,
+ INT32 layerAttributeFilter,
+ INT32 requestData,
+ CREFSTRING selectionColor,
+ CREFSTRING selectionFormat);
+
+ //////////////////////////////////////////////////////////////////
+ /// \brief
/// Processes a GetLayerImageMap request from the Viewer and returns an image map
/// for the visible features on the specified map layer
///
@@ -236,6 +269,16 @@
//////////////////////////////////////////////////////////////////
/// \brief
+ /// Assembles the composite QueryMapFeatures result
+ ///
+ virtual MgByteReader* CollectQueryMapFeaturesResult(INT32 requestData,
+ MgFeatureInformation* featInfo,
+ MgSelection* selectionSet,
+ MgBatchPropertyCollection* attributes,
+ MgByteReader* inlineSelection);
+
+ //////////////////////////////////////////////////////////////////
+ /// \brief
/// Dispose this object.
///
/// \return
Modified: sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/ProxyRenderingService.cpp
===================================================================
--- sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/ProxyRenderingService.cpp 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/ProxyRenderingService.cpp 2013-05-03 20:30:42 UTC (rev 7470)
@@ -803,6 +803,72 @@
return (MgBatchPropertyCollection*)cmd.GetReturnValue().val.m_obj;
}
+/////////////////////////////////////////////////////////////////
+/// \brief
+/// The QueryFeatureProperties operation identifies those features that
+/// meet the specified spatial selection criteria. This operation
+/// is used to implement WMS feature info and returns property values
+/// for all features which match the spatial query
+///
+/// \param map
+/// Input
+/// map object containing current state of map.
+/// \param layerNames
+/// Input
+/// Active layer names for which to query features
+/// \param filterGeometry
+/// Input
+/// geometry object specifying the selection area
+/// \param selectionVariant
+/// Input
+/// selection criterion - integer value corresponding to one of
+/// the MgFeatureSpatialOperations values
+/// \param featureFilter
+/// Input
+/// an XML selection string containing the required feature IDs
+/// \param maxFeatures
+/// Input
+/// the maximum number of features to return
+/// \param layerAttributeFilter
+/// Input
+/// bitmask values - 1=Visible, 2=Selectable, 4=HasTooltips
+///
+/// \return
+/// An MgSelection instance identifying the features that meet the
+/// selection criteria. Returns null if no features are identified.
+///
+MgBatchPropertyCollection* MgProxyRenderingService::QueryFeatureProperties(
+ MgMap* map,
+ MgStringCollection* layerNames,
+ MgGeometry* filterGeometry,
+ INT32 selectionVariant,
+ CREFSTRING featureFilter,
+ INT32 maxFeatures,
+ INT32 layerAttributeFilter,
+ bool bIncludeFeatureBBOX)
+{
+ MgCommand cmd;
+ cmd.ExecuteCommand(m_connProp, // Connection
+ MgCommand::knObject, // Return type expected
+ MgRenderingServiceOpId::QueryFeatureProperties2,// Command Code
+ 8, // No of arguments
+ Rendering_Service, // Service Id
+ BUILD_VERSION(2,6,0), // Operation version
+ MgCommand::knObject, map, // Argument#1
+ MgCommand::knObject, layerNames, // Argument#2
+ MgCommand::knObject, filterGeometry, // Argument#3
+ MgCommand::knInt32, selectionVariant, // Argument#4
+ MgCommand::knString, &featureFilter, // Argument#5
+ MgCommand::knInt32, maxFeatures, // Argument#6
+ MgCommand::knInt32, layerAttributeFilter, // Argument#7
+ MgCommand::knInt8, (INT8)bIncludeFeatureBBOX, // Argument#8
+ MgCommand::knNone); // End of arguments
+
+ SetWarning(cmd.GetWarningObject());
+
+ return (MgBatchPropertyCollection*)cmd.GetReturnValue().val.m_obj;
+}
+
//////////////////////////////////////////////////////////////////
/// \brief
/// Sets the connection properties for the Proxy Service. This
@@ -937,4 +1003,4 @@
SetWarning(cmd.GetWarningObject());
return (MgByteReader*)cmd.GetReturnValue().val.m_obj;
-}
+}
\ No newline at end of file
Modified: sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/ProxyRenderingService.h
===================================================================
--- sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/ProxyRenderingService.h 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/ProxyRenderingService.h 2013-05-03 20:30:42 UTC (rev 7470)
@@ -669,6 +669,50 @@
bool bKeepSelection,
ProfileRenderMapResult* profileRenderMapResult);
+ /////////////////////////////////////////////////////////////////
+ /// \brief
+ /// The QueryFeatureProperties operation identifies those features that
+ /// meet the specified spatial selection criteria. This operation
+ /// is used to implement WMS feature info and returns property values
+ /// for all features which match the spatial query
+ ///
+ /// \param map
+ /// Input
+ /// map object containing current state of map.
+ /// \param layerNames
+ /// Input
+ /// Active layer names for which to query features
+ /// \param filterGeometry
+ /// Input
+ /// geometry object specifying the selection area
+ /// \param selectionVariant
+ /// Input
+ /// selection criterion - integer value corresponding to one of
+ /// the MgFeatureSpatialOperations values
+ /// \param featureFilter
+ /// Input
+ /// an XML selection string containing the required feature IDs
+ /// \param maxFeatures
+ /// Input
+ /// the maximum number of features to return
+ /// \param layerAttributeFilter
+ /// Input
+ /// bitmask values - 1=Visible, 2=Selectable, 4=HasTooltips
+ ///
+ /// \return
+ /// An MgSelection instance identifying the features that meet the
+ /// selection criteria. Returns null if no features are identified.
+ ///
+ virtual MgBatchPropertyCollection* QueryFeatureProperties(
+ MgMap* map,
+ MgStringCollection* layerNames,
+ MgGeometry* filterGeometry,
+ INT32 selectionVariant,
+ CREFSTRING featureFilter,
+ INT32 maxFeatures,
+ INT32 layerAttributeFilter,
+ bool bIncludeFeatureBBOX);
+
protected:
//////////////////////////////////////////////////////////////////
Modified: sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/RenderingDefs.h
===================================================================
--- sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/RenderingDefs.h 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/RenderingDefs.h 2013-05-03 20:30:42 UTC (rev 7470)
@@ -39,6 +39,7 @@
static const int RenderMap4 = 0x1111E90B;
static const int RenderDynamicOverlay2 = 0x1111E90C;
static const int RenderMap5 = 0x1111E90D;
+ static const int QueryFeatureProperties2 = 0x1111E90E;
};
/// \endcond
Modified: sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/RenderingService.cpp
===================================================================
--- sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/RenderingService.cpp 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/RenderingService.cpp 2013-05-03 20:30:42 UTC (rev 7470)
@@ -48,3 +48,16 @@
{
delete this;
}
+
+MgBatchPropertyCollection* MgRenderingService::QueryFeatureProperties(
+ MgMap* map,
+ MgStringCollection* layerNames,
+ MgGeometry* filterGeometry,
+ INT32 selectionVariant,
+ CREFSTRING featureFilter,
+ INT32 maxFeatures,
+ INT32 layerAttributeFilter,
+ bool bIncludeFeatureBBOX)
+{
+ throw new MgNotImplementedException(L"MgRenderingService.QueryFeatureProperties", __LINE__, __WFILE__, NULL, L"", NULL);
+}
\ No newline at end of file
Modified: sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/RenderingService.h
===================================================================
--- sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/RenderingService.h 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Common/MapGuideCommon/Services/RenderingService.h 2013-05-03 20:30:42 UTC (rev 7470)
@@ -671,6 +671,50 @@
bool bKeepSelection,
ProfileRenderMapResult* profileRenderMapResult) = 0;
+ /////////////////////////////////////////////////////////////////
+ /// \brief
+ /// The QueryFeatureProperties operation identifies those features that
+ /// meet the specified spatial selection criteria. This operation
+ /// is used to implement WMS feature info and returns property values
+ /// for all features which match the spatial query
+ ///
+ /// \param map
+ /// Input
+ /// map object containing current state of map.
+ /// \param layerNames
+ /// Input
+ /// Active layer names for which to query features
+ /// \param filterGeometry
+ /// Input
+ /// geometry object specifying the selection area
+ /// \param selectionVariant
+ /// Input
+ /// selection criterion - integer value corresponding to one of
+ /// the MgFeatureSpatialOperations values
+ /// \param featureFilter
+ /// Input
+ /// an XML selection string containing the required feature IDs
+ /// \param maxFeatures
+ /// Input
+ /// the maximum number of features to return
+ /// \param layerAttributeFilter
+ /// Input
+ /// bitmask values - 1=Visible, 2=Selectable, 4=HasTooltips
+ ///
+ /// \return
+ /// An MgSelection instance identifying the features that meet the
+ /// selection criteria. Returns null if no features are identified.
+ ///
+ virtual MgBatchPropertyCollection* QueryFeatureProperties(
+ MgMap* map,
+ MgStringCollection* layerNames,
+ MgGeometry* filterGeometry,
+ INT32 selectionVariant,
+ CREFSTRING featureFilter,
+ INT32 maxFeatures,
+ INT32 layerAttributeFilter,
+ bool bIncludeFeatureBBOX);
+
protected:
/////////////////////////////////////////////////////////////////
Modified: sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/FeaturePropRenderer.cpp
===================================================================
--- sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/FeaturePropRenderer.cpp 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/FeaturePropRenderer.cpp 2013-05-03 20:30:42 UTC (rev 7470)
@@ -21,17 +21,22 @@
#include "FeaturePropRenderer.h"
#include "RS_FeatureReader.h"
+#define SPECIAL_PROP_LAYER_NAME L"_MgLayerName"
+#define SPECIAL_PROP_BOUNDING_BOX L"_MgFeatureBoundingBox"
-FeaturePropRenderer::FeaturePropRenderer(MgSelection* selection, int maxFeatures, double mapScale)
+FeaturePropRenderer::FeaturePropRenderer(MgSelection* selection, int maxFeatures, double mapScale, bool bIncludeFeatureBBOX)
: FeatureInfoRenderer(selection, maxFeatures, mapScale)
{
m_featprops = new MgBatchPropertyCollection();
+ m_currentFeature = NULL;
+ m_bIncludeFeatureBBOX = bIncludeFeatureBBOX;
}
FeaturePropRenderer::~FeaturePropRenderer()
{
SAFE_RELEASE(m_featprops);
+ SAFE_RELEASE(m_currentFeature);
}
@@ -69,12 +74,21 @@
}
*/
+ SAFE_RELEASE(m_currentFeature);
Ptr<MgPropertyCollection> featureProps = new MgPropertyCollection(true, true);
+ m_currentFeature = SAFE_ADDREF(featureProps.p);
//Add the layer name as a property with a special ID
- Ptr<MgStringProperty> layerNameProperty = new MgStringProperty(L"_MgLayerName", m_layerInfo->name());
+ Ptr<MgStringProperty> layerNameProperty = new MgStringProperty(SPECIAL_PROP_LAYER_NAME, m_layerInfo->name());
featureProps->Add(layerNameProperty);
+ //Add bounding box if we're instructed to
+ if (m_bIncludeFeatureBBOX)
+ {
+ Ptr<MgStringProperty> boundingBoxProperty = new MgStringProperty(SPECIAL_PROP_BOUNDING_BOX, L"");
+ featureProps->Add(boundingBoxProperty);
+ }
+
//for each property in the property mapping, add to the
//return property collection
@@ -109,3 +123,78 @@
// set to false to disable processing of hyperlinks
return false;
}
+
+void FeaturePropRenderer::ProcessPolygon(LineBuffer* lb,
+ RS_FillStyle& fill)
+{
+ if (!m_bIncludeFeatureBBOX)
+ return;
+
+ const RS_Bounds& featBounds = lb->bounds();
+ Ptr<MgStringProperty> bbox = dynamic_cast<MgStringProperty*>(m_currentFeature->GetItem(SPECIAL_PROP_BOUNDING_BOX));
+ STRING val;
+ STRING buf;
+ MgUtil::DoubleToString(featBounds.minx, buf);
+ val += buf;
+ MgUtil::DoubleToString(featBounds.miny, buf);
+ val += L" ";
+ val += buf;
+ MgUtil::DoubleToString(featBounds.maxx, buf);
+ val += L" ";
+ val += buf;
+ MgUtil::DoubleToString(featBounds.maxy, buf);
+ val += L" ";
+ val += buf;
+ bbox->SetValue(val);
+}
+
+void FeaturePropRenderer::ProcessPolyline(LineBuffer* lb,
+ RS_LineStroke& lsym)
+{
+ if (!m_bIncludeFeatureBBOX)
+ return;
+
+ const RS_Bounds& featBounds = lb->bounds();
+ Ptr<MgStringProperty> bbox = dynamic_cast<MgStringProperty*>(m_currentFeature->GetItem(SPECIAL_PROP_BOUNDING_BOX));
+ STRING val;
+ STRING buf;
+ MgUtil::DoubleToString(featBounds.minx, buf);
+ val += buf;
+ MgUtil::DoubleToString(featBounds.miny, buf);
+ val += L" ";
+ val += buf;
+ MgUtil::DoubleToString(featBounds.maxx, buf);
+ val += L" ";
+ val += buf;
+ MgUtil::DoubleToString(featBounds.maxy, buf);
+ val += L" ";
+ val += buf;
+ bbox->SetValue(val);
+}
+
+void FeaturePropRenderer::ProcessMarker(LineBuffer* lb,
+ RS_MarkerDef& mdef,
+ bool allowOverpost,
+ RS_Bounds* bounds)
+{
+ if (!m_bIncludeFeatureBBOX)
+ return;
+
+ //Should we inflate this a bit to represent an actual box?
+ const RS_Bounds& featBounds = lb->bounds();
+ Ptr<MgStringProperty> bbox = dynamic_cast<MgStringProperty*>(m_currentFeature->GetItem(SPECIAL_PROP_BOUNDING_BOX));
+ STRING val;
+ STRING buf;
+ MgUtil::DoubleToString(featBounds.minx, buf);
+ val += buf;
+ MgUtil::DoubleToString(featBounds.miny, buf);
+ val += L" ";
+ val += buf;
+ MgUtil::DoubleToString(featBounds.maxx, buf);
+ val += L" ";
+ val += buf;
+ MgUtil::DoubleToString(featBounds.maxy, buf);
+ val += L" ";
+ val += buf;
+ bbox->SetValue(val);
+}
\ No newline at end of file
Modified: sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/FeaturePropRenderer.h
===================================================================
--- sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/FeaturePropRenderer.h 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/FeaturePropRenderer.h 2013-05-03 20:30:42 UTC (rev 7470)
@@ -31,7 +31,8 @@
public:
FeaturePropRenderer(MgSelection* selection,
int maxFeatures,
- double mapScale);
+ double mapScale,
+ bool bIncludeFeatureBBOX);
virtual ~FeaturePropRenderer();
///////////////////////////////////
@@ -49,6 +50,17 @@
virtual bool SupportsTooltips();
virtual bool SupportsHyperlinks();
+ virtual void ProcessPolygon(LineBuffer* lb,
+ RS_FillStyle& fill);
+
+ virtual void ProcessPolyline(LineBuffer* lb,
+ RS_LineStroke& lsym);
+
+ virtual void ProcessMarker(LineBuffer* lb,
+ RS_MarkerDef& mdef,
+ bool allowOverpost,
+ RS_Bounds* bounds = NULL);
+
MgBatchPropertyCollection* GetProperties()
{
return SAFE_ADDREF(m_featprops);
@@ -56,6 +68,8 @@
private:
MgBatchPropertyCollection* m_featprops;
+ MgPropertyCollection* m_currentFeature;
+ bool m_bIncludeFeatureBBOX;
};
#endif
Modified: sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/OpQueryFeatureProperties.cpp
===================================================================
--- sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/OpQueryFeatureProperties.cpp 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/OpQueryFeatureProperties.cpp 2013-05-03 20:30:42 UTC (rev 7470)
@@ -60,7 +60,7 @@
ACE_ASSERT(m_stream != NULL);
- if (7 == m_packet.m_NumArguments)
+ if (7 == m_packet.m_NumArguments || 8 == m_packet.m_NumArguments)
{
Ptr<MgMap> map = (MgMap*)m_stream->GetObject();
Ptr<MgResourceIdentifier> resource = map->GetResourceId();
@@ -81,6 +81,11 @@
INT32 layerAttributeFilter = 3;
m_stream->GetInt32(layerAttributeFilter);
+ bool bIncludeFeatureBBOX = false;
+ if (8 == m_packet.m_NumArguments)
+ {
+ m_stream->GetBoolean(bIncludeFeatureBBOX);
+ }
BeginExecution();
MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
@@ -97,14 +102,26 @@
MG_LOG_OPERATION_MESSAGE_ADD_INT32(maxFeatures);
MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
MG_LOG_OPERATION_MESSAGE_ADD_INT32(layerAttributeFilter);
+ if (8 == m_packet.m_NumArguments)
+ {
+ MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+ MG_LOG_OPERATION_MESSAGE_ADD_BOOL(bIncludeFeatureBBOX);
+ }
MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
Validate();
- Ptr<MgBatchPropertyCollection> info =
- m_service->QueryFeatureProperties(map, layerNames, geom, selectionVariant,
- featureFilter, maxFeatures, layerAttributeFilter);
-
+ Ptr<MgBatchPropertyCollection> info;
+ if (8 == m_packet.m_NumArguments)
+ {
+ info = m_service->QueryFeatureProperties(map, layerNames, geom, selectionVariant,
+ featureFilter, maxFeatures, layerAttributeFilter, bIncludeFeatureBBOX);
+ }
+ else
+ {
+ info = m_service->QueryFeatureProperties(map, layerNames, geom, selectionVariant,
+ featureFilter, maxFeatures, layerAttributeFilter);
+ }
EndExecution(info);
}
else
Modified: sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/RenderingOperationFactory.cpp
===================================================================
--- sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/RenderingOperationFactory.cpp 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/RenderingOperationFactory.cpp 2013-05-03 20:30:42 UTC (rev 7470)
@@ -180,6 +180,17 @@
L"MgRenderingOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
}
break;
+ case MgRenderingServiceOpId::QueryFeatureProperties2:
+ switch (VERSION_NO_PHASE(operationVersion))
+ {
+ case VERSION_SUPPORTED(2,6):
+ handler.reset(new MgOpQueryFeatureProperties());
+ break;
+ default:
+ throw new MgInvalidOperationVersionException(
+ L"MgRenderingOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+ break;
case MgRenderingServiceOpId::RenderMapLegend:
switch (VERSION_NO_PHASE(operationVersion))
{
Modified: sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/ServerRenderingService.cpp
===================================================================
--- sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/ServerRenderingService.cpp 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/ServerRenderingService.cpp 2013-05-03 20:30:42 UTC (rev 7470)
@@ -864,10 +864,9 @@
INT32 maxFeatures)
{
// Call updated QueryFeatureProperties API
- return QueryFeatureProperties(map, layerNames, filterGeometry, selectionVariant, L"", maxFeatures, 3 /*visible and selectable*/);
+ return QueryFeatureProperties(map, layerNames, filterGeometry, selectionVariant, L"", maxFeatures, 3 /*visible and selectable*/, false);
}
-
///////////////////////////////////////////////////////////////////////////////
MgBatchPropertyCollection* MgServerRenderingService::QueryFeatureProperties(MgMap* map,
MgStringCollection* layerNames,
@@ -877,6 +876,19 @@
INT32 maxFeatures,
INT32 layerAttributeFilter)
{
+ return QueryFeatureProperties(map, layerNames, filterGeometry, selectionVariant, L"", maxFeatures, layerAttributeFilter, false);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+MgBatchPropertyCollection* MgServerRenderingService::QueryFeatureProperties(MgMap* map,
+ MgStringCollection* layerNames,
+ MgGeometry* filterGeometry,
+ INT32 selectionVariant, // Within, Touching, Topmost
+ CREFSTRING featureFilter,
+ INT32 maxFeatures,
+ INT32 layerAttributeFilter,
+ bool bIncludeFeatureBBOX)
+{
Ptr<MgBatchPropertyCollection> ret;
MG_TRY()
@@ -886,7 +898,7 @@
maxFeatures = INT_MAX;
Ptr<MgSelection> sel; //TODO: do we need this for this API? new MgSelection(map);
- FeaturePropRenderer fpr(sel, maxFeatures, map->GetViewScale());
+ FeaturePropRenderer fpr(sel, maxFeatures, map->GetViewScale(), bIncludeFeatureBBOX);
RenderForSelection(map, layerNames, filterGeometry, selectionVariant, featureFilter, maxFeatures, layerAttributeFilter, &fpr);
Modified: sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/ServerRenderingService.h
===================================================================
--- sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/ServerRenderingService.h 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Server/src/Services/Rendering/ServerRenderingService.h 2013-05-03 20:30:42 UTC (rev 7470)
@@ -173,6 +173,16 @@
INT32 maxFeatures,
INT32 layerAttributeFilter);
+ virtual MgBatchPropertyCollection* QueryFeatureProperties(
+ MgMap* map,
+ MgStringCollection* layerNames,
+ MgGeometry* filterGeometry,
+ INT32 selectionVariant,
+ CREFSTRING featureFilter,
+ INT32 maxFeatures,
+ INT32 layerAttributeFilter,
+ bool bIncludeFeatureBBOX);
+
private:
// used for tile generation
MgByteReader* RenderTile(MgMap* map,
Modified: sandbox/jng/queryfeatures_v2/Server/src/UnitTesting/TestRenderingService.cpp
===================================================================
--- sandbox/jng/queryfeatures_v2/Server/src/UnitTesting/TestRenderingService.cpp 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Server/src/UnitTesting/TestRenderingService.cpp 2013-05-03 20:30:42 UTC (rev 7470)
@@ -744,6 +744,10 @@
Ptr<MgPolygon> poly1 = CreateSelectionPolygon(map, 0.3, 0.3);
Ptr<MgFeatureInformation> fi1 = m_svcRendering->QueryFeatures(map, layerNames1, poly1, MgFeatureSpatialOperations::Within, -1);
+ Ptr<MgByteReader> br1 = fi1->ToXml();
+ Ptr<MgByteSink> sink1 = new MgByteSink(br1);
+ sink1->ToFile(L"../UnitTestFiles/QueryFeatures75k.xml");
+
// call the API using a scale of 12000
map->SetViewScale(12000.0);
@@ -752,6 +756,10 @@
layerNames2->Add(L"Parcels");
Ptr<MgPolygon> poly2 = CreateSelectionPolygon(map, 0.05, 0.05);
Ptr<MgFeatureInformation> fi2 = m_svcRendering->QueryFeatures(map, layerNames2, poly2, MgFeatureSpatialOperations::Within, -1);
+
+ Ptr<MgByteReader> br2 = fi2->ToXml();
+ Ptr<MgByteSink> sink2 = new MgByteSink(br2);
+ sink2->ToFile(L"../UnitTestFiles/QueryFeatures12k.xml");
}
catch (MgException* e)
{
Modified: sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpQueryMapFeatures.cpp
===================================================================
--- sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpQueryMapFeatures.cpp 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpQueryMapFeatures.cpp 2013-05-03 20:30:42 UTC (rev 7470)
@@ -70,6 +70,17 @@
// Get the feature filter
m_featureFilter = params->GetParameterValue(MgHttpResourceStrings::reqRenderingFeatureFilter);
+
+ INT32 version = m_userInfo->GetApiVersion();
+ if (version == MG_API_VERSION(2,6,0))
+ {
+ m_requestData = 1 | 2 | 4 | 8;
+ STRING strReqData = params->GetParameterValue(MgHttpResourceStrings::reqRenderingRequestData);
+ if (strReqData.empty())
+ m_requestData = MgUtil::StringToInt32(strReqData);
+ m_selectionFormat = params->GetParameterValue(MgHttpResourceStrings::reqRenderingSelectionFormat);
+ m_selectionColor = params->GetParameterValue(MgHttpResourceStrings::reqRenderingSelectionColor);
+ }
}
/// <summary>
@@ -120,9 +131,17 @@
// Call the HTML controller to process the request
MgHtmlController controller(m_siteConn);
- Ptr<MgByteReader> featureDescriptionInfo = controller.QueryMapFeatures(
- m_mapName, layerNames, filterGeometry, selectionVariant, m_featureFilter, m_maxFeatures, m_persist, m_layerAttributeFilter);
-
+ Ptr<MgByteReader> featureDescriptionInfo;
+
+ INT32 version = m_userInfo->GetApiVersion();
+ if (version == MG_API_VERSION(1, 0, 0))
+ {
+ featureDescriptionInfo = controller.QueryMapFeatures(m_mapName, layerNames, filterGeometry, selectionVariant, m_featureFilter, m_maxFeatures, m_persist, m_layerAttributeFilter);
+ }
+ else if (version == MG_API_VERSION(2, 6, 0))
+ {
+ featureDescriptionInfo = controller.QueryMapFeatures(m_mapName, layerNames, filterGeometry, selectionVariant, m_featureFilter, m_maxFeatures, m_persist, m_layerAttributeFilter, m_requestData, m_selectionColor, m_selectionFormat);
+ }
//Convert to alternate response format, if necessary
ProcessFormatConversion(featureDescriptionInfo);
@@ -131,3 +150,24 @@
MG_HTTP_HANDLER_CATCH_AND_THROW_EX(L"MgHttpQueryMapFeatures.Execute")
}
+
+/// <summary>
+/// This method is responsible for checking if
+/// a valid version was given
+/// </summary>
+/// <returns>Returns nothing</returns>
+void MgHttpQueryMapFeatures::ValidateOperationVersion()
+{
+ MG_HTTP_HANDLER_TRY()
+
+ // There are multiple supported versions
+ INT32 version = m_userInfo->GetApiVersion();
+ if (version != MG_API_VERSION(1,0,0) &&
+ version != MG_API_VERSION(2,6,0))
+ {
+ throw new MgInvalidOperationVersionException(
+ L"MgHttpQueryMapFeatures.ValidateOperationVersion", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ MG_HTTP_HANDLER_CATCH_AND_THROW(L"MgHttpQueryMapFeatures.ValidateOperationVersion");
+}
Modified: sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpQueryMapFeatures.h
===================================================================
--- sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpQueryMapFeatures.h 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpQueryMapFeatures.h 2013-05-03 20:30:42 UTC (rev 7470)
@@ -51,6 +51,9 @@
/// </returns>
MgRequestClassification GetRequestClassification() { return MgHttpRequestResponseHandler::mrcViewer; }
+protected:
+ virtual void ValidateOperationVersion();
+
private:
STRING m_mapName;
STRING m_layerNames;
@@ -60,6 +63,11 @@
INT32 m_maxFeatures;
INT32 m_layerAttributeFilter;
bool m_persist;
+
+ //New for 2.6
+ INT32 m_requestData;
+ STRING m_selectionColor;
+ STRING m_selectionFormat;
};
#endif // _FS_DESCRIBE_MAP_FEATURES_H
Modified: sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpResourceStrings.cpp
===================================================================
--- sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpResourceStrings.cpp 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpResourceStrings.cpp 2013-05-03 20:30:42 UTC (rev 7470)
@@ -230,6 +230,9 @@
const STRING MgHttpResourceStrings::reqRenderingSelectionVariant = L"SELECTIONVARIANT";
const STRING MgHttpResourceStrings::reqRenderingGeometry = L"GEOMETRY";
const STRING MgHttpResourceStrings::reqRenderingFeatureFilter = L"FEATUREFILTER";
+const STRING MgHttpResourceStrings::reqRenderingRequestData = L"REQUESTDATA";
+const STRING MgHttpResourceStrings::reqRenderingSelectionFormat = L"REQUESTDATA";
+
const STRING MgHttpResourceStrings::reqRenderingBaseMapLayerGroupName = L"BASEMAPLAYERGROUPNAME";
const STRING MgHttpResourceStrings::reqRenderingTileColumn = L"TILECOL";
const STRING MgHttpResourceStrings::reqRenderingTileRow = L"TILEROW";
Modified: sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpResourceStrings.h
===================================================================
--- sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpResourceStrings.h 2013-05-02 10:57:56 UTC (rev 7469)
+++ sandbox/jng/queryfeatures_v2/Web/src/HttpHandler/HttpResourceStrings.h 2013-05-03 20:30:42 UTC (rev 7470)
@@ -177,6 +177,8 @@
static const STRING reqRenderingClip;
static const STRING reqRenderingBehavior;
static const STRING reqRenderingSelectionColor;
+ static const STRING reqRenderingRequestData;
+ static const STRING reqRenderingSelectionFormat;
// PREDEFINED TILE REQUEST PARAMETERS
static const STRING reqTileMapDefinition;
More information about the mapguide-commits
mailing list