Tempelmodelle in der Irrlicht Engine

by Jan Seyler und Nithi Rungtanapirom

Die Shapelib

C++ Library zum Arbeiten mit Shapefiles

Als wir uns zu Anfang unseres Projekts mit der Verarbeitung von ArcGIS Shapedateien beschäftigt haben, sind wir nach einiger Zeit des Rumprobierens auf die Shapelib gestoßen.
Hierbei handelt es sich um eine C/C++ Library zum Arbeiten mit Shapefiles. Die Library läuft unter der GNU Lizenz und ist somit frei zugänglich und anpassbar.
Die Internetseite bietet eine vollständige API, welche ich an dieser Stelle wärmstens empfehle.

Wie die Shapelib funktioniert und wie wir sie angewendet haben, möchte ich hier kurz darstellen:

Die Dateien *.shp und *.shx werden bei der Benutzung der Shapelib gleichzeitig gelesen und als Objekt der Klasse "SHPHandle" gespeichert. Dies beinhaltet aber mehrere Unterobjekte der Klasse "SHPObject".

Um zuerst einmal einige wichtige Information über die Shapefiles zu erhalten, wird die Funktion SHPGetInfo aufgerufen. Dadurch erfährt man die Anzahl der Unterobjekte, den Typ der Shapefiles, und die Schranken der beinhalteten Daten.

Ein Objekt der Klasse "SHPObject" hat folgende Struktur:

typedef struct
{
int nSHPType; Shape Type

int nShapeId; Shape Number (-1 is unknown/unassigned)

int nParts; # of Parts (0 implies single part with no info)
int *panPartStart; Start Vertex of part
int *panPartType; Part Type (SHPP_RING if not SHPT_MULTIPATCH)

int nVertices; Vertex list
double *padfX;
double *padfY;
double *padfZ; (all zero if not provided)
double *padfM; (all zero if not provided)

double dfXMin; Bounds in X, Y, Z and M dimensions
double dfYMin;
double dfZMin;
double dfMMin;

double dfXMax;
double dfYMax;
double dfZMax;
double dfMMax;
} SHPObject;


Dabei haben die Arrays panPartStart und panPartType die Größe gleich nParts, die Arrays padfX, padfY, padfZ, padfM dann die Größe gleich nVertices. Ist SHPObject vom Typ 1 (Punkt), 3 (Polylinie), 5 (Polygon) oder 8 (Multipoint), so handelt es sich dabei um ein zweidimensionales Objekt, und alle Einträge padfZ und padfM sind dann gleich Null, wie z.B. in unseren Dateien.

Neben den *.shp und *.shx Dateien gibt es auch die *.dbf-Datei. Diese speichert die Attribute der Shapefiles und wird beim Auslesen als Objekt der Klasse "DBFHandle" gespeichert. Sie kann mehrere Felder enthalten, im jeweiligen Feld gibt es aber idR genauso viel Einträge wie Unterobjekte des SHPHandles. Mithilfe von DBFGetFieldCount() kann man die Anzahl der Felder, von DBFGetFieldInfo(), den Namen des jeweiligen Feldes, die Größe und ggf. die Genauigkeit der Dezimaldarstellung auslesen.

Im Rahmen unseres Softwarepraktikums haben wir folgende Shapefiles verwendet:

  • Contour. Typ 3, beschreibt jedoch die Höhenlinien des Geländes. Die entsprechenden Höhen sind in der DBF-Datei im Feld 0 gespeichert. Wir benötigen die Funktion
    DBFReadDoubleAttribute() für das Objekt der Klasse "DBFHandle". Um die x- und y-Koordinaten zu lesen, wird jede
    einzelne Höhelinie als Objekt der Klasse "SHPObject" erzeugt und die Einträge padfX bzw.
    padfY werden vermöge object->padfX[] bzw. object->padfY[] gelesen.

  • Water_Poly. Typ 5. Ein Polygon in kann konvex oder konkav sein, oder sogar aus mehreren Teilen bestehen. Im letzteren Fall hat der Eintrag "nParts" des SHPObjects einen entsprechenden Wert. Jedes einzelne Polygon beginnt und endet mit demselben Punkt. Um zu erfahren, mit welchem Punkt der neue Teil des Polygons beginnt, gibt es "panPartStart" im SHPObject. Dabei ist zu bestimmen, ob der Punkt innerhalb des Polygons liegt.
    Mehr dazu erfährt man unter Scanline-Algorithmus.


Anmerkung: da es sich hier um objektorientierte Programmierung handelt, muss man am Ende alle erzeugte Objekte wieder löschen. Dazu gibt es die Funktionen SHPClose() für SHPHandle, DBFClose() für DBFHandle, und SHPDestroyObject() für SHPObjekt (also der einzelne Eintrag von SHPHandle).