How to place annotations RANDOMLY in Mapkit Swift - ios

I want to know how to pin annotations randomly in a MapView
let latitude: CLLocationDegrees = 33.606800
let longitude: CLLocationDegrees = -111.845360
let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
//map annotation
let annotation = MKPointAnnotation()
annotation.coordinate = location
annotation.title = "Taliesin West"
annotation.subtitle = "Design"
map.addAnnotation(annotation)

For Anyone who wants the solution:
First: Adding Random Annotation according to current Location
Generating the Annotations:
func generateAnnoLoc() {
var num = 0
//First we declare While to repeat adding Annotation
while num != 15 {
num += 1
//Add Annotation
let annotation = MKPointAnnotation()
annotation.coordinate = generateRandomCoordinates(70, max: 150) //this will be the maximum and minimum distance of the annotation from the current Location (Meters)
annotation.title = "Annotation Title"
annotation.subtitle = "SubTitle"
mapView.addAnnotation(annotation)
}
}
Generating Coordinates:
func generateRandomCoordinates(min: UInt32, max: UInt32)-> CLLocationCoordinate2D {
//Get the Current Location's longitude and latitude
let currentLong = currentLoc.coordinate.longitude
let currentLat = currentLoc.coordinate.latitude
//1 KiloMeter = 0.00900900900901° So, 1 Meter = 0.00900900900901 / 1000
let meterCord = 0.00900900900901 / 1000
//Generate random Meters between the maximum and minimum Meters
let randomMeters = UInt(arc4random_uniform(max) + min)
//then Generating Random numbers for different Methods
let randomPM = arc4random_uniform(6)
//Then we convert the distance in meters to coordinates by Multiplying the number of meters with 1 Meter Coordinate
let metersCordN = meterCord * Double(randomMeters)
//here we generate the last Coordinates
if randomPM == 0 {
return CLLocationCoordinate2D(latitude: currentLat + metersCordN, longitude: currentLong + metersCordN)
}else if randomPM == 1 {
return CLLocationCoordinate2D(latitude: currentLat - metersCordN, longitude: currentLong - metersCordN)
}else if randomPM == 2 {
return CLLocationCoordinate2D(latitude: currentLat + metersCordN, longitude: currentLong - metersCordN)
}else if randomPM == 3 {
return CLLocationCoordinate2D(latitude: currentLat - metersCordN, longitude: currentLong + metersCordN)
}else if randomPM == 4 {
return CLLocationCoordinate2D(latitude: currentLat, longitude: currentLong - metersCordN)
}else {
return CLLocationCoordinate2D(latitude: currentLat - metersCordN, longitude: currentLong)
}
}
Second: Adding Random Annotation on all of the earth
erdekhayser Code to get a Random Float number
func randomBetweenNumbers(firstNum: CGFloat, secondNum: CGFloat) -> CGFloat {
return CGFloat(arc4random()) / CGFloat(UINT32_MAX) * abs(firstNum - secondNum) + min(firstNum, secondNum)
}
And then Calling:
func generateAnnoLoc() {
var num = 0
//First we declare While to repeat adding Annotation
while num != 15 {
num += 1
//Add Annotation
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: CLLocationDegrees(randomBetweenNumbers(-90, secondNum: 90)), longitude: CLLocationDegrees(randomBetweenNumbers(-180, secondNum: 180)))
//-180 is the minimum of longitude and 180 is the maximum
//-90 is the minimum of latitude and 90 is the maximum
annotation.title = "Annotation Title"
annotation.subtitle = "SubTitle"
mapView.addAnnotation(annotation)
}
}
Third: Adding Random Annotation in Specific Country
You only want the Bounding box of the country or city You can find it Here
this Will Generate Random Coordinates in Egypt:
CLLocationCoordinate2D(latitude: CLLocationDegrees(randomBetweenNumbers(22, secondNum: 24.698099)), longitude: CLLocationDegrees(randomBetweenNumbers(31.674179, secondNum: 36.89468)))

