HERE API 自动建议地理编码搜索

发布于 2025-01-12 20:44:39 字数 664 浏览 0 评论 0原文

我希望使用 HERE 地理编码自动建议。我了解 API 的工作原理,也是我寻求指导的 Flutter 实现。

以前的版本有一个 Javascript 示例,

    https://developer.here.com/documentation/examples/rest/geocoding_suggestions 

这演示了调用和 Json 返回,但我想知道在显示数据时是否有任何 Flutter 示例/实现指南。

例如,API 返回“伦敦”的地址结果,Flutter 是否具有内置功能来向用户显示这些结果(例如 TypeAheadField),例如在输入字段下方的下拉样式框中,如下面的此处屏幕截图,其中用户可以选择正确的建议吗?这个函数的调用是如何实现的呢? 此处屏幕截图

我想我会利用 onChanged/SetState 风格的函数来调用和显示,但它是如何在用户输入时进行调用然后显示返回的建议我会发现一个有用的例子。

欢迎任何资源/提示

谢谢

I am looking to use the HERE Geocoding Autosuggest. I understand how the API works and it is the implementation in Flutter I seek guidance on.

There is a Javascript example for the previous version

    https://developer.here.com/documentation/examples/rest/geocoding_suggestions 

This demonstrates the call and Json return, but I wondered if there were any Flutter examples/ guidance on implementation when it comes to displaying the data.

For example, the API returns address results for 'London', does Flutter have build in functionality to display these to the user (Such as TypeAheadField), in a dropdown style box below entry field for example, like the HERE screenshot below, where the user can select the correct suggestion? How would the call be implemented with this function?
HERE Screenshot

I presume I will utilise an onChanged/SetState style function to call and display, but it is how to make the call as user types and then display the returned suggestion that I would find an example useful.

Any resources/ tips welcome

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

当爱已成负担 2025-01-19 20:44:39

请检查下面的代码,它解释了颤振中自动建议的使用。

import 'dart:typed_data';

import 'package:flutter/services.dart';
import 'package:here_sdk/core.dart';
import 'package:here_sdk/core.errors.dart';
import 'package:here_sdk/gestures.dart';
import 'package:here_sdk/mapview.dart';
import 'package:here_sdk/search.dart';

import 'SearchResultMetadata.dart';

// A callback to notify the hosting widget.
typedef ShowDialogFunction = void Function(String title, String message);

class SearchExample {
  HereMapController _hereMapController;
  MapCamera _camera;
  MapImage? _poiMapImage;
  List<MapMarker> _mapMarkerList = [];
  late SearchEngine _onlineSearchEngine;
  late OfflineSearchEngine _offlineSearchEngine;
  bool useOnlineSearchEngine = true;
  ShowDialogFunction _showDialog;

  SearchExample(ShowDialogFunction showDialogCallback, HereMapController hereMapController)
      : _showDialog = showDialogCallback,
        _hereMapController = hereMapController,
        _camera = hereMapController.camera {
    double distanceToEarthInMeters = 5000;
    MapMeasure mapMeasureZoom = MapMeasure(MapMeasureKind.distance, distanceToEarthInMeters);
    _camera.lookAtPointWithMeasure(GeoCoordinates(52.520798, 13.409408), mapMeasureZoom);

    try {
      _onlineSearchEngine = SearchEngine();
    } on InstantiationException {
      throw ("Initialization of SearchEngine failed.");
    }

    try {
      // Allows to search on already downloaded or cached map data.
      _offlineSearchEngine = OfflineSearchEngine();
    } on InstantiationException {
      throw ("Initialization of OfflineSearchEngine failed.");
    }

    _setTapGestureHandler();
    _setLongPressGestureHandler();

    _showDialog("Note", "Long press on the map to get the address for that location with reverse geocoding.");
  }

  Future<void> searchButtonClicked() async {
    // Search for "Pizza" and show the results on the map.
    _searchExample();

    // Search for auto suggestions and log the results to the console.
    _autoSuggestExample();
  }

  Future<void> geocodeAnAddressButtonClicked() async {
    // Search for the location that belongs to an address and show it on the map.
    _geocodeAnAddress();
  }

  void useOnlineSearchEngineButtonClicked() {
    useOnlineSearchEngine = true;

    _showDialog('Switched to SearchEngine', 'Requests will be calculated online.');
  }

  void useOfflineSearchEngineButtonClicked() {
    useOnlineSearchEngine = false;

    // Note that this app does not show how to download offline maps. For this, check the offline_maps_app example.
    _showDialog(
        'Switched to OfflineSearchEngine', 'Requests will be calculated offline on cached or downloaded map data.');
  }

  void _searchExample() {
    String searchTerm = "Pizza";
    print("Searching in viewport for: " + searchTerm);
    _searchInViewport(searchTerm);
  }

  void _geocodeAnAddress() {
    // Set map to expected location.
    GeoCoordinates geoCoordinates = GeoCoordinates(52.53086, 13.38469);
    double distanceToEarthInMeters = 1000 * 5;
    MapMeasure mapMeasureZoom = MapMeasure(MapMeasureKind.distance, distanceToEarthInMeters);
    _camera.lookAtPointWithMeasure(geoCoordinates, mapMeasureZoom);

    String queryString = "Invalidenstraße 116, Berlin";

    print("Finding locations for: $queryString. Tap marker to see the coordinates.");

    _geocodeAddressAtLocation(queryString, geoCoordinates);
  }

  void _setTapGestureHandler() {
    _hereMapController.gestures.tapListener = TapListener((Point2D touchPoint) {
      _pickMapMarker(touchPoint);
    });
  }

  void _setLongPressGestureHandler() {
    _hereMapController.gestures.longPressListener = LongPressListener((GestureState gestureState, Point2D touchPoint) {
      if (gestureState == GestureState.begin) {
        GeoCoordinates? geoCoordinates = _hereMapController.viewToGeoCoordinates(touchPoint);
        if (geoCoordinates == null) {
          return;
        }
        _addPoiMapMarker(geoCoordinates);
        _getAddressForCoordinates(geoCoordinates);
      }
    });
  }

  Future<void> _getAddressForCoordinates(GeoCoordinates geoCoordinates) async {
    SearchOptions reverseGeocodingOptions = SearchOptions.withDefaults();
    reverseGeocodingOptions.languageCode = LanguageCode.enGb;
    reverseGeocodingOptions.maxItems = 1;

    if (useOnlineSearchEngine) {
      _onlineSearchEngine.searchByCoordinates(geoCoordinates, reverseGeocodingOptions,
          (SearchError? searchError, List<Place>? list) async {
        _handleReverseGeocodingResults(searchError, list);
      });
    } else {
      _offlineSearchEngine.searchByCoordinates(geoCoordinates, reverseGeocodingOptions,
          (SearchError? searchError, List<Place>? list) async {
        _handleReverseGeocodingResults(searchError, list);
      });
    }
  }

  // Note that this can be called by the online or offline search engine.
  void _handleReverseGeocodingResults(SearchError? searchError, List<Place>? list) {
    if (searchError != null) {
      _showDialog("Reverse geocoding", "Error: " + searchError.toString());
      return;
    }

    // If error is null, list is guaranteed to be not empty.
    _showDialog("Reverse geocoded address:", list!.first.address.addressText);
  }

  void _pickMapMarker(Point2D touchPoint) {
    double radiusInPixel = 2;
    _hereMapController.pickMapItems(touchPoint, radiusInPixel, (pickMapItemsResult) {
      if (pickMapItemsResult == null) {
        // Pick operation failed.
        return;
      }
      List<MapMarker>? mapMarkerList = pickMapItemsResult.markers;
      if (mapMarkerList.length == 0) {
        print("No map markers found.");
        return;
      }

      MapMarker topmostMapMarker = mapMarkerList.first;
      Metadata? metadata = topmostMapMarker.metadata;
      if (metadata != null) {
        CustomMetadataValue? customMetadataValue = metadata.getCustomValue("key_search_result");
        if (customMetadataValue != null) {
          SearchResultMetadata searchResultMetadata = customMetadataValue as SearchResultMetadata;
          String title = searchResultMetadata.searchResult.title;
          String vicinity = searchResultMetadata.searchResult.address.addressText;
          _showDialog("Picked Search Result", title + ". Vicinity: " + vicinity);
          return;
        }
      }

      double lat = topmostMapMarker.coordinates.latitude;
      double lon = topmostMapMarker.coordinates.longitude;
      _showDialog("Picked Map Marker", "Geographic coordinates: $lat, $lon.");
    });
  }

  Future<void> _searchInViewport(String queryString) async {
    _clearMap();

    GeoBox viewportGeoBox = _getMapViewGeoBox();
    TextQueryArea queryArea = TextQueryArea.withBox(viewportGeoBox);
    TextQuery query = TextQuery.withArea(queryString, queryArea);

    SearchOptions searchOptions = SearchOptions.withDefaults();
    searchOptions.languageCode = LanguageCode.enUs;
    searchOptions.maxItems = 30;

    if (useOnlineSearchEngine) {
      _onlineSearchEngine.searchByText(query, searchOptions, (SearchError? searchError, List<Place>? list) async {
        _handleSearchResults(searchError, list, queryString);
      });
    } else {
      _offlineSearchEngine.searchByText(query, searchOptions, (SearchError? searchError, List<Place>? list) async {
        _handleSearchResults(searchError, list, queryString);
      });
    }
  }

  // Note that this can be called by the online or offline search engine.
  void _handleSearchResults(SearchError? searchError, List<Place>? list, String queryString) {
    if (searchError != null) {
      // Note: When using the OfflineSearchEngine, the HERE SDK searches only on cached map data and
      // search results may not be available for all zoom levels.
      // Please also note that it may take time until the required map data is loaded.
      // Subsequently, the cache is filled when a user pans and zooms the map.
      _showDialog("Search", "Error: " + searchError.toString());
      return;
    }

    // If error is null, list is guaranteed to be not empty.
    int listLength = list!.length;
    _showDialog("Search for $queryString", "Results: $listLength. Tap marker to see details.");

    // Add new marker for each search result on map.
    for (Place searchResult in list) {
      Metadata metadata = Metadata();
      metadata.setCustomValue("key_search_result", SearchResultMetadata(searchResult));
      // Note: getGeoCoordinates() may return null only for Suggestions.
      _addPoiMapMarkerWithMetadata(searchResult.geoCoordinates!, metadata);
    }
  }

  Future<void> _autoSuggestExample() async {
    GeoCoordinates centerGeoCoordinates = _getMapViewCenter();

    SearchOptions searchOptions = SearchOptions.withDefaults();
    searchOptions.languageCode = LanguageCode.enUs;
    searchOptions.maxItems = 5;

    TextQueryArea queryArea = TextQueryArea.withCenter(centerGeoCoordinates);

    if (useOnlineSearchEngine) {
      // Simulate a user typing a search term.
      _onlineSearchEngine.suggest(
          TextQuery.withArea(
              "p", // User typed "p".
              queryArea),
          searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
        _handleSuggestionResults(searchError, list);
      });

      _onlineSearchEngine.suggest(
          TextQuery.withArea(
              "pi", // User typed "pi".
              queryArea),
          searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
        _handleSuggestionResults(searchError, list);
      });

      _onlineSearchEngine.suggest(
          TextQuery.withArea(
              "piz", // User typed "piz".
              queryArea),
          searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
        _handleSuggestionResults(searchError, list);
      });
    } else {
      // Simulate a user typing a search term.
      _offlineSearchEngine.suggest(
          TextQuery.withArea(
              "p", // User typed "p".
              queryArea),
          searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
        _handleSuggestionResults(searchError, list);
      });

      _offlineSearchEngine.suggest(
          TextQuery.withArea(
              "pi", // User typed "pi".
              queryArea),
          searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
        _handleSuggestionResults(searchError, list);
      });

      _offlineSearchEngine.suggest(
          TextQuery.withArea(
              "piz", // User typed "piz".
              queryArea),
          searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
        _handleSuggestionResults(searchError, list);
      });
    }
  }

  void _handleSuggestionResults(SearchError? searchError, List<Suggestion>? list) {
    if (searchError != null) {
      print("Autosuggest Error: " + searchError.toString());
      return;
    }

    // If error is null, list is guaranteed to be not empty.
    int listLength = list!.length;
    print("Autosuggest results: $listLength.");

    for (Suggestion autosuggestResult in list) {
      String addressText = "Not a place.";
      Place? place = autosuggestResult.place;
      if (place != null) {
        addressText = place.address.addressText;
      }

      print("Autosuggest result: " + autosuggestResult.title + " addressText: " + addressText);
    }
  }

  Future<void> _geocodeAddressAtLocation(String queryString, GeoCoordinates geoCoordinates) async {
    _clearMap();

    AddressQuery query = AddressQuery.withAreaCenter(queryString, geoCoordinates);

    SearchOptions geocodingOptions = SearchOptions.withDefaults();
    geocodingOptions.languageCode = LanguageCode.deDe;
    geocodingOptions.maxItems = 30;

    if (useOnlineSearchEngine) {
      _onlineSearchEngine.searchByAddress(query, geocodingOptions, (SearchError? searchError, List<Place>? list) async {
        _handleGeocodingResults(searchError, list, queryString);
      });
    } else {
      _offlineSearchEngine.searchByAddress(query, geocodingOptions,
          (SearchError? searchError, List<Place>? list) async {
        _handleGeocodingResults(searchError, list, queryString);
      });
    }
  }

  // Note that this can be called by the online or offline search engine.
  void _handleGeocodingResults(SearchError? searchError, List<Place>? list, String queryString) {
    if (searchError != null) {
      _showDialog("Geocoding", "Error: " + searchError.toString());
      return;
    }

    String locationDetails = "";

    // If error is null, list is guaranteed to be not empty.
    for (Place geocodingResult in list!) {
      // Note: getGeoCoordinates() may return null only for Suggestions.
      GeoCoordinates geoCoordinates = geocodingResult.geoCoordinates!;
      Address address = geocodingResult.address;
      locationDetails = address.addressText +
          ". GeoCoordinates: " +
          geoCoordinates.latitude.toString() +
          ", " +
          geoCoordinates.longitude.toString();

      print("GeocodingResult: " + locationDetails);
      _addPoiMapMarker(geoCoordinates);
    }

    int itemsCount = list.length;
    _showDialog("Geocoding result for $queryString. Results: $itemsCount", locationDetails);
  }

  Future<MapMarker> _addPoiMapMarker(GeoCoordinates geoCoordinates) async {
    // Reuse existing MapImage for new map markers.
    if (_poiMapImage == null) {
      Uint8List imagePixelData = await _loadFileAsUint8List('poi.png');
      _poiMapImage = MapImage.withPixelDataAndImageFormat(imagePixelData, ImageFormat.png);
    }

    MapMarker mapMarker = MapMarker(geoCoordinates, _poiMapImage!);
    _hereMapController.mapScene.addMapMarker(mapMarker);
    _mapMarkerList.add(mapMarker);

    return mapMarker;
  }

  Future<Uint8List> _loadFileAsUint8List(String fileName) async {
    // The path refers to the assets directory as specified in pubspec.yaml.
    ByteData fileData = await rootBundle.load('assets/' + fileName);
    return Uint8List.view(fileData.buffer);
  }

  Future<void> _addPoiMapMarkerWithMetadata(GeoCoordinates geoCoordinates, Metadata metadata) async {
    MapMarker mapMarker = await _addPoiMapMarker(geoCoordinates);
    mapMarker.metadata = metadata;
  }

  GeoCoordinates _getMapViewCenter() {
    return _camera.state.targetCoordinates;
  }

  GeoBox _getMapViewGeoBox() {
    GeoBox? geoBox = _camera.boundingBox;
    if (geoBox == null) {
      print(
          "GeoBox creation failed, corners are null. This can happen when the map is tilted. Falling back to a fixed box.");
      GeoCoordinates southWestCorner = GeoCoordinates(
          _camera.state.targetCoordinates.latitude - 0.05, _camera.state.targetCoordinates.longitude - 0.05);
      GeoCoordinates northEastCorner = GeoCoordinates(
          _camera.state.targetCoordinates.latitude + 0.05, _camera.state.targetCoordinates.longitude + 0.05);
      geoBox = GeoBox(southWestCorner, northEastCorner);
    }
    return geoBox;
  }

  void _clearMap() {
    _mapMarkerList.forEach((mapMarker) {
      _hereMapController.mapScene.removeMapMarker(mapMarker);
    });
    _mapMarkerList.clear();
  }
}

