Extracting elliptical properties from TrackCircle() geometry

450
3
Jump to solution
03-29-2012 04:04 AM
ManfredLauterbach
Occasional Contributor
Hi,

Previously, in the wonderful adventures of Map Objects V2, getting the radius and centroid of a user tracked circle on the map was as easy as calling a line-liner:

  Ellipse ellipse = map.TrackCircle();   TheCakeIsReal(ellipse.Center, ellipse.radius);


In Arc Objects 10, the universal forces of ESRI and Wheatley incorporated have decided to makes things a little more interesting.

> Searched the forums for TrackCircle, but the 3 hits (http://forums.arcgis.com/search.php?searchid=997900) don't elaborate on extracting properties of the returned geometry.
> The official API (http://help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/index.html#//001600000201000000) also has a wonderful little description : "TrackCircle returns a geometry object that implements IPolygon.".
> Having a look at older forums (http://forums.esri.com/Thread.asp?c=159&f=1706&t=159785) brings me a bit closer to the lost treasure of Atlantis, but they are calling a method called 'SetGeometry' on CircleElement, which no longer exists in the ArcObjects 10 API... and has been wiped off the ISurface of existence.
> I see that GeoEllipse is part of the Military Defence solutions extension - but I would like to be able to extract simple ellipse/circle properties without installing an extension to plan for world war 3.

Tried the following to extract elliptical properties, but all three test candidates realize that the cake is a lie when they have to face the truth that they are not compatible with the returned geometry (polyline) :
      IPolygon polygon = mapControl.TrackCircle() as IPolygon;        CircularArc circularArc = polygon as CircularArc;       CircleElement circleElement = polygon as CircleElement;       RubberCircle rubberCircle = polygon as RubberCircle;               //... circularArc.CenterPoint ?       //... circularArc.Radius ?       


Once again, could someone please point me in the right direction (for this apparently trivial operation)?
Thanks!
0 Kudos
1 Solution

Accepted Solutions
NeilClemmons
Regular Contributor III
The polygon returned by TrackCircle is indeed a circle.  A polygon is several things.  It's a point collection.  The point collection contains all of the points that make up the polygon.  In the case of a circle, the polygon is made up of a single circular arc.  A circular arc is a type of line segment that defined by the boundary of a true circle.  In the case of a complete circle, the circular arc begins and ends at the same point.  Therefore, the point collection of a polygon that is a circle will contain two points and these points will have identical coordinates.  A polygon is a segment collection.  The segment collection contains all of the line segments that make up the polygon.  In the case of a circle, the segment collection will contain a single segment that is a circular arc.  A polygon is also a geometry collection.  The geometry collection contains the collection of rings that make up the polygon.  Multi-part polygons or polygons with "holes" (a donut for example) are cases where a polygon's geometry collection will contain more than one ring.

So, if you want the center point and radius of a circle polygon then you need to get the circular arc segment from the segment collection.  ICircularArc has CenterPoint and Radius properties that you can access.

Dim segmentCollection As ISegmentCollection = DirectCast(polygon, ISegmentCollection)
Dim circularArc As ICircularArc = DirectCast(segmentCollection.Segment(0), ICircularArc)
Dim centerPoint As IPoint = circularArc.CenterPoint
Dim radius As Double = circularArc.Radius

View solution in original post

0 Kudos
3 Replies
ManfredLauterbach
Occasional Contributor
What is furthermore confusing, are the properties of the polygon (which the geometry claims to be, according to IGeometry.GeometryType) :

      IGeometry geometry = mapControl.TrackCircle();
      if (geometry.GeometryType == esriGeometryType.esriGeometryPolygon)
      {
        Polygon polygon = geometry as Polygon;
        if (polygon.PointCount == 2)
        {
          string polyInfoStr = String.Format("Point 1 : [{0:f2}, {1:f2}]\nPoint 2 : [{2:f2},{3:f2}]", polygon.Point[0].X, polygon.Point[0].Y, polygon.Point[1].X, polygon.Point[1].Y);
          MessageBox.Show(polyInfoStr);
        }
      }


Running the code above displays a message with 2 coordinates that are exactly the same.
This would imply that the geometry returned from TrackCircle(), is actually a Polygon with two points, which have exactly the same coordinates.

If the first coordinate were the centroid and the second point were the point on the circumference (representing the mouse up location for the track circle operation) then I would understand, but this is clearly not the case - I made sure that the tracked circle diameter spans a few thousand miles, but the returned coordinates are still equal.


To clarify why I'm expecting different coordinates, the following code tracks a polyline, and display the points in a similar manner. They are displayed correctly:
      IGeometry geometry = mapControl.TrackLine();
      IPointCollection pointCollection = geometry as IPointCollection;
      StringBuilder pointsInfoStr = new StringBuilder();

      for (int pointIndex = 0; pointIndex < pointCollection.PointCount; pointIndex++)
      {
        IPoint curPoint = pointCollection.Point[pointIndex];
        string pointInfo = String.Format("Point {0} : [{1:f2}, {2:f2}]", pointIndex + 1, curPoint.X, curPoint.Y);
        pointsInfoStr.AppendLine(pointInfo);
      }

      MessageBox.Show(pointsInfoStr.ToString());
0 Kudos
NeilClemmons
Regular Contributor III
The polygon returned by TrackCircle is indeed a circle.  A polygon is several things.  It's a point collection.  The point collection contains all of the points that make up the polygon.  In the case of a circle, the polygon is made up of a single circular arc.  A circular arc is a type of line segment that defined by the boundary of a true circle.  In the case of a complete circle, the circular arc begins and ends at the same point.  Therefore, the point collection of a polygon that is a circle will contain two points and these points will have identical coordinates.  A polygon is a segment collection.  The segment collection contains all of the line segments that make up the polygon.  In the case of a circle, the segment collection will contain a single segment that is a circular arc.  A polygon is also a geometry collection.  The geometry collection contains the collection of rings that make up the polygon.  Multi-part polygons or polygons with "holes" (a donut for example) are cases where a polygon's geometry collection will contain more than one ring.

So, if you want the center point and radius of a circle polygon then you need to get the circular arc segment from the segment collection.  ICircularArc has CenterPoint and Radius properties that you can access.

Dim segmentCollection As ISegmentCollection = DirectCast(polygon, ISegmentCollection)
Dim circularArc As ICircularArc = DirectCast(segmentCollection.Segment(0), ICircularArc)
Dim centerPoint As IPoint = circularArc.CenterPoint
Dim radius As Double = circularArc.Radius
0 Kudos
ManfredLauterbach
Occasional Contributor
ah, Excellent. thanks.
your response was perfect, and also explains the methodology for handling other ArcObjects objects.

In the mean time... (as is usually the case when one finds a solution), one finds another solution, staring me right in face!
Figured out that the returned geometry can simply be queried for its bounding envelope, and consequently also the centroid.
      IGeometry geometry = mapControl.TrackCircle();
      double radius = geometry.Envelope.Width / 2;
      IPoint centroid = ((EnvelopeClass)geometry.Envelope).Centroid;
0 Kudos