如何将VBscript转换为Python代码?

如何将VBscript转换为Python代码?,python,vb.net,vbscript,esri,Python,Vb.net,Vbscript,Esri,我的老板要求我将每周五手动运行的一段vb脚本转换成python,除非他希望它自动运行。我是编程新手,希望得到一些帮助来决定如何开始解决这个问题。这将是我的第一个真正的编程项目,幸运的是没有实时限制 背景:我们有一个ESRI Flexviewer,用于在我们的组织中显示地图。该脚本采用多段线,计算线的角度,然后计算流向。它通过在多段线要素类中使用“到”和“从”字段来执行此操作,并在每个管道的中点上放置方向箭头 我已将脚本粘贴到下面。。。这是一种长期的,但任何帮助将不胜感激 所以我想问的是一个如何解

我的老板要求我将每周五手动运行的一段vb脚本转换成python,除非他希望它自动运行。我是编程新手,希望得到一些帮助来决定如何开始解决这个问题。这将是我的第一个真正的编程项目,幸运的是没有实时限制

背景:我们有一个ESRI Flexviewer,用于在我们的组织中显示地图。该脚本采用多段线,计算线的角度,然后计算流向。它通过在多段线要素类中使用“到”和“从”字段来执行此操作,并在每个管道的中点上放置方向箭头

我已将脚本粘贴到下面。。。这是一种长期的,但任何帮助将不胜感激

所以我想问的是一个如何解决这个问题的建议。只是一个开始。我是否列出了VB脚本使用的主要进程?我是否绘制了流程图并正在为python编写psydo代码?我是否应该确定主要流程,例如循环?并以此作为开始的框架

Imports System.Runtime.InteropServices
Imports System.Drawing
Imports ESRI.ArcGIS.ADF.BaseClasses
Imports ESRI.ArcGIS.ADF.CATIDs
Imports ESRI.ArcGIS.Display
Imports ESRI.ArcGIS.Framework
Imports ESRI.ArcGIS.Catalog
Imports ESRI.ArcGIS.CatalogUI
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.Geometry
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.SystemUI
Imports System.Windows

<ComClass(CmdFlowCreation.ClassId, CmdFlowCreation.InterfaceId, CmdFlowCreation.EventsId), _
 ProgId("FlowArrows.CmdFlowCreation")> _
Public NotInheritable Class CmdFlowCreation
    Inherits BaseCommand

#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "35ac8cdc-4893-42d5-97ad-f41804dcb618"
    Public Const InterfaceId As String = "ec8ac176-19cc-4979-a5ca-4f7cf80bb37b"
    Public Const EventsId As String = "af685c91-ec0a-4ccd-ad21-56f9811c5f72"
#End Region

#Region "COM Registration Function(s)"
    <ComRegisterFunction(), ComVisibleAttribute(False)> _
    Public Shared Sub RegisterFunction(ByVal registerType As Type)
        ' Required for ArcGIS Component Category Registrar support
        ArcGISCategoryRegistration(registerType)

        'Add any COM registration code after the ArcGISCategoryRegistration() call

    End Sub

    <ComUnregisterFunction(), ComVisibleAttribute(False)> _
    Public Shared Sub UnregisterFunction(ByVal registerType As Type)
        ' Required for ArcGIS Component Category Registrar support
        ArcGISCategoryUnregistration(registerType)

        'Add any COM unregistration code after the ArcGISCategoryUnregistration() call

    End Sub

#Region "ArcGIS Component Category Registrar generated code"
    Private Shared Sub ArcGISCategoryRegistration(ByVal registerType As Type)
        Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID)
        GxCommands.Register(regKey)

    End Sub
    Private Shared Sub ArcGISCategoryUnregistration(ByVal registerType As Type)
        Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID)
        GxCommands.Unregister(regKey)

    End Sub

