Table of Contents

Formato EasyAR Mega Annotation 0.5

Questo documento definisce la specifica del formato EMA 0.5.

Prima di iniziare

In questo documento, "produttore" indica un programma che genera dati EMA, mentre "consumatore" indica un programma che legge dati EMA.

Convenzioni del formato

  • I file EMA usano la codifica UTF-8 e seguono la sintassi JSON definita da RFC 8259.
  • I nomi dei campi nello stesso oggetto non devono essere duplicati.
  • I nomi dei campi distinguono maiuscole e minuscole. Quelli definiti qui devono usare le forme indicate in tabelle ed esempi.
  • I campi obbligatori devono esistere e usare i tipi definiti nelle tabelle. I campi opzionali possono essere omessi se non hanno valore.
  • Gli UUID sono scritti come stringhe con trattini, ad esempio 123e4567-e89b-12d3-a456-426614174000.
  • I timestamp usano stringhe data-ora UTC nel formato YYYY-MM-DDThh:mm:ssZ, con precisione al secondo. Ad esempio 2026-08-12T00:00:00Z. Questo formato segue la rappresentazione UTC definita da W3C Date and Time Formats.
  • Le trasformazioni usano un sistema di coordinate OpenGL destrorso: +X a destra, +Y in alto e +Z all'indietro.

Struttura del documento

L'oggetto radice di un documento EMA contiene versione del formato, generatore, dichiarazioni di estensione, lista dei Mega Block e lista delle annotazioni.

Esempio di struttura dell'oggetto radice EMA:

{
  "version": "0.5.0",
  "generatedBy": "EasyAR Mega Support 2.14.0",
  "blocks": [],
  "annotations": [],
  "extensions": []
}
Campo Tipo Obbligatorio Descrizione
version string Versione del formato EMA. Un documento 0.5 si scrive come 0.5.0.
generatedBy string Informazioni sullo strumento o soggetto che ha generato il documento, di solito con nome prodotto e versione.
blocks array<Block> Mega Block referenziati dal documento. Può essere un array vuoto.
annotations array<Annotation> Oggetti annotazione. Può essere un array vuoto.
extensions array<string> No Dichiarazioni di estensione usate dal documento. Vedere Estensioni.

Block

Block rappresenta un Mega Block referenziato da un documento EMA e le relative informazioni di coordinate.

Campo Tipo Obbligatorio Descrizione
id UUID string Identificatore univoco del Mega Block. Deve essere usato il valore restituito dal servizio EasyAR Mega.
timestamp date-time string Ora dell'ultima modifica del Mega Block. Deve essere usato il valore restituito dal servizio EasyAR Mega. Vedere Convenzioni del formato.
location Location No Posizione geografica WGS 84 dell'origine del Mega Block.
transform Transform Trasformazione del Mega Block rispetto al sistema di coordinate radice della scena EMA.
keepTransform boolean Indica se mantenere e applicare il transform registrato nel documento. true significa mantenere la trasformazione regolata manualmente.

Esempio di 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 rappresenta un'annotazione in un documento EMA.

Campo Tipo Obbligatorio Descrizione
type string Tipo di annotazione. Il valore è node o relationship.
id UUID string Identificatore univoco dell'annotazione. Gli ID in annotations devono essere univoci.
timestamp date-time string Ora dell'ultima modifica dell'annotazione. Vedere Convenzioni del formato.
featureType string No Tipo di funzionalità a cui appartiene l'annotazione.
properties object No Proprietà dell'annotazione e dati di estensione.

Node

Node rappresenta un'annotazione con posizione spaziale.

Campo Tipo Obbligatorio Descrizione
type string Fisso a node.
geometry string Tipo di geometria. Il valore è point o cube.
parent Parent Sistema di coordinate di riferimento dell'annotazione node. Può fare riferimento a un Mega Block o a una posizione geografica WGS 84; per il supporto del prodotto del secondo caso, vedere WorldParent.
transform Transform Trasformazione dell'annotazione node rispetto al sistema di coordinate di riferimento. I campi inclusi sono determinati da geometry.

Quando geometry è point, rappresenta un punto di posizione. Quando è cube, rappresenta un'area a scatola centrata sull'origine. Vedere Transform per i requisiti di transform per i vari tipi di geometria.

Esempio di annotazione 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"
  }
}

Esempio di annotazione di area a scatola:

