Plot Points from dictionary - objective-c

I'm getting latitude, longitude and many other fields from the server.
I put each row from the database in a separate dictionary within a array.
I'm trying to map out a point from the latitude and longitude, but when I try to access the latitude by key I get a compiler error No visible #interface for NSDictionary....
Server Response
[{"id":1,"user_id":0,"latitude":"42.2367","longitude":"-71.11332","status":"active","responded_at":null,"created_at":"2015-04-13T12:52:51.144Z","updated_at":"2015-04-13T12:52:51.161Z"},{"id":2,"user_id":0,"latitude":"42.23497","longitude":"-71.11238","status":"active","responded_at":null,"created_at":"2015-04-13T12:57:03.000Z","updated_at":"2015-04-13T12:57:03.002Z"},{"id":3,"user_id":0,"latitude":"42.24222","longitude":"-71.11536","status":"active","responded_at":null,"created_at":"2015-04-13T12:57:49.012Z","updated_at":"2015-04-13T12:57:49.014Z"},{"id":4,"user_id":0,"latitude":"42.24194","longitude":"-71.11556","status":"active","responded_at":null,"created_at":"2015-04-13T13:03:10.710Z","updated_at":"2015-04-13T13:03:10.713Z"},{"id":5,"user_id":0,"latitude":"42.23493","longitude":"-71.11244","status":"active","responded_at":null,"created_at":"2015-04-13T13:05:39.713Z","updated_at":"2015-04-13T13:05:39.716Z"},{"id":6,"user_id":0,"latitude":"42.23598","longitude":"-71.11467","status":"active","responded_at":null,"created_at":"2015-04-13T13:08:12.983Z","updated_at":"2015-04-13T13:08:12.986Z"},{"id":7,"user_id":0,"latitude":"42.23598","longitude":"-71.11467","status":"active","responded_at":null,"created_at":"2015-04-13T13:08:38.115Z","updated_at":"2015-04-13T13:08:38.118Z"},{"id":8,"user_id":0,"latitude":"42.23794","longitude":"-71.11471","status":"active","responded_at":null,"created_at":"2015-04-13T13:10:11.593Z","updated_at":"2015-04-13T13:11:19.467Z"}]
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// The request is complete and data has been received
// You can parse the stuff in your instance variable now
NSError *error;
NSMutableDictionary *json = [NSJSONSerialization
JSONObjectWithData:_responseData
options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves
error:&error];
for (int i = 0; i < json.count; i++) {
double latitude = [[json objectAtIndex:i] objectForKey:#"latitude"];
double longitude = [[[json objectForKey:#"longitude"]objectAtIndex:i] doubleValue];
CLLocationCoordinate2D latlng = CLLocationCoordinate2DMake(latitude, longitude);
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
[point setCoordinate:latlng];
[worldView addAnnotation:point];
}
}

The server response (like you say in the question) is an array of dictionaries.
So json should be declared as an NSArray not an NSMutableDictionary.
This is what causes the compiler error No visible #interface for NSDictionary... because NSMutableDictionary does not have a objectAtIndex: method.
In addition, the code to get the longitude is backwards (it treats json like a dictionary and then tries to access an array inside the resulting key value).
The corrected code would be:
NSArray *json = [NSJSONSerialization
JSONObjectWithData:_responseData
options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves
error:&error];
for (int i = 0; i < json.count; i++) {
NSDictionary *pointDictionary = [json objectAtIndex:i];
double latitude = [[pointDictionary objectForKey:#"latitude"] doubleValue];
double longitude = [[pointDictionary objectForKey:#"longitude"] doubleValue];
CLLocationCoordinate2D latlng = CLLocationCoordinate2DMake(latitude, longitude);
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
[point setCoordinate:latlng];
[worldView addAnnotation:point];
}

Related

Unable to convert UTF-8 text from NSDictionary in Objective-C

Im using foursquare API to get some locations around me, but when the name of that place wasn't in english, the name will be like follows:
name = "\U0645\U0633\U062c\U062f \U0627\U0644\U0633\U064a\U062f\U0629 \U0639\U0627\U0626\U0634\U0629 | Aisha Mosque";
i tried to convert the response to a UTF-8 but nothing changed.
Here is my code:
-(void)setUpLocations{
NSURL *url = [NSURL URLWithString: #"https://api.foursquare...."];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSLog(#"Response: %#",[[[json objectForKey:#"response"]objectForKey:#"groups"]valueForKey:#"items"]);
}
And the log result is:
contact = {
};
id = 51712507498ec4e8c5ae9f48;
likes = {
count = 0;
groups = (
);
};
location = {
address = Abdoun;
cc = JO;
city = Amman;
country = Jordan;
distance = 3819;
lat = "31.95406043797281";
lng = "35.88095228186612";
};
name = "\U0645\U0633\U062c\U062f \U0627\U0644\U0633\U064a\U062f\U0629 \U0639\U0627\U0626\U0634\U0629 | Aisha Mosque";
restricted = 1;
stats = {
checkinsCount = 43;
tipCount = 2;
usersCount = 23;
};
verified = 0;
},
Any Suggestions ??
EDIT:
here is how i extract the data from the dictionary:
NSDictionary *dic = [[[[json objectForKey:#"response"]objectForKey:#"groups"]valueForKey:#"items"] copy];
namesArray = [[NSArray alloc]initWithArray:[self removeWhiteSpaces:[dic valueForKey:#"name"]]];
-(NSArray *)removeWhiteSpaces:(NSDictionary *)dic{
NSString *str = [NSString stringWithFormat:#"%#",dic];
NSString *str2 = [str stringByReplacingOccurrencesOfString:#"\n" withString:#""];
NSString *secondString = [str2 stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *thirdString = [secondString stringByReplacingOccurrencesOfString:#"(" withString:#""];
NSString *forthString = [thirdString stringByReplacingOccurrencesOfString:#")" withString:#""];
NSString *fifthString = [forthString stringByReplacingOccurrencesOfString:#"\"" withString:#""];
NSArray *items = [fifthString componentsSeparatedByString:#","];
return items;
}
And in the UITableView:
cell.textLabel.text = [NSString stringWithFormat:#"Name: %# ",[namesArray objectAtIndex:indexPath.row] ];
Update
After trying #Martin R answer i got the same results:
NSDictionary *dic = [[[[json objectForKey:#"response"]objectForKey:#"groups"]valueForKey:#"items"] copy];
NSString *value =[dic valueForKey:#"name"];
NSLog(#"%#", value);
UILabel *lbl = [[UILabel alloc]initWithFrame:self.view.frame];
lbl.numberOfLines = 0;
lbl.text = [NSString stringWithFormat:#"%#",value];;
[self.view addSubview:lbl];
and here is an image of the result
There is no problem.
NSLog() calls the description method of NSDictionary and NSArray, and that prints all non-ASCII characters as \Unnnn escape sequence.
If you extract the string values from the dictionary and print that you will see
that everything is correct.
Simple example:
NSDictionary *dict = #{ #"currency": #"€" };
NSLog(#"%#", dict);
// Output: { currency = "\U20ac"; }
NSString *value = dict[#"currency"];
NSLog(#"%#", value);
// Output: €
UPDATE: The problem seems to be in your removeWhiteSpaces: method, because
NSString *str = [NSString stringWithFormat:#"%#",dic];
already uses the description method to convert the dictionary to a string,
and the following stringByReplacingOccurrencesOfString calls are a (sorry!) very bad
method to fix that.
You should access the dictionary keys with objectForKey instead, or enumerate
the dictionary with for (NSString *key in dic) { ... } and build the desired
array.
UPDATE 2: From the JSON data (posted in chat discussion) it seem that you just need
NSArray *itemsArray = json[#"response"][#"groups"][0][#"items];
NSArray *namesArray = [itemsArray valueForKey:#"name"];
Note that "groups" is an array with one element.
Try to use this one..
[NSString stringWithUTF8String:]

Can't withdraw CGPoint Values from A mutableArray of NSValue

I made an NSMUtableArray of CGpoints and I stored them by subclassing as NSValue, but I cant get the values out. here I what I did.
CGPoint graphPoint;
NSMutableArray *pointValues = [[NSMutableArray alloc] init];
for( int x =0;x<5; x++)
{
NSDictionary* xValue = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:x] forKey:#"X"];
graphPoint.x =x;
graphPoint.y = [CalculatorBrain runProgram: self.graphingPoint usingVariableValues:xValue];
[pointValues addObject:[NSValue valueWithCGPoint:graphPoint]];
}
I tried using this to get the values but I just get null back
for( int x=0; x<5; x++) {
NSValue *val = [pointValues objectAtIndex:x];
CGPoint point = [val CGpointValue];
NSLog(#"Points = %#", point);
}
You can't print a CGPoint using the %# format specifier, as it is not an object. Instead, use NSStringFromCGPoint():
NSLog(#"%#", NSStringFromCGPoint(myPoint));

Annotations on MapView: Coordinates

I have two NSStrings (address, and key) which contain the coordinates (longitude and latitude) in form of numbers (34,56789...):
NSString *key = [allKeys objectAtIndex:i];
NSObject *obj = [DictionaryMap objectForKey:key];
NSString *address = [NSString stringWithFormat:#"%#", obj];
CLLocationCoordinate2D anyLocation;
anyLocation.latitude = [address doubleValue];
anyLocation.longitude = [key doubleValue];
MKPointAnnotation *annotationPoint2 = [[MKPointAnnotation alloc] init]; annotationPoint2.coordinate = anyLocation;
annotationPoint2.title = #"Event";
annotationPoint2.subtitle = #"Microsoft's headquarters2";
[mapView addAnnotation:annotationPoint2];
...But I can't understand why it doesn't plot in the same point as the coordinates written. I think this doesn't work:
[address doubleValue]
So I tried replacing it with:
location.latitude = NSNumber/NSString
but it gives an error.
UPDATE:
IN VIEW DID LOAD:
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPressGesture:)];
[self.mapView addGestureRecognizer:longPressGesture];
[mapView.userLocation setTitle:#"I am here"];
..then...
-(void)handleLongPressGesture:(UIGestureRecognizer*)sender {
// This is important if you only want to receive one tap and hold event
if (sender.state == UIGestureRecognizerStateEnded)
{
[self.mapView removeGestureRecognizer:sender];
}
else
{
// Here we get the CGPoint for the touch and convert it to latitude and longitude coordinates to display on the map
CGPoint point = [sender locationInView:self.mapView];
CLLocationCoordinate2D locCoord = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
// Then all you have to do is create the annotation and add it to the map
MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init]; annotationPoint.coordinate = locCoord;
annotationPoint.title = #"Microsoft";
annotationPoint.subtitle = #"Microsoft's headquarters";
[mapView addAnnotation:annotationPoint];
NSString *latitude = [[NSString alloc] initWithFormat:#"%f",locCoord.latitude];
NSString *longitude = [[NSString alloc] initWithFormat:#"%f", locCoord.longitude];
NSLog(latitude);
NSLog(longitude);
[[NSUserDefaults standardUserDefaults]setObject:latitude forKey:#"FolderLatitude"];
[[NSUserDefaults standardUserDefaults]setObject:longitude forKey:#"FolderLongitude"];
}
}
...I then save the coordinates in a JSON file and then read them from the file.
Print out the values that you are setting for lat/lon. It sounds like these values are not being converted to double properly. If the strings are not in "xxx.xxx" format then they will not convert to doubles properly when you call doubleValue.
Finally I understood: This is the correct way to make it work:
NSString *myString = (string initialization here)
float stringFloat = [myString floatValue];
anyLocation.longitude = stringFloat;

Adding Annotations for coordinates MKMapView

I am parsing this JSON file (correctly, it works with the UITextFields):
{"longitude":["37.786793","39.388528"],"latitude":["-122.395416","-78.887734"]}
ind creating MapViews, with the respective annotations in this way:
NSArray *allKeys2 = [DictionaryMap allKeys];
for (int h = 0; h < [allKeys2 count]; h++) {
CGRect mapFrame = CGRectMake( 400, e, 200, 110);
MKMapView *mapView2 = [[MKMapView alloc] initWithFrame:mapFrame];
[image1 addSubview:mapView2];
NSString *key2 = [allKeys2 objectAtIndex:i];
NSObject *obj2 = [DictionaryMap objectForKey:key2];
NSString *address = [NSString stringWithFormat:#"%#", obj2];
float stringFloat = [address floatValue];
float stringFloat2 = [key2 floatValue];
CLLocationCoordinate2D anyLocation;
anyLocation.longitude = stringFloat;
anyLocation.latitude = stringFloat2;
MKPointAnnotation *annotationPoint2 = [[MKPointAnnotation alloc] init]; annotationPoint2.coordinate = anyLocation;
annotationPoint2.title = #"Event";
annotationPoint2.subtitle = #"Microsoft's headquarters2";
[mapView2 addAnnotation:annotationPoint2];
[mapView2.userLocation setTitle:#"I am here"];
[mapView2.userLocation addObserver:self
forKeyPath:#"location"
options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
context:NULL];
[mapView2 setShowsUserLocation:NO];
[MapViewArray addObject:mapView2];
if (MapViewArray == nil)MapViewArray = [[NSMutableArray alloc]init];
[MapViewArray addObject: mapView2];
}}
}while(g < f);
...I want the first map view to show the first coordinate pin, and the second to show the second pair of coordinates. But now, it is plotting on all the map views the same pin, corresponding to the last coordinates, and not to the first and second... respectively. This method works for the UITextField text, so I can't find the problem.
Please help!!
EDIT:
NSString *filenameMap = [NSString stringWithFormat:#"%#%#Map", destDir, NavBar.topItem.title];
NSString *MapPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#Map", NavBar.topItem.title]];
[self.restClient loadFile:filenameMap intoPath:MapPath];
NSString *fileContentMap = [[NSString alloc] initWithContentsOfFile:MapPath];
SBJsonParser *parserMap = [[SBJsonParser alloc] init];
NSDictionary *dataMap = (NSDictionary *) [parserMap objectWithString:fileContentMap error:nil];
NSArray *MaparrayLongitude = [dataMap objectForKey:#"longitude"];
NSArray *MaparrayLatitude = [dataMap objectForKey:#"latitude"];
NSDictionary* DictionaryMap = [NSDictionary dictionaryWithObjects:MaparrayLatitude forKeys:MaparrayLongitude];
Another take:
You probably don't want to map your latitudes to longitudes in DictionaryMap. How about making an NSArray of NSDictionaries, where each dictionary has a "latitude" key and a "longitude" key?
Also, you have "[MapViewArray addObject: mapView2]" twice in your code.
And what is "g"? Maybe add some logging to your loop so you can see what's being created?

opencv ios cvseq storage

I am intending to pre-load all the images that I have stored inside application. Pre-loading of images involves:
Read images from bundle.
Extract object descriptors using cvExtractSurf from opencv framework.
Store IPLImage with corresponding object descriptors and keypoints.
I am having an issue in creating a dictionary containing CvSeq* keys and CvSeq* descs.
Please suggest how to store these values in NSMutableDictionary.
-(void) preloadImages:(NSMutableDictionary *)dictionary{
NSArray *d = [[NSBundle mainBundle] pathsForResourcesOfType:#"png" inDirectory:nil];
CvSURFParams params = cvSURFParams(500, 1);
CvMemStorage* storage = cvCreateMemStorage(0);
for( int i=0;i<[d count];i++){
NSString *searchForMe = #"myapp.app/1";
NSString *s = [[NSString alloc] initWithString:[d objectAtIndex:i]];
NSRange range = [s rangeOfString:searchForMe];
if( range.location != NSNotFound ){
NSMutableDictionary *surfDict = [[NSMutableDictionary alloc] init];
NSString *substring = [s substringFromIndex:range.location];
substring = [substring stringByReplacingOccurrencesOfString:#"myapp.app/" withString:#""];
UIImage *testImage = [UIImage imageNamed:substring];
IplImage *iplTestImage = [OpenCVUtilities CreateGRAYIplImageFromUIImage:testImage];
CvSeq *keys = 0 ;
CvSeq *descs = 0;
cvExtractSURF( iplTestImage, 0, &keys, &descs, storage, params );
[surfDict setObject:(id)testImage forKey:#"uiImage"];
NSLog(#"Image name : %#", substring);
[dictionary setObject:surfDict forKey:[NSString stringWithFormat:#"%d",i]];
[dictionary setObject:(NSObject *)keys forKey:#"keys"]; // error here
[dictionary setObject:(NSObject *)descs forKey:#"descs"]; // error here
[surfDict release];
}
}
}
Create a class that has an instance variable of type cvseq, add your cvseq to the object, and add that class to the dictionary.