diff --git a/CHANGELOG.md b/CHANGELOG.md index 8352cb93dc..3078068e85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # GeoJS Change Log +## Version 1.8.10 + +### Improvements + +- Added a uniformLine property to speed up line rendering ([#1211](../../pull/1211)) + +## Version 1.8.9 + +### Bug Fixes + +- Fix a bug introduced in #1207 ([#1210](../../pull/1210)) + ## Version 1.8.8 ### Improvements diff --git a/src/geojsonReader.js b/src/geojsonReader.js index ceb859f211..0df161a3bb 100644 --- a/src/geojsonReader.js +++ b/src/geojsonReader.js @@ -55,6 +55,7 @@ var geojsonReader = function (arg) { strokeOffset: 0, lineCap: 'butt', lineJoin: 'miter', + uniformLine: true, closed: false, ...arg.lineStyle }, @@ -66,6 +67,7 @@ var geojsonReader = function (arg) { strokeColor: '#999999', strokeWidth: 2, strokeOpacity: 1, + uniformPolygon: true, ...arg.polygonStyle } }; diff --git a/src/lineFeature.js b/src/lineFeature.js index 62e4cbef68..1eb70cb883 100644 --- a/src/lineFeature.js +++ b/src/lineFeature.js @@ -46,6 +46,9 @@ var util = require('./util'); * divided by the sine of half the angle between segments, then a bevel join * is used instead. This is a single value that applies to all lines. If a * function, it is called with `(data)`. + * @property {boolean|function} [uniformLine=false] Boolean indicating if each + * line has a uniform style (uniform stroke color, opacity, and width). Can + * vary by line. * @property {number|function} [antialiasing] Antialiasing distance in pixels. * Values must be non-negative. A value greater than 1 will produce a * visible gradient. This is a single value that applies to all lines. @@ -157,17 +160,26 @@ var lineFeature = function (arg) { var data = m_this.data(), line = m_this.line(), widthFunc = m_this.style.get('strokeWidth'), + widthVal = util.isFunction(m_this.style('strokeWidth')) ? undefined : widthFunc(), posFunc = m_this.position(), closedFunc = m_this.style.get('closed'), + closedVal = util.isFunction(m_this.style('closed')) ? undefined : closedFunc(), + uniformFunc = m_this.style.get('uniformLine'), + uniformVal = util.isFunction(m_this.style('uniformLine')) ? undefined : uniformFunc(), gcs = m_this.gcs(), mapgcs = m_this.layer().map().gcs(); - data.forEach(function (d, index) { - var closed = closedFunc(d, index), - last, lasti, lastr, lastr2, first, record = [], min, max; + for (let index = 0; index < data.length; index += 1) { + const d = data[index]; + const closed = closedVal === undefined ? closedFunc(d, index) : closedVal; + let last, lasti, lastr, lastr2, first, min, max, width; + const record = []; + const uniform = uniformVal === undefined ? uniformFunc(d, index) : uniformVal; - line(d, index).forEach(function (current, j) { - var p = posFunc(current, j, d, index); + const lineRecord = line(d, index); + for (let j = 0; j < lineRecord.length; j += 1) { + const current = lineRecord[j]; + let p = posFunc(current, j, d, index); if (gcs !== mapgcs) { p = transform.transformCoordinates(gcs, mapgcs, p); } @@ -177,9 +189,12 @@ var lineFeature = function (arg) { if (p.x > max.x) { max.x = p.x; } if (p.y < min.y) { min.y = p.y; } if (p.y > max.y) { max.y = p.y; } - var r = Math.ceil(widthFunc(current, j, d, index) / 2) + 2; + if (!uniform || !j) { + width = widthVal === undefined ? widthFunc(current, j, d, index) : widthVal; + } + const r = Math.ceil(width / 2) + 2; if (max.r === undefined || r > max.r) { max.r = r; } - var r2 = r * r; + const r2 = r * r; if (last) { record.push({u: p, v: last, r: lastr > r ? lastr : r, r2: lastr2 > r2 ? lastr2 : r2, i: j, j: lasti}); } @@ -190,14 +205,14 @@ var lineFeature = function (arg) { if (!first && closed) { first = {p: p, r: r, r2: r2, i: j}; } - }); + } if (closed && first && (last.x !== first.p.x || last.y !== first.p.y)) { record.push({u: last, v: first.p, r: lastr > first.r ? lastr : first.r, r2: lastr2 > first.r2 ? lastr2 : first.r2, i: lasti, j: first.i}); } record.min = min; record.max = max; m_pointSearchInfo.push(record); - }); + } return m_pointSearchInfo; }; diff --git a/src/polygonFeature.js b/src/polygonFeature.js index b85fbd76f8..53f4423541 100644 --- a/src/polygonFeature.js +++ b/src/polygonFeature.js @@ -495,7 +495,8 @@ var polygonFeature = function (arg) { strokeStyle: linePolyStyle(polyStyle.strokeStyle), strokeColor: linePolyStyle(polyStyle.strokeColor), strokeOffset: linePolyStyle(polyStyle.strokeOffset), - strokeOpacity: strokeOpacity + strokeOpacity: strokeOpacity, + uniformLine: linePolyStyle(polyStyle.uniformPolygon) }); var data = m_this.data(), posVal = m_this.style('position'); diff --git a/src/webgl/lineFeature.js b/src/webgl/lineFeature.js index 4e9934b613..e2c7fc7303 100644 --- a/src/webgl/lineFeature.js +++ b/src/webgl/lineFeature.js @@ -146,6 +146,7 @@ var webgl_lineFeature = function (arg) { strokeOffsetFunc = m_this.style.get('strokeOffset'), strokeOffsetVal, miterLimit = m_this.style.get('miterLimit')(data), antialiasing = m_this.style.get('antialiasing')(data) || 0, + uniformFunc = m_this.style.get('uniformLine'), uniformVal, uniform, order = m_this.featureVertices(), orderk0, prevkey, nextkey, offkey, orderLen = order.length, // webgl buffers; see _init for details @@ -164,6 +165,7 @@ var webgl_lineFeature = function (arg) { strokeOffsetVal = util.isFunction(m_this.style('strokeOffset')) ? undefined : (strokeOffsetFunc() || 0); strokeOpacityVal = util.isFunction(m_this.style('strokeOpacity')) ? undefined : strokeOpacityFunc(); strokeWidthVal = util.isFunction(m_this.style('strokeWidth')) ? undefined : strokeWidthFunc(); + uniformVal = util.isFunction(m_this.style('uniformLine')) ? undefined : uniformFunc(); if (miterLimit !== undefined) { /* We impose a limit no matter what, since otherwise the growth is @@ -262,6 +264,7 @@ var webgl_lineFeature = function (arg) { if (lineItem.length < 2) { continue; } + uniform = uniformVal === undefined ? uniformFunc(lineItem, i) : uniformVal; d = data[i]; closedVal = closed[i]; firstPosIdx3 = posIdx3; @@ -288,12 +291,26 @@ var webgl_lineFeature = function (arg) { (j !== lidx ? firstPosIdx3 + 3 : firstPosIdx3 + 6 - closedVal * 3) : posIdx3); } - v.strokeWidth = strokeWidthVal === undefined ? strokeWidthFunc(lineItemData, lidx, d, i) : strokeWidthVal; - v.strokeColor = strokeColorVal === undefined ? strokeColorFunc(lineItemData, lidx, d, i) : strokeColorVal; - v.strokeOpacity = strokeOpacityVal === undefined ? strokeOpacityFunc(lineItemData, lidx, d, i) : strokeOpacityVal; + if (uniform && j > 0) { + if (j === 1) { + v.strokeWidth = vert[0].strokeWidth; + v.strokeColor = vert[0].strokeColor; + v.strokeOpacity = vert[0].strokeOpacity; + } + } else { + v.strokeWidth = strokeWidthVal === undefined ? strokeWidthFunc(lineItemData, lidx, d, i) : strokeWidthVal; + v.strokeColor = strokeColorVal === undefined ? strokeColorFunc(lineItemData, lidx, d, i) : strokeColorVal; + v.strokeOpacity = strokeOpacityVal === undefined ? strokeOpacityFunc(lineItemData, lidx, d, i) : strokeOpacityVal; + } if (updateFlags) { if (strokeOffsetVal !== 0) { - v.strokeOffset = (strokeOffsetVal === undefined ? strokeOffsetFunc(lineItemData, lidx, d, i) : strokeOffsetVal) || 0; + if (uniform && j > 0) { + if (j === 1) { + v.strokeOffset = vert[0].strokeOffset; + } + } else { + v.strokeOffset = (strokeOffsetVal === undefined ? strokeOffsetFunc(lineItemData, lidx, d, i) : strokeOffsetVal) || 0; + } if (v.strokeOffset) { /* we use 11 bits to store the offset, and we want to store values * from -1 to 1, so multiply our values by 1023, and use some bit diff --git a/src/webgl/polygonFeature.js b/src/webgl/polygonFeature.js index 032f2069f7..9f0489c68d 100644 --- a/src/webgl/polygonFeature.js +++ b/src/webgl/polygonFeature.js @@ -77,7 +77,7 @@ var webgl_polygonFeature = function (arg) { fillColor, fillColorFunc, fillColorVal, fillOpacity, fillOpacityFunc, fillOpacityVal, fillFunc, fillVal, - uniformPolyFunc, uniform, + uniformFunc, uniformVal, uniform, indices, items = [], target_gcs = m_this.gcs(), @@ -93,7 +93,8 @@ var webgl_polygonFeature = function (arg) { fillOpacityVal = util.isFunction(m_this.style('fillOpacity')) ? undefined : fillOpacityFunc(); fillFunc = m_this.style.get('fill'); fillVal = util.isFunction(m_this.style('fill')) ? undefined : fillFunc(); - uniformPolyFunc = m_this.style.get('uniformPolygon'); + uniformFunc = m_this.style.get('uniformPolygon'); + uniformVal = util.isFunction(m_this.style('uniformPolygon')) ? undefined : uniformFunc(); if (!onlyStyle) { posFunc = m_this.style.get('position'); @@ -188,7 +189,7 @@ var webgl_polygonFeature = function (arg) { item = items[k].item; itemIndex = items[k].itemIndex; original = items[k].original; - uniform = uniformPolyFunc(item, itemIndex); + uniform = uniformVal === undefined ? uniformFunc(item, itemIndex) : uniformVal; opacity = fillOpacityVal; if (uniform) { if (fillColorVal === undefined) {