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