Import/Export

author : fdesbois <florian.desbois@codelutin.com>
date : $Date$

Echange de données

Le schéma ci-dessous reprend les principaux échanges de données possibles entre les différentes stations de travail. Chaque bloc bleue représente un type de station :

  • Central : Ordinateur avec la base de données centrale contenant toutes les données

  • Saisie : Ordinateur pour la saisie en vol

  • Validation: Ordinateur pour la validation des données

  • Suivi : Ordinateur pour le suivi et la préparation des vols

A noter que ce sont des rôles de station de travail, une seule même machine physique peut avoir tous ces différents rôles.

TODO explications supplémentaires sur les étapes

Import référentiels

Fichiers SHP (transects/strates)

Ces fichiers sont importés depuis l'édition d'une campagne. Toutes les données sont enregistrés en base sauf les fichiers shp.

Il y a deux import :

  • strates : contient la liste des strates et leurs secteurs

  • transects : contient la liste des transects et la référence au secteur et à la strate

On utilise le EsriPlugin d'OpenMap pour lire les fichiers. Trois types sont lus :

  • dbf : contient les méta-données

  • shp : contient les données géospacialisés

  • shx : fichier d'index du shp

Pour les fichiers dbf, le nom des colonnes est important à conserver pour l'import.

Fichier de strate (dbf)

Voir le dictionnaire de données concernant les strates

  • colonne 0 : "name" : Nom de la strate (strate.name)

  • colonne 1 : "strateType" : Type de la strate (strate.strateType)

    • C : COAST (Côte)

    • N : NERITIC (Néritique)

    • P : SLOPE (Pente)

    • O : OCEANIC (Océanique)

  • colonne 2 : "subRegion" : Nom de la sous-région (strate.subRegion.name)

    • NC

    • ALT

  • colonne 3 : "idStrate" : Numéro du la sous-région (strate.subRegion.subRegionNumber)

  • colonne 4 : "Area" : Surface de la strate (non utilisé pour le moment)

  • colonne 5 : "Shape_Leng" : Longueur sur le fichier shape (non utilisé pour le moment)

  • colonne 6 : "Shape_Area" : Surface sur le fichier shape (non utilisé pour le moment)

  • colonne 7 : "starte" : Code de la strate (strate.code)

Fichier de transect (dbf)

Voir le dictionnaire de données concernant les transects

  • colonne 0 : "transect" : Identifiant et nom du transect (transect.name)

  • colonne 1 : "xStart" : Coordonnée X de début du transect (transect.startX)

  • colonne 2 : "yStart" : Coordonnée Y de début du transect (transect.startY)

  • colonne 3 : "xEnd" : Coordonnée X de fin du transect (transect.endX)

  • colonne 4 : "yEnd" : Coordonnée Y de fin du transect (transect.endY)

  • colonne 5 : "length" : longueur du transect (transect.length)

  • colonne 6 : "passage" : Numéro de passage (transect.nbTimes)

  • colonne 7 : "idStrate" : Numéro de la sous-région (transect.strate.subRegion.subRegionNumber)

  • colonne 8 : "strateType" : Type de strate (transect.strate.strateType)

  • colonne 9 : "strate" : Code de la strate (transect.strate.code)

  • colonne 10 : "subRegion" : Nom de la sous-région (transect.strate.subRegion.name)

Sauvegarde des fichiers

Tous les fichiers qui ont le même nom que celui importé (avec des extensions différentes) sont conservés et copier dans le dossier de l'application :

  • .sammoa/campaign/{campaignTopiaId}/map/transects.*

  • .sammoa/campaign/{campaignTopiaId}/map/strates.*

Une fois l'application lancé avec une campagne, les fichiers sont retrouvés par rapport à cette campagne.

Observateurs (CSV)

Voir le dictionnaire de données concernant les observateurs

L'import des observateurs est possible depuis l'interface d'édition d'une campagne.

Le fichier doit être encodé en UTF-8. Le caractère de séparation est le ";". Le fichier des observateurs doit contenir les en-têtes suivantes

CAMPAIGN;INITIALS;FIRST_NAME;LAST_NAME;ORGANIZATION;EMAIL;PILOT
  • CAMPAIGN : code de la campagne (String)

  • INITIALS : initiales de l'observateur (String)

  • FIRST_NAME : prénom de l'observateur (String)

  • LAST_NAME : nom de l'observateur (String)

  • ORGANIZATION : société de l'observateur (String)

  • EMAIL : email de l'observateur (String)

  • PILOT : drapeau pour dire que l'observateur est pilote d'avion (Boolean : "true" ou "false")

Espèces (CSV)

Voir le dictionnaire de données concernant les espèces

L'import des espèces est possible depuis l'interface d'édition d'une région.

Le fichier doit être encodé en UTF-8. Le caractère de séparation est le ";". Le fichier des observateurs doit contenir les en-têtes suivantes

REGION;CODE;NOM_COMM;NOM_LATIN;TYPE;FAMILLE;GROUPE
  • REGION : code de la région (String)

  • CODE : code de l'espèce (String)

  • NOM_COMM : nom commun de l'espèce (String)

  • NOM_LATIN : nom latin de l'espèce (String)

  • TYPE : type d'espèce (String)

  • FAMILLE : famille de l'espèce (String)

  • GROUPE : groupe auquel appartient l'espèce (String)

Export SHP données réelles

L'export se fera via une interface dédiée accessible depuis l'écran d'accueil.

Trois types de SHP peuvent être exportés :

  • Points GPS : ensemble des points GPS capturés associés au vol

  • Effort : conditions d'observations, détails des routes et coordonnées GPS.

  • Observation : observations et coordonnées GPS des points sur lesquels ont été effectuées ces observations.

Points GPS

Voir le dictionnaire de données concernant les points GPS

On effectue un export des points GPS à partir d'une campagne sur une période (date de début, date de fin) encadrée par celle de la campagne

On récupère ainsi une liste de vols avec leurs points GPS capturés

Chaque point est une ligne du fichier DBF à exporter, et correspond à un point graphique sur le fichier SHP.

Voici les colonnes du fichier DBF :

  • region : Code de la région geoPoint.flight.campaign.region.code

  • survey : Code de la campagne geoPoint.flight.campaign.code

  • flight : Numéro de vol geoPoint.flight.flightNumber

  • computer : Identifiant du système geoPoint.flight.systemId

  • aircraft : Immatriculation de l'avion geoPoint.flight.planeImmatriculation

  • date : Date d'enregistrement du poin geoPoint.recordTime

  • hhmmss : Heure d'enregistrement du point format(geoPoint.recordTime, "HHmmss")

  • lat : Latitude du point GPS geoPoint.latitude

  • lon : Longitude du point GPS geoPoint.longitude

  • speed : Vitesse de l'avion à ce point GPS geoPoint.speed

  • altitude : Altitude de l'avion à ce point GPS geoPoint.altitude

  • gpsDelay : Délai en secondes depuis la capture GPS geoPoint.captureDelay

Effort

Voir le dictionnaire de données concernant l' effort

On effectue un export d'efforts à partir d'une campagne, d'une période (date de début, date de fin) encadrée par celle de la campagne et d'une sélection de strates. On peut également filtrer sur les types de parcours (LEG, TRANSIT, CIRCLE_BACK).

On récupère ainsi une liste de vols et pour chacun des vols, sa liste de parcours sur les strates sélectionnées pour les LEG.

Chaque parcours est une ligne d'effort du fichier DBF à exporter, et correspond à un point graphique sur le fichier SHP.

Une colonne STATUS pour chaque LEG est nécessaire pour distinguer un BEGIN, d'un ADD, de plus une ligne avec un status END devra être créée à l'export. Une ligne END correspond à la fin d'un groupe de LEG et comprendra les même données que le dernier LEG avec les données GPS (GeoPoint) du prochain TRANSIT ou CIRCLE_BACK.

Voici les colonnes du fichier DBF :

  • region : Code de la région

    • campaign.region.code

  • survey : Code de la campagne

    • campaign.code

  • idStrate* : Numéro de la sous région (N)

    • route.transectFlight.transect.strate.subRegion.subRegionNumber

  • strateType* : Type de strate

    • route.transectFlight.transect.strate.strateType.code

  • strate* : Code de la strate

    • route.transectFlight.transect.strate.code

  • subRegion* : Code de la strate

    • route.transectFlight.transect.subRegion.name

  • transect* : Code du transect

    • route.transectFlight.transect.name

  • passage* : Numéro de passage (N)

    • route.transectFlight.crossingNumber

  • flight : Numéro de vol (N)

    • route.flight.flightNumber

  • computer : Identifiant du système

    • route.flight.systemId

  • routeType : Type de parcours (LEG, TRANSIT, CIRCLE_BACK)

    • route.routeType.name

  • effortGrp* : Identifiant du group d'effort

    • "G" + BEGIN route.effortNumber + "-" + route.flight.flightNumber + "-" + route.flight.systemId

    • si route.routeType = LEG et currentLegGroup = null => création currentLegGroup avec l'identifiant de l'effort

  • effort* : Identifiant de l'effort

    • "L" + route.effortNumber + "-" + route.flight.flightNumber + "-" + route.flight.systemId

  • status* : LegStatus.name (BEGIN, ADD, END)

    • si route.routeType = TRANSIT ou CIRCLE_BACK => ajout d'une ligne END (ensuite currentLegGroup = null)

    • si previousRoute.routeType = TRANSIT ou CIRCLE_BACK (ou currentLegGroup = null) => BEGIN

    • si previousRoute.routeType = LEG et nextRoute.routeType = LEG (ou currentLegGroup != null) => ADD

  • date : Date du parcours/segment (D)

    • route.beginTime

  • hhmmss : Heure du parcours/segment

    • format(route.beginTime, "HHmmss")

  • seaState : Etat de la mer (N)

    • route.seaState

  • swell : Houle (N)

    • route.swell

  • turbidity : Turbidité (N)

    • route.turbidity

  • SkyGlint : Transparence (N)

    • route.skyGlint

  • glareForm : Eblouissement de

    • route.glareFrom

  • glareTo : Eblouissement à

    • route.glareTo

  • glareSeverity : Intensité d'éblouissement (N)

    • route.glareSeverity

  • glareUnder : (L)

    • route.glareUnder

  • cloudCover : Couverture nuageuse (N)

    • route.cloudCover

  • subjective : Détectabilité

    • route.subjectiveConditions

  • unexpLeft : Nombre d'observations à gauche (pour les exocet par exemple)

    • route.unexpectedLeft

  • unexpRight : Nombre d'observations à droite (pour les exocet par exemple)

    • route.unexpectedRight

  • left : Observateur à gauche

    • route.observerPosition[FRONT_LEFT].observer.initials

  • right : Observateur à droite

    • route.observerPosition[FRONT_RIGHT].observer.initials

  • center : Observateur au centre

    • route.observerPosition[NAVIGATOR].observer.initials

  • cbCause** : Cause du circle-back

    • "O" + route.circleBackCause.observationNumber + "-" + route.circleBackCause.flight.flightNumber + "-" + route.circleBackCause.flight.systemId

  • lat : Latitude du point GPS (N)

    • geoPoint.latitude

  • lon : Longitude du point GPS (N)

    • geoPoint.longitude

  • speed : Vitesse de l'avion à ce point GPS (N)

    • geoPoint.speed

  • altitude : Altitude de l'avion à ce point GPS (N)

    • geoPoint.altitude

  • gpsDelay : Délai en secondes depuis la capture GPS (N)

    • geoPoint.captureDelay

  • aircraft : Immatriculation de l'avion

    • route.flight.planeImmatriculation

  • comment : Commentaires

    • route.comment

(*) uniquement pour un parcours de type LEG, sinon la cellule sera vide

(**) uniquement pour un parcours de type CIRCLE_BACK, sinon la cellule sera vide

Observation

Voir le dictionnaire de données concernant les observations

On effectue un export des observations à partir d'une campagne, d'une période (date de début, date de fin) encadrée par celle de la campagne, d'une sélection de strates et d'une sélection d'espèces. On peut également filtrer sur les types de parcours (LEG, TRANSIT, CIRCLE_BACK).

On récupère ainsi une liste de vols et pour chacun des vols, sa liste de parcours sur les strates sélectionnées pour les LEG. Grâce à la date, on retrouve les observations pour ces parcours.

Chaque parcours est une ligne d'observation du fichier DBF à exporter, et correspond à un point graphique sur le fichier SHP.

Voici les colonnes du fichier DBF :

  • region : Code de la région

    • observation.flight.campaign.region.code

  • survey : Code de la campagne

    • observation.flight.campaign.code

  • idStrate* : Numéro du secteur (N)

    • route.transectFlight.transect.strate.sector.sectorNumber

  • strateType* : Type de strate

    • route.transectFlight.transect.strate.strateType

  • strate* : Code de la strate

    • route.transectFlight.transect.strate.code

  • transect* : Code du transect

    • route.transectFlight.transect.name

  • passage* : Numéro de passage (N)

    • route.transectFlight.crossingNumber

  • flight : Numéro de vol (N)

    • route.flight.flightNumber

  • computer : Identifiant du système

    • route.flight.systemId

  • routeType : Type de parcours (LEG, TRANSIT, CIRCLE_BACK)

    • route.routeType.name

  • effortGrp* : Identifiant du group d'effort

    • "G" + BEGIN route.effortNumber + "-" + route.flight.flightNumber + "-" + route.flight.systemId

    • si route.routeType = LEG et currentLegGroup = null => création currentLegGroup avec l'identifiant de l'effort

  • effort* : Identifiant de l'effort

    • "L" + route.effortNumber + "-" + route.flight.flightNumber + "-" + route.flight.systemId

  • sighting : Identifiant de l'observation

    • "O" + observation.observationNumber + "-" + observation.flight.flightNumber + "-" + observation.flight.systemId

  • date : Date de l'observation (D)

    • observation.beginTime

  • hhmmss : Heure de l'observation

    • format(observation.beginTime, "HHmmss")

  • taxon : Type d'espèce

    • observation.species.type

  • group : Groupe de l'espèce

    • observation.species.groupName

  • family : Famille de l'espèce

    • observation.species.family

  • species : Code de l'espèce

    • observation.species.code

  • speciesName : Nom commun de l'espèce

    • observation.species.commonName

  • speciesLatin : Nom latin de l'espèce

    • observation.species.latinName

  • podSize : Taille des groupes (N)

    • observation.podSize

  • age :

    • observation.age

  • decAngle : Angle ou Bande (N)

    • observation.decAngle

  • cue : Détection, signal visuel

    • observation.cue

  • behaviour : Comportement

    • observation.behaviour

  • swimDir : Direction de nage (N)

    • observation.swimDir

  • calves : Nombre de jeunes

    • observation.calves

  • photo : Des photos ont été prises (L)

    • observation.photo

  • observer : Initiales de l'observateur

    • observation.observerPosition.observer.initials

  • side : Position de l'observateur (L : LEFT, R : RIGHT, C : CENTER)

    • observation.observerPosition.observer.position.name

  • status : Status de l'observation (NEW, CIRCLE_BACK, RECAPTURE, NO_RECAPTURE)

    • observation.observationStatus.name

  • cbCause** : Cause du circle-back

    • "O" + route.circleBackCause.observationNumber + "-" + route.circleBackCause.flight.flightNumber + "-" + route.circleBackCause.flight.systemId

  • lat : Latitude du point GPS (N)

    • geoPoint.latitude

  • lon : Longitude du point GPS (N)

    • geoPoint.longitude

  • speed : Vitesse de l'avion à ce point GPS (N)

    • geoPoint.speed

  • altitude : Altitude de l'avion à ce point GPS (N)

    • geoPoint.altitude

  • gpsDelay : Délai en secondes depuis la capture GPS (N)

    • geoPoint.captureDelay

  • aircraft : Immatriculation de l'avion

    • observation.flight.planeImmatriculation

  • comment : Commentaires

    • observation.comment

(*) uniquement pour un parcours de type LEG, sinon la cellule sera vide

(**) uniquement pour un parcours de type CIRCLE_BACK, sinon la cellule sera vide

EFFORT, EFFORT_GROUP et OBSERVATION

L'incrément du effortNumber et observationNumber se fait au sein d'un vol. Ainsi le premier LEG d'un vol aura toujours le numéro 1. Une suppression d'un LEG ou d'une observation ne décalera pas ce numéro. On pourra donc passer du LEG 1 au LEG 4 par exemple (le 2 et 3 ayant été supprimés à la validation).

Pour pouvoir identifier à l'export de façon unique l'identifiant de l'effort (colonne EFFORT) contiendra le vol associé. Par exemple : L001-286-A : LEG n°1 pour le vol n°286 sur le système A

Même chose pour les observations (colonne OBSERVATION) : O0001-286-A : Observation n°1 pour le vol n°286 sur le sytème A

Petite précision : pour garder une uniformité, on considère un numéro de LEG (effortNumber) sur 3 chiffres (ex: 001, 012, 123) et un numéro d'observation sur 4 chiffres (ex: 0001, 0085, 1230).

L'ancienne colonne FLIGHT_NO des tableaux de résultats xls fournis sera renommé EFFORT_GROUP et correspondra à un ensemble de LEG sans interruption (TRANSIT ou CIRCLE_BACK). L'EFFORT_GROUPE commencera par la lettre G et gardera le même code que le premier effort du groupe.

Exemples :

Pour l'export des efforts :

  • EFFORT = L{effortNumber}-{flightNumber}-{systemId} (ex: L001-286-A)

  • EFFORT_GROUP = G{beginEffortNumber}-{flightNumber}-{systemId} (ex: G001-286-A)

ROUTE_TYPE

STATUS

EFFORT_GROUP

EFFORT

GPS data

CB_CAUSE

LEG

BEGIN

G001-286-A

L001-286-A

$1

LEG

ADD

G001-286-A

L002-286-A

$2

LEG

END

G001-286-A

L002-286-A

$3

TRANSIT

$3

