Skip to content

ProSnippets Geometry

arcgisprosdk edited this page Jan 12, 2017 · 23 revisions
Language:              C#  
Subject:               Geometry  
Contributor:           ArcGIS Pro SDK Team <[email protected]>  
Organization:          Esri, http://www.esri.com  
Date:                  1/5/2017  
ArcGIS Pro:            1.4  
Visual Studio:         2013, 2015  
.NET Target Framework: 4.6.1  

##Construct a SpatialReference - from a Well Known ID

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // use the builder constructor
  SpatialReferenceBuilder srBuilder = new SpatialReferenceBuilder(3857);
  SpatialReference sr3857 = srBuilder.ToSpatialReference();

  // or use the convenience method
  SpatialReference sr_3857 = SpatialReferenceBuilder.CreateSpatialReference(3857);
});

##Construct a SpatialReference - from a string

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  string wkt = "GEOGCS[\"MyGCS84\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Radian\",1.0]]";

  // use the builder constructor
  SpatialReferenceBuilder builder = new SpatialReferenceBuilder(wkt);
  SpatialReference sr = builder.ToSpatialReference();

  // or use the convenience method
  SpatialReference anotherSR = SpatialReferenceBuilder.CreateSpatialReference(wkt);
});

##Use WGS84 SpatialReference

SpatialReference wgs84 = SpatialReferences.WGS84;
bool isProjected = wgs84.IsProjected;     // false
bool isGeographic = wgs84.IsGeographic;   // true

##Construct a SpatialReference with a vertical coordinate system - from Well Known IDs

// see a list of vertical coordinate systems at http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#/Vertical_coordinate_systems/02r3000000rn000000/

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // use the builder constructor
  // 4326 = GCS_WGS_1984
  // 115700 = vertical WGS_1984
  SpatialReferenceBuilder sb = new SpatialReferenceBuilder(4326, 115700);
  SpatialReference sr = sb.ToSpatialReference();

  // or use the convenience method
  SpatialReference sr_4326 = SpatialReferenceBuilder.CreateSpatialReference(4326, 115700);
});

// test creation with wkid, vwkid

##Construct a SpatialReference with a verical coordinate system - from a string

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // custom VCS - use vertical shift of -1.23 instead of 0
  string custom_vWkt = @"VERTCS[""SHD_height"",VDATUM[""Singapore_Height_Datum""],PARAMETER[""Vertical_Shift"",-1.23],PARAMETER[""Direction"",-1.0],UNIT[""Meter"",1.0]]";

  SpatialReferenceBuilder sb = new SpatialReferenceBuilder(4326, custom_vWkt);
  SpatialReference sr = sb.ToSpatialReference();

  int wkid = sr.Wkid;             // wkid = 4326
  int vert_wkid = sr.VcsWkid;     // vert_wkid = 0
  string vert_wkt = sr.VcsWkt;    // vert_wkt = custom_vWkt

  // or use the convenience method
  SpatialReference sr_4326 = SpatialReferenceBuilder.CreateSpatialReference(4326, custom_vWkt);
});

##SpatialReference Properties

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // use the builder constructor
  SpatialReferenceBuilder srBuilder = new SpatialReferenceBuilder(3857);

  // spatialReferenceBuilder properties
  int wkid = srBuilder.Wkid;
  string wkt = srBuilder.Wkt;
  string name = srBuilder.Name;

  double xyScale = srBuilder.XYScale;
  double xyTolerance = srBuilder.XYTolerance;
  double xyResolution = srBuilder.XYResolution;
  Unit unit = srBuilder.Unit;

  double zScale = srBuilder.ZScale;
  double zTolerance = srBuilder.ZTolerance;
  Unit zUnit = srBuilder.ZUnit;

  double mScale = srBuilder.MScale;
  double mTolerance = srBuilder.MTolerance;

  double falseX = srBuilder.FalseX;
  double falseY = srBuilder.FalseY;
  double falseZ = srBuilder.FalseZ;
  double falseM = srBuilder.FalseM;

  // get the spatial reference
  SpatialReference sr3857 = srBuilder.ToSpatialReference();

  // spatial reference properties
  wkid = sr3857.Wkid;
  wkt = sr3857.Wkt;
  name = sr3857.Name;

  xyScale = sr3857.XYScale;
  xyTolerance = sr3857.XYTolerance;
  xyResolution = sr3857.XYResolution;
  unit = sr3857.Unit;

  zScale = sr3857.ZScale;
  zTolerance = sr3857.ZTolerance;
  zUnit = sr3857.ZUnit;

  mScale = sr3857.MScale;
  mTolerance = sr3857.MTolerance;

  falseX = sr3857.FalseX;
  falseY = sr3857.FalseY;
  falseZ = sr3857.FalseZ;
  falseM = sr3857.FalseM;
});

##Builder Properties

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // list of points
  List<MapPoint> points = new List<MapPoint> 
  { 
    MapPointBuilder.CreateMapPoint(0, 0, 2, 3, 1), 
    MapPointBuilder.CreateMapPoint(1, 1, 5, 6),
    MapPointBuilder.CreateMapPoint(2, 1, 6),
    MapPointBuilder.CreateMapPoint(0, 0)
  };

  // will have attributes because it is created with convenience method
  Polyline polylineWithAttrs = PolylineBuilder.CreatePolyline(points);

  bool hasZ = polylineWithAttrs.HasZ;          // hasZ = true
  bool hasM = polylineWithAttrs.HasM;          // hasM = true
  bool hasID = polylineWithAttrs.HasID;        // hasID = true

  // will not have attributes because it is passed something other than an attributed polyline
  PolylineBuilder polylineB = new PolylineBuilder(points);
  hasZ = polylineB.HasZ;                      // hasZ = false
  hasM = polylineB.HasM;                      // hasM = false
  hasID = polylineB.HasID;                    // hasID = false

  // will have attributes because it is passed an attributed polyline
  polylineB = new PolylineBuilder(polylineWithAttrs);
  hasZ = polylineB.HasZ;                      // hasZ = true
  hasM = polylineB.HasM;                      // hasM = true
  hasID = polylineB.HasID;                    // hasID = true


  // will have attributes because it is created with convenience method
  Polygon polygonWithAttrs = PolygonBuilder.CreatePolygon(points);
  hasZ = polygonWithAttrs.HasZ;               // hasZ = true
  hasM = polygonWithAttrs.HasM;               // hasM = true
  hasID = polygonWithAttrs.HasID;             // hasID = true

  // will not have attributes because it is passed something other than an attributed polygon
  PolygonBuilder polygonB = new PolygonBuilder(points);
  hasZ = polygonB.HasZ;                       // hasZ = false
  hasM = polygonB.HasM;                       // hasM = false
  hasID = polygonB.HasID;                     // hasID = false

  // will have attributes because it is passed an attributed polygon
  polygonB = new PolygonBuilder(polygonWithAttrs);
  hasZ = polygonB.HasZ;                       // hasZ = true
  hasM = polygonB.HasM;                       // hasM = true
  hasID = polygonB.HasID;                     // hasID = true
});

##Construct a MapPoint

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // create a 3d point with M
  // use the builder constructor
  MapPointBuilder mb = new MapPointBuilder(1.0, 2.0, 3.0, 4.0);
  MapPoint ptWithM = mb.ToGeometry();

  MapPoint clone = ptWithM.Clone() as MapPoint;

  // or use the convenience methods
  MapPoint anotherPt = MapPointBuilder.CreateMapPoint(1.0, 2.0, 3.0, 4.0);

  MapPoint anotherM = MapPointBuilder.CreateMapPoint(ptWithM);
});

##MapPoint Builder Properties

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPointBuilder mb = new MapPointBuilder(1.0, 2.0, 3.0);
  bool hasZ = mb.HasZ;          // hasZ = true
  bool hasM = mb.HasM;          // hasM = false
  bool hasID = mb.HasID;        // hasID = false

  MapPoint pt = mb.ToGeometry();
  double x = pt.X;                  // x = 1.0
  double y = pt.Y;                  // y = 2.0
  double z = pt.Z;                  // z = 3.0
  double m = pt.M;                  // m = Nan
  int ID = pt.ID;                   // ID = 0
  hasZ = pt.HasZ;                   // hasZ = true
  hasM = pt.HasM;                   // hasM = false
  hasID = pt.HasID;                 // hasID = false
  bool isEmpty = pt.IsEmpty;        // isEmpty = false

  MapPoint pt2 = MapPointBuilder.CreateMapPoint(pt);
  x = pt.X;                   // x = 1.0
  y = pt.Y;                   // y = 2.0
  z = pt.Z;                   // z = 3.0
  m = pt.M;                   // m = Nan
  hasZ = pt2.HasZ;            // hasZ = true
  hasM = pt2.HasM;            // hasM = false
  hasID = pt2.HasID;          // hasID = false
});

##MapPoint IsEqual

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint pt = MapPointBuilder.CreateMapPoint(1, 2, 3, 4, 5);
  int ID = pt.ID;           // ID = 5
  bool hasID = pt.HasID;    // hasID = true

  MapPoint pt2 = MapPointBuilder.CreateMapPoint(1, 2, 3, 4, 0);
  ID = pt2.ID;              // ID = 0
  hasID = pt2.HasID;        // hasID = true

  MapPoint pt3 = MapPointBuilder.CreateMapPoint(1, 2, 3, 4);
  ID = pt3.ID;              // ID = 0
  hasID = pt3.HasID;        // hasID = false

  MapPoint pt4 = MapPointBuilder.CreateMapPoint(1, 2, 3, 44);
  ID = pt4.ID;              // ID = 0
  hasID = pt4.HasID;        // hasID = false
  bool hasM = pt4.HasM;     // hasM = true

  MapPoint pt5 = MapPointBuilder.CreateMapPoint(1, 2, 3);
  ID = pt5.ID;              // ID = 0
  hasID = pt5.HasID;        // hasID = false
  hasM = pt5.HasM;          // hasM = false

  bool isEqual = pt.IsEqual(pt2);     // isEqual = false      // different IDs
  isEqual = pt2.IsEqual(pt3);         // isEqual = false      // HasId is different
  isEqual = pt4.IsEqual(pt3);         // isEqual = false      // different Ms
  isEqual = pt.IsEqual(pt5);          // isEqual = false      // pt has M, id but pt5 does not.  
});

##Construct a Polyline - from an enumeration of MapPoints

// methods need to run on MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint startPt = MapPointBuilder.CreateMapPoint(1.0, 1.0);
  MapPoint endPt = MapPointBuilder.CreateMapPoint(2.0, 1.0);

  List<MapPoint> list = new List<MapPoint>();
  list.Add(startPt);
  list.Add(endPt);

  // use the builder constructor
  PolylineBuilder pb = new PolylineBuilder(list);
  pb.SpatialReference = SpatialReferences.WGS84;
  Polyline polyline1 = pb.ToGeometry();

  // or use the convenience method
  Polyline polyline2 = PolylineBuilder.CreatePolyline(list, SpatialReferences.WGS84);
});

##Get the points of a Polyline

// get the points as a readonly Collection
ReadOnlyPointCollection pts = polyline.Points;
int numPts = polyline.PointCount;

// get an enumeration of the points
IEnumerator<MapPoint> enumPts = polyline.Points.GetEnumerator();

// get the point coordinates as a readonly list
IReadOnlyList<Coordinate> coordinates = polyline.CopyCoordinatesToList();

##Get the parts of a Polyline

int numParts = polyline.PartCount;
// get the parts as a readonly collection
ReadOnlyPartCollection parts = polyline.Parts;

##Enumerate the parts of a Polyline

ReadOnlyPartCollection polylineParts = polyline.Parts;

// enumerate the segments to get the length
double len = 0;
IEnumerator<ReadOnlySegmentCollection> segments = polylineParts.GetEnumerator();
while (segments.MoveNext())
{
  ReadOnlySegmentCollection seg = segments.Current;
  foreach (Segment s in seg)
  {
    len += s.Length;

    // perhaps do something specific per segment type
    switch (s.SegmentType)
    {
      case SegmentType.Line:
        break;
      case SegmentType.Bezier:
        break;
      case SegmentType.EllipticArc:
        break;
    }
  }
}

##Reverse the order of points in a Polyline

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  PolylineBuilder polylineBuilder = new PolylineBuilder(polyline);
  polylineBuilder.ReverseOrientation();
  Polyline reversedPolyline = polylineBuilder.ToGeometry();
});

##Build a multi-part Polyline

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  List<MapPoint> firstPoints = new List<MapPoint>();
  firstPoints.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0));
  firstPoints.Add(MapPointBuilder.CreateMapPoint(1.0, 2.0));
  firstPoints.Add(MapPointBuilder.CreateMapPoint(2.0, 2.0));
  firstPoints.Add(MapPointBuilder.CreateMapPoint(2.0, 1.0));

  List<MapPoint> nextPoints = new List<MapPoint>();
  nextPoints.Add(MapPointBuilder.CreateMapPoint(11.0, 1.0));
  nextPoints.Add(MapPointBuilder.CreateMapPoint(11.0, 2.0));
  nextPoints.Add(MapPointBuilder.CreateMapPoint(12.0, 2.0));
  nextPoints.Add(MapPointBuilder.CreateMapPoint(12.0, 1.0));

  PolylineBuilder pBuilder = new PolylineBuilder(firstPoints);
  pBuilder.AddPart(nextPoints);

  Polyline p = pBuilder.ToGeometry();
  // polyline p has 2 parts

  pBuilder.RemovePart(0);
  p = pBuilder.ToGeometry();
  // polyline p has 1 part
});

##Split Polyline at distance

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // create list of points
  MapPoint startPt = MapPointBuilder.CreateMapPoint(1.0, 1.0);
  MapPoint endPt = MapPointBuilder.CreateMapPoint(2.0, 1.0);

  List<MapPoint> list = new List<MapPoint>();
  list.Add(startPt);
  list.Add(endPt);

  // use the PolylineBuilder as we wish to manipulate the geometry
  PolylineBuilder polylineBuilder = new PolylineBuilder(list);
  // split at a distance 0.75
  polylineBuilder.SplitAtDistance(0.75, false);
  // get the polyline
  Polyline p = polylineBuilder.ToGeometry();

  // polyline p should have 3 points  (1,1), (1.75, 1), (2,1)

  // add another path
  MapPoint p1 = MapPointBuilder.CreateMapPoint(4.0, 1.0);
  MapPoint p2 = MapPointBuilder.CreateMapPoint(6.0, 1.0);
  MapPoint p3 = MapPointBuilder.CreateMapPoint(7.0, 1.0);
  List<MapPoint> pts = new List<MapPoint>();
  pts.Add(p1);
  pts.Add(p2);
  pts.Add(p3);

  polylineBuilder.AddPart(pts);
  p = polylineBuilder.ToGeometry();

  // polyline p has 2 parts.  Each part has 3 points

  // split the 2nd path half way - dont create a new path
  polylineBuilder.SplitPartAtDistance(1, 0.5, true, false);

  p = polylineBuilder.ToGeometry();

  // polyline p still has 2 parts; but now has 7 points 
});

##Construct a Polygon - from an enumeration of MapPoints

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint pt1 = MapPointBuilder.CreateMapPoint(1.0, 1.0);
  MapPoint pt2 = MapPointBuilder.CreateMapPoint(1.0, 2.0);
  MapPoint pt3 = MapPointBuilder.CreateMapPoint(2.0, 2.0);
  MapPoint pt4 = MapPointBuilder.CreateMapPoint(2.0, 1.0);

  List<MapPoint> list = new List<MapPoint>();
  list.Add(pt1);
  list.Add(pt2);
  list.Add(pt3);
  list.Add(pt4);

  // use the builder constructor
  PolygonBuilder pb = new PolygonBuilder(list);
  pb.SpatialReference = SpatialReferences.WGS84;
  Polygon polygon = pb.ToGeometry();

  // or use the convenience method
  Polygon anotherPolygon = PolygonBuilder.CreatePolygon(list, SpatialReferences.WGS84);
});

##Construct a Polygon - from an Envelope

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint minPt = MapPointBuilder.CreateMapPoint(1.0, 1.0);
  MapPoint maxPt = MapPointBuilder.CreateMapPoint(2.0, 2.0);

  // Create an envelope
  Envelope env = EnvelopeBuilder.CreateEnvelope(minPt, maxPt);
  // Create a polygon from the envelope
  Polygon polygon = PolygonBuilder.CreatePolygon(env);
});

##Get the points of a Polygon

// get the points as a readonly Collection
ReadOnlyPointCollection pts = poly.Points;

// get an enumeration of the points
IEnumerator<MapPoint> enumPts = poly.Points.GetEnumerator();

// get the point coordinates as a readonly list
IReadOnlyList<Coordinate> coordinates = poly.CopyCoordinatesToList();

##Get the parts of a Polygon

// get the parts as a readonly collection
ReadOnlyPartCollection parts = poly.Parts;

##Enumerate the parts of a Polygon

int numSegments = 0;
IEnumerator<ReadOnlySegmentCollection> segments = poly.Parts.GetEnumerator();
while (segments.MoveNext())
{
  ReadOnlySegmentCollection seg = segments.Current;
  numSegments += seg.Count;
  foreach (Segment s in seg)
  {
    // do something with the segment
  }
}

##Build a donut polygon

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  List<Coordinate2D> outerCoordinates = new List<Coordinate2D>();
  outerCoordinates.Add(new Coordinate2D(10.0, 10.0));
  outerCoordinates.Add(new Coordinate2D(10.0, 20.0));
  outerCoordinates.Add(new Coordinate2D(20.0, 20.0));
  outerCoordinates.Add(new Coordinate2D(20.0, 10.0));

  // use the PolygonBuilder as we wish to manipulate the parts
  PolygonBuilder pb = new PolygonBuilder(outerCoordinates);
  Polygon donut = pb.ToGeometry();
  double area = donut.Area;       // area = 100

  // define the inner polygon as anti-clockwise
  List<Coordinate2D> innerCoordinates = new List<Coordinate2D>();
  innerCoordinates.Add(new Coordinate2D(13.0, 13.0));
  innerCoordinates.Add(new Coordinate2D(17.0, 13.0));
  innerCoordinates.Add(new Coordinate2D(17.0, 17.0));
  innerCoordinates.Add(new Coordinate2D(13.0, 17.0));

  pb.AddPart(innerCoordinates);
  donut = pb.ToGeometry();

  area = donut.Area;    // area = 84.0

  area = GeometryEngine.Area(donut);    // area = 84.0
});

