Google Maps directions in maps shared app to personalized annotations - ios

I created an app that displays different points on a custom map with custom pins and showing the title and subtitle with a disclosure button (all right). The problem arises when the app launches maps to create the path and then provide directions. To move from the position of the user I've simply typed in the URL "saddr=Current Position". The problem comes when I try to give the destination that the user has touched, relative to the pin touched.
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
[self.navigationController pushViewController:[[UIViewController alloc] init] animated:YES];
NSString* addr = [NSString stringWithFormat:#"http://maps.google.com/maps?daddr=%1.6f%1.6f&saddr=Posizione Attuale", mapView.annotations.coordinate.latitude mapView.annotations.coordinate.longitude];
//also mapview.annotation.coordinate.latitude/longitude doesn't work
NSURL* url = [[NSURL alloc] initWithString:[addr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL:url];
}
I can not figure out how to pass the coordinates of the annotation in the piece of code!
Here's how I said and added the annotation to my view
NSMutableArray* annotations=[[NSMutableArray alloc] init];
CLLocationCoordinate2D theCoordinate1;
theCoordinate1.latitude = 45.7;
theCoordinate1.longitude = 7.64;
myAnnotation* myAnnotation1=[[myAnnotation alloc] init];
myAnnotation1.coordinate=theCoordinate1;
myAnnotation1.title=#"Pippo";
myAnnotation1.subtitle=#"Ufficio";
[myMapView addAnnotation:myAnnotation1];
This repeated for 4 main points that have different names (myAnnotation1, 2, 3, 4) and coordinates other! How can I do when the user touches 1-2-3 or 4 to move the right destination?
Thanks in advance! :)

In calloutAccessoryControlTapped, why are you pushing a blank view controller and calling openURL at the same time?
Anyway, the annotation's coordinates are in view.annotation.coordinate.
So the latitude is view.annotation.coordinate.latitude and longitude is view.annotation.coordinate.longitude.
Also, in your addr string, you are missing a comma between the coordinates.

Related

MKMapView Overlay in IOS6

