Skip to content
View on GitHub

Load a WFS feature table using an XML query.

Image of show WFS layer with XML query

Use case

QueryParameters objects can't represent all possible queries that can be made against a WFS feature service. For example, query parameters don't support wildcard searches. You can provide queries as raw XML strings, allowing you to access query functionality not available with QueryParameters.

How to use the sample

Run the sample and view the data loaded from the WFS feature table.

How it works

  1. Create a WFSFeatureTable and a FeatureLayer to visualize the table.
  2. Set the feature request mode to manualCache.
  3. Call populateFromService to populate the table with only those features returned by the XML query.

Relevant API

  • FeatureLayer
  • WFSFeatureTable
  • WFSFeatureTable.axisOrder
  • WFSFeatureTable.populateFromService

About the data

This service shows trees in downtown Seattle and the surrounding area. An XML-encoded GetFeature request is used to limit results to only trees of the genus Tilia.

For additional information, see the Seattle Downtown Features service on ArcGIS Online.

Tags

feature, OGC, query, service, web, WFS, XML

Sample Code

ShowWFSLayerWithXMLQueryView.swift
Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2025 Esri
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import ArcGIS
import SwiftUI

struct ShowWFSLayerWithXMLQueryView: View {
    /// The error shown in the error alert.
    @State private var error: (any Error)?

    /// Map with the Topographic basemap style.
    @State private var map = Map(basemapStyle: .arcGISTopographic)

    /// A Boolean value indicating whether the XML query is being loaded.
    @State private var isLoading = false

    var body: some View {
        MapViewReader { mapView in
            MapView(map: map)
                .overlay(alignment: .center) {
                    if isLoading {
                        loadingView
                    }
                }
                .task {
                    do {
                        isLoading = true
                        // A WFS (Web Feature Service) feature table for trees
                        // in the Seattle Downtown area.
                        let seattleTreesTable = WFSFeatureTable(
                            url: .seattleDowntownFeatures,
                            tableName: .seattleTreesDowntown
                        )
                        // Some WFS services return coordinates in (x,y) order,
                        // while others use (y,x) order.
                        // Set the axis order to not swap x and y.
                        seattleTreesTable.axisOrder = .noSwap
                        // Use manual cache mode so data must be explicitly
                        // loaded from the service.
                        seattleTreesTable.featureRequestMode = .manualCache
                        // Create a feature layer from the table.
                        let layer = FeatureLayer(featureTable: seattleTreesTable)
                        map.addOperationalLayer(layer)
                        // Populate the feature table with data from the WFS service using an XML query.
                        _ = try await seattleTreesTable.populateFromService(
                            usingXMLRequest: .xmlQuery,
                            clearCache: true
                        )
                        // Set the viewpoint to the extent of the data.
                        if let extent = seattleTreesTable.extent {
                            // Animate the map to the extent over 1 second.
                            await mapView.setViewpoint(
                                Viewpoint(boundingGeometry: extent),
                                duration: 1.0
                            )
                        }
                        // Mark that loading has completed.
                        isLoading = false
                    } catch {
                        // If an error occurs during loading, capture it to trigger an alert.
                        self.error = error
                    }
                }
                .errorAlert(presentingError: $error)
        }
    }

    var loadingView: some View {
        ProgressView(
            """
            Loading query
            data
            """
        )
        .padding()
        .background(.ultraThinMaterial)
        .clipShape(.rect(cornerRadius: 10))
        .shadow(radius: 50)
        .multilineTextAlignment(.center)
    }
}

private extension URL {
    /// A URL for the Seattle Downtown Features WFS GetCapabilities endpoint.
    static var seattleDowntownFeatures: URL {
        URL(string: "https://dservices2.arcgis.com/ZQgQTuoyBrtmoGdP/arcgis/services/Seattle_Downtown_Features/WFSServer?service=wfs&request=getcapabilities")!
    }
}

private extension String {
    /// This string matches the `typeNames` used in the XML query to identify the layer to query.
    static var seattleTreesDowntown: String {
        "Seattle_Downtown_Features:Trees"
    }

    /// XML query to request features from the WFS service.
    /// This specific query fetches only tree features where the "SCIENTIFIC" field equals "Tilia cordata".
    static var xmlQuery: String {
        """
        <wfs:GetFeature service="WFS" version="2.0.0" outputFormat="application/gml+xml; version=3.2"
          xmlns:Seattle_Downtown_Features="https://dservices2.arcgis.com/ZQgQTuoyBrtmoGdP/arcgis/services/Seattle_Downtown_Features/WFSServer"
          xmlns:wfs="http://www.opengis.net/wfs/2.0"
          xmlns:fes="http://www.opengis.net/fes/2.0"
          xmlns:gml="http://www.opengis.net/gml/3.2">
          <wfs:Query typeNames="Seattle_Downtown_Features:Trees">
            <fes:Filter>
              <fes:PropertyIsEqualTo>
                <fes:ValueReference>Seattle_Downtown_Features:SCIENTIFIC</fes:ValueReference>
                <fes:Literal>Tilia cordata</fes:Literal>
              </fes:PropertyIsEqualTo>
            </fes:Filter>
          </wfs:Query>
        </wfs:GetFeature>
        """
    }
}

#Preview {
    ShowWFSLayerWithXMLQueryView()
}

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.