[mapguide-commits] r1096 - in trunk/MgDev: Common/MapGuideCommon/Services Server/src/Services/Feature Server/src/Wfs Server/src/Wms UnitTest/WebTier/MapAgent/MapAgentForms Web/src/HttpHandler

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Thu Feb 8 17:43:38 EST 2007


Author: chrisclaydon
Date: 2007-02-08 17:43:38 -0500 (Thu, 08 Feb 2007)
New Revision: 1096

Added:
   trunk/MgDev/Server/src/Services/Feature/ServerFdoFeatureReader.cpp
   trunk/MgDev/Server/src/Services/Feature/ServerFdoFeatureReader.h
   trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/describefeaturetypewfsform.html
   trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getcapabilitieswfsform.html
   trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getfeaturewfsform.html
   trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/wfsserviceapi.html
Modified:
   trunk/MgDev/Common/MapGuideCommon/Services/Site.cpp
   trunk/MgDev/Server/src/Services/Feature/FilterUtil.cpp
   trunk/MgDev/Server/src/Services/Feature/FilterUtil.h
   trunk/MgDev/Server/src/Services/Feature/Makefile.am
   trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.cpp
   trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcproj
   trunk/MgDev/Server/src/Services/Feature/ServerFeatureServiceBuild.cpp
   trunk/MgDev/Server/src/Wfs/1.0.0.xml.awd
   trunk/MgDev/Server/src/Wfs/1.1.0.xml.awd
   trunk/MgDev/Server/src/Wms/1.0.0.xml.awd
   trunk/MgDev/Server/src/Wms/1.1.0.xml.awd
   trunk/MgDev/Server/src/Wms/1.1.1.xml.awd
   trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/services.html
   trunk/MgDev/Web/src/HttpHandler/HttpWfsDescribeFeatureType.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpWfsGetFeature.cpp
   trunk/MgDev/Web/src/HttpHandler/OgcWfsServer.cpp
   trunk/MgDev/Web/src/HttpHandler/OgcWfsServer.h
   trunk/MgDev/Web/src/HttpHandler/WfsFeatureDefinitions.cpp
   trunk/MgDev/Web/src/HttpHandler/WfsFeatureDefinitions.h
   trunk/MgDev/Web/src/HttpHandler/WfsGetFeatureParams.cpp
Log:
WMS/WFS bug fixes:
Allow WMS/WFS to support coordinate systems other than EPSG:4326
Add web tier test pages for WFS
Add server-side support for MaxFeatures in WFS GetFeature request
Fix spatial filtering for WFS requests
Performance enhancements to eliminate unnecessary calls to DescribeSchema for feature sources either not published via WFS or not required for a given request



Modified: trunk/MgDev/Common/MapGuideCommon/Services/Site.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/Site.cpp	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Common/MapGuideCommon/Services/Site.cpp	2007-02-08 22:43:38 UTC (rev 1096)
@@ -1237,9 +1237,6 @@
 
     CHECKARGUMENTNULL((MgUserInformation*)userInformation, L"MgSite.Authenticate")
 
-    MgConfiguration* configuration = MgConfiguration::GetInstance();
-    assert(NULL != configuration);
-
     assert(m_connProp == NULL);
     MgSiteManager* siteManager = MgSiteManager::GetInstance();
     if(siteInfo != NULL)

Modified: trunk/MgDev/Server/src/Services/Feature/FilterUtil.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/FilterUtil.cpp	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Server/src/Services/Feature/FilterUtil.cpp	2007-02-08 22:43:38 UTC (rev 1096)
@@ -44,11 +44,12 @@
 #endif
 }
 
-STRING MgOgcFilterUtil::Ogc2FdoFilter(CREFSTRING ogcFilter, MgCoordinateSystemTransform* xform)
+STRING MgOgcFilterUtil::Ogc2FdoFilter(CREFSTRING ogcFilter, MgCoordinateSystemTransform* xform, CREFSTRING geomProp)
 {
     //we will use the transform to transform geometry
     //from map coordinate system to layer/FDO data source coordinate system
     m_xform = SAFE_ADDREF(xform);
+    m_geomProp = geomProp;
 
     //convert to utf-8
     string utffilter = MgUtil::WideCharToMultiByte(ogcFilter);
@@ -465,6 +466,19 @@
     //this assumes the gml:Box tag is parsed as a WKT polygon for use
     //in FDO spatial conditions which expect that
 
+    if(left.empty() && !right.empty())
+    {
+        // If we have an empty property name, use the geometry property
+        left = m_geomProp;
+    }
+    else if(!left.empty() && right.empty())
+    {
+        // If we have no property name element at all, use the geometry
+        // property and shift the envelope part to the right
+        right = left;
+        left = m_geomProp;
+    }
+
     return L"(" + left + L" ENVELOPEINTERSECTS " + right + L")";
 }
 

Modified: trunk/MgDev/Server/src/Services/Feature/FilterUtil.h
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/FilterUtil.h	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Server/src/Services/Feature/FilterUtil.h	2007-02-08 22:43:38 UTC (rev 1096)
@@ -34,7 +34,7 @@
 {
 public:
 
-    STRING Ogc2FdoFilter(CREFSTRING ogcFilter, MgCoordinateSystemTransform* xform);
+    STRING Ogc2FdoFilter(CREFSTRING ogcFilter, MgCoordinateSystemTransform* xform, CREFSTRING geomProp);
 
 private:
 
@@ -75,6 +75,7 @@
 
     //state variables
     Ptr<MgCoordinateSystemTransform> m_xform;
+    STRING m_geomProp;
 
 };
 

Modified: trunk/MgDev/Server/src/Services/Feature/Makefile.am
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/Makefile.am	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Server/src/Services/Feature/Makefile.am	2007-02-08 22:43:38 UTC (rev 1096)
@@ -62,6 +62,7 @@
   OpCloseFeatureReader.cpp \
   OpGetFeatures.cpp \
   ServerFeatureReader.cpp \
+  ServerFdoFeatureReader.cpp \
   ServerFeatureReaderIdentifierPool.cpp \
   OpGetLongTransactions.cpp \
   ServerGetConnectionPropertyValues.cpp \
@@ -147,6 +148,7 @@
   OpCloseFeatureReader.h \
   OpGetFeatures.h \
   ServerFeatureReader.h \
+  ServerFdoFeatureReader.h \
   ServerFeatureReaderIdentifierPool.h \
   OpGetLongTransactions.h \
   ServerGetConnectionPropertyValues.h \

