This article is part of a series on learning Swift by writing code to The Swift Programming Language book from Apple.
We've covered the basics up to functions, and reviewed them in the last article, and we're going to continue reviewing those chapters in this one.
Set up a reading environment
If you are jumping around these articles, make sure you read the Introduction to see my recommendation for setting up a reading environment.
Exercises
For this chapter, we're going to write code inspired by the Maps app.
Copy this into your playground
let places: [[String: Any]] = [
["name": "Buckingham Palace", "location": (lat: 51.5000632, long: -0.1449567)],
["name": "Great Pyramid of Giza", "location": (lat: 29.9792391, long: 31.1320079)],
["name": "Sydney Opera House", "location": (lat: -33.8567799, long: 151.2131027)],
["name": "Machu Picchu", "location": (lat: -13.163136, long: -72.5471569)],
["name": "Victoria Falls", "location": (lat: -17.9149133, long: 25.8379429)],
["name": "Empire State Building", "location": (lat: 40.7484445, long: -73.9878584)],
["name": "The Forbidden City", "location": (lat: 39.9394501, long: 116.1152174)],
["name": "Parthenon", "location": (lat: 38.3336346, long: 20.9712001)],
]
To make sure you understand how to access data in this structure, start with this code:
let name = places[0]["name"] as? String
let location = places[0]["location"] as? (lat: Double, long: Double)
location?.lat
In your Playground write code to do the following
- Print out the longitude (
.long) of The Sydney Opera House. - Use this page to find the distance between two of these places by plugging in their latitudes and longitudes.
- Implement the Haversine distance formula. If you are an experienced programmer (just new to Swift), then read the Javascript version on that page and try to port it.
- Once you have that, write a function that takes the
placesdata and returns the two places that are closest to each other. (In Swift, the basic math functions are all global functions:sin,cos,atan2,pow, etc)
More help for beginners
Ok, step one is to declare a function that takes two lat/long tuples and returns a Double.
Start with this:
let location1 = places[0]["location"] as? (lat: Double, long:Double)
let location2 = places[1]["location"] as? (lat: Double, long:Double)
func distanceKm(loc1: (lat: Double, long: Double)?, loc2: (lat: Double, long: Double)?)
-> Double? {
if let loc1 = loc1, let loc2 = loc2 {
// Implement Haversine here
return 0 // .. replace this line
}
return 0
}
distanceKm(loc1: location1, loc2: location2)
Here is the basic algorithm:
- Declare a constant
Rwhich is 6371000.0 (the radius of the Earth) - Declare a constant
phi1which isloc1.latin radians:loc1.lat * .pi / 180.0(in general:radians = degrees * .pi / 180.0) - Declare a constant
phi2which isloc2.latin radians - Declare a constant
deltaPhiwhich is(loc2.lat - loc1.lat)in radians - Declare a constant
deltaLambdawhich is(loc2.long - loc1.long)in radians - Declare a constant
ato bepow(sin(deltaPhi / 2), 2) + cos(phi1) * cos(phi2) * pow(sin(deltaLambda/2), 2) - Declare a constant
cto be2 * atan2(sqrt(a), sqrt(1-a)) - Return
R * c / 1000.0
distanceKm(loc1: location1, loc2: location2) should be around 3511 just like the web page.
Now see if you can find the two closest places. Start with this
func closestTo(places: [[String: Any]], loc: (lat: Double, long: Double)) -> String {
var smallestDistance = Double.greatestFiniteMagnitude
var closest = ""
for p in places {
if
let name = p["name"] as? String,
let loc2 = p["location"] as? (lat: Double, long: Double),
let distance = distanceKm(loc1: loc, loc2: loc2),
distance < smallestDistance {
smallestDistance = distance
closest = name
}
}
return closest
}
// Find the closest place to the Eiffel Tower (should be Buckingham Palace)
closestTo(places: places, loc: (lat: 48.8583736, long: 2.2922873))
Use this function as a start. You need to make sure you don't compare a place to itself, because that will always be the closest.
DM me or comment below if you need help.
Next: Closures
The next article will provide exercises for the Closures chapter. Read it before you move on.
Top comments (0)