Skip to content

Commit

Permalink
feat: move 3d to layer catalogue instead of button
Browse files Browse the repository at this point in the history
  • Loading branch information
azarz committed Jan 16, 2025
1 parent 896cb9f commit 8defc27
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 52 deletions.
9 changes: 0 additions & 9 deletions src/css/map-buttons.css
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,6 @@
bottom: 132px;
}

#threeDBtn {
position: absolute;
top: calc(130px + var(--safe-area-inset-top));
font-family: "Open Sans Semibold";
display: flex;
align-items: center;
justify-content: center;
}

#filterPoiBtn {
background-image: url("assets/map-buttons/filtrer.svg");
position: fixed;
Expand Down
Binary file added src/html/img/layers/3D.BUILDINGS.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/html/img/layers/3D.TERRAIN.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 0 additions & 2 deletions src/html/mapButtons.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
<div class="button d-none" id="backTopLeftBtn" tabindex="2" title="Retour arrière" role="button"></div>
<!-- Filtres POI -->
<div class="button" id="filterPoiBtn" tabindex="3" role="button">Filtres</div>
<!-- 3D -->
<div class="button" id="threeDBtn" tabindex="7" title="Activer la 3D" role="button">3D</div>
<!-- Mode de comparaison de carte -->
<div id="compareMode" class="d-none">
<div id="compareLeftRight" title="Comparer horizontalement" class="selected" tabindex="4" role="button"></div>
Expand Down
1 change: 1 addition & 0 deletions src/js/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ const addControls = () => {

// 3d
Globals.threeD = new ThreeD(map, {});
Globals.manager.layerCatalogue.add3DThematicLayers();

// contrôle filtres POI
Globals.poi = new POI(map, {});
Expand Down
2 changes: 1 addition & 1 deletion src/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ function app() {
attributionControl: false,
maxZoom: 21,
locale: "fr",
maxPitch: 45,
maxPitch: 60,
crossSourceCollisions: false,
});

Expand Down
101 changes: 101 additions & 0 deletions src/js/layer-manager/layer-catalogue.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import LayersConfig from "./layer-config";
import LayersAdditional from "./layer-additional";

import ImageNotFound from "../../html/img/image-not-found.png";
import ReliefBuildingsImage from "../../html/img/layers/3D.BUILDINGS.jpg";
import ReliefTerrainImage from "../../html/img/layers/3D.TERRAIN.jpg";
import DomUtils from "../utils/dom-utils";

import { Toast } from "@capacitor/toast";
Expand Down Expand Up @@ -153,6 +155,105 @@ class LayerCatalogue extends EventTarget {
target.appendChild(container);
}

