Why my mapView does not display mi circle? - swift

I have a mapView outlet in my iOS project and I added it to my code:
var overlay = MKCircle(center: coords, radius: 100)
self.mapView.add(overlay)
and also, to be sure, i added
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
print("aaa")
let circleRenderer = MKCircleRenderer(overlay: overlay)
circleRenderer.fillColor = UIColor.blue.withAlphaComponent(0.1)
circleRenderer.strokeColor = UIColor.blue
circleRenderer.lineWidth = 1
return circleRenderer
}
But my mapView is displayed but not the circle, why ?

Related

MapKit Overlays - Circles

I'm trying to add a circle overlay to the map but it never happens - the annotations are added but thats it
Here is the code sample
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer
let circle = MKCircleRenderer(overlay: overlay)
circle.fillColor = UIColor.black.withAlphaComponent(0.1)
circle.strokeColor = UIColor.red
circle.lineWidth = 9
return circle
}
let circle = MKCircle(center: coordinates, radius: 9000)
mapView.addAnnotation(Loka_Location)
mapView.addOverlay(circle)
You might have missed setting the delegate of the mapView.
mapView.delegate = self
and don't forget to
class ViewController: UIViewController, MKMapViewDelegate {}

How to draw custom shapes on MKMapView

I need to draw custom shapes like Arc, Semi-circle? I tried the below code but it's not rendering anything on the MKMapView.
Is this the right way to draw custom shapes?
class ViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
mapView.delegate = self
let center = CLLocationCoordinate2D(latitude: 15.463157486154865, longitude: 73.78846049308775)
let radius = CLLocationCoordinate2D(latitude: 15.495608080208948, longitude: 73.83418584279791)
addCircle(center: center, radius: radius)
}
private func createArcPath() -> UIBezierPath {
let center = CLLocationCoordinate2D(latitude: 15.463157486154865, longitude: 73.78846049308775)
// converting the coordinates to CGPoint with respect to MKMapView.
let centerPoint = mapView.convert(center, toPointTo: self.mapView)
// Creating bezierPath of arc.
let path = UIBezierPath(arcCenter: centerPoint, radius: 6080.205481929489, startAngle: CGFloat.pi, endAngle: CGFloat.pi * 2, clockwise: true)
return path
}
}
extension ViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKCircle {
let arcRenderer = MKOverlayPathRenderer()
arcRenderer.path = createArcPath().cgPath
arcRenderer.strokeColor = UIColor.red
arcRenderer.fillColor = UIColor.red
arcRenderer.lineWidth = 10
arcRenderer.alpha = 1
arcRenderer.lineCap = .round
return arcRenderer
}
return MKOverlayRenderer()
}
}
extension ViewController {
private func addCircle(center ccoordinate: CLLocationCoordinate2D, radius rcoordinate: CLLocationCoordinate2D) {
let centerLocation = CLLocation.init(latitude: ccoordinate.latitude, longitude: ccoordinate.longitude)
let radiusLocation = CLLocation.init(latitude: rcoordinate.latitude, longitude: rcoordinate.longitude)
let radius = centerLocation.distance(from: radiusLocation)
let circle = MKCircle(center: ccoordinate, radius: radius)
mapView.addOverlay(circle)
}
}
Use this to add custom shape in MAPVIEW
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer
{
if overlay is MKCircle
{
print("overlay latitude: "+String(overlay.coordinate.latitude))
print("overlay longitude: "+String(overlay.coordinate.longitude))
let circleOverlay = overlay as! MKCircle
if(circleOverlay.accessibilityPath != nil)
{
let arcRenderer = MKOverlayPathRenderer()
arcRenderer.path = circleOverlay.accessibilityPath?.cgPath
arcRenderer.strokeColor = UIColor.red
arcRenderer.lineWidth = 10
arcRenderer.alpha = 0.3
return arcRenderer
}
let circle = MKCircleRenderer(overlay: overlay)
circle.strokeColor = UIColor.black
circle.fillColor = UIColor(red: 255, green: 0, blue: 0, alpha: 0.1)
circle.lineWidth = 1
circle.alpha = 0.3
return circle
}
}
After some RND I came across a library curvyRoute & used it to draw arch on MKMapView.
// Adds arch overlay to the mapView
private func addArcOverlays() {
let pointA = CLLocationCoordinate2D(latitude: 15.463157486154865, longitude: 73.78846049308775)
let pointB = CLLocationCoordinate2D(latitude: 15.495608080208948, longitude: 73.83418584279791)
mapView.addOverlay(LineOverlay(origin: pointA, destination: pointB))
let style = LineOverlayStyle(strokeColor: .red, lineWidth: 4, alpha: 1)
let arc = ArcOverlay(origin: pointA, destination: pointB, style: style)
arc.radiusMultiplier = 0.5
mapView.addOverlay(arc)
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
switch overlay {
case let lineOverlay as LineOverlay:
let linerender = MapLineOverlayRenderer(lineOverlay)
setVisibleMapRect(linerender.overlay, animated: true)
return linerender
case let polyline as MKPolyline:
let renderer = MKPolylineRenderer(overlay: polyline)
renderer.strokeColor = UIColor.yellow.withAlphaComponent(0.5)
renderer.lineWidth = 4
return renderer
default:
return MKOverlayRenderer()
}
}