##Construct an Envelope

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint minPt = MapPointBuilder.CreateMapPoint(1.0, 1.0);
  MapPoint maxPt = MapPointBuilder.CreateMapPoint(2.0, 2.0);

  EnvelopeBuilder ev = new EnvelopeBuilder(minPt, maxPt);
  Envelope env = ev.ToGeometry();
});

##Construct an Envelope - from a JSON string

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  string jsonString = "{ \"xmin\" : 1, \"ymin\" : 2,\"xmax\":3,\"ymax\":4,\"spatialReference\":{\"wkid\":4326}}";

  Envelope envFromJson = EnvelopeBuilder.FromJson(jsonString);
});

##Union two Envelopes

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  Envelope env1 = EnvelopeBuilder.CreateEnvelope(0, 0, 1, 1, SpatialReferences.WGS84);
  Envelope env2 = EnvelopeBuilder.CreateEnvelope(0.5, 0.5, 1.5, 1.5, SpatialReferences.WGS84);

  Envelope env3 = env1.Union(env2);
});

##Expand an Envelope

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  Envelope envelope = EnvelopeBuilder.CreateEnvelope(100.0, 100.0, 500.0, 500.0);

  // shrink the envelope by 50%
  Envelope result = envelope.Expand(0.5, 0.5, true);
});

##Construct a Multipoint - from an enumeration of MapPoints

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  List<MapPoint> list = new List<MapPoint>();
  list.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0));
  list.Add(MapPointBuilder.CreateMapPoint(1.0, 2.0));
  list.Add(MapPointBuilder.CreateMapPoint(2.0, 2.0));
  list.Add(MapPointBuilder.CreateMapPoint(2.0, 1.0));

  // use the builder constructor
  MultipointBuilder mpb = new MultipointBuilder(list);
  Multipoint mPt = mpb.ToGeometry();

  // or use the convenience method
  Multipoint multiPoint = MultipointBuilder.CreateMultipoint(list);
});

##Modify the points of a Multipoint

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // assume a multiPoint has been built from 4 points
  // the modified multiPoint will have the first point removed and the last point moved

  MultipointBuilder mpb = new MultipointBuilder(multiPt);

  // remove the first point
  mpb.RemovePoint(0);

  // modify the coordinates of the last point
  MapPoint pt = mpb.GetMapPoint(mpb.PointCount-1);
  mpb.RemovePoint(mpb.PointCount - 1);

  MapPoint newPt = MapPointBuilder.CreateMapPoint(pt.X + 1.0, pt.Y + 2.0);
  mpb.Add(newPt);

  Multipoint modifiedMultiPoint = mpb.ToGeometry();
});

##Construct a LineSegment using two MapPoints

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint startPt = MapPointBuilder.CreateMapPoint(1.0, 1.0);
  MapPoint endPt = MapPointBuilder.CreateMapPoint(2.0, 1.0);

  // use the builder constructor
  LineBuilder lb = new LineBuilder(startPt, endPt);
  LineSegment line = lb.ToSegment();

  // or use the convenience method
  LineSegment anotherLine = LineBuilder.CreateLineSegment(startPt, endPt);
});

##Construct a Cubic Bezier - from Coordinates

// builders need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  Coordinate startPt = new Coordinate(1.0, 1.0, 3.0);
  Coordinate endPt = new Coordinate(2.0, 2.0, 3.0);

  Coordinate2D ctrl1Pt = new Coordinate2D(1.0, 2.0);
  Coordinate2D ctrl2Pt = new Coordinate2D(2.0, 1.0);

  // use the builder constructor 
  CubicBezierBuilder cbb = new CubicBezierBuilder(startPt, ctrl1Pt, ctrl2Pt, endPt, SpatialReferences.WGS84);
  CubicBezierSegment bezier = cbb.ToSegment();

  // or use the convenience method
  CubicBezierSegment anotherBezier = CubicBezierBuilder.CreateCubicBezierSegment(startPt, ctrl1Pt, ctrl2Pt, endPt, SpatialReferences.WGS84);

});

##Construct a Cubic Bezier - from MapPoints

// builders need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint startPt = MapPointBuilder.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84);
  MapPoint endPt = MapPointBuilder.CreateMapPoint(2.0, 2.0, SpatialReferences.WGS84);

  MapPoint ctrl1Pt = MapPointBuilder.CreateMapPoint(1.0, 2.0, SpatialReferences.WGS84);
  MapPoint ctrl2Pt = MapPointBuilder.CreateMapPoint(2.0, 1.0, SpatialReferences.WGS84);

  // use the builder constructor
  CubicBezierBuilder cbb = new CubicBezierBuilder(startPt, ctrl1Pt, ctrl2Pt, endPt);
  CubicBezierSegment bezier = cbb.ToSegment();

  // or use the convenience method
  CubicBezierSegment anotherBezier = CubicBezierBuilder.CreateCubicBezierSegment(startPt, ctrl1Pt, ctrl2Pt, endPt);
});

##Construct a Cubic Bezier - from an enumeration of MapPoints

// builders need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint startPt = MapPointBuilder.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84);
  MapPoint endPt = MapPointBuilder.CreateMapPoint(2.0, 2.0, SpatialReferences.WGS84);

  MapPoint ctrl1Pt = MapPointBuilder.CreateMapPoint(1.0, 2.0, SpatialReferences.WGS84);
  MapPoint ctrl2Pt = MapPointBuilder.CreateMapPoint(2.0, 1.0, SpatialReferences.WGS84);

  List<MapPoint> listMapPoints = new List<MapPoint>();
  listMapPoints.Add(startPt);
  listMapPoints.Add(ctrl1Pt);
  listMapPoints.Add(ctrl2Pt);
  listMapPoints.Add(endPt);

  // use the builder constructor
  CubicBezierBuilder cbb = new CubicBezierBuilder(listMapPoints);
  CubicBezierSegment bezier = cbb.ToSegment();

  // or use the convenience method
  CubicBezierSegment anotherBezier = CubicBezierBuilder.CreateCubicBezierSegment(listMapPoints);
});

##Cubic Bezier Builder Properties

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // retrieve the bezier curve's control points
  CubicBezierBuilder cbb = new CubicBezierBuilder(bezierSegment);
  MapPoint startPt = cbb.StartPoint;
  Coordinate2D ctrlPt1 = cbb.ControlPoint1;
  Coordinate2D ctrlPt2 = cbb.ControlPoint2;
  MapPoint endPt = cbb.EndPoint;

  // or use the QueryCoords method
  cbb.QueryCoords(out startPt, out ctrlPt1, out ctrlPt2, out endPt);
});

##Cubic Bezier Properties

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // retrieve the bezier curve's control points
  CubicBezierSegment cb = CubicBezierBuilder.CreateCubicBezierSegment(bezierSegment);
  MapPoint startPt = cb.StartPoint;
  Coordinate2D ctrlPt1 = cb.ControlPoint1;
  Coordinate2D ctrlPt2 = cb.ControlPoint2;
  MapPoint endPt = cb.EndPoint;

  bool isCurve = cb.IsCurve;
  double len = cb.Length;          
});

##Construct a Polyline (from a Cubic Bezier)

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  Polyline polyline = PolylineBuilder.CreatePolyline(bezierSegment);
});

##Construct a Circular Arc - using an interior point

//  methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // Construct a circular arc from (2, 1) to (1, 2) with interior pt (1 + sqrt(2)/2, 1 + sqrt(2)/2).

  Coordinate fromPt = new Coordinate(2, 1);
  Coordinate toPt = new Coordinate(1, 2);
  Coordinate2D interiorPt = new Coordinate2D(1 + Math.Sqrt(2) / 2, 1 + Math.Sqrt(2) / 2);

  // use the builder constructor
  EllipticArcBuilder cab = new EllipticArcBuilder(fromPt.ToMapPoint(), toPt.ToMapPoint(), interiorPt);
  EllipticArcSegment circularArc = cab.ToSegment();

  // or use the convenience method
  EllipticArcSegment anotherCircularArc = EllipticArcBuilder.CreateEllipticArcSegment(fromPt.ToMapPoint(), toPt.ToMapPoint(), interiorPt);
});

##Construct a Circular Arc - using a chord length and bearing

//  methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // Construct a circular arc counterclockwise from (2, 1) to (1, 2) such that the embedded 
  // circle has center point at (1, 1) and radius = 1

  MapPoint fromPt = MapPointBuilder.CreateMapPoint(2, 1, SpatialReferences.WGS84);
  double chordLength = Math.Sqrt(2);
  double chordBearing = 3 * Math.PI / 4;
  double radius = 1;
  esriArcOrientation orientation = esriArcOrientation.esriArcCounterClockwise;
  MinorOrMajor minorOrMajor = MinorOrMajor.Minor;

  // use the builder constructor
  EllipticArcBuilder cab = new EllipticArcBuilder(fromPt, chordLength, chordBearing, radius, orientation, minorOrMajor);
  EllipticArcSegment circularArc = cab.ToSegment();

  // or use the convenience method
  EllipticArcSegment anotherCircularArc = EllipticArcBuilder.CreateEllipticArcSegment(fromPt, chordLength, chordBearing, radius, orientation, minorOrMajor);
});

##Construct a Circular Arc - using a center point and angle

//  methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{

  // Construct a circular arc with center point at (0, 0), from angle = 0, 
  // central angle = pi/2, radius = 1

  SpatialReference sr4326 = SpatialReferences.WGS84;

  Coordinate2D centerPt = new Coordinate2D(0, 0);
  double fromAngle = 0;
  double centralAngle = Math.PI / 2;
  double radius = 1;

  // use the builder constructor
  EllipticArcBuilder cab = new EllipticArcBuilder(fromAngle, centralAngle, centerPt, radius, sr4326);
  EllipticArcSegment circularArc = cab.ToSegment();

  // or use the convenience method
  EllipticArcSegment anotherCircularArc = EllipticArcBuilder.CreateEllipticArcSegment(fromAngle, centralAngle, centerPt, radius, sr4326);
});

##Construct a Circular Arc - using a center point and orientation

//  methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{

  // Construct a circular arc from (2, 1) to (1, 2) 
  // with center point at (1, 1) and orientation counterclockwise.

  Coordinate fromPt = new Coordinate(2, 1);
  Coordinate toPt = new Coordinate(1, 2);
  Coordinate2D centerPtCoord = new Coordinate2D(1, 1);

  // use the builder constructor
  EllipticArcBuilder cab = new EllipticArcBuilder(fromPt.ToMapPoint(), toPt.ToMapPoint(), centerPtCoord, esriArcOrientation.esriArcCounterClockwise);
  EllipticArcSegment circularArc = cab.ToSegment();

  // or use the convenience method
  EllipticArcSegment anotherCircularArc = EllipticArcBuilder.CreateEllipticArcSegment(fromPt.ToMapPoint(), toPt.ToMapPoint(), centerPtCoord, esriArcOrientation.esriArcCounterClockwise);
});

##Construct a Circle

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // Construct a circle with center at (-1,-1), radius = 2, and oriented clockwise.

  Coordinate2D centerPtCoord = new Coordinate2D(-1, -1);

  // use the builder constructor
  EllipticArcBuilder builder = new EllipticArcBuilder(centerPtCoord, 2, esriArcOrientation.esriArcClockwise);
  EllipticArcSegment circle = builder.ToSegment();

  // or use the convenience method
  EllipticArcSegment anotherCircle = EllipticArcBuilder.CreateEllipticArcSegment(centerPtCoord, 2, esriArcOrientation.esriArcClockwise);
});

##Construct an Ellipse

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // Construct an ellipse centered at (1, 2) with rotationAngle = -pi/6,  
  // semiMajorAxis = 5, minorMajorRatio = 0.2, oriented clockwise

  Coordinate2D centerPt = new Coordinate2D(1, 2);

  // use the builder constructor
  EllipticArcBuilder builder = new EllipticArcBuilder(centerPt, -1 * Math.PI / 6, 5, 0.2, esriArcOrientation.esriArcClockwise);
  EllipticArcSegment ellipse = builder.ToSegment();

  // or use the convenience method
  EllipticArcSegment anotherEllipse = EllipticArcBuilder.CreateEllipticArcSegment(centerPt, -1 * Math.PI / 6, 5, 0.2, esriArcOrientation.esriArcClockwise);
});

##Elliptic Arc Builder Properties

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // retrieve the curve's control points
  EllipticArcBuilder builder = new EllipticArcBuilder(arcSegment);
  MapPoint startPt = builder.StartPoint;
  MapPoint endPt = builder.EndPoint;
  Coordinate2D centerPt = builder.CenterPoint;
  bool isCircular = builder.IsCircular;
  bool isMinor = builder.IsMinor;
   
});

##Elliptic Arc Properties

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // retrieve the curve's control points
  EllipticArcSegment arc = EllipticArcBuilder.CreateEllipticArcSegment(arcSegment);
  MapPoint startPt = arc.StartPoint;
  MapPoint endPt = arc.EndPoint;
  Coordinate2D centerPt = arc.CenterPoint;
  bool isCircular = arc.IsCircular;
  bool isMinor = arc.IsMinor;

  double startAngle, centralAngle, rotationAngle, semiMajorAxis, semiMinorAxis;
  // or use QueryCoords
  arc.QueryCoords(out centerPt, out startAngle, out centralAngle, out rotationAngle, out semiMajorAxis, out semiMinorAxis);
});

##Get the individual parts of a multipart feature

/// <summary>
/// This method takes an input multi part geometry and breaks the parts into individual standalone geometries.
/// This method must be called on the MCT. Use QueuedTask.Run.
/// </summary>
/// <param name="inputGeometry">The geometry to be exploded into the individual parts.</param>
/// <returns>An enumeration of individual parts as standalone geometries. The type of geometry is maintained, i.e.
/// if the input geometry is of type Polyline then each geometry in the return is of type Polyline as well.
/// If the input geometry is of type Unknown then an empty list is returned.</returns>
/// <remarks>This method must be called on the MCT. Use QueuedTask.Run.</remarks>
public IEnumerable<Geometry> MultipartToSinglePart(Geometry inputGeometry)
{
  // list holding the part(s) of the input geometry
  List<Geometry> singleParts = new List<Geometry>();

  // check if the input is a null pointer or if the geometry is empty
  if (inputGeometry == null || inputGeometry.IsEmpty)
    return singleParts;

  // based on the type of geometry, take the parts/points and add them individually into a list
  switch (inputGeometry.GeometryType)
  {
    case GeometryType.Envelope:
      singleParts.Add(inputGeometry.Clone() as Envelope);
      break;
    case GeometryType.Multipatch:
      singleParts.Add(inputGeometry.Clone() as Multipatch);
      break;
    case GeometryType.Multipoint:
      var multiPoint = inputGeometry as Multipoint;

      foreach (var point in multiPoint.Points)
      {
        // add each point of collection as a standalone point into the list
        singleParts.Add(point);
      }
      break;
    case GeometryType.Point:
      singleParts.Add(inputGeometry.Clone() as MapPoint);
      break;
    case GeometryType.Polygon:
      var polygon = inputGeometry as Polygon;

      foreach (var polygonPart in polygon.Parts)
      {
        // use the PolygonBuilder turning the segments into a standalone 
        // polygon instance
        singleParts.Add(PolygonBuilder.CreatePolygon(polygonPart));
      }
      break;
    case GeometryType.Polyline:
      var polyline = inputGeometry as Polyline;

      foreach (var polylinePart in polyline.Parts)
      {
        // use the PolylineBuilder turning the segments into a standalone
        // polyline instance
        singleParts.Add(PolylineBuilder.CreatePolyline(polylinePart));
      }
      break;
    case GeometryType.Unknown:
      break;
    default:
      break;
  }

  return singleParts;
}

##Get the outermost rings of a polygon

/// <summary>
/// The methods retrieves the outer ring(s) of the input polygon.
/// This method must be called on the MCT. Use QueuedTask.Run.
/// </summary>
/// <param name="inputPolygon">Input Polygon.</param>
/// <returns>The outer most (exterior, clockwise) ring(s) of the polygon. If the input is null or empty, a null pointer is returned.</returns>
/// <remarks>This method must be called on the MCT. Use QueuedTask.Run.</remarks>
public Polygon GetOutermostRings(Polygon inputPolygon)
{
  if (inputPolygon == null || inputPolygon.IsEmpty)
    return null;

  PolygonBuilder outerRings = new PolygonBuilder();
  List<Polygon> internalRings = new List<Polygon>();

  // explode the parts of the polygon into a list of individual geometries
  // see the "Get the individual parts of a multipart feature" snippet for MultipartToSinglePart method defintion
  var parts = MultipartToSinglePart(inputPolygon);

  // get an enumeration of clockwise geometries (area > 0) ordered by the area
  var clockwiseParts = parts.Where(geom => ((Polygon)geom).Area > 0).OrderByDescending(geom => ((Polygon)geom).Area);

  // for each of the exterior rings
  foreach (var part in clockwiseParts)
  {
    // add the first (the largest) ring into the internal collection
    if (internalRings.Count == 0)
      internalRings.Add(part as Polygon);

    // use flag to indicate if current part is within the already selection polygons
    bool isWithin = false;

    foreach (var item in internalRings)
    {
      if (GeometryEngine.Within(part, item))
        isWithin = true;
    }

    // if the current polygon is not within any polygon of the internal collection
    // then it is disjoint and needs to be added to 
    if (isWithin == false)
      internalRings.Add(part as Polygon);
  }

  // now assemble a new polygon geometry based on the internal polygon collection
  foreach (var ring in internalRings)
  {
    outerRings.AddParts(ring.Parts);
  }

  // return the final geometry of the outer rings
  return outerRings.ToGeometry();
}

##Determine if a polygon ring is an outer ring or an inner ring

/// <summary>
/// Based on the shoelace formula (or aka Gauss's area formula) https://en.wikipedia.org/wiki/Shoelace_formula
/// It computes the area of a polygon by determining the area of ordered coordinate pairs.
/// This method is more efficient than using the Polygon.Area methodology.
/// </summary>
/// <param name="PolyToCheck">The geometry to investigate.</param>
private void FindOrientationSimple(Polygon PolyToCheck)
{
  foreach (var part in PolyToCheck.Parts)
  {
    // construct a list of ordered coordinate pairs
    List<Coordinate2D> ringCoordinates = new List<Coordinate2D>(PolyToCheck.PointCount);

    foreach (var segment in part)
    {
      ringCoordinates.Add(segment.StartCoordinate);
      ringCoordinates.Add(segment.EndCoordinate);
    }

    // this is not the true area of the part
    // a negative number indicates an outer ring and a positive number represents an inner ring
    // (this is the opposite from the ArcGIS.Core.Geometry understanding)
    double signedArea = 0;

    // for all coordinates pairs compute the area
    // the last coordinate needs to reach back to the starting coordinate to complete
    for (int cIndex = 0; cIndex < ringCoordinates.Count - 1; cIndex++)
    {
      double x1 = ringCoordinates[cIndex].X;
      double y1 = ringCoordinates[cIndex].Y;

      double x2, y2;

      if (cIndex == ringCoordinates.Count - 2)
      {
        x2 = ringCoordinates[0].X;
        y2 = ringCoordinates[0].Y;
      }
      else
      {
        x2 = ringCoordinates[cIndex + 1].X;
        y2 = ringCoordinates[cIndex + 1].Y;
      }

      signedArea += ((x1 * y2) - (x2 * y1));
    }

    // if signedArea is a negative number => indicates an outer ring 
    // if signedArea is a positive number => indicates an inner ring
    // (this is the opposite from the ArcGIS.Core.Geometry understanding)

  }
}

##Retrieve Geometry from Geodatabase

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{

  try
  {
    // open a gdb
    ArcGIS.Core.Data.Geodatabase gdb = new ArcGIS.Core.Data.Geodatabase(new FileGeodatabaseConnectionPath(new Uri(@"c:\Temp\MyDatabase.gdb")));

    //Open a featureClass 
    ArcGIS.Core.Data.FeatureClass featureClass = gdb.OpenDataset<ArcGIS.Core.Data.FeatureClass>("Polygon");

    // find a field 
    ArcGIS.Core.Data.FeatureClassDefinition featureClassDefinition = featureClass.GetDefinition();
    int fldIndex = featureClassDefinition.FindField("SomeField");
    if (fldIndex == -1)
    {
      return;
    }

    ArcGIS.Core.Data.QueryFilter filter = new ArcGIS.Core.Data.QueryFilter
    {
      WhereClause = "OBJECTID = 6"
    };

    // get the row
    ArcGIS.Core.Data.RowCursor rowCursor = featureClass.Search(filter, false);
    while (rowCursor.MoveNext())
    {
      long oid = rowCursor.Current.GetObjectID();

      // get the shape from the row
      ArcGIS.Core.Data.Feature feature = rowCursor.Current as ArcGIS.Core.Data.Feature;
      Polygon polygon = feature.GetShape() as Polygon;

      // get the attribute from the row (assume it's a double field)
      double value = (double)rowCursor.Current.GetOriginalValue(fldIndex);

      // do something here
    }
  }
  catch (Exception ex)
  {
    // error - handle appropriately
  }
});

##Import and Export Geometries to Well Known Text

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // create a point with z, m
  MapPoint point = MapPointBuilder.CreateMapPoint(100, 200, 300, 400, SpatialReferences.WebMercator);

  // set the flags
  WKTExportFlags exportFlags = WKTExportFlags.wktExportDefaults;
  WKTImportFlags importFlags = WKTImportFlags.wktImportDefaults;

  // export and import
  string wktString = GeometryEngine.ExportToWKT(exportFlags, point);
  MapPoint importPoint = GeometryEngine.ImportFromWKT(importFlags, wktString, SpatialReferences.WebMercator) as MapPoint;

  double x = importPoint.X;       // x = 100
  double y = importPoint.Y;       // y = 200
  bool hasZ = importPoint.HasZ;   // hasZ = true
  double z = importPoint.Z;       // z = 300
  bool hasM = importPoint.HasM;   // hasM = true
  double m = importPoint.M;       // m = 400

  // export without z
  WKTExportFlags exportFlagsNoZ = WKTExportFlags.wktExportStripZs;
  wktString = GeometryEngine.ExportToWKT(exportFlags, point);
  importPoint = GeometryEngine.ImportFromWKT(importFlags, wktString, SpatialReferences.WebMercator) as MapPoint;

  x = importPoint.X;        // x = 100
  y = importPoint.Y;        // y = 200
  hasZ = importPoint.HasZ;  // hasZ = false
  z = importPoint.Z;        // z = Nan
  hasM = importPoint.HasM;  // hasM = true
  m = importPoint.M;        // m = 400

  // export without m
  WKTExportFlags exportFlagsNoM = WKTExportFlags.wktExportStripMs;
  wktString = GeometryEngine.ExportToWKT(exportFlags, point);
  importPoint = GeometryEngine.ImportFromWKT(importFlags, wktString, SpatialReferences.WebMercator) as MapPoint;

  x = importPoint.X;        // x = 100
  y = importPoint.Y;        // y = 200
  hasZ = importPoint.HasZ;  // hasZ = true
  z = importPoint.Z;        // z = 300
  hasM = importPoint.HasM;  // hasM = false
  m = importPoint.M;        // m = Nan

  // export without z, m
  wktString = GeometryEngine.ExportToWKT(exportFlagsNoZ | exportFlagsNoM, point);
  importPoint = GeometryEngine.ImportFromWKT(importFlags, wktString, SpatialReferences.WebMercator) as MapPoint;

  x = importPoint.X;        // x = 100
  y = importPoint.Y;        // y = 200
  hasZ = importPoint.HasZ;  // hasZ = false
  z = importPoint.Z;        // z = Nan
  hasM = importPoint.HasM;  // hasM = false
  m = importPoint.M;        // m = Nan

});

##Import and Export Geometries to Well Known Binary

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // create a polyline
  List<Coordinate2D> coords = new List<Coordinate2D> 
  {
    new Coordinate2D(0, 0), 
    new Coordinate2D(0, 1),
    new Coordinate2D(1, 1),
    new Coordinate2D(1, 0)
  };

  Polyline polyline = PolylineBuilder.CreatePolyline(coords, SpatialReferences.WGS84);

  WKBExportFlags exportFlags = WKBExportFlags.wkbExportDefaults;
  WKBImportFlags importFlags = WKBImportFlags.wkbImportDefaults;

  // export and import
  byte[] buffer = GeometryEngine.ExportToWKB(exportFlags, polyline);
  Geometry geometry = GeometryEngine.ImportFromWKB(importFlags, buffer, SpatialReferences.WGS84);
  Polyline importPolyline = geometry as Polyline;


  // alternatively, determine the size for the buffer
  int bufferSize = GeometryEngine.GetWKBSize(exportFlags, polyline);
  buffer = new byte[bufferSize];
  // export
  bufferSize = GeometryEngine.ExportToWKB(exportFlags, polyline, ref buffer);
  // import
  importPolyline = GeometryEngine.ImportFromWKB(importFlags, buffer, SpatialReferences.WGS84) as Polyline;

});

##Import and Export Geometries to EsriShape

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // create an envelope
  List<Coordinate> coordsZM = new List<Coordinate> 
  {
    new Coordinate(1001, 1002, 1003, 1004), 
    new Coordinate(2001, 2002, Double.NaN, 2004),
    new Coordinate(3001, -3002, 3003, 3004),
    new Coordinate(1001, -4002, 4003, 4004)
  };

  Envelope envelope = EnvelopeBuilder.CreateEnvelope(coordsZM[0], coordsZM[2], SpatialReferences.WGS84);


  // export and import
  EsriShapeExportFlags exportFlags = EsriShapeExportFlags.esriShapeExportDefaults;
  EsriShapeImportFlags importFlags = EsriShapeImportFlags.esriShapeImportDefaults;
  byte[] buffer = GeometryEngine.ExportToEsriShape(exportFlags, envelope);
  Polygon importedPolygon = GeometryEngine.ImportFromEsriShape(importFlags, buffer, envelope.SpatialReference) as Polygon;
  Envelope importedEnvelope = importedPolygon.Extent;

  // export without z,m
  buffer = GeometryEngine.ExportToEsriShape(EsriShapeExportFlags.esriShapeExportStripZs | EsriShapeExportFlags.esriShapeExportStripMs, envelope);
  importedPolygon = GeometryEngine.ImportFromEsriShape(importFlags, buffer, SpatialReferences.WGS84) as Polygon;
  importedEnvelope = importedPolygon.Extent;

  bool hasZ = importedEnvelope.HasZ;      // hasZ = false
  bool hasM = importedEnvelope.HasM;      // hasM = false

  // export with shapeSize
  int bufferSize = GeometryEngine.GetEsriShapeSize(exportFlags, envelope);
  buffer = new byte[bufferSize];

  bufferSize = GeometryEngine.ExportToEsriShape(exportFlags, envelope, ref buffer);
  importedPolygon = GeometryEngine.ImportFromEsriShape(importFlags, buffer, envelope.SpatialReference) as Polygon;
  importedEnvelope = importedPolygon.Extent;
});

##Import and Export Geometries to JSON

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // MapPoint
  MapPoint point = MapPointBuilder.CreateMapPoint(1, 2, SpatialReferences.WGS84);
  string inputString = "{\"x\":1,\"y\":2,\"spatialReference\":{\"wkid\":4326,\"latestWkid\":4326}}";
  Geometry geometry = GeometryEngine.ImportFromJSON(JSONImportFlags.jsonImportDefaults, inputString);

  MapPoint importPoint = geometry as MapPoint;
  // importPoint = 1, 2
  // importPoint.SpatialReference.WKid = 4326

  string outputString = GeometryEngine.ExportToJSON(JSONExportFlags.jsonExportDefaults, point);
  // outputString =  "{\"x\":1,\"y\":2,\"spatialReference\":{\"wkid\":4326,\"latestWkid\":4326}}"

  inputString = "{\"spatialReference\":{\"wkid\":4326},\"z\":3,\"m\":4,\"x\":1,\"y\":2}";
  point = GeometryEngine.ImportFromJSON(JSONImportFlags.jsonImportDefaults, inputString) as MapPoint;
  // point.HasM = true
  // point.HasZ = true
  // point.M = 4
  // point.Z = 3

  // skip spatial reference
  outputString = GeometryEngine.ExportToJSON(JSONExportFlags.jsonExportSkipCRS, point);
  // outputString = "{\"x\":1,\"y\":2,\"z\":3,\"m\":4}"

  //
  // Multipoint
  //
  List<Coordinate2D> coords = new List<Coordinate2D>
  {
    new Coordinate2D(100, 200),
    new Coordinate2D(201, 300),
    new Coordinate2D(301, 400),
    new Coordinate2D(401, 500)
  };

  Multipoint multipoint = MultipointBuilder.CreateMultipoint(coords, SpatialReferences.WebMercator);

  inputString = "{\"points\":[[100,200],[201,300],[301,400],[401,500]],\"spatialReference\":{\"wkid\":3857}}";
  Multipoint importMultipoint = GeometryEngine.ImportFromJSON(JSONImportFlags.jsonImportDefaults, inputString) as Multipoint;
  // importMultipoint.IsEqual(multipoint) = true

  outputString = GeometryEngine.ExportToJSON(JSONExportFlags.jsonExportDefaults, multipoint);
  // outputString = inputString

  ReadOnlyPointCollection points = importMultipoint.Points;
  // points.Count = 4
  // points[0] = 100, 200
  // points[1] = 201, 300
  // points[2] = 301, 400
  // points[3] = 401, 500

  //
  // Polyline
  //
  Polyline polyline = PolylineBuilder.CreatePolyline(coords, SpatialReferences.WebMercator);

  outputString = GeometryEngine.ExportToJSON(JSONExportFlags.jsonExportSkipCRS, polyline);
  geometry = GeometryEngine.ImportFromJSON(JSONImportFlags.jsonImportDefaults, outputString);
  Polyline importPolyline = geometry as Polyline;
  // importPolyline.SpatialReference = null

  points = importPolyline.Points;
  // points.Count = 4
  // points[0] = 100, 200
  // points[1] = 201, 300
  // points[2] = 301, 400
  // points[3] = 401, 500

  //
  // Polygon
  //
  Polygon polygon = PolygonBuilder.CreatePolygon(coords, SpatialReferences.WebMercator);

  outputString = GeometryEngine.ExportToJSON(JSONExportFlags.jsonExportSkipCRS, polygon);
  geometry = GeometryEngine.ImportFromJSON(JSONImportFlags.jsonImportDefaults, outputString);

  Polygon importPolygon = geometry as Polygon;
  points = importPolygon.Points;
  // points.Count = 5


  // Empty polygon
  polygon = PolygonBuilder.CreatePolygon(SpatialReferences.WebMercator);
  outputString = GeometryEngine.ExportToJSON(JSONExportFlags.jsonExportDefaults, polygon);
  importPolygon = GeometryEngine.ImportFromJSON(JSONImportFlags.jsonImportDefaults, outputString) as Polygon;

  // importPolygon.IsEmpty = true
  // importPolygon.SpatialReference.Wkid = 3857
});

##Determine area of a polygon

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  var g1 = PolygonBuilder.FromJson("{\"rings\": [ [ [0, 0], [10, 0], [10, 10], [0, 10] ] ] }");
  double d = GeometryEngine.Area(g1);
  // d = -100.0         //negative due to wrong ring orientation
  d = GeometryEngine.Area(GeometryEngine.SimplifyAsFeature(g1));
  // d = 100.0        // feature has been simplifed; ring orientation is correct
});

##Determine the boundary of a multi-part Polygon

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // create a donut polygon.  Must use the PolygonBuilder object

  List<Coordinate2D> outerPts = new List<Coordinate2D>();
  outerPts.Add(new Coordinate2D(10.0, 10.0));
  outerPts.Add(new Coordinate2D(10.0, 20.0));
  outerPts.Add(new Coordinate2D(20.0, 20.0));
  outerPts.Add(new Coordinate2D(20.0, 10.0));

  List<Coordinate2D> innerPts = new List<Coordinate2D>();
  innerPts.Add(new Coordinate2D(13.0, 13.0));
  innerPts.Add(new Coordinate2D(17.0, 13.0));
  innerPts.Add(new Coordinate2D(17.0, 17.0));
  innerPts.Add(new Coordinate2D(13.0, 17.0));

  // add the outer points
  PolygonBuilder pb = new PolygonBuilder(outerPts);
  // add the inner points (note they are defined anticlockwise)
  pb.AddPart(innerPts);
  // get the polygon
  Polygon donut = pb.ToGeometry();

  // get the boundary 
  Geometry g = GeometryEngine.Boundary(donut);
  Polyline boundary = g as Polyline;
});

##Buffer a MapPoint

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // buffer a point
  MapPoint pt = MapPointBuilder.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84);
  Geometry ptBuffer = GeometryEngine.Buffer(pt, 5.0);
  Polygon buffer = ptBuffer as Polygon;
});

##Buffer a Circular Arc

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // create the circular arc
  Coordinate fromPt = new Coordinate(2, 1);
  Coordinate toPt = new Coordinate(1, 2);
  Coordinate2D interiorPt = new Coordinate2D(1 + Math.Sqrt(2) / 2, 1 + Math.Sqrt(2) / 2);

  EllipticArcSegment circularArc = EllipticArcBuilder.CreateEllipticArcSegment(fromPt.ToMapPoint(), toPt.ToMapPoint(), interiorPt);

  // buffer the arc
  Polyline polyline = PolylineBuilder.CreatePolyline(circularArc);
  Geometry lineBuffer = GeometryEngine.Buffer(polyline, 10);
});

##Buffer multiple MapPoints

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // creates a buffer around each MapPoint

  List<MapPoint> pts = new List<MapPoint>();
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0));
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 2.0));
  pts.Add(MapPointBuilder.CreateMapPoint(2.0, 2.0));
  pts.Add(MapPointBuilder.CreateMapPoint(2.0, 1.0));

  Geometry ptsBuffer = GeometryEngine.Buffer(pts, 0.25);
  Polygon bufferResult = ptsBuffer as Polygon;      // bufferResult will have 4 parts
});

##Buffer many different Geometry Types

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  List<Coordinate2D> coords = new List<Coordinate2D>()
  {
    new Coordinate2D(1, 2), new Coordinate2D(3, 4), new Coordinate2D(4, 2),
    new Coordinate2D(5, 6), new Coordinate2D(7, 8), new Coordinate2D(8, 4),
    new Coordinate2D(9, 10), new Coordinate2D(11, 12), new Coordinate2D(12, 8),
    new Coordinate2D(10, 8), new Coordinate2D(12, 12), new Coordinate2D(14, 10)
  };

  List<Geometry> manyGeometries = new List<Geometry>
  {
    MapPointBuilder.CreateMapPoint(coords[9]),
    PolylineBuilder.CreatePolyline(new List<Coordinate2D>(){coords[0], coords[1], coords[2]}, SpatialReferences.WGS84),
    PolylineBuilder.CreatePolyline(new List<Coordinate2D>(){coords[3], coords[4], coords[5]}),
    PolygonBuilder.CreatePolygon(new List<Coordinate2D>(){coords[6], coords[7], coords[8]})
  };

  Geometry manyGeomBuffer = GeometryEngine.Buffer(manyGeometries, 0.25);
});

##Interpolate Z values on a polyline

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  List<Coordinate> coords2 = new List<Coordinate>()
  {
    new Coordinate(0, 0, 0),
    new Coordinate(0, 1000),
    new Coordinate(1000, 1000, 50),
    new Coordinate(1000, 1000, 76),
    new Coordinate(0, 1000),
    new Coordinate(0, 0, 0)
  };

  SpatialReference sr = SpatialReferences.WebMercator;

  Polyline polyline = PolylineBuilder.CreatePolyline(coords2, sr);

  // polyline.HasZ = true
  // polyline.Points[1].HasZ = true
  // polyline.Points[1].Z  = NaN   
  // polyline.Points[4].HasZ = true
  // polyline.Points[4].Z  = NaN   

  Polyline polylineNoNaNZs = GeometryEngine.CalculateNonSimpleZs(polyline, 0) as Polyline;

  // polylineNoNaNZs.Points[1].HasZ = true
  // polylineNoNaNZs.Points[1].Z = 25  (halfway between 0 and 50)
  // polylineNoNaNZs.Points[4].HasZ = true
  // polylineNoNaNZs.Points[4].Z = 38  (halfway between 76 and 0)
});

##Interpolate M values on a polygon

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  List<Coordinate> coords = new List<Coordinate>()
  {
    new Coordinate(0, 0, 0, 0),
    new Coordinate(0, 1000),
    new Coordinate(1000, 1000, 10, 50)
  };

  SpatialReference sr2 = SpatialReferences.WebMercator;

  Polygon polygon = PolygonBuilder.CreatePolygon(coords, sr2);

  // polygon.HasM = true
  // polygon.Points[1].HasM = true
  // polygon.Points[1].M = NaN

  Polygon polygonNoNaNMs = GeometryEngine.CalculateNonSimpleMs(polygon, 0) as Polygon;

  // polygonNoNaNMs.Points[1].HasM = true
  // polygonNoNaNMs.Points[1].M = 25  (halfway between 0 and 50)

});

##Center an envelope around X,Y

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  Envelope env = EnvelopeBuilder.CreateEnvelope(1.0, 1.0, 5.0, 5.0);
  Envelope centered = GeometryEngine.CenterAt(env, 2.0, 2.0);

  // centered.Center.X = 2.0
  // centered.Center.Y = 2.0
  // centered.XMin = 0
  // centered.YMin = 0
  // centered.XMax = 4
  // centered.YMax = 4

  centered = env.CenterAt(4.0, 3.0);
  // centered.Center.X == 4.0
  // centered.Center.Y == 3.0
  // centered.XMin == 2.0
  // centered.YMin == 1.0
  // centered.XMax == 6.0
  // centered.YMax == 5.0
});

##Find the centroid of geometries

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // simple polygon
  List<Coordinate2D> list2D = new List<Coordinate2D>();
  list2D.Add(new Coordinate2D(0, 0));
  list2D.Add(new Coordinate2D(0, 2));
  list2D.Add(new Coordinate2D(2, 2));
  list2D.Add(new Coordinate2D(2, 0));

  Polygon polygon = PolygonBuilder.CreatePolygon(list2D, SpatialReferences.WGS84);

  // verify it is simple
  bool isSimple = GeometryEngine.IsSimpleAsFeature(polygon);
  // find the centroid
  MapPoint centroid = GeometryEngine.Centroid(polygon);
  // centroid.X = 1
  // centroid.Y = 1


  // map Point
  MapPoint pt1 = MapPointBuilder.CreateMapPoint(1, 2, 3, 4, SpatialReferences.WGS84);
  MapPoint pt2 = MapPointBuilder.CreateMapPoint(5, 2, double.NaN, 7);

  // pt1.HasZ = true
  // pt1.HasM = true
  centroid = GeometryEngine.Centroid(pt1);
  // centroid.HasZ = true
  // centroid.HasM = true
  // pt1.IsEqual(centroid) = true


  // multipoint
  List<MapPoint> list = new List<MapPoint>() { pt1, pt2 };
  Multipoint multipoint = MultipointBuilder.CreateMultipoint(list);
  // multipoint.HasZ = true
  // multipoint.HasM = true

  centroid = GeometryEngine.Centroid(multipoint);
  // centroid.X = 3
  // centroid.Y = 2
  // centroid.HasZ = false
  // centroid.HasM = false
});

##Clip a Polyline

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // clip a polyline by an envelope

  Envelope env = EnvelopeBuilder.CreateEnvelope(2.0, 2.0, 4.0, 4.0);
  LineSegment line = LineBuilder.CreateLineSegment(new Coordinate(0, 3), new Coordinate(5.0, 3.0));
  Polyline polyline = PolylineBuilder.CreatePolyline(line);

  Geometry clipGeom = GeometryEngine.Clip(polyline, env);
});

##Clip a Polyline by a Polygon

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // clip a polyline by a polygon

  List<Coordinate2D> list = new List<Coordinate2D>();
  list.Add(new Coordinate2D(1.0, 1.0));
  list.Add(new Coordinate2D(1.0, 4.0));
  list.Add(new Coordinate2D(4.0, 4.0));
  list.Add(new Coordinate2D(4.0, 1.0));

  Polygon polygon = PolygonBuilder.CreatePolygon(list, SpatialReferences.WGS84);

  LineSegment crossingLine = LineBuilder.CreateLineSegment(MapPointBuilder.CreateMapPoint(0, 3), MapPointBuilder.CreateMapPoint(5.0, 3.0));
  Polyline p = PolylineBuilder.CreatePolyline(crossingLine);
  Geometry geometry = GeometryEngine.Clip(p, polygon.Extent);
});

##Polygon contains MapPoints, Polylines, Polygons

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{

  // build a polygon      
  List<MapPoint> pts = new List<MapPoint>();
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0));
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 2.0));
  pts.Add(MapPointBuilder.CreateMapPoint(2.0, 2.0));
  pts.Add(MapPointBuilder.CreateMapPoint(2.0, 1.0));

  Polygon poly = PolygonBuilder.CreatePolygon(pts);

  // test if an inner point is contained
  MapPoint innerPt = MapPointBuilder.CreateMapPoint(1.5, 1.5);
  bool contains = GeometryEngine.Contains(poly, innerPt);   // contains = true

  // test a point on a boundary
  contains = GeometryEngine.Contains(poly, poly.Points[0]);     // contains = false

  // test an interior line
  MapPoint innerPt2 = MapPointBuilder.CreateMapPoint(1.25, 1.75);
  List<MapPoint> innerLinePts = new List<MapPoint>();
  innerLinePts.Add(innerPt);
  innerLinePts.Add(innerPt2);

  // test an inner polyline
  Polyline polyline = PolylineBuilder.CreatePolyline(innerLinePts);
  contains = GeometryEngine.Contains(poly, polyline);   // contains = true

  // test a line that crosses the boundary
  MapPoint outerPt = MapPointBuilder.CreateMapPoint(3, 1.5);
  List<MapPoint> crossingLinePts = new List<MapPoint>();
  crossingLinePts.Add(innerPt);
  crossingLinePts.Add(outerPt);

  polyline = PolylineBuilder.CreatePolyline(crossingLinePts);
  contains = GeometryEngine.Contains(poly, polyline);     // contains = false

  // test a polygon in polygon
  Envelope env = EnvelopeBuilder.CreateEnvelope(innerPt, innerPt2);
  contains = GeometryEngine.Contains(poly, env);      // contains = true
});

##Determine convex hull

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  //
  // convex hull around a point - returns a point
  //

  MapPoint pt = MapPointBuilder.CreateMapPoint(2.0, 2.0);
  Geometry hull = GeometryEngine.ConvexHull(pt);
  MapPoint hullPt = hull as MapPoint;
  // nullPt.X = 2
  // hullPt.Y = 2


  List<MapPoint> list = new List<MapPoint>();
  list.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0));
  list.Add(MapPointBuilder.CreateMapPoint(1.0, 2.0));
  list.Add(MapPointBuilder.CreateMapPoint(2.0, 2.0));
  list.Add(MapPointBuilder.CreateMapPoint(2.0, 1.0));

  //
  // convex hull around a multipoint - returns a polygon
  //

  // build a multiPoint
  Multipoint multiPoint = MultipointBuilder.CreateMultipoint(list);

  hull = GeometryEngine.ConvexHull(multiPoint);
  Polygon hullPoly = hull as Polygon;
  // hullPoly.Area = 1
  // hullPoly.PointCount = 5


  // 
  // convex hull around a line - returns a polyline or polygon
  // 

  List<MapPoint> polylineList = new List<MapPoint>();
  polylineList.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0));
  polylineList.Add(MapPointBuilder.CreateMapPoint(2.0, 2.0));

  // 2 point straight line
  Polyline polyline = PolylineBuilder.CreatePolyline(polylineList);
  hull = GeometryEngine.ConvexHull(polyline);
  Polyline hullPolyline = hull as Polyline;
  // hullPolyline.Length = Math.Sqrt(2)
  // hullPolyline.PointCount = 2

  // 3 point angular line
  polylineList.Add(MapPointBuilder.CreateMapPoint(2.0, 1.0));
  polyline = PolylineBuilder.CreatePolyline(polylineList);
  hull = GeometryEngine.ConvexHull(polyline);
  hullPoly = hull as Polygon;
  // hullPoly.Length = 2 + Math.Sqrt(2)
  // hullPoly.Area = 0.5
  // hullPoly.PointCount = 4


  //
  // convex hull around a polygon - returns a polygon
  //

  // simple polygon
  Polygon poly = PolygonBuilder.CreatePolygon(list);
  hull = GeometryEngine.ConvexHull(poly);
  hullPoly = hull as Polygon;
  
  // hullPoly.Length = 4.0
  // hullPoly.Area = 1.0
  // hullPoly.PointCount = 5


  // polygon with concave angles
  List<MapPoint> funkyList = new List<MapPoint>();
  funkyList.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0));
  funkyList.Add(MapPointBuilder.CreateMapPoint(1.5, 1.5));
  funkyList.Add(MapPointBuilder.CreateMapPoint(1.0, 2.0));
  funkyList.Add(MapPointBuilder.CreateMapPoint(2.0, 2.0));
  funkyList.Add(MapPointBuilder.CreateMapPoint(1.5, 1.5));
  funkyList.Add(MapPointBuilder.CreateMapPoint(2.0, 1.0));
  funkyList.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0));

  Polygon funkyPoly = PolygonBuilder.CreatePolygon(funkyList);
  hull = GeometryEngine.ConvexHull(funkyPoly);
  hullPoly = hull as Polygon;
  // hullPoly.Length = 4.0
  // hullPoly.Area = 1.0
  // hullPoly.PointCount = 5
  // hullPoly.Points[0] = 1.0, 1.0
  // hullPoly.Points[1] = 1.0, 2.0
  // hullPoly.Points[2] = 2.0, 2.0
  // hullPoly.Points[3] = 2.0, 1.0
  // hullPoly.Points[4] = 1.0, 1.0
});

##Determine if two geometries cross

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  //
  // pt on pt
  //

  MapPoint pt = MapPointBuilder.CreateMapPoint(1.0, 1.0);
  MapPoint pt2 = MapPointBuilder.CreateMapPoint(2.0, 2.0);

  bool crosses = GeometryEngine.Crosses(pt, pt2);         // crosses = false
  crosses = GeometryEngine.Crosses(pt, pt);               // crosses = false

  // 
  // pt and line
  // 

  List<MapPoint> list = new List<MapPoint>();
  list.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0));
  list.Add(MapPointBuilder.CreateMapPoint(3.0, 3.0));
  list.Add(MapPointBuilder.CreateMapPoint(5.0, 1.0));

  Polyline line1 = PolylineBuilder.CreatePolyline(list);
  crosses = GeometryEngine.Crosses(line1, pt2);           // crosses = false
  crosses = GeometryEngine.Crosses(pt2, line1);           // crosses = false
  // end pt of line
  crosses = GeometryEngine.Crosses(line1, pt);            // crosses = false

  //
  // pt and polygon
  //
  List<MapPoint> polyPts = new List<MapPoint>();
  polyPts.Add(MapPointBuilder.CreateMapPoint(3.0, 2.0));
  polyPts.Add(MapPointBuilder.CreateMapPoint(3.0, 6.0));
  polyPts.Add(MapPointBuilder.CreateMapPoint(6.0, 6.0));
  polyPts.Add(MapPointBuilder.CreateMapPoint(6.0, 2.0));

  Polygon poly1 = PolygonBuilder.CreatePolygon(polyPts);
  crosses = GeometryEngine.Crosses(poly1, pt);              // crosses = false
  crosses = GeometryEngine.Crosses(pt, poly1);              // crosses = false

  // 
  // line and line
  //
  List<MapPoint> list2 = new List<MapPoint>();
  list2.Add(MapPointBuilder.CreateMapPoint(1.0, 3.0));
  list2.Add(MapPointBuilder.CreateMapPoint(3.0, 1.0));
  list2.Add(MapPointBuilder.CreateMapPoint(5.0, 3.0));

  Polyline line2 = PolylineBuilder.CreatePolyline(list2);
  crosses = GeometryEngine.Crosses(line1, line2);           // crosses = true

  //
  // line and polygon
  //
  crosses = GeometryEngine.Crosses(poly1, line1);           // crosses = true

  //
  // polygon and polygon
  //
  Envelope env = EnvelopeBuilder.CreateEnvelope(MapPointBuilder.CreateMapPoint(1.0, 1.0), MapPointBuilder.CreateMapPoint(4, 4));
  Polygon poly2 = PolygonBuilder.CreatePolygon(env);
  crosses = GeometryEngine.Crosses(poly1, poly2);           // crosses = false
});

##Cut a geometry with a polyline

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  SpatialReference sr = SpatialReferences.WGS84;

  List<MapPoint> list = new List<MapPoint>();
  list.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0, sr));
  list.Add(MapPointBuilder.CreateMapPoint(1.0, 4.0, sr));
  list.Add(MapPointBuilder.CreateMapPoint(4.0, 4.0, sr));
  list.Add(MapPointBuilder.CreateMapPoint(4.0, 1.0, sr));

  List<Geometry> cutGeometries;

  LineSegment line = LineBuilder.CreateLineSegment(MapPointBuilder.CreateMapPoint(0, 0, sr), MapPointBuilder.CreateMapPoint(3, 6, sr));
  Polyline cutter = PolylineBuilder.CreatePolyline(line);

  // polyline
  Polyline polyline = PolylineBuilder.CreatePolyline(list);
  bool isSimple = GeometryEngine.IsSimpleAsFeature(polyline);
  cutGeometries = GeometryEngine.Cut(polyline, cutter) as List<Geometry>;

  Polyline leftPolyline = cutGeometries[0] as Polyline;
  Polyline rightPolyline = cutGeometries[1] as Polyline;

  // leftPolyline.Points[0] = 1, 2
  // leftPolyline.Points[1] = 1, 4
  // leftPolyline.Points[2] = 2, 4

  // rightPolyline.Points.Count = 5
  // rightPolyline.Parts.Count = 2
  
  ReadOnlySegmentCollection segments0 = rightPolyline.Parts[0];
  // segments0[0].StartCoordinate = 1, 1
  // segments0[0].EndCoordinate = 1, 2

  ReadOnlySegmentCollection segments1 = rightPolyline.Parts[1];
  // segments1.Count = 2
  // segments1[0].StartCoordinate = 2, 4
  // segments1[0].EndCoordinate = 4, 4
  // segments1[1].StartCoordinate = 4, 4
  // segments1[1].EndCoordinate = 4, 1

  // polygon 
  Polygon polygon = PolygonBuilder.CreatePolygon(list);
  isSimple = GeometryEngine.IsSimpleAsFeature(polygon);
  cutGeometries = GeometryEngine.Cut(polygon, cutter) as List<Geometry>;
});

##Densify By Length

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // densify a line segment
  MapPoint startPt = MapPointBuilder.CreateMapPoint(1.0, 1.0);
  MapPoint endPt = MapPointBuilder.CreateMapPoint(1, 21);
  LineSegment line = LineBuilder.CreateLineSegment(startPt, endPt);
  Polyline polyline = PolylineBuilder.CreatePolyline(line);

  Geometry geom = GeometryEngine.DensifyByLength(polyline, 2);
  Polyline result = geom as Polyline;

  
  // densify a circular arc
  Coordinate fromPt = new Coordinate(2, 1);
  Coordinate toPt = new Coordinate(1, 2);
  Coordinate2D interiorPt = new Coordinate2D(1 + Math.Sqrt(2) / 2, 1 + Math.Sqrt(2) / 2);

  EllipticArcBuilder cab = new EllipticArcBuilder(fromPt.ToMapPoint(), toPt.ToMapPoint(), interiorPt);
  EllipticArcSegment circularArc = cab.ToSegment();
  polyline = PolylineBuilder.CreatePolyline(line);

  geom = GeometryEngine.DensifyByLength(polyline, 2);
  result = geom as Polyline;
});

##Difference between two Polygons

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  List<MapPoint> polyPts = new List<MapPoint>();
  polyPts.Add(MapPointBuilder.CreateMapPoint(3.0, 2.0));
  polyPts.Add(MapPointBuilder.CreateMapPoint(3.0, 6.0));
  polyPts.Add(MapPointBuilder.CreateMapPoint(6.0, 6.0));
  polyPts.Add(MapPointBuilder.CreateMapPoint(6.0, 2.0));

  Polygon poly1 = PolygonBuilder.CreatePolygon(polyPts);

  Envelope env = EnvelopeBuilder.CreateEnvelope(MapPointBuilder.CreateMapPoint(1.0, 1.0), MapPointBuilder.CreateMapPoint(4, 4));
  Polygon poly2 = PolygonBuilder.CreatePolygon(env);

  Geometry result = GeometryEngine.Difference(poly1, poly2);
  Polygon polyResult = result as Polygon;
  // polyResult.Area = 10.0

  result = GeometryEngine.Difference(poly2, poly1);
  polyResult = result as Polygon;
  // polyResult.Area = 7.0

});

