Merge branch 'master' into vector-api
This commit is contained in:
@@ -18,7 +18,7 @@ var raster = new ol.layer.Tile({
|
||||
});
|
||||
|
||||
var vector = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({parser: null}),
|
||||
source: new ol.source.Vector(),
|
||||
style: new ol.style.Style({
|
||||
rules: [
|
||||
new ol.style.Rule({
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.RendererHint');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.control');
|
||||
goog.require('ol.expr');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.parser.GeoJSON');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Rule');
|
||||
@@ -62,108 +63,60 @@ var style = new ol.style.Style({rules: [
|
||||
var vector = new ol.layer.Vector({
|
||||
style: style,
|
||||
source: new ol.source.Vector({
|
||||
data: {
|
||||
'type': 'FeatureCollection',
|
||||
'features': [{
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'color': '#BADA55',
|
||||
'where': 'inner'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'LineString',
|
||||
'coordinates': [[-10000000, -10000000], [10000000, 10000000]]
|
||||
}
|
||||
}, {
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'color': '#BADA55',
|
||||
'where': 'inner'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'LineString',
|
||||
'coordinates': [[-10000000, 10000000], [10000000, -10000000]]
|
||||
}
|
||||
}, {
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'color': '#013',
|
||||
'where': 'outer'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'LineString',
|
||||
'coordinates': [[-10000000, -10000000], [-10000000, 10000000]]
|
||||
}
|
||||
}, {
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'color': '#013',
|
||||
'where': 'outer'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'LineString',
|
||||
'coordinates': [[-10000000, 10000000], [10000000, 10000000]]
|
||||
}
|
||||
}, {
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'color': '#013',
|
||||
'where': 'outer'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'LineString',
|
||||
'coordinates': [[10000000, 10000000], [10000000, -10000000]]
|
||||
}
|
||||
}, {
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'color': '#013',
|
||||
'where': 'outer'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'LineString',
|
||||
'coordinates': [[10000000, -10000000], [-10000000, -10000000]]
|
||||
}
|
||||
}, {
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'label': 'South'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'Point',
|
||||
'coordinates': [0, -6000000]
|
||||
}
|
||||
}, {
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'label': 'West'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'Point',
|
||||
'coordinates': [-6000000, 0]
|
||||
}
|
||||
}, {
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'label': 'North'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'Point',
|
||||
'coordinates': [0, 6000000]
|
||||
}
|
||||
}, {
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'label': 'East'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'Point',
|
||||
'coordinates': [6000000, 0]
|
||||
}
|
||||
}]
|
||||
},
|
||||
parser: new ol.parser.GeoJSON(),
|
||||
projection: ol.proj.get('EPSG:3857')
|
||||
features: [
|
||||
new ol.Feature({
|
||||
color: '#BADA55',
|
||||
where: 'inner',
|
||||
geometry: new ol.geom.LineString(
|
||||
[[-10000000, -10000000], [10000000, 10000000]])
|
||||
}),
|
||||
new ol.Feature({
|
||||
color: '#BADA55',
|
||||
where: 'inner',
|
||||
geometry: new ol.geom.LineString(
|
||||
[[-10000000, 10000000], [10000000, -10000000]])
|
||||
}),
|
||||
new ol.Feature({
|
||||
color: '#013',
|
||||
where: 'outer',
|
||||
geometry: new ol.geom.LineString(
|
||||
[[-10000000, -10000000], [-10000000, 10000000]])
|
||||
}),
|
||||
new ol.Feature({
|
||||
color: '#013',
|
||||
where: 'outer',
|
||||
geometry: new ol.geom.LineString(
|
||||
[[-10000000, 10000000], [10000000, 10000000]])
|
||||
}),
|
||||
new ol.Feature({
|
||||
color: '#013',
|
||||
where: 'outer',
|
||||
geometry: new ol.geom.LineString(
|
||||
[[10000000, 10000000], [10000000, -10000000]])
|
||||
}),
|
||||
new ol.Feature({
|
||||
color: '#013',
|
||||
where: 'outer',
|
||||
geometry: new ol.geom.LineString(
|
||||
[[10000000, -10000000], [-10000000, -10000000]])
|
||||
}),
|
||||
new ol.Feature({
|
||||
label: 'South',
|
||||
geometry: new ol.geom.Point([0, -6000000])
|
||||
}),
|
||||
new ol.Feature({
|
||||
label: 'West',
|
||||
geometry: new ol.geom.Point([-6000000, 0])
|
||||
}),
|
||||
new ol.Feature({
|
||||
label: 'North',
|
||||
geometry: new ol.geom.Point([0, 6000000])
|
||||
}),
|
||||
new ol.Feature({
|
||||
label: 'East',
|
||||
geometry: new ol.geom.Point([6000000, 0])
|
||||
})
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ goog.require('goog.asserts');
|
||||
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.FeatureRenderIntent');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.MapBrowserEvent');
|
||||
goog.require('ol.MapBrowserEvent.EventType');
|
||||
@@ -16,7 +17,6 @@ goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.interaction.Interaction');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.layer.VectorLayerRenderIntent');
|
||||
goog.require('ol.source.Vector');
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ ol.interaction.Draw.prototype.setMap = function(map) {
|
||||
if (!goog.isNull(map)) {
|
||||
if (goog.isNull(this.sketchLayer_)) {
|
||||
var layer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({parser: null}),
|
||||
source: new ol.source.Vector(),
|
||||
style: this.layer_.getStyle()
|
||||
});
|
||||
layer.setTemporary(true);
|
||||
@@ -233,7 +233,7 @@ ol.interaction.Draw.prototype.startDrawing_ = function(event) {
|
||||
var start = event.getCoordinate();
|
||||
this.finishCoordinate_ = start;
|
||||
var sketchFeature = new ol.Feature();
|
||||
sketchFeature.setRenderIntent(ol.layer.VectorLayerRenderIntent.SELECTED);
|
||||
sketchFeature.setRenderIntent(ol.FeatureRenderIntent.SELECTED);
|
||||
var features = [sketchFeature];
|
||||
var geometry;
|
||||
if (this.mode_ === ol.interaction.DrawMode.POINT) {
|
||||
@@ -242,7 +242,7 @@ ol.interaction.Draw.prototype.startDrawing_ = function(event) {
|
||||
var sketchPoint = new ol.Feature({
|
||||
geom: new ol.geom.Point(start.slice())
|
||||
});
|
||||
sketchPoint.setRenderIntent(ol.layer.VectorLayerRenderIntent.TEMPORARY);
|
||||
sketchPoint.setRenderIntent(ol.FeatureRenderIntent.TEMPORARY);
|
||||
this.sketchPoint_ = sketchPoint;
|
||||
features.push(sketchPoint);
|
||||
|
||||
@@ -256,7 +256,7 @@ ol.interaction.Draw.prototype.startDrawing_ = function(event) {
|
||||
sketchFeature.setGeometry(geometry);
|
||||
this.sketchFeature_ = sketchFeature;
|
||||
|
||||
this.sketchLayer_.addFeatures(features);
|
||||
this.sketchLayer_.getVectorSource().addFeatures(features);
|
||||
};
|
||||
|
||||
|
||||
@@ -325,7 +325,7 @@ ol.interaction.Draw.prototype.addToDrawing_ = function(event) {
|
||||
ol.interaction.Draw.prototype.finishDrawing_ = function(event) {
|
||||
var sketchFeature = this.abortDrawing_();
|
||||
goog.asserts.assert(!goog.isNull(sketchFeature));
|
||||
sketchFeature.setRenderIntent(ol.layer.VectorLayerRenderIntent.DEFAULT);
|
||||
sketchFeature.setRenderIntent(ol.FeatureRenderIntent.DEFAULT);
|
||||
var geometry = sketchFeature.getGeometry();
|
||||
var coordinates = geometry.getCoordinates();
|
||||
if (this.mode_ === ol.interaction.DrawMode.LINESTRING) {
|
||||
@@ -344,7 +344,7 @@ ol.interaction.Draw.prototype.finishDrawing_ = function(event) {
|
||||
} else if (this.type_ === ol.geom.GeometryType.MULTIPOLYGON) {
|
||||
sketchFeature.setGeometry(new ol.geom.MultiPolygon([coordinates]));
|
||||
}
|
||||
this.layer_.addFeatures([sketchFeature]);
|
||||
this.layer_.getVectorSource().addFeatures([sketchFeature]);
|
||||
};
|
||||
|
||||
|
||||
@@ -363,7 +363,7 @@ ol.interaction.Draw.prototype.abortDrawing_ = function() {
|
||||
features.push(this.sketchPoint_);
|
||||
this.sketchPoint_ = null;
|
||||
}
|
||||
this.sketchLayer_.removeFeatures(features);
|
||||
this.sketchLayer_.getVectorSource().removeFeatures(features);
|
||||
}
|
||||
return sketchFeature;
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ goog.require('goog.events');
|
||||
goog.require('goog.functions');
|
||||
goog.require('ol.CollectionEventType');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.FeatureRenderIntent');
|
||||
goog.require('ol.MapBrowserEvent.EventType');
|
||||
goog.require('ol.ViewHint');
|
||||
goog.require('ol.coordinate');
|
||||
@@ -18,9 +19,8 @@ goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.interaction.Drag');
|
||||
goog.require('ol.layer.Layer');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.layer.VectorEventType');
|
||||
goog.require('ol.layer.VectorLayerRenderIntent');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.source.VectorEventType');
|
||||
goog.require('ol.structs.RBush');
|
||||
|
||||
|
||||
@@ -59,6 +59,13 @@ ol.interaction.Modify = function(opt_options) {
|
||||
*/
|
||||
this.layerFilter_ = layerFilter;
|
||||
|
||||
/**
|
||||
* Layer lookup. Keys source id to layer.
|
||||
* @type {Object.<number, ol.layer.Vector>}
|
||||
* @private
|
||||
*/
|
||||
this.layerLookup_ = null;
|
||||
|
||||
/**
|
||||
* Temporary sketch layer.
|
||||
* @type {ol.layer.Vector}
|
||||
@@ -121,12 +128,13 @@ ol.interaction.Modify.prototype.setMap = function(map) {
|
||||
}
|
||||
|
||||
if (!goog.isNull(map)) {
|
||||
this.layerLookup_ = {};
|
||||
if (goog.isNull(this.rBush_)) {
|
||||
this.rBush_ = new ol.structs.RBush();
|
||||
}
|
||||
if (goog.isNull(this.sketchLayer_)) {
|
||||
var sketchLayer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({parser: null})
|
||||
source: new ol.source.Vector()
|
||||
});
|
||||
this.sketchLayer_ = sketchLayer;
|
||||
sketchLayer.setTemporary(true);
|
||||
@@ -141,6 +149,7 @@ ol.interaction.Modify.prototype.setMap = function(map) {
|
||||
false, this);
|
||||
} else {
|
||||
// removing from a map, clean up
|
||||
this.layerLookup_ = null;
|
||||
this.rBush_ = null;
|
||||
this.sketchLayer_ = null;
|
||||
}
|
||||
@@ -168,9 +177,11 @@ ol.interaction.Modify.prototype.handleLayerAdded_ = function(evt) {
|
||||
ol.interaction.Modify.prototype.addLayer_ = function(layer) {
|
||||
if (this.layerFilter_(layer) && layer instanceof ol.layer.Vector &&
|
||||
!layer.getTemporary()) {
|
||||
this.addIndex_(layer.getFeatures(ol.layer.Vector.selectedFeaturesFilter),
|
||||
var source = layer.getVectorSource();
|
||||
this.layerLookup_[goog.getUid(source)] = layer;
|
||||
this.addIndex_(source.getFeatures(ol.layer.Vector.selectedFeaturesFilter),
|
||||
layer);
|
||||
goog.events.listen(layer, ol.layer.VectorEventType.INTENTCHANGE,
|
||||
goog.events.listen(source, ol.source.VectorEventType.INTENTCHANGE,
|
||||
this.handleIntentChange_, false, this);
|
||||
}
|
||||
};
|
||||
@@ -195,9 +206,11 @@ ol.interaction.Modify.prototype.handleLayerRemoved_ = function(evt) {
|
||||
ol.interaction.Modify.prototype.removeLayer_ = function(layer) {
|
||||
if (this.layerFilter_(layer) && layer instanceof ol.layer.Vector &&
|
||||
!layer.getTemporary()) {
|
||||
var source = layer.getVectorSource();
|
||||
delete this.layerLookup_[goog.getUid(source)];
|
||||
this.removeIndex_(
|
||||
layer.getFeatures(ol.layer.Vector.selectedFeaturesFilter));
|
||||
goog.events.unlisten(layer, ol.layer.VectorEventType.INTENTCHANGE,
|
||||
source.getFeatures(ol.layer.Vector.selectedFeaturesFilter));
|
||||
goog.events.unlisten(source, ol.source.VectorEventType.INTENTCHANGE,
|
||||
this.handleIntentChange_, false, this);
|
||||
}
|
||||
};
|
||||
@@ -248,17 +261,19 @@ ol.interaction.Modify.prototype.removeIndex_ = function(features) {
|
||||
|
||||
/**
|
||||
* Listen for feature additions.
|
||||
* @param {ol.layer.VectorEvent} evt Event object.
|
||||
* @param {ol.source.VectorEvent} evt Event object.
|
||||
* @private
|
||||
*/
|
||||
ol.interaction.Modify.prototype.handleIntentChange_ = function(evt) {
|
||||
var layer = evt.target;
|
||||
var source = evt.target;
|
||||
goog.asserts.assertInstanceof(source, ol.source.Vector);
|
||||
var layer = this.layerLookup_[goog.getUid(source)];
|
||||
goog.asserts.assertInstanceof(layer, ol.layer.Vector);
|
||||
var features = evt.features;
|
||||
for (var i = 0, ii = features.length; i < ii; ++i) {
|
||||
var feature = features[i];
|
||||
var renderIntent = feature.getRenderIntent();
|
||||
if (renderIntent == ol.layer.VectorLayerRenderIntent.SELECTED) {
|
||||
if (renderIntent == ol.FeatureRenderIntent.SELECTED) {
|
||||
this.addIndex_([feature], layer);
|
||||
} else {
|
||||
this.removeIndex_([feature]);
|
||||
@@ -322,7 +337,7 @@ ol.interaction.Modify.prototype.createOrUpdateVertexFeature_ =
|
||||
if (goog.isNull(vertexFeature)) {
|
||||
vertexFeature = new ol.Feature({g: new ol.geom.Point(coordinates)});
|
||||
this.vertexFeature_ = vertexFeature;
|
||||
this.sketchLayer_.addFeatures([vertexFeature]);
|
||||
this.sketchLayer_.getVectorSource().addFeatures([vertexFeature]);
|
||||
} else {
|
||||
var geometry = vertexFeature.getGeometry();
|
||||
geometry.setCoordinates(coordinates);
|
||||
@@ -341,7 +356,7 @@ ol.interaction.Modify.prototype.handleDragStart = function(evt) {
|
||||
this.dragSegments_ = [];
|
||||
var vertexFeature = this.vertexFeature_;
|
||||
if (!goog.isNull(vertexFeature) && vertexFeature.getRenderIntent() !=
|
||||
ol.layer.VectorLayerRenderIntent.HIDDEN) {
|
||||
ol.FeatureRenderIntent.HIDDEN) {
|
||||
var renderIntent = vertexFeature.getRenderIntent();
|
||||
var insertVertices = [];
|
||||
var vertex = vertexFeature.getGeometry().getCoordinates();
|
||||
@@ -360,7 +375,7 @@ ol.interaction.Modify.prototype.handleDragStart = function(evt) {
|
||||
original.setSymbolizers(feature.getSymbolizers());
|
||||
feature.setOriginal(original);
|
||||
}
|
||||
if (renderIntent == ol.layer.VectorLayerRenderIntent.TEMPORARY) {
|
||||
if (renderIntent == ol.FeatureRenderIntent.TEMPORARY) {
|
||||
if (ol.coordinate.equals(segment[0], vertex)) {
|
||||
dragSegments.push([node, 0]);
|
||||
} else if (ol.coordinate.equals(segment[1], vertex)) {
|
||||
@@ -455,7 +470,7 @@ ol.interaction.Modify.prototype.handleMouseMove_ = function(evt) {
|
||||
var vertexFeature = this.vertexFeature_;
|
||||
var rBush = this.rBush_;
|
||||
var nodes = rBush.getAllInExtent(box);
|
||||
var renderIntent = ol.layer.VectorLayerRenderIntent.HIDDEN;
|
||||
var renderIntent = ol.FeatureRenderIntent.HIDDEN;
|
||||
if (nodes.length > 0) {
|
||||
nodes.sort(sortByDistance);
|
||||
var node = nodes[0];
|
||||
@@ -469,10 +484,10 @@ ol.interaction.Modify.prototype.handleMouseMove_ = function(evt) {
|
||||
var squaredDist1 = ol.coordinate.squaredDistance(vertexPixel, pixel1);
|
||||
var squaredDist2 = ol.coordinate.squaredDistance(vertexPixel, pixel2);
|
||||
var dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));
|
||||
renderIntent = ol.layer.VectorLayerRenderIntent.FUTURE;
|
||||
renderIntent = ol.FeatureRenderIntent.FUTURE;
|
||||
if (dist <= 10) {
|
||||
vertex = squaredDist1 > squaredDist2 ? segment[1] : segment[0];
|
||||
renderIntent = ol.layer.VectorLayerRenderIntent.TEMPORARY;
|
||||
renderIntent = ol.FeatureRenderIntent.TEMPORARY;
|
||||
}
|
||||
vertexFeature = this.createOrUpdateVertexFeature_(node.style, vertex);
|
||||
this.modifiable_ = true;
|
||||
|
||||
@@ -3,11 +3,11 @@ goog.provide('ol.interaction.Select');
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.FeatureRenderIntent');
|
||||
goog.require('ol.events.ConditionType');
|
||||
goog.require('ol.events.condition');
|
||||
goog.require('ol.interaction.Interaction');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.layer.VectorLayerRenderIntent');
|
||||
|
||||
|
||||
|
||||
@@ -97,21 +97,21 @@ ol.interaction.Select.prototype.select =
|
||||
}
|
||||
|
||||
var featuresToSelect = featuresByLayer[i];
|
||||
var selectedFeatures = layer.getFeatures(
|
||||
var selectedFeatures = layer.getVectorSource().getFeatures(
|
||||
ol.layer.Vector.selectedFeaturesFilter);
|
||||
if (clear) {
|
||||
for (var j = selectedFeatures.length - 1; j >= 0; --j) {
|
||||
selectedFeatures[j].setRenderIntent(
|
||||
ol.layer.VectorLayerRenderIntent.DEFAULT);
|
||||
ol.FeatureRenderIntent.DEFAULT);
|
||||
}
|
||||
}
|
||||
for (var j = featuresToSelect.length - 1; j >= 0; --j) {
|
||||
var feature = featuresToSelect[j];
|
||||
// TODO: Make toggle configurable
|
||||
feature.setRenderIntent(feature.getRenderIntent() ==
|
||||
ol.layer.VectorLayerRenderIntent.SELECTED ?
|
||||
ol.layer.VectorLayerRenderIntent.DEFAULT :
|
||||
ol.layer.VectorLayerRenderIntent.SELECTED);
|
||||
ol.FeatureRenderIntent.SELECTED ?
|
||||
ol.FeatureRenderIntent.DEFAULT :
|
||||
ol.FeatureRenderIntent.SELECTED);
|
||||
}
|
||||
// TODO: Dispatch an event with selectedFeatures and unselectedFeatures
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
goog.provide('ol.layer.VectorLayerRenderIntent');
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
ol.layer.VectorLayerRenderIntent = {
|
||||
DEFAULT: 'default',
|
||||
FUTURE: 'future',
|
||||
HIDDEN: 'hidden',
|
||||
SELECTED: 'selected',
|
||||
TEMPORARY: 'temporary'
|
||||
};
|
||||
@@ -75,7 +75,7 @@ ol.parser.KML = function(opt_options) {
|
||||
'*': function(node, obj) {
|
||||
if (this.extractAttributes === true) {
|
||||
var len = node.childNodes.length;
|
||||
if ((len === 1 || len === 2) && (node.firstChild.nodeType === 3 ||
|
||||
if (len > 0 && (node.firstChild.nodeType === 3 ||
|
||||
node.firstChild.nodeType === 4)) {
|
||||
var readers = this.readers[this.defaultNamespaceURI];
|
||||
readers['_attribute'].apply(this, arguments);
|
||||
|
||||
@@ -8,6 +8,7 @@ goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.FeatureRenderIntent');
|
||||
goog.require('ol.geom.AbstractCollection');
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
@@ -17,7 +18,6 @@ goog.require('ol.geom.MultiPoint');
|
||||
goog.require('ol.geom.MultiPolygon');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.layer.VectorLayerRenderIntent');
|
||||
goog.require('ol.style.IconLiteral');
|
||||
goog.require('ol.style.LineLiteral');
|
||||
goog.require('ol.style.Literal');
|
||||
@@ -158,7 +158,7 @@ ol.renderer.canvas.Vector.prototype.renderLineStringFeatures_ =
|
||||
context.beginPath();
|
||||
for (i = 0, ii = features.length; i < ii; ++i) {
|
||||
feature = features[i];
|
||||
if (feature.getRenderIntent() == ol.layer.VectorLayerRenderIntent.HIDDEN) {
|
||||
if (feature.getRenderIntent() == ol.FeatureRenderIntent.HIDDEN) {
|
||||
continue;
|
||||
}
|
||||
id = goog.getUid(feature);
|
||||
@@ -247,7 +247,7 @@ ol.renderer.canvas.Vector.prototype.renderPointFeatures_ =
|
||||
context.globalAlpha = alpha;
|
||||
for (i = 0, ii = features.length; i < ii; ++i) {
|
||||
feature = features[i];
|
||||
if (feature.getRenderIntent() == ol.layer.VectorLayerRenderIntent.HIDDEN) {
|
||||
if (feature.getRenderIntent() == ol.FeatureRenderIntent.HIDDEN) {
|
||||
continue;
|
||||
}
|
||||
id = goog.getUid(feature);
|
||||
@@ -323,7 +323,7 @@ ol.renderer.canvas.Vector.prototype.renderText_ =
|
||||
|
||||
for (var i = 0, ii = features.length; i < ii; ++i) {
|
||||
feature = features[i];
|
||||
if (feature.getRenderIntent() == ol.layer.VectorLayerRenderIntent.HIDDEN) {
|
||||
if (feature.getRenderIntent() == ol.FeatureRenderIntent.HIDDEN) {
|
||||
continue;
|
||||
}
|
||||
vecs = ol.renderer.canvas.Vector.getLabelVectors(
|
||||
@@ -391,7 +391,7 @@ ol.renderer.canvas.Vector.prototype.renderPolygonFeatures_ =
|
||||
context.beginPath();
|
||||
for (i = 0, ii = features.length; i < ii; ++i) {
|
||||
feature = features[i];
|
||||
if (feature.getRenderIntent() == ol.layer.VectorLayerRenderIntent.HIDDEN) {
|
||||
if (feature.getRenderIntent() == ol.FeatureRenderIntent.HIDDEN) {
|
||||
continue;
|
||||
}
|
||||
geometry = feature.getGeometry();
|
||||
|
||||
@@ -1,630 +0,0 @@
|
||||
// rtree.js - General-Purpose Non-Recursive Javascript R-Tree Library
|
||||
// Version 0.6.2, December 5st 2009
|
||||
//
|
||||
// Copyright (c) 2009 Jon-Carlos Rivera
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Jon-Carlos Rivera - imbcmdth@hotmail.com
|
||||
|
||||
|
||||
goog.provide('ol.structs.RTree');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('ol.extent');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{extent: ol.Extent,
|
||||
* leaf: (Object|undefined),
|
||||
* nodes: (Array.<ol.structs.RTreeNode>|undefined),
|
||||
* target: (Object|undefined)}}
|
||||
*/
|
||||
ol.structs.RTreeNode;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {number=} opt_maxWidth Width before a node is split. Default is `6`.
|
||||
*/
|
||||
ol.structs.RTree = function(opt_maxWidth) {
|
||||
|
||||
/**
|
||||
* Maximum width of any node before a split.
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.maxWidth_ = goog.isDef(opt_maxWidth) ? opt_maxWidth : 6;
|
||||
|
||||
/**
|
||||
* Minimum width of any node before a merge.
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.minWidth_ = Math.floor(this.maxWidth_ / 2);
|
||||
|
||||
/**
|
||||
* Start with an empty root-tree.
|
||||
* @private
|
||||
* @type {ol.structs.RTreeNode}
|
||||
*/
|
||||
this.rootTree_ = /** @type {ol.structs.RTreeNode} */
|
||||
({extent: ol.extent.createEmpty(), nodes: []});
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.structs.RTreeNode} node Node.
|
||||
* @private
|
||||
*/
|
||||
ol.structs.RTree.recalculateExtent_ = function(node) {
|
||||
var n = node.nodes.length;
|
||||
var extent = node.extent;
|
||||
if (n === 0) {
|
||||
ol.extent.empty(extent);
|
||||
} else {
|
||||
var firstNodeExtent = node.nodes[0].extent;
|
||||
extent[0] = firstNodeExtent[0];
|
||||
extent[2] = firstNodeExtent[2];
|
||||
extent[1] = firstNodeExtent[1];
|
||||
extent[3] = firstNodeExtent[3];
|
||||
var i;
|
||||
for (i = 1; i < n; ++i) {
|
||||
ol.extent.extend(extent, node.nodes[i].extent);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This is Jon-Carlos Rivera's special addition to the world of r-trees.
|
||||
* Every other (simple) method he found produced poor trees.
|
||||
* This skews insertions to prefering squarer and emptier nodes.
|
||||
*
|
||||
* @param {number} l L.
|
||||
* @param {number} w W.
|
||||
* @param {number} fill Fill.
|
||||
* @private
|
||||
* @return {number} Squarified ratio.
|
||||
*/
|
||||
ol.structs.RTree.squarifiedRatio_ = function(l, w, fill) {
|
||||
// Area of new enlarged rectangle
|
||||
var peri = (l + w) / 2; // Average size of a side of the new rectangle
|
||||
var area = l * w; // Area of new rectangle
|
||||
// return the ratio of the perimeter to the area - the closer to 1 we are,
|
||||
// the more "square" a rectangle is. conversly, when approaching zero the
|
||||
// more elongated a rectangle is
|
||||
var geo = area / (peri * peri);
|
||||
return area * fill / geo;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Choose the best for rectangle to be inserted into.
|
||||
*
|
||||
* @param {ol.structs.RTreeNode} rect Rectangle.
|
||||
* @param {ol.structs.RTreeNode} root Root to start search.
|
||||
* @private
|
||||
* @return {Array} Leaf node parent.
|
||||
*/
|
||||
ol.structs.RTree.prototype.chooseLeafSubtree_ = function(rect, root) {
|
||||
var bestChoiceIndex = -1;
|
||||
var bestChoiceStack = [];
|
||||
var bestChoiceArea;
|
||||
|
||||
bestChoiceStack.push(root);
|
||||
var nodes = root.nodes;
|
||||
|
||||
do {
|
||||
if (bestChoiceIndex != -1) {
|
||||
bestChoiceStack.push(nodes[bestChoiceIndex]);
|
||||
nodes = nodes[bestChoiceIndex].nodes;
|
||||
bestChoiceIndex = -1;
|
||||
}
|
||||
|
||||
for (var i = nodes.length - 1; i >= 0; --i) {
|
||||
var lTree = nodes[i];
|
||||
if (goog.isDef(lTree.leaf)) {
|
||||
// Bail out of everything and start inserting
|
||||
bestChoiceIndex = -1;
|
||||
break;
|
||||
}
|
||||
// Area of new enlarged rectangle
|
||||
var oldLRatio = ol.structs.RTree.squarifiedRatio_(
|
||||
lTree.extent[2] - lTree.extent[0],
|
||||
lTree.extent[3] - lTree.extent[1],
|
||||
lTree.nodes.length + 1);
|
||||
|
||||
// Enlarge rectangle to fit new rectangle
|
||||
var nw = (lTree.extent[2] > rect.extent[2] ?
|
||||
lTree.extent[2] : rect.extent[2]) -
|
||||
(lTree.extent[0] < rect.extent[0] ?
|
||||
lTree.extent[0] : rect.extent[0]);
|
||||
var nh = (lTree.extent[3] > rect.extent[3] ?
|
||||
lTree.extent[3] : rect.extent[3]) -
|
||||
(lTree.extent[1] < rect.extent[1] ?
|
||||
lTree.extent[1] : rect.extent[1]);
|
||||
|
||||
// Area of new enlarged rectangle
|
||||
var lRatio = ol.structs.RTree.squarifiedRatio_(
|
||||
nw, nh, lTree.nodes.length + 2);
|
||||
|
||||
if (bestChoiceIndex < 0 ||
|
||||
Math.abs(lRatio - oldLRatio) < bestChoiceArea) {
|
||||
bestChoiceArea = Math.abs(lRatio - oldLRatio);
|
||||
bestChoiceIndex = i;
|
||||
}
|
||||
}
|
||||
} while (bestChoiceIndex != -1);
|
||||
|
||||
return bestChoiceStack;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Non-recursive insert function.
|
||||
*
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {Object} obj Object to insert.
|
||||
*/
|
||||
ol.structs.RTree.prototype.insert = function(extent, obj) {
|
||||
var node = /** @type {ol.structs.RTreeNode} */
|
||||
({extent: extent, leaf: obj});
|
||||
this.insertSubtree_(node, this.rootTree_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Non-recursive internal insert function.
|
||||
*
|
||||
* @param {ol.structs.RTreeNode} node Node to insert.
|
||||
* @param {ol.structs.RTreeNode} root Root to begin insertion at.
|
||||
* @private
|
||||
*/
|
||||
ol.structs.RTree.prototype.insertSubtree_ = function(node, root) {
|
||||
var bc; // Best Current node
|
||||
// Initial insertion is special because we resize the Tree and we don't
|
||||
// care about any overflow (seriously, how can the first object overflow?)
|
||||
if (root.nodes.length === 0) {
|
||||
root.extent = ol.extent.clone(node.extent);
|
||||
root.nodes.push(node);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the best fitting leaf node
|
||||
// chooseLeaf returns an array of all tree levels (including root)
|
||||
// that were traversed while trying to find the leaf
|
||||
var treeStack = this.chooseLeafSubtree_(node, root);
|
||||
var workingObject = node;
|
||||
|
||||
// Walk back up the tree resizing and inserting as needed
|
||||
do {
|
||||
//handle the case of an empty node (from a split)
|
||||
if (bc && goog.isDef(bc.nodes) && bc.nodes.length === 0) {
|
||||
var pbc = bc; // Past bc
|
||||
bc = treeStack.pop();
|
||||
for (var t = 0, tt = bc.nodes.length; t < tt; ++t) {
|
||||
if (bc.nodes[t] === pbc || bc.nodes[t].nodes.length === 0) {
|
||||
bc.nodes.splice(t, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bc = treeStack.pop();
|
||||
}
|
||||
|
||||
// If there is data attached to this workingObject
|
||||
var isArray = goog.isArray(workingObject);
|
||||
if (goog.isDef(workingObject.leaf) ||
|
||||
goog.isDef(workingObject.nodes) || isArray) {
|
||||
// Do Insert
|
||||
if (isArray) {
|
||||
for (var ai = 0, aii = workingObject.length; ai < aii; ++ai) {
|
||||
ol.extent.extend(bc.extent, workingObject[ai].extent);
|
||||
}
|
||||
bc.nodes = bc.nodes.concat(workingObject);
|
||||
} else {
|
||||
ol.extent.extend(bc.extent, workingObject.extent);
|
||||
bc.nodes.push(workingObject); // Do Insert
|
||||
}
|
||||
|
||||
if (bc.nodes.length <= this.maxWidth_) { // Start Resizeing Up the Tree
|
||||
workingObject = {extent: ol.extent.clone(bc.extent)};
|
||||
} else { // Otherwise Split this Node
|
||||
// linearSplit_() returns an array containing two new nodes
|
||||
// formed from the split of the previous node's overflow
|
||||
var a = this.linearSplit_(bc.nodes);
|
||||
workingObject = a;//[1];
|
||||
|
||||
if (treeStack.length < 1) { // If are splitting the root..
|
||||
bc.nodes.push(a[0]);
|
||||
treeStack.push(bc); // Reconsider the root element
|
||||
workingObject = a[1];
|
||||
}
|
||||
}
|
||||
} else { // Otherwise Do Resize
|
||||
//Just keep applying the new bounding rectangle to the parents..
|
||||
ol.extent.extend(bc.extent, workingObject.extent);
|
||||
workingObject = ({extent: ol.extent.clone(bc.extent)});
|
||||
}
|
||||
} while (treeStack.length > 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Split a set of nodes into two roughly equally-filled nodes.
|
||||
*
|
||||
* @param {Array.<ol.structs.RTreeNode>} nodes Array of nodes.
|
||||
* @private
|
||||
* @return {Array.<ol.structs.RTreeNode>} An array of two nodes.
|
||||
*/
|
||||
ol.structs.RTree.prototype.linearSplit_ = function(nodes) {
|
||||
var n = this.pickLinear_(nodes);
|
||||
while (nodes.length > 0) {
|
||||
this.pickNext_(nodes, n[0], n[1]);
|
||||
}
|
||||
return n;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Pick the "best" two starter nodes to use as seeds using the "linear"
|
||||
* criteria.
|
||||
*
|
||||
* @param {Array.<ol.structs.RTreeNode>} nodes Array of source nodes.
|
||||
* @private
|
||||
* @return {Array.<ol.structs.RTreeNode>} An array of two nodes.
|
||||
*/
|
||||
ol.structs.RTree.prototype.pickLinear_ = function(nodes) {
|
||||
var lowestHighX = nodes.length - 1;
|
||||
var highestLowX = 0;
|
||||
var lowestHighY = nodes.length - 1;
|
||||
var highestLowY = 0;
|
||||
var t1, t2;
|
||||
|
||||
for (var i = nodes.length - 2; i >= 0; --i) {
|
||||
var l = nodes[i];
|
||||
if (l.extent[0] > nodes[highestLowX].extent[0]) {
|
||||
highestLowX = i;
|
||||
} else if (l.extent[2] < nodes[lowestHighX].extent[1]) {
|
||||
lowestHighX = i;
|
||||
}
|
||||
if (l.extent[1] > nodes[highestLowY].extent[1]) {
|
||||
highestLowY = i;
|
||||
} else if (l.extent[3] < nodes[lowestHighY].extent[3]) {
|
||||
lowestHighY = i;
|
||||
}
|
||||
}
|
||||
var dx = Math.abs(nodes[lowestHighX].extent[2] -
|
||||
nodes[highestLowX].extent[0]);
|
||||
var dy = Math.abs(nodes[lowestHighY].extent[3] -
|
||||
nodes[highestLowY].extent[1]);
|
||||
if (dx > dy) {
|
||||
if (lowestHighX > highestLowX) {
|
||||
t1 = nodes.splice(lowestHighX, 1)[0];
|
||||
t2 = nodes.splice(highestLowX, 1)[0];
|
||||
} else {
|
||||
t2 = nodes.splice(highestLowX, 1)[0];
|
||||
t1 = nodes.splice(lowestHighX, 1)[0];
|
||||
}
|
||||
} else {
|
||||
if (lowestHighY > highestLowY) {
|
||||
t1 = nodes.splice(lowestHighY, 1)[0];
|
||||
t2 = nodes.splice(highestLowY, 1)[0];
|
||||
} else {
|
||||
t2 = nodes.splice(highestLowY, 1)[0];
|
||||
t1 = nodes.splice(lowestHighY, 1)[0];
|
||||
}
|
||||
}
|
||||
return [
|
||||
/** @type {ol.structs.RTreeNode} */
|
||||
({extent: ol.extent.clone(t1.extent), nodes: [t1]}),
|
||||
/** @type {ol.structs.RTreeNode} */
|
||||
({extent: ol.extent.clone(t2.extent), nodes: [t2]})
|
||||
];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Insert the best source rectangle into the best fitting parent node: a or b.
|
||||
*
|
||||
* @param {Array.<ol.structs.RTreeNode>} nodes Source node array.
|
||||
* @param {ol.structs.RTreeNode} a Target node array a.
|
||||
* @param {ol.structs.RTreeNode} b Target node array b.
|
||||
* @private
|
||||
*/
|
||||
ol.structs.RTree.prototype.pickNext_ = function(nodes, a, b) {
|
||||
// Area of new enlarged rectangle
|
||||
var areaA = ol.structs.RTree.squarifiedRatio_(a.extent[2] - a.extent[0],
|
||||
a.extent[3] - a.extent[1], a.nodes.length + 1);
|
||||
var areaB = ol.structs.RTree.squarifiedRatio_(b.extent[2] - b.extent[0],
|
||||
b.extent[3] - b.extent[1], b.nodes.length + 1);
|
||||
var highAreaDelta;
|
||||
var highAreaNode;
|
||||
var lowestGrowthGroup;
|
||||
|
||||
for (var i = nodes.length - 1; i >= 0; --i) {
|
||||
var l = nodes[i];
|
||||
|
||||
var newAreaA = [
|
||||
a.extent[0] < l.extent[0] ? a.extent[0] : l.extent[0],
|
||||
a.extent[2] > l.extent[2] ? a.extent[2] : l.extent[2],
|
||||
a.extent[1] < l.extent[1] ? a.extent[1] : l.extent[1],
|
||||
a.extent[3] > l.extent[3] ? a.extent[3] : l.extent[3]
|
||||
];
|
||||
var changeNewAreaA = Math.abs(ol.structs.RTree.squarifiedRatio_(
|
||||
newAreaA[1] - newAreaA[0],
|
||||
newAreaA[3] - newAreaA[2], a.nodes.length + 2) - areaA);
|
||||
|
||||
var newAreaB = [
|
||||
b.extent[0] < l.extent[0] ? b.extent[0] : l.extent[0],
|
||||
b.extent[2] > l.extent[2] ? b.extent[2] : l.extent[2],
|
||||
b.extent[1] < l.extent[1] ? b.extent[1] : l.extent[1],
|
||||
b.extent[3] > l.extent[3] ? b.extent[3] : l.extent[3]
|
||||
];
|
||||
var changeNewAreaB = Math.abs(ol.structs.RTree.squarifiedRatio_(
|
||||
newAreaB[1] - newAreaB[0], newAreaB[3] - newAreaB[2],
|
||||
b.nodes.length + 2) - areaB);
|
||||
|
||||
var changeNewAreaDelta = Math.abs(changeNewAreaB - changeNewAreaA);
|
||||
if (!highAreaNode || !highAreaDelta ||
|
||||
changeNewAreaDelta < highAreaDelta) {
|
||||
highAreaNode = i;
|
||||
highAreaDelta = changeNewAreaDelta;
|
||||
lowestGrowthGroup = changeNewAreaB < changeNewAreaA ? b : a;
|
||||
}
|
||||
}
|
||||
var tempNode = nodes.splice(highAreaNode, 1)[0];
|
||||
if (a.nodes.length + nodes.length + 1 <= this.minWidth_) {
|
||||
a.nodes.push(tempNode);
|
||||
ol.extent.extend(a.extent, tempNode.extent);
|
||||
} else if (b.nodes.length + nodes.length + 1 <= this.minWidth_) {
|
||||
b.nodes.push(tempNode);
|
||||
ol.extent.extend(b.extent, tempNode.extent);
|
||||
}
|
||||
else {
|
||||
lowestGrowthGroup.nodes.push(tempNode);
|
||||
ol.extent.extend(lowestGrowthGroup.extent, tempNode.extent);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Non-recursive function that deletes a specific region.
|
||||
*
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {Object=} opt_obj Object.
|
||||
* @return {Array} Result.
|
||||
* @this {ol.structs.RTree}
|
||||
*/
|
||||
ol.structs.RTree.prototype.remove = function(extent, opt_obj) {
|
||||
arguments[0] = /** @type {ol.structs.RTreeNode} */ ({extent: extent});
|
||||
switch (arguments.length) {
|
||||
case 1:
|
||||
arguments[1] = false; // opt_obj == false for conditionals
|
||||
case 2:
|
||||
arguments[2] = this.rootTree_; // Add root node to end of argument list
|
||||
default:
|
||||
arguments.length = 3;
|
||||
}
|
||||
if (arguments[1] === false) { // Do area-wide †
|
||||
var numberDeleted = 0;
|
||||
var result = [];
|
||||
do {
|
||||
numberDeleted = result.length;
|
||||
result = result.concat(this.removeSubtree_.apply(this, arguments));
|
||||
} while (numberDeleted != result.length);
|
||||
return result;
|
||||
} else { // Delete a specific item
|
||||
return this.removeSubtree_.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Find the best specific node(s) for object to be deleted from.
|
||||
*
|
||||
* @param {ol.structs.RTreeNode} rect Rectangle.
|
||||
* @param {Object} obj Object.
|
||||
* @param {ol.structs.RTreeNode} root Root to start search.
|
||||
* @private
|
||||
* @return {Array} Leaf node parent.
|
||||
*/
|
||||
ol.structs.RTree.prototype.removeSubtree_ = function(rect, obj, root) {
|
||||
var hitStack = []; // Contains the elements that overlap
|
||||
var countStack = []; // Contains the elements that overlap
|
||||
var returnArray = [];
|
||||
var currentDepth = 1;
|
||||
|
||||
if (!rect || !ol.extent.intersects(rect.extent, root.extent)) {
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
/** @type {ol.structs.RTreeNode} */
|
||||
var workingObject = /** @type {ol.structs.RTreeNode} */
|
||||
({extent: ol.extent.clone(rect.extent), target: obj});
|
||||
|
||||
countStack.push(root.nodes.length);
|
||||
hitStack.push(root);
|
||||
|
||||
do {
|
||||
var tree = hitStack.pop();
|
||||
var i = countStack.pop() - 1;
|
||||
|
||||
if (goog.isDef(workingObject.target)) {
|
||||
// We are searching for a target
|
||||
while (i >= 0) {
|
||||
var lTree = tree.nodes[i];
|
||||
if (ol.extent.intersects(workingObject.extent, lTree.extent)) {
|
||||
if ((workingObject.target && goog.isDef(lTree.leaf) &&
|
||||
lTree.leaf === workingObject.target) ||
|
||||
(!workingObject.target && (goog.isDef(lTree.leaf) ||
|
||||
ol.extent.containsExtent(workingObject.extent, lTree.extent))))
|
||||
{ // A Match !!
|
||||
// Yup we found a match...
|
||||
// we can cancel search and start walking up the list
|
||||
if (goog.isDef(lTree.nodes)) {
|
||||
// If we are deleting a node not a leaf...
|
||||
returnArray = this.searchSubtree_(lTree, true, [], lTree);
|
||||
tree.nodes.splice(i, 1);
|
||||
} else {
|
||||
returnArray = tree.nodes.splice(i, 1);
|
||||
}
|
||||
// Resize MBR down...
|
||||
ol.structs.RTree.recalculateExtent_(tree);
|
||||
workingObject.target = undefined;
|
||||
if (tree.nodes.length < this.minWidth_) { // Underflow
|
||||
workingObject.nodes = /** @type {Array} */
|
||||
(this.searchSubtree_(tree, true, [], tree));
|
||||
}
|
||||
break;
|
||||
} else if (goog.isDef(lTree.nodes)) {
|
||||
// Not a Leaf
|
||||
currentDepth += 1;
|
||||
countStack.push(i);
|
||||
hitStack.push(tree);
|
||||
tree = lTree;
|
||||
i = lTree.nodes.length;
|
||||
}
|
||||
}
|
||||
i -= 1;
|
||||
}
|
||||
} else if (goog.isDef(workingObject.nodes)) {
|
||||
// We are unsplitting
|
||||
tree.nodes.splice(i + 1, 1); // Remove unsplit node
|
||||
// workingObject.nodes contains a list of elements removed from the
|
||||
// tree so far
|
||||
if (tree.nodes.length > 0) {
|
||||
ol.structs.RTree.recalculateExtent_(tree);
|
||||
}
|
||||
for (var t = 0, tt = workingObject.nodes.length; t < tt; ++t) {
|
||||
this.insertSubtree_(workingObject.nodes[t], tree);
|
||||
}
|
||||
workingObject.nodes.length = 0;
|
||||
if (hitStack.length === 0 && tree.nodes.length <= 1) {
|
||||
// Underflow..on root!
|
||||
workingObject.nodes = /** @type {Array} */
|
||||
(this.searchSubtree_(tree, true, workingObject.nodes, tree));
|
||||
tree.nodes.length = 0;
|
||||
hitStack.push(tree);
|
||||
countStack.push(1);
|
||||
} else if (hitStack.length > 0 && tree.nodes.length < this.minWidth_) {
|
||||
// Underflow..AGAIN!
|
||||
workingObject.nodes = /** @type {Array} */
|
||||
(this.searchSubtree_(tree, true, workingObject.nodes, tree));
|
||||
tree.nodes.length = 0;
|
||||
} else {
|
||||
workingObject.nodes = undefined; // Just start resizing
|
||||
}
|
||||
} else { // we are just resizing
|
||||
ol.structs.RTree.recalculateExtent_(tree);
|
||||
}
|
||||
currentDepth -= 1;
|
||||
} while (hitStack.length > 0);
|
||||
|
||||
return returnArray;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Non-recursive search function
|
||||
*
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @return {Array} Result.
|
||||
* @this {ol.structs.RTree}
|
||||
*/
|
||||
ol.structs.RTree.prototype.search = function(extent) {
|
||||
var rect = /** @type {ol.structs.RTreeNode} */ ({extent: extent});
|
||||
return /** @type {Array} */ (
|
||||
this.searchSubtree_(rect, false, [], this.rootTree_));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Non-recursive search function
|
||||
*
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @return {Object} Result. Keys are UIDs of the values.
|
||||
* @this {ol.structs.RTree}
|
||||
*/
|
||||
ol.structs.RTree.prototype.searchReturningObject = function(extent) {
|
||||
var rect = /** @type {ol.structs.RTreeNode} */ ({extent: extent});
|
||||
return /** @type {Object} */ (
|
||||
this.searchSubtree_(rect, false, [], this.rootTree_, true));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Non-recursive internal search function
|
||||
*
|
||||
* @param {ol.structs.RTreeNode} rect Rectangle.
|
||||
* @param {boolean} returnNode Do we return nodes?
|
||||
* @param {Array|Object} result Result.
|
||||
* @param {ol.structs.RTreeNode} root Root.
|
||||
* @param {boolean=} opt_resultAsObject If set, result will be an object keyed
|
||||
* by UID.
|
||||
* @private
|
||||
* @return {Array|Object} Result.
|
||||
*/
|
||||
ol.structs.RTree.prototype.searchSubtree_ = function(
|
||||
rect, returnNode, result, root, opt_resultAsObject) {
|
||||
var resultObject = {};
|
||||
var hitStack = []; // Contains the elements that overlap
|
||||
|
||||
if (!ol.extent.intersects(rect.extent, root.extent)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
hitStack.push(root.nodes);
|
||||
|
||||
do {
|
||||
var nodes = hitStack.pop();
|
||||
|
||||
for (var i = nodes.length - 1; i >= 0; --i) {
|
||||
var lTree = nodes[i];
|
||||
if (ol.extent.intersects(rect.extent, lTree.extent)) {
|
||||
if (goog.isDef(lTree.nodes)) { // Not a Leaf
|
||||
hitStack.push(lTree.nodes);
|
||||
} else if (goog.isDef(lTree.leaf)) { // A Leaf !!
|
||||
if (!returnNode) {
|
||||
// TODO keep track of type on all nodes so we don't have to
|
||||
// walk all the way in to the leaf to know that we don't need it
|
||||
var obj = lTree.leaf;
|
||||
if (goog.isDef(opt_resultAsObject)) {
|
||||
resultObject[goog.getUid(obj).toString()] = obj;
|
||||
} else {
|
||||
result.push(obj);
|
||||
}
|
||||
} else {
|
||||
result.push(lTree);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (hitStack.length > 0);
|
||||
|
||||
if (goog.isDef(opt_resultAsObject)) {
|
||||
return resultObject;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
goog.provide('ol.test.interaction.Draw');
|
||||
|
||||
describe('ol.interaction.Draw', function() {
|
||||
var target, map, vector;
|
||||
var target, map, source, layer;
|
||||
|
||||
var width = 360;
|
||||
var height = 180;
|
||||
@@ -15,11 +15,12 @@ describe('ol.interaction.Draw', function() {
|
||||
style.width = width + 'px';
|
||||
style.height = height + 'px';
|
||||
document.body.appendChild(target);
|
||||
vector = new ol.layer.Vector({source: new ol.source.Vector({})});
|
||||
source = new ol.source.Vector();
|
||||
layer = new ol.layer.Vector({source: source});
|
||||
map = new ol.Map({
|
||||
target: target,
|
||||
renderer: ol.RendererHint.CANVAS,
|
||||
layers: [vector],
|
||||
layers: [layer],
|
||||
view: new ol.View2D({
|
||||
projection: 'EPSG:4326',
|
||||
center: [0, 0],
|
||||
@@ -56,7 +57,7 @@ describe('ol.interaction.Draw', function() {
|
||||
|
||||
it('creates a new interaction', function() {
|
||||
var draw = new ol.interaction.Draw({
|
||||
layer: vector,
|
||||
layer: layer,
|
||||
type: ol.geom.GeometryType.POINT
|
||||
});
|
||||
expect(draw).to.be.a(ol.interaction.Draw);
|
||||
@@ -69,7 +70,7 @@ describe('ol.interaction.Draw', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
map.addInteraction(new ol.interaction.Draw({
|
||||
layer: vector,
|
||||
layer: layer,
|
||||
type: ol.geom.GeometryType.POINT
|
||||
}));
|
||||
});
|
||||
@@ -79,7 +80,7 @@ describe('ol.interaction.Draw', function() {
|
||||
simulateEvent('mousedown', 10, 20);
|
||||
simulateEvent('mouseup', 10, 20);
|
||||
simulateEvent('click', 10, 20);
|
||||
var features = vector.getFeatures();
|
||||
var features = source.getFeatures();
|
||||
expect(features).to.have.length(1);
|
||||
var geometry = features[0].getGeometry();
|
||||
expect(geometry).to.be.a(ol.geom.Point);
|
||||
@@ -92,7 +93,7 @@ describe('ol.interaction.Draw', function() {
|
||||
simulateEvent('mousemove', 15, 20);
|
||||
simulateEvent('mouseup', 15, 20);
|
||||
simulateEvent('click', 15, 20);
|
||||
var features = vector.getFeatures();
|
||||
var features = source.getFeatures();
|
||||
expect(features).to.have.length(0);
|
||||
});
|
||||
|
||||
@@ -102,7 +103,7 @@ describe('ol.interaction.Draw', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
map.addInteraction(new ol.interaction.Draw({
|
||||
layer: vector,
|
||||
layer: layer,
|
||||
type: ol.geom.GeometryType.MULTIPOINT
|
||||
}));
|
||||
});
|
||||
@@ -112,7 +113,7 @@ describe('ol.interaction.Draw', function() {
|
||||
simulateEvent('mousedown', 30, 15);
|
||||
simulateEvent('mouseup', 30, 15);
|
||||
simulateEvent('click', 30, 15);
|
||||
var features = vector.getFeatures();
|
||||
var features = source.getFeatures();
|
||||
expect(features).to.have.length(1);
|
||||
var geometry = features[0].getGeometry();
|
||||
expect(geometry).to.be.a(ol.geom.MultiPoint);
|
||||
@@ -125,7 +126,7 @@ describe('ol.interaction.Draw', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
map.addInteraction(new ol.interaction.Draw({
|
||||
layer: vector,
|
||||
layer: layer,
|
||||
type: ol.geom.GeometryType.LINESTRING
|
||||
}));
|
||||
});
|
||||
@@ -148,7 +149,7 @@ describe('ol.interaction.Draw', function() {
|
||||
simulateEvent('mouseup', 30, 20);
|
||||
simulateEvent('click', 30, 20);
|
||||
|
||||
var features = vector.getFeatures();
|
||||
var features = source.getFeatures();
|
||||
expect(features).to.have.length(1);
|
||||
var geometry = features[0].getGeometry();
|
||||
expect(geometry).to.be.a(ol.geom.LineString);
|
||||
@@ -181,7 +182,7 @@ describe('ol.interaction.Draw', function() {
|
||||
simulateEvent('mouseup', 30, 20);
|
||||
simulateEvent('click', 30, 20);
|
||||
|
||||
var features = vector.getFeatures();
|
||||
var features = source.getFeatures();
|
||||
expect(features).to.have.length(1);
|
||||
var geometry = features[0].getGeometry();
|
||||
expect(geometry).to.be.a(ol.geom.LineString);
|
||||
@@ -194,7 +195,7 @@ describe('ol.interaction.Draw', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
map.addInteraction(new ol.interaction.Draw({
|
||||
layer: vector,
|
||||
layer: layer,
|
||||
type: ol.geom.GeometryType.MULTILINESTRING
|
||||
}));
|
||||
});
|
||||
@@ -217,7 +218,7 @@ describe('ol.interaction.Draw', function() {
|
||||
simulateEvent('mouseup', 30, 20);
|
||||
simulateEvent('click', 30, 20);
|
||||
|
||||
var features = vector.getFeatures();
|
||||
var features = source.getFeatures();
|
||||
expect(features).to.have.length(1);
|
||||
var geometry = features[0].getGeometry();
|
||||
expect(geometry).to.be.a(ol.geom.MultiLineString);
|
||||
@@ -230,7 +231,7 @@ describe('ol.interaction.Draw', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
map.addInteraction(new ol.interaction.Draw({
|
||||
layer: vector,
|
||||
layer: layer,
|
||||
type: ol.geom.GeometryType.POLYGON
|
||||
}));
|
||||
});
|
||||
@@ -260,7 +261,7 @@ describe('ol.interaction.Draw', function() {
|
||||
simulateEvent('mouseup', 10, 20);
|
||||
simulateEvent('click', 10, 20);
|
||||
|
||||
var features = vector.getFeatures();
|
||||
var features = source.getFeatures();
|
||||
expect(features).to.have.length(1);
|
||||
var geometry = features[0].getGeometry();
|
||||
expect(geometry).to.be.a(ol.geom.Polygon);
|
||||
@@ -277,7 +278,7 @@ describe('ol.interaction.Draw', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
map.addInteraction(new ol.interaction.Draw({
|
||||
layer: vector,
|
||||
layer: layer,
|
||||
type: ol.geom.GeometryType.MULTIPOLYGON
|
||||
}));
|
||||
});
|
||||
@@ -307,7 +308,7 @@ describe('ol.interaction.Draw', function() {
|
||||
simulateEvent('mouseup', 10, 20);
|
||||
simulateEvent('click', 10, 20);
|
||||
|
||||
var features = vector.getFeatures();
|
||||
var features = source.getFeatures();
|
||||
expect(features).to.have.length(1);
|
||||
var geometry = features[0].getGeometry();
|
||||
expect(geometry).to.be.a(ol.geom.MultiPolygon);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
goog.provide('ol.test.interaction.Select');
|
||||
|
||||
describe('ol.interaction.Select', function() {
|
||||
var map, target, select, vector, features;
|
||||
var map, target, select, source, vector, features;
|
||||
|
||||
beforeEach(function() {
|
||||
target = document.createElement('div');
|
||||
@@ -11,24 +11,19 @@ describe('ol.interaction.Select', function() {
|
||||
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);
|
||||
|
||||
features = [
|
||||
new ol.Feature({
|
||||
geometry: new ol.geom.Point([-1, 1])
|
||||
}),
|
||||
new ol.Feature({
|
||||
geometry: new ol.geom.Point([1, -1])
|
||||
})
|
||||
];
|
||||
|
||||
source = new ol.source.Vector({});
|
||||
source.addFeatures(features);
|
||||
vector = new ol.layer.Vector({source: source});
|
||||
select = new ol.interaction.Select({
|
||||
layers: [vector]
|
||||
});
|
||||
@@ -52,21 +47,21 @@ describe('ol.interaction.Select', function() {
|
||||
|
||||
it('toggles selection of features', function() {
|
||||
select.select(map, [features], [vector]);
|
||||
expect(vector.getFeatures(selectedFeaturesFilter).length).to.be(2);
|
||||
expect(source.getFeatures(selectedFeaturesFilter).length).to.be(2);
|
||||
select.select(map, [features], [vector]);
|
||||
expect(vector.getFeatures(selectedFeaturesFilter).length).to.be(0);
|
||||
expect(source.getFeatures(selectedFeaturesFilter).length).to.be(0);
|
||||
});
|
||||
|
||||
it('can append features to an existing selection', function() {
|
||||
select.select(map, [[features[0]]], [vector], true);
|
||||
select.select(map, [[features[1]]], [vector]);
|
||||
expect(vector.getFeatures(selectedFeaturesFilter).length).to.be(2);
|
||||
expect(source.getFeatures(selectedFeaturesFilter).length).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);
|
||||
expect(vector.getFeatures(selectedFeaturesFilter).length).to.be(1);
|
||||
expect(source.getFeatures(selectedFeaturesFilter).length).to.be(1);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -74,8 +69,9 @@ describe('ol.interaction.Select', function() {
|
||||
});
|
||||
|
||||
goog.require('goog.dispose');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.interaction.Select');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.parser.GeoJSON');
|
||||
goog.require('ol.source.Vector');
|
||||
|
||||
@@ -2,177 +2,15 @@ goog.provide('ol.test.layer.Vector');
|
||||
|
||||
describe('ol.layer.Vector', function() {
|
||||
|
||||
describe('#addFeatures()', function() {
|
||||
describe('constructor', function() {
|
||||
|
||||
it('creates a new layer', function() {
|
||||
|
||||
it('allows adding features', function() {
|
||||
var layer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({})
|
||||
source: new ol.source.Vector()
|
||||
});
|
||||
layer.addFeatures([new ol.Feature(), new ol.Feature()]);
|
||||
expect(goog.object.getCount(layer.featureCache_.getFeaturesObject()))
|
||||
.to.eql(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ol.layer.FeatureCache#getFeaturesObject()', function() {
|
||||
|
||||
var layer, features;
|
||||
|
||||
beforeEach(function() {
|
||||
features = [
|
||||
new ol.Feature({
|
||||
g: new ol.geom.Point([16.0, 48.0])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[17.0, 49.0], [17.1, 49.1]])
|
||||
})
|
||||
];
|
||||
layer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({})
|
||||
});
|
||||
layer.addFeatures(features);
|
||||
});
|
||||
|
||||
it('returns the features in an object', function() {
|
||||
var featuresObject = layer.featureCache_.getFeaturesObject();
|
||||
expect(goog.object.getCount(featuresObject)).to.eql(features.length);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#groupFeaturesBySymbolizerLiteral()', function() {
|
||||
|
||||
var layer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
projection: ol.proj.get('EPSG:4326')
|
||||
}),
|
||||
style: new ol.style.Style({
|
||||
rules: [
|
||||
new ol.style.Rule({
|
||||
symbolizers: [
|
||||
new ol.style.Stroke({
|
||||
width: 2,
|
||||
color: ol.expr.parse('colorProperty'),
|
||||
opacity: 1
|
||||
})
|
||||
]
|
||||
})
|
||||
]
|
||||
})
|
||||
});
|
||||
var features;
|
||||
|
||||
it('groups equal symbolizers', function() {
|
||||
features = [
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, -10], [10, 10]]),
|
||||
colorProperty: '#BADA55'
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, 10], [10, -10]]),
|
||||
colorProperty: '#013'
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[10, -10], [-10, -10]]),
|
||||
colorProperty: '#013'
|
||||
})
|
||||
];
|
||||
|
||||
var groups = layer.groupFeaturesBySymbolizerLiteral(features, 1);
|
||||
expect(groups.length).to.be(2);
|
||||
expect(groups[0][0].length).to.be(1);
|
||||
expect(groups[0][1].color).to.be('#BADA55');
|
||||
expect(groups[1][0].length).to.be(2);
|
||||
expect(groups[1][1].color).to.be('#013');
|
||||
});
|
||||
|
||||
it('groups equal symbolizers also when defined on features', function() {
|
||||
var symbolizer = new ol.style.Stroke({
|
||||
width: 3,
|
||||
color: ol.expr.parse('colorProperty'),
|
||||
opacity: 1
|
||||
});
|
||||
var anotherSymbolizer = new ol.style.Stroke({
|
||||
width: 3,
|
||||
color: '#BADA55',
|
||||
opacity: 1
|
||||
});
|
||||
var featureWithSymbolizers = new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, -10], [-10, 10]]),
|
||||
colorProperty: '#BADA55'
|
||||
});
|
||||
featureWithSymbolizers.setSymbolizers([symbolizer]);
|
||||
var anotherFeatureWithSymbolizers = new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, 10], [-10, -10]])
|
||||
});
|
||||
anotherFeatureWithSymbolizers.setSymbolizers([anotherSymbolizer]);
|
||||
features.push(featureWithSymbolizers, anotherFeatureWithSymbolizers);
|
||||
|
||||
var groups = layer.groupFeaturesBySymbolizerLiteral(features, 1);
|
||||
expect(groups).to.have.length(3);
|
||||
expect(groups[2][0].length).to.be(2);
|
||||
expect(groups[2][1].width).to.be(3);
|
||||
|
||||
});
|
||||
|
||||
it('sorts groups by zIndex', function() {
|
||||
var symbolizer = new ol.style.Stroke({
|
||||
width: 3,
|
||||
color: '#BADA55',
|
||||
opacity: 1,
|
||||
zIndex: 1
|
||||
});
|
||||
var anotherSymbolizer = new ol.style.Stroke({
|
||||
width: 3,
|
||||
color: '#BADA55',
|
||||
opacity: 1
|
||||
});
|
||||
var featureWithSymbolizers = new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, -10], [-10, 10]])
|
||||
});
|
||||
featureWithSymbolizers.setSymbolizers([symbolizer]);
|
||||
var anotherFeatureWithSymbolizers = new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, 10], [-10, -10]])
|
||||
});
|
||||
anotherFeatureWithSymbolizers.setSymbolizers([anotherSymbolizer]);
|
||||
features = [featureWithSymbolizers, anotherFeatureWithSymbolizers];
|
||||
|
||||
var groups = layer.groupFeaturesBySymbolizerLiteral(features, 1);
|
||||
expect(groups).to.have.length(2);
|
||||
expect(groups[0][1].zIndex).to.be(0);
|
||||
expect(groups[1][1].zIndex).to.be(1);
|
||||
});
|
||||
|
||||
goog.dispose(layer);
|
||||
|
||||
});
|
||||
|
||||
describe('ol.layer.VectorEvent', function() {
|
||||
|
||||
var layer, features;
|
||||
|
||||
beforeEach(function() {
|
||||
features = [
|
||||
new ol.Feature({
|
||||
g: new ol.geom.Point([16.0, 48.0])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[17.0, 49.0], [17.1, 49.1]])
|
||||
})
|
||||
];
|
||||
layer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({})
|
||||
});
|
||||
layer.addFeatures(features);
|
||||
});
|
||||
|
||||
it('dispatches events on feature change', function(done) {
|
||||
layer.on('featurechange', function(evt) {
|
||||
expect(evt.features[0]).to.be(features[0]);
|
||||
expect(evt.extents[0]).to.eql(features[0].getGeometry().getBounds());
|
||||
done();
|
||||
});
|
||||
features[0].set('foo', 'bar');
|
||||
expect(layer).to.be.a(ol.layer.Vector);
|
||||
expect(layer).to.be.a(ol.layer.Layer);
|
||||
|
||||
});
|
||||
|
||||
@@ -180,15 +18,6 @@ describe('ol.layer.Vector', function() {
|
||||
|
||||
});
|
||||
|
||||
goog.require('goog.dispose');
|
||||
goog.require('goog.object');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.expr');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.layer.Layer');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Rule');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
@@ -163,6 +163,19 @@ describe('ol.parser.KML', function() {
|
||||
expect(obj.features[0].get('description')).to.eql('Full of text.');
|
||||
expect(obj.features[0].get('name')).to.eql('Pezinok');
|
||||
});
|
||||
it('Test CDATA attributes with newlines', function() {
|
||||
var cdata = '<kml xmlns="http://earth.google.com/kml/2.0"><Document>' +
|
||||
'<Placemark><name><![CDATA[Pezinok]]> </name><description>' +
|
||||
'\n' +
|
||||
'<![CDATA[Full of text.]]>' +
|
||||
'\n' +
|
||||
'</description><styleUrl>#rel1.0' +
|
||||
'</styleUrl><Point> <coordinates>17.266666, 48.283333</coordinates>' +
|
||||
'</Point></Placemark></Document></kml>';
|
||||
var obj = parser.read(cdata);
|
||||
expect(obj.features[0].get('description')).to.eql('Full of text.');
|
||||
expect(obj.features[0].get('name')).to.eql('Pezinok');
|
||||
});
|
||||
|
||||
it('handles line style (read / write)', function() {
|
||||
var kml = '<kml xmlns="http://www.opengis.net/kml/2.2" ' +
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
goog.provide('ol.test.structs.RTree');
|
||||
|
||||
|
||||
describe('ol.structs.RTree', function() {
|
||||
|
||||
var rTree = new ol.structs.RTree();
|
||||
|
||||
describe('creation', function() {
|
||||
it('can insert 1k objects', function() {
|
||||
var i = 1000;
|
||||
while (i > 0) {
|
||||
var min = [Math.random() * 10000, Math.random() * 10000];
|
||||
var max = [min[0] + Math.random() * 500, min[1] + Math.random() * 500];
|
||||
var bounds = [min[0], min[1], max[0], max[1]];
|
||||
rTree.insert(bounds, 'JUST A TEST OBJECT!_' + i);
|
||||
i--;
|
||||
}
|
||||
expect(goog.object.getCount(rTree.search([0, 0, 10600, 10600])))
|
||||
.to.be(1000);
|
||||
});
|
||||
it('can insert 1k more objects', function() {
|
||||
var i = 1000;
|
||||
while (i > 0) {
|
||||
var min = [Math.random() * 10000, Math.random() * 10000];
|
||||
var max = [min[0] + Math.random() * 500, min[1] + Math.random() * 500];
|
||||
var bounds = [min[0], min[1], max[0], max[1]];
|
||||
rTree.insert(bounds, 'JUST A TEST OBJECT!_' + i);
|
||||
i--;
|
||||
}
|
||||
expect(goog.object.getCount(rTree.search([0, 0, 10600, 10600])))
|
||||
.to.be(2000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('search', function() {
|
||||
it('can perform 1k out-of-bounds searches', function() {
|
||||
var i = 1000;
|
||||
var len = 0;
|
||||
while (i > 0) {
|
||||
var min = [-(Math.random() * 10000 + 501),
|
||||
-(Math.random() * 10000 + 501)];
|
||||
var max = [min[0] + Math.random() * 500, min[1] + Math.random() * 500];
|
||||
var bounds = [min[0], min[1], max[0], max[1]];
|
||||
len += rTree.search(bounds).length;
|
||||
i--;
|
||||
}
|
||||
expect(len).to.be(0);
|
||||
});
|
||||
it('can perform 1k in-bounds searches', function() {
|
||||
var i = 1000;
|
||||
var len = 0;
|
||||
while (i > 0) {
|
||||
var min = [Math.random() * 10000, Math.random() * 10000];
|
||||
var max = [min[0] + Math.random() * 500, min[1] + Math.random() * 500];
|
||||
var bounds = [min[0], min[1], max[0], max[1]];
|
||||
len += rTree.search(bounds).length;
|
||||
i--;
|
||||
}
|
||||
expect(len).not.to.be(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('deletion', function() {
|
||||
var len = 0;
|
||||
it('can delete half the RTree', function() {
|
||||
var bounds = [5000, 0, 10500, 10500];
|
||||
len += rTree.remove(bounds).length;
|
||||
expect(len).to.not.be(0);
|
||||
});
|
||||
it('can delete the other half of the RTree', function() {
|
||||
var bounds = [0, 0, 5000, 10500];
|
||||
len += rTree.remove(bounds).length;
|
||||
expect(len).to.be(2000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('result plausibility and structure', function() {
|
||||
|
||||
it('filters by rectangle', function() {
|
||||
rTree.insert([0, 0, 1, 1], 1);
|
||||
rTree.insert([1, 1, 4, 4], 2);
|
||||
rTree.insert([2, 2, 3, 3], 3);
|
||||
rTree.insert([-5, -5, -4, -4], 4);
|
||||
rTree.insert([-4, -4, -1, -1], 5);
|
||||
rTree.insert([-3, -3, -2, -2], 6);
|
||||
|
||||
var result;
|
||||
result = goog.object.getValues(rTree.search([2, 2, 3, 3]));
|
||||
expect(result).to.contain(2);
|
||||
expect(result).to.contain(3);
|
||||
expect(result.length).to.be(2);
|
||||
result = goog.object.getValues(rTree.search([-1, -1, 2, 2]));
|
||||
expect(result).to.contain(1);
|
||||
expect(result).to.contain(2);
|
||||
expect(result).to.contain(3);
|
||||
expect(result).to.contain(5);
|
||||
expect(result.length).to.be(4);
|
||||
expect(goog.object.getCount(rTree.search([5, 5, 6, 6]))).to.be(0);
|
||||
});
|
||||
|
||||
it('can return objects instead of arrays', function() {
|
||||
var obj = {foo: 'bar'};
|
||||
rTree.insert([5, 5, 5, 5], obj);
|
||||
var result = rTree.searchReturningObject([4, 4, 6, 6]);
|
||||
expect(result[goog.getUid(obj)]).to.equal(obj);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('goog.object');
|
||||
goog.require('ol.structs.RTree');
|
||||
@@ -122,6 +122,102 @@ describe('ol.style.Style', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('#groupFeaturesBySymbolizerLiteral()', function() {
|
||||
|
||||
var style = new ol.style.Style({
|
||||
symbolizers: [
|
||||
new ol.style.Stroke({
|
||||
width: 2,
|
||||
color: ol.expr.parse('colorProperty'),
|
||||
opacity: 1
|
||||
})
|
||||
]
|
||||
});
|
||||
var features;
|
||||
|
||||
it('groups equal symbolizers', function() {
|
||||
features = [
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, -10], [10, 10]]),
|
||||
colorProperty: '#BADA55'
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, 10], [10, -10]]),
|
||||
colorProperty: '#013'
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[10, -10], [-10, -10]]),
|
||||
colorProperty: '#013'
|
||||
})
|
||||
];
|
||||
|
||||
var groups = style.groupFeaturesBySymbolizerLiteral(features, 1);
|
||||
expect(groups.length).to.be(2);
|
||||
expect(groups[0][0].length).to.be(1);
|
||||
expect(groups[0][1].color).to.be('#BADA55');
|
||||
expect(groups[1][0].length).to.be(2);
|
||||
expect(groups[1][1].color).to.be('#013');
|
||||
});
|
||||
|
||||
it('groups equal symbolizers also when defined on features', function() {
|
||||
var symbolizer = new ol.style.Stroke({
|
||||
width: 3,
|
||||
color: ol.expr.parse('colorProperty'),
|
||||
opacity: 1
|
||||
});
|
||||
var anotherSymbolizer = new ol.style.Stroke({
|
||||
width: 3,
|
||||
color: '#BADA55',
|
||||
opacity: 1
|
||||
});
|
||||
var featureWithSymbolizers = new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, -10], [-10, 10]]),
|
||||
colorProperty: '#BADA55'
|
||||
});
|
||||
featureWithSymbolizers.setSymbolizers([symbolizer]);
|
||||
var anotherFeatureWithSymbolizers = new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, 10], [-10, -10]])
|
||||
});
|
||||
anotherFeatureWithSymbolizers.setSymbolizers([anotherSymbolizer]);
|
||||
features.push(featureWithSymbolizers, anotherFeatureWithSymbolizers);
|
||||
|
||||
var groups = style.groupFeaturesBySymbolizerLiteral(features, 1);
|
||||
expect(groups).to.have.length(3);
|
||||
expect(groups[2][0].length).to.be(2);
|
||||
expect(groups[2][1].width).to.be(3);
|
||||
|
||||
});
|
||||
|
||||
it('sorts groups by zIndex', function() {
|
||||
var symbolizer = new ol.style.Stroke({
|
||||
width: 3,
|
||||
color: '#BADA55',
|
||||
opacity: 1,
|
||||
zIndex: 1
|
||||
});
|
||||
var anotherSymbolizer = new ol.style.Stroke({
|
||||
width: 3,
|
||||
color: '#BADA55',
|
||||
opacity: 1
|
||||
});
|
||||
var featureWithSymbolizers = new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, -10], [-10, 10]])
|
||||
});
|
||||
featureWithSymbolizers.setSymbolizers([symbolizer]);
|
||||
var anotherFeatureWithSymbolizers = new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, 10], [-10, -10]])
|
||||
});
|
||||
anotherFeatureWithSymbolizers.setSymbolizers([anotherSymbolizer]);
|
||||
features = [featureWithSymbolizers, anotherFeatureWithSymbolizers];
|
||||
|
||||
var groups = style.groupFeaturesBySymbolizerLiteral(features, 1);
|
||||
expect(groups).to.have.length(2);
|
||||
expect(groups[0][1].zIndex).to.be(0);
|
||||
expect(groups[1][1].zIndex).to.be(1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('ol.style.getDefault()', function() {
|
||||
var style = ol.style.getDefault();
|
||||
|
||||
|
||||
16
test/spec/ol/source/vectorsource/single-feature.json
Normal file
16
test/spec/ol/source/vectorsource/single-feature.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"id": "point_1",
|
||||
"geometry": {
|
||||
"coordinates": [1, 2],
|
||||
"type": "Point"
|
||||
},
|
||||
"properties": {
|
||||
"name": "point"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user