I have this code below for my new iOS Google Maps app. I can create dynamic markers on the map as the user taps on the screen but the polygon shape between the markers does not gets drawn. Any ideas why is this happening?
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//Controls whether the My Location dot and accuracy circle is enabled.
CGFloat currentZoom = 14.0f;
self.mapView.myLocationEnabled = YES;
//adds type of map: kGMSTypeSatellite, kGMSTypeTerrain, kGMSTypeHybrid, kGMSTypeNormal
self.mapView.mapType = kGMSTypeHybrid;
//Shows the compass button on the map
self.mapView.settings.compassButton = YES;
//Shows the my location button on the map
self.mapView.settings.myLocationButton = YES;
//Sets the view controller to be the GMSMapView delegate
self.mapView.delegate = self;
GMSCameraPosition *manhattan = [GMSCameraPosition cameraWithLatitude:40.790278
longitude:-73.959722
zoom:14];
self.mapView.camera = manhattan;
}
//setting up zoom
-(void)ZoominOutMap:(CGFloat)level
{
self.mapView.delegate = self;
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:40.790218 longitude:-73.959722
zoom:level];
self.mapView.camera = camera;
}
-(void)zoomInMapView:(id)sender
{
CGFloat currentZoom;
currentZoom = currentZoom + 1;
[self ZoominOutMap:currentZoom];
}
-(void) zoomOutMapView:(id)sender
{
CGFloat currentZoom;
currentZoom = currentZoom - 1;
[self ZoominOutMap:currentZoom];
}
- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate
{
NSLog(#"You tapped at %f,%f", coordinate.latitude, coordinate.longitude);
GMSMarker *marker = [[GMSMarker alloc] init];
//adds animation for adding marker
marker.appearAnimation = kGMSMarkerAnimationPop;
//draw marker on tapped position
marker.position = CLLocationCoordinate2DMake(coordinate.latitude,coordinate.longitude);
marker.map = _mapView;
//set color of marker and make them draggable
marker.icon = [GMSMarker markerImageWithColor:[UIColor blueColor]];
[marker setDraggable: YES];
// Create a rectangular path
GMSMutablePath *rect = [GMSMutablePath path];
[rect addCoordinate:CLLocationCoordinate2DMake(coordinate.latitude,coordinate.longitude)];
// Create the polygon, and assign it to the map.
GMSPolygon *polygon = [GMSPolygon polygonWithPath:rect];
polygon.fillColor = [UIColor colorWithRed:0.25 green:0 blue:0 alpha:0.05];
polygon.strokeColor = [UIColor blackColor];
polygon.strokeWidth = 2;
polygon.map = _mapView;
}
In your code you are not providing rectangular path. Add proper polygon coordinates to draw GMSPolygon
// Create a rectangular path
GMSMutablePath *rect = [GMSMutablePath path];
[rect addCoordinate:CLLocationCoordinate2DMake(37.36, -122.0)];
[rect addCoordinate:CLLocationCoordinate2DMake(37.45, -122.0)];
[rect addCoordinate:CLLocationCoordinate2DMake(37.45, -122.2)];
[rect addCoordinate:CLLocationCoordinate2DMake(37.36, -122.2)];
// Create the polygon, and assign it to the map.
GMSPolygon *polygon = [GMSPolygon polygonWithPath:rect];
polygon.fillColor = [UIColor colorWithRed:0.25 green:0 blue:0 alpha:0.05];
polygon.strokeColor = [UIColor blackColor];
polygon.strokeWidth = 2;
polygon.map = mapView;
Update:
Answer How to insert array values to draw polygon based on long/lat values - Google Maps iOS?
You have to cut this line from 'didTapAtCoordinate' of code and paste it in viewDidLoad
#GMSMutablePath *rect = [GMSMutablePath path];#
Then it will work
Related
I am trying to set up a way for the user to change the zoom of the map. Here's the code I have. What's the problem? Is there no implementation for invoking the zoom functionality? or is it that I set self.mapView.camera twice, in two different functions (viewDidLoad and ZoominOutMap)?
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//Controls whether the My Location dot and accuracy circle is enabled.
CGFloat currentZoom = 14.0f;
self.mapView.myLocationEnabled = YES;
//adds type of map: kGMSTypeSatellite, kGMSTypeTerrain, kGMSTypeHybrid, kGMSTypeNormal
self.mapView.mapType = kGMSTypeHybrid;
//Shows the compass button on the map
self.mapView.settings.compassButton = YES;
//Shows the my location button on the map
self.mapView.settings.myLocationButton = YES;
//Sets the view controller to be the GMSMapView delegate
self.mapView.delegate = self;
GMSCameraPosition *manhattan = [GMSCameraPosition cameraWithLatitude:40.790278
longitude:-73.959722
zoom:14];
self.mapView.camera = manhattan;
}
//setting up zoom
-(void)ZoominOutMap:(CGFloat)level
{
self.mapView.delegate = self;
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:40.790218 longitude:-73.959722
zoom:level];
self.mapView.camera = camera;
}
-(void)zoomInMapView:(id)sender
{
CGFloat currentZoom;
currentZoom = currentZoom + 1;
[self ZoominOutMap:currentZoom];
}
-(void) zoomOutMapView:(id)sender
{
CGFloat currentZoom;
currentZoom = currentZoom - 1;
[self ZoominOutMap:currentZoom];
}
- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate
{
NSLog(#"You tapped at %f,%f", coordinate.latitude, coordinate.longitude);
GMSMarker *marker = [[GMSMarker alloc] init];
//adds animation for adding marker
marker.appearAnimation = kGMSMarkerAnimationPop;
//draw marker on tapped position
marker.position = CLLocationCoordinate2DMake(coordinate.latitude,coordinate.longitude);
marker.map = _mapView;
//set color of marker and make them draggable
marker.icon = [GMSMarker markerImageWithColor:[UIColor blueColor]];
[marker setDraggable: YES];
// Create a rectangular path
GMSMutablePath *rect = [GMSMutablePath path];
[rect addCoordinate:CLLocationCoordinate2DMake(coordinate.latitude,coordinate.longitude)];
// Create the polygon, and assign it to the map.
GMSPolygon *polygon = [GMSPolygon polygonWithPath:rect];
polygon.fillColor = [UIColor colorWithRed:0.25 green:0 blue:0 alpha:0.05];
polygon.strokeColor = [UIColor blackColor];
polygon.strokeWidth = 2;
polygon.map = _mapView;
}
You forget to add action to the buttons:
If buttons are added programatically :
[zoomOut addTarget:self
action:#selector(zoomOutMapView:)
forControlEvents:UIControlEventTouchUpInside];
[zoomOut addTarget:self
action:#selector(zoomInMapView:)
forControlEvents:UIControlEventTouchUpInside];
For Storyboard :
//zoom controls
- (IBAction)zoomOut:(id)sender {
currentZoom = currentZoom - 1;
[self zoomHandler:currentZoom];
}
- (IBAction)zoomIn:(id)sender {
currentZoom = currentZoom + 1;
[self zoomHandler:currentZoom];
}
- (void)zoomHandler:(CGFloat)level
{
self.mapView.delegate = self;
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:40.790218 longitude:-73.959722 zoom:level];
self.mapView.camera = camera;
}
- (void)loadView {
// Create a GMSCameraPosition that tells the map to display the
// coordinate -33.86,151.20 at zoom level 6.
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:37.551927
longitude:-77.456292
zoom:18];
GMSMapView *mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(37.551709, -77.456510);
GMSMarker *marker = [GMSMarker markerWithPosition:position];
marker.title = #"Hi";
marker.map = mapView;
mapView.settings.myLocationButton = YES;
mapView.myLocationEnabled = YES;
self.view = mapView;
GMSMutablePath *path = [GMSMutablePath path];
[path addCoordinate:CLLocationCoordinate2DMake(37.552243, -77.457415)];
[path addCoordinate:CLLocationCoordinate2DMake(37.551054, -77.455443)];
GMSPolyline *polyline = [GMSPolyline polylineWithPath:path];
int x = 0;
if ((x = 1)){
polyline.spans = #[[GMSStyleSpan spanWithColor:[UIColor redColor]]];
}
else polyline.spans = #[[GMSStyleSpan spanWithColor:[UIColor greenColor]]];
polyline.strokeWidth = 10.f;
polyline.map = mapView;}
I'm trying to change the color of this polyline based on a condition. I'm new to XCode so i just tried an if statement but for some reason it does not work. Any ideas would be appreciated!
You mixed your assignment and comparison operators.
= -> assign new value
== -> check if left and right hand values are equal
Unfortunately for you, it is still a valid "conditional" statement, though it means something different.
if (x = 1) -> if the assignment succeeds (i.e. the value in x is considered to be true)
if (x == 1) -> if x is equal to 1
How to stop scrolling beyond a radius. I need to restrict user to only scroll with in 20 meters of their current location.
I have tried below link:
Prevent scrolling outside map area on google map
But I am not able to find out the correct code to be put to implement current answer on this post.
You can use distanceFromLocation to calculate how far from your center coordinate point, then you can check if you scroll outside of the circle in the (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position delegate method.
Sample code:
- (void)viewDidLoad {
[super viewDidLoad];
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.86
longitude:151.20
zoom:11];
mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
mapView.myLocationEnabled = YES;
mapView.settings.myLocationButton = YES;
self.view = mapView;
// Creates a marker in the center of the map.
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(-33.86, 151.20);
marker.title = #"Sydney";
marker.snippet = #"Australia";
marker.map = mapView;
CLLocationCoordinate2D circleCenter = CLLocationCoordinate2DMake(-33.86, 151.20);
GMSCircle *circ = [GMSCircle circleWithPosition:circleCenter
radius:10000];
circ.fillColor = [UIColor colorWithRed:0.25 green:0 blue:0 alpha:0.05];
circ.strokeColor = [UIColor redColor];
circ.strokeWidth = 5;
circ.map = mapView;
mapView.delegate = self;
}
- (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position {
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(-33.86, 151.20);
int radius = 10000;
CLLocation *targetLoc = [[CLLocation alloc] initWithLatitude:position.target.latitude longitude:position.target.longitude];
CLLocation *centerLoc = [[CLLocation alloc] initWithLatitude:center.latitude longitude:center.longitude];
if ([targetLoc distanceFromLocation:centerLoc] > radius) {
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:center.latitude
longitude:center.longitude
zoom:mapView.camera.zoom];
[mapView animateToCameraPosition: camera];
}
}
I want to draw a GMSPolygon with an image in it or crop a GMSGroundOverlay's image.
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:48.774052
longitude:-110.375980
zoom:0];
mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera];
mapView_.myLocationEnabled = YES;
GMSMutablePath *shapePath = [[GMSMutablePath alloc] init];
[shapePath addLatitude:48.774052 longitude:-110.375980];
[shapePath addLatitude:40.676195 longitude:-123.911136];
[shapePath addLatitude:33.682907 longitude:-101.762699];
/*** **/
GMSCoordinateBounds *overlayBounds = [[GMSCoordinateBounds alloc] initWithPath:shapePath];
UIImage *icon = [UIImage imageNamed:#"usaimages.jpg"];
GMSGroundOverlay *overlay =
[GMSGroundOverlay groundOverlayWithBounds:overlayBounds icon:icon];
overlay.bearing = 0;
overlay.map = mapView_;
/*** **/
GMSPolygon *shape = [GMSPolygon polygonWithPath:shapePath];
shape.strokeWidth= 2;
shape.title=#"xx";
shape.fillColor= [UIColor redColor];
//shape.strokeColor= [UIColor brownColor];
shape.map=mapView_;
self.view = mapView_;
mapView_.delegate=self;
Now this is what I see:
and this is what I want to see:
I want to put the flag into GMSPolygon or get the same result by cropping GMSGroundOverlay's icon. I don't which is possible or how I can do it.
crop the image first and then use.i suggest to use Gmsgroundoverlay as u will have a lot of controll over the image.like angle for alingment,rotation etc
I am using Mapbox framework for maps and i want to fill polygons and the vertices of the polygon has given from the user touch.
Here is my code on user touch
- (void)singleTapOnMap:(RMMapView *)map at:(CGPoint)point
{
CLLocationCoordinate2D coord;
coord.latitude = [map pixelToCoordinate:point].latitude;
coord.longitude = [map pixelToCoordinate:point].longitude;
RMAnnotation *annotation = [[RMAnnotation alloc] initWithMapView:map coordinate:coord andTitle:#""];
annotation.userInfo = [[NSArray alloc]initWithObjects:[[CLLocation alloc] initWithLatitude:coord.latitude longitude:coord.longitude], nil];
[map addAnnotation:annotation];
}
Delegate method
- (RMMapLayer *)mapView:(RMMapView *)mapView layerForAnnotation:(RMAnnotation *)annotation
{
if (annotation.isUserLocationAnnotation)
return nil;
CLLocation *location = [annotation.userInfo objectAtIndex:0];
RMShape *line = [[RMShape alloc] initWithView:annotation.mapView];
line.lineWidth = 3.0;
line.position = annotation.position;
line.lineColor = [UIColor redColor];
line.fillColor = [UIColor greenColor];
[line moveToCoordinate:location.coordinate];
[line addLineToCoordinate:lastLocation.coordinate];
return line;
}
I can draw the polygon but unable to fill it.
It seems to me that, according to the way that you are currently doing it, for each tap on the map you are creating a NEW annotation, each containing one line segment from the last location to the current tap location, which will not create a polygon, but rather a series of individual annotations containing only one line segment.
You will need to create a separate array of locations of vertices. As you add more locations via tapping it adds to the location array:
// #1 create the following iVars for keeping state of drawing and polygon vertices
bool isDrawingPolygon;
NSMutableArray *savedPolygonVertices;
// #2 in viewDidLoad or your init code, be sure to set the initial states
-(void)viewDidLoad
{
isDrawingPolygon = FALSE;
savedPolygonVertices = nil;
...
... REST OF VIEW DID LOAD OR INIT METHOD
// #3 Create an IBAction button method to trigger beginning of drawing dynamic polygon (a start button)
-(void)startCreatingPolygon
{
isDrawingPolygon = TRUE;
savedPolygonVertices = [[NSMutableArray alloc] initWithCapacity:50]; // Some arbitrary number of points
}
// #4 Begin adding location vertices whenever singleTapOnMap
-(void)singleTapOnMap:(RMMapView *)map at:(CGPoint)point
{
if (isDrawingPolygon)
{
CLLocationCoordinate2D coord;
coord.latitude = [map pixelToCoordinate:point].latitude;
coord.longitude = [map pixelToCoordinate:point].longitude;
[savedPolygonVertices addObject:coord];
RMAnnotation *annotation = [[RMAnnotation alloc] initWithMapView:map coordinate:coord andTitle:#"tempPolygon"]; // Give each temporary line annotation some common identifier "tempPolygon"
annotation.userInfo = [[NSArray alloc]initWithObjects:[[CLLocation alloc] initWithLatitude:coord.latitude longitude:coord.longitude], nil];
[map addAnnotation:annotation];
}
}
// #5 When you tap the "stop" button, you would need to roll the location vertices in the array into ONE annotation object containing an RMShape polygon containing all the vertices for the polygon (and fill/line color attributes), and an identifier for that polygon.
-(void)stopCreatingPolygon // IBAction method for stop making polygon
{
isDrawingPolygon = FALSE;
RMAnnotation *annotation = [[RMAnnotation alloc] initWithMapView:self.mapView coordinate:coord andTitle:#"Polygon"];
annotation.userInfo = savedPolygonVertices;
[self.mapView addAnnotation:annotation];
savedPolygonVertices = nil;
for (RMAnnotation *ann in self.mapView.annotations)
{
if ([ann.title isEqualToString:#"tempPolygon"])
[self.mapView removeAnnotation:ann]; // Get rid of the temporary line segments
}
}
// #6 Then in layerForAnnotation, you would need to check for that identifier (annotation.title), and put the polygon wrapped in an if statement
- (RMMapLayer *)mapView:(RMMapView *)mapView layerForAnnotation:(RMAnnotation *)annotation
{
if (annotation.isUserLocationAnnotation)
return nil;
if ([annotation.title isEqualToString:#"tempPolygon"])
{
CLLocation *location = [annotation.userInfo objectAtIndex:0];
RMShape *line = [[RMShape alloc] initWithView:annotation.mapView];
line.lineWidth = 3.0;
line.position = annotation.position;
line.lineColor = [UIColor redColor];
line.fillColor = [UIColor greenColor];
[line moveToCoordinate:location.coordinate];
[line addLineToCoordinate:lastLocation.coordinate];
return line;
}
if ([annotation.title isEqualToString:#"Polygon"])
{
RMShape *shape = [[RMShape alloc] initWithView:self.mapView];
shape.lineWidth = 3.0;
shape.lineColor = [UIColor redColor];
shape.fillColor = [UIColor greenColor];
shape.fillRule= kCAFillRuleNonZero;
shape.lineJoin = kCALineJoinRound;
shape.lineCap = kCALineCapRound;
for (CLLocationCoordinate2D * location in annotation.userInfo){
// userInfo now contains all vertices between start & stop
[shape addLineToCoordinate:location];
}
return shape;
}
}
That should give you what you are looking for.
/blee/