2016年11月12日 星期六

iOS MapView 影像處理


import MapKit

import Foundation

extension UIImage {
    func grayScaleImage() -> UIImage {
        let imageRect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
        let colorSpace = CGColorSpaceCreateDeviceGray();
        
        let width = UInt(self.size.width)
        let height = UInt(self.size.height)
        let context = CGContext(data: nil, width: Int(width), height: Int(height), bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: .allZeros);
        context?.draw(self.cgImage!, in: imageRect)
        
        let imageRef = context!.makeImage();
        let newImage = UIImage(cgImage: imageRef!)
        return newImage
    }
}

class OSMTileOverlay: MKTileOverlay {

    let cache = NSCache<NSURL, NSData>()
    let operationQueue = OperationQueue()
    
    override func url(forTilePath path: MKTileOverlayPath) -> URL {
        return URL(string: String(format: "http://tile.openstreetmap.org/%d/%d/%d.png", path.z, path.x, path.y))!
    }
    
    override func loadTile(at path: MKTileOverlayPath, result: @escaping (Data?, Error?) -> Void)  {
        let url = self.url(forTilePath: path)
        if let cachedData = cache.object(forKey: url as NSURL) as? Data {
            result(cachedData, nil)
        } else {
            let request = URLRequest(url: url)
            URLSession.shared.dataTask(with: request, completionHandler: {
                [weak self]
                data, response, error in
                if let data = data {
                    var image = UIImage(data: data)
                    image = image?.grayScaleImage()
                    let newData = UIImagePNGRepresentation(image!)
                    self?.cache.setObject((newData as? NSData)!, forKey: url as NSURL)
                    result(newData, error)
                    return
                }
                result(data, error)
            }).resume()
        }
    }

}