Example #1
0
        /// <summary>
        /// Get the current row, convert the data to a plugin row
        /// Project the data in the right projection.
        /// </summary>
        /// <returns></returns>
        public override PluginRow GetCurrentRow()
        {
            if (StationMeasurements != null && StationMeasurements.Current != null)
            {
                // Create a point
                MapPointBuilder location = new MapPointBuilder(StationMeasurements.Current.Lon, StationMeasurements.Current.Lat, new SpatialReferenceBuilder(4326).ToSpatialReference());

                // Convert point to rd point.
                Geometry locationRD = GeometryEngine.Instance.Project(location.ToGeometry(), SpatialReferenceBuilder.CreateSpatialReference(28992));

                // Convert attribute data
                var listOfRowValues = new List <object>();
                listOfRowValues.Add(StationMeasurements.Current.Stationid);
                listOfRowValues.Add(StationMeasurements.Current.Stationname);
                listOfRowValues.Add(StationMeasurements.Current.Temperature);
                listOfRowValues.Add(StationMeasurements.Current.Timestamp);
                listOfRowValues.Add(StationMeasurements.Current.Weatherdescription);
                listOfRowValues.Add(StationMeasurements.Current.Iconurl);
                listOfRowValues.Add(StationMeasurements.Current.Humidity);
                listOfRowValues.Add(StationMeasurements.Current.Sunpower);
                listOfRowValues.Add(StationMeasurements.Current.Airpressure);
                listOfRowValues.Add(StationMeasurements.Current.Visibility);

                // Add the geometry
                listOfRowValues.Add(locationRD);

                return(new PluginRow(listOfRowValues));
            }

            return(new PluginRow());
        }
        private async void UpdateManualFeedback()
        {
            if (LineFromType == LineFromTypes.BearingAndDistance && Azimuth.HasValue && HasPoint1 && Point1 != null)
            {
                GeodeticCurveType curveType = DeriveCurveType(LineType);
                LinearUnit        lu        = DeriveUnit(LineDistanceType);
                // update feedback
                var segment = QueuedTask.Run(() =>
                {
                    var mpList = new List <MapPoint>()
                    {
                        Point1
                    };
                    // get point 2
                    // SDK Bug, GeometryEngine.GeodesicMove seems to not honor the LinearUnit passed in, always does Meters
                    var tempDistance = ConvertFromTo(LineDistanceType, DistanceTypes.Meters, Distance);
                    var results      = GeometryEngine.Instance.GeodeticMove(mpList, MapView.Active.Map.SpatialReference, tempDistance, LinearUnit.Meters /*GetLinearUnit(LineDistanceType)*/, GetAzimuthAsRadians().Value, GetCurveType());
                    foreach (var mp in results)
                    {
                        // WORKAROUND: For some odd reason GeodeticMove is removing the Z attribute of the point
                        // so need to put it back so all points will have a consistent Z.
                        // This is important when storing to feature class with Z
                        if (mp == null)
                        {
                            continue;
                        }

                        if (Double.IsNaN(mp.Z))
                        {
                            MapPointBuilder mb = new MapPointBuilder(mp.X, mp.Y, 0.0, mp.SpatialReference);
                            Point2             = mb.ToGeometry();
                        }
                        else
                        {
                            Point2 = mp;
                        }
                    }

                    if (Point2 != null)
                    {
                        var point2Proj = GeometryEngine.Instance.Project(Point2, Point1.SpatialReference);
                        return(LineBuilder.CreateLineSegment(Point1, (MapPoint)point2Proj));
                    }
                    else
                    {
                        return(null);
                    }
                }).Result;

                if (segment != null)
                {
                    await UpdateFeedbackWithGeoLine(segment, curveType, lu);
                }
            }
            else
            {
                ClearTempGraphics(); // if not, or no longer, valid clear
            }
        }
Example #3
0
        public static MapPoint MidPoint(MapPoint p1, MapPoint p2)
        {
            MapPointBuilder p = new MapPointBuilder(p1.SpatialReference);

            p.X = (p1.X + p2.X) / 2.0;
            p.Y = (p1.Y + p2.Y) / 2.0;
            return(p.ToGeometry());
        }
Example #4
0
        public static MapPoint InterpolatePointOnLine(MapPoint p1, MapPoint p2, double scale)
        {
            MapPointBuilder p = new MapPointBuilder(p1.SpatialReference);
            double          x = 0.0, y = 0.0;

            GeometryAlgorithms.InterpolatePointOnLine(p1.X, p1.Y, p2.X, p2.Y, scale, ref x, ref y);
            p.X = x;
            p.Y = y;
            return(p.ToGeometry());
        }
		// Helper method
		private static PointCollection FromArray(params double[] parameters)
		{
			PointCollection coll = new PointCollection(SpatialReferences.Wgs84);
			var mapPointBuilder = new MapPointBuilder(SpatialReferences.Wgs84);
			for (int i = 0; i < parameters.Length - 1; i+=2)
			{
				mapPointBuilder.SetValues(parameters[i], parameters[i + 1]);
				coll.Add(mapPointBuilder.ToGeometry());
			}
			return coll;
		}
Example #6
0
 // CreateOffsetMapPoint - creates a new MapPoint offset from a given base point.
 private MapPoint CreateOffsetMapPoint(MapPoint basePoint, double xOffset, double yOffset)
 {
     using (MapPointBuilder mapPointBuilder = new MapPointBuilder())
     {
         mapPointBuilder.X    = basePoint.X + xOffset;
         mapPointBuilder.Y    = basePoint.Y + yOffset;
         mapPointBuilder.Z    = basePoint.Z;
         mapPointBuilder.HasZ = true;
         return(mapPointBuilder.ToGeometry());
     }
 }
        // Helper method
        private static PointCollection FromArray(params double[] parameters)
        {
            PointCollection coll            = new PointCollection(SpatialReferences.Wgs84);
            var             mapPointBuilder = new MapPointBuilder(SpatialReferences.Wgs84);

            for (int i = 0; i < parameters.Length - 1; i += 2)
            {
                mapPointBuilder.SetValues(parameters[i], parameters[i + 1]);
                coll.Add(mapPointBuilder.ToGeometry());
            }
            return(coll);
        }
Example #8
0
        public void CanMapPointBuilderInstance()
        {
            using (var builder = new MapPointBuilder(1.0, 2.0))
            {
                Assert.False(builder.HasZ);
                Assert.False(builder.HasM);
                Assert.False(builder.HasID);
                Assert.False(builder.IsEmpty);

                var pt = builder.ToGeometry();
                Assert.False(pt.HasZ);
                Assert.False(pt.HasM);
                Assert.False(pt.HasID);
                Assert.False(pt.IsEmpty);
            }

            using (var builder = new MapPointBuilder(1.0, 2.0, 3.0))
            {
                Assert.True(builder.HasZ);
                Assert.False(builder.HasM);
                Assert.False(builder.HasID);
                Assert.False(builder.IsEmpty);

                var pt = builder.ToGeometry();
                Assert.True(pt.HasZ);
                Assert.False(pt.HasM);
                Assert.False(pt.HasID);
                Assert.False(pt.IsEmpty);
            }

            MapPoint pt3;

            using (var builder = new MapPointBuilder(1.0, 2.0, 3.0, 4.0))
            {
                Assert.True(builder.HasZ);
                Assert.True(builder.HasM);
                Assert.False(builder.HasID);
                Assert.False(builder.IsEmpty);

                pt3 = builder.ToGeometry();
                Assert.True(pt3.HasZ);
                Assert.True(pt3.HasM);
                Assert.False(pt3.HasID);
                Assert.False(pt3.IsEmpty);
            }

            using (var builder = new MapPointBuilder(pt3))
            {
                var pt = builder.ToGeometry();
                Assert.True(pt3.IsEqual(pt));
                Assert.False(ReferenceEquals(pt3, pt));
            }
        }
Example #9
0
        public static MapPoint SetPointID(MapPoint template, int?pointID)
        {
            if (!pointID.HasValue)
            {
                return(template);                // nothing to update
            }

            using (var builder = new MapPointBuilder(template))
            {
                builder.HasID = true;
                builder.ID    = pointID.Value;
                builder.HasID = pointID.Value > 0;
                return(builder.ToGeometry());
            }
        }
        private void InsertAnnotation(AnnotationFeature annofeat)
        {
            var selectedFeatures = MapView.Active.Map.GetSelection().Where(kvp => kvp.Key is AnnotationLayer).ToDictionary(kvp => (AnnotationLayer)kvp.Key, kvp => kvp.Value);
            var layer            = selectedFeatures.Keys.FirstOrDefault();

            // コピーするアノテーション用に行を作成
            AnnotationFeatureClass annotationFeatureClass = layer.GetFeatureClass() as AnnotationFeatureClass;
            RowBuffer rowBuffer = annotationFeatureClass.CreateRowBuffer();
            Feature   feature   = annotationFeatureClass.CreateRow(rowBuffer) as Feature;

            // コピーするアノテーションを作成
            AnnotationFeature copyAnnoFeat = feature as AnnotationFeature;

            copyAnnoFeat.SetStatus(AnnotationStatus.Placed);
            copyAnnoFeat.SetAnnotationClassID(0);

            // コピー元のアノテーションの重心にポイントを作成
            Envelope shape           = annofeat.GetShape().Extent;
            var      x               = shape.Center.X;
            var      y               = shape.Center.Y;
            var      mapPointBuilder = new MapPointBuilder(layer.GetSpatialReference());

            mapPointBuilder.X = x;
            mapPointBuilder.Y = y;
            MapPoint mapPoint = mapPointBuilder.ToGeometry();

            // コピー元のアノテーションのテキストを作成
            var annoGraphich = annofeat.GetGraphic() as CIMTextGraphic;

            // 作成したポイントとアノテーションをコピー先のアノテーションにコピー
            CIMTextGraphic cimTextGraphic = new CIMTextGraphic();

            cimTextGraphic.Text  = annoGraphich.Text;
            cimTextGraphic.Shape = mapPoint;

            // シンボル設定
            var symbolRef = new CIMSymbolReference();

            symbolRef.SymbolName  = annoGraphich.Symbol.SymbolName;
            symbolRef.Symbol      = annoGraphich.Symbol.Symbol;
            cimTextGraphic.Symbol = symbolRef;

            // コピー
            copyAnnoFeat.SetGraphic(cimTextGraphic);
            copyAnnoFeat.Store();
        }
Example #11
0
        VectorArrowPoints(double beginPntX, double beginPntY, MapPoint endPnt)
        {
            double x     = beginPntX - endPnt.X;
            double y     = beginPntY - endPnt.Y;
            double angle = Math.Atan2(y, x);

            double alpha  = Math.PI / 6;                        // arrow is 30 degree by each side of original line
            double length = Math.Sqrt(x * x + y * y) * 0.25;    // arrow is a quarter of original length

            MapPointBuilder p1 = new MapPointBuilder(endPnt);
            MapPointBuilder p2 = new MapPointBuilder(endPnt);

            p1.X += length * Math.Cos(angle + alpha);
            p1.Y += length * Math.Sin(angle + alpha);
            p2.X += length * Math.Cos(angle - alpha);
            p2.Y += length * Math.Sin(angle - alpha);

            Esri.ArcGISRuntime.Geometry.PointCollection pc = new Esri.ArcGISRuntime.Geometry.PointCollection();
            pc.Add(p1.ToGeometry());
            pc.Add(endPnt);
            pc.Add(p2.ToGeometry());

            return(pc);
        }
Example #12
0
        private void MyMapView_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            myMapView.Cursor = Cursors.Arrow;//恢复光标样式
            if (curSelGraphic == null || orgPoint == null)
            {
                return;             //计算位移
            }
            IInputElement ie     = (IInputElement)(sender);
            MapPoint      loc    = myMapView.ScreenToLocation(e.GetPosition(ie));
            double        deltaX = loc.X - orgPoint.X;
            double        deltaY = loc.Y - orgPoint.Y;

            if (operation == OperateType.None)                                 //非绘制状态或顶点编辑状态
            {
                if (curSelGraphic.Geometry.GeometryType == GeometryType.Point) //当前选择的图形 为点,重新构造点
                {
                    MapPointBuilder pb = new MapPointBuilder(loc);
                    curSelGraphic.Geometry = pb.ToGeometry();
                }
                else if (curSelGraphic.Geometry.GeometryType == GeometryType.Polyline)//当前选 择的图形为线,重新计算所有点


                {
                    Esri.ArcGISRuntime.Geometry.Polyline ln = (Esri.ArcGISRuntime.Geometry.Polyline)curSelGraphic.Geometry; pointCollection.Clear();
                    for (int i = 0; i < ln.Parts[0].Points.Count; i++)
                    {
                        double   X = ln.Parts[0].Points[i].X + deltaX; double Y = ln.Parts[0].Points[i].Y + deltaY;
                        MapPoint Pt = new MapPoint(X, Y); pointCollection.Add(Pt);
                    }
                    PolylineBuilder lb = new PolylineBuilder(pointCollection);
                    curSelGraphic.Geometry = lb.ToGeometry();
                }
                else if (curSelGraphic.Geometry.GeometryType == GeometryType.Polygon)//当前选 择图形为多边形,重新计算所有点
                {
                    Esri.ArcGISRuntime.Geometry.Polygon poly = (Esri.ArcGISRuntime.Geometry.Polygon)curSelGraphic.Geometry;
                    pointCollection.Clear();
                    for (int i = 0; i < poly.Parts[0].Points.Count; i++)
                    {
                        double   X = poly.Parts[0].Points[i].X + deltaX; double Y = poly.Parts[0].Points[i].Y + deltaY;
                        MapPoint Pt = new MapPoint(X, Y); pointCollection.Add(Pt);
                    }
                    PolygonBuilder pb = new PolygonBuilder(pointCollection);
                    curSelGraphic.Geometry = pb.ToGeometry();
                }
            }
            else if (operation == OperateType.EditVertex)//处于顶点编辑状态
            {
                if (selGracphicIndex >= 0)
                {
                    Graphic g = graphicsLayer.Graphics.ElementAt(selGracphicIndex); //找到所选 图形
                    if (g.Geometry.GeometryType == GeometryType.Point)              //图形为点
                    {
                        MapPointBuilder mpb = new MapPointBuilder(loc);
                        g.Geometry = mpb.ToGeometry();
                    }
                    else if (g.Geometry.GeometryType == GeometryType.Polyline && selPointIndex >= 0)//图形为线,顶点已捕捉


                    {
                        Esri.ArcGISRuntime.Geometry.Polyline pln = (Esri.ArcGISRuntime.Geometry.Polyline)g.Geometry;
                        pointCollection.Clear(); pointCollection.AddPoints(pln.Parts[0].Points); pointCollection.SetPoint(selPointIndex, loc.X, loc.Y);
                        PolylineBuilder plb = new PolylineBuilder(pointCollection); g.Geometry = plb.ToGeometry();
                    }
                    else if (g.Geometry.GeometryType == GeometryType.Polygon && selPointIndex >= 0)//图形为多边形,顶点已捕捉
                    {
                        Esri.ArcGISRuntime.Geometry.Polygon plg = (Esri.ArcGISRuntime.Geometry.Polygon)g.Geometry; pointCollection.Clear();
                        pointCollection.AddPoints(plg.Parts[0].Points); pointCollection.SetPoint(selPointIndex, loc.X, loc.Y);
                        PolygonBuilder pgb = new PolygonBuilder(pointCollection); g.Geometry = pgb.ToGeometry();
                    }
                    if (selPointIndex >= 0)
                    {//移动相应的顶点到当前位置
                        Graphic         vtGraphic = selVertexLayer.Graphics.ElementAt(selPointIndex);
                        MapPointBuilder tgPoint   = new MapPointBuilder(loc); vtGraphic.Geometry = tgPoint.ToGeometry();
                    }
                }
            }
        }
