MapKit Polyline custom zoom? - iphone

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.

Related

How to reduce the zoom level of MKMapview with annotation?

I'm having only one annotation in the mapview.
I'm using the following code to zoom to that annotation pin
- (void)zoomToFitMapAnnotations:(MKMapView *)mapView {
if ([mapView.annotations count] == 0) return;
CLLocationCoordinate2D topLeftCoord;
topLeftCoord.latitude = -90;
topLeftCoord.longitude = 180;
CLLocationCoordinate2D bottomRightCoord;
bottomRightCoord.latitude = 90;
bottomRightCoord.longitude = -180;
for(id<MKAnnotation> annotation in mapView.annotations) {
topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);
bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
}
MKCoordinateRegion region;
region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 0.1;
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 0.1;
region = [mapView regionThatFits:region];
[mapView setRegion:region animated:YES];
}
But it zooms to the extreme, I need to reduce the zoom level so the user can see some area around the annotation.
I tried changing the values of region.span, but can't get the solution.
Any suggestions would be appreciated.
Are you sure that this code :
region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 0.1;
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 0.1;
doesn't return latitude/longitude = 0 ?
Try to hardcode the span to 0.05 or something close.
The code below will center your map to your current position , you can change locationManager.coordinates with your annotation.coordinates.
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
MKCoordinateSpan span;
MKCoordinateRegion region;
span.latitudeDelta = 0.05;
span.longitudeDelta = 0.05;
location.latitude = locationManager.location.coordinate.latitude;
location.longitude = locationManager.location.coordinate.longitude;
NSLog(#"%f",location.latitude);
region.span = span;
region.center = location;
[_mapVIew setRegion:region animated:YES];
use this code to adjust your mapView zoom level
MKCoordinateRegion mapRegion;
// set the center of the map region to the now updated map view center
mapRegion.center = self.mapView.centerCoordinate;
mapRegion.span.latitudeDelta = 0.1;
mapRegion.span.longitudeDelta = 0.1;
mapView.region=mapRegion;
I used the below code for zooming to the annotation,
CLLocation *location = [[CLLocation alloc] initWithLatitude:[#"My annotation's latitude" doubleValue] longitude:[#"My annotation's longitude" doubleValue]];
MKCoordinateRegion mkr;
mkr.center = location.coordinate;
MKCoordinateSpan span;
span.latitudeDelta = 0.0144927536;
span.longitudeDelta = 0.0144927536;
mkr.span = span;
[mapView setRegion:mkr animated:YES];
Currently, it zooms to one mile around the lat long. If I want to zoom more or less, I'll change the latlong delta value.
ie, for 2 miles = 0.0144927536*2 and for 0.5 mile = 0.0144927536/2. I hope, it will be useful for others.

How to get users current exact location using MKMapkit by code in iPhone?

I want to get the user's current location from my iPhone app. I have tried Google search also, but can't get the exact answer. I am trying to develop the code.The location will not display properly.i can findout nearest location.But i canot find out exact location.Please give me any idea,how to display exact location.Thanks in advance.
MapviewAppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if([CLLocationManager locationServicesEnabled])
{
self.locationManager.delegate=self;
self.locationManager.distanceFilter=1;
[self.locationManager startUpdatingLocation];
}
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
double miles=12.0;
double scalingFactor= ABS( cos(2 * M_PI * newLocation.coordinate.latitude /360.0) );
MKCoordinateSpan span;
span.latitudeDelta=miles/69.0;
span.longitudeDelta=miles/(scalingFactor*69.0);
MKCoordinateRegion region;
region.span=span;
region.center=newLocation.coordinate;
[self.viewController.mapView setRegion:region animated:YES];
self.viewController.mapView.showsUserLocation=YES;
}
mapviewcontroller.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.mapView.showsUserLocation = YES;
MKCoordinateRegion region;
region.center = self.mapView.userLocation.coordinate;
MKCoordinateSpan span;
span.latitudeDelta = 20;
span.longitudeDelta = 20;
region.span = span;
[self.mapView setRegion:region animated:YES];
}
// create a region that fill fit all the locations in it
+ (MKCoordinateRegion) getRegionThatFitsLocations:(NSArray *)locations {
// initialize to minimums, maximums
CLLocationDegrees minLatitude = 90;
CLLocationDegrees maxLatitude = -90;
CLLocationDegrees minLongitude = 180;
CLLocationDegrees maxLongitude = -180;
// establish the min and max latitude and longitude
// of all the locations in the array
for (CLLocation *location in locations)
{
if (location.coordinate.latitude < minLatitude)
{
minLatitude = location.coordinate.latitude;
}
if (location.coordinate.latitude > maxLatitude)
{
maxLatitude = location.coordinate.latitude;
}
if (location.coordinate.longitude < minLongitude)
{
minLongitude = location.coordinate.longitude;
}
if (location.coordinate.longitude > maxLongitude)
{
maxLongitude = location.coordinate.longitude;
}
}
MKCoordinateSpan span;
CLLocationCoordinate2D center;
if ([locations count] > 1)
{
// for more than one location, the span is the diff between
// min and max latitude and longitude
span = MKCoordinateSpanMake(maxLatitude - minLatitude, maxLongitude - minLongitude);
// and the center is the min + the span (width) / 2
center.latitude = minLatitude + span.latitudeDelta / 2;
center.longitude = minLongitude + span.longitudeDelta / 2;
}
else
{
// for a single location make a fixed size span (pretty close in zoom)
span = MKCoordinateSpanMake(0.01, 0.01);
// and the center equal to the coords of the single point
// which will be the coords of the min (or max) coords
center.latitude = minLatitude;
center.longitude = minLongitude;
}
// create a region from the center and span
return MKCoordinateRegionMake(center, span);
}
Why not just enable userLocationVisible on the MKMapView? Then the users current location will be visible on the map as a blue dot.
Basically whenever you add mapView you should enable the showuserlocation option in the inspector.
The app will then start with your location when you run the app on the device.

How to set map rect with user location at the centre?

I have a mapView with one pin and the users location. I have made it so the VisibleMapRect is set so both pins can be seen.
The problem Im having is that I am using MKUserTrackingModeFollowWithHeading to show the users move movements and when I set the rect like this the movement is very jerky. I believe this is because the user location pin is not in the centre of the map.
How can I get both pins to be visible but keep the user location in the centre?
This is my code that starts the location and sets the rect.
[locationManager startUpdatingLocation];
// Start heading updates.
if ([CLLocationManager headingAvailable]) {
locationManager.headingFilter = kCLHeadingFilterNone;
[locationManager startUpdatingHeading];
//set the view to fit both the pins
MKMapPoint annotationPoint = MKMapPointForCoordinate(MapView.userLocation.coordinate);
MKMapRect zoomRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
for (id <MKAnnotation> annotation in MapView.annotations)
{
if (![annotation isKindOfClass:[MKUserLocation class]] ) {
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
zoomRect = MKMapRectUnion(zoomRect, pointRect);
}
}
NSLog(#"%f",zoomRect.size.height);
NSLog(#"%f",zoomRect.size.width);
[MapView setVisibleMapRect:zoomRect animated:NO];
}
I have tried commenting out the part that sets the rect and the movement of the user is smooth so I can tell my problem is this code.
I have also tried setting the centre point after the rect using
[MapView setCenterCoordinate:MapView.userLocation.coordinate animated:YES];
This did not seem to work. Also setting this after may make it so the other pin is not shown anymore.
I use this method:
- (void)setRegionFromCoordinates:(NSArray *)waypoints animated:(BOOL)animated {
if (waypoints != nil) {
CLLocationDegrees maxX = -DBL_MAX;
CLLocationDegrees maxY = -DBL_MAX;
CLLocationDegrees minX = DBL_MAX;
CLLocationDegrees minY = DBL_MAX;
for (NSUInteger i=0; i < waypoints.count; i++) {
CLLocationCoordinate2D currentLocation = [waypoints objectAtIndex:i];
MKMapPoint mapPoint = MKMapPointForCoordinate(currentLocation);
if (mapPoint.x > maxX) {
maxX = mapPoint.x;
}
if (mapPoint.x < minX) {
minX = mapPoint.x;
}
if (mapPoint.y > maxY) {
maxY = mapPoint.y;
}
if (mapPoint.y < minY) {
minY = mapPoint.y;
}
}
if (maxX != -DBL_MAX && minX != DBL_MAX) {
MKMapRect mapRect = MKMapRectMake(minX,minY,maxX-minX,maxY-minY);
[map setVisibleMapRect:mapRect edgePadding:UIEdgeInsetsMake(50.f, 50.f, 50.f, 50.f) animated:animated];
}
}
}
For Display All the Annotation with Your Current location use following method
- (void)zoomToFitMapAnnotations:(MKMapView *)mapView {
if ([mapView.annotations count] == 0) return;
CLLocationCoordinate2D topLeftCoord;
topLeftCoord.latitude = -90;
topLeftCoord.longitude = 180;
CLLocationCoordinate2D bottomRightCoord;
bottomRightCoord.latitude = 90;
bottomRightCoord.longitude = -180;
for(id<MKAnnotation> annotation in mapView.annotations) {
topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);
bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
}
MKCoordinateRegion region;
region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1;
// Add a little extra space on the sides
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1;
region = [mapView regionThatFits:region];
[mapView setRegion:region animated:YES];
}

Zoom Out the Location in MapView

Im Having MapView In which I added some 5 Annotations in the Areas of Chennai.. I want to Zoom Out the Chennai as soon as the MapView Begins Loading so that Annotations will be Visible Clearly.
In viewDidLoad:
CLLocationCoordinate2D location6;
location6.latitude=12.9758;
location6.longitude=80.2205;
MapAnnotation *ann6=[[MapAnnotation alloc]initWithTitle:#"Chennai-Velacherry" andCoordinate:location6];
[mapView addAnnotation:ann6];
CLLocationCoordinate2D centerlocation;
centerlocation.longitude=13.0810;
centerlocation.longitude=80.2740;
[mapView setCenterCoordinate:centerlocation animated:NO];
[self.view addSubview:mapView];
use this,
MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = [currentPlace.latitude doubleValue];
region.center.longitude = [currentPlace.longitude doubleValue];
region.span.longitudeDelta = 0.03f;
region.span.latitudeDelta = 0.03f;
[mapView setRegion:region animated:YES];
[mapView setDelegate:self];
mapView.zoomEnabled = YES;
mapView.scrollEnabled = NO;
these will vary your zoom level,
region.span.longitudeDelta = 0.03f;
region.span.latitudeDelta = 0.03f;
You cannot have a predefined set of zoom levels. Instead, you can set the visible area of a MKMapView using MKCoordinateRegion. Sample code available here.
You can do that like this:
Create a function like :
-(void)zoomToFitMapAnnotations:(MKMapView*)mv {
CLLocationCoordinate2D topLeftCoord;
topLeftCoord.latitude = -90;
topLeftCoord.longitude = 180;
CLLocationCoordinate2D bottomRightCoord;
bottomRightCoord.latitude = 90;
bottomRightCoord.longitude = -180;
for(MKAnnotations* annotation in mv.annotations)
{
topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);
bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
}
MKCoordinateRegion region;
region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1; // Add a little extra space on the sides
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1; // Add a little extra space on the sides
region = [mv regionThatFits:region];
[mv setRegion:region animated:YES];
}
And call this function in viewDidLoad after all the pins are plotted
Try this
#define kMAPSPAN 1600
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 1*kMAPSPAN, 1*kMAPSPAN);
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion];
[_mapView setRegion:adjustedRegion animated:YES];
mapView is your MKMapView object and kMAPSPAN can be set according to your need and zoomLocation is your coordinate2D location for chennai

