切换mapLayer

根据name移除,然后再添加

self.mapView.removeMapLayer(withName: kBasemapLayerName)
        
//add new layer
let newLayer = AGSTiledMapServiceLayer.init(url: URL.init(string: baseMapUrl!))
self.mapView.insertMapLayer(newLayer, withName: kBasemapLayerName, at: 0)

上代码:

class ViewController: UIViewController {

    @IBOutlet weak var mapView: AGSMapView!
    
    let kBasemapLayerName = "kBasemapLayerName"
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //使用  ArcGIS Online map service
        //Add a basemap tiled layer
        let urlString = "http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"

        let tiledLayer = AGSTiledMapServiceLayer(url:URL.init(string: urlString))
        self.mapView.addMapLayer(tiledLayer, withName: kBasemapLayerName)
        self.mapView.layerDelegate = self
        self.mapView.touchDelegate = self
        
    }
    
    
    @IBAction func switchBaseMap(_ sender: UISegmentedControl) {
        
        var baseMapUrl:String?
        
        switch sender.selectedSegmentIndex {
        case 0:
            baseMapUrl = "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer"
        case 1:
            baseMapUrl = "http://server.arcgisonline.com/arcgis/rest/services/Ocean_Basemap/MapServer"
        case 2:
            baseMapUrl = "http://server.arcgisonline.com/arcgis/rest/services/NatGeo_World_Map/MapServer"
        case 3:
            baseMapUrl = "http://server.arcgisonline.com/arcgis/rest/services/USA_Topo_Maps/MapServer"
        default:
            baseMapUrl = "http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"
        }
        
        self.mapView.removeMapLayer(withName: kBasemapLayerName)
        
        //add new layer
        let newLayer = AGSTiledMapServiceLayer.init(url: URL.init(string: baseMapUrl!))
        self.mapView.insertMapLayer(newLayer, withName: kBasemapLayerName, at: 0)
    }
}

//处理各种点击事件
extension ViewController:AGSMapViewTouchDelegate{
}

extension ViewController:AGSMapViewLayerDelegate{
    
    func mapViewDidLoad(_ mapView: AGSMapView!) {
        print("mapViewDidLoad")
        
        mapView.locationDisplay.startDataSource()
    }
}

访问云数据

该API提供了一个要素图层(类名AGSFeatureLayer),允许您访问和编辑矢量地图数据。

该图层依赖于ArcGIS要素服务,该服务提供对数据的访问,接受并保留编辑,并允许图层使用类似SQL的查询来过滤数据。

要素服务可以托管在ArcGIS Online(Esri的云)上或您的内部部署服务器上。 在本主题中,您将在ArcGIS Online上使用功能服务。

从 feature service中添加数据

首先需要提供服务的URL,本例子中服务是公开的,无需提供任何凭据。

举例:将图层添加到地图后,自定义图层的符号系统,以便在地图上将其数据显示为蓝色点。

(ps:这个例子没跑同。featureLayer.selectFeatures(with: selectQuery, selectionMethod: .new)方法貌似有问题)

class ViewController: UIViewController {

    @IBOutlet weak var mapView: AGSMapView!
        
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.mapView.layerDelegate = self
        self.mapView.touchDelegate = self
        self.addDataFormFeatureService()        
    }
     
    func addDataFormFeatureService(){
        
        let urlString = "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer"
        let tiledLayer = AGSTiledMapServiceLayer(url:URL.init(string: urlString))
        self.mapView.addMapLayer(tiledLayer, withName: kBasemapLayerName)        
        
        //CLOUD DATA
        let featurnlayerURL = URL.init(string: "http://services.arcgis.com/oKgs2tbjK6zwTdvi/arcgis/rest/services/Major_World_Cities/FeatureServer/0")
        let layer = AGSFeatureLayer(url: featurnlayerURL!, mode: AGSFeatureLayerMode.onDemand)
        self.mapView.addMapLayer(layer, withName: "CloudData")
        
        //SYMBOLOGY
        let featureSymbol = AGSSimpleMarkerSymbol(color: UIColor.red)
        featureSymbol?.size = CGSize.init(width: 8, height: 8)
        featureSymbol?.style = .circle
        featureSymbol?.outline = nil
        layer?.renderer = AGSSimpleRenderer.init(symbol: featureSymbol!)
        
    }
    
    //按钮点击
    @IBAction func buttonClick(_ sender: Any) {
        
        print("button click")
        
        //let countries = ["None", "US", "Canada", "France", "Australia", "Brazil"]
        
        let countryName = "Canada"
        
        let featureLayer = self.mapView.mapLayer(forName: "CloudData") as! AGSFeatureLayer
        
        if featureLayer.selectionSymbol == nil {
            let selectedFeatureSymbol = AGSSimpleMarkerSymbol()
            selectedFeatureSymbol.style = .circle
            selectedFeatureSymbol.color = UIColor.green
            selectedFeatureSymbol.size = CGSize.init(width: 10, height: 10)
            featureLayer.selectionSymbol = selectedFeatureSymbol
        }
        
        if featureLayer.queryDelegate == nil {
            featureLayer.queryDelegate = self
        }
        
        featureLayer.clearSelection()
        
        let selectQuery = AGSQuery()
        //let queryString = "COUNTRY = '\(countryName)'"
        let queryString = "CNTRY_NAME = '\(countryName)'"
        selectQuery.whereClause = queryString
        featureLayer.selectFeatures(with: selectQuery, selectionMethod: .new)
        
    }
}