Example #13
0
            VectorArrowPoints(double beginPntX, double beginPntY, MapPoint endPnt)
        {
            double x = beginPntX - endPnt.X;
            double y = beginPntY - endPnt.Y;
            double angle = Math.Atan2(y, x);

            double alpha = Math.PI / 6;                         // arrow is 30 degree by each side of original line
            double length = Math.Sqrt(x * x + y * y) * 0.25;      // arrow is a quarter of original length 

            MapPointBuilder p1 = new MapPointBuilder(endPnt);
            MapPointBuilder p2 = new MapPointBuilder(endPnt);
            p1.X += length * Math.Cos(angle + alpha);
            p1.Y += length * Math.Sin(angle + alpha);
            p2.X += length * Math.Cos(angle - alpha);
            p2.Y += length * Math.Sin(angle - alpha);

            Esri.ArcGISRuntime.Geometry.PointCollection pc = new Esri.ArcGISRuntime.Geometry.PointCollection();
            pc.Add(p1.ToGeometry());
            pc.Add(endPnt);
            pc.Add(p2.ToGeometry());

            return pc;
        }
Example #14
0
 public static MapPoint InterpolatePointOnLine(MapPoint p1, MapPoint p2, double scale)
 {
     MapPointBuilder p = new MapPointBuilder(p1.SpatialReference);
     double x = 0.0, y = 0.0;
     GeometryAlgorithms.InterpolatePointOnLine(p1.X, p1.Y, p2.X, p2.Y, scale, ref x, ref y);
     p.X = x;
     p.Y = y;
     return p.ToGeometry();
 }
Example #15
0
 public static MapPoint MidPoint(MapPoint p1, MapPoint p2)
 {
     MapPointBuilder p = new MapPointBuilder(p1.SpatialReference);
     p.X = (p1.X + p2.X) / 2.0;
     p.Y = (p1.Y + p2.Y) / 2.0;
     return p.ToGeometry();
 }
Example #16
0
        async private void   Image_MouseEnter(object sender, MouseEventArgs e)
        {
            Polygon polygon;


            var blackSolidLineSymbol = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.BlueRGB, 5, SimpleLineStyle.Solid);

            Geometry geometry = null;
            await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
            {
                SpatialReference inSR   = SpatialReferenceBuilder.CreateSpatialReference(32604);
                SpatialReference sr4326 = SpatialReferences.WGS84;
                SpatialReference sr3857 = SpatialReferences.WebMercator;
                ProjectionTransformation projTransFromSRs = ArcGIS.Core.Geometry.ProjectionTransformation.Create(inSR, sr3857);
                List <Coordinate2D> coordinates           = new List <Coordinate2D>()
                {
                    //new Coordinate2D(-159.20168702818188, 21.876487211082708),
                    //new Coordinate2D(-159.42653907783114, 21.838951660451173),
                    //new Coordinate2D(-159.44077880308507, 21.94718691051718),
                    //new Coordinate2D(-159.21630329750306, 21.94718691051718),
                    //new Coordinate2D(-159.21413990271841, 21.9365008022738),
                    //new Coordinate2D(-159.21383956606297, 21.93655454291286),
                    //new Coordinate2D(-159.20168702818188, 21.876487211082708),
                    new Coordinate2D(-17773406.8675, 2478583.7239999995),
                    new Coordinate2D(-17773406.8675, 2578583.7239999995),
                    new Coordinate2D(-16773406.8675, 2578583.7239999995),
                    new Coordinate2D(-17773406.8675, 2478583.7239999995)
                };
                //MapPoint point = new MapPointBuilder.FromGeoCoordinateString()
                //List<MapPoint> mapPoints = new List<MapPoint>();
                //foreach (Coordinate2D item in coordinates)
                //{
                //    MapPoint point = new MapPointBuilder()
                //}
                //mapPoints.Add( coordinates[0].ToMapPoint());
                MapPointBuilder asas = new MapPointBuilder(new Coordinate2D(-159.20168702818188, 21.876487211082708), MapView.Active.Extent.SpatialReference);
                _polygonSymbol       = SymbolFactory.Instance.ConstructPolygonSymbol(ColorFactory.Instance.BlackRGB, SimpleFillStyle.Null, SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.BlackRGB, 2.0, SimpleLineStyle.Solid));
                MapPoint point       = asas.ToGeometry();
                MapPoint point2      = MapPointBuilder.FromGeoCoordinateString(point.ToGeoCoordinateString(new ToGeoCoordinateParameter(GeoCoordinateType.DD)), MapView.Active.Extent.SpatialReference, GeoCoordinateType.DD);
                using (PolygonBuilder polygonBuilder = new PolygonBuilder(coordinates, inSR))
                {
                    polygonBuilder.SpatialReference = inSR;
                    polygon            = polygonBuilder.ToGeometry();
                    geometry           = polygonBuilder.ToGeometry();
                    Geometry geometry2 = GeometryEngine.Instance.ProjectEx(geometry, projTransFromSRs);
                    _graphic           = MapView.Active.AddOverlayAsync(geometry, _polygonSymbol.MakeSymbolReference());
                    //Application.Current.
                }
            });

            //await  QueuedTask.Run(() =>
            //{
            //    MapView.Active.UpdateOverlay(_graphic, point, SymbolFactory.Instance.ConstructPointSymbol(
            //                            ColorFactory.Instance.BlueRGB, 20.0, SimpleMarkerStyle.Circle).MakeSymbolReference());
            //});
            //_graphic = await this.AddOverlayAsync(geometry, _lineSymbol.MakeSymbolReference());
            Console.WriteLine(sender.ToString());
            //_graphic = MapView.Active.AddOverlay(geometry, _lineSymbol.MakeSymbolReference());


            //Geometry geometry = new PolygonBuilder.CreatePolygon(coordinates, inSR); ;
        }
        /// <summary>
        /// テキスト ボックスに格納される
        /// </summary>
        private void ManipulateGeometry(FeatureLayer manipulatedlayer)
        {
            QueuedTask.Run(() =>
            {
                var fileGDBpath = new FileGeodatabaseConnectionPath(new Uri(_gdbPath));
                using (Geodatabase geodatabase = new Geodatabase(fileGDBpath))
                {
                    // フィーチャクラスを取得する
                    using (FeatureClass featureClass = geodatabase.OpenDataset <FeatureClass>(_featureClassName))
                    {
                        using (var rowCursor = manipulatedlayer.Search(null))
                        {
                            var editOperation = new EditOperation();

                            if (manipulatedlayer.GetFeatureClass().GetDefinition().GetShapeType().ToString() == "Polygon")
                            {
                                while (rowCursor.MoveNext())
                                {
                                    using (var row = rowCursor.Current)
                                    {
                                        Feature feature = row as Feature;
                                        Geometry shape  = feature.GetShape();

                                        MapPoint mapPoint = GeometryEngine.Instance.Centroid(shape);

                                        //レイヤーのフィーチャクラスの Shape フィールドを取得
                                        string shapeField = featureClass.GetDefinition().GetShapeField();

                                        var attributes = new Dictionary <string, object>();
                                        attributes.Add(shapeField, mapPoint);

                                        //ジオメトリの属性値設定
                                        foreach (var fld in row.GetFields().Where(fld => fld.FieldType != FieldType.Geometry && fld.FieldType != FieldType.OID && fld.Name != "Shape_Length" && fld.Name != "Shape_Area"))
                                        {
                                            attributes.Add(fld.Name, row[fld.Name]);
                                        }

                                        //フィーチャの作成と編集実行
                                        editOperation.Create(featureClass, attributes);
                                    }
                                }
                            }
                            else if (manipulatedlayer.GetFeatureClass().GetDefinition().GetShapeType().ToString() == "Polyline")
                            {
                                while (rowCursor.MoveNext())
                                {
                                    using (var row = rowCursor.Current)
                                    {
                                        Feature feature             = row as Feature;
                                        Polyline polyline           = feature.GetShape() as Polyline;
                                        ReadOnlyPointCollection pts = polyline.Points;

                                        var mapPointBuilder    = new MapPointBuilder(manipulatedlayer.GetSpatialReference());
                                        mapPointBuilder.X      = pts.First().X;
                                        mapPointBuilder.Y      = pts.First().Y;
                                        MapPoint firstMapPoint = mapPointBuilder.ToGeometry();

                                        mapPointBuilder.X     = pts.Last().X;
                                        mapPointBuilder.Y     = pts.Last().Y;
                                        MapPoint lastMapPoint = mapPointBuilder.ToGeometry();

                                        //レイヤーのフィーチャクラスの Shape フィールドを取得
                                        string shapeField = featureClass.GetDefinition().GetShapeField();

                                        var firstAttributes = new Dictionary <string, object>();
                                        firstAttributes.Add(shapeField, firstMapPoint);

                                        var lastAttributes = new Dictionary <string, object>();
                                        lastAttributes.Add(shapeField, lastMapPoint);

                                        //ジオメトリの属性値設定
                                        foreach (var fld in row.GetFields().Where(fld => fld.FieldType != FieldType.Geometry && fld.FieldType != FieldType.OID && fld.Name != "Shape_Length" && fld.Name != "Shape_Area"))
                                        {
                                            firstAttributes.Add(fld.Name, row[fld.Name]);
                                            lastAttributes.Add(fld.Name, row[fld.Name]);
                                        }

                                        editOperation.Create(featureClass, firstAttributes);
                                        editOperation.Create(featureClass, lastAttributes);
                                    }
                                }
                            }

                            editOperation.Execute();
                        }
                    }
                }
            });
        }
        /// <summary>
        /// Execute the layout on the Diagram
        /// </summary>
        /// <param name="diagram"></param>
        internal void Execute(NetworkDiagram diagram)
        {
            _graphModel.Initialize(diagram);

            var junctions = _graphModel.Junctions;

            if (!junctions.Any())
            {
                return;
            }

            int maxColorCount = 12;

            var containerIDs = new HashSet <int>();

            UtilityNetwork un = diagram.DiagramManager?.GetNetwork <UtilityNetwork>();

            IReadOnlyList <NetworkSource> theSources = un.GetDefinition().GetNetworkSources();

            if (!_graphModel.Containers.Any() || !_graphModel.Edges.Any())
            {
                return;
            }

            Dictionary <int, Dictionary <int, Dictionary <string, string> > > attributesBySourceID = new Dictionary <int, Dictionary <int, Dictionary <string, string> > >();

            foreach (var jsonContainer in _graphModel.Containers)
            {
                int sourceID = jsonContainer.Element.AssociatedSourceID;
                if (sourceID != 9) // Communications Device source ID
                {
                    continue;
                }

                if (!attributesBySourceID.TryGetValue(sourceID, out Dictionary <int, Dictionary <string, string> > AttributesByEID))
                {
                    AttributesByEID = FillSources(Diagram: diagram, theSources: theSources, SourceID: sourceID);
                    attributesBySourceID.Add(sourceID, AttributesByEID);
                }

                if (AttributesByEID.TryGetValue(jsonContainer.ID, out Dictionary <string, string> IdProperties))
                {
                    jsonContainer.AssetGroup = IdProperties["Asset group"];
                    jsonContainer.AssetType  = IdProperties["Asset type"];
                }
            }

            foreach (var jsonEdge in _graphModel.Edges)
            {
                int sourceID = jsonEdge.Element.AssociatedSourceID;
                if (sourceID != 15) // Communications Edge Object source ID
                {
                    continue;
                }

                if (!attributesBySourceID.TryGetValue(sourceID, out Dictionary <int, Dictionary <string, string> > AttributesByEID))
                {
                    AttributesByEID = FillSources(Diagram: diagram, theSources: theSources, SourceID: sourceID, IsEdge: true);
                    attributesBySourceID.Add(sourceID, AttributesByEID);
                }

                if (AttributesByEID.TryGetValue(jsonEdge.ID, out Dictionary <string, string> IdProperties))
                {
                    string assetGroup = IdProperties["Asset group"];
                    string assetType  = IdProperties["Asset type"];

                    if (assetGroup != "Strand" || assetType != "Fiber")
                    {
                        continue;
                    }

                    string groupColor = IdProperties["Strand Group Color"].ToString();
                    string color      = IdProperties["Strand Color"].ToString();

                    int groupColorRank = GetColorRank(groupColor);
                    int colorRank      = GetColorRank(color);

                    if (groupColorRank < 0 || colorRank < 0)
                    {
                        continue;
                    }

                    int rank = maxColorCount * groupColorRank + colorRank;

                    int fromID = jsonEdge.Element.FromID;
                    int toID   = jsonEdge.Element.ToID;

                    int fromContainerID = 0;
                    int toContainerID   = 0;

                    var fromJunction = _graphModel.GetJunction(fromID);
                    fromJunction.Rank = rank;
                    fromContainerID   = fromJunction.Element.ContainerID;
                    if (fromContainerID > 0)
                    {
                        containerIDs.Add(fromContainerID);
                    }

                    var toJunction = _graphModel.GetJunction(toID);
                    toJunction.Rank = rank;
                    toContainerID   = toJunction.Element.ContainerID;
                    if (toContainerID > 0)
                    {
                        containerIDs.Add(toContainerID);
                    }

                    if (fromContainerID > 0 && toContainerID > 0)
                    {
                        var fromContainer = _graphModel.GetContainer(fromContainerID);
                        fromContainer.ToContainers.Add(toContainerID);
                        fromContainer.HasOutputFibers = true;

                        var toContainer = _graphModel.GetContainer(toContainerID);
                        toContainer.FromContainers.Add(fromContainerID);
                        toContainer.HasInputFibers = true;
                        if (fromJunction.Rank < toContainer.FromJunctionRankMin)
                        {
                            toContainer.FromJunctionRankMin = fromJunction.Rank;
                        }
                    }
                }
            }

            attributesBySourceID = null;

            foreach (var junction in junctions)
            {
                if (junction.Element.ContainerID < 1)
                {
                    continue;
                }

                if (junction.Rank >= 0)
                {
                    continue;
                }

                _graphModel.GetConnectedJunctions(junction.Element.ID, out IList <int> connectedJunctions);

                int             fromRank      = -1;
                int             toRank        = -1;
                CustomContainer fromContainer = null;
                CustomContainer toContainer   = null;

                int count = Math.Min(connectedJunctions.Count, 2);
                for (int i = 0; i < count; i++)
                {
                    var connectedJunction = _graphModel.GetJunction(connectedJunctions[i]);
                    var container         = _graphModel.GetContainer(connectedJunction.Element.ContainerID);
                    if (container.HasInputFibers)
                    {
                        fromRank      = connectedJunction.Rank;
                        fromContainer = container;
                    }
                    else if (container.HasOutputFibers)
                    {
                        toRank      = connectedJunction.Rank;
                        toContainer = container;
                    }
                }

                if (fromRank >= 0 || toRank >= 0)
                {
                    junction.Rank = fromRank >= 0 ? fromRank : toRank;

                    var container = _graphModel.GetContainer(junction.Element.ContainerID);
                    containerIDs.Add(container.Element.ID);

                    if (fromContainer != null)
                    {
                        container.FromContainers.Add(fromContainer.Element.ID);
                        fromContainer.ToContainers.Add(container.Element.ID);
                    }

                    if (toContainer != null)
                    {
                        container.ToContainers.Add(toContainer.Element.ID);
                        toContainer.FromContainers.Add(container.Element.ID);
                        if (junction.Rank < toContainer.FromJunctionRankMin)
                        {
                            toContainer.FromJunctionRankMin = junction.Rank;
                        }
                    }
                }
            }

            var    diagramInfo   = diagram.GetDiagramInfo();
            var    diagramExtent = diagramInfo.DiagramExtent;
            double ySpacing      = diagramInfo.ContainerMargin;
            double xSpacingMin   = diagramInfo.ContainerMargin * 15;

            var startContainers = new List <CustomContainer>();

            foreach (var containerID in containerIDs)
            {
                var container = _graphModel.GetContainer(containerID);
                if (!(container is null) && (container.FromContainers.Count > 0 || container.ToContainers.Count < 1))
                {
                    continue;
                }

                if (container.Element is null)
                {
                    continue;
                }

                var parent = _graphModel.GetContainer(container.Element.ContainerID);
                if (parent == null)
                {
                    continue;
                }

                if (parent.AssetType != "Hub Terminator" && parent.AssetType != "Mid Cable Splice Enclosure")
                {
                    continue;
                }

                startContainers.Add(container);
            }

            double startY = diagramExtent.YMax;

            foreach (var startContainer in startContainers)
            {
                if (startContainer.FromContainerOrder != Int32.MaxValue)
                {
                    continue;
                }

                var toContainerIDs = new HashSet <int>();
                foreach (var toContainerID in startContainer.ToContainers)
                {
                    toContainerIDs.Add(toContainerID);
                }

                double startX = diagramExtent.XMin;

                startContainer.X = startX;
                startContainer.Y = startY;

                while (toContainerIDs.Count > 0)
                {
                    double y     = startY;
                    bool   first = true;

                    var toContainers = new List <CustomContainer>();
                    foreach (var containerID in toContainerIDs)
                    {
                        var toContainer = _graphModel.GetContainer(containerID);
                        if (startContainer.FromContainerOrder == Int32.MaxValue)
                        {
                            toContainers.Add(toContainer);
                        }
                    }

                    var sortedContainers = toContainers.OrderBy(cntr => cntr.FromContainerOrder + 0.001 * cntr.FromJunctionRankMin);

                    int vertivalOrder = 0;
                    foreach (var container in sortedContainers)
                    {
                        int containerID = container.Element.ID;

                        container.Y = y;

                        y -= (_graphModel.GetContainedElements(containerID).Count() * ySpacing + 7 * diagramInfo.ContainerMargin);

                        if (first)
                        {
                            first       = false;
                            container.X = startX + xSpacingMin;
                            startX      = container.X;
                        }
                        else
                        {
                            container.X = startX;
                        }

                        foreach (var toContainerID in container.ToContainers)
                        {
                            var toContainer = _graphModel.GetContainer(toContainerID);
                            if (toContainer.FromContainerOrder == Int32.MaxValue)
                            {
                                toContainer.FromContainerOrder = vertivalOrder;
                                toContainerIDs.Add(toContainerID);
                            }
                        }

                        vertivalOrder++;

                        toContainerIDs.Remove(containerID);
                    }
                }

                startY -= (_graphModel.GetContainedElements(startContainer.Element.ID).Count() * ySpacing + 4 * diagramInfo.ContainerMargin);
            }

            IList <DiagramJunctionElement> junctionsToSave = new List <DiagramJunctionElement>();

            SpatialReference spatialRef      = diagramInfo.DiagramExtent.SpatialReference;
            MapPointBuilder  mapPointBuilder = new MapPointBuilder(spatialRef)
            {
                Z = 0
            };

            foreach (var containerID in containerIDs)
            {
                var container = _graphModel.GetContainer(containerID);
                if (container == null)
                {
                    continue;
                }

                int rankCount = maxColorCount * maxColorCount;

                BitArray isEmpty = new BitArray(rankCount, true);

                double yTop = container.Y;

                var containedJunctions   = _graphModel.GetContainedElements(containerID);
                var unconnectedJunctions = new Stack <int>();

                foreach (var junctionID in containedJunctions)
                {
                    var junction = _graphModel.GetJunction(junctionID);
                    if (junction == null)
                    {
                        continue;
                    }

                    if (junction.Rank < 0)
                    {
                        unconnectedJunctions.Push(junction.Element.ID);
                        continue;
                    }

                    isEmpty[junction.Rank] = false;

                    mapPointBuilder.X      = container.X;
                    mapPointBuilder.Y      = yTop - junction.Rank * ySpacing;
                    junction.Element.Shape = mapPointBuilder.ToGeometry();

                    junctionsToSave.Add(junction.Element);
                }

                int rank = 0;
                while (unconnectedJunctions.Count > 0 && rank < rankCount)
                {
                    if (isEmpty[rank])
                    {
                        var junction = _graphModel.GetJunction(unconnectedJunctions.Pop());
                        if (junction != null)
                        {
                            mapPointBuilder.X      = container.X;
                            mapPointBuilder.Y      = yTop - rank * ySpacing;
                            junction.Element.Shape = mapPointBuilder.ToGeometry();
                            junctionsToSave.Add(junction.Element);
                        }
                    }
                    rank++;
                }
            }

            if (junctionsToSave.Count > 0)
            {
                NetworkDiagramSubset nds = new NetworkDiagramSubset
                {
                    DiagramJunctionElements = junctionsToSave
                };

                diagram.SaveLayout(nds, true);
            }
        }
