UNPKG

leaflet-geosearch

Version:

Adds support for address lookup (a.k.a. geocoding / geosearching) to Leaflet.

103 lines (89 loc) 2.2 kB
import AbstractProvider, { BoundsTuple, EndpointArgument, ParseArgument, ProviderOptions, RequestType, SearchResult, } from './provider'; export type RequestResult = { results: RawResult[]; query: RawQuery[]; }; export interface RawResult { country: string; country_code: string; state: string; county: string; city: string; postcode: number; suburb: string; street: string; lon: string; lat: string; state_code: string; formatted: string; bbox?: BBox; } export interface RawQuery { text: string; parsed: RawQueryParsed; } export type RawQueryParsed = { city: string; expected_type: string; }; export type BBox = { lon1: string; lat1: string; lon2: string; lat2: string; }; export type GeoapifyProviderOptions = { searchUrl?: string; reverseUrl?: string; } & ProviderOptions; export default class GeoapifyProvider extends AbstractProvider< RequestResult, RawResult > { searchUrl: string; reverseUrl: string; constructor(options: GeoapifyProviderOptions = {}) { super(options); const host = 'https://api.geoapify.com/v1/geocode'; this.searchUrl = options.searchUrl || `${host}/search`; this.reverseUrl = options.reverseUrl || `${host}/reverse`; } endpoint({ query, type }: EndpointArgument): string { const params = typeof query === 'string' ? { text: query } : query; params.format = 'json'; switch (type) { case RequestType.REVERSE: return this.getUrl(this.reverseUrl, params); default: return this.getUrl(this.searchUrl, params); } } parse(response: ParseArgument<RequestResult>): SearchResult<RawResult>[] { const records = Array.isArray(response.data.results) ? response.data.results : [response.data.results]; return records.map((r) => { let bounds = null; if (r.bbox) { bounds = [ [parseFloat(r.bbox.lat1), parseFloat(r.bbox.lon1)], // s, w [parseFloat(r.bbox.lat2), parseFloat(r.bbox.lon2)], // n, e ] as BoundsTuple; } return { x: Number(r.lon), y: Number(r.lat), label: r.formatted, bounds, raw: r, }; }); } }