Skip to content

Instantly share code, notes, and snippets.

@nixta
Last active November 22, 2019 17:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nixta/9db8be083b1823f1cbbe87db5cef6325 to your computer and use it in GitHub Desktop.
Save nixta/9db8be083b1823f1cbbe87db5cef6325 to your computer and use it in GitHub Desktop.
Custom Query
public enum QueryError: LocalizedError {
case couldNotParseJSON
case unexpectedJSONResponse
}
func doQuery(layerURL: URL, mapPoint: AGSPoint, fields: [String] = ["*"], returnGeometry: Bool = true, completion: (([AGSGraphic]?, Error?) -> Void)? = nil) {
var mapPointData: Data?
do {
let mapPointJSON = try mapPoint.toJSON()
mapPointData = try JSONSerialization.data(withJSONObject: mapPointJSON)
} catch {
print("Could not convert AGSPoint to JSON: \(error.localizedDescription)")
completion?(nil, error)
return
}
guard mapPointData != nil,
let mapPointJSONString = String(data: mapPointData!, encoding: .utf8) else {
completion?(nil, QueryError.couldNotParseJSON)
return
}
let inSR = mapPoint.spatialReference ?? AGSSpatialReference.webMercator()
let outSR = mapView.spatialReference ?? AGSSpatialReference.webMercator()
let parameters: [String : Any] = [
"f": "json",
"geometry": mapPointJSONString,
"geometryType": "esriGeometryPoint",
"inSR": inSR.wkid,
"maxAllowableOffset": 0.000000,
"outFields": fields.joined(separator: ","),
"outSR": outSR.wkid,
"returnDistinctValues": false,
"returnGeometry": returnGeometry,
"returnM": true,
"returnZ": true,
"spatialRel": "esriSpatialRelIntersects"
]
let queryUrl = layerURL.appendingPathComponent("query")
let operation = AGSJSONRequestOperation(remoteResource: nil, url: queryUrl, queryParameters: parameters)
operation.registerListener(self) { (result, error) in
if let error = error {
print("Error performing query! \(error.localizedDescription)")
completion?(nil, error)
return
}
guard let result = result as? [String: Any],
let fields = (result["fields"] as? [Any])?.compactMap({ try? AGSField.fromJSON($0) as? AGSField }),
let graphics = (result["features"] as? [[String: Any]])?.compactMap({ data -> AGSGraphic? in
let attributes = data["attributes"] as? [String: Any]
let geometry: AGSGeometry? = {
if let geomDict = data["geometry"] as? [String: Any] {
let geom = try? AGSGeometry.fromJSON(geomDict) as? AGSGeometry
if let geom = geom, geom.spatialReference == nil {
// Bit of a hack to force an SR onto the empty geometry
return AGSGeometryEngine.projectGeometry(geom, to: outSR)
}
return geom
}
return nil
}()
if attributes == nil && geometry == nil { return nil }
return AGSGraphic(geometry: geometry, symbol: nil, attributes: attributes)
}) else
{
print("Result is not a dictionary. Hmm")
completion?(nil, QueryError.unexpectedJSONResponse)
return
}
completion?(graphics, nil)
}
#if DEBUG
if let rc = AGSRequestConfiguration.global().copy() as? AGSRequestConfiguration {
rc.debugLogRequests = true
rc.debugLogResponses = true
operation.requestConfiguration = rc
}
#endif
AGSOperationQueue.shared().addOperation(operation)
}
let layer: AGSArcGISMapImageLayer = {
let l = AGSArcGISMapImageLayer(url: URL(string: "https://demographics9.arcgis.com/arcgis/rest/services/USA_Demographics_and_Boundaries_2019/MapServer")!)
l.credential = AGSCredential(user: "<username>", password: "<password>")
return l
}()
let layerId = 49
// Only want to query if we're tapping on a visible layer.
guard layer.loadStatus == .loaded,
layer.subLayerContents.count > layerId,
let scale = mapView.currentViewpoint(with: .centerAndScale)?.targetScale,
layer.subLayerContents[layerId].isVisible(atScale: scale),
let subLayerURL = layer.url?.appendingPathComponent("\(layerId)") else { return }
doQuery(layerURL: subLayerURL, mapPoint: mapPoint,
fields: ["OBJECTID", "NAME"], returnGeometry: true) { graphics, error in
if let error = error {
print("Error during query: \(error.localizedDescription)")
return
}
guard let graphics = graphics else {
print("Something went wrong during the query")
return
}
print("Got \(graphics.count) graphics back!")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment