mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Base Map Lines
This commit is contained in:
parent
94f690fc48
commit
de57298a8b
2 changed files with 59 additions and 101 deletions
|
|
@ -160,45 +160,6 @@ struct MapViewSwiftUI: UIViewRepresentable {
|
|||
}
|
||||
}
|
||||
}
|
||||
private func setGeoJsonOverlay(mapView: MKMapView) {
|
||||
guard let geoJsonFileUrl = URL(string: "https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json"),
|
||||
// Bundle.main.url(forResource: "location", withExtension: "geojson"),
|
||||
// guard let geoJsonFileUrl = URL(string: "https://hrbrmstr.github.io/noaa-alerts-sp-to-geojson/current-all.geojson"),
|
||||
let geoJsonData = try? Data.init(contentsOf: geoJsonFileUrl) else {
|
||||
fatalError("Failure to fetch the file.")
|
||||
}
|
||||
guard let objs = try? MKGeoJSONDecoder().decode(geoJsonData) as? [MKGeoJSONFeature] else {
|
||||
fatalError("Wrong format")
|
||||
}
|
||||
// Parse the objects
|
||||
objs.forEach { (feature) in
|
||||
guard let geometry = feature.geometry.first,
|
||||
let propData = feature.properties else {
|
||||
return
|
||||
}
|
||||
// Check if it is MKPolygon
|
||||
if let polygon = geometry as? MKPolygon {
|
||||
let polygonInfo = try? JSONDecoder.init().decode(PolygonInfo.self, from: propData)
|
||||
mapView.addOverlay(polygon)
|
||||
// self.view?.render(overlay: polygon, info: polygonInfo)
|
||||
}
|
||||
// Check if it is MKPolyline
|
||||
if let polyline = geometry as? MKPolyline {
|
||||
mapView.addOverlay(polyline, level: .aboveLabels)
|
||||
// let polylineInfo = try? JSONDecoder.init().decode(PolylineInfo.self, from: propData)
|
||||
// self.view?.render(overlay: polyline, info: polylineInfo)
|
||||
}
|
||||
// Check if it is MKPointAnnotation
|
||||
// if let annotation = geometry as? MKPointAnnotation {
|
||||
// let info = try? JSONDecoder.init().decode(Info.self, from: propData)
|
||||
// let storeAnnotation = StoreAnnotation.init(title: info?.name,
|
||||
// subtitle: info?.subTitle,
|
||||
// website: info?.website,
|
||||
// coordinate: annotation.coordinate)
|
||||
// self.view?.setAnnotations(annotations: [storeAnnotation])
|
||||
// }
|
||||
}
|
||||
}
|
||||
func makeUIView(context: Context) -> MKMapView {
|
||||
currentMapLayer = nil
|
||||
mapView.delegate = context.coordinator
|
||||
|
|
|
|||
|
|
@ -13,12 +13,13 @@ import WeatherKit
|
|||
@available(iOS 17.0, *)
|
||||
struct NodeMapSwiftUI: View {
|
||||
|
||||
@Namespace var mapScope
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
/// Map State
|
||||
@Namespace var mapScope
|
||||
@AppStorage("meshMapType") private var meshMapType = 0
|
||||
@AppStorage("meshMapShowNodeHistory") private var showNodeHistory = false
|
||||
@AppStorage("meshMapShowRouteLines") private var meshMapShowRouteLines = false
|
||||
@AppStorage("meshMapShowRouteLines") private var showRouteLines = false
|
||||
@State private var selectedMapLayer: MapLayer = .standard
|
||||
@State var waypointCoordinate: WaypointCoordinate?
|
||||
@State var editingWaypoint: Int = 0
|
||||
|
|
@ -45,88 +46,84 @@ struct NodeMapSwiftUI: View {
|
|||
if mostRecent != nil {
|
||||
NavigationStack {
|
||||
ZStack {
|
||||
Map(initialPosition: .camera(MapCamera(centerCoordinate: mostRecent!.coordinate, distance: 500, heading: 90, pitch: 60)),
|
||||
bounds: MapCameraBounds(minimumDistance: 100, maximumDistance: 3500),
|
||||
Map(initialPosition: .camera(MapCamera(centerCoordinate: mostRecent!.coordinate, distance: 1000, heading: 0, pitch: 60)),
|
||||
bounds: MapCameraBounds(minimumDistance: 100, maximumDistance: .infinity),
|
||||
scope: mapScope) {
|
||||
/// Route Lines
|
||||
if meshMapShowRouteLines {
|
||||
if showRouteLines {
|
||||
MapPolyline(coordinates: lineCoords, contourStyle: .straight)
|
||||
.stroke(Color(nodeColor.lighter()), lineWidth: 8)
|
||||
.stroke(Color(nodeColor.lighter()), lineWidth: 6)
|
||||
}
|
||||
/// Node Annotations
|
||||
ForEach(positionArray.reversed(), id: \.id) { position in
|
||||
Annotation(position.latest ? node.user?.shortName ?? "?" : "", coordinate: position.coordinate) {
|
||||
ZStack {
|
||||
|
||||
let pf = PositionFlags(rawValue: Int(position.nodePosition?.metadata?.positionFlags ?? 3))
|
||||
|
||||
let symbolName = "flipphone"
|
||||
|
||||
if position.latest {
|
||||
Circle()
|
||||
.foregroundStyle(Color(nodeColor).opacity(0.4))
|
||||
let pf = PositionFlags(rawValue: Int(position.nodePosition?.metadata?.positionFlags ?? 3))
|
||||
let formatter = MeasurementFormatter()
|
||||
let speedText = formatter.string(from: Measurement(value: Double(position.speed), unit: UnitSpeed.kilometersPerHour))
|
||||
Annotation(position.latest ? node.user?.shortName ?? "?" : (pf.contains(.Speed) && position.speed > 2) ? speedText : "", coordinate: position.coordinate) {
|
||||
ZStack {
|
||||
if position.latest {
|
||||
Circle()
|
||||
.foregroundStyle(Color(nodeColor.lighter()).opacity(0.4))
|
||||
.frame(width: 60, height: 60)
|
||||
|
||||
Image(systemName: symbolName)
|
||||
|
||||
if pf.contains(.Heading) {
|
||||
Image(systemName: pf.contains(.Speed) && position.speed > 1 ? "location.north.fill" : "hexagon")
|
||||
.symbolEffect(.pulse.byLayer)
|
||||
.padding(7)
|
||||
.foregroundStyle(Color(nodeColor.lighter()).isLight() ? .black : .white)
|
||||
.padding(5)
|
||||
.foregroundStyle(Color(nodeColor).isLight() ? .black : .white)
|
||||
.background(Color(UIColor(hex: UInt32(node.num)).darker()))
|
||||
.clipShape(Circle())
|
||||
.zIndex(100)
|
||||
.rotationEffect(.degrees(Double(position.heading)))
|
||||
} else {
|
||||
if showNodeHistory {
|
||||
if pf.contains(.Heading) {
|
||||
// if parent.userTrackingMode != MKUserTrackingMode.followWithHeading {
|
||||
// annotationView.glyphImage = UIImage(systemName: "location.north.fill")?
|
||||
// subtitle.text! += "Heading: \(String(positionAnnotation.heading)) \n"
|
||||
// } else {
|
||||
// annotationView.glyphImage = UIImage(systemName: "flipphone")
|
||||
// }
|
||||
}
|
||||
if pf.contains(.Speed) {
|
||||
// let formatter = MeasurementFormatter()
|
||||
// formatter.locale = Locale.current
|
||||
// if positionAnnotation.speed <= 1 {
|
||||
// annotationView.glyphImage = UIImage(systemName: "hexagon")
|
||||
// }
|
||||
// subtitle.text! += "Speed: \(formatter.string(from: Measurement(value: Double(positionAnnotation.speed), unit: UnitSpeed.kilometersPerHour))) \n"
|
||||
}
|
||||
|
||||
|
||||
Image(systemName: "flipphone")
|
||||
.symbolEffect(.pulse.byLayer)
|
||||
.padding(5)
|
||||
.foregroundStyle(Color(nodeColor).isLight() ? .black : .white)
|
||||
.background(Color(UIColor(hex: UInt32(node.num)).darker()))
|
||||
.clipShape(Circle())
|
||||
}
|
||||
} else {
|
||||
if showNodeHistory {
|
||||
if pf.contains(.Heading) {
|
||||
Image(systemName: pf.contains(.Speed) && position.speed > 0 ? "location.north.fill" : "hexagon")
|
||||
.padding(2)
|
||||
.foregroundStyle(Color(UIColor(hex: UInt32(node.num)).lighter()).isLight() ? .black : .white)
|
||||
.background(Color(UIColor(hex: UInt32(node.num)).lighter()))
|
||||
.clipShape(Circle())
|
||||
.rotationEffect(.degrees(Double(position.heading)))
|
||||
} else {
|
||||
Image(systemName: "mappin.circle")
|
||||
.padding(2)
|
||||
.foregroundStyle(Color(UIColor(hex: UInt32(node.num)).lighter()).isLight() ? .black : .white)
|
||||
.background(Color(UIColor(hex: UInt32(node.num)).lighter()))
|
||||
.clipShape(Circle())
|
||||
.zIndex(1000)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
.tag(node.num)
|
||||
}
|
||||
.tag(node.num)
|
||||
}
|
||||
.mapScope(mapScope)
|
||||
.mapStyle(.imagery(elevation: .realistic))
|
||||
.mapControls {
|
||||
MapScaleView(scope: mapScope)
|
||||
.mapControlVisibility(.visible)
|
||||
MapUserLocationButton(scope: mapScope)
|
||||
.mapControlVisibility(.visible)
|
||||
MapPitchToggle(scope: mapScope)
|
||||
.mapControlVisibility(.visible)
|
||||
#if targetEnvironment(macCatalyst)
|
||||
MapZoomStepper(scope: mapScope)
|
||||
.mapControlVisibility(.visible)
|
||||
MapPitchSlider(scope: mapScope)
|
||||
.mapControlVisibility(.visible)
|
||||
#endif
|
||||
MapCompass(scope: mapScope)
|
||||
.mapControlVisibility(.visible)
|
||||
}
|
||||
.controlSize(.regular)
|
||||
}
|
||||
.mapScope(mapScope)
|
||||
.mapStyle(.imagery(elevation: .realistic))
|
||||
.mapControls {
|
||||
MapScaleView(scope: mapScope)
|
||||
.mapControlVisibility(.visible)
|
||||
MapUserLocationButton(scope: mapScope)
|
||||
.mapControlVisibility(.visible)
|
||||
MapPitchToggle(scope: mapScope)
|
||||
.mapControlVisibility(.visible)
|
||||
#if targetEnvironment(macCatalyst)
|
||||
MapZoomStepper(scope: mapScope)
|
||||
.mapControlVisibility(.visible)
|
||||
MapPitchSlider(scope: mapScope)
|
||||
.mapControlVisibility(.visible)
|
||||
#endif
|
||||
MapCompass(scope: mapScope)
|
||||
.mapControlVisibility(.visible)
|
||||
}
|
||||
.controlSize(.regular)
|
||||
}
|
||||
.navigationBarTitle(String("Node Map " + (node.user?.shortName ?? "unknown".localized)), displayMode: .inline)
|
||||
.navigationBarItems(trailing:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue