diff --git a/DRAFT_CHANGELOG.md b/DRAFT_CHANGELOG.md index 1eaee0d7b..9c88b1cdd 100644 --- a/DRAFT_CHANGELOG.md +++ b/DRAFT_CHANGELOG.md @@ -6,11 +6,14 @@ ## Summary +Correctifs sur le profil altimétriques + ## Changelog * [Added] * [Changed] + - Adaptation du style du profil alti par défaut * [Deprecated] @@ -18,11 +21,14 @@ * [Fixed] + - Correctif sur les clics multiple en fin de saisie du profil altimétrique (#298) + * [Security] --- + # Extension Geoportail Leaflet, version __VERSION__ **__DATE__** @@ -30,9 +36,7 @@ ## Summary -* gestion des loggers : -> Exposition de la classe statique *Logger* avec les méthodes suivantes : -`Gp.Logger.disableAll()` et `Gp.Logger.enableAll()` +Reparation du le profil altimétrique ## Changelog @@ -40,27 +44,13 @@ * [Changed] - - mise à jour de la lib. geoportal-access-lib : 2.1.8 - * [Deprecated] * [Removed] - - la dépendance *request* est supprimée, et remplacée par *node-fetch* - * [Fixed] - - Possibilité de activer / desactiver les loggers des API lors de l'utilisation des API en module ES6 : - - ```js - import { Logger } from "geoportal-extensions-leaflet"; - Logger.disableAll(); - ``` - - - corrections des erreurs à partir de DeepScan (#288) - - corrections syntaxiques eslint (da275a2 et 306506a) - - cf. issue : Erreur compilation par webpack [#294](https://github.com/IGNF/geoportal-extensions/issues/294) - - cf. issue : Erreur dépendances à la compilation [#283](https://github.com/IGNF/geoportal-extensions/issues/283) + - Correction et réparation du profil altimétrique de Leaflet (#297) * [Security] @@ -76,7 +66,7 @@ ## Summary -* gestion des loggers : +* gestion des loggers : > Exposition de la classe statique *Logger* avec les méthodes suivantes : `Gp.Logger.disableAll()` et `Gp.Logger.enableAll()` diff --git a/build/scripts/release/geoportal-extensions-openlayers-3.0.15.tgz b/build/scripts/release/geoportal-extensions-openlayers-3.0.15.tgz new file mode 100644 index 000000000..ea1c2fcb3 Binary files /dev/null and b/build/scripts/release/geoportal-extensions-openlayers-3.0.15.tgz differ diff --git a/doc/CHANGELOG-leaflet.md b/doc/CHANGELOG-leaflet.md index f9b89e954..e9eeffb06 100644 --- a/doc/CHANGELOG-leaflet.md +++ b/doc/CHANGELOG-leaflet.md @@ -54,6 +54,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [Extension Geoportail Leaflet, version 2.1.8](#extension-geoportail-leaflet-version-218) * [Summary](#summary-14) * [Changelog](#changelog-11) +- [Extension Geoportail Leaflet, version 2.1.9](#extension-geoportail-leaflet-version-219) + * [Summary](#summary-15) + * [Changelog](#changelog-12) @@ -449,3 +452,45 @@ Nouveau widget de profil altimétrique par défaut, et correctif mineur * [Security] --- +# Extension Geoportail Leaflet, version 2.1.9 + +**26/04/2021** +> Release Extension Geoportail leaflet + +## Summary + +* gestion des loggers : +> Exposition de la classe statique *Logger* avec les méthodes suivantes : +`Gp.Logger.disableAll()` et `Gp.Logger.enableAll()` + +## Changelog + +* [Added] + +* [Changed] + + - mise à jour de la lib. geoportal-access-lib : 2.1.8 + +* [Deprecated] + +* [Removed] + + - la dépendance *request* est supprimée, et remplacée par *node-fetch* + +* [Fixed] + + - Possibilité de activer / desactiver les loggers des API lors de l'utilisation des API en module ES6 : + + ```js + import { Logger } from "geoportal-extensions-leaflet"; + Logger.disableAll(); + ``` + + - corrections des erreurs à partir de DeepScan (#288) + - corrections syntaxiques eslint (da275a2 et 306506a) + - cf. issue : Erreur compilation par webpack [#294](https://github.com/IGNF/geoportal-extensions/issues/294) + - cf. issue : Erreur dépendances à la compilation [#283](https://github.com/IGNF/geoportal-extensions/issues/283) + +* [Security] + +--- diff --git a/package.json b/package.json index c6199a58a..5e79859b1 100644 --- a/package.json +++ b/package.json @@ -2,11 +2,11 @@ "name": "geoportal-extensions", "description": "French Geoportal Extensions for OpenLayers, Leaflet and iTowns libraries", "version": "2.3.5", - "date": "26/04/2021", + "date": "11/05/2021", "leafletExtName": "French Geoportal Extension for Leaflet", "leafletExtVersion": "2.1.9", "olExtName": "French Geoportal Extension for OpenLayers", - "olExtVersion": "3.0.15", + "olExtVersion": "3.0.16", "itownsExtName": "French Geoportal Extension for Itowns", "itownsExtVersion": "2.3.2", "main": "dist/leaflet/GpPluginLeaflet.js, dist/openlayers/GpPluginOpenLayers.js, dist/itowns/GpPluginItowns.js", diff --git a/src/Common/Controls/ProfileElevationPathDOM.js b/src/Common/Controls/ProfileElevationPathDOM.js index 75add5fc0..ba7fb103c 100644 --- a/src/Common/Controls/ProfileElevationPathDOM.js +++ b/src/Common/Controls/ProfileElevationPathDOM.js @@ -19,15 +19,21 @@ var ProfileElevationPathDOM = { * * @param {String} text The text to be rendered. * @param {String} container The container of the text + * @param {String} font The font of the container if known, format: 'weight size familiy' * @returns {Number} The width of the text * * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393 */ - _getTextWidth : function (text, container) { + _getTextWidth : function (text, container, font = null) { // re-use canvas object for better performance var canvas = this.canvas || (this.canvas = document.createElement("canvas")); var context = canvas.getContext("2d"); - context.font = `${this._getCssProperty(container, "font-weight")} ${this._getCssProperty(container, "font-size")} ${this._getCssProperty(container, "font-family")}`; + if (font === null) { + context.font = `${this._getCssProperty(container, "font-weight")} ${this._getCssProperty(container, "font-size")} ${this._getCssProperty(container, "font-family")}`; + } else { + context.font = font; + } + var metrics = context.measureText(text); return metrics.width; }, @@ -148,7 +154,7 @@ var ProfileElevationPathDOM = { const widgetWidth = container.clientWidth - margin.left - margin.right; const zLabelWidth = 17; - const zGradWidth = 8 + this._getTextWidth(Math.round(maxZ).toLocaleString() + ",88", container); + const zGradWidth = this._getTextWidth(Math.round(maxZ).toLocaleString() + ",88", container, "400 10 Verdana"); const xLabelHeight = 17; const xGradHeight = 15; @@ -225,6 +231,9 @@ var ProfileElevationPathDOM = { for (let i = 0; i <= numZguides; i++) { gradZtext = document.createElementNS("http://www.w3.org/2000/svg", "text"); gradZtext.setAttribute("class", "profile-z-graduation"); + gradZtext.setAttribute("font-family", "Verdana"); + gradZtext.setAttribute("font-size", "10px"); + gradZtext.setAttribute("fill", "#5E5E5E"); // Cas où gradZ < 1 : nombres flottants capricieux... // Le Math.round est pour éviter des ennuis du genre 3 * 0.1 = 0.300000000000004 gradZtext.textContent = (Math.round(100 * (minGraphZ + i * gradZ)) / 100).toLocaleString(); @@ -266,6 +275,9 @@ var ProfileElevationPathDOM = { var axisZLegend = document.createElementNS("http://www.w3.org/2000/svg", "text"); axisZLegend.setAttribute("class", "profile-z-legend"); + axisZLegend.setAttribute("font-family", "Verdana"); + axisZLegend.setAttribute("font-size", "11px"); + axisZLegend.setAttribute("fill", "#5E5E5E"); axisZLegend.textContent = "Altitude (m)"; axisZLegend.setAttribute("transform", `translate(${zLabelWidth - 8}, ${Math.round(pathHeight / 2)}) rotate(-90)`); @@ -319,6 +331,9 @@ var ProfileElevationPathDOM = { for (let i = 0; i <= numXguides + 1; i++) { gradXtext = document.createElementNS("http://www.w3.org/2000/svg", "text"); gradXtext.setAttribute("class", "profile-x-graduation"); + gradXtext.setAttribute("font-family", "Verdana"); + gradXtext.setAttribute("font-size", "10px"); + gradXtext.setAttribute("fill", "#5E5E5E"); // Exclusion du cas de la dernière graduation : correspond à la distance max : pas de texte if (i !== numXguides + 1) { @@ -367,6 +382,9 @@ var ProfileElevationPathDOM = { var axisXLegend = document.createElementNS("http://www.w3.org/2000/svg", "text"); axisXLegend.setAttribute("class", "profile-x-legend"); + axisXLegend.setAttribute("font-family", "Verdana"); + axisXLegend.setAttribute("font-size", "11px"); + axisXLegend.setAttribute("fill", "#5E5E5E"); axisXLegend.textContent = `Distance (${distUnit})`; axisXLegend.setAttribute("transform", `translate(${zLabelWidth + zGradWidth + pathWidth / 2}, ${pathHeight + xGradHeight + xLabelHeight + 3})`); @@ -468,7 +486,7 @@ var ProfileElevationPathDOM = { const br2 = document.createElement("br"); const coordsSpan = document.createElement("span"); - tooltipDiv.setAttribute("style", "text-align:center; max-width:220px; font-size:10px; color:#000000; font-family:Verdana;"); + tooltipDiv.setAttribute("style", "text-align:center; max-width:220px; font-size:10px; color:#000000; font-family:Verdana; z-index:50;"); tooltipDiv.style.pointerEvents = "none"; tooltipDiv.style.position = "fixed"; // tooltipDiv.classList.add("tooltipInit"); @@ -606,12 +624,12 @@ var ProfileElevationPathDOM = { let toolTipBubbleD; if (d.dist > (dist * factor) / 2) { - toolTipBubbleD = `M -0.5 -0.5 l -6 6 l 0 16 l -${tooltipTextWidth + 5} 0 l 0 -44 l ${tooltipTextWidth + 5} 0 l 0 16 l 6 6`; - tooltipDivLeft -= tooltipTextWidth; + toolTipBubbleD = `M -0.5 -0.5 l -6 6 l 0 16 l -${tooltipTextWidth + 10} 0 l 0 -44 l ${tooltipTextWidth + 10} 0 l 0 16 l 6 6`; + tooltipDivLeft -= (tooltipTextWidth + 12); } else if (d.dist <= (dist * factor) / 2) { - toolTipBubbleD = `M -0.5 -0.5 l 6 6 l 0 16 l ${tooltipTextWidth + 5} 0 l 0 -44 l -${tooltipTextWidth + 5} 0 l 0 16 l -6 6`; + toolTipBubbleD = `M -0.5 -0.5 l 6 6 l 0 16 l ${tooltipTextWidth + 10} 0 l 0 -44 l -${tooltipTextWidth + 10} 0 l 0 16 l -6 6`; // Largeur de la fleche de la bulle du tooltip - tooltipDivLeft += 15; + tooltipDivLeft += 12; } tooltipBubble.setAttribute("d", toolTipBubbleD); @@ -959,18 +977,18 @@ var ProfileElevationPathDOM = { } } - for (let i = 0; i < _points.length; i++){ - var dist = _points[i].dist; - var coeffArrond = 100; - if (dist > 100) { - coeffArrond = 1; - } else if (dist > 10) { - coeffArrond = 10; - } - - // Correction arrondi distance totale - dist = Math.round(dist * coeffArrond) / coeffArrond; - _points[i].dist = dist; + for (let i = 0; i < _points.length; i++) { + var dist = _points[i].dist; + var coeffArrond = 100; + if (dist > 100) { + coeffArrond = 1; + } else if (dist > 10) { + coeffArrond = 10; + } + + // Correction arrondi distance totale + dist = Math.round(dist * coeffArrond) / coeffArrond; + _points[i].dist = dist; } var settings = { diff --git a/src/Leaflet/Controls/ElevationPath.js b/src/Leaflet/Controls/ElevationPath.js index 912709447..90ea7ae2b 100644 --- a/src/Leaflet/Controls/ElevationPath.js +++ b/src/Leaflet/Controls/ElevationPath.js @@ -752,18 +752,20 @@ var ElevationPath = L.Control.extend(/** @lends L.geoportalControl.ElevationPath var _data = elevations; - // FIXME facteur à 2000 doit il etre une option ? - var _limite = 2000; // metres - var _unit = "km"; - var _factor = 1000; - if (this._distance < _limite) { - _factor = 1; - _unit = "m"; - } + var _unit = "m"; + + var _sketchPoints = this._geometry; + // section actuelle du sketch sur laquelle on est + var _currentSection = 0; + // longueur cumulée des sections précédentes + var _previousSectionsLength = 0; + var _nextSectionBegining = _sketchPoints[1]; // Calcul de la distance au départ pour chaque point + arrondi des lat/lon _data[0].dist = 0; _data[0].slope = 0; + _data[0].lat = Math.round(_data[0].lat * 10000) / 10000; + _data[0].lon = Math.round(_data[0].lon * 10000) / 10000; var _distanceMinus = 0; var _distancePlus = 0; @@ -772,10 +774,22 @@ var ElevationPath = L.Control.extend(/** @lends L.geoportalControl.ElevationPath var _distance = 0; var _slopes = 0; + var distances = []; + for (var i = 1; i < _data.length; i++) { var a = [_data[i].lon, _data[i].lat]; - var b = [_data[i - 1].lon, _data[i - 1].lat]; - var dist = _haversineDistance(a, b); + var distanceToStart = _previousSectionsLength + _haversineDistance(a, [_sketchPoints[_currentSection].lon, _sketchPoints[_currentSection].lat]); + var dist = distanceToStart - _distance; + + // Changement de section + if (a[0].toFixed(8) === _nextSectionBegining.lon.toFixed(8) && a[1].toFixed(8) === _nextSectionBegining.lat.toFixed(8)) { + _currentSection++; + _previousSectionsLength = distanceToStart; + // Pas de next section si on est sur le dernier point + if (i !== _data.length - 1) { + _nextSectionBegining = _sketchPoints[_currentSection + 1]; + } + } var za = _data[i].z; var zb = _data[i - 1].z; @@ -793,8 +807,10 @@ var ElevationPath = L.Control.extend(/** @lends L.geoportalControl.ElevationPath _distancePlus += dist; _ascendingElevation += slope; } - _distance += dist / _factor; - _data[i].dist = _distance; + _distance = distanceToStart; + _data[i].dist = distanceToStart; + + distances.push(distanceToStart); _slopes += (slope) ? Math.abs(Math.round(slope / dist * 100)) : 0; _data[i].slope = (slope) ? Math.abs(Math.round(slope / dist * 100)) : 0; @@ -817,18 +833,8 @@ var ElevationPath = L.Control.extend(/** @lends L.geoportalControl.ElevationPath _data[i].lon = Math.round(_data[i].lon * 10000) / 10000; } - // Valeur du coeff d'arrondi des distances en fonction de la distance totale - var coeffArrond = 100; - if (_distance > 100) { - coeffArrond = 1; - } else if (_distance > 10) { - coeffArrond = 10; - } - - // Correction arrondi distance totale - _distance = Math.round(_distance * coeffArrond) / coeffArrond; - _distanceMinus = Math.round(_distanceMinus * coeffArrond) / coeffArrond; - _distancePlus = Math.round(_distancePlus * coeffArrond) / coeffArrond; + // check distance totale + logger.trace("List Distances", distances); // Correction des altitudes aberrantes + arrondi des calculs de distance + ... var _altMin = _data[0].z; @@ -837,35 +843,30 @@ var ElevationPath = L.Control.extend(/** @lends L.geoportalControl.ElevationPath for (var ji = 0; ji < _data.length; ji++) { var d = _data[ji]; - if (d.z < 0) { + if (d.z < -100) { d.z = 0; } - if (d.z >= _altMax) { + if (d.z > _altMax) { _altMax = d.z; } - if (d.z <= _altMin) { + if (d.z < _altMin) { _altMin = d.z; } - d.dist = Math.round(d.dist * coeffArrond) / coeffArrond; - // FIXME erreur avec D3 car cette lib souhaite un numerique ! - // d.dist = d.dist.toLocaleString(); - if (d.slope > _greaterSlope) { _greaterSlope = d.slope; } } - return { greaterSlope : _greaterSlope, // pente max meanSlope : Math.round(_slopes / _data.length), // pente moyenne - distancePlus : _distancePlus.toLocaleString(), // distance cumulée positive - distanceMinus : _distanceMinus.toLocaleString(), // distance cumulée négative + distancePlus : _distancePlus, // distance cumulée positive + distanceMinus : _distanceMinus, // distance cumulée négative ascendingElevation : _ascendingElevation, // dénivelé cumulée positive descendingElevation : _descendingElevation, // dénivelé cumulée négative - altMin : _altMin.toLocaleString(), // altitude min - altMax : _altMax.toLocaleString(), // altitude max - distance : _distance.toLocaleString(), // distance totale + altMin : _altMin.toLocaleString(), // altitude min TODO: inutile ? + altMax : _altMax.toLocaleString(), // altitude max TODO: inutile ? + distance : this._distance, // distance totale unit : _unit, // unité des mesures de distance points : _data }; diff --git a/src/OpenLayers/Controls/ElevationPath.js b/src/OpenLayers/Controls/ElevationPath.js index 2e92bccef..46b4a1c3b 100644 --- a/src/OpenLayers/Controls/ElevationPath.js +++ b/src/OpenLayers/Controls/ElevationPath.js @@ -935,7 +935,8 @@ var ElevationPath = (function (Control) { this._measureDraw = new DrawInteraction({ source : this._measureSource, type : "LineString", - style : this._drawStyleStart + style : this._drawStyleStart, + stopClick : true }); this._measureDraw.setProperties({ @@ -994,6 +995,7 @@ var ElevationPath = (function (Control) { } // set an alti request and display results + this._measureDraw.setActive(false); this._requestService(); }); }; @@ -1190,6 +1192,7 @@ var ElevationPath = (function (Control) { self._displayProfile(result.elevations); self._waitingContainer.className = "GPelevationPathCalcWaitingContainerHidden"; self._waiting = false; + self._measureDraw.setActive(true); } }; @@ -1201,6 +1204,7 @@ var ElevationPath = (function (Control) { logger.error(error.message); self._waitingContainer.className = "GPelevationPathCalcWaitingContainerHidden"; self._waiting = false; + self._measureDraw.setActive(true); }; Utils.mergeParams(options, { @@ -1398,6 +1402,8 @@ var ElevationPath = (function (Control) { // sauvegarde des données var data = this._data = this._computeElevationMeasure(elevations); + this._updateInfoContainer(); + // container var container = this.options.displayProfileOptions.target; if (container) { @@ -1428,6 +1434,51 @@ var ElevationPath = (function (Control) { } }; + /** + * update info container + * + * @private + */ + ElevationPath.prototype._updateInfoContainer = function () { + logger.trace("ElevationPath::_updateInfoContainer"); + + // options d'affichage + var totalDistance = this.options.displayProfileOptions.totalDistance; + var meanSlope = this.options.displayProfileOptions.meanSlope; + var greaterSlope = this.options.displayProfileOptions.greaterSlope; + var ascendingElevation = this.options.displayProfileOptions.ascendingElevation; + var descendingElevation = this.options.displayProfileOptions.descendingElevation; + + // clean + var div = this._infoContainer; + if (div.childElementCount) { + while (div.firstChild) { + div.removeChild(div.firstChild); + } + } + + // creation des infomations + if (totalDistance) { + this._addElevationPathInformationsItem("Distance totale : " + Math.round(this._data.distance).toLocaleString() + " m"); + } + + if (ascendingElevation) { + this._addElevationPathInformationsItem("Dénivelé positif : " + this._data.ascendingElevation.toLocaleString() + " m"); + } + + if (descendingElevation) { + this._addElevationPathInformationsItem("Dénivelé négatif : " + this._data.descendingElevation.toLocaleString() + " m"); + } + + if (meanSlope) { + this._addElevationPathInformationsItem("Pente moyenne : " + this._data.meanSlope.toLocaleString() + " %"); + } + + if (greaterSlope) { + this._addElevationPathInformationsItem("Plus forte pente : " + this._data.greaterSlope.toLocaleString() + " %"); + } + }; + // ################################################################### // // ####################### handlers events to dom #################### // // ################################################################### // @@ -1470,41 +1521,8 @@ var ElevationPath = (function (Control) { * @private */ ElevationPath.prototype.onOpenElevationPathInfoClick = function () { - // options d'affichage - var totalDistance = this.options.displayProfileOptions.totalDistance; - var meanSlope = this.options.displayProfileOptions.meanSlope; - var greaterSlope = this.options.displayProfileOptions.greaterSlope; - var ascendingElevation = this.options.displayProfileOptions.ascendingElevation; - var descendingElevation = this.options.displayProfileOptions.descendingElevation; - // clean var div = this._infoContainer; - if (div.childElementCount) { - while (div.firstChild) { - div.removeChild(div.firstChild); - } - } - - // creation des infomations - if (totalDistance) { - this._addElevationPathInformationsItem("Distance totale : " + Math.round(this._data.distance).toLocaleString() + " m"); - } - - if (ascendingElevation) { - this._addElevationPathInformationsItem("Dénivelé positif : " + this._data.ascendingElevation.toLocaleString() + " m"); - } - - if (descendingElevation) { - this._addElevationPathInformationsItem("Dénivelé négatif : " + this._data.descendingElevation.toLocaleString() + " m"); - } - - if (meanSlope) { - this._addElevationPathInformationsItem("Pente moyenne : " + this._data.meanSlope.toLocaleString() + " %"); - } - - if (greaterSlope) { - this._addElevationPathInformationsItem("Plus forte pente : " + this._data.greaterSlope.toLocaleString() + " %"); - } // show des informations ! if (div.className === "GPelevationPathInformationsContainerVisible") {