ProSnippets Geometry - Esri/arcgis-pro-sdk GitHub Wiki

Language:              C#  
Subject:               Geometry  
Contributor:           ArcGIS Pro SDK Team <[email protected]>  
Organization:          Esri, http://www.esri.com  
Date:                  11/7/2025  
ArcGIS Pro:            3.6  
Visual Studio:         2022  

SpatialReference

Construct a SpatialReference - from a well-known ID

// Use a builder convenience method or use a builder constructor.

  // SpatialReferenceBuilder convenience methods don't need to run on the MCT.
  SpatialReference sr3857 = SpatialReferenceBuilder.CreateSpatialReference(3857);

  // SpatialReferenceBuilder constructors need to run on the MCT.
  ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
  {
    using (SpatialReferenceBuilder srBuilder = new SpatialReferenceBuilder(3857))
    {
      // do something with the builder

      sr3857 = srBuilder.ToSpatialReference();
    }
  });

Construct a SpatialReference - from a string

// Use a builder convenience method or use a builder constructor.

  string wkt = "GEOGCS[\"MyGCS84\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Radian\",1.0]]";

  // SpatialReferenceBuilder convenience methods don't need to run on the MCT.
  SpatialReference sr = SpatialReferenceBuilder.CreateSpatialReference(wkt);

  // SpatialReferenceBuilder constructors need to run on the MCT.
  ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
  {
    using (SpatialReferenceBuilder builder = new SpatialReferenceBuilder(wkt))
    {
      // do something with the builder
      SpatialReference anotherSR = builder.ToSpatialReference();
    }
  });

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

// Use a builder convenience method or use a builder constructor.
  // see a list of vertical coordinate systems at http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#/Vertical_coordinate_systems/02r3000000rn000000/

  // Builder convenience methods don't need to run on the MCT.
  // 4326 = GCS_WGS_1984
  // 115700 = vertical WGS_1984
  SpatialReference sr4326_115700 = SpatialReferenceBuilder.CreateSpatialReference(4326, 115700);

  // SpatialReferenceBuilder constructors need to run on the MCT.
  ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
  {
    using (SpatialReferenceBuilder sb = new SpatialReferenceBuilder(4326, 115700))
    {
      // SpatialReferenceBuilder properties
      //   sb.wkid == 4326
      //   sb.Wkt == "GEOGCS["MyGCS84",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT[\"Radian\",1.0]]"
      //   sb.name == GCS_WGS_1984
      //   sb.vcsWkid == 115700
      //   sb.VcsWkt == "VERTCS["WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PARAMETER["Vertical_Shift",0.0],PARAMETER["Direction",1.0],UNIT["Meter",1.0]]

      // do something with the builder

      sr4326_115700 = sb.ToSpatialReference();
    }
  });

Construct a SpatialReference with a vertical coordinate system - from a string

// Use a builder convenience method or use a builder constructor.

  // 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]]";

  // Builder convenience methods don't need to run on the MCT.
  SpatialReference sr4326_customVertical = SpatialReferenceBuilder.CreateSpatialReference(4326, custom_vWkt);
  // SpatialReferenceBuilder properties
  //   sr4326_customVertical.wkid == 4326
  //   sr4326_customVertical.vert_wkid == 0
  //   sr4326_customVertical.vert_wkt == custom_vWkt
  //   sr4326_customVertical.hasVcs == true

  // SpatialReferenceBuilder constructors need to run on the MCT.
  ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
  {
    using (SpatialReferenceBuilder sb = new SpatialReferenceBuilder(4326, custom_vWkt))
    {
      // do something with the builder

      sr4326_customVertical = sb.ToSpatialReference();
    }
  });

Construct a SpatialReference with a custom PCS - from a string

// Use a builder convenience method or use a builder constructor.

  // Custom PCS, Predefined GCS
  string customWkt = "PROJCS[\"WebMercatorMile\",GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Mercator_Auxiliary_Sphere\"],PARAMETER[\"False_Easting\",0.0],PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",0.0],PARAMETER[\"Standard_Parallel_1\",0.0],PARAMETER[\"Auxiliary_Sphere_Type\",0.0],UNIT[\"Mile\",1609.344000614692]]";

  // Builder convenience methods don't need to run on the MCT.
  SpatialReference spatialReference = SpatialReferenceBuilder.CreateSpatialReference(customWkt);
  // SpatialReferenceBuilder properties
  //   spatialReference.Wkt == customWkt
  //   spatialReference.Wkid == 0
  //   spatialReference.VcsWkid == 0
  //   spatialReference.GcsWkid == 4326

  SpatialReference gcs = spatialReference.Gcs;
  // gcs.Wkid == 4326
  // gcs.IsGeographic == true
  // spatialReference.GcsWkt == gcs.Wkt

  // SpatialReferenceBuilder constructors need to run on the MCT.
  ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
  {
    using (SpatialReferenceBuilder sb = new SpatialReferenceBuilder(customWkt))
    {
      // do something with the builder

      spatialReference = sb.ToSpatialReference();
    }
  });

SpatialReference Properties

// SpatialReferenceBuilder constructors need to run on the MCT.
  ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
  {
    // use the builder constructor
    using (SpatialReferenceBuilder srBuilder = new SpatialReferenceBuilder(3857))
    {
      // spatial reference builder properties
      int builderWkid = srBuilder.Wkid;
      string builderWkt = srBuilder.Wkt;
      string builderName = 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
      int srWkid = sr3857.Wkid;
      string srWkt = sr3857.Wkt;
      string srName = 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;

      bool hasVcs = sr3857.HasVcs;
    }
  });

SpatialReference WKT2

SpatialReference sr = SpatialReferences.WebMercator;

  // Get Esri WKT
  string wkt = sr.Wkt;
  /*
    PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",
     GEOGCS["GCS_WGS_1984",
      DATUM["D_WGS_1984",
       SPHEROID["WGS_1984", 6378137.0, 298.257223563]],
      PRIMEM["Greenwich", 0.0],
      UNIT["Degree", 0.0174532925199433]],
     PROJECTION["Mercator_Auxiliary_Sphere"],
     PARAMETER["False_Easting", 0.0],
     PARAMETER["False_Northing", 0.0],
     PARAMETER["Central_Meridian", 0.0],
     PARAMETER["Standard_Parallel_1", 0.0],
     PARAMETER["Auxiliary_Sphere_Type", 0.0],
     UNIT["Meter", 1.0]]
  */

  // Get OGC WKT2
  string wkt2 = sr.GetWkt2(WktFormatMode.None);
  /*
    PROJCRS["WGS_1984_Web_Mercator_Auxiliary_Sphere",
     BASEGEOGCRS["GCS_WGS_1984",
      DYNAMIC[FRAMEEPOCH[1990.5], MODEL["AM0-2"]],
      DATUM["D_WGS_1984",
       ELLIPSOID["WGS_1984", 6378137.0, 298.257223563, LENGTHUNIT["Meter", 1.0]]],
      PRIMEM["Greenwich", 0.0, ANGLEUNIT["Degree", 0.0174532925199433]],
      CS[ellipsoidal, 2],
      AXIS["Latitude (lat)", north, ORDER[1]],
      AXIS["Longitude (lon)", east, ORDER[2]],
      ANGLEUNIT["Degree", 0.0174532925199433]],
     CONVERSION["Mercator_Auxiliary_Sphere",
      METHOD["Mercator_Auxiliary_Sphere"],
      PARAMETER["False_Easting", 0.0, LENGTHUNIT["Meter", 1.0]],
      PARAMETER["False_Northing", 0.0, LENGTHUNIT["Meter", 1.0]],
      PARAMETER["Central_Meridian", 0.0, ANGLEUNIT["Degree", 0.0174532925199433]],
      PARAMETER["Standard_Parallel_1", 0.0, ANGLEUNIT["Degree", 0.0174532925199433]],
      PARAMETER["Auxiliary_Sphere_Type", 0.0]],
     CS[Cartesian, 2],
     AXIS["Easting (X)", east, ORDER[1]],
     AXIS["Northing (Y)", north, ORDER[2]],
     LENGTHUNIT["Meter", 1.0]]
  */

  // You can create a spatial reference with the Esri WKT string or the OCG WKT2 string
  sr = SpatialReferenceBuilder.CreateSpatialReference(wkt2);

  // Get OGC WKT2 including authority in top-level objects
  // In this case the authority is written as ID["EPSG",3857]
  wkt2 = sr.GetWkt2(WktFormatMode.AuthorityTop);
  /*  
    PROJCRS["WGS_1984_Web_Mercator_Auxiliary_Sphere",
     BASEGEOGCRS["GCS_WGS_1984",
     DYNAMIC[FRAMEEPOCH[1990.5],MODEL["AM0-2"]],
     DATUM["D_WGS_1984",
      ELLIPSOID["WGS_1984",6378137.0,298.257223563,LENGTHUNIT["Meter",1.0]]],
     PRIMEM["Greenwich",0.0,ANGLEUNIT["Degree",0.017453292519943295]],
     CS[ellipsoidal,2],
     AXIS["Latitude (lat)",north,ORDER[1]],
     AXIS["Longitude(lon)",east,ORDER[2]],
     ANGLEUNIT["Degree",0.017453292519943295]],
     CONVERSION["Mercator_Auxiliary_Sphere",
      METHOD["Mercator_Auxiliary_Sphere"],
      PARAMETER["False_Easting",0.0,LENGTHUNIT["Meter",1.0]],
      PARAMETER["False_Northing",0.0,LENGTHUNIT["Meter",1.0]],
      PARAMETER["Central_Meridian",0.0,ANGLEUNIT["Degree",0.017453292519943295]],
      PARAMETER["Standard_Parallel_1",0.0,ANGLEUNIT["Degree",0.017453292519943295]],
      PARAMETER["Auxiliary_Sphere_Type",0.0]],
      CS[Cartesian,2],
      AXIS["Easting (X)",east,ORDER[1]],
      AXIS["Northing (Y)",north,ORDER[2]],
      LENGTHUNIT["Meter",1.0],
      ID["EPSG",3857]]
  */

  // Get OGC WKT2 including authority in all objects
  // Authority is written as ID["ESPG",<id>] or ID["Esri",<id>]
  wkt2 = sr.GetWkt2(WktFormatMode.AuthorityAll);
  /*
    PROJCRS["WGS_1984_Web_Mercator_Auxiliary_Sphere",
     BASEGEOGCRS["GCS_WGS_1984",
      DYNAMIC[FRAMEEPOCH[1990.5],MODEL["AM0-2"]],
      DATUM["D_WGS_1984",
       ELLIPSOID["WGS_1984",6378137.0,298.257223563,LENGTHUNIT["Meter",1.0,ID["EPSG",9001]],ID["EPSG",7030]],
       ID["EPSG",6326]],
      PRIMEM["Greenwich",0.0,ANGLEUNIT["Degree",0.017453292519943295,ID["EPSG",9102]],ID["EPSG",8901]],
      CS[ellipsoidal,2],
      AXIS["Latitude (lat)",north,ORDER[1]],
      AXIS["Longitude(lon)",east,ORDER[2]],
      ANGLEUNIT["Degree",0.017453292519943295,ID["EPSG",9102]],ID["EPSG",4326]],
      CONVERSION["Mercator_Auxiliary_Sphere",
       METHOD["Mercator_Auxiliary_Sphere",ID["Esri",43104]],
       PARAMETER["False_Easting",0.0,LENGTHUNIT["Meter",1.0,ID["EPSG",9001]],ID["Esri",100001]],
       PARAMETER["False_Northing",0.0,LENGTHUNIT["Meter",1.0,ID["EPSG",9001]],ID["Esri",100002]],
       PARAMETER["Central_Meridian",0.0,ANGLEUNIT["Degree",0.017453292519943295,ID["EPSG",9102]],ID["Esri",100010]],
       PARAMETER["Standard_Parallel_1",0.0,ANGLEUNIT["Degree",0.017453292519943295,ID["EPSG",9102]],ID["Esri",100025]],
       PARAMETER["Auxiliary_Sphere_Type",0.0,ID["Esri",100035]]],
      CS[Cartesian,2],
      AXIS["Easting(X)",east,ORDER[1]],
      AXIS["Northing (Y)",north,ORDER[2]],
      LENGTHUNIT["Meter",1.0,ID["EPSG",9001]],
      ID["EPSG",3857]]
  */

Import and Export Spatial Reference

SpatialReference srWithVertical = SpatialReferenceBuilder.CreateSpatialReference(4326, 6916);

  string xml = srWithVertical.ToXml();
  SpatialReference importedSR = SpatialReferenceBuilder.FromXml(xml);
  // importedSR.Wkid = 4326
  // importedSR.VcsWkid = 6916

  string json = srWithVertical.ToJson();
  importedSR = SpatialReferenceBuilder.FromJson(json);
  // importedSR.Wkid = 4326
  // importedSR.VcsWkid = 6916

Determine grid convergence for a SpatialReference at a given point

Coordinate2D coordinate = new Coordinate2D(10, 30);
  double angle = SpatialReferences.WGS84.GetConvergenceAngle(coordinate);
  // angle = 0

  SpatialReference srUTM30N = SpatialReferenceBuilder.CreateSpatialReference(32630);
  coordinate.X = 500000;
  coordinate.Y = 550000;
  angle = srUTM30N.GetConvergenceAngle(coordinate);
  // angle = 0

  MapPoint pointWGS84 = MapPointBuilderEx.CreateMapPoint(10, 50, SpatialReferences.WGS84);
  MapPoint pointUTM30N = GeometryEngine.Instance.Project(
    pointWGS84, srUTM30N) as MapPoint;

  coordinate = (Coordinate2D)pointUTM30N;
  // get convergence angle and convert to degrees
  angle = srUTM30N.GetConvergenceAngle(coordinate) * 180 / Math.PI;
  // angle = 10.03

Datum

var cimMapDefinition = MapView.Active.Map.GetDefinition();
  // use if map's sr does not have a vertical coordinate system
  var datumTransformations = cimMapDefinition.DatumTransforms;
  // use if map's sr has a vertical coordinate system
  var hvDatumTransformations = cimMapDefinition.HVDatumTransforms;

SpatialReference Datum and datum properties

// Get datum of a spatial reference
  SpatialReference srWgs84 = SpatialReferences.WGS84;
  Datum datum = srWgs84.Datum;
  // datum.Name = "D_WGS_1984"
  // datum.Wkid = 6326
  // datum.SpheroidName = "WGS_1984"
  // datum.SpheroidWkid = 7030
  // datum.SpheroidFlattening = 0.0033528106647474805
  // datum.SpheroidSemiMajorAxis = 6378137.0
  // datum.SpheroidSemiMinorAxis = 6356752.3142451793

  // Custom WKT
  string wyomingWkt = "PROJCS[\"Wyoming_State_Pl_NAD_1927\",GEOGCS[\"GCS_North_American_1927\",DATUM[\"D_North_American_1927_Perry\",SPHEROID[\"Clarke_1866_Chase\",6378210.0,250.0]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"false_easting\",500000.0],PARAMETER[\"false_northing\",0.0],PARAMETER[\"central_meridian\",-107.3333333],PARAMETER[\"scale_factor\",0.9999412],PARAMETER[\"latitude_of_origin\",40.66666667],UNIT[\"Foot_US\",0.3048006096012192]]";
  SpatialReference srFromWkt = SpatialReferenceBuilder.CreateSpatialReference(wyomingWkt);
  datum = srWgs84.Datum;
  // datum.Name = "D_North_American_1927_Perry"
  // datum.Wkid = 0
  // datum.SpheroidName = "Clarke_1866_Chase"
  // datum.SpheroidWkid = 0
  // datum.SpheroidFlattening = 0.004
  // datum.SpheroidSemiMajorAxis = 6378210.0
  // datum.SpheroidSemiMinorAxis = 6352697.16

Coordinate3D

Vector Polar Coordinates

