/// <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> /// /// </summary> /// <param name="oldRenderable"></param> /// <param name="newRenderable"></param> private void updateRenderable(RenderableObject oldRenderable, RenderableObject newRenderable) { if (oldRenderable is Icon && newRenderable is Icon) { Icon oldIcon = (Icon)oldRenderable; Icon newIcon = (Icon)newRenderable; oldIcon.SetPosition((float)newIcon.Latitude, (float)newIcon.Longitude, (float)newIcon.Altitude); } else if (oldRenderable is GCP && newRenderable is GCP) { GCP oldGCP = (GCP)oldRenderable; GCP newGCP = (GCP)newRenderable; oldGCP.SetPosition((float)newGCP.Latitude, (float)newGCP.Longitude, (float)newGCP.Altitude); } else if (oldRenderable is RenderableObjectList && newRenderable is RenderableObjectList) { RenderableObjectList oldList = (RenderableObjectList)oldRenderable; RenderableObjectList newList = (RenderableObjectList)newRenderable; compareRefreshLists(newList, oldList); } }
///<summary> /// 使照相机ZOOM到图层的位置。 /// </summary> protected virtual void OnGotoClick(object sender, EventArgs e) { lock (this.ParentList.ChildObjects.SyncRoot) { for (int i = 0; i < this.ParentList.ChildObjects.Count; i++) { RenderableObject ro = (RenderableObject)this.ParentList.ChildObjects[i]; if (ro.Name.Equals(name)) { if (ro is QuadTileSet) {//瓦片集 QuadTileSet qts = (QuadTileSet)ro; //设置摄像机位置 DrawArgs.Camera.SetPosition((qts.North + qts.South) / 2, (qts.East + qts.West) / 2); //垂直视域范围 double perpendicularViewRange = (qts.North - qts.South > qts.East - qts.West ? qts.North - qts.South : qts.East - qts.West); //高度,海拔 DrawArgs.Camera.Altitude = qts.LayerRadius * Math.Sin(MathEngine.DegreesToRadians(perpendicularViewRange * 0.5)); break; } else if (ro is Icon) {//图标 Icon ico = (Icon)ro; DrawArgs.Camera.SetPosition(ico.Latitude, ico.Longitude); if (ico.Altitude != 0) { DrawArgs.Camera.Altitude = ico.Altitude; } else { DrawArgs.Camera.Altitude = ico.MaximumDisplayDistance - 100000; } break; } else if (ro is Icons) { double lat = 0, lon = 0; Icons icons = ro as Icons; foreach (Icon icon in icons.ChildObjects) { lat += icon.Latitude; lon += icon.Longitude; } lat /= ((Icons)ro).ChildObjects.Count; lon /= ((Icons)ro).ChildObjects.Count; DrawArgs.Camera.SetPosition(lat, lon); if (icons.MaximumDisplayDistance > 16521634) { icons.MaximumDisplayDistance = 16521634; } DrawArgs.Camera.Altitude = icons.MaximumDisplayDistance - 100000; break; } else if (ro is GCP) { GCP gcp = (GCP)ro; DrawArgs.Camera.SetPosition(gcp.Latitude, gcp.Longitude); break; } else if (ro is GCPs) { double lat = 0, lon = 0; foreach (GCP gcp in ((GCPs)ro).ChildObjects) { lat += gcp.Latitude; lon += gcp.Longitude; } lat /= ((GCPs)ro).ChildObjects.Count; lon /= ((GCPs)ro).ChildObjects.Count; DrawArgs.Camera.SetPosition(lat, lon); break; } else { DrawArgs.Camera.SetPosition((ro.Extension.North + ro.Extension.South) / 2, (ro.Extension.West + ro.Extension.East) / 2); //垂直视域范围 double perpendicularViewRange = (ro.Extension.North - ro.Extension.South > ro.Extension.East - ro.Extension.West ? ro.Extension.North - ro.Extension.South : ro.Extension.East - ro.Extension.West); //高度,海拔 double alt = (float)(ro.World.EquatorialRadius) * Math.Sin(MathEngine.DegreesToRadians(perpendicularViewRange * 1.1)); if (alt > ro.MaximumDisplayDistance - 100000) { alt = ro.MaximumDisplayDistance - 100000; } DrawArgs.Camera.Altitude = alt; } } } } }
/// <summary> /// 渲染对象:1.渲染所有的非GCP对象;2.渲染所有的非选中状态的GCP对象;3.渲染选中的GCP对象 /// </summary> /// <param name="drawArgs"></param> public override void Render(DrawArgs drawArgs) { if (!isOn) { return; } //如果新添加了一个控制点,需要重新初始化一次列表 if (isAddedOneGCP) { Initialize(drawArgs); isAddedOneGCP = false; } if (!IsInitialized) { return; } // 渲染所有的非GCP对象 foreach (RenderableObject ro in m_children) { if (!ro.IsOn) { continue; } ro.Render(drawArgs); } int closestGCPDistanceSquared = int.MaxValue; GCP closestGCP = null; // 开始渲染所有的的GCP图层 m_sprite.Begin(SpriteFlags.AlphaBlend); foreach (RenderableObject ro in m_children) { if (!ro.IsOn) { continue; } GCP GCP = ro as GCP; if (GCP == null) { continue; } //计算控制点的位置 Vector3 translationVector = new Vector3( (float)(GCP.PositionD.X - drawArgs.WorldCamera.ReferenceCenter.X), (float)(GCP.PositionD.Y - drawArgs.WorldCamera.ReferenceCenter.Y), (float)(GCP.PositionD.Z - drawArgs.WorldCamera.ReferenceCenter.Z)); // 计算最近的一个GCP对象 Vector3 projectedPoint = drawArgs.WorldCamera.Project(translationVector); int dx = DrawArgs.LastMousePosition.X - (int)projectedPoint.X; int dy = DrawArgs.LastMousePosition.Y - (int)projectedPoint.Y; if (GCP.SelectionRectangle.Contains(dx, dy)) { // Mouse is over, check whether this GCP is closest int distanceSquared = dx * dx + dy * dy; if (distanceSquared < closestGCPDistanceSquared) { closestGCPDistanceSquared = distanceSquared; closestGCP = GCP; } } //渲染不是被Hover的图层 if (GCP != mouseOverGCP) { Render(drawArgs, GCP, projectedPoint); } } // 渲染被Hover的图层 if (mouseOverGCP != null) { Vector3 translationVector = new Vector3( (float)(mouseOverGCP.PositionD.X - drawArgs.WorldCamera.ReferenceCenter.X), (float)(mouseOverGCP.PositionD.Y - drawArgs.WorldCamera.ReferenceCenter.Y), (float)(mouseOverGCP.PositionD.Z - drawArgs.WorldCamera.ReferenceCenter.Z)); Render(drawArgs, mouseOverGCP, drawArgs.WorldCamera.Project(translationVector)); } mouseOverGCP = closestGCP; m_sprite.End(); }
/// <summary> /// 鼠标点击事件 /// </summary> /// <param name="drawArgs"></param> /// <returns></returns> public override bool PerformSelectionAction(DrawArgs drawArgs) { //执行所有的子GCP的PerformSelectionAction方法 foreach (RenderableObject ro in m_children) { if (!ro.IsOn) { continue; } if (!ro.IsSelectable) { continue; } GCP GCP = ro as GCP; if (GCP == null) { if (ro.PerformSelectionAction(drawArgs)) { return(true); } continue; } //判断当前GCP的位置,是否在视域范围内,若不在则返回 if (!drawArgs.WorldCamera.ViewFrustum.ContainsPoint(GCP.Position)) { continue; } //判断鼠标的位置是否在控制点的包围盒内,若不在,则返回 Vector3 referenceCenter = new Vector3( (float)drawArgs.WorldCamera.ReferenceCenter.X, (float)drawArgs.WorldCamera.ReferenceCenter.Y, (float)drawArgs.WorldCamera.ReferenceCenter.Z); Vector3 projectedPoint = drawArgs.WorldCamera.Project(GCP.Position - referenceCenter); if (!GCP.SelectionRectangle.Contains( DrawArgs.LastMousePosition.X - (int)projectedPoint.X, DrawArgs.LastMousePosition.Y - (int)projectedPoint.Y)) { continue; } try { //若当前鼠标是左键事件 if (DrawArgs.IsLeftMouseButtonDown && !DrawArgs.IsRightMouseButtonDown) { //使摄像机设置到控制点设置的范围 ZYM:20130718-禁用摄像机的移动,确保窗口的不变型 //if (GCP.OnClickZoomAltitude != double.NaN || GCP.OnClickZoomHeading != double.NaN || GCP.OnClickZoomTilt != double.NaN) //{ // drawArgs.WorldCamera.SetPosition( // GCP.Latitude, // GCP.Longitude, // GCP.OnClickZoomHeading, // GCP.OnClickZoomAltitude, // GCP.OnClickZoomTilt); //} //执行当前GCP的PerformSelection方法 if (GCP.IsSelectable) { GCP.PerformSelectionAction(drawArgs); } } //若当前鼠标是右键事件 else if (!DrawArgs.IsLeftMouseButtonDown && DrawArgs.IsRightMouseButtonDown) { //不做任何处理 } return(true); } catch (Exception ex) { throw new Exception(ex.ToString()); } } return(false); }
/// <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> /// 添加一个GCP对象. /// </summary> public void AddGCP(GCP gcp) { Add(gcp); }
/// <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; } }