Untitled

asd
 avatar
unknown
plain_text
4 years ago
32 kB
4
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...