如何二维地图Map选择范围,加到三维ArcScene控件中显示、渲染(源代码)
一、 在arcMapControl_OnMouseDown事件中增加:
Dim objEnvelope As IEnvelope
Dim pScreenDisplay As IDisplay
Dim pRubberband As IRubberBand
Set m_pActiveView = arcMapControl.ActiveView.FocusMap
Set pScreenDisplay = arcMapControl.ActiveView.ScreenDisplay
Set pRubberband = New RubberEnvelope
Set objEnvelope = pRubberband.TrackNew(pScreenDisplay, Nothing)
If objEnvelope Is Nothing Then
Call MsgBox("Envelope is Empty", vbExclamation)
Exit Sub
End If
Call FrmMap3D.Init(objEnvelope)
二、初始化选择中的要素:
Public Sub LoadSceneLayers()
On Error GoTo ErrorHandler
'
Dim pMap As iMap
Dim pLayer As ILayer
Dim pCompositeLayer As ICompositeLayer
Dim pPriority As Long
Dim pIndex1 As Long
Dim pIndex2 As Long
'
Set mSceneGraph = FrmMap3D.ArcSceneControl.SceneGraph 'SceneViewerCtrl1.SceneGraph
Set mSceneGraphEvents = mSceneGraph
Set pMap = frmMapControl.arcMapControl.ActiveView.FocusMap
pPriority = 0
'
For pIndex1 = 0 To pMap.LayerCount - 1 Step 1
Set pLayer = pMap.Layer(pIndex1)
If pLayer.Visible = True Then
If TypeOf pLayer Is IGroupLayer Then
Set pCompositeLayer = pLayer
For pIndex2 = 0 To pCompositeLayer.Count - 1 Step 1
pPriority = pPriority + 1
Call LoadSceneLayers2(pCompositeLayer.Layer(pIndex2), pPriority)
Next pIndex2
Else
pPriority = pPriority + 1
Call LoadSceneLayers2(pLayer, pPriority)
End If
End If
Next pIndex1
Exit Sub
ErrorHandler:
MsgBox "LoadSceneLayers"
' Call HandleError(False, "LoadSceneLayers " & MODULE_NAME & " (" & CStr(Erl) & ")", Err.Number, Err.Source, Err.Description)
End Sub
Private Sub LoadSceneLayers2(ByVal pLayerMx As ILayer, _
ByRef pPriority As Long)
On Error GoTo ErrorHandler
'
Dim pfeatureselection As IFeatureSelection
Dim pSpatialFilter As ISpatialFilter
Dim pFeatureLayerDefinition As IFeatureLayerDefinition
Dim pFeatureLayerMx As IFeatureLayer
Dim pFeatureLayerSx As IFeatureLayer
Dim p3DProperties As I3DProperties
Dim pGeoFeatureLayerMx As IGeoFeatureLayer
Dim pGeoFeatureLayerSx As IGeoFeatureLayer
Dim pLayerSx As ILayer
Dim pColor As IColor
Dim pSymbol As ISymbol
Dim pObjectCopy As IObjectCopy 'esriControlsSupport.IObjectCopy
'
Dim pListItems As MSComctlLib.ListItems
Dim pListItem As MSComctlLib.ListItem
'------------------------------------------------------
' Select Features That pass through the current extent
'------------------------------------------------------
Set pLayerSx = Nothing
If TypeOf pLayerMx Is IFeatureLayer Then
Set pFeatureLayerMx = pLayerMx
If pFeatureLayerMx.FeatureClass.FeatureType = esriFTSimple Then
Set pSpatialFilter = New SpatialFilter
Set pSpatialFilter.Geometry = mEnvelope
'
' pSpatialFilter.GeometryField = pFeatureLayerMx.FeatureClass.ShapeFieldName
pSpatialFilter.SpatialRel = esriSpatialRelIntersects
'
Set pfeatureselection = pFeatureLayerMx
Call pfeatureselection.SelectFeatures(pSpatialFilter, esriSelectionResultNew, False)
'
Set pFeatureLayerDefinition = pFeatureLayerMx
Set pFeatureLayerSx = pFeatureLayerDefinition.CreateSelectionLayer(pFeatureLayerMx.Name, True, "", "")
pFeatureLayerSx.Visible = pFeatureLayerMx.Visible
'
Call pfeatureselection.Clear
'
Set pGeoFeatureLayerMx = pFeatureLayerMx
Set pGeoFeatureLayerSx = pFeatureLayerSx
Set pObjectCopy = New ObjectCopy
Set pGeoFeatureLayerSx.Renderer = pObjectCopy.Copy(pGeoFeatureLayerMx.Renderer)
'
Set pLayerSx = pFeatureLayerSx
End If
Else
If TypeOf pLayerMx Is IRasterLayer Then
Dim pRasterLayerMx As IRasterLayer
Set pRasterLayerMx = pLayerMx
pRasterLayerMx.VisibleExtent = mEnvelope
Set pLayerSx = pRasterLayerMx
End If
End If
'-----------------------
' Add Layer to ArcScene
'-----------------------
Call mSceneGraph.Scene.AddLayer(pLayerSx, False)
'---------------------------------
' Update 3D Properties of SxLayer
'---------------------------------
Set p3DProperties = Get3DPropertiesFromLayer(pLayerSx)
If Not (p3DProperties Is Nothing) Then
' p3DProperties.BaseExpressi
' p3DProperties.BaseOption = esriBaseShape
p3DProperties.DepthPriorityValue = pPriority
' p3DProperties.Extrusi
' p3DProperties.ExtrusionType = esriExtrusionNone
' p3DProperties.FaceCulling = esriFaceCullingNone
' p3DProperties.Illuminate = True
' p3DProperties.OffsetExpressi
' p3DProperties.RenderMode = esriRenderCache
' p3DProperties.RenderRefreshRate = 0.75
' p3DProperties.RenderVisibility = esriRenderAlways
' p3DProperties.SmoothShading = True
' p3DProperties.ZFactor = 1
'
Call p3DProperties.Apply3DProperties(pLayerSx)
End If
' End If
'
Exit Sub
ErrorHandler:
MsgBox "LoadSceneLayers2"
'Call HandleError(False, "LoadSceneLayers2 " & MODULE_NAME & " (" & CStr(Erl) & ")", Err.Number, Err.Source, Err.Description)
End Sub
三、进行符号渲染
Public Sub SymbolInit()
On Error GoTo errH
'ReadIni
Dim pRen As ISimpleRenderer
Dim pGeoFeatLyr As IGeoFeatureLayer
Dim i As Integer
For i = 0 To FrmMap3D.ArcSceneControl.Scene.LayerCount - 1
If FrmMap3D.ArcSceneControl.Scene.Layer(i).Name Like "*" & "l" Then
Set pGeoFeatLyr = FrmMap3D.ArcSceneControl.Scene.Layer(i)
Set pRen = pGeoFeatLyr.Renderer
' Dim pSimpleRenderer As ISimpleRenderer
Dim pLine3DSymbol As ILineSymbol
Dim pSimpleLineSymbol As ISimpleLine3DSymbol
Set pSimpleLineSymbol = New SimpleLine3DSymbol
pSimpleLineSymbol.Style = esriS3DLSTube
Set pLine3DSymbol = pSimpleLineSymbol
pLine3DSymbol.Width = 2
Dim pRgbColor As IRgbColor
Set pRgbColor = New RgbColor
pRgbColor.Red = 255
pLine3DSymbol.color = pRgbColor
ExitLOOP:
Set pRen.Symbol = pLine3DSymbol
FrmMap3D.ArcSceneControl.Scene.SceneGraph.Invalidate pGeoFeatLyr, True, True
FrmMap3D.ArcSceneControl.Scene.SceneGraph.RefreshViewers
End If
Next
frmTreeToc3Dcontrol.ArcTOCControl.Update
errH:
If Err.Number <> 0 Then
MsgBox Err.Number & Err.Description, vbOKOnly + vbInformation & "2"
End If
End Sub
Private Function Get3DPropertiesFromLayer(pLayer As ILayer) As I3DProperties
On Error GoTo ErrorHandler
'
Dim pIndex As Integer
Dim pLayerExtensions As ILayerExtensions
Dim p3DProperties As I3DProperties
'
Set pLayerExtensions = pLayer
Set p3DProperties = Nothing
'
If Not (pLayerExtensions Is Nothing) Then
For pIndex = 0 To pLayerExtensions.ExtensionCount - 1 Step 1
If TypeOf pLayerExtensions.Extension(pIndex) Is I3DProperties Then
Set p3DProperties = pLayerExtensions.Extension(pIndex)
Exit For
End If
Next pIndex
End If
'
Set Get3DPropertiesFromLayer = p3DProperties
'
Exit Function
ErrorHandler:
MsgBox "Get3DPropsFromLayer"
'Call HandleError(False, "Get3DPropsFromLayer " & MODULE_NAME & " (" & CStr(Erl) & ")", Err.Number, Err.Source, Err.Description)
End Function
Public Sub UniValueSymbol()
Dim pUniqueValueRenderer As IUniqueValueRenderer
Dim pSym As ISimpleLineSymbol ' IFillSymbol
Dim pColor As IColor
Dim pNextUniqueColor As IColor
Dim pEnumRamp As IEnumColors
Dim pTable As ITable
Dim FieldNumberDS As Long
Dim FieldNumberWidth As Long
Dim FieldNumberHeight As Long
Dim pNextRow As IRow
Dim pNextRowBuffer As IRowBuffer
Dim pCursor As ICursor
Dim pQueryFilter As iQueryFilter
Dim dbl_DSValue As Variant
'''''''''''''''''''''''''''''''''''''''''''
Dim pLine3DSymbol As ILineSymbol
Dim pSimpleLineSymbol As ISimpleLine3DSymbol
'''''''''''''''''''''''''''''''''''''''''''
Set pUniqueValueRenderer = New UniqueValueRenderer
Dim pGeoFeatLyr As IGeoFeatureLayer
Dim i As Integer
For i = 0 To FrmMap3D.ArcSceneControl.Scene.LayerCount - 1
Set pGeoFeatLyr = FrmMap3D.ArcSceneControl.Scene.Layer(i)
If pGeoFeatLyr.FeatureClass.ShapeType = esriGeometryLine Or pGeoFeatLyr.FeatureClass.ShapeType = esriGeometryPolyline Then
FieldNumberDS = pGeoFeatLyr.FeatureClass.FindField("D_S")
FieldNumberWidth = pGeoFeatLyr.FeatureClass.FindField("WIDTH")
FieldNumberHeight = pGeoFeatLyr.FeatureClass.FindField("HEIGHT")
If FieldNumberDS = -1 And FieldNumberWidth = -1 Then
GoTo NextIIII
End If
pUniqueValueRenderer.FieldCount = 1
Set pQueryFilter = New QueryFilter
If FieldNumberDS <> -1 Then
pUniqueValueRenderer.Field(0) = Con_D_S
pQueryFilter.AddField Con_D_S
Else
pUniqueValueRenderer.Field(0) = "WIDTH"
pQueryFilter.AddField "WIDTH"
End If
'Set up the Color ramp, this came from looking at ArcMaps Color Ramp
' properties for Pastels.
'
Dim pColorRamp As IRandomColorRamp
Set pColorRamp = New RandomColorRamp
pColorRamp.StartHue = 0
pColorRamp.MinValue = 99
pColorRamp.MinSaturation = 15
pColorRamp.EndHue = 360
pColorRamp.maxValue = 100
pColorRamp.MaxSaturation = 30
pColorRamp.SIZE = 100
pColorRamp.CreateRamp True
Set pEnumRamp = pColorRamp.Colors
Set pNextUniqueColor = Nothing
' Get a enumerator on the first row of the Layer '
Set pCursor = pGeoFeatLyr.Search(pQueryFilter, True)
Set pNextRow = pCursor.NextRow
Do While Not pNextRow Is Nothing
Set pNextRowBuffer = pNextRow
Set pSimpleLineSymbol = New SimpleLine3DSymbol
pSimpleLineSymbol.Style = esriS3DLSTube
If FieldNumberDS <> -1 Then
dbl_DSValue = pNextRowBuffer.Value(FieldNumberDS)
pSimpleLineSymbol.ResolutionQuality = 1#
Else
dbl_DSValue = pNextRowBuffer.Value(FieldNumberWidth)
pSimpleLineSymbol.ResolutionQuality = 0#
End If
Set pNextUniqueColor = pEnumRamp.Next
If pNextUniqueColor Is Nothing Then
pEnumRamp.Reset
Set pNextUniqueColor = pEnumRamp.Next
End If
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim Symbolwith As Double
Symbolwith = CDbl(dbl_DSValue)
Symbolwith = Symbolwith / 1000
Set pLine3DSymbol = pSimpleLineSymbol
pLine3DSymbol.Width = Symbolwith
pLine3DSymbol.color = pNextUniqueColor
pUniqueValueRenderer.AddValue dbl_DSValue, dbl_DSValue, pLine3DSymbol
Set pNextRow = pCursor.NextRow
Loop
Set pGeoFeatLyr.Renderer = pUniqueValueRenderer
FrmMap3D.ArcSceneControl.Scene.SceneGraph.Invalidate pGeoFeatLyr, True, True
FrmMap3D.ArcSceneControl.Scene.SceneGraph.RefreshViewers
End If
NextIIII:
Next
frmTreeToc3Dcontrol.ArcTOCControl.Update
End Sub