autocomplete method

Future<List<AutocompleteSuggestion>> autocomplete({
  1. required String query,
  2. LatLng? biasPosition,
  3. SearchFilter? filter,
  4. int maxResults = 5,
  5. PostalCodeMode? postalCodeMode,
  6. List<PlaceFeature> additionalFeatures = const <PlaceFeature>[],
  7. String? language,
  8. bool useCache = true,
})

Sugerencias mientras se escribe. POST /v2/autocomplete.

Es la operación más barata de las que producen sugerencias, y a cambio no devuelve coordenadas: para tenerlas hay que llamar a getPlace con el placeId de la que el usuario elija. Ese es el diseño correcto de una barra de búsqueda — escribir es barato, elegir cuesta una vez.

final sugerencias = await places.autocomplete(
  query: texto,
  biasPosition: posicionActual,
  filter: const SearchFilter(includeCountries: ['ECU']),
);
// y solo cuando el usuario toca una:
final lugar = await places.getPlace(sugerencias[i].placeId!);

biasPosition y filter no son excluyentes: el sesgo ordena, el filtro descarta. Lo que sí es excluyente es rellenar a la vez boundingBox y circle dentro de filter; se comprueba antes de enviar.

maxResults admite de 1 a 20.

El uso previsto de esta operación es siempre IntendedUse.singleUse, y no es una decisión de este paquete: la API rechaza Storage aquí. Una sugerencia a medio escribir no se puede guardar.

Implementation

Future<List<AutocompleteSuggestion>> autocomplete({
  required String query,
  LatLng? biasPosition,
  SearchFilter? filter,
  int maxResults = 5,
  PostalCodeMode? postalCodeMode,
  List<PlaceFeature> additionalFeatures = const <PlaceFeature>[],
  String? language,
  bool useCache = true,
}) async {
  if (query.trim().isEmpty) return const <AutocompleteSuggestion>[];
  _checkFilter(filter, 'autocomplete');
  final limit = _checkResults(maxResults, 1, 20, 'autocomplete');

  final cacheKey = _key(<Object?>[
    'auto',
    query,
    biasPosition,
    filter?.toJson(),
    limit,
    postalCodeMode?.wireName,
    language ?? this.language,
  ]);
  if (useCache) {
    final hit = _autocompleteCache.get(cacheKey);
    if (hit != null) return hit;
  }

  final json = await _transport.postJson(
    operation: 'Autocomplete',
    service: _service,
    path: '/v2/autocomplete',
    body: <String, dynamic>{
      'QueryText': query,
      'MaxResults': limit,
      if (biasPosition != null) 'BiasPosition': biasPosition.toLonLat(),
      if (filter != null && !filter.isEmpty) 'Filter': filter.toJson(),
      'PostalCodeMode': ?postalCodeMode?.wireName,
      if (additionalFeatures.isNotEmpty)
        'AdditionalFeatures': additionalFeatures
            .map((f) => f.wireName)
            .toList(),
      ..._localeFields(language),
      // Fijo a propósito: la API rechaza `Storage` en esta operación.
      'IntendedUse': IntendedUse.singleUse.wireName,
    },
  );

  final results = _items(json)
      .map(AutocompleteSuggestion.fromJson)
      .toList(growable: false);
  if (useCache) _autocompleteCache.set(cacheKey, results);
  return results;
}