LEG

BEGIN

G003-286-A

L003-286-A

$4

LEG

ADD

G003-286-A

L005-286-A

$5

LEG

END

G003-286-A

L005-286-A

$6

CIRCLE_BACK

$6

O0010-286-A

LEG

BEGIN

G006-286-A

L006-286-A

$7

LEG

END

G006-286-A

L006-286-A

$8

TRANSIT

$8

Pour l'export des observations :

  • OBSERVATION = O{observationNumber}-{flightNumber}-{systemId} (ex: O0001-286-A)

ROUTE_TYPE

EFFORT_GROUP

EFFORT

OBSERVATION

STATUS

CB_CAUSE

LEG

G001-286-A

L001-286-A

O0001-286-A

NEW

LEG

G001-286-A

L001-286-A

O0002-286-A

NEW

LEG

G001-286-A

L002-286-A

O0003-286-A

NEW

LEG

G003-286-A

L003-286-A

O0006-286-A

NEW

LEG

G003-286-A

L003-286-A

O0008-286-A

NEW

LEG

G003-286-A

L005-286-A

O0010-286-A

CIRCLE_BACK

CIRCLE_BACK

O0011-286-A

RECAPTURE

O0010-286-A

CIRCLE_BACK

O0012-286-A

NEW

O0010-286-A

LEG

G006-286-A

L006-286-A

O0013-286-A

NEW

Export SAMMOA

L'export est accessible depuis l'écran d'accueil ou la sélection d'une campagne et d'un vol est possible.

L'export SAMMOA est un export de la base de données H2 ainsi que des fichiers rattachés (fichiers audio) sous forme d'un fichier .sammoa et contenant :

campaign-${campaignCode}.sammoa  (nom du fichier exporté par défaut, mais peut être configurable)
├── campaign.properties (meta données sur la campagne)
├── csv
│   └── Données exportés depuis la base au format csv
├── flight
│   ├── {flightTopiaId 1}
│   │   ├── audio
│   │   │   └── Fichiers audio enregistrés pendant le vol
│   │   └── flight.properties (meta données sur le vol)
│   └── {flightTopiaId 2}
│       └── ...
└── map
    └── Fichiers sources au format SHP

L'export peut se faire sur deux niveaux :

  • Export d'une campagne (avec tous ses vols)

  • Export d'un vol (avec toutes les données réels)

Il est nécessaire de toujours exporter le référentiel rattaché aux données du vol (transects, strates, secteurs, observateurs, espèces, campagne, région).

Une option doit être disponible dans l'interface pour archiver les données exportées et ainsi avoir une base vierge. Le recouvrement si besoin est se fera à la main. Il serait intéressant de proposer également à l'utilisateur si il souhaite garder les référentiels (region/campaign/sector/strate/transect/observer/species) pour éviter une base complètement vierge.

Note
les derniers flightNumber, observationNumber et effortNumber de l'application devront être conservés dans la configuration lorsque la base est archivée.

Import SAMMOA

L'import est possible depuis l'écran d'accueil ou la sélection d'une campagne et d'un vol est possible.

L'import est symétrique avec l'export et ne peut être que sur deux niveaux :

  • Import d'une campagne (avec tous ses vols)

  • Import d'un vol (avec toutes les données réels)

Gestion des conflits

  • On ne fusionne pas les vols, l'utilisateur pourra choisir d'écraser un vol ou de ne rien faire.

  • Sur une campagne existante, l'utilisateur pourra choisir d'écraser la campagne ou de n'ajouter que les nouveaux vols et écrasement des SHP d'origine.

  • On ne supprime pas d'éléments du référentiel, seul les ajouts sont permis (observateurs, espèces, transects, strates, secteurs)

Le référentiel sera synchronisé sur les clés métiers, il sera nécessaire de traiter les contraintes de base de données pour garder la validité des données importées en fonction des objets existant.

Clés métiers

Les propriétés suffixés d'un ^ correspondent à des clés étrangères en base.

  • Region : code

  • Species [1] : code, region [2]

  • Campaign : code, region [2]

  • Observer [3] : initials, campaign [2]

  • Sector : sectorNumber, campaign [2]

  • Strate : strateType, sector [2]

  • Transect : name, strate [2]

  • Flight : systemId, flightNumber, campaign [2]

  • GeoPoints

  • ObserverPosition

  • TransectFlight

  • Observation

  • Route

[1]

Pas d'espèce commune entre deux régions ou sinon une copie sera effectuée

[2]

Propriété correspondant à une clé étrangère en base

[3]

Pas d'observateur commun entre deux campagnes ou sinon une copie sera effectuée