Added: trunk/MgDev/Server/src/Services/Feature/ServerFdoFeatureReader.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerFdoFeatureReader.cpp	                        (rev 0)
+++ trunk/MgDev/Server/src/Services/Feature/ServerFdoFeatureReader.cpp	2007-02-08 22:43:38 UTC (rev 1096)
@@ -0,0 +1,368 @@
+//
+//  Copyright (C) 2004-2006  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 "ServerFdoFeatureReader.h"
+
+MgServerFdoFeatureReader::MgServerFdoFeatureReader(FdoIFeatureReader* fdoFeatureReader) :
+    m_internalReader(fdoFeatureReader),
+    m_featureIndex(-1),
+    m_maxFeatures(-1)
+{
+}
+
+MgServerFdoFeatureReader::~MgServerFdoFeatureReader()
+{
+}
+
+// Set the max number of features returned by this reader
+void MgServerFdoFeatureReader::SetMaxFeatures(int maxFeatures)
+{
+    m_maxFeatures = maxFeatures;
+}
+
+/// \brief
+/// Gets the definition of the object currently being read. If the user
+/// has requested only a subset of the class properties, the class 
+/// definition reflects what the user has asked, rather than the full class 
+/// definition.
+/// 
+/// \return
+/// Returns the class definition object.
+/// 
+FdoClassDefinition* MgServerFdoFeatureReader::GetClassDefinition()
+{
+    return m_internalReader->GetClassDefinition();
+}
+
+/// \brief
+/// Gets a value indicating the depth of nesting for the current reader.
+/// The depth value increases each time GetFeatureObject is called and a new 
+/// reader is returned. The outermost reader has a depth of 0.
+/// 
+/// \return
+/// Returns the depth
+/// 
+FdoInt32 MgServerFdoFeatureReader::GetDepth()
+{
+    return m_internalReader->GetDepth();
+}
+
+/// \brief
+/// Gets the geometry value of the specified property as a byte array in 
+/// FGF format. Because no conversion is performed, the property must be
+/// of Geometric type; otherwise, an exception is thrown. 
+/// This method is a language-specific performance optimization that returns a
+/// pointer to the array data, rather than to an object that encapsulates
+/// the array.  The array's memory area is only guaranteed to be valid
+/// until a call to ReadNext() or Close(), or the disposal of this reader
+/// object.
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// \param count 
+/// Output the number of bytes in the array.
+/// 
+/// \return
+/// Returns a pointer to the byte array in FGF format.
+/// 
+const FdoByte * MgServerFdoFeatureReader::GetGeometry(FdoString* propertyName, FdoInt32 * count)
+{
+    return m_internalReader->GetGeometry(propertyName, count);
+}
+
+/// \brief
+/// Gets the geometry value of the specified property as a byte array in 
+/// FGF format. Because no conversion is performed, the property must be
+/// of Geometric type; otherwise, an exception is thrown.
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// 
+/// \return
+/// Returns the byte array in FGF format.
+/// 
+FdoByteArray* MgServerFdoFeatureReader::GetGeometry(FdoString* propertyName)
+{
+    return m_internalReader->GetGeometry(propertyName);
+}
+
+/// \brief
+/// Gets a reference to an FdoIFeatureReader to read the data contained in
+/// the object or object collection property. If the property is not an
+/// object property, an exception is thrown.
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// 
+/// \return
+/// Returns the nested feature reader
+/// 
+FdoIFeatureReader* MgServerFdoFeatureReader::GetFeatureObject(FdoString* propertyName)
+{
+    return m_internalReader->GetFeatureObject(propertyName);
+}
+
+/// \brief
+/// Gets the Boolean value of the specified property. No conversion is
+/// performed, thus the property must be FdoDataType_Boolean or an 
+/// exception is thrown.
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// 
+/// \return
+/// Returns the Boolean value.
+/// 
+bool MgServerFdoFeatureReader::GetBoolean(FdoString* propertyName)
+{
+    return m_internalReader->GetBoolean(propertyName);
+}
+
+/// \brief
+/// Gets the byte value of the specified property. No conversion is 
+/// performed, thus the property must be FdoDataType_Byte or an 
+/// exception is thrown.
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// 
+/// \return
+/// Returns the byte value.
+/// 
+FdoByte MgServerFdoFeatureReader::GetByte(FdoString* propertyName)
+{
+    return m_internalReader->GetByte(propertyName);
+}
+
+/// \brief
+///  Gets the date and time value of the specified property. No conversion is 
+/// performed, thus the property must be FdoDataType_DateTime or an 
+/// exception is thrown.
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// 
+/// \return
+/// Returns the date and time value.
+/// 
+FdoDateTime MgServerFdoFeatureReader::GetDateTime(FdoString* propertyName)
+{
+    return m_internalReader->GetDateTime(propertyName);
+}
+
+/// \brief
+/// Gets the double-precision floating point value of the specified property. No
+/// conversion is performed, thus the property must be FdoDataType_Double
+/// or an exception is thrown.
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// 
+/// \return
+/// Returns the double floating point value
+/// 
+double MgServerFdoFeatureReader::GetDouble(FdoString* propertyName)
+{
+    return m_internalReader->GetDouble(propertyName);
+}
+
+/// \brief
+/// Gets the 16-bit integer value of the specified property. No conversion is
+/// performed, thus the property must be FdoDataType_Int16 or an exception
+/// is thrown.
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// 
+/// \return
+/// Returns the FdoInt16 value.
+/// 
+FdoInt16 MgServerFdoFeatureReader::GetInt16(FdoString* propertyName)
+{
+    return m_internalReader->GetInt16(propertyName);
+}
+
+/// \brief
+/// Gets the 32-bit integer value of the specified property. No conversion is
+/// performed, thus the property must be FdoDataType_Int32 or an exception
+/// is thrown.
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// 
+/// \return
+/// Returns the FdoInt32 value
+/// 
+FdoInt32 MgServerFdoFeatureReader::GetInt32(FdoString* propertyName)
+{
+    return m_internalReader->GetInt32(propertyName);
+}
+
+/// \brief
+/// Gets the 64-bit integer value of the specified property. No conversion is
+/// performed, thus the property must be FdoDataType_Int64 or an exception
+/// is thrown.
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// 
+/// \return
+/// Returns the FdoInt64 value.
+/// 
+FdoInt64 MgServerFdoFeatureReader::GetInt64(FdoString* propertyName)
+{
+    return m_internalReader->GetInt64(propertyName);
+}
+
+/// \brief
+/// Gets the Single floating point value of the specified property. No
+/// conversion is performed, thus the property must be FdoDataType_Single
+/// or an exception is thrown.
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// 
+/// \return
+/// Returns the single value
+/// 
+float MgServerFdoFeatureReader::GetSingle(FdoString* propertyName)
+{
+    return m_internalReader->GetSingle(propertyName);
+}
+
+/// \brief
+/// Gets the string value of the specified property. No conversion is
+/// performed, thus the property must be FdoDataType_String or an exception
+/// is thrown.
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// 
+/// \return
+/// Returns the string value
+/// 
+FdoString* MgServerFdoFeatureReader::GetString(FdoString* propertyName)
+{
+    return m_internalReader->GetString(propertyName);
+}
+
+/// \brief
+/// Gets a LOBValue reference. The LOB is fully read in and data available.
+/// Because no conversion is performed, the property must be FdoDataType_BLOB or
+/// FdoDataType_CLOB etc. (a LOB type)
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// 
+/// \return
+/// Returns the reference to LOBValue
+/// 
+FdoLOBValue* MgServerFdoFeatureReader::GetLOB(FdoString* propertyName)
+{
+    return m_internalReader->GetLOB(propertyName);
+}
+
+/// \brief
+/// Gets a reference of the specified LOB property as a FdoBLOBStreamReader or
+/// FdoCLOBStreamReader etc. to allow reading in blocks of data.
+/// Because no conversion is performed, the property must be FdoDataType_BLOB 
+/// or FdoDataType_CLOB etc. (a LOB type)
+/// Cast the FdoIStreamReader to the appropiate LOB Stream Reader.
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// 
+/// \return
+/// Returns a reference to a LOB stream reader
+/// 
+FdoIStreamReader* MgServerFdoFeatureReader::GetLOBStreamReader(const wchar_t* propertyName )
+{
+    return m_internalReader->GetLOBStreamReader(propertyName);
+}
+
+/// \brief
+/// Returns true if the value of the specified property is null.
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// 
+/// \return
+/// Returns true if the value is null.
+/// 
+bool MgServerFdoFeatureReader::IsNull(FdoString* propertyName)
+{
+    return m_internalReader->IsNull(propertyName);
+}
+
+/// \brief
+/// Gets the raster object of the specified property.
+/// Because no conversion is performed, the property must be
+/// of Raster type; otherwise, an exception is thrown.
+/// 
+/// \param propertyName 
+/// Input the property name.
+/// 
+/// \return
+/// Returns the raster object.
+/// 
+FdoIRaster* MgServerFdoFeatureReader::GetRaster(FdoString* propertyName)
+{
+    return m_internalReader->GetRaster(propertyName);
+}
+
+/// \brief
+/// Advances the reader to the next item and returns true if there is
+/// another object to read or false if reading is complete. The default
+/// position of the reader is prior to the first item. Thus you must
+/// call ReadNext to begin accessing any data.
+/// 
+/// \return
+/// Returns true if there is a next item.
+/// 
+bool MgServerFdoFeatureReader::ReadNext()
+{
+    if(m_maxFeatures > 0 && m_featureIndex < m_maxFeatures)
+    {
+        m_featureIndex++;
+        return m_internalReader->ReadNext();
+    }
+    else
+    {
+        return false;
+    }
+}
+
+/// \brief
+/// Closes the FdoIFeatureReader object, freeing any resources it may be holding.
+/// 
+/// \return
+/// Returns nothing
+/// 
+void MgServerFdoFeatureReader::Close()
+{
+    return m_internalReader->Close();
+}
+
+/// \brief
+/// Dispose this object.
+/// 
+/// \return
+/// Returns nothing
+/// 
+void MgServerFdoFeatureReader::Dispose()
+{
+}
\ No newline at end of file

