Closed5

【Swift】CoreLocation 0->1

yoshitakayoshitaka

2点間の距離を計算するのにMapKitではなくこちらを使えないか

yoshitakayoshitaka

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
yoshitakayoshitaka

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でいいよね?

yoshitakayoshitaka

逆ジオコーディング

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.

yoshitakayoshitaka

位置情報取得

CLLocationManager

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つを使用してください。

このスクラップは2021/04/08にクローズされました