Skip to content
View on GitHubSample viewer app

Apply a renderer to a sublayer.

Image of Apply class breaks renderer to sublayer sample

Use case

A layer showing animal populations contains sublayers for different species. A renderer could be applied which gives each sublayer a different color, so that populations of each species can be compared visually.

How to use the sample

Wait for the map image layer to load. Tap the 'Change sublayer renderer' button to apply a unique value renderer to see different population ranges in the counties sub-layer data.

How it works

  1. Create an ArcGISMapImageLayer from a URL.
  2. After it is done loading, get its map image sublayers.
  3. Get the MapImageSublayer.
  4. Create a ClassBreaksRenderer with a collection of ClassBreaks for different population ranges.
  5. Set class breaks renderer as the renderer of the sublayer.

Relevant API

  • ArcGISMapImageLayer
  • ArcGISMapImageSublayer
  • ClassBreak
  • ClassBreaksRenderer

About the data

This application displays census data from an ArcGIS Server map service. It contains various population statistics, including total population for each county in 2007.

Additional information

The service hosting the layer must support dynamic layers to be able to change the rendering of sublayers.

Tags

class breaks, dynamic layer, dynamic rendering, renderer, sublayer, symbology, visualization

Sample Code

ApplyClassBreaksRendererToSublayerViewModel.ktApplyClassBreaksRendererToSublayerViewModel.ktMainActivity.ktApplyClassBreaksRendererToSublayerScreen.kt
Use dark colors for code blocksCopy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 /* Copyright 2025 Esri  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  * http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  *  */  package com.esri.arcgismaps.sample.applyclassbreaksrenderertosublayer.components  import android.app.Application import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope import com.arcgismaps.Color import com.arcgismaps.geometry.Envelope import com.arcgismaps.geometry.SpatialReference import com.arcgismaps.mapping.ArcGISMap import com.arcgismaps.mapping.BasemapStyle import com.arcgismaps.mapping.Viewpoint import com.arcgismaps.mapping.layers.ArcGISMapImageLayer import com.arcgismaps.mapping.layers.ArcGISMapImageSublayer import com.arcgismaps.mapping.symbology.ClassBreak import com.arcgismaps.mapping.symbology.ClassBreaksRenderer import com.arcgismaps.mapping.symbology.Renderer import com.arcgismaps.mapping.symbology.SimpleFillSymbol import com.arcgismaps.mapping.symbology.SimpleFillSymbolStyle import com.arcgismaps.mapping.symbology.SimpleLineSymbol import com.arcgismaps.mapping.symbology.SimpleLineSymbolStyle import com.esri.arcgismaps.sample.sampleslib.components.MessageDialogViewModel import kotlinx.coroutines.launch  class ApplyClassBreaksRendererToSublayerViewModel(app: Application) : AndroidViewModel(app) {   // The map image layer  private val mapImageLayer =  ArcGISMapImageLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer")   var arcGISMap = ArcGISMap(BasemapStyle.ArcGISTopographic).apply {  initialViewpoint = Viewpoint(  Envelope(  xMin = -13934661.666904,  yMin = 331181.323482,  xMax = -7355704.998713,  yMax = 9118038.075882,  spatialReference = SpatialReference.webMercator()  )  )  // Add the map image layer to the map  operationalLayers.add(mapImageLayer)  }   // The counties sublayer  private var countiesSublayer: ArcGISMapImageSublayer? = null   // The original renderer of the counties sublayer  private var originalRenderer: Renderer? = null   private var classBreaksRenderer = ClassBreaksRenderer(  fieldName = "POP2007",  classBreaks = classBreaks  )   // Whether the class breaks renderer is currently applied  var classBreaksRendererIsApplied by mutableStateOf(false)  private set   // Whether the sublayer is loaded and ready  var isSublayerReady by mutableStateOf(false)  private set   // Message dialog view model for error handling  val messageDialogVM = MessageDialogViewModel()   init {  viewModelScope.launch {   // Load the map image layer  mapImageLayer.load().onSuccess {  // Get the sublayers  val sublayers = mapImageLayer.mapImageSublayers  if (sublayers.size > 2) {  val sublayer = sublayers[2]  sublayer.load().onSuccess {  countiesSublayer = sublayer  originalRenderer = sublayer.renderer  isSublayerReady = true  }.onFailure { messageDialogVM.showMessageDialog(it) }  } else {  messageDialogVM.showMessageDialog("Counties sublayer not found.")  }  }.onFailure { messageDialogVM.showMessageDialog(it) }  }  }   /**  * Toggle the renderer on the counties sublayer between the original and the class breaks renderer.  */  fun toggleClassBreaksRenderer() {  val sublayer = countiesSublayer ?: return  classBreaksRendererIsApplied = !classBreaksRendererIsApplied  sublayer.renderer = if (classBreaksRendererIsApplied) {  classBreaksRenderer  } else {  originalRenderer  }  }   /**  * Companion object to hold the class breaks and symbols.  */  companion object {  private val outline = SimpleLineSymbol(  style = SimpleLineSymbolStyle.Solid,  color = Color.fromRgba(153, 153, 153, 255), // gray  width = 0.5f  )   private val symbol1 = SimpleFillSymbol(  style = SimpleFillSymbolStyle.Solid,  color = Color.fromRgba(227, 235, 207, 255), // light green  outline = outline  )  private val symbol2 = SimpleFillSymbol(  style = SimpleFillSymbolStyle.Solid,  color = Color.fromRgba(150, 193, 191, 255), // teal  outline = outline  )  private val symbol3 = SimpleFillSymbol(  style = SimpleFillSymbolStyle.Solid,  color = Color.fromRgba(98, 167, 182, 255), // blue-green  outline = outline  )  private val symbol4 = SimpleFillSymbol(  style = SimpleFillSymbolStyle.Solid,  color = Color.fromRgba(68, 125, 151, 255), // darker blue  outline = outline  )  private val symbol5 = SimpleFillSymbol(  style = SimpleFillSymbolStyle.Solid,  color = Color.fromRgba(41, 84, 121, 255), // navy  outline = outline  )   private val classBreaks = listOf(  ClassBreak(  description = "-99 to 8,560",  label = "-99 to 8,560",  minValue = -99.0,  maxValue = 8560.0,  symbol = symbol1  ),  ClassBreak(  description = "> 8,560 to 18,109",  label = "> 8,560 to 18,109",  minValue = 8561.0,  maxValue = 18109.0,  symbol = symbol2  ),  ClassBreak(  description = "> 18,109 to 35,501",  label = "> 18,109 to 35,501",  minValue = 18110.0,  maxValue = 35501.0,  symbol = symbol3  ),  ClassBreak(  description = "> 35,501 to 86,100",  label = "> 35,501 to 86,100",  minValue = 35502.0,  maxValue = 86100.0,  symbol = symbol4  ),  ClassBreak(  description = "> 86,100 to 10,110,975",  label = "> 86,100 to 10,110,975",  minValue = 86101.0,  maxValue = 10110975.0,  symbol = symbol5  )  )  } }

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.