ArcGIS Runtime SDK for iOS

Add graphics and text to graphics overlays

A graphic is a visible item on your map that can be seen as a point, line, polygon, or text. You can add graphics to your map view. These are contained in graphics overlays and are for showing temporary data that's not persisted once the application closes. For example, you may want to display a route between two locations or animate data items that change quickly.

This topic discusses adding graphics to your map in a way that generates a symbol instance for each graphic. If you're drawing a large number of graphics with the same symbology, then you should consider applying a renderer to the graphics overlay instead, which allows you to define the appearance of all the graphics in the overlay. Using renderers to add graphics is discussed in Symbols and renderers.

The image below shows an example of graphics drawn over a gray basemap. The graphics are showing:

  • Red markers showing location of buoys
  • Text symbols adding names to the islands of Craigleith and Bass Rock
  • A green cross hatched polygon showing a Gannet nesting ground on Bass Rock
  • A purple line showing the path of a boat trip.

Screenshot of a map with multiple graphics

For more information on graphics and when to use them, see Features and graphics. For more information on graphics overlays, see Add graphics overlays to your app.

Add point graphics

The following steps show how to create the red buoy markers on the image above.

  1. The location of point graphics is represented by the AGSPoint geometry class. The following code shows how the buoy locations are defined:

    //define the buoy locations
    let buoy1Loc = AGSPoint(x: -2.712642647560347, y: 56.062812566811544, spatialReference: .wgs84())
    let buoy2Loc = AGSPoint(x: -2.6908416959572303, y: 56.06444173689877, spatialReference: .wgs84())
    let buoy3Loc = AGSPoint(x: -2.6697273884990937, y: 56.064250073402874, spatialReference: .wgs84())
    let buoy4Loc = AGSPoint(x: -2.6395150461199726, y: 56.06127916736989, spatialReference: .wgs84())

    The points are defined in the WGS84 spatial reference, which is generally the spatial reference you would obtain from a GPS receiver, for example.

    Tip:

    If the spatial reference of the geometry of a graphic is null, then it is assumed the geometry is in the same spatial reference as the map view; if your graphics do not display as expected and have a null spatial reference, check that the coordinates of your geometry use the same spatial reference as the map view. If the spatial reference is set, and is different to that of the map view, geometries are automatically reprojected for display. For maximum efficiency, especially when dealing with large numbers of graphics or moving graphics, geometries of graphics should have the same spatial reference as the map view.

  2. Define what the points look like. Points can be drawn as simple marker symbols (circles, crosses, diamonds, etc.) or picture marker symbols represented by small bitmap images.

    The code below shows how to define a red circle.

    //create a marker symbol
    let buoyMarker = AGSSimpleMarkerSymbol(style: .circle, color: .red, size: 10)

  3. Create graphics, which are defined by the point geometry and the symbol.

    //create graphics
    let buoyGraphic1 = AGSGraphic(geometry: buoy1Loc, symbol: buoyMarker)
    let buoyGraphic2 = AGSGraphic(geometry: buoy2Loc, symbol: buoyMarker)
    let buoyGraphic3 = AGSGraphic(geometry: buoy3Loc, symbol: buoyMarker)
    let buoyGraphic4 = AGSGraphic(geometry: buoy4Loc, symbol: buoyMarker)

  4. Add the graphics to the graphics overlay, which will display them on the map view.

    //add the graphics to the graphics overlay
    graphicsOverlay.graphics.addObjects(from: [buoyGraphic1, buoyGraphic2, buoyGraphic3, buoyGraphic4])

Add line graphics

