# MGLFeature

    @protocol MGLFeature <MGLAnnotation>

The `MGLFeature` protocol is used to provide details about geographic features contained in an `MGLShapeSource` or `MGLVectorTileSource` object. Each concrete subclass of `MGLShape` in turn has a subclass that conforms to this protocol. A feature object associates a shape with an optional identifier and attributes.

You can add custom data to display on the map by creating feature objects and adding them to an `MGLShapeSource` using the `-[MGLShapeSource initWithIdentifier:shape:options:]` method or `MGLShapeSource.shape` property.

In addition to adding data to the map, you can also extract data from the map: `-[MGLMapView visibleFeaturesAtPoint:]` and related methods return feature objects that correspond to features in the source. This enables you to inspect the properties of features in vector tiles loaded by `MGLVectorTileSource` objects. You also reuse these feature objects as overlay annotations.

While it is possible to add `MGLFeature`-conforming objects to the map as annotations using `-[MGLMapView addAnnotations:]` and related methods, doing so has trade-offs:

- Features added as annotations will not have `identifier` or `attributes` properties when used with feature querying.

- Features added as annotations become interactive. Taps and selection can be handled in `-[MGLMapViewDelegate mapView:didSelectAnnotation:]`.

- `identifier`

  An object that uniquely identifies the feature in its containing content source.

  You can configure an `MGLVectorStyleLayer` object to include or exclude a specific feature in an `MGLShapeSource` or `MGLVectorTileSource`. In the `MGLVectorStyleLayer.predicate` property, compare the special `$id` attribute to the feature’s identifier.

  In vector tiles loaded by `MGLVectorTileSource` objects, the identifier corresponds to the feature identifier (`id`). If the source does not specify the feature’s identifier, the value of this property is `nil`. If specified, the identifier may be an integer, floating-point number, or string. These data types are mapped to instances of the following Foundation classes:

  In the tile source | This property
  --- | ---
  Integer | `NSNumber` (use the `unsignedLongLongValue` or `longLongValue` property)
  Floating-point number | `NSNumber` (use the `doubleValue` property)
  String | `NSString`

  For details about the identifiers used in most Mapbox-provided styles, consult the Mapbox Streets layer reference.

  The identifier should be set before adding the feature to an `MGLShapeSource` object; setting it afterwards has no effect on the map’s contents. While it is possible to change this value on feature instances obtained from `-[MGLMapView visibleFeaturesAtPoint:]` and related methods, doing so likewise has no effect on the map’s contents.

  #### Declaration

  Objective-C

      @property (readwrite, copy, nonatomic, nullable) id identifier;

  Swift

      var identifier: Any? { get set }

  View Source on GitHub
- `attributes`

  A dictionary of attributes for this feature.

  You can configure an `MGLVectorStyleLayer` object to include or exclude a specific feature in an `MGLShapeSource` or `MGLVectorTileSource`. In the `MGLVectorStyleLayer.predicate` property, compare a key of the attribute dictionary to the value you want to include. For example, if you want an `MGLLineStyleLayer` object to display only important features, you might assign a value above 50 to the important features’ `importance` attribute, then set `MGLVectorStyleLayer.predicate` to an `NSPredicate` with the format `importance > 50`.

  You can also configure many layout and paint attributes of an `MGLStyleLayer` object to match the value of an attribute in this dictionary whenever it renders this feature. For example, if you display features in an `MGLShapeSource` using an `MGLCircleStyleLayer`, you can assign a `halfway` attribute to each of the source’s features, then set `MGLCircleStyleLayer.circleRadius` to an `MGLStyleValue` object with an interpolation mode of `MGLInterpolationModeIdentity` and an attribute name of `halfway`.

  The `MGLSymbolStyleLayer.textField` and `MGLSymbolStyleLayer.iconImageName` properties allow you to use attributes yet another way. For example, to label features in an `MGLShapeSource` object by their names, you can assign a `name` attribute to each of the source’s features, then set `MGLSymbolStyleLayer.textField` to an `MGLStyleValue` object containing the raw string value `{name}`.

  In vector tiles loaded by `MGLVectorTileSource` objects, the keys and values of each feature’s attribute dictionary are determined by the source. Each attribute name is a string, while each attribute value may be a null value, Boolean value, integer, floating-point number, or string. These data types are mapped to instances of the following Foundation classes:

  In the tile source | In this dictionary
  --- | ---
  Null | `NSNull`
  Boolean | `NSNumber` (use the `boolValue` property)
  Integer | `NSNumber` (use the `unsignedLongLongValue` or `longLongValue` property)
  Floating-point number | `NSNumber` (use the `doubleValue` property)
  String | `NSString`

  For details about the attribute names and values found in Mapbox-provided vector tile sources, consult the Mapbox Streets and Mapbox Terrain layer references.

  When adding a feature to an `MGLShapeSource`, use the same Foundation types listed above for each attribute value. In addition to the Foundation types, you may also set an attribute to an `NSColor` (macOS) or `UIColor` (iOS), which will be converted into its CSS string representation when the feature is added to an `MGLShapeSource`. This can be convenient when using the attribute to supply a value for a color-typed layout or paint attribute via the `MGLInterpolationModeIdentity` interpolation mode.

  Note that while it is possible to change this value on feature instances obtained from `-[MGLMapView visibleFeaturesAtPoint:]` and related methods, there will be no effect on the map. Setting this value can be useful when the feature instance is used to initialize an `MGLShapeSource` and that source is added to the map and styled.

  #### Declaration

  Objective-C

      @property (readwrite, copy, nonatomic)
          NSDictionary<NSString *, id> *_Nonnull attributes;

  Swift

      var attributes: [String : Any] { get set }

  View Source on GitHub
- `-attributeForKey:`

  Returns the feature attribute for the given attribute name.

  See the `attributes` property’s documentation for details on keys and values associated with this method.

  #### Declaration

  Objective-C

      - (nullable id)attributeForKey:(nonnull NSString *)key;

  Swift

      func attribute(forKey key: String) -> Any?

  View Source on GitHub
- `-geoJSONDictionary`

  Returns a dictionary that can be serialized as a GeoJSON Feature representation of an instance of an `MGLFeature` subclass.

  The dictionary includes a `geometry` key corresponding to the receiver’s underlying geometry data, a `properties` key corresponding to the receiver’s `attributes` property, and an `id` key corresponding to the receiver’s `identifier` property.

  #### Declaration

  Objective-C

      - (nonnull NSDictionary<NSString *, id> *)geoJSONDictionary;

  Swift

      func geoJSONDictionary() -> [String : Any]

  View Source on GitHub