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

Posts under MapKit tag

200 Posts

Post

Replies

Boosts

Views

Activity

LongPressGesture to add and select Map Pin
Hi there! I am tying to add and select a map pin using view long press when the gesture is begin. However after adding and selecting the pin it got deselected immediately, my assumption that it's conflicting when the original map gesture and it's deselecting the pin on the map (like if a pin was selected and you click anywhere on the map to deselect it). Note that if I increase minimumPressDuration for the UILongPressGestureRecognizer it works fine, but I want the value at 0.5 so the pin is quickly added. here is the full code: import SwiftUI import MapKit struct ContentView: View { @State var selection: CustomMapSelection? @State private var longPressPosition: CGPoint = .zero @State private var pinCoordinate: CLLocationCoordinate2D? var body: some View { MapReader { proxy in Map(selection: $selection) { if let pinCoordinate { Marker("Custom Location", coordinate: pinCoordinate) .tag(CustomMapSelection(coordinate: pinCoordinate)) } } .gesture(LongPressGestureRecognizer(position: $longPressPosition)) .onChange(of: longPressPosition) { if let coordinate = proxy.convert(longPressPosition, from: .global) { pinCoordinate = coordinate selection = CustomMapSelection(coordinate: coordinate) } } } } } struct CustomMapSelection: Hashable { let latitude: Double let longitude: Double init(coordinate: CLLocationCoordinate2D) { latitude = coordinate.latitude longitude = coordinate.longitude } } struct LongPressGestureRecognizer: UIGestureRecognizerRepresentable { @Binding var position: CGPoint func makeCoordinator(converter: CoordinateSpaceConverter) -> Coordinator { Coordinator() } func makeUIGestureRecognizer(context: Context) -> UILongPressGestureRecognizer { let recognizer = UILongPressGestureRecognizer() recognizer.delegate = context.coordinator // if you make the minimumPressDuration above 2, it works fine and the selection doesn't cancel recognizer.minimumPressDuration = 0.5 return recognizer } func handleUIGestureRecognizerAction(_ recognizer: UILongPressGestureRecognizer, context: Context) { if recognizer.state == .began { let position = recognizer.location(in: recognizer.view) self.position = position } } class Coordinator: NSObject, UIGestureRecognizerDelegate { func gestureRecognizer( _ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer ) -> Bool { return true } } } #Preview { ContentView() }
1
0
939
Aug ’24
SwiftUI and MapKit - Find address from coordinates
I've seen a lot of posts around the internet about getting coordinates from an address, but none about how to do the opposite. What I would like to do is allow a person to drop a pin and then programmatically look up the address closest to the pin. Like if I drop a pin inside a mall on the map I would like to capture the address to the mall. Does anyone know how this could be done?
2
0
1.3k
Aug ’24
Is it possible to display a live 3D view of Google Maps in a Vision Pro app?
Hi everyone, I’m exploring the idea of displaying a live 3D view of Google Maps in a Vision Pro app using SwiftUI and RealityKit. I want users to be able to interact with the map, including panning, zooming in and out, and exploring different areas in a fully immersive environment. Is this technically possible within the Vision Pro ecosystem? If so, what would be the recommended approach to implement this? If not, are there any alternative methods or platforms that could provide a similar experience? Thanks in advance for your insights! Best, Siddharth
1
0
1.4k
Aug ’24
Loading large amounts of coordinates and annotations to a map?
My query might return 20,000 coordinates. Does MapKit JS try to load all the coordinates at once into the map or does it only load what’s in the viewport of the map if we were to load 20,000 annotations into the say something like “landmark data” const? We have 900,000 coordinates to load into Los Angeles and are planning how we will do this. Obviously we can’t load 900,000 coordinates at once without performance issues, but some query’s return 20,000 results. Can someone point me to some information about large datasets and MapKit js or let me know if it’s handled and already built in to not try to load that many locations at once?
0
0
654
Aug ’24
In MKMapView, show (some) annotations only when zoomed in
I have a UIKit app with an MKMapview. In that mapview, I show icons on the location of Airfields. When zooming out to Europe (or USA for that matter), the whole map is covered with the annotations, so I want to only show these annotations when zoomed in beyond some level. How can that be achieved? I did find a way like this: class MapViewController: UIViewController { var isAtBigZoom = true { didSet { guard oldValue != isAtBigZoom else { return } for case let annot in mapView.annotations { mapView.view(for: annot)?.alpha = isAtBigZoom ? 1 : 0 } } } } extension MapViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) { isAtBigZoom = mapView.region.span.latitudeDelta < self.airportThreshold } } But I have 2 problems with that: Seems like a lot of processing power It only takes effect after a pan. So I zoom beyond the limit, alpha has the 'old' value. Only after I pan, the alpha is suddenly represented in the MapView. Does anybody know a better solution?
3
0
1.1k
Aug ’24
MKLocalSearch request limit
Hello, It’s unclear to me if there is a limit of requests when using MKLocalSearch from MapKit. Let’s say I have a very large user base and will use 1000 requests per minute at peak times. Will MapKit support this? But if there is a limit, is it by user or by developer account? Also, if there is a limit, is it per day? Here is an example of the request we use. let searchRequest = MKLocalSearch.Request() searchRequest.naturalLanguageQuery = myQueryStringHere localSearch?.cancel() // cancel the previous call if it exists localSearch = MKLocalSearch(request: searchRequest) localSearch?.start { (response, error) in guard error == nil else { completion(.failure(.myError)) return } let mapSearchLocations = response?.mapItems completion(.success(mapSearchLocations)) } }
1
0
574
Aug ’24
SwiftUI Map + Marker + AsyncImage Support
I would like to be able to use AsyncImage inside of a SwiftUI Map Marker like this: Map(position: $cameraPosition) { Marker(coordinate: coord) { AsyncImage(url: url) } } But when I try to do this I get one of two outcomes. The first outcome I've seen is a crash like this: Thread 1: EXC_BAD_ACCESS (code=1, address=0x20) The second possible outcome I've seen is that the image doesn't load but just has a blank placeholder like this: I also tried creating a custom View that takes the url, downloads the data asynchronously, converts the data to a UIImage, sets the UIImage to a @State variable and then uses the Image(uiimage:) SwiftUI view but I got the same results. Has anyone else gotten something like this working?
2
0
685
Aug ’24
MKLocalSearch missing Music Venues from response
I have created an MKLocalSearch request as follows: let reqVenue = MKLocalSearch.Request() reqVenue.naturalLanguageQuery = "Music Venue" reqVenue.resultTypes = .pointOfInterest reqVenue.region = .init(center: mockCoord, latitudinalMeters: 150, longitudinalMeters: 150) I have made sure mockCoord is the exact location coordinate of the example music venue I want to get back in the response. I have noticed that all Music Venues I can find on Apple Maps do not come back as results in MKLocalSearch. I would love an explanation as to why and what I can do to make them appear in MKLocalSearch results please! best, nick
2
0
827
Aug ’24
MKLocalSearch request limit
I'm a bit unsure about whether there’s a limit on the number of requests when using MKLocalSearch from MapKit. For example, if I have a large user base and need to make 200 requests per minute at peak times, will MapKit be able to handle this? Will the user be throttled after a number of requests? If there is a limit, is it based on the user or developer account? Additionally, if there is a limit, is it per day? Can you clarify? Just to give you an idea, here is an example of the request we make: let searchRequest = MKLocalSearch.Request() searchRequest.naturalLanguageQuery = myQueryStringHere localSearch?.cancel() // cancel the previous call if it exists localSearch = MKLocalSearch(request: searchRequest) localSearch?.start { (response, error) in guard error == nil else { completion(.failure(.myError)) return } let mapSearchLocations = response?.mapItems completion(.success(mapSearchLocations)) } } I appreciate your help in advance.
1
0
759
Aug ’24
Showing MKPolygon cause termination of app (iOS 18.0 public beta)
The code worked on previous iOS versions (16 and 17). Recently I updated an iPhone to iOS 18.0 public beta and now the code of presenting a route fails with fatal error: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MKPolygon needsElevationCorrection]: unrecognized selector sent to instance 0x303295cc0' *** First throw call stack: (0x18861f11c 0x18591e698 0x1887247d4 0x1885bc888 0x1885bc1b0 0x191b08f28 0x191b09150 0x1a86bd424 0x1a86be134 0x191a69344 0x1919d68b8 0x1919d4e90 0x1919d5078 0x1919d54b0 0x1919d59a8 0x1919cb31c 0x104655110 0x104497ca9 0x104498309 0x1043e555d 0x1043e9eb9 0x194084689) libc++abi: terminating due to uncaught exception of type NSException The code that works on previous versions: final class MapService: NSObject, MapServiceInterface, ObservableObject { var mapView = MKMapView() override init() { super.init() mapView.delegate = self setup() } func setRoute(coordinates: [CLLocationCoordinate2D]) async { let polyline = MKPolygon(coordinates: coordinates, count: coordinates.count) await mapView.addOverlay(polyline) // fails and terminates app here let edges = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 12.0, right: 10.0) await mapView.setVisibleMapRect( polyline.boundingMapRect, edgePadding: edges, animated: true) } func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { let renderer = MKPolylineRenderer(overlay: overlay) renderer.strokeColor = UIColor(.modernBlue300) renderer.lineWidth = 6 return renderer } } The view: struct MapView: View { @StateObject var viewModel = MapViewModel() var body: some View { Wrapper(view: viewModel.mapService.mapView) } }
1
0
518
Aug ’24
MapKit .standard doesn't allow for globe view when zoomed out
Hi, I'm writing because I've been trying to set the .standard map style to render as a globe on an iPhone 15 running iOS 17 when zoomed out similar to how it works in Apple Maps but can't find any resources on how to make that happen as every time it appears as a flat 2D map, much unlike the .hybrid and .satellite types. I found another thread on this forum a year ago where someone said .standard was bugged and couldn't become a globe, but I'm honestly quite surprised this issue hasn't been brought up more often.
3
2
991
Jul ’24
MKMapview overlay renderding performance issue on iOS16
Hi , I have following scenario where I feel performance issue. Use-case: I have multiple Overlays(MKOverlay) rendered on MapView, and overlay needs to refresh on point Drag(MKPinAnnotation). I have custom logic to handle drag behaviour of annotation, on annotation drag I do update the overlay. As point update, I create new overlay with updated coordinate and re-render it. iT slow down the performance after few overlay added. Additional Notes: Performance was quite good on iOS16 but on iOS17, it lags the perforce on point drag. When I say it the performance, it point drag lags so it slow the overlay rendering. I am using MKMapView inside SwiftUI. I am sharing code-snippet where it re-render the overlay. Please help with issue in my code implementation. func renderSegments(mapView: MKMapView, segmentPoint: FencePointAnnotation, renderNeeded: Bool = true) { mapViewModel.updateFencePointOrder() guard let activeLayer = mapViewModel.activeLayer else { debugPrint("Invalid active layer.") return } let segments = mapViewModel.activeFence.connectedSegmentsOf(vertex: segmentPoint) // Remove existing overlay. for overlay in mapView.overlays { if let overlay = overlay as? FenceOverlay { if overlay.layerId == activeLayer.layerId { mapView.removeOverlay(overlay) } } else if let overlay = overlay as? FenceSegmentPolyline { if overlay.layerId == activeLayer.layerId { for segment in segments.values where segment.identifier == overlay.identifier { mapView.removeOverlay(overlay) } } } } // When vertex removed the no need to add segment if renderNeeded { if let segments = mapViewModel.updatedSegements(segment: segments.map({$0.key})) { let updatedSegments = mapView.updatedSegmentsWithOffset(segments: segments, layer: activeLayer) mapView.addOverlays(updatedSegments) } } }
5
1
975
Jul ’24
Places with MapKit Questions
Hello, I'm very interested in utilizing Place ID with MapKit. Reference: https://developer.apple.com/videos/play/wwdc2024/10097/ I do have some questions I've been unable to find in documentation or within the demo. Apologies in advance if they have been added since. Are place photos included with the call? It appeared so in the demo just want to make sure as I was unable to confirm in the documentation.) Are star ratings included with the Place ID? Reason: Looking for ways to display top/popular POI around a location. How do rate limits work? Can places be cached? (We're looking to keep saved/bookmarked POI cached to avoid pinging MapKit each time the app is used) How often is place data refreshed? For example if a new restaurant opens in town when will it be available to display. Can search provide place results by name (in and out burger) and by type (burgers in LA)? Would we have to pick one way or the other for search to work in this case? Thanks in advance.
3
1
842
Jul ’24
pointOfInterestCategory missing on mapkit js placeLookup
const lookup = new mapkit.PlaceLookup() lookup.getPlace(input?.id, (error, place) => { console.log("place", place) ... gives me for example { "id": "I65A54A72CE9E45D6", "alternateIds": [ "IB86C41DA005E0D9B" ], "muid": "7324342225941186006", "_styleAttributes": "4:226,6:16,10:0,82:12,85:12,89:1,164:1,193:1", "name": "The Museum of Modern Art", "region": { "center": { "latitude": 40.7612829, "longitude": -73.9768677 }, "span": { "latitudeDelta": 0.008983199999995861, "longitudeDelta": 0.01186000000001286 } }, "coordinate": { "latitude": 40.7617238, "longitude": -73.9777654 }, "formattedAddress": "11 W 53rd St, New York, NY 10019, United States", "countryCode": "US", "telephone": "+12127089400", "urls": [ "http://www.moma.org" ], "country": "United States", "administrativeArea": "New York", "administrativeAreaCode": "NY", "locality": "New York", "postCode": "10019", "subLocality": "Manhattan", "thoroughfare": "W 53rd St", "subThoroughfare": "11", "fullThoroughfare": "11 W 53rd St", "areasOfInterest": [ "Manhattan" ], "dependentLocalities": [ "Midtown Center", "Midtown East", "Midtown Manhattan", "Midtown", "North Hudson" ], "timezone": "America/New_York", "timezoneSecondsFromGmt": -14400 } Note there is no pointOfInterestCategory. but const place_search = new mapkit.Search() place_search.search( input, (error, result) => { console.log("result_places_0", result?.places?.[0]) ... i get { "id": "I65A54A72CE9E45D6", "alternateIds": [ "IB86C41DA005E0D9B" ], "muid": "7324342225941186006", "_wpURL": "https://maps.apple.com/place?q=The%20Museum%20of%20Modern%20Art&auid=7324342225941186006&address=11%20W%2053rd%20St,%20New%20York,%20NY%20%2010019,%20United%20States&ll=40.7617238,-73.9777654", "_styleAttributes": "4:226,6:16,10:0,82:12,85:12,89:1,164:1,193:1", "pointOfInterestCategory": "Museum", "name": "The Museum of Modern Art", "region": { "center": { "latitude": 40.7612829, "longitude": -73.9768677 }, "span": { "latitudeDelta": 0.008983199999995861, "longitudeDelta": 0.01186000000001286 } }, "coordinate": { "latitude": 40.7617238, "longitude": -73.9777654 }, "formattedAddress": "11 W 53rd St, New York, NY 10019, United States", "countryCode": "US", "telephone": "+12127089400", "urls": [ "http://www.moma.org" ], "country": "United States", "administrativeArea": "New York", "administrativeAreaCode": "NY", "locality": "New York", "postCode": "10019", "subLocality": "Manhattan", "thoroughfare": "W 53rd St", "subThoroughfare": "11", "fullThoroughfare": "11 W 53rd St", "areasOfInterest": [ "Manhattan" ], "dependentLocalities": [ "Midtown Center", "Midtown East", "Midtown Manhattan", "Midtown", "North Hudson" ], "timezone": "America/New_York", "timezoneSecondsFromGmt": -14400 } which gives me "pointOfInterestCategory": "Museum" I think pointOfInterestCategory should also be returned in the placeLookup and might be a mapkit error that its not it would also be cool if search autocomplete gave me the poi so i could tag the search result previews (mapbox does this). Unrelated from this topic but coming from mapbox where everything had a mapbox_id i feel like some things like localities like "columbus, Ohio" should still have a place id but maybe the muid serves that purpose idk and just something i should account for. Lastly on my mind is how to manage rate limiting since im just giving the same mapbox js token to all the clients. Of course for server api I can manage my own system for rate limiting logged in users a bit easier but not sure about mapkit js though I can only dream my project is big enough i need to even worry about that lol.
1
0
775
Jul ’24
Map behaves differently compared to MKMapView
Hey, I have a problem. I was using MKMapView in my app, and in the view where I had a background at the top of the screen, in the example it was Color.red, it extended all the way to the top of the screen. Now, I wanted to switch to the newer Map and I'm seeing an issue because I'm getting a navigation bar that cuts off my color as I indicated in the picture. Does anyone know why this is happening and if there's another way to achieve this? Steps to reproduce: Change MapView() to Map() to see difference import SwiftUI import MapKit @main struct TestAppApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { var body: some View { NavigationStack { ScrollView(.vertical) { Color.red .padding(.top, -200) .frame(height: 200) MapView().frame(minHeight: 300) // change this line to Map } .navigationTitle("Title") .navigationBarTitleDisplayMode(.large) } } } private typealias ViewControllerRepresentable = UIViewControllerRepresentable struct MapView: ViewControllerRepresentable { typealias ViewController = UIViewController class Controller: ViewController { var mapView: MKMapView { guard let tempView = view as? MKMapView else { fatalError("View could not be cast as MapView.") } return tempView } override func loadView() { let mapView = MKMapView() view = mapView } } func makeUIViewController(context: Context) -> Controller { Controller() } func updateUIViewController(_ controller: Controller, context: Context) { update(controller: controller) } func update(controller: Controller) { } } #Preview { ContentView() } I got: I want:
1
0
730
Jul ’24
mapItemDetailSheet Not Displaying Information
I'm on MacOS 15 Beta and Xcode 16 Beta. Running iOS 18 Beta on a 15 Pro Max. I'm leveraging the .mapItemDetailSheet(item: input) option to pull up a sheet that displays the Place Card for a selection made from a List of places. This is working great on my iPhone 15 Pro Max and my iPad Pro 13. I also have the Mac Catalyst option added under: Project \ General \ Supported Destinations If I launch the app from Xcode via the play button, the app functions fine on my MacBook Pro and I get logs in Xcode, etc. However, if stop the session in Xcode and attempt to run the same app on its own on my MacBook Pro, the mapItemDetailSheet does not populate with any information. Anyone have ideas on where the disconnect could be? Why would the sheet populate with data when ran from Xcode but not when ran on its own? Again, it runs fine on the iPhone and iPad. Any ideas would be helpful and appreciated.
1
0
606
Jul ’24
Flickering after removing MapKit MapPolygons/Polylines
I'm using MapKit for SwiftUI and having an issue when conditionally rendering MapPolygons or MapPolylines. Removing these overlays after a previous render causes them to flicker sporadically in their previous location when a user zooms or moves the camera. The relevant code is as follows: Map(position: $cameraPosition, scope: mapScope) { MapPolygon(coordinates: selectedTileVertices) .stroke( Color(red: 1.0, green: 1.0, blue: 1.0, opacity: isTileSelected ? 1.0 : 0.0), style: StrokeStyle(lineWidth: 5, lineJoin: .round)) .foregroundStyle(selectedTile.color.opacity(0.0)) } A polygon is rendered around a coordinate that a user selects. Upon selecting a new coordinate, a new polygon should render and the old be completely removed from the map. In practice, the new polygon is rendered and the old initially removed, but upon zooming the old polygon flickers in and out of appearance. At some zoom levels the old polygon is completely visible again. The crux of the problem sees to be that I am using .mapStyle(.imagery(elevation: .realistic)). Upon switching to .hybrid all flickering behavior is gone. The flickering becomes worse when doing a lot of zooming/camera movement while the old polygon is rendered and then swapping to a new polygon, and is largely nonexistent if swapping to a new polygon at the same zoom level. I imagine this has something to do with the extra rendering optimizations for satellite imagery. Any help resolving this issue would be appreciated.
1
0
789
Jul ’24
SwiftUI navigate to another view from a popup
when I click on a mapview pin, a PopupView comes up with some text and a button. I want to be able to navigate to another DetailsView by clicking on the button display in the popup, the button is embedded inside NavigationLink. But clicking on the button nothing happens. How to navigate from button click? struct MyMapView: View { @State var position: MapCameraPosition = .automatic @State var showCallout: Bool = false @State var selected: PinAnnotation? @Binding var locationPins: [PinAnnotation] @State private var toggler = false var body: some View { Map(position: $position) { ForEach(locationPins, id: \.self) { result in Annotation(result.title!, coordinate: result.coordinate) { ZStack { Image(systemName: "mappin.circle.fill") .resizable() .scaledToFit() .frame(width: 30, height: 30) .onTapGesture { selected = result toggler.toggle() } .foregroundStyle(.white, .purple) if selected == result && toggler { PopupView(pin: selected) } else { EmptyView() } } } } } } struct PopupView: View { @State var pin: PinAnnotation? @State private var select: Int? = 0 var body: some View { VStack (alignment: .leading) { HStack { if let val = pin { Text(val.text) .font(.system(size: 12, weight: .light, design: .default)) NavigationLink(destination: DetailsView(), label: { Button(action: {select = 1}){ Image(systemName: "play.circle") } .scaledToFit() .frame(width: 50, height: 50) .background(Color.blue) .foregroundColor(.white) .clipShape(Circle()) }) } else { Text("no data") } } // .fixedSize() } .scaledToFit() .foregroundStyle(.purple) .frame(maxWidth: .infinity) .background(Color.white) .cornerRadius(10) .shadow(radius: 5) .offset(x: 0, y: -45) } } struct DetailsView: View { @Environment(\.presentationMode) var presentation var body: some View { Group { Button("Back") { self.presentation.wrappedValue.dismiss() } } } } }
3
0
765
Jul ’24
LongPressGesture to add and select Map Pin
Hi there! I am tying to add and select a map pin using view long press when the gesture is begin. However after adding and selecting the pin it got deselected immediately, my assumption that it's conflicting when the original map gesture and it's deselecting the pin on the map (like if a pin was selected and you click anywhere on the map to deselect it). Note that if I increase minimumPressDuration for the UILongPressGestureRecognizer it works fine, but I want the value at 0.5 so the pin is quickly added. here is the full code: import SwiftUI import MapKit struct ContentView: View { @State var selection: CustomMapSelection? @State private var longPressPosition: CGPoint = .zero @State private var pinCoordinate: CLLocationCoordinate2D? var body: some View { MapReader { proxy in Map(selection: $selection) { if let pinCoordinate { Marker("Custom Location", coordinate: pinCoordinate) .tag(CustomMapSelection(coordinate: pinCoordinate)) } } .gesture(LongPressGestureRecognizer(position: $longPressPosition)) .onChange(of: longPressPosition) { if let coordinate = proxy.convert(longPressPosition, from: .global) { pinCoordinate = coordinate selection = CustomMapSelection(coordinate: coordinate) } } } } } struct CustomMapSelection: Hashable { let latitude: Double let longitude: Double init(coordinate: CLLocationCoordinate2D) { latitude = coordinate.latitude longitude = coordinate.longitude } } struct LongPressGestureRecognizer: UIGestureRecognizerRepresentable { @Binding var position: CGPoint func makeCoordinator(converter: CoordinateSpaceConverter) -> Coordinator { Coordinator() } func makeUIGestureRecognizer(context: Context) -> UILongPressGestureRecognizer { let recognizer = UILongPressGestureRecognizer() recognizer.delegate = context.coordinator // if you make the minimumPressDuration above 2, it works fine and the selection doesn't cancel recognizer.minimumPressDuration = 0.5 return recognizer } func handleUIGestureRecognizerAction(_ recognizer: UILongPressGestureRecognizer, context: Context) { if recognizer.state == .began { let position = recognizer.location(in: recognizer.view) self.position = position } } class Coordinator: NSObject, UIGestureRecognizerDelegate { func gestureRecognizer( _ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer ) -> Bool { return true } } } #Preview { ContentView() }
Replies
1
Boosts
0
Views
939
Activity
Aug ’24
SwiftUI and MapKit - Find address from coordinates
I've seen a lot of posts around the internet about getting coordinates from an address, but none about how to do the opposite. What I would like to do is allow a person to drop a pin and then programmatically look up the address closest to the pin. Like if I drop a pin inside a mall on the map I would like to capture the address to the mall. Does anyone know how this could be done?
Replies
2
Boosts
0
Views
1.3k
Activity
Aug ’24
Is it possible to display a live 3D view of Google Maps in a Vision Pro app?
Hi everyone, I’m exploring the idea of displaying a live 3D view of Google Maps in a Vision Pro app using SwiftUI and RealityKit. I want users to be able to interact with the map, including panning, zooming in and out, and exploring different areas in a fully immersive environment. Is this technically possible within the Vision Pro ecosystem? If so, what would be the recommended approach to implement this? If not, are there any alternative methods or platforms that could provide a similar experience? Thanks in advance for your insights! Best, Siddharth
Replies
1
Boosts
0
Views
1.4k
Activity
Aug ’24
Loading large amounts of coordinates and annotations to a map?
My query might return 20,000 coordinates. Does MapKit JS try to load all the coordinates at once into the map or does it only load what’s in the viewport of the map if we were to load 20,000 annotations into the say something like “landmark data” const? We have 900,000 coordinates to load into Los Angeles and are planning how we will do this. Obviously we can’t load 900,000 coordinates at once without performance issues, but some query’s return 20,000 results. Can someone point me to some information about large datasets and MapKit js or let me know if it’s handled and already built in to not try to load that many locations at once?
Replies
0
Boosts
0
Views
654
Activity
Aug ’24
In MKMapView, show (some) annotations only when zoomed in
I have a UIKit app with an MKMapview. In that mapview, I show icons on the location of Airfields. When zooming out to Europe (or USA for that matter), the whole map is covered with the annotations, so I want to only show these annotations when zoomed in beyond some level. How can that be achieved? I did find a way like this: class MapViewController: UIViewController { var isAtBigZoom = true { didSet { guard oldValue != isAtBigZoom else { return } for case let annot in mapView.annotations { mapView.view(for: annot)?.alpha = isAtBigZoom ? 1 : 0 } } } } extension MapViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) { isAtBigZoom = mapView.region.span.latitudeDelta < self.airportThreshold } } But I have 2 problems with that: Seems like a lot of processing power It only takes effect after a pan. So I zoom beyond the limit, alpha has the 'old' value. Only after I pan, the alpha is suddenly represented in the MapView. Does anybody know a better solution?
Replies
3
Boosts
0
Views
1.1k
Activity
Aug ’24
MKLocalSearch request limit
Hello, It’s unclear to me if there is a limit of requests when using MKLocalSearch from MapKit. Let’s say I have a very large user base and will use 1000 requests per minute at peak times. Will MapKit support this? But if there is a limit, is it by user or by developer account? Also, if there is a limit, is it per day? Here is an example of the request we use. let searchRequest = MKLocalSearch.Request() searchRequest.naturalLanguageQuery = myQueryStringHere localSearch?.cancel() // cancel the previous call if it exists localSearch = MKLocalSearch(request: searchRequest) localSearch?.start { (response, error) in guard error == nil else { completion(.failure(.myError)) return } let mapSearchLocations = response?.mapItems completion(.success(mapSearchLocations)) } }
Replies
1
Boosts
0
Views
574
Activity
Aug ’24
SwiftUI Map + Marker + AsyncImage Support
I would like to be able to use AsyncImage inside of a SwiftUI Map Marker like this: Map(position: $cameraPosition) { Marker(coordinate: coord) { AsyncImage(url: url) } } But when I try to do this I get one of two outcomes. The first outcome I've seen is a crash like this: Thread 1: EXC_BAD_ACCESS (code=1, address=0x20) The second possible outcome I've seen is that the image doesn't load but just has a blank placeholder like this: I also tried creating a custom View that takes the url, downloads the data asynchronously, converts the data to a UIImage, sets the UIImage to a @State variable and then uses the Image(uiimage:) SwiftUI view but I got the same results. Has anyone else gotten something like this working?
Replies
2
Boosts
0
Views
685
Activity
Aug ’24
MKLocalSearch missing Music Venues from response
I have created an MKLocalSearch request as follows: let reqVenue = MKLocalSearch.Request() reqVenue.naturalLanguageQuery = "Music Venue" reqVenue.resultTypes = .pointOfInterest reqVenue.region = .init(center: mockCoord, latitudinalMeters: 150, longitudinalMeters: 150) I have made sure mockCoord is the exact location coordinate of the example music venue I want to get back in the response. I have noticed that all Music Venues I can find on Apple Maps do not come back as results in MKLocalSearch. I would love an explanation as to why and what I can do to make them appear in MKLocalSearch results please! best, nick
Replies
2
Boosts
0
Views
827
Activity
Aug ’24
MKLocalSearch request limit
I'm a bit unsure about whether there’s a limit on the number of requests when using MKLocalSearch from MapKit. For example, if I have a large user base and need to make 200 requests per minute at peak times, will MapKit be able to handle this? Will the user be throttled after a number of requests? If there is a limit, is it based on the user or developer account? Additionally, if there is a limit, is it per day? Can you clarify? Just to give you an idea, here is an example of the request we make: let searchRequest = MKLocalSearch.Request() searchRequest.naturalLanguageQuery = myQueryStringHere localSearch?.cancel() // cancel the previous call if it exists localSearch = MKLocalSearch(request: searchRequest) localSearch?.start { (response, error) in guard error == nil else { completion(.failure(.myError)) return } let mapSearchLocations = response?.mapItems completion(.success(mapSearchLocations)) } } I appreciate your help in advance.
Replies
1
Boosts
0
Views
759
Activity
Aug ’24
Showing MKPolygon cause termination of app (iOS 18.0 public beta)
The code worked on previous iOS versions (16 and 17). Recently I updated an iPhone to iOS 18.0 public beta and now the code of presenting a route fails with fatal error: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MKPolygon needsElevationCorrection]: unrecognized selector sent to instance 0x303295cc0' *** First throw call stack: (0x18861f11c 0x18591e698 0x1887247d4 0x1885bc888 0x1885bc1b0 0x191b08f28 0x191b09150 0x1a86bd424 0x1a86be134 0x191a69344 0x1919d68b8 0x1919d4e90 0x1919d5078 0x1919d54b0 0x1919d59a8 0x1919cb31c 0x104655110 0x104497ca9 0x104498309 0x1043e555d 0x1043e9eb9 0x194084689) libc++abi: terminating due to uncaught exception of type NSException The code that works on previous versions: final class MapService: NSObject, MapServiceInterface, ObservableObject { var mapView = MKMapView() override init() { super.init() mapView.delegate = self setup() } func setRoute(coordinates: [CLLocationCoordinate2D]) async { let polyline = MKPolygon(coordinates: coordinates, count: coordinates.count) await mapView.addOverlay(polyline) // fails and terminates app here let edges = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 12.0, right: 10.0) await mapView.setVisibleMapRect( polyline.boundingMapRect, edgePadding: edges, animated: true) } func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { let renderer = MKPolylineRenderer(overlay: overlay) renderer.strokeColor = UIColor(.modernBlue300) renderer.lineWidth = 6 return renderer } } The view: struct MapView: View { @StateObject var viewModel = MapViewModel() var body: some View { Wrapper(view: viewModel.mapService.mapView) } }
Replies
1
Boosts
0
Views
518
Activity
Aug ’24
MapKit .standard doesn't allow for globe view when zoomed out
Hi, I'm writing because I've been trying to set the .standard map style to render as a globe on an iPhone 15 running iOS 17 when zoomed out similar to how it works in Apple Maps but can't find any resources on how to make that happen as every time it appears as a flat 2D map, much unlike the .hybrid and .satellite types. I found another thread on this forum a year ago where someone said .standard was bugged and couldn't become a globe, but I'm honestly quite surprised this issue hasn't been brought up more often.
Replies
3
Boosts
2
Views
991
Activity
Jul ’24
MKMapview overlay renderding performance issue on iOS16
Hi , I have following scenario where I feel performance issue. Use-case: I have multiple Overlays(MKOverlay) rendered on MapView, and overlay needs to refresh on point Drag(MKPinAnnotation). I have custom logic to handle drag behaviour of annotation, on annotation drag I do update the overlay. As point update, I create new overlay with updated coordinate and re-render it. iT slow down the performance after few overlay added. Additional Notes: Performance was quite good on iOS16 but on iOS17, it lags the perforce on point drag. When I say it the performance, it point drag lags so it slow the overlay rendering. I am using MKMapView inside SwiftUI. I am sharing code-snippet where it re-render the overlay. Please help with issue in my code implementation. func renderSegments(mapView: MKMapView, segmentPoint: FencePointAnnotation, renderNeeded: Bool = true) { mapViewModel.updateFencePointOrder() guard let activeLayer = mapViewModel.activeLayer else { debugPrint("Invalid active layer.") return } let segments = mapViewModel.activeFence.connectedSegmentsOf(vertex: segmentPoint) // Remove existing overlay. for overlay in mapView.overlays { if let overlay = overlay as? FenceOverlay { if overlay.layerId == activeLayer.layerId { mapView.removeOverlay(overlay) } } else if let overlay = overlay as? FenceSegmentPolyline { if overlay.layerId == activeLayer.layerId { for segment in segments.values where segment.identifier == overlay.identifier { mapView.removeOverlay(overlay) } } } } // When vertex removed the no need to add segment if renderNeeded { if let segments = mapViewModel.updatedSegements(segment: segments.map({$0.key})) { let updatedSegments = mapView.updatedSegmentsWithOffset(segments: segments, layer: activeLayer) mapView.addOverlays(updatedSegments) } } }
Replies
5
Boosts
1
Views
975
Activity
Jul ’24
polyline error
Hi I save a track and I get an error the last point isn't the user location by adding the point to core data. Is core data to slow? can you help me? greeting Fabain
Replies
1
Boosts
0
Views
576
Activity
Jul ’24
Places with MapKit Questions
Hello, I'm very interested in utilizing Place ID with MapKit. Reference: https://developer.apple.com/videos/play/wwdc2024/10097/ I do have some questions I've been unable to find in documentation or within the demo. Apologies in advance if they have been added since. Are place photos included with the call? It appeared so in the demo just want to make sure as I was unable to confirm in the documentation.) Are star ratings included with the Place ID? Reason: Looking for ways to display top/popular POI around a location. How do rate limits work? Can places be cached? (We're looking to keep saved/bookmarked POI cached to avoid pinging MapKit each time the app is used) How often is place data refreshed? For example if a new restaurant opens in town when will it be available to display. Can search provide place results by name (in and out burger) and by type (burgers in LA)? Would we have to pick one way or the other for search to work in this case? Thanks in advance.
Replies
3
Boosts
1
Views
842
Activity
Jul ’24
pointOfInterestCategory missing on mapkit js placeLookup
const lookup = new mapkit.PlaceLookup() lookup.getPlace(input?.id, (error, place) => { console.log("place", place) ... gives me for example { "id": "I65A54A72CE9E45D6", "alternateIds": [ "IB86C41DA005E0D9B" ], "muid": "7324342225941186006", "_styleAttributes": "4:226,6:16,10:0,82:12,85:12,89:1,164:1,193:1", "name": "The Museum of Modern Art", "region": { "center": { "latitude": 40.7612829, "longitude": -73.9768677 }, "span": { "latitudeDelta": 0.008983199999995861, "longitudeDelta": 0.01186000000001286 } }, "coordinate": { "latitude": 40.7617238, "longitude": -73.9777654 }, "formattedAddress": "11 W 53rd St, New York, NY 10019, United States", "countryCode": "US", "telephone": "+12127089400", "urls": [ "http://www.moma.org" ], "country": "United States", "administrativeArea": "New York", "administrativeAreaCode": "NY", "locality": "New York", "postCode": "10019", "subLocality": "Manhattan", "thoroughfare": "W 53rd St", "subThoroughfare": "11", "fullThoroughfare": "11 W 53rd St", "areasOfInterest": [ "Manhattan" ], "dependentLocalities": [ "Midtown Center", "Midtown East", "Midtown Manhattan", "Midtown", "North Hudson" ], "timezone": "America/New_York", "timezoneSecondsFromGmt": -14400 } Note there is no pointOfInterestCategory. but const place_search = new mapkit.Search() place_search.search( input, (error, result) => { console.log("result_places_0", result?.places?.[0]) ... i get { "id": "I65A54A72CE9E45D6", "alternateIds": [ "IB86C41DA005E0D9B" ], "muid": "7324342225941186006", "_wpURL": "https://maps.apple.com/place?q=The%20Museum%20of%20Modern%20Art&auid=7324342225941186006&address=11%20W%2053rd%20St,%20New%20York,%20NY%20%2010019,%20United%20States&ll=40.7617238,-73.9777654", "_styleAttributes": "4:226,6:16,10:0,82:12,85:12,89:1,164:1,193:1", "pointOfInterestCategory": "Museum", "name": "The Museum of Modern Art", "region": { "center": { "latitude": 40.7612829, "longitude": -73.9768677 }, "span": { "latitudeDelta": 0.008983199999995861, "longitudeDelta": 0.01186000000001286 } }, "coordinate": { "latitude": 40.7617238, "longitude": -73.9777654 }, "formattedAddress": "11 W 53rd St, New York, NY 10019, United States", "countryCode": "US", "telephone": "+12127089400", "urls": [ "http://www.moma.org" ], "country": "United States", "administrativeArea": "New York", "administrativeAreaCode": "NY", "locality": "New York", "postCode": "10019", "subLocality": "Manhattan", "thoroughfare": "W 53rd St", "subThoroughfare": "11", "fullThoroughfare": "11 W 53rd St", "areasOfInterest": [ "Manhattan" ], "dependentLocalities": [ "Midtown Center", "Midtown East", "Midtown Manhattan", "Midtown", "North Hudson" ], "timezone": "America/New_York", "timezoneSecondsFromGmt": -14400 } which gives me "pointOfInterestCategory": "Museum" I think pointOfInterestCategory should also be returned in the placeLookup and might be a mapkit error that its not it would also be cool if search autocomplete gave me the poi so i could tag the search result previews (mapbox does this). Unrelated from this topic but coming from mapbox where everything had a mapbox_id i feel like some things like localities like "columbus, Ohio" should still have a place id but maybe the muid serves that purpose idk and just something i should account for. Lastly on my mind is how to manage rate limiting since im just giving the same mapbox js token to all the clients. Of course for server api I can manage my own system for rate limiting logged in users a bit easier but not sure about mapkit js though I can only dream my project is big enough i need to even worry about that lol.
Replies
1
Boosts
0
Views
775
Activity
Jul ’24
Map behaves differently compared to MKMapView
Hey, I have a problem. I was using MKMapView in my app, and in the view where I had a background at the top of the screen, in the example it was Color.red, it extended all the way to the top of the screen. Now, I wanted to switch to the newer Map and I'm seeing an issue because I'm getting a navigation bar that cuts off my color as I indicated in the picture. Does anyone know why this is happening and if there's another way to achieve this? Steps to reproduce: Change MapView() to Map() to see difference import SwiftUI import MapKit @main struct TestAppApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { var body: some View { NavigationStack { ScrollView(.vertical) { Color.red .padding(.top, -200) .frame(height: 200) MapView().frame(minHeight: 300) // change this line to Map } .navigationTitle("Title") .navigationBarTitleDisplayMode(.large) } } } private typealias ViewControllerRepresentable = UIViewControllerRepresentable struct MapView: ViewControllerRepresentable { typealias ViewController = UIViewController class Controller: ViewController { var mapView: MKMapView { guard let tempView = view as? MKMapView else { fatalError("View could not be cast as MapView.") } return tempView } override func loadView() { let mapView = MKMapView() view = mapView } } func makeUIViewController(context: Context) -> Controller { Controller() } func updateUIViewController(_ controller: Controller, context: Context) { update(controller: controller) } func update(controller: Controller) { } } #Preview { ContentView() } I got: I want:
Replies
1
Boosts
0
Views
730
Activity
Jul ’24
mapItemDetailSheet Not Displaying Information
I'm on MacOS 15 Beta and Xcode 16 Beta. Running iOS 18 Beta on a 15 Pro Max. I'm leveraging the .mapItemDetailSheet(item: input) option to pull up a sheet that displays the Place Card for a selection made from a List of places. This is working great on my iPhone 15 Pro Max and my iPad Pro 13. I also have the Mac Catalyst option added under: Project \ General \ Supported Destinations If I launch the app from Xcode via the play button, the app functions fine on my MacBook Pro and I get logs in Xcode, etc. However, if stop the session in Xcode and attempt to run the same app on its own on my MacBook Pro, the mapItemDetailSheet does not populate with any information. Anyone have ideas on where the disconnect could be? Why would the sheet populate with data when ran from Xcode but not when ran on its own? Again, it runs fine on the iPhone and iPad. Any ideas would be helpful and appreciated.
Replies
1
Boosts
0
Views
606
Activity
Jul ’24
Flickering after removing MapKit MapPolygons/Polylines
I'm using MapKit for SwiftUI and having an issue when conditionally rendering MapPolygons or MapPolylines. Removing these overlays after a previous render causes them to flicker sporadically in their previous location when a user zooms or moves the camera. The relevant code is as follows: Map(position: $cameraPosition, scope: mapScope) { MapPolygon(coordinates: selectedTileVertices) .stroke( Color(red: 1.0, green: 1.0, blue: 1.0, opacity: isTileSelected ? 1.0 : 0.0), style: StrokeStyle(lineWidth: 5, lineJoin: .round)) .foregroundStyle(selectedTile.color.opacity(0.0)) } A polygon is rendered around a coordinate that a user selects. Upon selecting a new coordinate, a new polygon should render and the old be completely removed from the map. In practice, the new polygon is rendered and the old initially removed, but upon zooming the old polygon flickers in and out of appearance. At some zoom levels the old polygon is completely visible again. The crux of the problem sees to be that I am using .mapStyle(.imagery(elevation: .realistic)). Upon switching to .hybrid all flickering behavior is gone. The flickering becomes worse when doing a lot of zooming/camera movement while the old polygon is rendered and then swapping to a new polygon, and is largely nonexistent if swapping to a new polygon at the same zoom level. I imagine this has something to do with the extra rendering optimizations for satellite imagery. Any help resolving this issue would be appreciated.
Replies
1
Boosts
0
Views
789
Activity
Jul ’24
Display the real 3D map through model3d
In the apple map of some areas, there will be a very realistic real-life 3D map. And now I want to call it through 3d in visionOS (like model3d). How can I call it? Note: What I ask for is not to have an effect similar to 3d on a flat screen like in iOS, but to display the USDZ model in visionOS.
Replies
1
Boosts
0
Views
876
Activity
Jul ’24
SwiftUI navigate to another view from a popup
when I click on a mapview pin, a PopupView comes up with some text and a button. I want to be able to navigate to another DetailsView by clicking on the button display in the popup, the button is embedded inside NavigationLink. But clicking on the button nothing happens. How to navigate from button click? struct MyMapView: View { @State var position: MapCameraPosition = .automatic @State var showCallout: Bool = false @State var selected: PinAnnotation? @Binding var locationPins: [PinAnnotation] @State private var toggler = false var body: some View { Map(position: $position) { ForEach(locationPins, id: \.self) { result in Annotation(result.title!, coordinate: result.coordinate) { ZStack { Image(systemName: "mappin.circle.fill") .resizable() .scaledToFit() .frame(width: 30, height: 30) .onTapGesture { selected = result toggler.toggle() } .foregroundStyle(.white, .purple) if selected == result && toggler { PopupView(pin: selected) } else { EmptyView() } } } } } } struct PopupView: View { @State var pin: PinAnnotation? @State private var select: Int? = 0 var body: some View { VStack (alignment: .leading) { HStack { if let val = pin { Text(val.text) .font(.system(size: 12, weight: .light, design: .default)) NavigationLink(destination: DetailsView(), label: { Button(action: {select = 1}){ Image(systemName: "play.circle") } .scaledToFit() .frame(width: 50, height: 50) .background(Color.blue) .foregroundColor(.white) .clipShape(Circle()) }) } else { Text("no data") } } // .fixedSize() } .scaledToFit() .foregroundStyle(.purple) .frame(maxWidth: .infinity) .background(Color.white) .cornerRadius(10) .shadow(radius: 5) .offset(x: 0, y: -45) } } struct DetailsView: View { @Environment(\.presentationMode) var presentation var body: some View { Group { Button("Back") { self.presentation.wrappedValue.dismiss() } } } } }
Replies
3
Boosts
0
Views
765
Activity
Jul ’24