How to draw a path line on a map? - ios

I am building an iOS app using Rubymotion.
I am trying to draw a line (path) on a map using coordinates.
I can run it in my app but I see no lines on the map (and no errors either).
#mapview = MKMapView.alloc.initWithFrame(view.bounds)
#mapview.mapType = MKMapTypeStandard
#mapview.delegate = self
#mapview.showsUserLocation = true
#mapview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight
view.addSubview(#mapview)
Then I try to draw the line
path = [CLLocationCoordinate2D.new(41.878114,-87.629798), CLLocationCoordinate2D.new(41.865947,-87.622576)]
pointers = Pointer.new(CLLocationCoordinate2D.type, path.length)
pointers[0] = path[0]
pointers[1] = path[1]
polyLine = MKPolyline.polylineWithCoordinates(pointers, count:2)
#mapview.addOverlay(polyLine)

I'm no expert of ruby, but in order to actually see an overlay view on a map you need to set your class as the map's delegate and implement the – mapView:viewForOverlay: protocol method, where you need to return the actual MKPolyLineView object for the map to show!
In Objective C I would simply implement this method as:
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id < MKOverlay >)overlay
{
if ( [overlay isKindOfClass:[MKPolyLine class]] {
MKPolyLineView *polyView = [[MKPolyLineView alloc] initWithPolyline:overlay];
return polyView;
}
}
Hope this helps!

Related

How to draw path with MapKit in real time (iOS7+)

I'm trying to figure out how to draw a path with MapKit given an array of location (lat/long) points. I think I need to use MKPolyline and MKOverlayRenderer. I can only seem to find information on MKRoute and MKDirections, but this is not what I need.
To start with I will have one point. Every 10 seconds or so another point will be added. How can I draw a line on a map in real time given an array of points, where the array grows over time?
This is all I have so far:
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
if ([overlay isKindOfClass:[MKPolyline class]]) {
MKPolyline *route = overlay;
MKPolylineRenderer *routeRenderer = [[MKPolylineRenderer alloc] initWithPolyline:route];
routeRenderer.strokeColor = [UIColor blueColor];
return routeRenderer;
}
return nil;
}
You should be able to do this with MKPolyline and MKPolylineRenderer as you have, but also look into -[MKOverlayRenderer setNeedsDisplayInMapRect:] and the associated conversion routines to translate MKMapRect to CGRect (if necessary) and you should be able to force a screen refresh upon receipt of new data.

How to add circular region onto MKMapView

I am trying to add a circular region on my MKMapView like the picture below for my current location. I can pin the map with annotations but don't know how to get it to show a circular region like this with a radius and have it shaded.
So I figured it out...
Below is how I did it along with code.
Step 1: - Create MKCircle
MKCircle *circleOverlay = [MKCircle circleWithCenterCoordinate:zoomLocation radius:300];//radius in meters
Step 2: - Set title and add to Map Overlays
[circleOverlay setTitle:#"Circle1"];
[_mapView addOverlay:circleOverlay];
Step 3: - Implement the mapView:rendererForOverlay: method in my MapViewDelegate
-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay{
if ([overlay isKindOfClass:[MKCircle class]])
{
MKCircleRenderer* aRenderer = [[MKCircleRenderer alloc] initWithCircle:(MKCircle *)overlay];
aRenderer.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:0.2];
aRenderer.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];
aRenderer.lineWidth = 3;
return aRenderer;
}else{
return nil;
}
}
That was it! Boom! Hope it helps someone in the future! Not sure if this is the best way but it achieve my goal!
Edit: make sure to set your mapView's delegate to self or the required delegate method will not be called.

Two coloured/custom line on MKPolylineRenderer

