0

I am trying to convert this code to Swift 2.2.But I am getting this error.

enter image description here

Here is the objective - C Code

- (NSDictionary *)parseLatLonFile:(NSString *)fileName
{
    NSMutableDictionary *ret = [NSMutableDictionary new];
    NSString *path = [[NSBundle mainBundle] pathForResource:fileName
                                                     ofType:@"txt"];
    NSString *content = [NSString stringWithContentsOfFile:path
                                                  encoding:NSUTF8StringEncoding
                                                     error:NULL];
    NSArray *lines = [content componentsSeparatedByString:@"\n"];
    for (NSString *line in lines) {
        NSArray *parts = [line componentsSeparatedByString:@","];
        NSString *latStr = parts[0];
        NSString *lonStr = parts[1];

    CLLocationDegrees latitude = [latStr doubleValue];
    CLLocationDegrees longitude = [lonStr doubleValue];

    // For this example, each location is weighted equally
    double weight = 1;

    CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude
                                                      longitude:longitude];
    MKMapPoint point = MKMapPointForCoordinate(location.coordinate);
    NSValue *pointValue = [NSValue value:&point
                            withObjCType:@encode(MKMapPoint)];
    ret[pointValue] = @(weight);
}

return ret;
}

Here is my converted code

func parseLatLonFile(fileName: String) -> [NSObject : AnyObject] {
    var ret = [NSObject : AnyObject]()
    var path = NSBundle.mainBundle().pathForResource(fileName, ofType: "txt")!
    var content = try! String(contentsOfFile: path, encoding:NSUTF8StringEncoding)
    var lines = content.componentsSeparatedByString("\n")
    for line: String in lines {
        var parts = line.componentsSeparatedByString(",")
        var latStr = parts[0]
        var lonStr = parts[1]
        var latitude = CDouble(latStr)!
        var longitude = CDouble(lonStr)!
        // For this example, each location is weighted equally
        var weight: Double = 1
        var location = CLLocation(latitude: latitude, longitude: longitude)
        var point = MKMapPointForCoordinate(location.coordinate)
        var pointValue = NSValue.value(point, withObjCType: !)
        ret[pointValue!] = weight
    }
    return ret
}

I am trying to use this library to display heatmap : https://github.com/dataminr/DTMHeatmap

And I am converting this to Swift because I really want to understand how this work..

Any help with that?And if there are some heatmap example in swift are possible,all helps are welcome.I am trying to get kml data and parse it too.

Thiha Aung
  • 5,036
  • 8
  • 36
  • 79
  • Possible duplicate of [Convert MKMapPoint to NSValue in Swift](http://stackoverflow.com/questions/32454230/convert-mkmappoint-to-nsvalue-in-swift) – D4ttatraya Aug 26 '16 at 09:27

2 Answers2

1

The original code seems to be converting an MKMapPoint (a struct) instance to an NSValue (a class) instance, in order to use it as a dictionary key.

The reason is that, in Objective-C, dictionary keys/values (and array elements) can only be reference-type objects (class instances), not value type objects (struct instances, int, double, etc...).

For Swift dictionaries (and arrays), there is no such constrain: You can have a dictionary with keys of type MKMapPoint, so there is no need to use NSValue.


EDIT: It turns out MKMapPoint does not conform to the protocol Hashable, so you can not use the type as the keys to your dictionary; my mistake.

You could convert your MKMapPoint instance to a string, and use that instead. For example:

var ret = Dictionary<String, Double>()

// ... 

// Convert MKMapPoint to string for use as key:
let key = String(format:"%.2f,%.2f", point.x, point.y)

ret[key] = 1.0
Nicolas Miari
  • 16,006
  • 8
  • 81
  • 189
  • Thanks for explaining,any help with converting this whole function.It's only include Latitude and Longitude separated by comma(,) and break after one line of (Lat,long). – Thiha Aung Aug 26 '16 at 09:16
  • I am converting that view controller(DTMHeatMap) to swift that I mention.But I am having unrecognized selector error which I still I can't read txt.I will let you know if the code work.Thanks. – Thiha Aung Aug 26 '16 at 11:07
  • Did you find any solution to the problem? I can't make it work even with the let key = String .... – Thomas Jul 19 '17 at 13:27
1

Try This Code.

func parseLatLonFile(_ fileName: String) -> [AnyHashable: Any] {
    var ret = [AnyHashable: Any]()
    let path: String? = Bundle.main.path(forResource: fileName, ofType: "txt")
    let content = try? String(contentsOfFile: path!, encoding: String.Encoding.utf8)
    let lines: [Any]? = content?.components(separatedBy: "\n")
    for line: String in lines as! [String] {
        let parts: [Any] = line.components(separatedBy: ",")
        let latStr: String = parts[0] as! String
        let lonStr: String = parts[1] as! String
        let latitude: CLLocationDegrees =  Double(latStr)!
        let longitude: CLLocationDegrees = Double(lonStr)!

        // For this example, each location is weighted equally
        let weight: Double = 1
        let location = CLLocation(latitude: latitude, longitude: longitude)
        var point: MKMapPoint = MKMapPointForCoordinate(location.coordinate)
        let type = NSValue(mkCoordinate: location.coordinate).objCType
        let pointValue = NSValue(&point, withObjCType: type)

        ret[pointValue] = (weight)
    }

    return ret

}
Anit Kumar
  • 8,075
  • 1
  • 24
  • 27