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; static FrmCompareFeature frm; public static void ShowForm(GSOGlobeControl _globeControl1, GSOGlobeControl _globeControl2, GSOLayer _layerTemp, GSOLayer _layerTemp2, int width) { if (frm == null) { frm = new FrmCompareFeature(_globeControl1, _globeControl2, _layerTemp, _layerTemp2); 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) { 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; } private void buttonAnalysis_Click(object sender, EventArgs e) { dataGridViewX1.DataSource = null; double bufferWidth = Convert.ToDouble(textBox1.Text); if (srcFeature == null || dscFeature == null) MessageBox.Show("请选择要对比的管段!", "提示"); else { if (srcFeature.Geometry.Type != dscFeature.Geometry.Type) MessageBox.Show("请选择同种类型图层!"); else if (srcFeature.Geometry.Type == dscFeature.Geometry.Type && srcFeature.Geometry.Type == EnumGeometryType.GeoPolyline3D) { lineLayerCompare(srcFeature, dscFeature, bufferWidth); if (!isSamePolyline) MessageBox.Show("实测管段与施工管段非同一条管段,请选择同一管段进行比较!", "提示"); else { lineFeatureCompare(srcFeature, dscFeature); globeControl1.Globe.Action = EnumAction3D.ActionNull; globeControl2.Globe.Action = EnumAction3D.ActionNull; } } 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 = calculateDistance(srcLine, dscLine,false); double verticalDistance = calculateDistance(srcLine, dscLine,true); 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; } private void addPologyToGlobeControl(GSOGeoPolyline3D line, double bufferWidth) { 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(); } private GSOLayer getSameLayer(GSOFeature feature) { GSOLayer layer = null; if (!feature.Dataset.Caption.StartsWith("施工")) { layer = feature.Dataset.Caption == "供电管线" ? globeControl2.Globe.Layers.GetLayerByCaption("施工电力管线") : globeControl2.Globe.Layers.GetLayerByCaption("施工" + feature.Dataset.Caption); } else { layer = feature.Dataset.Caption == "施工电力管线" ? globeControl1.Globe.Layers.GetLayerByCaption("供电管线") : globeControl1.Globe.Layers.GetLayerByCaption(feature.Dataset.Caption.Replace("施工", "")); } return layer; } /// <summary> /// 地球1中点击地球2中同步添加缓冲区 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void globeControl1_MouseClick(object sender, MouseEventArgs e) { layerTemp.Visible = true; layerTemp2.Visible = true; GSOFeatures listFeatures = new GSOFeatures(); double maxLength = 0; if (globeControl1.Globe.SelectedObject == null) return; else { clearFeatureHighLight(globeControl1, globeControl2); try { double bufferWidth = Convert.ToDouble(textBox1.Text); resPolygon = null; if (globeControl1.Globe.Action == EnumAction3D.SelectObject && globeControl1.Globe.SelectedObject != null) { GSOGeoPolyline3D line = globeControl1.Globe.SelectedObject.Geometry as GSOGeoPolyline3D; addPologyToGlobeControl(line, bufferWidth); } srcFeature = globeControl1.Globe.SelectedObject; GSOLayer layers = getSameLayer(srcFeature); 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]); } calculate(out maxLength, out dscFeature, listFeatures, scLine); } catch (Exception ex) { LogError.PublishError(ex); } } } /// <summary> /// 地球2中点击地球1中同步添加缓冲区 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void globeControl2_MouseClick(object sender, MouseEventArgs e) { layerTemp.Visible = true; layerTemp2.Visible = true; GSOFeatures listFeatures = new GSOFeatures(); double maxLength = 0; if (globeControl2.Globe.SelectedObject == null) return; else { clearFeatureHighLight(globeControl1, globeControl2); try { double bufferWidth = Convert.ToDouble(textBox1.Text); resPolygon = null; if (globeControl2.Globe.Action != EnumAction3D.SelectObject || globeControl2.Globe.SelectedObject == null) return; else { GSOGeoPolyline3D line = globeControl2.Globe.SelectedObject.Geometry as GSOGeoPolyline3D; addPologyToGlobeControl(line, bufferWidth); } dscFeature = globeControl2.Globe.SelectedObject; //双屏同时选中同一管段 GSOLayer layers = getSameLayer(dscFeature); GSOFeatures features = layers.FindFeaturesInPolygon(resPolygon, false); GSOGeoPolyline3D scLine = dscFeature.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]); } } calculate(out maxLength, out srcFeature, listFeatures, scLine); } catch (Exception ex) { LogError.PublishError(ex); } } } private void calculate(out double maxLength, out GSOFeature feature, GSOFeatures listFeatures, GSOGeoPolyline3D scLine) { maxLength = 0; feature=new GSOFeature(); if (listFeatures.Length == 0) feature = null; else { if (listFeatures.Length == 1) { feature = 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)); if (m == 0) { feature = listFeatures[0]; listFeatures[0].HighLight = true; maxLength = lengthAbs; } else if (lengthAbs < maxLength) { feature = listFeatures[m]; listFeatures[m].HighLight = true; maxLength = lengthAbs; } } } } } /// <summary> /// 计算距离 /// </summary> /// <param name="line1"></param> /// <param name="line2"></param> /// <returns></returns> double calculateDistance(GSOGeoPolyline3D line1, GSOGeoPolyline3D line2,bool isVertical) { GSOPoint3d pntIntersect1 = new GSOPoint3d(); GSOPoint3d pntIntersect2 = new GSOPoint3d(); GSOPoint3d pntProIntersect1 = new GSOPoint3d(); GSOPoint3d pntProIntersect2 = new GSOPoint3d(); double dDist = 0; if (isVertical) { dDist = globeControl1.Globe.Analysis3D.ComputeVerticalDistance(line1, line2, out pntIntersect1, out pntIntersect2, out pntProIntersect1, out pntProIntersect2, false); LabelDistance(layerTemp, layerTemp2, pntProIntersect1, pntProIntersect2, dDist, true, "垂直"); } else { dDist = globeControl1.Globe.Analysis3D.ComputeHorizonDistance(line1, line2, out pntIntersect1, out pntIntersect2, out pntProIntersect1, out pntProIntersect2, false); LabelDistance(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)) continue; 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)) continue; 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 LabelDistance(GSOLayer markerLayer, GSOLayer markerLayer2, GSOPoint3d pntIntersect1, GSOPoint3d pntIntersect2, double distance, bool markerVisible,string label) { 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); GSOGeoMarker dismarker = new GSOGeoMarker(); GSOFeature marker = null; GSOFeature line = null; createLineStyle(out marker, out line,disline, pntIntersect1, pntIntersect2, distance, label, 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="marker"></param> /// <param name="line"></param> /// <param name="disline"></param> /// <param name="pntIntersect1"></param> /// <param name="pntIntersect2"></param> /// <param name="distance"></param> /// <param name="label"></param> /// <param name="dismarker"></param> private void createLineStyle(out GSOFeature marker,out GSOFeature line,GSOGeoPolyline3D disline, GSOPoint3d pntIntersect1,GSOPoint3d pntIntersect2, double distance, string label, GSOGeoMarker dismarker) { GSOSimpleLineStyle3D style = new GSOSimpleLineStyle3D(); //创建线的风格 style.LineColor = Color.Red; style.LineWidth = 5; //设置线的宽度为5 style.VertexVisible = true; //显示线的节点 disline.Style = style; //把风格添加到线上 disline.AltitudeMode = EnumAltitudeMode.Absolute; line=new GSOFeature(); line.Geometry = disline; dismarker.X = pntIntersect1.X; dismarker.Y = pntIntersect1.Y; dismarker.Z = (pntIntersect1.Z + pntIntersect2.Z) / 2; dismarker.Text = label + 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; marker=new GSOFeature(); marker.Geometry = dismarker; } } }