Coordinate3D polarVector = new Coordinate3D(0, 7, 0);
  Tuple<double, double, double> polarComponents = polarVector.QueryPolarComponents();
  // polarComponents.Item1 = 0  (azimuth)
  // polarComponents.Item2 = 0 (inclination)
  // polarComponents.Item3 = 7 (magnitude)

  polarVector.SetPolarComponents(Math.PI / 4, Math.PI / 2, 8);
  polarComponents = polarVector.QueryComponents();
  // polarComponents.Item1 = 0 (x)
  // polarComponents.Item2 = 0 (y)
  // polarComponents.Item3 = 7 (z)

Getting vector inclination

Coordinate3D v = new Coordinate3D(0, 0, 7);
  double inclination = v.Inclination;         // inclination = PI/2

  v.SetComponents(-2, -3, 0);
  inclination = v.Inclination;                // inclination = 0

  v.SetComponents(0, 0, -2);
  inclination = v.Inclination;                // inclination = -PI/2

Getting vector azimuth

Coordinate3D vector = new Coordinate3D(0, 7, 0);
  double azimuth = vector.Azimuth;      // azimuth = 0

  vector.SetComponents(1, 1, 42);
  azimuth = vector.Azimuth;
  double degrees = AngularUnit.Degrees.ConvertFromRadians(azimuth);       // degrees = 45

  vector.SetComponents(-8, 8, 2);
  azimuth = vector.Azimuth;
  degrees = AngularUnit.Degrees.ConvertFromRadians(azimuth);              // degrees = 315

Vector Operations

// Easy 3D vectors
  Coordinate3D v = new Coordinate3D(0, 1, 0);
  // v.Magnitude = 1

  Coordinate3D other = new Coordinate3D(-1, 0, 0);
  // other.Magnitude = -1

  double dotProduct = v.DotProduct(other);      // dotProduct = 0

  Coordinate3D crossProduct = v.CrossProduct(other);
  // crossProduct.X = 0
  // crossProduct.Y = 0
  // crossProduct.Z = 1

  Coordinate3D addVector = v.AddCoordinate3D(other);
  // addVector.X = -1
  // addVector.Y = 1
  // addVector.Z = 0

  // Rotate around x-axis
  Coordinate3D w = v;
  w.Rotate(Math.PI, other);
  // w.X = 0
  // w.Y = -1
  // w.Z = 0

  w.Scale(0.5);
  // w.X = 0
  // w.Y = -0.5
  // w.Z = 0

  w.Scale(-4);
  // w.X = 0
  // ww.Y = 2
  // w.Z = 0
  // w.Magnitude = 2

  w.Move(3, 2, 0);
  // w.X = 3
  // w.Y = 4
  // w.Z = 0
  // w.Magnitude = 5


  Coordinate3D emptyVector = new Coordinate3D();
  // emptyVector = (0, 0, 0)
  emptyVector.SetEmpty();
  // emptyVector = (Nan, Nan, Nan)

  Coordinate3D c1 = new Coordinate3D(2, 3, 4);
  Coordinate3D c2 = new Coordinate3D(9, -1, 3);

  var result_add = c1 + c2;
  // result_add = (11, 2, 7)
  var result_sub = c1 - c2;
  // result_sub = (-7, 4, 1)

  var b = result_sub != result_add;
  // b = true

  result_add = emptyVector + c1;
  // result_add = (Nan, Nan, Nan)

  b = result_add == emptyVector;
  // b = true

2D Vector Operations

Coordinate2D v = new Coordinate2D(0, 1);
  // v.Magnitude = 1

  Coordinate2D other = new Coordinate2D(-1, 0);
  double dotProduct = v.DotProduct(other);
  // dotProduct = 0

  Coordinate2D w = v + other;
  // w = (-1, 1)

  w += other;
  // w = (-2, 1)

  w -= other;
  // w = (-1, 1)

  w = v;
  w.Rotate(Math.PI, other);
  // w = (-2, -1)

  w = other;

  w.Scale(-4);
  // w = (4, 0)
  // w.Magnitude = 4

  w.Move(-1, 4);
  // w = (3, 4)
  // w.Magnitude = 5

  w.Move(-6, -1);
  Tuple<double, double> components = w.QueryComponents();
  // components = (-3, 3)
  // w.Magnitude = 3 * Math.Sqrt(2)

  Coordinate2D unitVector = w.GetUnitVector();
  // w = (-Math.Sqrt(2) / 2, Math.Sqrt(2) / 2)
  // w.Magnitude = 1
  w.SetComponents(3, 4);

Builder Properties

Builder Properties

// list of points
  List<MapPoint> pointsForBuilder = new List<MapPoint>
{
  MapPointBuilderEx.CreateMapPoint(0, 0, 2, 3, 1),
  MapPointBuilderEx.CreateMapPoint(1, 1, 5, 6),
  MapPointBuilderEx.CreateMapPoint(2, 1, 6),
  MapPointBuilderEx.CreateMapPoint(0, 0)
};

  // will have attributes because it is created with convenience method
  Polyline polylineWithAttrs = PolylineBuilderEx.CreatePolyline(pointsForBuilder);
  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 specified as a parameter
  Polyline polylineWithoutAttrs =
    PolylineBuilderEx.CreatePolyline(pointsForBuilder, AttributeFlags.None);
  hasZ = polylineWithoutAttrs.HasZ;          // hasZ = false
  hasM = polylineWithoutAttrs.HasM;          // hasM = false
  hasID = polylineWithoutAttrs.HasID;        // hasID = false

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

  // will not have attributes because it is specified as a parameter
  Polygon polygonWithoutAttrs =
        PolygonBuilderEx.CreatePolygon(pointsForBuilder, AttributeFlags.None);
  hasZ = polygonWithoutAttrs.HasZ;               // hasZ = false
  hasM = polygonWithoutAttrs.HasM;               // hasM = false
  hasID = polygonWithoutAttrs.HasID;             // hasID = false

  // will not have attributes because it is specified as a parameter
  PolylineBuilderEx polylineB =
             new PolylineBuilderEx(pointsForBuilder, AttributeFlags.None);
  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 PolylineBuilderEx(polylineWithAttrs);
  hasZ = polylineB.HasZ;                      // hasZ = true
  hasM = polylineB.HasM;                      // hasM = true
  hasID = polylineB.HasID;                    // hasID = true

  // will not have attributes because it is passed a non-attributed polyline
  polylineB = new PolylineBuilderEx(polylineWithoutAttrs);
  hasZ = polylineB.HasZ;                      // hasZ = false
  hasM = polylineB.HasM;                      // hasM = false
  hasID = polylineB.HasID;                    // hasID = false

  // will not have attributes because it is specified as a parameter
  PolygonBuilderEx polygonB = new PolygonBuilderEx(pointsForBuilder, AttributeFlags.None);
  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 PolygonBuilderEx(polygonWithAttrs);
  hasZ = polygonB.HasZ;                       // hasZ = true
  hasM = polygonB.HasM;                       // hasM = true
  hasID = polygonB.HasID;                     // hasID = true

  // will not have attributes because it is passed a non-attributed polygon
  polygonB = new PolygonBuilderEx(polygonWithoutAttrs);
  hasZ = polygonB.HasZ;                       // hasZ = true
  hasM = polygonB.HasM;                       // hasM = true
  hasID = polygonB.HasID;                     // hasID = true

MapPoint

Construct a MapPoint

// Use a builder convenience method or use a builder constructor.

  // Create a 2D point without a spatial reference
  MapPoint point2D = MapPointBuilderEx.CreateMapPoint(1, 2);
  SpatialReference sr = point2D.SpatialReference; // sr = null
  bool hasZ = point2D.HasZ;   // hasZ = false
  bool hasM = point2D.HasM;   // hasM = false
  bool hasID = point2D.HasID; // hasID = false
  double x = point2D.X;   // x = 1
  double y = point2D.Y;   // y = 2
  double z = point2D.Z;   // z = 0 default value
  double m = point2D.M;   // m is NaN default value
  double id = point2D.ID; // id = 0 default value

  // Or use a builderEx which doesn't need to run on the MCT. 
  MapPointBuilderEx builderEx = new MapPointBuilderEx(1, 2);

  // do something with the builder
  builderEx.Y = 3;
  point2D = builderEx.ToGeometry();
  sr = point2D.SpatialReference; // sr = null
  hasZ = point2D.HasZ;   // hasZ = false
  hasM = point2D.HasM;   // hasM = false
  hasID = point2D.HasID; // hasID = false
  x = point2D.X;   // x = 1
  y = point2D.Y;   // y = 3
  z = point2D.Z;   // z = 0 default value
  m = point2D.M;   // m is NaN default value
  id = point2D.ID; // id = 0 default value

  // Create a 2D point with a spatial reference
  SpatialReference spatialReference = SpatialReferenceBuilder.CreateSpatialReference(4269);
  point2D = MapPointBuilderEx.CreateMapPoint(1, 2, spatialReference);
  sr = point2D.SpatialReference; // sr != null
  int wkid = sr.Wkid; // wkid = 4269

  // Or use a builder
  builderEx = new MapPointBuilderEx(1, 2, spatialReference);

  // Do something with the builder
  builderEx.SetValues(3, 5);
  point2D = builderEx.ToGeometry();
  sr = point2D.SpatialReference; // sr != null
  wkid = sr.Wkid; // wkid = 4269
  x = point2D.X; // x = 3
  y = point2D.Y; // y = 5

  // Change the spatial reference of the builder
  builderEx.SpatialReference = SpatialReferences.WGS84;
  point2D = builderEx.ToGeometry();
  sr = point2D.SpatialReference; // sr != null
  wkid = sr.Wkid; // wkid = 4326
  x = point2D.X; // x = 3
  y = point2D.Y; // y = 5

  // Create a 3D point with M
  MapPoint pointZM = MapPointBuilderEx.CreateMapPoint(1, 2, 3, 4);
  sr = pointZM.SpatialReference; // sr = null
  hasZ = pointZM.HasZ;   // hasZ = true
  hasM = pointZM.HasM;   // hasM = true
  hasID = pointZM.HasID; // hasID = false
  x = pointZM.X;   // x = 1
  y = pointZM.Y;   // y = 2
  z = pointZM.Z;   // z = 3
  m = pointZM.M;   // m = 4
  id = pointZM.ID; // id = 0 default value

  // Create a 3D point with M and a spatial reference
  pointZM = MapPointBuilderEx.CreateMapPoint(1, 2, 3, 4, spatialReference);
  sr = pointZM.SpatialReference; // sr != null
  wkid = sr.Wkid; // wkid = 4269

  // Create a point from another point in three ways
  MapPoint clone = pointZM.Clone() as MapPoint; // Has the same values including the spatial reference as pointZM
  MapPoint anotherZM = MapPointBuilderEx.CreateMapPoint(pointZM);  // Has the same values including the spatial reference as pointZM

  builderEx = new MapPointBuilderEx(pointZM); // Has the same values including the spatial reference as pointZM
  // Do something with the builder
  builderEx.HasM = false;
  builderEx.ID = 7; // Setting the id also sets HasID = true
  MapPoint pointZId = builderEx.ToGeometry();
  sr = pointZId.SpatialReference; // sr != null
  wkid = sr.Wkid; // wkid = 4269
  hasZ = pointZId.HasZ;   // hasZ = true
  hasM = pointZId.HasM;   // hasM = false
  hasID = pointZId.HasID; // hasID = true
  x = pointZId.X;   // x = 1
  y = pointZId.Y;   // y = 2
  z = pointZId.Z;   // z = 3
  m = pointZId.M;   // m is NaN, default value
  id = pointZId.ID; // id = 7

  // Create a point with Z, M, and ID-values
  MapPoint pointZMId = MapPointBuilderEx.CreateMapPoint(1, 2, 3, 4, 5, spatialReference);
  sr = pointZMId.SpatialReference; // sr != null
  wkid = sr.Wkid; // wkid = 4269
  hasZ = pointZMId.HasZ;   // hasZ = true
  hasM = pointZMId.HasM;   // hasM = true
  hasID = pointZMId.HasID; // hasID = true
  x = pointZMId.X;   // x = 1
  y = pointZMId.Y;   // y = 2
  z = pointZMId.Z;   // z = 3
  m = pointZMId.M;   // m = 4
  id = pointZMId.ID; // id = 5

  // Pick and choose which attributes to include
  MapPoint point = MapPointBuilderEx.CreateMapPoint(1, 2, false, 3, true, 4, true, 5);
  sr = point.SpatialReference; // sr = null
  hasZ = point.HasZ;   // hasZ = false
  hasM = point.HasM;   // hasM = true
  hasID = point.HasID; // hasID = true
  x = point.X;   // x = 1
  y = point.Y;   // y = 2
  z = point.Z;   // z = 0, default value
  m = point.M;   // m = 4
  id = point.ID; // id = 5

  // Or use a builder
  builderEx = new(1, 2, true, 3, false, 4, true, 5);
  // Do something with the builder
  builderEx.ID = 7;
  builderEx.SpatialReference = SpatialReferences.WGS84;
  point = builderEx.ToGeometry();
  sr = point.SpatialReference; // sr != null
  wkid = sr.Wkid; // wkid = 4326
  hasZ = point.HasZ;   // hasZ = true
  hasM = point.HasM;   // hasM = false
  hasID = point.HasID; // hasID = true
  x = point.X;   // x = 1
  y = point.Y;   // y = 2
  z = point.Z;   // z = 0, default value
  m = point.M;   // m is NaN, default value
  id = point.ID; // id = 7

MapPoint Builder Properties

// MapPointBuilderEx constructors can run on any thread.

  MapPoint point1 = null;
  MapPoint point2 = null;

  SpatialReference spatialReference = SpatialReferenceBuilder.CreateSpatialReference(54004);

  MapPointBuilderEx mapPointBuilder = new MapPointBuilderEx(100, 200, spatialReference);
  SpatialReference sr = mapPointBuilder.SpatialReference; // sr != null
  int wkid = sr.Wkid; // wkid = 54004
  bool hasZ = mapPointBuilder.HasZ;   // hasZ = false
  bool hasM = mapPointBuilder.HasM;   // hasM = false
  bool hasID = mapPointBuilder.HasID; // hasID = false
  bool isEmpty = mapPointBuilder.IsEmpty; // isEmpty = false
  double x = mapPointBuilder.X;   // x = 100
  double y = mapPointBuilder.Y;   // y = 200
  double z = mapPointBuilder.Z;   // z = 0, default value
  double m = mapPointBuilder.M;   // m is NaN, default value
  double id = mapPointBuilder.ID; // id = 0, default value

  // Do something with the builder
  mapPointBuilder.Z = 12; // Setting the z-value automatically sets HasZ property to true

  point1 = mapPointBuilder.ToGeometry();
  sr = point1.SpatialReference; // sr != null
  wkid = sr.Wkid; // wkid = 54004
  hasZ = point1.HasZ;   // hasZ = true
  hasM = point1.HasM;   // hasM = false
  hasID = point1.HasID; // hasID = false
  x = point1.X;   // x = 100
  y = point1.Y;   // y = 200
  z = point1.Z;   // z = 12
  m = point1.M;   // m is NaN, default value
  id = point1.ID; // id = 0, default value

  // Change some of the builder properties
  mapPointBuilder.SetValues(11, 22);
  mapPointBuilder.HasZ = false;
  mapPointBuilder.HasM = true;
  mapPointBuilder.M = 44;

  // Create another point
  point2 = mapPointBuilder.ToGeometry();

  bool isEqual = point1.IsEqual(point2); // isEqual = false

  // Set the builder to empty
  // Sets X and Y to NaN. Sets other attributes to the default values.
  // Does not change the attribute awareness.
  mapPointBuilder.SetEmpty();

  MapPoint point3 = mapPointBuilder.ToGeometry();
  sr = point3.SpatialReference; // sr != null
  wkid = sr.Wkid; // wkid = 54004
  hasZ = point3.HasZ;        // hasZ = false
  hasM = point3.HasM;        // hasM = true
  hasID = point3.HasID;      // hasID = false
  isEmpty = point3.IsEmpty;  // isEmpty = true
  x = point3.X;              // x is NaN
  y = point3.Y;              // y is NaN
  z = point3.Z;              // z = 0, default value
  m = point3.M;              // m is NaN, default value
  id = point3.ID;            // ID = 0, default value

  // Create a builder from a point
  mapPointBuilder = new MapPointBuilderEx(point2); // point1 = (11, 22, 0, 44, 0)
  sr = mapPointBuilder.SpatialReference; // sr != null
  wkid = sr.Wkid; // wkid = 54004
  hasZ = mapPointBuilder.HasZ;        // hasZ = false
  hasM = mapPointBuilder.HasM;        // hasM = true
  hasID = mapPointBuilder.HasID;      // hasID = false
  isEmpty = mapPointBuilder.IsEmpty;  // isEmpty = false
  x = mapPointBuilder.X;              // x = 11
  y = mapPointBuilder.Y;              // y = 22
  z = mapPointBuilder.Z;              // z = 0, default value
  m = mapPointBuilder.M;              // m = 44
  id = mapPointBuilder.ID;            // ID = 0, default value

  // Setting attribute values automatically sets the corresponding flag to true
  mapPointBuilder.Z = 150;
  mapPointBuilder.ID = 2;

  // Remove the spatial reference
  mapPointBuilder.SpatialReference = null;

  MapPoint point4 = mapPointBuilder.ToGeometry() as MapPoint;
  sr = point3.SpatialReference; // sr = null
  hasZ = point3.HasZ;        // hasZ = true
  hasM = point3.HasM;        // hasM = true
  hasID = point3.HasID;      // hasID = true
  isEmpty = point3.IsEmpty;  // isEmpty = false
  x = point3.X;              // x = 11
  y = point3.Y;              // y = 22
  z = point3.Z;              // z = 150
  m = point3.M;              // m = 44
  id = point3.ID;            // ID = 2

MapPoint IsEqual

MapPoint pt1 = MapPointBuilderEx.CreateMapPoint(1, 2, 3, 4, 5);
  int ID = pt1.ID;           // ID = 5
  bool hasID = pt1.HasID;     // hasID = true

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

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

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

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

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

Zoom to a specified point

double x = -122.45;
  double y = 37.75;
  double buffer_size = 0.1;
  //Create a point
  var pt = MapPointBuilderEx.CreateMapPoint(x, y,
                 SpatialReferenceBuilder.CreateSpatialReference(4326));
  //Buffer it - for purpose of zoom
  var poly = GeometryEngine.Instance.Buffer(pt, buffer_size);

  //do we need to project the buffer polygon?
  if (!MapView.Active.Map.SpatialReference.IsEqual(poly.SpatialReference))
  {
    //project the polygon
    poly = GeometryEngine.Instance.Project(poly, MapView.Active.Map.SpatialReference);
  }

  // Must run on MCT.
  QueuedTask.Run(() =>
  {
    //Zoom - add in a delay for animation effect
    MapView.Active.ZoomTo(poly, new TimeSpan(0, 0, 0, 3));
  });

Polyline

Construct a Polyline - from an enumeration of MapPoints

// Use a builderEx convenience method or a builderEx constructor.
  // neither need to run on the MCT

  MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
  MapPoint endPt = MapPointBuilderEx.CreateMapPoint(2.0, 1.0);

  List<MapPoint> list = new List<MapPoint>() { startPt, endPt };

  Polyline polylineFromPointList = PolylineBuilderEx.CreatePolyline(list, SpatialReferences.WGS84);

  // use AttributeFlags.None since we only have 2D points in the list
  PolylineBuilderEx pb = new PolylineBuilderEx(list, AttributeFlags.None);
  pb.SpatialReference = SpatialReferences.WGS84;
  Polyline polyline2 = pb.ToGeometry();

  // Use AttributeFlags.NoAttributes because we only have 2d points in the list
  Polyline polyline4 = PolylineBuilderEx.CreatePolyline(list, AttributeFlags.None);

Get the points of a Polyline

// get the points as a readonly Collection
  //Refer to the initialization region for polyline creation
  ReadOnlyPointCollection pts = polyline.Points;
  int numPts = polyline.PointCount;

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

  // OR   get the point coordinates as a readonly list of Coordinate2D
  IReadOnlyList<Coordinate2D> coordinates = polyline.Copy2DCoordinatesToList();

  // OR   get the point coordinates as a readonly list of Coordinate3D
  IReadOnlyList<Coordinate3D> coordinates3D = polyline.Copy3DCoordinatesToList();

  // OR   get a subset of the collection as Coordinate2D using preallocated memory

  IList<Coordinate2D> coordinate2Ds = new List<Coordinate2D>(10);   // allocate some space
  ICollection<Coordinate2D> subsetCoordinates2D = coordinate2Ds;    // assign
  pts.Copy2DCoordinatesToList(1, 2, ref subsetCoordinates2D);       // copy 2 elements from index 1 into the allocated list
                                                                    // coordinate2Ds.Count = 2
                                                                    // do something with the coordinate2Ds

  // without allocating more space, obtain a different set of coordinates
  pts.Copy2DCoordinatesToList(5, 9, ref subsetCoordinates2D);       // copy 9 elements from index 5 into the allocated list
                                                                    // coordinate2Ds.Count = 9


  // OR   get a subset of the collection as Coordinate3D using preallocated memory

  IList<Coordinate3D> coordinate3Ds = new List<Coordinate3D>(15);   // allocate some space
  ICollection<Coordinate3D> subsetCoordinates3D = coordinate3Ds;    // assign
  pts.Copy3DCoordinatesToList(3, 5, ref subsetCoordinates3D);       // copy 5 elements from index 3 into the allocated list
                                                                    // coordinate3Ds.Count = 5


  // OR   get a subset of the collection as MapPoint using preallocated memory

  IList<MapPoint> mapPoints = new List<MapPoint>(7);   // allocate some space
  ICollection<MapPoint> subsetMapPoint = mapPoints;    // assign
  pts.CopyPointsToList(1, 4, ref subsetMapPoint);      // copy 4 elements from index 1 into the allocated list
                                                       // mapPoints.Count = 4

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> segmentsPolyline = polylineParts.GetEnumerator();
  while (segmentsPolyline.MoveNext())
  {
    ReadOnlySegmentCollection seg = segmentsPolyline.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;
      }
    }
  }

  // or use foreach pattern
  foreach (var part in polyline.Parts)
  {
    foreach (var segment in part)
    {
      len += segment.Length;

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

Reverse the order of points in a Polyline

var polylineBuilder = new PolylineBuilderEx(polyline);
  polylineBuilder.ReverseOrientation();
  Polyline reversedPolyline = polylineBuilder.ToGeometry();

Get the segments of a Polyline

ICollection<Segment> collectionSegments = new List<Segment>();
  polyline.GetAllSegments(ref collectionSegments);
  int numSegmentsInCollection = collectionSegments.Count;    // = 10

  IList<Segment> iList = collectionSegments as IList<Segment>;
  for (int i = 0; i < numSegmentsInCollection; i++)
  {
    // do something with iList[i]
  }

  // use the segments to build another polyline
  Polyline polylineFromSegments = PolylineBuilderEx.CreatePolyline(collectionSegments);

Build a multi-part Polyline

List<MapPoint> firstPoints = new List<MapPoint>();
  firstPoints.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0));
  firstPoints.Add(MapPointBuilderEx.CreateMapPoint(1.0, 2.0));
  firstPoints.Add(MapPointBuilderEx.CreateMapPoint(2.0, 2.0));
  firstPoints.Add(MapPointBuilderEx.CreateMapPoint(2.0, 1.0));

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

  // use AttributeFlags.None since we have 2D points in the list
  PolylineBuilderEx pBuilder = new PolylineBuilderEx(firstPoints, AttributeFlags.None);
  pBuilder.AddPart(nextPoints);

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

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

StartPoint of a Polyline

// Method 1: Get the start point of the polyline by converting the polyline 
  //    into a collection of points and getting the first point

  // sketchGeometry is a Polyline
  // get the sketch as a point collection
  Geometry sketchGeometry = polyline; // for example
  var pointCol = ((Multipart)sketchGeometry).Points;
  // Get the start point of the line
  var firstPoint = pointCol[0];

  // Method 2: Convert polyline into a collection of line segments 
  //   and get the "StartPoint" of the first line segment.
  var polylineGeom = sketchGeometry as ArcGIS.Core.Geometry.Polyline;
  var polyLineParts = polylineGeom.Parts;

  ReadOnlySegmentCollection polylineSegments = polyLineParts.First();

  //get the first segment as a LineSegment
  var firsLineSegment = polylineSegments.First() as LineSegment;

  //Now get the start Point
  var startPointOfSegment = firsLineSegment.StartPoint;

Construct a Clothoid by Angle

MapPoint startPoint = MapPointBuilderEx.CreateMapPoint(0, 0);
  double tangentDirection = Math.PI / 6;
  ArcOrientation orientation = ArcOrientation.ArcCounterClockwise;
  double startRadius = double.PositiveInfinity;
  double endRadius = 0.2;
  ClothoidCreateMethod createMethod = ClothoidCreateMethod.ByAngle;
  double angle = Math.PI / 2;
  CurveDensifyMethod densifyMethod = CurveDensifyMethod.ByLength;
  double densifyParameter = 0.1;

  Polyline polylineCl = PolylineBuilderEx.CreatePolyline(startPoint, tangentDirection, startRadius, endRadius, orientation, createMethod, angle, densifyMethod, densifyParameter, SpatialReferences.WGS84);

  int numPoints = polylineCl.PointCount;
  MapPoint queryPoint = polylineCl.Points[numPoints - 2];

  MapPoint pointOnPath;
  double radiusCalculated, tangentDirectionCalculated, lengthCalculated, angleCalculated;

  PolylineBuilderEx.QueryClothoidParameters(queryPoint, startPoint, tangentDirection, startRadius, endRadius, orientation, createMethod, angle, out pointOnPath, out radiusCalculated, out tangentDirectionCalculated, out lengthCalculated, out angleCalculated, SpatialReferences.WGS84);

Construct a Clothoid by Length

MapPoint startPoint = MapPointBuilderEx.CreateMapPoint(0, 0);
  MapPoint queryPoint = MapPointBuilderEx.CreateMapPoint(3.8, 1);
  double tangentDirection = 0;
  ArcOrientation orientation = ArcOrientation.ArcCounterClockwise;
  double startRadius = double.PositiveInfinity;
  double endRadius = 1;
  ClothoidCreateMethod createMethod = ClothoidCreateMethod.ByLength;
  double curveLength = 10;
  MapPoint pointOnPath;
  double radiusCalculated, tangentDirectionCalculated, lengthCalculated, angleCalculated;


  PolylineBuilderEx.QueryClothoidParameters(queryPoint, startPoint, tangentDirection, startRadius, endRadius, orientation, createMethod, curveLength, out pointOnPath, out radiusCalculated, out tangentDirectionCalculated, out lengthCalculated, out angleCalculated, SpatialReferences.WGS84);

  pointOnPath = MapPointBuilderEx.CreateMapPoint(3.7652656620171379, 1.0332006103128575);
  radiusCalculated = 2.4876382887687227;
  tangentDirectionCalculated = 0.80797056423543978;
  lengthCalculated = 4.0198770235802987;
  angleCalculated = 0.80797056423544011;

  queryPoint = MapPointBuilderEx.CreateMapPoint(1.85, 2.6);

  PolylineBuilderEx.QueryClothoidParameters(queryPoint, startPoint, tangentDirection, startRadius, endRadius, orientation, createMethod, curveLength, out pointOnPath, out radiusCalculated, out tangentDirectionCalculated, out lengthCalculated, out angleCalculated, SpatialReferences.WGS84);

  pointOnPath = MapPointBuilderEx.CreateMapPoint(1.8409964973501549, 2.6115979967308132);
  radiusCalculated = 1;
  tangentDirectionCalculated = -1.2831853071795867;
  lengthCalculated = 10;
  angleCalculated = 5;

  tangentDirection = Math.PI / 4;
  orientation = ArcOrientation.ArcClockwise;
  startRadius = double.PositiveInfinity;
  endRadius = 0.8;
  createMethod = ClothoidCreateMethod.ByLength;
  curveLength = 10;

  Polyline polylineByLength = PolylineBuilderEx.CreatePolyline(startPoint, tangentDirection, startRadius, endRadius, orientation, createMethod, curveLength, CurveDensifyMethod.ByLength, 0.5, SpatialReferences.WGS84);

Split Polyline at distance

// create list of points
  MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
  MapPoint endPt = MapPointBuilderEx.CreateMapPoint(2.0, 1.0);

  List<MapPoint> list = new List<MapPoint>() { startPt, endPt };

  // BuilderEx constructors don't need to run on the MCT.

  // use the PolylineBuilder as we wish to manipulate the geometry
  // use AttributeFlags.None as we have 2D points
  PolylineBuilderEx polylineBuilder = new PolylineBuilderEx(list, AttributeFlags.None);
  // split at a distance 0.75
  polylineBuilder.SplitAtDistance(0.75, false);
  // get the polyline
  Polyline polylineFromBuilder = polylineBuilder.ToGeometry();
  // polyline should have 3 points  (1,1), (1.75, 1), (2,1)

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

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

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

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

  polylineFromBuilder = polylineBuilder.ToGeometry();

  // polyline still has 2 parts; but now has 7 points

Create 3D Polyline and set Z-values while preserving curve segments

PolylineBuilderEx polylineBuilder = new PolylineBuilderEx(polyline);
  polylineBuilder.HasZ = true;

  // The HasZ property is set to true for all the points in
  // polyline3D when you call ToGeometry().
  Polyline polyline3D = polylineBuilder.ToGeometry();

  // For this example, create Z-values. 
  // You may want to pass them in as a parameter.
  int numPoints = polyline3D.PointCount;
  double[] zValues = new double[numPoints];
  for (int i = 0; i < numPoints; i++)
  {
    zValues[i] = i % 2 == 0 ? 2 : 1;
  }

  // We need to know at which point index each part starts
  int partPointIndex = 0;
  int numParts = polyline3D.PartCount;

  for (int i = 0; i < numParts; i++)
  {
    var part = polyline3D.Parts[i];
    int numSegmentsInPolyline3D = part.Count;

    for (int j = 0; j < numSegmentsInPolyline3D; j++)
    {
      Segment segment = part[j];

      MapPointBuilderEx pointBuilder = new MapPointBuilderEx(segment.StartPoint);
      pointBuilder.Z = zValues[partPointIndex++];
      MapPoint startPoint = pointBuilder.ToGeometry();

      // Make sure that the end point of this segment is the same as the start point of the next segment
      pointBuilder = new MapPointBuilderEx(segment.EndPoint);
      pointBuilder.Z = zValues[partPointIndex];
      MapPoint endPoint = pointBuilder.ToGeometry();

      SegmentType segmentType = segment.SegmentType;
      SegmentBuilderEx segmentBuilder = null;
      switch (segmentType)
      {
        case SegmentType.Line:
          segmentBuilder = new LineBuilderEx((LineSegment)segment);
          break;
        case SegmentType.Bezier:
          segmentBuilder = new CubicBezierBuilderEx((CubicBezierSegment)segment);
          break;
        case SegmentType.EllipticArc:
          segmentBuilder = new EllipticArcBuilderEx((EllipticArcSegment)segment);
          break;
      }

      // Only change the start and end point which now have Z-values set. 
      // This will preserve the curve if the segment is an EllipticArcSegment or CubicBezierSegment.
      segmentBuilder.StartPoint = startPoint;
      segmentBuilder.EndPoint = endPoint;
      segment = segmentBuilder.ToSegment();

      polylineBuilder.ReplaceSegment(i, j, segment);
    }

    // Move point index for the next part
    partPointIndex++;
  }

  polyline3D = polylineBuilder.ToGeometry();

Polygon

Construct a Polygon - from an enumeration of MapPoints

