Drive Time Analysis
DriveTimeAnalysis_button.vb
' 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.
' 

' 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 at <your ArcGIS Explorer install location>/DeveloperKit/userestrictions.txt.
' 

Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms

Imports ESRI.ArcGISExplorer
Imports ESRI.ArcGISExplorer.Application
Imports ESRI.ArcGISExplorer.Mapping
Imports ESRI.ArcGISExplorer.Geometry
Imports ESRI.ArcGISExplorer.Data
Imports ESRI.ArcGISExplorer.Threading

Imports DriveTimeAnalysisVB.DriveTime

Public Class DriveTimeAnalysis_Button
  Inherits ESRI.ArcGISExplorer.Application.Button

  Private sDriveTimes As String = "3 5"   'Drive times to be used with the sample

  Public Overrides Sub OnClick()

    'Get the active map display
    Dim mapDisp As MapDisplay = ESRI.ArcGISExplorer.Application.Application.ActiveMapDisplay

    'Get a point from the screen to start the analysis from
    Dim startPt As ESRI.ArcGISExplorer.Geometry.Point = mapDisp.TrackPoint()
    If startPt Is Nothing Then
      Return
    End If

    'Call the routine for generating the drive time polygons
    Dim gpOutput As GPFeatureRecordSetLayer = CreateBufferPolys(startPt)
    If gpOutput Is Nothing Then
      MessageBox.Show("No results returned from geoprocessing service!  Try location inside United States.")
      Return
    End If

    'Add a folder to the contents to hold the results
    Dim fold As New Folder("Drive Time Analysis")
    mapDisp.Map.ChildItems.Add(fold)
    Dim recs As DriveTimeAnalysisVB.DriveTime.RecordSet = gpOutput.RecordSet

        'Figure out which field contains the shape (though it's probably always index 1)
    Dim shapefld As Integer = 0
    For i As Integer = 0 To recs.Fields.FieldArray.Length - 1
      Dim f As Field = recs.Fields.FieldArray(i)
      System.Diagnostics.Debug.WriteLine(f.Name)
      If f.Name = gpOutput.ShapeFieldName Then
        shapefld = i
        Exit For
      End If
    Next

    'Process the results
    For j As Integer = 0 To recs.Records.Length - 1
      Dim record As Record = recs.Records(j)
      Dim newPoly As ESRI.ArcGISExplorer.Geometry.Polygon = TryCast(SoapConverter.FromSoap(Of ESRI.ArcGISExplorer.Geometry.Polygon)(record.Values(shapefld)), ESRI.ArcGISExplorer.Geometry.Polygon)
      newPoly.CoordinateSystem = New CoordinateSystem(4326)   'set the coordinate system to WGS 1984 (4326)
      Dim sym As ESRI.ArcGISExplorer.Mapping.Symbol = Nothing
      Select Case j
        Case 0
          sym = ESRI.ArcGISExplorer.Mapping.Symbol.Fill.Solid.Red
          Exit Select
        Case 1
          sym = ESRI.ArcGISExplorer.Mapping.Symbol.Fill.Solid.Yellow
          Exit Select
        Case Else
          sym = ESRI.ArcGISExplorer.Mapping.Symbol.Fill.Solid.Green
          Exit Select
      End Select
      Dim res As New Note(record.Values(4).ToString() & " to " & record.Values(5).ToString() & " minute zone", newPoly, sym)
      fold.ChildItems.Add(res)
    Next
  End Sub

  Private Function CreateBufferPolys(ByVal pt As ESRI.ArcGISExplorer.Geometry.Point) As GPFeatureRecordSetLayer
    'Create progress helper so user knows something is happening
    Dim prog As ProgressHelper = New ProgressHelper("Running ...", "Please wait:", "Drive Time polygons being calculated ...")
    prog.Show()

    'Call a Geoprocessing service to calculate the drive time polygons
    Dim driveMe As New DriveTime.ESRI_DriveTime_US_GPServer()
    driveMe.Url = "http://sampleserver1.arcgisonline.com/ArcGIS/services/Network/ESRI_DriveTime_US/GPServer"
    Dim toolInfo As GPToolInfo = driveMe.GetToolInfo("CreateDriveTimePolygonsDisks")

        Dim projected As CoordinateSystem = CoordinateSystem.GeographicCoordinateSystems.World.WGS1984
        Dim outputPoint As ESRI.ArcGISExplorer.Geometry.Point = GeometryOperations.Project(pt, projected)

    'Create input parameters for gp task
    Dim inParams As GPParameterInfo() = toolInfo.ParameterInfo
    Dim newPT As New PointN()
        newPT.X = outputPoint.X
        newPT.Y = outputPoint.Y
    Dim projsr As New GeographicCoordinateSystem()
    projsr.WKID = 4326   'set the coordinate system to WGS 1984 (4326)
    projsr.WKIDSpecified = True
    newPT.SpatialReference = projsr

    Dim frsl As GPFeatureRecordSetLayer = DirectCast(inParams(0).Value, GPFeatureRecordSetLayer)
    Dim newRec As New Record()
    Dim flds As Fields = frsl.RecordSet.Fields
    Dim o As Object() = New Object(flds.FieldArray.Length - 1) {}
    For i As Integer = 0 To flds.FieldArray.Length - 1
      If flds.FieldArray(i).Name = frsl.ShapeFieldName Then
        o(i) = newPT
      ElseIf flds.FieldArray(i).Name = frsl.OIDFieldName Then
        o(i) = 1
      Else
        Dim ftype As esriFieldType = flds.FieldArray(i).Type
        If ftype = esriFieldType.esriFieldTypeString Then
          o(i) = String.Empty
        Else
          o(i) = 1
        End If
      End If
    Next
    newRec.Values = o
    Dim newRecs As Record() = New Record(0) {}
    newRecs(0) = newRec
    frsl.RecordSet.Records = newRecs

    Dim times As GPString = DirectCast(inParams(1).Value, GPString)
    times.Value = sDriveTimes

    Dim inValues As GPValue() = New GPValue() {frsl, times}

    'The DriveTime Analysis geoprocessing service in this sample is setup as a synchronous
    'service, hence the use of the Execute statement below.  If you are accessing geoprocessing
    'services that are setup as asynchronous services, then you will need to use the SubmitJob
    'statement instead of Execute.  SubmitJob would then be followed up with code to check the 
    'status of the job (using GetJobStatus), and finally a call (GetJobResults) to retrieve
    'the results when the service has completed execution.
    '
    'Execute the task synchronously, since this geoprocessing service is setup on the server as
    'a synchronous service
    Dim gpOutput As GPFeatureRecordSetLayer = Nothing
    Try
      Dim result As GPResult = driveMe.Execute(toolInfo.Name, inValues, Nothing, Nothing)
      gpOutput = DirectCast(result.Values(0), GPFeatureRecordSetLayer)
    Catch ex As Exception
      MessageBox.Show("Execution of service failed with this message: " & ex.Message)
    End Try

    'Hide the progress helper
    prog.Hide()
    prog = Nothing

    'Send back the results
    Return gpOutput
  End Function
End Class