I'm moving my app over to Mapbox and one of the things that I'm stuck on is creating a multicolored polyline where the segment color is set dynamically by speed. The closest thing I've been able to do is create an array of different colored lines and add them to the map as many individual lines but the processing time and frame rate degradation it too much not to mention you can see the different segments. This is easily achievable with MapKit or Google Maps, but as far as I can tell a polyline can only have one color in Mapbox.
A very similar question was asked Here but that was 3 years ago and the answer seem to relate to using the directions API.
The basic function looks like this and I created a custom MGLMulticolorPolyline class so that I could set the color
func locationPolyLine(locations : [Location], averageSpeed: Double, topSpeed: Double) -> [MGLMulticolorPolyline] {
var coordinates: [(CLLocation, CLLocation)] = []
var speeds: [Double] = []
let smallerLocationArray = locations.enumerated().filter({ index, _ in
index % 2 != 0
}).map { $0.1 }
for (first, second) in zip(smallerLocationArray, smallerLocationArray.dropFirst()) {
//create an array of coordinates
let start = CLLocation(latitude: first.locLatitude, longitude: first.locLongitude)
let end = CLLocation(latitude: second.locLatitude, longitude: second.locLongitude)
coordinates.append((start, end))
let distance = end.distance(from: start)
guard let firstTimestamp = first.locTimestamp,
let secondTimestamp = second.locTimestamp else {continue}
let time = secondTimestamp.timeIntervalSince(firstTimestamp as Date)
let speed = time > 0 ? distance / time : 0
speeds.append(speed)
}
var segments: [MGLMulticolorPolyline] = []
var index = 0
for ((start, end), speed) in zip(coordinates, speeds) {
let coords = [start.coordinate, end.coordinate]
let segment = MGLMulticolorPolyline(coordinates: coords, count: 2)
if smallerLocationArray[index].lift == true{
segment.color = UIColor.blue
} else{
segment.color = segmentColor(speed: speed,
midSpeed: averageSpeed,
slowestSpeed: 0.0,
fastestSpeed: topSpeed)
}
segments.append(segment)
index += 1
}
return segments
}
}
and it get added to the map like so
let multiColoredPolyline = MapboxHelper().locationPolyLine(locations: locationsArray, averageSpeed: avgSpeed, topSpeed: maxSpeed)
mapView.addAnnotations(multiColoredPolyline)