You can use random double values between coordinate values in the earth for example:
do{
let latitude: CLLocationDegrees = randomLatitude()
let longitude: CLLocationDegrees = randomLongtitude()
let location: CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longtitude)
annotation = MKPointAnnotation()
annotation.coordinate = location
map.addAnnotation(annotation)
}while count == 15
P.S. Random value for swift you can look at this

Related

Get the closest longitude and latitude from an existing longitude and latitude - swift [duplicate]

I want to make it so that it will show the amount of distance between two CLLocation coordinates. Is there someway to do this without a complex math formula? If there isn't how would you do it with a formula?
CLLocation has a distanceFromLocation method so given two CLLocations:
CLLocationDistance distanceInMeters = [location1 distanceFromLocation:location2];
or in Swift 4:
//: Playground - noun: a place where people can play
import CoreLocation
let coordinate₀ = CLLocation(latitude: 5.0, longitude: 5.0)
let coordinate₁ = CLLocation(latitude: 5.0, longitude: 3.0)
let distanceInMeters = coordinate₀.distance(from: coordinate₁) // result is in meters
you get here distance in meter so 1 miles = 1609 meter
if(distanceInMeters <= 1609)
{
// under 1 mile
}
else
{
// out of 1 mile
}
Swift 4.1
import CoreLocation
//My location
let myLocation = CLLocation(latitude: 59.244696, longitude: 17.813868)
//My buddy's location
let myBuddysLocation = CLLocation(latitude: 59.326354, longitude: 18.072310)
//Measuring my distance to my buddy's (in km)
let distance = myLocation.distance(from: myBuddysLocation) / 1000
//Display the result in km
print(String(format: "The distance to my buddy is %.01fkm", distance))
Try this out:
distanceInMeters = fromLocation.distanceFromLocation(toLocation)
distanceInMiles = distanceInMeters/1609.344
From Apple Documentation:
Return Value: The distance (in meters) between the two locations.
import CoreLocation
//My location
let myLocation = CLLocation(latitude: 31.5101892, longitude: 74.3440842)
//My Next Destination
let myNextDestination = CLLocation(latitude: 33.7181584, longitude: 73.071358)
//Finding my distance to my next destination (in km)
let distance = myLocation.distance(from: myNextDestination) / 1000
func calculateDistanceInMiles(){
let coordinate₀ = CLLocation(latitude:34.54545, longitude:56.64646)
let coordinate₁ = CLLocation(latitude: 28.4646, longitude:76.65464)
let distanceInMeters = coordinate₀.distance(from: coordinate₁)
if(distanceInMeters <= 1609)
{
let s = String(format: "%.2f", distanceInMeters)
self.fantasyDistanceLabel.text = s + " Miles"
}
else
{
let s = String(format: "%.2f", distanceInMeters)
self.fantasyDistanceLabel.text = s + " Miles"
}
}
For swift 4
let locationOne = CLLocation(latitude: lat, longitude: long)
let locationTwo = CLLocation(latitude: lat,longitude: long)
let distance = locationOne.distance(from: locationTwo) * 0.000621371
distanceLabel.text = "\(Int(round(distance))) mi"
For objective-c
You can use distanceFromLocation to find the distance between two coordinates.
Code Snippets:
CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:lat1 longitude:lng1];
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:lat2 longitude:lng2];
CLLocationDistance distance = [loc1 distanceFromLocation:loc2];
Your output will come in meters.
import UIKit
import CoreLocation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var currentLocation = CLLocation(latitude: 23.1929, longitude: 72.6156)
var DestinationLocation = CLLocation(latitude: 23.0504, longitude: 72.4991)
var distance = currentLocation.distance(from: DestinationLocation) / 1000
print(String(format: "The distance to my buddy is %.01fkm", distance))
}
}
You can also use the HaversineDistance algorithm just like android developers used, this is helpfull when you have antother app in android similar to it, else above answer is correct for you.
import UIKit
func haversineDinstance(la1: Double, lo1: Double, la2: Double, lo2: Double, radius: Double = 6367444.7) -> Double {
let haversin = { (angle: Double) -> Double in
return (1 - cos(angle))/2
}
let ahaversin = { (angle: Double) -> Double in
return 2*asin(sqrt(angle))
}
// Converts from degrees to radians
let dToR = { (angle: Double) -> Double in
return (angle / 360) * 2 * .pi
}
let lat1 = dToR(la1)
let lon1 = dToR(lo1)
let lat2 = dToR(la2)
let lon2 = dToR(lo2)
return radius * ahaversin(haversin(lat2 - lat1) + cos(lat1) * cos(lat2) * haversin(lon2 - lon1))
}
let amsterdam = (52.3702, 4.8952)
let newYork = (40.7128, -74.0059)
// Google says it's 5857 km so our result is only off by 2km which could be due to all kinds of things, not sure how google calculates the distance or which latitude and longitude google uses to calculate the distance.
haversineDinstance(la1: amsterdam.0, lo1: amsterdam.1, la2: newYork.0, lo2: newYork.1)
I have picked the code written above from the refrence link
https://github.com/raywenderlich/swift-algorithm-club/blob/master/HaversineDistance/HaversineDistance.playground/Contents.swift
Swift 5.
func calculateDistance(mobileLocationX:Double,mobileLocationY:Double,DestinationX:Double,DestinationY:Double) -> Double {
let coordinate₀ = CLLocation(latitude: mobileLocationX, longitude: mobileLocationY)
let coordinate₁ = CLLocation(latitude: DestinationX, longitude: DestinationY)
let distanceInMeters = coordinate₀.distance(from: coordinate₁)
return distanceInMeters
}
use to
let distance = calculateDistance("add parameters")

