Table of Contents

EasyAR Mega Annotation 형식 0.5

이 문서는 EMA 0.5의 형식 사양을 정의합니다.

시작하기 전에

이 문서에서 "producer"는 EMA 데이터를 생성하는 프로그램을, "consumer"는 EMA 데이터를 읽는 프로그램을 의미합니다.

형식 규칙

  • EMA 파일은 UTF-8 인코딩을 사용하며 RFC 8259에 정의된 JSON 문법을 따릅니다.
  • 같은 객체 안의 필드 이름은 중복될 수 없습니다.
  • 필드 이름은 대소문자를 구분합니다. 이 문서에서 정의한 필드 이름은 표와 예시에 제시된 형식을 사용해야 합니다.
  • 필수 필드는 존재해야 하며 표에 정의된 타입을 사용해야 합니다. 선택 필드는 값이 없으면 생략할 수 있습니다.
  • UUID는 하이픈이 포함된 문자열로 작성합니다. 예: 123e4567-e89b-12d3-a456-426614174000.
  • 타임스탬프는 YYYY-MM-DDThh:mm:ssZ 형식의 UTC 날짜-시간 문자열을 사용하며 초 단위까지 정확합니다. 예: 2026-08-12T00:00:00Z. 이 형식은 W3C Date and Time Formats에 정의된 UTC 표현을 따릅니다.
  • 좌표 변환은 오른손 OpenGL 좌표계를 사용합니다. +X는 오른쪽, +Y는 위쪽, +Z는 뒤쪽을 가리킵니다.

문서 구조

EMA 문서의 루트 객체에는 형식 버전, 생성자, 확장 선언, Mega Block 목록 및 annotation 목록이 포함됩니다.

EMA 루트 객체 구조 예:

{
  "version": "0.5.0",
  "generatedBy": "EasyAR Mega Support 2.14.0",
  "blocks": [],
  "annotations": [],
  "extensions": []
}
필드 타입 필수 설명
version string EMA 형식 버전입니다. 0.5 문서는 0.5.0으로 작성합니다.
generatedBy string 문서를 생성한 도구 또는 주체 정보이며 일반적으로 제품 이름과 버전을 포함합니다.
blocks array<Block> 문서가 참조하는 Mega Block입니다. 빈 배열일 수 있습니다.
annotations array<Annotation> annotation 객체입니다. 빈 배열일 수 있습니다.
extensions array<string> 아니요 문서가 사용하는 확장 선언입니다. 확장을 참조하십시오.

Block

Block는 EMA 문서가 참조하는 Mega Block과 해당 좌표 정보를 나타냅니다.

필드 타입 필수 설명
id UUID string Mega Block의 고유 식별자입니다. EasyAR Mega 서비스가 반환한 값을 사용해야 합니다.
timestamp date-time string Mega Block의 마지막 수정 시간입니다. EasyAR Mega 서비스가 반환한 값을 사용해야 합니다. 형식 규칙을 참조하십시오.
location Location 아니요 Mega Block 원점의 WGS 84 지리 위치입니다.
transform Transform EMA 장면 루트 좌표계에 대한 Mega Block의 변환입니다.
keepTransform boolean 문서에 기록된 transform을 유지하고 적용할지 여부입니다. true는 수동 조정된 변환을 유지함을 의미합니다.

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은 EMA 문서의 annotation을 나타냅니다.

필드 타입 필수 설명
type string annotation 타입입니다. 값은 node 또는 relationship입니다.
id UUID string annotation의 고유 식별자입니다. annotations의 ID는 고유해야 합니다.
timestamp date-time string annotation의 마지막 수정 시간입니다. 형식 규칙을 참조하십시오.
featureType string 아니요 annotation이 속한 기능 타입입니다.
properties object 아니요 annotation 속성과 확장 데이터입니다.

Node

Node는 공간 위치를 가진 annotation을 나타냅니다.

