object.PartialRefresh (phase, Data, envelope )---好好体会

本文详细介绍了ArcMap中的缓存机制,包括不同类型的缓存及其用途,如何使用IActiveView::PartialRefresh来提高绘图性能,以及具体的编程示例。

The main application window is controlled by a view (IActiveView).  ArcMap currently has two view objects: Map (data view) and PageLayout (layout view).  Each view has a ScreenDisplay object which performs drawing operations. The ScreenDisplay object also makes it possible for clients to create any number of caches.  A cache is an off screen bitmap representing the application's window.  Instead of drawing directly to the screen, graphics are drawn into caches, then the caches are drawn on the screen.  When the application's window is obscured模糊 晦涩 and requires redrawing, it is done so from the caches instead of from a database.  In this way, caches improve drawing performance - bitmap rendering is faster than reading and displaying data from a database.

 一个Cache是一个独立于屏幕的位图,代表着应用程序窗口.

ScreenDisplay可以是客户创建任意数量的Cache.

图象并不是直接画在屏幕上,而是先画在caches中,然后由caches画到屏幕上.

当应用程序窗口模糊需要重画的时候,直接从caches中而不是从database中进行.

通过这种方式,caches提高了效率---------位图渲染比从数据库中读显数据快得多.

In general, the Map creates three caches: one for all the layers, another if there are annotation or graphics, and a third cache if there is a feature selection.  A layer can create its own private cache if it sets ILayer::Cached equal to TRUE.  In this case, the Map will create a separate cache for the layer and groups the layers above and below it into different caches.

一般而言,地图建立三个caches:一个是为所有图层用的,另一个是在由annotation或graphics的时候用,第三个是为selection准备的.

如果图层把它的cached属性设为TRUE,这个图层(Layer)可以用来建立自己的私有cache.这样,地图将为这个图层建立一个单独的cache,地图把其他图层放在它之前或之后的不同caches中.

IActiveView::PartialRefresh uses its knowledge of the cache layout to invalidate as little as possible.  IActiveView::Refresh , on the other hand, invalidates all the caches which is very inefficient.  Use PartialRefresh whenever possible. 

使用IActiveView::Refresh效率极低,它会使所有的caches无效重画.

尽可能使用IActiveView::PartialRefresh

Both PartialRefresh and Refresh call IScreenDisplay::Invalidate which sets a flag clients watch for.  Clients draw a cache from scratch (the database) if its flag is set to true, and from cache if the flag is set to false.

PartialRefresh和Refresh会调用IScreenDisplay::Invalidate ,如果设为true,客户端从数据库画一个cache,如果false,则从cache画一个cache

The following table shows the phases each view supports and what they map to:

phaseMapLayout
esriViewBackground  Map grids Page/snap grid
esriViewGeography LayersUnused
*esriViewGeoSelection Feature selectionUnused
esriViewGraphics  Labels/graphicsGraphics
esriViewGraphicSelection Graphic selectionElement selection
esriViewForeground  UnusedSnap guides

To specify multiple draw phases, combine individual phases together using a bitwise OR. This is equivalent to adding together the integer enumeration values. For example, pass 6 to invalidate both the esriViewGeography (2) and esriViewGeoSelection (4) phases.

可以通过OR组合使用参数.

Use the data parameter to invalidate just a specific piece of data.  For example, if a layer is loaded and its cache property is set to TRUE, this layer alone can be invalidated.  A tracking layer is a good example of this.

使用参数,只会使某些数据无效重画,例如,如果一个图层被加载进来并且其cached属性设为TRUE,这个图层可以单独被invalidated,A tracking layer就是一个极好的例子.

The envelope parameter specifies a region to invalidate.  For example, if a graphic element is added, it is usually only necessary to invalidate the immediate area surrounding the new graphic.

 envelope参数指定了一个重画的区域.例如,如果一个元素被添加了,只需要重画元素周围的区域.

Both the data and envelope parameters are optional. 

*When selecting features, you must call PartialRefresh twice, once before and once after the selection operation.

选择元素的时候,你必须使用PartialRefresh两次,一次在选择操作之前,一次在选择操作之后.

In Visual Basic specify a phase of 6 to invalidate both the esriViewGeography (2) and the esriViewGeoSelection (4). 

  pActiveView.PartialRefresh esriViewGeography + esriViewGeoSelection, Nothing, Nothing 

which is the same as:

  pActiveView.PartialRefresh 6, Nothing, Nothing

Below are several usage examples in Visual Basic.

Map:

Refresh layer          pActiveView.PartialRefresh esriViewGeography, pLayer, Nothing 
Refresh all layers     pActiveView.PartialRefresh esriViewGeography, Nothing, Nothing 
Refresh selection      pActiveView.PartialRefresh esriViewGeoSelection, Nothing, Nothing
Refresh labels         pActiveView.PartialRefresh esriViewGraphics, Nothing, Nothing

PageLayout:

Refresh element        pActiveView.PartialRefresh esriViewGraphics, pElement, Nothing
Refresh all elements   pActiveView.PartialRefresh esriViewGraphics, Nothing, Nothing
Refresh selection      pActiveView.PartialRefresh esriViewGraphicSelection, Nothing, Nothing

 

 
The example shows how to select and refresh graphics and features using PartialRefresh.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Display; namespace WaterPipelineGIS2 { public partial class Form1 : Form { private IFeatureLayer _selectedFeatureLayer; private System.Drawing.Point _lastRightClickPosition; private enum SelectionMode { None, Rectangle, Circle, Polygon, Polyline } private SelectionMode currentMode = SelectionMode.None; private enum MeasureMode { None, Area, Length, Point } private MeasureMode currentMeasureMode = MeasureMode.None; private IGeometry tempGeometry; private IPointCollection pointCollection; private ToolStripStatusLabel lblMeasureResult; // 修改为ToolStripStatusLabel private IGraphicsContainer _spatialSelectionGraphics; private IGraphicsContainer _attributeHighlightGraphics; private void InitializeGraphicsContainers() { try { if (axMapControl1.ActiveView != null) { _spatialSelectionGraphics = axMapControl1.ActiveView.GraphicsContainer; _attributeHighlightGraphics = axMapControl1.ActiveView.GraphicsContainer; } } catch (Exception ex) { MessageBox.Show("初始化图形容器失败: " + ex.Message); } } private void Form1_Load(object sender, EventArgs e) { InitializeGraphicsContainers(); // 初始化量测结果标签 lblMeasureResult = new ToolStripStatusLabel(); statusStrip1.Items.Add(lblMeasureResult); } public Form1() { InitializeComponent(); // 确保设计器初始化完成 if (statusStrip1 != null) { lblMeasureResult = new ToolStripStatusLabel(); statusStrip1.Items.Add(lblMeasureResult); } InitializeGraphicsContainers(); axMapControl1.OnMouseMove += new IMapControlEvents2_Ax_OnMouseMoveEventHandler(axMapControl1_OnMouseMove); axMapControl1.OnMouseDown += new IMapControlEvents2_Ax_OnMouseDownEventHandler(axMapControl1_OnMouseDown); axMapControl1.OnDoubleClick += new IMapControlEvents2_Ax_OnDoubleClickEventHandler(axMapControl1_OnDoubleClick); } private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e) { double mapX = e.mapX; double mapY = e.mapY; lblCoordinate.Text = "X: " + mapX.ToString("F3") + " Y: " + mapY.ToString("F3"); statusStrip1.Refresh(); } private void toolStripMenuItem2_Click(object sender, EventArgs e) { using (var rotateForm = new RotateForm()) { if (rotateForm.ShowDialog() == DialogResult.OK) { try { axMapControl1.Rotation = rotateForm.RotationAngle; axMapControl1.ActiveView.Refresh(); lblCoordinate.Text += " 旋转角度:" + rotateForm.RotationAngle + "°"; } catch (Exception ex) { MessageBox.Show("旋转失败:" + ex.Message); } } } } private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e) { if (e.button == 2) // 右键 { _lastRightClickPosition = new System.Drawing.Point(e.x, e.y); ITOCControl2 tocControl = (ITOCControl2)axTOCControl1.Object; IBasicMap basicMap = null; ILayer layer = null; object other = Type.Missing; object index = Type.Missing; esriTOCControlItem itemType = esriTOCControlItem.esriTOCControlItemNone; tocControl.HitTest(e.x, e.y, ref itemType, ref basicMap, ref layer, ref other, ref index); if (itemType == esriTOCControlItem.esriTOCControlItemLayer && layer != null) { contextMenuStripTOC.Show(axTOCControl1, e.x, e.y); } } } private void openAttributeTableToolStripMenuItem_Click(object sender, EventArgs e) { ITOCControl2 tocControl = (ITOCControl2)axTOCControl1.Object; IBasicMap basicMap = null; ILayer layer = null; object other = Type.Missing; object index = Type.Missing; esriTOCControlItem itemType = esriTOCControlItem.esriTOCControlItemNone; System.Drawing.Point screenPos = contextMenuStripTOC.PointToClient(Control.MousePosition); System.Drawing.Point controlPos = axTOCControl1.PointToClient(Control.MousePosition); tocControl.HitTest( controlPos.X, controlPos.Y, ref itemType, ref basicMap, ref layer, ref other, ref index ); IFeatureLayer featureLayer = layer as IFeatureLayer; if (featureLayer != null) { _selectedFeatureLayer = featureLayer; AttributeTableForm attrForm = new AttributeTableForm( _selectedFeatureLayer, this ); attrForm.Show(); } } private void SetSelectionSymbol() { ISimpleFillSymbol fillSymbol = new SimpleFillSymbolClass(); fillSymbol.Color = GetRgbColor(255, 0, 0); fillSymbol.Style = esriSimpleFillStyle.esriSFSSolid; ISimpleLineSymbol lineSymbol = new SimpleLineSymbolClass(); lineSymbol.Color = GetRgbColor(255, 255, 0); lineSymbol.Width = 2; fillSymbol.Outline = lineSymbol; if (_selectedFeatureLayer != null) { IGeoFeatureLayer geoLayer = (IGeoFeatureLayer)_selectedFeatureLayer; ISimpleRenderer renderer = new SimpleRendererClass(); renderer.Symbol = (ISymbol)fillSymbol; geoLayer.Renderer = (IFeatureRenderer)renderer; axMapControl1.ActiveView.Refresh(); } } private IRgbColor GetRgbColor(int r, int g, int b) { IRgbColor color = new RgbColorClass(); color.Red = r; color.Green = g; color.Blue = b; return color; } private IRgbColor GetRgbColor(int r, int g, int b, int alpha) { IRgbColor color = new RgbColorClass(); color.Red = r; color.Green = g; color.Blue = b; color.Transparency = (byte)(255 - alpha); return color; } public void ActivateFeatureLayer(IFeatureLayer featureLayer) { if (featureLayer == null) return; _selectedFeatureLayer = featureLayer; axMapControl1.ActiveView.Refresh(); axTOCControl1.Update(); } public void HighlightAndZoomToFeature(IFeatureLayer featureLayer, int oid) { try { if (featureLayer == null || featureLayer.FeatureClass == null) { MessageBox.Show("图层或要素类无效!"); return; } IFeature feature = featureLayer.FeatureClass.GetFeature(oid); if (feature == null || feature.Shape == null) { MessageBox.Show("要素 OID " + oid + " 不存在或无几何!"); return; } IGeometry geometry = feature.Shape; IEnvelope envelope = geometry.Envelope; if (envelope.IsEmpty || envelope.Width == 0 || envelope.Height == 0) { envelope.Expand(10, 10, true); } else { envelope.Expand(1.5, 1.5, true); } axMapControl1.Extent = envelope; axMapControl1.ActiveView.ScreenDisplay.UpdateWindow(); HighlightGeometry(geometry); } catch (Exception ex) { MessageBox.Show("高亮要素失败: " + ex.Message); } } private void btnRectSelect_Click(object sender, EventArgs e) { currentMode = SelectionMode.Rectangle; axMapControl1.CurrentTool = null; axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair; } private void btnCircleSelect_Click(object sender, EventArgs e) { currentMode = SelectionMode.Circle; axMapControl1.CurrentTool = null; axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair; } private void btnPolygonSelect_Click(object sender, EventArgs e) { currentMode = SelectionMode.Polygon; axMapControl1.CurrentTool = null; axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair; } private void btnLineSelect_Click(object sender, EventArgs e) { currentMode = SelectionMode.Polyline; axMapControl1.CurrentTool = null; axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair; } private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e) { try { if (currentMode != SelectionMode.None) { HandleSpatialSelection(e); return; } if (currentMeasureMode != MeasureMode.None) { HandleMeasurement(e); } } catch (Exception ex) { MessageBox.Show("操作错误:" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void PerformSpatialSelection(IGeometry geometry) { try { IMap map = axMapControl1.Map; if (map == null) return; map.ClearSelection(); for (int i = 0; i < map.LayerCount; i++) { IFeatureLayer featureLayer = map.get_Layer(i) as IFeatureLayer; if (featureLayer == null || !featureLayer.Valid || featureLayer.FeatureClass == null) continue; ISpatialFilter filter = new SpatialFilterClass(); filter.Geometry = geometry; filter.GeometryField = featureLayer.FeatureClass.ShapeFieldName; filter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; IFeatureSelection selection = (IFeatureSelection)featureLayer; selection.SelectFeatures(filter, esriSelectionResultEnum.esriSelectionResultNew, false); } axMapControl1.Refresh(esriViewDrawPhase.esriViewGeoSelection, null, null); axMapControl1.ActiveView.Refresh(); } catch (Exception ex) { MessageBox.Show("空间查询失败: " + ex.Message); } } private void HighlightGeometry(IGeometry geometry) { try { if (_spatialSelectionGraphics != null) { _spatialSelectionGraphics.DeleteAllElements(); } IElement element = null; switch (geometry.GeometryType) { case esriGeometryType.esriGeometryPolygon: { ISimpleFillSymbol fillSymbol = new SimpleFillSymbolClass(); fillSymbol.Color = GetRgbColor(255, 0, 0, 80); ISimpleLineSymbol outline = new SimpleLineSymbolClass(); outline.Color = GetRgbColor(255, 0, 0); outline.Width = 2; fillSymbol.Outline = outline; element = new PolygonElementClass(); element.Geometry = geometry; ((IFillShapeElement)element).Symbol = fillSymbol; } break; case esriGeometryType.esriGeometryPolyline: { ISimpleLineSymbol lineSymbol = new SimpleLineSymbolClass(); lineSymbol.Color = GetRgbColor(255, 0, 0); lineSymbol.Width = 3; element = new LineElementClass(); element.Geometry = geometry; ((ILineElement)element).Symbol = lineSymbol; } break; case esriGeometryType.esriGeometryPoint: { ISimpleMarkerSymbol markerSymbol = new SimpleMarkerSymbolClass(); markerSymbol.Color = GetRgbColor(255, 0, 0); markerSymbol.Size = 12; element = new MarkerElementClass(); element.Geometry = geometry; ((IMarkerElement)element).Symbol = markerSymbol; } break; } if (element != null && _spatialSelectionGraphics != null) { _spatialSelectionGraphics.AddElement(element, 0); axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null); } } catch (Exception ex) { MessageBox.Show("高亮显示失败: " + ex.Message); } } private void btnClearSelection_Click(object sender, EventArgs e) { try { if (axMapControl1.Map != null) { axMapControl1.Map.ClearSelection(); } if (_spatialSelectionGraphics != null) { _spatialSelectionGraphics.DeleteAllElements(); } ClearTempGraphics(); axMapControl1.ActiveView.PartialRefresh( esriViewDrawPhase.esriViewGeoSelection | esriViewDrawPhase.esriViewGraphics, null, null ); axMapControl1.ActiveView.Refresh(); currentMode = SelectionMode.None; axMapControl1.MousePointer = esriControlsMousePointer.esriPointerDefault; currentMeasureMode = MeasureMode.None; } catch (Exception ex) { MessageBox.Show("清除选择失败: " + ex.Message); } } private void axMapControl1_OnDoubleClick(object sender, IMapControlEvents2_OnDoubleClickEvent e) { if (currentMode != SelectionMode.None) { currentMode = SelectionMode.None; axMapControl1.CurrentTool = null; axMapControl1.MousePointer = esriControlsMousePointer.esriPointerDefault; } if (currentMeasureMode == MeasureMode.Area || currentMeasureMode == MeasureMode.Length) { if (pointCollection != null && pointCollection.PointCount > 1) { ShowMeasureResult(); pointCollection = null; currentMeasureMode = MeasureMode.None; axMapControl1.MousePointer = esriControlsMousePointer.esriPointerDefault; } } } private void btnMeasureArea_Click(object sender, EventArgs e) { ResetMeasureMode(MeasureMode.Area); if (lblMeasureResult != null) lblMeasureResult.Text = "状态:绘制多边形(双击结束)"; } private void btnMeasureLength_Click(object sender, EventArgs e) { ResetMeasureMode(MeasureMode.Length); if (lblMeasureResult != null) lblMeasureResult.Text = "状态:绘制折线(双击结束)"; } private void btnMeasurePoint_Click(object sender, EventArgs e) { ResetMeasureMode(MeasureMode.Point); if (lblMeasureResult != null) lblMeasureResult.Text = "状态:移动鼠标查看坐标"; } private void ResetMeasureMode(MeasureMode mode) { currentMeasureMode = mode; ClearTempGraphics(); axMapControl1.CurrentTool = null; axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair; } private void ClearTempGraphics() { try { if (_spatialSelectionGraphics != null) { _spatialSelectionGraphics.DeleteAllElements(); axMapControl1.ActiveView.PartialRefresh( esriViewDrawPhase.esriViewGraphics, null, null ); } pointCollection = null; } catch (Exception ex) { MessageBox.Show("清除临时图形失败: " + ex.Message); } } private void HandleSpatialSelection(IMapControlEvents2_OnMouseDownEvent e) { IGeometry geometry = null; switch (currentMode) { case SelectionMode.Rectangle: IEnvelope rectEnv = axMapControl1.TrackRectangle(); if (rectEnv != null) { IPolygon polygon = new PolygonClass(); polygon.SpatialReference = axMapControl1.SpatialReference; ISegmentCollection segColl = (ISegmentCollection)polygon; segColl.SetRectangle(rectEnv); geometry = (IGeometry)polygon; } break; case SelectionMode.Circle: IEnvelope envelope = axMapControl1.TrackRectangle(); if (envelope.Width <= 0 || envelope.Height <= 0) { MessageBox.Show("请拖拽有效的矩形范围以创建圆形!"); return; } IPoint center = new PointClass(); center.PutCoords( (envelope.XMin + envelope.XMax) / 2, (envelope.YMin + envelope.YMax) / 2 ); double radius = Math.Max(envelope.Width, envelope.Height) / 2; ICircularArc circularArc = new CircularArcClass(); IConstructCircularArc constructArc = (IConstructCircularArc)circularArc; constructArc.ConstructCircle(center, radius, true); ISegmentCollection circleSegColl = new PolygonClass(); circleSegColl.AddSegment((ISegment)circularArc); geometry = (IGeometry)circleSegColl; geometry.SpatialReference = axMapControl1.SpatialReference; break; case SelectionMode.Polygon: geometry = axMapControl1.TrackPolygon(); break; case SelectionMode.Polyline: geometry = axMapControl1.TrackLine(); break; } if (geometry != null) { PerformSpatialSelection(geometry); HighlightGeometry(geometry); } } private void HandleMeasurement(IMapControlEvents2_OnMouseDownEvent e) { if (currentMeasureMode == MeasureMode.None) return; IPoint currentPoint = axMapControl1.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y); switch (currentMeasureMode) { case MeasureMode.Area: case MeasureMode.Length: if (pointCollection == null) { pointCollection = currentMeasureMode == MeasureMode.Area ? (IPointCollection)new PolygonClass() : (IPointCollection)new PolylineClass(); pointCollection.AddPoint(currentPoint); } pointCollection.AddPoint(currentPoint); DrawTempGeometry(); break; } } private void DrawTempGeometry() { if (pointCollection == null) return; ClearTempGraphics(); IElement element = null; if (pointCollection is IPolygon) { ISimpleFillSymbol fillSymbol = new SimpleFillSymbolClass(); fillSymbol.Color = GetRgbColor(0, 255, 0, 50); ISimpleLineSymbol outline = new SimpleLineSymbolClass(); outline.Color = GetRgbColor(0, 255, 0); outline.Width = 2; fillSymbol.Outline = outline; element = new PolygonElementClass(); element.Geometry = (IGeometry)pointCollection; ((IFillShapeElement)element).Symbol = fillSymbol; } else if (pointCollection is IPolyline) { ISimpleLineSymbol lineSymbol = new SimpleLineSymbolClass(); lineSymbol.Color = GetRgbColor(0, 255, 0); lineSymbol.Width = 2; element = new LineElementClass(); element.Geometry = (IGeometry)pointCollection; ((ILineElement)element).Symbol = lineSymbol; } if (element != null && _spatialSelectionGraphics != null) { _spatialSelectionGraphics.AddElement(element, 0); axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null); } } private void ShowMeasureResult() { try { if (pointCollection == null) return; double result = 0; string unit = ""; ISpatialReference spatialRef = axMapControl1.SpatialReference; if (pointCollection is IPolygon) { IPolygon polygon = pointCollection as IPolygon; ITopologicalOperator topoOp = polygon as ITopologicalOperator; topoOp.Simplify(); IArea area = polygon as IArea; result = area.Area; unit = "平方米"; } else if (pointCollection is IPolyline) { IPolyline polyline = pointCollection as IPolyline; ICurve curve = polyline as ICurve; result = curve.Length; unit = "米"; } else { return; } if (lblMeasureResult != null) lblMeasureResult.Text = "测量结果: " + result.ToString("F2") + " " + unit; } catch (Exception ex) { MessageBox.Show("计算量测结果失败: " + ex.Message); } } } }点击空间量测后怎么进行量测,我怎么右击mapcontrol控件(axMapControl1)不进行绘制量测呢,给出修改后的完整代码,不要省略任何部分,注意vs版本为2010
07-13
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值