Table of Contents

Formato EasyAR Mega Annotation 0.5

Este documento define a especificação do formato EMA 0.5.

Antes de começar

Neste documento, "produtor" refere-se a um programa que gera dados EMA, e "consumidor" a um programa que lê dados EMA.

Convenções do formato

  • Arquivos EMA usam codificação UTF-8 e seguem a sintaxe JSON definida pela RFC 8259.
  • Nomes de campos no mesmo objeto não devem ser duplicados.
  • Nomes de campos diferenciam maiúsculas de minúsculas. Os definidos neste documento devem usar as formas indicadas nas tabelas e exemplos.
  • Campos obrigatórios devem existir e usar os tipos definidos nas tabelas. Campos opcionais podem ser omitidos quando não têm valor.
  • UUIDs são escritos como strings com hifens, por exemplo 123e4567-e89b-12d3-a456-426614174000.
  • Carimbos de data/hora usam strings de data e hora UTC no formato YYYY-MM-DDThh:mm:ssZ, com precisão de segundos. Por exemplo, 2026-08-12T00:00:00Z. Esse formato segue a representação UTC definida por W3C Date and Time Formats.
  • Transformações de coordenadas usam um sistema OpenGL de mão direita: +X para a direita, +Y para cima e +Z para trás.

Estrutura do documento

O objeto raiz de um documento EMA contém a versão do formato, o gerador, declarações de extensão, lista de Mega Blocks e lista de anotações.

Exemplo de estrutura do objeto raiz EMA:

{
  "version": "0.5.0",
  "generatedBy": "EasyAR Mega Support 2.14.0",
  "blocks": [],
  "annotations": [],
  "extensions": []
}
Campo Tipo Obrigatório Descrição
version string Sim Versão do formato EMA. Um documento 0.5 é escrito como 0.5.0.
generatedBy string Sim Informações sobre a ferramenta ou entidade que gerou o documento, geralmente incluindo nome do produto e versão.
blocks array<Block> Sim Mega Blocks referenciados pelo documento. Pode ser um array vazio.
annotations array<Annotation> Sim Objetos de anotação. Pode ser um array vazio.
extensions array<string> Não Declarações de extensão usadas pelo documento. Consulte Extensões.

Block

Block representa um Mega Block referenciado por um documento EMA e suas informações de coordenadas.

Campo Tipo Obrigatório Descrição
id UUID string Sim Identificador único do Mega Block. O valor retornado pelo serviço EasyAR Mega deve ser usado.
timestamp date-time string Sim Hora da última modificação do Mega Block. O valor retornado pelo serviço EasyAR Mega deve ser usado. Consulte Convenções do formato.
location Location Não Localização geográfica WGS 84 da origem do Mega Block.
transform Transform Sim Transformação do Mega Block relativa ao sistema de coordenadas raiz da cena EMA.
keepTransform boolean Sim Indica se o transform registrado no documento deve ser mantido e aplicado. true significa manter a transformação ajustada manualmente.

Exemplo 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 uma anotação em um documento EMA.

Campo Tipo Obrigatório Descrição
type string Sim Tipo de anotação. O valor é node ou relationship.
id UUID string Sim Identificador único da anotação. IDs em annotations devem ser únicos.
timestamp date-time string Sim Hora da última modificação da anotação. Consulte Convenções do formato.
featureType string Não Tipo de recurso ao qual a anotação pertence.
properties object Não Propriedades da anotação e dados de extensão.

Node

Node representa uma anotação com posição espacial.

Campo Tipo Obrigatório Descrição
type string Sim Fixo em node.
geometry string Sim Tipo de geometria. O valor é point ou cube.
parent Parent Sim Sistema de coordenadas de referência da anotação node. Pode referenciar um Mega Block ou uma localização geográfica WGS 84; para suporte do produto ao segundo caso, consulte WorldParent.
transform Transform Sim Transformação da anotação node relativa ao sistema de coordenadas de referência. Os campos incluídos são determinados por geometry.

Quando geometry é point, representa um ponto de posição. Quando é cube, representa uma área em forma de caixa centrada na origem. Consulte Transform para requisitos de transform.

Exemplo de anotação de ponto:

{
  "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"
  }
}

Exemplo de anotação de área em caixa:

{
  "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 uma relação entre anotações e também pode organizar várias anotações em uma coleção.

Campo Tipo Obrigatório Descrição
type string Sim Fixo em relationship.
members array<UUID string> Sim Registra em ordem os IDs das anotações membros. Membros podem referenciar anotações node ou relationship.

Exemplo de anotação de relacionamento:

{
  "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 o sistema de coordenadas de referência ao qual um Node está ligado e determina a base de interpretação de sua transformação espacial.

BlockParent

BlockParent representa um sistema de coordenadas de referência baseado em um Mega Block.

Campo Tipo Obrigatório Descrição
type string Sim Fixo em block.
id UUID string Sim ID do Mega Block referenciado. Esse ID deve existir em blocks do objeto raiz.
timestamp date-time string Sim Hora de modificação do Mega Block referenciado quando a anotação foi criada ou atualizada. Consulte Convenções do formato.

WorldParent

WorldParent representa um sistema mundial de coordenadas de referência cuja origem é uma localização WGS 84.

Campo Tipo Obrigatório Descrição
type string Sim Fixo em world.
location Location Sim Localização geográfica WGS 84 da origem do sistema de coordenadas de referência da anotação node.
Aviso

EMA 0.5 define a estrutura em que parent.type é world, mas o EasyAR Mega Studio 2.13 e versões após o EasyAR Sense Unity Plugin 4003 removeram os recursos relacionados. A definição do formato não significa que essas versões do produto suportem o uso de WorldParent.

Coordenadas e tipos básicos

Location

Location representa uma localização geográfica WGS 84.

Campo Tipo Obrigatório Descrição
latitude number Sim Latitude, um número de ponto flutuante de 64 bits expresso em graus decimais.
longitude number Sim Longitude, um número de ponto flutuante de 64 bits expresso em graus decimais.
altitude number Sim Altitude, um número de ponto flutuante de 64 bits em metros.

Transform

Transform representa a transformação espacial de um objeto em relação a um sistema de coordenadas de referência.

Campo Tipo Obrigatório Descrição
position Vector3F Sim Posição relativa ao sistema de coordenadas de referência.
rotation Vector4F Condicional Rotação relativa ao sistema de coordenadas de referência.
scale Vector3F Condicional Escala relativa ao sistema de coordenadas de referência.

Os requisitos de cada campo em diferentes casos de uso são os seguintes:

Caso de uso position rotation scale
Mega Block Obrigatório Obrigatório Obrigatório
Anotação cujo geometry é point Obrigatório Omitido Omitido
Anotação cujo geometry é cube Obrigatório Obrigatório Obrigatório

Vector3F

Vector3F representa um vetor tridimensional usado para registrar posição e escala.

Campo Tipo Obrigatório Descrição
x number Sim Componente do eixo x, um número de ponto flutuante de 32 bits.
y number Sim Componente do eixo y, um número de ponto flutuante de 32 bits.
z number Sim Componente do eixo z, um número de ponto flutuante de 32 bits.

Vector4F

Vector4F representa um quaternion usado para registrar rotação.

Campo Tipo Obrigatório Descrição
x number Sim Componente x do quaternion, um número de ponto flutuante de 32 bits.
y number Sim Componente y do quaternion, um número de ponto flutuante de 32 bits.
z number Sim Componente z do quaternion, um número de ponto flutuante de 32 bits.
w number Sim Componente w do quaternion, um número de ponto flutuante de 32 bits.

Propriedades

properties armazena propriedades comuns, propriedades de recurso e dados de extensão das anotações. Esse campo é um objeto chave-valor, e o valor pode ser qualquer valor JSON.

EMA 0.5 define as seguintes propriedades comuns:

Propriedade Objeto aplicável Tipo Obrigatório Descrição
name node, relationship string Não Nome de exibição da anotação.
isDirected relationship boolean Não Indica se o relacionamento é direcionado. Se não especificado, é true.
category relationship string Não Categoria do relacionamento.

Tipos de recurso

featureType especifica o tipo de recurso do qual a anotação participa. Cada tipo define a estrutura, o relacionamento e as propriedades dedicadas das anotações relacionadas.

Grafo de pontos de navegação

Um grafo de pontos de navegação representa pontos de navegação no espaço, rotas que conectam pontos de navegação e a rede composta por eles. Ele pode expressar rotas e relações de conectividade. Todas as anotações que compõem o grafo definem featureType como navPointGraph.

O grafo de pontos de navegação consiste em três tipos de anotações:

Objeto Requisito de estrutura
Ponto de navegação type é node, e geometry é point.
Rota type é relationship, e members referencia dois pontos de navegação em ordem.
Rede type é relationship, e members referencia pontos de navegação e rotas incluídos na rede.

Anotações de relacionamento em um grafo de pontos de navegação usam as seguintes propriedades de properties:

Propriedade Objeto aplicável Tipo Obrigatório Descrição
category Rota, rede string Sim Distingue tipos de relacionamento: rota é route, e rede é network.
isDirected Rota boolean Não true significa do primeiro ponto de navegação em members para o segundo; false significa não direcionado.
weight Rota number Não Peso da rota, um número de ponto flutuante de 32 bits. O significado específico é definido pelo aplicativo que usa o grafo de pontos de navegação.

Exemplo de anotação de grafo de pontos de navegação:

[
  {
    "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"
    }
  }
]

Extensões

Extensões adicionam dados personalizados às anotações sem alterar a estrutura central do EMA 0.5.

O array extensions do objeto raiz declara as extensões usadas pelo documento. Cada item usa o seguinte formato:

PROVIDER:NAME#MAJOR.MINOR.PATCH
  • PROVIDER é o nome do provedor da extensão.
  • NAME é o nome da extensão.
  • A versão consiste em três inteiros não negativos.
  • PROVIDER e NAME não devem conter : ou #.
  • O mesmo PROVIDER:NAME é declarado apenas uma vez em extensions.

Dados de extensão são armazenados em properties da anotação, com o nome de propriedade PROVIDER:NAME e sem o número da versão. O valor da extensão pode ser qualquer valor JSON. Recomenda-se um objeto JSON para que campos possam ser adicionados depois.

Exemplo de declaração e dados de extensão:

{
  "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 consistência

Produtores devem garantir que:

  • IDs de Mega Block e IDs de anotação são únicos em suas respectivas coleções.
  • Quando parent.type é block, parent.id referencia um Mega Block existente em blocks.
  • Quando type é relationship, IDs em members referenciam anotações existentes em annotations.
  • Propriedades de extensão usadas em properties têm declarações correspondentes em extensions.

Consumidores podem ignorar campos comuns que não reconhecem. type, parent.type ou geometry desconhecidos devem ser tratados como dados não suportados.

Exemplo completo

Exemplo de documento EMA completo contendo dados de extensão:

{
  "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
      }
    }
  ]
}