// Use a builderEx convenience method or use a builderEx constructor.

  MapPoint pt1 = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
  MapPoint pt2 = MapPointBuilderEx.CreateMapPoint(1.0, 2.0);
  MapPoint pt3 = MapPointBuilderEx.CreateMapPoint(2.0, 2.0);
  MapPoint pt4 = MapPointBuilderEx.CreateMapPoint(2.0, 1.0);

  List<MapPoint> list = new List<MapPoint>() { pt1, pt2, pt3, pt4 };

  Polygon polygonFromPoints = PolygonBuilderEx.CreatePolygon(list, SpatialReferences.WGS84);
  // polygon.HasZ will be false - it is determined by the HasZ flag of the points in the list

  // or specifically use AttributeFlags.NoAttributes
  polygonFromPoints = PolygonBuilderEx.CreatePolygon(list, AttributeFlags.None);

  // use AttributeFlags.None as we have 2D points
  PolygonBuilderEx polygonBuilder = new PolygonBuilderEx(list, AttributeFlags.None);
  polygonBuilder.SpatialReference = SpatialReferences.WGS84;
  polygonFromPoints = polygonBuilder.ToGeometry();

Construct a Polygon - from an Envelope

// Use a builderEx convenience method or use a builderEx constructor.

  MapPoint minPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
  MapPoint maxPt = MapPointBuilderEx.CreateMapPoint(2.0, 2.0);

  // Create an envelope
  Envelope env = EnvelopeBuilderEx.CreateEnvelope(minPt, maxPt);

  Polygon polygonFromEnv = PolygonBuilderEx.CreatePolygon(env);

  PolygonBuilderEx polygonBuilderEx = new PolygonBuilderEx(env);
  polygonBuilderEx.SpatialReference = SpatialReferences.WGS84;
  polygonFromEnv = polygonBuilderEx.ToGeometry() as Polygon;

Get the points of a Polygon

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

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

  // get the point coordinates as a readonly list of Coordinate2D
  IReadOnlyList<Coordinate2D> coordinates = polygon.Copy2DCoordinatesToList();

  // get the point coordinates as a readonly list of Coordinate3D
  IReadOnlyList<Coordinate3D> coordinates3D = polygon.Copy3DCoordinatesToList();

Get the parts of a Polygon

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

Enumerate the parts of a Polygon

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

Get the segments of a Polygon

List<Segment> segmentList = new List<Segment>(30);
  ICollection<Segment> collection = segmentList;
  polygon.GetAllSegments(ref collection);
  // segmentList.Count = 4
  // segmentList.Capacity = 30

  // use the segments to build another polygon
  Polygon polygonFromSegments = PolygonBuilderEx.CreatePolygon(collection);

Build a donut polygon

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));

  // 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));

  PolygonBuilderEx pbEx = new PolygonBuilderEx(outerCoordinates);
  Polygon donutEx = pbEx.ToGeometry() as Polygon;
  double areaEx = donutEx.Area;       // area = 100

  pbEx.AddPart(innerCoordinates);
  donutEx = pbEx.ToGeometry() as Polygon;

  areaEx = donutEx.Area;    // area = 84.0

  areaEx = GeometryEngine.Instance.Area(donutEx);    // area = 84.0

Create an N-sided regular polygon

// <summary>
  // Create an N-sided regular polygon.  A regular sided polygon is a polygon that is equiangular (all angles are equal in measure) 
  // and equilateral (all sides are equal in length).  See https://en.wikipedia.org/wiki/Regular_polygon
  // </summary>
  // <param name="numSides">The number of sides in the polygon.</param>
  // <param name="center">The center of the polygon.</param>
  // <param name="radius">The distance from the center of the polygon to a vertex.</param>
  // <param name="rotation">The rotation angle in radians of the start point of the polygon. The start point will be
  // rotated counterclockwise from the positive x-axis.</param>
  // <returns>N-sided regular polygon.</returns>
  // <exception cref="ArgumentException">Number of sides is less than 3.</exception>
  static Polygon CreateRegularPolygon(int numSides, Coordinate2D center, double radius, double rotation)
  {
    if (numSides < 3)
      throw new ArgumentException();

    Coordinate2D[] coords = new Coordinate2D[numSides + 1];

    double centerX = center.X;
    double centerY = center.Y;
    double x = radius * Math.Cos(rotation) + centerX;
    double y = radius * Math.Sin(rotation) + centerY;
    Coordinate2D start = new Coordinate2D(x, y);
    coords[0] = start;

    double da = 2 * Math.PI / numSides;
    for (int i = 1; i < numSides; i++)
    {
      x = radius * Math.Cos(i * da + rotation) + centerX;
      y = radius * Math.Sin(i * da + rotation) + centerY;

      coords[i] = new Coordinate2D(x, y);
    }

    coords[numSides] = start;

    return PolygonBuilderEx.CreatePolygon(coords);
  }

Get the exterior rings of a polygon - polygon.GetExteriorRing

static void GetExteriorRings(Polygon inputPolygon)
  {
    if (inputPolygon == null || inputPolygon.IsEmpty)
      return;

    // polygon part count
    int partCount = inputPolygon.PartCount;
    // polygon exterior ring count
    int numExtRings = inputPolygon.ExteriorRingCount;
    // get set of exterior rings for the polygon
    IList<Polygon> extRings = inputPolygon.GetExteriorRings();

    // test each part for "exterior ring"
    for (int idx = 0; idx < partCount; idx++)
    {
      bool isExteriorRing = inputPolygon.IsExteriorRing(idx);
      var ring = inputPolygon.GetExteriorRing(idx);
    }
  }

Envelope

Construct an Envelope

// Use a builderEx convenience method or use a builderEx constructor.

  MapPoint minPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
  MapPoint maxPt = MapPointBuilderEx.CreateMapPoint(2.0, 2.0);

  Envelope envelope = EnvelopeBuilderEx.CreateEnvelope(minPt, maxPt);

  EnvelopeBuilderEx builderEx = new EnvelopeBuilderEx(minPt, maxPt);
  envelope = builderEx.ToGeometry() as Envelope;

Construct an Envelope - from a JSON string

string jsonString = "{ \"xmin\" : 1, \"ymin\" : 2,\"xmax\":3,\"ymax\":4,\"spatialReference\":{\"wkid\":4326}}";
  Envelope envFromJson = EnvelopeBuilderEx.FromJson(jsonString);

Union two Envelopes

// use the convenience builders
  Envelope env1 = EnvelopeBuilderEx.CreateEnvelope(0, 0, 1, 1, SpatialReferences.WGS84);
  Envelope env2 = EnvelopeBuilderEx.CreateEnvelope(0.5, 0.5, 1.5, 1.5, SpatialReferences.WGS84);

  Envelope env3 = env1.Union(env2);

  double area = env3.Area;
  double depth = env3.Depth;
  double height = env3.Height;
  double width = env3.Width;
  double len = env3.Length;

  MapPoint centerPt = env3.Center;
  Coordinate2D coord = env3.CenterCoordinate;

  bool isEmpty = env3.IsEmpty;
  int pointCount = env3.PointCount;

  // coordinates
  //env3.XMin, env3.XMax, env3.YMin, env3.YMax
  //env3.ZMin, env3.ZMax, env3.MMin, env3.MMax

  bool isEqual = env1.IsEqual(env2);    // false

  // or use the builderEx constructors which don't need to run on the MCT.
  EnvelopeBuilderEx builderEx = new EnvelopeBuilderEx(0, 0, 1, 1, SpatialReferences.WGS84);
  builderEx.Union(env2);      // builder is updated to the result

  depth = builderEx.Depth;
  height = builderEx.Height;
  width = builderEx.Width;

  centerPt = builderEx.Center;
  coord = builderEx.CenterCoordinate;

  isEmpty = builderEx.IsEmpty;

  env3 = builderEx.ToGeometry() as Envelope;

Intersect two Envelopes

// use the convenience builders
  Envelope env1 = EnvelopeBuilderEx.CreateEnvelope(0, 0, 1, 1, SpatialReferences.WGS84);
  Envelope env2 = EnvelopeBuilderEx.CreateEnvelope(0.5, 0.5, 1.5, 1.5, SpatialReferences.WGS84);

  bool intersects = env1.Intersects(env2); // true
  Envelope env3 = env1.Intersection(env2);


  // or use the builderEx constructors which don't need to run on the MCT.
  EnvelopeBuilderEx builderEx = new EnvelopeBuilderEx(0, 0, 1, 1, SpatialReferences.WGS84);
  intersects = builderEx.Intersects(env2);
  builderEx.Intersection(env2);   // note this sets the builder to the intersection
  env3 = builderEx.ToGeometry() as Envelope;

Expand an Envelope

// Use a builderEx convenience method or use a builderEx constructor.

  // convenience methods don't need to run on the MCT.
  Envelope envelope = EnvelopeBuilderEx.CreateEnvelope(100.0, 100.0, 500.0, 500.0);

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


  // builderEx constructors don't need to run on the MCT.
  EnvelopeBuilderEx builderEx = new EnvelopeBuilderEx(100.0, 100.0, 500.0, 500.0);
  builderEx.Expand(0.5, 0.5, true);
  envelope = builderEx.ToGeometry() as Envelope;

Update Coordinates of an Envelope

Coordinate2D minCoord = new Coordinate2D(1, 3);
  Coordinate2D maxCoord = new Coordinate2D(2, 4);

  Coordinate2D c1 = new Coordinate2D(0, 5);
  Coordinate2D c2 = new Coordinate2D(1, 3);


  // use the EnvelopeBuilderEx.  This constructor doesn't need to run on the MCT.

  EnvelopeBuilderEx builderEx = new EnvelopeBuilderEx(minCoord, maxCoord);
  // builderEx.XMin, YMin, Zmin, MMin  = 1, 3, 0, double.Nan
  // builderEx.XMax, YMax, ZMax, MMax = 2, 4, 0, double.Nan

  // set XMin.  if XMin > XMax; both XMin and XMax change
  builderEx.XMin = 6;
  // builderEx.XMin, YMin, ZMin, MMin  = 6, 3, 0, double.Nan
  // builderEx.XMax, YMax, ZMax, MMax = 6, 4, 0, double.Nan

  // set XMax
  builderEx.XMax = 8;
  // builderEx.XMin, YMin, ZMin, MMin  = 6, 3, 0, double.Nan
  // builderEx.XMax, YMax, ZMax, MMax = 8, 4, 0, double.Nan

  // set XMax.  if XMax < XMin, both XMin and XMax change
  builderEx.XMax = 3;
  // builderEx.XMin, YMin, ZMin, MMin  = 3, 3, 0, double.Nan
  // builderEx.XMax, YMax, ZMax, MMax = 3, 4, 0, double.Nan

  // set YMin
  builderEx.YMin = 2;
  // builderEx.XMin, YMin, ZMin, MMin  = 3, 2, 0, double.Nan
  // builderEx.XMax, YMax, ZMax, MMax = 3, 4, 0, double.Nan

  // set ZMin.  if ZMin > ZMax, both ZMin and ZMax change
  builderEx.ZMin = 3;
  // builderEx.XMin, YMin, ZMin, MMin  = 3, 2, 3, double.Nan
  // builderEx.XMax, YMax, ZMax, MMax = 3, 4, 3, double.Nan

  // set ZMax.  if ZMax < ZMin. both ZMin and ZMax change
  builderEx.ZMax = -1;
  // builderEx.XMin, YMin, ZMin, MMin  = 3, 2, -1, double.Nan
  // builderEx.XMax, YMax, ZMax, MMax = 3, 4, -1, double.Nan

  builderEx.SetZCoords(8, -5);
  // builderEx.XMin, YMin, ZMin, MMin  = 3, 2, -5, double.Nan
  // builderEx.XMax, YMax, ZMax, MMax = 3, 4, 8, double.Nan


  builderEx.SetXYCoords(c1, c2);
  // builderEx.XMin, YMin, ZMin, MMin  = 0, 3, -5, double.Nan
  // builderEx.XMax, YMax, ZMax, MMax = 1, 5, 8, double.Nan


  builderEx.HasM = true;
  builderEx.SetMCoords(2, 5);

  var geomEx = builderEx.ToGeometry();

Multipoint

Construct a Multipoint - from an enumeration of MapPoints

// Use a builderEx convenience method or use a builderEx constructor.

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

  // use the builderEx constructors which don't need to run on the MCT.
  // use AttributeFlags.NoAttributes since we have 2d points in the list
  MultipointBuilderEx builderEx = new MultipointBuilderEx(list, AttributeFlags.None);
  Multipoint multiPoint = builderEx.ToGeometry() as Multipoint;
  int ptCount = builderEx.PointCount;

  // builderEx convenience methods don't need to run on the MCT
  multiPoint = MultipointBuilderEx.CreateMultipoint(list);
  // multiPoint.HasZ, HasM, HasID will be false - the attributes are determined 
  //    based on the attribute state of the points in the list

  // or specifically set the state
  multiPoint = MultipointBuilderEx.CreateMultipoint(list, AttributeFlags.None);
  // multiPoint.HasM = false

  multiPoint = MultipointBuilderEx.CreateMultipoint(list, AttributeFlags.HasM);
  // multiPoint.HasM = true

  ptCount = multiPoint.PointCount;

Construct a Multipoint - using MultipointBuilderEx

Coordinate2D[] coordinate2Ds = new Coordinate2D[] { new Coordinate2D(1, 2), new Coordinate2D(-1, -2) };
  SpatialReference sr = SpatialReferences.WGS84;

  MultipointBuilderEx builder = new MultipointBuilderEx(coordinate2Ds, sr);

  // builder.PointCount = 2

  builder.HasZ = true;
  // builder.Zs.Count = 2
  // builder.Zs[0] = 0
  // builder.Zs[1] = 0

  builder.HasM = true;
  // builder.Ms.Count = 2
  // builder.Ms[0] = NaN
  // builder.Ms[1] = NaN

  builder.HasID = true;
  // builder.IDs.Count = 2
  // builder.IDs[0] = 0
  // builder.IDs[1] = 0

  // set it empty
  builder.SetEmpty();
  // builder.Coords.Count = 0
  // builder.Zs.Count = 0
  // builder.Ms.Count = 0
  // builder.IDs.Count = 0


  // reset coordinates
  List<Coordinate2D> inCoords = new List<Coordinate2D>() { new Coordinate2D(1, 2), new Coordinate2D(3, 4), new Coordinate2D(5, 6) };
  builder.Coordinate2Ds = inCoords;
  // builder.Coords.Count = 3
  // builder.HasZ = true
  // builder.HasM = true
  // builder.HasID = true

  double[] zs = new double[] { 1, 2, 1, 2, 1, 2 };
  builder.Zs = zs;
  // builder.Zs.Count = 6

  double[] ms = new double[] { 0, 1 };
  builder.Ms = ms;
  // builder.Ms.Count = 2

  // coordinates are now   (x, y, z, m, id)
  //  (1, 2, 1, 0, 0), (3, 4, 2, 1, 0) (5, 6, 1, NaN, 0)

  MapPoint mapPointFromBuilder = builder.GetPoint(2);
  // mapPoint.HasZ = true
  // mapPoint.HasM = true
  // mapPoint.HasID = true
  // mapPoint.Z  = 1
  // mapPoint.M = NaN
  // mapPoint.ID = 0

  // add an M to the list
  builder.Ms.Add(2);
  // builder.Ms.count = 3

  // coordinates are now   (x, y, z, m, id)
  //  (1, 2, 1, 0, 0), (3, 4, 2, 1, 0) (5, 6, 1, 2, 0)

  // now get the 2nd point again; it will now have an M value
  mapPointFromBuilder = builder.GetPoint(2);
  // mapPoint.M = 2


  int[] ids = new int[] { -1, -2, -3 };
  // assign ID values
  builder.IDs = ids;

  // coordinates are now   (x, y, z, m, id)
  //  (1, 2, 1, 0, -1), (3, 4, 2, 1, -2) (5, 6, 1, 2, -3)


  // create a new point
  MapPoint pointFromBuilder = MapPointBuilderEx.CreateMapPoint(-300, 400, 4);
  builder.SetPoint(2, pointFromBuilder);

  // coordinates are now   (x, y, z, m, id)
  //  (1, 2, 1, 0, -1), (3, 4, 2, 1, -2) (-300, 400, 4, NaN, 0)


  builder.RemovePoints(1, 3);
  // builder.PointCount = 1

Modify the points of a Multipoint

// assume a multiPoint has been built from 4 points
  // the modified multiPoint will have the first point removed and the last point moved

  // use the builderEx constructors which don't need to run on the MCT.
  MultipointBuilderEx builderEx = new MultipointBuilderEx(multipoint);
  // remove the first point
  builderEx.RemovePoint(0);
  // modify the coordinates of the last point
  var ptEx = builderEx.GetPoint(builderEx.PointCount - 1);
  builderEx.RemovePoint(builderEx.PointCount - 1);

  var newPtEx = MapPointBuilderEx.CreateMapPoint(ptEx.X + 1.0, ptEx.Y + 2.0);
  builderEx.AddPoint(newPtEx);
  Multipoint modifiedMultiPointEx = builderEx.ToGeometry() as Multipoint;

Retrieve Points, 2D Coordinates, 3D Coordinates from a multipoint

ReadOnlyPointCollection pointsReadOnly = multipoint.Points;
  IReadOnlyList<Coordinate2D> coords2d = multipoint.Copy2DCoordinatesToList();
  IReadOnlyList<Coordinate3D> coords3d = multipoint.Copy3DCoordinatesToList();

Line Segment

Construct a LineSegment using two MapPoints

// Use a builderEx convenience method or use a builderEx constructor.

  MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
  MapPoint endPt = MapPointBuilderEx.CreateMapPoint(2.0, 1.0);

  // BuilderEx convenience methods don't need to run on the MCT.
  LineSegment lineFromMapPoint = LineBuilderEx.CreateLineSegment(startPt, endPt);

  // coordinate2D
  Coordinate2D start2d = (Coordinate2D)startPt;
  Coordinate2D end2d = (Coordinate2D)endPt;

  LineSegment lineFromCoordinate2D = LineBuilderEx.CreateLineSegment(start2d, end2d);

  // coordinate3D
  Coordinate3D start3d = (Coordinate3D)startPt;
  Coordinate3D end3d = (Coordinate3D)endPt;

  LineSegment lineFromCoordinate3D = LineBuilderEx.CreateLineSegment(start3d, end3d);

  // lineSegment
  LineSegment anotherLineFromLineSegment = LineBuilderEx.CreateLineSegment(lineFromCoordinate3D);


  // builderEx constructors don't need to run on the MCT
  LineBuilderEx lbEx = new LineBuilderEx(startPt, endPt);
  lineFromMapPoint = lbEx.ToSegment() as LineSegment;

  lbEx = new LineBuilderEx(start2d, end2d);
  lineFromCoordinate2D = lbEx.ToSegment() as LineSegment;

  lbEx = new LineBuilderEx(start3d, end3d);
  lineFromCoordinate3D = lbEx.ToSegment() as LineSegment;

  lbEx = new LineBuilderEx(startPt, endPt);
  lineFromMapPoint = lbEx.ToSegment() as LineSegment;

  lbEx = new LineBuilderEx(lineFromCoordinate3D);
  anotherLineFromLineSegment = lbEx.ToSegment() as LineSegment;

Alter LineSegment Coordinates

MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
  MapPoint endPt = MapPointBuilderEx.CreateMapPoint(2.0, 1.0);
  // builderEx constructors don't need to run on the MCT
  LineBuilderEx lbuilderEx = new LineBuilderEx(lineSegment);
  // find the existing coordinates
  lbuilderEx.QueryCoords(out startPt, out endPt);

  // or use 
  //startPt = lbuilderEx.StartPoint;
  //endPt = lbuilderEx.EndPoint;

  // update the coordinates
  lbuilderEx.SetCoords(GeometryEngine.Instance.Move(startPt, 10, 10) as MapPoint, GeometryEngine.Instance.Move(endPt, -10, -10) as MapPoint);

  // or use 
  //lbuilderEx.StartPoint = GeometryEngine.Instance.Move(startPt, 10, 10) as MapPoint;
  //lbuilderEx.EndPoint = GeometryEngine.Instance.Move(endPt, -10, -10) as MapPoint;

  LineSegment segment2 = lbuilderEx.ToSegment() as LineSegment;

Cubic Bezier

Construct a Cubic Bezier - from Coordinates

// Use a builderEx convenience method or a builderEx constructor.

  MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0, 3.0);
  MapPoint endPt = MapPointBuilderEx.CreateMapPoint(2.0, 2.0, 3.0);

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

  // BuilderEx convenience methods don't need to run on the MCT
  CubicBezierSegment bezier = CubicBezierBuilderEx.CreateCubicBezierSegment(startPt, ctrl1Pt, ctrl2Pt, endPt, SpatialReferences.WGS84);

  // without a SR
  bezier = CubicBezierBuilderEx.CreateCubicBezierSegment(startPt, ctrl1Pt, ctrl2Pt, endPt);


  // builderEx constructors don't need to run on the MCT
  CubicBezierBuilderEx cbbEx = new CubicBezierBuilderEx(startPt, ctrl1Pt, ctrl2Pt, endPt);
  bezier = cbbEx.ToSegment() as CubicBezierSegment;

  // another alternative
  cbbEx = new CubicBezierBuilderEx(startPt, ctrl1Pt.ToMapPoint(), ctrl2Pt.ToMapPoint(), endPt);
  bezier = cbbEx.ToSegment() as CubicBezierSegment;

Construct a Cubic Bezier - from MapPoints

// Use a builderEx convenience method or a builderEx constructor.

  MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84);
  MapPoint endPt = MapPointBuilderEx.CreateMapPoint(2.0, 2.0, SpatialReferences.WGS84);

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

  // BuilderEx convenience methods don't need to run on the MCT
  CubicBezierSegment bezier = CubicBezierBuilderEx.CreateCubicBezierSegment(startPt, ctrl1Pt, ctrl2Pt, endPt);

  // builderEx constructors don't need to run on the MCT
  CubicBezierBuilderEx cbbEx = new CubicBezierBuilderEx(startPt, ctrl1Pt, ctrl2Pt, endPt);
  bezier = cbbEx.ToSegment() as CubicBezierSegment;

Construct a Cubic Bezier - from an enumeration of MapPoints

// Use a buildeExr convenience method or use a builderEx constructor.

  MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84);
  MapPoint endPt = MapPointBuilderEx.CreateMapPoint(2.0, 2.0, SpatialReferences.WGS84);

  MapPoint ctrl1Pt = MapPointBuilderEx.CreateMapPoint(1.0, 2.0, SpatialReferences.WGS84);
  MapPoint ctrl2Pt = MapPointBuilderEx.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);

  // BuilderEx convenience methods don't need to run on the MCT
  CubicBezierSegment bezier = CubicBezierBuilderEx.CreateCubicBezierSegment(listMapPoints);

  // builderEx constructors don't need to run on the MCT
  CubicBezierBuilderEx cbbEx = new CubicBezierBuilderEx(listMapPoints);
  bezier = cbbEx.ToSegment() as CubicBezierSegment;

Cubic Bezier Builder Properties

// retrieve the bezier curve's control points

  CubicBezierBuilderEx cbbEx = new CubicBezierBuilderEx(bezierSegment);
  MapPoint startPtEx = cbbEx.StartPoint;
  Coordinate2D ctrlPt1Ex = cbbEx.ControlPoint1;
  Coordinate2D ctrlPt2Ex = cbbEx.ControlPoint2;
  MapPoint endPtEx = cbbEx.EndPoint;

  // or use the QueryCoords method
  cbbEx.QueryCoords(out startPtEx, out ctrlPt1Ex, out ctrlPt2Ex, out endPtEx);

Cubic Bezier Properties

// retrieve the bezier curve's control points
  CubicBezierSegment cb = CubicBezierBuilderEx.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

polyline = PolylineBuilderEx.CreatePolyline(bezierSegment);

Arc

Construct a Circular Arc - using an interior point

// Construct a circular arc from (2, 1) to (1, 2) with interior pt (1 + sqrt(2)/2, 1 + sqrt(2)/2).
  // Use a builderEx convenience method or use a builderEx constructor.

  MapPoint fromPtCircArc = MapPointBuilderEx.CreateMapPoint(2, 1);
  MapPoint toPtCircArc = MapPointBuilderEx.CreateMapPoint(1, 2);
  Coordinate2D interiorPtNew = new Coordinate2D(1 + Math.Sqrt(2) / 2, 1 + Math.Sqrt(2) / 2);

  // BuilderEx convenience methods don't need to run on the MCT.
  EllipticArcSegment circularArcBuilder = EllipticArcBuilderEx.CreateCircularArc(fromPtCircArc, toPtCircArc, interiorPtNew);

  // BuilderEx constructors don't need to run on the MCT.
  EllipticArcBuilderEx eab = new EllipticArcBuilderEx(fromPtCircArc, toPtCircArc, interiorPtNew);
  // do something with the builder

  EllipticArcSegment anotherCircularArc = eab.ToSegment();

Construct a Circular Arc - using a chord length and bearing

// 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.
  // Use a builderEx convenience method or use a builderEx constructor.

  MapPoint fromPtArc = MapPointBuilderEx.CreateMapPoint(2, 1, SpatialReferences.WGS84);
  double chordLength = Math.Sqrt(2);
  double chordBearing = 3 * Math.PI / 4;
  double radius = 1;
  ArcOrientation orientation = ArcOrientation.ArcCounterClockwise;
  MinorOrMajor minorOrMajor = MinorOrMajor.Minor;

  // BuildeEx convenience methods don't need to run on the MCT.
  EllipticArcSegment circularArcBuilder = EllipticArcBuilderEx.CreateCircularArc(fromPtArc, chordLength, chordBearing, radius, orientation, minorOrMajor);

  // BuilderEx constructors don't need to run on the MCT either.
  EllipticArcBuilderEx ellipticArcBuilderEx = new EllipticArcBuilderEx(fromPtArc, chordLength, chordBearing, radius, orientation, minorOrMajor);
  // do something with the builder

  EllipticArcSegment anotherCircularArc = ellipticArcBuilderEx.ToSegment();

Construct a Circular Arc - using a center point, angle and radius

// Construct a circular arc with center point at (0, 0), from angle = 0, 
  // central angle = pi/2, radius = 1.
  // Use a builderEx convenience method or use a builderEx constructor.

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

  // BuilderEx convenience methods don't need to run on the MCT.
  EllipticArcSegment circularArcBuilder = EllipticArcBuilderEx.CreateCircularArc(fromAngle, centralAngle, centerPt, radius, sr4326);

  // BuilderEx constructors don't need to run on the MCT.
  EllipticArcBuilderEx ellipticArcBuilderEx = new EllipticArcBuilderEx(fromAngle, centralAngle, centerPt, radius, sr4326);
  ellipticArcSegment = ellipticArcBuilderEx.ToSegment();

Construct an Elliptic Arc - using a center point and rotation angle

// Construct an elliptic arc centered at (1,1), startAngle = 0, centralAngle = PI/2, 
  // rotationAngle = 0, semiMajorAxis = 1, minorMajorRatio = 0.5.
  // Use a builderEx convenience method or use a builderEx constructor.

  Coordinate2D centerPt = new Coordinate2D(1, 1);

  // BuilderEx convenience methods don't need to run on the MCT.
  ellipticArcSegment = EllipticArcBuilderEx.CreateEllipticArcSegment(centerPt, 0, Math.PI / 2, 0, 1, 0.5);

  double semiMajor;
  double semiMinor;
  ellipticArcSegment.GetAxes(out semiMajor, out semiMinor);
  // semiMajor = 1, semiMinor = 0.5

  // BuilderEx constructors don't need to run on the MCT.
  EllipticArcBuilderEx ellipticArcBuilderEx = new EllipticArcBuilderEx(centerPt, 0, Math.PI / 2, 0, 1, 0.5);
  ellipticArcBuilderEx.GetAxes(out semiMajor, out semiMinor);
  EllipticArcSegment arcSegment = ellipticArcBuilderEx.ToSegment();

Construct a Circular Arc - using a center point and orientation

// Construct a circular arc from (2, 1) to (1, 2) 
  // with center point at (1, 1) and orientation counterclockwise.
  // Use a builderEx convenience method or use a builderEx constructor.

  MapPoint toPt = MapPointBuilderEx.CreateMapPoint(1, 2);
  MapPoint fromPt = MapPointBuilderEx.CreateMapPoint(2, 1);
  Coordinate2D centerPtCoord = new Coordinate2D(1, 1);

  // BuilderEx convenience methods don't need to run on the MCT.
  ellipticArcSegment = EllipticArcBuilderEx.CreateCircularArc(fromPt, toPt, centerPtCoord, ArcOrientation.ArcCounterClockwise);

  // BuilderEx constructors need to run on the MCT.
  EllipticArcBuilderEx ellipticArcBuilder = new EllipticArcBuilderEx(fromPt, toPt, centerPtCoord, ArcOrientation.ArcCounterClockwise);
  EllipticArcSegment arcSegment = ellipticArcBuilder.ToSegment();

Construct a Circular Arc - using two segments and radius

// Construct a segment from (100, 100) to (50, 50) and another segment from (100, 100) to (150, 50).
  // Use a builderEx convenience method or use a builderEx constructor.

  LineSegment segment1 = LineBuilderEx.CreateLineSegment(new Coordinate2D(100, 100), new Coordinate2D(50, 50));
  LineSegment segment2 = LineBuilderEx.CreateLineSegment(new Coordinate2D(100, 100), new Coordinate2D(150, 50));

  // Construct the hint point to determine where the arc will be constructed.
  Coordinate2D hintPoint = new Coordinate2D(100, 75);

  // Call QueryFilletRadius to get the minimum and maximum radii that can be used with these segments.
  var minMaxRadii = EllipticArcBuilderEx.QueryFilletRadiusRange(segment1, segment2, hintPoint);

  // Use the maximum radius to create the arc.
  double maxRadius = minMaxRadii.Item2;

  // BuilderEx convenience methods don't need to run on the MCT.
  //At 2.x - EllipticArcSegment circularArc = EllipticArcBuilderEx.CreateEllipticArcSegment(segment1, segment2, maxRadius, hintPoint);
  EllipticArcSegment circularArc = EllipticArcBuilderEx.CreateCircularArc(
                      segment1, segment2, maxRadius, hintPoint);

  // This EllipticArcBuilderEx constructor needs to run on the MCT either.
  EllipticArcBuilderEx cab = new EllipticArcBuilderEx(segment1, segment2, maxRadius, hintPoint);
  EllipticArcSegment otherCircularArc = cab.ToSegment();

Construct a Circle

// Construct a circle with center at (-1,-1), radius = 2, and oriented clockwise.
  // Use a builderEx convenience method or use a builderEx constructor.

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

  // Builder convenience methods don't need to run on the MCT.
  EllipticArcSegment circle = EllipticArcBuilderEx.CreateCircle(centerPtCoord, 2, ArcOrientation.ArcClockwise);
  // circle.IsCircular = true
  // circle.IsCounterClockwise = false
  // circle.IsMinor = false

  double startAngle, rotationAngle, centralAngle, semiMajor, semiMinor;
  Coordinate2D actualCenterPt;
  circle.QueryCoords(out actualCenterPt, out startAngle, out centralAngle, out rotationAngle, out semiMajor, out semiMinor);

  // semiMajor = 2.0
  // semiMinor = 2.0
  // startAngle = PI/2
  // centralAngle = -2*PI
  // rotationAngle = 0
  // endAngle = PI/2

  // This EllipticArcBuilderEx constructor doesn't need to run on the MCT.
  EllipticArcBuilderEx builder = new EllipticArcBuilderEx(centerPtCoord, 2, ArcOrientation.ArcClockwise);
  EllipticArcSegment otherCircle = builder.ToSegment();

Construct an Ellipse

// Construct an ellipse centered at (1, 2) with rotationAngle = -pi/6,  
  // semiMajorAxis = 5, minorMajorRatio = 0.2, oriented clockwise.
  // Use a builderEx convenience method or use a builderEx constructor.

  Coordinate2D centerPt = new Coordinate2D(1, 2);

  // BuilderEx convenience methods don't need to run on the MCT.
  EllipticArcSegment ellipse = EllipticArcBuilderEx.CreateEllipse(centerPt, -1 * Math.PI / 6, 5, 0.2, ArcOrientation.ArcClockwise);

  // This EllipticArcBuilderEx constructor doesn't need to run on the MCT.
  EllipticArcBuilderEx builder = new EllipticArcBuilderEx(centerPt, -1 * Math.PI / 6, 5, 0.2, ArcOrientation.ArcClockwise);
  EllipticArcSegment anotherEllipse = builder.ToSegment();

Elliptic Arc Builder Properties

// retrieve the curve's properties
  EllipticArcBuilderEx builder = new EllipticArcBuilderEx(ellipticArcSegment);
  MapPoint startPt = builder.StartPoint;
  MapPoint endPt = builder.EndPoint;
  Coordinate2D centerPt = builder.CenterPoint;
  bool isCircular = builder.IsCircular;
  bool isMinor = builder.IsMinor;
  double startAngle = builder.StartAngle;
  double endAngle = builder.EndAngle;
  double centralAngle = builder.CentralAngle;
  double rotationAngle = builder.RotationAngle;
  ArcOrientation orientation = builder.Orientation;

Elliptic Arc Properties

// retrieve the curve's control points
  EllipticArcSegment arc = EllipticArcBuilderEx.CreateEllipticArcSegment(ellipticArcSegment);
  MapPoint startPt = arc.StartPoint;
  MapPoint endPt = arc.EndPoint;
  Coordinate2D centerPt = arc.CenterPoint;
  bool isCircular = arc.IsCircular;
  bool isMinor = arc.IsMinor;
  bool isCounterClockwise = arc.IsCounterClockwise;
  bool isCurve = arc.IsCurve;
  double len = arc.Length;
  double ratio = arc.MinorMajorRatio;

  double semiMajorAxis, semiMinorAxis;
  // get the axes
  arc.GetAxes(out semiMajorAxis, out semiMinorAxis);
  // or use the properties
  // semiMajorAxis = arc.SemiMajorAxis;
  // semiMinorAxis = arc.SemiMinorAxis;

  double startAngle, centralAngle, rotationAngle;
  // or use QueryCoords to get complete information
  arc.QueryCoords(out centerPt, out startAngle, out centralAngle, out rotationAngle, out semiMajorAxis, out semiMinorAxis);

  // use properties to get angle information
  //double endAngle = arc.EndAngle;
  //centralAngle = arc.CentralAngle;
  //rotationAngle = arc.RotationAngle;
  //startAngle = arc.StartAngle;

GeometryBag

Construct GeometryBag

MapPoint point = MapPointBuilderEx.CreateMapPoint(1, 2, SpatialReferences.WebMercator);

  List<Coordinate2D> coords2DToUse = new List<Coordinate2D>()
  {
    new Coordinate2D(0, 0),
    new Coordinate2D(0, 1),
    new Coordinate2D(1, 1),
    new Coordinate2D(1, 0)
  };

  Multipoint multipointNew = MultipointBuilderEx.CreateMultipoint(coords2DToUse, SpatialReferences.WGS84);
  Polyline polylineNew = PolylineBuilderEx.CreatePolyline(coords2DToUse, SpatialReferences.WebMercator);

  GeometryBagBuilderEx builder = new GeometryBagBuilderEx(SpatialReferences.WGS84);

  GeometryBag emptyBag = builder.ToGeometry();
  // emptyBag.IsEmpty = true

  builder.AddGeometry(point);
  // builder.GeometryCount = 1

  GeometryBag geometryBag = builder.ToGeometry();
  // geometryBag.PartCount = 1
  // geometryBag.PointCount = 1
  // geometryBag.IsEmpty = false

  IReadOnlyList<ArcGIS.Core.Geometry.Geometry> geometries = geometryBag.Geometries;
  // geometries.Count = 1
  // geometries[0] is MapPoint with a sr of WGS84

  bool isEqual = geometryBag.IsEqual(emptyBag);   // isEqual = false

  builder.InsertGeometry(0, multipoint);
  geometryBag = builder.ToGeometry();
  // geometryBag.PartCount = 2

  geometries = geometryBag.Geometries;
  // geometries.Count = 2
  // geometries[0] is Multipoint
  // geometries[1] is MapPoint

  builder.AddGeometry(polyline);
  builder.RemoveGeometry(1);
  geometryBag = builder.ToGeometry();
  // geometryBag.PartCount = 2

  geometries = geometryBag.Geometries;
  // geometries.Count = 2
  // geometries[0] is Multipoint
  // geometries[1] is Polyline

Construct GeometryBag - from an enumeration of geometries

// Use a builder convenience method or use a builder constructor.

  MapPoint point = MapPointBuilderEx.CreateMapPoint(10, 20);
  List<Coordinate2D> coords = new List<Coordinate2D>() { new Coordinate2D(50, 60), new Coordinate2D(-120, -70), new Coordinate2D(40, 60) };
  Multipoint multipointNew = MultipointBuilderEx.CreateMultipoint(coords, SpatialReferences.WebMercator);
  Polyline polylineNew = PolylineBuilderEx.CreatePolyline(coords);

  string json = "{\"rings\":[[[0,0],[0,1],[1,1],[1,0],[0,0]],[[3,0],[3,1],[4,1],[4,0],[3,0]]]}";
  Polygon polygonNew = PolygonBuilderEx.FromJson(json);

  var geometries = new List<Geometry>() { point, multipoint, polyline, polygon };

  // Builder convenience methods don't need to run on the MCT.
  var bag = GeometryBagBuilderEx.CreateGeometryBag(geometries, SpatialReferences.WGS84);

  var builder = new GeometryBagBuilderEx(geometries, SpatialReferences.WGS84);
  // do something with the builder
  bag = builder.ToGeometry();

Construct GeometryBag - from JSON, Xml

const string jsonString = "{\"geometries\":[{\"x\":1,\"y\":2},{\"rings\":[[[0,0],[0,4],[3,4],[3,0],[0,0]]]}],\"spatialReference\":{\"wkid\":4326,\"latestWkid\":4326}}";
  var geometryBag = GeometryBagBuilderEx.FromJson(jsonString);

  string xml = geometryBag.ToXml();
  var xmlString = GeometryBagBuilderEx.FromXml(xml);

Construct GeometryBag - adding or inserting an enumeration of geometries

MapPoint point = MapPointBuilderEx.CreateMapPoint(10, 20);
  List<Coordinate2D> coords = new List<Coordinate2D>() { new Coordinate2D(50, 60), new Coordinate2D(-120, -70), new Coordinate2D(40, 60) };
  Multipoint multipointNew = MultipointBuilderEx.CreateMultipoint(coords, SpatialReferences.WebMercator);
  Polyline polylineNew = PolylineBuilderEx.CreatePolyline(coords);

  string json = "{\"rings\":[[[0,0],[0,1],[1,1],[1,0],[0,0]],[[3,0],[3,1],[4,1],[4,0],[3,0]]]}";
  Polygon polygonNew = PolygonBuilderEx.FromJson(json);

  var geometries = new List<Geometry>() { point, multipoint, polyline, polygon };

  var builder = new GeometryBagBuilderEx(SpatialReferences.WGS84);
  builder.AddGeometries(geometries);

  GeometryBag geomBag = builder.ToGeometry();
  // geomBag.PartCount == 4    (point, multipoint, polyline, polygon)

  geometries = new List<Geometry>() { point, polyline };
  builder.InsertGeometries(1, geometries);
  // builder.GeometryCount == 6
  geomBag = builder.ToGeometry();
  // geomBag.PartCount == 6    (point, point, polyline, multipoint, polyline, polygon)

Multipatch

Construct Multipatch via Extrusion of Polygon or Polyline

// build a polygon
  string json = "{\"hasZ\":true,\"rings\":[[[0,0,0],[0,1,0],[1,1,0],[1,0,0],[0,0,0]]],\"spatialReference\":{\"wkid\":4326}}";
  Polygon polygonNew = PolygonBuilderEx.FromJson(json);

  // extrude the polygon by an offset to create a multipatch
  multipatch = GeometryEngine.Instance.ConstructMultipatchExtrude(polygon, 2);

  // a different polygon
  json = "{\"hasZ\":true,\"rings\":[[[0,0,1],[0,1,2],[1,1,3],[1,0,4],[0,0,1]]],\"spatialReference\":{\"wkid\":4326}}";
  polygon = PolygonBuilderEx.FromJson(json);

  // extrude between z values to create a multipatch
  multipatch = GeometryEngine.Instance.ConstructMultipatchExtrudeFromToZ(polygon, -10, 20);

  // extrude along the axis defined by the coordinate to create a multipatch
  Coordinate3D coord = new Coordinate3D(10, 18, -10);
  multipatch = GeometryEngine.Instance.ConstructMultipatchExtrudeAlongVector3D(polygon, coord);

  // build a polyline
  json = "{\"hasZ\":true,\"paths\":[[[400,800,1000],[800,1400,1500],[1200,800,2000],[1800,1800,2500],[2200,800,3000]]],\"spatialReference\":{\"wkid\":3857}}";
  Polyline polylineNew = PolylineBuilderEx.FromJson(json);

  // extrude to a specific z value to create a multipatch
  multipatch = GeometryEngine.Instance.ConstructMultipatchExtrudeToZ(polyline, 500);

  Coordinate3D fromCoord = new Coordinate3D(50, 50, -500);
  Coordinate3D toCoord = new Coordinate3D(200, 50, 1000);

  // extrude between two coordinates to create a multipatch
  multipatch = GeometryEngine.Instance.ConstructMultipatchExtrudeAlongLine(polyline, fromCoord, toCoord);

Multipatch Properties

int patchIndex = 0;

  // standard geometry properties
  bool hasZ = multipatch.HasZ;
  bool hasM = multipatch.HasM;
  bool hasID = multipatch.HasID;
  bool isEmpty = multipatch.IsEmpty;
  var sr = multipatch.SpatialReference;

  // number of patches (parts)
  int patchCount = multipatch.PartCount;
  // number of points
  int pointCount = multipatch.PointCount;

  // retrieve the points as MapPoints
  ReadOnlyPointCollection pointsMultipatch = multipatch.Points;
  // or as 3D Coordinates
  IReadOnlyList<Coordinate3D> coordinates = multipatch.Copy3DCoordinatesToList();


  // multipatch materials
  bool hasMaterials = multipatch.HasMaterials;
  int materialCount = multipatch.MaterialCount;


  // multipatch textures
  bool hasTextures = multipatch.HasTextures;
  int textureVertexCount = multipatch.TextureVertexCount;

  // normals
  bool hasNormals = multipatch.HasNormals;


  // properties for an individual patch (if multipatch.PartCount > 0)
  int patchPriority = multipatch.GetPatchPriority(patchIndex);
  PatchType patchType = multipatch.GetPatchType(patchIndex);

  // patch points
  int patchPointCount = multipatch.GetPatchPointCount(patchIndex);
  int pointStartIndex = multipatch.GetPatchStartPointIndex(patchIndex);
  // the patch Points are then the points in multipatch.Points from pointStartIndex to pointStartIndex + patchPointCount 

  // if the multipatch has materials 
  if (hasMaterials)
  {
    // does the patch have a material?  
    //   materialIndex = -1 if the patch does not have a material; 
    //   0 <= materialIndex < materialCount if the patch does have materials
    int materialIndex = multipatch.GetPatchMaterialIndex(patchIndex);


    // properties for an individual material (if multipatch.MaterialCount > 0)
    var color = multipatch.GetMaterialColor(materialIndex);
    var edgeColor = multipatch.GetMaterialEdgeColor(materialIndex);
    var edgeWidth = multipatch.GetMaterialEdgeWidth(materialIndex);
    var shiness = multipatch.GetMaterialShininess(materialIndex);
    var percent = multipatch.GetMaterialTransparencyPercent(materialIndex);
    var cullBackFace = multipatch.IsMaterialCullBackFace(materialIndex);

    // texture properties
    bool isTextured = multipatch.IsMaterialTextured(materialIndex);
    if (isTextured)
    {
      int columnCount = multipatch.GetMaterialTextureColumnCount(materialIndex);
      int rowCount = multipatch.GetMaterialTextureRowCount(materialIndex);
      int bpp = multipatch.GetMaterialTextureBytesPerPixel(materialIndex);
      TextureCompressionType compressionType = multipatch.GetMaterialTextureCompressionType(materialIndex);
      var texture = multipatch.GetMaterialTexture(materialIndex);
    }
  }

  // texture coordinates (if multipatch.HasTextures = true)
  if (hasTextures)
  {
    int numPatchTexturePoints = multipatch.GetPatchTextureVertexCount(patchIndex);
    var coordinate2D = multipatch.GetPatchTextureCoordinate(patchIndex, 0);

    ICollection<Coordinate2D> textureCoordinates = new List<Coordinate2D>(numPatchTexturePoints);
    multipatch.GetPatchTextureCoordinates(patchIndex, ref textureCoordinates);
  }


  // patch normals (if multipatch.HasNormals = true)
  if (hasNormals)
  {
    //  number of normal coordinates = multipatch.GetPatchPointCount(patchIndex)
    Coordinate3D patchNormal = multipatch.GetPatchNormal(patchIndex, 0);
    ICollection<Coordinate3D> normalCoordinates = new List<Coordinate3D>(patchPointCount);
    multipatch.GetPatchNormals(patchIndex, ref normalCoordinates);
  }

Construct Multipatch

// export to binary xml
  string binaryXml = multipatch.ToBinaryXml();

  // import from binaryXML - methods need to run on the MCT
  Multipatch binaryMultipatch = MultipatchBuilderEx.FromBinaryXml(binaryXml);

  // xml export / import
  string xml = multipatch.ToXml();
  Multipatch xmlMultipatch = MultipatchBuilderEx.FromXml(xml);

  // esriShape export/import
  byte[] buffer = multipatch.ToEsriShape();
  Multipatch esriPatch = MultipatchBuilderEx.FromEsriShape(buffer);

  // or use GeometryEngine
  Multipatch patchImport = GeometryEngine.Instance.ImportFromEsriShape(EsriShapeImportFlags.EsriShapeImportDefaults, buffer, multipatch.SpatialReference) as Multipatch;

Construct Multipatch via MultipatchBuilderEx

var coords_face1 = new List<Coordinate3D>()
{
  new Coordinate3D(12.495461061000071,41.902603910000039,62.552700000000186),
  new Coordinate3D(12.495461061000071,41.902603910000039,59.504700000004959),
  new Coordinate3D(12.495461061000071,41.902576344000067,59.504700000004959),
  new Coordinate3D(12.495461061000071,41.902603910000039,62.552700000000186),
  new Coordinate3D(12.495461061000071,41.902576344000067,59.504700000004959),
  new Coordinate3D(12.495461061000071,41.902576344000067,62.552700000000186),
};

  var coords_face2 = new List<Coordinate3D>()
{
  new Coordinate3D(12.495461061000071, 41.902576344000067, 62.552700000000186),
  new Coordinate3D(12.495461061000071, 41.902576344000067, 59.504700000004959),
  new Coordinate3D(12.495488442000067, 41.902576344000067, 59.504700000004959),
  new Coordinate3D(12.495461061000071, 41.902576344000067, 62.552700000000186),
  new Coordinate3D(12.495488442000067, 41.902576344000067, 59.504700000004959),
  new Coordinate3D(12.495488442000067, 41.902576344000067, 62.552700000000186),
};

  var coords_face3 = new List<Coordinate3D>()
{
  new Coordinate3D(12.495488442000067, 41.902576344000067, 62.552700000000186),
  new Coordinate3D(12.495488442000067, 41.902576344000067, 59.504700000004959),
  new Coordinate3D(12.495488442000067, 41.902603910000039, 59.504700000004959),
  new Coordinate3D(12.495488442000067, 41.902576344000067, 62.552700000000186),
  new Coordinate3D(12.495488442000067, 41.902603910000039, 59.504700000004959),
  new Coordinate3D(12.495488442000067, 41.902603910000039, 62.552700000000186),
};

  var coords_face4 = new List<Coordinate3D>()
{
  new Coordinate3D(12.495488442000067, 41.902576344000067, 59.504700000004959),
  new Coordinate3D(12.495461061000071, 41.902576344000067, 59.504700000004959),
  new Coordinate3D(12.495461061000071, 41.902603910000039, 59.504700000004959),
  new Coordinate3D(12.495488442000067, 41.902576344000067, 59.504700000004959),
  new Coordinate3D(12.495461061000071, 41.902603910000039, 59.504700000004959),
  new Coordinate3D(12.495488442000067, 41.902603910000039, 59.504700000004959),
};

  var coords_face5 = new List<Coordinate3D>()
{
  new Coordinate3D(12.495488442000067, 41.902603910000039, 59.504700000004959),
  new Coordinate3D(12.495461061000071, 41.902603910000039, 59.504700000004959),
  new Coordinate3D(12.495461061000071, 41.902603910000039, 62.552700000000186),
  new Coordinate3D(12.495488442000067, 41.902603910000039, 59.504700000004959),
  new Coordinate3D(12.495461061000071, 41.902603910000039, 62.552700000000186),
  new Coordinate3D(12.495488442000067, 41.902603910000039, 62.552700000000186),
};

  var coords_face6 = new List<Coordinate3D>()
{
  new Coordinate3D(12.495488442000067, 41.902603910000039, 62.552700000000186),
  new Coordinate3D(12.495461061000071, 41.902603910000039, 62.552700000000186),
  new Coordinate3D(12.495461061000071, 41.902576344000067, 62.552700000000186),
  new Coordinate3D(12.495488442000067, 41.902603910000039, 62.552700000000186),
  new Coordinate3D(12.495461061000071, 41.902576344000067, 62.552700000000186),
  new Coordinate3D(12.495488442000067, 41.902576344000067, 62.552700000000186),
};

  // materials
  var materialRed = new BasicMaterial();
  materialRed.Color = System.Windows.Media.Colors.Red;

  var materialTransparent = new BasicMaterial();
  materialTransparent.Color = System.Windows.Media.Colors.White;
  materialTransparent.TransparencyPercent = 80;

  var blueTransparent = new BasicMaterial(materialTransparent);
  blueTransparent.Color = System.Windows.Media.Colors.SkyBlue;

  // create a list of patch objects
  var patchesList = new List<Patch>();

  // create the multipatchBuilderEx object
  var mpb = new ArcGIS.Core.Geometry.MultipatchBuilderEx();

  // make each patch using the appropriate coordinates and add to the patch list
  var patch = mpb.MakePatch(PatchType.Triangles);
  patch.Coords = coords_face1;
  patchesList.Add(patch);

  patch = mpb.MakePatch(PatchType.Triangles);
  patch.Coords = coords_face2;
  patchesList.Add(patch);

  patch = mpb.MakePatch(PatchType.Triangles);
  patch.Coords = coords_face3;
  patchesList.Add(patch);

  patch = mpb.MakePatch(PatchType.Triangles);
  patch.Coords = coords_face4;
  patchesList.Add(patch);

  patch = mpb.MakePatch(PatchType.Triangles);
  patch.Coords = coords_face5;
  patchesList.Add(patch);

  patch = mpb.MakePatch(PatchType.Triangles);
  patch.Coords = coords_face6;
  patchesList.Add(patch);

  patchesList[0].Material = materialRed;
  patchesList[1].Material = materialTransparent;
  patchesList[2].Material = materialRed;
  patchesList[3].Material = materialRed;
  patchesList[4].Material = materialRed;
  patchesList[5].Material = blueTransparent;

  // assign the patches to the multipatchBuilder
  mpb.Patches = patchesList;

  // check which patches currently contain the material
  var red = mpb.QueryPatchIndicesWithMaterial(materialRed);
  //   red should be [0, 2, 3, 4]
  // call ToGeometry to get the multipatch
  multipatch = mpb.ToGeometry() as Multipatch;

Construct Multipatch from another Multipatch

TextureResource brickTextureResource = null;
  BasicMaterial brickMaterialTexture = new BasicMaterial();
  var coords = new List<Coordinate3D>();

  // create the multipatchBuilderEx object
  var builder = new ArcGIS.Core.Geometry.MultipatchBuilderEx(multipatch);

  // check some properties
  bool hasM = builder.HasM;
  bool hasZ = builder.HasZ;
  bool hasID = builder.HasID;
  bool isEmpty = builder.IsEmpty;
  bool hasNormals = builder.HasNormals;

  var patches = builder.Patches;
  int patchCount = patches.Count;

  // if there's some patches
  if (patchCount > 0)
  {
    int pointCount = builder.GetPatchPointCount(0);

    // replace the first point in the first patch
    if (pointCount > 0)
    {
      // get the first point
      var pt = builder.GetPoint(0, 0);
      builder.SetPoint(0, 0, mapPoint);
    }

    // check which patches currently contain the texture
    var texture = builder.QueryPatchIndicesWithTexture(brickTextureResource);

    // assign a texture material
    patches[0].Material = brickMaterialTexture;
  }

  // update the builder for M awareness
  builder.HasM = true;
  // synchronize the patch attributes to match the builder attributes
  //   in this instance because we just set HasM to true on the builder, each patch will now get a default M value for it's set of coordinates
  builder.SynchronizeAttributeAwareness();

  // call ToGeometry to get the multipatch
  multipatch = builder.ToGeometry() as Multipatch;

  // multipatch.HasM will be true

Construct Multipatch from a 3D model file

try
  {
    var model = ArcGIS.Core.Geometry.MultipatchBuilderEx.From3DModelFile(@"c:\Temp\My3dModelFile.dae");
    bool modelIsEmpty = model.IsEmpty;
  }
  catch (FileNotFoundException)
  {
    // file not found
  }
  catch (ArgumentException)
  {
    // File extension is unsupported or cannot read the file
  }

Construct 3D special Multipatch shapes

var sr = MapView.Active.Map.SpatialReference;

  var extent = MapView.Active.Extent;
  var center = extent.Center;
  var centerZ = MapPointBuilderEx.CreateMapPoint(center.X, center.Y, 500, sr);

  // cube
  multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Cube, centerZ, 200, sr);
  // tetrahedron
  multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Tetrahedron, centerZ, 200, sr);
  // diamond
  multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Diamond, centerZ, 200, sr);
  // hexagon
  multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Hexagon, centerZ, 200, sr);

  // sphere frame
  multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.SphereFrame, centerZ, 200, 0.8, sr);
  // sphere
  multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Sphere, centerZ, 200, 0.8, sr);
  // cylinder
  multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Cylinder, centerZ, 200, 0.8, sr);
  // cone
  multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Cone, centerZ, 200, 0.8, sr);

  // use the builder to add materials or textures
  // create the multipatchBuilderEx object
  var builder = new ArcGIS.Core.Geometry.MultipatchBuilderEx(multipatch);
  //   - create a cone with a material
  builder = new MultipatchBuilderEx(MultipatchConstructType.Cone, centerZ, 200, 0.8, sr);

  BasicMaterial faceMaterial = new BasicMaterial();
  faceMaterial.Color = System.Windows.Media.Color.FromRgb(255, 0, 0);
  faceMaterial.Shininess = 150;
  faceMaterial.TransparencyPercent = 50;
  faceMaterial.EdgeWidth = 20;

  foreach (var patch in builder.Patches)
    patch.Material = faceMaterial;

  multipatch = builder.ToGeometry() as Multipatch;

Create BasicMaterial

// Create BasicMaterial with default values
  BasicMaterial material = new BasicMaterial();
  System.Windows.Media.Color color = material.Color;         // color = Colors.Black
  System.Windows.Media.Color edgeColor = material.EdgeColor; // edgeColor = Colors.Black
  int edgeWidth = material.EdgeWidth;                        // edgeWidth = 0
  int transparency = material.TransparencyPercent;           // transparency = 0
  int shininess = material.Shininess;                        // shininess = 0
  bool cullBackFace = material.IsCullBackFace;               // cullBackFace = false

  // Modify the properties
  material.Color = System.Windows.Media.Colors.Red;
  material.EdgeColor = System.Windows.Media.Colors.Blue;
  material.EdgeWidth = 10;
  material.TransparencyPercent = 50;
  material.Shininess = 25;
  material.IsCullBackFace = true;

Create BasicMaterial with JPEG texture

// read the jpeg into a buffer
  //At 3.0 you need https://www.nuget.org/packages/Microsoft.Windows.Compatibility
  //System.Drawing
  System.Drawing.Image image = System.Drawing.Image.FromFile(@"C:\temp\myImageFile.jpg");
  MemoryStream memoryStream = new MemoryStream();

  System.Drawing.Imaging.ImageFormat format = System.Drawing.Imaging.ImageFormat.Jpeg;
  image.Save(memoryStream, format);
  byte[] imageBuffer = memoryStream.ToArray();

  var jpgTexture = new JPEGTexture(imageBuffer);

  // texture properties
  int bpp = jpgTexture.BytesPerPixel;
  int columnCount = jpgTexture.ColumnCount;
  int rowCount = jpgTexture.RowCount;

  // build the textureResource and the material
  BasicMaterial material = new BasicMaterial();
  material.TextureResource = new TextureResource(jpgTexture);

Create BasicMaterial with Uncompressed texture

UncompressedTexture uncompressedTexture1 = new UncompressedTexture(new byte[10 * 12 * 3], 10, 12, 3);

  // texture properties
  int bpp = uncompressedTexture1.BytesPerPixel;
  int columnCount = uncompressedTexture1.ColumnCount;
  int rowCount = uncompressedTexture1.RowCount;

  // build the textureResource and the material
  TextureResource tr = new TextureResource(uncompressedTexture1);
  BasicMaterial material = new BasicMaterial();
  material.TextureResource = tr;

Get the texture image of a multipatch

int patchIndex = 0;
  int materialIndex = multipatch.GetPatchMaterialIndex(patchIndex);
  if (!multipatch.IsMaterialTextured(materialIndex))
    return;

  TextureCompressionType compressionType =
    multipatch.GetMaterialTextureCompressionType(materialIndex);

  string ext = compressionType == TextureCompressionType.CompressionJPEG ? ".jpg" : ".dat";
  byte[] textureBuffer = multipatch.GetMaterialTexture(materialIndex);

  Stream imageStream = new MemoryStream(textureBuffer);
  System.Drawing.Image image = System.Drawing.Image.FromStream(imageStream);
  image.Save(@"C:\temp\myImage" + ext);

Get the normal coordinate of a multipatch

if (multipatch.HasNormals)
  {
    int patchIndex = 0;
    // If the multipatch has normals, then the number of normals is equal to the number of points.
    int numNormals = multipatch.GetPatchPointCount(patchIndex);

    for (int pointIndex = 0; pointIndex < numNormals; pointIndex++)
    {
      Coordinate3D normal = multipatch.GetPatchNormal(patchIndex, pointIndex);

      // Do something with the normal coordinate.
    }
  }

Get the normals of a multipatch

if (multipatch.HasNormals)
  {
    // Allocate the list only once
    int numPoints = multipatch.PointCount;
    ICollection<Coordinate3D> normals = new List<Coordinate3D>(numPoints);

    // The parts of a multipatch are also called patches
    int numPatches = multipatch.PartCount;

    for (int patchIndex = 0; patchIndex < numPatches; patchIndex++)
    {
      multipatch.GetPatchNormals(patchIndex, ref normals);

      // Do something with the normals for this patch.
    }
  }

Get the material properties of a multipatch

if (multipatch.HasMaterials)
  {
    int patchIndex = 0;
    // Get the material index for the specified patch.
    int materialIndex = multipatch.GetPatchMaterialIndex(patchIndex);

    System.Windows.Media.Color color = multipatch.GetMaterialColor(materialIndex);
    int tranparencyPercent = multipatch.GetMaterialTransparencyPercent(materialIndex);
    bool isBackCulled = multipatch.IsMaterialCullBackFace(materialIndex);

    if (multipatch.IsMaterialTextured(materialIndex))
    {
      int bpp = multipatch.GetMaterialTextureBytesPerPixel(materialIndex);
      int columnCount = multipatch.GetMaterialTextureColumnCount(materialIndex);
      int rowCount = multipatch.GetMaterialTextureRowCount(materialIndex);
    }
  }

Multiparts

Get the individual parts of a multipart feature

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 polygonNew = inputGeometry as Polygon;

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

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

Get the outermost rings of a polygon

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
    var parts = MultipartToSinglePart(polygon); //any polygon

    // 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.Instance.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);
    }

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

    // the final geometry of the outer rings
    var outerRingsResult =  outerRings.ToGeometry();

Retrieve Geometry from Geodatabase

Retrieve Geometry from Geodatabase