有关更多详细信息,请检查 在此处输入链接描述

Please check the below code ,which explains the use of auto suggest in the flutter.

import 'dart:typed_data';

import 'package:flutter/services.dart';
import 'package:here_sdk/core.dart';
import 'package:here_sdk/core.errors.dart';
import 'package:here_sdk/gestures.dart';
import 'package:here_sdk/mapview.dart';
import 'package:here_sdk/search.dart';

import 'SearchResultMetadata.dart';

// A callback to notify the hosting widget.
typedef ShowDialogFunction = void Function(String title, String message);

class SearchExample {
  HereMapController _hereMapController;
  MapCamera _camera;
  MapImage? _poiMapImage;
  List<MapMarker> _mapMarkerList = [];
  late SearchEngine _onlineSearchEngine;
  late OfflineSearchEngine _offlineSearchEngine;
  bool useOnlineSearchEngine = true;
  ShowDialogFunction _showDialog;

  SearchExample(ShowDialogFunction showDialogCallback, HereMapController hereMapController)
      : _showDialog = showDialogCallback,
        _hereMapController = hereMapController,
        _camera = hereMapController.camera {
    double distanceToEarthInMeters = 5000;
    MapMeasure mapMeasureZoom = MapMeasure(MapMeasureKind.distance, distanceToEarthInMeters);
    _camera.lookAtPointWithMeasure(GeoCoordinates(52.520798, 13.409408), mapMeasureZoom);

    try {
      _onlineSearchEngine = SearchEngine();
    } on InstantiationException {
      throw ("Initialization of SearchEngine failed.");
    }

    try {
      // Allows to search on already downloaded or cached map data.
      _offlineSearchEngine = OfflineSearchEngine();
    } on InstantiationException {
      throw ("Initialization of OfflineSearchEngine failed.");
    }

    _setTapGestureHandler();
    _setLongPressGestureHandler();

    _showDialog("Note", "Long press on the map to get the address for that location with reverse geocoding.");
  }

  Future<void> searchButtonClicked() async {
    // Search for "Pizza" and show the results on the map.
    _searchExample();

    // Search for auto suggestions and log the results to the console.
    _autoSuggestExample();
  }

  Future<void> geocodeAnAddressButtonClicked() async {
    // Search for the location that belongs to an address and show it on the map.
    _geocodeAnAddress();
  }

  void useOnlineSearchEngineButtonClicked() {
    useOnlineSearchEngine = true;

    _showDialog('Switched to SearchEngine', 'Requests will be calculated online.');
  }

  void useOfflineSearchEngineButtonClicked() {
    useOnlineSearchEngine = false;

    // Note that this app does not show how to download offline maps. For this, check the offline_maps_app example.
    _showDialog(
        'Switched to OfflineSearchEngine', 'Requests will be calculated offline on cached or downloaded map data.');
  }

  void _searchExample() {
    String searchTerm = "Pizza";
    print("Searching in viewport for: " + searchTerm);
    _searchInViewport(searchTerm);
  }

  void _geocodeAnAddress() {
    // Set map to expected location.
    GeoCoordinates geoCoordinates = GeoCoordinates(52.53086, 13.38469);
    double distanceToEarthInMeters = 1000 * 5;
    MapMeasure mapMeasureZoom = MapMeasure(MapMeasureKind.distance, distanceToEarthInMeters);
    _camera.lookAtPointWithMeasure(geoCoordinates, mapMeasureZoom);

    String queryString = "Invalidenstraße 116, Berlin";

    print("Finding locations for: $queryString. Tap marker to see the coordinates.");

    _geocodeAddressAtLocation(queryString, geoCoordinates);
  }

  void _setTapGestureHandler() {
    _hereMapController.gestures.tapListener = TapListener((Point2D touchPoint) {
      _pickMapMarker(touchPoint);
    });
  }

  void _setLongPressGestureHandler() {
    _hereMapController.gestures.longPressListener = LongPressListener((GestureState gestureState, Point2D touchPoint) {
      if (gestureState == GestureState.begin) {
        GeoCoordinates? geoCoordinates = _hereMapController.viewToGeoCoordinates(touchPoint);
        if (geoCoordinates == null) {
          return;
        }
        _addPoiMapMarker(geoCoordinates);
        _getAddressForCoordinates(geoCoordinates);
      }
    });
  }

  Future<void> _getAddressForCoordinates(GeoCoordinates geoCoordinates) async {
    SearchOptions reverseGeocodingOptions = SearchOptions.withDefaults();
    reverseGeocodingOptions.languageCode = LanguageCode.enGb;
    reverseGeocodingOptions.maxItems = 1;

    if (useOnlineSearchEngine) {
      _onlineSearchEngine.searchByCoordinates(geoCoordinates, reverseGeocodingOptions,
          (SearchError? searchError, List<Place>? list) async {
        _handleReverseGeocodingResults(searchError, list);
      });
    } else {
      _offlineSearchEngine.searchByCoordinates(geoCoordinates, reverseGeocodingOptions,
          (SearchError? searchError, List<Place>? list) async {
        _handleReverseGeocodingResults(searchError, list);
      });
    }
  }

  // Note that this can be called by the online or offline search engine.
  void _handleReverseGeocodingResults(SearchError? searchError, List<Place>? list) {
    if (searchError != null) {
      _showDialog("Reverse geocoding", "Error: " + searchError.toString());
      return;
    }

    // If error is null, list is guaranteed to be not empty.
    _showDialog("Reverse geocoded address:", list!.first.address.addressText);
  }

  void _pickMapMarker(Point2D touchPoint) {
    double radiusInPixel = 2;
    _hereMapController.pickMapItems(touchPoint, radiusInPixel, (pickMapItemsResult) {
      if (pickMapItemsResult == null) {
        // Pick operation failed.
        return;
      }
      List<MapMarker>? mapMarkerList = pickMapItemsResult.markers;
      if (mapMarkerList.length == 0) {
        print("No map markers found.");
        return;
      }

      MapMarker topmostMapMarker = mapMarkerList.first;
      Metadata? metadata = topmostMapMarker.metadata;
      if (metadata != null) {
        CustomMetadataValue? customMetadataValue = metadata.getCustomValue("key_search_result");
        if (customMetadataValue != null) {
          SearchResultMetadata searchResultMetadata = customMetadataValue as SearchResultMetadata;
          String title = searchResultMetadata.searchResult.title;
          String vicinity = searchResultMetadata.searchResult.address.addressText;
          _showDialog("Picked Search Result", title + ". Vicinity: " + vicinity);
          return;
        }
      }

      double lat = topmostMapMarker.coordinates.latitude;
      double lon = topmostMapMarker.coordinates.longitude;
      _showDialog("Picked Map Marker", "Geographic coordinates: $lat, $lon.");
    });
  }

