//: A MapKit based Playground import PlaygroundSupport import MapKit private var artworks: [Artwork] = [] class ArtworkMarkerView: MKMarkerAnnotationView { override var annotation: MKAnnotation? { willSet { // 1 guard let artwork = newValue as? Artwork else { return } canShowCallout = true calloutOffset = CGPoint(x: -5, y: 5) //rightCalloutAccessoryView = UIButton(type: // .detailDisclosure) // 2 markerTintColor = artwork.markerTintColor if let letter = artwork.art_type?.first { glyphText = String(letter) } } } } class Artwork: NSObject, MKAnnotation { let title: String? let locationName: String? let art_type: String? let coordinate: CLLocationCoordinate2D var markerTintColor: NSColor { switch art_type { case "Monument": return .red case "Mural": return .cyan case "Plaque": return .blue case "Fountain": return .yellow case "Sculpture": return .purple case "Art": return .magenta default: return .green } } init( title: String?, locationName: String?, art_type: String?, coordinate: CLLocationCoordinate2D ) { self.title = title self.locationName = locationName self.art_type = art_type self.coordinate = coordinate super.init() } init?(feature: MKGeoJSONFeature) { // 1 guard let point = feature.geometry.first as? MKPointAnnotation, let propertiesData = feature.properties, let json = try? JSONSerialization.jsonObject(with: propertiesData), let properties = json as? [String: Any] else { return nil } // 3 title = properties["name"] as? String locationName = properties["descriptio"] as? String art_type = properties["art_type"] as? String coordinate = point.coordinate super.init() } var subtitle: String? { return locationName } } private func loadInitialData() { // 1 guard let fileName = Bundle.main.url(forResource: "PublicArt", withExtension: "geojson"), let artworkData = try? Data(contentsOf: fileName) else { return } do { // 2 let features = try MKGeoJSONDecoder() .decode(artworkData) .compactMap { $0 as? MKGeoJSONFeature } // 3 let validWorks = features.compactMap(Artwork.init) // 4 artworks.append(contentsOf: validWorks) } catch { // 5 print("Unexpected error: \(error).") } } let chatswoodCoordinates = CLLocationCoordinate2DMake(-33.8009948,151.1664372) // Now let's create a MKMapView let mapView = MKMapView(frame: CGRect(x:0, y:0, width:800, height:800)) // Define a region for our map view var mapRegion = MKCoordinateRegion() let mapRegionSpan = 0.001 mapRegion.center = chatswoodCoordinates mapRegion.span.latitudeDelta = mapRegionSpan mapRegion.span.longitudeDelta = mapRegionSpan mapView.setRegion(mapRegion, animated: true) // Create a map annotation let annotation = MKPointAnnotation() annotation.coordinate = chatswoodCoordinates annotation.title = "Chatswood" annotation.subtitle = "Greville" mapView.addAnnotation(annotation) // Show artwork on map let artwork = Artwork( title: "The Cheesetree", locationName: "Santa Clause Lane", art_type: "Nature, like", coordinate: CLLocationCoordinate2D(latitude: -33.8010376, longitude: 151.1663819)) mapView.addAnnotation(artwork) loadInitialData() mapView.addAnnotations(artworks) mapView.register( ArtworkMarkerView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier) // Add the created mapView to our Playground Live View PlaygroundPage.current.liveView = mapView