I am drawing x amount of lines on an MKMapView. The data is being downloaded from a webservice and for each line that needs drawing I am creating a MKPolyline, adding it to an overlayArray (some overlays have more than one polyline) and finally adding that overlay to the map via:
[self.mapView addOverlays:overlayArray];`
The next function is therefore called which works wonderfully:
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
if (![overlay isKindOfClass:[MKPolygon class]]) {
MKPolyline *route = overlay;
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:route];
renderer.strokeColor = [lineColours objectForKey:route.title];
renderer.lineWidth = 3.0;
return renderer;
} else {
return nil;
}
}
As you can see, the strokeColor gets the correct UIColor from a pre-defined NSMutableDictionary. This all works as expected.
However, some of the lines overlap and using a single colour is not always desired. I was wondering if there was a way of creating a line made up of two or even 3 colours, but not a gradient along the line as seen in many fitness apps, but colours across the line. For example, another use would be to draw a motorway route made up of two white lines with a transparent strip in the middle.
This is quite important for an app I am developing so I will post any findings I find here, and I hope that other people can share their thoughts and knowledge too.

Google maps for iOS [map balloons]

How do I make map balloons when a marker is being touched or tapped in iOS?
to put it simply i want my application's map feature to be able to popup a map balloon to display certain information on the location where the marker is located.
I'm using google maps since i've heard that for now it is more accurate than the Mapkit in iOS.
the image below is my objective in this question:
If you want this custom map balloons for your markers, while using google maps sdk for ios, you can use the function
- (UIView *) mapView: (GMSMapView *) mapView markerInfoWindow: (GMSMarker *) marker
This allows you to display a custom info window for a marker instead of the default infowindow. You need to design a view as shown in your picture , assign the required values and return the view in this function. Please check this earlier post to see an example of making a custom infowindow . You can adjust how the infowindow is located with respect to the marker, by setting value for the property marker.infoWindowAnchor
To create a balloon like annotation , you need to override MKMapView's method
- (MKAnnotationView *)viewForAnnotation:(id < MKAnnotation >)annotation
Like this:
- (MKAnnotationView *)viewForAnnotation:(id < MKAnnotation >)annotation{
static NSString* annotationIdentifier = #"Identifier";
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];
if(annotationView)
return annotationView;
else
{
MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];
// here we say NO to call out, it means the default popover type view wont open when you click on an //annotation and you can override to show your custom popover
annotationView.canShowCallout = NO;
// here you need to give a ballon image
annotationView.image = [UIImage imageNamed:[NSString stringWithFormat:#"balloon.png"]];
return annotationView;
}
return nil;
}
To create the custom popover/ view that opens when you tap on an annotation , you need to override MKMapViewDelegate's method
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
Here in this method you woould need to create a Popover Controller and present it.

To draw polygon on google map with MapKit framework

I wanted to display Google map in a map view on which I want to draw a polygon/circle.
Any advice?
The way I'm reading your question is that you want to programmatically draw the polygon on the map. For this, consult the Apple docs on MapKit.
You don't need to add transparent views over the MapKit map (MKMapView). You create an overlay object, in this case an MKPolygon. (in the following example, the variable map will be the MKMapView instance owned by the view controller that you put this code in):
CLLocationCoordinate2D points[4];
points[0] = CLLocationCoordinate2DMake(41.000512, -109.050116);
points[1] = CLLocationCoordinate2DMake(41.002371, -102.052066);
points[2] = CLLocationCoordinate2DMake(36.993076, -102.041981);
points[3] = CLLocationCoordinate2DMake(36.99892, -109.045267);
MKPolygon* poly = [MKPolygon polygonWithCoordinates:points count:4];
poly.title = #"Colorado";
[map addOverlay:poly];
Then, if you want to customize the look (colors, stroke, etc.) of the overlay, you implement the MKMapViewDelegate protocol in the view controller you have that owns the MKMapView object and provide an implementation of mapView:viewForOverlay:
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
if ([overlay isKindOfClass:[MKPolygon class]])
{
MKPolygonView* aView = [[[MKPolygonView alloc] initWithPolygon:(MKPolygon*)overlay] autorelease];
aView.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:0.2];
aView.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];
aView.lineWidth = 3;
return aView;
}
return nil;
}
Of course, always remember to actually assign the map instance's delegate to your view controller (MKMapViewDelegate), either in the interface builder, or in code (e.g. viewDidLoad).
I used ideas from this persons blog post to accomplish this. It basically involves adding a transparent view over the map. The map then allows you to convert locations to points on the view. Let me know if the site does not help you and I can try and dig up an example from my code.
http://spitzkoff.com/craig/?p=65

Resources