Simple MapLibre example showing polygons, lines and points from vector tiles
An example of a simple web map using MapLibre to display vector tiles as polygons, lines and points.
This page presents a simple web map using MapLibre to display vector tiles as polygons, lines and points.
For this example, we used several datasets provided by Ordnance Survey Ireland and hosted by ArcGIS here. The data has the tag "250K Map of Ireland" and so entering that tag into the search bar returns a list of datasets. We've downloaded the shapefiles for "Built Up Areas - National 250k Map Of Ireland" (polygons), "Rail Network - National 250k Map Of Ireland" (lines) and "Railway Stations - National 250k Map Of Ireland" (points).
After downloading and unzipping these files, we created vector tiles using File Tiler. We created tiles for zoom levels 2-14 for each set.
We start by creating a web map using the Clockwork Micro base map. We center it on Ireland and choose an appropriate zoom. We create a Map object using MapLibre and then add the Clockwork Micro base map as the style.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Polygon, Line, Point Example</title>
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<script src="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js"></script>
<link
href="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css"
rel="stylesheet"
/>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var cwmkey = "9G4F5b99xO28esL8tArIO2Bbp8sGhURW5qIieYTy";
var map = new maplibregl.Map({
container: "map", // Container ID
style: `https://maps.clockworkmicro.com/streets/v1/style?x-api-key=${cwmkey}`, // Note that we use backticks ` so that the variable is evaluated
center: [-8.25, 53],
zoom: 7,
});
</script>
</body>
</html>
Now, we add a layer to be added to the map object when the map loads. We add a source, which we name "built_source". These are the vector tiles for the polygons of built up areas in Ireland. The type is 'vector', and we provide a url in z/x/y format with the same key appended.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Polygon, Line, Point Example</title>
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<script src="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js"></script>
<link
href="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css"
rel="stylesheet"
/>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var cwmkey = "9G4F5b99xO28esL8tArIO2Bbp8sGhURW5qIieYTy";
var map = new maplibregl.Map({
container: "map", // container id
style: `https://maps.clockworkmicro.com/streets/v1/style?x-api-key=${cwmkey}`,
center: [-8.25, 53],
zoom: 7,
});
map.on("load", function () {
map.addSource("built_source", {
type: "vector",
tiles: [
`https://filetiler.clockworkmicro.com/tile/a14c29f8-ea55-49ef-ad9c-07f72de728ae/f5567795-ddb4-4800-9bf3-01a1d6786120/{z}/{x}/{y}.pbf?x-api-key=${cwmkey}`,
],
minzoom: 2,
maxzoom: 14,
});
map.addLayer({
id: "built_layer",
type: "fill",
source: "built_source",
"source-layer": "default",
paint: {
"fill-color": "#051AF0",
"fill-opacity": 0.7,
"fill-outline-color": "#000000",
},
});
});
</script>
</body>
</html>
The request for the vector tiles has the z/x/y format. z is the zoom level or height of the viewer. z can range from 1 to 22, though is generally between 1 (the entire earth) and 15 (a close neighborhood view). x is the count of the tile from West to East and y is the count of the tile from North to South. Note that the ranges for x and y depend on z, i.e. the larger z is the smaller the tiles and the greater the number of tiles.
Adding a source does not mean that anything will be displayed. The source is available to be displayed but must be added as a layer. When we add a layer, we refer to the source by the name it was assigned. Tiles also have a layer name, which is the "source-layer". This can be assigned when the tiles are created. File Tiler uses the default name "default". Each layer must have a unique ID and a styling compatible with its type. Here we've shown an example fill styling for the polygons.
Now we repeat adding a source and a layer two more times. We have to give each new source an appropriate name; the layer must use that name and assign an ID; and the layer must have a style compatible with the type, i.e. polygon, line or point. Points can be represented as circles or symbols, and we've chosen circles here.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Polygon, Line, Point Example</title>
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<script src="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js"></script>
<link
href="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css"
rel="stylesheet"
/>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var cwmkey = "9G4F5b99xO28esL8tArIO2Bbp8sGhURW5qIieYTy";
var map = new maplibregl.Map({
container: "map",
style: `https://maps.clockworkmicro.com/streets/v1/style?x-api-key=${cwmkey}`,
center: [-8.25, 53],
zoom: 7,
});
map.on("load", function () {
map.addSource("built_source", {
type: "vector",
tiles: [
`https://filetiler.clockworkmicro.com/tile/a14c29f8-ea55-49ef-ad9c-07f72de728ae/f5567795-ddb4-4800-9bf3-01a1d6786120/{z}/{x}/{y}.pbf?x-api-key=${cwmkey}`,
],
minzoom: 2,
maxzoom: 14,
});
map.addLayer({
id: "built_layer",
type: "fill",
source: "built_source",
"source-layer": "default",
paint: {
"fill-color": "#051AF0",
"fill-opacity": 0.7,
"fill-outline-color": "#000000",
},
});
map.addSource("raillines_source", {
type: "vector",
tiles: [
`https://filetiler.clockworkmicro.com/tile/a14c29f8-ea55-49ef-ad9c-07f72de728ae/ff8a1c77-6286-4438-bf6b-37aa81655300/{z}/{x}/{y}.pbf?x-api-key=${cwmkey}`,
],
minzoom: 2,
maxzoom: 14,
});
map.addLayer({
id: "raillines_layer",
type: "line",
source: "raillines_source",
"source-layer": "default",
paint: {
"line-color": "#000000",
"line-width": 1,
"line-opacity": 0.7,
},
});
map.addSource("railstations_source", {
type: "vector",
tiles: [
`https://filetiler.clockworkmicro.com/tile/a14c29f8-ea55-49ef-ad9c-07f72de728ae/535321e0-428c-4a8c-931a-46dd40e88c69/{z}/{x}/{y}.pbf?x-api-key=${cwmkey}`,
],
minzoom: 2,
maxzoom: 14,
});
map.addLayer({
id: "railstations_layer",
type: "circle",
source: "railstations_source",
"source-layer": "default",
paint: {
"circle-blur": 0,
"circle-color": "#F51111",
"circle-opacity": 0.4,
"circle-radius": 1.2,
"circle-stroke-color": "#F51111",
"circle-stroke-opacity": 0.9,
"circle-stroke-width": 1,
},
minzoom: 2,
maxzoom: 14,
});
});
</script>
</body>
</html>