Verified Commit 383e471b authored by asahiocean's avatar asahiocean 🚀
Browse files

New features

Adding and removing markers
Laying the route
Search for a user on the map
Clearing map markers
parent 401f9251
......@@ -725,7 +725,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 4;
CURRENT_PROJECT_VERSION = 5;
DEVELOPMENT_TEAM = KXDT64LHVB;
INFOPLIST_FILE = "SZRCAI/Root Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
......@@ -746,7 +746,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 4;
CURRENT_PROJECT_VERSION = 5;
DEVELOPMENT_TEAM = KXDT64LHVB;
INFOPLIST_FILE = "SZRCAI/Root Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
......
import Foundation
import UIKit
import MapKit
import CoreLocation
extension ViewController: ModelDelegate {
func deselectPin(pin: PinAnnotation) {
func deselectPin(pin annotation: PinAnnotation) {
mapView.deselectAnnotation(annotation, animated: true)
guard let view = mapView.view(for: annotation) else { return }
if let marker = view as? MKMarkerAnnotationView {
marker.markerTintColor = annotation.markerColor
}
}
func modelButtonExecute(sender: UIButton) {
let selected = mapView.model.selected
switch sender.tag {
case Model.buttonTag.graphs.rawValue:
#if DEBUG
print("Trying to build graphs...")
#endif
constructGraphs()
case Model.buttonTag.start.rawValue:
guard selected != nil else { return }
#if DEBUG
print("User has chosen a starting point!")
#endif
case Model.buttonTag.finish.rawValue:
guard selected != nil else { return }
#if DEBUG
print("User selected endpoint!")
#endif
case Model.buttonTag.routecalc.rawValue:
#if DEBUG
print("Trying to make the shortest route!")
#endif
let coords = mapView.model.route.compactMap({ $0.coordinate })
for (i,coord) in coords.enumerated() {
if (i + 1) < coords.count {
createRouteTo(from: coord, to: coords[i+1])
}
}
mainButton?.removeTarget(nil, action: nil, for: .allEvents)
case Model.buttonTag.clear.rawValue:
clearingMap()
print("❌ Clearing the map...")
default: fatalError()
}
}
func createRouteTo(from: CLLocationCoordinate2D, to: CLLocationCoordinate2D) {
if CLLocationCoordinate2DIsValid(from) && CLLocationCoordinate2DIsValid(to) {
let directionRequest = MKDirections.Request()
directionRequest.source = .init(placemark: .init(coordinate: from))
directionRequest.destination = .init(placemark: .init(coordinate: to))
directionRequest.requestsAlternateRoutes = false
directionRequest.transportType = .any
let directions = MKDirections(request: directionRequest)
directions.calculate { [self] (response, error) in
guard let response = response else {
if let error = error {
// MARK: Error message while building a route
let alert = UIAlertController(title: "FAILED TO CREATE A ROUTE",
message: error.localizedDescription, preferredStyle: .alert)
alert.addAction(.init(title: "Remove annotations", style: .destructive, handler: {_ in clearingMap() }))
present(alert, animated: true)
}
return
}
enum TransportType: UInt {
case automobile = 1, walking, transit
var value: String {
switch self {
case .automobile: return "car"
case .walking: return "walk"
case .transit: return "transit"
}
}
}
guard let route = response.routes.first else { return }
mapView.addOverlay(route.polyline)
let transport = (TransportType(rawValue: route.transportType.rawValue)?.value ?? "")
mapView.model.mainButton?.setTitle("\(Int((route.expectedTravelTime)/60)) min / \(transport)", for: .normal)
}
}
}
// Clearing the entire map of annotations and overlays (including graphs)
fileprivate func clearingMap() {
DispatchQueue.main.async { [mapView] () -> Void in
mapView?.model.pins.removeAll()
mapView?.model.route.removeAll()
mapView?.model.graphsBuilt = false
mapView?.overlays.forEach({ mapView?.removeOverlay($0) })
mapView?.annotations.forEach({ mapView?.removeAnnotation($0) })
}
}
internal func constructGraphs() {
......@@ -25,7 +113,6 @@ extension ViewController: ModelDelegate {
// MARK: вершины соединены ребрами при условии, что расстояние между вершинами не более 5км
// condition: vertices are connected by edges, provided that the distance between the vertices is no more than 5 km
print("distance", locations.distance)
if locations.distance < 5000 {
let dashline = DashLine(locations: locations)
......
......@@ -4,7 +4,7 @@ import MapKit
// Тестовое задание «СЗ РЦАИ» iOS Developer
class ViewController: UIViewController {
var mapView: MapView!
/// Button for building graphs and routes
......@@ -19,7 +19,7 @@ class ViewController: UIViewController {
mapView = .init(frame: view.frame)
mapView.delegate = self
view.addSubview(mapView)
mapView.model.delegate = self
buttonsSetup()
......
......@@ -2,12 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string>For the app to work correctly, it needs access to your location</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>For the app to work correctly, it needs access to your location</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>For the app to work correctly, it needs access to your location</string>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
......@@ -28,6 +22,12 @@
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>For the app to work correctly, it needs access to your location</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>For the app to work correctly, it needs access to your location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>For the app to work correctly, it needs access to your location</string>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment