How can I include all the coordinates in the MapBox by adjusting the zoom level? - annotations

The code I have used is:
let bounds = MGLCoordinateBounds(
sw: CLLocationCoordinate2D(latitude: 40.7115, longitude: 10.3725),
ne: CLLocationCoordinate2D(latitude: 40.7318, longitude: 10.4222))
mapView.setVisibleCoordinateBounds(bounds, animated: false)
I have 3 annotation and I want to see the 3 annotaion in the mapBox by adjusting the zoom level. Please help me to find it out.

There is method on MGLMapView that you can use:
func showAllAnnotations() {
guard let annotations = mapView.annotations else { return }
// Either this...
mapView.showAnnotations(annotations, edgePadding: UIEdgeInsets(top: 40, left: 35, bottom: 35, right: 35), animated: true)
// or this.
mapView.showAnnotations(annotations, animated: true)
}

Related

Creating own marker with iconView on Google Maps

I created my own marker with iconView for showing my own position. As you can see it is the green one. But every time I move the screen it is reloading my green view and it seems lagging. I don't have the same problem with the other marker shown, which are simple png.
How can I solve that? I can solve that problem by removing the line mapView.clear() But the result is that every loaded marker don't go away if I zoom out. So the map gets more and more crowded.
func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
mapView.clear()
let fullCordinate = "\(mapView.camera.target.latitude),\(mapView.camera.target.longitude)"
networkGoogleApiConnect.fetchPoi(geoCordinate: fullCordinate)
networkGoogleApi.testVariable.forEach {
let marker1 = GMSMarker()
marker1.position = CLLocationCoordinate2D(latitude: $0.position.lat, longitude: $0.position.lng)
marker1.title = $0.title
marker1.icon = UIImage(named: "house")
var dict = [String:String]()
dict["id"] = $0.id
marker1.userData = dict
marker1.map = mapView
locationManager.stopUpdatingLocation()
}
locationManager.delegate=self
let neuLongitudeEigenerStandort = locationManager.location!.coordinate.longitude
let neuLatitudeEigenerStandort = locationManager.location!.coordinate.latitude
let fullCordinateEigenerStandort = "\(neuLatitudeEigenerStandort),\(neuLongitudeEigenerStandort)"
let ownMarker = GMSMarker()
ownMarker.iconView = UIView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
ownMarker.iconView?.backgroundColor = .green
ownMarker.position = CLLocationCoordinate2D(latitude: neuLatitudeEigenerStandort, longitude: neuLongitudeEigenerStandort)
ownMarker.title = "Eigene Position"
ownMarker.snippet = "GPS"
ownMarker.icon = GMSMarker.markerImage(with: .blue)
ownMarker.map = mapView
}

MKMapView (MapKit) - Trying to zoom out to see the entire globe

Edit: I found a solution. MKMapView won't show the entire globe if you build it in Xcode's simulator, but it will if you build it on an actual device.
Existing versions of the question haven't worked - Need Swift 4, Xcode 10 solution:
I'm trying to zoom an MKMapView out to show the entire globe in my app. I can zoom out to see a map of the whole world, but not the entire globe.
​
Here's what I know:
-It has to be satellite, hybrid, satelliteFlyover, or hybridFlyover
-3D must be enabled.
​
Here is what I've tried:
-Adjusting the span of the region (no matter how big I make the span, it never zooms out enough to see the globe)
-Adjusting the altitude of the camera (no matter how high I make it, it never zooms out enough to see the globe)
​
I have googled and stack-overflowed, and I can't find any solutions that work. I am reduced to posting this question myself, violating my lurker principals, but I am totally stuck.
Here is some code I've tried from tutorials, etc. (several attempts commented out):
import UIKit
import MapKit
class ViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
mapView.mapType = .standard
mapView.isPitchEnabled = true
// mapView.showsBuildings = true // displays buildings
let eiffelTowerCoordinates = CLLocationCoordinate2DMake(48.85815, 2.29452)
mapView.region = MKCoordinateRegion(center: eiffelTowerCoordinates, latitudinalMeters: 1000, longitudinalMeters: 100) // sets the visible region of the map
// create a 3D Camera
let mapCamera = MKMapCamera()
mapCamera.centerCoordinate = eiffelTowerCoordinates
mapCamera.pitch = 45
mapCamera.altitude = 50000000 // example altitude
mapCamera.heading = 45
// set the camera property
mapView.camera = mapCamera
// var ausCenter = CLLocationCoordinate2D(latitude: -25.354917, longitude: 134.347407)
// let camera = MKMapCamera(lookingAtCenter: ausCenter, fromDistance: 300, pitch: 10, heading: 0)
// mapView.camera = camera
// var ausCenter = CLLocationCoordinate2D(latitude: -25.354917, longitude: 134.347407)
// var ausSpan = MKCoordinateSpan(latitudeDelta: 5, longitudeDelta: 5)
// var region = MKCoordinateRegion(center: ausCenter, span: ausSpan)
// mapView.setRegion(region, animated: true)
// let camera = MKMapCamera()
// camera.centerCoordinate = mapView.centerCoordinate
// camera.pitch = 90.0
// camera.altitude = 30000000
// camera.heading = 0
// mapView.setCamera(camera, animated: true)
// var ausCenter = CLLocationCoordinate2D(latitude: -25.354917, longitude: 134.347407)
//
//// mapView.setCenter(ausCenter, animated: true)
//
// let span = MKCoordinateSpan(latitudeDelta: 150, longitudeDelta: 150)
// let region = MKCoordinateRegion(center: ausCenter, span: span)
// mapView.setRegion(region, animated: true)
//
// //add an annotation
// let annotation = MKPointAnnotation()
// annotation.coordinate = ausCenter
// annotation.title = "Australia"
// annotation.subtitle = "Details Forthcoming"
// mapView.addAnnotation(annotation)
}
}

Google map view color error

I would like to change marker position if button tapped. I tried like below. but it will look like this. Some how color will be changed to like so.
How can I fix this? Thank you!
#objc func changeMarker() {
let next = CLLocationCoordinate2DMake(40.730610, -73.935242)
mapView.camera = GMSCameraPosition.camera(withLatitude: next.latitude, longitude: next.longitude, zoom: 13)
let marker = GMSMarker(position: next)
marker.title = "over here"
marker.map = mapView
}
Add this marker and try this
func addMarker() {
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: CLLocationDegrees(yourCoordinateLatitude), longitude: CLLocationDegrees(yourCoordinateLongitude))
marker.map = mapView
}
Now you can zoom to your marker
func zoomToCoordinate(coordinate: CLLocationCoordinate2D, zoom: Float) {
CATransaction.begin()
CATransaction.setValue(1, forKey: kCATransactionAnimationDuration)
let camera = GMSCameraPosition.camera(withLatitude: coordinate.latitude, longitude: coordinate.longitude, zoom: zoom)
self.animate(to: camera)
CATransaction.commit()
}
I would call it like this
mapView.clear() // to clear your mapView
mapView.addMarker()
mapView.zoomToCoordinate(coordinate: yourCoordinate, zoom: 15)
Always check if your function is called and if the coordinations are correct.
This code works in my project. If it doesn't work for your project please share more code from you.

Zoom to fit user location and annotation map view swift

My map view shows both the user location and annotation for the destination mural, but the zoom is off. How can I make it scale to fit the current location and the destination annotation based on how far apart they are and more centered?
This is how it zooms (so far away)
func mapPoints(){
let annotations = MKPointAnnotation()
annotations.title = muralModel.muralName!
muralModel.getMainArtistModel(completion: { (anArtistModel) in
annotations.subtitle = " \(anArtistModel!.firstName!) \(anArtistModel!.lastName!)"
})
annotations.coordinate = coordinates
muralLocation.addAnnotation(annotations)
self.muralLocation.showsUserLocation = true
var zoomRect: MKMapRect = MKMapRectNull
let mapEdgePadding = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
//convert CLLocationCoordinate2D to MKMapPointForCoordinate so you don't end up in Bering Sea
let userPoint = MKMapPointForCoordinate(muralLocation.userLocation.coordinate)
let destinationPoint = MKMapPointForCoordinate(coordinates)
let userPointRect = MKMapRectMake(userPoint.x, userPoint.y, 0.1, 0.1)
let destinationPointRect = MKMapRectMake(destinationPoint.x, destinationPoint.y, 0.1, 0.1)
zoomRect = userPointRect
zoomRect = MKMapRectUnion(zoomRect, destinationPointRect)
muralLocation.setVisibleMapRect(zoomRect, edgePadding: mapEdgePadding, animated: true)
}
You can use the 'func setRegion(_ region: MKCoordinateRegion, animated: Bool)'. MKCoordinateRegion has a center and also defines a span for the region. The center here can be a point at an equal distance from the userLocation and the destination. You can decide the span accordingly.

MapView to show all annotations and zoom in as much as possible of the map

