I am unable to load a spatially enabled raster .png file into my map. The raster is made up of three files:
- sketch.png
- sketch.pgwx
- sketch.png.aux.xml
It loads fine in ArcMap. In attachment "ArcMap.png", the red lines are coming from the raster.
By using raster.load(completion: ) to set my own completion block, I was able to see that it is getting an error:
Failed to open raster dataset: /Users/Worth/Library/Developer/CoreSimulator/Devices/5690DA36-3E43-4DE1-881A-CF85BE5E2C43/data/Containers/Bundle/Application/79766C92-DBAD-4169-86AC-1CAECD4FABC9/testMapView.app/sketch.png
Here is my ViewController.swift source code:
import UIKit
import ArcGIS
<SPAN class="keyword token">class</SPAN> <SPAN class="token class-name">ViewController</SPAN><SPAN class="operator token">:</SPAN> UIViewController <SPAN class="punctuation token">{</SPAN>
@IBOutlet weak var mapView<SPAN class="operator token">:</SPAN> AGSMapView<SPAN class="operator token">!</SPAN>
<SPAN class="keyword token">private</SPAN> var map<SPAN class="operator token">:</SPAN> AGSMap<SPAN class="operator token">!</SPAN>
<SPAN class="keyword token">private</SPAN> var raster<SPAN class="operator token">:</SPAN> AGSRaster<SPAN class="operator token">!</SPAN>
<SPAN class="keyword token">private</SPAN> var rasterLayer<SPAN class="operator token">:</SPAN> AGSRasterLayer<SPAN class="operator token">!</SPAN>
override func <SPAN class="token function">viewDidLoad</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN>
super<SPAN class="punctuation token">.</SPAN><SPAN class="token function">viewDidLoad</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="comment token">// create map with assigned spatial reference "web mercator (alternate sphere)"</SPAN>
self<SPAN class="punctuation token">.</SPAN>map <SPAN class="operator token">=</SPAN> <SPAN class="token function">AGSMap</SPAN><SPAN class="punctuation token">(</SPAN>spatialReference<SPAN class="operator token">:</SPAN> AGSSpatialReference<SPAN class="punctuation token">.</SPAN><SPAN class="token function">webMercator</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="comment token">// assign a basemap to map</SPAN>
self<SPAN class="punctuation token">.</SPAN>map<SPAN class="punctuation token">.</SPAN>basemap <SPAN class="operator token">=</SPAN> AGSBasemap<SPAN class="punctuation token">.</SPAN><SPAN class="token function">topographic</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="comment token">// create raster</SPAN>
self<SPAN class="punctuation token">.</SPAN>raster <SPAN class="operator token">=</SPAN> <SPAN class="token function">AGSRaster</SPAN><SPAN class="punctuation token">(</SPAN>name<SPAN class="operator token">:</SPAN> <SPAN class="string token">"sketch"</SPAN><SPAN class="punctuation token">,</SPAN> extension<SPAN class="operator token">:</SPAN> <SPAN class="string token">"png"</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="comment token">// for debugging, verify we can load the raster</SPAN>
self<SPAN class="punctuation token">.</SPAN>raster<SPAN class="punctuation token">.</SPAN><SPAN class="token function">load</SPAN><SPAN class="punctuation token">(</SPAN>completion<SPAN class="operator token">:</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="punctuation token">(</SPAN>error<SPAN class="operator token">:</SPAN> Error<SPAN class="operator token">?</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">-</SPAN><SPAN class="operator token">></SPAN> Void in
<SPAN class="keyword token">if</SPAN> let error <SPAN class="operator token">=</SPAN> error <SPAN class="punctuation token">{</SPAN>
<SPAN class="token function">print</SPAN><SPAN class="punctuation token">(</SPAN>error<SPAN class="punctuation token">.</SPAN>localizedDescription<SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="comment token">// create raster layer using the raster and name it</SPAN>
self<SPAN class="punctuation token">.</SPAN>rasterLayer <SPAN class="operator token">=</SPAN> <SPAN class="token function">AGSRasterLayer</SPAN><SPAN class="punctuation token">(</SPAN>raster<SPAN class="operator token">:</SPAN> self<SPAN class="punctuation token">.</SPAN>raster<SPAN class="punctuation token">)</SPAN>
self<SPAN class="punctuation token">.</SPAN>rasterLayer<SPAN class="punctuation token">.</SPAN>name <SPAN class="operator token">=</SPAN> <SPAN class="string token">"sketch raster"</SPAN>
<SPAN class="comment token">// add rasterLayer to the map's operationalLayers</SPAN>
self<SPAN class="punctuation token">.</SPAN>map<SPAN class="punctuation token">.</SPAN>operationalLayers<SPAN class="punctuation token">.</SPAN><SPAN class="token function">add</SPAN><SPAN class="punctuation token">(</SPAN>self<SPAN class="punctuation token">.</SPAN>rasterLayer<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">for</SPAN> <SPAN class="keyword token">case</SPAN> let layer as AGSLayer in self<SPAN class="punctuation token">.</SPAN>map<SPAN class="punctuation token">.</SPAN>operationalLayers <SPAN class="punctuation token">{</SPAN>
<SPAN class="token function">print</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">"\nSpatial reference for raster layer \"\(layer.name)\":"</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">if</SPAN> let spatialReference <SPAN class="operator token">=</SPAN> layer<SPAN class="punctuation token">.</SPAN>spatialReference <SPAN class="punctuation token">{</SPAN>
<SPAN class="token function">print</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">" WKID = \(spatialReference.wkid)\n"</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN> <SPAN class="keyword token">else</SPAN> <SPAN class="punctuation token">{</SPAN>
<SPAN class="token function">print</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">" <undefined>\n"</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="comment token">// assign map to mapView</SPAN>
self<SPAN class="punctuation token">.</SPAN>mapView<SPAN class="punctuation token">.</SPAN>map <SPAN class="operator token">=</SPAN> map
<SPAN class="comment token">// zoom to hard-coded Esri Charlotte office location where raster should appear</SPAN>
let point <SPAN class="operator token">=</SPAN> <SPAN class="token function">AGSPoint</SPAN><SPAN class="punctuation token">(</SPAN>x<SPAN class="operator token">:</SPAN> <SPAN class="operator token">-</SPAN><SPAN class="number token">8992543.0</SPAN><SPAN class="punctuation token">,</SPAN> y<SPAN class="operator token">:</SPAN> <SPAN class="number token">4177500.0</SPAN><SPAN class="punctuation token">,</SPAN> spatialReference<SPAN class="operator token">:</SPAN> AGSSpatialReference<SPAN class="punctuation token">.</SPAN><SPAN class="token function">webMercator</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
let viewpoint <SPAN class="operator token">=</SPAN> <SPAN class="token function">AGSViewpoint</SPAN><SPAN class="punctuation token">(</SPAN>center<SPAN class="operator token">:</SPAN> point<SPAN class="punctuation token">,</SPAN> scale<SPAN class="operator token">:</SPAN> <SPAN class="number token">2400.0</SPAN><SPAN class="punctuation token">)</SPAN>
mapView<SPAN class="punctuation token">.</SPAN><SPAN class="token function">setViewpoint</SPAN><SPAN class="punctuation token">(</SPAN>viewpoint<SPAN class="punctuation token">)</SPAN>
<SPAN class="comment token">// use KVO on drawStatus to know when it thinks it is finished drawing</SPAN>
mapView<SPAN class="punctuation token">.</SPAN><SPAN class="token function">addObserver</SPAN><SPAN class="punctuation token">(</SPAN>self<SPAN class="punctuation token">,</SPAN> forKeyPath<SPAN class="operator token">:</SPAN> <SPAN class="string token">"drawStatus"</SPAN><SPAN class="punctuation token">,</SPAN> options<SPAN class="operator token">:</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="keyword token">new</SPAN><SPAN class="punctuation token">,</SPAN> context<SPAN class="operator token">:</SPAN> nil<SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN>
override func <SPAN class="token function">didReceiveMemoryWarning</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN>
super<SPAN class="punctuation token">.</SPAN><SPAN class="token function">didReceiveMemoryWarning</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN>
override func <SPAN class="token function">observeValue</SPAN><SPAN class="punctuation token">(</SPAN>forKeyPath keyPath<SPAN class="operator token">:</SPAN> String<SPAN class="operator token">?</SPAN><SPAN class="punctuation token">,</SPAN>
of object<SPAN class="operator token">:</SPAN> Any<SPAN class="operator token">?</SPAN><SPAN class="punctuation token">,</SPAN>
change<SPAN class="operator token">:</SPAN> <SPAN class="punctuation token">[</SPAN>NSKeyValueChangeKey <SPAN class="operator token">:</SPAN> Any<SPAN class="punctuation token">]</SPAN><SPAN class="operator token">?</SPAN><SPAN class="punctuation token">,</SPAN>
context<SPAN class="operator token">:</SPAN> UnsafeMutableRawPointer<SPAN class="operator token">?</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN>
guard let keyPath <SPAN class="operator token">=</SPAN> keyPath <SPAN class="keyword token">else</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">return</SPAN> <SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">if</SPAN> keyPath <SPAN class="operator token">==</SPAN> <SPAN class="string token">"drawStatus"</SPAN> <SPAN class="punctuation token">{</SPAN>
<SPAN class="keyword token">if</SPAN> mapView<SPAN class="punctuation token">.</SPAN>drawStatus <SPAN class="operator token">==</SPAN> AGSDrawStatus<SPAN class="punctuation token">.</SPAN>completed <SPAN class="punctuation token">{</SPAN>
guard let viewpoint <SPAN class="operator token">=</SPAN> self<SPAN class="punctuation token">.</SPAN>mapView<SPAN class="punctuation token">.</SPAN><SPAN class="token function">currentViewpoint</SPAN><SPAN class="punctuation token">(</SPAN>with<SPAN class="operator token">:</SPAN> AGSViewpointType<SPAN class="punctuation token">.</SPAN>centerAndScale<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">else</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">return</SPAN> <SPAN class="punctuation token">}</SPAN>
<SPAN class="token function">print</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">"\ndrawStatus == .completed"</SPAN><SPAN class="punctuation token">)</SPAN>
guard let point <SPAN class="operator token">=</SPAN> viewpoint<SPAN class="punctuation token">.</SPAN>targetGeometry as<SPAN class="operator token">?</SPAN> AGSPoint <SPAN class="keyword token">else</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">return</SPAN> <SPAN class="punctuation token">}</SPAN>
<SPAN class="token function">print</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">"point: (x: \(point.x), y: \(point.y)), scale: \(viewpoint.targetScale)"</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>What is the best way to load a .png file as a raster in ArcGIS Runtime SDK for iOS?