Reputation: 125
I have Requirement Were i have to Draw a Circle for Region in CLLocationManager. i have Accomplished the Requirement with this Code as,
CLLocationDegrees latitude = 37.33492222;
CLLocationDegrees longitude = -122.03304215;
CLLocationCoordinate2D centerPoint = CLLocationCoordinate2DMake(latitude, longitude);
CLLocationDistance radius = 100.0;
CLRegion *region = [[CLRegion alloc]initCircularRegionWithCenter:centerPoint radius:radius identifier:@"Apple"];
[locationManager startMonitoringForRegion:region];
CAShapeLayer *circle = [CAShapeLayer layer];
circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0*radius, 2.0*radius)
cornerRadius:radius].CGPath;
// Center the shape in self.view
circle.position = CGPointMake(CGRectGetMidX(self.view.frame)-radius,
CGRectGetMidY(self.view.frame)-radius);
// Configure the apperence of the circle
circle.fillColor = [UIColor clearColor].CGColor;
circle.strokeColor = [UIColor redColor].CGColor;
circle.lineWidth = 1;
circle.opacity = 0.5;
// Add to parent layer
[self.view.layer addSublayer:circle;
I have Got Out Put as
Problem is When i given the radius value as 100, i got result as ScreenShot. if i will give value as 200 then obviously the Circle Will Increase.
My Question is, I want the Circle as in same Size When any Value is Given say 200, 300 or 400.
Upvotes: 2
Views: 743
Reputation: 437882
Your question talks about increasing the radius, but in this forum, "radius" will generally be construed as the radius of the circle measured in points/pixels.
Clearly, that's not what you're asking for, though. Now, you've said you don't want to use a MKMapView
, but I think it's a useful language to use when talking about your goals. Bottom line, you don't want to change the radius of the circle presented on the screen. You want to change the "span" (MKCoordinateSpan
) of the "region" (MKCoordinateRegion
) of the map which will be presented in the aforementioned circle.
There are two ways of approaching this problem of how to draw a circle of fixed size that represents a projection of a map (but you don't, for some reason, want a map).
Manually:
Define a few useful properties:
@property (nonatomic) MKCoordinateRegion region;
@property (nonatomic) CGRect frame;
The region
defines the range of latitude and longitudes that will be presented in your user interface. The frame
will be the screen coordinates in which we'll be presenting the those latitude and longitude points. Note, to do a visual representation of lat/long coordinates in a user interface you need both of these two aspects, something that defines what lat/long can be represented and something else that says where to put it on the screen.
So, the first question is how you define the region. Here I'm defining the center coordinate and defining a region as being 500 meters from that:
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(...);
self.region = MKCoordinateRegionMakeWithDistance(coordinate, 500.0, 500.0);
You asked "how do I change the radius [i.e. the span] of what is shown?" You do that by changing the region
variable which says that range of lat/long will be represented in the UI.
Anyway, you can now you can add the circle to your screen:
- (void)addCircle
{
CGPoint center = CGPointMake(self.view.layer.bounds.size.width / 2.0, self.view.layer.bounds.size.height / 2.0);
CGFloat radius = self.view.layer.bounds.size.width * 0.40;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center
radius:radius
startAngle:0.0
endAngle:M_PI * 2.0
clockwise:YES];
self.frame = CGRectMake(center.x - radius, center.y - radius, radius * 2.0, radius * 2.0);
CAShapeLayer *layer = [CAShapeLayer layer];
layer.path = [path CGPath];
layer.strokeColor = [[UIColor darkGrayColor] CGColor];
layer.fillColor = [[UIColor whiteColor] CGColor];
layer.lineWidth = 3.0;
[self.view.layer addSublayer:layer];
self.view.backgroundColor = [UIColor lightGrayColor];
}
Write a routine to convert from a CLLocationCoordinate2D
to a location on the screen:
- (CGPoint)determineCGPointFromCoordinate:(CLLocationCoordinate2D)coordinate
{
CGFloat percentX = (coordinate.longitude - self.region.center.longitude + self.region.span.longitudeDelta / 2.0) / self.region.span.longitudeDelta;
CGFloat percentY = 1.0 - (coordinate.latitude - self.region.center.latitude + self.region.span.latitudeDelta / 2.0) / self.region.span.latitudeDelta;
return CGPointMake(self.frame.origin.x + percentX * self.frame.size.width,
self.frame.origin.y + percentY * self.frame.size.height);
}
You can then add your points on your screen:
CGPoint center = [self determineCGPointFromCoordinate:coordinate];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"spot.png"]];
imageView.center = center;
[self.view addSubview:imageView];
That yields us a view that looks like:
Even easier, in my opinion, is to reevaluate your decision to not to use a map view.
You could add a map view (see the Location Awareness Programming Guide)
Take your CAShapeLayer
that you created, and rather than adding as a sublayer, you could instead clip the map to that circular CAShapeLayer
:
[self.mapView.layer setMask:circleShapeLayer];
And, once you've done all of the adding of annotations to the view, you get something like this:
Personally, I like the map kit approach, as it gets you out of the business of manually calculating screen coordinates. But if you really don't want the map background there, you can do it manually.
Upvotes: 2
Reputation: 113757
I assume you want your circle to increase and decrease in size as the user zooms. That way, the circle will always be over the same area of land on the map.
In that case, use an MKCircle
, created with +circleWithCenterCoordinate:radius:
, conform to MKMapViewDelegate
and set the stroke and fill in mapView:viewForOverlay:
.
Upvotes: 0