CartoDB Basemaps

Complete list:

Positron with labels: URL: https://{s}{z}/{x}/{y}.png

Positron without labels: URL: https://{s}{z}/{x}/{y}.png

Own Base Map

An OpenStreetMap vector tileset for Ontario is available (2.5 GiB). The tiles are generated on zoom levels 1 to 14, but can be overzoomed to level 18+. Vector tiles contain selection of OpenStreetMap data – following the OpenMapTiles schema, compatible with the open styles.

Install the MapTiler server software to you run the maps on your own infrastructure and to generate traditional raster tiles compatible with Leaflet or standard map services for desktop GIS.


We may *simply* use MapTiler’s My Cloud basic maps:

  • Basic
  • Basic WSG84 (EPSG4236) – not in the commonly-used “Web Mercator” and, so might require more complicated setup of your application (see the examples). We’d used WSG84 projection in converting the Shapefiles to GeoJSON.

Basic WSG84

Embeddable Viewer

Insert the following code into your page and use this map:

Embedding with an iframe is the simplest way:

<iframe width=”500″ height=”300″ src=”″></iframe>

Use vector style

JavaScript viewers – check one of the prepared examples:

Copy link to JSON style into OpenLayers, Mapbox GL JS or mobile SDKs:


OpenLayers is a full featured web mapping library that allows you to display maps from various sources and formats.

Vector tiles can be displayed in OpenLayers using the ol-mapbox-style plugin together with OpenMapTiles.

See also OpenLayers examples and the full API Specification.

Examine the sample code and use the buttons in the top-right corner to copy the code or edit in jsFiddle:

<!DOCTYPE html>
<script src=””></script>
<script src=””></script>
<link rel=”stylesheet” href=””>
#map {position: absolute; top: 0; right: 0; bottom: 0; left: 0;}
<div id=”map”></div><p><a href=”” target=”_blank”>&copy; MapTiler</a> <a href=”” target=”_blank”>&copy; OpenStreetMap contributors</a></p>
var projection = ‘EPSG:4326’;

var tileGridOpts = {“extent”: [-180, -90, 180, 90], “minZoom”: 0, “sizes”: [[2, 1], [4, 2], [8, 4], [16, 8], [32, 16], [64, 32], [128, 64], [256, 128], [512, 256], [1024, 512], [2048, 1024], [4096, 2048], [8192, 4096], [16384, 8192]], “tileSizes”: [[512, 512], [512, 512], [512, 512], [512, 512], [512, 512], [512, 512], [512, 512], [512, 512], [512, 512], [512, 512], [512, 512], [512, 512], [512, 512], [512, 512]], “resolutions”: 1};
var tilegrid = new ol.tilegrid.TileGrid(tileGridOpts);

var viewResolutions = tileGridOpts.resolutions.concat();
var overzoomLevels = 3;
while (overzoomLevels– > 0) {
viewResolutions.push(viewResolutions[viewResolutions.length – 1] / 2);

var map = new ol.Map({
layers: [],
target: ‘map’,
view: new ol.View({
constrainResolution: true,
projection: projection,
resolutions: viewResolutions,
center: ol.proj.transform([0, 0.00010], ‘EPSG:4326’, projection),
zoom: 0

.then(function(response) { return response.json() })
.then(function(style) {
var mapExtent = tileGridOpts.extent;
var center =;
if (!center || center.length < 2) {
var bounds = ol.proj.transformExtent(mapExtent, projection, ‘EPSG:4326’);
center = [
bounds ? bounds[0] + (bounds[2] – bounds[0]) / 2 : 0,
bounds ? bounds[1] + (bounds[3] – bounds[1]) / 2 : 0

Object.keys(style.sources).forEach(function(sourceId) {
var source = style.sources[sourceId];
if (source && source.url) {
.then(response => response.json())
.then(tileJSON => {
let zIndex = style.layers.findIndex(l => l.source == sourceId);

if (source.type == ‘vector’) {
var layer = new ol.layer.VectorTile({
zIndex: zIndex,
declutter: true,
extent: mapExtent,
source: new ol.source.VectorTile({
attributions: tileJSON.attribution,
format: new ol.format.MVT(),
projection: projection,
tileGrid: tilegrid,
urls: tileJSON.tiles

olms.applyStyle(layer, style, sourceId, undefined, viewResolutions)
.then(function() {
} else if (source.type == ‘raster’) {
var layer = new ol.layer.Tile({
zIndex: zIndex,
extent: mapExtent,
source: new ol.source.XYZ({
projection: projection,
attributions: tileJSON.attribution,
tileGrid: tilegrid,
urls: tileJSON.tiles
olms.applyBackground(map, style);

map.getView().setCenter(ol.proj.transform([center[0], center[1]], ‘EPSG:4326’, projection));
map.getView().setZoom(style.zoom || tileGridOpts.minZoom || 0);

Digging Deeper into OpenLayers

The ol package

The recommended way to use OpenLayers is to work with the ol package. You can install the latest with npm:

npm install ol

Hosted builds for development

If you want to try out OpenLayers without downloading anything (not recommended for production), include the following in the head of your html page:

<script src=""></script>
<link rel="stylesheet" href="">
Downloads for the v6.5.0 release
Archive Description Includes a full build of the library (ol.js), a source map (, and library CSS (ol.css with source map Includes all of the above plus examples, API docs, and sources.

Modern JavaScript works best when using and authoring modules. The recommended way of using OpenLayers is installing the ol package. This tutorial walks you through setting up a simple dev environment, which requires node for everything to work.

In this tutorial, we will be using Parcel to bundle our application. There are several other options, some of which are linked from the README.

Initial steps

Create a new empty directory for your project C:\ol\new-project.  In cli, navigate to \new-project and initialize the project with

npm init

This will create a package.json file in your working directory. Add OpenLayers as dependency to your application with

npm install ol

At this point you can ask NPM to add required development dependencies by running

npm install --save-dev parcel-bundler

Application code and index.html

Place your application code in index.js. Here is a simple starting point:

import 'ol/ol.css';
import {Map, View} from 'ol';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';

const map = new Map({
  target: 'map',
  layers: [
    new TileLayer({
      source: new OSM()
  view: new View({
    center: [0, 0],
    zoom: 0

You will also need an index.html file that will use your bundle. Here is a simple example:

<!DOCTYPE html>
    <meta charset="utf-8">
    <title>Using Parcel with OpenLayers</title>
      #map {
        width: 400px;
        height: 250px;
    <div id="map"></div>
    <script src="./index.js"></script>

Creating a bundle

With two additional lines in package.json you can introduce the commands npm run build and npm start to manually build your bundle and watch for changes, respectively. The final package.json with the two additional commands "start" and "build" should look like this:

  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "parcel index.html",
    "build": "parcel build --public-url . index.html"
  "author": "",
  "license": "ISC"

That’s it. Now to run your application, enter

npm start

in your console. To test your application, open http://localhost:1234/ in your browser. Whenever you change something, the page will reload automatically to show the result of your changes.

Note that a single JavaScript file with all your application code and all dependencies used in your application has been created. From the OpenLayers package, it only contains the required components.

To create a production bundle of your application, simply type

npm run build

and copy the dist/ folder to your production server.


  1. 3515625, 0.17578125, 0.087890625, 0.0439453125, 0.02197265625, 0.010986328125, 0.0054931640625, 0.00274658203125, 0.001373291015625, 0.0006866455078125, 0.00034332275390625, 0.000171661376953125, 8.58306884765625e-05, 4.291534423828125e-05