// Copyright 2022 Luca Casonato. All rights reserved. MIT license. /** * Air Quality API Client for Deno * =============================== * * The Air Quality API. * * Docs: https://developers.google.com/maps/documentation/air-quality * Source: https://googleapis.deno.dev/v1/airquality:v1.ts */ import { auth, CredentialsClient, GoogleAuth, request } from "/_/base@v1/mod.ts"; export { auth, GoogleAuth }; export type { CredentialsClient }; /** * The Air Quality API. */ export class AirQuality { #client: CredentialsClient | undefined; #baseUrl: string; constructor(client?: CredentialsClient, baseUrl: string = "https://airquality.googleapis.com/") { this.#client = client; this.#baseUrl = baseUrl; } /** * The Current Conditions endpoint provides hourly air quality information in * more than 100 countries, up to a 500 x 500 meters resolution. Includes over * 70 local indexes and global air quality index and categories. * */ async currentConditionsLookup(req: LookupCurrentConditionsRequest): Promise { const url = new URL(`${this.#baseUrl}v1/currentConditions:lookup`); const body = JSON.stringify(req); const data = await request(url.href, { client: this.#client, method: "POST", body, }); return deserializeLookupCurrentConditionsResponse(data); } /** * Returns air quality forecast for a specific location for a given time * range. * */ async forecastLookup(req: LookupForecastRequest): Promise { req = serializeLookupForecastRequest(req); const url = new URL(`${this.#baseUrl}v1/forecast:lookup`); const body = JSON.stringify(req); const data = await request(url.href, { client: this.#client, method: "POST", body, }); return deserializeLookupForecastResponse(data); } /** * Returns air quality history for a specific location for a given time * range. * */ async historyLookup(req: LookupHistoryRequest): Promise { req = serializeLookupHistoryRequest(req); const url = new URL(`${this.#baseUrl}v1/history:lookup`); const body = JSON.stringify(req); const data = await request(url.href, { client: this.#client, method: "POST", body, }); return deserializeLookupHistoryResponse(data); } /** * Returns a bytes array containing the data of the tile PNG image. * * @param mapType Required. The type of the air quality heatmap. Defines the pollutant that the map will graphically represent. Allowed values: - UAQI_RED_GREEN (UAQI, red-green palette) - UAQI_INDIGO_PERSIAN (UAQI, indigo-persian palette) - PM25_INDIGO_PERSIAN - GBR_DEFRA - DEU_UBA - CAN_EC - FRA_ATMO - US_AQI * @param x Required. Defines the east-west point in the requested tile. * @param y Required. Defines the north-south point in the requested tile. * @param zoom Required. The map's zoom level. Defines how large or small the contents of a map appear in a map view. Zoom level 0 is the entire world in a single tile. Zoom level 1 is the entire world in 4 tiles. Zoom level 2 is the entire world in 16 tiles. Zoom level 16 is the entire world in 65,536 tiles. Allowed values: 0-16 */ async mapTypesHeatmapTilesLookupHeatmapTile(mapType: | "MAP_TYPE_UNSPECIFIED" | "UAQI_RED_GREEN" | "UAQI_INDIGO_PERSIAN" | "PM25_INDIGO_PERSIAN" | "GBR_DEFRA" | "DEU_UBA" | "CAN_EC" | "FRA_ATMO" | "US_AQI", x: number, y: number, zoom: number): Promise { const url = new URL(`${this.#baseUrl}v1/mapTypes/${ mapType }/heatmapTiles/${ zoom }/${ x }/${ y }`); const data = await request(url.href, { client: this.#client, method: "GET", }); return deserializeHttpBody(data); } } /** * The emission sources and health effects of a given pollutant. */ export interface AdditionalInfo { /** * Text representing the pollutant's main health effects. */ effects?: string; /** * Text representing the pollutant's main emission sources. */ sources?: string; } /** * The basic object for representing different air quality metrics. When * brought together, these metrics provide a snapshot about the current air * quality conditions. There are multiple indexes in the world serving different * purposes and groups interested in measuring different aspects of air quality. */ export interface AirQualityIndex { /** * The index's numeric score. Examples: 10, 100. The value is not normalized * and should only be interpreted in the context of its related air-quality * index. For non-numeric indexes, this field will not be returned. Note: This * field should be used for calculations, graph display, etc. For displaying * the index score, you should use the AQI display field. */ aqi?: number; /** * Textual representation of the index numeric score, that may include prefix * or suffix symbols, which usually represents the worst index score. Example: * >100 or 10+. Note: This field should be used when you want to display the * index score. For non-numeric indexes, this field is empty. */ aqiDisplay?: string; /** * Textual classification of the index numeric score interpretation. For * example: "Excellent air quality". */ category?: string; /** * The index's code. This field represents the index for programming purposes * by using snake case instead of spaces. Examples: "uaqi", "fra_atmo". */ code?: string; /** * The color used to represent the AQI numeric score. */ color?: Color; /** * A human readable representation of the index name. Example: "AQI (US)" */ displayName?: string; /** * The chemical symbol of the dominant pollutant. For example: "CO". */ dominantPollutant?: string; } /** * Represents a color in the RGBA color space. This representation is designed * for simplicity of conversion to and from color representations in various * languages over compactness. For example, the fields of this representation * can be trivially provided to the constructor of `java.awt.Color` in Java; it * can also be trivially provided to UIColor's `+colorWithRed:green:blue:alpha` * method in iOS; and, with just a little work, it can be easily formatted into * a CSS `rgba()` string in JavaScript. This reference page doesn't have * information about the absolute color space that should be used to interpret * the RGB value—for example, sRGB, Adobe RGB, DCI-P3, and BT.2020. By default, * applications should assume the sRGB color space. When color equality needs to * be decided, implementations, unless documented otherwise, treat two colors as * equal if all their red, green, blue, and alpha values each differ by at most * `1e-5`. Example (Java): import com.google.type.Color; // ... public static * java.awt.Color fromProto(Color protocolor) { float alpha = * protocolor.hasAlpha() ? protocolor.getAlpha().getValue() : 1.0; return new * java.awt.Color( protocolor.getRed(), protocolor.getGreen(), * protocolor.getBlue(), alpha); } public static Color toProto(java.awt.Color * color) { float red = (float) color.getRed(); float green = (float) * color.getGreen(); float blue = (float) color.getBlue(); float denominator = * 255.0; Color.Builder resultBuilder = Color .newBuilder() .setRed(red / * denominator) .setGreen(green / denominator) .setBlue(blue / denominator); int * alpha = color.getAlpha(); if (alpha != 255) { result.setAlpha( FloatValue * .newBuilder() .setValue(((float) alpha) / denominator) .build()); } return * resultBuilder.build(); } // ... Example (iOS / Obj-C): // ... static UIColor* * fromProto(Color* protocolor) { float red = [protocolor red]; float green = * [protocolor green]; float blue = [protocolor blue]; FloatValue* alpha_wrapper * = [protocolor alpha]; float alpha = 1.0; if (alpha_wrapper != nil) { alpha = * [alpha_wrapper value]; } return [UIColor colorWithRed:red green:green * blue:blue alpha:alpha]; } static Color* toProto(UIColor* color) { CGFloat * red, green, blue, alpha; if (![color getRed:&red green:&green blue:&blue * alpha:&alpha]) { return nil; } Color* result = [[Color alloc] init]; [result * setRed:red]; [result setGreen:green]; [result setBlue:blue]; if (alpha <= * 0.9999) { [result setAlpha:floatWrapperWithValue(alpha)]; } [result * autorelease]; return result; } // ... Example (JavaScript): // ... var * protoToCssColor = function(rgb_color) { var redFrac = rgb_color.red || 0.0; * var greenFrac = rgb_color.green || 0.0; var blueFrac = rgb_color.blue || 0.0; * var red = Math.floor(redFrac * 255); var green = Math.floor(greenFrac * 255); * var blue = Math.floor(blueFrac * 255); if (!('alpha' in rgb_color)) { return * rgbToCssColor(red, green, blue); } var alphaFrac = rgb_color.alpha.value || * 0.0; var rgbParams = [red, green, blue].join(','); return ['rgba(', * rgbParams, ',', alphaFrac, ')'].join(''); }; var rgbToCssColor = * function(red, green, blue) { var rgbNumber = new Number((red << 16) | (green * << 8) | blue); var hexString = rgbNumber.toString(16); var missingZeros = 6 - * hexString.length; var resultBuilder = ['#']; for (var i = 0; i < * missingZeros; i++) { resultBuilder.push('0'); } * resultBuilder.push(hexString); return resultBuilder.join(''); }; // ... */ export interface Color { /** * The fraction of this color that should be applied to the pixel. That is, * the final pixel color is defined by the equation: `pixel color = alpha * * (this color) + (1.0 - alpha) * (background color)` This means that a value * of 1.0 corresponds to a solid color, whereas a value of 0.0 corresponds to * a completely transparent color. This uses a wrapper message rather than a * simple float scalar so that it is possible to distinguish between a default * value and the value being unset. If omitted, this color object is rendered * as a solid color (as if the alpha value had been explicitly given a value * of 1.0). */ alpha?: number; /** * The amount of blue in the color as a value in the interval [0, 1]. */ blue?: number; /** * The amount of green in the color as a value in the interval [0, 1]. */ green?: number; /** * The amount of red in the color as a value in the interval [0, 1]. */ red?: number; } /** * The concentration of a given pollutant in the air. */ export interface Concentration { /** * Units for measuring this pollutant concentration. */ units?: | "UNIT_UNSPECIFIED" | "PARTS_PER_BILLION" | "MICROGRAMS_PER_CUBIC_METER"; /** * Value of the pollutant concentration. */ value?: number; } /** * Expresses a 'country/region to AQI' relationship. Pairs a country/region * with a desired AQI so that air quality data that is required for that * country/region will be displayed according to the chosen AQI. */ export interface CustomLocalAqi { /** * The AQI to associate the country/region with. Value should be a [valid * index](/maps/documentation/air-quality/laqis) code. */ aqi?: string; /** * The country/region requiring the custom AQI. Value should be provided * using [ISO 3166-1 * alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code. */ regionCode?: string; } /** * Health recommendations for different population groups in a free text * format. The recommendations are derived from their associated air quality * conditions. */ export interface HealthRecommendations { /** * Sports and other strenuous outdoor activities. */ athletes?: string; /** * Younger populations including children, toddlers, and babies. */ children?: string; /** * Retirees and people older than the general population. */ elderly?: string; /** * No specific sensitivities. */ generalPopulation?: string; /** * Heart and circulatory system diseases. */ heartDiseasePopulation?: string; /** * Respiratory related problems and asthma suffers. */ lungDiseasePopulation?: string; /** * Women at all stages of pregnancy. */ pregnantWomen?: string; } /** * Contains the air quality information for each hour in the requested range. * For example, if the request is for 48 hours of history there will be 48 * elements of hourly info. */ export interface HourInfo { /** * A rounded down timestamp indicating the time the data refers to in RFC3339 * UTC "Zulu" format, with nanosecond resolution and up to nine fractional * digits. For example: "2014-10-02T15:00:00Z". */ dateTime?: Date; /** * Health advice and recommended actions related to the reported air quality * conditions. Recommendations are tailored differently for populations at * risk, groups with greater sensitivities to pollutants, and the general * population. */ healthRecommendations?: HealthRecommendations; /** * Based on the request parameters, this list will include (up to) two air * quality indexes: - Universal AQI. Will be returned if the universalAqi * boolean is set to true. - Local AQI. Will be returned if the LOCAL_AQI * extra computation is specified. */ indexes?: AirQualityIndex[]; /** * A list of pollutants affecting the location specified in the request. * Note: This field will be returned only for requests that specified one or * more of the following extra computations: POLLUTANT_ADDITIONAL_INFO, * DOMINANT_POLLUTANT_CONCENTRATION, POLLUTANT_CONCENTRATION. */ pollutants?: Pollutant[]; } function serializeHourInfo(data: any): HourInfo { return { ...data, dateTime: data["dateTime"] !== undefined ? data["dateTime"].toISOString() : undefined, }; } function deserializeHourInfo(data: any): HourInfo { return { ...data, dateTime: data["dateTime"] !== undefined ? new Date(data["dateTime"]) : undefined, }; } /** * Contains the air quality information for each hour in the requested range. * For example, if the request is for 48 hours of forecast there will be 48 * elements of hourly forecasts. */ export interface HourlyForecast { /** * A rounded down timestamp indicating the time (hour) the data refers to in * RFC3339 UTC "Zulu" format. For example: "2014-10-02T15:00:00Z". */ dateTime?: Date; /** * Health advice and recommended actions related to the reported air quality * conditions. Recommendations are tailored differently for populations at * risk, groups with greater sensitivities to pollutants, and the general * population. */ healthRecommendations?: HealthRecommendations; /** * Based on the request parameters, this list will include (up to) two air * quality indexes: - Universal AQI. Will be returned if the `universal_aqi` * boolean is set to true. - Local AQI. Will be returned if the LOCAL_AQI * extra computation is specified. */ indexes?: AirQualityIndex[]; /** * A list of pollutants affecting the location specified in the request. * Note: This field will be returned only for requests that specified one or * more of the following extra computations: POLLUTANT_ADDITIONAL_INFO, * DOMINANT_POLLUTANT_CONCENTRATION, POLLUTANT_CONCENTRATION. */ pollutants?: Pollutant[]; } function serializeHourlyForecast(data: any): HourlyForecast { return { ...data, dateTime: data["dateTime"] !== undefined ? data["dateTime"].toISOString() : undefined, }; } function deserializeHourlyForecast(data: any): HourlyForecast { return { ...data, dateTime: data["dateTime"] !== undefined ? new Date(data["dateTime"]) : undefined, }; } /** * Message that represents an arbitrary HTTP body. It should only be used for * payload formats that can't be represented as JSON, such as raw binary or an * HTML page. This message can be used both in streaming and non-streaming API * methods in the request as well as the response. It can be used as a top-level * request field, which is convenient if one wants to extract parameters from * either the URL or HTTP template into the request fields and also want access * to the raw HTTP body. Example: message GetResourceRequest { // A unique * request id. string request_id = 1; // The raw HTTP body is bound to this * field. google.api.HttpBody http_body = 2; } service ResourceService { rpc * GetResource(GetResourceRequest) returns (google.api.HttpBody); rpc * UpdateResource(google.api.HttpBody) returns (google.protobuf.Empty); } * Example with streaming methods: service CaldavService { rpc * GetCalendar(stream google.api.HttpBody) returns (stream google.api.HttpBody); * rpc UpdateCalendar(stream google.api.HttpBody) returns (stream * google.api.HttpBody); } Use of this type only changes how the request and * response bodies are handled, all other features will continue to work * unchanged. */ export interface HttpBody { /** * The HTTP Content-Type header value specifying the content type of the * body. */ contentType?: string; /** * The HTTP request/response body as raw binary. */ data?: Uint8Array; /** * Application specific response metadata. Must be set in the first response * for streaming APIs. */ extensions?: { [key: string]: any }[]; } function serializeHttpBody(data: any): HttpBody { return { ...data, data: data["data"] !== undefined ? encodeBase64(data["data"]) : undefined, }; } function deserializeHttpBody(data: any): HttpBody { return { ...data, data: data["data"] !== undefined ? decodeBase64(data["data"] as string) : undefined, }; } /** * Represents a time interval, encoded as a Timestamp start (inclusive) and a * Timestamp end (exclusive). The start must be less than or equal to the end. * When the start equals the end, the interval is empty (matches no time). When * both start and end are unspecified, the interval matches any time. */ export interface Interval { /** * Optional. Exclusive end of the interval. If specified, a Timestamp * matching this interval will have to be before the end. */ endTime?: Date; /** * Optional. Inclusive start of the interval. If specified, a Timestamp * matching this interval will have to be the same or after the start. */ startTime?: Date; } function serializeInterval(data: any): Interval { return { ...data, endTime: data["endTime"] !== undefined ? data["endTime"].toISOString() : undefined, startTime: data["startTime"] !== undefined ? data["startTime"].toISOString() : undefined, }; } function deserializeInterval(data: any): Interval { return { ...data, endTime: data["endTime"] !== undefined ? new Date(data["endTime"]) : undefined, startTime: data["startTime"] !== undefined ? new Date(data["startTime"]) : undefined, }; } /** * An object that represents a latitude/longitude pair. This is expressed as a * pair of doubles to represent degrees latitude and degrees longitude. Unless * specified otherwise, this object must conform to the WGS84 standard. Values * must be within normalized ranges. */ export interface LatLng { /** * The latitude in degrees. It must be in the range [-90.0, +90.0]. */ latitude?: number; /** * The longitude in degrees. It must be in the range [-180.0, +180.0]. */ longitude?: number; } /** * The request definition of the air quality current conditions. */ export interface LookupCurrentConditionsRequest { /** * Optional. Expresses a 'country/region to AQI' relationship. Pairs a * country/region with a desired AQI so that air quality data that is required * for that country/region will be displayed according to the chosen AQI. This * parameter can be used to specify a non-default AQI for a given country, for * example, to get the US EPA index for Canada rather than the default index * for Canada. */ customLocalAqis?: CustomLocalAqi[]; /** * Optional. Additional features that can be optionally enabled. Specifying * extra computations will result in the relevant elements and fields to be * returned in the response. */ extraComputations?: | "EXTRA_COMPUTATION_UNSPECIFIED" | "LOCAL_AQI" | "HEALTH_RECOMMENDATIONS" | "POLLUTANT_ADDITIONAL_INFO" | "DOMINANT_POLLUTANT_CONCENTRATION" | "POLLUTANT_CONCENTRATION"[]; /** * Optional. Allows the client to choose the language for the response. If * data cannot be provided for that language the API uses the closest match. * Allowed values rely on the IETF standard. Default value is en. */ languageCode?: string; /** * Required. The longitude and latitude from which the API looks for air * quality current conditions data. */ location?: LatLng; /** * Optional. Determines the color palette used for data provided by the * 'Universal Air Quality Index' (UAQI). This color palette is relevant just * for UAQI, other AQIs have a predetermined color palette that can't be * controlled. */ uaqiColorPalette?: | "COLOR_PALETTE_UNSPECIFIED" | "RED_GREEN" | "INDIGO_PERSIAN_DARK" | "INDIGO_PERSIAN_LIGHT"; /** * Optional. If set to true, the Universal AQI will be included in the * 'indexes' field of the response. Default value is true. */ universalAqi?: boolean; } export interface LookupCurrentConditionsResponse { /** * A rounded down timestamp in RFC3339 UTC "Zulu" format, with nanosecond * resolution and up to nine fractional digits. For example: * "2014-10-02T15:00:00Z". */ dateTime?: Date; /** * Health advice and recommended actions related to the reported air quality * conditions. Recommendations are tailored differently for populations at * risk, groups with greater sensitivities to pollutants, and the general * population. */ healthRecommendations?: HealthRecommendations; /** * Based on the request parameters, this list will include (up to) two air * quality indexes: - Universal AQI. Will be returned if the universalAqi * boolean is set to true. - Local AQI. Will be returned if the LOCAL_AQI * extra computation is specified. */ indexes?: AirQualityIndex[]; /** * A list of pollutants affecting the location specified in the request. * Note: This field will be returned only for requests that specified one or * more of the following extra computations: POLLUTANT_ADDITIONAL_INFO, * DOMINANT_POLLUTANT_CONCENTRATION, POLLUTANT_CONCENTRATION. */ pollutants?: Pollutant[]; /** * The ISO_3166-1 alpha-2 code of the country/region corresponding to the * location provided in the request. This field might be omitted from the * response if the location provided in the request resides in a disputed * territory. */ regionCode?: string; } function serializeLookupCurrentConditionsResponse(data: any): LookupCurrentConditionsResponse { return { ...data, dateTime: data["dateTime"] !== undefined ? data["dateTime"].toISOString() : undefined, }; } function deserializeLookupCurrentConditionsResponse(data: any): LookupCurrentConditionsResponse { return { ...data, dateTime: data["dateTime"] !== undefined ? new Date(data["dateTime"]) : undefined, }; } /** * The request object of the air quality forecast API. */ export interface LookupForecastRequest { /** * Optional. Expresses a 'country/region to AQI' relationship. Pairs a * country/region with a desired AQI so that air quality data that is required * for that country/region will be displayed according to the chosen AQI. This * parameter can be used to specify a non-default AQI for a given country, for * example, to get the US EPA index for Canada rather than the default index * for Canada. */ customLocalAqis?: CustomLocalAqi[]; /** * A timestamp for which to return the data for a specific point in time. The * timestamp is rounded to the previous exact hour. Note: this will return * hourly data for the requested timestamp only (i.e. a single hourly info * element). For example, a request sent where the date_time parameter is set * to 2023-01-03T11:05:49Z will be rounded down to 2023-01-03T11:00:00Z. */ dateTime?: Date; /** * Optional. Additional features that can be optionally enabled. Specifying * extra computations will result in the relevant elements and fields to be * returned in the response. */ extraComputations?: | "EXTRA_COMPUTATION_UNSPECIFIED" | "LOCAL_AQI" | "HEALTH_RECOMMENDATIONS" | "POLLUTANT_ADDITIONAL_INFO" | "DOMINANT_POLLUTANT_CONCENTRATION" | "POLLUTANT_CONCENTRATION"[]; /** * Optional. Allows the client to choose the language for the response. If * data cannot be provided for that language the API uses the closest match. * Allowed values rely on the IETF standard (default = 'en'). */ languageCode?: string; /** * Required. The latitude and longitude for which the API looks for air * quality data. */ location?: LatLng; /** * Optional. The maximum number of hourly info records to return per page * (default = 24). */ pageSize?: number; /** * Optional. A page token received from a previous forecast call. It is used * to retrieve the subsequent page. */ pageToken?: string; /** * Indicates the start and end period for which to get the forecast data. The * timestamp is rounded to the previous exact hour. */ period?: Interval; /** * Optional. Determines the color palette used for data provided by the * 'Universal Air Quality Index' (UAQI). This color palette is relevant just * for UAQI, other AQIs have a predetermined color palette that can't be * controlled. */ uaqiColorPalette?: | "COLOR_PALETTE_UNSPECIFIED" | "RED_GREEN" | "INDIGO_PERSIAN_DARK" | "INDIGO_PERSIAN_LIGHT"; /** * Optional. If set to true, the Universal AQI will be included in the * 'indexes' field of the response (default = true). */ universalAqi?: boolean; } function serializeLookupForecastRequest(data: any): LookupForecastRequest { return { ...data, dateTime: data["dateTime"] !== undefined ? data["dateTime"].toISOString() : undefined, period: data["period"] !== undefined ? serializeInterval(data["period"]) : undefined, }; } function deserializeLookupForecastRequest(data: any): LookupForecastRequest { return { ...data, dateTime: data["dateTime"] !== undefined ? new Date(data["dateTime"]) : undefined, period: data["period"] !== undefined ? deserializeInterval(data["period"]) : undefined, }; } /** * The response object of the air quality forecast API. */ export interface LookupForecastResponse { /** * Optional. Contains the air quality information for each hour in the * requested range. For example, if the request is for 48 hours of forecast * there will be 48 elements of hourly forecasts. */ hourlyForecasts?: HourlyForecast[]; /** * Optional. The token to retrieve the next page. */ nextPageToken?: string; /** * Optional. The ISO_3166-1 alpha-2 code of the country/region corresponding * to the location provided in the request. This field might be omitted from * the response if the location provided in the request resides in a disputed * territory. */ regionCode?: string; } function serializeLookupForecastResponse(data: any): LookupForecastResponse { return { ...data, hourlyForecasts: data["hourlyForecasts"] !== undefined ? data["hourlyForecasts"].map((item: any) => (serializeHourlyForecast(item))) : undefined, }; } function deserializeLookupForecastResponse(data: any): LookupForecastResponse { return { ...data, hourlyForecasts: data["hourlyForecasts"] !== undefined ? data["hourlyForecasts"].map((item: any) => (deserializeHourlyForecast(item))) : undefined, }; } /** * The request object of the air quality history API. */ export interface LookupHistoryRequest { /** * Optional. Expresses a 'country/region to AQI' relationship. Pairs a * country/region with a desired AQI so that air quality data that is required * for that country/region will be displayed according to the chosen AQI. This * parameter can be used to specify a non-default AQI for a given country, for * example, to get the US EPA index for Canada rather than the default index * for Canada. */ customLocalAqis?: CustomLocalAqi[]; /** * A timestamp for which to return historical data. The timestamp is rounded * to the previous exact hour. Note: this will return hourly data for the * requested timestamp only (i.e. a single hourly info element). For example, * a request sent where the dateTime parameter is set to 2023-01-03T11:05:49Z * will be rounded down to 2023-01-03T11:00:00Z. A timestamp in RFC3339 UTC * "Zulu" format, with nanosecond resolution and up to nine fractional digits. * Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z". */ dateTime?: Date; /** * Optional. Additional features that can be optionally enabled. Specifying * extra computations will result in the relevant elements and fields to be * returned in the response. */ extraComputations?: | "EXTRA_COMPUTATION_UNSPECIFIED" | "LOCAL_AQI" | "HEALTH_RECOMMENDATIONS" | "POLLUTANT_ADDITIONAL_INFO" | "DOMINANT_POLLUTANT_CONCENTRATION" | "POLLUTANT_CONCENTRATION"[]; /** * Number from 1 to 720 that indicates the hours range for the request. For * example: A value of 48 will yield data from the last 48 hours. */ hours?: number; /** * Optional. Allows the client to choose the language for the response. If * data cannot be provided for that language the API uses the closest match. * Allowed values rely on the IETF standard. Default value is en. */ languageCode?: string; /** * Required. The latitude and longitude for which the API looks for air * quality history data. */ location?: LatLng; /** * Optional. The maximum number of hourly info records to return per page. * The default is 72 and the max value is 168 (7 days of data). */ pageSize?: number; /** * Optional. A page token received from a previous history call. It is used * to retrieve the subsequent page. Note that when providing a value for this * parameter all other parameters provided must match the call that provided * the page token (the previous call). */ pageToken?: string; /** * Indicates the start and end period for which to get the historical data. * The timestamp is rounded to the previous exact hour. */ period?: Interval; /** * Optional. Determines the color palette used for data provided by the * 'Universal Air Quality Index' (UAQI). This color palette is relevant just * for UAQI, other AQIs have a predetermined color palette that can't be * controlled. */ uaqiColorPalette?: | "COLOR_PALETTE_UNSPECIFIED" | "RED_GREEN" | "INDIGO_PERSIAN_DARK" | "INDIGO_PERSIAN_LIGHT"; /** * Optional. If set to true, the Universal AQI will be included in the * 'indexes' field of the response. Default value is true. */ universalAqi?: boolean; } function serializeLookupHistoryRequest(data: any): LookupHistoryRequest { return { ...data, dateTime: data["dateTime"] !== undefined ? data["dateTime"].toISOString() : undefined, period: data["period"] !== undefined ? serializeInterval(data["period"]) : undefined, }; } function deserializeLookupHistoryRequest(data: any): LookupHistoryRequest { return { ...data, dateTime: data["dateTime"] !== undefined ? new Date(data["dateTime"]) : undefined, period: data["period"] !== undefined ? deserializeInterval(data["period"]) : undefined, }; } export interface LookupHistoryResponse { /** * Optional. Contains the air quality information for each hour in the * requested range. For example, if the request is for 48 hours of history * there will be 48 elements of hourly info. */ hoursInfo?: HourInfo[]; /** * Optional. The token to retrieve the next page. */ nextPageToken?: string; /** * Optional. The ISO_3166-1 alpha-2 code of the country/region corresponding * to the location provided in the request. This field might be omitted from * the response if the location provided in the request resides in a disputed * territory. */ regionCode?: string; } function serializeLookupHistoryResponse(data: any): LookupHistoryResponse { return { ...data, hoursInfo: data["hoursInfo"] !== undefined ? data["hoursInfo"].map((item: any) => (serializeHourInfo(item))) : undefined, }; } function deserializeLookupHistoryResponse(data: any): LookupHistoryResponse { return { ...data, hoursInfo: data["hoursInfo"] !== undefined ? data["hoursInfo"].map((item: any) => (deserializeHourInfo(item))) : undefined, }; } /** * Data regarding an air quality pollutant. */ export interface Pollutant { /** * Additional information about the pollutant. */ additionalInfo?: AdditionalInfo; /** * The pollutant's code name (for example, "so2"). For a list of supported * pollutant codes, see [Reported * pollutants](/maps/documentation/air-quality/pollutants#reported_pollutants). */ code?: string; /** * The pollutant's concentration level measured by one of the standard air * pollutation measure units. */ concentration?: Concentration; /** * The pollutant's display name. For example: "NOx". */ displayName?: string; /** * The pollutant's full name. For chemical compounds, this is the IUPAC name. * Example: "Sulfur Dioxide". For more information about the IUPAC names * table, see https://iupac.org/what-we-do/periodic-table-of-elements/. */ fullName?: string; } function decodeBase64(b64: string): Uint8Array { const binString = atob(b64); const size = binString.length; const bytes = new Uint8Array(size); for (let i = 0; i < size; i++) { bytes[i] = binString.charCodeAt(i); } return bytes; } const base64abc = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","+","/"]; /** * CREDIT: https://gist.github.com/enepomnyaschih/72c423f727d395eeaa09697058238727 * Encodes a given Uint8Array, ArrayBuffer or string into RFC4648 base64 representation * @param data */ function encodeBase64(uint8: Uint8Array): string { let result = "", i; const l = uint8.length; for (i = 2; i < l; i += 3) { result += base64abc[uint8[i - 2] >> 2]; result += base64abc[((uint8[i - 2] & 0x03) << 4) | (uint8[i - 1] >> 4)]; result += base64abc[((uint8[i - 1] & 0x0f) << 2) | (uint8[i] >> 6)]; result += base64abc[uint8[i] & 0x3f]; } if (i === l + 1) { // 1 octet yet to write result += base64abc[uint8[i - 2] >> 2]; result += base64abc[(uint8[i - 2] & 0x03) << 4]; result += "=="; } if (i === l) { // 2 octets yet to write result += base64abc[uint8[i - 2] >> 2]; result += base64abc[((uint8[i - 2] & 0x03) << 4) | (uint8[i - 1] >> 4)]; result += base64abc[(uint8[i - 1] & 0x0f) << 2]; result += "="; } return result; }