From b5b95de9f81fdab5ca919d92c3e1bf56dda9416d Mon Sep 17 00:00:00 2001 From: Karim Naaji Date: Thu, 23 Jan 2020 02:42:01 -0500 Subject: [PATCH] Fix line distances breaking gradient across tile boundaries (#9220) * Fix line line distances breaking gradients Ensure scaled line distance is computed at least once when calculating the entire line distance, otherwise we hit a corner case where the distance isn't updated. Specifically when the beginning of the line doesn't have a sharp corner. Fixes #8969 * Add render test for line gradient across tile boundaries * Address review comments --- src/data/bucket/line_bucket.js | 10 +++- .../gradient-tile-boundaries/expected.png | Bin 0 -> 674 bytes .../gradient-tile-boundaries/style.json | 56 ++++++++++++++++++ 3 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 test/integration/render-tests/line-gradient/gradient-tile-boundaries/expected.png create mode 100644 test/integration/render-tests/line-gradient/gradient-tile-boundaries/style.json diff --git a/src/data/bucket/line_bucket.js b/src/data/bucket/line_bucket.js index d76021b75d6..d15b18a4c8d 100644 --- a/src/data/bucket/line_bucket.js +++ b/src/data/bucket/line_bucket.js @@ -231,6 +231,7 @@ class LineBucket implements Bucket { for (let i = 0; i < vertices.length - 1; i++) { this.totalDistance += vertices[i].dist(vertices[i + 1]); } + this.updateScaledDistance(); } const isPolygon = vectorTileFeatureTypes[feature.type] === 'Polygon'; @@ -526,9 +527,7 @@ class LineBucket implements Bucket { } } - updateDistance(prev: Point, next: Point) { - this.distance += prev.dist(next); - + updateScaledDistance() { // Knowing the ratio of the full linestring covered by this tiled feature, as well // as the total distance (in tile units) of this tiled feature, and the distance // (in tile units) of the current vertex, we can determine the relative distance @@ -537,6 +536,11 @@ class LineBucket implements Bucket { (this.clipStart + (this.clipEnd - this.clipStart) * this.distance / this.totalDistance) * (MAX_LINE_DISTANCE - 1) : this.distance; } + + updateDistance(prev: Point, next: Point) { + this.distance += prev.dist(next); + this.updateScaledDistance(); + } } register('LineBucket', LineBucket, {omit: ['layers', 'patternFeatures']}); diff --git a/test/integration/render-tests/line-gradient/gradient-tile-boundaries/expected.png b/test/integration/render-tests/line-gradient/gradient-tile-boundaries/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..e85d8986b3173748bff1abc1920e046d64d36c4c GIT binary patch literal 674 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!3HFEH|A$CFfe6$x;TbZFupx#crGtkg6%@- zxk|rje`^7l#FY(B8^-t=cRiH*Sv5ALqG z-EzBRQ?Z>)^_*D@q;%<-m$&nCl2aRO~W@NE@U_ zD6NW(>IN$mne&Xt+hu8Vb)cpMNC>E{8)S**jxAzS^JG9m3%3Ft(Wbg6=!`VbbaSv9 zG$laVwt8m=YFca+o7xnd9r*HE9M};-23y3gE&}R_0ctjfxfAY|t9n3}OHT*e0oLja zH6!n>>r${|n}8OIfxHLw=dQvGT`ku3Ym0&kfQ+MifG*PoI~dsnpygm!pqfw&a&keY zF4x{YmS-&22)4>S;NYxB;kanP#v;VN#N{4P|3g7+;nD!VvUHx3vIVCg!0KPyi?*IS* literal 0 HcmV?d00001 diff --git a/test/integration/render-tests/line-gradient/gradient-tile-boundaries/style.json b/test/integration/render-tests/line-gradient/gradient-tile-boundaries/style.json new file mode 100644 index 00000000000..106da0da967 --- /dev/null +++ b/test/integration/render-tests/line-gradient/gradient-tile-boundaries/style.json @@ -0,0 +1,56 @@ +{ + "version": 8, + "metadata": { + "test": { + "width": 64, + "height": 128 + } + }, + "center": [ + -77.02803308586635, + 38.891047607560125 + ], + "zoom": 18, + "sources": { + "gradient": { + "type": "geojson", + "data": { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [-77.028035, 38.890600 ], + [-77.028035, 38.891088 ] + ] + } + }, + "lineMetrics": true + } + }, + "layers": [ + { + "id": "line", + "type": "line", + "source": "gradient", + "layout": { + "line-cap": "round", + "line-join": "round" + }, + "paint": { + "line-width": 15, + "line-gradient": [ + "interpolate", + ["linear"], + ["line-progress"], + 0, "rgba(0, 0, 255, 0)", + 0.1, "royalblue", + 0.3, "cyan", + 0.5, "lime", + 0.7, "yellow", + 1, "red" + ] + } + } + ] +}