feat : cashing map from internet
This commit is contained in:
@@ -7,9 +7,12 @@ export 'package:device_info_plus/device_info_plus.dart';
|
|||||||
export 'package:dio/dio.dart';
|
export 'package:dio/dio.dart';
|
||||||
//other packages
|
//other packages
|
||||||
export 'package:flutter_localizations/flutter_localizations.dart';
|
export 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
|
//map
|
||||||
export 'package:flutter_map/flutter_map.dart';
|
export 'package:flutter_map/flutter_map.dart';
|
||||||
export 'package:flutter_map_animations/flutter_map_animations.dart';
|
export 'package:flutter_map_animations/flutter_map_animations.dart';
|
||||||
export 'package:flutter_map_marker_cluster/flutter_map_marker_cluster.dart';
|
export 'package:flutter_map_marker_cluster/flutter_map_marker_cluster.dart';
|
||||||
|
export 'package:flutter_map_tile_caching/flutter_map_tile_caching.dart';
|
||||||
|
|
||||||
export 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
export 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
||||||
export 'package:flutter_screenutil/flutter_screenutil.dart';
|
export 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
export 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
export 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter_map_tile_caching/flutter_map_tile_caching.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
import 'package:logger/logger.dart';
|
import 'package:logger/logger.dart';
|
||||||
import 'package:rasadyar_core/data/services/network_status.dart';
|
import 'package:rasadyar_core/data/services/network_status.dart';
|
||||||
@@ -10,6 +11,14 @@ Future<void> setupAllCoreProvider() async {
|
|||||||
await _setupLocalStorage();
|
await _setupLocalStorage();
|
||||||
await _setupRemote();
|
await _setupRemote();
|
||||||
diCore.registerSingleton(NetworkStatus()..startListening());
|
diCore.registerSingleton(NetworkStatus()..startListening());
|
||||||
|
|
||||||
|
//max 500MB Map Cashing
|
||||||
|
await diCore.registerSingleton(
|
||||||
|
FMTCObjectBoxBackend().initialise(maxDatabaseSize: 500 * 1024 * 1024),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
await diCore.allReady();
|
await diCore.allReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -385,6 +385,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
|
flat_buffers:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flat_buffers
|
||||||
|
sha256: "380bdcba5664a718bfd4ea20a45d39e13684f5318fcd8883066a55e21f37f4c3"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "23.5.26"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -451,6 +459,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
version: "7.0.0"
|
||||||
|
flutter_map_tile_caching:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_map_tile_caching
|
||||||
|
sha256: "1839c6157cf9b444083a626b30f3ba9f6db802ac8bb5292440e1628882faa392"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "10.0.0"
|
||||||
flutter_plugin_android_lifecycle:
|
flutter_plugin_android_lifecycle:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1045,6 +1061,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.2"
|
||||||
|
objectbox:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: objectbox
|
||||||
|
sha256: "25c2e24b417d938decb5598682dc831bc6a21856eaae65affbc57cfad326808d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.3.0"
|
||||||
|
objectbox_flutter_libs:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: objectbox_flutter_libs
|
||||||
|
sha256: "574b0233ba79a7159fca9049c67974f790a2180b6141d4951112b20bd146016a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.3.0"
|
||||||
package_config:
|
package_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ dependencies:
|
|||||||
flutter_map: ^7.0.0
|
flutter_map: ^7.0.0
|
||||||
flutter_map_animations: ^0.8.0
|
flutter_map_animations: ^0.8.0
|
||||||
flutter_map_marker_cluster: ^1.4.0
|
flutter_map_marker_cluster: ^1.4.0
|
||||||
|
flutter_map_tile_caching: ^10.0.0
|
||||||
|
|
||||||
#location
|
#location
|
||||||
latlong2: ^0.9.1
|
latlong2: ^0.9.1
|
||||||
geolocator: ^14.0.2
|
geolocator: ^14.0.2
|
||||||
|
|||||||
1
packages/livestock/lib/data/common/constant.dart
Normal file
1
packages/livestock/lib/data/common/constant.dart
Normal file
@@ -0,0 +1 @@
|
|||||||
|
const String mapStoreKey = 'mapStoreLiveStock';
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:rasadyar_core/core.dart';
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
import 'package:rasadyar_livestock/data/common/constant.dart';
|
||||||
import 'package:rasadyar_livestock/data/common/dio_exception_handeler.dart';
|
import 'package:rasadyar_livestock/data/common/dio_exception_handeler.dart';
|
||||||
import 'package:rasadyar_livestock/data/data_source/remote/auth/auth_remote.dart';
|
import 'package:rasadyar_livestock/data/data_source/remote/auth/auth_remote.dart';
|
||||||
import 'package:rasadyar_livestock/data/data_source/remote/auth/auth_remote_imp.dart';
|
import 'package:rasadyar_livestock/data/data_source/remote/auth/auth_remote_imp.dart';
|
||||||
@@ -25,11 +26,14 @@ Future<void> setupLiveStockDI() async {
|
|||||||
await tokenService.saveBaseUrl('https://api.dam.rasadyar.net/');
|
await tokenService.saveBaseUrl('https://api.dam.rasadyar.net/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await FMTCStore(mapStoreKey).manage.create();
|
||||||
|
|
||||||
|
|
||||||
// First register AppInterceptor with lazy callbacks
|
// First register AppInterceptor with lazy callbacks
|
||||||
diLiveStock.registerLazySingleton<AppInterceptor>(
|
diLiveStock.registerLazySingleton<AppInterceptor>(
|
||||||
() => AppInterceptor(
|
() => AppInterceptor(
|
||||||
refreshTokenCallback: () async {
|
refreshTokenCallback: () async {
|
||||||
/* // Use lazy access to avoid circular dependency
|
// Use lazy access to avoid circular dependency
|
||||||
final authRepository = diLiveStock.get<AuthRepository>();
|
final authRepository = diLiveStock.get<AuthRepository>();
|
||||||
final hasAuthenticated = await authRepository.hasAuthenticated();
|
final hasAuthenticated = await authRepository.hasAuthenticated();
|
||||||
if (hasAuthenticated) {
|
if (hasAuthenticated) {
|
||||||
@@ -37,7 +41,7 @@ Future<void> setupLiveStockDI() async {
|
|||||||
authRequest: {'refresh': tokenService.refreshToken.value},
|
authRequest: {'refresh': tokenService.refreshToken.value},
|
||||||
);
|
);
|
||||||
return newToken?.access;
|
return newToken?.access;
|
||||||
}*/
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
saveTokenCallback: (String newToken) async {
|
saveTokenCallback: (String newToken) async {
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:rasadyar_core/core.dart';
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
import 'package:rasadyar_livestock/data/common/constant.dart';
|
||||||
import 'package:rasadyar_livestock/data/repository/livestock/livestock_repository.dart';
|
import 'package:rasadyar_livestock/data/repository/livestock/livestock_repository.dart';
|
||||||
import 'package:rasadyar_livestock/data/repository/livestock/livestock_repository_imp.dart';
|
|
||||||
import 'package:rasadyar_livestock/injection/live_stock_di.dart';
|
import 'package:rasadyar_livestock/injection/live_stock_di.dart';
|
||||||
import 'package:rasadyar_livestock/presentation/page/root/logic.dart';
|
import 'package:rasadyar_livestock/presentation/page/root/logic.dart';
|
||||||
|
|
||||||
@@ -21,9 +22,11 @@ class MapWidgetLogic extends GetxController with GetTickerProviderStateMixin {
|
|||||||
Timer? _debounceTimer;
|
Timer? _debounceTimer;
|
||||||
RxBool isLoading = false.obs;
|
RxBool isLoading = false.obs;
|
||||||
|
|
||||||
|
late FMTCTileProvider tileProvider;
|
||||||
|
|
||||||
RxList<LatLng> markerLocations = RxList();
|
RxList<LatLng> markerLocations = RxList();
|
||||||
RootLogic rootLogic = Get.find<RootLogic>();
|
RootLogic rootLogic = Get.find<RootLogic>();
|
||||||
LivestockRepository repository = diLiveStock.get<LivestockRepository>();
|
LivestockRepository repository = diLiveStock.get<LivestockRepository>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
@@ -53,6 +56,10 @@ class MapWidgetLogic extends GetxController with GetTickerProviderStateMixin {
|
|||||||
errorLocationType.remove(ErrorLocationType.serviceDisabled);
|
errorLocationType.remove(ErrorLocationType.serviceDisabled);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tileProvider = FMTCTileProvider(stores: {mapStoreKey: BrowseStoreStrategy.readUpdateCreate});
|
||||||
|
|
||||||
|
repository.addLocations(generateRandomLocations(currentLocation.value, 10, 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -60,6 +67,7 @@ class MapWidgetLogic extends GetxController with GetTickerProviderStateMixin {
|
|||||||
super.onReady();
|
super.onReady();
|
||||||
determineCurrentPosition();
|
determineCurrentPosition();
|
||||||
getLoc();
|
getLoc();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -156,9 +164,38 @@ class MapWidgetLogic extends GetxController with GetTickerProviderStateMixin {
|
|||||||
await safeCall(
|
await safeCall(
|
||||||
call: () async => repository.getLocations(),
|
call: () async => repository.getLocations(),
|
||||||
onSuccess: (result) {
|
onSuccess: (result) {
|
||||||
|
iLog("OOOpssss => ${result.length}");
|
||||||
markerLocations.addAll(result);
|
markerLocations.addAll(result);
|
||||||
},
|
},
|
||||||
onError: (error, stackTrace) {},
|
onError: (error, stackTrace) {},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<LatLng> generateRandomLocations(LatLng currentPosition, double radiusInKm, int count) {
|
||||||
|
final random = Random();
|
||||||
|
final locations = <LatLng>[];
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
// فاصله تصادفی (۰ تا radius)
|
||||||
|
final distance = random.nextDouble() * radiusInKm * 1000; // متر
|
||||||
|
// زاویه تصادفی (۰ تا ۲π)
|
||||||
|
final angle = random.nextDouble() * 2 * pi;
|
||||||
|
|
||||||
|
// فاصله به درجه
|
||||||
|
final dx = distance * cos(angle);
|
||||||
|
final dy = distance * sin(angle);
|
||||||
|
|
||||||
|
// 1 درجه lat ≈ 111km
|
||||||
|
final newLat = currentPosition.latitude + (dy / 111000.0);
|
||||||
|
|
||||||
|
// 1 درجه lon ≈ 111km * cos(lat)
|
||||||
|
final newLng = currentPosition.longitude +
|
||||||
|
(dx / (111000.0 * cos(currentPosition.latitude * pi / 180)));
|
||||||
|
|
||||||
|
locations.add(LatLng(newLat, newLng));
|
||||||
|
}
|
||||||
|
|
||||||
|
return locations;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ class MapWidget extends GetView<MapWidgetLogic> {
|
|||||||
flags: InteractiveFlag.all & ~InteractiveFlag.rotate,
|
flags: InteractiveFlag.all & ~InteractiveFlag.rotate,
|
||||||
),
|
),
|
||||||
initialZoom: 15,
|
initialZoom: 15,
|
||||||
|
|
||||||
onPositionChanged: (camera, hasGesture) {
|
onPositionChanged: (camera, hasGesture) {
|
||||||
controller.currentZoom.value = camera.zoom;
|
controller.currentZoom.value = camera.zoom;
|
||||||
/* controller.debouncedUpdateVisibleMarkers(
|
/* controller.debouncedUpdateVisibleMarkers(
|
||||||
@@ -117,6 +118,7 @@ class MapWidget extends GetView<MapWidgetLogic> {
|
|||||||
TileLayer(
|
TileLayer(
|
||||||
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||||
userAgentPackageName: 'ir.mnpc.rasadyar',
|
userAgentPackageName: 'ir.mnpc.rasadyar',
|
||||||
|
tileProvider: controller.tileProvider,
|
||||||
),
|
),
|
||||||
|
|
||||||
ObxValue((markers) {
|
ObxValue((markers) {
|
||||||
@@ -153,8 +155,6 @@ class MapWidget extends GetView<MapWidgetLogic> {
|
|||||||
top: 15,
|
top: 15,
|
||||||
left: 20,
|
left: 20,
|
||||||
child: ObxValue((status) {
|
child: ObxValue((status) {
|
||||||
|
|
||||||
|
|
||||||
return Text("Connection: ${status.value}", style: TextStyle(fontSize: 20));
|
return Text("Connection: ${status.value}", style: TextStyle(fontSize: 20));
|
||||||
}, NetworkStatus().isConnected),
|
}, NetworkStatus().isConnected),
|
||||||
),
|
),
|
||||||
|
|||||||
32
pubspec.lock
32
pubspec.lock
@@ -385,6 +385,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
|
flat_buffers:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flat_buffers
|
||||||
|
sha256: "380bdcba5664a718bfd4ea20a45d39e13684f5318fcd8883066a55e21f37f4c3"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "23.5.26"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -459,6 +467,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
version: "7.0.0"
|
||||||
|
flutter_map_tile_caching:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_map_tile_caching
|
||||||
|
sha256: "1839c6157cf9b444083a626b30f3ba9f6db802ac8bb5292440e1628882faa392"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "10.0.0"
|
||||||
flutter_plugin_android_lifecycle:
|
flutter_plugin_android_lifecycle:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1045,6 +1061,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.0"
|
version: "0.5.0"
|
||||||
|
objectbox:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: objectbox
|
||||||
|
sha256: "25c2e24b417d938decb5598682dc831bc6a21856eaae65affbc57cfad326808d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.3.0"
|
||||||
|
objectbox_flutter_libs:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: objectbox_flutter_libs
|
||||||
|
sha256: "574b0233ba79a7159fca9049c67974f790a2180b6141d4951112b20bd146016a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.3.0"
|
||||||
package_config:
|
package_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
Reference in New Issue
Block a user