wherewhy

Change mapview Layers works inconsistently

Discussion created by wherewhy on Aug 17, 2011
Latest reply on Aug 17, 2011 by njarecha-esristaff
Could someone please instruct me on the proper way to remove layers from my mapView and replace them with new layers? I've tried a multitude of ways, and none works consistently.
I get strange 'EXC_BAD_ACCESS' errors, or it will work twice, but on the 3rd time ALWAYS bombs.


Here's what I'm trying to do -
I initialize my map with 2 layers, a Base Layer and a Feature Layer.
Then, during runtime, I want to remove those two layers and add in two new ones.

Initial Set up Code:

        //Set up the map view
        self.mapView.layerDelegate = self;
        self.mapView.touchDelegate = self;
        self.mapView.calloutDelegate = self;
        self.mapView.showMagnifierOnTapAndHold = YES;
       
       
        // Add the Feature Layer to the mapView   
        NSURL* url = [NSURL URLWithString: featureLayerURL];
        self.featureLayer = [AGSFeatureLayer featureServiceLayerWithURL: url mode: AGSFeatureLayerModeOnDemand];
        [self.mapView addMapLayer:self.featureLayer withName:@"featureLayer"];
       

       
        // Create dynamic map service info with URL of base map
        AGSMapServiceInfo *bms = [[[AGSMapServiceInfo alloc] initWithURL:[NSURL URLWithString:baseLayerURL] error:&error] autorelease];
        AGSDynamicMapServiceLayer *baseLayer = [[AGSDynamicMapServiceLayer alloc] initWithMapServiceInfo:bms];
       
       
        // Add base layer to the mapView
        [self.mapView addMapLayer:baseLayer withName:@"baseLayer"];


No problems there.
Then, in runtime, if the mapView has already been initialized I do this:


        [self.mapView reset];

           
        // Add the Feature Layer to the mapView   
        NSURL* url = [NSURL URLWithString: featureLayerURL];
       
        self.featureLayer = [AGSFeatureLayer featureServiceLayerWithURL: url mode: AGSFeatureLayerModeOnDemand];
        [self.mapView addMapLayer:self.featureLayer withName:@"featureLayer"];
        self.featureLayer.infoTemplateDelegate = self.featureLayer;
       

    // Create dynamic map service info with URL of base map
        AGSMapServiceInfo *bms = [[[AGSMapServiceInfo alloc] initWithURL:[NSURL URLWithString:baseLayerURL] error:&error] autorelease];
        AGSDynamicMapServiceLayer *baseLayer = [[AGSDynamicMapServiceLayer alloc] initWithMapServiceInfo:bms];
        [self.mapView addMapLayer:baseLayer withName:@"baseLayer"];


This works SOME times, and then IF it works, it only works twice. On the third execution it always fails. 

In case you're wondering, the line it fails on is the one with the self.featureLayer

        self.featureLayer = [AGSFeatureLayer featureServiceLayerWithURL: url mode: AGSFeatureLayerModeOnDemand];



I have also tried to just remove the layers, and add them back in

        [self.mapView removeMapLayerWithName:@"featureLayer"];
        [self.mapView removeMapLayerWithName:@"baseLayer"];

        // Add the Feature Layer to the mapView   
        NSURL* url = [NSURL URLWithString: featureLayerURL];
        AGSFeatureLayer *tmpFeatureLayer = [[AGSFeatureLayer alloc] initWithURL:url mode:AGSFeatureLayerModeOnDemand];
        [self.mapView addMapLayer:tmpFeatureLayer withName:@"featureLayer"];


    // Create dynamic map service info with URL of base map
        AGSMapServiceInfo *bms = [[[AGSMapServiceInfo alloc] initWithURL:[NSURL URLWithString:baseLayerURL] error:&error] autorelease];
        AGSDynamicMapServiceLayer *baseLayer = [[AGSDynamicMapServiceLayer alloc] initWithMapServiceInfo:bms];
        [self.mapView addMapLayer:baseLayer withName:@"baseLayer"];



While this method works solid EVERY TIME, because I'm not setting the self.featureLayer info that I am in the first way of doing it - the if statement in the didLoadLayerForLayerView delegate call is never met, so therefore, the infoTemplateDelegate is never set, and I have no popup info windows on my newly added Feature Layer.



-(void)mapView:(AGSMapView *)mapView didLoadLayerForLayerView:(UIView <AGSLayerView>*)layerView{
   
    //grab the feature layer
    if (layerView.agsLayer == self.featureLayer){
       
       
        AGSFeatureLayer *tmpfeatureLayer = (AGSFeatureLayer *)layerView.agsLayer;
       
        //set the feature layer as its infoTemplateDelegate
        //this will then automatically set the callout's title to a value
        //from the display field of the feature service
        tmpfeatureLayer.infoTemplateDelegate = tmpfeatureLayer;
       
        //Get all the fields
        tmpfeatureLayer.outFields = [NSArray arrayWithObject:@"*"];
       
        //This view controller should be notified when features are edited
        tmpfeatureLayer.editingDelegate = self;
       
        [tmpfeatureLayer release];
       
       
    }
}




If someone can tell me the proper way to do this, I would be VERY appreciative.

Outcomes