Am adding custom overlays to MKMapView and need to clear the map content before adding overlay (i.e when zoomed or panned default map should be invisible)
Something similar to "canReplaceMapContent" in IOS7 and later.
Is there any method to perform this action in IOS6?
Thanks in advance.,
You method below:
- (void) removeMapOverlay {
[self.mapView removeOverlays:[self.mapView overlays]];
NSMutableArray *tempArray = [NSMutableArray arrayWithArray:[self.mapView annotations]];
if ([tempArray containsObject:[MKUserLocation class]]) {
[tempArray removeObject:[MKUserLocation class]];
}
NSArray *annotationArray = [NSArray arrayWithArray:tempArray];
tempArray = nil;
[self.mapView removeAnnotations:annotationArray];
}
Edit:
When you pinch/zoom or pan in the map. There are two delegate methods are available you can use to check map is loading or not?
- (void)mapViewWillStartLoadingMap:(MKMapView *)mapView {
NSLog(#"loading...");
}
- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView {
NSLog(#"Map loaded...");
}
What i suggest you to use above two methods. Create a bool variable or some means not to load annotations when zoom. How ever i'll keep update if there is other simple way to do it.
You could draw a custom, opaque overlay on top of Apple's maps, but there is still a very slight chance that you will see the map beneath from time to time. I'd recommend an alternative, open source toolset that you can control like Mapbox for complete control.

mapView viewForOverlay never called

So I want to display where my app's user walked on a MKMapView, I collect datas with the following code :
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
// calc. distance walked
CLLocationDistance meters = [newLocation distanceFromLocation:oldLocation];
self.totalMetters += meters;
[[self labelDistance] setText:[self formatDistanceIntoString:self.totalMetters]];
// create another annotation
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = newLocation.coordinate;
// Also add to our map so we can remove old values later
[self.locations addObject:annotation];
// Remove values if the array is too big
while (self.locations.count > 100)
{
annotation = [self.locations objectAtIndex:0];
[self.locations removeObjectAtIndex:0];
// Also remove from the map
[self.map removeAnnotation:annotation];
}
Once it's finished, I call my draw method :
[self drawRoute];
Which contains the following :
- (void)drawRoute {
NSLog(#"drawRoute");
NSInteger pointsCount = self.locations.count;
CLLocationCoordinate2D pointsToUse[pointsCount];
for(int i = 0; i < pointsCount; i++) {
MKPointAnnotation *an = [self.locations objectAtIndex:i];
pointsToUse[i] = CLLocationCoordinate2DMake(an.coordinate.latitude,an.coordinate.latitude);
}
MKPolyline *myPolyline = [MKPolyline polylineWithCoordinates:pointsToUse count:pointsCount];
[self.map addOverlay:myPolyline];
}
Finally my mapView delegate :
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay {
NSLog(#"route");
if ([overlay isKindOfClass:MKPolyline.class]) {
MKPolylineView *lineView = [[MKPolylineView alloc] initWithOverlay:overlay];
lineView.strokeColor = [UIColor greenColor];
return lineView;
}
return nil;
}
Obviously my controller is MKMapView Delegate conform
#interface NewWalkViewController : UIViewController <CLLocationManagerDelegate, MKMapViewDelegate>
And the mapView in the Storyboard is linked to the controller (outlet and delegate)
I use the "bike road" debug tool and there is the output :
2014-01-25 20:27:30.132 The walking dog[2963:70b] new location : 37.330435
2014-01-25 20:27:30.133 The walking dog[2963:70b] drawRoute
As I can see the method for drawing the overlay is never called, and I don't have a single clue how to fix it.
The main problem is that in drawRoute, this line is passing latitude for both parameters to CLLocationCoordinate2DMake:
pointsToUse[i] = CLLocationCoordinate2DMake
(an.coordinate.latitude,an.coordinate.latitude);
This results in the line being drawn in a different part of the world than where the actual an.coordinate is. For example, if an.coordinate is 37,-122 (somewhere near San Francisco), the line is being drawn instead at 37,37 (somewhere in southern Turkey).
Since you are not actually positioning the map at the wrong location (you are looking for the line at the "right" location), viewForOverlay is never called because the map only calls it when it's possible that the overlay will be visible.
Change that line to:
pointsToUse[i] = CLLocationCoordinate2DMake
(an.coordinate.latitude,an.coordinate.longitude);
or simply:
pointsToUse[i] = an.coordinate;
As James Frost mentions in the comments, as of iOS 7, you should be using rendererForOverlay instead of viewForOverlay though the map view will still call viewForOverlay in iOS 7 if rendererForOverlay has not been implemented. Though this isn't preventing your overlay from displaying in the current case, you should implement the new delegate method as well as the old one (if the iOS 7 app will also be running on iOS 6 or earlier).
Another important but unrelated issue is that you are unnecessarily creating multiple, overlapping overlays. In drawRoute, since the overlay you are creating includes all the locations, you should remove any existing overlays before adding the new one. Otherwise, the map ends up with an overlay for location 0 to 1, an overlay for location 0 to location 2, an overlay for location 0 to location 3, etc. The previous overlays are not obviously visible since they have the same color and line width. Before the addOverlay line, put:
[self.map removeOverlays:self.map.overlays];

Mapbox online map on iOS

I'm totally new to mapbox API on iOS , i follow the instruction on there site and make a custom map with marker -
My Map Online Link
- and i add the binary framework and it load with the map without any marker
#import <MapBox/MapBox.h>
-(void)viewWillAppear:(BOOL)animated{
RMMapView *map =[[RMMapBoxSource alloc]initWithMapID:#"scorpioo.map-a6l64b06"];
RMMapView *mapV = [[RMMapView alloc] initWithFrame:view.bounds andTilesource:map];
}
so anyone can tell me why it not shown ? or know how can i show the marker that i put on the online map on my ios ?
This is possible using this method of RMMapBoxSource:
http://www.mapbox.com/mapbox-ios-sdk/api/#//api/name/initWithMapID:enablingDataOnMapView:
Create your RMMapView first, then create your RMMapBoxSource, pass the map view as the second argument. This will pull down server-side markers and automatically display them.
Here is an example project which shows this:
https://github.com/mapbox/weekend-picks-template-ios
The technology here is called simplestyle.
You need to add the following lines in the above code. So that you can get the desired marker :
RMPointAnnotation *annotation = [[RMPointAnnotation alloc] initWithMapView:map coordinate:MENTION_COORDINATES_HERE andTitle:#"Hello, world!"];
[mapView addAnnotation:annotation];
Complete Example :
RMMapBoxSource *tileSource = [[RMMapBoxSource alloc] initWithMapID:#"examples.map-z2effxa8"];
RMMapView *mapView = [[RMMapView alloc] initWithFrame:self.view.bounds andTilesource:tileSource];
[self.view addSubview:mapView];
RMPointAnnotation *annotation = [[RMPointAnnotation alloc] initWithMapView:mapView
coordinate:mapView.centerCoordinate
andTitle:#"Hello, world!"];
[mapView addAnnotation:annotation];
Hope that helps.

iOS MKMapView starts zoomed out default map but zooms in only on refresh

Everytime I start the app, the first time seeing the map results in a default map that is always zoomed out with no annotations. When I go back on the navigation controller and go back into the map, it now shows the correct region with the appropriate pins. The code I use to add the
- (void) zoomIn {
mapView.showsUserLocation = YES;
CLLocationCoordinate2D annotation;
annotation.latitude = 47.640071;
annotation.longitude = -122.129598;
MKPointAnnotation *annoPoint = [[MKPointAnnotation alloc] init];
annoPoint.coordinate = annotation;
annoPoint.title = #"name";
[mapView addAnnotation:annoPoint];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(annotation, 500, 500);
[mapView setRegion:region animated:YES];
}
I call this block of code from the viewDidLoad, but it only works after I go back to the main page from the navigation controller and enter this UIViewController again.
Does anyone know what the problem is or have seen it before?
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
// this delegate fonction is called when the userlocation is updated
// try to move your code here
}
you have also
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
}
hope this helps
Show us your viewDidLoad function, you're probably calling zoomIn too early, maybe before your MKMapView has been initialized.

How can I share the variable for mapkit between two viewcontroller?

I want to show the pin annotation on the new view controller when the "map" button is clicked on the upper level view controller.
So I used the "IBAction" method on the method file of the upper level controller as below.
Then the latitude and longitude values appeared normally (in the NSLog) from the property list.
But I can't see the pin annotation on the new view controller.
However, if I put the code marked "code for viewDidLoad" on the new view controller (named "location") then I can see the pin annotation.
But the latitude and longitude value is only 0.00000.
I think the variable isn't shared between two view controller.
Please help me to solve this problem.
- (IBAction) goAddView:(id)sender {
// the code for viewDidLoad
double myLat = [[drink objectForKey:lati_KEY] doubleValue];
double myLong = [[drink objectForKey:long_KEY] doubleValue]; CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = myLat;
theCoordinate.longitude = myLong;
NSLog(#"the latitude = %f",theCoordinate.latitude);
NSLog(#"the longitude = %f",theCoordinate.longitude);
myAnnotation *myAnnotation1=[[myAnnotation alloc] init];
myAnnotation1.coordinate=theCoordinate;
myAnnotation1.title=#"Destination";
myAnnotation1.subtitle=#"in the city";
[self.mapView addAnnotation:myAnnotation1];
// the code end
location *lm= [[location alloc] initWithNibName:#"location" bundle:nil];
[self.navigationController pushViewController:lm animated:YES];
I assume the variable you want to share is drink. If you've just declared drink as an ivar in both view controllers, that won't "share" it automatically. After you alloc+init location in goAddView, drink will be nil in lm. The viewDidLoad method in location will get called when you push/present it.
One way to pass the value to location is using properties. First, declare drink as a property in the location view controller:
//in location.h:
#property (retain) NSDictionary *drink;
//in location.m:
#synthesize drink;
//and release in dealloc if not using ARC
Next, set the property after you alloc+init it in goAddView and before you call pushViewController:
- (IBAction) goAddView:(id)sender
{
location *lm = [[location alloc] initWithNibName:#"location" bundle:nil];
lm.drink = drink; //point drink in lm to the one in current vc
[self.navigationController pushViewController:lm animated:YES];
//and do [lm release]; if not using ARC
}

Resources