Convert NSNumber to CLCoordinate

Discussion in 'iOS Programming' started by doanelinde, Sep 1, 2009.

  1. doanelinde macrumors member

    Joined:
    Jul 24, 2009
    #1
    I want to pull a list of coordinates from a database into an array (Before displaying them on a map). however, in the database they are of type Number, and I can't figure out how to convert them to coordinates.

    This doesn't work: Where I have an ATM object (The coordinates are for atm machines) with NSNumbers for latitude and longitude. This is in a loop with index i, in order to pull them out one by one. The atmsArray has already been loaded.

    Code:
    ATM *aATM = [self.atmsArray objectAtIndex:i];
    
    
    CLLocationCoordinate2D coord=[[CLLocationCoordinate2D alloc] initWithLatitude:(CLLocationDegrees)aATM.Latitude longitude:(CLLocationDegrees)aATM.Longitude];
    Shows up the errors:
    -CLLocationCoordinate2D is not an objectiveC class name or alias -pointer value used when a floating point value was expected
    -pointer value used when a floating point value was expected

    I've tried a few different things but can't figure it out.

    Also tried:

    Code:
    atm1.latitude=(CLLocationDegrees)aATM.Latitude;
    Where atm1 is a CLLocationCoordinate (That works when I'm not pulling from the database but hardcoding coordinates in)..
    And I get the error:
    "Pointer value used when a floating point value was expected"

    If more information is needed, please let me know.
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
  3. doanelinde thread starter macrumors member

    Joined:
    Jul 24, 2009
    #3
    Oh ok, apologies.

    I don't have a very good knowledge of structs, but how come I can say

    atm1.latitude=23.675487;

    Or whatever, but I can't let it pull that value from the database? Is there no simple way around this? Or is there some datatype I should be using?
     
  4. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    You can as long as the value you are pulling is of the correct type. The type is clearly declared in the documentation as double. So you need a value of type double. Not NSNumber.
     
  5. doanelinde thread starter macrumors member

    Joined:
    Jul 24, 2009
    #5
    Well in that case shouldn't something as simple as this work?

    Code:
    double lat=(double)aATM.Latitude;
    or

    Code:
    double lon=aATM.Longitude;
    The first throws the error:
    Pointer value used where a floating point value was expected

    The second throws the error:
    incompatible types in initialization
     
  6. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #6
    What type is aATM.latitude? You can't cast a pointer to an object to a double.

    Given the questions you are posting I think you need to take about 10 steps back and learn basic C, then basic Objective-C as these are very basic, fundamental, core-undertanding errors.
     
  7. doanelinde thread starter macrumors member

    Joined:
    Jul 24, 2009
    #7
    aATM is NSNumber.

    I have an object of ATM with latitude and longitude properties (and more), so then I have

    Code:
    	ATM *aATM = [self.atmsArray objectAtIndex:i];
    I know, my knowledge of pointers is limited, though I did learn C.

    I've spent a lot of time working this project and realise that I'm missing some of the basics, but at this stage, due to time constraints, I don't have a choice, I have to get this project finished!

    I don't see why what I'm trying to do here has become so complicated though.
     
  8. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #8
    double is a primitive C type. You cannot assign a pointer to it. It's not an object. So you cannot cast an object to it. You need to convert your NSNumber to a double. If you look at the NSNumber documentation (which is where you should have started: I get the feeling you simply are unwilling to read the documentation) you will see a very obvious method to turn a NSNumber into a double. Use it.
     
  9. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #9
    Sorry but that just sounds like you are demanding an answer. Just realize that we are not obligated to provide you one. Project time constraints are not our fault.

    It's not complicated if you understand the basics.
     
  10. doanelinde thread starter macrumors member

    Joined:
    Jul 24, 2009
    #10
    Apologies, I am of course not demanding anything. It's more of a desperate plea at this stage!

    When I was trying to learn all this, I went and learned C, and I "got" pointers, but I probably should have worked with them a lot more, I understand what a pointer is in C, though I didn't really understand why they're used or what benefits they have. I then went through the beginners iphone development book, and did tutorials online. I don't know why this language has a reputation for being easy, because I've spent a lot of time with it, and find it very challenging! Admittedly I probably didn't go about learning it the best way.

    Anyways, I assure you I am very greatful for all and any help I am getting, and I try to help others with the more basic questions on the forums in return, if I can.

    I'm not avoiding the documentation, I had actually seen the documentation for CLLocationCoordinate2D, but wasn't too aware of what a struct was so I didn't realise that at the time. Also, I didn't see it reference the double type there at all. But I'll go check out the NSNumber documentation now.

    Thanks guys. Sorry for the drawn out reply!
     
  11. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #11
    Probably not. It would have behooved you to learn Objective-C in between learning C and learning iPhone development. It really is the cornerstone.
     
  12. doanelinde thread starter macrumors member

    Joined:
    Jul 24, 2009
    #12
    I have spent a lot of time learning objective c, and doing tutorials and trying to learn by examples, maybe I've been looking in the wrong places.

    I'm finding it hard to learn certain aspects of it because at this stage I really don't know what questions to ask. But it's not like I just skipped the language, and I felt a lot of the time the best way to learn was by doing.
     
  13. doanelinde thread starter macrumors member

    Joined:
    Jul 24, 2009
    #13
    Ok, I think this works:

    Code:
    		NSNumber *numlat=[[NSNumber alloc] initWithInt:(int)aATM.Latitude];
    		NSNumber *numlon=[[NSNumber alloc] initWithInt:(int)aATM.Longitude];
    		
    		lat=[numlat doubleValue];
    		lon=[numlon doubleValue];
    		
    		atm1.latitude=lat;
    		atm1.longitude=lon;
    But now I'm having an issue loading my db (which I thought I had working - issues with datatypes), so I can't test it until I get some code in there!


    Thanks for all your efforts, I will let you know when I am able to check if it works! No errors or warnings for now anyways!
     
  14. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #14
    TIP: Don't convert your lat and long to int. You remove all of their precision and your locations will be way off! Use initWithDouble: instead.
     
  15. doanelinde thread starter macrumors member

    Joined:
    Jul 24, 2009
    #15
    Ah! That one I should have got, that was a bit obvious, thanks again!

    Edit:
    However when I convert it to a double it throws an error:
    -pointer value used where a floating point value was expected

    The line of code:
    Code:
    NSNumber *numlat=[[NSNumber alloc] initWithDouble:(double)aATM.Latitude];
    hasn't changed except for the datatype, so when it's the same value and the same pointer, I don't see why this error is appearing. Am I missing something obvious? Thanks!
     
  16. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #16
    Oh, and if aATM.Latitude is a double and atm1.latitude is also a double, just eliminate most of that code and use:
    Code:
    atm1.latitude = aATM.Latitude
     
  17. doanelinde thread starter macrumors member

    Joined:
    Jul 24, 2009
    #17
    Sorry, I should have posted a new post rather than just edit as above, but converting to a double isn't working, please see the edit in my last post!

    aATM.Latitude is an NSNumber not a double. This is where I get confused bewtween the data types again, it's now a pointer as an attribute of my ATM object, I can't just change it from NSNumber to double can I?
     
  18. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #18
    You can. Please consult post #8 again.

    EDIT: I'll give you a big hint:
    Code:
    atm1.latitude = [aATM.Latitude [I]instanceMethodName[/I]];
     
  19. doanelinde thread starter macrumors member

    Joined:
    Jul 24, 2009
    #19
    Cool, well that works perfectly, although I'm still a little curious as to why this:
    Code:
    NSNumber *numlat=[[NSNumber alloc] initWithDouble:(double)aATM.Latitude];
    threw up the error, as I don't understand the error, could you help me understand it please?


    Also, while converting the datatype like you suggested made a lot more sense, what I was asking was would it be possible to go into the code of the class definition and change the actual original definition from NSNumber to double, even though one is a pointer and one simply a datatype? That's where my main confusion lies.

    Thank you.
     
  20. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #20
    You are trying to cast an NSNumber (aATM.Latitude), which is an object, into a primitive: double. That's not allowed.

    Possibly. What class is aAtm an object of?
     
  21. doanelinde thread starter macrumors member

    Joined:
    Jul 24, 2009
    #21
    Ok, so what I should have done is this?:
    Code:
    NSNumber *numlat=[[NSNumber alloc] initWithDouble:[aATM.Latitude doubleValue]];
    I thought that's what the casting was doing as well, my bad.


    NSManagedObject, if I understand your question correctly. This is the code for the header of ATM.h

    Code:
    #import <CoreData/CoreData.h>
    
    
    @interface ATM :  NSManagedObject  
    {
    }
    //@property (nonatomic, readwrite) NSInteger atmID;
    @property (nonatomic, retain) NSNumber *atmID;
    @property (nonatomic, retain) NSString * Name;
    @property (nonatomic, retain) NSString * Add3;
    @property (nonatomic, retain) NSNumber * Longitude;
    @property (nonatomic, retain) NSString * IntExt;
    @property (nonatomic, retain) NSString * Add2;
    @property (nonatomic, retain) NSString * County;
    @property (nonatomic, retain) NSString * FX;
    @property (nonatomic, retain) NSNumber * Latitude;
    @property (nonatomic, retain) NSString * Add1;
    
    @end
    That code is taken from a tutorial and modified, then they are @dynamic rather than @synthesize in the .m file.
     
  22. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #22
    That'll work. But I need to ask: Why do you need to store numlat in a NSNumber? Isn't aATM.Latitude already one? What you are doing is pulling the double value out of an NSNumber and putting it back into another NSNumber. Seems useless.

    Actually, looks like aATM is an object of class ATM. And since it sounds like you have control over the definition of this class, why not just change Latitude / Longitude from NSNumber to double, if that's what you really want. As in:
    Code:
    @interface ATM :  NSManagedObject  
    {
        ...
        double Longitude;
        ...
        double Latitude;
        ...
    }
    ...
    @property (assign) double Longitude;
    ...
    @property (assign) double Latitude;
    ...
    
    @end
    P.S. If done, there will both other required changes in the .m since Latitude / Longitude are no longer NSNumbers.
     
  23. doanelinde thread starter macrumors member

    Joined:
    Jul 24, 2009
    #23
    Yes, that is an unnessesary line of code, but I wanted to know how it worked. I was doing it that way before I realised (you pointed out!) that I could just say

    Code:
    atm1.latitude = aATM.Latitude;
    while converting it to a double. Infact, that line (without converting it to a double) is how I started off, it just took me a very roundabout way to get to the end product of:

    Code:
    atm1.latitude = [aATM.Latitude doubleValue];
    But it helped me figure out what was happening so it's all good!

    Yep, aATM is an object of class ATM, I misunderstood the question. And yes I have complete control over the class, that's what I was asking a couple of posts ago, which I didn't really understand, about whether I could just change the type in the class definition. I understand that an NSNumber is a pointer, and that a double is a primitive C type, I just don't know what the implications of this are, and how this will change the way the code works. As in not just changing the datatype, but changing the way it behaves.

    For an example (of my confusion!) see the first property in the class, atmID, which is now an NSNumber, but was originally an NSInteger. This has gone back and forth a few times as I try to get it to work in my code, and has caused me a lot of problems.
    Currently, I'm trying to save to the database but it bails out on this line:
    Code:
     [atm setAtmID:aATM.atmID];
    With this in the console:
    unrecognized selector sent to instance 0x1261a90'

    And for some reason, my lat, long, and atmID, which are pulled from an XML file are all weird numbers:
    2009-09-02 17:55:00.941 ATM Finder[2256:20b] ATM id 19262784
    2009-09-02 17:55:00.943 ATM Finder[2256:20b] Latitude: 19264672
    2009-09-02 17:55:00.943 ATM Finder[2256:20b] Longitude: 19262704

    even though all the other values pulled from the file are fine.

    I think I would be able to solve this issue if I had a better understanding of the datatypes.
     
  24. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #24
    Here's what this error means: ATM, which I'm hoping atm is an instance of, has no method named setAtmID:. That's probably due to using @dynamic instead of @synthesize. I don't know a ton about using @dynamic and NSManagedObjects but I believe you're left on your own to define the getters and setters with this approach.
     
  25. doanelinde thread starter macrumors member

    Joined:
    Jul 24, 2009
    #25
    Thanks, I tried it with @synthesize and there is no change at all...
     

Share This Page