I basically have a map where I add two annotations and they are shown as expected.
Then I´m using the following code:
let annotations = [start, end]
mapView?.showAnnotations(annotations, animated: false)
And this zooms to show my map with the two annotations, but the map could be zoomed in much more and show a more detailed map view.
This is what I get today and this is the expected result that I want.
As you can see the map could be zoomed in a lot more.
Any ideas how to achieve this?
Swift 5.0 / 4.2 version of nyxee's answer
extension MKMapView {
/// When we call this function, we have already added the annotations to the map, and just want all of them to be displayed.
func fitAll() {
var zoomRect = MKMapRect.null;
for annotation in annotations {
let annotationPoint = MKMapPoint(annotation.coordinate)
let pointRect = MKMapRect(x: annotationPoint.x, y: annotationPoint.y, width: 0.01, height: 0.01);
zoomRect = zoomRect.union(pointRect);
}
setVisibleMapRect(zoomRect, edgePadding: UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100), animated: true)
}
/// We call this function and give it the annotations we want added to the map. we display the annotations if necessary
func fitAll(in annotations: [MKAnnotation], andShow show: Bool) {
var zoomRect:MKMapRect = MKMapRect.null
for annotation in annotations {
let aPoint = MKMapPoint(annotation.coordinate)
let rect = MKMapRect(x: aPoint.x, y: aPoint.y, width: 0.1, height: 0.1)
if zoomRect.isNull {
zoomRect = rect
} else {
zoomRect = zoomRect.union(rect)
}
}
if(show) {
addAnnotations(annotations)
}
setVisibleMapRect(zoomRect, edgePadding: UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100), animated: true)
}
}
Use this:
extension MKMapView {
/// when we call this function, we have already added the annotations to the map, and just want all of them to be displayed.
func fitAll() {
var zoomRect = MKMapRectNull;
for annotation in annotations {
let annotationPoint = MKMapPointForCoordinate(annotation.coordinate)
let pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.01, 0.01);
zoomRect = MKMapRectUnion(zoomRect, pointRect);
}
setVisibleMapRect(zoomRect, edgePadding: UIEdgeInsetsMake(100, 100, 100, 100), animated: true)
}
/// we call this function and give it the annotations we want added to the map. we display the annotations if necessary
func fitAll(in annotations: [MKAnnotation], andShow show: Bool) {
var zoomRect:MKMapRect = MKMapRectNull
for annotation in annotations {
let aPoint = MKMapPointForCoordinate(annotation.coordinate)
let rect = MKMapRectMake(aPoint.x, aPoint.y, 0.1, 0.1)
if MKMapRectIsNull(zoomRect) {
zoomRect = rect
} else {
zoomRect = MKMapRectUnion(zoomRect, rect)
}
}
if(show) {
addAnnotations(annotations)
}
setVisibleMapRect(zoomRect, edgePadding: UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100), animated: true)
}
}
then, after creating an outlet for your MapView, for example as map, and with you annotations either added to the map of in an array called annotations, access the above methods like so:
map.fitAll()
OR
map.fitAll(in:annotations, true)
respectively.
Use true or false in the last statement depending on whether you had added the annotations to the map before or not...
In Swift:
self.mapView.showAnnotations(self.mapView.annotations, animated: true)
This is what I use to show all annotations. almost the same as you are doing yes. the map zoom this to fit the visible or usable section of the map, on my app the zoom is good and does add some padding so that none of the pins are touching the edges.
so possibly once the maps is done you can quickly use setVisibleMapRect:edgePadding:animated: using the new visibleRect with a negative padding.
Swift 5.3 version with adjustable padding.
extension MKMapView {
func fitAllAnnotations(with padding: UIEdgeInsets = UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100)) {
var zoomRect: MKMapRect = .null
annotations.forEach({
let annotationPoint = MKMapPoint($0.coordinate)
let pointRect = MKMapRect(x: annotationPoint.x, y: annotationPoint.y, width: 0.01, height: 0.01)
zoomRect = zoomRect.union(pointRect)
})
setVisibleMapRect(zoomRect, edgePadding: padding, animated: true)
}
func fit(annotations: [MKAnnotation], andShow show: Bool, with padding: UIEdgeInsets = UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100)) {
var zoomRect: MKMapRect = .null
annotations.forEach({
let aPoint = MKMapPoint($0.coordinate)
let rect = MKMapRect(x: aPoint.x, y: aPoint.y, width: 0.1, height: 0.1)
zoomRect = zoomRect.isNull ? rect : zoomRect.union(rect)
})
if show {
addAnnotations(annotations)
}
setVisibleMapRect(zoomRect, edgePadding: padding, animated: true)
}
}