Change mapview Layers works inconsistently

2050
1
08-17-2011 04:22 AM
DarrenMackiewicz
Occasional Contributor
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.
0 Kudos
1 Reply
NimeshJarecha
Esri Regular Contributor
First, i would like to correct you for one thing. You are adding feature layer first and then base layer. If you do this the feature layer becomes the base layer. Please keep in mind that the first layer you add to mapView becomes a base layer.

Now, lets come to the actual problem. You mentioned that "In runtime, if the mapView has already been initialized I do this" and you reset the mapView and load new feature and base layer. Are you executing this code in mapViewDidLoad delegate method? or in any where else? If possible, please provide a sample application demonstrating the problem so I can help you out efficiently.

Regards,
Nimesh
0 Kudos