Niantic Spatial VPS2
Niantic Spatial’s Visual Positioning System 2, or VPS2, helps an app estimate where the device is in the world and place content at a stable position inside a mapped Site. It reports a geoposition as latitude, longitude, and altitude in a global coordinate system and a heading relative to geographic north.
VPS2 combines device sensors, visual data, and cloud services to estimate location and place content. When a processed VPS map is available, VPS2 can also provide localization in map-relative space for that Site. A map-relative pose is a full six-degree-of-freedom pose, also known as 6DOF, with position coordinates x, y, and z and orientation values for roll, pitch, and yaw expressed in the coordinate frame of a VPS map.
How VPS2 works
- The device runs local AR tracking.
- VPS2 uses coarse localization to establish a global geoposition and heading without requiring a VPS map.
- The app tracks a Site anchor, which is a persistent real-world pose used to attach virtual content. If the Site has a processed VPS map, VPS2 can match the camera view against the map. A successful match resolves a map-relative pose against the VPS map and provides precise localization. When a localization request fails, VPS2 reports errors through
LocalizationError. - Anchor tracking provides a pose and geolocation for each anchor. VPS2 resolves them from the global geoposition while anchor tracking is
limitedand from the VPS map while anchor tracking istracked. - You can obtain the device's current geolocation and heading from VPS2 at any time. The VPS2 tracking state indicates the current localization quality category. Separate accuracy values report the estimated horizontal, vertical, and rotational margins of error.
Tracking states
VPS2 reports device localization separately from anchor tracking, and the two can change independently. For example, device localization can be precise while a given anchor's tracking is still limited or notTracked. Do not use one state as a substitute for the other: a device localization state of coarse or precise does not mean a Site anchor is ready for placement. Your app must track an anchor before VPS2 can place content at that Site. See Anchor tracking states and Place virtual content with VPS2.
| Concept | API type | Scope | Values | What it tells you | Use it when |
|---|---|---|---|---|---|
| VPS2 tracking state | Vps2TrackingState | Device and session | unavailable, coarse, precise | Based on VPS2 geoposition from GPS and cloud services, it answers, "How well does the device know where it is in the world?" It describes a quality category; separate accuracy values provide numeric margins of error. | Placing content from geographic coordinates or evaluating the device's geolocation and heading. |
| Anchor tracking state | Platform-specific anchor tracking API | Individual anchor | Not tracked, limited, tracked | Based on per-anchor updates from the session's anchor update stream, it answers, "Is this anchor ready for reliable content placement?" Swift exposes these values through VpsAnchorUpdate.AnchorTrackingState as notTracked, limited, and tracked. Kotlin uses AnchorTrackingState.NOT_TRACKED, LIMITED, and TRACKED. Unity uses AR Foundation TrackingState. | Deciding whether content attached to a Site anchor is reliably placed. For placement UI such as Localizing or Localized, use that anchor's update. Evaluate every anchor separately and include its confidence. |
Localization modes
VPS2 operates in two distinct modes, coarse localization and precise localization, depending on what data is available in the moment to estimate the device’s real-world position and heading.
Coarse localization and precise localization work independently, and both are enabled by default.
Coarse localization
Coarse localization provides a global geoposition expressed as latitude, longitude, and altitude, along with a heading. Notably, it:
- Works globally
- Does not require a VPS map
- Provides stable global alignment suitable for large-scale AR experiences
It operates through two methods:
Local Sensor Fusion
Formerly known as the World Positioning System, or WPS, this method fuses GPS and magnetometer data with device AR tracking locally on the device. It improves frame-to-frame stability beyond raw GPS and compass readings and is available globally without any cloud dependency.
Cloud-based Geopositioning
When enabled, VPS2 sends camera imagery to the cloud to compute an improved geoposition and heading. This can provide greater accuracy than local sensor fusion alone. Improvements are most apparent in dense urban environments, where multipath effects and signal obstruction frequently degrade GPS accuracy. Enable this via the Universal Localization Enabled configuration option.
Cloud geopositioning defaults to 1 request per second, which is enough to determine a stable geoposition and heading in most conditions. Raising the rate can help the device work out where it is sooner, at the cost of bandwidth, battery, and CPU. See Tuning request rates before changing it.
In some regions, the first cloud geopositioning response may take 60 seconds or longer. Until this initial cloud response is received, global geoposition accuracy mirrors standard device GPS. This delay applies only to cloud-based coarse geopositioning. It does not affect VPS map localization once a VPS map is available and localization is attempted.
Precise localization
Precise localization is available when your application has access to a VPS Site that has been fully processed from a Scaniverse capture. It does not start automatically. To start precise localization, track one of the Site's anchors, such as the default anchor. When VPS2 successfully localizes the device to that Site, your app can place content at a stable position inside it.
VPS2 represents that stable position as a six-degree-of-freedom pose for the Site's default anchor in the device's local coordinate frame. Virtual objects placed relative to that anchor can be used in persistent and shared AR experiences. VPS2 handles the conversions between AR space, map space, and global coordinates.
Precise localization enables:
- High-precision AR content placement
- Persistent and shared anchors
- Stable alignment to mapped real-world environments
Additionally, when localized to a VPS map, VPS2 will often improve global geoposition and heading accuracy. However, improvements to absolute geoposition are not guaranteed, particularly for smaller maps.
When a localization method sends camera imagery to the cloud, including cloud-based coarse localization and precise localization, hold the device upright at approximately eye level and point it toward visually distinctive features. Avoid low-texture surfaces, ground-only views, or sky.
Anchors
Anchor accuracy depends on the anchor's own tracking state, delivered through the platform's anchor update API:
| State | What it means | How to use it |
|---|---|---|
notTracked | The anchor is not currently being tracked. The update carries no position or geolocation data. | Its pose is not usable. |
limited | The device is not localized to a VPS map. The anchor's position is estimated from coarse localization instead of from the camera view, so its accuracy is that of the device's current coarse position. | The reported horizontal, vertical, and rotation accuracy values describe the current margin of error. |
tracked | The device is localized to a VPS map, so the anchor's position comes from matching the camera view against that map. | Treat this state as necessary, but not sufficient, before relying on placed content. Also evaluate the update's confidence as described in the following table. |
An anchor may transition between these states as map localization is gained or lost. These anchor tracking states let your app adapt its user interface based on how reliable the anchor pose is.
Anchor updates provide additional context:
- Reason: Anchors in the
limitedandnotTrackedstates carry a reason explaining the state.noVisualLocalizationis the most common reason forlimited. The device knows roughly where it is but has not yet localized to the anchor's map.permissionDeniedandfatalNetworkErrordescribe conditions that persist until the underlying problem is resolved, rather than states the session recovers from on its own.
- Geolocation: Anchor updates include geolocation data directly, so you can access the anchor's geographic coordinates without performing a separate conversion.
- Orientation: The
headingvalue on an anchor's geolocation is never filled in. Use the East-Down-North orientation quaternion instead — see Anchor geolocation.
Interpret anchor updates. The previous table defines what each API state means at a point in time. The following table explains how those states behave over time and highlights cases where a state or a stream of updates can be misleading:
| Signal or situation | What it means | What your app should do |
|---|---|---|
A limited position | A limited position is a real estimate in real-world coordinates, not a placeholder or an error value. Its accuracy is enough to establish roughly where an anchor is, but not enough to align content to a specific real-world surface. | The position changes over time in two ways: it moves as the coarse estimate improves, and it shifts again when the device localizes to the map and the anchor becomes tracked. The size of that final shift is roughly the accuracy of the coarse position it replaced. |
A tracked state | tracked means VPS2 worked out a position on the map. It tells you the position exists, not that it is accurate. Accuracy still varies with lighting and camera conditions, how far the user is from the mapped area, and how well the map was built. | Check the update's confidence value, which ranges from 0.0 for unreliable results to 1.0 for highly reliable results, alongside the tracking state. Confidence varies within the tracked state, so two anchors both reporting tracked can differ in accuracy. |
| Updates continue after AR tracking is disturbed | Anchor updates can keep arriving after AR tracking has been disturbed — for example when the camera is covered, the device is moved abruptly, or the session is interrupted. A steady stream of updates therefore does not confirm that a position is still correct; it only means the anchor is still being checked. | The signal that a position has actually been re-established is the anchor's own state: after a disturbance it drops to limited with reason noVisualLocalization, and returns to tracked once the device localizes to the map again. |
Tracking state tells you whether device localization or anchor tracking is working as expected, but it does not explain why localization remains unavailable, is delayed, or appears inaccurate. If an anchor remains notTracked or limited, localization takes longer than expected, or VPS2 reports an unexpected position, use VPS Debugger to inspect localization requests, response timing, camera frames, pose and gravity information, and geographic tracks from the session.
Geo-alignment and accuracy
Each VPS map is aligned to geographic coordinates in global space during processing. This alignment determines how poses in map-relative space convert to global latitude, longitude, altitude, and heading.
In Scaniverse Web, you can manually adjust maps with the Georeference tool to better align the VPS map with geographic imagery. This adjustment affects global geoposition accuracy but does not change local map-relative accuracy. The following points are important:
- Satellite imagery is not guaranteed to be accurate and may be outdated.
- Satellite images typically show rooftops, which may occlude or obscure ground-level geometry.
- Indoor scans cannot always be precisely aligned to overhead imagery.
- Tall buildings and shadows can reduce visual clarity in satellite imagery.
- Rotation accuracy is critical. Small rotational misalignment between the VPS map and geographic north can produce increasing positional error as distance from the map origin increases. Positional offset remains constant, but rotational error is magnified as users move farther from the map center.
Global geoposition accuracy depends heavily on how precisely the VPS map is aligned to the real-world geographic coordinate system.
Applications should rely on:
- Map-relative pose for high-precision AR alignment.
- Geoposition accuracy values returned by the localization to evaluate global alignment reliability.
Troubleshoot localization
The cloud services used for coarse localization and precise localization send requests through the same VPS2 channel. VPS2 exposes a diagnostic stream of localization request records describing these requests. Each record carries a request type, a status, an error, and timing information.
This stream exists for diagnostics and monitoring. It is not the way to read localization results — device localization and anchor tracking updates report those. Three behaviors of the stream affect how its records add up.
Record lifecycle. A record is written every time a request changes status, not once per request. Each delivery contains only the records that changed since the last delivery, rather than a running history.
| Scenario | Records produced | How to interpret it |
|---|---|---|
| A request reaches the network and finishes | A pending record when it is sent, then a second record with its final status. Both records share the same request identifier. | Only the final record carries an outcome. A pending record marks the moment a request was sent, not answered, so a request that has both records appears twice in the stream. |
| A frame is rejected on-device | One frameRejected record | This record is written during on-device frame checks. Nothing is sent, so there is no pending record to match it. |
| A frame is flagged on-device | One advisory frameFlagged record. Because the frame is still sent, its network request produces separate pending and final records with a request identifier. | The frameFlagged record itself has no matching pending record. Use the separate final request record to determine the outcome of the localization attempt. |
| The session stops or a request is cancelled while still in progress | A pending record with no matching final record | The pending record is the last one that identifier produces. |
Completed means answered, not successful. status describes the fate of the request; the error field describes the fate of the localization.
| Status | Meaning | Is it a localization result? |
|---|---|---|
pending | The request was sent and is waiting for a response. | No — the outcome is not known yet |
completed | The server answered. The error field says whether the localization itself succeeded: a successful localization is completed with no error, and a failed one is completed with an error set. | Yes |
failed | The request never got a usable answer: network error, HTTP error, or a response that could not be read. The request itself failed, so nothing was learned about the location. | No — it reports a transport failure, not a localization outcome |
frameRejected | Not sent, because the camera frame was unsuitable — for example, pointing at the ground. | No — no request was made |
frameFlagged | The frame had a minor quality problem such as blur but was still sent. The send itself gets its own pending and final records. | No — it describes the frame, not the outcome |
Only vpsLocalize requests try to localize to a map. VPS2 sends several types of request, all reported through the same stream:
| Type | What it is |
|---|---|
vpsLocalize | An attempt to locate the device by matching the camera view against a VPS map. |
universalLocalize | Cloud geopositioning for coarse localization. It improves the device's global position. |
assetInfo | Fetching asset details from the portal. |
A vpsLocalize record is what tells you a map localization attempt was made: each one represents a single attempt, and its final status and error describe how that attempt turned out. universalLocalize and assetInfo records report other work, so their outcomes say nothing about whether the device localized to a map.
Coarse and precise localization work independently, and each platform's VPS2 configuration enables both. A session that keeps those settings sends universalLocalize requests throughout, and adds vpsLocalize requests once your app tracks a Site anchor. Seeing both is expected and does not mean something is misconfigured. See Get started with VPS2 for the settings on your platform.
Next steps
End-to-end guide:
Using VPS2 with the Niantic SDK: