Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Geranium/GeraniumApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ class AppSettings: ObservableObject {
@AppStorage("keepCheckBoxesC") var keepCheckBoxesC: Bool = true
@AppStorage("LocSimAttempts") var locSimAttemptNB: Int = 1
@AppStorage("locSimMultipleAttempts") var locSimMultipleAttempts: Bool = false
@AppStorage("locSimDefaultRadiusMeters") var locSimDefaultRadiusMeters: Double = 5000.0
@AppStorage("locSimRadiusUnit") var locSimRadiusUnit: String = Locale.current.usesMetricSystem ? "km" : "mi"
@AppStorage("locSimCenterOnBookmark") var locSimCenterOnBookmark: Bool = true
@AppStorage("usrUUID") var usrUUID: String = UIDevice.current.identifierForVendor?.uuidString ?? "unknown"
@AppStorage("languageCode") var languageCode: String = ""
@AppStorage("defaultTab") var defaultTab: Int = 1
Expand Down
4 changes: 4 additions & 0 deletions Geranium/LocSim/BookMark/BookMarkSlider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct BookMarkSlider: View {
@Environment(\.dismiss) var dismiss
@Binding var lat: Double
@Binding var long: Double
let onBookmarkSelected: (Bookmark) -> Void
@State private var name = ""
@State private var result: Bool = false
@AppStorage("isMika") var isMika: Bool = false
Expand All @@ -31,6 +32,9 @@ struct BookMarkSlider: View {
List {
ForEach(bookmarks) { bookmark in
Button(action: {
lat = bookmark.lat
long = bookmark.long
onBookmarkSelected(bookmark)
close()
LocSimManager.startLocSim(location: .init(latitude: bookmark.lat, longitude: bookmark.long))
AlertKitAPI.present(
Expand Down
44 changes: 43 additions & 1 deletion Geranium/LocSim/CustomMapView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import MapKit

struct CustomMapView: UIViewRepresentable {
@Binding var tappedCoordinate: EquatableCoordinate?
let defaultRadiusMeters: CLLocationDistance
let centerRequest: MapCenterRequest?

func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
Expand All @@ -23,19 +25,54 @@ struct CustomMapView: UIViewRepresentable {
return mapView
}

func updateUIView(_ uiView: MKMapView, context: Context) {}
func updateUIView(_ uiView: MKMapView, context: Context) {
context.coordinator.parent = self
context.coordinator.applyInitialRegionIfPossible(to: uiView)
context.coordinator.applyCenterRequestIfNeeded(to: uiView)
}

func makeCoordinator() -> Coordinator {
Coordinator(self)
}

class Coordinator: NSObject, MKMapViewDelegate {
var parent: CustomMapView
private var appliedRadiusMeters: CLLocationDistance?
private var handledCenterRequestID: UUID?

init(_ parent: CustomMapView) {
self.parent = parent
}

func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
applyInitialRegionIfPossible(to: mapView)
}

func applyInitialRegionIfPossible(to mapView: MKMapView) {
guard let location = mapView.userLocation.location,
CLLocationCoordinate2DIsValid(location.coordinate) else { return }

let radiusMeters = max(100.0, min(parent.defaultRadiusMeters, 1_000_000.0))
guard appliedRadiusMeters != radiusMeters else { return }

let region = MKCoordinateRegion(
center: location.coordinate,
latitudinalMeters: radiusMeters * 2,
longitudinalMeters: radiusMeters * 2
)
mapView.setRegion(region, animated: false)
appliedRadiusMeters = radiusMeters
}

func applyCenterRequestIfNeeded(to mapView: MKMapView) {
guard let request = parent.centerRequest,
request.id != handledCenterRequestID,
CLLocationCoordinate2DIsValid(request.coordinate) else { return }

mapView.setCenter(request.coordinate, animated: true)
handledCenterRequestID = request.id
}

@objc func handleTap(_ gesture: UITapGestureRecognizer) {
let mapView = gesture.view as! MKMapView
let touchPoint = gesture.location(in: mapView)
Expand All @@ -44,3 +81,8 @@ struct CustomMapView: UIViewRepresentable {
}
}
}

struct MapCenterRequest {
let id = UUID()
let coordinate: CLLocationCoordinate2D
}
22 changes: 16 additions & 6 deletions Geranium/LocSim/LocSimView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ struct LocSimView: View {
@State private var long: Double = 0.0
@State private var altitude: String = "0.0"
@State private var tappedCoordinate: EquatableCoordinate? = nil
@State private var mapCenterRequest: MapCenterRequest? = nil
@State private var bookmarkSheetTggle: Bool = false
var body: some View {
if #available(iOS 16.0, *) {
Expand All @@ -32,15 +33,16 @@ struct LocSimView: View {
@ViewBuilder
private func LocSimMainView() -> some View {
VStack {
CustomMapView(tappedCoordinate: $tappedCoordinate)
CustomMapView(
tappedCoordinate: $tappedCoordinate,
defaultRadiusMeters: appSettings.locSimDefaultRadiusMeters,
centerRequest: mapCenterRequest
)
.onAppear {
CLLocationManager().requestAlwaysAuthorization()
locationManager.requestWhenInUseAuthorization()
}
}
.ignoresSafeArea(.keyboard)
.onAppear {
LocationModel().requestAuthorisation()
}
.onChange(of: tappedCoordinate) { newValue in
if let coordinate = newValue {
let altitudeValue = Double(altitude) ?? 0.0
Expand Down Expand Up @@ -140,7 +142,15 @@ struct LocSimView: View {
}
}
.sheet(isPresented: $bookmarkSheetTggle) {
BookMarkSlider(lat: $lat, long: $long)
BookMarkSlider(lat: $lat, long: $long) { bookmark in
guard appSettings.locSimCenterOnBookmark else { return }
mapCenterRequest = MapCenterRequest(
coordinate: CLLocationCoordinate2D(
latitude: bookmark.lat,
longitude: bookmark.long
)
)
}
}
}

Expand Down
46 changes: 46 additions & 0 deletions Geranium/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,28 @@ struct SettingsView: View {
}
}
Section(header: Label("LocSim Settings", systemImage: "location.fill.viewfinder"), footer: Text("Various settings for LocSim. Sometimes, users can encounter issues with stopping LocSim. Those settings will allow you to attempt to stop LocSim multiple time.")) {
HStack {
Text("Default Map Radius")
Spacer()
TextField("5", value: locSimRadiusBinding, formatter: locSimRadiusFormatter)
.keyboardType(.decimalPad)
.multilineTextAlignment(.trailing)
.frame(maxWidth: 90)
.id(appSettings.locSimRadiusUnit)
Text(appSettings.locSimRadiusUnit == "mi" ? "mi" : "km")
.foregroundColor(.secondary)
}

Picker("Distance Unit", selection: $appSettings.locSimRadiusUnit) {
Text("Kilometers").tag("km")
Text("Miles").tag("mi")
}
.pickerStyle(.segmented)

Toggle(isOn: $appSettings.locSimCenterOnBookmark) {
Text("Center map on selected bookmark")
}

Toggle(isOn: $appSettings.locSimMultipleAttempts) {
Text("Try stopping LocSim multiple times")
}
Expand Down Expand Up @@ -369,4 +391,28 @@ struct SettingsView: View {
.navigationTitle("Settings")
}
}

private var metersPerSelectedUnit: Double {
appSettings.locSimRadiusUnit == "mi" ? 1609.344 : 1000.0
}

private var locSimRadiusBinding: Binding<Double> {
Binding(
get: {
appSettings.locSimDefaultRadiusMeters / metersPerSelectedUnit
},
set: { radius in
guard radius.isFinite, radius > 0 else { return }
appSettings.locSimDefaultRadiusMeters = max(100.0, min(radius * metersPerSelectedUnit, 1_000_000.0))
}
)
}

private var locSimRadiusFormatter: NumberFormatter {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = 2
return formatter
}
}