#End Region
#End Region

    Private Const dDistance As Double = 0.5
    Private Const bAsRatio As Boolean = True

    Private m_application As IApplication
    Dim pFClass As IFeatureClass

    Public m_pPropertySet As ESRI.ArcGIS.esriSystem.IPropertySet  'SDE Connection Properties
    Public m_pWS As IWorkspace
    Public m_pWSF As IWorkspaceFactory


    Public bContinue As Boolean
    Public pLineLayer As IFeatureLayer
    Public pPointLayer As IFeatureLayer
    Public bCreate As Boolean
    Public bUpdate As Boolean

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
        MyBase.New()

        ' TODO: Define values for the public properties
        MyBase.m_category = "PNCC ARCCatalog"  'localizable text 
        MyBase.m_caption = "Flow Creation"   'localizable text 
        MyBase.m_message = "Create flow arrows. 9.3"   'localizable text 
        MyBase.m_toolTip = "Flow Creation 9.3 (17-May-2010)" 'localizable text 
        MyBase.m_name = "FlowArrows.CmdFlowCreation"  'unique id, non-localizable (e.g. "MyCategory_ArcCatalogCommand")

        Try
            'TODO: change bitmap name if necessary
            Dim bitmapResourceName As String = Me.GetType().Name + ".bmp"
            ' MyBase.m_bitmap = New Bitmap(Me.GetType(), bitmapResourceName)
            MyBase.m_bitmap = Global.FlowArrows.My.Resources.BMPCmdFlowCreation
        Catch ex As Exception
            System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap")
        End Try


    End Sub

    ''   Public ReadOnly Property Enabled() As Boolean Implements ESRI.ArcGIS.SystemUI.ICommand.Enabled
    ''    Dim mxDoc As IMxDocument
    ''   Dim layerCount As Integer
    ''   'pApp is set in OnCreate    
    ''    mxDoc = CType(m_pApp.Document, IMxDocument)
    ''    layerCount = mxDoc.FocusMap.LayerCount

    ''    If pLayerCount>  0 Then
    ''        Return True
    ''    Else
    ''        Return False
    ''    End If
    ''   End Property

    'Private Property Get ICommand_Enabled() As Boolean
    'ICommand_Enabled = True
    'Dim pGxApplication As IGxApplication
    'Dim pGxObject As IGxObject
    'Dim pGxDataSet As IGxDataset

    'Set pGxApplication = mApplication
    'Set pGxObject = pGxApplication.SelectedObject
    ''
    'If TypeOf pGxObject Is IGxDataset Then

    '    Set pGxDataSet = pGxObject

    '    If TypeOf pGxDataSet.Dataset Is IFeatureClass Then
    ''            Dim pFClass As IFeatureClass
    '        Set pFClass = pGxDataSet.Dataset
    '        If pFClass.ShapeType = esriGeometryPolyline Then
    '          ICommand_Enabled = True
    '        End If
    '    End If
    'Else
    '    ICommand_Enabled = False
    'End If

    'End Property


    Public Overrides Sub OnCreate(ByVal hook As Object)
        If Not hook Is Nothing Then
            m_application = CType(hook, IApplication)

            'Disable if it is not ArcCatalog
            If TypeOf hook Is IGxApplication Then
                MyBase.m_enabled = True
            Else
                MyBase.m_enabled = False
            End If
        End If


        ' TODO:  Add other initialization code
    End Sub

    Public Overrides Sub OnClick()
        'TODO: Add CmdFlowCreation.OnClick implementation
        Dim pLayer As ILayer
        Dim pFeatLayer As IFeatureLayer
        Dim pFeatClass As IFeatureClass

        pLineLayer = New FeatureLayer
        pFeatClass = GetArcCatalogSelectedLayer()

        If pFeatClass Is Nothing Then
            Exit Sub
        End If

        pLineLayer.FeatureClass = pFeatClass

        ''''MyBase.m_enabled = False



        GetWSFactory()

        PopulateLineAngle()
    End Sub

    Public Function GetArcCatalogSelectedLayer() As IFeatureClass

        Dim arcCatalog As IGxApplication
        arcCatalog = CType(m_application, IGxApplication)

        'Get the Selected Object in Catalog
        Dim catalogSelectedObject As ESRI.ArcGIS.Catalog.IGxObject = arcCatalog.SelectedObject

        If (Not (TypeOf catalogSelectedObject Is ESRI.ArcGIS.Catalog.IGxDataset)) Then
            System.Windows.Forms.MessageBox.Show("Must have feature dataset selected")
            Return Nothing
        End If
        'Make sure it's a Feature Class
        Dim catalogDataset As IGxDataset
        catalogDataset = CType(catalogSelectedObject, IGxDataset)
        If (catalogDataset.Type <> esriDatasetType.esriDTFeatureClass) Then
            System.Windows.Forms.MessageBox.Show("Must have feature featureclass selected")
            Return Nothing
        End If

        Dim featureClass As IFeatureClass
        featureClass = CType(catalogDataset.Dataset, IFeatureClass)

        If featureClass.ShapeType <> esriGeometryType.esriGeometryPolyline Then
            System.Windows.Forms.MessageBox.Show("Must have a LINE type featureclass selected")
            Return Nothing
        End If

        Return featureClass

    End Function


    Public Sub GetWSFactory()


        On Error Resume Next
        Dim pDataset As IDataset
        Dim pWorkSpace As IWorkspace
        pDataset = pLineLayer.FeatureClass

        pWorkSpace = pDataset.Workspace
        m_pPropertySet = pWorkSpace.ConnectionProperties

        If Not m_pPropertySet Is Nothing Then

            m_pWSF = New ESRI.ArcGIS.DataSourcesGDB.SdeWorkspaceFactory
            m_pWS = m_pWSF.Open(m_pPropertySet, 0)

        End If

    End Sub


    Private Sub PopulateLineAngle()
        'get the center point of the line segment and populate the angle if the line
        Dim str As String = ""
        Try

            Dim pQueryFilt As IQueryFilter
            Dim pFeature As IFeature
            Dim pFeatCur As IFeatureCursor
            Dim pLnFeatClass As IFeatureClass
            Dim pPtFeatClass As IFeatureClass

            Dim pStatusBar As ESRI.ArcGIS.esriSystem.IStatusBar

            Dim Pi As Double
            Dim pCurve As ICurve
            Dim pMiddlePoint As IPoint
            Dim dAngle As Double
            Dim pLine As ILine
            Dim pTable As ITable
            Dim dLength As Double

            Dim lLnCompKeyFld As Long
            Dim lLnCompTypeFld As Long
            Dim lCompKeyFld As Long
            Dim lAngleFld As Long
            Dim lCompTypeFld As Long

            Dim pNewFeat As IFeature
            Dim pDS As IDataset

            Dim lastOID As Integer = 0

            pStatusBar = m_application.StatusBar
            Pi = 4 * System.Math.Atan(1)

            '--------  1. Get the point layer ---------------
            pPointLayer = GetPointLayer()
            lastOID = GetLastOID(pPointLayer.FeatureClass)


            If pPointLayer Is Nothing Then
                '     MsgBox "The Update point layer does not exist!", vbCritical, "Process Halted"
                Exit Sub
            End If

            '--------  2. populate update fields index ----------
            pPtFeatClass = pPointLayer.FeatureClass
            lCompKeyFld = pPtFeatClass.FindField("CompKey")
            lAngleFld = pPtFeatClass.FindField("Angle")
            lCompTypeFld = pPtFeatClass.FindField("CompType")

            pLnFeatClass = pLineLayer.FeatureClass
            lLnCompKeyFld = pLnFeatClass.FindField("Compkey")
            lLnCompTypeFld = pLnFeatClass.FindField("CompType")

            '--------- 3. populate the angle for all the features in the line layer ----
            ''''pQueryFilt = New QueryFilter
            ''''pFeatCur = pLnFeatClass.Search(pQueryFilt, False)

            pQueryFilt = New QueryFilter
            ''''''
            pTable = CType(pLnFeatClass, ITable)
            Dim tableSort As ITableSort = New TableSortClass()
            tableSort.Table = pTable
            tableSort.QueryFilter = pQueryFilt
            tableSort.Fields = "OBJECTID"

            pLnFeatClass = CType(pTable, IFeatureClass)


            pFeatCur = pLnFeatClass.Search(pQueryFilt, False)

            ''''''
            pFeature = pFeatCur.NextFeature
            Dim iCnt As Integer = 0
            Dim pWorkspaceEdit As ITransactions
            pWorkspaceEdit = m_pWS
            pWorkspaceEdit.StartTransaction()

            Do While Not pFeature Is Nothing And iCnt < lastOID  'Loop through existing features.
                iCnt += 1
                pStatusBar.Message(0) = "Finding .... feature:" & pFeature.OID & " - " & iCnt.ToString
                pFeature = pFeatCur.NextFeature

                System.Windows.Forms.Application.DoEvents()

            Loop

            Do While Not pFeature Is Nothing

                iCnt += 1
                pStatusBar.Message(0) = "Calculating .... feature:" & pFeature.OID & " - " & iCnt.ToString
                pCurve = pFeature.Shape
                dLength = pCurve.Length
                pMiddlePoint = New ESRI.ArcGIS.Geometry.Point
                'get the middle point
                pCurve.QueryPoint(esriSegmentExtension.esriNoExtension, dDistance, bAsRatio, pMiddlePoint)
                'get the angle
                pLine = New ESRI.ArcGIS.Geometry.Line
                pCurve.QueryTangent(esriSegmentExtension.esriNoExtension, dDistance, bAsRatio, dLength, pLine)

                dAngle = pLine.Angle * 360 / (2 * Pi)
                dAngle = 270 + dAngle
                '     If dAngle < 90 Then
                '       dAngle = 90 - dAngle
                '     Else
                '       dAngle = 450 - dAngle
                '     End If

                'add to point layer
                pNewFeat = pPtFeatClass.CreateFeature
                pNewFeat.Shape = pMiddlePoint
                If lAngleFld <> -1 Then pNewFeat.Value(lAngleFld) = CLng(dAngle)
                If lCompKeyFld <> -1 And lLnCompKeyFld <> -1 Then
                    pNewFeat.Value(lCompKeyFld) = pFeature.Value(lLnCompKeyFld)
                End If
                If lCompTypeFld <> -1 And lLnCompTypeFld <> -1 Then
                    pNewFeat.Value(lCompTypeFld) = pFeature.Value(lLnCompTypeFld)
                End If
                pNewFeat.Store()
                pWorkspaceEdit.CommitTransaction()

                pFeature = pFeatCur.NextFeature

                If iCnt Mod 100 = 0 Then
                    System.Windows.Forms.Application.DoEvents()
                End If

            Loop
            pStatusBar.Message(0) = "Finished!"

        Catch ex As Exception
            MsgBox(ex.Message + " - " + str)
            m_application.StatusBar.Message(0) = "Finished with errors!"
        End Try


    End Sub


    Private Function GetLastOID(ByVal pFClass As IFeatureClass) As Integer
        'sde workspace open start a transaction to rollback if any error occurs
        On Error Resume Next
        Dim pWorkspaceEdit As ITransactions
        pWorkspaceEdit = m_pWS
        '' pWorkspaceEdit.StartTransaction()


        ' 'delete feature class records
        '
        Dim pFeatCursor As IFeatureCursor
        Dim pFeature As IFeature
        pFeatCursor = pFClass.Update(Nothing, False)
        pFeature = pFeatCursor.NextFeature
        Dim OID As Integer = 0
        '
        Do While pFeature Is Nothing = False
            OID = pFeature.OID
            pFeature = pFeatCursor.NextFeature
        Loop

        If OID > 0 Then  '' Delete the last one, it might have been corrupted
            Dim qFilter As IQueryFilter
            qFilter = New QueryFilter
            qFilter.WhereClause = "OBJECTID = " & OID.ToString

            pFeatCursor = pFClass.Update(qFilter, False)
            pFeature = pFeatCursor.NextFeature
            pFeatCursor.DeleteFeature()
            OID = OID - 1
        End If

        Return OID


    End Function

    Private Function GetPointLayer() As ILayer
        On Error GoTo eh


        Dim pFWS As IFeatureWorkspace
        pFWS = m_pWS

        Dim sNewFCName As String
        Dim sFCName As String

        sFCName = GetFeatureClassName(pLineLayer)
        sNewFCName = sFCName & "_FLOW_UPDATE"

        ' ' Get the feature class
        Dim pFeatureClass As IFeatureClass
        pFeatureClass = pFWS.OpenFeatureClass(sNewFCName)

        If pFeatureClass Is Nothing Then  'not exits
            MsgBox("The feature class : " & sNewFCName & " does not exist, please create it first then run the tool again.")
            GoTo eh
        Else

            ''AK dont delete features.  Will find the last and continue from there.
            ''''DeleteFeatures(pFeatureClass)
            'already exists, delete all the features
            '       Dim pDS As IDataset
            '       Set pDS = pFeatureClass
            '       pDS.Delete
            '
            '       Set pFeatureClass = CreateFeatureClass(sNewFCName)
        End If

        Dim pFeatureLayer As IFeatureLayer
        pFeatureLayer = New FeatureLayer
        pFeatureLayer.FeatureClass = pFeatureClass

        GetPointLayer = pFeatureLayer
        Exit Function