The following steps show how to create the purple, dashed line representing the boat trip in the image near the top of this topic.

  1. The geometry for the boat trip is represented by the AGSPolyline class. This is built with a collection of points used to define the vertices of the line.

    //create a polyline
    let boatRoute = AGSPolylineBuilder(spatialReference: .wgs84())
    //add positions to the point collection
    boatRoute.addPointWith(x: -2.7184791227926772, y: 56.06147084563517)
    boatRoute.addPointWith(x: -2.7196807500463924, y: 56.06147084563517)
    boatRoute.addPointWith(x: -2.722084004553823, y: 56.062141712059706)
    boatRoute.addPointWith(x: -2.726375530459948, y: 56.06386674355254)
    boatRoute.addPointWith(x: -2.726890513568683, y: 56.0660708381432)
    boatRoute.addPointWith(x: -2.7270621746049275, y: 56.06779569383808)
    boatRoute.addPointWith(x: -2.7255172252787228, y: 56.068753913653914)
    boatRoute.addPointWith(x: -2.723113970771293, y: 56.069424653352335)
    boatRoute.addPointWith(x: -2.719165766937657, y: 56.07028701581465)
    boatRoute.addPointWith(x: -2.713672613777817, y: 56.070574465681325)
    boatRoute.addPointWith(x: -2.7093810878716917, y: 56.07095772883556)
    boatRoute.addPointWith(x: -2.7044029178205866, y: 56.07153261642126)
    boatRoute.addPointWith(x: -2.698223120515766, y: 56.072394931722265)
    boatRoute.addPointWith(x: -2.6923866452834355, y: 56.07325722773041)
    boatRoute.addPointWith(x: -2.68672183108735, y: 56.07335303720707)
    boatRoute.addPointWith(x: -2.6812286779275096, y: 56.07354465544585)
    boatRoute.addPointWith(x: -2.6764221689126497, y: 56.074215311778964)
    boatRoute.addPointWith(x: -2.6698990495353394, y: 56.07488595644139)
    boatRoute.addPointWith(x: -2.6647492184479886, y: 56.075748196715914)
    boatRoute.addPointWith(x: -2.659427726324393, y: 56.076131408423215)
    boatRoute.addPointWith(x: -2.654792878345778, y: 56.07622721075461)
    boatRoute.addPointWith(x: -2.651359657620878, y: 56.076514616319784)
    boatRoute.addPointWith(x: -2.6477547758597324, y: 56.07708942101955)
    boatRoute.addPointWith(x: -2.6450081992798125, y: 56.07814320736718)
    boatRoute.addPointWith(x: -2.6432915889173625, y: 56.08025069360931)
    boatRoute.addPointWith(x: -2.638656740938747, y: 56.08044227755186)
    boatRoute.addPointWith(x: -2.636940130576297, y: 56.078813783674946)
    boatRoute.addPointWith(x: -2.636425147467562, y: 56.07728102068079)
    boatRoute.addPointWith(x: -2.637798435757522, y: 56.076610417698504)
    boatRoute.addPointWith(x: -2.638656740938747, y: 56.07507756705851)
    boatRoute.addPointWith(x: -2.641231656482422, y: 56.07479015077557)
    boatRoute.addPointWith(x: -2.6427766058086277, y: 56.075748196715914)
    boatRoute.addPointWith(x: -2.6456948434247924, y: 56.07546078543464)
    boatRoute.addPointWith(x: -2.647239792750997, y: 56.074598538729404)
    boatRoute.addPointWith(x: -2.6492997251859376, y: 56.072682365868616)
    boatRoute.addPointWith(x: -2.6530762679833284, y: 56.0718200569986)
    boatRoute.addPointWith(x: -2.655479522490758, y: 56.070861913404286)
    boatRoute.addPointWith(x: -2.6587410821794135, y: 56.07047864929729)
    boatRoute.addPointWith(x: -2.6633759301580286, y: 56.07028701581465)
    boatRoute.addPointWith(x: -2.666637489846684, y: 56.07009538137926)
    boatRoute.addPointWith(x: -2.670070710571584, y: 56.06990374599109)
    boatRoute.addPointWith(x: -2.6741905754414645, y: 56.069137194910745)
    boatRoute.addPointWith(x: -2.678310440311345, y: 56.06808316228391)
    boatRoute.addPointWith(x: -2.682086983108735, y: 56.06789151689155)
    boatRoute.addPointWith(x: -2.6868934921235956, y: 56.06760404701653)
    boatRoute.addPointWith(x: -2.6911850180297208, y: 56.06722075051504)
    boatRoute.addPointWith(x: -2.695133221863356, y: 56.06702910083509)
    boatRoute.addPointWith(x: -2.698223120515766, y: 56.066837450202335)
    boatRoute.addPointWith(x: -2.7016563412406667, y: 56.06645414607839)
    boatRoute.addPointWith(x: -2.7061195281830366, y: 56.0660708381432)
    boatRoute.addPointWith(x: -2.7100677320166717, y: 56.065591697864576)
    boatRoute.addPointWith(x: -2.713329291705327, y: 56.06520838135397)
    boatRoute.addPointWith(x: -2.7167625124302273, y: 56.06453756828941)
    boatRoute.addPointWith(x: -2.718307461756433, y: 56.06348340989081)
    boatRoute.addPointWith(x: -2.719165766937657, y: 56.062812566811544)
    boatRoute.addPointWith(x: -2.7198524110826376, y: 56.06204587471371)
    boatRoute.addPointWith(x: -2.719165766937657, y: 56.06166252294756)
    boatRoute.addPointWith(x: -2.718307461756433, y: 56.06147084563517)

    For more information on drawing lines using the geometry API, see Geometries.

  2. Define the symbol for the boat trip using the AGSSimpleLineSymbol class.

    The code below defines this as a purple dashed line.

    //define a line symbol
    let lineSymbol = AGSSimpleLineSymbol(style: .dash, color: UIColor(red: 0.5, green: 0, blue: 0.5, alpha: 1), width: 4)

  3. Create the graphic from the line geometry and line symbol.

    //create the graphic
    let boatTripGraphic = AGSGraphic(geometry: boatRoute.toGeometry(), symbol: lineSymbol)

  4. Add the graphic to the graphics overlay.

    graphicsOverlay.graphics.add(boatTripGraphic)

