Node distance filter for the mesh map

This commit is contained in:
Garth Vander Houwen 2024-03-24 22:23:55 -07:00
parent 5c212cff04
commit 554fe9a3ca
9 changed files with 83 additions and 11 deletions

View file

@ -50,6 +50,20 @@ enum MeshMapTypes: Int, CaseIterable, Identifiable {
}
}
enum MeshMapDistances: Double, CaseIterable, Identifiable {
case fiftyMiles = 80467.2
case oneHundredMiles = 160934
case twoHundredMiles = 321869
case fiveHundredMiles = 804672
case oneThousandMiles = 1609000
case twoThousandMiles = 3218688
var id: Double { self.rawValue }
var description: String {
let distanceFormatter = MKDistanceFormatter()
return "\(distanceFormatter.string(fromDistance: Double(self.rawValue))) away"
}
}
enum UserTrackingModes: Int, CaseIterable, Identifiable {
case none = 0
case follow = 1

View file

@ -21,13 +21,13 @@ extension PositionEntity {
request.returnsDistinctResults = true
request.sortDescriptors = [NSSortDescriptor(key: "time", ascending: false)]
let positionPredicate = NSPredicate(format: "nodePosition != nil && nodePosition.user.shortName != nil && latest == true && time >= %@", Calendar.current.date(byAdding: .day, value: -2, to: Date())! as NSDate)
let positionPredicate = NSPredicate(format: "nodePosition != nil && (nodePosition.user.shortName != nil || nodePosition.user.shortName != '') && latest == true && time >= %@", Calendar.current.date(byAdding: .day, value: -2, to: Date())! as NSDate)
let pointOfInterest = LocationHelper.currentLocation
if pointOfInterest.latitude != LocationHelper.DefaultLocation.latitude && pointOfInterest.longitude != LocationHelper.DefaultLocation.longitude {
/// Lets just get nodes within about 500 miles
let D: Double = 800000 * 1.1
let D: Double = UserDefaults.meshMapDistance * 1.1
let R: Double = 6371009
let meanLatitidue = pointOfInterest.latitude * .pi / 180
let deltaLatitude = D / R * 180 / .pi

View file

@ -67,4 +67,29 @@ extension String {
: $0 + String($1)
}
}
var length: Int {
return count
}
subscript (i: Int) -> String {
return self[i ..< i + 1]
}
func substring(fromIndex: Int) -> String {
return self[min(fromIndex, length) ..< length]
}
func substring(toIndex: Int) -> String {
return self[0 ..< max(0, toIndex)]
}
subscript (r: Range<Int>) -> String {
let range = Range(uncheckedBounds: (lower: max(0, min(length, r.lowerBound)),
upper: min(length, max(0, r.upperBound))))
let start = index(startIndex, offsetBy: range.lowerBound)
let end = index(start, offsetBy: range.upperBound - range.lowerBound)
return String(self[start ..< end])
}
}

View file

@ -34,6 +34,7 @@ extension UserDefaults {
case provideLocation
case provideLocationInterval
case mapLayer
case meshMapDistance
case meshMapRecentering
case meshMapShowNodeHistory
case meshMapShowRouteLines
@ -76,6 +77,9 @@ extension UserDefaults {
@UserDefault(.mapLayer, defaultValue: .standard)
static var mapLayer: MapLayer
@UserDefault(.meshMapDistance, defaultValue: 800000)
static var meshMapDistance: Double
@UserDefault(.enableMapRecentering, defaultValue: false)
static var enableMapRecentering: Bool

View file

@ -15,7 +15,7 @@ import ActivityKit
func generateMessageMarkdown (message: String) -> String {
let types: NSTextCheckingResult.CheckingType = [.address, .link, .phoneNumber]
let detector = try! NSDataDetector(types: types.rawValue)
let matches = detector.matches(in: message, options: [], range: NSRange(location: 0, length: message.utf16.count))
let matches = detector.matches(in: message, options: [], range: NSRange(location: 0, length: message.utf8.count))
var messageWithMarkdown = message
if matches.count > 0 {
for match in matches {
@ -28,9 +28,14 @@ func generateMessageMarkdown (message: String) -> String {
let phone = messageWithMarkdown[range]
messageWithMarkdown = messageWithMarkdown.replacingOccurrences(of: phone, with: "[\(phone)](tel:\(phone))")
} else if match.resultType == .link {
let url = messageWithMarkdown[range]
let absoluteUrl = match.url?.absoluteString ?? ""
messageWithMarkdown = messageWithMarkdown.replacingOccurrences(of: url, with: "[\(String(match.url?.host ?? "Link"))\(String(match.url?.path ?? ""))](\(absoluteUrl))")
let start = match.range.lowerBound
let stop = match.range.upperBound
if stop > start {
let url = message[start ..< stop]
let absoluteUrl = match.url?.absoluteString ?? ""
let markdownUrl = "[\(url)](\(absoluteUrl))"
messageWithMarkdown = messageWithMarkdown.replacingOccurrences(of: url, with: markdownUrl)
}
}
}
}

View file

@ -19,6 +19,7 @@ struct MapSettingsForm: View {
@Binding var traffic: Bool
@Binding var pointsOfInterest: Bool
@Binding var mapLayer: MapLayer
@Binding var meshMapDistance: Double
@Binding var meshMap: Bool
var body: some View {
@ -56,6 +57,27 @@ struct MapSettingsForm: View {
self.routeLines.toggle()
UserDefaults.enableMapRouteLines = self.routeLines
}
} else {
VStack {
HStack {
Label("Show nodes up to", systemImage: "lines.measurement.horizontal")
Picker("", selection: $meshMapDistance) {
ForEach(MeshMapDistances.allCases) { di in
Text(di.description)
.tag(di.id)
}
}
.pickerStyle(DefaultPickerStyle())
}
.listRowSeparator(.hidden)
Text("You will need to close and re-open the app for this to take effect.")
.font(.callout)
.foregroundColor(.gray)
.listRowSeparator(/*@START_MENU_TOKEN@*/.visible/*@END_MENU_TOKEN@*/)
}
.onChange(of: meshMapDistance) { newMeshMapDistance in
UserDefaults.meshMapDistance = newMeshMapDistance
}
}
Toggle(isOn: $convexHull) {
Label("Convex Hull", systemImage: "button.angledbottom.horizontal.right")

View file

@ -20,6 +20,7 @@ struct NodeMapSwiftUI: View {
@State var showUserLocation: Bool = false
@State var positions: [PositionEntity] = []
/// Map State User Defaults
@AppStorage("meshMapDistance") private var meshMapDistance: Double = 800000
@AppStorage("meshMapShowNodeHistory") private var showNodeHistory = false
@AppStorage("meshMapShowRouteLines") private var showRouteLines = false
@AppStorage("enableMapConvexHull") private var showConvexHull = false
@ -92,7 +93,7 @@ struct NodeMapSwiftUI: View {
.padding()
}
.sheet(isPresented: $isEditingSettings) {
MapSettingsForm(nodeHistory: $showNodeHistory, routeLines: $showRouteLines, convexHull: $showConvexHull, traffic: $showTraffic, pointsOfInterest: $showPointsOfInterest, mapLayer: $selectedMapLayer, meshMap: $isMeshMap)
MapSettingsForm(nodeHistory: $showNodeHistory, routeLines: $showRouteLines, convexHull: $showConvexHull, traffic: $showTraffic, pointsOfInterest: $showPointsOfInterest, mapLayer: $selectedMapLayer, meshMapDistance: $meshMapDistance, meshMap: $isMeshMap)
.onChange(of: (selectedMapLayer)) { newMapLayer in
switch selectedMapLayer {
case .standard:

View file

@ -24,6 +24,7 @@ struct MeshMap: View {
/// Parameters
@State var showUserLocation: Bool = true
/// Map State User Defaults
@AppStorage("meshMapDistance") private var meshMapDistance: Double = 800000
@AppStorage("meshMapShowNodeHistory") private var showNodeHistory = false
@AppStorage("meshMapShowRouteLines") private var showRouteLines = false
@AppStorage("enableMapConvexHull") private var showConvexHull = false
@ -32,8 +33,8 @@ struct MeshMap: View {
@AppStorage("mapLayer") private var selectedMapLayer: MapLayer = .standard
// Map Configuration
@Namespace var mapScope
@State var mapStyle: MapStyle = MapStyle.standard(elevation: .flat, emphasis: MapStyle.StandardEmphasis.muted ,pointsOfInterest: .all, showsTraffic: true)
@State var position = MapCameraPosition.camera(MapCamera(centerCoordinate: LocationHelper.currentLocation, distance: 2500000, heading: 0, pitch: 0))
@State var mapStyle: MapStyle = MapStyle.standard(elevation: .flat, emphasis: MapStyle.StandardEmphasis.muted ,pointsOfInterest: .excludingAll, showsTraffic: false)
@State var position = MapCameraPosition.automatic
@State var isEditingSettings = false
@State var selectedPosition: PositionEntity?
@State var showWaypoints = false
@ -120,7 +121,7 @@ struct MeshMap: View {
.padding()
}
.sheet(isPresented: $isEditingSettings) {
MapSettingsForm(nodeHistory: $showNodeHistory, routeLines: $showRouteLines, convexHull: $showConvexHull, traffic: $showTraffic, pointsOfInterest: $showPointsOfInterest, mapLayer: $selectedMapLayer, meshMap: $isMeshMap)
MapSettingsForm(nodeHistory: $showNodeHistory, routeLines: $showRouteLines, convexHull: $showConvexHull, traffic: $showTraffic, pointsOfInterest: $showPointsOfInterest, mapLayer: $selectedMapLayer, meshMapDistance: $meshMapDistance, meshMap: $isMeshMap)
}
.onChange(of: (appState.navigationPath)) { newPath in

View file

@ -245,7 +245,7 @@ struct ChannelForm: View {
}
}
}
.presentationDetents([.fraction(0.45), .fraction(0.65)])
.presentationDetents([.large])
.presentationDragIndicator(.visible)
}
}