5 Replies Latest reply on Jun 12, 2014 7:02 AM by purpledunes

    Radius of a circle drawn as a polygon

    kunal.mehta@sap.com
      All,

      I found this solution to draw a circle as a polygon of 360 points:

      -(AGSPolygon*) circleWithCenter:(AGSPoint*)point raduis:(double)radius
      {
          AGSMutablePolygon * p = [AGSMutablePolygon new];
          [p addRingToPolygon];
          int pointsCount = 360;
          double slice = 2 * M_PI / pointsCount;
          for(int i = 0; i<pointsCount;i++){
              double rad = slice * i;
              double px = point.x + radius * cos(rad);
              double py = point.y + radius * sin(rad);
              [p addPointToRing:[AGSPoint pointWithX:px y:py spatialReference:[AGSSpatialReference spatialReferenceWithWKID:4326]]];
          }
         
          return p;
      }


      The question I have is what is the units of the radius passed in? For example, if I want to draw a circle of raduis 10 miles, what value do I pass in? If I pass in 10, it just draws a really huge circle with radius several multiples of 10!

      I tried to look into the sdk api docs and could not find much info, so any help will be appreciated.
        • Re: Radius of a circle drawn as a polygon
          DGoyal-esristaff
          Since you're using the WGS84 spatial reference, the value 10 is assumed to be in decimal degrees.
          At the equator, 1 degree = 69 miles (approx).
          So if you want 10 miles, you should use 10/69 as radius
          • Re: Radius of a circle drawn as a polygon
            NFurness-esristaff
            The units will be decimal degrees.

            What you might find useful is to buffer around your center-point.

            Try something like this:

            -(AGSPolygon*) circleWithCenter:(AGSPoint*)point radius:(double)radiusInMiles
            {
                AGSGeometryEngine *ge = [AGSGeometryEngine defaultGeometryEngine];
            
                // Get a point in a spatial reference whose unit is Meters.
                AGSPoint *pointToBufferAround = (AGSPoint *)[ge projectGeometry:point toSpatialReference:[AGSSpatialReference webMercatorSpatialReference]];
            
                // Get a "circle" around it, using the unit Meters (1 mile ~= 1609.344 meters).
                AGSPolygon *circle = [ge bufferGeometry:pointToBufferAround byDistance:radiusInMiles*1609.344];
            
                // Project the output back to the projection of the input point (which is presumably what you're after).
                circle = (AGSPolygon *)[ge projectGeometry:circle toSpatialReference:point.spatialReference];
            
                return circle;
            }
            


            That will use Meters (WebMercator's units). Note that your output may not be what you expect as the input or output approaches the poles. Also, there's no guarantee how many points the output polygon will have in its boundary.
            • Re: Radius of a circle drawn as a polygon
              kunal.mehta@sap.com
              Thanks nfurness and Technobrat for your solutions.

              Both work, however, per nfurness's solution using buffer around the center point and webMercatorSpatialReference, I am getting an oval shape rather than a circle. Is this expected?
              • Re: Radius of a circle drawn as a polygon
                NFurness-esristaff
                Could be. Depends on what the projection is of your map. I'm guessing it's not Web Mercator :D

                My solution will generate you a polygon that is pretty close to circular on the ground (i.e the edge is R miles north and R miles east of the center). If you are using a Web Mercator projection, it will appear circular on the map. If you are using WGS84 for example, it will indeed appear less tall as you move north or south from the equator, by virtue of the projection.

                If you want something that looks circular on a WGS84 map, and you know that your center point is WGS84, you can either use your & Technobrat's solution or something like this:

                -(AGSPolygon*) circleWithCenter:(AGSPoint*)point radius:(double)radiusInMiles
                {
                    AGSGeometryEngine *ge = [AGSGeometryEngine defaultGeometryEngine];
                
                    // Get a "circle" around the point, using the 1 decimal degree ~= 69 miles.
                    AGSPolygon *circle = [ge bufferGeometry:point byDistance:radiusInMiles/69];
                
                    return circle;
                }


                But remember that this is approximating the conversion between decimal degrees and meters, which is not constant for longitude as latitude varies.

                So, it really depends on what you are generating the 10 mile radius geometry for and (in short) how far north or south of the equator. Your solution may be good enough for what you want, but bear in mind that a degree of longitude will be very much less than 69 miles as you approach the poles. On the other hand, your application users may keep asking you why the "circle" is elliptical, and that might be a bigger headache than considering some things that might be more than 10 miles away.
                • Re: Radius of a circle drawn as a polygon
                  purpledunes
                  How do I go about adding this to a graphics layer?