How to reproduce the error:
let mapView = MKMapView.init(frame: UIScreen.mainScreen().bounds)
mapView.region.center = CLLocationCoordinate2D.init(latitude: 60, longitude: 100)
mapView.region.span = MKCoordinateSpanMake(20, 20)
print(mapView.region.center)
self.view = mapView
And the print statement prints this:
CLLocationCoordinate2D(latitude: 44.880507991448255, longitude: 100.00000000000004)
The problem is that I actually set the latitude to 60 at line 2. However the resulted latitude is 44.88x. And I have tried other values above 45, and they are not correct also. Any ideas? Thanks!
This seems to be an issue with Swift. If you try this code in Objective-C
mapView.region.center = CLLocationCoordinate2D.init(latitude: 60, longitude: 100)
The compiler gives an error expression is not assignable. The correct approach is to create a new region and then assign this region to the map view:
let region = MKCoordinateRegionMake(CLLocationCoordinate2DMake(60.0,100.0), MKCoordinateSpanMake(20, 20))
mapView.region = region
Related
I am using a map with some annotations, I want to group the nearest annotations in annotation group to not overlap in the design in case of user zoom out, but my problem is to how to know the distance between annotations and this distance should change when zooming in and out.
the distance should be between points with x and y formate note meters
So my question is to how to catch the difference between 2 points on the map and consider the zoom
// convert location to cLLocation
let cLLocation1 = CLLocation(latitude: post1Location?.lat ?? 0, longitude: post1Location?.lng ?? 0)
let cLLocation2 = CLLocation(latitude: post2Location?.lat ?? 0, longitude: post2Location?.lng ?? 0)
// this is return the dinsactence in metres but i don't need that
let distance = cLLocation1.distance(from: cLLocation2)
let annotaionPoint1 = MKMapPoint(cLLocation1.coordinate)
let annotaionPoint2 = MKMapPoint(cLLocation2.coordinate)
let xDistance = max(annotaionPoint1.x, annotaionPoint2.x) - min(annotaionPoint1.x, annotaionPoint2.x)
let yDistance = max(annotaionPoint1.y, annotaionPoint2.y) - min(annotaionPoint1.y, annotaionPoint2.y)
this is working but zoom in and zoom out no effect so I need zoom to make change
if min(xDistance, yDistance) <= 32 {
/// action
}
While driving I record the different coordinates during the drive. If I drive between two points that is generally in a straight line, then the map span of the following code works well but if I drive around the block then the map span doesn't show the route. I can generally see that since I am using the first and last coordinate this would be why. The region is then put into a snapshot to generate an image of the map. What I'm struggling with is being able to use all coordinates to calculate the needed span.
//calculate region
let span = MKCoordinateSpan.init(latitudeDelta: fabs(startCoord.latitude - endCoord.latitude) * 1.6, longitudeDelta: fabs(endCoord.longitude - startCoord.longitude) * 1.6)
let resd = CLLocationCoordinate2D.init(latitude: startCoord.latitude - (startCoord.latitude - endCoord.latitude) * 0.5, longitude: startCoord.longitude + (endCoord.longitude - startCoord.longitude) * 0.5)
let options = MKMapSnapshotter.Options()
options.scale = UIScreen.main.scale
options.region = MKCoordinateRegion.init(center: resd, span: span);
options.size = CGSize(width: 600, height: 450) //map size
options.showsBuildings = true
options.showsPointsOfInterest = true
I found this bit of code on another question
func regionFor(coordinates coords: [CLLocationCoordinate2D]) -> MKCoordinateRegion {
var r = MKMapRect.null
for i in 0 ..< coords.count {
let p = MKMapPoint(coords[i])
r = r.union(MKMapRect(x: p.x, y: p.y, width: 0, height: 0))
}
return MKCoordinateRegion(r)
}
But I couldn't get it to work to show the circle either. Anyone have an idea of how I could do this?
A region span is a rectangle. Finding a bounding rectangle is a simpler problem than finding a circle that fully encloses a set of points.
Just set up max and min latitude and longitude variables that start with values that are out of range in the opposite direction, loop through your points, and when a points co-ord is >max or <min, replace that value. When you're done, use the min-max latitude and min-max longitude values to define your region span.
I have 2 CLLocation coordinates and I wanna know the distance between them using as a path an array of coordinates that go from point A to B. I know how to calculate the distance from point A to B but the problem is that it seems to be measured in a straight line rather than following a given route. Any idea on how to do this efficiently?
It's very simple if you have all CLLocations. Just one line code can do it. For example:
var locations : [CLLocation] = [CLLocation.init(latitude: CLLocationDegrees(10.00000), longitude: CLLocationDegrees(100.00000)),
CLLocation.init(latitude: CLLocationDegrees(10.00001), longitude: CLLocationDegrees(100.00001)),
CLLocation.init(latitude: CLLocationDegrees(10.00002), longitude: CLLocationDegrees(100.00002)),
CLLocation.init(latitude: CLLocationDegrees(10.00003), longitude: CLLocationDegrees(100.00003)),
]
let totalDistance = locations.dropFirst().reduce((locations.first!, 0.0)) { ($1 , $0.1 + $0.0.distance(from: $1)) }.1
print(totalDistance)
I made E.Coms answer more readable:
guard let firstLocation = locations.first else { return }
let distance = locations.reduce((location: firstLocation, distance: 0.0)) { partialResult, nextLocation in
return (nextLocation, partialResult.distance + partialResult.location.distance(from: nextLocation))
}.distance
I am working with Google maps in iOS. I wanted to animate my Camera such that it shows all the required Lat, Lngs. I am storing those locations in the array(as CLLocationCoordinate2D instances) and using GMSCoordinateBounds class to add these locations. This is my code:
let bounds = GMSCoordinateBounds()
bounds.includingCoordinate(firstLocation)
bounds.includingCoordinate(lastLocation)
let camUpdate = GMSCameraUpdate.fit(bounds, withPadding: 60)
mMapView.camera = GMSCameraPosition.camera(withLatitude: firstLocation.latitude, longitude: firstLocation.longitude, zoom: 18)
mMapView.animate(with: camUpdate)
firstLocation and lastLocation have correct values but the camera is not animating. Am I missing something?
Very silly mistake. includingCoordinates function returns GMSCoordinateBounds object. I had to set to itself again for it to work like so:
bounds = bounds.includingCoordinate(firstLocation)
bounds = bounds.includingCoordinate(lastLocation)
If i set like above, it is working fine.
I want to set a location based reminder. This is my code:
let locattionnotification = UILocalNotification()
locattionnotification.alertBody = textAllert
locattionnotification.regionTriggersOnce = false
locattionnotification.region = CLCircularRegion(circularRegionWithCenter: CLLocationCoordinate2D(latitude:
mylatitude, longitude: mylongitude), radius: 300.0, identifier: "Location1")
UIApplication.sharedApplication().scheduleLocalNotification(locattionnotification)
mylatitude and mylongitude are double values. The problem is, that Xcode is complaining:
init(circularRegionWithCenter:radius:identifier:)' is unavailable: APIs >deprecated as of iOS 7 and earlier are unavailable in Swift
Is there any better way to set the region based reminder? I already did some research, and saw that it is also possible with CLRegion, but couldn't figure out how to set it up with manually set coordinates.
You can use another CLCircularRegion constructor:
locattionnotification.region = CLCircularRegion(center: CLLocationCoordinate2D(latitude:
mylatitude, longitude: mylongitude), radius: 300.0, identifier: "Location1")