Style vector tiles

Learn how to perform data-driven styling to customize the appearance of vector tiles based on their underlying feature data.

You can use MapLibre GL JS to display vector tile data using custom styles. The MapLibre style specification allows you to customize the fill, outline, opacity and other properties of vector tiles to display data effectively. If your vector tiles are published from a feature service, you can also perform data-driven visualizations based on attributes of the original feature service.

In this tutorial, you style land parcels from a public vector tile service according to their use type.

Prerequisites

You need an ArcGIS Developer or ArcGIS Online account to access the developer dashboard and create an API key.

Steps

Review the source data

This tutorial uses the Santa Monica Mountains Parcels vector tile service. This vector tile service was created by publishing a feature service as vector tiles using ArcGIS.com. It contains the attributes of the original feature service, which can be accessed to style layers in your application. Find the original feature service in ArcGIS.com to view the names and values of different attributes.

  1. Go to the item page for the Santa Monica Mountains Parcels vector tile layer.

  2. Under Details, find the Created from property. Follow the link to view the item page for the original feature layer, Santa_Monica_Mountains_Parcels.

  3. Click the Data tab to view the layer's features and attributes. Each feature represents a land parcel and has attributes such as an address, use code, and number of square feet.

  4. Review the values of the UseType field. You will use this field to style vector tiles in your application.

Create a new pen

  1. To get started, either complete the Display a map tutorial or .

Set the API key

To access location services, you need an API key or OAuth 2.0 access token. To learn how to create and scope your key, visit the Create an API key tutorial.

  1. Go to your dashboard to get an API key. The API key must be scoped to access the services used in this tutorial.

  2. In CodePen, update apiKey to use your key.

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    const apiKey = "YOUR_API_KEY";
    const basemapEnum = "arcgis/streets";
    const map = new maplibregl.Map({
      container: "map", // the id of the div element
      style: `https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/styles/${basemapEnum}?token=${apiKey}`,
      zoom: 12, // starting zoom
      center: [-118.805, 34.027] // starting location [longitude, latitude]
    });
    

Add a vector tile source

Use a source of type vector to reference the Santa Monica Mountains Parcels vector tile service in your application.

  1. Add an event handler to the map load event.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
      <script>
        const apiKey = "YOUR_API_KEY";
        const basemapEnum = "ArcGIS:HumanGeography";
        const map = new maplibregl.Map({
          container: "map", // the id of the div element
          style: `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/${basemapEnum}?type=style&token=${apiKey}`,
          zoom: 13, // starting zoom
          center: [-118.4877, 34.0227] // starting location [longitude, latitude]
        });
    
        map.once("load", () => {
    
        });
    
      </script>
    
    Expand
  2. Inside the load event handler, add a vector tile source with id parcels. The source tells MapLibre GL JS how to access the data for the layer, but does not visually add it to the map.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
        map.once("load", () => {
    
          map.addSource("parcels", {
            type: "vector",
            tiles: [
              "https://vectortileservices3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Santa_Monica_Mountains_Parcels_VTL/VectorTileServer/tile/{z}/{y}/{x}.pbf"
            ]
          });
    
        });
    
    Expand

Style parcels by use type

Use a layer of type fill to style land parcels according to their UseType category.

  1. Add a fill layer that references the parcels source you created. Set source-layer to Santa_Monica_Mountains_Parcels to reference the original feature service.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
        map.once("load", () => {
    
          map.addSource("parcels", {
            type: "vector",
            tiles: [
              "https://vectortileservices3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Santa_Monica_Mountains_Parcels_VTL/VectorTileServer/tile/{z}/{y}/{x}.pbf"
            ]
          });
    
          map.addLayer({
            id: "parcels-fill",
            type: "fill",
            source: "parcels",
            "source-layer": "Santa_Monica_Mountains_Parcels",
    
          });
    
        });
    
    Expand
  2. Add a custom fill-color to the layer. Use get to retrieve UseType attribute values, viewed in the previous step. Use case to create a conditional expression that assigns a unique color to each use type.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
          map.addLayer({
            id: "parcels-fill",
            type: "fill",
            source: "parcels",
            "source-layer": "Santa_Monica_Mountains_Parcels",
    
            paint: {
                "fill-color": ['case',
                    ['==', ['get','UseType'], 'Residential'], '#E8E191', // Yellow
                    ['==', ['get','UseType'], 'Commercial'], '#E580A2', // Red
                    ['==', ['get','UseType'], 'Government'], '#79E284', // Green
                    ['==', ['get','UseType'], 'Industrial'], '#C080E5', // Purple
                    ['==', ['get','UseType'], 'Institutional'], '#80BBE5', // Blue
                    '#bfbfbf'
                ]
            }
    
          });
    
    Expand

Add an outline layer

The MapLibre style specification has limited options for customizing polygon outlines. Add a second vector tile layer to customize the parcel outlines.

  1. Add a line layer that also references the parcels source. Style the color, width, and opacity of the parcel outlines.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
            paint: {
                "fill-color": ['case',
                    ['==', ['get','UseType'], 'Residential'], '#E8E191', // Yellow
                    ['==', ['get','UseType'], 'Commercial'], '#E580A2', // Red
                    ['==', ['get','UseType'], 'Government'], '#79E284', // Green
                    ['==', ['get','UseType'], 'Industrial'], '#C080E5', // Purple
                    ['==', ['get','UseType'], 'Institutional'], '#80BBE5', // Blue
                    '#bfbfbf'
                ]
            }
    
          });
    
          map.addLayer({
            id: "parcels-outline",
            type: "line",
            source: "parcels",
            "source-layer": "Santa_Monica_Mountains_Parcels",
            paint: {
                'line-color':'#000000',
                'line-width':0.25,
                'line-opacity':0.25
            }
          });
    
    
    Expand
  2. Use moveLayer to display the outline layer on top of the fill layer.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
            paint: {
                "fill-color": ['case',
                    ['==', ['get','UseType'], 'Residential'], '#E8E191', // Yellow
                    ['==', ['get','UseType'], 'Commercial'], '#E580A2', // Red
                    ['==', ['get','UseType'], 'Government'], '#79E284', // Green
                    ['==', ['get','UseType'], 'Industrial'], '#C080E5', // Purple
                    ['==', ['get','UseType'], 'Institutional'], '#80BBE5', // Blue
                    '#bfbfbf'
                ]
            }
    
          });
    
          map.addLayer({
            id: "parcels-outline",
            type: "line",
            source: "parcels",
            "source-layer": "Santa_Monica_Mountains_Parcels",
            paint: {
                'line-color':'#000000',
                'line-width':0.25,
                'line-opacity':0.25
            }
          });
    
          map.moveLayer('parcels-outline');
    
    Expand

Run the app

In CodePen, run your code to display the map.

You should see the styled vector tile layer with parcels displayed on the basemap layer. Parcels shouold be styled in different colors based on their use type, and thin outlines should be present around each parcel.

What's next?

Learn how to use additional ArcGIS location services in these tutorials:

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.