  Future<void> _searchInViewport(String queryString) async {
    _clearMap();

    GeoBox viewportGeoBox = _getMapViewGeoBox();
    TextQueryArea queryArea = TextQueryArea.withBox(viewportGeoBox);
    TextQuery query = TextQuery.withArea(queryString, queryArea);

    SearchOptions searchOptions = SearchOptions.withDefaults();
    searchOptions.languageCode = LanguageCode.enUs;
    searchOptions.maxItems = 30;

    if (useOnlineSearchEngine) {
      _onlineSearchEngine.searchByText(query, searchOptions, (SearchError? searchError, List<Place>? list) async {
        _handleSearchResults(searchError, list, queryString);
      });
    } else {
      _offlineSearchEngine.searchByText(query, searchOptions, (SearchError? searchError, List<Place>? list) async {
        _handleSearchResults(searchError, list, queryString);
      });
    }
  }

  // Note that this can be called by the online or offline search engine.
  void _handleSearchResults(SearchError? searchError, List<Place>? list, String queryString) {
    if (searchError != null) {
      // Note: When using the OfflineSearchEngine, the HERE SDK searches only on cached map data and
      // search results may not be available for all zoom levels.
      // Please also note that it may take time until the required map data is loaded.
      // Subsequently, the cache is filled when a user pans and zooms the map.
      _showDialog("Search", "Error: " + searchError.toString());
      return;
    }

    // If error is null, list is guaranteed to be not empty.
    int listLength = list!.length;
    _showDialog("Search for $queryString", "Results: $listLength. Tap marker to see details.");

    // Add new marker for each search result on map.
    for (Place searchResult in list) {
      Metadata metadata = Metadata();
      metadata.setCustomValue("key_search_result", SearchResultMetadata(searchResult));
      // Note: getGeoCoordinates() may return null only for Suggestions.
      _addPoiMapMarkerWithMetadata(searchResult.geoCoordinates!, metadata);
    }
  }

  Future<void> _autoSuggestExample() async {
    GeoCoordinates centerGeoCoordinates = _getMapViewCenter();

    SearchOptions searchOptions = SearchOptions.withDefaults();
    searchOptions.languageCode = LanguageCode.enUs;
    searchOptions.maxItems = 5;

    TextQueryArea queryArea = TextQueryArea.withCenter(centerGeoCoordinates);

    if (useOnlineSearchEngine) {
      // Simulate a user typing a search term.
      _onlineSearchEngine.suggest(
          TextQuery.withArea(
              "p", // User typed "p".
              queryArea),
          searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
        _handleSuggestionResults(searchError, list);
      });

      _onlineSearchEngine.suggest(
          TextQuery.withArea(
              "pi", // User typed "pi".
              queryArea),
          searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
        _handleSuggestionResults(searchError, list);
      });

