#2832 まで解決

This commit is contained in:
2024-04-20 12:34:49 +09:00
parent 797f01f76b
commit 33bd2b97a1
18 changed files with 517 additions and 147 deletions

View File

@ -24,7 +24,7 @@ import 'package:rogapp/services/perfecture_service.dart';
import 'package:rogapp/utils/database_gps.dart';
import 'package:rogapp/utils/database_helper.dart';
import 'package:rogapp/utils/location_controller.dart';
import 'package:rogapp/widgets/bottom_sheets/bottom_sheet_normal_point.dart';
import 'package:rogapp/widgets/bottom_sheet_new.dart';
import 'dart:async';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
@ -201,18 +201,33 @@ class DestinationController extends GetxController {
}
// 指定された目的地の位置情報に基づいてタイマーを開始する関数です。
// CP情報(fs)と現在位置からCPまでの距離distance を引数として渡します。
//
Future<void> startTimerLocation(GeoJSONFeature fs, double distance) async {
//print("---- in startTimer ----");
// print("---- is in rog is $is_in_rog ----");
double checkinRadious = fs.properties!['checkin_radius'] ?? double.infinity;
// CPのcheckin_radiusを取得し、checkinRadius に代入。値がなければinfinityとする。
if (checkinRadious >= distance) {
// checkinRadious以内に入ったら、
indexController.currentFeature.clear();
// indexController.currentFeatureを空にします。
Destination d = festuretoDestination(fs);
// festuretoDestination(fs)を呼び出し、GeoJSONFeatureオブジェクトfsからDestinationオブジェクトdを作成します。
// print("----- destination lenght is ${destinations.length} -----");
indexController.currentFeature.add(fs);
// indexController.currentFeatureにfsを追加します。
//print("---- before calling startTimer ----");
await startTimer(d, distance);
// startTimer(d, distance)を非同期で呼び出し、その完了を待機します。
return;
}
}
@ -227,43 +242,51 @@ class DestinationController extends GetxController {
//
// 要検討:エラーが発生した場合のエラーハンドリングを追加し、適切なメッセージを表示することを検討してください。
//
// 引数CPオブジェクトと現在地からCPまでの距離を渡す。
//
Future<void> startTimer(Destination d, double distance) async {
//print("=== passed dest is ${d.location_id} ${d.checkedin} ====");
skipGps = true;
//print("---- in startTimer ----");
//debugPrint("---- in startTimer ----");
DatabaseHelper db = DatabaseHelper.instance;
List<Destination> ds = await db.getDestinationByLatLon(d.lat!, d.lon!);
//指定位置のオブジェクトのリストを取得。
Destination? dss;
if (ds.isNotEmpty) {
dss = ds.first;
dss = ds.first; // 取得したリストが空でない場合、dss変数に最初の要素を代入します。
}
double checkinRadious = d.checkin_radious ?? double.infinity;
bool autoCheckin = d.auto_checkin == 0 ? false : true;
bool buyPoint = dss != null && dss.buy_point != null && dss.buy_point! > 0
// 変数を計算
double checkinRadious = d.checkin_radious ?? double.infinity; // 反応半径
bool autoCheckin = d.auto_checkin == 0 ? false : true; // 自動チェックイン
bool buyPoint = dss != null && dss.buy_point != null && dss.buy_point! > 0 // 買い物ポイント
? true
: false;
bool buyPointImageAdded =
bool buyPointImageAdded = // 買い物画像
dss != null && dss.buypoint_image != null ? true : false;
bool buyPointCanceled =
bool buyPointCanceled = // 買い物キャンセル
dss != null && dss.buy_point != null && dss.buy_point == 0
? true
: false;
bool locationAlreadyCheckedIn =
bool locationAlreadyCheckedIn = // チェックイン済みか
ds.isNotEmpty && ds[0].checkedin == true ? true : false;
bool isuserLoggedIn = indexController.currentUser.isNotEmpty ? true : false;
//make current destination
// print("---- checkin_radious $checkinRadious ----");
// print("---- distance $distance ----");
if (checkinRadious >= distance || checkinRadious == -1) {
bool isuserLoggedIn = indexController.currentUser.isNotEmpty ? true : false; // ログイン済みか
// 初期化。GPS信号が強くても弱くても
if (checkinRadious >= distance || checkinRadious == -1) { // 反応半径内か、-1(=距離を無視)
//currentSelectedDestinations.add(d);
// 目的地として登録する。
//debugPrint("目的地の初期化");
indexController.currentDestinationFeature.clear();
indexController.currentDestinationFeature.add(d);
// print(
// "---- checked in as ${indexController.currentDestinationFeature[0].checkedin.toString()} ----");
} else {
// ここには来ないのでは?
debugPrint("検出範囲外...");
// GPS信号が弱い場合でも、チェックインやゴールの処理を続行する
// comment out by Akira, 2024-4-5
// skipGps = false;
@ -282,7 +305,7 @@ class DestinationController extends GetxController {
);
*/
if (checkinRadious >= lastValidDistance || checkinRadious == -1) {
if (checkinRadious >= lastValidDistance || checkinRadious == -1) { // 反応半径内か、距離無視CPなら
indexController.currentDestinationFeature.clear();
indexController.currentDestinationFeature.add(d);
} else {
@ -295,11 +318,14 @@ class DestinationController extends GetxController {
}
}
if (isPhotoShoot.value == true) {
photos.clear();
if (shouldShowBottomSheet) {
if (isPhotoShoot.value == true) { // 写真撮影するなら ... isPhotoShoot=True にしてる場所がない。
debugPrint("isPhotoShoot.value == true ... will camera popup");
photos.clear(); // まず既存の写真をクリア
if (shouldShowBottomSheet) { // ボトムシートを使うべきなら
shouldShowBottomSheet = false;
if (d.cp == -1) return;
if (d.cp == -1) return; // CPは開始点なら戻る。
// カメラページをポップアップ
await showModalBottomSheet(
constraints:
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
@ -316,21 +342,28 @@ class DestinationController extends GetxController {
return;
}
// 写真撮影モードでない場合
if (ds.isEmpty) {
debugPrint("* 目的地がない場合 ==> 検知半径=-1の場合");
// print("----- in location popup cp - ${d.cp}----");
if (d.cp == -1 && DateTime.now().difference(lastGoalAt).inHours >= 24) {
if ((d.cp == -1 || d.cp==0 ) && DateTime.now().difference(lastGoalAt).inHours >= 24) {
debugPrint("**1: 開始CPで、最後にゴールしてから時間経過していれば、");
chekcs = 1;
//start
// print("~~~~ calling start ~~~~");
// print("---- in start -----");
chekcs = 1;
print("---- in start -----");
chekcs = 1; // スタート地点で前のゴールから24時間経過
isInCheckin.value = true;
isAtStart.value = true;
if (shouldShowBottomSheet) {
shouldShowBottomSheet = false;
shouldShowBottomSheet = false; // bottom_sheet を起動させない。
if (d.cp == -1||d.cp==-2||d.cp==0) return;
Widget bottomSheet = BottomSheetNormalPoint(destination: d);
Widget bottomSheet = BottomSheetNew(destination: d);
await showModalBottomSheet(
constraints:
@ -339,25 +372,30 @@ class DestinationController extends GetxController {
isScrollControlled: true,
builder: ((context) => bottomSheet)
).whenComplete(() {
shouldShowBottomSheet = true;
shouldShowBottomSheet = true; // bottom_sheet 起動許可
skipGps = false;
chekcs = 0;
chekcs = 0; // ボトムシートモード=1,
isAtStart.value = false;
isInCheckin.value = false;
});
}
return;
} else if (isInRog.value == true &&
indexController.rogMode.value == 1 &&
d.cp != -1) {
(locationAlreadyCheckedIn==null || locationAlreadyCheckedIn==false) &&
d.cp != -1 && d.cp != 0 && d.cp != -2) {
debugPrint("**2: 標準CP まだチェックインしていない。");
// print("----- in location popup checkin cp - ${d.cp}----");
chekcs = 2;
chekcs = 2; // 標準CP
isInCheckin.value = true;
if (shouldShowBottomSheet) {
shouldShowBottomSheet = false;
if (d.cp == -1||d.cp==-2||d.cp==0) return;
Widget bottomSheet = BottomSheetNormalPoint(destination: d);
Widget bottomSheet = BottomSheetNew(destination: d);
await showModalBottomSheet(
constraints:
@ -376,36 +414,49 @@ class DestinationController extends GetxController {
}
}
// 以降、検知範囲にある場合。
//debugPrint("検知範囲にある場合");
// print("---- location checkin radious ${d.checkin_radious} ----");
// print("---- already checked in $locationAlreadyCheckedIn ----");
if ((checkinRadious >= distance || checkinRadious == -1) &&
locationAlreadyCheckedIn == false &&
isInRog.value == true) {
if (autoCheckin) {
debugPrint("* 検知範囲または距離無視CPで、ゲーム中でまだチェックインしていない。");
if (autoCheckin) { // 自動チェックインなら
if (!checkingIn) {
debugPrint("** 自動チェックインの場合");
//print(
// "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ make checkin ${d.sub_loc_id}@@@@@@@@@@@");
makeCheckin(d, true, "");
if (d.cp != -1) {
rogainingCounted.value = true;
makeCheckin(d, true, ""); // チェックインして
if (d.cp != -1 && d.cp != -2 && d.cp != 0 ) {
rogainingCounted.value = true; // ゴール用チェックイン済み
}
skipGps = false;
}
return;
return; // 戻る
} else {
// それ以外
debugPrint("* 自動チェックイン以外の場合");
// print("--- hidden loc ${d.hidden_location} ----");
// ask for checkin
if (d.hidden_location != null &&
d.hidden_location == 0 &&
d.hidden_location == 0 && // 隠しCPフラグ==0 ... 通常CP
isInRog.value == true &&
d.cp != -1) {
d.cp != -1 && d.cp != -2 && d.cp != 0) {
// 隠しCPの場合、
debugPrint("**3 通常CPの場合");
chekcs = 3;
isInCheckin.value = true;
photos.clear();
// print("--- calling checkin ---");
if (shouldShowBottomSheet) {
shouldShowBottomSheet = false;
if (d.cp == -1) return;
await showModalBottomSheet(
constraints:
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
@ -422,14 +473,20 @@ class DestinationController extends GetxController {
});
}
return;
} else if (isInRog.value == true && d.cp != -1) {
} else if (isInRog.value == true &&
(locationAlreadyCheckedIn==null || locationAlreadyCheckedIn==false) &&
d.cp != -1 && d.cp != -2 && d.cp != 0) {
// 通常CP
debugPrint("**4 通常CP以外の場合....どんな場合?");
chekcs = 4;
isInCheckin.value = true;
if (shouldShowBottomSheet) {
shouldShowBottomSheet = false;
if (d.cp == -1||d.cp==-2||d.cp==0) return;
Widget bottomSheet = BottomSheetNormalPoint(destination: d);
Widget bottomSheet = BottomSheetNew(destination: d);
await showMaterialModalBottomSheet(
expand: true,
@ -453,13 +510,18 @@ class DestinationController extends GetxController {
buyPoint == true &&
buyPointCanceled == false &&
isInRog.value == true) {
// チェックイン後で買い物ポイントの場合。
debugPrint("**5 チェックイン後で買い物ポイントの場合");
chekcs = 5;
isInCheckin.value = true;
photos.clear();
//print("--- open buy point $buyPointImageAdded ${d.buypoint_image} ----");
if (shouldShowBottomSheet) {
shouldShowBottomSheet = false;
if (d.cp == -1) return;
if (d.cp == -1 && d.cp != -2 && d.cp != 0) return;
await showModalBottomSheet(
constraints:
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
@ -486,14 +548,17 @@ class DestinationController extends GetxController {
// print(
// "==== date diff is ${DateTime.now().difference(last_goal_at).inHours} ====");
if (isuserLoggedIn &&
d.cp == -1 &&
(d.cp == -2 || d.cp == 0 ) && // Goal CP
locationAlreadyCheckedIn &&
skip_10s == false) {
//check for rogaining
if (isAtGoal.value == false && rogainingCounted.value) {
//goal
//print("---- in goal -----");
chekcs = 5;
debugPrint("**5 ゴールで時計撮影の場合");
chekcs = 5; // Goal 時計撮影
isAtGoal.value = true;
photos.clear();
if (shouldShowBottomSheet) {
@ -514,18 +579,23 @@ class DestinationController extends GetxController {
});
}
return;
} else if (isInRog.value == false &&
indexController.rogMode.value == 1 &&
DateTime.now().difference(lastGoalAt).inHours >= 24) {
//start
//print("---- in start -----");
chekcs = 6;
debugPrint("**5 スタートの場合で最後のゴールから24時間経過している場合");
chekcs = 6; // start point
isAtStart.value = true;
if (shouldShowBottomSheet) {
shouldShowBottomSheet = false;
if (d.cp == -1||d.cp==-2||d.cp==0) return;
Widget bottomSheet = BottomSheetNormalPoint(destination: d);
if (d.cp != -1 && d.cp != 0) return;
Widget bottomSheet = BottomSheetNew(destination: d);
await showModalBottomSheet(
constraints:
@ -546,6 +616,7 @@ class DestinationController extends GetxController {
}
//print("==== _chekcs $chekcs ====");
if (chekcs == 0) {
//debugPrint("いずれにも当てはまらないので、処理スキップ");
skipGps = false;
}
return;
@ -639,7 +710,7 @@ class DestinationController extends GetxController {
//
Future<void> callforCheckin(Destination d) async {
bool autoCheckin = d.auto_checkin == 0 ? false : true;
//print("---- f- checkin ${d.sub_loc_id} ----");
print("---- f- checkin ${d.sub_loc_id} ----");
if (autoCheckin) {
if (!checkingIn) {
makeCheckin(d, true, "");
@ -717,20 +788,22 @@ class DestinationController extends GetxController {
// GPSデータをデータベースに追加する関数です。
//
Future<void> addGPStoDB(double la, double ln, {isCheckin = 0}) async {
//print("in addGPStoDB ${indexController.currentUser}");
//debugPrint("in addGPStoDB ${indexController.currentUser}");
try {
GpsDatabaseHelper db = GpsDatabaseHelper.instance;
final team_name = indexController.currentUser[0]["user"]['team_name'];
final event_code = indexController.currentUser[0]["user"]["event_code"];
GpsData gps_data = GpsData(
id: 0,
team_name: team_name,
event_code: event_code,
lat: la,
lon: ln,
is_checkin: isCheckin,
created_at: DateTime.now().millisecondsSinceEpoch);
var res = await db.insertGps(gps_data);
if(indexController.currentUser.length>0){
final team_name = indexController.currentUser[0]["user"]['team_name'];
final event_code = indexController.currentUser[0]["user"]["event_code"];
GpsData gps_data = GpsData(
id: 0,
team_name: team_name,
event_code: event_code,
lat: la,
lon: ln,
is_checkin: isCheckin,
created_at: DateTime.now().millisecondsSinceEpoch);
var res = await db.insertGps(gps_data);
}
} catch (err) {
print("errr ready gps ${err}");
return;
@ -752,25 +825,28 @@ class DestinationController extends GetxController {
game_started = true;
try {
indexController.locations[0].features.forEach((fs) async {
GeoJSONMultiPoint mp = fs!.geometry as GeoJSONMultiPoint;
LatLng pt = LatLng(mp.coordinates[0][1], mp.coordinates[0][0]);
// ここで、エラー
if( indexController.locations.length>0 ) {
indexController.locations[0].features.forEach((fs) async {
GeoJSONMultiPoint mp = fs!.geometry as GeoJSONMultiPoint;
LatLng pt = LatLng(mp.coordinates[0][1], mp.coordinates[0][0]);
double latFs = pt.latitude;
double lonFs = pt.longitude;
var distanceFs = const Distance();
double distFs = distanceFs.as(LengthUnit.Meter, LatLng(latFs, lonFs),
LatLng(currentLat, currentLon));
Destination des = festuretoDestination(fs);
double latFs = pt.latitude;
double lonFs = pt.longitude;
var distanceFs = const Distance();
double distFs = distanceFs.as(LengthUnit.Meter, LatLng(latFs, lonFs),
LatLng(currentLat, currentLon));
Destination des = festuretoDestination(fs);
if (distFs <= des.checkin_radious! && skipGps == false) {
await startTimerLocation(fs, distFs);
// Note: You cannot break out of forEach. If you need to stop processing, you might have to reconsider using forEach.
if (distFs <= des.checkin_radious! && skipGps == false) {
await startTimerLocation(fs, distFs);
// Note: You cannot break out of forEach. If you need to stop processing, you might have to reconsider using forEach.
}
});
if (gps_push_started == false) {
unawaited(pushGPStoServer());
}
});
if (gps_push_started == false) {
unawaited( pushGPStoServer() );
}
//print("--- 123 ---- $skip_gps----");
} catch (e) {
@ -980,14 +1056,13 @@ class DestinationController extends GetxController {
//final signalStrength = locationController.getGpsSignalStrength();
okToUseGPS = false;
double prevLat = currentLat; // 直前の位置
double prevLat = currentLat; // 直前の位置
double prevLon = currentLon;
if (position!=null){
if (position != null) {
currentLat = position.latitude;
currentLon = position.longitude;
okToUseGPS = true;
} else {
// 信号強度が低い場合、最後に取得した高いまたは中程度の位置情報を使用
// 但し、最初から高精度のものがない場合、どうするか?
@ -1012,7 +1087,7 @@ class DestinationController extends GetxController {
}
}
if (okToUseGPS && position!=null) {
if (okToUseGPS && position != null) {
// スタート位置から150m離れたら、ready_for_goal
if (distanceToStart() >= 150) {
ready_for_goal = true;
@ -1025,20 +1100,31 @@ class DestinationController extends GetxController {
LatLng(prevLat, prevLon)
);
Duration difference = lastGPSCollectedTime.difference(DateTime.now()).abs();
Duration difference = lastGPSCollectedTime.difference(DateTime.now())
.abs();
// 最後にGPS信号を取得した時刻から10秒以上経過、かつ10m以上経過普通に歩くスピード
if (difference.inSeconds >= 10 || distanceToDest >= 10) {
// print(
// "^^^^^^^^ GPS data collected ${DateFormat('kk:mm:ss \n EEE d MMM').format(DateTime.now())}, ^^^ ${position.latitude}, ${position.longitude}");
LogManager().addLog(
"GPS : $currentLat, $currentLon - ${DateTime.now().hour}:${DateTime.now().minute}:${DateTime.now().second}:${DateTime.now().microsecond}");
"GPS : $currentLat, $currentLon - ${DateTime
.now()
.hour}:${DateTime
.now()
.minute}:${DateTime
.now()
.second}:${DateTime
.now()
.microsecond}");
if (isInRog.value) {
await addGPStoDB(position.latitude, position.longitude);
lastGPSCollectedTime = DateTime.now();
}
}
}
} catch(e) {
debugPrint("Error: ${e}");
} finally {
/* Akira , 2024-4-5
if (position != null &&