/// <summary>${core_GeoRegion_method_clone_D}</summary> public override Geometry Clone() { GeoRegion region = new GeoRegion(); if (this.Parts != null) { foreach (Point2DCollection points in this.Parts) { if (points != null) { Point2DCollection item = new Point2DCollection(); foreach (Point2D point in points) { if (point != null) { item.Add(point.Clone()); } } region.Parts.Add(item); continue; } region.Parts.Add(null); } } return region; }
/// <summary>${WP_utility_Extensions_method_ToGeoRegion_PolygonElement_D}</summary> public static GeoRegion ToGeoRegion(this PolygonElement polygonElement) { if (polygonElement != null && polygonElement.Point2Ds != null && polygonElement.Point2Ds.Count > 0) { GeoRegion region = new GeoRegion(); region.Parts.Add(polygonElement.Point2Ds.Clone()); return region; } return null; }
private void endDraw(bool isCancel = false) { if (points != null) { PolygonElement pRegion = new PolygonElement() { Point2Ds = this.points.Clone(), #region 所有风格的控制 Stroke = this.Stroke, StrokeThickness = this.StrokeThickness, StrokeMiterLimit = this.StrokeMiterLimit, StrokeDashOffset = this.StrokeDashOffset, StrokeDashArray = this.StrokeDashArray, StrokeDashCap = this.StrokeDashCap, StrokeEndLineCap = this.StrokeEndLineCap, StrokeLineJoin = this.StrokeLineJoin, StrokeStartLineCap = this.StrokeStartLineCap, Opacity = this.Opacity, Fill = this.Fill, FillRule = this.FillRule #endregion }; GeoRegion geoRegion = new GeoRegion();//构造返回的Geometry points.Add(startPt);//需要添加起始点做为最后一个点 geoRegion.Parts.Add(points); DrawEventArgs args = new DrawEventArgs { DrawName = Name, Element = pRegion, Geometry = geoRegion, Canceled = isCancel }; Deactivate(); OnDrawCompleted(args); } }
//预留接口 private static GeoRegion ToGeoRegion(XElement xe) { GeoRegion region = new GeoRegion(); return region; }
private void endDraw(bool isDblClick = false, bool isCancel = false) { if (points != null) { points.RemoveAt(points.Count - 2); if (isDblClick) { points.RemoveAt(points.Count - 2); } PolygonElement pRegion = new PolygonElement() { Point2Ds = points.Clone(),//不克隆,在返回后还与下面的GeoRegion指向一个内存地址 #region 所有风格的控制 Stroke = this.Stroke, StrokeThickness = this.StrokeThickness, StrokeMiterLimit = this.StrokeMiterLimit, StrokeDashOffset = this.StrokeDashOffset, StrokeDashArray = this.StrokeDashArray, StrokeDashCap = this.StrokeDashCap, StrokeEndLineCap = this.StrokeEndLineCap, StrokeLineJoin = this.StrokeLineJoin, StrokeStartLineCap = this.StrokeStartLineCap, Opacity = this.Opacity, Fill = this.Fill, FillRule = this.FillRule #endregion };//构造返回Element对象 GeoRegion geoRegion = new GeoRegion();//构造返回的Geometry points.Add(startPoint);//需要添加起始点做为最后一个点 geoRegion.Parts.Add(points); DrawEventArgs args = new DrawEventArgs { DrawName = Name, Element = pRegion, //Element = this.polyline //直接返回是固定像素的 Geometry = geoRegion, Canceled = isCancel }; Deactivate(); OnDrawCompleted(args); } }
private void endDraw(bool isCancel = false) { Rectangle2D bounds = this.map.Bounds; if (bounds.IsEmpty || bounds.Width == 0.0 || bounds.Height == 0.0) { return; } GeoRegion geoRegion = new GeoRegion();//构造返回的Geometry Point2DCollection geoPoints = new Point2DCollection(); geoPoints.Add(bounds.BottomLeft); geoPoints.Add(new Point2D(bounds.Right, bounds.Bottom)); geoPoints.Add(bounds.TopRight); geoPoints.Add(new Point2D(bounds.Left, bounds.Top)); geoPoints.Add(bounds.BottomLeft);//需要添加起始点做为最后一个点 geoRegion.Parts.Add(geoPoints); DrawEventArgs args2 = new DrawEventArgs { Geometry = geoRegion }; Deactivate(); OnDrawCompleted(args2); }
//从底层拷贝的判断点是否在面内,貌似速度没有扫描线算法快啊。 internal static bool CheckInRegion1(GeoRegion region, double x, double y) { // 判断是否在边线上。 // 设点为Q,线段为P1P2 ,判断点Q在该线段上的依据是:( Q - P1 ) × ( P2 - P1 ) = 0 且 Q 在以 // P1,P2为对角顶点的矩形内。前者保证Q点在直线P1P2上,后者是保证Q点不在线段P1P2的延长线或反向延长线上 Point2D p1; Point2D p2; bool isInLine = false; for (int i = 0; i < region.Parts.Count; i++) { for (int j = 0; j < region.Parts[i].Count; j++) { p1 = region.Parts[i][j]; if (j == region.Parts[i].Count - 1) { continue; } else { p2 = region.Parts[i][j + 1]; } if (p1.X == p2.X && p1.Y == p2.Y) // 同一点 { continue; } double cross = (x - p1.X) * (p2.Y - p1.Y) - (y - p1.Y) * (p2.X - p1.X); bool xIsInLine = x <= Math.Max(p1.X, p2.X) && x >= Math.Min(p1.X, p2.X); bool yIsInLine = y <= Math.Max(p1.Y, p2.Y) && y >= Math.Min(p1.Y, p2.Y); if (cross == 0 && xIsInLine && yIsInLine) { isInLine = true; break; } } if (isInLine) { break; } } if (isInLine) { return true; } bool oddNODES = false; for (int p = 0; p < region.Parts.Count; p++) { int polySides = region.Parts[p].Count; double[] polyX = new double[polySides]; double[] polyY = new double[polySides]; int j = 0; for (int i = 0; i < polySides; i++) { polyX[i] = region.Parts[p][i].X; polyY[i] = region.Parts[p][i].Y; } for (int i = 0; i < polySides; i++) { j++; if (j == polySides) { j = 0; } bool innerY = polyY[i] < y && polyY[j] >= y; bool innerY2 = polyY[j] < y && polyY[i] >= y; innerY = innerY || innerY2; if (innerY && (polyX[i] + (y - polyY[i]) / (polyY[j] - polyY[i]) * (polyX[j] - polyX[i]) < x)) { oddNODES = !oddNODES; } } // 已经在某一部分的内部,所以不需要继续判断。 if (oddNODES) { return oddNODES; } } return oddNODES; }
internal static bool CheckInRegion(GeoRegion region, double x, double y) { Point2DCollection points = region.Parts[0]; double pValue = double.NaN; int i = 0; int j = 0; double yValue = double.NaN; int m = 0; int n = 0; double iPointX = double.NaN; double iPointY = double.NaN; double jPointX = double.NaN; double jPointY = double.NaN; int k = 0; int p = 0; yValue = points[0].Y - points[(points.Count - 1)].Y; if (yValue < 0) { p = 1; } else if (yValue > 0) { p = 0; } else { m = points.Count - 2; n = m + 1; while (points[m].Y == points[n].Y) { m--; n--; if (m == 0) { return true; } } yValue = points[n].Y - points[m].Y; if (yValue < 0) { p = 1; } else if (yValue > 0) { p = 0; } } //使多边形封闭 int count = points.Count; i = 0; j = count - 1; while (i < count) { iPointX = points[j].X; iPointY = points[j].Y; jPointX = points[i].X; jPointY = points[i].Y; if (y > iPointY) { if (y < jPointY) { pValue = (y - iPointY) * (jPointX - iPointX) / (jPointY - iPointY) + iPointX; if (x < pValue) { k++; } else if (x == pValue) { return true; } } else if (x == jPointY) { p = 0; } } else if (y < iPointY) { if (y > jPointY) { pValue = (y - iPointY) * (jPointX - iPointX) / (jPointY - iPointY) + iPointX; if (x < pValue) { k++; } else if (x == pValue) { return true; } } else if (y == jPointY) { p = 1; } } else { if (x == iPointX) { return true; } if (y < jPointY) { if (p != 1) { if (x < iPointX) { k++; } } } else if (y > jPointY) { if (p > 0) { if (x < iPointX) { k++; } } } else { if (x > iPointX && x <= jPointX) { return true; } if (x < iPointX && x >= jPointX) { return true; } } } j = i; i++; } if (k % 2 != 0) { return true; } return false; }
internal GeoRegion ToGeoRegion() { if (this.Parts != null) { List<Point2DCollection> pss = new List<Point2DCollection>(); Point2DCollection copy = new Point2DCollection(); foreach (Point2D item in this.Points) { copy.Add(item); } for (int i = 0; i < this.Parts.Count; i++) { Point2DCollection temp = new Point2DCollection(); for (int j = 0; j < this.Parts[i]; j++) { temp.Add(copy[j]); } pss.Add(temp); copy.RemoveRange(0, this.Parts[i]); } GeoRegion region = new GeoRegion(); foreach (Point2DCollection item in pss) { region.Parts.Add(item); } return region; } return null; }