Add polygon graphics

The following steps show how to create the polygon representing the nesting ground area in the image near the top of this topic.

  1. The geometry for the nesting ground is defined using the AGSPolygon class. The vertices of the polygon are created from a collection of points. For more information on building polygons, see Geometries.

    let nestingGround = AGSPolygonBuilder(spatialReference: .wgs84())
    //add points to the point collection
    nestingGround.addPointWith(x: -2.643077012566659, y: 56.077125346044475)
    nestingGround.addPointWith(x: -2.6428195210159444, y: 56.07717324600376)
    nestingGround.addPointWith(x: -2.6425405718360033, y: 56.07774804087097)
    nestingGround.addPointWith(x: -2.6427122328698127, y: 56.077927662508635)
    nestingGround.addPointWith(x: -2.642454741319098, y: 56.07829887790651)
    nestingGround.addPointWith(x: -2.641853927700763, y: 56.078526395253725)
    nestingGround.addPointWith(x: -2.6409741649024867, y: 56.078801809192434)
    nestingGround.addPointWith(x: -2.6399871139580795, y: 56.07881378366685)
    nestingGround.addPointWith(x: -2.6394077579689705, y: 56.07908919555142)
    nestingGround.addPointWith(x: -2.638764029092183, y: 56.07917301616904)
    nestingGround.addPointWith(x: -2.638485079912242, y: 56.07896945149566)
    nestingGround.addPointWith(x: -2.638570910429147, y: 56.078203080726844)
    nestingGround.addPointWith(x: -2.63878548672141, y: 56.077568418396)
    nestingGround.addPointWith(x: -2.6391931816767085, y: 56.077197195961084)
    nestingGround.addPointWith(x: -2.6399441986996273, y: 56.07675411934114)
    nestingGround.addPointWith(x: -2.6406523004640934, y: 56.076730169108444)
    nestingGround.addPointWith(x: -2.6406737580933193, y: 56.07632301287509)
    nestingGround.addPointWith(x: -2.6401802326211157, y: 56.075999679860494)
    nestingGround.addPointWith(x: -2.6402446055087943, y: 56.075844000034046)
    nestingGround.addPointWith(x: -2.640416266542604, y: 56.07578412301025)
    nestingGround.addPointWith(x: -2.6408883343855822, y: 56.075808073830935)
    nestingGround.addPointWith(x: -2.6417680971838577, y: 56.076239186057734)
    nestingGround.addPointWith(x: -2.642197249768383, y: 56.076251161328514)
    nestingGround.addPointWith(x: -2.6428409786451708, y: 56.07661041772168)
    nestingGround.addPointWith(x: -2.643077012566659, y: 56.077125346044475)

  2. Define a symbol for the polygon. The symbol in the screen shot above is made up of a line symbol for the outline and a fill symbol for the polygon fill.

    //define the fill symbol and outline
    let outlineSymbol = AGSSimpleLineSymbol(style: .dash,
        color: UIColor(red: 0, green: 0, blue: 0.5, alpha: 1),
        width: 1)
    
    let fillSymbol = AGSSimpleFillSymbol(style: .diagonalCross,
        color: UIColor(red: 0, green: 80/255.0, blue: 0, alpha: 1),
        outline: outlineSymbol)

  3. Create the graphic from the polygon geometry and fill symbol.

    let nestingGraphic = AGSGraphic(geometry: nestingGround.toGeometry(), symbol: fillSymbol)

  4. Add the polygon graphic to the graphics overlay.

    graphicsOverlay.graphics.add(nestingGraphic)

