@nextgis/geocoder 1.17.0 → 1.18.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,13 @@
2
2
 
3
3
  ![size](https://img.shields.io/bundlephobia/minzip/@nextgis/geocoder) ![version](https://img.shields.io/npm/v/@nextgis/geocoder)
4
4
 
5
- Modern geocoder on async generators. May use different data providers.
5
+ Geocoder is a versatile library designed for intuitive geocoding functionalities.
6
+ With an emphasis on ease-of-use, it supports multiple providers to cater to diverse requirements, allowing developers to seamlessly integrate geocoding into their applications.
7
+
8
+ ## Built-in providers
9
+
10
+ - NgwProvider: Specifically for the NGW vector layer, ideal for applications that rely on NextGIS services.
11
+ - NominatimProvider: Utilizes the Nominatim geocoding service, suitable for applications requiring free geocoding services with OpenStreetMap data.
6
12
 
7
13
  ## Installation
8
14
 
@@ -48,12 +54,41 @@ $ yarn add @nextgis/geocoder
48
54
 
49
55
  ## Usage
50
56
 
51
- ```javascript
52
- import { Geocoder } from '@nextgis/geocoder';
57
+ ### Basic Usage with NGW Provider
53
58
 
54
- const ngwConnector = new Geocoder({
55
- ...options
59
+ ```javascript
60
+ import { Geocoder, NgwProvider } from '@nextgis/geocoder';
61
+
62
+ // Initialize the NGW Provider
63
+ const ngwProvider = new NgwProvider({
64
+ connectorOptions: {
65
+ baseUrl: 'https://demo.nextgis.com',
66
+ },
67
+ searchResources: [
68
+ {
69
+ resourceId: 4224,
70
+ limit: 3,
71
+ },
72
+ // ... other resources
73
+ ],
56
74
  });
75
+
76
+ // Initialize the geocoder
77
+ const geocoder = new Geocoder({ providers: [ngwProvider] });
78
+
79
+ // Use geocoder.search() for geocoding queries
80
+ const searchQuery = "example_search_query"; // Replace with your search term
81
+ const geocoderGenerator = geocoder.search(searchQuery);
82
+
83
+ // Iterate over the geocoder generator to get the search results
84
+ for await (const item of geocoderGenerator) {
85
+ console.log(item.text); // Log the item name or description
86
+ item.result().then(({ extent }) => {
87
+ // Use the result's extent or other properties as needed
88
+ console.log(extent);
89
+ });
90
+ break;
91
+ }
57
92
  ```
58
93
 
59
94
  Check out the [API Documentation](https://code-api.nextgis.com/modules/geocoder.html)
@@ -1,4 +1,4 @@
1
- /** Bundle of @nextgis/geocoder; version: 1.17.0; author: NextGIS */
1
+ /** Bundle of @nextgis/geocoder; version: 1.18.6; author: NextGIS */
2
2
  'use strict';
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
@@ -6,12 +6,19 @@ Object.defineProperty(exports, '__esModule', { value: true });
6
6
  var CancelablePromise = require('@nextgis/cancelable-promise');
7
7
  var utils = require('@nextgis/utils');
8
8
  var NgwConnector = require('@nextgis/ngw-connector');
9
+ var ngwKit = require('@nextgis/ngw-kit');
9
10
 
10
11
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
11
12
 
12
13
  var CancelablePromise__default = /*#__PURE__*/_interopDefaultLegacy(CancelablePromise);
13
14
  var NgwConnector__default = /*#__PURE__*/_interopDefaultLegacy(NgwConnector);
14
15
 
16
+ /**
17
+ * Represents the base class for a geocoder.
18
+ * This abstract class provides the basic methods that every geocoder should implement.
19
+ *
20
+ * @template O - The type of options that can be passed to the geocoder.
21
+ */
15
22
  class BaseGeocoder {
16
23
  constructor(options) {
17
24
  if (options) {
@@ -57,62 +64,89 @@ class Geocoder extends BaseGeocoder {
57
64
  }
58
65
  }
59
66
 
67
+ /**
68
+ * Abstract base class representing a search provider.
69
+ * It builds upon the BaseGeocoder functionalities with provider-specific properties.
70
+ * @template O - Options type which extends BaseProviderOptions.
71
+ */
60
72
  class BaseProvider extends BaseGeocoder {
61
73
  }
62
74
 
63
75
  class NgwProvider extends BaseProvider {
64
76
  constructor(options) {
77
+ var _a;
65
78
  super(options);
66
- this.caseInsensitive = true;
67
- this.searchUrl = 'https://maxim.nextgis.com';
68
79
  this.searchResources = [];
69
- this.requests = [];
80
+ this._abortControllers = [];
81
+ if (!options.searchUrl && !((_a = options.connectorOptions) === null || _a === void 0 ? void 0 : _a.baseUrl)) {
82
+ throw new Error('The `searchUrl` of `connectorOptions.baseUrl` are required');
83
+ }
70
84
  this.connector =
71
85
  options.connector ||
72
86
  new NgwConnector__default({
73
87
  baseUrl: this.searchUrl,
88
+ ...options.connectorOptions,
74
89
  });
75
90
  this.searchResources = options.searchResources;
76
91
  }
77
92
  abort() {
78
- this.requests.forEach((x) => {
79
- x.cancel();
93
+ this._abortControllers.forEach((a) => {
94
+ a.abort();
80
95
  });
81
- this.requests = [];
96
+ this._abortControllers.length = 0;
82
97
  }
83
- async *search(like) {
84
- for (const resource of this.searchResources) {
85
- const limit = resource.limit || 300;
86
- const request = this.connector.get('feature_layer.store', {
87
- headers: { RANGE: `items=0-${limit}` },
88
- }, {
89
- id: resource.id,
90
- like,
91
- });
92
- this.requests.push(request);
93
- request.catch((er) => {
94
- console.warn(er);
95
- });
96
- const resp = await request;
97
- const entries = [];
98
- if (resp) {
99
- resp.forEach((x) => {
100
- entries.push({
101
- query: like,
102
- resourceId: resource.id,
103
- ...x,
104
- });
98
+ async *search(query) {
99
+ var _a, _b;
100
+ const signal = this._makeSignal();
101
+ for (const config of this.searchResources) {
102
+ if (signal.aborted) {
103
+ break;
104
+ }
105
+ const { searchMethod } = config;
106
+ const limit = (_a = config.limit) !== null && _a !== void 0 ? _a : NgwProvider.limit;
107
+ //
108
+ const resourceId = (_b = config.id) !== null && _b !== void 0 ? _b : config.resourceId;
109
+ try {
110
+ const resource = await this.connector.getResourceOrFail(resourceId, {
111
+ cache: true,
105
112
  });
113
+ const options = {
114
+ connector: this.connector,
115
+ resourceId,
116
+ signal,
117
+ limit,
118
+ };
119
+ if (searchMethod === 'like') {
120
+ options.like = query;
121
+ }
122
+ else {
123
+ options.ilike = query;
124
+ }
125
+ const request = ngwKit.fetchNgwLayerItems(options);
126
+ const entries = await request;
127
+ for (const item of this._items({
128
+ entries,
129
+ query,
130
+ config,
131
+ resourceItem: resource,
132
+ })) {
133
+ item.result = () => this.result(item);
134
+ yield item;
135
+ }
106
136
  }
107
- for (const item of this._items(entries)) {
108
- item.result = () => this.result(item);
109
- yield item;
137
+ catch (er) {
138
+ if (er &&
139
+ 'name' in er &&
140
+ er.name !== 'CancelError') {
141
+ console.warn(er);
142
+ }
110
143
  }
111
144
  }
112
145
  }
113
146
  result(item) {
147
+ const signal = this._makeSignal();
114
148
  const req = this.connector
115
- .get('feature_layer.feature.item_extent', null, {
149
+ .get('feature_layer.feature.item_extent', { signal }, {
116
150
  id: item.resourceId,
117
151
  fid: item.featureId,
118
152
  })
@@ -123,25 +157,47 @@ class NgwProvider extends BaseProvider {
123
157
  extent: [e.minLon, e.minLat, e.maxLon, e.maxLat],
124
158
  };
125
159
  });
126
- this.requests.push(req);
127
160
  return req;
128
161
  }
129
- _items(entries) {
162
+ _makeSignal() {
163
+ const abortController = new AbortController();
164
+ this._abortControllers.push(abortController);
165
+ return abortController.signal;
166
+ }
167
+ _items({ entries, query, config, resourceItem, }) {
168
+ var _a;
130
169
  const items = [];
131
- entries.forEach((entry) => {
132
- const meta = this.searchResources.find((x) => x.id === entry.resourceId);
133
- if (meta) {
170
+ let labelField = undefined;
171
+ if (resourceItem.feature_layer) {
172
+ labelField = (_a = resourceItem.feature_layer.fields.find((f) => f.label_field)) === null || _a === void 0 ? void 0 : _a.keyname;
173
+ }
174
+ const meta = this.searchResources.find((x) => { var _a; return (_a = x.id) !== null && _a !== void 0 ? _a : x.resourceId === resourceItem.resource.id; });
175
+ if (meta) {
176
+ entries.forEach((entry) => {
177
+ let text = labelField ? entry.fields[labelField] : entry.id;
178
+ if (config.renderSearch) {
179
+ text = config.renderSearch({
180
+ item: entry,
181
+ resourceItem,
182
+ });
183
+ }
184
+ else if (labelField) {
185
+ text = entry.fields[labelField];
186
+ }
134
187
  items.push({
135
- query: entry.query,
136
- text: entry.label,
188
+ query: query,
189
+ text,
137
190
  featureId: entry.id,
138
- resourceId: entry.resourceId,
191
+ resourceId: resourceItem.resource.id,
192
+ item: entry,
193
+ resourceItem,
139
194
  });
140
- }
141
- });
195
+ });
196
+ }
142
197
  return items;
143
198
  }
144
199
  }
200
+ NgwProvider.limit = 300;
145
201
 
146
202
  class NominatimProvider extends BaseProvider {
147
203
  constructor(options) {
@@ -207,6 +263,12 @@ class NominatimProvider extends BaseProvider {
207
263
  }
208
264
  }
209
265
 
266
+ /**
267
+ * Modern geocoder on async generators. May use different data providers.
268
+ *
269
+ * @packageDocumentation
270
+ * @module geocoder
271
+ */
210
272
  function create(options) {
211
273
  return new Geocoder(options);
212
274
  }
@@ -1 +1 @@
1
- {"version":3,"file":"geocoder.cjs.js","sources":["../src/BaseGeocoder.ts","../src/Geocoder.ts","../src/providers/BaseProvider.ts","../src/providers/NgwProvider.ts","../src/providers/NominatimProvider.ts","../src/index.ts"],"sourcesContent":["import { objectAssign } from '@nextgis/utils';\nimport CancelablePromise from '@nextgis/cancelable-promise';\nimport { SearchItem } from './types/SearchItem';\n\nexport abstract class BaseGeocoder<\n O extends Record<string, any> = Record<string, any>,\n> {\n constructor(options?: O) {\n if (options) {\n objectAssign(this, options);\n }\n }\n\n abstract search(query: string): AsyncGenerator<SearchItem>;\n\n abstract result(item: SearchItem): CancelablePromise<any>;\n\n abstract abort?(): void;\n}\n","import CancelablePromise from '@nextgis/cancelable-promise';\nimport { BaseProvider } from './providers/BaseProvider';\nimport { GeocoderOptions } from './GeocoderOptions';\nimport { BaseGeocoder } from './BaseGeocoder';\nimport { SearchItem } from './types/SearchItem';\n\nlet ID = 0;\n\nexport class Geocoder extends BaseGeocoder<GeocoderOptions> {\n providers: BaseProvider[] = [];\n\n constructor(options: GeocoderOptions) {\n super(options);\n if (options && options.providers) {\n this.providers = options.providers;\n }\n }\n\n abort(): void {\n this.providers.forEach((x) => {\n if (x.abort) {\n x.abort();\n }\n });\n }\n\n async *search(query: string): AsyncGenerator<SearchItem, void, unknown> {\n for (const provider of this.providers) {\n try {\n const results = provider.search(query);\n\n for await (const r of results) {\n yield { ...r, provider, _id: ID++ };\n }\n } catch (er) {\n //\n }\n }\n }\n\n result(item: SearchItem): CancelablePromise<any> {\n if (item.provider) {\n return item.provider.result(item);\n }\n return CancelablePromise.resolve(undefined);\n }\n}\n","import { BaseProviderOptions } from './BaseProviderOptions';\nimport { BaseGeocoder } from '../BaseGeocoder';\n\nexport abstract class BaseProvider<\n O extends BaseProviderOptions = BaseProviderOptions,\n> extends BaseGeocoder<O> {\n searchUrl?: string;\n label?: string;\n}\n","import NgwConnector, { ResourceStoreItem } from '@nextgis/ngw-connector';\nimport CancelablePromise from '@nextgis/cancelable-promise';\nimport { BaseProvider } from './BaseProvider';\nimport { BaseProviderOptions } from './BaseProviderOptions';\nimport { SearchItem } from '../types/SearchItem';\nimport { ResultItem } from '../types/ResultItem';\n\ninterface NgwSearchItem extends SearchItem {\n resourceId: number;\n featureId: number;\n}\n\ninterface SearchResource {\n id: number;\n limit?: number;\n}\n\ninterface NgwProviderOptions extends BaseProviderOptions {\n connector?: NgwConnector;\n searchResources: SearchResource[];\n}\n\nexport class NgwProvider extends BaseProvider<NgwProviderOptions> {\n caseInsensitive = true;\n searchUrl = 'https://maxim.nextgis.com';\n searchResources: SearchResource[] = [];\n private connector: NgwConnector;\n private requests: CancelablePromise[] = [];\n\n constructor(options: NgwProviderOptions) {\n super(options);\n\n this.connector =\n options.connector ||\n new NgwConnector({\n baseUrl: this.searchUrl,\n });\n this.searchResources = options.searchResources;\n }\n\n abort(): void {\n this.requests.forEach((x) => {\n x.cancel();\n });\n this.requests = [];\n }\n\n async *search(like: string): AsyncGenerator<NgwSearchItem, void, unknown> {\n for (const resource of this.searchResources) {\n const limit = resource.limit || 300;\n const request = this.connector.get(\n 'feature_layer.store',\n {\n headers: { RANGE: `items=0-${limit}` },\n },\n {\n id: resource.id,\n like,\n },\n );\n this.requests.push(request);\n request.catch((er) => {\n console.warn(er);\n });\n const resp = await request;\n const entries: ResourceStoreItem[] = [];\n if (resp) {\n resp.forEach((x) => {\n entries.push({\n query: like,\n resourceId: resource.id,\n ...x,\n });\n });\n }\n for (const item of this._items(entries)) {\n item.result = () => this.result(item);\n yield item;\n }\n }\n }\n\n result(item: NgwSearchItem): CancelablePromise<ResultItem> {\n const req = this.connector\n .get('feature_layer.feature.item_extent', null, {\n id: item.resourceId,\n fid: item.featureId,\n })\n .then((x) => {\n const e = x.extent;\n return {\n text: item.text,\n extent: [e.minLon, e.minLat, e.maxLon, e.maxLat],\n };\n });\n this.requests.push(req);\n return req;\n }\n\n _items(entries: ResourceStoreItem[]): NgwSearchItem[] {\n const items: NgwSearchItem[] = [];\n entries.forEach((entry) => {\n const meta = this.searchResources.find((x) => x.id === entry.resourceId);\n if (meta) {\n items.push({\n query: entry.query,\n text: entry.label,\n featureId: entry.id,\n resourceId: entry.resourceId,\n });\n }\n });\n return items;\n }\n}\n","import { fixUrlStr } from '@nextgis/utils';\nimport CancelablePromise from '@nextgis/cancelable-promise';\nimport { BaseProvider } from './BaseProvider';\nimport { BaseProviderOptions } from './BaseProviderOptions';\nimport { FeatureCollection } from 'geojson';\nimport { SearchItem } from '../types/SearchItem';\nimport { ResultItem } from '../types/ResultItem';\n\nexport class NominatimProvider extends BaseProvider {\n searchUrl = 'https://nominatim.openstreetmap.org';\n\n private _requests: CancelablePromise[] = [];\n\n constructor(options?: BaseProviderOptions) {\n super(options);\n }\n\n abort(): void {\n this._requests.forEach((x) => x.cancel());\n this._requests = [];\n }\n\n async *search(val: string): AsyncGenerator<SearchItem, void, unknown> {\n // RFC2616 accept - language string\n const url = fixUrlStr(\n // `${this.baseUrl}/search?format=geojson&polygon_geojson=1${window.locale === 'ru' ? '&accept-language=ru-RU,en-US' : ''}&q=${val}`\n `${this.searchUrl}/search?format=geojson&polygon_geojson=1&q=${val}`,\n );\n const request = new CancelablePromise<SearchItem[]>(\n (resolve, reject, onCancel) => {\n const xhr = new XMLHttpRequest();\n xhr.open('GET', url, true);\n xhr.onload = () => {\n try {\n const geojson = JSON.parse(xhr.responseText) as FeatureCollection;\n const features: SearchItem[] = geojson.features.map((x) => {\n return {\n geom: x,\n extent: x.bbox,\n text: x.properties && x.properties.display_name,\n query: val,\n };\n });\n resolve(features);\n } catch (er) {\n reject(er);\n }\n };\n\n xhr.onerror = (er) => {\n reject(er);\n };\n\n onCancel(() => {\n xhr.abort();\n });\n\n xhr.send();\n },\n ).catch((er) => {\n if (er.name === 'CancelError') {\n //\n }\n throw er;\n });\n this._requests.push(request);\n const items = await request;\n if (items) {\n for (const i of items) {\n i.result = () => this.result(i);\n yield i;\n }\n }\n }\n\n result(model: SearchItem): CancelablePromise<ResultItem> {\n return CancelablePromise.resolve({\n text: model.text,\n extent: model.extent || [],\n geom: model.geom,\n });\n }\n}\n","/**\n * Modern geocoder on async generators. May use different data providers.\n *\n * @packageDocumentation\n * @module geocoder\n */\nimport { GeocoderOptions } from './GeocoderOptions';\nimport { Geocoder } from './Geocoder';\n\nexport { Geocoder, GeocoderOptions };\nexport { BaseProvider } from './providers/BaseProvider';\nexport { NgwProvider } from './providers/NgwProvider';\nexport { NominatimProvider } from './providers/NominatimProvider';\n\nexport * from './providers/BaseProviderOptions';\nexport * from './types/ResultItem';\nexport * from './types/SearchItem';\n\nexport function create(options: GeocoderOptions): Geocoder {\n return new Geocoder(options);\n}\n"],"names":["objectAssign","CancelablePromise","NgwConnector","fixUrlStr"],"mappings":"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"}
1
+ {"version":3,"file":"geocoder.cjs.js","sources":["../src/BaseGeocoder.ts","../src/Geocoder.ts","../src/providers/BaseProvider.ts","../src/providers/NgwProvider.ts","../src/providers/NominatimProvider.ts","../src/index.ts"],"sourcesContent":["import { objectAssign } from '@nextgis/utils';\nimport type CancelablePromise from '@nextgis/cancelable-promise';\nimport type { SearchItem } from './types/SearchItem';\n\n/**\n * Represents the base class for a geocoder.\n * This abstract class provides the basic methods that every geocoder should implement.\n *\n * @template O - The type of options that can be passed to the geocoder.\n */\nexport abstract class BaseGeocoder<\n O extends Record<string, any> = Record<string, any>,\n> {\n constructor(options?: O) {\n if (options) {\n objectAssign(this, options);\n }\n }\n\n /**\n * Search method to retrieve geocoding results.\n *\n * @abstract\n * @param {string} query - The search string to geocode.\n * @yields {AsyncGenerator<SearchItem>} - An async generator that yields search results.\n */\n abstract search(query: string): AsyncGenerator<SearchItem>;\n\n /**\n * Method to retrieve detailed result for a specific search item.\n *\n * @abstract\n * @param {SearchItem} item - The search item to get detailed result for.\n * @returns {CancelablePromise<any>} - A promise that resolves to the detailed result.\n */\n abstract result(item: SearchItem): CancelablePromise<any>;\n\n /**\n * Optional method to abort any ongoing geocoding requests.\n *\n * @abstract\n */\n abstract abort?(): void;\n}\n","import CancelablePromise from '@nextgis/cancelable-promise';\nimport { BaseProvider } from './providers/BaseProvider';\nimport { GeocoderOptions } from './GeocoderOptions';\nimport { BaseGeocoder } from './BaseGeocoder';\nimport { SearchItem } from './types/SearchItem';\n\nlet ID = 0;\n\nexport class Geocoder extends BaseGeocoder<GeocoderOptions> {\n providers: BaseProvider[] = [];\n\n constructor(options: GeocoderOptions) {\n super(options);\n if (options && options.providers) {\n this.providers = options.providers;\n }\n }\n\n abort(): void {\n this.providers.forEach((x) => {\n if (x.abort) {\n x.abort();\n }\n });\n }\n\n async *search(query: string): AsyncGenerator<SearchItem, void, unknown> {\n for (const provider of this.providers) {\n try {\n const results = provider.search(query);\n\n for await (const r of results) {\n yield { ...r, provider, _id: ID++ };\n }\n } catch (er) {\n //\n }\n }\n }\n\n result(item: SearchItem): CancelablePromise<any> {\n if (item.provider) {\n return item.provider.result(item);\n }\n return CancelablePromise.resolve(undefined);\n }\n}\n","import { BaseProviderOptions } from './BaseProviderOptions';\nimport { BaseGeocoder } from '../BaseGeocoder';\n\n/**\n * Abstract base class representing a search provider.\n * It builds upon the BaseGeocoder functionalities with provider-specific properties.\n * @template O - Options type which extends BaseProviderOptions.\n */\nexport abstract class BaseProvider<\n O extends BaseProviderOptions = BaseProviderOptions,\n> extends BaseGeocoder<O> {\n /**\n * URL endpoint for the search service.\n * This is where queries will be sent to obtain search results.\n */\n searchUrl?: string;\n\n /**\n * Label to represent the provider.\n * Useful for user interfaces to display the source of search results.\n */\n label?: string;\n}\n","import NgwConnector from '@nextgis/ngw-connector';\nimport { fetchNgwLayerItems } from '@nextgis/ngw-kit';\n\nimport { BaseProvider } from './BaseProvider';\n\nimport type CancelablePromise from '@nextgis/cancelable-promise';\nimport type {\n FeatureItem,\n NgwConnectorOptions,\n ResourceItem,\n} from '@nextgis/ngw-connector';\nimport type { FetchNgwItemsOptions } from '@nextgis/ngw-kit';\n\nimport type { ResultItem } from '../types/ResultItem';\nimport type { SearchItem } from '../types/SearchItem';\nimport type { BaseProviderOptions } from './BaseProviderOptions';\n\n/**\n * Extends the basic search item with NGW-specific properties.\n */\ninterface NgwSearchItem extends SearchItem {\n /** ID of the NGW resource */\n resourceId: number;\n /** ID of the feature in the NGW resource */\n featureId: number;\n /** The specific feature item from NGW */\n item: FeatureItem;\n /** The NGW resource item */\n resourceItem: ResourceItem;\n}\n\n/**\n * Defines the structure for a rendered search item.\n */\ninterface RenderSearchItem {\n /** The specific feature item */\n item: FeatureItem;\n /** The NGW resource item */\n resourceItem: ResourceItem;\n}\n\n/**\n * Options for searching within a NGW resource.\n */\ninterface SearchResource extends FetchNgwItemsOptions {\n /** The search method used ('ilike' is case-insensitive) */\n searchMethod?: 'ilike' | 'like';\n /** Custom rendering function for search results */\n renderSearch?: (item: RenderSearchItem) => string | HTMLElement;\n}\n\n/**\n * Options required to initialize an NGW provider.\n */\ninterface NgwProviderOptions extends BaseProviderOptions {\n /** Connector instance for NGW. If not provided, will be created internally */\n connector?: NgwConnector;\n /** List of NGW resources to search within */\n searchResources: SearchResource[];\n /** Options for the internal NgwConnector (if one needs to be created) */\n connectorOptions?: NgwConnectorOptions;\n}\n\nexport class NgwProvider extends BaseProvider<NgwProviderOptions> {\n static limit = 300;\n\n searchResources: SearchResource[] = [];\n\n private connector: NgwConnector;\n private _abortControllers: AbortController[] = [];\n\n constructor(options: NgwProviderOptions) {\n super(options);\n if (!options.searchUrl && !options.connectorOptions?.baseUrl) {\n throw new Error(\n 'The `searchUrl` of `connectorOptions.baseUrl` are required',\n );\n }\n\n this.connector =\n options.connector ||\n new NgwConnector({\n baseUrl: this.searchUrl,\n ...options.connectorOptions,\n });\n this.searchResources = options.searchResources;\n }\n\n abort(): void {\n this._abortControllers.forEach((a) => {\n a.abort();\n });\n this._abortControllers.length = 0;\n }\n\n async *search(query: string): AsyncGenerator<NgwSearchItem, void, unknown> {\n const signal = this._makeSignal();\n for (const config of this.searchResources) {\n if (signal.aborted) {\n break;\n }\n const { searchMethod } = config;\n\n const limit = config.limit ?? NgwProvider.limit;\n //\n const resourceId = (config as any).id ?? config.resourceId;\n\n try {\n const resource = await this.connector.getResourceOrFail(resourceId, {\n cache: true,\n });\n\n const options: FetchNgwItemsOptions = {\n connector: this.connector,\n resourceId,\n signal,\n limit,\n };\n\n if (searchMethod === 'like') {\n options.like = query;\n } else {\n options.ilike = query;\n }\n\n const request = fetchNgwLayerItems(options);\n\n const entries = await request;\n\n for (const item of this._items({\n entries,\n query,\n config,\n resourceItem: resource,\n })) {\n item.result = () => this.result(item);\n yield item;\n }\n } catch (er) {\n if (\n er &&\n 'name' in (er as Error) &&\n (er as Error).name !== 'CancelError'\n ) {\n console.warn(er);\n }\n }\n }\n }\n\n result(item: NgwSearchItem): CancelablePromise<ResultItem> {\n const signal = this._makeSignal();\n const req = this.connector\n .get(\n 'feature_layer.feature.item_extent',\n { signal },\n {\n id: item.resourceId,\n fid: item.featureId,\n },\n )\n .then((x) => {\n const e = x.extent;\n return {\n text: item.text,\n extent: [e.minLon, e.minLat, e.maxLon, e.maxLat],\n };\n });\n return req;\n }\n\n private _makeSignal() {\n const abortController = new AbortController();\n this._abortControllers.push(abortController);\n return abortController.signal;\n }\n\n private _items({\n entries,\n query,\n config,\n resourceItem,\n }: {\n config: SearchResource;\n entries: FeatureItem[];\n query: string;\n resourceItem: ResourceItem;\n }): NgwSearchItem[] {\n const items: NgwSearchItem[] = [];\n\n let labelField: string | undefined = undefined;\n\n if (resourceItem.feature_layer) {\n labelField = resourceItem.feature_layer.fields.find(\n (f) => f.label_field,\n )?.keyname;\n }\n\n const meta = this.searchResources.find(\n (x) => (x as any).id ?? x.resourceId === resourceItem.resource.id,\n );\n if (meta) {\n entries.forEach((entry) => {\n let text = labelField ? entry.fields[labelField] : entry.id;\n if (config.renderSearch) {\n text = config.renderSearch({\n item: entry,\n resourceItem,\n });\n } else if (labelField) {\n text = entry.fields[labelField];\n }\n\n items.push({\n query: query,\n text,\n featureId: entry.id,\n resourceId: resourceItem.resource.id,\n item: entry,\n resourceItem,\n });\n });\n }\n return items;\n }\n}\n","import { fixUrlStr } from '@nextgis/utils';\nimport CancelablePromise from '@nextgis/cancelable-promise';\nimport { BaseProvider } from './BaseProvider';\nimport { BaseProviderOptions } from './BaseProviderOptions';\nimport { FeatureCollection } from 'geojson';\nimport { SearchItem } from '../types/SearchItem';\nimport { ResultItem } from '../types/ResultItem';\n\nexport class NominatimProvider extends BaseProvider {\n searchUrl = 'https://nominatim.openstreetmap.org';\n\n private _requests: CancelablePromise[] = [];\n\n constructor(options?: BaseProviderOptions) {\n super(options);\n }\n\n abort(): void {\n this._requests.forEach((x) => x.cancel());\n this._requests = [];\n }\n\n async *search(val: string): AsyncGenerator<SearchItem, void, unknown> {\n // RFC2616 accept - language string\n const url = fixUrlStr(\n // `${this.baseUrl}/search?format=geojson&polygon_geojson=1${window.locale === 'ru' ? '&accept-language=ru-RU,en-US' : ''}&q=${val}`\n `${this.searchUrl}/search?format=geojson&polygon_geojson=1&q=${val}`,\n );\n const request = new CancelablePromise<SearchItem[]>(\n (resolve, reject, onCancel) => {\n const xhr = new XMLHttpRequest();\n xhr.open('GET', url, true);\n xhr.onload = () => {\n try {\n const geojson = JSON.parse(xhr.responseText) as FeatureCollection;\n const features: SearchItem[] = geojson.features.map((x) => {\n return {\n geom: x,\n extent: x.bbox,\n text: x.properties && x.properties.display_name,\n query: val,\n };\n });\n resolve(features);\n } catch (er) {\n reject(er);\n }\n };\n\n xhr.onerror = (er) => {\n reject(er);\n };\n\n onCancel(() => {\n xhr.abort();\n });\n\n xhr.send();\n },\n ).catch((er) => {\n if (er.name === 'CancelError') {\n //\n }\n throw er;\n });\n this._requests.push(request);\n const items = await request;\n if (items) {\n for (const i of items) {\n i.result = () => this.result(i);\n yield i;\n }\n }\n }\n\n result(model: SearchItem): CancelablePromise<ResultItem> {\n return CancelablePromise.resolve({\n text: model.text,\n extent: model.extent || [],\n geom: model.geom,\n });\n }\n}\n","/**\n * Modern geocoder on async generators. May use different data providers.\n *\n * @packageDocumentation\n * @module geocoder\n */\nimport { Geocoder } from './Geocoder';\nimport type { GeocoderOptions } from './GeocoderOptions';\n\nexport { Geocoder, GeocoderOptions };\nexport { BaseProvider } from './providers/BaseProvider';\nexport { NgwProvider } from './providers/NgwProvider';\nexport { NominatimProvider } from './providers/NominatimProvider';\n\nexport * from './providers/BaseProviderOptions';\nexport * from './types/ResultItem';\nexport * from './types/SearchItem';\n\nexport function create(options: GeocoderOptions): Geocoder {\n return new Geocoder(options);\n}\n"],"names":["objectAssign","CancelablePromise","NgwConnector","fetchNgwLayerItems","fixUrlStr"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@nextgis/cancelable-promise"),t=require("@nextgis/utils"),s=require("@nextgis/ngw-connector");function r(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var o=r(e),c=r(s);class i{constructor(e){e&&t.objectAssign(this,e)}}let n=0;class a extends i{constructor(e){super(e),this.providers=[],e&&e.providers&&(this.providers=e.providers)}abort(){this.providers.forEach((e=>{e.abort&&e.abort()}))}async*search(e){for(const s of this.providers)try{const t=s.search(e);for await(const e of t)yield{...e,provider:s,_id:n++}}catch(t){}}result(e){return e.provider?e.provider.result(e):o.resolve(void 0)}}class u extends i{}exports.BaseProvider=u,exports.Geocoder=a,exports.NgwProvider=class extends u{constructor(e){super(e),this.caseInsensitive=!0,this.searchUrl="https://maxim.nextgis.com",this.searchResources=[],this.requests=[],this.connector=e.connector||new c({baseUrl:this.searchUrl}),this.searchResources=e.searchResources}abort(){this.requests.forEach((e=>{e.cancel()})),this.requests=[]}async*search(e){for(const t of this.searchResources){const s=this.connector.get("feature_layer.store",{headers:{RANGE:`items=0-${t.limit||300}`}},{id:t.id,like:e});this.requests.push(s),s.catch((e=>{console.warn(e)}));const r=await s,o=[];r&&r.forEach((s=>{o.push({query:e,resourceId:t.id,...s})}));for(const e of this._items(o))e.result=()=>this.result(e),yield e}}result(e){const t=this.connector.get("feature_layer.feature.item_extent",null,{id:e.resourceId,fid:e.featureId}).then((t=>{const s=t.extent;return{text:e.text,extent:[s.minLon,s.minLat,s.maxLon,s.maxLat]}}));return this.requests.push(t),t}_items(e){const t=[];return e.forEach((e=>{this.searchResources.find((t=>t.id===e.resourceId))&&t.push({query:e.query,text:e.label,featureId:e.id,resourceId:e.resourceId})})),t}},exports.NominatimProvider=class extends u{constructor(e){super(e),this.searchUrl="https://nominatim.openstreetmap.org",this._requests=[]}abort(){this._requests.forEach((e=>e.cancel())),this._requests=[]}async*search(e){const s=t.fixUrlStr(`${this.searchUrl}/search?format=geojson&polygon_geojson=1&q=${e}`),r=new o(((t,r,o)=>{const c=new XMLHttpRequest;c.open("GET",s,!0),c.onload=()=>{try{const s=JSON.parse(c.responseText).features.map((t=>({geom:t,extent:t.bbox,text:t.properties&&t.properties.display_name,query:e})));t(s)}catch(s){r(s)}},c.onerror=e=>{r(e)},o((()=>{c.abort()})),c.send()})).catch((e=>{throw e}));this._requests.push(r);const c=await r;if(c)for(const t of c)t.result=()=>this.result(t),yield t}result(e){return o.resolve({text:e.text,extent:e.extent||[],geom:e.geom})}},exports.create=function(e){return new a(e)};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@nextgis/cancelable-promise"),r=require("@nextgis/utils"),t=require("@nextgis/ngw-connector"),s=require("@nextgis/ngw-kit");function o(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var n=o(e),i=o(t);class c{constructor(e){e&&r.objectAssign(this,e)}}let a=0;class l extends c{constructor(e){super(e),this.providers=[],e&&e.providers&&(this.providers=e.providers)}abort(){this.providers.forEach((e=>{e.abort&&e.abort()}))}async*search(e){for(const t of this.providers)try{const r=t.search(e);for await(const e of r)yield{...e,provider:t,_id:a++}}catch(r){}}result(e){return e.provider?e.provider.result(e):n.resolve(void 0)}}class u extends c{}class h extends u{constructor(e){var r;if(super(e),this.searchResources=[],this._abortControllers=[],!e.searchUrl&&!(null===(r=e.connectorOptions)||void 0===r?void 0:r.baseUrl))throw new Error("The `searchUrl` of `connectorOptions.baseUrl` are required");this.connector=e.connector||new i({baseUrl:this.searchUrl,...e.connectorOptions}),this.searchResources=e.searchResources}abort(){this._abortControllers.forEach((e=>{e.abort()})),this._abortControllers.length=0}async*search(e){var r,t;const o=this._makeSignal();for(const i of this.searchResources){if(o.aborted)break;const{searchMethod:c}=i,a=null!==(r=i.limit)&&void 0!==r?r:h.limit,l=null!==(t=i.id)&&void 0!==t?t:i.resourceId;try{const r=await this.connector.getResourceOrFail(l,{cache:!0}),t={connector:this.connector,resourceId:l,signal:o,limit:a};"like"===c?t.like=e:t.ilike=e;const n=s.fetchNgwLayerItems(t),u=await n;for(const s of this._items({entries:u,query:e,config:i,resourceItem:r}))s.result=()=>this.result(s),yield s}catch(n){n&&"name"in n&&"CancelError"!==n.name&&console.warn(n)}}}result(e){const r=this._makeSignal();return this.connector.get("feature_layer.feature.item_extent",{signal:r},{id:e.resourceId,fid:e.featureId}).then((r=>{const t=r.extent;return{text:e.text,extent:[t.minLon,t.minLat,t.maxLon,t.maxLat]}}))}_makeSignal(){const e=new AbortController;return this._abortControllers.push(e),e.signal}_items({entries:e,query:r,config:t,resourceItem:s}){var o;const n=[];let i;s.feature_layer&&(i=null===(o=s.feature_layer.fields.find((e=>e.label_field)))||void 0===o?void 0:o.keyname);const c=this.searchResources.find((e=>{var r;return null!==(r=e.id)&&void 0!==r?r:e.resourceId===s.resource.id}));return c&&e.forEach((e=>{let o=i?e.fields[i]:e.id;t.renderSearch?o=t.renderSearch({item:e,resourceItem:s}):i&&(o=e.fields[i]),n.push({query:r,text:o,featureId:e.id,resourceId:s.resource.id,item:e,resourceItem:s})})),n}}h.limit=300;exports.BaseProvider=u,exports.Geocoder=l,exports.NgwProvider=h,exports.NominatimProvider=class extends u{constructor(e){super(e),this.searchUrl="https://nominatim.openstreetmap.org",this._requests=[]}abort(){this._requests.forEach((e=>e.cancel())),this._requests=[]}async*search(e){const t=r.fixUrlStr(`${this.searchUrl}/search?format=geojson&polygon_geojson=1&q=${e}`),s=new n(((r,s,o)=>{const n=new XMLHttpRequest;n.open("GET",t,!0),n.onload=()=>{try{const t=JSON.parse(n.responseText).features.map((r=>({geom:r,extent:r.bbox,text:r.properties&&r.properties.display_name,query:e})));r(t)}catch(t){s(t)}},n.onerror=e=>{s(e)},o((()=>{n.abort()})),n.send()})).catch((e=>{throw e}));this._requests.push(s);const o=await s;if(o)for(const r of o)r.result=()=>this.result(r),yield r}result(e){return n.resolve({text:e.text,extent:e.extent||[],geom:e.geom})}},exports.create=function(e){return new l(e)};
2
2
  //# sourceMappingURL=geocoder.cjs.prod.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"geocoder.cjs.prod.js","sources":["../src/BaseGeocoder.ts","../src/Geocoder.ts","../src/providers/BaseProvider.ts","../src/providers/NgwProvider.ts","../src/providers/NominatimProvider.ts","../src/index.ts"],"sourcesContent":["import { objectAssign } from '@nextgis/utils';\nimport CancelablePromise from '@nextgis/cancelable-promise';\nimport { SearchItem } from './types/SearchItem';\n\nexport abstract class BaseGeocoder<\n O extends Record<string, any> = Record<string, any>,\n> {\n constructor(options?: O) {\n if (options) {\n objectAssign(this, options);\n }\n }\n\n abstract search(query: string): AsyncGenerator<SearchItem>;\n\n abstract result(item: SearchItem): CancelablePromise<any>;\n\n abstract abort?(): void;\n}\n","import CancelablePromise from '@nextgis/cancelable-promise';\nimport { BaseProvider } from './providers/BaseProvider';\nimport { GeocoderOptions } from './GeocoderOptions';\nimport { BaseGeocoder } from './BaseGeocoder';\nimport { SearchItem } from './types/SearchItem';\n\nlet ID = 0;\n\nexport class Geocoder extends BaseGeocoder<GeocoderOptions> {\n providers: BaseProvider[] = [];\n\n constructor(options: GeocoderOptions) {\n super(options);\n if (options && options.providers) {\n this.providers = options.providers;\n }\n }\n\n abort(): void {\n this.providers.forEach((x) => {\n if (x.abort) {\n x.abort();\n }\n });\n }\n\n async *search(query: string): AsyncGenerator<SearchItem, void, unknown> {\n for (const provider of this.providers) {\n try {\n const results = provider.search(query);\n\n for await (const r of results) {\n yield { ...r, provider, _id: ID++ };\n }\n } catch (er) {\n //\n }\n }\n }\n\n result(item: SearchItem): CancelablePromise<any> {\n if (item.provider) {\n return item.provider.result(item);\n }\n return CancelablePromise.resolve(undefined);\n }\n}\n","import { BaseProviderOptions } from './BaseProviderOptions';\nimport { BaseGeocoder } from '../BaseGeocoder';\n\nexport abstract class BaseProvider<\n O extends BaseProviderOptions = BaseProviderOptions,\n> extends BaseGeocoder<O> {\n searchUrl?: string;\n label?: string;\n}\n","import NgwConnector, { ResourceStoreItem } from '@nextgis/ngw-connector';\nimport CancelablePromise from '@nextgis/cancelable-promise';\nimport { BaseProvider } from './BaseProvider';\nimport { BaseProviderOptions } from './BaseProviderOptions';\nimport { SearchItem } from '../types/SearchItem';\nimport { ResultItem } from '../types/ResultItem';\n\ninterface NgwSearchItem extends SearchItem {\n resourceId: number;\n featureId: number;\n}\n\ninterface SearchResource {\n id: number;\n limit?: number;\n}\n\ninterface NgwProviderOptions extends BaseProviderOptions {\n connector?: NgwConnector;\n searchResources: SearchResource[];\n}\n\nexport class NgwProvider extends BaseProvider<NgwProviderOptions> {\n caseInsensitive = true;\n searchUrl = 'https://maxim.nextgis.com';\n searchResources: SearchResource[] = [];\n private connector: NgwConnector;\n private requests: CancelablePromise[] = [];\n\n constructor(options: NgwProviderOptions) {\n super(options);\n\n this.connector =\n options.connector ||\n new NgwConnector({\n baseUrl: this.searchUrl,\n });\n this.searchResources = options.searchResources;\n }\n\n abort(): void {\n this.requests.forEach((x) => {\n x.cancel();\n });\n this.requests = [];\n }\n\n async *search(like: string): AsyncGenerator<NgwSearchItem, void, unknown> {\n for (const resource of this.searchResources) {\n const limit = resource.limit || 300;\n const request = this.connector.get(\n 'feature_layer.store',\n {\n headers: { RANGE: `items=0-${limit}` },\n },\n {\n id: resource.id,\n like,\n },\n );\n this.requests.push(request);\n request.catch((er) => {\n console.warn(er);\n });\n const resp = await request;\n const entries: ResourceStoreItem[] = [];\n if (resp) {\n resp.forEach((x) => {\n entries.push({\n query: like,\n resourceId: resource.id,\n ...x,\n });\n });\n }\n for (const item of this._items(entries)) {\n item.result = () => this.result(item);\n yield item;\n }\n }\n }\n\n result(item: NgwSearchItem): CancelablePromise<ResultItem> {\n const req = this.connector\n .get('feature_layer.feature.item_extent', null, {\n id: item.resourceId,\n fid: item.featureId,\n })\n .then((x) => {\n const e = x.extent;\n return {\n text: item.text,\n extent: [e.minLon, e.minLat, e.maxLon, e.maxLat],\n };\n });\n this.requests.push(req);\n return req;\n }\n\n _items(entries: ResourceStoreItem[]): NgwSearchItem[] {\n const items: NgwSearchItem[] = [];\n entries.forEach((entry) => {\n const meta = this.searchResources.find((x) => x.id === entry.resourceId);\n if (meta) {\n items.push({\n query: entry.query,\n text: entry.label,\n featureId: entry.id,\n resourceId: entry.resourceId,\n });\n }\n });\n return items;\n }\n}\n","import { fixUrlStr } from '@nextgis/utils';\nimport CancelablePromise from '@nextgis/cancelable-promise';\nimport { BaseProvider } from './BaseProvider';\nimport { BaseProviderOptions } from './BaseProviderOptions';\nimport { FeatureCollection } from 'geojson';\nimport { SearchItem } from '../types/SearchItem';\nimport { ResultItem } from '../types/ResultItem';\n\nexport class NominatimProvider extends BaseProvider {\n searchUrl = 'https://nominatim.openstreetmap.org';\n\n private _requests: CancelablePromise[] = [];\n\n constructor(options?: BaseProviderOptions) {\n super(options);\n }\n\n abort(): void {\n this._requests.forEach((x) => x.cancel());\n this._requests = [];\n }\n\n async *search(val: string): AsyncGenerator<SearchItem, void, unknown> {\n // RFC2616 accept - language string\n const url = fixUrlStr(\n // `${this.baseUrl}/search?format=geojson&polygon_geojson=1${window.locale === 'ru' ? '&accept-language=ru-RU,en-US' : ''}&q=${val}`\n `${this.searchUrl}/search?format=geojson&polygon_geojson=1&q=${val}`,\n );\n const request = new CancelablePromise<SearchItem[]>(\n (resolve, reject, onCancel) => {\n const xhr = new XMLHttpRequest();\n xhr.open('GET', url, true);\n xhr.onload = () => {\n try {\n const geojson = JSON.parse(xhr.responseText) as FeatureCollection;\n const features: SearchItem[] = geojson.features.map((x) => {\n return {\n geom: x,\n extent: x.bbox,\n text: x.properties && x.properties.display_name,\n query: val,\n };\n });\n resolve(features);\n } catch (er) {\n reject(er);\n }\n };\n\n xhr.onerror = (er) => {\n reject(er);\n };\n\n onCancel(() => {\n xhr.abort();\n });\n\n xhr.send();\n },\n ).catch((er) => {\n if (er.name === 'CancelError') {\n //\n }\n throw er;\n });\n this._requests.push(request);\n const items = await request;\n if (items) {\n for (const i of items) {\n i.result = () => this.result(i);\n yield i;\n }\n }\n }\n\n result(model: SearchItem): CancelablePromise<ResultItem> {\n return CancelablePromise.resolve({\n text: model.text,\n extent: model.extent || [],\n geom: model.geom,\n });\n }\n}\n","/**\n * Modern geocoder on async generators. May use different data providers.\n *\n * @packageDocumentation\n * @module geocoder\n */\nimport { GeocoderOptions } from './GeocoderOptions';\nimport { Geocoder } from './Geocoder';\n\nexport { Geocoder, GeocoderOptions };\nexport { BaseProvider } from './providers/BaseProvider';\nexport { NgwProvider } from './providers/NgwProvider';\nexport { NominatimProvider } from './providers/NominatimProvider';\n\nexport * from './providers/BaseProviderOptions';\nexport * from './types/ResultItem';\nexport * from './types/SearchItem';\n\nexport function create(options: GeocoderOptions): Geocoder {\n return new Geocoder(options);\n}\n"],"names":["BaseGeocoder","constructor","options","objectAssign","this","ID","Geocoder","super","providers","abort","forEach","x","search","query","provider","results","r","_id","er","result","item","CancelablePromise","resolve","undefined","BaseProvider","caseInsensitive","searchUrl","searchResources","requests","connector","NgwConnector","baseUrl","cancel","like","resource","request","get","headers","RANGE","limit","id","push","catch","console","warn","resp","entries","resourceId","_items","req","fid","featureId","then","e","extent","text","minLon","minLat","maxLon","maxLat","items","entry","find","label","_requests","val","url","fixUrlStr","reject","onCancel","xhr","XMLHttpRequest","open","onload","features","JSON","parse","responseText","map","geom","bbox","properties","display_name","onerror","send","i","model"],"mappings":"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"}
1
+ {"version":3,"file":"geocoder.cjs.prod.js","sources":["../src/BaseGeocoder.ts","../src/Geocoder.ts","../src/providers/BaseProvider.ts","../src/providers/NgwProvider.ts","../src/providers/NominatimProvider.ts","../src/index.ts"],"sourcesContent":["import { objectAssign } from '@nextgis/utils';\nimport type CancelablePromise from '@nextgis/cancelable-promise';\nimport type { SearchItem } from './types/SearchItem';\n\n/**\n * Represents the base class for a geocoder.\n * This abstract class provides the basic methods that every geocoder should implement.\n *\n * @template O - The type of options that can be passed to the geocoder.\n */\nexport abstract class BaseGeocoder<\n O extends Record<string, any> = Record<string, any>,\n> {\n constructor(options?: O) {\n if (options) {\n objectAssign(this, options);\n }\n }\n\n /**\n * Search method to retrieve geocoding results.\n *\n * @abstract\n * @param {string} query - The search string to geocode.\n * @yields {AsyncGenerator<SearchItem>} - An async generator that yields search results.\n */\n abstract search(query: string): AsyncGenerator<SearchItem>;\n\n /**\n * Method to retrieve detailed result for a specific search item.\n *\n * @abstract\n * @param {SearchItem} item - The search item to get detailed result for.\n * @returns {CancelablePromise<any>} - A promise that resolves to the detailed result.\n */\n abstract result(item: SearchItem): CancelablePromise<any>;\n\n /**\n * Optional method to abort any ongoing geocoding requests.\n *\n * @abstract\n */\n abstract abort?(): void;\n}\n","import CancelablePromise from '@nextgis/cancelable-promise';\nimport { BaseProvider } from './providers/BaseProvider';\nimport { GeocoderOptions } from './GeocoderOptions';\nimport { BaseGeocoder } from './BaseGeocoder';\nimport { SearchItem } from './types/SearchItem';\n\nlet ID = 0;\n\nexport class Geocoder extends BaseGeocoder<GeocoderOptions> {\n providers: BaseProvider[] = [];\n\n constructor(options: GeocoderOptions) {\n super(options);\n if (options && options.providers) {\n this.providers = options.providers;\n }\n }\n\n abort(): void {\n this.providers.forEach((x) => {\n if (x.abort) {\n x.abort();\n }\n });\n }\n\n async *search(query: string): AsyncGenerator<SearchItem, void, unknown> {\n for (const provider of this.providers) {\n try {\n const results = provider.search(query);\n\n for await (const r of results) {\n yield { ...r, provider, _id: ID++ };\n }\n } catch (er) {\n //\n }\n }\n }\n\n result(item: SearchItem): CancelablePromise<any> {\n if (item.provider) {\n return item.provider.result(item);\n }\n return CancelablePromise.resolve(undefined);\n }\n}\n","import { BaseProviderOptions } from './BaseProviderOptions';\nimport { BaseGeocoder } from '../BaseGeocoder';\n\n/**\n * Abstract base class representing a search provider.\n * It builds upon the BaseGeocoder functionalities with provider-specific properties.\n * @template O - Options type which extends BaseProviderOptions.\n */\nexport abstract class BaseProvider<\n O extends BaseProviderOptions = BaseProviderOptions,\n> extends BaseGeocoder<O> {\n /**\n * URL endpoint for the search service.\n * This is where queries will be sent to obtain search results.\n */\n searchUrl?: string;\n\n /**\n * Label to represent the provider.\n * Useful for user interfaces to display the source of search results.\n */\n label?: string;\n}\n","import NgwConnector from '@nextgis/ngw-connector';\nimport { fetchNgwLayerItems } from '@nextgis/ngw-kit';\n\nimport { BaseProvider } from './BaseProvider';\n\nimport type CancelablePromise from '@nextgis/cancelable-promise';\nimport type {\n FeatureItem,\n NgwConnectorOptions,\n ResourceItem,\n} from '@nextgis/ngw-connector';\nimport type { FetchNgwItemsOptions } from '@nextgis/ngw-kit';\n\nimport type { ResultItem } from '../types/ResultItem';\nimport type { SearchItem } from '../types/SearchItem';\nimport type { BaseProviderOptions } from './BaseProviderOptions';\n\n/**\n * Extends the basic search item with NGW-specific properties.\n */\ninterface NgwSearchItem extends SearchItem {\n /** ID of the NGW resource */\n resourceId: number;\n /** ID of the feature in the NGW resource */\n featureId: number;\n /** The specific feature item from NGW */\n item: FeatureItem;\n /** The NGW resource item */\n resourceItem: ResourceItem;\n}\n\n/**\n * Defines the structure for a rendered search item.\n */\ninterface RenderSearchItem {\n /** The specific feature item */\n item: FeatureItem;\n /** The NGW resource item */\n resourceItem: ResourceItem;\n}\n\n/**\n * Options for searching within a NGW resource.\n */\ninterface SearchResource extends FetchNgwItemsOptions {\n /** The search method used ('ilike' is case-insensitive) */\n searchMethod?: 'ilike' | 'like';\n /** Custom rendering function for search results */\n renderSearch?: (item: RenderSearchItem) => string | HTMLElement;\n}\n\n/**\n * Options required to initialize an NGW provider.\n */\ninterface NgwProviderOptions extends BaseProviderOptions {\n /** Connector instance for NGW. If not provided, will be created internally */\n connector?: NgwConnector;\n /** List of NGW resources to search within */\n searchResources: SearchResource[];\n /** Options for the internal NgwConnector (if one needs to be created) */\n connectorOptions?: NgwConnectorOptions;\n}\n\nexport class NgwProvider extends BaseProvider<NgwProviderOptions> {\n static limit = 300;\n\n searchResources: SearchResource[] = [];\n\n private connector: NgwConnector;\n private _abortControllers: AbortController[] = [];\n\n constructor(options: NgwProviderOptions) {\n super(options);\n if (!options.searchUrl && !options.connectorOptions?.baseUrl) {\n throw new Error(\n 'The `searchUrl` of `connectorOptions.baseUrl` are required',\n );\n }\n\n this.connector =\n options.connector ||\n new NgwConnector({\n baseUrl: this.searchUrl,\n ...options.connectorOptions,\n });\n this.searchResources = options.searchResources;\n }\n\n abort(): void {\n this._abortControllers.forEach((a) => {\n a.abort();\n });\n this._abortControllers.length = 0;\n }\n\n async *search(query: string): AsyncGenerator<NgwSearchItem, void, unknown> {\n const signal = this._makeSignal();\n for (const config of this.searchResources) {\n if (signal.aborted) {\n break;\n }\n const { searchMethod } = config;\n\n const limit = config.limit ?? NgwProvider.limit;\n //\n const resourceId = (config as any).id ?? config.resourceId;\n\n try {\n const resource = await this.connector.getResourceOrFail(resourceId, {\n cache: true,\n });\n\n const options: FetchNgwItemsOptions = {\n connector: this.connector,\n resourceId,\n signal,\n limit,\n };\n\n if (searchMethod === 'like') {\n options.like = query;\n } else {\n options.ilike = query;\n }\n\n const request = fetchNgwLayerItems(options);\n\n const entries = await request;\n\n for (const item of this._items({\n entries,\n query,\n config,\n resourceItem: resource,\n })) {\n item.result = () => this.result(item);\n yield item;\n }\n } catch (er) {\n if (\n er &&\n 'name' in (er as Error) &&\n (er as Error).name !== 'CancelError'\n ) {\n console.warn(er);\n }\n }\n }\n }\n\n result(item: NgwSearchItem): CancelablePromise<ResultItem> {\n const signal = this._makeSignal();\n const req = this.connector\n .get(\n 'feature_layer.feature.item_extent',\n { signal },\n {\n id: item.resourceId,\n fid: item.featureId,\n },\n )\n .then((x) => {\n const e = x.extent;\n return {\n text: item.text,\n extent: [e.minLon, e.minLat, e.maxLon, e.maxLat],\n };\n });\n return req;\n }\n\n private _makeSignal() {\n const abortController = new AbortController();\n this._abortControllers.push(abortController);\n return abortController.signal;\n }\n\n private _items({\n entries,\n query,\n config,\n resourceItem,\n }: {\n config: SearchResource;\n entries: FeatureItem[];\n query: string;\n resourceItem: ResourceItem;\n }): NgwSearchItem[] {\n const items: NgwSearchItem[] = [];\n\n let labelField: string | undefined = undefined;\n\n if (resourceItem.feature_layer) {\n labelField = resourceItem.feature_layer.fields.find(\n (f) => f.label_field,\n )?.keyname;\n }\n\n const meta = this.searchResources.find(\n (x) => (x as any).id ?? x.resourceId === resourceItem.resource.id,\n );\n if (meta) {\n entries.forEach((entry) => {\n let text = labelField ? entry.fields[labelField] : entry.id;\n if (config.renderSearch) {\n text = config.renderSearch({\n item: entry,\n resourceItem,\n });\n } else if (labelField) {\n text = entry.fields[labelField];\n }\n\n items.push({\n query: query,\n text,\n featureId: entry.id,\n resourceId: resourceItem.resource.id,\n item: entry,\n resourceItem,\n });\n });\n }\n return items;\n }\n}\n","import { fixUrlStr } from '@nextgis/utils';\nimport CancelablePromise from '@nextgis/cancelable-promise';\nimport { BaseProvider } from './BaseProvider';\nimport { BaseProviderOptions } from './BaseProviderOptions';\nimport { FeatureCollection } from 'geojson';\nimport { SearchItem } from '../types/SearchItem';\nimport { ResultItem } from '../types/ResultItem';\n\nexport class NominatimProvider extends BaseProvider {\n searchUrl = 'https://nominatim.openstreetmap.org';\n\n private _requests: CancelablePromise[] = [];\n\n constructor(options?: BaseProviderOptions) {\n super(options);\n }\n\n abort(): void {\n this._requests.forEach((x) => x.cancel());\n this._requests = [];\n }\n\n async *search(val: string): AsyncGenerator<SearchItem, void, unknown> {\n // RFC2616 accept - language string\n const url = fixUrlStr(\n // `${this.baseUrl}/search?format=geojson&polygon_geojson=1${window.locale === 'ru' ? '&accept-language=ru-RU,en-US' : ''}&q=${val}`\n `${this.searchUrl}/search?format=geojson&polygon_geojson=1&q=${val}`,\n );\n const request = new CancelablePromise<SearchItem[]>(\n (resolve, reject, onCancel) => {\n const xhr = new XMLHttpRequest();\n xhr.open('GET', url, true);\n xhr.onload = () => {\n try {\n const geojson = JSON.parse(xhr.responseText) as FeatureCollection;\n const features: SearchItem[] = geojson.features.map((x) => {\n return {\n geom: x,\n extent: x.bbox,\n text: x.properties && x.properties.display_name,\n query: val,\n };\n });\n resolve(features);\n } catch (er) {\n reject(er);\n }\n };\n\n xhr.onerror = (er) => {\n reject(er);\n };\n\n onCancel(() => {\n xhr.abort();\n });\n\n xhr.send();\n },\n ).catch((er) => {\n if (er.name === 'CancelError') {\n //\n }\n throw er;\n });\n this._requests.push(request);\n const items = await request;\n if (items) {\n for (const i of items) {\n i.result = () => this.result(i);\n yield i;\n }\n }\n }\n\n result(model: SearchItem): CancelablePromise<ResultItem> {\n return CancelablePromise.resolve({\n text: model.text,\n extent: model.extent || [],\n geom: model.geom,\n });\n }\n}\n","/**\n * Modern geocoder on async generators. May use different data providers.\n *\n * @packageDocumentation\n * @module geocoder\n */\nimport { Geocoder } from './Geocoder';\nimport type { GeocoderOptions } from './GeocoderOptions';\n\nexport { Geocoder, GeocoderOptions };\nexport { BaseProvider } from './providers/BaseProvider';\nexport { NgwProvider } from './providers/NgwProvider';\nexport { NominatimProvider } from './providers/NominatimProvider';\n\nexport * from './providers/BaseProviderOptions';\nexport * from './types/ResultItem';\nexport * from './types/SearchItem';\n\nexport function create(options: GeocoderOptions): Geocoder {\n return new Geocoder(options);\n}\n"],"names":["BaseGeocoder","constructor","options","objectAssign","this","ID","Geocoder","super","providers","abort","forEach","x","search","query","provider","results","r","_id","er","result","item","CancelablePromise","resolve","undefined","BaseProvider","NgwProvider","searchResources","_abortControllers","searchUrl","_a","connectorOptions","baseUrl","Error","connector","NgwConnector","a","length","signal","_makeSignal","config","aborted","searchMethod","limit","resourceId","_b","id","resource","getResourceOrFail","cache","like","ilike","request","fetchNgwLayerItems","entries","_items","resourceItem","name","console","warn","get","fid","featureId","then","e","extent","text","minLon","minLat","maxLon","maxLat","abortController","AbortController","push","items","labelField","feature_layer","fields","find","f","label_field","keyname","meta","entry","renderSearch","_requests","cancel","val","url","fixUrlStr","reject","onCancel","xhr","XMLHttpRequest","open","onload","features","JSON","parse","responseText","map","geom","bbox","properties","display_name","onerror","send","catch","i","model"],"mappings":"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"}