Skip to content
Add a Pattern to a Polygon

Add a Pattern to a Polygon in Maptoolkit Maps JS

Maptoolkit Maps JS supports pattern fills on polygon layers, letting you tile any image across a geographic area. You load the image into the map’s sprite using addImage, then reference it by name in a fill-pattern paint property on a fill layer. Use pattern fills to represent land use types, annotate restricted zones, or add decorative texture to any polygon on your map.

const API_KEY = 'YOUR_API_KEY';

    const map = new maptoolkit.Map({
        container: 'map',
        apiKey: API_KEY,
        style: `https://styles.maptoolkit.net/maptoolkit/maptoolkit.summer.json?api_key=${API_KEY}`,
        zoom: 1,
        attributionControl: { compact: false }
    });

    map.on('load', async () => {
        map.addSource('source', {
            type: 'geojson',
            data: {
                type: 'Feature',
                properties: {},
                geometry: {
                    type: 'Polygon',
                    coordinates: [
                        [
                            [-30, -25],
                            [-30,  35],
                            [ 30,  35],
                            [ 30, -25],
                            [-30, -25]
                        ]
                    ]
                }
            }
        });

        const image = await map.loadImage(
            'https://upload.wikimedia.org/wikipedia/commons/thumb/6/60/Cat_silhouette.svg/60px-Cat_silhouette.svg.png'
        );
        map.addImage('pattern', image.data);

        map.addLayer({
            id: 'pattern-layer',
            type: 'fill',
            source: 'source',
            paint: {
                'fill-pattern': 'pattern'
            }
        });
    });
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Add a Pattern to a Polygon - Maptoolkit Maps JS</title>
    <meta property="og:description" content="Fill a polygon with a repeating image pattern." />
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://unpkg.com/@maptoolkit/maps@11.0.0-beta.3/dist/maptoolkit.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/@maptoolkit/maps@11.0.0-beta.3/dist/maptoolkit.css" />
    <style>
        html, body { width: 100%; height: 100%; margin: 0; padding: 0; }
        #map { width: 100%; height: 100%; }
    </style>
</head>
<body>
<div id="map"></div>
<script>
    const API_KEY = 'YOUR_API_KEY';

    const map = new maptoolkit.Map({
        container: 'map',
        apiKey: API_KEY,
        style: `https://styles.maptoolkit.net/maptoolkit/maptoolkit.summer.json?api_key=${API_KEY}`,
        zoom: 1,
        attributionControl: { compact: false }
    });

    map.on('load', async () => {
        map.addSource('source', {
            type: 'geojson',
            data: {
                type: 'Feature',
                properties: {},
                geometry: {
                    type: 'Polygon',
                    coordinates: [
                        [
                            [-30, -25],
                            [-30,  35],
                            [ 30,  35],
                            [ 30, -25],
                            [-30, -25]
                        ]
                    ]
                }
            }
        });

        const image = await map.loadImage(
            'https://upload.wikimedia.org/wikipedia/commons/thumb/6/60/Cat_silhouette.svg/60px-Cat_silhouette.svg.png'
        );
        map.addImage('pattern', image.data);

        map.addLayer({
            id: 'pattern-layer',
            type: 'fill',
            source: 'source',
            paint: {
                'fill-pattern': 'pattern'
            }
        });
    });
</script>
</body>
</html>

Use the prompt below with any LLM to get the same result. Make sure the Maptoolkit MCP server is connected first — check out AI Integration & MCP to get started.

Use the Maptoolkit Connector. Create an interactive map with zoom level 1. Add a polygon from [-30, -25] to [30, 35] filled with a repeating image pattern using this image: https://upload.wikimedia.org/wikipedia/commons/thumb/6/60/Cat_silhouette.svg/60px-Cat_silhouette.svg.png.

How it works

A pattern fill is an image tiled across a polygon, and it goes through the same sprite mechanism as an icon: loadImage, then addImage under a name, then fill-pattern on the layer referencing that name.

fill-pattern and fill-color are mutually exclusive. Setting a pattern means the colour is ignored, so tinting a pattern has to happen in the image itself.

The image tiles in screen space, not geographic space, so the pattern stays the same size on screen as you zoom rather than scaling with the ground. That is usually what you want for hatching, and wrong if you meant to represent a real-world size.

Patterns work best when the source image tiles seamlessly; a non-tiling image shows visible seams across a large polygon.

Next steps

Patterns earn their place when they mean something, so the next step is usually one pattern per category: hatching for restricted areas, dots for planned ones, solid for active. That also survives being printed or photocopied, which colour alone does not.

Pairing a pattern with a semi-transparent fill underneath is worth trying too, since it keeps the basemap readable while still marking the area clearly.