← Documentation

Créer une observation

Dessinez-la dans l'éditeur, ou écrivez le fichier vous-même. Les deux produisent la même chose : un fichier JSON qui est le vôtre, et que n'importe qui peut rejouer.

1. Dans l'éditeur#

La voie ordinaire, et celle à prendre sauf raison contraire. Dessinez ce qui a été vu, dites quand et où, enregistrez le mouvement — et le ciel, la météo et le sol sont relevés pour vous plutôt que remémorés.

Ouvrir l'éditeur Lire le manuel

Cela se termine par Exporter, qui vous remet un fichier. Ce fichier est l'enregistrement complet : il n'y a pas de compte, et rien n'est conservé ici. Posez-le quelque part avec une adresse publique et il est prêt à partager.

Vous en avez déjà un et voulez le modifier ? L'éditeur s'ouvre sur un enregistrement existant — le panneau ? de toute reconstitution publiée porte le lien qui le fait.

2. À la main, ou depuis vos propres archives#

Un enregistrement est un fichier de forme documentée : rien ne vous empêche d'en écrire un dans un éditeur de texte, ni d'en engendrer mille depuis une base que vous avez déjà. Tout ce qui suit est ce que l'éditeur lui-même écrit.

Un enregistrement est un simple fichier JSON. Rien dedans n'est un blob binaire, un identifiant dans une base de données, ni une référence à ce site — vous pouvez en écrire un à la main, en engendrer depuis vos propres archives, ou en comparer deux dans une relecture de code.

L'observation#

ChampSens
versionToujours 1
time, endTime{ year, month, day, hour, minute, second }, chaque partie facultative — c'est ainsi que le format énonce « 1954 » ou « vers 05:00 »
durationSecondsUne alternative à endTime, et c'est elle qui l'emporte si les deux sont là
utcOffsetHoursL'heure LÉGALE de la montre du témoin (+1 pour la France en 1965). Absent, elle est approchée depuis la longitude, qui ne peut connaître ni l'heure légale ni un changement d'heure
place[{ lat, lng, name }]name est le nom qualifié depuis lequel les coordonnées ont été résolues
witness{ id, dirName, title, lastName, firstNames }, tous facultatifs ; à omettre entièrement pour un témoin anonyme
caseIdPartagé par le fichier de chaque témoin d'un même dossier — ce qui permet à un manifeste de les réunir
description, tagsTexte libre, et une liste de chaînes

Ce qui a été vu#

timeline.keyframes est une liste de { t, shapes }, t en millisecondes depuis le début. Chaque forme porte un sourceId — plusieurs formes peuvent partager une chronologie (le phénomène, une flamme qui traîne, une seconde lumière) — et une shape :

{
  "kind": "oval",          // ou "polygon", qui prend alors aussi "points"
  "bounds": { "x": 0, "y": 0, "width": 0, "height": 0 },
  "color": "#39ff14",      // n'importe quelle couleur CSS
  "angle": 0,              // radians
  "transparency": 0,       // 0 opaque .. 1 invisible
  "haloScale": 1.5,        // 0 = aucune lueur
  "brightness": 0,         // l'éblouissement : un voile, les aigrettes du diaphragme, un cœur saturé au blanc
  "blur": 0,               // à quel point le témoin a dit les contours indistincts
  "selected": false,
  "title": "le phénomène",
  "behindCloud": false,    // ÉNONCÉ par le témoin, jamais déduit
  "angular": { "widthDeg": 1.2, "heightDeg": 0.4 }
}

C'est angular qui fait foi. bounds est cet angle projeté sur le canevas fixe de 640×360 au champ de la pose et à travers l'instrument de l'enregistrement ; il est redérivé au chargement, si bien qu'un fichier survit à un changement de canevas, de champ ou d'instrument. Si les deux divergent, c'est l'angle qui gagne.

timeline.order est l'ordre de tracé de l'arrière vers l'avant, timeline.groups les identifiants groupés. Les deux sont facultatifs.

Tout ce qu'il y a autour#

ChampSens
witnessTrack{ keyframes: [{ t, pose }] }pose porte lat, lng, elevationM (au-dessus du sol local), headingDeg, pitchDeg, rollDeg, fovDeg, et pour un appareil fNumber et focusDistanceM
weatherTrack{ keyframes: [{ t, weather }] } — couverture, noirceur, base, la couche haute (glacée) tenue à part, alignement des cristaux, précipitation et son intensité, vent, orage
weatherSource{ id, name, url } du relevé d'où vient la météo. Sa présence signifie que l'enregistrement est rejoué tel qu'il a été composé et n'est jamais reconsulté. Absent : le récit du témoin lui-même
soundTrack{ keyframes: [{ t, sound }] }kind (none/hum/whistle/rumble/crackle), volume, pitchHz, et un src facultatif vers un vrai enregistrement
instrument, exposureSecondsÀ travers quoi l'observation a été faite, et combien de temps l'obturateur est resté ouvert. Absent : l'œil nu
decorLe décor, à une vraie distance eastM/northM du témoin : bâtiments (avec floors, windows), arbres, lampadaires, véhicules, autres témoins, aéronefs — éventuellement avec une track et des lights dont le pattern porte une vraie cadence d'éclats

