From d7902e1388406fa82138fd11695f1462d0794287 Mon Sep 17 00:00:00 2001 From: Martin Raifer Date: Wed, 2 Aug 2023 11:16:03 +0200 Subject: [PATCH] only show regional street-level photo providers in the available region and disable selection checkbox if not zoomed in enough to load the photos --- data/core.yaml | 2 ++ modules/services/vegbilder.js | 9 +++++++- modules/svg/kartaview_images.js | 4 ++++ modules/svg/mapilio_images.js | 4 ++++ modules/svg/mapillary_images.js | 4 ++++ modules/svg/mapillary_map_features.js | 4 ++++ modules/svg/mapillary_position.js | 4 ++++ modules/svg/mapillary_signs.js | 4 ++++ modules/svg/streetside.js | 4 ++++ modules/svg/vegbilder.js | 9 ++++++++ modules/ui/sections/photo_overlays.js | 30 +++++++++++++++++++++++++-- 11 files changed, 75 insertions(+), 3 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index b5be4d062..6320908e5 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -1440,6 +1440,8 @@ en: mapilio: title: Mapilio tooltip: "Street-level photos from Mapilio" + street_side: + minzoom_tooltip: "Zoom in to see street-side photos" note: note: Note title: Edit note diff --git a/modules/services/vegbilder.js b/modules/services/vegbilder.js index 3fc3daf4a..3e2761629 100644 --- a/modules/services/vegbilder.js +++ b/modules/services/vegbilder.js @@ -1,12 +1,14 @@ import { json as d3_json, xml as d3_xml} from 'd3-fetch'; import { dispatch as d3_dispatch } from 'd3-dispatch'; import { pairs as d3_pairs } from 'd3-array'; +import RBush from 'rbush'; +import { iso1A2Codes } from '@rapideditor/country-coder'; import { t, localizer } from '../core/localizer'; import { utilQsString, utilTiler, utilRebind, utilArrayUnion, utilStringQs} from '../util'; import {geoExtent, geoScaleToZoom, geoVecAngle, geoVecEqual} from '../geo'; import pannellumPhotoFrame from './pannellum_photo'; import planePhotoFrame from './plane_photo'; -import RBush from 'rbush'; + const owsEndpoint = 'https://www.vegvesen.no/kart/ogc/vegbilder_1_0/ows?'; const tileZoom = 14; @@ -599,6 +601,11 @@ export default { } }, + validHere: function(extent) { + const bbox = Object.values(extent.bbox()); + return iso1A2Codes(bbox).includes('NO'); + }, + cache: function () { return _vegbilderCache; diff --git a/modules/svg/kartaview_images.js b/modules/svg/kartaview_images.js index 65cd48a17..3beb60862 100644 --- a/modules/svg/kartaview_images.js +++ b/modules/svg/kartaview_images.js @@ -301,6 +301,10 @@ export function svgKartaviewImages(projection, context, dispatch) { return !!getService(); }; + drawImages.rendered = function(zoom) { + return zoom >= minZoom; + }; + init(); return drawImages; diff --git a/modules/svg/mapilio_images.js b/modules/svg/mapilio_images.js index 1f4a679a8..ac62b52ef 100644 --- a/modules/svg/mapilio_images.js +++ b/modules/svg/mapilio_images.js @@ -243,6 +243,10 @@ export function svgMapilioImages(projection, context, dispatch) { return !!getService(); }; + drawImages.rendered = function(zoom) { + return zoom >= minZoom; + }; + init(); return drawImages; diff --git a/modules/svg/mapillary_images.js b/modules/svg/mapillary_images.js index 7e9d9ea08..6afba1c05 100644 --- a/modules/svg/mapillary_images.js +++ b/modules/svg/mapillary_images.js @@ -310,6 +310,10 @@ export function svgMapillaryImages(projection, context, dispatch) { return !!getService(); }; + drawImages.rendered = function(zoom) { + return zoom >= minZoom; + }; + init(); return drawImages; diff --git a/modules/svg/mapillary_map_features.js b/modules/svg/mapillary_map_features.js index 68a4fadf2..996cc2431 100644 --- a/modules/svg/mapillary_map_features.js +++ b/modules/svg/mapillary_map_features.js @@ -208,6 +208,10 @@ export function svgMapillaryMapFeatures(projection, context, dispatch) { return !!getService(); }; + drawMapFeatures.rendered = function(zoom) { + return zoom >= minZoom; + }; + init(); return drawMapFeatures; diff --git a/modules/svg/mapillary_position.js b/modules/svg/mapillary_position.js index e5af5154b..836cb26a5 100644 --- a/modules/svg/mapillary_position.js +++ b/modules/svg/mapillary_position.js @@ -157,6 +157,10 @@ export function svgMapillaryPosition(projection, context) { return !!getService(); }; + drawImages.rendered = function(zoom) { + return zoom >= minZoom; + }; + init(); return drawImages; diff --git a/modules/svg/mapillary_signs.js b/modules/svg/mapillary_signs.js index 8c6b00c5a..b2837a389 100644 --- a/modules/svg/mapillary_signs.js +++ b/modules/svg/mapillary_signs.js @@ -197,6 +197,10 @@ export function svgMapillarySigns(projection, context, dispatch) { return !!getService(); }; + drawSigns.rendered = function(zoom) { + return zoom >= minZoom; + }; + init(); return drawSigns; diff --git a/modules/svg/streetside.js b/modules/svg/streetside.js index 36649189f..73ec4eeb7 100644 --- a/modules/svg/streetside.js +++ b/modules/svg/streetside.js @@ -379,6 +379,10 @@ export function svgStreetside(projection, context, dispatch) { return !!getService(); }; + drawImages.rendered = function(zoom) { + return zoom >= minZoom; + }; + init(); return drawImages; diff --git a/modules/svg/vegbilder.js b/modules/svg/vegbilder.js index 2a2066d6e..5563e5ebc 100644 --- a/modules/svg/vegbilder.js +++ b/modules/svg/vegbilder.js @@ -371,6 +371,15 @@ export function svgVegbilder(projection, context, dispatch) { return !!getService(); }; + drawImages.rendered = function(zoom) { + return zoom >= minZoom; + }; + + drawImages.validHere = function(extent, zoom) { + return zoom >= (minZoom - 2) + && getService().validHere(extent); + }; + init(); return drawImages; diff --git a/modules/ui/sections/photo_overlays.js b/modules/ui/sections/photo_overlays.js index 7d5c76fe6..b9a9b5876 100644 --- a/modules/ui/sections/photo_overlays.js +++ b/modules/ui/sections/photo_overlays.js @@ -1,3 +1,4 @@ +import _debounce from 'lodash-es/debounce'; import { select as d3_select } from 'd3-selection'; @@ -33,7 +34,14 @@ export function uiSectionPhotoOverlays(context) { function drawPhotoItems(selection) { var photoKeys = context.photos().overlayLayerIDs(); var photoLayers = layers.all().filter(function(obj) { return photoKeys.indexOf(obj.id) !== -1; }); - var data = photoLayers.filter(function(obj) { return obj.layer.supported(); }); + var data = photoLayers.filter(function(obj) { + if (!obj.layer.supported()) return false; + if (layerEnabled(obj)) return true; + if (typeof obj.layer.validHere === 'function') { + return obj.layer.validHere(context.map().extent(), context.map().zoom()); + } + return true; + }); function layerSupported(d) { return d.layer && d.layer.supported(); @@ -41,6 +49,9 @@ export function uiSectionPhotoOverlays(context) { function layerEnabled(d) { return layerSupported(d) && d.layer.enabled(); } + function layerRendered(d) { + return d.layer.rendered?.(context.map().zoom()) ?? true; + } var ul = selection .selectAll('.layer-list-photos') @@ -77,7 +88,13 @@ export function uiSectionPhotoOverlays(context) { else titleID = d.id.replace(/-/g, '_') + '.tooltip'; d3_select(this) .call(uiTooltip() - .title(() => t.append(titleID)) + .title(() => { + if (!layerRendered(d)) { + return t.append('street_side.minzoom_tooltip'); + } else { + return t.append(titleID); + } + }) .placement('top') ); }); @@ -100,6 +117,7 @@ export function uiSectionPhotoOverlays(context) { .merge(liEnter) .classed('active', layerEnabled) .selectAll('input') + .property('disabled', d => !layerRendered(d)) .property('checked', layerEnabled); } @@ -320,5 +338,13 @@ export function uiSectionPhotoOverlays(context) { context.layers().on('change.uiSectionPhotoOverlays', section.reRender); context.photos().on('change.uiSectionPhotoOverlays', section.reRender); + context.map() + .on('move.background_list', + _debounce(function() { + // layers in-view may have changed due to map move + window.requestIdleCallback(section.reRender); + }, 1000) + ); + return section; }