課題
- 海の中で目印となる、GPSブイが欲しい
ニーズ
- GPSを活用して、位置情報を記録できる機能が欲しい
- 釣っている最中は釣り具以外何も持ちたくない
背景
釣行計画はスマートフォンで
- 釣りスポットの履歴をGPSで簡単に確認できることで、以前に釣った場所を特定しやすくなる。
- 釣りスポットの情報を見ながら、新しい釣りスポットを開拓する楽しみが増す。
- 潮の流れや季節の変化など環境情報をより正確に把握し、釣果向上につなげることができる。
現場まで航行は
GPS釣りスポット記録アプリの利用し目的地に行ける
船にGPS付き魚群探知機があれば便利
実釣
目印としてのGPSブイやマーキング装置を設定し、潮でどれだけ流れたか知りたい
ほしい機能
- GPSブイの投入
- ブイID、緯度経度記録
- ○ブイIは3個
- Xブイは3個
- GPSブイからの距離計測
- ○ブイから50m離れたら振動でお知ら
- Xブイから50m以内に入ったら振動でお知らせ
- ブイ使用履歴を作成
- 記録は5個
最初の一歩 マップ表示
- >|Swift|
-
import SwiftUI
import MapKit
-
struct ContentView: View {
var body: some View {
Map()
}
}
- ||<
場所指定
- 緯度経度と表示エリアを設定
>|Swift|
import SwiftUI
import MapKit
struct ContentView: View {
var body: some View {
@State var region = MKCoordinateRegion(
center : CLLocationCoordinate2D (
latitude: 34.349, // 緯度
longitude: 136.697 // 経度
),
latitudinalMeters: 500.0, // 南北の表示エリア(単位:メートル)
longitudinalMeters: 500.0 // 東西の表示エリア(単位:メートル)
)
Map(coordinateRegion: $region)
}
}
||<
現在位置表示
- 緯度経度取得 LocationManagerクラス作成
- ググって、情報をまとめました。みなさんありがとうございます
>|Swift|
import WatchKit
import MapKit
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
// CLLocationManagerをインスタンス化
let manager = CLLocationManager()
// 更新のたびに変化するので@Publishedを付与して観測
@Published var region = MKCoordinateRegion()
override init() {
super.init() // スーパクラスイニシャライズ
manager.delegate = self //自身をデリゲートプロパティに
manager.requestWhenInUseAuthorization() // 位置情報を利用許可を要求
manager.desiredAccuracy = kCLLocationAccuracyBest // 最高精度の位置情報を要求
manager.distanceFilter = 3.0 // 更新距離(m)
manager.startUpdatingLocation() //現在位置アップデート生成開始
}
// 領域の更新をするデリゲートメソッド
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// 配列の最後に最新のロケーションが格納される
// map関数を使って全要素にアクセス map{ $0←要素に参照 }
locations.last.map {
let center = CLLocationCoordinate2D(
latitude: $0.coordinate.latitude,
longitude: $0.coordinate.longitude)
// 地図を表示するための領域を再構築
region = MKCoordinateRegion(
center: center,
latitudinalMeters: 100.0,
longitudinalMeters: 100.0
)
}
}
}
||<
- View改良
- ググって、情報をまとめました。みなさんありがとうございます
>|Swift|
import SwiftUI
import MapKit
struct ContentView: View {
@ObservedObject var manager = LocationManager()
//ユーザートラッキングモードを追従モード変数 .follow ユーザーを追跡 .none ユーザーの追跡を停止
@State var trackingMode = MapUserTrackingMode.follow
struct ContentView: View {
@ObservedObject var manager = LocationManager()
//ユーザートラッキングモードを追従モード変数 .follow ユーザーを追跡 .none ユーザーの追跡を停止
@State var trackingMode = MapUserTrackingMode.follow
var body: some View {
ZStack{
Map(coordinateRegion: $manager.region, //状態変数をバインディング指定
showsUserLocation: true, // マップ上にユーザーの場所を表示するオプションをBool値で指定
userTrackingMode: $trackingMode
)
.edgesIgnoringSafeArea(.bottom)
.edgesIgnoringSafeArea(.top)
}
}
}
- ||<
- 動かしてみる
-
Xで見てください
AppleWatchで位置取得できるかなぁ pic.twitter.com/mSvotIko4U
— shigu (@yshigu) 2024年4月10日
GPSブイ設置
- 緯度経度取得 LocationManagerクラスに、記録機能追加
>|Swift|
func reloadRegion (bouyNo: Int){
// オプショナルバインディング
if let location = manager.location {
let center = CLLocationCoordinate2D(
latitude: location.coordinate.latitude,
longitude: location.coordinate.longitude
)
if bouyNo == 0 || bouyNo == 1 || bouyNo == 2 {
//GPSブイ投下を記録
pointList[bouyNo] = Point(
name: "No.\(bouyNo + 1)",
latitude: location.coordinate.latitude ,
longitude: location.coordinate.longitude
)
region = MKCoordinateRegion(
center: center,
latitudinalMeters: 50.0,
longitudinalMeters: 50.0
)
} else {
//ロケーションボタン
region = MKCoordinateRegion(
center: center,
latitudinalMeters: 200.0,
longitudinalMeters: 200.0
)
}
}
}
||<
- View改良し
- ブイ投下ボタン追加
- ブイ番号表示
>|Swift|
struct Point: Identifiable {
let id = UUID() //ユニークID
let name: String
let latitude: Double // 緯度
let longitude: Double // 経度
// 座標
var coordinate: CLLocationCoordinate2D {
CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
}
var pointList = [
Point(name: "1", latitude: 35.709152712026265, longitude: 139.80771829999996),
Point(name: "2", latitude: 35.711554715026265, longitude: 139.81371829999996),
Point(name: "3", latitude: 35.712527719026265, longitude: 139.81071829999996)
]
struct ContentView: View {
@ObservedObject var manager = LocationManager()
//ユーザートラッキングモードを追従モード変数 .follow ユーザーを追跡 .none ユーザーの追跡を停止
@State var trackingMode = MapUserTrackingMode.follow
var body: some View {
ZStack{
Map(coordinateRegion: $manager.region, //状態変数をバインディング指定
showsUserLocation: true, //ユーザーの場所を表示するオプションをBool値で指定
userTrackingMode: $trackingMode,
annotationItems: pointList,
annotationContent: { (pointList) in
MapAnnotation(coordinate: pointList.coordinate) {
VStack {
Image(systemName: "mappin")
.foregroundColor(.orange)
.font(.system(size: 20))
Text(pointList.name)
.foregroundColor(.orange)
.font(.system(size: 12))
}
}
}
)
.edgesIgnoringSafeArea(.all)
.edgesIgnoringSafeArea(.bottom)
.edgesIgnoringSafeArea(.top)
VStack{
Spacer()
HStack{
Button(action: {
manager.reloadRegion(bouyNo: 0)
}) {
Image(systemName: "mappin.circle.fill")
.foregroundColor(.white)
.font(.system(size: 12))
Text("1")
.foregroundColor(.white)
.font(.system(size: 12))
}
.frame(width: 41, height: 25)
.cornerRadius(30.0)
Button(action: {
manager.reloadRegion(bouyNo: 1)
}) {
Image(systemName: "mappin.circle.fill")
.foregroundColor(.white)
.font(.system(size: 12))
Text("2")
.foregroundColor(.white)
.font(.system(size: 12))
}
.frame(width: 41, height: 25)
.cornerRadius(30.0)
Button(action: {
manager.reloadRegion(bouyNo: 2)
}) {
Image(systemName: "mappin.circle.fill")
.foregroundColor(.white)
.font(.system(size: 12))
Text("3")
.foregroundColor(.white)
.font(.system(size: 12))
}
.frame(width: 41, height: 25)
.cornerRadius(30.0)
Button(action: {
manager.reloadRegion(bouyNo: 3)
}) {
Image(systemName: "location.fill")
.foregroundColor(.white)
.font(.system(size: 16))
}
.frame(width: 32, height: 25)
.cornerRadius(30.0)
}
.background(Color(red: 0.4, green: 0.5, blue: 0.2)) //背景色
.cornerRadius(30.0)
}
}
}
}
||<
-
- 動画は下記を参照
- 動画は下記を参照
GPSブイとの距離
- 次回、記載します