geoportal-access-lib
Version:
French Geoportal resources access library
279 lines (245 loc) • 10.3 kB
JavaScript
import Logger from "../../Utils/LoggerByDefault";
import _ from "../../Utils/MessagesResources";
import ErrorService from "../../Exceptions/ErrorService";
import CommonService from "../CommonService";
import DefaultUrlService from "../DefaultUrlService";
import GeocodeRequestFactory from "./Request/GeocodeRequestFactory";
import GeocodeResponseFactory from "./Response/GeocodeResponseFactory";
/**
* @classdesc
* Appel du service de géocodage direct du Géoportail :
* envoi de la requête construite selon les paramètres en options,
* éventuellement parsing et analyse de la réponse,
* retour d'une réponse en paramètre de la fonction onSuccess.
*
*
* @constructor
* @extends {Gp.Services.CommonService}
* @alias Gp.Services.Geocode
*
* @param {Object} options - options spécifiques au service (+ les options heritées)
*
* @param {String|Object} options.query - Nom de l'adresse, du toponyme, de l'unité administrative ou de la parcelle cadastrale recherchée.
*
* @param {Object} [options.filters] - Les propriétés possibles de cet objet sont décrites ci-après.
* @param {String} [options.filters.[prop]] - Critère supplémentaire pour filtrer la recherche sous la forme
* d'un couple clé/valeur à définir selon les possibilités du serveur ajouté à la requête.
* Le service de géocodage du Géoportail permet de filtrer les adresses postales avec les propriétés :
* "postalCode", "inseeCode", "city".
* Il permet également de filtrer les toponymes avec les propriétés :
* "postalCode", "inseeCode", "type".
* Enfin, il permet de filtrer les parcelles cadastrales avec les propriétés :
* "codeDepartement", "codeCommune", "nomCommune", "codeCommuneAbs", "codeArrondissement", "section", "numero", "feuille".
*
* @param {String} [options.index = "StreetAddress"] - Type de l'objet recherché.
* Le service de géocodage du Géoportail permet de rechercher des 'PositionOfInterest' pour des toponymes, des 'StreetAddress'
* pour des adresses postales ou des 'CadastralParcel' pour des parcelles cadastrales.
* L'index 'location' regroupe les indexes 'StreetAddress' et 'PositionOfInterest'.
* D'autres types pourront être rajoutés selon l'évolution du service.
* Par défaut, index = 'StreetAddress'.
*
* @param {Object} options.position - Position du point de référence pour le calcul de proximité exprimée dans le système de référence spécifié par le srs.
* @param {Float} options.position.lon - Longitude du point de référence pour le calcul de proximité.
* @param {Float} options.position.lat - Latitude du point de référence pour le calcul de proximité.
*
* @param {Number} [options.maximumResponses] - Nombre de réponses maximal que l'on souhaite recevoir.
* Pas de valeur par défaut.
* Si le serveur consulté est celui du Géoportail, la valeur par défaut sera donc celle du service : 20.
*
* @param {Boolean} [options.returnTrueGeometry = false] - Booléen indiquant si l'on souhaite récupérer la géométrie vraie des objects géolocalisés.
* false par défaut.
*
*
* @example
* var options = {
* apiKey : null,
* serverUrl : 'http://localhost/service/',
* proxyURL : null,
* timeOut : 10000, // ms
* rawResponse : false, // true|false
* scope : null, // this
* onSuccess : function (response) {},
* onFailure : function (error) {},
* // spécifique au service
* position : {lon:, lat:},
* index : 'StreetAddress',
* query : '10 rue du pont Machin-ville'
* (...)
* };
*/
function Geocode (options_) {
if (!(this instanceof Geocode)) {
throw new TypeError(_.getMessage("CLASS_CONSTRUCTOR", "Geocode"));
}
/**
* Nom de la classe (heritage)
* FIXME instance ou classe ?
*/
this.CLASSNAME = "Geocode";
this.logger = Logger.getLogger("Gp.Services.Geocode");
this.logger.trace("[Constructeur Geocode (options)]");
var options = this.patchOptionConvertor(options_);
if (!options.serverUrl) {
options.serverUrl = DefaultUrlService.Geocode.newUrl();
}
// appel du constructeur par heritage
CommonService.apply(this, [options]);
if (!options.hasOwnProperty("query")) {
throw new Error(_.getMessage("PARAM_MISSING", "query"));
}
// ajout des options spécifiques au service
this.options.query = options.query;
// on definit l'index par defaut
if (!options.index) {
this.options.index = options.index = "StreetAddress";
}
if (options.filters) {
var filter = Object.keys(options.filters);
for (var i = 0; i < filter.length; i++) {
var key = filter[i];
// on supprime les filtres vides
if (typeof options.filters[key] === "undefined" ||
(typeof options.filters[key] === "object" && Object.keys(options.filters[key]).length === 0) ||
(typeof options.filters[key] === "string" && options.filters[key].length === 0) ||
(Array.isArray(options.filters[key]) && options.filters[key].length === 0)
) {
delete this.options.filters[key];
}
}
}
this.options.index = options.index || "StreetAddress";
this.options.maximumResponses = options.maximumResponses || 20;
}
/**
* @lends module:Geocode#
*/
Geocode.prototype = Object.create(CommonService.prototype, {
// todo
// getter/setter
});
/*
* Constructeur (alias)
*/
Geocode.prototype.constructor = Geocode;
/**
* Patch pour la convertion des options vers le nouveau formalisme.
*
* @param {Object} options_ - options du service
* @return {Object} - options
*/
Geocode.prototype.patchOptionConvertor = function (options_) {
const options = options_;
if (options.hasOwnProperty("location")) {
this.logger.warn("The parameter 'location' is deprecated");
if (!options.query) {
options.query = options.location;
}
delete options.location;
}
if (options.filterOptions) {
this.logger.warn("The parameter 'filterOptions' is deprecated");
if (!options.filters) {
options.filters = options.filterOptions;
if (options.filters.type) {
this.logger.warn("The parameter 'filterOptions.type' is deprecated");
if (!options.index) {
if (Array.isArray(options.filters.type) && options.filters.type.length > 0) {
options.index = options.filters.type[0];
} else {
options.index = options.filters.type;
}
}
delete options.filters.type;
}
if (options.filters.bbox) {
this.logger.warn("The parameter 'filterOptions.bbox' is deprecated");
delete options.filters.bbox;
}
}
delete options.filterOptions;
}
if (options.position) {
if (options.position.x) {
this.logger.warn("The parameter 'position.x' is deprecated");
if (!options.position.lon) {
options.position.lon = options.position.x;
}
delete options.position.x;
}
if (options.position.y) {
this.logger.warn("The parameter 'position.y' is deprecated");
if (!options.position.lat) {
options.position.lat = options.position.y;
}
delete options.position.y;
}
}
if (options.returnFreeForm) {
this.logger.warn("The parameter 'returnFreeForm' is deprecated");
delete options.returnFreeForm;
}
if (options.srs) {
this.logger.warn("The parameter 'srs' is deprecated");
delete options.srs;
}
return options;
};
/**
* Création de la requête (overwrite)
*
* @param {Function} error - callback des erreurs
* @param {Function} success - callback
*/
Geocode.prototype.buildRequest = function (error, success) {
var options = {
httpMethod : this.options.httpMethod,
// options specifiques du service
geocodeMethod : "search",
query : this.options.query,
index : this.options.index,
returnTrueGeometry : this.options.returnTrueGeometry,
position : this.options.position,
maxResp : this.options.maximumResponses,
filters : this.options.filters
};
this.request = GeocodeRequestFactory.build(options);
// on teste si la requete a bien été construite !
(!this.request)
? error.call(this, new ErrorService(_.getMessage("SERVICE_REQUEST_BUILD")))
: success.call(this, this.request);
};
/**
* Analyse de la reponse (overwrite)
*
* @param {Function} error - callback des erreurs
* @param {Function} success - callback
*/
Geocode.prototype.analyzeResponse = function (error, success) {
/* INFO :
Etape 1 : Création de la requête (URL)
-> stockage de la requête dans this.request
Etape 2 : Envoi de la requête
-> appel du protocol XHR, et envoi (par ex send ())
-> récupération de la réponse JSON dans la fonction onSuccess () (this.response)
-> si code HTTP 200 et pas de message d'erreur : etape 3
-> si code HTTP != 200 : lancement de la fonction de callback onFailure avec le message d'erreur
Etape 3 : Analyse de la réponse JSON (si rawResponse === false )
-> appel du parser pour récupérer le document
Etape 4 : Lancement de la fonction de callback onSuccess avec la réponse :
-> JSON (si rawResponse === true)
-> ou geocodedLocations
*/
if (this.response) {
var options = {
response : this.response,
rawResponse : this.options.rawResponse,
onError : error,
onSuccess : success,
scope : this
};
GeocodeResponseFactory.build(options);
} else {
error.call(this, new ErrorService(_.getMessage("SERVICE_RESPONSE_EMPTY")));
}
};
export default Geocode;