mousebird-consulting-inc / WhirlyGlobe

WhirlyGlobe Development
Other
830 stars 255 forks source link

Draw circle line #536

Closed jerald-acacus closed 3 years ago

jerald-acacus commented 8 years ago

I know that there are Circle, Sphere and Cylinder using MaplyShape. But is there any feature that allows me to draw a circle using a line? Much like VectorObject but is a circle.

mousebird commented 8 years ago

So a vector feature that's just a sampled circle? No, you'd have to sample it yourself.

jerald-acacus commented 8 years ago

I was thinking of drawing a line from a circle of points around a center in a location in the map. But I am thinking that this might not result to a smoothly shaped circle, rather a circle with flat edges much like a polygon.

jerald-acacus commented 8 years ago

Is this kind of circle on the map possible using a vector?

screen shot 2016-03-08 at 9 29 45 am
mousebird commented 8 years ago

Yes, that's how I'd do it. The trick is to sample it finely enough to get a smooth circle.

jerald-acacus commented 8 years ago

Sorry to ask this but can you please elaborate what you mean in "sample/sampling"? Is there any part in WhirlyGlobe source that I can take a look at as for example?

The above image is MKCircleRenderer in MapKit and that is what I am going for.

mousebird commented 8 years ago

You could make a MaplyVectorObject with a circle. Just use sin and cos around a point.

jerald-acacus commented 8 years ago

I finally got to draw a circle on the globe and map. However, it looks weird on the map when it is near the north/south pole. Is this normal because of the globe's projection? I tried also a MaplyShapeCircle but it seems to draw the circle perfectly from the center and over the north pole.

Blue line is the MaplyVectorObject circle, purple is the MaplyShapeCircle.

1

2

jerald-acacus commented 8 years ago
[self drawCircleWithRadius:20 withCoordinates:-68 lat:76 angle:1];

- (void)drawCircleWithRadius:(float)radius withCoordinates:(float)lon lat:(float)lat angle:(float)angle {

    MaplyScreenMarker *marker = [[MaplyScreenMarker alloc] init];
    marker.image = [UIImage imageNamed:@"marker"];
    marker.size = CGSizeMake(25, 25);
    marker.loc = MaplyCoordinateMakeWithDegrees(lon, lat);
    marker.layoutImportance = MAXFLOAT;
    [self.maplyVC addScreenMarkers:@[marker] desc:nil];

    float x = 0;
    float y = 0;

    int num = 100;

    MaplyCoordinate coords[num];

    for (int i = 0; i < num; i++) {
        x = lat + radius * sin(i * 2 * M_PI/num);
        y = lon + radius * cos(i * 2 * M_PI/num);
        coords[i] = MaplyCoordinateMakeWithDegrees(y, x);
    }

    NSDictionary *desc = @{kMaplyColor: [UIColor blueColor], kMaplySubdivType: kMaplySubdivStatic, kMaplySubdivEpsilon: @(0.001), kMaplyVecWidth: @(5), kMaplyFilled: kMaplyFilled, kMaplyDrawPriority: @(MAXFLOAT)};
    MaplyVectorObject *vec = [[MaplyVectorObject alloc] initWithLineString:coords numCoords:num attributes:nil];
    [self.maplyVC addVectors:@[vec] desc:desc];
}
mousebird commented 8 years ago

Right, it would go a little nuts near the poles.

Another solution is to render the circle into a image and place that as a marker. I guess how well that works depends on what coordinate system you need the circle to be in. Is it in geographic?

jerald-acacus commented 8 years ago

The circle would act as a range circle with a measurement in nautical miles. So it would be geographic.

mousebird commented 8 years ago

It's a tricky problem. I'd say the safest approach is to just calculate the points yourself and pass in a custom vector.