Google logo does not show up in Google Map (IPad Application)

I have a IPad application in which I add MKMapView programmatically without using the NIB.
{
CGRect r = CGRectMake(0, 0, 768, 980);
//CGRect r = CGRectMake(0, 0, 1004, 1004);
mapView = [[MKMapView alloc] initWithFrame:r];
mapView.showsUserLocation = FALSE;
mapView.mapType = MKMapTypeStandard;
//mapView.mapType = MKMapTypeHybrid;
//mapView.mapType = MKMapTypeSatellite;
mapView.delegate = self;
/*Region and Zoom*/
// one degree = 69 miles
// get the distance
// .01 = 1 mile square
//float distance = controller.itemDistance;
float distance = 1.0;
distance = distance/100.0;
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = distance;
span.longitudeDelta = distance;
CLLocationCoordinate2D location = mapView.userLocation.coordinate;
location.latitude = currLocation.coordinate.latitude;
location.longitude = currLocation.coordinate.longitude;
region.span = span;
region.center = location;
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];
[self addSubview:mapView];
[self addAnnotation];
}
The problem that I am facing is that the GOOGLE Logo Does not show up at the bottom of the MAP and also not showing the copyright notice. Due to this the application has been rejected from App Store. Can anyone help to add the logo on the MAP ?
Thanks in advance
may be your mapview is bigger than your view that you want to add in. Log frame height and width of view, and see if it is smaller than mapView.
Also consider to add [self setClipToBounds:NO]; and see mapView is flooding.