Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Extension to calculate tile image extents overlapped by a given geometry
extension AGSTileInfo {
func calculateTiles(for geometry: AGSGeometry) -> [AGSTileKey: AGSEnvelope]? {
return calculateTiles(for: geometry.extent)?.filter({ item in
let env = item.value
return AGSGeometryEngine.geometry(geometry, intersects: env)
})
}
// Get the tile extents for the greatest level of detail. This is good for downloading tiles for
// elevation queries, but might not be the desired tile count for a range of LODs.
// For that, call calculateTile(forExtent,lod) repeatedly.
func calculateTiles(for sourceExtent: AGSEnvelope) -> [AGSTileKey: AGSEnvelope]? {
guard let lod = self.levelsOfDetail.last,
let extent = AGSGeometryEngine.projectGeometry(
sourceExtent,
to: self.spatialReference
) as? AGSEnvelope else {
return nil
}
return calculateTiles(forExtent: extent, lod: lod)
}
fileprivate func calculateTiles(forExtent extent: AGSEnvelope, lod: AGSLevelOfDetail) -> [AGSTileKey : AGSEnvelope]? {
let tileWidth = Double(self.tileWidth) * lod.resolution
let tileHeight = Double(self.tileHeight) * lod.resolution
let minCol = Int(floor((extent.xMin - self.origin.x) / tileWidth)),
minRow = Int(floor(-(extent.yMax - self.origin.y) / tileHeight)),
maxCol = Int(ceil((extent.xMax - self.origin.x) / tileWidth))-1,
maxRow = Int(ceil(-(extent.yMin - self.origin.y) / tileHeight))-1
var result = [AGSTileKey:AGSEnvelope]()
for col in minCol...maxCol {
for row in minRow...maxRow {
let env = AGSEnvelope(
xMin: self.origin.x + (Double(col) * tileWidth),
yMin: self.origin.y - (Double(row + 1) * tileHeight),
xMax: self.origin.x + (Double(col + 1) * tileWidth),
yMax: self.origin.y - (Double(row) * tileHeight),
spatialReference: self.spatialReference
)
result[AGSTileKey(
level: lod.level,
column: col,
row: row)] = env
}
}
return result
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment