So I have the following code block, which is supposed to iterate over an array of JSON objects and place MKPointAnnotations on a map:
for(id jsonObject in dataArray)
{
NSLog(#"%d",[dataArray count]);
NSDictionary* jsonDictionary = jsonObject;
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
NSString *lat = [jsonDictionary objectForKey:#"latitude"];
NSString *lon = [jsonDictionary objectForKey:#"longitude"];
point.coordinate.latitude = [lat doubleValue];
point.coordinate.longitude = [lon doubleValue];
[map addAnnotation:point];
}
However, the two lines:
point.coordinate.latitude = [lat doubleValue];
point.coordinate.longitude = [lon doubleValue];
are giving me an "Expression is not Assignable" error. I can't for the life of me figure it out. I've tried to make a CLLocationCoordinate2D object and assigning that, but it doesn't work either.
This should work:
CLLocationCoordinate2d coordinate = ...
MKPointAnnotation* annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = coordinate;
[mapView addAnnotation:annotation];
It works in an existing app, just checked the code and the app.
Check this answer as well: https://stackoverflow.com/a/15162092/1032151
Related
I'm using the below code to display addresses from an array (responseObject) as annotations on my mapview. It works, and the pin is dropped successfully from my location string, however it only shows a pin for the most recent address added to the array. How can I change my code so that it shows pins on the map for all addresses in my array instead of just the most recent one? Apologies if this is a newb question. Thanks!
viewcontroller.m
NSMutableDictionary *viewParams = [NSMutableDictionary new];
[viewParams setValue:#"u000" forKey:#"view_name"];
[DIOSView viewGet:viewParams success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.addressData = [responseObject mutableCopy];
NSString *location = self.addressData[0][#"address"];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:location
completionHandler:^(NSArray* placemarks, NSError* error){
if (placemarks && placemarks.count > 0) {
CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
MKCoordinateRegion region = self.mapView.region;
// region.center = placemark.region.center;
region.span.longitudeDelta /= 8.0;
region.span.latitudeDelta /= 8.0;
[self.mapView setRegion:region animated:YES];
[self.mapView addAnnotation:placemark];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = placemark.coordinate;
point.title = self.addressData[0][#"users_name"];
point.subtitle = self.addressData[0][#"userbio"];
[self.mapView addAnnotation:point];
You are accessing only one object ?
NSString *location = self.addressData[0][#"address"];
Edited
I think you should handle your data, separated with your view. i.e. implement geocoder related code in the mapView:viewForAnnotation: method in your map view delegate. Then you should be able to create the annotations one by one and use [self.mapView addAnnotations] for all of them
For your code, which I believe is inspired by this answer, you should be able to iterate through all location addresses by something like
for (NSMutableDictionary *loc in self.addressData) {
NSString *loc = location[#"address"];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
......
}
Forgive me if the syntax is wrong for Objective C.
I am inserting some annotations that are coming from a json server, but I wanted to check if the annotation is already on the map, if so, does not add it again. For they are being added on each other , have someone help me solve this problem?
my code:
// adiciona produtos ao mapa
- (void)adicionaAnnotationsNoMapa:(id)objetos{
NSMutableArray *annotationsPins = [[NSMutableArray alloc] init];
for (NSDictionary *annotationDeProdutos in objetos) {
CLLocationCoordinate2D location;
AnnotationMap *myAnn;
myAnn = [[AnnotationMap alloc] init];
location.latitude = [[annotationDeProdutos objectForKey:#"latitude"] floatValue];
location.longitude = [[annotationDeProdutos objectForKey:#"longitude"] floatValue];
myAnn.coordinate = location;
myAnn.title = [annotationDeProdutos objectForKey:#"name"];
myAnn.subtitle = [NSString stringWithFormat:#"R$ %#",[annotationDeProdutos objectForKey:#"price"]];
myAnn.categoria = [NSString stringWithFormat:#"%#", [annotationDeProdutos objectForKey:#"id_categoria"]];
myAnn.idProduto = [NSString stringWithFormat:#"%#", [annotationDeProdutos objectForKey:#"id"]];
[annotationsPins addObject:myAnn];
}
[self.mapView addAnnotations:annotationsPins];
}
You can iterate through annotations already on MkMapView and see if they are already there:
NSArray * annotations = [self.mapView.annotations copy];
for (NSDictionary *annotationDeProdutos in objetos)
{
// Check if annotation in annotations are duplicate of annotationDeProdutos.
// You can match using name.
}
Or the other way if you only want to show annotations from single server call:
[self.mapView removeAnnotations: self.mapView.annotations];
// Now add from JSON response.
You can do this for each of your annotations:
if(![self.mapView.annotations containsObject: myAnn]) {
[self.mapView addAnnotations: myAnn];
}
I solved the problem with this code :
// adiciona produtos ao mapa
- (void)adicionaAnnotationsNoMapa:(id)objetos{
NSMutableArray *annotationsPins = [[NSMutableArray alloc] init];
for (NSDictionary *annotationDeProdutos in objetos) {
CLLocationCoordinate2D location;
AnnotationMap *myAnn;
myAnn = [[AnnotationMap alloc] init];
location.latitude = [[annotationDeProdutos objectForKey:#"latitude"] floatValue];
location.longitude = [[annotationDeProdutos objectForKey:#"longitude"] floatValue];
myAnn.coordinate = location;
myAnn.title = [annotationDeProdutos objectForKey:#"name"];
myAnn.subtitle = [NSString stringWithFormat:#"R$ %#",[annotationDeProdutos objectForKey:#"price"]];
myAnn.categoria = [NSString stringWithFormat:#"%#", [annotationDeProdutos objectForKey:#"id_categoria"]];
myAnn.idProduto = [NSString stringWithFormat:#"%#", [annotationDeProdutos objectForKey:#"id"]];
if (self.mapView.annotations.count <1) {
[annotationsPins addObject:myAnn];
} else {
__block NSInteger foundIndex = NSNotFound;
[annotationsPins enumerateObjectsUsingBlock:^(AnnotationMap *annotation, NSUInteger idx, BOOL *stop) {
CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:location.latitude longitude:location.longitude];
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:annotation.coordinate.latitude longitude:annotation.coordinate.longitude];
if ([loc1 distanceFromLocation:loc2] <= 1.0f) {
foundIndex = idx;
*stop = YES;
}
}];
if (foundIndex != NSNotFound) {
[annotationsPins addObject:myAnn];
}
}
}
[self.mapView addAnnotations:annotationsPins];
}
I am using Google Maps SDK in iOS app.I am stuck at plotting multiple pins on map.This is how I am trying to plot the pins.And I used the exact same approach to show multiple pins using MapKit which worked fine.But no success with google Maps.
-(void)plotMembersOnMap
{
for (NSMutableDictionary *obj in self.jsonDictionary)
{
membersDict = [obj objectForKey:#"members"];
NSLog(#"Count member %d",[membersDict count]); // shows count
for (NSDictionary *obj in membersDict)
{
CLLocationCoordinate2D center;
NSString *latitudeString = [obj objectForKey:#"lat"];
NSString *longitudeString = [obj objectForKey:#"lng"];
double latitude = [latitudeString doubleValue];
double longitude = [longitudeString doubleValue];
center.latitude =latitude;
center.longitude = longitude;
NSString *userName = [obj objectForKey:#"pseudo"];
GMSMarker *marker = [[GMSMarker alloc] init];
marker.map = mapView_;
marker.position = CLLocationCoordinate2DMake(center.latitude, center.longitude);
customGoogleCallout.callOutTitleLabel.text = #"Member";
customGoogleCallout.callOutUserName.text = userName;
marker.icon = [UIImage imageNamed:#"marker_membre.png"];
}
}
}
just try to add lat and lon to an array then supply the marker.position.
have some loop for i and position is object at index[i].
this might help...
CLLocationCoordinate2D center = { [[obj objectForKey:#"lat"] floatValue] , [[obj objectForKey:#"lon"] floatValue] };
GMSMarker *marker = [GMSMarker markerWithPosition:center];
Try this ,
NSArray *latitudeString = [obj objectForKey:#"lat"];
NSArray *longitudeString = [obj objectForKey:#"lng"];
Instead of
NSString *latitudeString = [obj objectForKey:#"lat"];
NSString *longitudeString = [obj objectForKey:#"lng"];
Maybe because it's plotting the latest coordinate you assign to center. You should make new instance so the previous value will not replaced.
In my app, I have done JSON parsing and I got the coordinates in the form of a dictionary, I want to use the coordinates angd plot it in the map,
I have using this
SBJsonParser *jsonParser = [SBJsonParser new];
NSArray *jsonData = (NSArray *) [jsonParser objectWithString:outputData error:nil];
for(int i=0;i<[jsonData count];i++)
{
NSDictionary *dict=(NSDictionary *)[jsonData objectAtIndex:i];
Nslog(#"%#",dict);
double la=[[dict objectForKey:#"latitude"] doubleValue];
double lo=[[dict objectForKey:#"longitude"] doubleValue];
CLLocation * loca=[[CLLocation alloc]initWithLatitude:la longitude:lo];
CLLocationCoordinate2D coordi=loca.coordinate;
marker=[GMSMarker markerWithPosition:coordi];
marker.snippet = #"Hello World";
marker.animated = YES;
marker.map = mapView;
}
it is printed as
[{"driver_id":"Tn1234sunil#gmail.com","username":"sunil","latitude":"0.000000000000000",
"longitude":"0.000000000000000"},
{"driver_id":"ma12marii#yahoo.com","username":"mari","latitude":"13.040720500000000",
"longitude":"80.243139600000000"}, {"driver_id":"45sabala#gmail.com","username":"balaji","latitude":"0.000000000000000",
"longitude":"0.000000000000000"}
Then, In my log, it is getting printed as
2014-01-04 10:55:48.121 MyTaxi[608:12e03] latitude : 0.000000
2014-01-04 10:55:48.121 MyTaxi[608:12e03] longitude : 0.000000
2014-01-04 10:55:48.122 MyTaxi[608:12e03] latitude : 13.040721
2014-01-04 10:55:48.122 MyTaxi[608:12e03] longitude : 80.243140
2014-01-04 10:55:48.122 MyTaxi[608:12e03] latitude : 0.000000
2014-01-04 10:55:48.123 MyTaxi[608:12e03] longitude : 0.000000
But, this doesnt works properly
Does any body have an idea how to plot these points to the google maps
try this one this might be helpful just create a for loop to your count ,increment it ...
NSDictionary *dict=(NSDictionary *)[jsonData objectAtIndex:i];
double la=[[dict valueForKey:#"latitude"] doubleValue];
double lo=[[dict valueForKey:#"longitude"] doubleValue];
NSMutableArray * latArray=[[NSMutableArray alloc]init];
NSMutableArray * longArray=[[NSMutableArray alloc]init];
[latArray addObject:[NSNumber numberWithDouble:la]];
[longArray addObject:[NSNumber numberWithDouble:lo]];
CLLocation * loca=[[CLLocation alloc]initWithLatitude:[[latArray objectAtIndex:i]doubleValue] longitude:[[longArray objectAtIndex:i]doubleValue]];
CLLocationCoordinate2D coordi=loca.coordinate;
GMSMarker *marker= [[GMSMarker alloc] init];
marker=[GMSMarker markerWithPosition:coordi];
marker.position = CLLocationCoordinate2DMake([[latArray objectAtIndex:i]doubleValue], [[longArray objectAtIndex:i]doubleValue]);
marker.snippet = #"Hello World";
marker.animated = YES;
marker.map = mapView;
I think , You have to alloc Marker in for loop,
right now you are creating only one marker,
for(int i=0;i<[jsonData count];i++)
{
NSDictionary *dict=(NSDictionary *)[jsonData objectAtIndex:i];
double la=[dict valueForKey:#"latitude" doubleValue];
double lo=[dict valueForKey:#"longitude" doubleValue];
CLLocation * loca=[[CLLocation alloc]initWithLatitude:la longitude:lo];
CLLocationCoordinate2D coordi=loca.coordinate;
GMSMarker *marker= [[GMSMarker alloc] init];
marker=[GMSMarker markerWithPosition:coordi];
marker.snippet = #"Hello World";
marker.animated = YES;
marker.map = mapView;
.....
}
I am trying to add pins from the server and show it one the map.
Normally I can show the pin but I want to add it online. I have three parsed json data NAME, Longitude and Latitude. I have parsed it in array. I couldn't know how to view it on the map
CLLocationCoordinate2D annotationCoord;
annotationCoord.latitude = 40.0000;
annotationCoord.longitude = 29.000;
MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
annotationPoint.coordinate = annotationCoord;
annotationPoint.title = name;
[self.locationMap addAnnotation:annotationPoint];
I have tried to add annotationCoord.latitude and annotationCoord.longitude in for loop but I get this error "bad receiver type 'CLLocationDegrees' (akadouble)" I think I am making big mistake but where I couldn't know. Please need help.
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
for (int i = 0; i < jsonArray.count; i++) {
NSString *lat = [jsonArray objectAtIndex:i];
[annotationCoord.latitude addObject:lat];
}
}
My JSON return:
response = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://kalkatawi.com/mapLocation.php"]];
NSError *parseError = nil;
jsonArray = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingAllowFragments error:&parseError];
jsonArray1 = [[NSMutableArray alloc] init];
jsonArray2 = [[NSMutableArray alloc] init];
jsonArray3 = [[NSMutableArray alloc] init];
for(int i=0;i<[jsonArray count];i++)
{
name = [[jsonArray objectAtIndex:i] objectForKey:#"name"];
[jsonArray1 addObject:name];
}
for(int i=0;i<[jsonArray count];i++)
{
longitude = [[jsonArray objectAtIndex:i] objectForKey:#"longitude"];
[jsonArray2 addObject:longitude];
}
for(int i=0;i<[jsonArray count];i++)
{
latitude = [[jsonArray objectAtIndex:i] objectForKey:#"latitude"];
[jsonArray3 addObject:latitude];
}
self.locationMap.delegate = self;
Based on the updated code, jsonArray already is an array of dictionaries with each dictionary holding the properties of each annotation.
I don't understand why you want to split that up into three separate arrays (one for each property).
Why not use jsonArray as-is to create the annotations:
jsonArray = [NSJSONSerialization JSONObjectWithData:...
self.locationMap.delegate = self; //set delegate before adding annotations
for (int i=0; i < [jsonArray count]; i++)
{
NSDictionary *annotationDictionary = [jsonArray objectAtIndex:i];
name = [annotationDictionary objectForKey:#"name"];
annotationCoord.latitude
= [[annotationDictionary objectForKey:#"latitude"] doubleValue];
annotationCoord.longitude
= [[annotationDictionary objectForKey:#"longitude"] doubleValue];
MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
annotationPoint.coordinate = annotationCoord;
annotationPoint.title = name;
[self.locationMap addAnnotation:annotationPoint];
}
The updated code in the question also shows it looping through jsonArray in the didUpdateUserLocation delegate method. It's not clear why this is being done in that delegate method but if you're planning to update the annotations on the map every time the user moves, you may also need to remove all/some existing annotations before adding again to avoid duplicate annotations.
Try
- (void)addAnnotations:(NSArray *)annotations;
of MKMApView
The explanation given in top answer. I only convert this code into Swift 3.
Swift 3
jsonArray = JSONSerialization.jsonObjectWithData()
locationMap.delegate = self
for i in 0..<jsonArray.count() {
var annotationDictionary = jsonArray[i]
name = annotationDictionary["name"]
annotationCoord.latitude = annotationDictionary["latitude"]!
annotationCoord.longitude = annotationDictionary["longitude"]!
var annotationPoint = MKPointAnnotation()
annotationPoint.coordinate = annotationCoord
annotationPoint.title = name
locationMap.addAnnotation(annotationPoint)
}