Skip to Content
ExamplesPlaces Management

Places Management Example

This example demonstrates how to load, display, and manage places in Lazarillo Maps Flutter.

Places Management Features

The Lazarillo Maps plugin provides methods to fetch places and their sub-places (children):

Fetch Places

// Fetch all places for an API key final List<LzPlace?> places = await lazarilloMaps.getPlacesForApiKey('your-api-key'); // Fetch sub-places for a specific parent place by ID final List<LzPlace?> subPlaces = await lazarilloMaps.getSubPlacesById(place.lazarilloId);

Get Place Details

// Fetch detailed info for a single place final LzPlace? place = await lazarilloMaps.getPlaceInfo('place-id');

Complete Example

import 'package:flutter/material.dart'; import 'package:lazarillo_maps/lazarillo_maps.dart'; class PlacesManagementExample extends StatefulWidget { const PlacesManagementExample({super.key}); @override State<PlacesManagementExample> createState() => _PlacesManagementExampleState(); } class _PlacesManagementExampleState extends State<PlacesManagementExample> { final String _apiKey = 'your-api-key'; final LazarilloMaps _lazarilloMaps = LazarilloMaps('your-api-key'); List<LzPlace?> _places = []; List<LzPlace?> _subPlaces = []; LzPlace? _selectedPlace; bool _isLoading = false; @override void initState() { super.initState(); _initialize(); } Future<void> _initialize() async { await _lazarilloMaps.initialize(); await _loadPlaces(); } Future<void> _loadPlaces() async { setState(() => _isLoading = true); try { final places = await _lazarilloMaps.getPlacesForApiKey(_apiKey); setState(() { _places = places; _isLoading = false; }); } catch (e) { setState(() => _isLoading = false); debugPrint('Error loading places: $e'); } } Future<void> _loadSubPlaces(LzPlace parentPlace) async { setState(() { _isLoading = true; _selectedPlace = parentPlace; }); try { final subPlaces = await _lazarilloMaps.getSubPlacesById(parentPlace.lazarilloId); setState(() { _subPlaces = subPlaces; _isLoading = false; }); } catch (e) { setState(() => _isLoading = false); debugPrint('Error loading sub-places: $e'); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Places Management'), actions: [ IconButton( onPressed: _loadPlaces, icon: const Icon(Icons.refresh), tooltip: 'Refresh places', ), ], ), body: Column( children: [ if (_selectedPlace != null) Container( padding: const EdgeInsets.all(16), color: Colors.blue.shade50, child: Row( children: [ const Icon(Icons.location_on, color: Colors.blue), const SizedBox(width: 8), Expanded( child: Text( 'Selected: ${_selectedPlace!.title}', style: const TextStyle(fontWeight: FontWeight.bold), ), ), IconButton( onPressed: () { setState(() { _selectedPlace = null; _subPlaces = []; }); }, icon: const Icon(Icons.close), ), ], ), ), Expanded( child: _isLoading ? const Center(child: CircularProgressIndicator()) : _selectedPlace == null ? _buildPlacesList(_places) : _buildPlacesList(_subPlaces), ), ], ), ); } Widget _buildPlacesList(List<LzPlace?> places) { return ListView.builder( itemCount: places.length, itemBuilder: (context, index) { final place = places[index]; if (place == null) return const SizedBox.shrink(); return Card( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), child: ListTile( leading: CircleAvatar(child: Text(place.title[0])), title: Text(place.title), subtitle: Text(place.category), trailing: place.innerFloors.isNotEmpty ? const Icon(Icons.folder, color: Colors.orange) : null, onTap: () => _loadSubPlaces(place), ), ); }, ); } }

LzPlace Properties

PropertyTypeDescription
lazarilloIdStringUnique identifier assigned by Lazarillo
clientIdString?External (client-provided) identifier
titleStringDisplay name of the place
descriptionStringHuman-readable description
categoryStringLocalized category name (e.g. “Restaurant”)
categoryIdStringCategory identifier
positionLatLngGeographic coordinates
addressString?Street address
accessibleRoutesboolWhether accessible routes are available
hasBeaconsboolWhether BLE beacons exist for indoor positioning
hasMessagePointsboolWhether message points exist
propertiesList<LzProperty>Custom properties
innerFloorsMap<String, InnerFloor>Floor map for multi-floor places
inFloorIdString?Floor ID this place belongs to
logoString?URL of the place’s logo image

API Methods

MethodReturnsDescription
getPlacesForApiKey(apiKey)Future<List<LzPlace?>>Fetch all places for the given API key
getSubPlacesById(id)Future<List<LzPlace?>>Fetch sub-places (children) of a place
getPlaceInfo(id)Future<LzPlace?>Fetch detailed info for a single place
setParentPlaceId(id)Future<void>Set the parent place context for the SDK

Important Notes

  1. API Key: Ensure your API key has access to the places you want to query
  2. Nullable results: Both getPlacesForApiKey and getSubPlacesById return List<LzPlace?> — filter out nulls before displaying
  3. Indoor places: Use innerFloors to check if a place has multiple floors, and inFloorId for which floor a sub-place belongs to
  4. Place logos: The logo field contains a URL that can be used with LzAttributeMarker.imageUrl (see Place Marker with Logo)
Last updated on