For the complete documentation index, see llms.txt. This page is also available as Markdown.

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.

When to use which

Situation
Use

Scans overlap visually

Scans do not overlap, but share a survey frame

This page

Scans do not overlap and were not geo-referenced

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

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 (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

Create a Map Set from the maps' shared georeference

post

Builds a MapSet from the survey frame the scans were captured in, rather than from a visual overlap job, so sections of a site that never see each other can still be merged.

Every map must be a geo-referenced E57 in the same source frame: the same declared Helmert (one plant grid), or the same projected EPSG code. Use /map-set/overlap when the maps were not geo-referenced.

The origin is the map flagged origin: true, or a central one chosen for you. frame decides where the set's coordinates are rooted.

Rejected with 400 when a map is not geo-referenced, when the maps are in different frames, or when generations are mixed; 409 when a map already belongs to a MapSet.

Authorizations
AuthorizationstringRequired
Bearer authentication header of the form Bearer <token>.
Body
namestringRequiredExample: North plant
framestring · enumOptional

Where the set's coordinates are rooted: the origin map (the default), or the source grid's (0,0,0), which is available for Helmert-placed maps only.

Default: origin-mapPossible values:
Responses
201

MapSet created; every member is active immediately.

application/json
messagestringOptional
mapSetCodestringOptionalExample: MSET-a1b2c3
mapSetIdstringOptional
originMapCodestringOptionalExample: MAP_7QK2M9XR4TLD
warningsstring[]Optional
post/vps/map-set/from-georeference
POST /v1/vps/map-set/from-georeference HTTP/1.1
Host: api.multiset.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 138

{
  "name": "North plant",
  "maps": [
    {
      "mapCode": "MAP_7QK2M9XR4TLD",
      "origin": true
    },
    {
      "mapCode": "MAP_3HN8P1WY6VZQ"
    },
    {
      "mapCode": "MAP_5BD4R7KT2MFJ"
    }
  ]
}
{
  "message": "text",
  "mapSetCode": "MSET-a1b2c3",
  "mapSetId": "text",
  "originMapCode": "MAP_7QK2M9XR4TLD",
  "frame": {
    "kind": "helmert",
    "description": "local grid -> WGS 84 via declared 7-parameter Helmert",
    "rootedAt": "origin-map"
  },
  "georeference": {
    "coordinates": {
      "latitude": 41.42066483,
      "longitude": -88.19195008,
      "altitude": 134.068
    },
    "heading": 179.0607,
    "frame": "origin-map"
  },
  "warnings": [
    "text"
  ],
  "maps": [
    {
      "mapCode": "text",
      "order": 1,
      "relativePose": {
        "position": {
          "x": -468,
          "y": 2,
          "z": -564
        },
        "rotation": {
          "qx": 0,
          "qy": 0,
          "qz": 0,
          "qw": 1
        }
      }
    }
  ]
}

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.

Value
Set coordinates are
Use when

origin-map (default)

Rooted at the origin map

The default. Nothing changes for existing consumers.

local

Rooted at the source grid's (0,0,0), so set coordinates are that grid's coordinates

Helmert-placed maps only, when you want to work in the customer's plant grid directly

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.

Add maps to a Map Set from their shared georeference

put

Adds one or more maps to a MapSet that was built from a shared survey frame. The maps are usable immediately, with no overlap job to wait on.

Every new map must be geo-referenced and in the same source frame as the set.

Maps already in the set never move, and the request is all or nothing: if any map fails a check, none are added. Use PUT /map-set/overlap/{mapSetId} when the map being added was not geo-referenced.

Authorizations
AuthorizationstringRequired
Bearer authentication header of the form Bearer <token>.
Path parameters
mapSetIdstringRequired

MapSet MongoDB ID or mapSetCode

Body
Responses
200

Maps added, with the pose each was given

application/json
messagestringOptionalExample: Maps added to the MapSet from their shared georeference
mapSetCodestringOptionalExample: MSET_9XQ2T7KD4MRV
mapSetIdstringOptionalExample: 68c1f0a2b4d5e60011aa22b0
originMapCodestringOptional

The order 0 map the new poses were measured against

Example: MAP_1AB2C3D4E5FG
warningsstring[]Optional

Present only when something is worth checking before you rely on the result.

put/vps/map-set/{mapSetId}/from-georeference
PUT /v1/vps/map-set/{mapSetId}/from-georeference HTTP/1.1
Host: api.multiset.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 41

{
  "maps": [
    {
      "mapCode": "MAP_7QK2M9XR4TLD"
    }
  ]
}
{
  "message": "Maps added to the MapSet from their shared georeference",
  "mapSetCode": "MSET_9XQ2T7KD4MRV",
  "mapSetId": "68c1f0a2b4d5e60011aa22b0",
  "frame": {
    "rootedAt": "origin-map",
    "description": "EPSG:25832"
  },
  "originMapCode": "MAP_1AB2C3D4E5FG",
  "maps": [
    {
      "mapCode": "MAP_7QK2M9XR4TLD",
      "relativePose": {
        "position": {
          "x": -468,
          "y": 2,
          "z": -564
        },
        "rotation": {
          "qx": 0,
          "qy": 0,
          "qz": 0,
          "qw": 1
        }
      }
    }
  ],
  "warnings": [
    "text"
  ]
}

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} instead when the map being added was not geo-referenced.

Correcting the origin

Update MapSet origin (order=0 map)

put

Updates the coordinates and/or heading of a MapSet's origin. At least one of the two must be provided.

A set that carries its own geo anchor is updated there, and for a set on the default origin-map frame the same values are also written to the order-0 map so both stay consistent (mirroredToOriginMap: true). An older set without an anchor updates the order-0 map instead.

applyTo overrides that choice, and the response's updated says what was written.

Authorizations
AuthorizationstringRequired
Bearer authentication header of the form Bearer <token>.
Path parameters
mapSetIdstringRequired

MapSet _id or mapSetCode.

Example: 672d2d3186b28d5376433370
Body

At least one of coordinates or heading is required.

headingnumber · double · max: 360OptionalExample: 45
Responses
200

MapSet origin updated successfully.

application/json
messagestringOptionalExample: MapSet origin updated successfully
mapSetIdstringOptionalExample: 672d2d3186b28d5376433370
mapIdstringOptional

The _id of the origin map (order=0) that was updated.

Example: 67292e01be60965ad653bb65
put/vps/map-set/{mapSetId}/origin
PUT /v1/vps/map-set/{mapSetId}/origin HTTP/1.1
Host: api.multiset.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 86

{
  "coordinates": {
    "latitude": 12.9716,
    "longitude": 77.5946,
    "altitude": 920.4
  },
  "heading": 45
}
{
  "message": "MapSet origin updated successfully",
  "mapSetId": "672d2d3186b28d5376433370",
  "mapId": "67292e01be60965ad653bb65"
}

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.

Changing a geo-reference refreshes the map's geo-fence, so geoFenceReady is briefly false after a correction.

Last updated

Was this helpful?