opencage.ts 2.79 KB
Newer Older
JOE XMG's avatar
update  
JOE XMG committed
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
import * as L from 'leaflet';
import { getJSON } from '../util';
import {
  IGeocoder,
  GeocoderOptions,
  GeocodingCallback,
  geocodingParams,
  GeocodingResult,
  reverseParams
} from './api';

export interface OpenCageOptions extends GeocoderOptions {}

/**
 * Implementation of the [OpenCage Data API](https://opencagedata.com/)
 */
export class OpenCage implements IGeocoder {
  options: OpenCageOptions = {
    serviceUrl: 'https://api.opencagedata.com/geocode/v1/json'
  };

  constructor(options?: Partial<OpenCageOptions>) {
    L.Util.setOptions(this, options);
  }

  geocode(query: string, cb: GeocodingCallback, context?: any): void {
    const params = geocodingParams(this.options, {
      key: this.options.apiKey,
      q: query
    });
    getJSON(this.options.serviceUrl, params, data => {
      const results: GeocodingResult[] = [];
      if (data.results && data.results.length) {
        for (let i = 0; i < data.results.length; i++) {
          const loc = data.results[i];
          const center = L.latLng(loc.geometry);
          let bbox: L.LatLngBounds;
          if (loc.annotations && loc.annotations.bounds) {
            bbox = L.latLngBounds(
              L.latLng(loc.annotations.bounds.northeast),
              L.latLng(loc.annotations.bounds.southwest)
            );
          } else {
            bbox = L.latLngBounds(center, center);
          }
          results.push({
            name: loc.formatted,
            bbox: bbox,
            center: center
          });
        }
      }
      cb.call(context, results);
    });
  }

  suggest(query: string, cb: GeocodingCallback, context?: any): void {
    return this.geocode(query, cb, context);
  }

  reverse(location: L.LatLngLiteral, scale: number, cb: GeocodingCallback, context?: any): void {
    const params = reverseParams(this.options, {
      key: this.options.apiKey,
      q: [location.lat, location.lng].join(',')
    });
    getJSON(this.options.serviceUrl, params, data => {
      const results: GeocodingResult[] = [];
      if (data.results && data.results.length) {
        for (let i = 0; i < data.results.length; i++) {
          const loc = data.results[i];
          const center = L.latLng(loc.geometry);
          let bbox: L.LatLngBounds;
          if (loc.annotations && loc.annotations.bounds) {
            bbox = L.latLngBounds(
              L.latLng(loc.annotations.bounds.northeast),
              L.latLng(loc.annotations.bounds.southwest)
            );
          } else {
            bbox = L.latLngBounds(center, center);
          }
          results.push({
            name: loc.formatted,
            bbox: bbox,
            center: center
          });
        }
      }
      cb.call(context, results);
    });
  }
}

export function opencage(options?: Partial<OpenCageOptions>) {
  return new OpenCage(options);
}