Skip to content

Commit

Permalink
fix(ICherche): add a custom cache hash to account for http params (#1262
Browse files Browse the repository at this point in the history
)

* feat(SearchBar): add a way to invalidate the cache on setting change
infra-geo-ouverte/igo2#928

* fix(ICherche): add a custom cache hash to account for http settings

* fix(Request): bust the cache on params changes.
fix(OsrmDirection): route
fix(Cadastre): search
fix(iLayer): search
fix(Nominatim): search
fix(StoredQueries): search and reverseSearch

* remove projects
  • Loading branch information
alecarn authored Sep 13, 2023
1 parent ca7f5ec commit 776fc4b
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { map } from 'rxjs/operators';

import { Cacheable } from 'ts-cacheable';

import { uuid } from '@igo2/utils';
import { customCacheHasher, uuid } from '@igo2/utils';
import { ConfigService } from '@igo2/core';

import { Direction, DirectionOptions } from '../shared/directions.interface';
Expand Down Expand Up @@ -37,16 +37,27 @@ export class OsrmDirectionsSource extends DirectionsSource {
return OsrmDirectionsSource._name;
}

route(
coordinates: [number, number][],
directionsOptions: DirectionOptions = {}
): Observable<Direction[]> {
const directionsParams = this.getRouteParams(directionsOptions);
return this.getRoute(coordinates, directionsParams);
}

@Cacheable({
maxCacheCount: 20
maxCacheCount: 20,
cacheHasher: customCacheHasher
})
route(coordinates: [number, number][], directionsOptions: DirectionOptions = {}): Observable<Direction[]> {
const directionsParams = this.getRouteParams(directionsOptions);
private getRoute(
coordinates: [number, number][],
params: HttpParams
): Observable<Direction[]> {
return this.http
.get<JSON[]>(this.directionsUrl + coordinates.join(';'), {
params: directionsParams
params
})
.pipe(map(res => this.extractRoutesData(res)));
.pipe(map((res) => this.extractRoutesData(res)));
}

private extractRoutesData(response): Direction[] {
Expand Down
15 changes: 12 additions & 3 deletions packages/geo/src/lib/search/shared/sources/cadastre.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { LanguageService, StorageService } from '@igo2/core';
import { computeTermSimilarity } from '../search.utils';
import { Cacheable } from 'ts-cacheable';
import { GeoJsonGeometryTypes } from 'geojson';
import { customCacheHasher } from '@igo2/utils';

/**
* Cadastre search source
Expand Down Expand Up @@ -57,9 +58,6 @@ export class CadastreSearchSource extends SearchSource implements TextSearch {
* @param term Place name
* @returns Observable of <SearchResult<Feature>[]
*/
@Cacheable({
maxCacheCount: 20
})
search(
term: string | undefined,
options?: TextSearchOptions
Expand All @@ -72,6 +70,17 @@ export class CadastreSearchSource extends SearchSource implements TextSearch {
if (!params.get('numero') || !params.get('numero').match(/^[0-9,]+$/g)) {
return of([]);
}
return this.getCadastre(term, params);
}

@Cacheable({
maxCacheCount: 20,
cacheHasher: customCacheHasher
})
private getCadastre(
term: string,
params: HttpParams
): Observable<SearchResult<Feature>[]> {
return this.http
.get(this.searchUrl, { params, responseType: 'text' })
.pipe(map((response: string) => this.extractResults(response, term)));
Expand Down
25 changes: 17 additions & 8 deletions packages/geo/src/lib/search/shared/sources/icherche.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { map, catchError } from 'rxjs/operators';

import { AuthService } from '@igo2/auth';
import { LanguageService, StorageService } from '@igo2/core';
import { ObjectUtils } from '@igo2/utils';
import { ObjectUtils, customCacheHasher } from '@igo2/utils';

import pointOnFeature from '@turf/point-on-feature';

Expand Down Expand Up @@ -360,9 +360,6 @@ export class IChercheSearchSource extends SearchSource implements TextSearch {
* @param term Location name or keyword
* @returns Observable of <SearchResult<Feature>[]
*/
@Cacheable({
maxCacheCount: 20
})
search(
term: string,
options?: TextSearchOptions
Expand All @@ -373,6 +370,14 @@ export class IChercheSearchSource extends SearchSource implements TextSearch {
}
this.options.params.page = params.get('page') || '1';

return this.getSearch(term, params);
}

@Cacheable({
maxCacheCount: 20,
cacheHasher: customCacheHasher,
})
private getSearch(term: string, params: HttpParams): Observable<SearchResult<Feature>[]> {
return this.http.get(`${this.searchUrl}/geocode`, { params }).pipe(
map((response: IChercheResponse) => this.extractResults(response, term)),
catchError((err) => {
Expand All @@ -384,7 +389,6 @@ export class IChercheSearchSource extends SearchSource implements TextSearch {
})
);
}

private getAllowedTypes() {
return this.http
.get(`${this.searchUrl}/types`)
Expand Down Expand Up @@ -773,9 +777,6 @@ export class IChercheReverseSearchSource extends SearchSource
* @param distance Search raidus around lonLat
* @returns Observable of <SearchResult<Feature>[]
*/
@Cacheable({
maxCacheCount: 20
})
reverseSearch(
lonLat: [number, number],
options?: ReverseSearchOptions
Expand All @@ -784,6 +785,14 @@ export class IChercheReverseSearchSource extends SearchSource
if (!params.get('type').length) {
return of([]);
}
return this.getReverseSearch(params);
}

@Cacheable({
maxCacheCount: 20,
cacheHasher: customCacheHasher,
})
private getReverseSearch(params: HttpParams): Observable<SearchResult<Feature>[]> {
return this.http.get(`${this.searchUrl}/locate`, { params }).pipe(
map((response: IChercheReverseResponse) => {
return this.extractResults(response);
Expand Down
20 changes: 14 additions & 6 deletions packages/geo/src/lib/search/shared/sources/ilayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Observable, BehaviorSubject, of } from 'rxjs';
import { map } from 'rxjs/operators';

import { LanguageService, StorageService } from '@igo2/core';
import { ObjectUtils } from '@igo2/utils';
import { customCacheHasher, ObjectUtils } from '@igo2/utils';

import { getResolutionFromScale } from '../../../map/shared/map.utils';
import { LAYER } from '../../../layer';
Expand Down Expand Up @@ -204,10 +204,6 @@ export class ILayerSearchSource extends SearchSource implements TextSearch {
* @param term Layer name or keyword
* @returns Observable of <SearchResult<LayerOptions>[]
*/

@Cacheable({
maxCacheCount: 20
})
search(
term: string | undefined,
options?: TextSearchOptions
Expand All @@ -217,11 +213,23 @@ export class ILayerSearchSource extends SearchSource implements TextSearch {
return of([]);
}
this.options.params.page = params.get('page') || '1';
return this.getSearch(term, params);
}

@Cacheable({
maxCacheCount: 20,
cacheHasher: customCacheHasher
})
private getSearch(
term: string,
params: HttpParams
): Observable<SearchResult<ILayerItemResponse>[]> {
return this.http
.get(this.searchUrl, { params })
.pipe(
map((response: ILayerServiceResponse) => this.extractResults(response, term))
map((response: ILayerServiceResponse) =>
this.extractResults(response, term)
)
);
}

Expand Down
12 changes: 9 additions & 3 deletions packages/geo/src/lib/search/shared/sources/nominatim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { SearchSourceOptions, TextSearchOptions } from './source.interfaces';
import { NominatimData } from './nominatim.interfaces';
import { computeTermSimilarity } from '../search.utils';
import { Cacheable } from 'ts-cacheable';
import { customCacheHasher } from '@igo2/utils';

/**
* Nominatim search source
Expand Down Expand Up @@ -142,9 +143,6 @@ export class NominatimSearchSource extends SearchSource implements TextSearch {
* @param term Place name
* @returns Observable of <SearchResult<Feature>[]
*/
@Cacheable({
maxCacheCount: 20
})
search(
term: string | undefined,
options?: TextSearchOptions
Expand All @@ -153,6 +151,14 @@ export class NominatimSearchSource extends SearchSource implements TextSearch {
if (!params.get('q')) {
return of([]);
}
return this.getSearch(term, params);
}

@Cacheable({
maxCacheCount: 20,
cacheHasher: customCacheHasher,
})
private getSearch(term: string, params: HttpParams): Observable<SearchResult<Feature>[]> {
return this.http
.get(this.searchUrl, { params })
.pipe(map((response: NominatimData[]) => this.extractResults(response, term)));
Expand Down
104 changes: 59 additions & 45 deletions packages/geo/src/lib/search/shared/sources/storedqueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

import { ObjectUtils } from '@igo2/utils';
import { ObjectUtils, customCacheHasher } from '@igo2/utils';
import { FEATURE, Feature } from '../../../feature';

import { SearchResult, TextSearch, ReverseSearch } from '../search.interfaces';
Expand Down Expand Up @@ -164,10 +164,6 @@ export class StoredQueriesSearchSource extends SearchSource
* @param term Location name or keyword
* @returns Observable of <SearchResult<Feature>[]
*/

@Cacheable({
maxCacheCount: 20
})
search(
term: string,
options?: TextSearchOptions
Expand All @@ -183,38 +179,56 @@ export class StoredQueriesSearchSource extends SearchSource
this.options.params = this.options.params ? this.options.params : {};
this.options.params.page = options.page ? String(options.page) : '1';

if (
new RegExp('.*?gml.*?', 'i').test(this.storedQueriesOptions.outputformat)
) {
return this.http
.get(this.searchUrl, { params, responseType: 'text' })
.pipe(
map(response => {
let resultArray = this.extractResults(this.extractWFSData(response), term);
return this.getSearch(term, params);
}

@Cacheable({
maxCacheCount: 20,
cacheHasher: customCacheHasher
})
private getSearch(
term: string,
params: HttpParams
): Observable<SearchResult<Feature>[]> {
return new RegExp('.*?gml.*?', 'i').test(
this.storedQueriesOptions.outputformat
)
? this.http.get(this.searchUrl, { params, responseType: 'text' }).pipe(
map((response) => {
let resultArray = this.extractResults(
this.extractWFSData(response),
term
);
resultArray.sort((a, b) =>
(a.meta.score > b.meta.score) ? 1 :
(a.meta.score === b.meta.score) ? ((a.meta.titleHtml < b.meta.titleHtml) ? 1 : -1) : -1);
a.meta.score > b.meta.score
? 1
: a.meta.score === b.meta.score
? a.meta.titleHtml < b.meta.titleHtml
? 1
: -1
: -1
);
resultArray.reverse();
if (resultArray.length > Number(this.options.params.limit)) {
const idxEnd = Number(this.options.params.limit) * Number(this.options.params.page);
const idxEnd =
Number(this.options.params.limit) *
Number(this.options.params.page);
const resultTotLenght = resultArray.length;
resultArray = resultArray.slice(0, idxEnd);
if (idxEnd < resultTotLenght) {
resultArray[resultArray.length - 1 ].meta.nextPage = true;
resultArray[resultArray.length - 1].meta.nextPage = true;
} else {
resultArray[resultArray.length - 1 ].meta.nextPage = false;
resultArray[resultArray.length - 1].meta.nextPage = false;
}
}
return resultArray;
})
)
: this.http.get(this.searchUrl, { params }).pipe(
map((response) => {
return this.extractResults(this.extractWFSData(response), term);
})
);
} else {
return this.http.get(this.searchUrl, { params }).pipe(
map(response => {
return this.extractResults(this.extractWFSData(response), term);
})
);
}
}

private getFormatFromOptions() {
Expand Down Expand Up @@ -432,32 +446,32 @@ export class StoredQueriesReverseSearchSource extends SearchSource
* @param distance Search raidus around lonLat
* @returns Observable of <SearchResult<Feature>[]
*/
@Cacheable({
maxCacheCount: 20
})
reverseSearch(
lonLat: [number, number],
options?: ReverseSearchOptions
): Observable<SearchResult<Feature>[]> {
const params = this.computeRequestParams(lonLat, options || {});
return this.getReverseSearch(params);
}

if (
new RegExp('.*?gml.*?', 'i').test(this.storedQueriesOptions.outputformat)
) {
return this.http
.get(this.searchUrl, { params, responseType: 'text' })
.pipe(
map(response => {
return this.extractResults(this.extractWFSData(response));
})
);
} else {
return this.http.get(this.searchUrl, { params }).pipe(
map(response => {
return this.extractResults(this.extractWFSData(response));
})
);
}
@Cacheable({
maxCacheCount: 20,
cacheHasher: customCacheHasher
})
private getReverseSearch(
params: HttpParams
): Observable<SearchResult<Feature>[]> {
const isGml = new RegExp('.*?gml.*?', 'i').test(
this.storedQueriesOptions.outputformat
);
const request$ = isGml
? this.http.get(this.searchUrl, { params, responseType: 'text' })
: this.http.get(this.searchUrl, { params });
return request$.pipe(
map((response) => {
return this.extractResults(this.extractWFSData(response));
})
);
}

private getFormatFromOptions() {
Expand Down
10 changes: 10 additions & 0 deletions packages/utils/src/lib/cache.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { HttpParams } from '@angular/common/http';

export function customCacheHasher(parameters: unknown[]): unknown[] {
return parameters.map((param) => {
if (param instanceof HttpParams) {
return param.toString();
}
return param !== undefined ? JSON.parse(JSON.stringify(param)) : param;
});
}
1 change: 1 addition & 0 deletions packages/utils/src/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './base64';
export * from './cache.utils';
export * from './clipboard';
export * from './change';
export * from './change.interface';
Expand Down

0 comments on commit 776fc4b

Please sign in to comment.