Select to view content in your preferred language

toggle basemap layer?

2166
5
06-17-2010 09:03 AM
AkhlaqRao
Emerging Contributor
Hi,

I am trying to toggle between two base map layers, i.e. I am using segmented tool to switch from one base layer let's say street view to satellite view. I am not quite sure if I can use VisibleLayer property while using AGSTiledMapLayer and also if I can then how to use this property?. Please give me an example since I am fairly new on ArcGis.

Regards
Rao
GeoSurfInc.
0 Kudos
5 Replies
AkhlaqRao
Emerging Contributor
I made it working, but I am not sure how efficient it is. All I did is very simple by one "if and else" condition and removed all the Layers by the time it toggles including base map layer and added new layers accordingly.

The code as follows will not work if you tried as it is, please modify according to your need:

if (((UISegmentedControl *) sender). selectedSegmentIndex ==1 or 0)
{
//---------Number of layers you want to remove.
[self.mapView removeMapLayerWithName:@"LayerName"];
|
|
//--------Number of layers you want to add.
//-------Ofcourse you need to create an instance of MapLayer first.
[self.mapView addMapLayer:LayerName withName:@"LayerName"];
|
|
}
else
{
//---------Number of layers you want to remove.
[self.mapView removeMapLayerWithName:@"LayerName"];
|
|
//--------Number of layers you want to add.
//-------Ofcourse you need to create an instance of MapLayer first.
[self.mapView addMapLayer:LayerName withName:@"LayerName"];
|
|
}

"NOW THE QUESTION IS, CAN WE DO BETTER THAN THIS???"

Regards
Rao
GeoSurfInc.
0 Kudos
JeremyBixby
Regular Contributor
I load 3 different AGSTiledMapService layers into a static model class when the AppDelegate first runs.  Then, depending on how the user interacts with the app, I swap out basemaps on the fly. 

There is a "loaded" boolean property on AGSTiledMapServiceLayer...I set a basemap property on my main map view that holds my AGSMapView as the user interacts with the app.  Then I check for the boolean "loaded" property.  If it's loaded and the current basemap is not the same as the one that I am trying to load, it swaps it out.  See below:

-(void) changeBasemap{
 
 iLenexaModel *myModel = [iLenexaModel sharedModel];
 
 if (myBasemap.loaded==YES) {
  NSLog(@"the basemap is loaded...");
  [mapView removeMapLayerWithName:@"myBasemap"];
  [mapView addMapLayer:myBasemap withName:@"myBasemap"];
  [mapView addMapLayer:myModel.aerials withName:@"aerials"];
 
 }
 
 else if(myBasemap.loaded==NO){
  NSLog(@"The basemap is not loaded...");
  //[self addLenexaTiledMapLayerURL:myBasemap.URL :@"myBasemap"];
  
  [mapView addMapLayer:myBasemap withName:@"myBasemap"];
  [mapView addMapLayer:myModel.aerials withName:@"aerials"];
  
 }
}


You could also add both layers to the AGSMapView, and then alter the "alpha" property from 1.0 to 0.0, depending on the user's selection on your toggle control.  I have a similar set up with a UISlider, but I haven't had much luck with getting it to correctly show through the AGSTiledMapServiceLayer that is on top...There is an Opaque property shown in the XCode autocomplete, but I can't find much about it. 

[mySlider addTarget:self action:@selector(handleSliderChange:) forControlEvents:UIControlEventTouchDragInside];


-(IBAction)handleSliderChange:(id)sender{
 
 NSLog(@"value : %f", self.mySlider.value);
 //NSLog(basemapName);
 AGSTiledLayerView *basemapView = [self.mapView.mapLayerViews objectForKey:@"myBasemap"];
 //basemapView.opaque = NO;
 basemapView.alpha = self.mySlider.value;
 
 //AGSTiledLayerView *aerialsView = [self.mapView.mapLayerViews objectForKey:@"aerials"];
 //aerialsView.alpha = 1.0;
 
 // [basemapView release];
 
}
0 Kudos
AkhlaqRao
Emerging Contributor
Thanks!, but the idea is not to have more than one TiledMapLayer loaded at a time. Yes, I've tried the alphaSlider property and NO LUCK. So far, the solution I came up it's working pretty good I only need to use Zombies to clear the Object references which it creates on every single toggle. I am interested to know how can I instantiate an object of TiledMapLayer in .h and initialize it in implement .m class. I can do it very easilly when I am using feature layers such graphics layer, but I am not sure how to do it using TiledMapLayer which can save my whole lots memory and avoid crushing the program.

