Untitled
asdunknown
plain_text
4 years ago
32 kB
11
Indexable
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:geocoding/geocoding.dart';
import 'package:google_maps_cluster_manager/google_maps_cluster_manager.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:parstaksimapp/Components/constants.dart';
import 'package:parstaksimapp/Components/custom_button.dart';
import 'package:parstaksimapp/Components/custom_text.dart';
import 'package:parstaksimapp/Models/last_info_model.dart';
import 'package:parstaksimapp/Services/web_service.dart';
import 'package:parstaksimapp/Views/DetailPage/detail_page.dart';
import 'package:parstaksimapp/Views/Menu/menu.dart';
import 'package:parstaksimapp/Views/HomePage/home_page.dart';
import 'package:parstaksimapp/Views/VehicleInfoPage/vehicle_info_page.dart';
class MapPage extends StatefulWidget {
final DeviceLastInfoModel deviceLastInfoModel;
Timer previousTimer;
final String email;
MapPage({
Key key,
this.previousTimer,
this.deviceLastInfoModel,
this.email,
}) : super(key: key);
@override
_MapPageState createState() => _MapPageState();
}
class _MapPageState extends State<MapPage> {
//a controller for map
GoogleMapController mapController;
//for map's markers
Map<MarkerId, Marker> markers = <MarkerId, Marker>{};
//for map's polyline (can show the road map with polylines)
final Set<Polyline> _polyline = {};
//to save coordinates which will add to _polyline array
List<LatLng> latlngSegment1 = [];
List<LatLng> vehiclePos = [];
int selectedIndex = -1;
//to save address
String address = "";
final Completer<GoogleMapController> _controller = Completer();
DeviceLastInfoModel _deviceLastInfoModel;
ClusterManager _clusterManager;
Set<Marker> clusterMarkers = Set();
//taxi status
int closedTaxiStatus = 0;
int hiredTaxiStatus = 0;
int idleTaxiStatus = 0;
int unknownTaxiStatus = 0;
int activeTaxiStatus = 0;
// //to Get address with latitude and longitude values
Future<String> getAddress(lat, lng) async {
List<Placemark> placemarks = await placemarkFromCoordinates(lat, lng);
Placemark place = placemarks[0];
String myAdress =
'${place.street}, ${place.thoroughfare}, No:${place.name}, ${place.postalCode}, ${place.subAdministrativeArea}/${place.administrativeArea}, ${place.country}';
return myAdress;
}
getLastInfo(String email) async {
await WebService.lastInfo(email).then((value) {
setState(() {
_deviceLastInfoModel = value;
});
});
}
_getLastInfoThenSetLocationAndStatus(String email) async {
await WebService.lastInfo(email).then((value) {
setState(() {
_deviceLastInfoModel = value;
});
int countDevice = _deviceLastInfoModel != null
? _deviceLastInfoModel.deviceLastInfo.length
: 0;
vehiclePos = List<LatLng>.filled(countDevice, null);
_setCurrentLocationAndStatus();
});
}
Future<BitmapDescriptor> bitmapDescriptorFromSvgAsset(
BuildContext context, String plaka, String myColor) async {
String svgStrings =
'''<svg width="75" height="50" xmlns="http://www.w3.org/2000/svg">
<path stroke=
"#000"
id="svg_1"
d="m74.14781,
0.22566l-73.83144,-0.00774l0,31.59256l30.27788,0l5.12395,17.65467c0.04658,
0.00774 3.86625,-17.02746 3.86625,-17.02746c0,0 34.48279,0 34.42362,
-0.00774c0.00739,0.00097 0.01513,-0.5015 0.02299,-1.38155c0.00393,
-0.44003 0.0079,-0.97446 0.01188,-1.58755c0.00398,-0.61309 0.00796,
-1.30486 0.01193,-2.05955c0.02677,-7.20252 0.04414,-12.03835 0.05589,
-15.41562c0.01175,-3.37727 0.0179,-5.29597 0.02223,-6.66423c0.00433,
-1.36826 0.00686,-2.18608 0.00844,-2.71689c0.00158,-0.53081 0.00223,
-0.77459 0.00281,-0.99479c0.00058,-0.2202 0.00109,-0.4168 0.00154,
-0.58784c0.00044,-0.17104 0.00082,-0.31653 0.00112,-0.4345c0.0003,
-0.11796 0.00053,-0.2084 0.00069,-0.26935c0.00015,-0.06095 0.00023,
-0.0924 0.00023,-0.0924c-0.0102,3.52301 -0.01745,6.03945 -0.02249,
7.80293c-0.00505,1.76348 -0.00789,2.77399 -0.00928,3.28516c-0.00139,
0.51116 -0.00132,0.52297 -0.00054,0.28903c0.00077,-0.23394 0.00225,
-0.71362 0.0037,-1.18544c0.00144,-0.47182 0.00284,-0.93578 0.00419,
-1.38991c0.00135,-0.45413 0.00266,-0.89844 0.00393,-1.33095c0.00126,
-0.43251 0.00248,-0.85323 0.00364,-1.26018c0.00116,-0.40696 0.00228,
-0.80015 0.00334,-1.17762c-0.02728,9.05903 -0.02086,7.04596 -0.0151,
5.15867c0.00576,-1.88729 0.01086,-3.64879 0.0151,-5.15867c0.00848,
-3.01976 0.01351,-5.03301 0.01351,-5.03301z"
stroke-width="1.7"
fill=$myColor/>
<text y="20.77155" x="6.02531"
fill="#ffffff">$plaka</text>
</svg>''';
DrawableRoot svgDrawableRoot = await svg.fromSvgString(
svgStrings,
null,
);
// toPicture() and toImage() don't seem to be pixel ratio aware, so we calculate the actual sizes here
MediaQueryData queryData = MediaQuery.of(context);
double devicePixelRatio = queryData.devicePixelRatio;
double width =
70 * devicePixelRatio; // where 32 is your SVG's original width
double height = 45 * devicePixelRatio; // same thing
// Convert to ui.Picture
ui.Picture picture = svgDrawableRoot.toPicture(size: Size(width, height));
// Convert to ui.Image. toImage() takes width and height as parameters
// you need to find the best size to suit your needs and take into account the
// screen DPI
ui.Image image = await picture.toImage(width.toInt(), height.toInt());
ByteData bytes = await image.toByteData(format: ui.ImageByteFormat.png);
return BitmapDescriptor.fromBytes(bytes.buffer.asUint8List());
}
_setCurrentLocationAndStatus() async {
closedTaxiStatus = 0;
hiredTaxiStatus = 0;
idleTaxiStatus = 0;
unknownTaxiStatus = 0;
activeTaxiStatus = 0;
if (_deviceLastInfoModel != null) {
for (int i = 0; i < _deviceLastInfoModel.deviceLastInfo.length; i++) {
vehiclePos[i] = LatLng(
_deviceLastInfoModel
.deviceLastInfo[i].lastLocations.lastLocation.latitude,
_deviceLastInfoModel
.deviceLastInfo[i].lastLocations.lastLocation.longitude);
if (_deviceLastInfoModel.deviceLastInfo[i].taxiStatus != null &&
_deviceLastInfoModel
.deviceLastInfo[i].lastLocations.lastLocation.timeReal >=
(DateTime.now().millisecondsSinceEpoch / 1000 - 120).toInt()) {
switch (_deviceLastInfoModel
.deviceLastInfo[i].taxiStatus.statusDevices.status) {
case 0:
idleTaxiStatus++;
await bitmapDescriptorFromSvgAsset(
context,
'${_deviceLastInfoModel.deviceLastInfo[i].vehicleLabel}',
'"#E49B0F"',
).then((value) {
_setMarkerForCurrentLocation(value, i);
});
break;
case 1:
hiredTaxiStatus++;
await bitmapDescriptorFromSvgAsset(
context,
'${_deviceLastInfoModel.deviceLastInfo[i].vehicleLabel}',
'"#008000"')
.then((value) {
_setMarkerForCurrentLocation(value, i);
});
break;
case 2:
closedTaxiStatus++;
await bitmapDescriptorFromSvgAsset(
context,
'${_deviceLastInfoModel.deviceLastInfo[i].vehicleLabel}',
'"#DC143C"')
.then((value) {
_setMarkerForCurrentLocation(value, i);
});
break;
default:
activeTaxiStatus++;
await bitmapDescriptorFromSvgAsset(
context,
'${_deviceLastInfoModel.deviceLastInfo[i].vehicleLabel}',
'"#808080"')
.then((value) {
_setMarkerForCurrentLocation(value, i);
});
}
} else {
activeTaxiStatus++;
await bitmapDescriptorFromSvgAsset(
context,
'${_deviceLastInfoModel.deviceLastInfo[i].vehicleLabel}',
'"#808080"')
.then((value) {
_setMarkerForCurrentLocation(value, i);
});
}
}
}
}
_setMarkerForCurrentLocation(BitmapDescriptor value, int i) {
{
Marker marker = Marker(
icon: value,
markerId: MarkerId("$i"),
position: vehiclePos[i],
infoWindow: const InfoWindow(),
onTap: () {
setState(() {
selectedIndex = i;
print('selectIndex : $selectedIndex');
getAddress(
vehiclePos[i].latitude,
vehiclePos[i].longitude,
).then((value) {
setState(() {
address = value;
});
});
});
});
setState(() {
markers[MarkerId("$i")] = marker;
});
}
}
Timer timer;
@override
void initState() {
_getLastInfoThenSetLocationAndStatus(widget.email);
timer = Timer.periodic(Duration(seconds: 15), (Timer t) {
_getLastInfoThenSetLocationAndStatus(widget.email);
});
super.initState();
}
void _updateMarkers(Set<Marker> clusterMarkers) {
print('Updated ${clusterMarkers.length} markers');
setState(() {
this.clusterMarkers = clusterMarkers;
});
}
@override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
return Scaffold(
appBar: AppBar(
title: Text('HARİTA'),
centerTitle: true,
automaticallyImplyLeading: false,
backgroundColor: Colors.blue.shade900,
leading: Menu(
currentPage: "MapPage",
previousTimer:
widget.previousTimer != null ? widget.previousTimer : null,
deviceLastInfoModel:
_deviceLastInfoModel != null ? _deviceLastInfoModel : null,
email: widget.email,
timer: timer,
)),
body: WillPopScope(
onWillPop: _onBackPressed,
child: Stack(
children: [
GoogleMap(
myLocationButtonEnabled: false,
//This part is for scrolling on map
gestureRecognizers: Set()
..add(
Factory<PanGestureRecognizer>(() => PanGestureRecognizer()))
..add(Factory<ScaleGestureRecognizer>(
() => ScaleGestureRecognizer()))
..add(
Factory<TapGestureRecognizer>(() => TapGestureRecognizer()))
..add(Factory<VerticalDragGestureRecognizer>(
() => VerticalDragGestureRecognizer())),
//************/
mapType: MapType.normal,
initialCameraPosition: CameraPosition(
target: LatLng(
widget.deviceLastInfoModel == null
? 40.77184230219736
: widget.deviceLastInfoModel.deviceLastInfo[0]
.lastLocations.lastLocation.latitude,
widget.deviceLastInfoModel == null
? 30.38627231235851
: widget.deviceLastInfoModel.deviceLastInfo[0]
.lastLocations.lastLocation.longitude),
zoom: widget.deviceLastInfoModel == null ? 5 : 10),
minMaxZoomPreference: const MinMaxZoomPreference(1, 25),
onMapCreated: _deviceLastInfoModel == null
? null
: (GoogleMapController controller) async {
if (!_controller.isCompleted) {
//first calling is false
//call "completer()"
_controller.complete(controller);
// _manager.setMapId(controller.mapId);
} else {}
},
polylines: _polyline,
markers: Set<Marker>.of(markers.values),
),
Align(
alignment: Alignment.bottomLeft,
child: Wrap(
children: [
Container(
// width: width * 0.2,
// height: height * 0.2,
child: Card(
color: Colors.grey.withOpacity(0.7),
shadowColor: Colors.grey[300],
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Wrap(
children: [
Icon(
Icons.circle,
color: Colors.green,
size: 10,
),
Text(
" Araç kiralanmış",
style: TextStyle(fontSize: 12),
)
],
),
Wrap(
children: [
Icon(
Icons.circle,
color: Colors.yellow,
size: 10,
),
Text(
" Araç boşta",
style: TextStyle(fontSize: 12),
)
],
),
Wrap(
children: [
Icon(
Icons.circle,
color: Colors.red,
size: 10,
),
Text(
" Taksimetre kapalı",
style: TextStyle(fontSize: 12),
)
],
),
Wrap(
children: [
Icon(
Icons.circle,
color: Colors.grey[600],
size: 10,
),
Text(
" Durum bilgisi alınmadı",
style: TextStyle(fontSize: 12),
)
],
),
],
),
)),
),
],
),
),
//if any vehicle is selected
selectedIndex >= 0
//A button sheet after user selected a car
? DraggableScrollableSheet(
//Sheet's settings
initialChildSize: width < 390
? 0.48
: width > 500
? 0.58
: 0.49,
minChildSize: width < 390
? 0.47
: width > 500
? 0.33
: 0.47,
maxChildSize: 0.62,
expand: true,
builder: (BuildContext context,
ScrollController scrollController) {
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
return //View
Container(
color: Colors.white,
child: ListView(
shrinkWrap: true,
controller: scrollController,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//fkdsjflkjdlkfjs
//Vehicle Label and Close icon
ListTile(
title: Padding(
padding: width > 500
? const EdgeInsets.only(left: 30.0)
: width > 390
? const EdgeInsets.only(left: 8.0)
: const EdgeInsets.only(left: 0.0),
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
CustomText(
color: Colors.black,
sizes: Sizes.title,
text: _deviceLastInfoModel != null
? _deviceLastInfoModel
.deviceLastInfo[selectedIndex]
.vehicleLabel
: 'ARAÇ YOK!',
),
(_deviceLastInfoModel
.deviceLastInfo[
selectedIndex]
.taxiStatus !=
null &&
_deviceLastInfoModel
.deviceLastInfo[
selectedIndex]
.lastLocations
.lastLocation
.timeReal <
(DateTime.now().millisecondsSinceEpoch /
1000 -
120)
.toInt())
? CustomText(
color: Colors.black,
sizes: Sizes.small,
text: _deviceLastInfoModel !=
null
? 'Bu Son Veri Zamanı : ${DateFormat('dd/MM/yyy kk:mm:ss').format(DateTime.fromMillisecondsSinceEpoch((_deviceLastInfoModel.deviceLastInfo[selectedIndex].lastLocations.lastLocation.timeReal * 1000) + (10800 * 1000)))}'
: '',
)
: SizedBox(),
],
),
),
trailing: Padding(
padding: width > 500
? const EdgeInsets.only(right: 40.0)
: const EdgeInsets.only(right: 8.0),
child: CircleAvatar(
backgroundColor: Colors.grey[300],
child: IconButton(
// ignore: prefer_const_constructors
icon: Icon(
Icons.close,
color: Colors.red,
),
onPressed: () {
setState(
() {
address = "";
selectedIndex = -1;
},
);
},
),
),
),
),
SizedBox(
height: width > 500
? height * 0.05
: width > 390
? height * 0.03
: 0,
),
//Adress
AnimatedOpacity(
duration: const Duration(milliseconds: 2000),
// ignore: unnecessary_null_comparison
opacity: address == null ? 0 : 1,
child: ListTile(
leading: Padding(
padding: width > 500
? const EdgeInsets.only(left: 20.0)
: const EdgeInsets.only(left: 8.0),
child: Icon(
Icons.location_on,
color: const Color(0xffff7643),
size: width > 500
? 60
: width > 390
? 40
: 20,
),
),
title: Text(
address,
maxLines: 2,
style: TextStyle(
color: Colors.black,
fontSize: width > 500
? 22
: width > 390
? 16
: 14),
),
),
),
SizedBox(
height: width > 500
? height * 0.05
: width > 390
? height * 0.03
: height * 0.01),
Row(
children: [
// A button to go to the info page
SizedBox(
width: width * 0.5,
child: CustomButton(
label: "Bilgi",
onPressed: () {
// timer.cancel();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
VehicleInfoPage(
selectIndex: selectedIndex,
email: widget.email,
deviceLastInfoModel:
_deviceLastInfoModel != null
? _deviceLastInfoModel
: null,
),
),
);
},
color: primaryColor,
padding: 10,
),
),
//A button to go to the detail page
SizedBox(
width: width * 0.5,
child: CustomButton(
label: "Detay",
onPressed: () {
_selectDate(context, selectedIndex);
},
color: primaryColor,
padding: 10,
),
),
],
),
],
),
],
),
);
},
)
: const SizedBox(),
],
),
),
);
}
//On back pressed
Future<bool> _onBackPressed() {
timer.cancel();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomePage(
email: widget.email,
previousTimer:
widget.previousTimer != null ? widget.previousTimer : null)),
);
}
// ignore: missing_return
//Select Date for Report
Future<void> _selectDate(BuildContext context, int selectedIndex) async {
String startDateString = "";
DateTime startDateTime = DateTime.now();
int startGmt = startDateTime.timeZoneOffset.inHours;
DateTime selectedStartDate = DateTime.now();
String selectedStartString;
String finishDateString = "";
DateTime finishDateTime = DateTime.now();
int finishGmt = finishDateTime.timeZoneOffset.inHours;
DateTime selectedFinishDate = DateTime.now();
String selectedFinishString;
final DateTimeRange pickedDateRange = await showDateRangePicker(
locale: EasyLocalization.of(context).locale,
context: context,
helpText: 'Başlangıç ve Bitiş Tarihi Seçin',
firstDate: DateTime(2015),
lastDate: DateTime.now(),
);
if (pickedDateRange != null) {
if (pickedDateRange.start != null && pickedDateRange.end != null) {
print(pickedDateRange);
setState(
() {
selectedStartDate = DateTime(
pickedDateRange.start.year,
pickedDateRange.start.month,
pickedDateRange.start.day,
0 + startGmt)
.toUtc();
selectedStartString = selectedStartDate.millisecondsSinceEpoch
.toString()
.substring(0, 10);
selectedStartString == null
? setState(
() {
selectedStartDate = DateTime(
startDateTime.year,
startDateTime.month,
startDateTime.day,
0 + startGmt)
.toUtc();
selectedStartString = selectedStartDate
.millisecondsSinceEpoch
.toString()
.substring(0, 10);
},
)
: print(" ");
startDateString = selectedStartString;
selectedFinishDate = DateTime(
pickedDateRange.end.year,
pickedDateRange.end.month,
pickedDateRange.end.day,
0 + finishGmt)
.toUtc();
selectedFinishString = selectedFinishDate.millisecondsSinceEpoch
.toString()
.substring(0, 10);
selectedFinishString == null
? setState(() {
selectedFinishDate = DateTime(
finishDateTime.year,
finishDateTime.month,
finishDateTime.day,
0 + finishGmt)
.toUtc();
selectedFinishString = selectedFinishDate
.millisecondsSinceEpoch
.toString()
.substring(0, 10);
})
: print(" ");
finishDateString = selectedFinishString;
},
);
}
}
if (pickedDateRange != null) {
if (pickedDateRange.start != null && pickedDateRange.end != null) {
startDateString != null && finishDateString != null
? Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPage(
selectIndex: selectedIndex,
date: startDateString,
finishDate: finishDateString,
imei: _deviceLastInfoModel
.deviceLastInfo[selectedIndex].vehicleID,
),
),
)
: print("startDate or finishDate is null");
}
}
}
}
Editor is loading...