80 lines
2.6 KiB
Swift
80 lines
2.6 KiB
Swift
|
|
// Copyright 2020 Google LLC. All rights reserved.
|
||
|
|
//
|
||
|
|
//
|
||
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||
|
|
// file except in compliance with the License. You may obtain a copy of the License at
|
||
|
|
//
|
||
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
//
|
||
|
|
// Unless required by applicable law or agreed to in writing, software distributed under
|
||
|
|
// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||
|
|
// ANY KIND, either express or implied. See the License for the specific language governing
|
||
|
|
// permissions and limitations under the License.
|
||
|
|
|
||
|
|
import GoogleMaps
|
||
|
|
import UIKit
|
||
|
|
|
||
|
|
struct Coordinate: Decodable {
|
||
|
|
let latitude: Double
|
||
|
|
let longitude: Double
|
||
|
|
let elevation: Double
|
||
|
|
|
||
|
|
enum CodingKeys: String, CodingKey {
|
||
|
|
case elevation
|
||
|
|
case latitude = "lat"
|
||
|
|
case longitude = "lng"
|
||
|
|
}
|
||
|
|
|
||
|
|
init(from decoder: Decoder) throws {
|
||
|
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||
|
|
latitude = try container.decode(Double.self, forKey: .latitude)
|
||
|
|
longitude = try container.decode(Double.self, forKey: .longitude)
|
||
|
|
elevation = try container.decode(Double.self, forKey: .elevation)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
final class GradientPolylinesViewController: UIViewController {
|
||
|
|
|
||
|
|
private lazy var mapView: GMSMapView = {
|
||
|
|
let camera = GMSCameraPosition(
|
||
|
|
latitude: 44.1314, longitude: 9.6921, zoom: 14.059, bearing: 328, viewingAngle: 40)
|
||
|
|
return GMSMapView(frame: .zero, camera: camera)
|
||
|
|
}()
|
||
|
|
|
||
|
|
override func loadView() {
|
||
|
|
view = mapView
|
||
|
|
}
|
||
|
|
|
||
|
|
override func viewDidLoad() {
|
||
|
|
super.viewDidLoad()
|
||
|
|
addTrackToMap()
|
||
|
|
}
|
||
|
|
|
||
|
|
private func addTrackToMap() {
|
||
|
|
guard let filePath = Bundle.main.path(forResource: "track", ofType: "json") else { return }
|
||
|
|
guard let data = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else { return }
|
||
|
|
guard let track = try? JSONDecoder().decode([Coordinate].self, from: data)
|
||
|
|
else {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
let path = GMSMutablePath()
|
||
|
|
var colorSpans: [GMSStyleSpan] = []
|
||
|
|
var previousColor: UIColor?
|
||
|
|
|
||
|
|
for coordinate in track {
|
||
|
|
path.addLatitude(coordinate.latitude, longitude: coordinate.longitude)
|
||
|
|
|
||
|
|
let elevation = CGFloat(coordinate.elevation)
|
||
|
|
let toColor = UIColor(hue: elevation / 700.0, saturation: 1, brightness: 0.9, alpha: 1)
|
||
|
|
let fromColor = previousColor ?? toColor
|
||
|
|
let style = GMSStrokeStyle.gradient(from: fromColor, to: toColor)
|
||
|
|
colorSpans.append(GMSStyleSpan(style: style))
|
||
|
|
previousColor = toColor
|
||
|
|
}
|
||
|
|
let polyline = GMSPolyline(path: path)
|
||
|
|
polyline.strokeWidth = 6
|
||
|
|
polyline.map = mapView
|
||
|
|
polyline.spans = colorSpans
|
||
|
|
}
|
||
|
|
}
|