Working with Symbols and Renderers
Symbols define all the non-geographic aspects of a Graphic's appearance. This includes a Graphic's color, border width, transparency, and more. The ArcGIS API for iOS includes many symbol classes, each of which allows you to specify symbology in a unique way. Each symbol type is also specific to one geometry type (i.e. point, line, or polygon).
Renderers define sets of Symbols to apply to a Graphics layer. The Symbol applied to each Graphic depends on the Graphic's attributes. The Renderer specifies which attribute values correspond to which Symbol.
Symbol Types
The available Symbols and the geometries to which they apply are summarized in the table below:
Symbol | Geometry | Description | Symbol Class |
---|---|---|---|
Simple Marker Symbol | Point | Symbolizes points with simple shapes | AGSSimpleMarkerSymbol |
Picture Marker Symbol | Point | Symbolizes points with images | AGSPictureMarkerSymbol |
Simple Line Symbol | Polyline | Symbolizes lines with pre-defined styles | AGSSimpleLineSymbol |
Composite Symbol | Point, Polyline, or Polygon | Symbolizes geometries with an array of symbols | AGSCompositeSymbol |
Simple Fill Symbol | Polygon | Fills polygons with a variety of patterns | AGSSimpleFillSymbol |
All the symbol classes mentioned above inherit from AGSSymbol.
Creating Symbols
In many applications, the same Symbol will be used many times. Consider, for instance, an application that uses the Find task to allow users to search for counties. In this situation, it makes sense to apply the same symbology to the task's results every time the task is executed. In such cases, In such cases, you should store a reference to the object in an instance variable/property in your class.
The following code creates an AGSSimpleMarkerSymbol drawn as a blue diamond with a white, three pixel-wide white outline.
//Create the AGSSimpleMarker Symbol and set some properties
AGSSimpleMarkerSymbol* myMarkerSymbol = [AGSSimpleMarkerSymbol simpleMarkerSymbol];
myMarkerSymbol.color = [UIColor blueColor];
myMarkerSymbol.style = AGSSimpleMarkerSymbolStyleDiamond;
myMarkerSymbol.outline.color = [UIColor whiteColor];
myMarkerSymbol.outline.width = 3;
The code below creates an AGSSimpleFillSymbol with a semi-transparent red fill and a red outline that is two pixels wide. Note that the outline for a simple fill symbol is itself an AGSSimpleLineSymbol.
//Create the AGSSimpleFillSymbol and set it’s color
AGSSimpleFillSymbol* myFillSymbol = [AGSSimpleFillSymbol simpleFillSymbol];
myFillSymbol.color = [UIColor colorWithRed:0.7 green:0.1 blue:0.1 alpha:0.5];
//Create the AGSSimpleLineSymbol used for the outline
AGSSimpleLineSymbol* myOutlineSymbol = [AGSSimpleLineSymbol simpleLineSymbol];
myOutlineSymbol.color = [UIColor redColor];
myOutlineSymbol.width = 2;
//set the outline property to myOutlineSymbol
myFillSymbol.outline = myOutlineSymbol;
Now that the symbol is declared, you can attach it to a graphic or use it in a renderer.
Renderers
A renderer defines a set of symbols that will be used for graphics in a Graphics Layer. You can use renderers to symbolize features with different colors or sizes based on a the graphic's attribute values. To use a renderer, you create it, define the symbology you want, then set the renderer property of a Graphics Layer.
myGraphicsLayer.renderer = myRenderer;
Creating a Simple Renderer
A simple renderer uses the same symbol for every graphic. All you have to do is create the renderer with the desired symbol, then Graphics Layer’s renderer property.
AGSSimpleRenderer* mySimpleRenderer = [AGSSimpleRenderer
simpleRendererWithSymbol:myMarkerSymbol];
myGraphicsLayer.renderer = mySimpleRenderer;
Note that the symbol property on AGSSimpleRenderer is read-only. To use a Symbol with a simple renderer you must create a Renderer with the desired symbol. Also, the Symbol type needs to match the feature type (marker symbols for point features, line symbols for polyline features, fill symbols for polygon features).
Creating a Class Breaks Renderer
A class breaks renderer symbolizes each Graphic based on the value of some numeric attribute. Graphics with similar values for the attribute get the same Symbol. The "breaks" define the values at which the symbology changes.
The mapping between symbols and values is defined in an array of AGSClassBreak objects. The AGSClassBreaksRenderer stores this in its classBreaks property as an array of AGSClassBreak objects. The AGSClassBreak object contains the Symbol used to draw the graphic, a minimum value, and a maximum value. Any value greater than or equal to the minimum value and less than the maximum value will get drawn using the class break symbol.
The following code creates an AGSClassBreaksRenderer in order to symbolize cities according to size. There are three class breaks, the first is from DBL_MIN to 50,000; the second is from 50,000 to 250,000; the last is from 250,000 to DBL_MAX:
//create the renderer with a default simple marker symbol
//and an attribute field.
AGSClassBreaksRenderer *cityRenderer = [[[AGSClassBreaksRenderer alloc] init] autorelease];
cityRenderer.field = @"POP1990";
cityRenderer.minValue = DBL_MIN;
//create three AGSClassBreak objects, one each for
//low, medium and high populations and the appropriate
//symbol (for clarity, the symbol creation has been omitted)
AGSClassBreak* lowClassBreak = [AGSClassBreak classBreakInfoWithLabel:@"Low" description:@"" maxValue:50000 symbol:lowMarkerSymbol];
AGSClassBreak* mediumClassBreak =[AGSClassBreak classBreakInfoWithLabel:@"Medium" description:@"" maxValue:250000 symbol:mediumMarkerSymbol];
AGSClassBreak* highClassBreak = [AGSClassBreak classBreakInfoWithLabel:@"High" description:@"" maxValue:DBL_MAX symbol:highMarkerSymbol];
//add the AGSClassBreak objects to the renderer in ascending order
NSMutableArray* classBreaks = [NSMutableArray array];
[classBreaks addObject:lowClassBreak];
[classBreaks addObject:mediumClassBreak];
[classBreaks addObject:highClassBreak];
cityRenderer.classBreaks = classBreaks;
//add the renderer to the graphics layer
citiesGraphicsLayer.renderer = cityRenderer;
The order of class breaks in the array will be important if you have overlapping ranges in your AGSClassBreak objects. The test whether a value lands in a particular class break starts with the first element of the array and proceeds which each subsequent element. Therefore, if a value could fall into more than one class break, the first one encountered in the array will be the one it is symbolized with.
Creating a Unique Value Renderer
A unique value renderer symbolizes groups of Graphics that have matching attributes. This is most common with nominal, or string data. For example, you could use a unique value renderer to symbolize zoning designations: yellow for "Residential", purple for "Industrial", red for "Commercial", and so on. You can also use unique value renderers on numeric fields that are coded values, or on ordinal attributes such as "First", "Second", "Third", and so on.
The following code creates an AGSUniqueValueRenderer for symbolizing cities with three values: “VILLAGE”, “CITY”, and “TOWN”, each with a unique Symbol to represent the “TYPE” attribute field (the creation of the Symbols has been omitted for clarity):
//create the renderer
//specify the attribute field whose values will decide the symbol
//we need to provide a default symbol for unmatched values
AGSUniqueValueRenderer *cityRenderer = [[[AGSUniqueValueRenderer alloc] init] autorelease];
cityRenderer.defaultSymbol = defaultMakerSymbol;
cityRenderer.field1 = @"TYPE";
//create three AGSUniqueValue objects, one each for
//CITY, TOWN, and VILLAGE
AGSUniqueValue* village = [[AGSUniqueValue alloc] initWithValue:@"VILLAGE" label:@"village" description:nil symbol:villageSymbol];
AGSUniqueValue* city = [[AGSUniqueValue alloc] initWithValue:@"CITY" label:@"city" description:nil symbol:citySymbol];
AGSUniqueValue* town = [[AGSUniqueValue alloc] initWithValue:@"TOWN" label:@"town" description:nil symbol:townSymbol];
//add the AGSUniqueValue objects to the renderer
[cityRenderer.uniqueValues addObject:village];
[cityRenderer.uniqueValues addObject:city];
[cityRenderer.uniqueValues addObject:town];
//add the renderer to the graphics layer
citiesGraphicsLayer.renderer = cityRenderer;
Note that the object in the setObject method above is the Symbol and the key is the attribute that Symbol will represent. The attributes are members of the attribute field specified in the AGSUniqueValueRenderer uniqueValueRendererWithDefaultSymbol method.
Remember, for all Renderer variations, the Symbol type needs to match the feature type: marker symbols for point features, line symbols for polyline features, and fill symbols for polygon features.