Customize MGLPolyline using mapbox
You need to set the map delegate to self for the functions to work. Here is the code:
Initiate your viewController with MGLMapViewDelegate
class yourController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate, MGLMapViewDelegate{
Then after you set the map, add self.mapView.delegate = self
like so
mapView = MGLMapView(frame: mapViewWrapper.bounds, styleURL: NSURL(string: Mapbox.getTheme()))
mapView = Mapbox.configure(mapView)
mapView.setCenterCoordinate(appleMap.userLocation.coordinate, zoomLevel: 12, animated: true)
mapViewWrapper.addSubview(mapView)
self.mapView.delegate = self
Then your functions will work:
func mapView(mapView: MGLMapView, alphaForShapeAnnotation annotation: MGLShape) -> CGFloat {
// Set the alpha for all shape annotations to 1 (full opacity)
return 1
}
func mapView(mapView: MGLMapView, lineWidthForPolylineAnnotation annotation: MGLPolyline) -> CGFloat {
// Set the line width for polyline annotations
return 5.0
}
func mapView(mapView: MGLMapView, strokeColorForShapeAnnotation annotation: MGLShape) -> UIColor {
// Give our polyline a unique color by checking for its `title` property
return UIColor.redColor()
}
Is it possible to create a custom popup for a MGLPolyline?
When you tap on the MGLPolyline you are selecting it. Even when you have returned false
from annotationCanShowCallout:
the polyline is selected after a tap even though there is probably no visible cue. This is why some of your taps have no visible action. These taps are deselecting the polyline (again invisibly).
What you can do is return false
from annotationCanShowCallout:
(assuming you don't want ANY annotations to have a callout) and use another delegate method to achieve your desired goal.
func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
return false
}
func mapView(_ mapView: MGLMapView, didSelect annotation: MGLAnnotation) {
print("Tapped")
mapView.deselectAnnotation(annotation, animated: false)
}
By immediately deselecting the annotation you can register each tap as a selection, eliminating the missed ones.
Is it possible to make MGLPolyLines selectable? - Swift, MapBox
I've just checked back and it looks like this has been implemented though I'm not sure which Mapbox release rolled this out.
If you take a look at the simple Mapbox example, Annotation Models, that demos an MGLPolyline and interspaced circular annotations, you can make a simple mod to the supplied code and see for yourself. The demo looks like this:
If you look into the viewController code, add a couple of lines below the polyline creation:
let polyline = CustomPolyline(coordinates: &coordinates, count: UInt(coordinates.count))
polyline.title = "Polyline" // New line
polyline.subtitle = "Pretty Poly". // New line
// Set the custom `color` property, later used in the `mapView:strokeColorForShapeAnnotation:` delegate method.
polyline.color = .darkGray
Now you can tap and see a basic callout:
This example subclasses MGLPolyline (CustomPolyline) so that its appearance can be altered slightly but that doesn't change anything with regards to the tappability.
How to draw polyline(MGLPolyline) with dashed lines using mapbox : swift
One option is to use an MGLLineStyleLayer
, which has a lineDashPattern
property.
This example shows how to add a dashed line, but for your use case, it would look more like:
func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
var mapCoordinates: [CLLocationCoordinate2D] = []
let newCoord1 = CLLocationCoordinate2D(latitude: 8.5241, longitude: 76.9366)
let newCoord2 = CLLocationCoordinate2D(latitude:11.8745, longitude: 75.3704)
mapCoordinates.append(newCoord1)
mapCoordinates.append(newCoord2)
polyline = MGLPolyline(coordinates: mapCoordinates, count: UInt(mapCoordinates.count))
source = MGLShapeSource(identifier: "line", shape: polyline, options: nil)
style.addSource(source)
let layer = MGLLineStyleLayer(identifier: "line-layer", source: source)
layer.lineDashPattern = NSExpression(forConstantValue: [2, 1.5])
style.addLayer(layer)
}
Then update the shape
property on source
as necessary.
Mapbox iOS SDK create a curve MGLPolyline with MKGeodesicPolyline get some strange
This is due to the fact the the line cross the international date change line so it's wrapping all the way around.
To avoid that you can add or subtract 360 from your longitude to fix it. https://github.com/mapbox/mapbox.js/issues/360
For example:
import Mapbox
import MapKit
public extension MGLPolyline {
class func geodesicPolyline(fromCoordinate: CLLocationCoordinate2D, toCoordinate: CLLocationCoordinate2D) -> MGLPolyline {
var coordinates = [fromCoordinate, toCoordinate]
let geodesicPolyline = MKGeodesicPolyline(coordinates: &coordinates, count: 2)
var normalizedCoordinates: [CLLocationCoordinate2D] = []
var previousCoordinate: CLLocationCoordinate2D?
for coordinate in geodesicPolyline.coordinates {
var normalizedCoordinate = coordinate
if let previousCoordinate = previousCoordinate, abs(previousCoordinate.longitude - coordinate.longitude) > 180 {
if (previousCoordinate.longitude > coordinate.longitude) {
normalizedCoordinate.longitude += 360
} else {
normalizedCoordinate.longitude -= 360
}
}
normalizedCoordinates.append(normalizedCoordinate)
previousCoordinate = normalizedCoordinate
}
return MGLPolyline(coordinates: normalizedCoordinates, count: UInt(geodesicPolyline.pointCount))
}
}
public extension MKPolyline {
var coordinates: [CLLocationCoordinate2D] {
var coords = [CLLocationCoordinate2D](repeating: kCLLocationCoordinate2DInvalid, count: self.pointCount)
self.getCoordinates(&coords, range: NSRange(location: 0, length: self.pointCount))
return coords
}
}
How to change the color of a MGLPolyline?
You have to make mapView.delegate = self
Then implement this method:
func mapView(_ mapView: MGLMapView, strokeColorForShapeAnnotation annotation: MGLShape) -> UIColor {
return .blue
}
How to make a MGLPolyline tapable?
The Mapbox iOS API doesn't support that yet, unfortunately. See here.
There are a couple of workarounds within that link that you could try though.
UPDATE:
This is now possible: Check here.
How can I change the color of an MGLPolyline?
I found that what needs to be done is you need to create a custom object for the polyline. The default MGLPolyline
does not support this.
Add a custom polyline like so:
class CustomPostPolyline: MGLPolyline {
var color: UIColor!
}
Put this in your didSelect
:
self.mapView.removeAnnotation(chosenPolyline!.polyline!)
chosenPolyline!.polyline!.lineColor = UIColor.green
self.mapView.addAnnotation(chosenPolyline!.polyline!)
Related Topics
How Pass Data from Button in Tableviewcell to View Controller
How to Show an Alert in Swift UIalertview Not Working
Showing Action Sheet in The Custom Cell in Swift
Performance Issue with Swiftui List
Implementing a Custom Viewmodifier Where Output Is Conditional on Concrete View Type (Swiftui)
How to Convert a Pair of Bytes into a Float Using Swift
Swift Variable Declaration Meaning
How to Use Protocols for Stucts to Emulate Classes Inheritance
Swift & Nstextfield: How to Work with Text Completion
Wkwebview on Macos Cuts Off Top
Data Structure for Fast Lookup with Multiple Criteria
Functional Programming Way of Doing Array Conversion
Advantage of Computed Properties (Gettable Ones Only) VS. Stored Properties