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
| Property | Type | Description |
|---|---|---|
lazarilloId | String | Unique identifier assigned by Lazarillo |
clientId | String? | External (client-provided) identifier |
title | String | Display name of the place |
description | String | Human-readable description |
category | String | Localized category name (e.g. “Restaurant”) |
categoryId | String | Category identifier |
position | LatLng | Geographic coordinates |
address | String? | Street address |
accessibleRoutes | bool | Whether accessible routes are available |
hasBeacons | bool | Whether BLE beacons exist for indoor positioning |
hasMessagePoints | bool | Whether message points exist |
properties | List<LzProperty> | Custom properties |
innerFloors | Map<String, InnerFloor> | Floor map for multi-floor places |
inFloorId | String? | Floor ID this place belongs to |
logo | String? | URL of the place’s logo image |
API Methods
| Method | Returns | Description |
|---|---|---|
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
- API Key: Ensure your API key has access to the places you want to query
- Nullable results: Both
getPlacesForApiKeyandgetSubPlacesByIdreturnList<LzPlace?>— filter out nulls before displaying - Indoor places: Use
innerFloorsto check if a place has multiple floors, andinFloorIdfor which floor a sub-place belongs to - Place logos: The
logofield contains a URL that can be used withLzAttributeMarker.imageUrl(see Place Marker with Logo)
Last updated on