How can i increase zoom in Apple Mapkit with multiple annotations in iOS

I tried this code, here I increase MKCoordinateSpan to 200 - 200, but my application got crashed, can someone please help me.
func setupMap(hotelListData:[HotelListData], cityLocation:
CLLocationCoordinate2D )
{
let coordinateRegion = MKCoordinateRegion(center: cityLocation, span: MKCoordinateSpan(latitudeDelta: 200, longitudeDelta: 200))
mapView.setRegion(coordinateRegion, animated: true)
//Set Multiple Annotation
for data in hotelListData {
let annotation = MKPointAnnotation()
annotation.title = data.hotel?.name
annotation.coordinate = CLLocationCoordinate2D(latitude: Double(data.hotel?.latitude ?? 0.0), longitude: Double(data.hotel?.longitude ?? 0.0))
mapView.addAnnotation(annotation)
}
}
Update:
I changed span from (latitudinalMeters & longitudinalMeters) and got the desired results :-
Now one can found here :
i)Set multiple Annotations to apple maps.
ii)Adjust Zoom with the desired location.
func setupMap(hotelListData:[HotelListData], cityLocation:
CLLocationCoordinate2D ){
let coordinateRegion = MKCoordinateRegion(center: cityLocation, latitudinalMeters: CLLocationDistance(exactly: 15000)!, longitudinalMeters: CLLocationDistance(exactly: 15000)!)
mapView.setRegion(coordinateRegion, animated: true)
//Set Multiple Annotation
for data in hotelListData {
let annotation = MKPointAnnotation()
annotation.title = data.hotel?.name
annotation.coordinate = CLLocationCoordinate2D(latitude: Double(data.hotel?.latitude ?? 0.0), longitude: Double(data.hotel?.longitude ?? 0.0))
mapView.addAnnotation(annotation)
}
}
The longitudeDelta and latitudeDelta for a MKCoordinateSpan are measured in degrees. There are only 180 degrees of latitude from the north pole to the south pole, so using 200 for that parameter is not very sensible.
Since you want to show just the region of a city on the map, you can use this other initialiser that takes in distances in meters, if you know how big the cities that your app is handling usually are.
For example,
let coordinateRegion = MKCoordinateRegion(center: cityLocation, latitudinalMeters: 30000, longitudinalMeters: 30000)
If your cities have varying sizes, or you don't know how big they are, then another way is to calculate the range of latitudes and longitudes of the hotels, and use that to create an MKCoordinateSpan.
var minLat: CLLocationDegrees = 90
var maxLat: CLLocationDegrees = -90
var minLong: CLLocationDegrees = 180
var maxLong: CLLocationDegrees = -180
for data in hotelListData {
// ... you annotation code ...
guard let hotel = data.hotel else { continue }
if hotel.latitude < minLat { minLat = hotel.latitude }
if hotel.latitude > maxLat { maxLat = hotel.latitude }
if hotel.longitude < minLong { minLong = hotel.longitude }
if hotel.longitude > maxLong { maxLong = hotel.longitude }
}
let latRange = max(0.01, maxLat - minLat) // if the range is too small, make it at least 0.01
let longRange = max(0.01, maxLong - minLong)
let coordinateRegion = MKCoordinateRegion(
center: cityLocation,
span: MKCoordinateSpan(latitudeDelta: latRange, longitudeDelta: longRange)

Draw equal circle with in current location radius using Google Map SDK ios

I need to divide current location radius (1000 meters) area into equal parts(100 meter each part) and get those center point coordinates in google map SDK. I am using google map sdk in my app. can any one help me?
Thank you in advance.
GMSCircle *circ = [GMSCircle circleWithPosition:CLLocationCoordinate2DMake(latitudeCir, longitudeCir)
radius:radiusValue];
UIColor *colr = [UIColor colorWithRed:284.0/255.0 green:51.0/255.0 blue:84.0/255.0 alpha:0.3];
circ.fillColor = colr;
circ.strokeColor = colr;
circ.map = _mapkitView;
try this
var num = 0
//First we declare While to repeat adding Annotation
while num != 15 {
num += 1
let rotateDegree : CLLocationDegrees = 90
//Add Annotation
let annotation = GMSMarker()
annotation.position = generateRandomCoordinates(min: 1000, max: 10000) //this will be the maximum and minimum distance of the annotation from the current Location (Meters)
annotation.groundAnchor = CGPoint(x: 0.5, y: 0.5)
annotation.rotation = rotateDegree
annotation.icon = UIImage.init(named: "icon_machine_location")
annotation.map = mapView
}
Generate Random Coordinates Function
func generateRandomCoordinates(min: UInt32, max: UInt32)-> CLLocationCoordinate2D {
//Get the Current Location's longitude and latitude
let currentLong = currentLocation.coordinate.longitude
let currentLat = currentLocation.coordinate.latitude
//1 KiloMeter = 0.00900900900901° So, 1 Meter = 0.00900900900901 / 1000
let meterCord = 0.00900900900901 / 1000
//Generate random Meters between the maximum and minimum Meters
let randomMeters = UInt(arc4random_uniform(max) + min)
//then Generating Random numbers for different Methods
let randomPM = arc4random_uniform(6)
//Then we convert the distance in meters to coordinates by Multiplying number of meters with 1 Meter Coordinate
let metersCordN = meterCord * Double(randomMeters)
//here we generate the last Coordinates
if randomPM == 0 {
return CLLocationCoordinate2D(latitude: currentLat + metersCordN, longitude: currentLong + metersCordN)
}else if randomPM == 1 {
return CLLocationCoordinate2D(latitude: currentLat - metersCordN, longitude: currentLong - metersCordN)
}else if randomPM == 2 {
return CLLocationCoordinate2D(latitude: currentLat + metersCordN, longitude: currentLong - metersCordN)
}else if randomPM == 3 {
return CLLocationCoordinate2D(latitude: currentLat - metersCordN, longitude: currentLong + metersCordN)
}else if randomPM == 4 {
return CLLocationCoordinate2D(latitude: currentLat, longitude: currentLong - metersCordN)
}else {
return CLLocationCoordinate2D(latitude: currentLat - metersCordN, longitude: currentLong)
}
}

How to make Text Show distance from The user current location to a certain Map annotation

Just wondering How to do that , really would like this in my custom cell in the table view in my app...
Will appreciate any help thank you !
You can calculate the distance between two CLLocation objects with the distanceFromLocation method:
let newYork = CLLocation(latitude: 40.725530, longitude: -73.996738)
let sanFrancisco = CLLocation(latitude: 37.768, longitude: -122.441)
let distanceInMeters = newYork.distanceFromLocation(sanFrancisco)
With an MKMapView object and an MKAnnotationView object, you can calculate the distance between the user's current location and the annotation as follows:
if let userLocation = mapView.userLocation.location, annotation = annotationView.annotation {
// Calculate the distance from the user to the annotation
let annotationLocation = CLLocation(latitude: annotation.coordinate.latitude, longitude: annotation.coordinate.longitude)
let distanceFromUserToAnnotationInMeters = userLocation.distanceFromLocation(annotationLocation)
...
}
The following function uses the NSNumberFormatter class to format a distance in meters or kilometres (if the number of meters is more than 1000):
func formatDistance(distanceInMeters: CLLocationDistance) -> String? {
// Set up a number formatter with two decimal places
let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = .DecimalStyle
numberFormatter.maximumFractionDigits = 2
// Display as kilometers if the distance is more than 1000 meters
let distanceToFormat: CLLocationDistance = distanceInMeters > 1000 ? distanceInMeters/1000.0 : distanceInMeters
let units = distanceInMeters > 1000 ? "Km" : "m"
// Format the distance
if let formattedDistance = numberFormatter.stringFromNumber(distanceToFormat) {
return "\(formattedDistance)\(units)"
} else {
return nil
}
}
Putting all this together gives us the following:
if let userLocation = mapView.userLocation.location, annotation = annotationView.annotation {
// Calculate the distance from the user to the annotation
let annotationLocation = CLLocation(latitude: annotation.coordinate.latitude, longitude: annotation.coordinate.longitude)
let distanceFromUserToAnnotationInMeters = userLocation.distanceFromLocation(annotationLocation)
if let formattedDistance = formatDistance(distanceFromUserToAnnotationInMeters) {
// Now set the vaue of your label to formattedDistance
}
}

How to find out distance between coordinates?

I want to make it so that it will show the amount of distance between two CLLocation coordinates. Is there someway to do this without a complex math formula? If there isn't how would you do it with a formula?
CLLocation has a distanceFromLocation method so given two CLLocations:
CLLocationDistance distanceInMeters = [location1 distanceFromLocation:location2];
or in Swift 4:
//: Playground - noun: a place where people can play
import CoreLocation
let coordinate₀ = CLLocation(latitude: 5.0, longitude: 5.0)
let coordinate₁ = CLLocation(latitude: 5.0, longitude: 3.0)
let distanceInMeters = coordinate₀.distance(from: coordinate₁) // result is in meters
you get here distance in meter so 1 miles = 1609 meter
if(distanceInMeters <= 1609)
{
// under 1 mile
}
else
{
// out of 1 mile
}
Swift 4.1
import CoreLocation
//My location
let myLocation = CLLocation(latitude: 59.244696, longitude: 17.813868)
//My buddy's location
let myBuddysLocation = CLLocation(latitude: 59.326354, longitude: 18.072310)
//Measuring my distance to my buddy's (in km)
let distance = myLocation.distance(from: myBuddysLocation) / 1000
//Display the result in km
print(String(format: "The distance to my buddy is %.01fkm", distance))
Try this out:
distanceInMeters = fromLocation.distanceFromLocation(toLocation)
distanceInMiles = distanceInMeters/1609.344
From Apple Documentation:
Return Value: The distance (in meters) between the two locations.
import CoreLocation
//My location
let myLocation = CLLocation(latitude: 31.5101892, longitude: 74.3440842)
//My Next Destination
let myNextDestination = CLLocation(latitude: 33.7181584, longitude: 73.071358)
//Finding my distance to my next destination (in km)
let distance = myLocation.distance(from: myNextDestination) / 1000
func calculateDistanceInMiles(){
let coordinate₀ = CLLocation(latitude:34.54545, longitude:56.64646)
let coordinate₁ = CLLocation(latitude: 28.4646, longitude:76.65464)
let distanceInMeters = coordinate₀.distance(from: coordinate₁)
if(distanceInMeters <= 1609)
{
let s = String(format: "%.2f", distanceInMeters)
self.fantasyDistanceLabel.text = s + " Miles"
}
else
{
let s = String(format: "%.2f", distanceInMeters)
self.fantasyDistanceLabel.text = s + " Miles"
}
}
For swift 4
let locationOne = CLLocation(latitude: lat, longitude: long)
let locationTwo = CLLocation(latitude: lat,longitude: long)
let distance = locationOne.distance(from: locationTwo) * 0.000621371
distanceLabel.text = "\(Int(round(distance))) mi"
For objective-c
You can use distanceFromLocation to find the distance between two coordinates.
Code Snippets:
CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:lat1 longitude:lng1];
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:lat2 longitude:lng2];
CLLocationDistance distance = [loc1 distanceFromLocation:loc2];
Your output will come in meters.
import UIKit
import CoreLocation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var currentLocation = CLLocation(latitude: 23.1929, longitude: 72.6156)
var DestinationLocation = CLLocation(latitude: 23.0504, longitude: 72.4991)
var distance = currentLocation.distance(from: DestinationLocation) / 1000
print(String(format: "The distance to my buddy is %.01fkm", distance))
}
}
You can also use the HaversineDistance algorithm just like android developers used, this is helpfull when you have antother app in android similar to it, else above answer is correct for you.
import UIKit
func haversineDinstance(la1: Double, lo1: Double, la2: Double, lo2: Double, radius: Double = 6367444.7) -> Double {
let haversin = { (angle: Double) -> Double in
return (1 - cos(angle))/2
}
let ahaversin = { (angle: Double) -> Double in
return 2*asin(sqrt(angle))
}
// Converts from degrees to radians
let dToR = { (angle: Double) -> Double in
return (angle / 360) * 2 * .pi
}
let lat1 = dToR(la1)
let lon1 = dToR(lo1)
let lat2 = dToR(la2)
let lon2 = dToR(lo2)
return radius * ahaversin(haversin(lat2 - lat1) + cos(lat1) * cos(lat2) * haversin(lon2 - lon1))
}
let amsterdam = (52.3702, 4.8952)
let newYork = (40.7128, -74.0059)
// Google says it's 5857 km so our result is only off by 2km which could be due to all kinds of things, not sure how google calculates the distance or which latitude and longitude google uses to calculate the distance.
haversineDinstance(la1: amsterdam.0, lo1: amsterdam.1, la2: newYork.0, lo2: newYork.1)
I have picked the code written above from the refrence link
https://github.com/raywenderlich/swift-algorithm-club/blob/master/HaversineDistance/HaversineDistance.playground/Contents.swift
Swift 5.
func calculateDistance(mobileLocationX:Double,mobileLocationY:Double,DestinationX:Double,DestinationY:Double) -> Double {
let coordinate₀ = CLLocation(latitude: mobileLocationX, longitude: mobileLocationY)
let coordinate₁ = CLLocation(latitude: DestinationX, longitude: DestinationY)
let distanceInMeters = coordinate₀.distance(from: coordinate₁)
return distanceInMeters
}
use to
let distance = calculateDistance("add parameters")

Resources