Skip to content

Draw GeoJSON Points in Maptoolkit Maps JS

The circle layer type in Maptoolkit Maps JS renders GeoJSON point features as filled circles with configurable radius, color, opacity, and stroke. You add a GeoJSON source with your point data and then reference it in a circle layer’s source property. Use this as the foundation for any point dataset visualization, including store locations, sensor readings, or event markers that need consistent styling across zoom levels.

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}`,
        center: [12.0, 47.5],
        zoom: 7,
        attributionControl: { compact: false }
    });

    map.addControl(new maptoolkit.NavigationControl(), 'top-right');

    map.on('load', () => {
        map.addSource('cities', {
            type: 'geojson',
            data: {
                type: 'FeatureCollection',
                features: [
                    { type: 'Feature', geometry: { type: 'Point', coordinates: [11.39085, 47.27574] }, properties: { name: 'Innsbruck' } },
                    { type: 'Feature', geometry: { type: 'Point', coordinates: [16.3738, 48.2082] }, properties: { name: 'Vienna' } },
                    { type: 'Feature', geometry: { type: 'Point', coordinates: [13.0550, 47.8095] }, properties: { name: 'Salzburg' } },
                    { type: 'Feature', geometry: { type: 'Point', coordinates: [15.4395, 47.0707] }, properties: { name: 'Graz' } },
                    { type: 'Feature', geometry: { type: 'Point', coordinates: [11.576, 48.1374] }, properties: { name: 'Munich' } },
                    { type: 'Feature', geometry: { type: 'Point', coordinates: [8.5417, 47.3769] }, properties: { name: 'Zurich' } }
                ]
            }
        });

        map.addLayer({
            id: 'cities',
            type: 'circle',
            source: 'cities',
            paint: {
                'circle-radius': 8,
                'circle-color': '#3887be',
                'circle-stroke-width': 2,
                'circle-stroke-color': '#fff'
            }
        });
    });
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Draw GeoJSON Points - Maptoolkit Maps JS</title>
    <meta property="og:description" content="Add a GeoJSON point source and render it as a circle layer." />
    <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}`,
        center: [12.0, 47.5],
        zoom: 7,
        attributionControl: { compact: false }
    });

    map.addControl(new maptoolkit.NavigationControl(), 'top-right');

    map.on('load', () => {
        map.addSource('cities', {
            type: 'geojson',
            data: {
                type: 'FeatureCollection',
                features: [
                    { type: 'Feature', geometry: { type: 'Point', coordinates: [11.39085, 47.27574] }, properties: { name: 'Innsbruck' } },
                    { type: 'Feature', geometry: { type: 'Point', coordinates: [16.3738, 48.2082] }, properties: { name: 'Vienna' } },
                    { type: 'Feature', geometry: { type: 'Point', coordinates: [13.0550, 47.8095] }, properties: { name: 'Salzburg' } },
                    { type: 'Feature', geometry: { type: 'Point', coordinates: [15.4395, 47.0707] }, properties: { name: 'Graz' } },
                    { type: 'Feature', geometry: { type: 'Point', coordinates: [11.576, 48.1374] }, properties: { name: 'Munich' } },
                    { type: 'Feature', geometry: { type: 'Point', coordinates: [8.5417, 47.3769] }, properties: { name: 'Zurich' } }
                ]
            }
        });

        map.addLayer({
            id: 'cities',
            type: 'circle',
            source: 'cities',
            paint: {
                'circle-radius': 8,
                'circle-color': '#3887be',
                'circle-stroke-width': 2,
                'circle-stroke-color': '#fff'
            }
        });
    });
</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 7, centered around [12.0, 47.5]. Add GeoJSON circle markers for Innsbruck, Vienna, Salzburg, Graz, Munich, and Zurich.

How it works

A circle layer is the cheapest way to draw points. No image, no sprite, no DOM: the renderer draws them in WebGL, so tens of thousands stay smooth where the same number of Marker objects would not.

circle-radius is in screen pixels, so circles keep their size as you zoom rather than covering a fixed area of ground. For a real-world radius you need a generated polygon; see Draw a Circle.

circle-stroke-width and circle-stroke-color give the outline. Without a stroke, points over a busy basemap are hard to pick out.

Any of these properties can be an expression rather than a constant, which is how radius or colour gets driven from a feature property.

Next steps

Driving size and colour from the data is the next step and the one that makes a point layer informative: radius by magnitude, colour by category, opacity by confidence.

After that it is interaction. A click that reports which point was hit, and a hover that highlights it, turn a scatter of circles into something you can interrogate. Once there are enough points to overlap badly, clustering is the usual answer.