a.erbeesri-de-esridist

Offline Basemaps in ArcGIS Runtime Apps

Blog Post created by a.erbeesri-de-esridist Employee on Mar 26, 2015

Eine digitale Karte besteht in der Regel aus Basemaps und Vektordaten, welche in Form von Layern übereinander dargestellt werden. Basemaps sind georeferenzierte Bilder ohne abrufbare geografische Informationen. Sie werden nicht sehr häufig aktualisiert und dienen im Wesentlichen der Orientierung. Vektordaten hingegen sind Geo-Objekte (Features), die jeweils aus einer Geometrie und zugehörigen Informationen bestehen. Sie werden meistens oberhalb der Basemaps mit einer geeigneten Symbologie dargestellt. Vektordaten können im Client zum Informieren, Analysieren und auch zur Datenerfassung genutzt werden.

 

ArcGIS bietet verschiedene Möglichkeiten, Basemaps und Vektordaten auch offline auf unterschiedlichen Geräten nutzen zu können. In diesem Blog wird sich näher mit Offline-Vektordaten beschäftigt. Im Folgenden werden wir uns näher mit Offline-Basemaps und deren Nutzung in Apps auf Basis von ArcGIS Runtime beschäftigen.

 

 

Wie komme ich zu einer Offline Basemap?

 

Vorbereitung

 

Vorab müssen sich grundlegende Gedanken über das Projekt gemacht werden, um die richtigen Entscheidungen zu treffen, zB:

 

  • Wie groß ist das geografische Gebiet und welche Skalierung wird offline benötigt? Das hat direkte Auswirkung auf die Größe des Datenpakets und kann sehr schnell Richtung vieler Gigabyte gehen.
  • Soll die Offline Basemap zentral erzeugt und anschließend auf die Geräte kopiert werden? Hierzu wird eine Infrastruktur zum Verteilen der Daten benötigt.
  • Soll die Offline Basemap in jeder App direkt von einem Tiled MapService exportiert werden? Hier muss unter anderem die Wartezeit der Anwender und die Performance des GIS Servers bei vielen gleichzeitigen Zugriffen geprüft werden.

 

Formate

 

Offline Basemaps können als ArcGIS for Server Compact Cache oder als Tile Package erzeugt werden. Ein Compact Cache ist eine Ordnerstruktur mit mehreren Dateien und ein Tile Package ist ein geziptes File mit der Endung *.tpk. Alle ArcGIS Runtime SDKs können mit beiden Formaten umgehen. Sie sind auch gleich performant. Für die Verteilung sind Tile Packages zu empfehlen, da es nur eine einzelne Datei ist.

 

Datenquellen

 

Es können Tiled MapServices und lokale Daten zur Erzeugung einer Offline Basemap genutzt werden.

 

 

In den Einstellungen der Services muss der Export erlaubt werden.

 

Noch eine Info speziell zum Export von ArcGIS Online Basemaps:

Die Standard Basemaps auf ArcGIS.com sind frei zugänglich und können nicht exportiert werden. Für den Export stellt Esri einen weiteren Server mit den gleichen Basemaps bereit. Dafür ist zwar eine Authentifizierung (ArcGIS Developer Account oder Mitglieder einer ArcGIS Online Subskription) notwendig, der Export selber verursacht aber keine Kosten. Das bedeutet für Entwickler, dass eventuell im Code der Host der URL ausgetauscht werden muss:

 

http://services.arcgisonline.com/arcgis/rest/services/World_Topo_Map/MapServer

                                                            zu

http://tiledbasemaps.arcgis.com/arcgis/rest/services/World_Topo_Map/MapServer

 

Werkzeuge zum Erstellen von Offline Basemaps

 

ArcGIS for Desktop bietet verschiedene Werkzeuge, um Offline Basemaps in den zwei Formaten sowohl aus lokalen Daten als auch von Services zu exportieren. Diese Aufgaben können auch mit Python automatisiert werden.

 

Weiterhin verfügen alle ArcGIS Runtime SDKs über Methoden zum Exportieren von Offline Basemaps von Services direkt in der App.

 

 

Exportieren von Offline Basemaps mit ArcGIS Runtime

 

Mit allen ArcGIS Runtime SDKs können Daten von Tiled MapServices exportiert und offline genutzt werden. Die Vorgehensweise dafür ist bei allen identisch. Für die folgenden Schritte wird ein Tiled MapService mit entsprechenden Einstellungen und Nutzerrechten vorausgesetzt.

 

So wird es gemacht (ArcGIS Runtime SDK for .NET):

 

     1. Erzeugen eines ExportTileCacheTask Objekts:

 

_exportTileCacheTask = new ExportTileCacheTask(exportArcGisTiledMapServiceLayerServiceUri);

 

     2. Parameter für den Export festlegen, wir wollen als Format ein Tile Package, nicht alle Scales und nur ein bestimmtes Gebiet

 

_generateTileCacheParameters = new GenerateTileCacheParameters
{
        Format = ExportTileCacheFormat.TilePackage,
        MinScale = CurrentEsriMapView.MinScale,
        MaxScale = CurrentEsriMapView.MaxScale,
        GeometryFilter = _areaToExportGraphic.Geometry.Extent
};

 

     3. Größe und Anzahl der angeforderten Tiles mit der Funktion EstimateTileCacheSizeAsync prüfen und falls notwendig Probleme abfangen.

 

var exportTileCacheJobStatusProgress = new Progress<ExportTileCacheJob>();
exportTileCacheJobStatusProgress.ProgressChanged += (p, q) =>

{
                if (q.Messages == null)
                               return;
                //do something
};

await _exportTileCacheTask.EstimateTileCacheSizeAsync(_generateTileCacheParameters,
                (result, ex) => // Callback for when estimate operation has completed
                {
                               if (ex == null) // Check whether operation completed with errors
                               {
                                               _model.SetMessageInfo(string.Format("Tiles: {0} - Size (kb): {1:0}", result.TileCount, result.Size/1024));
                               }
                               else
                               {
                                               _model.SetMessageInfo(string.Format("Error: {0}", ex.Message));
                               }
                }, TimeSpan.FromSeconds(5), CancellationToken.None, exportTileCacheJobStatusProgress);

 

     4. Erzeugen des Tile Packages auf dem Server und Download zum Client inklusive Abfrage des Status:

 

var downloadOptions = new DownloadTileCacheParameters(_exportMapPath)
{
         OverwriteExistingFiles = true
};

var generateStatusCheckProgress = new Progress<ExportTileCacheJob>();
generateStatusCheckProgress.ProgressChanged += (p, q) =>

{
         if (q.Messages.Count < 1)
                   return;
         _model.SetMessageInfo(string.Format("{0}", q.Messages[1].Description));
};

var downloadProgressChanged = new Progress<ExportTileCacheDownloadProgress>();
downloadProgressChanged.ProgressChanged += (p, q) =>

{
         //do something
};


var downloadTileCacheResult = await _exportTileCacheTask.GenerateTileCacheAndDownloadAsync(
         _generateTileCacheParameters,
         downloadOptions, TimeSpan.FromSeconds(5), CancellationToken.None, generateStatusCheckProgress,
         downloadProgressChanged);

 

Wenn alles sauber durchgelaufen ist haben wir nun eine Offline Basemap als Tile Package lokal auf unserem Gerät gespeichert.

 

 

Implementieren von Offline Basemaps in ArcGIS Runtime

 

Das Einbinden von Offline Basemaps in die Karte ist relativ simpel. In allen ArcGIS Runtime SDKs gibt es das Objekt ArcGisLocalTiledLayer. Diesem geben wir den Pfad zu unserem Tile Package und fügen es anschließend der LayerCollection der Karte hinzu.

 

So wird es gemacht (ArcGIS Runtime SDK for .NET):

 

var arcGisLocalTiledLayer = new ArcGISLocalTiledLayer(@"c:\temp\basemap.tpk");
var offlineMap = new Map();
offlineMap.Layers.Add(arcGisLocalTiledLayer);

var mapView = new MapView { Map = offlineMap };
CurrentEsriMapView = mapView;

 

 

Weitere Informationen

 

Outcomes