cl991036
管理员
管理员
  • 注册日期2003-07-25
  • 发帖数5917
  • QQ14265545
  • 铜币29669枚
  • 威望217点
  • 贡献值0点
  • 银元0个
  • GIS帝国居民
  • GIS帝国铁杆
阅读:1696回复:4

使用API在Scene或Globe中画橡皮条线

楼主#
更多 发布于:2008-06-04 09:28

<P><FONT style="BACKGROUND-COLOR: rgb(204,232,207)" face=Verdana>在Scene或Globe中绘制橡皮条线的工具,其中wsUtilityBaseTool是我自己封装的基类,<BR>大家只需要把它替换成AE的<FONT style="BACKGROUND-COLOR: rgb(204,232,207)" face=Verdana>BaseTool,把其中相应的代码放在相应的函数中,然后再进行一些简单的修改就好了<BR>附上VB.Net源码<BR></FONT><BR>Imports ESRI.ArcGIS.Analyst3D<BR>Imports ESRI.ArcGIS.Carto<BR>Imports ESRI.ArcGIS.Controls<BR>Imports ESRI.ArcGIS.Display<BR>Imports ESRI.ArcGIS.Geometry<BR>Imports ESRI.ArcGIS.GlobeCore<BR>Imports ESRI.ArcGIS.SystemUI<BR></FONT></P>
<P><FONT style="BACKGROUND-COLOR: rgb(204,232,207)" face=Verdana>Public Class wsSceneDrawLine<BR>  Inherits wsUtilityBaseTool</FONT></P>
<P>  Private Declare Function Polygon Lib "gdi32" (ByVal hDC As Integer, ByVal lpPoint As Integer, ByVal nCount As Integer) As Integer<BR>  Private Declare Function SetCapture Lib "USER32" (ByVal hWnd As Integer) As Integer<BR>  Private Declare Function GetCapture Lib "USER32" () As Integer<BR>  Private Declare Function ReleaseCapture Lib "USER32" () As Integer<BR>  Private Declare Function GetCursorPos Lib "USER32" (ByVal lpPoint As PointAPI) As Integer<BR>  Private Declare Function SetCursor Lib "USER32" (ByVal hCursor As Integer) As Integer<BR>  Private Declare Function GetClientRect Lib "USER32" (ByVal hWnd As Integer, ByVal lpRect As rect) As Integer<BR>  Private Declare Function GetWindowRect Lib "USER32" (ByVal hWnd As Integer, ByVal lpRect As rect) As Integer<BR>  Private Declare Function CreatePen Lib "gdi32" (ByVal nPenStyle As Integer, ByVal nWidth As Integer, ByVal crColor As Integer) As Integer<BR>  Private Declare Function GetStockObject Lib "gdi32" (ByVal nIndex As Integer) As Integer<BR>  Private Declare Function GetROP2 Lib "gdi32" (ByVal hDC As Integer) As Integer<BR>  Private Declare Function SetROP2 Lib "gdi32" (ByVal hDC As Integer, ByVal nDrawMode As Integer) As Integer<BR>  Private Declare Function Rectangle Lib "gdi32" (ByVal hDC As Integer, ByVal X1 As Integer, ByVal Y1 As Integer, ByVal X2 As Integer, ByVal Y2 As Integer) As Integer<BR>  Private Declare Function SelectObject Lib "gdi32" (ByVal hDC As Integer, ByVal hObject As Integer) As Integer<BR>  Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Integer) As Integer<BR>  Private Declare Function Polyline Lib "gdi32" (ByVal hDC As Integer, ByVal lpPoint() As PointAPI, ByVal nCount As Integer) As Integer<BR>  Private Declare Function CreatePolygonRgn Lib "gdi32" (ByVal lpPoint As Integer, ByVal nCount As Integer, ByVal nPolyFillMode As Integer) As Integer<BR>  Private Structure rect<BR>    Dim Left As Integer<BR>    Dim Top As Integer<BR>    Dim Right As Integer<BR>    Dim Bottom As Integer<BR>  End Structure<BR>  Private Structure PointAPI<BR>    Dim x As Integer<BR>    Dim y As Integer<BR>  End Structure</P>
<P><FONT style="BACKGROUND-COLOR: rgb(204,232,207)" face=Verdana>  Private m_pSceneHookhelper As ISceneHookHelper<BR>  Private m_pGlobeHookhelper As IGlobeHookHelper<BR>  Private m_bInUse As Boolean<BR>  Private m_Pen As Long, m_Brush As Long<BR>  Private m_lDrawMode As Long<BR>  Private m_pUserLine As IPointCollection<BR>  Private m_pGeoLine As IPointCollection<BR>  Private m_MovePoint_Old As IPoint '当前点<BR>  Private m_pScene As IScene<BR>  Private m_pSceneViewer As ISceneViewer<BR>  <BR>  Public Sub New()<BR>    MyBase.New()<BR>    MyBase.Tool = New ControlsScenePanTool<BR>    MyBase.m_Caption = "画线"<BR>    MyBase.m_ToolTip = "画线"<BR>    MyBase.m_Name = "画线"<BR>    MyBase.m_Message = "画线"<BR>    m_pSceneHookHelper = New SceneHookHelper<BR>  End Sub</FONT></P>
<P><FONT style="BACKGROUND-COLOR: rgb(204,232,207)" face=Verdana><FONT style="BACKGROUND-COLOR: rgb(204,232,207)" face=Verdana>  Public Overrides Sub OnCreate(ByVal hook As Object)<BR>    m_pSceneHookhelper = New SceneHookHelper<BR>    m_pSceneHookhelper.Hook = hook<BR>    m_pSceneViewer = m_pSceneHookhelper.ActiveViewer<BR>    m_pScene = m_pSceneHookhelper.Scene<BR>    If m_pScene Is Nothing Then<BR>      m_pGlobeHookhelper = New GlobeHookHelper<BR>      m_pGlobeHookhelper.Hook = hook<BR>      m_pSceneViewer = m_pGlobeHookhelper.ActiveViewer<BR>      m_pScene = m_pGlobeHookhelper.Globe<BR>    End If<BR>  End Sub</FONT><BR>  Public Overrides ReadOnly Property Enabled() As Boolean<BR>    Get<BR>      If (m_pSceneHookhelper.Scene Is Nothing) Then<BR>        Return False<BR>      Else<BR>        Return True<BR>      End If<BR>    End Get<BR>  End Property</FONT></P><FONT style="BACKGROUND-COLOR: rgb(204,232,207)" face=Verdana>
<P><BR>  Public Overrides Sub OnMouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Integer, ByVal Y As Integer)<BR>    Dim pGeoPoint As IPoint<BR>    pGeoPoint = GetGeoPointByScene(m_pScene, X, Y, m_pUserLine)<BR>    If pGeoPoint Is Nothing Then Exit Sub<BR>    m_bInUse = True</P>
<P>    Dim pStartPoint As IPoint<BR>    pStartPoint = New Point<BR>    pStartPoint.PutCoords(X, Y)</P>
<P>    m_pUserLine.AddPoint(pStartPoint)<BR>    m_pGeoLine.AddPoint(pGeoPoint)</P>
<P>    m_Pen = CreatePen(0, 2, 0)   'A solid, width of 2 black pen<BR>    m_Brush = GetStockObject(5)  'A hollow brush</P>
<P>    m_lDrawMode = GetROP2(m_pSceneViewer.hDC)<BR>    SelectObject(m_pSceneViewer.hDC, m_Pen)<BR>    SelectObject(m_pSceneViewer.hDC, m_Brush)<BR>    SetROP2(m_pSceneViewer.hDC, 14)<BR>    SetCapture(m_pSceneViewer.hWnd)<BR>  End Sub</P>
<P>  Public Overrides Sub OnMouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Integer, ByVal Y As Integer)<BR>    If Not m_bInUse Then Exit Sub<BR>    DrawLine(X, Y)<BR>  End Sub</P>
<P>  Public Overrides Sub OnMouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Integer, ByVal Y As Integer)</P>
<P>  End Sub<BR>  Public Overrides Sub OnClick()<BR>    MyBase.OnClick()<BR>    'Not implemented<BR>    m_pUserLine = New Polyline<BR>    m_pGeoLine = New Polyline<BR>  End Sub<BR>  Public Overrides Sub OnDblClick()<BR>    MyBase.OnDblClick()<BR>    If Not m_bInUse Then Exit Sub<BR>    If GetCapture = m_pSceneViewer.hWnd Then<BR>      ReleaseCapture()<BR>    End If<BR>    m_MovePoint_Old = Nothing<BR>    m_pUserLine = New Polyline<BR>    m_pGeoLine = New Polyline<BR>    m_pSceneViewer.Redraw(True)</P>
<P>    DeleteObject(m_Pen)<BR>    DeleteObject(m_Brush)<BR>    SetROP2(m_pSceneViewer.hDC, m_lDrawMode)<BR>    m_bInUse = False<BR>  End Sub<BR>  Public Overrides Sub OnKeyDown(ByVal keyCode As Integer, ByVal shift As Integer)<BR>    MyBase.OnKeyDown(keyCode, shift)<BR>    If m_bInUse = True Then<BR>      If keyCode = 0 Then<BR>        m_pSceneViewer.Redraw(True)<BR>        m_MovePoint_Old = Nothing<BR>        m_pUserLine = New Polyline<BR>        m_pGeoLine = New Polyline<BR>        'GDI calls to delete pen and brush objects<BR>        DeleteObject(m_Pen)<BR>        DeleteObject(m_Brush)<BR>        'GDI call to set device to the original draw mode<BR>        SetROP2(m_pSceneViewer.hDC, m_lDrawMode)<BR>        ReleaseCapture()<BR>        m_bInUse = False<BR>      End If<BR>    End If<BR>  End Sub<BR>  Public Sub DrawLine(ByVal x As Long, ByVal y As Long)<BR>    Dim pPtNums As Long<BR>    pPtNums = m_pUserLine.PointCount<BR>    Dim Pts() As PointAPI<BR>    ReDim Pts(pPtNums) 'As PointAPI<BR>    Dim i As Long<BR>    Dim pPoint As IPoint<BR>    For i = 0 To pPtNums - 1<BR>      pPoint = m_pUserLine.Point(i)<BR>      Pts(i).x = pPoint.X : Pts(i).y = pPoint.Y<BR>    Next<BR>    If Not m_MovePoint_Old Is Nothing Then<BR>      Pts(pPtNums).x = m_MovePoint_Old.X : Pts(pPtNums).y = m_MovePoint_Old.Y<BR>      Polyline(m_pSceneViewer.hDC, Pts, pPtNums + 1)<BR>    End If<BR>    Pts(pPtNums).x = x : Pts(pPtNums).y = y<BR>    Polyline(m_pSceneViewer.hDC, Pts, pPtNums + 1)<BR>    m_MovePoint_Old = New Point<BR>    m_MovePoint_Old.PutCoords(x, y)<BR>  End Sub  <BR>Private Function GetGeoPointByScene(ByVal pScene As IScene, ByVal x As Long, ByVal y As Long, Optional ByVal CheckPointDou As IPointCollection = Nothing) As IPoint</P>
<P>    Dim i As Long<BR>    Dim pPoint As IPoint<BR>    If Not CheckPointDou Is Nothing Then<BR>      For i = 0 To CheckPointDou.PointCount - 1<BR>        pPoint = CheckPointDou.Point(i)<BR>        If pPoint.X = x And pPoint.Y = y Then<BR>          Return Nothing<BR>          Exit Function<BR>        End If<BR>      Next<BR>    End If<BR>    Return LocatePoint(pScene, x, y)<BR>  End Function<BR>  Private Function LocatePoint(ByVal pScene As IScene, ByVal x As Long, ByVal y As Long) As IPoint<BR>    If TypeOf pScene Is IGlobe Then<BR>      Dim pGlobe As IGlobe<BR>      pGlobe = pScene<BR>      Return GlobeToPoint(pGlobe.GlobeDisplay, x, y, True)<BR>    ElseIf TypeOf pScene Is IScene Then<BR>      Return XYToPoint(pScene.SceneGraph, x, y)<BR>    Else<BR>      Return Nothing<BR>    End If<BR>  End Function</P>
<P>  Private Function GlobeToPoint(ByVal pGlobeDisplay As IGlobeDisplay, ByVal dx As Long, ByVal dy As Long, ByVal bMaxResolution As Boolean, Optional ByVal pOffset As Double = 0) As IPoint<BR>    On Error GoTo errhandler<BR>    Dim pPoint As IPoint = Nothing<BR>    Dim objectOwner As stdole.IUnknown = Nothing<BR>    Dim objectObject As stdole.IUnknown = Nothing<BR>    pGlobeDisplay.Locate(pGlobeDisplay.ActiveViewer, dx, dy, False, True, pPoint, objectOwner, objectObject)<BR>    If pPoint Is Nothing Then<BR>      Return Nothing<BR>      Exit Function<BR>    Else<BR>      If pPoint.IsEmpty Then<BR>        Return Nothing<BR>        Exit Function<BR>      End If<BR>    End If<BR>    pPoint.Z = pPoint.Z * 1000<BR>    Return pPoint<BR>    Exit Function</P>
<P>errhandler:<BR>  End Function<BR>  Private Function XYToPoint(ByVal pSceneGraph As SceneGraph, ByVal x As Long, ByVal y As Long) As IPoint</P>
<P>    Dim pSG As ISceneGraph<BR>    pSG = pSceneGraph<BR>    Dim pViewer As ISceneViewer<BR>    pViewer = pSG.ActiveViewer<BR>    Dim pOwner As stdole.IUnknown = Nothing<BR>    Dim pObject As stdole.IUnknown = Nothing<BR>    Dim pPoint As IPoint = Nothing<BR>    pSG.Locate(pViewer, x, y, esriScenePickMode.esriScenePickGeography, True, pPoint, pOwner, pObject)<BR>    pOwner = Nothing<BR>    pObject = Nothing<BR>    Return pPoint<BR>  End Function</P></FONT>
<P><FONT style="BACKGROUND-COLOR: rgb(204,232,207)" face=Verdana>End Class</FONT></P>
喜欢0 评分0
没钱又丑,农村户口。头可断,发型一定不能乱。 邮箱:gisempire@qq.com
gisren111
路人甲
路人甲
  • 注册日期2008-05-11
  • 发帖数6
  • QQ
  • 铜币122枚
  • 威望0点
  • 贡献值0点
  • 银元0个