Added: trunk/MgDev/Server/src/Services/Feature/ServerFdoFeatureReader.h
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerFdoFeatureReader.h	                        (rev 0)
+++ trunk/MgDev/Server/src/Services/Feature/ServerFdoFeatureReader.h	2007-02-08 22:43:38 UTC (rev 1096)
@@ -0,0 +1,308 @@
+//
+//  Copyright (C) 2004-2006  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_SERVER_FDO_FEATURE_READER_H
+#define _MG_SERVER_FDO_FEATURE_READER_H
+
+#include "Fdo.h"
+
+/////////////////////////////////////////////////////////////////
+///<summary>
+/// This class wraps an FdoIFeatureReader object in order to
+/// add custom behavior
+///</summary>
+
+class MgServerFdoFeatureReader : public FdoIFeatureReader
+{
+public:
+
+    MgServerFdoFeatureReader(FdoIFeatureReader* fdoFeatureReader);
+    virtual ~MgServerFdoFeatureReader();
+
+    // Set the max number of features returned by this reader
+    void SetMaxFeatures(int maxFeatures);
+
+    /// \brief
+    /// Gets the definition of the object currently being read. If the user
+    /// has requested only a subset of the class properties, the class 
+    /// definition reflects what the user has asked, rather than the full class 
+    /// definition.
+    /// 
+    /// \return
+    /// Returns the class definition object.
+    /// 
+    virtual FdoClassDefinition* GetClassDefinition();
+
+    /// \brief
+    /// Gets a value indicating the depth of nesting for the current reader.
+    /// The depth value increases each time GetFeatureObject is called and a new 
+    /// reader is returned. The outermost reader has a depth of 0.
+    /// 
+    /// \return
+    /// Returns the depth
+    /// 
+    virtual FdoInt32 GetDepth();
+
+    /// \brief
+    /// Gets the geometry value of the specified property as a byte array in 
+    /// FGF format. Because no conversion is performed, the property must be
+    /// of Geometric type; otherwise, an exception is thrown. 
+    /// This method is a language-specific performance optimization that returns a
+    /// pointer to the array data, rather than to an object that encapsulates
+    /// the array.  The array's memory area is only guaranteed to be valid
+    /// until a call to ReadNext() or Close(), or the disposal of this reader
+    /// object.
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// \param count 
+    /// Output the number of bytes in the array.
+    /// 
+    /// \return
+    /// Returns a pointer to the byte array in FGF format.
+    /// 
+    virtual const FdoByte * GetGeometry(FdoString* propertyName, FdoInt32 * count);
+
+    /// \brief
+    /// Gets the geometry value of the specified property as a byte array in 
+    /// FGF format. Because no conversion is performed, the property must be
+    /// of Geometric type; otherwise, an exception is thrown.
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// 
+    /// \return
+    /// Returns the byte array in FGF format.
+    /// 
+    virtual FdoByteArray* GetGeometry(FdoString* propertyName);
+
+    /// \brief
+    /// Gets a reference to an FdoIFeatureReader to read the data contained in
+    /// the object or object collection property. If the property is not an
+    /// object property, an exception is thrown.
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// 
+    /// \return
+    /// Returns the nested feature reader
+    /// 
+    virtual FdoIFeatureReader* GetFeatureObject(FdoString* propertyName);
+
+    /// \brief
+    /// Gets the Boolean value of the specified property. No conversion is
+    /// performed, thus the property must be FdoDataType_Boolean or an 
+    /// exception is thrown.
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// 
+    /// \return
+    /// Returns the Boolean value.
+    /// 
+    virtual bool GetBoolean(FdoString* propertyName);
+
+    /// \brief
+    /// Gets the byte value of the specified property. No conversion is 
+    /// performed, thus the property must be FdoDataType_Byte or an 
+    /// exception is thrown.
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// 
+    /// \return
+    /// Returns the byte value.
+    /// 
+    virtual FdoByte GetByte(FdoString* propertyName);
+
+    /// \brief
+    ///  Gets the date and time value of the specified property. No conversion is 
+    /// performed, thus the property must be FdoDataType_DateTime or an 
+    /// exception is thrown.
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// 
+    /// \return
+    /// Returns the date and time value.
+    /// 
+    virtual FdoDateTime GetDateTime(FdoString* propertyName);
+
+    /// \brief
+    /// Gets the double-precision floating point value of the specified property. No
+    /// conversion is performed, thus the property must be FdoDataType_Double
+    /// or an exception is thrown.
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// 
+    /// \return
+    /// Returns the double floating point value
+    /// 
+    virtual double GetDouble(FdoString* propertyName);
+
+    /// \brief
+    /// Gets the 16-bit integer value of the specified property. No conversion is
+    /// performed, thus the property must be FdoDataType_Int16 or an exception
+    /// is thrown.
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// 
+    /// \return
+    /// Returns the FdoInt16 value.
+    /// 
+    virtual FdoInt16 GetInt16(FdoString* propertyName);
+
+    /// \brief
+    /// Gets the 32-bit integer value of the specified property. No conversion is
+    /// performed, thus the property must be FdoDataType_Int32 or an exception
+    /// is thrown.
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// 
+    /// \return
+    /// Returns the FdoInt32 value
+    /// 
+    virtual FdoInt32 GetInt32(FdoString* propertyName);
+
+    /// \brief
+    /// Gets the 64-bit integer value of the specified property. No conversion is
+    /// performed, thus the property must be FdoDataType_Int64 or an exception
+    /// is thrown.
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// 
+    /// \return
+    /// Returns the FdoInt64 value.
+    /// 
+    virtual FdoInt64 GetInt64(FdoString* propertyName);
+
+    /// \brief
+    /// Gets the Single floating point value of the specified property. No
+    /// conversion is performed, thus the property must be FdoDataType_Single
+    /// or an exception is thrown.
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// 
+    /// \return
+    /// Returns the single value
+    /// 
+    virtual float GetSingle(FdoString* propertyName);
+
+    /// \brief
+    /// Gets the string value of the specified property. No conversion is
+    /// performed, thus the property must be FdoDataType_String or an exception
+    /// is thrown.
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// 
+    /// \return
+    /// Returns the string value
+    /// 
+    virtual FdoString* GetString(FdoString* propertyName);
+
+    /// \brief
+    /// Gets a LOBValue reference. The LOB is fully read in and data available.
+    /// Because no conversion is performed, the property must be FdoDataType_BLOB or
+    /// FdoDataType_CLOB etc. (a LOB type)
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// 
+    /// \return
+    /// Returns the reference to LOBValue
+    /// 
+    virtual FdoLOBValue* GetLOB(FdoString* propertyName);
+
+    /// \brief
+    /// Gets a reference of the specified LOB property as a FdoBLOBStreamReader or
+    /// FdoCLOBStreamReader etc. to allow reading in blocks of data.
+    /// Because no conversion is performed, the property must be FdoDataType_BLOB 
+    /// or FdoDataType_CLOB etc. (a LOB type)
+    /// Cast the FdoIStreamReader to the appropiate LOB Stream Reader.
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// 
+    /// \return
+    /// Returns a reference to a LOB stream reader
+    /// 
+    virtual FdoIStreamReader* GetLOBStreamReader(const wchar_t* propertyName );
+
+    /// \brief
+    /// Returns true if the value of the specified property is null.
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// 
+    /// \return
+    /// Returns true if the value is null.
+    /// 
+    virtual bool IsNull(FdoString* propertyName);
+
+    /// \brief
+    /// Gets the raster object of the specified property.
+    /// Because no conversion is performed, the property must be
+    /// of Raster type; otherwise, an exception is thrown.
+    /// 
+    /// \param propertyName 
+    /// Input the property name.
+    /// 
+    /// \return
+    /// Returns the raster object.
+    /// 
+    virtual FdoIRaster* GetRaster(FdoString* propertyName);
+
+    /// \brief
+    /// Advances the reader to the next item and returns true if there is
+    /// another object to read or false if reading is complete. The default
+    /// position of the reader is prior to the first item. Thus you must
+    /// call ReadNext to begin accessing any data.
+    /// 
+    /// \return
+    /// Returns true if there is a next item.
+    /// 
+    virtual bool ReadNext();
+
+    /// \brief
+    /// Closes the FdoIFeatureReader object, freeing any resources it may be holding.
+    /// 
+    /// \return
+    /// Returns nothing
+    /// 
+    virtual void Close();
+
+    /// \brief
+    /// Dispose this object.
+    /// 
+    /// \return
+    /// Returns nothing
+    /// 
+    virtual void Dispose();
+
+private:
+
+    FdoIFeatureReader* m_internalReader;
+    int m_maxFeatures;
+    int m_featureIndex;
+};
+#endif

Modified: trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.cpp	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.cpp	2007-02-08 22:43:38 UTC (rev 1096)
@@ -38,6 +38,7 @@
 #include "ServerUpdateFeatures.h"
 #include "ServerCreateFeatureSource.h"
 #include "ServerFeatureReader.h"
