I want to zoom-in if there are multiple pins that overlapping and if they are not just want to show some detail page.
I've came up with a solution but it works most of the time but not always
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{
MKMapPoint annotationPoint = MKMapPointForCoordinate(view.annotation.coordinate);
MKMapRect mRect = self.mapView.visibleMapRect;
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, (mRect.size.width/view.frame.size.width)*[self.mapView currentZoomLevel]*10 , (mRect.size.height/view.frame.size.height)*[self.mapView currentZoomLevel]*10 );
NSLog(#"point rect origin %f ..%f.....size %f....%f",pointRect.origin.x, pointRect.origin.y, pointRect.size.width, pointRect.size.height);
NSSet * AnnSet = [self.mapView annotationsInMapRect:pointRect];
NSLog(#"annotations obtained :%i",[[AnnSet allObjects] count]);
// [self.mapView setVisibleMapRect:pointRect animated:YES];
NSLog(#"max zoom level :%i",[self.mapView currentZoomLevel]);
if ([[AnnSet allObjects] count]>1 && [self.mapView currentZoomLevel]<19 ) {//zoom it
[self.mapView setCenterCoordinate:view.annotation.coordinate zoomLevel:[self.mapView currentZoomLevel]+1 animated:YES];
[self.mapView deselectAnnotation:view.annotation animated:NO];
}
else{
//Show detail page
}
}
problem seems to be how i'm generating pointRect.
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, (mRect.size.width/view.frame.size.width)*[self.mapView currentZoomLevel]*10 , (mRect.size.height/view.frame.size.height)*[self.mapView currentZoomLevel]*10 );
any kind of help is welcome :)
Related
I am trying to learn how to use a polyline to connect two points on a map in ios6. First off, I have read over every tutorial on this subject that a simple Google search turns up and can not get polylines to work for one reason. Every tutorial that I have seen always adds the polyline to the map and adjusts the zoom of the map to fit the whole line. How would I go about making and adding a polyline to a map in ios6 if I want the map to stay zoomed in at a constant distance and only show the end of the polyline if it is larger then the current view?
For example say I had a polyline that was a mile long and wanted the map to stay zoomed in at a constand distacne equivelent to:
MKCoordinateRegion userRegion = MKCoordinateRegionMakeWithDistance(self.currentLocation.coordinate, 1000, 1000);
[self.mainMap setRegion:[self.mainMap regionThatFits:userRegion] animated:YES];
How would I go about doing this? Please provide full code examples or a sample project that I could download!
MKMapPoint * malloc / assign:
MKMapPoint *newPoints = malloc((sizeof (MKMapPoint) * nbPoints));
newPoints[index] = varMKMapPoint;
free(newPoints);
MKPolyline must be initialize in your needed :
MKPolyline *polyline = [MKPolyline polylineWithPoints:newPoints count:nbPoints];
[self.mapView addOverlay:polyline];
to display your MKPolyline, you have to use viewForOverlay :
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
MKOverlayView* overlayView = [[MKOverlayView alloc] initWithOverlay:overlay];
if([overlay isKindOfClass:[MKPolyline class]]) {
MKPolylineView *backgroundView = [[MKPolylineView alloc] initWithPolyline:overlay];
backgroundView.fillColor = [UIColor blackColor];
backgroundView.strokeColor = backgroundView.fillColor;
backgroundView.lineWidth = 10;
backgroundView.lineCap = kCGLineCapSquare;
overlayView = backgroundView;
}
return overlayView;
}
To use this method, you have to convert your points to CLLocation, it will returns a MKCoordinateRegion that you will set to mapView :
- (MKCoordinateRegion)getCenterRegionFromPoints:(NSArray *)points
{
CLLocationCoordinate2D topLeftCoordinate;
topLeftCoordinate.latitude = -90;
topLeftCoordinate.longitude = 180;
CLLocationCoordinate2D bottomRightCoordinate;
bottomRightCoordinate.latitude = 90;
bottomRightCoordinate.longitude = -180;
for (CLLocation *location in points) {
topLeftCoordinate.longitude = fmin(topLeftCoordinate.longitude, location.coordinate.longitude);
topLeftCoordinate.latitude = fmax(topLeftCoordinate.latitude, location.coordinate.latitude);
bottomRightCoordinate.longitude = fmax(bottomRightCoordinate.longitude, location.coordinate.longitude);
bottomRightCoordinate.latitude = fmin(bottomRightCoordinate.latitude, location.coordinate.latitude);
}
MKCoordinateRegion region;
region.center.latitude = topLeftCoordinate.latitude - (topLeftCoordinate.latitude - bottomRightCoordinate.latitude) * 0.5;
region.center.longitude = topLeftCoordinate.longitude + (bottomRightCoordinate.longitude - topLeftCoordinate.longitude) * 0.5;
region.span.latitudeDelta = fabs(topLeftCoordinate.latitude - bottomRightCoordinate.latitude) * 1.2; //2
region.span.longitudeDelta = fabs(bottomRightCoordinate.longitude - topLeftCoordinate.longitude) * 1.2; //2
// NSLog(#"zoom lvl : %f, %f", region.span.latitudeDelta, region.span.latitudeDelta);
return region;
}
Hope this helps.
I am having trouble when trying to use a MKMapView. This is my first time trying to use one of these and I haven't been able to figure out how to work it. Here are the two different pieces of sample code that I used to try to get it to work and neither work:
mapView = [[MKMapView alloc] initWithFrame:CGRectMake( 0, 0, 320, 150 )];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance( CLLocationCoordinate2DMake( latitude, longitude ), metersPerMile*0.5, metersPerMile*0.5 );
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:region];
[mapView setRegion:adjustedRegion];
or
mapView = [[MKMapView alloc] initWithFrame:CGRectMake( 0, 0, 320, 150 )];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance( CLLocationCoordinate2DMake( latitude, longitude ), metersPerMile*0.5, metersPerMile*0.5 );
[mapView setRegion:region];
or
mapView = [[MKMapView alloc] initWithFrame:CGRectMake( 0, 0, 320, 150 )];
[self.mapView setRegion:MKCoordinateRegionMake(CLLocationCoordinate2DMake( latitude, longitude ), MKCoordinateSpanMake( 0.01, 0.01 ))];
all of these snippets of code do absolutely nothing for the MKMapView. Whenever the view ends up loading, it doesn't do anything and I'm just left looking at all of North America, which isn't very helpful.
If anyone can help me out with this, I would greatly appreciate it.
You haven't added map to your view.. like [self.view addSubView:mapView];
I show the user where he is by implementing – mapView:viewForAnnotation: from MKMapViewDelegate. Take a look at this:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
// If it's the user location, return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
{
MKCoordinateSpan coordinateSpan = MKCoordinateSpanMake(0.009, 0.009);
[mapView setRegion:MKCoordinateRegionMake(annotation.coordinate, coordinateSpan) animated:YES];
}
return nil;
}
If you are tying to load the MapView this will help
- (void)mapViewWillStartLoadingMap:(MKMapView *)mapView
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSLog(#"map loading...");
}
I am just wondering how to center the map view as the user is vein tracked with CLLocationmanager and map kit
This is currently how I am tracking the user and updating the location etc.
- (void)viewDidLoad
{
// Initialize the TileOverlay with tiles in the application's bundle's resource directory.
// Any valid tiled image directory structure in there will do.
NSString *tileDirectory = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Tiles"];
TileOverlay *overlay = [[TileOverlay alloc] initWithTileDirectory:tileDirectory];
[map addOverlay:overlay];
// zoom in by a factor of two from the rect that contains the bounds
// because MapKit always backs up to get to an integral zoom level so
// we need to go in one so that we don't end up backed out beyond the
// range of the TileOverlay.
MKMapRect visibleRect = [map mapRectThatFits:overlay.boundingMapRect];
visibleRect.size.width /= 2;
visibleRect.size.height /= 2;
visibleRect.origin.x += visibleRect.size.width / 2;
visibleRect.origin.y += visibleRect.size.height / 2;
map.visibleMapRect = visibleRect;
// map.showsUserLocation = YES;
//location tracking
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
//Show the users location.. hopefully it works with tracking.
map.showsUserLocation = YES;
[overlay release]; // map is now keeping track of overlay
}
//OverLays Topographical map
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
TileOverlayView *view = [[TileOverlayView alloc] initWithOverlay:overlay];
view.tileAlpha = 0.6;
return [view autorelease];
}
//Tracks Users location and Prints out the Lat and Lon
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
CLLocationCoordinate2D here = newLocation.coordinate;
NSLog(#"%f %f ", here.latitude, here.longitude);
}
The below method focus a particular location in the map,
//Don't forget to add this method to your header also
-(void)focusLocationInMap:(CLLocationCoordinate2D)location
{
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.01;
span.longitudeDelta=0.01;
region.span=span;
region.center=location;
[self.yourMapView setRegion:region animated:TRUE];
[self.yourMapView regionThatFits:region];
}
You could use it anywhere by passing coordinates to it,
CLLocationCoordinate2D here = newLocation.coordinate;
[self focusLocationInMap:here];
here.coordinate is not correct, should be just 'here'
The firs two-three rimes I tested the app and it crashed a few times after I used the UISlider created to change a circle´s diameter (overlay),and then it crashed.Now,just when i click/tap at the slider to change the value, it suddenly crashes.As a result I have a warning 'MKMapView' may not respond to '-addCircleWithRadius:'.What am I doing wrong?I am posting the code too.
- (void)handleLongPress:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state != UIGestureRecognizerStateBegan)
return;
CGPoint touchPoint = [gestureRecognizer locationInView:mapview];
CLLocationCoordinate2D touchMapCoordinate = [mapview convertPoint:touchPoint toCoordinateFromView:mapview];
//add pin where user touched down...
MKPointAnnotation *pa = [[MKPointAnnotation alloc] init];
pa.coordinate = touchMapCoordinate;
pa.title = #"Kerkim me baze rrethin";
[mapview addAnnotation:pa];
[pa release];
tmC = touchMapCoordinate;
double radius = 500.0;
MKCircle *circle = [MKCircle circleWithCenterCoordinate:tmC radius:radius];
[mapview addOverlay:circle];
}
- (void)addCircleWithRadius:(double)radius
{
MKCircle *circle = [MKCircle circleWithCenterCoordinate:tmC radius:radius];
[mapview addOverlay:circle];
[circle release];
}
- (IBAction)sliderChanged:(UISlider *)sender
{
[mapview removeOverlays:[mapview overlays]];
double radius = (sender.value);
[mapview addCircleWithRadius:radius];//Here appears the warning,this is the order of my code.
}
The MKMapView class doesn't have an addCircleWithRadius: method – that method is part of the class you wrote, so you should probably be calling [self addCircleWithRadius:radius] instead.
I am showing the user location in an MKMapView. I don't want the default blue circle but instead the red pin.
Therefore I implemented mapView:viewForAnnotation: and made it always return a red pin as the user's location is the only pin I will show on the map view.
When using the default blue circle the location is quite precise but when changing to the red pin it's off quite a lot. It's as if the red pin is dropped precisely and is then moved up so it does not longer show my current position.
This is my code:
- (MKAnnotationView *)mapView:(MKMapView *)_mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
NSLog(#"MapView: Annotation.");
MKPinAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];
[pin setPinColor:MKPinAnnotationColorRed];
[pin setAnimatesDrop:YES];
[pin setCanShowCallout:NO];
return pin;
}
I use mapView:didAddAnnotationViews: to center the map view to my current location.
- (void)mapView:(MKMapView *)_mapView didAddAnnotationViews:(NSArray *)views
{
for(MKAnnotationView *annotationView in views)
{
if(annotationView.annotation == _mapView.userLocation)
{
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 0.20;
span.longitudeDelta = 0.20;
CLLocationCoordinate2D location = [[_mapView userLocation] coordinate];
region.span = span;
region.center = location;
[_mapView setRegion:region animated:YES];
[_mapView regionThatFits:region];
}
}
}
Does anyone know why my annotation is no longer placed correct when using the red pin instead of the default annotation view?
Setting [pin setAnimatesDrop:NO] instead of YES solved this.