Skip to content

Commit

Permalink
Switch 2D<->3D des widgets de calculs (itineraire, iso, ...) (#100)
Browse files Browse the repository at this point in the history
Persistance des couches issues de calculs entre la 2D/3D (itineraire, iso, ...)
  • Loading branch information
lowzonenose authored Feb 22, 2023
1 parent 0d38bf2 commit c24d373
Show file tree
Hide file tree
Showing 11 changed files with 540 additions and 21 deletions.
5 changes: 5 additions & 0 deletions DRAFT_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@
## Summary

Maj des extensions OpenLayers : 3.2.20

## Changelog

* [Added]

- Possibilité de charger un KML, GPX ou GeoJSON directement avec les données sans passer par une URL en utilisant l'option *layerOptions:data*
> Persistance des tracés de calcul (itineraire et iso) entre la 2D / 3D

* [Changed]

* [Removed]
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"expose-loader": "^0.7.5",
"fs-extra": "^9.0.0",
"geoportal-extensions-itowns": "2.3.10",
"geoportal-extensions-openlayers": "3.2.19",
"geoportal-extensions-openlayers": "3.2.20",
"handlebars": "^4.7.5",
"handlebars-layouts": "^3.1.4",
"html-webpack-plugin": "^4.0.4",
Expand Down
19 changes: 9 additions & 10 deletions samples-src/pages/2d/page-pdf-bundle.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{{/content}}

{{#content "vendor"}}
<script src="{{ resources }}/vendor/jspdf.min.js"></script>
<script src="{{ resources }}/vendor/jspdf.umd.min.js"></script>
{{/content}}

{{#content "style"}}
Expand Down Expand Up @@ -39,28 +39,27 @@ <h2>Contrôle de l'azimuth</h2>
function printRender() {
map.getLibMap().once('rendercomplete', function(event) {
const { jsPDF } = window.jspdf;
var canvas = event.context.canvas;

// var canvas = document.createElement('canvas');
// var canvas = event.context.canvas;
var canvas = document.querySelector("canvas");
var size = map.getLibMap().getSize();
canvas.width = size[0];
canvas.height = size[1];
ctx = canvas.getContext('2d');
ctx.fillStyle = 'blue';
ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.globalAlpha = 1;
var c = document.querySelector("canvas");
ctx.drawImage(c, 0, 0, canvas.width, canvas.height);
ctx.fillRect(0,0,100,100);
ctx.globalAlpha = 0.5;
ctx.drawImage(canvas, 0, 0, 100, 100);
// ctx.restore();
ctx.save();

var data = canvas.toDataURL('image/png');
var data = canvas.toDataURL('image/jpeg', 1.0);
var pdf = new jsPDF({
orientation: 'landscape',
unit :'mm',
format : 'a4'
});
pdf.addImage(data, 'PNG', 0, 0, canvas.width, canvas.height);
console.log(data);
pdf.addImage(data, 'JPEG', 0, 0, canvas.width, canvas.height);
pdf.save("download.pdf");

});
Expand Down
11 changes: 5 additions & 6 deletions samples-src/pages/3d/page-pdf-bundle.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{{#extend "sample-bundle-layout-3d"}}

{{#content "head"}}
<title>Sample SDK 3D PDF</title>
<title>Sample SDK 3D PDF (failed)</title>
{{/content}}

{{#content "vendor"}}
<script src="{{ resources }}/vendor/jspdf.min.js"></script>
<script src="{{ resources }}/vendor/jspdf.umd.min.js"></script>
{{/content}}

{{#content "style"}}
Expand Down Expand Up @@ -48,14 +48,13 @@ <h2>Carte 3D.</h2>
// You can try to render the PDF on a canvas element via PDF.js and then use it
// to create an instance of THREE.CanvasTexture for a plane mesh.
function printRender() {
var imgData = map.getLibMap().getGlobeView().mainLoop.gfxEngine.getRenderer().domElement.toDataURL("image/jpeg", 1.0);
// option preserveDrawingBuffer !?
// renderer = new THREE.WebGLRenderer( { preserveDrawingBuffer: true } );
var render = map.getLibMap().getGlobeView().mainLoop.gfxEngine.getRenderer();
var imgData = render.domElement.toDataURL('image/jpeg', 1.0);

console.log(imgData);
const { jsPDF } = window.jspdf;
var pdf = new jsPDF();
pdf.addImage(imgData, 'JPEG', 0, 0);
pdf.addImage(imgData, 'JPEG', 100, 100, 100, 100);
pdf.save("download.pdf");
};

Expand Down
3 changes: 2 additions & 1 deletion samples-src/pages/3d/page-switch-bundle.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
{{#content "style"}}
<style>
#geoportalMap1 {
height: 400px;
height: 600px;
width: 600px;
position:relative;
display:"inline";
Expand Down Expand Up @@ -92,6 +92,7 @@ <h1>Test de la bascule 3D / 2D</h1>
maximised : true
},
route : {},
isocurve : {},
layerimport : {},
mousePosition : {
// div : "extControlDiv",
Expand Down
398 changes: 398 additions & 0 deletions samples-src/resources/vendor/jspdf.umd.min.js

Large diffs are not rendered by default.

97 changes: 96 additions & 1 deletion src/Interface/IMapBase.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
/* global __SWITCH2D3D_ALLOWED__ */
import Logger from "../Utils/LoggerByDefault";
import { transform as olTransformProj } from "ol/proj";
import { Services, ProxyUtils } from "geoportal-extensions-openlayers";
import {
Services,
ProxyUtils
} from "geoportal-extensions-openlayers";
import { MapLoader } from "../Utils/MapLoader";

/**
Expand Down Expand Up @@ -31,6 +34,64 @@ var switch2D3D = function (viewMode) {
oldMap.enableRotation = this.mapOptions.enableRotation !== undefined ? this.mapOptions.enableRotation : null;
oldMap.mapEventsOptions = this.mapOptions.mapEventsOptions !== undefined ? this.mapOptions.mapEventsOptions : null;

// add all compute layer to 3D map with layersOptions
if (viewMode === "3d") {
for (var index = 0; index < this._layers.length; index++) {
var layer = this._layers[index];
// traitement des couches de calcul
if (layer.options.format.toUpperCase() === "COMPUTE") {
// TODO :
// transmettre les bons styles à la couche 2D->3D
// isocurve = fill-color : "rgba(0, 183, 152, 0.7)"
// itineraire = stroke-color : "rgba(0,183,152,0.9)",
// stroke-width : 12

// les controles fournissent leurs méta-informations utiles à leur reconstruction en 2D.
// les infos issues de la methode getData() :
// * point de départ
// * point intermédiares
// * point d'arrivée
// * mode de transport
// * mode de calcul
// * passage
// * résultats
// idem pour la couche..., on récupere uniquement le tracé au format GeoJSON.
// la couche au format natif n'est pas utile pour la switch 2D<->3D.
var geojsonStr = null;
var geojsonObj = null;
switch (layer.options.control) {
case "Itineraire":
oldMap.layersOptions[layer.id].controlOptions = this.getLibMapControl("route").getData();
geojsonStr = this.getLibMapControl("route").getGeoJSON();
geojsonObj = JSON.parse(geojsonStr);
geojsonObj.features.forEach(feature => {
if (feature.geometry.type === "Point") {
feature.properties.icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAmCAYAAABpuqMCAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAQxSURBVFiF3ZldaBxVFMd/d2ayTRtjQpo2mlilWBEMshoj+FAERZIHIdA3iw+V1icRREFIQAKNgsUHQfBFwZI2WgWxqYUiVTDBBj9ILC5Nu2tjdjemsR+mSZNNNvsxO8eHTTRuk+zMnQmCf9iHnXvO+Z//nDvn3rmjRIT/C6zAI4ZVFRbtKDpQNCM0AvXANIo/EC4inMbmLBFZDJJaBVaZJ9Sd2HQCrwDbXHikgfewOMKPMh9ECsGIeVx1IHxEsQJeMY3iEMNy2m8aht8AtKpOhH70hADUI/TTqjr9puKvMsUE3vabxCp0MSJHdJ31xRSnVj9BVPcfOCj26U45PTHFh30c/am1EaaxuF+nKejd1WLX2gwhAPXL8T3De2XCqooKbuCu/eoiTZ6dXtch75WxaMeNENOyOXx8kHOpGMPOIudSMQ4fH8S0bBcs25Z5PMF7ZVpVL3BgQxvTsvn6+kVq6sK3jc3NRGhraKZgl9t9HGNEXvCSmvfKKJrL2nQfHVpTCEBNXZjuo0OB8JTAu5jiXmtjPL3vLl/jbnlKoNPN6spaVFbt8jXulqcEOmKSZS0yi5O+xt3ylEBHTLSsxbf913yNu+UpgU4DKE/Sc3AvczORNcfmZiL0HNwbCE8JvItxWDvJ1SjYFm0NzZzpG2RpIYbIIksLMc70Dbpsy+54SqCzzlQAY8B9Xsk8YAJ4gBHJe3HyXpkRyaN407OfN7zlVQjobjTv4BgQ1/ItjzjV9Oo46okZEBuhS8u3PDoZEDf7t9vg903zBLBfP8C/4cAnD87teclIGyFlLoVyllWh8vmQYRgVAOI4OQmFciKSFZFsMpmck1UC/Il5VNViEgHu9StkQYyb7bNNH1wrmDm3PgqWUHLBhl+SyeRV/6czLepJDAbw8fos4HTNb+/9PFv9u3YMU/X6f38/L98B7/gJ8U2uasiPEADTcRqDOozoBn7WcbzqmFOvpnYM+uTPpvP5SDBiimvP8xRPKV3DFpV7fX7HyYyD44M96xicmpqaSgd3TDQsv6J4zYvLx5nqsz/kK29qcyq5kFpafD+RSMSKf4P+CvCY+hJFRzmzmB2KPTvb+JnX8CsdzDGM8/F4/PrqseC/AggvZlGXtyipXc8kLcbCy6mdrg/6lBIbR41DYXR8cjIqIoW17IIXc17+nHnEOnS3VfhiHQt5d7HmVMK2Nn6+DHLiOGMmRLdMVI+NymjZ9Sf4abaMqZbQp01G/rnS60P5rT8duNXw1TpuGaXksmMYlxKJxLiIt23NponhKVV5a874rdZwmlYuTTvmjWdmGj9Mifl3kkpJ2hGJGY4THb9yJS4i2p0t+Gm2ggHJxMNb94eNzIAJZgEKbyxsP5kS00ZJSkG0oFQ0mZyYkKDuqIhs6u/7hyt75luM2RMPVfft3rW7bU9T0z2bxbV50+w/wF8f81R5OpwBhwAAAABJRU5ErkJggg==";
}
});
oldMap.layersOptions[layer.id].data = JSON.stringify(geojsonObj);
break;
case "Isocurve":
oldMap.layersOptions[layer.id].controlOptions = this.getLibMapControl("isocurve").getData();
geojsonStr = this.getLibMapControl("isocurve").getGeoJSON();
geojsonObj = JSON.parse(geojsonStr);
geojsonObj.features.forEach(feature => {
if (feature.geometry.type === "Point") {
feature.properties.icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAmCAYAAABpuqMCAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAQxSURBVFiF3ZldaBxVFMd/d2ayTRtjQpo2mlilWBEMshoj+FAERZIHIdA3iw+V1icRREFIQAKNgsUHQfBFwZI2WgWxqYUiVTDBBj9ILC5Nu2tjdjemsR+mSZNNNvsxO8eHTTRuk+zMnQmCf9iHnXvO+Z//nDvn3rmjRIT/C6zAI4ZVFRbtKDpQNCM0AvXANIo/EC4inMbmLBFZDJJaBVaZJ9Sd2HQCrwDbXHikgfewOMKPMh9ECsGIeVx1IHxEsQJeMY3iEMNy2m8aht8AtKpOhH70hADUI/TTqjr9puKvMsUE3vabxCp0MSJHdJ31xRSnVj9BVPcfOCj26U45PTHFh30c/am1EaaxuF+nKejd1WLX2gwhAPXL8T3De2XCqooKbuCu/eoiTZ6dXtch75WxaMeNENOyOXx8kHOpGMPOIudSMQ4fH8S0bBcs25Z5PMF7ZVpVL3BgQxvTsvn6+kVq6sK3jc3NRGhraKZgl9t9HGNEXvCSmvfKKJrL2nQfHVpTCEBNXZjuo0OB8JTAu5jiXmtjPL3vLl/jbnlKoNPN6spaVFbt8jXulqcEOmKSZS0yi5O+xt3ylEBHTLSsxbf913yNu+UpgU4DKE/Sc3AvczORNcfmZiL0HNwbCE8JvItxWDvJ1SjYFm0NzZzpG2RpIYbIIksLMc70Dbpsy+54SqCzzlQAY8B9Xsk8YAJ4gBHJe3HyXpkRyaN407OfN7zlVQjobjTv4BgQ1/ItjzjV9Oo46okZEBuhS8u3PDoZEDf7t9vg903zBLBfP8C/4cAnD87teclIGyFlLoVyllWh8vmQYRgVAOI4OQmFciKSFZFsMpmck1UC/Il5VNViEgHu9StkQYyb7bNNH1wrmDm3PgqWUHLBhl+SyeRV/6czLepJDAbw8fos4HTNb+/9PFv9u3YMU/X6f38/L98B7/gJ8U2uasiPEADTcRqDOozoBn7WcbzqmFOvpnYM+uTPpvP5SDBiimvP8xRPKV3DFpV7fX7HyYyD44M96xicmpqaSgd3TDQsv6J4zYvLx5nqsz/kK29qcyq5kFpafD+RSMSKf4P+CvCY+hJFRzmzmB2KPTvb+JnX8CsdzDGM8/F4/PrqseC/AggvZlGXtyipXc8kLcbCy6mdrg/6lBIbR41DYXR8cjIqIoW17IIXc17+nHnEOnS3VfhiHQt5d7HmVMK2Nn6+DHLiOGMmRLdMVI+NymjZ9Sf4abaMqZbQp01G/rnS60P5rT8duNXw1TpuGaXksmMYlxKJxLiIt23NponhKVV5a874rdZwmlYuTTvmjWdmGj9Mifl3kkpJ2hGJGY4THb9yJS4i2p0t+Gm2ggHJxMNb94eNzIAJZgEKbyxsP5kS00ZJSkG0oFQ0mZyYkKDuqIhs6u/7hyt75luM2RMPVfft3rW7bU9T0z2bxbV50+w/wF8f81R5OpwBhwAAAABJRU5ErkJggg==";
}
});
oldMap.layersOptions[layer.id].data = JSON.stringify(geojsonObj);
break;
default:
// TODO other format...
// * les mesures
// * profil alti
break;
}
}
}
}

// remove old controls and associated listeners
for (var controlId in oldMap.controlsOptions) {
this.removeControls(controlId);
Expand Down Expand Up @@ -224,6 +285,40 @@ var switch2D3D = function (viewMode) {
mapEventsOptions : oldMap.mapEventsOptions
}
);

// une fois la carte chargée en 2D, on reconstruit les controles avec les couches
// de calcul...
if (viewMode === "2d") {
newMap.listen("mapLoaded", function () {
for (var i = 0; i < this._layers.length; i++) {
var clayer = this._layers[i];
// traitement des couches de calcul
if (clayer.options.format.toUpperCase() === "COMPUTE") {
var control = null;
switch (clayer.options.control) {
case "Itineraire":
control = this.getLibMapControl("route");
break;
case "Isocurve":
control = this.getLibMapControl("isocurve");
break;
default:
// TODO other format...
// * les mesures
// * profil alti
break;
}
if (control) {
control.setData(clayer.options.controlOptions);
control.setLayer(clayer.obj);
control.setGeoJSON(clayer.options.data); // inutile ?
control.init();
}
}
}
});
}

return newMap;
};

Expand Down
1 change: 1 addition & 0 deletions src/Interface/IMapLayers.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ IMap.prototype.addLayers = function (layersOptions) {
case "GEORSS":
// TODO GeoRSS
break;
case "COMPUTE":
case "KML":
case "GPX":
case "GEOJSON":
Expand Down
5 changes: 4 additions & 1 deletion src/Itowns/ItMapControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,10 @@ ItMap.prototype.addLayerSwitcherControl = function (controlOpts) {
for (var i = 0; i < this._layers.length; i++) {
var layer = this._layers[i];
// Si la couche est un MNT, on ne l'ajoute pas au layerSwitcher
if (layer.obj.type !== "color" && !layer.obj.isColorLayer) {
if (layer.options.format.toLowerCase() !== "kml" &&
layer.options.format.toLowerCase() !== "compute" &&
layer.obj.type !== "color" &&
!layer.obj.isColorLayer) {
continue;
}
this.logger.trace("[ItMap] : layerSwitcher : configuring layer : " + layer.id);
Expand Down
1 change: 1 addition & 0 deletions src/Itowns/ItMapLayers.js
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ ItMap.prototype._addVectorLayer = function (layerObj) {
};
}
break;
case "COMPUTE":
case "GEOJSON":
this.logger.trace("ajout d'une couche GEOJSON");
layer.source = new FileSource({
Expand Down
19 changes: 18 additions & 1 deletion src/OpenLayers/OlMapLayers.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ OlMap.prototype._addVectorLayer = function (layerObj) {
case "GEORSS":
// TODO GeoRSS
break;
case "COMPUTE":
case "GEOJSON":
this.logger.trace("[_addVectorLayer] : ajout d'une couche GeoJSON");
if (layerOpts.url) {
Expand Down Expand Up @@ -734,7 +735,7 @@ OlMap.prototype._getLayerOpts = function (layerObj, layersStack) {
* @returns {Object} - new layer index in this._layers
*/
OlMap.prototype._registerUnknownLayer = function (layerObj) {
// couches de résultat (itineraire, isochrone)
// couches de résultats ou de calcul (itineraire, isochrone, ...)
var layerId = "unknownLayer";
if (layerObj.hasOwnProperty("gpResultLayerId")) {
// isochrones : [GraphName]$GEOPORTAIL:GPP:Isocurve
Expand Down Expand Up @@ -776,6 +777,22 @@ OlMap.prototype._registerUnknownLayer = function (layerObj) {
} else if (layerId.indexOf("layerimport:MAPBOX") === 0) {
options.format = "MAPBOX";
}

if (layerObj.hasOwnProperty("gpResultLayerId")) {
// result layer name
options.format = "COMPUTE";
// graph name (voiture / pieton)
options.graph = layerObj.gpResultLayerId.split(/[$:;]/)[0];
// control name (isocurve / itineraire)
options.control = layerObj.gpResultLayerId.split(/[$:;]/).slice(-1)[0];
// title by default
options.title = options.control + " (" + options.graph + ")";
// options control
options.controlOptions = {};
// features to geojson
options.data = {};
}

this._layers.push({
id : layerId,
obj : layerObj,
Expand Down

0 comments on commit c24d373

Please sign in to comment.