All files / engine/Source/Core IonGeocoderService.js

100% Statements 34/34
87.5% Branches 14/16
100% Functions 10/10
100% Lines 34/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148                                175x   514x     2x           1x             88x       3x 5x                                   86x     86x       86x   86x     85x 85x 85x   85x 85x 84x         85x       85x 85x     85x 85x 85x     85x     1x                   1x                     3x         89x 88x         88x 84x   88x                       1x 1x      
import Check from "./Check.js";
import Credit from "./Credit.js";
import Frozen from "./Frozen.js";
import defined from "./defined.js";
import DeveloperError from "./DeveloperError.js";
import Ion from "./Ion.js";
import IonGeocodeProviderType from "./IonGeocodeProviderType.js";
import PeliasGeocoderService from "./PeliasGeocoderService.js";
import Resource from "./Resource.js";
 
/**
 * @param {*} geocodeProviderType
 * @throws {DeveloperError}
 * @private
 */
function validateIonGeocodeProviderType(geocodeProviderType) {
  if (
    !Object.values(IonGeocodeProviderType).some(
      (value) => value === geocodeProviderType,
    )
  ) {
    throw new DeveloperError(
      `Invalid geocodeProviderType: "${geocodeProviderType}"`,
    );
  }
}
 
const providerToParameterMap = Object.freeze({
  [IonGeocodeProviderType.GOOGLE]: "google",
  [IonGeocodeProviderType.BING]: "bing",
  [IonGeocodeProviderType.DEFAULT]: undefined,
});
 
function providerToQueryParameter(provider) {
  return providerToParameterMap[provider];
}
 
function queryParameterToProvider(parameter) {
  return Object.entries(providerToParameterMap).find(
    (entry) => entry[1] === parameter,
  )[0];
}
 
/**
 * Provides geocoding through Cesium ion.
 * @alias IonGeocoderService
 * @constructor
 *
 * @param {object} options Object with the following properties:
 * @param {Scene} options.scene The scene
 * @param {string} [options.accessToken=Ion.defaultAccessToken] The access token to use.
 * @param {string|Resource} [options.server=Ion.defaultServer] The resource to the Cesium ion API server.
 * @param {IonGeocodeProviderType} [options.geocodeProviderType=IonGeocodeProviderType.DEFAULT] The geocoder the Cesium ion API server should use to fulfill this request.
 *
 * @see Ion
 */
function IonGeocoderService(options) {
  options = options ?? Frozen.EMPTY_OBJECT;
 
  //>>includeStart('debug', pragmas.debug);
  Check.typeOf.object("options.scene", options.scene);
  //>>includeEnd('debug');
 
  const geocodeProviderType =
    options.geocodeProviderType ?? IonGeocodeProviderType.DEFAULT;
  //>>includeStart('debug', pragmas.debug);
  validateIonGeocodeProviderType(geocodeProviderType);
  //>>includeEnd('debug');
 
  const accessToken = options.accessToken ?? Ion.defaultAccessToken;
  const server = Resource.createIfNeeded(options.server ?? Ion.defaultServer);
  server.appendForwardSlash();
 
  const defaultTokenCredit = Ion.getDefaultTokenCredit(accessToken);
  if (defined(defaultTokenCredit)) {
    options.scene.frameState.creditDisplay.addStaticCredit(
      Credit.clone(defaultTokenCredit),
    );
  }
 
  const searchEndpoint = server.getDerivedResource({
    url: "v1/geocode",
  });
 
  Eif (defined(accessToken)) {
    searchEndpoint.appendQueryParameters({ access_token: accessToken });
  }
 
  this._accessToken = accessToken;
  this._server = server;
  this._pelias = new PeliasGeocoderService(searchEndpoint);
  // geocoderProviderType isn't stored here directly but instead relies on the
  // query parameters of this._pelias.url.  Use the setter logic to update value.
  this.geocodeProviderType = geocodeProviderType;
}
 
Object.defineProperties(IonGeocoderService.prototype, {
  /**
   * Gets the credit to display after a geocode is performed. Typically this is used to credit
   * the geocoder service.
   * @memberof IonGeocoderService.prototype
   * @type {Credit|undefined}
   * @readonly
   */
  credit: {
    get: function () {
      return undefined;
    },
  },
  /**
   * The geocoding service that Cesium ion API server should use to fulfill geocding requests.
   * @memberof IonGeocoderService.prototype
   * @type {IonGeocodeProviderType}
   * @default IonGeocodeProviderType.DEFAULT
   */
  geocodeProviderType: {
    get: function () {
      return queryParameterToProvider(
        this._pelias.url.queryParameters["geocoder"],
      );
    },
    set: function (geocodeProviderType) {
      validateIonGeocodeProviderType(geocodeProviderType);
      const query = {
        ...this._pelias.url.queryParameters,
        geocoder: providerToQueryParameter(geocodeProviderType),
      };
      // Delete the geocoder parameter to prevent sending &geocoder=undefined in the query
      if (!defined(query.geocoder)) {
        delete query.geocoder;
      }
      this._pelias.url.setQueryParameters(query);
    },
  },
});
 
/**
 * @function
 *
 * @param {string} query The query to be sent to the geocoder service
 * @param {GeocodeType} [type=GeocodeType.SEARCH] The type of geocode to perform.
 * @returns {Promise<GeocoderService.Result[]>}
 */
IonGeocoderService.prototype.geocode = async function (query, geocodeType) {
  return this._pelias.geocode(query, geocodeType);
};
export default IonGeocoderService;