How to enable MapKit floor level?

I am trying to show floor level into my apple app. I know in apple map there are some selected place like airport or shopping mall where this floor level can be seen. I need to achieve exactly that. Just need to show the floor level where this is available. As you can see in the picture, in the right hand side of the image there are 5F,4F,3F,2F etc. I have searched the net but left with no clue yet.
You need to use MKOverlay. You would add each floor as an overlay to your MKMapView and show whatever floor the user selects, hide the others.
Here is a sample for making an overlay:
import MapKit
class MapOverlay: NSObject, MKOverlay {
var coordinate: CLLocationCoordinate2D
var boundingMapRect: MKMapRect
override init() {
let location = CLLocationCoordinate2D(latitude: 75.3307, longitude: -152.1929) // change these for the position of your overlay
let mapSize = MKMapSize(width: 240000000, height: 200000000) // change these numbers for the width and height of your image
boundingMapRect = MKMapRect(origin: MKMapPoint(location), size: mapSize)
coordinate = location
super.init()
}
}
class MapOverlayRenderer: MKOverlayRenderer {
let overlayImage: UIImage
init(overlay: MKOverlay, image: UIImage) {
self.overlayImage = image
super.init(overlay: overlay)
}
override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) {
guard let imageReference = overlayImage.cgImage else { return }
let rect = self.rect(for: overlay.boundingMapRect)
context.scaleBy(x: 1.0, y: -1.0)
context.translateBy(x: 0.0, y: -rect.size.height)
context.draw(imageReference, in: rect)
}
}
Then add it to your map:
let mapOverlay = MapOverlay()
mapView.addOverlay(mapOverlay)
And don't forget the delegate:
mapView.delegate = self
extension ViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
return MapOverlayRenderer(overlay: overlay, image: UIImage(named: "overlayImage")!)
}
}

How to draw a constant line between a series of CLLocationCoordinate in a MapView

