【Swift】CoreLocation 0->1
2点間の距離を計算するのにMapKitではなくこちらを使えないか
CLLocation
The latitude, longitude, and course information reported by the system.
...
You may create location objects yourself when you want to cache custom location data or calculate the distance between two geographical coordinates.
これでいけそう
init(latitude: CLLocationDegrees, longitude: CLLocationDegrees)
Use this method to create location objects that are not necessarily based on the user's current location.
CLLocationってGPSの位置情報でinitしないといけないイメージを持ったけど、そんなことないって
func distance(from location: CLLocation) -> CLLocationDistance
Parameters
location
The destination location.
Return Value
The distance (in meters) between the two locations.
Discussion
This method measures the distance between the location in the current object and the value in the location parameter. The distance is calculated by tracing a line between the two points that follows the curvature of the Earth, and measuring the length of the resulting arc. The arc is a smooth curve that doesn’t take into account altitude changes between the two locations.
これで距離はでるじゃん
Type Alias
CLLocationDistance
A distance measurement (measured in meters) from an existing location.
Declaration
typealias CLLocationDistance = Double
CLCircularRegion
A circular geographic region, specified as a center point and radius.
Declaration
class CLCircularRegion : CLRegion
Overview
The CLCircularRegion class defines the location and boundaries for a circular geographic region. You can use instances of this class to define geo fences for a specific location. The crossing of a geo fence’s boundary causes the location manager to notify its delegate.
最後の一行はよくわからないけど
Initializing a Circular Region
init(center: CLLocationCoordinate2D, radius: CLLocationDistance, identifier: String) //Initializes and returns a region object defining a circular geographic area.
Accessing a Region’s Attributes
var center: CLLocationCoordinate2D //The center point of the geographic area. var radius: CLLocationDistance //The radius (measured in meters) that defines the geographic area’s outer boundary.
Hit Testing in a Region
func contains(CLLocationCoordinate2D) -> Bool //Returns a Boolean value indicating whether the geographic area contains the specified coordinate.
最後のcontainsを使えばやりたいことが一気に満たせる
あとはどうやって中心を見つけるかだな
やっぱりこれが一番楽そうなので、実装することにした
class DistanceFilterManger {
static let shared: DistanceFilterManger = DistanceFilterManger()
func filterByDistance(mainPhoto: BasePhoto, photoArray: [BasePhoto], distance: Float) -> [BasePhoto] {
guard let lat = mainPhoto.latitude else { return photoArray }
guard let lon = mainPhoto.longitude else { return photoArray }
let center = CLLocationCoordinate2D(latitude: Double(truncating: lat), longitude: Double(truncating: lon))
let filterArea = CLCircularRegion(center: center, radius: CLLocationDistance(distance), identifier: "filterArea")
let photoArrayFiltered = photoArray.filter { (photo) -> Bool in
guard let latitude = photo.latitude else { return false }
guard let longitude = photo.longitude else { return false }
let photoLocation = CLLocationCoordinate2D(latitude: Double(truncating: latitude), longitude: Double(truncating: longitude))
return filterArea.contains(photoLocation)
}
return photoArrayFiltered
}
}
こんな感じでやってみた。距離mでいいよね?
逆ジオコーディング
CLGeocoder
Reverse Geocoding a Location
func reverseGeocodeLocation(_ location: CLLocation,
completionHandler: @escaping CLGeocodeCompletionHandler)
Submits a reverse-geocoding request for the specified location.
Parameters
location
The location object containing the coordinate data to look up.
completionHandler
The handler block to execute with the results. The geocoder executes this handler regardless of whether the request was successful or unsuccessful. For more information on the format of this block, see CLGeocodeCompletionHandler.
Discussion
This method submits the specified location data to the geocoding server asynchronously and returns. When the request completes, the geocoder executes the provided completion handler on the main thread.
After initiating a reverse-geocoding request, do not attempt to initiate another reverse- or forward-geocoding request. Geocoding requests are rate-limited for each app, so making too many requests in a short period of time may cause some of the requests to fail. When the maximum rate is exceeded, the geocoder passes an error object with the value CLError.Code.network to your completion handler.
CLGeocodeCompletionHandler
A block to be called when a geocoding request is complete.
Declaration
typealias CLGeocodeCompletionHandler = ([CLPlacemark]?, Error?) -> Void
Discussion
Upon completion of a geocoding request, a block of this form is called to give you a chance to process the results. The parameters of this block are as follows:
placemark
Contains an array of CLPlacemark objects. For most geocoding requests, this array should contain only one entry. However, forward-geocoding requests may return multiple placemark objects in situations where the specified address could not be resolved to a single location.
If the request was canceled or there was an error in obtaining the placemark information, this parameter is nil.
error
Contains nil or an error object indicating why the placemark data was not returned. For a list of possible error codes, see CLError.Code.
CLPlacemark
A user-friendly description of a geographic coordinate, often containing the name of the place, its address, and other relevant information.
init(location: CLLocation, name: String?, postalAddress: CNPostalAddress?)
Creates and initializes a placemark object using the specified location and address information.
位置情報取得
CLLocationManager
The object that you use to start and stop the delivery of location-related events to your app.
startUpdatingLocation()
Starts the generation of updates that report the user’s current location.
func startUpdatingLocation()
このメソッドはすぐに戻ります。このメソッドを呼び出すと、ロケーションマネージャーは最初のロケーションフィックス(数秒かかる場合があります)を取得し、locationManager(_:didUpdateLocations :)メソッドを呼び出してデリゲートに通知します。その後、レシーバーは、主にdistanceFilterプロパティの値を超えたときに更新イベントを生成します。ただし、更新は他の状況で配信される場合があります。たとえば、ハードウェアがより正確な位置の読み取り値を収集した場合、受信者は別の通知を送信することがあります。
このメソッドを連続して数回呼び出しても、新しいイベントが自動的に生成されるわけではありません。ただし、その間にstopUpdatingLocation()を呼び出すと、次にこのメソッドを呼び出したときに新しい初期イベントが送信されます。
このサービスを開始してアプリが一時停止された場合、システムはアプリの実行が再開されるまで(フォアグラウンドまたはバックグラウンドで)イベントの配信を停止します。アプリが終了すると、新しいロケーションイベントの配信は完全に停止します。したがって、アプリがバックグラウンドでロケーションイベントを受信する必要がある場合は、Info.plistファイルにUIBackgroundModesキー(ロケーション値を含む)を含める必要があります。
locationManager(:didUpdateLocations :)メソッドを実装するデリゲートオブジェクトに加えて、潜在的なエラーに応答するためにlocationManager(:didFailWithError :)メソッドも実装する必要があります。
stopUpdatingLocation()
Stops the generation of location updates.
func stopUpdatingLocation()
コードが場所関連のイベントを受信する必要がなくなったときはいつでも、このメソッドを呼び出します。 イベント配信を無効にすると、受信者は、クライアントが位置データを必要としないときに、適切なハードウェアを無効にする(そしてそれによって電力を節約する)オプションを利用できます。 startUpdatingLocation()メソッドを再度呼び出すことで、いつでも場所の更新の生成を再開できます。
distanceFilter
The minimum distance (measured in meters) a device must move horizontally before an update event is generated.
更新イベントが生成される前に、デバイスが水平方向に移動する必要がある最小距離(メートル単位で測定)。
var distanceFilter: CLLocationDistance { get set }
この距離は、以前に配信された場所を基準にして測定されます。 値kCLDistanceFilterNoneを使用して、すべての動きを通知します。 このプロパティのデフォルト値はkCLDistanceFilterNoneです。
このプロパティは、標準の位置情報サービスと組み合わせてのみ使用され、重要な位置変更を監視する場合には使用されません。
kCLDistanceFilterNone
A constant indicating that all movement should be reported.
すべての動きを報告する必要があることを示す定数。
let kCLDistanceFilterNone: CLLocationDistance
この定数を使用して、場所の変更によって新しい場所の更新がトリガーされるように指定します。
CLLocationDistance
A distance measurement (measured in meters) from an existing location.
既存の場所からの距離測定(メートル単位で測定)。
typealias CLLocationDistance = Double
desiredAccuracy
The accuracy of the location data that your app wants to receive.
アプリが受信したい位置データの精度。
var desiredAccuracy: CLLocationAccuracy { get set }
位置情報サービスは、要求された精度を達成するために最善を尽くします。ただし、アプリは精度の低いデータを使用するように準備する必要があります。アプリが正確な位置情報へのアクセスを許可されていない場合(isAuthorizedForPreciseLocationがfalseの場合)、このプロパティの値を変更しても効果はありません。精度は常にkCLLocationAccuracyReducedです。
アプリの電池寿命への影響を減らすには、このプロパティに使用に適した値を割り当てます。たとえば、現在の場所が1 km以内でのみ必要な場合は、kCLLocationAccuracyKilometerを指定します。より正確な位置データも、利用可能になるまでに時間がかかります。
精度の高い位置データをリクエストした後も、アプリが一定期間、精度の低いデータを取得する可能性があります。要求された精度内で位置を特定するのにかかる時間中、位置情報サービスは、アプリが要求したほど正確ではない場合でも、利用可能なデータを提供し続けます。アプリは、データが利用可能になると、より正確な位置データを受け取ります。
iOSの場合、このプロパティのデフォルト値はkCLLocationAccuracyBestです。 macOS、watchOS、およびtvOSの場合、デフォルト値はkCLLocationAccuracyHundredMetersです。
このプロパティは、標準の位置情報サービスにのみ影響し、重要な位置変更を監視するためには影響しません。
kCLLocationAccuracyBest
The best level of accuracy available.
let kCLLocationAccuracyBest: CLLocationAccuracy
非常に高い精度が必要であるが、ナビゲーションアプリに必要な同じレベルの精度は必要ない場合は、この定数を指定します。
このレベルの精度は、isAuthorizedForPreciseLocationがtrueの場合にのみ使用できます。
kCLLocationAccuracyKilometer
Accurate to the nearest kilometer.
let kCLLocationAccuracyKilometer: CLLocationAccuracy
このレベルの精度は、isAuthorizedForPreciseLocationがtrueの場合にのみ使用できます。
CLLocationAccuracy
The accuracy of a geographical coordinate.
typealias CLLocationAccuracy = Double
CLLocationオブジェクトで報告される場合、精度値は、ユーザーの実際の位置を生成できる元の地理座標からのメートル数です。 CLLocationManagerオブジェクトのdesiredAccuracyプロパティに値を指定するときは、適切な定数の1つを使用してください。