+#include "ServerFdoFeatureReader.h"
 #include "ServerEnumerateDataStores.h"
 #include "ServerGetSchemaMapping.h"
 #include "FilterUtil.h"
@@ -50,6 +51,7 @@
 
 IMPLEMENT_CREATE_SERVICE(MgServerFeatureService)
 
+
 //////////////////////////////////////////////////////////////////
 /// <summary>
 /// Default constructor - needed to prevent a compile error under GCC 3
@@ -1276,7 +1278,8 @@
     if (!wfsFilter.empty())
     {
         MgOgcFilterUtil u;
-        options->SetFilter(u.Ogc2FdoFilter(wfsFilter, trans));
+        STRING fdoFilterString = u.Ogc2FdoFilter(wfsFilter, trans, geomPropName);
+        options->SetFilter(fdoFilterString);
     }
 
     // TODO: can FeatureName be an extension name rather than a FeatureClass?
@@ -1285,6 +1288,10 @@
     //get underlying FDO feature reader
     FdoPtr<FdoIFeatureReader> fdoRdr = ((MgServerFeatureReader*)(rdr.p))->GetInternalReader();
 
+    //wrap the reader to enforce maxfeatures
+    MgServerFdoFeatureReader maxFeatureReader(fdoRdr);
+    maxFeatureReader.SetMaxFeatures(maxFeatures);
+
     //generate a file name to serialize wfs data
     STRING fileName = MgFileUtil::GenerateTempFileName(false, L"wfs", L"xml");
 
@@ -1311,7 +1318,7 @@
     FdoPtr<FdoXmlFeaturePropertyWriter> propWriter = FdoXmlFeaturePropertyWriter::Create(xmlWriter);
     FdoPtr<FdoXmlFeatureWriter> featWriter = FdoXmlFeatureWriter::Create(propWriter, flags);
 
-    FdoXmlFeatureSerializer::XmlSerialize(fdoRdr, featWriter, flags);
+    FdoXmlFeatureSerializer::XmlSerialize(&maxFeatureReader, featWriter, flags);
 
     flags = NULL;
     featWriter = NULL;

Modified: trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcproj
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcproj	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcproj	2007-02-08 22:43:38 UTC (rev 1096)
@@ -1624,6 +1624,30 @@
 			>
 		</File>
 		<File
+			RelativePath=".\ServerFdoFeatureReader.cpp"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				ExcludedFromBuild="true"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				ExcludedFromBuild="true"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath=".\ServerFdoFeatureReader.h"
+			>
+		</File>
+		<File
 			RelativePath=".\ServerFeatureConnection.cpp"
 			>
 			<FileConfiguration

Modified: trunk/MgDev/Server/src/Services/Feature/ServerFeatureServiceBuild.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerFeatureServiceBuild.cpp	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Server/src/Services/Feature/ServerFeatureServiceBuild.cpp	2007-02-08 22:43:38 UTC (rev 1096)
@@ -45,6 +45,7 @@
 #include "OpCloseFeatureReader.cpp"
 #include "OpGetFeatures.cpp"
 #include "ServerFeatureReader.cpp"
+#include "ServerFdoFeatureReader.cpp"
 #include "ServerFeatureReaderIdentifierPool.cpp"
 #include "OpGetLongTransactions.cpp"
 #include "ServerGetConnectionPropertyValues.cpp"

Modified: trunk/MgDev/Server/src/Wfs/1.0.0.xml.awd
===================================================================
--- trunk/MgDev/Server/src/Wfs/1.0.0.xml.awd	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Server/src/Wfs/1.0.0.xml.awd	2007-02-08 22:43:38 UTC (rev 1096)
@@ -1,4 +1,4 @@
-<?xml version='1.0'?>
+<?xml version='1.0'?>
 <Template service="WFS" version="1.0.0">
 
 <Definitions>
@@ -35,7 +35,11 @@
       <?Ifdef item="Feature.Keywords"?>
       <Keyword>&Feature.Keywords;</Keyword>
       <?Endif?>
+      <?Ifdef item="Feature.PrimarySRS"?>
+      <SRS>&Feature.PrimarySRS;</SRS>
+      <?Else?>
       <?Enum list="&Feature.Bounds;" item="Bounds" using="&SRS.xml;"?>
+      <?Endif?>
       <?Enum list="&Feature.Bounds;" item="Bounds" using="&LatLonBoundingBox.xml;"?>
     </FeatureType>
   </Define>
@@ -46,9 +50,9 @@
   </Define>
 
   <!-- Sniff out the EPSG:4326 item and use it for LatLon bounds -->
-  <Define item="LatLonBoundingBox.xml"><?If l="&Enum.item.SRS" op="eq" r="EPSG:4326"?>
+  <Define item="LatLonBoundingBox.xml">
     <LatLongBoundingBox minx="&Enum.item.west;" miny="&Enum.item.south;" maxx="&Enum.item.east;" maxy="&Enum.item.north;"/>
-    <?Endif?></Define>
+  </Define>
   <Define item="BoundingBox.xml">
     <BoundingBox SRS="&Enum.item.SRS;" minx="&Enum.item.west;" miny="&Enum.item.south;" maxx="&Enum.item.east;" maxy="&Enum.item.north;"/>
   </Define>

Modified: trunk/MgDev/Server/src/Wfs/1.1.0.xml.awd
===================================================================
--- trunk/MgDev/Server/src/Wfs/1.1.0.xml.awd	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Server/src/Wfs/1.1.0.xml.awd	2007-02-08 22:43:38 UTC (rev 1096)
@@ -22,7 +22,7 @@
    <?Endif?>
    <wfs:DefaultSRS>&Feature.DefaultSRS;</wfs:DefaultSRS>
    <?Ifdef item="Feature.OtherSRS"?>
-    <?EnumDelim list="&Feature.OtherSRS;" using="OtherSRS.xml"?>
+    <?EnumDelim list="&Feature.OtherSRS;" using="&OtherSRS.xml"?>
    <?Endif?>
    <wfs:OutputFormats>
     <?Enum list="&Formats.GetFeature;" using="&Format.xml"?>

Modified: trunk/MgDev/Server/src/Wms/1.0.0.xml.awd
===================================================================
--- trunk/MgDev/Server/src/Wms/1.0.0.xml.awd	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Server/src/Wms/1.0.0.xml.awd	2007-02-08 22:43:38 UTC (rev 1096)
@@ -256,7 +256,6 @@
     <Title>&Service.Title;</Title>
     <?Enum list="&ReferenceSystems;" using="&RS.xml;"?>
     <LatLonBoundingBox minx="-180" miny="-90" maxx="180" maxy="90"/>
-    <BoundingBox SRS="EPSG:4326" minx="-180" miny="-90" maxx="180" maxy="90"/>
    <?EnumLayers using="&Layer.xml;" ?>
   </Layer>
  </Capability>

Modified: trunk/MgDev/Server/src/Wms/1.1.0.xml.awd
===================================================================
--- trunk/MgDev/Server/src/Wms/1.1.0.xml.awd	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Server/src/Wms/1.1.0.xml.awd	2007-02-08 22:43:38 UTC (rev 1096)
@@ -258,7 +258,6 @@
      <Title>&Service.Title;</Title>
      <?Enum list="&ReferenceSystems;" using="&RS.xml;"?>
      <LatLonBoundingBox minx="-180" miny="-90" maxx="180" maxy="90"/>
-     <BoundingBox SRS="EPSG:4326" minx="-180" miny="-90" maxx="180" maxy="90"/>
      <?EnumLayers using="&Layer.xml;" ?>
     </Layer>
 

Modified: trunk/MgDev/Server/src/Wms/1.1.1.xml.awd
===================================================================
--- trunk/MgDev/Server/src/Wms/1.1.1.xml.awd	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Server/src/Wms/1.1.1.xml.awd	2007-02-08 22:43:38 UTC (rev 1096)
@@ -243,7 +243,6 @@
      <Title>&Service.Title;</Title>
      <?Enum list="&ReferenceSystems;" using="&RS.xml;"?>
      <LatLonBoundingBox minx="-180" miny="-90" maxx="180" maxy="90"/>
-     <BoundingBox SRS="EPSG:4326" minx="-180" miny="-90" maxx="180" maxy="90"/>
      <?EnumLayers using="&Layer.xml;" ?>
     </Layer>
    </Capability>

