SpatialQuerySOE.Manager_CSharp\Configurator.cs
// 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. // using System; using System.Collections.Generic; using System.Text; namespace SpatialQuerySOE.Manager { /// <summary> /// SpatialQuerySOE property configuration page for Manager. Defines the appearance and behavior of the page. /// </summary> public class Configurator : ESRI.ArcGIS.ServerManager.IServerObjectExtensionConfigurator { #region Member variables // Controls to enable configuration of the SOE's layer and field private System.Web.UI.WebControls.DropDownList m_layersDropDown = new System.Web.UI.WebControls.DropDownList(); private System.Web.UI.WebControls.DropDownList m_fieldsDropDown = new System.Web.UI.WebControls.DropDownList(); // The SOE's current layer private string m_layer; // The SOE's current field private string m_field; // JSON string storing the names of the current service's layers and their fields private string m_jsonServiceLayersAndFields = "{}"; #endregion #region IServerObjectExtensionConfigurator Members #region Properties - HtmlElementIds, SupportingJavaScript /// <summary> /// IDs of the controls that define SOE properties /// </summary> public List<string> HtmlElementIds { get { return new List<string>(new string[] { "layersDropDown", "fieldsDropDown" }); } } /// <summary> /// JavaScript to execute when the property page is loaded /// </summary> public string SupportingJavaScript { get { return string.Format(@" // JSON object storing the names of the current service's layers and their fields var layerFieldsMapping = {0}; // ExtensionConfigurator is a global JavaScript object defined by Manager and available to SOE property page // implementations. Here we use it to define the client logic to execute when a new layer is selected. ExtensionConfigurator.OnLayerChanged = function(layersDropDown) {{ // Get the currently selected layer var layerName = layersDropDown.options[layersDropDown.selectedIndex].value; // Get the fields drop down and the number of items in it var fieldsDropDown = document.getElementById('fieldsDropDown'); var len = fieldsDropDown.options ? fieldsDropDown.options.length : 0; // Remove all the drop down's items for(var i=0; i < len; i++) fieldsDropDown.remove(0); // Get the fields for the currently selected layer and populate the fields drop down with them var fieldsArray = layerFieldsMapping[layerName]; if(fieldsArray) {{ for(i=0; i < fieldsArray.length; i++) fieldsDropDown.options.add(new Option(fieldsArray[i], fieldsArray[i])); fieldsDropDown.options[0].selected = true; }} }}", m_jsonServiceLayersAndFields); } } #endregion #region Methods - LoadConfigurator, SaveProperties /// <summary> /// Called when the property page is loaded /// </summary> /// <param name="serverContext">server context for the service</param> /// <param name="ServerObjectProperties">properties of the server object (i.e. service)</param> /// <param name="ExtensionProperties">SOE properties for the current server object</param> /// <param name="InfoProperties">global SOE properties</param> /// <param name="isEnabled">whether the SOE is enabled on the current server object</param> /// <param name="servicesEndPoint">end point for server's web services </param> /// <param name="serviceName">name of the server object</param> /// <returns>An HTML string that defines the property page's UI</returns> public string LoadConfigurator(ESRI.ArcGIS.Server.IServerContext serverContext, System.Collections.Specialized.NameValueCollection ServerObjectProperties, System.Collections.Specialized.NameValueCollection ExtensionProperties, System.Collections.Specialized.NameValueCollection InfoProperties, bool isEnabled, string servicesEndPoint, string serviceName) { // Just return a message if the SOE is not enabled on the current service if (!isEnabled) return ("<span>No Properties to configure</span>"); // Initialize member variables holding the SOE's properties if (!string.IsNullOrEmpty(ExtensionProperties["LayerName"])) m_layer = ExtensionProperties["LayerName"]; if (!string.IsNullOrEmpty(ExtensionProperties["FieldName"])) m_field = ExtensionProperties["FieldName"]; //Container div and table System.Web.UI.HtmlControls.HtmlGenericControl propertiesDiv = new System.Web.UI.HtmlControls.HtmlGenericControl("propertiesDiv"); propertiesDiv.Style[System.Web.UI.HtmlTextWriterStyle.Padding] = "10px"; System.Web.UI.HtmlControls.HtmlTable table = new System.Web.UI.HtmlControls.HtmlTable(); table.CellPadding = table.CellSpacing = 4; propertiesDiv.Controls.Add(table); // Header row System.Web.UI.HtmlControls.HtmlTableRow row = new System.Web.UI.HtmlControls.HtmlTableRow(); table.Rows.Add(row); System.Web.UI.HtmlControls.HtmlTableCell cell = new System.Web.UI.HtmlControls.HtmlTableCell(); row.Cells.Add(cell); cell.ColSpan = 2; System.Web.UI.WebControls.Label lbl = new System.Web.UI.WebControls.Label(); lbl.Text = "Choose the layer and field."; cell.Controls.Add(lbl); // Layer drop-down row row = new System.Web.UI.HtmlControls.HtmlTableRow(); table.Rows.Add(row); cell = new System.Web.UI.HtmlControls.HtmlTableCell(); row.Cells.Add(cell); lbl = new System.Web.UI.WebControls.Label(); cell.Controls.Add(lbl); lbl.Text = "Layer:"; cell = new System.Web.UI.HtmlControls.HtmlTableCell(); row.Cells.Add(cell); cell.Controls.Add(m_layersDropDown); m_layersDropDown.ID = "layersDropDown"; // Wire the OnLayerChanged JavaScript function (defined in SupportingJavaScript) to fire when a new layer is selected m_layersDropDown.Attributes["onchange"] = "ExtensionConfigurator.OnLayerChanged(this);"; // Fields drop-down row row = new System.Web.UI.HtmlControls.HtmlTableRow(); table.Rows.Add(row); cell = new System.Web.UI.HtmlControls.HtmlTableCell(); row.Cells.Add(cell); lbl = new System.Web.UI.WebControls.Label(); cell.Controls.Add(lbl); lbl.Text = "Fields:"; cell = new System.Web.UI.HtmlControls.HtmlTableCell(); row.Cells.Add(cell); cell.Controls.Add(m_fieldsDropDown); m_fieldsDropDown.ID = "fieldsDropDown"; // Get the path of the underlying map document and use it to populate the properties drop-downs string fileName = ServerObjectProperties["FilePath"]; populateDropDowns(serverContext, fileName); // Render and return the HTML for the container div System.IO.StringWriter stringWriter = new System.IO.StringWriter(); System.Web.UI.HtmlTextWriter htmlWriter = new System.Web.UI.HtmlTextWriter(stringWriter); propertiesDiv.RenderControl(htmlWriter); string html = stringWriter.ToString(); stringWriter.Close(); return html; } /// <summary> /// Persists the server object extension's properties /// </summary> /// <param name="serverContext">the server context of the service</param> /// <param name="Request">values of the controls specified in HtmlElementIds</param> /// <param name="isEnabled">whether the extension is enabled on the current server object</param> /// <param name="ExtensionProperties">collection of server object properties to save</param> /// <param name="InfoProperties">collection of global extension properties to save</param> public void SaveProperties(ESRI.ArcGIS.Server.IServerContext serverContext, System.Collections.Specialized.NameValueCollection Request, bool isEnabled, out System.Collections.Specialized.NameValueCollection ExtensionProperties, out System.Collections.Specialized.NameValueCollection InfoProperties) { // Instantiate the properties collection and define the LayerName and FieldName properties ExtensionProperties = new System.Collections.Specialized.NameValueCollection(); string layerName = Request["layersDropDown"]; if (!string.IsNullOrEmpty(layerName)) ExtensionProperties.Add("LayerName", layerName); string fieldName = Request["fieldsDropDown"]; if (!string.IsNullOrEmpty(fieldName)) ExtensionProperties.Add("FieldName", fieldName); InfoProperties = new System.Collections.Specialized.NameValueCollection(); } #endregion #endregion // Retrieves the current service's layers and fields and populates the property page UI with them private void populateDropDowns(ESRI.ArcGIS.Server.IServerContext serverContext, string mapDocPath) { ESRI.ArcGIS.Carto.IMapDocument mapDoc = null; ESRI.ArcGIS.Carto.IMap map = null; try { // Get the map underlying the current service mapDoc = (ESRI.ArcGIS.Carto.IMapDocument)serverContext.CreateObject("esriCarto.MapDocument"); mapDoc.Open(mapDocPath, null); map = mapDoc.get_Map(0); // Get IGeoFeatureLayers from the map ESRI.ArcGIS.esriSystem.UID id = (ESRI.ArcGIS.esriSystem.UID)serverContext.CreateObject("esriSystem.UID"); id.Value = "{E156D7E5-22AF-11D3-9F99-00C04F6BC78E}"; ESRI.ArcGIS.Carto.IEnumLayer enumLayer = map.get_Layers(id, true); // Loop through each layer and the fields for that layer. For each simple polygon layer, add its name and // a list containing the names of all its fields to the dictionary. ESRI.ArcGIS.Carto.IFeatureLayer featureLayer = (ESRI.ArcGIS.Carto.IFeatureLayer)enumLayer.Next(); Dictionary<string, List<string>> layersAndFieldsDictionary = new Dictionary<string, List<string>>(); bool addFields = false; while (featureLayer != null) { List<string> fieldsList = new List<string>(); // Check whether the current layer is a simple polygon layer if (featureLayer.FeatureClass.ShapeType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon && featureLayer.FeatureClass.FeatureType == ESRI.ArcGIS.Geodatabase.esriFeatureType.esriFTSimple) { // Add the layer to the layers drop-down m_layersDropDown.Items.Add(featureLayer.Name); // Check whether the fields drop-down should be initialized with fields from the current loop layer if (featureLayer.Name == m_layer || (m_layer == null && m_layersDropDown.Items.Count == 1)) addFields = true; // Add each field to the fields list ESRI.ArcGIS.Geodatabase.IFields fields = featureLayer.FeatureClass.Fields; for (int i = 0; i < fields.FieldCount; i++) { ESRI.ArcGIS.Geodatabase.IField field = fields.get_Field(i); fieldsList.Add(field.Name); // If the current loop layer is the first, add its fields to the fields drop-down if (addFields) m_fieldsDropDown.Items.Add(field.Name); } addFields = false; // Add the layer name and its fields to the dictionary layersAndFieldsDictionary.Add(featureLayer.Name, fieldsList); } featureLayer = (ESRI.ArcGIS.Carto.IFeatureLayer)enumLayer.Next(); } // Serialize the dictionary containing the layer and field names to JSON System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); m_jsonServiceLayersAndFields = serializer.Serialize(layersAndFieldsDictionary); // If a layer is defined for the extension, select it in the layers drop-down. if (m_layer != null) m_layersDropDown.SelectedValue = m_layer; // If a field is defined for the extension, select it in the fields drop-down. if (m_field != null) m_fieldsDropDown.SelectedValue = m_field; } catch { } finally { // Close the service's map document if (mapDoc != null) mapDoc.Close(); map = null; } } } }