// methods need to run on the MCT
  ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
  {
    try
    {
      // open a gdb
      using (ArcGIS.Core.Data.Geodatabase gdb =
                new ArcGIS.Core.Data.Geodatabase(
                    new FileGeodatabaseConnectionPath(new Uri(@"c:\Temp\MyDatabase.gdb"))))
      {
        //Open a featureClass 
        using (ArcGIS.Core.Data.FeatureClass featureClass =
                       gdb.OpenDataset<ArcGIS.Core.Data.FeatureClass>("Polygon"))
        {

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

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

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

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

Import, Export Geometries

Import and Export Geometries to well-known Text

// create a point with z, m
  MapPoint point = MapPointBuilderEx.CreateMapPoint(
           100, 200, 300, 400, SpatialReferences.WebMercator);

  // set the flags
  WktExportFlags wktExportFlags = WktExportFlags.WktExportDefaults;
  WktImportFlags wktImportFlags = WktImportFlags.WktImportDefaults;

  // export and import
  string wktString = GeometryEngine.Instance.ExportToWKT(wktExportFlags, point);
  MapPoint importPointGeom = GeometryEngine.Instance.ImportFromWKT(
        wktImportFlags, wktString, SpatialReferences.WebMercator) as MapPoint;

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

  // export without z
  WktExportFlags exportFlagsNoZ = WktExportFlags.WktExportStripZs;
  wktString = GeometryEngine.Instance.ExportToWKT(exportFlagsNoZ, point);
  importPointGeom = GeometryEngine.Instance.ImportFromWKT(
    wktImportFlags, wktString, SpatialReferences.WebMercator) as MapPoint;

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

  // export without m
  WktExportFlags exportFlagsNoM = WktExportFlags.WktExportStripMs;
  wktString = GeometryEngine.Instance.ExportToWKT(exportFlagsNoM, point);
  importPointGeom = GeometryEngine.Instance.ImportFromWKT(
    wktImportFlags, wktString, SpatialReferences.WebMercator) as MapPoint;

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

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

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

Import and Export Geometries to well-known Binary

// 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 = PolylineBuilderEx.CreatePolyline(
              coords, SpatialReferences.WGS84);

  WkbExportFlags wkbExportFlags = WkbExportFlags.WkbExportDefaults;
  WkbImportFlags wkbImportFlags = WkbImportFlags.WkbImportDefaults;

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


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

Import and Export Geometries to EsriShape

// create an envelope
  List<MapPoint> coordsZM = new List<MapPoint>
{
  MapPointBuilderEx.CreateMapPoint(1001, 1002, 1003, 1004),
  MapPointBuilderEx.CreateMapPoint(2001, 2002, Double.NaN, 2004),
  MapPointBuilderEx.CreateMapPoint(3001, -3002, 3003, 3004),
  MapPointBuilderEx.CreateMapPoint(1001, -4002, 4003, 4004)
};

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

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

  // export without z,m
  buffer = GeometryEngine.Instance.ExportToEsriShape(
          EsriShapeExportFlags.EsriShapeExportStripZs |
          EsriShapeExportFlags.EsriShapeExportStripMs, envelope);
  importedPolygon = GeometryEngine.Instance.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.Instance.GetEsriShapeSize(
                                         exportFlags, envelope);
  buffer = new byte[bufferSize];

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

  // or use the envelope and envelopeBuilderEx classes
  buffer = envelope.ToEsriShape();
  // buffer represents a polygon as there is not an envelope Esri shape buffer
  // EnvelopeBuilderEx.FromEsriShape takes a polygon Esri shape buffer and returns the extent of the polygon.
  importedEnvelope = EnvelopeBuilderEx.FromEsriShape(buffer);

Import and Export Geometries to JSON

// MapPoint
  string inputString =
    "{\"x\":1,\"y\":2,\"spatialReference\":{\"wkid\":4326,\"latestWkid\":4326}}";
  Geometry geometryFromJson = GeometryEngine.Instance.ImportFromJson(
    JsonImportFlags.JsonImportDefaults, inputString);

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

  // use the MapPointBuilderEx convenience method
  MapPoint importPoint2 = MapPointBuilderEx.FromJson(inputString);
  // importPoint2 = 1, 2
  // impointPoint2.SpatialReference.Wkid = 4326

  string outputString = GeometryEngine.Instance.ExportToJson(
    JsonExportFlags.JsonExportDefaults, importPoint);
  // outputString =
  //   "{\"x\":1,\"y\":2,\"spatialReference\":{\"wkid\":4326,\"latestWkid\":4326}}"

  string outputString2 = importPoint.ToJson();

  inputString =
    "{\"spatialReference\":{\"wkid\":4326},\"z\":3,\"m\":4,\"x\":1,\"y\":2}";
  importPoint = GeometryEngine.Instance.ImportFromJson(
    JsonImportFlags.JsonImportDefaults, inputString) as MapPoint;
  // importPoint.HasM = true
  // importPoint.HasZ = true
  // importPoint.X = 1
  // importPoint.Y = 2
  // importPoint.M = 4
  // importPoint.Z = 3

  importPoint2 = MapPointBuilderEx.FromJson(inputString);

  // export to json - skip spatial reference
  outputString = GeometryEngine.Instance.ExportToJson(
                JsonExportFlags.JsonExportSkipCRS, importPoint);
  // outputString = "{\"x\":1,\"y\":2,\"z\":3,\"m\":4}"

  // export from mappoint, skipping the sr - same as GeometryEngine.Instance.ExportToJson w JsonExportFlags.JsonExportSkipCRS
  outputString2 = importPoint.ToJson(true);

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

  Multipoint multipointFromCoords = MultipointBuilderEx.CreateMultipoint(
    coords, SpatialReferences.WebMercator);

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

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

  // use the MultipointbuilderEx convenience method
  Multipoint importMultipoint2 = MultipointBuilderEx.FromJson(inputString);
  // importMultipoint2.IsEqual(multipoint) = true

  // export to json
  outputString = GeometryEngine.Instance.ExportToJson(
                  JsonExportFlags.JsonExportDefaults, multipointFromCoords);
  // outputString = inputString

  // or use the multipoint itself
  outputString2 = multipointFromCoords.ToJson();

  //
  // Polyline
  //
  Polyline polylineFromCoords = PolylineBuilderEx.CreatePolyline(
                           coords, SpatialReferences.WebMercator);

  // export without the spatial reference
  outputString = GeometryEngine.Instance.ExportToJson(
                          JsonExportFlags.JsonExportSkipCRS, polylineFromCoords);
  // import
  geometry = GeometryEngine.Instance.ImportFromJson(
               JsonImportFlags.JsonImportDefaults, outputString);
  Polyline importPolyline = geometryFromJson as Polyline;
  // importPolyline.SpatialReference = null


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

  // use the polylineBuilderEx convenience method 
  Polyline importPolyline2 = PolylineBuilderEx.FromJson(outputString);
  // importPolyline2 = importPolyline

  outputString2 = importPolyline2.ToJson();
  // outputString2 = outputString

  //
  // Polygon
  //
  Polygon polygonFromCoords = PolygonBuilderEx.CreatePolygon(
                                coords, SpatialReferences.WebMercator);

  // export without the spatial reference
  outputString = GeometryEngine.Instance.ExportToJson(
                            JsonExportFlags.JsonExportSkipCRS, polygonFromCoords);
  // import
  geometryFromJson = GeometryEngine.Instance.ImportFromJson(
                       JsonImportFlags.JsonImportDefaults, outputString);

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

  // polygonBuilderEx convenience method
  Polygon importPolyon2 = PolygonBuilderEx.FromJson(outputString);
  // importPolygon2 = importPolygon

  // export from the polygon
  outputString2 = importPolyon2.ToJson(true);

  // Empty polygon
  polygon = PolygonBuilderEx.CreatePolygon(SpatialReferences.WebMercator);
  outputString = GeometryEngine.Instance.ExportToJson(
                                 JsonExportFlags.JsonExportDefaults, polygon);
  importPolygon = GeometryEngine.Instance.ImportFromJson(
                      JsonImportFlags.JsonImportDefaults, outputString) as Polygon;

  // importPolygon.IsEmpty = true
  // importPolygon.SpatialReference.Wkid = 3857

Import and Export Geometries to XML

MapPoint minPoint = MapPointBuilderEx.CreateMapPoint(1, 1, 1, 1, 3);
  MapPoint maxPoint = MapPointBuilderEx.CreateMapPoint(5, 5, 5);

  // 
  //  MapPoint
  // 
  string xml = minPoint.ToXml();
  MapPoint minPointImport = MapPointBuilderEx.FromXml(xml);
  // minPointImport = minPoint

  //
  // Envelope
  //
  Envelope envelopeWithID = EnvelopeBuilderEx.CreateEnvelope(minPoint, maxPoint);

  // Envelopes don't have IDs
  // envelopeWithID.HasID = false
  // envelopeWithID.HasM = true
  // envelopeWithID.HasZ = true

  xml = envelopeWithID.ToXml();
  Envelope envelopeImport = EnvelopeBuilderEx.FromXml(xml);

  //
  // Multipoint
  //
  List<MapPoint> list = new List<MapPoint>();
  list.Add(minPoint);
  list.Add(maxPoint);

  Multipoint multiPoint = MultipointBuilderEx.CreateMultipoint(list);

  xml = multiPoint.ToXml();
  Multipoint multipointImport = MultipointBuilderEx.FromXml(xml);
  // multipointImport.PointCount == 2
  // multipointImport.HasID = true
  // multipointImport.HasM = true
  // multipointImport.HasZ= true

Transformations

Create Geographic Transformation

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

  // 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

  var wkt = gt0.Wkt;
  // create from string 
  CompositeGeographicTransformation third_cgt =
     ArcGIS.Core.Geometry.CompositeGeographicTransformation.Create(wkt, gt0.IsForward);
  count = third_cgt.Count;        // count = 1

  // create from josn
  string json = cgt.ToJson();
  CompositeGeographicTransformation joson_cgt =
    DatumTransformation.CreateFromJson(json) as CompositeGeographicTransformation;

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 = EnvelopeBuilderEx.CreateEnvelope(
               new Coordinate2D(2, 2), new Coordinate2D(3, 3), sr4267);

    // Project with one geo transform 4267 -> 3857
    Envelope projectedEnvEx = GeometryEngine.Instance.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.Instance.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

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

  // create from xml
  string xml = compositehv.ToXml();

  var xml_compositehv = CompositeHVDatumTransformation.CreateFromXml(xml);

  // create from json
  string json = compositehv.ToJson();
  CompositeHVDatumTransformation json_compositehv =
      DatumTransformation.CreateFromJson(json) as CompositeHVDatumTransformation;

Determine Transformations

// methods need to run on the MCT
  ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
  {
    //
    // find the first transformation used between spatial references 4267 and 4326
    //
    SpatialReference sr4267 =
         SpatialReferenceBuilder.CreateSpatialReference(4267);
    SpatialReference sr4326 = SpatialReferences.WGS84;

    List<ProjectionTransformation> transformations =
           ProjectionTransformation.FindTransformations(sr4267, sr4326);
    // transformations.Count = 1
    ProjectionTransformation projTrans = transformations[0];
    CompositeGeographicTransformation compositeGT =
         projTrans.Transformation as CompositeGeographicTransformation;
    GeographicTransformation gt = compositeGT[0];
    // gt.Wkid = 15851
    // gt.Name = "NAD_1927_To_WGS_1984_79_CONUS"
    // gt.IsForward = true


    //
    // find the first five transformation used between spatial references 4267 and 4326
    //
    transformations = ProjectionTransformation.FindTransformations(
                                       sr4267, sr4326, numResults: 5);
    // transformations.Count = 5
    projTrans = transformations[0];
    compositeGT = projTrans.Transformation as CompositeGeographicTransformation;
    // compositeGT.Count = 1
    // compositeGT[0].Wkid = 15851
    // compositeGT[0].Name = "NAD_1927_To_WGS_1984_79_CONUS"
    // compositeGT[0].IsForward = true

    projTrans = transformations[1];
    compositeGT = projTrans.Transformation as CompositeGeographicTransformation;
    // compositeGT.Count = 1
    // compositeGT[0].Wkid = 1173
    // compositeGT[0].Name = "NAD_1927_To_WGS_1984_4"
    // compositeGT[0].IsForward = true

    projTrans = transformations[2];
    compositeGT = projTrans.Transformation as CompositeGeographicTransformation;
    // compositeGT.Count = 1
    // compositeGT[0].Wkid = 1172
    // compositeGT[0].Name = "NAD_1927_To_WGS_1984_3"
    // compositeGT[0].IsForward = true

    projTrans = transformations[3];
    compositeGT = projTrans.Transformation as CompositeGeographicTransformation;
    // compositeGT.Count = 2
    // compositeGT[0].Wkid = 1241
    // compositeGT[0].Name = "NAD_1927_To_NAD_1983_NADCON"
    // compositeGT[0].IsForward = true

    // compositeGT[1].Wkid = 108190
    // compositeGT[1].Name = "WGS_1984_(ITRF00)_To_NAD_1983"
    // compositeGT[1].IsForward = false

    projTrans = transformations[4];
    compositeGT = projTrans.Transformation as CompositeGeographicTransformation;
    // compositeGT.Count = 2
    // compositeGT[0].Wkid = 1241
    // compositeGT[0].Name = "NAD_1927_To_NAD_1983_NADCON"
    // compositeGT[0].IsForward = true

    // compositeGT[1].Wkid = 1515
    // compositeGT[1].Name = "NAD_1983_To_WGS_1984_5"
    // compositeGT[1].IsForward = true


    //
    // find the first transformation used between spatial
    // references 4267 and 4326 within Alaska
    //

    // Alaska
    Envelope envelope = EnvelopeBuilderEx.CreateEnvelope(-161, 61, -145, 69);
    transformations = ProjectionTransformation.FindTransformations(
                                                sr4267, sr4326, envelope);
    // transformations.Count = 1
    projTrans = transformations[0];
    compositeGT = projTrans.Transformation as CompositeGeographicTransformation;
    // compositeGT.Count = 2
    // compositeGT[0].Wkid = 1243
    // compositeGT[0].Name = "NAD_1927_To_NAD_1983_Alaska"
    // compositeGT[0].IsForward = true

    // compositeGT[1].Wkid = 108190
    // compositeGT[1].Name = "WGS_1984_(ITRF00)_To_NAD_1983"
    // compositeGT[1].IsForward = false


    //
    // find the first geographic transformation used between two spatial references with VCS  (use vertical = false)
    //
    SpatialReference inSR =
                    SpatialReferenceBuilder.CreateSpatialReference(4269, 115702);
    SpatialReference outSR =
                    SpatialReferenceBuilder.CreateSpatialReference(4326, 3855);

    // Even though each spatial reference has a VCS,
    // vertical = false should return geographic transformations.
    transformations = ProjectionTransformation.FindTransformations(inSR, outSR);
    // transformations.Count = 1
    projTrans = transformations[0];
    compositeGT = projTrans.Transformation as CompositeGeographicTransformation;
    // compositeGT.Count = 1
    // compositeGT[0].Wkid = 108190
    // compositeGT[0].Name = ""WGS_1984_(ITRF00)_To_NAD_1983"
    // compositeGT[0].IsForward = false

    //
    // find the first vertical transformation used between two spatial references with VCS  (use vertical = true)
    //

    transformations =
              ProjectionTransformation.FindTransformations(
                                      inSR, outSR, vertical: true);
    // transformations.Count = 1
    projTrans = transformations[0];

    CompositeHVDatumTransformation compositeHV =
            projTrans.Transformation as CompositeHVDatumTransformation;
    // compositeHV.Count = 2
    // compositeHV[0].Wkid = 1188
    // compositeHV[0].Name = "NAD_1983_To_WGS_1984_1"
    // compositeHV[0].IsForward = true

    // compositeHV[1].Wkid = 110019
    // compositeHV[1].Name = "WGS_1984_To_WGS_1984_EGM2008_2.5x2.5_Height"
    // compositeHV[1].IsForward = true
  });

MapPoint GeoCoordinateString

MapPoint - GeoCoordinateString Conversion

SpatialReference sr = SpatialReferences.WGS84;
  SpatialReference sr2 = SpatialReferences.WebMercator;

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

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

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

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

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

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


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

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

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

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

AngularUnit

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);

  // get the wkt
  string wkt = myAngularUnit.Wkt;

  // create an angular unit from this wkt
  var anotherAngularUnit = AngularUnit.CreateAngularUnit(wkt);
  // anotherAngularUnit.ConversionFactor = 3
  // anotherAngularUnit.FactoryCode = 0    
  // anotherAngularUnit.RadiansPerUnit = 3

LinearUnit

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);

  // get the wkt
  string lu_wkt = myLinearUnit.Wkt;

  // create an angular unit from this wkt
  var anotherLinearUnit = LinearUnit.CreateLinearUnit(lu_wkt);
  // anotherLinearUnit.ConversionFactor = 0.33
  // anotherLinearUnit.FactoryCode = 0    
  // anotherLinearUnit.MetersPerUnit = 0.33

AreaUnit

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 - How many Square meters in various units

double sqMetersPerUnit = AreaUnit.Acres.SquareMetersPerUnit;
  sqMetersPerUnit = AreaUnit.Ares.SquareMetersPerUnit;
  sqMetersPerUnit = AreaUnit.Hectares.SquareMetersPerUnit;
  sqMetersPerUnit = AreaUnit.SquareKilometers.SquareMetersPerUnit;
  sqMetersPerUnit = AreaUnit.SquareMiles.SquareMetersPerUnit;
  sqMetersPerUnit = AreaUnit.SquareYards.SquareMetersPerUnit;

AreaUnit - Create an AreaUnit

try
  {
    var myFactoryCodeInit = AreaUnit.CreateAreaUnit(109439);     // 109439 is the factory code for square miles

    var myWktUnit = AreaUnit.CreateAreaUnit("HECTARE_AREAUNIT[\"H\",10000.0]");

    var myCustomUnit = AreaUnit.CreateAreaUnit("myAreaUnit", 12);
  }
  catch (ArgumentException)
  {
    // ArgumentException will be thrown by CreateAreaUnit in the following scenarios
    // - if the factory code used is a non-areal factory code  (i.e. it corresponds to degrees which is an angular unit code)
    // - if the factory code used is invalid (i.e. it is negative or doesn't correspond to any factory code)
  }
⚠️ **GitHub.com Fallback** ⚠️