SpatialQuerySOE.Manager_VBNet\Configurator.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 Imports System.Collections.Generic Imports System.Text Namespace SpatialQuerySOE.Manager_VBNet ''' <summary> ''' SpatialQuerySOE property configuration page for Manager. Defines the appearance and behavior of the page. ''' </summary> Public Class Configurator Implements ESRI.ArcGIS.ServerManager.IServerObjectExtensionConfigurator #Region "Member variables" ' Controls to enable configuration of the SOE's layer and field Private m_layersDropDown As New System.Web.UI.WebControls.DropDownList() Private m_fieldsDropDown As New System.Web.UI.WebControls.DropDownList() ' The SOE's current layer Private m_layer As String ' The SOE's current field Private m_field As String ' JSON string storing the names of the current service's layers and their fields Private m_jsonServiceLayersAndFields As String = "{}" #End Region #Region "IServerObjectExtensionConfigurator Members" #Region "Properties - HtmlElementIds, SupportingJavaScript" ''' <summary> ''' IDs of the controls that define SOE properties ''' </summary> 'Public ReadOnly Property HtmlElementIds() As List(Of String) ' Get ' Return New List(Of String)(New String() {"layersDropDown", "fieldsDropDown"}) ' End Get 'End Property Public ReadOnly Property HtmlElementIds1() As System.Collections.Generic.List(Of String) Implements ESRI.ArcGIS.ServerManager.IServerObjectExtensionConfigurator.HtmlElementIds Get Return New List(Of String)(New String() {"layersDropDown", "fieldsDropDown"}) End Get End Property ''' <summary> ''' JavaScript to execute when the property page is loaded ''' </summary> Public ReadOnly Property SupportingJavaScript() As String Implements ESRI.ArcGIS.ServerManager.IServerObjectExtensionConfigurator.SupportingJavaScript Get Return String.Format("" & ControlChars.CrLf & " // JSON object storing the names of the current service's layers and their fields" & ControlChars.CrLf & " var layerFieldsMapping = {0};" & ControlChars.CrLf & ControlChars.CrLf & " // ExtensionConfigurator is a global JavaScript object defined by Manager and available to SOE property page" & ControlChars.CrLf & " // implementations. Here we use it to define the client logic to execute when a new layer is selected." & ControlChars.CrLf & " ExtensionConfigurator.OnLayerChanged = function(layersDropDown) {{" & ControlChars.CrLf & " // Get the currently selected layer " & ControlChars.CrLf & " var layerName = layersDropDown.options[layersDropDown.selectedIndex].value;" & ControlChars.CrLf & " // Get the fields drop down and the number of items in it" & ControlChars.CrLf & " var fieldsDropDown = document.getElementById('fieldsDropDown'); " & ControlChars.CrLf & " var len = fieldsDropDown.options ? fieldsDropDown.options.length : 0;" & ControlChars.CrLf & ControlChars.CrLf & " // Remove all the drop down's items" & ControlChars.CrLf & " for(var i=0; i < len; i++)" & ControlChars.CrLf & " fieldsDropDown.remove(0);" & ControlChars.CrLf & ControlChars.CrLf & " // Get the fields for the currently selected layer and populate the fields drop down with them" & ControlChars.CrLf & " var fieldsArray = layerFieldsMapping[layerName];" & ControlChars.CrLf & " if(fieldsArray)" & ControlChars.CrLf & " {{ " & ControlChars.CrLf & " for(i=0; i < fieldsArray.length; i++)" & ControlChars.CrLf & " fieldsDropDown.options.add(new Option(fieldsArray[i], fieldsArray[i]));" & ControlChars.CrLf & ControlChars.CrLf & " fieldsDropDown.options[0].selected = true;" & ControlChars.CrLf & " }}" & ControlChars.CrLf & " }}", m_jsonServiceLayersAndFields) End Get End Property #End Region #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 Function LoadConfigurator(ByVal serverContext As ESRI.ArcGIS.Server.IServerContext, ByVal ServerObjectProperties As System.Collections.Specialized.NameValueCollection, ByVal ExtensionProperties As System.Collections.Specialized.NameValueCollection, ByVal InfoProperties As System.Collections.Specialized.NameValueCollection, ByVal isEnabled As Boolean, ByVal servicesEndPoint As String, ByVal serviceName As String) As String Implements ESRI.ArcGIS.ServerManager.IServerObjectExtensionConfigurator.LoadConfigurator ' Just return a message if the SOE is not enabled on the current service If (Not isEnabled) Then Return ("<span>No Properties to configure</span>") End If ' Initialize member variables holding the SOE's properties If (Not String.IsNullOrEmpty(ExtensionProperties("LayerName"))) Then m_layer = ExtensionProperties("LayerName") End If If (Not String.IsNullOrEmpty(ExtensionProperties("FieldName"))) Then m_field = ExtensionProperties("FieldName") End If 'Container div and table Dim propertiesDiv As New System.Web.UI.HtmlControls.HtmlGenericControl("propertiesDiv") propertiesDiv.Style(System.Web.UI.HtmlTextWriterStyle.Padding) = "10px" Dim table As New System.Web.UI.HtmlControls.HtmlTable() table.CellSpacing = 4 table.CellPadding = table.CellSpacing propertiesDiv.Controls.Add(table) ' Header row Dim row As New System.Web.UI.HtmlControls.HtmlTableRow() table.Rows.Add(row) Dim cell As New System.Web.UI.HtmlControls.HtmlTableCell() row.Cells.Add(cell) cell.ColSpan = 2 Dim lbl As 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 Dim fileName As String = ServerObjectProperties("FilePath") populateDropDowns(serverContext, fileName) ' Render and return the HTML for the container div Dim stringWriter As New System.IO.StringWriter() Dim htmlWriter As New System.Web.UI.HtmlTextWriter(stringWriter) propertiesDiv.RenderControl(htmlWriter) Dim html As String = stringWriter.ToString() stringWriter.Close() Return html End Function ''' <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 Sub SaveProperties(ByVal serverContext As ESRI.ArcGIS.Server.IServerContext, ByVal Request As System.Collections.Specialized.NameValueCollection, ByVal isEnabled As Boolean, <System.Runtime.InteropServices.Out()> ByRef ExtensionProperties As System.Collections.Specialized.NameValueCollection, <System.Runtime.InteropServices.Out()> ByRef InfoProperties As System.Collections.Specialized.NameValueCollection) Implements ESRI.ArcGIS.ServerManager.IServerObjectExtensionConfigurator.SaveProperties ' Instantiate the properties collection and define the LayerName and FieldName properties ExtensionProperties = New System.Collections.Specialized.NameValueCollection() Dim layerName As String = Request("layersDropDown") If (Not String.IsNullOrEmpty(layerName)) Then ExtensionProperties.Add("LayerName", layerName) End If Dim fieldName As String = Request("fieldsDropDown") If (Not String.IsNullOrEmpty(fieldName)) Then ExtensionProperties.Add("FieldName", fieldName) End If InfoProperties = New System.Collections.Specialized.NameValueCollection() End Sub #End Region #End Region ' Retrieves the current service's layers and fields and populates the property page UI with them Private Sub populateDropDowns(ByVal serverContext As ESRI.ArcGIS.Server.IServerContext, ByVal mapDocPath As String) Dim mapDoc As ESRI.ArcGIS.Carto.IMapDocument = Nothing Dim map As ESRI.ArcGIS.Carto.IMap = Nothing Try ' Get the map underlying the current service mapDoc = CType(serverContext.CreateObject("esriCarto.MapDocument"), ESRI.ArcGIS.Carto.IMapDocument) mapDoc.Open(mapDocPath, Nothing) map = mapDoc.Map(0) ' Get IGeoFeatureLayers from the map Dim id As ESRI.ArcGIS.esriSystem.UID = CType(serverContext.CreateObject("esriSystem.UID"), ESRI.ArcGIS.esriSystem.UID) id.Value = "{E156D7E5-22AF-11D3-9F99-00C04F6BC78E}" Dim enumLayer As ESRI.ArcGIS.Carto.IEnumLayer = map.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. Dim featureLayer As ESRI.ArcGIS.Carto.IFeatureLayer = CType(enumLayer.Next(), ESRI.ArcGIS.Carto.IFeatureLayer) Dim layersAndFieldsDictionary As New Dictionary(Of String, List(Of String))() Dim addFields As Boolean = False Do While featureLayer IsNot Nothing Dim fieldsList As New List(Of String)() ' Check whether the current layer is a simple polygon layer If featureLayer.FeatureClass.ShapeType = ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon AndAlso featureLayer.FeatureClass.FeatureType = ESRI.ArcGIS.Geodatabase.esriFeatureType.esriFTSimple Then ' 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 OrElse (m_layer Is Nothing AndAlso m_layersDropDown.Items.Count = 1) Then addFields = True End If ' Add each field to the fields list Dim fields As ESRI.ArcGIS.Geodatabase.IFields = featureLayer.FeatureClass.Fields For i As Integer = 0 To fields.FieldCount - 1 Dim field As ESRI.ArcGIS.Geodatabase.IField = fields.Field(i) fieldsList.Add(field.Name) ' If the current loop layer is the first, add its fields to the fields drop-down If addFields Then m_fieldsDropDown.Items.Add(field.Name) End If Next i addFields = False ' Add the layer name and its fields to the dictionary layersAndFieldsDictionary.Add(featureLayer.Name, fieldsList) End If featureLayer = CType(enumLayer.Next(), ESRI.ArcGIS.Carto.IFeatureLayer) Loop ' Serialize the dictionary containing the layer and field names to JSON Dim serializer As 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 IsNot Nothing Then m_layersDropDown.SelectedValue = m_layer End If ' If a field is defined for the extension, select it in the fields drop-down. If m_field IsNot Nothing Then m_fieldsDropDown.SelectedValue = m_field End If Catch Finally ' Close the service's map document If mapDoc IsNot Nothing Then mapDoc.Close() End If map = Nothing End Try End Sub End Class End Namespace