Added: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/describefeaturetypewfsform.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/describefeaturetypewfsform.html	                        (rev 0)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/describefeaturetypewfsform.html	2007-02-08 22:43:38 UTC (rev 1096)
@@ -0,0 +1,25 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<script type="text/javascript" src="setactiontarget.js" >
+</script>
+</head>
+<body>
+<form name="input" action="" method="get">
+<b>Request:</b>
+<input type="text" name="REQUEST" value="DESCRIBEFEATURETYPE" size="50">
+<p> Service:
+<input type="text" name="SERVICE" value="WFS" size="10">
+<p> Version:
+<input type="text" name="VERSION" value="1.0.0" size="10">
+<p> Type Name:
+<input type="text" name="TYPENAME" value="ns34414117:Parcels" size="10">
+<p> Output Format:
+<select name="OUTPUTFORMAT">
+<option value="GML2">GML2</option>
+</select>
+<p>
+<input type="submit" value="Submit" onclick="SetActionTarget()"> <input type="reset">
+</form>
+</body>
+</html>

Added: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getcapabilitieswfsform.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getcapabilitieswfsform.html	                        (rev 0)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getcapabilitieswfsform.html	2007-02-08 22:43:38 UTC (rev 1096)
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<script type="text/javascript" src="setactiontarget.js" >
+</script>
+</head>
+<body>
+<form name="input" action="" method="get">
+<b>Request:</b>
+<input type="text" name="REQUEST" value="GETCAPABILITIES" size="50">
+<p> Service:
+<input type="text" name="SERVICE" value="WFS" size="10">
+<p> Version:
+<input type="text" name="VERSION" value="1.0.0" size="10">
+<p> Format:
+<select name="FORMAT">
+<option value="text/xml">text/xml</option>
+<option value="text/html">text/html</option>
+</select>
+<p>
+<input type="submit" value="Submit" onclick="SetActionTarget()"> <input type="reset">
+</form>
+</body>
+</html>

Added: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getfeaturewfsform.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getfeaturewfsform.html	                        (rev 0)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getfeaturewfsform.html	2007-02-08 22:43:38 UTC (rev 1096)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<script type="text/javascript" src="setactiontarget.js" >
+</script>
+</head>
+<body>
+<form name="input" action="" method="get">
+<b>Request:</b>
+<input type="text" name="REQUEST" value="GETFEATURE" size="50">
+<p> Service:
+<input type="text" name="SERVICE" value="WFS" size="10">
+<p> Version:
+<input type="text" name="VERSION" value="1.0.0" size="10">
+<p> Property Name(s):
+<input type="text" name="PROPERTYNAME" value="" size="50">
+<p> Max Features:
+<input type="text" name="MAXFEATURES" value="1000" size="10">
+<p> SRS Name:
+<input type="text" name="SRSNAME" value="EPSG:4326" size="10">
+<p> Type Name(s):
+<input type="text" name="TYPENAME" value="ns55197509:VotingDistricts" size="50">
+<p> Feature ID(s):
+<input type="text" name="FEATUREID" value="" size="50">
+<p> Filter:
+<input type="text" name="FILTER" value="" size="50">
+<p> Bounding Box:
+<input type="text" name="BBOX" value="" size="50">
+<p> Output Format:
+<select name="OUTPUTFORMAT">
+<option value="GML2">GML2</option>
+</select>
+<p>
+<input type="submit" value="Submit" onclick="SetActionTarget()"> <input type="reset">
+</form>
+</body>
+</html>

Modified: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/services.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/services.html	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/services.html	2007-02-08 22:43:38 UTC (rev 1096)
@@ -19,6 +19,7 @@
 <li><a href="tileserviceapi.html" target="apilist">Tile</a></li>
 <li><a href="kmlserviceapi.html" target="apilist">Kml</a></li>
 <li><a href="wmsserviceapi.html" target="apilist">Wms</a></li>
+<li><a href="wfsserviceapi.html" target="apilist">Wfs</a></li>
 <p></p>
 <b>Miscellaneous API</b>
 <li><a href="coordinatesystemapi.html" target="apilist">Coordinate System</a></li>

Added: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/wfsserviceapi.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/wfsserviceapi.html	                        (rev 0)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/wfsserviceapi.html	2007-02-08 22:43:38 UTC (rev 1096)
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+    <head>
+        <title></title>
+        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+        <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
+        <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+    </head>
+    <body>
+        <UL>
+            <LI>
+                <A href="getcapabilitieswfsform.html" target="showform">GetCapabilities</a>
+            </LI>
+            <LI>
+                <A href="describefeaturetypewfsform.html" target="showform">DescribeFeatureType</a>
+            </LI>
+             <LI>
+                <A href="getfeaturewfsform.html" target="showform">GetFeature</a>
+            </LI>
+        </UL>
+        <P>&nbsp;</P>
+    </body>
+</html>

Modified: trunk/MgDev/Web/src/HttpHandler/HttpWfsDescribeFeatureType.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpWfsDescribeFeatureType.cpp	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Web/src/HttpHandler/HttpWfsDescribeFeatureType.cpp	2007-02-08 22:43:38 UTC (rev 1096)
@@ -57,11 +57,6 @@
 
     MG_HTTP_HANDLER_TRY()
 
-    Ptr<MgResourceService> pResourceService = (MgResourceService*)(CreateService(MgServiceType::ResourceService));
-    Ptr<MgFeatureService> pFeatureService = (MgFeatureService*)(CreateService(MgServiceType::FeatureService));
-    //
-    MgWfsFeatureDefinitions oFeatureTypes(pResourceService,pFeatureService);
-
     // We have to wrap the request parameters, since the outside
     // world is case-sensitive (with respect to names,) but
     // we need our parameters NOT to be so.
@@ -74,20 +69,35 @@
     MgUserInformation::SetCurrentUserInfo(m_userInfo);
 
     // Instance a server-lette
-    MgOgcWfsServer Wfs(Parms,Out,oFeatureTypes);
+    MgOgcWfsServer Wfs(Parms,Out);
 
+    // Determine required feature types
+    CPSZ pszFeatureTypes = Wfs.RequestParameter(MgHttpResourceStrings::reqWfsTypeName.c_str());
+    STRING sFeatureTypes = pszFeatureTypes? pszFeatureTypes : _("");
+    Ptr<MgStringCollection> featureTypeList;
+    if(sFeatureTypes.empty())
+    {
+        featureTypeList = NULL;
+    }
+    else
+    {
+        featureTypeList = MgStringCollection::ParseCollection(sFeatureTypes, L",");
+    }
+
+    Ptr<MgResourceService> pResourceService = (MgResourceService*)(CreateService(MgServiceType::ResourceService));
+    Ptr<MgFeatureService> pFeatureService = (MgFeatureService*)(CreateService(MgServiceType::FeatureService));
+    
+    // Retrieve feature definitions
+    MgWfsFeatureDefinitions oFeatureTypes(pResourceService,pFeatureService,featureTypeList);
+    Wfs.SetFeatureDefinitions(&oFeatureTypes);
+
     // This is a comma-sep a list.  If empty, == all.
     // If it's just one feature (no comma sep found) let's do
     // a single response, else let's recursively enumerate the features.
