Table of Contents

Format EasyAR Mega Annotation 0.5

Ce document définit la spécification du format EMA 0.5.

Avant de commencer

Dans ce document, "producteur" désigne un programme qui génère des données EMA, et "consommateur" un programme qui lit des données EMA.

Conventions du format

  • Les fichiers EMA utilisent l'encodage UTF-8 et suivent la syntaxe JSON définie par RFC 8259.
  • Les noms de champs dans un même objet ne doivent pas être dupliqués.
  • Les noms de champs sont sensibles à la casse. Ceux définis ici doivent utiliser les formes indiquées dans les tableaux et exemples.
  • Les champs requis doivent exister et utiliser les types définis dans les tableaux. Les champs facultatifs peuvent être omis sans valeur.
  • Les UUID sont écrits sous forme de chaînes avec traits d'union, par exemple 123e4567-e89b-12d3-a456-426614174000.
  • Les horodatages utilisent des chaînes date-heure UTC au format YYYY-MM-DDThh:mm:ssZ, avec une précision à la seconde. Par exemple 2026-08-12T00:00:00Z. Ce format suit la représentation UTC définie par W3C Date and Time Formats.
  • Les transformations de coordonnées utilisent un repère OpenGL droitier: +X vers la droite, +Y vers le haut et +Z vers l'arrière.

Structure du document

L'objet racine d'un document EMA contient la version du format, le générateur, les déclarations d'extension, la liste des Mega Blocks et la liste des annotations.

Exemple de structure de l'objet racine EMA:

{
  "version": "0.5.0",
  "generatedBy": "EasyAR Mega Support 2.14.0",
  "blocks": [],
  "annotations": [],
  "extensions": []
}
Champ Type Requis Description
version string Oui Version du format EMA. Un document 0.5 s'écrit 0.5.0.
generatedBy string Oui Informations sur l'outil ou l'entité ayant généré le document, généralement avec nom du produit et version.
blocks array<Block> Oui Mega Blocks référencés par le document. Ce peut être un tableau vide.
annotations array<Annotation> Oui Objets d'annotation. Ce peut être un tableau vide.
extensions array<string> Non Déclarations d'extensions utilisées par le document. Voir Extensions.

Block

Block représente un Mega Block référencé par un document EMA et ses informations de coordonnées.

Champ Type Requis Description
id UUID string Oui Identifiant unique du Mega Block. La valeur renvoyée par le service EasyAR Mega doit être utilisée.
timestamp date-time string Oui Heure de dernière modification du Mega Block. La valeur renvoyée par le service EasyAR Mega doit être utilisée. Voir Conventions du format.
location Location Non Position géographique WGS 84 de l'origine du Mega Block.
transform Transform Oui Transformation du Mega Block par rapport au repère racine de la scène EMA.
keepTransform boolean Oui Indique s'il faut conserver et appliquer le transform enregistré dans le document. true signifie conserver la transformation ajustée manuellement.

Exemple 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 représente une annotation dans un document EMA.

Champ Type Requis Description
type string Oui Type d'annotation. La valeur est node ou relationship.
id UUID string Oui Identifiant unique de l'annotation. Les ID dans annotations doivent être uniques.
timestamp date-time string Oui Heure de dernière modification de l'annotation. Voir Conventions du format.
featureType string Non Type de fonctionnalité auquel appartient l'annotation.
properties object Non Propriétés de l'annotation et données d'extension.

Node

Node représente une annotation avec une position spatiale.

Champ Type Requis Description
type string Oui Fixé à node.
geometry string Oui Type de géométrie. La valeur est point ou cube.
parent Parent Oui Repère de référence de l'annotation node. Il peut référencer un Mega Block ou une position géographique WGS 84; pour la prise en charge produit de ce dernier cas, voir WorldParent.
transform Transform Oui Transformation de l'annotation node par rapport au repère de référence. Les champs inclus sont déterminés par geometry.

Lorsque geometry vaut point, il représente un point de position. Lorsqu'il vaut cube, il représente une zone en boîte centrée sur l'origine. Voir Transform pour les exigences du champ transform.

Exemple d'annotation de point:

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

Exemple d'annotation de zone en boîte:

{
  "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 représente une relation entre annotations et peut aussi organiser plusieurs annotations en collection.

Champ Type Requis Description
type string Oui Fixé à relationship.
members array<UUID string> Oui Enregistre dans l'ordre les ID des annotations membres. Les membres peuvent référencer des annotations node ou relationship.

Exemple d'annotation de relation:

{
  "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 représente le repère de référence auquel un Node est attaché et détermine la base d'interprétation de sa transformation spatiale.

BlockParent

BlockParent représente un repère de référence basé sur un Mega Block.

Champ Type Requis Description
type string Oui Fixé à block.
id UUID string Oui ID du Mega Block référencé. Cet ID doit exister dans blocks de l'objet racine.
timestamp date-time string Oui Heure de modification du Mega Block référencé lors de la création ou mise à jour de l'annotation. Voir Conventions du format.

WorldParent

WorldParent représente un repère mondial dont l'origine est une position géographique WGS 84.

Champ Type Requis Description
type string Oui Fixé à world.
location Location Oui Position géographique WGS 84 de l'origine du repère de référence de l'annotation node.
Avertissement

EMA 0.5 définit la structure où parent.type vaut world, mais EasyAR Mega Studio 2.13 et les versions postérieures à EasyAR Sense Unity Plugin 4003 ont supprimé les fonctionnalités associées. La définition du format ne signifie pas que ces versions du produit prennent en charge WorldParent.

Coordonnées et types de base

Location

Location représente une position géographique WGS 84.

Champ Type Requis Description
latitude number Oui Latitude, nombre à virgule flottante 64 bits exprimé en degrés décimaux.
longitude number Oui Longitude, nombre à virgule flottante 64 bits exprimé en degrés décimaux.
altitude number Oui Altitude, nombre à virgule flottante 64 bits en mètres.

Transform

Transform représente la transformation spatiale d'un objet par rapport à un repère de référence.

Champ Type Requis Description
position Vector3F Oui Position par rapport au repère de référence.
rotation Vector4F Conditionnel Rotation par rapport au repère de référence.
scale Vector3F Conditionnel Échelle par rapport au repère de référence.

Les exigences de chaque champ selon les cas d'utilisation sont les suivantes:

Cas d'utilisation position rotation scale
Mega Block Requis Requis Requis
geometry valant point Requis Omis Omis
geometry valant cube Requis Requis Requis

Vector3F

Vector3F représente un vecteur tridimensionnel utilisé pour enregistrer position et échelle.

Champ Type Requis Description
x number Oui Composante de l'axe x, nombre à virgule flottante 32 bits.
y number Oui Composante de l'axe y, nombre à virgule flottante 32 bits.
z number Oui Composante de l'axe z, nombre à virgule flottante 32 bits.

Vector4F

Vector4F représente un quaternion utilisé pour enregistrer la rotation.

Champ Type Requis Description
x number Oui Composante x du quaternion, nombre à virgule flottante 32 bits.
y number Oui Composante y du quaternion, nombre à virgule flottante 32 bits.
z number Oui Composante z du quaternion, nombre à virgule flottante 32 bits.
w number Oui Composante w du quaternion, nombre à virgule flottante 32 bits.

Propriétés

properties stocke les propriétés communes, les propriétés de fonctionnalité et les données d'extension des annotations. Ce champ est un objet clé-valeur, et la valeur peut être n'importe quelle valeur JSON.

EMA 0.5 définit les propriétés communes suivantes:

Propriété Objet applicable Type Requis Description
name node, relationship string Non Nom affiché de l'annotation.
isDirected relationship boolean Non Indique si la relation est dirigée. Si non spécifié, la valeur est true.
category relationship string Non Catégorie de relation.

Types de fonctionnalités

featureType spécifie le type de fonctionnalité auquel l'annotation participe. Chaque type définit la structure, la relation et les propriétés dédiées des annotations associées.

Graphe de points de navigation

Un graphe de points de navigation représente les points de navigation dans l'espace, les itinéraires qui les relient et le réseau qu'ils composent. Il peut exprimer les itinéraires et les relations de connectivité. Toutes les annotations qui le composent définissent featureType sur navPointGraph.

Le graphe de points de navigation se compose de trois types d'annotations:

Objet Exigence de structure
Point de navigation type vaut node, et geometry vaut point.
Itinéraire type vaut relationship, et members référence deux points de navigation dans l'ordre.
Réseau type vaut relationship, et members référence les points de navigation et itinéraires inclus dans le réseau.

Les annotations de relation dans un graphe de points de navigation utilisent les propriétés properties suivantes:

Propriété Objet applicable Type Requis Description
category Itinéraire, réseau string Oui Distingue les types de relation: itinéraire vaut route, et réseau vaut network.
isDirected Itinéraire boolean Non true signifie du premier point de navigation dans members vers le second; false signifie non dirigé.
weight Itinéraire number Non Poids de l'itinéraire, nombre à virgule flottante 32 bits. Le sens précis est défini par l'application qui utilise le graphe de points de navigation.

Exemple d'annotation de graphe de points de navigation:

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

Les extensions ajoutent des données personnalisées aux annotations sans modifier la structure centrale EMA 0.5.

Le tableau extensions de l'objet racine déclare les extensions utilisées par le document. Chaque élément utilise le format suivant:

PROVIDER:NAME#MAJOR.MINOR.PATCH
  • PROVIDER est le nom du fournisseur de l'extension.
  • NAME est le nom de l'extension.
  • La version se compose de trois entiers non négatifs.
  • PROVIDER et NAME ne doivent pas contenir : ni #.
  • Le même PROVIDER:NAME n'est déclaré qu'une seule fois dans extensions.

Les données d'extension sont stockées dans les properties de l'annotation, avec le nom de propriété PROVIDER:NAME et sans numéro de version. La valeur d'extension peut être n'importe quelle valeur JSON. Un objet JSON est recommandé afin de pouvoir ajouter des champs plus tard.

Exemple de déclaration et données d'extension:

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

Exigences de cohérence

Les producteurs doivent s'assurer que:

  • Les ID de Mega Block et d'annotation sont uniques dans leurs collections respectives.
  • Lorsque parent.type vaut block, parent.id référence un Mega Block existant dans blocks.
  • Lorsque type vaut relationship, les ID dans members référencent des annotations existantes dans annotations.
  • Les propriétés d'extension utilisées dans properties ont des déclarations correspondantes dans extensions.

Les consommateurs peuvent ignorer les champs ordinaires non reconnus. Les type, parent.type ou geometry inconnus doivent être traités comme non pris en charge.

Exemple complet

Exemple de document EMA complet contenant des données d'extension:

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