ArcGIS Geocode Search service
ArcGIS_Geocode_Search_VBNet\App_Code\Utility.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
Public Class Utility
    ''' <summary>
    ''' Creates a spatial reference that will minimize distortion near the input point.  Ideal for operations 
    ''' that will derive geometry based on that point (e.g. buffer).
    ''' </summary>
    ''' <param name="agsSoapPoint">Point to use as the center of the spatial reference's datum</param>
    ''' <param name="geometryServerDcomProxy">Geometry service to use in creating the spatial reference</param>
    Public Shared Function CreateOperationSpatialReference(ByVal agsSoapPoint As ESRI.ArcGIS.ADF.ArcGISServer.PointN, ByVal geometryServerDcomProxy As ESRI.ArcGIS.ADF.ArcGISServer.GeometryServerDcomProxy) As ESRI.ArcGIS.ADF.ArcGISServer.SpatialReference
        ' If the input point's spatial reference uses a projected coordinate system, project the point to a 
        ' geographic coordinate system (WGS 1984 in this case).  We do this because the point's coordinates 
        ' will be used to initialize the datum of the operation spatial reference
        If TypeOf agsSoapPoint.SpatialReference Is ESRI.ArcGIS.ADF.ArcGISServer.ProjectedCoordinateSystem Then
            ' Create an ArcGIS Server spatial reference initalized to use the WGS 1984 coordinate system
            Dim agsSoapGeographicSpatialReference As ESRI.ArcGIS.ADF.ArcGISServer.SpatialReference = New ESRI.ArcGIS.ADF.ArcGISServer.GeographicCoordinateSystem()
            agsSoapGeographicSpatialReference.WKID = 4326
            agsSoapGeographicSpatialReference.WKIDSpecified = True

            ' Place the input point in an array for the project operation
            Dim agsSoapInputGeometryArray As ESRI.ArcGIS.ADF.ArcGISServer.Geometry() = New ESRI.ArcGIS.ADF.ArcGISServer.Geometry(0) {}
            agsSoapInputGeometryArray(0) = agsSoapPoint

            ' Execute the projection
            Dim agsSoapOutputGeometryArray As ESRI.ArcGIS.ADF.ArcGISServer.Geometry() = geometryServerDcomProxy.Project(agsSoapPoint.SpatialReference, agsSoapGeographicSpatialReference, True, Nothing, Nothing, agsSoapInputGeometryArray)

            ' Retrieve the projected point from the results array
            agsSoapPoint = TryCast(agsSoapOutputGeometryArray(0), ESRI.ArcGIS.ADF.ArcGISServer.PointN)
        End If

        ' Create the definition string for the operation spatial reference's coordinate system.  We will use 
        ' the Hotine Oblique Mercator coordinate system because it lends itself well to minimizing operational
        ' distortion anywhere on the earth
        Dim hotineObliqueMercatorDefinition As String = "" & ControlChars.CrLf & "            PROJCS[""World_Hotine""," & ControlChars.CrLf & "            GEOGCS[""GCS_WGS_1984""," & ControlChars.CrLf & "            DATUM[""D_WGS_1984""," & ControlChars.CrLf & "            SPHEROID[""WGS_1984"",6378137.0,298.257223563]]," & ControlChars.CrLf & "            PRIMEM[""Greenwich"",0.0]," & ControlChars.CrLf & "            UNIT[""Degree"",0.0174532925199433]]," & ControlChars.CrLf & "            PROJECTION[""Hotine_Oblique_Mercator_Two_Point_Natural_Origin""]," & ControlChars.CrLf & "            PARAMETER[""False_Easting"",0.0]," & ControlChars.CrLf & "            PARAMETER[""False_Northing"",0.0]," & ControlChars.CrLf & "            PARAMETER[""Latitude_Of_1st_Point"",{0}],   " & ControlChars.CrLf & "            PARAMETER[""Latitude_Of_2nd_Point"",{1}]," & ControlChars.CrLf & "            PARAMETER[""Scale_Factor"",1.0]," & ControlChars.CrLf & "            PARAMETER[""Longitude_Of_1st_Point"",{2}]," & ControlChars.CrLf & "            PARAMETER[""Longitude_Of_2nd_Point"",{3}]," & ControlChars.CrLf & "            PARAMETER[""Latitude_Of_Center"",{4}]," & ControlChars.CrLf & "            UNIT[""Meter"",1.0]]"

        ' Specify the coordinate system's datum parameters based on the projected point's coordinates
        Dim customHotineObliqueCylindricalMercator As String = String.Format(hotineObliqueMercatorDefinition, agsSoapPoint.Y - 1, agsSoapPoint.Y + 1, agsSoapPoint.X - 1, agsSoapPoint.X + 1, agsSoapPoint.Y)

        ' Create the spatial reference
        Dim agsSoapBufferSpatialReference As ESRI.ArcGIS.ADF.ArcGISServer.SpatialReference = geometryServerDcomProxy.FindSRByWKT(customHotineObliqueCylindricalMercator, Nothing, True, True)

        Return agsSoapBufferSpatialReference
    End Function

    ''' <summary>
    ''' Creates a spatial reference that will minimize distortion near the input point.  Ideal for operations 
    ''' that will derive geometry based on that point (e.g. buffer).
    ''' </summary>
    ''' <param name="aoPoint">Point to use as the center of the spatial reference's datum</param>
    ''' <param name="geometryServer">Geometry service to use in creating the spatial reference</param>
    Public Shared Function CreateOperationSpatialReference(ByVal aoPoint As ESRI.ArcGIS.Geometry.IPoint, ByVal geometryServerContext As ESRI.ArcGIS.Server.IServerContext) As ESRI.ArcGIS.Geometry.ISpatialReference
        Dim geometryServer As ESRI.ArcGIS.Geometry.IGeometryServer = TryCast(geometryServerContext.ServerObject, ESRI.ArcGIS.Geometry.IGeometryServer)
        Dim aoGeographicPoint As ESRI.ArcGIS.Geometry.IPoint = Nothing

        ' If the input point's spatial reference uses a projected coordinate system, project the point to a 
        ' geographic coordinate system (WGS 1984 in this case).  We do this because the point's coordinates 
        ' will be used to define the projection parameters of the operations spatial reference.
        If TypeOf aoPoint.SpatialReference Is ESRI.ArcGIS.Geometry.ProjectedCoordinateSystem Then
            ' Create an ArcGIS Server spatial reference initalized to use the WGS 1984 coordinate system
            Dim aoGeographicSpatialReference As ESRI.ArcGIS.Geometry.ISpatialReference = geometryServer.FindSRByWKID(Nothing, 4326, -1, True, True)

            ' Store the point in an array for passing to the project operation
            Dim aoInputGeometryArray As ESRI.ArcGIS.Geometry.IGeometryArray = TryCast(geometryServerContext.CreateObject("esriGeometry.GeometryArray"), ESRI.ArcGIS.Geometry.IGeometryArray)
            aoInputGeometryArray.Add(aoPoint)

            ' Create a transformation object to specify the GCS transformation
            Dim spatialReferenceFactory As ESRI.ArcGIS.Geometry.ISpatialReferenceFactory = CType(geometryServerContext.CreateObject("esriGeometry.SpatialReferenceEnvironment"), ESRI.ArcGIS.Geometry.ISpatialReferenceFactory)

            Dim aoTransformation As ESRI.ArcGIS.Geometry.ITransformation = spatialReferenceFactory.CreateGeoTransformation(1188)

            ' Execute the project operation
            Dim aoOutputGeomeryArray As ESRI.ArcGIS.Geometry.IGeometryArray = geometryServer.Project(aoPoint.SpatialReference, aoGeographicSpatialReference, ESRI.ArcGIS.Geometry.esriTransformDirection.esriTransformForward, aoTransformation, Nothing, aoInputGeometryArray)

            ' Retrieve the projected point from the operation results
            aoGeographicPoint = TryCast(aoOutputGeomeryArray.Element(0), ESRI.ArcGIS.Geometry.IPoint)
        End If

        ' Create the definition string for the operation spatial reference's coordinate system.  We will use 
        ' the Hotine Oblique Mercator coordinate system because it lends itself well to minimizing operational
        ' distortion anywhere on the earth
        Dim hotineObliqueMercatorDefinition As String = "" & ControlChars.CrLf & "            PROJCS[""World_Hotine""," & ControlChars.CrLf & "            GEOGCS[""GCS_WGS_1984""," & ControlChars.CrLf & "            DATUM[""D_WGS_1984""," & ControlChars.CrLf & "            SPHEROID[""WGS_1984"",6378137.0,298.257223563]]," & ControlChars.CrLf & "            PRIMEM[""Greenwich"",0.0]," & ControlChars.CrLf & "            UNIT[""Degree"",0.0174532925199433]]," & ControlChars.CrLf & "            PROJECTION[""Hotine_Oblique_Mercator_Two_Point_Natural_Origin""]," & ControlChars.CrLf & "            PARAMETER[""False_Easting"",0.0]," & ControlChars.CrLf & "            PARAMETER[""False_Northing"",0.0]," & ControlChars.CrLf & "            PARAMETER[""Latitude_Of_1st_Point"",{0}],   " & ControlChars.CrLf & "            PARAMETER[""Latitude_Of_2nd_Point"",{1}]," & ControlChars.CrLf & "            PARAMETER[""Scale_Factor"",1.0]," & ControlChars.CrLf & "            PARAMETER[""Longitude_Of_1st_Point"",{2}]," & ControlChars.CrLf & "            PARAMETER[""Longitude_Of_2nd_Point"",{3}]," & ControlChars.CrLf & "            PARAMETER[""Latitude_Of_Center"",{4}]," & ControlChars.CrLf & "            UNIT[""Meter"",1.0]]"

        ' Specify the coordinate system's datum parameters based on the projected point's coordinates
        Dim customHotineObliqueCylindricalMercator As String = String.Format(hotineObliqueMercatorDefinition, aoGeographicPoint.Y - 1, aoGeographicPoint.Y + 1, aoGeographicPoint.X - 1, aoGeographicPoint.X + 1, aoGeographicPoint.Y)

        ' Create the spatial reference
        Dim aoOperationSpatialReference As ESRI.ArcGIS.Geometry.ISpatialReference = geometryServer.FindSRByWKT(customHotineObliqueCylindricalMercator, Nothing, True, True)

        Return aoOperationSpatialReference
    End Function

    ''' <summary>
    ''' Returns an ArcGIS Server LinearUnit corresponding to the passed in esriUnits enumeration
    ''' </summary>
    ''' <param name="unitType"></param>
    ''' <returns></returns>
    Public Shared Function ConvertUnitType(ByVal unitType As ESRI.ArcGIS.ADF.ArcGISServer.esriUnits) As ESRI.ArcGIS.ADF.ArcGISServer.LinearUnit
        ' Instantiate an ArcGI Server linear unit and specify its WKID (well-known identifier) based on 
        ' the passed-in enumeration
        Dim linearUnit As ESRI.ArcGIS.ADF.ArcGISServer.LinearUnit = New ESRI.ArcGIS.ADF.ArcGISServer.LinearUnit()
        Select Case unitType
            Case ESRI.ArcGIS.ADF.ArcGISServer.esriUnits.esriCentimeters
                linearUnit.WKID = 109006
            Case ESRI.ArcGIS.ADF.ArcGISServer.esriUnits.esriDecimalDegrees
                linearUnit.WKID = 9102
            Case ESRI.ArcGIS.ADF.ArcGISServer.esriUnits.esriDecimeters
                linearUnit.WKID = 109005
            Case ESRI.ArcGIS.ADF.ArcGISServer.esriUnits.esriFeet
                linearUnit.WKID = 9003
            Case ESRI.ArcGIS.ADF.ArcGISServer.esriUnits.esriInches
                linearUnit.WKID = 109008
            Case ESRI.ArcGIS.ADF.ArcGISServer.esriUnits.esriKilometers
                linearUnit.WKID = 9036
            Case ESRI.ArcGIS.ADF.ArcGISServer.esriUnits.esriMeters
                linearUnit.WKID = 9001
            Case ESRI.ArcGIS.ADF.ArcGISServer.esriUnits.esriMiles
                linearUnit.WKID = 9035
            Case ESRI.ArcGIS.ADF.ArcGISServer.esriUnits.esriMillimeters
                linearUnit.WKID = 109007
            Case ESRI.ArcGIS.ADF.ArcGISServer.esriUnits.esriNauticalMiles
                linearUnit.WKID = 9030
            Case ESRI.ArcGIS.ADF.ArcGISServer.esriUnits.esriYards
                linearUnit.WKID = 109002
        End Select

        linearUnit.WKIDSpecified = True
        Return linearUnit
    End Function

    ''' <summary>
    ''' Returns an ArcObjects IUnit corresponding to the passed in esriUnits enumeration
    ''' </summary>
    ''' <param name="unitType"></param>
    ''' <param name="spatialReferenceEnvironment"></param>
    ''' <returns></returns>
    Public Shared Function ConvertUnitType(ByVal unitType As ESRI.ArcGIS.esriSystem.esriUnits, ByVal spatialReferenceEnvironment As ESRI.ArcGIS.Geometry.SpatialReferenceEnvironment) As ESRI.ArcGIS.Geometry.IUnit
        ' Create an ArcObjects IUnit object from a well-known identifier that is determined by the
        ' value of the passed-in enumeration
        Dim linearUnit As ESRI.ArcGIS.Geometry.IUnit = Nothing
        Select Case unitType
            Case ESRI.ArcGIS.esriSystem.esriUnits.esriCentimeters
                linearUnit = spatialReferenceEnvironment.CreateUnit(109006)
            Case ESRI.ArcGIS.esriSystem.esriUnits.esriDecimalDegrees
                linearUnit = spatialReferenceEnvironment.CreateUnit(9102)
            Case ESRI.ArcGIS.esriSystem.esriUnits.esriDecimeters
                linearUnit = spatialReferenceEnvironment.CreateUnit(109005)
            Case ESRI.ArcGIS.esriSystem.esriUnits.esriFeet
                linearUnit = spatialReferenceEnvironment.CreateUnit(9003)
            Case ESRI.ArcGIS.esriSystem.esriUnits.esriInches
                linearUnit = spatialReferenceEnvironment.CreateUnit(109008)
            Case ESRI.ArcGIS.esriSystem.esriUnits.esriKilometers
                linearUnit = spatialReferenceEnvironment.CreateUnit(9036)
            Case ESRI.ArcGIS.esriSystem.esriUnits.esriMeters
                linearUnit = spatialReferenceEnvironment.CreateUnit(9001)
            Case ESRI.ArcGIS.esriSystem.esriUnits.esriMiles
                linearUnit = spatialReferenceEnvironment.CreateUnit(9035)
            Case ESRI.ArcGIS.esriSystem.esriUnits.esriMillimeters
                linearUnit = spatialReferenceEnvironment.CreateUnit(109007)
            Case ESRI.ArcGIS.esriSystem.esriUnits.esriNauticalMiles
                linearUnit = spatialReferenceEnvironment.CreateUnit(9030)
            Case ESRI.ArcGIS.esriSystem.esriUnits.esriYards
                linearUnit = spatialReferenceEnvironment.CreateUnit(109002)
        End Select

        Return linearUnit
    End Function
End Class