Display map or satellite imagery from your app's interface, call out points of interest, and determine placemark information for map coordinates using MapKit.

MapKit Documentation

Posts under MapKit tag

124 Posts
Sort by:
Post not yet marked as solved
1 Replies
58 Views
I added multiple MKPolyline to a MKMapView. It looks fine on the beginning, but when I start zooming, the border of the MKPolyline gets lost on some poly lines. zoomed out: zoomed in: here is the code I used: import MapKit import UIKit class ViewController: UIViewController {     @IBOutlet weak var mapView: MKMapView!     override func viewDidLoad() {         super.viewDidLoad()         mapView.delegate = self         mapView.mapType = .mutedStandard         mapView.pointOfInterestFilter = .excludingAll         let tiles = [             MapTile(x: 8586, y: 5514),             MapTile(x: 8587, y: 5514),             MapTile(x: 8588, y: 5514),             MapTile(x: 8587, y: 5515),         ]         let polygons = tiles.map { tile in             MKPolygon(coordinates: tile.locations, count: tile.locations.count)         }         mapView.addOverlays(polygons, level: .aboveLabels)     } } extension ViewController: MKMapViewDelegate {     func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {         if let mapTile = overlay as? MKPolygon {             let renderer = MKPolygonRenderer(polygon: mapTile)             renderer.fillColor = .systemBlue.withAlphaComponent(0.15)             renderer.strokeColor = .systemBlue             renderer.lineWidth = 0.7             return renderer         }         return MKOverlayRenderer(overlay: overlay)     } } struct MapTile: Identifiable, Hashable {     let x: Int     let y: Int     var id: String { "\(x)-\(y)" }     static let zoomFactor = Double(1 << 14)     static func locationOrigin(tileX: Int, tileY: Int) -> CLLocationCoordinate2D {         let lon = (Double(tileX) / MapTile.zoomFactor) * 360.0 - 180.0         let lat = atan( sinh (.pi - (Double(tileY) / MapTile.zoomFactor) * 2 * Double.pi)) * (180.0 / .pi)         return CLLocationCoordinate2D(latitude: lat, longitude: lon)     }     var locationOrigin: CLLocationCoordinate2D {         MapTile.locationOrigin(tileX: x, tileY: y)     }     var locations: [CLLocationCoordinate2D] {         let topLeft = locationOrigin         let topRight = MapTile.locationOrigin(tileX: x + 1, tileY: y)         let bottomRight = MapTile.locationOrigin(tileX: x + 1, tileY: y + 1)         let bottomLeft = MapTile.locationOrigin(tileX: x, tileY: y + 1)         return [             topLeft,             topRight,             bottomRight,             bottomLeft         ]     } } any ideas why this happens?
Posted
by
Post not yet marked as solved
0 Replies
43 Views
I'm messing about with the new Look Around APIs in iOS 16, and can't seem to find a way to do a few things: Hide the current location label that shows up at the bottom of the Look Around view Go straight into the Look Around view rather than having to tap into it with the button Overlay a view on top of the Look Around view when panning/movement is active (the view seems to take highest priority and I cannot override it) Get it running on MacOS (as an iPad app) struct LookAroundView: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> some UIViewController { let viewController = MKLookAroundViewController() viewController.badgePosition = .topLeading viewController.isNavigationEnabled = true viewController.pointOfInterestFilter = .excludingAll viewController.showsRoadLabels = false viewController.title = "Round 1" let location = CLLocationCoordinate2D( latitude: 37.80770, longitude: -122.47207 ) let sceneRequest = MKLookAroundSceneRequest(coordinate: location) Task { do { viewController.scene = try await sceneRequest.scene } catch { viewController.scene = nil } } return viewController } func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { } }
Posted
by
Post not yet marked as solved
0 Replies
65 Views
I try to develop an indoor map program by IMDF. Before starting, I want to ask, does anyone know the development process? Mainly want to know at which stage the map data needs to be uploaded to the Apple server?(or unnecessary?) I mean, For the conversion between GeoJSON and IMDF, the data only be uploaded to the Apple server for conversion?
Posted
by
Post not yet marked as solved
0 Replies
95 Views
As I currently live in ReactNative Hell, I like to flesh out all my native iOS demos and samples to the max. Including things like accessibility. Recently, I wrote a very simple demo containing a map, and I stumbled upon some issues I was unable to resolve. I think they present very general usecases, and so I would be happy if anyone of you had any idea. The condensed source code for the issues can be found on GitHub Issue 1: The Phantom Overlay To reproduce Run the app on a device, and be sure that VoiceOver is on. Swipe right to get to the Annotations. Expected Result The title of the annotation is read. Actual Result The title of the annotation is read twice. What I know For every annotation on the map view, there is also an overlay, an MKCircle, generated by an MKCircleRenderer. When this overlay is not present, the title is — correctly — only read once. What I have tried In ViewController.swift, lines 54 and 92, I have set both the overlay's and the renderer's isAccessibilityElement property to false. This does not fix the issue (probably because neither of them are the actual views). The overlay should never be an accessible element. Any information should be encoded in the annotation (e.g. "There is a 10m region around this marker") Issue 2: The Unknown Trait While it is correct that the title of the annotation should be read, there is no indication that the annotation can be clicked or interacted with. I have set annotationView.accessibilityTraits = [.button], but this does not change anything. My expectation would be "Cologne Cathedral, Button" or a similar hint that the item is clickable. Issue 3: The Unreachable Callout With VoiceOver active, click on an annotation. I have taken some hints from Stackoverflow, and tried to disable the accessibility on the annotation, and enable it on the callout. This leads to the callout being reachable somehow, but it is absolutely not obvious if you can not see the screen. How can I indicate to the VoiceOver user that now a callout is being shown? A Working Extra: The Annotation Rotor The app also contains a custom rotor, to go through the annotations one by one, without also reading the default Points-Of-Interest on the map. Interestingly (or maybe rather as expected), the title of the annotation is correctly only read once. I whould be extremely happy to get some feedback on these issues, it sounds like most of them could be rather common. Thanks! Alex
Posted
by
Post not yet marked as solved
1 Replies
107 Views
Recently I am working on an AR navigation app. I have tried to use a library call ARCL which is downloaded from Cocoapods. I can plot out a route in AR. However, the route is always jumping around when i am walking. Is there any way that I can make the route be stable and stick on the ground. Hope can someone help me. This is what I have done so far
Posted
by
Post not yet marked as solved
0 Replies
65 Views
Hello everyone, I wanna take user speed in km. How can I take ?
Posted
by
Post not yet marked as solved
0 Replies
130 Views
I'm trying to get a new value on annotationView.center. And it sometimes returns the last location that I have already got. It was working fine before iOS 15.3. But after iOS 15.3 update, it started to be intermittent. Code: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if let annotationView = object as? MKAnnotationView { let position = annotationView.center } }
Posted
by
Post not yet marked as solved
0 Replies
98 Views
I'm working on a navigation app and I would like to snap the userLocation to the MKRoute's Polyline much like how Apple does in Apple Maps. I've added the route's MKPolyline to my MKMapView and it looks great, the user's location is just usually not centered on the road or is off to the side a bit even when using kCLLocationAccuracyBestForNavigation as the CLLocationManager's accuracy. I need it to be centered like Apple Maps as shown bellow. How would I go about doing this? Is there a way to snap MKAnnotation's to roads (or MKPloylines) and update with the CLLocationManager's userLocation?
Posted
by
Post not yet marked as solved
0 Replies
100 Views
When closing the lines of a polygon that is being drawn on the map using MapKit, we observe that the polygon is no longer closing. We didn't have any changes in the application and it stopped working after the iOS version 15.3 update. Until the previous versions it worked normally. if (mainGleba.tamanhoArea != nil && mainGleba.tamanhoArea! > 0) {                             if let areaText = formatter.string(from: mainGleba.tamanhoArea!) {                                 print("Área text: \(areaText)")                                 areaSize = sizeArea as! Double                                 textFieldArea.text = "\(areaText.replacingOccurrences(of: ",", with: ".").formatToLocalCurrency(with: 2)) \.                                                (mainGleba.unidadeMedidaArea!)"                             }                              }else{                                 if let areaText = formatter.string(from: sizeArea) {                                 print("Área text: \(areaText)")                                 areaSize = sizeArea as! Double                                 textFieldArea.text = "\(areaText.replacingOccurrences(of: ",", with: ".").formatToLocalCurrency(with: 2)) \                                                (mainGleba.unidadeMedidaArea!)"                             }                         }                       func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {                                let polygonView = MKPolygonRenderer(overlay: overlay)                                polygonView.strokeColor = Color.white()                                if let _ = overlay as? MKPolygon{                                     polygonView.fillColor = Color.set(Color.white(), alpha: 0.2)                                 }                                if(isAreaEnquadrada){                                      polygonView.strokeColor = Color.blue().withAlphaComponent(0.5)                                      polygonView.fillColor = Color.blue().withAlphaComponent(0.3)                                 }                                 polygonView.lineWidth = 2.0                                 polygonView.lineCap = CGLineCap.****                                 isAreaEnquadrada = false                                   return polygonView                       }
Posted
by
Post marked as solved
2 Replies
128 Views
Dear MapKit Team, For my current project I'd like to include additional custom 3D geometries to a MapView alike 3D landmarks (e.g. London Eye). Think of it as adding 3D stages to a concert area or balloons, etc. Preferably alike annotations with given coordinates and altitudes. So far I haven't seen anything comparable. Is it yet supported? Kind regards, Moritz
Posted
by
Post not yet marked as solved
1 Replies
165 Views
Hi, I have a controller where the user can search for map locations or points of interest by typing inside a search box. To retrieve the list of results I set the queryFragment parameter of a MKLocalSearchCompleter with the search content. This correctly gives me back a list of MKLocalSearchCompletion of locations and points of interest. When a user tap on one of this locations, I need to load the coordinates. In order to do that I do a MKLocalSearch passing the selected MKLocalSearchCompletion, like so: let item = items[indexPath.row] let request = MKLocalSearch.Request(completion: item) let search = MKLocalSearch(request: request) search.start { (response, error) in //Do stuff with the result. //For some specific items I receive an MKErrorDomain 4 error. } This works most of the time, but for some specific items the MKLocalSearch call return the error: Error Domain=MKErrorDomain Code=4 "(null)" UserInfo={MKErrorGEOError=-8} This error correspond to "placemarkNotFound", ie MapKit is not able to find a placemark for the specific MKLocalSearchCompletion. I just don't understant why this should be the case. The MKLocalSearchCompletion is returned by MapKit. If it is returned by MapKit then a corresponding placemark should exist, right? Why then is MapKit unable to perform a local search on it? The problem now is that I present the user with a list of completions returned by MapKit but tapping some of them nothing happens because I cannot determine their respective coordinates. Why is the search failing sometime? I miss something? Thank you
Posted
by
Post not yet marked as solved
0 Replies
130 Views
Hi Apple MapKit team, I am a new iOS developer and recently learned SwiftUI. This WWDC is my first one. I noticed that although Apple is moving towards SwiftUI, the new features released for MapKit is still largely UIKit based. I am not very familiar with UIKit. I wondered that if MapKit team is going to mainly develop in MapKit space instead of the SwiftUI space. Cheers,
Posted
by
Post not yet marked as solved
1 Replies
221 Views
The new ImageRenderer in SwiftUI is really great and should help me to remove some custom code I've had to write in the past. I've noticed that when used to capture a view that contains a map view, the map is replaced with a 'no entry' sign 🚫 Is this intentional? Here's some sample code to replicate the issue: https://gist.github.com/shaundon/282cf7ff276093681a1c246ae318c9d4
Posted
by
Post marked as solved
1 Replies
205 Views
Hi, I want to set the glyphImage property for an annotation view (MKMarkerAnnotationView) of a cluster annotation (MKClusterAnnotation). Using the below code, inside the marker I get, instead of the glyphImage, the standard cluster number. func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { if let cluster = annotation as? MKClusterAnnotation { var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "GroupMapClusterAnnotation") if annotationView == nil { annotationView = MKMarkerAnnotationView(annotation: cluster, reuseIdentifier: "GroupMapClusterAnnotation") } (annotationView as? MKMarkerAnnotationView)?.glyphImage = UIImage(systemName: "star.fill") return annotationView } } I think that the problem is that if you keep the glyphText property empty, MapKit automatically set it with the number of the cluster member annotations. The documentation for glyphImage says: Use this property or the glyphText property to specify the marker balloon content. If you specify both an image and text, MapKit displays the text. So, MapKit is setting glyphText with a value an therefore the glyphImage property is ignored. How can we use the glyphImage property for a cluster annotation? Thank you
Posted
by
Post not yet marked as solved
2 Replies
262 Views
There appears to be an issue with satellite map tile appearing as blank/black when using Mapkit JS on the web. See example from duckduckgo which uses Mapkit JS below (switch to satellite view to see blank tiles):- https://duckduckgo.com/?q=CH44+5UP&t=h_&ia=maps&iaxm=maps I have the same issue when using Mapkit JS. It is only a recent issue but appears widely across the UK (not sure of other countries). Does anyone know, how to raise this as an issue to the Apple Maps or Mapkit JS people (I can't seem to see a support email address or similar)? Thanks in advance.
Posted
by
Post not yet marked as solved
1 Replies
201 Views
I am trying to detect wether two MKOverlays (might be circles or polygons) intersect. Tried using boundingMapRect but it draws a rectangle around my overlay thus giving me inaccurate results. if polygon != nil { intersectionOverlay = polygon! } else { intersectionOverlay = circle! } for overlay: MKOverlay in mapView.overlays { let rect = overlay.boundingMapRect if rect.intersects(intersectionOverlay.boundingMapRect) { print("Intersects \(overlay.title)") } Using that piece of code, would return true for the situation in the images below. Is there any other better way to achieve the desired results? Thanks
Posted
by
Post not yet marked as solved
0 Replies
178 Views
Hi, I need to generate the image of a map at a specific resolution. I tried to use the following code: let options = MKMapSnapshotter.Options() options.size = CGSize(width: 300, height: 200) options.scale = 1.0 options.mapRect = mapRect let mapSnapshotter = MKMapSnapshotter(options: options) if let snapshot = try? await mapSnapshotter.start() { let image = snapshot.image } Since I specified the options.scale to be 1 I expect the image resolution to be exactly 300x200 pixel (and with a scale of 1). Unfortunately the resulting image has a scale factor of 3 (on an iPhone) and the actual resolution is 900x600 pixel. I also tried, instead of using the scale option, to set the traitCollection option, like this: options.traitCollection = UITraitCollection(displayScale: 1.0) but I still get a 3x scale image with a resolution of 900x600. Why is the scale option ignored? I miss something? Thank you
Posted
by
Post not yet marked as solved
2 Replies
201 Views
I am trying to calculate the  latitudeDelta & longitudeDelta of visible map area on the phone screen. The two method used were: spanLat = map.visibleMapRect.size.width / 111000; spanLon = map.visibleMapRect.size.height / (111000 * cos(centreLat*3.14159/180)); And MKMapRect mRect = map.visibleMapRect; MKMapPoint eastMapPoint = MKMapPointMake(MKMapRectGetMinX(mRect), MKMapRectGetMidY(mRect)); MKMapPoint westMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), MKMapRectGetMidY(mRect));     MKMapPoint northMapPoint = MKMapPointMake(MKMapRectGetMinY(mRect), MKMapRectGetMidX(mRect)); MKMapPoint southMapPoint = MKMapPointMake(MKMapRectGetMaxY(mRect), MKMapRectGetMidX(mRect));     CLLocationDistance wLength = MKMetersBetweenMapPoints(eastMapPoint, westMapPoint); CLLocationDistance hLength = MKMetersBetweenMapPoints(northMapPoint, southMapPoint);       spanLat = wLength / 111000;   spanLon = hLength / (111000 * cos(centreLat*3.14159/180)); Neither gives me right  latitudeDelta & longitudeDelta of the visible area.
Posted
by
Post not yet marked as solved
0 Replies
212 Views
Hello everyone, how can I change the standard pin icon to another? And how is it possible when I tap on the pin that an additional popup view opens in which the name of the city is at the top and that the associated image from the PhotoView is displayed? How could I best implement this? Thanks in advance MapView import MapKit import SwiftUI struct City: Identifiable {     let id = UUID()     let name: String     let coordinate: CLLocationCoordinate2D } struct MapView: View {     @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 46.62407, longitude: 8.03434), span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1))          let annotations = [         City(name: "Alte Strasse(Zuhause)", coordinate: CLLocationCoordinate2D(latitude: 46.63649, longitude: 7.97512)),         City(name: "Stalden1", coordinate: CLLocationCoordinate2D(latitude: 46.63937, longitude: 7.97216)),         City(name: "Stalden2", coordinate: CLLocationCoordinate2D(latitude: 46.63873, longitude: 7.96684)),         City(name: "Scheideggstrasse(Wetterhorn)1", coordinate: CLLocationCoordinate2D(latitude: 46.63353, longitude: 8.07356)),         City(name: "Scheideggstrasse(Wetterhorn)2", coordinate: CLLocationCoordinate2D(latitude: 46.63293, longitude: 8.07380)),         City(name: "Scheideggstrasse(Wetterhorn)3", coordinate: CLLocationCoordinate2D(latitude: 46.63313, longitude: 8.07329)),         City(name: "Scheideggstrasse(Wetterhorn)4", coordinate: CLLocationCoordinate2D(latitude: 46.63456, longitude: 8.07337)),         City(name: "Obere Gletscherstrasse(Wetterhorn)", coordinate: CLLocationCoordinate2D(latitude: 46.63205, longitude: 8.07022)),         City(name: "Obere Gletscherstrasse(Hotel Blümlisalp)", coordinate: CLLocationCoordinate2D(latitude: 46.63173, longitude: 8.06699)),         City(name: "Itramenstrasse", coordinate: CLLocationCoordinate2D(latitude: 46.62060, longitude: 7.99514))     ]     var body: some View {         Map(coordinateRegion: $region, annotationItems: annotations) {             MapMarker(coordinate: $0.coordinate)             }         .onAppear {             MKMapView.appearance().mapType = .satellite         }             }     struct MapView_Previews: PreviewProvider {         static var previews: some View {             MapView()         }     } } PhotoView struct ContentView: View {     var images: [String] = ["noaa1", "noaa2", "noaa3", "noaa4", "noaa5", "noaa6", "noaa7", "noaa8", "noaa9", "noaa10", "noaa11", "noaa12", "noaa13", "noaa14", "noaa15", "noaa16", "noaa17", "noaa18"]          var columnGrid: [GridItem] = [GridItem(.fixed(180), spacing: 16), GridItem(.fixed(180), spacing: 16)]              var body: some View {         NavigationView {             ScrollView {                 LazyVGrid(columns: columnGrid, alignment: .center, spacing: 16) {                     ForEach(images, id: \.self) { image in                         NavigationLink (destination: ImageDetail(imageName: image)) {                             Image(image)                                 .resizable()                                 .scaledToFit()                                 .cornerRadius(10)                         }                     }                 }             }.navigationBarTitle(Text("Test"), displayMode: .inline)         }.navigationViewStyle(.stack)     } }
Posted
by