      _onlineSearchEngine.suggest(
          TextQuery.withArea(
              "piz", // User typed "piz".
              queryArea),
          searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
        _handleSuggestionResults(searchError, list);
      });
    } else {
      // Simulate a user typing a search term.
      _offlineSearchEngine.suggest(
          TextQuery.withArea(
              "p", // User typed "p".
              queryArea),
          searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
        _handleSuggestionResults(searchError, list);
      });

      _offlineSearchEngine.suggest(
          TextQuery.withArea(
              "pi", // User typed "pi".
              queryArea),
          searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
        _handleSuggestionResults(searchError, list);
      });

      _offlineSearchEngine.suggest(
          TextQuery.withArea(
              "piz", // User typed "piz".
              queryArea),
          searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
        _handleSuggestionResults(searchError, list);
      });
    }
  }

  void _handleSuggestionResults(SearchError? searchError, List<Suggestion>? list) {
    if (searchError != null) {
      print("Autosuggest Error: " + searchError.toString());
      return;
    }

    // If error is null, list is guaranteed to be not empty.
    int listLength = list!.length;
    print("Autosuggest results: $listLength.");

    for (Suggestion autosuggestResult in list) {
      String addressText = "Not a place.";
      Place? place = autosuggestResult.place;
      if (place != null) {
        addressText = place.address.addressText;
      }

      print("Autosuggest result: " + autosuggestResult.title + " addressText: " + addressText);
    }
  }

  Future<void> _geocodeAddressAtLocation(String queryString, GeoCoordinates geoCoordinates) async {
    _clearMap();

    AddressQuery query = AddressQuery.withAreaCenter(queryString, geoCoordinates);

    SearchOptions geocodingOptions = SearchOptions.withDefaults();
    geocodingOptions.languageCode = LanguageCode.deDe;
    geocodingOptions.maxItems = 30;

    if (useOnlineSearchEngine) {
      _onlineSearchEngine.searchByAddress(query, geocodingOptions, (SearchError? searchError, List<Place>? list) async {
        _handleGeocodingResults(searchError, list, queryString);
      });
    } else {
      _offlineSearchEngine.searchByAddress(query, geocodingOptions,
          (SearchError? searchError, List<Place>? list) async {
        _handleGeocodingResults(searchError, list, queryString);
      });
    }
  }

  // Note that this can be called by the online or offline search engine.
  void _handleGeocodingResults(SearchError? searchError, List<Place>? list, String queryString) {
    if (searchError != null) {
      _showDialog("Geocoding", "Error: " + searchError.toString());
      return;
    }

    String locationDetails = "";

    // If error is null, list is guaranteed to be not empty.
    for (Place geocodingResult in list!) {
      // Note: getGeoCoordinates() may return null only for Suggestions.
      GeoCoordinates geoCoordinates = geocodingResult.geoCoordinates!;
      Address address = geocodingResult.address;
      locationDetails = address.addressText +
          ". GeoCoordinates: " +
          geoCoordinates.latitude.toString() +
          ", " +
          geoCoordinates.longitude.toString();

      print("GeocodingResult: " + locationDetails);
      _addPoiMapMarker(geoCoordinates);
    }

    int itemsCount = list.length;
    _showDialog("Geocoding result for $queryString. Results: $itemsCount", locationDetails);
  }

  Future<MapMarker> _addPoiMapMarker(GeoCoordinates geoCoordinates) async {
    // Reuse existing MapImage for new map markers.
    if (_poiMapImage == null) {
      Uint8List imagePixelData = await _loadFileAsUint8List('poi.png');
      _poiMapImage = MapImage.withPixelDataAndImageFormat(imagePixelData, ImageFormat.png);
    }

    MapMarker mapMarker = MapMarker(geoCoordinates, _poiMapImage!);
    _hereMapController.mapScene.addMapMarker(mapMarker);
    _mapMarkerList.add(mapMarker);

    return mapMarker;
  }

  Future<Uint8List> _loadFileAsUint8List(String fileName) async {
    // The path refers to the assets directory as specified in pubspec.yaml.
    ByteData fileData = await rootBundle.load('assets/' + fileName);
    return Uint8List.view(fileData.buffer);
  }

  Future<void> _addPoiMapMarkerWithMetadata(GeoCoordinates geoCoordinates, Metadata metadata) async {
    MapMarker mapMarker = await _addPoiMapMarker(geoCoordinates);
    mapMarker.metadata = metadata;
  }

  GeoCoordinates _getMapViewCenter() {
    return _camera.state.targetCoordinates;
  }

  GeoBox _getMapViewGeoBox() {
    GeoBox? geoBox = _camera.boundingBox;
    if (geoBox == null) {
      print(
          "GeoBox creation failed, corners are null. This can happen when the map is tilted. Falling back to a fixed box.");
      GeoCoordinates southWestCorner = GeoCoordinates(
          _camera.state.targetCoordinates.latitude - 0.05, _camera.state.targetCoordinates.longitude - 0.05);
      GeoCoordinates northEastCorner = GeoCoordinates(
          _camera.state.targetCoordinates.latitude + 0.05, _camera.state.targetCoordinates.longitude + 0.05);
      geoBox = GeoBox(southWestCorner, northEastCorner);
    }
    return geoBox;
  }

  void _clearMap() {
    _mapMarkerList.forEach((mapMarker) {
      _hereMapController.mapScene.removeMapMarker(mapMarker);
    });
    _mapMarkerList.clear();
  }
}

For more details please check enter link description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文