Inheritance: Geometry
        private void MyBtn2_Click(object sender, RoutedEventArgs e)
        {
            Feature feature = new Feature();
            GeoRegion geoRegion = new GeoRegion();
            geoRegion.Parts.Add(new Point2DCollection() { new Point2D(50, 150), new Point2D(250, 250), new Point2D(400, 150), new Point2D(150, 150) });
            feature.Geometry = geoRegion;
            featureLayer.Features.Add(feature);

            mytb.Text = MyMap.Center.ToString();
        }
 /// <summary>${utility_DictionaryConverter_method_ToGeoRegion_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 MyMap_Loaded(object sender, RoutedEventArgs e)
        {
            #region 使用预定义点符号
            Feature featurePoint = new Feature();
            GeoPoint point = new GeoPoint();
            point.X = 116.2;
            point.Y = 39.6;
            PredefinedMarkerStyle simpleMarkerStyle = new PredefinedMarkerStyle();
            simpleMarkerStyle.Color = new SolidColorBrush(Colors.Red);
            simpleMarkerStyle.Size = 20;
            simpleMarkerStyle.Symbol = SuperMap.Web.Core.PredefinedMarkerStyle.MarkerSymbol.Star;
            featurePoint.Style = simpleMarkerStyle;
            featurePoint.Geometry = point;
            featuresLayer.Features.Add(featurePoint);
            #endregion

            #region 使用预定义线符号
            Feature featureLine = new Feature();
            Point2DCollection points = new Point2DCollection();
            points.Add(new Point2D(116.2, 39.6));
            points.Add(new Point2D(90, 50));
            points.Add(new Point2D(50, 25));
            points.Add(new Point2D(-80, 45));
            points.Add(new Point2D(-100, 38));
            ObservableCollection<Point2DCollection> path = new ObservableCollection<Point2DCollection>();
            path.Add(points);
            GeoLine geoLine = new GeoLine();
            geoLine.Parts = path;

            PredefinedLineStyle simpleLineStyle = new PredefinedLineStyle();
            simpleLineStyle.Stroke = new SolidColorBrush(Colors.Black);
            simpleLineStyle.StrokeThickness = 1;
            simpleLineStyle.StrokeDashArray = new DoubleCollection { 3, 1 };

            featureLine.Geometry = geoLine;
            featureLine.Style = simpleLineStyle;
            featuresLayer.Features.Add(featureLine);
            #endregion

            #region 使用预定义面符号
            Feature featureRegion = new Feature();
            Point2DCollection pointsRegion = new Point2DCollection();
            pointsRegion.Add(new Point2D(-8, 61));
            pointsRegion.Add(new Point2D(-6, 55));
            pointsRegion.Add(new Point2D(-8, 50));
            pointsRegion.Add(new Point2D(2, 50));
            pointsRegion.Add(new Point2D(1, 61));
            pointsRegion.Add(new Point2D(-8, 61));
            ObservableCollection<Point2DCollection> pRegion = new ObservableCollection<Point2DCollection>();
            pRegion.Add(pointsRegion);
            GeoRegion geoRegion = new GeoRegion();
            geoRegion.Parts = pRegion;

            PredefinedFillStyle simpleFillStyle = new PredefinedFillStyle();
            simpleFillStyle.StrokeThickness = 1;
            simpleFillStyle.Stroke = new SolidColorBrush(Colors.Black);
            simpleFillStyle.Fill = new SolidColorBrush(Colors.Yellow);

            featureRegion.Geometry = geoRegion;
            featureRegion.Style = simpleFillStyle;
            featuresLayer.Features.Add(featureRegion);
            #endregion

            #region 添加文本
            Feature featureText = new Feature();
            GeoPoint text = new GeoPoint();
            text.X = 5;
            text.Y = 10;

            TextStyle textStyle = new TextStyle();
            textStyle.Text = "Africa";
            textStyle.FontSize = 40;
            textStyle.Foreground = new SolidColorBrush(Colors.Blue);

            featureText.Geometry = text;
            featureText.Style = textStyle;
            featuresLayer.Features.Add(featureText);
            #endregion
        }
        public override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            if (this.points != null)
            {
                GeoRegion geoRegion = new GeoRegion();
                points.Add(a0);
                geoRegion.Parts.Add(points);

                PolygonElement pPen = new PolygonElement()
                {
                    Point2Ds = points,
                    #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
                };

                DrawEventArgs args2 = new DrawEventArgs
                {
                    DrawName = Name,
                    Element = pPen,
                    Geometry = geoRegion
                };

                Deactivate();
                OnDrawComplete(args2);
            }
            e.Handled = true;
            base.OnMouseLeftButtonUp(e);
        }
 //预留接口
 private static GeoRegion ToGeoRegion(XElement xe)
 {
     GeoRegion region = new GeoRegion();
     return region;
 }
        //绘制面结束后将所绘制的面转化为矢量要素并加载到矢量要素图层中
        private void polygon_DrawCompleted(object sender, DrawEventArgs e)
        {
            //将绘制面转化为面要素并加载到矢量要素图层中
            Feature feature = new Feature()
            {
                Geometry = e.Geometry as GeoRegion,
                Style = new PredefinedFillStyle
                {
                    Fill = regionColor1
                }
            };

            regionLayer.Features.Add(feature);
            region = e.Geometry as GeoRegion;

            Check();
        }
        public static bool CheckRegion(GeoRegion region, Point2D point)
        {
            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 (point.Y > iPointY)
                {
                    if (point.Y < jPointY)
                    {
                        pValue = (point.Y - iPointY) * (jPointX - iPointX) / (jPointY - iPointY) + iPointX;
                        if (point.X < pValue)
                        {
                            k++;
                        }
                        else if (point.X == pValue)
                        {
                            return true;
                        }
                    }
                    else if (point.X == jPointY)
                    {
                        p = 0;
                    }
                }
                else if (point.Y < iPointY)
                {
                    if (point.Y > jPointY)
                    {
                        pValue = (point.Y - iPointY) * (jPointX - iPointX) / (jPointY - iPointY) + iPointX;
                        if (point.X < pValue)
                        {
                            k++;
                        }
                        else if (point.X == pValue)
                        {
                            return true;
                        }
                    }
                    else if (point.Y == jPointY)
                    {
                        p = 1;
                    }
                }
                else
                {
                    if (point.X == iPointX)
                    {
                        return true;
                    }
                    if (point.Y < jPointY)
                    {
                        if (p != 1)
                        {
                            if (point.X < iPointX)
                            {
                                k++;
                            }
                        }
                    }
                    else if (point.Y > jPointY)
                    {
                        if (p > 0)
                        {
                            if (point.X < iPointX)
                            {
                                k++;
                            }
                        }
                    }
                    else
                    {
                        if (point.X > iPointX && point.X <= jPointX)
                        {
                            return true;
                        }
                        if (point.X < iPointX && point.X >= jPointX)
                        {
                            return true;
                        }
                    }
                }
                j = i;
                i++;
            }

            if (k % 2 != 0)
            {
                return true;
            }
            return false;
        }
        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);
            }
        }
        internal GeoRegion ToGeoRegion()
        {
            if (this.Parts != null)
            {
                List<Point2DCollection> pss = new List<Point2DCollection>();
                Point2DCollection copy = new Point2DCollection();
                foreach (Point2D item in this.Point2Ds)
                {
                    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]);
                    }
                    temp.Add(copy[0]); //面的话把第一个点作为最后一个点
                    pss.Add(temp);
                    copy.RemoveRange(0, this.Parts[i]);//把前面的删除
                } //把Point2Ds根据Parts分成一段一段的

                GeoRegion region = new GeoRegion();
                foreach (Point2DCollection item in pss)
                {
                    region.Parts.Add(item);
                }
                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);
            }
        }
        //从底层拷贝的判断点是否在面内,貌似速度没有扫描线算法快啊。
        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;
        }
 /// <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;
 }
 private GeoRegion ParseRegionCoordinates(XElement ele)
 {
     GeoRegion region = new GeoRegion();
     if (ele != null && !string.IsNullOrEmpty(ele.Value))
     {
         foreach (var linearRing in ele.Descendants(XName.Get("LinearRing", nameSpacePair["gml"])))
         {
             string[] values = linearRing.Value.Trim().Split(',', ' ');
             region.Parts.Add(GetPoint2Ds(values));
         }
     }
     return region;
 }