{
  "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 rappresenta una relazione tra annotazioni e può anche organizzare più annotazioni in una raccolta.

Campo Tipo Obbligatorio Descrizione
type string Fisso a relationship.
members array<UUID string> Registra in ordine gli ID delle annotazioni membro. I membri possono fare riferimento ad annotazioni node o relationship.

Esempio di annotazione relazione:

{
  "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 rappresenta il sistema di coordinate di riferimento a cui è collegato un Node e determina la base di interpretazione della sua trasformazione spaziale.

BlockParent

BlockParent rappresenta un sistema di coordinate di riferimento basato su un Mega Block.

Campo Tipo Obbligatorio Descrizione
type string Fisso a block.
id UUID string ID del Mega Block referenziato. Questo ID deve esistere in blocks dell'oggetto radice.
timestamp date-time string Ora di modifica del Mega Block referenziato quando l'annotazione è stata creata o aggiornata. Vedere Convenzioni del formato.

WorldParent

WorldParent rappresenta un sistema di coordinate di riferimento globale con origine in una posizione WGS 84.

Campo Tipo Obbligatorio Descrizione
type string Fisso a world.
location Location Posizione geografica WGS 84 dell'origine del sistema di coordinate di riferimento dell'annotazione node.
Avvertenza

EMA 0.5 definisce la struttura in cui parent.type è world, ma EasyAR Mega Studio 2.13 e le versioni successive a EasyAR Sense Unity Plugin 4003 hanno rimosso le funzionalità correlate. La definizione del formato non significa che tali versioni del prodotto supportino l'uso di WorldParent.

Coordinate e tipi di base

Location

Location rappresenta una posizione geografica WGS 84.

Campo Tipo Obbligatorio Descrizione
latitude number Latitudine, numero in virgola mobile a 64 bit espresso in gradi decimali.
longitude number Longitudine, numero in virgola mobile a 64 bit espresso in gradi decimali.
altitude number Altitudine, numero in virgola mobile a 64 bit in metri.

Transform

Transform rappresenta la trasformazione spaziale di un oggetto rispetto a un sistema di coordinate di riferimento.

Campo Tipo Obbligatorio Descrizione
position Vector3F Posizione rispetto al sistema di coordinate di riferimento.
rotation Vector4F Condizionale Rotazione rispetto al sistema di coordinate di riferimento.
scale Vector3F Condizionale Scala rispetto al sistema di coordinate di riferimento.

I requisiti di ciascun campo nei diversi casi d'uso sono i seguenti:

Caso d'uso position rotation scale
Mega Block Obbligatorio Obbligatorio Obbligatorio
Annotazione il cui geometry è point Obbligatorio Omettere Omettere
Annotazione il cui geometry è cube Obbligatorio Obbligatorio Obbligatorio

Vector3F

Vector3F rappresenta un vettore tridimensionale usato per registrare posizione e scala.

Campo Tipo Obbligatorio Descrizione
x number Componente dell'asse x, numero in virgola mobile a 32 bit.
y number Componente dell'asse y, numero in virgola mobile a 32 bit.
z number Componente dell'asse z, numero in virgola mobile a 32 bit.

Vector4F

Vector4F rappresenta un quaternione usato per registrare la rotazione.

Campo Tipo Obbligatorio Descrizione
x number Componente x del quaternione, numero in virgola mobile a 32 bit.
y number Componente y del quaternione, numero in virgola mobile a 32 bit.
z number Componente z del quaternione, numero in virgola mobile a 32 bit.
w number Componente w del quaternione, numero in virgola mobile a 32 bit.

Proprietà

properties memorizza proprietà comuni, proprietà di funzionalità e dati di estensione delle annotazioni. Questo campo è un oggetto chiave-valore e il valore può essere qualsiasi valore JSON.

EMA 0.5 definisce le seguenti proprietà comuni:

Proprietà Oggetto applicabile Tipo Obbligatorio Descrizione
name node, relationship string No Nome visualizzato dell'annotazione.
isDirected relationship boolean No Indica se la relazione è diretta. Se non specificato, è true.
category relationship string No Categoria della relazione.

Tipi di funzionalità

featureType specifica il tipo di funzionalità a cui partecipa l'annotazione. Ogni tipo definisce struttura, relazione e proprietà dedicate delle annotazioni correlate.

Grafo di punti di navigazione

Un grafo di punti di navigazione rappresenta punti di navigazione nello spazio, percorsi che li collegano e la rete composta da essi. Può esprimere percorsi e relazioni di connettività. Tutte le annotazioni che compongono il grafo impostano featureType su navPointGraph.

Il grafo di punti di navigazione è composto da tre tipi di annotazioni:

Oggetto Requisito strutturale
Punto di navigazione type è node e geometry è point.
Percorso type è relationship e members fa riferimento a due punti di navigazione in ordine.
Rete type è relationship e members fa riferimento a punti di navigazione e percorsi inclusi nella rete.

Le annotazioni relazione in un grafo di punti di navigazione usano le seguenti proprietà properties:

Proprietà Oggetto applicabile Tipo Obbligatorio Descrizione
category Percorso, rete string Distingue i tipi di relazione: il percorso è route e la rete è network.
isDirected Percorso boolean No true significa dal primo punto di navigazione in members al secondo; false significa non diretto.
weight Percorso number No Peso del percorso, numero in virgola mobile a 32 bit. Il significato specifico è definito dall'applicazione che usa il grafo di punti di navigazione.

Esempio di annotazione del grafo di punti di navigazione:

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

Estensioni

Le estensioni aggiungono dati personalizzati alle annotazioni senza cambiare la struttura core di EMA 0.5.

L'array extensions dell'oggetto radice dichiara le estensioni usate dal documento. Ogni elemento usa il seguente formato:

PROVIDER:NAME#MAJOR.MINOR.PATCH
  • PROVIDER è il nome del provider dell'estensione.
  • NAME è il nome dell'estensione.
  • La versione è composta da tre interi non negativi.
  • PROVIDER e NAME non devono contenere : o #.
  • Lo stesso PROVIDER:NAME viene dichiarato una sola volta in extensions.

I dati di estensione sono archiviati in properties dell'annotazione, con il nome proprietà PROVIDER:NAME e senza numero di versione. Il valore dell'estensione può essere qualsiasi valore JSON. È consigliato un oggetto JSON per poter aggiungere campi in seguito.

Esempio di dichiarazione e dati di estensione:

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

Requisiti di coerenza

I produttori devono assicurarsi che:

  • Gli ID dei Mega Block e delle annotazioni sono univoci nelle rispettive raccolte.
  • Quando parent.type è block, parent.id fa riferimento a un Mega Block esistente in blocks.
  • Quando type è relationship, gli ID in members fanno riferimento ad annotazioni esistenti in annotations.
  • Le proprietà di estensione usate in properties hanno dichiarazioni corrispondenti in extensions.

I consumatori possono ignorare i campi ordinari non riconosciuti. type, parent.type o geometry non riconosciuti vanno trattati come dati non supportati.

Esempio completo

Esempio di documento EMA completo con dati di estensione:

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