// MARK: Radar Loop Methods
// Slow loop overlay with notification
@objc func slowRadarLoopwith(_ notification: Nsnotification) {
DispatchQueue.main.async {
if (self.timeSlider.value) >= (self.timeSlider.minimumValue) && (self.timeSlider.value) <= (self.timeSlider.maximumValue)
{
DispatchQueue.main.async {
self.timeSlider.value = (self.timeSlider.value) + 1
}
self.timeSlider((self.timeSlider))
if self.timeSlider.value == self.timeSlider.maximumValue
{
// self?.timeSlider.value = 0
//self?.isPlaying = false
self.timer?.invalidate()
//self?.btnPlay.setImage(UIImage.init(named: "play"),for: .normal)
// DispatchQueue.main.async { self.dismissHUD( isAnimated: true ) }
self.isPlayLoopStarted = true
let nc = NotificationCenter.default
nc.removeObserver(self,name: Notification.Name("TileOverlayDownloaded"),object: nil)
self.perform(#selector(self.fastRadarLoop),with: nil,afterDelay: 3.0)
//self.fastRadarLoop()
}
}
else
{
// self?.timeSlider.value = 0
self.isPlaying = false
self.isPlayLoopStarted = false
self.timer?.invalidate()
self.btnPlay.setImage(UIImage.init(named: "play"),for: .normal)
DispatchQueue.main.async { self.dismissHUD( isAnimated: true ) }
}
}
}
// fast loop overlay with timer speed 0.4 sec
@objc func fastRadarLoop() {
DispatchQueue.main.async {
self.dismissHUD( isAnimated: true )
self.timeSlider.value = 0
self.timeSlider((self.timeSlider))
}
isRegionChanged = false
var isTimerStart = false
// self.timeSlider(self.timeSlider)
var loopTimeDelay: TimeInterval = 0.4
let zoom = Int(log2(360 * (Double(mapView.frame.size.width/256) / mapView.region.span.longitudeDelta)) + 1)
if DeviceType.IS_IPHONE_6
{
switch zoom {
case 0 ... 4:
loopTimeDelay = 0.5
case 5 ... 6:
loopTimeDelay = 0.6
case 7 ... 9:
loopTimeDelay = 0.7
case 10 ... 13:
loopTimeDelay = 0.8
default:
break
}
}
else
{
switch zoom {
case 0 ... 4:
loopTimeDelay = 0.4
case 5 ... 6:
loopTimeDelay = 0.5
case 7 ... 9:
loopTimeDelay = 0.6
case 10 ... 13:
loopTimeDelay = 0.7
default:
break
}
}
loopTimer = Timer.scheduledTimer(withTimeInterval: 0.3,repeats: true,block: { (timer) in
if self.canExecuteLoop
{
self.canExecuteLoop = false
DispatchQueue.main.async {
timer.tolerance = 0.5
if (self.timeSlider.value) >= (self.timeSlider.minimumValue) && (self.timeSlider.value) <= (self.timeSlider.maximumValue)
{
if isTimerStart == false // timer moved to first value
{
isTimerStart = true
if self.timeSlider.value == self.timeSlider.minimumValue || self.timeSlider.value == self.timeSlider.maximumValue
{
self.timeSlider.value = 0
}
}
else
{
self.timeSlider.value = (self.timeSlider.value) + 1
}
/*
var arrTilerOverlay = self.mapView.overlays.filter { (overlay) -> Bool in
if overlay is PredictNowTileOverlay
{
return true
}
return false
}
if arrTilerOverlay.count>0
{
//arrTilerOverlay.remove(at: arrTilerOverlay.count-1)
DispatchQueue.main.async {
self.mapView.removeOverlays(arrTilerOverlay)
}
}*/
/*
if let _ = self.overlay
{
if (self.mapView.overlays.count)>1,let firstOverlay = self.mapView.overlays.first as? PredictNowTileOverlay
{
DispatchQueue.main.async {
self.mapView.removeOverlay(firstOverlay)
}
}
}*/
self.timeSlider((self.timeSlider))
if DeviceType.IS_IPHONE_6
{
self.perform(#selector(self.removePreviousOverlaysFromLoop),afterDelay: 0.05)
}
else
{
self.perform(#selector(self.removePreviousOverlaysFromLoop),afterDelay: 0.15) // called after 0.15 second delay so that it will remove tile after adding next tile so that it will not show flickering
}
if self.timeSlider.value == self.timeSlider.maximumValue // if time slider is at last position move to starting
{
isTimerStart = false
}
}
}
}
})
}
// removing previous tiles
@objc func removePreviousOverlaysFromLoop(){
DispatchQueue.main.async {
var arrTilerOverlay = self.mapView.overlays.filter { (overlay) -> Bool in
if overlay is PredictNowTileOverlay
{
return true
}
return false
}
if arrTilerOverlay.count>1
{
arrTilerOverlay.remove(at: arrTilerOverlay.count-1)
DispatchQueue.main.async {
self.mapView.removeOverlays(arrTilerOverlay)
}
}
}
}
Map tile overlay sub class
init(urlTemp: String?,strDateTime: String?,strProduct: String? ) {
super.init(urlTemplate: urlTemp)
//printLog(urlTemp)
//printLog(strDateTime)
timeForLoadingOverlay = strDateTime
product = strProduct
// arrlRequestedTiles.removeAll()
// arrResponseTiles.removeAll()
urlRequestCount = 0
postCount = 0
// urlRequestCount = 0
// urlResponseCount = 0
}
override func url(forTilePath path: MKTileOverlayPath) -> URL {
// printLog("current zoom is \(path.z)")
// printLog("requested tile\tz:\(path.z)\tx:\(path.x)\ty:\(path.y)")
let tilePath = URL.init(string: self.urlTemplate! + "/\(path.z)/\(path.x)/\(path.y).png?token=" + APITokens.allisonHouseAuthToken)
// https://tiler.allisonhouse.com/tile/{MODELID}/{PRODUCTID}/{RUNDATE}/{RUNTIME}/{VALIDDATE}/{VALIDTIME}/raw/{Z}/{Y}/{X}.png?token={TOKEN}
guard let tile = tilePath else {
// printLog("noTile")
return Bundle.main.url(
forResource: "parchment",withExtension: "png",subdirectory: "Tiles1",localization: nil)!
}
// printLog(tile)
arrlRequestedTiles.append(tile)
urlRequestCount = urlRequestCount + 1
return tile
}
override func loadTile(at path: MKTileOverlayPath,result: @escaping (Data?,Error?) -> Void) {
// let path = Bundle.main.path(forResource: "11",ofType: "gif")!
// let data = try! Data(contentsof: URL(fileURLWithPath: path))
// result(data,nil)
let tileUrl = url(forTilePath: path)
var request = URLRequest.init(url: tileUrl)
let session = URLSession.shared
let parentXFolderURL = URLFortilecacheFolder().appendingPathComponent(self.cacheXFolderNameForPath(path))
let tileFilePathURL = parentXFolderURL.appendingPathComponent(fileNameForTile(path))
let tileFilePath = tileFilePathURL.path
var useCachedVersion = false
if FileManager.default.fileExists(atPath: tileFilePath) {
if let fileAttributes = try? FileManager.default.attributesOfItem(atPath: tileFilePath),let fileModificationDate = fileAttributes[FileAttributeKey.modificationDate] as? Date {
if fileModificationDate.timeIntervalSinceNow > -1.0 * maximumCacheAge {
useCachedVersion = true
}
}
}
if (useCachedVersion) {
arrResponseTiles.append(tileUrl)
// printLog("useCachedtile")
// autoreleasepool{
do
{
let cachedData = try Data(contentsof: URL(fileURLWithPath: tileFilePath))
result(cachedData,nil)
}
catch let error{
printLog(error)
result(UIImage.init(named: "parchment")?.pngData(),error)
} // }
}
else
{
request.timeoutInterval = 120
Alamofire.request(request).responseData { (response) in
if let url = response.request?.url
{
self.arrResponseTiles.append(url)
}
guard let responseData = response.result.value else{return}
// self.urlResponseCount = self.urlResponseCount + 1
if response.result.isSuccess
{
do {
try FileManager.default.createDirectory(at: parentXFolderURL,withIntermediateDirectories: true,attributes: nil)
try responseData.write(to: URL(fileURLWithPath: tileFilePath),options: [.atomic])
} catch let error {
printLog(error)
}
// printLog("downloadedtile")
// printLog(responseData.count)
result(responseData,response.result.error as NSError?)
}
else
{
// result(UIImage.init(named: "parchment")?.pngData(),response.result.error)
result(nil,response.result.error)
}
// serviceGroup.leave()
}
// serviceGroup.notify(queue: DispatchQueue.main) {
// // downloaded
//
// printLog("PostNotifiation for searvceGroup downloaded for tiles in current region")
// }
}
}
我已经实现了在mapview上添加天气雷达数据叠加层的代码,并且我试图在12个不同的时间间隔上实现这些雷达叠加层的循环,以便看起来像动画效果,这就是我的代码。我已经使用mktileoverlay子类在路径上加载了