⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bastrackingimport.bas

📁 esir公司的产品MapObject的vb例子
💻 BAS
📖 第 1 页 / 共 5 页
字号:
Attribute VB_Name = "basTrackingImport"
'
' ESRI
' 3D Analyst Developer Sample - sxTrackingEventImport
' basTrackingImport.bas
'
' Includes command to import layer keyframes from event features or records,
' * ImportTrackingPointsToLayerKeyframes

' Requires references to
' ESRI ArcScene Object Library
' ESRI ArcMap Object Library
' ESRI TIN Object Library
' ESRI Object Library

Option Explicit

Dim g_pGraphicElement As IElement


' we will need to normalize all date\time events inside a 0-1 range.
' we will first convert all date\times to a double using these constants:
Const minF = (1# / 60#)
Const secF = (1# / 3600#)

Const dayF = (1# / 365#)
Const monthF = (1# / 12#)

Dim varIDS() As String  ' an array of all unique group IDs (such as airline flight #'s)

' for progress dialog:
Dim m_pTrackCancel As ITrackCancel
Dim m_pProgDialog As IProgressDialog
Dim m_pStepProgressor As IStepProgressor
'
' Accepting a feature layer or standalone table with attributes defining the position of
' and time of an event (such as the location of an airline), and a ID fieldname which will
' link occurances of the same group (such as the path of an airplane with a flight ID),
' as well as a layer which to animate,
' return a group layer containing layers cloned from the animate layer (CAD, graphics, feature layer)
' and a collection of animation tracks which control their movement through the event locations
' they designate.
' Additional parameters control the filtering of events via their selection or time range,
' a height offset and\or z conversion, and control over how the layer azimuthal rotation changes
' along the event paths.
' (bSetKeyframeAzimuth = TRUE & bSetAdditionalKeyframeForAzimuth = FALSE)
' - will set the azimuth property for each keyframe based on it's and the next event in the group's location.
' - This will rotate the direction the layer is pointing in along the path.
' - However, for an path which moves through various postions that should not be considered in
'   factoring the azimuth, such as a flight from LA to NY to Miami which should not be turning
'   towards Miami until reaching NY, use
' (bSetKeyframeAzimuth = TRUE & bSetAdditionalKeyframeForAzimuth = TRUE)
' - which will add a duplicate keyframe for each event with the last azimuth position so that the
'   rotation effect is not consider throughout the entire path, but from location to location.
'
Public Function ImportTrackingPointsToLayerKeyframes(pLayerWithSelection As ILayer, pORStandAloneTable As IStandaloneTable, sTimeStampField As String, _
sEventGroupIDField As String, pSymbolLayer As ILayer, sOutputGroupLayerName As String, _
ByRef ppOutAnimationTracks As Collection, ByRef ppOutGroupLayer As IGroupLayer, _
Optional nZOffset As Double = 0, _
Optional nZUnitConversion As Double = 1, _
Optional sTimeFilterStart As String, Optional sTimeFilterEnd As String, _
Optional sXFieldName As String, Optional sYFieldName As String, Optional sZFieldName As String, _
Optional nMaxTracks As Long = -1, Optional bUseSelectedEvents As Boolean, Optional bSortRecords As Boolean = False, _
Optional bHideEventAtStartAndFinish As Boolean = True, Optional bSetKeyframeAzimuth As Boolean = True, _
Optional bSetAdditionalKeyframeForAzimuth As Boolean = False, Optional sBaseTrackName As String = "Import Track", Optional nProgBarOwnerHWND As Long) As Boolean

  Debug.Assert 0
  On Error GoTo ImportTrackingPointsToLayerKeyframes_ERR
  
  Dim sTotalEventsStartTime As String
  Dim sTotalEventsEndTime As String
  Dim nGroupIDField As Long
  Dim nTimeFieldIndex As Long
  Dim nXFieldIndex As Long
  Dim nYFieldIndex As Long
  Dim nZFieldIndex As Long
  Dim nAniStartTime As Double
  Dim nAniEndTime As Double
  Dim nAniTotalTime As Double
  Dim dLastAzi As Double
  Dim nTrackCount As Double
  Dim nSymbolLayerX As Double
  Dim nSymbolLayerY As Double
  Dim nSymbolLayerZ As Double
  Dim pCursorEvents As ICursor
  Dim pRow As IRow
  Dim sID As String
  Dim pF As IField
  Dim nIDCount As Double
  Dim i As Long
  Dim bFound As Boolean
  Dim sEventGroupIDField2 As String ' the given fieldname with any modifications such as an underscore where spaces were
  Dim sTimeStampField2 As String    ' ""  ""  ""
  Dim sXField2 As String            ' ""  ""  ""
  Dim sYField2 As String            ' ""  ""  ""
  Dim sZField2 As String            ' ""  ""  ""
  Dim nNumFeatures As Double
  Dim pFCFullRecords As ICursor
  Dim pFCSortIndividual As ICursor
  Dim pFC_FID As IFeatureCursor
  Dim pRC_FID As ICursor
  Dim bUseFeatures As Boolean
  Dim pFakeAzimuthKeyframe As IKeyframe
  Dim bUseRecordsCurrentSorting As Boolean
  Dim bUseTimeFilter As Boolean
  ReDim varIDS(0)
  nZFieldIndex = -1
  nXFieldIndex = -1
  nYFieldIndex = -1
  
  If Right(sBaseTrackName, 1) <> " " Then sBaseTrackName = sBaseTrackName & " "
  bUseRecordsCurrentSorting = Not (bSortRecords)
  If bSetAdditionalKeyframeForAzimuth Then bSetKeyframeAzimuth = True
  If Len(Trim(sTimeFilterStart)) > 0 And Len(Trim(sTimeFilterEnd)) > 0 Then bUseTimeFilter = True
  
  ' evaluate if the input is a feature layer or an attribute table:
  If Not pLayerWithSelection Is Nothing Then
    If Not TypeOf pLayerWithSelection Is IFeatureLayer Then
      MsgBox "Input layer type was not feature layer.", vbExclamation, "Import Tracking Points"
      Exit Function
    End If
    bUseFeatures = True
  ElseIf Not pORStandAloneTable Is Nothing Then
    bUseFeatures = False
  Else
    MsgBox "No valid input was designated.", vbExclamation, "Import Tracking Points"
    Exit Function
  End If
  
  If pSymbolLayer Is Nothing Then
    MsgBox "No layer to animate was found.", vbExclamation, "Import Tracking Points"
    Exit Function
  End If
  
  Dim sIDName As String
  If bUseFeatures Then  ' todo -get this from table, not hardcoded
    sIDName = "FID = "
  Else
    sIDName = "OID = "
  End If
      
  ' retrieve a cursor for all, or selected, event records:
  If bUseSelectedEvents Then
    If bUseFeatures Then
      Set pCursorEvents = priv_GetSelectedFeatures(pLayerWithSelection, True, Nothing)
    Else
      Set pCursorEvents = priv_GetSelectedRecords(pORStandAloneTable, True, Nothing)
    End If
  Else
    If bUseFeatures Then
      Set pCursorEvents = priv_GetFeatureCursorFromLayer(pLayerWithSelection, Nothing)
    Else
      Set pCursorEvents = priv_GetAllRecords(pORStandAloneTable, Nothing)
    End If
  End If

  If pCursorEvents Is Nothing Then
    Debug.Assert 0
    MsgBox "Error retrieving cursor from input records.", vbExclamation, "Import Tracking Points"
    Exit Function
  End If
  
  ' get the index of the eventgroupID field:
  nGroupIDField = pCursorEvents.FindField(sEventGroupIDField)
  If nGroupIDField < 1 Then  ' try modifying the field name to use underscores:
    sEventGroupIDField2 = Replace(sEventGroupIDField, " ", "_")
    nGroupIDField = pCursorEvents.FindField(sEventGroupIDField2)
  Else
    sEventGroupIDField2 = sEventGroupIDField  ' the original fieldname to use is OK
  End If
  If nGroupIDField < 0 Then
    MsgBox "There was a error accessing field: " & sEventGroupIDField & ".", vbExclamation, "Import Tracking Points"
    Exit Function
  End If
  
  ' get the index of the timestamp field:
  nTimeFieldIndex = pCursorEvents.FindField(sTimeStampField)
  If nTimeFieldIndex < 0 Then ' try modifying the field name to use underscores:
    sTimeStampField2 = Replace(sTimeStampField, " ", "_")
    nTimeFieldIndex = pCursorEvents.FindField(sTimeStampField2)
  Else
    sTimeStampField2 = sTimeStampField ' the original fieldname to use is OK
  End If
  If nTimeFieldIndex < 0 Then
    MsgBox "There was a error accessing field: " & sTimeStampField & ".", vbExclamation, "Import Tracking Points"
    Exit Function
  End If
    
  ' get the index of the X and y field:
  If Not bUseFeatures Or (bUseFeatures And (sXFieldName <> "" And sYFieldName <> "")) Then
    nXFieldIndex = pCursorEvents.FindField(sXFieldName)
    If nXFieldIndex < 0 Then ' try modifying the field name to use underscores:
      sXField2 = Replace(sXFieldName, " ", "_")
      nXFieldIndex = pCursorEvents.FindField(sXField2)
    Else
      sXField2 = sXFieldName ' the original fieldname to use is OK
    End If
    If nXFieldIndex < 0 And Not bUseFeatures Then
      MsgBox "There was a error accessing field: " & sXFieldName & ".", vbExclamation, "Import Tracking Points"
      Exit Function
    End If
  
    nYFieldIndex = pCursorEvents.FindField(sYFieldName)
    If nYFieldIndex < 0 Then ' try modifying the field name to use underscores:
      sYField2 = Replace(sYFieldName, " ", "_")
      nYFieldIndex = pCursorEvents.FindField(sYField2)
    Else
      sYField2 = sYFieldName ' the original fieldname to use is OK
    End If
    If nYFieldIndex < 0 And Not bUseFeatures Then
      MsgBox "There was a error accessing field: " & sYFieldName & ".", vbExclamation, "Import Tracking Points"
      Exit Function
    End If
    
  
  End If
  
  ' get the index of the Z field (either features or table)
  If (bUseFeatures And (nZFieldIndex < 0)) Or Not bUseFeatures Then
    If sZFieldName <> "" Then
      nZFieldIndex = pCursorEvents.FindField(sZFieldName)
      If nZFieldIndex < 0 Then ' try modifying the field name to use underscores:
        sZField2 = Replace(sZFieldName, " ", "_")
        nZFieldIndex = pCursorEvents.FindField(sZFieldName)
      Else
        sZField2 = sZFieldName ' the original fieldname to use is OK
      End If
      If nZFieldIndex < 0 Then
        MsgBox "There was a error accessing field: " & sZFieldName & ".", vbExclamation, "Import Tracking Points"
        Exit Function
      End If
    End If
  End If
  
  
  ' create an array containing the unique group IDS of the events:
  Set pRow = pCursorEvents.NextRow
  Dim iRowCount As Double
  Do While Not pRow Is Nothing
    sID = pRow.Value(nGroupIDField)
    bFound = False
    For i = 0 To nIDCount - 1
      If UCase(varIDS(i)) = UCase(sID) Then
        bFound = True
        Exit For
      End If
    Next
    If Not bFound Then
      ReDim Preserve varIDS(nIDCount)
      varIDS(nIDCount) = sID
      nIDCount = nIDCount + 1
      If nMaxTracks > 0 And nIDCount = nMaxTracks Then Exit Do
    End If
    Set pRow = pCursorEvents.NextRow
    iRowCount = iRowCount + 1
    DoEvents
  Loop

  ' if the real world animation start and end times, were not given, we must parse this
  ' information ourselves:
  Dim nMax As Double
  If (nMaxTracks = -1) Or (nIDCount < nMaxTracks) Then nMaxTracks = nIDCount
  If (nMaxTracks = -1) Then  ' was there a maximum number of tracks, and therefore, group IDs?
    nMax = nIDCount
  Else
    nMax = nMaxTracks
  End If
  
  ' read table for start and end times if they were not given:
  'If (Len(Trim(sTotalEventsStartTime)) < 1 Or Len(Trim(sTotalEventsEndTime)) < 1) Then
    If Not ParseRecordsForStartAndEndTime(pLayerWithSelection, pORStandAloneTable, bUseSelectedEvents, nTimeFieldIndex, sEventGroupIDField2, nMax, sTimeFilterStart, sTimeFilterEnd, sTotalEventsStartTime, sTotalEventsEndTime) Then
      Debug.Assert 0
      SetDoneWorkingState
      MsgBox "There was a error reading the table for start and end times.", vbExclamation, "Import Tracking Points"
      
      Exit Function
    End If
  'End If
  
  ' since the total events range was either given or just parsed, now we can
  ' tokenize (convert to a double)
  nAniStartTime = TokenTime(sTotalEventsStartTime)
  nAniEndTime = TokenTime(sTotalEventsEndTime)
  Debug.Print "Events start at: " & sTotalEventsStartTime & "(" & nAniStartTime & ") - Events end at: " & sTotalEventsEndTime & "(" & nAniEndTime & ")"
  'OffsetProgressMSG "Events start at: " & sTotalEventsStartTime & "(" & nAniStartTime & ") - Events end at: " & sTotalEventsEndTime & "(" & nAniEndTime & ")", False
  
  nAniTotalTime = nAniEndTime - nAniStartTime
  
  Debug.Print nIDCount & " unique groups out of " & iRowCount & " total records."
  'OffsetProgressMSG nIDCount & " unique groups out of " & iRowCount & " total records.", False
  
  Dim pQF_Group As IQueryFilter
  Set pQF_Group = New QueryFilter
  
  Dim lID As Double
  Dim pQF_FID As IQueryFilter
    
  Dim pTrack As IAnimationTrack
  Dim pKeyFrame As IKeyframe
  Dim pTrackFeat As IFeature
  Dim pTrackRow As IRow
  Dim nTrackX As Double
  Dim nTrackY As Double
  Dim nTrackZ As Double
  Dim nTransX As Double
  Dim nTransY As Double
  Dim nTransZ As Double
  
  ' inevitably, we will build a collection of animation tracks to return,
  ' as well as a group layer representing a layer for each event group, such as a flight:
  Dim pAniTracks As Collection
  Set pAniTracks = New Collection
  
  ' build the outgoing group layer, and name it:
  Dim pOutGroupLayer As IGroupLayer
  Set pOutGroupLayer = New GroupLayer
  
  Dim pLayerNaming As ILayer
  Set pLayerNaming = pOutGroupLayer
  pLayerNaming.name = sOutputGroupLayerName

  Dim pTable As IAttributeTable
  Dim pSelSet As ISelectionSet
  Dim pFeatSel As IFeatureSelection
  Dim pRowSel As ITableSelection
  Dim pTableSort As ITableSort
  Dim pIDSorted As IEnumIDs
  Dim pFeatureLayer As IFeatureLayer
  Dim pStandAloneEventTable As ITable
  Dim pFeatureCur As IFeatureCursor
  Dim pFLayer As IFeatureLayer
  Dim pFeat2 As IFeature
  
  ' for each unique group ID, create a new animation track
  ' and use the geometries of the point locations and their time stamps
  ' to create layer keyframes with proper time stamps and translations:
  If nMaxTracks <= 0 Then nMaxTracks = nIDCount

  If bUseFeatures Then
    Set pFeatureLayer = pLayerWithSelection
  Else
    Set pStandAloneEventTable = pORStandAloneTable
  End If
    
  ' DETERMINE THE POSITION OF THE ANIMATED LAYER.
  ' get the original location of the symbol layer (use 1st feature):
  If TypeOf pSymbolLayer Is IFeatureLayer Then
    
    Set pFLayer = pSymbolLayer
    Set pFeatureCur = pFLayer.Search(Nothing, False)
    Set pFeat2 = pFeatureCur.NextFeature
    nSymbolLayerX = (pFeat2.Extent.xmax + pFeat2.Extent.xmin) / 2
    nSymbolLayerY = (pFeat2.Extent.ymax + pFeat2.Extent.ymin) / 2
    
    If Not IsNaN(pFeat2.Extent.zmax) And Not (IsNaN(pFeat2.Extent.zmin)) Then
      nSymbolLayerZ = (pFeat2.Extent.zmax + pFeat2.Extent.zmin) / 2
    Else
      nSymbolLayerZ = 0
    End If
    
  ElseIf TypeOf pSymbolLayer Is IGraphicsLayer Then
    
    Dim pElem As IElement
    Dim pGC As IGraphicsContainer3D
    Set pGC = pSymbolLayer
    Set pElem = pGC.Element(0)
    nSymbolLayerX = (pElem.Geometry.Envelope.xmax + pElem.Geometry.Envelope.xmin) / 2
    nSymbolLayerY = (pElem.Geometry.Envelope.ymax + pElem.Geometry.Envelope.ymin) / 2
    nSymbolLayerZ = (pElem.Geometry.Envelope.zmax + pElem.Geometry.Envelope.zmin) / 2
    
  End If
              
  For i = 0 To nMaxTracks - 1 ' MAIN TRACK LOOP  ========================================================================
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -