Last active
August 31, 2021 15:34
-
-
Save nixta/32365d85c8cdd4bf7d69dcb5dae83400 to your computer and use it in GitHub Desktop.
Extension to calculate tile image extents overlapped by a given geometry
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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