I'm trying to display mapview with an array of coordinates. So, i load the latitudes and longitudes from array where those are contains. It is showing perfectly. Now, i want to display one paritcular latitude & longitude with different color pin. I've referred this answer no such different i can't see.
ViewController.m
-(void)showMap:
{
...
...
DataProvider *d = [DataProvider getInstance];
NSInteger numb = sender.view.tag;
d.colorlatitude = [[arraxy objectAtIndex:numb] objectForKey:#"lat"];
d.colorlongitude = [[arraxy objectAtIndex:numb] objectForKey:#"lng"];
[d._address removeAllObjects];
[arraxy removeObjectAtIndex:sender.view.tag];
d._address = arraxy;
MapViewController *map = [[MapViewController alloc]initWithNibName:#"MapViewController" bundle:nil];
[self.navigationController pushViewController:map animated:YES];
}
MapViewController.m
-(void)viewWillAppear:(BOOL)animated
{
DataProvider *d = [DataProvider getInstance];
[_mapView removeAnnotations:_mapView.annotations];
RegisterViewController *appDelegate = [[RegisterViewController alloc]init];
[_mapView setShowsUserLocation:YES];
[_mapView setRegion:MKCoordinateRegionMakeWithDistance([appDelegate.locationManager location].coordinate, 1000, 1000)];
[_mapView setUserTrackingMode:MKUserTrackingModeNone];
MKCoordinateRegion rregion = {{0.0,0.0},{0.0,0.0}};
rregion.center.latitude = [d.colorlatitude floatValue];
rregion.center.longitude = [d.colorlongitude floatValue];
rregion.span.latitudeDelta=0.001f;
rregion.span.longitudeDelta=0.001f;
[_mapView setRegion:rregion];
MapviewAnnotations *add = [[MapviewAnnotations alloc]init];
add.coordinate = rregion.center;
[_mapView addAnnotation:add];
if (d._address)
{
for (int i=0; i<[d._address count]; i++)
{
NSDictionary *dic=[d._address objectAtIndex:i];
MKCoordinateRegion region={{0.0,0.0},{0.0,0.0}};
region.center.latitude=[[dic objectForKey:#"lat"]floatValue];
region.center.longitude=[[dic objectForKey:#"lng"]floatValue];
region.span.latitudeDelta=0.001f;
region.span.longitudeDelta=0.001f;
[_mapView setRegion:region];
MapviewAnnotations *ann=[[MapviewAnnotations alloc]init];
ann.coordinate=region.center;
[_mapView addAnnotation:ann];
}
}
[super viewWillAppear:YES];
}
and my MKMapView's delegate method is
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if (![annotation isKindOfClass:[MapviewAnnotations class]])
{
return nil;
}
static NSString *reuseId = #"currentloc";
MKPinAnnotationView *annView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
if (annView == nil)
{
annView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId];
annView.animatesDrop = NO;
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5, 5);
}
else
{
annView.annotation = annotation;
}
DataProvider *mvAnn = [DataProvider getInstance];
if (mvAnn.colorlatitude) // here i'm checking the condition.
{
annView.pinColor = MKPinAnnotationColorGreen;
}
else
{
annView.pinColor = MKPinAnnotationColorRed;
}
return annView;
}
I'm just writting the condition if the co-ordinate is there i've to plot the green color pin to that particular coordinate only. How to achieve this?
The difference between your code and the one Hinata has referred you to is that the if statement in the other code uses a value (yesno) on the annotation it is currently drawing to decide what colour to use. You are getting a value from DataProvider but not telling it which annotation you are drawing, so the instance it gives you is just what ever the instance method feels like returning at the time the map is asking for the pin. You need to tell it what you're drawing for it to decide what to put into colorlatitude
I've done this through some flags like below inside of my - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
MapviewAnnotations *mvAnn = (MapviewAnnotations *)annotation;
if (mvAnn.flag == 1)
{
annView.pinColor = MKPinAnnotationColorGreen;
}
else if (mvAnn.flag == 10)
{
annView.pinColor = MKPinAnnotationColorPurple;
}
else
{
annView.pinColor = MKPinAnnotationColorRed;
}
In my viewWillAppear i received the coordinates from DataProvider and assigned with separate MapviewAnnotations with flags and differentiate it with three type of pins simply.
Cheers!
Related
I have a an array of latitude and longitude and using for loop am displaying the MKPointAnnotation on the map. I want to show a view as a popup with data when the specific MKPointAnnotation is tapped.
Here is my code -
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 10000, 10000);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
[_locationManager stopUpdatingLocation];
NSArray *set = [[NSArray alloc] init];
for (int i = 0; i < _json.count; i++) {
_name = [_json[i] valueForKey:#"name"];
_class = [_json[i] valueForKey:#"class"];
set = [_json[i] valueForKey:#"set"];
if (setFreeHour.count != 0) {
for (int j=0;j<set.count;j++) {
NSDictionary *dict = [[NSDictionary alloc] init];
dict = set[j];
_lat = dict[#"latitude"];
_longi = dict[#"longitude"];
CLLocationCoordinate2D coordinate;
coordinate.latitude = [_lat doubleValue];
coordinate.longitude = [_longi doubleValue];
// Add an annotation
MKPointAnnotation *point1 = [[MKPointAnnotation alloc] init];
point1.coordinate = CLLocationCoordinate2DMake(coordinate.latitude, coordinate.longitude);
point1.title = _name;
point1.subtitle = _class;
[self.mapView addAnnotation:point1];
}
}
}
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
// Handle any custom annotations.
if ([annotation isKindOfClass:[MKPointAnnotation class]]) {
// Try to dequeue an existing pin view first.
MKAnnotationView *pinView = (MKAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"CustomPinAnnotationView"];
if (!pinView) {
// If an existing pin view was not available, create one.
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"CustomPinAnnotationView"];
pinView.canShowCallout = YES;
pinView.image = [UIImage imageNamed:#"annotation"];
pinView.calloutOffset = CGPointMake(0, 0);
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showDetails)];
[pinView addGestureRecognizer:tap];
} else {
pinView.annotation = annotation;
}
return pinView;
}
return nil;
}
- (void)showDetails{
self.popup.hidden = NO;
}
//PS: popup is a view that contains labels. I want to pass data from MKPointAnnotation to the view
Why don't you use mapView(_:didSelect:) method instead of UITapGestureRecognizer?
(void)mapView:(MKMapView *)mapview didSelectAnnotationView:(MKAnnotationView *)view {
// 1. get data from view(MKAnnotationView)
// 2. pass data to another view
}
https://developer.apple.com/documentation/mapkit/mkmapviewdelegate/1452393-mapview
As user is moving i wanted to plot another mkannotation on his old position which is different than current annotation in objective-c
for which I have written code
-(void)plotDotted:(double)latitude :(double)longitude
{
_busOldAnnotation.coordinate = CLLocationCoordinate2DMake(latitude, longitude);
[self.sampleMap addAnnotation:_busOldAnnotation];
}
-(void)plotPoint:(double)latitude :(double)longitude
{
_busAnnotation.coordinate = CLLocationCoordinate2DMake(latitude, longitude);
[self.sampleMap addAnnotation:_busAnnotation];
}
Annotation Delegate
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
static NSString *Identifier = #"driverView";
MKAnnotationView* myAnnotation = [self.sampleMap dequeueReusableAnnotationViewWithIdentifier:Identifier];
if (myAnnotation == nil)
{
myAnnotation = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:Identifier];
//myAnnotation.enabled = YES;
}
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(_latituDouble, _longitudeDouble);
if (coordinate.latitude == _latituDouble && coordinate.longitude == _longitudeDouble)
{
myAnnotation.image = [UIImage imageNamed:#"bus_icon.png"];
}
else if (_busOldAnnotation)
{
myAnnotation.image = [UIImage imageNamed:#"blue_dot.png"];
}
return myAnnotation;
}
Called Functions
//1. Remove
[self removeAnnotation];
//3. Add new
[self plotPoint:latitudeDouble :longitudeDouble];
//2. Add Old
[self plotDotted:_latituDouble :_longitudeDouble];
//4. Assign that coordinate to global
_latituDouble = latitudeDouble;
_longitudeDouble = longitudeDouble;
[self.sampleMap reloadInputViews];
Everything is working fine that , user is moving on my map ,
Removing previous location,
but not able to add blue_dot image after that user is moving
Use this and see if it works
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(_latituDouble, _longitudeDouble);
if (coordinate.latitude == _latituDouble && coordinate.longitude == _longitudeDouble)
{
static NSString *Identifier1 = #"driverView";
MKAnnotationView* myAnnotation = [self.sampleMap dequeueReusableAnnotationViewWithIdentifier:Identifier1];
if (myAnnotation == nil)
{
myAnnotation = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:Identifier];
//myAnnotation.enabled = YES;
}
myAnnotation.image = [UIImage imageNamed:#"bus_icon.png"];
return myAnnotation;
}
else if (_busOldAnnotation)
{
static NSString *Identifier2 = #"driverView2";
MKAnnotationView* myAnnotation = [self.sampleMap dequeueReusableAnnotationViewWithIdentifier:Identifier2];
if (myAnnotation == nil)
{
myAnnotation = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:Identifier];
//myAnnotation.enabled = YES;
}
myAnnotation.image = [UIImage imageNamed:#"blue_dot.png"];
return myAnnotation;
}
return nil;
}
I am using mapview and want to add custom image to show the location in map view , how to add image i am not able to add. this code i have used.
-(void)addAllPins
{
self.mapView.delegate=self;
for(int i = 0; i < name1.count; i++)
{
[self addPinWithTitle:name1[i] AndCoordinate:arrCoordinateStr[i]];
}
}
-(void)addPinWithTitle:(NSString *)title AndCoordinate:(NSString *)strCoordinate
{
MKPointAnnotation *mapPin = [[MKPointAnnotation alloc] init];
// clear out any white space
strCoordinate = [strCoordinate stringByReplacingOccurrencesOfString:#" " withString:#""];
// convert string into actual latitude and longitude values
NSArray *components = [strCoordinate componentsSeparatedByString:#","];
double latitude = [components[0] doubleValue];
double longitude = [components[1] doubleValue];
// setup the map pin with all data and add to map view
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);
mapPin.title = title;
mapPin.coordinate = coordinate;
// UIImage *image = [UIImage imageNamed:#"hover.9.png"];
// [[self.mapView viewForAnnotation:mapPin] setImage:image];
[self.mapView addAnnotation:mapPin];
}
i want to set zoom in scale also . can some help me to solve this.
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
// NSLog(#"%#", [self deviceLocation]);
//View Area
MKCoordinateRegion region = self.mapView.region;
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.015;
region.span.longitudeDelta = 0.015;
[mapView setRegion:region animated:YES];
[self addAllPins];
}
My code is help you.You can put custom pin annotation
- (MKAnnotationView *)mapView:(MKMapView *)sender viewForAnnotation:(id < MKAnnotation >)annotation
{
static NSString *reuseId = #"StandardPin";
MKAnnotationView *aView = (MKAnnotationView *)[sender
dequeueReusableAnnotationViewWithIdentifier:reuseId];
if (aView == nil)
{
aView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId];
aView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
aView.canShowCallout = YES;
}
aView.image = [UIImage imageNamed : #"Location_OnMap"];
aView.annotation = annotation;
aView.calloutOffset = CGPointMake(0, -5);
aView.draggable = YES;
aView.enabled = YES;
return aView;
}
You need to use mapView Delegate Method
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if (annotation == mapView.userLocation)
{
MKPinAnnotationView *pinView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"MKPinAnnotationView"];
if (pinView ==nil) {
pinView = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:#"MKPinAnnotationView"];
pinView.animatesDrop = YES;
}
pinView.canShowCallout = YES;
pinView.pinColor = MKPinAnnotationColorGreen;//if you want
return pinView;
}
else
{
static NSString *viewId = #"MKAnnotationView";
MKAnnotationView *annotationView = (MKAnnotationView*)
[mapView dequeueReusableAnnotationViewWithIdentifier:viewId];
if (annotationView == nil) {
annotationView = [[MKAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:viewId];
}
annotationView.canShowCallout=YES;
annotationView.image = [UIImage imageNamed:#"yourImage"];//set your image here
return annotationView;
}
}
2.) to zoom
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(yourLocation.coordinate, 100, 100);
MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:viewRegion];
[self.mapView setRegion:adjustedRegion animated:YES];
It will help.Thank you.
i have many annotations on my map, How can i grouping Annotation Pins on the Same Coordinate?, i found this but i down't know how can i use that
I think do you mean use something like a cluster on your map for grouping the pins, isn't it?
I used sometime REVClusterMap:
https://github.com/RVLVR/REVClusterMap
Is very useful to avoid to show many points on the map. With that, you show groups of annotations (the clusters) when you are far on the map, and when you zoom in, the points are appearing.
You only have to define your map like this:
REVClusterMapView *mapView;
mapView = [[REVClusterMapView alloc] initWithFrame:viewBounds];
And when you have to add and define the annotations, it will be like this:
NSMutableArray *pins = [NSMutableArray array];
for(int i=0;i<50;i++) {
...
CLLocationCoordinate2D newCoord = {lat+latDelta, lng+lonDelta};
REVClusterPin *pin = [[REVClusterPin alloc] init];
pin.title = [NSString stringWithFormat:#"Pin %i",i+1];;
pin.subtitle = [NSString stringWithFormat:#"Pin %i subtitle",i+1];
pin.coordinate = newCoord;
[pins addObject:pin];
[pin release];
}
[mapView addAnnotations:pins];
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation {
...
REVClusterPin *pin = (REVClusterPin *)annotation;
MKAnnotationView *annView;
if( [pin nodeCount] > 0 ) { //cluster
pin.title = #"___";
annView = (REVClusterAnnotationView*)
[mapView dequeueReusableAnnotationViewWithIdentifier:#"cluster"];
if( !annView )
annView = (REVClusterAnnotationView*)
[[REVClusterAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:#"cluster"];
annView.image = [UIImage imageNamed:#"cluster.png"];
[(REVClusterAnnotationView*)annView setClusterText:
[NSString stringWithFormat:#"%i",[pin nodeCount]]];
annView.canShowCallout = NO;
}
else { //show your code for a single annotation
...
}
I hope it will be useful :)
Have your ADClusterMapView? It works really well for us.
I created a map view in my app. Now I want the user to be able to add several addresses to drop pins at those locations. I also want the user to be able to remove these pins.
Does anyone know where I can find a good tutorial, or where to start? I have no experience with mapviews...
try this......
-
(void)ShowPins
{
activity.hidden=YES;
[activity stopAnimating];
double lat;
double lng;
for (int ijk=0; ijk<arrayLocationList.count; ijk++)
{
/*Set your lat and long here*/
lat=[[[[arrayLocationList objectAtIndex:ijk]objectForKey:#"location"] objectForKey:#"lat"] doubleValue];
lng=[[[[arrayLocationList objectAtIndex:ijk]objectForKey:#"location"] objectForKey:#"lng"] doubleValue];
CLLocationCoordinate2D geos = CLLocationCoordinate2DMake(lat, lng);
MKPlacemark* marker = [[MKPlacemark alloc] initWithCoordinate:geos addressDictionary:nil];
[mapVieww addAnnotation:marker];
}
CLLocationCoordinate2D coord1 = {.latitude = lat, .longitude =lng};
MKCoordinateSpan span = {.latitudeDelta = .03,.longitudeDelta = .03};
MKCoordinateRegion region = {coord1, span};
[mapVieww setRegion:region];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
{
MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"annotation1"];
UILabel *lable=[[UILabel alloc]init];
[newAnnotation addSubview:lable];
newAnnotation.pinColor = MKPinAnnotationColorRed;
newAnnotation.animatesDrop = YES;
newAnnotation.canShowCallout = NO;
[newAnnotation setSelected:YES animated:YES];
return newAnnotation;
}
To Drop pins at several locations u have to try this code:
You need to put all those location latitude and longitude in an array and call this function everytime after incrementing the num value
-(void)Mapview
{ NSMutableArray* annotations=[[NSMutableArray alloc] init];
CLLocationCoordinate2D theCoordinate1;
theCoordinate1.latitude = [latit[num]doubleValue];
theCoordinate1.longitude = [longit[num]doubleValue];
Annotation* myAnnotation1=[[Annotation alloc] init];
myAnnotation1.coordinate=theCoordinate1;
[map_view addAnnotation:myAnnotation1];
map_view.showsUserLocation = NO;
[annotations addObject:myAnnotation1];
MKMapRect rect = MKMapRectNull;
for (id <MKAnnotation> annotation in annotations) {
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 20);
if (MKMapRectIsNull(rect)) {
rect = pointRect;
} else {
rect = MKMapRectUnion(rect, pointRect);
}
}
map_view.visibleMapRect = rect;
}
You can edit this code by adding leftcallout acessoryview or modify the contents in callout view .
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
map_view.showsUserLocation= NO;
// if it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
MKPinAnnotationView* pinView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"AnnotationIdentifier"];
if(pinView == nil)
{
pinView = pinView=[[MKPinAnnotationView alloc]
initWithAnnotation:annotation
reuseIdentifier:#"currentloc"] ;
pinView.centerOffset = CGPointMake(0,60);
pinView.animatesDrop=YES;
pinView.canShowCallout=YES;
}
return pinView;
}
To Remove the pins you can use this code
[self.map_view removeAnnotations:map_view.annotations];
(or)
[self.map_view removeAnnotations: [self.map_view.annotations filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"!(self isKindOfClass: %#)", [MKUserLocation class]]]];