# MapLibre

> A MapLibre GL JS 6 map of the geolith india tile set from api.geolith.app: the TileJSON as a vector source, a small style, and the attribution line.

A MapLibre map drawn from the hosted `india` tile set. The source is the TileJSON URL; MapLibre reads the tile URL, zooms and bounds from it, and the tile URL already carries your key.

Use a publishable key (`gc_pk_…`) whose allowed origins include your site and `http://localhost:5173` for development. See [API keys](/search/hosted/keys).

## Set up

```bash
npm create vite@latest geolith-tiles -- --template vanilla-ts
cd geolith-tiles
npm install maplibre-gl@6
echo "VITE_GEOLITH_KEY=gc_pk_your_publishable_key" > .env.local
```

In `index.html`, give the map a full-page element:

```html
<div id="map" style="position: absolute; inset: 0"></div>
<script type="module" src="/src/main.ts"></script>
```

## src/main.ts

```ts
import { Map, setWorkerUrl } from 'maplibre-gl';
import workerUrl from 'maplibre-gl/dist/maplibre-gl-worker.mjs?url';
import 'maplibre-gl/dist/maplibre-gl.css';

// MapLibre 6 runs its worker from a separate module; let Vite emit it.
setWorkerUrl(workerUrl);

const KEY = import.meta.env.VITE_GEOLITH_KEY as string; // gc_pk_…, allowed origin: this site
const TILEJSON = `https://api.geolith.app/v1/tiles/india.json?api_key=${KEY}`;

new Map({
  container: 'map',
  center: [73.86, 18.52],
  zoom: 11,
  style: {
    version: 8,
    sources: {
      geolith: { type: 'vector', url: TILEJSON },
    },
    layers: [
      {
        id: 'background',
        type: 'background',
        paint: { 'background-color': '#dfe7ec' },
      },
      {
        id: 'earth',
        type: 'fill',
        source: 'geolith',
        'source-layer': 'earth',
        paint: { 'fill-color': '#f4f1ea' },
      },
      {
        id: 'water',
        type: 'fill',
        source: 'geolith',
        'source-layer': 'water',
        filter: ['==', ['geometry-type'], 'Polygon'],
        paint: { 'fill-color': '#a9cde0' },
      },
      {
        id: 'buildings',
        type: 'fill',
        source: 'geolith',
        'source-layer': 'buildings',
        paint: { 'fill-color': '#dcd6cc' },
      },
      {
        id: 'minor-roads',
        type: 'line',
        source: 'geolith',
        'source-layer': 'roads',
        filter: ['==', ['get', 'kind'], 'minor_road'],
        paint: { 'line-color': '#ffffff', 'line-width': 1 },
      },
      {
        id: 'major-roads',
        type: 'line',
        source: 'geolith',
        'source-layer': 'roads',
        filter: ['in', ['get', 'kind'], ['literal', ['highway', 'major_road']]],
        paint: { 'line-color': '#f2b56b', 'line-width': 2 },
      },
      {
        id: 'boundaries',
        type: 'line',
        source: 'geolith',
        'source-layer': 'boundaries',
        paint: { 'line-color': '#8a7f99', 'line-dasharray': [3, 2] },
      },
    ],
  },
});
```

The style has no label layers, so it needs no `glyphs` URL. For labels, add `symbol` layers on `places` and `roads` with a `glyphs` URL of your own.

MapLibre shows the attribution from the TileJSON (`© OpenStreetMap contributors (ODbL), Overture Maps Foundation`) in its attribution control. Keep that control on.

## Notes

- A map view asks for about 30 tiles at once. A publishable key allows 20 tile requests a second per visitor, enough for two such views; see [Keys and limits](/tiles/hosted/limits).
- Outside India the tile set has no data: tiles there answer `204`.
- To add place search to the same map, see [Search with MapLibre](/search/hosted/maplibre).
