diff --git a/examples/mapbox-vector-tiles-advanced.js b/examples/mapbox-vector-tiles-advanced.js index b960ad8964..9261d52a01 100644 --- a/examples/mapbox-vector-tiles-advanced.js +++ b/examples/mapbox-vector-tiles-advanced.js @@ -50,6 +50,7 @@ var map = new ol.Map({ '© ' + 'OpenStreetMap contributors', format: new ol.format.MVT(), + overlaps: false, tileGrid: new ol.tilegrid.TileGrid({ extent: ol.proj.get('EPSG:3857').getExtent(), resolutions: resolutions diff --git a/examples/mapbox-vector-tiles.js b/examples/mapbox-vector-tiles.js index ed3688bd4e..da9719a18e 100644 --- a/examples/mapbox-vector-tiles.js +++ b/examples/mapbox-vector-tiles.js @@ -21,6 +21,7 @@ var map = new ol.Map({ '© ' + 'OpenStreetMap contributors', format: new ol.format.MVT(), + overlaps: false, tileGrid: ol.tilegrid.createXYZ({maxZoom: 22}), tilePixelRatio: 16, url: 'http://{a-d}.tiles.mapbox.com/v4/mapbox.mapbox-streets-v6/' + diff --git a/examples/osm-vector-tiles.js b/examples/osm-vector-tiles.js index bef1e300e1..aef7ca7c87 100644 --- a/examples/osm-vector-tiles.js +++ b/examples/osm-vector-tiles.js @@ -92,6 +92,7 @@ var map = new ol.Map({ new ol.layer.VectorTile({ source: new ol.source.VectorTile({ format: format, + overlaps: false, tileGrid: tileGrid, url: 'http://{a-c}.tile.openstreetmap.us/' + 'vectiles-land-usages/{z}/{x}/{y}.topojson' diff --git a/examples/topojson.js b/examples/topojson.js index 551636788a..2373203887 100644 --- a/examples/topojson.js +++ b/examples/topojson.js @@ -29,7 +29,8 @@ var style = new ol.style.Style({ var vector = new ol.layer.Vector({ source: new ol.source.Vector({ url: 'data/topojson/world-110m.json', - format: new ol.format.TopoJSON() + format: new ol.format.TopoJSON(), + overlaps: false }), style: function(feature) { // don't want to render the full world polygon, which repeats all countries diff --git a/externs/olx.js b/externs/olx.js index 61e8fed4e5..f2711e433d 100644 --- a/externs/olx.js +++ b/externs/olx.js @@ -4356,6 +4356,7 @@ olx.source.TileImageOptions.prototype.wrapX; * cacheSize: (number|undefined), * format: (ol.format.Feature|undefined), * logo: (string|olx.LogoOptions|undefined), + * overlaps: (boolean|undefined), * projection: ol.ProjectionLike, * state: (ol.source.State|undefined), * tileClass: (function(new: ol.VectorTile, ol.TileCoord, @@ -4405,6 +4406,17 @@ olx.source.VectorTileOptions.prototype.format; olx.source.VectorTileOptions.prototype.logo; +/** + * This source may have overlapping geometries. Default is `true`. Setting this + * to `false` (e.g. for sources with polygons that represent adminstrative + * boundaries or TopoJSON sources) allows the renderer to optimise fill and + * stroke operations. + * @type {boolean|undefined} + * @api + */ +olx.source.VectorTileOptions.prototype.overlaps; + + /** * Projection. * @type {ol.ProjectionLike} @@ -5775,6 +5787,7 @@ olx.source.TileWMSOptions.prototype.wrapX; * format: (ol.format.Feature|undefined), * loader: (ol.FeatureLoader|undefined), * logo: (string|olx.LogoOptions|undefined), + * overlaps: (boolean|undefined), * strategy: (ol.LoadingStrategy|undefined), * url: (string|ol.FeatureUrlFunction|undefined), * useSpatialIndex: (boolean|undefined), @@ -5827,6 +5840,17 @@ olx.source.VectorOptions.prototype.loader; olx.source.VectorOptions.prototype.logo; +/** + * This source may have overlapping geometries. Default is `true`. Setting this + * to `false` (e.g. for sources with polygons that represent adminstrative + * boundaries or TopoJSON sources) allows the renderer to optimise fill and + * stroke operations. + * @type {boolean|undefined} + * @api + */ +olx.source.VectorOptions.prototype.overlaps; + + /** * The loading strategy to use. By default an {@link ol.loadingstrategy.all} * strategy is used, a one-off strategy which loads all features at once. diff --git a/src/ol/color/color.js b/src/ol/color/color.js index 84ba8e6694..c322252c37 100644 --- a/src/ol/color/color.js +++ b/src/ol/color/color.js @@ -183,16 +183,6 @@ ol.color.fromStringInternal_ = function(s) { }; -/** - * @param {ol.ColorLike|string} color Color. - * @return {boolean} Is rgba. - */ -ol.color.isRgba = function(color) { - return Array.isArray(color) && color.length == 4 || - typeof color == 'string' && ol.color.rgbaColorRe_.test(color); -}; - - /** * @param {ol.Color} color Color. * @return {boolean} Is valid. diff --git a/src/ol/render/canvas/canvasreplay.js b/src/ol/render/canvas/canvasreplay.js index 20066e4c56..97bba2b460 100644 --- a/src/ol/render/canvas/canvasreplay.js +++ b/src/ol/render/canvas/canvasreplay.js @@ -52,10 +52,11 @@ ol.render.canvas.Instruction = { * @param {number} tolerance Tolerance. * @param {ol.Extent} maxExtent Maximum extent. * @param {number} resolution Resolution. + * @param {boolean} overlaps The replay can have overlapping geometries. * @protected * @struct */ -ol.render.canvas.Replay = function(tolerance, maxExtent, resolution) { +ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, overlaps) { ol.render.VectorContext.call(this); /** @@ -75,7 +76,7 @@ ol.render.canvas.Replay = function(tolerance, maxExtent, resolution) { * @protected * @type {boolean} */ - this.transparency = false; + this.overlaps = overlaps; /** * @private @@ -266,7 +267,7 @@ ol.render.canvas.Replay.prototype.replay_ = function( var pendingFill = 0; var pendingStroke = 0; var batchSize = - this.instructions != instructions || this.transparency ? 0 : 200; + this.instructions != instructions || this.overlaps ? 0 : 200; while (i < ii) { var instruction = instructions[i]; var type = /** @type {ol.render.canvas.Instruction} */ (instruction[0]); @@ -691,11 +692,12 @@ ol.render.canvas.Replay.prototype.getBufferedMaxExtent = function() { * @param {number} tolerance Tolerance. * @param {ol.Extent} maxExtent Maximum extent. * @param {number} resolution Resolution. + * @param {boolean} overlaps The replay can have overlapping geometries. * @protected * @struct */ -ol.render.canvas.ImageReplay = function(tolerance, maxExtent, resolution) { - ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution); +ol.render.canvas.ImageReplay = function(tolerance, maxExtent, resolution, overlaps) { + ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps); /** * @private @@ -957,12 +959,13 @@ ol.render.canvas.ImageReplay.prototype.setImageStyle = function(imageStyle) { * @param {number} tolerance Tolerance. * @param {ol.Extent} maxExtent Maximum extent. * @param {number} resolution Resolution. + * @param {boolean} overlaps The replay can have overlapping geometries. * @protected * @struct */ -ol.render.canvas.LineStringReplay = function(tolerance, maxExtent, resolution) { +ol.render.canvas.LineStringReplay = function(tolerance, maxExtent, resolution, overlaps) { - ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution); + ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps); /** * @private @@ -1191,12 +1194,13 @@ ol.render.canvas.LineStringReplay.prototype.setFillStrokeStyle = function(fillSt * @param {number} tolerance Tolerance. * @param {ol.Extent} maxExtent Maximum extent. * @param {number} resolution Resolution. + * @param {boolean} overlaps The replay can have overlapping geometries. * @protected * @struct */ -ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution) { +ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution, overlaps) { - ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution); + ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps); /** * @private @@ -1457,10 +1461,6 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyle = function(fillStyle var fillStyleColor = fillStyle.getColor(); state.fillStyle = ol.colorlike.asColorLike(fillStyleColor ? fillStyleColor : ol.render.canvas.defaultFillStyle); - if (!this.transparency && ol.color.isRgba(state.fillStyle)) { - this.transparency = ol.color.asArray( - /** @type {ol.Color|string} */ (state.fillStyle))[0] != 1; - } } else { state.fillStyle = undefined; } @@ -1468,9 +1468,6 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyle = function(fillStyle var strokeStyleColor = strokeStyle.getColor(); state.strokeStyle = ol.color.asString(strokeStyleColor ? strokeStyleColor : ol.render.canvas.defaultStrokeStyle); - if (!this.transparency && ol.color.isRgba(state.strokeStyle)) { - this.transparency = ol.color.asArray(state.strokeStyle)[3] != 1; - } var strokeStyleLineCap = strokeStyle.getLineCap(); state.lineCap = strokeStyleLineCap !== undefined ? strokeStyleLineCap : ol.render.canvas.defaultLineCap; @@ -1553,12 +1550,13 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function() { * @param {number} tolerance Tolerance. * @param {ol.Extent} maxExtent Maximum extent. * @param {number} resolution Resolution. + * @param {boolean} overlaps The replay can have overlapping geometries. * @protected * @struct */ -ol.render.canvas.TextReplay = function(tolerance, maxExtent, resolution) { +ol.render.canvas.TextReplay = function(tolerance, maxExtent, resolution, overlaps) { - ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution); + ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps); /** * @private @@ -1862,11 +1860,12 @@ ol.render.canvas.TextReplay.prototype.setTextStyle = function(textStyle) { * @param {number} tolerance Tolerance. * @param {ol.Extent} maxExtent Max extent. * @param {number} resolution Resolution. + * @param {boolean} overlaps The replay group can have overlapping geometries. * @param {number=} opt_renderBuffer Optional rendering buffer. * @struct */ ol.render.canvas.ReplayGroup = function( - tolerance, maxExtent, resolution, opt_renderBuffer) { + tolerance, maxExtent, resolution, overlaps, opt_renderBuffer) { /** * @private @@ -1880,6 +1879,12 @@ ol.render.canvas.ReplayGroup = function( */ this.maxExtent_ = maxExtent; + /** + * @private + * @type {boolean} + */ + this.overlaps_ = overlaps; + /** * @private * @type {number} @@ -1998,7 +2003,7 @@ ol.render.canvas.ReplayGroup.prototype.getReplay = function(zIndex, replayType) replayType + ' constructor missing from ol.render.canvas.BATCH_CONSTRUCTORS_'); replay = new Constructor(this.tolerance_, this.maxExtent_, - this.resolution_); + this.resolution_, this.overlaps_); replays[replayType] = replay; } return replay; @@ -2112,7 +2117,7 @@ ol.render.canvas.ReplayGroup.prototype.replayHitDetection_ = function( * @private * @type {Object.