eh:
        GetPointLayer = Nothing

    End Function

    Public Function GetFeatureClassName(ByVal pFeatLayer As IFeatureLayer) As String
        Dim pDataset As IDataset
        pDataset = pFeatLayer.FeatureClass
        GetFeatureClassName = pDataset.Name

    End Function

    Private Sub DeleteFeatures(ByVal pFClass As IFeatureClass)

        'sde workspace open start a transaction to rollback if any error occurs
        On Error Resume Next
        Dim pWorkspaceEdit As ITransactions
        pWorkspaceEdit = m_pWS
        pWorkspaceEdit.StartTransaction()


        ' 'delete feature class records
        '
        '  Dim pFeatCursor As IFeatureCursor
        '  Dim pFeature As IFeature
        '  Set pFeatCursor = pFClass.Update(Nothing, False)
        '  Set pFeature = pFeatCursor.NextFeature
        '
        '  Do While pFeature Is Nothing = False
        '    pFeatCursor.DeleteFeature
        '    Set pFeature = pFeatCursor.NextFeature
        '  Loop


        Dim pFeatureWorkspace As IFeatureWorkspace
        pFeatureWorkspace = pWorkspaceEdit

        Dim t As ITable


        t = pFeatureWorkspace.OpenTable(pFClass.AliasName)
        t.DeleteSearchedRows(Nothing)

        pWorkspaceEdit.CommitTransaction()
    End Sub