##Determine if two Geometries are disjoint

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{

  //
  // pt on pt
  //

  MapPoint pt = MapPointBuilder.CreateMapPoint(1.0, 1.0);
  MapPoint pt2 = MapPointBuilder.CreateMapPoint(2.0, 2.5);

  bool disjoint = GeometryEngine.Disjoint(pt, pt2);       // result is true

  MultipointBuilder mpb = new MultipointBuilder();
  mpb.Add(pt);
  mpb.Add(pt2);
  Multipoint multiPoint = mpb.ToGeometry();

  disjoint = GeometryEngine.Disjoint(multiPoint, pt);     // result is false

  // 
  // pt and line
  // 

  List<MapPoint> list = new List<MapPoint>();
  list.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0));
  list.Add(MapPointBuilder.CreateMapPoint(3.0, 3.0));
  list.Add(MapPointBuilder.CreateMapPoint(5.0, 1.0));

  Polyline line1 = PolylineBuilder.CreatePolyline(list);
  disjoint = GeometryEngine.Disjoint(line1, pt2);       // result is true

  disjoint = GeometryEngine.Disjoint(pt2, line1);       // result is true

  // end pt of line
  disjoint = GeometryEngine.Disjoint(line1, pt);        // result is false

  //
  // pt and polygon
  //
  List<MapPoint> polyPts = new List<MapPoint>();
  polyPts.Add(MapPointBuilder.CreateMapPoint(3.0, 2.0));
  polyPts.Add(MapPointBuilder.CreateMapPoint(3.0, 6.0));
  polyPts.Add(MapPointBuilder.CreateMapPoint(6.0, 6.0));
  polyPts.Add(MapPointBuilder.CreateMapPoint(6.0, 2.0));

  Polygon poly1 = PolygonBuilder.CreatePolygon(polyPts);
  disjoint = GeometryEngine.Disjoint(poly1, pt);          // result is true
  disjoint = GeometryEngine.Disjoint(pt, poly1);          // result is true

  // 
  // line and line
  //

  List<MapPoint> list2 = new List<MapPoint>();
  list2.Add(MapPointBuilder.CreateMapPoint(1.0, 3.0));
  list2.Add(MapPointBuilder.CreateMapPoint(3.0, 1.0));
  list2.Add(MapPointBuilder.CreateMapPoint(5.0, 3.0));

  Polyline line2 = PolylineBuilder.CreatePolyline(list2);
  disjoint = GeometryEngine.Disjoint(line1, line2);         // result is false

  //
  // line and polygon
  //
  disjoint = GeometryEngine.Disjoint(poly1, line1);         // result is false
  disjoint = GeometryEngine.Disjoint(line1, poly1);         // result is false

  //
  // polygon and polygon
  //
  Envelope env = EnvelopeBuilder.CreateEnvelope(MapPointBuilder.CreateMapPoint(1.0, 1.0), MapPointBuilder.CreateMapPoint(4, 4));
  Polygon poly2 = PolygonBuilder.CreatePolygon(env);

  disjoint = GeometryEngine.Disjoint(poly1, poly2);         // result is false


  // disjoint3D

  SpatialReference sr = SpatialReferences.WGS84;

  MapPoint pt3D_1 = MapPointBuilder.CreateMapPoint(1, 1, 1, sr);
  MapPoint pt3D_2 = MapPointBuilder.CreateMapPoint(2, 2, 2, sr);
  MapPoint pt3D_3 = MapPointBuilder.CreateMapPoint(1, 1, 2, sr);

  mpb = new MultipointBuilder();
  mpb.Add(pt3D_1);
  mpb.Add(pt3D_2);
  mpb.HasZ = true;

  multiPoint = mpb.ToGeometry();
  disjoint = GeometryEngine.Disjoint3D(multiPoint, pt3D_2);     // disjoint = false
  disjoint = GeometryEngine.Disjoint3D(multiPoint, pt3D_3);     // disjoint = true
});

##Determine distance between two Geometries

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint pt1 = MapPointBuilder.CreateMapPoint(1.0, 1.0);
  MapPoint pt2 = MapPointBuilder.CreateMapPoint(2.0, 2.0);
  MapPoint pt3 = MapPointBuilder.CreateMapPoint(4.0, 2.0);

  //
  // pt and pt 
  //
  double d = GeometryEngine.Distance(pt1, pt2);         // d = Math.Sqrt(2)

  //
  // pt and multipoint
  //
  List<MapPoint> multiPts = new List<MapPoint>();
  multiPts.Add(pt2);
  multiPts.Add(pt3);
  Multipoint multiPoint = MultipointBuilder.CreateMultipoint(multiPts);
  d = GeometryEngine.Distance(pt1, multiPoint);         // d = Math.Sqrt(2)

  //
  // pt and envelope
  //
  Envelope env = EnvelopeBuilder.CreateEnvelope(pt1, pt2);
  d = GeometryEngine.Distance(pt1, env);                // d = 0

  //
  // pt and polyline
  //
  List<MapPoint> polylinePts = new List<MapPoint>();
  polylinePts.Add(MapPointBuilder.CreateMapPoint(2.0, 1.0));
  polylinePts.Add(pt2);
  Polyline polyline = PolylineBuilder.CreatePolyline(polylinePts);

  d = GeometryEngine.Distance(pt1, polyline);             // d = 1.0

  //
  // pt and polygon
  //
  Envelope env2 = EnvelopeBuilder.CreateEnvelope(MapPointBuilder.CreateMapPoint(3.0, 3.0), MapPointBuilder.CreateMapPoint(5.0, 5.0));
  Polygon poly = PolygonBuilder.CreatePolygon(env2);
  d = GeometryEngine.Distance(pt1, poly);                 // d = Math.Sqrt(8)

  //
  // envelope and polyline
  //
  d = GeometryEngine.Distance(env, polyline);             // d = 0

  //
  // polyline and polyline
  //
  List<MapPoint> polylineList = new List<MapPoint>();
  polylineList.Add(MapPointBuilder.CreateMapPoint(4, 3));
  polylineList.Add(MapPointBuilder.CreateMapPoint(4, 4));
  Polyline polyline2 = PolylineBuilder.CreatePolyline(polylineList);

  d = GeometryEngine.Distance(polyline, polyline2);           // d = Math.Sqrt(5)


  //
  // polygon and polygon
  //
  Polygon poly2 = PolygonBuilder.CreatePolygon(env);
  d = GeometryEngine.Distance(poly, poly2);                 // d = Math.Sqrt(2)
});

##Determine 3D distance between two Geometries

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{

  // between points 
  MapPoint pt1 = MapPointBuilder.CreateMapPoint(1, 1, 1);
  MapPoint pt2 = MapPointBuilder.CreateMapPoint(2, 2, 2);
  MapPoint pt3 = MapPointBuilder.CreateMapPoint(10, 2, 1);

  // pt1 to pt2
  double d = GeometryEngine.Distance3D(pt1, pt2);        // d = Math.Sqrt(3)

  // pt1 to pt3
  d = GeometryEngine.Distance3D(pt1, pt3);        // d = Math.Sqrt(82)

  // pt2 to pt3
  d = GeometryEngine.Distance3D(pt2, pt3);        // d = Math.Sqrt(65)



  // intersecting lines

  List<MapPoint> list = new List<MapPoint>();
  list.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0, 1.0));
  list.Add(MapPointBuilder.CreateMapPoint(3.0, 3.0, 1.0));
  list.Add(MapPointBuilder.CreateMapPoint(5.0, 1.0, 1.0));

  Polyline line1 = PolylineBuilder.CreatePolyline(list);

  List<MapPoint> list2 = new List<MapPoint>();
  list2.Add(MapPointBuilder.CreateMapPoint(1.0, 3.0, 1.0));
  list2.Add(MapPointBuilder.CreateMapPoint(3.0, 1.0, 1.0));
  list2.Add(MapPointBuilder.CreateMapPoint(5.0, 3.0, 1.0));

  Polyline line2 = PolylineBuilder.CreatePolyline(list2);

  bool intersects = GeometryEngine.Intersects(line1, line2);    // intersects = true
  d = GeometryEngine.Distance3D(line1, line2);                  // d = 0   (distance is 0 when geomtries intersect)

});

##Expand envelopes

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  Envelope env = EnvelopeBuilder.CreateEnvelope(100.0, 100.0, 500.0, 500.0);
  // env.HasZ = false

  Envelope result = GeometryEngine.Expand(env, 0.5, 0.5, true);
  // result.Center = 300, 300
  // result.XMin = 200
  // result.YMin = 200
  // result.XMax = 400
  // result.YMax = 400

  result = GeometryEngine.Expand(env, 100, 200, false);
  // result.Center = 300, 300
  // result.XMin = 0
  // result.YMin = -100
  // result.XMax = 600
  // result.YMax = 700

  try
  {
    // expand in 3 dimensions
    result = GeometryEngine.Expand(env, 0.5, 0.5, 0.5, true);
  }
  catch (InvalidOperationException e)
  {
    // the geometry is not Z-Aware
  }

  // expand a 3d envelope
  MapPoint pt1 = MapPointBuilder.CreateMapPoint(100, 100, 100);
  MapPoint pt2 = MapPointBuilder.CreateMapPoint(200, 200, 200);

  EnvelopeBuilder eb = new EnvelopeBuilder(pt1, pt2);
  eb.HasZ = true;
  env = eb.ToGeometry();
  result = GeometryEngine.Expand(env, 0.5, 0.5, 0.5, true);

  // result.Center = 150, 150, 150
  // result.XMin = 125
  // result.YMin = 125
  // result.ZMin = 125
  // result.XMax = 175
  // result.YMax = 175
  // result.ZMax = 175
});

##Extend a polyline

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // build a polyline
  var polyline = PolylineBuilder.CreatePolyline(new[]
  {
      MapPointBuilder.CreateMapPoint( 1,  1, 10, 20),
      MapPointBuilder.CreateMapPoint( 0,  0, 10, 20),
      MapPointBuilder.CreateMapPoint( 1, -1, 10, 20)
  });

  // build the extender line
  var extender = PolylineBuilder.CreatePolyline(new[]
  {
      MapPointBuilder.CreateMapPoint( 2, 2),
      MapPointBuilder.CreateMapPoint( 2,-2), 
  });

  // extend
  var result = GeometryEngine.Extend(polyline, extender, ExtendFlags.KeepEndAttributes);
  Polyline extendedLine = result as Polyline;
  // result.Parts[0].Points[0] = 2, 2, 10, 20
  // result.parts[0].Points[1] = 1, 1, 10, 20
  // result.Parts[0].Points[2] = 0, 0, 10, 20
  // result.Parts[0].Points[3] = 1, -1, 10, 20
  // result.Parts[0].Points[4] = 2, -2, 10, 20

  // change the flags
  result = GeometryEngine.Extend(polyline, extender, ExtendFlags.NoEndAttributes);
  extendedLine = result as Polyline;
  // result.Parts[0].Points[0] = 2, 2, 0
  // result.parts[0].Points[1] = 1, 1, 10, 20
  // result.Parts[0].Points[2] = 0, 0, 10, 20
  // result.Parts[0].Points[3] = 1, -1, 10, 20
  // result.Parts[0].Points[4] = 2, -2, 0

  // extend
  result = GeometryEngine.Extend(polyline, extender, ExtendFlags.KeepEndAttributes | ExtendFlags.NoExtendAtTo);
  extendedLine = result as Polyline;
  // result.Parts[0].Points[0] = 2, 2, 10, 20
  // result.parts[0].Points[1] = 1, 1, 10, 20
  // result.Parts[0].Points[2] = 0, 0, 10, 20
  // result.Parts[0].Points[3] = 1, -1, 10, 20


  // extend with no intersection 

  polyline = PolylineBuilder.CreatePolyline(new[]
  {
      MapPointBuilder.CreateMapPoint( 1,  1),
      MapPointBuilder.CreateMapPoint( 3,  1),
  });

  extender = PolylineBuilder.CreatePolyline(new[]
  {
      MapPointBuilder.CreateMapPoint( 1, 4),
      MapPointBuilder.CreateMapPoint( 3, 4), 
  });

  result = GeometryEngine.Extend(polyline, extender, ExtendFlags.Default);
  // result = null
});

##GeodesicBuffer

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // buffer a point
  MapPoint pt = MapPointBuilder.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84);
  Polygon outPolygon = GeometryEngine.GeodesicBuffer(pt, 5) as Polygon;

  double delta = SpatialReferences.WGS84.XYTolerance * 2 * Math.Sqrt(2);
  ReadOnlyPointCollection points = outPolygon.Points;
  foreach (MapPoint p in points)
  {
    double d = GeometryEngine.GeodesicDistance(pt, p);
    // d = 5 (+- delta)
  }

  // buffer of 0 distance produces an empty geometry
  Geometry g = GeometryEngine.GeodesicBuffer(pt, 0);
  // g.IsEmpty = true


  // buffer many points
  List<MapPoint> list = new List<MapPoint>();
  list.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84));
  list.Add(MapPointBuilder.CreateMapPoint(10.0, 20.0));
  list.Add(MapPointBuilder.CreateMapPoint(40.0, 40.0));
  list.Add(MapPointBuilder.CreateMapPoint(60.0, 60.0));

  outPolygon = GeometryEngine.GeodesicBuffer(list, 10000) as Polygon;
  // outPolygon.PartCount = 4


  // buffer different geometry types
  List<Coordinate2D> coords = new List<Coordinate2D>()
  {
    new Coordinate2D(1, 2), new Coordinate2D(10, 20), new Coordinate2D(20, 30),
    new Coordinate2D(50, 60), new Coordinate2D(70, 80), new Coordinate2D(80, 40),
    new Coordinate2D(90, 10), new Coordinate2D(110, 15), new Coordinate2D(120, 30),
    new Coordinate2D(10, 40), new Coordinate2D(-10, 40), new Coordinate2D(-10, 50)
  };

  List<Geometry> manyGeometries = new List<Geometry>
  {
    MapPointBuilder.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84), 
    PolylineBuilder.CreatePolyline(new List<Coordinate2D>(){coords[0], coords[1], coords[2]}, SpatialReferences.WGS84),
    PolylineBuilder.CreatePolyline(new List<Coordinate2D>(){coords[3], coords[4], coords[5]}),
    PolygonBuilder.CreatePolygon(new List<Coordinate2D>(){coords[9], coords[10], coords[11]})
  };

  outPolygon = GeometryEngine.GeodesicBuffer(manyGeometries, 20000) as Polygon;
});

##GeodeticDensifyByDeviation - polyline

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  List<Coordinate> coords = new List<Coordinate>()
  {
    new Coordinate(-80, 0),
    new Coordinate(-20, 60),
    new Coordinate(40, 20),
    new Coordinate(0, -20),
    new Coordinate(-80, 0)
  };

  SpatialReference sr = SpatialReferences.WGS84;

  // create a polyline
  Polyline polyline = PolylineBuilder.CreatePolyline(coords, sr);

  // densify in km
  Polyline geodesicPolyline = GeometryEngine.GeodeticDensifyByDeviation(polyline, 200, LinearUnit.Kilometers, CurveType.Geodesic) as Polyline;
  // densify in m
  geodesicPolyline = GeometryEngine.GeodeticDensifyByDeviation(polyline, 200, LinearUnit.Meters, CurveType.Geodesic) as Polyline;

  // Change curve type to Loxodrome
  Polyline loxodromePolyline = GeometryEngine.GeodeticDensifyByDeviation(polyline, 200, LinearUnit.Meters, CurveType.Loxodrome) as Polyline;
});

##GeodeticDensifyByLength - polygon

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  List<Coordinate> coords = new List<Coordinate>()
  {
    new Coordinate(-80, 0),
    new Coordinate(-20, 60),
    new Coordinate(40, 20),
    new Coordinate(0, -20),
    new Coordinate(-80, 0)
  };

  SpatialReference sr = SpatialReferences.WGS84;

  // create a polygon
  Polygon polygon = PolygonBuilder.CreatePolygon(coords, sr);

  // get the geodesic lengths of the polygon segments
  ReadOnlySegmentCollection segments = polygon.Parts[0];
  List<Double> geoLengths = new List<Double>(segments.Count);
  foreach (Segment s in segments)
  {
    Polyline line = PolylineBuilder.CreatePolyline(s, sr);
    double geoLen = GeometryEngine.GeodesicLength(line);
    geoLengths.Add(geoLen);
  }

  // find the max length
  geoLengths.Sort();
  double maxLen = geoLengths[geoLengths.Count - 1];

  // densify the polygon (in meters)
  Polygon densifiedPoly = GeometryEngine.GeodeticDensifyByLength(polygon, maxLen, LinearUnit.Meters, CurveType.Geodesic) as Polygon;

  // densify the polygon (in km)
  double maxSegmentLength = maxLen / 10000;
  densifiedPoly = GeometryEngine.GeodeticDensifyByLength(polygon, maxSegmentLength, LinearUnit.Kilometers, CurveType.Geodesic) as Polygon;
});

##GeodesicEllipse

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  GeometryEngine.GeodesicEllipseParameter param = new GeometryEngine.GeodesicEllipseParameter();
  param.AxisDirection = 4 * Math.PI / 3;
  param.Center = new Coordinate(-120, 60);
  param.LinearUnit = LinearUnit.Meters;
  param.OutGeometryType = GeometryType.Polyline;
  param.SemiAxis1Length = 6500000;
  param.SemiAxis2Length = 1500000;
  param.VertexCount = 800;

  Geometry geometry = GeometryEngine.GeodesicEllipse(param, SpatialReferences.WGS84);
  // geometry.IsEmpty = false

  Polyline polyline = geometry as Polyline;
  // polyline.PointCount = 801
  // polyline.PartCount = 1
});

##Perform Geodetic Move on a set of MapPoints

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  SpatialReference sr = SpatialReferences.WebMercator;
  var points = new[] { MapPointBuilder.CreateMapPoint(0, 0, sr) };
  double distance = 10;
  double azimuth = Math.PI / 2;
  var resultPoints = GeometryEngine.GeodeticMove(points, sr, distance, LinearUnit.Meters, azimuth, CurveType.Geodesic);

  // resultPoints.First().X = 10
  // resultPoints.First().Y = 0
  // resultPoints.First().SpatialReference.Wkid = sr.Wkid

  // Change LinearUnit to Miles
  resultPoints = GeometryEngine.GeodeticMove(points, sr, distance, LinearUnit.Miles, azimuth, CurveType.Geodesic);
  // resultPoints.First().X = 16093.44
  // resultPoints.First().Y = 0

  // Change curve type
  resultPoints = GeometryEngine.GeodeticMove(points, sr, distance, LinearUnit.Miles, azimuth, CurveType.Loxodrome);
  // resultPoints.First().X = 16093.44
  // resultPoints.First().Y = 0
});

##GeodesicSector

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  GeometryEngine.GeodesicSectorParameter param = new GeometryEngine.GeodesicSectorParameter();
  param.ArcVertexCount = 50;
  param.AxisDirection = Math.PI / 4;
  param.Center = new Coordinate(0, 0);
  param.LinearUnit = LinearUnit.Meters;
  param.OutGeometryType = GeometryType.Polygon;
  param.RadiusVertexCount = 10;
  param.SectorAngle = 5 * Math.PI / 3;
  param.SemiAxis1Length = 100000;
  param.SemiAxis2Length = 20000;
  param.StartDirection = 11 * Math.PI / 6;

  Geometry geometry = GeometryEngine.GeodesicSector(param, SpatialReferences.WGS84);
  // geometry.IsEmpty = false

  Polygon polygon = geometry as Polygon;
  // polygon.PointCount = 68
  // polygon.PartCount = 1
});