/**
* Ajout de 2 faux "Layers" 3D qui n'apparaissent pas dans le Layer Switcher et du bouton 3D pour les filtrer
* - Bâtiments 3D
* - Relief
*/
add3DThematicLayers() {
var target = this.options.target || document.getElementById("layer-thematics");
if (!target) {
console.warn();
return;
}
var container = target.querySelector("#thematicLayers");

var buildings3DLayerHtml = `
<div class="layer thematicLayer" id="3D.BUILDINGS">
<div class="layerImg">
<img src="${ReliefBuildingsImage}" alt="Bâtiments 3D" onerror="this.onerror=null;this.src='${ImageNotFound}'" />
<div class="layer-badge"></div>
<div class="layer-interactive-badge-false"></div>
</div>
<div class="layer-title-thematic">3D</div>
<div id="3d-buildings" class="layer-title">Bâtiments 3D</div>
</div>
`;
var buildings3DLayerElement = DomUtils.stringToHTML(buildings3DLayerHtml.trim());
buildings3DLayerElement.addEventListener("click", () => {
if (buildings3DLayerElement.classList.contains("selectedLayer")) {
Globals.threeD.remove3dBuildings();
buildings3DLayerElement.classList.remove("selectedLayer");
} else {
Globals.threeD.add3dBuildings();
buildings3DLayerElement.classList.add("selectedLayer");
}
});
container.appendChild(buildings3DLayerElement);

var terrainLayerHtml = `
<div class="layer thematicLayer" id="3D.TERRAIN">
<div class="layerImg">
<img src="${ReliefTerrainImage}" alt="Relief 3D" onerror="this.onerror=null;this.src='${ImageNotFound}'" />
<div class="layer-badge"></div>
<div class="layer-interactive-badge-false"></div>
</div>
<div class="layer-title-thematic">3D</div>
<div id="3d-terrain" class="layer-title">Relief 3D</div>
</div>
`;
var terrainLayerElement = DomUtils.stringToHTML(terrainLayerHtml.trim());
terrainLayerElement.addEventListener("click", () => {
if (terrainLayerElement.classList.contains("selectedLayer")) {
Globals.threeD.remove3dTerrain();
terrainLayerElement.classList.remove("selectedLayer");
} else {
Globals.threeD.add3dTerrain();
terrainLayerElement.classList.add("selectedLayer");
}
});
container.appendChild(terrainLayerElement);

// Ajout de la pastille de filtre "3D"
var buttonsContainer = target.querySelector("#thematicButtons");
var buttonElement = DomUtils.stringToHTML(`
<button class="thematicButton" data-name="3D">
3D
</button>
`.trim());

buttonElement.addEventListener("click", (e) => {
var buttons = document.querySelectorAll(".thematicButton");
for (let h = 0; h < buttons.length; h++) {
const element = buttons[h];
element.classList.remove("thematic-button-active");
}
var layers = document.querySelectorAll(".thematicLayer");
for (let i = 0; i < layers.length; i++) {
const element = layers[i];
element.classList.add("layer-hidden");
}
var layersId = ["3D.BUILDINGS", "3D.TERRAIN"];
for (let j = 0; j < layersId.length; j++) {
const id = layersId[j];
var element = document.getElementById(id);
element.classList.remove("layer-hidden");
}
e.target.classList.add("thematic-button-active");
});
buttonsContainer.firstElementChild.after(buttonElement);

// Ajoute le réaffichage des boutons 3D au click sur la pastille "Tous"
buttonsContainer.querySelector("[data-name=Tous]").addEventListener("click", () => {
var layersId = ["3D.BUILDINGS", "3D.TERRAIN"];
for (let j = 0; j < layersId.length; j++) {
const id = layersId[j];
var element = document.getElementById(id);
element.classList.remove("layer-hidden");
}
});
}

