UNPKG

geoportal-access-lib

Version:

French Geoportal resources access library

248 lines (220 loc) 9.24 kB
import Logger from "../../Utils/LoggerByDefault"; import _ from "../../Utils/MessagesResources"; import ErrorService from "../../Exceptions/ErrorService"; import CommonService from "../CommonService"; import DefaultUrlService from "../DefaultUrlService"; import AltiRequestFactory from "./Request/AltiRequestFactory"; import AltiResponseFactory from "./Response/AltiResponseFactory"; /** * @classdesc * * Appel du service d'altimétrie du Géoportail * * @todo gestion du parma. output et callback * @todo outputFormat (REST) et format (WPS) * @todo La reponse JSON peut encapsuler un XML ! * * @constructor * @extends {Gp.Services.CommonService} * @alias Gp.Services.Alti * @param {Object} options - options spécifiques au service (+ les options heritées) * * @param {Array.<Object>} options.positions - Tableau ({lon:float,lat:float}) contenant les coordonnées des points (CRS:84) * dont on veut connaître les altitudes (ou à partir desquelles on va calculer le profil). * Chaque élément du tableau est un objet JavaScript avec deux attributs : lon et lat, qui sont des flottants. * Minimum 2 éléments si on souhaite calculer un profil altimétrique (ElevationLine). * Maximum 50 éléments. * * @param {String} options.outputFormat - Le format de la réponse du service alti : 'xml' ou 'json'. * Ce paramètre déterminera l'extension '.xml' ou '.json' du service dans le cas de l'API REST, * ou la valeur du paramètre 'format' dans le cas de la norme WPS. * Nécessaire si serverUrl est renseigné, et qu'on souhaite passer par l'API REST, * pour connaître le format dans lequel sera fournie la réponse (pour son traitement). * Non nécessaire pour la norme WPS. Par défaut, ce paramètre vaut 'json'. * * @param {Number} [options.sampling] - Nombre de points à utiliser pour déterminer le tracé d'un profil altimétrique, compris entre 2 et 5000. * A spécifier lorsqu'on souhaite accéder à cette fonctionnalité. * Dans ce cas, les points fournis en entrée (au minimum de deux) servent à déterminer l'axe planimétrique * le long duquel le profil doit être calculé. * Si le paramètre sampling n'est pas spécifié ou moins de deux points sont fournis, * c'est le service Elevation qui sera interrogé (altitudes simples calculées pour les points fournis). * Une valeur de sampling strictement inférieure à 2 déclenchera un échantillonnage avec la valeur par défaut du service (3 points). * * @param {String} [options.api] - Manière d'accéder au service : 'REST' (via l'API REST) ou 'WPS' (via la norme WPS). * Par défaut, on utilise l'API REST. * * @param {Boolean} [options.zonly] - Permet de ne récupérer que les altitudes en sortie s'il vaut 'true'. * Vaut 'false' par défaut. * * @param {String} [options.resource] - Resource utilisée pour réaliser le calcul. * * @example * var options = { * apiKey : null, * serverUrl : 'http://localhost/service/', * protocol : 'JSONP', // JSONP|XHR * proxyURL : null, * httpMethod : 'GET', // GET|POST * timeOut : 10000, // ms * rawResponse : false, // true|false * scope : null, // this * onSuccess : function (response) {}, * onFailure : function (error) {}, * // spécifique au service * positions : [{lon:, lat:}, {lon:, lat:}], * outputFormat : 'json' // json|xml * sampling : 3, * api : 'REST', // REST|WPS * zonly : false // false|true, * resource : "resource-par-defaut" * }; * */ function Alti (options) { if (!(this instanceof Alti)) { throw new TypeError(_.getMessage("CLASS_CONSTRUCTOR", "Alti")); } /** * Nom de la classe (heritage) * FIXME instance ou classe ? */ this.CLASSNAME = "Alti"; // appel du constructeur par heritage CommonService.apply(this, arguments); this.logger = Logger.getLogger("Gp.Services.Alti"); this.logger.trace("[Constructeur Alti (options)]"); // ##################### // analyse des options // ##################### if (!options.positions) { throw new Error(_.getMessage("PARAM_MISSING", "positions")); } if (options.positions.length === 0) { throw new Error(_.getMessage("PARAM_EMPTY", "positions")); } // ajout des options spécifiques au service this.options.positions = options.positions; // format de réponse du service : "json" ou "xml" (valeur par défaut), en minuscule ! this.options.outputFormat = (typeof options.outputFormat === "string") ? options.outputFormat.toLowerCase() : "xml"; // ressource utilisée pour le calcul altimétrique this.options.resource = options.resource || "ign_rge_alti_wld"; // sampling this.options.sampling = options.sampling || null; // type d'api utilisé pour requeter le service, en majuscule ! this.options.api = (typeof options.api === "string") ? options.api.toUpperCase() : "REST"; // l'api ne peut être interrogée qu'en GET. if (this.options.api === "REST") { this.options.httpMethod = "GET"; } // param. zonly this.options.zonly = options.zonly || false; // param. measures this.options.measures = options.measures || false; // gestion de l'url du service par defaut // si l'url n'est pas renseignée, il faut utiliser les urls par defaut // en fonction du type d'api, REST ou WPS, du format de reponse demandé (outputFormat) // ainsi que sur le type de service (profil ou elevation) if (!this.options.serverUrl) { var lstUrlByDefault = DefaultUrlService.Alti.newUrl(); var urlFound = null; switch (this.options.api) { case "WPS": urlFound = lstUrlByDefault.wps; break; case "REST": var key = (options.sampling ? "profil" : "elevation") + "-" + this.options.outputFormat; urlFound = lstUrlByDefault[key]; break; default: throw new Error(_.getMessage("PARAM_UNKNOWN", "api")); } if (!urlFound) { throw new Error("Url by default not found !"); } this.options.serverUrl = urlFound; this.logger.trace("Server URL by default : " + this.options.serverUrl); } // gestion du type de service // si l'extension de l'url est .json ou .xml, on surcharge le format de sortie (outputFormat) var idx = this.options.serverUrl.lastIndexOf("."); if (idx !== -1) { var extension = this.options.serverUrl.substring(idx + 1); if (extension && extension.length < 5) { // FIXME extension de moins de 4 car. ... this.logger.trace("Server Extension URL : " + extension); switch (extension.toLowerCase()) { case "json": case "xml": this.options.outputFormat = extension.toLowerCase(); break; default: throw new Error("type of service : unknown or unsupported (json or xml) !"); } } } } /** * @lends module:Alti# */ Alti.prototype = Object.create(CommonService.prototype, { // todo // getter/setter }); /** * Constructeur (alias) */ Alti.prototype.constructor = Alti; /** * Création de la requête (overwrite) * * @param {Function} error - callback des erreurs * @param {Function} success - callback */ Alti.prototype.buildRequest = function (error, success) { // utilisation en mode callback var options = { httpMethod : this.options.httpMethod, // callback onSuccess : function (result) { // sauvegarde de la requete ! this.request = result; success.call(this, this.request); }, onError : error, scope : this, // spécifique au service : resource : this.options.resource, positions : this.options.positions, outputFormat : this.options.outputFormat, sampling : this.options.sampling, api : this.options.api, zonly : this.options.zonly, measures : this.options.measures }; AltiRequestFactory.build(options); }; /** * Analyse de la reponse (overwrite) * * @param {Function} error - callback des erreurs * @param {Function} success - callback */ Alti.prototype.analyzeResponse = function (error, success) { // INFO // Factory pour masquer la complexité du retour du service qui renvoie soit // - une 'string' qui contient du XML ou JSON natif en mode XHR // - un objet JSON qui est natif ou encapsulé if (this.response) { var options = { response : this.response, outputFormat : this.options.outputFormat, // utile pour parser la string en mode XHR : JSON ou XML ! rawResponse : this.options.rawResponse, onError : error, onSuccess : success, scope : this }; AltiResponseFactory.build(options); } else { error.call(this, new ErrorService(_.getMessage("SERVICE_RESPONSE_EMPTY"))); } }; export default Alti;