Container
Die Datei beginnt mit der ZIP-Signatur PK und lässt sich mit jedem
ZIP-Werkzeug öffnen. Die Einträge folgen einem festen Namensschema: Datensätze tragen eine
Nummer ohne Endung, Nutzlasten dieselbe Nummer mit Endung. Die Nummer verbindet eine
Nutzlast mit dem Datensatz, der sie beschreibt.
export.pce ZIP, Methoden 0 (stored) und 8 (deflate)
├── 1 Datensatz, JSON, UTF-8
├── 2 Datensatz, JSON, UTF-8
├── …
├── SourceTypes Typtabelle, binär
├── ActionMap Verweistabelle Aktion → Kunde
├── BenefitMap Verweistabelle Leistung → Aktion
├── ProjectMap Verweistabelle Projekt → Leistung
├── PrjFilesMap Verweistabelle Dokument → Projekt
├── 7.sca Höhenrelief, uint16
├── 8.ima Graubild, uint8
└── 12.history Modellier-Verlauf, Text
Ein Export ohne Scan-Projekt enthält nur Datensätze und Tabellen und ist wenige Kilobyte groß. Mit Relief und Bildern liegt die Größe im Megabyte-Bereich.
Datensätze
Jeder nummerierte Eintrag ist ein JSON-Objekt. Das Feld DocumentType
bestimmt die Art des Satzes. Ein Projekt trägt kein DocumentType, sondern
eine Liste Documents. Die Hierarchie ist fest:
Kunde → Aktion → Leistung → Projekt → Dokument.
struct Customer { // DocumentType = "Customer"
string FamilyName, FirstName;
date DateOfBirth;
enum Gender;
Address Address;
Contact Contact; // Telefonliste, EMail
Ref HealthInsurance; // Kennung und Name des Kostenträgers
Ref Doctor;
number SizeOfShoes;
Origin Original; // Schlüssel des Quellsystems
}
struct Action { // DocumentType = "Action"
Ref Customer;
TypeRef Type; // Kennung, aufgelöst über SourceTypes
datetime CreatedLogically; // fachliches Datum
datetime CreatedDb; // Schreibdatum des Satzes
html Notice;
Workflow WorkflowState; // Phase, Freigabe
}
struct Benefit { // DocumentType = "Benefit"
Ref Action;
TypeRef Type;
}
struct Project { // ohne DocumentType
enum Side; // Side::Left | Side::Right
Document Documents[]; // Id, Role
}
enum eDocumentRole { SCA, IMA, ADDITIONAL_IMA, HISTORY }
CreatedLogically und CreatedDb sind getrennte Angaben. Für
die fachliche Historie einer Versorgung ist CreatedLogically maßgeblich;
CreatedDb weicht davon ab, sobald Daten nacherfasst oder aus einem
Vorsystem übernommen wurden. Notice enthält HTML und wird vor der Anzeige
bereinigt. Über Original lässt sich ein Kunde systemübergreifend
wiedererkennen, auch bei abweichender Schreibweise des Namens.
Verweistabellen und Typen
Die vier *Map-Einträge halten die Eltern-Beziehungen als Zahlenpaare. Sie
sind redundant zu den Ref-Feldern der Datensätze und eignen sich zur
Konsistenzprüfung: Jeder Satz, den eine Tabelle nennt, muss im Archiv vorhanden sein.
struct Map { // Byte-Reihenfolge: Big-Endian
int32 count;
struct { int32 record; int32 parent; } pairs[count];
}
struct SourceTypes { // Big-Endian
struct {
uint32 length; // Länge in Bytes
byte text[length]; // UTF-16BE oder UTF-8
} strings[];
}
Die Typkennungen in Action.Type und Benefit.Type werden über
SourceTypes in Klartext aufgelöst, etwa „Einlagen" und „Scan" als
Aktionsarten sowie „pcs-Scan3D" und „Modellieren" als Leistungsarten. Zu beachten ist die
Byte-Reihenfolge: Tabellen und Typen sind Big-Endian, der ZIP-Container und die
Nutzlasten Little-Endian.
Nutzlasten
Relief und Bilder teilen sich einen Kopf von 512 Byte. Er nennt Signatur, Raster und Auflösung; danach folgen die Zellen zeilenweise.
struct Header { // 512 Byte, Little-Endian
char magic[7]; // "PCSC001" (.sca) | "PCIM001" (.ima)
int32 width; // Offset 12
int32 height; // Offset 16
float32 xres, yres, zres; // Offset 32, 36, 40 — Millimeter je Schritt
}
.sca: Header + uint16 cells[width * height] // 0 = kein Kontakt
.ima: Header + uint8 cells[width * height] // Grauwert
| Größe | Berechnung | Beispiel |
|---|---|---|
| Plattenbreite | width × xres | 572 × 0,522 mm = 299 mm |
| Plattenlänge | height × yres | 740 × 0,522 mm = 386 mm |
| Höhe einer Zelle | cell × zres | Wertebereich 0 … 65.535 |
| Dateigröße .sca | 512 + 2 × width × height | 847.072 Byte |
Die Dateigröße ist damit vollständig durch den Kopf bestimmt und dient als Integritätsprüfung. Das Relief lässt sich in jedem Programm mit Rohdaten-Import darstellen: 16 Bit ohne Vorzeichen, Little-Endian, 512 Byte Versatz, Breite und Höhe aus dem Kopf.
.history ist eine Textdatei in Latin-1. Jede Zeile besteht aus einem
vierstelligen Code und einem Schlüssel mit optionalem Wert:
line = code " " key [ "=" value ]
code = 4DIGIT
0001 Parocontur
0101 xres=0.522000
0101 xnum=461
Die im Verlauf genannten Auflösungen entsprechen den Werten im Kopf des Reliefs. Eine Abweichung zeigt an, dass Relief und Verlauf nicht aus demselben Arbeitsschritt stammen.
Eine .pce ist offen lesbar: ein ZIP-Archiv mit JSON-Datensätzen und Nutzlasten mit festem 512-Byte-Kopf. Für das Lesen ist keine Herstellersoftware erforderlich.
Hinweise für den Betrieb
- Datenschutz. Der Kundensatz enthält Geburtsdatum, Kostenträger und Verordner. Eine .pce ist damit ein Gesundheitsdatensatz im Sinne von Art. 9 DSGVO und wird nur verschlüsselt übertragen und zugriffsgeschützt abgelegt.
- Prüfung beim Import. Sinnvoll sind drei Kontrollen: genau ein Kundensatz je Export, alle Verweise der Tabellen auflösbar, Dateigröße jeder Nutzlast passend zum Kopf.
- Archivierung. Da Container und Datensätze auf offenen Standards beruhen, bleibt der Inhalt unabhängig von der erzeugenden Software lesbar.
Ortavis liest .pce-Dateien direkt am Vorgang: Kunde, Aktionen und Projekte werden angezeigt, das Relief steht als drehbares 3D-Modell in der Mappe und wird wie ein STL-Scan vermessen. Auffälligkeiten aus den drei Kontrollen erscheinen als Hinweis am Import.
Normen und Grundlagen
- ZIP-Container: PKWARE, „.ZIP File Format Specification" (APPNOTE) — lokaler Dateikopf, zentrales Verzeichnis, Methoden 0 und 8.
- JSON: ECMA-404 und RFC 8259. Gleitkommazahlen im Kopf: IEEE 754, einfache Genauigkeit.
- Schutz von Gesundheitsdaten: Art. 9 und Art. 32 DSGVO.