How to fix cracks appearing in MKPolyline rendering - swift

I am facing cracks issue when rendering MKPolyline. Is there a way to control the Z of the polyline (like we do in game dev with the z-bias) or any other technic?
I believe my code’s quite standard, as follows:
public func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKPolyline {
let renderer = MKPolylineRenderer(overlay: overlay)
// Some code where I define thickness and color
renderer.strokeColor = color
renderer.lineWidth = CGFloat(thickness)
return renderer
}
return MKOverlayRenderer(overlay: overlay)
}

Related

swift MKPolyLineRenderer intersect issue

I'm rendering a bunch of lines on a map that are having an issue when one line goes over another resulting in a merge. I'm using a custom renderer which sets the width and colors etc inside the func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer method. How can I prevent the merge of the MKPolyLines
Here's an image detailing the "merge" issue.
final class RouteRenderer: MKPolylineRenderer {
override func strokePath(_ path: CGPath, in context: CGContext) {
guard let overlayColor = self.overlay as? RouteLine, let color = overlayColor.color else {
super.strokePath(path, in: context)
return
}
context.saveGState()
context.setStrokeColor(color.cgColor)
context.addPath(path)
context.drawPath(using: .stroke)
context.restoreGState()
}
}
Note I'm storing the lines as an array of [MKPolylines] in an attempt to solve the issue but I think that partly solved it, the issue I think is with the renderer.

Prevent replacing of WMS Overlay while adding Polygon or Polyline to MKMapView

I have implemented Web Map Service in the MKMapView by subclassing the MKTileOverlay & rendering it using MKTileOverlayRenderer. It works fine and displays the custom map properly.
When I call method like mapView.addOverlay(polyLine) to add Polyline or Polygon. The WMS overlay gets replaced with the Apple Maps overly.
// Set up the overlay and adds it to MKMapView.
func setupTileRenderer() {
let wmsURL = formTemplate?.wmsURL
let overlay = WMSTileOverlay(urlTemplate: wmsURL)
overlay.canReplaceMapContent = true
mapView.addOverlay(overlay, level: .aboveLabels)
tileRenderer = MKTileOverlayRenderer(tileOverlay: overlay)
wmsTileOverlay = overlay
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKPolyline {
let render = MKPolylineRenderer(overlay: overlay)
render.lineWidth = 2
render.strokeColor = UIColor.red
return render
} else if overlay is MKPolygon {
let render = MKPolygonRenderer(overlay: overlay)
render.lineWidth = 2
render.strokeColor = UIColor.red
return render
} else if overlay is WMSTileOverlay {
return tileRenderer!
}
return MKOverlayRenderer(overlay: overlay)
}
How do I prevent this? I don't want wmsTileOverlay to get replaced while adding polyline or polygon.
I realised that before drawing the polygon I was removing the previous overlays so at that time I was removing all the overlays. Just checking the overlay is WMSTileOverlay then not removing it.
/// Clears the overlays added by the user.
func clearOverlaysOnMapView() {
for overlay in mapView.overlays {
if !(overlay is WMSTileOverlay) {
mapView.removeOverlay(overlay)
}
}
}

How to prevent overlays on the map from disappearing when zoom scale changes in swift?

I am trying to render an overlay (polygon) on the map using swift MapKit. I can render successfully but when I zoom out too much then zoom in again, all the rendered polygons get disappear. How can I prevent that from happening and force the rendered polygons to stay on the map at all zoom scales? I am using MapKit and MKPolygonRenderer.
I add the polygons to the map using the following method in my viewController:
// function to add polygon overlay to the map
private func addPolygonsToMap() {
guard let polygons = arrayOfpolygons else {
return
}
for polygon in polygons {
mapView.addOverlay(polygon)
}
}
My view controller conforms to MKMapViewDelegate and here is the delegate method for it.
// method for overlay on map
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolygonRenderer(overlay: overlay)
renderer.fillColor = UIColor.purple.withAlphaComponent(0.4)
renderer.strokeColor = .black
renderer.lineWidth = 2
return renderer
}
here is a simple demonstration with some points to draw a test polygon.
https://developer.apple.com/documentation/mapkitjs/mapkit/polygonoverlay
I did not find any swift solution for this problem.
I am running on simulator with iOS 13.

MKPolygon Swift not appearing

Im trying to create a shape on my map but I'm having a hard time finding any information about mkpolygon with swift. I was hoping someone on here would see this and point me into the right direction.
This is what I currently have but the polygon is not appearing.
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
let pr = MKPolygonRenderer(overlay: overlay)
pr.strokeColor = UIColor.purpleColor()
pr.lineWidth = 14
return pr
}
func createPolyline(mapView: MKMapView) {
var points=[CLLocationCoordinate2DMake(49.142677, -123.135139),CLLocationCoordinate2DMake(49.142730, -123.125794),CLLocationCoordinate2DMake(49.140874, -123.125805),CLLocationCoordinate2DMake(49.140885, -123.135214)]
let polygon = MKPolygon(coordinates: &points, count: points.count)
self.mapView.addOverlay(polygon)
}
Turns out what I was forgetting was to set the map view delegate. I will leave this up incase anyone wants to see what I used to get mkpolygon working in swift.

iOS 8 SDK, Swift, MapKit Drawing a Route

I need to draw route between two points and I'm using MKDirectionsRequest for my purpose.
Getting a route is OK, but I have trouble with drawing it.
In iOS 8 SDK there's no function
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
There is only this one:
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer!
And for some reason, I can't understand why that method isn't called.
Delegate for MapView is set and MapKit is imported.
Here is the rendererForOverlay function that is implemented:
func rendererForOverlay(overlay: MKOverlay!) -> MKOverlayRenderer! {
println("rendererForOverlay");
var overlayRenderer : MKOverlayRenderer = MKOverlayRenderer(overlay: overlay);
var overlayView : MKPolylineRenderer = MKPolylineRenderer(overlay: overlay);
view.backgroundColor = UIColor.blueColor().colorWithAlphaComponent(0.5);
return overlayView;
}
The map view isn't calling your rendererForOverlay method because it is not named correctly.
The method must be named exactly:
mapView(mapView:rendererForOverlay)
but in your code it's named:
rendererForOverlay(overlay:)
In addition, you should check that the type of the overlay argument is MKPolyline and set the strokeColor of the polyline renderer.
(The view.backgroundColor in the existing code is actually changing the background color of the view controller's view -- not the polyline.)
Example:
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
println("rendererForOverlay");
if (overlay is MKPolyline) {
var pr = MKPolylineRenderer(overlay: overlay);
pr.strokeColor = UIColor.blueColor().colorWithAlphaComponent(0.5);
pr.lineWidth = 5;
return pr;
}
return nil
}