aibogis
路人甲
路人甲
  • 注册日期2006-06-28
  • 发帖数7
  • QQ
  • 铜币130枚
  • 威望0点
  • 贡献值0点
  • 银元0个
阅读:3754回复:12

请教一个engine中实现捕捉功能的问题

楼主#
更多 发布于:2006-06-28 20:18
<P>各位大侠,请教一个捕捉的问题。</P>
<P>我现在通过hittest已经得到了捕捉点,我想像arcmap的sketch工具一样,通过一个小圆圈表示当前捕捉到的点。</P>
<P>请问通过什么方法绘制这个小圆圈比较好? 多谢!</P>
<P>我现在是通过element来绘制的,但对鼠标轨迹的擦除不是很好,总是有些痕迹的残留。代码如下:</P>
<P>捕捉鼠标绘制<BR>Dim pCurrentSymbol As ISimpleMarkerSymbol<BR>pCurrentSymbol = New SimpleMarkerSymbol<BR>With pCurrentSymbol<BR>     .Outline = True<BR>     .OutlineSize = 0.2<BR>     .OutlineColor = GetRGBColor(0, 0, 0)<BR>     .Color = GetRGBColor(0, 200, 240, 0)<BR>     .Style = esriSimpleMarkerStyle.esriSMSSquare<BR>     .Size = 6<BR>End With</P>
<P>Dim pPointGeo As IGeometry<BR>pPointGeo = m_pPoint     'm_pPoint是捕捉到的点,从窗体传入类中的<BR>Dim pElement As IElement<BR>Dim pME As IMarkerElement<BR>pME = New MarkerElement<BR>pElement = pME<BR>pElement.Geometry = pPointGeo<BR>pME.Symbol = pCurrentSymbol</P>
<P>Dim pGraphicsContainer As IGraphicsContainer<BR>pGraphicsContainer = GetMap()<BR>pGraphicsContainer.DeleteAllElements()<BR>pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, pElement, Nothing)<BR>pGraphicsContainer.AddElement(pElement, 0)</P>
<P>Dim pEnve As IEnvelope               ’用于擦除鼠标轨迹的矩形区域<BR>If m_pOldPoint Is Nothing Then      <BR>         m_pOldPoint.PutCoords(m_pPoint.X, m_pPoint.Y)<BR>End If<BR>pEnve = m_pOldPoint.Envelope<BR>pEnve.Height = 10<BR>pEnve.Width = 10<BR>pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, Nothing, pEnve)</P>
<P>pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, pElement, Nothing)</P>
<P>m_pOldPoint = m_pPoint</P>
喜欢0 评分0
aibogis
路人甲
路人甲
  • 注册日期2006-06-28
  • 发帖数7
  • QQ
  • 铜币130枚
  • 威望0点
  • 贡献值0点
  • 银元0个
1楼#
发布于:2006-07-05 21:42
Dim pSymbol As ISymbol<BR>pSymbol = pCurrentSymbol<BR>pSymbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen
<P>通过这个Symbol重绘小圆圈,即可实现擦除!</P>
<P>这是一个很好的方法,大家可以试试。呵呵!</P>
举报 回复(0) 喜欢(0)     评分
aibogis
路人甲
路人甲
  • 注册日期2006-06-28
  • 发帖数7
  • QQ
  • 铜币130枚
  • 威望0点
  • 贡献值0点
  • 银元0个
2楼#
发布于:2006-07-05 09:54
<P>        Dim pSymbol As ISymbol<BR>        pSymbol = pCurrentSymbol<BR>        pSymbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen</P>
<P>通过这个Symbol重绘小圆圈,即可实现擦除!</P>
<P>这是一个很好的方法,大家可以试试。呵呵!</P>
举报 回复(0) 喜欢(0)     评分
wanilyer
路人甲
路人甲
  • 注册日期2004-12-29
  • 发帖数43
  • QQ
  • 铜币60枚
  • 威望0点
  • 贡献值0点
  • 银元0个
3楼#
发布于:2006-07-03 11:52
<P>你可以在移动之前就是绘制小圆圈之前 先擦掉原来已经画的圆圈</P>
举报 回复(0) 喜欢(0)     评分
semon1981
路人甲
路人甲
  • 注册日期2006-06-04
  • 发帖数28
  • QQ
  • 铜币198枚
  • 威望0点
  • 贡献值0点
  • 银元0个
4楼#
发布于:2006-07-02 11:47
<P>在使用的时候发现在扑获以后不能 移动 鼠标,所以隔一段时间进行扑获</P>
<P>全局变量:</P>
<P>const int internalTime = 10;//时间间隔</P>
<P>int snapTime =10;//初始值</P>
<P>在map mousemove中的代码</P>
<P>                 IPoint iPt = null;</P>
<P>                snapTime+++;</P>
<P>                snapTime = snapTime%internalTime ;<BR>                //鼠标自动扑获顶点  </P>
<P>                if(snapTime ==0)             <BR>                    iPt = Snapping(e.x, e.y, m_iFeatureLyr);<BR>                if (bCreateElement)<BR>                {<BR>                    CreateMarkerElement(e.x, e.y);<BR>                    bCreateElement = false;<BR>                }<BR>                else if (iPt != null)<BR>                    ElementMoveTo(iPt);<BR>                else<BR>                    m_featEdit.ElementMoveTo(pt12);<BR>                if (iPt != null)<BR>                {<BR>                    map.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(iPt, out x1, out y1);<BR>                    System.Drawing.Point pt1 = PointToScreen(new System.Drawing.Point(x1, y1));</P>
<P>                    System.Drawing.Point pt11 = map.PointToScreen(new System.Drawing.Point(x1, y1));<BR>                    SetCursorPos(pt11.X, pt11.Y);                </P>
<P>                 }</P>
举报 回复(0) 喜欢(0)     评分
aibogis
路人甲
路人甲
  • 注册日期2006-06-28
  • 发帖数7
  • QQ
  • 铜币130枚
  • 威望0点
  • 贡献值0点
  • 银元0个
5楼#
发布于:2006-06-30 22:17
<P>semon1981,多谢!</P>
<P>我用了另一个方法,大家研究一下:</P>
<P>            ''捕捉鼠标绘制<BR>            If m_pIfSnap Then<BR>                Dim pCurrentSymbol As ISimpleMarkerSymbol<BR>                pCurrentSymbol = New SimpleMarkerSymbol</P>
<P>                With pCurrentSymbol<BR>                    .Outline = True<BR>                    .OutlineSize = 0.2<BR>                    .OutlineColor = GetRGBColor(0, 0, 0)<BR>                    .Color = GetRGBColor(0, 200, 240, 0)<BR>                    .Style = esriSimpleMarkerStyle.esriSMSSquare<BR>                    .Size = 6<BR>                End With</P>
<P>                Dim pPointGeo As IGeometry<BR>                pPointGeo = m_pPoint<BR>                With pScreenDisplay<BR>                    .ActiveCache = -1<BR>                    .StartDrawing(0, -1)<BR>                    .SetSymbol(pCurrentSymbol)<BR>                    .DrawPoint(pPointGeo)<BR>                    .FinishDrawing()<BR>                End With<BR>            Else<BR>                pScreenDisplay.Invalidate(pActiveView.Extent.Envelope, True, -1)<BR>            End If</P>
举报 回复(0) 喜欢(0)     评分
semon1981
路人甲
路人甲
  • 注册日期2006-06-04
  • 发帖数28
  • QQ
  • 铜币198枚
  • 威望0点
  • 贡献值0点
  • 银元0个
6楼#
发布于:2006-06-30 14:13
<P>     我的实现方法,先建立一个element,同时用IDisplayFeedback 随着鼠标移动该元素:</P>
<P>       //移动elment对象<BR>        public IDisplayFeedback m_iElementFeedBack;<BR>        public IElement m_element;</P>
<P>       public void  CreateMarkerElement(int x,int y)<BR>        {<BR>            IActiveView iView = map.ActiveView;<BR>            //清除选择<BR>            map.Map.ClearSelection();<BR>            //x,y鼠标位置<BR>            IPoint iPt = iView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);<BR>            IGraphicsContainer iGraphContainer = map.Map as IGraphicsContainer;<BR>            //IElement iElement;<BR>            //建立一个marker元素<BR>            IMarkerElement iMarkerElement = new MarkerElement() as IMarkerElement;<BR>            ISimpleMarkerSymbol iSym = new SimpleMarkerSymbol();<BR>            //符号化元素<BR>            IRgbColor iColor = new RgbColor();<BR>            iColor.Red = 0;<BR>            iColor.Blue = 100;<BR>            iColor.Green = 255;<BR>            iSym.Color = iColor;<BR>            <BR>            IRgbColor iColor2 = new RgbColor();<BR>            iColor2.Red = 0;<BR>            iColor2.Blue = 0;<BR>            iColor2.Green = 0;<BR>            iSym.Outline = true;<BR>            iSym.OutlineColor = iColor2 as IColor;<BR>            iSym.OutlineSize = 1;<BR>            iSym.Size = 5;<BR>            iSym.Style = esriSimpleMarkerStyle.esriSMSCircle;</P>
<P>            iMarkerElement.Symbol = iSym;<BR>            m_element = iMarkerElement as IElement;<BR>            m_element.Geometry = iPt as IGeometry;<BR>            iGraphContainer.AddElement(m_element, 0);<BR>            iView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, m_element, null);<BR>            //iView.Refresh();<BR>            //m_element = iElement;</P>
<P>            IGeometry iGeo = m_element.Geometry;<BR>            m_iElementFeedBack = new MovePointFeedback();<BR>            m_iElementFeedBack.Display = iView.ScreenDisplay;<BR>     <BR>            IMovePointFeedback iMovePtFdBack = m_iElementFeedBack as IMovePointFeedback;<BR>            //feedback具有与该元素有相同的symbol<BR>            iMovePtFdBack.Symbol = iSym as ISymbol;<BR>            iMovePtFdBack.Start(iGeo as IPoint, iPt);<BR>        }</P>
<P>        public void ElementMoveTo(IPoint iPt)<BR>        {<BR>            map.Map.ClearSelection();<BR>            //移动元素<BR>            m_iElementFeedBack.MoveTo(iPt);<BR>            IGeometry iGeo1 = null;<BR>            IGeometry iGeoResult;<BR>            if (m_element != null)<BR>            {<BR>                iGeo1 = m_element.Geometry;<BR>                IMovePointFeedback iPtFeedback;<BR>                iPtFeedback = m_iElementFeedBack as IMovePointFeedback;<BR>                iGeoResult = iPtFeedback.Stop();<BR>                //map.ActiveView.Refresh();<BR>                m_element.Geometry = iGeoResult;<BR>                //更新该元素的位置<BR>                map.ActiveView.GraphicsContainer.UpdateElement(m_element);<BR>                //重新移动元素<BR>                iPtFeedback.Start(iGeo1 as IPoint, iPt);<BR>                //map.ActiveView.Refresh();<BR>                map.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);<BR>            }<BR>        }</P>
<P>在map mousemove中的代码</P>
<P>IPoint iPt = null;<BR>                //鼠标自动扑获顶点               <BR>                iPt = Snapping(e.x, e.y, m_iFeatureLyr);<BR>                if (bCreateElement)<BR>                {<BR>                    CreateMarkerElement(e.x, e.y);<BR>                    bCreateElement = false;<BR>                }<BR>                else if (iPt != null)<BR>                    ElementMoveTo(iPt);<BR>                else<BR>                    m_featEdit.ElementMoveTo(pt12);<BR>                if (iPt != null)<BR>                {<BR>                    map.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(iPt, out x1, out y1);<BR>                    System.Drawing.Point pt1 = PointToScreen(new System.Drawing.Point(x1, y1));</P>
<P>                    System.Drawing.Point pt11 = map.PointToScreen(new System.Drawing.Point(x1, y1));<BR>                    SetCursorPos(pt11.X, pt11.Y);                </P>
<P>}</P>

<P>public IPoint Snapping(int x, int y, IFeatureLayer iFeatureLyr)<BR>        {<BR>         <BR>            //扑获顶点vertex<BR>            <BR>            IPoint iHitPoint = null;<BR>            IMap iMap = map.Map;<BR>            IActiveView iView = map.ActiveView;<BR>            IFeatureClass iFClss = iFeatureLyr.FeatureClass;</P>
<P>            SelectFeature(x, y, iFeatureLyr,false);<BR>            IEnumFeature iSelected = (IEnumFeature)map.Map.FeatureSelection;<BR>            iSelected.Reset();<BR>            IFeature iF = iSelected.Next();<BR>            if (iF == null) return null;</P>
<P>            IPoint iPt = iView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);<BR>            IPoint iHitPt = new ESRI.ArcGIS.Geometry.Point();<BR>            IHitTest iHitTest = iF.Shape as IHitTest;<BR>            double hitDist = 0;<BR>            int partIndex = 0;<BR>            int vertexIndex = 0;<BR>            bool bVertexHit = false;<BR>            // Tolerance in pixels for line hits<BR>            double tol = ConvertPixelsToMapUnits(iView, 3);</P>
<P>            if (iHitTest.HitTest(iPt,3, esriGeometryHitPartType.esriGeometryPartVertex,<BR>                iHitPt, ref hitDist, ref partIndex, ref vertexIndex, ref bVertexHit))<BR>            {<BR>                iHitPoint = iHitPt;<BR>            }<BR>            map.ActiveView.Refresh();<BR>            return iHitPoint;<BR>        }<BR></P>
举报 回复(0) 喜欢(0)     评分
aibogis
路人甲
路人甲
  • 注册日期2006-06-28
  • 发帖数7
  • QQ
  • 铜币130枚
  • 威望0点
  • 贡献值0点
  • 银元0个
7楼#
发布于:2006-06-30 08:46
<P>就是ArcMap的Sketch工具中的鼠标显示。</P>
<P>研究好几天了,还是没搞出来。:(</P>
举报 回复(0) 喜欢(0)     评分
semon1981
路人甲
路人甲
  • 注册日期2006-06-04
  • 发帖数28
  • QQ
  • 铜币198枚
  • 威望0点
  • 贡献值0点
  • 银元0个
8楼#
发布于:2006-06-29 21:28
<P>我跟你一样的问题</P>
<P>在快速移动鼠标时候,扑获出现很多的小圆圈,停止鼠标移动才会消失多余的小圆圈。</P>
<P>我用sleep及一个耗时的循环,同样出现这个问题,问题出在用hittest扑获速度太慢,而鼠标移动太快就会出现很多的小圆圈。</P>
<P>望 高手解答</P>
举报 回复(0) 喜欢(0)     评分
gis
gis
管理员
管理员
  • 注册日期2003-07-16
  • 发帖数15951
  • QQ
  • 铜币25345枚
  • 威望15368点
  • 贡献值0点
  • 银元0个
  • GIS帝国居民
  • 帝国沙发管家
  • GIS帝国明星
  • GIS帝国铁杆
9楼#
发布于:2006-06-29 17:30
<P>跟随鼠标的小圆圈?</P>
<P>最简单的方式就是更改鼠标的icur了:)</P>
GIS麦田守望者,期待与您交流。
举报 回复(0) 喜欢(0)     评分
上一页
游客

返回顶部