Skip to content

Commit

Permalink
refactor(app): map annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
krystxf committed May 20, 2024
1 parent ad86f2c commit 9066908
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 28 deletions.
4 changes: 4 additions & 0 deletions app/metro-now.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
2D1B2C582BFAD9FB007ED5EB /* metro-routes.geojson in Resources */ = {isa = PBXBuildFile; fileRef = 2D1B2C552BFAD9FB007ED5EB /* metro-routes.geojson */; };
2D1B2C592BFAD9FB007ED5EB /* metro-stations.geojson in Resources */ = {isa = PBXBuildFile; fileRef = 2D1B2C562BFAD9FB007ED5EB /* metro-stations.geojson */; };
2D1B2C5A2BFAD9FB007ED5EB /* metro-stations.geojson in Resources */ = {isa = PBXBuildFile; fileRef = 2D1B2C562BFAD9FB007ED5EB /* metro-stations.geojson */; };
2D350E672BFBE50600F68039 /* MapStationAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D350E662BFBE50600F68039 /* MapStationAnnotationView.swift */; };
2D4486862BFAA10A005C59CE /* metro_now_watchApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4486852BFAA10A005C59CE /* metro_now_watchApp.swift */; };
2D4486882BFAA10A005C59CE /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4486872BFAA10A005C59CE /* ContentView.swift */; };
2D44868A2BFAA10B005C59CE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2D4486892BFAA10B005C59CE /* Assets.xcassets */; };
Expand Down Expand Up @@ -90,6 +91,7 @@
2D1B2C512BFAD90B007ED5EB /* metroStationsTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = metroStationsTypes.swift; sourceTree = "<group>"; };
2D1B2C552BFAD9FB007ED5EB /* metro-routes.geojson */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "metro-routes.geojson"; path = "../../../data/metro-routes.geojson"; sourceTree = "<group>"; };
2D1B2C562BFAD9FB007ED5EB /* metro-stations.geojson */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "metro-stations.geojson"; path = "../../../data/metro-stations.geojson"; sourceTree = "<group>"; };
2D350E662BFBE50600F68039 /* MapStationAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapStationAnnotationView.swift; sourceTree = "<group>"; };
2D4486832BFAA10A005C59CE /* metro-now-watch Watch App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "metro-now-watch Watch App.app"; sourceTree = BUILT_PRODUCTS_DIR; };
2D4486852BFAA10A005C59CE /* metro_now_watchApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = metro_now_watchApp.swift; sourceTree = "<group>"; };
2D4486872BFAA10A005C59CE /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -297,6 +299,7 @@
isa = PBXGroup;
children = (
2DC63A072BF4C25B00A72C7F /* MapView.swift */,
2D350E662BFBE50600F68039 /* MapStationAnnotationView.swift */,
);
path = Map;
sourceTree = "<group>";
Expand Down Expand Up @@ -471,6 +474,7 @@
2D1B2C4B2BFAD807007ED5EB /* fileUtils.swift in Sources */,
2D1B2C482BFAD7F2007ED5EB /* metroUtils.swift in Sources */,
2D1B2C3B2BFAD6CC007ED5EB /* LocationModel.swift in Sources */,
2D350E672BFBE50600F68039 /* MapStationAnnotationView.swift in Sources */,
2D84CC9F2BF8BD7000D2382B /* PlatformListModel.swift in Sources */,
2D1B2C422BFAD72C007ED5EB /* jsonUtils.swift in Sources */,
2D1B2C3F2BFAD70F007ED5EB /* timeUtils.swift in Sources */,
Expand Down
73 changes: 73 additions & 0 deletions app/metro-now/Core/Map/MapStationAnnotationView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// metro-now
//
// Created by Kryštof Krátký on 20.05.2024.
//

import MapKit
import SwiftUI

struct MapMetroStationView: View {
let metroLines: [String]

var body: some View {
ZStack {
ForEach(Array(metroLines.enumerated()), id: \.0) {
index, metroLine in
let offset: CGFloat = index == 0 ? 0 : (-10 * CGFloat(index))

Rectangle()
.foregroundStyle(.white)
.clipShape(.rect(cornerRadius: .infinity))
.offset(x: offset, y: offset)

Image(
systemName:
getMetroLineIcon(metroLine)
)
.foregroundStyle(getMetroLineColor(metroLine))
.offset(x: offset, y: offset)
}
}
}
}

#Preview("One station annotation") {
Map {
Annotation(
"Random place on map", coordinate: CLLocationCoordinate2D(
latitude: 50.113680, longitude: 14.449520)
) {
MapMetroStationView(
metroLines: ["A"]
)
}
}
}

#Preview("Two stations annotation") {
Map {
Annotation(
"Random place on map", coordinate: CLLocationCoordinate2D(
latitude: 50.113680, longitude: 14.449520)
) {
MapMetroStationView(
metroLines: ["A", "B"]
)
}
}
}

// this is not very valid for Prague, but might be useful in the future
#Preview("Multiple stations annotation") {
Map {
Annotation(
"Random place on map", coordinate: CLLocationCoordinate2D(
latitude: 50.113680, longitude: 14.449520)
) {
MapMetroStationView(
metroLines: ["A", "B", "C", "A", "B", "C"]
)
}
}
}
57 changes: 29 additions & 28 deletions app/metro-now/Core/Map/MapView.swift
Original file line number Diff line number Diff line change
@@ -1,52 +1,53 @@
//
// MapView.swift
// metro-now
//

import MapKit
import SwiftUI

private struct MetroStationAnnotation {
let name: String
let coordinate: CLLocationCoordinate2D
let metroLines: [String] // A | B | C
}

struct MapView: View {
let metroStationsGeoJSON: MetroStationsGeoJSON! = getParsedJSONFile(.METRO_STATIONS_FILE)
@State private var metroStationAnnotations: [MetroStationAnnotation] = []

var body: some View {
Map {
UserAnnotation(
)
UserAnnotation()

ForEach(metroStationsGeoJSON!.features, id: \.properties.name) { feature in
let metroLines: [String] = Array(Set(feature.properties.platforms.map(\.name)))
ForEach(metroStationAnnotations, id: \.name) { station in
Annotation(station.name, coordinate: station.coordinate) {
MapMetroStationView(metroLines: station.metroLines)
}
}
}
.task {
let metroStationsGeoJSON: MetroStationsGeoJSON! = getParsedJSONFile(.METRO_STATIONS_FILE)
guard metroStationsGeoJSON != nil, metroStationsGeoJSON?.features != nil else {
return
}

Annotation(
feature.properties.name,
metroStationAnnotations = metroStationsGeoJSON.features.map { feature in
MetroStationAnnotation(
name: feature.properties.name,
coordinate: CLLocationCoordinate2D(
latitude: feature.geometry.coordinates[1],
longitude: feature.geometry.coordinates[0]
)
) {
ZStack {
ForEach(Array(metroLines.enumerated()), id: \.0) {
index, metroLine in

Rectangle()
.foregroundStyle(.white)
.clipShape(.rect(cornerRadius: .infinity))
.offset(x: index == 0 ? 0 : -10, y: index == 0 ? 0 : -10)

Image(
systemName:
getMetroLineIcon(metroLine)
)
.foregroundStyle(getMetroLineColor(metroLine))
.offset(x: index == 0 ? 0 : -10, y: index == 0 ? 0 : -10)
}
}
}
),
metroLines: Array(Set(feature.properties.platforms.map(\.name)))
)
}
}
.mapStyle(.standard(elevation: .realistic))
.mapControls {
MapUserLocationButton()
/// Shows up when you rotate the map
MapCompass()
/// 3D and 2D button on the top right
MapPitchToggle()
}
}
}
Expand Down

0 comments on commit 9066908

Please sign in to comment.