free_map 2.5.0 copy "free_map: ^2.5.0" to clipboard
free_map: ^2.5.0 copied to clipboard

A Flutter package powered by OpenStreetMap for free map, autocomplete places textfield, polylines drawing, geocoding, and reverse geocoding.

example/main.dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:free_map/free_map.dart';

void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  FmData? _address;
  LatLng? _currentPos;
  bool _loading = false;
  bool _isOverlayVisible = false;
  late final MapController _mapController;
  final _src = const LatLng(37.4165849896396, -122.08051867783071);
  final _dest = const LatLng(37.420921119071586, -122.08535335958004);

  @override
  void initState() {
    super.initState();
    _mapController = MapController();
  }

  @override
  void dispose() {
    _mapController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Builder(builder: (context) {
        return GestureDetector(
          onTap: FocusScope.of(context).unfocus,
          child: Scaffold(
            appBar: AppBar(title: const Text('Free Map Demo')),
            body: SafeArea(
              bottom: false,
              child: Stack(children: [
                _map,
                if (_loading)
                  Container(
                    alignment: Alignment.center,
                    color: Colors.white.withAlpha(112),
                    child: CircularProgressIndicator(),
                  ),
                _searchField
              ]),
            ),
          ),
        );
      }),
    );
  }

  /// Free map widget
  Widget get _map {
    final ignoreTap = _isOverlayVisible || _loading;
    return GestureDetector(
      onTap: ignoreTap ? FocusScope.of(context).unfocus : null,
      child: IgnorePointer(
        ignoring: ignoreTap,
        child: FmMap(
          mapController: _mapController,
          mapOptions: MapOptions(
            minZoom: 5,
            maxZoom: 18,
            initialZoom: 15,
            initialCenter: _src,
            onTap: (pos, point) => _onMapTap(point),
          ),
          markers: [
            Marker(
              point: _currentPos ?? _src,
              child: const Icon(
                size: 40.0,
                color: Colors.red,
                Icons.location_on_rounded,
              ),
            ),
            if (_currentPos == null)
              Marker(
                point: _dest,
                child: const Icon(
                  size: 40.0,
                  color: Colors.blue,
                  Icons.location_on_rounded,
                ),
              ),
          ],
          polylineOptions: const FmPolylineOptions(
            strokeWidth: 3,
            color: Colors.blue,
          ),
        ),
      ),
    );
  }

  /// Auto-complete places search field
  Widget get _searchField {
    return Padding(
      padding: const EdgeInsets.all(20.0),
      child: FmSearchField(
        selectedValue: _address,
        onSelected: _onAddressSelected,
        searchParams: const FmSearchParams(),
        resultViewOptions: FmResultViewOptions(
          onOverlayVisible: (v) => setState(() => _isOverlayVisible = v),
        ),
        textFieldBuilder: (focus, controller, onChanged) {
          return TextFormField(
            focusNode: focus,
            onChanged: onChanged,
            controller: controller,
            decoration: InputDecoration(
              filled: true,
              hintText: 'Search',
              fillColor: Colors.grey[300],
              suffixIcon: controller.text.trim().isEmpty || !focus.hasFocus
                  ? null
                  : IconButton(
                      padding: EdgeInsets.zero,
                      icon: const Icon(Icons.close),
                      onPressed: controller.clear,
                      visualDensity: VisualDensity.compact,
                    ),
            ),
          );
        },
      ),
    );
  }

  /// On address selected from auto-complete search field
  void _onAddressSelected(FmData? data) {
    if (data == null) return;
    _address = data;
    _currentPos = LatLng(data.lat, data.lng);
    _mapController.move(_currentPos!, 12);
  }

  /// REVERSE GEOCODING: Get address from geocode
  Future<void> _onMapTap(LatLng pos) async {
    setState(() => _loading = true);

    final data = await FmService().getAddress(
      lat: pos.latitude,
      lng: pos.longitude,
    );

    _address = data;
    _currentPos = pos;
    setState(() => _loading = false);
  }

  /// GEOCODING: Get geocode from an address
  Future<void> getGeocode(String address) async {
    final data = await FmService().getGeocode(address: address);
    if (kDebugMode) print('${data?.lat},${data?.lng}');
  }
}
11
likes
150
points
453
downloads

Publisher

verified publishervalueoutput.com

Weekly Downloads

A Flutter package powered by OpenStreetMap for free map, autocomplete places textfield, polylines drawing, geocoding, and reverse geocoding.

Topics

#map #geocoding #autocomplete #polylines #openstreetmap

Documentation

API reference

License

Apache-2.0 (license)

Dependencies

flutter, flutter_map, http, latlong2, package_info_plus, path, sqflite

More

Packages that depend on free_map