geoportal-access-lib
Version:
French Geoportal resources access library
248 lines (220 loc) • 9.24 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 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;