LocationView.swift 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Copyright (C) 2016 Inigo Valentin
  2. //
  3. // This file is part of the Gasteizko Margolariak IOS app.
  4. //
  5. // The Gasteizko Margolariak IOS app is free software: you can
  6. // redistribute it and/or modify it under the terms of the
  7. // GNU General Public License as published by the Free Software
  8. // Foundation, either version 3 of the License, or (at your
  9. // option) any later version.
  10. //
  11. // The Gasteizko Margolariak IOS app is distributed in the
  12. // hope that it will be useful, but WITHOUT ANY WARRANTY;
  13. // without even the implied warranty of MERCHANTABILITY or
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
  15. // Public License for more details.
  16. //
  17. // You should have received a copy of the GNU General Public
  18. // License along with the Gasteizko Margolariak IOS app.
  19. // If not, see <http://www.gnu.org/licenses/>.
  20. import Foundation
  21. import CoreData
  22. import UIKit
  23. import GoogleMaps
  24. /**
  25. Class to handle the location view.
  26. */
  27. class LocationView: UIView {
  28. @IBOutlet var container: UIView!
  29. @IBOutlet weak var map: GMSMapView!
  30. @IBOutlet weak var lbTitle: UILabel!
  31. @IBOutlet weak var lbDistance: UILabel!
  32. @IBOutlet weak var lbNo: UILabel!
  33. var controller: ViewController
  34. var storyboard: UIStoryboard
  35. var didFindMyLocation = false
  36. var locationTimer: Timer? = nil
  37. /**
  38. Default constructor for the interface builder.
  39. :param: frame View frame.
  40. */
  41. override init(frame: CGRect){
  42. // Set controller
  43. self.storyboard = UIStoryboard(name: "Main", bundle: nil)
  44. self.controller = storyboard.instantiateViewController(withIdentifier: "GMViewController") as! ViewController
  45. super.init(frame: frame)
  46. }
  47. /**
  48. Run when the view is started.
  49. */
  50. required init?(coder aDecoder: NSCoder) {
  51. // Set controller
  52. self.storyboard = UIStoryboard(name: "Main", bundle: nil)
  53. self.controller = storyboard.instantiateViewController(withIdentifier: "GMViewController") as! ViewController
  54. super.init(coder: aDecoder)
  55. // Load the contents of the HomeView.xib file.
  56. Bundle.main.loadNibNamed("LocationView", owner: self, options: nil)
  57. self.addSubview(self.container)
  58. self.container.frame = self.bounds
  59. // Set map up
  60. map.isMyLocationEnabled = true
  61. //map.addObserver(self, forKeyPath: "myLocation", options: NSKeyValueObservingOptions.new, context: nil)
  62. let camera: GMSCameraPosition = GMSCameraPosition.camera(withLatitude: 42.846399, longitude: -2.673365, zoom: 12.0)
  63. map.camera = camera
  64. // Schedule location fetches
  65. getNewLocation()
  66. Timer.scheduledTimer(timeInterval: 60, target: self, selector: #selector(getNewLocation), userInfo: nil, repeats: true)
  67. }
  68. /**
  69. Enables the user location dot in the map, checking for permission.
  70. :param: manager Location manager used to get the location.
  71. :param: didChangeAuthorizationStatus status Permission status
  72. */
  73. func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
  74. if status == CLAuthorizationStatus.authorizedWhenInUse {
  75. map.isMyLocationEnabled = true
  76. }
  77. }
  78. /**
  79. Get new user location and recalculates distance to GM .
  80. */
  81. func getNewLocation(){
  82. let defaults = UserDefaults.standard
  83. if (defaults.value(forKey: "GMLocLat") != nil && defaults.value(forKey: "GMLocLon") != nil){
  84. let lat = defaults.value(forKey: "GMLocLat") as! Double
  85. let lon = defaults.value(forKey: "GMLocLon") as! Double
  86. let time = defaults.value(forKey: "GMLocTime") as! Date
  87. let cTime = Date()
  88. let minutes = Calendar.current.dateComponents([.minute], from: time, to: cTime).minute
  89. if (minutes! < 30){
  90. self.map.isHidden = false
  91. self.lbTitle.isHidden = false
  92. self.lbDistance.isHidden = false
  93. self.lbNo.isHidden = true
  94. let marker = GMSMarker()
  95. marker.position = CLLocationCoordinate2D(latitude: lat, longitude: lon)
  96. marker.title = "Gasteizko Margolariak"
  97. //marker.snippet = "Australia"
  98. marker.map = self.map
  99. let location = self.controller.getLocation()
  100. if location != nil {
  101. let d: Int = calculateDistance(lat1: location.latitude, lon1: location.longitude, lat2: lat, lon2: lon)
  102. if d <= 1000 {
  103. self.lbDistance.text = "A \(d) metros de ti."
  104. }
  105. else{
  106. self.lbDistance.text = "A \(Int(d/1000)) kilómetros de ti."
  107. }
  108. }
  109. }
  110. else{
  111. self.map.isHidden = true
  112. self.lbTitle.isHidden = true
  113. self.lbDistance.isHidden = true
  114. self.lbNo.isHidden = false
  115. }
  116. }
  117. }
  118. /**
  119. Converts degrees to radians.
  120. :param: degrees Angle in degrees.
  121. :return: Angle in radiands.
  122. */
  123. func degreesToRadians(degrees: Double) -> Double {
  124. return degrees * Double.pi / 180;
  125. }
  126. /**
  127. Calculates the distance, in integer meters, between two coordinates.
  128. :param: lat1 Latitude component of the first point.
  129. :param: lon1 Longitude component of the first point.
  130. :param: lat2 Latitude component of the second point.
  131. :param: lon2 Longitude component of the second point.
  132. :return: Distance, in integer meters, between the points.
  133. */
  134. func calculateDistance(lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> Int {
  135. let eRadius: Double = 6371
  136. let dLat: Double = degreesToRadians(degrees: lat2-lat1)
  137. let dLon: Double = degreesToRadians(degrees: lon2-lon1)
  138. let l1: Double = degreesToRadians(degrees: lat1)
  139. let l2: Double = degreesToRadians(degrees: lat2)
  140. let a: Double = sin(dLat/2) * sin(dLat/2) + sin(dLon/2) * sin(dLon/2) * cos(l1) * cos(l2)
  141. let c: Double = 2 * atan2(sqrt(a), sqrt(1-a))
  142. let m: Double = eRadius * c * 1000
  143. return Int(m)
  144. }
  145. /*
  146. // TODO: Whato does this do?
  147. func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutableRawPointer) {
  148. if !didFindMyLocation {
  149. let myLocation: CLLocation = change[NSKeyValueChangeNewKey] as CLLocation
  150. map.camera = GMSCameraPosition.camera(withTarget: myLocation.coordinate, zoom: 10.0)
  151. map.settings.myLocationButton = true
  152. didFindMyLocation = true
  153. }
  154. }
  155. */
  156. }