Common_CustomDataSource_VBNet\REXMLDataSource_VBNet\QueryFunctionality.vb
' Copyright 2010 ESRI ' ' All rights reserved under the copyright laws of the United States ' and applicable international laws, treaties, and conventions. ' ' You may freely redistribute and use this sample code, with or ' without modification, provided you include the original copyright ' notice and use restrictions. ' ' See the use restrictions. ' Imports Microsoft.VisualBasic Imports System Namespace REXMLDataSource_VBNet ' Along with IGISDataSource and IGISResource, IGISFunctionality is one of the three required ' interfaces for any Web ADF Data Source implementation. This interface is responsible for ' providing members to functionally interact with the underlying data. Essentially, an ' IGISFunctionality implementation can be thought of as describing what can be done with the ' data. ' ' This particular implementation inherits from IQueryFunctionality, which implements ' IGISFunctionality. IQueryFunctionality provides methods and properties that allow the ' extraction of attributes and geometry from the underlying data source via query expressions ' and geometries. Public Class QueryFunctionality Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality #Region "Instance Variable Declarations" Private m_name As String = String.Empty Private m_gisResource As ESRI.ArcGIS.ADF.Web.DataSources.IGISResource = Nothing Private m_webControl As System.Web.UI.WebControls.WebControl Private m_initialized As Boolean = False #End Region #Region "Constructor " Public Sub New(ByVal name As String, ByVal resource As REXMLDataSource_VBNet.MapResource) m_name = name m_gisResource = resource End Sub #End Region #Region "REXML QueryFunctionality Members" ' Enables convenient retrieval of the graphics dataset underlying either (a) the resource ' associated with the QueryFunctionality instance (if no functionality name is passed into ' the function) or (b) the specific MapFunctionality indicated by the mapFunctionalityName ' parameter Private Function GetGraphicsDataSet(ByVal mapFunctionalityName As String) As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet Dim mapResource As REXMLDataSource_VBNet.MapResource = TryCast(m_gisResource, REXMLDataSource_VBNet.MapResource) If mapResource Is Nothing Then Return Nothing End If ' If no functionality name was passed in, return the graphics dataset underlying the REXML ' MapResource associated with the QueryFunctionality instance. Otherwise, retrieve the ' REXML MapFunctionality indicated by the passed-in name and return the graphics dataset ' underlying that functionality. If mapFunctionalityName Is Nothing Then Return mapResource.Graphics Else Dim mapFunctionality As REXMLDataSource_VBNet.MapFunctionality = TryCast(mapResource.Functionalities.Find(mapFunctionalityName), REXMLDataSource_VBNet.MapFunctionality) If mapFunctionality Is Nothing Then Return Nothing Else Return mapFunctionality.GraphicsDataSet End If End If End Function ' Enables convenient retrieval of the graphics layer with the specified ID from the REXML ' MapFunctionality with the specified name Private Function GetGraphicsLayer(ByVal mapFunctionalityName As String, ByVal layerID As String) As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer ' Make sure a layerID was specified If layerID Is Nothing Then Return Nothing End If ' Retrieve the graphics dataset from the REXML MapFunctionality with the passed-in name Dim graphicsDataSet As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet = GetGraphicsDataSet(mapFunctionalityName) ' Make sure a graphics dataset was found If graphicsDataSet Is Nothing Then Return Nothing End If ' Return the table in the graphics dataset that has a name matching the passed-in layer ID ' as a Web ADF GraphicsLayer Return TryCast(graphicsDataSet.Tables(layerID), ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer) End Function ' Copies records satisfying a Web ADF Query Filter from a graphics layer to a data table. ' Also returns a list of the geometries for the rows that satsify the query Private Function InitialAttributeQuery(ByVal graphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer, ByVal resultsDataTable As System.Data.DataTable, ByVal adfQueryFilter As ESRI.ArcGIS.ADF.Web.QueryFilter) As System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.Geometry.Geometry) Dim adfGeometryList As System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.Geometry.Geometry) = New System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.Geometry.Geometry)() Dim dataRowArray As System.Data.DataRow() = graphicsLayer.Select(adfQueryFilter.WhereClause) For Each dataRow As System.Data.DataRow In dataRowArray resultsDataTable.ImportRow(dataRow) adfGeometryList.Add(graphicsLayer.GeometryFromRow(dataRow)) Next dataRow Return adfGeometryList End Function ' Copies records satisfying a Web ADF Spatial Filter from a graphics layer to a data table. Private Sub InitialSpatialQuery(ByVal graphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer, ByVal resultsDataTable As System.Data.DataTable, ByVal adfSpatialFilter As ESRI.ArcGIS.ADF.Web.SpatialFilter) For Each dataRow As System.Data.DataRow In graphicsLayer.Rows Dim adfGeometry As ESRI.ArcGIS.ADF.Web.Geometry.Geometry = graphicsLayer.GeometryFromRow(dataRow) ' Evaluate feature geometry and spatial filter geometry. Designed to work if the spatial ' filter geometry is an Envelope - not implemented for other geometry types. If (Not adfGeometry Is Nothing) AndAlso (TypeOf adfSpatialFilter.Geometry Is ESRI.ArcGIS.ADF.Web.Geometry.Envelope) AndAlso (ESRI.ArcGIS.ADF.Web.Geometry.Utility.GeometryInExtent(adfGeometry, CType(adfSpatialFilter.Geometry, ESRI.ArcGIS.ADF.Web.Geometry.Envelope))) Then resultsDataTable.ImportRow(dataRow) End If Next dataRow End Sub ' Allows filtering of rows in a data table based on a Web ADF QueryFilter Private Sub AttributeQueryOnSpatialResults(ByVal dataTable As System.Data.DataTable, ByVal adfQueryFilter As ESRI.ArcGIS.ADF.Web.QueryFilter) ' The passed-in query filter has no query, so no filtering will be performed If adfQueryFilter.WhereClause = "" Then Return End If ' Get the rows from the passed-in data table that satisfy the query filter's where clause Dim selectionDataRowArray As System.Data.DataRow() = dataTable.Select(adfQueryFilter.WhereClause) ' Iterate through all the rows in the passed-in data table, removing rows that are not For Each dataRow As System.Data.DataRow In dataTable.Rows If System.Array.IndexOf(selectionDataRowArray, dataRow) = -1 Then dataTable.Rows.Remove(dataRow) End If Next dataRow End Sub ' Allows filtering of rows in a data table based on whether the passed-in geometries intersect ' the spatial filter geometry. The passed-in geometries are meant to be the geoemtries from ' the rows in the data table. Private Sub SpatialQueryOnAttributeResults(ByVal dataTable As System.Data.DataTable, ByVal adfSpatialFilter As ESRI.ArcGIS.ADF.Web.SpatialFilter, ByVal geometries As System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.Geometry.Geometry)) If geometries Is Nothing OrElse geometries.Count = 0 Then Return End If Dim i As Integer = 0 Dim j As Integer = 0 Do While i < dataTable.Rows.Count ' To implement, evaluate if feature geometry intersects spatial filter geometry 'if (!GeometriesIntersect(geometries[j], sf.Geometry)) '{ 'dataTable.Rows.Remove(dataTable.Rows[i]); '--i; '} i += 1 j += 1 Loop End Sub ' Clones the passed-in data column Private Function CloneColumn(ByVal sourceDataColumn As System.Data.DataColumn) As System.Data.DataColumn ' Create a data column instance that matches the type of the passed-in data column Dim clonedDataColumn As System.Data.DataColumn = CType(System.Activator.CreateInstance(sourceDataColumn.GetType()), System.Data.DataColumn) ' Copy the properties from the passed-in data column to the new data column clonedDataColumn.AllowDBNull = sourceDataColumn.AllowDBNull clonedDataColumn.AutoIncrement = sourceDataColumn.AutoIncrement clonedDataColumn.AutoIncrementStep = sourceDataColumn.AutoIncrementStep clonedDataColumn.AutoIncrementSeed = sourceDataColumn.AutoIncrementSeed clonedDataColumn.Caption = sourceDataColumn.Caption clonedDataColumn.ColumnName = sourceDataColumn.ColumnName clonedDataColumn.DataType = sourceDataColumn.DataType clonedDataColumn.DefaultValue = sourceDataColumn.DefaultValue clonedDataColumn.ColumnMapping = sourceDataColumn.ColumnMapping clonedDataColumn.ReadOnly = sourceDataColumn.ReadOnly clonedDataColumn.MaxLength = sourceDataColumn.MaxLength clonedDataColumn.DateTimeMode = sourceDataColumn.DateTimeMode clonedDataColumn.Namespace = sourceDataColumn.Namespace clonedDataColumn.Prefix = sourceDataColumn.Prefix clonedDataColumn.Unique = sourceDataColumn.Unique ' Copy the extended properties from the passed-in data column to the new data column If Not sourceDataColumn.ExtendedProperties Is Nothing Then For Each extendedPropertyKey As Object In sourceDataColumn.ExtendedProperties.Keys clonedDataColumn.ExtendedProperties(extendedPropertyKey) = sourceDataColumn.ExtendedProperties(extendedPropertyKey) Next extendedPropertyKey End If Return clonedDataColumn End Function ' Gets the REXML MapFunctionality of the passed-in name from the MapResource associated with the ' current QueryFunctionality instance Private Function GetMapFunctionality(ByVal mapFunctionalityName As String) As REXMLDataSource_VBNet.MapFunctionality If m_gisResource Is Nothing Then Return Nothing End If Dim mapResource As REXMLDataSource_VBNet.MapResource = TryCast(m_gisResource, REXMLDataSource_VBNet.MapResource) If mapFunctionalityName Is Nothing Then Return Nothing Else Dim mapFunctionality As REXMLDataSource_VBNet.MapFunctionality = TryCast(mapResource.Functionalities.Find(mapFunctionalityName), REXMLDataSource_VBNet.MapFunctionality) Return mapFunctionality End If End Function #End Region #Region "IQueryFunctionality Members" ' Allows querying of the REXML MapFunctionality indicated by the passed-in name with the parameters ' specified by the passed-in FindParameters object. More specifically, Find searches the layers ' and fields specified by FindParameters for values that completely or partly match the FindString ' of the FindParameters object. Public Function Find(ByVal mapFunctionalityName As String, ByVal findParameters As ESRI.ArcGIS.ADF.Web.FindParameters) As System.Data.DataTable() Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.Find Dim dataTableList As System.Collections.Generic.List(Of System.Data.DataTable) = New System.Collections.Generic.List(Of System.Data.DataTable)() Dim graphicsDataSet As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet = GetGraphicsDataSet(mapFunctionalityName) If graphicsDataSet Is Nothing Then Return Nothing End If ' Initialize Web ADF QueryFilter based on passed-in FindParameters Dim adfQueryFilter As ESRI.ArcGIS.ADF.Web.QueryFilter = New ESRI.ArcGIS.ADF.Web.QueryFilter() adfQueryFilter.MaxRecords = findParameters.MaxRecords adfQueryFilter.ReturnADFGeometries = findParameters.ReturnADFGeometries ' Get an enumerator of the layers and fields to be searched from the FindParameters object Dim dictionaryEnumerator As System.Collections.IDictionaryEnumerator = findParameters.LayersAndFields.GetEnumerator() Do While dictionaryEnumerator.MoveNext() ' Each index of the enumerator will have the layer ID as its key and a string array ' of field names as its value Dim layerID As String = TryCast(dictionaryEnumerator.Key, String) Dim searchFields As String() = TryCast(dictionaryEnumerator.Value, String()) ' Iterate through the fields to be searched for the current layer and build the where clause Dim whereExpression As System.Text.StringBuilder = New System.Text.StringBuilder() Dim i As Integer = 0 Do While i < searchFields.Length If findParameters.UseSqlContains Then ' todo: change to use SQL CONTAINS statement whereExpression.Append(String.Format("{0} like '%{1}%'", searchFields(i), findParameters.FindString)) Else whereExpression.Append(String.Format("{0} like '%{1}%'", searchFields(i), findParameters.FindString)) End If If i <> searchFields.Length - 1 Then whereExpression.Append(" OR ") End If i += 1 Loop adfQueryFilter.WhereClause = whereExpression.ToString() ' Get the graphics layer corresponding to the current layer ID from the map functionality's ' graphics dataset Dim graphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer = TryCast(graphicsDataSet.Tables(layerID), ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer) If Not graphicsLayer Is Nothing Then ' Make sure the current graphics layer satisfies the specified visibility option If findParameters.FindOption <> ESRI.ArcGIS.ADF.Web.FindOption.VisibleLayers OrElse (findParameters.FindOption = ESRI.ArcGIS.ADF.Web.FindOption.VisibleLayers AndAlso graphicsLayer.Visible = True) Then ' Execute the query for the current layer and add the results to the list of data tables dataTableList.Add(Query(mapFunctionalityName, graphicsLayer.TableName, adfQueryFilter)) End If End If Loop Return dataTableList.ToArray() End Function ' Allows querying of multiple layers of a REXML MapFunctionality based on an input point Public Function Identify(ByVal mapFunctionalityName As String, ByVal adfGeometry As ESRI.ArcGIS.ADF.Web.Geometry.Geometry, ByVal tolerance As Integer, ByVal identifyOption As ESRI.ArcGIS.ADF.Web.IdentifyOption, ByVal layerIDs As String()) As System.Data.DataTable() Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.Identify Dim dataTableList As System.Collections.Generic.List(Of System.Data.DataTable) = New System.Collections.Generic.List(Of System.Data.DataTable)() ' Get the graphics dataset for the REXML MapFunctionality indicated by the passed-in name Dim graphicsDataSet As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet = GetGraphicsDataSet(mapFunctionalityName) If graphicsDataSet Is Nothing Then Return Nothing End If ' Get the REXML MapFunctionality object Dim rexmlMapFunctionality As REXMLDataSource_VBNet.MapFunctionality = GetMapFunctionality(mapFunctionalityName) If rexmlMapFunctionality Is Nothing Then Return Nothing End If ' Get the screen dimensions and the Web ADF extent of the map displaying the data source. ' These will be used in calculating a search tolerance around the input point Dim viewWidth, viewHeight As Integer rexmlMapFunctionality.GetMapDimensions(viewWidth, viewHeight) Dim mapExtent As ESRI.ArcGIS.ADF.Web.Geometry.Envelope = rexmlMapFunctionality.GetMapExtent() If mapExtent Is Nothing Then Return Nothing End If Dim adfSpatialFilter As ESRI.ArcGIS.ADF.Web.SpatialFilter = New ESRI.ArcGIS.ADF.Web.SpatialFilter() adfSpatialFilter.SearchOrder = ESRI.ArcGIS.ADF.Web.SearchOrder.Spatial ' Make sure the passed-in geometry is a Web ADF Point. Other geometry types are not supported in ' this implementation If TypeOf adfGeometry Is ESRI.ArcGIS.ADF.Web.Geometry.Point Then ' Calculate the tolerance to add around the point for the search geometry Dim pixelsPerMapUnit As Double = viewWidth / mapExtent.Width Dim mapTolerance As Double = tolerance / pixelsPerMapUnit ' Create the search geometry by initializing a Web ADF Envelope with the passed-in point's ' coordinates plus and minus the calculated search tolerance Dim adfPoint As ESRI.ArcGIS.ADF.Web.Geometry.Point = TryCast(adfGeometry, ESRI.ArcGIS.ADF.Web.Geometry.Point) adfSpatialFilter.Geometry = New ESRI.ArcGIS.ADF.Web.Geometry.Envelope(adfPoint.X - mapTolerance, adfPoint.Y - mapTolerance, adfPoint.X + mapTolerance, adfPoint.Y + mapTolerance) Else Throw New System.NotSupportedException("GraphicsLayer only supports Points in the " & "Identify method.") End If ' Check whether any layer IDs were specified in the operation. If so, only query those layers. If ' not, query all the layers. Add the results of each query to the list of data tables. If layerIDs Is Nothing Then For Each graphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer In graphicsDataSet.Tables dataTableList.Add(Query(mapFunctionalityName, graphicsLayer.TableName, adfSpatialFilter)) Next graphicsLayer Else For Each layerID As String In layerIDs dataTableList.Add(Query(mapFunctionalityName, layerID, adfSpatialFilter)) Next layerID End If Return dataTableList.ToArray() End Function ' Executes a query based on the passed-in parameters and returns the results as a DataTable Public Function Query(ByVal mapFunctionalityName As String, ByVal layerID As String, ByVal adfQueryFilter As ESRI.ArcGIS.ADF.Web.QueryFilter) As System.Data.DataTable Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.Query ' Get the graphics layer specified by the passed-in layer ID and map functionality name Dim graphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer = GetGraphicsLayer(mapFunctionalityName, layerID) If graphicsLayer Is Nothing Then Return Nothing End If ' Declare a data table. This table will hold the query results Dim resultsDataTable As System.Data.DataTable = Nothing ' Declare a list of data columns. This will hold the columns to be included in the query results Dim resultsDataColumnList As System.Collections.Generic.List(Of System.Data.DataColumn) = New System.Collections.Generic.List(Of System.Data.DataColumn)() ' Iterate through the columns in the graphics layer, adding each one to be included in ' the query results to the results data column list For Each dataColumn As System.Data.DataColumn In graphicsLayer.Columns ' If no fields were specified in the query; the current column name matches one of ' the specified field names; or the current column is a geometry column and geometries ' are to be returned in the query, add a copy of the current column to the results column ' list If adfQueryFilter.SubFields.Count = 0 OrElse adfQueryFilter.SubFields.IndexOf(dataColumn.ColumnName) <> -1 Then resultsDataColumnList.Add(CloneColumn(dataColumn)) ElseIf adfQueryFilter.ReturnADFGeometries AndAlso (dataColumn.DataType Is GetType(ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement) OrElse dataColumn.DataType Is GetType(ESRI.ArcGIS.ADF.Web.Geometry.Geometry)) Then resultsDataColumnList.Add(CloneColumn(dataColumn)) End If Next dataColumn ' If the query is to return geometries, initialize the results data table as a Web ADF graphics ' layer of the appropriate type If adfQueryFilter.ReturnADFGeometries Then If TypeOf graphicsLayer Is ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer Then Dim featureGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer = TryCast(graphicsLayer, ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer) resultsDataTable = New ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer(featureGraphicsLayer.TableName, resultsDataColumnList.ToArray(), featureGraphicsLayer.GeometryColumnName, featureGraphicsLayer.GraphicsIDColumn.ColumnName, featureGraphicsLayer.FeatureType) Else Dim elementGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer = TryCast(graphicsLayer, ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer) resultsDataTable = New ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer(elementGraphicsLayer.TableName, resultsDataColumnList.ToArray(), elementGraphicsLayer.GraphicsColumn.ColumnName, elementGraphicsLayer.GraphicsIDColumn.ColumnName) End If End If ' If the query is not to return geometries, the results data table will not yet be intialized. ' Initialize it as an ordinary DataTable. If resultsDataTable Is Nothing Then resultsDataTable = New System.Data.DataTable(graphicsLayer.TableName) resultsDataTable.Columns.AddRange(resultsDataColumnList.ToArray()) End If ' Execute the query using the appropriate private functions. If TypeOf adfQueryFilter Is ESRI.ArcGIS.ADF.Web.SpatialFilter Then ' Get a reference to the passed-in query filter as a Web ADF Spatial Filter Dim adfSpatialFilter As ESRI.ArcGIS.ADF.Web.SpatialFilter = TryCast(adfQueryFilter, ESRI.ArcGIS.ADF.Web.SpatialFilter) If adfSpatialFilter.SearchOrder = ESRI.ArcGIS.ADF.Web.SearchOrder.Spatial Then ' Execute the spatial query first, then filter the spatial query based on the ' query filter's where clause InitialSpatialQuery(graphicsLayer, resultsDataTable, adfSpatialFilter) AttributeQueryOnSpatialResults(resultsDataTable, adfQueryFilter) Else ' Execute the attribute query first, then filter the query results based on the filter ' geometry. Dim adfGeometryList As System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.Geometry.Geometry) = InitialAttributeQuery(graphicsLayer, resultsDataTable, adfQueryFilter) SpatialQueryOnAttributeResults(resultsDataTable, adfSpatialFilter, adfGeometryList) End If Else ' The query is non-spatial, so simply execute an attribute query based on the query filter's ' where clause InitialAttributeQuery(graphicsLayer, resultsDataTable, adfQueryFilter) End If ' If the results data table contains more records than the number specified by the query filter ' as the maximum, remove the extra results from the end of the table If resultsDataTable.Rows.Count > adfQueryFilter.MaxRecords AndAlso adfQueryFilter.MaxRecords > 0 Then Do While resultsDataTable.Rows.Count > adfQueryFilter.MaxRecords resultsDataTable.Rows.RemoveAt(resultsDataTable.Rows.Count - 1) Loop End If Return resultsDataTable End Function ' Gets layers of the passed-in feature type that can be queried Public Sub GetQueryableLayers(ByVal mapFunctionalityName As String, <System.Runtime.InteropServices.Out()> ByRef layerIDs As String(), <System.Runtime.InteropServices.Out()> ByRef layerNames As String(), ByVal featureType As ESRI.ArcGIS.ADF.Web.FeatureType) Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.GetQueryableLayers layerIDs = Nothing layerNames = Nothing Dim queryableDataTableList As System.Collections.Generic.List(Of System.Data.DataTable) = New System.Collections.Generic.List(Of System.Data.DataTable)() ' Get the graphics dataset underlying the map functionality having the passed-in name Dim graphicsDataSet As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet = GetGraphicsDataSet(mapFunctionalityName) If graphicsDataSet Is Nothing Then Return End If ' Iterate through the graphics layers in the graphics dataset, adding layers that are ' FeatureGraphicsLayers of the passed-in feature type to the data table list of queryable layers For Each graphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer In graphicsDataSet.Tables Dim featureGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer = TryCast(graphicsLayer, ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer) ' If the layer is not a feature graphics layer or is not of the passed-in type, skip to the ' next layer If Not featureGraphicsLayer Is Nothing AndAlso featureGraphicsLayer.FeatureType <> featureType Then Continue For End If queryableDataTableList.Add(graphicsLayer) Next graphicsLayer ' Re-dimension the output arrays with the number of queryable layers found layerIDs = New String(queryableDataTableList.Count - 1) {} layerNames = New String(queryableDataTableList.Count - 1) {} ' Iterate through the queryable table list, adding the name of each table to the output arrays Dim i As Integer = 0 Do While i < queryableDataTableList.Count layerIDs(i) = queryableDataTableList(i).TableName layerNames(i) = queryableDataTableList(i).TableName i += 1 Loop End Sub ' Gets all the layers referenced by the map functionality of the specified name that can be queried Public Sub GetQueryableLayers(ByVal mapFunctionalityName As String, <System.Runtime.InteropServices.Out()> ByRef layerIDs As String(), <System.Runtime.InteropServices.Out()> ByRef layerNames As String()) Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.GetQueryableLayers layerIDs = Nothing layerNames = Nothing ' Get the graphics dataset underlying the map functionality having the passed-in name Dim graphicsDataSet As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet = GetGraphicsDataSet(mapFunctionalityName) If graphicsDataSet Is Nothing Then Return End If ' Copy the names of the tables in the graphics dataset to the output arrays layerIDs = New String(graphicsDataSet.Tables.Count - 1) {} layerNames = New String(graphicsDataSet.Tables.Count - 1) {} Dim i As Integer = 0 Do While i < graphicsDataSet.Tables.Count layerIDs(i) = graphicsDataSet.Tables(i).TableName layerNames(i) = graphicsDataSet.Tables(i).TableName i += 1 Loop End Sub ' Gets the names of the fields in the layer specified by the passed-in ID Public Function GetFields(ByVal mapFunctionalityName As String, ByVal layerID As String) As String() Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.GetFields ' Get the Web ADF graphics layer belonging to the map functionality specified by the passed-in ' name with the passed-in ID Dim graphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer = GetGraphicsLayer(mapFunctionalityName, layerID) If graphicsLayer Is Nothing Then Return Nothing End If ' Copy the names of all the columns in the graphics layer to a string array Dim fieldNameArray As String() = New String(graphicsLayer.Columns.Count - 1) {} Dim i As Integer = 0 Do While i < graphicsLayer.Columns.Count fieldNameArray(i) = graphicsLayer.Columns(i).ColumnName i += 1 Loop Return fieldNameArray End Function ' Gets the names and types of the fields in the layer specified by the passed-in ID Public Function GetFields(ByVal mapFunctionalityName As String, ByVal layerID As String, <System.Runtime.InteropServices.Out()> ByRef fieldTypes As System.Type()) As String() Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.GetFields ' Get the Web ADF graphics layer belonging to the map functionality specified by the passed-in ' name with the passed-in ID Dim graphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer = GetGraphicsLayer(mapFunctionalityName, layerID) If graphicsLayer Is Nothing Then fieldTypes = Nothing Return Nothing End If ' Copy the names of all the columns in the graphics layer to a string array, and the types of ' the columns to the passed-in type array Dim fieldNameArray As String() = New String(graphicsLayer.Columns.Count - 1) {} fieldTypes = New System.Type(graphicsLayer.Columns.Count - 1) {} Dim i As Integer = 0 Do While i < graphicsLayer.Columns.Count fieldNameArray(i) = graphicsLayer.Columns(i).ColumnName fieldTypes(i) = graphicsLayer.Columns(i).DataType i += 1 Loop Return fieldNameArray End Function #End Region #Region "IGISFunctionality implementation" Public Property WebControl() As System.Web.UI.WebControls.WebControl Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.WebControl Get Return m_webControl End Get Set(ByVal value As System.Web.UI.WebControls.WebControl) m_webControl = Value End Set End Property Public Property Name() As String Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.Name Get Return m_name End Get Set(ByVal value As String) m_name = Value End Set End Property Public Property Resource() As ESRI.ArcGIS.ADF.Web.DataSources.IGISResource Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.Resource Get Return m_gisResource End Get Set(ByVal value As ESRI.ArcGIS.ADF.Web.DataSources.IGISResource) m_gisResource = Value End Set End Property Public ReadOnly Property Initialized() As Boolean Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.Initialized Get Return m_initialized End Get End Property Public Sub LoadState() Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.LoadState End Sub Public Sub Initialize() Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.Initialize m_initialized = True End Sub Public Sub SaveState() Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.SaveState End Sub ' Set the flag indicating whether the functionality is intitialized to false. Any necessary ' disposal logic (e.g. releasing object references) should go here. Note that, if there is ' additional logic here, users of this class will have to EXPLCITLY call dispose. It is not ' invoked by other Web ADF components or the Page life-cycle. Public Sub Dispose() Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.Dispose m_initialized = False End Sub Public Function Supports(ByVal operation As String) As Boolean Implements ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality.Supports Return True End Function #End Region End Class End Namespace