I have got an Array of CLLocationCoordinate. I want to draw a constant line.This line will link each adjacent CLLocationCoordinate so when the CLLocationCoordinates‘ distance is very near the line will look like a curve.I wonder how to develop it?
I tried to use the MKPolyLine like this:
var polyline:MKPolyline=MKPolyline(coordinates: arrcoordinate, count: arrcoordinate.count);
but it didn't meet my desire. I also tried like the MKGeodesicPolyline,and it also did not meet my desire.
I just make this probem simple,so I make an array of CLLocationCoordinate like this:
var arrcoordinate:[CLLocationCoordinate2D]=[CLLocationCoordinate2D].init();
arrcoordinate.append(CLLocationCoordinate2D.init(latitude: 100, longitude: 39));
arrcoordinate.append(CLLocationCoordinate2D.init(latitude: 128, longitude: 33));
arrcoordinate.append(CLLocationCoordinate2D.init(latitude: 118, longitude: 55));
arrcoordinate.append(CLLocationCoordinate2D.init(latitude: 122, longitude: 57));
print(arrcoordinate)
var polyline:MKPolyline=MKPolyline.init(coordinates: &arrcoordinate, count: arrcoordinate.count);
self.MapView.addOverlay(polyline);
and make the OverlayRender delegate like this:
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKPolyline {
var polylineRenderer=MKPolylineRenderer.init(overlay: overlay);
polylineRenderer.strokeColor = UIColor.white;
polylineRenderer.lineWidth=2
return polylineRenderer
}
return MKOverlayRenderer.init();
}
but there is no any line appears on the mapview,so I dont know why?
Works fine for me.
I had to change your code a little, because your coordinates are nonsensical. So my version of your code looks like this:
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate {
#IBOutlet weak var map: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
self.map.delegate = self
var arrcoordinate = [CLLocationCoordinate2D]()
arrcoordinate.append(CLLocationCoordinate2D(latitude: 0, longitude: 39))
arrcoordinate.append(CLLocationCoordinate2D(latitude: 28, longitude: 33))
arrcoordinate.append(CLLocationCoordinate2D(latitude: 18, longitude: 55))
arrcoordinate.append(CLLocationCoordinate2D(latitude: 22, longitude: 57))
let polyline = MKPolyline(coordinates: &arrcoordinate, count: arrcoordinate.count)
self.map.add(polyline)
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKPolyline {
let polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = .red
polylineRenderer.lineWidth = 2
return polylineRenderer
}
return MKOverlayRenderer()
}
}

Can't draw a polyline via MapKit in Swift

I'm trying to draw a line between two annotations on my map. The code is working, but i don't see it on map. Here is my code:
func longPressGesture()
{
let lpg = UILongPressGestureRecognizer(target: self, action: "longPressAction:")
lpg.minimumPressDuration = 1;
Map.addGestureRecognizer(lpg)
}
func longPressAction(myRecognizer : UILongPressGestureRecognizer)
{
let currPoint = myRecognizer.locationInView(Map)
let point = Map.convertPoint(currPoint, toCoordinateFromView: Map)
points.append(currPoint);
if(points.count>1)
{
let startPoint = Map.convertPoint(points[points.count-2], toCoordinateFromView: Map)
let endPoint = Map.convertPoint(currPoint, toCoordinateFromView: Map)
var lineCoords = [startPoint,endPoint]
var line = MKPolyline(coordinates: &lineCoords, count: 2)
Map.addOverlay(line)
}
let myAnnotation = MKPointAnnotation();
myAnnotation.coordinate = point
myAnnotation.title = "Test"
myAnnotation.subtitle = "Test subtitle"
Map.addAnnotation(myAnnotation);
}
mapView method(not sure if it is used, i'm new to swift and i didn't write this):
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
print(overlay)
if overlay is MKCircle {
let circle = MKCircleRenderer(overlay: overlay);
circle.strokeColor = UIColor.redColor();
circle.fillColor = UIColor(red: 255, green: 0, blue: 0, alpha: 0.1);
circle.lineWidth = 1;
return circle;
}else if overlay is MKTileOverlay {
let carte_Renderer = MKTileOverlayRenderer(overlay: overlay)
carte_Renderer.alpha = 1
return carte_Renderer
}else if overlay is MKPolyline {
let polylineRenderer = MKPolylineRenderer(overlay: overlay);
polylineRenderer.strokeColor = UIColor.blueColor();
polylineRenderer.lineWidth = 5;
return polylineRenderer;
}else {
return MKPolylineRenderer();
}
}
Ensure you've got an rendererForOverlay method, which defines how your MKPolyline objects will look.
You'll need to include theMKMapViewDelegate as well for this to work.
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer!
{
if overlay is MKPolyline
{
let route: MKPolyline = overlay as MKPolyline
let routeRenderer = MKPolylineRenderer(polyline:route)
routeRenderer.lineWidth = 3.0
routeRenderer.strokeColor = UIColor(red: 45.0/255.0, green: 200.0/255.0, blue: 0.0/255.0, alpha: 1);
return routeRenderer
}
return nil
}