mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Format headings and speed better
This commit is contained in:
parent
cb63d13b90
commit
c523b05d23
7 changed files with 158 additions and 137 deletions
|
|
@ -969,25 +969,30 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
if #available(iOS 17.0, macOS 14.0, *) {
|
||||
|
||||
/// Throw out crappy locations and only send a position if we are connected to a device
|
||||
if fromNodeNum <= 0 || LocationsHandler.shared.lastLocation.horizontalAccuracy < 0 || LocationsHandler.shared.lastLocation.horizontalAccuracy > 100 {
|
||||
return false
|
||||
}
|
||||
positionPacket.latitudeI = Int32(LocationsHandler.shared.lastLocation.coordinate.latitude * 1e7)
|
||||
positionPacket.longitudeI = Int32(LocationsHandler.shared.lastLocation.coordinate.longitude * 1e7)
|
||||
let timestamp = LocationsHandler.shared.lastLocation.timestamp
|
||||
positionPacket.time = UInt32(timestamp.timeIntervalSince1970)
|
||||
positionPacket.timestamp = UInt32(timestamp.timeIntervalSince1970)
|
||||
positionPacket.altitude = Int32(LocationsHandler.shared.lastLocation.altitude)
|
||||
positionPacket.satsInView = UInt32(LocationsHandler.satsInView)
|
||||
let currentSpeed = LocationsHandler.shared.lastLocation.speed
|
||||
if currentSpeed > 0 && (!currentSpeed.isNaN || !currentSpeed.isInfinite) {
|
||||
positionPacket.groundSpeed = UInt32(currentSpeed * 3.6)
|
||||
}
|
||||
let currentHeading = LocationsHandler.shared.lastLocation.course
|
||||
if currentHeading > 0 && (!currentHeading.isNaN || !currentHeading.isInfinite) {
|
||||
positionPacket.groundTrack = UInt32(currentHeading)
|
||||
if let lastLocation = LocationsHandler.shared.locationsArray.last {
|
||||
|
||||
/// Throw out crappy locations and only send a position if we are connected to a device
|
||||
if fromNodeNum <= 0 || lastLocation.horizontalAccuracy < 0 || lastLocation.horizontalAccuracy > 100 {
|
||||
return false
|
||||
}
|
||||
positionPacket.latitudeI = Int32(lastLocation.coordinate.latitude * 1e7)
|
||||
positionPacket.longitudeI = Int32(lastLocation.coordinate.longitude * 1e7)
|
||||
let timestamp = lastLocation.timestamp
|
||||
positionPacket.time = UInt32(timestamp.timeIntervalSince1970)
|
||||
positionPacket.timestamp = UInt32(timestamp.timeIntervalSince1970)
|
||||
positionPacket.altitude = Int32(lastLocation.altitude)
|
||||
positionPacket.satsInView = UInt32(LocationsHandler.satsInView)
|
||||
let currentSpeed = lastLocation.speed
|
||||
if currentSpeed > 0 && (!currentSpeed.isNaN || !currentSpeed.isInfinite) {
|
||||
positionPacket.groundSpeed = UInt32(currentSpeed * 3.6)
|
||||
}
|
||||
let currentHeading = lastLocation.course
|
||||
if currentHeading > 0 && (!currentHeading.isNaN || !currentHeading.isInfinite) {
|
||||
positionPacket.groundTrack = UInt32(currentHeading)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
if fromNodeNum <= 0 || LocationHelper.currentLocation.distance(from: LocationHelper.DefaultLocation) == 0.0 {
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import CoreLocation
|
|||
var locationsArray: [CLLocation]
|
||||
var enableSmartPosition: Bool
|
||||
|
||||
@Published var lastLocation = CLLocation()
|
||||
//@Published var lastLocation = CLLocation()
|
||||
@Published var isStationary = false
|
||||
@Published var count = 0
|
||||
|
||||
|
|
@ -59,9 +59,9 @@ import CoreLocation
|
|||
var locationAdded: Bool
|
||||
if enableSmartPosition {
|
||||
locationAdded = addLocation(loc)
|
||||
//print("Added Location \(self.count): \(loc)")
|
||||
} else {
|
||||
locationsArray.append(loc)
|
||||
self.lastLocation = loc
|
||||
locationAdded = true
|
||||
}
|
||||
if !locationAdded {
|
||||
|
|
@ -96,32 +96,33 @@ import CoreLocation
|
|||
return false
|
||||
}
|
||||
locationsArray.append(location)
|
||||
lastLocation = location
|
||||
return true
|
||||
}
|
||||
|
||||
static let DefaultLocation = CLLocationCoordinate2D(latitude: 37.3346, longitude: -122.0090)
|
||||
|
||||
static var satsInView: Int {
|
||||
// If we have a position we have a sat
|
||||
var sats = 1
|
||||
if shared.lastLocation.verticalAccuracy > 0 {
|
||||
sats = 4
|
||||
if 0...5 ~= shared.lastLocation.horizontalAccuracy {
|
||||
sats = 12
|
||||
} else if 6...15 ~= shared.lastLocation.horizontalAccuracy {
|
||||
sats = 10
|
||||
} else if 16...30 ~= shared.lastLocation.horizontalAccuracy {
|
||||
sats = 9
|
||||
} else if 31...45 ~= shared.lastLocation.horizontalAccuracy {
|
||||
sats = 7
|
||||
} else if 46...60 ~= shared.lastLocation.horizontalAccuracy {
|
||||
sats = 5
|
||||
var sats = 0
|
||||
if let newLocation = shared.locationsArray.last{
|
||||
sats = 1
|
||||
if newLocation.verticalAccuracy > 0 {
|
||||
sats = 4
|
||||
if 0...5 ~= newLocation.horizontalAccuracy {
|
||||
sats = 12
|
||||
} else if 6...15 ~= newLocation.horizontalAccuracy {
|
||||
sats = 10
|
||||
} else if 16...30 ~= newLocation.horizontalAccuracy {
|
||||
sats = 9
|
||||
} else if 31...45 ~= newLocation.horizontalAccuracy {
|
||||
sats = 7
|
||||
} else if 46...60 ~= newLocation.horizontalAccuracy {
|
||||
sats = 5
|
||||
}
|
||||
} else if newLocation.verticalAccuracy < 0 && 60...300 ~= newLocation.horizontalAccuracy {
|
||||
sats = 3
|
||||
} else if newLocation.verticalAccuracy < 0 && newLocation.horizontalAccuracy > 300 {
|
||||
sats = 2
|
||||
}
|
||||
} else if shared.lastLocation.verticalAccuracy < 0 && 60...300 ~= shared.lastLocation.horizontalAccuracy {
|
||||
sats = 3
|
||||
} else if shared.lastLocation.verticalAccuracy < 0 && shared.lastLocation.horizontalAccuracy > 300 {
|
||||
sats = 2
|
||||
}
|
||||
return sats
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,20 +111,18 @@ struct PositionPopover: View {
|
|||
let degrees = Angle.degrees(Double(position.heading))
|
||||
Label {
|
||||
let heading = Measurement(value: degrees.degrees, unit: UnitAngle.degrees)
|
||||
Text("Heading: \(heading.formatted())")
|
||||
.foregroundColor(.primary)
|
||||
Text("Heading: \(heading.formatted(.measurement(width: .narrow, numberFormatStyle: .number.precision(.fractionLength(0)))))")
|
||||
} icon: {
|
||||
Image(systemName: "location.north")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.frame(width: 35)
|
||||
.rotationEffect(degrees)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.frame(width: 35)
|
||||
.rotationEffect(degrees)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
/// Speed
|
||||
let formatter = MeasurementFormatter()
|
||||
let speed = Measurement(value: Double(position.speed), unit: UnitSpeed.kilometersPerHour)
|
||||
Label {
|
||||
Text("Speed: \(formatter.string(from: Measurement(value: Double(position.speed), unit: UnitSpeed.kilometersPerHour)))")
|
||||
// .font(.footnote)
|
||||
Text("Speed: \(speed.formatted(.measurement(width: .abbreviated, numberFormatStyle: .number.precision(.fractionLength(0)))))")
|
||||
.foregroundColor(.primary)
|
||||
} icon: {
|
||||
Image(systemName: "gauge.with.dots.needle.33percent")
|
||||
|
|
@ -132,17 +130,18 @@ struct PositionPopover: View {
|
|||
.frame(width: 35)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
|
||||
/// Distance
|
||||
if locationsHandler.lastLocation.distance(from: CLLocation(latitude: LocationsHandler.DefaultLocation.latitude, longitude: LocationsHandler.DefaultLocation.longitude)) > 0.0 {
|
||||
let metersAway = position.coordinate.distance(from:CLLocationCoordinate2D(latitude: locationsHandler.lastLocation.coordinate.latitude, longitude: locationsHandler.lastLocation.coordinate.longitude))
|
||||
Label {
|
||||
Text("distance".localized + ": \(distanceFormatter.string(fromDistance: Double(metersAway)))")
|
||||
.foregroundColor(.primary)
|
||||
} icon: {
|
||||
Image(systemName: "lines.measurement.horizontal")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.frame(width: 35)
|
||||
if let lastLocation = locationsHandler.locationsArray.last {
|
||||
/// Distance
|
||||
if lastLocation.distance(from: CLLocation(latitude: LocationsHandler.DefaultLocation.latitude, longitude: LocationsHandler.DefaultLocation.longitude)) > 0.0 {
|
||||
let metersAway = position.coordinate.distance(from:CLLocationCoordinate2D(latitude: lastLocation.coordinate.latitude, longitude: lastLocation.coordinate.longitude))
|
||||
Label {
|
||||
Text("distance".localized + ": \(distanceFormatter.string(fromDistance: Double(metersAway)))")
|
||||
.foregroundColor(.primary)
|
||||
} icon: {
|
||||
Image(systemName: "lines.measurement.horizontal")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.frame(width: 35)
|
||||
}
|
||||
}
|
||||
}
|
||||
Spacer()
|
||||
|
|
|
|||
|
|
@ -64,16 +64,17 @@ struct NodeListItem: View {
|
|||
HStack {
|
||||
let lastPostion = node.positions!.reversed()[0] as! PositionEntity
|
||||
if #available(iOS 17.0, macOS 14.0, *) {
|
||||
let myCoord = CLLocation(latitude: LocationsHandler.shared.lastLocation.coordinate.latitude, longitude: LocationsHandler.shared.lastLocation.coordinate.longitude)
|
||||
if lastPostion.nodeCoordinate != nil && myCoord.coordinate.longitude != LocationsHandler.DefaultLocation.longitude && myCoord.coordinate.latitude != LocationsHandler.DefaultLocation.latitude {
|
||||
let nodeCoord = CLLocation(latitude: lastPostion.nodeCoordinate!.latitude, longitude: lastPostion.nodeCoordinate!.longitude)
|
||||
let metersAway = nodeCoord.distance(from: myCoord)
|
||||
Image(systemName: "lines.measurement.horizontal")
|
||||
.font(.callout)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
DistanceText(meters: metersAway).font(.callout)
|
||||
if let currentLocation = LocationsHandler.shared.locationsArray.last {
|
||||
let myCoord = CLLocation(latitude: currentLocation.coordinate.latitude, longitude: currentLocation.coordinate.longitude)
|
||||
if lastPostion.nodeCoordinate != nil && myCoord.coordinate.longitude != LocationsHandler.DefaultLocation.longitude && myCoord.coordinate.latitude != LocationsHandler.DefaultLocation.latitude {
|
||||
let nodeCoord = CLLocation(latitude: lastPostion.nodeCoordinate!.latitude, longitude: lastPostion.nodeCoordinate!.longitude)
|
||||
let metersAway = nodeCoord.distance(from: myCoord)
|
||||
Image(systemName: "lines.measurement.horizontal")
|
||||
.font(.callout)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
DistanceText(meters: metersAway).font(.callout)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
let myCoord = CLLocation(latitude: LocationHelper.currentLocation.latitude, longitude: LocationHelper.currentLocation.longitude)
|
||||
|
|
|
|||
|
|
@ -52,8 +52,16 @@ struct AppSettings: View {
|
|||
.font(.footnote)
|
||||
}
|
||||
if locationHelper.locationManager.location?.courseAccuracy ?? 0 > 0 {
|
||||
Label("Heading \(String(format: "%.2f", locationHelper.locationManager.location?.course ?? 0))°", systemImage: "location.circle")
|
||||
.font(.footnote)
|
||||
let degrees = Angle.degrees(locationHelper.locationManager.location?.course ?? 0)
|
||||
Label {
|
||||
let heading = Measurement(value: degrees.degrees, unit: UnitAngle.degrees)
|
||||
Text("Heading: \(heading.formatted(.measurement(width: .narrow)))")
|
||||
} icon: {
|
||||
Image(systemName: "location.north")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.rotationEffect(degrees)
|
||||
}
|
||||
.font(.footnote)
|
||||
}
|
||||
if locationHelper.locationManager.location?.speedAccuracy ?? 0 > 0 {
|
||||
Label("Speed \(speed.formatted())", systemImage: "speedometer")
|
||||
|
|
|
|||
|
|
@ -13,48 +13,52 @@ struct GPSStatus: View {
|
|||
|
||||
@ObservedObject var locationsHandler: LocationsHandler = LocationsHandler.shared
|
||||
var body: some View {
|
||||
let horizontalAccuracy = Measurement(value: locationsHandler.lastLocation.horizontalAccuracy, unit: UnitLength.meters)
|
||||
let verticalAccuracy = Measurement(value: locationsHandler.lastLocation.verticalAccuracy, unit: UnitLength.meters)
|
||||
let altitiude = Measurement(value: locationsHandler.lastLocation.altitude, unit: UnitLength.meters)
|
||||
let speed = Measurement(value: locationsHandler.lastLocation.speed, unit: UnitSpeed.kilometersPerHour)
|
||||
let speedAccuracy = Measurement(value: locationsHandler.lastLocation.speedAccuracy, unit: UnitSpeed.metersPerSecond)
|
||||
let courseAccuracy = Measurement(value: locationsHandler.lastLocation.courseAccuracy, unit: UnitAngle.degrees)
|
||||
Label("Coordinate \(String(format: "%.5f", locationsHandler.lastLocation.coordinate.latitude)), \(String(format: "%.5f", LocationsHandler.shared.lastLocation.coordinate.longitude))", systemImage: "mappin")
|
||||
.font(.footnote)
|
||||
.textSelection(.enabled)
|
||||
HStack {
|
||||
Label("Accuracy \(horizontalAccuracy.formatted())", systemImage: "scope")
|
||||
|
||||
if let newLocation = locationsHandler.locationsArray.last {
|
||||
let horizontalAccuracy = Measurement(value: newLocation.horizontalAccuracy, unit: UnitLength.meters)
|
||||
let verticalAccuracy = Measurement(value: newLocation.verticalAccuracy, unit: UnitLength.meters)
|
||||
let altitiude = Measurement(value: newLocation.altitude, unit: UnitLength.meters)
|
||||
let speed = Measurement(value: newLocation.speed, unit: UnitSpeed.kilometersPerHour)
|
||||
let speedAccuracy = Measurement(value: newLocation.speedAccuracy, unit: UnitSpeed.metersPerSecond)
|
||||
let courseAccuracy = Measurement(value: newLocation.courseAccuracy, unit: UnitAngle.degrees)
|
||||
Label("Coordinate \(String(format: "%.5f", newLocation.coordinate.latitude)), \(String(format: "%.5f", newLocation.coordinate.longitude))", systemImage: "mappin")
|
||||
.font(.footnote)
|
||||
Label("Sats Estimate \(LocationsHandler.satsInView)", systemImage: "sparkles")
|
||||
.font(.footnote)
|
||||
}
|
||||
HStack {
|
||||
if locationsHandler.lastLocation.verticalAccuracy > 0 {
|
||||
Label("Altitude \(altitiude.formatted())", systemImage: "mountain.2")
|
||||
.textSelection(.enabled)
|
||||
HStack {
|
||||
Label("Accuracy \(horizontalAccuracy.formatted())", systemImage: "scope")
|
||||
.font(.footnote)
|
||||
Label("Sats Estimate \(LocationsHandler.satsInView)", systemImage: "sparkles")
|
||||
.font(.footnote)
|
||||
|
||||
}
|
||||
Label("Accuracy \(verticalAccuracy.formatted())", systemImage: "lines.measurement.vertical")
|
||||
.font(.caption2)
|
||||
}
|
||||
HStack {
|
||||
let degrees = Angle.degrees(LocationsHandler.shared.lastLocation.course)
|
||||
Label {
|
||||
let heading = Measurement(value: degrees.degrees, unit: UnitAngle.degrees)
|
||||
Text("Heading: \(heading.formatted())")
|
||||
} icon: {
|
||||
Image(systemName: "location.north")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.rotationEffect(degrees)
|
||||
HStack {
|
||||
if newLocation.verticalAccuracy > 0 {
|
||||
Label("Altitude \(altitiude.formatted())", systemImage: "mountain.2")
|
||||
.font(.footnote)
|
||||
}
|
||||
Label("Accuracy \(verticalAccuracy.formatted())", systemImage: "lines.measurement.vertical")
|
||||
.font(.caption2)
|
||||
}
|
||||
.font(.footnote)
|
||||
Label("Accuracy \(courseAccuracy.formatted())", systemImage: "safari")
|
||||
.font(.caption2)
|
||||
}
|
||||
HStack {
|
||||
Label("Speed \(speed.formatted())", systemImage: "speedometer")
|
||||
HStack {
|
||||
let degrees = Angle.degrees(newLocation.course)
|
||||
Label {
|
||||
let heading = Measurement(value: degrees.degrees, unit: UnitAngle.degrees)
|
||||
Text("Heading: \(heading.formatted(.measurement(width: .narrow, numberFormatStyle: .number.precision(.fractionLength(0)))))")
|
||||
} icon: {
|
||||
Image(systemName: "location.north")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.rotationEffect(degrees)
|
||||
}
|
||||
.font(.footnote)
|
||||
Label("Accuracy \(speedAccuracy.formatted())", systemImage: "gauge.with.dots.needle.bottom.50percent.badge.plus")
|
||||
.font(.caption2)
|
||||
Label("Accuracy \(courseAccuracy.formatted(.measurement(width: .narrow, numberFormatStyle: .number.precision(.fractionLength(0)))))", systemImage: "safari")
|
||||
.font(.caption2)
|
||||
}
|
||||
HStack {
|
||||
Label("Speed \(speed.formatted(.measurement(width: .abbreviated, numberFormatStyle: .number.precision(.fractionLength(0)))))", systemImage: "speedometer")
|
||||
.font(.footnote)
|
||||
Label("Accuracy \(speedAccuracy.formatted(.measurement(width: .abbreviated, numberFormatStyle: .number.precision(.fractionLength(0)))))", systemImage: "gauge.with.dots.needle.bottom.50percent.badge.plus")
|
||||
.font(.caption2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,40 +123,43 @@ struct RouteRecorder: View {
|
|||
.padding()
|
||||
Divider()
|
||||
VStack(alignment: .leading) {
|
||||
let horizontalAccuracy = Measurement(value: locationsHandler.lastLocation.horizontalAccuracy, unit: UnitLength.meters)
|
||||
let verticalAccuracy = Measurement(value: locationsHandler.lastLocation.verticalAccuracy, unit: UnitLength.meters)
|
||||
let altitiude = Measurement(value: locationsHandler.lastLocation.altitude, unit: UnitLength.meters)
|
||||
let speed = Measurement(value: locationsHandler.lastLocation.speed, unit: UnitSpeed.kilometersPerHour)
|
||||
List {
|
||||
Label("Coordinate \(String(format: "%.5f", locationsHandler.lastLocation.coordinate.latitude)), \(String(format: "%.5f", locationsHandler.lastLocation.coordinate.longitude))", systemImage: "mappin")
|
||||
.textSelection(.enabled)
|
||||
Label("Horizontal Accuracy \(horizontalAccuracy.formatted())", systemImage: "scope")
|
||||
if locationsHandler.lastLocation.verticalAccuracy > 0 {
|
||||
Label("Altitude \(altitiude.formatted())", systemImage: "mountain.2")
|
||||
}
|
||||
Label("Vertical Accuracy \(verticalAccuracy.formatted())", systemImage: "lines.measurement.vertical")
|
||||
Label("Satellites Estimate \(LocationHelper.satsInView)", systemImage: "sparkles")
|
||||
Label("\(locationsHandler.isStationary ? "Moving" : "Stationary")", systemImage: locationsHandler.isStationary ? "figure.walk.motion" : "figure.stand")
|
||||
if locationsHandler.lastLocation.speedAccuracy > 0 {
|
||||
Label("Speed \(speed.formatted())", systemImage: "speedometer")
|
||||
}
|
||||
if locationsHandler.lastLocation.courseAccuracy > 0 {
|
||||
/// Heading
|
||||
let degrees = Angle.degrees(Double(locationsHandler.lastLocation.course))
|
||||
Label {
|
||||
let heading = Measurement(value: degrees.degrees, unit: UnitAngle.degrees)
|
||||
/// Text("Heading: \(heading.formatted())")
|
||||
Text("Heading \(String(format: "%.2f", locationsHandler.lastLocation.course))°")
|
||||
.foregroundColor(.primary)
|
||||
} icon: {
|
||||
Image(systemName: "location.circle")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.frame(width: 35)
|
||||
.rotationEffect(degrees)
|
||||
if let lastLocation = locationsHandler.locationsArray.last {
|
||||
|
||||
let horizontalAccuracy = Measurement(value: lastLocation.horizontalAccuracy, unit: UnitLength.meters)
|
||||
let verticalAccuracy = Measurement(value: lastLocation.verticalAccuracy, unit: UnitLength.meters)
|
||||
let altitiude = Measurement(value: lastLocation.altitude, unit: UnitLength.meters)
|
||||
let speed = Measurement(value: lastLocation.speed, unit: UnitSpeed.kilometersPerHour)
|
||||
List {
|
||||
Label("Coordinate \(String(format: "%.5f", lastLocation.coordinate.latitude)), \(String(format: "%.5f", lastLocation.coordinate.longitude))", systemImage: "mappin")
|
||||
.textSelection(.enabled)
|
||||
Label("Horizontal Accuracy \(horizontalAccuracy.formatted())", systemImage: "scope")
|
||||
if lastLocation.verticalAccuracy > 0 {
|
||||
Label("Altitude \(altitiude.formatted())", systemImage: "mountain.2")
|
||||
}
|
||||
Label("Vertical Accuracy \(verticalAccuracy.formatted())", systemImage: "lines.measurement.vertical")
|
||||
Label("Satellites Estimate \(LocationHelper.satsInView)", systemImage: "sparkles")
|
||||
Label("\(locationsHandler.isStationary ? "Moving" : "Stationary")", systemImage: locationsHandler.isStationary ? "figure.walk.motion" : "figure.stand")
|
||||
if lastLocation.speedAccuracy > 0 {
|
||||
Label("Speed \(speed.formatted())", systemImage: "speedometer")
|
||||
}
|
||||
if lastLocation.courseAccuracy > 0 {
|
||||
/// Heading
|
||||
let degrees = Angle.degrees(Double(lastLocation.course))
|
||||
Label {
|
||||
let heading = Measurement(value: degrees.degrees, unit: UnitAngle.degrees)
|
||||
/// Text("Heading: \(heading.formatted())")
|
||||
Text("Heading \(String(format: "%.2f", lastLocation.course))°")
|
||||
.foregroundColor(.primary)
|
||||
} icon: {
|
||||
Image(systemName: "location.circle")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.frame(width: 35)
|
||||
.rotationEffect(degrees)
|
||||
}
|
||||
}
|
||||
}
|
||||
.listStyle(.plain)
|
||||
}
|
||||
.listStyle(.plain)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue