# Map Layers & Places

The dashboard's **Now Map** shows where your conversations are happening.
This page lets a workspace admin put **your own data** on the same map, so a
call lights up next to the truck that could take it, inside (or outside) the
area you serve, with the weather it is happening in.

Everything on this page is either yours or free. The one priced layer — live
traffic — is governed elsewhere: by [Location & Map
Precision](/docs/workspace-administration/location-and-map-precision) and the
[map data budget](/docs/workspace-administration/spend-limits#the-map-data-budget).

## What you'll need

- A **tenant admin** login — the page is **Settings** (the gear in the top
  bar) → **Workspace** → **Map Layers & Places**.
- For an upload: a CSV, JSON, GeoJSON, KML or KMZ file.
- For a scheduled feed: an `https://` URL that returns one of those formats.
- For a live stream: one of your [trigger webhook
  endpoints](/docs/integrations/webhooks) — your system posts rows to it.
- For Workiz jobs: the Workiz connector, connected.

## Layers — your data in five shapes

A **layer** is a named set of things drawn on the map. Pick the shape that
matches what the rows are:

| Shape | For | Drawn as |
|---|---|---|
| **Moving points** | drivers, trucks, couriers — a timestamped position per unit | a dot with a heading tick and a dashed trail of its last positions; the feed's age on the legend |
| **Fixed points with a state** | sites, sensors, jobs, stores | a rounded square coloured by state |
| **Areas** | service areas, regions, territories | an outline with a soft fill, under the street labels |
| **A value at a place over time** | queue depth, a sensor reading | a disc sized and coloured by the value; a sparkline of the last readings on selection |
| **Links between two places** | order → warehouse, request → dispatched unit | an arc with an arrowhead — each one a real relation, never decoration |

**State colours.** A state that reads like a status word takes the status
meaning everywhere on the platform: *available / online / done* read as good,
*busy / en route / pending* as attention, *offline / failed / cancelled* as
bad. Any other state takes a categorical slot in a fixed order, and past six
distinct states the rest fold into **All others** on the legend. Colours
follow the state, not the count, so filtering never repaints survivors.

### Sources

- **A file you upload.** Create the layer, then **Upload**. GeoJSON and KML
  carry their own geometry and need no mapping. CSV and JSON open the
  **column-mapping wizard**: the platform pre-fills its guess from the
  headers (and from the values, for latitude and longitude), you confirm or
  correct each field, and a re-check tells you how many rows will place
  before you import. Rows with an address but no coordinates can be geocoded
  (one Google Geocoding call per distinct address — the platform's Maps key
  must be configured). Untick **Replace** to add rows to the layer instead of
  replacing it.
- **A URL fetched on a schedule.** Every *N* minutes (minimum five) the
  platform fetches the URL and replaces the layer with what it returns. CSV
  and JSON feeds reuse the mapping you set with one sample upload.
- **A trigger webhook endpoint.** Name the endpoint's slug; every delivery's
  rows become features on the next refresh (about a minute). The body may be
  an array, or an object with the rows under a key you name (**Rows path**).
  Moving points keep a trail across deliveries.
- **Workiz jobs.** Jobs from the last day and the coming week that carry
  coordinates, coloured by status bucket, linking back to Workiz.
- **Your contacts.** Contacts with a located address (typed and geocoded, or
  learned on the [location ladder](/docs/workspace-administration/location-and-map-precision#where-each-location-comes-from)).
  Because this is customer data it is drawn **only for viewers with street
  precision**; city-scale viewers see the layer listed as *street precision
  only*.

### Uploads improve the core map

A row with an **email or phone** is matched to your contacts through the same
resolver that places every inbound text and call. A match places that
contact on the location ladder with the row's coordinates (source: *your
upload*), so the contact page reads "Likely in …" and territory filters find
them. The map's **In focus** card says which layer placed a contact. Nothing
overwrites the address you typed.

### Freshness

A layer always says how old its data is — in its tick beneath the map
("trucks · 41 min old") and on this page. A URL feed that has missed three of
its intervals, or a webhook or Workiz layer silent for an hour, is marked
**stale**, and a failed refresh shows its error on the layer and in that
tick's tooltip. A stale feed never masquerades as live.

### Meaning — what a tag unlocks

Give a layer a **meaning** and the map reasons with it. Select any light (a
call, a chat, a job) and the **In focus** card's **Around this spot** section says:

- **Fleet:** the nearest unit whose state does not read as busy, its
  distance, how old its position is, and — where Google Maps is configured
  and the viewer has street-scoped context — a driving ETA. ETAs are Routes
  calls, so they count against the map data budget like a traffic refresh;
  when the budget is paused the line says so.
- **Service area:** which areas the spot falls inside, or **outside every
  service area** when it falls in none.
- **Site / fulfilment:** the nearest site and its distance.

## Places — bookmarks, not boundaries

A **place** is a camera shortcut: pin a depot, a city, a region by address or
coordinates, and it appears as a pill under the globe, in the **In focus**
menu, and ringed and labelled on the map itself. The platform also
**suggests** the cities your conversations and contacts come from most, best
first; accept the ones you want one click away. Places never limit the map —
every workspace keeps the whole planet. Up to sixty per workspace.

## Overlays — free context, switched off until you say so

The platform ships four free overlays, all **off** by default:

- **Weather** — current conditions at the place being looked at (Open-Meteo).
- **Air quality** — the European air quality index there (Open-Meteo / CAMS).
- **Daylight** — the night side of the planet, computed from the clock; it
  moves with the map's time slider.
- **Public holidays** — today's and the coming week's, for the country of
  your workspace timezone (Nager.Date).

A tenant admin turns each one on here; every viewer then chooses what they
show from the map's **Layers → Context** menu. Weather and air quality
appear in the line under the headline ("12° light rain · air good"), holidays
as "Today is …". None of these count against the map data budget.

## What a tester should expect

- With no layers, places or overlays, the page says so and the Now Map is
  unchanged.
- Creating a layer records an audit event (**Map layers & places** in the
  Audit Trail), as does every upload, refresh, deletion, place and overlay
  change.
- A CSV with `lat`/`lng` columns pre-fills the mapping; the re-check reports
  "N place" before the import.
- A layer hidden with **Hide** stays configured but is left off the map for
  everyone; a viewer's own tick beneath the map is personal to them.
- The contacts layer reads *street precision only* for a city-scale viewer.
- The night overlay darkens the far side of the globe and slides as the
  −30/+30 scrubber moves.

## Related

- [Location & Map Precision](/docs/workspace-administration/location-and-map-precision) — street precision, street-scoped context and the traffic layer.
- [Spend Limits](/docs/workspace-administration/spend-limits#the-map-data-budget) — the map data budget that ETAs and traffic draw on.
- [Dashboard Overview](/docs/getting-started/dashboard) — the Now tab.

[Sign in to Karmaflow.ai](https://omni.karmaflow.ai/auth/login)
