AutoCAD Map 3D 2009 Geospatial Platform Reference

AutoCAD Map 3D Geospatial Platform API

Provider Capabilities
[Feature Service]

Provider Capabilities

The MgFeatureService API delegates much of its functionality to FDO providers. The providers implement the storage and retrieval of feature data from a variety of RDBMS and file-based datastore technologies.

A set of provider capabilities has been defined, and each provider has been characterized according to what capabilities it supports. For example, the FDO Provider for Oracle supports the creation, description, and destruction of a schema definition, but the FDO Provider for ArcSDE supports only the description of a schema definition.

The capabilities are grouped in the following categories:

  • Connection
  • Schema
  • Commands
  • Expressions
  • Filters
  • Raster
  • Topology

The MgFeatureService::GetCapabilities method returns an XML representation of a provider's capabilities. See FdoProviderCapabilities for the definition of the XML representation.

The capability characterization can be used to execute code conditionally depending on the provider being used and what capability is being executed.

Example (C#)

The GetFeatureProviders method cyles through the list of provider names and creates a FeatureProvider object for each one.

The FeatureProvider constructor uses the MgFeatureService object to get the capabilities for the provider. The capabilities are in xml and the Extract methods use xpath expressions to extract the capability values from the xml.

The utility methods show the use of System Xml classes to extract values from the xml.

Here are a few of the capability strings generated by this code for the SDF provider.

  • ConnectionCapabilities:ThreadCapability=PerConnectionThreaded;SpatialContextExtentType=Dynamic;
  • CommandCapabilities:Commands=+Select+Insert+Delete+Update+DescribeSchema+ApplySchema+CreateSpatialContext+GetSpatialContexts+SelectAggregates;SelectExpressions;SelectFunctions;SelectDistinct;
  • SchemaCapabilities:ClassType=+Class+FeatureClass;DataType=+Boolean+Byte+DateTime+Decimal+Double+Int16+Int32+Int64+Single+String;Inheritance;AssociationProperties;AutoIdGeneration;SupportedAutoGeneratedTypes=+Int32;SchemaModification;
  • GeometryCapabilities:GeometryTypes=+Point+LineString+Polygon+MultiPoint+MultiLineString+MultiPolygon+MultiGeometry+CurveString+CurvePolygon+MultiCurveString+MultiCurvePolygon;ComponentType=+LinearRing+ArcSegment+LinearSegment+CurveRing;Dimensionality=XYZM;
  • FilterCapabilities:ConditionType=+Comparison+Like+In+Null+Spatial;SpatialOperation=+Contains+Disjoint+Intersects+Within+Inside+EnvelopeIntersects;DistanceOperation=;
  • ExpressionCapabilities:ExpressionType=+Basic+Function;FunctionDefinitions=+Concat+SpatialExtents+Ceil+Floor+Lower+Upper+Sum+Count+Min+Avg+Max;
using OSGeo.MapGuide;
// The MgFeatureService example code shows how the MgFeatureService object is created.
private MgFeatureService featureService;
private String providerNamesActual;
private ListDictionary featureProviders;

private void GetProviderNames()
{
	System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo(0x0409);
	String[] names;
	MgByteReader byteReader = featureService.GetFeatureProviders();
	String xmlContent = byteReader.ToString();
	names = GetXpathValuesRtnStrArr(xmlContent,
		"//FeatureProviderRegistry/FeatureProvider/Name");
	providerCountActual = names.GetLength(0);
	Array.Sort(names, StringComparer.Create(culture, false));
	providerNamesActual = StringArrayToString(names);
}

private void GetFeatureProviders()
{
	featureProviders = new ListDictionary();
	FeatureProvider featureProvider;
	String providerName;
	string[] names = providerNamesActual.Split();
	for (int i = 0; i < providerCountActual; i++)
	{
		providerName = names[i];
		featureProvider = new FeatureProvider(logger, providerName,
			featureService, utilities, timings);
		featureProviders.Add(providerName, featureProvider);
	}
}

class FeatureProvider
{
	public FeatureProvider(...
		MgFeatureService featureService,
		Utilities utilities,
		...)
	{
		...
		MgByteReader byteReader = featureService.GetCapabilities(providerName);
        xmlContent = byteReader.ToString();
        ExtractConnectionCapabilities();
        ExtractSchemaCapabilities();
        ExtractCommandCapabilities();
        ExtractFilterCapabilities();
        ExtractExpressionCapabilities();
        ExtractRasterCapabilities();
        ExtractTopologyCapabilities();
        ExtractGeometryCapabilities();
    }
    private MgFeatureService featureService;
    private String xmlContent;
    private String connectionCapabilitiesToStr;
    private String schemaCapabilitiesToStr;
    private String commandCapabilitiesToStr;
    private String filterCapabilitiesToStr;
    private String expressionCapabilitiesToStr;
    private String rasterCapabilitiesToStr;
    private String topologyCapabilitiesToStr;
    private String geometryCapabilitiesToStr;
    private StringBuilder sb;
    private const int sblength = 640;
    private Boolean multipleSchema;

	// public property declarations to expose capability strings

	private void ExtractConnectionCapabilities()
	{
		sb = new StringBuilder(sblength);
		sb.Append("ConnectionCapabilities:");
		String ThreadCapability = utilities.GetXpathValuesRtnStr(xmlContent, "Connection/ThreadCapability");
		sb.Append("ThreadCapability=" + ThreadCapability + ';');
		String SpatialContextExtentType = utilities.GetXpathValuesRtnStr(xmlContent, "Connection/SpatialContextExtent/Type");
		sb.Append("SpatialContextExtentType=" + SpatialContextExtentType + ';');
		String SupportsLocking = utilities.GetXpathValuesRtnStr(xmlContent, "Connection/SupportsLocking");
		if (SupportsLocking.Equals("true"))
		{
			sb.Append("Locking;");
		}
		String SupportsTimeout = utilities.GetXpathValuesRtnStr(xmlContent, "Connection/SupportsTimeout");
		if (SupportsTimeout.Equals("true"))
		{
			sb.Append("Timeout;");
		}
		String SupportsTransactions = utilities.GetXpathValuesRtnStr(xmlContent, "Connection/SupportsTransactions");
		if (SupportsTransactions.Equals("true"))
		{
			sb.Append("Transactions;");
		}
		String SupportsLongTransactions = utilities.GetXpathValuesRtnStr(xmlContent, "Connection/SupportsLongTransactions");
		if (SupportsLongTransactions.Equals("true"))
		{
			sb.Append("LongTransactions;");
		}
		String SupportsSQL = utilities.GetXpathValuesRtnStr(xmlContent, "Connection/SupportsSQL");
		if (SupportsSQL.Equals("true"))
		{
			sb.Append("SQL;");
		}
		String SupportsConfiguration = utilities.GetXpathValuesRtnStr(xmlContent, "Connection/SupportsConfiguration");
		if (SupportsConfiguration.Equals("true"))
		{
			sb.Append("Configuration;");
		}
		connectionCapabilitiesToStr = sb.ToString();
	}
	private void ExtractSchemaCapabilities()
	{
		String value;
		sb = new StringBuilder(sblength);
		sb.Append("SchemaCapabilities:");
		MgStringCollection ClassType = utilities.GetXpathValuesRtnMgStrColl(xmlContent, "Schema/Class/Type");
		sb.Append("ClassType=");
		int classCount = ClassType.GetCount();
		for (int i = 0; i < classCount; i++)
		{
			sb.Append("+" + ClassType.GetItem(i));
		}
		sb.Append(";");
		MgStringCollection DataType = utilities.GetXpathValuesRtnMgStrColl(xmlContent, "Schema/Data/Type");
		sb.Append("DataType=");
		int dataCount = DataType.GetCount();
		for (int i = 0; i < dataCount; i++)
		{
			sb.Append("+" + DataType.GetItem(i));
		}
		sb.Append(";");
		String SupportsInheritance = utilities.GetXpathValuesRtnStr(xmlContent, "Schema/SupportsInheritance");
		if (SupportsInheritance.Equals("true"))
		{
			sb.Append("Inheritance;");
		}
		String SupportsMultipleSchemas = utilities.GetXpathValuesRtnStr(xmlContent, "Schema/SupportsMultipleSchemas");
		if (SupportsMultipleSchemas.Equals("true"))
		{
			sb.Append("MultipleSchemas;");
			multipleSchema = true;
		}
		else
		{
			multipleSchema = false;
		}
		String SupportsObjectProperties = utilities.GetXpathValuesRtnStr(xmlContent, "Schema/SupportsObjectProperties");
		if (SupportsObjectProperties.Equals("true"))
		{
			sb.Append("ObjectProperties;");
		}
		String SupportsAssociationProperties = utilities.GetXpathValuesRtnStr(xmlContent, "Schema/SupportsAssociationProperties");
		if (SupportsAssociationProperties.Equals("true"))
		{
			sb.Append("AssociationProperties;");
		}
		String SupportsSchemaOverrides = utilities.GetXpathValuesRtnStr(xmlContent, "Schema/SupportsSchemaOverrides");
		if (SupportsSchemaOverrides.Equals("true"))
		{
			sb.Append("SchemaOverrides;");
		}
		String SupportsNetworkModel = utilities.GetXpathValuesRtnStr(xmlContent, "Schema/SupportsNetworkModel");
		if (SupportsNetworkModel.Equals("true"))
		{
			sb.Append("NetworkModel;");
		}
		String SupportsAutoIdGeneration = utilities.GetXpathValuesRtnStr(xmlContent, "Schema/SupportsAutoIdGeneration");
		if (SupportsAutoIdGeneration.Equals("true"))
		{
			sb.Append("AutoIdGeneration;");
		}
		String SupportsDataStoreUniqueIdGeneration = utilities.GetXpathValuesRtnStr(xmlContent, "Schema/SupportsDataStoreUniqueIdGeneration");
		if (SupportsDataStoreUniqueIdGeneration.Equals("true"))
		{
			sb.Append("DataStoreUniqueIdGeneration;");
		}
		MgStringCollection SupportedAutoGeneratedTypes = utilities.GetXpathValuesRtnMgStrColl(xmlContent, "Schema/SupportedAutoGeneratedTypes/Type");
		sb.Append("SupportedAutoGeneratedTypes=");
		int autoGenTypeCount = SupportedAutoGeneratedTypes.GetCount();
		for (int i = 0; i < autoGenTypeCount; i++)
		{
			value = SupportedAutoGeneratedTypes.GetItem(i);
			if (value != "")
			{
				sb.Append("+" + value);
			}
		}
		sb.Append(";");
		String SupportsSchemaModification = utilities.GetXpathValuesRtnStr(xmlContent, "Schema/SupportsSchemaModification");
		if (SupportsSchemaModification.Equals("true"))
		{
			sb.Append("SchemaModification;");
		}
		schemaCapabilitiesToStr = sb.ToString();
	}
	private void ExtractCommandCapabilities()
	{
		sb = new StringBuilder(sblength);
		sb.Append("CommandCapabilities:");
		MgStringCollection Commands = utilities.GetXpathValuesRtnMgStrColl(xmlContent, "Command/SupportedCommands/Name");
		sb.Append("Commands=");
		int cmdCount = Commands.GetCount();
		for (int i = 0; i < cmdCount; i++)
		{
			sb.Append("+" + Commands.GetItem(i));
		}
		sb.Append(";");
		String SupportsParameters = utilities.GetXpathValuesRtnStr(xmlContent, "Command/SupportsParameters");
		if (SupportsParameters.Equals("true"))
		{
			sb.Append("Parameters;");
		}
		String SupportsTimeout = utilities.GetXpathValuesRtnStr(xmlContent, "Command/SupportsTimeout");
		if (SupportsTimeout.Equals("true"))
		{
			sb.Append("Timeout;");
		}
		String SupportsSelectExpressions = utilities.GetXpathValuesRtnStr(xmlContent, "Command/SupportsSelectExpressions");
		if (SupportsSelectExpressions.Equals("true"))
		{
			sb.Append("SelectExpressions;");
		}
		String SupportsSelectFunctions = utilities.GetXpathValuesRtnStr(xmlContent, "Command/SupportsSelectFunctions");
		if (SupportsSelectFunctions.Equals("true"))
		{
			sb.Append("SelectFunctions;");
		}
		String SupportsSelectDistinct = GetXpathValuesRtnStr(xmlContent, "Command/SupportsSelectDistinct");
		if (SupportsSelectDistinct.Equals("true"))
		{
			sb.Append("SelectDistinct;");
		}
		String SupportsSelectOrdering = utilities.GetXpathValuesRtnStr(xmlContent, "Command/SupportsSelectOrdering");
		if (SupportsSelectOrdering.Equals("true"))
		{
			sb.Append("SelectOrdering;");
		}
		String SupportsSelectGrouping = utilities.GetXpathValuesRtnStr(xmlContent, "Command/SupportsSelectGrouping");
		if (SupportsSelectGrouping.Equals("true"))
		{
			sb.Append("SelectGrouping;");
		}
		commandCapabilitiesToStr = sb.ToString();
	}
	private void ExtractFilterCapabilities()
	{
		String value;
		sb = new StringBuilder(sblength);
		sb.Append("FilterCapabilities:");
		MgStringCollection ConditionType = utilities.GetXpathValuesRtnMgStrColl(xmlContent, "Filter/Condition/Type");
		sb.Append("ConditionType=");
		int conditionCount = ConditionType.GetCount();
		for (int i = 0; i < conditionCount; i++)
		{
			value = ConditionType.GetItem(i);
			if (value != "")
			{
				sb.Append("+" + value);
			}
		}
		sb.Append(";");
		MgStringCollection SpatialOperation = utilities.GetXpathValuesRtnMgStrColl(xmlContent, "Filter/Spatial/Operation");
		sb.Append("SpatialOperation=");
		int spatialOpCount = SpatialOperation.GetCount();
		for (int i = 0; i < spatialOpCount; i++)
		{
			value = SpatialOperation.GetItem(i);
			if (value != "")
			{
				sb.Append("+" + value);
			}
		}
		sb.Append(";");
		MgStringCollection DistanceOperation = utilities.GetXpathValuesRtnMgStrColl(xmlContent, "Filter/Distance/Operation");
		sb.Append("DistanceOperation=");
		int distanceOpCount = DistanceOperation.GetCount();
		for (int i = 0; i < distanceOpCount; i++)
		{
			value = DistanceOperation.GetItem(i);
			if (value != "")
			{
				sb.Append("+" + value);
			}
		}
		sb.Append(";");
		String SupportsGeodesicDistance = utilities.GetXpathValuesRtnStr(xmlContent, "Filter/SupportsGeodesicDistance");
		if (SupportsGeodesicDistance.Equals("true"))
		{
			sb.Append("GeodesicDistance;");
		}
		String SupportsNonLinearGeometricOperations = utilities.GetXpathValuesRtnStr(xmlContent, "Filter/SupportsNonLinearGeometricOperations");
		if (SupportsNonLinearGeometricOperations.Equals("true"))
		{
			sb.Append("NonLinearGeometricOperations;");
		}
		filterCapabilitiesToStr = sb.ToString();
	}
	private void ExtractExpressionCapabilities()
	{
		String value;
		sb = new StringBuilder(sblength);
		sb.Append("ExpressionCapabilities:");
		MgStringCollection ExpressionType = utilities.GetXpathValuesRtnMgStrColl(xmlContent, "Expression/Type/Name");
		sb.Append("ExpressionType=");
		int typeCount = ExpressionType.GetCount();
		for (int i = 0; i < typeCount; i++)
		{
			sb.Append("+" + ExpressionType.GetItem(i));
		}
		sb.Append(";");
		MgStringCollection FunctionDefinitions = utilities.GetXpathValuesRtnMgStrColl(xmlContent, "Expression/FunctionDefinitionCollection/FunctionDefinition/Name");
		sb.Append("FunctionDefinitions=");
		int functionCount = FunctionDefinitions.GetCount();
		for (int i = 0; i < functionCount; i++)
		{
			value = FunctionDefinitions.GetItem(i);
			if (value != "")
			{
				sb.Append("+" + value);
			}
		}
		sb.Append(";");
		expressionCapabilitiesToStr = sb.ToString();
	}
	private void ExtractRasterCapabilities()
	{
		sb = new StringBuilder(sblength);
		sb.Append("RasterCapabilities:");
		String SupportsRaster = utilities.GetXpathValuesRtnStr(xmlContent, "Raster/SupportsRaster");
		if (SupportsRaster.Equals("true"))
		{
			sb.Append("Raster;");
		}
		String SupportsStitching = utilities.GetXpathValuesRtnStr(xmlContent, "Raster/SupportsStitching");
		if (SupportsStitching.Equals("true"))
		{
			sb.Append("Stitching;");
		}
		String SupportsSubsmpling = utilities.GetXpathValuesRtnStr(xmlContent, "Raster/SupportsSubsmpling");
		if (SupportsSubsmpling.Equals("true"))
		{
			sb.Append("Subsmpling;");
		}
		rasterCapabilitiesToStr = sb.ToString();
	}
	private void ExtractTopologyCapabilities()
	{
		sb = new StringBuilder(sblength);
		sb.Append("TopologyCapabilities:");
		String SupportsTopology = utilities.GetXpathValuesRtnStr(xmlContent, "Topology/SupportsTopology");
		if (SupportsTopology.Equals("true"))
		{
			sb.Append("Topology;");
		}
		String SupportsTopologicalHierarchy = utilities.GetXpathValuesRtnStr(xmlContent, "Topology/SupportsTopologicalHierarchy");
		if (SupportsTopologicalHierarchy.Equals("true"))
		{
			sb.Append("TopologicalHierarchy;");
		}
		String BreaksCurveCrossingsAutomatically = utilities.GetXpathValuesRtnStr(xmlContent, "Topology/BreaksCurveCrossingsAutomatically");
		if (BreaksCurveCrossingsAutomatically.Equals("true"))
		{
			sb.Append("BreaksCurveCrossingsAutomatically;");
		}
		String ActivatesTopologyByArea = utilities.GetXpathValuesRtnStr(xmlContent, "Topology/ActivatesTopologyByArea");
		if (ActivatesTopologyByArea.Equals("true"))
		{
			sb.Append("ActivatesTopologyByArea;");
		}
		String ConstrainsFeatureMovements = utilities.GetXpathValuesRtnStr(xmlContent, "Topology/ConstrainsFeatureMovements");
		if (ConstrainsFeatureMovements.Equals("true"))
		{
			sb.Append("ConstrainsFeatureMovements;");
		}
		topologyCapabilitiesToStr = sb.ToString();
	}
	private void ExtractGeometryCapabilities()
	{
		sb = new StringBuilder(sblength);
		sb.Append("GeometryCapabilities:");
		MgStringCollection GeometryTypes = utilities.GetXpathValuesRtnMgStrColl(xmlContent, "Geometry/Types/Type");
		sb.Append("GeometryTypes=");
		int geomTypeCount = GeometryTypes.GetCount();
		for (int i = 0; i < geomTypeCount; i++)
		{
			sb.Append("+" + GeometryTypes.GetItem(i));
		}
		sb.Append(";");
		MgStringCollection ComponentType = utilities.GetXpathValuesRtnMgStrColl(xmlContent, "Geometry/Components/Type");
		sb.Append("ComponentType=");
		int compTypeCount = ComponentType.GetCount();
		for (int i = 0; i < compTypeCount; i++)
		{
			sb.Append("+" + ComponentType.GetItem(i));
		}
		sb.Append(";");
		String Dimensionality = utilities.GetXpathValuesRtnStr(xmlContent, "Geometry/Dimensionality");
		sb.Append("Dimensionality=" + MgCoordinateDimensionToStr(Convert.ToInt32(Dimensionality)) + ';');
		geometryCapabilitiesToStr = sb.ToString();
	}
}

public String[] GetXpathValuesRtnStrArr(String xmlContent, String xpath)
{
	System.Collections.ArrayList strList = new System.Collections.ArrayList(10);
	String[] strArr;
	System.Xml.XmlDocument xmlDocument = new XmlDocument();
	xmlDocument.LoadXml(xmlContent);
	XmlNodeList nodeList;
	XmlElement root = xmlDocument.DocumentElement;
	nodeList = root.SelectNodes(xpath);
	int count = nodeList.Count;
	if (count == 0)
	{
		strArr = new String[] { "" };
		return strArr;
	}
	XmlNode node;
	for (int i = 0; i < count; i++)
	{
		node = nodeList.Item(i);
		strList.Add(node.FirstChild.Value);
	}
	strArr = (String[])strList.ToArray(typeof(string));
	return strArr;
}

public String GetXpathValuesRtnStr(String xmlContent, String xpath)
{
	String value;
	System.Xml.XmlDocument xmlDocument = new XmlDocument();
	xmlDocument.LoadXml(xmlContent);
	XmlElement root = xmlDocument.DocumentElement;
	XmlNode node;
	node = root.SelectSingleNode(xpath);
	if (node == null)
	{
		value = "";
		return value;
	}
	value = node.FirstChild.Value;
	return value;
}

public MgStringCollection GetXpathValuesRtnMgStrColl(String xmlContent, String xpath)
{
	MgStringCollection strings = new MgStringCollection();
	System.Xml.XmlDocument xmlDocument = new XmlDocument();
	xmlDocument.LoadXml(xmlContent);
	XmlNodeList nodeList;
	XmlElement root = xmlDocument.DocumentElement;
	nodeList = root.SelectNodes(xpath);
	int count = nodeList.Count;
	if (count == 0)
	{
		strings.Add("");
		return strings;
	}
	XmlNode node;
	for (int i = 0; i < count; i++)
	{
		node = nodeList.Item(i);
		strings.Add(node.FirstChild.Value);
	}
	return strings;
}

 

Capabilities for Autodesk.Oracle.2.0

What follows is a sample output from a PHP program used to get the capabilities for the Oracle provider. The program code follows the sample output. This program does the following:

Connection
    ThreadCapability
        supportsSingleThreaded(): false
        supportsPerConnectionThreaded(): true
        supportsPerCommandThreaded(): false
        supportsMultiThreaded(): false
    SpatialContextExtent
        Type
            supportsDynamic(): false
            supportsStatic(): true
    supportsLocking(): true
    supportsConnectionTimeout(): false
    supportsTransactions(): true
    supportsLongTransactions(): true
    supportsSQL(): true
    supportsConfiguration(): false
Schema
    Class
        Type
            supportsClass(): true
            supportsFeatureClass(): true
    Data
        Type
            supportsBoolean(): true
            supportsByte(): true
            supportsDateTime(): true
            supportsDecimal(): true
            supportsDouble(): true
            supportsInt16(): true
            supportsInt32(): true
            supportsInt64(): true
            supportsSingle(): true
            supportsString(): true
            supportsBLOB(): true
            supportsCLOB(): true
            supportsUniqueID(): false
    supportsInheritance(): true
    supportsMultipleSchemas(): true
    supportsObjectProperties(): true
    supportsAssociationProperties(): true
    supportsSchemaOverrides(): true
    supportsNetworkModel(): false
    supportsAutoIdGeneration(): true
    supportsDataStoreScopeUniqueIdGeneration(): true
    supportsSchemaModification(): true
Command
    SupportedCommands
        Name
            supportsSelect(): true
            supportsInsert(): true
            supportsDelete(): true
            supportsUpdate(): true
            supportsSelectAggregates(): true
            supportsDescribeSchema(): true
            supportsDescribeSchemaMapping(): false
            supportsDestroySchema(): true
            supportsApplySchema(): true
            supportsActivateSpatialContext(): true
            supportsCreateSpatialContext(): true
            supportsDestroySpatialContext(): true
            supportsDestroySpatialContext(): true
            supportsCreateMeasureUnit(): false
            supportsDestroyMeasureUnit()t: false
            supportsGetMeasureUnits(): false
            supportsSQLCommand(): true
            supportsAcquireLock(): true
            supportsGetLockInfo(): true
            supportsGetLockedObjects(): true
            supportsGetLockOwners(): true
            supportsReleaseLock(): true
            supportsActivateLongTransaction(): true
            supportsCommitLongTransaction(): true
            supportsCreateLongTransaction(): true
            supportsGetLongTransactions(): true
            supportsFreezeLongTransaction(): false
            supportsRollbackLongTransaction(): true
            supportsActivateLongTransactionCheckpoint(): false
            supportsCreateLongTransactionCheckpoint(): false
            supportsGetLongTransactionCheckpoints(): false
            supportsRollbackLongTransactionCheckpoint(): false
            supportsChangeLongTransactionPrivileges(): false
            supportsGetLongTransactionPrivileges(): false
            supportsChangeLongTransactionSet(): false
            supportsGetLongTransactionsInSet(): false
            supportsFirstProviderCommand(): false
            supportsDeactivateLongTransaction(): true
    supportsParameters(): false
    supportsCommandTimeout(): false
    supportsSelectExpressions(): true
    supportsSelectFunctions(): true
    supportsSelectDistinct(): true
    supportsSelectOrdering(): true
    supportsSelectGrouping(): true
Filter
    Condition
        Type
            supportsComparison(): true
            supportsLike(): true
            supportsIn(): true
            supportsNull(): true
            supportsSpatial(): true
            supportsDistance(): true
    Spatial
        Operation
            supportsContains(): false
            supportsCrosses(): false
            supportsDisjoint(): false
            supportsEquals(): false
            supportsIntersects(): true
            supportsOverlaps()s: false
            supportsTouches(): false
            supportsSpatialWithin(): false
            supportsCoveredBy(): true
            supportsInside(): true
            supportsEnvelopeIntersects(): true
    Distance
        Operation
            supportsDistanceWithin(): true
            supportsBeyond(): false
    supportsGeodesicDistance(): false
    supportsNonLiteralGeometricOperations(): false
Expression
    Type
        Name
            supportsBasic(): true
            supportsFunction(): true
            supportsParameter(): true
    FunctionDefinitionCollection
        FunctionDefinition
            Name
                supportsAvg(): true
                supportsCeil(): true
                supportsCLIP(): false
                supportsConcat(): true
                supportsCount(): true
                supportsFloor(): true
                supportsLower(): true
                supportsMax(): true
                supportsMin(): true
                supportsMOSAIC(): false
                supportsStdDev(): false
                supportsSum(): true
                supportsUpper(): true
Raster
    supportsRaster(): false
    supportsStitching(): false
    supportsSubsampling(): false
Topology
    supportsTopology(): false
    supportsTopologicalHierarchy(): false
    supportsBreaksCurveCrossingsAutomatically(): false
    supportsActivatesTopologyByArea(): false
    supportsConstrainsFeatureMovements(): false
Geometry
    Type
        supportsPoint(): true
        supportsMultiPoint(): true
        supportsLineString(): true
        supportsMultiLineString(): true
        supportsPolygon(): true
        supportsMultiPolygon(): true
        supportsCurveString(): true
        supportsMultiCurveString(): true
        supportsCurvePolygon(): true
        supportsMultiCurvePolygon(): true
        supportsMultiGeometry(): false
    Components
        Type
            supportsLinearRing(): true
            supportsLinearSegment(): true
            supportsArcSegment(): true
            supportsCurveRing(): true
    dimensionality(): 3

PHP Example Code

This code does the following:

The constructor takes a provider name, a file handle, and an MgByteReader containing the provider capabilities. The provider name is obtained from MgFeatureService::GetFeatureProviders. The provider capabilities is obtained from MgFeatureService::GetCapabilities. The file handle is for logging.

class ProviderCapabilities {
   var $logFileHandle;
   var $xpath;
   var $providerName;

   function ProviderCapabilities( $providerName, $logFileHandle, $byteReader ) {
      try {
     $this->providerName = $providerName;
     $this->logFileHandle = $logFileHandle;
     $doc = new DOMDocument();
     $byteSink = new MgByteSink($byteReader);
     $filePath = "temp_byte_reader_file.$providerName";
//     fwrite($this->logFileHandle, "file path is \"$filePath\"\n");
     $byteSink->ToFile($filePath);
     $doc->load($filePath);
//     unlink($filePath);
     $this->xpath = new DOMXPath($doc);
     $this->queryConnection();
     $this->querySchema();
     $this->queryCommand();
     $this->queryFilter();
     $this->queryExpression();
     $this->queryRaster();
     $this->queryTopology();
     $this->queryGeometry();
      } catch (Exception $e) {
     $msg = $e->GetMessage();
     fwrite($logFileHandle, "ProviderCapabilities PHP Exception: $msg\n");
      }
   }

   function prtBool($bool) {
      if ($bool) {
     return "true";
      } else {
     return "false";
      }
   }

   function queryBooleanElement($queryExpr, &$reference) {
      $domNodeList = $this->xpath->query($queryExpr);
      if ($domNodeList->length == 0) return;
      $domNode = $domNodeList->item(0);
      $value = $domNode->nodeValue;
      switch($value) {
     case "true" : $reference = TRUE; break;
     case "false" : $reference = FALSE; break;
     default : fwrite($this->logFileHandle, "
queryExpr
value\n"); } }

/*
   var $supports = FALSE;
   function supports() {
      return $this->supports;
   }
\*/

   // CONNECTION CAPABILITIES
   // thread capability

   var $supportsSingleThreaded = FALSE;
   function supportsSingleThreaded() {
      return $this->supportsSingleThreaded;
   }

   var $supportsPerConnectionThreaded = FALSE;
   function supportsPerConnectionThreaded() {
      return $this->supportsPerConnectionThreaded;
   }

   var $supportsPerCommandThreaded = FALSE;
   function supportsPerCommandThreaded() {
      return $this->supportsPerCommandThreaded;
   }

   var $supportsMultiThreaded = FALSE;
   function supportsMultiThreaded() {
      return $this->supportsMultiThreaded;
   }

   // spatial context extent type

   var $supportsDynamic = FALSE;
   function supportsDynamic() {
      return $this->supportsDynamic;
   }

   var $supportsStatic = FALSE;
   function supportsStatic() {
      return $this->supportsStatic;
   }

   // rest of connection capabilities
   var $supportsLocking = FALSE;
   function supportsLocking() {
      return $this->supportsLocking;
   }

   var $supportsConnectionTimeout = FALSE;
   function supportsConnectionTimeout() {
      return $this->supportsConnectionTimeout;
   }

   var $supportsTransactions = FALSE;
   function supportsTransactions() {
      return $this->supportsTransactions;
   }

   var $supportsLongTransactions = FALSE;
   function supportsLongTransactions() {
      return $this->supportsLongTransactions;
   }

   var $supportsSQL = FALSE;
   function supportsSQL() {
      return $this->supportsSQL;
   }

   var $supportsConfiguration = FALSE;
   function supportsConfiguration() {
      return $this->supportsConfiguration;
   }

   function queryConnection() {
      $this->queryThreadCapability();
      $this->querySpatialContextExtentType();
      $this->queryBooleanElement("//FeatureProviderCapabilities/Connection/SupportsLocking", $this->supportsLocking);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Connection/SupportsTimeout", $this->supportsConnectionTimeout);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Connection/SupportsTransactions", $this->supportsTransactions);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Connection/SupportsLongTransactions", $this->supportsLongTransactions);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Connection/SupportsSQL", $this->supportsSQL);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Connection/SupportsConfiguration", $this->supportsConfiguration);
   }

   function queryThreadCapability() {
      $domNodeList = $this->xpath->query("//FeatureProviderCapabilities/Connection/ThreadCapability");
      if ($domNodeList->length == 0) return;
      $domNode = $domNodeList->item(0);
      $value = $domNode->nodeValue;
      switch($value) {
     case "PerConnectionThreaded" : $this->supportsPerConnectionThreaded = TRUE; break;
     case "SingleThreaded" : $this->supportsSingleThreaded = TRUE; break;
     case "PerCommandThreaded" : $this->supportsPerCommandThreaded = TRUE; break;
     case "MultiThreaded" : $this->supportsMultiThreaded = TRUE; break;
     default : fwrite($this->logFileHandle, "unknown thread type: $value\n");
      }
   }

   function querySpatialContextExtentType() {
      $domNodeList = $this->xpath->query("//FeatureProviderCapabilities/Connection/SpatialContextExtent/Type");
      if ($domNodeList->length == 0) return;
      $domNode = $domNodeList->item(0);
      $value = $domNode->nodeValue;
      switch($value) {
     case "Static" : $this->supportsStatic = TRUE; break;
     case "Dynamic" : $this->supportsDynamic = TRUE; break;
     default : fwrite($this->logFileHandle, "unknown spatial context extent type: $value\n");
      }
   }

   // SCHEMA
   // class type
   var $supportsFeatureClass = FALSE;
   function supportsFeatureClass() {
      return $this->supportsFeatureClass;
   }

   var $supportsClass = FALSE;
   function supportsClass() {
      return $this->supportsClass;
   }

   // data types
   var $supportsBoolean = FALSE;
   function supportsBoolean() {
      return $this->supportsBoolean;
   }

   var $supportsByte = FALSE;
   function supportsByte() {
      return $this->supportsByte;
   }

   var $supportsDateTime = FALSE;
   function supportsDateTime() {
      return $this->supportsDateTime;
   }

   var $supportsDecimal = FALSE;
   function supportsDecimal() {
      return $this->supportsDecimal;
   }

   var $supportsDouble = FALSE;
   function supportsDouble() {
      return $this->supportsDouble;
   }

   var $supportsInt16 = FALSE;
   function supportsInt16() {
      return $this->supportsInt16;
   }

   var $supportsInt32 = FALSE;
   function supportsInt32() {
      return $this->supportsInt32;
   }

   var $supportsInt64 = FALSE;
   function supportsInt64() {
      return $this->supportsInt64;
   }

   var $supportsSingle = FALSE;
   function supportsSingle() {
      return $this->supportsSingle;
   }

   var $supportsString = FALSE;
   function supportsString() {
      return $this->supportsString;
   }

   var $supportsBLOB = FALSE;
   function supportsBLOB() {
      return $this->supportsBLOB;
   }

   var $supportsCLOB = FALSE;
   function supportsCLOB() {
      return $this->supportsCLOB;
   }

   var $supportsUniqueID = FALSE;
   function supportsUniqueID() {
      return $this->supportsUniqueID;
   }

   // rest of schema

   var $supportsInheritance = FALSE;
   function supportsInheritance() {
      return $this->supportsInheritance;
   }

   var $supportsMultipleSchemas = FALSE;
   function supportsMultipleSchemas() {
      return $this->supportsMultipleSchemas;
   }

   var $supportsObjectProperties = FALSE;
   function supportsObjectProperties() {
      return $this->supportsObjectProperties;
   }

   var $supportsAssociationProperties = FALSE;
   function supportsAssociationProperties() {
      return $this->supportsAssociationProperties;
   }

   var $supportsSchemaOverrides = FALSE;
   function supportsSchemaOverrides() {
      return $this->supportsSchemaOverrides;
   }

   var $supportsNetworkModel = FALSE;
   function supportsNetworkModel() {
      return $this->supportsNetworkModel;
   }

   var $supportsAutoIdGeneration = FALSE;
   function supportsAutoIdGeneration() {
      return $this->supportsAutoIdGeneration;
   }

   var $supportsDataStoreScopeUniqueIdGeneration = FALSE;
   function supportsDataStoreScopeUniqueIdGeneration() {
      return $this->supportsDataStoreScopeUniqueIdGeneration;
   }

   var $supportsSchemaModification = FALSE;
   function supportsSchemaModification() {
      return $this->supportsSchemaModification;
   }

   function querySchema() {
      $this->queryClassTypes();
      $this->queryDataTypes();
      $this->queryBooleanElement("//FeatureProviderCapabilities/Schema/SupportsInheritance", $this->supportsInheritance);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Schema/SupportsMultipleSchemas", $this->supportsMultipleSchemas);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Schema/SupportsObjectProperties", $this->supportsObjectProperties);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Schema/SupportsAssociationProperties", $this->supportsAssociationProperties);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Schema/SupportsSchemaOverrides", $this->supportsSchemaOverrides);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Schema/SupportsNetworkModel", $this->supportsNetworkModel);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Schema/SupportsAutoIdGeneration", $this->supportsAutoIdGeneration);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Schema/SupportsDataStoreScopeUniqueIdGeneration", $this->supportsDataStoreScopeUniqueIdGeneration);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Schema/SupportsSchemaModification", $this->supportsSchemaModification);
   }

   function queryClassTypes() {
      $domNodeList = $this->xpath->query("//FeatureProviderCapabilities/Schema/Class/Type");
      $count = $domNodeList->length;
      for($i=0; $i<$count; $i++) {
     $domNode = $domNodeList->item($i);
     $value = $domNode->nodeValue;
     switch($value) {
        case "Class" : $this->supportsClass = TRUE; break;
        case "FeatureClass" : $this->supportsFeatureClass = TRUE; break;
        default : fwrite($this->logFileHandle, "unknown schema class type: $value\n");
     }
      }
   }

   function queryDataTypes() {
      $domNodeList = $this->xpath->query("//FeatureProviderCapabilities/Schema/Data/Type");
      $count = $domNodeList->length;
      for($i=0; $i<$count; $i++) {
     $domNode = $domNodeList->item($i);
     $value = $domNode->nodeValue;
     switch($value) {
        case "Boolean" : $this->supportsBoolean = TRUE; break;
        case "Byte" : $this->supportsByte = TRUE; break;
        case "DateTime" : $this->supportsDateTime = TRUE; break;
        case "Decimal" : $this->supportsDecimal = TRUE; break;
        case "Double" : $this->supportsDouble = TRUE; break;
        case "Int16" : $this->supportsInt16 = TRUE; break;
        case "Int32" : $this->supportsInt32 = TRUE; break;
        case "Int64" : $this->supportsInt64 = TRUE; break;
        case "Single" : $this->supportsSingle = TRUE; break;
        case "String" : $this->supportsString = TRUE; break;
        case "CLOB" : $this->supportsCLOB = TRUE; break;
        case "BLOB" : $this->supportsBLOB = TRUE; break;
        case "UniqueID" : $this->supportsUniqueID = TRUE; break;
        default : fwrite($this->logFileHandle, "unknown data type: $value\n");
     }
      }
   }

   // COMMAND

   var $supportsSelect = FALSE;
   function supportsSelect() {
      return $this->supportsSelect;
   }

   var $supportsSelectAggregates = FALSE;
   function supportsSelectAggregates() {
      return $this->supportsSelectAggregates;
   }

   var $supportsInsert = FALSE;
   function supportsInsert() {
      return $this->supportsInsert;
   }

   var $supportsDelete = FALSE;
   function supportsDelete() {
      return $this->supportsDelete;
   }

   var $supportsUpdate = FALSE;
   function supportsUpdate() {
      return $this->supportsUpdate;
   }

   var $supportsDescribeSchema = FALSE;
   function supportsDescribeSchema() {
      return $this->supportsDescribeSchema;
   }

   var $supportsDescribeSchemaMapping = FALSE;
   function supportsDescribeSchemaMapping() {
      return $this->supportsDescribeSchemaMapping;
   }

   var $supportsApplySchema = FALSE;
   function supportsApplySchema() {
      return $this->supportsApplySchema;
   }

   var $supportsDestroySchema = FALSE;
   function supportsDestroySchema() {
      return $this->supportsDestroySchema;
   }

   var $supportsActivateSpatialContext = FALSE;
   function supportsActivateSpatialContext() {
      return $this->supportsActivateSpatialContext;
   }
   var $supportsCreateSpatialContext = FALSE;
   function supportsCreateSpatialContext() {
      return $this->supportsCreateSpatialContext;
   }

   var $supportsDestroySpatialContext = FALSE;
   function supportsDestroySpatialContext() {
      return $this->supportsDestroySpatialContext;
   }

   var $supportsGetSpatialContexts = FALSE;
   function supportsGetSpatialContexts() {
      return $this->supportsGetSpatialContexts;
   }

   var $supportsCreateMeasureUnit = FALSE;
   function supportsCreateMeasureUnit() {
      return $this->supportsCreateMeasureUnit;
   }

   var $supportsDestroyMeasureUnit = FALSE;
   function supportsDestroyMeasureUnit() {
      return $this->supportsDestroyMeasureUnit;
   }

   var $supportsGetMeasureUnits = FALSE;
   function supportsGetMeasureUnits() {
      return $this->supportsGetMeasureUnits;
   }

   var $supportsSQLCommand = FALSE;
   function supportsSQLCommand() {
      return $this->supportsSQLCommand;
   }

   var $supportsAcquireLock = FALSE;
   function supportsAcquireLock() {
      return $this->supportsAcquireLock;
   }

   var $supportsGetLockInfo = FALSE;
   function supportsGetLockInfo() {
      return $this->supportsGetLockInfo;
   }

   var $supportsGetLockedObjects = FALSE;
   function supportsGetLockedObjects() {
      return $this->supportsGetLockedObjects;
   }

   var $supportsGetLockOwners = FALSE;
   function supportsGetLockOwners() {
      return $this->supportsGetLockOwners;
   }

   var $supportsReleaseLock = FALSE;
   function supportsReleaseLock() {
      return $this->supportsReleaseLock;
   }

   var $supportsActivateLongTransaction = FALSE;
   function supportsActivateLongTransaction() {
      return $this->supportsActivateLongTransaction;
   }

   var $supportsCommitLongTransaction = FALSE;
   function supportsCommitLongTransaction() {
      return $this->supportsCommitLongTransaction;
   }

   var $supportsCreateLongTransaction = FALSE;
   function supportsCreateLongTransaction() {
      return $this->supportsCreateLongTransaction;
   }

   var $supportsGetLongTransactions = FALSE;
   function supportsGetLongTransactions() {
      return $this->supportsGetLongTransactions;
   }

   var $supportsFreezeLongTransaction = FALSE;
   function supportsFreezeLongTransaction() {
      return $this->supportsFreezeLongTransaction;
   }

   var $supportsRollbackLongTransaction = FALSE;
   function supportsRollbackLongTransaction() {
      return $this->supportsRollbackLongTransaction;
   }

   var $supportsActivateLongTransactionCheckpoint = FALSE;
   function supportsActivateLongTransactionCheckpoint() {
      return $this->supportsActivateLongTransactionCheckpoint;
   }

   var $supportsCreateLongTransactionCheckpoint = FALSE;
   function supportsCreateLongTransactionCheckpoint() {
      return $this->supportsCreateLongTransactionCheckpoint;
   }

   var $supportsGetLongTransactionCheckpoints = FALSE;
   function supportsGetLongTransactionCheckpoints() {
      return $this->supportsGetLongTransactionCheckpoints;
   }

   var $supportsRollbackLongTransactionCheckpoint = FALSE;
   function supportsRollbackLongTransactionCheckpoint() {
      return $this->supportsRollbackLongTransactionCheckpoint;
   }

   var $supportsChangeLongTransactionPrivileges = FALSE;
   function supportsChangeLongTransactionPrivileges() {
      return $this->supportsChangeLongTransactionPrivileges;
   }

   var $supportsGetLongTransactionPrivileges = FALSE;
   function supportsGetLongTransactionPrivileges() {
      return $this->supportsGetLongTransactionPrivileges;
   }

   var $supportsChangeLongTransactionSet = FALSE;
   function supportsChangeLongTransactionSet() {
      return $this->supportsChangeLongTransactionSet;
   }

   var $supportsGetLongTransactionsInSet = FALSE;
   function supportsGetLongTransactionsInSet() {
      return $this->supportsGetLongTransactionsInSet;
   }

   var $supportsFirstProviderCommand = FALSE;
   function supportsFirstProviderCommand() {
      return $this->supportsFirstProviderCommand;
   }

   var $supportsDeactivateLongTransaction = FALSE;
   function supportsDeactivateLongTransaction() {
      return $this->supportsDeactivateLongTransaction;
   }

   // rest of Commands

   var $supportsParameters = FALSE;
   function supportsParameters() {
      return $this->supportsParameters;
   }

   var $supportsCommandTimeout = FALSE;
   function supportsCommandTimeout() {
      return $this->supportsCommandTimeout;
   }

   var $supportsSelectExpressions = FALSE;
   function supportsSelectExpressions() {
      return $this->supportsSelectExpressions;
   }

   var $supportsSelectFunctions = FALSE;
   function supportsSelectFunctions() {
      return $this->supportsSelectFunctions;
   }

   var $supportsSelectDistinct = FALSE;
   function supportsSelectDistinct() {
      return $this->supportsSelectDistinct;
   }

   var $supportsSelectOrdering = FALSE;
   function supportsSelectOrdering() {
      return $this->supportsSelectOrdering;
   }

   var $supportsSelectGrouping = FALSE;
   function supportsSelectGrouping() {
      return $this->supportsSelectGrouping;
   }

   function queryCommand() {
      $this->queryCommands();
      $this->queryBooleanElement("//FeatureProviderCapabilities/Command/SupportsParameters", $this->supportsParameters);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Command/SupportsTimeout", $this->supportsCommandTimeout);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Command/SupportsSelectExpressions", $this->supportsSelectExpressions);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Command/SupportsSelectFunctions", $this->supportsSelectFunctions);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Command/SupportsSelectDistinct", $this->supportsSelectDistinct);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Command/SupportsSelectOrdering", $this->supportsSelectOrdering);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Command/SupportsSelectGrouping", $this->supportsSelectGrouping);
   }

   function queryCommands() {
      $domNodeList = $this->xpath->query("//FeatureProviderCapabilities/Command/SupportedCommands/Name");
      $count = $domNodeList->length;
      for($i=0; $i<$count; $i++) {
     $domNode = $domNodeList->item($i);
     $value = $domNode->nodeValue;
     switch($value) {
        case "Insert" : $this->supportsInsert = TRUE; break;
        case "Delete" : $this->supportsDelete = TRUE; break;
        case "Update" : $this->supportsUpdate = TRUE; break;
        case "Select" : $this->supportsSelect = TRUE; break;
        case "SelectAggregates" : $this->supportsSelectAggregates = TRUE; break;
        case "DescribeSchema" : $this->supportsDescribeSchema = TRUE; break;
        case "DescribeSchemaMapping" : $this->supportsDescribeSchemaMapping = TRUE; break;
        case "DestroySchema" : $this->supportsDestroySchema = TRUE; break;
        case "ApplySchema" : $this->supportsApplySchema = TRUE; break;
        case "SQLCommand" : $this->supportsSQLCommand = TRUE; break;
        case "ActivateSpatialContext" : $this->supportsActivateSpatialContext = TRUE; break;
        case "CreateSpatialContext" : $this->supportsCreateSpatialContext = TRUE; break;
        case "DestroySpatialContext" : $this->supportsDestroySpatialContext = TRUE; break;
        case "GetSpatialContexts" : $this->supportsGetSpatialContexts = TRUE; break;
        case "CreateMeasureUnit" : $this->supportsCreateMeasureUnit = TRUE; break;
        case "DestroyMeasureUnit" : $this->supportsDestroyMeasureUnit = TRUE; break;
        case "GetMeasureUnits" : $this->supportsGetMeasureUnits = TRUE; break;
        case "AcquireLock" : $this->supportsAcquireLock = TRUE; break;
        case "GetLockInfo" : $this->supportsGetLockInfo = TRUE; break;
        case "GetLockedObjects" : $this->supportsGetLockedObjects = TRUE; break;
        case "GetLockOwners" : $this->supportsGetLockOwners = TRUE; break;
        case "ReleaseLock" : $this->supportsReleaseLock = TRUE; break;
        case "ActivateLongTransaction" : $this->supportsActivateLongTransaction = TRUE; break;
        case "CommitLongTransaction" : $this->supportsCommitLongTransaction = TRUE; break;
        case "CreateLongTransaction" : $this->supportsCreateLongTransaction = TRUE; break;
        case "GetLongTransactions" : $this->supportsGetLongTransactions = TRUE; break;
        case "FreezeLongTransaction" : $this->supportsFreezeLongTransaction = TRUE; break;
        case "RollbackLongTransaction" : $this->supportsRollbackLongTransaction = TRUE; break;
        case "ActivateLongTransactionCheckpoint" : $this->supportsActivateLongTransactionCheckpoint = TRUE; break;
        case "CreateLongTransactionCheckpoint" : $this->supportsCreateLongTransactionCheckpoint = TRUE; break;
        case "GetLongTransactionCheckpoints" : $this->supportsGetLongTransactionCheckpoints = TRUE; break;
        case "RollbackLongTransactionCheckpoint" : $this->supportsRollbackLongTransactionCheckpoint = TRUE; break;
        case "ChangeLongTransactionPrivileges" : $this->supportsChangeLongTransactionPrivileges = TRUE; break;
        case "GetLongTransactionPrivileges" : $this->supportsGetLongTransactionPrivileges = TRUE; break;
        case "ChangeLongTransactionSet" : $this->supportsChangeLongTransactionSet = TRUE; break;
        case "GetLongTransactionsInSet" : $this->supportsGetLongTransactionsInSet = TRUE; break;
        case "FirstProviderCommand" : $this->supportsFirstProviderCommand = TRUE; break;
        case "DeactivateLongTransaction" : $this->supportsDeactivateLongTransaction = TRUE; break;
        default : fwrite($this->logFileHandle, "unknown command type: $value\n");
     }
      }
   }

   // FILTER

   // Condition types

   var $supportsComparison = FALSE;
   function supportsComparison() {
      return $this->supportsComparison;
   }

   var $supportsLike = FALSE;
   function supportsLike() {
      return $this->supportsLike;
   }

   var $supportsIn = FALSE;
   function supportsIn() {
      return $this->supportsIn;
   }

   var $supportsNull = FALSE;
   function supportsNull() {
      return $this->supportsNull;
   }

   var $supportsSpatial = FALSE;
   function supportsSpatial() {
      return $this->supportsSpatial;
   }

   var $supportsDistance = FALSE;
   function supportsDistance() {
      return $this->supportsDistance;
   }

   // Spatial types

   var $supportsContains = FALSE;
   function supportsContains() {
      return $this->supportsContains;
   }

   var $supportsCrosses = FALSE;
   function supportsCrosses() {
      return $this->supportsCrosses;
   }

   var $supportsDisjoint = FALSE;
   function supportsDisjoint() {
      return $this->supportsDisjoint;
   }

   var $supportsEquals = FALSE;
   function supportsEquals() {
      return $this->supportsEquals;
   }

   var $supportsIntersects = FALSE;
   function supportsIntersects() {
      return $this->supportsIntersects;
   }

   var $supportsOverlaps = FALSE;
   function supportsOverlaps() {
      return $this->supportsOverlaps;
   }

   var $supportsTouches = FALSE;
   function supportsTouches() {
      return $this->supportsTouches;
   }

   var $supportsSpatialWithin = FALSE;
   function supportsSpatialWithin() {
      return $this->supportsSpatialWithin;
   }

   var $supportsCoveredBy = FALSE;
   function supportsCoveredBy() {
      return $this->supportsCoveredBy;
   }

   var $supportsInside = FALSE;
   function supportsInside() {
      return $this->supportsInside;
   }

   var $supportsEnvelopeIntersects = FALSE;
   function supportsEnvelopeIntersects() {
      return $this->supportsEnvelopeIntersects;
   }

   // Distance types

   var $supportsBeyond = FALSE;
   function supportsBeyond() {
      return $this->supportsBeyond;
   }

   var $supportsDistanceWithin = FALSE;
   function supportsDistanceWithin() {
      return $this->supportsDistanceWithin;
   }

   // rest of Filter

   var $supportsGeodesicDistance = FALSE;
   function supportsGeodesicDistance() {
      return $this->supportsGeodesicDistance;
   }

   var $supportsNonLiteralGeometricOperations = FALSE;
   function supportsNonLiteralGeometricOperations() {
      return $this->supportsNonLiteralGeometricOperations;
   }

   function queryFilter() {
      $this->queryConditionType();
      $this->querySpatialOperations();
      $this->queryDistanceOperations();
      $this->queryBooleanElement("//FeatureProviderCapabilities/Filter/SupportsGeodesicDistance", $this->supportsGeodesicDistance);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Filter/SupportsNonLiteralGeometricOperations", $this->supportsNonLiteralGeometricOperations);
   }

   function queryConditionType() {
      $domNodeList = $this->xpath->query("//FeatureProviderCapabilities/Filter/Condition/Type");
      $count = $domNodeList->length;
      for($i=0; $i<$count; $i++) {
     $domNode = $domNodeList->item($i);
     $value = $domNode->nodeValue;
     switch($value) {
        case "Comparison" : $this->supportsComparison = TRUE; break;
        case "Like" : $this->supportsLike = TRUE; break;
        case "In" : $this->supportsIn = TRUE; break;
        case "Null" : $this->supportsNull = TRUE; break;
        case "Spatial" : $this->supportsSpatial = TRUE; break;
        case "Distance" : $this->supportsDistance = TRUE; break;
; break;
        default : fwrite($this->logFileHandle, "unknown filter condition type: $value\n");
     }
      }
   }

   function querySpatialOperations() {
      $domNodeList = $this->xpath->query("//FeatureProviderCapabilities/Filter/Spatial/Operation");
      $count = $domNodeList->length;
      for($i=0; $i<$count; $i++) {
     $domNode = $domNodeList->item($i);
     $value = $domNode->nodeValue;
     switch($value) {
        case "Contains" : $this->supportsContains = TRUE; break;
        case "Crosses" : $this->supportsCrosses = TRUE; break;
        case "Disjoint" : $this->supportsDisjoint = TRUE; break;
        case "Equals" : $this->supportsEquals = TRUE; break;
        case "Intersects" : $this->supportsIntersects = TRUE; break;
        case "Overlaps" : $this->supportsOverlaps = TRUE; break;
        case "Touches" : $this->supportsTouches = TRUE; break;
        case "Within" : $this->supportsSpatialWithin = TRUE; break;
        case "CoveredBy" : $this->supportsCoveredBy = TRUE; break;
        case "Inside" : $this->supportsInside = TRUE; break;
        case "EnvelopeIntersects" : $this->supportsEnvelopeIntersects = TRUE; break;
        default : fwrite($this->logFileHandle, "unknown filter spatial operation: $value\n");
     }
      }
   }

   function queryDistanceOperations() {
      $domNodeList = $this->xpath->query("//FeatureProviderCapabilities/Filter/Distance/Operation");
      $count = $domNodeList->length;
      for($i=0; $i<$count; $i++) {
     $domNode = $domNodeList->item($i);
     $value = $domNode->nodeValue;
     switch($value) {
        case "Within" : $this->supportsDistanceWithin = TRUE; break;
        case "Beyond" : $this->supportsBeyond = TRUE; break;
        default : fwrite($this->logFileHandle, "unknown filter distance operation: $value\n");
     }
      }
   }

   // EXPRESSION

   // types

   var $supportsBasic = FALSE;
   function supportsBasic() {
      return $this->supportsBasic;
   }

   var $supportsFunction = FALSE;
   function supportsFunction() {
      return $this->supportsFunction;
   }

   var $supportsParameter = FALSE;
   function supportsParameter() {
      return $this->supportsParameter;
   }

   var $supportsAvg = FALSE;
   function supportsAvg() {
      return $this->supportsAvg;
   }

   var $supportsCeil = FALSE;
   function supportsCeil() {
      return $this->supportsCeil;
   }

   var $supportsCLIP = FALSE;
   function supportsCLIP() {
      return $this->supportsCLIP;
   }

   var $supportsConcat = FALSE;
   function supportsConcat() {
      return $this->supportsConcat;
   }

   var $supportsCount = FALSE;
   function supportsCount() {
      return $this->supportsCount;
   }

   var $supportsFloor = FALSE;
   function supportsFloor() {
      return $this->supportsFloor;
   }

   var $supportsLower = FALSE;
   function supportsLower() {
      return $this->supportsLower;
   }

   var $supportsMax = FALSE;
   function supportsMax() {
      return $this->supportsMax;
   }

   var $supportsMin = FALSE;
   function supportsMin() {
      return $this->supportsMin;
   }

   var $supportsMOSAIC = FALSE;
   function supportsMOSAIC() {
      return $this->supportsMOSAIC;
   }

   var $supportsStdDev = FALSE;
   function supportsStdDev() {
      return $this->supportsStdDev;
   }

   var $supportsSum = FALSE;
   function supportsSum() {
      return $this->supportsSum;
   }

   var $supportsUpper = FALSE;
   function supportsUpper() {
      return $this->supportsUpper;
   }

   function queryExpression() {
      $this->queryExpressionType();
      $this->queryFunctionDefinitions();
   }

   function queryExpressionType() {
      $domNodeList = $this->xpath->query("//FeatureProviderCapabilities/Expression/Type/Name");
      $count = $domNodeList->length;
      for($i=0; $i<$count; $i++) {
     $domNode = $domNodeList->item($i);
     $value = $domNode->nodeValue;
     switch($value) {
        case "Basic" : $this->supportsBasic = TRUE; break;
        case "Function" : $this->supportsFunction = TRUE; break;
        case "Parameter" : $this->supportsParameter = TRUE; break;
        default : fwrite($this->logFileHandle, "unknown filter distance operation: $value\n");
     }
      }
   }

   function queryFunctionDefinitions() {
      $domNodeList = $this->xpath->query("//FeatureProviderCapabilities/Expression/FunctionDefinitionCollection/FunctionDefinition/Name");
      $count = $domNodeList->length;
      for($i=0; $i<$count; $i++) {
     $domNode = $domNodeList->item($i);
     $value = $domNode->nodeValue;
     switch($value) {
        case "Avg" : $this->supportsAvg = TRUE; break;
        case "Ceil" : $this->supportsCeil = TRUE; break;
        case "CLIP" : $this->supportsCLIP = TRUE; break;
        case "Concat" : $this->supportsConcat = TRUE; break;
        case "Count" : $this->supportsCount = TRUE; break;
        case "Floor" : $this->supportsFloor = TRUE; break;
        case "Lower" : $this->supportsLower = TRUE; break;
        case "Max" : $this->supportsMax = TRUE; break;
        case "Min" : $this->supportsMin = TRUE; break;
        case "MOSAIC" : $this->supportsMOSAIC = TRUE; break;
        case "StdDev" : $this->supportsStdDev = TRUE; break;
        case "Sum" : $this->supportsSum = TRUE; break;
        case "Upper" : $this->supportsUpper = TRUE; break;
        default : fwrite($this->logFileHandle, "unknown expression function name: $value\n");
     }
      }
   }

   // RASTER

   var $supportsRaster = FALSE;
   function supportsRaster() {
      return $this->supportsRaster;
   }

   var $supportsStitching = FALSE;
   function supportsStitching() {
      return $this->supportsStitching;
   }

   var $supportsSubsampling = FALSE;
   function supportsSubsampling() {
      return $this->supportsSubsampling;
   }

   function queryRaster() {
      $this->queryBooleanElement("//FeatureProviderCapabilities/Raster/SupportsRaster", $this->supportsRaster);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Raster/SupportsStitching", $this->supportsStitching);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Raster/SupportsSubsampling", $this->supportsSubsampling);
   }

   // TOPOLOGY

   var $supportsTopology = FALSE;
   function supportsTopology() {
      return $this->supportsTopology;
   }

   var $supportsTopologicalHierarchy = FALSE;
   function supportsTopologicalHierarchy() {
      return $this->supportsTopologicalHierarchy;
   }

   var $supportsBreaksCurveCrossingsAutomatically = FALSE;
   function supportsBreaksCurveCrossingsAutomatically() {
      return $this->supportsBreaksCurveCrossingsAutomatically;
   }

   var $supportsActivatesTopologyByArea = FALSE;
   function supportsActivatesTopologyByArea() {
      return $this->supportsActivatesTopologyByArea;
   }

   var $supportsConstrainsFeatureMovements = FALSE;
   function supportsConstrainsFeatureMovements() {
      return $this->supportsConstrainsFeatureMovements;
   }

   function queryTopology() {
      $this->queryBooleanElement("//FeatureProviderCapabilities/Topology/SupportsTopology", $this->supportsTopology);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Topology/SupportsTopologicalHierarchy", $this->supportsTopologicalHierarchy);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Topology/BreaksCurveCrossingsAutomatically", $this->supportsBreaksCurveCrossingsAutomatically);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Topology/ActivatesTopologyByArea", $this->supportsActivatesTopologyByArea);
      $this->queryBooleanElement("//FeatureProviderCapabilities/Topology/ConstrainsFeatureMovements", $this->supportsConstrainsFeatureMovements);
   }

   // GEOMETRY

   var $supportsPoint = FALSE;
   function supportsPoint() {
      return $this->supportsPoint;
   }

   var $supportsMultiPoint = FALSE;
   function supportsMultiPoint() {
      return $this->supportsMultiPoint;
   }

   var $supportsLineString = FALSE;
   function supportsLineString() {
      return $this->supportsLineString;
   }

   var $supportsMultiLineString = FALSE;
   function supportsMultiLineString() {
      return $this->supportsMultiLineString;
   }

   var $supportsPolygon = FALSE;
   function supportsPolygon() {
      return $this->supportsPolygon;
   }

   var $supportsMultiPolygon = FALSE;
   function supportsMultiPolygon() {
      return $this->supportsMultiPolygon;
   }

   var $supportsCurveString = FALSE;
   function supportsCurveString() {
      return $this->supportsCurveString;
   }

   var $supportsMultiCurveString = FALSE;
   function supportsMultiCurveString() {
      return $this->supportsMultiCurveString;
   }

   var $supportsCurvePolygon = FALSE;
   function supportsCurvePolygon() {
      return $this->supportsCurvePolygon;
   }

   var $supportsMultiCurvePolygon = FALSE;
   function supportsMultiCurvePolygon() {
      return $this->supportsMultiCurvePolygon;
   }

   var $supportsMultiGeometry = FALSE;
   function supportsMultiGeometry() {
      return $this->supportsMultiGeometry;
   }

   var $supportsLinearRing = FALSE;
   function supportsLinearRing() {
      return $this->supportsLinearRing;
   }
   var $supportsLinearSegment = FALSE;
   function supportsLinearSegment() {
      return $this->supportsLinearSegment;
   }
   var $supportsArcSegment = FALSE;
   function supportsArcSegment() {
      return $this->supportsArcSegment;
   }
   var $supportsCurveRing = FALSE;
   function supportsCurveRing() {
      return $this->supportsCurveRing;
   }

   var $dimensionality = -1;
   function getDimensionality() {
      return $this->dimensionality;
   }

   function queryGeometry() {
      $this->queryGeometries();
      $this->queryComponents();
      $this->queryDimensionality();
   }

   function queryGeometries() {
      $domNodeList = $this->xpath->query("//FeatureProviderCapabilities/Geometry/Type");
      $count = $domNodeList->length;
      for($i=0; $i<$count; $i++) {
     $domNode = $domNodeList->item($i);
     $value = $domNode->nodeValue;
     switch($value) {
        case "Point" : $this->supportsPoint = TRUE; break;
        case "MultiPoint" : $this->supportsMultiPoint = TRUE; break;
        case "LineString" : $this->supportsLineString = TRUE; break;
        case "MultiLineString" : $this->supportsMultiLineString = TRUE; break;
        case "Polygon" : $this->supportsPolygon = TRUE; break;
        case "MultiPolygon" : $this->supportsMultiPolygon = TRUE; break;
        case "CurveString" : $this->supportsCurveString = TRUE; break;
        case "MultiCurveString" : $this->supportsMultiCurveString = TRUE; break;
        case "CurvePolygon" : $this->supportsCurvePolygon = TRUE; break;
        case "MultiCurvePolygon" : $this->supportsMultiCurvePolygon = TRUE; break;
        case "MultiGeometry" : $this->supportsMultiGeometry = TRUE; break;
        default : fwrite($this->logFileHandle, "unknown geometry type: $value\n");
     }
      }
   }

   function queryComponents() {
      $domNodeList = $this->xpath->query("//FeatureProviderCapabilities/Geometry/Components/Type");
      $count = $domNodeList->length;
      for($i=0; $i<$count; $i++) {
     $domNode = $domNodeList->item($i);
     $value = $domNode->nodeValue;
     switch($value) {
        case "LinearRing" : $this->supportsLinearRing = TRUE; break;
        case "LinearSegment" : $this->supportsLinearSegment = TRUE; break;
        case "ArcSegment" : $this->supportsArcSegment = TRUE; break;
        case "CurveRing" : $this->supportsCurveRing = TRUE; break;
        default : fwrite($this->logFileHandle, "unknown geometry component type: $value\n");
     }
      }
   }

   function queryDimensionality() {
      $domNodeList = $this->xpath->query("//FeatureProviderCapabilities/Geometry/Dimensionality");
      if ($domNodeList->length == 0) return;
      $domNode = $domNodeList->item(0);
      $value = $domNode->nodeValue;
      $this->dimensionality = $value;
   }

   function logCapabilities() {
      fwrite($this->logFileHandle, "Capabilities for $this->providerName\n");
      fwrite($this->logFileHandle, "Connection\n");
      fwrite($this->logFileHandle, "\tThreadCapability\n");
      $logEntry = "\t\tsupportsSingleThreaded(): " . $this->prtBool($this->supportsSingleThreaded()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\tsupportsPerConnectionThreaded(): " . $this->prtBool($this->supportsPerConnectionThreaded()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\tsupportsPerCommandThreaded(): " . $this->prtBool($this->supportsPerCommandThreaded()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\tsupportsMultiThreaded(): " . $this->prtBool($this->supportsMultiThreaded()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      fwrite($this->logFileHandle, "\tSpatialContextExtent\n");
      fwrite($this->logFileHandle, "\t\tType\n");
      $logEntry = "\t\t\tsupportsDynamic(): " . $this->prtBool($this->supportsDynamic()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsStatic(): " . $this->prtBool($this->supportsStatic()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsLocking(): " . $this->prtBool($this->supportsLocking()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsConnectionTimeout(): " . $this->prtBool($this->supportsConnectionTimeout()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsTransactions(): " . $this->prtBool($this->supportsTransactions()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsLongTransactions(): " . $this->prtBool($this->supportsLongTransactions()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsSQL(): " . $this->prtBool($this->supportsSQL()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsConfiguration(): " . $this->prtBool($this->supportsConfiguration()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      fwrite($this->logFileHandle, "Schema\n");
      fwrite($this->logFileHandle, "\tClass\n");
      fwrite($this->logFileHandle, "\t\tType\n");
     $logEntry = "\t\t\tsupportsClass(): " . $this->prtBool($this->supportsClass()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsFeatureClass(): " . $this->prtBool($this->supportsFeatureClass()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      fwrite($this->logFileHandle, "\tData\n");
      fwrite($this->logFileHandle, "\t\tType\n");
      $logEntry = "\t\t\tsupportsBoolean(): " . $this->prtBool($this->supportsBoolean()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsByte(): " . $this->prtBool($this->supportsByte()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsDateTime(): " . $this->prtBool($this->supportsDateTime()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsDecimal(): " . $this->prtBool($this->supportsDecimal()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsDouble(): " . $this->prtBool($this->supportsDouble()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsInt16(): " . $this->prtBool($this->supportsInt16()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsInt32(): " . $this->prtBool($this->supportsInt32()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsInt64(): " . $this->prtBool($this->supportsInt64()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsSingle(): " . $this->prtBool($this->supportsSingle()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsString(): " . $this->prtBool($this->supportsString()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsBLOB(): " . $this->prtBool($this->supportsBLOB()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsCLOB(): " . $this->prtBool($this->supportsCLOB()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsUniqueID(): " . $this->prtBool($this->supportsUniqueID()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsInheritance(): " . $this->prtBool($this->supportsInheritance()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsMultipleSchemas(): " . $this->prtBool($this->supportsMultipleSchemas()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsObjectProperties(): " . $this->prtBool($this->supportsObjectProperties()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsAssociationProperties(): " . $this->prtBool($this->supportsAssociationProperties()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsSchemaOverrides(): " . $this->prtBool($this->supportsSchemaOverrides()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsNetworkModel(): " . $this->prtBool($this->supportsNetworkModel()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsAutoIdGeneration(): " . $this->prtBool($this->supportsAutoIdGeneration()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsDataStoreScopeUniqueIdGeneration(): " . $this->prtBool($this->supportsDataStoreScopeUniqueIdGeneration()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsSchemaModification(): " . $this->prtBool($this->supportsSchemaModification()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      fwrite($this->logFileHandle, "Command\n");
      fwrite($this->logFileHandle, "\tSupportedCommands\n");
      fwrite($this->logFileHandle, "\t\tName\n");
      $logEntry = "\t\t\tsupportsSelect(): " . $this->prtBool($this->supportsSelect()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsInsert(): " . $this->prtBool($this->supportsInsert()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsDelete(): " . $this->prtBool($this->supportsDelete()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsUpdate(): " . $this->prtBool($this->supportsUpdate()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsSelectAggregates(): " . $this->prtBool($this->supportsSelectAggregates()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsDescribeSchema(): " . $this->prtBool($this->supportsDescribeSchema()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsDescribeSchemaMapping(): " . $this->prtBool($this->supportsDescribeSchemaMapping()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsDestroySchema(): " . $this->prtBool($this->supportsDestroySchema()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsApplySchema(): " . $this->prtBool($this->supportsApplySchema()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsActivateSpatialContext(): " . $this->prtBool($this->supportsActivateSpatialContext()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsCreateSpatialContext(): " . $this->prtBool($this->supportsCreateSpatialContext()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsDestroySpatialContext(): " . $this->prtBool($this->supportsDestroySpatialContext()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsDestroySpatialContext(): " . $this->prtBool($this->supportsGetSpatialContexts) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsCreateMeasureUnit(): " . $this->prtBool($this->supportsCreateMeasureUnit()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsDestroyMeasureUnit()t: " . $this->prtBool($this->supportsDestroyMeasureUnit()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsGetMeasureUnits(): " . $this->prtBool($this->supportsGetMeasureUnits()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsSQLCommand(): " . $this->prtBool($this->supportsSQLCommand()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsAcquireLock(): " . $this->prtBool($this->supportsAcquireLock()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsGetLockInfo(): " . $this->prtBool($this->supportsGetLockInfo()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsGetLockedObjects(): " . $this->prtBool($this->supportsGetLockedObjects()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsGetLockOwners(): " . $this->prtBool($this->supportsGetLockOwners()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsReleaseLock(): " . $this->prtBool($this->supportsReleaseLock()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsActivateLongTransaction(): " . $this->prtBool($this->supportsActivateLongTransaction()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsCommitLongTransaction(): " . $this->prtBool($this->supportsCommitLongTransaction()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsCreateLongTransaction(): " . $this->prtBool($this->supportsCreateLongTransaction()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsGetLongTransactions(): " . $this->prtBool($this->supportsGetLongTransactions()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsFreezeLongTransaction(): " . $this->prtBool($this->supportsFreezeLongTransaction()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsRollbackLongTransaction(): " . $this->prtBool($this->supportsRollbackLongTransaction()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsActivateLongTransactionCheckpoint(): " . $this->prtBool($this->supportsActivateLongTransactionCheckpoint()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsCreateLongTransactionCheckpoint(): " . $this->prtBool($this->supportsCreateLongTransactionCheckpoint()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsGetLongTransactionCheckpoints(): " . $this->prtBool($this->supportsGetLongTransactionCheckpoints()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsRollbackLongTransactionCheckpoint(): " . $this->prtBool($this->supportsRollbackLongTransactionCheckpoint()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsChangeLongTransactionPrivileges(): " . $this->prtBool($this->supportsChangeLongTransactionPrivileges()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsGetLongTransactionPrivileges(): " . $this->prtBool($this->supportsGetLongTransactionPrivileges()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsChangeLongTransactionSet(): " . $this->prtBool($this->supportsChangeLongTransactionSet()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsGetLongTransactionsInSet(): " . $this->prtBool($this->supportsGetLongTransactionsInSet()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsFirstProviderCommand(): " . $this->prtBool($this->supportsFirstProviderCommand()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsDeactivateLongTransaction(): " . $this->prtBool($this->supportsDeactivateLongTransaction()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsParameters(): " . $this->prtBool($this->supportsParameters()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsCommandTimeout(): " . $this->prtBool($this->supportsCommandTimeout()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsSelectExpressions(): " . $this->prtBool($this->supportsSelectExpressions()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsSelectFunctions(): " . $this->prtBool($this->supportsSelectFunctions()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsSelectDistinct(): " . $this->prtBool($this->supportsSelectDistinct()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsSelectOrdering(): " . $this->prtBool($this->supportsSelectOrdering()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsSelectGrouping(): " . $this->prtBool($this->supportsSelectGrouping()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      fwrite($this->logFileHandle, "Filter\n");
      fwrite($this->logFileHandle, "\tCondition\n");
      fwrite($this->logFileHandle, "\t\tType\n");
      $logEntry = "\t\t\tsupportsComparison(): " . $this->prtBool($this->supportsComparison()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsLike(): " . $this->prtBool($this->supportsLike()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsIn(): " . $this->prtBool($this->supportsIn()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsNull(): " . $this->prtBool($this->supportsNull()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsSpatial(): " . $this->prtBool($this->supportsSpatial()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsDistance(): " . $this->prtBool($this->supportsDistance()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      fwrite($this->logFileHandle, "\tSpatial\n");
      fwrite($this->logFileHandle, "\t\tOperation\n");
      $logEntry = "\t\t\tsupportsContains(): " . $this->prtBool($this->supportsContains()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsCrosses(): " . $this->prtBool($this->supportsCrosses()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsDisjoint(): " . $this->prtBool($this->supportsDisjoint()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsEquals(): " . $this->prtBool($this->supportsEquals()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsIntersects(): " . $this->prtBool($this->supportsIntersects()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsOverlaps()s: " . $this->prtBool($this->supportsOverlaps()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsTouches(): " . $this->prtBool($this->supportsTouches()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsSpatialWithin(): " . $this->prtBool($this->supportsSpatialWithin()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsCoveredBy(): " . $this->prtBool($this->supportsCoveredBy()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsInside(): " . $this->prtBool($this->supportsInside()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsEnvelopeIntersects(): " . $this->prtBool($this->supportsEnvelopeIntersects()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      fwrite($this->logFileHandle, "\tDistance\n");
      fwrite($this->logFileHandle, "\t\tOperation\n");
      $logEntry = "\t\t\tsupportsDistanceWithin(): " . $this->prtBool($this->supportsDistanceWithin()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsBeyond(): " . $this->prtBool($this->supportsBeyond()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsGeodesicDistance(): " . $this->prtBool($this->supportsGeodesicDistance()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsNonLiteralGeometricOperations(): " . $this->prtBool($this->supportsNonLiteralGeometricOperations()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      fwrite($this->logFileHandle, "Expression\n");
      fwrite($this->logFileHandle, "\tType\n");
      fwrite($this->logFileHandle, "\t\tName\n");
      $logEntry = "\t\t\tsupportsBasic(): " . $this->prtBool($this->supportsBasic()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsFunction(): " . $this->prtBool($this->supportsFunction()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsParameter(): " . $this->prtBool($this->supportsParameter()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      fwrite($this->logFileHandle, "\tFunctionDefinitionCollection\n");
      fwrite($this->logFileHandle, "\t\tFunctionDefinition\n");
      fwrite($this->logFileHandle, "\t\t\tName\n");
      $logEntry = "\t\t\t\tsupportsAvg(): " . $this->prtBool($this->supportsAvg()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\t\tsupportsCeil(): " . $this->prtBool($this->supportsCeil()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\t\tsupportsCLIP(): " . $this->prtBool($this->supportsCLIP()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\t\tsupportsConcat(): " . $this->prtBool($this->supportsConcat()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\t\tsupportsCount(): " . $this->prtBool($this->supportsCount()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\t\tsupportsFloor(): " . $this->prtBool($this->supportsFloor()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\t\tsupportsLower(): " . $this->prtBool($this->supportsLower()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\t\tsupportsMax(): " . $this->prtBool($this->supportsMax()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\t\tsupportsMin(): " . $this->prtBool($this->supportsMin()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\t\tsupportsMOSAIC(): " . $this->prtBool($this->supportsMOSAIC()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\t\tsupportsStdDev(): " . $this->prtBool($this->supportsStdDev()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\t\tsupportsSum(): " . $this->prtBool($this->supportsSum()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\t\tsupportsUpper(): " . $this->prtBool($this->supportsUpper()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      fwrite($this->logFileHandle, "Raster\n");
      $logEntry = "\tsupportsRaster(): " . $this->prtBool($this->supportsRaster()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsStitching(): " . $this->prtBool($this->supportsStitching()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsSubsampling(): " . $this->prtBool($this->supportsSubsampling()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      fwrite($this->logFileHandle, "Topology\n");
      $logEntry = "\tsupportsTopology(): " . $this->prtBool($this->supportsTopology()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsTopologicalHierarchy(): " . $this->prtBool($this->supportsTopologicalHierarchy()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsBreaksCurveCrossingsAutomatically(): " . $this->prtBool($this->supportsBreaksCurveCrossingsAutomatically()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsActivatesTopologyByArea(): " . $this->prtBool($this->supportsActivatesTopologyByArea()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tsupportsConstrainsFeatureMovements(): " . $this->prtBool($this->supportsConstrainsFeatureMovements()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      fwrite($this->logFileHandle, "Geometry\n");
      fwrite($this->logFileHandle, "\tType\n");
      $logEntry = "\t\tsupportsPoint(): " . $this->prtBool($this->supportsPoint()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\tsupportsMultiPoint(): " . $this->prtBool($this->supportsMultiPoint()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\tsupportsLineString(): " . $this->prtBool($this->supportsLineString()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\tsupportsMultiLineString(): " . $this->prtBool($this->supportsMultiLineString()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\tsupportsPolygon(): " . $this->prtBool($this->supportsPolygon()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\tsupportsMultiPolygon(): " . $this->prtBool($this->supportsMultiPolygon()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\tsupportsCurveString(): " . $this->prtBool($this->supportsCurveString()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\tsupportsMultiCurveString(): " . $this->prtBool($this->supportsMultiCurveString()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\tsupportsCurvePolygon(): " . $this->prtBool($this->supportsCurvePolygon()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\tsupportsMultiCurvePolygon(): " . $this->prtBool($this->supportsMultiCurvePolygon()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\tsupportsMultiGeometry(): " . $this->prtBool($this->supportsMultiGeometry()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      fwrite($this->logFileHandle, "\tComponents\n");
      fwrite($this->logFileHandle, "\t\tType\n");
      $logEntry = "\t\t\tsupportsLinearRing(): " . $this->prtBool($this->supportsLinearRing()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsLinearSegment(): " . $this->prtBool($this->supportsLinearSegment()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsArcSegment(): " . $this->prtBool($this->supportsArcSegment()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\t\t\tsupportsCurveRing(): " . $this->prtBool($this->supportsCurveRing()) . "\n";
      fwrite($this->logFileHandle, $logEntry);
      $logEntry = "\tdimensionality(): " . $this->getDimensionality() . "\n";
      fwrite($this->logFileHandle, $logEntry);
   }
}