##Retrieve coordinate systems

// get all the geographic coordinate systems
IReadOnlyList<CoordinateSystemListEntry> gcs_list = GeometryEngine.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.GeographicCoordinateSystem);

// get the projected coordinate systems
IReadOnlyList<CoordinateSystemListEntry> proj_list = GeometryEngine.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.ProjectedCoordinateSystem);

// get the vertical coordinate systems
IReadOnlyList<CoordinateSystemListEntry> vert_list = GeometryEngine.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.VerticalCoordinateSystem);

// get geographic and projected coordinate systems
IReadOnlyList<CoordinateSystemListEntry> combined_list = GeometryEngine.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.GeographicCoordinateSystem | CoordinateSystemFilter.ProjectedCoordinateSystem);

##Get Sub-curve of a polyline or polygon

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  SpatialReference sr = SpatialReferences.WGS84;

  List<Coordinate> coords = new List<Coordinate>()
  {
    new Coordinate(-111, 72),
    new Coordinate(-108, 68),
    new Coordinate(-114, 68)
  };

  Polyline polyline = PolylineBuilder.CreatePolyline(coords, sr);

  Polyline subCurve = GeometryEngine.GetSubCurve(polyline, 0, 5, GeometryEngine.AsRatioOrLength.AsLength);
  // subCurve.PartCount = 1
  // subCurve.PointCount = 2

  ReadOnlyPointCollection points = subCurve.Points;
  // points[0] = -111, 72
  // points[1] = -108, 68

  subCurve = GeometryEngine.GetSubCurve(polyline, 0, 0.5, GeometryEngine.AsRatioOrLength.AsRatio);
  // subCurve.PointCount = 3

  points = subCurve.Points;
  // points[0] = -111, 72
  // points[1] = -108, 68
  // points[2] = -108.5, 68



  List<Coordinate> coords3D = new List<Coordinate>()
  {
    new Coordinate(0, 0, 0),
    new Coordinate(0, 1, 1),
    new Coordinate(1, 1, 2),
    new Coordinate(1, 0, 3)
  };

  Polygon polygon = PolygonBuilder.CreatePolygon(coords3D, sr);

  subCurve = GeometryEngine.GetSubCurve3D(polygon, 0, 1, GeometryEngine.AsRatioOrLength.AsLength);
  // subCurve.HasZ = true

  points = subCurve.Points;
  // points.Count = 2
  // points[0] = 0, 0, 0
  // points[1] = 0, 0.70710678118654746, 0.70710678118654746

});

##Intersection between two Polylines

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // determine intersection between two polylines

  List<MapPoint> pts = new List<MapPoint>();
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0));
  pts.Add(MapPointBuilder.CreateMapPoint(3.0, 3.0));
  pts.Add(MapPointBuilder.CreateMapPoint(5.0, 1.0));

  Polyline line1 = PolylineBuilder.CreatePolyline(pts);

  List<MapPoint> pts2 = new List<MapPoint>();
  pts2.Add(MapPointBuilder.CreateMapPoint(1.0, 3.0));
  pts2.Add(MapPointBuilder.CreateMapPoint(3.0, 1.0));
  pts2.Add(MapPointBuilder.CreateMapPoint(5.0, 3.0));

  Polyline line2 = PolylineBuilder.CreatePolyline(pts2);

  bool intersects = GeometryEngine.Intersects(line1, line2);    // intersects = true
  Geometry g = GeometryEngine.Intersection(line1, line2, GeometryDimension.esriGeometry0Dimension);
  Multipoint resultMultipoint = g as Multipoint;

  // result is a multiPoint that intersects at (2,2) and (4,2)
});

##Intersection between two Polygons

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // determine intersection between two polygons

  Envelope env1 = EnvelopeBuilder.CreateEnvelope(new Coordinate2D(3.0, 2.0), new Coordinate2D(6.0, 6.0));
  Polygon poly1 = PolygonBuilder.CreatePolygon(env1);

  Envelope env2 = EnvelopeBuilder.CreateEnvelope(new Coordinate2D(1.0, 1.0), new Coordinate2D(4.0, 4.0));
  Polygon poly2 = PolygonBuilder.CreatePolygon(env2);

  Polygon polyResult = GeometryEngine.Intersection(poly1, poly2) as Polygon;
});

##Determine label point for a Polygon

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // create a polygon
  List<Coordinate2D> list2D = new List<Coordinate2D>();
  list2D.Add(new Coordinate2D(1.0, 1.0));
  list2D.Add(new Coordinate2D(1.0, 2.0));
  list2D.Add(new Coordinate2D(2.0, 2.0));
  list2D.Add(new Coordinate2D(2.0, 1.0));

  Polygon polygon = PolygonBuilder.CreatePolygon(list2D);
  bool isSimple = GeometryEngine.IsSimpleAsFeature(polygon);
  MapPoint pt = GeometryEngine.LabelPoint(polygon); 
});

##Move a MapPoint

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint pt = MapPointBuilder.CreateMapPoint(1.0, 3.0);

  MapPoint ptResult = GeometryEngine.Move(pt, -3.5, 2.5) as MapPoint;
  // ptResult is (-2.5, 5.5)
});

##Move a z-aware MapPoint

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint zPt = MapPointBuilder.CreateMapPoint(1.0, 3.0, 2.0);
  MapPoint zPtResult = GeometryEngine.Move(zPt, 4, 0.25, 0.5) as MapPoint;
  // zPtResult is (5.0, 3.25, 2.5);
});

##Move a Polyline

ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  List<MapPoint> pts = new List<MapPoint>();
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0, 3.0));
  pts.Add(MapPointBuilder.CreateMapPoint(3.0, 3.0, 3.0));
  pts.Add(MapPointBuilder.CreateMapPoint(3, 2, 3.0));
  pts.Add(MapPointBuilder.CreateMapPoint(4.0, 2.0, 3.0));

  Polyline polyline = PolylineBuilder.CreatePolyline(pts);

  Geometry g = GeometryEngine.Move(polyline, 3, 2);
  Polyline polylineResult = g as Polyline;

  // polylineResult.Points[0] = 4.0, 3.0, 3.0
  // polylineResult.Points[1] = 6.0, 5.0, 3.0
  // polylineResult.Points[2] = 6.0, 4.0, 3.0
  // polylineResult.Points[3] = 7.0, 4.0, 3.0
});

##MovePointAlongLine

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  LineSegment line = LineBuilder.CreateLineSegment(MapPointBuilder.CreateMapPoint(0, 3), MapPointBuilder.CreateMapPoint(5.0, 3.0));
  Polyline polyline = PolylineBuilder.CreatePolyline(line);
  bool simple = GeometryEngine.IsSimpleAsFeature(polyline);

  // ratio = false
  MapPoint pt = GeometryEngine.MovePointAlongLine(polyline, 1.0, false, 0.0, GeometryEngine.SegmentExtension.NoExtension);
  // pt = 1.0, 3.0

  pt = GeometryEngine.MovePointAlongLine(polyline, 1.0, false, -1.0, GeometryEngine.SegmentExtension.NoExtension);
  // pt = 1.0, 4.0

  pt = GeometryEngine.MovePointAlongLine(polyline, 1.0, false, 2.0, GeometryEngine.SegmentExtension.NoExtension);
  // pt = 1.0, 1.0

  // ratio = true
  pt = GeometryEngine.MovePointAlongLine(polyline, 0.5, true, 0, GeometryEngine.SegmentExtension.NoExtension);
  // pt = 2.5, 3.0

  // move past the line
  pt = GeometryEngine.MovePointAlongLine(polyline, 7, false, 0, GeometryEngine.SegmentExtension.NoExtension);
  // pt = 5.0, 3.0

  // move past the line with extension at "to" point
  pt = GeometryEngine.MovePointAlongLine(polyline, 7, false, 0, GeometryEngine.SegmentExtension.ExtendEmbeddedAtTo);
  // pt = 7.0, 3.0

  // negative distance with extension at "from" point
  pt = GeometryEngine.MovePointAlongLine(polyline, -2, false, 0, GeometryEngine.SegmentExtension.ExtendEmbeddedAtFrom);
  // pt = -2.0, 3.0

  // ratio = true
  pt = GeometryEngine.MovePointAlongLine(polyline, 0.5, true, 0, GeometryEngine.SegmentExtension.NoExtension);
  // pt = 2.5, 3.0


  // line with Z
  List<Coordinate> coords3D = new List<Coordinate> { new Coordinate(0, 0, 0), new Coordinate(1113195, 1118890, 5000) };
  Polyline polylineZ = PolylineBuilder.CreatePolyline(coords3D, SpatialReferences.WebMercator);
  // polylineZ.HasZ = true

  // ratio = true, no offset
  pt = GeometryEngine.MovePointAlongLine(polylineZ, 0.5, true, 0, GeometryEngine.SegmentExtension.NoExtension);
  // pt.X = 556597.5
  // pt.Y = 559445
  // pt.Z = 2500

  // ratio = true, past the line with "to" extension, no offset
  pt = GeometryEngine.MovePointAlongLine(polylineZ, 1.5, true, 0, GeometryEngine.SegmentExtension.ExtendEmbeddedAtTo);
  // pt.X = 1669792.5
  // pt.Y = 1678335
  // pt.Z = 7500

  // ratio = true, negative distance past the line with no extension, no offset
  pt = GeometryEngine.MovePointAlongLine(polylineZ, -1.5, true, 0, GeometryEngine.SegmentExtension.NoExtension);
  // pt.X = 0
  // pt.Y = 0
  // pt.Z = -7500


  // polyline with Z but 2d distance = 0
  MapPoint pt3 = MapPointBuilder.CreateMapPoint(5, 5, 0);
  MapPoint pt4 = MapPointBuilder.CreateMapPoint(5, 5, 10);
  List<MapPoint> pts = new List<MapPoint>() { pt3, pt4 };

  PolylineBuilder pb = new PolylineBuilder();
  pb.SetEmpty();
  pb.AddPart(pts);
  pb.HasZ = true;
  polyline = pb.ToGeometry();
  // polyline.Length3D = 10
  // polyline.Length = 0

  MapPoint result = GeometryEngine.MovePointAlongLine(polyline, 2, false, 0, GeometryEngine.SegmentExtension.NoExtension);
  // result = 5, 5, 2


  // polyline with length2d = 0 and length3d = 0
  MapPoint pt5 = MapPointBuilder.CreateMapPoint(5, 5, 10);
  MapPoint pt6 = MapPointBuilder.CreateMapPoint(5, 5, 10);
  pts.Clear();
  pts.Add(pt5);
  pts.Add(pt6);

  pb.SetEmpty();
  pb.AddPart(pts);
  pb.HasZ = true;
  polyline = pb.ToGeometry();
  // polyline.Length3D = 0
  // polyline.Length = 0

  result = GeometryEngine.MovePointAlongLine(polyline, 3, true, 0, GeometryEngine.SegmentExtension.NoExtension);
  // result = 5, 5, 10

  result = GeometryEngine.MovePointAlongLine(polyline, 3, true, 0, GeometryEngine.SegmentExtension.ExtendEmbeddedAtFrom);
  // result = 5, 5, 10


  // polyline with Z and M
  List<MapPoint> inputPoints = new List<MapPoint>()
  {
    MapPointBuilder.CreateMapPoint(1, 2, 3, 4),
    MapPointBuilder.CreateMapPoint(1, 2, 33, 44),
  };

  Polyline polylineZM = PolylineBuilder.CreatePolyline(inputPoints, SpatialReferences.WGS84);
  // polylineZM.HasZ = true
  // polylineZM.HasM = true

  // ratio = true, no offset
  MapPoint pointAlong = GeometryEngine.MovePointAlongLine(polylineZM, 0.5, true, 0, GeometryEngine.SegmentExtension.NoExtension);
  // pointAlong = 1, 2, 18, 24

  // ratio = true with offset
  pointAlong = GeometryEngine.MovePointAlongLine(polylineZM, 0.2, true, 2.23606797749979, GeometryEngine.SegmentExtension.NoExtension);
  // pointAlong = 1, 2, 9, 12
});

##Nearest Point versus Nearest Vertex

ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  SpatialReference sr = SpatialReferences.WGS84;
  MapPoint pt = MapPointBuilder.CreateMapPoint(5, 5, sr);

  List<Coordinate> coords = new List<Coordinate>()
  {
    new Coordinate(10, 1),
    new Coordinate(10, -4),
    new Coordinate(0, -4),
    new Coordinate(0, 1),
    new Coordinate(10, 1)
  };

  Polygon polygon = PolygonBuilder.CreatePolygon(coords);

  // find the nearest point in the polygon geomtry to the pt
  GeometryEngine.ProximityResult result = GeometryEngine.NearestPoint(polygon, pt);
  // result.Point = 5, 1
  // result.SegmentIndex = 3
  // result.PartIndex = 0
  // result.PointIndex = null
  //result.Distance = 4
  //result.RightSide = false

  // find the nearest vertex in the polgyon geometry to the pt
  result = GeometryEngine.NearestVertex(polygon, pt);
  // result.Point = 10, 1
  // result.PointIndex = 0
  // result.SegmentIndex = null
  // result.PartIndex = 0
  // result.Distance = Math.Sqrt(41)
  // result.RightSide = false

});

##Determine Nearest Point in 3D

ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint pt1 = MapPointBuilder.CreateMapPoint(1, 1, 1);
  MapPoint pt2 = MapPointBuilder.CreateMapPoint(2, 2, 2);
  MapPoint pt3 = MapPointBuilder.CreateMapPoint(10, 2, 1);

  //
  // test pt1 to pt2
  //
  GeometryEngine.ProximityResult result = GeometryEngine.NearestPoint3D(pt1, pt2);
  // result.Point = 1,1,1
  // result.Distance = Math.Sqrt(3)
  // result.SegmentIndex = null
  // result.PartIndex = 0
  // result.PointIndex = 0
  // result.RightSide = false

  // 
  // multipoint built from pt1, pt2.   should be closer to pt2
  // 
  MultipointBuilder mpb = new MultipointBuilder(pt1);
  mpb.Add(pt2);
  mpb.HasZ = true;
  Multipoint multipoint = mpb.ToGeometry();
  result = GeometryEngine.NearestPoint3D(multipoint, pt3);

  // result.Point = 2, 2, 2
  // result.Distance = Math.Sqrt(65)
  // result.SegmentIndex = null
  // result.PartIndex = 1
  // result.PointIndex = 1
  // result.RightSide = false
});

##Determine if geometries overlap

ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint pt1 = MapPointBuilder.CreateMapPoint(1.5, 1.5);
  MapPoint pt2 = MapPointBuilder.CreateMapPoint(1.25, 1.75);
  MapPoint pt3 = MapPointBuilder.CreateMapPoint(3, 1.5);
  MapPoint pt4 = MapPointBuilder.CreateMapPoint(1.5, 2);

  //
  // point and point overlap
  //
  bool overlaps = GeometryEngine.Overlaps(pt1, pt2);        // overlaps = false
  overlaps = GeometryEngine.Overlaps(pt1, pt1);             // overlaps = false
  // Two geometries overlap if the region of their intersection is of the same dimension as the geometries involved and 
  // is not equivalent to either of the geometries.  

  List<MapPoint> pts = new List<MapPoint>();
  pts.Add(pt1);
  pts.Add(pt2);
  pts.Add(pt3);

  List<MapPoint> pts2 = new List<MapPoint>();
  pts2.Add(pt2);
  pts2.Add(pt3);
  pts2.Add(pt4);

  //
  // pt and line overlap
  //
  Polyline polyline = PolylineBuilder.CreatePolyline(pts);
  bool isSimple = GeometryEngine.IsSimpleAsFeature(polyline);         // isSimple = true
  overlaps = GeometryEngine.Overlaps(polyline, pt1);                  // overlaps = false

  //
  // line and line
  //
  Polyline polyline2 = PolylineBuilder.CreatePolyline(pts2);
  isSimple = GeometryEngine.IsSimpleAsFeature(polyline2);             // isSimple = true
  overlaps = GeometryEngine.Overlaps(polyline, polyline2);            // overlaps = true

});

##Project from WGS84 to WebMercator

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint pt = MapPointBuilder.CreateMapPoint(1.0, 3.0, SpatialReferences.WGS84);
  Geometry result = GeometryEngine.Project(pt, SpatialReferences.WebMercator);
  MapPoint projectedPt = result as MapPoint;
});

##Project from WGS84

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // create the polygon
  List<MapPoint> pts = new List<MapPoint>();
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84));
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 2.0, SpatialReferences.WGS84));
  pts.Add(MapPointBuilder.CreateMapPoint(2.0, 2.0, SpatialReferences.WGS84));
  pts.Add(MapPointBuilder.CreateMapPoint(2.0, 1.0, SpatialReferences.WGS84));

  Polygon polygon = PolygonBuilder.CreatePolygon(pts);
  // ensure it is simple
  bool isSimple = GeometryEngine.IsSimpleAsFeature(polygon);

  // create the spatial reference to project to
  SpatialReference northPole = SpatialReferenceBuilder.CreateSpatialReference(102018);   // north pole stereographic 

  // project
  Geometry g = GeometryEngine.Project(polygon, northPole);
});

##QueryPointAndDistance

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // Horizontal line segment
  List<MapPoint> linePts = new List<MapPoint>();
  linePts.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84));
  linePts.Add(MapPointBuilder.CreateMapPoint(11.0, 1.0, SpatialReferences.WGS84));
  Polyline polyline = PolylineBuilder.CreatePolyline(linePts);
  bool isSimple = GeometryEngine.IsSimpleAsFeature(polyline);

  // Don't extent the segment
  GeometryEngine.SegmentExtension extension = GeometryEngine.SegmentExtension.NoExtension;

  // A point on the line segment
  MapPoint inPoint = MapPointBuilder.CreateMapPoint(2, 1, SpatialReferences.WGS84);

  double distanceAlongCurve, distanceFromCurve;
  GeometryEngine.LeftOrRightSide whichSide;
  GeometryEngine.AsRatioOrLength asRatioOrLength = GeometryEngine.AsRatioOrLength.AsLength;

  MapPoint outPoint = GeometryEngine.QueryPointAndDistance(polyline, extension, inPoint, asRatioOrLength, out distanceAlongCurve, out distanceFromCurve, out whichSide);
  // outPoint = 2, 1
  // distanceAlongCurve = 1
  // distanceFromCurve = 0
  // whichSide = GeometryEngine.LeftOrRightSide.LeftSide


  // Extend infinitely in both directions
  extension = GeometryEngine.SegmentExtension.ExtendTangents;

  // A point on the left side
  inPoint = MapPointBuilder.CreateMapPoint(16, 6, SpatialReferences.WGS84);
  asRatioOrLength = GeometryEngine.AsRatioOrLength.AsRatio;

  outPoint = GeometryEngine.QueryPointAndDistance(polyline, extension, inPoint, asRatioOrLength, out distanceAlongCurve, out distanceFromCurve, out whichSide);
  // outPoint = 16, 1
  // distanceAlongCurve = 1.5
  // distanceFromCurve = 5
  // whichSide = GeometryEngine.LeftOrRightSide.LeftSide

});

