Skip to content

Instantly share code, notes, and snippets.

@cedricbahirwe
Created September 28, 2023 19:24
Show Gist options
  • Save cedricbahirwe/31a582e0753cec96e4383863d493c33b to your computer and use it in GitHub Desktop.
Save cedricbahirwe/31a582e0753cec96e4383863d493c33b to your computer and use it in GitHub Desktop.
A demo on seats simulations using MapBox
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