---
id: "packages/active-geo/getting-started"
title: "Getting started"
description: "Receive active-geo, supply geometry and data, and draw a first map."
url: "/packages/active-geo/getting-started"
locale: "en"
revision: "ec907068c9dd906d"
---

# Getting started

## Receive the package

`active-geo` is a product; its owners `active-format`, `active-helpers` and `active-virtual` come
along. Ask the maintainer of Foundation for a bundle of your whole managed set, then follow
[Receiving packages](/receiving-packages):

```bash
node tools/rps/rps-apply.mjs plan --bundle <bundle-folder> --development
node tools/rps/rps-apply.mjs apply --bundle <bundle-folder> --expect-plan <digest> --development
```

## Declare, install and verify

```json
{
  "dependencies": {
    "@workspace/active-geo": "workspace:*",
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  }
}
```

```bash
pnpm install
node tools/rps/rps-apply.mjs verify-install --from <app-folder>
```

The entry imports its own stylesheet; in Next.js list the package and its owners in
`transpilePackages`.

## A first map

```tsx
'use client';

import {englishGeoTranslator, GeoMap} from '@workspace/active-geo';

<GeoMap
  title="Regions"
  projection="conic-equal-area"
  locale="en-GB"
  t={englishGeoTranslator}
  layers={[
    {
      type: 'area',
      id: 'regions',
      title: 'Regions',
      features: regions, // [{key, name, geometry: Polygon | MultiPolygon}]
      measures: [{id: 'index', label: 'Index'}],
      data: [{key: 'north', values: {index: 72}}],
      fill: {
        measure: 'index',
        scale: {type: 'threshold', thresholds: [40, 60, 80]},
      },
    },
  ]}
/>;
```

The map takes its width from its container; give it a container with a width.

**Example: Sites sized by their staff**

Client: Runs entirely in your browser. Source: `examples/geo/points.tsx`.

```tsx
// apps/docs/examples/geo/points.tsx
'use client';

import {useEffect, useState} from 'react';

import {
  englishGeoTranslator,
  GeoMap,
  type GeoAreaFeature,
  type GeoContextGeometry,
} from '@workspace/active-geo';
import {
  loadWorld50m,
  world50m,
} from '@workspace/active-geo/collections/world-50m';

const BENELUX = new Set(['NLD', 'BEL', 'LUX']);

// Invented sites, sized by their staff.
const SITES = [
  {key: 'ams', name: 'Amsterdam', latitude: 52.37, longitude: 4.9, staff: 120},
  {key: 'rtm', name: 'Rotterdam', latitude: 51.92, longitude: 4.48, staff: 64},
  {key: 'utr', name: 'Utrecht', latitude: 52.09, longitude: 5.12, staff: 38},
  {key: 'ein', name: 'Eindhoven', latitude: 51.44, longitude: 5.47, staff: 45},
  {key: 'bru', name: 'Brussels', latitude: 50.85, longitude: 4.35, staff: 72},
  {key: 'ant', name: 'Antwerp', latitude: 51.22, longitude: 4.4, staff: 51},
  {key: 'lux', name: 'Luxembourg', latitude: 49.61, longitude: 6.13, staff: 19},
];

/**
 * Point symbols over context geometry, sized by a count, with a legend, a
 * tooltip and selection (click, or Enter on a focused point).
 */
export default function SitesMap() {
  const [outline, setOutline] = useState<GeoAreaFeature[] | null>(null);
  useEffect(() => {
    let current = true;
    void loadWorld50m().then((loaded) => {
      if (current) setOutline(loaded.filter((f) => BENELUX.has(String(f.key))));
    });
    return () => {
      current = false;
    };
  }, []);
  if (!outline) {
    return <p className="text-muted-foreground text-sm">Loading the map…</p>;
  }
  return (
    // The map takes the width of its container (a ResizeObserver);
    // in a centring layout the host gives it one.
    <div className="w-full">
      <GeoMap
        title="Sites in the Benelux"
        projection="conic-equal-area"
        locale="en-GB"
        t={englishGeoTranslator}
        attribution={world50m.attribution}
        layers={[
          {
            type: 'context',
            id: 'benelux',
            title: 'Benelux',
            // Context, not the frame: the Netherlands of Natural Earth
            // include the Caribbean islands, so the sites frame the map.
            fit: false,
            geometries: outline.flatMap((feature): GeoContextGeometry[] =>
              feature.geometry ? [feature.geometry] : [],
            ),
          },
          {
            type: 'point',
            id: 'sites',
            title: 'Sites',
            measures: [
              {id: 'staff', label: 'Staff', semantics: {kind: 'count'}},
            ],
            marker: {size: {measure: 'staff'}},
            points: SITES.map(({staff, ...site}) => ({
              ...site,
              values: {staff},
            })),
          },
        ]}
      />
    </div>
  );
}
```