/**
* Ecouteurs
*/
Expand Down
6 changes: 5 additions & 1 deletion src/js/layer-manager/layer-switcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ class LayerSwitcher extends EventTarget {
this.layers[id].style = data_2.layers; // sauvegarde !
} catch (e) {
if (fallback) {
fetchStyle(fallback, null);
await fetchStyle(fallback, null);
} else {
this.layers[id].error = true;
throw new Error(e);
Expand Down Expand Up @@ -680,6 +680,10 @@ class LayerSwitcher extends EventTarget {
this.#setColor(id, !layerOptions.gray);
}
this.#setVisibility(id, layerOptions.visible);
// Cas particulier : ajout de l'ombrage à plan IGN si la 3D est activée
if (id === "PLAN.IGN.INTERACTIF$GEOPORTAIL:GPP:TMS" && Globals.threeD && Globals.threeD.terrainOn) {
Globals.threeD.addHillShadeToPlanIgn();
}
/**
* Evenement "addlayer"
* @event addlayer
Expand Down
22 changes: 0 additions & 22 deletions src/js/map-buttons-listeners.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,28 +89,6 @@ const addListeners = () => {
}
});

// Toggle 3D
DOM.$threeDBtn.addEventListener("click", () => {
if (Globals.threeD.on) {
Globals.threeD.remove3dBuildings();
Globals.threeD.remove3dTerrain();
if (!Location.isTrackingActive()) {
Globals.map.flyTo({
pitch: 0,
duration: 500,
});
setTimeout( () => {Globals.map.setMaxPitch(0)}, 500);
}
} else {
Globals.map.setMaxPitch(80);
Globals.threeD.add3dBuildings();
Globals.threeD.add3dTerrain();
Globals.map.flyTo({
pitch: 45,
duration: 500,
});
}
});
};

export default {
Expand Down
42 changes: 25 additions & 17 deletions src/js/three-d.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const hillsLayer = {
type: "hillshade",
source: "bil-terrain",
layout: {visibility: "visible"},
paint: {"hillshade-shadow-color": "#473B24"}
paint: {"hillshade-shadow-color": "#473B24"},
metadata: {group: "PLAN.IGN.INTERACTIF$GEOPORTAIL:GPP:TMS"},
}

/**
Expand All @@ -37,8 +38,7 @@ class ThreeD {
this.map = map;

this.buildingsLayers = [];

this.on = false;
this.terrainOn = false;

return this;
}
Expand Down Expand Up @@ -117,17 +117,25 @@ class ThreeD {

// Set terrain using the custom source
Globals.map.setTerrain({ source: 'bil-terrain', exaggeration: 1.5 });
Globals.map.setSky({
"sky-color": "#199EF3",
"fog-ground-blend": 0.8,
});
this.addHillShadeToPlanIgn();
this.terrainOn = true;
}

addHillShadeToPlanIgn() {
if (Globals.map.getLayer(hillsLayer.id)) {
return;
}
// HACK
// on positionne toujours le style avant ceux du calcul d'itineraires (directions)
// afin que le calcul soit toujours la couche visible du dessus !
var layerIndexBefore = Globals.map.getStyle().layers.findIndex((l) => l.source === "maplibre-gl-directions");
// on positionne toujours le layer après la dernière couche de PLAN IGN
var beforeId = "detail_hydrographique$$$PLAN.IGN.INTERACTIF$GEOPORTAIL:GPP:TMS";
if (!Globals.map.getLayer(beforeId)) {
return;
}
var layerIndexBefore = Globals.map.getStyle().layers.findIndex((l) => l.id === beforeId) + 1;
var layerIdBefore = (layerIndexBefore !== -1) ? Globals.map.getStyle().layers[layerIndexBefore].id : null;
Globals.map.addLayer(hillsLayer, layerIdBefore);
this.on = true;
if (layerIdBefore) {
Globals.map.addLayer(hillsLayer, layerIdBefore);
}
}

async add3dBuildings() {
Expand All @@ -137,25 +145,25 @@ class ThreeD {
// HACK
// on positionne toujours le style avant ceux du calcul d'itineraires (directions)
// afin que le calcul soit toujours la couche visible du dessus !
var layerIndexBefore = Globals.map.getStyle().layers.findIndex((l) => l.source === "maplibre-gl-directions");
var layerIndexBefore = Globals.map.getStyle().layers.findIndex((l) => l.source === "maplibre-gl-directions") + 1;
var layerIdBefore = (layerIndexBefore !== -1) ? Globals.map.getStyle().layers[layerIndexBefore].id : null;
this.buildingsLayers.forEach((layer) => {
Globals.map.addLayer(layer, layerIdBefore);
});
this.on = true;
}

remove3dBuildings() {
this.buildingsLayers.forEach((layer) => {
Globals.map.removeLayer(layer.id);
})
this.on = false;
}

remove3dTerrain() {
Globals.map.setTerrain();
Globals.map.removeLayer(hillsLayer.id);
this.on = false;
if (Globals.map.getLayer(hillsLayer.id)) {
Globals.map.removeLayer(hillsLayer.id);
}
this.terrainOn = false;
}
}

Expand Down

0 comments on commit 8defc27

Please sign in to comment.