-    CPSZ pszFeatureTypes = Wfs.RequestParameter(MgHttpResourceStrings::reqWfsTypeName.c_str());
-    STRING sFeatureTypes = pszFeatureTypes? pszFeatureTypes : _("");
     if(sFeatureTypes.length() > 0 && sFeatureTypes.find(_(",")) == STRING::npos) {
         // TODO: assumes that this is GML type.
         //STRING sOutputFormat = origReqParams->GetParameterValue(_("OUTPUTFORMAT"));
 
-        // Create Proxy Feature Service instance
-        Ptr<MgFeatureService> pFeatureService = (MgFeatureService*)(CreateService(MgServiceType::FeatureService));
-
         STRING::size_type iPos = sFeatureTypes.find(_(":"));
         if(iPos != STRING::npos) {
             STRING sPrefix = sFeatureTypes.substr(0,iPos);

Modified: trunk/MgDev/Web/src/HttpHandler/HttpWfsGetFeature.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpWfsGetFeature.cpp	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Web/src/HttpHandler/HttpWfsGetFeature.cpp	2007-02-08 22:43:38 UTC (rev 1096)
@@ -129,11 +129,6 @@
 // Acquire data required to generate the response
 void MgHttpWfsGetFeature::AcquireResponseData(MgOgcServer* ogcServer)
 {
-    Ptr<MgResourceService> pResourceService = (MgResourceService*)(CreateService(MgServiceType::ResourceService));
-    Ptr<MgFeatureService> pFeatureService = (MgFeatureService*)(CreateService(MgServiceType::FeatureService));
-    //
-    MgWfsFeatureDefinitions oFeatureTypes(pResourceService,pFeatureService);
-
     MgOgcWfsServer* wfsServer = (MgOgcWfsServer*)ogcServer;
     if(wfsServer != NULL)
     {
@@ -145,8 +140,11 @@
             Ptr<MgStringCollection> featureTypeList = m_getFeatureParams->GetFeatureTypes();
             if(featureTypeList != NULL && featureTypeList->GetCount() > 0)
             {
-                // Create an instance of the feature service
+                // Create required services
                 Ptr<MgFeatureService> featureService = (MgFeatureService*)(CreateService(MgServiceType::FeatureService));
+                Ptr<MgResourceService> resourceService = (MgResourceService*)(CreateService(MgServiceType::ResourceService));
+                
+                MgWfsFeatureDefinitions oFeatureTypes(resourceService,featureService,featureTypeList);
 
                 int numFeaturesRetrieved = 0;
                 int maxFeatures = m_getFeatureParams->GetMaxFeatures();

Modified: trunk/MgDev/Web/src/HttpHandler/OgcWfsServer.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/OgcWfsServer.cpp	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Web/src/HttpHandler/OgcWfsServer.cpp	2007-02-08 22:43:38 UTC (rev 1096)
@@ -411,4 +411,10 @@
     m_pGetFeatureParams = SAFE_ADDREF(pGetFeatureParams);
 }
 
+void MgOgcWfsServer::SetFeatureDefinitions(MgWfsFeatureDefinitions* pFeatureDefs)
+{
+    m_pFeatures = pFeatureDefs;
+}
 
+
+

Modified: trunk/MgDev/Web/src/HttpHandler/OgcWfsServer.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/OgcWfsServer.h	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Web/src/HttpHandler/OgcWfsServer.h	2007-02-08 22:43:38 UTC (rev 1096)
@@ -31,6 +31,7 @@
     void GenerateTypeNameException(CREFSTRING sTypeName);
     void SetFeatures(MgWfsFeatures* pFeatures);
     void SetGetFeatureRequestParams(WfsGetFeatureParams* pGetFeatureParams);
+    void SetFeatureDefinitions(MgWfsFeatureDefinitions* pFeatureDefs);
 
 protected:
     virtual void RespondToRequest();

Modified: trunk/MgDev/Web/src/HttpHandler/WfsFeatureDefinitions.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/WfsFeatureDefinitions.cpp	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Web/src/HttpHandler/WfsFeatureDefinitions.cpp	2007-02-08 22:43:38 UTC (rev 1096)
@@ -46,166 +46,31 @@
 #include "OgcFramework.h"
 #include "WfsFeatureDefinitions.h"
 
-MgWfsFeatureDefinitions::MgWfsFeatureDefinitions(MgResourceService* pResourceService,MgFeatureService* pFeatureService)
+MgWfsFeatureDefinitions::MgWfsFeatureDefinitions(MgResourceService* pResourceService,
+                                                 MgFeatureService* pFeatureService)
 :   m_pResourceService(pResourceService)
 ,   m_pFeatureService(pFeatureService)
+,   m_pFeatureTypes(NULL)
 ,   m_pXmlInput(NULL)
 ,   m_sSubsetOfTypes(_("\n"))
 ,   m_bOk(false)
 {
+    Initialize();
+}
 
-    /*
-    // NOTE: It would be cool if this logic could exist on the server, allowing only
-    // one round-trip between webtier and server for this entire aggregated bit of info.
-    */
-
-    // Create MgResourceIdentifier
-    MgResourceIdentifier mgrIdentifier(_("Library://"));
-
-    // Run API command
-    STRING sType = _("FeatureSource");
-    INT32 keProperties = MgResourceHeaderProperties::Metadata;
-    STRING sDontCare(_(""));
-    Ptr<MgByteReader> Result =
-          pResourceService->EnumerateResources(&mgrIdentifier, // "Library://"
-                                                -1,             // Infinite depth
-                                                sType,          // "LayerDefinition"
-                                                keProperties,   // want metadata, not security
-                                                sDontCare,      // start date; don't care
-                                                sDontCare);     // end date; don't care
-
-    STRING sLayers = Result->ToString();
-    MgXmlParser Input(sLayers.c_str());
-    Input.SetOptions(keSkipWhitespace|keSkipComments|keSkipProcessingInstructions);
-
-    // Scoot us up to the first element
-    Input.Next();
-
-    // Is it a ResourceList element?
-    MgXmlSynchronizeOnElement ResourceList(Input,_("ResourceList"));
-    if(!ResourceList.AtBegin())
-        return;
-
-    // Everything will be put into this thing
-    // though we don't get things in the right order,
-    // so some juggling is called for.
-    // The end result is some "pseudo-XML" (no single root element)
-    // that is a collection of feature classes, as follows:
-    //  
-    //  <FeatureClass id='ns180401301:BuildingOutlines' xmlns:ns180401301='Library://Samples/Sheboygan/Data/BuildingOutlines.FeatureSource'>
-    //  <Define item='Feature.Name'>BuildingOutlines</Define>
-    //  <Define item='Feature.Title'>BuildingOutlines</Define>
-    //  <Define item='Feature.FullName'>ns180401301:BuildingOutlines</Define>
-    //  <Define item='Feature.Description'></Define>
-    //  <Define item='Feature.Prefix'>ns180401301</Define>
-    //  <Define item='Feature.Resource'>Library://Samples/Sheboygan/Data/BuildingOutlines.FeatureSource</Define>
-    //  <Define item='Feature.PrimarySRS'>EPSG:4326</Define>
-    //  <Define item='Feature.Bounds'><Bounds SRS="EPSG:4326" west="-87.74" south="43.68" east="-87.69" north="43.815"></Define>
-    //  <Define item='Feature.Abstract'>Building Outlines.</Define>
-    //  <Define item='Feature.Keywords'>Buildings, Outlines</Define>
-    //  <Define item='Feature.Title'>Building Outlines</Define>
-    //  <Define item='Feature.IsPublished'>1</Define>
-    //  </FeatureClass>
-
-    CStringStream oTheWholeEnchilada;
-
-    while(!ResourceList.AtEnd()) {
-        // And just inside of that, is it a ResourceDocument element?
-        MgXmlSynchronizeOnElement ResourceDocument(Input,_("ResourceDocument"));
-        if(!ResourceDocument.AtBegin())
-            return; // Something is wrong.  We leave.
-
-        STRING sResource; // "Library://....FeatureSource"
-        STRING sPrefix;   // "ns######" based on hash of sResource.
-
-        CStringStream oDefinitions;
-        // We're looking specifically for ResourceId elements.
-        while(!ResourceDocument.AtEnd()) {
-            if(GetElementContents(Input,_("ResourceId"),sResource)) {
-                // We get the canonical xmlns:prefix associated with the resource.
-                FeatureSourceToPrefix(sResource,sPrefix);
-
-                AddDefinition(oDefinitions,_("Feature.Prefix"),sPrefix.c_str());
-                AddDefinition(oDefinitions,_("Feature.Resource"),sResource.c_str());
-            }
-            else if(GetMetadataDefinitions(Input,oDefinitions)) {
-            }
-            else {
-              SkipElement(Input,NULL);
-            }
-        } // while not at end of ResourceDocument
-
-        // Now, given the feature source, we need to find out stuff about
-        // it; there are one or more Feature *Classes* defined within it.
-        MgResourceIdentifier idResource(sResource);
-
-        // And what classes we can expect to find.
-        // That's done indirectly by enumerating the schemas the source reports...
-        STRING sDontCare(_(""));
-        Ptr<MgFeatureSchemaCollection> pSchemas = this->m_pFeatureService->DescribeSchema(&idResource,sDontCare);
-
-        for(INT32 iSchema=0; iSchema<pSchemas->GetCount(); iSchema++) {
-            Ptr<MgFeatureSchema> pSchema = pSchemas->GetItem(iSchema);
-            Ptr<MgClassDefinitionCollection> pClasses = pSchema->GetClasses();
-            // ... and by the classes each schema reports.
-            for(INT32 iClass=0; iClass<pClasses->GetCount(); iClass++) {
-                Ptr<MgClassDefinition> pClass = pClasses->GetItem(iClass);
-
-                // TODO: STALE?
-                // What internally is known as the name is really
-                // the human-readable thing, which in OGC parlance is the title.
-                STRING sName = pClass->GetName();
-
-                // TODO: STALE?
-                // And what OGC wants to call a Name is really the internal
-                // cookie.  We use the stripped down resource name (source)
-                // plus the human-readable name
-                STRING sFullName = sPrefix+_(":")+sName;
-
-                // Now, spew out everything we know about this class.
-                STRING sFeatureNameAttr(_("id='"));
-                sFeatureNameAttr += sFullName;
-                sFeatureNameAttr += _("' xmlns:");
-                sFeatureNameAttr += sPrefix;
-                sFeatureNameAttr += _("='");
-                sFeatureNameAttr += sResource;
-                sFeatureNameAttr += _("'");
-
-                MgXmlElementEmitter oXmlFeatureClass(oTheWholeEnchilada,_("FeatureClass"),sFeatureNameAttr.c_str());
-                AddDefinition(oTheWholeEnchilada,_("Feature.Name"),sName.c_str());
-                AddDefinition(oTheWholeEnchilada,_("Feature.Title"),sName.c_str());
-                AddDefinition(oTheWholeEnchilada,_("Feature.FullName"),sFullName.c_str());
-                // Stuff like Feature.Prefix and Feature.Resource are in oDefinitions, and
-                // will be appended below.
-
-                // This is strange; it's called the "Description", but ends up being
-                // the type's name. 
-                STRING sDescription = pClass->GetDescription();
-                AddDefinition(oTheWholeEnchilada,_("Feature.Description"),sDescription.c_str());
-
-                // TODO: evaluate what, of interest, can be found here.
-                //Ptr<MgPropertyDefinitionCollection> pProperties = pClass->GetProperties();
-
-                // Also tack on the definitions that are common to all classes in this source.
-                STRING sDefinitions = oDefinitions.Contents();
-                oXmlFeatureClass.Write(sDefinitions.c_str(),sDefinitions.length());
-            }
-        }
-    } // while not end of ResourceList
-
-    // TODO: rename this m_s... it's a misnomer.
-    m_sSourcesAndClasses = oTheWholeEnchilada.Contents();
-
-    // Note that the string m_sSourcesAndClasses is really just an xml fragment;
-    // there's no one root item, just a bunch of <Class> elements.
-    m_pXmlInput = new MgXmlParser(m_sSourcesAndClasses.c_str());
-    // Skip anything out of the ordinary.
-    m_pXmlInput->SetOptions(keSkipWhitespace|keSkipComments|keSkipProcessingInstructions);
-    // Advance to the first thing on our list.
-    m_bOk = m_pXmlInput->Next();
+MgWfsFeatureDefinitions::MgWfsFeatureDefinitions(MgResourceService* pResourceService,
+                                                 MgFeatureService* pFeatureService,
+                                                 MgStringCollection* pFeatureTypes)
+:   m_pResourceService(pResourceService)
+,   m_pFeatureService(pFeatureService)
+,   m_pFeatureTypes(pFeatureTypes)
+,   m_pXmlInput(NULL)
+,   m_sSubsetOfTypes(_("\n"))
+,   m_bOk(false)
+{
+    Initialize();
 }
 
-
 MgWfsFeatureDefinitions::~MgWfsFeatureDefinitions()
 {
     if(m_pXmlInput != NULL)
@@ -319,7 +184,7 @@
 }
 
 
-bool MgWfsFeatureDefinitions::GetMetadataDefinitions(MgXmlParser& Input,CStream& oStream)
+bool MgWfsFeatureDefinitions::GetMetadataDefinitions(MgXmlParser& Input,CStream& oStream, bool& isPublished)
 {
     STRING sDebug = Input.Current().Contents();
     MgXmlSynchronizeOnElement ElementResourceDocumentHeader(Input,_("ResourceDocumentHeader"));
@@ -375,6 +240,10 @@
                 }
                 //----------------------------------------------------------------------
                 AddDefinition(oStream,sDefinitionName.c_str(),sValue.c_str());
+                if(SZ_EQ(sDefinitionName.c_str(), _("Feature.IsPublished")) && SZ_EQ(sValue.c_str(), _("1")))
+                {
+                    isPublished = true;
+                }
             }
         }
     }
@@ -400,11 +269,220 @@
 
 void MgWfsFeatureDefinitions::Initialize()
 {
-    /* a debuggery cheat, for when the server isn't there...
-    VPSZ p = MgOgcServer::LoadFile(_("c:\\FeatureDefinitions.xml"));
-    sLayers = p;
-    free(p);
-    //*/
+    /*
+    // NOTE: It would be cool if this logic could exist on the server, allowing only
+    // one round-trip between webtier and server for this entire aggregated bit of info.
+    */
+
+    // Create MgResourceIdentifier
+    MgResourceIdentifier mgrIdentifier(_("Library://"));
+
+    // Run API command
+    STRING sType = _("FeatureSource");
+    INT32 keProperties = MgResourceHeaderProperties::Metadata;
+    STRING sDontCare(_(""));
+    Ptr<MgByteReader> Result =
+          m_pResourceService->EnumerateResources(&mgrIdentifier, // "Library://"
+                                                -1,             // Infinite depth
+                                                sType,          // "LayerDefinition"
+                                                keProperties,   // want metadata, not security
+                                                sDontCare,      // start date; don't care
+                                                sDontCare);     // end date; don't care
+
+    STRING sLayers = Result->ToString();
+    MgXmlParser Input(sLayers.c_str());
+    Input.SetOptions(keSkipWhitespace|keSkipComments|keSkipProcessingInstructions);
+
+    // Scoot us up to the first element
+    Input.Next();
+
+    // Is it a ResourceList element?
+    MgXmlSynchronizeOnElement ResourceList(Input,_("ResourceList"));
+    if(!ResourceList.AtBegin())
+        return;
+
+    // Everything will be put into this thing
+    // though we don't get things in the right order,
+    // so some juggling is called for.
+    // The end result is some "pseudo-XML" (no single root element)
+    // that is a collection of feature classes, as follows:
+    //  
+    //  <FeatureClass id='ns180401301:BuildingOutlines' xmlns:ns180401301='Library://Samples/Sheboygan/Data/BuildingOutlines.FeatureSource'>
+    //  <Define item='Feature.Name'>BuildingOutlines</Define>
+    //  <Define item='Feature.Title'>BuildingOutlines</Define>
+    //  <Define item='Feature.FullName'>ns180401301:BuildingOutlines</Define>
+    //  <Define item='Feature.Description'></Define>
+    //  <Define item='Feature.Prefix'>ns180401301</Define>
+    //  <Define item='Feature.Resource'>Library://Samples/Sheboygan/Data/BuildingOutlines.FeatureSource</Define>
+    //  <Define item='Feature.PrimarySRS'>EPSG:4326</Define>
+    //  <Define item='Feature.Bounds'><Bounds SRS="EPSG:4326" west="-87.74" south="43.68" east="-87.69" north="43.815"></Define>
+    //  <Define item='Feature.Abstract'>Building Outlines.</Define>
+    //  <Define item='Feature.Keywords'>Buildings, Outlines</Define>
+    //  <Define item='Feature.Title'>Building Outlines</Define>
+    //  <Define item='Feature.IsPublished'>1</Define>
+    //  </FeatureClass>
+
+    CStringStream oTheWholeEnchilada;
+
+    // Optimization: Determine the prefix for each required feature type.
+    // This allows us to filter out any feature sources with a prefix not
+    // in the list.
+    Ptr<MgStringCollection> requiredPrefixList;
+    if(m_pFeatureTypes != NULL)
+    {
+        requiredPrefixList= new MgStringCollection();
+        for(int i = 0; i< m_pFeatureTypes->GetCount(); i++)
+        {
+            STRING typeName = m_pFeatureTypes->GetItem(i);
+            STRING::size_type separatorPos = typeName.find(_(":"));
+            if(separatorPos != STRING::npos) 
+            {
+                STRING requiredPrefix = typeName.substr(0, separatorPos);
+                if(!requiredPrefix.empty())
+                {
+                    requiredPrefixList->Add(requiredPrefix);
+                }
+                else
+                {
+                    // No prefix. We can't filter this way.
+                    requiredPrefixList = NULL;
+                    break;
+                }
+            }
+            else
+            {
+                // No prefix. We can't filter this way.
+                requiredPrefixList = NULL;
+                break;
+            }
+        }
+    }
+    else
+    {
+        // No typenames were specified. No filtering required.
+        requiredPrefixList = NULL;
+    }
+
+    while(!ResourceList.AtEnd()) 
+    {
+        // And just inside of that, is it a ResourceDocument element?
+        MgXmlSynchronizeOnElement ResourceDocument(Input,_("ResourceDocument"));
+        if(!ResourceDocument.AtBegin())
+            return; // Something is wrong.  We leave.
+
+        STRING sResource; // "Library://....FeatureSource"
+        STRING sPrefix;   // "ns######" based on hash of sResource.
+
+        CStringStream oDefinitions;
+        bool required = false;
+
+        // We're looking specifically for ResourceId elements.
+        while(!ResourceDocument.AtEnd()) 
+        {
+            if(GetElementContents(Input,_("ResourceId"),sResource)) 
+            {
+                // We get the canonical xmlns:prefix associated with the resource.
+                FeatureSourceToPrefix(sResource,sPrefix);
+
+                // Optimization: Stop processing if this feature source isn't published
+                if(requiredPrefixList != NULL)
+                {
+                    if(!requiredPrefixList->Contains(sPrefix))
+                    {
+                        required = false;
+                        break;
+                    }
+                }
+
+                AddDefinition(oDefinitions,_("Feature.Prefix"),sPrefix.c_str());
+                AddDefinition(oDefinitions,_("Feature.Resource"),sResource.c_str());
+            }
+            else if(GetMetadataDefinitions(Input,oDefinitions,required)) 
+            {
+                // Optimization: Stop processing if this feature source isn't published
+                if(!required)
+                {
+                    break;
+                }
+            }
+            else 
+            {
+              SkipElement(Input,NULL);
+            }
+        } // while not at end of ResourceDocument
+
+        // We are only interested in feature sources that are published via WFS
+        if(required)
+        {
+            MgResourceIdentifier idResource(sResource);
+            
+            // Now, given the feature source, we need to find out stuff about
+            // it; there are one or more Feature *Classes* defined within it.
+            // And what classes we can expect to find.
+            // That's done indirectly by enumerating the schemas the source reports...
+            STRING sDontCare(_(""));
+            Ptr<MgFeatureSchemaCollection> pSchemas = this->m_pFeatureService->DescribeSchema(&idResource,sDontCare);
+
+            for(INT32 iSchema=0; iSchema<pSchemas->GetCount(); iSchema++) {
+                Ptr<MgFeatureSchema> pSchema = pSchemas->GetItem(iSchema);
+                Ptr<MgClassDefinitionCollection> pClasses = pSchema->GetClasses();
+                // ... and by the classes each schema reports.
+                for(INT32 iClass=0; iClass<pClasses->GetCount(); iClass++) {
+                    Ptr<MgClassDefinition> pClass = pClasses->GetItem(iClass);
+
+                    // TODO: STALE?
+                    // What internally is known as the name is really
+                    // the human-readable thing, which in OGC parlance is the title.
+                    STRING sName = pClass->GetName();
+
+                    // TODO: STALE?
+                    // And what OGC wants to call a Name is really the internal
+                    // cookie.  We use the stripped down resource name (source)
+                    // plus the human-readable name
+                    STRING sFullName = sPrefix+_(":")+sName;
+
+                    // Now, spew out everything we know about this class.
+                    STRING sFeatureNameAttr(_("id='"));
+                    sFeatureNameAttr += sFullName;
+                    sFeatureNameAttr += _("' xmlns:");
+                    sFeatureNameAttr += sPrefix;
+                    sFeatureNameAttr += _("='");
+                    sFeatureNameAttr += sResource;
+                    sFeatureNameAttr += _("'");
+
+                    MgXmlElementEmitter oXmlFeatureClass(oTheWholeEnchilada,_("FeatureClass"),sFeatureNameAttr.c_str());
+                    AddDefinition(oTheWholeEnchilada,_("Feature.Name"),sName.c_str());
+                    AddDefinition(oTheWholeEnchilada,_("Feature.Title"),sName.c_str());
+                    AddDefinition(oTheWholeEnchilada,_("Feature.FullName"),sFullName.c_str());
+                    // Stuff like Feature.Prefix and Feature.Resource are in oDefinitions, and
+                    // will be appended below.
+
+                    // This is strange; it's called the "Description", but ends up being
+                    // the type's name. 
+                    STRING sDescription = pClass->GetDescription();
+                    AddDefinition(oTheWholeEnchilada,_("Feature.Description"),sDescription.c_str());
+
+                    // TODO: evaluate what, of interest, can be found here.
+                    //Ptr<MgPropertyDefinitionCollection> pProperties = pClass->GetProperties();
+
+                    // Also tack on the definitions that are common to all classes in this source.
+                    STRING sDefinitions = oDefinitions.Contents();
+                    oXmlFeatureClass.Write(sDefinitions.c_str(),sDefinitions.length());
+                }
+            }
+        } // while not end of ResourceList
+    }
+
+    // TODO: rename this m_s... it's a misnomer.
+    m_sSourcesAndClasses = oTheWholeEnchilada.Contents();
+
+    // Note that the string m_sSourcesAndClasses is really just an xml fragment;
+    // there's no one root item, just a bunch of <Class> elements.
+    m_pXmlInput = new MgXmlParser(m_sSourcesAndClasses.c_str());
+    // Skip anything out of the ordinary.
+    m_pXmlInput->SetOptions(keSkipWhitespace|keSkipComments|keSkipProcessingInstructions);
+    // Advance to the first thing on our list.
+    m_bOk = m_pXmlInput->Next();    
 }
 
 

Modified: trunk/MgDev/Web/src/HttpHandler/WfsFeatureDefinitions.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/WfsFeatureDefinitions.h	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Web/src/HttpHandler/WfsFeatureDefinitions.h	2007-02-08 22:43:38 UTC (rev 1096)
@@ -25,6 +25,7 @@
 {
 public:
     MgWfsFeatureDefinitions(MgResourceService* pResourceService,MgFeatureService* pFeatureService);
+    MgWfsFeatureDefinitions(MgResourceService* pResourceService,MgFeatureService* pFeatureService,MgStringCollection* pFeatureTypes);
     ~MgWfsFeatureDefinitions();
 
     bool Next();
@@ -56,7 +57,7 @@
 private:
     bool   SkipElement(MgXmlParser& Input,CPSZ pszElementName);
     bool   GetElementContents(MgXmlParser& Input,CPSZ pszElementName,STRING& sValue);
-    bool   GetMetadataDefinitions(MgXmlParser& Input,CStream& oStream);
+    bool   GetMetadataDefinitions(MgXmlParser& Input,CStream& oStream,bool& isPublished);
 
     void   AddDefinition(CStream& oStream,CPSZ pszPropertyName,CPSZ pszPropertyValue);
 
@@ -68,6 +69,7 @@
     MgXmlParser*       m_pXmlInput;
     MgResourceService* m_pResourceService;
     MgFeatureService*  m_pFeatureService;
+    MgStringCollection* m_pFeatureTypes;
 
     STRING m_sSourcesAndClasses;
     STRING m_sSubsetOfTypes;

Modified: trunk/MgDev/Web/src/HttpHandler/WfsGetFeatureParams.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/WfsGetFeatureParams.cpp	2007-02-07 21:22:45 UTC (rev 1095)
+++ trunk/MgDev/Web/src/HttpHandler/WfsGetFeatureParams.cpp	2007-02-08 22:43:38 UTC (rev 1096)
@@ -237,15 +237,15 @@
             {
                 // TODO: Look into using StringStream and XmlElementEmitter for simplified generation
                 // of these elements.
-                STRING filterString = L"<ogc:Filter><ogc:BBOX><gml:Envelope><gml:lowerCorner>";
+                STRING filterString = L"<ogc:Filter><ogc:BBOX><ogc:PropertyName></ogc:PropertyName><gml:Box><gml:coordinates>";
                 filterString.append(MgUtil::Trim(bboxCoords->GetItem(0)));
+                filterString.append(L",");
+                filterString.append(MgUtil::Trim(bboxCoords->GetItem(1)));
                 filterString.append(L" ");
-                filterString.append(MgUtil::Trim(bboxCoords->GetItem(1)));
-                filterString.append(L"</gml:lowerCorner><gml:upperCorner>");
                 filterString.append(MgUtil::Trim(bboxCoords->GetItem(2)));
-                filterString.append(L" ");
+                filterString.append(L",");
                 filterString.append(MgUtil::Trim(bboxCoords->GetItem(3)));
-                filterString.append(L"</gml:upperCorner></gml:Envelope></ogc:BBOX></ogc:Filter>");
+                filterString.append(L"</gml:coordinates></gml:Box></ogc:BBOX></ogc:Filter>");
                 m_filterStrings->Add(filterString);
             }
         }



More information about the mapguide-commits mailing list