/// <summary> /// 从缓存中获得当前图层的纹理对象,若不存在,则返回null /// </summary> protected GCPTexture GetTexture(GCP GCP) { object key = null; if (GCP.Image == null) { key = GCP.TextureFileName; } else { key = GCP.Image; } if (key == null) { return(null); } GCPTexture res = (GCPTexture)m_textures[key]; return(res); }
/// <summary> /// 初始化控制点集合:1.把所有的控制点读到缓存Hashtable中去,并设置GCP的高宽.2.计算每个GCP的包围范围 /// </summary> /// <param name="drawArgs"></param> public override void Initialize(DrawArgs drawArgs) { //判断是否显示此图层,若不显示,则返回 if (!isOn) { return; } //判断绘制GCP的对象,是否存在,若不存在,则创建,若存在,则先释放 if (m_sprite != null) { m_sprite.Dispose(); m_sprite = null; } m_sprite = new Sprite(drawArgs.device); System.TimeSpan smallestRefreshInterval = System.TimeSpan.MaxValue; // 添加所有的GCP对象的纹理到缓存中去,并设置GCP的宽与高 foreach (RenderableObject ro in m_children) { GCP gcp = ro as GCP; if (gcp == null) { // 判断当前GCP是否显示,若不显示,则Continue下一个 if (ro.IsOn) { ro.Initialize(drawArgs); } continue; } if (gcp.RefreshInterval.TotalMilliseconds != 0 && gcp.RefreshInterval != TimeSpan.MaxValue && gcp.RefreshInterval < smallestRefreshInterval) { smallestRefreshInterval = gcp.RefreshInterval; } // 子GCP初始化 gcp.Initialize(drawArgs); object key = null; //创建一个GCPeTexture对象 GCPTexture gcpTexture = null; //从文件中读取当前GCP纹理 if (gcp.TextureFileName != null && gcp.TextureFileName.Length > 0) { // 从缓存中读取GCP纹理对象 gcpTexture = (GCPTexture)m_textures[gcp.TextureFileName]; //若缓存中不存在,则从文件中读取GCP对象 if (gcpTexture == null) { key = gcp.TextureFileName; gcpTexture = new GCPTexture(drawArgs.device, gcp.TextureFileName); } } //从Bitmap对象中读取GCP对象 else { if (gcp.Image != null) { gcpTexture = (GCPTexture)m_textures[gcp.Image]; if (gcpTexture == null) { key = gcp.Image; gcpTexture = new GCPTexture(drawArgs.device, gcp.Image); } } } //若仍然没有纹理,则循环下一个 if (gcpTexture == null) { continue; } //若有纹理的话 if (key != null) { //把纹理放到缓存中去 m_textures.Add(key, gcpTexture); // 设置GCP的宽度 if (gcp.Width == 0) { gcp.Width = gcpTexture.Width; } // 设置GCP的高度 if (gcp.Height == 0) { gcp.Height = gcpTexture.Height; } } } // 计算GCP的包围盒 foreach (RenderableObject ro in m_children) { GCP GCP = ro as GCP; if (GCP == null) { continue; } if (GetTexture(GCP) == null) { //计算文字的范围 GCP.SelectionRectangle = drawArgs.DefaultDrawingFont.MeasureString(null, GCP.Name, DrawTextFormat.None, 0); } else { //计算控制点的范围 GCP.SelectionRectangle = new Rectangle(0, 0, GCP.Width, GCP.Height); } // Center the box at (0,0) GCP.SelectionRectangle.Offset(-GCP.SelectionRectangle.Width / 2, -GCP.SelectionRectangle.Height / 2); } if (refreshTimer == null && smallestRefreshInterval != TimeSpan.MaxValue) { refreshTimer = new System.Timers.Timer(smallestRefreshInterval.TotalMilliseconds); refreshTimer.Elapsed += new System.Timers.ElapsedEventHandler(refreshTimer_Elapsed); refreshTimer.Start(); } IsInitialized = true; }
/// <summary> /// 刷新控制点集合图层 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void refreshTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if (isUpdating) { return; } isUpdating = true; try { for (int i = 0; i < this.ChildObjects.Count; i++) { RenderableObject ro = (RenderableObject)this.ChildObjects[i]; if (ro != null && ro.IsOn && ro is GCP) { GCP GCP = (GCP)ro; if (GCP.RefreshInterval == TimeSpan.MaxValue || GCP.LastRefresh > System.DateTime.Now - GCP.RefreshInterval) { continue; } object key = null; GCPTexture GCPTexture = null; if (GCP.TextureFileName != null && GCP.TextureFileName.Length > 0) { // GCP image from file GCPTexture = (GCPTexture)m_textures[GCP.TextureFileName]; if (GCPTexture != null) { GCPTexture tempTexture = GCPTexture; m_textures[GCP.SaveFilePath] = new GCPTexture(DrawArgs.Device, GCP.TextureFileName); tempTexture.Dispose(); } else { key = GCP.SaveFilePath; GCPTexture = new GCPTexture(DrawArgs.Device, GCP.TextureFileName); // New texture, cache it m_textures.Add(key, GCPTexture); // Use default dimensions if not set if (GCP.Width == 0) { GCP.Width = GCPTexture.Width; } if (GCP.Height == 0) { GCP.Height = GCPTexture.Height; } } } else { // GCP image from bitmap if (GCP.Image != null) { GCPTexture = (GCPTexture)m_textures[GCP.Image]; if (GCPTexture != null) { GCPTexture tempTexture = GCPTexture; m_textures[GCP.SaveFilePath] = new GCPTexture(DrawArgs.Device, GCP.Image); tempTexture.Dispose(); } else { key = GCP.SaveFilePath; GCPTexture = new GCPTexture(DrawArgs.Device, GCP.Image); // New texture, cache it m_textures.Add(key, GCPTexture); // Use default dimensions if not set if (GCP.Width == 0) { GCP.Width = GCPTexture.Width; } if (GCP.Height == 0) { GCP.Height = GCPTexture.Height; } } } } GCP.LastRefresh = System.DateTime.Now; } } } catch (Exception ex) { throw new Exception(ex.ToString()); } finally { isUpdating = false; } }
/// <summary> /// 渲染控制点 /// </summary> protected virtual void Render(DrawArgs drawArgs, GCP gcp, Vector3 projectedPoint) { //判断当前GCP是否被初始化了,比如,若重新定义了控制点的位置,则它的isInitialized就是false if (!gcp.IsInitialized) { gcp.Initialize(drawArgs); } //判断当前控制点是否在视地范围内,若不在,则不进行绘制 if (!drawArgs.WorldCamera.ViewFrustum.ContainsPoint(gcp.Position)) { return; } // 判断控制点是否在最大,最小可见的范围内,若不在,则不进行绘制 double distanceToGCP = Vector3.Length(gcp.Position - drawArgs.WorldCamera.Position); if (distanceToGCP > gcp.MaximumDisplayDistance) { return; } if (distanceToGCP < gcp.MinimumDisplayDistance) { return; } //获得当前图层的纹理对象 GCPTexture gcpTexture = GetTexture(gcp); //判断是否是MouseOver对象 bool isMouseOver = gcp == mouseOverGCP; //若是MouseOver对象,则绘制Description里的内容 if (isMouseOver) { //若是MouseOver对象 isMouseOver = true; //若当前图层可以操作,则设置当前的鼠标是Hand if (gcp.IsSelectable) { DrawArgs.MouseCursor = DrawArgs.MouseCursor == CursorType.SizeAll ? CursorType.SizeAll : CursorType.Hand; } //显示文字描述信息,暂时不需要 string description = string.Format("纬度:{0:f6}°\n经度:{1:f6}°\n", gcp.Latitude, gcp.Longitude); //绘制文字信息 if (description != null) { //设置文字的绘制区域 DrawTextFormat format = DrawTextFormat.NoClip | DrawTextFormat.WordBreak | DrawTextFormat.Bottom; Rectangle rect = Rectangle.FromLTRB(DrawArgs.CurrentMousePosition.X, DrawArgs.CurrentMousePosition.Y, DrawArgs.CurrentMousePosition.X + 200, DrawArgs.CurrentMousePosition.Y + 60); //绘制边框 drawArgs.DefaultDrawingFont.DrawText( m_sprite, description, rect, format, 0xb0 << 24); rect.Offset(2, 0); drawArgs.DefaultDrawingFont.DrawText( m_sprite, description, rect, format, 0xb0 << 24); rect.Offset(0, 2); drawArgs.DefaultDrawingFont.DrawText( m_sprite, description, rect, format, 0xb0 << 24); rect.Offset(-2, 0); drawArgs.DefaultDrawingFont.DrawText( m_sprite, description, rect, format, 0xb0 << 24); // 绘制文字信息 rect.Offset(1, -1); drawArgs.DefaultDrawingFont.DrawText( m_sprite, description, rect, format, descriptionColor); } } //获取颜色 int color = isMouseOver ? hotColor : normalColor; if (gcpTexture == null || isMouseOver || gcp.NameAlwaysVisible) { // 绘制控制点的名称 if (gcp.Name != null) { // Render name field const int labelWidth = 1000; // Dummy value needed for centering the text if (gcpTexture == null) { // Center over target as we have no bitmap Rectangle rect = new Rectangle( (int)projectedPoint.X - (labelWidth >> 1), (int)(projectedPoint.Y - (drawArgs.GCPNameFont.Description.Height >> 1)), labelWidth, drawArgs.ScreenHeight); drawArgs.GCPNameFont.DrawText(m_sprite, gcp.Name, rect, DrawTextFormat.Center, color); } else { // Adjust text to make room for GCP int spacing = (int)(gcp.Width * 0.3f); if (spacing > 10) { spacing = 10; } int offsetForGCP = (gcp.Width >> 1) + spacing; Rectangle rect = new Rectangle( (int)projectedPoint.X + offsetForGCP, (int)(projectedPoint.Y - (drawArgs.GCPNameFont.Description.Height >> 1)), labelWidth, drawArgs.ScreenHeight); drawArgs.GCPNameFont.DrawText(m_sprite, gcp.Name, rect, DrawTextFormat.WordBreak, color); } } } //绘制控制点 if (gcpTexture != null) { // Render GCP float xscale = (float)gcp.Width / gcpTexture.Width; float yscale = (float)gcp.Height / gcpTexture.Height; m_sprite.Transform = Matrix.Scaling(xscale, yscale, 0); if (gcp.IsRotated) { m_sprite.Transform *= Matrix.RotationZ((float)gcp.Rotation.Radians - (float)drawArgs.WorldCamera.Heading.Radians); } m_sprite.Transform *= Matrix.Translation(projectedPoint.X, projectedPoint.Y, 0); m_sprite.Draw(gcpTexture.Texture, new Vector3(gcpTexture.Width >> 1, gcpTexture.Height >> 1, 0), Vector3.Empty, color); // Reset transform to prepare for text rendering later m_sprite.Transform = Matrix.Identity; } }