How to create WMTS layer in SwiftUI SDK

1301
6
08-19-2023 09:44 PM
bux225
by
Emerging Contributor

I was successful adding a WMTS layer to my ArcGIS online map, streaming imagery.   However, I attempted to mimic the setup in SwiftUI SDK with no luck.

In ArcGIS Online:
1.  I added a new item:  URL -> ....WMTS....

2. Added the URL:  https://api.maxar.com/streaming/v1/ogc/gwc/service/wmts?service=WMTS&request=GetCapabilities&version...

3.  Custom parameter:  maxar_api_token, <token>

4.  Select a layer to add:  Imagery,  Matrix tile:  EPSG:3857

5.  Success

However, in iOS, not able to get the same results:

import SwiftUI

import ArcGIS

struct OverlayImagesView: View {

    @State private var map: Map = {

        let map = Map(basemapStyle: .arcGISStreets)

        map.initialViewpoint = Viewpoint(

            latitude: 39, longitude: -98, scale: 4e7

        )

        let url = URL(string: "https://api.maxar.com/streaming/v1/ogc/gwc/service/wmts?service=WMTS&request=GetCapabilities&version...")

        var wmtsLayer = WMTSLayer(url: url!, layerID: "Imagery", tileMatrixSetID: "EPSG:3857", preferredImageFormat: TileImageFormat.png)

       wmtsLayer.setCustomParameterValue("***********************", forKey: "maxar_api_token")

        map.addOperationalLayer(wmtsLayer)

        return map

    }()

    

    var body: some View {

        MapView(map: map)

    }

}

 

Builds and runs successfully but just shows basemap at all zoom levels

Tags (2)
0 Kudos
6 Replies
Ting
by Esri Contributor
Esri Contributor

Hi, welcome to Esri Community! I'm not a subject-matter expert on this topic so I reached out to our OGC team and they may share more details later after getting a Maxar API token.

Meanwhile, I'm wondering if it is related to spatial reference. Consider this snippet. When I create a map with WGS 84 SR, the demo WMTS service from NASA displays just fine. While if I use the default Web Mercator SR, the layer doesn't display. Could it be similar to your situation?

 

import SwiftUI
import ArcGIS

struct ContentView: View {
    @State private var map: Map = {
        // Esri WGS84 Topo basemap.
        let map = Map(
            item: PortalItem(
                portal: .arcGISOnline(connection: .anonymous),
                id: PortalItem.ID("6b4764e99107496f9193e4b68a77b73a")!
            )
        )
        let url = URL(string: "https://map1.vis.earthdata.nasa.gov/wmts-geo/1.0.0/WMTSCapabilities.xml")!
        let wmtsLayer = WMTSLayer(url: url, layerID: "AMSR2_Wind_Speed_Day")
        map.addOperationalLayer(wmtsLayer)
        return map
    }()
    
    @State private var mapWebMercator: Map = {
        let map = Map(basemapStyle: .arcGISTopographic)
        let url = URL(string: "https://map1.vis.earthdata.nasa.gov/wmts-geo/1.0.0/WMTSCapabilities.xml")!
        let wmtsLayer = WMTSLayer(url: url, layerID: "AMSR2_Wind_Speed_Day")
        map.addOperationalLayer(wmtsLayer)
        return map
    }()

    var body: some View {
        MapView(map: map)  // mapWebMercator
    }
}

 

---

p.s. when adding a code snippet in this forum, you can click the ellipsis button in the editor and use "Insert/Edit code example" button to make it code highlighted 😉

0 Kudos
bux225
by
Emerging Contributor

Much appreciated.  Gave your idea a try but no luck

0 Kudos
Ting
by Esri Contributor
Esri Contributor

I've asked for help from @MatveiStefarov . He's looking into the Maxar service.

0 Kudos
MatveiStefarov
Esri Contributor

Hello!  I tested this Maxar WMTS service, specifically the "Imagery" layer with EPSG:3857 tile matrix.  I was able to use it in both SceneViews and MapViews:

2023-08-29_151159 WmtsTest.png

 

If nothing from the WMTS service is showing, try checking the loadStatus on the layer, and layerViewState on the MapView.  You may find additional information there -- let us know if you spot any error messages or warnings.

 

Also, it looks like layers in this WMTS service are meant to be used as base layers, rather than an operational layer.  They are opaque tiled layers with global coverage, so they would completely cover up your arcGISStreets basemap.  You can create a custom basemap from this layer using init(baseLayer:) and use it for your Map instead.  Your other operational layers should now display on top of Maxar imagery.  You can also add a reference layer to your custom basemap.  For example, here I added an ArcGISVectorTiledLayer created from OSM Hybrid Reference to the basemap's referenceLayers.  It looked like this when I zoomed in:

2023-08-30_031009 WmtsTest.png

 

bux225
by
Emerging Contributor

Thanks Matvei.   Do you have this running in iOS?  I'm getting notloaded for load status

0 Kudos
Ting
by Esri Contributor
Esri Contributor

After some more discussion with Matvei, we think this might be a bug in our API and we need to look further.

 

Meanwhile,

1. This code can display the basemap correctly. Note a few things: the layer ID can be obtained from the XML doc; you'll need to set the token both on the "GetCapabilities" endpoint (the bug we are looking into), and the custom parameters, to ensure both the endpoint and further request are correctly authenticated.

let url = URL(string: "https://api.maxar.com/streaming/v1/ogc/gwc/service/wmts?service=WMTS&request=GetCapabilities&version=1.0.0&maxar_api_token=*****")!
let wmtsLayer = WMTSLayer(url: url, layerID: "Maxar:Imagery")
wmtsLayer.setCustomParameterValue("*****", forKey: "maxar_api_token")
return Map(basemap: Basemap(baseLayer: wmtsLayer))

 2. Alternatively, you can create an WMTSService and use it to construct the layer, such as

let service = WMTSService(url: URL(string: "https://api.maxar.com/streaming/v1/ogc/gwc/service/wmts?service=WMTS&request=GetCapabilities&version=1.0.0")!)
service.setCustomParameterValue("*****", forKey: "maxar_api_token")
try? await service.load()
let wmtsLayer = WMTSLayer(layerInfo: service.serviceInfo!.layerInfos[1])
map = Map(basemap: Basemap(baseLayer: wmtsLayer))

In this way, the service is authenticated with the API token so all further requests are valid.

 

Please let me know if it solves your problem.

p.s. apologies for the delayed response. It took us a while to figure out how to get a Maxar API token… 😉

0 Kudos