필드 타입 필수 설명
type string node로 고정됩니다.
geometry string geometry 타입입니다. 값은 point 또는 cube입니다.
parent Parent node annotation의 참조 좌표계입니다. Mega Block 또는 WGS 84 지리 위치를 참조할 수 있으며, 후자의 제품 지원은 WorldParent를 참조하십시오.
transform Transform 참조 좌표계에 대한 node annotation의 변환입니다. 포함되는 필드는 geometry에 따라 결정됩니다.

geometrypoint이면 위치점을 나타냅니다. cube이면 원점을 중심으로 하는 박스 영역을 나타냅니다. 각 geometry의 transform 요구사항은 Transform을 참조하십시오.

점 annotation 예:

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

박스 영역 annotation 예:

{
  "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는 annotation 간의 관계를 나타내며 여러 annotation을 하나의 컬렉션으로 구성하는 데도 사용할 수 있습니다.

필드 타입 필수 설명
type string relationship로 고정됩니다.
members array<UUID string> 멤버 annotation ID를 순서대로 기록합니다. 멤버는 node 또는 relationship annotation을 참조할 수 있습니다.

관계 annotation 예:

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

ParentNode가 붙는 참조 좌표계를 나타내며 Node 공간 변환의 해석 기준을 결정합니다.

BlockParent

BlockParent는 Mega Block 기반의 참조 좌표계를 나타냅니다.

필드 타입 필수 설명
type string block로 고정됩니다.
id UUID string 참조된 Mega Block의 ID입니다. 이 ID는 루트 객체의 blocks에 있어야 합니다.
timestamp date-time string annotation을 만들거나 업데이트할 때 참조된 Mega Block의 수정 시간입니다. 형식 규칙을 참조하십시오.

WorldParent

WorldParent는 WGS 84 지리 위치를 원점으로 하는 월드 참조 좌표계를 나타냅니다.

필드 타입 필수 설명
type string world로 고정됩니다.
location Location node annotation 참조 좌표계 원점의 WGS 84 지리 위치입니다.
경고

EMA 0.5는 parent.typeworld인 구조를 정의하지만 EasyAR Mega Studio 2.13 및 EasyAR Sense Unity Plugin 4003 이후 버전은 관련 기능을 제거했습니다. 형식 정의가 해당 제품 버전에서 WorldParent 사용을 지원한다는 의미는 아닙니다.

좌표와 기본 타입

Location

Location은 WGS 84 지리 위치를 나타냅니다.

필드 타입 필수 설명
latitude number 위도이며 십진 도 단위로 표현되는 64비트 부동소수점 숫자입니다.
longitude number 경도이며 십진 도 단위로 표현되는 64비트 부동소수점 숫자입니다.
altitude number 고도이며 미터 단위의 64비트 부동소수점 숫자입니다.

Transform

Transform는 참조 좌표계에 대한 객체의 공간 변환을 나타냅니다.

필드 타입 필수 설명
position Vector3F 참조 좌표계에 대한 위치입니다.
rotation Vector4F 조건부 참조 좌표계에 대한 회전입니다.
scale Vector3F 조건부 참조 좌표계에 대한 스케일입니다.

각 필드의 사용 사례별 요구사항은 다음과 같습니다:

사용 사례 position rotation scale
Mega Block 필수 필수 필수
geometrypoint인 annotation 필수 생략 생략
geometrycube인 annotation 필수 필수 필수

Vector3F

Vector3F는 위치와 스케일을 기록하는 3차원 벡터를 나타냅니다.

필드 타입 필수 설명
x number x축 성분이며 32비트 부동소수점 숫자입니다.
y number y축 성분이며 32비트 부동소수점 숫자입니다.
z number z축 성분이며 32비트 부동소수점 숫자입니다.

Vector4F

Vector4F는 회전을 기록하는 쿼터니언을 나타냅니다.

필드 타입 필수 설명
x number 쿼터니언의 x 성분이며 32비트 부동소수점 숫자입니다.
y number 쿼터니언의 y 성분이며 32비트 부동소수점 숫자입니다.
z number 쿼터니언의 z 성분이며 32비트 부동소수점 숫자입니다.
w number 쿼터니언의 w 성분이며 32비트 부동소수점 숫자입니다.

속성

properties는 annotation의 공통 속성, 기능 속성 및 확장 데이터를 저장합니다. 이 필드는 키-값 객체이며 값은 임의의 JSON 값일 수 있습니다.

EMA 0.5는 다음 공통 속성을 정의합니다:

속성 적용 대상 타입 필수 설명
name node, relationship string 아니요 annotation의 표시 이름입니다.
isDirected relationship boolean 아니요 관계가 방향성을 가지는지 여부입니다. 지정하지 않으면 true입니다.
category relationship string 아니요 관계 카테고리입니다.

기능 타입

featureType는 annotation이 참여하는 기능 타입을 지정합니다. 각 기능 타입은 관련 annotation의 구조, 관계 및 전용 속성을 정의합니다.

내비게이션 지점 그래프

내비게이션 지점 그래프는 공간의 내비게이션 지점, 내비게이션 지점을 연결하는 경로, 그리고 이들로 구성된 네트워크를 나타냅니다. 경로와 연결 관계를 표현할 수 있습니다. 내비게이션 지점 그래프를 구성하는 모든 annotation은 featureTypenavPointGraph로 설정합니다.

내비게이션 지점 그래프는 세 가지 annotation 타입으로 구성됩니다:

객체 구조 요구사항
내비게이션 지점 typenode이고 geometrypoint입니다.
경로 typerelationship이고 members는 두 내비게이션 지점을 순서대로 참조합니다.
네트워크 typerelationship이고 members는 네트워크에 포함된 내비게이션 지점과 경로를 참조합니다.

내비게이션 지점 그래프의 관계 annotation은 다음 properties 속성을 사용합니다:

속성 적용 대상 타입 필수 설명
category 경로, 네트워크 string 관계 타입을 구분합니다. 경로는 route, 네트워크는 network입니다.
isDirected 경로 boolean 아니요 truemembers의 첫 번째 내비게이션 지점에서 두 번째 지점으로 향함을 의미하고, false는 무방향을 의미합니다.
weight 경로 number 아니요 경로 가중치이며 32비트 부동소수점 숫자입니다. 구체적인 의미는 내비게이션 지점 그래프를 사용하는 애플리케이션이 정의합니다.

내비게이션 지점 그래프 annotation 예:

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

확장

확장은 EMA 0.5 핵심 구조를 변경하지 않고 annotation에 사용자 정의 데이터를 추가하는 데 사용됩니다.

루트 객체의 extensions 배열은 문서가 사용하는 확장을 선언합니다. 각 항목은 다음 형식을 사용합니다:

PROVIDER:NAME#MAJOR.MINOR.PATCH
  • PROVIDER는 확장 제공자 이름입니다.
  • NAME은 확장 이름입니다.
  • 버전은 세 개의 음이 아닌 정수로 구성됩니다.
  • PROVIDERNAME에는 : 또는 #이 포함될 수 없습니다.
  • 동일한 PROVIDER:NAMEextensions에서 한 번만 선언됩니다.

확장 데이터는 annotation의 properties에 저장하며, 속성 이름은 PROVIDER:NAME이고 버전 번호는 포함하지 않습니다. 확장 값은 임의의 JSON 값일 수 있습니다. 나중에 필드를 추가할 수 있도록 JSON 객체를 권장합니다.

확장 선언 및 데이터 예:

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

일관성 요구사항

producer는 다음을 보장해야 합니다:

  • Mega Block ID와 annotation ID는 각각의 컬렉션에서 고유합니다.
  • parent.typeblock이면 parent.idblocks에 있는 기존 Mega Block을 참조합니다.
  • typerelationship이면 members의 ID는 annotations에 있는 기존 annotation을 참조합니다.
  • properties에서 사용되는 확장 속성은 extensions에 해당 선언이 있어야 합니다.

consumer는 인식하지 못하는 일반 필드를 무시할 수 있습니다. 인식할 수 없는 type, parent.type, geometry는 지원되지 않는 데이터로 처리해야 합니다.

전체 예

확장 데이터를 포함하는 완전한 EMA 문서 예:

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