how to remove particular markers from GMS? - ios

I asked earlier how to show different markerInfoWindow in this question,
and now I'm trying to delete a particular marker when the user clicks on the button on the left corner.
first in .h file :
NSMutableArray *ADSMarray;
GMSMarker *adsMarker;
Then I created Ads marker like this:
for (int l=0 ; l<self.ADS.count; l++) {
CLLocationCoordinate2D pos = CLLocationCoordinate2DMake([[[self.ADS objectAtIndex:l] objectForKey:#"lati"] doubleValue],[[[self.ADS objectAtIndex:l] objectForKey:#"longi"] doubleValue]);
NSLog(#"Ads:: %f",[[[self.ADS objectAtIndex:l] objectForKey:#"longi"] doubleValue]);
adsMarker = [[GMSMarker alloc]init];
adsMarker.position=pos;
//marker.infoWindowAnchor = CGPointMake(0.44f, 0.45f);
adsMarker.draggable = NO;
adsMarker.appearAnimation=YES;
NSMutableArray*tempArray = [[NSMutableArray
alloc] init];
[tempArray addObject:#"ADS"];
[tempArray addObject:[self.ADS objectAtIndex:l]];
adsMarker.userData = tempArray;
adsMarker.map = mapView_;
adsMarker.icon=[GMSMarker markerImageWithColor:[UIColor blueColor]];
}
then in IBAction to remove them I wrote:
for (int i =0; i<self.ADS.count; i++) {
// adsMarker.map = nil;
[adsMarker setMap:nil];
}

When you add a marker store a reference to it. Then when you want to remove it, set its map property to nil - that will remove it from the map.

if you want to remove all markers in MapView you can use clear method that already built in GSM ..
Example:
[self.mapView clear];
link:
Remove a marker
and if you want to remove all markers with specific color you can use this code if the user click on blue markers button :
NSArray *blueMarkers = #[ markerBlue1, markerBlue2 ];
NSArray *greenMarkers = #[ markerGreen1, markerGreen2 ];
NSArray *purpleMarkers = #[ markerPurple1, markerPurple2 ];
for (GMSMarker *marker in blueMarkers ){
marker.map = nil;
}

To remove all markers
mapView.clear()
To remove a specific marker
myMarker.map = nil

Related

How to add new Annotation with existed annotations?

In my application, I was published recorded video from particular location. I can get the list of published location details from another service response. so Initially I got that published location details and displayed it on MapView. In MapView the pins are displayed with Cluster effect, so I used kingpin.
Here below I have loaded the Annotations on Map.
- (void)loadLocations:(NSArray *)arrayValues
{
_annotationArray = arrayValues;
[self.clusteringController setAnnotations:[self reSetannotations]];
[self.mapView setZoomEnabled:YES];
[self.mapView setCenterCoordinate:self.mapView.userLocation.coordinate];
[self.mapView setUserTrackingMode:MKUserTrackingModeFollow];
KPGridClusteringAlgorithm *algorithm = [KPGridClusteringAlgorithm new];
algorithm.annotationSize = CGSizeMake(25, 50);
algorithm.clusteringStrategy = KPGridClusteringAlgorithmStrategyTwoPhase;
self.clusteringController = [[KPClusteringController alloc] initWithMapView:self.mapView
clusteringAlgorithm:algorithm];
self.clusteringController.delegate = self;
self.clusteringController.animationOptions = UIViewAnimationOptionCurveEaseOut;
[self.clusteringController setAnnotations:[self annotations]];
NSString * lastobjlat;
double miles;
CLLocation * location = [COMMON currentLocation];
lastobjlat = [NSString stringWithFormat:#"%f",location.coordinate.latitude];
miles = 1.;
double scalingFactor = ABS( (cos(2 * M_PI * [lastobjlat floatValue] / 360.0) ));
MKCoordinateSpan span;
span.latitudeDelta = miles/69.0;
span.longitudeDelta = miles/(scalingFactor * 69.0);
MKCoordinateRegion region;
region.span = span;
region.center = location.coordinate;
[self.mapView setRegion:region animated:YES];
self.mapView.showsUserLocation = YES;
//Call in the below selectAnnotationAction method when I came to this, after I published new one on existed or new locations
if (COMMON.isRecentPublication == YES) {
COMMON.isRecentPublication = NO;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self selectAnnotationAction];
});
}
}
//To reset the Annotations
- (NSArray *)reSetannotations
{
NSMutableArray *annotations = [NSMutableArray array];
return annotations;
}
//Here I managed location details on my custom marker class MapAnnotation.
- (NSArray *)annotations {
CLLocationCoordinate2D locationPort;
NSMutableArray *annotations = [NSMutableArray array];
NSString *latitude, *longitude;
if ([_annotationArray count] > 0) {
for (int i = 0; i <[_annotationArray count]; i++){
latitude = [NSString stringWithFormat:#"%#",[[_annotationArray objectAtIndex:i] valueForKey:#"latitude"]];
latitude = [latitude stringByReplacingOccurrencesOfString:#"\n" withString:#""];
latitude = [latitude stringByReplacingOccurrencesOfString:#"\t" withString:#""];
longitude = [NSString stringWithFormat:#"%#",[[_annotationArray objectAtIndex:i] valueForKey:#"longitude"]];
longitude = [longitude stringByReplacingOccurrencesOfString:#"\n" withString:#""];
longitude = [longitude stringByReplacingOccurrencesOfString:#"\t" withString:#""];
latitude = [NSString replaceEmptyStringInsteadOfNull:latitude];
longitude = [NSString replaceEmptyStringInsteadOfNull:longitude];
int publicationRatio = [[[_annotationArray objectAtIndex:i] valueForKey:#"publicationRatio"] intValue];
int publicationCount = [[[_annotationArray objectAtIndex:i] valueForKey:#"publicationsCount"] intValue];
int teazLocationId = [[[_annotationArray objectAtIndex:i] valueForKey:#"objectId"] intValue];
BOOL isUpgrade = [[[_annotationArray objectAtIndex:i] valueForKey:#"isUpgraded"] boolValue];
locationPort = CLLocationCoordinate2DMake([latitude doubleValue] ,
[longitude doubleValue]);
//TODO : This is my custom annotation method
MapAnnotation *a1 = [[MapAnnotation alloc] initWithCoordinate:locationPort
tag:i
publicationRatio:publicationRatio
publicationCount:publicationCount
teazLocationId:teazLocationId isUpgraded:isUpgrade];
a1.itemindex = i + 1;
a1.publicationRatio = publicationRatio;
a1.publicationCount = publicationCount;
a1.teazLocationId = teazLocationId;
a1.isUpgraded = isUpgrade;
a1.coordinate = CLLocationCoordinate2DMake([latitude doubleValue] ,
[longitude doubleValue] );
[annotations addObject:a1];
if (COMMON.isRecentPublication == YES) {
if ([COMMON.recentPublicationLocationID isEqual: #(publishedLocationId)]) {
_recentAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:a1 reuseIdentifier:#"cluster"];
}
}
}
}
return annotations;
}
It's not a problem to load Annotations with clustering effect on initial time. But when I published some one from same or different(new also) locations, I need to redirect Map screen(publishing section is other screen) and I need to display that publication detail with Active pin image.
Following steps I made to show the published location detail on Map
I created recentPublicationLocationID as a global variable and store the recentPublishedLocationID from response after published service.
Then this return type method - (NSArray *)annotations(after redirect to mapView I got the location details from another webservice after that it will called),
I have compared with recentPublishedId If existed or not. Then If existed, I have assigned my custom annotation (contains the recentPublished location details) to global MKPinAnnotationView instance - _recentAnnotationView
Then I directly called the didSelectPinAnnotation delegate method from this method - (void)loadLocations:(NSArray *)arrayValues like below,
//Pass recent published location details
if (COMMON.isRecentPublication == YES)
{
COMMON.isRecentPublication = NO;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self selectAnnotationAction];
});
}
//selectAnnotationAction
- (void)selectAnnotationAction {
COMMON.isRecentPublication = NO;
COMMON.recentPublicationLocationID = nil;
[self mapView:self.mapView didSelectAnnotationView:_recentAnnotationView];
}
If I directly passed recentPublishedLocation details to didSelectAnnotationView delegate, I can only show the In Active pin instead of Active pin.
Then I debug with breakpoint why I can see the In active pin only ?
Because In this situation the didselect delegate was called and I can see the Active pin image. But it's only within sec.
Because viewForAnnotation delegate was called quickly for other pin annotations so the selected one goes to unselected state
This is the real problem. How can I overcome this work with clusters ?
Because when I displayed that published location detail correctly on map even it should be work with clustering effect. Yes I will zoom back to see the pins with cluster effect .
Finally I got the solution and achieved my requirement using ClusterKit library instead of Kingpin.
This tool really helpful me against possible to achieve append annotations and customize every thing adopt with my requirements.
So it's more helpful to me. Of course all of you.
And this tool supports Apple & Goole maps with Objective c as well as Swift.
I hope this one more helpful to other developers also.
Thanks :)

Adding annotations from a KML file to an MKMapView

I am trying to load data from a KML file over to an MKMapView. I was able to parse the data into an array and now I am trying to create annotations on the map for each item.
Using the code below, I was able to create annotations on the map but the location is not correct:
Parser *parser = [[Parser alloc] initWithContentsOfURL:url];
parser.rowName = #"Placemark";
parser.elementNames = #[#"name", #"address", #"coordinates", #"description"];
[parser parse];
//parseItem is an array returned with all data after items are parsed.
for (NSDictionary *locationDetails in parser.parseItems) {
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.title = locationDetails[#"name"];
NSArray *coordinates = [locationDetails[#"coordinates"] componentsSeparatedByString:#","];
annotation.coordinate = CLLocationCoordinate2DMake([coordinates[0] floatValue], [coordinates[1] floatValue]);
[self.mapView addAnnotation:annotation];
}
The result of the NSLog of the coordinates was:
coords=-73.96300100000001,40.682846,0
So it looks like the coordinates are coming in longitude,latitude order but the CLLocationCoordinate2DMake function takes latitude,longitude.
Unless the coordinates are supposed to be in Antarctica instead of New York City, try:
annotation.coordinate = CLLocationCoordinate2DMake(
[coordinates[1] doubleValue],
[coordinates[0] doubleValue]);
Also note you should change floatValue to doubleValue for more accurate placement (it will also match the type of CLLocationDegrees which is a synonym for double).

iOS7 - Map view pin do not appear until screen is touched

In my app, I download a set of point from a web service using json.
Actualizing the app to iOS7, I am experimenting that problem: the locations are downloaded but pins on the map are not painted until user touchs and "moves" the map. Then they appear and all work as in iOS6.
How can I correct that behavior?
EDIT:
AddAnnotation is called at the end of a method that receive data, parse the json and pass them to mylocaction object:
- (void)plotBarPosition:(NSString *)data_string {
// Parse the string into JSON
NSDictionary *json = [(NSDictionary*)[datos_string1 JSONValue]objectForKey:#"features"];
for (int i = 0; i < [json count]; i++){
/*
PARSING EACH POINT
*/
MyLocation *location =[[MyLocation alloc] initWithName:nameLoc coordinate:coordinate estado:status antenaId:antenaId];
[_mapView addAnnotation:location];
}
}
I tryed also:
[_mapView performSelectorOnMainThread: #selector(addAnnotations:) withObject: location waitUntilDone: NO];
but in this case, annotations do not appear at all.
As this answer and the comment by #RAJA suggest, call addAnnotation: or addAnnotations: on the main thread. You could do this using GCD or performSelectorOnMainThread.
The option with the least changes to your existing code is to call addAnnotation: (singular):
- (void)plotBarPosition:(NSString *)data_string {
// Parse the string into JSON
NSDictionary *json = [(NSDictionary*)[datos_string1 JSONValue]objectForKey:#"features"];
for (int i = 0; i < [json count]; i++){
/*
PARSING EACH POINT
*/
MyLocation *location =[[MyLocation alloc] initWithName:nameLoc coordinate:coordinate estado:status antenaId:antenaId];
//[_mapView addAnnotation:location];
[_mapView performSelectorOnMainThread:#selector(addAnnotation:)
withObject:location
waitUntilDone:YES];
}
}
Alternatively, to use addAnnotations: (plural), you first add your annotations to a local array and give them to the map view all together in a single call. Changes below are marked with >>>:
- (void)plotBarPosition:(NSString *)data_string {
// Parse the string into JSON
NSDictionary *json = [(NSDictionary*)[datos_string1 JSONValue]objectForKey:#"features"];
//>>> initialize array to hold annotations...
NSMutableArray *annotationsToAdd = [NSMutableArray array];
for (int i = 0; i < [json count]; i++){
/*
PARSING EACH POINT
*/
MyLocation *location =[[MyLocation alloc] initWithName:nameLoc coordinate:coordinate estado:status antenaId:antenaId];
//>>> comment out direct addAnnotation...
//[_mapView addAnnotation:location];
//>>> add annotation to local array...
[annotationsToAdd addObject:location];
}
//>>> call addAnnotations: (plural) on main thread...
[_mapView performSelectorOnMainThread:#selector(addAnnotations:)
withObject:annotationsToAdd
waitUntilDone:YES];
}
There is a protocol MKAnnotation - you have to determine you own class for annotation with realizing of this protocol:
#interface MyAnnotation : NSObject <MKAnnotation> {
CLLocationCoordinate2D coordinate;
}
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate;
Then you have to init MyAnnotation and add it on map:
MyAnnotation *annotation = [[MyAnnotation alloc] initWithCoordinate:CLLocationCoordinate2DMake(latitude, longitude)];
[myMap addAnnotation:annotation];
Also try to call
[mapView setNeedsDisplay];
or
[mapView setNeedsLayout];
after adding annotations

plot marker on Google Maps iOS from JSON file

I would like to plot markers on Google Maps for iOS, and this by including JSON file that will includes longitude and latitude. I can do it manually in the code, by replacing the values.
The problem is that I don't know how to show new markers on the map from JSON file.
Here is my code :
- (void)addDefaultMarkers {
// Add a custom 'glow' marker around Sydney.
GMSMarker *sydneyMarker = [[GMSMarker alloc] init];
sydneyMarker.title = #"Sydney!";
sydneyMarker.icon = [UIImage imageNamed:#"glow-marker"];
sydneyMarker.position = CLLocationCoordinate2DMake(25.062718, 55.130761);
sydneyMarker.map = mapView_;
GMSMarker *melbourneMarker = [[GMSMarker alloc] init];
melbourneMarker.title = #"Melbourne!";
melbourneMarker.icon = [UIImage imageNamed:#"arrow"];
melbourneMarker.position = CLLocationCoordinate2DMake(25.100822, 55.17467);
melbourneMarker.map = mapView_;
}
Any ideas on how to do it ?
chech my question in this link, stackoverflow.com/questions/20902732/…. This link will help,
First of all parse the json data. And collect it as array or dictionary, then U can directly plot the value in map
The first two lines are to parse the data into an array
SBJsonParser *jsonParser = [SBJsonParser new];
NSArray *jsonData = (NSArray *) [jsonParser objectWithString:outputData error:nil];
then, the loop should continue till the no. of values,
for(int i=0;i<[jsonData count];i++)
{
NSDictionary *dict=(NSDictionary *)[jsonData objectAtIndex:i];
Nslog(#"%#",dict);
double la=[[dict objectForKey:#"latitude"] doubleValue];
double lo=[[dict objectForKey:#"longitude"] doubleValue];
CLLocation * loca=[[CLLocation alloc]initWithLatitude:la longitude:lo];
CLLocationCoordinate2D coordi=loca.coordinate;
marker=[GMSMarker markerWithPosition:coordi];
marker.snippet = #"Hello World";
marker.animated = YES;
marker.map = mapView;
}

Plotting multiple markers in Google Maps

Hi I am working on Google Maps SDK for ios. I want to plot a number of markers in Google maps from NSArray which contains location name, latitude and longitude.
I tried using For loops which seems a little lame already but,
for(int i=0;i<=[myArray count];i++){
self.view = mapView_;
NSString *lat = [[myArray objectAtIndex:i] objectForKey:#"latitude"];
NSString *lon = [[myArray objectAtIndex:i] objectForKey:#"longitude"];
double lt=[lat doubleValue];
double ln=[lon doubleValue];
NSString *name = [[myArray objectAtIndex:i] objectForKey:#"name"];
NSLog(#"%# and %# and %f and %f of %#",lat,lon, lt,ln,name);
GMSMarker *marker = [[GMSMarker alloc] init];
marker.animated=YES;
marker.position = CLLocationCoordinate2DMake(lt,ln);
marker.title = name;
marker.snippet = #"Kathmandu";
marker.map = mapView_;
}
Here myarray is the array that has location name , latitude longitude in string format which I converted it to double. When I run this code Xcode shows me NSRangeException: index beyond bounds, which is probably because I am trying to use same object to display different indexes in same map. But at the same time, I couldnot think of any way to use GMSMarker as array.
I could however plot multiple markers if I used different GMSMarker objects, but that doesnot solve my problem. I made another object like this, using two GMSMarker objects work to show two markers on the same map.
GMSMarker *marker1 = [[GMSMarker alloc] init];
marker1.animated=YES;
marker1.position = CLLocationCoordinate2DMake(lt,ln);
marker1.title = name;
marker1.snippet = #"Kathmandu";
marker1.map = mapView_;
Any help?
But at the same time, I couldnot think of any way to use GMSMarker as array.
try this:
NSMutableArray *markersArray = [[NSMutableArray alloc] init];
for(int i=0;i<[myArray count];i++){
// ... initialise marker here
marker.map = mapView_;
[markersArray addObject:marker];
[marker release];
}

Resources