From d231c6d989ea7ac6d274410b344334f748b44e85 Mon Sep 17 00:00:00 2001 From: Xiaoji Chen Date: Thu, 16 Jan 2020 12:04:21 -0800 Subject: [PATCH] Fix H3HexagonLayer update when viewport jumps (#4158) --- .../src/h3-layers/h3-hexagon-layer.js | 13 +++-- test/modules/geo-layers/h3-layers.spec.js | 52 ++++++++++++++++++- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/modules/geo-layers/src/h3-layers/h3-hexagon-layer.js b/modules/geo-layers/src/h3-layers/h3-hexagon-layer.js index c163678700a..ae245cd2ea2 100644 --- a/modules/geo-layers/src/h3-layers/h3-hexagon-layer.js +++ b/modules/geo-layers/src/h3-layers/h3-hexagon-layer.js @@ -159,12 +159,17 @@ export default class H3HexagonLayer extends CompositeLayer { return; } const hex = geoToH3(viewport.latitude, viewport.longitude, resolution); - if ( - centerHex === hex || - (centerHex && h3Distance(centerHex, hex) * edgeLengthKM < UPDATE_THRESHOLD_KM) - ) { + if (centerHex === hex) { return; } + if (centerHex) { + const distance = h3Distance(centerHex, hex); + // h3Distance returns a negative number if the distance could not be computed + // due to the two indexes very far apart or on opposite sides of a pentagon. + if (distance >= 0 && distance * edgeLengthKM < UPDATE_THRESHOLD_KM) { + return; + } + } const {unitsPerMeter} = viewport.distanceScales; diff --git a/test/modules/geo-layers/h3-layers.spec.js b/test/modules/geo-layers/h3-layers.spec.js index 4a3fa3c29e1..46f8978d0b6 100644 --- a/test/modules/geo-layers/h3-layers.spec.js +++ b/test/modules/geo-layers/h3-layers.spec.js @@ -20,7 +20,7 @@ import test from 'tape-catch'; import {h3ToGeoBoundary, h3ToGeo} from 'h3-js'; -import {_count as count} from '@deck.gl/core'; +import {_count as count, WebMercatorViewport} from '@deck.gl/core'; import {testLayer, generateLayerTests} from '@deck.gl/test-utils'; import {H3HexagonLayer, H3ClusterLayer} from '@deck.gl/geo-layers'; import {scalePolygon, normalizeLongitudes} from '@deck.gl/geo-layers/h3-layers/h3-hexagon-layer'; @@ -53,6 +53,56 @@ test('H3HexagonLayer', t => { t.end(); }); +test('H3HexagonLayer#viewportUpdate', t => { + let vertices = null; + + testLayer({ + Layer: H3HexagonLayer, + onError: t.notOk, + testCases: [ + { + props: SAMPLE_PROPS, + onAfterUpdate({layer}) { + vertices = layer.state.vertices; + t.ok(vertices, 'vertices are generated'); + } + }, + { + // viewport does not move + viewport: new WebMercatorViewport({longitude: 0, latitude: 0, zoom: 10}), + onAfterUpdate({layer}) { + t.is(vertices, layer.state.vertices, 'vertices are not changed'); + } + }, + { + // viewport moves a small distance + viewport: new WebMercatorViewport({longitude: 0.001, latitude: 0.001, zoom: 10}), + onAfterUpdate({layer}) { + t.is(vertices, layer.state.vertices, 'vertices are not changed'); + } + }, + { + // far viewport jump, h3Distance fails + viewport: new WebMercatorViewport({longitude: -100, latitude: 65, zoom: 10}), + onAfterUpdate({layer}) { + t.not(vertices, layer.state.vertices, 'vertices are updated'); + vertices = layer.state.vertices; + } + }, + { + // viewport moves far enough + viewport: new WebMercatorViewport({longitude: -102, latitude: 60, zoom: 10}), + onAfterUpdate({layer}) { + t.not(vertices, layer.state.vertices, 'vertices are updated'); + vertices = layer.state.vertices; + } + } + ] + }); + + t.end(); +}); + test('H3HexagonLayer#mergeTriggers', t => { testLayer({ Layer: H3HexagonLayer,