¿Cómo puedo dibujar líneas (polígonos, círculos) en el mapa con un gesto de la mano y buscar listados de bienes raíces dentro del área de la línea en aleteo?

4 minutos de lectura

soy nuevo en flutter, actualmente estoy desarrollando una aplicación móvil de bienes raíces y quiero poder arrastrar y dibujar líneas (polígono, círculos) en el mapa flutter y devolver listados dentro del área en la que dibujo al igual que en la aplicación redfin.

He probado muchas implementaciones de mapas flutter en línea, pero ninguno de los complementos con los que me encuentro no incluye el dibujo de líneas en el mapa.
Este es un ejemplo de resultado de búsqueda dentro de líneas dibujadas

avatar de usuario de kashlo
Kashlo

Me encontré con este ejemplo de dibujo en Flutter usando CustomPaint y un convertidor agregado de List<Offset> al List<LatLng> usándolo para la creación de polígonos en los mapas de Google (google_maps_flutter enchufar)

https://medium.com/flutter-community/dibujo-en-flutter-usando-custompainter-307a9f1c21f8

  buildPolygon(List<Offset> shape) async {
    final List<LatLng> points = <LatLng>[];
    final devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
    await Future.forEach(shape, (Offset offset) async {
      LatLng point = await mapController.getLatLng(
        ScreenCoordinate(
          x: (offset.dx  * devicePixelRatio).round() ,
          y: (offset.dy * devicePixelRatio).round()
        )
      );
      points.add(point);
    });

    final PolygonId polygonId = PolygonId("1");
    polygon = Polygon(
      polygonId: polygonId,
      consumeTapEvents: true,
      strokeColor: Colors.blue,
      strokeWidth: 5,
      fillColor: Colors.orange.withOpacity(0.2),
      points: points,
    );
  }

Visualización del polígono

GoogleMap(
  polygons: [polygon].toSet(),
  onMapCreated: (GoogleMapController controller) {
    mapController = controller;
  },
)

Para alternar el modo de dibujo en el mapa, puede ponerlo en la Pila de esta manera

 Stack(
   children: <Widget>[
      buildMap(),
      drawingModeOn ? buildMapDraw() : Container(),
   ],
);

resultado final

enchufar:

google_maps_flutter: ^1.0.6

código:

import 'dart:async';
import 'dart:collection';
import 'dart:io';
import 'dart:math' as Math;
import 'AddEditPage.dart';
import 'details.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class MapPage extends StatefulWidget {
  MapPage({Key key}) : super(key: key);

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

class _MapPageState extends State<MapPage> {
  static final Completer<GoogleMapController> _controller = Completer();

  static final CameraPosition _kGooglePlex = CameraPosition(
    target: LatLng(13.0827, 80.2707),
    zoom: 14.4746,
  );

  final Set<Polygon> _polygons = HashSet<Polygon>();
  final Set<Polyline> _polyLines = HashSet<Polyline>();

  bool _drawPolygonEnabled = false;
  List<LatLng> _userPolyLinesLatLngList = List();
  bool _clearDrawing = false;
  int _lastXCoordinate, _lastYCoordinate;

  List<LatLng> _mapLatLang = List();
  List<LatLng> _latLang = List();

  
  _getlatlan(){
    setState(() => LatLng(13.0827, 80.2707));
  }

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

  _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);
        _latLang.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(() {});
    }
  }

  _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;
        _mapLatLang =_userPolyLinesLatLngList;
      });
    }
  }

  _clearPolygons() {
    setState(() {
      _polyLines.clear();
      _polygons.clear();
      _userPolyLinesLatLngList.clear();
    });
  }
var lat = [LatLng(12.82879876203614, 80.12908793985844)];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Farm'),
        iconTheme: IconThemeData(color: Colors.grey.shade800),
        actions: <Widget>[
    FlatButton(
      textColor: Colors.grey.shade800,
      onPressed: () {_drawPolygonEnabled?
        Navigator.push(context, MaterialPageRoute(builder: (context) => AddEditPage(data: new DataLat(_latLang)),),) : null;
      },
      child: _drawPolygonEnabled? Text("Save") : Text("Draw"),
      shape: CircleBorder(side: BorderSide(color: Colors.transparent)),
    ),
  ],
      ),
      body: GestureDetector(
        onPanUpdate: (_drawPolygonEnabled) ? _onPanUpdate : null,
        onPanEnd: (_drawPolygonEnabled) ? _onPanEnd : null,
        child: GoogleMap(
          myLocationEnabled: true,
          mapType: MapType.normal,
          initialCameraPosition: _kGooglePlex,
          polygons: _polygons,
          polylines: _polyLines,
          onMapCreated: (GoogleMapController controller) {
            _controller.complete(controller);
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _toggleDrawing,
        tooltip: 'Drawing',
        child: new IconTheme(
              data: new IconThemeData(
                  color: Colors.grey.shade800), 
              child: new Icon((_drawPolygonEnabled) ? Icons.cancel : Icons.edit),
          ),
      ),
    );
  }

  
}
class DataLat {
  List<LatLng> latLng;

  DataLat(this.latLng);
}

  • Su respuesta podría mejorarse con información de apoyo adicional. Edite para agregar más detalles, como citas o documentación, para que otros puedan confirmar que su respuesta es correcta. Puede encontrar más información sobre cómo escribir buenas respuestas en el centro de ayuda.

    – Comunidad
    Bot

    22/09/2021 a las 17:30

  • Me disculpo contigo. Acabo de comenzar mi carrera en desarrollo, así que no sé cómo escribir la documentación correcta. Trataré de dar completo tan pronto

    – dinesh balan

    22/09/2021 a las 18:07

¿Ha sido útil esta solución?