CARTO VL

This is a DEPRECATED VERSION of CARTO VL. You can find more information about the support and the availability of the different CARTO VL versions.

CARTO VL is a JavaScript library to create custom Location Intelligence applications over vector rendering.

This library is still under support but it will not be further developed. We don’t recommend starting new projects with it as it will eventually become deprecated. Instead, learn more about our current CARTO for deck.gl library here

Using data in your visualization with Sources

In this guide you will learn how to use different data sources for your CARTO VL visualizations. After practicing with it, you will be able to connect to your datasets in several ways, and you will know which is the better option for you.

This guide assumes that you have previously gone through the Getting Started Guide, so you already know how to make a simple map.

After practicing with this guide, you will be able to create this CARTO VL map:

How to get data

CARTO VL is a library that visualizes geographical datasets in a powerful and flexible way. Those datasets can be yours or they can be served by some other provider, but the first step to know is where they are hosted and how they can be accessed.

Our library currently supports these three options:

  • Dataset: a vector dataset hosted by CARTO and available with your credentials (for example, a dataset with all the stores in your city).
  • GeoJSON: a vector dataset in GeoJSON format.
  • SQL: a Dataset with a SQL query applied to it (e.g. just the stores with > 500 sq meters).

Every option is a different kind of Source, and CARTO VL provides you with a suitable object in its API to connect to them under the namespace carto.source (for example carto.source.Dataset).

Both Dataset and SQL are based in Vector Tiles, following Mapbox Vector Tile Specification or MVT. This is an advanced technology which allows transferring geographic data from the server to your browser in small chunks, allowing a good performance and a powerful dynamic styling.

In fact, there is a fourth type of source in CARTO VL called MVT but it is not meant to be used directly by the users, except in very precise / advanced cases.

Now you will see how to use the main three type of sources, but first let’s create a basic map.

You can start from this basemap. Go ahead and clone its source code into a new file called sources.html, we will wait for you…

To copy the source code from an example, you just have to navigate to it with your browser, click right button > View source and copy the whole text, from <html> to </html> tags.

You can then add a simple navigation control to warm up, just after the map creation:

1
2
const nav = new mapboxgl.NavigationControl();
map.addControl(nav, 'top-left');

Dataset

A Dataset can be managed using carto.source.Dataset. It is a source with information regarding to an specific topic (such as stores, streets or counties). If you have a GIS background, this is like a local vector file with points, lines or polygons, but hosted at CARTO. If you don’t, you can imagine it as a simple table at the server, with a geometry field you can map.

Add a Dataset

You already know how to add a Dataset thanks to Getting Started guide:

1
const aSource = new carto.source.Dataset('name_of_your_dataset');

That was using carto.setDefaultAuth method, but now you will see how to include custom credentials for an specific dataset. Add this to your current working file (sources.html if you followed our suggestion), just after map creation.

1
2
3
4
const citiesSource = new carto.source.Dataset('populated_places', {
    username: 'cartovl',
    apiKey: 'default_public'
});

As with any Source, you should then pass it to a Layer to visualize it, but first let’s create its Viz with a simple style:

1
2
3
4
const citiesViz = new carto.Viz(`
    color: grey
    width: 4
`);

Now you’re ready for the layer creation

1
const citiesLayer = new carto.Layer('cities', citiesSource, citiesViz);

It is a good practice to give them a short but clear name, like ‘cities’

And now you can add that layer to the map, so include this code:

1
citiesLayer.addTo(map);

The result should look like this:

When to use a Dataset?

You have a CARTO account, with several custom datasets, and you want to easily visualize one of them in a map, with all its rows.

GeoJSON

A GeoJSON can be used in CARTO VL with carto.source.GeoJSON. GeoJSON is an standard format to encode geographic data using JavaScript. It is indeed a common JSON, extended with spatial features, and you can easily create some .geojson contents online at geojson.io.

With the next steps, you’ll create a new layer with this format, in this case visualizing the main CARTO offices.

First you can include GeoJSON content and embed it directly in your JavaScript, like this:

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
const offices = {
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [-73.944158, 40.678178]
            },
            "properties": {
                "address": "Brooklyn, New York"
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [-3.70379, 40.416775]
            },
            "properties": {
                "address": "Madrid, Spain"
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [-0.127758, 51.507351]
            },
            "properties": {
                "address": "London, United Kingdom"
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [-77.036871, 38.907192]
            },
            "properties": {
                "address": "Washington, DC"
            }
        }
    ]
};

If your dataset is much bigger, you would probably store that content in an external file (see this External GeoJSON layer example).

And then use it within a GeoJSON source, like this:

1
const officesSource = new carto.source.GeoJSON(offices);

Create a custom style for the layer:

1
2
3
4
const officesViz = new carto.Viz(`
    color: red
    width: 20
`);

Define a map layer:

1
const officesLayer = new carto.Layer('offices', officesSource, officesViz);

And finally add that layer to the map:

1
officesLayer.addTo(map);

Now the map should look like this:

When to use a GeoJSON?

You already have your data in that format, and you currently don’t have access to a CARTO account (if you have, you should import it to get a better performance and more capabilities, and then use another type of Source). It can also be a useful format for some quick tests, using inline GeoJSON if you are managing just a few rows or a .geojson file just next to your .html.

SQL

SQL is a very common language to make queries in databases and geospatial software. It provides a flexible mechanism to adapt your dataset to your specific needs. Let’s use it now in your map!

Define query, to select just the biggest cities in the world

1
const query = 'SELECT * FROM populated_places WHERE megacity = 1';

This is a very simple query but the SQL runs on CARTO’s backend, which is powered by PostGIS, so you could also execute more sophisticated queries and even spatial analysis.

Create a SQL source:

1
2
3
4
const megacitiesSource = new carto.source.SQL(query, {
    username: 'cartovl',
    apiKey: 'default_public'
});

Define the new style:

1
const megacitiesViz = new carto.Viz('color: blue');

Create a common layer with those selected megacities:

1
const megacitiesLayer = new carto.Layer('megacities', megacitiesSource, megacitiesViz);

And finally add this layer to the map:

1
megacitiesLayer.addTo(map);

When to use SQL?

You have a CARTO account, with several custom datasets, and you want to visualize them in a layer, applying some kind of transformation to the source, from a simple filter to more advanced analysis.


All together

Congrats! You have finished this guide. The final map should look like this:

This is the complete code:

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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<!DOCTYPE html>
<html>

<head>
    <!-- Include CARTO VL JS -->
    <script src="../../../../dist/carto-vl.js"></script>
    <!-- Include Mapbox GL JS -->
    <script src="https://libs.cartocdn.com/mapbox-gl/v0.48.0-carto1/mapbox-gl.js"></script>
    <!-- Include Mapbox GL CSS -->
    <link href="https://libs.cartocdn.com/mapbox-gl/v0.48.0-carto1/mapbox-gl.css" rel="stylesheet" />
    <!-- Make the map visible -->
    <style>
        #map {
            position: absolute;
            height: 100%;
            width: 100%;
        }
    </style>
</head>

<body>
    <!-- Add map container -->
    <div id="map"></div>

    <script>
        // Add basemap and set properties
        const map = new mapboxgl.Map({
            container: 'map',
            style: carto.basemaps.voyager,
            center: [0, 30],
            zoom: 2
        });

        // Add zoom controls
        const nav = new mapboxgl.NavigationControl();
        map.addControl(nav, 'top-left');


        //** CARTO VL functionality begins here **//


        // DATASET
        // Define Dataset source with custom credentials
        const citiesSource = new carto.source.Dataset('populated_places', {
            username: 'cartovl',
            apiKey: 'default_public'
        });

        // Define Viz object with custom style
        const citiesViz = new carto.Viz(`
            color: grey
            width: 4
        `);

        // Define map Layer
        const citiesLayer = new carto.Layer('cities', citiesSource, citiesViz);

        // Add map Layer
        citiesLayer.addTo(map);


        // GEOJSON
        // Create GeoJSON content
        const offices = {
            "type": "FeatureCollection",
            "features": [
                {
                    "type": "Feature",
                    "geometry": {
                        "type": "Point",
                        "coordinates": [-73.944158, 40.678178]
                    },
                    "properties": {
                        "address": "Brooklyn, New York"
                    }
                },
                {
                    "type": "Feature",
                    "geometry": {
                        "type": "Point",
                        "coordinates": [-3.70379, 40.416775]
                    },
                    "properties": {
                        "address": "Madrid, Spain"
                    }
                },
                {
                    "type": "Feature",
                    "geometry": {
                        "type": "Point",
                        "coordinates": [-0.127758, 51.507351]
                    },
                    "properties": {
                        "address": "London, United Kingdom"
                    }
                },
                {
                    "type": "Feature",
                    "geometry": {
                        "type": "Point",
                        "coordinates": [-77.036871, 38.907192]
                    },
                    "properties": {
                        "address": "Washington, DC"
                    }
                }
            ]
        };

        // Define GeoJSON source
        const officesSource = new carto.source.GeoJSON(offices);

        // Define Viz object with custom style
        const officesViz = new carto.Viz(`
            color: red
            width: 20
        `);

        // Define map Layer
        const officesLayer = new carto.Layer('offices', officesSource, officesViz);

        // Add map Layer
        officesLayer.addTo(map);


        // SQL
        // Define query
        const query = 'SELECT * FROM populated_places WHERE megacity = 1';

        // Define SQL source with query and custom credentials
        const megacitiesSource = new carto.source.SQL(query, {
            username: 'cartovl',
            apiKey: 'default_public'
        });

        // Define Viz object with custom style
        const megacitiesViz = new carto.Viz('color: blue');

        // Define map Layer
        const megacitiesLayer = new carto.Layer('megacities', megacitiesSource, megacitiesViz);

        // Add map Layer
        megacitiesLayer.addTo(map);
    </script>
</body>

</html>