Monday 28 February 2022

Show fixed 100 m x 100 m grid on lowest zoom level

I am using leaflet with openstreetmap to create a fixed grid on top of the world map that consists of 100m x 100m tiles. Basically, I am creating a turn-based game, where a player should be able to click on a certain tile, which then reveals a context menu. The server is going to know that the player has opened the tile for a certain place.

I tried the following:

<!DOCTYPE html>
<html>

<head>
    <title>GridLayer Test</title>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.1/dist/leaflet.css" />
    <style>
        body {
            padding: 0;
            margin: 0;
        }

        html,
        body,
        #map {
            height: 100%;
            width: 100%;
        }
    </style>
</head>

<body>
    <div id="map"></div>

    <script src="https://unpkg.com/leaflet@1.0.1/dist/leaflet.js"></script>

    <script>
        var map = new L.Map('map', { center: [10, 0], zoom: 2 });

        var tiles = new L.GridLayer();
        tiles.createTile = function (coords) {
            var tile = L.DomUtil.create('canvas', 'leaflet-tile');
            var ctx = tile.getContext('2d');
            var size = this.getTileSize()
            tile.width = size.x
            tile.height = size.y

            // calculate projection coordinates of top left tile pixel
            var nwPoint = coords.scaleBy(size)

            // calculate geographic coordinates of top left tile pixel
            var nw = map.unproject(nwPoint, coords.z)

            ctx.fillStyle = 'white';
            ctx.fillRect(0, 0, size.x, 50);
            ctx.fillStyle = 'black';
            ctx.fillText('x: ' + coords.x + ', y: ' + coords.y + ', zoom: ' + coords.z, 20, 20);
            ctx.fillText('lat: ' + nw.lat + ', lon: ' + nw.lng, 20, 40);
            ctx.strokeStyle = 'red';
            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.lineTo(size.x - 1, 0);
            ctx.lineTo(size.x - 1, size.y - 1);
            ctx.lineTo(0, size.y - 1);
            ctx.closePath();
            ctx.stroke();
            return tile;
        }

        L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: 'Map data &copy; <a href="http://www.osm.org">OpenStreetMap</a>',
            minNativeZoom: 1,
            maxNativeZoom: 1,
        }).addTo(map)

        tiles.addTo(map)
    </script>
</body>

</html>

As you can see the grid changed when I zoom in or out, even though I used minNativeZoom. However, I would like to have the grid fixed and 100m x 100m wide.

I also tried to only return tile when zoomLevel = 18. This does not work.

Any suggestions what I am doing wrong?

I appreciate your replies!



from Show fixed 100 m x 100 m grid on lowest zoom level

No comments:

Post a Comment