@@ -0,0 +1,56 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||||
|
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
|
||||||
|
<link rel="stylesheet" href="../css/ol.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap.min.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
|
||||||
|
<title>Select features example</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<div class="container">
|
||||||
|
<a class="brand" href="./">OpenLayers 3 Examples</a>
|
||||||
|
<ul class="nav pull-right">
|
||||||
|
<li><iframe class="github-watch-button" src="http://ghbtns.com/github-btn.html?user=openlayers&repo=ol3&type=watch&count=true"
|
||||||
|
allowtransparency="true" frameborder="0" scrolling="0" height="20" width="90"></iframe></li>
|
||||||
|
<li><a href="https://twitter.com/share" class="twitter-share-button" data-count="none" data-hashtags="openlayers"> </a></li>
|
||||||
|
<li><div class="g-plusone-wrapper"><div class="g-plusone" data-size="medium" data-annotation="none"></div></div></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span12">
|
||||||
|
<div id="map" class="map"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row-fluid">
|
||||||
|
|
||||||
|
<div class="span12">
|
||||||
|
<h4 id="title">Select features example</h4>
|
||||||
|
<p id="shortdesc">Example of using the Select interaction. Select features by clicking polygons. Hold the Shift-key to add to the selection.</p>
|
||||||
|
<div id="docs">
|
||||||
|
<p>See the <a href="select-features.js" target="_blank">select-features.js source</a> to see how this is done.</p>
|
||||||
|
</div>
|
||||||
|
<div id="tags">select, vector</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="loader.js?id=select-features" type="text/javascript"></script>
|
||||||
|
<script src="../resources/social-links.js" type="text/javascript"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
goog.require('ol.Map');
|
||||||
|
goog.require('ol.RendererHint');
|
||||||
|
goog.require('ol.View2D');
|
||||||
|
goog.require('ol.interaction.Select');
|
||||||
|
goog.require('ol.interaction.defaults');
|
||||||
|
goog.require('ol.layer.TileLayer');
|
||||||
|
goog.require('ol.layer.Vector');
|
||||||
|
goog.require('ol.parser.ogc.GML_v3');
|
||||||
|
goog.require('ol.source.MapQuestOpenAerial');
|
||||||
|
goog.require('ol.source.Vector');
|
||||||
|
goog.require('ol.style.Fill');
|
||||||
|
goog.require('ol.style.Rule');
|
||||||
|
goog.require('ol.style.Stroke');
|
||||||
|
goog.require('ol.style.Style');
|
||||||
|
|
||||||
|
var raster = new ol.layer.TileLayer({
|
||||||
|
source: new ol.source.MapQuestOpenAerial()
|
||||||
|
});
|
||||||
|
|
||||||
|
var vector = new ol.layer.Vector({
|
||||||
|
id: 'vector',
|
||||||
|
source: new ol.source.Vector({
|
||||||
|
parser: new ol.parser.ogc.GML_v3(),
|
||||||
|
url: 'data/gml/topp-states-wfs.xml'
|
||||||
|
}),
|
||||||
|
style: new ol.style.Style({
|
||||||
|
rules: [
|
||||||
|
new ol.style.Rule({
|
||||||
|
filter: 'renderIntent("selected")',
|
||||||
|
symbolizers: [
|
||||||
|
new ol.style.Fill({
|
||||||
|
color: '#ffffff',
|
||||||
|
opacity: 0.5
|
||||||
|
})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
],
|
||||||
|
symbolizers: [
|
||||||
|
new ol.style.Fill({
|
||||||
|
color: '#ffffff',
|
||||||
|
opacity: 0.25
|
||||||
|
}),
|
||||||
|
new ol.style.Stroke({
|
||||||
|
color: '#6666ff'
|
||||||
|
})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
var selectInteraction = new ol.interaction.Select({
|
||||||
|
layerFilter: function(layer) { return layer.get('id') == 'vector'; }
|
||||||
|
});
|
||||||
|
|
||||||
|
var map = new ol.Map({
|
||||||
|
interactions: ol.interaction.defaults().extend([selectInteraction]),
|
||||||
|
layers: [raster, vector],
|
||||||
|
renderer: ol.RendererHint.CANVAS,
|
||||||
|
target: 'map',
|
||||||
|
view: new ol.View2D({
|
||||||
|
center: [-11000000, 4600000],
|
||||||
|
zoom: 4
|
||||||
|
})
|
||||||
|
});
|
||||||
@@ -244,7 +244,7 @@
|
|||||||
/**
|
/**
|
||||||
* @typedef {Object} ol.interaction.DragPanOptions
|
* @typedef {Object} ol.interaction.DragPanOptions
|
||||||
* @property {ol.Kinetic|undefined} kinetic Kinetic.
|
* @property {ol.Kinetic|undefined} kinetic Kinetic.
|
||||||
* @property {ol.interaction.ConditionType|undefined} condition Conditon.
|
* @property {ol.interaction.ConditionType|undefined} condition Condition.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -295,6 +295,13 @@
|
|||||||
* @property {number|undefined} delta Delta.
|
* @property {number|undefined} delta Delta.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} ol.interaction.SelectOptions
|
||||||
|
* @property {ol.interaction.ConditionType|undefined} condition Condition.
|
||||||
|
* @property {undefined|function(ol.layer.Layer):boolean} layerFilter Filter
|
||||||
|
* function to restrict selection to a subset of layers.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} ol.interaction.TouchPanOptions
|
* @typedef {Object} ol.interaction.TouchPanOptions
|
||||||
* @property {ol.Kinetic|undefined} kinetic Kinetic.
|
* @property {ol.Kinetic|undefined} kinetic Kinetic.
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ ol.expr.functions = {
|
|||||||
EXTENT: 'extent',
|
EXTENT: 'extent',
|
||||||
FID: 'fid',
|
FID: 'fid',
|
||||||
GEOMETRY_TYPE: 'geometryType',
|
GEOMETRY_TYPE: 'geometryType',
|
||||||
|
RENDER_INTENT: 'renderIntent',
|
||||||
INTERSECTS: 'intersects',
|
INTERSECTS: 'intersects',
|
||||||
CONTAINS: 'contains',
|
CONTAINS: 'contains',
|
||||||
DWITHIN: 'dwithin',
|
DWITHIN: 'dwithin',
|
||||||
@@ -252,6 +253,17 @@ ol.expr.lib[ol.expr.functions.GEOMETRY_TYPE] = function(type) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if a feature's renderIntent matches the given one.
|
||||||
|
* @param {string} renderIntent Render intent.
|
||||||
|
* @return {boolean} The feature's renderIntent matches the given one.
|
||||||
|
* @this {ol.Feature}
|
||||||
|
*/
|
||||||
|
ol.expr.lib[ol.expr.functions.RENDER_INTENT] = function(renderIntent) {
|
||||||
|
return this.renderIntent == renderIntent;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
ol.expr.lib[ol.expr.functions.INTERSECTS] = function(geom, opt_projection,
|
ol.expr.lib[ol.expr.functions.INTERSECTS] = function(geom, opt_projection,
|
||||||
opt_attribute) {
|
opt_attribute) {
|
||||||
throw new Error('Spatial function not implemented: ' +
|
throw new Error('Spatial function not implemented: ' +
|
||||||
|
|||||||
+8
-1
@@ -2,6 +2,7 @@ goog.provide('ol.Feature');
|
|||||||
|
|
||||||
goog.require('ol.Object');
|
goog.require('ol.Object');
|
||||||
goog.require('ol.geom.Geometry');
|
goog.require('ol.geom.Geometry');
|
||||||
|
goog.require('ol.layer.VectorLayerRenderIntent');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -34,6 +35,12 @@ ol.Feature = function(opt_values) {
|
|||||||
*/
|
*/
|
||||||
this.geometryName_;
|
this.geometryName_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The render intent for this feature.
|
||||||
|
* @type {ol.layer.VectorLayerRenderIntent|string}
|
||||||
|
*/
|
||||||
|
this.renderIntent = ol.layer.VectorLayerRenderIntent.DEFAULT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Array.<ol.style.Symbolizer>}
|
* @type {Array.<ol.style.Symbolizer>}
|
||||||
* @private
|
* @private
|
||||||
@@ -109,7 +116,7 @@ ol.Feature.prototype.set = function(key, value) {
|
|||||||
* Set the feature's commonly used identifier. This identifier is usually the
|
* Set the feature's commonly used identifier. This identifier is usually the
|
||||||
* unique id in the source store.
|
* unique id in the source store.
|
||||||
*
|
*
|
||||||
* @param {string} featureId The feature's identifier.
|
* @param {string|undefined} featureId The feature's identifier.
|
||||||
*/
|
*/
|
||||||
ol.Feature.prototype.setFeatureId = function(featureId) {
|
ol.Feature.prototype.setFeatureId = function(featureId) {
|
||||||
this.featureId_ = featureId;
|
this.featureId_ = featureId;
|
||||||
|
|||||||
@@ -27,6 +27,19 @@ ol.geom.Geometry = function() {
|
|||||||
ol.geom.Geometry.prototype.dimension;
|
ol.geom.Geometry.prototype.dimension;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a clone of this geometry. The clone will not be represented in any
|
||||||
|
* shared structure.
|
||||||
|
* @return {ol.geom.Geometry} The cloned geometry.
|
||||||
|
*/
|
||||||
|
ol.geom.Geometry.prototype.clone = function() {
|
||||||
|
var clone = new this.constructor(this.getCoordinates());
|
||||||
|
clone.bounds_ = this.bounds_;
|
||||||
|
clone.dimension = this.dimension;
|
||||||
|
return clone;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the rectangular 2D envelope for this geoemtry.
|
* Get the rectangular 2D envelope for this geoemtry.
|
||||||
* @return {ol.Extent} The bounding rectangular envelope.
|
* @return {ol.Extent} The bounding rectangular envelope.
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ goog.provide('ol.interaction.ConditionType');
|
|||||||
goog.provide('ol.interaction.condition');
|
goog.provide('ol.interaction.condition');
|
||||||
|
|
||||||
goog.require('goog.dom.TagName');
|
goog.require('goog.dom.TagName');
|
||||||
|
goog.require('goog.events.EventType');
|
||||||
goog.require('goog.functions');
|
goog.require('goog.functions');
|
||||||
|
|
||||||
|
|
||||||
@@ -42,6 +43,15 @@ ol.interaction.condition.altShiftKeysOnly = function(browserEvent) {
|
|||||||
ol.interaction.condition.always = goog.functions.TRUE;
|
ol.interaction.condition.always = goog.functions.TRUE;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {goog.events.BrowserEvent} browserEvent Browser event.
|
||||||
|
* @return {boolean} True only the event is a click event.
|
||||||
|
*/
|
||||||
|
ol.interaction.condition.clickOnly = function(browserEvent) {
|
||||||
|
return browserEvent.type == goog.events.EventType.CLICK;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {goog.events.BrowserEvent} browserEvent Browser event.
|
* @param {goog.events.BrowserEvent} browserEvent Browser event.
|
||||||
* @return {boolean} True if only the no modifier keys are pressed.
|
* @return {boolean} True if only the no modifier keys are pressed.
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
goog.provide('ol.interaction.Interaction');
|
goog.provide('ol.interaction.Interaction');
|
||||||
|
|
||||||
|
goog.require('goog.Disposable');
|
||||||
goog.require('ol.MapBrowserEvent');
|
goog.require('ol.MapBrowserEvent');
|
||||||
goog.require('ol.animation.pan');
|
goog.require('ol.animation.pan');
|
||||||
goog.require('ol.animation.rotate');
|
goog.require('ol.animation.rotate');
|
||||||
@@ -12,9 +13,12 @@ goog.require('ol.easing');
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
|
* @extends {goog.Disposable}
|
||||||
*/
|
*/
|
||||||
ol.interaction.Interaction = function() {
|
ol.interaction.Interaction = function() {
|
||||||
|
goog.base(this);
|
||||||
};
|
};
|
||||||
|
goog.inherits(ol.interaction.Interaction, goog.Disposable);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
@exportClass ol.interaction.Select ol.interaction.SelectOptions
|
||||||
@@ -0,0 +1,172 @@
|
|||||||
|
goog.provide('ol.interaction.Select');
|
||||||
|
|
||||||
|
goog.require('goog.array');
|
||||||
|
goog.require('ol.Feature');
|
||||||
|
goog.require('ol.interaction.ConditionType');
|
||||||
|
goog.require('ol.interaction.Interaction');
|
||||||
|
goog.require('ol.interaction.condition');
|
||||||
|
goog.require('ol.layer.Vector');
|
||||||
|
goog.require('ol.layer.VectorLayerRenderIntent');
|
||||||
|
goog.require('ol.source.Vector');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.interaction.Interaction}
|
||||||
|
* @param {ol.interaction.SelectOptions=} opt_options Options.
|
||||||
|
*/
|
||||||
|
ol.interaction.Select = function(opt_options) {
|
||||||
|
var options = goog.isDef(opt_options) ? opt_options : {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {ol.interaction.ConditionType}
|
||||||
|
*/
|
||||||
|
this.condition_ = goog.isDef(options.condition) ?
|
||||||
|
options.condition : ol.interaction.condition.clickOnly;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapping between original features and cloned features on selection layers.
|
||||||
|
* @type {Object.<*,Object.<*,ol.Feature>>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.featureMap_ = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapping between original layers and selection layers, by map.
|
||||||
|
* @type {Object.<*,{map:ol.Map,layers:Object.<*,ol.layer.Vector>}>}
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
this.selectionLayers = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {null|function(ol.layer.Layer):boolean}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.layerFilter_ = goog.isDef(options.layerFilter) ?
|
||||||
|
options.layerFilter : null;
|
||||||
|
|
||||||
|
goog.base(this);
|
||||||
|
};
|
||||||
|
goog.inherits(ol.interaction.Select, ol.interaction.Interaction);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.interaction.Select.prototype.disposeInternal = function() {
|
||||||
|
for (var m in this.selectionLayers) {
|
||||||
|
var selectionLayers = this.selectionLayers[m].layers;
|
||||||
|
var map = this.selectionLayers[m].map;
|
||||||
|
for (var l in selectionLayers) {
|
||||||
|
map.removeLayer(selectionLayers[l]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goog.base(this, 'disposeInternal');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc.
|
||||||
|
*/
|
||||||
|
ol.interaction.Select.prototype.handleMapBrowserEvent = function(evt) {
|
||||||
|
var browserEvent = evt.browserEvent;
|
||||||
|
if (this.condition_(browserEvent)) {
|
||||||
|
var map = evt.map;
|
||||||
|
var layers = map.getLayerGroup().getLayersArray();
|
||||||
|
if (!goog.isNull(this.layerFilter_)) {
|
||||||
|
layers = goog.array.filter(layers, this.layerFilter_);
|
||||||
|
}
|
||||||
|
var clear = !ol.interaction.condition.shiftKeyOnly(browserEvent);
|
||||||
|
|
||||||
|
var that = this;
|
||||||
|
var select = function(featuresByLayer) {
|
||||||
|
that.select(map, featuresByLayer, layers, clear);
|
||||||
|
};
|
||||||
|
|
||||||
|
map.getFeatures({
|
||||||
|
layers: layers,
|
||||||
|
pixel: evt.getPixel(),
|
||||||
|
success: select
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// TODO: Implement box selection
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.Map} map The map where the selction event originated.
|
||||||
|
* @param {Array.<Array.<ol.Feature>>} featuresByLayer Features by layer.
|
||||||
|
* @param {Array.<ol.layer.Layer>} layers The queried layers.
|
||||||
|
* @param {boolean} clear Whether the current layer content should be cleared.
|
||||||
|
*/
|
||||||
|
ol.interaction.Select.prototype.select =
|
||||||
|
function(map, featuresByLayer, layers, clear) {
|
||||||
|
var mapId = goog.getUid(map);
|
||||||
|
for (var i = 0, ii = featuresByLayer.length; i < ii; ++i) {
|
||||||
|
var layer = layers[i];
|
||||||
|
var layerId = goog.getUid(layer);
|
||||||
|
if (!(mapId in this.selectionLayers)) {
|
||||||
|
this.selectionLayers[mapId] = {map: map, layers: {}};
|
||||||
|
}
|
||||||
|
var selectionLayer = this.selectionLayers[mapId].layers[layerId];
|
||||||
|
if (!goog.isDef(selectionLayer)) {
|
||||||
|
selectionLayer = new ol.layer.Vector({
|
||||||
|
source: new ol.source.Vector({parser: null}),
|
||||||
|
style: goog.isFunction(layer.getStyle) ? layer.getStyle() : null
|
||||||
|
});
|
||||||
|
selectionLayer.setTemporary(true);
|
||||||
|
map.addLayer(selectionLayer);
|
||||||
|
this.selectionLayers[mapId].layers[layerId] = selectionLayer;
|
||||||
|
this.featureMap_[layerId] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
var features = featuresByLayer[i];
|
||||||
|
var numFeatures = features.length;
|
||||||
|
var selectedFeatures = [];
|
||||||
|
var featuresToAdd = [];
|
||||||
|
var unselectedFeatures = [];
|
||||||
|
var featuresToRemove = [];
|
||||||
|
var featureMap = this.featureMap_[layerId];
|
||||||
|
var oldFeatureMap = featureMap;
|
||||||
|
if (clear) {
|
||||||
|
for (var f in featureMap) {
|
||||||
|
unselectedFeatures.push(layer.getFeatureWithUid(f));
|
||||||
|
featuresToRemove.push(featureMap[f]);
|
||||||
|
}
|
||||||
|
featureMap = {};
|
||||||
|
this.featureMap_[layerId] = featureMap;
|
||||||
|
}
|
||||||
|
for (var j = 0; j < numFeatures; ++j) {
|
||||||
|
var feature = features[j];
|
||||||
|
var featureId = goog.getUid(feature);
|
||||||
|
var clone = featureMap[featureId];
|
||||||
|
if (clone) {
|
||||||
|
// TODO: make toggle configurable
|
||||||
|
unselectedFeatures.push(feature);
|
||||||
|
featuresToRemove.push(clone);
|
||||||
|
delete featureMap[featureId];
|
||||||
|
} else if (!(featureId in oldFeatureMap)) {
|
||||||
|
clone = new ol.Feature(feature.getAttributes());
|
||||||
|
clone.setGeometry(feature.getGeometry().clone());
|
||||||
|
clone.setFeatureId(feature.getFeatureId());
|
||||||
|
clone.setSymbolizers(feature.getSymbolizers());
|
||||||
|
clone.renderIntent = ol.layer.VectorLayerRenderIntent.SELECTED;
|
||||||
|
featureMap[featureId] = clone;
|
||||||
|
selectedFeatures.push(feature);
|
||||||
|
featuresToAdd.push(clone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (goog.isFunction(layer.setRenderIntent)) {
|
||||||
|
layer.setRenderIntent(ol.layer.VectorLayerRenderIntent.HIDDEN,
|
||||||
|
selectedFeatures);
|
||||||
|
layer.setRenderIntent(ol.layer.VectorLayerRenderIntent.DEFAULT,
|
||||||
|
unselectedFeatures);
|
||||||
|
}
|
||||||
|
selectionLayer.removeFeatures(featuresToRemove);
|
||||||
|
selectionLayer.addFeatures(featuresToAdd);
|
||||||
|
// TODO: Dispatch an event with selectedFeatures and unselectedFeatures
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -3,6 +3,7 @@ goog.provide('ol.layer.VectorLayerEventType');
|
|||||||
|
|
||||||
goog.require('goog.array');
|
goog.require('goog.array');
|
||||||
goog.require('goog.asserts');
|
goog.require('goog.asserts');
|
||||||
|
goog.require('goog.events.EventType');
|
||||||
goog.require('goog.object');
|
goog.require('goog.object');
|
||||||
goog.require('ol.Feature');
|
goog.require('ol.Feature');
|
||||||
goog.require('ol.expr');
|
goog.require('ol.expr');
|
||||||
@@ -201,6 +202,16 @@ ol.layer.FeatureCache.prototype.getFeaturesByIds_ = function(ids) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} uid Feature uid.
|
||||||
|
* @return {ol.Feature|undefined} The feature with the provided uid if it is in
|
||||||
|
* the cache, otherwise undefined.
|
||||||
|
*/
|
||||||
|
ol.layer.FeatureCache.prototype.getFeatureWithUid = function(uid) {
|
||||||
|
return this.idLookup_[uid];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a feature from the cache.
|
* Remove a feature from the cache.
|
||||||
* @param {ol.Feature} feature Feature.
|
* @param {ol.Feature} feature Feature.
|
||||||
@@ -225,7 +236,9 @@ ol.layer.FeatureCache.prototype.remove = function(feature) {
|
|||||||
*/
|
*/
|
||||||
ol.layer.VectorLayerEventType = {
|
ol.layer.VectorLayerEventType = {
|
||||||
ADD: 'add',
|
ADD: 'add',
|
||||||
REMOVE: 'remove'
|
CHANGE: goog.events.EventType.CHANGE,
|
||||||
|
REMOVE: 'remove',
|
||||||
|
INTENTCHANGE: 'intentchange'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -287,6 +300,13 @@ ol.layer.Vector = function(options) {
|
|||||||
*/
|
*/
|
||||||
this.polygonVertices_ = new ol.geom.SharedVertices();
|
this.polygonVertices_ = new ol.geom.SharedVertices();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if this is a temporary layer.
|
||||||
|
* @type {boolean}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.temp_ = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
goog.inherits(ol.layer.Vector, ol.layer.Layer);
|
goog.inherits(ol.layer.Vector, ol.layer.Layer);
|
||||||
|
|
||||||
@@ -313,6 +333,25 @@ ol.layer.Vector.prototype.addFeatures = function(features) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all features from the layer.
|
||||||
|
*/
|
||||||
|
ol.layer.Vector.prototype.clear = function() {
|
||||||
|
this.featureCache_.clear();
|
||||||
|
this.dispatchEvent(/** @type {ol.layer.VectorLayerEventObject} */ ({
|
||||||
|
type: ol.layer.VectorLayerEventType.CHANGE
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {boolean} Whether this layer is temporary.
|
||||||
|
*/
|
||||||
|
ol.layer.Vector.prototype.getTemporary = function() {
|
||||||
|
return this.temp_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {ol.source.Vector} Source.
|
* @return {ol.source.Vector} Source.
|
||||||
*/
|
*/
|
||||||
@@ -321,6 +360,14 @@ ol.layer.Vector.prototype.getVectorSource = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {ol.style.Style} This layer's style.
|
||||||
|
*/
|
||||||
|
ol.layer.Vector.prototype.getStyle = function() {
|
||||||
|
return this.style_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all features whose bounding box intersects the provided extent. This
|
* Get all features whose bounding box intersects the provided extent. This
|
||||||
* method is intended for being called by the renderer. When null is returned,
|
* method is intended for being called by the renderer. When null is returned,
|
||||||
@@ -426,6 +473,16 @@ ol.layer.Vector.prototype.groupFeaturesBySymbolizerLiteral =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string|number} uid Feature uid.
|
||||||
|
* @return {ol.Feature|undefined} The feature with the provided uid if it is on
|
||||||
|
* the layer, otherwise undefined.
|
||||||
|
*/
|
||||||
|
ol.layer.Vector.prototype.getFeatureWithUid = function(uid) {
|
||||||
|
return this.featureCache_.getFeatureWithUid(/** @type {string} */ (uid));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object|Element|Document|string} data Feature data.
|
* @param {Object|Element|Document|string} data Feature data.
|
||||||
* @param {ol.parser.Parser} parser Feature parser.
|
* @param {ol.parser.Parser} parser Feature parser.
|
||||||
@@ -532,12 +589,48 @@ ol.layer.Vector.prototype.removeFeatures = function(features) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the renderIntent for an array of features.
|
||||||
|
* @param {string} renderIntent Render intent.
|
||||||
|
* @param {Array.<ol.Feature>=} opt_features Features to change the renderIntent
|
||||||
|
* for. If not provided, all features will be changed.
|
||||||
|
*/
|
||||||
|
ol.layer.Vector.prototype.setRenderIntent =
|
||||||
|
function(renderIntent, opt_features) {
|
||||||
|
var features = goog.isDef(opt_features) ? opt_features :
|
||||||
|
goog.object.getValues(this.featureCache_.getFeaturesObject());
|
||||||
|
var extent = ol.extent.createEmpty(),
|
||||||
|
feature, geometry;
|
||||||
|
for (var i = features.length - 1; i >= 0; --i) {
|
||||||
|
feature = features[i];
|
||||||
|
feature.renderIntent = renderIntent;
|
||||||
|
geometry = feature.getGeometry();
|
||||||
|
if (!goog.isNull(geometry)) {
|
||||||
|
ol.extent.extend(extent, geometry.getBounds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.dispatchEvent(/** @type {ol.layer.VectorLayerEventObject} */ ({
|
||||||
|
extent: extent,
|
||||||
|
features: features,
|
||||||
|
type: ol.layer.VectorLayerEventType.INTENTCHANGE
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} temp Whether this layer is temporary.
|
||||||
|
*/
|
||||||
|
ol.layer.Vector.prototype.setTemporary = function(temp) {
|
||||||
|
this.temp_ = temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Array.<ol.Feature>} features Features.
|
* @param {Array.<ol.Feature>} features Features.
|
||||||
* @return {string} Feature info.
|
* @return {string} Feature info.
|
||||||
*/
|
*/
|
||||||
ol.layer.Vector.uidTransformFeatureInfo = function(features) {
|
ol.layer.Vector.uidTransformFeatureInfo = function(features) {
|
||||||
var featureIds = goog.array.map(features,
|
var uids = goog.array.map(features,
|
||||||
function(feature) { return goog.getUid(feature); });
|
function(feature) { return goog.getUid(feature); });
|
||||||
return featureIds.join(', ');
|
return uids.join(', ');
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
goog.provide('ol.layer.VectorLayerRenderIntent');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum {string}
|
||||||
|
*/
|
||||||
|
ol.layer.VectorLayerRenderIntent = {
|
||||||
|
DEFAULT: 'default',
|
||||||
|
HIDDEN: 'hidden',
|
||||||
|
SELECTED: 'selected'
|
||||||
|
};
|
||||||
@@ -88,7 +88,9 @@ ol.renderer.canvas.VectorLayer = function(mapRenderer, layer) {
|
|||||||
ol.renderer.canvas.VectorLayer.TILECACHE_SIZE);
|
ol.renderer.canvas.VectorLayer.TILECACHE_SIZE);
|
||||||
goog.events.listen(layer, [
|
goog.events.listen(layer, [
|
||||||
ol.layer.VectorLayerEventType.ADD,
|
ol.layer.VectorLayerEventType.ADD,
|
||||||
ol.layer.VectorLayerEventType.REMOVE
|
ol.layer.VectorLayerEventType.CHANGE,
|
||||||
|
ol.layer.VectorLayerEventType.REMOVE,
|
||||||
|
ol.layer.VectorLayerEventType.INTENTCHANGE
|
||||||
],
|
],
|
||||||
this.handleLayerChange_, false, this);
|
this.handleLayerChange_, false, this);
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ goog.require('ol.geom.MultiPoint');
|
|||||||
goog.require('ol.geom.MultiPolygon');
|
goog.require('ol.geom.MultiPolygon');
|
||||||
goog.require('ol.geom.Point');
|
goog.require('ol.geom.Point');
|
||||||
goog.require('ol.geom.Polygon');
|
goog.require('ol.geom.Polygon');
|
||||||
|
goog.require('ol.layer.VectorLayerRenderIntent');
|
||||||
goog.require('ol.style.IconLiteral');
|
goog.require('ol.style.IconLiteral');
|
||||||
goog.require('ol.style.LineLiteral');
|
goog.require('ol.style.LineLiteral');
|
||||||
goog.require('ol.style.Literal');
|
goog.require('ol.style.Literal');
|
||||||
@@ -176,6 +177,9 @@ ol.renderer.canvas.VectorRenderer.prototype.renderLineStringFeatures_ =
|
|||||||
context.beginPath();
|
context.beginPath();
|
||||||
for (i = 0, ii = features.length; i < ii; ++i) {
|
for (i = 0, ii = features.length; i < ii; ++i) {
|
||||||
feature = features[i];
|
feature = features[i];
|
||||||
|
if (feature.renderIntent === ol.layer.VectorLayerRenderIntent.HIDDEN) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
id = goog.getUid(feature);
|
id = goog.getUid(feature);
|
||||||
currentSize = goog.isDef(this.symbolSizes_[id]) ?
|
currentSize = goog.isDef(this.symbolSizes_[id]) ?
|
||||||
this.symbolSizes_[id] : [0];
|
this.symbolSizes_[id] : [0];
|
||||||
@@ -253,6 +257,9 @@ ol.renderer.canvas.VectorRenderer.prototype.renderPointFeatures_ =
|
|||||||
context.globalAlpha = alpha;
|
context.globalAlpha = alpha;
|
||||||
for (i = 0, ii = features.length; i < ii; ++i) {
|
for (i = 0, ii = features.length; i < ii; ++i) {
|
||||||
feature = features[i];
|
feature = features[i];
|
||||||
|
if (feature.renderIntent === ol.layer.VectorLayerRenderIntent.HIDDEN) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
id = goog.getUid(feature);
|
id = goog.getUid(feature);
|
||||||
size = this.symbolSizes_[id];
|
size = this.symbolSizes_[id];
|
||||||
this.symbolSizes_[id] = goog.isDef(size) ?
|
this.symbolSizes_[id] = goog.isDef(size) ?
|
||||||
@@ -296,7 +303,7 @@ ol.renderer.canvas.VectorRenderer.prototype.renderPointFeatures_ =
|
|||||||
ol.renderer.canvas.VectorRenderer.prototype.renderText_ =
|
ol.renderer.canvas.VectorRenderer.prototype.renderText_ =
|
||||||
function(features, text, texts) {
|
function(features, text, texts) {
|
||||||
var context = this.context_,
|
var context = this.context_,
|
||||||
vecs, vec;
|
feature, vecs, vec;
|
||||||
|
|
||||||
if (context.fillStyle !== text.color) {
|
if (context.fillStyle !== text.color) {
|
||||||
context.fillStyle = text.color;
|
context.fillStyle = text.color;
|
||||||
@@ -309,8 +316,12 @@ ol.renderer.canvas.VectorRenderer.prototype.renderText_ =
|
|||||||
context.textBaseline = 'middle';
|
context.textBaseline = 'middle';
|
||||||
|
|
||||||
for (var i = 0, ii = features.length; i < ii; ++i) {
|
for (var i = 0, ii = features.length; i < ii; ++i) {
|
||||||
|
feature = features[i];
|
||||||
|
if (feature.renderIntent === ol.layer.VectorLayerRenderIntent.HIDDEN) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
vecs = ol.renderer.canvas.VectorRenderer.getLabelVectors(
|
vecs = ol.renderer.canvas.VectorRenderer.getLabelVectors(
|
||||||
features[i].getGeometry());
|
feature.getGeometry());
|
||||||
for (var j = 0, jj = vecs.length; j < jj; ++j) {
|
for (var j = 0, jj = vecs.length; j < jj; ++j) {
|
||||||
vec = vecs[j];
|
vec = vecs[j];
|
||||||
goog.vec.Mat4.multVec3(this.transform_, vec, vec);
|
goog.vec.Mat4.multVec3(this.transform_, vec, vec);
|
||||||
@@ -336,7 +347,7 @@ ol.renderer.canvas.VectorRenderer.prototype.renderPolygonFeatures_ =
|
|||||||
fillOpacity = symbolizer.fillOpacity,
|
fillOpacity = symbolizer.fillOpacity,
|
||||||
globalAlpha,
|
globalAlpha,
|
||||||
i, ii, geometry, components, j, jj, poly,
|
i, ii, geometry, components, j, jj, poly,
|
||||||
rings, numRings, ring, dim, k, kk, vec;
|
rings, numRings, ring, dim, k, kk, vec, feature;
|
||||||
|
|
||||||
if (strokeColor) {
|
if (strokeColor) {
|
||||||
context.strokeStyle = strokeColor;
|
context.strokeStyle = strokeColor;
|
||||||
@@ -359,7 +370,11 @@ ol.renderer.canvas.VectorRenderer.prototype.renderPolygonFeatures_ =
|
|||||||
*/
|
*/
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
for (i = 0, ii = features.length; i < ii; ++i) {
|
for (i = 0, ii = features.length; i < ii; ++i) {
|
||||||
geometry = features[i].getGeometry();
|
feature = features[i];
|
||||||
|
if (feature.renderIntent === ol.layer.VectorLayerRenderIntent.HIDDEN) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
geometry = feature.getGeometry();
|
||||||
if (geometry instanceof ol.geom.Polygon) {
|
if (geometry instanceof ol.geom.Polygon) {
|
||||||
components = [geometry];
|
components = [geometry];
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -116,10 +116,20 @@ ol.style.Fill.prototype.setOpacity = function(opacity) {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{fillColor: (string),
|
* @typedef {{color: (string),
|
||||||
* fillOpacity: (number)}}
|
* opacity: (number)}}
|
||||||
*/
|
*/
|
||||||
ol.style.FillDefaults = {
|
ol.style.FillDefaults = {
|
||||||
color: '#ffffff',
|
color: '#ffffff',
|
||||||
opacity: 0.4
|
opacity: 0.4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{color: (string),
|
||||||
|
* opacity: (number)}}
|
||||||
|
*/
|
||||||
|
ol.style.FillDefaultsSelect = {
|
||||||
|
color: '#ffffff',
|
||||||
|
opacity: 0.7
|
||||||
|
};
|
||||||
|
|||||||
@@ -158,12 +158,24 @@ ol.style.Stroke.prototype.setWidth = function(width) {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{strokeColor: (string),
|
* @typedef {{color: (string),
|
||||||
* strokeOpacity: (number),
|
* opacity: (number),
|
||||||
* strokeWidth: (number)}}
|
* width: (number)}}
|
||||||
*/
|
*/
|
||||||
ol.style.StrokeDefaults = {
|
ol.style.StrokeDefaults = {
|
||||||
color: '#696969',
|
color: '#696969',
|
||||||
opacity: 0.75,
|
opacity: 0.75,
|
||||||
width: 1.5
|
width: 1.5
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{color: (string),
|
||||||
|
* opacity: (number),
|
||||||
|
* width: (number)}}
|
||||||
|
*/
|
||||||
|
ol.style.StrokeDefaultsSelect = {
|
||||||
|
color: '#696969',
|
||||||
|
opacity: 0.9,
|
||||||
|
width: 2.0
|
||||||
|
};
|
||||||
|
|||||||
@@ -67,6 +67,19 @@ ol.style.Style.prototype.createLiterals = function(feature) {
|
|||||||
* @type {ol.style.Style}
|
* @type {ol.style.Style}
|
||||||
*/
|
*/
|
||||||
ol.style.Style.defaults = new ol.style.Style({
|
ol.style.Style.defaults = new ol.style.Style({
|
||||||
|
rules: [
|
||||||
|
new ol.style.Rule({
|
||||||
|
filter: 'renderIntent("select")',
|
||||||
|
symbolizers: [
|
||||||
|
new ol.style.Shape({
|
||||||
|
fill: new ol.style.Fill(ol.style.FillDefaultsSelect),
|
||||||
|
stroke: new ol.style.Stroke(ol.style.StrokeDefaultsSelect)
|
||||||
|
}),
|
||||||
|
new ol.style.Fill(ol.style.FillDefaultsSelect),
|
||||||
|
new ol.style.Stroke(ol.style.StrokeDefaultsSelect)
|
||||||
|
]
|
||||||
|
})
|
||||||
|
],
|
||||||
symbolizers: [
|
symbolizers: [
|
||||||
new ol.style.Shape({
|
new ol.style.Shape({
|
||||||
fill: new ol.style.Fill(),
|
fill: new ol.style.Fill(),
|
||||||
|
|||||||
@@ -872,6 +872,24 @@ describe('ol.expr.lib', function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('renderIntent()', function() {
|
||||||
|
|
||||||
|
var feature = new ol.Feature();
|
||||||
|
feature.renderIntent = 'foo';
|
||||||
|
|
||||||
|
var isFoo = parse('renderIntent("foo")');
|
||||||
|
var isBar = parse('renderIntent("bar")');
|
||||||
|
|
||||||
|
it('True when renderIntent matches', function() {
|
||||||
|
expect(evaluate(isFoo, feature), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('False when renderIntent does not match', function() {
|
||||||
|
expect(evaluate(isBar, feature), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('ol.expr.register()', function() {
|
describe('ol.expr.register()', function() {
|
||||||
|
|||||||
@@ -55,6 +55,23 @@ describe('ol.geom.GeometryCollection', function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#clone()', function() {
|
||||||
|
|
||||||
|
it('has a working clone method', function() {
|
||||||
|
var point = new ol.geom.Point([10, 20]);
|
||||||
|
var line = new ol.geom.LineString([[10, 20], [30, 40]]);
|
||||||
|
var poly = new ol.geom.Polygon([outer, inner1, inner2]);
|
||||||
|
var multi = new ol.geom.GeometryCollection([point, line, poly]);
|
||||||
|
var clone = multi.clone();
|
||||||
|
expect(clone).to.not.be(multi);
|
||||||
|
var components = clone.components;
|
||||||
|
expect(components[0]).to.eql([10, 20]);
|
||||||
|
expect(components[1]).to.eql([[10, 20], [30, 40]]);
|
||||||
|
expect(components[2]).to.eql([outer, inner1, inner2]);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
describe('#getBounds()', function() {
|
describe('#getBounds()', function() {
|
||||||
|
|
||||||
it('returns the bounding extent', function() {
|
it('returns the bounding extent', function() {
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
goog.provide('ol.test.interaction.Select');
|
||||||
|
|
||||||
|
describe('ol.interaction.Select', function() {
|
||||||
|
var map, target, select, vector, features;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
target = document.createElement('div');
|
||||||
|
target.style.width = '256px';
|
||||||
|
target.style.height = '256px';
|
||||||
|
document.body.appendChild(target);
|
||||||
|
map = new ol.Map({
|
||||||
|
target: target
|
||||||
|
});
|
||||||
|
features = ol.parser.GeoJSON.read(JSON.stringify({
|
||||||
|
'type': 'FeatureCollection',
|
||||||
|
'features': [{
|
||||||
|
'type': 'Feature',
|
||||||
|
'geometry': {
|
||||||
|
'type': 'Point',
|
||||||
|
'coordinates': [-1, 1]
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'type': 'Feature',
|
||||||
|
'geometry': {
|
||||||
|
'type': 'Point',
|
||||||
|
'coordinates': [1, -1]
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}));
|
||||||
|
vector = new ol.layer.Vector({source: new ol.source.Vector({})});
|
||||||
|
vector.addFeatures(features);
|
||||||
|
select = new ol.interaction.Select({
|
||||||
|
layerFilter: function(layer) { return layer === vector; }
|
||||||
|
});
|
||||||
|
map.getInteractions().push(select);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
goog.dispose(select);
|
||||||
|
goog.dispose(map);
|
||||||
|
document.body.removeChild(target);
|
||||||
|
select = null;
|
||||||
|
map = null;
|
||||||
|
target = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#select', function() {
|
||||||
|
|
||||||
|
it('toggles selection of features', function() {
|
||||||
|
select.select(map, [features], [vector]);
|
||||||
|
var layer = select.selectionLayers[goog.getUid(map)]
|
||||||
|
.layers[goog.getUid(vector)];
|
||||||
|
expect(goog.object.getCount(layer.featureCache_.idLookup_)).to.be(2);
|
||||||
|
select.select(map, [features], [vector]);
|
||||||
|
expect(goog.object.getCount(layer.featureCache_.idLookup_)).to.be(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can append features to an existing selection', function() {
|
||||||
|
select.select(map, [[features[0]]], [vector]);
|
||||||
|
select.select(map, [[features[1]]], [vector]);
|
||||||
|
var layer = select.selectionLayers[goog.getUid(map)]
|
||||||
|
.layers[goog.getUid(vector)];
|
||||||
|
expect(goog.object.getCount(layer.featureCache_.idLookup_)).to.be(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can clear a selection before selecting new features', function() {
|
||||||
|
select.select(map, [[features[0]]], [vector], true);
|
||||||
|
select.select(map, [[features[1]]], [vector], true);
|
||||||
|
var layer = select.selectionLayers[goog.getUid(map)]
|
||||||
|
.layers[goog.getUid(vector)];
|
||||||
|
expect(goog.object.getCount(layer.featureCache_.idLookup_)).to.be(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
goog.require('goog.dispose');
|
||||||
|
goog.require('goog.object');
|
||||||
|
goog.require('ol.Map');
|
||||||
|
goog.require('ol.interaction.Select');
|
||||||
|
goog.require('ol.layer.Vector');
|
||||||
|
goog.require('ol.parser.GeoJSON');
|
||||||
|
goog.require('ol.source.Vector');
|
||||||
Reference in New Issue
Block a user