@nextgis/geocoder 1.19.2 → 2.0.0-alpha.1

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.
@@ -1,4 +1,4 @@
1
- /** Bundle of @nextgis/geocoder; version: 1.19.2; author: NextGIS */
1
+ /** Bundle of @nextgis/geocoder; version: 2.0.0-alpha.1; author: NextGIS */
2
2
  'use strict';
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
@@ -8,362 +8,389 @@ var utils = require('@nextgis/utils');
8
8
  var NgwConnector = require('@nextgis/ngw-connector');
9
9
  var ngwKit = require('@nextgis/ngw-kit');
10
10
 
11
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
12
-
13
- var CancelablePromise__default = /*#__PURE__*/_interopDefaultLegacy(CancelablePromise);
14
- var NgwConnector__default = /*#__PURE__*/_interopDefaultLegacy(NgwConnector);
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
- */
22
11
  class BaseGeocoder {
23
- constructor(options) {
24
- if (options) {
25
- utils.objectAssign(this, options);
26
- }
12
+ constructor(options) {
13
+ if (options) {
14
+ utils.objectAssign(this, options);
27
15
  }
16
+ }
28
17
  }
29
18
 
19
+ var __defProp$3 = Object.defineProperty;
20
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
21
+ var __publicField$3 = (obj, key, value) => {
22
+ __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
23
+ return value;
24
+ };
30
25
  let ID = 0;
31
26
  class Geocoder extends BaseGeocoder {
32
- constructor(options) {
33
- super(options);
34
- this.providers = [];
35
- if (options && options.providers) {
36
- this.providers = options.providers;
37
- }
27
+ constructor(options) {
28
+ super(options);
29
+ __publicField$3(this, "providers", []);
30
+ if (options && options.providers) {
31
+ this.providers = options.providers;
38
32
  }
39
- abort() {
40
- this.providers.forEach((x) => {
41
- if (x.abort) {
42
- x.abort();
43
- }
44
- });
45
- }
46
- async *search(query) {
47
- this.abort();
48
- let allProvidersFailed = true;
49
- const errors = [];
50
- for (const provider of this.providers) {
51
- try {
52
- const results = provider.search(query);
53
- for await (const r of results) {
54
- allProvidersFailed = false;
55
- yield { ...r, provider, _id: ID++ };
56
- }
57
- }
58
- catch (err) {
59
- const er = err;
60
- if (er.name !== 'CancelError') {
61
- errors.push(er);
62
- }
63
- }
33
+ }
34
+ abort() {
35
+ this.providers.forEach((x) => {
36
+ if (x.abort) {
37
+ x.abort();
38
+ }
39
+ });
40
+ }
41
+ async *search(query) {
42
+ this.abort();
43
+ let allProvidersFailed = true;
44
+ const errors = [];
45
+ for (const provider of this.providers) {
46
+ try {
47
+ const results = provider.search(query);
48
+ for await (const r of results) {
49
+ allProvidersFailed = false;
50
+ yield { ...r, provider, _id: ID++ };
64
51
  }
65
- if (allProvidersFailed && errors.length) {
66
- throw new Error(`All providers failed: ${errors.map((e) => e.message).join('; ')}`);
52
+ } catch (err) {
53
+ const er = err;
54
+ if (er.name !== "CancelError") {
55
+ errors.push(er);
67
56
  }
57
+ }
68
58
  }
69
- result(item) {
70
- if (item.provider) {
71
- return item.provider.result(item);
72
- }
73
- return CancelablePromise__default.resolve(undefined);
59
+ if (allProvidersFailed && errors.length) {
60
+ throw new Error(
61
+ `All providers failed: ${errors.map((e) => e.message).join("; ")}`
62
+ );
74
63
  }
75
- async *reverse(coordinates) {
76
- for (const provider of this.providers) {
77
- if (!provider.reverse) {
78
- continue;
79
- }
80
- try {
81
- const results = provider.reverse(coordinates);
82
- for await (const r of results) {
83
- yield { ...r, provider, _id: ID++ };
84
- }
85
- }
86
- catch (er) {
87
- // Handle or log errors as needed
88
- }
64
+ }
65
+ result(item) {
66
+ if (item.provider) {
67
+ return item.provider.result(item);
68
+ }
69
+ return CancelablePromise.resolve(void 0);
70
+ }
71
+ async *reverse(coordinates) {
72
+ for (const provider of this.providers) {
73
+ if (!provider.reverse) {
74
+ continue;
75
+ }
76
+ try {
77
+ const results = provider.reverse(coordinates);
78
+ for await (const r of results) {
79
+ yield { ...r, provider, _id: ID++ };
89
80
  }
81
+ } catch (er) {
82
+ }
90
83
  }
91
- /**
92
- * Returns the first reverse geocoding result for given coordinates from any provider.
93
- *
94
- * @param coordinates - The longitude and latitude values.
95
- * @returns A promise that resolves to the first reverse geocoding result, or undefined if no results are found.
96
- */
97
- async reverseGeocodeFirstResult(coordinates) {
98
- for (const provider of this.providers) {
99
- if (typeof provider.reverse === 'function') {
100
- try {
101
- for await (const result of provider.reverse(coordinates)) {
102
- return result;
103
- }
104
- }
105
- catch (error) {
106
- console.error('Error in reverse geocoding:', error);
107
- }
108
- }
84
+ }
85
+ /**
86
+ * Returns the first reverse geocoding result for given coordinates from any provider.
87
+ *
88
+ * @param coordinates - The longitude and latitude values.
89
+ * @returns A promise that resolves to the first reverse geocoding result, or undefined if no results are found.
90
+ */
91
+ async reverseGeocodeFirstResult(coordinates) {
92
+ for (const provider of this.providers) {
93
+ if (typeof provider.reverse === "function") {
94
+ try {
95
+ for await (const result of provider.reverse(coordinates)) {
96
+ return result;
97
+ }
98
+ } catch (error) {
99
+ console.error("Error in reverse geocoding:", error);
109
100
  }
110
- return undefined;
101
+ }
111
102
  }
103
+ return void 0;
104
+ }
112
105
  }
113
106
 
114
- /**
115
- * Abstract base class representing a search provider.
116
- * It builds upon the BaseGeocoder functionalities with provider-specific properties.
117
- * @template O - Options type which extends BaseProviderOptions.
118
- */
107
+ var __defProp$2 = Object.defineProperty;
108
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
109
+ var __publicField$2 = (obj, key, value) => {
110
+ __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
111
+ return value;
112
+ };
119
113
  class BaseProvider extends BaseGeocoder {
114
+ constructor() {
115
+ super(...arguments);
116
+ /**
117
+ * URL endpoint for the search service.
118
+ * This is where queries will be sent to obtain search results.
119
+ */
120
+ __publicField$2(this, "searchUrl");
121
+ /**
122
+ * Label to represent the provider.
123
+ * Useful for user interfaces to display the source of search results.
124
+ */
125
+ __publicField$2(this, "label");
126
+ }
120
127
  }
121
128
 
122
- class NgwProvider extends BaseProvider {
123
- constructor(options) {
124
- var _a;
125
- super(options);
126
- this.searchResources = [];
127
- this._abortControllers = [];
128
- if (!options.searchUrl && !((_a = options.connectorOptions) === null || _a === void 0 ? void 0 : _a.baseUrl)) {
129
- throw new Error('The `searchUrl` of `connectorOptions.baseUrl` are required');
130
- }
131
- this.connector =
132
- options.connector ||
133
- new NgwConnector__default({
134
- baseUrl: this.searchUrl,
135
- ...options.connectorOptions,
136
- });
137
- this.searchResources = options.searchResources;
129
+ var __defProp$1 = Object.defineProperty;
130
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
131
+ var __publicField$1 = (obj, key, value) => {
132
+ __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
133
+ return value;
134
+ };
135
+ const _NgwProvider = class _NgwProvider extends BaseProvider {
136
+ constructor(options) {
137
+ var _a;
138
+ super(options);
139
+ __publicField$1(this, "searchResources", []);
140
+ __publicField$1(this, "connector");
141
+ __publicField$1(this, "_abortControllers", []);
142
+ if (!options.searchUrl && !((_a = options.connectorOptions) == null ? void 0 : _a.baseUrl)) {
143
+ throw new Error(
144
+ "The `searchUrl` of `connectorOptions.baseUrl` are required"
145
+ );
138
146
  }
139
- abort() {
140
- this._abortControllers.forEach((a) => {
141
- a.abort();
147
+ this.connector = options.connector || new NgwConnector({
148
+ baseUrl: this.searchUrl,
149
+ ...options.connectorOptions
150
+ });
151
+ this.searchResources = options.searchResources;
152
+ }
153
+ abort() {
154
+ this._abortControllers.forEach((a) => {
155
+ a.abort();
156
+ });
157
+ this._abortControllers.length = 0;
158
+ }
159
+ async *search(query) {
160
+ var _a, _b;
161
+ const signal = this._makeSignal();
162
+ for (const config of this.searchResources) {
163
+ if (signal.aborted) {
164
+ break;
165
+ }
166
+ const { searchMethod } = config;
167
+ const limit = (_a = config.limit) != null ? _a : _NgwProvider.limit;
168
+ const resourceId = (_b = config.id) != null ? _b : config.resourceId;
169
+ try {
170
+ const resource = await this.connector.getResourceOrFail(resourceId, {
171
+ cache: true
142
172
  });
143
- this._abortControllers.length = 0;
144
- }
145
- async *search(query) {
146
- var _a, _b;
147
- const signal = this._makeSignal();
148
- for (const config of this.searchResources) {
149
- if (signal.aborted) {
150
- break;
151
- }
152
- const { searchMethod } = config;
153
- const limit = (_a = config.limit) !== null && _a !== void 0 ? _a : NgwProvider.limit;
154
- //
155
- const resourceId = (_b = config.id) !== null && _b !== void 0 ? _b : config.resourceId;
156
- try {
157
- const resource = await this.connector.getResourceOrFail(resourceId, {
158
- cache: true,
159
- });
160
- const options = {
161
- connector: this.connector,
162
- resourceId,
163
- signal,
164
- limit,
165
- };
166
- if (searchMethod === 'like') {
167
- options.like = query;
168
- }
169
- else {
170
- options.ilike = query;
171
- }
172
- const request = ngwKit.fetchNgwLayerItems(options);
173
- const entries = await request;
174
- for (const item of this._items({
175
- entries,
176
- query,
177
- config,
178
- resourceItem: resource,
179
- })) {
180
- item.result = () => this.result(item);
181
- yield item;
182
- }
183
- }
184
- catch (er) {
185
- if (er &&
186
- 'name' in er &&
187
- er.name !== 'CancelError') {
188
- console.warn(er);
189
- }
190
- }
173
+ const options = {
174
+ connector: this.connector,
175
+ resourceId,
176
+ signal,
177
+ limit
178
+ };
179
+ if (searchMethod === "like") {
180
+ options.like = query;
181
+ } else {
182
+ options.ilike = query;
191
183
  }
184
+ const request = ngwKit.fetchNgwLayerItems(options);
185
+ const entries = await request;
186
+ for (const item of this._items({
187
+ entries,
188
+ query,
189
+ config,
190
+ resourceItem: resource
191
+ })) {
192
+ item.result = () => this.result(item);
193
+ yield item;
194
+ }
195
+ } catch (er) {
196
+ if (er && "name" in er && er.name !== "CancelError") {
197
+ console.warn(er);
198
+ }
199
+ }
192
200
  }
193
- result(item) {
194
- const signal = this._makeSignal();
195
- const req = this.connector
196
- .get('feature_layer.feature.item_extent', { signal }, {
197
- id: item.resourceId,
198
- fid: item.featureId,
199
- })
200
- .then((x) => {
201
- const e = x.extent;
202
- return {
203
- text: item.text,
204
- extent: [e.minLon, e.minLat, e.maxLon, e.maxLat],
205
- };
206
- });
207
- return req;
208
- }
209
- async *reverse(coordinates) {
210
- throw new Error('Not implemented');
211
- }
212
- _makeSignal() {
213
- const abortController = new AbortController();
214
- this._abortControllers.push(abortController);
215
- return abortController.signal;
201
+ }
202
+ result(item) {
203
+ const signal = this._makeSignal();
204
+ const req = this.connector.get(
205
+ "feature_layer.feature.item_extent",
206
+ { signal },
207
+ {
208
+ id: item.resourceId,
209
+ fid: item.featureId
210
+ }
211
+ ).then((x) => {
212
+ const e = x.extent;
213
+ return {
214
+ text: item.text,
215
+ extent: [e.minLon, e.minLat, e.maxLon, e.maxLat]
216
+ };
217
+ });
218
+ return req;
219
+ }
220
+ async *reverse(coordinates) {
221
+ throw new Error("Not implemented");
222
+ }
223
+ _makeSignal() {
224
+ const abortController = new AbortController();
225
+ this._abortControllers.push(abortController);
226
+ return abortController.signal;
227
+ }
228
+ _items({
229
+ entries,
230
+ query,
231
+ config,
232
+ resourceItem
233
+ }) {
234
+ var _a;
235
+ const items = [];
236
+ let labelField = void 0;
237
+ if (resourceItem.feature_layer) {
238
+ labelField = (_a = resourceItem.feature_layer.fields.find(
239
+ (f) => f.label_field
240
+ )) == null ? void 0 : _a.keyname;
216
241
  }
217
- _items({ entries, query, config, resourceItem, }) {
218
- var _a;
219
- const items = [];
220
- let labelField = undefined;
221
- if (resourceItem.feature_layer) {
222
- labelField = (_a = resourceItem.feature_layer.fields.find((f) => f.label_field)) === null || _a === void 0 ? void 0 : _a.keyname;
242
+ const meta = this.searchResources.find(
243
+ (x) => {
244
+ var _a2;
245
+ return (_a2 = x.id) != null ? _a2 : x.resourceId === resourceItem.resource.id;
246
+ }
247
+ );
248
+ if (meta) {
249
+ entries.forEach((entry) => {
250
+ let text = labelField ? entry.fields[labelField] : entry.id;
251
+ if (config.renderSearch) {
252
+ text = config.renderSearch({
253
+ item: entry,
254
+ resourceItem
255
+ });
256
+ } else if (labelField) {
257
+ text = entry.fields[labelField];
223
258
  }
224
- const meta = this.searchResources.find((x) => { var _a; return (_a = x.id) !== null && _a !== void 0 ? _a : x.resourceId === resourceItem.resource.id; });
225
- if (meta) {
226
- entries.forEach((entry) => {
227
- let text = labelField ? entry.fields[labelField] : entry.id;
228
- if (config.renderSearch) {
229
- text = config.renderSearch({
230
- item: entry,
231
- resourceItem,
232
- });
233
- }
234
- else if (labelField) {
235
- text = entry.fields[labelField];
236
- }
237
- items.push({
238
- query: query,
239
- text,
240
- featureId: entry.id,
241
- resourceId: resourceItem.resource.id,
242
- item: entry,
243
- resourceItem,
244
- });
245
- });
246
- }
247
- return items;
259
+ items.push({
260
+ query,
261
+ text,
262
+ featureId: entry.id,
263
+ resourceId: resourceItem.resource.id,
264
+ item: entry,
265
+ resourceItem
266
+ });
267
+ });
248
268
  }
249
- }
250
- NgwProvider.limit = 300;
269
+ return items;
270
+ }
271
+ };
272
+ __publicField$1(_NgwProvider, "limit", 300);
273
+ let NgwProvider = _NgwProvider;
251
274
 
275
+ var __defProp = Object.defineProperty;
276
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
277
+ var __publicField = (obj, key, value) => {
278
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
279
+ return value;
280
+ };
252
281
  class NominatimProvider extends BaseProvider {
253
- constructor(options) {
254
- super(options);
255
- this.searchUrl = 'https://nominatim.openstreetmap.org';
256
- this._requests = [];
257
- if (options && options.searchUrl) {
258
- this.searchUrl = options.searchUrl;
259
- }
282
+ constructor(options) {
283
+ super(options);
284
+ __publicField(this, "searchUrl", "https://nominatim.openstreetmap.org");
285
+ __publicField(this, "_requests", []);
286
+ if (options && options.searchUrl) {
287
+ this.searchUrl = options.searchUrl;
260
288
  }
261
- abort() {
262
- this._requests.forEach((x) => x.cancel());
263
- this._requests = [];
264
- }
265
- async *search(val) {
266
- // RFC2616 accept - language string
267
- const url = utils.fixUrlStr(
268
- // `${this.baseUrl}/search?format=geojson&polygon_geojson=1${window.locale === 'ru' ? '&accept-language=ru-RU,en-US' : ''}&q=${val}`
269
- `${this.searchUrl}/search?format=geojson&polygon_geojson=1&q=${val}`);
270
- const request = new CancelablePromise__default((resolve, reject, onCancel) => {
271
- const xhr = new XMLHttpRequest();
272
- xhr.open('GET', url, true);
273
- xhr.onload = () => {
274
- try {
275
- const geojson = JSON.parse(xhr.responseText);
276
- const features = geojson.features.map((x) => {
277
- return {
278
- geom: x,
279
- extent: x.bbox,
280
- text: x.properties && x.properties.display_name,
281
- query: val,
282
- };
283
- });
284
- resolve(features);
285
- }
286
- catch (er) {
287
- reject(er);
288
- }
289
- };
290
- xhr.onerror = (er) => {
291
- reject(er);
292
- };
293
- onCancel(() => {
294
- xhr.abort();
289
+ }
290
+ abort() {
291
+ this._requests.forEach((x) => x.cancel());
292
+ this._requests = [];
293
+ }
294
+ async *search(val) {
295
+ const url = utils.fixUrlStr(
296
+ // `${this.baseUrl}/search?format=geojson&polygon_geojson=1${window.locale === 'ru' ? '&accept-language=ru-RU,en-US' : ''}&q=${val}`
297
+ `${this.searchUrl}/search?format=geojson&polygon_geojson=1&q=${val}`
298
+ );
299
+ const request = new CancelablePromise(
300
+ (resolve, reject, onCancel) => {
301
+ const xhr = new XMLHttpRequest();
302
+ xhr.open("GET", url, true);
303
+ xhr.onload = () => {
304
+ try {
305
+ const geojson = JSON.parse(xhr.responseText);
306
+ const features = geojson.features.map((x) => {
307
+ return {
308
+ geom: x,
309
+ extent: x.bbox,
310
+ text: x.properties && x.properties.display_name,
311
+ query: val
312
+ };
295
313
  });
296
- xhr.send();
297
- }).catch((er) => {
298
- if (er.name === 'CancelError') ;
299
- throw er;
314
+ resolve(features);
315
+ } catch (er) {
316
+ reject(er);
317
+ }
318
+ };
319
+ xhr.onerror = (er) => {
320
+ reject(er);
321
+ };
322
+ onCancel(() => {
323
+ xhr.abort();
300
324
  });
301
- this._requests.push(request);
302
- const items = await request;
303
- if (items) {
304
- for (const i of items) {
305
- i.result = () => this.result(i);
306
- yield i;
307
- }
308
- }
325
+ xhr.send();
326
+ }
327
+ ).catch((er) => {
328
+ if (er.name === "CancelError") ;
329
+ throw er;
330
+ });
331
+ this._requests.push(request);
332
+ const items = await request;
333
+ if (items) {
334
+ for (const i of items) {
335
+ i.result = () => this.result(i);
336
+ yield i;
337
+ }
309
338
  }
310
- result(model) {
311
- return CancelablePromise__default.resolve({
312
- text: model.text,
313
- extent: model.extent || [],
314
- geom: model.geom,
315
- });
316
- }
317
- async *reverse(coordinates) {
318
- const [lng, lat] = coordinates;
319
- const url = utils.fixUrlStr(`${this.searchUrl}/reverse?format=geojson&lat=${lat}&lon=${lng}`);
320
- const request = new CancelablePromise__default((resolve, reject, onCancel) => {
321
- const xhr = new XMLHttpRequest();
322
- xhr.open('GET', url, true);
323
- xhr.onload = () => {
324
- try {
325
- const geojson = JSON.parse(xhr.responseText);
326
- const feature = geojson.features[0];
327
- const result = {
328
- geom: feature,
329
- extent: feature.bbox,
330
- text: feature.properties && feature.properties.display_name,
331
- query: `${lat}, ${lng}`,
332
- };
333
- resolve(result);
334
- }
335
- catch (er) {
336
- reject(er);
337
- }
338
- };
339
- xhr.onerror = (er) => {
340
- reject(er);
339
+ }
340
+ result(model) {
341
+ return CancelablePromise.resolve({
342
+ text: model.text,
343
+ extent: model.extent || [],
344
+ geom: model.geom
345
+ });
346
+ }
347
+ async *reverse(coordinates) {
348
+ const [lng, lat] = coordinates;
349
+ const url = utils.fixUrlStr(
350
+ `${this.searchUrl}/reverse?format=geojson&lat=${lat}&lon=${lng}`
351
+ );
352
+ const request = new CancelablePromise(
353
+ (resolve, reject, onCancel) => {
354
+ const xhr = new XMLHttpRequest();
355
+ xhr.open("GET", url, true);
356
+ xhr.onload = () => {
357
+ try {
358
+ const geojson = JSON.parse(xhr.responseText);
359
+ const feature = geojson.features[0];
360
+ const result = {
361
+ geom: feature,
362
+ extent: feature.bbox,
363
+ text: feature.properties && feature.properties.display_name,
364
+ query: `${lat}, ${lng}`
341
365
  };
342
- onCancel(() => {
343
- xhr.abort();
344
- });
345
- xhr.send();
346
- }).catch((er) => {
347
- if (er.name === 'CancelError') ;
348
- throw er;
366
+ resolve(result);
367
+ } catch (er) {
368
+ reject(er);
369
+ }
370
+ };
371
+ xhr.onerror = (er) => {
372
+ reject(er);
373
+ };
374
+ onCancel(() => {
375
+ xhr.abort();
349
376
  });
350
- this._requests.push(request);
351
- const item = await request;
352
- if (item) {
353
- item.result = () => this.result(item);
354
- yield item;
355
- }
377
+ xhr.send();
378
+ }
379
+ ).catch((er) => {
380
+ if (er.name === "CancelError") ;
381
+ throw er;
382
+ });
383
+ this._requests.push(request);
384
+ const item = await request;
385
+ if (item) {
386
+ item.result = () => this.result(item);
387
+ yield item;
356
388
  }
389
+ }
357
390
  }
358
391
 
359
- /**
360
- * Modern geocoder on async generators. May use different data providers.
361
- *
362
- * @packageDocumentation
363
- * @module geocoder
364
- */
365
392
  function create(options) {
366
- return new Geocoder(options);
393
+ return new Geocoder(options);
367
394
  }
368
395
 
369
396
  exports.BaseProvider = BaseProvider;