Skip to content

Use addProtocol to Transform Feature Properties

Reverse country names with addProtocol in plain JavaScript.

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Use addProtocol to Transform Feature Properties</title>
    <meta property="og:description" content="Reverse country names with addProtocol in plain JavaScript." />
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://unpkg.com/maplibre-gl@5.1.0/dist/maplibre-gl.css" />
    <script src="https://unpkg.com/maplibre-gl@5.1.0/dist/maplibre-gl.js"></script>
    <style>
        body { margin: 0; padding: 0; }
        html, body, #map { height: 100%; }
    </style>
</head>
<body>
    <div id="map"></div>
    <script type="module">
        import Protobuf from 'https://unpkg.com/pbf@4.0.1/index.js';
        import {VectorTile} from 'https://esm.run/@mapbox/vector-tile@2.0.3/index.js';
        import tileToProtobuf from 'https://esm.run/vt-pbf@3.1.3/index.js';

        const protocol = 'reverse';
        maplibregl.addProtocol(protocol, (request) => {
            const url = request.url.replace(protocol + '://', '');
            return fetch(url)
                .then((response) => response.arrayBuffer())
                .then((data) => new VectorTile(new Protobuf(data)))
                .then((tile) => ({
                    layers: Object.entries(tile.layers).reduce((acc, [layerId, layer]) => ({
                        ...acc,
                        [layerId]: {
                            ...layer,
                            feature: (index) => {
                                const feature = layer.feature(index);
                                if (feature.properties && typeof feature.properties['NAME'] === 'string') {
                                    feature.properties['NAME'] = feature.properties['NAME'].split('').reverse().join('');
                                }
                                if (feature.properties && typeof feature.properties['ABBREV'] === 'string') {
                                    feature.properties['ABBREV'] = feature.properties['ABBREV'].split('').reverse().join('');
                                }
                                return feature;
                            }
                        }
                    }), {})
                }))
                .then((tile) => tileToProtobuf(tile).buffer)
                .then((data) => ({ data }));
        });

        const map = new maplibregl.Map({
            container: 'map',
            style: 'https://demotiles.maplibre.org/style.json',
            center: [8, 47],
            zoom: 5,
            hash: 'map'
        });

        map.setTransformRequest((url, resourceType) => {
            if (url.startsWith('https://demotiles.maplibre.org/tiles/') && resourceType === 'Tile') {
                return { url: protocol + '://' + url };
            }
            return undefined;
        });
    </script>
</body>
</html>