Select to view content in your preferred language

ArcGIS URLRequestBuildable.makeURLRequest() - Crash

326
4
08-06-2024 12:22 PM
CristhianSanchez
New Contributor

Hello, we have found this crash which occurs when we use the CustomTiledLayer class. We use it to render MBTiles in the map but we haven't found the cause, we are wondering if you have some idea what could be happening, here is an image with part of the stack trace:

Screenshot 2024-08-06 at 1.55.40 PM.png

 

0 Kudos
4 Replies
rolson_esri
Regular Contributor

It looks like we are somehow ending up with a `nil` URL when we didn't expect to. Can you provide some reproducible code please?

0 Kudos
CristhianSanchez
New Contributor

Code looks similar to this:

import ArcGIS

class ArcGISMBTilesLayer {
    var customLayer: CustomTiledLayer
    
    static let defaultSpatialReference = SpatialReference(wkid: WKID(rawValue: 3857) ?? .webMercator)!

    
    init(mbtilesFilePath: String) {
        let tileInfo = TileInfo(
            dpi: 96,
            format: .png,
            levelsOfDetail: ArcGISMBTilesLayer.defaultLevelsOfDetail(),
            origin: ArcGISMBTilesLayer.defaultOrigin(),
            spatialReference: ArcGISMBTilesLayer.defaultSpatialReference,
            tileHeight: 256,
            tileWidth: 256
        )
        
        self.customLayer = CustomTiledLayer(tileInfo: tileInfo, fullExtent: ArcGISMBTilesLayer.defaultEnvelope()){(tileKey: TileKey)  in
            let provider = SomeDataMBTilesProvider.getTiles(withPath: mbtilesFilePath)
            let tileY = Int(pow(2.0, Double(tileKey.level))) - tileKey.row - 1
            
            guard tileY >= 0 else {
                return nil
            }
            
            let image: UIImage? = ImageFromTile.tile(with: provider, x: UInt(tileKey.column), y: UInt(tileY), zoom: UInt(tileKey.level))
            
            if let image = image, let data = image.pngData() {
                return data
            }
            else {
                return nil
            }
        }
        
        self.customLayer.noDataTileBehavior = .blank
    }
    
    static func defaultEnvelope() -> Envelope {
        return Envelope.init(
            xMin: -2.003750834278E7,
            yMin: -2.003750834278E7,
            xMax: 2.003750834278E7,
            yMax: 2.003750834278E7,
            spatialReference: defaultSpatialReference
        )
    }
    
    static func defaultLevelsOfDetail() -> [LevelOfDetail] {
        return [
            LevelOfDetail.init(level: 0, resolution: 156543.0339279998, scale: 0.91657527591555E8),
            LevelOfDetail.init(level: 1, resolution: 78271.5169639999, scale: 2.95828763795777E8),
            LevelOfDetail.init(level: 2, resolution: 39135.7584820001, scale: 1.47914381897889E8),
            LevelOfDetail.init(level: 3, resolution: 19567.8792409999, scale: 7.3957190948944E7),
            LevelOfDetail.init(level: 4, resolution: 9783.93962049996, scale: 3.6978595474472E7),
            LevelOfDetail.init(level: 5, resolution: 4891.96981024998, scale: 1.8489297737236E7),
            LevelOfDetail.init(level: 6, resolution: 2445.98490512499, scale: 9244648.868618),
            LevelOfDetail.init(level: 7, resolution: 1222.99245256249, scale: 4622324.434309),
            LevelOfDetail.init(level: 8, resolution: 611.49622628138, scale: 2311162.217155),
            LevelOfDetail.init(level: 9, resolution: 305.748113140558, scale: 1155581.108577),
            LevelOfDetail.init(level: 10, resolution: 152.874056570411, scale: 577790.554289),
            LevelOfDetail.init(level: 11, resolution: 76.4370282850732, scale: 288895.277144),
            LevelOfDetail.init(level: 12, resolution: 38.2185141425366, scale: 144447.638572),
            LevelOfDetail.init(level: 13, resolution: 19.1092570712683, scale: 72223.819286),
            LevelOfDetail.init(level: 14, resolution: 9.55462853563415, scale: 36111.909643),
            LevelOfDetail.init(level: 15, resolution: 4.77731426794937, scale: 18055.954822),
            LevelOfDetail.init(level: 16, resolution: 2.38865713397468, scale: 9027.977411),
            LevelOfDetail.init(level: 17, resolution: 1.19432856685505, scale: 4513.988705),
            LevelOfDetail.init(level: 18, resolution: 0.597164283559817, scale: 2256.994353),
            LevelOfDetail.init(level: 19, resolution: 0.298582141647617, scale: 1128.497176),
            LevelOfDetail.init(level: 20, resolution: 0.149291070823808, scale: 564.248588),
            LevelOfDetail.init(level: 21, resolution: 0.074645535411904, scale: 282.124294),
            LevelOfDetail.init(level: 22, resolution: 0.037322767705952, scale: 141.062147),
            LevelOfDetail.init(level: 23, resolution: 0.018661383985268, scale: 70.531074)
        ]
    }
    
    static func defaultOrigin() -> Point {
        return Point.init(x: -2.003750834278E7, y: 2.003750834278E7, spatialReference: defaultSpatialReference)
    }
}

//Some class to add layer to map operational layers
class SomeClassToAddMapLayerToMap {
    func setupLayer(filePath: String) {
        let mbTilesLayer = ArcGISMBTilesLayer(mbtilesFilePath: filePath)
        let operationalLayer = mbTilesLayer.customLayer
        addLayers(from: [operationalLayer])
    }

    func addLayers(from layers: [Layer]) {
        viewModel?.selectedMap?.addOperationalLayers(layers)
    }
}

 

0 Kudos
rolson_esri
Regular Contributor

Unfortunately there is missing code for function calls in your code. What would be really helpful is a self-contained reproducible example. Then we can debug and fix the issue. 

0 Kudos
Nicholas-Furness
Esri Regular Contributor

Hello @CristhianSanchez. Please could you DM me with some more details? We'd like to reproduce this and see if we can work out a solution. We'll need some data and a self-contained reproducer project.

Thank you!

0 Kudos