Merge pull request #442 from meshtastic/2.2.17_Working_Changes

Format headings and speed better
This commit is contained in:
Garth Vander Houwen 2023-12-23 22:49:05 -08:00 committed by GitHub
commit 8d9d345e9b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 158 additions and 137 deletions

View file

@ -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

View file

@ -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
}

View file

@ -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()

View file

@ -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)

View file

@ -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")

View file

@ -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)
}
}
}
}

View file

@ -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)
}
}
}