##Determine relationship between two geometries

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // set up some geometries

  // points
  MapPoint point0 = MapPointBuilder.CreateMapPoint(0, 0, SpatialReferences.WGS84);
  MapPoint point1 = MapPointBuilder.CreateMapPoint(1, 1, SpatialReferences.WGS84);
  MapPoint point2 = MapPointBuilder.CreateMapPoint(-5, 5, SpatialReferences.WGS84);

  // multipoint
  List<MapPoint> points = new List<MapPoint>() { point0, point1, point2 };
  Multipoint multipoint = MultipointBuilder.CreateMultipoint(points, SpatialReferences.WGS84);

  // polygon 
  List<Coordinate2D> polygonCoords = new List<Coordinate2D>()
  {
    new Coordinate2D(-10, 0),
    new Coordinate2D(0, 10),
    new Coordinate2D(10, 0),
    new Coordinate2D(-10, 0)
  };
  Polygon polygon = PolygonBuilder.CreatePolygon(polygonCoords, SpatialReferences.WGS84);

  // polylines
  Polyline polyline1 = PolylineBuilder.CreatePolyline(LineBuilder.CreateLineSegment(new Coordinate(-9.1, 0.1), new Coordinate(0, 9)), SpatialReferences.WGS84);
  Polyline polyline2 = PolylineBuilder.CreatePolyline(LineBuilder.CreateLineSegment(new Coordinate(-5, 5), new Coordinate(0, 5)), SpatialReferences.WGS84);
  Polyline polyline3 = PolylineBuilder.CreatePolyline(LineBuilder.CreateLineSegment(new Coordinate(2.09, -2.04), new Coordinate(5, 10)), SpatialReferences.WGS84);
  Polyline polyline4 = PolylineBuilder.CreatePolyline(LineBuilder.CreateLineSegment(new Coordinate(10, -5), new Coordinate(10, 5)), SpatialReferences.WGS84);

  List<Segment> segments = new List<Segment>()
  {
    LineBuilder.CreateLineSegment(new Coordinate(5.05, -2.87), new Coordinate(6.35, 1.57)),
    LineBuilder.CreateLineSegment(new Coordinate(6.35, 1.57), new Coordinate(4.13, 2.59)),
    LineBuilder.CreateLineSegment(new Coordinate(4.13, 2.59), new Coordinate(5, 5))
  };
  Polyline polyline5 = PolylineBuilder.CreatePolyline(segments, SpatialReferences.WGS84);

  segments.Add(LineBuilder.CreateLineSegment(new Coordinate(5, 5), new Coordinate(10, 10)));

  Polyline polyline6 = PolylineBuilder.CreatePolyline(segments, SpatialReferences.WGS84);
  Polyline polyline7 = PolylineBuilder.CreatePolyline(polyline5);
  Polyline polyline8 = PolylineBuilder.CreatePolyline(LineBuilder.CreateLineSegment(new Coordinate(5, 5), new Coordinate(10, 10)), SpatialReferences.WGS84);

  segments.Clear();
  segments.Add(LineBuilder.CreateLineSegment(new Coordinate(0.6, 3.5), new Coordinate(0.7, 7)));
  segments.Add(LineBuilder.CreateLineSegment(new Coordinate(0.7, 7), new Coordinate(3, 9)));

  Polyline polyline9 = PolylineBuilder.CreatePolyline(segments, SpatialReferences.WGS84);

  // now do the Related tests

  // Interior/Interior Intersects
  string scl = "T********";
  bool related = GeometryEngine.Relate(polygon, polyline1, scl);     // related = true
  related = GeometryEngine.Relate(point0, point1, scl);              // related = false
  related = GeometryEngine.Relate(point0, multipoint, scl);          // related = true
  related = GeometryEngine.Relate(multipoint, polygon, scl);         // related = true
  related = GeometryEngine.Relate(multipoint, polyline1, scl);       // related = false
  related = GeometryEngine.Relate(polyline2, point2, scl);           // related = false
  related = GeometryEngine.Relate(point1, polygon, scl);             // related = true

  // Interior/Boundary Intersects
  scl = "*T*******";
  related = GeometryEngine.Relate(polygon, polyline2, scl);          // related = true
  related = GeometryEngine.Relate(polygon, polyline3, scl);          // related = false
  related = GeometryEngine.Relate(point1, polygon, scl);             // related = false

  // Boundary/Boundary Interior intersects
  scl = "***T*****";
  related = GeometryEngine.Relate(polygon, polyline4, scl);          // related = true

  // Overlaps Dim1
  scl = "1*T***T**";
  related = GeometryEngine.Relate(polygon, polyline5, scl);          // related = true

  // Crosses Area/Line (LineB crosses PolygonA)
  scl = "1020F1102";
  related = GeometryEngine.Relate(polygon, polyline6, scl);          // related = false
  related = GeometryEngine.Relate(polygon, polyline9, scl);          // related = true

  // Boundary/Boundary Touches
  scl = "F***T****";
  related = GeometryEngine.Relate(polygon, polyline7, scl);          // related = false
  related = GeometryEngine.Relate(polygon, polyline8, scl);          // related = true
});

##Replace NaN Zs in a polygon

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  List<Coordinate> coordsZ = new List<Coordinate>() 
  { 
    new Coordinate(1, 2, double.NaN), 
    new Coordinate(4, 5, 3), 
    new Coordinate(7, 8, double.NaN) 
  };

  Polygon polygon = PolygonBuilder.CreatePolygon(coordsZ);
  // polygon.HasZ = true

  Polygon polygonZReplaced = GeometryEngine.ReplaceNaNZs(polygon, -1) as Polygon;

  // polygonZReplaced.Points[0].Z = -1
  // polygonZReplaced.Points[1].Z = 3
  // polygonZReplaced.Points[2].Z = -1
});

##Reverse the order of points in a Polygon

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  List<Coordinate2D> list2D = new List<Coordinate2D>();
  list2D.Add(new Coordinate2D(1.0, 1.0));
  list2D.Add(new Coordinate2D(1.0, 2.0));
  list2D.Add(new Coordinate2D(2.0, 2.0));
  list2D.Add(new Coordinate2D(2.0, 1.0));

  Polygon polygon = PolygonBuilder.CreatePolygon(list2D);

  Geometry g = GeometryEngine.ReverseOrientation(polygon);
  Polygon gPolygon = g as Polygon;

  // gPolygon.Points[0] = 1.0, 1.0
  // gPolygon.Points[1] = 2.0, 1.0
  // gPolygon.Points[2] = 2.0, 2.0
  // gPolygon.Points[3] = 1.0, 2.0
  // gPolygon.Points[4] = 1.0, 1.0
  // gPolygon.Area = -1 * polygon.Area
});

##Rotate a MapPoint

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint pt = MapPointBuilder.CreateMapPoint(1.0, 3.0);
  MapPoint rotatePt = MapPointBuilder.CreateMapPoint(3.0, 3.0);

  Geometry result = GeometryEngine.Rotate(pt, rotatePt, Math.PI / 2);
  // result point is (3, 1)
});

##Rotate a Polyline

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // rotate a polyline

  MapPoint fixedPt = MapPointBuilder.CreateMapPoint(3.0, 3.0);
  
  List<MapPoint> pts = new List<MapPoint>();
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0));
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 5.0));
  pts.Add(MapPointBuilder.CreateMapPoint(5, 5));
  pts.Add(MapPointBuilder.CreateMapPoint(5.0, 1.0));
  Polyline polyline = PolylineBuilder.CreatePolyline(pts);

  Polyline rotated = GeometryEngine.Rotate(polyline, fixedPt, Math.PI / 4) as Polyline;  // rotate 45 deg
});

##Set all Zs in a polyline

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  List<Coordinate> coordsZ = new List<Coordinate>() 
  { 
    new Coordinate(1, 2, 3), 
    new Coordinate(4, 5, 6), 
    new Coordinate(7, 8, double.NaN) 
  };

  Polyline polyline = PolylineBuilder.CreatePolyline(coordsZ);
  // polyline.HasZ = true

  Polyline polylineSetZ = GeometryEngine.SetConstantZ(polyline, -1) as Polyline;
  // polylineSetZ.Points[0].Z = -1
  // polylineSetZ.Points[1].Z = -1
  // polylineSetZ.Points[2].Z = -1

  polylineSetZ = GeometryEngine.SetConstantZ(polyline, double.NaN) as Polyline;
  // polyline.HasZ = true
  // polylineSetZ.Points[0].HasZ = true
  // polylineSetZ.Points[0].Z = NaN
  // polylineSetZ.Points[1].HasZ = true
  // polylineSetZ.Points[1].Z = NaN
  // polylineSetZ.Points[2].HasZ = true
  // polylineSetZ.Points[2].Z = NaN

  polylineSetZ = GeometryEngine.SetConstantZ(polyline, double.PositiveInfinity) as Polyline;
  // polyline.HasZ = true
  // polylineSetZ.Points[0].HasZ = true
  // polylineSetZ.Points[0].Z = double.PositiveInfinity
  // polylineSetZ.Points[1].HasZ = true
  // polylineSetZ.Points[1].Z = double.PositiveInfinity
  // polylineSetZ.Points[2].HasZ = true
  // polylineSetZ.Points[2].Z = double.PositiveInfinity
});

##Calculate area of geometry on surface of Earth's ellipsoid - ShapePreservingArea

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // pt
  MapPoint pt = MapPointBuilder.CreateMapPoint(1.0, 3.0, SpatialReferences.WebMercator);
  double area = GeometryEngine.ShapePreservingArea(pt);         // area = 0


  List<MapPoint> pts = new List<MapPoint>();
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0, 3.0));
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 3.0, 3.0));
  pts.Add(MapPointBuilder.CreateMapPoint(3, 3, 3.0));
  pts.Add(MapPointBuilder.CreateMapPoint(3.0, 1.0, 3.0));

  // multipoint
  Multipoint mPt = MultipointBuilder.CreateMultipoint(pts);
  area = GeometryEngine.ShapePreservingArea(mPt);               // area = 0

  // polyline
  Polyline polyline = PolylineBuilder.CreatePolyline(pts);
  area = GeometryEngine.ShapePreservingArea(polyline);          // area = 0

  // polygon
  Polygon polygon = PolygonBuilder.CreatePolygon(pts, SpatialReferences.WGS84);
  area = GeometryEngine.ShapePreservingArea(polygon);

  polygon = PolygonBuilder.CreatePolygon(pts, SpatialReferences.WebMercator);
  area = GeometryEngine.ShapePreservingArea(polygon);
});

##Calculate length of geometry on surface of Earth's ellipsoid - ShapePreservingLength

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // pt
  MapPoint pt = MapPointBuilder.CreateMapPoint(1.0, 3.0, SpatialReferences.WebMercator);
  double len = GeometryEngine.ShapePreservingLength(pt);          // len = 0


  List<MapPoint> pts = new List<MapPoint>();
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0, 3.0));
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 3.0, 3.0));
  pts.Add(MapPointBuilder.CreateMapPoint(3, 3, 3.0));
  pts.Add(MapPointBuilder.CreateMapPoint(3.0, 1.0, 3.0));

  // multipoint
  Multipoint mPt = MultipointBuilder.CreateMultipoint(pts);
  len = GeometryEngine.ShapePreservingLength(mPt);                // len = 0

  // polyline
  Polyline polyline = PolylineBuilder.CreatePolyline(pts, SpatialReferences.WGS84);
  len = GeometryEngine.ShapePreservingLength(polyline);

  // polygon
  Polygon polygon = PolygonBuilder.CreatePolygon(pts, SpatialReferences.WGS84);
  len = GeometryEngine.ShapePreservingLength(polygon);
});

##Scale a geometry

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  List<MapPoint> pts = new List<MapPoint>();
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0, 3.0));
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 3.0, 3.0));
  pts.Add(MapPointBuilder.CreateMapPoint(3, 3, 3.0));
  pts.Add(MapPointBuilder.CreateMapPoint(3.0, 1.0, 3.0));

  MapPoint midPt = MapPointBuilder.CreateMapPoint(1.5, 1.5);

  // polyline
  Polyline polyline = PolylineBuilder.CreatePolyline(pts);
  // polyline.Length = 6
  // polyline.Length3D = 0
  Geometry g = GeometryEngine.Scale(polyline, midPt, 0.5, 0.5);
  Polyline resultPolyline = g as Polyline;
  // resultPolyline.length  = 3
  // resultPolyline.Points[0] = 1.25, 1.25, 3
  // resultPolyline.Points[1] = 1.25, 2.25, 3
  // resultPolyline.Points[2] = 2.25, 2.25, 3
  // resultPolyline.Points[3] = 2.25, 1.25, 3

  // 3D point - scale in 3d
  MapPoint midPtZ = MapPointBuilder.CreateMapPoint(1.5, 1.5, 1);
  g = GeometryEngine.Scale(polyline, midPtZ, 0.5, 0.5, 0.25);
  resultPolyline = g as Polyline;
  // resultPolyline.Points[0] = 1.25, 1.25, 1.5
  // resultPolyline.Points[1] = 1.25, 2.25, 1.5
  // resultPolyline.Points[2] = 2.25, 2.25, 1.5
  // resultPolyline.Points[3] = 2.25, 1.25, 1.5

});

##xxxx

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
});

##Simplify a polyline with intersections, overlaps

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  List<Coordinate> coords = new List<Coordinate>()
  {
    new Coordinate(8, 0),
    new Coordinate(8, 4),
    new Coordinate(6, 4),
    new Coordinate(8, 4),
    new Coordinate(10, 4),
    new Coordinate(8, 4)
  };

  SpatialReference sr = SpatialReferences.WGS84;

  // build a line that has segments that cross over each other
  Polyline polyline = PolylineBuilder.CreatePolyline(coords, sr);
  // polyline.PartCount = 1
  ReadOnlyPartCollection parts = polyline.Parts;
  ReadOnlySegmentCollection segments = parts[0];
  // segments.Count = 5

  //  note there is a difference between SimpleAsFeature (doesn't detect intersections and overlaps, determines if it's simple enough for gdb storage)
  //  and SimplifyPolyline  (does detect intersections etc)
  bool isSimple = GeometryEngine.IsSimpleAsFeature(polyline, false);
  // isSimple = true

  // simplify it (with force = false)
  // because it has already been deemed 'simple' (previous IsSimpleAsFeature call) no detection of intersections, overlaps occur
  Polyline simplePolyline = GeometryEngine.SimplifyPolyline(polyline, SimplifyType.Planar, false);
  // simplePolyline.PartCount = 1
  ReadOnlyPartCollection simpleParts = simplePolyline.Parts;
  ReadOnlySegmentCollection simpleSegments = simpleParts[0];
  // simpleSegments.Count = 5

  // simplify it (with force = true)
  // detection of intersections, overlaps occur 
  simplePolyline = GeometryEngine.SimplifyPolyline(polyline, SimplifyType.Planar, true);
  // simplePolyline.PartCount = 3
  simpleParts = simplePolyline.Parts;
  simpleSegments = simpleParts[0];
  // simpleSegments.Count = 1
});

##Polygon touches another Polygon

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // two disjoint polygons
  Envelope env = EnvelopeBuilder.CreateEnvelope(MapPointBuilder.CreateMapPoint(4.0, 4.0), MapPointBuilder.CreateMapPoint(8, 8));
  Polygon poly1 = PolygonBuilder.CreatePolygon(env);

  Envelope env2 = EnvelopeBuilder.CreateEnvelope(MapPointBuilder.CreateMapPoint(1.0, 1.0), MapPointBuilder.CreateMapPoint(5, 5));
  Polygon poly2 = PolygonBuilder.CreatePolygon(env2);

  bool touches = GeometryEngine.Touches(poly1, poly2);    // touches = false

  // another polygon that touches the first
  Envelope env3 = EnvelopeBuilder.CreateEnvelope(MapPointBuilder.CreateMapPoint(1.0, 1.0), MapPointBuilder.CreateMapPoint(4, 4));
  Polygon poly3 = PolygonBuilder.CreatePolygon(env3);

  touches = GeometryEngine.Touches(poly1, poly3);         // touches = true
});

##Union two MapPoints - creates a Multipoint

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  MapPoint pt1 = MapPointBuilder.CreateMapPoint(1.0, 1.0);
  MapPoint pt2 = MapPointBuilder.CreateMapPoint(2.0, 2.5);

  Geometry geometry = GeometryEngine.Union(pt1, pt2);
  Multipoint multipoint = geometry as Multipoint;   // multipoint has point count of 2
});

##Union two Polygons

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // union two polygons

  List<MapPoint> polyPts = new List<MapPoint>();
  polyPts.Add(MapPointBuilder.CreateMapPoint(3.0, 2.0));
  polyPts.Add(MapPointBuilder.CreateMapPoint(3.0, 6.0));
  polyPts.Add(MapPointBuilder.CreateMapPoint(6.0, 6.0));
  polyPts.Add(MapPointBuilder.CreateMapPoint(6.0, 2.0));

  Polygon poly1 = PolygonBuilder.CreatePolygon(polyPts);
  bool isSimple = GeometryEngine.IsSimpleAsFeature(poly1);

  Envelope env = EnvelopeBuilder.CreateEnvelope(MapPointBuilder.CreateMapPoint(4.0, 4.0), MapPointBuilder.CreateMapPoint(8, 8));
  Polygon poly2 = PolygonBuilder.CreatePolygon(env);
  isSimple = GeometryEngine.IsSimpleAsFeature(poly2);

  Geometry g = GeometryEngine.Union(poly1, poly2);
  Polygon polyResult = g as Polygon;
});