@interface.......{
AGSTileMapServiceLayer *LayerName;
}
@property......... AGSTileMapServiceLayer *LayerName;
@end

@implement
@synthesize AGSTileMapServiceLayer LayerName;

-(void) viewDidLoad{
I've tried couple other ways but none of them worked.
CAN SOMEONE PLEASE COMPLETE THIS FOR ME BY INITIALIZING THEN ADDING AGSTiledMapLayer?
}

Regards
Rao
GeoSurfInc.
0 Kudos
ManojrajTeli
Deactivated User
I have more than 4 layers in my web app but i want to toggle between only two layers how do i do this using checkbox or radio button.I tried using javascript and c# both the time i was unsuccessful.
0 Kudos
BradyHoak
Esri Contributor
This seems to work OK:

- (void)viewDidLoad {
    [super viewDidLoad];

// set the delegate for the map view
self.mapView.mapViewDelegate = self;

//create an instance of a tiled map service lay

self.tiledBasemapLayer = [[AGSTiledMapServiceLayer alloc] initWithURL:[NSURL URLWithString:@"http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"]];



[self.mapView addMapLayer:self.tiledBasemapLayer withName:@"Basemap1"];
//release to avoid memory leaks
[self.tiledBasemapLayer release];


//create an instance of a dynmaic map layer
self.dynamicLayer = [[[AGSDynamicMapServiceLayer alloc] initWithURL:[NSURL URLWithString:kDynamicMapServiceURL]] autorelease];


//name the layer. This is the name that is displayed if there was a property page, tocs, etc...
self.dynamicLayerView = [self.mapView addMapLayer:self.dynamicLayer withName:@"Layer1"];


//set transparency
self.dynamicLayerView.alpha = 1.0;

// create and add the graphics layer to the map
self.graphicsLayer = [AGSGraphicsLayer graphicsLayer];
[self.mapView addMapLayer:self.graphicsLayer withName:@"Graphics Layer"];
}

to toggle the basemap there is a button that sets a new basmapurl

NSString *newBasemapURL = (your rest url)

if (newBasemapURL != nil) {

  //idea is that we have one basemap at all times, and its either called Basemap1 or Basemap2
  //the basemap is always at index 0
 
  //when the app starts we have one basemap at index 0 called Basemap1 and
  //a dynamic layer on top at index 1
 
  //Note that if you remove the current basemap before inserting the new one, the dynmaic layer will be under the new basemap,
  //so we need to add the new one at index 0, then remove the old basemap using its unique name
 
  //create new tilelayer for new basemap
  self.tiledBasemapLayer = [[AGSTiledMapServiceLayer alloc] initWithURL:[NSURL URLWithString:newBasemapURL]];
 
  //create a string to compare name of current basemap to
  NSString *baseMapStr = @"Basemap1";
 
  //get the names of the layers in the map
  NSArray *myLyrArray = [self.mapView mapLayerNames];
 
  //print out the names of the layers to the log
  NSLog(@"array: %@", myLyrArray);

  //see if the current basemap is called Basemap1
  if ([baseMapStr isEqualToString:[myLyrArray objectAtIndex:0]]) { 
   [self.mapView insertMapLayer:self.tiledBasemapLayer withName:@"Basemap2" atIndex:0];
   [self.mapView removeMapLayerWithName:@"Basemap1"];
  }
  else { //its called basemap2 then ....
   [self.mapView insertMapLayer:self.tiledBasemapLayer withName:@"Basemap1" atIndex:0];
   [self.mapView removeMapLayerWithName:@"Basemap2"];
  }
 
  [self.tiledBasemapLayer release];
  
}
0 Kudos