Add text

The following steps show how to add the "Craigleith" and "Bass Rock" text to the graphics overlay.

  1. The geometry for text symbols is a point. The point represents the anchor point for the text. The following code defines the anchor points for the two text symbols in the image at the top of this topic.

    let bassLocation = AGSPoint(x: -2.640631, y: 56.078083, spatialReference: .wgs84())
    let craigleithLocation = AGSPoint(x: -2.720324, y: 56.073569, spatialReference: .wgs84())

  2. Create the symbols for the text items.

    //create text symbols
    let bassRockSymbol = AGSTextSymbol(text: "Bass Rock",
        color: UIColor(red: 0, green: 0, blue: 230/255.0, alpha: 1),
        size: 10,
        horizontalAlignment: .left,
        verticalAlignment: .bottom)
    let craigleithSymbol = AGSTextSymbol(text: "Craigleith",
        color: UIColor(red: 0, green: 0, blue: 230/255.0, alpha: 1),
        size: 10,
        horizontalAlignment: .right,
        verticalAlignment: .top)

  3. Create the graphics from the point and text symbol.

    let bassRockGraphic = AGSGraphic(geometry: bassLocation, symbol: bassRockSymbol)
    let craigleithGraphic = AGSGraphic(geometry: craigleithLocation, symbol: craigleithSymbol)

  4. Add the text graphics to the graphics overlays.

    //add the text to the graphics overlay
    graphicsOverlay.graphics.add(bassRockGraphic)
    graphicsOverlay.graphics.add(craigleithGraphic)

Identify graphics

In your app, you can add code to allow users to click on a graphic and get more information about it. For example, you may tap or click on a seabird in your graphics overlay to display the name of the bird's species in a dialog box.

The identifyGraphicsOverlay method on the map view allows you identify graphics at a point on the map for a given graphics overlay. If you have more than one graphics overlay and want to perform an identify operation on all graphics overlays, use the identifyGraphicsOverlays method. The example below shows how you can perform an identify on a single graphics overlay in response to a tap on the map view.

//create a new point a little north of the original position
let originalPosition = bassRockGraphic.geometry as! AGSPoint
let newPosition = AGSPoint(x:originalPosition.x, y: originalPosition.y + 0.1, spatialReference: .wgs84())
//update with the new geometry
bassRockGraphic.geometry = newPosition

You can iterate through each result returned from an identify. For example, you can display a list of the attribute values from each result.

Select graphics

Selecting a graphic is a way of bringing it to the attention of a user by drawing a halo around it. Change the selection state of a graphic by using the AGSGraphic class.

Screenshot of selected graphic

Update graphics

It's possible to update the geometry or attributes of a graphic by using the graphics collection of the graphics overlay.

graphicsOverlay.graphics.remove(bassRockGraphic)

Remove graphics

To remove graphics you work with the graphics collection and call the removeObject method.

//identify graphics at the tapped location
self.mapView.identify(self.graphicsOverlay, screenPoint: screenPoint, tolerance: 44, returnPopupsOnly: false, maximumResults: 10) { (identifyResult: AGSIdentifyGraphicsOverlayResult) -> Void in
    if let error = identifyResult.error {
        print(error.localizedDescription)
        return
    }
    //if a graphics is found then show an alert
    for graphic in (identifyResult.graphics) {
        print(graphic.attributes.value(forKey: "SEABIRD")!)
    }
}