using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.Windows.Forms; using DevComponents.DotNetBar; using GeoScene.Data; using GeoScene.Globe; namespace Cyberpipe { public partial class FrmCompareFeature : Office2007Form { GSOFeature srcFeature; GSOFeature dscFeature; GSOGlobeControl globeControl1; GSOGlobeControl globeControl2; bool isSamePolyline; GSOLayer layerTemp; GSOLayer layerTemp2; GSOFeature new_feat; GSOGeoPolygon3D resPolygon; List<string> m_PipelineLayerNames = new List<string>(); List<string> sgPipeLayersNames = new List<string>(); static FrmCompareFeature frm; public static void ShowForm(GSOGlobeControl _globeControl1, GSOGlobeControl _globeControl2, GSOLayer _layerTemp, GSOLayer _layerTemp2, List<string> m_PipelineLayerNames, List<string> sgPipeLayersNames,int width) { if (frm == null) { frm = new FrmCompareFeature(_globeControl1, _globeControl2, _layerTemp, _layerTemp2, m_PipelineLayerNames, sgPipeLayersNames); frm.Location = new Point((width - frm.Width) / 2, 50); frm.Show(_globeControl1.Parent); } else { if (frm.WindowState == FormWindowState.Minimized) { frm.WindowState = FormWindowState.Normal; } } } public FrmCompareFeature(GSOGlobeControl _globeControl1, GSOGlobeControl _globeControl2, GSOLayer _layerTemp, GSOLayer _layerTemp2, List<string> m_PipelineLayerNames, List<string> sgPipeLayersNames) { globeControl1 = _globeControl1; globeControl2 = _globeControl2; InitializeComponent(); globeControl1.Globe.Action = EnumAction3D.SelectObject; globeControl2.Globe.Action = EnumAction3D.SelectObject; layerTemp = _layerTemp; layerTemp2 = _layerTemp2; globeControl1.MouseClick += globeControl1_MouseClick; globeControl2.MouseClick += globeControl2_MouseClick; this.m_PipelineLayerNames = m_PipelineLayerNames; this.sgPipeLayersNames = sgPipeLayersNames; } private void buttonAnalysis_Click(object sender, EventArgs e) { dataGridViewX1.DataSource = null; double bufferWidth = Convert.ToDouble(textBox1.Text); if (srcFeature != null && dscFeature != null) { if (srcFeature.Geometry.Type != dscFeature.Geometry.Type) { MessageBox.Show("请选择同种类型图层!"); } //TODO LIST按缓冲区的方式处理线的方式 else if (srcFeature.Geometry.Type == dscFeature.Geometry.Type && srcFeature.Geometry.Type == EnumGeometryType.GeoPolyline3D) { lineLayerCompare(srcFeature, dscFeature, bufferWidth); if (isSamePolyline) { lineFeatureCompare(srcFeature, dscFeature); globeControl1.Globe.Action = EnumAction3D.ActionNull; globeControl2.Globe.Action = EnumAction3D.ActionNull; } else { MessageBox.Show("实测管段与施工管段非同一条管段,请选择同一管段进行比较!", "提示"); } } else { MessageBox.Show("无法处理该类型图层!"); } } else { MessageBox.Show("请选择要对比的管段!", "提示"); } } /// <summary> /// 在容差范围内判断是否同一根管段 /// </summary> /// <param name="srcFeature"></param> /// <param name="dscFeature"></param> /// <param name="bufferWidth"></param> /// <returns></returns> private bool lineLayerCompare(GSOFeature srcFeature, GSOFeature dscFeature, double bufferWidth) { isSamePolyline = false; GSOGeoPolyline3D srcLine = srcFeature.Geometry as GSOGeoPolyline3D; GSOGeoPolygon3D srcBufferPolygon = srcLine.CreateBuffer(bufferWidth * 2, true, 5, true, false); GSOLayer dsc = globeControl2.Globe.Layers.GetLayerByCaption(dscFeature.Dataset.Caption); if (srcBufferPolygon != null) { GSOFeatures featuresInSrcLayer = dsc.FindFeaturesInPolygon(srcBufferPolygon, true); if (featuresInSrcLayer != null && featuresInSrcLayer.Length > 0) { for (int i = 0; i < featuresInSrcLayer.Length; i++) { if (featuresInSrcLayer[i].Name == dscFeature.Name) { isSamePolyline = true; break; } } } } GSOGeoPolyline3D dscLine = dscFeature.Geometry as GSOGeoPolyline3D; GSOGeoPolygon3D dscBufferPolygon = dscLine.CreateBuffer(bufferWidth * 2, true, 5, true, false); GSOLayer src = globeControl1.Globe.Layers.GetLayerByCaption(srcFeature.Dataset.Caption); if (dscBufferPolygon != null) { GSOFeatures featuresInDscLayer = src.FindFeaturesInPolygon(dscBufferPolygon, true); if (featuresInDscLayer != null && featuresInDscLayer.Length > 0) { for (int i = 0; i < featuresInDscLayer.Length; i++) { if (featuresInDscLayer[i].Name == srcFeature.Name) { isSamePolyline = true; break; } } } } return isSamePolyline; } /// <summary> /// 分析两根管段的具体差异 /// </summary> /// <param name="srcFeature"></param> /// <param name="dscFeature"></param> private void lineFeatureCompare(GSOFeature srcFeature, GSOFeature dscFeature) { GSOGeoPolyline3D srcLine = srcFeature.Geometry as GSOGeoPolyline3D; double srcLineLength = srcLine.GetSpaceLength(false, 6378137); GSOGeoPolyline3D dscLine = dscFeature.Geometry as GSOGeoPolyline3D; double dscLineLength = dscLine.GetSpaceLength(false, 6378137); double horizonDistance = HorizonDistance(srcLine, dscLine); double verticalDistance = VerticalDistance(srcLine, dscLine); DataTable dt = new DataTable(); dt.Columns.Add("数据名称"); dt.Columns.Add("图层名称"); dt.Columns.Add("管段编号"); dt.Columns.Add("管段长度"); dt.Columns.Add("材质"); dt.Columns.Add("水平距离/米"); dt.Columns.Add("垂直距离/米"); DataRow srcRow = dt.NewRow(); srcRow[0] = "实测数据"; srcRow[1] = srcFeature.Dataset.Caption; srcRow[2] = srcFeature.Name; srcRow[3] = srcLineLength.ToString("0.000"); srcRow[4] = srcFeature.GetFieldAsString("材质"); srcRow[5] = horizonDistance.ToString("0.000"); srcRow[6] = verticalDistance.ToString("0.000"); dt.Rows.Add(srcRow); DataRow dscRow=dt.NewRow(); dscRow[0] = "施工数据"; dscRow[1] = dscFeature.Dataset.Caption; dscRow[2] = dscFeature.Name; dscRow[3] = dscLineLength.ToString("0.000"); dscRow[4] = dscFeature.GetFieldAsString("材质"); dscRow[5] = horizonDistance.ToString("0.000"); dscRow[6] = verticalDistance.ToString("0.000"); dt.Rows.Add(dscRow); dataGridViewX1.DataSource = dt; } private void FrmCompareFeature_FormClosing(object sender, FormClosingEventArgs e) { globeControl1.Globe.Action = EnumAction3D.ActionNull; globeControl2.Globe.Action = EnumAction3D.ActionNull; frm = null; } /// <summary> /// 地球1中点击地球2中同步添加缓冲区 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void globeControl1_MouseClick(object sender, MouseEventArgs e) { //add by zhangfan layerTemp.Visible = true; layerTemp2.Visible = true; GSOFeatures listFeatures = new GSOFeatures(); double maxLength = 0; if (globeControl1.Globe.SelectedObject == null) { } else { clearFeatureHighLight(globeControl1, globeControl2); try { double bufferWidth = Convert.ToDouble(textBox1.Text); resPolygon = null; layerTemp.RemoveAllFeature(); if (new_feat != null) { layerTemp2.RemoveFeatureByID(new_feat.ID); } //双屏通视增加缓冲区 if (globeControl1.Globe.Action == EnumAction3D.SelectObject && globeControl1.Globe.SelectedObject != null) { GSOGeoPolyline3D line = globeControl1.Globe.SelectedObject.Geometry as GSOGeoPolyline3D; new_feat = new GSOFeature(); resPolygon = line.CreateBuffer(bufferWidth * 2, true, 0, false, false); resPolygon.AltitudeMode = EnumAltitudeMode.RelativeToGround; new_feat.Geometry = resPolygon; layerTemp.AddFeature(new_feat); layerTemp2.AddFeature(new_feat); globeControl1.Refresh(); globeControl2.Refresh(); } srcFeature = globeControl1.Globe.SelectedObject; //双屏同时选中同一管段 GSOLayer layers = null; //获取相对图层,后续得改 if (srcFeature.Dataset.Caption == "雨水管线") { layers = globeControl2.Globe.Layers.GetLayerByCaption("施工雨水管线"); } else { if (srcFeature.Dataset.Caption == "污水管线") { layers = globeControl2.Globe.Layers.GetLayerByCaption("施工污水管线"); } else if (srcFeature.Dataset.Caption == "供电管线") { layers = globeControl2.Globe.Layers.GetLayerByCaption("施工电力管线"); } } GSOFeatures features = layers.FindFeaturesInPolygon(resPolygon, false); GSOGeoPolyline3D scLine = srcFeature.Geometry as GSOGeoPolyline3D; for (int i = 0; i < features.Length; i++) { lineLayerCompare(srcFeature, features[i], Convert.ToDouble(textBox1.Text)); if (isSamePolyline) { listFeatures.Add(features[i]); } } if (listFeatures.Length != 0) { if (listFeatures.Length == 1) { dscFeature = listFeatures[0]; listFeatures[0].HighLight = true; } else { for (int m = 0; m < listFeatures.Length; m++) { GSOGeoPolyline3D tempSGLine = listFeatures[m].Geometry as GSOGeoPolyline3D; double tempLength = tempSGLine.GetSpaceLength(false, 6378137); double lengthAbs = Math.Abs(tempLength - scLine.GetSpaceLength(false, 6378137)); //tempLengthList.Add(lengthAbs); if (m == 0) { dscFeature = listFeatures[0]; listFeatures[0].HighLight = true; maxLength = lengthAbs; } else if (lengthAbs < maxLength) { dscFeature = listFeatures[m]; listFeatures[m].HighLight = true; maxLength = lengthAbs; } } } } else { dscFeature = null; } } catch (Exception ex) { } } } /// <summary> /// 地球2中点击地球1中同步添加缓冲区 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void globeControl2_MouseClick(object sender, MouseEventArgs e) { //add by zhangfan layerTemp.Visible = true; layerTemp2.Visible = true; GSOFeatures listFeatures = new GSOFeatures(); double maxLength = 0; if (globeControl2.Globe.SelectedObject == null) { } else { clearFeatureHighLight(globeControl1, globeControl2); try { double bufferWidth = Convert.ToDouble(textBox1.Text); resPolygon = null; layerTemp.RemoveAllFeature(); if (new_feat != null) { layerTemp2.RemoveFeatureByID(new_feat.ID); } if (globeControl2.Globe.Action == EnumAction3D.SelectObject && globeControl2.Globe.SelectedObject != null) { GSOGeoPolyline3D line = globeControl2.Globe.SelectedObject.Geometry as GSOGeoPolyline3D; new_feat = new GSOFeature(); resPolygon = line.CreateBuffer(bufferWidth * 2, true, 0, false, false); resPolygon.AltitudeMode = EnumAltitudeMode.RelativeToGround; new_feat.Geometry = resPolygon; layerTemp.AddFeature(new_feat); layerTemp2.AddFeature(new_feat); globeControl1.Refresh(); globeControl2.Refresh(); } dscFeature = globeControl2.Globe.SelectedObject; //双屏同时选中同一管段 GSOLayer layers = null; //获取相对图层,后续得改 if (dscFeature.Dataset.Caption == "施工雨水管线") { layers = globeControl1.Globe.Layers.GetLayerByCaption("雨水管线"); } else { if (dscFeature.Dataset.Caption == "施工污水管线") { layers = globeControl1.Globe.Layers.GetLayerByCaption("污水管线"); } else if (dscFeature.Dataset.Caption == "施工电力管线") { layers = globeControl1.Globe.Layers.GetLayerByCaption("供电管线"); } } GSOFeatures features = layers.FindFeaturesInPolygon(resPolygon, false); GSOGeoPolyline3D scLine = srcFeature.Geometry as GSOGeoPolyline3D; for (int i = 0; i < features.Length; i++) { lineLayerCompare(features[i], dscFeature, Convert.ToDouble(textBox1.Text)); if (isSamePolyline) { listFeatures.Add(features[i]); } } if (listFeatures.Length != 0) { if (listFeatures.Length == 1) { srcFeature = listFeatures[0]; listFeatures[0].HighLight = true; } else { for (int m = 0; m < listFeatures.Length; m++) { GSOGeoPolyline3D tempSGLine = listFeatures[m].Geometry as GSOGeoPolyline3D; double tempLength = tempSGLine.GetSpaceLength(false, 6378137); double lengthAbs = Math.Abs(tempLength - scLine.GetSpaceLength(false, 6378137)); //tempLengthList.Add(lengthAbs); if (m == 0) { srcFeature = listFeatures[0]; listFeatures[0].HighLight = true; maxLength = lengthAbs; } else if (lengthAbs < maxLength) { srcFeature = listFeatures[m]; listFeatures[m].HighLight = true; maxLength = lengthAbs; } } } } else { srcFeature = null; } } catch (Exception ex) { } } } /// <summary> /// 计算水平距离 /// </summary> /// <param name="line1"></param> /// <param name="line2"></param> /// <returns></returns> private double HorizonDistance(GSOGeoPolyline3D line1, GSOGeoPolyline3D line2) { GSOPoint3d pntIntersect1 = new GSOPoint3d(); GSOPoint3d pntIntersect2 = new GSOPoint3d(); GSOPoint3d pntProIntersect1 = new GSOPoint3d(); GSOPoint3d pntProIntersect2 = new GSOPoint3d(); GSOPipeLineStyle3D pipeStyle1 = line1.Style as GSOPipeLineStyle3D; GSOPipeLineStyle3D pipeStyle2 = line2.Style as GSOPipeLineStyle3D; double dDist = globeControl1.Globe.Analysis3D.ComputeHorizonDistance(line1, line2, out pntIntersect1, out pntIntersect2, out pntProIntersect1, out pntProIntersect2, false); GSOPoint3d markerPosition = new GSOPoint3d(); markerPosition = LabelHorizontalDistance(layerTemp, layerTemp2, pntProIntersect1, pntProIntersect2, dDist, true); return dDist; } /// <summary> /// 计算垂直距离 /// </summary> /// <param name="line1"></param> /// <param name="line2"></param> /// <returns></returns> private double VerticalDistance(GSOGeoPolyline3D line1, GSOGeoPolyline3D line2) { GSOPoint3d pntIntersect1 = new GSOPoint3d(); GSOPoint3d pntIntersect2 = new GSOPoint3d(); GSOPoint3d pntProIntersect1 = new GSOPoint3d(); GSOPoint3d pntProIntersect2 = new GSOPoint3d(); GSOPipeLineStyle3D pipeStyle1 = line1.Style as GSOPipeLineStyle3D; GSOPipeLineStyle3D pipeStyle2 = line2.Style as GSOPipeLineStyle3D; double dDist = globeControl1.Globe.Analysis3D.ComputeVerticalDistance(line1, line2, out pntIntersect1, out pntIntersect2, out pntProIntersect1, out pntProIntersect2, false); GSOPoint3d markerPosition = new GSOPoint3d(); markerPosition = LabelVerticalDistance(layerTemp, layerTemp2, pntProIntersect1, pntProIntersect2, dDist, true); return dDist; } /// <summary> /// 清除所有高亮Feature /// </summary> /// <param name="glb"></param> private void clearFeatureHighLight(GSOGlobeControl glb1,GSOGlobeControl glb2) { layerTemp.RemoveAllFeature(); layerTemp2.RemoveAllFeature(); //清除gbl1中高亮 for (int i = 0; i < glb1.Globe.Layers.Count; i++) { GSOLayer layer = glb1.Globe.Layers[i]; if (layer is GSOFeatureLayer) { GSOFeatures feats = layer.GetAllFeatures(); for (int j = 0; j < feats.Length; j++) { GSOFeature feat = feats[j]; feat.HighLight = false; } } } //清除gbl2中高亮 for (int i = 0; i < glb2.Globe.Layers.Count; i++) { GSOLayer layer = glb2.Globe.Layers[i]; if (layer is GSOFeatureLayer) { GSOFeatures feats = layer.GetAllFeatures(); for (int j = 0; j < feats.Length; j++) { GSOFeature feat = feats[j]; feat.HighLight = false; } } } } /// <summary> /// 添加垂直标注 /// </summary> /// <param name="markerLayer"></param> /// <param name="pntIntersect1"></param> /// <param name="pntIntersect2"></param> /// <param name="distance"></param> /// <param name="markerVisible"></param> /// <returns></returns> private GSOPoint3d LabelVerticalDistance(GSOLayer markerLayer, GSOLayer markerLayer2, GSOPoint3d pntIntersect1, GSOPoint3d pntIntersect2, double distance, bool markerVisible) { if (pntIntersect1 == null || pntIntersect2 == null) { return new GSOPoint3d(); } GSOGeoPolyline3D disline = new GSOGeoPolyline3D(); GSOPoint3ds point3ds = new GSOPoint3ds(); point3ds.Add(pntIntersect1); point3ds.Add(pntIntersect2); disline.AddPart(point3ds); GSOSimpleLineStyle3D style = new GSOSimpleLineStyle3D();//创建线的风格 //设置透明度及颜色,FromArgb()中的四个参数分别为alpha、red、green、blue,取值范围为0到255 style.LineColor = Color.Red; style.LineWidth = 5; //设置线的宽度为5 style.VertexVisible = true; //显示线的节点 disline.Style = style; //把风格添加到线上 disline.AltitudeMode = EnumAltitudeMode.Absolute; GSOFeature line = new GSOFeature(); line.Geometry = disline; GSOGeoMarker dismarker = new GSOGeoMarker(); dismarker.X = pntIntersect1.X; dismarker.Y = pntIntersect1.Y; dismarker.Z = (pntIntersect1.Z + pntIntersect2.Z) / 2; dismarker.Text = "垂直" + distance.ToString("0.00") + "米"; dismarker.AltitudeMode = EnumAltitudeMode.Absolute; GSOMarkerStyle3D styleMarker = new GSOMarkerStyle3D(); GSOTextStyle styleText = new GSOTextStyle(); styleText.IsSizeFixed = true; styleText.ForeColor = Color.Red; styleText.FontSize = 20; styleMarker.TextStyle = styleText; dismarker.Style = styleMarker; GSOFeature marker = new GSOFeature(); marker.Geometry = dismarker; line.Visible = marker.Visible = markerVisible; markerLayer.AddFeature(line); markerLayer.AddFeature(marker); markerLayer2.AddFeature(line); markerLayer2.AddFeature(marker); return dismarker.Position; } /// <summary> /// 添加水平标注 /// </summary> /// <param name="markerLayer"></param> /// <param name="pntIntersect1"></param> /// <param name="pntIntersect2"></param> /// <param name="distance"></param> /// <param name="markerVisible"></param> /// <returns></returns> private GSOPoint3d LabelHorizontalDistance(GSOLayer markerLayer, GSOLayer markerLayer2, GSOPoint3d pntIntersect1, GSOPoint3d pntIntersect2, double distance, bool markerVisible) { if (pntIntersect1 == null || pntIntersect2 == null) { return new GSOPoint3d(); } GSOGeoPolyline3D disline = new GSOGeoPolyline3D(); GSOPoint3ds point3ds = new GSOPoint3ds(); point3ds.Add(pntIntersect1); point3ds.Add(pntIntersect2); disline.AddPart(point3ds); GSOSimpleLineStyle3D style = new GSOSimpleLineStyle3D(); //创建线的风格 //设置透明度及颜色,FromArgb()中的四个参数分别为alpha、red、green、blue,取值范围为0到255 style.LineColor = Color.Red; style.LineWidth = 5; //设置线的宽度为3 style.VertexVisible = true; //显示线的节点 disline.Style = style; //把风格添加到线上 disline.AltitudeMode = EnumAltitudeMode.Absolute; GSOFeature line = new GSOFeature(); line.Geometry = disline; GSOGeoMarker dismarker = new GSOGeoMarker(); dismarker.X = pntIntersect1.X; dismarker.Y = pntIntersect1.Y; dismarker.Z = (pntIntersect1.Z + pntIntersect2.Z) / 2; dismarker.Text = "水平" + distance.ToString("0.00") + "米"; dismarker.AltitudeMode = EnumAltitudeMode.Absolute; GSOMarkerStyle3D styleMarker = new GSOMarkerStyle3D(); GSOTextStyle styleText = new GSOTextStyle(); styleText.IsSizeFixed = true; styleText.ForeColor = Color.Red; styleText.FontSize = 20; styleMarker.TextStyle = styleText; dismarker.Style = styleMarker; GSOFeature marker = new GSOFeature(); marker.Geometry = dismarker; line.Visible = marker.Visible = markerVisible; markerLayer.AddFeature(line); markerLayer.AddFeature(marker); markerLayer2.AddFeature(line); markerLayer2.AddFeature(marker); return dismarker.Position; } } }