[mapguide-commits] r10068 - in branches/4.0/MgDev/Doc/landing: . topics
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Fri Nov 10 12:21:37 PST 2023
Author: jng
Date: 2023-11-10 12:21:36 -0800 (Fri, 10 Nov 2023)
New Revision: 10068
Added:
branches/4.0/MgDev/Doc/landing/topics/feature-connection.md.tpl
branches/4.0/MgDev/Doc/landing/topics/feature-filters.md.tpl
branches/4.0/MgDev/Doc/landing/topics/feature-intro.md.tpl
branches/4.0/MgDev/Doc/landing/topics/feature-provider-registry.md.tpl
branches/4.0/MgDev/Doc/landing/topics/feature-provider.md.tpl
branches/4.0/MgDev/Doc/landing/topics/feature-schema.md.tpl
Modified:
branches/4.0/MgDev/Doc/landing/toc.yml
branches/4.0/MgDev/Doc/landing/topics/toc.yml
Log:
#2877:
- Finish migrating across feature service conceptual topics
- Add .net/Java/PHP top-level links
Modified: branches/4.0/MgDev/Doc/landing/toc.yml
===================================================================
--- branches/4.0/MgDev/Doc/landing/toc.yml 2023-11-10 19:15:59 UTC (rev 10067)
+++ branches/4.0/MgDev/Doc/landing/toc.yml 2023-11-10 20:21:36 UTC (rev 10068)
@@ -1,3 +1,9 @@
# TODO: Link to conceptual topics once they've all been migrated to markdown and copied into this dir
- name: Conceptual Topics
- href: topics/toc.yml
\ No newline at end of file
+ href: topics/toc.yml
+- name: .net Reference
+ href: dotnet_api/index.html
+- name: Java Reference
+ href: java_api/index.html
+- name: PHP Reference
+ href: php_api/index.html
\ No newline at end of file
Added: branches/4.0/MgDev/Doc/landing/topics/feature-connection.md.tpl
===================================================================
--- branches/4.0/MgDev/Doc/landing/topics/feature-connection.md.tpl (rev 0)
+++ branches/4.0/MgDev/Doc/landing/topics/feature-connection.md.tpl 2023-11-10 20:21:36 UTC (rev 10068)
@@ -0,0 +1,542 @@
+# Connection to Feature Source
+
+## About feature sources
+
+A feature source contains feature data. The term 'feature
+source' refers to a feature data resource in the site server
+repository. The feature source is installed in the repository
+using the resource service (`MgResourceService`).
+
+What constitutes a feature source varies depending on the
+nature of the actual data source. For example, some data
+sources are text files, some are binary files, and some are
+relational databases. If the data source is a file, the file
+itself is stored in the repository. If the data source is a
+relational database, a connection specification is stored in
+the repository. Some relational databases support
+partitioning into multiple data sources. Each partition
+requires a separate connection specification.
+
+## Storing and identifying feature sources
+
+In addition to features sources, the site server repository
+contains many other objects, which are collectively referred
+to as resources and identified by resource identifiers
+(`MgResourceIdentifier`) [!doclinkclass MgResourceIdentifier]. The resource identifier specifies the
+location of a resource in the repository by using a URL.
+
+The feature source URL is of the form
+`Library:://.../<featureSourceName>.FeatureSource`. The
+ellipsis (`...`) represents an optional folder structure
+contained within the root Library folder. An example
+identifier is
+`Library://FeatureService/PointsMDB.FeatureSource`. The
+FeatureSource extension is specific to the feature source
+resource. All of the methods in the MgFeatureService API that
+do actual work require an MgResourceIdentifier object as an
+argument.
+
+<p>
+
+</p>
+
+## Before installing a feature source in the repository
+
+The `MgFeatureService` [!doclinkclass MgFeatureService] API provides a `TestConnection`
+method for testing the connection parameter values for a
+feature source prior to installation in the repository. For
+file-based feature sources the connection value could be a
+file name, a folder name, or a symbolic name which is used
+by the provider to query the operating system for the file
+location. For relational database feature sources, possible
+connection values include host name, service name, service
+instance name, user name, password, and datastore name.
+
+The connection string used to connect to a feature source is
+specific to the feature source. Examples follow for various
+providers.
+
+The `MgFeatureService` API provides a `GetConnectionPropertyValues`
+method for listing the names of the feature source partitions
+within a relational database. You can then construct a
+connection string for each partition and test it using `TestConnection`
+
+After the installation of the feature source in the
+repository, connection is done by a different `TestConnection(MgResourceIdentifier)`
+method that takes the feature source's resource identifier as
+an argument.
+
+## Installing the feature source in the repository
+
+Install a feature source in the repository by:
+ * Specifying the location of the feature source in the
+repository in a resource identifier.
+ * Uploading a feature source XML value containing the
+property values used to connect to and configure the feature
+source. The structure of a feature source XML value conforms
+to the [FeatureSource](xmlschema-featuresource.md) XML schema. The element values
+vary according to the feature source type. Examples for each
+provider follow.
+ * Uploading an XML value containing values governing the
+security of the feature source. See the \link ResourceDocumentHeader_schema ResourceDocumentHeader \endlink
+and [ResourceSecurity](xmlschema-resourcesecurity.md) schema topics for a general
+discussion about the XML element definitions. See the
+contents of an example header file at the end of this topic.
+ * Uploading the file or files which constitute the feature
+source if the feature source is file-based.
+Upload the feature source property XML file and document
+header XML file using the
+`MgResourceService::SetResource` method
+Upload a feature source file using the `MgResourceService::SetResourceData` method.
+
+## Examples for various providers
+
+### Autodesk.Oracle.2.0 Provider
+
+<p>
+ The feature source is a relational database, which supports
+ multiple partitions, referred to as datastores. Each
+ datastore can be a feature source. You use Sysadmin.exe to
+ create datastores and add usernames and passwords. The tool
+ and documentation for doing these and other tasks is
+ contained in the installation. For a typical installation,
+ the path is <i>C:\\Program Files\\Common Files\\Autodesk
+ Shared\\GIS\\FDO\\2.0\\Oracle</i>.
+</p>
+
+Example Connection String
+
+```
+Username=smith;Password=test;Service=TuxService;DataStore=TUX
+```
+
+All parameters are required.
+
+The `DataStore` property value identifies the feature source
+partition within the database. This value can be retrieved
+from the database using the `MgFeatureService::GetConnectionPropertyValues` Method.
+
+The Service property value identifies an entry in the `tnsnames.ora` file located in the Oracle instance or Oracle client
+installation on the local host.
+
+Feature Source XML File
+
+The filename is `TuxService.FeatureSource`.
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<FeatureSource version="1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance " xsi:noNamespaceSchemaLocation="FeatureSource-1.0.0.xsd">
+ <Provider>Autodesk.Oracle.2.0</Provider>
+ <ConnectionProperties>
+ <ConnectionProperty>
+ <Name>DataStore</Name>
+ <Value>TUX</Value>
+ </ConnectionProperty>
+ <ConnectionProperty>
+ <Name>Username</Name>
+ <Value>smith</Value>
+ </ConnectionProperty>
+ <ConnectionProperty>
+ <Name>Password</Name>
+ <Value>test</Value>
+ </ConnectionProperty>
+ <ConnectionProperty>
+ <Name>Service</Name>
+ <Value>TuxService</Value>
+ </ConnectionProperty>
+ </ConnectionProperties>
+ <Configuration/>
+ <SpatialContext/>
+ <LongTransaction/>
+</FeatureSource>
+```
+
+### Autodesk.ArcSDE.1.0 Provider
+
+The feature source is a relational database. Access to it is
+indirect. The provider talks to an ArcSDE client, which talks
+to the ArcSDE server, which talks to the feature source.
+
+Example Connection String
+
+```
+Username=smith;Password=test;Server=otwhost1;Instance=sde_inst1;Datastore=Default Datastore
+```
+
+All parameters are required.
+
+The `Server` value is a hostname whose IP address can be
+resolved using a network domain name server.
+
+The `instance` value must appear in the services file on the
+local host. The path is `C:\\WINDOWS\\system32\\drivers\\etc\\services`.
+An example entry is `sde_inst1 5151/tcp \#ArcSDE Server listening port`.
+
+The `Datastore` property value identifies the feature source
+partition within the database. This value can be retrieved
+from the database using the `MgFeatureService::GetConnectionPropertyValues` Method.
+
+A value of `Default Datastore` indicates that only one
+partition exists.
+
+Feature Source XML File
+
+The filename is `sde_inst1.FeatureSource`
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<FeatureSource version="1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance " xsi:noNamespaceSchemaLocation="FeatureSource-1.0.0.xsd">
+ <Provider>Autodesk.ArcSDE.1.0</Provider>
+ <ConnectionProperties>
+ <ConnectionProperty>
+ <Name>Datastore</Name>
+ <Value>Default Datastore</Value>
+ </ConnectionProperty>
+ <ConnectionProperty>
+ <Name>Username</Name>
+ <Value>smith</Value>
+ </ConnectionProperty>
+ <ConnectionProperty>
+ <Name>Password</Name>
+ <Value>test</Value>
+ </ConnectionProperty>
+ <ConnectionProperty>
+ <Name>Server</Name>
+ <Value>otwhost1</Value>
+ </ConnectionProperty>
+ <ConnectionProperty>
+ <Name>Instance</Name>
+ <Value>sde_inst1</Value>
+ </ConnectionProperty>
+ </ConnectionProperties>
+ <Configuration/>
+ <SpatialContext/>
+<LongTransaction/>
+</FeatureSource>
+```
+
+### Autodesk.Sdf.3.0 Provider
+
+The feature source is a file. As part of installing the
+feature source in the repository, the <i>.sdf</i> file is
+loaded into the repository.
+
+Example Connection String
+
+```
+File=C:/SDFFeatureResources/testSDF.sdf;ReadOnly=FALSE
+```
+
+The `File` parameter is mandatory, and the `ReadOnly` parameter
+defaults to `FALSE`.
+
+Feature Source XML File
+
+The `ConnectionProperty` element whose `Name` is `File` has a `Value` element that is a symbolic reference to the location of the `.sdf` file in the repository.
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<FeatureSource version="1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance " xsi:noNamespaceSchemaLocation="FeatureSource-1.0.0.xsd">
+ <Provider>Autodesk.Sdf.3.0</Provider>
+ <ConnectionProperties>
+ <ConnectionProperty>
+ <Name>File</Name>
+ <Value>%MG_DATA_FILE_PATH%</Value>
+ </ConnectionProperty>
+ <ConnectionProperty>
+ <Name>ReadOnly</Name>
+ <Value>FALSE</Value>
+ </ConnectionProperty>
+ </ConnectionProperties>
+ <SpatialContext/>
+ <LongTransaction/>
+</FeatureSource>
+```
+
+### Autodesk.Shp.1.0 Provider
+
+The feature source is a set of up to 4 related files,
+collectively referred to as shapefiles. They consist of a <i>.shp</i> file containing the shape geometry, the <i>.shx</i> file
+containing the shape row index, the <i>.dbf</i> file
+containing shape attributes in dBASE format, and the <i>.prj</i> file containing the coordinate system.
+
+It is possible to connect to a <i>.shp</i> file by itself.
+The SHP provider treats each <i>.shp</i> and associated <i>.dbf</i> file as a feature class with a single geometry property and
+optionally, with data attribute properties.
+
+The four files can be accessed by applications other than the
+provider. In addition the provider may create two files that
+are used by the provider and not by other applications: an <i>.idx</i> file containing a spatial index and an .xml configuration
+file containing a mapping of the SHP data in the <i>.shp</i> file and the DBF data in the <i>.dbf</i> file to feature
+classes and properties in the FDO data model.
+
+The connection string used as an argument to the
+`TestConnection()` method references a folder in the file
+system. As part of installing the feature source in the
+repository, the shapefiles (<i>.shp</i>, <i>.shx</i>, <i>.dbf</i>,
+and <i>.prj</i> files) are loaded into the repository. The
+value of the DefaultFileLocation element as specified in the
+feature source XML file is a symbolic reference to the
+location of the shapefiles in the repository.
+
+Example Connection String
+
+```
+DefaultFileLocation=C:/SHPFeatureResources;TemporaryFileLocation=C:/SHPFeatureResources
+```
+
+Feature Source XML File
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<FeatureSource version="1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance " xsi:noNamespaceSchemaLocation="FeatureSource-1.0.0.xsd">
+ <Provider>Autodesk.Shp.1.0</Provider>
+ <ConnectionProperties>
+ <ConnectionProperty>
+ <Name>DefaultFileLocation</Name>
+ <Value>%MG_DATA_FILE_PATH%</Value>
+ </ConnectionProperty>
+ <ConnectionProperty>
+ <Name>TemporaryFileLocation</Name>
+ </ConnectionProperty>
+ </ConnectionProperties>
+ <SpatialContext/>
+ <LongTransaction/>
+</FeatureSource>
+```
+
+### Autodesk.RFP.1.0 Provider
+
+Example Connection String
+
+```
+DefaultRasterFileLocation=C:/RasterFeatureResources
+```
+
+Feature Source XML File
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<FeatureSource version="1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance " xsi:noNamespaceSchemaLocation="FeatureSource-1.0.0.xsd">
+ <Provider>Autodesk.RFP.1.0</Provider>
+ <ConnectionProperties>
+ <ConnectionProperty>
+ <Name>DefaultRasterFileLocation</Name>
+ <Value>%MG_DATA_FILE_PATH%</Value>
+ </ConnectionProperty>
+ </ConnectionProperties>
+ <SpatialContext/>
+ <LongTransaction/>
+</FeatureSource>
+```
+
+### Autodesk.ODBC.1.0 Provider
+
+Typically you use this provider is to access text-based
+feature source files.
+
+The essential first step is to use a Windows OS
+administrative tool to define a data source name. This action
+associates a symbolic name with a file path. You then use the
+symbolic name in the connection string and XML feature source
+file.
+
+On an XP computer, the path to the ODBC Data Source
+Administrator is Start > Settings > Control Panel >
+Administrative Tools > Data Sources (ODBC). You can create a
+User DSN (Data Source Name), a System DSN or File DSN in the
+ODBC Data Source Administrator dialog box.
+
+The sequence of clicks or data entry to create a User or
+System DSN for a Microsoft Access <i>.mdb</i> file is System
+DSN or User DSN/Add > Create New Data Source/Microsoft
+Access Driver (<i>*.mdb</i>) > Finish > ODBC Microsoft
+Access Setup/<type name> > Select > Select
+Database/<select folder> > <select file> > OK > ODBC
+Microsoft Access Setup/OK. The name that you enter is the DSN
+name and is used in the connection string and the XML feature
+source file.
+
+The sequence of clicks or data entry to create a User or
+System DSN for a dBase <i>.dbf</i> file is System DNS or User
+DSN/Add > Create New Data Source/Microsoft dBase Driver (<i>*.dbf</i>)
+> Finish > ODBC dBase Setup/<type name> > Save > Create
+New Data Source/Next > Finish > Select Directory> Select
+Database/<select folder> > <select file> > OK > ODBC
+dBase Setup/OK. If "Select Directory" is unavailable, clear
+"Use Current Directory". The name that you enter is the DSN
+name and is used in the connection string and XML feature
+source file.
+
+The sequence of clicks or data entry to create a File DSN for
+a Microsoft Access <i>.mdb</i> file is File DSN/Add > Create
+New Data Source/Microsoft Access Driver (<i>*.mdb</i>) >
+Next> Browse > Save As/<pick folder> > <type filename>
+Finish > ODBC Microsoft Access Setup/Select > Select
+Database/<select folder> > <select file> > OK > ODBC
+Microsoft Access Setup/OK. The filename that you enter will
+be given an extension of <i>.dsn</i>.
+
+Example Connection String
+
+```
+DataSourceName=Country
+```
+
+Feature Source XML File
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<FeatureSource version="1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance " xsi:noNamespaceSchemaLocation="FeatureSource-1.0.0.xsd">
+ <Provider>Autodesk.ODBC.1.0</Provider>
+ <ConnectionProperties>
+ <ConnectionProperty>
+ <Name>DataSourceName</Name>
+ <Value>Country</Value>
+ </ConnectionProperty>
+ <ConnectionProperty>
+ <Name>UserId</Name>
+ </ConnectionProperty>
+ <ConnectionProperty>
+ <Name>Password</Name>
+ </ConnectionProperty>
+ </ConnectionProperties>
+ <Configuration/>
+ <SpatialContext/>
+ <LongTransaction/>
+</FeatureSource>
+```
+
+ResourceDocumentHeader XML File
+
+```XML
+<?xml version="1.0" encoding="UTF-8"?>
+<ResourceDocumentHeader xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance " xsi:noNamespaceSchemaLocation="ResourceDocumentHeader-1.0.0.xsd">
+ <Security>
+ <Inherited>true</Inherited>
+ </Security>
+</ResourceDocumentHeader>
+```
+
+## Examples
+
+The code samples here how to add feature sources to the
+repository. You connect to a feature source in the
+repository. For example code showing how to connect to a
+feature source, see `MgFeatureService::TestConnection`.
+
+The first example adds a resource to the repository for a
+connection to an FDO Provider for Oracle. Since the
+connection is to a relational database and not a file, you
+need only call `MgResourceService::SetResource` passing in the
+FeatureSource XML containing the property values for the
+connection to the provider.
+
+PHP code
+
+```PHP
+<?php
+// creating the resource in the repository for a
+// connection to an FDO Provider for Oracle
+// first arg to $resourceService->SetResource()
+$featSrcResIdArg = "Library://FeatureService/testOracle.FeatureSource";
+$featSrcResId = new MgResourceIdentifier($featSrcResIdArg);
+
+// second arg to $resourceService->SetResource()
+$featSrcFileByteContent = new MgByteSource($pathToFeatSrcFile);
+$featSrcFileReaderContent = $featSrcFileByteContent->GetReader();
+
+// third arg to $resourceService->SetResource()
+$headerPathByteContent = new MgByteSource($headerPath);
+$headerPathReaderContent = $headerPathByteContent->GetReader();
+
+// add the resource to the repository
+$resourceService->SetResource($featSrcResId, $featSrcFileReaderContent, $headerPathReaderContent);
+?>
+\endcode
+\htmlinclude ExampleBottom.html
+\htmlinclude PHPExampleTop.html
+The second example adds a resource to the repository for a
+connection to an FDO Provider for SDF. Since the connection
+is to a file, you must call MgResourceService::SetResource
+passing in the FeatureSource XML containing the property
+values for the connection to the SDF file, and you must call
+MgResourceService::SetResourceData passing in the contents of
+the SDF file.
+\code
+<?php
+// creating the resource in the repository for a
+// connection to an FDO Provider for SDF
+// first arg to $resourceService->SetResource()
+$featSrcResIdArg = "Library://FeatureService/testSDF.FeatureSource";
+$featSrcResId = new MgResourceIdentifier($featSrcResIdArg);
+
+// second arg to $resourceService->SetResource()
+$featSrcFileByteContent = new MgByteSource($pathToFeatSrcFile);
+$featSrcFileReaderContent = $featSrcFileByteContent->GetReader();
+
+// third arg to $resourceService->SetResource()
+$headerPathByteContent = new MgByteSource($headerPath);
+$headerPathReaderContent = $headerPathByteContent->GetReader();
+
+// add the resource to the repository
+$resourceService->SetResource($featSrcResId, $featSrcFileReaderContent, $headerPathReaderContent);
+
+// add the contents of the SDF file to the repository
+$fileByteContent = new MgByteSource($pathToDataFile);
+$fileReader = $fileByteContent->GetReader();
+$resourceService->SetResourceData($featSrcResId, $fileName, "File", $fileReader);
+?>
+```
+
+C# code
+
+```C#
+using OSGeo.MapGuide;
+using OSGeo.MapGuide.Schema.FeatureSource;
+// The MgResourceService example code shows the creation of an instance.
+private MgResourceService resourceService;
+
+public void ConnectToSdfFeatureClassFile(MgResourceIdentifier resourceId,
+ Boolean readOnly, String filename, String SDFProviderName)
+{
+ FileInfo info = new FileInfo(fileName);
+
+ // Check if the specified file exists
+ if (!info.Exists)
+ {
+ throw new FileNotFoundException(
+ string.Format("The specified file {1} doesn't exist.", info.FullName));
+ }
+
+ // an xml string containing values for the two SDF connection parameters: File and ReadOnly
+ String featureSourceDefinition;
+
+ // Build the feature source object model
+ FeatureSourceType fsType = new FeatureSourceType();
+
+ fsType.Provider = SDFProviderName; // FDO provider name, case sensitive
+
+ NameValuePairType p1 = new NameValuePairType();
+ p1.Name = "ReadOnly";
+ p1.Value = readOnly.ToString(); // non case sensitive
+ NameValuePairType p2 = new NameValuePairType();
+ p2.Name = "File";
+ p2.Value = info.FullName; // Either double backslash or single backslash is OK for the file path
+
+ fsType.Parameter = new NameValuePairType[] { p2, p1 };
+
+ // Serialize the feature source object model to xml string
+ using (StringWriter writer = new StringWriter())
+ {
+ XmlSerializer xs = new XmlSerializer(fsType.GetType());
+ xs.Serialize(writer, fsType);
+ featureSourceDefinition = writer.ToString();
+ }
+
+ // Add the resource to repository
+ byte[] bytes = Utilities.StringToBytes(featureSourceDefinition);
+ MgByteSource source = new MgByteSource(bytes, bytes.Length);
+ resourceService.SetResource(resourceId, source.GetReader(), null);
+}
+```
\ No newline at end of file
Added: branches/4.0/MgDev/Doc/landing/topics/feature-filters.md.tpl
===================================================================
--- branches/4.0/MgDev/Doc/landing/topics/feature-filters.md.tpl (rev 0)
+++ branches/4.0/MgDev/Doc/landing/topics/feature-filters.md.tpl 2023-11-10 20:21:36 UTC (rev 10068)
@@ -0,0 +1,794 @@
+# Filters and Expressions
+
+Use a filter to select a subset of the features in a
+datastore. Filters are used in calls to
+`MgFeatureService::SelectFeatures()` and
+`MgFeatureService::SelectAggregate()`. There are two types of
+filters: basic and spatial.
+
+## Spatial Filter
+
+A spatial filter relates two geometries by way of a spatial
+operator. A spatial filter is set by a call to
+`MgFeatureQueryOptions::SetSpatialFilter()` or
+`MgFeatureAggregateOptions::SetSpatialFilter()`. These methods
+take 3 arguments: a name which identifies a geometry property
+of a feature in a datastore, a geometry object, and a
+spatial operation identifier. The effect of the filter is to
+select features from the datastore whose geometry property is
+related according to the spatial operator to the geometry
+object argument. For example, if the spatial operator is
+MgFeatureSpatialOperations::Within, and the geometry object's
+WKT representation is `POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))`,
+then the effect of the filter is to select those features
+which have geometries within this polygon.
+
+## Basic Filter
+
+ Use non-geometry feature property names, data values, and
+operators to construct a filter string which is passed as an
+argument to the `MgFeatureQueryOption::SetFilter()` or
+`MgFeatureAggregateOptions::SetFilter()` method. For example,
+if FEATID is a feature property name, then the filter "FEATID > 20" selects the features whose FEATID has a value greater
+than 20.
+
+## Expressions
+
+Expressions are subcomponents of a basic filter. One
+expression might constitute the entire filter, or several
+expressions can be strung together using operators.
+
+## Basic Filter Grammar
+
+```
+<Filter> ::= '(' Filter ')'
+| <LogicalOperator>
+| <SearchCondition>
+<LogicalOperator> ::= <BinaryLogicalOperator>
+| <UnaryLogicalOperator>
+
+<BinaryLogicalOperator> ::=
+
+<Filter> <BinaryLogicalOperations> <Filter>
+
+<SearchCondition> ::= <InCondition>
+| <ComparisonCondition>
+| <GeometricCondition>
+| <NullCondition>
+
+<InCondition> ::= <Identifier> IN '('
+ValueExpressionCollection ')'
+
+<ValueExpressionCollection> ::= <ValueExpression>
+| <ValueExpressionCollection> ',' <ValueExpression>
+
+<ComparisonCondition> ::=
+
+<Expression> <ComparisonOperations> <Expression>
+
+<GeometricCondition> ::= <SpatialCondition> |
+<DistanceCondition>
+
+<NullCondition> ::= <Identifier> NULL
+
+<SpatialCondition> ::= <Identifier> <SpatialOperations>
+<Expression>
+
+<DistanceCondition> ::= <Identifier> <DistanceOperations>
+<Expression> <distance>
+
+<UnaryLogicalOperator> ::= NOT <Filter>
+
+<BinaryLogicalOperations> ::= AND | OR
+
+<ComparisionOperations> ::= =
+| <>
+| >
+| >=
+| <
+| <=
+| LIKE
+
+<SpatialOperations> ::= CONTAINS | CROSSES | DISJOINT |
+EQUALS | INTERSECTS | OVERLAPS | TOUCHES | WITHIN | COVEREDBY
+| INSIDE
+
+<DistanceOperations> ::= BEYOND | WITHINDISTANCE
+
+<distance> ::= BEYOND | WITHINDISTANCE
+```
+
+## Expression Grammar
+
+```
+<Expression> ::= '(' Expression ')'
+| <UnaryExpression>
+| <BinaryExpression>
+| <Function>
+| <Identifier>
+| <ValueExpression>
+
+<BinaryExpression> ::= <Expression> '+' <Expression>
+| <Expression> '-' <Expression>
+| <Expression> '*' <Expression>
+| <Expression> '/' <Expression>
+
+<ValueExpression> ::= <LiteralValue>
+
+<LiteralValue> ::= <GeometryValue> | <DataValue>
+
+<GeometryValue> ::= GEOMFROMTEXT '(' STRING ')'
+
+<DataValue> ::= TRUE
+| FALSE
+| DATETIME
+| DOUBLE
+| INTEGER
+| STRING
+| BLOB
+| CLOB
+| NULL
+
+<Function> ::= <Identifier> '(' <ExpressionCollection>
+')'
+
+<ExpressionCollection> ::=
+| <Expression>
+| <ExpressionCollection> ',' <Expression>
+
+<Identifier> ::= IDENTIFIER
+
+<UnaryExpression> ::= '-' <Expression>
+```
+
+## Operator Precedence
+
+The operator precedence from highest to lowest is:
+
+Negate NOT
+Multiply Divide
+Add Subtract
+= <> > >= < <=
+AND
+OR
+
+## Filter and Expression Keywords
+
+The following case-insensitive keywords are reserved in the
+language. That is, they cannot be used as identifier or
+function names:
+
+```
+AND BEYOND COMPARE CONTAINS COVEREDBY CROSSES DATA DISJOINT
+DISTANCE EQUALS FALSE GEOMFROMTEXT IN INSIDE INTERSECTS LIKE
+NOT NULL OR OVERLAPS RELATE SPATIAL TIME TIMESTAMP TOUCHES
+TRUE WITHIN WITHINDISTANCE
+```
+
+## STRING
+
+Strings are literal constants enclosed in single quotes. If
+you need to include a single quote character inside a string,
+you can double the character, for example, 'aaa''bbb'.
+
+## IDENTIFIER
+
+An identifier can be any alphanumeric sequence of characters
+other than a keyword. Identifiers can be enclosed in double
+quotes to show special characters and white space. If you
+need to include a double quote character inside an
+identifier, you can double the character, for example
+"abc""def".
+
+## INTEGER
+Integers allow only decimal characters with an optional unary
+minus sign. Unary plus is not supported. If an integer is out
+of the 32-bit precision range, it is converted to floating
+point.
+
+## DOUBLE
+Floating point numbers have a decimal point, can be signed
+(-), and include an optional exponent (e{[0-9]}).
+
+## DATETIME
+
+Date and time are parsed using the standard literal strings:
+
+`DATE 'YYYY-MM-DD'`
+`TIME 'HH:MM:SS[.sss]'`
+`TIMESTAMP 'YYYY-MM-DD HH:MM:SS[.sss]'`
+
+## CLOB/BLOB
+
+These data types are not currently supported. If you need to
+support binary input, use parameters.
+
+## `<Function>`
+
+Some functions such as ceil, floor, concat, lower, and upper
+take as an argument the value of a property from a single
+feature and return a value related to the property value.
+
+Some functions such as avg, count, max, min, stddev, and sum
+take as an argument the values of a property from multiple
+features and return a single value related to the values of
+the group of property arguments.
+
+<TABLE class="RuledTable">
+ <tr>
+ <th>Function</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>Double Avg(n)</td>
+ <td>Average value of n, ignoring nulls</td>
+ </tr>
+ <tr>
+ <td>Int64 Ceil(Double)</td>
+ <td>Smallest integer >= Double</td>
+ </tr>
+ <tr>
+ <td>String Concat(Str1, Str2)</td>
+ <td>Concatenates Str1 and Str2</td>
+ </tr>
+ <tr>
+ <td>Int64 Count(expression)</td>
+ <td>Number of features where expression is not null</td>
+ </tr>
+ <tr>
+ <td>Int64 Floor(Double)</td>
+ <td>Largest integer <= Double</td>
+ </tr>
+ <tr>
+ <td>String Lower(Str)</td>
+ <td>Str with all lowercase letters</td>
+ </tr>
+ <tr>
+ <td>Double Min(expression)</td>
+ <td>Minimum value of expression</td>
+ </tr>
+ <tr>
+ <td>Double Max(expression)</td>
+ <td>Maximum value of expression</td>
+ </tr>
+ <tr>
+ <td>Double Stddev(n)</td>
+ <td>Standard deviation of n, ignoring nulls</td>
+ </tr>
+ <tr>
+ <td>Double Sum(n)</td>
+ <td>Sum of values of n</td>
+ </tr>
+ <tr>
+ <td>String Upper(Str)</td>
+ <td>Str with all uppercase letters</td>
+ </tr>
+</TABLE>
+
+## Examples
+
+PHP and C# sample code for the setting of filters for select operations is
+presented. The SQL expression equivalent to the PHP and C# code is also
+presented.
+
+PHP Code
+
+```PHP
+<?php
+$queryOptions = new MgFeatureQueryOptions();
+$stringCollection = new MgStringCollection();
+$wktReaderWriter = new MgWktReaderWriter();
+?>
+```
+
+C# code
+
+```C#
+using OSGeo.MapGuide;
+private MgFeatureQueryOptions queryOptions;
+private MgStringCollection stringCollection;
+private MgWktReaderWriter wktReaderWriter;
+private String featClassName = "SdfFeatureClass";
+private MgResourceIdentifier featureSrcResourceId;
+private MgFeatureService featureService;
+
+stringCollection = new MgStringCollection();
+queryOptions = new MgFeatureQueryOptions();
+// the feature source has already been installed in the repository
+featureSrcResourceId = new MgResourceIdentifier("Library://PlatformApiDocTests/SdfFeatureClass.FeatureSource");
+wktReaderWriter = new MgWktReaderWriter();
+```
+
+
+### `<Identifier> NULL`
+
+SometimesNULL is a string property. If you have not given a
+value to it when inserting certain features and you apply
+the filter, sometimesNULL NULL, you select those
+features. If you have given a value to it when inserting other
+features and you apply the filter, NOT sometimesNULL
+NULL, you select those other features.
+
+```
+sqlplus> select sometimesnull from featclass where sometimesnull is null;
+```
+
+PHP code
+
+```PHP
+<?php
+$queryOptions->AddFeatureProperty("sometimesNULL");
+$queryOptions->SetFilter("sometimesNULL NULL");
+$featureReader = $featureService->SelectFeatures($featureSrcResourceId, $featClassName, $queryOptions);
+# process $featureReader
+$featureReader->Close();
+?>
+```
+
+C# code
+
+```C#
+queryOptions.AddFeatureProperty("SometimesNull");
+queryOptions.SetFilter("SometimesNull NULL");
+featureReader = featureService.SelectFeatures(featureSrcResourceId, featClassName, queryOptions);
+// process featureReader
+featureReader.Close();
+```
+
+```
+sqlplus> select sometimesnull from featclass where sometimesnull is not null;
+```
+
+PHP code
+
+```PHP
+<?php
+$queryOptions->AddFeatureProperty("sometimesNULL");
+$queryOptions->SetFilter("NOT sometimesNULL NULL");
+$featureReader = $featureService->SelectFeatures($featureSrcResourceId, $featClassName, $queryOptions);
+# process $featureReader
+$featureReader->Close();
+?>
+```
+
+C# code
+
+```C#
+queryOptions.AddFeatureProperty("SometimesNull");
+queryOptions.SetFilter("NOT SometimesNull NULL");
+featureReader = featureService.SelectFeatures(featureSrcResourceId, featClassName, queryOptions);
+// process featureReader
+featureReader.Close();
+```
+
+### `<Identifier> LIKE <String>`
+
+Identifier is the name of a property whose type is
+MgPropertyType::String. String contains a pattern. A percent
+character (%) in a pattern matches zero or more characters.
+An underscore character (_) matches one character.
+
+Description is a string property. There are 2 features with
+this property in the datastore, and the contents of the two
+properties are: "POINT XY (1 1)" and "POLYGON XY ((0 0, 2 0, 2 2, 0 2, 0 0))".
+
+The filter, Description LIKE '%POLYGON%', returns
+"POLYGON XY ((0 0, 2 0, 2 2, 0 2, 0 0))", the filter,
+NOT Description LIKE '%POLYGON%', returns
+"POINT XY (1 1)", and the filter, Description LIKE
+'%POL_GON%', returns "POLYGON XY ((0 0, 2 0, 2 2, 0
+2, 0 0))".
+
+```
+sqlplus> select Description from featclass where Description LIKE '%POLYGON%';
+```
+
+PHP code
+
+```PHP
+$queryOptions->AddFeatureProperty("Description");
+$queryOptions->SetFilter("Description LIKE '%POLYGON%'");
+$featureReader = $featureService->SelectFeatures($featureSrcResourceId, $featClassName, $queryOptions);
+# process $featureReader
+$featureReader->Close();
+```
+
+C# code
+
+```C#
+queryOptions.AddFeatureProperty("Description");
+queryOptions.SetFilter("Description LIKE '%POLYGON%'");
+featureReader = featureService.SelectFeatures(featureSrcResourceId, featClassName, queryOptions);
+// process featureReader
+featureReader.Close();
+```
+
+```
+sqlplus> select Description from featclass where Description NOT LIKE '%POLYGON%';
+```
+
+PHP code
+
+```PHP
+$queryOptions->AddFeatureProperty("Description");
+$queryOptions->SetFilter("NOT Description LIKE '%POLYGON%'");
+$featureReader = $featureService->SelectFeatures($featureSrcResourceId, $featClassName, $queryOptions);
+# process $featureReader
+$featureReader->Close();
+```
+
+C# code
+
+```C#
+queryOptions.AddFeatureProperty("Description");
+queryOptions.SetFilter("NOT Description LIKE '%POLYGON%'");
+featureReader = featureService.SelectFeatures(featureSrcResourceId, featClassName, queryOptions);
+// process featureReader
+featureReader.Close();
+```
+
+```
+sqlplus> select Description from featclass where Description LIKE '%POL_GON%';
+```
+
+PHP code
+
+```PHP
+$queryOptions->AddFeatureProperty("Description");
+$queryOptions->SetFilter("Description LIKE '%POL_GON%'");
+$featureReader = $featureService->SelectFeatures($featureSrcResourceId, $featClassName, $queryOptions);
+# process $featureReader
+$featureReader->Close();
+```
+
+C# code
+
+```C#
+queryOptions.AddFeatureProperty("Description");
+queryOptions.SetFilter("Description LIKE '%POL_GON%'");
+featureReader = featureService.SelectFeatures(featureSrcResourceId, featClassName, queryOptions);
+// process featureReader
+featureReader.Close();
+```
+
+### `<Identifier> IN ( <ValueExpressionCollection> )`
+
+anInt16 is an Int16 property. In one feature instance the
+value of anInt16 is -7033. If you apply <filter>anInt16 IN
+( -5995, -7033 ), you select this feature.
+
+```
+sqlplus> select anInt16 from featclass where anInt16 in ( -5995, -7033 );
+```
+
+PHP code
+
+```PHP
+<?php
+$queryOptions->AddFeatureProperty("anInt16");
+$queryOptions->SetFilter("anInt16 IN ( -5995, -7033 )");
+$featureReader = $featureService->SelectFeatures($featureSrcResourceId, $featClassName, $queryOptions);
+# process $featureReader
+$featureReader->Close();
+?>
+```
+
+C# code
+
+```C#
+queryOptions.AddFeatureProperty("anInt16");
+queryOptions.SetFilter("anInt16 IN ( -5995, -7033 )");
+featureReader = featureService.SelectFeatures(featureSrcResourceId, featClassName, queryOptions);
+// process featureReader
+featureReader.Close();
+```
+
+### `<Identifier> > <DataValue>`
+
+featid is an identity property. If you apply the filter, featid
+> 20, you select the features whose featid has a
+value > 20. If you apply the filter, featid > 0 AND featid <
+5, you select the features whose featid belongs to
+{ 1, 2, 3, 4}. If you apply the filter, featid < 3 OR featid
+> 3, you select features whose featid is not 3.
+
+aDateTime is a date property. There is a feature whose
+aDateTime property has the value 9/20/2005::10:9:34:0. If you
+apply the filter, aDateTime < '2005-09-21', you
+select this feature.
+
+```
+sqlplus> select anInt16 from featclass where adatetime < '21-SEP-05';
+```
+
+PHP code
+
+```PHP
+<?php
+$queryOptions->AddFeatureProperty("anInt16");
+$queryOptions->SetFilter("aDateTime < '2005-09-21'");
+$featureReader = $featureService->SelectFeatures($featureSrcResourceId, $featClassName, $queryOptions);
+# process $featureReader
+$featureReader->Close();
+?>
+```
+
+C# code
+
+```C#
+queryOptions.AddFeatureProperty("anInt16");
+queryOptions.SetFilter("aDateTime < '2005-09-21'");
+featureReader = featureService.SelectFeatures(featureSrcResourceId, featClassName, queryOptions);
+// process featureReader
+featureReader.Close();
+```
+### `<Expression> < <DataValue>`
+
+anInt16 is an Int16 property. Two features have non-NULL
+values for this property. One has a value -7033, and the
+other -5995. If you apply the filter, ( anInt16 + 1000 ) <
+-5995, you select the feature whose anInt16
+property has the value -7033. The parentheses in this filter
+are optional because operator precedence would dictate that
+the filter, anInt16 + 1000 < -5995, is equivalent.
+
+```
+sqlplus> select anInt16 from featclass where anInt16 + 1000 < -5995;
+```
+
+PHP code
+
+```PHP
+<?php
+$queryOptions->AddFeatureProperty("anInt16");
+$queryOptions->SetFilter("anInt16 + 1000 < -5995");
+$featureReader = $featureService->SelectFeatures($featureSrcResourceId, $featClassName, $queryOptions);
+# process $featureReader
+$featureReader->Close();
+?>
+```
+
+C# code
+
+```C#
+queryOptions.AddFeatureProperty("anInt16");
+queryOptions.SetFilter("anInt16 + 1000 < -5995");
+featureReader = featureService.SelectFeatures(featureSrcResourceId, featClassName, queryOptions);
+// process featureReader
+featureReader.Close();
+```
+### `<FunctionValue> = <DataValue>`
+
+aDouble is a double property. One feature has aDouble
+property with a value of 8103.08393. If you apply
+the filter, ceil(aDouble) = 8104, you select this
+feature.
+
+```
+sqlplus> select aDouble from featclass where ceil(aDouble) = 8104;
+```
+
+PHP code
+
+```PHP
+<?php
+$queryOptions->AddFeatureProperty("aDouble");
+$queryOptions->SetFilter("ceil(aDouble) = 8104");
+$featureReader = $featureService->SelectFeatures($featureSrcResourceId, $featClassName, $queryOptions);
+# process $featureReader
+$featureReader->Close();
+?>
+```
+
+C# code
+
+```C#
+queryOptions.AddFeatureProperty("aDouble");
+queryOptions.SetFilter("ceil(aDouble) = 8104");
+featureReader = featureService.SelectFeatures(featureSrcResourceId, featClassName, queryOptions);
+// process featureReader
+featureReader.Close();
+```
+
+### Group Function
+
+aDouble is a double property. sum is a group function.
+sum(aDouble) sums the values of the aDouble property taken
+from a group of features.
+
+```
+sqlplus> select sum(aDouble) from featclass;
+```
+
+PHP code
+
+```php
+<?php
+$queryOptions->AddComputedProperty("sumDbl", "sum(aDouble)");
+$featureReader = $featureService->SelectFeatures($featureSrcResourceId, $featClassName, $queryOptions);
+# process $featureReader
+$featureReader->Close();
+?>
+```
+
+C# code
+
+```C#
+queryOptions.AddComputedProperty("sumDbl", "sum(aDouble)");
+featureReader = featureService.SelectFeatures(featureSrcResourceId, featClassName, queryOptions);
+// process featureReader
+featureReader.Close();
+```
+
+### Ordering
+
+aDouble is a double property. anInt32Key is the identity
+property. The first example returns aDouble values in
+ascending order, and the second example returns them in
+descending order.
+
+#### Ascending
+
+```
+sqlplus> select anint32key,adouble from tuxuniversalclassxy order by adouble ASC;
+```
+
+PHP code
+
+```PHP
+<?php
+$queryOptions->AddFeatureProperty("aDouble");
+$queryOptions->AddFeatureProperty("anInt32Key");
+$stringCollection->Add("aDouble");
+$queryOptions->SetOrderingFilter($stringCollection, MgOrderingOption::Ascending);
+$featureReader = $featureService->SelectFeatures($featureSrcResourceId, $featClassName, $queryOptions);
+# process $featureReader
+$featureReader->Close();
+?>
+```
+
+C# code
+
+```C#
+queryOptions.AddFeatureProperty("aDouble");
+queryOptions.AddFeatureProperty("anInt32Key");
+stringCollection.Add("aDouble");
+queryOptions.SetOrderingFilter(stringCollection, MgOrderingOption::Ascending);
+featureReader = $featureService.SelectFeatures(featureSrcResourceId, featClassName, queryOptions);
+// process $featureReader
+featureReader.Close();
+```
+
+#### Descending
+
+```
+sqlplus> select anint32key,adouble from tuxuniversalclassxy order by adouble DESC;
+```
+
+PHP code
+
+```PHP
+<?php
+$queryOptions->AddFeatureProperty("aDouble");
+$queryOptions->AddFeatureProperty("anInt32Key");
+$stringCollection->Add("aDouble");
+$queryOptions->SetOrderingFilter($stringCollection, MgOrderingOption::Descending);
+$featureReader = $featureService->SelectFeatures($featureSrcResourceId, $featClassName, $queryOptions);
+# process $featureReader
+$featureReader->Close();
+?>
+```
+
+C# code
+
+```C#
+queryOptions.AddFeatureProperty("aDouble");
+queryOptions.AddFeatureProperty("anInt32Key");
+stringCollection.Add("aDouble");
+queryOptions.SetOrderingFilter(stringCollection, MgOrderingOption::Descending);
+featureReader = featureService.SelectFeatures(featureSrcResourceId, featClassName, queryOptions);
+// process $featureReader
+featureReader.Close();
+```
+
+### Basic Filter OR Spatial Filter
+
+featId is an identity property, and geometry is a geometry
+property. The feature whose featId value is 0 has a geometry
+value of POINT(1 1). The feature whose featid value is 1 has
+a null geometry value. The spatial filter requests features
+whose geometry intersects with POINT(1 1). The following
+select operation returns both of these features. The
+operation can be coded in two ways. The first way uses the
+SetFilter(), SetSpatialFilter() and SetBinaryOperator()
+methods, and the second way uses only the SetFilter() method.
+
+```
+sqlplus> select a.featId from featclass a where a.featId = 1 or sdo_relate(a.geometry, MDSYS.SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(1,1,NULL), NULL, NULL), 'mask=anyinteract') = 'TRUE';
+```
+
+PHP code
+
+```PHP
+<?php
+$queryOptions->AddFeatureProperty("featId");
+$queryOptions->SetFilter("featId = 1");
+$queryOptions->SetBinaryOperator(false);
+$geometry = $wktReaderWriter->Read("POINT(1 1)");
+$queryOptions->SetSpatialFilter("geometry", $geometry, MgFeatureSpatialOperations::Intersects);
+$featureReader = $featureService->SelectFeatures($featureSrcResourceId, $featClassName, $queryOptions);
+# process $featureReader
+$featureReader->Close();
+?>
+```
+
+C# code
+
+```C#
+queryOptions.AddFeatureProperty("featId");
+queryOptions.SetFilter("featId = 1");
+queryOptions.SetBinaryOperator(false);
+geometry = wktReaderWriter.Read("POINT(1 1)");
+queryOptions.SetSpatialFilter("geometry", geometry, MgFeatureSpatialOperations::Intersects);
+featureReader = featureService.SelectFeatures(featureSrcResourceId, featClassName, queryOptions);
+// process $featureReader
+featureReader.Close();
+```
+
+PHP code
+
+```PHP
+<?php
+$queryOptions->AddFeatureProperty("featId");
+$queryOptions->SetFilter("(featId = 1) OR (geometry INTERSECTS GEOMFROMTEXT ( 'POINT(1 1)' )");
+$featureReader = $featureService->SelectFeatures($featureSrcResourceId, $featClassName, $queryOptions);
+# process $featureReader
+$featureReader->Close();
+?>
+```
+
+C# code
+
+```C#
+queryOptions.AddFeatureProperty("featId");
+geometry = wktReaderWriter.Read("POINT(1 1)");
+queryOptions.SetFilter("(featId = 1) OR (geometry INTERSECTS GEOMFROMTEXT ( 'POINT(1 1)' )");
+featureReader = featureService.SelectFeatures(featureSrcResourceId, featClassName, queryOptions);
+// process $featureReader
+featureReader.Close();
+```
+
+### Distance Filter
+
+featId is an identity property, and geometry is a geometry
+property. The feature whose featId value is 0 has a geometry
+value of POINT(1 1). The distance filter requests features
+whose geometry is within a distance of 1 from POINT(2 1). The
+following select operation returns the feature whose featId
+is 0.
+
+```
+sqlplus> select a.featId from featclass a where sdo_within_distance(a.geometry, MDSYS SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(2,1 NULL), NULL, NULL), 'distance=1') = 'TRUE';
+```
+
+PHP code
+
+```PHP
+<?php
+$queryOptions->AddFeatureProperty("featId");
+$queryOptions->SetFilter("geometry WITHINDISTANCE GEOMFROMTEXT ('POINT(2 1)') 1");
+$featureReader = $featureService->SelectFeatures($featureSrcResourceId, $featClassName, $queryOptions);
+# process $featureReader
+$featureReader->Close();
+?>
+```
+
+C# code
+
+``` C#
+queryOptions.AddFeatureProperty("featId");
+queryOptions.SetFilter("geometry WITHINDISTANCE GEOMFROMTEXT ('POINT(2 1)') 1");
+featureReader = featureService.SelectFeatures(featureSrcResourceId, featClassName, queryOptions);
+// process $featureReader
+featureReader.Close();
+```
Added: branches/4.0/MgDev/Doc/landing/topics/feature-intro.md.tpl
===================================================================
--- branches/4.0/MgDev/Doc/landing/topics/feature-intro.md.tpl (rev 0)
+++ branches/4.0/MgDev/Doc/landing/topics/feature-intro.md.tpl 2023-11-10 20:21:36 UTC (rev 10068)
@@ -0,0 +1,35 @@
+# Feature Service
+
+The Feature Service provides an abstraction layer for the
+storage and retrieval of feature data in a
+technology-independent way. You can use the API to determine
+which storage technologies are available and which
+capabilities they have. Access to the storage technology is
+modeled as a connection. For example, you can connect to a
+file and do simple insertions or connect to a relational
+database and do transaction-based operations.
+
+The root methods are contained in the `MgFeatureService` [!doclinkclass MgFeatureService] class.
+
+In general, you may do any of the following, subject to
+ provider capability limitations:
+ * Determine which storage technologies are available (see
+ `MgFeatureService::GetFeatureProviders()`),
+ * Determine which capabilities a feature provider has (see
+ `MgFeatureService::GetCapabilities()`),
+ * Verify the connection property values (see
+ `MgFeatureService::GetConnectionPropertyValues()`),
+ * Connect to a storage technology (feature provider) using
+ `MgFeatureService::TestConnection()`
+ * Describe the structure of feature data using ``MgFeatureService::DescribeSchema()`
+ * Determine the spatial contexts available in the datastore
+ (see `MgFeatureService::GetSpatialContexts()`),
+ * Insert feature data (see `MgInsertFeatures` [!doclinkclass MgInsertFeatures]),
+ * Select feature data (see
+ MgFeatureService::SelectFeatures() and
+ MgFeatureService::SelectAggregate()),
+ * Update feature data (see `MgUpdateFeatures` [!doclinkclass MgUpdateFeatures]),
+ * Delete feature data (see `MgDeleteFeatures` [!doclinkclass MgDeleteFeatures]),
+ * Execute SQL commands (see
+ `MgFeatureService::ExecuteSqlQuery()` and
+ `MgFeatureService::ExecuteSqlNonQuery()`).
Added: branches/4.0/MgDev/Doc/landing/topics/feature-provider-registry.md.tpl
===================================================================
--- branches/4.0/MgDev/Doc/landing/topics/feature-provider-registry.md.tpl (rev 0)
+++ branches/4.0/MgDev/Doc/landing/topics/feature-provider-registry.md.tpl 2023-11-10 20:21:36 UTC (rev 10068)
@@ -0,0 +1,122 @@
+# Feature Provider Registry
+
+The feature provider registry contains most importantly the
+name of each available provider, version information and the name of the provider DLL.
+The full set of registry information elements and attributes is specified
+in the XML schema [FeatureProviderRegistry](xmlschema-featureproviderregistry.md).
+
+The FeatureProviders constructor takes the XML string
+containing the provider registry as an argument. It creates
+an array of FeatureProvider objects. Currently it only parses
+the Name elements from the registry information.
+
+PHP code
+
+```PHP
+<?php
+class FeatureProviders {
+ var $xpath;
+ var $featureProviders;
+ var $logFileHandle;
+ function arrayOfProviderNames() {
+ return array_keys($this->featureProviders);
+ }
+ function FeatureProviders( $logFileHandle, $byteReader ) {
+ $this->logFileHandle = $logFileHandle;
+ $doc = new DOMDocument();
+ $xmlStr = $byteReader->ToString();
+ $doc->loadXML($xmlStr);
+ $this->xpath = new DOMXPath($doc);
+ $this->queryProviders();
+ }
+ function queryProviders() {
+ $providers = $this->xpath->query("//FeatureProviderRegistry/FeatureProvider");
+ $count = $providers->length;
+ for($i=0; $i<$count; $i++) {
+ $provider = $providers->item($i);
+ $providerElements = $provider->childNodes;
+ $connectionProperties = NULL;
+ foreach($providerElements as $providerElement) {
+ $providerElemTagname = $providerElement->tagName;
+ if ($providerElemTagname == "Name") {
+ $providerName = $providerElement->nodeValue;
+ $featureProvider = new FeatureProvider($providerName);
+ }
+ }
+ $this->featureProviders[$providerName] = $featureProvider;
+ }
+ }
+}
+class FeatureProvider {
+ var $providerName;
+ var $connectionProperties = NULL;
+ function FeatureProvider( $providerName ) {
+ $this->providerName = $providerName;
+ }
+ function GetProviderName() {
+ return $providerName;
+ }
+}
+?>
+```
+
+The GetProviderNames method gets the provider registry from Feature Services.
+The registry is in xml and the method uses an xpath expression to retrieve
+the provider names. It concatenates the provider names for use in a test expression.
+
+The following string is an example of the output from this program.
+
+```Autodesk.Oracle.3.2 Autodesk.Raster.3.2 Autodesk.SqlServer.3.2 OSGeo.ArcSDE.3.2 OSGeo.MySQL.3.2 OSGeo.ODBC.3.2 OSGeo.SDF.3.2 OSGeo.SHP.3.2 OSGeo.WFS.3.2 OSGeo.WMS.3.2```
+
+The utility method shows the use of System Xml classes to extract values
+from the xml.
+
+C# code
+
+```C#
+using OSGeo.MapGuide;
+// The MgFeatureService example code shows how the MgFeatureService object is created.
+private MgFeatureService featureService;
+private String providerNamesActual;
+
+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 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;
+}
+
+GetProviderNames();
+System.Console.WriteLine(providerNamesActual);
+```
Added: branches/4.0/MgDev/Doc/landing/topics/feature-provider.md.tpl
===================================================================
--- branches/4.0/MgDev/Doc/landing/topics/feature-provider.md.tpl (rev 0)
+++ branches/4.0/MgDev/Doc/landing/topics/feature-provider.md.tpl 2023-11-10 20:21:36 UTC (rev 10068)
@@ -0,0 +1,2186 @@
+# Feature Providers
+
+## 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:
+<ul>
+<li>Connection</li>
+<li>Schema</li>
+<li>Commands</li>
+<li>Expressions</li>
+<li>Filters</li>
+<li>Raster</li>
+<li>Topology</li>
+</ul>
+
+The MgFeatureService::GetCapabilities method returns an XML
+representation of a provider's capabilities. See \link FdoProviderCapabilities_schema FdoProviderCapabilities \endlink
+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.
+
+<ul>
+ <li>ConnectionCapabilities:ThreadCapability=PerConnectionThreaded;SpatialContextExtentType=Dynamic;</li>
+ <li>CommandCapabilities:Commands=+Select+Insert+Delete+Update+DescribeSchema+ApplySchema+CreateSpatialContext+GetSpatialContexts+SelectAggregates;SelectExpressions;SelectFunctions;SelectDistinct;</li>
+ <li>SchemaCapabilities:ClassType=+Class+FeatureClass;DataType=+Boolean+Byte+DateTime+Decimal+Double+Int16+Int32+Int64+Single+String;Inheritance;AssociationProperties;AutoIdGeneration;SupportedAutoGeneratedTypes=+Int32;SchemaModification;</li>
+ <li>GeometryCapabilities:GeometryTypes=+Point+LineString+Polygon+MultiPoint+MultiLineString+MultiPolygon+MultiGeometry+CurveString+CurvePolygon+MultiCurveString+MultiCurvePolygon;ComponentType=+LinearRing+ArcSegment+LinearSegment+CurveRing;Dimensionality=XYZM;</li>
+ <li>FilterCapabilities:ConditionType=+Comparison+Like+In+Null+Spatial;SpatialOperation=+Contains+Disjoint+Intersects+Within+Inside+EnvelopeIntersects;DistanceOperation=;</li>
+ <li>ExpressionCapabilities:ExpressionType=+Basic+Function;FunctionDefinitions=+Concat+SpatialExtents+Ceil+Floor+Lower+Upper+Sum+Count+Min+Avg+Max;</li>
+</ul>
+
+C# code
+
+```C#
+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:
+
+<ul>
+ <li>parses the XML returned by MgFeatureService::GetCapabilities()</li>
+ <li>implements a set of boolean capability functions</li>
+ <li>prints the values of the functions</li>
+</ul>
+
+
+```
+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:
+
+<ul>
+ <li>parses the XML returned by MgFeatureService::GetCapabilities()</li>
+ <li>implements a set of boolean capability functions</li>
+ <li>prints the values of the functions</li>
+</ul>
+
+The constructor takes a provider name, a file handle, and an
+MgByteReader containing the provider capabilities. The
+provider name is obtained from \link MgFeatureService::GetFeatureProviders MgFeatureService::GetFeatureProviders\endlink.
+The provider capabilities is obtained from
+\link MgFeatureService::GetCapabilities MgFeatureService::GetCapabilities\endlink.
+The file handle is for logging.
+
+PHP code
+
+```PHP
+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: unknown value: $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);
+ }
+}
+```
+
Added: branches/4.0/MgDev/Doc/landing/topics/feature-schema.md.tpl
===================================================================
--- branches/4.0/MgDev/Doc/landing/topics/feature-schema.md.tpl (rev 0)
+++ branches/4.0/MgDev/Doc/landing/topics/feature-schema.md.tpl 2023-11-10 20:21:36 UTC (rev 10068)
@@ -0,0 +1,154 @@
+# Feature Schema
+
+A feature schema is a class or set of classes that define the
+structure of data contained in a feature source (datastore),
+for example, an Oracle database. A feature class consists of
+a set of properties. Each property has a set of attributes
+appropriate to the type of information it contains. Class and
+property here correspond roughly to table and column in a
+relational database.
+
+The class and property definition classes have methods for
+both getting and setting attributes. In general, however, the
+set methods are of no use except in the case of the FDO
+Provider for SDF. `MgFeatureService::CreateFeatureSource`
+permits you to create an SDF schema, that is, an SDF file
+containing a schema. The intent is that this method be used
+as part of a mechanism for caching feature data locally.
+The schema used for this SDF cache file would typically be
+the schema extracted by `MgFeatureService::DescribeSchema`
+from the feature source whose features are being cached.
+It is possible to create a schema from scratch; see the sample code below.
+
+Five property types are distinguished, and there is a
+property definition class for each type. The five types are:
+
+ * Simple data. The MgDataPropertyDefinition [!doclinkclass MgDataPropertyDefinition] class is used
+to define the attributes of simple data properties. The
+simple data types are BLOB, boolean, byte, CLOB, MgDateTime,
+double, Int16, Int32, Int64, single, and string.
+ * Geometry data. The MgGeometricPropertyDefinition [!doclinkclass MgGeometricPropertyDefinition] class is
+used to define the attributes of geometry data. The geometry
+data type is MgGeometry.
+ * Association data. The MgAssociationPropertyDefinition [!doclinkclass MgAssociationPropertyDefinition]
+class is used to define the attributes of association
+properties. This is not currently used.
+ * Object data. The MgObjectPropertyDefinition [!doclinkclass MgObjectPropertyDefinition] class is used
+to define the attributes of object data. This allows us to
+model information using object composition. The type of
+object data is user-defined.
+ * Raster data. The MgRasterPropertyDefinition [!doclinkclass MgRasterPropertyDefinition] class is used
+to define the attributes of raster data. The type of raster
+data is MgRaster [!doclinkclass MgRaster].
+
+```C#
+using OSGeo.MapGuide;
+MgDataPropertyDefinition dataProperty;
+MgGeometricPropertyDefinition geometricProperty;
+MgClassDefinition classDef = new MgClassDefinition();
+
+className = "SdfFeatureClass";
+
+classDef.SetName(className);
+classDef.SetDefaultGeometryPropertyName("theFeatureGeometry");
+
+// feature geometry property that takes 2D XY geometries
+geometricProperty = new MgGeometricPropertyDefinition("theFeatureGeometry");
+geometricProperty.SetGeometryTypes(MgFeatureGeometricType.Point |
+ MgFeatureGeometricType.Curve | MgFeatureGeometricType.Surface);
+geometricProperty.SetHasElevation(false);
+geometricProperty.SetHasMeasure(false);
+geometricProperty.SetReadOnly(false);
+geometricProperty.SetSpatialContextAssociation(spatialContextName);
+classDef.GetProperties().Add(geometricProperty);
+
+// non-feature geometry
+geometricProperty = new MgGeometricPropertyDefinition("aNonFeatureGeometry");
+geometricProperty.SetGeometryTypes(MgFeatureGeometricType.Point |
+ MgFeatureGeometricType.Curve | MgFeatureGeometricType.Surface);
+geometricProperty.SetHasElevation(false);
+geometricProperty.SetHasMeasure(false);
+geometricProperty.SetReadOnly(false);
+geometricProperty.SetSpatialContextAssociation(spatialContextName);
+classDef.GetProperties().Add(geometricProperty);
+
+// identity property
+dataProperty = new MgDataPropertyDefinition("FeatId");
+dataProperty.SetDataType(MgPropertyType.Int32);
+dataProperty.SetAutoGeneration(false);
+dataProperty.SetNullable(false);
+dataProperty.SetReadOnly(true);
+classDef.GetIdentityProperties().Add(dataProperty);
+classDef.GetProperties().Add(dataProperty);
+
+// boolean property
+dataProperty = new MgDataPropertyDefinition("aBoolean");
+dataProperty.SetDataType(MgPropertyType.Boolean);
+dataProperty.SetNullable(true);
+dataProperty.SetReadOnly(false);
+classDef.GetProperties().Add(dataProperty);
+
+// byte property
+dataProperty = new MgDataPropertyDefinition("aByte");
+dataProperty.SetDataType(MgPropertyType.Byte);
+dataProperty.SetNullable(true);
+dataProperty.SetReadOnly(false);
+classDef.GetProperties().Add(dataProperty);
+
+// DataTime property
+dataProperty = new MgDataPropertyDefinition("aDateTime");
+dataProperty.SetDataType(MgPropertyType.DateTime);
+dataProperty.SetNullable(true);
+dataProperty.SetReadOnly(false);
+classDef.GetProperties().Add(dataProperty);
+
+// cannot create Decimal property because MgPropertyType.Decimal doesn't exist
+// even though SDF schema capabilities says that Decimal property is supported
+
+// double property
+dataProperty = new MgDataPropertyDefinition("aDouble");
+dataProperty.SetDataType(MgPropertyType.Double);
+dataProperty.SetNullable(true);
+dataProperty.SetReadOnly(false);
+classDef.GetProperties().Add(dataProperty);
+
+// Int16 property
+dataProperty = new MgDataPropertyDefinition("anInt16");
+dataProperty.SetDataType(MgPropertyType.Int16);
+dataProperty.SetNullable(true);
+dataProperty.SetReadOnly(false);
+classDef.GetProperties().Add(dataProperty);
+
+// Int32 property
+dataProperty = new MgDataPropertyDefinition("anInt32");
+dataProperty.SetDataType(MgPropertyType.Int32);
+dataProperty.SetNullable(true);
+dataProperty.SetReadOnly(false);
+classDef.GetProperties().Add(dataProperty);
+
+// Int64 property
+dataProperty = new MgDataPropertyDefinition("anInt64");
+dataProperty.SetDataType(MgPropertyType.Int64);
+dataProperty.SetNullable(true);
+dataProperty.SetReadOnly(false);
+classDef.GetProperties().Add(dataProperty);
+
+// Single property
+dataProperty = new MgDataPropertyDefinition("aSingle");
+dataProperty.SetDataType(MgPropertyType.Single);
+dataProperty.SetNullable(true);
+dataProperty.SetReadOnly(false);
+classDef.GetProperties().Add(dataProperty);
+
+// String property
+dataProperty = new MgDataPropertyDefinition("aString");
+dataProperty.SetDataType(MgPropertyType.String);
+dataProperty.SetNullable(true);
+dataProperty.SetReadOnly(false);
+classDef.GetProperties().Add(dataProperty);
+
+schema = new MgFeatureSchema();
+schemaName = "SdfFeatureClassSchema";
+schema.SetName(schemaName);
+schema.GetClasses().Add(classDef);
+```
\ No newline at end of file
Modified: branches/4.0/MgDev/Doc/landing/topics/toc.yml
===================================================================
--- branches/4.0/MgDev/Doc/landing/topics/toc.yml 2023-11-10 19:15:59 UTC (rev 10067)
+++ branches/4.0/MgDev/Doc/landing/topics/toc.yml 2023-11-10 20:21:36 UTC (rev 10068)
@@ -7,8 +7,21 @@
href: collections.md
- name: Feature Service
items:
+ - name: Introduction
+ href: feature-intro.md
+ - name: Feature Providers
+ href: feature-provider.md
+ - name: Feature Provider Registry
+ href: feature-provider-registry.md
+ - name: Connection to Feature Source
+ href: feature-connection.md
+ - name: Feature Schemas
+ href: feature-schema.md
- name: Feature Properties
href: feature-properties.md
+ - name: Filters and Expressions
+ href: feature-filters.md
+
- name: Geometry
items:
- name: Collections
More information about the mapguide-commits
mailing list