Skip to content

Commit 1b344b4

Browse files
Zoom in after selecting cluster even if cluster extent matches view (#1407)
Closes getodk/central#1444.
1 parent 937c957 commit 1b344b4

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

src/components/geojson-map.vue

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import VectorSource from 'ol/source/Vector';
4545
import View from 'ol/View';
4646
import WebGLVectorLayer from 'ol/layer/WebGLVector';
4747
import Zoom from 'ol/control/Zoom';
48-
import { boundingExtent, containsExtent, createEmpty as createEmptyExtent, extend, getCenter } from 'ol/extent';
48+
import { boundingExtent, createEmpty as createEmptyExtent, extend, getCenter } from 'ol/extent';
4949
import { get as getProjection } from 'ol/proj';
5050
5151
import { equals } from 'ramda';
@@ -80,9 +80,6 @@ const { redAlert, config, buildMode } = inject('container');
8080
// eslint-disable-next-line no-console
8181
const log = config.devTools ? console.log.bind(console) : noop;
8282
83-
// Constants
84-
const animationDuration = 1000;
85-
8683
const el = useTemplateRef('el');
8784
const mapContainer = useTemplateRef('mapContainer');
8885
@@ -285,10 +282,13 @@ const resize = () => {
285282
////////////////////////////////////////////////////////////////////////////////
286283
// VIEW
287284
285+
const viewPadding = 50;
286+
const animationDuration = 1000;
287+
288288
const fitView = (extent, options = undefined) => {
289289
mapInstance.getView().fit(extent, {
290290
// We need to provide enough space for styled features.
291-
padding: [50, 50, 50, 50],
291+
padding: new Array(4).fill(viewPadding),
292292
// Avoid zooming in to an extreme degree.
293293
maxZoom: maxZoom.value,
294294
...options
@@ -568,13 +568,18 @@ const selectCluster = (cluster) => {
568568
extend(featureExtent, feature.getGeometry().getExtent());
569569
570570
// The cluster could contain a LineString or Polygon of arbitrary size, so
571-
// we have to check whether featureExtent is fully in view. We want to zoom
572-
// in, not zoom out.
573-
const viewExtent = view.calculateExtent();
574-
const viewContainsFeatures = containsExtent(viewExtent, featureExtent) &&
575-
!equals(viewExtent, featureExtent);
576-
577-
if (viewContainsFeatures) {
571+
// it's possible that featureExtent is not fully in view. In that case,
572+
// fitting the view to featureExtent could cause the map to zoom out, not
573+
// in. Here, we check whether fitting the view to featureExtent would cause
574+
// the map to zoom in.
575+
const oldResolution = view.getResolution();
576+
// Subtracting the padding, as padding reduces the effective size of the
577+
// area in which featureExtent can be shown.
578+
const size = mapInstance.getSize().map(length => length - 2 * viewPadding);
579+
const newResolution = view.getResolutionForExtent(featureExtent, size);
580+
const fitWouldZoomIn = newResolution < oldResolution;
581+
582+
if (fitWouldZoomIn) {
578583
fitView(featureExtent, { duration: animationDuration });
579584
return;
580585
}

0 commit comments

Comments
 (0)