Created
September 28, 2023 19:24
-
-
Save cedricbahirwe/31a582e0753cec96e4383863d493c33b to your computer and use it in GitHub Desktop.
A demo on seats simulations using MapBox
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import MapboxMaps | |
class ViewController: UIViewController { | |
private let geoJSONDataSourceIdentifier = "geoJSON-data-source" | |
private var mapView: MapView! | |
private var label: UILabel! | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
let options = MapInitOptions(styleURI: .light) | |
mapView = MapView(frame: view.bounds, mapInitOptions: options) | |
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] | |
view.addSubview(mapView) | |
mapView.mapboxMap.onNext(event: .mapLoaded) { [weak self] _ in | |
guard let self else { return } | |
// Remove Stadium ID | |
try! self.mapView.mapboxMap.style.removeLayer(withId: "poi-label") | |
self.setupExample() | |
// Set the center coordinate and zoom level. | |
let centerCoordinate = CLLocationCoordinate2D(latitude: -1.954857, longitude: 30.114292) | |
let camera = CameraOptions(center: centerCoordinate, zoom: 17.0) | |
self.mapView.mapboxMap.setCamera(to: camera) | |
} | |
setupLabel() | |
} | |
private func setupLabel() { | |
label = UILabel() | |
label.text = "Uknown selection" | |
label.backgroundColor = .black.withAlphaComponent(0.3) | |
label.textColor = .white | |
label.translatesAutoresizingMaskIntoConstraints = false | |
view.addSubview(label) | |
NSLayoutConstraint.activate([ | |
label.centerXAnchor.constraint(equalTo: view.centerXAnchor), | |
label.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0.0), | |
label.heightAnchor.constraint(equalToConstant: 100.0), | |
label.leadingAnchor.constraint(equalTo: view.leadingAnchor), | |
label.trailingAnchor.constraint(equalTo: view.trailingAnchor) | |
]) | |
} | |
// Load GeoJSON file from local bundle and decode into a `FeatureCollection`. | |
private func decodeGeoJSON(from fileName: String) throws -> FeatureCollection? { | |
guard let path = Bundle.main.path(forResource: fileName, ofType: "geojson") else { | |
preconditionFailure("File '\(fileName)' not found.") | |
} | |
let filePath = URL(fileURLWithPath: path) | |
var featureCollection: FeatureCollection? | |
do { | |
let data = try Data(contentsOf: filePath) | |
featureCollection = try JSONDecoder().decode(FeatureCollection.self, from: data) | |
} catch { | |
print("Error parsing data: \(error)") | |
} | |
return featureCollection | |
} | |
private func setupExample() { | |
// Attempt to decode GeoJSON from file bundled with application. | |
guard let featureCollection = try? decodeGeoJSON(from: "map") else { fatalError() } | |
// Create a GeoJSON data source. | |
var geoJSONSource = GeoJSONSource() | |
geoJSONSource.data = .featureCollection(featureCollection) | |
var polyLayer = FillLayer(id: "fill-layer") | |
polyLayer.filter = Exp(.eq) { | |
"$type" | |
"Polygon" | |
} | |
polyLayer.source = geoJSONDataSourceIdentifier | |
polyLayer.fillColor = .constant(.init(.black.withAlphaComponent(0.2))) | |
polyLayer.fillOutlineColor = .constant(.init(.black.withAlphaComponent(0.9))) | |
polyLayer.fillOutlineColorTransition = .init(duration: 3, delay: 1) | |
// Add the source and style layer to the map style. | |
try! mapView.mapboxMap.style.addSource(geoJSONSource, id: geoJSONDataSourceIdentifier) | |
try! mapView.mapboxMap.style.addLayer(polyLayer, layerPosition: nil) | |
mapView.gestures.delegate = self | |
} | |
} | |
extension ViewController: GestureManagerDelegate { | |
func gestureManager(_ gestureManager: GestureManager, didBegin gestureType: GestureType) {} | |
func gestureManager(_ gestureManager: GestureManager, didEndAnimatingFor gestureType: GestureType) {} | |
func gestureManager(_ gestureManager: GestureManager, didEnd gestureType: GestureType, willAnimate: Bool) { | |
switch gestureType { | |
case .singleTap: | |
let point = gestureManager.singleTapGestureRecognizer.location(in: mapView) | |
let coordinate = mapView.mapboxMap.coordinate(for: point) | |
let options = RenderedQueryOptions(layerIds: ["fill-layer"], filter: nil) | |
mapView.mapboxMap.queryRenderedFeatures(with: point, options: options) { [weak self] result in | |
switch result { | |
case .failure(let error): | |
self?.label.text = "Error: \(error.localizedDescription)" | |
case .success(let queryFeatures): | |
guard !queryFeatures.isEmpty else { | |
self?.label.text = "Query returned empty feature" | |
return | |
} | |
let queryFeature = queryFeatures.first! | |
let name = (queryFeature.feature.properties?["name"] as? JSONValue)?.rawValue | |
let price = (queryFeature.feature.properties?["price"] as? JSONValue)?.rawValue | |
self?.label.text = "Name: \(name ?? "-") And Price: \(price ?? "-")" | |
let circleAnnotationManager = self?.mapView.annotations.makeCircleAnnotationManager() | |
circleAnnotationManager?.delegate = self | |
var annotation = CircleAnnotation(centerCoordinate: coordinate) | |
annotation.circleColor = StyleColor(.red) | |
annotation.circleRadius = 8 | |
annotation.isDraggable = true | |
circleAnnotationManager?.annotations = [annotation] | |
// Set the center coordinate and zoom level. | |
let camera = CameraOptions(center: coordinate, zoom: 19.0) | |
self?.mapView.camera.fly(to: camera, duration: 1) | |
} | |
} | |
default: break | |
} | |
} | |
} | |
extension ViewController: AnnotationInteractionDelegate { | |
func annotationManager(_ manager: AnnotationManager, didDetectTappedAnnotations annotations: [Annotation]) { | |
print("AnnotationManager did detect tapped annotations: \(annotations)") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment