Select to view content in your preferred language

AGSDynamicLayer for api 100

2741
9
03-10-2017 07:49 AM
mh10
by
Occasional Contributor

Hi

Is there anything in api 100 that provides similar functionality to AGSDynamicLayer? We have existing code that creates a layer from images that I am trying to port.

thanks

9 Replies
MarkDostal
Esri Regular Contributor

Thank you for your question!  Support for dynamic layer capabilities on the AGSArcGISMapImageLayer is coming with our next release, due in late Q2 2017.

0 Kudos
RyanOlson1
Esri Contributor

You were subclassing AGSDynamicLayer before?   If so then the closest thing we have is allowing you to create custom tiled layers. Check out this category:

@interface AGSImageTiledLayer (CustomImageTiledLayer)

Also depending on what you were doing you might be able to use a raster layer instead now.

0 Kudos
mh10
by
Occasional Contributor

Hi

thanks for replying, is there an example of this anywhere?

I am never geting any calls to tileRequestHandler, probably messed up AGSTileInfo.

0 Kudos
MarkDostal
Esri Regular Contributor

If you are not getting calls to your tileRequestHandler, yes, double check your AGSTileInfo and make sure you have created a layer of type AGSImageTiledLayer.  There is a AGSServiceImageTiledLayer class has a different handler that is used to provide a URL for a tile.

Here is a some sample code which gets a a default AGSTileInfo and extent from one of the standard base maps, then uses that information to create a custom tiled layer.

```

override func viewDidLoad() {

    super.viewDidLoad()

    // Do any additional setup after loading the view.

    

    //This will get the default tileInfo; it passes a completion handler

    //which will create the custom layer and add it as a baseLayer to

    //a new map.

    defaultTileInfoWithCompletion { (tileInfo, fullExtent, error) in

        //make sure we have no error and our tileInfo and fullExtent are OK

        guard error == nil else { print("defaultTileInfo generated an error: \(error)"); return }

        guard let tileInfo = tileInfo else { print("tileInfo is nil"); return }

        guard let fullExtent = fullExtent else { print("fullExtent is nil"); return }

        

        //creat the customLayer

        let customLayer = AGSImageTiledLayer(tileInfo: tileInfo, fullExtent: fullExtent)

        

        //Set tileRequestHandler, which gets called when the map needs a tile

        customLayer.tileRequestHandler = { [weak customLayer] (tileKey: AGSTileKeyin

            //In this sample, we're just responding with the data for a blue pushpin; for your own tiles,

            //you would use the information in tileKey to return the correct tile data.

            let image = UIImage(named: "BluePushpin")

            customLayer?.respond(with: tileKey, data: UIImagePNGRepresentation(image!), error: nil)

        }

        

        //create a basemap, adding our customLayer as a baseLayer

        let basemap = AGSBasemap()

        basemap.baseLayers.add(customLayer)

        

        //create the map and load it.  You could also set it on a mapView, which would load it for you.

        let map = AGSMap(basemap: basemap)

        map.load(completion: { (error) in

            guard error == nil else { print("Error loading map: \(error)"); return }

            

            print("Map is loaded!")

        })

        

        self.myMap = map

    }

}

//This method gets the default tileInfo from a simple basemap

//Because loading the baseLayer is asynchronous, a completion handler

//is provided; the handler will be called when the baseLayer is loaded

//

//Clients should create a tileInfo object using one of the AGSTileInfo constructors,

//based on your specific tile information.

func defaultTileInfoWithCompletion(_ completion: @escaping (_ tileInfo: AGSTileInfo?, _ fullExtent: AGSEnvelope?, _ error: Error?) -> Void) {

    let basemap = AGSBasemap.lightGrayCanvas()

    basemap.load { (error) in

        guard error == nil else { print("basemap failed to load: \(error)"); return }

        

        if let baseLayer = basemap.baseLayers[0] as? AGSArcGISTiledLayer {

            baseLayer.load(completion: { (error) in

                if error != nil {

                    completion(nil, nil, error)

                    return

                }

                

                let tileInfo = baseLayer.mapServiceInfo?.tileInfo

                completion(tileInfo, baseLayer.fullExtent, nil)

            })

        }

    }

}

```

Let us know if you're still having problems.

mh10
by
Occasional Contributor

thanks a lot, the example helped

But I'm not sure if AGSImageTiledLayer is going to work for us, we have large hires images that I think will be to slow to resize and section.

AGSDynamicLayer worked really well for these, on Android we are using PictureFillSymbol that worked fairly well. Is PictureFillSymbol going to be added?

MarkDostal
Esri Regular Contributor

PictureFillSymbol will be added in a future release.

You can also take a look at AGSRaster and AGSRaterLayer.  The supported image types for those classes are here:  ArcGIS Runtime SDK for iOS: AGSRaster Class Reference 

Note that the Raster classes are in beta in the current release for our mobile platforms (including iOS).

To learn more about rasters, you can go here:  

http://desktop.arcgis.com/en/arcmap/latest/manage-data/raster-and-images/what-is-raster-data.htm

If your data is not local, you can look for ImageServiceRaster, which is not out yet, but coming soon.

0 Kudos
mh10
by
Occasional Contributor

I actually got this to work as a AGSImageTiledLayer, the key was cropping the giant image before scaling. It seems so obvious now but I was scaling THEN cropping... and running out of memory.

thanks your help!

0 Kudos
MarkDostal
Esri Regular Contributor

Excellent!  Let us know if you have any more questions!

0 Kudos
MuruganandhamKuppan1
Regular Contributor

MDostal-esristaff‌ thanks its worked for me

0 Kudos