void m_sceneControl_Tracked(object sender, Tracked3DEventArgs e) { this.cb_TargetPtsIndex.Items.Clear(); if (m_sceneControl.Action == Action3D.CreatePolyline) { GeoLine3D geoline3d = e.Geometry as GeoLine3D; if (geoline3d != null && geoline3d.PartCount > 0) { Point3Ds pts = geoline3d[0]; m_sightLine.ViewerPosition = pts[0]; updateObservePosition(pts[0]); m_sightLine.RemoveAllTargetPoints(); for (int i = 1; i < pts.Count; ++i) { m_sightLine.AddTargetPoint(pts[i]); this.cb_TargetPtsIndex.Items.Add(i - 1); } } } if (this.cb_TargetPtsIndex.Items.Count > 0) { this.cb_TargetPtsIndex.SelectedIndex = 0; } }
void m_sceneControl_Tracking(object sender, Tracking3DEventArgs e) { if (m_sceneControl.Action == Action3D.CreateLine) { if (m_bHasDone) { m_viewshed3D = CreateViewShed3D(); m_bHasDone = false; } if (m_viewshed3D != null) { GeoLine3D geoline3d = e.Geometry as GeoLine3D; if (geoline3d.PartCount > 0) { Point3Ds pts = geoline3d[0]; m_viewshed3D.ViewerPosition = pts[0]; updateObserverPosition(m_viewshed3D); m_viewshed3D.SetDistDirByPoint(pts[1]); updateParam(m_viewshed3D, false); } } } }
/// <summary> /// 初始化 /// </summary> private void Initialize() { try { mSceneControl.Action = Action3D.Pan; //注册事件 mSceneControl.Tracking += new Tracking3DEventHandler(TrackingHandler); mSceneControl.Tracked += new Tracked3DEventHandler(TrackedHandler); mSceneControl.MouseUp += SceneControlMouseUp; mPoint3Ds = new Point3Ds(); mGeoStyle3D = new GeoStyle3D(); mGeoStyle3D.MarkerColor = Color.FromArgb(255, 0, 255); mGeoStyle3D.LineColor = Color.FromArgb(255, 255, 0); mGeoStyle3D.LineWidth = 2; mGeoStyle3D.FillForeColor = Color.FromArgb(180, Color.Violet); mGeoStyle3D.AltitudeMode = AltitudeMode.RelativeToUnderground; //临时样式 mGeoStyle3DTemp = new GeoStyle3D(); mGeoStyle3DTemp.MarkerColor = Color.FromArgb(255, 0, 0); mGeoStyle3DTemp.LineColor = Color.FromArgb(0, 255, 0); mGeoStyle3DTemp.LineWidth = 2; mGeoStyle3DTemp.FillForeColor = Color.FromArgb(180, Color.Violet); mGeoStyle3DTemp.AltitudeMode = AltitudeMode.RelativeToUnderground; } catch (Exception ex) { Trace.WriteLine(ex.Message); } }
public void run() { Recordset rc = dv.GetRecordset(false, CursorType.Dynamic); Dictionary <int, Feature> feas = rc.GetAllFeatures(); foreach (KeyValuePair <int, Feature> item in feas) { GeoModel gm = item.Value.GetGeometry() as GeoModel; Console.WriteLine("==" + gm.Position + "=="); //GeoModel model = new ModelIncubation.CuboidModel(10, 10, 10); Point3Ds p3ds = new Point3Ds(); for (int i = 0; i < 7; i++) { double seta = 2 * Math.PI * i / 7; p3ds.Add(new Point3D(Math.Sin(seta) * 10, Math.Cos(seta) * 10, 0)); } GeoModel model = new ModelIncubation.PrismModel(p3ds, 30); //临时处理,未知原因导致Position.Z属性设置无效,手动偏移模型实体 model.OffsetModel(new Point3D(0, 0, 1650)); model.Position = gm.Position; model.MergeMeshs(); Console.WriteLine(""); model.Position = gm.Position; model.ComputeBoundingBox(); scene.TrackingLayer.Add(model, model.Position.ToString()); scene.Refresh(); GeoModel m = scene.TrackingLayer.Get(0) as GeoModel; Thread.Sleep(1000); break; } }
protected void InitModel(Point3Ds Bottom, Point3Ds Top) { geoModel = new GeoModel(); n = Math.Min(Bottom.Count, Top.Count); surface = new Mesh[n + 2]; surface[n] = geoModel.CreateMesh(Bottom); surface[n + 1] = geoModel.CreateMesh(Top); for (int i = 0; i < n; i++) { Point3Ds p3ds = new Point3Ds(); p3ds.Add(Bottom[i]); p3ds.Add(Bottom[(i + 1) % n]); p3ds.Add(Top[(i + 1) % n]); p3ds.Add(Top[i]); surface[i] = geoModel.CreateMesh(p3ds); } if (this.Meshes.Count > 0) { this.Meshes.Clear(); } for (int i = 0; i < surface.Length; i++) { this.Meshes.Add(surface[i]); } }
public Query(SceneControl bd_sceneControl, UseData bd_usedata, DataGridView bd_DataGridView) { this.mSceneControl = bd_sceneControl; this.mUseData = bd_usedata; this.mDataGridView = bd_DataGridView; mPoint3Ds = new Point3Ds(); }
/// <summary> /// 设置管段起始终止点为分析点 /// </summary> /// <param name="Geoline3Ds"></param> void SetPoint(List <GeoLine3D> Geoline3Ds) { for (int i = 0; i < Geoline3Ds.Count; i++) { mGeoLine3D = Geoline3Ds[i]; mPoint3Ds = mGeoLine3D[0]; mPoint3Ds = coordinateTrans3D(mPoint3Ds); if (i == 0) { mPoint3D_0 = mPoint3Ds.ToArray(); } else { mPoint3D_1 = mPoint3Ds.ToArray(); } } mResult = ClearDistanceAlgorithm(mPoint3D_0[0], mPoint3D_0[1], mPoint3D_1[0], mPoint3D_1[1]); switch (mFlag) { case 1: GetHResult(); break; case 2: GetVResult(); break; case 4: GetColResult(); break; } }
//关闭窗体 private void DlgProfileAnalysis_FormClosing(object sender, FormClosingEventArgs e) { this.pictureBox.Image = null; this.pictureBox.Controls.Clear(); m_sceneControl.Scene.TrackingLayer.Clear(); if (m_profile != null) { m_profile.Clear(); m_profile.Dispose(); m_profile = null; } if (m_point3Ds != null) { m_point3Ds.Clear(); m_point3Ds = null; } if (m_bitmap != null) { m_bitmap = null; } this.RegisterEvents(false); m_bHasDrawn = false; m_bShownPicture = false; m_timer.Stop(); m_timer.Enabled = false; }
private void DlgProfileAnalysis_Load(object sender, EventArgs e) { m_point3Ds = new Point3Ds(); m_timer = new Timer(); m_timer.Enabled = false; this.ClearResult_ToolStripMenuItem.Enabled = false; }
/// <summary> /// 构造一个棱柱 /// </summary> /// <param name="Bottom">棱柱底面外围坐标序列</param> /// <param name="h">棱柱高</param> public PrismModel(Point3Ds Bottom,double h) { Point3Ds Top = new Point3Ds(); for (int i = 0; i < Bottom.Count; i++) { Top.Add(new Point3D(Bottom[i].X, Bottom[i].Y, Bottom[i].Z + h)); } InitModel(Bottom, Top); }
/// <summary> /// 构造一个棱柱 /// </summary> /// <param name="Bottom">棱柱底面外围坐标序列</param> /// <param name="h">棱柱高</param> public PrismModel(Point3Ds Bottom, double h) { Point3Ds Top = new Point3Ds(); for (int i = 0; i < Bottom.Count; i++) { Top.Add(new Point3D(Bottom[i].X, Bottom[i].Y, Bottom[i].Z + h)); } InitModel(Bottom, Top); }
/// <summary> /// 空构造函数,生成单位正方体 /// </summary> public PrismModel() { Point3Ds Bottom = new Point3Ds(); Point3Ds Top = new Point3Ds(); for (int i = 0; i < 4; i++) { Bottom.Add(new Point3D(i%2,i/2,0)); Top.Add(new Point3D(i%2,i/2,1)); } InitModel(Bottom, Top); }
/// <summary> /// 空构造函数,生成单位正方体 /// </summary> public PrismModel() { Point3Ds Bottom = new Point3Ds(); Point3Ds Top = new Point3Ds(); for (int i = 0; i < 4; i++) { Bottom.Add(new Point3D(i % 2, i / 2, 0)); Top.Add(new Point3D(i % 2, i / 2, 1)); } InitModel(Bottom, Top); }
/// <summary> /// 正方体 /// </summary> public CuboidModel(double a = 1, double b = 1, double c = 1) { Point3Ds Bottom = new Point3Ds(); Point3Ds Top = new Point3Ds(); for (int i = 0; i < 4; i++) { Bottom.Add(new Point3D(((i + 1) / 2) % 2 * a - a / 2, i / 2 * b - b / 2, 0)); Top.Add(new Point3D(((i + 1) / 2) % 2 * a - a / 2, i / 2 * b - b / 2, c)); } InitModel(Bottom, Top); }
/// <summary> /// 从vPDic和vPIndex导入顶点到Point3Ds /// </summary> /// <param name="ps"></param> /// <param name="vPDic"></param> /// <param name="vPIndex"></param> public static void ImportVPList(this Point3Ds ps, Dictionary <int, Vertice> vPDic, List <Index> vPIndex) { foreach (Index index in vPIndex) { ps.Add(new Point3D(vPDic[index.P1].X, vPDic[index.P1].Y, vPDic[index.P1].Z)); ps.Add(new Point3D(vPDic[index.P2].X, vPDic[index.P2].Y, vPDic[index.P2].Z)); ps.Add(new Point3D(vPDic[index.P3].X, vPDic[index.P3].Y, vPDic[index.P3].Z)); } //foreach (KeyValuePair<int, Vertice> vP in vPDic) //{ // ps.Add(new Point3D(vP.Value.X, vP.Value.Y, vP.Value.Z)); //} }
/// <summary> /// 导出Point3Ds数据到vPDic和vPIndex(未完成,需要一个三角网构成算法,在这儿调用。同时替代以前构成mesh时候用的临时算法) /// </summary> /// <param name="ps"></param> /// <param name="vPDic"></param> /// <param name="vPIndex"></param> public static void ExportVPList(this Point3Ds ps, ref Dictionary <int, Vertice> vPDic, ref List <Index> vPIndex) { foreach (Point3D p3d in ps) { Vertice vp = new Vertice(p3d.X, p3d.Y, p3d.Z); if (!vPDic.ContainsKey(vp.HashCode)) { vPDic.Add(vp.HashCode, vp); } } #region 调用一个三角网构建算法 #endregion }
//鼠标右键事件,结束分析操作 void m_sceneControl_Tracked(object sender, Tracked3DEventArgs e) { if (m_sceneControl.Action == Action3D.CreateLine) { GeoLine3D geoline3d = e.Geometry as GeoLine3D; if (geoline3d != null && geoline3d.PartCount > 0) { Point3Ds pts = geoline3d[0]; m_profile.StartPoint = pts[0]; m_profile.EndPoint = pts[1]; outPutPic(); } m_sceneControl.Action = m_oldAction; m_bHasDrawn = true; } }
Mesh MakeMeshPot(Point3Ds ps) { Mesh mesh = new Mesh(); Double[] vertexes = new Double[12]; Double[] normals = new Double[12]; Int32[] indexes = new Int32[6]; Double[] textureCoords = new Double[8]; //设置顶点坐标,每三个一组,对应坐标系的X,Y,Z数值 // -0.661115958904828,-0.239472665266096,1646.15246582031 double offsetX = 0; double offsetY = 0; double offsetZ = 0; vertexes[0] = ps.leftbottom().X + (ps.rightbottom().X - ps.leftbottom().X) / 10 + offsetX; vertexes[1] = ps.leftbottom().Y + (ps.rightbottom().Y - ps.leftbottom().Y) / 10 + offsetY; vertexes[2] = ps.leftbottom().Z + (ps.leftup().Z - ps.leftbottom().Z) / 10 * 8 + offsetZ; vertexes[3] = ps.leftup().X + (ps.rightup().X - ps.leftup().X) / 10 + offsetX; vertexes[4] = ps.leftup().Y + (ps.rightup().Y - ps.leftup().Y) / 10 + offsetY; vertexes[5] = ps.leftup().Z - (ps.leftup().Z - ps.leftbottom().Z) / 10 + offsetZ; vertexes[6] = ps.rightup().X - (ps.rightup().X - ps.leftup().X) / 10 + offsetX; vertexes[7] = ps.rightup().Y - (ps.rightup().Y - ps.leftup().Y) / 10 + offsetY; vertexes[8] = ps.rightup().Z - (ps.rightup().Z - ps.rightbottom().Z) / 10 + offsetZ; vertexes[9] = ps.rightbottom().X - (ps.rightbottom().X - ps.leftbottom().X) / 10 + offsetX; vertexes[10] = ps.rightbottom().Y - (ps.rightbottom().Y - ps.leftbottom().Y) / 10 + offsetY; vertexes[11] = ps.rightbottom().Z + (ps.rightup().Z - ps.rightbottom().Z) / 10 * 8 + offsetZ; //设置顶点索引,用于绘制图形时应用 indexes[0] = 0; indexes[1] = 1; indexes[2] = 2; indexes[3] = 0; indexes[4] = 2; indexes[5] = 3; //设置顶点的法向量方向,设置法向量可以突出Mesh的阴影效果,更加逼真。 for (int i = 0; i < 12; i += 3) { normals[i] = 0; normals[i + 1] = 1; normals[i + 2] = 0; } mesh.Vertices = vertexes; mesh.Indexes = indexes; return(mesh); }
//鼠标移动事件 void m_sceneControl_Tracking(object sender, Tracking3DEventArgs e) { m_sceneControl.Scene.TrackingLayer.Clear(); if (m_sceneControl.Action == Action3D.CreateLine) { GeoLine3D geoline3d = e.Geometry as GeoLine3D; if (geoline3d.PartCount > 0) { Rectangle2D rect = m_contour.CoverageArea; Point3Ds pts = geoline3d[0]; rect.Left = pts[0].X; rect.Top = pts[0].Y; rect.Right = pts[1].X; rect.Bottom = pts[1].Y; m_contour.CoverageArea = rect; } } }
/// <summary> /// 初始化 /// </summary> private void Initialize() { //设置鼠标抓手 mSceneControl.Action = Action3D.Pan2; //清空跟踪图层 mSceneControl.Scene.TrackingLayer.Clear(); //注册鼠标点击/对象选择事件 mSceneControl.MouseDown += new MouseEventHandler(mSceneControl_MouseDown); mSceneControl.ObjectSelected += new ObjectSelectedEventHandler(mSceneControlSelected); //设置符号样式 mTextPoint3Ds = new Point3Ds(); mGeoStyle3D = new GeoStyle3D(); mGeoStyle3D.MarkerColor = Color.FromArgb(255, 0, 255); mGeoStyle3D.LineColor = Color.FromArgb(255, 255, 0); mGeoStyle3D.LineWidth = 2; mGeoStyle3D.FillForeColor = Color.FromArgb(180, Color.Violet); mGeoStyle3D.AltitudeMode = AltitudeMode.RelativeToUnderground; }
public SampleRun(WorkspaceControl workspaceControl, LayersControl layersControl, MapControl mapControl, MapControl mapControl2, MapLayoutControl mapLayoutControl1, ToolStripStatusLabel toolStripStatusLabel2, TextBox textBoxResult, ToolStripStatusLabel toolStripStatusLabel3, SceneControl scenecontrol ) { workspaceControl1 = workspaceControl; workspace1 = workspaceControl1.WorkspaceTree.Workspace; layersControl1 = layersControl; mapControl1 = mapControl; m_mapControlEagleEye = mapControl2; m_mapLayoutControl = mapLayoutControl1; m_toolStrip = toolStripStatusLabel2; m_textBoxResult = textBoxResult; scontrol = scenecontrol; label1 = toolStripStatusLabel3; m_datasource = workspace1.Datasources[0]; m_point3Ds = new Point3Ds(); m_pointName = "Point"; m_geoLine3D = new GeoLine3D(); m_point3DsAll = new Point3Ds(); m_flyManager = scontrol.Scene.FlyManager; m_flyManager.Routes.Clear(); m_flyManager.Scene = scontrol.Scene; m_mapControlEagleEye.MouseMove += new MouseEventHandler(EagleEyeMapMouseMoveHandler); m_mapControlEagleEye.MouseDown += new MouseEventHandler(EagleEyeMapMouseDownHandler); m_mapControlEagleEye.MouseUp += new MouseEventHandler(EagleEyeMapMouseUpHandler); m_mapControlEagleEye.ActionCursorChanging += new ActionCursorChangingEventHandler(EagleEyeMapCursorChangedHandler); mapControl1.Map.Drawn += new MapDrawnEventHandler(MainMapDrawnHandler); scontrol.MouseDown += new System.Windows.Forms.MouseEventHandler(m_sceneControl_MouseDown); scontrol.MouseMove += new System.Windows.Forms.MouseEventHandler(m_sceneControl_MouseMove); Initialize(); }
public static Point3D rightbottom(this Point3Ds p3ds) { Point3D p = p3ds[0]; for (int i = 1; i < p3ds.Count; i++) { if (p.X < p3ds[i].X) { p = p3ds[i]; } } for (int i = 1; i < p3ds.Count; i++) { if (p.X == p3ds[i].X && p.Y < p3ds[i].Y) { p = p3ds[i]; } } p.Z = Math.Min(Math.Min(p3ds[0].Z, p3ds[1].Z), p3ds[2].Z); return(p); }
private Route GetRoute() { Route route = new Route(); Point3Ds point3Ds = m_geoLine3D[0]; for (int i = 0; i < point3Ds.Count; i++) { Point3D point3D = new Point3D(point3Ds[i].X, point3Ds[i].Y, point3Ds[i].Z + 1000); point3Ds[i] = point3D; } GeoLine3D geoLine3D = new GeoLine3D(point3Ds); route.FromGeoLine3D(geoLine3D); route.IsFlyAlongTheRoute = true; route.IsHeadingFixed = true; route.IsAltitudeFixed = true; route.IsTiltFixed = true; route.IsLinesVisible = false; route.IsStopsVisible = false; return(route); }
/// <summary> /// 地理坐标向投影坐标转换 /// </summary> /// <param name="point3Ds"></param> /// <returns></returns> private Point3Ds coordinateTrans3D(Point3Ds point3Ds) { Point2Ds point2Ds = new Point2Ds(); foreach (Point3D p3d in point3Ds) { Point2D point2D = new Point2D(p3d.X, p3d.Y); point2Ds.Add(point2D); } //Assume Wgs1984WorldMercator as target project coordinate system PrjCoordSys prjTarget = new PrjCoordSys(PrjCoordSysType.Wgs1984Utm50N); bool b = CoordSysTranslator.Forward(point2Ds, prjTarget); Point3Ds result = new Point3Ds(); for (int i = 0; i < point2Ds.Count; i++) { Point3D point3D = new Point3D(point2Ds[i].X, point2Ds[i].Y, point3Ds[i].Z); result.Add(point3D); } return(result); }
public static Point3D leftup(this Point3Ds p3ds) { Point3D p = p3ds[0]; for (int i = 1; i < p3ds.Count; i++) { if (p.X > p3ds[i].X) { p = p3ds[i]; } } for (int i = 1; i < p3ds.Count; i++) { if (p.X == p3ds[i].X && p.Y > p3ds[i].Y) { p = p3ds[i]; } } p.Z = Math.Max(Math.Max(p3ds[0].Z, p3ds[1].Z), p3ds[2].Z); return(p); }
void m_sceneControl_Tracking(object sender, Tracking3DEventArgs e) { this.m_sceneControl.Scene.TrackingLayer.Clear(); if (m_sceneControl.Action == Action3D.CreatePolyline) { if (m_sightLine != null) { GeoLine3D geoline3d = e.Geometry as GeoLine3D; if (geoline3d != null && geoline3d.PartCount > 0) { Point3Ds pts = geoline3d[0]; m_sightLine.ViewerPosition = pts[0]; updateObservePosition(pts[0]); m_sightLine.RemoveAllTargetPoints(); for (int i = 1; i < pts.Count; ++i) { m_sightLine.AddTargetPoint(pts[i]); } } } } }
private void button3_Click(object sender, EventArgs e) { Point3Ds p3ds = new Point3Ds(); p3ds.Add(new Point3D(0, 0, 0)); p3ds.Add(new Point3D(0, 0.8, 0)); p3ds.Add(new Point3D(0.8, 0.8, 0)); p3ds.Add(new Point3D(0.8, 0, 0)); scon.Scene.EnsureVisible(new Rectangle2D(new Point2D(0, 0), new Size2D(0.5, 0.5))); GeoModel gm = new PrismModel(p3ds, 0.2); gm.Position = new Point3D(0, 0, 0); gm.OffsetModel(new Point3D(0, 0, scon.Scene.GetAltitude(0, 0) + 100)); for (int i = 0; i < 30; i++) { for (int j = 0; j < 40; j++) { gm.OffsetModel(new Point3D(i, j, 0)); scon.Scene.TrackingLayer.Add(gm, string.Format("{0}-{1}", i, j)); gm.OffsetModel(new Point3D(0 - i, 0 - j, 0)); } } }
//鼠标右键事件 void m_sceneControl_Tracked(object sender, Tracked3DEventArgs e) { if (m_sceneControl.Action == Action3D.CreatePolygon) { GeoRegion3D region3D = e.Geometry as GeoRegion3D; if (region3D != null) { Point3Ds point3Ds = region3D[0]; if (point3Ds.Count < 3) { return; } else { Point3D pt1 = point3Ds[0]; Point3D pt2 = point3Ds[1]; Point3D pt3 = point3Ds[2]; m_layer3D.SetCustomClipPlane(pt1, pt2, pt3); } } m_sceneControl.Action = m_oldAction; m_sceneControl.Scene.TrackingLayer.Clear(); } }
/// <summary> /// 打开需要的地形文件和影像文件 /// </summary> private void Initialize() { try { // 调整sceneControl的状态 m_sceneControl.Action = Action3D.Pan; //注册事件 m_sceneControl.Tracking += new Tracking3DEventHandler(TrackingHandler); m_sceneControl.Tracked += new Tracked3DEventHandler(TrackedHandler); m_sceneControl.MouseUp += m_SceneControl_MouseUp; m_point3Ds = new Point3Ds(); m_style3d = new GeoStyle3D(); m_GeoStyle3D = new GeoStyle3D(); m_GeoStyle3D.MarkerColor = Color.FromArgb(255, 0, 255); m_GeoStyle3D.LineColor = Color.FromArgb(255, 255, 0); m_GeoStyle3D.LineWidth = 1; m_GeoStyle3D.FillForeColor = Color.FromArgb(180, Color.Violet); m_GeoStyle3D.AltitudeMode = AltitudeMode.ClampToGround; m_GeoStyle3DTemp = new GeoStyle3D(); m_GeoStyle3DTemp.MarkerColor = Color.FromArgb(255, 0, 0); m_GeoStyle3DTemp.LineColor = Color.FromArgb(0, 255, 0); m_GeoStyle3DTemp.LineWidth = 1; m_GeoStyle3DTemp.FillForeColor = Color.FromArgb(180, Color.Violet); m_GeoStyle3DTemp.AltitudeMode = AltitudeMode.ClampToGround; } catch (Exception ex) { MessageBox.Show(ex.Message); } }
Mesh MakeMeshPot(Point3Ds ps) { Mesh mesh = new Mesh(); Double[] vertexes = new Double[12]; Double[] normals = new Double[12]; Int32[] indexes = new Int32[6]; Double[] textureCoords = new Double[8]; //设置顶点坐标,每三个一组,对应坐标系的X,Y,Z数值 // -0.661115958904828,-0.239472665266096,1646.15246582031 double offsetX = 0; double offsetY = 0; double offsetZ = 0; vertexes[0] = ps.leftbottom().X + (ps.rightbottom().X - ps.leftbottom().X) / 10 + offsetX; vertexes[1] = ps.leftbottom().Y + (ps.rightbottom().Y - ps.leftbottom().Y) / 10 + offsetY; vertexes[2] = ps.leftbottom().Z + (ps.leftup().Z - ps.leftbottom().Z) / 10 * 8 + offsetZ; vertexes[3] = ps.leftup().X + (ps.rightup().X - ps.leftup().X) / 10 + offsetX; vertexes[4] = ps.leftup().Y + (ps.rightup().Y - ps.leftup().Y) / 10 + offsetY; vertexes[5] = ps.leftup().Z - (ps.leftup().Z - ps.leftbottom().Z) / 10 + offsetZ; vertexes[6] = ps.rightup().X - (ps.rightup().X - ps.leftup().X) / 10 + offsetX; vertexes[7] = ps.rightup().Y - (ps.rightup().Y - ps.leftup().Y) / 10 + offsetY; vertexes[8] = ps.rightup().Z - (ps.rightup().Z - ps.rightbottom().Z) / 10 + offsetZ; vertexes[9] = ps.rightbottom().X - (ps.rightbottom().X - ps.leftbottom().X) / 10 + offsetX; vertexes[10] = ps.rightbottom().Y - (ps.rightbottom().Y - ps.leftbottom().Y) / 10 + offsetY; vertexes[11] = ps.rightbottom().Z + (ps.rightup().Z - ps.rightbottom().Z) / 10 * 8 + offsetZ; //设置顶点索引,用于绘制图形时应用 indexes[0] = 0; indexes[1] = 1; indexes[2] = 2; indexes[3] = 0; indexes[4] = 2; indexes[5] = 3; //设置顶点的法向量方向,设置法向量可以突出Mesh的阴影效果,更加逼真。 for (int i = 0; i < 12; i += 3) { normals[i] = 0; normals[i + 1] = 1; normals[i + 2] = 0; } mesh.Vertices = vertexes; mesh.Indexes = indexes; return mesh; }
/// <summary> /// 打开需要的地形文件和影像文件 /// </summary> private void Initialize() { try { // 调整sceneControl的状态 //SmObjectLocator.getInstance().GlobeObject.Action = Action3D.Pan; //注册事件 //SmObjectLocator.getInstance().GlobeObject.Tracking += new Tracking3DEventHandler(TrackingHandler); //SmObjectLocator.getInstance().GlobeObject.Tracked += new Tracked3DEventHandler(TrackedHandler); //SmObjectLocator.getInstance().GlobeObject.MouseUp += m_SceneControl_MouseUp; m_point3Ds = new Point3Ds(); m_style3d = new GeoStyle3D(); m_GeoStyle3D = new GeoStyle3D(); m_GeoStyle3D.MarkerColor = Color.FromArgb(255, 0, 255); m_GeoStyle3D.LineColor = Color.FromArgb(255, 255, 0); m_GeoStyle3D.LineWidth = 1; m_GeoStyle3D.FillForeColor = Color.FromArgb(180, Color.Violet); m_GeoStyle3D.AltitudeMode = AltitudeMode.ClampToGround; m_GeoStyle3DTemp = new GeoStyle3D(); m_GeoStyle3DTemp.MarkerColor = Color.FromArgb(255, 0, 0); m_GeoStyle3DTemp.LineColor = Color.FromArgb(0, 255, 0); m_GeoStyle3DTemp.LineWidth = 1; m_GeoStyle3DTemp.FillForeColor = Color.FromArgb(180, Color.Violet); m_GeoStyle3DTemp.AltitudeMode = AltitudeMode.ClampToGround; } catch (Exception ex) { Trace.WriteLine(ex.Message); } }
public void run() { Recordset rc = dv.GetRecordset(false, CursorType.Dynamic); Dictionary<int, Feature> feas = rc.GetAllFeatures(); foreach (KeyValuePair<int, Feature> item in feas) { GeoModel gm = item.Value.GetGeometry() as GeoModel; Console.WriteLine("==" + gm.Position + "=="); GeoModel model = new GeoModel(); model.Position = gm.Position; foreach (Mesh m in gm.Meshes) { if (m.Material.TextureFile.Length > 1) { //Console.WriteLine(m.Material.TextureFile.ToString()); Point3Ds p3ds = new Point3Ds(); for (int i = 0; i < m.Vertices.Length; i += 3) { bool repition = false; foreach (Point3D p in p3ds) { if (p.X == m.Vertices[i] && p.Y == m.Vertices[i + 1] && p.Z == m.Vertices[i + 2]) { repition = true; } } if (!repition) { p3ds.Add(new Point3D(m.Vertices[i], m.Vertices[i + 1], m.Vertices[i + 2])); } } foreach (Point3D p3d in p3ds) { Console.WriteLine(string.Format(" {0},{1},{2}", p3d.X, p3d.Y, p3d.Z)); scene.TrackingLayer.Add(new GeoPoint3D(p3d.X, p3d.Y, p3d.Z), ""); } //model.Meshes.Add(MakeMeshPot(p3ds)); Mesh mesh = new Mesh(m); mesh.Material.TextureFile = @".\78310a55b319ebc41f7810198326cffc1e171629.png"; model.Meshes.Add(mesh); #region 写属性表 Dictionary<string, double> fields = new Dictionary<string, double>(); fields.Add("FaceMeshCenterX", model.Position.X); fields.Add("FaceMeshCenterY", model.Position.Y); fields.Add("FaceMeshCenterZ", model.Position.Z); fields.Add("FaceMeshLx", p3ds.leftbottom().X); fields.Add("FaceMeshLy", p3ds.leftbottom().Y); fields.Add("FaceMeshLz", p3ds.leftbottom().Z); fields.Add("FaceMeshUx", p3ds.rightup().X); fields.Add("FaceMeshUy", p3ds.rightup().Y); fields.Add("FaceMeshUz", p3ds.rightup().Z); foreach (KeyValuePair<string, double> field in fields) { if (dv.FieldInfos.IndexOf(field.Key) < 0) { FieldInfo fieldInf = new FieldInfo(field.Key, FieldType.Double); dv.FieldInfos.Add(fieldInf); } string fieldName = field.Key; double fieldValue = field.Value; try { rc.SeekID(item.Value.GetID()); rc.Edit(); rc.SetFieldValue(fieldName, fieldValue); rc.Update(); } catch { Console.WriteLine("error!"); } //Console.WriteLine(string.Format("{0},{1},{2}", item.GetID(), fieldName, fieldValue)); } #endregion } } Console.WriteLine(""); model.ComputeBoundingBox(); scene.TrackingLayer.Add(model, gm.Position.ToString()); scene.Refresh(); } }
/// <summary> /// 按平面切割模型 /// </summary> /// <param name="geoModel"></param> /// <param name="surface">切割平面</param> public static void ClipModel(this GeoModel geoModel, Surface surface) { if (geoModel.Meshes == null) return; #region 提取顶点 Dictionary<int, Vertice> vPDic; List<Index> vPIndex; geoModel.structureData(2, out vPDic, out vPIndex); #endregion List<Index> wellBeRm = new List<Index>(); List<Index> wellBeAdd = new List<Index>(); foreach (Index index in vPIndex) { #region 找到至少具有一点高于切割平面的三角面 if (!surface.isBelowMe(vPDic[index.P1]) || !surface.isBelowMe(vPDic[index.P2]) || !surface.isBelowMe(vPDic[index.P3])) { wellBeRm.Add(index); //第一步去掉都三个顶点都在切割面上方的三角面 if (!surface.isBelowMe(vPDic[index.P1]) && !surface.isBelowMe(vPDic[index.P2]) && !surface.isBelowMe(vPDic[index.P3])) { //vPDic.Remove(index.P1); vPDic.Remove(index.P2); vPDic.Remove(index.P3); //只需要删掉索引!不要删掉点,这个点还可能被其它三角面索引到,而其它三角面可能与切割平面相交 //这里不能直接在循环体内删除。应该记录列表,待循环完毕后再统一删,否则会打乱集合。 //vPIndex.Remove(index); //这里逻辑应该是都会删掉的,移到判断外去执行了 //wellBeRm.Add(index); } else { //剩下的就是和切割平面相交的三角面。这里开始计算三角形边与平面的交点 #region 计算交点的函数 //P1在下 if (surface.isBelowMe(vPDic[index.P1])) { #region //P1,P2在下,P3在上 if (surface.isBelowMe(vPDic[index.P2])) { #region Vertice vP1 = surface.Intersect(vPDic[index.P1], vPDic[index.P3]);//第一个交点 Vertice vP2 = surface.Intersect(vPDic[index.P2], vPDic[index.P3]);//第二个交点 //插入新生成的两个点,并添加这两点和剩下两点构成三角面的索引。 if (!vPDic.ContainsKey(vP1.HashCode)) vPDic.Add(vP1.HashCode, vP1); if (!vPDic.ContainsKey(vP2.HashCode)) vPDic.Add(vP2.HashCode, vP2); //连接P1和vP2,构成两个三角形 Index vIn1 = new Index() { P1 = vP1.HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P1].HashCode }; Index vIn2 = new Index() { P1 = vPDic[index.P1].HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P2].HashCode }; //同理这里不能直接编辑当前循环的list //vPIndex.Add(vIn1); //vPIndex.Add(vIn2); wellBeAdd.Add(vIn1); wellBeAdd.Add(vIn2); #endregion } //P1,P3在下,P2在上 else if (surface.isBelowMe(vPDic[index.P3])) { #region Vertice vP1 = surface.Intersect(vPDic[index.P1], vPDic[index.P2]);//第一个交点 Vertice vP2 = surface.Intersect(vPDic[index.P3], vPDic[index.P2]);//第二个交点 //插入新生成的两个点,并添加这两点和剩下两点构成三角面的索引。 if (!vPDic.ContainsKey(vP1.HashCode)) vPDic.Add(vP1.HashCode, vP1); if (!vPDic.ContainsKey(vP2.HashCode)) vPDic.Add(vP2.HashCode, vP2); //连接P1和vP2,构成两个三角形 Index vIn1 = new Index() { P1 = vP1.HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P1].HashCode }; Index vIn2 = new Index() { P1 = vPDic[index.P1].HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P3].HashCode }; //vPIndex.Add(vIn1); //vPIndex.Add(vIn2); wellBeAdd.Add(vIn1); wellBeAdd.Add(vIn2); #endregion } //P1在下,P2,P3在上 else { #region Vertice vP1 = surface.Intersect(vPDic[index.P1], vPDic[index.P2]);//第一个交点 Vertice vP2 = surface.Intersect(vPDic[index.P1], vPDic[index.P3]);//第二个交点 //插入新生成的两个点,并添加这两点和剩下一点构成三角面的索引 if (!vPDic.ContainsKey(vP1.HashCode)) vPDic.Add(vP1.HashCode, vP1); if (!vPDic.ContainsKey(vP2.HashCode)) vPDic.Add(vP2.HashCode, vP2); Index vIn = new Index() { P1 = vP1.HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P1].HashCode }; //vPIndex.Add(vIn); wellBeAdd.Add(vIn); #endregion } #endregion } else //P1在上 { #region //P1,P2在上,P3在下 if (!surface.isBelowMe(vPDic[index.P2])) { #region Vertice vP1 = surface.Intersect(vPDic[index.P3], vPDic[index.P2]);//第一个交点 Vertice vP2 = surface.Intersect(vPDic[index.P3], vPDic[index.P1]);//第二个交点 //插入新生成的两个点,并添加这两点和剩下一点构成三角面的索引 if (!vPDic.ContainsKey(vP1.HashCode)) vPDic.Add(vP1.HashCode, vP1); if (!vPDic.ContainsKey(vP2.HashCode)) vPDic.Add(vP2.HashCode, vP2); Index vIn = new Index() { P1 = vP1.HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P3].HashCode }; //vPIndex.Add(vIn); wellBeAdd.Add(vIn); #endregion } //P1,P3在上,P2在下 else if (!surface.isBelowMe(vPDic[index.P3])) { #region Vertice vP1 = surface.Intersect(vPDic[index.P2], vPDic[index.P3]);//第一个交点 Vertice vP2 = surface.Intersect(vPDic[index.P2], vPDic[index.P1]);//第二个交点 //插入新生成的两个点,并添加这两点和剩下一点构成三角面的索引 if (!vPDic.ContainsKey(vP1.HashCode)) vPDic.Add(vP1.HashCode, vP1); if (!vPDic.ContainsKey(vP2.HashCode)) vPDic.Add(vP2.HashCode, vP2); Index vIn = new Index() { P1 = vP1.HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P2].HashCode }; //vPIndex.Add(vIn); wellBeAdd.Add(vIn); #endregion } //P1在上,P2,P3在下 else { #region Vertice vP1 = surface.Intersect(vPDic[index.P2], vPDic[index.P1]);//第一个交点 Vertice vP2 = surface.Intersect(vPDic[index.P3], vPDic[index.P1]);//第二个交点 //插入新生成的两个点,并添加这两点和剩下两点构成三角面的索引。 if (!vPDic.ContainsKey(vP1.HashCode)) vPDic.Add(vP1.HashCode, vP1); if (!vPDic.ContainsKey(vP2.HashCode)) vPDic.Add(vP2.HashCode, vP2); //连接P1和vP2,构成两个三角形 Index vIn1 = new Index() { P1 = vP1.HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P2].HashCode }; Index vIn2 = new Index() { P1 = vPDic[index.P2].HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P3].HashCode }; //vPIndex.Add(vIn1); //vPIndex.Add(vIn2); wellBeAdd.Add(vIn1); wellBeAdd.Add(vIn2); #endregion } #endregion } //surface.Intersect() #endregion } } #endregion } //统一删除刚刚记录的三角面 foreach (Index index in wellBeRm) { vPIndex.Remove(index);} //统一添加 foreach (Index index in wellBeAdd) { Console.WriteLine("=添加点="); Console.WriteLine(string.Format("{0},{1},{2}", vPDic[index.P1].X, vPDic[index.P1].Y, vPDic[index.P1].Z)); Console.WriteLine(string.Format("{0},{1},{2}", vPDic[index.P2].X, vPDic[index.P1].Y, vPDic[index.P2].Z)); Console.WriteLine(string.Format("{0},{1},{2}", vPDic[index.P3].X, vPDic[index.P1].Y, vPDic[index.P3].Z)); Console.WriteLine("========"); vPIndex.Add(index); } Point3Ds ps = new Point3Ds(); ps.ImportVPList(vPDic, wellBeAdd); Mesh m = geoModel.CreateMesh(ps); //geoModel.Meshes.Clear(); geoModel.Meshes.Add(m); geoModel.MergeMeshs(); geoModel.MakeMesh(vPDic, vPIndex); geoModel.CalculateNormals(ref vPDic, vPIndex); }
/// <summary> /// 构造一个斜棱柱 /// </summary> /// <param name="Bottom">底面</param> /// <param name="Top">顶面</param> public PrismModel(Point3Ds Bottom, Point3Ds Top) { InitModel(Bottom, Top); }
/// <summary> /// 获取两点之间的距离 /// </summary> /// <param name="point3D1"></param> /// <param name="point3D2"></param> /// <returns></returns> public double GetLengthBy2Point(Point3D point3D1, Point3D point3D2) { double tempR = 0.0; GeoLine3D tempL = new GeoLine3D(); Point3Ds temp3Ds = new Point3Ds(); temp3Ds.Add(point3D1); temp3Ds.Add(point3D2); tempL.AddPart(temp3Ds); tempR = Geometrist.ComputeLength(tempL, new PrjCoordSys(PrjCoordSysType.EarthLongitudeLatitude)); return tempR == 0.0 ? 10000.0 : tempR; }
/// <summary> /// 给定坐标序列,构造凸多边形 /// </summary> /// <param name="ps"></param> /// <returns></returns> public static Mesh CreateMesh(this GeoModel geoMoel, Point3Ds ps) { //顶点去重 #region List<int> wellBeRm = new List<int>(); for (int i = ps.Count - 1; i >= 0; i--) { for (int j = 0; j < i; j++) { if (i == 0) break; if (ps[i].X == ps[j].X && ps[i].Y == ps[j].Y && ps[i].Z == ps[j].Z) if (!wellBeRm.Contains(i)) wellBeRm.Add(i); } } foreach (int i in wellBeRm) { ps.Remove(i); } if (ps.Count < 4) return null; #endregion Mesh mesh = new Mesh(); Double[] Vertices = new Double[ps.Count * 3]; Int32[] Indexes = new Int32[3 * (ps.Count - 2)]; Double[] Normals = new Double[ps.Count * 3]; for (int i = 0; i < ps.Count; i++) { //读入坐标 Vertices[3 * i] = ps[i].X; Vertices[3 * i + 1] = ps[i].Y; Vertices[3 * i + 2] = ps[i].Z; } for (int i = 0; i < ps.Count - 2; i++) { //生成索引 Indexes[3 * i] = 0; Indexes[3 * i + 1] = i + 1; Indexes[3 * i + 2] = i + 2; //构造三角面的时候累计计算顶点法向量。顶点法向量为该点为顶点所有面的法向量之和 //给定直角坐标系的单位向量i,j,k满足下列等式: //i×j=k ; //j×k=i ; //k×i=j ; //通过这些规则,两个向量的叉积的坐标可以方便地计算出来,不需要考虑任何角度:设 //a= [a1, a2, a3] =a1i+ a2j+ a3k //b= [b1,b2,b3]=b1i+ b2j+ b3k ; //则 //a × b= [a2b3-a3b2,a3b1-a1b3, a1b2-a2b1] double a1 = Vertices[3 * (Indexes[3 * i + 1])] - Vertices[3 * (Indexes[3 * i])], a2 = Vertices[3 * (Indexes[3 * i + 1]) + 1] - Vertices[3 * (Indexes[3 * i]) + 1], a3 = Vertices[3 * (Indexes[3 * i + 1]) + 2] - Vertices[3 * (Indexes[3 * i]) + 2], b1 = Vertices[3 * (Indexes[3 * i + 2])] - Vertices[3 * (Indexes[3 * i])], b2 = Vertices[3 * (Indexes[3 * i + 2]) + 1] - Vertices[3 * (Indexes[3 * i]) + 1], b3 = Vertices[3 * (Indexes[3 * i + 2]) + 2] - Vertices[3 * (Indexes[3 * i]) + 2]; double aXb1 = a2 * b3 - a3 * b2, aXb2 = a3 * b1 - a1 * b3, aXb3 = a1 * b2 - a2 * b1; //更新法向量 //但是这算法未完善,由于现在model的各个侧面是独立的mesh,法向量累加实际上无效,依然是各个面遵循自己的方向 for (int j = 0; j < 3; j++) { Normals[3 * (Indexes[3 * i + 1])] += aXb1; Normals[3 * (Indexes[3 * i + 1]) + 1] += aXb2; Normals[3 * (Indexes[3 * i + 1]) + 2] += aXb3; } } mesh.Vertices = Vertices; mesh.Indexes = Indexes; mesh.Normals = Normals; return mesh; }
/// <summary> /// 标注流向 /// </summary> public void FlowLabel() { Selection3D[] selection = mSceneControl.Scene.FindSelection(true); //判断选择集是否为空 if (selection == null || selection.Length == 0) { MessageBox.Show("请选择要标注流向的空间对象"); return; } //将选择集转换为记录 Recordset recordset = selection[0].ToRecordset(); GeoLine3D m_line = recordset.GetGeometry() as GeoLine3D; Point3D m_Point3D1 = m_line.InnerPoint3D; double x1 = System.Convert.ToDouble(recordset.GetFieldValue("SmSdriE")); double y1 = System.Convert.ToDouble(recordset.GetFieldValue("SmSdriS")); double z = System.Convert.ToDouble(recordset.GetFieldValue("BottomAltitude")); Point3D m_Point3D2 = new Point3D(x1, y1, z); Point3Ds m_Point3Ds = new Point3Ds(new Point3D[] { m_Point3D1, m_Point3D2 }); m_Point3Ds = coordinateTrans3D(m_Point3Ds); GeoLine3D m_Line3D = new GeoLine3D(m_Point3Ds); // GeoModel3D m_model=m_Line3D.ConvertToGeoModel3D(false); //设置线样式 GeoStyle3D m_Style3D = new GeoStyle3D(); m_Style3D.IsMarker3D = true; m_Style3D.AltitudeMode = AltitudeMode.Absolute; m_Style3D.FillForeColor = Color.FromArgb(0x64, 0x40, 0xFF, 0x5F); m_Style3D.FillMode = FillMode3D.Fill; m_Style3D.LineColor = Color.Lime; m_Style3D.LineWidth = 3; m_Line3D.Style3D = m_Style3D.Clone(); TrackingLayer3D trackinglayer = mSceneControl.Scene.TrackingLayer; trackinglayer.IsEditable = true; trackinglayer.IsVisible = true; trackinglayer.Add(m_Line3D, "FlowLine"); // mSceneControl.Scene.Refresh(); //double x2 = System.Convert.ToDouble(mPoint3D.X); //double y2 = System.Convert.ToDouble(mPoint3D.Y); //Point3D m_Point3D1 = new Point3D(x1, y1, 0); //Point3D m_Point3D2 = new Point3D(x1, y1, 0); // Point3Ds m_Point3Ds = new Point3Ds(new Point3D[] { m_Point3D1, m_Point3D2 }); //m_Point3Ds = coordinateTrans3D(m_Point3Ds); //m_Point3D1 = m_Point3Ds[0]; //m_Point3D2 = m_Point3Ds[1]; //x1 = m_Point3D1.X; //y1 = m_Point3D1.Y; //x2 = m_Point3D2.X; //y2 = m_Point3D2.Y; //double m_Roation = Math.Atan(Math.Abs((y1 - y2) / (x1 - x2))); //m_Roation=m_Roation * 180 / Math.PI; // String m_text = string.Empty; // String m_Start = System.Convert.ToString(recordset.GetFieldValue("SmFNode")); // m_Start=""; // String m_End = System.Convert.ToString(recordset.GetFieldValue("SmTNode")); // m_End=""; // m_text = m_Start + "→→→→→→→→→" + m_End; // TextPart3D mText1 = new TextPart3D(); // mText1.Text = m_text; // mText1.AnchorPoint = m_Point3D1; // TextStyle mTextStyle1 = new TextStyle(); // mTextStyle1.FontName = "微软雅黑"; // mTextStyle1.ForeColor = Color.Red; // mTextStyle1.FontHeight = 7; // mTextStyle1.IsSizeFixed = false; // mTextStyle1.Alignment = TextAlignment.BaselineCenter; //// mTextStyle1.Rotation = m_Roation; // GeoText3D geoText_1 = new GeoText3D(mText1, mTextStyle1); // GeoStyle3D geostyle_1 = new GeoStyle3D(); // geostyle_1.AltitudeMode = AltitudeMode.RelativeToGround; // geoText_1.Style3D = geostyle_1; // TrackingLayer3D trackinglayer = mSceneControl.Scene.TrackingLayer; // trackinglayer.IsEditable = true; // trackinglayer.IsVisible = true; // trackinglayer.Add(geoText_1, "FlowLa"); // mSceneControl.Scene.Refresh(); // //得到所选对象的起点和终点坐标 // double x1=System.Convert.ToDouble(recordset.GetFieldValue("SmSdriW")); // double y1=System.Convert.ToDouble(recordset.GetFieldValue("SmSdriN")); // double x2 = System.Convert.ToDouble(recordset.GetFieldValue("SmSdriE")); // double y2 = System.Convert.ToDouble(recordset.GetFieldValue("SmSdriS")); // double z = System.Convert.ToDouble(recordset.GetFieldValue("BottomAltitude")); // Point3D m_Point3D1 = new Point3D(x1, y1, z); // Point3D m_Point3D2 = new Point3D(x2, y2, z); // Point3Ds m_Point3Ds = new Point3Ds(new Point3D[]{mPoint3D,m_Point3D2}); // m_Point3Ds=coordinateTrans3D(m_Point3Ds); // //根据坐标画线 // GeoLine3D m_Line3D = new GeoLine3D(m_Point3Ds); // //设置线样式 // GeoStyle3D m_Style3D = new GeoStyle3D(); //// m_Style3D.IsMarker3D = true; // m_Style3D.AltitudeMode = AltitudeMode.RelativeToGround; // m_Style3D.LineColor = Color.Lime; // m_Style3D.LineWidth = 3; // m_Line3D.Style3D = m_Style3D; // TrackingLayer3D trackinglayer = mSceneControl.Scene.TrackingLayer; // trackinglayer.IsEditable = true; // trackinglayer.IsVisible = true; // trackinglayer.Add(m_Line3D, "FlowLine"); // mSceneControl.Scene.Refresh(); }
/// <summary> /// 在查询结果面板上初始化查询结果列表 /// </summary> /// <param name="type">查询方式,默认为属性查询-Attribute,空间查询-Spatial</param> private void ExecuteQueryListBox(string type, Point3Ds TempPoints3Ds=null, string actionStr=null) { string layerName = ""; if (this.QueryLayerList.Items.Count > 0) { layerName = this.QueryLayerList.SelectedValue.ToString(); } if (layerName != "")//关键字为空时查询全部要素 { string queryTxt = this.QueryNameTxt.Text.Trim(); Workspace ws = MainWindow.m_workspace; if (ws != null) { string sourceName = ConfigurationManager.AppSettings.Get(queryDataSource); Datasource dSource = ws.Datasources[sourceName]; if (dSource != null) { DatasetVector dSetV = (DatasetVector)dSource.Datasets[layerName]; if (dSetV != null) { string fieldName = ConfigurationManager.AppSettings.Get(queryNameField); string fieldCode = ConfigurationManager.AppSettings.Get(queryCodeField); Recordset recordset = null; if (type != ATTRIBUTE_QUERY) { double queryBuffer = 0.0; SuperMap.Data.Geometry queryGeometry = null; switch (actionStr) { case "createpoint": queryBuffer = 0.01; if (TempPoints3Ds.Count == 1) { GeoPoint geoPoint = new GeoPoint(TempPoints3Ds[0].X, TempPoints3Ds[0].Y); queryGeometry = geoPoint; } break; case "createline": if (TempPoints3Ds.Count == 2) { Point2D point2D = new Point2D(TempPoints3Ds[0].X, TempPoints3Ds[0].Y); Point2D point2D1 = new Point2D(TempPoints3Ds[1].X, TempPoints3Ds[1].Y); double radius = Geometrist.Distance(new GeoPoint(point2D), new GeoPoint(point2D1)); GeoCircle geoCircle = new GeoCircle(point2D, radius); GeoRegion geoRegion = geoCircle.ConvertToRegion(72); queryGeometry = geoRegion; } break; case "createpolygon": if (TempPoints3Ds.Count > 2) { Point2Ds tempPoint2Ds = new Point2Ds(); for (int i = 0; i < TempPoints3Ds.Count; i++) { tempPoint2Ds.Add(new Point2D(TempPoints3Ds[i].X, TempPoints3Ds[i].Y)); } GeoRegion geoRegion = new GeoRegion(tempPoint2Ds); queryGeometry = geoRegion; } break; default: break; } if (queryGeometry != null) { recordset = dSetV.Query(queryGeometry, queryBuffer, SuperMap.Data.CursorType.Static); } } else { QueryParameter queryParameter = new QueryParameter(); queryParameter.CursorType = SuperMap.Data.CursorType.Static; queryParameter.HasGeometry = true; if (this.QueryNameTxt.Text.Trim() != "") { queryParameter.AttributeFilter = fieldName + " like '%" + queryTxt + "%'"; } recordset = dSetV.Query(queryParameter); } if (recordset != null && recordset.RecordCount > 0) { ObservableCollection<QueryRecordVO> recordList = SysModelLocator.getInstance().recordList; recordList.Clear(); bool isExist = false; FieldInfos fis = recordset.GetFieldInfos(); for (int j = 0; j < fis.Count; j++) { FieldInfo fi = fis[j]; if (fi != null) { if (fi.Name.ToString().ToUpper() == fieldName) { isExist = true; break; } continue; } } if (isExist) { for (recordset.MoveFirst(); recordset.IsEOF == false; recordset.MoveNext()) { QueryRecordVO qVO = new QueryRecordVO(); qVO.RecordLayerId = layerName; qVO.RecordName = recordset.GetFieldValue(fieldName).ToString(); qVO.RecordIndex = recordset.GetFieldValue(fieldCode).ToString(); qVO.RecordCenterX = recordset.GetGeometry().InnerPoint.X.ToString(); qVO.RecordCenterY = recordset.GetGeometry().InnerPoint.Y.ToString(); recordList.Add(qVO); } this.QueryListBox.ItemsSource = recordList; this.QueryInfo.Text = "查询结果合计:" + recordList.Count + "条"; } else { this.QueryListBox.ItemsSource = null; this.QueryInfo.Text = ""; } } else { SysModelLocator.getInstance().recordList.Clear(); this.QueryListBox.ItemsSource = null; this.QueryInfo.Text = "查询结果合计:0条"; } } } } } }
/// <summary> /// 执行查询 /// </summary> /// <param name="type"></param> /// <param name="TempPoints3Ds"></param> /// <param name="actionStr"></param> public void ExecuteQuery(string type = "attribute", Point3Ds TempPoints3Ds = null, string actionStr = null) { InitGeoPoint3DParams(true); ExecuteQueryListBox(type, TempPoints3Ds, actionStr); InitQueryListOnMap(); this.ResetQueryState(); }
/// <summary> /// 给定坐标序列,构造凸多边形 /// </summary> /// <param name="ps"></param> /// <returns></returns> public static Mesh CreateMesh(this GeoModel geoMoel, Point3Ds ps) { //顶点去重 #region List <int> wellBeRm = new List <int>(); for (int i = ps.Count - 1; i >= 0; i--) { for (int j = 0; j < i; j++) { if (i == 0) { break; } if (ps[i].X == ps[j].X && ps[i].Y == ps[j].Y && ps[i].Z == ps[j].Z) { if (!wellBeRm.Contains(i)) { wellBeRm.Add(i); } } } } foreach (int i in wellBeRm) { ps.Remove(i); } if (ps.Count < 4) { return(null); } #endregion Mesh mesh = new Mesh(); Double[] Vertices = new Double[ps.Count * 3]; Int32[] Indexes = new Int32[3 * (ps.Count - 2)]; Double[] Normals = new Double[ps.Count * 3]; for (int i = 0; i < ps.Count; i++) { //读入坐标 Vertices[3 * i] = ps[i].X; Vertices[3 * i + 1] = ps[i].Y; Vertices[3 * i + 2] = ps[i].Z; } for (int i = 0; i < ps.Count - 2; i++) { //生成索引 Indexes[3 * i] = 0; Indexes[3 * i + 1] = i + 1; Indexes[3 * i + 2] = i + 2; //构造三角面的时候累计计算顶点法向量。顶点法向量为该点为顶点所有面的法向量之和 //给定直角坐标系的单位向量i,j,k满足下列等式: //i×j=k ; //j×k=i ; //k×i=j ; //通过这些规则,两个向量的叉积的坐标可以方便地计算出来,不需要考虑任何角度:设 //a= [a1, a2, a3] =a1i+ a2j+ a3k //b= [b1,b2,b3]=b1i+ b2j+ b3k ; //则 //a × b= [a2b3-a3b2,a3b1-a1b3, a1b2-a2b1] double a1 = Vertices[3 * (Indexes[3 * i + 1])] - Vertices[3 * (Indexes[3 * i])], a2 = Vertices[3 * (Indexes[3 * i + 1]) + 1] - Vertices[3 * (Indexes[3 * i]) + 1], a3 = Vertices[3 * (Indexes[3 * i + 1]) + 2] - Vertices[3 * (Indexes[3 * i]) + 2], b1 = Vertices[3 * (Indexes[3 * i + 2])] - Vertices[3 * (Indexes[3 * i])], b2 = Vertices[3 * (Indexes[3 * i + 2]) + 1] - Vertices[3 * (Indexes[3 * i]) + 1], b3 = Vertices[3 * (Indexes[3 * i + 2]) + 2] - Vertices[3 * (Indexes[3 * i]) + 2]; double aXb1 = a2 * b3 - a3 * b2, aXb2 = a3 * b1 - a1 * b3, aXb3 = a1 * b2 - a2 * b1; //更新法向量 //但是这算法未完善,由于现在model的各个侧面是独立的mesh,法向量累加实际上无效,依然是各个面遵循自己的方向 for (int j = 0; j < 3; j++) { Normals[3 * (Indexes[3 * i + 1])] += aXb1; Normals[3 * (Indexes[3 * i + 1]) + 1] += aXb2; Normals[3 * (Indexes[3 * i + 1]) + 2] += aXb3; } } mesh.Vertices = Vertices; mesh.Indexes = Indexes; mesh.Normals = Normals; return(mesh); }
/// <summary> /// 按平面切割模型 /// </summary> /// <param name="geoModel"></param> /// <param name="surface">切割平面</param> public static void ClipModel(this GeoModel geoModel, Surface surface) { if (geoModel.Meshes == null) { return; } #region 提取顶点 Dictionary <int, Vertice> vPDic; List <Index> vPIndex; geoModel.structureData(2, out vPDic, out vPIndex); #endregion List <Index> wellBeRm = new List <Index>(); List <Index> wellBeAdd = new List <Index>(); foreach (Index index in vPIndex) { #region 找到至少具有一点高于切割平面的三角面 if (!surface.isBelowMe(vPDic[index.P1]) || !surface.isBelowMe(vPDic[index.P2]) || !surface.isBelowMe(vPDic[index.P3])) { wellBeRm.Add(index); //第一步去掉都三个顶点都在切割面上方的三角面 if (!surface.isBelowMe(vPDic[index.P1]) && !surface.isBelowMe(vPDic[index.P2]) && !surface.isBelowMe(vPDic[index.P3])) { //vPDic.Remove(index.P1); vPDic.Remove(index.P2); vPDic.Remove(index.P3); //只需要删掉索引!不要删掉点,这个点还可能被其它三角面索引到,而其它三角面可能与切割平面相交 //这里不能直接在循环体内删除。应该记录列表,待循环完毕后再统一删,否则会打乱集合。 //vPIndex.Remove(index); //这里逻辑应该是都会删掉的,移到判断外去执行了 //wellBeRm.Add(index); } else { //剩下的就是和切割平面相交的三角面。这里开始计算三角形边与平面的交点 #region 计算交点的函数 //P1在下 if (surface.isBelowMe(vPDic[index.P1])) { #region //P1,P2在下,P3在上 if (surface.isBelowMe(vPDic[index.P2])) { #region Vertice vP1 = surface.Intersect(vPDic[index.P1], vPDic[index.P3]); //第一个交点 Vertice vP2 = surface.Intersect(vPDic[index.P2], vPDic[index.P3]); //第二个交点 //插入新生成的两个点,并添加这两点和剩下两点构成三角面的索引。 if (!vPDic.ContainsKey(vP1.HashCode)) { vPDic.Add(vP1.HashCode, vP1); } if (!vPDic.ContainsKey(vP2.HashCode)) { vPDic.Add(vP2.HashCode, vP2); } //连接P1和vP2,构成两个三角形 Index vIn1 = new Index() { P1 = vP1.HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P1].HashCode }; Index vIn2 = new Index() { P1 = vPDic[index.P1].HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P2].HashCode }; //同理这里不能直接编辑当前循环的list //vPIndex.Add(vIn1); //vPIndex.Add(vIn2); wellBeAdd.Add(vIn1); wellBeAdd.Add(vIn2); #endregion } //P1,P3在下,P2在上 else if (surface.isBelowMe(vPDic[index.P3])) { #region Vertice vP1 = surface.Intersect(vPDic[index.P1], vPDic[index.P2]); //第一个交点 Vertice vP2 = surface.Intersect(vPDic[index.P3], vPDic[index.P2]); //第二个交点 //插入新生成的两个点,并添加这两点和剩下两点构成三角面的索引。 if (!vPDic.ContainsKey(vP1.HashCode)) { vPDic.Add(vP1.HashCode, vP1); } if (!vPDic.ContainsKey(vP2.HashCode)) { vPDic.Add(vP2.HashCode, vP2); } //连接P1和vP2,构成两个三角形 Index vIn1 = new Index() { P1 = vP1.HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P1].HashCode }; Index vIn2 = new Index() { P1 = vPDic[index.P1].HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P3].HashCode }; //vPIndex.Add(vIn1); //vPIndex.Add(vIn2); wellBeAdd.Add(vIn1); wellBeAdd.Add(vIn2); #endregion } //P1在下,P2,P3在上 else { #region Vertice vP1 = surface.Intersect(vPDic[index.P1], vPDic[index.P2]); //第一个交点 Vertice vP2 = surface.Intersect(vPDic[index.P1], vPDic[index.P3]); //第二个交点 //插入新生成的两个点,并添加这两点和剩下一点构成三角面的索引 if (!vPDic.ContainsKey(vP1.HashCode)) { vPDic.Add(vP1.HashCode, vP1); } if (!vPDic.ContainsKey(vP2.HashCode)) { vPDic.Add(vP2.HashCode, vP2); } Index vIn = new Index() { P1 = vP1.HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P1].HashCode }; //vPIndex.Add(vIn); wellBeAdd.Add(vIn); #endregion } #endregion } else //P1在上 { #region //P1,P2在上,P3在下 if (!surface.isBelowMe(vPDic[index.P2])) { #region Vertice vP1 = surface.Intersect(vPDic[index.P3], vPDic[index.P2]); //第一个交点 Vertice vP2 = surface.Intersect(vPDic[index.P3], vPDic[index.P1]); //第二个交点 //插入新生成的两个点,并添加这两点和剩下一点构成三角面的索引 if (!vPDic.ContainsKey(vP1.HashCode)) { vPDic.Add(vP1.HashCode, vP1); } if (!vPDic.ContainsKey(vP2.HashCode)) { vPDic.Add(vP2.HashCode, vP2); } Index vIn = new Index() { P1 = vP1.HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P3].HashCode }; //vPIndex.Add(vIn); wellBeAdd.Add(vIn); #endregion } //P1,P3在上,P2在下 else if (!surface.isBelowMe(vPDic[index.P3])) { #region Vertice vP1 = surface.Intersect(vPDic[index.P2], vPDic[index.P3]); //第一个交点 Vertice vP2 = surface.Intersect(vPDic[index.P2], vPDic[index.P1]); //第二个交点 //插入新生成的两个点,并添加这两点和剩下一点构成三角面的索引 if (!vPDic.ContainsKey(vP1.HashCode)) { vPDic.Add(vP1.HashCode, vP1); } if (!vPDic.ContainsKey(vP2.HashCode)) { vPDic.Add(vP2.HashCode, vP2); } Index vIn = new Index() { P1 = vP1.HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P2].HashCode }; //vPIndex.Add(vIn); wellBeAdd.Add(vIn); #endregion } //P1在上,P2,P3在下 else { #region Vertice vP1 = surface.Intersect(vPDic[index.P2], vPDic[index.P1]); //第一个交点 Vertice vP2 = surface.Intersect(vPDic[index.P3], vPDic[index.P1]); //第二个交点 //插入新生成的两个点,并添加这两点和剩下两点构成三角面的索引。 if (!vPDic.ContainsKey(vP1.HashCode)) { vPDic.Add(vP1.HashCode, vP1); } if (!vPDic.ContainsKey(vP2.HashCode)) { vPDic.Add(vP2.HashCode, vP2); } //连接P1和vP2,构成两个三角形 Index vIn1 = new Index() { P1 = vP1.HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P2].HashCode }; Index vIn2 = new Index() { P1 = vPDic[index.P2].HashCode, P2 = vP2.HashCode, P3 = vPDic[index.P3].HashCode }; //vPIndex.Add(vIn1); //vPIndex.Add(vIn2); wellBeAdd.Add(vIn1); wellBeAdd.Add(vIn2); #endregion } #endregion } //surface.Intersect() #endregion } } #endregion } //统一删除刚刚记录的三角面 foreach (Index index in wellBeRm) { vPIndex.Remove(index); } //统一添加 foreach (Index index in wellBeAdd) { Console.WriteLine("=添加点="); Console.WriteLine(string.Format("{0},{1},{2}", vPDic[index.P1].X, vPDic[index.P1].Y, vPDic[index.P1].Z)); Console.WriteLine(string.Format("{0},{1},{2}", vPDic[index.P2].X, vPDic[index.P1].Y, vPDic[index.P2].Z)); Console.WriteLine(string.Format("{0},{1},{2}", vPDic[index.P3].X, vPDic[index.P1].Y, vPDic[index.P3].Z)); Console.WriteLine("========"); vPIndex.Add(index); } Point3Ds ps = new Point3Ds(); ps.ImportVPList(vPDic, wellBeAdd); Mesh m = geoModel.CreateMesh(ps); //geoModel.Meshes.Clear(); geoModel.Meshes.Add(m); geoModel.MergeMeshs(); geoModel.MakeMesh(vPDic, vPIndex); geoModel.CalculateNormals(ref vPDic, vPIndex); }