Simple Tiles Map

Version Flutter Dart

Un package de Flutter para crear mapas base de manera sencilla usando diferentes proveedores de tiles como OpenStreetMap, Google Maps, Stamen, CartoDB y Esri. Compatible con cualquier versión de flutter_map >= 8.0.0.

🎯 Características

  • ✅ Soporte para múltiples proveedores de mapas
  • ✅ Mapas online y offline
  • ✅ Compatible con flutter_map ^8.0.0+
  • ✅ Fácil de usar y configurar
  • ✅ Personalización completa
  • ✅ Atribuciones automáticas

📦 Instalación

Agrega el package a tu pubspec.yaml:

dependencies:
  simple_tiles_map: ^3.0.0
  flutter_map: ^8.0.0
  latlong2: ^0.9.0
  
  # Solo si usarás mapas offline:
  flutter_map_tile_caching: ^10.0.0

🚀 Uso Básico

import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:simple_tiles_map/simple_tiles_map.dart';

class MyMapPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SimpleTilesMap(
        typeMap: TypeMap.osm,
        mapController: MapController(),
        mapOptions: MapOptions(
          initialCenter: LatLng(-16.480954, -68.189594),
          initialZoom: 13.0,
          minZoom: 5.0,
          maxZoom: 18.0,
        ),
      ),
    );
  }
}

🗺️ Tipos de Mapas Disponibles

TypeMap.osm               // OpenStreetMap
TypeMap.osmHot            // OpenStreetMap Humanitarian
TypeMap.osmFr             // OpenStreetMap France
TypeMap.google            // Google Maps
TypeMap.googleSatellite   // Google Satellite
TypeMap.googleHybrid      // Google Hybrid
TypeMap.cartoMapPositron  // Carto Light
TypeMap.cartoMapDark      // Carto Dark
TypeMap.stamenTerrain     // Stamen Terrain
TypeMap.stamenToner       // Stamen Toner
TypeMap.stamenWater       // Stamen Watercolor
TypeMap.esriSatellite     // Esri Satellite
TypeMap.esriStreets       // Esri Streets
TypeMap.esriTopo          // Esri Topographic
TypeMap.custom            // Mapa personalizado

📍 Ejemplo con Marcadores

import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:simple_tiles_map/simple_tiles_map.dart';

