Flutter Google Maps实时动态多边形绘制:基于设备移动位置的实地区域追踪技术问询
Solution: Dynamic Polygon Drawing Based on Real-Time Device Location in Flutter Google Maps
Got it, let's adapt your existing manual polygon drawing code to work with real-time device location. Here's a step-by-step implementation that lets you add vertices as you walk to key points, then close the polygon when you return to the starting point:
1. Update Dependencies (if needed)
First, make sure you have the geolocator package installed to handle high-accuracy real-time location updates. Add it to your pubspec.yaml:
dependencies: flutter: sdk: flutter google_maps_flutter: ^2.5.0 geolocator: ^10.1.0
2. Modified State Class Implementation
Here's the updated state code with real-time location tracking, vertex addition, and polygon closure logic:
import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:geolocator/geolocator.dart'; class MyMapScreen extends StatefulWidget { const MyMapScreen({super.key}); @override State<MyMapScreen> createState() => _MyMapScreenState(); } class _MyMapScreenState extends State<MyMapScreen> { Position? _currentPosition; late StreamSubscription<Position> _positionSubscription; Set<Marker> _markers = {}; Set<Polygon> _polygons = {}; List<LatLng> polygonLatLngs1 = []; // Define your preferred colors final Color strokeColor = Colors.blue; final Color fillColor = Colors.blue.withOpacity(0.2); @override void initState() { super.initState(); _startRealTimeLocationTracking(); } @override void dispose() { _positionSubscription.cancel(); super.dispose(); } // Start listening to real-time location updates void _startRealTimeLocationTracking() { _positionSubscription = Geolocator.getPositionStream( locationSettings: const LocationSettings( accuracy: LocationAccuracy.high, // High accuracy for walking paths distanceFilter: 1, // Update location every 1 meter moved ), ).listen((Position position) { setState(() { _currentPosition = position; }); }); } // Update the polygon with the latest vertex list void _updatePolygon() { setState(() { _polygons.clear(); // Only draw if we have at least 3 vertices if (polygonLatLngs1.length >= 3) { _polygons.add(Polygon( polygonId: const PolygonId("tracking-area"), points: polygonLatLngs1, strokeWidth: 2, strokeColor: strokeColor, fillColor: fillColor, )); } else if (polygonLatLngs1.length == 2) { // Optional: Draw a preview line between first two points _polygons.add(Polygon( polygonId: const PolygonId("tracking-area"), points: polygonLatLngs1, strokeWidth: 2, strokeColor: strokeColor, fillColor: Colors.transparent, )); } }); } // Add current location as a polygon vertex (call this when you reach a key point) void drawPolygonNow() { if (_currentPosition == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Waiting for location data...')), ); return; } setState(() { polygonLatLngs1.add(LatLng( _currentPosition!.latitude, _currentPosition!.longitude, )); _updatePolygon(); }); } // Close the polygon when back to starting point void closePolygon() { if (polygonLatLngs1.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Add at least one vertex first!')), ); return; } final startPoint = polygonLatLngs1.first; final currentPoint = polygonLatLngs1.last; // Calculate distance between current position and starting point (in meters) final distance = Geolocator.distanceBetween( startPoint.latitude, startPoint.longitude, currentPoint.latitude, currentPoint.longitude, ); if (distance < 10) { // Consider 10 meters as "back to start" setState(() { // Add starting point again to close the polygon polygonLatLngs1.add(startPoint); _updatePolygon(); }); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Polygon closed successfully!')), ); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Move ${distance.toStringAsFixed(0)} meters back to the starting point to close.')), ); } } // Reset polygon data void resetPolygon() { setState(() { polygonLatLngs1.clear(); _polygons.clear(); }); } @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ GoogleMap( initialCameraPosition: CameraPosition( target: LatLng( _currentPosition?.latitude ?? 0.0, _currentPosition?.longitude ?? 0.0, ), zoom: 18.0, // Close zoom for walking paths ), polygons: _polygons, myLocationEnabled: true, // Show real-time location marker myLocationButtonEnabled: true, onCameraMove: (CameraPosition position) { // Keep your existing onCameraMove logic here }, ), // Control buttons for adding vertices, closing, and resetting Positioned( bottom: 30, left: 20, right: 20, child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ ElevatedButton( onPressed: drawPolygonNow, child: const Text('Add Vertex'), ), ElevatedButton( onPressed: closePolygon, child: const Text('Close Polygon'), ), ElevatedButton( onPressed: resetPolygon, child: const Text('Reset'), ), ], ), ), ], ), ); } }
3. Key Changes Explained
- Real-Time Location Tracking: Uses
Geolocator.getPositionStream()to get high-accuracy updates as you move, ensuring we always have your current location. drawPolygonNow(): Replaces the manual onTap logic—tap this button when you reach a vertex (like a corner of the building/forest) to add your current location to the polygon.- Polygon Closure: The
closePolygon()function checks if you're within 10 meters of the starting point before closing the polygon (you can adjust this distance threshold to fit your needs). - Visual Feedback: Shows a preview line when you have 2 vertices, and fills the polygon once it's closed for clear visual confirmation.
4. Usage Tips
- Make sure to request location permissions in your app (add the necessary permissions to
AndroidManifest.xmlandInfo.plist). - Start your walk at the desired starting point, tap "Add Vertex" to set the first point.
- Walk to each corner/vertex and tap "Add Vertex" to record the position.
- When you return to the starting point, tap "Close Polygon" to complete the shape.
内容的提问来源于stack exchange,提问作者Jacob Okello Okomo
相关产品推荐
相关产品推荐