End Class
导入System.Runtime.InteropServices
导入系统。绘图
导入ESRI.ArcGIS.ADF.BaseClasses
导入ESRI.ArcGIS.ADF.CATIDs
导入ESRI.ArcGIS.Display
导入ESRI.ArcGIS.Framework
导入ESRI.ArcGIS.Catalog
导入ESRI.ArcGIS.Catalogi
导入ESRI.ArcGIS.Carto
导入ESRI.ArcGIS.Geometry
导入ESRI.ArcGIS.Geodatabase
导入ESRI.ArcGIS.esriSystem
导入ESRI.ArcGIS.SystemUI
导入系统.Windows
_
公共不可继承类CmdFlowCreation
继承BaseCommand
#区域“COM GUID”
'这些GUID提供此类的COM标识
'及其COM接口。如果您更改它们,则现有
'客户端将无法再访问该类。
Public Const ClassId为String=“35ac8cdc-4893-42d5-97ad-f41804dcb618”
Public Const InterfaceId As String=“ec8ac176-19cc-4979-a5ca-4f7cf80bb37b”
Public Const EventsId As String=“af685c91-ec0a-4ccd-ad21-56f9811c5f72”
#末端区域
#区域“COM注册功能”
_
公共共享子注册表函数(ByVal registerType作为类型)
“ArcGIS组件类别注册支持所需
ArcGISCategoryRegistration(注册表类型)
'在ArcGISCategoryRegistration()调用后添加任何COM注册码
端接头
_
公共共享子注销函数(ByVal registerType作为类型)
“ArcGIS组件类别注册支持所需
ArcGISCategoryUnregistration(registerType)
'在ArcGISCategoryUnregistration()调用后添加任何COM注销代码
端接头
#区域“ArcGIS组件类别注册器生成代码”
私有共享子ArcGISCategoryRegistration(ByVal registerType作为类型)
Dim regKey As String=String.Format(“HKEY_CLASSES_ROOT\CLSID\{{{0}}}”,registerType.GUID)
GxCommand.寄存器(regKey)
端接头
私有共享子ArcGISCategoryUnregistration(ByVal registerType作为类型)
Dim regKey As String=String.Format(“HKEY_CLASSES_ROOT\CLSID\{{{0}}}”,registerType.GUID)
GxCommand.Unregister(regKey)
端接头
#末端区域
#末端区域
专用常量D为双精度=0.5
Private Const bAsRatio为布尔值=True
作为IApplication的专用m_应用程序
将pFClass设置为IFeatureClass
公共m_属性集为ESRI.ArcGIS.esriSystem.IPropertySet的SDE连接属性
公共m_pWS作为我的工作空间
公共m_pWSF As IWorkspaceFactory
公共bContinue作为布尔值
作为IFeatureLayer的公共柱脚层
公共pPointLayer作为IFeatureLayer
公共b创建为布尔值
公共bUpdate为布尔值
'可创建的COM类必须有一个Public Sub New()
'如果没有参数,则该类将不会
'已在COM注册表中注册,无法创建
'通过CreateObject。
公共分新()
MyBase.New()
'TODO:定义公共属性的值
MyBase.m_category=“PNCC ARCCatalog”'可本地化文本
MyBase.m_caption=“流创建”可本地化文本
MyBase.m_message=“创建流箭头.9.3”可本地化文本
MyBase.m_toolTip=“流程创建9.3(2010年5月17日)”“可本地化文本
MyBase.m_name=“FlowArrows.CmdFlowCreation”唯一id,不可本地化(例如“MyCategory_ArcCatalogCommand”)
尝试
'TODO:必要时更改位图名称
Dim bitmapResourceName作为字符串=Me.GetType().Name+“.bmp”
'MyBase.m_bitmap=新位图(Me.GetType(),bitmapResourceName)
MyBase.m_bitmap=Global.FlowArrows.My.Resources.BMPCmdFlowCreation
特例
System.Diagnostics.Trace.WriteLine(例如消息“无效位图”)
结束尝试
端接头
“”公共只读属性Enabled()作为布尔值实现ESRI.ArcGIS.SystemUI.ICommand.Enabled
“”作为IMxDocument的Dim mxDoc
“”Dim layerCount为整数
''pApp在OnCreate中设置
''mxDoc=CType(m_pApp.Document,IMxDocument)
“”layerCount=mxDoc.FocusMap.layerCount
“”如果pLayerCount>0,则
“”返回True
”“还有吗
“”返回False
“”如果结束
“”结束属性
'Private Property Get ICommand_Enabled()作为布尔值
'ICommand_Enabled=True
“Dim PGX应用程序作为IGX应用程序
'作为IGxObject的Dim pGxObject
'将pGxDataSet设置为IGxDataset
'设置pGxApplication=mApplication
'设置pGxObject=pGxApplication.SelectedObject
''
'如果pGxObject的类型为IGxDataset,则
'设置pGxDataSet=pGxObject
'如果pGxDataSet.Dataset的类型为IFeatureClass,则
“”将pFClass设置为IFeatureClass
'Set-pFClass=pGxDataSet.Dataset
'如果pFClass.ShapeType=esriGeometryPolyline,则
'ICommand_Enabled=True
"完"
"完"
”“否则呢
'ICommand_Enabled=Fals