Skip to content

OpenLayers

OpenLayers is a popular web mapping framework and can load image layers from ReadyMap

Note

ReadyMap provides tiles using the Tile Map Service specification which inverts the Y coordinate from what what OpenLayers expects so we provide a custom tileUrlFunction function to do the inversion.

Spherical Mercator image layers

Here is a complete example of loading a spherical mercator image layer in OpenLayers

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v8.2.0/ol.css">

    <title>OpenLayers ReadyMap</title>
    <style>
        #map {
            position: absolute;
            top: 0;
            left: 0;
            height: 100%;
            width: 100%;
            margin: 0;
            overflow: hidden;
            padding: 0;
        }
    </style>
</head>

<body>
    <div id="map"></div>
    <script src="https://cdn.jsdelivr.net/npm/ol@v8.2.0/dist/ol.js"></script>
    <script>
        const map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.XYZ({
                        tileUrlFunction: function (tileCoord) {
                            var z = tileCoord[0];
                            var x = tileCoord[1];
                            var y = tileCoord[2];
                            var flippedY = (1 << z) - y - 1;
                            return `https://readymap.org/readymap/tiles/1.0.0/158/${z}/${x}/${flippedY}`;
                        }
                    })
                })
            ],
            view: new ol.View({
                center: ol.proj.fromLonLat([0, 0]),
                zoom: 0
            })
        });
    </script>

</body>

</html>

Global Geodetic image layers

Loading global geodetic image layers in OpenLayers is a bit more complicated as we need to provide a custom TileGrid to OpenLayers so it understands the 2x1 tiling scheme.

Here is a complete example of loading an global geodetic image layer using OpenLayers

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v8.2.0/ol.css">

    <title>OpenLayers ReadyMap</title>
    <style>
        #map {
            position: absolute;
            top: 0;
            left: 0;
            height: 100%;
            width: 100%;
            margin: 0;
            overflow: hidden;
            padding: 0;
        }
    </style>
</head>

<body>
    <div id="map"></div>
    <script src="https://cdn.jsdelivr.net/npm/ol@v8.2.0/dist/ol.js"></script>
    <script>

        let resolutions = [];
        let baseRes = 180.0 / 256.0;
        let maxLevel = 19;
        for (let i = 0; i < maxLevel; i++) {
            resolutions.push(baseRes / Math.pow(2, i));
        }

        const map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.XYZ({
                        projection: 'EPSG:4326',
                        tileUrlFunction: function (tileCoord) {
                            var z = tileCoord[0];
                            var x = tileCoord[1];
                            var y = tileCoord[2];
                            var flippedY = (1 << z) - y - 1;
                            return `https://readymap.org/readymap/tiles/1.0.0/7/${z}/${x}/${flippedY}`;
                        },
                        tileGrid: new ol.tilegrid.TileGrid({
                            extent: [-180, -90, 180, 90],
                            origin: [-180, 90],
                            resolutions: resolutions,
                            tileSize: [256, 256]
                        }),
                    })
                })
            ],
            view: new ol.View({
                center: ol.proj.fromLonLat([0, 0]),
                projection: 'EPSG:4326',
                zoom: 0
            })
        });
    </script>

</body>

</html>