Un fichier entier#

Le plus petit enregistrement qui énonce encore quelque chose — un ovale silencieux traversant le ciel en douze secondes, à une date réelle et en un lieu réel. Tout le reste du format est facultatif, et tout ce qui suit sert à quelque chose :

{
  "version": 1,
  "description": "The smallest recording that still states something: one silent orange oval, a degree and a half wide, crossing the south-western sky from left to right over twelve seconds.",
  "time": { "year": 2024, "month": 8, "day": 12, "hour": 22, "minute": 30 },
  "durationSeconds": 12,
  "utcOffsetHours": 2,
  "place": [{ "lat": 45.19, "lng": 5.72, "name": "Grenoble, Isère, France" }],
  "timeline": {
    "keyframes": [
      {
        "t": 0,
        "shapes": [
          {
            "sourceId": "ufo-1",
            "shape": {
              "kind": "oval",
              "bounds": { "x": 150, "y": 150, "width": 10, "height": 3 },
              "angular": { "widthDeg": 1.6, "heightDeg": 0.5 },
              "color": "#ff8c1a",
              "angle": 0,
              "transparency": 0,
              "haloScale": 1.2,
              "selected": false
            }
          }
        ]
      },
      {
        "t": 12000,
        "shapes": [
          {
            "sourceId": "ufo-1",
            "shape": {
              "kind": "oval",
              "bounds": { "x": 480, "y": 130, "width": 10, "height": 3 },
              "angular": { "widthDeg": 1.6, "heightDeg": 0.5 },
              "color": "#ff8c1a",
              "angle": 0,
              "transparency": 0,
              "haloScale": 1.2,
              "selected": false
            }
          }
        ]
      }
    ]
  },
  "witnessTrack": {
    "keyframes": [
      {
        "t": 0,
        "pose": { "lat": 45.19, "lng": 5.72, "elevationM": 0, "headingDeg": 215, "pitchDeg": 20, "fovDeg": 60 }
      }
    ]
  },
  "soundTrack": { "keyframes": [{ "t": 0, "sound": { "kind": "none", "volume": 0, "pitchHz": 100 } }] }
}

À vous d'y taper : il complète sur chaque clé du format, propose les mots que chacune accepte, et dit ce que le modèle en dit. Rien n'est enregistré ni joué ici — pour en voir une tourner, le lecteur prend un fichier.

C'est /demo-data/example-minimal.json sur ce site : vous pouvez le récupérer, et le jouer avant d'y toucher. Remarquez que angular et bounds y figurent tous deux : l'angle est ce que le fichier SIGNIFIE, et les pixels en sont redérivés au chargement — écrivez l'angle, et laissez corriger une mauvaise estimation des pixels.

De plus gros, à lire#

Chaque démo de ce site est un simple fichier que vous pouvez ouvrir. Ces quatre-là valent la lecture pour voir comment un vrai enregistrement est bâti :

FichierCe qu'il faut y regarder
witness-chiles.jsonUn vrai dossier : un témoin, un identifiant de dossier partagé avec un second enregistrement, dix keyframes, un weatherTrack relevé avec son weatherSource
sky-test-halos.jsonAucun phénomène — un ciel réglé par sa météo, avec un witnessTrack de quatre poses qui balaie le cortège
sky-test-aircraft.jsonUn instrument et un exposureSeconds, et un décor d'aéronef avec sa track et sept lights à leurs cadences réelles
instrument-instamatic.jsonLa même observation que witness-socorro.json, à un champ près. Comparez les deux

Quatre règles qui décident du sens d'un fichier#

  • Les champs discrets sont tenus, les continus sont interpolés. Une forme absente d'un keyframe ultérieur reste dans son état ; une forme dont le premier keyframe est à cinq secondes est déjà peinte, dans cet état, dès zéro. Pour qu'une chose cesse d'être visible, posez-lui un keyframe à transparency: 1.
  • Des angles, rien d'autre. Aucune taille ni distance réelle n'est stockée où que ce soit. Les mètres sont déduits, en inégalités, de ce que le phénomène a été déclaré passer derrière ou devant (decor[].occludesSourceIds).
  • L'énoncé l'emporte sur le déduit. behindCloud et occludesSourceIds sont des affirmations du témoin. Rien dans ce format ne peut les déduire : il décrit une apparence dans un champ de vision, pas une position dans l'espace.
  • Absent n'est pas zéro. Pas de piste sonore signifie que personne n'a posé la question ; kind: "none" signifie que le témoin a déclaré n'avoir rien entendu. La même distinction traverse la météo et les nuages de glace.

Le README porte la référence complète, champ par champ, avec le raisonnement derrière chaque choix ; c'est lui qui fait foi si cette page et lui venaient à diverger.