Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
19 kB
1
Indexable
Never
import 'dart:async';
import 'dart:collection';
import 'dart:io';
import 'dart:math' as Math;
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:google_maps_utils/google_maps_utils.dart';
import 'package:parstaksimapp/Models/last_info_model.dart';
import 'package:parstaksimapp/Services/web_service.dart';
import 'package:parstaksimapp/Views/HomePage/home_page.dart';

class DrawArea extends StatefulWidget {
  final String email;
  final int selectedIndex;
  final LatLng firstPosition;
  DrawArea({Key key, this.email, this.selectedIndex, this.firstPosition})
      : super(key: key);

  @override
  _DrawAreaState createState() => _DrawAreaState();
}

class _DrawAreaState extends State<DrawArea> {
  final _scaffKey = GlobalKey<ScaffoldState>();
  static final Completer<GoogleMapController> _controller = Completer();

  TextEditingController userController;
  double userDefinedCounterInside = -1;
  double userDefinedCounterOutside = -1;
  double _counterInside = -1;
  double _counterOutside = -1;
  Timer timer;

  final Set<Polygon> _polygons = HashSet<Polygon>();
  final Set<Polyline> _polyLines = HashSet<Polyline>();
  Marker marker;
  Map<MarkerId, Marker> markers = <MarkerId, Marker>{};

  bool _drawPolygonEnabled = false;
  List<LatLng> _userPolyLinesLatLngList = [];
  List<Point> _userPolygon = [];
  List<List<Point>> userPolygons = [];
  bool _clearDrawing = false;
  int _lastXCoordinate, _lastYCoordinate;

  Position currentLocation;
  bool containsInside;
  bool wantInside = false;
  bool wantOutside = false;

  DeviceLastInfoModel deviceLastInfoModel;

  getUserLocation() async {
    currentLocation = await locateUser();
  }

  getLastInfo(String email) async {
    await WebService.lastInfo(email).then((value) {

        deviceLastInfoModel = value;

    });
  }

  setFirstPosition() {
    marker = Marker(
        markerId: const MarkerId("0"),
        position: widget.firstPosition,
        infoWindow: const InfoWindow(),
        onTap: () {});
    markers[const MarkerId("0")] = marker;
  }

  setCurrentLocation() {
    marker = Marker(
        markerId: const MarkerId("0"),
        position: LatLng(
            deviceLastInfoModel.deviceLastInfo[widget.selectedIndex]
                .lastLocations.lastLocation.latitude,
            deviceLastInfoModel.deviceLastInfo[widget.selectedIndex]
                .lastLocations.lastLocation.longitude),
        infoWindow: const InfoWindow(),
        onTap: () {});

    markers[const MarkerId("0")] = marker;
  }

  Future<Position> locateUser() async {
    return Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high);
  }

  void initState() {
    userController = new TextEditingController();
    setFirstPosition();
    timer = new Timer(const Duration(seconds: 15), () {
            setState(() {
              getLastInfo(widget.email);
            });
      if (deviceLastInfoModel.deviceLastInfoResult == true) {
        setCurrentLocation();
      }
          });
    //Point Timer
    Timer.periodic(Duration(seconds: 1), (Timer t) {
      getUserLocation();
      containsInside = PolyUtils.containsLocationPoly(
          Point(currentLocation.latitude, currentLocation.longitude),
          userPolygons[0]);
      if (wantInside || wantOutside) {}
      if (wantInside) {
        if (containsInside && _counterInside > 0) {
          print("İçinde, $_counterInside");
          _counterInside--;
        } else if (containsInside && _counterInside == 0) {
          print(
              "---------------------------------Bildirim---------------------------------");
          _counterInside = userDefinedCounterInside;
        } else if (!containsInside) {
          _counterInside = userDefinedCounterInside;
        }
      }
      if (wantOutside) {
        if (!containsInside && _counterOutside > 0) {
          print("Dışında, $_counterOutside");
          _counterOutside--;
        } else if (!containsInside && _counterOutside == 0) {
          print(
              "---------------------------------Bildirim---------------------------------");
          _counterOutside = userDefinedCounterOutside;
        } else if (containsInside) {
          _counterOutside = userDefinedCounterOutside;
        }
      }
    });
    //getLastInfo Timer
    getLastInfo(widget.email);
    Timer.periodic(Duration(seconds: 15), (timer) {
      getLastInfo(widget.email);
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.blue.shade900,
        leading: IconButton(
          onPressed: () {
            timer.cancel();
            Navigator.pop(context);
          },
          icon: const Icon(Icons.arrow_back),
        ),
      ),
      resizeToAvoidBottomInset: false,
      key: _scaffKey,
      body: GestureDetector(
        onPanUpdate: (_drawPolygonEnabled) ? _onPanUpdate : null,
        onPanEnd: (_drawPolygonEnabled) ? _onPanEnd : null,
        child: GoogleMap(
          mapType: MapType.normal,
          initialCameraPosition: CameraPosition(
            target: widget.firstPosition,
            zoom: 17,
          ),
          polygons: _polygons,
          polylines: _polyLines,
          myLocationEnabled: true,
          myLocationButtonEnabled: true,
          onMapCreated: (GoogleMapController controller) {
            if (!_controller.isCompleted) {
              //first calling is false
              //call "completer()"
              _controller.complete(controller);
            } else {
              //other calling, later is true,
              //don't call again completer()
            }
          },
          markers: Set<Marker>.of(markers.values),
        ),
      ),
      floatingActionButton:
          Column(mainAxisAlignment: MainAxisAlignment.center, children: [
        FloatingActionButton(
          child: Icon(Icons.arrow_upward_rounded),
          onPressed: () {
            showDialog(
                context: context, builder: (context) => _userPopUp(context));
          },
          heroTag: "btn1",
        ),
        SizedBox(
          height: 10,
        ),
        FloatingActionButton(
          onPressed: _toggleDrawing,
          tooltip: 'Drawing',
          child: Icon((_drawPolygonEnabled) ? Icons.cancel : Icons.edit),
          heroTag: "btn2",
        )
      ]),
    );
  }

  Widget _userTimePopUp(context, bool isInside) {
    return Align(
      alignment: Alignment.topCenter,
      child: Container(
        padding: EdgeInsets.all(0.1),
        height: MediaQuery.of(context).size.width * .18,
        width: MediaQuery.of(context).size.width * .3,
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(40),
        ),
        margin: EdgeInsets.all(15),
        child: Column(
          children: <Widget>[
            SizedBox(
              height: MediaQuery.of(context).size.width * .14,
              child: Center(
                child: Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Material(
                    child: TextField(
                      autofocus: true,
                      controller: userController,
                      decoration: new InputDecoration(
                        border: new OutlineInputBorder(
                          borderSide: BorderSide(
                            color: Theme.of(context).colorScheme.primary,
                          ),
                          borderRadius: const BorderRadius.all(
                            const Radius.circular(10.0),
                          ),
                        ),
                        focusedBorder: new OutlineInputBorder(
                          borderSide: BorderSide(
                            color: Theme.of(context).colorScheme.primary,
                          ),
                          borderRadius: const BorderRadius.all(
                            const Radius.circular(10.0),
                          ),
                        ),
                        enabledBorder: new OutlineInputBorder(
                          borderSide: BorderSide(
                            color: Theme.of(context).colorScheme.primary,
                          ),
                          borderRadius: const BorderRadius.all(
                            const Radius.circular(10.0),
                          ),
                        ),
                        errorBorder: new OutlineInputBorder(
                          borderSide: BorderSide(
                            color: Theme.of(context).colorScheme.error,
                          ),
                          borderRadius: const BorderRadius.all(
                            const Radius.circular(10.0),
                          ),
                        ),
                        filled: true,
                        hintText: 'Süre Giriniz (Saniye)',
                        hintStyle: TextStyle(fontSize: 16.0),
                      ),
                    ),
                  ),
                ),
              ),
            ),
            SizedBox(
              height: MediaQuery.of(context).size.width * .025,
              child: Center(
                child: Align(
                  alignment: Alignment.center,
                  child: RaisedButton(
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(18.0),
                    ),
                    color: Colors.black,
                    child: Text(
                      'Kaydet',
                      style: TextStyle(
                          color: Theme.of(context).colorScheme.onSecondary),
                    ),
                    onPressed: () async {
                      if (userController.text.isNotEmpty) {
                        if (isInside) {
                          setState(() {
                            wantInside = true;
                            userDefinedCounterInside =
                                double.parse(userController.text);
                            _counterInside = userDefinedCounterInside;
                          });
                        } else {
                          setState(() {
                            wantOutside = true;
                            userDefinedCounterOutside =
                                double.parse(userController.text);
                            _counterOutside = userDefinedCounterOutside;
                          });
                        }

                        userController.clear();
                        Navigator.pop(context);
                      } else {
                        showSnackPlzWithMessage(
                            context, 'Süre giriş kısmı boş kalamaz.');
                        Navigator.pop(context);
                      }
                    },
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  showSnackPlzWithMessage(BuildContext context, String message) {
    final SnackBar snackMe = SnackBar(
      content: new Text(message),
    );
    _scaffKey.currentState.showSnackBar(snackMe);
  }

  _toggleDrawing() {
    // showDialog(
    //     context: context,
    //     builder: (BuildContext context) {
    //       return AlertDialog(title: Text("Kaydet"));
    //     });

    _clearPolygons();
    setState(() => _drawPolygonEnabled = !_drawPolygonEnabled);
  }

  Widget _userPopUp(context) {
    return Align(
      alignment: Alignment.topCenter,
      child: Container(
        padding: EdgeInsets.all(5),
        height: MediaQuery.of(context).size.height * .27,
        width: MediaQuery.of(context).size.width * .215,
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(40),
        ),
        margin: EdgeInsets.all(15),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            Row(
              children: [
                SizedBox(
                  height: MediaQuery.of(context).size.height * .085,
                  width: MediaQuery.of(context).size.width * .155,
                  child: Center(
                    child: Align(
                      alignment: Alignment.center,
                      child: RaisedButton(
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(18.0),
                        ),
                        color: Colors.black,
                        child: Text(
                          ' Bölge İçi ',
                          softWrap: false,
                          style: TextStyle(
                              color: Theme.of(context).colorScheme.onSecondary),
                        ),
                        onPressed: () {
                          Navigator.pop(context);
                          showDialog(
                              context: context,
                              builder: (context) =>
                                  _userTimePopUp(context, true));
                        },
                      ),
                    ),
                  ),
                ),
                wantInside
                    ? SizedBox(
                        height: MediaQuery.of(context).size.height * .073,
                        width: MediaQuery.of(context).size.width * .026,
                        child: RawMaterialButton(
                          child: Icon(Icons.delete),
                          onPressed: () {
                            wantInside = false;
                            Navigator.pop(context);
                          },
                        ))
                    : SizedBox(),
              ],
            ),
            Row(
              children: [
                SizedBox(
                  height: MediaQuery.of(context).size.height * .085,
                  width: MediaQuery.of(context).size.width * .155,
                  child: Center(
                    child: Align(
                      alignment: Alignment.center,
                      child: RaisedButton(
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(18.0),
                        ),
                        color: Colors.black,
                        child: Text(
                          'Bölge Dışı',
                          softWrap: false,
                          style: TextStyle(
                              color: Theme.of(context).colorScheme.onSecondary),
                        ),
                        onPressed: () {
                          Navigator.pop(context);
                          showDialog(
                              context: context,
                              builder: (context) =>
                                  _userTimePopUp(context, false));
                        },
                      ),
                    ),
                  ),
                ),
                SizedBox(
                    height: MediaQuery.of(context).size.height * .073,
                    width: MediaQuery.of(context).size.width * .026,
                    child: wantOutside
                        ? RawMaterialButton(
                            child: Icon(Icons.delete),
                            onPressed: () {
                              wantOutside = false;
                              Navigator.pop(context);
                            },
                          )
                        : null),
              ],
            ),
          ],
        ),
      ),
    );
  }

  _onPanUpdate(DragUpdateDetails details) async {
    // To start draw new polygon every time.
    if (_clearDrawing) {
      _clearDrawing = false;
      _clearPolygons();
    }

    if (_drawPolygonEnabled) {
      double x, y;
      if (Platform.isAndroid) {
        // It times in 3 without any meaning,
        // We think it's an issue with GoogleMaps package.
        x = details.globalPosition.dx * 3;
        y = details.globalPosition.dy * 3;
      } else if (Platform.isIOS) {
        x = details.globalPosition.dx;
        y = details.globalPosition.dy;
      }

      // Round the x and y.
      int xCoordinate = x.round();
      int yCoordinate = y.round();

      // Check if the distance between last point is not too far.
      // to prevent two fingers drawing.
      if (_lastXCoordinate != null && _lastYCoordinate != null) {
        var distance = Math.sqrt(Math.pow(xCoordinate - _lastXCoordinate, 2) +
            Math.pow(yCoordinate - _lastYCoordinate, 2));
        // Check if the distance of point and point is large.
        if (distance > 80.0) return;
      }

      // Cached the coordinate.
      _lastXCoordinate = xCoordinate;
      _lastYCoordinate = yCoordinate;

      ScreenCoordinate screenCoordinate =
          ScreenCoordinate(x: xCoordinate, y: yCoordinate);

      final GoogleMapController controller = await _controller.future;
      LatLng latLng = await controller.getLatLng(screenCoordinate);

      try {
        // Add new point to list.
        _userPolyLinesLatLngList.add(latLng);

        _polyLines.removeWhere(
            (polyline) => polyline.polylineId.value == 'user_polyline');
        _polyLines.add(
          Polyline(
            polylineId: PolylineId('user_polyline'),
            points: _userPolyLinesLatLngList,
            width: 2,
            color: Colors.blue,
          ),
        );
      } catch (e) {
        print(" error painting $e");
      }
      setState(() {
        _userPolygon = _userPolyLinesLatLngList
            .map((e) => Math.Point(e.latitude, e.longitude))
            .toList();
        userPolygons.insert(0, _userPolygon);
        print(userPolygons[0]);
      });
    }
  }

  _onPanEnd(DragEndDetails details) async {
    // Reset last cached coordinate
    _lastXCoordinate = null;
    _lastYCoordinate = null;

    if (_drawPolygonEnabled) {
      _polygons
          .removeWhere((polygon) => polygon.polygonId.value == 'user_polygon');
      _polygons.add(
        Polygon(
          polygonId: PolygonId('user_polygon'),
          points: _userPolyLinesLatLngList,
          strokeWidth: 2,
          strokeColor: Colors.blue,
          fillColor: Colors.blue.withOpacity(0.4),
        ),
      );
      setState(() {
        _clearDrawing = true;
      });
    }
  }

  _clearPolygons() {
    setState(() {
      _polyLines.clear();
      _polygons.clear();
      _userPolyLinesLatLngList.clear();
      _userPolygon.clear();
    });
  }
}