How to center map view while tracking user - iphone

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'

Related

MapKit Polyline custom zoom?

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.

Display the users location on a Mapkit with CLLocationManager

I am using mapkit to display my map, I have also created an overlay. Now I am tracking the user using CLLocationManager and outputting that to the consol for testing. I hope someone knows or has a tutorial/example of how to place a dot or annotation where the users location is based on the lat lon results.. This is what I am doing at the moment..
- (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];
[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);
}
//Call [locationManager stopUpdatingLocation] as some point

Warning: 'MKMapView' may not respond to '-addCircleWithRadius:'

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.

MapView not zooming to user location

My mapview is not zooming to my user location. Please can you point out the error:
- (void)viewDidLoad {
[super viewDidLoad];
mapView = [[MKMapView alloc] init];
mapView.showsUserLocation = YES;
mapView.mapType = MKMapTypeHybrid;
mapView.delegate = self;
[self performSelector:#selector(startupZoom) withObject:nil afterDelay:1.25];
}
- (void)startupZoom {
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.2;
span.longitudeDelta=0.2;
CLLocationCoordinate2D location=mapView.userLocation.coordinate;
location.latitude=mapView.userLocation.coordinate.latitude;
location.longitude=mapView.userLocation.coordinate.longitude;
region.span=span;
region.center=location;
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];
NSLog(#"%f, %f", mapView.userLocation.coordinate.latitude, mapView.userLocation.coordinate.longitude);
}
The mapView is being created but its frame is not set and it's not being added as a subview of the view controller's view.
Change the alloc+init line to (change the dimensions as needed):
mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 300)];
Then before the performSelector line, add this:
[self.view addSubview:mapView];
Note however that it's better to use the MKMapView's didUpdateUserLocation delegate method to zoom to the user's location instead of assuming the user location will be available after some arbitrary, fixed interval like 1.25 seconds.
For example, remove the performSelector line and implement didUpdateUserLocation:
- (void)mapView:(MKMapView *)mapView
didUpdateUserLocation:(MKUserLocation *)userLocation
{
[self startupZoom];
}
Only possible problem using the didUpdateUserLocation method is that it will be called every time the user's location changes so if you only want to zoom once on startup, you'll need to add a BOOL flag ivar and check/set it accordingly.

Retrieve UserLocation Coordinate with MapKit

I"m using MapKit in my application and disaply the user location with
[mapview setShowUserLocation:YES];
I want to set the region.center.latitude and region.center.longitude with the coordinate of the userLocation, how to do it?
Here is my answer, I try something like that and its working:
//inside my ViewDidLOad
locManager = [[CLLocationManager alloc] init];
[locManager setDelegate:self];
[locManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locManager startUpdatingLocation];
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
CLLocationCoordinate2D loc = [newLocation coordinate];
[maptView setCenterCoordiante:loc];
}
Much easier:
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.location.coordinate, 1500, 1500);
[mapView setRegion:region animated:YES];
}
For some reason, this didn't work for me. It's taking me to the coordinates (0.0000, 0.0000). Below is my code if you have a chance to check it out. Thanks for the help!
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
mapView.showsUserLocation=TRUE;
MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
CLLocationCoordinate2D myCoord = {mapView.userLocation.location.coordinate.latitude,mapView.userLocation.location.coordinate.longitude};
[mapView setCenterCoordinate:myCoord animated:YES];
region.span.longitudeDelta = 0.01f;
region.span.latitudeDelta = 0.01f;
[mapView setRegion:region animated:YES];
[mapView setDelegate:self];
I think this answers your question :
Returning Mapkit Userlocation Coordinates
(uses the mapView.userLocation.location.coordinate.latitude and mapView.userLocation.location.coordinate.longitude properties )
and then inject those coordinates into the
-(void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated
of your MKMapView instance.
Using delegate:
Add Mapkit delegate: MKMapViewDelegate
Achieve method:MapView didUpdateUserLocation
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.location.coordinate,
500, 500);
[mapView setRegion:region animated:YES];
}
Without delegate:
[self.mapView setuserTrackingMode:MKUserTrackingModeFollow];