//得到阈值 public void GetThreshold(double original)//此函数必须在edges初始化完成后才能调用 { double theEpsilon = trace.EPSILON; if (trace.GetEdges().Count == 0) { return; } //double threshold = 0; foreach (var e in trace.GetEdges()) { if (e.p1.Value == original) { Tin_Point p = trace.GetValuePoint(e, original + theEpsilon, 0); double distance = Math.Abs((e.p1.X - p.X) * (e.p1.X - p.X) + (e.p1.Y - p.Y) * (e.p1.Y - p.Y)); if (distance > threshold) { threshold = distance; } } else if (e.p2.Value == original) { Tin_Point p = trace.GetValuePoint(e, original + theEpsilon, 0); double distance = Math.Abs((e.p2.X - p.X) * (e.p2.X - p.X) + (e.p2.Y - p.Y) * (e.p2.Y - p.Y)); if (distance > threshold) { threshold = distance; } } } }
// public double GetThreshold(double value)//此函数必须在edges初始化完成后才能调用 { double theEpsilon = 0.02; if (edges.Count == 0) { return(0); } double threshold = 0; foreach (var e in edges) { if (e.p1.Value == value && e.p2.Value > value) { Tin_Point p = GetValuePoint(e, value + theEpsilon, 0); double distance = Math.Sqrt((e.p1.X - p.X) * (e.p1.X - p.X) + (e.p1.Y - p.Y) * (e.p1.Y - p.Y)); if (distance > threshold) { threshold = distance; } //Console.WriteLine("p1阈值为:" + threshold); } else if (e.p2.Value == value && e.p1.Value > value) { Tin_Point p = GetValuePoint(e, value + theEpsilon, 0); double distance = Math.Sqrt((e.p2.X - p.X) * (e.p2.X - p.X) + (e.p2.Y - p.Y) * (e.p2.Y - p.Y)); if (distance > threshold) { threshold = distance; } //Console.WriteLine("p1阈值为:" + threshold); } } return(threshold); }
public bool ContainPoint(Tin_Point t1, Tin_Point t2, double value)//边上是否包括等值点 { if ((t1.Value - value) * (t2.Value - value) <= 0) { return(true); } else { return(false); } }
public Tin_Point GetValuePoint(Edges edges, double value, int type)//得到一条边上的等值点 { double factor = 0; double thex = 0; double they = 0; if (edges.p1.Value == value && edges.p2.Value > value) { factor = (value - edges.p1.Value - EPSILON) / (edges.p2.Value - edges.p1.Value - EPSILON); thex = edges.p1.X + factor * (edges.p2.X - edges.p1.X); they = edges.p1.Y + factor * (edges.p2.Y - edges.p1.Y); } else if (edges.p1.Value == value && edges.p2.Value < value) { factor = (value - edges.p1.Value + EPSILON) / (edges.p2.Value - edges.p1.Value + EPSILON); thex = edges.p1.X + factor * (edges.p2.X - edges.p1.X); they = edges.p1.Y + factor * (edges.p2.Y - edges.p1.Y); } else if (edges.p2.Value == value && edges.p1.Value < value) { factor = (value - edges.p1.Value + EPSILON) / (edges.p2.Value - edges.p1.Value + EPSILON); thex = edges.p1.X + factor * (edges.p2.X - edges.p1.X); they = edges.p1.Y + factor * (edges.p2.Y - edges.p1.Y); } else if (edges.p2.Value == value && edges.p1.Value > value) { factor = (value - edges.p1.Value - EPSILON) / (edges.p2.Value - edges.p1.Value - EPSILON); thex = edges.p1.X + factor * (edges.p2.X - edges.p1.X); they = edges.p1.Y + factor * (edges.p2.Y - edges.p1.Y); } else { factor = (value - edges.p1.Value) / (edges.p2.Value - edges.p1.Value); thex = edges.p1.X + factor * (edges.p2.X - edges.p1.X); they = edges.p1.Y + factor * (edges.p2.Y - edges.p1.Y); } Tin_Point thepoint = new Tin_Point(thex, they, value); //if(thepoint.Equals(edges.p1)) thepoint.Type = type; return(thepoint); }
public FeatureSet DrawLine() { FeatureSet lineF = new FeatureSet(FeatureType.Line); lineF.Projection = map.Projection; lineF.DataTable.Columns.Add("Value", typeof(double));//方便之后在等值线上标注 MapLineLayer lineLayer = default(MapLineLayer); lineLayer = (MapLineLayer)map.Layers.Add(lineF); LineSymbolizer symnol = new LineSymbolizer(Color.Black, 2); lineLayer.Symbolizer = symnol; string[] thename = raster.Filename.Split('\\'); lineLayer.LegendText = thename[thename.Length - 1] + "_line"; //MapLabelLayer MapLabelLayer labelLayer = new MapLabelLayer(); ILabelCategory category = labelLayer.Symbology.Categories[0]; category.Expression = "[Value]"; category.SelectionSymbolizer.BackColorEnabled = true; category.Symbolizer.BorderVisible = false; category.Symbolizer.BackColor = Color.FromArgb(128, Color.LightBlue);; category.Symbolizer.FontStyle = FontStyle.Regular; category.Symbolizer.FontColor = Color.Black; category.Symbolizer.FontSize = 8.5f; category.Symbolizer.Orientation = ContentAlignment.MiddleCenter; category.Symbolizer.Alignment = StringAlignment.Center; lineLayer.ShowLabels = true; lineLayer.LabelLayer = labelLayer; /*double min_X, min_Y, max_X, max_Y; * min_X = raster.Xllcenter - raster.CellWidth / 2; * min_Y = raster.Yllcenter - raster.CellHeight / 2; * max_X = raster.CellToProj(0, raster.NumColumns-1).X + raster.CellWidth / 2; * max_Y = raster.CellToProj(0, 0).Y + raster.CellHeight/2; * double interspace = (raster.CellToProj(1, 1).X - raster.CellToProj(0, 0).X) * * (raster.CellToProj(1, 1).X - raster.CellToProj(0, 0).X) + (raster.CellToProj(1, 1).Y - raster.CellToProj(0, 0).Y) * * (raster.CellToProj(1, 1).Y - raster.CellToProj(0, 0).Y); * Console.WriteLine("minX: " + min_X + " , minY: "+ min_Y + " , maxX: " + max_X + " , maxY: " + max_Y);*/ List <Tin_Point> lpoints = new List <Tin_Point>(); foreach (var lines in contourData) { //if(lines.Key == 18) //{ //int i = 0; foreach (var line in lines.Value) { Tin_Point p1 = new Tin_Point(line.startPoint.X, line.startPoint.Y, lines.Key); Tin_Point p2 = new Tin_Point(line.endPoint.X, line.endPoint.Y, lines.Key); //p1.Type = i; //p2.Type = i; lpoints.Add(p1); lpoints.Add(p2); List <Coordinate> lineArray = new List <Coordinate>(); LineString lineGeometry = new LineString(lineArray); IFeature lineFeature = lineF.AddFeature(lineGeometry); lineFeature.Coordinates.Add(line.startPoint); lineFeature.Coordinates.Add(line.endPoint); lineFeature.DataRow["Value"] = lines.Key; lineF.InitializeVertices(); //i++; } //} } /* * Polish polish = new Polish(); * List<List<Tin_Point>> new_tin_points = polish.ClassifyLine(lpoints); * Console.WriteLine("new_tin_point num: " + new_tin_points.Count); * foreach(var lines in new_tin_points) * { * //int i = 0; * foreach(var p in lines) * { * Console.Write(p.X + " , " + p.Y + "||"); * } * Console.WriteLine("*********************************"); * } * foreach (var lines in new_tin_points) * { * //int i = 0; * * Console.WriteLine(lines[0].X + " , " + lines[0].Y + "||" + lines[lines.Count-1].X + " , " + lines[lines.Count - 1].Y); * } * * * foreach (var freeline in new_tin_points) * { * List<Coordinate> lineArray = new List<Coordinate>(); ; * ILineString lineGeometry = new LineString(lineArray); * IFeature lineFeature = lineF.AddFeature(lineGeometry); * lineFeature.DataRow["Value"] = (int)freeline[0].Value; * foreach (var p in freeline) * { * Coordinate coordinate = new Coordinate(p.X, p.Y); * lineArray.Add(coordinate); * lineFeature.Coordinates.Add(coordinate); * lineF.InitializeVertices(); * } * } */ map.ResetBuffer(); return(lineF); }
// public List <List <Tin_Point> > TraceModify(List <List <Tin_Point> > tp, double original)//等值线改进算法 { Console.WriteLine("改进值为: " + original); threshold = trace.GetThreshold(original); Console.WriteLine("阈值的大小为:" + threshold); //首先要计算临界距离,在这个距离内的点表示与当前等值点几乎重合。 List <Tin_Point> p18 = new List <Tin_Point>(); List <bool> flag = new List <bool>();//用来记录那几条等值线包含特殊点 Tin_Point p1 = null; Tin_Point p2 = null; Tin_Point p3 = null; Tin_Point p4 = null; List <Tin_Point> sps = new List <Tin_Point>(); int l1, l2; int type1, type2; //需要处理的两条等值线的类型,-1为开放,-2为闭合,如果都是闭合则最后只生成一条等值线,如果都是开放则生成两条等值线,如果一条开放一条闭合则生成一条开放等值线 l1 = l2 = -1; //两条等值线的序号 type1 = type2 = 0; sps = trace.GetSpecialPoint(original); //value = 18 foreach (var points in sps) { p18.Clear(); flag.Clear(); tp = SetLinesType(tp); foreach (var tpline in tp) { Console.WriteLine(tpline[0].Type); } for (int i = 0; i < tp.Count; i++) { flag.Add(false); if (tp[i][0].Type == -1) { tp[i] = RemoveInvalid(tp[i], points);//移除距离太近的且靠近等值点的点 } //tp[i] = RemoveInvalid(tp[i], points);//移除距离太近的且靠近等值点的点 foreach (var p in tp[i]) { double distance = Math.Sqrt((p.X - points.X) * (p.X - points.X) + (p.Y - points.Y) * (p.Y - points.Y)); if (distance <= threshold) { p18.Add(p); flag[i] = true; break; } } if (flag[i] == false) { p18.Add(null); } } for (int i = 0; i < flag.Count; i++) { if (flag[i] == true) { for (int j = 0; j < tp[i].Count; j++) { if (tp[i][j].Equals(p18[i])) { if (p1 == null && p3 == null) { type1 = tp[i][0].Type; if (type1 == -1) { if (j - 1 < 0 || j + 1 == tp[i].Count) { break; } else { p1 = tp[i][j - 1]; p3 = tp[i][j + 1]; l1 = i; } } else { if (j - 1 < 0) { p1 = tp[i][tp[i].Count - 2]; p3 = tp[i][1]; l1 = i; } if (j + 1 == tp[i].Count) { p1 = tp[i][j - 1]; p3 = tp[i][1]; l1 = i; } else { p1 = tp[i][j - 1]; p3 = tp[i][j + 1]; l1 = i; } } } else { type2 = tp[i][0].Type; if (type2 == -1) { if (j - 1 < 0 || j + 1 == tp[i].Count) { break; } else { p2 = tp[i][j - 1]; p4 = tp[i][j + 1]; l2 = i; } } else { if (j - 1 < 0) { p2 = tp[i][tp[i].Count - 2]; p4 = tp[i][1]; l2 = i; } if (j + 1 == tp[i].Count) { p2 = tp[i][j - 1]; p4 = tp[i][1]; l2 = i; } else if (j - 1 > 0 && j + 1 != tp[i].Count) { p2 = tp[i][j - 1]; p4 = tp[i][j + 1]; l2 = i; } } } break; } } } } Console.WriteLine("L1: " + l1 + ", L2: " + l2); if (l1 != -1 && l2 != -1)//得到tp中的两条等值线 { Console.WriteLine("得到两条等值线,进行合并操作"); if (type1 == -1 && type2 == -1) { Console.WriteLine("两条等值线均为开放形!"); List <Tin_Point> newline1, newline2;//共同构建出两条新的等值线 newline1 = new List <Tin_Point>(); newline2 = new List <Tin_Point>(); bool sign = false; if ((GetDistance(p1, p2) + GetDistance(p3, p4)) < (GetDistance(p1, p4) + GetDistance(p2, p3)))//12 34分别为两组 { Console.WriteLine("12 34 < 14 23"); if (GetDistance(p1, p2) < GetDistance(p3, p4)) { Console.WriteLine("12 < 43"); for (int k = tp[l1].Count - 1; k >= 0; k--) { if (tp[l1][k].Equals(p3)) { newline1.Add(p3); newline1.Add(points); break; } newline1.Add(tp[l1][k]); } for (int k = 0; k < tp[l2].Count; k++) { if (sign) { newline1.Add(tp[l2][k]); } if (tp[l2][k].Equals(p4)) { newline1.Add(p4); sign = true; } } sign = false; for (int k = 0; k < tp[l1].Count; k++) { if (tp[l1][k].Equals(p1)) { newline2.Add(p1); break; } newline2.Add(tp[l1][k]); } for (int k = tp[l2].Count - 1; k >= 0; k--) { if (sign) { newline2.Add(tp[l2][k]); } if (tp[l2][k].Equals(p2)) { newline2.Add(p2); sign = true; } } sign = false; } else { Console.WriteLine("12 > 43"); for (int k = 0; k < tp[l1].Count; k++) { if (tp[l1][k].Equals(p1)) { newline1.Add(p1); newline1.Add(points); break; } newline1.Add(tp[l1][k]); } for (int k = tp[l2].Count - 1; k >= 0; k--) { if (sign) { newline1.Add(tp[l2][k]); } if (tp[l2][k].Equals(p2)) { newline1.Add(p2); sign = true; } } sign = false; for (int k = tp[l1].Count - 1; k >= 0; k--) { if (tp[l1][k].Equals(p3)) { newline2.Add(p3); break; } newline2.Add(tp[l1][k]); } for (int k = 0; k < tp[l2].Count; k++) { if (sign) { newline2.Add(tp[l2][k]); } if (tp[l2][k].Equals(p4)) { newline2.Add(p4); sign = true; } } sign = false; } } else//14 23分别为两组 { Console.WriteLine("14 23 < 12 24"); if (GetDistance(p1, p4) < GetDistance(p3, p2))//p3后,p3,p18,p2,p2前(p1前,p1,p4,p4后) { Console.WriteLine("14 < 32"); for (int k = 0; k < tp[l2].Count; k++)//newl1,p2前 p2 p18 { if (tp[l2][k].Equals(p2)) { newline1.Add(p2); Console.WriteLine("P2: " + p2.ToString()); newline1.Add(points); break; } newline1.Add(tp[l2][k]); } for (int k = 0; k < tp[l1].Count; k++)//newl1,p3 p3后 { if (sign == true) { newline1.Add(tp[l1][k]); } if (tp[l1][k].Equals(p3)) { Console.WriteLine("P3: " + p3.ToString()); newline1.Add(p3); sign = true; } } sign = false; for (int k = 0; k < tp[l1].Count; k++)//newl2,p1前,p1 { if (tp[l1][k].Equals(p1)) { newline2.Add(p1); break; } newline2.Add(tp[l1][k]); } for (int k = 0; k < tp[l2].Count; k++)//newl2,p4,p4后 { if (sign) { newline2.Add(tp[l2][k]); } if (tp[l2][k].Equals(p4)) { newline2.Add(p4); sign = true; } } sign = false; } else//p1前,p1,p18,p4,p4后(p3后,p3,p2,p2前) { Console.WriteLine("23 < 14"); for (int k = 0; k < tp[l1].Count; k++)//newl1加入p1,p18以及之前 { if (tp[l1][k].Equals(p1)) { newline1.Add(p1); newline1.Add(points); break; } newline1.Add(tp[l1][k]); } for (int k = 0; k < tp[l2].Count; k++)//newl1加入p4以及之后 { if (sign == true) { newline1.Add(tp[l2][k]); } if (tp[l2][k].Equals(p4)) { newline1.Add(p4); sign = true; } } sign = false; for (int k = 0; k < tp[l2].Count; k++)//newl2加入p2以及之前 { if (tp[l2][k].Equals(p2)) { newline2.Add(p2); //newline2.Add(points); break; } newline2.Add(tp[l2][k]); } for (int k = 0; k < tp[l1].Count; k++)//newl2加入p3以及之后 { if (sign) { newline2.Add(tp[l1][k]); } if (tp[l1][k].Equals(p3)) { newline2.Add(p3); sign = true; } } sign = false; } } //将newl1和newl2加入等值线 tp.Add(newline1); tp.Add(newline2); tp.RemoveAt(l1); l2--; tp.RemoveAt(l2); } else if (type1 == -1 || type2 == -1) { Console.WriteLine("其中一条等值线均为开放形!"); List <Tin_Point> newline = new List <Tin_Point>(); bool sign = false; bool special = false; if ((GetDistance(p1, p2) + GetDistance(p3, p4)) < (GetDistance(p1, p4) + GetDistance(p2, p3)))//12 34分别为两组 { if (type1 == -1) { for (int k = 0; k < tp[l1].Count; k++) { newline.Add(tp[l1][k]); if (tp[l1][k] == p1) { break; } } newline.Add(points); if (tp[l2][tp[l2].Count - 1] == p2) { special = true; } for (int k = tp[l2].Count - 1; k >= 0; k--) { if (tp[l2][k] == p2) { sign = true; } if (sign) { newline.Add(tp[l2][k]); } if (k == 0 && special) { k = tp[l2].Count - 1; } if (special && tp[l2][k] == p4) { break; } } sign = false; for (int k = 0; k < tp[l1].Count; k++) { if (tp[l1][k] == p3) { sign = true; } if (sign) { newline.Add(tp[l1][k]); } } } else { for (int k = 0; k < tp[l2].Count; k++) { newline.Add(tp[l2][k]); if (tp[l2][k] == p2) { break; } } newline.Add(points); if (tp[l1][tp[l1].Count - 1] == p1) { special = true; } for (int k = tp[l1].Count - 1; k >= 0; k--) { if (tp[l1][k] == p1) { sign = true; } if (sign) { newline.Add(tp[l1][k]); } if (k == 0 && special) { k = tp[l1].Count - 1; } if (special && tp[l1][k] == p3) { break; } } sign = false; for (int k = 0; k < tp[l2].Count; k++) { if (tp[l2][k] == p4) { sign = true; } if (sign) { newline.Add(tp[l2][k]); } } } } else { sign = false; special = false; if (type1 == -1) { for (int k = 0; k < tp[l1].Count; k++) { newline.Add(tp[l1][k]); if (tp[l1][k] == p1) { break; } } newline.Add(points); if (p4 == tp[l2][1]) { special = true; } for (int k = 0; k < tp[l2].Count; k++) { if (tp[l2][k] == p4) { sign = true; } if (sign) { newline.Add(tp[l2][k]); } if (special && k == tp[l2].Count - 1) { k = 0; } if (special && tp[l2][k] == p2) { break; } } sign = false; for (int k = 0; k < tp[l1].Count; k++) { if (tp[l1][k] == p3) { sign = true; } if (sign) { newline.Add(tp[l1][k]); } } } else { for (int k = 0; k < tp[l2].Count; k++) { newline.Add(tp[l2][k]); if (tp[l2][k] == p2) { break; } } newline.Add(points); if (p3 == tp[l2][1]) { special = true; } for (int k = 0; k < tp[l1].Count; k++) { if (tp[l1][k] == p3) { sign = true; } if (sign) { newline.Add(tp[l1][k]); } if (special && k == tp[l1].Count - 1) { k = 0; } if (special && tp[l1][k] == p1) { break; } } sign = false; for (int k = 0; k < tp[l2].Count; k++) { if (tp[l2][k] == p4) { sign = true; } if (sign) { newline.Add(tp[l2][k]); } } } } tp.Add(newline); tp.RemoveAt(l1); l2--; tp.RemoveAt(l2); } else { List <Tin_Point> newline = new List <Tin_Point>(); if ((GetDistance(p1, p2) + GetDistance(p3, p4)) < (GetDistance(p1, p4) + GetDistance(p2, p3)))//12 34分别为两组 { } else { } } } p1 = p2 = p3 = p4 = null; l1 = l2 = -1; type1 = type2 = 0; } foreach (var tpline in tp) { foreach (var linepoint in tpline) { linepoint.Value -= trace.EPSILON; } } return(tp); }
//一条等值线上两个点距离因为某等值点的原因太近可以进行移除 public List <Tin_Point> RemoveInvalid(List <Tin_Point> lines, Tin_Point point) { //Console.WriteLine("Spetial Point: "+point.ToString()); Tin_Point p1, p2; bool flag = false; //Console.WriteLine("*******************************"); for (int i = 0; i < lines.Count - 1; i++) { p1 = lines[i]; p2 = lines[i + 1]; //Console.WriteLine("p2: " + p2.ToString()); if (!flag) { if (GetDistance(p1, point) <= threshold) { flag = true; if (GetDistance(p2, point) <= threshold) { if (GetDistance(p1, p2) < 2 * threshold) { lines.RemoveAt(i + 1); i--; } } } } else { /*if (GetDistance(lines[0], point) <= threshold) * { * lines.RemoveAt(0); * i--; * } * else if (GetDistance(lines[lines.Count - 1], point) <= threshold) * { * lines.RemoveAt(lines.Count - 1); * i--; * }*/ if (GetDistance(lines[0], point) <= threshold) { lines.RemoveAt(0); i--; flag = false; } else if (GetDistance(lines[lines.Count - 1], point) <= threshold) { lines.RemoveAt(lines.Count - 1); i--; flag = false; } if (GetDistance(p2, point) <= threshold) { lines.RemoveAt(i + 1); //Console.WriteLine("Remove Point: " + point.ToString()); i--; } } } return(lines); }
public double GetDistance(Tin_Point p1, Tin_Point p2) { double distance = Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y)); return(distance); }