[mapguide-commits] r9243 - in sandbox/jng/ogc: Common/MapGuideCommon/Services Common/PlatformBase/Services Server/src/Services/Feature Web/src/HttpHandler
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Fri Oct 6 06:49:24 PDT 2017
Author: jng
Date: 2017-10-06 06:49:24 -0700 (Fri, 06 Oct 2017)
New Revision: 9243
Added:
sandbox/jng/ogc/Server/src/Services/Feature/WfsQueryAdapter.cpp
sandbox/jng/ogc/Server/src/Services/Feature/WfsQueryAdapter.h
Modified:
sandbox/jng/ogc/Common/MapGuideCommon/Services/ProxyFeatureService.cpp
sandbox/jng/ogc/Common/MapGuideCommon/Services/ProxyFeatureService.h
sandbox/jng/ogc/Common/PlatformBase/Services/FeatureService.h
sandbox/jng/ogc/Server/src/Services/Feature/FeatureOperationFactory.cpp
sandbox/jng/ogc/Server/src/Services/Feature/Makefile.am
sandbox/jng/ogc/Server/src/Services/Feature/OpGetWfsReader.cpp
sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.cpp
sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.h
sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.vcxproj
sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.vcxproj.filters
sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureServiceBuild.cpp
sandbox/jng/ogc/Web/src/HttpHandler/HttpWfsGetFeature.cpp
sandbox/jng/ogc/Web/src/HttpHandler/ReaderByteSourceImpl.cpp
sandbox/jng/ogc/Web/src/HttpHandler/ReaderByteSourceImpl.h
Log:
Remove the MgLimitingFeatureReader. The reader pooling mechanism that applies to any MgFeatureReader kind of throws a monkey wrench of wanting to limit reader iterations on the server-tier. It is easier to limit the iterations on the web tier instead and just let the server-tier pre-buffer however many configuration-defined results upfront as it already does. As a result, for WFS GetFeature responses in GeoJSON, we now simply house the MgFeatureReader from MgFeatureService::GetWfsReader into a MgReaderByteSourceImpl and add support in this class for max iterations via SetMaxFeatures. This means the maxfeatures parameter of WFS GetFeature now works for GeoJSON output format.
This submission also unifies the base WFS GetFeature reader acquisition logic into a new MgWfsQueryAdapter class. Both GetWfsFeature and GetWfsReader have been refactored to use MgWfsQueryAdapter to set up the base feature reader instead of doing this themselves.
Modified: sandbox/jng/ogc/Common/MapGuideCommon/Services/ProxyFeatureService.cpp
===================================================================
--- sandbox/jng/ogc/Common/MapGuideCommon/Services/ProxyFeatureService.cpp 2017-10-02 22:12:57 UTC (rev 9242)
+++ sandbox/jng/ogc/Common/MapGuideCommon/Services/ProxyFeatureService.cpp 2017-10-06 13:49:24 UTC (rev 9243)
@@ -1478,14 +1478,13 @@
MgStringCollection* requiredProperties,
CREFSTRING srs,
CREFSTRING filter,
- INT32 maxFeatures,
CREFSTRING sortCriteria)
{
MgCommand cmd;
cmd.ExecuteCommand(m_connProp, // Connection
MgCommand::knObject, // Return type expected
MgFeatureServiceOpId::GetWfsReader_Id, // Command Code
- 7, // No of arguments
+ 6, // No of arguments
Feature_Service, // Service Id
BUILD_VERSION(3,3,0), // Operation version
MgCommand::knObject, featureSourceId, // Argument#1
@@ -1493,8 +1492,7 @@
MgCommand::knObject, requiredProperties, // Argument#3
MgCommand::knString, &srs, // Argument#4
MgCommand::knString, &filter, // Argument#5
- MgCommand::knInt32, maxFeatures, // Argument#6
- MgCommand::knString, &sortCriteria, // Argument#7
+ MgCommand::knString, &sortCriteria, // Argument#6
MgCommand::knNone); // End of argument
SetWarning(cmd.GetWarningObject());
Modified: sandbox/jng/ogc/Common/MapGuideCommon/Services/ProxyFeatureService.h
===================================================================
--- sandbox/jng/ogc/Common/MapGuideCommon/Services/ProxyFeatureService.h 2017-10-02 22:12:57 UTC (rev 9242)
+++ sandbox/jng/ogc/Common/MapGuideCommon/Services/ProxyFeatureService.h 2017-10-06 13:49:24 UTC (rev 9243)
@@ -1561,7 +1561,6 @@
MgStringCollection* requiredProperties,
CREFSTRING srs,
CREFSTRING filter,
- INT32 maxFeatures,
CREFSTRING sortCriteria);
////////////////////////////////////////////////////////////////////////////////
Modified: sandbox/jng/ogc/Common/PlatformBase/Services/FeatureService.h
===================================================================
--- sandbox/jng/ogc/Common/PlatformBase/Services/FeatureService.h 2017-10-02 22:12:57 UTC (rev 9242)
+++ sandbox/jng/ogc/Common/PlatformBase/Services/FeatureService.h 2017-10-06 13:49:24 UTC (rev 9243)
@@ -2068,9 +2068,6 @@
/// The spatial reference system in which to return feature geometries
/// \param filter (String/string)
/// An XML string containing the definition for an OGC filter
- /// \param maxFeatures (int)
- /// The maximum number of features to retrieve. If the value is less
- /// than or equal to zero, all features will be retrieved.
/// \param sortCriteria (String/string)
/// A string identifying the sort criteria
///
@@ -2093,7 +2090,6 @@
MgStringCollection* requiredProperties,
CREFSTRING srs,
CREFSTRING filter,
- INT32 maxFeatures,
CREFSTRING sortCriteria) = 0;
////////////////////////////////////////////////////////////////////////////////
Modified: sandbox/jng/ogc/Server/src/Services/Feature/FeatureOperationFactory.cpp
===================================================================
--- sandbox/jng/ogc/Server/src/Services/Feature/FeatureOperationFactory.cpp 2017-10-02 22:12:57 UTC (rev 9242)
+++ sandbox/jng/ogc/Server/src/Services/Feature/FeatureOperationFactory.cpp 2017-10-06 13:49:24 UTC (rev 9243)
@@ -690,11 +690,11 @@
}
break;
- case MgFeatureServiceOpId::AddSavePoint_Id:
- switch (VERSION_NO_PHASE(operationVersion))
+ case MgFeatureServiceOpId::AddSavePoint_Id:
+ switch (VERSION_NO_PHASE(operationVersion))
{
case VERSION_SUPPORTED(1,0):
- handler.reset(new MgOpAddSavePoint());
+ handler.reset(new MgOpAddSavePoint());
break;
default:
throw new MgInvalidOperationVersionException(
@@ -706,7 +706,7 @@
switch (VERSION_NO_PHASE(operationVersion))
{
case VERSION_SUPPORTED(1,0):
- handler.reset(new MgOpRollbackSavePoint());
+ handler.reset(new MgOpRollbackSavePoint());
break;
default:
throw new MgInvalidOperationVersionException(
@@ -715,7 +715,7 @@
break;
case MgFeatureServiceOpId::ReleaseSavePoint_Id:
- switch (VERSION_NO_PHASE(operationVersion))
+ switch (VERSION_NO_PHASE(operationVersion))
{
case VERSION_SUPPORTED(1,0):
handler.reset(new MgOpReleaseSavePoint());
Modified: sandbox/jng/ogc/Server/src/Services/Feature/Makefile.am
===================================================================
--- sandbox/jng/ogc/Server/src/Services/Feature/Makefile.am 2017-10-02 22:12:57 UTC (rev 9242)
+++ sandbox/jng/ogc/Server/src/Services/Feature/Makefile.am 2017-10-06 13:49:24 UTC (rev 9243)
@@ -107,6 +107,7 @@
OpGetWfsFeature.cpp \
OpGetWfsReader.cpp \
FilterUtil.cpp \
+ WfsQueryAdapter.cpp \
OpEnumerateDataStores.cpp \
OpGetSchemaMapping.cpp \
ServerEnumerateDataStores.cpp \
@@ -219,6 +220,7 @@
OpGetWfsFeature.h \
OpGetWfsReader.h \
FilterUtil.h \
+ WfsQueryAdapter.h \
OpEnumerateDataStores.h \
OpGetSchemaMapping.h \
ServerEnumerateDataStores.h \
Modified: sandbox/jng/ogc/Server/src/Services/Feature/OpGetWfsReader.cpp
===================================================================
--- sandbox/jng/ogc/Server/src/Services/Feature/OpGetWfsReader.cpp 2017-10-02 22:12:57 UTC (rev 9242)
+++ sandbox/jng/ogc/Server/src/Services/Feature/OpGetWfsReader.cpp 2017-10-06 13:49:24 UTC (rev 9243)
@@ -62,7 +62,7 @@
ACE_ASSERT(m_stream != NULL);
- if (7 == m_packet.m_NumArguments)
+ if (6 == m_packet.m_NumArguments)
{
// Get the feature source
Ptr<MgResourceIdentifier> featureSourceId = (MgResourceIdentifier*)m_stream->GetObject();
@@ -82,10 +82,6 @@
STRING filter;
m_stream->GetString(filter);
- // Get the max features to return
- INT32 maxFeatures;
- m_stream->GetInt32(maxFeatures);
-
// Get the sort criteria
STRING sortCriteria;
m_stream->GetString(sortCriteria);
@@ -103,15 +99,13 @@
MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
MG_LOG_OPERATION_MESSAGE_ADD_STRING(filter.c_str());
MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
- MG_LOG_OPERATION_MESSAGE_ADD_INT32(maxFeatures);
- MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
MG_LOG_OPERATION_MESSAGE_ADD_STRING(sortCriteria.c_str());
MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
Validate();
// Execute the operation
- Ptr<MgFeatureReader> fr = m_service->GetWfsReader(featureSourceId, featureClass, requiredProperties, srs, filter, maxFeatures, sortCriteria);
+ Ptr<MgFeatureReader> fr = m_service->GetWfsReader(featureSourceId, featureClass, requiredProperties, srs, filter, sortCriteria);
// Write the response
EndExecution(fr);
Modified: sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.cpp
===================================================================
--- sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.cpp 2017-10-02 22:12:57 UTC (rev 9242)
+++ sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.cpp 2017-10-06 13:49:24 UTC (rev 9243)
@@ -48,6 +48,7 @@
#include "ServerSqlDataReader.h"
#include "ServerFeatureTransaction.h"
#include "TransformedGeometryFeatureReader.h"
+#include "WfsQueryAdapter.h"
#include <Fdo/Xml/FeatureSerializer.h>
#include <Fdo/Xml/FeatureWriter.h>
@@ -2048,172 +2049,20 @@
MgStringCollection* propNames,
CREFSTRING srs,
CREFSTRING wfsFilter,
- INT32 maxFeatures,
CREFSTRING sortCriteria)
{
+ MG_LOG_TRACE_ENTRY(L"MgServerFeatureService::GetWfsReader()");
+
Ptr<MgFeatureReader> mgfReader;
- TransformCacheMap transformCache;
MG_FEATURE_SERVICE_TRY()
- STRING lfeatureName = featureClass;
- STRING schemaName, className;
- MgUtil::ParseQualifiedClassName(lfeatureName, schemaName, className);
+ MgWfsQueryAdapter wfsQuery(this);
+ wfsQuery.SetOptions(fs, featureClass, propNames, srs, wfsFilter, sortCriteria);
+ mgfReader = wfsQuery.GetWfsReader();
- bool hashed = (0 == schemaName.find_first_of(
- MG_SCHEMA_NAME_HASH_PREFIX.c_str(), 0, MG_SCHEMA_NAME_HASH_PREFIX.length()));
- Ptr<MgStringCollection> classNames = new MgStringCollection();
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(fs, L"MgServerFeatureService.GetWfsReader")
- if (!className.empty())
- {
- classNames->Add(className);
- }
-
- // Find the needed class definition.
- Ptr<MgFeatureSchemaCollection> fsc = DescribeSchema(
- fs, hashed ? L"" : schemaName, classNames);
- Ptr<MgFeatureSchema> schema;
- Ptr<MgClassDefinition> fc;
- STRING schemaHash;
-
- FindClassDefinition(fsc, schemaName, className, schemaHash, schema, fc);
-
- if (hashed && NULL != schema.p)
- {
- MgUtil::FormatQualifiedClassName(schema->GetName(), className, lfeatureName);
- }
-
- MgCoordinateSystemFactory fact;
- std::wstring wkt = srs;
- if (wkt.empty())
- {
- //If there is no coordinate system pass in, get the default one in resource header.
- MgServiceManager* serviceMan = MgServiceManager::GetInstance();
- assert(NULL != serviceMan);
- Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(serviceMan->RequestService(MgServiceType::ResourceService));
- assert(resourceService != NULL);
- Ptr<MgByteReader> byteReaderHeader = resourceService->GetResourceHeader(fs);
- Ptr<MgByteSink> byteSinkHeader = new MgByteSink(byteReaderHeader);
- std::string resourceHeader;
- byteSinkHeader->ToStringUtf8(resourceHeader);
- //parse for default SRS of this WFS, the format is:
- //<Property xsi:noNamespaceSchemaLocation="Property-1.0.0.xsd">
- // <Name>_PrimarySRS</Name>
- // <Value>EPSG:4326</Value>
- //</Property>
- std::string primary("<Name>_PrimarySRS</Name>");
- std::size_t primaryPos = resourceHeader.find(primary);
- if (primaryPos != std::string::npos)
- {
- std::string begin("<Value>EPSG:");
- std::size_t beginPos = resourceHeader.find(begin, primaryPos);
- if (beginPos != std::string::npos)
- {
- std::size_t endPos = resourceHeader.find("</Value>", beginPos);
- if (endPos != std::string::npos)
- {
- std::string primarySRS = resourceHeader.substr(beginPos + begin.length(), endPos - beginPos - begin.length());
- int epsgCode = atoi(primarySRS.c_str());
- wkt = fact.ConvertEpsgCodeToWkt(epsgCode);
- }
- }
- }
- }
-
- Ptr<MgCoordinateSystem> mapCs = NULL;
- if (!wkt.empty())
- {
- MG_TRY();
- mapCs = fact.Create(wkt);
- MG_CATCH_AND_RELEASE();
- }
-
- //get a transform from feature space to mapping space
- TransformCache* item = TransformCache::GetLayerToMapTransform(transformCache, lfeatureName, fs, mapCs, &fact, this, false);
- Ptr<MgCoordinateSystemTransform> trans = item ? item->GetMgTransform() : NULL;
-
- assert(fc != NULL);
- if (fc == NULL)
- return NULL;
-
- //execute the spatial query
- Ptr<MgFeatureQueryOptions> options = new MgFeatureQueryOptions();
-
- //add the properties we need from FDO
- if (propNames)
- {
- for (int i = 0; i<propNames->GetCount(); i++)
- options->AddFeatureProperty(propNames->GetItem(i));
- }
-
- //convert the WFS filter to an FDO filter
- //and set it to the FDO feature query
- if (!wfsFilter.empty())
- {
- STRING GEOM_PROP_TAG = L"%MG_GEOM_PROP%"; //NOXLATE
- STRING fdoFilterString = L""; //NOXLATE
-
- Ptr<MgPropertyDefinitionCollection> properties = fc->GetProperties();
- MgOgcFilterUtil u;
-
- for (int i = 0; i<properties->GetCount(); i++)
- {
- Ptr<MgPropertyDefinition> prop = properties->GetItem(i);
- if (prop->GetPropertyType() == MgFeaturePropertyType::GeometricProperty)
- {
- STRING ogcFilter = wfsFilter;
-
- if (wfsFilter.find(GEOM_PROP_TAG, 0) != STRING::npos)
- {
- ogcFilter = MgUtil::ReplaceString(wfsFilter, GEOM_PROP_TAG.c_str(), prop->GetName().c_str());
- }
- if (!fdoFilterString.empty())
- {
- fdoFilterString += L" OR "; //NOXLATE
- }
- TransformCache* itemFilter = TransformCache::GetLayerToMapTransform(transformCache, lfeatureName, fs, mapCs, &fact, this, true);
- Ptr<MgCoordinateSystemTransform> transFilter = itemFilter ? itemFilter->GetMgTransform() : NULL;
- fdoFilterString += u.Ogc2FdoFilter(ogcFilter, transFilter, prop->GetName(), properties);
- }
- }
-
- options->SetFilter(fdoFilterString);
- }
-
- if (!sortCriteria.empty())
- {
- Ptr<MgStringCollection> orderByProperties = new MgStringCollection();
- int orderOption = MgOrderingOption::Ascending;
-
- STRING sSortCriteria = sortCriteria;
- STRING::size_type pos = sSortCriteria.find_last_of(L" ");
- if (pos != STRING::npos)
- {
- STRING sSortByProperty = sSortCriteria.substr(0, pos);
- orderByProperties->Add(sSortByProperty);
-
- STRING sSortOption = MgUtil::ToUpper(sSortCriteria.substr(pos + 1));
- if (sSortOption == L"D")
- {
- orderOption = MgOrderingOption::Descending;
- }
- }
- else
- {
- orderByProperties->Add(sortCriteria);
- }
-
- options->SetOrderingFilter(orderByProperties, orderOption);
- }
- // TODO: can FeatureName be an extension name rather than a FeatureClass?
- mgfReader = SelectFeatures(fs, lfeatureName, options);
-
- MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH(fs, L"MgServerFeatureService.GetWfsReader")
-
- TransformCache::Clear(transformCache);
-
- MG_FEATURE_SERVICE_THROW()
-
return mgfReader.Detach();
}
@@ -2284,162 +2133,17 @@
MG_LOG_TRACE_ENTRY(L"MgServerFeatureService::GetWfsFeature()");
Ptr<MgByteReader> byteReader;
- TransformCacheMap transformCache;
MG_FEATURE_SERVICE_TRY()
- STRING lfeatureName = featureClass;
- STRING schemaName, className;
- MgUtil::ParseQualifiedClassName(lfeatureName, schemaName, className);
+ MgWfsQueryAdapter wfsQuery(this);
+ wfsQuery.SetOptions(fs, featureClass, propNames, srs, wfsFilter, sortCriteria);
- bool hashed = (0 == schemaName.find_first_of(
- MG_SCHEMA_NAME_HASH_PREFIX.c_str(), 0, MG_SCHEMA_NAME_HASH_PREFIX.length()));
- Ptr<MgStringCollection> classNames = new MgStringCollection();
+ Ptr<MgFeatureReader> mgfReader = wfsQuery.GetWfsReader();
+ Ptr<MgCoordinateSystemTransform> trans = wfsQuery.GetTransform();
+ Ptr<MgCoordinateSystem> mapCs = wfsQuery.GetMapCs();
+ Ptr<MgClassDefinition> fc = wfsQuery.GetClassDefinition();
- if (!className.empty())
- {
- classNames->Add(className);
- }
-
- // Find the needed class definition.
- Ptr<MgFeatureSchemaCollection> fsc = DescribeSchema(
- fs, hashed ? L"" : schemaName, classNames);
- Ptr<MgFeatureSchema> schema;
- Ptr<MgClassDefinition> fc;
- STRING schemaHash;
-
- FindClassDefinition(fsc, schemaName, className, schemaHash, schema, fc);
-
- if (hashed && NULL != schema.p)
- {
- MgUtil::FormatQualifiedClassName(schema->GetName(), className, lfeatureName);
- }
-
- MgCoordinateSystemFactory fact;
- std::wstring wkt = srs;
- if (wkt.empty())
- {
- //If there is no coordinate system pass in, get the default one in resource header.
- MgServiceManager* serviceMan = MgServiceManager::GetInstance();
- assert(NULL != serviceMan);
- Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(serviceMan->RequestService(MgServiceType::ResourceService));
- assert(resourceService != NULL);
- Ptr<MgByteReader> byteReaderHeader = resourceService->GetResourceHeader(fs);
- Ptr<MgByteSink> byteSinkHeader = new MgByteSink(byteReaderHeader);
- std::string resourceHeader;
- byteSinkHeader->ToStringUtf8(resourceHeader);
- //parse for default SRS of this WFS, the format is:
- //<Property xsi:noNamespaceSchemaLocation="Property-1.0.0.xsd">
- // <Name>_PrimarySRS</Name>
- // <Value>EPSG:4326</Value>
- //</Property>
- std::string primary("<Name>_PrimarySRS</Name>");
- std::size_t primaryPos = resourceHeader.find(primary);
- if (primaryPos != std::string::npos)
- {
- std::string begin("<Value>EPSG:");
- std::size_t beginPos = resourceHeader.find(begin, primaryPos);
- if (beginPos != std::string::npos)
- {
- std::size_t endPos = resourceHeader.find("</Value>", beginPos);
- if (endPos != std::string::npos)
- {
- std::string primarySRS = resourceHeader.substr(beginPos+begin.length(), endPos-beginPos-begin.length());
- int epsgCode = atoi(primarySRS.c_str());
- wkt = fact.ConvertEpsgCodeToWkt(epsgCode);
- }
- }
- }
- }
-
- Ptr<MgCoordinateSystem> mapCs = NULL;
- if (!wkt.empty())
- {
- MG_TRY();
- mapCs = fact.Create(wkt);
- MG_CATCH_AND_RELEASE();
- }
-
- //get a transform from feature space to mapping space
- TransformCache* item = TransformCache::GetLayerToMapTransform(transformCache, lfeatureName, fs, mapCs, &fact, this, false);
- Ptr<MgCoordinateSystemTransform> trans = item? item->GetMgTransform() : NULL;
-
- assert(fc != NULL);
- if (fc == NULL)
- return NULL;
-
- //execute the spatial query
- Ptr<MgFeatureQueryOptions> options = new MgFeatureQueryOptions();
-
- //add the properties we need from FDO
- if (propNames)
- {
- for (int i=0; i<propNames->GetCount(); i++)
- options->AddFeatureProperty(propNames->GetItem(i));
- }
-
- //convert the WFS filter to an FDO filter
- //and set it to the FDO feature query
- if (!wfsFilter.empty())
- {
- STRING GEOM_PROP_TAG = L"%MG_GEOM_PROP%"; //NOXLATE
- STRING fdoFilterString = L""; //NOXLATE
-
- Ptr<MgPropertyDefinitionCollection> properties = fc->GetProperties();
- MgOgcFilterUtil u;
-
- for(int i = 0; i<properties->GetCount(); i++)
- {
- Ptr<MgPropertyDefinition> prop = properties->GetItem(i);
- if(prop->GetPropertyType() == MgFeaturePropertyType::GeometricProperty)
- {
- STRING ogcFilter = wfsFilter;
-
- if(wfsFilter.find(GEOM_PROP_TAG, 0) != STRING::npos)
- {
- ogcFilter = MgUtil::ReplaceString(wfsFilter,GEOM_PROP_TAG.c_str(),prop->GetName().c_str());
- }
- if(!fdoFilterString.empty())
- {
- fdoFilterString += L" OR "; //NOXLATE
- }
- TransformCache* itemFilter = TransformCache::GetLayerToMapTransform(transformCache, lfeatureName, fs, mapCs, &fact, this, true);
- Ptr<MgCoordinateSystemTransform> transFilter = itemFilter? itemFilter->GetMgTransform() : NULL;
- fdoFilterString += u.Ogc2FdoFilter(ogcFilter, transFilter, prop->GetName(), properties);
- }
- }
-
- options->SetFilter(fdoFilterString);
- }
-
- if(!sortCriteria.empty())
- {
- Ptr<MgStringCollection> orderByProperties = new MgStringCollection();
- int orderOption = MgOrderingOption::Ascending;
-
- STRING sSortCriteria = sortCriteria;
- STRING::size_type pos = sSortCriteria.find_last_of(L" ");
- if(pos != STRING::npos)
- {
- STRING sSortByProperty = sSortCriteria.substr(0, pos);
- orderByProperties->Add(sSortByProperty);
-
- STRING sSortOption = MgUtil::ToUpper(sSortCriteria.substr(pos+1));
- if(sSortOption == L"D")
- {
- orderOption = MgOrderingOption::Descending;
- }
- }
- else
- {
- orderByProperties->Add(sortCriteria);
- }
-
- options->SetOrderingFilter(orderByProperties,orderOption);
- }
- // TODO: can FeatureName be an extension name rather than a FeatureClass?
- Ptr<MgFeatureReader> mgfReader = SelectFeatures(fs, lfeatureName, options);
-
FdoPtr<MgGMLCsTransform> transform = new MgGMLCsTransform(trans);
//get underlying FDO feature reader
@@ -2569,12 +2273,8 @@
src->SetMimeType(MgMimeType::Xml);
byteReader = src->GetReader();
- MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH(fs, L"MgServerFeatureService.GetWfsFeature")
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(fs, L"MgServerFeatureService.GetWfsFeature")
- TransformCache::Clear(transformCache);
-
- MG_FEATURE_SERVICE_THROW()
-
return byteReader.Detach();
}
Modified: sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.h
===================================================================
--- sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.h 2017-10-02 22:12:57 UTC (rev 9242)
+++ sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.h 2017-10-06 13:49:24 UTC (rev 9243)
@@ -23,8 +23,12 @@
#include <set>
+class MgWfsQueryAdapter;
+
class MG_SERVER_FEATURE_API MgServerFeatureService : public MgFeatureService
{
+ friend class MgWfsQueryAdapter;
+
DECLARE_CLASSNAME(MgServerFeatureService)
public:
@@ -946,7 +950,6 @@
MgStringCollection* requiredProperties,
CREFSTRING srs,
CREFSTRING filter,
- INT32 maxFeatures,
CREFSTRING sortCriteria);
////////////////////////////////////////////////////////////////////////////////
Modified: sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.vcxproj
===================================================================
--- sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.vcxproj 2017-10-02 22:12:57 UTC (rev 9242)
+++ sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.vcxproj 2017-10-06 13:49:24 UTC (rev 9243)
@@ -822,6 +822,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
+ <ClCompile Include="WfsQueryAdapter.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="FdoForcedOneToOneFeatureReader.h" />
@@ -892,6 +898,7 @@
<ClInclude Include="FeatureStringFunctions.h" />
<ClInclude Include="FilterUtil.h" />
<ClInclude Include="GeometryDataReaderCreator.h" />
+ <ClInclude Include="WfsQueryAdapter.h" />
<CustomBuildStep Include="GwsConnectionPool.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
Modified: sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.vcxproj.filters
===================================================================
--- sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.vcxproj.filters 2017-10-02 22:12:57 UTC (rev 9242)
+++ sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureService.vcxproj.filters 2017-10-06 13:49:24 UTC (rev 9243)
@@ -204,6 +204,7 @@
<ClCompile Include="OpGetWfsReader.cpp">
<Filter>Ops</Filter>
</ClCompile>
+ <ClCompile Include="WfsQueryAdapter.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="FeatureOperation.h">
@@ -417,6 +418,7 @@
<ClInclude Include="OpGetWfsReader.h">
<Filter>Ops</Filter>
</ClInclude>
+ <ClInclude Include="WfsQueryAdapter.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ServerFeatureService.rc" />
Modified: sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureServiceBuild.cpp
===================================================================
--- sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureServiceBuild.cpp 2017-10-02 22:12:57 UTC (rev 9242)
+++ sandbox/jng/ogc/Server/src/Services/Feature/ServerFeatureServiceBuild.cpp 2017-10-06 13:49:24 UTC (rev 9243)
@@ -88,6 +88,7 @@
#include "OpGetWfsFeature.cpp"
#include "OpGetWfsReader.cpp"
#include "FilterUtil.cpp"
+#include "WfsQueryAdapter.cpp"
#include "ServerGwsFeatureReader.cpp"
#include "GwsConnectionPool.cpp"
#include "OpEnumerateDataStores.cpp"
@@ -112,4 +113,4 @@
#include "OpInsertFeaturesBatched.cpp"
#include "OpUpdateMatchingFeatures.cpp"
#include "OpDeleteFeatures.cpp"
-#include "TransformedGeometryFeatureReader.cpp"
+#include "TransformedGeometryFeatureReader.cpp"
\ No newline at end of file
Added: sandbox/jng/ogc/Server/src/Services/Feature/WfsQueryAdapter.cpp
===================================================================
--- sandbox/jng/ogc/Server/src/Services/Feature/WfsQueryAdapter.cpp (rev 0)
+++ sandbox/jng/ogc/Server/src/Services/Feature/WfsQueryAdapter.cpp 2017-10-06 13:49:24 UTC (rev 9243)
@@ -0,0 +1,216 @@
+//
+// Copyright (C) 2004-2017 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "ServerFeatureServiceDefs.h"
+#include "WfsQueryAdapter.h"
+
+MgWfsQueryAdapter::MgWfsQueryAdapter(MgServerFeatureService* featSvc)
+{
+ m_featSvc = SAFE_ADDREF(featSvc);
+}
+
+MgWfsQueryAdapter::~MgWfsQueryAdapter()
+{
+ TransformCache::Clear(m_transformCache);
+ m_classDef = NULL;
+ m_fs = NULL;
+ m_options = NULL;
+ m_featSvc = NULL;
+ m_mapCs = NULL;
+ m_xform = NULL;
+}
+
+bool MgWfsQueryAdapter::SetOptions(MgResourceIdentifier* fs,
+ CREFSTRING featureClass,
+ MgStringCollection* propNames,
+ CREFSTRING srs,
+ CREFSTRING wfsFilter,
+ CREFSTRING sortCriteria)
+{
+ m_fs = SAFE_ADDREF(fs);
+ m_className = featureClass;
+ STRING schemaName, className;
+ MgUtil::ParseQualifiedClassName(m_className, schemaName, className);
+
+ bool hashed = (0 == schemaName.find_first_of(MG_SCHEMA_NAME_HASH_PREFIX.c_str(), 0, MG_SCHEMA_NAME_HASH_PREFIX.length()));
+ Ptr<MgStringCollection> classNames = new MgStringCollection();
+
+ if (!className.empty())
+ {
+ classNames->Add(className);
+ }
+
+ // Find the needed class definition.
+ Ptr<MgFeatureSchemaCollection> fsc = m_featSvc->DescribeSchema(m_fs, hashed ? L"" : schemaName, classNames);
+ Ptr<MgFeatureSchema> schema;
+ STRING schemaHash;
+
+ m_featSvc->FindClassDefinition(fsc, schemaName, className, schemaHash, schema, m_classDef);
+
+ if (hashed && NULL != schema.p)
+ {
+ MgUtil::FormatQualifiedClassName(schema->GetName(), className, m_className);
+ }
+
+ MgCoordinateSystemFactory fact;
+ std::wstring wkt = srs;
+ if (wkt.empty())
+ {
+ //If there is no coordinate system pass in, get the default one in resource header.
+ MgServiceManager* serviceMan = MgServiceManager::GetInstance();
+ assert(NULL != serviceMan);
+ Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(serviceMan->RequestService(MgServiceType::ResourceService));
+ assert(resourceService != NULL);
+ Ptr<MgByteReader> byteReaderHeader = resourceService->GetResourceHeader(m_fs);
+ Ptr<MgByteSink> byteSinkHeader = new MgByteSink(byteReaderHeader);
+ std::string resourceHeader;
+ byteSinkHeader->ToStringUtf8(resourceHeader);
+ //parse for default SRS of this WFS, the format is:
+ //<Property xsi:noNamespaceSchemaLocation="Property-1.0.0.xsd">
+ // <Name>_PrimarySRS</Name>
+ // <Value>EPSG:4326</Value>
+ //</Property>
+ std::string primary("<Name>_PrimarySRS</Name>");
+ std::size_t primaryPos = resourceHeader.find(primary);
+ if (primaryPos != std::string::npos)
+ {
+ std::string begin("<Value>EPSG:");
+ std::size_t beginPos = resourceHeader.find(begin, primaryPos);
+ if (beginPos != std::string::npos)
+ {
+ std::size_t endPos = resourceHeader.find("</Value>", beginPos);
+ if (endPos != std::string::npos)
+ {
+ std::string primarySRS = resourceHeader.substr(beginPos + begin.length(), endPos - beginPos - begin.length());
+ int epsgCode = atoi(primarySRS.c_str());
+ wkt = fact.ConvertEpsgCodeToWkt(epsgCode);
+ }
+ }
+ }
+ }
+
+ if (!wkt.empty())
+ {
+ MG_TRY();
+ m_mapCs = fact.Create(wkt);
+ MG_CATCH_AND_RELEASE();
+ }
+
+ //get a transform from feature space to mapping space
+ TransformCache* item = TransformCache::GetLayerToMapTransform(m_transformCache, m_className, m_fs, m_mapCs, &fact, m_featSvc, false);
+ m_xform = item ? item->GetMgTransform() : NULL;
+
+ assert(m_classDef.p != NULL);
+ if (NULL == m_classDef.p)
+ return false;
+
+ //execute the spatial query
+ Ptr<MgFeatureQueryOptions> options = new MgFeatureQueryOptions();
+
+ //add the properties we need from FDO
+ if (propNames)
+ {
+ for (int i = 0; i<propNames->GetCount(); i++)
+ options->AddFeatureProperty(propNames->GetItem(i));
+ }
+
+ //convert the WFS filter to an FDO filter
+ //and set it to the FDO feature query
+ if (!wfsFilter.empty())
+ {
+ STRING GEOM_PROP_TAG = L"%MG_GEOM_PROP%"; //NOXLATE
+ STRING fdoFilterString = L""; //NOXLATE
+
+ Ptr<MgPropertyDefinitionCollection> properties = m_classDef->GetProperties();
+ MgOgcFilterUtil u;
+
+ for (int i = 0; i<properties->GetCount(); i++)
+ {
+ Ptr<MgPropertyDefinition> prop = properties->GetItem(i);
+ if (prop->GetPropertyType() == MgFeaturePropertyType::GeometricProperty)
+ {
+ STRING ogcFilter = wfsFilter;
+
+ if (wfsFilter.find(GEOM_PROP_TAG, 0) != STRING::npos)
+ {
+ ogcFilter = MgUtil::ReplaceString(wfsFilter, GEOM_PROP_TAG.c_str(), prop->GetName().c_str());
+ }
+ if (!fdoFilterString.empty())
+ {
+ fdoFilterString += L" OR "; //NOXLATE
+ }
+ TransformCache* itemFilter = TransformCache::GetLayerToMapTransform(m_transformCache, m_className, m_fs, m_mapCs, &fact, m_featSvc, true);
+ Ptr<MgCoordinateSystemTransform> transFilter = itemFilter ? itemFilter->GetMgTransform() : NULL;
+ fdoFilterString += u.Ogc2FdoFilter(ogcFilter, transFilter, prop->GetName(), properties);
+ }
+ }
+
+ options->SetFilter(fdoFilterString);
+ }
+
+ if (!sortCriteria.empty())
+ {
+ Ptr<MgStringCollection> orderByProperties = new MgStringCollection();
+ int orderOption = MgOrderingOption::Ascending;
+
+ STRING sSortCriteria = sortCriteria;
+ STRING::size_type pos = sSortCriteria.find_last_of(L" ");
+ if (pos != STRING::npos)
+ {
+ STRING sSortByProperty = sSortCriteria.substr(0, pos);
+ orderByProperties->Add(sSortByProperty);
+
+ STRING sSortOption = MgUtil::ToUpper(sSortCriteria.substr(pos + 1));
+ if (sSortOption == L"D")
+ {
+ orderOption = MgOrderingOption::Descending;
+ }
+ }
+ else
+ {
+ orderByProperties->Add(sortCriteria);
+ }
+
+ options->SetOrderingFilter(orderByProperties, orderOption);
+ }
+ return true;
+}
+
+MgClassDefinition* MgWfsQueryAdapter::GetClassDefinition()
+{
+ return SAFE_ADDREF(m_classDef.p);
+}
+
+MgCoordinateSystemTransform* MgWfsQueryAdapter::GetTransform()
+{
+ return SAFE_ADDREF(m_xform.p);
+}
+
+MgCoordinateSystem* MgWfsQueryAdapter::GetMapCs()
+{
+ return SAFE_ADDREF(m_mapCs.p);
+}
+
+MgFeatureReader* MgWfsQueryAdapter::GetWfsReader()
+{
+ Ptr<MgFeatureReader> fr;
+ MG_FEATURE_SERVICE_TRY()
+ // TODO: can FeatureName be an extension name rather than a FeatureClass?
+ fr = m_featSvc->SelectFeatures(m_fs, m_className, m_options);
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(m_fs, L"MgWfsQueryAdapter.GetWfsReader")
+ return fr.Detach();
+}
\ No newline at end of file
Added: sandbox/jng/ogc/Server/src/Services/Feature/WfsQueryAdapter.h
===================================================================
--- sandbox/jng/ogc/Server/src/Services/Feature/WfsQueryAdapter.h (rev 0)
+++ sandbox/jng/ogc/Server/src/Services/Feature/WfsQueryAdapter.h 2017-10-06 13:49:24 UTC (rev 9243)
@@ -0,0 +1,52 @@
+//
+// Copyright (C) 2004-2017 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MG_WFS_QUERY_ADAPTER_H_
+#define _MG_WFS_QUERY_ADAPTER_H_
+
+class MgServerFeatureService;
+
+// This is a helper class that contains most of the boilerplate for translating WFS GetFeature request parameters
+// to our feature service queries
+class MgWfsQueryAdapter
+{
+public:
+ MgWfsQueryAdapter(MgServerFeatureService* featSvc);
+ ~MgWfsQueryAdapter();
+ bool SetOptions(MgResourceIdentifier* fs,
+ CREFSTRING featureClass,
+ MgStringCollection* propNames,
+ CREFSTRING srs,
+ CREFSTRING wfsFilter,
+ CREFSTRING sortCriteria);
+ MgFeatureReader* GetWfsReader();
+ MgCoordinateSystem* GetMapCs();
+ MgCoordinateSystemTransform* GetTransform();
+ MgClassDefinition* GetClassDefinition();
+
+private:
+ Ptr<MgClassDefinition> m_classDef;
+ Ptr<MgResourceIdentifier> m_fs;
+ Ptr<MgFeatureQueryOptions> m_options;
+ Ptr<MgServerFeatureService> m_featSvc;
+ Ptr<MgCoordinateSystem> m_mapCs;
+ Ptr<MgCoordinateSystemTransform> m_xform;
+ STRING m_className;
+ TransformCacheMap m_transformCache;
+};
+
+#endif
\ No newline at end of file
Modified: sandbox/jng/ogc/Web/src/HttpHandler/HttpWfsGetFeature.cpp
===================================================================
--- sandbox/jng/ogc/Web/src/HttpHandler/HttpWfsGetFeature.cpp 2017-10-02 22:12:57 UTC (rev 9242)
+++ sandbox/jng/ogc/Web/src/HttpHandler/HttpWfsGetFeature.cpp 2017-10-06 13:49:24 UTC (rev 9243)
@@ -297,10 +297,11 @@
// NOTE: This API doesn't accept WFS version, format and XML namepaces because these are GML-isms baked into the GetWfsFeature API itself, making
// it unsuitable for non-GML output, hence the need for this new GetWfsReader API
Ptr<MgFeatureReader> fr = featureService->GetWfsReader(featureSourceId, ((sSchemaHash.size() == 0) ? sClass : sSchemaHash + _(":") + sClass),
- requiredProperties, m_getFeatureParams->GetSrs(), filter, numFeaturesToRetrieve - 1, sSortCriteria);
+ requiredProperties, m_getFeatureParams->GetSrs(), filter, sSortCriteria);
//MgByteSource owns this and will clean it up when done
- ByteSourceImpl* bsImpl = new MgReaderByteSourceImpl(fr, MgMimeType::Json, true, false, -1);
+ MgReaderByteSourceImpl* bsImpl = new MgReaderByteSourceImpl(fr, MgMimeType::Json, true, false, -1);
+ bsImpl->SetMaxFeatures(numFeaturesToRetrieve - 1);
Ptr<MgByteSource> bs = new MgByteSource(bsImpl);
resultReader = bs->GetReader();
}
Modified: sandbox/jng/ogc/Web/src/HttpHandler/ReaderByteSourceImpl.cpp
===================================================================
--- sandbox/jng/ogc/Web/src/HttpHandler/ReaderByteSourceImpl.cpp 2017-10-02 22:12:57 UTC (rev 9242)
+++ sandbox/jng/ogc/Web/src/HttpHandler/ReaderByteSourceImpl.cpp 2017-10-06 13:49:24 UTC (rev 9243)
@@ -18,6 +18,8 @@
#include "PlatformBase.h"
MgReaderByteSourceImpl::MgReaderByteSourceImpl(MgReader* reader, CREFSTRING format, bool bCleanJson, bool bEnablePrecision, INT32 precision)
+ : m_maxFeatures(-1),
+ m_featureIndex(-1)
{
m_reader = SAFE_ADDREF(reader);
m_format = format;
@@ -40,6 +42,24 @@
m_reader = NULL;
}
+void MgReaderByteSourceImpl::SetMaxFeatures(INT32 maxFeatures)
+{
+ m_maxFeatures = maxFeatures;
+}
+
+bool MgReaderByteSourceImpl::ReadNextInternal()
+{
+ if (m_maxFeatures < 0 || m_featureIndex < m_maxFeatures)
+ {
+ m_featureIndex++;
+ return m_reader->ReadNext();
+ }
+ else
+ {
+ return false;
+ }
+}
+
///////////////////////////////////////////////////////////////////////////
/// \brief
/// Reads a buffer
@@ -161,7 +181,7 @@
if (m_bInternalReaderHasMore && bAdvanceReader)
{
- m_bInternalReaderHasMore = m_reader->ReadNext();
+ m_bInternalReaderHasMore = ReadNextInternal();
if (m_bInternalReaderHasMore)
{
if (m_format == MgMimeType::Json)
Modified: sandbox/jng/ogc/Web/src/HttpHandler/ReaderByteSourceImpl.h
===================================================================
--- sandbox/jng/ogc/Web/src/HttpHandler/ReaderByteSourceImpl.h 2017-10-02 22:12:57 UTC (rev 9242)
+++ sandbox/jng/ogc/Web/src/HttpHandler/ReaderByteSourceImpl.h 2017-10-06 13:49:24 UTC (rev 9243)
@@ -80,7 +80,10 @@
///
virtual void Rewind();
+ void SetMaxFeatures(INT32 maxFeatures);
+
private:
+ bool ReadNextInternal();
INT32 ReadInternalBuffer(BYTE_ARRAY_OUT buffer, INT32 fromIndex, INT32 length);
Ptr<MgReader> m_reader;
@@ -90,6 +93,8 @@
bool m_bInternalReaderHasMore;
bool m_bFirstRecord;
bool m_bEnablePrecision;
+ INT32 m_maxFeatures;
+ INT32 m_featureIndex;
std::string m_buf;
INT32 m_bufOffset;
More information about the mapguide-commits
mailing list