UNPKG

nominatim-browser

Version:

A Nominatim client that can be used from the browser.

284 lines (224 loc) 7.4 kB
import * as Axios from "axios"; import * as Bluebird from "bluebird"; export class NominatimError extends Error { constructor(message: string, public requestData) { super(message); console.log("New nominatim error", requestData); } } export interface Viewbox { left: number; right: number; top: number; bottom: number; } export type FeatureType = 'settlement' | 'country' | 'city' | 'state'; export interface Request { /** * Include a breakdown of the address into elements */ addressdetails?: boolean; /** * If you are making large numbers of requests please include a valid email address or alternatively include * your email address as part of the User-Agent string. This information will be kept confidential and only * used to contact you in the event of a problem. */ email?: string; /** * Include additional information in the result if available, e.g. wikipedia link, opening hours. */ extratags?: boolean; /** * Include a list of alternative names in the results. These may include language variants, references, * operator and brand. */ namedetails?: boolean; } export interface BaseGeocodeRequest extends Request { /** * Output geometry of results in geojson format. */ polygon_geojson?: boolean; /** * Output geometry of results in kml format. */ polygon_kml?: boolean; /** * Output geometry of results in svg format. */ polygon_svg?: boolean; /** * Output geometry of results as a WKT. */ polygon_text?: boolean; } export interface GeocodeRequest extends BaseGeocodeRequest { /** * House number and street name. */ street?: string; city?: string; county?: string; state?: string; country?: string; postalcode?: string; /** * Limit search results to the given 2-digit country codes. */ countrycodes?: string[]; /** * The preferred area to find search results */ viewbox?: Viewbox; /** * The preferred area to find search results */ viewboxlbrt?: Viewbox; /** * Restrict the results to only items contained with the bounding box. Restricting the results to the bounding * box also enables searching by amenity only. */ bounded?: boolean; /** * If you do not want certain openstreetmap objects to appear in the search result, give a comma separated * list of the place_id's you want to skip. */ exclude_place_ids?: string[]; /** * Limit the number of returned results. */ limit?: number; /** * No explanation yet. */ dedupe?: boolean; /** * No explanation yet. */ debug?: boolean; /** * Query string to search for. Can be sent as an alternative to the street, city, county, etc. properties. */ q?: string; /** * Limit results to certain type, instead of trying to match all possible matches. */ featuretype?: FeatureType; } export interface ReverseGeocodeRequest extends BaseGeocodeRequest { osm_type?: string[]; /** * A specific osm node / way / relation to return an address for. Please use this in preference to * lat/lon where possible. */ osm_id?: string; lat?: string; lon?: string; /** * Level of detail required where 0 is country and 18 is house/building. */ zoom?: number; } export interface LookupRequest extends Request { /** * A list of up to 50 specific osm node, way or relations ids separated by commas and prefixed by 'N', 'W' or 'R'. * To determine the osm_id, use a NominatimResponse's 'osm_id' and prefix it with the first letter of its `osm_type`. */ osm_ids: string; } export interface GeocodeAddress { "county": string; "city": string; "city_district": string; "construction": string; "continent": string; "country": string; "country_code": string; "house_number": string; "neighbourhood": string; "postcode": string; "public_building": string; "state": string; "suburb": string; } export interface NominatimResponse { address: GeocodeAddress; boundingbox: string[]; class: string; display_name: string; importance: number; lat: string; /** * [sic] */ licence: string; lon: string; osm_id: string; osm_type: string; place_id: string; svg: string; type: string; extratags: any; } const NOMINATIM_URL: string = 'https://nominatim.openstreetmap.org'; /** Creates a webrequest to the given path. */ function createRequest<T>(path: string, data: Object = {}, nominatimUrl: string) { //Result should be in JSON data["format"] = "json"; const request = Axios<T>({ url: `${nominatimUrl}/${path}`, method: "GET", params: data, responseType: "json", }); return request; }; /** * Finishes a web request and automatically resolves or rejects it. Pass an optional callback to receive the * response's string content and the promise resolver. * @param message The web request method. * @param resolve The promise resolver. * @param reject The promise rejecter. */ function finishRequest<T>(request: Axios.IPromise<Axios.AxiosXHR<T>>) { // While it would be nicer to use Bluebird's Promise.resolve here rather than manually resolving and rejecting, // we would then lose the error message. return new Bluebird<T>((res, rej) => { request.then((resp) => { if (resp.status > 205 || resp.status < 200) { return rej(new NominatimError(`Response for request did not indicate success. ${resp.status} ${resp.statusText}.`, resp.data)); }; res(resp.data); }).catch(e => rej(new NominatimError(e.message, e))); }); }; /** * Creates and handles a complete web request. * @param method The request's HTTP method. * @param path The request's path. * @param data The request's optional querystring or body data object. */ function handleFullRequest<T>(path: string, nominatimUrl: string, data?: any) { var request = createRequest<T>(path, data, nominatimUrl); return finishRequest<T>(request); }; /** * Lookup the latitude and longitude data for a given address. */ export function geocode(data: GeocodeRequest, nominatimUrl: string = NOMINATIM_URL) { return handleFullRequest<NominatimResponse[]>("search", nominatimUrl, data); } /** * Lookup the address data for a pair of latitude and longitude coordinates. */ export function reverseGeocode(data: ReverseGeocodeRequest, nominatimUrl: string = NOMINATIM_URL) { return handleFullRequest<NominatimResponse>("reverse", nominatimUrl, data); } /** * Lookup the address of one or multiple OSM objects like node, way or relation. */ export function lookupAddress(data: LookupRequest, nominatimUrl: string = NOMINATIM_URL) { return handleFullRequest<NominatimResponse[]>("lookup", nominatimUrl, data); }