We have an app where we drop some pins on a map.
So it loads to ar perfectly but it always shows on the screen even though I am way away from that pin location. That pin does not stay at a specific point.
Do you have any idea how to place a pin at a specific location and does not show away from that location
var location = CLLocation(coordinate: CLLocationCoordinate2D(latitude: 28.610497, longitude: 77.360733), altitude: 0) // ISKPRO
let image = UIImage(named: "LocationPin")!
var annotationNode = LocationAnnotationNode(location: location, image: image)
annotationNode.annotationNode.name = "ISKPRO"
sceneLocationView.addLocationNodeWithConfirmedLocation(locationNode: annotationNode)
VStack {
Map(coordinateRegion: $manager.Region,interactionModes: .all,showsUserLocation: true, userTrackingMode: $trackMode,annotationItems: manager.CampingArray){ area in
MapAnnotation(coordinate: CLLocationCoordinate2D(latitude: area.lat, longitude: area.lon) ) {
Button {
manager.selectedArea = area
showDetail.toggle()
} label: {
CampMarker(CampAreaName: area.name)
}
}
}.onAppear(){
manager.fit()
manager.checkManager()
}
}
.ignoresSafeArea()
This is part of my code;
as you can see I give the camping pins with "annotationItems"
also you can watch this video this video will help you.
Related
What I'm attempting to do is run fitbounds on a set of markers, which works perfectly. However, I would like to center the map based on the user's location while keeping all markers within the map view. But I haven't found a solution. Is it possible? below is my code currently use to fit bounds.
func focusMapToShowAllMarkers() {
var bounds = GMSCoordinateBounds()
for location in locationsArray
{
let latitude = location.position.latitude
let longitude = location.position.longitude
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude:latitude, longitude:longitude)
//marker.map = self.viewMap
bounds = bounds.includingCoordinate(marker.position)
}
//bounds = bounds.includingCoordinate(CLLocationCoordinate2D(latitude:latitude, longitude:longitude))
let update = GMSCameraUpdate.fit(bounds, withPadding: 10)
viewMap.animate(with:update)
}
I'm pretty new to Swift/iOS app dev. so far, so I'm struggling to figure this out. Basically, I'm trying to make it so when the app opens (first screen is the map), it automatically finds nearby places that are only parks around the user's current location and have these locations annotated with markers on a map (Google Maps) using Google Places API for iOS using updated SwiftUI/Swift 5.0: Using no storyboards!. Table I types, in this case, parks: https://developers.google.com/places/web-service/supported_types
So far, this is the code I have... It uses GMSPlaceLikelihood of places nearby the user's location. This is more so an example of what I want to achieve, however using Google Places API nearby search instead so I can show only parks. Image of app running:
Image
(The place's found from nearby are then listed in a table as shown on the image. This list is just for show)
Thanks in advance for any advice/help.
GoogleMapsView.swift:
#ObservedObject var locationManager = LocationManager()
#ObservedObject var place = PlacesManager()
func makeUIView(context: Self.Context) -> GMSMapView {
let camera = GMSCameraPosition.camera(withLatitude: locationManager.latitude, longitude: locationManager.longitude, zoom: 14)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
mapView.isMyLocationEnabled = true
mapView.settings.rotateGestures = false
mapView.settings.tiltGestures = false
mapView.isIndoorEnabled = false
mapView.isTrafficEnabled = false
mapView.isBuildingsEnabled = false
mapView.settings.myLocationButton = true
place.currentPlacesList(completion: { placeLikelihoodList in
if let placeLikelihoodList = placeLikelihoodList {
print("total places: \(placeLikelihoodList.count)")
for likelihood in placeLikelihoodList {
let place = likelihood.place
let position = CLLocationCoordinate2D(latitude: place.coordinate.latitude, longitude: place.coordinate.longitude)
let marker = GMSMarker(position: position)
marker.title = place.name
marker.map = mapView
}
}
})
return mapView
}
func updateUIView(_ mapView: GMSMapView, context: Context) {
// let camera = GMSCameraPosition.camera(withLatitude: locationManager.latitude, longitude: locationManager.longitude, zoom: zoom)
// mapView.camera = camera
mapView.animate(toLocation: CLLocationCoordinate2D(latitude: locationManager.latitude, longitude: locationManager.longitude))
}
PlacesManager.swift:
class PlacesManager: NSObject, ObservableObject {
private var placesClient = GMSPlacesClient.shared()
#Published var places = [GMSPlaceLikelihood]()
override init() {
super.init()
currentPlacesList { (places) in
guard let places = places else {
return
}
self.places = places
}
}
func currentPlacesList(completion: #escaping (([GMSPlaceLikelihood]?) -> Void)) {
// Specify the place data types to return.
let fields: GMSPlaceField = GMSPlaceField(rawValue: UInt(GMSPlaceField.name.rawValue) |
UInt(GMSPlaceField.placeID.rawValue) | UInt(GMSPlaceField.types.rawValue) | UInt(GMSPlaceField.coordinate.rawValue))!
placesClient.findPlaceLikelihoodsFromCurrentLocation(withPlaceFields: fields, callback: {
(placeLikelihoodList: Array<GMSPlaceLikelihood>?, error: Error?) in
if let error = error {
print("An error occurred: \(error.localizedDescription)")
return
}
if let placeLikelihoodList = placeLikelihoodList {
for likelihood in placeLikelihoodList {
let place = likelihood.place
}
completion(placeLikelihoodList)
}
})
}
ContentView.swift:
var body: some View {
VStack {
GoogleMapsView()
.edgesIgnoringSafeArea(.top)
.frame(height: 400)
PlacesList()
}
.offset(y: 100)
}
https://developers.google.com/places/web-service/search
I suggest you visit this page, it describes the API in detail and shows examples how to call it with different parameters.
After you get the response (I suggest getting it in json format and using SwiftyJSON cocoa pod to parse it) populate the table.
I was wondering if was possible to check if a marker is outside of the region.
I can check if the user left the region, but I want to also check if any marker on the map to the same thing as well, I want to check the geofence region between to markers.
func setUpGeofence() {
let geofenceRegionCenter = CLLocationCoordinate2DMake(getLatitude(),getLongitude());
let geofenceRegion = CLCircularRegion(center: geofenceRegionCenter, radius: 400, identifier: "Geofence");
geofenceRegion.notifyOnExit = true;
geofenceRegion.notifyOnEntry = true;
self.locationManager.startMonitoring(for: geofenceRegion)
}
}
You can use CLLocation.distance(from:) to calculate each marker's distance from your geofence center.
let center = CLLocation(latitude: getLatitude(), longitude: getLongitude())
for marker in markers {
if marker.location.distance(from: center) > radius {
// outside
} else {
// inside
}
}
I'm adding markers with the titles to the map using below code.
func showAllMarker(){
loadLocatons(){
completion in
if completion {
super.hideLoading()
self.mapView.clear()
self.circle(withRadius: self.Defradius, circleCenter: self.myLocation2D)
for point in self.mobLocationData {
if point.status == ConstantValues.activeStatus{
let marker = GMSMarker()
let latitude = point.latitude
let longitude = point.longitude
let position = CLLocationCoordinate2D(latitude: NSString(string: latitude!).doubleValue, longitude: NSString(string: longitude!).doubleValue)
marker.position = position
marker.title = point.description
marker.userData = LocationMarkerData(id: point.id!, address: point.address!)
marker.map = self.mapView
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: {
let camera = GMSCameraPosition.camera(withLatitude: self.myLocation.coordinate.latitude, longitude: self.myLocation.coordinate.longitude, zoom: 10.5,bearing: 350,viewingAngle: 10)
CATransaction.begin()
CATransaction.setValue(1.5, forKey: kCATransactionAnimationDuration)
self.mapView.animate(to: camera)
CATransaction.commit()
})
}
}
}
Some times when tapped on the marker doesn't show the full title. It truncates the title. See below image.
In the google maps docs it says that only the very long messages may be truncated.
Strings that are longer than the width of the info window are
automatically wrapped over several lines. Very long messages may be
truncated.
But the title of the above marker in the image is "test". So it is not a very long title. Also there are some other markers which have more longer titles than this and they are not getting truncated. See below image
So could someone explain me what I'm doing wrong and how to correct this?
Just make the first letter of your word Capital case like this:
let outlet_name = "\(DataDict["routeName"] ?? "")".lowercased()
marker.title = outlet_name.capitalizingFirstLetter()
This magically worked for me.
I'm a newbie in iOS development. I want to create a custom button with the same functionality as the default button (myLocationButton) in Google Maps SDK for iOS. Can I do that?
I can create the button but I don't know how to add action to track my current location and show the marker in the center of the screen. I'm using Swift 3.
Any help would be appreciated!
You could implement the action like so:
func gotoMyLocationAction(sender: UIButton)
{
guard let lat = self.mapView.myLocation?.coordinate.latitude,
let lng = self.mapView.myLocation?.coordinate.longitude else { return }
let camera = GMSCameraPosition.camera(withLatitude: lat ,longitude: lng , zoom: zoom)
self.mapView.animate(to: camera)
}
This center your map to your current position if they exists. Hope that helps.
Be sure the position detection on your GMSMapView is enabled
self.mapView.isMyLocationEnabled = true
Update Swift 4 for #Thomas answer, with GoogleMapSDK 2.7.0
func didTapMyLocationButton(for mapView: GMSMapView) -> Bool {
guard let lat = googleMapView.myLocation?.coordinate.latitude,
let lng = googleMapView.myLocation?.coordinate.longitude else { return false }
let camera = GMSCameraPosition.camera(withLatitude: lat ,longitude: lng , zoom: userMapZoom)
googleMapView.animate(to: camera)
return true
}