From 2cdf24e8044a286b34f56b24acd5bb2808acbe66 Mon Sep 17 00:00:00 2001 From: mattiapezzotti Date: Sat, 8 Jun 2024 17:50:24 +0200 Subject: [PATCH] 360 photos now keep heading between sequences, added hd checkbox --- css/60_photos.css | 13 ++++ data/core.yaml | 2 + modules/services/panoramax.js | 115 ++++++++++++++++++++------------ modules/svg/panoramax_images.js | 14 +++- 4 files changed, 100 insertions(+), 44 deletions(-) diff --git a/css/60_photos.css b/css/60_photos.css index dcd567111..9f0893a53 100644 --- a/css/60_photos.css +++ b/css/60_photos.css @@ -349,6 +349,19 @@ overflow: hidden } +label.panoramax-hd { + float: left; + cursor: pointer; +} +.panoramax-hd span { + margin-top: 2px; +} +.panoramax-hd input[type="checkbox"] { + width: 12px; + height: 12px; + margin: 0 5px; +} + /* Streetside Viewer (pannellum) */ .ms-wrapper .photo-attribution .image-link { diff --git a/data/core.yaml b/data/core.yaml index f0ed90d24..806488a52 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -1452,6 +1452,8 @@ en: panoramax: title: Panoramax tooltip: "Street-level photos from Panoramax" + report: "Report" + hd: "High resolution" street_side: minzoom_tooltip: "Zoom in to see street-side photos" local_photos: diff --git a/modules/services/panoramax.js b/modules/services/panoramax.js index 42944ecdd..da82cfd31 100644 --- a/modules/services/panoramax.js +++ b/modules/services/panoramax.js @@ -8,7 +8,7 @@ import { VectorTile } from '@mapbox/vector-tile'; import { utilRebind, utilTiler, utilQsString, utilStringQs, utilSetTransform, utilUniqueDomId} from '../util'; import { geoExtent, geoScaleToZoom } from '../geo'; -import { localizer } from '../core/localizer'; +import { t, localizer } from '../core/localizer'; const apiUrl = 'https://panoramax.openstreetmap.fr/'; const tileUrl = apiUrl + 'api/map/{z}/{x}/{y}.pbf'; @@ -308,6 +308,18 @@ export default { sequences.classed('highlighted', function(d) { return d.properties.sequence_id === hoveredSequenceId; }) .classed('currentView', function(d) { return d.properties.sequence_id === selectedSequenceId; }); + // update viewfields if needed + context.container().selectAll('.layer-streetside-images .viewfield-group .viewfield') + .attr('d', viewfieldPath); + + function viewfieldPath() { + if (this.parentNode.__data__.type == "equirectangular") { + return 'M 8,13 m -10,0 a 10,10 0 1,0 20,0 a 10,10 0 1,0 -20,0'; + } else { + return 'M 6,9 C 8,8.4 8,8.4 10,9 L 16,-2 C 12,-5 4,-5 0,-2 z'; + } + } + return this; }, @@ -359,6 +371,51 @@ export default { let wrap = context.container().select('.photoviewer .panoramax-wrapper'); let attribution = wrap.selectAll('.photo-attribution').text(''); + let line1 = attribution + .append('div') + + const hiresDomId = utilUniqueDomId('panoramax-hd'); + + let label = line1 + .append('label') + .attr('for', hiresDomId) + .attr('class', 'panoramax-hd'); + + label + .append('input') + .attr('type', 'checkbox') + .attr('id', hiresDomId) + .property('checked', _isHD) + .on('click', (d3_event) => { + d3_event.stopPropagation(); + + _isHD = !_isHD; + _definition = _isHD ? highDefinition : standardDefinition; + + let viewstate = { + yaw: _pannellumViewer.getYaw(), + pitch: _pannellumViewer.getPitch(), + hfov: _pannellumViewer.getHfov() + }; + + _sceneOptions = Object.assign(_sceneOptions, viewstate); + that.selectImage(context, d.id) + .showViewer(context); + }); + + label + .append('span') + .call(t.append('panoramax.hd')); + + wrap + .transition() + .duration(100) + .call(imgZoom.transform, d3_zoomIdentity); + + wrap + .selectAll('img') + .remove(); + if (d.capture_time) { attribution .append('span') @@ -374,7 +431,7 @@ export default { .append('a') .attr('class', 'report-photo') .attr('href', "mailto:signalement.ign@panoramax.fr") - .text('Report'); + .call(t.append('panoramax.report')); attribution .append('span') @@ -387,45 +444,6 @@ export default { .attr('href', imageUrl) .text('panoramax.fr'); - let line1 = attribution - .append('div') - .attr('class', 'attribution-row'); - - const hiresDomId = utilUniqueDomId('panoramax-hd'); - - let label = line1 - .append('label') - .attr('for', hiresDomId) - .attr('class', 'panoramax-hd'); - - label - .append('input') - .attr('type', 'checkbox') - .attr('id', hiresDomId) - .property('checked', _isHD) - .on('click', (d3_event) => { - d3_event.stopPropagation(); - - _isHD = !_isHD; - _definition = _isHD ? highDefinition : standardDefinition; - wrap.call(setupCanvas, true); - - that.selectImage(context, d.id) - .showViewer(context); - }); - - label - .append('span'); - - wrap - .transition() - .duration(100) - .call(imgZoom.transform, d3_zoomIdentity); - - wrap - .selectAll('img') - .remove(); - getImageData(d.sequence_id, d.id).then(function(data){ _currentScene = { currentImage: null, @@ -619,6 +637,13 @@ export default { if (!nextId) return; + let viewstate = { + yaw: _pannellumViewer.getYaw(), + pitch: _pannellumViewer.getPitch(), + hfov: _pannellumViewer.getHfov() + }; + + _sceneOptions = Object.assign(_sceneOptions, viewstate); const nextImage = _cache.images.forImageId[nextId]; @@ -637,7 +662,13 @@ export default { return _loadViewerPromise; }, - showViewer:function (context) { + yaw: function(yaw) { + if (typeof yaw !== 'number') return yaw; + _sceneOptions.yaw = yaw; + return this; + }, + + showViewer: function (context) { let wrap = context.container().select('.photoviewer') .classed('hide', false); diff --git a/modules/svg/panoramax_images.js b/modules/svg/panoramax_images.js index a98a1716e..7dda1a31c 100644 --- a/modules/svg/panoramax_images.js +++ b/modules/svg/panoramax_images.js @@ -11,6 +11,8 @@ export function svgPanoramaxImages(projection, context, dispatch) { const viewFieldZoomLevel = 18; let layer = d3_select(null); let _panoramax; + let _viewerYaw = 0; + let _selectedSequence; function init() { if (svgPanoramaxImages.initialized) return; @@ -58,8 +60,9 @@ export function svgPanoramaxImages(projection, context, dispatch) { function transform(d) { let t = svgPointTransform(projection)(d); - if (d.heading) { - t += ' rotate(' + Math.floor(d.heading) + ',0,0)'; + var rot = d.heading + _viewerYaw; + if (rot) { + t += ' rotate(' + Math.floor(rot) + ',0,0)'; } return t; } @@ -79,11 +82,18 @@ export function svgPanoramaxImages(projection, context, dispatch) { const service = getService(); if (!service) return; + if (image.sequence_id !== _selectedSequence) { + _viewerYaw = 0; // reset + } + + _selectedSequence = image.sequence_id; + service .ensureViewerLoaded(context, image.id) .then(function() { service .selectImage(context, image.id) + .yaw(_viewerYaw) .showViewer(context); });