I have a list of coordinates in database, but i would like to load only the coordinates that currently in the view of Google Map and add a marker onto it. How can i do that ?
Once you get latitude and longitude, you can use the following function to add map marker and zoom to marker location :
func showMapMarker() {
self.currentLocationMapView.clear()
DispatchQueue.main.async {
let position = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
let marker = GMSMarker(position: position)
let bounds: GMSCoordinateBounds = GMSCoordinateBounds(coordinate: position, coordinate: position)
marker.title = "Snippet Title"
marker.map = self.currentLocationMapView
marker.snippet = "Snippet Text"
let camera = self.currentLocationMapView.camera(for: bounds, insets: UIEdgeInsets())
self.currentLocationMapView.animate(with: GMSCameraUpdate.fit(bounds, withPadding: 15.0))
self.currentLocationMapView.camera = camera!
}
}
Related
I am getting locations from Firestore and successfully show the marker on particular locations on Google Map but the problem I am facing when I run the app in Simulator it is not animating to the current marker positions. And I don't know how can I draw the route between the markers. Please help?
Here is the code of getting locations from Firestore in swift.
for document in snapshot!.documents {
print(document.data())
let marker = GMSMarker()
self.location.append(Location(trackingData: document.data()))
print(self.location)
let latitude = document.data()["Latitude"] ?? 0
print(latitude)
let longitude = document.data()["longitude"] ?? 0
print(longitude)
marker.position = CLLocationCoordinate2D(latitude: latitude as! CLLocationDegrees , longitude: longitude as! CLLocationDegrees)
marker.map = self.mapView
marker.userData = self.location
marker.icon = UIImage(named: "marker")
print("Data stored in marker \(marker.userData!)")
}
You can achieve this with GMSCoordinateBounds
Reference: https://stackoverflow.com/a/45169325/8447312
Have a bounds object before your for loop:
var bounds = GMSCoordinateBounds()
Then in your for loop you will make each marker's position to be included in bounds object:
var bounds = GMSCoordinateBounds()
for document in snapshot!.documents {
print(document.data())
let marker = GMSMarker()
self.location.append(Location(trackingData: document.data()))
let latitude = document.data()["Latitude"] ?? 0
let longitude = document.data()["longitude"] ?? 0
marker.position = CLLocationCoordinate2D(latitude: latitude as! CLLocationDegrees , longitude: longitude as! CLLocationDegrees)
marker.map = self.mapView
marker.userData = self.location
marker.icon = UIImage(named: "marker")
//include position for each marker
bounds = bounds.includingCoordinate(marker.position)
}
//when your loop is completed you included all your marker's coordinate in your bounds now, you need to animate:
mapView.animate(with: GMSCameraUpdate.fit(bounds, with: UIEdgeInsets(top: 20.0, left: 20.0, bottom: 20.0, right: 20.0)))
I gave 20 insets for each side, you can change it to a value of your desire.
About drawing lines try this:
Create a path right above you create bounds:
let path = GMSMutablePath()
Then in your for loop add each marker's position to this path like you did for bounds:
path.add(marker.position)
At the end before animating your mapView create directions like:
let directions = GMSPolyline(path: path)
directions.strokeWidth = 1.0
directions.map = mapView
Whole code (paths added):
var bounds = GMSCoordinateBounds()
var path = GMSMutablePath()
for document in snapshot!.documents {
print(document.data())
let marker = GMSMarker()
self.location.append(Location(trackingData: document.data()))
let latitude = document.data()["Latitude"] ?? 0
let longitude = document.data()["longitude"] ?? 0
marker.position = CLLocationCoordinate2D(latitude: latitude as! CLLocationDegrees , longitude: longitude as! CLLocationDegrees)
marker.map = self.mapView
marker.userData = self.location
marker.icon = UIImage(named: "marker")
bounds = bounds.includingCoordinate(marker.position)
path.add(marker.position)
}
let directions = GMSPolyline(path: path)
directions.strokeWidth = 1.0
directions.map = mapView
mapView.animate(with: GMSCameraUpdate.fit(bounds, with: UIEdgeInsets(top: 20.0, left: 20.0, bottom: 20.0, right: 20.0)))
I am new to iOS Swift. I recently started working on GMSMaps. In my code I am able to get the latitude and longitude values of source and destination to find the direction and I am also able to add the marker to map. But, I want to change the position of marker based on changing the source and destination values. When I tried to change source/destination ,then again one more marker is adding to maps. I don't want to add one more marker, I just want to move the previous marker to updated location . If any one gives solution it would be so great.
This is my code which I have written to add marker for source and destination. I have written this code in didSelectRowAtIndexPath method of tableView
let centerr = CLLocationCoordinate2D(latitude: lat, longitude: lon)
var camera = GMSCameraPosition.camera(withLatitude: lat, longitude: lon, zoom: 10);
self.googlemapsview.camera = camera
var marker = GMSMarker(position: centerr)
print("Latitude :- \(lat)")
print("Longitude :-\(lon)")
marker.map = self.googlemapsview
Make the marker as global variable and update its coordinates via position property.
var marker: GMSMarker!
Update marker:
let newPosition = CLLocationCoordinate2D(latitude: newLat, longitude: newLon)
marker.position = newPosition
https://developers.google.com/maps/documentation/ios-sdk/reference/interface_g_m_s_marker#a2b9fdae0160d7acf439889ffcdb5f68b
in tableViewDidSelect
let centerr = CLLocationCoordinate2D(latitude: lat, longitude: lon)
var camera = GMSCameraPosition.camera(withLatitude: lat, longitude: lon, zoom: 10);
self.googlemapsview.camera = camera
marker = GMSMarker(position: centerr)
print("Latitude :- \(lat)")
print("Longitude :-\(lon)")
marker.map = self.googlemapsview
I am using google's direction api to get all the Route information. From the response i am passing value of "overview_polyline" to the GMSPath object. Unfortunately it's not showing map . I have applied same logic in previous screen and its loading polyline perfectly. Are my cell's initialized before map loads?
let camera = GMSCameraPosition.camera(withLatitude: searchLocation.coordinate.latitude,
longitude: searchLocation.coordinate.longitude, zoom: 8)
let mapView = GMSMapView.map(withFrame: cell.viaMap.frame, camera: camera)
let center = CLLocationCoordinate2D(latitude: MomentaryLatitude, longitude: MomentaryLongitude)
mapView.isMyLocationEnabled = true
cell.viaMap.addSubview(mapView)
let marker = GMSMarker()
marker.title = "Current Location"
marker.snippet = "XXX"
marker.map = cell.viaMap
let path: GMSPath = GMSPath(fromEncodedPath: myPolyLine)!
let routePolyline = GMSPolyline(path: path)
routePolyline.map = cell.viaMap
routePolyline.strokeWidth = 50
routePolyline.strokeColor = UIColor.red
routePolyline.map = cell.viaMap
var bounds = GMSCoordinateBounds()
let pathInt = Int((path.count()))
for i in 0 ..< pathInt{
bounds = bounds.includingCoordinate(path.coordinate(at: UInt(i)))
}
cell.viaMap.animate(with: GMSCameraUpdate.fit(bounds))
I'm trying to loop through an array with coordinates and show markers on a map with this code:
for index in 0...3 {
let latitude: Double = latCoordinate.objectAtIndex(index) as! Double
let longitude: Double = longCoordinate.objectAtIndex(index) as! Double
let position = CLLocationCoordinate2DMake(latitude, longitude)
print([latitude],[longitude])
let marker = GMSMarker(position: position)
marker.title = "Hello World"
marker.map = self.mapView
}
But I just get one marker on the map, it should be 4. Why can't I see the other markers on the map?
Your code looks good for displaying the marker, but are you sure the coordinates are correct? - Just looked at the comments again and the issue is in how you're populating your array, if you only have one coordinate in your array then you're only going to see one marker on the map.
This code from my app adds all the coordinates to a GMSCoordinateBounds and then sets the GMSMapView camera to the bounds of all the coordinates - so everything should be visible on the displayed map.
func plotAll(){
let bounds = GMSCoordinateBounds.init()
for property in fetchedResultsController.fetchedObjects!
{
let capitalAsset : CapitalAsset = property as! CapitalAsset
let marker = GMSMarker.init()
marker.draggable = false
marker.snippet = capitalAsset.address
let location = CLLocationCoordinate2DMake(Double(capitalAsset.latitude!), Double(capitalAsset.longitude!))
marker.position = location
marker.map = mapView
// Update bounds to include marker
bounds.includingCoordinate(marker.position)
}
let camera = mapView.cameraForBounds(bounds, insets:UIEdgeInsetsZero)
mapView.camera = camera;
}
Hope that helps.
I have a google map with a bunch of coordinates
path.addCoordinate(CLLocationCoordinate2DMake(-37.813047, 144.959911))
path.addCoordinate(CLLocationCoordinate2DMake(-37.814895, 144.960759))
path.addCoordinate(CLLocationCoordinate2DMake(-37.814361, 144.963140))
path.addCoordinate(CLLocationCoordinate2DMake(-37.812386, 144.962239))
I would like the map to be automatically zoomed to the best level based on the points however I can't find anything relating to this.
I have this working:
var vancouver = CLLocationCoordinate2DMake(-37.813047, 144.959911)
var calgary = CLLocationCoordinate2DMake(-37.814361, 144.963140)
var bounds = GMSCoordinateBounds(coordinate: vancouver, coordinate: calgary)
var camera = viewMap.cameraForBounds(bounds, insets:UIEdgeInsetsZero)
viewMap.camera = camera
however it only accepts 2 coordinates where I may have up to 100
Thanks
You can use GMSCoordinateBounds(path:) to fit all coordinates. But it will display a world size scale if you update the camera right after your another update. So you can use dispatch_after to solve the problem.
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.whiteColor();
let camera = GMSCameraPosition.cameraWithLatitude(-37.813047, longitude: -72.8561644, zoom:5)
mapView = GMSMapView.mapWithFrame(CGRectZero, camera:camera)
let marker = GMSMarker()
marker.position = camera.target
marker.snippet = "Hello World"
marker.appearAnimation = kGMSMarkerAnimationPop
marker.map = mapView
self.view = mapView
delay(seconds: 2) { () -> () in
let path = GMSMutablePath()
path.addCoordinate(CLLocationCoordinate2DMake(37.36, -122.0))
path.addCoordinate(CLLocationCoordinate2DMake(37.45, -122.0))
path.addCoordinate(CLLocationCoordinate2DMake(37.45, -122.2))
path.addCoordinate(CLLocationCoordinate2DMake(37.36, -122.2))
path.addCoordinate(CLLocationCoordinate2DMake(37.36, -122.0))
let rectangle = GMSPolyline(path: path)
rectangle.map = self.mapView
let bounds = GMSCoordinateBounds(path: path)
self.mapView!.animateWithCameraUpdate(GMSCameraUpdate.fitBounds(bounds, withPadding: 15.0))
}
}
The delay method uses the dispatch_after:
func delay(#seconds: Double, completion:()->()) {
let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64( Double(NSEC_PER_SEC) * seconds ))
dispatch_after(popTime, dispatch_get_main_queue()) {
completion()
}
}
Iterate through your points. The southwest corner is the minimum latitude and longitude. The northeast corner is the maximum latitude and longitude. Once you have those two points, pass them into your cameraForBounds method.
Try finding an optimal viewing box on google maps by:
-Clicking on the north east corner of the area you think will cover the coordinates in a browser. Note the lat & long.
-Then click the south east corner in the same area which you think will enclose all the coordinates & note the lat & long.
Put the latitudes & longitudes in the respective variables of the below code:
var southWest = CLLocationCoordinate2DMake(latitide,longititude)
var northEast = CLLocationCoordinate2DMake(latitude,longitude)
var bounds = GMSCoordinateBounds(coordinate: northEast, coordinate: southWest)
var camera = mapView.cameraForBounds(bounds, insets:UIEdgeInsetsZero)
mapView.camera = camera;