class MapWithMarkers extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Mapa con Marcadores')),
      body: SimpleTilesMap(
        typeMap: TypeMap.google,
        mapController: MapController(),
        mapOptions: MapOptions(
          initialCenter: LatLng(-16.480954, -68.189594),
          initialZoom: 13.0,
        ),
        additionalLayers: [
          MarkerLayer(
            markers: [
              Marker(
                point: LatLng(-16.480954, -68.189594),
                width: 80,
                height: 80,
                child: Icon(
                  Icons.location_on,
                  color: Colors.red,
                  size: 40,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

🔌 Uso Offline

Para usar mapas offline, primero debes configurar flutter_map_tile_caching:

1. Agregar dependencia

dependencies:
  flutter_map_tile_caching: ^10.0.0

2. Inicializar en tu app

import 'package:flutter_map_tile_caching/flutter_map_tile_caching.dart';
import 'package:path_provider/path_provider.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Inicializar FMTC
  final appDir = await getApplicationDocumentsDirectory();
  await FMTCObjectBoxBackend().initialise(rootDirectory: appDir.path);
  await FMTCStore('OfflineMap').manage.create();
  
  runApp(MyApp());
}

3. Usar SimpleTilesMap con modo offline

SimpleTilesMap(
  typeMap: TypeMap.osm,
  mapController: MapController(),
  mapOptions: MapOptions(
    initialCenter: LatLng(-16.480954, -68.189594),
    initialZoom: 13.0,
  ),
  isOffline: true,
  storeName: 'OfflineMap',
  cachedValidDuration: 30, // días
)

⚙️ Parámetros de Configuración

Parámetro Tipo Requerido Default Descripción
typeMap TypeMap ✅ - Tipo de mapa a mostrar
mapController MapController ✅ - Controlador del mapa
mapOptions MapOptions ✅ - Opciones de configuración del mapa
customUrlTemplate String? ❌ null URL personalizada para TypeMap.custom
attribution String ❌ " Simple Tiles Map"
additionalLayers List<Widget> ❌ [] Capas adicionales (marcadores, polígonos, etc)
isOffline bool ❌ false Activar modo offline
packageId String ❌ "com.simpletilesmap.app" ID del package para user agent
cachedValidDuration int ❌ 200 Días de validez del caché
storeName String ❌ "OfflineMap" Nombre del store FMTC
showAttribution bool ❌ true Mostrar/ocultar atribuciones

🎨 Ejemplo Completo con UI

import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:simple_tiles_map/simple_tiles_map.dart';

class InteractiveMapPage extends StatefulWidget {
  @override
  _InteractiveMapPageState createState() => _InteractiveMapPageState();
}

class _InteractiveMapPageState extends State<InteractiveMapPage> {
  late MapController _mapController;
  TypeMap _currentMapType = TypeMap.osm;

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

  void _changeMapType(TypeMap newType) {
    setState(() {
      _currentMapType = newType;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Mapa Interactivo'),
        actions: [
          PopupMenuButton<TypeMap>(
            icon: Icon(Icons.layers),
            onSelected: _changeMapType,
            itemBuilder: (context) => [
              PopupMenuItem(
                value: TypeMap.osm,
                child: Text('OpenStreetMap'),
              ),
              PopupMenuItem(
                value: TypeMap.google,
                child: Text('Google Maps'),
              ),
              PopupMenuItem(
                value: TypeMap.googleSatellite,
                child: Text('Google Satellite'),
              ),
              PopupMenuItem(
                value: TypeMap.cartoMapDark,
                child: Text('Carto Dark'),
              ),
            ],
          ),
        ],
      ),
      body: SimpleTilesMap(
        typeMap: _currentMapType,
        mapController: _mapController,
        mapOptions: MapOptions(
          initialCenter: LatLng(-16.480954, -68.189594),
          initialZoom: 13.0,
          minZoom: 5.0,
          maxZoom: 18.0,
        ),
        attribution: "| Mi Aplicación",
      ),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
            heroTag: 'zoom_in',
            mini: true,
            child: Icon(Icons.add),
            onPressed: () {
              _mapController.move(
                _mapController.camera.center,
                _mapController.camera.zoom + 1,
              );
            },
          ),
          SizedBox(height: 8),
          FloatingActionButton(
            heroTag: 'zoom_out',
            mini: true,
            child: Icon(Icons.remove),
            onPressed: () {
              _mapController.move(
                _mapController.camera.center,
                _mapController.camera.zoom - 1,
              );
            },
          ),
        ],
      ),
    );
  }
}

🔄 Migración desde 2.x

Cambios principales:

  1. Inicialización offline: Ahora debes inicializar FMTC manualmente
  2. Dependencias: Eliminadas Isar y path_provider del package
  3. API: Misma API, solo cambia la configuración inicial

Antes (2.x):

// No requería configuración adicional
SimpleTilesMap(
  isOffline: true,
  // ... otros parámetros
)

Ahora (3.x):

// main.dart - Inicializar primero
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final appDir = await getApplicationDocumentsDirectory();
  await FMTCObjectBoxBackend().initialise(rootDirectory: appDir.path);
  await FMTCStore('OfflineMap').manage.create();
  runApp(MyApp());
}

// Usar igual que antes
SimpleTilesMap(
  isOffline: true,
  // ... otros parámetros
)

📄 Licencia

MIT License - Ver LICENSE para más detalles.

🤝 Contribuciones

Las contribuciones son bienvenidas. Por favor abre un issue o pull request en el repositorio.

📧 Contacto

🙏 Créditos

Basado en el package base_map_osm_google.