大幅変更&環境バージョンアップ
This commit is contained in:
@ -2,7 +2,9 @@
|
||||
|
||||
|
||||
class ConstValues{
|
||||
static const container_svr = "http://container.intranet.sumasen.net:8100";
|
||||
//static const container_svr = "http://container.intranet.sumasen.net:8100";
|
||||
//static const server_uri = "https://rogaining.intranet.sumasen.net";
|
||||
static const container_svr = "http://container.sumasen.net:8100";
|
||||
static const server_uri = "https://rogaining.sumasen.net";
|
||||
static const dev_server = "http://localhost:8100";
|
||||
static const dev_ip_server = "http://192.168.8.100:8100";
|
||||
@ -10,6 +12,7 @@ class ConstValues{
|
||||
static const dev_home_ip_mserver = "http://192.168.1.10:8100";
|
||||
|
||||
static String currentServer(){
|
||||
//return dev_ip_server;
|
||||
return server_uri;
|
||||
}
|
||||
}
|
||||
|
||||
102
lib/utils/database_gps.dart
Normal file
102
lib/utils/database_gps.dart
Normal file
@ -0,0 +1,102 @@
|
||||
import 'dart:io';
|
||||
import 'package:path/path.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:gifunavi/model/gps_data.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
class GpsDatabaseHelper {
|
||||
GpsDatabaseHelper._privateConstructor();
|
||||
static final GpsDatabaseHelper instance =
|
||||
GpsDatabaseHelper._privateConstructor();
|
||||
static Database? _database;
|
||||
Future<Database> get database async => _database ??= await _initDatabase();
|
||||
|
||||
Future<Database> _initDatabase() async {
|
||||
Directory documentDirectory = await getApplicationDocumentsDirectory();
|
||||
String path = join(documentDirectory.path, 'rog.db');
|
||||
// return await openDatabase(
|
||||
// path,
|
||||
// version: 1,
|
||||
// onCreate: _onCreate,
|
||||
// );
|
||||
return openDatabase(
|
||||
join(
|
||||
await getDatabasesPath(),
|
||||
'gps.db',
|
||||
),
|
||||
version: 1,
|
||||
onCreate: _onCreate);
|
||||
}
|
||||
|
||||
Future _onCreate(Database db, int version) async {
|
||||
await db.execute('''
|
||||
CREATE TABLE gps(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
team_name TEXT,
|
||||
event_code TEXT,
|
||||
lat REAL,
|
||||
lon REAL,
|
||||
is_checkin int,
|
||||
created_at INTEGER,
|
||||
is_synced INTEGER DEFAULT 0
|
||||
)
|
||||
''');
|
||||
}
|
||||
|
||||
Future<int> insertGps(GpsData gps) async {
|
||||
try {
|
||||
//print("---- try insering ${gps.toMap()}");
|
||||
Database db = await instance.database;
|
||||
int? nextOrder =
|
||||
Sqflite.firstIntValue(await db.rawQuery('SELECT MAX(id) FROM gps'));
|
||||
nextOrder = nextOrder ?? 0;
|
||||
nextOrder = nextOrder + 1;
|
||||
gps.id = nextOrder;
|
||||
//print("---- insering ${gps.toMap()}");
|
||||
int res = await db.insert(
|
||||
'gps',
|
||||
gps.toMap(),
|
||||
conflictAlgorithm: ConflictAlgorithm.replace,
|
||||
);
|
||||
//print("------ database helper insert $res-----------::::::::");
|
||||
return res;
|
||||
} catch (err) {
|
||||
print("------ error $err-----------::::::::");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<GpsData>> getGPSData(String teamName, String eventCode) async {
|
||||
Database db = await instance.database;
|
||||
var gpss = await db.query('gps',
|
||||
where: "team_name = ? and event_code = ?",
|
||||
whereArgs: [teamName, eventCode],
|
||||
orderBy: 'created_at');
|
||||
List<GpsData> gpsDatas =
|
||||
gpss.isNotEmpty ? gpss.map((e) => GpsData.fromMap(e)).toList() : [];
|
||||
//print("--------- db list $gpsDatas");
|
||||
return gpsDatas;
|
||||
}
|
||||
|
||||
Future<List<GpsData>> getUnsyncedGPSData(
|
||||
String teamName, String eventCode) async {
|
||||
Database db = await instance.database;
|
||||
var gpss = await db.query('gps',
|
||||
where: 'team_name = ? and event_code = ? and is_synced = 0',
|
||||
whereArgs: [teamName, eventCode],
|
||||
orderBy: 'created_at');
|
||||
return gpss.isNotEmpty ? gpss.map((e) => GpsData.fromMap(e)).toList() : [];
|
||||
}
|
||||
|
||||
Future<void> setSyncData(List<GpsData> data) async {
|
||||
Database db = await instance.database;
|
||||
for (var record in data) {
|
||||
await db.update(
|
||||
'gps',
|
||||
{'is_synced': 1},
|
||||
where: 'id = ?',
|
||||
whereArgs: [record.id],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,12 @@
|
||||
import 'dart:io';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:rogapp/model/destination.dart';
|
||||
import 'package:gifunavi/model/destination.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
import 'package:path/path.dart';
|
||||
|
||||
import '../model/rog.dart';
|
||||
|
||||
class DatabaseHelper{
|
||||
class DatabaseHelper {
|
||||
DatabaseHelper._privateConstructor();
|
||||
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
|
||||
|
||||
@ -21,7 +21,13 @@ class DatabaseHelper{
|
||||
// version: 1,
|
||||
// onCreate: _onCreate,
|
||||
// );
|
||||
return openDatabase(join(await getDatabasesPath(), 'rog.db',), version: 1, onCreate: _onCreate);
|
||||
return openDatabase(
|
||||
join(
|
||||
await getDatabasesPath(),
|
||||
'rog.db',
|
||||
),
|
||||
version: 1,
|
||||
onCreate: _onCreate);
|
||||
}
|
||||
|
||||
Future _onCreate(Database db, int version) async {
|
||||
@ -48,11 +54,16 @@ class DatabaseHelper{
|
||||
cp REAL,
|
||||
checkin_point REAL,
|
||||
buy_point REAL,
|
||||
hidden_location INTEGER
|
||||
hidden_location INTEGER,
|
||||
checkin_image TEXT,
|
||||
buypoint_image TEXT,
|
||||
forced_checkin INTEGER,
|
||||
recipt_times INTEGER,
|
||||
tags TEXT
|
||||
)
|
||||
''');
|
||||
|
||||
await db.execute('''
|
||||
await db.execute('''
|
||||
CREATE TABLE rogaining(
|
||||
rog_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
course_id INTEGER,
|
||||
@ -65,7 +76,7 @@ class DatabaseHelper{
|
||||
)
|
||||
''');
|
||||
|
||||
await db.execute('''
|
||||
await db.execute('''
|
||||
CREATE TABLE rog(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
team_name TEXT,
|
||||
@ -77,86 +88,72 @@ class DatabaseHelper{
|
||||
rog_action_type INTEGER
|
||||
)
|
||||
''');
|
||||
|
||||
}
|
||||
|
||||
Future<List<Rog>> allRogianing() async {
|
||||
Database db = await instance.database;
|
||||
var rog = await db.query('rog');
|
||||
List<Rog> roglist = rog.isNotEmpty ?
|
||||
rog.map((e) => Rog.fromMap(e)).toList() : [];
|
||||
print("--------- $rog");
|
||||
List<Rog> roglist =
|
||||
rog.isNotEmpty ? rog.map((e) => Rog.fromMap(e)).toList() : [];
|
||||
//print("--------- $rog");
|
||||
return roglist;
|
||||
}
|
||||
|
||||
|
||||
Future<List<Rog>> getRogainingByLatLon(double lat, double lon) async {
|
||||
Database db = await instance.database;
|
||||
var rog = await db.query('rog', where: "lat = $lat and lon= $lon");
|
||||
List<Rog> roglist = rog.isNotEmpty
|
||||
? rog.map((e) => Rog.fromMap(e)).toList() : [];
|
||||
List<Rog> roglist =
|
||||
rog.isNotEmpty ? rog.map((e) => Rog.fromMap(e)).toList() : [];
|
||||
return roglist;
|
||||
}
|
||||
|
||||
Future clearSelection() async {
|
||||
Database db = await instance.database;
|
||||
Map<String, dynamic> rowClear = {
|
||||
"selected": false
|
||||
};
|
||||
return await db.update(
|
||||
"destination",
|
||||
rowClear
|
||||
);
|
||||
Map<String, dynamic> rowClear = {"selected": false};
|
||||
return await db.update("destination", rowClear);
|
||||
}
|
||||
|
||||
Future<int> toggleSelecttion(Destination dest) async {
|
||||
Database db = await instance.database;
|
||||
|
||||
|
||||
bool val = !dest.selected!;
|
||||
Map<String, dynamic> rowTarget = {
|
||||
"selected": val
|
||||
};
|
||||
Map<String, dynamic> rowTarget = {"selected": val};
|
||||
|
||||
await clearSelection();
|
||||
|
||||
return await db.update(
|
||||
"destination",
|
||||
rowTarget,
|
||||
where: 'location_id = ?',
|
||||
whereArgs: [dest.location_id!]
|
||||
);
|
||||
return await db.update("destination", rowTarget,
|
||||
where: 'location_id = ?', whereArgs: [dest.location_id!]);
|
||||
}
|
||||
|
||||
Future<int> deleteRogaining(int id) async {
|
||||
Database db = await instance.database;
|
||||
var rog = await db.delete('rog', where: "id = $id");
|
||||
int ret = rog > 0 ? rog : -1;
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Future<void> deleteAllRogaining() async {
|
||||
Database db = await instance.database;
|
||||
await db.delete('rog');
|
||||
}
|
||||
|
||||
|
||||
Future<bool>isRogAlreadyAvailable(int id) async{
|
||||
Future<bool> isRogAlreadyAvailable(int id) async {
|
||||
Database db = await instance.database;
|
||||
var rog = await db.query('rog', where: "id = $id");
|
||||
return rog.isNotEmpty ? true : false;
|
||||
}
|
||||
|
||||
Future<int?>latestGoal() async{
|
||||
Future<int?> latestGoal() async {
|
||||
Database db = await instance.database;
|
||||
return Sqflite.firstIntValue(await db.rawQuery('SELECT MAX(checkintime) FROM rog'));
|
||||
|
||||
return Sqflite.firstIntValue(
|
||||
await db.rawQuery('SELECT MAX(checkintime) FROM rog'));
|
||||
}
|
||||
|
||||
Future<int> insertRogaining(Rog rog) async {
|
||||
Database db = await instance.database;
|
||||
int? nextOrder = Sqflite.firstIntValue(await db.rawQuery('SELECT MAX(id) FROM rog'));
|
||||
int? nextOrder =
|
||||
Sqflite.firstIntValue(await db.rawQuery('SELECT MAX(id) FROM rog'));
|
||||
nextOrder = nextOrder ?? 0;
|
||||
nextOrder = nextOrder + 1;
|
||||
rog.id = nextOrder;
|
||||
@ -165,68 +162,63 @@ class DatabaseHelper{
|
||||
rog.toMap(),
|
||||
conflictAlgorithm: ConflictAlgorithm.replace,
|
||||
);
|
||||
print("------ database helper insert $res-----------::::::::");
|
||||
//print("------ database helper insert $res-----------::::::::");
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Future<List<Destination>> getDestinations() async {
|
||||
Database db = await instance.database;
|
||||
var dest = await db.query('destination', orderBy: 'list_order');
|
||||
List<Destination> destList = dest.isNotEmpty ?
|
||||
dest.map((e) => Destination.fromMap(e)).toList() : [];
|
||||
print("--------- $destList");
|
||||
List<Destination> destList =
|
||||
dest.isNotEmpty ? dest.map((e) => Destination.fromMap(e)).toList() : [];
|
||||
//print("--------- $destList");
|
||||
return destList;
|
||||
}
|
||||
|
||||
Future<List<Destination>> getDestinationById(int id) async {
|
||||
Database db = await instance.database;
|
||||
var rog = await db.query('destination', where: "location_id = $id");
|
||||
List<Destination> deslist = rog.isNotEmpty
|
||||
? rog.map((e) => Destination.fromMap(e)).toList() : [];
|
||||
List<Destination> deslist =
|
||||
rog.isNotEmpty ? rog.map((e) => Destination.fromMap(e)).toList() : [];
|
||||
return deslist;
|
||||
}
|
||||
|
||||
|
||||
Future<List<Destination>> getDestinationByLatLon(double lat, double lon) async {
|
||||
Future<List<Destination>> getDestinationByLatLon(
|
||||
double lat, double lon) async {
|
||||
Database db = await instance.database;
|
||||
var dest = await db.query('destination', where: "lat = $lat and lon= $lon", orderBy: 'list_order');
|
||||
List<Destination> destList = dest.isNotEmpty
|
||||
? dest.map((e) => Destination.fromMap(e)).toList() : [];
|
||||
var dest = await db.query('destination',
|
||||
where: "lat = $lat and lon= $lon", orderBy: 'list_order');
|
||||
List<Destination> destList =
|
||||
dest.isNotEmpty ? dest.map((e) => Destination.fromMap(e)).toList() : [];
|
||||
return destList;
|
||||
}
|
||||
|
||||
Future<int> deleteDestination(int locationId) async {
|
||||
Database db = await instance.database;
|
||||
var dest = await db.delete('destination', where: "location_id = $locationId");
|
||||
var dest =
|
||||
await db.delete('destination', where: "location_id = $locationId");
|
||||
int ret = dest > 0 ? dest : -1;
|
||||
|
||||
//after deleting set correct order
|
||||
await setOrder();
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Future<void>setOrder() async {
|
||||
Future<void> setOrder() async {
|
||||
Database db = await instance.database;
|
||||
var byOrder = await db.query('destination', orderBy: 'list_order');
|
||||
|
||||
List<Destination> desDb = byOrder.isNotEmpty
|
||||
? byOrder.map((e) => Destination.fromMap(e)).toList() : [];
|
||||
? byOrder.map((e) => Destination.fromMap(e)).toList()
|
||||
: [];
|
||||
|
||||
int order = 1;
|
||||
for( Destination d in desDb){
|
||||
for (Destination d in desDb) {
|
||||
Map<String, dynamic> rowTarget = {"list_order": order};
|
||||
|
||||
Map<String, dynamic> rowTarget = {
|
||||
"list_order": order
|
||||
};
|
||||
|
||||
await db.update(
|
||||
"destination",
|
||||
rowTarget,
|
||||
where: 'location_id = ?',
|
||||
whereArgs: [d.location_id]
|
||||
);
|
||||
await db.update("destination", rowTarget,
|
||||
where: 'location_id = ?', whereArgs: [d.location_id]);
|
||||
|
||||
order += 1;
|
||||
}
|
||||
@ -237,15 +229,18 @@ class DatabaseHelper{
|
||||
await db.delete('destination');
|
||||
}
|
||||
|
||||
Future<bool>isAlreadyAvailable(int locationId) async{
|
||||
Future<bool> isAlreadyAvailable(int locationId) async {
|
||||
Database db = await instance.database;
|
||||
var dest = await db.query('destination', where: "location_id = $locationId");
|
||||
var dest =
|
||||
await db.query('destination', where: "location_id = $locationId");
|
||||
return dest.isNotEmpty ? true : false;
|
||||
}
|
||||
|
||||
Future<int> insertDestination(Destination dest) async {
|
||||
await deleteDestination(dest.location_id!);
|
||||
Database db = await instance.database;
|
||||
int? nextOrder = Sqflite.firstIntValue(await db.rawQuery('SELECT MAX(list_order) FROM destination'));
|
||||
int? nextOrder = Sqflite.firstIntValue(
|
||||
await db.rawQuery('SELECT MAX(list_order) FROM destination'));
|
||||
nextOrder = nextOrder ?? 0;
|
||||
nextOrder = nextOrder + 1;
|
||||
dest.list_order = nextOrder;
|
||||
@ -258,39 +253,50 @@ class DatabaseHelper{
|
||||
return res;
|
||||
}
|
||||
|
||||
Future<int> updateAction(Destination destination, bool checkin)async {
|
||||
Future<int> updateCancelBuyPoint(Destination destination) async {
|
||||
//print("---- updating puypint image in db -----");
|
||||
Database db = await instance.database;
|
||||
int act = checkin == false ? 0 : 1;
|
||||
Map<String, dynamic> row = {
|
||||
"checkedin": act
|
||||
};
|
||||
return await db.update(
|
||||
"destination",
|
||||
row,
|
||||
where: 'location_id = ?',
|
||||
whereArgs: [destination.location_id!]
|
||||
);
|
||||
Map<String, dynamic> row = {"buy_point": 0};
|
||||
return await db.update("destination", row,
|
||||
where: 'location_id = ?', whereArgs: [destination.location_id!]);
|
||||
}
|
||||
|
||||
Future<void> updateOrder(Destination d, int dir)async {
|
||||
Future<int> updateBuyPoint(Destination destination, String imageUrl) async {
|
||||
//print("---- updating puypint image in db -----");
|
||||
Database db = await instance.database;
|
||||
var target = await db.query('destination', where: "list_order = ${d.list_order! + dir}");
|
||||
var dest = await db.query('destination', where: "location_id = ${d.location_id}");
|
||||
Map<String, dynamic> row = {"buypoint_image": imageUrl};
|
||||
return await db.update("destination", row,
|
||||
where: 'location_id = ?', whereArgs: [destination.location_id!]);
|
||||
}
|
||||
|
||||
print("--- target in db is $target");
|
||||
print("--- destine in db is $dest");
|
||||
Future<int> updateAction(Destination destination, bool checkin) async {
|
||||
Database db = await instance.database;
|
||||
int act = checkin == false ? 0 : 1;
|
||||
Map<String, dynamic> row = {"checkedin": act};
|
||||
return await db.update("destination", row,
|
||||
where: 'location_id = ?', whereArgs: [destination.location_id!]);
|
||||
}
|
||||
|
||||
if(target.isNotEmpty){
|
||||
Future<void> updateOrder(Destination d, int dir) async {
|
||||
Database db = await instance.database;
|
||||
var target = await db.query('destination',
|
||||
where: "list_order = ${d.list_order! + dir}");
|
||||
var dest =
|
||||
await db.query('destination', where: "location_id = ${d.location_id}");
|
||||
|
||||
// print("--- target in db is $target");
|
||||
// print("--- destine in db is $dest");
|
||||
|
||||
if (target.isNotEmpty) {
|
||||
List<Destination> targetIndb = target.isNotEmpty
|
||||
? target.map((e) => Destination.fromMap(e)).toList() : [];
|
||||
? target.map((e) => Destination.fromMap(e)).toList()
|
||||
: [];
|
||||
|
||||
List<Destination> destIndb = dest.isNotEmpty
|
||||
? dest.map((e) => Destination.fromMap(e)).toList() : [];
|
||||
? dest.map((e) => Destination.fromMap(e)).toList()
|
||||
: [];
|
||||
|
||||
Map<String, dynamic> rowTarget = {
|
||||
"list_order": d.list_order
|
||||
};
|
||||
Map<String, dynamic> rowTarget = {"list_order": d.list_order};
|
||||
|
||||
Map<String, dynamic> rowDes = {
|
||||
"list_order": destIndb[0].list_order! + dir
|
||||
@ -299,19 +305,11 @@ class DatabaseHelper{
|
||||
// print("--- target destination is ${target_indb[0].location_id}");
|
||||
// print("--- destine destination is is ${dest_indb[0].location_id}");
|
||||
|
||||
await db.update(
|
||||
"destination",
|
||||
rowTarget,
|
||||
where: 'location_id = ?',
|
||||
whereArgs: [targetIndb[0].location_id]
|
||||
);
|
||||
await db.update("destination", rowTarget,
|
||||
where: 'location_id = ?', whereArgs: [targetIndb[0].location_id]);
|
||||
|
||||
await db.update(
|
||||
"destination",
|
||||
rowDes,
|
||||
where: 'location_id = ?',
|
||||
whereArgs: [destIndb[0].location_id]
|
||||
);
|
||||
await db.update("destination", rowDes,
|
||||
where: 'location_id = ?', whereArgs: [destIndb[0].location_id]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,6 +317,4 @@ class DatabaseHelper{
|
||||
// Database db = await instance.database;
|
||||
// return await Sqflite.firstIntValue(await db.rawQuery("SELECT COUNT(*) FROM incidents"));
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
372
lib/utils/location_controller.dart
Normal file
372
lib/utils/location_controller.dart
Normal file
@ -0,0 +1,372 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
//import 'package:gifunavi/widgets/debug_widget.dart';
|
||||
import 'package:flutter_map_location_marker/flutter_map_location_marker.dart';
|
||||
import 'package:gifunavi/pages/destination/destination_controller.dart';
|
||||
import 'package:gifunavi/pages/permission/permission.dart';
|
||||
|
||||
// LocationControllerクラスは、GetxControllerを継承したクラスであり、位置情報の管理を担当しています。
|
||||
// LocationControllerは以下の機能を提供しています。
|
||||
// LocationControllerは、アプリ全体で位置情報を一元管理するための重要なコンポーネントです。
|
||||
// 他のコンポーネントは、LocationControllerから位置情報を取得し、位置情報に関連する機能を実装することができます。
|
||||
//
|
||||
// Features:
|
||||
// * 現在の位置情報を保持し、他のコンポーネントからアクセスできるようにします。
|
||||
// * 位置情報のストリームを管理し、位置情報の更新を監視します。
|
||||
// * 位置情報サービスの有効性と権限の確認を行い、適切な処理を行います。
|
||||
// * 位置情報のストリームを開始、停止、再開する機能を提供します。
|
||||
// * 位置マーカーの位置情報をStreamControllerを通じて他のコンポーネントに通知します。
|
||||
//
|
||||
// Logic:
|
||||
// 1. startPositionStreamメソッドで、Geolocator.getPositionStreamを使用して位置情報のストリームを開始します。
|
||||
// 2. ストリームから位置情報を受信すると、LocationMarkerPositionオブジェクトを作成し、locationMarkerPositionStreamControllerに追加します。
|
||||
// 3. 位置情報が取得できなかった場合や、エラーが発生した場合は、適切な処理を行います。
|
||||
// 4. stopPositionStreamメソッドで、位置情報のストリームを一時停止することができます。
|
||||
// 5. resumePositionStreamメソッドで、一時停止中の位置情報のストリームを再開することができます。
|
||||
// 6. onCloseメソッドで、コントローラーのクローズ時に位置情報のストリームをキャンセルします。
|
||||
//
|
||||
class LocationController extends GetxController {
|
||||
// Reactive variable to hold the current position
|
||||
Rx<Position?> currentPosition = Rx<Position?>(null);
|
||||
// 現在の位置情報を保持するReactive変数です。Rx<Position?>型で宣言されています。
|
||||
|
||||
// Subscription to the position stream
|
||||
StreamSubscription<Position>? positionStream;
|
||||
// 位置情報のストリームを保持する変数です。StreamSubscription<Position>型で宣言されています。
|
||||
|
||||
LatLng? lastValidLocation;
|
||||
DateTime lastGPSDataReceivedTime = DateTime.now(); // 最後にGPSデータを受け取った時刻
|
||||
|
||||
bool gpsDebugMode = true;
|
||||
/*
|
||||
// GPSシミュレーション用のメソッドを追加
|
||||
void setSimulationMode(bool value) {
|
||||
isSimulationMode = value;
|
||||
}
|
||||
|
||||
// ====== Akira , GPS信号強度をシミュレート ==== ここから
|
||||
//
|
||||
|
||||
//===== Akira Added 2024-4-9 start
|
||||
// GPSシミュレーション用の変数を追加 ===> 本番では false にする。
|
||||
bool isSimulationMode = false;
|
||||
|
||||
// GPS信号強度をシミュレートするための変数
|
||||
final Rx<String> _simulatedSignalStrength = Rx<String>('high');
|
||||
|
||||
// GPS信号強度をシミュレートするための関数
|
||||
void setSimulatedSignalStrength(String strength) {
|
||||
if( strength!='real') {
|
||||
isSimulationMode = true;
|
||||
_simulatedSignalStrength.value = strength;
|
||||
latestSignalStrength.value = strength;
|
||||
}else{
|
||||
isSimulationMode = false;
|
||||
_simulatedSignalStrength.value = strength;
|
||||
}
|
||||
}
|
||||
|
||||
// シミュレートされた信号強度を取得するための関数
|
||||
String getSimulatedSignalStrength() {
|
||||
//debugPrint("strength : ${_simulatedSignalStrength.value}");
|
||||
return _simulatedSignalStrength.value;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
//
|
||||
// ====== Akira , GPS信号強度をシミュレート ==== ここまで
|
||||
|
||||
|
||||
// GPS信号が弱い場合のフラグ. 本番では、false,high にする。
|
||||
bool isGpsSignalWeak = false;
|
||||
RxString latestSignalStrength = 'high'.obs;
|
||||
//final _latestSignalStrength = 'low'.obs; // 初期値を設定
|
||||
//String get latestSignalStrength => _latestSignalStrength.value;
|
||||
Stream<String> get gpsSignalStrengthStream => latestSignalStrength.stream;
|
||||
|
||||
bool isRunningBackgroundGPS=false;
|
||||
int activeEngineCount = 0;
|
||||
|
||||
// GPS信号の強弱を判断するメソッドを追加. 10m 以内:強、30m以内:中、それ以上:弱
|
||||
//
|
||||
String getGpsSignalStrength(Position? position) {
|
||||
if (isSimulationMode.value) {
|
||||
return getSimulatedSignalStrength();
|
||||
}
|
||||
|
||||
if (position == null) {
|
||||
//gpsDebugMode ? debugPrint("getGpsSignalStrength position is null.") : null;
|
||||
latestSignalStrength.value = "low";
|
||||
isGpsSignalWeak = true;
|
||||
return 'low';
|
||||
}
|
||||
final accuracy = position.accuracy;
|
||||
//gpsDebugMode ? debugPrint("getGpsSignalStrength : ${accuracy}") : null;
|
||||
/*
|
||||
if(isSimulationMode){
|
||||
return _simulatedSignalStrength.value; // GPS信号強度シミュレーション
|
||||
}else {
|
||||
*/
|
||||
if (accuracy <= 10) {
|
||||
latestSignalStrength.value = "high";
|
||||
isGpsSignalWeak = false;
|
||||
return 'high';
|
||||
} else if (accuracy <= 50) {
|
||||
latestSignalStrength.value = "medium";
|
||||
isGpsSignalWeak = false;
|
||||
return 'medium';
|
||||
} else {
|
||||
latestSignalStrength.value = "low";
|
||||
isGpsSignalWeak = true;
|
||||
return 'low';
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
// 現在位置を調整するメソッドを追加
|
||||
LatLng? adjustCurrentLocation(Position? position) {
|
||||
if (position == null) {
|
||||
if( lastValidLocation!=null ) {
|
||||
//debugPrint("=== adjustCurrentLocation (Position:Null and using LastValidLocation ${lastValidLocation})===");
|
||||
return LatLng(lastValidLocation!.latitude, lastValidLocation!.longitude);
|
||||
}else {
|
||||
print("=== adjustCurrentLocation (Position:Null and No LastValidLocation ... )===");
|
||||
return null;
|
||||
}
|
||||
//return lastValidLocation ?? LatLng(0, 0);
|
||||
}
|
||||
final signalStrength = getGpsSignalStrength(position);
|
||||
if (signalStrength == 'high' || signalStrength == 'medium') {
|
||||
//debugPrint("=== adjustCurrentLocation (Position:Get and return Valid location:${position} ... )===");
|
||||
lastValidLocation = LatLng(position.latitude, position.longitude);
|
||||
}
|
||||
return lastValidLocation ?? LatLng(lastValidLocation!.latitude, lastValidLocation!.longitude);
|
||||
}
|
||||
|
||||
//===== Akira Added 2024-4-9 end
|
||||
|
||||
final locationMarkerPositionStreamController =
|
||||
StreamController<LocationMarkerPosition?>.broadcast();
|
||||
// 位置マーカーの位置情報を送信するためのStreamControllerです。
|
||||
// StreamController<LocationMarkerPosition?>型で宣言されています。
|
||||
|
||||
bool isStreamPaused = false; // 位置情報のストリームが一時停止中かどうかを示すフラグです。bool型で宣言されています。
|
||||
|
||||
// 位置マーカーの位置情報のストリームを取得するゲッター関数です。
|
||||
// locationMarkerPositionStreamController.streamを返します。
|
||||
//
|
||||
Stream<LocationMarkerPosition?> get locationMarkerPositionStream =>
|
||||
locationMarkerPositionStreamController.stream;
|
||||
|
||||
// コントローラーの初期化時に呼び出されるライフサイクルメソッドです。
|
||||
// startPositionStreamメソッドを呼び出して、位置情報のストリームを開始します。
|
||||
//
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
// Start listening to location updates when the controller is initialized
|
||||
startPositionStream();
|
||||
|
||||
}
|
||||
|
||||
// 位置情報のストリームを開始するメソッドです。
|
||||
// 位置情報サービスが有効か確認し、無効な場合はダイアログを表示します。
|
||||
// 位置情報の権限を確認し、必要な権限がない場合は権限をリクエストします。
|
||||
// 既存の位置情報のストリームをキャンセルします。
|
||||
// Geolocator.getPositionStreamを使用して、新しい位置情報のストリームを開始します。
|
||||
// ストリームから受信した位置情報をlocationMarkerPositionStreamControllerに追加します。
|
||||
// エラーが発生した場合は、locationMarkerPositionStreamControllerにエラーを追加します。
|
||||
// ストリームが一時停止中の場合は、ストリームを再開します。
|
||||
//
|
||||
// 2024-4-8 Akira : See 2809
|
||||
// stopPositionStreamメソッドを追加して、既存のストリームをキャンセルするようにしました。また、ストリームが完了したらnullに設定し、エラー発生時にストリームをキャンセルするようにしました。
|
||||
//
|
||||
void startPositionStream() async {
|
||||
// Check for location service and permissions before starting the stream
|
||||
// 位置情報サービスの有効性をチェックし、無効な場合はエラーハンドリングを行います。
|
||||
//
|
||||
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
||||
if (!serviceEnabled) {
|
||||
Get.snackbar('位置情報サービスが無効です', '設定から位置情報サービスを有効にしてください');
|
||||
return;
|
||||
}
|
||||
|
||||
await PermissionController.checkAndRequestPermissions();
|
||||
|
||||
// 位置情報の設定を行います。z11
|
||||
// Set up the location options
|
||||
const locationOptions =
|
||||
LocationSettings(accuracy: LocationAccuracy.medium, distanceFilter: 0);
|
||||
|
||||
// 既存の位置情報のストリームをキャンセルします。
|
||||
await positionStream?.cancel();
|
||||
|
||||
// 新しい位置情報のストリームを開始します。
|
||||
//
|
||||
positionStream = Geolocator.getPositionStream(locationSettings: locationOptions).listen(
|
||||
(Position? position) {
|
||||
//gpsDebugMode ? debugPrint("Position = ${position}"):null;
|
||||
final signalStrength = getGpsSignalStrength(position);
|
||||
if (signalStrength == 'low') {
|
||||
isGpsSignalWeak = true;
|
||||
//gpsDebugMode ? debugPrint("LocationController.getPositionStream : isGpsSignalWeak = ${isGpsSignalWeak}"):null;
|
||||
} else {
|
||||
isGpsSignalWeak = false;
|
||||
//gpsDebugMode ? debugPrint("LocationController.getPositionStream : isGpsSignalWeak = ${isGpsSignalWeak}"):null;
|
||||
}
|
||||
|
||||
final DestinationController destinationController = Get.find<DestinationController>();
|
||||
|
||||
// ロゲ開始前、終了後、GPS=low の場合は更新しない。
|
||||
//
|
||||
if (isGpsSignalWeak == false) {
|
||||
//if (destinationController.isInRog.value && isGpsSignalWeak == false) {
|
||||
final adjustedLocation = adjustCurrentLocation(position);
|
||||
if (adjustedLocation != null) {
|
||||
final locationMarkerPosition = LocationMarkerPosition(
|
||||
latitude: adjustedLocation.latitude,
|
||||
longitude: adjustedLocation.longitude,
|
||||
accuracy: position?.accuracy ?? 0,
|
||||
);
|
||||
handleLocationUpdate(locationMarkerPosition);
|
||||
//locationMarkerPositionStreamController.add(locationMarkerPosition); // 位置データ送信
|
||||
} else {
|
||||
// 位置情報が取得できなかった場合、
|
||||
// locationMarkerPositionStreamControllerにnullを追加します。
|
||||
locationMarkerPositionStreamController.add(null); // null 送信?
|
||||
//forceUpdateLocation(Position? position);
|
||||
|
||||
}
|
||||
//}else{
|
||||
// debugPrint("GPS処理対象外");
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
onError: (e) {
|
||||
// エラーが発生した場合、locationMarkerPositionStreamControllerにエラーを追加します。
|
||||
locationMarkerPositionStreamController.addError(e);
|
||||
},
|
||||
onDone: () {
|
||||
positionStream = null; // ストリームが完了したらnullに設定
|
||||
},
|
||||
cancelOnError: true // エラー発生時にストリームをキャンセル
|
||||
);
|
||||
|
||||
// Resume stream if it was paused previously
|
||||
// ストリームが一時停止中の場合、ストリームを再開します。
|
||||
//
|
||||
if (isStreamPaused) {
|
||||
isStreamPaused = false;
|
||||
positionStream!.resume();
|
||||
}
|
||||
}
|
||||
|
||||
// Method to stop the position stream
|
||||
// 位置情報のストリームを停止するメソッドです。
|
||||
// positionStreamが存在する場合、ストリームを一時停止します。
|
||||
// isStreamPausedフラグをtrueに設定します。
|
||||
//
|
||||
void stopPositionStream() async {
|
||||
if (positionStream != null) {
|
||||
// updated Akira 2024-4-8
|
||||
await positionStream!.cancel();
|
||||
positionStream = null;
|
||||
|
||||
//positionStream!.pause();
|
||||
//isStreamPaused = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Method to resume the position stream
|
||||
// 位置情報のストリームを再開するメソッドです。
|
||||
// positionStreamが存在し、ストリームが一時停止中の場合、ストリームを再開します。
|
||||
// isStreamPausedフラグをfalseに設定します。
|
||||
//
|
||||
void resumePositionStream() {
|
||||
if (positionStream != null && isStreamPaused) {
|
||||
positionStream!.resume();
|
||||
isStreamPaused = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void handleLocationUpdate(LocationMarkerPosition? position) async {
|
||||
//debugPrint("locationController.handleLocationUpdate");
|
||||
try {
|
||||
if (position != null) {
|
||||
double currentLat = position.latitude;
|
||||
double currentLon = position.longitude;
|
||||
//debugPrint("Flutter: Received GPS signal. Latitude: $currentLat, Longitude: $currentLon");
|
||||
|
||||
//debugPrint("position = ${position}");
|
||||
/*
|
||||
currentPosition.value = position;
|
||||
final locationMarkerPosition = LocationMarkerPosition(
|
||||
latitude: position.latitude,
|
||||
longitude: position.longitude,
|
||||
accuracy: position.accuracy,
|
||||
);
|
||||
*/
|
||||
lastGPSDataReceivedTime = DateTime.now(); // 最後にGPS信号を受け取った時刻
|
||||
locationMarkerPositionStreamController.add(position);
|
||||
}else{
|
||||
gpsDebugMode ? debugPrint("Flutter: No GPS signal received."):null;
|
||||
}
|
||||
} catch( e ) {
|
||||
debugPrint("Flutter: Error in handleLocationUpdate: $e");
|
||||
}
|
||||
}
|
||||
|
||||
// このメソッドは、現在の位置情報を locationMarkerPositionStreamController に送信します。
|
||||
//
|
||||
void forceUpdateLocation(Position? position) {
|
||||
if (position != null) {
|
||||
final adjustedLocation = adjustCurrentLocation(position);
|
||||
if (adjustedLocation != null) {
|
||||
final locationMarkerPosition = LocationMarkerPosition(
|
||||
latitude: adjustedLocation.latitude,
|
||||
longitude: adjustedLocation.longitude,
|
||||
accuracy: position.accuracy,
|
||||
);
|
||||
locationMarkerPositionStreamController.add(locationMarkerPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// コントローラーのクローズ時に呼び出されるライフサイクルメソッドです。
|
||||
// positionStreamをキャンセルします。
|
||||
//
|
||||
@override
|
||||
void onClose() {
|
||||
// Cancel the position stream subscription when the controller is closed
|
||||
positionStream?.cancel();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
// シミュレーションモードのフラグ
|
||||
RxBool isSimulationMode = RxBool(false);
|
||||
|
||||
// シミュレーションモードを切り替えるための関数
|
||||
void setSimulationMode(bool value) {
|
||||
isSimulationMode.value = value;
|
||||
}
|
||||
|
||||
// GPS信号強度をシミュレートするための変数
|
||||
final Rx<String> _simulatedSignalStrength = Rx<String>('high');
|
||||
|
||||
// GPS信号強度をシミュレートするための関数
|
||||
void setSimulatedSignalStrength(String strength) {
|
||||
_simulatedSignalStrength.value = strength;
|
||||
}
|
||||
|
||||
// シミュレートされた信号強度を取得するための関数
|
||||
String getSimulatedSignalStrength() {
|
||||
return _simulatedSignalStrength.value;
|
||||
}
|
||||
|
||||
}
|
||||
@ -7,7 +7,8 @@ class StringValues extends Translations{
|
||||
'drawer_title':'Rogaining participants can view checkpoints by logging in',
|
||||
'app_title': '- Rogaining -',
|
||||
'address':'address',
|
||||
'email':'Email',
|
||||
'bib':'Bib number',
|
||||
'email':'Email address',
|
||||
'password':'Password',
|
||||
'web':'Web',
|
||||
'wikipedia':'Wikipedia',
|
||||
@ -29,9 +30,9 @@ class StringValues extends Translations{
|
||||
'visit_history': 'Visit History',
|
||||
'rog_web': 'rog website',
|
||||
'no_values': 'No Values',
|
||||
'email_and_password_required': 'Email and password required',
|
||||
'email_and_password_required': 'Email and password are required to register user',
|
||||
'rogaining_user_need_tosign_up': "Rogaining participants do need to sign up.",
|
||||
'add_location': 'Add Location',
|
||||
'add_location': 'Gifu',
|
||||
'select_travel_mode':'Select your travel mode',
|
||||
'walking':'Walking',
|
||||
'driving': 'Driving',
|
||||
@ -70,16 +71,158 @@ class StringValues extends Translations{
|
||||
"Not reached the goal yet": "Not reached the goal yet",
|
||||
"You have not reached the goal yet.":"You have not reached the goal yet.",
|
||||
"delete_account": "Delete account",
|
||||
"delete_account_title": "Are you ok to delete your account?",
|
||||
"delete_account_middle": "All your account information and data history will be removed from local device and server side.",
|
||||
"accounted_deleted": "Account deleted",
|
||||
"account_deleted_message": "your account has beed successfully deleted",
|
||||
"privacy": "Privacy policy",
|
||||
"app_developed_by_gifu_dx": "This app was developed by the Gifu Prefecture DX subsidy project."
|
||||
"app_developed_by_gifu_dx": "This app was developed by the Gifu Prefecture DX subsidy project.",
|
||||
|
||||
'location_permission_title': 'Location Permission',
|
||||
'location_permission_content': 'Gifu Navi app collects location data to provide better services.\nLocation data is used for automatic check-in at checkpoints and delivery of notifications.\nLocation data may be collected even when the app is closed or not in use.\nCollected location data is only used as statistical information that cannot identify individuals and is never linked to personal information.\nIf you do not allow the use of location data, please select "Do not allow" on the next screen.',
|
||||
'location_disabled_title': 'Location Service Disabled',
|
||||
'location_disabled_content': 'Location information is disabled.\nTo continue, please enable location services for Gifu Navi in Settings > Privacy and Security > Location Services.',
|
||||
'drawer_title': 'Rogaining participants can view checkpoints by logging in',
|
||||
'app_title': 'Travel Itinerary',
|
||||
'want_to_go': 'Want to Go',
|
||||
'schedule_point': 'Schedule Point',
|
||||
'rog_web': 'Rogaining Website',
|
||||
'rogaining_user_need_tosign_up': "Rogaining participants do not need to sign up.",
|
||||
'add_location': 'Gifu',
|
||||
'finish': 'Finish',
|
||||
'my_route': 'My Route',
|
||||
'visit_history': 'Visit History',
|
||||
'search': 'Search',
|
||||
'login': 'Login',
|
||||
'password': 'Password',
|
||||
'already_have_account': 'Already have an account?',
|
||||
'sign_up': 'Sign Up',
|
||||
'create_account': 'Create an account, it\'s free',
|
||||
'confirm_password': 'Confirm Password',
|
||||
'cancel_checkin': 'Cancel Check-in',
|
||||
'go_here': 'Show route',
|
||||
'cancel_route':'Clear route',
|
||||
'start_rogaining': 'Start Rogaining',
|
||||
'in_game': 'In Game',
|
||||
'finish_rogaining': 'Finish Rogaining',
|
||||
'checkin': 'Check-in',
|
||||
'rogaining_not_started': 'Rogaining not started',
|
||||
'confirm': 'Confirm',
|
||||
'clear_rog_data_message': 'Starting rogaining will clear all previous rogaining data. Are you sure you want to start?',
|
||||
'no': 'No',
|
||||
'yes': 'Yes',
|
||||
'retake': 'Retake',
|
||||
'take_photo': 'Take Photo',
|
||||
'take_receipt_photo': 'Please take a photo of the receipt',
|
||||
'buypoint_added': 'Buypoint added.',
|
||||
'no_purchase': 'No Purchase',
|
||||
'complete': 'Complete',
|
||||
'movement_history': 'Movement History',
|
||||
'pass_history': 'Pass History',
|
||||
'no_checkin_yet': 'No check-in yet',
|
||||
'game_status': 'Game Status',
|
||||
'take_cp_photo': 'This is a CP. Please take a photo.',
|
||||
'save_goal_success': 'Goal saved successfully',
|
||||
'save_goal_failed': 'Goal not added',
|
||||
'please_try_again': 'Please try again',
|
||||
'click_start_to_start_rogaining': 'Click start to start rogaining',
|
||||
'at_rogaining_point_start': 'You are at a rogaining point, start rogaining',
|
||||
'start': 'Start',
|
||||
'rogaining_started': 'Rogaining Started',
|
||||
'rogaining_session_started': 'Rogaining session started',
|
||||
'not_started_yet': 'Not started yet',
|
||||
'not_started_rogaining_yet': 'You have not started rogaining yet.',
|
||||
'not_reached_goal_yet': 'Not reached the goal yet',
|
||||
'not_reached_goal_yet_message': 'You have not reached the goal yet.',
|
||||
'reload_qr': 'Reload QR',
|
||||
'read_qr': 'Read QR',
|
||||
'read_qr_code': 'Please read the QR code',
|
||||
'canceled': 'Canceled',
|
||||
'checkin_failed_try_again': 'Check-in failed. Please tap the checkpoint again if necessary.',
|
||||
'rogaining_not_started': 'Rogaining not started',
|
||||
'need_to_start_rogaining': 'You need to tap the start button to begin rogaining',
|
||||
'no_destination': 'No destination',
|
||||
'near_cp_not_checkin': 'Near a CP or distance-ignored CP, in-game but not checked in yet.',
|
||||
'auto_checkin_case': 'Auto check-in case',
|
||||
'non_auto_checkin_case': 'Non-auto check-in case',
|
||||
'normal_cp_case': 'Normal CP case',
|
||||
'non_normal_cp_case': 'Non-normal CP case... what case?',
|
||||
'goal_clock_photo_case': 'Goal clock photo case',
|
||||
'start_case_24_hours_passed': 'Start case and 24 hours have passed since the last goal',
|
||||
'start_cp_24_hours_passed': 'At the start CP, and 24 hours have passed since the last goal,',
|
||||
'standard_cp_not_checkin': 'Standard CP not checked in yet.',
|
||||
'after_checkin_buypoint_case': 'After check-in, buypoint case.',
|
||||
'goal_case': 'Goal case',
|
||||
'start_case': 'Start case',
|
||||
'no_match_skip_process': 'Does not match any conditions, skipping process',
|
||||
'server_error_occurred': 'A server error occurred',
|
||||
'could_not_communicate_with_server': 'Could not communicate with the server',
|
||||
'communication_error_occurred': 'A communication error occurred',
|
||||
'checked_in': 'Checked in.',
|
||||
'cancel_checkin': 'Cancel Check-in',
|
||||
'checkin_canceled_for': 'Check-in canceled for',
|
||||
'error': 'Error',
|
||||
'failed_to_cancel_checkin': 'Failed to cancel check-in.',
|
||||
'buypoint_added': 'Buypoint added',
|
||||
'error_occurred': 'An error occurred',
|
||||
'failed_to_process_checkpoint': 'Failed to process the checkpoint.',
|
||||
'start_rogaining': 'Start Rogaining',
|
||||
'in_competition': 'In Competition',
|
||||
'map_auto_return_message': 'If there is no map operation, it will automatically return to the current location. Please enter the timer seconds. If you check the checkbox, auto-return will not be performed.',
|
||||
'no_auto_return': 'No Auto Return',
|
||||
'failed_to_load_markers': 'Failed to load markers',
|
||||
'screen_switching_error': 'Screen switching error',
|
||||
'failed_to_switch_screen': 'Failed to switch the screen',
|
||||
'timer_duration': 'Timer Duration',
|
||||
'user_data_deletion': 'User Data Deletion',
|
||||
'user_consent_set_for_data_deletion': 'User consent is set for data deletion. User data has been deleted from the app and server',
|
||||
'go_to_gps_signal_area': 'Please go to an area with GPS signal.',
|
||||
'location_service_disabled': 'Location service is disabled. Please enable location service from the settings screen. If you are unsure, please contact the engineering staff.',
|
||||
'location_permission_not_granted': 'Location permission is not granted. Please allow location service for Gifu Navi from the settings screen. If you are unsure, please contact the engineering staff.',
|
||||
'location_service_issue_occurred': 'An issue occurred with the location service. The location service is being restarted, please wait a moment.',
|
||||
'login_failed': 'Login Failed',
|
||||
'check_login_id_or_password': 'Please check your login ID or password.',
|
||||
'communication_error_occurred': 'A communication error occurred',
|
||||
'could_not_communicate_with_server': 'Could not communicate with the server',
|
||||
'before_game': 'Before Game',
|
||||
'location_permission_denied_title': 'Location Permission Denied',
|
||||
'location_permission_denied_message': 'This app requires location permission to function properly. Please grant location permission to continue.',
|
||||
'location_permission_permanently_denied_title': 'Location Permission Permanently Denied',
|
||||
'location_permission_permanently_denied_message': 'Location permission has been permanently denied. Please open app settings to grant location permission.',
|
||||
'open_settings': 'Open Settings',
|
||||
'location_permission_needed_title': 'Location Permission Needed',
|
||||
'location_permission_needed_main': 'Location permissions have been permanently denied. Please open app settings to enable location permissions.',
|
||||
'open_settings': 'Open Settings',
|
||||
'location_services_disabled_title': 'Location Services Disabled',
|
||||
'location_service_disabled_main': 'Please enable location services to continue using the app.',
|
||||
'location_permission_denied_title': 'Location Permission Denied',
|
||||
'location_permission_denied_main': 'This app requires location permissions to function properly. Please enable location permissions in your device settings.',
|
||||
'home': 'Home',
|
||||
'welcome': 'Welcome to Gifu Navi',
|
||||
'location_disabled_message': 'Location services are disabled. Some features may not work properly.',
|
||||
'enable_location_service': 'Enable Location Service',
|
||||
'start_app': 'Start App',
|
||||
'location_permission_required_title': 'Location Permission Required',
|
||||
'location_permission_required_message': 'This app requires access to your location. Please grant permission to continue.',
|
||||
'cancel': 'Cancel',
|
||||
'checkins': 'Check-ins',
|
||||
'reset_button': 'Reset data',
|
||||
'reset_title': 'Reset the data in this device.',
|
||||
'reset_message': 'Are you ok to reset all data in this device?',
|
||||
'reset_done': 'Reset Done.',
|
||||
'reset_explain': 'All data has been reset. You should tap start rogaining to start game.',
|
||||
'no_match': 'No match!',
|
||||
'password_does_not_match':'The passwords you entered were not match.',
|
||||
'forgot_password':'Forgot password',
|
||||
'user_registration_successful':'Sent activation mail to you. Pls click activation link on the email.',
|
||||
|
||||
},
|
||||
'ja_JP': {
|
||||
'drawer_title':'ロゲイニング参加者はログイン するとチェックポイントが参照 できます',
|
||||
'app_title': '旅行工程表',
|
||||
'address':'住所',
|
||||
'email':'Eメール',
|
||||
'bib':'ゼッケン番号',
|
||||
'email':'メールアドレス',
|
||||
'password':'パスワード',
|
||||
'web':'ウェブ',
|
||||
'wikipedia':'ウィキペディア',
|
||||
@ -103,9 +246,9 @@ class StringValues extends Translations{
|
||||
'visit_history': '訪問履歴',
|
||||
'rog_web': 'ロゲイニングウェブサイト',
|
||||
'no_values': '値なし',
|
||||
'email_and_password_required': 'メールとパスワードが必要です',
|
||||
'email_and_password_required': 'メールとパスワードの入力が必要です',
|
||||
'rogaining_user_need_tosign_up': "ロゲイニング参加者はサインアップの必要はありません。",
|
||||
'add_location': '目的地選択',
|
||||
'add_location': '岐阜',
|
||||
'select_travel_mode':'移動モードを選択してください',
|
||||
'walking':'歩行',
|
||||
'driving': '自動車利用',
|
||||
@ -115,12 +258,12 @@ class StringValues extends Translations{
|
||||
'confirm': '確認',
|
||||
'cancel': 'キャンセル',
|
||||
'all_destinations_are_deleted_successfully' : 'すべての宛先が正常に削除されました',
|
||||
'deleted': "削除された",
|
||||
'deleted': "削除されました",
|
||||
'remarks' : '備考',
|
||||
'old_password' : '以前のパスワード',
|
||||
'new_password' : '新しいパスワード',
|
||||
'values_required' : '必要な値',
|
||||
'failed' : '失敗した',
|
||||
'failed' : '失敗',
|
||||
'password_change_failed_please_try_again' : 'パスワードの変更に失敗しました。もう一度お試しください',
|
||||
'user_registration_failed_please_try_again' : 'ユーザー登録に失敗しました。もう一度お試しください',
|
||||
'all': '全て',
|
||||
@ -129,13 +272,13 @@ class StringValues extends Translations{
|
||||
'finishing_rogaining' : 'ロゲイニングを終えて',
|
||||
'cp_pls_take_photo' : "CPです。撮影してください。",
|
||||
'take_photo of the clock' : '時計の写真を撮る',
|
||||
'finish_goal': 'フィニッシュゴール',
|
||||
'finish_goal': 'ゴール完了',
|
||||
'goal_saved': "目標を保存しました",
|
||||
'goal_added_successfuly' : '目標が正常に追加されました',
|
||||
'goal_not_added' : '目標が追加されていません',
|
||||
'please_try_again' : 'もう一度お試しください',
|
||||
"Click start to start rogaining":"開始をクリックして、ロゲイニングを開始します",
|
||||
"you are at roganing point, start rogaining":"あなたはロガニングポイントにいます、ロガニングを始めてください",
|
||||
"you are at roganing point, start rogaining":"あなたはロゲイニングポイントにいます、ロゲイニングを始めてください",
|
||||
"Start":"始める",
|
||||
"Rogaining Started":"ロゲイニング開始",
|
||||
"Rogaining session started":"ロゲイニングセッション開始",
|
||||
@ -143,11 +286,153 @@ class StringValues extends Translations{
|
||||
"You have not started rogaining yet.":"あなたはまだロゲイニングを始めていません。",
|
||||
"Not reached the goal yet": "まだ目標に達していない",
|
||||
"You have not reached the goal yet.":"あなたはまだゴールに達していません。",
|
||||
"delete_account": "アカウントを削除する",
|
||||
"delete_account": "アカウントを削除します",
|
||||
"delete_account_title": "アカウントを削除しますがよろしいですか?",
|
||||
"delete_account_middle": "これにより、アカウント情報とすべてのゲーム データが削除され、すべての状態が削除されます",
|
||||
"accounted_deleted": "アカウントが削除されました",
|
||||
"account_deleted_message": "あなたのアカウントは正常に削除されました",
|
||||
"privacy": "プライバシーポリシー",
|
||||
"app_developed_by_gifu_dx": "このアプリは岐阜県DX補助金事業で開発されました。"
|
||||
"app_developed_by_gifu_dx": "※このアプリは令和4、6年度岐阜県DX補助金事業で開発されました。",
|
||||
|
||||
'location_permission_title': 'ロケーション許可',
|
||||
'location_permission_content': 'このアプリでは、位置情報の収集を行います。\n岐阜ナビアプリではチェックポイントの自動チェックインの機能を可能にするために、現在地のデータが収集されます。アプリを閉じている時や、使用していないときにも収集されます。位置情報は、個人を特定できない統計的な情報として、ユーザーの個人情報とは一切結びつかない形で送信されます。お知らせの配信、位置情報の利用を許可しない場合は、この後表示されるダイアログで「許可しない」を選択してください。',
|
||||
'location_disabled_title': '位置情報サービスが無効です',
|
||||
'location_disabled_content': '位置情報が無効になっています\nこのアプリケーションへの位置情報アクセスが無効になっています。続行するには設定>プライバシーとセキュリティ>位置情報サービス>岐阜ナビ で有効にしてください。',
|
||||
'drawer_title': 'ロゲイニング参加者はログイン するとチェックポイントが参照 できます',
|
||||
'app_title': '旅行工程表',
|
||||
'want_to_go': '行きたい',
|
||||
'schedule_point': '予定地点',
|
||||
'rog_web': 'ロゲイニングウェブサイト',
|
||||
'rogaining_user_need_tosign_up': "ロゲイニング参加者はサインアップの必要はありません。",
|
||||
'add_location': '岐阜',
|
||||
'finish': '終了する',
|
||||
'my_route': 'マイルート',
|
||||
'visit_history': '訪問履歴',
|
||||
'search': '検索',
|
||||
'login': 'ログイン',
|
||||
'password': 'パスワード',
|
||||
'already_have_account': 'すでにアカウントをお持ちですか?',
|
||||
'sign_up': 'サインアップ',
|
||||
'create_account': 'アカウントを無料で作成します',
|
||||
'confirm_password': '確認用パスワード',
|
||||
'cancel_checkin': 'チェックイン取消',
|
||||
'go_here': 'ルート表示',
|
||||
'cancel_route':'ルート消去',
|
||||
'start_rogaining': 'ロゲ開始',
|
||||
'in_game': '競技中',
|
||||
'finish_rogaining': 'ロゲゴール',
|
||||
'checkin': 'チェックイン',
|
||||
'rogaining_not_started': 'ロゲは始まっていません',
|
||||
'confirm': '確認',
|
||||
'clear_rog_data_message': 'ロゲを開始すると、今までのロゲデータが全てクリアされます。本当に開始しますか?',
|
||||
'no': 'いいえ',
|
||||
'yes': 'はい',
|
||||
'retake': '再撮影',
|
||||
'take_photo': '撮影',
|
||||
'take_receipt_photo': 'レシートの写真を撮ってください',
|
||||
'buypoint_added': 'お買い物加点を行いました。',
|
||||
'no_purchase': '買い物なし',
|
||||
'complete': '完了',
|
||||
'movement_history': '移動履歴',
|
||||
'pass_history': '通過履歴',
|
||||
'no_checkin_yet': 'チェックインはまだされてません',
|
||||
'game_status': 'ゲームステータス',
|
||||
'take_cp_photo': 'CPです。撮影してください。',
|
||||
'save_goal_success': '目標が保存されました',
|
||||
'save_goal_failed': '目標が追加されていません',
|
||||
'please_try_again': 'もう一度お試しください',
|
||||
'click_start_to_start_rogaining': 'ロゲを開始するには開始をクリックしてください',
|
||||
'at_rogaining_point_start': 'あなたはロガニングポイントにいます、ロガニングを始めてください',
|
||||
'start': '開始',
|
||||
'rogaining_started': 'ロゲイニングを開始しました',
|
||||
'rogaining_session_started': 'ロゲイニングセッションを開始しました',
|
||||
'not_started_yet': 'まだ開始されていません',
|
||||
'not_started_rogaining_yet': 'あなたはまだロゲイニングを始めていません。',
|
||||
'not_reached_goal_yet': 'まだゴールに達していません',
|
||||
'not_reached_goal_yet_message': 'あなたはまだゴールに達していません。',
|
||||
'reload_qr': '再QR読込',
|
||||
'read_qr': 'QR読込',
|
||||
'read_qr_code': 'QRコードを読み取ってください',
|
||||
'canceled': 'キャンセルされました',
|
||||
'checkin_failed_try_again': 'チェックインしていません。必要ならもう一度チェックポイントをタップして下さい。',
|
||||
'rogaining_not_started': 'ロゲが始まっていません',
|
||||
'need_to_start_rogaining': 'ロゲ開始ボタンをタップして、ロゲイニングを始める必要があります',
|
||||
'no_destination': '目的地がない場合',
|
||||
'near_cp_not_checkin': '検知範囲または距離無視CPで、ゲーム中でまだチェックインしていない。',
|
||||
'auto_checkin_case': '自動チェックインの場合',
|
||||
'non_auto_checkin_case': '自動チェックイン以外の場合',
|
||||
'normal_cp_case': '通常CPの場合',
|
||||
'non_normal_cp_case': '通常CP以外の場合....どんな場合?',
|
||||
'goal_clock_photo_case': 'ゴールで時計撮影の場合',
|
||||
'start_case_24_hours_passed': 'スタートの場合で最後のゴールから24時間経過している場合',
|
||||
'start_cp_24_hours_passed': '開始CPで、最後にゴールしてから24時間経過していれば、',
|
||||
'standard_cp_not_checkin': '標準CP まだチェックインしていない。',
|
||||
'after_checkin_buypoint_case': 'チェックイン後で買い物ポイントの場合。',
|
||||
'goal_case': 'ゴールの場合',
|
||||
'start_case': 'スタートの場合',
|
||||
'no_match_skip_process': 'いずれにも当てはまらないので、処理スキップ',
|
||||
'server_error_occurred': 'サーバーエラーがおきました',
|
||||
'could_not_communicate_with_server': 'サーバーと通信できませんでした',
|
||||
'communication_error_occurred': '通信エラーがおきました',
|
||||
'checked_in': 'チェックインしました。',
|
||||
'cancel_checkin': 'チェックイン取消',
|
||||
'checkin_canceled_for': 'のチェックインは取り消されました',
|
||||
'error': 'エラー',
|
||||
'failed_to_cancel_checkin': 'チェックイン取り消しに失敗しました。',
|
||||
'buypoint_added': 'お買い物加点を行いました',
|
||||
'error_occurred': 'エラーがおきました',
|
||||
'failed_to_process_checkpoint': 'チェックポイントの処理に失敗しました。',
|
||||
'start_rogaining': 'ロゲ開始',
|
||||
'in_competition': '競技中',
|
||||
'map_auto_return_message': 'マップ操作がなければ自動的に現在地に復帰します。そのタイマー秒数を入れて下さい。チェックボックスをチェックすると、自動復帰は行われなくなります。',
|
||||
'no_auto_return': '自動復帰なし',
|
||||
'failed_to_load_markers': 'マーカーの読み込みに失敗しました',
|
||||
'screen_switching_error': '画面切り替えでエラー',
|
||||
'failed_to_switch_screen': '画面の切り替えができませんでした',
|
||||
'timer_duration': 'タイマーの長さ',
|
||||
'user_data_deletion': 'ユーザーデータを削除する',
|
||||
'user_consent_set_for_data_deletion': 'データを削除するためにユーザーの同意が設定されています アプリとサーバーでユーザーデータが削除されました',
|
||||
'go_to_gps_signal_area': 'GPSの届く場所に行って、信号を拾ってください。',
|
||||
'location_service_disabled': '位置情報サービスが無効になっています。設定画面から位置情報サービスを有効にして下さい。不明な場合にはエンジニアスタッフにお問い合わせください。',
|
||||
'location_permission_not_granted': '位置情報サービスが許可されていません。設定画面から岐阜ナビの位置情報サービスを許可して下さい。不明な場合にはエンジニアスタッフにお問い合わせください。',
|
||||
'location_service_issue_occurred': '位置情報サービスに問題が発生しました。位置情報サービスを再起動していますので少しお待ちください。',
|
||||
'login_failed': 'ログイン失敗',
|
||||
'check_login_id_or_password': 'ログインIDかパスワードを確認して下さい。',
|
||||
'communication_error_occurred': '通信エラーがおきました',
|
||||
'could_not_communicate_with_server': 'サーバーと通信できませんでした',
|
||||
'before_game': 'ゲーム前',
|
||||
'location_permission_denied_title': '位置情報の許可が拒否されました',
|
||||
'location_permission_denied_message': 'このアプリを適切に機能させるには、位置情報の許可が必要です。続行するには、位置情報の許可を付与してください。',
|
||||
'location_permission_permanently_denied_title': '位置情報の許可が永久に拒否されました',
|
||||
'location_permission_permanently_denied_message': '位置情報の許可が永久に拒否されました。位置情報の許可を付与するには、アプリ設定を開いてください。',
|
||||
'open_settings': '設定を開く',
|
||||
'storage_permission_needed_title': '写真ライブラリへの許可が必要です',
|
||||
'storage_permission_needed_main': '岐阜ロゲでは、写真ライブラリを使用してスタート・チェックイン・ゴール等の通過照明写真の記録のために、写真ライブラリへの書き込みを行なっています。このためチェックイン時に写真をライブラリに保存する権限が必要です。設定画面で、「岐阜ナビ」に対して、ライブラリに写真の保存を許可するように設定してください。',
|
||||
'location_permission_needed_title': '位置情報への許可が必要です',
|
||||
'location_permission_needed_main': '岐阜ロゲでは、位置情報を使用してスタート・チェックイン・ゴール等の通過照明及び移動手段の記録のために、位置情報のトラッキングを行なっています。このためバックグラウンドでもトラッキングができるように位置情報の権限が必要です。設定画面で、「岐阜ナビ」に対して、常に位置情報を許可するように設定してください。',
|
||||
'open_settings': '設定を開く',
|
||||
'location_permission_denied_title': '位置情報へのアクセスが拒否されています。',
|
||||
'location_permission_denied_main': 'この岐阜ナビアプリは正常に動かすには位置情報への許可が必要です。「設定」画面で位置情報の許可を指定してください。',
|
||||
'location_services_disabled_title': '位置情報サービスが拒否されています',
|
||||
'location_service_disabled_main': '岐阜ナビアプリを使用するには位置情報サービスを許可してください。',
|
||||
'home': 'ホーム',
|
||||
'welcome': '岐阜ナビへようこそ',
|
||||
'location_disabled_message': '位置情報サービスが無効になっています。一部の機能が正しく動作しない可能性があります。',
|
||||
'enable_location_service': '位置情報サービスを有効にする',
|
||||
'start_app': 'アプリを開始する',
|
||||
'location_permission_required_title': '位置情報の許可が必要です',
|
||||
'location_permission_required_message': 'このアプリを使用するには、位置情報へのアクセスが必要です。続行するには許可を付与してください。',
|
||||
'cancel': 'キャンセル',
|
||||
'checkins': 'チェックイン',
|
||||
'reset_button': 'リセット',
|
||||
'reset_title': 'リセットしますがよろしいですか?',
|
||||
'reset_message': 'これにより、すべてのゲーム データが削除され、すべての状態が削除されます',
|
||||
'reset_done': 'リセット完了',
|
||||
'reset_explain': 'すべてリセットされました。ロゲ開始から再開して下さい。',
|
||||
'no_match': '不一致',
|
||||
'password_does_not_match':'入力したパスワードが一致しません',
|
||||
'forgot_password':'パスワードを忘れた場合',
|
||||
'user_registration_successful':'ユーザー認証のメールをお届けしました。メール上のリンクをクリックして正式登録してください。',
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,42 +1,43 @@
|
||||
import 'package:geojson_vi/geojson_vi.dart';
|
||||
import 'package:gifunavi/model/destination.dart';
|
||||
|
||||
import 'package:geojson/geojson.dart';
|
||||
import 'package:rogapp/model/destination.dart';
|
||||
|
||||
class TextUtils{
|
||||
|
||||
static String getDisplayTextFeture(GeoJsonFeature f){
|
||||
RegExp regex = RegExp(r'([.]*0)(?!.*\d)');
|
||||
String txt = "";
|
||||
// if(f.properties!["cp"] > 0){
|
||||
// //print("-- sub-- ${f.properties!["cp"]} ----");
|
||||
// txt = "${f.properties!["cp"].toString().replaceAll(regex, '')}";
|
||||
// }
|
||||
//if(f.properties!["buy_point"] != null && f.properties!["buy_point"] > 0){
|
||||
txt = "$txt${f.properties!["sub_loc_id"]}";
|
||||
//}
|
||||
return txt;
|
||||
class TextUtils {
|
||||
static String getDisplayTextFeture(GeoJSONFeature f) {
|
||||
RegExp regex = RegExp(r'([.]*0)(?!.*\d)');
|
||||
String txt = "";
|
||||
if (f.properties!["sub_loc_id"] != null) {
|
||||
txt = "${f.properties!["sub_loc_id"]}";
|
||||
}
|
||||
|
||||
|
||||
static String getDisplayText(Destination dp){
|
||||
RegExp regex = RegExp(r'([.]*0)(?!.*\d)');
|
||||
String txt = "";
|
||||
if(dp.cp! > 0){
|
||||
txt = dp.cp.toString().replaceAll(regex, '');
|
||||
if(dp.checkin_point != null && dp.checkin_point! > 0){
|
||||
txt = "$txt{${dp.checkin_point.toString().replaceAll(regex, '')}}";
|
||||
}
|
||||
if(dp.buy_point != null && dp.buy_point! > 0){
|
||||
print("^^^^^^^^^ ${dp.sub_loc_id}^^^^^^^^^^");
|
||||
txt = "#${dp.cp.toString().replaceAll(regex, '')}(${dp.checkin_point.toString().replaceAll(regex, '')}+${dp.buy_point.toString().replaceAll(regex, '')})";
|
||||
}
|
||||
}
|
||||
return txt;
|
||||
}
|
||||
|
||||
// static String getDisplayText(String num){
|
||||
// RegExp regex = RegExp(r'([.]*0)(?!.*\d)');
|
||||
// return "${num.replaceAll(regex, '')}";
|
||||
// if(f.properties!["cp"] > 0){
|
||||
// //print("-- sub-- ${f.properties!["cp"]} ----");
|
||||
// txt = "${f.properties!["cp"].toString().replaceAll(regex, '')}";
|
||||
// }
|
||||
//if(f.properties!["buy_point"] != null && f.properties!["buy_point"] > 0){
|
||||
//txt = "$txt${f.properties!["sub_loc_id"]}";
|
||||
//}
|
||||
//print("Text = ${txt}");
|
||||
return txt;
|
||||
}
|
||||
|
||||
}
|
||||
static String getDisplayText(Destination dp) {
|
||||
RegExp regex = RegExp(r'([.]*0)(?!.*\d)');
|
||||
String txt = "";
|
||||
if (dp.cp! > 0) {
|
||||
txt = dp.cp.toString().replaceAll(regex, '');
|
||||
if (dp.checkin_point != null && dp.checkin_point! > 0) {
|
||||
txt = "$txt{${dp.checkin_point.toString().replaceAll(regex, '')}}";
|
||||
}
|
||||
if (dp.buy_point != null && dp.buy_point! > 0) {
|
||||
//print("^^^^^^^^^ ${dp.sub_loc_id}^^^^^^^^^^");
|
||||
txt =
|
||||
"#${dp.cp.toString().replaceAll(regex, '')}(${dp.checkin_point.toString().replaceAll(regex, '')}+${dp.buy_point.toString().replaceAll(regex, '')})";
|
||||
}
|
||||
}
|
||||
return txt;
|
||||
}
|
||||
|
||||
// static String getDisplayText(String num){
|
||||
// RegExp regex = RegExp(r'([.]*0)(?!.*\d)');
|
||||
// return "${num.replaceAll(regex, '')}";
|
||||
// }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user