Skip to content
cccskills
FreePublished on GitHub

map-integration

Google Maps and Mapbox integration for Flutter applications

The English summary is being prepared. Showing the original description.

Works withGoogle Cloud
See how to install

Files included (1)

  • SKILL.md9.3 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Skill 18: Map Integration

Overview

This skill enables map integration in Flutter applications using Google Maps and Mapbox. Includes features like markers, polylines, clustering, custom styles, and location tracking.

Features

  • Google Maps integration
  • Mapbox integration
  • Custom markers and clusters
  • Location tracking
  • Polylines and polygons
  • Offline maps support
  • Geocoding and reverse geocoding
  • Directions and routing

Installation

Dependencies

dependencies:
  google_maps_flutter: ^2.5.0
  mapbox_gl: ^0.16.0
  geolocator: ^10.1.0
  geocoding: ^2.1.1
  flutter_polyline_points: ^2.0.0
  maps_toolkit: ^3.0.0

Google Maps Setup

1. Configuration

Android:

<!-- AndroidManifest.xml -->
<manifest>
  <application>
    <meta-data
      android:name="com.google.android.geo.API_KEY"
      android:value="YOUR_API_KEY" />
  </application>
</manifest>

iOS:

<!-- AppDelegate.swift -->
import GoogleMaps

GMSServices.provideAPIKey("YOUR_API_KEY")

2. Basic Map Widget

import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:flutter/material.dart';

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

  @override
  State<MapPage> createState() => _MapPageState();
}

class _MapPageState extends State<MapPage> {
  GoogleMapController? _mapController;

  static const CameraPosition _initialPosition = CameraPosition(
    target: LatLng(37.7749, -122.4194), // San Francisco
    zoom: 12,
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GoogleMap(
        mapType: MapType.normal,
        initialCameraPosition: _initialPosition,
        onMapCreated: (controller) {
          _mapController = controller;
        },
        myLocationEnabled: true,
        myLocationButtonEnabled: true,
      ),
    );
  }

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

3. Map Service

class MapService {
  GoogleMapController? _controller;

  void setController(GoogleMapController controller) {
    _controller = controller;
  }

  Future<void> animateToLocation(LatLng location, {double zoom = 15}) async {
    await _controller?.animateCamera(
      CameraUpdate.newCameraPosition(
        CameraPosition(target: location, zoom: zoom),
      ),
    );
  }

  Future<void> addMarker(Marker marker) async {
    // Implementation depends on your state management
  }

  Future<void> drawPolyline(List<LatLng> points) async {
    // Implementation
  }
}

Markers and Clusters

class MarkerManager {
  final Set<Marker> _markers = {};

  Set<Marker> get markers => _markers;

  void addMarker({
    required String id,
    required LatLng position,
    String? title,
    String? snippet,
    BitmapDescriptor? icon,
  }) {
    final marker = Marker(
      markerId: MarkerId(id),
      position: position,
      infoWindow: InfoWindow(
        title: title,
        snippet: snippet,
      ),
      icon: icon ?? BitmapDescriptor.defaultMarker,
    );

    _markers.add(marker);
  }

  void removeMarker(String id) {
    _markers.removeWhere((marker) => marker.markerId.value == id);
  }

  void clearMarkers() {
    _markers.clear();
  }
}

Location Tracking

import 'package:geolocator/geolocator.dart';

class LocationService {
  Future<Position> getCurrentLocation() async {
    bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      throw Exception('Location services are disabled');
    }

    LocationPermission permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        throw Exception('Location permissions are denied');
      }
    }

    return await Geolocator.getCurrentPosition();
  }

  Stream<Position> getLocationStream() {
    return Geolocator.getPositionStream(
      locationSettings: const LocationSettings(
        accuracy: LocationAccuracy.high,
        distanceFilter: 10, // meters
      ),
    );
  }
}

// Usage in a map
class TrackingMap extends ConsumerWidget {
  const TrackingMap({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final locationService = LocationService();

    return StreamBuilder<Position>(
      stream: locationService.getLocationStream(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          return const Center(child: CircularProgressIndicator());
        }

        final position = snapshot.data!;

        return GoogleMap(
          initialCameraPosition: CameraPosition(
            target: LatLng(position.latitude, position.longitude),
            zoom: 15,
          ),
          markers: {
            Marker(
              markerId: const MarkerId('currentLocation'),
              position: LatLng(position.latitude, position.longitude),
              icon: BitmapDescriptor.defaultMarkerWithHue(
                BitmapDescriptor.hueBlue,
              ),
            ),
          },
        );
      },
    );
  }
}

Routing and Directions

import 'package:flutter_polyline_points/flutter_polyline_points.dart';

class RoutingService {
  final String apiKey;
  final PolylinePoints _polylinePoints = PolylinePoints();

  RoutingService({required this.apiKey});

  Future<List<LatLng>> getDirections(
    LatLng origin,
    LatLng destination,
  ) async {
    final result = await _polylinePoints.getRouteBetweenCoordinates(
      googleApiKey: apiKey,
      request: PolylineRequest(
        origin: PointLatLng(origin.latitude, origin.longitude),
        destination: PointLatLng(destination.latitude, destination.longitude),
        mode: TravelMode.driving,
      ),
    );

    if (result.points.isNotEmpty) {
      return result.points
          .map((point) => LatLng(point.latitude, point.longitude))
          .toList();
    }

    return [];
  }
}

Complete Map Example

class RescueMapPage extends ConsumerStatefulWidget {
  const RescueMapPage({super.key});

  @override
  ConsumerState<RescueMapPage> createState() => _RescueMapPageState();
}

class _RescueMapPageState extends ConsumerState<RescueMapPage> {
  GoogleMapController? _controller;
  final Set<Marker> _markers = {};
  List<LatLng> _routePoints = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Rescue Map')),
      body: Stack(
        children: [
          GoogleMap(
            mapType: MapType.normal,
            initialCameraPosition: const CameraPosition(
              target: LatLng(37.7749, -122.4194),
              zoom: 12,
            ),
            markers: _markers,
            polylines: {
              Polyline(
                polylineId: const PolylineId('route'),
                points: _routePoints,
                color: Colors.blue,
                width: 5,
              ),
            },
            onMapCreated: (controller) {
              _controller = controller;
              _loadRescueLocations();
            },
            onTap: _handleMapTap,
          ),
          Positioned(
            bottom: 16,
            right: 16,
            child: FloatingActionButton(
              onPressed: _centerOnCurrentLocation,
              child: const Icon(Icons.my_location),
            ),
          ),
        ],
      ),
    );
  }

  void _loadRescueLocations() {
    // Add rescue markers
    setState(() {
      _markers.addAll([
        Marker(
          markerId: const MarkerId('rescue1'),
          position: const LatLng(37.7849, -122.4094),
          infoWindow: const InfoWindow(
            title: 'Dog Rescue',
            snippet: 'Urgent - Needs transport',
          ),
          icon: BitmapDescriptor.defaultMarkerWithHue(
            BitmapDescriptor.hueRed,
          ),
        ),
      ]);
    });
  }

  void _handleMapTap(LatLng position) {
    // Add marker at tap location
    setState(() {
      _markers.add(
        Marker(
          markerId: MarkerId('tap_${position.latitude}_${position.longitude}'),
          position: position,
        ),
      );
    });
  }

  Future<void> _centerOnCurrentLocation() async {
    final position = await LocationService().getCurrentLocation();
    _controller?.animateCamera(
      CameraUpdate.newLatLng(
        LatLng(position.latitude, position.longitude),
      ),
    );
  }
}

Best Practices

  1. Request location permissions properly - Handle all permission states
  2. Dispose controllers - Always dispose map controllers
  3. Limit markers - Use clustering for large numbers of markers
  4. Cache tiles - Enable map tile caching for offline use
  5. Optimize updates - Don't rebuild map on every state change

Troubleshooting

Map not showing

  • Check API key is valid
  • Verify billing is enabled on Google Cloud
  • Enable Maps SDK for Android/iOS in Google Cloud Console

Location not working

  • Verify location permissions in manifest
  • Check if location services are enabled
  • Test on physical device (emulator may have issues)

High memory usage

  • Limit number of markers
  • Use marker clustering
  • Dispose controllers properly
  • Clear cache when not needed

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Machine Learning integration for Flutter using TensorFlow Lite and Firebase ML

The English summary is being prepared. Showing the original description.

chimeranext/flutter-boilerplate-monorepo-template4Updated Oct 13, 2026

Payment processing integration with Stripe and PayPal for Flutter

The English summary is being prepared. Showing the original description.

chimeranext/flutter-boilerplate-monorepo-template4Updated Oct 13, 2026

Instructions for translating Google Stitch designs (HTML/Tailwind) into production-ready Flutter/Dart code.

The English summary is being prepared. Showing the original description.

chimeranext/flutter-boilerplate-monorepo-template4Updated Oct 13, 2026

Video and audio processing capabilities for Flutter applications

The English summary is being prepared. Showing the original description.

chimeranext/flutter-boilerplate-monorepo-template4Updated Oct 13, 2026

WebSocket and Socket.io integration for real-time communication in Flutter

The English summary is being prepared. Showing the original description.

chimeranext/flutter-boilerplate-monorepo-template4Updated Oct 13, 2026

See all skills by chimeranext

Report a problem with this skill