Annotations on MapView: Coordinates - objective-c

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;

Related

Get CGRect from NSStringFromCGRect

I stored a frame (CGRect) in a NSStringFromCGRect, how do I later retrieve the rect?
[mDict setObject:NSStringFromCGRect(frame) forKey:#"frame"];
I need to get the data back how?
CGRect frame = [[mDict objectForKey:#"frame"] ..?]
Does a method exist or I have to parse the string manually?
I think you are looking for,
CGRect frame = CGRectFromString([mDict objectForKey:#"frame"]);
I recommend to use NSValue instead of creating a string representation.
NSValue instances are objects and can be put into a dictionary
CGRect frame = CGRectMake(0.0, 0.0, 100.0, 100.0);
NSValue *value = [NSValue valueWithRect:(NSRect)frame];
NSDictionary *dict = #{#"frame" : value};
CGRect frameBack = (CGRect)[dict[#"frame"] rectValue];
NSLog(#"%#", NSStringFromRect(frameBack));
If you need a string representation which is easily reversible, you could use this
CGRect frame = CGRectMake(0.0, 0.0, 100., 100.0);
NSValue *value = [NSValue valueWithRect:(NSRect)frame];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:value];
NSString *base64String = [data base64EncodedStringWithOptions:0];
NSLog(#"%#", base64String);
NSData *dataBack = [[NSData alloc] initWithBase64Encoding:base64String];
NSValue *valueBack = (NSValue *)[NSKeyedUnarchiver unarchiveObjectWithData:dataBack];
CGRect frameBack = (CGRect)[valueBack rectValue];
NSLog(#"%#", NSStringFromRect(frameBack));
Until someone find a better solution this is what I came up with:
-(CGRect) CGRectFromNStringFromCGRect: (NSString *) string {
NSString *newString = [string stringByReplacingOccurrencesOfString:#"{" withString:#""];
newString = [newString stringByReplacingOccurrencesOfString:#"}" withString:#""];
newString = [newString stringByReplacingOccurrencesOfString:#" " withString:#""];
NSArray *array = [newString componentsSeparatedByString:#","];
if ([array count]==4) {
return CGRectMake([array[0] floatValue], [array[1] floatValue], [array[2] floatValue], [array[3] floatValue]);
} else {
return CGRectZero;
}
}
Use Like this:
CGRect frame = [self CGRectFromNStringFromCGRect:[mDict objectForKey:#"frame"];

Plot Points from dictionary

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];
}

Changing the width of the space character in NSTextView

I’m trying to make a reader application to help a girl with reading difficulties. Some research shows that just changing the colors of the text, background and shadow can really help kids out so I’m trying to allow her to do that. It’s just a big NSTextView with buttons so she can change the font size, color, background color, shadow properties, letter spacing, line spacing and word spacing. I know you can do most of this just using Word but I’m trying to make it as intuitive/fun as possible for her.
The place where I could use a hand is in changing the size of the spacing between words. Currently I’m just searching for a string of spaces equal to the number of spaces I expect to be there and then replacing with more or less spaces it as follows:
- (IBAction)increaseSpacing:(id)sender{
NSInteger spacing = [[NSUserDefaults standardUserDefaults] integerForKey:#"wordSpacing"];
NSMutableString * oldString = [ NSMutableString stringWithCapacity:0];
NSMutableString * newString =[ NSMutableString stringWithCapacity:0];
for (int i = 0; i < spacing; i+=1) {
[oldString appendString:#" "];
}
[newString setString:oldString];
[newString appendString:#" "];
[[[textView textStorage] mutableString] replaceOccurrencesOfString:oldString
withString:newString options:0
range:NSMakeRange(0, [[textView textStorage] length])];
spacing += 1;
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInteger: spacing] forKey:#"wordSpacing"];
}
- (IBAction)reduceSpacing:(id)sender{
NSInteger spacing = [[NSUserDefaults standardUserDefaults] integerForKey:#"wordSpacing"];
if (spacing > 1) {
NSMutableString * oldString = [ NSMutableString stringWithCapacity:0];
NSMutableString * newString =[ NSMutableString stringWithCapacity:0];
for (int i = 0; i < spacing-1; i+=1) {
[newString appendString:#" "];
}
[oldString setString:newString];
[oldString appendString:#" "];
[[[textView textStorage] mutableString] replaceOccurrencesOfString:oldString
withString:newString options:0
range:NSMakeRange(0, [[textView textStorage] length])];
spacing -= 1;
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInteger: spacing] forKey:#"wordSpacing"];
}
}
This approach feels sloppy to me, especially when moving the cursor around with arrow keys. I could just change the font size of a space character when it’s typed, but that would also change the line height. Is there a way that I can just change the width of the space character? Thanks in advance for your help.
My eventual solution was to swap out spaces for blank images (blanks) that have the adjusted width.
Basic components:
a) Method to replace spaces with blanks
b) Method to replace blanks with spaces
c) NSValueTransformer for the NSTextView to do (a) for transformedValue and (b) for reverseTransformedValue
d) NSTextViewDelegate to do (a) when the text changes
e) Subclass NSTextView to do (b) on copied or cut text before sending to pasteboard
f) Action assigned to the stepper to make the size changes
Code for each part is below:
a) AppDelegate method to replace spaces with blanks
- (NSAttributedString * ) replaceSpacesWithBlanks:(NSString *)replaceString {
CGFloat imageWidth = [[NSUserDefaults standardUserDefaults] integerForKey:#"wordSpacing"];
NSImage * pic = [[NSImage alloc] initWithSize:NSMakeSize(imageWidth, 1.0f)];
NSTextAttachmentCell *attachmentCell = [[NSTextAttachmentCell alloc] initImageCell:pic];
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
[attachment setAttachmentCell: attachmentCell ];
NSAttributedString *replacementString = [NSAttributedString attributedStringWithAttachment: attachment];
NSMutableAttributedString *mutableString = [[NSMutableAttributedString alloc] initWithString:replaceString];
NSRange range = [[mutableString string] rangeOfString:#" "];
while (range.location != NSNotFound) {
[mutableString replaceCharactersInRange:range withAttributedString:replacementString];
range = [[mutableString string] rangeOfString:#" "];
}
return [[NSAttributedString alloc] initWithAttributedString: mutableString];
}
b) AppDelegate method to replace blanks with spaces
- (NSString * ) replaceBlanksWithSpaces:(NSAttributedString *)replaceAttributedString {
NSMutableAttributedString * mutAttrString = [[NSMutableAttributedString alloc] initWithAttributedString:replaceAttributedString];
for (int index = 0; index < mutAttrString.length; index += 1) {
NSRange theRange;
NSDictionary * theAttributes = [mutAttrString attributesAtIndex:index effectiveRange:&theRange];
NSTextAttachment *theAttachment = [theAttributes objectForKey:NSAttachmentAttributeName];
if(theAttachment != NULL) {
[mutAttrString replaceCharactersInRange:theRange withString:#" "];
}
}
return mutAttrString.string;
}
c) NSValueTransformer for the NSTextView to replace spaces with blanks for transformedValue and replace blanks with spaces for reverseTransformedValue
#implementation DBAttributedStringTransformer
- (id)init
{
self = [super init];
if (self) {
appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
}
return self;
}
+ (Class)transformedValueClass
{
return [NSAttributedString class];
}
+ (BOOL)allowsReverseTransformation
{
return YES;
}
- (id)transformedValue:(id)value
{
return [appDelegate replaceSpacesWithBlanks:value];
}
- (id)reverseTransformedValue:(id)value
{
return [appDelegate replaceBlanksWithSpaces:value];
}
d) NSTextViewDelegate to replace spaces with blanks when the text changes
#implementation DBTextViewDelegate
-(void)awakeFromNib {
appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
}
- (void)textViewDidChangeSelection:(NSNotification *)aNotification{
// Need to keep track of where the cursor should be reinserted
textLength = myTextView.string.length;
insertionPoint = [[[myTextView selectedRanges] objectAtIndex:0] rangeValue].location;
}
//replaces spaces with blank image and puts cursor back in correct position
- (void)textDidChange:(NSNotification *)aNotification{
NSInteger newTextLength = myTextView.string.length;
NSInteger newInsertionPoint = insertionPoint + newTextLength - textLength;
NSString * stringValue = [[NSUserDefaults standardUserDefaults] stringForKey:#"textViewString"];
NSAttributedString * attrStringWithBlanks = [[ NSAttributedString alloc] initWithAttributedString:[appDelegate replaceSpacesWithBlanks:stringValue ]];
NSMutableAttributedString *mutableString = [[NSMutableAttributedString alloc] initWithAttributedString:attrStringWithBlanks];
[myTextView.textStorage setAttributedString: mutableString];
//Put the cursor back where it was
[myTextView setSelectedRange:NSMakeRange(newInsertionPoint, 0)];
}
e) Subclass NSTextView to replace blanks with spaces on copied or cut text before writing to pasteboard
#implementation DBTextView
-(void)awakeFromNib {
appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
}
-(void) selectedTextToClipBoard{
NSRange selectedRange = [self selectedRange];
NSAttributedString * selectedText = [[self textStorage] attributedSubstringFromRange: selectedRange];
NSString * textWithoutBlanks = [appDelegate replaceBlanksWithSpaces:selectedText];
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
[pasteboard clearContents];
NSArray *copiedObject = [NSArray arrayWithObject:textWithoutBlanks];
[pasteboard writeObjects:copiedObject];
}
-(void) copy:(id)sender{
[self selectedTextToClipBoard];
}
-(void) cut:(id)sender{
[self selectedTextToClipBoard];
// Delete selected text so it acts like a cut
NSRange selectedRange = [self selectedRange];
[[self textStorage] deleteCharactersInRange:selectedRange];
}
f) Action assigned to the stepper to make the size changes
- (IBAction)changeWordSpacing:(id)sender {
CGFloat imageWidth = [[NSUserDefaults standardUserDefaults] integerForKey:#"wordSpacing"];
NSImage * pic = [[NSImage alloc] initWithSize:NSMakeSize(imageWidth, 1.0f)];
NSTextAttachmentCell *attachmentCell = [[NSTextAttachmentCell alloc] initImageCell:pic];
NSMutableAttributedString * mutAttrString = [[NSMutableAttributedString alloc] initWithAttributedString:[textView textStorage]];
for (int index = 0; index < mutAttrString.length; index += 1) {
NSRange theRange;
NSDictionary * theAttributes = [mutAttrString attributesAtIndex:index effectiveRange:&theRange];
NSTextAttachment *theAttachment = [theAttributes objectForKey:NSAttachmentAttributeName];
if(theAttachment != NULL) {
[theAttachment setAttachmentCell: attachmentCell ];
}
}
[[textView textStorage] setAttributedString:mutAttrString];
}
Also, NSTextView should be set to “Continuously Updates Value”
It is possible to adjust the font kerning specifically for space characters. Here is a simple way to do that using the new AttributedString:
var searchRange = text.startIndex..<text.endIndex
while let range = text[searchRange].range(of: " ") {
text[range].mergeAttributes(AttributeContainer([.kern: 10]))
searchRange = range.upperBound..<text.endIndex
}
You may use text[range].kern = 10 if you are using SwiftUI's Text view, but as of Xcode 13.4 the SwiftUI.Kern attribute created in that way will not convert properly for NSAttributedStrings.

MapKit/CoreLocation iOS7 why can't I save annotation data (coordinates) to array?

Alright, I've looked high and low for an answer to this. Why can I query the mapview.annotations array for coordinate data but I cant save the same annotation data at generation into an array that is query-able in the same fashion.
This is my code:
- (void)retrieveData {
NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:#"http://PRIVATE.com/api/cprapi.php?function=request&uid=PRIVATE"]];
NSLog(#"%#",url);
NSData * data = [NSData dataWithContentsOfURL:url];
json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
workzoneArray = [[NSMutableArray alloc]init];
for (int i = 0; i < json.count; i++) {
//Create workzone objects
NSString * sT = [[json objectAtIndex:i]objectForKey:#"startTime"];
NSString * eT = [[json objectAtIndex:i]objectForKey:#"endTime"];
NSString * sLat = [[json objectAtIndex:i]objectForKey:#"startLat"];
NSString * sLon = [[json objectAtIndex:i]objectForKey:#"startLon"];
NSString * eLat = [[json objectAtIndex:i]objectForKey:#"endLat"];
NSString * eLon = [[json objectAtIndex:i]objectForKey:#"endLon"];
NSString * A = [[json objectAtIndex:i]objectForKey:#"active"];
NSString * DUID = [[json objectAtIndex:i]objectForKey:#"deviceUID"];
LTB * workzone = [[LTB alloc] initWithStartTime:sT andEndTime:eT andStartLat:sLat andStartLon:sLon andEndLat:eLat andEndLon:eLon andActive:A andDeviceUID:DUID];
[workzoneArray addObject:workzone];
NSLog(#"workzoneArray: %#", workzoneArray);
}
for (int i = 0; i < workzoneArray.count; i++) {
LTB * workzone = [workzoneArray objectAtIndex:i];
CLLocationCoordinate2D thiscoordinate;
CLLocationCoordinate2D thatcoordinate;
float sLat = [workzone.startLat floatValue];
float sLon = [workzone.startLon floatValue];
NSLog(#"Start: %# %#",workzone.startLat,workzone.startLon);
float eLat = [workzone.endLat floatValue];
float eLon = [workzone.endLon floatValue];
NSLog(#"End: %# %#",workzone.endLat,workzone.endLon);
thiscoordinate.latitude = sLat;
thiscoordinate.longitude = sLon;
thatcoordinate.latitude = eLat;
thatcoordinate.longitude = eLon;
myAnnotation *annotation1 = [[myAnnotation alloc] initWithCoordinate:thiscoordinate title:#"Limit"];
[self.mapView addAnnotation:annotation1];
[AnnotationArray addObject:annotation1];
myAnnotation * annotation2 = [[myAnnotation alloc] initWithCoordinate:thatcoordinate title:#"Limit"];
[self.mapView addAnnotation:annotation2];
[AnnotationArray addObject:annotation2];
NSLog(#"%#", AnnotationArray);
NSLog(#"%#", [AnnotationArray objectAtIndex:0]);
NSLog(#"%#", [AnnotationArray objectAtIndex:1]);
}
}
and the code that handles comparisons between my points where I am attempting to pull data from my array.
-(void) mapView:(MKMapView *)mapView
didUpdateUserLocation:(MKUserLocation *)userLocation
{
NSLog(#"checking distances...");
myAnnotation * annotation = [AnnotationArray objectAtIndex:0];
CLLocation *loc = [[CLLocation alloc] initWithLatitude:annotation.coordinate.latitude longitude:annotation.coordinate.longitude];
NSLog(#"%f - %f", annotation.coordinate.latitude, annotation.coordinate.longitude);
annotation = [AnnotationArray objectAtIndex:1];
CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:annotation.coordinate.latitude longitude:annotation.coordinate.longitude];
NSLog(#"%f - %f", annotation.coordinate.latitude, annotation.coordinate.longitude);
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:self.mapView.userLocation.coordinate.latitude longitude:self.mapView.userLocation.coordinate.longitude];
CLLocationDistance dist = [loc1 distanceFromLocation:loc2];
float distance = dist;
NSLog(#"%f", distance);
if (distance < 50) {
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Limit Alert"
message:#"50 Meters to Limit"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
}
}
If I objectAtIndex the self.mapView.annotations I get the correct lat and lon, so I'm guessing it's an invalid type conversion as it goes into the array am I right in thinking that?
Is there a better way I could do that? I only am looking at using the array as the mapView.annotations is unreliable based on network speed to which annotated view is at which index with out alot more code.
The goal is to compare loc1 and loc2 get the distance between them. compare current location's distance to loc1 add the current location's distance to loc2 and if within a margin of error check that it is less or the same. But I cant do this until I figure out a reliable way of knowing which mapView.annotation is which.
Maybe I'm blind. Thanks!
ANSWER:
Looked through my code again, decided to use my earlier array which I fed my JSON into and then extract data from there as that will allow it to be extended further down the road. Here's the code I wound up with and it seems to work ok.
NSLog(#"checking distances...");
LTB * workzone = [workzoneArray objectAtIndex:0];
CLLocationCoordinate2D startCoord;
CLLocationCoordinate2D endCoord;
double sLat = [workzone.startLat doubleValue];
double sLon = [workzone.startLon doubleValue];
startCoord.latitude = sLat;
startCoord.longitude = sLon;
double eLat = [workzone.endLat doubleValue];
double eLon = [workzone.endLon doubleValue];
endCoord.latitude =eLat;
endCoord.longitude = eLon;
CLLocation *loc = [[CLLocation alloc] initWithLatitude:startCoord.latitude longitude:startCoord.longitude];
NSLog(#"%f - %f", startCoord.latitude, startCoord.longitude);
CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:endCoord.latitude longitude:endCoord.longitude];
NSLog(#"%f - %f",endCoord.latitude, endCoord.longitude);
CLLocation *myloc = [[CLLocation alloc] initWithLatitude:self.mapView.userLocation.coordinate.latitude longitude:self.mapView.userLocation.coordinate.longitude];
CLLocationDistance area = [loc distanceFromLocation:loc1];
NSLog(#"area: %f",area);
CLLocationDistance distToA = [myloc distanceFromLocation:loc];
NSLog(#"distToA %f",distToA);
CLLocationDistance distToB = [myloc distanceFromLocation:loc1];
NSLog(#"distToB %f",distToB);
double outOfBounds = ((distToA+distToB) - area);
NSLog(#"%f", outOfBounds);
if (outOfBounds < (area + 50)) {
if (workzoneAlert == TRUE) {
workzoneAlert = false;
}
if (distToA < 10) {
if (workzoneAlertA == false) {
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Limit Alert"
message:#"10 Meters to Limit A"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
//set variable so it only shows once
self.workzoneAlertA = true;
}
else {
}
}
else if (distToB <10) {
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Limit Alert"
message:#"10 Meters to Limit B"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
}
}
else {
if (workzoneAlert == FALSE){
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Limit Alert"
message:#"Exceeded WorkZone"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
workzoneAlert = TRUE;
}
}
}

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?