@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 +40 -5
- package/lib/geocoder.cjs.js +105 -43
- package/lib/geocoder.cjs.js.map +1 -1
- package/lib/geocoder.cjs.prod.js +1 -1
- package/lib/geocoder.cjs.prod.js.map +1 -1
- package/lib/geocoder.esm-browser.js +474 -46
- package/lib/geocoder.esm-browser.js.map +1 -1
- package/lib/geocoder.esm-browser.prod.js +1 -1
- package/lib/geocoder.esm-browser.prod.js.map +1 -1
- package/lib/geocoder.esm-bundler.js +105 -43
- package/lib/geocoder.esm-bundler.js.map +1 -1
- package/lib/geocoder.esm-bundler.prod.js +1 -1
- package/lib/geocoder.esm-bundler.prod.js.map +1 -1
- package/lib/geocoder.global.js +498 -90
- package/lib/geocoder.global.js.map +1 -1
- package/lib/geocoder.global.prod.js +1 -1
- package/lib/geocoder.global.prod.js.map +1 -1
- package/lib/index.d.ts +131 -9
- package/package.json +5 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Bundle of @nextgis/geocoder; version: 1.
|
|
1
|
+
/** Bundle of @nextgis/geocoder; version: 1.18.6; author: NextGIS */
|
|
2
2
|
class CancelError extends Error {
|
|
3
3
|
constructor() {
|
|
4
4
|
super();
|
|
@@ -376,6 +376,47 @@ function full(val) {
|
|
|
376
376
|
return typeof val === 'string' ? !!val : defined(val);
|
|
377
377
|
}
|
|
378
378
|
|
|
379
|
+
function getBoundsCoordinates(b) {
|
|
380
|
+
const westNorth = [b[0], b[1]];
|
|
381
|
+
const eastNorth = [b[2], b[1]];
|
|
382
|
+
const eastSouth = [b[2], b[3]];
|
|
383
|
+
const westSouth = [b[0], b[3]];
|
|
384
|
+
return [westNorth, eastNorth, eastSouth, westSouth, westNorth];
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function degrees2meters(lng, lat) {
|
|
388
|
+
lat = lat > 85.06 ? 85.06 : lat < -85.06 ? -85.06 : lat;
|
|
389
|
+
const x = (lng * 20037508.34) / 180;
|
|
390
|
+
let y = Math.log(Math.tan(((90 + lat) * Math.PI) / 360)) / (Math.PI / 180);
|
|
391
|
+
y = (y * 20037508.34) / 180;
|
|
392
|
+
return [x, y];
|
|
393
|
+
}
|
|
394
|
+
// export function degrees2meters2(lon: number, lat: number): [number, number] {
|
|
395
|
+
// const radius = 6378137.0;
|
|
396
|
+
// const x = (radius * lon * Math.PI) / 180.0;
|
|
397
|
+
// const y =
|
|
398
|
+
// radius * Math.log(Math.tan(Math.PI / 4.0 + (lat * Math.PI) / 360.0));
|
|
399
|
+
// return [x, y];
|
|
400
|
+
// }
|
|
401
|
+
// export function meters2degress2(x: number, y: number): LngLatArray {
|
|
402
|
+
// const radius = 6378137.0;
|
|
403
|
+
// const lon = (180 / Math.PI) * (x / radius);
|
|
404
|
+
// const lat = (360 / Math.PI) * (Math.atan(Math.exp(y / radius)) - Math.PI / 4);
|
|
405
|
+
// return [lon, lat];
|
|
406
|
+
// }
|
|
407
|
+
// const lon = -77.035974;
|
|
408
|
+
// const lat = 38.898717;
|
|
409
|
+
// console.log(degrees2meters(lon, lat), degrees2meters2(lon, lat));
|
|
410
|
+
// const x = -8575605.398443861;
|
|
411
|
+
// const y = 4707174.018280405;
|
|
412
|
+
// console.log(meters2degress(x, y), meters2degress2(x, y));
|
|
413
|
+
|
|
414
|
+
function isLngLatBoundsArray(array) {
|
|
415
|
+
return (Array.isArray(array) &&
|
|
416
|
+
array.length === 4 &&
|
|
417
|
+
array.every((x) => typeof x === 'number'));
|
|
418
|
+
}
|
|
419
|
+
|
|
379
420
|
/**
|
|
380
421
|
* Copy the values of all of the enumerable own properties from one or more source objects to a
|
|
381
422
|
* target object. Returns the target object.
|
|
@@ -451,11 +492,29 @@ function objectRemoveEmpty(obj) {
|
|
|
451
492
|
return newObj;
|
|
452
493
|
}
|
|
453
494
|
|
|
495
|
+
function round(val, toFixed) {
|
|
496
|
+
const n = toFixed ? Number('1e+' + toFixed) : 1;
|
|
497
|
+
return Math.round((val + Number.EPSILON) * n) / n;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
function isObject$1(val) {
|
|
501
|
+
return Object.prototype.toString.call(val) === '[object Object]';
|
|
502
|
+
}
|
|
503
|
+
function isArray(val) {
|
|
504
|
+
return Object.prototype.toString.call(val) === '[object Array]';
|
|
505
|
+
}
|
|
506
|
+
|
|
454
507
|
function fixUrlStr(url) {
|
|
455
508
|
// remove double slash
|
|
456
509
|
return url.replace(/([^:]\/)\/+/g, '$1');
|
|
457
510
|
}
|
|
458
511
|
|
|
512
|
+
/**
|
|
513
|
+
* Represents the base class for a geocoder.
|
|
514
|
+
* This abstract class provides the basic methods that every geocoder should implement.
|
|
515
|
+
*
|
|
516
|
+
* @template O - The type of options that can be passed to the geocoder.
|
|
517
|
+
*/
|
|
459
518
|
class BaseGeocoder {
|
|
460
519
|
constructor(options) {
|
|
461
520
|
if (options) {
|
|
@@ -501,6 +560,11 @@ class Geocoder extends BaseGeocoder {
|
|
|
501
560
|
}
|
|
502
561
|
}
|
|
503
562
|
|
|
563
|
+
/**
|
|
564
|
+
* Abstract base class representing a search provider.
|
|
565
|
+
* It builds upon the BaseGeocoder functionalities with provider-specific properties.
|
|
566
|
+
* @template O - Options type which extends BaseProviderOptions.
|
|
567
|
+
*/
|
|
504
568
|
class BaseProvider extends BaseGeocoder {
|
|
505
569
|
}
|
|
506
570
|
|
|
@@ -1866,8 +1930,9 @@ class NgwConnector$1 {
|
|
|
1866
1930
|
* ```
|
|
1867
1931
|
*/
|
|
1868
1932
|
apiRequest(name, params_ = {}, requestOptions = {}) {
|
|
1869
|
-
var _a;
|
|
1933
|
+
var _a, _b;
|
|
1870
1934
|
const { method, headers, withCredentials, responseType } = requestOptions;
|
|
1935
|
+
params_ = (_a = requestOptions.params) !== null && _a !== void 0 ? _a : params_;
|
|
1871
1936
|
const params = objectRemoveEmpty(params_);
|
|
1872
1937
|
const makeApiRequest = () => apiRequest({ name, params, requestOptions, connector: this });
|
|
1873
1938
|
if (requestOptions.cache && method === 'GET') {
|
|
@@ -1879,7 +1944,7 @@ class NgwConnector$1 {
|
|
|
1879
1944
|
withCredentials,
|
|
1880
1945
|
responseType,
|
|
1881
1946
|
baseUrl: this.options.baseUrl,
|
|
1882
|
-
userId: (
|
|
1947
|
+
userId: (_b = this.user) === null || _b === void 0 ? void 0 : _b.id,
|
|
1883
1948
|
}),
|
|
1884
1949
|
});
|
|
1885
1950
|
}
|
|
@@ -2138,59 +2203,394 @@ NgwConnector$1.errors = {
|
|
|
2138
2203
|
*/
|
|
2139
2204
|
var NgwConnector = NgwConnector$1;
|
|
2140
2205
|
|
|
2206
|
+
function reEscape(s) {
|
|
2207
|
+
return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
2208
|
+
}
|
|
2209
|
+
function like(b, a, iLike) {
|
|
2210
|
+
a = String(a);
|
|
2211
|
+
b = String(b);
|
|
2212
|
+
if (a === b)
|
|
2213
|
+
return true;
|
|
2214
|
+
if (iLike && a.toUpperCase() === b.toUpperCase())
|
|
2215
|
+
return true;
|
|
2216
|
+
const re = `^${reEscape(a)}$`.replace(/%/g, '.*').replace('_', '.');
|
|
2217
|
+
return new RegExp(re, iLike ? 'i' : '').exec(b) !== null;
|
|
2218
|
+
}
|
|
2219
|
+
const operationsAliases = {
|
|
2220
|
+
// greater(>)
|
|
2221
|
+
gt: (a, b) => a > b,
|
|
2222
|
+
// lower(<)
|
|
2223
|
+
lt: (a, b) => a < b,
|
|
2224
|
+
// greater or equal(>=)
|
|
2225
|
+
ge: (a, b) => a >= b,
|
|
2226
|
+
// lower or equal(<=)
|
|
2227
|
+
le: (a, b) => a <= b,
|
|
2228
|
+
// equal(=)
|
|
2229
|
+
eq: (a, b) => a === b,
|
|
2230
|
+
// not equal(!=)
|
|
2231
|
+
ne: (a, b) => a !== b,
|
|
2232
|
+
in: (a, b) => b.indexOf(a) !== -1,
|
|
2233
|
+
notin: (a, b) => b.indexOf(a) === -1,
|
|
2234
|
+
// LIKE SQL statement(for strings compare)
|
|
2235
|
+
like: (a, b) => {
|
|
2236
|
+
return like(a, b);
|
|
2237
|
+
},
|
|
2238
|
+
// ILIKE SQL statement(for strings compare)
|
|
2239
|
+
ilike: (a, b) => {
|
|
2240
|
+
return like(a, b, true);
|
|
2241
|
+
},
|
|
2242
|
+
};
|
|
2243
|
+
function isPropertyFilter(filter) {
|
|
2244
|
+
const pf = filter;
|
|
2245
|
+
if (pf.length === 3 &&
|
|
2246
|
+
typeof pf[0] === 'string' &&
|
|
2247
|
+
typeof pf[1] === 'string') {
|
|
2248
|
+
return true;
|
|
2249
|
+
}
|
|
2250
|
+
return false;
|
|
2251
|
+
}
|
|
2252
|
+
function propertiesFilter(properties, filters) {
|
|
2253
|
+
const logic = typeof filters[0] === 'string' ? filters[0] : 'all';
|
|
2254
|
+
const filterFunction = (p) => {
|
|
2255
|
+
if (isPropertyFilter(p)) {
|
|
2256
|
+
const [field, operation, value] = p;
|
|
2257
|
+
const operationExec = operationsAliases[operation];
|
|
2258
|
+
if (operationExec) {
|
|
2259
|
+
if (operation === 'like' || operation === 'ilike') {
|
|
2260
|
+
if (typeof field === 'string') {
|
|
2261
|
+
let prop = '';
|
|
2262
|
+
const value_ = field.replace(/^%?(\w+)%?$/, (match, cleanField) => {
|
|
2263
|
+
prop = properties[cleanField];
|
|
2264
|
+
return field.replace(cleanField, value);
|
|
2265
|
+
});
|
|
2266
|
+
return operationExec(prop, value_);
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
return operationExec(properties[field], value);
|
|
2270
|
+
}
|
|
2271
|
+
return false;
|
|
2272
|
+
}
|
|
2273
|
+
else {
|
|
2274
|
+
return propertiesFilter(properties, p);
|
|
2275
|
+
}
|
|
2276
|
+
};
|
|
2277
|
+
const filters_ = filters.filter((x) => Array.isArray(x));
|
|
2278
|
+
return logic === 'any'
|
|
2279
|
+
? filters_.some(filterFunction)
|
|
2280
|
+
: filters_.every(filterFunction);
|
|
2281
|
+
}
|
|
2282
|
+
|
|
2283
|
+
const FEATURE_REQUEST_PARAMS = {
|
|
2284
|
+
srs: 4326,
|
|
2285
|
+
geom_format: 'geojson',
|
|
2286
|
+
};
|
|
2287
|
+
function updateItemRequestParam(params, options) {
|
|
2288
|
+
const { extensions, geom, fields, srs, ilike, like } = options;
|
|
2289
|
+
if (extensions) {
|
|
2290
|
+
params.extensions = extensions.join(',');
|
|
2291
|
+
}
|
|
2292
|
+
if (fields !== undefined) {
|
|
2293
|
+
params.fields = Array.isArray(fields) ? fields.join(',') : '';
|
|
2294
|
+
}
|
|
2295
|
+
if (geom !== undefined) {
|
|
2296
|
+
params.geom = geom ? 'yes' : 'no';
|
|
2297
|
+
if (!geom) {
|
|
2298
|
+
delete params.srs;
|
|
2299
|
+
delete params.geom_format;
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
if (defined(ilike)) {
|
|
2303
|
+
params.ilike = ilike;
|
|
2304
|
+
}
|
|
2305
|
+
else if (defined(like)) {
|
|
2306
|
+
params.like = like;
|
|
2307
|
+
}
|
|
2308
|
+
if (defined(srs)) {
|
|
2309
|
+
params.srs = srs;
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
// NGW REST API is not able to filtering by combined queries
|
|
2313
|
+
// therefore the filter is divided into several requests
|
|
2314
|
+
function createFeatureFieldFilterQueries(opt) {
|
|
2315
|
+
const queries = getQueries(opt);
|
|
2316
|
+
return CancelablePromise.all(queries).then((itemsParts) => {
|
|
2317
|
+
// this list of ids used for optimization
|
|
2318
|
+
const ids = [];
|
|
2319
|
+
const items = [];
|
|
2320
|
+
for (const part of itemsParts) {
|
|
2321
|
+
for (const item of part) {
|
|
2322
|
+
if (!ids.includes(item.id)) {
|
|
2323
|
+
items.push(item);
|
|
2324
|
+
ids.push(item.id);
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
const offset = opt.offset !== undefined ? opt.offset : 0;
|
|
2329
|
+
const limit = opt.limit !== undefined ? opt.limit : items.length;
|
|
2330
|
+
if (opt.offset || opt.limit) {
|
|
2331
|
+
return items.splice(offset, limit);
|
|
2332
|
+
}
|
|
2333
|
+
return items;
|
|
2334
|
+
});
|
|
2335
|
+
}
|
|
2336
|
+
function createParam(pf) {
|
|
2337
|
+
const [field, operation, value] = pf;
|
|
2338
|
+
const isFldStr = field !== 'id' ? 'fld_' : '';
|
|
2339
|
+
let vStart = '';
|
|
2340
|
+
let vEnd = '';
|
|
2341
|
+
const field_ = String(field)
|
|
2342
|
+
.trim()
|
|
2343
|
+
.replace(/^(%?)(.+?)(%?)$/, (m, a, b, c) => {
|
|
2344
|
+
vStart = a;
|
|
2345
|
+
vEnd = c;
|
|
2346
|
+
return b;
|
|
2347
|
+
});
|
|
2348
|
+
const v = vStart + value + vEnd;
|
|
2349
|
+
return [`${isFldStr}${field_}__${operation}`, v];
|
|
2350
|
+
}
|
|
2351
|
+
function getQueries(opt, _queries = [], _parentAllParams = []) {
|
|
2352
|
+
const { filters } = opt;
|
|
2353
|
+
const logic = typeof filters[0] === 'string' ? filters[0] : 'all';
|
|
2354
|
+
const filters_ = filters.filter((x) => Array.isArray(x));
|
|
2355
|
+
if (logic === 'any') {
|
|
2356
|
+
for (const f of filters_) {
|
|
2357
|
+
if (isPropertyFilter(f)) {
|
|
2358
|
+
_queries.push(fetchNgwLayerItemsRequest({
|
|
2359
|
+
...opt,
|
|
2360
|
+
paramList: [..._parentAllParams, createParam(f)],
|
|
2361
|
+
}));
|
|
2362
|
+
}
|
|
2363
|
+
else {
|
|
2364
|
+
getQueries({
|
|
2365
|
+
...opt,
|
|
2366
|
+
filters: f,
|
|
2367
|
+
}, _queries, [..._parentAllParams]);
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
2371
|
+
else if (logic === 'all') {
|
|
2372
|
+
const filters = [];
|
|
2373
|
+
const propertiesFilterList = [];
|
|
2374
|
+
for (const f of filters_) {
|
|
2375
|
+
if (isPropertyFilter(f)) {
|
|
2376
|
+
filters.push(createParam(f));
|
|
2377
|
+
}
|
|
2378
|
+
else {
|
|
2379
|
+
propertiesFilterList.push(f);
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
if (propertiesFilterList.length) {
|
|
2383
|
+
for (const x of propertiesFilterList) {
|
|
2384
|
+
getQueries({
|
|
2385
|
+
...opt,
|
|
2386
|
+
filters: x,
|
|
2387
|
+
}, _queries, [..._parentAllParams, ...filters]);
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
else {
|
|
2391
|
+
_queries.push(fetchNgwLayerItemsRequest({
|
|
2392
|
+
...opt,
|
|
2393
|
+
paramList: [..._parentAllParams, ...filters],
|
|
2394
|
+
}));
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
return _queries;
|
|
2398
|
+
}
|
|
2399
|
+
function createWktFromCoordArray(coord) {
|
|
2400
|
+
const polygon = coord.map(([lng, lat]) => {
|
|
2401
|
+
const [x, y] = degrees2meters(lng, lat).map((c) => round(c));
|
|
2402
|
+
return x + ' ' + y;
|
|
2403
|
+
});
|
|
2404
|
+
return `POLYGON((${polygon.join(', ')}))`;
|
|
2405
|
+
}
|
|
2406
|
+
function fetchNgwLayerItemsRequest(options) {
|
|
2407
|
+
const params = {
|
|
2408
|
+
...FEATURE_REQUEST_PARAMS,
|
|
2409
|
+
};
|
|
2410
|
+
const { limit, cache, signal, offset, orderBy, paramList, connector, geomFormat, intersects, resourceId, } = options;
|
|
2411
|
+
if (limit) {
|
|
2412
|
+
if (limit !== Number.POSITIVE_INFINITY) {
|
|
2413
|
+
params.limit = limit;
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
else {
|
|
2417
|
+
// Strict restriction on loading data from large layers
|
|
2418
|
+
params.limit = 7000;
|
|
2419
|
+
}
|
|
2420
|
+
if (offset) {
|
|
2421
|
+
params.offset = offset;
|
|
2422
|
+
}
|
|
2423
|
+
if (geomFormat) {
|
|
2424
|
+
params.geom_format = geomFormat;
|
|
2425
|
+
}
|
|
2426
|
+
updateItemRequestParam(params, options);
|
|
2427
|
+
if (orderBy) {
|
|
2428
|
+
params.order_by = orderBy.join(',');
|
|
2429
|
+
}
|
|
2430
|
+
if (Array.isArray(intersects)) {
|
|
2431
|
+
const coordinates = isLngLatBoundsArray(intersects)
|
|
2432
|
+
? getBoundsCoordinates(intersects)
|
|
2433
|
+
: intersects;
|
|
2434
|
+
params.intersects = createWktFromCoordArray(coordinates);
|
|
2435
|
+
}
|
|
2436
|
+
else if (typeof intersects === 'string') {
|
|
2437
|
+
params.intersects = intersects;
|
|
2438
|
+
}
|
|
2439
|
+
if (paramList) {
|
|
2440
|
+
params.paramList = paramList;
|
|
2441
|
+
}
|
|
2442
|
+
const reqParams = {
|
|
2443
|
+
id: resourceId,
|
|
2444
|
+
...params,
|
|
2445
|
+
};
|
|
2446
|
+
return connector.get('feature_layer.feature.collection', { cache, signal }, reqParams);
|
|
2447
|
+
}
|
|
2448
|
+
|
|
2449
|
+
function prepareNgwFieldsToPropertiesFilter(fields) {
|
|
2450
|
+
let f;
|
|
2451
|
+
for (f in fields) {
|
|
2452
|
+
const field = fields[f];
|
|
2453
|
+
if (isObject$1(field)) {
|
|
2454
|
+
const date = field;
|
|
2455
|
+
if (defined(date.year) && defined(date.month) && defined(date.day)) {
|
|
2456
|
+
const dt = [
|
|
2457
|
+
date.year,
|
|
2458
|
+
date.month - 1,
|
|
2459
|
+
date.day,
|
|
2460
|
+
];
|
|
2461
|
+
if ('hour' in date) {
|
|
2462
|
+
[date.hour, date.minute, date.second].forEach((x) => {
|
|
2463
|
+
dt.push(x);
|
|
2464
|
+
});
|
|
2465
|
+
}
|
|
2466
|
+
fields[f] = new Date(...dt).toISOString();
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2469
|
+
else if (f === 'id' && typeof field === 'string') {
|
|
2470
|
+
fields[f] = field.split(',').map(Number);
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
return fields;
|
|
2474
|
+
}
|
|
2475
|
+
|
|
2476
|
+
function fetchNgwLayerItems(options) {
|
|
2477
|
+
const filters = options.filters;
|
|
2478
|
+
if (filters) {
|
|
2479
|
+
return createFeatureFieldFilterQueries({
|
|
2480
|
+
...options,
|
|
2481
|
+
filters,
|
|
2482
|
+
}).then((data) => {
|
|
2483
|
+
var _a;
|
|
2484
|
+
const clientFilterValidate = (_a = options.clientFilterValidate) !== null && _a !== void 0 ? _a : isFilterWithAnyCase(filters);
|
|
2485
|
+
// Additional client-side filter check
|
|
2486
|
+
if (clientFilterValidate) {
|
|
2487
|
+
data = data.filter((y) => {
|
|
2488
|
+
const fields = prepareNgwFieldsToPropertiesFilter({
|
|
2489
|
+
...y.fields,
|
|
2490
|
+
id: y.id,
|
|
2491
|
+
});
|
|
2492
|
+
const result = propertiesFilter(fields, filters);
|
|
2493
|
+
return result;
|
|
2494
|
+
});
|
|
2495
|
+
}
|
|
2496
|
+
return data;
|
|
2497
|
+
});
|
|
2498
|
+
}
|
|
2499
|
+
else {
|
|
2500
|
+
return fetchNgwLayerItemsRequest(options);
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
function isFilterWithAnyCase(filters) {
|
|
2504
|
+
if (filters[0] === 'any') {
|
|
2505
|
+
return true;
|
|
2506
|
+
}
|
|
2507
|
+
for (let i = 1; i < filters.length; i++) {
|
|
2508
|
+
const p = filters[i];
|
|
2509
|
+
if (isArray(p)) {
|
|
2510
|
+
const deep = isFilterWithAnyCase(p);
|
|
2511
|
+
if (deep) {
|
|
2512
|
+
return true;
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
return false;
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2141
2519
|
class NgwProvider extends BaseProvider {
|
|
2142
2520
|
constructor(options) {
|
|
2521
|
+
var _a;
|
|
2143
2522
|
super(options);
|
|
2144
|
-
this.caseInsensitive = true;
|
|
2145
|
-
this.searchUrl = 'https://maxim.nextgis.com';
|
|
2146
2523
|
this.searchResources = [];
|
|
2147
|
-
this.
|
|
2524
|
+
this._abortControllers = [];
|
|
2525
|
+
if (!options.searchUrl && !((_a = options.connectorOptions) === null || _a === void 0 ? void 0 : _a.baseUrl)) {
|
|
2526
|
+
throw new Error('The `searchUrl` of `connectorOptions.baseUrl` are required');
|
|
2527
|
+
}
|
|
2148
2528
|
this.connector =
|
|
2149
2529
|
options.connector ||
|
|
2150
2530
|
new NgwConnector({
|
|
2151
2531
|
baseUrl: this.searchUrl,
|
|
2532
|
+
...options.connectorOptions,
|
|
2152
2533
|
});
|
|
2153
2534
|
this.searchResources = options.searchResources;
|
|
2154
2535
|
}
|
|
2155
2536
|
abort() {
|
|
2156
|
-
this.
|
|
2157
|
-
|
|
2537
|
+
this._abortControllers.forEach((a) => {
|
|
2538
|
+
a.abort();
|
|
2158
2539
|
});
|
|
2159
|
-
this.
|
|
2160
|
-
}
|
|
2161
|
-
async *search(
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
const entries = [];
|
|
2176
|
-
if (resp) {
|
|
2177
|
-
resp.forEach((x) => {
|
|
2178
|
-
entries.push({
|
|
2179
|
-
query: like,
|
|
2180
|
-
resourceId: resource.id,
|
|
2181
|
-
...x,
|
|
2182
|
-
});
|
|
2540
|
+
this._abortControllers.length = 0;
|
|
2541
|
+
}
|
|
2542
|
+
async *search(query) {
|
|
2543
|
+
var _a, _b;
|
|
2544
|
+
const signal = this._makeSignal();
|
|
2545
|
+
for (const config of this.searchResources) {
|
|
2546
|
+
if (signal.aborted) {
|
|
2547
|
+
break;
|
|
2548
|
+
}
|
|
2549
|
+
const { searchMethod } = config;
|
|
2550
|
+
const limit = (_a = config.limit) !== null && _a !== void 0 ? _a : NgwProvider.limit;
|
|
2551
|
+
//
|
|
2552
|
+
const resourceId = (_b = config.id) !== null && _b !== void 0 ? _b : config.resourceId;
|
|
2553
|
+
try {
|
|
2554
|
+
const resource = await this.connector.getResourceOrFail(resourceId, {
|
|
2555
|
+
cache: true,
|
|
2183
2556
|
});
|
|
2557
|
+
const options = {
|
|
2558
|
+
connector: this.connector,
|
|
2559
|
+
resourceId,
|
|
2560
|
+
signal,
|
|
2561
|
+
limit,
|
|
2562
|
+
};
|
|
2563
|
+
if (searchMethod === 'like') {
|
|
2564
|
+
options.like = query;
|
|
2565
|
+
}
|
|
2566
|
+
else {
|
|
2567
|
+
options.ilike = query;
|
|
2568
|
+
}
|
|
2569
|
+
const request = fetchNgwLayerItems(options);
|
|
2570
|
+
const entries = await request;
|
|
2571
|
+
for (const item of this._items({
|
|
2572
|
+
entries,
|
|
2573
|
+
query,
|
|
2574
|
+
config,
|
|
2575
|
+
resourceItem: resource,
|
|
2576
|
+
})) {
|
|
2577
|
+
item.result = () => this.result(item);
|
|
2578
|
+
yield item;
|
|
2579
|
+
}
|
|
2184
2580
|
}
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2581
|
+
catch (er) {
|
|
2582
|
+
if (er &&
|
|
2583
|
+
'name' in er &&
|
|
2584
|
+
er.name !== 'CancelError') {
|
|
2585
|
+
console.warn(er);
|
|
2586
|
+
}
|
|
2188
2587
|
}
|
|
2189
2588
|
}
|
|
2190
2589
|
}
|
|
2191
2590
|
result(item) {
|
|
2591
|
+
const signal = this._makeSignal();
|
|
2192
2592
|
const req = this.connector
|
|
2193
|
-
.get('feature_layer.feature.item_extent',
|
|
2593
|
+
.get('feature_layer.feature.item_extent', { signal }, {
|
|
2194
2594
|
id: item.resourceId,
|
|
2195
2595
|
fid: item.featureId,
|
|
2196
2596
|
})
|
|
@@ -2201,25 +2601,47 @@ class NgwProvider extends BaseProvider {
|
|
|
2201
2601
|
extent: [e.minLon, e.minLat, e.maxLon, e.maxLat],
|
|
2202
2602
|
};
|
|
2203
2603
|
});
|
|
2204
|
-
this.requests.push(req);
|
|
2205
2604
|
return req;
|
|
2206
2605
|
}
|
|
2207
|
-
|
|
2606
|
+
_makeSignal() {
|
|
2607
|
+
const abortController = new AbortController();
|
|
2608
|
+
this._abortControllers.push(abortController);
|
|
2609
|
+
return abortController.signal;
|
|
2610
|
+
}
|
|
2611
|
+
_items({ entries, query, config, resourceItem, }) {
|
|
2612
|
+
var _a;
|
|
2208
2613
|
const items = [];
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2614
|
+
let labelField = undefined;
|
|
2615
|
+
if (resourceItem.feature_layer) {
|
|
2616
|
+
labelField = (_a = resourceItem.feature_layer.fields.find((f) => f.label_field)) === null || _a === void 0 ? void 0 : _a.keyname;
|
|
2617
|
+
}
|
|
2618
|
+
const meta = this.searchResources.find((x) => { var _a; return (_a = x.id) !== null && _a !== void 0 ? _a : x.resourceId === resourceItem.resource.id; });
|
|
2619
|
+
if (meta) {
|
|
2620
|
+
entries.forEach((entry) => {
|
|
2621
|
+
let text = labelField ? entry.fields[labelField] : entry.id;
|
|
2622
|
+
if (config.renderSearch) {
|
|
2623
|
+
text = config.renderSearch({
|
|
2624
|
+
item: entry,
|
|
2625
|
+
resourceItem,
|
|
2626
|
+
});
|
|
2627
|
+
}
|
|
2628
|
+
else if (labelField) {
|
|
2629
|
+
text = entry.fields[labelField];
|
|
2630
|
+
}
|
|
2212
2631
|
items.push({
|
|
2213
|
-
query:
|
|
2214
|
-
text
|
|
2632
|
+
query: query,
|
|
2633
|
+
text,
|
|
2215
2634
|
featureId: entry.id,
|
|
2216
|
-
resourceId:
|
|
2635
|
+
resourceId: resourceItem.resource.id,
|
|
2636
|
+
item: entry,
|
|
2637
|
+
resourceItem,
|
|
2217
2638
|
});
|
|
2218
|
-
}
|
|
2219
|
-
}
|
|
2639
|
+
});
|
|
2640
|
+
}
|
|
2220
2641
|
return items;
|
|
2221
2642
|
}
|
|
2222
2643
|
}
|
|
2644
|
+
NgwProvider.limit = 300;
|
|
2223
2645
|
|
|
2224
2646
|
class NominatimProvider extends BaseProvider {
|
|
2225
2647
|
constructor(options) {
|
|
@@ -2285,6 +2707,12 @@ class NominatimProvider extends BaseProvider {
|
|
|
2285
2707
|
}
|
|
2286
2708
|
}
|
|
2287
2709
|
|
|
2710
|
+
/**
|
|
2711
|
+
* Modern geocoder on async generators. May use different data providers.
|
|
2712
|
+
*
|
|
2713
|
+
* @packageDocumentation
|
|
2714
|
+
* @module geocoder
|
|
2715
|
+
*/
|
|
2288
2716
|
function create(options) {
|
|
2289
2717
|
return new Geocoder(options);
|
|
2290
2718
|
}
|