I am trying to add drag and drop functionality on Google map. Overall it is done but one thing has to fix. That is when I drag and drop GMSMarker on Google map pervious GMSMarker still exist and another (wherever I dropped it) GMSMarker created new. But I want only one GMSMarker. How to remove pervious/ old GMSMarker. Any suggestion will be Great. Thanks in advance.
Code :
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
// Mumbabi address
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:19.01761470
longitude:72.85616440
zoom:4];
// mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
mapViewGMS.camera=camera;
mapViewGMS.delegate = self;
CLLocationCoordinate2D position = CLLocationCoordinate2DMake([#"19.01761470" floatValue ], [#"72.85616440" floatValue]);
GMSMarker *marker = [GMSMarker markerWithPosition:position];
marker.title = #"This is your current location";
[marker setDraggable: YES];
marker.appearAnimation=0.2f;
marker.map = mapViewGMS;
}
- (void)mapView:(GMSMapView *)mapView didEndDraggingMarker:(GMSMarker *)marker
{
NSLog(#">>> mapView:didEndDraggingMarker: %#", [marker description]);
NSString *lati=[NSString stringWithFormat:#"%f",marker.position.latitude];
NSString *longi=[NSString stringWithFormat:#"%f",marker.position.longitude];
NSString * urpPath = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?latlng=%#,%#&sensor=true",lati,longi];
[[ConnectionManager connectionManagerSharedInstance]sendPOSTRequestForPath:urpPath data:nil timeoutInterval:50 completion:^(NSDictionary *dictionary, NSError *error) {
if(!error){
if(dictionary){
if([dictionary valueForKey:#"results"] == nil || [[dictionary valueForKey:#"status"]isEqualToString:#"ZERO_RESULTS"]){
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:[ViewUtilities showAlert:#"Message!!" :#"Unable to fetch this location, May be this is an invalid loation. However Please Check your Internet Connection, and re- run this app."] animated:YES completion:nil];
});
}
else
{
strUserCurrentAddressAuto=[NSString stringWithFormat:#"%#",[[[dictionary valueForKey:#"results"] objectAtIndex:0] valueForKey:#"formatted_address"]];
NSLog(#"\n\n ***** Great User address found,---> %# *****\n\n",strUserCurrentAddressAuto);
dispatch_async(dispatch_get_main_queue(), ^{
//[self.automaticallySearchBtn setTitle:self.fullSourceAddress forState:UIControlStateNormal];
UIAlertController *alert= [UIAlertController alertControllerWithTitle:strUserCurrentAddressAuto message:#"Select this Loaction for ?"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *pick = [UIAlertAction actionWithTitle:#"Pick Up Location" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
labelSourceLocation.text=strUserCurrentAddressAuto;
// nil marker title (old title it is : This is your current location)
marker.title = nil;
locationSource = [[CLLocation alloc] initWithLatitude:marker.position.latitude longitude:marker.position.longitude];
if (locationSource !=nil && locationDest!=nil) {
CLLocationDistance dist = [locationSource distanceFromLocation:locationDest]/1000;
NSLog(#"\n\n **** Using Drag and drop Poin, Total distance in K.M. => %f",dist);
totalDistance = [NSString stringWithFormat:#"%f",dist];
}
[alert dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction *drop = [UIAlertAction actionWithTitle:#"Drop Location" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
labelDropLocation.text=strUserCurrentAddressAuto;
// nil marker title (old title it is : This is your current location)
marker.title = nil;
locationDest = [[CLLocation alloc] initWithLatitude:marker.position.latitude longitude:marker.position.longitude];
if (locationSource !=nil && locationDest!=nil) {
CLLocationDistance dist = [locationSource distanceFromLocation:locationDest]/1000;
NSLog(#"\n\n **** Using Drag and drop Poin, Total distance in K.M. => %f",dist);
totalDistance = [NSString stringWithFormat:#"%f",dist];
}
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:pick];
[alert addAction:drop];
[self presentViewController:alert animated:YES completion:nil];
});
}
}
}
}];
}
You need to remove the previous marker placed over mapView, it is the most preferable solution in this kind of situation or accordingly.
To Clear mapView:
[mapView clear];
Use below code to drag and drop marker excluding previous one:
-(void)mapView:(GMSMapView *)mapView didEndDraggingMarker:(GMSMarker *)marker{
CLLocationCoordinate2D pos;
pos.latitude = marker.position.latitude;
pos.longitude = marker.position.longitude;
// this removes the previous markers
[mapView clear];
// this method adds the marker where user dropped it
[self placeMarker:pos.latitude withLong:pos.longitude];
}
// helping method
-(void) placeMarker:(float)lat withLong:(float)lon{
CLLocationCoordinate2D pinlocation;
pinlocation.latitude = lat;
pinlocation.longitude = lon;
GMSMarker *marker = [[GMSMarker alloc] init];
[marker setDraggable: YES];
marker.position = pinlocation;
marker.title = #"Hi";
marker.snippet = #"New marker";
marker.appearAnimation = kGMSMarkerAnimationPop;
marker.icon = [GMSMarker markerImageWithColor:[UIColor redColor]];
marker.map = self.mapView;
// this always visible marker info window, comment if do not need
[self.mapView setSelectedMarker:marker];
}
Update:
To remove specific marker on map, just keep the reference of that marker object and later set it to nil see below code:
// declare marker globally to declare its scope to entire class.
GMSMarker *markerToRemoveLater;
// initialization and configuration
markerToRemoveLater = [[GMSMarker alloc] init];
// set nil where you want to remove specific marker
markerToRemoveLater.map = nil;
I had the same issue when I was working on Gmaps. I wanted to clear the marker without using [map clear]. I came up with this solution.
-(void)mapView:(GMSMapView *)mapView didEndDraggingMarker:(GMSMarker *)marker{
CLLocationCoordinate2D pos;
pos.latitude = marker.position.latitude;
pos.longitude = marker.position.longitude;
// this removes the previous marker from map
marker.map = nil;
// ** Give your marker new position from CLLocationCoordinate2D
//Then
[self mapView:mapViewGoog didTapAtCoordinate:marker.position];
}
- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate {
[self addMarkerInTheMapView:coordinate];
}
-(void)addMarkerInTheMapView:(CLLocationCoordinate2D)coordinate{
markerMYLocation.map = nil;
markerMYLocation = [[GMSMarker alloc] init];
//Your code here.
markerMYLocation.map = mapView;
}
Related
I have a map to show directions. I am able to tap on a direction to view an annotation with the instructions but what I am trying to do is add a marker to the directions coordinates. Here is the code I am currently using:
-(void) getDirectionsFromStart: (CLLocation*) start toEnd: (CLLocation*) end
{
NSString *mapDir = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&sensor=false", start.coordinate.latitude, start.coordinate.longitude, end.coordinate.latitude, end.coordinate.longitude];
if ([self.directionsArray count] == 0) {
//parse the string response and then draw the points on a map
NSError *error;
NSString *response = [NSString stringWithContentsOfURL:[NSURL URLWithString:mapDir] encoding:NSUTF8StringEncoding error:&error];
if (response == nil) {
NSLog(#"Google Maps error: %#", [error localizedDescription]);
NSLog(#"Google Maps recovery: %#", [error localizedRecoverySuggestion]);
//[self getDirectionsFromStart:nil toEnd:nil];
}
self.directionsArray = [gMapsJsonDirectionsParser parseJsonToMapDirections:response];
}
for (gMapsJourneyLeg *leg in self.directionsArray) {
#autoreleasepool {
self.directionsHeader.text = [NSString stringWithFormat:#"To %# Taking: %#", leg.end_address, leg.duration.text];
for (gMapsStep *step in leg.steps ) {
MKPolyline *polyLine = [gMapsJsonDirectionsParser polylineWithEncodedString:step.polyLine];
MKPolylineView *line = [[MKPolylineView alloc] initWithPolyline: polyLine];
line.fillColor = [UIColor blueColor];
line.strokeColor = [UIColor blueColor];
line.lineWidth = 5;
[self.mapView addOverlay:polyLine];
//[self.mapView setVisibleMapRect:polyLine.boundingMapRect];
//map point code
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = step.end_location.coordinate;
point.title = step.htmlInstructions;
[[self.mapView viewForAnnotation:point] setTag:1];
UIImage *image = [UIImage imageNamed:#"marker_red.png"];
[[self.mapView viewForAnnotation:point] setImage:image];
[self.mapView addAnnotation:point];
}
}
}
[self.tableView reloadData];
}
To be clear, the annotations and polyline are both fine it's just the marker is never shown.
Base on the code in the Google Docs for Markers:
Here is the sample code for adding markers with custom image.
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(51.5, -0.127);
GMSMarker *london = [GMSMarker markerWithPosition:position];
london.title = #"London";
london.icon = [UIImage imageNamed:#"house"];
london.map = mapView_;
May be you have not set the GMSMarker *london = [GMSMarker markerWithPosition:position]; that is why your marker is not visible.
Kindly check the marker without a custom image if it will show up, if not try adding the markerPosition property.
I am displaying the google map using Google Maps SDK for iOS. When I start the view controller first time it shows the map fine. But when I goto the view controller second time it does not display the google map. It shows the blank screen. Actually I am passing the address in the google geo coding api from there I am getting the lang & lat then I am displaying the google map.
Code for displaying google map
//
// GmapViewController.m
// MyDex
// Created by Admin on 8/18/15.
// Copyright (c) 2015 com.vastedge. All rights reserved.
#import "GmapViewController.h"
#import "AFNetworking.h"
#import "UIKit+AFNetworking.h"
#import GoogleMaps;
#interface GmapViewController ()
#end
#implementation GmapViewController
{
GMSMapView *mapView_;
NSString *lat;
NSString *lng;
CLLocationDegrees latitude;
CLLocationDegrees longitude;
UIActivityIndicatorView *activityView;
}
-(void)geoCodeAddress
{
NSCharacterSet *doNotWant = [NSCharacterSet characterSetWithCharactersInString:#":/,."];
self.address = [[self.address componentsSeparatedByCharactersInSet: doNotWant] componentsJoinedByString: #""];
NSString *urlString=[NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/geocode/json?address=%#",self.address];
urlString = [urlString stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding];
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:urlString]];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
AFHTTPRequestOperation *operation = [manager GET:urlString parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSArray * results = [responseObject objectForKey:#"results"];
NSDictionary *records=[results objectAtIndex:0];
NSDictionary *geometry=[records objectForKey:#"geometry"];
NSLog(#"geomatry is %#",geometry);
NSDictionary *latLong=[geometry objectForKey:#"location"];
lat=[latLong objectForKey:#"lat"];
lng=[latLong objectForKey:#"lng"];
latitude=[lat floatValue];
longitude=[lng floatValue];
NSLog(#"main lat is %f",latitude);
NSLog(#"main lng is %f",longitude);
[self activityIndicator:#"hide"];
[self Loadgmap];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"failure string is");
[self activityIndicator:#"hide"];
UIAlertView *alert =[[UIAlertView alloc]initWithTitle:#"Warning" message:#"Unable to display map" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
}];
[operation start];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self activityIndicator:#"show"];
[self geoCodeAddress];
}
-(void)Loadgmap
{
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.868
longitude:151.2086
zoom:6];
GMSMapView *mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = camera.target;
marker.snippet = #"Hello World";
marker.appearAnimation = kGMSMarkerAnimationPop;
marker.map = mapView;
self.view = mapView;
}
-(void)activityIndicator:(NSString *)show
{
if([show isEqual:#"show"])
{
NSLog(#"loading shown");
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityView.layer.backgroundColor = [[UIColor colorWithWhite:0.0f alpha:0.5f] CGColor];
activityView.hidesWhenStopped = YES;
activityView.frame = self.view.bounds;
[self.view addSubview:activityView];
[activityView startAnimating];
}
else
{
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
[activityView stopAnimating];
[activityView removeFromSuperview];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
Using dispatch_async(dispatch_get_main_queue(), ^{}) is a better practice, but the main problem of your white screen issue is the view in your ViewController get assigned to new value twice.
When the [self Loadgmap] is called in you viewDidLoad(), the self.view = mapView; is called. When your networking required is done, your [self Loadgmap] is called again, and the self.view = mapView; is called again, which make your view become a white screen.
You should only assign value to your view in the viewDidLoad() method, not later in other method calls.
To fix your problem, you can make a new method call -(void)updateMap():
-(void)updateMap {
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:[lat floatValue]
longitude:[lng floatValue]
zoom:6];
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = camera.target;
marker.snippet = #"Hello World";
marker.appearAnimation = kGMSMarkerAnimationPop;
marker.map = (GMSMapView*)self.view;
[((GMSMapView*)self.view) animateToCameraPosition:camera];
}
You should call it inside your network request success block:
NSArray * results = [responseObject objectForKey:#"results"];
NSDictionary *records=[results objectAtIndex:0];
NSDictionary *geometry=[records objectForKey:#"geometry"];
NSLog(#"geomatry is %#",geometry);
NSDictionary *latLong=[geometry objectForKey:#"location"];
lat=[latLong objectForKey:#"lat"];
lng=[latLong objectForKey:#"lng"];
latitude=[lat floatValue];
longitude=[lng floatValue];
NSLog(#"main lat is %f",latitude);
NSLog(#"main lng is %f",longitude);
dispatch_async(dispatch_get_main_queue(), ^{
[self activityIndicator:#"hide"];
[self updateMap];
});
Your viewDidLoad() should call [self Loadgmap] first to initialize a Google Map to your view.
- (void)viewDidLoad
{
[super viewDidLoad];
[self activityIndicator:#"show"];
[self Loadgmap];
[self geoCodeAddress];
}
Full code snippet: https://gist.github.com/ziyang0621/f66dd536382b1b16597d
Hi in my application I have integrated google map now i want to give navigation direction from my current location to destination point please tell me how to achieve this one.
My code.
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:12.9259
longitude:77.6229
zoom:6];
mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
mapView.myLocationEnabled= NO;
self.view = mapView;
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(12.9259, 77.6229);
marker.title = #"Hello World";
marker.snippet = #"bangalore";
marker.map = mapView;
The above code i have used to point maker of my destination point in that please tell me how to add the navigation direction to that i have been stuck here for long time please help me out.
Thanks.
You can use either the comgooglemaps:// or comgooglemaps-x-callback:// URL schemes.
Note: Buttons added via the x-source parameter will not be displayed in the turn-by-turn navigation UI.
The below code snippet shows how to use the comgooglemaps-x-callback:// scheme to request directions, and then return to your app when your user is ready. The code will do the following:
Verify that the comgooglemaps-x-callback:// URL scheme is available.
Launch the Google Maps for iOS app, and request directions to JFK Airport in New York city. Leave the start address blank to request directions from the user's current location.
Add a button labelled "AirApp" to the Google Maps for iOS App. The button label is defined by the x-source parameter.
Call the fictitious URL scheme, sourceapp://, when the users clicks the back button.
The code is shown below.
NSURL *testURL = [NSURL URLWithString:#"comgooglemaps-x-callback://"];
if ([[UIApplication sharedApplication] canOpenURL:testURL]) {
NSString *directionsRequest = #"comgooglemaps-x-callback://" +
#"? daddr=John+F.+Kennedy+International+Airport,+Van+Wyck+Expressway,+Jamaica,+New+York" +
#"&x-success=sourceapp://?resume=true&x-source=AirApp";
NSURL *directionsURL = [NSURL URLWithString:directionsRequest];
[[UIApplication sharedApplication] openURL:directionsURL];
}
else
{
NSLog(#"Can't use comgooglemaps-x-callback:// on this device.");
}
Go with this answer..
- (IBAction)handleRoutePressed:(id)sender {
// We're working
self.activityIndicator.hidden = NO;
[self.activityIndicator startAnimating];
self.routeButton.enabled = NO;
self.routeDetailsButton.enabled = NO;
// Make a directions request
MKDirectionsRequest *directionsRequest = [MKDirectionsRequest new];
// Start at our current location
MKMapItem *source = [MKMapItem mapItemForCurrentLocation];
[directionsRequest setSource:source];
// Make the destination
CLLocationCoordinate2D destinationCoords = CLLocationCoordinate2DMake(38.8977, -77.0365);
MKPlacemark *destinationPlacemark = [[MKPlacemark alloc] initWithCoordinate:destinationCoords addressDictionary:nil];
MKMapItem *destination = [[MKMapItem alloc] initWithPlacemark:destinationPlacemark];
[directionsRequest setDestination:destination];
MKDirections *directions = [[MKDirections alloc] initWithRequest:directionsRequest];
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
// We're done
self.activityIndicator.hidden = YES;
[self.activityIndicator stopAnimating];
self.routeButton.enabled = YES;
// Now handle the result
if (error) {
NSLog(#"There was an error getting your directions");
return;
}
// So there wasn't an error - let's plot those routes
self.routeDetailsButton.enabled = YES;
self.routeDetailsButton.hidden = NO;
_currentRoute = [response.routes firstObject];
[self plotRouteOnMap:_currentRoute];
}];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.destinationViewController isKindOfClass:[SCStepsViewController class]]) {
SCStepsViewController *vc = (SCStepsViewController *)segue.destinationViewController;
vc.route = _currentRoute;
}
}
#pragma mark - Utility Methods
- (void)plotRouteOnMap:(MKRoute *)route
{
if(_routeOverlay) {
[self.mapView removeOverlay:_routeOverlay];
}
// Update the ivar
_routeOverlay = route.polyline;
// Add it to the map
[self.mapView addOverlay:_routeOverlay];
}
#pragma mark - MKMapViewDelegate methods
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay: (id<MKOverlay>)overlay
{
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
renderer.strokeColor = [UIColor redColor];
renderer.lineWidth = 4.0;
return renderer;
}
If u dont want to use NSURL then you can simply use[MKMapItem openMapsWithItems:]
- (void)openMapsWithDirectionsTo:(CLLocationCoordinate2D)to {
Class itemClass = [MKMapItem class];
if (itemClass && [itemClass res pondsToSelector:#selector(openMapsWithItems:launchOptions:)]) {
MKMapItem *currentLocation = [MKMapItem mapItemForCurrentLocation];
MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[[MKPlacemark alloc] initWithCoordinate:to addressDictionary:nil] autorelease]];
toLocation.name = #"Destination";
[MKMapItem openMapsWithItems:[NSArray arrayWithObjects:currentLocation, toLocation, nil]
launchOptions:[NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:MKLaunchOptionsDirectionsModeDriving, [NSNumber numberWithBool:YES], nil]
forKeys:[NSArray arrayWithObjects:MKLaunchOptionsDirectionsModeKey, MKLaunchOptionsShowsTrafficKey, nil]]];
[toLocation release];
}
else {
NSMutableString *mapURL = [NSMutableString stringWithString:#"http://maps.google.com/maps?"];
[mapURL appendFormat:#"saddr=Current Location"];
[mapURL appendFormat:#"&daddr=%f,%f", to.latitude, to.longitude];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[mapURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
}
}
i am working on a map kit that shows all the data extracted from an xml web service .this web service contains 3 variables longitude (lon),latitude(lat), the name of the atm (atmName).the for loop is extracting the data from the Aatm array but the pins are not showing on the map .also my pins are all from the same region thats why i used a default center from the Aatm array with a default value. here is my code
thank you for helping me in advance :
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Aatm = [[NSMutableArray alloc] init];
pinArray = [[NSMutableArray alloc] init];
NSString *url=#"http://192.168.83.1:8080/jeeRestApp-1.0/rest/Atm";
NSXMLParser *parser;
parser=[[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
parser.delegate=self;
if ([parser parse]==FALSE){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Erreur" message:#"erreur de connection!" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:nil, nil];
[alert show];
}
//Setting the approximate region
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.mapview setShowsUserLocation:YES];
MKCoordinateRegion Myregion;
CLLocationCoordinate2D center1;
//replace by variable -----------------------------------
atm=[Aatm objectAtIndex:1];
center1.latitude=[atm.lat doubleValue];
center1.longitude=[atm.lon doubleValue];
NSLog(#"la latitude (defaut) est: %#",atm.lat);
MKCoordinateSpan span1;
span1.longitudeDelta = 0.01f;
span1.latitudeDelta = 0.01f;
Myregion.center=center1;
Myregion.span=span1;
[mapview setRegion:Myregion animated:YES];
for(int i = 0; i<=[Aatm count] - 1;i++)
{
//CLLocationCoordinate2D newCoord = { atm.lat, atm.lon};
atm=[Aatm objectAtIndex:i];
CLLocationCoordinate2D pinLocaton;
pinLocaton.latitude=[atm.lat doubleValue];
NSLog(#"latitude est de :%#",atm.lat);
pinLocaton.longitude=[atm.lon doubleValue];
NSLog(#"longitude est de :%#",atm.lon);
MKPointAnnotation *annotation=[MKPointAnnotation alloc];
annotation.title=atm.atmName;
NSLog(#"latitude est de :%#",atm.atmName);
annotation.coordinate=pinLocaton;
MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"annotation1"];
newAnnotation.pinColor = MKPinAnnotationColorGreen;
newAnnotation.animatesDrop = YES;
newAnnotation.canShowCallout = NO;
[newAnnotation setSelected:YES animated:YES];
[mapview addAnnotation:annotation];
NSLog(#"annotation added");
}
You need to implement mapView:viewForAnnotation: something like:
-(MKAnnotationView*)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if([annotation isKindOfClass:[MKPointAnnotation class]])
{
MKPinAnnotationView* view = (MKPinAnnotationView*) [mapView dequeueReusableAnnotationViewWithIdentifier:#"pin"];
if(!view)
{
view = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pin"];
}
else
{
view.annotation = annotation;
}
view.pinColor = MKPinAnnotationColorGreen;
view.animatesDrop = YES;
view.canShowCallout = NO;
return view;
}
else
{
return nil;
}
}
I've got Google Map embedded in a View Controller in a Map on an iPhone. I can create my map using:
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:39.93
longitude:-75.17
zoom:12];
mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera];
// use GPS to determine location of self
mapView_.myLocationEnabled = YES;
mapView_.settings.myLocationButton = YES;
mapView_.settings.compassButton = YES;
Now, I want to add a kml file (from a URL) that displays a route. I would imagine there is something within GMSMapView to allow this either as a layer or something else, but I'm not having any luck. I've seen the KMS Tutorial but that uses some other kit, MK something. Anyway, is there a way I can load a KML file using the Google Maps for iOS API?
I know this question is more than 1 year old but I couldn't find any solution, so I hope my solution will be useful.
You can load KML into GMSMapView using iOS-KML-Framework. I've ported this code from a project that was using KML-Viewer
Add method for parsing KML from the given URL, make sure you pass correct app bundle to dispatch_queue_create():
- (void)loadKMLAtURL:(NSURL *)url
{
dispatch_queue_t loadKmlQueue = dispatch_queue_create("com.example.app.kmlqueue", NULL);
dispatch_async(loadKmlQueue, ^{
KMLRoot *newKml = [KMLParser parseKMLAtURL:url];
[self performSelectorOnMainThread:#selector(kmlLoaded:) withObject:newKml waitUntilDone:YES];
});
}
Handle the KML parsing result or error:
- (void)kmlLoaded:(id)sender {
self.navigationController.view.userInteractionEnabled = NO;
__kml = sender;
// remove KML format error observer
[[NSNotificationCenter defaultCenter] removeObserver:self name:kKMLInvalidKMLFormatNotification object:nil];
if (__kml) {
__geometries = __kml.geometries;
dispatch_async(dispatch_get_main_queue(), ^{
self.navigationController.view.userInteractionEnabled = YES;
[self reloadMapView];
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
self.navigationController.view.userInteractionEnabled = YES;
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Error", nil)
message:NSLocalizedString(#"Failed to read the KML file", nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(#"OK", nil)
otherButtonTitles:nil];
[alertView show];
});
}
}
Go over the geometry items from KML and add them to the GMSMapView as markers:
- (void)reloadMapView
{
NSMutableArray *annotations = [NSMutableArray array];
for (KMLAbstractGeometry *geometry in __geometries) {
MKShape *mkShape = [geometry mapkitShape];
if (mkShape) {
if ([mkShape isKindOfClass:[MKPointAnnotation class]]) {
MKPointAnnotation *annotation = (MKPointAnnotation*)mkShape;
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = annotation.coordinate;
marker.appearAnimation = kGMSMarkerAnimationPop;
marker.icon = [UIImage imageNamed:#"marker"];
marker.title = annotation.title;
marker.userData = [NSString stringWithFormat:#"%#", geometry.placemark.descriptionValue];
marker.map = self.mapView;
[annotations addObject:annotation];
}
}
}
// set bounds in next run loop.
dispatch_async(dispatch_get_main_queue(), ^{
GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] init];
for (id <MKAnnotation> annotation in annotations)
{
bounds = [bounds includingCoordinate:annotation.coordinate];
}
GMSCameraUpdate *update = [GMSCameraUpdate fitBounds:bounds];
[self.mapView moveCamera:update];
[self.mapView animateToViewingAngle:50];
});
}
At the end of the last method we're updating the camera view to fit all the markers that were added to the map. You can remove this part if it's not needed.
KML is not yet supported in the SDK. Please file a feature request in the issue tracker.
This is how I solved similar problem using mentioned iOS-KML-Framework.
#import <GoogleMaps/GoogleMaps.h>
#import "KML.h"
#property (weak, nonatomic) IBOutlet GMSMapView *mapView;
- (void)loadZonesFromURL:(NSURL *)url {
KMLRoot* kml = [KMLParser parseKMLAtURL: url];
for (KMLPlacemark *placemark in kml.placemarks) {
GMSMutablePath *rect = [GMSMutablePath path];
if ([placemark.geometry isKindOfClass:[KMLPolygon class]]) {
KMLLinearRing *ring = [(KMLPolygon *)placemark.geometry outerBoundaryIs];
for (KMLCoordinate *coordinate in ring.coordinates) {
[rect addCoordinate:CLLocationCoordinate2DMake(coordinate.latitude, coordinate.longitude)];
}
GMSPolygon *polygon = [GMSPolygon polygonWithPath:rect];
polygon.fillColor = [UIColor colorWithRed:67.0/255.0 green:172.0/255.0 blue:52.0/255.0 alpha:0.3];
polygon.map = self.mapView;
}
}
}