import { r as registerInstance, f as createEvent } from './index-cb74209c.js';

class NominatimClient {
  async forward(options, clientOptions = {}) {
    let params = {
      format: "jsonv2",
      addressdetails: clientOptions.addressdetails || "1",
    };
    if (clientOptions.countrycodes != undefined)
      params["countrycodes"] = clientOptions.countrycodes;
    if (typeof options.address === "string") {
      params["q"] = options.address;
    }
    else {
      Object.assign(params, options.address);
    }
    if (options.bbox != undefined)
      params["viewbox"] = options.bbox.join(",");
    if (options.bounded)
      params["bounded"] = "1";
    if (options.limit != undefined)
      params["limit"] = options.limit;
    let res = await fetch(this.addParams(options.url, params), {
      mode: clientOptions.mode || "cors",
    });
    let json = await res.json();
    if (json.error)
      return json;
    return this.formatResponse(json);
  }
  async reverse(options, clientOptions = {}) {
    let params = {
      format: "jsonv2",
      addressdetails: clientOptions.addressdetails || "1",
      zoom: clientOptions.zoom || "18",
    };
    params["lon"] = options.location.lon.toString();
    params["lat"] = options.location.lat.toString();
    let res = await fetch(this.addParams(options.url, params), {
      mode: clientOptions.mode || "cors",
    });
    let json = await res.json();
    if (json.error)
      return json;
    return this.formatResponseItem(json);
  }
  formatResponse(res) {
    return res.map((item) => this.formatResponseItem(item));
  }
  formatResponseItem(item) {
    let bbox = null;
    if (item.boundingbox) {
      let coords = item.boundingbox.map((coord) => parseFloat(coord));
      bbox = [coords[2], coords[0], coords[3], coords[1]];
    }
    let gr = {
      address: {
        name: item.address[item.type] || item.address[item.category] || null,
        housenumber: item.address.house_number || null,
        street: item.address.road || null,
        city: item.address.city || null,
        county: item.address.county || null,
        state: item.address.state || null,
        country: item.address.country || null,
        countrycode: item.address.country_code || null,
        postalcode: item.address.postcode || null,
      },
      bbox: bbox,
      client: {
        osm_id: item.osm_id || null,
        osm_type: item.osm_type || null,
        category: item.category || null,
        type: item.type || null,
        importance: item.importance || null,
        place_id: item.place_id || null,
        place_rank: item.place_rank || null,
      },
      display: item.display_name || null,
      location: {
        lon: parseFloat(item.lon),
        lat: parseFloat(item.lat),
      },
      polygon: item.geojson || null,
    };
    return gr;
  }
  addParams(endpoint, params) {
    let url = new URL(endpoint);
    Object.keys(params).forEach((key) => url.searchParams.append(key, params[key]));
    return url.toString();
  }
}

const GeocodeController = class {
  constructor(hostRef) {
    registerInstance(this, hostRef);
    this.glForwardGeocode = createEvent(this, "glForwardGeocode", 7);
    this.glReverseGeocode = createEvent(this, "glReverseGeocode", 7);
    this.defaultClient = "nominatim";
  }
  /**
   * Performs forward geocoding by converting an address to a geolocation.
   * @param options Forward geocoding options object.
   * @param clientOptions Additional client options object.
   */
  async forward(options, clientOptions) {
    let client = this.getClient(options.client);
    let res = await client.forward(options, clientOptions);
    this.glForwardGeocode.emit({
      options: options,
      response: res,
    });
    return res;
  }
  /**
   * Performs reverse geocoding by converting a geolocation to an address.
   * @param options Reverse geocoding options object.
   * @param clientOptions Additional client options.
   */
  async reverse(options, clientOptions) {
    let client = this.getClient(options.client);
    let res = await client.reverse(options, clientOptions);
    this.glReverseGeocode.emit({
      options: options,
      response: res,
    });
    return res;
  }
  getClient(id) {
    return GeocodeController.clients[id || this.defaultClient];
  }
  /**
   * Adds a client to the geocode controller
   * @param id The ide of the client
   * @param service A client able to handle nominatim results. For an example see {@link ./nominatim}
   */
  static async addClient(id, service) {
    GeocodeController.clients[id] = service;
  }
};
GeocodeController.clients = {};
GeocodeController.addClient("nominatim", new NominatimClient());

export { GeocodeController as gl_geocode_controller };

//# sourceMappingURL=gl-geocode-controller.entry.js.map