> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/ios/ja/maps/llms.txt)

# Join data to vector geometry

![Join local JSON data with vector tile geometries.](https://docs.mapbox.com/ios/ja/assets/ideal-img/maps-examples-data-join.344180d.480.png)

This example demonstrates a client-side data join to assign properties to spacial data, creating a choropleth map of the Human Development Index (HDI) score of each country in Europe using the **Mapbox Maps SDK for iOS**.

The countries on the map are colored various shades of green, where a lighter shade of green indicates a higher HDI score.

In the code below, the HDI values are hard coded, while the boundaries of the countries are imported in a [`VectorSource`](https://docs.mapbox.com/ios/maps/api/latest/documentation/mapboxmaps/vectorsource/). The boundaries are matched with their respective HDI scores through a GL match expression and the results are then applied to a [`FillLayer`](https://docs.mapbox.com/ios/ja/maps/guides/styles/work-with-layers/#fill-layer), which colors the country polygons on the [`MapView`](https://docs.mapbox.com/ios/maps/api/latest/documentation/mapboxmaps/mapview/).

> **Note: iOS Examples App Available**
> 
> This example code is part of the **Maps SDK for iOS Examples App**, a working iOS project [available on Github](https://github.com/mapbox/mapbox-maps-ios/tree/11.33.0/Sources/Examples). iOS developers are encouraged to run the examples app locally to interact with this example in an emulator and explore other features of the Maps SDK.
> 
> See our [Run the Maps SDK for iOS Examples App](https://docs.mapbox.com/help/tutorials/maps-sdk-ios-examples-app/) tutorial for step-by-step instructions.

**Swift**

Title: `DataJoinExample.swift`

[View on GitHub](https://github.com/mapbox/mapbox-maps-ios/blob/main/Sources/Examples/All%20Examples/DataJoinExample.swift)

```swift
import MapboxMaps
import UIKit

final class ViewController: UIViewController {
    private var mapView: MapView!
    private var cancelables = Set<AnyCancelable>()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Set up map and camera
        let centerCoordinate = CLLocationCoordinate2D(latitude: 50, longitude: 12)
        let camera = CameraOptions(center: centerCoordinate, zoom: 1.6)
        let mapInitOptions = MapInitOptions(cameraOptions: camera)

        mapView = MapView(frame: view.bounds, mapInitOptions: mapInitOptions)
        mapView.mapboxMap.mapStyle = .standard(theme: .monochrome)
        mapView.autoresizingMask = [.flexibleHeight, .flexibleWidth]

        view.addSubview(mapView)

        // Add the data layer once the map has finished loading.
        mapView.mapboxMap.onMapLoaded.observeNext { _ in
            self.addJSONDataLayer()

            
            
        }.store(in: &cancelables)
    }

    func addJSONDataLayer() {
        // Create an array of countries and their HDI score
        // Data: UN Human Development Index 2017 Europe extract
        // Source: https://ourworldindata.org/human-development-index
        struct Country {
            let code: String
            let hdi: Double
        }

        let countries = [Country(code: "ROU", hdi: 0.811),
                        Country(code: "RUS", hdi: 0.816),
                        Country(code: "SRB", hdi: 0.787 ),
                        Country(code: "SVK", hdi: 0.855 ),
                        Country(code: "SVN", hdi: 0.896 ),
                        Country(code: "ESP", hdi: 0.891 ),
                        Country(code: "SWE", hdi: 0.933 ),
                        Country(code: "CHE", hdi: 0.944 ),
                        Country(code: "HRV", hdi: 0.831 ),
                        Country(code: "CZE", hdi: 0.888 ),
                        Country(code: "DNK", hdi: 0.929 ),
                        Country(code: "EST", hdi: 0.871 ),
                        Country(code: "FIN", hdi: 0.92 ),
                        Country(code: "FRA", hdi: 0.901 ),
                        Country(code: "DEU", hdi: 0.936 ),
                        Country(code: "GRC", hdi: 0.87 ),
                        Country(code: "ALB", hdi: 0.785 ),
                        Country(code: "AND", hdi: 0.858 ),
                        Country(code: "AUT", hdi: 0.908 ),
                        Country(code: "BLR", hdi: 0.808 ),
                        Country(code: "BEL", hdi: 0.916 ),
                        Country(code: "BIH", hdi: 0.768 ),
                        Country(code: "BGR", hdi: 0.813 ),
                        Country(code: "MKD", hdi: 0.757 ),
                        Country(code: "MLT", hdi: 0.878 ),
                        Country(code: "MDA", hdi: 0.7 ),
                        Country(code: "MNE", hdi: 0.814 ),
                        Country(code: "NLD", hdi: 0.931 ),
                        Country(code: "NOR", hdi: 0.953 ),
                        Country(code: "POL", hdi: 0.865 ),
                        Country(code: "PRT", hdi: 0.847 ),
                        Country(code: "HUN", hdi: 0.838 ),
                        Country(code: "ISL", hdi: 0.935 ),
                        Country(code: "IRL", hdi: 0.938 ),
                        Country(code: "ITA", hdi: 0.88 ),
                        Country(code: "LVA", hdi: 0.847 ),
                        Country(code: "LIE", hdi: 0.916 ),
                        Country(code: "LTU", hdi: 0.858 ),
                        Country(code: "LUX", hdi: 0.904 ),
                        Country(code: "UKR", hdi: 0.751 ),
                        Country(code: "GBR", hdi: 0.922 )]

        // Create the source for country polygons using the Mapbox Countries tileset
        // The polygons contain an ISO 3166 alpha-3 code which can be used to for joining the data
        // https://docs.mapbox.com/vector-tiles/reference/mapbox-countries-v1
        var source = VectorSource(id: "countries")
        source.url = "mapbox://mapbox.country-boundaries-v1"

        // Add layer from the vector tile source to create the choropleth
        var layer = FillLayer(id: "countries", source: source.id)
        layer.sourceLayer = "country_boundaries"
        layer.slot = .middle

        // Build a GL match expression that defines the color for every vector tile feature
        // https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions/#match
        // Use the ISO 3166-1 alpha 3 code as the lookup key for the country shape
        let expressionHeader =
            """
            [
            "match",
            ["get", "iso_3166_1_alpha_3"],

            """

        // Calculate color values for each country based on 'hdi' value
        var green: Double
        var expressionBody: String = ""
        for country in countries {
            // Convert the range of data values to a suitable color
            green = country.hdi*255
            expressionBody += """
            "\(country.code)",
            "rgb(0, \(green), 0)",

            """
        }

        // Last value is the default, used where there is no data
        let expressionFooter =
            """
            "rgba(0, 0, 0, 0)"
            ]
            """

        // Combine the expression strings into a single JSON expression
        // You can alternatively translate JSON expressions into Swift: https://docs.mapbox.com/ios/maps/guides/styles/use-expressions/
        let jsonExpression = expressionHeader + expressionBody + expressionFooter

        // Add the source
        // Insert the vector layer below the 'admin-1-boundary-bg' layer in the style
        // Join data to the vector layer
        do {
            try mapView.mapboxMap.addSource(source)
            try mapView.mapboxMap.addLayer(layer)
            if let expressionData = jsonExpression.data(using: .utf8) {
                let expJSONObject = try JSONSerialization.jsonObject(with: expressionData, options: [])
                try mapView.mapboxMap.setLayerProperty(for: "countries",
                                                           property: "fill-color",
                                                           value: expJSONObject)
            }
        } catch {
            print("Failed to add the data layer. Error: \(error.localizedDescription)")
        }
    }
}
```