Formato EasyAR Mega Annotation 0.5
Este documento define la especificación del formato EMA 0.5.
Antes de empezar
- Lea la introducción al formato EasyAR Mega Annotation para conocer los usos y escenarios aplicables de EMA.
En este documento, "productor" se refiere al programa que genera datos EMA, y "consumidor" al programa que lee datos EMA.
Convenciones del formato
- Los archivos EMA usan codificación UTF-8 y siguen la sintaxis JSON definida por RFC 8259.
- Los nombres de campo dentro del mismo objeto no deben repetirse.
- Los nombres de campo distinguen mayúsculas y minúsculas. Los definidos en este documento deben usar las formas de las tablas y ejemplos.
- Los campos obligatorios deben existir y usar los tipos definidos en las tablas. Los opcionales pueden omitirse si no tienen valor.
- Los UUID se escriben como cadenas con guiones, por ejemplo
123e4567-e89b-12d3-a456-426614174000. - Las marcas de tiempo usan cadenas de fecha y hora UTC con el formato
YYYY-MM-DDThh:mm:ssZ, con precisión de segundos. Por ejemplo,2026-08-12T00:00:00Z. Este formato sigue la representación UTC definida por W3C Date and Time Formats. - Las transformaciones de coordenadas usan un sistema OpenGL de mano derecha: +X hacia la derecha, +Y hacia arriba y +Z hacia atrás.
Estructura del documento
El objeto raíz de un documento EMA contiene la versión del formato, el generador, las declaraciones de extensiones, la lista de Mega Block y la lista de anotaciones.
Ejemplo de estructura del objeto raíz EMA:
{
"version": "0.5.0",
"generatedBy": "EasyAR Mega Support 2.14.0",
"blocks": [],
"annotations": [],
"extensions": []
}
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
version |
string | Sí | Versión del formato EMA. Un documento 0.5 se escribe como 0.5.0. |
generatedBy |
string | Sí | Información sobre la herramienta o entidad que generó el documento, normalmente con nombre de producto y versión. |
blocks |
array<Block> | Sí | Mega Blocks referenciados por el documento. Puede ser un arreglo vacío. |
annotations |
array<Annotation> | Sí | Objetos de anotación. Puede ser un arreglo vacío. |
extensions |
array<string> | No | Declaraciones de extensión usadas por el documento. Consulte Extensiones. |
Block
Block representa un Mega Block referenciado por un documento EMA y su información de coordenadas.
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id |
UUID string | Sí | Identificador único del Mega Block. Debe usarse el valor devuelto por el servicio EasyAR Mega. |
timestamp |
date-time string | Sí | Hora de última modificación del Mega Block. Debe usarse el valor devuelto por el servicio EasyAR Mega. Consulte Convenciones del formato. |
location |
Location | No | Ubicación geográfica WGS 84 del origen del Mega Block. |
transform |
Transform | Sí | Transformación del Mega Block relativa al sistema de coordenadas raíz de la escena EMA. |
keepTransform |
boolean | Sí | Indica si se conserva y aplica el transform registrado en el documento. true significa conservar la transformación ajustada manualmente. |
Ejemplo de Mega Block:
{
"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 representa una anotación en un documento EMA.
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
type |
string | Sí | Tipo de anotación. El valor es node o relationship. |
id |
UUID string | Sí | Identificador único de la anotación. Los ID de annotations deben ser únicos. |
timestamp |
date-time string | Sí | Hora de última modificación de la anotación. Consulte Convenciones del formato. |
featureType |
string | No | Tipo de función al que pertenece la anotación. |
properties |
object | No | Propiedades de la anotación y datos de extensión. |
Node
Node representa una anotación con posición espacial.
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
type |
string | Sí | Fijo en node. |
geometry |
string | Sí | Tipo de geometría. El valor es point o cube. |
parent |
Parent | Sí | Sistema de coordenadas de referencia de la anotación node. Puede referenciar un Mega Block o una ubicación geográfica WGS 84; para el soporte del producto en este último caso, consulte WorldParent. |
transform |
Transform | Sí | Transformación de la anotación node relativa al sistema de coordenadas de referencia. Los campos incluidos los determina geometry. |
Cuando geometry es point, representa un punto de posición. Cuando es cube, representa un área con forma de caja centrada en el origen. Consulte Transform para los requisitos de transform según la geometría.
Ejemplo de anotación de punto:
{
"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"
}
}
Ejemplo de anotación de área en caja:
{
"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 representa una relación entre anotaciones y también puede usarse para organizar varias anotaciones en una colección.
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
type |
string | Sí | Fijo en relationship. |
members |
array<UUID string> | Sí | Registra en orden los ID de las anotaciones miembro. Los miembros pueden referenciar anotaciones node o relationship. |
Ejemplo de anotación de relación:
{
"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 representa el sistema de coordenadas de referencia al que se adjunta un Node y determina la base de interpretación de su transformación espacial.
BlockParent
BlockParent representa un sistema de coordenadas de referencia basado en un Mega Block.
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
type |
string | Sí | Fijo en block. |
id |
UUID string | Sí | ID del Mega Block referenciado. Este ID debe existir en blocks del objeto raíz. |
timestamp |
date-time string | Sí | Hora de modificación del Mega Block referenciado cuando se creó o actualizó la anotación. Consulte Convenciones del formato. |
WorldParent
WorldParent representa un sistema mundial de coordenadas de referencia cuyo origen es una ubicación WGS 84.
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
type |
string | Sí | Fijo en world. |
location |
Location | Sí | Ubicación geográfica WGS 84 del origen del sistema de coordenadas de referencia de la anotación node. |
Advertencia
EMA 0.5 define la estructura donde parent.type es world, pero EasyAR Mega Studio 2.13 y las versiones posteriores a EasyAR Sense Unity Plugin 4003 eliminaron las funciones relacionadas. La definición del formato no significa que esas versiones del producto admitan el uso de WorldParent.
Coordenadas y tipos básicos
Location
Location representa una ubicación geográfica WGS 84.
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
latitude |
number | Sí | Latitud, número de coma flotante de 64 bits expresado en grados decimales. |
longitude |
number | Sí | Longitud, número de coma flotante de 64 bits expresado en grados decimales. |
altitude |
number | Sí | Altitud, número de coma flotante de 64 bits en metros. |
Transform
Transform representa la transformación espacial de un objeto relativa a un sistema de coordenadas de referencia.
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
position |
Vector3F | Sí | Posición relativa al sistema de coordenadas de referencia. |
rotation |
Vector4F | Condicional | Rotación relativa al sistema de coordenadas de referencia. |
scale |
Vector3F | Condicional | Escala relativa al sistema de coordenadas de referencia. |
Los requisitos de cada campo en los distintos casos de uso son los siguientes:
| Caso de uso | position |
rotation |
scale |
|---|---|---|---|
| Mega Block | Obligatorio | Obligatorio | Obligatorio |
Anotación cuyo geometry es point |
Obligatorio | Omitido | Omitido |
Anotación cuyo geometry es cube |
Obligatorio | Obligatorio | Obligatorio |
Vector3F
Vector3F representa un vector tridimensional usado para registrar posición y escala.
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
x |
number | Sí | Componente del eje x, número de coma flotante de 32 bits. |
y |
number | Sí | Componente del eje y, número de coma flotante de 32 bits. |
z |
number | Sí | Componente del eje z, número de coma flotante de 32 bits. |
Vector4F
Vector4F representa un cuaternión usado para registrar rotación.
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
x |
number | Sí | Componente x del cuaternión, número de coma flotante de 32 bits. |
y |
number | Sí | Componente y del cuaternión, número de coma flotante de 32 bits. |
z |
number | Sí | Componente z del cuaternión, número de coma flotante de 32 bits. |
w |
number | Sí | Componente w del cuaternión, número de coma flotante de 32 bits. |
Propiedades
properties almacena propiedades comunes, propiedades de función y datos de extensión de las anotaciones. Este campo es un objeto clave-valor, y el valor puede ser cualquier valor JSON.
EMA 0.5 define las siguientes propiedades comunes:
| Propiedad | Objeto aplicable | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
name |
node, relationship |
string | No | Nombre visible de la anotación. |
isDirected |
relationship |
boolean | No | Indica si la relación es dirigida. Si no se especifica, es true. |
category |
relationship |
string | No | Categoría de relación. |
Tipos de función
featureType especifica el tipo de función en el que participa la anotación. Cada tipo define la estructura, la relación y las propiedades dedicadas de las anotaciones relacionadas.
Grafo de puntos de navegación
Un grafo de puntos de navegación representa puntos de navegación en el espacio, rutas que los conectan y la red formada por ellos. Puede expresar rutas y relaciones de conectividad. Todas las anotaciones que forman el grafo establecen featureType en navPointGraph.
El grafo de puntos de navegación consta de tres tipos de anotaciones:
| Objeto | Requisito de estructura |
|---|---|
| Punto de navegación | type es node y geometry es point. |
| Ruta | type es relationship y members referencia dos puntos de navegación en orden. |
| Red | type es relationship y members referencia puntos de navegación y rutas incluidos en la red. |
Las anotaciones de relación en un grafo de puntos de navegación usan las siguientes propiedades de properties:
| Propiedad | Objeto aplicable | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
category |
Ruta, red | string | Sí | Distingue tipos de relación: la ruta es route y la red es network. |
isDirected |
Ruta | boolean | No | true significa desde el primer punto de navegación en members hacia el segundo; false significa no dirigido. |
weight |
Ruta | number | No | Peso de la ruta, número de coma flotante de 32 bits. El significado específico lo define la aplicación que usa el grafo de puntos de navegación. |
Ejemplo de anotación de grafo de puntos de navegación:
[
{
"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"
}
}
]
Extensiones
Las extensiones agregan datos personalizados a las anotaciones sin cambiar la estructura central de EMA 0.5.
El array extensions del objeto raíz declara las extensiones usadas por el documento. Cada elemento usa el siguiente formato:
PROVIDER:NAME#MAJOR.MINOR.PATCH
PROVIDERes el nombre del proveedor de la extensión.NAMEes el nombre de la extensión.- La versión consta de tres enteros no negativos.
PROVIDERyNAMEno deben contener:ni#.- El mismo
PROVIDER:NAMEse declara solo una vez enextensions.
Los datos de extensión se almacenan en properties de la anotación, con el nombre de propiedad PROVIDER:NAME y sin el número de versión. El valor de la extensión puede ser cualquier valor JSON. Se recomienda un objeto JSON para poder agregar campos más adelante.
Ejemplo de declaración y datos de extensión:
{
"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
}
}
}
]
}
Requisitos de coherencia
Los productores deben asegurarse de que:
- Los ID de Mega Block y de anotación son únicos en sus colecciones respectivas.
- Cuando
parent.typeesblock,parent.idreferencia un Mega Block existente enblocks. - Cuando
typeesrelationship, los ID demembersreferencian anotaciones existentes enannotations. - Las propiedades de extensión usadas en
propertiestienen declaraciones correspondientes enextensions.
Los consumidores pueden ignorar campos ordinarios no reconocidos. type, parent.type o geometry desconocidos deben tratarse como datos no compatibles.
Ejemplo completo
Ejemplo de documento EMA completo con datos de extensión:
{
"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
}
}
]
}