Der Geoff-Karteneditor

Eclipse Geoff als technische Basis für einen Karteneditor

Erdal Karaca

© Shutterstock / MskPhotoLife

Mit LocationTech Geoff steht ein Framework zur Verfügung, das als Basis für die Entwicklung eigener Anwendungen zur Visualisierung von Geodaten dienen kann. In diesem Artikel geht es um die technische Realisierung eines Projekts, das die Möglichkeit bereitstellt, geografische Karten über einen Eclipse-Editor zu erstellen und die Ergebnisse im Web zu veröffentlichen.

In Eclipse Magazin 3.15 haben wir das Geoff-Projekt bereits in seinen Grundzügen vorgestellt. Dort wurde das Tortenbacken als Analogie für die Erstellung geografischer Karten herangezogen. Eine Karte besteht demnach aus mehreren Schichten, von der jede eine andere Thematik behandelt: die Grundschicht mit dem gerasterten Straßennetz, dann – je nach Anwendungsfall – Vektordaten zur Verdeutlichung bzw. Ortung von Objekten der realen Welt (so genannte Points of Interest). Diese Analogie hilft erneut bei der Entwicklung eines Karteneditors, der sich in die Eclipse-IDE installieren lässt und dessen Funktionalität im Folgenden beschrieben wird. Der Editor soll die folgenden Anforderungen erfüllen:

  • Integration in die Eclipse-IDE und Eclipse-RCPs
  • Undo-/Redo-Support
  • Erweiterbarkeit
  • Deployment der Karte in einen Webcontainer

Integration in die Eclipse-IDE und Eclipse-RCPs

Die nahtlose Integration in die Eclipse-Infrastruktur sei als Selbstverständlichkeit vorausgesetzt. Interessanter ist die Frage, in welchem „Modus“ der Editor selbst und die zugehörigen Views/Wizards etc. programmiert werden sollen. Unter Modus ist hier das API nach Eclipse 3.x oder 4.x gemeint. Da die Kompatibilitätsebene der 4.x-Plattform mit dem 3.x-API inzwischen relativ stabil läuft, wird der Editor und dessen Views über 3.x-Mechanismen bereitgestellt, jedoch der Komfort der Injection Engine von 4.x genutzt.

Ein Eclipse-Editor kann generell beliebig (mit jeweils unterschiedlichem Input) geöffnet werden. Unterschiedliche Aspekte des Editors können von unterschiedlichen Views behandelt werden. Findet ein Wechsel des Editors statt, so aktualisieren die Views ihre Darstellung abhängig vom behandelten Aspekt. Eine Implementierung dieses Ansatzes findet sich im Konzept der PageBook View wieder. Eine PageBook View horcht an aktivierten Parts der Workbench und ermittelt, ob der Part ein relevanter Sender von Informationen für die PageBook View darstellt.

Da es noch keine native 4.x-Lösung für PageBook Views gibt, wird die 3.x-Variante als Container/Wrapper verwendet und die eigentliche Behandlung an ein 4.x POJO weitergeleitet. Auf ähnliche Weise werden auch Eclipse 3.x Commands bereitgestellt: Es wird ein IHandler des 3.x-APIs als Wrapper verwendet, der in der Execute-Methode an das 4.x POJO weitergeleitet wird (Listing 1).

@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
  IEditorPart activeEditor = HandlerUtil.getActiveEditor(event);
  IEclipseContext context = (IEclipseContext) activeEditor.getSite().getService(IEclipseContext.class);
  ISelection currentSelection = HandlerUtil.getCurrentSelection(event);
  final IEclipseContext child = context.createChild();
  child.set(ISelection.class, currentSelection);
  child.set("parameters", event.getParameters());
  Class<?> type = getPOJOType();
  Object make = ContextInjectionFactory.make(type, child);
  ContextInjectionFactory.invoke(make, Execute.class, child);
  child.dispose();
  return null;
}

Die Ausführung der eigentlichen Logik im 4.x POJO kann dann wie folgt aussehen:

@Execute
public void execute(ISelection selection, @Named("parameters") Map params) {
  // Abarbeitung der Logik hier... 
}

Wer sich an dieser Stelle für mehr Details interessiert, kann einen Blick auf die Sourcen im LocationTech GitHub werfen.

Undo-/Redo-Support

Eine weitere größere Anforderung ist der Support für Undo/Redo. Während diese Anforderung sich trivial anhören mag, ist ihre Berücksichtigung maßgeblich für die weitere Entwicklung des Editors. Zur Erinnerung sei angemerkt, dass das gesamte Metamodell der Geomapping-Domäne als Ecore-Modell des Eclipse-Modeling-Frameworks abgebildet ist. EMF bietet von Haus aus Support für Undo/Redo, indem es jede von einem Modul modifizierte Aktion in einem Command ausführt, der sich rückgängig machen lässt. Eine Aktion im Kontext des Editors kann z. B. sein:

  • Layer zur Karte hinzufügen oder Layer löschen
  • Visualisierungsreihenfolge von Layern ändern
  • Karte zoomen
  • Karte verschieben
  • Eigenschaften der Karte ändern usw.

Die zentrale Klasse der Geomapping-Domäne ist GeoMap. Es bietet sich also an, eine Instanz dieser Klasse in einem Service zu kapseln und alle relevanten Aktionen über den Service verfügbar zu machen (Abb. 1).

Abb. 1: Auszug der Methoden vom Editing-Service

Abb. 1: Auszug der Methoden vom Editing-Service

