Table of Contents

EasyAR Mega Annotation format 0.5

This document defines the format specification of EMA 0.5.

Before you begin

In this document, "producer" refers to a program that generates EMA data, and "consumer" refers to a program that reads EMA data.

Format conventions

  • EMA files use UTF-8 encoding and follow the JSON syntax defined by RFC 8259.
  • Field names in the same object must not be duplicated.
  • Field names are case-sensitive. Field names defined in this document must use the forms given in the tables and examples.
  • Required fields must exist and use the types defined in the tables. Optional fields can be omitted when they have no value.
  • UUIDs are written as strings with hyphens, for example 123e4567-e89b-12d3-a456-426614174000.
  • Timestamps use UTC date-time strings in the format YYYY-MM-DDThh:mm:ssZ, accurate to seconds. For example, 2026-08-12T00:00:00Z. This format follows the UTC representation defined by W3C Date and Time Formats.
  • Coordinate transforms use a right-handed OpenGL coordinate system: +X points right, +Y points up, and +Z points backward.

Document structure

The root object of an EMA document contains the format version, generator, extension declarations, Mega Block list, and annotation list.

Example EMA root object structure:

{
  "version": "0.5.0",
  "generatedBy": "EasyAR Mega Support 2.14.0",
  "blocks": [],
  "annotations": [],
  "extensions": []
}
Field Type Required Description
version string Yes EMA format version. A 0.5 document is written as 0.5.0.
generatedBy string Yes Information about the tool or subject that generated the document, usually including the product name and version.
blocks array<Block> Yes Mega Blocks referenced by the document. This can be an empty array.
annotations array<Annotation> Yes Annotation objects. This can be an empty array.
extensions array<string> No Extension declarations used by the document. See Extensions.

Block

Block represents a Mega Block referenced by an EMA document and its coordinate information.

Field Type Required Description
id UUID string Yes Unique identifier of the Mega Block. The value returned by the EasyAR Mega service must be used.
timestamp date-time string Yes Last modification time of the Mega Block. The value returned by the EasyAR Mega service must be used. See Format conventions.
location Location No WGS 84 geographic location of the Mega Block origin.
transform Transform Yes Transform of the Mega Block relative to the EMA scene root coordinate system.
keepTransform boolean Yes Whether to keep and apply the transform recorded in the document. true means keeping the manually adjusted transform.

Mega Block example:

{
  "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
  "timestamp": "2026-08-12T00:00:00Z",
  "location": {
    "latitude": 31.2304,
    "longitude": 121.4737,
    "altitude": 5.5
  },
  "transform": {
    "position": { "x": 0.0, "y": 0.0, "z": 0.0 },
    "rotation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 },
    "scale": { "x": 1.0, "y": 1.0, "z": 1.0 }
  },
  "keepTransform": true
}

Annotation

Annotation represents an annotation in an EMA document.

Field Type Required Description
type string Yes Annotation type. The value is node or relationship.
id UUID string Yes Unique identifier of the annotation. IDs in annotations should be unique.
timestamp date-time string Yes Last modification time of the annotation. See Format conventions.
featureType string No Feature type that the annotation belongs to.
properties object No Annotation properties and extension data.

Node

Node represents an annotation with a spatial position.

Field Type Required Description
type string Yes Fixed to node.
geometry string Yes Geometry type. The value is point or cube.
parent Parent Yes Reference coordinate system of the node annotation. It can reference a Mega Block or a WGS 84 geographic location; for product support of the latter, see WorldParent.
transform Transform Yes Transform of the node annotation relative to the reference coordinate system. Included fields are determined by geometry.

When geometry is point, it represents a position point. When geometry is cube, it represents a box-shaped area centered at the origin. See Transform for the requirements of different geometry types on the transform field.

Point annotation example:

{
  "type": "node",
  "id": "b62fd4b5-66aa-4418-a603-69ae6faedbe6",
  "timestamp": "2026-08-12T00:00:01Z",
  "geometry": "point",
  "parent": {
    "type": "block",
    "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
    "timestamp": "2026-08-12T00:00:00Z"
  },
  "transform": {
    "position": { "x": 1.0, "y": 2.0, "z": 3.0 }
  },
  "properties": {
    "name": "Entrance"
  }
}

Box area annotation example:

{
  "type": "node",
  "id": "76c0e24a-a01a-4a50-9246-e7d827c96b38",
  "timestamp": "2026-08-12T00:00:02Z",
  "geometry": "cube",
  "parent": {
    "type": "block",
    "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
    "timestamp": "2026-08-12T00:00:00Z"
  },
  "transform": {
    "position": { "x": 0.0, "y": 0.0, "z": 0.0 },
    "rotation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 },
    "scale": { "x": 0.5, "y": 1.75, "z": 0.5 }
  }
}

Relationship

Relationship represents a relationship between annotations, and can also be used to organize multiple annotations into a collection.

Field Type Required Description
type string Yes Fixed to relationship.
members array<UUID string> Yes Records member annotation IDs in order. Members can reference node or relationship annotations.

Relationship annotation example:

{
  "type": "relationship",
  "id": "b7cf28e4-041e-460e-81cf-a0591c09faee",
  "timestamp": "2026-08-12T00:00:03Z",
  "members": [
    "b62fd4b5-66aa-4418-a603-69ae6faedbe6",
    "76c0e24a-a01a-4a50-9246-e7d827c96b38"
  ],
  "properties": {
    "name": "Annotation Group",
    "isDirected": false
  }
}

Parent

Parent represents the reference coordinate system to which a Node is attached, and determines the interpretation basis of the Node spatial transform.

BlockParent

BlockParent represents a reference coordinate system based on a Mega Block.

Field Type Required Description
type string Yes Fixed to block.
id UUID string Yes ID of the referenced Mega Block. This ID should exist in blocks of the root object.
timestamp date-time string Yes Modification time of the Mega Block referenced when the annotation was created or updated. See Format conventions.

WorldParent

WorldParent represents a world reference coordinate system whose origin is a WGS 84 geographic location.

Field Type Required Description
type string Yes Fixed to world.
location Location Yes WGS 84 geographic location of the reference coordinate system origin of the node annotation.
Warning

EMA 0.5 defines the structure where parent.type is world, but EasyAR Mega Studio 2.13 and versions after EasyAR Sense Unity Plugin 4003 have removed the related features. The format definition does not mean these product versions support using WorldParent.

Coordinates and basic types

Location

Location represents a WGS 84 geographic location.

Field Type Required Description
latitude number Yes Latitude, a 64-bit floating-point number expressed in decimal degrees.
longitude number Yes Longitude, a 64-bit floating-point number expressed in decimal degrees.
altitude number Yes Altitude, a 64-bit floating-point number in meters.

Transform

Transform represents the spatial transform of an object relative to a reference coordinate system.

Field Type Required Description
position Vector3F Yes Position relative to the reference coordinate system.
rotation Vector4F Conditional Rotation relative to the reference coordinate system.
scale Vector3F Conditional Scale relative to the reference coordinate system.

The requirements for each field in different use cases are as follows:

Use case position rotation scale
Mega Block Required Required Required
Annotation whose geometry is point Required Omitted Omitted
Annotation whose geometry is cube Required Required Required

Vector3F

Vector3F represents a three-dimensional vector used to record position and scale.

Field Type Required Description
x number Yes x-axis component, a 32-bit floating-point number.
y number Yes y-axis component, a 32-bit floating-point number.
z number Yes z-axis component, a 32-bit floating-point number.

Vector4F

Vector4F represents a quaternion used to record rotation.

Field Type Required Description
x number Yes x component of the quaternion, a 32-bit floating-point number.
y number Yes y component of the quaternion, a 32-bit floating-point number.
z number Yes z component of the quaternion, a 32-bit floating-point number.
w number Yes w component of the quaternion, a 32-bit floating-point number.

Properties

properties stores common properties, feature properties, and extension data of annotations. This field is a key-value object, and the value can be any JSON value.

EMA 0.5 defines the following common properties:

Property Applicable object Type Required Description
name node, relationship string No Display name of the annotation.
isDirected relationship boolean No Whether the relationship is directed. If not specified, it is true.
category relationship string No Relationship category.

Feature types

featureType specifies the feature type that the annotation participates in. Each feature type defines the structure, relationship, and dedicated properties of related annotations.

A navigation point graph represents navigation points in space, routes connecting navigation points, and the network composed of them. It can express routes and connectivity relationships. All annotations that compose a navigation point graph set featureType to navPointGraph.

The navigation point graph consists of three types of annotations:

Object Structure requirement
Navigation point type is node, and geometry is point.
Route type is relationship, and members reference two navigation points in order.
Network type is relationship, and members reference navigation points and routes included in the network.

Relationship annotations in a navigation point graph use the following properties properties:

Property Applicable object Type Required Description
category Route, network string Yes Distinguishes relationship types: route is route, and network is network.
isDirected Route boolean No true means from the first navigation point in members to the second; false means undirected.
weight Route number No Route weight, a 32-bit floating-point number. The specific meaning is defined by the application that uses the navigation point graph.

Navigation point graph annotation example:

[
  {
    "type": "node",
    "id": "25634f2e-c42d-4163-84c4-86757e8f6e8f",
    "timestamp": "2026-08-12T00:00:00Z",
    "featureType": "navPointGraph",
    "geometry": "point",
    "parent": {
      "type": "block",
      "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
      "timestamp": "2026-08-12T00:00:00Z"
    },
    "transform": {
      "position": { "x": 0.0, "y": 0.0, "z": 0.0 }
    }
  },
  {
    "type": "node",
    "id": "fa144e57-c388-4673-a940-9a3f904247c5",
    "timestamp": "2026-08-12T00:00:01Z",
    "featureType": "navPointGraph",
    "geometry": "point",
    "parent": {
      "type": "block",
      "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
      "timestamp": "2026-08-12T00:00:00Z"
    },
    "transform": {
      "position": { "x": 0.0, "y": 0.0, "z": 0.0 }
    }
  },
  {
    "type": "relationship",
    "id": "455427a3-b68d-4237-a78f-22213de89dc8",
    "timestamp": "2026-08-12T00:00:02Z",
    "featureType": "navPointGraph",
    "members": [
      "25634f2e-c42d-4163-84c4-86757e8f6e8f",
      "fa144e57-c388-4673-a940-9a3f904247c5"
    ],
    "properties": {
      "category": "route",
      "isDirected": true,
      "weight": 1.0
    }
  },
  {
    "type": "relationship",
    "id": "b579c5fe-e574-410b-853f-77c985966d0f",
    "timestamp": "2026-08-12T00:00:03Z",
    "featureType": "navPointGraph",
    "members": [
      "25634f2e-c42d-4163-84c4-86757e8f6e8f",
      "fa144e57-c388-4673-a940-9a3f904247c5",
      "455427a3-b68d-4237-a78f-22213de89dc8"
    ],
    "properties": {
      "category": "network"
    }
  }
]

Extensions

Extensions are used to add custom data to annotations without changing the EMA 0.5 core structure.

The root object's extensions array declares the extensions used by the document. Each item uses the following format:

PROVIDER:NAME#MAJOR.MINOR.PATCH
  • PROVIDER is the extension provider name.
  • NAME is the extension name.
  • The version consists of three non-negative integers.
  • PROVIDER and NAME must not contain : or #.
  • The same PROVIDER:NAME is declared only once in extensions.

Extension data is stored in the annotation's properties, with the property name PROVIDER:NAME and without the version number. The extension value can be any JSON value. A JSON object is recommended so that fields can be added later.

Extension declaration and data example:

{
  "version": "0.5.0",
  "generatedBy": "Sample Producer 1.0.0",
  "extensions": [
    "SampleCompany:SampleExtension#1.0.0"
  ],
  "blocks": [],
  "annotations": [
    {
      "type": "relationship",
      "id": "15da6815-174a-4963-ac27-6dc97f324474",
      "timestamp": "2026-08-12T00:00:04Z",
      "members": [],
      "properties": {
        "SampleCompany:SampleExtension": {
          "label": "sample",
          "priority": 10
        }
      }
    }
  ]
}

Consistency requirements

Producers should ensure that:

  • Mega Block IDs and annotation IDs are unique in their respective collections.
  • When parent.type is block, parent.id references an existing Mega Block in blocks.
  • When type is relationship, IDs in members reference existing annotations in annotations.
  • Extension properties used in properties have corresponding declarations in extensions.

Consumers can ignore ordinary fields they do not recognize. Unrecognized type, parent.type, or geometry should be treated as unsupported data.

Complete example

Example of a complete EMA document containing extension data:

{
  "version": "0.5.0",
  "generatedBy": "EasyAR Mega Support 2.14.0",
  "extensions": [
    "SampleCompany:SampleExtension#1.0.0"
  ],
  "blocks": [
    {
      "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
      "timestamp": "2026-08-12T00:00:00Z",
      "location": {
        "latitude": 31.2304,
        "longitude": 121.4737,
        "altitude": 5.5
      },
      "transform": {
        "position": { "x": 0.0, "y": 0.0, "z": 0.0 },
        "rotation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 },
        "scale": { "x": 1.0, "y": 1.0, "z": 1.0 }
      },
      "keepTransform": true
    }
  ],
  "annotations": [
    {
      "type": "node",
      "id": "b62fd4b5-66aa-4418-a603-69ae6faedbe6",
      "timestamp": "2026-08-12T00:00:01Z",
      "geometry": "point",
      "parent": {
        "type": "block",
        "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
        "timestamp": "2026-08-12T00:00:00Z"
      },
      "transform": {
        "position": { "x": 1.0, "y": 2.0, "z": 3.0 }
      },
      "properties": {
        "name": "Entrance",
        "SampleCompany:SampleExtension": {
          "label": "sample",
          "priority": 10
        }
      }
    },
    {
      "type": "node",
      "id": "76c0e24a-a01a-4a50-9246-e7d827c96b38",
      "timestamp": "2026-08-12T00:00:02Z",
      "geometry": "cube",
      "parent": {
        "type": "block",
        "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
        "timestamp": "2026-08-12T00:00:00Z"
      },
      "transform": {
        "position": { "x": 0.0, "y": 0.0, "z": 0.0 },
        "rotation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 },
        "scale": { "x": 0.5, "y": 1.75, "z": 0.5 }
      },
      "properties": {
        "name": "Display Area"
      }
    },
    {
      "type": "relationship",
      "id": "b7cf28e4-041e-460e-81cf-a0591c09faee",
      "timestamp": "2026-08-12T00:00:03Z",
      "members": [
        "b62fd4b5-66aa-4418-a603-69ae6faedbe6",
        "76c0e24a-a01a-4a50-9246-e7d827c96b38"
      ],
      "properties": {
        "name": "Tour Area",
        "isDirected": false
      }
    }
  ]
}