2013-12-16 5 views
4

저는 매주 금요일 수동으로 파이썬으로 실행되는 vb 스크립트를 내 상사가 변환하도록 요청했습니다. 프로그래밍에 익숙하지 않고이 문제로 시작하는 방법을 결정하는 데 도움이 필요합니다. 이것은 나의 첫번째 진짜 프로그래밍 프로젝트이고 fortunatley에는 실시간 제한이 없다.VBscript를 파이썬 코드로 변환하는 방법은 무엇입니까?

컨텍스트 : 우리 조직의지도를 표시하는 ESRI Flexviewer가 있습니다. 문제의 스크립트는 폴리선을 취하고 선의 각도를 계산 한 다음 흐름 방향을 계산합니다. 폴리선 피쳐 클래스 내에서 시작 및 끝 필드를 사용하여 각 파이프의 중간 점에 방향 화살표를 배치합니다.

아래에 스크립트를 붙여 넣었습니다 ... 긴 종류의 도움말은 많은 도움이 될 것입니다.

그래서 나는 이것을 공격하는 방법에 대한 제안을하고 있습니다. 그냥 시작. VB 스크립트가 사용하는 기본 프로세스를 나열합니까? 흐름도를 그리고 파이썬을위한 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 
+1

게시 한 코드는 VBScript가 아니기 때문에 실행할 수 없습니다. –

답변

5

코드의 흐름도를 그리시오. 그것을 의사 코드로 변환하십시오. 데이터를 보관할 주요 변수 ("컨테이너")를 정의하십시오. 이들의 관계는 무엇입니까? 다른 것들은 일정하지만 다른 것들은 변합니까? 데이터 배열이 있습니까?

이러한 것들에 대해 미리 생각하면 코드 작성에 도움이됩니다. 그리고 올바른 방향으로 프로그래밍 여행을 시작하십시오. 대부분의 사람들은 코드를 작성하기 시작할 것입니다.

시간을내어이 질문에 답해 주시면 감사하겠습니다. 행운을 빕니다.

관련 문제