Die meisten der Methoden in der obigen Abbildung sind selbsterklärend. Etwas mehr Hintergrund erfordert hingegen die Methode createAddResourceCommand: In bestimmten Fällen werden Ressourcen für die Visualisierung benötigt, z. B. Icondateien als Symbol für Punkte in einem Layer. Die genannte Methode erzeugt einen Command, der einen Link zu einer Ressource annimmt und zur Ausführungszeit die Ressource in das Zielverzeichnis kopiert. Wird der Command rückgängig gemacht, wird auch die Ressource wieder gelöscht. Das bedeutet also, dass der Service die Ressourcen selbst verwaltet.

Erweiterbarkeit

Erweiterbarkeit ist durch Nutzung der Eclipse-Mechanismen standardmäßig gegeben. Zur Verdeutlichung dieses Aspekts schauen wir uns eine konkrete Erweiterung an. In einem separaten Plug-in soll der Editor um die Funktionalität erweitert werden, georeferenzierte Bilder (z. B. Bildaufnahmen über ein Smartphone mit eingeschaltetem GPS) in einem Verzeichnis als Layer zur Karte hinzuzufügen. Voraussetzungen hierfür:

  • Auslesen der GPS-Koordinaten aus den Bildern
  • Icon, das die Position auf der Karte verdeutlicht
  • jQuery UI zur Anzeige eines angeklickten Icons in einem Dialog

Für das Auslesen der GPS-Koordinaten aus den Bildern nutzen wir das Framework Metadata Extractor von Drew Noakes (Listing 2).

Metadata md = ImageMetadataReader.readMetadata(file.getContents());
GpsDirectory gpsDir = md.getFirstDirectoryOfType(GpsDirectory.class);
GeoLocation geoLocation = gpsDir.getGeoLocation();
double longitude = geoLocation.getLongitude(); // x-Koordinate 
double latitude = geoLocation.getLatitude(); // y-Koordinate

Das Icon zur Anzeige des Aufnahmeorts ist mithilfe eines Vektorprogramms schnell entworfen. Die gesammelten Metadaten (GPS-Koordinaten und Bildpfade) werden dann wie in Listing 3 als zusätzlicher Layer zur Karte hinzugefügt.

VectorSource vectorSource = Geoff.vectorSource();
VectorLayer layer = Geoff.vectorLayer(vectorSource);

for (GeoTaggedImage img : images) {
  XYZLocation xyLocation = Geoff.xyLocation(img.longitude, img.latitude, Geoff.EPSG4326_WGS84);
  Feature feature = Geoff.feature(Geoff.pointGeom(xyLocation), Geoff.style(Geoff.icon(markerTarget)));
  feature.getProperties().add(Geoff.featureProperty("src", img.imageSrc));
  feature.setOnclick("geoff_designer_geoimages_onFeatureClick");
  vectorSource.getFeatures().add(feature);
}

Im Code wird ein Vektorlayer erzeugt, der Punktgeometrien enthält, die durch ein Icon symbolisiert werden. Sobald das Icon auf der Karte angeklickt wird, soll ein Dialog erscheinen, in dem das Bild selbst zentriert dargestellt wird. Hierzu wird der onclick Handler für die Geometrien gesetzt. Listing 4 zeigt, wie der Handler selbst programmiert wird, bevor er als JavaScript-Datei in der Kartendatei abgelegt wird.

function geoff_designer_geoimages_onFeatureClick(feature) {
  var src = feature.get("src");
  var imageDialog = $('#geoff_designer_geoimages_onFeatureClick_dialog');

  if (!imageDialog[0]) {
    imageDialog = $("<div id='geoff_designer_geoimages_onFeatureClick_dialog' style='display: none;'></div>");
    var img = $("<img id='geoff_designer_geoimages_onFeatureClick_image' src=''></img>");
    imageDialog.append(img);
    $(document.body).append(imageDialog);
  }

  var imageTag = $('#geoff_designer_geoimages_onFeatureClick_image');
  srcParts = src.split("/");
  imageTag.attr('src', src);
  imageTag.load(function() {
    imageDialog.dialog({
      modal : true,
      resizable : false,
      draggable : false,
      width : 'auto',
      title : srcParts[srcParts.length - 1]
    });
  });
}

Deployment der Karte in einen Webcontainer

Die produzierten Ergebnisse wie Kartendatei, Skripte und Ressourcen laufen in einer Webumgebung. Der Editor selbst benötigt daher einen Webserver, um diese anzufordern und richtig darzustellen. Hierzu werden sämtliche Dateien in einem Webprojekt in der IDE verwaltet und als Modul zu einem Webserver hinzugefügt. Die Web-Plug-ins von Eclipse liefern hier bereits alle erforderlichen Tools. Eine Anleitung zur Nutzung der Webtools findet sich z. B. in der Hilfe von Eclipse.

Fazit

In diesem Artikel wurde das Geoff-Projekt eingesetzt, um einen vollwertigen Editor für das Entwerfen von einfach strukturierten geografischen Karten zu entwickeln. Da der Editor in der Eclipse-IDE läuft und Ressourcen in einem Projekt im Workspace gehalten werden, lassen sich weitere Plug-ins verwenden, die weitaus komplexere Szenarien zur Visualisierung von Geodaten ermöglichen. WalWare StatET bietet beispielsweise die Möglichkeit, über die Statistikplattform R statistische Auswertungen in der Eclipse-IDE selbst durchzuführen und hierüber erstellte Geodaten in die Karte zu integrieren.

Aufmacherbild: green car and pen on map of Europe von Shutterstock.com / Urheberrecht: MskPhotoLife

Geschrieben von
Erdal Karaca
Erdal Karaca
Erdal Karaca hat Geoinformatik an der Fachhochschule Oldenburg studiert. Als freiberuflicher IT-Berater und Software-Engineer unterstützt er Unternehmen bei der Entwicklung ihrer Softwareprodukte auf Basis von Open-Source-Technologien.
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: