0

Working in iOS 6, I cannot seem to get the map view to update itself to show markers added or removed.

When the app opens, a number of markers are placed on the map. The user can then make choices that add new markers and/or remove existing markers. This uses the same method as when the RMMarkerManager is populated at viewWillLoad, and I can iterate through the markers in the RMMarkerManager and see that it has the new set of markers, but the map view never updates to show them.

I have tried [mapview setNeedsDisplay] with no effect.

Clearly, I'm missing something that causes the mapview to update the display of the markers, but I have not figured out what, despite lots of head-scratching and digging through documentations and posts.

I will appreciate any suggestions as to what I should change or add.

As requested, here is the appropriate code. I'll explain how it works.

In the viewController's createMarkers method, the markers are created by accessing a sqlite database. One marker is created for each record that I want displayed as a marker on the map. I then iterate through the array of markers, adding each to the mapView's marketManager (addMarker method). The method createMarkers is called in the viewController's viewWillLoad method, and works correctly: all markers are displayed.

When using the app, a user can select or de-select records in the database. Then the viewController receives a notification that the user has changed the selection, and calls its setMarkers method. The mapview's marketmanager gets a removeMarkers message, then the marker array is re-created; it now has markers reflecting the user's selections. But the map never updates the on-view markers. Markers removed by the user are not removed on the view; markers added by the user are not added.

After the update, I can iterate through mapview.markermanager.markers and see that it now contains the new markers. But they're never shown on the mapView.

Class: Marker, subclass of RMMarker. Simply holds data about the marker to be displayed Marker.h:

//  Marker.h

#import <Foundation/Foundation.h>
#import "Location.h"
#import "RMMarker.h"

@interface Marker : RMMarker {
    NSString *category_name;
    NSString *name;
    NSString *desc;
    NSString *address;
    NSString *png;
    int marker_id;
    float lat;
    float longi;
    CLLocationCoordinate2D node;
    float label_x_offset;
    float label_y_offset;
}
@property (nonatomic, strong) NSString *category_name;
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *desc;
@property (nonatomic, retain) NSString *address;
@property (nonatomic, retain) NSString *png;
@property (nonatomic) int marker_id;
@property (nonatomic) float lat;
@property (nonatomic) float longi;
@property (nonatomic) CLLocationCoordinate2D node;
@property (nonatomic) float label_x_offset;
@property (nonatomic) float label_y_offset;

@end

Class: Markers Holds an NSMutableArray of Markers, which is populated from a sqlite database:

//  Markers.m

#import "Markers.h"
#import "defs.h"
#import "FileLocator.h"
#import "Marker.h"

@implementation Markers 
@synthesize markers;

-(NSMutableArray *) createMarkers {        
    markers = [[NSMutableArray alloc] init];

    [self openDatabase];

    NSString *query = [NSString stringWithFormat:@"SELECT categories.selected, categories.category_id, categories.png, places.name, address, description, latitude, longitude, place_id FROM places, categories WHERE (categories.selected = 1 AND places.category_id = categories.category_id);"];

    debugPrintArgs(@"query: %@", query);
    FMResultSet *rs = [db executeQuery:query];
    while ([rs next]) {
        Marker *marker = [[Marker alloc] init];
        marker.marker_id = [rs intForColumn:@"place_id"];
        marker.name = [rs stringForColumn:@"name"];
        marker.address = [rs stringForColumn:@"address"];
        marker.desc = [rs stringForColumn:@"description"];
        marker.lat = [rs doubleForColumn:@"latitude"];
        marker.longi = [rs doubleForColumn:@"longitude"];
        marker.png = [rs stringForColumn:@"png"];
        debugPrintArgs(@"%@, %@, %@, %f, %f", marker.name, marker.address, marker.description, marker.lat, marker.longi);
        marker.label_y_offset = 150.0f;
        marker.label_x_offset = 30.0f;
        [markers addObject:marker];
    }

    [db close];
    return markers;
}

@end    

Methods in the viewcontroller: setMarkers: Iterates through the NSMUtableArray Markers, calling the method addMarker: for each marker in that array:

- (void) setMarkers {

//  class Markers is essentially an NSMutableArray that holds instantiations of Marker - one for each marker to be displayed
//  Markers is also responsible for populating itself from a sqlite database via the createMarkers method   
    Markers *markers = [[Markers alloc] init];
    NSMutableArray *allMarkers = [markers createMarkers];

//  allMarkers contains the markers to be displayed. 

    CLLocationCoordinate2D loc;
    if ([allMarkers count] > 0) {
        for (Marker *mrkr in allMarkers) {
            loc.longitude = mrkr.longi;
            loc.latitude = mrkr.lat ;
            [self addMarker: mrkr at:loc withText:mrkr.name xOffset: mrkr.label_x_offset yOffset: mrkr.label_y_offset png: mrkr.png];
        }
    }
}

Also in the viewController: addMarker And, finally, the addMarker method used to add a marker to the RMMarkerManager:

- (void) addMarker: (Marker *) marker at:(CLLocationCoordinate2D)loc withText:(NSString *)text xOffset: (float) x_offset yOffset:(float) y_offset png:(NSString *) png {

    UIImage* markerImage = [UIImage imageNamed:png];
    [marker replaceUIImage:markerImage anchorPoint:CGPointMake(0.38f, 1.08f)];

    [viewMap.markerManager addMarker: marker AtLatLong: loc];

    CGPoint position = CGPointMake(  0.0f, 0.0f);

    [marker changeLabelUsingText: text position: position ];
    }
johnz
  • 11
  • 3
  • post some code showing how the map annotations are added. – Wain May 08 '13 at 15:33
  • Please give better explanation of what you do. Using addAnnotation / removeAnnotation always did it for me. – Mirco Ellmann May 08 '13 at 15:34
  • Code and comments added. – johnz May 08 '13 at 21:14
  • Stil digging around in the innards of route-me to figure this out. Another piece of information is that when I have added or deleted markers,I can iterate over viewMap.contents.overlay.sublayers (where viewMap is my RMMapView) and see all the sub-layers that should exist. This is more and more appearing (to my novice eye) that something is preventing the drawing of the sub-layers, but I surely don't know what is preventing that. – johnz May 09 '13 at 22:22

1 Answers1

0

The offending line here is in setMarkers:

Markers *markers = [[Markers alloc] init];

Making markers an instance variable and doing the alloc-init in the class's viewWillLoad method corrected the problem.

I wish I could explain this better, but I am unsure as to why this caused the problem. But, it's corrected now and I'll explore when I've got some time.

johnz
  • 11
  • 3