##Union many Polylines

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // union many polylines

  List<Coordinate2D> coords = new List<Coordinate2D>()
  {
    new Coordinate2D(1, 2), new Coordinate2D(3, 4), new Coordinate2D(4, 2),
    new Coordinate2D(5, 6), new Coordinate2D(7, 8), new Coordinate2D(8, 4),
    new Coordinate2D(9, 10), new Coordinate2D(11, 12), new Coordinate2D(12, 8),
    new Coordinate2D(10, 8), new Coordinate2D(12, 12), new Coordinate2D(14, 10)
  };

  // create Disjoint lines
  List<Polyline> manyLines = new List<Polyline>
  {
    PolylineBuilder.CreatePolyline(new List<Coordinate2D>(){coords[0], coords[1], coords[2]}, SpatialReferences.WGS84),
    PolylineBuilder.CreatePolyline(new List<Coordinate2D>(){coords[3], coords[4], coords[5]}),
    PolylineBuilder.CreatePolyline(new List<Coordinate2D>(){coords[6], coords[7], coords[8]})
  };

  Polyline polyline = GeometryEngine.Union(manyLines) as Polyline;
});

##Union many Polygons

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // union many polygons

  List<Coordinate> coordsZ = new List<Coordinate>()
  {
    new Coordinate(1, 2, 0), new Coordinate(3, 4, 1), new Coordinate(4, 2, 2),
    new Coordinate(5, 6, 3), new Coordinate(7, 8, 4), new Coordinate(8, 4, 5),
    new Coordinate(9, 10, 6), new Coordinate(11, 12, 7), new Coordinate(12, 8, 8),
    new Coordinate(10, 8, 9), new Coordinate(12, 12, 10), new Coordinate(14, 10, 11)
  };

  // create polygons
  List<Polygon> manyPolygonsZ = new List<Polygon>
  {
    PolygonBuilder.CreatePolygon(new List<Coordinate>(){coordsZ[0], coordsZ[1], coordsZ[2]}, SpatialReferences.WGS84),
    PolygonBuilder.CreatePolygon(new List<Coordinate>(){coordsZ[3], coordsZ[4], coordsZ[5]}),
    PolygonBuilder.CreatePolygon(new List<Coordinate>(){coordsZ[6], coordsZ[7], coordsZ[8]})
  };

  Polygon polygon = GeometryEngine.Union(manyPolygonsZ) as Polygon;
});

##MapPoints, Polylines, Polygons within Polygon

// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // build a polygon      
  List<MapPoint> pts = new List<MapPoint>();
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0));
  pts.Add(MapPointBuilder.CreateMapPoint(1.0, 2.0));
  pts.Add(MapPointBuilder.CreateMapPoint(2.0, 2.0));
  pts.Add(MapPointBuilder.CreateMapPoint(2.0, 1.0));

  Polygon poly = PolygonBuilder.CreatePolygon(pts);

  // an inner point
  MapPoint innerPt = MapPointBuilder.CreateMapPoint(1.5, 1.5);
  bool within = GeometryEngine.Within(innerPt, poly);   // within = true

  // point on a boundary
  within = GeometryEngine.Within(pts[0], poly);     // within = false

  // an interior line
  MapPoint innerPt2 = MapPointBuilder.CreateMapPoint(1.25, 1.75);
  List<MapPoint> innerLinePts = new List<MapPoint>();
  innerLinePts.Add(innerPt);
  innerLinePts.Add(innerPt2);

  Polyline polyline = PolylineBuilder.CreatePolyline(innerLinePts);
  within = GeometryEngine.Within(polyline, poly);   // within = true

  // a line that crosses the boundary
  MapPoint outerPt = MapPointBuilder.CreateMapPoint(3, 1.5);
  List<MapPoint> crossingLinePts = new List<MapPoint>();
  crossingLinePts.Add(innerPt);
  crossingLinePts.Add(outerPt);

  polyline = PolylineBuilder.CreatePolyline(crossingLinePts);
  within = GeometryEngine.Within(polyline, poly);     // within = false


  // polygon in polygon
  Envelope env = EnvelopeBuilder.CreateEnvelope(innerPt, innerPt2);
  within = GeometryEngine.Within(env, poly);      // within = true
});

##Create Geographic Transformation

// create from wkid
GeographicTransformation gt1478 = ArcGIS.Core.Geometry.GeographicTransformation.Create(1478);
string name = gt1478.Name;
string wkt = gt1478.Wkt;

// create from wkt
GeographicTransformation another_gt1478 = ArcGIS.Core.Geometry.GeographicTransformation.Create(wkt);

// inverse
GeographicTransformation inverse_gt148 = another_gt1478.GetInverse() as GeographicTransformation;
bool isForward = inverse_gt148.IsForward;

##Create Composite Geographic Transformation

// Create singleton from wkid
CompositeGeographicTransformation cgt = ArcGIS.Core.Geometry.CompositeGeographicTransformation.Create(108272);
int count = cgt.Count;    // count = 1

IList<GeographicTransformation> gts = cgt.Transformations as IList<GeographicTransformation>;
gts.Add(ArcGIS.Core.Geometry.GeographicTransformation.Create(1437, false));
count = cgt.Count;        // count = 2

// create from an enumeration
CompositeGeographicTransformation another_cgt = ArcGIS.Core.Geometry.CompositeGeographicTransformation.Create(gts);
GeographicTransformation gt0 = another_cgt[0];
GeographicTransformation gt1 = another_cgt[1];

// get the inverse
CompositeGeographicTransformation inversed_cgt = another_cgt.GetInverse() as CompositeGeographicTransformation;
// inversed_cgt[0] is same as gt1
// inversed_cgt[1] is same as gt0

##Create Projection Transformation

// methods need to be on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  SpatialReference sr4267 = SpatialReferenceBuilder.CreateSpatialReference(4267);
  SpatialReference sr4326 = SpatialReferences.WGS84;
  SpatialReference sr3857 = SpatialReferences.WebMercator;

  // Create transformation from  4267 -> 3857
  ProjectionTransformation projTransFromSRs = ArcGIS.Core.Geometry.ProjectionTransformation.Create(sr4267, sr3857);

  // create an envelope
  Envelope env = EnvelopeBuilder.CreateEnvelope(new Coordinate2D(2, 2), new Coordinate2D(3, 3), sr4267);

  // Project with one geo transform 4267 -> 3857
  Envelope projectedEnvEx = GeometryEngine.ProjectEx(env, projTransFromSRs) as Envelope;

  // Create inverse transformation, 3857 -> 4267
  ProjectionTransformation projTransFromSRsInverse = ArcGIS.Core.Geometry.ProjectionTransformation.Create(sr3857, sr4267);
  // Project the projected envelope back using the inverse transformation
  Envelope projectedEnvBack = GeometryEngine.ProjectEx(projectedEnvEx, projTransFromSRsInverse) as Envelope;

  bool isEqual = env.IsEqual(projectedEnvBack);
});

##Create HV Datum Transformation

// Create from wkid
HVDatumTransformation hv110018 = HVDatumTransformation.Create(110018);
int wkid = hv110018.Wkid;
bool isForward = hv110018.IsForward;    // isForward = true
string name = hv110018.Name;            // Name = WGS_1984_To_WGS_1984_EGM2008_1x1_Height

// Create from wkt
string wkt = hv110018.Wkt;
HVDatumTransformation hv110018FromWkt = HVDatumTransformation.Create(wkt);

// Get the inverse
HVDatumTransformation hv110018Inverse = hv110018.GetInverse() as HVDatumTransformation;
// hv110018Inverse.IsForward = false

##Create Composite HV Datum Transformation

HVDatumTransformation hv1 = HVDatumTransformation.Create(108034);
HVDatumTransformation hv2 = HVDatumTransformation.Create(108033, false);
List<HVDatumTransformation> hvs = new List<HVDatumTransformation>() { hv1, hv2 };

// create from enumeration
CompositeHVDatumTransformation compositehv = CompositeHVDatumTransformation.Create(hvs);
int count = compositehv.Count;      // count = 2

List<HVDatumTransformation> transforms = compositehv.Transformations as List<HVDatumTransformation>;
HVDatumTransformation tranform = transforms[0];
// transform.Wkid = 108034

string xml = compositehv.ToXML();

// create from xml
CompositeHVDatumTransformation another_compositehv = CompositeHVDatumTransformation.CreateFromXML(xml);

// get inverse
CompositeHVDatumTransformation inverse_compositehv = another_compositehv.GetInverse() as CompositeHVDatumTransformation;

##MapPoint - GeoCoordinateString Conversion

// methods need to be on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  SpatialReference sr = SpatialReferences.WGS84;
  SpatialReference sr2 = SpatialReferences.WebMercator;

  // create some points
  MapPoint point0 = MapPointBuilder.CreateMapPoint(0, 0, sr);
  MapPoint point1 = MapPointBuilder.CreateMapPoint(10, 20, sr);
  MapPoint point2 = GeometryEngine.Project(point1, sr2) as MapPoint;
  MapPoint pointEmpty = MapPointBuilder.CreateMapPoint(sr);
  MapPoint pointwithNoSR = MapPointBuilder.CreateMapPoint(1, 1);
  MapPoint pointZM = MapPointBuilder.CreateMapPoint(1, 2, 3, 4, sr);

  // convert to MGRS
  ToGeoCoordinateParameter mgrsParam = new ToGeoCoordinateParameter(GeoCoordinateType.MGRS);
  string geoCoordString = point0.ToGeoCoordinateString(mgrsParam);        // 31NAA6602100000

  // use the builder to create a new point from the string.  Coordinates are the same 
  MapPoint outPoint = MapPointBuilder.FromGeoCoordinateString(geoCoordString, sr, GeoCoordinateType.MGRS);    // outPoint.x = 0; outPoint.Y = 0

  geoCoordString = point1.ToGeoCoordinateString(mgrsParam);             // 32QPH0460911794
  outPoint = MapPointBuilder.FromGeoCoordinateString(geoCoordString, sr, GeoCoordinateType.MGRS);       // outPoint.X = 10; outPoint.Y = 20

  // z, m are not transformed
  geoCoordString = pointZM.ToGeoCoordinateString(mgrsParam);
  outPoint = MapPointBuilder.FromGeoCoordinateString(geoCoordString, sr, GeoCoordinateType.MGRS);     // outPoint.X = 1; outPoint.Y = 2; outPoint.Z = Nan; outPoint.M = Nan;

  // set the number of digits to 2 and convert
  mgrsParam.NumDigits = 2;
  geoCoordString = point1.ToGeoCoordinateString(mgrsParam);             // 32QPH0512
  outPoint = MapPointBuilder.FromGeoCoordinateString(geoCoordString, sr, GeoCoordinateType.MGRS);     // outPoint.X = 10; outPoint.Y = 20


  // convert to UTM
  ToGeoCoordinateParameter utmParam = new ToGeoCoordinateParameter(GeoCoordinateType.UTM);
  geoCoordString = point0.ToGeoCoordinateString(utmParam);        // 31N 166021 0000000
  geoCoordString = point1.ToGeoCoordinateString(utmParam);        // 32Q 604609 2211793

  // convert to DMS
  ToGeoCoordinateParameter dmsParam = new ToGeoCoordinateParameter(GeoCoordinateType.DMS);
  geoCoordString = point0.ToGeoCoordinateString(dmsParam);        // 00 00 00.00N 000 00 00.00E
  geoCoordString = point1.ToGeoCoordinateString(dmsParam);        // 20 00 00.00N 010 00 00.00E

  // convert to DDM
  ToGeoCoordinateParameter ddmParam = new ToGeoCoordinateParameter(GeoCoordinateType.DDM);
  geoCoordString = point0.ToGeoCoordinateString(ddmParam);        // 00 00.0000N 000 00.0000E
  geoCoordString = point1.ToGeoCoordinateString(ddmParam);        // 20 00.0000N 010 00.0000E

  // convert to DD
  ToGeoCoordinateParameter ddParam = new ToGeoCoordinateParameter(GeoCoordinateType.DD);
  geoCoordString = point0.ToGeoCoordinateString(ddParam);       // 00.000000N 000.000000E
  geoCoordString = point1.ToGeoCoordinateString(ddParam);       // 20.000000N 010.000000E
});

##AngularUnit - Convert between degrees and radians

// convert 45 degrees to radians
double radians = AngularUnit.Degrees.ConvertToRadians(45);

// convert PI to degrees
double degrees = AngularUnit.Degrees.ConvertFromRadians(Math.PI);

##AngularUnit - Create an AngularUnit with a factory code

try
{
  // create a Grad unit
  var grad = AngularUnit.CreateAngularUnit(9105);
  string unitName = grad.Name;                        // Grad
  double conversionFactor = grad.ConversionFactor;    // 0.015708
  double radiansPerUnit = grad.RadiansPerUnit;
  int factoryCode = grad.FactoryCode;                 // 9105

  // convert 10 grads to degrees
  double val = grad.ConvertTo(10, AngularUnit.Degrees);

  // convert 10 radians to grads
  val = grad.ConvertFromRadians(10);
}
catch (ArgumentException)
{
  // ArgumentException will be thrown by CreateAngularUnit in the following scenarios
  // - if the factory code used is a non-angular factory code  (i.e. it corresponds to square meters which is an area unit code)
  // - if the factory code used is invalid (i.e. it is negative or doesn't correspond to any factory code)
}

##AngularUnit - Create a Custom AngularUnit

// custom unit - 3 radians per unit
var myAngularUnit = AngularUnit.CreateAngularUnit("myCustomAngularUnit", 3);
string Name = myAngularUnit.Name;               // myCustomAngularUnit
double Factor = myAngularUnit.ConversionFactor;   // 3
int Code = myAngularUnit.FactoryCode;             // 0 because it is a custom angular unit
double radiansUnit = myAngularUnit.RadiansPerUnit; // 3

// convert 10 degrees to my unit
double converted = AngularUnit.Degrees.ConvertTo(10, myAngularUnit);
// convert it back to degrees
converted = myAngularUnit.ConvertTo(converted, AngularUnit.Degrees);

// convert 1 radian into my angular units
converted = myAngularUnit.ConvertFromRadians(1);

##LinearUnit - Convert between feet and meters

// convert 10 feet to meters
double metres = LinearUnit.Feet.ConvertToMeters(10);

// convert 20 meters to feet
double feet = LinearUnit.Feet.ConvertFromMeters(20.0);

##LinearUnit - Convert between centimeters and millimeters

// convert 11 centimeters to millimeters
double mm = LinearUnit.Centimeters.ConvertTo(11, LinearUnit.Millimeters);

// convert the result back to centimeters
double cm = LinearUnit.Millimeters.ConvertTo(mm, LinearUnit.Centimeters);

// convert the millimeter result back to meters
double meters = LinearUnit.Millimeters.ConvertToMeters(mm);

##LinearUnit - Create a LinearUnit with a factory code

try
{
  // create a british 1936 foot
  var britFoot = LinearUnit.CreateLinearUnit(9095);
  string unitName = britFoot.Name;                        //  "Foot_British_1936"
  double conversionFactor = britFoot.ConversionFactor;    // 0.3048007491
  double metersPerUnit = britFoot.MetersPerUnit;
  int factoryCode = britFoot.FactoryCode;                 // 9095

  // convert 10 british 1936 feet to centimeters
  double val = britFoot.ConvertTo(10, LinearUnit.Centimeters);

  // convert 10 m to british 1936 feet
  val = britFoot.ConvertFromMeters(10);
}
catch (ArgumentException)
{
  // ArgumentException will be thrown by CreateLinearUnit in the following scenarios
  // - if the factory code used is a non-linear factory code  (i.e. it corresponds to square meters which is an area unit code)
  // - if the factory code used is invalid (i.e. it is negative or doesn't correspond to any factory code)
}

##LinearUnit - Create a Custom LinearUnit

// create a custom linear unit - there are 0.33 meters per myLinearUnit
var myLinearUnit = LinearUnit.CreateLinearUnit("myCustomLinearUnit", 0.33);
string name = myLinearUnit.Name;                          // myCustomLinearUnit
double convFactor = myLinearUnit.ConversionFactor;        // 0.33
int code = myLinearUnit.FactoryCode;                      // 0 for custom units
double metersUnit = myLinearUnit.MetersPerUnit;           // 0.33
string toString = myLinearUnit.ToString();                // same as Name - myCustomLinearUnit

// convert 10 centimeters to myLinearUnit 
double convertedVal = LinearUnit.Centimeters.ConvertTo(10, myLinearUnit);

##LinearUnit - Convert to AreaUnit

try
{
  // convert metres to area unit
  AreaUnit areaUnit = LinearUnit.Meters.ConvertToAreaUnit();
  double factor = areaUnit.ConversionFactor;             // 1.0
  string areaName = areaUnit.Name;                        // Square_Meter
  UnitType unitType = areaUnit.UnitType;                  // UnitType.Area

  // convert back again
  LinearUnit linearUnit = LinearUnit.CreateFromAreaUnit(areaUnit);
}
catch (ArgumentException)
{
}

##AreaUnit - Convert between square feet and square meters

// convert 700 square meters to square feet
double sqFeet = AreaUnit.SquareFeet.ConvertFromSquareMeters(700);

// convert 1100 square feet to square meters
double sqMeters = AreaUnit.SquareFeet.ConvertToSquareMeters(1000);

##AreaUnit - Convert between hectares and acres

// convert 2 hectares to acres
double acres = AreaUnit.Hectares.ConvertTo(2, AreaUnit.Acres);

##AreaUnit - Convert between hectares and square miles

// convert 300 hectares to square miles
double sqMiles = AreaUnit.Hectares.ConvertTo(300, AreaUnit.SquareMiles);

##AreaUnit - Convert to LinearUnit

try
{
  // convert square meters to linear unit 
  LinearUnit linearUnit = AreaUnit.SquareMeters.ConvertToLinearUnit();
  double factor = linearUnit.ConversionFactor;             
  string linearName = linearUnit.Name;                        
  UnitType unitType = linearUnit.UnitType;                  

  // convert back again
  AreaUnit areaUnit = AreaUnit.CreateFromLinearUnit(linearUnit);
  double SqMetersPerUnit = areaUnit.SquareMetersPerUnit;

}
catch (ArgumentException)
{
}

Home

ProSnippets: Geometry

Clone this wiki locally