Example #19
0
        public void EditOperations()
        {
            var featureLayer = MapView.Active.Map.GetLayersAsFlattenedList()[0] as FeatureLayer;
            var polygon      = new PolygonBuilder().ToGeometry();
            var clipPoly     = new PolygonBuilder().ToGeometry();
            var cutLine      = new PolylineBuilder().ToGeometry();
            var modifyLine   = cutLine;
            var oid          = 1;

            #region Edit Operation Create Features

            var createFeatures = new EditOperation();
            createFeatures.Name = "Create Features";
            //Create a feature with a polygon
            createFeatures.Create(featureLayer, polygon);

            //with a callback
            createFeatures.Create(featureLayer, polygon, (object_id) => {
                //TODO - use the oid of the created feature
                //in your callback
            });

            //Do a create features and set attributes
            var attributes = new Dictionary <string, object>();
            attributes.Add("SHAPE", polygon);
            attributes.Add("NAME", "Corner Market");
            attributes.Add("SIZE", 1200.5);
            attributes.Add("DESCRIPTION", "Corner Market");

            createFeatures.Create(featureLayer, attributes);

            //Create features using the current template
            //Must be within a MapTool
            createFeatures.Create(this.CurrentTemplate, polygon);

            //Execute to execute the operation
            //Must be called within QueuedTask.Run
            createFeatures.Execute();

            //or use async flavor
            //await createFeatures.ExecuteAsync();

            #endregion

            #region Edit Operation Clip Features

            var clipFeatures = new EditOperation();
            clipFeatures.Name = "Clip Features";
            clipFeatures.Clip(featureLayer, oid, clipPoly, ClipMode.PreserveArea);
            //Execute to execute the operation
            //Must be called within QueuedTask.Run
            clipFeatures.Execute();

            //or use async flavor
            //await clipFeatures.ExecuteAsync();

            #endregion

            #region Edit Operation Cut Features

            var select = MapView.Active.SelectFeatures(clipPoly);

            var cutFeatures = new EditOperation();
            cutFeatures.Name = "Cut Features";
            cutFeatures.Cut(featureLayer, oid, cutLine);

            //Cut all the selected features in the active view
            //Select using a polygon (for example)
            var kvps = MapView.Active.SelectFeatures(polygon).Select(
                k => new KeyValuePair <MapMember, List <long> >(k.Key as MapMember, k.Value));
            cutFeatures.Cut(kvps, cutLine);

            //Execute to execute the operation
            //Must be called within QueuedTask.Run
            cutFeatures.Execute();

            //or use async flavor
            //await cutFeatures.ExecuteAsync();

            #endregion

            #region Edit Operation Delete Features

            var deleteFeatures = new EditOperation();
            deleteFeatures.Name = "Delete Features";
            var table = MapView.Active.Map.StandaloneTables[0];
            //Delete a row in a standalone table
            deleteFeatures.Delete(table, oid);

            //Delete all the selected features in the active view
            //Select using a polygon (for example)
            var selection = MapView.Active.SelectFeatures(polygon).Select(
                k => new KeyValuePair <MapMember, List <long> >(k.Key as MapMember, k.Value));

            deleteFeatures.Delete(selection);

            //Execute to execute the operation
            //Must be called within QueuedTask.Run
            deleteFeatures.Execute();

            //or use async flavor
            //await deleteFeatures.ExecuteAsync();

            #endregion

            #region Edit Operation Duplicate Features

            var duplicateFeatures = new EditOperation();
            duplicateFeatures.Name = "Duplicate Features";

            //Duplicate with an X and Y offset of 500 map units
            duplicateFeatures.Duplicate(featureLayer, oid, 500.0, 500.0, 0.0);

            //Execute to execute the operation
            //Must be called within QueuedTask.Run
            duplicateFeatures.Execute();

            //or use async flavor
            //await duplicateFeatures.ExecuteAsync();

            #endregion

            #region Edit Operation Explode Features

            var explodeFeatures = new EditOperation();
            explodeFeatures.Name = "Explode Features";

            //Take a multipart and convert it into one feature per part
            //Provide a list of ids to convert multiple
            explodeFeatures.Explode(featureLayer, new List <long>()
            {
                oid
            }, true);

            //Execute to execute the operation
            //Must be called within QueuedTask.Run
            explodeFeatures.Execute();

            //or use async flavor
            //await explodeFeatures.ExecuteAsync();

            #endregion

            var destinationLayer = featureLayer;

            #region Edit Operation Merge Features

            var mergeFeatures = new EditOperation();
            mergeFeatures.Name = "Merge Features";

            //Merge three features into a new feature using defaults
            //defined in the current template
            mergeFeatures.Merge(this.CurrentTemplate as EditingFeatureTemplate, featureLayer, new List <long>()
            {
                10, 96, 12
            });

            //Merge three features into a new feature in the destination layer
            mergeFeatures.Merge(destinationLayer, featureLayer, new List <long>()
            {
                10, 96, 12
            });

            //Use an inspector to set the new attributes of the merged feature
            var inspector = new Inspector();
            inspector.Load(featureLayer, oid);//base attributes on an existing feature
            //change attributes for the new feature
            inspector["NAME"]        = "New name";
            inspector["DESCRIPTION"] = "New description";

            //Merge features into a new feature in the same layer using the
            //defaults set in the inspector
            mergeFeatures.Merge(featureLayer, new List <long>()
            {
                10, 96, 12
            }, inspector);

            //Execute to execute the operation
            //Must be called within QueuedTask.Run
            mergeFeatures.Execute();

            //or use async flavor
            //await mergeFeatures.ExecuteAsync();

            #endregion

            #region Edit Operation Modify single feature

            var modifyFeature = new EditOperation();
            modifyFeature.Name = "Modify a feature";

            //use an inspector
            var modifyInspector = new Inspector();
            modifyInspector.Load(featureLayer, oid);//base attributes on an existing feature

            //change attributes for the new feature
            modifyInspector["SHAPE"] = polygon;        //Update the geometry
            modifyInspector["NAME"]  = "Updated name"; //Update attribute(s)

            modifyFeature.Modify(modifyInspector);

            //update geometry and attributes using overload
            var featureAttributes = new Dictionary <string, object>();
            featureAttributes["NAME"] = "Updated name";//Update attribute(s)
            modifyFeature.Modify(featureLayer, oid, polygon, featureAttributes);

            //Execute to execute the operation
            //Must be called within QueuedTask.Run
            modifyFeature.Execute();

            //or use async flavor
            //await modifyFeatures.ExecuteAsync();

            #endregion

            #region Edit Operation Modify multiple features

            //Search by attribute
            var queryFilter = new QueryFilter();
            queryFilter.WhereClause = "OBJECTID < 1000000";
            //Create list of oids to update
            var oidSet = new List <long>();
            using (var rc = featureLayer.Search(queryFilter))
            {
                while (rc.MoveNext())
                {
                    oidSet.Add(rc.Current.GetObjectID());
                }
            }

            //create and execute the edit operation
            var modifyFeatures = new EditOperation();
            modifyFeatures.Name           = "Modify features";
            modifyFeatures.ShowProgressor = true;

            var insp = new Inspector();
            insp.Load(featureLayer, oidSet);
            insp["MOMC"] = 24;
            modifyFeatures.Modify(insp);
            modifyFeatures.ExecuteAsync();
            #endregion

            #region Move features

            //Get all of the selected ObjectIDs from the layer.
            var firstLayer       = MapView.Active.Map.GetLayersAsFlattenedList().OfType <FeatureLayer>().FirstOrDefault();
            var selectionfromMap = firstLayer.GetSelection();

            // set up a dictionary to store the layer and the object IDs of the selected features
            var selectionDictionary = new Dictionary <MapMember, List <long> >();
            selectionDictionary.Add(firstLayer as MapMember, selectionfromMap.GetObjectIDs().ToList());

            var moveFeature = new EditOperation();
            moveFeature.Name = "Move features";
            moveFeature.Move(selectionDictionary, 10, 10); //specify your units along axis to move the geometry

            moveFeature.Execute();
            #endregion

            #region Move feature to a specific coordinate

            //Get all of the selected ObjectIDs from the layer.
            var abLayer     = MapView.Active.Map.GetLayersAsFlattenedList().OfType <FeatureLayer>().FirstOrDefault();
            var mySelection = abLayer.GetSelection();
            var selOid      = mySelection.GetObjectIDs().FirstOrDefault();

            var moveToPoint = new MapPointBuilder(1.0, 2.0, 3.0, 4.0, MapView.Active.Map.SpatialReference); //can pass in coordinates.

            var modifyFeatureCoord = new EditOperation();
            modifyFeatureCoord.Name = "Move features";
            modifyFeatureCoord.Modify(abLayer, selOid, moveToPoint.ToGeometry()); //Modify the feature to the new geometry
            modifyFeatureCoord.Execute();

            #endregion

            #region Edit Operation Planarize Features

            var planarizeFeatures = new EditOperation();
            planarizeFeatures.Name = "Planarize Features";

            //Planarize one or more features
            planarizeFeatures.Planarize(featureLayer, new List <long>()
            {
                oid
            });

            //Execute to execute the operation
            //Must be called within QueuedTask.Run
            planarizeFeatures.Execute();

            //or use async flavor
            //await planarizeFeatures.ExecuteAsync();

            #endregion

            #region Edit Operation Reshape Features

            var reshapeFeatures = new EditOperation();
            reshapeFeatures.Name = "Reshape Features";

            reshapeFeatures.Reshape(featureLayer, oid, modifyLine);

            //Reshape a set of features that intersect some geometry....
            var selFeatures = MapView.Active.GetFeatures(modifyLine).Select(
                k => new KeyValuePair <MapMember, List <long> >(k.Key as MapMember, k.Value));

            reshapeFeatures.Reshape(selFeatures, modifyLine);

            //Execute to execute the operation
            //Must be called within QueuedTask.Run
            reshapeFeatures.Execute();

            //or use async flavor
            //await reshapeFeatures.ExecuteAsync();

            #endregion

            var origin = MapPointBuilder.CreateMapPoint(0, 0, null);

            #region Edit Operation Rotate Features

            var rotateFeatures = new EditOperation();
            rotateFeatures.Name = "Rotate Features";

            //Rotate works on a selected set of features
            //Get all features that intersect a polygon
            var rotateSelection = MapView.Active.GetFeatures(polygon).Select(
                k => new KeyValuePair <MapMember, List <long> >(k.Key as MapMember, k.Value));

            //Rotate selected features 90 deg about "origin"
            rotateFeatures.Rotate(rotateSelection, origin, Math.PI / 2);

            //Execute to execute the operation
            //Must be called within QueuedTask.Run
            rotateFeatures.Execute();

            //or use async flavor
            //await rotateFeatures.ExecuteAsync();

            #endregion

            #region Edit Operation Scale Features

            var scaleFeatures = new EditOperation();
            scaleFeatures.Name = "Scale Features";

            //Rotate works on a selected set of features
            var scaleSelection = MapView.Active.GetFeatures(polygon).Select(
                k => new KeyValuePair <MapMember, List <long> >(k.Key as MapMember, k.Value));

            //Scale the selected features by 2.0 in the X and Y direction
            scaleFeatures.Scale(scaleSelection, origin, 2.0, 2.0, 0.0);

            //Execute to execute the operation
            //Must be called within QueuedTask.Run
            scaleFeatures.Execute();

            //or use async flavor
            //await scaleFeatures.ExecuteAsync();

            #endregion

            var mp1 = MapPointBuilder.CreateMapPoint(0, 0, null);
            var mp2 = mp1;
            var mp3 = mp1;

            #region Edit Operation Split Features

            var splitFeatures = new EditOperation();
            splitFeatures.Name = "Split Features";

            var splitPoints = new List <MapPoint>()
            {
                mp1, mp2, mp3
            };

            //Split the feature at 3 points
            splitFeatures.Split(featureLayer, oid, splitPoints);

            // split using percentage
            var splitByPercentage = new SplitByPercentage()
            {
                Percentage = 33, SplitFromStartPoint = true
            };
            splitFeatures.Split(featureLayer, oid, splitByPercentage);

            // split using equal parts
            var splitByEqualParts = new SplitByEqualParts()
            {
                NumParts = 3
            };
            splitFeatures.Split(featureLayer, oid, splitByEqualParts);

            // split using single distance
            var splitByDistance = new SplitByDistance()
            {
                Distance = 27.3, SplitFromStartPoint = false
            };
            splitFeatures.Split(featureLayer, oid, splitByDistance);

            // split using varying distance
            var distances = new List <double>()
            {
                12.5, 38.2, 89.99
            };
            var splitByVaryingDistance = new SplitByVaryingDistance()
            {
                Distances = distances, SplitFromStartPoint = true, ProportionRemainder = true
            };
            splitFeatures.Split(featureLayer, oid, splitByVaryingDistance);

            //Execute to execute the operation
            //Must be called within QueuedTask.Run
            splitFeatures.Execute();

            //or use async flavor
            //await splitAtPointsFeatures.ExecuteAsync();

            #endregion

            var linkLayer = featureLayer;

            #region Edit Operation Transform Features

            var transformFeatures = new EditOperation();
            transformFeatures.Name = "Transform Features";

            //Transform a selected set of features
            var transformSelection = MapView.Active.GetFeatures(polygon).Select(
                k => new KeyValuePair <MapMember, List <long> >(k.Key as MapMember, k.Value));

            transformFeatures.Transform(transformSelection, linkLayer);

            //Transform just a layer
            transformFeatures.Transform(featureLayer, linkLayer);

            //Perform an affine transformation
            transformFeatures.TransformAffine(featureLayer, linkLayer);

            //Execute to execute the operation
            //Must be called within QueuedTask.Run
            transformFeatures.Execute();

            //or use async flavor
            //await transformFeatures.ExecuteAsync();

            #endregion

            #region Edit Operation Perform a Clip, Cut, and Planarize

            //Multiple operations can be performed by a single
            //edit operation.
            var clipCutPlanarizeFeatures = new EditOperation();
            clipCutPlanarizeFeatures.Name = "Clip, Cut, and Planarize Features";
            clipCutPlanarizeFeatures.Clip(featureLayer, oid, clipPoly);
            clipCutPlanarizeFeatures.Cut(featureLayer, oid, cutLine);
            clipCutPlanarizeFeatures.Planarize(featureLayer, new List <long>()
            {
                oid
            });

            //Note: An edit operation is a single transaction.
            //Execute the operations (in the order they were declared)
            clipCutPlanarizeFeatures.Execute();

            //or use async flavor
            //await clipCutPlanarizeFeatures.ExecuteAsync();

            #endregion

            #region Edit Operation Chain Edit Operations

            //Chaining operations is a special case. Use "Chained Operations" when you require multiple transactions
            //to be undo-able with a single "Undo".

            //The most common use case for operation chaining is creating a feature with an attachement.
            //Adding an attachment requires the object id (of a new feature) has already been created.
            var editOperation1 = new EditOperation();
            editOperation1.Name = string.Format("Create point in '{0}'", CurrentTemplate.Layer.Name);

            long newFeatureID = -1;
            //The Create operation has to execute so we can get an object_id
            editOperation1.Create(this.CurrentTemplate, polygon, (object_id) => newFeatureID = object_id);
            //Must be within a QueuedTask
            editOperation1.Execute();

            //or use async flavor
            //await editOperation1.ExecuteAsync();

            //Now, because we have the object id, we can add the attachment.  As we are chaining it, adding the attachment
            //can be undone as part of the "Undo Create" operation. In other words, only one undo operation will show on the
            //Pro UI and not two.
            var editOperation2 = editOperation1.CreateChainedOperation();
            //Add the attachement using the new feature id
            editOperation2.AddAttachment(this.CurrentTemplate.Layer, newFeatureID, @"C:\data\images\Hydrant.jpg");

            //editOperation1 and editOperation2 show up as a single Undo operation on the UI even though
            //we had two transactions
            //Must be within a QueuedTask
            editOperation2.Execute();

            //or use async flavor
            //await editOperation2.ExecuteAsync();

            #endregion

            #region SetOnUndone, SetOnRedone, SetOnComitted

            // SetOnUndone, SetOnRedone and SetOnComittedManage can be used to manage
            // external actions(such as writing to a log table) that are associated with
            // each edit operation.

            //get selected feature and update attribute
            var selectedFeatures = MapView.Active.Map.GetSelection();
            var testInspector    = new Inspector();
            testInspector.Load(selectedFeatures.Keys.First(), selectedFeatures.Values.First());
            testInspector["Name"] = "test";

            //create and execute the edit operation
            var updateTestField = new EditOperation();
            updateTestField.Name = "Update test field";
            updateTestField.Modify(insp);

            //actions for SetOn...
            updateTestField.SetOnUndone(() =>
            {
                //Sets an action that will be called when this operation is undone.
                Debug.WriteLine("Operation is undone");
            });

            updateTestField.SetOnRedone(() =>
            {
                //Sets an action that will be called when this editoperation is redone.
                Debug.WriteLine("Operation is redone");
            });

            updateTestField.SetOnComitted((bool b) => //called on edit session save(true)/discard(false).
            {
                // Sets an action that will be called when this editoperation is committed.
                Debug.WriteLine("Operation is committed");
            });

            updateTestField.Execute();

            #endregion
        }
        private async void SyncViews(MapView mapView)
        {
            // Get Altitude *Google Earth Range
            MapPoint lowerLeftPoint  = null;
            MapPoint upperRightPoint = null;

            await QueuedTask.Run(() =>
            {
                lowerLeftPoint  = MapPointBuilder.CreateMapPoint(mapView.Extent.XMin, mapView.Extent.YMin, mapView.Extent.SpatialReference);
                upperRightPoint = MapPointBuilder.CreateMapPoint(mapView.Extent.XMax, mapView.Extent.YMax, mapView.Extent.SpatialReference);
            });

            double latXmin, latXmax, longYmin, longYmax, diagonal;

            Tuple <double, double> tupleResult = null;

            tupleResult = await PointToLatLong(lowerLeftPoint);

            longYmin = tupleResult.Item1;
            latXmin  = tupleResult.Item2;

            tupleResult = await PointToLatLong(upperRightPoint);

            longYmax = tupleResult.Item1;
            latXmax  = tupleResult.Item2;

            diagonal = Math.Round(DistanceBetweenPoints(latXmin, longYmin, latXmax, longYmax, 'K') * 1000, 2); // 1km * 1000m

            double altitude = diagonal * Math.Sqrt(3) * 0.5;

            _altitude = altitude.ToString();



            // Longitude, Latitude
            MapPoint point = null;

            await QueuedTask.Run(() =>
            {
                Coordinate2D coordinate = new Coordinate2D(mapView.Camera.X, mapView.Camera.Y);
                //Coordinate coordinate = new Coordinate(((map.Extent.XMax + map.Extent.XMin) / 2), ((map.Extent.YMax + map.Extent.YMin) / 2));
                MapPointBuilder pointBuilder = new MapPointBuilder(coordinate, mapView.Extent.SpatialReference);
                point = pointBuilder.ToGeometry();
            });

            double latitude;
            double longitude;

            var result = await PointToLatLong(point);

            longitude = result.Item1;
            latitude  = result.Item2;

            _latitude  = Convert.ToString(Math.Round(latitude, 5));
            _longitude = Convert.ToString(Math.Round(longitude, 5));

            // Altitude
            // Arcmap Heading 0, 90, 180, -90:       Point of Reference is the Camera
            // Google Earth Heading 0, 90, 180, 270: Point of Reference is the Bearing
            double heading = mapView.Camera.Heading;

            heading  = 360 - (heading < 0 ? (heading + 360) : heading); // Flip Point of Reference - Flip to 360
            _heading = heading.ToString();


            // Tilt
            double tilt = (mapView.Camera.Pitch + 90); // Convert To Google Earth Formatting

            _tilt = tilt.ToString();


            WriteCurrentView();
        }