Style layers
While Annotations and View Annotations provide a convenient way to add elements to a map, there may be cases where you want to add many elements or have greater control. In such cases, Style Layers offer a more performant approach to displaying these map elements.
Benefits:
- Style Layers are more efficient and performant, especially when dealing with a large number of features on the map from
vector
orgeojson
sources. - Style Layers offer extensive customization options, allowing developers to precisely control the appearance of map elements. This includes options such as the color, opacity, size and many other visual attributes listed in the Layers section of the Mapbox Style Spec.
Limitations:
- No default image available. You will need to provide your own image in Xcode and pass a reference of the file to the Mapbox SDK.
- Style Layers require a developer to learn specific Mapbox APIs and usage patterns associated with Layers. In contrast, Annotations and View Annotations use higher-level abstractions.
- Using the lower-level APIs of Style Layers may take more time, especially if you are new to the Maps SDK or mapping technologies.
- To achieve more sophisticated data-driven styling, developers will need to learn how to use Mapbox Expressions to control the appearance of map features based on the underlying data. This adds complexity to the development process.
This guide covers the basics of adding your own data to a map using sources and layers. To learn more about working with sources and layers, see the full guide:
See the full guide on working with sources and layers in the Maps SDK for iOS.
Add your data as a source
Before you can add a Style Layer, you need to add a data source to the map. Sources provide the geographic data that the Style Layer will render. The most commonly used source types are vector
and geojson
sources, each requiring different data formats and handling.
vector
sources
Vector sources retrieve data from a server in the form of vector tiles, or chunks of geographic data representing small areas of the earth's surface. Using vector tiles means you don't have to load all the data at once, which is ideal for large datasets that cover wide geographic areas.
To add your own data as a vector source, you must first process the data into a vector tileset. There are several options available for creating and hosting vector tilesets:
- Use Mapbox's Data manager to upload data and generate vector tiles using an intuitive graphical user interface.
- Use Mapbox Tiling Service (MTS) to build a data pipeline for continuous updates to a vector tileset from source data.
- Use third party tools to create vector tiles from your source data and host them on your own infrastructure.
Vector tilesets hosted on your Mapbox account are accessible using the tileset URL following the format mapbox://username.tilesetid
.
The following snippet shows how to add a Mapbox-hosted vector source to the SwiftUI Map
or by using addSource
for UIKit.
Map {
// Add a vector source
VectorSource(id: "vector-source")
.url("mapbox://your-tileset-id")
// now you can add a layer to use this source
}
// Create a vector source
var vectorSource = VectorSource(id: "vector-source")
vectorSource.url = "mapbox://your-tileset-id"
// Add the source to the map
try! mapView.mapboxMap.addSource(vectorSource)
// now you can add a layer to use this source
geojson
sources
geojson
sources contain the same type of data as vector sources, but the data is loaded from a GeoJSON string or file. This allows for more flexibility as developers can change and host GeoJSON data without needing to regenerate and serve vector tiles.
A limitation of geojson
sources is that they may not perform as well as vector tiles when rendering large datasets, as the entire dataset must be added to the map at once regardless of what features are currently visible on the map's current location and zoom level.
Developers will often source data from a custom API endpoint that serves GeoJSON data live from a database, or they may use static GeoJSON files hosted on the web or bundled with their app.
Add ageojson
source from a URL
Map {
// Add a geojson source from a URL
GeoJSONSource(id: "geojson-source")
.data(.url(URL(string: "https://example.com/data.geojson")!))
// now you can add a layer to use this source
}
// Create a geojson source from a remote URL
guard let geoJSONURL = URL(string: "https://example.com/data.geojson") else {
fatalError("Invalid URL")
}
var geoJSONSource = GeoJSONSource(id: "geojson-source")
geoJSONSource.data = .url(geoJSONURL)
// Add the source to the map
try! mapView.mapboxMap.addSource(geoJSONSource)
// now you can add a layer to use this source
Add a geojson
source from a file in the app bundle
Map {
// Add a geojson source and circle layer from a file
GeoJSONSource(id: "geojson-source")
.data(.url(Bundle.main.url(forResource: "my-data", withExtension: "geojson")!))
// now you can add a layer to use this source
}
// Create a geojson source from a file in the app bundle
guard let geoJSONURL = Bundle.main.url(forResource: "my-data", withExtension: "geojson") else {
fatalError("Could not find data.geojson file")
}
var geoJSONSource = GeoJSONSource(id: "geojson-source")
geoJSONSource.data = .url(geoJSONURL)
// Add the source to the map
try! mapView.mapboxMap.addSource(geoJSONSource)
// now you can add a layer to use this source
Add a geojson
source from a string
Map {
// Add a geojson source and circle layer from a string
GeoJSONSource(id: "geojson-source")
.data(.string("""
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-74.0060, 40.7128]
},
"properties": {
"title": "New York City"
}
}
]
}
"""))
// now you can add a layer to use this source
}
// Create a GeoJSON source with inline data
let geoJSONString = """
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-74.0060, 40.7128]
},
"properties": {
"title": "New York City"
}
}
]
}
"""
var geoJSONSource = GeoJSONSource(id: "geojson-source")
geoJSONSource.data = .string(geoJSONString)
// Add the source to the map
try! mapView.mapboxMap.addSource(geoJSONSource)
// now you can add a layer to use this source
Other source types
For a complete list of source types supported by the Maps SDK for iOS, see the Work with sources and layers guide or consult the references listed below.
API reference documentation for adding sources using the Maps SDK.
View the reference docs for the Mapbox Style Specification to see details about each layer type and its properties.
Add layers that use your data sources
Once you have added a source to the map, you can add a Style Layer that uses that source to render features on the map.
For example, you can create a CircleLayer
to represent point data as circles on the map, or a SymbolLayer
to display icons or text. The following snippet shows how to add a CircleLayer
and a SymbolLayer
that uses a common source:
Map {
...
// a vector or geojson source with id "my-pointdata-source" must have been added to the map
CircleLayer(id: "circle-layer", source: "my-pointdata-source")
.circleColor(.blue)
.circleRadius(6)
SymbolLayer(id: "symbol-layer", source: "my-pointdata-source")
.iconImage(.constant(StyleImage("my-icon")))
.iconSize(.constant(1.5))
}
// a vector or geojson source with id "my-pointdata-source" must have been added to the map
...
// Create a circle layer
let circleLayer = CircleLayer(id: "circle-layer", source: "my-pointdata-source")
circleLayer.circleColor = .constant(StyleColor(.blue))
circleLayer.circleRadius = .constant(6)
// Create a symbol layer
let symbolLayer = SymbolLayer(id: "symbol-layer", source: "my-pointdata-source")
symbolLayer.iconImage = .constant(StyleImage("my-icon"))
symbolLayer.iconSize = .constant(1.5)
// Add the layers to the map
try! mapView.mapboxMap.addLayer(circleLayer)
try! mapView.mapboxMap.addLayer(symbolLayer)
Layer Types for vector
and geojson
sources
Layer types are defined in the Mapbox Style Specification and are used to render different types of data on the map. The most common layer types for showing data from vector
and geojson
sources are:
- Circle Layer: This layer is used to represent point data as circles on the map, useful for visualizing locations with minimal code and configuration.
- Line Layer: This layer is used to render lines on the map, often used to show routes, directions or paths.
- Fill Layer: This layer is used to fill a polygon with a color.
- Symbol Layer: This layer is used to render icons or text representing point locations on the map.
The layers each have their own set of properties and styling options, allowing you to customize the appearance of the map features. For example, you can set the color, opacity, size, and other visual attributes of each layer type.
For details and code snippets about all available layer types, see the Work with sources and layers guide, or browse the examples below.
Add a teardrop-shaped marker image to a style and display it on the map using a SymbolLayer
.
Add markers that use different icons using a SymbolLayer
.
Animate updates to a line layer from a geojson
source.
Each layer must specify a data source, which defines the geographic data that a layer will render.
Other layer types
For a complete list of layer types supported by the Maps SDK for iOS, see the Work with sources and layers guide or consult the references listed below.
API reference documentation for adding style layers using the Maps SDK.
View the reference docs for the Mapbox Style Specification to see details about each layer type and its properties.
Add your data to a custom style in Mapbox Studio
The concepts outlined above involve coding to add sources and layers to the map at runtime after the initial map style has been loaded. Using Mapbox Studio, you can create a custom style that combines your data sources and layers with basemap layers provided by Mapbox.
Adding your data to a custom style requires vector sources (GeoJSON sources are not supported in Mapbox Studio) and allows you to load the map in your application with your data already included and styled, simplifying your runtime code.
See our tutorials for more information on creating custom styles:
This tutorial will walk you through the process of adding custom data to a style that uses the Mapbox Standard basemap.