Untitled
asdunknown
plain_text
4 years ago
26 kB
8
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:geocoder/geocoder.dart' as geo;
import 'package:flutter/material.dart';
import 'package:flutter/services.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/VehicleInfoPage/vehicle_info_page.dart';
class MapPage extends StatefulWidget {
Timer previousTimer;
final String email;
MapPage({
Key key,
this.previousTimer,
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 = [];
int selectedIndex = -1;
//to save address
String address = "";
final Completer<GoogleMapController> _controller = Completer();
DeviceLastInfoModel _deviceLastInfoModel;
//taxi status
int closedTaxiStatus = 0;
int hiredTaxiStatus = 0;
int idleTaxiStatus = 0;
int unknownTaxiStatus = 0;
int activeTaxiStatus = 0;
void _setStatus() {
closedTaxiStatus = 0;
hiredTaxiStatus = 0;
idleTaxiStatus = 0;
unknownTaxiStatus = 0;
activeTaxiStatus = 0;
for (int i = 0; i < _deviceLastInfoModel.deviceLastInfo.length; i++) {
if (_deviceLastInfoModel.deviceLastInfo[i].taxiStatus != null) {
switch (_deviceLastInfoModel
.deviceLastInfo[i].taxiStatus.statusDevices.status) {
case 0:
idleTaxiStatus++;
break;
case 1:
hiredTaxiStatus++;
break;
case 2:
closedTaxiStatus++;
break;
default:
activeTaxiStatus++;
}
} else {
activeTaxiStatus++;
}
}
}
//to Get address with latitude and longitude values
Future<String> getAddress(lat, lng) async {
var coordinates;
coordinates = geo.Coordinates(lat, lng);
var adress =
await geo.Geocoder.local.findAddressesFromCoordinates(coordinates);
return adress.first.addressLine.toString();
}
getLastInfo(String email) async {
await WebService.lastInfo(email).then((value) {
setState(() {
_deviceLastInfoModel = value;
});
});
}
Future<BitmapDescriptor> bitmapDescriptorFromSvgAsset(
BuildContext context, String plaka, String myColor) async {
// Read SVG file as String
// String svgString = await DefaultAssetBundle.of(context).loadString(assetName,);
// Create DrawableRoot from SVG String
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());
}
var bd;
_handleMarker() async {
for (int i = 0; i < _deviceLastInfoModel.deviceLastInfo.length; i++) {
if (_deviceLastInfoModel.deviceLastInfo[i].taxiStatus != null &&
_deviceLastInfoModel
.deviceLastInfo[i].taxiStatus.statusDevices.timeReal *
1000 >
DateTime.now().millisecondsSinceEpoch - 12 * 1000) {
switch (_deviceLastInfoModel
.deviceLastInfo[i].taxiStatus.statusDevices.status) {
case 0:
bd = await bitmapDescriptorFromSvgAsset(
context,
'${_deviceLastInfoModel.deviceLastInfo[i].vehicleLabel}',
'"#E49B0F"');
break;
case 1:
bd = await bitmapDescriptorFromSvgAsset(
context,
'${_deviceLastInfoModel.deviceLastInfo[i].vehicleLabel}',
'"#008000"');
break;
case 2:
bd = await bitmapDescriptorFromSvgAsset(
context,
'${_deviceLastInfoModel.deviceLastInfo[i].vehicleLabel}',
'"#DC143C"');
break;
default:
bd = await bitmapDescriptorFromSvgAsset(
context,
'${_deviceLastInfoModel.deviceLastInfo[i].vehicleLabel}',
'"#808080"');
}
} else {
bd = await bitmapDescriptorFromSvgAsset(
context,
'${_deviceLastInfoModel.deviceLastInfo[i].vehicleLabel}',
'"#808080"');
}
Marker marker = Marker(
icon: bd,
markerId: MarkerId("$i"),
position: LatLng(
_deviceLastInfoModel
.deviceLastInfo[i].lastLocations.lastLocation.latitude,
_deviceLastInfoModel
.deviceLastInfo[i].lastLocations.lastLocation.longitude),
infoWindow: const InfoWindow(),
onTap: () {
setState(() {
selectedIndex = i;
print('selectIndex : $selectedIndex');
getAddress(
_deviceLastInfoModel.deviceLastInfo[i].lastLocations
.lastLocation.latitude,
_deviceLastInfoModel.deviceLastInfo[i].lastLocations
.lastLocation.longitude)
.then((value) {
setState(() {
address = value;
});
});
});
});
markers[MarkerId(i.toString())] = marker;
}
}
Timer timer;
@override
void initState() {
getLastInfo(widget.email);
timer = Timer.periodic(Duration(seconds: 5), (Timer t) {
getLastInfo(widget.email);
_handleMarker();
_setStatus();
print('${DateTime.now().millisecondsSinceEpoch}');
});
super.initState();
}
@override
void dispose() {
mapController.dispose();
super.dispose();
}
@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(
previousTimer:
widget.previousTimer != null ? widget.previousTimer : null,
deviceLastInfoModel: _deviceLastInfoModel,
email: widget.email,
timer: timer,
)),
body: (bd == null)
? Center(child: CircularProgressIndicator())
: WillPopScope(
onWillPop: _onBackPressed,
child: Stack(children: [
GoogleMap(
//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(
_deviceLastInfoModel == null
? 39.952262065691784
: _deviceLastInfoModel.deviceLastInfo[0]
.lastLocations.lastLocation.latitude,
_deviceLastInfoModel == null
? 32.79434192218846
: _deviceLastInfoModel.deviceLastInfo[0]
.lastLocations.lastLocation.longitude),
zoom: _deviceLastInfoModel == null ? 5 : 10),
minMaxZoomPreference: const MinMaxZoomPreference(1, 25),
onMapCreated: _deviceLastInfoModel == null
? null
: (GoogleMapController controller) async {
mapController = controller;
_controller.complete(controller);
//A marker for places
setState(() {
_handleMarker();
});
},
polylines: _polyline,
markers: Set<Marker>.of(markers.values),
),
Align(
alignment: Alignment.topRight,
child: Container(
width: width * 0.20,
height: height * 0.19,
child: Card(
color: Colors.white.withOpacity(0.1),
shadowColor: Colors.grey[300],
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [Row(
children: [
Icon(Icons.circle,color: Colors.green,size: 10,),
Text(" Araç kiralanmış",style: TextStyle(fontSize:12),)
],
),
Row(
children: [
Icon(Icons.circle,color: Colors.yellow,size: 10,),
Text(" Araç boşta",style: TextStyle(fontSize:12),)
],
),
Row(
children: [
Icon(Icons.circle,color: Colors.red,size: 10,),
Text(" Taksimetre kapalı",style: TextStyle(fontSize:12),)
],
),
Row(
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: [
//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: CustomText(
color: Colors.black,
sizes: Sizes.title,
text: _deviceLastInfoModel
.deviceLastInfo[selectedIndex]
.vehicleLabel
.toString(),
),
),
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)));
},
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
// ignore: missing_return
Future<bool> _onBackPressed() {
SystemNavigator.pop();
}
//Select Date for Report
Future<void> _selectDate(BuildContext context, int selectedIndex) async {
String startDate = "";
DateTime date = DateTime.now();
int gmt = date.timeZoneOffset.inHours;
DateTime selectedStartDate = DateTime.now();
String selectedStartString;
final DateTime pickedDate = await showDatePicker(
locale: EasyLocalization.of(context).locale,
context: context,
initialDate: date,
firstDate: DateTime(2015),
lastDate: DateTime.now());
if (pickedDate != null && pickedDate != date) {
setState(() {
selectedStartDate =
DateTime(pickedDate.year, pickedDate.month, pickedDate.day, 0 + gmt)
.toUtc();
selectedStartString = selectedStartDate.millisecondsSinceEpoch
.toString()
.substring(0, 10);
selectedStartString == null
? setState(() {
selectedStartDate =
DateTime(date.year, date.month, date.day, 0 + gmt).toUtc();
selectedStartString = selectedStartDate.millisecondsSinceEpoch
.toString()
.substring(0, 10);
})
: print(" ");
startDate = selectedStartString;
});
startDate != null
? Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPage(
selectIndex: selectedIndex,
date: startDate,
imei: _deviceLastInfoModel
.deviceLastInfo[selectedIndex].vehicleID,
)))
: print("startDate is null");
}
}
}
Editor is loading...