Files
comaps/iphone/Maps/UI/PlacePage/Components/ElevationProfile/ElevationProfileFormatter.swift
Konstantin Pastbin e3e4a1985a Organic Maps sources as of 02.04.2025 (fad26bbf22ac3da75e01e62aa01e5c8e11861005)
To expand with full Organic Maps and Maps.ME commits history run:
  git remote add om-historic [om-historic.git repo url]
  git fetch --tags om-historic
  git replace squashed-history historic-commits
2025-05-08 21:10:51 +07:00

68 lines
2.1 KiB
Swift

import Chart
import CoreApi
final class ElevationProfileFormatter {
private enum Constants {
static let metricToImperialMultiplier: CGFloat = 0.3048
static var metricAltitudeStep: CGFloat = 50
static var imperialAltitudeStep: CGFloat = 100
}
private let distanceFormatter: DistanceFormatter.Type
private let altitudeFormatter: AltitudeFormatter.Type
private let unitSystemMultiplier: CGFloat
private let altitudeStep: CGFloat
private let units: Units
init(units: Units = Settings.measurementUnits()) {
self.units = units
self.distanceFormatter = DistanceFormatter.self
self.altitudeFormatter = AltitudeFormatter.self
switch units {
case .metric:
self.altitudeStep = Constants.metricAltitudeStep
self.unitSystemMultiplier = 1
case .imperial:
self.altitudeStep = Constants.imperialAltitudeStep
self.unitSystemMultiplier = Constants.metricToImperialMultiplier
@unknown default:
fatalError("Unsupported units")
}
}
}
extension ElevationProfileFormatter: ChartFormatter {
func xAxisString(from value: Double) -> String {
distanceFormatter.distanceString(fromMeters: value)
}
func yAxisString(from value: Double) -> String {
altitudeFormatter.altitudeString(fromMeters: value)
}
func yAxisLowerBound(from value: CGFloat) -> CGFloat {
floor((value / unitSystemMultiplier) / altitudeStep) * altitudeStep * unitSystemMultiplier
}
func yAxisUpperBound(from value: CGFloat) -> CGFloat {
ceil((value / unitSystemMultiplier) / altitudeStep) * altitudeStep * unitSystemMultiplier
}
func yAxisSteps(lowerBound: CGFloat, upperBound: CGFloat) -> [CGFloat] {
let lower = yAxisLowerBound(from: lowerBound)
let upper = yAxisUpperBound(from: upperBound)
let range = upper - lower
var stepSize = altitudeStep
var stepsCount = Int((range / stepSize).rounded(.up))
while stepsCount > 6 {
stepSize *= 2 // Double the step size to reduce the step count
stepsCount = Int((range / stepSize).rounded(.up))
}
let steps = stride(from: lower, through: upper, by: stepSize)
return Array(steps)
}
}