How to create Programmatic Popups?

3343
3
Jump to solution
02-17-2016 09:02 PM
by Anonymous User
Not applicable

This is my first attempt with the Runtime SDK for iOS with Swift (after finding the Qt Runtime SDK to be too buggy) and I have some questions regarding the workflow for creating programmatic popups.  All the code samples I have seen have used AGOL web maps rather than feature services directly.  So far, I just have a basic map with a map service and 2 feature layers that I need to make pop ups for.  I have set up the AGSPopupInfo's for each feature layer and am not sure what the rest of the workflow should look like.

My best guess is to call the queryFeatures() method from each feature layer and pass in a geometry from the map touch delegate.  From here, I am stuck as I do not know how to handle the query delegate and more specifically passing the operation returned from the query to the handler since it is outside the scope where the query operation is performed.  I think I should also be using the AGSPopupsContainer as well.  Is there a better or more appropriate workflow to accomplish this?

Does anyone have any code samples for how you have done programmatic popups for feature service layers (not AGOL web maps)?  This is the code I have so far but I am struggling:

import UIKit

import ArcGIS

let kBasemapLayerName = "Basemap Tiled Layer"

var isAdmin = false

let sightingFields = ["Visual_Cue", "Tree_Stress", "Knowledge_Level", "EAB_Found_On", "Comments", "Site_Description", "Latitude", "Longitude", "Site_Address", "Inspector_Name", "Email"]

let countyFields = ["CTY_NAME", "QUARANTINED"]

// MARK: reference feature layers

let countiesURL = NSURL(string: "http://services.arcgis.com/g2UdLvZr5lOrmlXl/arcgis/rest/services/EAB_FS/FeatureServer/1")

let counties = AGSFeatureLayer(URL: countiesURL, mode: .Snapshot)

let sightingURL = NSURL(string: "http://services.arcgis.com/g2UdLvZr5lOrmlXl/arcgis/rest/services/EAB_FS/FeatureServer/0")

let sightings = AGSFeatureLayer(URL: sightingURL, mode: .OnDemand)

class FirstViewController: UIViewController, AGSMapViewLayerDelegate, AGSCalloutDelegate, AGSMapViewTouchDelegate, AGSPopupsContainerDelegate {

  

  

    @IBOutlet weak var mapView: AGSMapView!

    var popupVC:AGSPopupsContainerViewController!

  

    override func viewDidLoad() {

        super.viewDidLoad()

      

        // MARK: set up map with default basemaps and feature layers

        let streetsURL = "http://services.arcgisonline.com/arcgis/rest/services/World_Street_Map/MapServer"

        let tiledLayer = AGSTiledMapServiceLayer(URL: NSURL(string: streetsURL))

        self.mapView.addMapLayer(tiledLayer, withName: kBasemapLayerName)

      

        // mapview layer delegate

        self.mapView.layerDelegate = self

        self.mapView.touchDelegate = self

      

        // MDA EAB service

        let mneabURL = NSURL(string: "http://gis.mda.state.mn.us/arcgis/rest/services/MN_Agriculture_EAB_Detection/MapServer")

        let eabDynMS = AGSDynamicMapServiceLayer(URL: mneabURL)

        self.mapView.addMapLayer(eabDynMS, withName: "MDA EAB Service")

      

        // make counties transparent

        counties.opacity = 0.5

      

        self.mapView.addMapLayer(counties, withName: "Counties")

        self.mapView.addMapLayer(sightings, withName: "Sightings")

      

        //MARK: Feature Layer popups for sightings and counties

        // sightings

      

        let sightingPopupInfo = AGSPopupInfo(forFeatureLayer: sightings)

        sightingPopupInfo.showAttachments = true

        sightingPopupInfo.fieldInfos = sightingFields

      

        // counties

        let countyPopupInfo =  AGSPopupInfo(forFeatureLayer: counties)

        countyPopupInfo.fieldInfos = countyFields

      

    }

  

    // MARK: query features from touch delegate for mapview

    func mapView(mapView: AGSMapView!, didClickAtPoint screen: CGPoint, mapPoint mappoint: AGSPoint!, features: [NSObject : AnyObject]!) {

      

        let geometryEngine = AGSGeometryEngine.defaultGeometryEngine()

        let buffer = geometryEngine.bufferGeometry(mappoint, byDistance:(10 * mapView.resolution))

      

        // query for sightings

        var querySightings = AGSQuery()

        querySightings.geometry = buffer

        querySightings.outFields = sightingFields

        sightings.queryFeatures(querySightings)

      

        // query for counties

        var queryCounties = AGSQuery()

        queryCounties.geometry = buffer

        queryCounties.outFields = countyFields

        var countyQueryOp = counties.queryFeatureCount(queryCounties)

      

    }

  

    //  I am not sure how to do handle the query results and display popups from resulting features

    // MARK: handle query delegates (not sure how to pass operations from outside touch delegate scope)

    func featureLayer(featureLayer: AGSFeatureLayer!, op: NSOperation, didQueryFeaturesWithFeatureSet: AGSFeatureSet?) {

      

    }

   

  

    // MARK: get user's location

    func mapViewDidLoad(mapView: AGSMapView!) {

        mapView.locationDisplay.startDataSource()

        mapView.locationDisplay.autoPanMode = .Default

        mapView.locationDisplay.wanderExtentFactor = 0.75

    }

  

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

      

    }

  

    // MARK: switch basemaps

    @IBAction func basemapChanged(sender: UISegmentedControl) {

        var basemapURL: NSURL

        switch sender.selectedSegmentIndex {

        case 0: //streets

            basemapURL = NSURL(string: "http://services.arcgisonline.com/arcgis/rest/services/World_Street_Map/MapServer")!

        case 1: // aerial

            basemapURL = NSURL(string: "http://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer")!

        default: //streets

            basemapURL = NSURL(string: "http://services.arcgisonline.com/arcgis/rest/services/World_Street_Map/MapServer")!

        }

      

      

        self.mapView.removeMapLayerWithName(kBasemapLayerName)

      

        let newBasemapLayer = AGSTiledMapServiceLayer(URL: basemapURL)

        self.mapView.insertMapLayer(newBasemapLayer, withName: kBasemapLayerName, atIndex: 0)

    }

  

  

}

0 Kudos
1 Solution

Accepted Solutions
GagandeepSingh
Occasional Contributor II

The features are already provided in the mapView:didClickAtPoint:mapPoint:features: method on the touch delegate. So you don't need a query. The features parameter is a dictionary of feature layer names as keys and the features in those layers as the values.

Simply create an AGSPopupInfo object using popupInfoForFeatureLayer: initializer. And use that to create AGSPopups and eventually an AGSPopupsContainerViewController to display them all.

View solution in original post

3 Replies
GagandeepSingh
Occasional Contributor II

The features are already provided in the mapView:didClickAtPoint:mapPoint:features: method on the touch delegate. So you don't need a query. The features parameter is a dictionary of feature layer names as keys and the features in those layers as the values.

Simply create an AGSPopupInfo object using popupInfoForFeatureLayer: initializer. And use that to create AGSPopups and eventually an AGSPopupsContainerViewController to display them all.

by Anonymous User
Not applicable

Thank you very much.  I was able to figure this out due to your suggestions.

0 Kudos
ozcandurak
New Contributor III

Is it possible to create our own view to display AGSPopupInfo data instead of using AGSPopupsContainerViewController. I cannot customize it, therefore i need a custom display, Please do suggest a way how can i handle it to show in custom view. I m using your offline editing sample in swift.

Regards.
Thank you.

0 Kudos