Common_CustomDataSource_CSharp\REXMLDataSource_CSharp\QueryFunctionality.cs
// Copyright 2011 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. // namespace REXMLDataSource_CSharp { // 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 : ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality { #region Instance Variable Declarations private string m_name = string.Empty; private ESRI.ArcGIS.ADF.Web.DataSources.IGISResource m_gisResource = null; [System.NonSerialized] System.Web.UI.WebControls.WebControl m_webControl; bool m_initialized = false; #endregion #region Constructor public QueryFunctionality(string name, REXMLDataSource_CSharp.MapResource resource) { m_name = name; m_gisResource = resource; } #endregion #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 ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet GetGraphicsDataSet(string mapFunctionalityName) { REXMLDataSource_CSharp.MapResource mapResource = m_gisResource as REXMLDataSource_CSharp.MapResource; if (mapResource == null) return null; // 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 == null) { return mapResource.Graphics; } else { REXMLDataSource_CSharp.MapFunctionality mapFunctionality = mapResource.Functionalities.Find(mapFunctionalityName) as REXMLDataSource_CSharp.MapFunctionality; return mapFunctionality == null ? null : mapFunctionality.GraphicsDataSet; } } // Enables convenient retrieval of the graphics layer with the specified ID from the REXML // MapFunctionality with the specified name private ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer GetGraphicsLayer(string mapFunctionalityName, string layerID) { // Make sure a layerID was specified if (layerID == null) return null; // Retrieve the graphics dataset from the REXML MapFunctionality with the passed-in name ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet graphicsDataSet = GetGraphicsDataSet(mapFunctionalityName); // Make sure a graphics dataset was found if (graphicsDataSet == null) return null; // Return the table in the graphics dataset that has a name matching the passed-in layer ID // as a Web ADF GraphicsLayer return graphicsDataSet.Tables[layerID] as ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer; } // 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 System.Collections.Generic.List<ESRI.ArcGIS.ADF.Web.Geometry.Geometry> InitialAttributeQuery(ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer graphicsLayer, System.Data.DataTable resultsDataTable, ESRI.ArcGIS.ADF.Web.QueryFilter adfQueryFilter) { System.Collections.Generic.List<ESRI.ArcGIS.ADF.Web.Geometry.Geometry> adfGeometryList = new System.Collections.Generic.List<ESRI.ArcGIS.ADF.Web.Geometry.Geometry>(); System.Data.DataRow[] dataRowArray = graphicsLayer.Select(adfQueryFilter.WhereClause); foreach (System.Data.DataRow dataRow in dataRowArray) { resultsDataTable.ImportRow(dataRow); adfGeometryList.Add(graphicsLayer.GeometryFromRow(dataRow)); } return adfGeometryList; } // Copies records satisfying a Web ADF Spatial Filter from a graphics layer to a data table. private void InitialSpatialQuery(ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer graphicsLayer, System.Data.DataTable resultsDataTable, ESRI.ArcGIS.ADF.Web.SpatialFilter adfSpatialFilter) { foreach (System.Data.DataRow dataRow in graphicsLayer.Rows) { ESRI.ArcGIS.ADF.Web.Geometry.Geometry adfGeometry = 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 ((adfGeometry != null) && (adfSpatialFilter.Geometry is ESRI.ArcGIS.ADF.Web.Geometry.Envelope) && (ESRI.ArcGIS.ADF.Web.Geometry.Utility.GeometryInExtent(adfGeometry, (ESRI.ArcGIS.ADF.Web.Geometry.Envelope)adfSpatialFilter.Geometry))) { resultsDataTable.ImportRow(dataRow); } } } // Allows filtering of rows in a data table based on a Web ADF QueryFilter private void AttributeQueryOnSpatialResults(System.Data.DataTable dataTable, ESRI.ArcGIS.ADF.Web.QueryFilter adfQueryFilter) { // The passed-in query filter has no query, so no filtering will be performed if (adfQueryFilter.WhereClause == "") return; // Get the rows from the passed-in data table that satisfy the query filter's where clause System.Data.DataRow[] selectionDataRowArray = dataTable.Select(adfQueryFilter.WhereClause); // Iterate through all the rows in the passed-in data table, removing rows that are not foreach (System.Data.DataRow dataRow in dataTable.Rows) { if (System.Array.IndexOf(selectionDataRowArray, dataRow) == -1) dataTable.Rows.Remove(dataRow); } } // 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 void SpatialQueryOnAttributeResults(System.Data.DataTable dataTable, ESRI.ArcGIS.ADF.Web.SpatialFilter adfSpatialFilter, System.Collections.Generic.List<ESRI.ArcGIS.ADF.Web.Geometry.Geometry> geometries) { if (geometries == null || geometries.Count == 0) return; for (int i = 0, j = 0; i < dataTable.Rows.Count; ++i, ++j) { // To implement, evaluate if feature geometry intersects spatial filter geometry /*if (!GeometriesIntersect(geometries[j], sf.Geometry)) { dataTable.Rows.Remove(dataTable.Rows[i]); --i; }*/ } } // Clones the passed-in data column private System.Data.DataColumn CloneColumn(System.Data.DataColumn sourceDataColumn) { // Create a data column instance that matches the type of the passed-in data column System.Data.DataColumn clonedDataColumn = (System.Data.DataColumn)System.Activator.CreateInstance( sourceDataColumn.GetType()); // 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 (sourceDataColumn.ExtendedProperties != null) { foreach (object extendedPropertyKey in sourceDataColumn.ExtendedProperties.Keys) { clonedDataColumn.ExtendedProperties[extendedPropertyKey] = sourceDataColumn.ExtendedProperties[extendedPropertyKey]; } } return clonedDataColumn; } // Gets the REXML MapFunctionality of the passed-in name from the MapResource associated with the // current QueryFunctionality instance private REXMLDataSource_CSharp.MapFunctionality GetMapFunctionality(string mapFunctionalityName) { if (m_gisResource == null) return null; REXMLDataSource_CSharp.MapResource mapResource = m_gisResource as REXMLDataSource_CSharp.MapResource; if (mapFunctionalityName == null) { return null; } else { REXMLDataSource_CSharp.MapFunctionality mapFunctionality = mapResource.Functionalities.Find(mapFunctionalityName) as REXMLDataSource_CSharp.MapFunctionality; return mapFunctionality; } } #endregion #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 System.Data.DataTable[] Find(string mapFunctionalityName, ESRI.ArcGIS.ADF.Web.FindParameters findParameters) { System.Collections.Generic.List<System.Data.DataTable> dataTableList = new System.Collections.Generic.List<System.Data.DataTable>(); ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet graphicsDataSet = GetGraphicsDataSet(mapFunctionalityName); if (graphicsDataSet == null) return null; // Initialize Web ADF QueryFilter based on passed-in FindParameters ESRI.ArcGIS.ADF.Web.QueryFilter adfQueryFilter = 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 System.Collections.IDictionaryEnumerator dictionaryEnumerator = findParameters.LayersAndFields.GetEnumerator(); 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 string layerID = dictionaryEnumerator.Key as string; string[] searchFields = dictionaryEnumerator.Value as string[]; // Iterate through the fields to be searched for the current layer and build the where clause System.Text.StringBuilder whereExpression = new System.Text.StringBuilder(); for (int i = 0; i < searchFields.Length; i++) { if (findParameters.UseSqlContains) { // 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)); } if (i != searchFields.Length - 1) whereExpression.Append(" OR "); } adfQueryFilter.WhereClause = whereExpression.ToString(); // Get the graphics layer corresponding to the current layer ID from the map functionality's // graphics dataset ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer graphicsLayer = graphicsDataSet.Tables[layerID] as ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer; if (graphicsLayer != null) { // Make sure the current graphics layer satisfies the specified visibility option if (findParameters.FindOption != ESRI.ArcGIS.ADF.Web.FindOption.VisibleLayers || (findParameters.FindOption == ESRI.ArcGIS.ADF.Web.FindOption.VisibleLayers && graphicsLayer.Visible == true)) { // Execute the query for the current layer and add the results to the list of data tables dataTableList.Add(Query(mapFunctionalityName, graphicsLayer.TableName, adfQueryFilter)); } } } return dataTableList.ToArray(); } // Allows querying of multiple layers of a REXML MapFunctionality based on an input point public System.Data.DataTable[] Identify(string mapFunctionalityName, ESRI.ArcGIS.ADF.Web.Geometry.Geometry adfGeometry, int tolerance, ESRI.ArcGIS.ADF.Web.IdentifyOption identifyOption, string[] layerIDs) { System.Collections.Generic.List<System.Data.DataTable> dataTableList = new System.Collections.Generic.List<System.Data.DataTable>(); // Get the graphics dataset for the REXML MapFunctionality indicated by the passed-in name ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet graphicsDataSet = GetGraphicsDataSet(mapFunctionalityName); if (graphicsDataSet == null) return null; // Get the REXML MapFunctionality object REXMLDataSource_CSharp.MapFunctionality rexmlMapFunctionality = GetMapFunctionality(mapFunctionalityName); if (rexmlMapFunctionality == null) return null; // 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 int viewWidth, viewHeight; rexmlMapFunctionality.GetMapDimensions(out viewWidth, out viewHeight); ESRI.ArcGIS.ADF.Web.Geometry.Envelope mapExtent = rexmlMapFunctionality.GetMapExtent(); if (mapExtent == null) return null; ESRI.ArcGIS.ADF.Web.SpatialFilter adfSpatialFilter = 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 (adfGeometry is ESRI.ArcGIS.ADF.Web.Geometry.Point) { // Calculate the tolerance to add around the point for the search geometry double pixelsPerMapUnit = viewWidth / mapExtent.Width; double mapTolerance = 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 ESRI.ArcGIS.ADF.Web.Geometry.Point adfPoint = adfGeometry as 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."); } // 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 == null) { foreach (ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer graphicsLayer in graphicsDataSet.Tables) { dataTableList.Add(Query(mapFunctionalityName, graphicsLayer.TableName, adfSpatialFilter)); } } else { foreach (string layerID in layerIDs) { dataTableList.Add(Query(mapFunctionalityName, layerID, adfSpatialFilter)); } } return dataTableList.ToArray(); } // Executes a query based on the passed-in parameters and returns the results as a DataTable public System.Data.DataTable Query(string mapFunctionalityName, string layerID, ESRI.ArcGIS.ADF.Web.QueryFilter adfQueryFilter) { // Get the graphics layer specified by the passed-in layer ID and map functionality name ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer graphicsLayer = GetGraphicsLayer(mapFunctionalityName, layerID); if (graphicsLayer == null) return null; // Declare a data table. This table will hold the query results System.Data.DataTable resultsDataTable = null; // Declare a list of data columns. This will hold the columns to be included in the query results System.Collections.Generic.List<System.Data.DataColumn> resultsDataColumnList = new System.Collections.Generic.List<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 foreach (System.Data.DataColumn 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 || adfQueryFilter.SubFields.IndexOf(dataColumn.ColumnName) != -1) resultsDataColumnList.Add(CloneColumn(dataColumn)); else if (adfQueryFilter.ReturnADFGeometries && (dataColumn.DataType == typeof(ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement) || dataColumn.DataType == typeof(ESRI.ArcGIS.ADF.Web.Geometry.Geometry))) resultsDataColumnList.Add(CloneColumn(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) { if (graphicsLayer is ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer) { ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer featureGraphicsLayer = graphicsLayer as 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 { ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer elementGraphicsLayer = graphicsLayer as 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); } } // 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 == null) { resultsDataTable = new System.Data.DataTable(graphicsLayer.TableName); resultsDataTable.Columns.AddRange(resultsDataColumnList.ToArray()); } // Execute the query using the appropriate private functions. if (adfQueryFilter is ESRI.ArcGIS.ADF.Web.SpatialFilter) { // Get a reference to the passed-in query filter as a Web ADF Spatial Filter ESRI.ArcGIS.ADF.Web.SpatialFilter adfSpatialFilter = adfQueryFilter as ESRI.ArcGIS.ADF.Web.SpatialFilter; if (adfSpatialFilter.SearchOrder == ESRI.ArcGIS.ADF.Web.SearchOrder.Spatial) { // 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. System.Collections.Generic.List<ESRI.ArcGIS.ADF.Web.Geometry.Geometry> adfGeometryList = InitialAttributeQuery(graphicsLayer, resultsDataTable, adfQueryFilter); SpatialQueryOnAttributeResults(resultsDataTable, adfSpatialFilter, adfGeometryList); } } else { // The query is non-spatial, so simply execute an attribute query based on the query filter's // where clause InitialAttributeQuery(graphicsLayer, resultsDataTable, adfQueryFilter); } // 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 && adfQueryFilter.MaxRecords > 0) { while (resultsDataTable.Rows.Count > adfQueryFilter.MaxRecords) resultsDataTable.Rows.RemoveAt(resultsDataTable.Rows.Count - 1); } return resultsDataTable; } // Gets layers of the passed-in feature type that can be queried public void GetQueryableLayers(string mapFunctionalityName, out string[] layerIDs, out string[] layerNames, ESRI.ArcGIS.ADF.Web.FeatureType featureType) { layerIDs = null; layerNames = null; System.Collections.Generic.List<System.Data.DataTable> queryableDataTableList = new System.Collections.Generic.List<System.Data.DataTable>(); // Get the graphics dataset underlying the map functionality having the passed-in name ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet graphicsDataSet = GetGraphicsDataSet(mapFunctionalityName); if (graphicsDataSet == null) return; // 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 foreach (ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer graphicsLayer in graphicsDataSet.Tables) { ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer featureGraphicsLayer = graphicsLayer as 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 (featureGraphicsLayer != null && featureGraphicsLayer.FeatureType != featureType) continue; queryableDataTableList.Add(graphicsLayer); } // Re-dimension the output arrays with the number of queryable layers found layerIDs = new string[queryableDataTableList.Count]; layerNames = new string[queryableDataTableList.Count]; // Iterate through the queryable table list, adding the name of each table to the output arrays for (int i = 0; i < queryableDataTableList.Count; ++i) { layerIDs[i] = queryableDataTableList[i].TableName; layerNames[i] = queryableDataTableList[i].TableName; } } // Gets all the layers referenced by the map functionality of the specified name that can be queried public void GetQueryableLayers(string mapFunctionalityName, out string[] layerIDs, out string[] layerNames) { layerIDs = null; layerNames = null; // Get the graphics dataset underlying the map functionality having the passed-in name ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet graphicsDataSet = GetGraphicsDataSet(mapFunctionalityName); if (graphicsDataSet == null) return; // Copy the names of the tables in the graphics dataset to the output arrays layerIDs = new string[graphicsDataSet.Tables.Count]; layerNames = new string[graphicsDataSet.Tables.Count]; for (int i = 0; i < graphicsDataSet.Tables.Count; ++i) { layerIDs[i] = graphicsDataSet.Tables[i].TableName; layerNames[i] = graphicsDataSet.Tables[i].TableName; } } // Gets the names of the fields in the layer specified by the passed-in ID public string[] GetFields(string mapFunctionalityName, string layerID) { // Get the Web ADF graphics layer belonging to the map functionality specified by the passed-in // name with the passed-in ID ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer graphicsLayer = GetGraphicsLayer(mapFunctionalityName, layerID); if (graphicsLayer == null) return null; // Copy the names of all the columns in the graphics layer to a string array string[] fieldNameArray = new string[graphicsLayer.Columns.Count]; for (int i = 0; i < graphicsLayer.Columns.Count; ++i) { fieldNameArray[i] = graphicsLayer.Columns[i].ColumnName; } return fieldNameArray; } // Gets the names and types of the fields in the layer specified by the passed-in ID public string[] GetFields(string mapFunctionalityName, string layerID, out System.Type[] fieldTypes) { // Get the Web ADF graphics layer belonging to the map functionality specified by the passed-in // name with the passed-in ID ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer graphicsLayer = GetGraphicsLayer(mapFunctionalityName, layerID); if (graphicsLayer == null) { fieldTypes = null; return null; } // 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 string[] fieldNameArray = new string[graphicsLayer.Columns.Count]; fieldTypes = new System.Type[graphicsLayer.Columns.Count]; for (int i = 0; i < graphicsLayer.Columns.Count; ++i) { fieldNameArray[i] = graphicsLayer.Columns[i].ColumnName; fieldTypes[i] = graphicsLayer.Columns[i].DataType; } return fieldNameArray; } #endregion #region IGISFunctionality implementation public System.Web.UI.WebControls.WebControl WebControl { get { return m_webControl; } set { m_webControl = value; } } public string Name { get { return m_name; } set { m_name = value; } } public ESRI.ArcGIS.ADF.Web.DataSources.IGISResource Resource { get { return m_gisResource; } set { m_gisResource = value; } } public bool Initialized { get { return m_initialized; } } public void LoadState() { } public void Initialize() { m_initialized = true; } public void SaveState() { } // 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 void Dispose() { m_initialized = false; } public bool Supports(string operation) { return true; } #endregion } }