extension ViewController:AGSFeatureLayerQueryDelegate{
    
    func featureLayer(_ featureLayer: AGSFeatureLayer!, operation op: Operation!, didSelectFeaturesWith featureSet: AGSFeatureSet!) {
        
        //ZOOM TO SELECTED DATA
        var env:AGSMutableEnvelope!
        for selectedFeature in featureSet.features as! [AGSGraphic]{
            if env != nil {
                env.union(with: selectedFeature.geometry.envelope)
            }
            else {
                env = selectedFeature.geometry.envelope.mutableCopy() as! AGSMutableEnvelope
            }
        }
        self.mapView.zoom(to: env, withPadding: 20, animated: true)
    }
}

extension ViewController:AGSMapViewLayerDelegate{
    
    func mapViewDidLoad(_ mapView: AGSMapView!) {
        print("mapViewDidLoad")
        mapView.locationDisplay.startDataSource()
    }
}

查找地点 && 展示大头针和气泡

API提供了定位器(AGSLocator),允许开发者进行定位或反地理编码。

该定位器依赖于Esri的地理编码网络服务,该服务可以托管在Esri的云平台(ArcGIS Online)中或您的内部部署服务器上。

点击按钮 -> 搜索关键字 -> 代理回调中添加大头针等。

class ViewController: UIViewController{

    @IBOutlet weak var mapView: AGSMapView!
    
    var locator:AGSLocator?
    var graphicLayer:AGSGraphicsLayer?
    //展示结果信息
    var calloutTemplat:AGSCalloutTemplate?
    
    ...
    @IBAction func buttonClick(_ sender: Any) {
            
            print("button click")
            
            if self.graphicLayer == nil {
                
                //Add a graphics layer to the map. This layer will hold geocoding results
                //添加图层,放地理位置的搜索结果
                self.graphicLayer = AGSGraphicsLayer()
                self.mapView.addMapLayer(self.graphicLayer, withName: "Results")
                
                //Assign a simple renderer to the layer to display results as pushpins
                let pushpin = AGSPictureMarkerSymbol(imageNamed: "BluePushpin.png")!
                pushpin.offset = CGPoint.init(x: 9, y: 16)
                pushpin.leaderPoint = CGPoint.init(x: -9, y: 11)
                
                let renderer = AGSSimpleRenderer(symbol: pushpin)
                self.graphicLayer?.renderer = renderer
            
            }else{
                //清除
                self.graphicLayer?.removeAllGraphics()
            }
            
            if self.locator == nil {
                let url = URL.init(string: "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer")
                self.locator = AGSLocator.init(url: url)
                self.locator?.delegate = self
            }
            
            //设置参数
            let params = AGSLocatorFindParameters()
            params.text = "Portland"
            params.outFields = ["*"]
            params.outSpatialReference = self.mapView.spatialReference
            params.location = AGSPoint(x: 0, y: 0, spatialReference: nil)
    
            //Kick off the geocoding operation
            //This will invoke the geocode service on a background thread
            self.locator?.find(with: params)
        }
}


extension ViewController:AGSLocatorDelegate{
    
    func locator(_ locator: AGSLocator!, operation op: Operation!, didFind results: [Any]!) {
        
        print("did Find")
        
        if results.count == 0 {
        
            print("未找到结果")
        
        }else{
            
            //展示信息 气泡
            if self.calloutTemplat == nil {
                
                self.calloutTemplat = AGSCalloutTemplate()
                self.calloutTemplat!.titleTemplate = "${Match_addr}"
                self.calloutTemplat!.detailTemplate = "${DisplayY}\u{00b0} ${DisplayX}\u{00b0}"
                //Assign the callout template to the layer so that all graphics within this layer
                //display their information in the callout in the same manner
                self.graphicLayer?.calloutDelegate = self.calloutTemplat
            }
            
            
             //Add a graphic for each result
            for res in results as! [AGSLocatorFindResult]{
                self.graphicLayer?.addGraphic(res.graphic)
            }
            
            //Zoom in to the results
            let extent = self.graphicLayer!.fullEnvelope.mutableCopy() as! AGSMutableEnvelope
            extent.expand(byFactor: 1.5)
            self.mapView.zoom(to: extent, animated: true)
            
        }
    }
    
    
    func locator(_ locator: AGSLocator!, operation op: Operation!, didFindLocationsForAddress candidates: [Any]!) {
        print("didFindLocationsForAddress")
    }
    
    func locator(_ locator: AGSLocator!, operation op: Operation!, didFailToFindWithError error: Error!) {
        
        print("didFailToFindWithError")
    }   
}

2018040894065img1.png

行车路线

如何查找行车路线:

该API提供了一个路线任务(class名称AGSRouteTask),可让您找到两个或更多地点之间的驾车路线。 您可以通过指定首选项来自定义路线,例如是查找最短路线还是最快路线,还可以添加约束条件(如访问每个位置的时间窗口,代表道路封闭的障碍等)。

路线任务依赖于ArcGIS Server Network Analyst服务。 这些服务可以托管在ArcGIS Online,Esri云平台或本地服务器上。 ArcGIS Online提供了可用于订阅ArcGIS Online的全球Network Analyst服务。 您也可以使用ArcGIS for Server创建自己的服务。 在本主题中,您将在ArcGIS Online上使用覆盖北美的示例路由Web服务.

代码略。