About the Find near features REST SOE Sample
[C#]
FindNearFeaturesRestSOE_VBNet.cs
[Visual Basic .NET]
FindNearFeaturesRestSOE_VBNet.vb
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Collections.Specialized
Imports System.Text
Imports System.Runtime.InteropServices
Imports System.EnterpriseServices
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.Server
Imports ESRI.ArcGIS.Geometry
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.SOESupport
Namespace FindNearFeaturesRestSOE_VBNet
<ComVisible(True), Guid("3350AAE7-4F56-46AC-876B-A960776C1286"), ClassInterface(ClassInterfaceType.None)> _
Public Class FindNearFeaturesRESTSOE_VBNet
Inherits ServicedComponent
Implements IServerObjectExtension, IObjectConstruct, IRESTRequestHandler
Private Const c_SOEName As String = "FindNearFeaturesRESTSOE_VBNet"
Private Const c_CapabilityGetInfo As String = "GetInfo"
Private Const c_CapabilityFindFeatures As String = "FindFeatures"
Private configProps As IPropertySet
Private serverObjectHelper As IServerObjectHelper
Private logger As ServerLogger
Private reqHandler As IRESTRequestHandler
Public Sub New()
logger = New ServerLogger()
Dim rootResource As RestResource = CreateRestSchema()
Dim restImpl As New SoeRestImpl(c_SOEName, rootResource)
reqHandler = CType(restImpl, IRESTRequestHandler)
End Sub
Private Function CreateRestSchema() As RestResource
Dim soeResource As New RestResource("FindNearFeaturesRESTSOE_VBNet", False, AddressOf SOE, c_CapabilityGetInfo)
Dim customLayerResource As New RestResource("customLayers", True, AddressOf CustomLayer, c_CapabilityGetInfo)
Dim findNearFeatsOp As New RestOperation("findNearFeatures", New String() {"location", "distance"}, New String() {"json"}, AddressOf FindNearFeatures, c_CapabilityFindFeatures)
customLayerResource.operations.Add(findNearFeatsOp)
soeResource.resources.Add(customLayerResource)
Return soeResource
End Function
#Region "IServerObjectExtension"
Public Sub Init(ByVal pSOH As IServerObjectHelper) Implements IServerObjectExtension.Init
serverObjectHelper = pSOH
End Sub
Public Sub Shutdown() Implements IServerObjectExtension.Shutdown
serverObjectHelper = Nothing
End Sub
#End Region
#Region "IObjectConstruct"
Public Overloads Sub Construct(ByVal props As IPropertySet) Implements IObjectConstruct.Construct
Dim timer As New AutoTimer()
logger.LogMessage(ServerLogger.msgType.infoSimple, "Construct", -1, c_SOEName & " Construct has started.")
configProps = props
'TODO - put any construct-time logic here
logger.LogMessage(ServerLogger.msgType.infoSimple, "Construct", -1, timer.Elapsed, c_SOEName & " Construct has completed.")
End Sub
#End Region
#Region "IRESTRequestHandler"
Public Function GetSchema() As String Implements IRESTRequestHandler.GetSchema
Return reqHandler.GetSchema()
End Function
Public Function HandleRESTRequest(ByVal Capabilities As String, ByVal resourceName As String, ByVal operationName As String, ByVal operationInput As String, ByVal outputFormat As String, ByVal requestProperties As String, <System.Runtime.InteropServices.Out()> ByRef responseProperties As String) As Byte() Implements IRESTRequestHandler.HandleRESTRequest
Return reqHandler.HandleRESTRequest(Capabilities, resourceName, operationName, operationInput, outputFormat, requestProperties, responseProperties)
End Function
#End Region
#Region "Resource Handlers"
Private Function SOE(ByVal boundVariables As NameValueCollection, ByVal outputFormat As String, ByVal requestProperties As String, <System.Runtime.InteropServices.Out()> ByRef responseProperties As String) As Byte()
responseProperties = Nothing
Dim layerInfos() As CustomLayerInfo_VBNet = GetLayerInfos()
Dim jos(layerInfos.Length - 1) As JsonObject
For i As Integer = 0 To layerInfos.Length - 1
jos(i) = layerInfos(i).ToJsonObject()
Next i
Dim result As New JsonObject()
result.AddArray("customLayers", jos)
Dim json As String = result.ToJson()
Return Encoding.UTF8.GetBytes(json)
End Function
'customLayers/{customLayersID}
'returns json with simplified layerinfo (name, id, extent)
Private Function CustomLayer(ByVal boundVariables As NameValueCollection, ByVal outputFormat As String, ByVal requestProperties As String, <System.Runtime.InteropServices.Out()> ByRef responseProperties As String) As Byte()
responseProperties = Nothing
'layerID
Dim layerID As Integer = Convert.ToInt32(boundVariables("customLayersID"))
'execute
Dim layerInfo As CustomLayerInfo_VBNet = GetLayerInfo(layerID)
Dim json As String = layerInfo.ToJsonObject().ToJson()
Return Encoding.UTF8.GetBytes(json)
End Function
#End Region
#Region "Operation Handlers"
'customLayers/{customLayersID}/findNearFeatures?location=<jsonPoint>&distance=<double>
Private Function FindNearFeatures(ByVal boundVariables As NameValueCollection, ByVal operationInput As JsonObject, ByVal outputFormat As String, ByVal requestProperties As String, <System.Runtime.InteropServices.Out()> ByRef responseProperties As String) As Byte()
responseProperties = Nothing
'layerID
Dim layerID As Integer = Convert.ToInt32(boundVariables("customLayersID"))
'location
Dim jsonPoint As JsonObject
If (Not operationInput.TryGetJsonObject("location", jsonPoint)) Then
Throw New ArgumentNullException("location")
End If
Dim location As IPoint = TryCast(ESRI.ArcGIS.SOESupport.Conversion.ToGeometry(jsonPoint, esriGeometryType.esriGeometryPoint), IPoint)
If location Is Nothing Then
Throw New ArgumentException("FindNearFeatures: invalid location", "location")
End If
'distance
Dim distance? As Double
If (Not operationInput.TryGetAsDouble("distance", distance)) OrElse (Not distance.HasValue) Then
Throw New ArgumentException("FindNearFeatures: invalid distance", "distance")
End If
'execute asking the map server to generate json directly (not an IRecordSet)
Dim result() As Byte = FindNearFeatures(layerID, location, distance.Value)
Return result
End Function
#End Region
#Region "Business Methods"
Private Function GetLayerInfo(ByVal layerID As Integer) As CustomLayerInfo_VBNet
If layerID < 0 Then
Throw New ArgumentOutOfRangeException("layerID")
End If
Dim mapServer As IMapServer3 = TryCast(serverObjectHelper.ServerObject, IMapServer3)
If mapServer Is Nothing Then
Throw New Exception("Unable to access the map server.")
End If
Dim layerInfo As IMapLayerInfo
Dim layerInfos As IMapLayerInfos = mapServer.GetServerInfo(mapServer.DefaultMapName).MapLayerInfos
Dim c As Long = layerInfos.Count
For i As Integer = 0 To c - 1
layerInfo = layerInfos.Element(i)
If layerInfo.ID = layerID Then
Return New CustomLayerInfo_VBNet(layerInfo)
End If
Next i
Throw New ArgumentOutOfRangeException("layerID")
End Function
Private Function GetLayerInfos() As CustomLayerInfo_VBNet()
Dim mapServer As IMapServer3 = TryCast(serverObjectHelper.ServerObject, IMapServer3)
If mapServer Is Nothing Then
Throw New Exception("Unable to access the map server.")
End If
Dim msInfo As IMapServerInfo = mapServer.GetServerInfo(mapServer.DefaultMapName)
Dim layerInfos As IMapLayerInfos = msInfo.MapLayerInfos
Dim c As Integer = layerInfos.Count
Dim customLayerInfos(c - 1) As CustomLayerInfo_VBNet
For i As Integer = 0 To c - 1
Dim layerInfo As IMapLayerInfo = layerInfos.Element(i)
customLayerInfos(i) = New CustomLayerInfo_VBNet(layerInfo)
Next i
Return customLayerInfos
End Function
Private Function FindNearFeatures(ByVal layerID As Integer, ByVal location As IPoint, ByVal distance As Double) As Byte()
If layerID < 0 Then
Throw New ArgumentOutOfRangeException("layerID")
End If
If distance <= 0.0 Then
Throw New ArgumentOutOfRangeException("distance")
End If
Dim mapServer As IMapServer3 = TryCast(serverObjectHelper.ServerObject, IMapServer3)
If mapServer Is Nothing Then
Throw New Exception("Unable to access the map server.")
End If
Dim queryGeometry As IGeometry = (CType(location, ITopologicalOperator)).Buffer(distance)
Dim filter As ISpatialFilter = New SpatialFilterClass()
filter.Geometry = queryGeometry
filter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects
Dim resultOptions As IQueryResultOptions = New QueryResultOptionsClass()
resultOptions.Format = esriQueryResultFormat.esriQueryResultJsonAsMime
Dim timer As New AutoTimer() 'starts the timer
Dim tableDesc As IMapTableDescription = GetTableDesc(mapServer, layerID)
logger.LogMessage(ServerLogger.msgType.infoDetailed, "FindNearFeatures", -1, timer.Elapsed, "Finding table description elapsed this much.")
Dim result As IQueryResult = mapServer.QueryData(mapServer.DefaultMapName, tableDesc, filter, resultOptions)
Return result.MimeData
End Function
Private Function GetTableDesc(ByVal mapServer As IMapServer3, ByVal layerID As Integer) As IMapTableDescription
Dim layerDescs As ILayerDescriptions = mapServer.GetServerInfo(mapServer.DefaultMapName).DefaultMapDescription.LayerDescriptions
Dim c As Long = layerDescs.Count
For i As Integer = 0 To c - 1
Dim layerDesc As ILayerDescription3 = CType(layerDescs.Element(i), ILayerDescription3)
If layerDesc.ID = layerID Then
layerDesc.LayerResultOptions = New LayerResultOptionsClass()
layerDesc.LayerResultOptions.GeometryResultOptions = New GeometryResultOptionsClass()
layerDesc.LayerResultOptions.GeometryResultOptions.DensifyGeometries = True
Return CType(layerDesc, IMapTableDescription)
End If
Next i
Throw New ArgumentOutOfRangeException("layerID")
End Function
#End Region
End Class
End Namespace