Untitled

asd
mail@pastecode.io avatar
unknown
plain_text
2 years ago
26 kB
1
Indexable
Never
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");
    }
  }
}