UNPKG

geoportal-access-lib

Version:

French Geoportal resources access library

279 lines (245 loc) 10.3 kB
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;