> For the complete documentation index, see [llms.txt](https://docs.multiset.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.multiset.ai/fundamentals/mapset-multiple-maps/merging-maps-by-georeference.md).

# Merging Maps by Georeference

Merge scans that never see each other by using the survey frame they were captured in, instead of running a visual overlap job.

## Overview

Most MapSets are built by finding visual overlap between scans. That needs the scans to actually see each other, which fails on a large site: a conveyor corridor and a tank farm a kilometre apart share no imagery at all.

If those scans were captured in the **same survey frame**, the frame already tells you where each one sits. `POST /v1/vps/map-set/from-georeference` builds a MapSet from that instead.

Because the survey frame already fixes where each scan sits, the placement is exact rather than estimated, and no imagery has to be matched between them.

{% hint style="info" %}
**When to use which**

| Situation                                        | Use                                                                                                                                                                                        |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Scans overlap visually                           | [Merging Maps with Overlap](/fundamentals/mapset-multiple-maps/merging-maps-with-overlap.md)                                                                                               |
| Scans do not overlap, but share a survey frame   | This page                                                                                                                                                                                  |
| Scans do not overlap and were not geo-referenced | [Merging Maps without Overlap](/fundamentals/mapset-multiple-maps/merging-maps-without-overlap.md) or [Merging Maps Manually](/fundamentals/mapset-multiple-maps/merging-maps-manually.md) |

Prefer this route whenever the survey frame is the truth the customer works in, even if the scans happen to overlap.
{% endhint %}

## Requirements

Every map in the request must:

* have been processed as a **geo-referenced E57**,
* be in the **same source frame** as the others, meaning the same declared [Helmert](/fundamentals/third-party-scans/coordinate-reference-system.md) (one plant grid) or the same projected EPSG code,
* be of the same generation, and not already belong to a MapSet.

A request that breaks any of these is rejected before anything is created:

| Response | Cause                                                                                                                               |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `400`    | A map is not geo-referenced, the maps are in different frames (the message names each map and its frame), or generations are mixed. |
| `409`    | A map already belongs to a MapSet.                                                                                                  |

## Creating the set

{% openapi src="/files/rqMWUdRriVppQLKWsyiP" path="/vps/map-set/from-georeference" method="post" %}
[mapset-georeference-api.yaml](https://3163433004-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FokTDI7QVY04Zvb1pQ8Ry%2Fuploads%2Fgit-blob-95b95b30f1093a09e7b4f61e6d5e6cfb733ef3f4%2Fmapset-georeference-api.yaml?alt=media)
{% endopenapi %}

```json
{
  "name": "North plant",
  "maps": [
    { "mapCode": "MAP_7QK2M9XR4TLD", "origin": true },
    { "mapCode": "MAP_3HN8P1WY6VZQ" },
    { "mapCode": "MAP_5BD4R7KT2MFJ" }
  ]
}
```

Every member is `active` immediately, with no overlap job to wait on.

### Choosing the origin

The `order: 0` origin is the map you flag with `origin: true`. If you flag none, a central map is chosen for you, which keeps accuracy as even as possible across a large site.

Flag an origin deliberately when one part of the site is the natural reference for the people using it. Let it default when the set is large and evenly spread.

## Choosing the frame

`frame` decides where the set's coordinates are rooted, and it is the one choice worth thinking about before you create the set.

<table><thead><tr><th width="150">Value</th><th>Set coordinates are</th><th>Use when</th></tr></thead><tbody><tr><td><code>origin-map</code><br>(default)</td><td>Rooted at the origin map</td><td>The default. Nothing changes for existing consumers.</td></tr><tr><td><code>local</code></td><td>Rooted at the source grid's <code>(0,0,0)</code>, so set coordinates <strong>are</strong> that grid's coordinates</td><td>Helmert-placed maps only, when you want to work in the customer's plant grid directly</td></tr></tbody></table>

{% hint style="warning" %}
**`frame: "local"` is not yet supported by the Developer Portal viewer.** Localization is unaffected, but a local-frame set will not display correctly in the portal. The create response flags this in `warnings`.

Use `local` when you consume the set through the API. Stay on the default when people will view the set in the portal.
{% endhint %}

## The set's own geo anchor

A set built this way carries a `georeference` of its own, returned by `GET /v1/vps/map-set/{id}`. Set queries use it for geo conversion in preference to the origin map's location.

With the default `frame: "origin-map"` the anchor is a copy of the origin map's location and heading, so nothing changes for anything already reading the set. With `frame: "local"` the anchor is the Helmert at the grid origin.

## Adding maps later

A set built this way can be extended from the same survey frame, without an overlap job.

{% openapi src="/files/rqMWUdRriVppQLKWsyiP" path="/vps/map-set/{mapSetId}/from-georeference" method="put" %}
[mapset-georeference-api.yaml](https://3163433004-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FokTDI7QVY04Zvb1pQ8Ry%2Fuploads%2Fgit-blob-95b95b30f1093a09e7b4f61e6d5e6cfb733ef3f4%2Fmapset-georeference-api.yaml?alt=media)
{% endopenapi %}

```json
{
  "maps": [
    { "mapCode": "MAP_9XW2T6QN8KRV" },
    { "mapCode": "MAP_2FJ5L8CD3PYB" }
  ]
}
```

Each entry carries either `mapCode` or `mapId`, not both. Pass a single-entry array to add one map.

Two guarantees worth relying on:

* **Maps already in the set never move.** Poses your customer has already worked against stay exactly where they were.
* **The request is all or nothing.** If any map fails a check, none are added.

Each new map must be in the same source frame the set was built in. The set already knows its own frame, so there is nothing to pass here.

Use [`PUT /v1/vps/map-set/overlap/{mapSetId}`](/fundamentals/mapset-multiple-maps/merging-maps-with-overlap.md) instead when the map being added was not geo-referenced.

## Correcting the origin

{% openapi src="/files/rqMWUdRriVppQLKWsyiP" path="/vps/map-set/{mapSetId}/origin" method="put" %}
[mapset-georeference-api.yaml](https://3163433004-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FokTDI7QVY04Zvb1pQ8Ry%2Fuploads%2Fgit-blob-95b95b30f1093a09e7b4f61e6d5e6cfb733ef3f4%2Fmapset-georeference-api.yaml?alt=media)
{% endopenapi %}

```json
{
  "coordinates": {
    "latitude": 12.9716,
    "longitude": 77.5946,
    "altitude": 920.4
  },
  "heading": 45
}
```

Updates the coordinates and heading of the set's origin, mirroring the equivalent portion of `PUT /v1/vps/map/{mapId}`. At least one of `coordinates` or `heading` is required.

Which record is written depends on the set:

| Set                                                          | What is written                                                                                                                          |
| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
| Has its own anchor, `frame: origin-map`                      | The set anchor, and the same values are mirrored onto the order-0 map (`mirroredToOriginMap: true`) so readers of either stay consistent |
| Has its own anchor, `frame: local`                           | The set anchor only. The map is left alone                                                                                               |
| Has no anchor (any set created before this endpoint existed) | The map holding `order: 0`, which is the original behaviour                                                                              |

`applyTo` overrides that choice: `"mapset"` creates or updates the set anchor (both coordinates and heading are required the first time), `"origin-map"` writes the map. The response's `updated` field says which happened.

{% hint style="info" %}
Changing a geo-reference refreshes the map's [geo-fence](/fundamentals/georeferencing-maps/geo-fence.md), so `geoFenceReady` is briefly `false` after a correction.
{% endhint %}

## Related

* [Coordinate Reference System](/fundamentals/third-party-scans/coordinate-reference-system.md), for declaring the Helmert or EPSG grid that makes this possible.
* [Merging Maps with Overlap](/fundamentals/mapset-multiple-maps/merging-maps-with-overlap.md), the visual route.
* [Geo-fence](/fundamentals/georeferencing-maps/geo-fence.md), which is rebuilt when an origin moves.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.multiset.ai/fundamentals/mapset-multiple-maps/merging-maps-by-georeference.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