1楼#
发布于:2008-06-05 15:57
谢谢你的共享,我现在在MapControl里做了一个橡皮线,用的是inewlinefeedback,我想同时能用右键做Pan功能,但是一旦视图刷新,前面绘制的线段就在视图上消失了,有什么好的解决办法吗, 谢谢啦。
举报 回复(0) 喜欢(0)     评分
beautymeteor
路人甲
路人甲
  • 注册日期2006-05-11
  • 发帖数15
  • QQ
  • 铜币168枚
  • 威望0点
  • 贡献值0点
  • 银元0个
2楼#
发布于:2008-06-17 11:12
lz转载请注明出处,<a href="http://www.cnblogs.com/wall/archive/2008/05/28/1209391.html" target="_blank" >http://www.cnblogs.com/wall/archive/2008/05/28/1209391.html</A>
http://wall.cnblogs.com/
举报 回复(0) 喜欢(0)     评分
murphy1314
外卖仔
外卖仔
  • 注册日期2005-05-11
  • 发帖数76
  • QQ
  • 铜币288枚
  • 威望0点
  • 贡献值0点
  • 银元0个
  • GIS帝国居民
3楼#
发布于:2008-06-23 18:32
<P>看不太明白  所有函数都被封装成lib了   代码没什么意思  希望博主能讲一下思路</P>
[url]http://hi.baidu.com/murphy1314[/url]
举报 回复(0) 喜欢(0)     评分
beautymeteor
路人甲
路人甲
  • 注册日期2006-05-11
  • 发帖数15
  • QQ
  • 铜币168枚
  • 威望0点
  • 贡献值0点
  • 银元0个
4楼#
发布于:2008-07-03 08:46
<P>所有代码都被封装成lib是什么意思?</P>
<P>那些是引用的windows的api,不是我自己封装的</P>
<P>你用过api吗????????</P>
<P>这个思路已经很清楚了,就是用windows的api来绘制线</P>
http://wall.cnblogs.com/
举报 回复(0) 喜欢(0)     评分
游客

返回顶部