Last active
November 22, 2019 17:07
-
-
Save nixta/9db8be083b1823f1cbbe87db5cef6325 to your computer and use it in GitHub Desktop.
Custom Query
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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