@geogirafe/lib-geoportal
Version:
GeoGirafe is a flexible application to build online geoportals.
79 lines (78 loc) • 3.08 kB
JavaScript
import { GeoJSON } from 'ol/format.js';
import GirafeSingleton from '../../base/GirafeSingleton.js';
import { createBufferedExtentFromFeature } from '../geometrytools.js';
// The default provider is a container for search results that do not result from a provider search (e.g. map re-centering)
export const SEARCH_PROVIDER_DEFAULT = 'default';
// The default search group contains search results that do not belong to a specific category
export const SEARCH_GROUP_DEFAULT = 'default';
// The map recenter search group contains the coordinates for re-centering the map
export const SEARCH_GROUP_RECENTER_MAP = 'recenter_map';
class AbstractSearchClient extends GirafeSingleton {
type;
providerName;
url;
resultSrid;
searchTermPlaceholder = '###SEARCHTERM###';
searchLangPlaceholder = '###SEARCHLANG###';
geoJsonFormatter = new GeoJSON();
constructor(context, type, name, url, resultSrid) {
super(context);
this.type = type;
this.providerName = name;
this.url = new URL(url);
this.resultSrid = resultSrid;
}
initializeSingleton() {
super.initializeSingleton();
}
get mapProjection() {
return this.context.mapManager.getMap().getView().getProjection();
}
async requestSearch(term, abortController) {
const url = this.url
.toString()
.replace(this.searchTermPlaceholder, term)
.replace(this.searchLangPlaceholder, this.context.stateManager.state.language);
try {
const response = await fetch(url, { signal: abortController.signal });
return await this.parseResponse(response);
}
catch (error) {
console.error(`Error fetching search results from ${this.url.toString()}:`, error);
return [];
}
}
/**
* Parses the response from the server and returns an array of features.
* Features must have the following properties to be used correctly with the search component:
* - `provider`
* - `label`
* - `label_html`: optional, for styled entries in the search results list
* - `actions`: optional, a list of SearchResultsActions
*/
async parseResponse(response) {
const data = (await response.json());
const features = this.geoJsonFormatter.readFeatures(data, {
dataProjection: this.resultSrid,
featureProjection: this.mapProjection
});
return features.map((f) => {
f.set('provider', this.providerName);
return f;
});
}
/**
* Groups results by the default group, which equivalates to no grouping. Should be overridden by the client class
* to group results by a custom criteria.
*/
groupedResults(results) {
return { [SEARCH_GROUP_DEFAULT]: results };
}
/**
* Returns a bbox around the geometry that is 50% larger than the geometry.
*/
getZoomToBbox(feature) {
return createBufferedExtentFromFeature(feature);
}
}
export default AbstractSearchClient;