Quantcast
Channel: Recent Questions - Stack Overflow
Viewing all articles
Browse latest Browse all 12111

Using flutter_maps package, intercative polygons drawn are not all shown , only the last is rendered

$
0
0

I have used flutter_map package:https://github.com/fleaflet/flutter_map

I have already modified it for my own project in such a way that a user can use 1 click to start drawing, simplifying hovering mouse ( no clicks needed), a 2nd click to stop drawing, followed by either a long press to discard the drawing or a right click to save the polygon.

The problem is that ONLY the last one that is just drawn can be seen and as soon as a new polygon is started to be drawn, the previous one disappeared (all others already hidden ;) )

Any comments please?

FYI, my desired platform is Windows only ...

import 'package:flutter/foundation.dart';import 'package:flutter/material.dart';import 'package:flutter_map/flutter_map.dart';import 'package:flutter_map_example/main.dart';import 'package:flutter_map_example/misc/tile_providers.dart';import 'package:flutter_map_example/widgets/drawer/menu_drawer.dart';import 'package:latlong2/latlong.dart'; import 'dart:math';int  polygonssaved = 1; // one is defined as a constant belowtypedef HitValue = ({String title, String subtitle});void writedatajson(List <LatLng> coordinates) async{   Geofences geo;   if (defaultTargetPlatform == TargetPlatform.windows)   {         final parsedCoordinates=coordinates.toString().replaceAll('LatLng(latitude:','[').replaceAll(', longitude:',',').replaceAll('), ','],').replaceAll(')',']');        geo= Geofences(1,mycomputerName , DateTime.now().toString(),'myaudio' ,'emeregency','myprovince'  ,parsedCoordinates  ,'active',1);        geo.writeJsonFile();         }}class PolygonPage extends StatefulWidget {  static const String route = '/polygon';  const PolygonPage({super.key});  @override  State<PolygonPage> createState() => _PolygonPageState();}class _PolygonPageState extends State<PolygonPage> {  bool drawingfinished=true, oncedone=false;  List<LatLng> mypolygonpoints=List.empty(growable: true);  static const double pointSize = 65;  static const double pointY = 250;  final mapController = MapController();  LatLng? latLng; Polygon<HitValue> buildPolygon(List<LatLng> points, HitValue hitvals)   {   final Polygon<HitValue> p= Polygon<HitValue>(                    points:points,     pattern: StrokePattern.dashed(segments: const [50, 20]),     // pattern: const StrokePattern.dotted(),      color: Colors.blue,      borderColor: Colors.red,       rotateLabel: true,     //  label: 'Pre-defined polygon ',      borderStrokeWidth: 2,      hitValue: (      title: 'Created at ${DateTime.now()}',       subtitle: '- Nothing really special here...'   ),      );       return p; }  final LayerHitNotifier<HitValue> _hitNotifier = ValueNotifier(null);  List<HitValue>? _prevHitValues;  List<Polygon<HitValue>>? _hoverGons; List<Polygon<HitValue>> polygonsRaw =<Polygon<HitValue>>[                 Polygon(                  points: const [LatLng(-37.927145, 144.984677), LatLng(-37.931937, 144.985144), LatLng(-37.932306, 144.985144), LatLng(-37.932674, 144.985144), LatLng(-37.932859, 144.985144), LatLng(-37.933227, 144.985144), LatLng(-37.933596, 144.985144), LatLng(-37.93378, 144.98491), LatLng(-37.934149, 144.984443), LatLng(-37.934518, 144.984443), LatLng(-37.934886, 144.984209), LatLng(-37.935071, 144.983742), LatLng(-37.935071, 144.983274), LatLng(-37.935439, 144.983274), LatLng(-37.935439, 144.982807), LatLng(-37.935808, 144.982807), LatLng(-37.935808, 144.982573), LatLng(-37.935808, 144.982106), LatLng(-37.935808, 144.981639), LatLng(-37.935808, 144.981405), LatLng(-37.935808, 144.980938), LatLng(-37.935808, 144.98047), LatLng(-37.935623, 144.980236), LatLng(-37.935623, 144.979769), LatLng(-37.935255, 144.979302), LatLng(-37.935255, 144.978834), LatLng(-37.934886, 144.978133), LatLng(-37.934702, 144.977666), LatLng(-37.934702, 144.977198), LatLng(-37.934333, 144.976965), LatLng(-37.934333, 144.976497), LatLng(-37.933965, 144.976497), LatLng(-37.933965, 144.97603), LatLng(-37.93378, 144.97603), LatLng(-37.93378, 144.975563), LatLng(-37.933412, 144.975329), LatLng(-37.933412, 144.974862), LatLng(-37.933043, 144.974862), LatLng(-37.933043, 144.974394), LatLng(-37.933043, 144.974394)],                pattern: StrokePattern.dashed(segments: const [50, 20]),                // pattern: const StrokePattern.dotted(),                  color: Colors.blue,                  borderColor: Colors.red,                  rotateLabel: true,                  // label: 'Pre-defined polygon ',                  borderStrokeWidth: 2,                  hitValue: (      title:  'Created at ${DateTime.now()}',     subtitle: '- Nothing really special here...'   ),                ), ];  //final List<Polygon<HitValue>> _polygonsRaw = List.empty(growable: true);  late var _polygons =      Map.fromEntries(polygonsRaw.map((e) => MapEntry(e.hitValue, e)));  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(title: const Text('Draw & Manage Geofences ...')),      drawer: const MenuDrawer(PolygonPage.route),      body: Stack(        children: [          Flexible(            child:  FlutterMap(              mapController: mapController,              options: MapOptions(                              keepAlive: true,                              onPositionChanged: (_, __) => updatePoint(context),                              onTap: (tapPos, latLng)   =>{                                                                     drawingfinished=drawingfinished?false:true,                                                                   if (drawingfinished==false) {mypolygonpoints.clear(),// first time click means just started gathering latlngs (previous ones must be deleted)                                                                                            print('1st click ...> drawing has just started ')},                                                                  ScaffoldMessenger.maybeOf(context)?.showSnackBar(   SnackBar(duration: const Duration(milliseconds: 100),                                                                                                                              backgroundColor:Colors.green[400] ,                                                                                                                              content: Text('Primary tap at $latLng')) ),                                                                                                             mypolygonpoints.add(latLng),                                                                  if (drawingfinished==false)  print('2nd click ...> drawing has just Ended for total number of points  ${mypolygonpoints.length} selected ... ')  //called when the 2nd click (finished drawing indicator) is called reporting number of locations gathered                                                                    },                                 onPointerHover: (tapPos, latLng)   =>{   //freehand                                          print('moved .............'),                                       if (!drawingfinished)     {                                                                            mypolygonpoints.add(latLng),                                                                               setState(() => polygonsRaw.add(buildPolygon(mypolygonpoints,(   title:'Created at ${DateTime.now()}',  subtitle: 'the subtitle test'   ))))  ,                                                                            _polygons =      Map.fromEntries(polygonsRaw.map((e) => MapEntry(e.hitValue, e))),                                                                          }                                        },                                                            onLongPress: (tapPos, latLng)  => {     ScaffoldMessenger.maybeOf(context)?.showSnackBar(   SnackBar(duration: const Duration(milliseconds: 1000),                                                                                                                                padding: const EdgeInsets.symmetric(   horizontal: 100,     ),                                                                                                                                  backgroundColor:mypolygonpoints.isNotEmpty ?  Colors.red[400] : Colors.blueAccent,                                                                                                                                width: 500,                                                                                                                                behavior: SnackBarBehavior.floating,                                                                                                                                content: mypolygonpoints.isEmpty ? const Text('No polygons to delete !'): const Text('Polygon Deleted successfully ...') ,                                                                                                                                  shape: RoundedRectangleBorder(      borderRadius: BorderRadius.circular(100),     ))),                                                                   if(mypolygonpoints.isNotEmpty &&drawingfinished )                                                                                      {                                                                                                    setState(() => polygonsRaw.removeRange(polygonssaved,polygonsRaw.length)),                                                                                        _polygons =      Map.fromEntries(polygonsRaw.map((e) => MapEntry(e.hitValue, e))),                                                                                      print('Long press :   ${mypolygonpoints.length} points Deleted --> number of  polygons left :${polygonsRaw.length}'),                                                                                    }                                        },                              onSecondaryTap: (tapPos, latLng)  => {                                                                           ScaffoldMessenger.maybeOf(context)?.showSnackBar(   SnackBar(duration: const Duration(milliseconds: 1000),                                                                                                    padding: const EdgeInsets.symmetric(   horizontal: 100,     ),                                                                                                      backgroundColor:mypolygonpoints.isNotEmpty ?  Colors.red[600] : Colors.greenAccent,                                                                                                    width: 500,                                                                                                    behavior: SnackBarBehavior.floating,                                                                                                    content: mypolygonpoints.isEmpty ? const Text('No polygons to save !'): const Text('Polygon saved successfully ...') ,                                                                                                      shape: RoundedRectangleBorder(      borderRadius: BorderRadius.circular(100),     ))),                                                                       if(mypolygonpoints.isNotEmpty && drawingfinished)     finalizepolygonsaving(),                                                                            },                              initialCenter: myglobalccp,                              initialZoom: 20,                            ),              children:   [                              openStreetMapTileLayer,                                if (latLng != null)                              MarkerLayer(                                    markers: [                                      Marker(                                        width: pointSize,                                        height: pointSize,                                        point: latLng!,                                        child: const Icon(                                          Icons.circle,                                          size: 10,                                          color: Color.fromARGB(255, 252, 3, 3),                                        ),                                      )                                    ],                                  ),                              MouseRegion(                                hitTestBehavior: HitTestBehavior.deferToChild,                                cursor: SystemMouseCursors.click,                                onHover: (_) {                                                   if((!drawingfinished) || mypolygonpoints.isNotEmpty )  return;   // added to avoid unrequired processing fees ( wait till polygon is saved or discarded )                                                  final hitValues = _hitNotifier.value?.hitValues.toList();                                                  if (hitValues == null) return;                                                if (listEquals(hitValues, _prevHitValues)) return;                                                  _prevHitValues = hitValues;                                                  final hoverLines = hitValues.map((v) { //  _polygons =      Map.fromEntries(polygonsRaw.map((e) => MapEntry(e.hitValue, e)));                                                                          final original = _polygons[v]!;                                                          return Polygon<HitValue>(                                                                        points: original.points,                                                                        holePointsList: original.holePointsList,                                                                        color: Colors.blue,                                                                        borderStrokeWidth: 2,                                                                        borderColor: Colors.green,                                                                        disableHolesBorder: original.disableHolesBorder,                                                                      );                                                        }).toList();                                  setState(() => _hoverGons = hoverLines);                                },                                onExit: (_) {if((!drawingfinished) || mypolygonpoints.isNotEmpty )  return;   // added to avoid unrequired processing fees ( wait till polygon is saved or discarded )                                            _prevHitValues = null;                                            setState(() => _hoverGons = null);                                          },                                child: GestureDetector(                                          onTap: () =>_openTouchedGonsModal('Clicked ',                                            _hitNotifier.value!.hitValues,                                            _hitNotifier.value!.coordinate,                                          ),                                          onLongPress: () =>{ _openTouchedGonsModal('Long press ',                                            _hitNotifier.value!.hitValues,                                            _hitNotifier.value!.coordinate,                                          ),                                           },                                          onSecondaryTap: () => _openTouchedGonsModal('Secondary click ',                                            _hitNotifier.value!.hitValues,                                            _hitNotifier.value!.coordinate,                                          ),                                        child: PolygonLayer(                                          hitNotifier: _hitNotifier,                                          simplificationTolerance: 0,                                          polygons: [...polygonsRaw, ...?_hoverGons],                                        ),                                ),                              ),                              const Scalebar(                            textStyle: TextStyle(color: Colors.black, fontSize: 14),                            padding: EdgeInsets.only(right: 10, left: 10, bottom: 40),                            alignment: Alignment.bottomLeft,                          ),                          const Scalebar(                            textStyle: TextStyle(color: Colors.black, fontSize: 14),                            padding: EdgeInsets.only(right: 10, left: 10, bottom: 80),                            alignment: Alignment.bottomLeft,                            length: ScalebarLength.s,                          ),                          const Scalebar(                            textStyle: TextStyle(color: Colors.black, fontSize: 14),                            alignment: Alignment.bottomCenter,                            length: ScalebarLength.s,                          ),                          const Scalebar(                            textStyle: TextStyle(color: Colors.black, fontSize: 14),                            length: ScalebarLength.xxl,                          ),                          const Scalebar(                            textStyle: TextStyle(color: Colors.black, fontSize: 14),                            padding: EdgeInsets.only(right: 10, left: 10, top: 40),                          ),                          const Scalebar(                            textStyle: TextStyle(color: Colors.black, fontSize: 14),                            padding: EdgeInsets.only(right: 10, left: 10, top: 80),                            length: ScalebarLength.s,                          ),                            ],                          ),    ),          Positioned(            top: pointY - pointSize / 2,            left: _getPointX(context) - pointSize / 2,            child: const IgnorePointer(              child: Icon(                Icons.center_focus_strong_outlined,                size: pointSize,                color: Color(0xFF0E0E0F),              ),            ),          ),          Positioned(            top: pointY + pointSize / 2 + 6,            left: 0,            right: 0,            child: IgnorePointer(              child: Text('(${latLng?.latitude.toStringAsFixed(3)},${latLng?.longitude.toStringAsFixed(3)})',                textAlign: TextAlign.center,                style: const TextStyle(                  color: Color.fromARGB(255, 4, 67, 255),                  fontWeight: FontWeight.bold,                  fontSize: 16,                ),              ),            ),          )        ],      ),    );  }  @override  void initState() {    super.initState();    WidgetsBinding.instance.addPostFrameCallback((_) => updatePoint(context));  }  void finalizepolygonsaving(){            setState(() => polygonsRaw.removeRange(polygonssaved,polygonsRaw.length));           _polygons =      Map.fromEntries(polygonsRaw.map((e) => MapEntry(e.hitValue, e)));            setState(() => polygonsRaw.add(buildPolygon(mypolygonpoints,(    title:'Created at ${DateTime.now()}',  subtitle: 'the subtitle test'   ))))  ;              _polygons =      Map.fromEntries(polygonsRaw.map((e) => MapEntry(e.hitValue, e)));            print('Right clicked (Saving Polygon requested) with: ${mypolygonpoints.length} vertices --> NEW number of polygons  =${polygonsRaw.length}');            polygonssaved++;       }  void _openTouchedGonsModal(    String eventType,    List<HitValue> tappedLines,    LatLng coords,  ) {  // if((drawingfinished) && mypolygonpoints.isEmpty )  return; // added to avoid unrequired processing fees ( wait till polygon is saved or discarded )    showModalBottomSheet<void>(      context: context,      builder: (context) => Padding(        padding: const EdgeInsets.all(16),        child: Column(          crossAxisAlignment: CrossAxisAlignment.start,          children: [            const Text('The Geofence(s)',              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),            ),            Text('$eventType at point: (${coords.latitude.toStringAsFixed(6)}, ${coords.longitude.toStringAsFixed(6)})',            ),            const SizedBox(height: 8),            Expanded(              child: ListView.builder(                itemBuilder: (context, index) {                  final tappedLineData = tappedLines[index];                  return ListTile(                    leading: index == 0                        ? const Icon(Icons.vertical_align_top)                        : index == tappedLines.length - 1                            ? const Icon(Icons.vertical_align_bottom)                            : const SizedBox.shrink(),                    title: Text(tappedLineData.title),                    subtitle: Text(tappedLineData.subtitle),                    dense: true,                  );                },                itemCount: tappedLines.length,              ),            ),            const SizedBox(height: 8),            Align(              alignment: Alignment.bottomCenter,              child: SizedBox(                width: double.infinity,                child: OutlinedButton(                  onPressed: () => Navigator.pop(context),                  child: const Text('Close'),                ),              ),            ),          ],        ),      ),    );   }    void updatePoint(BuildContext context) => setState(() => latLng =      mapController.camera.pointToLatLng(Point(_getPointX(context), pointY)));  double _getPointX(BuildContext context) =>      MediaQuery.sizeOf(context).width / 2;}

Viewing all articles
Browse latest Browse all 12111

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>