From 53d5d8c1d9a050ff99755703b16239a6e48a4750 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Tue, 9 Jun 2015 13:25:51 +0200 Subject: [PATCH] Get rid of ol.FeatureOverlay This also introduces a wrapX option to the Draw, Modify and Select interaction. --- changelog/upgrade-notes.md | 34 ++ examples/draw-and-modify-features.js | 16 +- examples/geolocation.js | 9 +- examples/icon-sprite-webgl.js | 9 +- examples/igc.js | 6 +- examples/image-vector-layer.js | 9 +- examples/modify-features.js | 4 +- examples/vector-layer.js | 8 +- externs/olx.js | 33 +- src/ol/featureoverlay.js | 326 ------------------ src/ol/interaction/drawinteraction.js | 16 +- src/ol/interaction/modifyinteraction.js | 19 +- src/ol/interaction/selectinteraction.js | 22 +- src/ol/map.js | 12 +- src/ol/render/canvas/canvasimmediate.js | 4 +- src/ol/render/renderevent.js | 10 +- src/ol/renderer/canvas/canvaslayerrenderer.js | 4 +- src/ol/renderer/canvas/canvasmaprenderer.js | 40 +-- .../canvas/canvasvectorlayerrenderer.js | 23 +- src/ol/renderer/dom/dommaprenderer.js | 13 +- src/ol/renderer/dom/domvectorlayerrenderer.js | 4 +- src/ol/renderer/maprenderer.js | 27 -- src/ol/renderer/webgl/webgllayerrenderer.js | 2 +- src/ol/renderer/webgl/webglmaprenderer.js | 78 +---- test/spec/ol/featureoverlay.test.js | 42 --- .../ol/interaction/drawinteraction.test.js | 21 +- .../ol/interaction/selectinteraction.test.js | 15 +- .../renderer/canvas/canvasmaprenderer.test.js | 47 --- 28 files changed, 177 insertions(+), 676 deletions(-) delete mode 100644 src/ol/featureoverlay.js delete mode 100644 test/spec/ol/featureoverlay.test.js diff --git a/changelog/upgrade-notes.md b/changelog/upgrade-notes.md index 2c6b08768d..15c957ec08 100644 --- a/changelog/upgrade-notes.md +++ b/changelog/upgrade-notes.md @@ -1,5 +1,39 @@ ## Upgrade notes +### v3.7.0 + +#### Removal of `ol.FeatureOverlay` + +Instead of an `ol.FeatureOverlay`, we now use an `ol.layer.Vector` with an +`ol.source.Vector`. If you previously had: +```js +var featureOverlay = new ol.FeatureOverlay({ + map: map, + style: overlayStyle +}); +featureOverlay.addFeature(feature); +featureOverlay.removeFeature(feature); +var collection = featureOverlay.getFeatures(); +``` +you will have to change this to: +```js +var collection = new ol.Collection(); +var featureOverlay = new ol.layer.Vector({ + map: map, + style: overlayStyle, + source: new ol.source.Vector({ + features: collection, + useSpatialIndex: false // optional, might improve performance + }); +}); +featureOverlay.getSource().addFeature(feature); +featureOverlay.getSource().removeFeature(feature); +``` + +With the removal of `ol.FeatureOverlay`, `zIndex` symbolizer properties of overlays are no longer stacked per map, but per layer/overlay. If you previously had multiple feature overlays where you controlled the rendering order of features by using `zIndex` symbolizer properties, you can now achieve the same rendering order only if all overlay features are on the same layer. + +Note that `ol.FeatureOverlay#getFeatures()` returned an `{ol.Collection.}`, whereas `ol.source.Vector#getFeatures()` returns an `{Array.}`. + ### v3.6.0 #### `ol.interaction.Draw` changes diff --git a/examples/draw-and-modify-features.js b/examples/draw-and-modify-features.js index ae9d56a018..8e79524424 100644 --- a/examples/draw-and-modify-features.js +++ b/examples/draw-and-modify-features.js @@ -1,11 +1,13 @@ -goog.require('ol.FeatureOverlay'); +goog.require('ol.Collection'); goog.require('ol.Map'); goog.require('ol.View'); goog.require('ol.events.condition'); goog.require('ol.interaction.Draw'); goog.require('ol.interaction.Modify'); goog.require('ol.layer.Tile'); +goog.require('ol.layer.Vector'); goog.require('ol.source.MapQuest'); +goog.require('ol.source.Vector'); goog.require('ol.style.Circle'); goog.require('ol.style.Fill'); goog.require('ol.style.Stroke'); @@ -24,11 +26,9 @@ var map = new ol.Map({ }) }); -// The features are not added to a regular vector layer/source, -// but to a feature overlay which holds a collection of features. -// This collection is passed to the modify and also the draw -// interaction, so that both can add or modify features. -var featureOverlay = new ol.FeatureOverlay({ +var features = new ol.Collection(); +var featureOverlay = new ol.layer.Vector({ + source: new ol.source.Vector({features: features}), style: new ol.style.Style({ fill: new ol.style.Fill({ color: 'rgba(255, 255, 255, 0.2)' @@ -48,7 +48,7 @@ var featureOverlay = new ol.FeatureOverlay({ featureOverlay.setMap(map); var modify = new ol.interaction.Modify({ - features: featureOverlay.getFeatures(), + features: features, // the SHIFT key must be pressed to delete vertices, so // that new vertices can be drawn at the same position // of existing vertices @@ -62,7 +62,7 @@ map.addInteraction(modify); var draw; // global so we can remove it later function addInteraction() { draw = new ol.interaction.Draw({ - features: featureOverlay.getFeatures(), + features: features, type: /** @type {ol.geom.GeometryType} */ (typeSelect.value) }); map.addInteraction(draw); diff --git a/examples/geolocation.js b/examples/geolocation.js index b6b3f70a41..a35eacd2b2 100644 --- a/examples/geolocation.js +++ b/examples/geolocation.js @@ -1,12 +1,13 @@ goog.require('ol.Feature'); -goog.require('ol.FeatureOverlay'); goog.require('ol.Geolocation'); goog.require('ol.Map'); goog.require('ol.View'); goog.require('ol.control'); goog.require('ol.geom.Point'); goog.require('ol.layer.Tile'); +goog.require('ol.layer.Vector'); goog.require('ol.source.OSM'); +goog.require('ol.source.Vector'); goog.require('ol.style.Circle'); goog.require('ol.style.Fill'); goog.require('ol.style.Stroke'); @@ -85,7 +86,9 @@ geolocation.on('change:position', function() { new ol.geom.Point(coordinates) : null); }); -var featuresOverlay = new ol.FeatureOverlay({ +var featuresOverlay = new ol.layer.Vector({ map: map, - features: [accuracyFeature, positionFeature] + source: new ol.source.Vector({ + features: [accuracyFeature, positionFeature] + }) }); diff --git a/examples/icon-sprite-webgl.js b/examples/icon-sprite-webgl.js index ffda56a325..7f65cb3e27 100644 --- a/examples/icon-sprite-webgl.js +++ b/examples/icon-sprite-webgl.js @@ -1,5 +1,4 @@ goog.require('ol.Feature'); -goog.require('ol.FeatureOverlay'); goog.require('ol.Map'); goog.require('ol.View'); goog.require('ol.geom.Point'); @@ -102,12 +101,14 @@ for (i = 0; i < featureCount; i += 30) { overlayFeatures.push(clone); } -var featureOverlay = new ol.FeatureOverlay({ +var featureOverlay = new ol.layer.Vector({ map: map, + source: new ol.source.Vector({ + features: overlayFeatures + }), style: new ol.style.Style({ image: icons[iconCount - 1] - }), - features: overlayFeatures + }) }); map.on('click', function(evt) { diff --git a/examples/igc.js b/examples/igc.js index 43020959ef..5ebd160ec6 100644 --- a/examples/igc.js +++ b/examples/igc.js @@ -1,6 +1,5 @@ goog.require('ol.Attribution'); goog.require('ol.Feature'); -goog.require('ol.FeatureOverlay'); goog.require('ol.Map'); goog.require('ol.View'); goog.require('ol.control'); @@ -180,7 +179,8 @@ map.on('postcompose', function(evt) { } }); -var featureOverlay = new ol.FeatureOverlay({ +var featureOverlay = new ol.layer.Vector({ + source: new ol.source.Vector(), map: map, style: new ol.style.Style({ image: new ol.style.Circle({ @@ -203,7 +203,7 @@ document.getElementById('time').addEventListener('input', function() { if (highlight === undefined) { highlight = new ol.Feature(new ol.geom.Point(coordinate)); feature.set('highlight', highlight); - featureOverlay.addFeature(highlight); + featureOverlay.getSource().addFeature(highlight); } else { highlight.getGeometry().setCoordinates(coordinate); } diff --git a/examples/image-vector-layer.js b/examples/image-vector-layer.js index 6e7eaf352b..47111dfff8 100644 --- a/examples/image-vector-layer.js +++ b/examples/image-vector-layer.js @@ -1,9 +1,9 @@ -goog.require('ol.FeatureOverlay'); goog.require('ol.Map'); goog.require('ol.View'); goog.require('ol.format.GeoJSON'); goog.require('ol.layer.Image'); goog.require('ol.layer.Tile'); +goog.require('ol.layer.Vector'); goog.require('ol.source.ImageVector'); goog.require('ol.source.MapQuest'); goog.require('ol.source.Vector'); @@ -42,7 +42,8 @@ var map = new ol.Map({ }) }); -var featureOverlay = new ol.FeatureOverlay({ +var featureOverlay = new ol.layer.Vector({ + source: new ol.source.Vector(), map: map, style: new ol.style.Style({ stroke: new ol.style.Stroke({ @@ -71,10 +72,10 @@ var displayFeatureInfo = function(pixel) { if (feature !== highlight) { if (highlight) { - featureOverlay.removeFeature(highlight); + featureOverlay.getSource().removeFeature(highlight); } if (feature) { - featureOverlay.addFeature(feature); + featureOverlay.getSource().addFeature(feature); } highlight = feature; } diff --git a/examples/modify-features.js b/examples/modify-features.js index 25c6ee18dc..903cf3bc40 100644 --- a/examples/modify-features.js +++ b/examples/modify-features.js @@ -24,7 +24,9 @@ var vector = new ol.layer.Vector({ }) }); -var select = new ol.interaction.Select(); +var select = new ol.interaction.Select({ + wrapX: false +}); var modify = new ol.interaction.Modify({ features: select.getFeatures() diff --git a/examples/vector-layer.js b/examples/vector-layer.js index 25faeca41f..3b7907c5b3 100644 --- a/examples/vector-layer.js +++ b/examples/vector-layer.js @@ -1,4 +1,3 @@ -goog.require('ol.FeatureOverlay'); goog.require('ol.Map'); goog.require('ol.View'); goog.require('ol.format.GeoJSON'); @@ -60,7 +59,8 @@ var map = new ol.Map({ var highlightStyleCache = {}; -var featureOverlay = new ol.FeatureOverlay({ +var featureOverlay = new ol.layer.Vector({ + source: new ol.source.Vector(), map: map, style: function(feature, resolution) { var text = resolution < 5000 ? feature.get('name') : ''; @@ -106,10 +106,10 @@ var displayFeatureInfo = function(pixel) { if (feature !== highlight) { if (highlight) { - featureOverlay.removeFeature(highlight); + featureOverlay.getSource().removeFeature(highlight); } if (feature) { - featureOverlay.addFeature(feature); + featureOverlay.getSource().addFeature(feature); } highlight = feature; } diff --git a/externs/olx.js b/externs/olx.js index aae7de390a..d6a597db02 100644 --- a/externs/olx.js +++ b/externs/olx.js @@ -2366,7 +2366,8 @@ olx.interaction.DragZoomOptions.prototype.style; * geometryFunction: (ol.interaction.DrawGeometryFunctionType|undefined), * geometryName: (string|undefined), * condition: (ol.events.ConditionType|undefined), - * freehandCondition: (ol.events.ConditionType|undefined)}} + * freehandCondition: (ol.events.ConditionType|undefined), + * wrapX: (boolean|undefined)}} * @api */ olx.interaction.DrawOptions; @@ -2470,6 +2471,14 @@ olx.interaction.DrawOptions.prototype.condition; olx.interaction.DrawOptions.prototype.freehandCondition; +/** + * Wrap the world horizontally on the sketch overlay. Default is `false`. + * @type {boolean|undefined} + * @api + */ +olx.interaction.DrawOptions.prototype.wrapX; + + /** * @typedef {{condition: (ol.events.ConditionType|undefined), * duration: (number|undefined), @@ -2545,7 +2554,8 @@ olx.interaction.KeyboardZoomOptions.prototype.delta; * @typedef {{deleteCondition: (ol.events.ConditionType|undefined), * pixelTolerance: (number|undefined), * style: (ol.style.Style|Array.|ol.style.StyleFunction|undefined), - * features: ol.Collection.}} + * features: ol.Collection., + * wrapX: (boolean|undefined)}} * @api */ olx.interaction.ModifyOptions; @@ -2587,6 +2597,14 @@ olx.interaction.ModifyOptions.prototype.style; olx.interaction.ModifyOptions.prototype.features; +/** + * Wrap the world horizontally on the sketch overlay. Default is `false`. + * @type {boolean|undefined} + * @api + */ +olx.interaction.ModifyOptions.prototype.wrapX; + + /** * @typedef {{duration: (number|undefined)}} * @api @@ -2708,7 +2726,8 @@ olx.interaction.PointerOptions.prototype.handleUpEvent; * removeCondition: (ol.events.ConditionType|undefined), * toggleCondition: (ol.events.ConditionType|undefined), * multi: (boolean|undefined), - * filter: (ol.interaction.SelectFilterFunction|undefined)}} + * filter: (ol.interaction.SelectFilterFunction|undefined), + * wrapX: (boolean|undefined)}} * @api */ olx.interaction.SelectOptions; @@ -2803,6 +2822,14 @@ olx.interaction.SelectOptions.prototype.multi; olx.interaction.SelectOptions.prototype.filter; +/** + * Wrap the world horizontally on the selection overlay. Default is `true`. + * @type {boolean|undefined} + * @api + */ +olx.interaction.SelectOptions.prototype.wrapX; + + /** * Options for snap * @typedef {{ diff --git a/src/ol/featureoverlay.js b/src/ol/featureoverlay.js deleted file mode 100644 index 5a555a0973..0000000000 --- a/src/ol/featureoverlay.js +++ /dev/null @@ -1,326 +0,0 @@ -goog.provide('ol.FeatureOverlay'); - -goog.require('goog.array'); -goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.object'); -goog.require('ol.Collection'); -goog.require('ol.CollectionEventType'); -goog.require('ol.Feature'); -goog.require('ol.render.EventType'); -goog.require('ol.renderer.vector'); -goog.require('ol.style.Style'); - - - -/** - * @classdesc - * A mechanism for changing the style of a small number of features on a - * temporary basis, for example highlighting. This is necessary with the Canvas - * renderer, where, unlike in SVG, features cannot be individually referenced. - * See examples/vector-layers for an example: create a FeatureOverlay with a - * different style, copy the feature(s) you want rendered in this different - * style into it, and then remove them again when you're finished. - * - * @constructor - * @param {olx.FeatureOverlayOptions=} opt_options Options. - * @api - */ -ol.FeatureOverlay = function(opt_options) { - - var options = goog.isDef(opt_options) ? opt_options : {}; - - /** - * @private - * @type {ol.Collection.} - */ - this.features_ = null; - - /** - * @private - * @type {Array.} - */ - this.featuresListenerKeys_ = null; - - /** - * @private - * @type {Object.} - */ - this.featureChangeListenerKeys_ = null; - - /** - * @private - * @type {ol.Map} - */ - this.map_ = null; - - /** - * @private - * @type {goog.events.Key} - */ - this.postComposeListenerKey_ = null; - - /** - * @private - * @type {ol.style.Style|Array.|ol.style.StyleFunction} - */ - this.style_ = null; - - /** - * @private - * @type {ol.style.StyleFunction|undefined} - */ - this.styleFunction_ = undefined; - - this.setStyle(goog.isDef(options.style) ? - options.style : ol.style.defaultStyleFunction); - - if (goog.isDef(options.features)) { - if (goog.isArray(options.features)) { - this.setFeatures(new ol.Collection(options.features.slice())); - } else { - goog.asserts.assertInstanceof(options.features, ol.Collection, - 'options.features should be an ol.Collection'); - this.setFeatures(options.features); - } - } else { - this.setFeatures(new ol.Collection()); - } - - if (goog.isDef(options.map)) { - this.setMap(options.map); - } - -}; - - -/** - * Add a feature to the overlay. - * @param {ol.Feature} feature Feature. - * @api - */ -ol.FeatureOverlay.prototype.addFeature = function(feature) { - this.features_.push(feature); -}; - - -/** - * Get the features on the overlay. - * @return {ol.Collection.} Features collection. - * @api - */ -ol.FeatureOverlay.prototype.getFeatures = function() { - return this.features_; -}; - - -/** - * Get the map associated with the overlay. - * @return {?ol.Map} The map with which this feature overlay is associated. - * @api - */ -ol.FeatureOverlay.prototype.getMap = function() { - return this.map_; -}; - - -/** - * @private - */ -ol.FeatureOverlay.prototype.handleFeatureChange_ = function() { - this.render_(); -}; - - -/** - * @private - * @param {ol.CollectionEvent} collectionEvent Collection event. - */ -ol.FeatureOverlay.prototype.handleFeaturesAdd_ = function(collectionEvent) { - goog.asserts.assert(!goog.isNull(this.featureChangeListenerKeys_), - 'this.featureChangeListenerKeys_ should not be null'); - var feature = /** @type {ol.Feature} */ (collectionEvent.element); - this.featureChangeListenerKeys_[goog.getUid(feature).toString()] = - goog.events.listen(feature, goog.events.EventType.CHANGE, - this.handleFeatureChange_, false, this); - this.render_(); -}; - - -/** - * @private - * @param {ol.CollectionEvent} collectionEvent Collection event. - */ -ol.FeatureOverlay.prototype.handleFeaturesRemove_ = function(collectionEvent) { - goog.asserts.assert(!goog.isNull(this.featureChangeListenerKeys_), - 'this.featureChangeListenerKeys_ should not be null'); - var feature = /** @type {ol.Feature} */ (collectionEvent.element); - var key = goog.getUid(feature).toString(); - goog.events.unlistenByKey(this.featureChangeListenerKeys_[key]); - delete this.featureChangeListenerKeys_[key]; - this.render_(); -}; - - -/** - * Handle changes in image style state. - * @param {goog.events.Event} event Image style change event. - * @private - */ -ol.FeatureOverlay.prototype.handleImageChange_ = function(event) { - this.render_(); -}; - - -/** - * @param {ol.render.Event} event Event. - * @private - */ -ol.FeatureOverlay.prototype.handleMapPostCompose_ = function(event) { - if (goog.isNull(this.features_)) { - return; - } - var styleFunction = this.styleFunction_; - if (!goog.isDef(styleFunction)) { - styleFunction = ol.style.defaultStyleFunction; - } - var replayGroup = /** @type {ol.render.IReplayGroup} */ - (event.replayGroup); - goog.asserts.assert(goog.isDef(replayGroup), - 'replayGroup should be defined'); - var frameState = event.frameState; - var pixelRatio = frameState.pixelRatio; - var resolution = frameState.viewState.resolution; - var squaredTolerance = ol.renderer.vector.getSquaredTolerance(resolution, - pixelRatio); - var i, ii, styles, featureStyleFunction; - this.features_.forEach(function(feature) { - featureStyleFunction = feature.getStyleFunction(); - styles = goog.isDef(featureStyleFunction) ? - featureStyleFunction.call(feature, resolution) : - styleFunction(feature, resolution); - - if (!goog.isDefAndNotNull(styles)) { - return; - } - ii = styles.length; - for (i = 0; i < ii; ++i) { - ol.renderer.vector.renderFeature(replayGroup, feature, styles[i], - squaredTolerance, this.handleImageChange_, this); - } - }, this); -}; - - -/** - * Remove a feature from the overlay. - * @param {ol.Feature} feature The feature to be removed. - * @api - */ -ol.FeatureOverlay.prototype.removeFeature = function(feature) { - this.features_.remove(feature); -}; - - -/** - * @private - */ -ol.FeatureOverlay.prototype.render_ = function() { - if (!goog.isNull(this.map_)) { - this.map_.render(); - } -}; - - -/** - * Set the features for the overlay. - * @param {ol.Collection.} features Features collection. - * @api - */ -ol.FeatureOverlay.prototype.setFeatures = function(features) { - if (!goog.isNull(this.featuresListenerKeys_)) { - goog.array.forEach(this.featuresListenerKeys_, goog.events.unlistenByKey); - this.featuresListenerKeys_ = null; - } - if (!goog.isNull(this.featureChangeListenerKeys_)) { - goog.array.forEach( - goog.object.getValues(this.featureChangeListenerKeys_), - goog.events.unlistenByKey); - this.featureChangeListenerKeys_ = null; - } - this.features_ = features; - if (!goog.isNull(features)) { - this.featuresListenerKeys_ = [ - goog.events.listen(features, ol.CollectionEventType.ADD, - this.handleFeaturesAdd_, false, this), - goog.events.listen(features, ol.CollectionEventType.REMOVE, - this.handleFeaturesRemove_, false, this) - ]; - this.featureChangeListenerKeys_ = {}; - features.forEach(function(feature) { - this.featureChangeListenerKeys_[goog.getUid(feature).toString()] = - goog.events.listen(feature, goog.events.EventType.CHANGE, - this.handleFeatureChange_, false, this); - }, this); - } - this.render_(); -}; - - -/** - * Set the map for the overlay. - * @param {ol.Map} map Map. - * @api - */ -ol.FeatureOverlay.prototype.setMap = function(map) { - if (!goog.isNull(this.postComposeListenerKey_)) { - goog.events.unlistenByKey(this.postComposeListenerKey_); - this.postComposeListenerKey_ = null; - } - this.render_(); - this.map_ = map; - if (!goog.isNull(map)) { - this.postComposeListenerKey_ = goog.events.listen( - map, ol.render.EventType.POSTCOMPOSE, this.handleMapPostCompose_, false, - this); - map.render(); - } -}; - - -/** - * Set the style for features. This can be a single style object, an array - * of styles, or a function that takes a feature and resolution and returns - * an array of styles. - * @param {ol.style.Style|Array.|ol.style.StyleFunction} style - * Overlay style. - * @api - */ -ol.FeatureOverlay.prototype.setStyle = function(style) { - this.style_ = style; - this.styleFunction_ = ol.style.createStyleFunction(style); - this.render_(); -}; - - -/** - * Get the style for features. This returns whatever was passed to the `style` - * option at construction or to the `setStyle` method. - * @return {ol.style.Style|Array.|ol.style.StyleFunction} - * Overlay style. - * @api - */ -ol.FeatureOverlay.prototype.getStyle = function() { - return this.style_; -}; - - -/** - * Get the style function. - * @return {ol.style.StyleFunction|undefined} Style function. - * @api - */ -ol.FeatureOverlay.prototype.getStyleFunction = function() { - return this.styleFunction_; -}; diff --git a/src/ol/interaction/drawinteraction.js b/src/ol/interaction/drawinteraction.js index 1a0cfe6a03..da5e210aad 100644 --- a/src/ol/interaction/drawinteraction.js +++ b/src/ol/interaction/drawinteraction.js @@ -10,7 +10,6 @@ goog.require('goog.events.Event'); goog.require('ol.Collection'); goog.require('ol.Coordinate'); goog.require('ol.Feature'); -goog.require('ol.FeatureOverlay'); goog.require('ol.MapBrowserEvent'); goog.require('ol.MapBrowserEvent.EventType'); goog.require('ol.Object'); @@ -27,6 +26,7 @@ goog.require('ol.geom.Polygon'); goog.require('ol.geom.SimpleGeometry'); goog.require('ol.interaction.InteractionProperty'); goog.require('ol.interaction.Pointer'); +goog.require('ol.layer.Vector'); goog.require('ol.source.Vector'); goog.require('ol.style.Style'); @@ -269,10 +269,14 @@ ol.interaction.Draw = function(options) { /** * Draw overlay where our sketch features are drawn. - * @type {ol.FeatureOverlay} + * @type {ol.layer.Vector} * @private */ - this.overlay_ = new ol.FeatureOverlay({ + this.overlay_ = new ol.layer.Vector({ + source: new ol.source.Vector({ + useSpatialIndex: false, + wrapX: goog.isDef(options.wrapX) ? options.wrapX : false + }), style: goog.isDef(options.style) ? options.style : ol.interaction.Draw.getDefaultStyleFunction() }); @@ -674,7 +678,7 @@ ol.interaction.Draw.prototype.abortDrawing_ = function() { this.sketchFeature_ = null; this.sketchPoint_ = null; this.sketchLine_ = null; - this.overlay_.getFeatures().clear(); + this.overlay_.getSource().clear(); } return sketchFeature; }; @@ -701,7 +705,9 @@ ol.interaction.Draw.prototype.updateSketchFeatures_ = function() { if (!goog.isNull(this.sketchPoint_)) { sketchFeatures.push(this.sketchPoint_); } - this.overlay_.setFeatures(new ol.Collection(sketchFeatures)); + var overlaySource = this.overlay_.getSource(); + overlaySource.clear(); + overlaySource.addFeatures(sketchFeatures); }; diff --git a/src/ol/interaction/modifyinteraction.js b/src/ol/interaction/modifyinteraction.js index 66f3b5ed28..b0276b2195 100644 --- a/src/ol/interaction/modifyinteraction.js +++ b/src/ol/interaction/modifyinteraction.js @@ -7,7 +7,6 @@ goog.require('goog.functions'); goog.require('ol.Collection'); goog.require('ol.CollectionEventType'); goog.require('ol.Feature'); -goog.require('ol.FeatureOverlay'); goog.require('ol.MapBrowserEvent.EventType'); goog.require('ol.ViewHint'); goog.require('ol.coordinate'); @@ -21,6 +20,8 @@ goog.require('ol.geom.MultiPolygon'); goog.require('ol.geom.Point'); goog.require('ol.geom.Polygon'); goog.require('ol.interaction.Pointer'); +goog.require('ol.layer.Vector'); +goog.require('ol.source.Vector'); goog.require('ol.structs.RBush'); goog.require('ol.style.Style'); @@ -112,10 +113,14 @@ ol.interaction.Modify = function(options) { /** * Draw overlay where are sketch features are drawn. - * @type {ol.FeatureOverlay} + * @type {ol.layer.Vector} * @private */ - this.overlay_ = new ol.FeatureOverlay({ + this.overlay_ = new ol.layer.Vector({ + source: new ol.source.Vector({ + useSpatialIndex: false, + wrapX: goog.isDef(options.wrapX) ? options.wrapX : false + }), style: goog.isDef(options.style) ? options.style : ol.interaction.Modify.getDefaultStyleFunction() }); @@ -208,7 +213,7 @@ ol.interaction.Modify.prototype.handleFeatureRemove_ = function(evt) { // There remains only vertexFeature… if (!goog.isNull(this.vertexFeature_) && this.features_.getLength() === 0) { - this.overlay_.removeFeature(this.vertexFeature_); + this.overlay_.getSource().removeFeature(this.vertexFeature_); this.vertexFeature_ = null; } }; @@ -383,7 +388,7 @@ ol.interaction.Modify.prototype.createOrUpdateVertexFeature_ = if (goog.isNull(vertexFeature)) { vertexFeature = new ol.Feature(new ol.geom.Point(coordinates)); this.vertexFeature_ = vertexFeature; - this.overlay_.addFeature(vertexFeature); + this.overlay_.getSource().addFeature(vertexFeature); } else { var geometry = /** @type {ol.geom.Point} */ (vertexFeature.getGeometry()); geometry.setCoordinates(coordinates); @@ -630,7 +635,7 @@ ol.interaction.Modify.prototype.handlePointerAtPixel_ = function(pixel, map) { } } if (!goog.isNull(this.vertexFeature_)) { - this.overlay_.removeFeature(this.vertexFeature_); + this.overlay_.getSource().removeFeature(this.vertexFeature_); this.vertexFeature_ = null; } }; @@ -800,7 +805,7 @@ ol.interaction.Modify.prototype.removeVertex_ = function() { newSegmentData); this.updateSegmentIndices_(geometry, index, segmentData.depth, -1); - this.overlay_.removeFeature(this.vertexFeature_); + this.overlay_.getSource().removeFeature(this.vertexFeature_); this.vertexFeature_ = null; } } diff --git a/src/ol/interaction/selectinteraction.js b/src/ol/interaction/selectinteraction.js index 161eff39ae..2f4e35c71e 100644 --- a/src/ol/interaction/selectinteraction.js +++ b/src/ol/interaction/selectinteraction.js @@ -8,10 +8,11 @@ goog.require('goog.events.Event'); goog.require('goog.functions'); goog.require('ol.CollectionEventType'); goog.require('ol.Feature'); -goog.require('ol.FeatureOverlay'); goog.require('ol.events.condition'); goog.require('ol.geom.GeometryType'); goog.require('ol.interaction.Interaction'); +goog.require('ol.layer.Vector'); +goog.require('ol.source.Vector'); goog.require('ol.style.Style'); @@ -73,7 +74,7 @@ goog.inherits(ol.SelectEvent, goog.events.Event); /** * @classdesc - * Handles selection of vector data. A {@link ol.FeatureOverlay} is maintained + * Handles selection of vector data. An {@link ol.source.Vector} is maintained * internally to store the selected feature(s). Which features are selected is * determined by the `condition` option, and optionally the `toggle` or * `add`/`remove` options. @@ -160,14 +161,18 @@ ol.interaction.Select = function(opt_options) { /** * @private - * @type {ol.FeatureOverlay} + * @type {ol.layer.Vector} */ - this.featureOverlay_ = new ol.FeatureOverlay({ + this.featureOverlay_ = new ol.layer.Vector({ + source: new ol.source.Vector({ + useSpatialIndex: false, + wrapX: options.wrapX + }), style: goog.isDef(options.style) ? options.style : ol.interaction.Select.getDefaultStyleFunction() }); - var features = this.featureOverlay_.getFeatures(); + var features = this.featureOverlay_.getSource().getFeaturesCollection(); goog.events.listen(features, ol.CollectionEventType.ADD, this.addFeature_, false, this); goog.events.listen(features, ol.CollectionEventType.REMOVE, @@ -183,7 +188,7 @@ goog.inherits(ol.interaction.Select, ol.interaction.Interaction); * @api stable */ ol.interaction.Select.prototype.getFeatures = function() { - return this.featureOverlay_.getFeatures(); + return this.featureOverlay_.getSource().getFeaturesCollection(); }; @@ -204,7 +209,7 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) { var toggle = this.toggleCondition_(mapBrowserEvent); var set = !add && !remove && !toggle; var map = mapBrowserEvent.map; - var features = this.featureOverlay_.getFeatures(); + var features = this.featureOverlay_.getSource().getFeaturesCollection(); var /** @type {Array.} */ deselected = []; var /** @type {Array.} */ selected = []; var change = false; @@ -280,7 +285,8 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) { */ ol.interaction.Select.prototype.setMap = function(map) { var currentMap = this.getMap(); - var selectedFeatures = this.featureOverlay_.getFeatures(); + var selectedFeatures = + this.featureOverlay_.getSource().getFeaturesCollection(); if (!goog.isNull(currentMap)) { selectedFeatures.forEach(currentMap.unskipFeature, currentMap); } diff --git a/src/ol/map.js b/src/ol/map.js index 013c4901e7..13806ef880 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -577,10 +577,8 @@ ol.Map.prototype.disposeInternal = function() { * @param {function(this: S, ol.Feature, ol.layer.Layer): T} callback Feature * callback. The callback will be called with two arguments. The first * argument is one {@link ol.Feature feature} at the pixel, the second is - * the {@link ol.layer.Layer layer} of the feature. If the detected feature - * is not on a layer, but on a {@link ol.FeatureOverlay}, then the second - * argument to this function will be `null`. To stop detection, callback - * functions can return a truthy value. + * the {@link ol.layer.Layer layer} of the feature. To stop detection, + * callback functions can return a truthy value. * @param {S=} opt_this Value to use as `this` when executing `callback`. * @param {(function(this: U, ol.layer.Layer): boolean)=} opt_layerFilter Layer * filter function. The filter function will receive one argument, the @@ -618,10 +616,8 @@ ol.Map.prototype.forEachFeatureAtPixel = * @param {ol.Pixel} pixel Pixel. * @param {function(this: S, ol.layer.Layer): T} callback Layer * callback. Will receive one argument, the {@link ol.layer.Layer layer} - * that contains the color pixel. If the detected color value is not from a - * layer, but from a {@link ol.FeatureOverlay}, then the argument to this - * function will be `null`. To stop detection, callback functions can return - * a truthy value. + * that contains the color pixel. To stop detection, callback functions can + * return a truthy value. * @param {S=} opt_this Value to use as `this` when executing `callback`. * @param {(function(this: U, ol.layer.Layer): boolean)=} opt_layerFilter Layer * filter function. The filter function will receive one argument, the diff --git a/src/ol/render/canvas/canvasimmediate.js b/src/ol/render/canvas/canvasimmediate.js index 78306cbd5f..ce0ed0e96e 100644 --- a/src/ol/render/canvas/canvasimmediate.js +++ b/src/ol/render/canvas/canvasimmediate.js @@ -471,8 +471,8 @@ ol.render.canvas.Immediate.prototype.drawCircleGeometry = * Render a feature into the canvas. In order to respect the zIndex of the * style this method draws asynchronously and thus *after* calls to * drawXxxxGeometry have been finished, effectively drawing the feature - * *on top* of everything else. You probably should be using - * {@link ol.FeatureOverlay} instead of calling this method directly. + * *on top* of everything else. You probably should be using an + * {@link ol.layer.Vector} instead of calling this method directly. * * @param {ol.Feature} feature Feature. * @param {ol.style.Style} style Style. diff --git a/src/ol/render/renderevent.js b/src/ol/render/renderevent.js index 6fc57b63bc..6d8810ae7e 100644 --- a/src/ol/render/renderevent.js +++ b/src/ol/render/renderevent.js @@ -35,14 +35,13 @@ ol.render.EventType = { * @param {ol.render.EventType} type Type. * @param {Object=} opt_target Target. * @param {ol.render.VectorContext=} opt_vectorContext Vector context. - * @param {ol.render.IReplayGroup=} opt_replayGroup Replay group. * @param {olx.FrameState=} opt_frameState Frame state. * @param {?CanvasRenderingContext2D=} opt_context Context. * @param {?ol.webgl.Context=} opt_glContext WebGL Context. */ ol.render.Event = function( - type, opt_target, opt_vectorContext, opt_replayGroup, opt_frameState, - opt_context, opt_glContext) { + type, opt_target, opt_vectorContext, opt_frameState, opt_context, + opt_glContext) { goog.base(this, type, opt_target); @@ -53,11 +52,6 @@ ol.render.Event = function( */ this.vectorContext = opt_vectorContext; - /** - * @type {ol.render.IReplayGroup|undefined} - */ - this.replayGroup = opt_replayGroup; - /** * @type {olx.FrameState|undefined} * @api diff --git a/src/ol/renderer/canvas/canvaslayerrenderer.js b/src/ol/renderer/canvas/canvaslayerrenderer.js index ac8b9a112a..7e85d22355 100644 --- a/src/ol/renderer/canvas/canvaslayerrenderer.js +++ b/src/ol/renderer/canvas/canvaslayerrenderer.js @@ -131,8 +131,8 @@ ol.renderer.canvas.Layer.prototype.dispatchComposeEvent_ = var render = new ol.render.canvas.Immediate( context, frameState.pixelRatio, frameState.extent, transform, frameState.viewState.rotation); - var composeEvent = new ol.render.Event(type, layer, render, null, - frameState, context, null); + var composeEvent = new ol.render.Event(type, layer, render, frameState, + context, null); layer.dispatchEvent(composeEvent); render.flush(); } diff --git a/src/ol/renderer/canvas/canvasmaprenderer.js b/src/ol/renderer/canvas/canvasmaprenderer.js index 6a1c38e691..609dc09c02 100644 --- a/src/ol/renderer/canvas/canvasmaprenderer.js +++ b/src/ol/renderer/canvas/canvasmaprenderer.js @@ -10,7 +10,6 @@ goog.require('ol'); goog.require('ol.RendererType'); goog.require('ol.css'); goog.require('ol.dom'); -goog.require('ol.extent'); goog.require('ol.layer.Image'); goog.require('ol.layer.Layer'); goog.require('ol.layer.Tile'); @@ -18,13 +17,11 @@ goog.require('ol.layer.Vector'); goog.require('ol.render.Event'); goog.require('ol.render.EventType'); goog.require('ol.render.canvas.Immediate'); -goog.require('ol.render.canvas.ReplayGroup'); goog.require('ol.renderer.Map'); goog.require('ol.renderer.canvas.ImageLayer'); goog.require('ol.renderer.canvas.Layer'); goog.require('ol.renderer.canvas.TileLayer'); goog.require('ol.renderer.canvas.VectorLayer'); -goog.require('ol.renderer.vector'); goog.require('ol.source.State'); goog.require('ol.vec.Mat4'); @@ -103,55 +100,27 @@ ol.renderer.canvas.Map.prototype.dispatchComposeEvent_ = var extent = frameState.extent; var pixelRatio = frameState.pixelRatio; var viewState = frameState.viewState; - var projection = viewState.projection; - var resolution = viewState.resolution; var rotation = viewState.rotation; - var offsetX = 0; - if (projection.canWrapX()) { - var projectionExtent = projection.getExtent(); - var worldWidth = ol.extent.getWidth(projectionExtent); - var x = frameState.focus[0]; - if (x < projectionExtent[0] || x > projectionExtent[2]) { - var worldsAway = Math.ceil((projectionExtent[0] - x) / worldWidth); - offsetX = worldWidth * worldsAway; - extent = [ - extent[0] + offsetX, extent[1], - extent[2] + offsetX, extent[3] - ]; - } - } - - var transform = this.getTransform(frameState, offsetX); - - var tolerance = ol.renderer.vector.getTolerance(resolution, pixelRatio); - var replayGroup = new ol.render.canvas.ReplayGroup( - tolerance, extent, resolution); + var transform = this.getTransform(frameState); var vectorContext = new ol.render.canvas.Immediate(context, pixelRatio, extent, transform, rotation); var composeEvent = new ol.render.Event(type, map, vectorContext, - replayGroup, frameState, context, null); + frameState, context, null); map.dispatchEvent(composeEvent); - replayGroup.finish(); - if (!replayGroup.isEmpty()) { - replayGroup.replay(context, pixelRatio, transform, rotation, {}); - - } vectorContext.flush(); - this.replayGroup = replayGroup; } }; /** * @param {olx.FrameState} frameState Frame state. - * @param {number} offsetX Offset on the x-axis in view coordinates. * @protected * @return {!goog.vec.Mat4.Number} Transform. */ -ol.renderer.canvas.Map.prototype.getTransform = function(frameState, offsetX) { +ol.renderer.canvas.Map.prototype.getTransform = function(frameState) { var pixelRatio = frameState.pixelRatio; var viewState = frameState.viewState; var resolution = viewState.resolution; @@ -159,8 +128,7 @@ ol.renderer.canvas.Map.prototype.getTransform = function(frameState, offsetX) { this.canvas_.width / 2, this.canvas_.height / 2, pixelRatio / resolution, -pixelRatio / resolution, -viewState.rotation, - -viewState.center[0] - offsetX, - -viewState.center[1]); + -viewState.center[0], -viewState.center[1]); }; diff --git a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js index 6cebf93ab7..e9a1c4b5b2 100644 --- a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js +++ b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js @@ -77,7 +77,6 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, layerState, context) { var extent = frameState.extent; - var focus = frameState.focus; var pixelRatio = frameState.pixelRatio; var skippedFeatureUids = layerState.unmanaged ? {} : frameState.skippedFeatureUids; @@ -109,20 +108,11 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = // see http://jsperf.com/context-save-restore-versus-variable var alpha = replayContext.globalAlpha; replayContext.globalAlpha = layerState.opacity; - var noSkip = {}; - var focusX = focus[0]; + replayGroup.replay(replayContext, pixelRatio, transform, rotation, + skippedFeatureUids); if (vectorSource.getWrapX() && projection.canWrapX() && !ol.extent.containsExtent(projectionExtent, extent)) { - var projLeft = projectionExtent[0]; - var projRight = projectionExtent[2]; - // A feature from skippedFeatureUids will only be skipped in the world - // that has the frameState's focus, because this is where a feature - // overlay for highlighting or selection would render the skipped - // feature. - replayGroup.replay(replayContext, pixelRatio, transform, rotation, - projLeft <= focusX && focusX <= projRight ? - skippedFeatureUids : noSkip); var startX = extent[0]; var worldWidth = ol.extent.getWidth(projectionExtent); var world = 0; @@ -132,8 +122,7 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = offsetX = worldWidth * world; transform = this.getTransform(frameState, offsetX); replayGroup.replay(replayContext, pixelRatio, transform, rotation, - projLeft + offsetX <= focusX && focusX <= projRight + offsetX ? - skippedFeatureUids : noSkip); + skippedFeatureUids); startX += worldWidth; } world = 0; @@ -143,13 +132,9 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = offsetX = worldWidth * world; transform = this.getTransform(frameState, offsetX); replayGroup.replay(replayContext, pixelRatio, transform, rotation, - projLeft + offsetX <= focusX && focusX <= projRight + offsetX ? - skippedFeatureUids : noSkip); + skippedFeatureUids); startX -= worldWidth; } - } else { - replayGroup.replay( - replayContext, pixelRatio, transform, rotation, skippedFeatureUids); } if (replayContext != context) { diff --git a/src/ol/renderer/dom/dommaprenderer.js b/src/ol/renderer/dom/dommaprenderer.js index ea2cb5ee6e..bbe8e4e9ca 100644 --- a/src/ol/renderer/dom/dommaprenderer.js +++ b/src/ol/renderer/dom/dommaprenderer.js @@ -20,13 +20,11 @@ goog.require('ol.layer.Vector'); goog.require('ol.render.Event'); goog.require('ol.render.EventType'); goog.require('ol.render.canvas.Immediate'); -goog.require('ol.render.canvas.ReplayGroup'); goog.require('ol.renderer.Map'); goog.require('ol.renderer.dom.ImageLayer'); goog.require('ol.renderer.dom.Layer'); goog.require('ol.renderer.dom.TileLayer'); goog.require('ol.renderer.dom.VectorLayer'); -goog.require('ol.renderer.vector'); goog.require('ol.source.State'); goog.require('ol.vec.Mat4'); @@ -139,7 +137,6 @@ ol.renderer.dom.Map.prototype.dispatchComposeEvent_ = var extent = frameState.extent; var pixelRatio = frameState.pixelRatio; var viewState = frameState.viewState; - var resolution = viewState.resolution; var rotation = viewState.rotation; var context = this.context_; var canvas = context.canvas; @@ -153,18 +150,10 @@ ol.renderer.dom.Map.prototype.dispatchComposeEvent_ = -viewState.center[0], -viewState.center[1]); var vectorContext = new ol.render.canvas.Immediate(context, pixelRatio, extent, this.transform_, rotation); - var replayGroup = new ol.render.canvas.ReplayGroup( - ol.renderer.vector.getTolerance(resolution, pixelRatio), extent, - resolution); var composeEvent = new ol.render.Event(type, map, vectorContext, - replayGroup, frameState, context, null); + frameState, context, null); map.dispatchEvent(composeEvent); - replayGroup.finish(); - if (!replayGroup.isEmpty()) { - replayGroup.replay(context, pixelRatio, this.transform_, rotation, {}); - } vectorContext.flush(); - this.replayGroup = replayGroup; } }; diff --git a/src/ol/renderer/dom/domvectorlayerrenderer.js b/src/ol/renderer/dom/domvectorlayerrenderer.js index 79c1bfb776..a59873f645 100644 --- a/src/ol/renderer/dom/domvectorlayerrenderer.js +++ b/src/ol/renderer/dom/domvectorlayerrenderer.js @@ -165,8 +165,8 @@ ol.renderer.dom.VectorLayer.prototype.dispatchEvent_ = var render = new ol.render.canvas.Immediate( context, frameState.pixelRatio, frameState.extent, transform, frameState.viewState.rotation); - var event = new ol.render.Event(type, layer, render, null, - frameState, context, null); + var event = new ol.render.Event(type, layer, render, frameState, + context, null); layer.dispatchEvent(event); render.flush(); } diff --git a/src/ol/renderer/maprenderer.js b/src/ol/renderer/maprenderer.js index 666ae642b0..9d5344ee22 100644 --- a/src/ol/renderer/maprenderer.js +++ b/src/ol/renderer/maprenderer.js @@ -48,12 +48,6 @@ ol.renderer.Map = function(container, map) { */ this.map_ = map; - /** - * @protected - * @type {ol.render.IReplayGroup} - */ - this.replayGroup = null; - /** * @private * @type {Object.} @@ -137,7 +131,6 @@ ol.renderer.Map.prototype.forEachFeatureAtCoordinate = var result; var viewState = frameState.viewState; var viewResolution = viewState.resolution; - var viewRotation = viewState.rotation; /** @type {Object.} */ var features = {}; @@ -168,13 +161,6 @@ ol.renderer.Map.prototype.forEachFeatureAtCoordinate = } } - if (!goog.isNull(this.replayGroup)) { - result = this.replayGroup.forEachFeatureAtCoordinate(translatedCoordinate, - viewResolution, viewRotation, {}, forEachFeatureAtCoordinate); - if (result) { - return result; - } - } var layerStates = frameState.layerStatesArray; var numLayers = layerStates.length; var i; @@ -216,20 +202,7 @@ ol.renderer.Map.prototype.forEachLayerAtPixel = var result; var viewState = frameState.viewState; var viewResolution = viewState.resolution; - var viewRotation = viewState.rotation; - if (!goog.isNull(this.replayGroup)) { - var coordinate = this.getMap().getCoordinateFromPixel(pixel); - var hasFeature = this.replayGroup.forEachFeatureAtCoordinate(coordinate, - viewResolution, viewRotation, {}, goog.functions.TRUE); - - if (hasFeature) { - result = callback.call(thisArg, null); - if (result) { - return result; - } - } - } var layerStates = frameState.layerStatesArray; var numLayers = layerStates.length; var i; diff --git a/src/ol/renderer/webgl/webgllayerrenderer.js b/src/ol/renderer/webgl/webgllayerrenderer.js index 45b66f2512..30b37343e9 100644 --- a/src/ol/renderer/webgl/webgllayerrenderer.js +++ b/src/ol/renderer/webgl/webgllayerrenderer.js @@ -247,7 +247,7 @@ ol.renderer.webgl.Layer.prototype.dispatchComposeEvent_ = var render = new ol.render.webgl.Immediate( context, center, resolution, rotation, size, extent, pixelRatio); var composeEvent = new ol.render.Event( - type, layer, render, null, frameState, null, context); + type, layer, render, frameState, null, context); layer.dispatchEvent(composeEvent); } }; diff --git a/src/ol/renderer/webgl/webglmaprenderer.js b/src/ol/renderer/webgl/webglmaprenderer.js index c90f09536a..a62a8f0348 100644 --- a/src/ol/renderer/webgl/webglmaprenderer.js +++ b/src/ol/renderer/webgl/webglmaprenderer.js @@ -24,9 +24,7 @@ goog.require('ol.layer.Vector'); goog.require('ol.render.Event'); goog.require('ol.render.EventType'); goog.require('ol.render.webgl.Immediate'); -goog.require('ol.render.webgl.ReplayGroup'); goog.require('ol.renderer.Map'); -goog.require('ol.renderer.vector'); goog.require('ol.renderer.webgl.ImageLayer'); goog.require('ol.renderer.webgl.Layer'); goog.require('ol.renderer.webgl.TileLayer'); @@ -287,27 +285,14 @@ ol.renderer.webgl.Map.prototype.dispatchComposeEvent_ = var resolution = viewState.resolution; var center = viewState.center; var rotation = viewState.rotation; - var tolerance = ol.renderer.vector.getTolerance(resolution, pixelRatio); var vectorContext = new ol.render.webgl.Immediate(context, center, resolution, rotation, size, extent, pixelRatio); - var replayGroup = new ol.render.webgl.ReplayGroup(tolerance, extent); var composeEvent = new ol.render.Event(type, map, vectorContext, - replayGroup, frameState, null, context); + frameState, null, context); map.dispatchEvent(composeEvent); - replayGroup.finish(context); - if (!replayGroup.isEmpty()) { - // use default color values - var d = ol.renderer.webgl.Map.DEFAULT_COLOR_VALUES_; - replayGroup.replay(context, center, resolution, rotation, size, - pixelRatio, d.opacity, d.brightness, d.contrast, - d.hue, d.saturation, {}); - } - replayGroup.getDeleteResourcesFunction(context)(); - vectorContext.flush(); - this.replayGroup = replayGroup; } }; @@ -561,37 +546,8 @@ ol.renderer.webgl.Map.prototype.forEachFeatureAtCoordinate = return false; } - var context = this.getContext(); var viewState = frameState.viewState; - // do the hit-detection for the overlays first - if (!goog.isNull(this.replayGroup)) { - /** @type {Object.} */ - var features = {}; - - // use default color values - var d = ol.renderer.webgl.Map.DEFAULT_COLOR_VALUES_; - - result = this.replayGroup.forEachFeatureAtCoordinate(coordinate, - context, viewState.center, viewState.resolution, viewState.rotation, - frameState.size, frameState.pixelRatio, - d.opacity, d.brightness, d.contrast, d.hue, d.saturation, {}, - /** - * @param {ol.Feature} feature Feature. - * @return {?} Callback result. - */ - function(feature) { - goog.asserts.assert(goog.isDef(feature), 'received a feature'); - var key = goog.getUid(feature).toString(); - if (!(key in features)) { - features[key] = true; - return callback.call(thisArg, feature, null); - } - }); - if (result) { - return result; - } - } var layerStates = frameState.layerStatesArray; var numLayers = layerStates.length; var i; @@ -623,22 +579,8 @@ ol.renderer.webgl.Map.prototype.hasFeatureAtCoordinate = return false; } - var context = this.getContext(); var viewState = frameState.viewState; - // do the hit-detection for the overlays first - if (!goog.isNull(this.replayGroup)) { - // use default color values - var d = ol.renderer.webgl.Map.DEFAULT_COLOR_VALUES_; - - hasFeature = this.replayGroup.hasFeatureAtCoordinate(coordinate, - context, viewState.center, viewState.resolution, viewState.rotation, - frameState.size, frameState.pixelRatio, - d.opacity, d.brightness, d.contrast, d.hue, d.saturation, {}); - if (hasFeature) { - return true; - } - } var layerStates = frameState.layerStatesArray; var numLayers = layerStates.length; var i; @@ -669,27 +611,9 @@ ol.renderer.webgl.Map.prototype.forEachLayerAtPixel = return false; } - var context = this.getContext(); var viewState = frameState.viewState; var result; - // do the hit-detection for the overlays first - if (!goog.isNull(this.replayGroup)) { - // use default color values - var d = ol.renderer.webgl.Map.DEFAULT_COLOR_VALUES_; - var coordinate = this.getMap().getCoordinateFromPixel(pixel); - - var hasFeature = this.replayGroup.hasFeatureAtCoordinate(coordinate, - context, viewState.center, viewState.resolution, viewState.rotation, - frameState.size, frameState.pixelRatio, - d.opacity, d.brightness, d.contrast, d.hue, d.saturation, {}); - if (hasFeature) { - result = callback.call(thisArg, null); - if (result) { - return result; - } - } - } var layerStates = frameState.layerStatesArray; var numLayers = layerStates.length; var i; diff --git a/test/spec/ol/featureoverlay.test.js b/test/spec/ol/featureoverlay.test.js deleted file mode 100644 index 78fc78fbc3..0000000000 --- a/test/spec/ol/featureoverlay.test.js +++ /dev/null @@ -1,42 +0,0 @@ -goog.provide('ol.test.FeatureOverlay'); - -describe('ol.FeatureOverlay', function() { - - describe('constructor', function() { - - it('creates an new feature overlay', function() { - var featureOverlay = new ol.FeatureOverlay(); - expect(featureOverlay).to.be.a(ol.FeatureOverlay); - }); - - it('takes features', function() { - var featureOverlay = new ol.FeatureOverlay({ - features: [new ol.Feature(new ol.geom.Point([0, 0]))] - }); - expect(featureOverlay.getFeatures().getLength()).to.be(1); - }); - - it('takes a style', function() { - var style = [new ol.style.Style()]; - var featureOverlay = new ol.FeatureOverlay({ - style: [new ol.style.Style()] - }); - expect(featureOverlay.getStyle()).to.eql(style); - expect(featureOverlay.getStyleFunction()()).to.eql(style); - }); - - it('takes a map', function() { - var map = new ol.Map({}); - var featureOverlay = new ol.FeatureOverlay({ - map: map - }); - expect(featureOverlay.getMap()).to.eql(map); - }); - }); -}); - -goog.require('ol.Feature'); -goog.require('ol.FeatureOverlay'); -goog.require('ol.Map'); -goog.require('ol.geom.Point'); -goog.require('ol.style.Style'); diff --git a/test/spec/ol/interaction/drawinteraction.test.js b/test/spec/ol/interaction/drawinteraction.test.js index 91c7df892b..140104c6a8 100644 --- a/test/spec/ol/interaction/drawinteraction.test.js +++ b/test/spec/ol/interaction/drawinteraction.test.js @@ -619,17 +619,19 @@ describe('ol.interaction.Draw', function() { describe('#setActive(false)', function() { it('unsets the map from the feature overlay', function() { + var spy = sinon.spy(interaction.overlay_, 'setMap'); interaction.setActive(false); - expect(interaction.overlay_.map_).to.be(null); + expect(spy.getCall(0).args[0]).to.be(null); }); it('aborts the drawing', function() { interaction.setActive(false); expect(interaction.sketchFeature_).to.be(null); }); it('fires change:active', function() { + var spy = sinon.spy(interaction.overlay_, 'setMap'); var listenerSpy = sinon.spy(function() { // test that the interaction's change:active listener is called first - expect(interaction.overlay_.map_).to.be(null); + expect(spy.getCall(0).args[0]).to.be(null); }); interaction.on('change:active', listenerSpy); interaction.setActive(false); @@ -642,13 +644,15 @@ describe('ol.interaction.Draw', function() { interaction.setActive(false); }); it('sets the map into the feature overlay', function() { + var spy = sinon.spy(interaction.overlay_, 'setMap'); interaction.setActive(true); - expect(interaction.overlay_.map_).to.be(map); + expect(spy.getCall(0).args[0]).to.be(map); }); it('fires change:active', function() { + var spy = sinon.spy(interaction.overlay_, 'setMap'); var listenerSpy = sinon.spy(function() { // test that the interaction's change:active listener is called first - expect(interaction.overlay_.map_).not.to.be(null); + expect(spy.getCall(0).args[0]).to.be(map); }); interaction.on('change:active', listenerSpy); interaction.setActive(true); @@ -682,8 +686,9 @@ describe('ol.interaction.Draw', function() { }); describe('#setMap(null) when interaction is active', function() { it('unsets the map from the feature overlay', function() { + var spy = sinon.spy(interaction.overlay_, 'setMap'); interaction.setMap(null); - expect(interaction.overlay_.map_).to.be(null); + expect(spy.getCall(0).args[0]).to.be(null); }); it('aborts the drawing', function() { interaction.setMap(null); @@ -695,15 +700,17 @@ describe('ol.interaction.Draw', function() { describe('#setMap(map)', function() { describe('#setMap(map) when interaction is active', function() { it('sets the map into the feature overlay', function() { + var spy = sinon.spy(interaction.overlay_, 'setMap'); interaction.setMap(map); - expect(interaction.overlay_.map_).to.be(map); + expect(spy.getCall(0).args[0]).to.be(map); }); }); describe('#setMap(map) when interaction is not active', function() { it('does not set the map into the feature overlay', function() { interaction.setActive(false); + var spy = sinon.spy(interaction.overlay_, 'setMap'); interaction.setMap(map); - expect(interaction.overlay_.map_).to.be(null); + expect(spy.getCall(0).args[0]).to.be(null); }); }); diff --git a/test/spec/ol/interaction/selectinteraction.test.js b/test/spec/ol/interaction/selectinteraction.test.js index 101c87a783..50a05ac798 100644 --- a/test/spec/ol/interaction/selectinteraction.test.js +++ b/test/spec/ol/interaction/selectinteraction.test.js @@ -219,15 +219,8 @@ describe('ol.interaction.Select', function() { beforeEach(function() { interaction.setActive(false); }); - it('sets the map into the feature overlay', function() { - interaction.setActive(true); - expect(interaction.featureOverlay_.map_).to.be(map); - }); it('fires change:active', function() { - var listenerSpy = sinon.spy(function() { - // test that the interaction's change:active listener is called first - expect(interaction.featureOverlay_.map_).not.to.be(null); - }); + var listenerSpy = sinon.spy(); interaction.on('change:active', listenerSpy); interaction.setActive(true); expect(listenerSpy.callCount).to.be(1); @@ -253,8 +246,9 @@ describe('ol.interaction.Select', function() { }); describe('#setMap(null) when interaction is active', function() { it('unsets the map from the feature overlay', function() { + var spy = sinon.spy(interaction.featureOverlay_, 'setMap'); interaction.setMap(null); - expect(interaction.featureOverlay_.map_).to.be(null); + expect(spy.getCall(0).args[0]).to.be(null); }); }); }); @@ -262,8 +256,9 @@ describe('ol.interaction.Select', function() { describe('#setMap(map)', function() { describe('#setMap(map) when interaction is active', function() { it('sets the map into the feature overlay', function() { + var spy = sinon.spy(interaction.featureOverlay_, 'setMap'); interaction.setMap(map); - expect(interaction.featureOverlay_.map_).to.be(map); + expect(spy.getCall(0).args[0]).to.be(map); }); }); }); diff --git a/test/spec/ol/renderer/canvas/canvasmaprenderer.test.js b/test/spec/ol/renderer/canvas/canvasmaprenderer.test.js index f5209f1ce6..b46ad7579d 100644 --- a/test/spec/ol/renderer/canvas/canvasmaprenderer.test.js +++ b/test/spec/ol/renderer/canvas/canvasmaprenderer.test.js @@ -31,52 +31,6 @@ describe('ol.renderer.canvas.Map', function() { renderer.layerRenderers_[goog.getUid(layer)] = layerRenderer; }); - it('uses correct extent and offset on wrapped worlds', function() { - var spy = sinon.spy(renderer, 'getTransform'); - var proj = new ol.proj.Projection({ - code: 'foo', - extent: [-180, -90, 180, 90], - global: true - }); - var frameState = { - coordinateToPixelMatrix: map.coordinateToPixelMatrix_, - pixelToCoordinateMatrix: map.pixelToCoordinateMatrix_, - pixelRatio: 1, - size: [100, 100], - skippedFeatureUids: {}, - extent: proj.getExtent(), - viewState: { - center: [0, 0], - projection: proj, - resolution: 1, - rotation: 0 - }, - layerStates: {}, - layerStatesArray: [{ - layer: layer, - sourceState: 'ready', - visible: true, - minResolution: 1, - maxResolution: 2 - }], - postRenderFunctions: [] - }; - frameState.focus = [0, 0]; - // focus is on real world - renderer.renderFrame(frameState); - expect(spy.getCall(0).args[1]).to.be(0); - expect(renderer.replayGroup.maxExtent_).to.eql([-180, -90, 180, 90]); - frameState.focus = [-200, 0]; - // focus is one world left of the real world - renderer.renderFrame(frameState); - expect(spy.getCall(1).args[1]).to.be(360); - expect(renderer.replayGroup.maxExtent_).to.eql([180, -90, 540, 90]); - frameState.focus = [200, 0]; - // focus is one world right of the real world - renderer.renderFrame(frameState); - expect(spy.getCall(2).args[1]).to.be(-360); - expect(renderer.replayGroup.maxExtent_).to.eql([-540, -90, -180, 90]); - }); }); }); @@ -84,7 +38,6 @@ describe('ol.renderer.canvas.Map', function() { goog.require('ol.layer.Vector'); goog.require('ol.Map'); -goog.require('ol.proj.Projection'); goog.require('ol.renderer.canvas.Layer'); goog.require('ol.renderer.canvas.Map'); goog.require('ol.source.Vector');